235 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			235 lines
		
	
	
		
			7.9 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
/* Internal definitions for configurable Xtensa ISA support.
 | 
						|
   Copyright 2003, 2004, 2005, 2008, 2010 Free Software Foundation, Inc.
 | 
						|
 | 
						|
   This file is part of BFD, the Binary File Descriptor library.
 | 
						|
 | 
						|
   This program is free software; you can redistribute it and/or modify
 | 
						|
   it under the terms of the GNU General Public License as published by
 | 
						|
   the Free Software Foundation; either version 3 of the License, or
 | 
						|
   (at your option) any later version.
 | 
						|
 | 
						|
   This program is distributed in the hope that it will be useful,
 | 
						|
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
						|
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
						|
   GNU General Public License for more details.
 | 
						|
 | 
						|
   You should have received a copy of the GNU General Public License
 | 
						|
   along with this program; if not, write to the Free Software
 | 
						|
   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301,
 | 
						|
   USA.  */
 | 
						|
 | 
						|
#ifndef XTENSA_ISA_INTERNAL_H
 | 
						|
#define XTENSA_ISA_INTERNAL_H
 | 
						|
 | 
						|
/* Flags.  */
 | 
						|
 | 
						|
#define XTENSA_OPERAND_IS_REGISTER	0x00000001
 | 
						|
#define XTENSA_OPERAND_IS_PCRELATIVE	0x00000002
 | 
						|
#define XTENSA_OPERAND_IS_INVISIBLE	0x00000004
 | 
						|
#define XTENSA_OPERAND_IS_UNKNOWN	0x00000008
 | 
						|
 | 
						|
#define XTENSA_OPCODE_IS_BRANCH		0x00000001
 | 
						|
#define XTENSA_OPCODE_IS_JUMP		0x00000002
 | 
						|
#define XTENSA_OPCODE_IS_LOOP		0x00000004
 | 
						|
#define XTENSA_OPCODE_IS_CALL		0x00000008
 | 
						|
 | 
						|
#define XTENSA_STATE_IS_EXPORTED	0x00000001
 | 
						|
#define XTENSA_STATE_IS_SHARED_OR	0x00000002
 | 
						|
 | 
						|
#define XTENSA_INTERFACE_HAS_SIDE_EFFECT 0x00000001
 | 
						|
 | 
						|
/* Function pointer typedefs */
 | 
						|
typedef void (*xtensa_format_encode_fn) (xtensa_insnbuf);
 | 
						|
typedef void (*xtensa_get_slot_fn) (const xtensa_insnbuf, xtensa_insnbuf);
 | 
						|
typedef void (*xtensa_set_slot_fn) (xtensa_insnbuf, const xtensa_insnbuf);
 | 
						|
typedef int (*xtensa_opcode_decode_fn) (const xtensa_insnbuf);
 | 
						|
typedef uint32 (*xtensa_get_field_fn) (const xtensa_insnbuf);
 | 
						|
typedef void (*xtensa_set_field_fn) (xtensa_insnbuf, uint32);
 | 
						|
typedef int (*xtensa_immed_decode_fn) (uint32 *);
 | 
						|
typedef int (*xtensa_immed_encode_fn) (uint32 *);
 | 
						|
typedef int (*xtensa_do_reloc_fn) (uint32 *, uint32);
 | 
						|
typedef int (*xtensa_undo_reloc_fn) (uint32 *, uint32);
 | 
						|
typedef void (*xtensa_opcode_encode_fn) (xtensa_insnbuf);
 | 
						|
typedef int (*xtensa_format_decode_fn) (const xtensa_insnbuf);
 | 
						|
typedef int (*xtensa_length_decode_fn) (const unsigned char *);
 | 
						|
 | 
						|
typedef struct xtensa_format_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Instruction format name.  */
 | 
						|
  int length;				/* Instruction length in bytes.  */
 | 
						|
  xtensa_format_encode_fn encode_fn;
 | 
						|
  int num_slots;
 | 
						|
  int *slot_id;				/* Array[num_slots] of slot IDs.  */
 | 
						|
} xtensa_format_internal;
 | 
						|
 | 
						|
