00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <stdio.h>
00023
00024 #define DISASSEMBLER_TABLE
00025 #define DEFINE_TABLE
00026
00027 #include "sysdep.h"
00028 #include "h8500-opc.h"
00029 #include "dis-asm.h"
00030 #include "opintl.h"
00031
00032
00033 #define MAXLEN 8
00034
00035 #include <setjmp.h>
00036
00037 static int fetch_data PARAMS ((struct disassemble_info *, bfd_byte *));
00038
00039 struct private
00040 {
00041
00042 bfd_byte *max_fetched;
00043 bfd_byte the_buffer[MAXLEN];
00044 bfd_vma insn_start;
00045 jmp_buf bailout;
00046 };
00047
00048
00049
00050
00051 #define FETCH_DATA(info, addr) \
00052 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
00053 ? 1 : fetch_data ((info), (addr)))
00054
00055 static int
00056 fetch_data (info, addr)
00057 struct disassemble_info *info;
00058 bfd_byte *addr;
00059 {
00060 int status;
00061 struct private *priv = (struct private *) info->private_data;
00062 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
00063
00064 status = (*info->read_memory_func) (start,
00065 priv->max_fetched,
00066 addr - priv->max_fetched,
00067 info);
00068 if (status != 0)
00069 {
00070 (*info->memory_error_func) (status, start, info);
00071 longjmp (priv->bailout, 1);
00072 }
00073 else
00074 priv->max_fetched = addr;
00075 return 1;
00076 }
00077
00078 static char *crname[] = { "sr", "ccr", "*", "br", "ep", "dp", "*", "tp" };
00079
00080 int
00081 print_insn_h8500 (addr, info)
00082 bfd_vma addr;
00083 disassemble_info *info;
00084 {
00085 const h8500_opcode_info *opcode;
00086 void *stream = info->stream;
00087 fprintf_ftype func = info->fprintf_func;
00088
00089 struct private priv;
00090 bfd_byte *buffer = priv.the_buffer;
00091
00092 info->private_data = (PTR) & priv;
00093 priv.max_fetched = priv.the_buffer;
00094 priv.insn_start = addr;
00095 if (setjmp (priv.bailout) != 0)
00096
00097 return -1;
00098
00099 if (0)
00100 {
00101 static int one;
00102
00103 if (!one)
00104 {
00105 one = 1;
00106 for (opcode = h8500_table; opcode->name; opcode++)
00107 {
00108 if ((opcode->bytes[0].contents & 0x8) == 0)
00109 printf ("%s\n", opcode->name);
00110 }
00111 }
00112 }
00113
00114
00115 for (opcode = h8500_table; opcode->name; opcode++)
00116 {
00117 int byte;
00118 int rn = 0;
00119 int rd = 0;
00120 int rs = 0;
00121 int disp = 0;
00122 int abs = 0;
00123 int imm = 0;
00124 int pcrel = 0;
00125 int qim = 0;
00126 int i;
00127 int cr = 0;
00128
00129 for (byte = 0; byte < opcode->length; byte++)
00130 {
00131 FETCH_DATA (info, buffer + byte + 1);
00132 if ((buffer[byte] & opcode->bytes[byte].mask)
00133 != (opcode->bytes[byte].contents))
00134 {
00135 goto next;
00136 }
00137 else
00138 {
00139
00140 switch (opcode->bytes[byte].insert)
00141 {
00142 case 0:
00143 case FP:
00144 break;
00145 default:
00146
00147 func (stream, _("can't cope with insert %d\n"),
00148 opcode->bytes[byte].insert);
00149 break;
00150 case RN:
00151 rn = buffer[byte] & 0x7;
00152 break;
00153 case RS:
00154 rs = buffer[byte] & 0x7;
00155 break;
00156 case CRB:
00157 cr = buffer[byte] & 0x7;
00158 if (cr == 0)
00159 goto next;
00160 break;
00161 case CRW:
00162 cr = buffer[byte] & 0x7;
00163 if (cr != 0)
00164 goto next;
00165 break;
00166 case DISP16:
00167 FETCH_DATA (info, buffer + byte + 2);
00168 disp = (buffer[byte] << 8) | (buffer[byte + 1]);
00169 break;
00170 case FPIND_D8:
00171 case DISP8:
00172 disp = ((char) (buffer[byte]));
00173 break;
00174 case RD:
00175 case RDIND:
00176 rd = buffer[byte] & 0x7;
00177 break;
00178 case ABS24:
00179 FETCH_DATA (info, buffer + byte + 3);
00180 abs =
00181 (buffer[byte] << 16)
00182 | (buffer[byte + 1] << 8)
00183 | (buffer[byte + 2]);
00184 break;
00185 case ABS16:
00186 FETCH_DATA (info, buffer + byte + 2);
00187 abs = (buffer[byte] << 8) | (buffer[byte + 1]);
00188 break;
00189 case ABS8:
00190 abs = (buffer[byte]);
00191 break;
00192 case IMM16:
00193 FETCH_DATA (info, buffer + byte + 2);
00194 imm = (buffer[byte] << 8) | (buffer[byte + 1]);
00195 break;
00196 case IMM4:
00197 imm = (buffer[byte]) & 0xf;
00198 break;
00199 case IMM8:
00200 case RLIST:
00201 imm = (buffer[byte]);
00202 break;
00203 case PCREL16:
00204 FETCH_DATA (info, buffer + byte + 2);
00205 pcrel = (buffer[byte] << 8) | (buffer[byte + 1]);
00206 break;
00207 case PCREL8:
00208 pcrel = (buffer[byte]);
00209 break;
00210 case QIM:
00211 switch (buffer[byte] & 0x7)
00212 {
00213 case 0:
00214 qim = 1;
00215 break;
00216 case 1:
00217 qim = 2;
00218 break;
00219 case 4:
00220 qim = -1;
00221 break;
00222 case 5:
00223 qim = -2;
00224 break;
00225 }
00226 break;
00227
00228 }
00229 }
00230 }
00231
00232
00233 FETCH_DATA (info, buffer + opcode->length);
00234 (func) (stream, "%s\t", opcode->name);
00235 for (i = 0; i < opcode->nargs; i++)
00236 {
00237 if (i)
00238 (func) (stream, ",");
00239 switch (opcode->arg_type[i])
00240 {
00241 case FP:
00242 func (stream, "fp");
00243 break;
00244 case RNIND_D16:
00245 func (stream, "@(0x%x:16,r%d)", disp, rn);
00246 break;
00247 case RNIND_D8:
00248 func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
00249 break;
00250 case RDIND_D16:
00251 func (stream, "@(0x%x:16,r%d)", disp, rd);
00252 break;
00253 case RDIND_D8:
00254 func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
00255 break;
00256 case FPIND_D8:
00257 func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp, rn);
00258 break;
00259 case CRB:
00260 case CRW:
00261 func (stream, "%s", crname[cr]);
00262 break;
00263 case RN:
00264 func (stream, "r%d", rn);
00265 break;
00266 case RD:
00267 func (stream, "r%d", rd);
00268 break;
00269 case RS:
00270 func (stream, "r%d", rs);
00271 break;
00272 case RNDEC:
00273 func (stream, "@-r%d", rn);
00274 break;
00275 case RNINC:
00276 func (stream, "@r%d+", rn);
00277 break;
00278 case RNIND:
00279 func (stream, "@r%d", rn);
00280 break;
00281 case RDIND:
00282 func (stream, "@r%d", rd);
00283 break;
00284 case SPINC:
00285 func (stream, "@sp+");
00286 break;
00287 case SPDEC:
00288 func (stream, "@-sp");
00289 break;
00290 case ABS24:
00291 func (stream, "@0x%0x:24", abs);
00292 break;
00293 case ABS16:
00294 func (stream, "@0x%0x:16", abs & 0xffff);
00295 break;
00296 case ABS8:
00297 func (stream, "@0x%0x:8", abs & 0xff);
00298 break;
00299 case IMM16:
00300 func (stream, "#0x%0x:16", imm & 0xffff);
00301 break;
00302 case RLIST:
00303 {
00304 int i;
00305 int nc = 0;
00306 func (stream, "(");
00307 for (i = 0; i < 8; i++)
00308 {
00309 if (imm & (1 << i))
00310 {
00311 func (stream, "r%d", i);
00312 if (nc)
00313 func (stream, ",");
00314 nc = 1;
00315 }
00316 }
00317 func (stream, ")");
00318 }
00319 break;
00320 case IMM8:
00321 func (stream, "#0x%0x:8", imm & 0xff);
00322 break;
00323 case PCREL16:
00324 func (stream, "0x%0x:16",
00325 (pcrel + addr + opcode->length) & 0xffff);
00326 break;
00327 case PCREL8:
00328 func (stream, "#0x%0x:8",
00329 ((char) pcrel + addr + opcode->length) & 0xffff);
00330 break;
00331 case QIM:
00332 func (stream, "#%d:q", qim);
00333 break;
00334 case IMM4:
00335 func (stream, "#%d:4", imm);
00336 break;
00337 }
00338 }
00339 return opcode->length;
00340 next:
00341 ;
00342 }
00343
00344
00345
00346 func (stream, _("%02x\t\t*unknown*"), buffer[0]);
00347 return 1;
00348 }