00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "sysdep.h"
00021 #include "dis-asm.h"
00022
00023 static const char *const reg_names[] = {
00024 "pfp", "sp", "rip", "r3", "r4", "r5", "r6", "r7",
00025 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
00026 "g0", "g1", "g2", "g3", "g4", "g5", "g6", "g7",
00027 "g8", "g9", "g10", "g11", "g12", "g13", "g14", "fp",
00028 "pc", "ac", "ip", "tc", "fp0", "fp1", "fp2", "fp3"
00029 };
00030
00031
00032 static FILE *stream;
00033 static struct disassemble_info *info;
00034 static void print_addr (bfd_vma);
00035 static void ctrl (bfd_vma, unsigned long, unsigned long);
00036 static void cobr (bfd_vma, unsigned long, unsigned long);
00037 static void reg (unsigned long);
00038 static int mem (bfd_vma, unsigned long, unsigned long, int);
00039 static void ea (bfd_vma, int, const char *, const char *, int, unsigned int);
00040 static void dstop (int, int, int);
00041 static void regop (int, int, int, int);
00042 static void invalid (int);
00043 static int pinsn (bfd_vma, unsigned long, unsigned long);
00044 static void put_abs (unsigned long, unsigned long);
00045
00046
00047
00048
00049
00050 int
00051 print_insn_i960 (bfd_vma memaddr, struct disassemble_info *info_arg)
00052 {
00053 unsigned int word1, word2 = 0xdeadbeef;
00054 bfd_byte buffer[8];
00055 int status;
00056
00057 info = info_arg;
00058 stream = info->stream;
00059
00060
00061
00062
00063 status = (*info->read_memory_func) (memaddr, (bfd_byte *) buffer, 4, info);
00064 if (status != 0)
00065 {
00066 (*info->memory_error_func) (status, memaddr, info);
00067 return -1;
00068 }
00069
00070 word1 = bfd_getl32 (buffer);
00071
00072
00073 switch ( (word1 >> 28) & 0xf )
00074 {
00075 default:
00076 break;
00077 case 0x8:
00078 case 0x9:
00079 case 0xa:
00080 case 0xb:
00081 case 0xc:
00082
00083 status = (*info->read_memory_func)
00084 (memaddr + 4, (bfd_byte *) (buffer + 4), 4, info);
00085 if (status != 0)
00086 {
00087 (*info->memory_error_func) (status, memaddr, info);
00088 return -1;
00089 }
00090 word2 = bfd_getl32 (buffer + 4);
00091 break;
00092 }
00093
00094 return pinsn( memaddr, word1, word2 );
00095 }
00096
00097 #define IN_GDB
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107 struct tabent {
00108 char *name;
00109 short numops;
00110 };
00111
00112 struct sparse_tabent {
00113 int opcode;
00114 char *name;
00115 short numops;
00116 };
00117
00118 static int
00119 pinsn (bfd_vma memaddr, unsigned long word1, unsigned long word2)
00120 {
00121 int instr_len;
00122
00123 instr_len = 4;
00124 put_abs (word1, word2);
00125
00126
00127 switch ((word1 >> 28) & 0xf)
00128 {
00129 case 0x0:
00130 case 0x1:
00131 ctrl (memaddr, word1, word2);
00132 break;
00133 case 0x2:
00134 case 0x3:
00135 cobr (memaddr, word1, word2);
00136 break;
00137 case 0x5:
00138 case 0x6:
00139 case 0x7:
00140 reg (word1);
00141 break;
00142 case 0x8:
00143 case 0x9:
00144 case 0xa:
00145 case 0xb:
00146 case 0xc:
00147 instr_len = mem (memaddr, word1, word2, 0);
00148 break;
00149 default:
00150
00151 invalid (word1);
00152 break;
00153 }
00154 return instr_len;
00155 }
00156
00157
00158
00159 static void
00160 ctrl (bfd_vma memaddr, unsigned long word1, unsigned long word2 ATTRIBUTE_UNUSED)
00161 {
00162 int i;
00163 static const struct tabent ctrl_tab[] = {
00164 { NULL, 0, },
00165 { NULL, 0, },
00166 { NULL, 0, },
00167 { NULL, 0, },
00168 { NULL, 0, },
00169 { NULL, 0, },
00170 { NULL, 0, },
00171 { NULL, 0, },
00172 { "b", 1, },
00173 { "call", 1, },
00174 { "ret", 0, },
00175 { "bal", 1, },
00176 { NULL, 0, },
00177 { NULL, 0, },
00178 { NULL, 0, },
00179 { NULL, 0, },
00180 { "bno", 1, },
00181 { "bg", 1, },
00182 { "be", 1, },
00183 { "bge", 1, },
00184 { "bl", 1, },
00185 { "bne", 1, },
00186 { "ble", 1, },
00187 { "bo", 1, },
00188 { "faultno", 0, },
00189 { "faultg", 0, },
00190 { "faulte", 0, },
00191 { "faultge", 0, },
00192 { "faultl", 0, },
00193 { "faultne", 0, },
00194 { "faultle", 0, },
00195 { "faulto", 0, },
00196 };
00197
00198 i = (word1 >> 24) & 0xff;
00199 if ((ctrl_tab[i].name == NULL) || ((word1 & 1) != 0))
00200 {
00201 invalid (word1);
00202 return;
00203 }
00204
00205 (*info->fprintf_func) (stream, ctrl_tab[i].name);
00206 if (word1 & 2)
00207
00208 (*info->fprintf_func) (stream, ".f");
00209
00210 if (ctrl_tab[i].numops == 1)
00211 {
00212
00213 word1 &= 0x00ffffff;
00214
00215 if (word1 & 0x00800000)
00216 {
00217
00218 word1 |= (-1 & ~0xffffff);
00219 }
00220
00221 (*info->fprintf_func) (stream, "\t");
00222 print_addr (word1 + memaddr);
00223 }
00224 }
00225
00226
00227
00228 static void
00229 cobr (bfd_vma memaddr, unsigned long word1, unsigned long word2 ATTRIBUTE_UNUSED)
00230 {
00231 int src1;
00232 int src2;
00233 int i;
00234
00235 static const struct tabent cobr_tab[] = {
00236 { "testno", 1, },
00237 { "testg", 1, },
00238 { "teste", 1, },
00239 { "testge", 1, },
00240 { "testl", 1, },
00241 { "testne", 1, },
00242 { "testle", 1, },
00243 { "testo", 1, },
00244 { NULL, 0, },
00245 { NULL, 0, },
00246 { NULL, 0, },
00247 { NULL, 0, },
00248 { NULL, 0, },
00249 { NULL, 0, },
00250 { NULL, 0, },
00251 { NULL, 0, },
00252 { "bbc", 3, },
00253 { "cmpobg", 3, },
00254 { "cmpobe", 3, },
00255 { "cmpobge",3, },
00256 { "cmpobl", 3, },
00257 { "cmpobne",3, },
00258 { "cmpoble",3, },
00259 { "bbs", 3, },
00260 { "cmpibno",3, },
00261 { "cmpibg", 3, },
00262 { "cmpibe", 3, },
00263 { "cmpibge",3, },
00264 { "cmpibl", 3, },
00265 { "cmpibne",3, },
00266 { "cmpible",3, },
00267 { "cmpibo", 3, },
00268 };
00269
00270 i = ((word1 >> 24) & 0xff) - 0x20;
00271 if (cobr_tab[i].name == NULL)
00272 {
00273 invalid (word1);
00274 return;
00275 }
00276
00277 (*info->fprintf_func) (stream, cobr_tab[i].name);
00278
00279
00280 if (word1 & 2)
00281 (*info->fprintf_func) (stream, ".f");
00282
00283 (*info->fprintf_func) (stream, "\t");
00284
00285 src1 = (word1 >> 19) & 0x1f;
00286 src2 = (word1 >> 14) & 0x1f;
00287
00288 if (word1 & 0x02000)
00289
00290 (*info->fprintf_func) (stream, "%d", src1);
00291 else
00292 (*info->fprintf_func) (stream, reg_names[src1]);
00293
00294 if (cobr_tab[i].numops > 1)
00295 {
00296 if (word1 & 1)
00297
00298 (*info->fprintf_func) (stream, ",sf%d,", src2);
00299 else
00300
00301 (*info->fprintf_func) (stream, ",%s,", reg_names[src2]);
00302
00303
00304 word1 &= 0x00001ffc;
00305 if (word1 & 0x00001000)
00306
00307 word1 |= (-1 & ~0x1fff);
00308
00309 print_addr (memaddr + word1);
00310 }
00311 }
00312
00313
00314
00315
00316 static int
00317 mem (bfd_vma memaddr, unsigned long word1, unsigned long word2, int noprint)
00318 {
00319 int i, j;
00320 int len;
00321 int mode;
00322 int offset;
00323 const char *reg1, *reg2, *reg3;
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333 static struct tabent *mem_tab;
00334
00335 #define MEM_MIN 0x80
00336 #define MEM_MAX 0xcf
00337 #define MEM_SIZ ( * sizeof(struct tabent))
00338
00339 static const struct sparse_tabent mem_init[] = {
00340 { 0x80, "ldob", 2 },
00341 { 0x82, "stob", -2 },
00342 { 0x84, "bx", 1 },
00343 { 0x85, "balx", 2 },
00344 { 0x86, "callx", 1 },
00345 { 0x88, "ldos", 2 },
00346 { 0x8a, "stos", -2 },
00347 { 0x8c, "lda", 2 },
00348 { 0x90, "ld", 2 },
00349 { 0x92, "st", -2 },
00350 { 0x98, "ldl", 2 },
00351 { 0x9a, "stl", -2 },
00352 { 0xa0, "ldt", 2 },
00353 { 0xa2, "stt", -2 },
00354 { 0xac, "dcinva", 1 },
00355 { 0xb0, "ldq", 2 },
00356 { 0xb2, "stq", -2 },
00357 { 0xc0, "ldib", 2 },
00358 { 0xc2, "stib", -2 },
00359 { 0xc8, "ldis", 2 },
00360 { 0xca, "stis", -2 },
00361 { 0, NULL, 0 }
00362 };
00363 static struct tabent mem_tab_buf[MEM_MAX - MEM_MIN + 1];
00364
00365 if (mem_tab == NULL)
00366 {
00367 mem_tab = mem_tab_buf;
00368
00369 for (i = 0; mem_init[i].opcode != 0; i++)
00370 {
00371 j = mem_init[i].opcode - MEM_MIN;
00372 mem_tab[j].name = mem_init[i].name;
00373 mem_tab[j].numops = mem_init[i].numops;
00374 }
00375 }
00376
00377 i = ((word1 >> 24) & 0xff) - MEM_MIN;
00378 mode = (word1 >> 10) & 0xf;
00379
00380 if ((mem_tab[i].name != NULL)
00381 && ((mode == 5) || (mode >= 12)))
00382
00383 len = 8;
00384 else
00385 len = 4;
00386
00387 if (noprint)
00388 return len;
00389
00390 if ((mem_tab[i].name == NULL) || (mode == 6))
00391 {
00392 invalid (word1);
00393 return len;
00394 }
00395
00396 (*info->fprintf_func) (stream, "%s\t", mem_tab[i].name);
00397
00398 reg1 = reg_names[ (word1 >> 19) & 0x1f ];
00399 reg2 = reg_names[ (word1 >> 14) & 0x1f ];
00400 reg3 = reg_names[ word1 & 0x1f ];
00401 offset = word1 & 0xfff;
00402
00403 switch (mem_tab[i].numops)
00404 {
00405 case 2:
00406 if (mode & 4)
00407 {
00408 ea (memaddr, mode, reg2, reg3, word1, word2);
00409 (*info->fprintf_func) (stream, ",%s", reg1);
00410 }
00411 else
00412 {
00413 (*info->fprintf_func) (stream, "0x%x", (unsigned) offset);
00414
00415 if (mode & 8)
00416 (*info->fprintf_func) (stream, "(%s)", reg2);
00417
00418 (*info->fprintf_func)(stream, ",%s", reg1);
00419 }
00420 break;
00421
00422 case -2:
00423 if (mode & 4)
00424 {
00425
00426 (*info->fprintf_func) (stream, "%s,", reg1);
00427 ea (memaddr, mode, reg2, reg3, word1, word2);
00428 }
00429 else
00430 {
00431
00432 (*info->fprintf_func) (stream, "%s,0x%x", reg1, (unsigned) offset);
00433
00434 if (mode & 8)
00435 (*info->fprintf_func) (stream, "(%s)", reg2);
00436 }
00437 break;
00438
00439 case 1:
00440 if (mode & 4)
00441 {
00442
00443 ea (memaddr, mode, reg2, reg3, word1, word2);
00444 }
00445 else
00446 {
00447
00448 (*info->fprintf_func) (stream, "0x%x", (unsigned) offset);
00449 if (mode & 8)
00450 (*info->fprintf_func) (stream, "(%s)", reg2);
00451 }
00452 break;
00453 }
00454
00455 return len;
00456 }
00457
00458
00459
00460 static void
00461 reg (unsigned long word1)
00462 {
00463 int i, j;
00464 int opcode;
00465 int fp;
00466 int m1, m2, m3;
00467 int s1, s2;
00468 int src, src2, dst;
00469 char *mnemp;
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485 static struct tabent *reg_tab;
00486 static const struct sparse_tabent reg_init[] =
00487 {
00488 #define REG_MIN 0x580
00489 { 0x580, "notbit", 3 },
00490 { 0x581, "and", 3 },
00491 { 0x582, "andnot", 3 },
00492 { 0x583, "setbit", 3 },
00493 { 0x584, "notand", 3 },
00494 { 0x586, "xor", 3 },
00495 { 0x587, "or", 3 },
00496 { 0x588, "nor", 3 },
00497 { 0x589, "xnor", 3 },
00498 { 0x58a, "not", -2 },
00499 { 0x58b, "ornot", 3 },
00500 { 0x58c, "clrbit", 3 },
00501 { 0x58d, "notor", 3 },
00502 { 0x58e, "nand", 3 },
00503 { 0x58f, "alterbit", 3 },
00504 { 0x590, "addo", 3 },
00505 { 0x591, "addi", 3 },
00506 { 0x592, "subo", 3 },
00507 { 0x593, "subi", 3 },
00508 { 0x594, "cmpob", 2 },
00509 { 0x595, "cmpib", 2 },
00510 { 0x596, "cmpos", 2 },
00511 { 0x597, "cmpis", 2 },
00512 { 0x598, "shro", 3 },
00513 { 0x59a, "shrdi", 3 },
00514 { 0x59b, "shri", 3 },
00515 { 0x59c, "shlo", 3 },
00516 { 0x59d, "rotate", 3 },
00517 { 0x59e, "shli", 3 },
00518 { 0x5a0, "cmpo", 2 },
00519 { 0x5a1, "cmpi", 2 },
00520 { 0x5a2, "concmpo", 2 },
00521 { 0x5a3, "concmpi", 2 },
00522 { 0x5a4, "cmpinco", 3 },
00523 { 0x5a5, "cmpinci", 3 },
00524 { 0x5a6, "cmpdeco", 3 },
00525 { 0x5a7, "cmpdeci", 3 },
00526 { 0x5ac, "scanbyte", 2 },
00527 { 0x5ad, "bswap", -2 },
00528 { 0x5ae, "chkbit", 2 },
00529 { 0x5b0, "addc", 3 },
00530 { 0x5b2, "subc", 3 },
00531 { 0x5b4, "intdis", 0 },
00532 { 0x5b5, "inten", 0 },
00533 { 0x5cc, "mov", -2 },
00534 { 0x5d8, "eshro", 3 },
00535 { 0x5dc, "movl", -2 },
00536 { 0x5ec, "movt", -2 },
00537 { 0x5fc, "movq", -2 },
00538 { 0x600, "synmov", 2 },
00539 { 0x601, "synmovl", 2 },
00540 { 0x602, "synmovq", 2 },
00541 { 0x603, "cmpstr", 3 },
00542 { 0x604, "movqstr", 3 },
00543 { 0x605, "movstr", 3 },
00544 { 0x610, "atmod", 3 },
00545 { 0x612, "atadd", 3 },
00546 { 0x613, "inspacc", -2 },
00547 { 0x614, "ldphy", -2 },
00548 { 0x615, "synld", -2 },
00549 { 0x617, "fill", 3 },
00550 { 0x630, "sdma", 3 },
00551 { 0x631, "udma", 0 },
00552 { 0x640, "spanbit", -2 },
00553 { 0x641, "scanbit", -2 },
00554 { 0x642, "daddc", 3 },
00555 { 0x643, "dsubc", 3 },
00556 { 0x644, "dmovt", -2 },
00557 { 0x645, "modac", 3 },
00558 { 0x646, "condrec", -2 },
00559 { 0x650, "modify", 3 },
00560 { 0x651, "extract", 3 },
00561 { 0x654, "modtc", 3 },
00562 { 0x655, "modpc", 3 },
00563 { 0x656, "receive", -2 },
00564 { 0x658, "intctl", -2 },
00565 { 0x659, "sysctl", 3 },
00566 { 0x65b, "icctl", 3 },
00567 { 0x65c, "dcctl", 3 },
00568 { 0x65d, "halt", 0 },
00569 { 0x660, "calls", 1 },
00570 { 0x662, "send", 3 },
00571 { 0x663, "sendserv", 1 },
00572 { 0x664, "resumprcs", 1 },
00573 { 0x665, "schedprcs", 1 },
00574 { 0x666, "saveprcs", 0 },
00575 { 0x668, "condwait", 1 },
00576 { 0x669, "wait", 1 },
00577 { 0x66a, "signal", 1 },
00578 { 0x66b, "mark", 0 },
00579 { 0x66c, "fmark", 0 },
00580 { 0x66d, "flushreg", 0 },
00581 { 0x66f, "syncf", 0 },
00582 { 0x670, "emul", 3 },
00583 { 0x671, "ediv", 3 },
00584 { 0x673, "ldtime", -1 },
00585 { 0x674, "Fcvtir", -2 },
00586 { 0x675, "Fcvtilr", -2 },
00587 { 0x676, "Fscalerl", 3 },
00588 { 0x677, "Fscaler", 3 },
00589 { 0x680, "Fatanr", 3 },
00590 { 0x681, "Flogepr", 3 },
00591 { 0x682, "Flogr", 3 },
00592 { 0x683, "Fremr", 3 },
00593 { 0x684, "Fcmpor", 2 },
00594 { 0x685, "Fcmpr", 2 },
00595 { 0x688, "Fsqrtr", -2 },
00596 { 0x689, "Fexpr", -2 },
00597 { 0x68a, "Flogbnr", -2 },
00598 { 0x68b, "Froundr", -2 },
00599 { 0x68c, "Fsinr", -2 },
00600 { 0x68d, "Fcosr", -2 },
00601 { 0x68e, "Ftanr", -2 },
00602 { 0x68f, "Fclassr", 1 },
00603 { 0x690, "Fatanrl", 3 },
00604 { 0x691, "Flogeprl", 3 },
00605 { 0x692, "Flogrl", 3 },
00606 { 0x693, "Fremrl", 3 },
00607 { 0x694, "Fcmporl", 2 },
00608 { 0x695, "Fcmprl", 2 },
00609 { 0x698, "Fsqrtrl", -2 },
00610 { 0x699, "Fexprl", -2 },
00611 { 0x69a, "Flogbnrl", -2 },
00612 { 0x69b, "Froundrl", -2 },
00613 { 0x69c, "Fsinrl", -2 },
00614 { 0x69d, "Fcosrl", -2 },
00615 { 0x69e, "Ftanrl", -2 },
00616 { 0x69f, "Fclassrl", 1 },
00617 { 0x6c0, "Fcvtri", -2 },
00618 { 0x6c1, "Fcvtril", -2 },
00619 { 0x6c2, "Fcvtzri", -2 },
00620 { 0x6c3, "Fcvtzril", -2 },
00621 { 0x6c9, "Fmovr", -2 },
00622 { 0x6d9, "Fmovrl", -2 },
00623 { 0x6e1, "Fmovre", -2 },
00624 { 0x6e2, "Fcpysre", 3 },
00625 { 0x6e3, "Fcpyrsre", 3 },
00626 { 0x701, "mulo", 3 },
00627 { 0x708, "remo", 3 },
00628 { 0x70b, "divo", 3 },
00629 { 0x741, "muli", 3 },
00630 { 0x748, "remi", 3 },
00631 { 0x749, "modi", 3 },
00632 { 0x74b, "divi", 3 },
00633 { 0x780, "addono", 3 },
00634 { 0x781, "addino", 3 },
00635 { 0x782, "subono", 3 },
00636 { 0x783, "subino", 3 },
00637 { 0x784, "selno", 3 },
00638 { 0x78b, "Fdivr", 3 },
00639 { 0x78c, "Fmulr", 3 },
00640 { 0x78d, "Fsubr", 3 },
00641 { 0x78f, "Faddr", 3 },
00642 { 0x790, "addog", 3 },
00643 { 0x791, "addig", 3 },
00644 { 0x792, "subog", 3 },
00645 { 0x793, "subig", 3 },
00646 { 0x794, "selg", 3 },
00647 { 0x79b, "Fdivrl", 3 },
00648 { 0x79c, "Fmulrl", 3 },
00649 { 0x79d, "Fsubrl", 3 },
00650 { 0x79f, "Faddrl", 3 },
00651 { 0x7a0, "addoe", 3 },
00652 { 0x7a1, "addie", 3 },
00653 { 0x7a2, "suboe", 3 },
00654 { 0x7a3, "subie", 3 },
00655 { 0x7a4, "sele", 3 },
00656 { 0x7b0, "addoge", 3 },
00657 { 0x7b1, "addige", 3 },
00658 { 0x7b2, "suboge", 3 },
00659 { 0x7b3, "subige", 3 },
00660 { 0x7b4, "selge", 3 },
00661 { 0x7c0, "addol", 3 },
00662 { 0x7c1, "addil", 3 },
00663 { 0x7c2, "subol", 3 },
00664 { 0x7c3, "subil", 3 },
00665 { 0x7c4, "sell", 3 },
00666 { 0x7d0, "addone", 3 },
00667 { 0x7d1, "addine", 3 },
00668 { 0x7d2, "subone", 3 },
00669 { 0x7d3, "subine", 3 },
00670 { 0x7d4, "selne", 3 },
00671 { 0x7e0, "addole", 3 },
00672 { 0x7e1, "addile", 3 },
00673 { 0x7e2, "subole", 3 },
00674 { 0x7e3, "subile", 3 },
00675 { 0x7e4, "selle", 3 },
00676 { 0x7f0, "addoo", 3 },
00677 { 0x7f1, "addio", 3 },
00678 { 0x7f2, "suboo", 3 },
00679 { 0x7f3, "subio", 3 },
00680 { 0x7f4, "selo", 3 },
00681 #define REG_MAX 0x7f4
00682 { 0, NULL, 0 }
00683 };
00684 static struct tabent reg_tab_buf[REG_MAX - REG_MIN + 1];
00685
00686 if (reg_tab == NULL)
00687 {
00688 reg_tab = reg_tab_buf;
00689
00690 for (i = 0; reg_init[i].opcode != 0; i++)
00691 {
00692 j = reg_init[i].opcode - REG_MIN;
00693 reg_tab[j].name = reg_init[i].name;
00694 reg_tab[j].numops = reg_init[i].numops;
00695 }
00696 }
00697
00698 opcode = ((word1 >> 20) & 0xff0) | ((word1 >> 7) & 0xf);
00699 i = opcode - REG_MIN;
00700
00701 if ((opcode<REG_MIN) || (opcode>REG_MAX) || (reg_tab[i].name==NULL))
00702 {
00703 invalid (word1);
00704 return;
00705 }
00706
00707 mnemp = reg_tab[i].name;
00708 if (*mnemp == 'F')
00709 {
00710 fp = 1;
00711 mnemp++;
00712 }
00713 else
00714 {
00715 fp = 0;
00716 }
00717
00718 (*info->fprintf_func) (stream, mnemp);
00719
00720 s1 = (word1 >> 5) & 1;
00721 s2 = (word1 >> 6) & 1;
00722 m1 = (word1 >> 11) & 1;
00723 m2 = (word1 >> 12) & 1;
00724 m3 = (word1 >> 13) & 1;
00725 src = word1 & 0x1f;
00726 src2 = (word1 >> 14) & 0x1f;
00727 dst = (word1 >> 19) & 0x1f;
00728
00729 if (reg_tab[i].numops != 0)
00730 {
00731 (*info->fprintf_func) (stream, "\t");
00732
00733 switch (reg_tab[i].numops)
00734 {
00735 case 1:
00736 regop (m1, s1, src, fp);
00737 break;
00738 case -1:
00739 dstop (m3, dst, fp);
00740 break;
00741 case 2:
00742 regop (m1, s1, src, fp);
00743 (*info->fprintf_func) (stream, ",");
00744 regop (m2, s2, src2, fp);
00745 break;
00746 case -2:
00747 regop (m1, s1, src, fp);
00748 (*info->fprintf_func) (stream, ",");
00749 dstop (m3, dst, fp);
00750 break;
00751 case 3:
00752 regop (m1, s1, src, fp);
00753 (*info->fprintf_func) (stream, ",");
00754 regop (m2, s2, src2, fp);
00755 (*info->fprintf_func) (stream, ",");
00756 dstop (m3, dst, fp);
00757 break;
00758 }
00759 }
00760 }
00761
00762
00763
00764 static void
00765 ea (bfd_vma memaddr, int mode, const char *reg2, const char *reg3, int word1,
00766 unsigned int word2)
00767 {
00768 int scale;
00769 static const int scale_tab[] = { 1, 2, 4, 8, 16 };
00770
00771 scale = (word1 >> 7) & 0x07;
00772
00773 if ((scale > 4) || (((word1 >> 5) & 0x03) != 0))
00774 {
00775 invalid (word1);
00776 return;
00777 }
00778 scale = scale_tab[scale];
00779
00780 switch (mode)
00781 {
00782 case 4:
00783 (*info->fprintf_func)( stream, "(%s)", reg2 );
00784 break;
00785 case 5:
00786 print_addr (word2 + 8 + memaddr);
00787 break;
00788 case 7:
00789 if (scale == 1)
00790 (*info->fprintf_func) (stream, "(%s)[%s]", reg2, reg3);
00791 else
00792 (*info->fprintf_func) (stream, "(%s)[%s*%d]", reg2, reg3, scale);
00793 break;
00794 case 12:
00795 print_addr ((bfd_vma) word2);
00796 break;
00797 case 13:
00798 print_addr ((bfd_vma) word2);
00799 (*info->fprintf_func) (stream, "(%s)", reg2);
00800 break;
00801 case 14:
00802 print_addr ((bfd_vma) word2);
00803 if (scale == 1)
00804 (*info->fprintf_func) (stream, "[%s]", reg3);
00805 else
00806 (*info->fprintf_func) (stream, "[%s*%d]", reg3, scale);
00807 break;
00808 case 15:
00809 print_addr ((bfd_vma) word2);
00810 if (scale == 1)
00811 (*info->fprintf_func) (stream, "(%s)[%s]", reg2, reg3);
00812 else
00813 (*info->fprintf_func) (stream, "(%s)[%s*%d]", reg2, reg3, scale);
00814 break;
00815 default:
00816 invalid (word1);
00817 return;
00818 }
00819 }
00820
00821
00822
00823
00824 static void
00825 regop (int mode, int spec, int reg, int fp)
00826 {
00827 if (fp)
00828 {
00829
00830 if (mode == 1)
00831 {
00832
00833 switch (reg)
00834 {
00835 case 0: (*info->fprintf_func) (stream, "fp0");
00836 break;
00837 case 1: (*info->fprintf_func) (stream, "fp1");
00838 break;
00839 case 2: (*info->fprintf_func) (stream, "fp2");
00840 break;
00841 case 3: (*info->fprintf_func) (stream, "fp3");
00842 break;
00843 case 16: (*info->fprintf_func) (stream, "0f0.0");
00844 break;
00845 case 22: (*info->fprintf_func) (stream, "0f1.0");
00846 break;
00847 default: (*info->fprintf_func) (stream, "?");
00848 break;
00849 }
00850 }
00851 else
00852 {
00853
00854 (*info->fprintf_func) (stream, reg_names[reg]);
00855 }
00856 }
00857 else
00858 {
00859
00860 if (mode == 1)
00861 {
00862
00863 (*info->fprintf_func) (stream, "%d", reg);
00864 }
00865 else
00866 {
00867
00868 if (spec == 0)
00869 (*info->fprintf_func) (stream, reg_names[reg]);
00870 else
00871 (*info->fprintf_func) (stream, "sf%d", reg);
00872 }
00873 }
00874 }
00875
00876
00877
00878 static void
00879 dstop (int mode, int reg, int fp)
00880 {
00881
00882
00883
00884 if (fp)
00885 regop (mode, 0, reg, fp);
00886 else
00887 regop (0, mode, reg, fp);
00888 }
00889
00890 static void
00891 invalid (int word1)
00892 {
00893 (*info->fprintf_func) (stream, ".word\t0x%08x", (unsigned) word1);
00894 }
00895
00896 static void
00897 print_addr (bfd_vma a)
00898 {
00899 (*info->print_address_func) (a, info);
00900 }
00901
00902 static void
00903 put_abs (unsigned long word1 ATTRIBUTE_UNUSED,
00904 unsigned long word2 ATTRIBUTE_UNUSED)
00905 {
00906 #ifdef IN_GDB
00907 return;
00908 #else
00909 int len;
00910
00911 switch ((word1 >> 28) & 0xf)
00912 {
00913 case 0x8:
00914 case 0x9:
00915 case 0xa:
00916 case 0xb:
00917 case 0xc:
00918
00919 len = mem (0, word1, word2, 1);
00920 break;
00921 default:
00922 len = 4;
00923 break;
00924 }
00925
00926 if (len == 8)
00927 (*info->fprintf_func) (stream, "%08x %08x\t", word1, word2);
00928 else
00929 (*info->fprintf_func) (stream, "%08x \t", word1);
00930 #endif
00931 }