00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include "sysdep.h"
00023 #include "dis-asm.h"
00024 #include "opcode/a29k.h"
00025
00026 static void print_general PARAMS ((int, struct disassemble_info *));
00027 static void print_special PARAMS ((unsigned int, struct disassemble_info *));
00028 static int is_delayed_branch PARAMS ((int));
00029 static void find_bytes_little
00030 PARAMS ((char *, unsigned char *, unsigned char *, unsigned char *,
00031 unsigned char *));
00032 static void find_bytes_big
00033 PARAMS ((char *, unsigned char *, unsigned char *, unsigned char *,
00034 unsigned char *));
00035 static int print_insn PARAMS ((bfd_vma, struct disassemble_info *));
00036
00037
00038
00039
00040
00041
00042 static void
00043 print_general (num, info)
00044 int num;
00045 struct disassemble_info *info;
00046 {
00047 if (num < 128)
00048 (*info->fprintf_func) (info->stream, "gr%d", num);
00049 else
00050 (*info->fprintf_func) (info->stream, "lr%d", num - 128);
00051 }
00052
00053
00054
00055
00056
00057
00058 static void
00059 print_special (num, info)
00060 unsigned int num;
00061 struct disassemble_info *info;
00062 {
00063
00064 static char *spec0_names[] = {
00065 "vab", "ops", "cps", "cfg", "cha", "chd", "chc", "rbp", "tmc", "tmr",
00066 "pc0", "pc1", "pc2", "mmu", "lru", "rsn", "rma0", "rmc0", "rma1", "rmc1",
00067 "spc0", "spc1", "spc2", "iba0", "ibc0", "iba1", "ibc1", "dba", "dbc",
00068 "cir", "cdr"
00069 };
00070 #define SPEC0_NUM ((sizeof spec0_names) / (sizeof spec0_names[0]))
00071
00072
00073 static char *spec128_names[] = {
00074 "ipc", "ipa", "ipb", "q", "alu", "bp", "fc", "cr"
00075 };
00076 #define SPEC128_NUM ((sizeof spec128_names) / (sizeof spec128_names[0]))
00077
00078
00079 static char *spec160_names[] = {
00080 "fpe", "inte", "fps", "sr163", "exop"
00081 };
00082 #define SPEC160_NUM ((sizeof spec160_names) / (sizeof spec160_names[0]))
00083
00084 if (num < SPEC0_NUM)
00085 (*info->fprintf_func) (info->stream, spec0_names[num]);
00086 else if (num >= 128 && num < 128 + SPEC128_NUM)
00087 (*info->fprintf_func) (info->stream, spec128_names[num-128]);
00088 else if (num >= 160 && num < 160 + SPEC160_NUM)
00089 (*info->fprintf_func) (info->stream, spec160_names[num-160]);
00090 else
00091 (*info->fprintf_func) (info->stream, "sr%d", num);
00092 }
00093
00094
00095 static int
00096 is_delayed_branch (opcode)
00097 int opcode;
00098 {
00099 return (opcode == 0xa8 || opcode == 0xa9 || opcode == 0xa0 || opcode == 0xa1
00100 || opcode == 0xa4 || opcode == 0xa5
00101 || opcode == 0xb4 || opcode == 0xb5
00102 || opcode == 0xc4 || opcode == 0xc0
00103 || opcode == 0xac || opcode == 0xad
00104 || opcode == 0xcc);
00105 }
00106
00107
00108 static void
00109 find_bytes_big (insn, insn0, insn8, insn16, insn24)
00110 char *insn;
00111 unsigned char *insn0;
00112 unsigned char *insn8;
00113 unsigned char *insn16;
00114 unsigned char *insn24;
00115 {
00116 *insn24 = insn[0];
00117 *insn16 = insn[1];
00118 *insn8 = insn[2];
00119 *insn0 = insn[3];
00120 }
00121
00122 static void
00123 find_bytes_little (insn, insn0, insn8, insn16, insn24)
00124 char *insn;
00125 unsigned char *insn0;
00126 unsigned char *insn8;
00127 unsigned char *insn16;
00128 unsigned char *insn24;
00129 {
00130 *insn24 = insn[3];
00131 *insn16 = insn[2];
00132 *insn8 = insn[1];
00133 *insn0 = insn[0];
00134 }
00135
00136 typedef void (*find_byte_func_type)
00137 PARAMS ((char *, unsigned char *, unsigned char *,
00138 unsigned char *, unsigned char *));
00139
00140
00141
00142
00143 static int
00144 print_insn (memaddr, info)
00145 bfd_vma memaddr;
00146 struct disassemble_info *info;
00147 {
00148
00149 char insn[4];
00150
00151
00152 unsigned char insn24, insn16, insn8, insn0;
00153
00154 find_byte_func_type find_byte_func = (find_byte_func_type)info->private_data;
00155
00156 struct a29k_opcode const * opcode;
00157
00158 {
00159 int status =
00160 (*info->read_memory_func) (memaddr, (bfd_byte *) &insn[0], 4, info);
00161 if (status != 0)
00162 {
00163 (*info->memory_error_func) (status, memaddr, info);
00164 return -1;
00165 }
00166 }
00167
00168 (*find_byte_func) (insn, &insn0, &insn8, &insn16, &insn24);
00169
00170 printf ("%02x%02x%02x%02x ", insn24, insn16, insn8, insn0);
00171
00172
00173 if ((insn24==0x70) && (insn16==0x40) && (insn8==0x01) && (insn0==0x01)) {
00174 (*info->fprintf_func) (info->stream,"nop");
00175 return 4;
00176 }
00177
00178
00179 for (opcode = &a29k_opcodes[0];
00180 opcode < &a29k_opcodes[num_opcodes];
00181 ++opcode)
00182 {
00183 if (((unsigned long) insn24 << 24) == opcode->opcode)
00184 {
00185 char *s;
00186
00187 (*info->fprintf_func) (info->stream, "%s ", opcode->name);
00188 for (s = opcode->args; *s != '\0'; ++s)
00189 {
00190 switch (*s)
00191 {
00192 case 'a':
00193 print_general (insn8, info);
00194 break;
00195
00196 case 'b':
00197 print_general (insn0, info);
00198 break;
00199
00200 case 'c':
00201 print_general (insn16, info);
00202 break;
00203
00204 case 'i':
00205 (*info->fprintf_func) (info->stream, "%d", insn0);
00206 break;
00207
00208 case 'x':
00209 (*info->fprintf_func) (info->stream, "0x%x", (insn16 << 8) + insn0);
00210 break;
00211
00212 case 'h':
00213
00214 (*info->fprintf_func) (info->stream, "0x%x",
00215 (insn16 << 24) + (insn0 << 16));
00216 break;
00217
00218 case 'X':
00219 (*info->fprintf_func) (info->stream, "%d",
00220 ((insn16 << 8) + insn0) | 0xffff0000);
00221 break;
00222
00223 case 'P':
00224
00225
00226
00227
00228 (*info->print_address_func)
00229 (memaddr +
00230 (((int)((insn16 << 10) + (insn0 << 2)) << 14) >> 14),
00231 info);
00232 break;
00233
00234 case 'A':
00235 (*info->print_address_func)
00236 ((insn16 << 10) + (insn0 << 2), info);
00237 break;
00238
00239 case 'e':
00240 (*info->fprintf_func) (info->stream, "%d", insn16 >> 7);
00241 break;
00242
00243 case 'n':
00244 (*info->fprintf_func) (info->stream, "0x%x", insn16 & 0x7f);
00245 break;
00246
00247 case 'v':
00248 (*info->fprintf_func) (info->stream, "0x%x", insn16);
00249 break;
00250
00251 case 's':
00252 print_special (insn8, info);
00253 break;
00254
00255 case 'u':
00256 (*info->fprintf_func) (info->stream, "%d", insn0 >> 7);
00257 break;
00258
00259 case 'r':
00260 (*info->fprintf_func) (info->stream, "%d", (insn0 >> 4) & 7);
00261 break;
00262
00263 case 'I':
00264 if ((insn16 & 3) != 0)
00265 (*info->fprintf_func) (info->stream, "%d", insn16 & 3);
00266 break;
00267
00268 case 'd':
00269 (*info->fprintf_func) (info->stream, "%d", (insn0 >> 2) & 3);
00270 break;
00271
00272 case 'f':
00273 (*info->fprintf_func) (info->stream, "%d", insn0 & 3);
00274 break;
00275
00276 case 'F':
00277 (*info->fprintf_func) (info->stream, "%d", (insn16 >> 2) & 15);
00278 break;
00279
00280 case 'C':
00281 (*info->fprintf_func) (info->stream, "%d", insn16 & 3);
00282 break;
00283
00284 default:
00285 (*info->fprintf_func) (info->stream, "%c", *s);
00286 }
00287 }
00288
00289
00290
00291 if (insn24 == 2)
00292 {
00293 int errcode;
00294 char prev_insn[4];
00295 unsigned char prev_insn0, prev_insn8, prev_insn16, prev_insn24;
00296
00297 errcode = (*info->read_memory_func) (memaddr - 4,
00298 (bfd_byte *) &prev_insn[0],
00299 4,
00300 info);
00301 if (errcode == 0)
00302 {
00303
00304
00305
00306
00307
00308
00309
00310
00311 (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8,
00312 &prev_insn16, &prev_insn24);
00313 if (is_delayed_branch (prev_insn24))
00314 {
00315 errcode = (*info->read_memory_func)
00316 (memaddr - 8, (bfd_byte *) &prev_insn[0], 4, info);
00317 (*find_byte_func) (prev_insn, &prev_insn0, &prev_insn8,
00318 &prev_insn16, &prev_insn24);
00319 }
00320 }
00321
00322
00323
00324 if (errcode == 0)
00325 {
00326
00327 if (prev_insn24 == 3
00328 && prev_insn8 == insn8)
00329 {
00330 (*info->fprintf_func) (info->stream, "\t; ");
00331 (*info->print_address_func)
00332 (((insn16 << 24) + (insn0 << 16)
00333 + (prev_insn16 << 8) + (prev_insn0)),
00334 info);
00335 }
00336 }
00337 }
00338
00339 return 4;
00340 }
00341 }
00342
00343 (*info->fprintf_func)
00344 (info->stream, ".word 0x%08x",
00345 (insn24 << 24) + (insn16 << 16) + (insn8 << 8) + insn0);
00346 return 4;
00347 }
00348
00349
00350 int
00351 print_insn_big_a29k (memaddr, info)
00352 bfd_vma memaddr;
00353 struct disassemble_info *info;
00354 {
00355 info->private_data = (PTR) find_bytes_big;
00356 return print_insn (memaddr, info);
00357 }
00358
00359
00360 int
00361 print_insn_little_a29k (memaddr, info)
00362 bfd_vma memaddr;
00363 struct disassemble_info *info;
00364 {
00365 info->private_data = (PTR) find_bytes_little;
00366 return print_insn (memaddr, info);
00367 }