arc-opc.c revision 1.1.1.1
1/* Opcode table for the ARC. 2 Copyright (c) 1994, 1995, 1997, 1998 Free Software Foundation, Inc. 3 Contributed by Doug Evans (dje@cygnus.com). 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 2, or (at your option) 8 any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program; if not, write to the Free Software 17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ 18 19#include <stdio.h> 20#include "sysdep.h" 21#include "opcode/arc.h" 22#include "opintl.h" 23 24#ifndef NULL 25#define NULL 0 26#endif 27 28#define INSERT_FN(fn) \ 29static arc_insn fn PARAMS ((arc_insn, const struct arc_operand *, \ 30 int, const struct arc_operand_value *, long, \ 31 const char **)) 32#define EXTRACT_FN(fn) \ 33static long fn PARAMS ((arc_insn *, const struct arc_operand *, \ 34 int, const struct arc_operand_value **, int *)) 35 36INSERT_FN (insert_reg); 37INSERT_FN (insert_shimmfinish); 38INSERT_FN (insert_limmfinish); 39INSERT_FN (insert_shimmoffset); 40INSERT_FN (insert_shimmzero); 41INSERT_FN (insert_flag); 42INSERT_FN (insert_flagfinish); 43INSERT_FN (insert_cond); 44INSERT_FN (insert_forcelimm); 45INSERT_FN (insert_reladdr); 46INSERT_FN (insert_absaddr); 47INSERT_FN (insert_unopmacro); 48 49EXTRACT_FN (extract_reg); 50EXTRACT_FN (extract_flag); 51EXTRACT_FN (extract_cond); 52EXTRACT_FN (extract_reladdr); 53EXTRACT_FN (extract_unopmacro); 54 55/* Various types of ARC operands, including insn suffixes. */ 56 57/* Insn format values: 58 59 'a' REGA register A field 60 'b' REGB register B field 61 'c' REGC register C field 62 'S' SHIMMFINISH finish inserting a shimm value 63 'L' LIMMFINISH finish inserting a limm value 64 'd' SHIMMOFFSET shimm offset in ld,st insns 65 '0' SHIMMZERO 0 shimm value in ld,st insns 66 'f' FLAG F flag 67 'F' FLAGFINISH finish inserting the F flag 68 'G' FLAGINSN insert F flag in "flag" insn 69 'n' DELAY N field (nullify field) 70 'q' COND condition code field 71 'Q' FORCELIMM set `cond_p' to 1 to ensure a constant is a limm 72 'B' BRANCH branch address (22 bit pc relative) 73 'J' JUMP jump address (26 bit absolute) 74 'z' SIZE1 size field in ld a,[b,c] 75 'Z' SIZE10 size field in ld a,[b,shimm] 76 'y' SIZE22 size field in st c,[b,shimm] 77 'x' SIGN0 sign extend field ld a,[b,c] 78 'X' SIGN9 sign extend field ld a,[b,shimm] 79 'w' ADDRESS3 write-back field in ld a,[b,c] 80 'W' ADDRESS12 write-back field in ld a,[b,shimm] 81 'v' ADDRESS24 write-back field in st c,[b,shimm] 82 'e' CACHEBYPASS5 cache bypass in ld a,[b,c] 83 'E' CACHEBYPASS14 cache bypass in ld a,[b,shimm] 84 'D' CACHEBYPASS26 cache bypass in st c,[b,shimm] 85 'U' UNOPMACRO fake operand to copy REGB to REGC for unop macros 86 87 The following modifiers may appear between the % and char (eg: %.f): 88 89 '.' MODDOT '.' prefix must be present 90 'r' REG generic register value, for register table 91 'A' AUXREG auxiliary register in lr a,[b], sr c,[b] 92 93 Fields are: 94 95 CHAR BITS SHIFT FLAGS INSERT_FN EXTRACT_FN 96*/ 97 98const struct arc_operand arc_operands[] = 99{ 100/* place holder (??? not sure if needed) */ 101#define UNUSED 0 102 { 0 }, 103 104/* register A or shimm/limm indicator */ 105#define REGA (UNUSED + 1) 106 { 'a', 6, ARC_SHIFT_REGA, ARC_OPERAND_SIGNED, insert_reg, extract_reg }, 107 108/* register B or shimm/limm indicator */ 109#define REGB (REGA + 1) 110 { 'b', 6, ARC_SHIFT_REGB, ARC_OPERAND_SIGNED, insert_reg, extract_reg }, 111 112/* register C or shimm/limm indicator */ 113#define REGC (REGB + 1) 114 { 'c', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED, insert_reg, extract_reg }, 115 116/* fake operand used to insert shimm value into most instructions */ 117#define SHIMMFINISH (REGC + 1) 118 { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish, 0 }, 119 120/* fake operand used to insert limm value into most instructions. */ 121#define LIMMFINISH (SHIMMFINISH + 1) 122 { 'L', 32, 32, ARC_OPERAND_ADDRESS + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE, insert_limmfinish, 0 }, 123 124/* shimm operand when there is no reg indicator (ld,st) */ 125#define SHIMMOFFSET (LIMMFINISH + 1) 126 { 'd', 9, 0, ARC_OPERAND_SIGNED, insert_shimmoffset, 0 }, 127 128/* 0 shimm operand for ld,st insns */ 129#define SHIMMZERO (SHIMMOFFSET + 1) 130 { '0', 9, 0, ARC_OPERAND_FAKE, insert_shimmzero, 0 }, 131 132/* flag update bit (insertion is defered until we know how) */ 133#define FLAG (SHIMMZERO + 1) 134 { 'f', 1, 8, ARC_OPERAND_SUFFIX, insert_flag, extract_flag }, 135 136/* fake utility operand to finish 'f' suffix handling */ 137#define FLAGFINISH (FLAG + 1) 138 { 'F', 1, 8, ARC_OPERAND_FAKE, insert_flagfinish, 0 }, 139 140/* fake utility operand to set the 'f' flag for the "flag" insn */ 141#define FLAGINSN (FLAGFINISH + 1) 142 { 'G', 1, 8, ARC_OPERAND_FAKE, insert_flag, 0 }, 143 144/* branch delay types */ 145#define DELAY (FLAGINSN + 1) 146 { 'n', 2, 5, ARC_OPERAND_SUFFIX }, 147 148/* conditions */ 149#define COND (DELAY + 1) 150 { 'q', 5, 0, ARC_OPERAND_SUFFIX, insert_cond, extract_cond }, 151 152/* set `cond_p' to 1 to ensure a constant is treated as a limm */ 153#define FORCELIMM (COND + 1) 154 { 'Q', 0, 0, ARC_OPERAND_FAKE, insert_forcelimm }, 155 156/* branch address; b, bl, and lp insns */ 157#define BRANCH (FORCELIMM + 1) 158 { 'B', 20, 7, ARC_OPERAND_RELATIVE_BRANCH + ARC_OPERAND_SIGNED, insert_reladdr, extract_reladdr }, 159 160/* jump address; j insn (this is basically the same as 'L' except that the 161 value is right shifted by 2) */ 162#define JUMP (BRANCH + 1) 163 { 'J', 24, 32, ARC_OPERAND_ABSOLUTE_BRANCH + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE, insert_absaddr }, 164 165/* size field, stored in bit 1,2 */ 166#define SIZE1 (JUMP + 1) 167 { 'z', 2, 1, ARC_OPERAND_SUFFIX }, 168 169/* size field, stored in bit 10,11 */ 170#define SIZE10 (SIZE1 + 1) 171 { 'Z', 2, 10, ARC_OPERAND_SUFFIX, }, 172 173/* size field, stored in bit 22,23 */ 174#define SIZE22 (SIZE10 + 1) 175 { 'y', 2, 22, ARC_OPERAND_SUFFIX, }, 176 177/* sign extend field, stored in bit 0 */ 178#define SIGN0 (SIZE22 + 1) 179 { 'x', 1, 0, ARC_OPERAND_SUFFIX }, 180 181/* sign extend field, stored in bit 9 */ 182#define SIGN9 (SIGN0 + 1) 183 { 'X', 1, 9, ARC_OPERAND_SUFFIX }, 184 185/* address write back, stored in bit 3 */ 186#define ADDRESS3 (SIGN9 + 1) 187 { 'w', 1, 3, ARC_OPERAND_SUFFIX }, 188 189/* address write back, stored in bit 12 */ 190#define ADDRESS12 (ADDRESS3 + 1) 191 { 'W', 1, 12, ARC_OPERAND_SUFFIX }, 192 193/* address write back, stored in bit 24 */ 194#define ADDRESS24 (ADDRESS12 + 1) 195 { 'v', 1, 24, ARC_OPERAND_SUFFIX }, 196 197/* cache bypass, stored in bit 5 */ 198#define CACHEBYPASS5 (ADDRESS24 + 1) 199 { 'e', 1, 5, ARC_OPERAND_SUFFIX }, 200 201/* cache bypass, stored in bit 14 */ 202#define CACHEBYPASS14 (CACHEBYPASS5 + 1) 203 { 'E', 1, 14, ARC_OPERAND_SUFFIX }, 204 205/* cache bypass, stored in bit 26 */ 206#define CACHEBYPASS26 (CACHEBYPASS14 + 1) 207 { 'D', 1, 26, ARC_OPERAND_SUFFIX }, 208 209/* unop macro, used to copy REGB to REGC */ 210#define UNOPMACRO (CACHEBYPASS26 + 1) 211 { 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro }, 212 213/* '.' modifier ('.' required). */ 214#define MODDOT (UNOPMACRO + 1) 215 { '.', 1, 0, ARC_MOD_DOT }, 216 217/* Dummy 'r' modifier for the register table. 218 It's called a "dummy" because there's no point in inserting an 'r' into all 219 the %a/%b/%c occurrences in the insn table. */ 220#define REG (MODDOT + 1) 221 { 'r', 6, 0, ARC_MOD_REG }, 222 223/* Known auxiliary register modifier (stored in shimm field). */ 224#define AUXREG (REG + 1) 225 { 'A', 9, 0, ARC_MOD_AUXREG }, 226 227/* end of list place holder */ 228 { 0 } 229}; 230 231/* Given a format letter, yields the index into `arc_operands'. 232 eg: arc_operand_map['a'] = REGA. */ 233unsigned char arc_operand_map[256]; 234 235#define I(x) (((x) & 31) << 27) 236#define A(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGA) 237#define B(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGB) 238#define C(x) (((x) & ARC_MASK_REG) << ARC_SHIFT_REGC) 239#define R(x,b,m) (((x) & (m)) << (b)) /* value X, mask M, at bit B */ 240 241/* ARC instructions. 242 243 Longer versions of insns must appear before shorter ones (if gas sees 244 "lsr r2,r3,1" when it's parsing "lsr %a,%b" it will think the ",1" is 245 junk). This isn't necessary for `ld' because of the trailing ']'. 246 247 Instructions that are really macros based on other insns must appear 248 before the real insn so they're chosen when disassembling. Eg: The `mov' 249 insn is really the `and' insn. 250 251 This table is best viewed on a wide screen (161 columns). I'd prefer to 252 keep it this way. The rest of the file, however, should be viewable on an 253 80 column terminal. */ 254 255/* ??? This table also includes macros: asl, lsl, and mov. The ppc port has 256 a more general facility for dealing with macros which could be used if 257 we need to. */ 258 259/* This table can't be `const' because members `next_asm' and `next_dis' are 260 computed at run-time. We could split this into two, but that doesn't seem 261 worth it. */ 262 263struct arc_opcode arc_opcodes[] = { 264 265 /* Macros appear first. */ 266 /* "mov" is really an "and". */ 267 { "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12) }, 268 /* "asl" is really an "add". */ 269 { "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) }, 270 /* "lsl" is really an "add". */ 271 { "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8) }, 272 /* "nop" is really an "xor". */ 273 { "nop", 0xffffffff, 0x7fffffff }, 274 /* "rlc" is really an "adc". */ 275 { "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9) }, 276 277 /* The rest of these needn't be sorted, but it helps to find them if they are. */ 278 { "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9) }, 279 { "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8) }, 280 { "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12) }, 281 { "asr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(1) }, 282 { "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14) }, 283 { "b%q%.n %B", I(-1), I(4), ARC_OPCODE_COND_BRANCH }, 284 { "bl%q%.n %B", I(-1), I(5), ARC_OPCODE_COND_BRANCH }, 285 { "extb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(7) }, 286 { "extw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(8) }, 287 { "flag%.q %b%G%S%L", I(-1)+A(-1)+C(-1), I(3)+A(ARC_REG_SHIMM_UPDATE)+C(0) }, 288 /* %Q: force cond_p=1 --> no shimm values */ 289 /* ??? This insn allows an optional flags spec. */ 290 { "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) }, 291 /* Put opcode 1 ld insns first so shimm gets prefered over limm. */ 292 /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */ 293 { "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) }, 294 { "ld%Z%.X%.W%.E %a,[%b,%d]%S%L", I(-1)+R(-1,13,1), I(1)+R(0,13,1) }, 295 { "ld%z%.x%.w%.e%Q %a,[%b,%c]%L", I(-1)+R(-1,4,1)+R(-1,6,7), I(0)+R(0,4,1)+R(0,6,7) }, 296 { "lp%q%.n %B", I(-1), I(6), }, 297 { "lr %a,[%Ab]%S%L", I(-1)+C(-1), I(1)+C(0x10) }, 298 { "lsr%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(2) }, 299 { "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13) }, 300 { "ror%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(3) }, 301 { "rrc%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(4) }, 302 { "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11) }, 303 { "sexb%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(5) }, 304 { "sexw%.q%.f %a,%b%F%S%L", I(-1)+C(-1), I(3)+C(6) }, 305 { "sr %c,[%Ab]%S%L", I(-1)+A(-1), I(2)+A(0x10) }, 306 /* "[%b]" is before "[%b,%d]" so 0 offsets don't get printed. */ 307 { "st%y%.v%.D%Q %0%c,[%b]%L", I(-1)+R(-1,25,1)+R(-1,21,1)+R(-1,0,511), I(2)+R(0,25,1)+R(0,21,1)+R(0,0,511) }, 308 { "st%y%.v%.D %c,[%b,%d]%S%L", I(-1)+R(-1,25,1)+R(-1,21,1), I(2)+R(0,25,1)+R(0,21,1) }, 309 { "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10) }, 310 { "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15) } 311}; 312const int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]); 313 314const struct arc_operand_value arc_reg_names[] = 315{ 316 /* Sort this so that the first 61 entries are sequential. 317 IE: For each i (i<61), arc_reg_names[i].value == i. */ 318 319 { "r0", 0, REG }, { "r1", 1, REG }, { "r2", 2, REG }, { "r3", 3, REG }, 320 { "r4", 4, REG }, { "r5", 5, REG }, { "r6", 6, REG }, { "r7", 7, REG }, 321 { "r8", 8, REG }, { "r9", 9, REG }, { "r10", 10, REG }, { "r11", 11, REG }, 322 { "r12", 12, REG }, { "r13", 13, REG }, { "r14", 14, REG }, { "r15", 15, REG }, 323 { "r16", 16, REG }, { "r17", 17, REG }, { "r18", 18, REG }, { "r19", 19, REG }, 324 { "r20", 20, REG }, { "r21", 21, REG }, { "r22", 22, REG }, { "r23", 23, REG }, 325 { "r24", 24, REG }, { "r25", 25, REG }, { "r26", 26, REG }, { "fp", 27, REG }, 326 { "sp", 28, REG }, { "ilink1", 29, REG }, { "ilink2", 30, REG }, { "blink", 31, REG }, 327 { "r32", 32, REG }, { "r33", 33, REG }, { "r34", 34, REG }, { "r35", 35, REG }, 328 { "r36", 36, REG }, { "r37", 37, REG }, { "r38", 38, REG }, { "r39", 39, REG }, 329 { "r40", 40, REG }, { "r41", 41, REG }, { "r42", 42, REG }, { "r43", 43, REG }, 330 { "r44", 44, REG }, { "r45", 45, REG }, { "r46", 46, REG }, { "r47", 47, REG }, 331 { "r48", 48, REG }, { "r49", 49, REG }, { "r50", 50, REG }, { "r51", 51, REG }, 332 { "r52", 52, REG }, { "r53", 53, REG }, { "r54", 54, REG }, { "r55", 55, REG }, 333 { "r56", 56, REG }, { "r57", 57, REG }, { "r58", 58, REG }, { "r59", 59, REG }, 334 { "lp_count", 60, REG }, 335 336 /* I'd prefer to output these as "fp" and "sp" by default, but we still need 337 to recognize the canonical values. */ 338 { "r27", 27, REG }, { "r28", 28, REG }, 339 340 /* Someone may wish to refer to these in this way, and it's probably a 341 good idea to reserve them as such anyway. */ 342 { "r29", 29, REG }, { "r30", 30, REG }, { "r31", 31, REG }, { "r60", 60, REG }, 343 344 /* Standard auxiliary registers. */ 345 { "status", 0, AUXREG }, 346 { "semaphore", 1, AUXREG }, 347 { "lp_start", 2, AUXREG }, 348 { "lp_end", 3, AUXREG }, 349 { "identity", 4, AUXREG }, 350 { "debug", 5, AUXREG }, 351}; 352const int arc_reg_names_count = sizeof (arc_reg_names) / sizeof (arc_reg_names[0]); 353 354/* The suffix table. 355 Operands with the same name must be stored together. */ 356 357const struct arc_operand_value arc_suffixes[] = 358{ 359 /* Entry 0 is special, default values aren't printed by the disassembler. */ 360 { "", 0, -1 }, 361 { "al", 0, COND }, 362 { "ra", 0, COND }, 363 { "eq", 1, COND }, 364 { "z", 1, COND }, 365 { "ne", 2, COND }, 366 { "nz", 2, COND }, 367 { "p", 3, COND }, 368 { "pl", 3, COND }, 369 { "n", 4, COND }, 370 { "mi", 4, COND }, 371 { "c", 5, COND }, 372 { "cs", 5, COND }, 373 { "lo", 5, COND }, 374 { "nc", 6, COND }, 375 { "cc", 6, COND }, 376 { "hs", 6, COND }, 377 { "v", 7, COND }, 378 { "vs", 7, COND }, 379 { "nv", 8, COND }, 380 { "vc", 8, COND }, 381 { "gt", 9, COND }, 382 { "ge", 10, COND }, 383 { "lt", 11, COND }, 384 { "le", 12, COND }, 385 { "hi", 13, COND }, 386 { "ls", 14, COND }, 387 { "pnz", 15, COND }, 388 { "f", 1, FLAG }, 389 { "nd", ARC_DELAY_NONE, DELAY }, 390 { "d", ARC_DELAY_NORMAL, DELAY }, 391 { "jd", ARC_DELAY_JUMP, DELAY }, 392/*{ "b", 7, SIZEEXT },*/ 393/*{ "b", 5, SIZESEX },*/ 394 { "b", 1, SIZE1 }, 395 { "b", 1, SIZE10 }, 396 { "b", 1, SIZE22 }, 397/*{ "w", 8, SIZEEXT },*/ 398/*{ "w", 6, SIZESEX },*/ 399 { "w", 2, SIZE1 }, 400 { "w", 2, SIZE10 }, 401 { "w", 2, SIZE22 }, 402 { "x", 1, SIGN0 }, 403 { "x", 1, SIGN9 }, 404 { "a", 1, ADDRESS3 }, 405 { "a", 1, ADDRESS12 }, 406 { "a", 1, ADDRESS24 }, 407 { "di", 1, CACHEBYPASS5 }, 408 { "di", 1, CACHEBYPASS14 }, 409 { "di", 1, CACHEBYPASS26 }, 410}; 411const int arc_suffixes_count = sizeof (arc_suffixes) / sizeof (arc_suffixes[0]); 412 413/* Indexed by first letter of opcode. Points to chain of opcodes with same 414 first letter. */ 415static struct arc_opcode *opcode_map[26 + 1]; 416 417/* Indexed by insn code. Points to chain of opcodes with same insn code. */ 418static struct arc_opcode *icode_map[32]; 419 420/* Configuration flags. */ 421 422/* Various ARC_HAVE_XXX bits. */ 423static int cpu_type; 424 425/* Translate a bfd_mach_arc_xxx value to a ARC_MACH_XXX value. */ 426 427int 428arc_get_opcode_mach (bfd_mach, big_p) 429 int bfd_mach, big_p; 430{ 431 static int mach_type_map[] = 432 { 433 ARC_MACH_BASE 434 }; 435 436 return mach_type_map[bfd_mach] | (big_p ? ARC_MACH_BIG : 0); 437} 438 439/* Initialize any tables that need it. 440 Must be called once at start up (or when first needed). 441 442 FLAGS is a set of bits that say what version of the cpu we have, 443 and in particular at least (one of) ARC_MACH_XXX. */ 444 445void 446arc_opcode_init_tables (flags) 447 int flags; 448{ 449 static int init_p = 0; 450 451 cpu_type = flags; 452 453 /* We may be intentionally called more than once (for example gdb will call 454 us each time the user switches cpu). These tables only need to be init'd 455 once though. */ 456 /* ??? We can remove the need for arc_opcode_supported by taking it into 457 account here, but I'm not sure I want to do that yet (if ever). */ 458 if (!init_p) 459 { 460 register int i,n; 461 462 memset (arc_operand_map, 0, sizeof (arc_operand_map)); 463 n = sizeof (arc_operands) / sizeof (arc_operands[0]); 464 for (i = 0; i < n; ++i) 465 arc_operand_map[arc_operands[i].fmt] = i; 466 467 memset (opcode_map, 0, sizeof (opcode_map)); 468 memset (icode_map, 0, sizeof (icode_map)); 469 /* Scan the table backwards so macros appear at the front. */ 470 for (i = arc_opcodes_count - 1; i >= 0; --i) 471 { 472 int opcode_hash = ARC_HASH_OPCODE (arc_opcodes[i].syntax); 473 int icode_hash = ARC_HASH_ICODE (arc_opcodes[i].value); 474 475 arc_opcodes[i].next_asm = opcode_map[opcode_hash]; 476 opcode_map[opcode_hash] = &arc_opcodes[i]; 477 478 arc_opcodes[i].next_dis = icode_map[icode_hash]; 479 icode_map[icode_hash] = &arc_opcodes[i]; 480 } 481 482 init_p = 1; 483 } 484} 485 486/* Return non-zero if OPCODE is supported on the specified cpu. 487 Cpu selection is made when calling `arc_opcode_init_tables'. */ 488 489int 490arc_opcode_supported (opcode) 491 const struct arc_opcode *opcode; 492{ 493 if (ARC_OPCODE_CPU (opcode->flags) == 0) 494 return 1; 495 if (ARC_OPCODE_CPU (opcode->flags) & ARC_HAVE_CPU (cpu_type)) 496 return 1; 497 return 0; 498} 499 500/* Return non-zero if OPVAL is supported on the specified cpu. 501 Cpu selection is made when calling `arc_opcode_init_tables'. */ 502 503int 504arc_opval_supported (opval) 505 const struct arc_operand_value *opval; 506{ 507 if (ARC_OPVAL_CPU (opval->flags) == 0) 508 return 1; 509 if (ARC_OPVAL_CPU (opval->flags) & ARC_HAVE_CPU (cpu_type)) 510 return 1; 511 return 0; 512} 513 514/* Return the first insn in the chain for assembling INSN. */ 515 516const struct arc_opcode * 517arc_opcode_lookup_asm (insn) 518 const char *insn; 519{ 520 return opcode_map[ARC_HASH_OPCODE (insn)]; 521} 522 523/* Return the first insn in the chain for disassembling INSN. */ 524 525const struct arc_opcode * 526arc_opcode_lookup_dis (insn) 527 unsigned int insn; 528{ 529 return icode_map[ARC_HASH_ICODE (insn)]; 530} 531 532/* Nonzero if we've seen an 'f' suffix (in certain insns). */ 533static int flag_p; 534 535/* Nonzero if we've finished processing the 'f' suffix. */ 536static int flagshimm_handled_p; 537 538/* Nonzero if we've seen a 'q' suffix (condition code). */ 539static int cond_p; 540 541/* Nonzero if we've inserted a shimm. */ 542static int shimm_p; 543 544/* The value of the shimm we inserted (each insn only gets one but it can 545 appear multiple times. */ 546static int shimm; 547 548/* Nonzero if we've inserted a limm (during assembly) or seen a limm 549 (during disassembly). */ 550static int limm_p; 551 552/* The value of the limm we inserted. Each insn only gets one but it can 553 appear multiple times. */ 554static long limm; 555 556/* Insertion functions. */ 557 558/* Called by the assembler before parsing an instruction. */ 559 560void 561arc_opcode_init_insert () 562{ 563 flag_p = 0; 564 flagshimm_handled_p = 0; 565 cond_p = 0; 566 shimm_p = 0; 567 limm_p = 0; 568} 569 570/* Called by the assembler to see if the insn has a limm operand. 571 Also called by the disassembler to see if the insn contains a limm. */ 572 573int 574arc_opcode_limm_p (limmp) 575 long *limmp; 576{ 577 if (limmp) 578 *limmp = limm; 579 return limm_p; 580} 581 582/* Insert a value into a register field. 583 If REG is NULL, then this is actually a constant. 584 585 We must also handle auxiliary registers for lr/sr insns. */ 586 587static arc_insn 588insert_reg (insn, operand, mods, reg, value, errmsg) 589 arc_insn insn; 590 const struct arc_operand *operand; 591 int mods; 592 const struct arc_operand_value *reg; 593 long value; 594 const char **errmsg; 595{ 596 static char buf[100]; 597 598 if (reg == NULL) 599 { 600 /* We have a constant that also requires a value stored in a register 601 field. Handle these by updating the register field and saving the 602 value for later handling by either %S (shimm) or %L (limm). */ 603 604 /* Try to use a shimm value before a limm one. */ 605 if (ARC_SHIMM_CONST_P (value) 606 /* If we've seen a conditional suffix we have to use a limm. */ 607 && !cond_p 608 /* If we already have a shimm value that is different than ours 609 we have to use a limm. */ 610 && (!shimm_p || shimm == value)) 611 { 612 int marker = flag_p ? ARC_REG_SHIMM_UPDATE : ARC_REG_SHIMM; 613 flagshimm_handled_p = 1; 614 shimm_p = 1; 615 shimm = value; 616 insn |= marker << operand->shift; 617 /* insn |= value & 511; - done later */ 618 } 619 /* We have to use a limm. If we've already seen one they must match. */ 620 else if (!limm_p || limm == value) 621 { 622 limm_p = 1; 623 limm = value; 624 insn |= ARC_REG_LIMM << operand->shift; 625 /* The constant is stored later. */ 626 } 627 else 628 { 629 *errmsg = _("unable to fit different valued constants into instruction"); 630 } 631 } 632 else 633 { 634 /* We have to handle both normal and auxiliary registers. */ 635 636 if (reg->type == AUXREG) 637 { 638 if (!(mods & ARC_MOD_AUXREG)) 639 *errmsg = _("auxiliary register not allowed here"); 640 else 641 { 642 insn |= ARC_REG_SHIMM << operand->shift; 643 insn |= reg->value << arc_operands[reg->type].shift; 644 } 645 } 646 else 647 { 648 /* We should never get an invalid register number here. */ 649 if ((unsigned int) reg->value > 60) 650 { 651 /* xgettext:c-format */ 652 sprintf (buf, _("invalid register number `%d'"), reg->value); 653 *errmsg = buf; 654 } 655 else 656 insn |= reg->value << operand->shift; 657 } 658 } 659 660 return insn; 661} 662 663/* Called when we see an 'f' flag. */ 664 665static arc_insn 666insert_flag (insn, operand, mods, reg, value, errmsg) 667 arc_insn insn; 668 const struct arc_operand *operand; 669 int mods; 670 const struct arc_operand_value *reg; 671 long value; 672 const char **errmsg; 673{ 674 /* We can't store anything in the insn until we've parsed the registers. 675 Just record the fact that we've got this flag. `insert_reg' will use it 676 to store the correct value (ARC_REG_SHIMM_UPDATE or bit 0x100). */ 677 flag_p = 1; 678 679 return insn; 680} 681 682/* Called after completely building an insn to ensure the 'f' flag gets set 683 properly. This is needed because we don't know how to set this flag until 684 we've parsed the registers. */ 685 686static arc_insn 687insert_flagfinish (insn, operand, mods, reg, value, errmsg) 688 arc_insn insn; 689 const struct arc_operand *operand; 690 int mods; 691 const struct arc_operand_value *reg; 692 long value; 693 const char **errmsg; 694{ 695 if (flag_p && !flagshimm_handled_p) 696 { 697 if (shimm_p) 698 abort (); 699 flagshimm_handled_p = 1; 700 insn |= (1 << operand->shift); 701 } 702 return insn; 703} 704 705/* Called when we see a conditional flag (eg: .eq). */ 706 707static arc_insn 708insert_cond (insn, operand, mods, reg, value, errmsg) 709 arc_insn insn; 710 const struct arc_operand *operand; 711 int mods; 712 const struct arc_operand_value *reg; 713 long value; 714 const char **errmsg; 715{ 716 cond_p = 1; 717 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift; 718 return insn; 719} 720 721/* Used in the "j" instruction to prevent constants from being interpreted as 722 shimm values (which the jump insn doesn't accept). This can also be used 723 to force the use of limm values in other situations (eg: ld r0,[foo] uses 724 this). 725 ??? The mechanism is sound. Access to it is a bit klunky right now. */ 726 727static arc_insn 728insert_forcelimm (insn, operand, mods, reg, value, errmsg) 729 arc_insn insn; 730 const struct arc_operand *operand; 731 int mods; 732 const struct arc_operand_value *reg; 733 long value; 734 const char **errmsg; 735{ 736 cond_p = 1; 737 return insn; 738} 739 740/* Used in ld/st insns to handle the shimm offset field. */ 741 742static arc_insn 743insert_shimmoffset (insn, operand, mods, reg, value, errmsg) 744 arc_insn insn; 745 const struct arc_operand *operand; 746 int mods; 747 const struct arc_operand_value *reg; 748 long value; 749 const char **errmsg; 750{ 751 long minval, maxval; 752 static char buf[100]; 753 754 if (reg != NULL) 755 { 756 *errmsg = "register appears where shimm value expected"; 757 } 758 else 759 { 760 /* This is *way* more general than necessary, but maybe some day it'll 761 be useful. */ 762 if (operand->flags & ARC_OPERAND_SIGNED) 763 { 764 minval = -(1 << (operand->bits - 1)); 765 maxval = (1 << (operand->bits - 1)) - 1; 766 } 767 else 768 { 769 minval = 0; 770 maxval = (1 << operand->bits) - 1; 771 } 772 if (value < minval || value > maxval) 773 { 774 /* xgettext:c-format */ 775 sprintf (buf, _("value won't fit in range %ld - %ld"), 776 minval, maxval); 777 *errmsg = buf; 778 } 779 else 780 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift; 781 } 782 return insn; 783} 784 785/* Used in ld/st insns when the shimm offset is 0. */ 786 787static arc_insn 788insert_shimmzero (insn, operand, mods, reg, value, errmsg) 789 arc_insn insn; 790 const struct arc_operand *operand; 791 int mods; 792 const struct arc_operand_value *reg; 793 long value; 794 const char **errmsg; 795{ 796 shimm_p = 1; 797 shimm = 0; 798 return insn; 799} 800 801/* Called at the end of processing normal insns (eg: add) to insert a shimm 802 value (if present) into the insn. */ 803 804static arc_insn 805insert_shimmfinish (insn, operand, mods, reg, value, errmsg) 806 arc_insn insn; 807 const struct arc_operand *operand; 808 int mods; 809 const struct arc_operand_value *reg; 810 long value; 811 const char **errmsg; 812{ 813 if (shimm_p) 814 insn |= (shimm & ((1 << operand->bits) - 1)) << operand->shift; 815 return insn; 816} 817 818/* Called at the end of processing normal insns (eg: add) to insert a limm 819 value (if present) into the insn. 820 821 Note that this function is only intended to handle instructions (with 4 byte 822 immediate operands). It is not intended to handle data. */ 823 824/* ??? Actually, there's nothing for us to do as we can't call frag_more, the 825 caller must do that. The extract fns take a pointer to two words. The 826 insert fns could be converted and then we could do something useful, but 827 then the reloc handlers would have to know to work on the second word of 828 a 2 word quantity. That's too much so we don't handle them. */ 829 830static arc_insn 831insert_limmfinish (insn, operand, mods, reg, value, errmsg) 832 arc_insn insn; 833 const struct arc_operand *operand; 834 int mods; 835 const struct arc_operand_value *reg; 836 long value; 837 const char **errmsg; 838{ 839 if (limm_p) 840 ; /* nothing to do, gas does it */ 841 return insn; 842} 843 844/* Called at the end of unary operand macros to copy the B field to C. */ 845 846static arc_insn 847insert_unopmacro (insn, operand, mods, reg, value, errmsg) 848 arc_insn insn; 849 const struct arc_operand *operand; 850 int mods; 851 const struct arc_operand_value *reg; 852 long value; 853 const char **errmsg; 854{ 855 insn |= ((insn >> ARC_SHIFT_REGB) & ARC_MASK_REG) << operand->shift; 856 return insn; 857} 858 859/* Insert a relative address for a branch insn (b, bl, or lp). */ 860 861static arc_insn 862insert_reladdr (insn, operand, mods, reg, value, errmsg) 863 arc_insn insn; 864 const struct arc_operand *operand; 865 int mods; 866 const struct arc_operand_value *reg; 867 long value; 868 const char **errmsg; 869{ 870 if (value & 3) 871 *errmsg = _("branch address not on 4 byte boundary"); 872 insn |= ((value >> 2) & ((1 << operand->bits) - 1)) << operand->shift; 873 return insn; 874} 875 876/* Insert a limm value as a 26 bit address right shifted 2 into the insn. 877 878 Note that this function is only intended to handle instructions (with 4 byte 879 immediate operands). It is not intended to handle data. */ 880 881/* ??? Actually, there's nothing for us to do as we can't call frag_more, the 882 caller must do that. The extract fns take a pointer to two words. The 883 insert fns could be converted and then we could do something useful, but 884 then the reloc handlers would have to know to work on the second word of 885 a 2 word quantity. That's too much so we don't handle them. */ 886 887static arc_insn 888insert_absaddr (insn, operand, mods, reg, value, errmsg) 889 arc_insn insn; 890 const struct arc_operand *operand; 891 int mods; 892 const struct arc_operand_value *reg; 893 long value; 894 const char **errmsg; 895{ 896 if (limm_p) 897 ; /* nothing to do */ 898 return insn; 899} 900 901/* Extraction functions. 902 903 The suffix extraction functions' return value is redundant since it can be 904 obtained from (*OPVAL)->value. However, the boolean suffixes don't have 905 a suffix table entry for the "false" case, so values of zero must be 906 obtained from the return value (*OPVAL == NULL). */ 907 908static const struct arc_operand_value *lookup_register (int type, long regno); 909 910/* Called by the disassembler before printing an instruction. */ 911 912void 913arc_opcode_init_extract () 914{ 915 flag_p = 0; 916 flagshimm_handled_p = 0; 917 shimm_p = 0; 918 limm_p = 0; 919} 920 921/* As we're extracting registers, keep an eye out for the 'f' indicator 922 (ARC_REG_SHIMM_UPDATE). If we find a register (not a constant marker, 923 like ARC_REG_SHIMM), set OPVAL so our caller will know this is a register. 924 925 We must also handle auxiliary registers for lr/sr insns. They are just 926 constants with special names. */ 927 928static long 929extract_reg (insn, operand, mods, opval, invalid) 930 arc_insn *insn; 931 const struct arc_operand *operand; 932 int mods; 933 const struct arc_operand_value **opval; 934 int *invalid; 935{ 936 int regno; 937 long value; 938 939 /* Get the register number. */ 940 regno = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1); 941 942 /* Is it a constant marker? */ 943 if (regno == ARC_REG_SHIMM) 944 { 945 value = insn[0] & 511; 946 if ((operand->flags & ARC_OPERAND_SIGNED) 947 && (value & 256)) 948 value -= 512; 949 flagshimm_handled_p = 1; 950 } 951 else if (regno == ARC_REG_SHIMM_UPDATE) 952 { 953 value = insn[0] & 511; 954 if ((operand->flags & ARC_OPERAND_SIGNED) 955 && (value & 256)) 956 value -= 512; 957 flag_p = 1; 958 flagshimm_handled_p = 1; 959 } 960 else if (regno == ARC_REG_LIMM) 961 { 962 value = insn[1]; 963 limm_p = 1; 964 } 965 /* It's a register, set OPVAL (that's the only way we distinguish registers 966 from constants here). */ 967 else 968 { 969 const struct arc_operand_value *reg = lookup_register (REG, regno); 970 971 if (reg == NULL) 972 abort (); 973 if (opval != NULL) 974 *opval = reg; 975 value = regno; 976 } 977 978 /* If this field takes an auxiliary register, see if it's a known one. */ 979 if ((mods & ARC_MOD_AUXREG) 980 && ARC_REG_CONSTANT_P (regno)) 981 { 982 const struct arc_operand_value *reg = lookup_register (AUXREG, value); 983 984 /* This is really a constant, but tell the caller it has a special 985 name. */ 986 if (reg != NULL && opval != NULL) 987 *opval = reg; 988 } 989 990 return value; 991} 992 993/* Return the value of the "flag update" field for shimm insns. 994 This value is actually stored in the register field. */ 995 996static long 997extract_flag (insn, operand, mods, opval, invalid) 998 arc_insn *insn; 999 const struct arc_operand *operand; 1000 int mods; 1001 const struct arc_operand_value **opval; 1002 int *invalid; 1003{ 1004 int f; 1005 const struct arc_operand_value *val; 1006 1007 if (flagshimm_handled_p) 1008 f = flag_p != 0; 1009 else 1010 f = (insn[0] & (1 << operand->shift)) != 0; 1011 1012 /* There is no text for zero values. */ 1013 if (f == 0) 1014 return 0; 1015 1016 val = arc_opcode_lookup_suffix (operand, 1); 1017 if (opval != NULL && val != NULL) 1018 *opval = val; 1019 return val->value; 1020} 1021 1022/* Extract the condition code (if it exists). 1023 If we've seen a shimm value in this insn (meaning that the insn can't have 1024 a condition code field), then we don't store anything in OPVAL and return 1025 zero. */ 1026 1027static long 1028extract_cond (insn, operand, mods, opval, invalid) 1029 arc_insn *insn; 1030 const struct arc_operand *operand; 1031 int mods; 1032 const struct arc_operand_value **opval; 1033 int *invalid; 1034{ 1035 long cond; 1036 const struct arc_operand_value *val; 1037 1038 if (flagshimm_handled_p) 1039 return 0; 1040 1041 cond = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1); 1042 val = arc_opcode_lookup_suffix (operand, cond); 1043 1044 /* Ignore NULL values of `val'. Several condition code values are 1045 reserved for extensions. */ 1046 if (opval != NULL && val != NULL) 1047 *opval = val; 1048 return cond; 1049} 1050 1051/* Extract a branch address. 1052 We return the value as a real address (not right shifted by 2). */ 1053 1054static long 1055extract_reladdr (insn, operand, mods, opval, invalid) 1056 arc_insn *insn; 1057 const struct arc_operand *operand; 1058 int mods; 1059 const struct arc_operand_value **opval; 1060 int *invalid; 1061{ 1062 long addr; 1063 1064 addr = (insn[0] >> operand->shift) & ((1 << operand->bits) - 1); 1065 if ((operand->flags & ARC_OPERAND_SIGNED) 1066 && (addr & (1 << (operand->bits - 1)))) 1067 addr -= 1 << operand->bits; 1068 1069 return addr << 2; 1070} 1071 1072/* The only thing this does is set the `invalid' flag if B != C. 1073 This is needed because the "mov" macro appears before it's real insn "and" 1074 and we don't want the disassembler to confuse them. */ 1075 1076static long 1077extract_unopmacro (insn, operand, mods, opval, invalid) 1078 arc_insn *insn; 1079 const struct arc_operand *operand; 1080 int mods; 1081 const struct arc_operand_value **opval; 1082 int *invalid; 1083{ 1084 /* This misses the case where B == ARC_REG_SHIMM_UPDATE && 1085 C == ARC_REG_SHIMM (or vice versa). No big deal. Those insns will get 1086 printed as "and"s. */ 1087 if (((insn[0] >> ARC_SHIFT_REGB) & ARC_MASK_REG) 1088 != ((insn[0] >> ARC_SHIFT_REGC) & ARC_MASK_REG)) 1089 if (invalid != NULL) 1090 *invalid = 1; 1091 1092 return 0; 1093} 1094 1095/* Utility for the extraction functions to return the index into 1096 `arc_suffixes'. */ 1097 1098const struct arc_operand_value * 1099arc_opcode_lookup_suffix (type, value) 1100 const struct arc_operand *type; 1101 int value; 1102{ 1103 register const struct arc_operand_value *v,*end; 1104 1105 /* ??? This is a little slow and can be speeded up. */ 1106 1107 for (v = arc_suffixes, end = arc_suffixes + arc_suffixes_count; v < end; ++v) 1108 if (type == &arc_operands[v->type] 1109 && value == v->value) 1110 return v; 1111 return 0; 1112} 1113 1114static const struct arc_operand_value * 1115lookup_register (type, regno) 1116 int type; 1117 long regno; 1118{ 1119 register const struct arc_operand_value *r,*end; 1120 1121 if (type == REG) 1122 return &arc_reg_names[regno]; 1123 1124 /* ??? This is a little slow and can be speeded up. */ 1125 1126 for (r = arc_reg_names, end = arc_reg_names + arc_reg_names_count; 1127 r < end; ++r) 1128 if (type == r->type && regno == r->value) 1129 return r; 1130 return 0; 1131} 1132