typedef struct xtensa_slot_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Not necessarily unique.  */
 | 
						|
  const char *format;
 | 
						|
  int position;
 | 
						|
  xtensa_get_slot_fn get_fn;
 | 
						|
  xtensa_set_slot_fn set_fn;
 | 
						|
  xtensa_get_field_fn *get_field_fns;	/* Array[field_id].  */
 | 
						|
  xtensa_set_field_fn *set_field_fns;	/* Array[field_id].  */
 | 
						|
  xtensa_opcode_decode_fn opcode_decode_fn;
 | 
						|
  const char *nop_name;
 | 
						|
} xtensa_slot_internal;
 | 
						|
 | 
						|
typedef struct xtensa_operand_internal_struct
 | 
						|
{
 | 
						|
  const char *name;
 | 
						|
  int field_id;
 | 
						|
  xtensa_regfile regfile;		/* Register file.  */
 | 
						|
  int num_regs;				/* Usually 1; 2 for reg pairs, etc.  */
 | 
						|
  uint32 flags;				/* See XTENSA_OPERAND_* flags.  */
 | 
						|
  xtensa_immed_encode_fn encode;	/* Encode the operand value.  */
 | 
						|
  xtensa_immed_decode_fn decode;	/* Decode the value from the field.  */
 | 
						|
  xtensa_do_reloc_fn do_reloc;		/* Perform a PC-relative reloc.  */
 | 
						|
  xtensa_undo_reloc_fn undo_reloc;	/* Undo a PC-relative relocation.  */
 | 
						|
} xtensa_operand_internal;
 | 
						|
 | 
						|
typedef struct xtensa_arg_internal_struct
 | 
						|
{
 | 
						|
  union {
 | 
						|
    int operand_id;			/* For normal operands.  */
 | 
						|
    xtensa_state state;			/* For stateOperands.  */
 | 
						|
  } u;
 | 
						|
  char inout;				/* Direction: 'i', 'o', or 'm'.  */
 | 
						|
} xtensa_arg_internal;
 | 
						|
 | 
						|
typedef struct xtensa_iclass_internal_struct
 | 
						|
{
 | 
						|
  int num_operands;			/* Size of "operands" array.  */
 | 
						|
  xtensa_arg_internal *operands;	/* Array[num_operands].  */
 | 
						|
 | 
						|
  int num_stateOperands;		/* Size of "stateOperands" array.  */
 | 
						|
  xtensa_arg_internal *stateOperands;	/* Array[num_stateOperands].  */
 | 
						|
 | 
						|
  int num_interfaceOperands;		/* Size of "interfaceOperands".  */
 | 
						|
  xtensa_interface *interfaceOperands;	/* Array[num_interfaceOperands].  */
 | 
						|
} xtensa_iclass_internal;
 | 
						|
 | 
						|
typedef struct xtensa_opcode_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Opcode mnemonic.  */
 | 
						|
  int iclass_id;			/* Iclass for this opcode.  */
 | 
						|
  uint32 flags;				/* See XTENSA_OPCODE_* flags.  */
 | 
						|
  xtensa_opcode_encode_fn *encode_fns;	/* Array[slot_id].  */
 | 
						|
  int num_funcUnit_uses;		/* Number of funcUnit_use entries.  */
 | 
						|
  xtensa_funcUnit_use *funcUnit_uses;	/* Array[num_funcUnit_uses].  */
 | 
						|
} xtensa_opcode_internal;
 | 
						|
 | 
						|
typedef struct xtensa_regfile_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Full name of the regfile.  */
 | 
						|
  const char *shortname;		/* Abbreviated name.  */
 | 
						|
  xtensa_regfile parent;		/* View parent (or identity).  */
 | 
						|
  int num_bits;				/* Width of the registers.  */
 | 
						|
  int num_entries;			/* Number of registers.  */
 | 
						|
} xtensa_regfile_internal;
 | 
						|
 | 
						|
typedef struct xtensa_interface_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Interface name.  */
 | 
						|
  int num_bits;				/* Width of the interface.  */
 | 
						|
  uint32 flags;				/* See XTENSA_INTERFACE_* flags.  */
 | 
						|
  int class_id;				/* Class of related interfaces.  */
 | 
						|
  char inout;				/* "i" or "o".  */
 | 
						|
} xtensa_interface_internal;
 | 
						|
 | 
						|
typedef struct xtensa_funcUnit_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Functional unit name.  */
 | 
						|
  int num_copies;			/* Number of instances.  */
 | 
						|
} xtensa_funcUnit_internal;
 | 
						|
 | 
						|
