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