From 5c7ad1c66167a23cc9babd50f93dd466fa8981d3 Mon Sep 17 00:00:00 2001 From: Joern Rennecke Date: Thu, 10 Sep 2009 15:09:41 +0000 Subject: Commit patches for ARCompact support to binutils-arc-20081103-branch . --- configure | 2 +- include/ChangeLog.ARC | 2 + include/dis-asm.h | 2 +- include/elf/ChangeLog.ARC | 2 + include/elf/arc.h | 97 +++++++++-- include/elf/common.h | 2 +- include/opcode/ChangeLog.ARC | 9 + include/opcode/arc.h | 395 +++++++++++++++++++++++++++++-------------- include/opcode/cgen.h | 2 +- 9 files changed, 366 insertions(+), 147 deletions(-) create mode 100644 include/ChangeLog.ARC create mode 100644 include/elf/ChangeLog.ARC create mode 100644 include/opcode/ChangeLog.ARC diff --git a/configure b/configure index 0000ea85a..3b374d119 100755 --- a/configure +++ b/configure @@ -2049,7 +2049,7 @@ if test "${ENABLE_GOLD}" = "yes"; then is_elf=no case "${target}" in *-*-elf* | *-*-sysv4* | *-*-unixware* | *-*-eabi* | hppa*64*-*-hpux* \ - | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ + | arc-elf* | arc-linux-* | *-*-linux* | frv-*-uclinux* | *-*-irix5* | *-*-irix6* \ | *-*-netbsd* | *-*-openbsd* | *-*-freebsd* | *-*-solaris2*) case "${target}" in *-*-linux*aout* | *-*-linux*oldld*) diff --git a/include/ChangeLog.ARC b/include/ChangeLog.ARC new file mode 100644 index 000000000..e07c88e1f --- /dev/null +++ b/include/ChangeLog.ARC @@ -0,0 +1,2 @@ +14 Irfan Rafiq + * dis-asm.h (arc_get_disassembler) Update prototype. \ No newline at end of file diff --git a/include/dis-asm.h b/include/dis-asm.h index db74d85ac..a74fb1a1e 100644 --- a/include/dis-asm.h +++ b/include/dis-asm.h @@ -285,7 +285,7 @@ extern int print_insn_z80 (bfd_vma, disassemble_info *); extern int print_insn_z8001 (bfd_vma, disassemble_info *); extern int print_insn_z8002 (bfd_vma, disassemble_info *); -extern disassembler_ftype arc_get_disassembler (void *); +extern disassembler_ftype arc_get_disassembler (bfd *); extern disassembler_ftype cris_get_disassembler (bfd *); extern void print_i386_disassembler_options (FILE *); diff --git a/include/elf/ChangeLog.ARC b/include/elf/ChangeLog.ARC new file mode 100644 index 000000000..f298faa99 --- /dev/null +++ b/include/elf/ChangeLog.ARC @@ -0,0 +1,2 @@ +2008-11-14 Irfan Rafiq + * common.h (EM_ARCOMPACT) Removed obsolete flag and added new for ARCOMPACT cores. \ No newline at end of file diff --git a/include/elf/arc.h b/include/elf/arc.h index e2f4f4160..09dcd93f1 100644 --- a/include/elf/arc.h +++ b/include/elf/arc.h @@ -1,6 +1,7 @@ /* ARC ELF support for BFD. - Copyright 1995, 1997, 1998, 2000, 2001 Free Software Foundation, Inc. - Contributed by Doug Evans, (dje@cygnus.com) + Copyright 1995, 1997, 1998, 2000, 2001, 2002, 2005, 2006, 2007, 2008, 2009 + Free Software Foundation, Inc. + Contributed by Doug Evans (dje@cygnus.com). This file is part of BFD, the Binary File Descriptor library. @@ -28,29 +29,89 @@ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. /* Relocations. */ START_RELOC_NUMBERS (elf_arc_reloc_type) - RELOC_NUMBER (R_ARC_NONE, 0) - RELOC_NUMBER (R_ARC_32, 1) - RELOC_NUMBER (R_ARC_B26, 2) - RELOC_NUMBER (R_ARC_B22_PCREL, 3) + RELOC_NUMBER (R_ARC_NONE, 0x0) + RELOC_NUMBER (R_ARC_8, 0x1) + RELOC_NUMBER (R_ARC_16,0x2) + RELOC_NUMBER (R_ARC_24,0x3) + RELOC_NUMBER (R_ARC_32,0x4) + RELOC_NUMBER (R_ARC_B26,0x5) + RELOC_NUMBER (R_ARC_B22_PCREL, 0x6) + + RELOC_NUMBER (R_ARC_H30,0x7) + RELOC_NUMBER (R_ARC_N8, 0x8) + RELOC_NUMBER (R_ARC_N16,0x9) + RELOC_NUMBER (R_ARC_N24,0xA) + RELOC_NUMBER (R_ARC_N32,0xB) + RELOC_NUMBER (R_ARC_SDA,0xC) + RELOC_NUMBER (R_ARC_SECTOFF,0xD) + + RELOC_NUMBER (R_ARC_S21H_PCREL, 0xE) + RELOC_NUMBER (R_ARC_S21W_PCREL, 0xF) + RELOC_NUMBER (R_ARC_S25H_PCREL, 0x10) + RELOC_NUMBER (R_ARC_S25W_PCREL, 0x11) + + RELOC_NUMBER (R_ARC_SDA32, 0x12) + RELOC_NUMBER (R_ARC_SDA_LDST, 0x13) + RELOC_NUMBER (R_ARC_SDA_LDST1, 0x14) + RELOC_NUMBER (R_ARC_SDA_LDST2, 0x15) + RELOC_NUMBER (R_ARC_SDA16_LD,0x16) + RELOC_NUMBER (R_ARC_SDA16_LD1,0x17) + RELOC_NUMBER (R_ARC_SDA16_LD2,0x18) + + + RELOC_NUMBER (R_ARC_S13_PCREL,0x19 ) + + RELOC_NUMBER (R_ARC_W, 0x1A) + RELOC_NUMBER (R_ARC_32_ME, 0x1B) + + RELOC_NUMBER (R_ARC_N32_ME , 0x1C) + RELOC_NUMBER (R_ARC_SECTOFF_ME, 0x1D) + RELOC_NUMBER (R_ARC_SDA32_ME , 0x1E) + RELOC_NUMBER (R_ARC_W_ME, 0x1F) + RELOC_NUMBER (R_ARC_H30_ME, 0x20) + + RELOC_NUMBER (R_ARC_SECTOFF_U8, 0x21) + RELOC_NUMBER (R_ARC_SECTOFF_S9, 0x22) + + + RELOC_NUMBER (R_AC_SECTOFF_U8, 0x23) + RELOC_NUMBER (R_AC_SECTOFF_U8_1, 0x24) + RELOC_NUMBER (R_AC_SECTOFF_U8_2, 0x25) + + + RELOC_NUMBER (R_AC_SECTOFF_S9, 0x26) + RELOC_NUMBER (R_AC_SECTOFF_S9_1, 0x27) + RELOC_NUMBER (R_AC_SECTOFF_S9_2, 0x28) + + + RELOC_NUMBER (R_ARC_SECTOFF_ME_1 ,0x29) + RELOC_NUMBER (R_ARC_SECTOFF_ME_2, 0x2A) + RELOC_NUMBER (R_ARC_SECTOFF_1, 0x2B) + RELOC_NUMBER (R_ARC_SECTOFF_2, 0x2C) + + + RELOC_NUMBER (R_ARC_PC32, 0x32) + RELOC_NUMBER (R_ARC_GOTPC32,0x33) + RELOC_NUMBER (R_ARC_PLT32,0x34) + RELOC_NUMBER (R_ARC_COPY, 0x35) + RELOC_NUMBER (R_ARC_GLOB_DAT, 0x36) + RELOC_NUMBER (R_ARC_JMP_SLOT, 0x37) + RELOC_NUMBER (R_ARC_RELATIVE, 0x38) + RELOC_NUMBER (R_ARC_GOTOFF, 0x39) + RELOC_NUMBER (R_ARC_GOTPC, 0x3A) + RELOC_NUMBER (R_ARC_GOT32, 0x3B) END_RELOC_NUMBERS (R_ARC_max) /* Processor specific flags for the ELF header e_flags field. */ /* Four bit ARC machine type field. */ - -#define EF_ARC_MACH 0x0000000f +#define EF_ARC_MACH 0x0000000f /* Various CPU types. */ +#define E_ARC_MACH_A4 0x00000000 +#define E_ARC_MACH_A5 0x00000001 +#define E_ARC_MACH_ARC600 0x00000002 +#define E_ARC_MACH_ARC700 0x00000003 -#define E_ARC_MACH_ARC5 0 -#define E_ARC_MACH_ARC6 1 -#define E_ARC_MACH_ARC7 2 -#define E_ARC_MACH_ARC8 3 - -/* Leave bits 0xf0 alone in case we ever have more than 16 cpu types. */ - -/* File contains position independent code. */ - -#define EF_ARC_PIC 0x00000100 #endif /* _ELF_ARC_H */ diff --git a/include/elf/common.h b/include/elf/common.h index 995edbc58..b1b40035f 100644 --- a/include/elf/common.h +++ b/include/elf/common.h @@ -178,7 +178,7 @@ #define EM_MN10200 90 /* Matsushita MN10200 */ #define EM_PJ 91 /* picoJava */ #define EM_OPENRISC 92 /* OpenRISC 32-bit embedded processor */ -#define EM_ARC_A5 93 /* ARC Cores Tangent-A5 */ +#define EM_ARCOMPACT 93 /* ARC Cores */ #define EM_XTENSA 94 /* Tensilica Xtensa Architecture */ #define EM_VIDEOCORE 95 /* Alphamosaic VideoCore processor */ #define EM_TMM_GPP 96 /* Thompson Multimedia General Purpose Processor */ diff --git a/include/opcode/ChangeLog.ARC b/include/opcode/ChangeLog.ARC new file mode 100644 index 000000000..d09ed08cb --- /dev/null +++ b/include/opcode/ChangeLog.ARC @@ -0,0 +1,9 @@ +2009-09-07 Irfan Rafiq + + * cgen.h (struct cgen_cpu_desc) : Update parameter list. + +2008-11-14 Irfan Rafiq + * arc.h: Sync with processor info. + + + diff --git a/include/opcode/arc.h b/include/opcode/arc.h index 8ddcf5433..30aaa0385 100644 --- a/include/opcode/arc.h +++ b/include/opcode/arc.h @@ -1,5 +1,5 @@ /* Opcode table for the ARC. - Copyright 1994, 1995, 1997, 2001, 2002, 2003 + Copyright 1994, 1995, 1997, 1998, 2000, 2001, 2002, 2005, 2006, 2007, 2008, 2009 Free Software Foundation, Inc. Contributed by Doug Evans (dje@cygnus.com). @@ -27,86 +27,160 @@ whatever is supported by a particular cpu. This lets us have one entry apply to several cpus. - The `base' cpu must be 0. The cpu type is treated independently of - endianness. The complete `mach' number includes endianness. + This duplicates bfd_mach_arc_xxx. For now I wish to isolate this from bfd + and bfd from this. Also note that these numbers are bit values as we want + to allow for things available on more than one ARC (but not necessarily all + ARCs). */ + +/* The `base' cpu must be 0 (table entries are omitted for the base cpu). + The cpu type is treated independently of endianness. + The complete `mach' number includes endianness. These values are internal to opcodes/bfd/binutils/gas. */ -#define ARC_MACH_5 0 -#define ARC_MACH_6 1 -#define ARC_MACH_7 2 -#define ARC_MACH_8 4 +#define ARC_MACH_ARC4 1 +#define ARC_MACH_ARC5 2 +#define ARC_MACH_ARC6 4 +#define ARC_MACH_ARC7 8 /* Additional cpu values can be inserted here and ARC_MACH_BIG moved down. */ #define ARC_MACH_BIG 16 +/* ARC processors which implement ARCompact ISA. */ +#define ARCOMPACT (ARC_MACH_ARC5 | ARC_MACH_ARC6 | ARC_MACH_ARC7) + /* Mask of number of bits necessary to record cpu type. */ #define ARC_MACH_CPU_MASK (ARC_MACH_BIG - 1) - /* Mask of number of bits necessary to record cpu type + endianness. */ #define ARC_MACH_MASK ((ARC_MACH_BIG << 1) - 1) /* Type to denote an ARC instruction (at least a 32 bit unsigned int). */ - typedef unsigned int arc_insn; struct arc_opcode { - char *syntax; /* syntax of insn */ - unsigned long mask, value; /* recognize insn if (op&mask) == value */ - int flags; /* various flag bits */ + char *syntax; /* syntax of insn */ + unsigned long mask, value; /* recognize insn if (op&mask)==value */ + int flags; /* various flag bits */ + /* Values for `flags'. */ /* Return CPU number, given flag bits. */ #define ARC_OPCODE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK) - /* Return MACH number, given flag bits. */ #define ARC_OPCODE_MACH(bits) ((bits) & ARC_MACH_MASK) - /* First opcode flag bit available after machine mask. */ #define ARC_OPCODE_FLAG_START (ARC_MACH_MASK + 1) /* This insn is a conditional branch. */ #define ARC_OPCODE_COND_BRANCH (ARC_OPCODE_FLAG_START) -#define SYNTAX_3OP (ARC_OPCODE_COND_BRANCH << 1) -#define SYNTAX_LENGTH (SYNTAX_3OP ) -#define SYNTAX_2OP (SYNTAX_3OP << 1) -#define OP1_MUST_BE_IMM (SYNTAX_2OP << 1) -#define OP1_IMM_IMPLIED (OP1_MUST_BE_IMM << 1) -#define SYNTAX_VALID (OP1_IMM_IMPLIED << 1) - -#define I(x) (((x) & 31) << 27) -#define A(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGA) -#define B(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGB) -#define C(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGC) -#define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */ - -/* These values are used to optimize assembly and disassembly. Each insn - is on a list of related insns (same first letter for assembly, same - insn code for disassembly). */ - - struct arc_opcode *next_asm; /* Next instr to try during assembly. */ - struct arc_opcode *next_dis; /* Next instr to try during disassembly. */ - -/* Macros to create the hash values for the lists. */ +#define SYNTAX_LENGTH (ARC_OPCODE_COND_BRANCH << 1) +#define SYNTAX_3OP (SYNTAX_LENGTH ) +#define SYNTAX_2OP (SYNTAX_3OP << 1) +#define SYNTAX_1OP (SYNTAX_2OP << 1) +#define SYNTAX_NOP (SYNTAX_1OP << 1) +#define OP1_DEST_IGNORED (SYNTAX_NOP << 1) +#define OP1_MUST_BE_IMM (OP1_DEST_IGNORED << 1) +#define OP1_IMM_IMPLIED (OP1_MUST_BE_IMM << 1) +#define SUFFIX_NONE (OP1_IMM_IMPLIED << 1) +#define SUFFIX_COND (SUFFIX_NONE << 1) +#define SUFFIX_FLAG (SUFFIX_COND << 1) +#define SYNTAX_VALID (SUFFIX_FLAG << 1) +#define SIMD_LONG_INST (SYNTAX_VALID << 1) + +#define AC_SYNTAX_3OP (0x01) +#define AC_SYNTAX_2OP (AC_SYNTAX_3OP << 1) +#define AC_SYNTAX_1OP (AC_SYNTAX_2OP << 1) +#define AC_SYNTAX_NOP (AC_SYNTAX_1OP << 1) +#define AC_SYNTAX_SIMD (AC_SYNTAX_NOP << 1) +#define AC_OP1_DEST_IGNORED (AC_SYNTAX_SIMD << 1) +#define AC_OP1_MUST_BE_IMM (AC_OP1_DEST_IGNORED << 1) +#define AC_OP1_IMM_IMPLIED (AC_OP1_MUST_BE_IMM << 1) +#define AC_SIMD_SYNTAX_DISC (AC_OP1_IMM_IMPLIED << 1) +#define AC_SIMD_IREGA (AC_SIMD_SYNTAX_DISC << 1) +#define AC_SIMD_IREGB (AC_SIMD_IREGA << 1) + +#define AC_SIMD_SYNTAX_VVV (AC_SIMD_IREGB << 1) +#define AC_SIMD_SYNTAX_VV0 (AC_SIMD_SYNTAX_VVV << 1) +#define AC_SIMD_SYNTAX_VbI0 (AC_SIMD_SYNTAX_VV0 << 1) +#define AC_SIMD_SYNTAX_Vb00 (AC_SIMD_SYNTAX_VbI0 << 1) +#define AC_SIMD_SYNTAX_VbC0 (AC_SIMD_SYNTAX_Vb00 << 1) +#define AC_SIMD_SYNTAX_V00 (AC_SIMD_SYNTAX_VbC0 << 1) +#define AC_SIMD_SYNTAX_VC0 (AC_SIMD_SYNTAX_V00 << 1) +#define AC_SIMD_SYNTAX_VVC (AC_SIMD_SYNTAX_VC0 << 1) +#define AC_SIMD_SYNTAX_VV (AC_SIMD_SYNTAX_VVC << 1) +#define AC_SIMD_SYNTAX_VVI (AC_SIMD_SYNTAX_VV << 1) +#define AC_SIMD_SYNTAX_C (AC_SIMD_SYNTAX_VVI << 1) +#define AC_SIMD_SYNTAX_0 (AC_SIMD_SYNTAX_C << 1) +#define AC_SIMD_SYNTAX_CC (AC_SIMD_SYNTAX_0 << 1) +#define AC_SIMD_SYNTAX_C0 (AC_SIMD_SYNTAX_CC << 1) +#define AC_SIMD_SYNTAX_DC (AC_SIMD_SYNTAX_C0 << 1) +#define AC_SIMD_SYNTAX_D0 (AC_SIMD_SYNTAX_DC << 1) +#define AC_SIMD_SYNTAX_VD (AC_SIMD_SYNTAX_D0 << 1) +#define AC_SIMD_SYNTAX_VVL (AC_SIMD_SYNTAX_VD << 1) +#define AC_SIMD_SYNTAX_VU0 (AC_SIMD_SYNTAX_VVL << 1) +#define AC_SIMD_SYNTAX_VL0 (AC_SIMD_SYNTAX_VU0 << 1) +#define AC_SIMD_SYNTAX_C00 (AC_SIMD_SYNTAX_VL0 << 1) + + + //#define AC_SUFFIX_NONE (AC_SIMD_SYNTAX_VD << 1) +#define AC_SUFFIX_NONE (0x1) +#define AC_SUFFIX_COND (AC_SUFFIX_NONE << 1) +#define AC_SUFFIX_FLAG (AC_SUFFIX_COND << 1) +#define AC_SIMD_FLAGS_NONE (AC_SUFFIX_FLAG << 1) +#define AC_SIMD_FLAG_SET (AC_SIMD_FLAGS_NONE << 1) +#define AC_SIMD_FLAG1_SET (AC_SIMD_FLAG_SET << 1) +#define AC_SIMD_FLAG2_SET (AC_SIMD_FLAG1_SET << 1) +#define AC_SIMD_ENCODE_U8 (AC_SIMD_FLAG2_SET << 1) +#define AC_SIMD_ENCODE_U6 (AC_SIMD_ENCODE_U8 << 1) +#define AC_SIMD_SCALE_1 (AC_SIMD_ENCODE_U6 << 1) +#define AC_SIMD_SCALE_2 (AC_SIMD_SCALE_1 << 1) +#define AC_SIMD_SCALE_3 (AC_SIMD_SCALE_2 << 1) +#define AC_SIMD_SCALE_4 (AC_SIMD_SCALE_3 << 1) +#define AC_SIMD_SCALE_0 (AC_SIMD_SCALE_4 << 1) +#define AC_SIMD_ENCODE_LIMM (AC_SIMD_SCALE_0 << 1) +#define AC_SIMD_EXTENDED (AC_SIMD_ENCODE_LIMM << 1) +#define AC_SIMD_EXTEND2 (AC_SIMD_EXTENDED << 1) +#define AC_SIMD_EXTEND3 (AC_SIMD_EXTEND2 << 1) +#define AC_SUFFIX_LANEMASK (AC_SIMD_EXTEND3 << 1) +#define AC_SIMD_ENCODE_S12 (AC_SUFFIX_LANEMASK << 1) +#define AC_SIMD_ZERVA (AC_SIMD_ENCODE_S12 << 1) +#define AC_SIMD_ZERVB (AC_SIMD_ZERVA << 1) +#define AC_SIMD_ZERVC (AC_SIMD_ZERVB << 1) +#define AC_SIMD_SETLM (AC_SIMD_ZERVC << 1) +#define AC_SIMD_EXTEND1 (AC_SIMD_SETLM << 1) +#define AC_SIMD_KREG (AC_SIMD_EXTEND1 << 1) +#define AC_SIMD_ENCODE_U16 (AC_SIMD_KREG << 1) + + +#define I(x) (((unsigned) (x) & 31) << 27) +#define A(x) (((unsigned) (x) & ARC_MASK_REG) << ARC_SHIFT_REGA) +#define B(x) (((unsigned) (x) & ARC_MASK_REG) << ARC_SHIFT_REGB) +#define C(x) (((unsigned) (x) & ARC_MASK_REG) << ARC_SHIFT_REGC) +#define R(x,b,m) (((unsigned) (x) & (m)) << (b)) /* value X, mask M, at bit B */ + + /* These values are used to optimize assembly and disassembly. Each insn is + on a list of related insns (same first letter for assembly, same insn code + for disassembly). */ + struct arc_opcode *next_asm; /* Next instruction to try during assembly. */ + struct arc_opcode *next_dis; /* Next instruction to try during disassembly. */ + + /* Macros to create the hash values for the lists. */ #define ARC_HASH_OPCODE(string) \ ((string)[0] >= 'a' && (string)[0] <= 'z' ? (string)[0] - 'a' : 26) #define ARC_HASH_ICODE(insn) \ ((unsigned int) (insn) >> 27) - /* Macros to access `next_asm', `next_dis' so users needn't care about the - underlying mechanism. */ + /* Macros to access `next_asm', `next_dis' so users needn't care about the + underlying mechanism. */ #define ARC_OPCODE_NEXT_ASM(op) ((op)->next_asm) #define ARC_OPCODE_NEXT_DIS(op) ((op)->next_dis) + unsigned long mask2,value2; /* second word for 64 bit instructions*/ }; -/* this is an "insert at front" linked list per Metaware spec - that new definitions override older ones. */ -extern struct arc_opcode *arc_ext_opcodes; - struct arc_operand_value { - char *name; /* eg: "eq" */ - short value; /* eg: 1 */ - unsigned char type; /* index into `arc_operands' */ - unsigned char flags; /* various flag bits */ + char *name; /* eg: "eq" */ + short value; /* eg: 1 */ + unsigned char type; /* index into `arc_operands' */ + unsigned char flags; /* various flag bits */ /* Values for `flags'. */ @@ -121,20 +195,22 @@ struct arc_ext_operand_value { struct arc_operand_value operand; }; +/* List of extension condition codes, core registers and auxiliary registers. + Calls to gas/config/tc-arc.c:arc_extoper built up this list. */ extern struct arc_ext_operand_value *arc_ext_operands; struct arc_operand { -/* One of the insn format chars. */ + /* One of the insn format chars. */ unsigned char fmt; -/* The number of bits in the operand (may be unused for a modifier). */ + /* The number of bits in the operand (may be unused for a modifier). */ unsigned char bits; -/* How far the operand is left shifted in the instruction, or - the modifier's flag bit (may be unused for a modifier. */ + /* How far the operand is left shifted in the instruction, or + the modifier's flag bit (may be unused for a modifier. */ unsigned char shift; -/* Various flag bits. */ + /* Various flag bits. */ int flags; /* Values for `flags'. */ @@ -176,10 +252,11 @@ struct arc_operand { in special ways. */ #define ARC_OPERAND_FAKE 0x100 -/* separate flags operand for j and jl instructions */ +/* separate flags operand for j and jl instructions */ #define ARC_OPERAND_JUMPFLAGS 0x200 -/* allow warnings and errors to be issued after call to insert_xxxxxx */ +/* allow warnings and errors to be issued after call to insert_xxxxxx */ + #define ARC_OPERAND_WARN 0x400 #define ARC_OPERAND_ERROR 0x800 @@ -189,6 +266,15 @@ struct arc_operand { /* this is a store operand */ #define ARC_OPERAND_STORE 0x10000 +/* this is an unsigned operand */ +#define ARC_OPERAND_UNSIGNED 0x20000 + +/* this operand's value must be 2-byte aligned */ +#define ARC_OPERAND_2BYTE_ALIGNED 0x40000 + +/* this operand's value must be 4-byte aligned */ +#define ARC_OPERAND_4BYTE_ALIGNED 0x80000 + /* Modifier values. */ /* A dot is required before a suffix. Eg: .le */ #define ARC_MOD_DOT 0x1000 @@ -199,70 +285,108 @@ struct arc_operand { /* An auxiliary register name is expected. */ #define ARC_MOD_AUXREG 0x4000 + /* This should be a small data symbol, i.e. suffixed with an @sda */ +#define ARC_MOD_SDASYM 0x100000 + /* Sum of all ARC_MOD_XXX bits. */ -#define ARC_MOD_BITS 0x7000 +#define ARC_MOD_BITS 0x107000 /* Non-zero if the operand type is really a modifier. */ #define ARC_MOD_P(X) ((X) & ARC_MOD_BITS) -/* enforce read/write only register restrictions */ +/* enforce read/write only register restrictions */ + #define ARC_REGISTER_READONLY 0x01 #define ARC_REGISTER_WRITEONLY 0x02 #define ARC_REGISTER_NOSHORT_CUT 0x04 -/* Insertion function. This is used by the assembler. To insert an - operand value into an instruction, check this field. - - If it is NULL, execute - i |= (p & ((1 << o->bits) - 1)) << o->shift; - (I is the instruction which we are filling in, O is a pointer to - this structure, and OP is the opcode value; this assumes twos - complement arithmetic). - - If this field is not NULL, then simply call it with the - instruction and the operand value. It will return the new value - of the instruction. If the ERRMSG argument is not NULL, then if - the operand value is illegal, *ERRMSG will be set to a warning - string (the operand will be inserted in any case). If the - operand value is legal, *ERRMSG will be unchanged. - - REG is non-NULL when inserting a register value. */ - - arc_insn (*insert) - (arc_insn insn, const struct arc_operand *operand, int mods, - const struct arc_operand_value *reg, long value, const char **errmsg); - -/* Extraction function. This is used by the disassembler. To - extract this operand type from an instruction, check this field. - - If it is NULL, compute - op = ((i) >> o->shift) & ((1 << o->bits) - 1); - if ((o->flags & ARC_OPERAND_SIGNED) != 0 - && (op & (1 << (o->bits - 1))) != 0) - op -= 1 << o->bits; - (I is the instruction, O is a pointer to this structure, and OP - is the result; this assumes twos complement arithmetic). - - If this field is not NULL, then simply call it with the - instruction value. It will return the value of the operand. If - the INVALID argument is not NULL, *INVALID will be set to - non-zero if this operand type can not actually be extracted from - this operand (i.e., the instruction does not match). If the - operand is valid, *INVALID will not be changed. - - INSN is a pointer to an array of two `arc_insn's. The first element is - the insn, the second is the limm if present. - - Operands that have a printable form like registers and suffixes have - their struct arc_operand_value pointer stored in OPVAL. */ - - long (*extract) - (arc_insn *insn, const struct arc_operand *operand, int mods, - const struct arc_operand_value **opval, int *invalid); +/* Registers which are normally used in 16-bit ARCompact insns */ +#define ARC_REGISTER_16 0x8 + + /* + FIXME: The following 5 definitions is a unclean way of passing + information to md_assemble. New opcode is a possibility but its + already very crowded. + */ + /*The u6 operand needs to be incremented by 1 for some pseudo mnemonics of + the BRcc instruction. */ +#define ARC_INCR_U6 0x100000 + +#define ARC_SIMD_SCALE1 (ARC_INCR_U6 << 0x1) +#define ARC_SIMD_SCALE2 (ARC_SIMD_SCALE1 << 0x1) +#define ARC_SIMD_SCALE3 (ARC_SIMD_SCALE2 << 0x1) +#define ARC_SIMD_SCALE4 (ARC_SIMD_SCALE3 << 0x1) +#define ARC_SIMD_LANEMASK (ARC_SIMD_SCALE4 <<0x1) +#define ARC_SIMD_REGISTER (ARC_SIMD_LANEMASK <<0x1) +#define ARC_SIMD_ZERVA (ARC_SIMD_REGISTER <<0x1) +#define ARC_SIMD_ZERVB (ARC_SIMD_ZERVA <<0x1) +#define ARC_SIMD_ZERVC (ARC_SIMD_ZERVB <<0x1) +#define ARC_SIMD_SETLM (ARC_SIMD_ZERVC <<0x1) + +/* Registers for the Aurora SIMD ISA*/ +#define ARC_REGISTER_SIMD_VR 0x10 +#define ARC_REGISTER_SIMD_I 0x20 +#define ARC_REGISTER_SIMD_DR 0x40 +#define ARC_REGISTER_SIMD_K 0x80 + + + /* Insertion function. This is used by the assembler. To insert an + operand value into an instruction, check this field. + + If it is NULL, execute + i |= (p & ((1 << o->bits) - 1)) << o->shift; + (I is the instruction which we are filling in, O is a pointer to + this structure, and OP is the opcode value; this assumes twos + complement arithmetic). + + If this field is not NULL, then simply call it with the + instruction and the operand value. It will return the new value + of the instruction. If the ERRMSG argument is not NULL, then if + the operand value is illegal, *ERRMSG will be set to a warning + string (the operand will be inserted in any case). If the + operand value is legal, *ERRMSG will be unchanged. + + REG is non-NULL when inserting a register value. + extend is only meaningful for extended length instructions + and the special fields that use them. + */ + + arc_insn (*insert) (arc_insn insn, long *extend, const struct arc_operand *operand, + int mods, const struct arc_operand_value *reg, + long value, const char **errmsg); + + /* Extraction function. This is used by the disassembler. To + extract this operand type from an instruction, check this field. + + If it is NULL, compute + op = ((i) >> o->shift) & ((1 << o->bits) - 1); + if ((o->flags & ARC_OPERAND_SIGNED) != 0 + && (op & (1 << (o->bits - 1))) != 0) + op -= 1 << o->bits; + (I is the instruction, O is a pointer to this structure, and OP + is the result; this assumes twos complement arithmetic). + + If this field is not NULL, then simply call it with the + instruction value. It will return the value of the operand. If + the INVALID argument is not NULL, *INVALID will be set to + non-zero if this operand type can not actually be extracted from + this operand (i.e., the instruction does not match). If the + operand is valid, *INVALID will not be changed. + + INSN is a pointer to an array of two `arc_insn's. The first element is + the insn, the second is the limm if present. + + Operands that have a printable form like registers and suffixes have + their struct arc_operand_value pointer stored in OPVAL. */ + + long (*extract) (arc_insn *insn, + const struct arc_operand *operand, int mods, + const struct arc_operand_value **opval, int *invalid); }; -/* Bits that say what version of cpu we have. These should be passed to - arc_init_opcode_tables. At present, all there is is the cpu type. */ +/* Bits that say what version of cpu we have. + These should be passed to arc_init_opcode_tables. + At present, all there is is the cpu type. */ /* CPU number, given value passed to `arc_init_opcode_tables'. */ #define ARC_HAVE_CPU(bits) ((bits) & ARC_MACH_CPU_MASK) @@ -281,29 +405,41 @@ struct arc_operand { #define ARC_SHIFT_REGA 21 #define ARC_SHIFT_REGB 15 #define ARC_SHIFT_REGC 9 +#define ARC_SHIFT_REGA_AC 0 +#define ARC_SHIFT_REGB_LOW_AC 24 +#define ARC_SHIFT_REGB_HIGH_AC 12 +#define ARC_SHIFT_REGC_AC 6 #define ARC_MASK_REG 63 /* Delay slot types. */ -#define ARC_DELAY_NONE 0 /* no delay slot */ -#define ARC_DELAY_NORMAL 1 /* delay slot in both cases */ -#define ARC_DELAY_JUMP 2 /* delay slot only if branch taken */ +#define ARC_DELAY_NONE 0 /* no delay slot */ +#define ARC_DELAY_NORMAL 1 /* delay slot in both cases */ +#define ARC_DELAY_JUMP 2 /* delay slot only if branch taken */ /* Non-zero if X will fit in a signed 9 bit field. */ #define ARC_SHIMM_CONST_P(x) ((long) (x) >= -256 && (long) (x) <= 255) -extern const struct arc_operand arc_operands[]; -extern const int arc_operand_count; -extern struct arc_opcode arc_opcodes[]; -extern const int arc_opcodes_count; -extern const struct arc_operand_value arc_suffixes[]; -extern const int arc_suffixes_count; -extern const struct arc_operand_value arc_reg_names[]; -extern const int arc_reg_names_count; -extern unsigned char arc_operand_map[]; +extern const struct arc_operand *arc_operands; +extern int arc_operand_count; + +extern const struct arc_operand_value *arc_suffixes; +extern int arc_suffixes_count; + +extern const struct arc_operand_value *arc_reg_names; +extern int arc_reg_names_count; + +extern unsigned char *arc_operand_map; + +/* Nonzero if we've seen a 'q' suffix (condition code). + * 'Q' FORCELIMM set `arc_cond_p' to 1 to ensure a constant is a limm */ +extern int arc_cond_p; + +extern int arc_mach_a4; +extern unsigned long arc_ld_ext_mask; +extern int arc_user_mode_only; /* Utility fns in arc-opc.c. */ int arc_get_opcode_mach (int, int); - /* `arc_opcode_init_tables' must be called before `arc_xxx_supported'. */ void arc_opcode_init_tables (int); void arc_opcode_init_insert (void); @@ -311,13 +447,22 @@ void arc_opcode_init_extract (void); const struct arc_opcode *arc_opcode_lookup_asm (const char *); const struct arc_opcode *arc_opcode_lookup_dis (unsigned int); int arc_opcode_limm_p (long *); -const struct arc_operand_value *arc_opcode_lookup_suffix - (const struct arc_operand *type, int value); +const struct arc_operand_value *arc_opcode_lookup_suffix (const struct arc_operand *type, int value); int arc_opcode_supported (const struct arc_opcode *); int arc_opval_supported (const struct arc_operand_value *); -int arc_limm_fixup_adjust (arc_insn); -int arc_insn_is_j (arc_insn); int arc_insn_not_jl (arc_insn); -int arc_operand_type (int); -struct arc_operand_value *get_ext_suffix (char *); -int arc_get_noshortcut_flag (void); + +extern char *arc_aux_reg_name (int); +extern struct arc_operand_value *get_ext_suffix (char *,char); + +extern int ac_branch_or_jump_insn (arc_insn, int); +extern int ac_lpcc_insn (arc_insn); +extern int ac_constant_operand (const struct arc_operand *); +extern int ac_register_operand (const struct arc_operand *); +extern int ac_symbol_operand (const struct arc_operand *); +extern int ARC700_register_simd_operand (char); +extern int arc_operand_type (int); +extern int ac_add_reg_sdasym_insn (arc_insn); +extern int ac_get_load_sdasym_insn_type (arc_insn, int); +extern int ac_get_store_sdasym_insn_type (arc_insn, int); +extern int arc_limm_fixup_adjust (arc_insn); diff --git a/include/opcode/cgen.h b/include/opcode/cgen.h index e8fd5d3d9..abac03e54 100644 --- a/include/opcode/cgen.h +++ b/include/opcode/cgen.h @@ -1339,7 +1339,7 @@ typedef struct cgen_cpu_desc int (* dis_hash_p) (const CGEN_INSN *); /* Disassembler hash function. */ - unsigned int (* dis_hash) (const char *, CGEN_INSN_INT); + unsigned int (* dis_hash) (const char *, CGEN_INSN_INT, int); /* Number of entries in disassembler hash table. */ unsigned int dis_hash_size; -- cgit v1.2.3