00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023 #include <stdio.h>
00024 #include "sysdep.h"
00025 #define STATIC_TABLE
00026 #define DEFINE_TABLE
00027
00028 #include "sh-opc.h"
00029 #include "dis-asm.h"
00030
00031 #ifdef ARCH_all
00032 #define INCLUDE_SHMEDIA
00033 #endif
00034
00035 static void print_movxy
00036 PARAMS ((const sh_opcode_info *, int, int, fprintf_ftype, void *));
00037 static void print_insn_ddt PARAMS ((int, struct disassemble_info *));
00038 static void print_dsp_reg PARAMS ((int, fprintf_ftype, void *));
00039 static void print_insn_ppi PARAMS ((int, struct disassemble_info *));
00040
00041 static void
00042 print_movxy (op, rn, rm, fprintf_fn, stream)
00043 const sh_opcode_info *op;
00044 int rn, rm;
00045 fprintf_ftype fprintf_fn;
00046 void *stream;
00047 {
00048 int n;
00049
00050 fprintf_fn (stream, "%s\t", op->name);
00051 for (n = 0; n < 2; n++)
00052 {
00053 switch (op->arg[n])
00054 {
00055 case A_IND_N:
00056 case AX_IND_N:
00057 case AXY_IND_N:
00058 case AY_IND_N:
00059 case AYX_IND_N:
00060 fprintf_fn (stream, "@r%d", rn);
00061 break;
00062 case A_INC_N:
00063 case AX_INC_N:
00064 case AXY_INC_N:
00065 case AY_INC_N:
00066 case AYX_INC_N:
00067 fprintf_fn (stream, "@r%d+", rn);
00068 break;
00069 case AX_PMOD_N:
00070 case AXY_PMOD_N:
00071 fprintf_fn (stream, "@r%d+r8", rn);
00072 break;
00073 case AY_PMOD_N:
00074 case AYX_PMOD_N:
00075 fprintf_fn (stream, "@r%d+r9", rn);
00076 break;
00077 case DSP_REG_A_M:
00078 fprintf_fn (stream, "a%c", '0' + rm);
00079 break;
00080 case DSP_REG_X:
00081 fprintf_fn (stream, "x%c", '0' + rm);
00082 break;
00083 case DSP_REG_Y:
00084 fprintf_fn (stream, "y%c", '0' + rm);
00085 break;
00086 case DSP_REG_AX:
00087 fprintf_fn (stream, "%c%c",
00088 (rm & 1) ? 'x' : 'a',
00089 (rm & 2) ? '1' : '0');
00090 break;
00091 case DSP_REG_XY:
00092 fprintf_fn (stream, "%c%c",
00093 (rm & 1) ? 'y' : 'x',
00094 (rm & 2) ? '1' : '0');
00095 break;
00096 case DSP_REG_AY:
00097 fprintf_fn (stream, "%c%c",
00098 (rm & 2) ? 'y' : 'a',
00099 (rm & 1) ? '1' : '0');
00100 break;
00101 case DSP_REG_YX:
00102 fprintf_fn (stream, "%c%c",
00103 (rm & 2) ? 'x' : 'y',
00104 (rm & 1) ? '1' : '0');
00105 break;
00106 default:
00107 abort ();
00108 }
00109 if (n == 0)
00110 fprintf_fn (stream, ",");
00111 }
00112 }
00113
00114
00115
00116
00117
00118
00119 static void
00120 print_insn_ddt (insn, info)
00121 int insn;
00122 struct disassemble_info *info;
00123 {
00124 fprintf_ftype fprintf_fn = info->fprintf_func;
00125 void *stream = info->stream;
00126
00127
00128 if (insn == 0x000)
00129 fprintf_fn (stream, "nopx\tnopy");
00130
00131
00132
00133 if ((insn & 0x800) && (insn & 0x3ff))
00134 fprintf_fn (stream, "\t");
00135
00136
00137 if (((insn & 0xc) == 0 && (insn & 0x2a0))
00138 || ((insn & 3) == 0 && (insn & 0x150)))
00139 if (info->mach != bfd_mach_sh_dsp
00140 && info->mach != bfd_mach_sh3_dsp)
00141 {
00142 static const sh_opcode_info *first_movx, *first_movy;
00143 const sh_opcode_info *op;
00144 int is_movy;
00145
00146 if (! first_movx)
00147 {
00148 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX_NOPY;)
00149 first_movx++;
00150 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY_NOPX;)
00151 first_movy++;
00152 }
00153
00154 is_movy = ((insn & 3) != 0);
00155
00156 if (is_movy)
00157 op = first_movy;
00158 else
00159 op = first_movx;
00160
00161 while (op->nibbles[2] != (unsigned) ((insn >> 4) & 3)
00162 || op->nibbles[3] != (unsigned) (insn & 0xf))
00163 op++;
00164
00165 print_movxy (op,
00166 (4 * ((insn & (is_movy ? 0x200 : 0x100)) == 0)
00167 + 2 * is_movy
00168 + 1 * ((insn & (is_movy ? 0x100 : 0x200)) != 0)),
00169 (insn >> 6) & 3,
00170 fprintf_fn, stream);
00171 }
00172 else
00173 fprintf_fn (stream, ".word 0x%x", insn);
00174 else
00175 {
00176 static const sh_opcode_info *first_movx, *first_movy;
00177 const sh_opcode_info *opx, *opy;
00178 unsigned int insn_x, insn_y;
00179
00180 if (! first_movx)
00181 {
00182 for (first_movx = sh_table; first_movx->nibbles[1] != MOVX;)
00183 first_movx++;
00184 for (first_movy = first_movx; first_movy->nibbles[1] != MOVY;)
00185 first_movy++;
00186 }
00187 insn_x = (insn >> 2) & 0xb;
00188 if (insn_x)
00189 {
00190 for (opx = first_movx; opx->nibbles[2] != insn_x;)
00191 opx++;
00192 print_movxy (opx, ((insn >> 9) & 1) + 4, (insn >> 7) & 1,
00193 fprintf_fn, stream);
00194 }
00195 insn_y = (insn & 3) | ((insn >> 1) & 8);
00196 if (insn_y)
00197 {
00198 if (insn_x)
00199 fprintf_fn (stream, "\t");
00200 for (opy = first_movy; opy->nibbles[2] != insn_y;)
00201 opy++;
00202 print_movxy (opy, ((insn >> 8) & 1) + 6, (insn >> 6) & 1,
00203 fprintf_fn, stream);
00204 }
00205 }
00206 }
00207
00208 static void
00209 print_dsp_reg (rm, fprintf_fn, stream)
00210 int rm;
00211 fprintf_ftype fprintf_fn;
00212 void *stream;
00213 {
00214 switch (rm)
00215 {
00216 case A_A1_NUM:
00217 fprintf_fn (stream, "a1");
00218 break;
00219 case A_A0_NUM:
00220 fprintf_fn (stream, "a0");
00221 break;
00222 case A_X0_NUM:
00223 fprintf_fn (stream, "x0");
00224 break;
00225 case A_X1_NUM:
00226 fprintf_fn (stream, "x1");
00227 break;
00228 case A_Y0_NUM:
00229 fprintf_fn (stream, "y0");
00230 break;
00231 case A_Y1_NUM:
00232 fprintf_fn (stream, "y1");
00233 break;
00234 case A_M0_NUM:
00235 fprintf_fn (stream, "m0");
00236 break;
00237 case A_A1G_NUM:
00238 fprintf_fn (stream, "a1g");
00239 break;
00240 case A_M1_NUM:
00241 fprintf_fn (stream, "m1");
00242 break;
00243 case A_A0G_NUM:
00244 fprintf_fn (stream, "a0g");
00245 break;
00246 default:
00247 fprintf_fn (stream, "0x%x", rm);
00248 break;
00249 }
00250 }
00251
00252 static void
00253 print_insn_ppi (field_b, info)
00254 int field_b;
00255 struct disassemble_info *info;
00256 {
00257 static char *sx_tab[] = { "x0", "x1", "a0", "a1" };
00258 static char *sy_tab[] = { "y0", "y1", "m0", "m1" };
00259 fprintf_ftype fprintf_fn = info->fprintf_func;
00260 void *stream = info->stream;
00261 unsigned int nib1, nib2, nib3;
00262 unsigned int altnib1, nib4;
00263 char *dc = NULL;
00264 const sh_opcode_info *op;
00265
00266 if ((field_b & 0xe800) == 0)
00267 {
00268 fprintf_fn (stream, "psh%c\t#%d,",
00269 field_b & 0x1000 ? 'a' : 'l',
00270 (field_b >> 4) & 127);
00271 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
00272 return;
00273 }
00274 if ((field_b & 0xc000) == 0x4000 && (field_b & 0x3000) != 0x1000)
00275 {
00276 static char *du_tab[] = { "x0", "y0", "a0", "a1" };
00277 static char *se_tab[] = { "x0", "x1", "y0", "a1" };
00278 static char *sf_tab[] = { "y0", "y1", "x0", "a1" };
00279 static char *sg_tab[] = { "m0", "m1", "a0", "a1" };
00280
00281 if (field_b & 0x2000)
00282 {
00283 fprintf_fn (stream, "p%s %s,%s,%s\t",
00284 (field_b & 0x1000) ? "add" : "sub",
00285 sx_tab[(field_b >> 6) & 3],
00286 sy_tab[(field_b >> 4) & 3],
00287 du_tab[(field_b >> 0) & 3]);
00288 }
00289 else if ((field_b & 0xf0) == 0x10
00290 && info->mach != bfd_mach_sh_dsp
00291 && info->mach != bfd_mach_sh3_dsp)
00292 {
00293 fprintf_fn (stream, "pclr %s \t", du_tab[(field_b >> 0) & 3]);
00294 }
00295 else if ((field_b & 0xf3) != 0)
00296 {
00297 fprintf_fn (stream, ".word 0x%x\t", field_b);
00298 }
00299 fprintf_fn (stream, "pmuls%c%s,%s,%s",
00300 field_b & 0x2000 ? ' ' : '\t',
00301 se_tab[(field_b >> 10) & 3],
00302 sf_tab[(field_b >> 8) & 3],
00303 sg_tab[(field_b >> 2) & 3]);
00304 return;
00305 }
00306
00307 nib1 = PPIC;
00308 nib2 = field_b >> 12 & 0xf;
00309 nib3 = field_b >> 8 & 0xf;
00310 nib4 = field_b >> 4 & 0xf;
00311 switch (nib3 & 0x3)
00312 {
00313 case 0:
00314 dc = "";
00315 nib1 = PPI3;
00316 break;
00317 case 1:
00318 dc = "";
00319 break;
00320 case 2:
00321 dc = "dct ";
00322 nib3 -= 1;
00323 break;
00324 case 3:
00325 dc = "dcf ";
00326 nib3 -= 2;
00327 break;
00328 }
00329 if (nib1 == PPI3)
00330 altnib1 = PPI3NC;
00331 else
00332 altnib1 = nib1;
00333 for (op = sh_table; op->name; op++)
00334 {
00335 if ((op->nibbles[1] == nib1 || op->nibbles[1] == altnib1)
00336 && op->nibbles[2] == nib2
00337 && op->nibbles[3] == nib3)
00338 {
00339 int n;
00340
00341 switch (op->nibbles[4])
00342 {
00343 case HEX_0:
00344 break;
00345 case HEX_XX00:
00346 if ((nib4 & 3) != 0)
00347 continue;
00348 break;
00349 case HEX_1:
00350 if ((nib4 & 3) != 1)
00351 continue;
00352 break;
00353 case HEX_00YY:
00354 if ((nib4 & 0xc) != 0)
00355 continue;
00356 break;
00357 case HEX_4:
00358 if ((nib4 & 0xc) != 4)
00359 continue;
00360 break;
00361 default:
00362 abort ();
00363 }
00364 fprintf_fn (stream, "%s%s\t", dc, op->name);
00365 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
00366 {
00367 if (n && op->arg[1] != A_END)
00368 fprintf_fn (stream, ",");
00369 switch (op->arg[n])
00370 {
00371 case DSP_REG_N:
00372 print_dsp_reg (field_b & 0xf, fprintf_fn, stream);
00373 break;
00374 case DSP_REG_X:
00375 fprintf_fn (stream, sx_tab[(field_b >> 6) & 3]);
00376 break;
00377 case DSP_REG_Y:
00378 fprintf_fn (stream, sy_tab[(field_b >> 4) & 3]);
00379 break;
00380 case A_MACH:
00381 fprintf_fn (stream, "mach");
00382 break;
00383 case A_MACL:
00384 fprintf_fn (stream, "macl");
00385 break;
00386 default:
00387 abort ();
00388 }
00389 }
00390 return;
00391 }
00392 }
00393
00394 fprintf_fn (stream, ".word 0x%x", field_b);
00395 }
00396
00397
00398
00399 int
00400 print_insn_sh (memaddr, info)
00401 bfd_vma memaddr;
00402 struct disassemble_info *info;
00403 {
00404 fprintf_ftype fprintf_fn = info->fprintf_func;
00405 void *stream = info->stream;
00406 unsigned char insn[4];
00407 unsigned char nibs[8];
00408 int status;
00409 bfd_vma relmask = ~(bfd_vma) 0;
00410 const sh_opcode_info *op;
00411 unsigned int target_arch;
00412 int allow_op32;
00413
00414 switch (info->mach)
00415 {
00416 case bfd_mach_sh:
00417 target_arch = arch_sh1;
00418
00419
00420
00421 if (info->symbols
00422 && bfd_asymbol_flavour(*info->symbols) == bfd_target_coff_flavour)
00423 target_arch = arch_sh4;
00424 break;
00425 case bfd_mach_sh5:
00426 #ifdef INCLUDE_SHMEDIA
00427 status = print_insn_sh64 (memaddr, info);
00428 if (status != -2)
00429 return status;
00430 #endif
00431
00432
00433 target_arch = arch_sh4;
00434 break;
00435 default:
00436 target_arch = sh_get_arch_from_bfd_mach (info->mach);
00437 }
00438
00439 status = info->read_memory_func (memaddr, insn, 2, info);
00440
00441 if (status != 0)
00442 {
00443 info->memory_error_func (status, memaddr, info);
00444 return -1;
00445 }
00446
00447 if (info->endian == BFD_ENDIAN_LITTLE)
00448 {
00449 nibs[0] = (insn[1] >> 4) & 0xf;
00450 nibs[1] = insn[1] & 0xf;
00451
00452 nibs[2] = (insn[0] >> 4) & 0xf;
00453 nibs[3] = insn[0] & 0xf;
00454 }
00455 else
00456 {
00457 nibs[0] = (insn[0] >> 4) & 0xf;
00458 nibs[1] = insn[0] & 0xf;
00459
00460 nibs[2] = (insn[1] >> 4) & 0xf;
00461 nibs[3] = insn[1] & 0xf;
00462 }
00463 status = info->read_memory_func (memaddr + 2, insn + 2, 2, info);
00464 if (status != 0)
00465 allow_op32 = 0;
00466 else
00467 {
00468 allow_op32 = 1;
00469
00470 if (info->endian == BFD_ENDIAN_LITTLE)
00471 {
00472 nibs[4] = (insn[3] >> 4) & 0xf;
00473 nibs[5] = insn[3] & 0xf;
00474
00475 nibs[6] = (insn[2] >> 4) & 0xf;
00476 nibs[7] = insn[2] & 0xf;
00477 }
00478 else
00479 {
00480 nibs[4] = (insn[2] >> 4) & 0xf;
00481 nibs[5] = insn[2] & 0xf;
00482
00483 nibs[6] = (insn[3] >> 4) & 0xf;
00484 nibs[7] = insn[3] & 0xf;
00485 }
00486 }
00487
00488 if (nibs[0] == 0xf && (nibs[1] & 4) == 0
00489 && SH_MERGE_ARCH_SET_VALID (target_arch, arch_sh_dsp_up))
00490 {
00491 if (nibs[1] & 8)
00492 {
00493 int field_b;
00494
00495 status = info->read_memory_func (memaddr + 2, insn, 2, info);
00496
00497 if (status != 0)
00498 {
00499 info->memory_error_func (status, memaddr + 2, info);
00500 return -1;
00501 }
00502
00503 if (info->endian == BFD_ENDIAN_LITTLE)
00504 field_b = insn[1] << 8 | insn[0];
00505 else
00506 field_b = insn[0] << 8 | insn[1];
00507
00508 print_insn_ppi (field_b, info);
00509 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
00510 return 4;
00511 }
00512 print_insn_ddt ((nibs[1] << 8) | (nibs[2] << 4) | nibs[3], info);
00513 return 2;
00514 }
00515 for (op = sh_table; op->name; op++)
00516 {
00517 int n;
00518 int imm = 0;
00519 int rn = 0;
00520 int rm = 0;
00521 int rb = 0;
00522 int disp_pc;
00523 bfd_vma disp_pc_addr = 0;
00524 int disp = 0;
00525 int has_disp = 0;
00526 int max_n = SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 8 : 4;
00527
00528 if (!allow_op32
00529 && SH_MERGE_ARCH_SET (op->arch, arch_op32))
00530 goto fail;
00531
00532 if (!SH_MERGE_ARCH_SET_VALID (op->arch, target_arch))
00533 goto fail;
00534 for (n = 0; n < max_n; n++)
00535 {
00536 int i = op->nibbles[n];
00537
00538 if (i < 16)
00539 {
00540 if (nibs[n] == i)
00541 continue;
00542 goto fail;
00543 }
00544 switch (i)
00545 {
00546 case BRANCH_8:
00547 imm = (nibs[2] << 4) | (nibs[3]);
00548 if (imm & 0x80)
00549 imm |= ~0xff;
00550 imm = ((char) imm) * 2 + 4;
00551 goto ok;
00552 case BRANCH_12:
00553 imm = ((nibs[1]) << 8) | (nibs[2] << 4) | (nibs[3]);
00554 if (imm & 0x800)
00555 imm |= ~0xfff;
00556 imm = imm * 2 + 4;
00557 goto ok;
00558 case IMM0_3c:
00559 if (nibs[3] & 0x8)
00560 goto fail;
00561 imm = nibs[3] & 0x7;
00562 break;
00563 case IMM0_3s:
00564 if (!(nibs[3] & 0x8))
00565 goto fail;
00566 imm = nibs[3] & 0x7;
00567 break;
00568 case IMM0_3Uc:
00569 if (nibs[2] & 0x8)
00570 goto fail;
00571 imm = nibs[2] & 0x7;
00572 break;
00573 case IMM0_3Us:
00574 if (!(nibs[2] & 0x8))
00575 goto fail;
00576 imm = nibs[2] & 0x7;
00577 break;
00578 case DISP0_12:
00579 case DISP1_12:
00580 disp = (nibs[5] << 8) | (nibs[6] << 4) | nibs[7];
00581 has_disp = 1;
00582 goto ok;
00583 case DISP0_12BY2:
00584 case DISP1_12BY2:
00585 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 1;
00586 relmask = ~(bfd_vma) 1;
00587 has_disp = 1;
00588 goto ok;
00589 case DISP0_12BY4:
00590 case DISP1_12BY4:
00591 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 2;
00592 relmask = ~(bfd_vma) 3;
00593 has_disp = 1;
00594 goto ok;
00595 case DISP0_12BY8:
00596 case DISP1_12BY8:
00597 disp = ((nibs[5] << 8) | (nibs[6] << 4) | nibs[7]) << 3;
00598 relmask = ~(bfd_vma) 7;
00599 has_disp = 1;
00600 goto ok;
00601 case IMM0_20_4:
00602 break;
00603 case IMM0_20:
00604 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
00605 | (nibs[6] << 4) | nibs[7]);
00606 if (imm & 0x80000)
00607 imm -= 0x100000;
00608 goto ok;
00609 case IMM0_20BY8:
00610 imm = ((nibs[2] << 16) | (nibs[4] << 12) | (nibs[5] << 8)
00611 | (nibs[6] << 4) | nibs[7]);
00612 imm <<= 8;
00613 if (imm & 0x8000000)
00614 imm -= 0x10000000;
00615 goto ok;
00616 case IMM0_4:
00617 case IMM1_4:
00618 imm = nibs[3];
00619 goto ok;
00620 case IMM0_4BY2:
00621 case IMM1_4BY2:
00622 imm = nibs[3] << 1;
00623 goto ok;
00624 case IMM0_4BY4:
00625 case IMM1_4BY4:
00626 imm = nibs[3] << 2;
00627 goto ok;
00628 case IMM0_8:
00629 case IMM1_8:
00630 imm = (nibs[2] << 4) | nibs[3];
00631 disp = imm;
00632 has_disp = 1;
00633 if (imm & 0x80)
00634 imm -= 0x100;
00635 goto ok;
00636 case PCRELIMM_8BY2:
00637 imm = ((nibs[2] << 4) | nibs[3]) << 1;
00638 relmask = ~(bfd_vma) 1;
00639 goto ok;
00640 case PCRELIMM_8BY4:
00641 imm = ((nibs[2] << 4) | nibs[3]) << 2;
00642 relmask = ~(bfd_vma) 3;
00643 goto ok;
00644 case IMM0_8BY2:
00645 case IMM1_8BY2:
00646 imm = ((nibs[2] << 4) | nibs[3]) << 1;
00647 goto ok;
00648 case IMM0_8BY4:
00649 case IMM1_8BY4:
00650 imm = ((nibs[2] << 4) | nibs[3]) << 2;
00651 goto ok;
00652 case REG_N_D:
00653 if ((nibs[n] & 1) != 0)
00654 goto fail;
00655
00656 case REG_N:
00657 rn = nibs[n];
00658 break;
00659 case REG_M:
00660 rm = nibs[n];
00661 break;
00662 case REG_N_B01:
00663 if ((nibs[n] & 0x3) != 1 )
00664 goto fail;
00665 rn = (nibs[n] & 0xc) >> 2;
00666 break;
00667 case REG_NM:
00668 rn = (nibs[n] & 0xc) >> 2;
00669 rm = (nibs[n] & 0x3);
00670 break;
00671 case REG_B:
00672 rb = nibs[n] & 0x07;
00673 break;
00674 case SDT_REG_N:
00675
00676 rn = nibs[n];
00677 if ((rn & 0xc) != 4)
00678 goto fail;
00679 rn = rn & 0x3;
00680 rn |= (!(rn & 2)) << 2;
00681 break;
00682 case PPI:
00683 case REPEAT:
00684 goto fail;
00685 default:
00686 abort ();
00687 }
00688 }
00689
00690 ok:
00691
00692
00693
00694 if (target_arch == arch_sh2a
00695 && ((op->arg[0] == DX_REG_M && (rm & 1) != 0)
00696 || (op->arg[1] == DX_REG_N && (rn & 1) != 0)))
00697 goto fail;
00698
00699 fprintf_fn (stream, "%s\t", op->name);
00700 disp_pc = 0;
00701 for (n = 0; n < 3 && op->arg[n] != A_END; n++)
00702 {
00703 if (n && op->arg[1] != A_END)
00704 fprintf_fn (stream, ",");
00705 switch (op->arg[n])
00706 {
00707 case A_IMM:
00708 fprintf_fn (stream, "#%d", imm);
00709 break;
00710 case A_R0:
00711 fprintf_fn (stream, "r0");
00712 break;
00713 case A_REG_N:
00714 fprintf_fn (stream, "r%d", rn);
00715 break;
00716 case A_INC_N:
00717 case AS_INC_N:
00718 fprintf_fn (stream, "@r%d+", rn);
00719 break;
00720 case A_DEC_N:
00721 case AS_DEC_N:
00722 fprintf_fn (stream, "@-r%d", rn);
00723 break;
00724 case A_IND_N:
00725 case AS_IND_N:
00726 fprintf_fn (stream, "@r%d", rn);
00727 break;
00728 case A_DISP_REG_N:
00729 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rn);
00730 break;
00731 case AS_PMOD_N:
00732 fprintf_fn (stream, "@r%d+r8", rn);
00733 break;
00734 case A_REG_M:
00735 fprintf_fn (stream, "r%d", rm);
00736 break;
00737 case A_INC_M:
00738 fprintf_fn (stream, "@r%d+", rm);
00739 break;
00740 case A_DEC_M:
00741 fprintf_fn (stream, "@-r%d", rm);
00742 break;
00743 case A_IND_M:
00744 fprintf_fn (stream, "@r%d", rm);
00745 break;
00746 case A_DISP_REG_M:
00747 fprintf_fn (stream, "@(%d,r%d)", has_disp?disp:imm, rm);
00748 break;
00749 case A_REG_B:
00750 fprintf_fn (stream, "r%d_bank", rb);
00751 break;
00752 case A_DISP_PC:
00753 disp_pc = 1;
00754 disp_pc_addr = imm + 4 + (memaddr & relmask);
00755 (*info->print_address_func) (disp_pc_addr, info);
00756 break;
00757 case A_IND_R0_REG_N:
00758 fprintf_fn (stream, "@(r0,r%d)", rn);
00759 break;
00760 case A_IND_R0_REG_M:
00761 fprintf_fn (stream, "@(r0,r%d)", rm);
00762 break;
00763 case A_DISP_GBR:
00764 fprintf_fn (stream, "@(%d,gbr)", has_disp?disp:imm);
00765 break;
00766 case A_TBR:
00767 fprintf_fn (stream, "tbr");
00768 break;
00769 case A_DISP2_TBR:
00770 fprintf_fn (stream, "@@(%d,tbr)", has_disp?disp:imm);
00771 break;
00772 case A_INC_R15:
00773 fprintf_fn (stream, "@r15+");
00774 break;
00775 case A_DEC_R15:
00776 fprintf_fn (stream, "@-r15");
00777 break;
00778 case A_R0_GBR:
00779 fprintf_fn (stream, "@(r0,gbr)");
00780 break;
00781 case A_BDISP12:
00782 case A_BDISP8:
00783 (*info->print_address_func) (imm + memaddr, info);
00784 break;
00785 case A_SR:
00786 fprintf_fn (stream, "sr");
00787 break;
00788 case A_GBR:
00789 fprintf_fn (stream, "gbr");
00790 break;
00791 case A_VBR:
00792 fprintf_fn (stream, "vbr");
00793 break;
00794 case A_DSR:
00795 fprintf_fn (stream, "dsr");
00796 break;
00797 case A_MOD:
00798 fprintf_fn (stream, "mod");
00799 break;
00800 case A_RE:
00801 fprintf_fn (stream, "re");
00802 break;
00803 case A_RS:
00804 fprintf_fn (stream, "rs");
00805 break;
00806 case A_A0:
00807 fprintf_fn (stream, "a0");
00808 break;
00809 case A_X0:
00810 fprintf_fn (stream, "x0");
00811 break;
00812 case A_X1:
00813 fprintf_fn (stream, "x1");
00814 break;
00815 case A_Y0:
00816 fprintf_fn (stream, "y0");
00817 break;
00818 case A_Y1:
00819 fprintf_fn (stream, "y1");
00820 break;
00821 case DSP_REG_M:
00822 print_dsp_reg (rm, fprintf_fn, stream);
00823 break;
00824 case A_SSR:
00825 fprintf_fn (stream, "ssr");
00826 break;
00827 case A_SPC:
00828 fprintf_fn (stream, "spc");
00829 break;
00830 case A_MACH:
00831 fprintf_fn (stream, "mach");
00832 break;
00833 case A_MACL:
00834 fprintf_fn (stream, "macl");
00835 break;
00836 case A_PR:
00837 fprintf_fn (stream, "pr");
00838 break;
00839 case A_SGR:
00840 fprintf_fn (stream, "sgr");
00841 break;
00842 case A_DBR:
00843 fprintf_fn (stream, "dbr");
00844 break;
00845 case F_REG_N:
00846 fprintf_fn (stream, "fr%d", rn);
00847 break;
00848 case F_REG_M:
00849 fprintf_fn (stream, "fr%d", rm);
00850 break;
00851 case DX_REG_N:
00852 if (rn & 1)
00853 {
00854 fprintf_fn (stream, "xd%d", rn & ~1);
00855 break;
00856 }
00857 case D_REG_N:
00858 fprintf_fn (stream, "dr%d", rn);
00859 break;
00860 case DX_REG_M:
00861 if (rm & 1)
00862 {
00863 fprintf_fn (stream, "xd%d", rm & ~1);
00864 break;
00865 }
00866 case D_REG_M:
00867 fprintf_fn (stream, "dr%d", rm);
00868 break;
00869 case FPSCR_M:
00870 case FPSCR_N:
00871 fprintf_fn (stream, "fpscr");
00872 break;
00873 case FPUL_M:
00874 case FPUL_N:
00875 fprintf_fn (stream, "fpul");
00876 break;
00877 case F_FR0:
00878 fprintf_fn (stream, "fr0");
00879 break;
00880 case V_REG_N:
00881 fprintf_fn (stream, "fv%d", rn * 4);
00882 break;
00883 case V_REG_M:
00884 fprintf_fn (stream, "fv%d", rm * 4);
00885 break;
00886 case XMTRX_M4:
00887 fprintf_fn (stream, "xmtrx");
00888 break;
00889 default:
00890 abort ();
00891 }
00892 }
00893
00894 #if 0
00895
00896
00897
00898
00899
00900 if (!(info->flags & 1)
00901 && (op->name[0] == 'j'
00902 || (op->name[0] == 'b'
00903 && (op->name[1] == 'r'
00904 || op->name[1] == 's'))
00905 || (op->name[0] == 'r' && op->name[1] == 't')
00906 || (op->name[0] == 'b' && op->name[2] == '.')))
00907 {
00908 info->flags |= 1;
00909 fprintf_fn (stream, "\t(slot ");
00910 print_insn_sh (memaddr + 2, info);
00911 info->flags &= ~1;
00912 fprintf_fn (stream, ")");
00913 return 4;
00914 }
00915 #endif
00916
00917 if (disp_pc && strcmp (op->name, "mova") != 0)
00918 {
00919 int size;
00920 bfd_byte bytes[4];
00921
00922 if (relmask == ~(bfd_vma) 1)
00923 size = 2;
00924 else
00925 size = 4;
00926 status = info->read_memory_func (disp_pc_addr, bytes, size, info);
00927 if (status == 0)
00928 {
00929 unsigned int val;
00930
00931 if (size == 2)
00932 {
00933 if (info->endian == BFD_ENDIAN_LITTLE)
00934 val = bfd_getl16 (bytes);
00935 else
00936 val = bfd_getb16 (bytes);
00937 }
00938 else
00939 {
00940 if (info->endian == BFD_ENDIAN_LITTLE)
00941 val = bfd_getl32 (bytes);
00942 else
00943 val = bfd_getb32 (bytes);
00944 }
00945 if ((*info->symbol_at_address_func) (val, info))
00946 {
00947 fprintf_fn (stream, "\t! 0x");
00948 (*info->print_address_func) (val, info);
00949 }
00950 else
00951 fprintf_fn (stream, "\t! 0x%x", val);
00952 }
00953 }
00954
00955 return SH_MERGE_ARCH_SET (op->arch, arch_op32) ? 4 : 2;
00956 fail:
00957 ;
00958
00959 }
00960 fprintf_fn (stream, ".word 0x%x%x%x%x", nibs[0], nibs[1], nibs[2], nibs[3]);
00961 return 2;
00962 }