00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #include "dis-asm.h"
00021 #include "opcode/i860.h"
00022
00023
00024 #define I860_REG_PREFIX "%"
00025
00026
00027 static const char *const grnames[] =
00028 {"r0", "r1", "sp", "fp", "r4", "r5", "r6", "r7",
00029 "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15",
00030 "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23",
00031 "r24", "r25", "r26", "r27", "r28", "r29", "r30", "r31"};
00032
00033
00034 static const char *const frnames[] =
00035 {"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
00036 "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
00037 "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
00038 "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"};
00039
00040
00041
00042 static const char *const crnames[] =
00043 {"fir", "psr", "dirbase", "db", "fsr", "epsr", "bear", "ccr",
00044 "p0", "p1", "p2", "p3", "--", "--", "--", "--" };
00045
00046
00047
00048
00049 #define BITWISE_OP(op) ((op) == 0x30 || (op) == 0x31 \
00050 || (op) == 0x34 || (op) == 0x35 \
00051 || (op) == 0x38 || (op) == 0x39 \
00052 || (op) == 0x3c || (op) == 0x3d \
00053 || (op) == 0x33 || (op) == 0x37 \
00054 || (op) == 0x3b || (op) == 0x3f)
00055
00056
00057
00058 static int
00059 sign_ext (unsigned int x, int n)
00060 {
00061 int t;
00062 t = x >> (n - 1);
00063 t = ((-t) << n) | x;
00064 return t;
00065 }
00066
00067
00068
00069
00070 static void
00071 print_br_address (disassemble_info *info, bfd_vma memaddr, long val)
00072 {
00073
00074 long adj = (long)memaddr + 4 + (val << 2);
00075
00076 (*info->fprintf_func) (info->stream, "0x%08x", adj);
00077
00078
00079
00080 if (info->print_address_func && adj != 0)
00081 {
00082 (*info->fprintf_func) (info->stream, "\t// ");
00083 (*info->print_address_func) (adj, info);
00084 }
00085 }
00086
00087
00088
00089 int
00090 print_insn_i860 (bfd_vma memaddr, disassemble_info *info)
00091 {
00092 bfd_byte buff[4];
00093 unsigned int insn, i;
00094 int status;
00095 const struct i860_opcode *opcode = 0;
00096
00097 status = (*info->read_memory_func) (memaddr, buff, sizeof (buff), info);
00098 if (status != 0)
00099 {
00100 (*info->memory_error_func) (status, memaddr, info);
00101 return -1;
00102 }
00103
00104
00105
00106 insn = bfd_getl32 (buff);
00107
00108 status = 0;
00109 i = 0;
00110 while (i860_opcodes[i].name != NULL)
00111 {
00112 opcode = &i860_opcodes[i];
00113 if ((insn & opcode->match) == opcode->match
00114 && (insn & opcode->lose) == 0)
00115 {
00116 status = 1;
00117 break;
00118 }
00119 ++i;
00120 }
00121
00122 if (status == 0)
00123 {
00124
00125 (*info->fprintf_func) (info->stream, ".long %#08x", insn);
00126 }
00127 else
00128 {
00129 const char *s;
00130 int val;
00131
00132
00133
00134 if (((insn & 0xfc000000) == 0x48000000
00135 || (insn & 0xfc000000) == 0xb0000000)
00136 && (insn & 0x200))
00137 (*info->fprintf_func) (info->stream, "d.%s\t", opcode->name);
00138 else
00139 (*info->fprintf_func) (info->stream, "%s\t", opcode->name);
00140
00141 for (s = opcode->args; *s; s++)
00142 {
00143 switch (*s)
00144 {
00145
00146 case '1':
00147 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00148 grnames[(insn >> 11) & 0x1f]);
00149 break;
00150
00151
00152 case '2':
00153 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00154 grnames[(insn >> 21) & 0x1f]);
00155 break;
00156
00157
00158 case 'd':
00159 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00160 grnames[(insn >> 16) & 0x1f]);
00161 break;
00162
00163
00164 case 'e':
00165 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00166 frnames[(insn >> 11) & 0x1f]);
00167 break;
00168
00169
00170 case 'f':
00171 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00172 frnames[(insn >> 21) & 0x1f]);
00173 break;
00174
00175
00176 case 'g':
00177 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00178 frnames[(insn >> 16) & 0x1f]);
00179 break;
00180
00181
00182 case 'c':
00183 (*info->fprintf_func) (info->stream, "%s%s", I860_REG_PREFIX,
00184 crnames[(insn >> 21) & 0xf]);
00185 break;
00186
00187
00188 case 'i':
00189 if (BITWISE_OP ((insn & 0xfc000000) >> 26))
00190 (*info->fprintf_func) (info->stream, "0x%04x",
00191 (unsigned int) (insn & 0xffff));
00192 else
00193 (*info->fprintf_func) (info->stream, "%d",
00194 sign_ext ((insn & 0xffff), 16));
00195 break;
00196
00197
00198 case 'I':
00199 (*info->fprintf_func) (info->stream, "%d",
00200 sign_ext ((insn & 0xffff), 16));
00201 break;
00202
00203
00204 case 'J':
00205 (*info->fprintf_func) (info->stream, "%d",
00206 sign_ext ((insn & 0xfffe), 16));
00207 break;
00208
00209
00210 case 'K':
00211 (*info->fprintf_func) (info->stream, "%d",
00212 sign_ext ((insn & 0xfffc), 16));
00213 break;
00214
00215
00216 case 'L':
00217 (*info->fprintf_func) (info->stream, "%d",
00218 sign_ext ((insn & 0xfff8), 16));
00219 break;
00220
00221
00222 case 'M':
00223 (*info->fprintf_func) (info->stream, "%d",
00224 sign_ext ((insn & 0xfff0), 16));
00225 break;
00226
00227
00228 case '5':
00229 (*info->fprintf_func) (info->stream, "%d",
00230 ((insn >> 11) & 0x1f));
00231 break;
00232
00233
00234 case 's':
00235 val = ((insn >> 5) & 0xf800) | (insn & 0x07ff);
00236 (*info->fprintf_func) (info->stream, "%d",
00237 sign_ext (val, 16));
00238 break;
00239
00240
00241 case 'S':
00242 val = ((insn >> 5) & 0xf800) | (insn & 0x07ff);
00243 (*info->fprintf_func) (info->stream, "%d",
00244 sign_ext (val, 16));
00245 break;
00246
00247
00248 case 'T':
00249 val = ((insn >> 5) & 0xf800) | (insn & 0x07fe);
00250 (*info->fprintf_func) (info->stream, "%d",
00251 sign_ext (val, 16));
00252 break;
00253
00254
00255 case 'U':
00256 val = ((insn >> 5) & 0xf800) | (insn & 0x07fc);
00257 (*info->fprintf_func) (info->stream, "%d",
00258 sign_ext (val, 16));
00259 break;
00260
00261
00262 case 'l':
00263 val = sign_ext ((insn & 0x03ffffff), 26);
00264 print_br_address (info, memaddr, val);
00265 break;
00266
00267
00268 case 'r':
00269 val = sign_ext ((((insn >> 5) & 0xf800) | (insn & 0x07ff)), 16);
00270 print_br_address (info, memaddr, val);
00271 break;
00272
00273 default:
00274 (*info->fprintf_func) (info->stream, "%c", *s);
00275 break;
00276 }
00277 }
00278 }
00279
00280 return sizeof (insn);
00281 }
00282