- { 'A', 9, 0, ARC_MOD_AUXREG },
-
-/* end of list place holder */
- { 0 }
-};
-\f
-/* Given a format letter, yields the index into `arc_operands'.
- eg: arc_operand_map['a'] = REGA. */
-unsigned char arc_operand_map[256];
-
-#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 */
-
-/* ARC instructions (sorted by at least the first letter, and equivalent
- opcodes kept together).
-
- By recording the insns this way, the table is not hashable on the opcode.
- That's not a real loss though as there are only a few entries for each
- insn (ld/st being the exception), which are quickly found and since
- they're stored together (eg: all `ld' variants are together) very little
- time is spent on the opcode itself. The slow part is parsing the options,
- but that's always going to be slow.
-
- Longer versions of insns must appear before shorter ones (if gas sees
- "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is
- junk).
-
- This table is best viewed on a wide screen (161 columns).
- I'd prefer to keep it this way. */
-
-/* ??? This table also includes macros: asl, lsl, and mov. The ppc port has
- a more general facility for dealing with macros which could be used if
- we need to. */
-/* ??? As an experiment, the "mov" macro appears at the start so it is
- prefered to "and" when disassembling. At present, the table needn't be
- sorted, though all opcodes with the same first letter must be kept
- together. */
-
-const struct arc_opcode arc_opcodes[] = {
- { "mac%u%.s%.q%.f %a,%b,%c%F%S%L", I(-4), I(24), ARC_MACH_AUDIO },
- /* Note that "mov" is really an "and". */
- { "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12) },
- { "mul%u%.q%.f %a,%b,%c%F%S%L", I(-2), I(28), ARC_MACH_AUDIO },
- /* ??? This insn allows an optional "0," preceding the args. */
- /* We can't use %u here because it's not a suffix (the "64" is in the way). */
- { "mul64%.q%.f %b,%c%F%S%L", I(-1)+A(-1), I(20)+A(-1), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
- { "mulu64%.q%.f %b,%c%F%S%L", I(-1)+A(-1), I(21)+A(-1), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
-
- { "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9) },
- { "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8) },
- { "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12) },
- { "asl%.q%.f %a,%b,%c%F%S%L", I(-1), I(16), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
- /* Note that "asl" is really an "add". */
- { "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
- { "asr%.q%.f %a,%b,%c%F%S%L", I(-1), I(18), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
- { "asr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(1) },
- { "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14) },
- { "b%q%.n %B", I(-1), I(4) },
- { "bl%q%.n %B", I(-1), I(5) },
- { "extb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(7) },
- { "extw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(8) },
- { "flag%.q %b%G%S%L", I(-1)+A(-1)+C(-1), I(3)+A(ARC_REG_SHIMM_UPDATE)+C(0) },
- /* %Q: force cond_p=1 --> no shimm values */
- /* ??? This insn allows an optional flags spec. */
- { "j%q%Q%.n%.f %b%J", I(-1)+A(-1)+C(-1)+R(-1,7,1), I(7)+A(0)+C(0)+R(0,7,1) },
- /* Put opcode 1 ld insns first so shimm gets prefered over limm. */
- /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */
- { "ld%Z%.X%.W%.E %0%a,[%b]%L", I(-1)+R(-1,13,1)+R(-1,0,511), I(1)+R(0,13,1)+R(0,0,511) },
- { "ld%Z%.X%.W%.E %a,[%b,%d]%S%L", I(-1)+R(-1,13,1), I(1)+R(0,13,1) },
- { "ld%z%.x%.w%.e %a,[%b,%c]", I(-1)+R(-1,4,1)+R(-1,6,7), I(0)+R(0,4,1)+R(0,6,7) },
- { "lp%q%.n %B", I(-1), I(6), },
- { "lr %a,[%Ab]%S%L", I(-1)+C(-1), I(1)+C(0x10) },
- /* Note that "lsl" is really an "add". */
- { "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) },
- { "lsr%.q%.f %a,%b,%c%F%S%L", I(-1), I(17), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
- { "lsr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(2) },
- /* Note that "nop" is really an "xor". */
- { "nop", 0xffffffff, 0x7fffffff },
- { "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13) },
- /* ??? The %a here should be %p or something. */
- { "padc%.q%.f %a,%b,%c%F%S%L", I(-1), I(25), ARC_MACH_GRAPHICS },
- { "padd%.q%.f %a,%b,%c%F%S%L", I(-1), I(24), ARC_MACH_GRAPHICS },
- /* Note that "pmov" is really a "pand". */
- { "pmov%.q%.f %a,%b%F%S%L%U", I(-1), I(28), ARC_MACH_GRAPHICS },
- { "pand%.q%.f %a,%b,%c%F%S%L", I(-1), I(28), ARC_MACH_GRAPHICS },
- { "psbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(27), ARC_MACH_GRAPHICS },
- { "psub%.q%.f %a,%b,%c%F%S%L", I(-1), I(26), ARC_MACH_GRAPHICS },
- /* Note that "rlc" is really an "adc". */
- { "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9) },
- { "ror%.q%.f %a,%b,%c%F%S%L", I(-1), I(19), ARC_MACH_HOST+ARC_MACH_GRAPHICS },
- { "ror%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(3) },
- { "rrc%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(4) },
- { "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11) },
- { "sexb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(5) },
- { "sexw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(6) },
- { "sr %c,[%Ab]%S%L", I(-1)+A(-1), I(2)+A(0x10) },
- /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */
- { "st%y%.v%.D %0%c,[%b]%L", I(-1)+R(-1,25,3)+R(-1,21,1)+R(-1,0,511), I(2)+R(0,25,3)+R(0,21,1)+R(0,0,511) },
- { "st%y%.v%.D %c,[%b,%d]%S%L", I(-1)+R(-1,25,3)+R(-1,21,1), I(2)+R(0,25,3)+R(0,21,1) },
- { "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10) },
- { "swap%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(9), ARC_MACH_AUDIO },
- { "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15) }
-};
-const int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
-
-const struct arc_operand_value arc_reg_names[] =
-{
- /* Sort this so that the first 61 entries are sequential.
- IE: For each i (i<61), arc_reg_names[i].value == i. */
-
- { "r0", 0, REG }, { "r1", 1, REG }, { "r2", 2, REG }, { "r3", 3, REG },
- { "r4", 4, REG }, { "r5", 5, REG }, { "r6", 6, REG }, { "r7", 7, REG },
- { "r8", 8, REG }, { "r9", 9, REG }, { "r10", 10, REG }, { "r11", 11, REG },
- { "r12", 12, REG }, { "r13", 13, REG }, { "r14", 14, REG }, { "r15", 15, REG },
- { "r16", 16, REG }, { "r17", 17, REG }, { "r18", 18, REG }, { "r19", 19, REG },
- { "r20", 20, REG }, { "r21", 21, REG }, { "r22", 22, REG }, { "r23", 23, REG },
- { "r24", 24, REG }, { "r25", 25, REG }, { "r26", 26, REG }, { "fp", 27, REG },
- { "sp", 28, REG }, { "ilink1", 29, REG }, { "ilink2", 30, REG }, { "blink", 31, REG },
- { "r32", 32, REG }, { "r33", 33, REG }, { "r34", 34, REG }, { "r35", 35, REG },
- { "r36", 36, REG }, { "r37", 37, REG }, { "r38", 38, REG }, { "r39", 39, REG },
- { "r40", 40, REG }, { "r41", 41, REG }, { "r42", 42, REG }, { "r43", 43, REG },
- { "r44", 44, REG }, { "r45", 45, REG }, { "r46", 46, REG }, { "r47", 47, REG },
- { "r48", 48, REG }, { "r49", 49, REG }, { "r50", 50, REG }, { "r51", 51, REG },
- { "r52", 52, REG }, { "r53", 53, REG }, { "r54", 54, REG }, { "r55", 55, REG },
- { "r56", 56, REG }, { "r57", 57, REG }, { "r58", 58, REG }, { "r59", 59, REG },
- { "lp_count", 60, REG },
-
- /* I'd prefer to output these as "fp" and "sp" by default, but we still need
- to recognize the canonical values. */
- { "r27", 27, REG }, { "r28", 28, REG },
-
- /* Standard auxiliary registers. */
- { "status", 0, AUXREG },
- { "semaphore", 1, AUXREG },
- { "lp_start", 2, AUXREG },
- { "lp_end", 3, AUXREG },
- { "identity", 4, AUXREG },
- { "debug", 5, AUXREG },
-
- /* Host ARC Extensions. */
- { "mlo", 57, REG, ARC_MACH_HOST },
- { "mmid", 58, REG, ARC_MACH_HOST },
- { "mhi", 59, REG, ARC_MACH_HOST },
- { "ivic", 0x10, AUXREG, ARC_MACH_HOST },
- { "ivdc", 0x11, AUXREG, ARC_MACH_HOST },
- { "ivdcn", 0x12, AUXREG, ARC_MACH_HOST },
- { "flushd", 0x13, AUXREG, ARC_MACH_HOST },
- { "saha", 0x14, AUXREG, ARC_MACH_HOST },
- { "gahd", 0x15, AUXREG, ARC_MACH_HOST },
- { "aahd", 0x16, AUXREG, ARC_MACH_HOST },
- { "rrcr", 0x17, AUXREG, ARC_MACH_HOST },
- { "rpcr", 0x18, AUXREG, ARC_MACH_HOST },
- { "flushdn", 0x19, AUXREG, ARC_MACH_HOST },
- { "dbgad1", 0x1a, AUXREG, ARC_MACH_HOST },
- { "dbgad2", 0x1b, AUXREG, ARC_MACH_HOST },
- { "dbgmde", 0x1c, AUXREG, ARC_MACH_HOST },
- { "dbgstat", 0x1d, AUXREG, ARC_MACH_HOST },
- { "wag", 0x1e, AUXREG, ARC_MACH_HOST },
- { "mulhi", 0x1f, AUXREG, ARC_MACH_HOST },
- { "intwide", 0x20, AUXREG, ARC_MACH_HOST },
- { "intgen", 0x21, AUXREG, ARC_MACH_HOST },
- { "rfsh_n", 0x22, AUXREG, ARC_MACH_HOST },
-
- /* Graphics ARC Extensions. */
- { "mlo", 57, REG, ARC_MACH_GRAPHICS },
- { "mmid", 58, REG, ARC_MACH_GRAPHICS },
- { "mhi", 59, REG, ARC_MACH_GRAPHICS },
- { "ivic", 0x10, AUXREG, ARC_MACH_GRAPHICS },
- { "wag", 0x1e, AUXREG, ARC_MACH_GRAPHICS },
- { "mulhi", 0x1f, AUXREG, ARC_MACH_GRAPHICS },
- { "intwide", 0x20, AUXREG, ARC_MACH_GRAPHICS },
- { "intgen", 0x21, AUXREG, ARC_MACH_GRAPHICS },
- { "pix", 0x100, AUXREG, ARC_MACH_GRAPHICS },
- { "scratch", 0x120, AUXREG, ARC_MACH_GRAPHICS },
-
- /* Audio ARC Extensions. */
- { "macmode", 39, REG, ARC_MACH_AUDIO },
- { "rs1", 40, REG, ARC_MACH_AUDIO },
- { "rs1n", 41, REG, ARC_MACH_AUDIO },
- { "rs1start", 42, REG, ARC_MACH_AUDIO },
- { "rs1size", 43, REG, ARC_MACH_AUDIO },
- { "rs1delta", 44, REG, ARC_MACH_AUDIO },
- { "rs1pos", 45, REG, ARC_MACH_AUDIO },
- { "rd1", 46, REG, ARC_MACH_AUDIO },
- { "rd1n", 47, REG, ARC_MACH_AUDIO },
- { "rd1d", 48, REG, ARC_MACH_AUDIO },
- { "rd1pos", 49, REG, ARC_MACH_AUDIO },
- { "rs2", 50, REG, ARC_MACH_AUDIO },
- { "rs2n", 51, REG, ARC_MACH_AUDIO },
- { "rs2start", 52, REG, ARC_MACH_AUDIO },
- { "rs2size", 53, REG, ARC_MACH_AUDIO },
- { "rs2delta", 54, REG, ARC_MACH_AUDIO },
- { "rs2pos", 55, REG, ARC_MACH_AUDIO },
- { "rd2", 56, REG, ARC_MACH_AUDIO },
- { "rd2n", 57, REG, ARC_MACH_AUDIO },
- { "rd2d", 58, REG, ARC_MACH_AUDIO },
- { "rd2pos", 59, REG, ARC_MACH_AUDIO },
- { "ivic", 0x10, AUXREG, ARC_MACH_AUDIO },
- { "wag", 0x1e, AUXREG, ARC_MACH_AUDIO },
- { "intwide", 0x20, AUXREG, ARC_MACH_AUDIO },
- { "intgen", 0x21, AUXREG, ARC_MACH_AUDIO },
- { "bm_sstart", 0x30, AUXREG, ARC_MACH_AUDIO },
- { "bm_length", 0x31, AUXREG, ARC_MACH_AUDIO },
- { "bm_rstart", 0x32, AUXREG, ARC_MACH_AUDIO },
- { "bm_go", 0x33, AUXREG, ARC_MACH_AUDIO },
- { "xtp_newval", 0x40, AUXREG, ARC_MACH_AUDIO },
- { "sram", 0x400, AUXREG, ARC_MACH_AUDIO },
- { "reg_file", 0x800, AUXREG, ARC_MACH_AUDIO },
-};
-const int arc_reg_names_count = sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
-
-/* The suffix table.
- Operands with the same name must be stored together. */