typedef struct xtensa_state_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* State name.  */
 | 
						|
  int num_bits;				/* Number of state bits.  */
 | 
						|
  uint32 flags;				/* See XTENSA_STATE_* flags.  */
 | 
						|
} xtensa_state_internal;
 | 
						|
 | 
						|
typedef struct xtensa_sysreg_internal_struct
 | 
						|
{
 | 
						|
  const char *name;			/* Register name.  */
 | 
						|
  int number;				/* Register number.  */
 | 
						|
  int is_user;				/* Non-zero if a "user register".  */
 | 
						|
} xtensa_sysreg_internal;
 | 
						|
 | 
						|
typedef struct xtensa_lookup_entry_struct
 | 
						|
{
 | 
						|
  const char *key;
 | 
						|
  union
 | 
						|
  {
 | 
						|
    xtensa_opcode opcode;		/* Internal opcode number.  */
 | 
						|
    xtensa_sysreg sysreg;		/* Internal sysreg number.  */
 | 
						|
    xtensa_state state;			/* Internal state number.  */
 | 
						|
    xtensa_interface intf;		/* Internal interface number.  */
 | 
						|
    xtensa_funcUnit fun;		/* Internal funcUnit number.  */
 | 
						|
  } u;
 | 
						|
} xtensa_lookup_entry;
 | 
						|
 | 
						|
typedef struct xtensa_isa_internal_struct
 | 
						|
{
 | 
						|
  int is_big_endian;			/* Endianness.  */
 | 
						|
  int insn_size;			/* Maximum length in bytes.  */
 | 
						|
  int insnbuf_size;			/* Number of insnbuf_words.  */
 | 
						|
 | 
						|
  int num_formats;
 | 
						|
  xtensa_format_internal *formats;
 | 
						|
  xtensa_format_decode_fn format_decode_fn;
 | 
						|
  xtensa_length_decode_fn length_decode_fn;
 | 
						|
 | 
						|
  int num_slots;
 | 
						|
  xtensa_slot_internal *slots;
 | 
						|
 | 
						|
  int num_fields;
 | 
						|
 | 
						|
  int num_operands;
 | 
						|
  xtensa_operand_internal *operands;
 | 
						|
 | 
						|
  int num_iclasses;
 | 
						|
  xtensa_iclass_internal *iclasses;
 | 
						|
 | 
						|
  int num_opcodes;
 | 
						|
  xtensa_opcode_internal *opcodes;
 | 
						|
  xtensa_lookup_entry *opname_lookup_table;
 | 
						|
 | 
						|
  int num_regfiles;
 | 
						|
  xtensa_regfile_internal *regfiles;
 | 
						|
 | 
						|
  int num_states;
 | 
						|
  xtensa_state_internal *states;
 | 
						|
  xtensa_lookup_entry *state_lookup_table;
 | 
						|
 | 
						|
  int num_sysregs;
 | 
						|
  xtensa_sysreg_internal *sysregs;
 | 
						|
  xtensa_lookup_entry *sysreg_lookup_table;
 | 
						|
 | 
						|
  /* The current Xtensa ISA only supports 256 of each kind of sysreg so
 | 
						|
     we can get away with implementing lookups with tables indexed by
 | 
						|
     the register numbers.  If we ever allow larger sysreg numbers, this
 | 
						|
     may have to be reimplemented.  The first entry in the following
 | 
						|
     arrays corresponds to "special" registers and the second to "user"
 | 
						|
     registers.  */
 | 
						|
  int max_sysreg_num[2];
 | 
						|
  xtensa_sysreg *sysreg_table[2];
 | 
						|
 | 
						|
  int num_interfaces;
 | 
						|
  xtensa_interface_internal *interfaces;
 | 
						|
  xtensa_lookup_entry *interface_lookup_table;
 | 
						|
 | 
						|
  int num_funcUnits;
 | 
						|
  xtensa_funcUnit_internal *funcUnits;
 | 
						|
  xtensa_lookup_entry *funcUnit_lookup_table;
 | 
						|
 | 
						|
} xtensa_isa_internal;
 | 
						|
 | 
						|
extern int xtensa_isa_name_compare (const void *, const void *);
 | 
						|
 | 
						|
extern xtensa_isa_status xtisa_errno;
 | 
						|
extern char xtisa_error_msg[];
 | 
						|
 | 
						|
#endif /* !XTENSA_ISA_INTERNAL_H */
 |