00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "sysdep.h"
00025 #include <stdio.h>
00026 #include "ansidecl.h"
00027 #include "bfd.h"
00028 #include "opcode/arc.h"
00029
00030 #define INSERT_FN(fn) \
00031 static arc_insn fn PARAMS ((arc_insn, const struct arc_operand *, \
00032 int, const struct arc_operand_value *, long, \
00033 const char **))
00034 #define EXTRACT_FN(fn) \
00035 static long fn PARAMS ((arc_insn *, const struct arc_operand *, \
00036 int, const struct arc_operand_value **, int *))
00037
00038 INSERT_FN (insert_reg);
00039 INSERT_FN (insert_shimmfinish);
00040 INSERT_FN (insert_limmfinish);
00041 INSERT_FN (insert_offset);
00042 INSERT_FN (insert_base);
00043 INSERT_FN (insert_st_syntax);
00044 INSERT_FN (insert_ld_syntax);
00045 INSERT_FN (insert_addr_wb);
00046 INSERT_FN (insert_flag);
00047 INSERT_FN (insert_nullify);
00048 INSERT_FN (insert_flagfinish);
00049 INSERT_FN (insert_cond);
00050 INSERT_FN (insert_forcelimm);
00051 INSERT_FN (insert_reladdr);
00052 INSERT_FN (insert_absaddr);
00053 INSERT_FN (insert_jumpflags);
00054 INSERT_FN (insert_unopmacro);
00055
00056 EXTRACT_FN (extract_reg);
00057 EXTRACT_FN (extract_ld_offset);
00058 EXTRACT_FN (extract_ld_syntax);
00059 EXTRACT_FN (extract_st_offset);
00060 EXTRACT_FN (extract_st_syntax);
00061 EXTRACT_FN (extract_flag);
00062 EXTRACT_FN (extract_cond);
00063 EXTRACT_FN (extract_reladdr);
00064 EXTRACT_FN (extract_jumpflags);
00065 EXTRACT_FN (extract_unopmacro);
00066
00067 enum operand {OP_NONE,OP_REG,OP_SHIMM,OP_LIMM};
00068
00069 #define OPERANDS 3
00070
00071 enum operand ls_operand[OPERANDS];
00072
00073 struct arc_opcode *arc_ext_opcodes;
00074 struct arc_ext_operand_value *arc_ext_operands;
00075
00076 #define LS_VALUE 0
00077 #define LS_DEST 0
00078 #define LS_BASE 1
00079 #define LS_OFFSET 2
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129 const struct arc_operand arc_operands[] =
00130 {
00131
00132 #define UNUSED 0
00133 { 0, 0, 0, 0, 0, 0 },
00134
00135
00136 #define REGA (UNUSED + 1)
00137 { 'a', 6, ARC_SHIFT_REGA, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR, insert_reg, extract_reg },
00138
00139
00140 #define REGB (REGA + 1)
00141 { 'b', 6, ARC_SHIFT_REGB, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR, insert_reg, extract_reg },
00142
00143
00144 #define REGC (REGB + 1)
00145 { 'c', 6, ARC_SHIFT_REGC, ARC_OPERAND_SIGNED | ARC_OPERAND_ERROR, insert_reg, extract_reg },
00146
00147
00148 #define SHIMMFINISH (REGC + 1)
00149 { 'S', 9, 0, ARC_OPERAND_SIGNED + ARC_OPERAND_FAKE, insert_shimmfinish, 0 },
00150
00151
00152 #define LIMMFINISH (SHIMMFINISH + 1)
00153 { 'L', 32, 32, ARC_OPERAND_ADDRESS + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE, insert_limmfinish, 0 },
00154
00155
00156 #define ST_OFFSET (LIMMFINISH + 1)
00157 { 'o', 9, 0, ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED | ARC_OPERAND_STORE, insert_offset, extract_st_offset },
00158
00159
00160 #define LD_OFFSET (ST_OFFSET + 1)
00161 { 'O', 9, 0,ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED | ARC_OPERAND_LOAD, insert_offset, extract_ld_offset },
00162
00163
00164 #define BASE (LD_OFFSET + 1)
00165 { 's', 6, ARC_SHIFT_REGB, ARC_OPERAND_LIMM | ARC_OPERAND_SIGNED, insert_base, extract_reg},
00166
00167
00168 #define SYNTAX_ST_NE (BASE + 1)
00169 { '0', 9, 0, ARC_OPERAND_FAKE, insert_st_syntax, extract_st_syntax },
00170
00171
00172 #define SYNTAX_LD_NE (SYNTAX_ST_NE + 1)
00173 { '1', 9, 0, ARC_OPERAND_FAKE, insert_ld_syntax, extract_ld_syntax },
00174
00175
00176 #define SYNTAX_ST (SYNTAX_LD_NE + 1)
00177 { '2', 9, 0, ARC_OPERAND_FAKE | ARC_OPERAND_ERROR, insert_st_syntax, extract_st_syntax },
00178
00179
00180 #define SYNTAX_LD (SYNTAX_ST + 1)
00181 { '3', 9, 0, ARC_OPERAND_FAKE | ARC_OPERAND_ERROR, insert_ld_syntax, extract_ld_syntax },
00182
00183
00184 #define FLAG (SYNTAX_LD + 1)
00185 { 'f', 1, 8, ARC_OPERAND_SUFFIX, insert_flag, extract_flag },
00186
00187
00188 #define FLAGFINISH (FLAG + 1)
00189 { 'F', 1, 8, ARC_OPERAND_FAKE, insert_flagfinish, 0 },
00190
00191
00192 #define FLAGINSN (FLAGFINISH + 1)
00193 { 'G', 1, 8, ARC_OPERAND_FAKE, insert_flag, 0 },
00194
00195
00196 #define DELAY (FLAGINSN + 1)
00197 { 'n', 2, 5, ARC_OPERAND_SUFFIX , insert_nullify, 0 },
00198
00199
00200 #define COND (DELAY + 1)
00201 { 'q', 5, 0, ARC_OPERAND_SUFFIX, insert_cond, extract_cond },
00202
00203
00204 #define FORCELIMM (COND + 1)
00205 { 'Q', 0, 0, ARC_OPERAND_FAKE, insert_forcelimm, 0 },
00206
00207
00208 #define BRANCH (FORCELIMM + 1)
00209 { 'B', 20, 7, (ARC_OPERAND_RELATIVE_BRANCH + ARC_OPERAND_SIGNED) | ARC_OPERAND_ERROR, insert_reladdr, extract_reladdr },
00210
00211
00212
00213 #define JUMP (BRANCH + 1)
00214 { 'J', 24, 32, ARC_OPERAND_ERROR | (ARC_OPERAND_ABSOLUTE_BRANCH + ARC_OPERAND_LIMM + ARC_OPERAND_FAKE), insert_absaddr, 0 },
00215
00216
00217 #define JUMPFLAGS (JUMP + 1)
00218 { 'j', 6, 26, ARC_OPERAND_JUMPFLAGS | ARC_OPERAND_ERROR, insert_jumpflags, extract_jumpflags },
00219
00220
00221 #define SIZE1 (JUMPFLAGS + 1)
00222 { 'z', 2, 1, ARC_OPERAND_SUFFIX, 0, 0 },
00223
00224
00225 #define SIZE10 (SIZE1 + 1)
00226 { 'Z', 2, 10, ARC_OPERAND_SUFFIX, 0, 0 },
00227
00228
00229 #define SIZE22 (SIZE10 + 1)
00230 { 'y', 2, 22, ARC_OPERAND_SUFFIX, 0, 0 },
00231
00232
00233 #define SIGN0 (SIZE22 + 1)
00234 { 'x', 1, 0, ARC_OPERAND_SUFFIX, 0, 0 },
00235
00236
00237 #define SIGN9 (SIGN0 + 1)
00238 { 'X', 1, 9, ARC_OPERAND_SUFFIX, 0, 0 },
00239
00240
00241 #define ADDRESS3 (SIGN9 + 1)
00242 { 'w', 1, 3, ARC_OPERAND_SUFFIX, insert_addr_wb, 0},
00243
00244
00245 #define ADDRESS12 (ADDRESS3 + 1)
00246 { 'W', 1, 12, ARC_OPERAND_SUFFIX, insert_addr_wb, 0},
00247
00248
00249 #define ADDRESS24 (ADDRESS12 + 1)
00250 { 'v', 1, 24, ARC_OPERAND_SUFFIX, insert_addr_wb, 0},
00251
00252
00253 #define CACHEBYPASS5 (ADDRESS24 + 1)
00254 { 'e', 1, 5, ARC_OPERAND_SUFFIX, 0, 0 },
00255
00256
00257 #define CACHEBYPASS14 (CACHEBYPASS5 + 1)
00258 { 'E', 1, 14, ARC_OPERAND_SUFFIX, 0, 0 },
00259
00260
00261 #define CACHEBYPASS26 (CACHEBYPASS14 + 1)
00262 { 'D', 1, 26, ARC_OPERAND_SUFFIX, 0, 0 },
00263
00264
00265 #define UNOPMACRO (CACHEBYPASS26 + 1)
00266 { 'U', 6, ARC_SHIFT_REGC, ARC_OPERAND_FAKE, insert_unopmacro, extract_unopmacro },
00267
00268
00269 #define MODDOT (UNOPMACRO + 1)
00270 { '.', 1, 0, ARC_MOD_DOT, 0, 0 },
00271
00272
00273
00274
00275 #define REG (MODDOT + 1)
00276 { 'r', 6, 0, ARC_MOD_REG, 0, 0 },
00277
00278
00279 #define AUXREG (REG + 1)
00280 { 'A', 9, 0, ARC_MOD_AUXREG, 0, 0 },
00281
00282
00283 { 0, 0, 0, 0, 0, 0 }
00284 };
00285
00286
00287
00288 unsigned char arc_operand_map[256];
00289
00290
00291
00292
00293
00294
00295
00296
00297
00298
00299
00300 struct arc_opcode arc_opcodes[] =
00301 {
00302
00303
00304
00305 { "mov%.q%.f %a,%b%F%S%L%U", I(-1), I(12), ARC_MACH_5, 0, 0 },
00306
00307 { "asl%.q%.f %a,%b%F%S%L%U", I(-1), I(8), ARC_MACH_5, 0, 0 },
00308
00309 { "lsl%.q%.f %a,%b%F%S%L%U", I(-1), I(8), ARC_MACH_5, 0, 0 },
00310
00311 { "nop", 0x7fffffff, 0x7fffffff, ARC_MACH_5, 0, 0 },
00312
00313 { "rlc%.q%.f %a,%b%F%S%L%U", I(-1), I(9), ARC_MACH_5, 0, 0 },
00314 { "adc%.q%.f %a,%b,%c%F%S%L", I(-1), I(9), ARC_MACH_5, 0, 0 },
00315 { "add%.q%.f %a,%b,%c%F%S%L", I(-1), I(8), ARC_MACH_5, 0, 0 },
00316 { "and%.q%.f %a,%b,%c%F%S%L", I(-1), I(12), ARC_MACH_5, 0, 0 },
00317 { "asr%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(1), ARC_MACH_5, 0, 0 },
00318 { "bic%.q%.f %a,%b,%c%F%S%L", I(-1), I(14), ARC_MACH_5, 0, 0 },
00319 { "b%q%.n %B", I(-1), I(4), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
00320 { "bl%q%.n %B", I(-1), I(5), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
00321 { "extb%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(7), ARC_MACH_5, 0, 0 },
00322 { "extw%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(8), ARC_MACH_5, 0, 0 },
00323 { "flag%.q %b%G%S%L", I(-1)|A(-1)|C(-1), I(3)|A(ARC_REG_SHIMM_UPDATE)|C(0), ARC_MACH_5, 0, 0 },
00324 { "brk", 0x1ffffe00, 0x1ffffe00, ARC_MACH_7, 0, 0 },
00325 { "sleep", 0x1ffffe01, 0x1ffffe01, ARC_MACH_7, 0, 0 },
00326 { "swi", 0x1ffffe02, 0x1ffffe02, ARC_MACH_8, 0, 0 },
00327
00328
00329 { "j%q%Q%.n%.f %b%F%J,%j", I(-1)|A(-1)|C(-1)|R(-1,7,1), I(7)|A(0)|C(0)|R(0,7,1), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
00330 { "j%q%Q%.n%.f %b%F%J", I(-1)|A(-1)|C(-1)|R(-1,7,1), I(7)|A(0)|C(0)|R(0,7,1), ARC_MACH_5 | ARC_OPCODE_COND_BRANCH, 0, 0 },
00331
00332 { "jl%q%Q%.n%.f %b%F%J,%j", I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1), I(7)|A(0)|C(0)|R(0,7,1)|R(1,9,1), ARC_MACH_6 | ARC_OPCODE_COND_BRANCH, 0, 0 },
00333 { "jl%q%Q%.n%.f %b%F%J", I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1), I(7)|A(0)|C(0)|R(0,7,1)|R(1,9,1), ARC_MACH_6 | ARC_OPCODE_COND_BRANCH, 0, 0 },
00334
00335
00336 { "ld%Z%.X%.W%.E %a,[%s]%S%L%1", I(-1)|R(-1,13,1)|R(-1,0,511), I(1)|R(0,13,1)|R(0,0,511), ARC_MACH_5, 0, 0 },
00337 { "ld%z%.x%.w%.e %a,[%s]%S%L%1", I(-1)|R(-1,4,1)|R(-1,6,7), I(0)|R(0,4,1)|R(0,6,7), ARC_MACH_5, 0, 0 },
00338 { "ld%z%.x%.w%.e %a,[%s,%O]%S%L%1", I(-1)|R(-1,4,1)|R(-1,6,7), I(0)|R(0,4,1)|R(0,6,7), ARC_MACH_5, 0, 0 },
00339 { "ld%Z%.X%.W%.E %a,[%s,%O]%S%L%3", I(-1)|R(-1,13,1), I(1)|R(0,13,1), ARC_MACH_5, 0, 0 },
00340 { "lp%q%.n %B", I(-1), I(6), ARC_MACH_5, 0, 0 },
00341 { "lr %a,[%Ab]%S%L", I(-1)|C(-1), I(1)|C(0x10), ARC_MACH_5, 0, 0 },
00342 { "lsr%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(2), ARC_MACH_5, 0, 0 },
00343 { "or%.q%.f %a,%b,%c%F%S%L", I(-1), I(13), ARC_MACH_5, 0, 0 },
00344 { "ror%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(3), ARC_MACH_5, 0, 0 },
00345 { "rrc%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(4), ARC_MACH_5, 0, 0 },
00346 { "sbc%.q%.f %a,%b,%c%F%S%L", I(-1), I(11), ARC_MACH_5, 0, 0 },
00347 { "sexb%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(5), ARC_MACH_5, 0, 0 },
00348 { "sexw%.q%.f %a,%b%F%S%L", I(-1)|C(-1), I(3)|C(6), ARC_MACH_5, 0, 0 },
00349 { "sr %c,[%Ab]%S%L", I(-1)|A(-1), I(2)|A(0x10), ARC_MACH_5, 0, 0 },
00350
00351 { "st%y%.v%.D %c,[%s]%L%S%0", I(-1)|R(-1,25,1)|R(-1,21,1), I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
00352 { "st%y%.v%.D %c,[%s,%o]%S%L%2", I(-1)|R(-1,25,1)|R(-1,21,1), I(2)|R(0,25,1)|R(0,21,1), ARC_MACH_5, 0, 0 },
00353 { "sub%.q%.f %a,%b,%c%F%S%L", I(-1), I(10), ARC_MACH_5, 0, 0 },
00354 { "xor%.q%.f %a,%b,%c%F%S%L", I(-1), I(15), ARC_MACH_5, 0, 0 }
00355 };
00356
00357 const int arc_opcodes_count = sizeof (arc_opcodes) / sizeof (arc_opcodes[0]);
00358
00359 const struct arc_operand_value arc_reg_names[] =
00360 {
00361
00362
00363
00364 { "r0", 0, REG, 0 }, { "r1", 1, REG, 0 }, { "r2", 2, REG, 0 },
00365 { "r3", 3, REG, 0 }, { "r4", 4, REG, 0 }, { "r5", 5, REG, 0 },
00366 { "r6", 6, REG, 0 }, { "r7", 7, REG, 0 }, { "r8", 8, REG, 0 },
00367 { "r9", 9, REG, 0 }, { "r10", 10, REG, 0 }, { "r11", 11, REG, 0 },
00368 { "r12", 12, REG, 0 }, { "r13", 13, REG, 0 }, { "r14", 14, REG, 0 },
00369 { "r15", 15, REG, 0 }, { "r16", 16, REG, 0 }, { "r17", 17, REG, 0 },
00370 { "r18", 18, REG, 0 }, { "r19", 19, REG, 0 }, { "r20", 20, REG, 0 },
00371 { "r21", 21, REG, 0 }, { "r22", 22, REG, 0 }, { "r23", 23, REG, 0 },
00372 { "r24", 24, REG, 0 }, { "r25", 25, REG, 0 }, { "r26", 26, REG, 0 },
00373 { "r27", 27, REG, 0 }, { "r28", 28, REG, 0 },
00374
00375 { "ilink1", 29, REG, 0 },
00376
00377 { "ilink2", 30, REG, 0 },
00378
00379 { "blink", 31, REG, 0 },
00380
00381
00382 { "r32", 32, REG, 0 }, { "r33", 33, REG, 0 }, { "r34", 34, REG, 0 },
00383 { "r35", 35, REG, 0 }, { "r36", 36, REG, 0 }, { "r37", 37, REG, 0 },
00384 { "r38", 38, REG, 0 }, { "r39", 39, REG, 0 }, { "r40", 40, REG, 0 },
00385 { "r41", 41, REG, 0 }, { "r42", 42, REG, 0 }, { "r43", 43, REG, 0 },
00386 { "r44", 44, REG, 0 }, { "r45", 45, REG, 0 }, { "r46", 46, REG, 0 },
00387 { "r47", 47, REG, 0 }, { "r48", 48, REG, 0 }, { "r49", 49, REG, 0 },
00388 { "r50", 50, REG, 0 }, { "r51", 51, REG, 0 }, { "r52", 52, REG, 0 },
00389 { "r53", 53, REG, 0 }, { "r54", 54, REG, 0 }, { "r55", 55, REG, 0 },
00390 { "r56", 56, REG, 0 }, { "r57", 57, REG, 0 }, { "r58", 58, REG, 0 },
00391 { "r59", 59, REG, 0 },
00392
00393
00394 { "lp_count", 60, REG, 0 },
00395
00396 { "r61", 61, REG, ARC_REGISTER_READONLY },
00397
00398 { "r62", 62, REG, ARC_REGISTER_READONLY },
00399
00400 { "r63", 63, REG, ARC_REGISTER_READONLY },
00401
00402
00403 { "gp", 26, REG, 0 },
00404
00405 { "fp", 27, REG, 0 },
00406
00407 { "sp", 28, REG, 0 },
00408
00409 { "r29", 29, REG, 0 },
00410 { "r30", 30, REG, 0 },
00411 { "r31", 31, REG, 0 },
00412 { "r60", 60, REG, 0 },
00413
00414
00415
00416
00417
00418
00419
00420
00421
00422
00423 { "status", 0x00, AUXREG, 0 },
00424 { "semaphore", 0x01, AUXREG, 0 },
00425 { "lp_start", 0x02, AUXREG, 0 },
00426 { "lp_end", 0x03, AUXREG, 0 },
00427 { "identity", 0x04, AUXREG, ARC_REGISTER_READONLY },
00428 { "debug", 0x05, AUXREG, 0 },
00429 };
00430
00431 const int arc_reg_names_count =
00432 sizeof (arc_reg_names) / sizeof (arc_reg_names[0]);
00433
00434
00435
00436
00437 const struct arc_operand_value arc_suffixes[] =
00438 {
00439
00440 { "", 0, -1, 0 },
00441
00442
00443 { "al", 0, COND, 0 },
00444 { "ra", 0, COND, 0 },
00445 { "eq", 1, COND, 0 },
00446 { "z", 1, COND, 0 },
00447 { "ne", 2, COND, 0 },
00448 { "nz", 2, COND, 0 },
00449 { "pl", 3, COND, 0 },
00450 { "p", 3, COND, 0 },
00451 { "mi", 4, COND, 0 },
00452 { "n", 4, COND, 0 },
00453 { "cs", 5, COND, 0 },
00454 { "c", 5, COND, 0 },
00455 { "lo", 5, COND, 0 },
00456 { "cc", 6, COND, 0 },
00457 { "nc", 6, COND, 0 },
00458 { "hs", 6, COND, 0 },
00459 { "vs", 7, COND, 0 },
00460 { "v", 7, COND, 0 },
00461 { "vc", 8, COND, 0 },
00462 { "nv", 8, COND, 0 },
00463 { "gt", 9, COND, 0 },
00464 { "ge", 10, COND, 0 },
00465 { "lt", 11, COND, 0 },
00466 { "le", 12, COND, 0 },
00467 { "hi", 13, COND, 0 },
00468 { "ls", 14, COND, 0 },
00469 { "pnz", 15, COND, 0 },
00470
00471
00472
00473 { "f", 1, FLAG, 0 },
00474
00475 { "nd", ARC_DELAY_NONE, DELAY, 0 },
00476 { "d", ARC_DELAY_NORMAL, DELAY, 0 },
00477 { "jd", ARC_DELAY_JUMP, DELAY, 0 },
00478
00479 { "b", 1, SIZE1, 0 },
00480 { "b", 1, SIZE10, 0 },
00481 { "b", 1, SIZE22, 0 },
00482 { "w", 2, SIZE1, 0 },
00483 { "w", 2, SIZE10, 0 },
00484 { "w", 2, SIZE22, 0 },
00485 { "x", 1, SIGN0, 0 },
00486 { "x", 1, SIGN9, 0 },
00487 { "a", 1, ADDRESS3, 0 },
00488 { "a", 1, ADDRESS12, 0 },
00489 { "a", 1, ADDRESS24, 0 },
00490
00491 { "di", 1, CACHEBYPASS5, 0 },
00492 { "di", 1, CACHEBYPASS14, 0 },
00493 { "di", 1, CACHEBYPASS26, 0 },
00494 };
00495
00496 const int arc_suffixes_count =
00497 sizeof (arc_suffixes) / sizeof (arc_suffixes[0]);
00498
00499
00500
00501 static struct arc_opcode *opcode_map[26 + 1];
00502
00503
00504 static struct arc_opcode *icode_map[32];
00505
00506
00507
00508
00509 static int cpu_type;
00510
00511
00512
00513 int
00514 arc_get_opcode_mach (bfd_mach, big_p)
00515 int bfd_mach, big_p;
00516 {
00517 static int mach_type_map[] =
00518 {
00519 ARC_MACH_5,
00520 ARC_MACH_6,
00521 ARC_MACH_7,
00522 ARC_MACH_8
00523 };
00524 return mach_type_map[bfd_mach - bfd_mach_arc_5] | (big_p ? ARC_MACH_BIG : 0);
00525 }
00526
00527
00528
00529
00530
00531
00532
00533 void
00534 arc_opcode_init_tables (flags)
00535 int flags;
00536 {
00537 static int init_p = 0;
00538
00539 cpu_type = flags;
00540
00541
00542
00543
00544 if (!init_p)
00545 {
00546 register int i,n;
00547
00548 memset (arc_operand_map, 0, sizeof (arc_operand_map));
00549 n = sizeof (arc_operands) / sizeof (arc_operands[0]);
00550 for (i = 0; i < n; ++i)
00551 arc_operand_map[arc_operands[i].fmt] = i;
00552
00553 memset (opcode_map, 0, sizeof (opcode_map));
00554 memset (icode_map, 0, sizeof (icode_map));
00555
00556 for (i = arc_opcodes_count - 1; i >= 0; --i)
00557 {
00558 int opcode_hash = ARC_HASH_OPCODE (arc_opcodes[i].syntax);
00559 int icode_hash = ARC_HASH_ICODE (arc_opcodes[i].value);
00560
00561 arc_opcodes[i].next_asm = opcode_map[opcode_hash];
00562 opcode_map[opcode_hash] = &arc_opcodes[i];
00563
00564 arc_opcodes[i].next_dis = icode_map[icode_hash];
00565 icode_map[icode_hash] = &arc_opcodes[i];
00566 }
00567
00568 init_p = 1;
00569 }
00570 }
00571
00572
00573
00574
00575 int
00576 arc_opcode_supported (opcode)
00577 const struct arc_opcode *opcode;
00578 {
00579 if (ARC_OPCODE_CPU (opcode->flags) <= cpu_type)
00580 return 1;
00581 return 0;
00582 }
00583
00584
00585
00586 const struct arc_opcode *
00587 arc_opcode_lookup_asm (insn)
00588 const char *insn;
00589 {
00590 return opcode_map[ARC_HASH_OPCODE (insn)];
00591 }
00592
00593
00594
00595 const struct arc_opcode *
00596 arc_opcode_lookup_dis (insn)
00597 unsigned int insn;
00598 {
00599 return icode_map[ARC_HASH_ICODE (insn)];
00600 }
00601
00602
00603 static int flag_p;
00604
00605
00606 static int flagshimm_handled_p;
00607
00608
00609 static int addrwb_p;
00610
00611
00612 static int cond_p;
00613
00614
00615 static int nullify_p;
00616
00617
00618 static int nullify;
00619
00620
00621 static int jumpflags_p;
00622
00623
00624 static int shimm_p;
00625
00626
00627
00628 static int shimm;
00629
00630
00631
00632 static int limm_p;
00633
00634
00635
00636 static long limm;
00637
00638
00639
00640
00641
00642 void
00643 arc_opcode_init_insert ()
00644 {
00645 int i;
00646
00647 for(i = 0; i < OPERANDS; i++)
00648 ls_operand[i] = OP_NONE;
00649
00650 flag_p = 0;
00651 flagshimm_handled_p = 0;
00652 cond_p = 0;
00653 addrwb_p = 0;
00654 shimm_p = 0;
00655 limm_p = 0;
00656 jumpflags_p = 0;
00657 nullify_p = 0;
00658 nullify = 0;
00659 }
00660
00661
00662
00663
00664 int
00665 arc_opcode_limm_p (limmp)
00666 long *limmp;
00667 {
00668 if (limmp)
00669 *limmp = limm;
00670 return limm_p;
00671 }
00672
00673
00674
00675
00676
00677
00678 static arc_insn
00679 insert_reg (insn, operand, mods, reg, value, errmsg)
00680 arc_insn insn;
00681 const struct arc_operand *operand;
00682 int mods;
00683 const struct arc_operand_value *reg;
00684 long value;
00685 const char **errmsg;
00686 {
00687 static char buf[100];
00688 enum operand op_type = OP_NONE;
00689
00690 if (reg == NULL)
00691 {
00692
00693
00694
00695
00696
00697 if (ARC_SHIMM_CONST_P (value)
00698
00699 && !cond_p
00700
00701
00702 && (!shimm_p || shimm == value))
00703 {
00704 int marker;
00705
00706 op_type = OP_SHIMM;
00707
00708
00709 if ('a' != operand->fmt)
00710 {
00711 shimm_p = 1;
00712 shimm = value;
00713 flagshimm_handled_p = 1;
00714 marker = flag_p ? ARC_REG_SHIMM_UPDATE : ARC_REG_SHIMM;
00715 }
00716 else
00717 {
00718
00719 marker = ARC_REG_SHIMM;
00720 }
00721 insn |= marker << operand->shift;
00722
00723 }
00724
00725 else if (!limm_p || limm == value)
00726 {
00727 op_type = OP_LIMM;
00728 limm_p = 1;
00729 limm = value;
00730 insn |= ARC_REG_LIMM << operand->shift;
00731
00732 }
00733 else
00734 {
00735 *errmsg = "unable to fit different valued constants into instruction";
00736 }
00737 }
00738 else
00739 {
00740
00741
00742 if (reg->type == AUXREG)
00743 {
00744 if (!(mods & ARC_MOD_AUXREG))
00745 *errmsg = "auxiliary register not allowed here";
00746 else
00747 {
00748 if ((insn & I(-1)) == I(2))
00749 {
00750 if (reg->flags & ARC_REGISTER_READONLY)
00751 *errmsg = "attempt to set readonly register";
00752 }
00753 else
00754 {
00755 if (reg->flags & ARC_REGISTER_WRITEONLY)
00756 *errmsg = "attempt to read writeonly register";
00757 }
00758 insn |= ARC_REG_SHIMM << operand->shift;
00759 insn |= reg->value << arc_operands[reg->type].shift;
00760 }
00761 }
00762 else
00763 {
00764
00765 if ('a' == operand->fmt || ((insn & I(-1)) < I(2)))
00766 {
00767 if (reg->flags & ARC_REGISTER_READONLY)
00768 *errmsg = "attempt to set readonly register";
00769 }
00770 if ('a' != operand->fmt)
00771 {
00772 if (reg->flags & ARC_REGISTER_WRITEONLY)
00773 *errmsg = "attempt to read writeonly register";
00774 }
00775
00776 if ((unsigned int) reg->value > 60)
00777 {
00778 sprintf (buf, "invalid register number `%d'", reg->value);
00779 *errmsg = buf;
00780 }
00781 insn |= reg->value << operand->shift;
00782 op_type = OP_REG;
00783 }
00784 }
00785
00786 switch (operand->fmt)
00787 {
00788 case 'a':
00789 ls_operand[LS_DEST] = op_type;
00790 break;
00791 case 's':
00792 ls_operand[LS_BASE] = op_type;
00793 break;
00794 case 'c':
00795 if ((insn & I(-1)) == I(2))
00796 ls_operand[LS_VALUE] = op_type;
00797 else
00798 ls_operand[LS_OFFSET] = op_type;
00799 break;
00800 case 'o': case 'O':
00801 ls_operand[LS_OFFSET] = op_type;
00802 break;
00803 }
00804
00805 return insn;
00806 }
00807
00808
00809
00810 static arc_insn
00811 insert_flag (insn, operand, mods, reg, value, errmsg)
00812 arc_insn insn;
00813 const struct arc_operand *operand ATTRIBUTE_UNUSED;
00814 int mods ATTRIBUTE_UNUSED;
00815 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
00816 long value ATTRIBUTE_UNUSED;
00817 const char **errmsg ATTRIBUTE_UNUSED;
00818 {
00819
00820
00821
00822 flag_p = 1;
00823 return insn;
00824 }
00825
00826
00827
00828 static arc_insn
00829 insert_nullify (insn, operand, mods, reg, value, errmsg)
00830 arc_insn insn;
00831 const struct arc_operand *operand;
00832 int mods ATTRIBUTE_UNUSED;
00833 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
00834 long value;
00835 const char **errmsg ATTRIBUTE_UNUSED;
00836 {
00837 nullify_p = 1;
00838 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
00839 nullify = value;
00840 return insn;
00841 }
00842
00843
00844
00845
00846
00847 static arc_insn
00848 insert_flagfinish (insn, operand, mods, reg, value, errmsg)
00849 arc_insn insn;
00850 const struct arc_operand *operand;
00851 int mods ATTRIBUTE_UNUSED;
00852 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
00853 long value ATTRIBUTE_UNUSED;
00854 const char **errmsg ATTRIBUTE_UNUSED;
00855 {
00856 if (flag_p && !flagshimm_handled_p)
00857 {
00858 if (shimm_p)
00859 abort ();
00860 flagshimm_handled_p = 1;
00861 insn |= (1 << operand->shift);
00862 }
00863 return insn;
00864 }
00865
00866
00867
00868 static arc_insn
00869 insert_cond (insn, operand, mods, reg, value, errmsg)
00870 arc_insn insn;
00871 const struct arc_operand *operand;
00872 int mods ATTRIBUTE_UNUSED;
00873 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
00874 long value;
00875 const char **errmsg ATTRIBUTE_UNUSED;
00876 {
00877 cond_p = 1;
00878 insn |= (value & ((1 << operand->bits) - 1)) << operand->shift;
00879 return insn;
00880 }
00881
00882
00883
00884
00885
00886
00887
00888 static arc_insn
00889 insert_forcelimm (insn, operand, mods, reg, value, errmsg)
00890 arc_insn insn;
00891 const struct arc_operand *operand ATTRIBUTE_UNUSED;
00892 int mods ATTRIBUTE_UNUSED;
00893 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
00894 long value ATTRIBUTE_UNUSED;
00895 const char **errmsg ATTRIBUTE_UNUSED;
00896 {
00897 cond_p = 1;
00898 return insn;
00899 }
00900
00901 static arc_insn
00902 insert_addr_wb (insn, operand, mods, reg, value, errmsg)
00903 arc_insn insn;
00904 const struct arc_operand *operand;
00905 int mods ATTRIBUTE_UNUSED;
00906 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
00907 long value ATTRIBUTE_UNUSED;
00908 const char **errmsg ATTRIBUTE_UNUSED;
00909 {
00910 addrwb_p = 1 << operand->shift;
00911 return insn;
00912 }
00913
00914 static arc_insn
00915 insert_base (insn, operand, mods, reg, value, errmsg)
00916 arc_insn insn;
00917 const struct arc_operand *operand;
00918 int mods;
00919 const struct arc_operand_value *reg;
00920 long value;
00921 const char **errmsg;
00922 {
00923 if (reg != NULL)
00924 {
00925 arc_insn myinsn;
00926 myinsn = insert_reg (0, operand,mods, reg, value, errmsg) >> operand->shift;
00927 insn |= B(myinsn);
00928 ls_operand[LS_BASE] = OP_REG;
00929 }
00930 else if (ARC_SHIMM_CONST_P (value) && !cond_p)
00931 {
00932 if (shimm_p && value != shimm)
00933 {
00934
00935 limm_p = 1;
00936 limm = shimm;
00937 insn &= ~C(-1);
00938 insn |= C(ARC_REG_LIMM);
00939 ls_operand[LS_VALUE] = OP_LIMM;
00940 }
00941 insn |= ARC_REG_SHIMM << operand->shift;
00942 shimm_p = 1;
00943 shimm = value;
00944 ls_operand[LS_BASE] = OP_SHIMM;
00945 ls_operand[LS_OFFSET] = OP_SHIMM;
00946 }
00947 else
00948 {
00949 if (limm_p && value != limm)
00950 {
00951 *errmsg = "too many long constants";
00952 return insn;
00953 }
00954 limm_p = 1;
00955 limm = value;
00956 insn |= B(ARC_REG_LIMM);
00957 ls_operand[LS_BASE] = OP_LIMM;
00958 }
00959
00960 return insn;
00961 }
00962
00963
00964
00965
00966 static arc_insn
00967 insert_offset (insn, operand, mods, reg, value, errmsg)
00968 arc_insn insn;
00969 const struct arc_operand *operand;
00970 int mods;
00971 const struct arc_operand_value *reg;
00972 long value;
00973 const char **errmsg;
00974 {
00975 long minval, maxval;
00976
00977 if (reg != NULL)
00978 {
00979 arc_insn myinsn;
00980 myinsn = insert_reg (0,operand,mods,reg,value,errmsg) >> operand->shift;
00981 ls_operand[LS_OFFSET] = OP_REG;
00982 if (operand->flags & ARC_OPERAND_LOAD)
00983 if ((insn & I(-1)) != I(1))
00984 insn |= C(myinsn);
00985 }
00986 else
00987 {
00988
00989
00990 if (operand->flags & ARC_OPERAND_SIGNED)
00991 {
00992 minval = -(1 << (operand->bits - 1));
00993 maxval = (1 << (operand->bits - 1)) - 1;
00994 }
00995 else
00996 {
00997 minval = 0;
00998 maxval = (1 << operand->bits) - 1;
00999 }
01000 if ((cond_p && !limm_p) || (value < minval || value > maxval))
01001 {
01002 if (limm_p && value != limm)
01003 {
01004 *errmsg = "too many long constants";
01005 }
01006 else
01007 {
01008 limm_p = 1;
01009 limm = value;
01010 if (operand->flags & ARC_OPERAND_STORE)
01011 insn |= B(ARC_REG_LIMM);
01012 if (operand->flags & ARC_OPERAND_LOAD)
01013 insn |= C(ARC_REG_LIMM);
01014 ls_operand[LS_OFFSET] = OP_LIMM;
01015 }
01016 }
01017 else
01018 {
01019 if ((value < minval || value > maxval))
01020 *errmsg = "need too many limms";
01021 else if (shimm_p && value != shimm)
01022 {
01023
01024 if ((insn & I(-1)) == I(1))
01025 {
01026 *errmsg = "to many shimms in load";
01027 goto out;
01028 }
01029 if (limm_p && operand->flags & ARC_OPERAND_LOAD)
01030 {
01031 *errmsg = "too many long constants";
01032 goto out;
01033 }
01034
01035 limm_p = 1;
01036 limm = shimm;
01037 if (ls_operand[LS_VALUE] == OP_SHIMM && operand->flags & ARC_OPERAND_STORE)
01038 {
01039 insn &= ~C(-1);
01040 insn |= C(ARC_REG_LIMM);
01041 ls_operand[LS_VALUE] = OP_LIMM;
01042 }
01043 if (ls_operand[LS_BASE] == OP_SHIMM && operand->flags & ARC_OPERAND_STORE)
01044 {
01045 insn &= ~B(-1);
01046 insn |= B(ARC_REG_LIMM);
01047 ls_operand[LS_BASE] = OP_LIMM;
01048 }
01049 }
01050 shimm = value;
01051 shimm_p = 1;
01052 ls_operand[LS_OFFSET] = OP_SHIMM;
01053 }
01054 }
01055 out:
01056 return insn;
01057 }
01058
01059
01060
01061 static long
01062 extract_st_syntax (insn, operand, mods, opval, invalid)
01063 arc_insn *insn;
01064 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01065 int mods ATTRIBUTE_UNUSED;
01066 const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
01067 int *invalid;
01068 {
01069 #define ST_SYNTAX(V,B,O) \
01070 ((ls_operand[LS_VALUE] == (V) && \
01071 ls_operand[LS_BASE] == (B) && \
01072 ls_operand[LS_OFFSET] == (O)))
01073
01074 if (!((ST_SYNTAX(OP_REG,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
01075 || ST_SYNTAX(OP_REG,OP_LIMM,OP_NONE)
01076 || (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
01077 || (ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_NONE) && (insn[0] & 511) == 0)
01078 || ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE)
01079 || ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_SHIMM)
01080 || ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_SHIMM)
01081 || (ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE) && (insn[0] & 511) == 0)
01082 || ST_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
01083 || ST_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
01084 || ST_SYNTAX(OP_SHIMM,OP_REG,OP_SHIMM)
01085 || ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_SHIMM)
01086 || ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_NONE)
01087 || ST_SYNTAX(OP_LIMM,OP_REG,OP_SHIMM)))
01088 *invalid = 1;
01089 return 0;
01090 }
01091
01092 int
01093 arc_limm_fixup_adjust(insn)
01094 arc_insn insn;
01095 {
01096 int retval = 0;
01097
01098
01099 if ((insn & (I(-1) | C(-1) | B(-1))) ==
01100 (I(2) | C(ARC_REG_SHIMM) | B(ARC_REG_LIMM)))
01101 {
01102 retval = insn & 0x1ff;
01103 if (retval & 0x100)
01104 retval |= ~0x1ff;
01105 }
01106 return -retval;
01107 }
01108
01109
01110
01111 static arc_insn
01112 insert_st_syntax (insn, operand, mods, reg, value, errmsg)
01113 arc_insn insn;
01114 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01115 int mods ATTRIBUTE_UNUSED;
01116 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01117 long value ATTRIBUTE_UNUSED;
01118 const char **errmsg;
01119 {
01120 if (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && shimm != 0)
01121 {
01122
01123
01124 limm_p = 1;
01125 limm = shimm;
01126 shimm_p = 0;
01127 shimm = 0;
01128 insn = insn & ~(C(-1) | 511);
01129 insn |= ARC_REG_LIMM << ARC_SHIFT_REGC;
01130 ls_operand[LS_VALUE] = OP_LIMM;
01131 }
01132
01133 if (ST_SYNTAX(OP_REG,OP_SHIMM,OP_NONE) || ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_NONE))
01134 {
01135
01136 if (shimm & 0x1)
01137 {
01138 if (limm_p)
01139 {
01140 *errmsg = "impossible store";
01141 }
01142 limm_p = 1;
01143 limm = shimm;
01144 shimm = 0;
01145 shimm_p = 0;
01146 insn = insn & ~(B(-1) | 511);
01147 insn |= B(ARC_REG_LIMM);
01148 ls_operand[LS_BASE] = OP_LIMM;
01149 }
01150 else
01151 {
01152 shimm >>= 1;
01153 insn = insn & ~511;
01154 insn |= shimm;
01155 ls_operand[LS_OFFSET] = OP_SHIMM;
01156 }
01157 }
01158 if (ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE))
01159 {
01160 limm += arc_limm_fixup_adjust(insn);
01161 }
01162 if (!(ST_SYNTAX(OP_REG,OP_REG,OP_NONE)
01163 || ST_SYNTAX(OP_REG,OP_LIMM,OP_NONE)
01164 || ST_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
01165 || ST_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
01166 || (ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_NONE) && (shimm == 0))
01167 || ST_SYNTAX(OP_SHIMM,OP_LIMM,OP_NONE)
01168 || ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE)
01169 || ST_SYNTAX(OP_SHIMM,OP_REG,OP_SHIMM)
01170 || ST_SYNTAX(OP_SHIMM,OP_SHIMM,OP_SHIMM)
01171 || ST_SYNTAX(OP_LIMM,OP_SHIMM,OP_SHIMM)
01172 || ST_SYNTAX(OP_LIMM,OP_REG,OP_NONE)
01173 || ST_SYNTAX(OP_LIMM,OP_REG,OP_SHIMM)))
01174 *errmsg = "st operand error";
01175 if (addrwb_p)
01176 {
01177 if (ls_operand[LS_BASE] != OP_REG)
01178 *errmsg = "address writeback not allowed";
01179 insn |= addrwb_p;
01180 }
01181 if (ST_SYNTAX(OP_SHIMM,OP_REG,OP_NONE) && shimm)
01182 *errmsg = "store value must be zero";
01183 return insn;
01184 }
01185
01186
01187
01188 static arc_insn
01189 insert_ld_syntax (insn, operand, mods, reg, value, errmsg)
01190 arc_insn insn;
01191 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01192 int mods ATTRIBUTE_UNUSED;
01193 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01194 long value ATTRIBUTE_UNUSED;
01195 const char **errmsg;
01196 {
01197 #define LD_SYNTAX(D,B,O) \
01198 ((ls_operand[LS_DEST] == (D) && \
01199 ls_operand[LS_BASE] == (B) && \
01200 ls_operand[LS_OFFSET] == (O)))
01201
01202 int test = insn & I(-1);
01203
01204 if (!(test == I(1)))
01205 {
01206 if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
01207 || ls_operand[LS_OFFSET] == OP_SHIMM))
01208 *errmsg = "invalid load/shimm insn";
01209 }
01210 if (!(LD_SYNTAX(OP_REG,OP_REG,OP_NONE)
01211 || LD_SYNTAX(OP_REG,OP_REG,OP_REG)
01212 || LD_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
01213 || (LD_SYNTAX(OP_REG,OP_LIMM,OP_REG) && !(test == I(1)))
01214 || (LD_SYNTAX(OP_REG,OP_REG,OP_LIMM) && !(test == I(1)))
01215 || LD_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
01216 || (LD_SYNTAX(OP_REG,OP_LIMM,OP_NONE) && (test == I(1)))))
01217 *errmsg = "ld operand error";
01218 if (addrwb_p)
01219 {
01220 if (ls_operand[LS_BASE] != OP_REG)
01221 *errmsg = "address writeback not allowed";
01222 insn |= addrwb_p;
01223 }
01224 return insn;
01225 }
01226
01227
01228
01229 static long
01230 extract_ld_syntax (insn, operand, mods, opval, invalid)
01231 arc_insn *insn;
01232 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01233 int mods ATTRIBUTE_UNUSED;
01234 const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
01235 int *invalid;
01236 {
01237 int test = insn[0] & I(-1);
01238
01239 if (!(test == I(1)))
01240 {
01241 if ((ls_operand[LS_DEST] == OP_SHIMM || ls_operand[LS_BASE] == OP_SHIMM
01242 || ls_operand[LS_OFFSET] == OP_SHIMM))
01243 *invalid = 1;
01244 }
01245 if (!((LD_SYNTAX(OP_REG,OP_REG,OP_NONE) && (test == I(1)))
01246 || LD_SYNTAX(OP_REG,OP_REG,OP_REG)
01247 || LD_SYNTAX(OP_REG,OP_REG,OP_SHIMM)
01248 || (LD_SYNTAX(OP_REG,OP_REG,OP_LIMM) && !(test == I(1)))
01249 || (LD_SYNTAX(OP_REG,OP_LIMM,OP_REG) && !(test == I(1)))
01250 || (LD_SYNTAX(OP_REG,OP_SHIMM,OP_NONE) && (shimm == 0))
01251 || LD_SYNTAX(OP_REG,OP_SHIMM,OP_SHIMM)
01252 || (LD_SYNTAX(OP_REG,OP_LIMM,OP_NONE) && (test == I(1)))))
01253 *invalid = 1;
01254 return 0;
01255 }
01256
01257
01258
01259
01260 static arc_insn
01261 insert_shimmfinish (insn, operand, mods, reg, value, errmsg)
01262 arc_insn insn;
01263 const struct arc_operand *operand;
01264 int mods ATTRIBUTE_UNUSED;
01265 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01266 long value ATTRIBUTE_UNUSED;
01267 const char **errmsg ATTRIBUTE_UNUSED;
01268 {
01269 if (shimm_p)
01270 insn |= (shimm & ((1 << operand->bits) - 1)) << operand->shift;
01271 return insn;
01272 }
01273
01274
01275
01276
01277
01278
01279
01280
01281
01282
01283
01284
01285
01286 static arc_insn
01287 insert_limmfinish (insn, operand, mods, reg, value, errmsg)
01288 arc_insn insn;
01289 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01290 int mods ATTRIBUTE_UNUSED;
01291 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01292 long value ATTRIBUTE_UNUSED;
01293 const char **errmsg ATTRIBUTE_UNUSED;
01294 {
01295 #if 0
01296 if (limm_p)
01297 ;
01298 #endif
01299 return insn;
01300 }
01301
01302 static arc_insn
01303 insert_jumpflags (insn, operand, mods, reg, value, errmsg)
01304 arc_insn insn;
01305 const struct arc_operand *operand;
01306 int mods ATTRIBUTE_UNUSED;
01307 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01308 long value;
01309 const char **errmsg;
01310 {
01311 if (!flag_p)
01312 {
01313 *errmsg = "jump flags, but no .f seen";
01314 }
01315 if (!limm_p)
01316 {
01317 *errmsg = "jump flags, but no limm addr";
01318 }
01319 if (limm & 0xfc000000)
01320 {
01321 *errmsg = "flag bits of jump address limm lost";
01322 }
01323 if (limm & 0x03000000)
01324 {
01325 *errmsg = "attempt to set HR bits";
01326 }
01327 if ((value & ((1 << operand->bits) - 1)) != value)
01328 {
01329 *errmsg = "bad jump flags value";
01330 }
01331 jumpflags_p = 1;
01332 limm = ((limm & ((1 << operand->shift) - 1))
01333 | ((value & ((1 << operand->bits) - 1)) << operand->shift));
01334 return insn;
01335 }
01336
01337
01338
01339 static arc_insn
01340 insert_unopmacro (insn, operand, mods, reg, value, errmsg)
01341 arc_insn insn;
01342 const struct arc_operand *operand;
01343 int mods ATTRIBUTE_UNUSED;
01344 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01345 long value ATTRIBUTE_UNUSED;
01346 const char **errmsg ATTRIBUTE_UNUSED;
01347 {
01348 insn |= ((insn >> ARC_SHIFT_REGB) & ARC_MASK_REG) << operand->shift;
01349 return insn;
01350 }
01351
01352
01353
01354 static arc_insn
01355 insert_reladdr (insn, operand, mods, reg, value, errmsg)
01356 arc_insn insn;
01357 const struct arc_operand *operand;
01358 int mods ATTRIBUTE_UNUSED;
01359 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01360 long value;
01361 const char **errmsg;
01362 {
01363 if (value & 3)
01364 *errmsg = "branch address not on 4 byte boundary";
01365 insn |= ((value >> 2) & ((1 << operand->bits) - 1)) << operand->shift;
01366 return insn;
01367 }
01368
01369
01370
01371
01372
01373
01374
01375
01376
01377
01378
01379
01380
01381
01382
01383 static arc_insn
01384 insert_absaddr (insn, operand, mods, reg, value, errmsg)
01385 arc_insn insn;
01386 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01387 int mods ATTRIBUTE_UNUSED;
01388 const struct arc_operand_value *reg ATTRIBUTE_UNUSED;
01389 long value ATTRIBUTE_UNUSED;
01390 const char **errmsg;
01391 {
01392 if (limm_p)
01393 {
01394
01395 if (insn & R(-1,9,1))
01396 {
01397 if (!nullify_p)
01398 {
01399 insn |= 0x02 << 5;
01400 }
01401 else
01402 {
01403 if (nullify != 0x02)
01404 {
01405 *errmsg = "must specify .jd or no nullify suffix";
01406 }
01407 }
01408 }
01409 }
01410 return insn;
01411 }
01412
01413
01414
01415
01416
01417
01418
01419
01420 static const struct arc_operand_value *lookup_register (int type, long regno);
01421
01422
01423
01424 void
01425 arc_opcode_init_extract ()
01426 {
01427 arc_opcode_init_insert();
01428 }
01429
01430
01431
01432
01433
01434
01435
01436
01437 static long
01438 extract_reg (insn, operand, mods, opval, invalid)
01439 arc_insn *insn;
01440 const struct arc_operand *operand;
01441 int mods;
01442 const struct arc_operand_value **opval;
01443 int *invalid ATTRIBUTE_UNUSED;
01444 {
01445 int regno;
01446 long value;
01447 enum operand op_type;
01448
01449
01450 regno = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
01451
01452
01453 if (regno == ARC_REG_SHIMM)
01454 {
01455 op_type = OP_SHIMM;
01456
01457
01458 if ('a' != operand->fmt)
01459 {
01460 value = *insn & 511;
01461 if ((operand->flags & ARC_OPERAND_SIGNED)
01462 && (value & 256))
01463 value -= 512;
01464 if (!flagshimm_handled_p)
01465 flag_p = 0;
01466 flagshimm_handled_p = 1;
01467 }
01468 else
01469 {
01470 value = 0;
01471 }
01472 }
01473 else if (regno == ARC_REG_SHIMM_UPDATE)
01474 {
01475 op_type = OP_SHIMM;
01476
01477
01478
01479 if ('a' != operand->fmt)
01480 {
01481 value = *insn & 511;
01482 if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
01483 value -= 512;
01484 }
01485 else
01486 {
01487 value = 0;
01488 }
01489 flag_p = 1;
01490 flagshimm_handled_p = 1;
01491 }
01492 else if (regno == ARC_REG_LIMM)
01493 {
01494 op_type = OP_LIMM;
01495 value = insn[1];
01496 limm_p = 1;
01497
01498 if (0x07 == ((*insn & I(-1)) >> 27))
01499 {
01500 value = (value & 0xffffff);
01501 }
01502 }
01503
01504
01505 else
01506 {
01507 const struct arc_operand_value *reg = lookup_register (REG, regno);
01508 op_type = OP_REG;
01509
01510 if (reg == NULL)
01511 abort ();
01512 if (opval != NULL)
01513 *opval = reg;
01514 value = regno;
01515 }
01516
01517
01518 if ((mods & ARC_MOD_AUXREG)
01519 && ARC_REG_CONSTANT_P (regno))
01520 {
01521 const struct arc_operand_value *reg = lookup_register (AUXREG, value);
01522
01523
01524
01525 if (reg != NULL && opval != NULL)
01526 *opval = reg;
01527 }
01528 switch(operand->fmt)
01529 {
01530 case 'a':
01531 ls_operand[LS_DEST] = op_type;
01532 break;
01533 case 's':
01534 ls_operand[LS_BASE] = op_type;
01535 break;
01536 case 'c':
01537 if ((insn[0]& I(-1)) == I(2))
01538 ls_operand[LS_VALUE] = op_type;
01539 else
01540 ls_operand[LS_OFFSET] = op_type;
01541 break;
01542 case 'o': case 'O':
01543 ls_operand[LS_OFFSET] = op_type;
01544 break;
01545 }
01546
01547 return value;
01548 }
01549
01550
01551
01552
01553 static long
01554 extract_flag (insn, operand, mods, opval, invalid)
01555 arc_insn *insn;
01556 const struct arc_operand *operand;
01557 int mods ATTRIBUTE_UNUSED;
01558 const struct arc_operand_value **opval;
01559 int *invalid ATTRIBUTE_UNUSED;
01560 {
01561 int f;
01562 const struct arc_operand_value *val;
01563
01564 if (flagshimm_handled_p)
01565 f = flag_p != 0;
01566 else
01567 f = (*insn & (1 << operand->shift)) != 0;
01568
01569
01570 if (f == 0)
01571 return 0;
01572 flag_p = 1;
01573 val = arc_opcode_lookup_suffix (operand, 1);
01574 if (opval != NULL && val != NULL)
01575 *opval = val;
01576 return val->value;
01577 }
01578
01579
01580
01581
01582
01583
01584 static long
01585 extract_cond (insn, operand, mods, opval, invalid)
01586 arc_insn *insn;
01587 const struct arc_operand *operand;
01588 int mods ATTRIBUTE_UNUSED;
01589 const struct arc_operand_value **opval;
01590 int *invalid ATTRIBUTE_UNUSED;
01591 {
01592 long cond;
01593 const struct arc_operand_value *val;
01594
01595 if (flagshimm_handled_p)
01596 return 0;
01597
01598 cond = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
01599 val = arc_opcode_lookup_suffix (operand, cond);
01600
01601
01602
01603 if (opval != NULL && val != NULL)
01604 *opval = val;
01605 return cond;
01606 }
01607
01608
01609
01610
01611 static long
01612 extract_reladdr (insn, operand, mods, opval, invalid)
01613 arc_insn *insn;
01614 const struct arc_operand *operand;
01615 int mods ATTRIBUTE_UNUSED;
01616 const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
01617 int *invalid ATTRIBUTE_UNUSED;
01618 {
01619 long addr;
01620
01621 addr = (*insn >> operand->shift) & ((1 << operand->bits) - 1);
01622 if ((operand->flags & ARC_OPERAND_SIGNED)
01623 && (addr & (1 << (operand->bits - 1))))
01624 addr -= 1 << operand->bits;
01625 return addr << 2;
01626 }
01627
01628
01629 static long
01630 extract_jumpflags(insn, operand, mods, opval, invalid)
01631 arc_insn *insn;
01632 const struct arc_operand *operand;
01633 int mods ATTRIBUTE_UNUSED;
01634 const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
01635 int *invalid;
01636 {
01637 if (!flag_p || !limm_p)
01638 *invalid = 1;
01639 return ((flag_p && limm_p)
01640 ? (insn[1] >> operand->shift) & ((1 << operand->bits) -1): 0);
01641 }
01642
01643
01644
01645 static long
01646 extract_st_offset (insn, operand, mods, opval, invalid)
01647 arc_insn *insn;
01648 const struct arc_operand *operand;
01649 int mods ATTRIBUTE_UNUSED;
01650 const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
01651 int *invalid;
01652 {
01653 int value = 0;
01654
01655 if (ls_operand[LS_VALUE] != OP_SHIMM || ls_operand[LS_BASE] != OP_LIMM)
01656 {
01657 value = insn[0] & 511;
01658 if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
01659 value -= 512;
01660 if (value)
01661 ls_operand[LS_OFFSET] = OP_SHIMM;
01662 }
01663 else
01664 {
01665 *invalid = 1;
01666 }
01667 return(value);
01668 }
01669
01670
01671
01672 static long
01673 extract_ld_offset (insn, operand, mods, opval, invalid)
01674 arc_insn *insn;
01675 const struct arc_operand *operand;
01676 int mods;
01677 const struct arc_operand_value **opval;
01678 int *invalid;
01679 {
01680 int test = insn[0] & I(-1);
01681 int value;
01682
01683 if (test)
01684 {
01685 value = insn[0] & 511;
01686 if ((operand->flags & ARC_OPERAND_SIGNED) && (value & 256))
01687 value -= 512;
01688 if (value)
01689 ls_operand[LS_OFFSET] = OP_SHIMM;
01690 return(value);
01691 }
01692
01693 return extract_reg (insn, &arc_operands[arc_operand_map['c']],
01694 mods, opval, invalid);
01695 }
01696
01697
01698
01699
01700
01701 static long
01702 extract_unopmacro (insn, operand, mods, opval, invalid)
01703 arc_insn *insn;
01704 const struct arc_operand *operand ATTRIBUTE_UNUSED;
01705 int mods ATTRIBUTE_UNUSED;
01706 const struct arc_operand_value **opval ATTRIBUTE_UNUSED;
01707 int *invalid;
01708 {
01709
01710
01711
01712 if (((*insn >> ARC_SHIFT_REGB) & ARC_MASK_REG)
01713 != ((*insn >> ARC_SHIFT_REGC) & ARC_MASK_REG))
01714 if (invalid != NULL)
01715 *invalid = 1;
01716 return 0;
01717 }
01718
01719
01720
01721
01722 const struct arc_operand_value *
01723 arc_opcode_lookup_suffix (type, value)
01724 const struct arc_operand *type;
01725 int value;
01726 {
01727 register const struct arc_operand_value *v,*end;
01728 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
01729
01730 while (ext_oper)
01731 {
01732 if (type == &arc_operands[ext_oper->operand.type]
01733 && value == ext_oper->operand.value)
01734 return (&ext_oper->operand);
01735 ext_oper = ext_oper->next;
01736 }
01737
01738
01739
01740 for (v = arc_suffixes, end = arc_suffixes + arc_suffixes_count; v < end; ++v)
01741 if (type == &arc_operands[v->type]
01742 && value == v->value)
01743 return v;
01744 return 0;
01745 }
01746
01747 static const struct arc_operand_value *
01748 lookup_register (type, regno)
01749 int type;
01750 long regno;
01751 {
01752 register const struct arc_operand_value *r,*end;
01753 struct arc_ext_operand_value *ext_oper = arc_ext_operands;
01754
01755 while (ext_oper)
01756 {
01757 if (ext_oper->operand.type == type && ext_oper->operand.value == regno)
01758 return (&ext_oper->operand);
01759 ext_oper = ext_oper->next;
01760 }
01761
01762 if (type == REG)
01763 return &arc_reg_names[regno];
01764
01765
01766
01767 for (r = arc_reg_names, end = arc_reg_names + arc_reg_names_count;
01768 r < end; ++r)
01769 if (type == r->type && regno == r->value)
01770 return r;
01771 return 0;
01772 }
01773
01774 int
01775 arc_insn_is_j(insn)
01776 arc_insn insn;
01777 {
01778 return (insn & (I(-1))) == I(0x7);
01779 }
01780
01781 int
01782 arc_insn_not_jl(insn)
01783 arc_insn insn;
01784 {
01785 return ((insn & (I(-1)|A(-1)|C(-1)|R(-1,7,1)|R(-1,9,1)))
01786 != (I(0x7) | R(-1,9,1)));
01787 }
01788
01789 int
01790 arc_operand_type(int opertype)
01791 {
01792 switch (opertype)
01793 {
01794 case 0:
01795 return(COND);
01796 break;
01797 case 1:
01798 return(REG);
01799 break;
01800 case 2:
01801 return(AUXREG);
01802 break;
01803 }
01804 return -1;
01805 }
01806
01807 struct arc_operand_value *
01808 get_ext_suffix(s)
01809 char *s;
01810 {
01811 struct arc_ext_operand_value *suffix = arc_ext_operands;
01812
01813 while (suffix)
01814 {
01815 if ((COND == suffix->operand.type)
01816 && !strcmp(s,suffix->operand.name))
01817 return(&suffix->operand);
01818 suffix = suffix->next;
01819 }
01820 return NULL;
01821 }
01822
01823 int
01824 arc_get_noshortcut_flag()
01825 {
01826 return ARC_REGISTER_NOSHORT_CUT;
01827 }