m10300-dis.c revision 1.5.2.1 1 1.1 christos /* Disassemble MN10300 instructions.
2 1.5.2.1 martin Copyright (C) 1996-2018 Free Software Foundation, Inc.
3 1.1 christos
4 1.1 christos This file is part of the GNU opcodes library.
5 1.1 christos
6 1.1 christos This library is free software; you can redistribute it and/or modify
7 1.1 christos it under the terms of the GNU General Public License as published by
8 1.1 christos the Free Software Foundation; either version 3, or (at your option)
9 1.1 christos any later version.
10 1.1 christos
11 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT
12 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 1.1 christos License for more details.
15 1.1 christos
16 1.1 christos You should have received a copy of the GNU General Public License
17 1.1 christos along with this program; if not, write to the Free Software
18 1.1 christos Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 1.1 christos MA 02110-1301, USA. */
20 1.1 christos
21 1.1 christos #include "sysdep.h"
22 1.1 christos #include <stdio.h>
23 1.1 christos #include "opcode/mn10300.h"
24 1.5.2.1 martin #include "disassemble.h"
25 1.1 christos #include "opintl.h"
26 1.1 christos
27 1.1 christos #define HAVE_AM33_2 (info->mach == AM33_2)
28 1.1 christos #define HAVE_AM33 (info->mach == AM33 || HAVE_AM33_2)
29 1.1 christos #define HAVE_AM30 (info->mach == AM30)
30 1.1 christos
31 1.1 christos static void
32 1.1 christos disassemble (bfd_vma memaddr,
33 1.1 christos struct disassemble_info *info,
34 1.1 christos unsigned long insn,
35 1.1 christos unsigned int size)
36 1.1 christos {
37 1.1 christos struct mn10300_opcode *op = (struct mn10300_opcode *) mn10300_opcodes;
38 1.1 christos const struct mn10300_operand *operand;
39 1.1 christos bfd_byte buffer[4];
40 1.1 christos unsigned long extension = 0;
41 1.1 christos int status, match = 0;
42 1.1 christos
43 1.1 christos /* Find the opcode. */
44 1.1 christos while (op->name)
45 1.1 christos {
46 1.1 christos int mysize, extra_shift;
47 1.1 christos
48 1.1 christos if (op->format == FMT_S0)
49 1.1 christos mysize = 1;
50 1.1 christos else if (op->format == FMT_S1
51 1.1 christos || op->format == FMT_D0)
52 1.1 christos mysize = 2;
53 1.1 christos else if (op->format == FMT_S2
54 1.1 christos || op->format == FMT_D1)
55 1.1 christos mysize = 3;
56 1.1 christos else if (op->format == FMT_S4)
57 1.1 christos mysize = 5;
58 1.1 christos else if (op->format == FMT_D2)
59 1.1 christos mysize = 4;
60 1.1 christos else if (op->format == FMT_D3)
61 1.1 christos mysize = 5;
62 1.1 christos else if (op->format == FMT_D4)
63 1.1 christos mysize = 6;
64 1.1 christos else if (op->format == FMT_D6)
65 1.1 christos mysize = 3;
66 1.1 christos else if (op->format == FMT_D7 || op->format == FMT_D10)
67 1.1 christos mysize = 4;
68 1.1 christos else if (op->format == FMT_D8)
69 1.1 christos mysize = 6;
70 1.1 christos else if (op->format == FMT_D9)
71 1.1 christos mysize = 7;
72 1.1 christos else
73 1.1 christos mysize = 7;
74 1.1 christos
75 1.1 christos if ((op->mask & insn) == op->opcode
76 1.1 christos && size == (unsigned int) mysize
77 1.1 christos && (op->machine == 0
78 1.1 christos || (op->machine == AM33_2 && HAVE_AM33_2)
79 1.1 christos || (op->machine == AM33 && HAVE_AM33)
80 1.1 christos || (op->machine == AM30 && HAVE_AM30)))
81 1.1 christos {
82 1.1 christos const unsigned char *opindex_ptr;
83 1.1 christos unsigned int nocomma;
84 1.1 christos int paren = 0;
85 1.1 christos
86 1.1 christos if (op->format == FMT_D1 || op->format == FMT_S1)
87 1.1 christos extra_shift = 8;
88 1.1 christos else if (op->format == FMT_D2 || op->format == FMT_D4
89 1.1 christos || op->format == FMT_S2 || op->format == FMT_S4
90 1.1 christos || op->format == FMT_S6 || op->format == FMT_D5)
91 1.1 christos extra_shift = 16;
92 1.1 christos else if (op->format == FMT_D7
93 1.1 christos || op->format == FMT_D8
94 1.1 christos || op->format == FMT_D9)
95 1.1 christos extra_shift = 8;
96 1.1 christos else
97 1.1 christos extra_shift = 0;
98 1.1 christos
99 1.1 christos if (size == 1 || size == 2)
100 1.1 christos extension = 0;
101 1.1 christos
102 1.1 christos else if (size == 3
103 1.1 christos && (op->format == FMT_D1
104 1.1 christos || op->opcode == 0xdf0000
105 1.1 christos || op->opcode == 0xde0000))
106 1.1 christos extension = 0;
107 1.1 christos
108 1.1 christos else if (size == 3
109 1.1 christos && op->format == FMT_D6)
110 1.1 christos extension = 0;
111 1.1 christos
112 1.1 christos else if (size == 3)
113 1.1 christos {
114 1.1 christos insn &= 0xff0000;
115 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
116 1.1 christos if (status != 0)
117 1.1 christos {
118 1.1 christos (*info->memory_error_func) (status, memaddr, info);
119 1.1 christos return;
120 1.1 christos }
121 1.1 christos
122 1.1 christos insn |= bfd_getl16 (buffer);
123 1.1 christos extension = 0;
124 1.1 christos }
125 1.1 christos else if (size == 4
126 1.1 christos && (op->opcode == 0xfaf80000
127 1.1 christos || op->opcode == 0xfaf00000
128 1.1 christos || op->opcode == 0xfaf40000))
129 1.1 christos extension = 0;
130 1.1 christos
131 1.1 christos else if (size == 4
132 1.1 christos && (op->format == FMT_D7
133 1.1 christos || op->format == FMT_D10))
134 1.1 christos extension = 0;
135 1.1 christos
136 1.1 christos else if (size == 4)
137 1.1 christos {
138 1.1 christos insn &= 0xffff0000;
139 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
140 1.1 christos if (status != 0)
141 1.1 christos {
142 1.1 christos (*info->memory_error_func) (status, memaddr, info);
143 1.1 christos return;
144 1.1 christos }
145 1.1 christos
146 1.1 christos insn |= bfd_getl16 (buffer);
147 1.1 christos extension = 0;
148 1.1 christos }
149 1.1 christos else if (size == 5 && op->opcode == 0xdc000000)
150 1.1 christos {
151 1.1 christos unsigned long temp = 0;
152 1.1 christos
153 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
154 1.1 christos if (status != 0)
155 1.1 christos {
156 1.1 christos (*info->memory_error_func) (status, memaddr, info);
157 1.1 christos return;
158 1.1 christos }
159 1.1 christos temp |= bfd_getl32 (buffer);
160 1.1 christos
161 1.1 christos insn &= 0xff000000;
162 1.1 christos insn |= (temp & 0xffffff00) >> 8;
163 1.1 christos extension = temp & 0xff;
164 1.1 christos }
165 1.1 christos else if (size == 5 && op->format == FMT_D3)
166 1.1 christos {
167 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 2, info);
168 1.1 christos if (status != 0)
169 1.1 christos {
170 1.1 christos (*info->memory_error_func) (status, memaddr, info);
171 1.1 christos return;
172 1.1 christos }
173 1.1 christos insn &= 0xffff0000;
174 1.1 christos insn |= bfd_getl16 (buffer);
175 1.1 christos
176 1.1 christos status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
177 1.1 christos if (status != 0)
178 1.1 christos {
179 1.1 christos (*info->memory_error_func) (status, memaddr, info);
180 1.1 christos return;
181 1.1 christos }
182 1.1 christos extension = *(unsigned char *) buffer;
183 1.1 christos }
184 1.1 christos else if (size == 5)
185 1.1 christos {
186 1.1 christos unsigned long temp = 0;
187 1.1 christos
188 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 2, info);
189 1.1 christos if (status != 0)
190 1.1 christos {
191 1.1 christos (*info->memory_error_func) (status, memaddr, info);
192 1.1 christos return;
193 1.1 christos }
194 1.1 christos temp |= bfd_getl16 (buffer);
195 1.1 christos
196 1.1 christos insn &= 0xff0000ff;
197 1.1 christos insn |= temp << 8;
198 1.1 christos
199 1.1 christos status = (*info->read_memory_func) (memaddr + 4, buffer, 1, info);
200 1.1 christos if (status != 0)
201 1.1 christos {
202 1.1 christos (*info->memory_error_func) (status, memaddr, info);
203 1.1 christos return;
204 1.1 christos }
205 1.1 christos extension = *(unsigned char *) buffer;
206 1.1 christos }
207 1.1 christos else if (size == 6 && op->format == FMT_D8)
208 1.1 christos {
209 1.1 christos insn &= 0xffffff00;
210 1.1 christos status = (*info->read_memory_func) (memaddr + 5, buffer, 1, info);
211 1.1 christos if (status != 0)
212 1.1 christos {
213 1.1 christos (*info->memory_error_func) (status, memaddr, info);
214 1.1 christos return;
215 1.1 christos }
216 1.1 christos insn |= *(unsigned char *) buffer;
217 1.1 christos
218 1.1 christos status = (*info->read_memory_func) (memaddr + 3, buffer, 2, info);
219 1.1 christos if (status != 0)
220 1.1 christos {
221 1.1 christos (*info->memory_error_func) (status, memaddr, info);
222 1.1 christos return;
223 1.1 christos }
224 1.1 christos extension = bfd_getl16 (buffer);
225 1.1 christos }
226 1.1 christos else if (size == 6)
227 1.1 christos {
228 1.1 christos unsigned long temp = 0;
229 1.1 christos
230 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
231 1.1 christos if (status != 0)
232 1.1 christos {
233 1.1 christos (*info->memory_error_func) (status, memaddr, info);
234 1.1 christos return;
235 1.1 christos }
236 1.1 christos temp |= bfd_getl32 (buffer);
237 1.1 christos
238 1.1 christos insn &= 0xffff0000;
239 1.1 christos insn |= (temp >> 16) & 0xffff;
240 1.1 christos extension = temp & 0xffff;
241 1.1 christos }
242 1.1 christos else if (size == 7 && op->format == FMT_D9)
243 1.1 christos {
244 1.1 christos insn &= 0xffffff00;
245 1.1 christos status = (*info->read_memory_func) (memaddr + 3, buffer, 4, info);
246 1.1 christos if (status != 0)
247 1.1 christos {
248 1.1 christos (*info->memory_error_func) (status, memaddr, info);
249 1.1 christos return;
250 1.1 christos }
251 1.1 christos extension = bfd_getl32 (buffer);
252 1.1 christos insn |= (extension & 0xff000000) >> 24;
253 1.1 christos extension &= 0xffffff;
254 1.1 christos }
255 1.1 christos else if (size == 7 && op->opcode == 0xdd000000)
256 1.1 christos {
257 1.1 christos unsigned long temp = 0;
258 1.1 christos
259 1.1 christos status = (*info->read_memory_func) (memaddr + 1, buffer, 4, info);
260 1.1 christos if (status != 0)
261 1.1 christos {
262 1.1 christos (*info->memory_error_func) (status, memaddr, info);
263 1.1 christos return;
264 1.1 christos }
265 1.1 christos temp |= bfd_getl32 (buffer);
266 1.1 christos
267 1.1 christos insn &= 0xff000000;
268 1.1 christos insn |= (temp >> 8) & 0xffffff;
269 1.1 christos extension = (temp & 0xff) << 16;
270 1.1 christos
271 1.1 christos status = (*info->read_memory_func) (memaddr + 5, buffer, 2, info);
272 1.1 christos if (status != 0)
273 1.1 christos {
274 1.1 christos (*info->memory_error_func) (status, memaddr, info);
275 1.1 christos return;
276 1.1 christos }
277 1.1 christos extension |= bfd_getb16 (buffer);
278 1.1 christos }
279 1.1 christos else if (size == 7)
280 1.1 christos {
281 1.1 christos unsigned long temp = 0;
282 1.1 christos
283 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 4, info);
284 1.1 christos if (status != 0)
285 1.1 christos {
286 1.1 christos (*info->memory_error_func) (status, memaddr, info);
287 1.1 christos return;
288 1.1 christos }
289 1.1 christos temp |= bfd_getl32 (buffer);
290 1.1 christos
291 1.1 christos insn &= 0xffff0000;
292 1.1 christos insn |= (temp >> 16) & 0xffff;
293 1.1 christos extension = (temp & 0xffff) << 8;
294 1.1 christos
295 1.1 christos status = (*info->read_memory_func) (memaddr + 6, buffer, 1, info);
296 1.1 christos if (status != 0)
297 1.1 christos {
298 1.1 christos (*info->memory_error_func) (status, memaddr, info);
299 1.1 christos return;
300 1.1 christos }
301 1.1 christos extension |= *(unsigned char *) buffer;
302 1.1 christos }
303 1.1 christos
304 1.1 christos match = 1;
305 1.1 christos (*info->fprintf_func) (info->stream, "%s\t", op->name);
306 1.1 christos
307 1.1 christos /* Now print the operands. */
308 1.1 christos for (opindex_ptr = op->operands, nocomma = 1;
309 1.1 christos *opindex_ptr != 0;
310 1.1 christos opindex_ptr++)
311 1.1 christos {
312 1.1 christos unsigned long value;
313 1.1 christos
314 1.1 christos operand = &mn10300_operands[*opindex_ptr];
315 1.1 christos
316 1.1 christos /* If this operand is a PLUS (autoincrement), then do not emit
317 1.1 christos a comma before emitting the plus. */
318 1.1 christos if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
319 1.1 christos nocomma = 1;
320 1.1 christos
321 1.1 christos if ((operand->flags & MN10300_OPERAND_SPLIT) != 0)
322 1.1 christos {
323 1.1 christos unsigned long temp;
324 1.1 christos
325 1.1 christos value = insn & ((1 << operand->bits) - 1);
326 1.1 christos value <<= (32 - operand->bits);
327 1.1 christos temp = extension >> operand->shift;
328 1.1 christos temp &= ((1 << (32 - operand->bits)) - 1);
329 1.1 christos value |= temp;
330 1.1 christos value = ((value ^ (((unsigned long) 1) << 31))
331 1.1 christos - (((unsigned long) 1) << 31));
332 1.1 christos }
333 1.1 christos else if ((operand->flags & MN10300_OPERAND_24BIT) != 0)
334 1.1 christos {
335 1.1 christos unsigned long temp;
336 1.1 christos
337 1.1 christos value = insn & ((1 << operand->bits) - 1);
338 1.1 christos value <<= (24 - operand->bits);
339 1.1 christos temp = extension >> operand->shift;
340 1.1 christos temp &= ((1 << (24 - operand->bits)) - 1);
341 1.1 christos value |= temp;
342 1.1 christos if ((operand->flags & MN10300_OPERAND_SIGNED) != 0)
343 1.1 christos value = ((value & 0xffffff) ^ 0x800000) - 0x800000;
344 1.1 christos }
345 1.1 christos else if ((operand->flags & (MN10300_OPERAND_FSREG
346 1.1 christos | MN10300_OPERAND_FDREG)))
347 1.1 christos {
348 1.1 christos /* See m10300-opc.c just before #define FSM0 for an
349 1.1 christos explanation of these variables. Note that
350 1.1 christos FMT-implied shifts are not taken into account for
351 1.1 christos FP registers. */
352 1.1 christos unsigned long mask_low, mask_high;
353 1.1 christos int shl_low, shr_high, shl_high;
354 1.1 christos
355 1.1 christos switch (operand->bits)
356 1.1 christos {
357 1.1 christos case 5:
358 1.1 christos /* Handle regular FP registers. */
359 1.1 christos if (operand->shift >= 0)
360 1.1 christos {
361 1.1 christos /* This is an `m' register. */
362 1.1 christos shl_low = operand->shift;
363 1.1 christos shl_high = 8 + (8 & shl_low) + (shl_low & 4) / 4;
364 1.1 christos }
365 1.1 christos else
366 1.1 christos {
367 1.1 christos /* This is an `n' register. */
368 1.1 christos shl_low = -operand->shift;
369 1.1 christos shl_high = shl_low / 4;
370 1.1 christos }
371 1.1 christos mask_low = 0x0f;
372 1.1 christos mask_high = 0x10;
373 1.1 christos shr_high = 4;
374 1.1 christos break;
375 1.1 christos
376 1.1 christos case 3:
377 1.1 christos /* Handle accumulators. */
378 1.1 christos shl_low = -operand->shift;
379 1.1 christos shl_high = 0;
380 1.1 christos mask_low = 0x03;
381 1.1 christos mask_high = 0x04;
382 1.1 christos shr_high = 2;
383 1.1 christos break;
384 1.1 christos
385 1.1 christos default:
386 1.1 christos abort ();
387 1.1 christos }
388 1.1 christos value = ((((insn >> shl_high) << shr_high) & mask_high)
389 1.1 christos | ((insn >> shl_low) & mask_low));
390 1.1 christos }
391 1.1 christos else if ((operand->flags & MN10300_OPERAND_EXTENDED) != 0)
392 1.1 christos value = ((extension >> (operand->shift))
393 1.1 christos & ((1 << operand->bits) - 1));
394 1.1 christos
395 1.1 christos else
396 1.1 christos value = ((insn >> (operand->shift))
397 1.1 christos & ((1 << operand->bits) - 1));
398 1.1 christos
399 1.1 christos if ((operand->flags & MN10300_OPERAND_SIGNED) != 0
400 1.1 christos /* These are properly extended by the code above. */
401 1.1 christos && ((operand->flags & MN10300_OPERAND_24BIT) == 0))
402 1.1 christos value = ((value ^ (((unsigned long) 1) << (operand->bits - 1)))
403 1.1 christos - (((unsigned long) 1) << (operand->bits - 1)));
404 1.1 christos
405 1.1 christos if (!nocomma
406 1.1 christos && (!paren
407 1.1 christos || ((operand->flags & MN10300_OPERAND_PAREN) == 0)))
408 1.1 christos (*info->fprintf_func) (info->stream, ",");
409 1.1 christos
410 1.1 christos nocomma = 0;
411 1.1 christos
412 1.1 christos if ((operand->flags & MN10300_OPERAND_DREG) != 0)
413 1.1 christos {
414 1.1 christos value = ((insn >> (operand->shift + extra_shift))
415 1.1 christos & ((1 << operand->bits) - 1));
416 1.1 christos (*info->fprintf_func) (info->stream, "d%d", (int) value);
417 1.1 christos }
418 1.1 christos
419 1.1 christos else if ((operand->flags & MN10300_OPERAND_AREG) != 0)
420 1.1 christos {
421 1.1 christos value = ((insn >> (operand->shift + extra_shift))
422 1.1 christos & ((1 << operand->bits) - 1));
423 1.1 christos (*info->fprintf_func) (info->stream, "a%d", (int) value);
424 1.1 christos }
425 1.1 christos
426 1.1 christos else if ((operand->flags & MN10300_OPERAND_SP) != 0)
427 1.1 christos (*info->fprintf_func) (info->stream, "sp");
428 1.1 christos
429 1.1 christos else if ((operand->flags & MN10300_OPERAND_PSW) != 0)
430 1.1 christos (*info->fprintf_func) (info->stream, "psw");
431 1.1 christos
432 1.1 christos else if ((operand->flags & MN10300_OPERAND_MDR) != 0)
433 1.1 christos (*info->fprintf_func) (info->stream, "mdr");
434 1.1 christos
435 1.1 christos else if ((operand->flags & MN10300_OPERAND_RREG) != 0)
436 1.1 christos {
437 1.1 christos value = ((insn >> (operand->shift + extra_shift))
438 1.1 christos & ((1 << operand->bits) - 1));
439 1.1 christos if (value < 8)
440 1.1 christos (*info->fprintf_func) (info->stream, "r%d", (int) value);
441 1.1 christos else if (value < 12)
442 1.1 christos (*info->fprintf_func) (info->stream, "a%d", (int) value - 8);
443 1.1 christos else
444 1.1 christos (*info->fprintf_func) (info->stream, "d%d", (int) value - 12);
445 1.1 christos }
446 1.1 christos
447 1.1 christos else if ((operand->flags & MN10300_OPERAND_XRREG) != 0)
448 1.1 christos {
449 1.1 christos value = ((insn >> (operand->shift + extra_shift))
450 1.1 christos & ((1 << operand->bits) - 1));
451 1.1 christos if (value == 0)
452 1.1 christos (*info->fprintf_func) (info->stream, "sp");
453 1.1 christos else
454 1.1 christos (*info->fprintf_func) (info->stream, "xr%d", (int) value);
455 1.1 christos }
456 1.1 christos
457 1.1 christos else if ((operand->flags & MN10300_OPERAND_FSREG) != 0)
458 1.1 christos (*info->fprintf_func) (info->stream, "fs%d", (int) value);
459 1.1 christos
460 1.1 christos else if ((operand->flags & MN10300_OPERAND_FDREG) != 0)
461 1.1 christos (*info->fprintf_func) (info->stream, "fd%d", (int) value);
462 1.1 christos
463 1.1 christos else if ((operand->flags & MN10300_OPERAND_FPCR) != 0)
464 1.1 christos (*info->fprintf_func) (info->stream, "fpcr");
465 1.1 christos
466 1.1 christos else if ((operand->flags & MN10300_OPERAND_USP) != 0)
467 1.1 christos (*info->fprintf_func) (info->stream, "usp");
468 1.1 christos
469 1.1 christos else if ((operand->flags & MN10300_OPERAND_SSP) != 0)
470 1.1 christos (*info->fprintf_func) (info->stream, "ssp");
471 1.1 christos
472 1.1 christos else if ((operand->flags & MN10300_OPERAND_MSP) != 0)
473 1.1 christos (*info->fprintf_func) (info->stream, "msp");
474 1.1 christos
475 1.1 christos else if ((operand->flags & MN10300_OPERAND_PC) != 0)
476 1.1 christos (*info->fprintf_func) (info->stream, "pc");
477 1.1 christos
478 1.1 christos else if ((operand->flags & MN10300_OPERAND_EPSW) != 0)
479 1.1 christos (*info->fprintf_func) (info->stream, "epsw");
480 1.1 christos
481 1.1 christos else if ((operand->flags & MN10300_OPERAND_PLUS) != 0)
482 1.1 christos (*info->fprintf_func) (info->stream, "+");
483 1.1 christos
484 1.1 christos else if ((operand->flags & MN10300_OPERAND_PAREN) != 0)
485 1.1 christos {
486 1.1 christos if (paren)
487 1.1 christos (*info->fprintf_func) (info->stream, ")");
488 1.1 christos else
489 1.1 christos {
490 1.1 christos (*info->fprintf_func) (info->stream, "(");
491 1.1 christos nocomma = 1;
492 1.1 christos }
493 1.1 christos paren = !paren;
494 1.1 christos }
495 1.1 christos
496 1.1 christos else if ((operand->flags & MN10300_OPERAND_PCREL) != 0)
497 1.1 christos (*info->print_address_func) ((long) value + memaddr, info);
498 1.1 christos
499 1.1 christos else if ((operand->flags & MN10300_OPERAND_MEMADDR) != 0)
500 1.1 christos (*info->print_address_func) (value, info);
501 1.1 christos
502 1.1 christos else if ((operand->flags & MN10300_OPERAND_REG_LIST) != 0)
503 1.1 christos {
504 1.1 christos int comma = 0;
505 1.1 christos
506 1.1 christos (*info->fprintf_func) (info->stream, "[");
507 1.1 christos if (value & 0x80)
508 1.1 christos {
509 1.1 christos (*info->fprintf_func) (info->stream, "d2");
510 1.1 christos comma = 1;
511 1.1 christos }
512 1.1 christos
513 1.1 christos if (value & 0x40)
514 1.1 christos {
515 1.1 christos if (comma)
516 1.1 christos (*info->fprintf_func) (info->stream, ",");
517 1.1 christos (*info->fprintf_func) (info->stream, "d3");
518 1.1 christos comma = 1;
519 1.1 christos }
520 1.1 christos
521 1.1 christos if (value & 0x20)
522 1.1 christos {
523 1.1 christos if (comma)
524 1.1 christos (*info->fprintf_func) (info->stream, ",");
525 1.1 christos (*info->fprintf_func) (info->stream, "a2");
526 1.1 christos comma = 1;
527 1.1 christos }
528 1.1 christos
529 1.1 christos if (value & 0x10)
530 1.1 christos {
531 1.1 christos if (comma)
532 1.1 christos (*info->fprintf_func) (info->stream, ",");
533 1.1 christos (*info->fprintf_func) (info->stream, "a3");
534 1.1 christos comma = 1;
535 1.1 christos }
536 1.1 christos
537 1.1 christos if (value & 0x08)
538 1.1 christos {
539 1.1 christos if (comma)
540 1.1 christos (*info->fprintf_func) (info->stream, ",");
541 1.1 christos (*info->fprintf_func) (info->stream, "other");
542 1.1 christos comma = 1;
543 1.1 christos }
544 1.1 christos
545 1.1 christos if (value & 0x04)
546 1.1 christos {
547 1.1 christos if (comma)
548 1.1 christos (*info->fprintf_func) (info->stream, ",");
549 1.1 christos (*info->fprintf_func) (info->stream, "exreg0");
550 1.1 christos comma = 1;
551 1.1 christos }
552 1.1 christos if (value & 0x02)
553 1.1 christos {
554 1.1 christos if (comma)
555 1.1 christos (*info->fprintf_func) (info->stream, ",");
556 1.1 christos (*info->fprintf_func) (info->stream, "exreg1");
557 1.1 christos comma = 1;
558 1.1 christos }
559 1.1 christos if (value & 0x01)
560 1.1 christos {
561 1.1 christos if (comma)
562 1.1 christos (*info->fprintf_func) (info->stream, ",");
563 1.1 christos (*info->fprintf_func) (info->stream, "exother");
564 1.1 christos comma = 1;
565 1.1 christos }
566 1.1 christos (*info->fprintf_func) (info->stream, "]");
567 1.1 christos }
568 1.1 christos
569 1.1 christos else
570 1.1 christos (*info->fprintf_func) (info->stream, "%ld", (long) value);
571 1.1 christos }
572 1.1 christos /* All done. */
573 1.1 christos break;
574 1.1 christos }
575 1.1 christos op++;
576 1.1 christos }
577 1.1 christos
578 1.1 christos if (!match)
579 1.1 christos /* xgettext:c-format */
580 1.1 christos (*info->fprintf_func) (info->stream, _("unknown\t0x%04lx"), insn);
581 1.1 christos }
582 1.1 christos
583 1.1 christos int
584 1.1 christos print_insn_mn10300 (bfd_vma memaddr, struct disassemble_info *info)
585 1.1 christos {
586 1.1 christos int status;
587 1.1 christos bfd_byte buffer[4];
588 1.1 christos unsigned long insn;
589 1.1 christos unsigned int consume;
590 1.1 christos
591 1.1 christos /* First figure out how big the opcode is. */
592 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 1, info);
593 1.1 christos if (status != 0)
594 1.1 christos {
595 1.1 christos (*info->memory_error_func) (status, memaddr, info);
596 1.1 christos return -1;
597 1.1 christos }
598 1.1 christos insn = *(unsigned char *) buffer;
599 1.1 christos
600 1.1 christos /* These are one byte insns. */
601 1.1 christos if ((insn & 0xf3) == 0x00
602 1.1 christos || (insn & 0xf0) == 0x10
603 1.1 christos || (insn & 0xfc) == 0x3c
604 1.1 christos || (insn & 0xf3) == 0x41
605 1.1 christos || (insn & 0xf3) == 0x40
606 1.1 christos || (insn & 0xfc) == 0x50
607 1.1 christos || (insn & 0xfc) == 0x54
608 1.1 christos || (insn & 0xf0) == 0x60
609 1.1 christos || (insn & 0xf0) == 0x70
610 1.1 christos || ((insn & 0xf0) == 0x80
611 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
612 1.1 christos || ((insn & 0xf0) == 0x90
613 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
614 1.1 christos || ((insn & 0xf0) == 0xa0
615 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
616 1.1 christos || ((insn & 0xf0) == 0xb0
617 1.1 christos && (insn & 0x0c) >> 2 != (insn & 0x03))
618 1.1 christos || (insn & 0xff) == 0xcb
619 1.1 christos || (insn & 0xfc) == 0xd0
620 1.1 christos || (insn & 0xfc) == 0xd4
621 1.1 christos || (insn & 0xfc) == 0xd8
622 1.1 christos || (insn & 0xf0) == 0xe0
623 1.1 christos || (insn & 0xff) == 0xff)
624 1.1 christos {
625 1.1 christos consume = 1;
626 1.1 christos }
627 1.1 christos
628 1.1 christos /* These are two byte insns. */
629 1.1 christos else if ((insn & 0xf0) == 0x80
630 1.1 christos || (insn & 0xf0) == 0x90
631 1.1 christos || (insn & 0xf0) == 0xa0
632 1.1 christos || (insn & 0xf0) == 0xb0
633 1.1 christos || (insn & 0xfc) == 0x20
634 1.1 christos || (insn & 0xfc) == 0x28
635 1.1 christos || (insn & 0xf3) == 0x43
636 1.1 christos || (insn & 0xf3) == 0x42
637 1.1 christos || (insn & 0xfc) == 0x58
638 1.1 christos || (insn & 0xfc) == 0x5c
639 1.1 christos || ((insn & 0xf0) == 0xc0
640 1.1 christos && (insn & 0xff) != 0xcb
641 1.1 christos && (insn & 0xff) != 0xcc
642 1.1 christos && (insn & 0xff) != 0xcd)
643 1.1 christos || (insn & 0xff) == 0xf0
644 1.1 christos || (insn & 0xff) == 0xf1
645 1.1 christos || (insn & 0xff) == 0xf2
646 1.1 christos || (insn & 0xff) == 0xf3
647 1.1 christos || (insn & 0xff) == 0xf4
648 1.1 christos || (insn & 0xff) == 0xf5
649 1.1 christos || (insn & 0xff) == 0xf6)
650 1.1 christos {
651 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 2, info);
652 1.1 christos if (status != 0)
653 1.1 christos {
654 1.1 christos (*info->memory_error_func) (status, memaddr, info);
655 1.1 christos return -1;
656 1.1 christos }
657 1.1 christos insn = bfd_getb16 (buffer);
658 1.1 christos consume = 2;
659 1.1 christos }
660 1.1 christos
661 1.1 christos /* These are three byte insns. */
662 1.1 christos else if ((insn & 0xff) == 0xf8
663 1.1 christos || (insn & 0xff) == 0xcc
664 1.1 christos || (insn & 0xff) == 0xf9
665 1.1 christos || (insn & 0xf3) == 0x01
666 1.1 christos || (insn & 0xf3) == 0x02
667 1.1 christos || (insn & 0xf3) == 0x03
668 1.1 christos || (insn & 0xfc) == 0x24
669 1.1 christos || (insn & 0xfc) == 0x2c
670 1.1 christos || (insn & 0xfc) == 0x30
671 1.1 christos || (insn & 0xfc) == 0x34
672 1.1 christos || (insn & 0xfc) == 0x38
673 1.1 christos || (insn & 0xff) == 0xde
674 1.1 christos || (insn & 0xff) == 0xdf
675 1.1 christos || (insn & 0xff) == 0xf9
676 1.1 christos || (insn & 0xff) == 0xcc)
677 1.1 christos {
678 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 2, info);
679 1.1 christos if (status != 0)
680 1.1 christos {
681 1.1 christos (*info->memory_error_func) (status, memaddr, info);
682 1.1 christos return -1;
683 1.1 christos }
684 1.1 christos insn = bfd_getb16 (buffer);
685 1.1 christos insn <<= 8;
686 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buffer, 1, info);
687 1.1 christos if (status != 0)
688 1.1 christos {
689 1.1 christos (*info->memory_error_func) (status, memaddr, info);
690 1.1 christos return -1;
691 1.1 christos }
692 1.1 christos insn |= *(unsigned char *) buffer;
693 1.1 christos consume = 3;
694 1.1 christos }
695 1.1 christos
696 1.1 christos /* These are four byte insns. */
697 1.1 christos else if ((insn & 0xff) == 0xfa
698 1.1 christos || (insn & 0xff) == 0xf7
699 1.1 christos || (insn & 0xff) == 0xfb)
700 1.1 christos {
701 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
702 1.1 christos if (status != 0)
703 1.1 christos {
704 1.1 christos (*info->memory_error_func) (status, memaddr, info);
705 1.1 christos return -1;
706 1.1 christos }
707 1.1 christos insn = bfd_getb32 (buffer);
708 1.1 christos consume = 4;
709 1.1 christos }
710 1.1 christos
711 1.1 christos /* These are five byte insns. */
712 1.1 christos else if ((insn & 0xff) == 0xcd
713 1.1 christos || (insn & 0xff) == 0xdc)
714 1.1 christos {
715 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
716 1.1 christos if (status != 0)
717 1.1 christos {
718 1.1 christos (*info->memory_error_func) (status, memaddr, info);
719 1.1 christos return -1;
720 1.1 christos }
721 1.1 christos insn = bfd_getb32 (buffer);
722 1.1 christos consume = 5;
723 1.1 christos }
724 1.1 christos
725 1.1 christos /* These are six byte insns. */
726 1.1 christos else if ((insn & 0xff) == 0xfd
727 1.1 christos || (insn & 0xff) == 0xfc)
728 1.1 christos {
729 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
730 1.1 christos if (status != 0)
731 1.1 christos {
732 1.1 christos (*info->memory_error_func) (status, memaddr, info);
733 1.1 christos return -1;
734 1.1 christos }
735 1.1 christos
736 1.1 christos insn = bfd_getb32 (buffer);
737 1.1 christos consume = 6;
738 1.1 christos }
739 1.1 christos
740 1.1 christos /* Else its a seven byte insns (in theory). */
741 1.1 christos else
742 1.1 christos {
743 1.1 christos status = (*info->read_memory_func) (memaddr, buffer, 4, info);
744 1.1 christos if (status != 0)
745 1.1 christos {
746 1.1 christos (*info->memory_error_func) (status, memaddr, info);
747 1.1 christos return -1;
748 1.1 christos }
749 1.1 christos
750 1.1 christos insn = bfd_getb32 (buffer);
751 1.1 christos consume = 7;
752 1.1 christos /* Handle the 5-byte extended instruction codes. */
753 1.1 christos if ((insn & 0xfff80000) == 0xfe800000)
754 1.1 christos consume = 5;
755 1.1 christos }
756 1.1 christos
757 1.1 christos disassemble (memaddr, info, insn, consume);
758 1.1 christos
759 1.1 christos return consume;
760 1.1 christos }
761