m68k-dis.c revision 1.10 1 1.1 christos /* Print Motorola 68k instructions.
2 1.10 christos Copyright (C) 1986-2022 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.8 christos #include "disassemble.h"
23 1.1 christos #include "floatformat.h"
24 1.1 christos #include "libiberty.h"
25 1.1 christos #include "opintl.h"
26 1.9 christos #include "cpu-m68k.h"
27 1.1 christos #include "opcode/m68k.h"
28 1.1 christos
29 1.1 christos /* Local function prototypes. */
30 1.1 christos
31 1.1 christos const char * const fpcr_names[] =
32 1.1 christos {
33 1.1 christos "", "%fpiar", "%fpsr", "%fpiar/%fpsr", "%fpcr",
34 1.1 christos "%fpiar/%fpcr", "%fpsr/%fpcr", "%fpiar/%fpsr/%fpcr"
35 1.1 christos };
36 1.1 christos
37 1.1 christos static char *const reg_names[] =
38 1.1 christos {
39 1.1 christos "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
40 1.1 christos "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%fp", "%sp",
41 1.1 christos "%ps", "%pc"
42 1.1 christos };
43 1.1 christos
44 1.1 christos /* Name of register halves for MAC/EMAC.
45 1.1 christos Seperate from reg_names since 'spu', 'fpl' look weird. */
46 1.1 christos static char *const reg_half_names[] =
47 1.1 christos {
48 1.1 christos "%d0", "%d1", "%d2", "%d3", "%d4", "%d5", "%d6", "%d7",
49 1.1 christos "%a0", "%a1", "%a2", "%a3", "%a4", "%a5", "%a6", "%a7",
50 1.1 christos "%ps", "%pc"
51 1.1 christos };
52 1.1 christos
53 1.1 christos /* Sign-extend an (unsigned char). */
54 1.1 christos #if __STDC__ == 1
55 1.1 christos #define COERCE_SIGNED_CHAR(ch) ((signed char) (ch))
56 1.1 christos #else
57 1.1 christos #define COERCE_SIGNED_CHAR(ch) ((int) (((ch) ^ 0x80) & 0xFF) - 128)
58 1.1 christos #endif
59 1.1 christos
60 1.7 christos /* Error code of print_insn_arg's return value. */
61 1.7 christos
62 1.7 christos enum print_insn_arg_error
63 1.7 christos {
64 1.7 christos /* An invalid operand is found. */
65 1.7 christos PRINT_INSN_ARG_INVALID_OPERAND = -1,
66 1.7 christos
67 1.7 christos /* An opcode table error. */
68 1.7 christos PRINT_INSN_ARG_INVALID_OP_TABLE = -2,
69 1.7 christos
70 1.7 christos /* A memory error. */
71 1.7 christos PRINT_INSN_ARG_MEMORY_ERROR = -3,
72 1.7 christos };
73 1.7 christos
74 1.1 christos /* Get a 1 byte signed integer. */
75 1.1 christos #define NEXTBYTE(p, val) \
76 1.1 christos do \
77 1.1 christos { \
78 1.1 christos p += 2; \
79 1.1 christos if (!FETCH_DATA (info, p)) \
80 1.7 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
81 1.1 christos val = COERCE_SIGNED_CHAR (p[-1]); \
82 1.1 christos } \
83 1.1 christos while (0)
84 1.1 christos
85 1.1 christos /* Get a 2 byte signed integer. */
86 1.1 christos #define COERCE16(x) ((int) (((x) ^ 0x8000) - 0x8000))
87 1.1 christos
88 1.1 christos #define NEXTWORD(p, val, ret_val) \
89 1.1 christos do \
90 1.1 christos { \
91 1.1 christos p += 2; \
92 1.1 christos if (!FETCH_DATA (info, p)) \
93 1.1 christos return ret_val; \
94 1.1 christos val = COERCE16 ((p[-2] << 8) + p[-1]); \
95 1.1 christos } \
96 1.6 christos while (0)
97 1.1 christos
98 1.1 christos /* Get a 4 byte signed integer. */
99 1.9 christos #define COERCE32(x) (((bfd_vma) (x) ^ 0x80000000) - 0x80000000)
100 1.1 christos
101 1.1 christos #define NEXTLONG(p, val, ret_val) \
102 1.1 christos do \
103 1.1 christos { \
104 1.1 christos p += 4; \
105 1.1 christos if (!FETCH_DATA (info, p)) \
106 1.1 christos return ret_val; \
107 1.9 christos val = COERCE32 (((((((unsigned) p[-4] << 8) + p[-3]) << 8) \
108 1.9 christos + p[-2]) << 8) + p[-1]); \
109 1.1 christos } \
110 1.1 christos while (0)
111 1.1 christos
112 1.1 christos /* Get a 4 byte unsigned integer. */
113 1.1 christos #define NEXTULONG(p, val) \
114 1.1 christos do \
115 1.1 christos { \
116 1.1 christos p += 4; \
117 1.1 christos if (!FETCH_DATA (info, p)) \
118 1.7 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
119 1.9 christos val = (((((((unsigned) p[-4] << 8) + p[-3]) << 8) \
120 1.9 christos + p[-2]) << 8) + p[-1]); \
121 1.1 christos } \
122 1.1 christos while (0)
123 1.1 christos
124 1.1 christos /* Get a single precision float. */
125 1.1 christos #define NEXTSINGLE(val, p) \
126 1.1 christos do \
127 1.1 christos { \
128 1.1 christos p += 4; \
129 1.1 christos if (!FETCH_DATA (info, p)) \
130 1.7 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
131 1.1 christos floatformat_to_double (& floatformat_ieee_single_big, \
132 1.1 christos (char *) p - 4, & val); \
133 1.1 christos } \
134 1.1 christos while (0)
135 1.1 christos
136 1.1 christos /* Get a double precision float. */
137 1.1 christos #define NEXTDOUBLE(val, p) \
138 1.1 christos do \
139 1.1 christos { \
140 1.1 christos p += 8; \
141 1.1 christos if (!FETCH_DATA (info, p)) \
142 1.7 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
143 1.1 christos floatformat_to_double (& floatformat_ieee_double_big, \
144 1.1 christos (char *) p - 8, & val); \
145 1.1 christos } \
146 1.1 christos while (0)
147 1.1 christos
148 1.1 christos /* Get an extended precision float. */
149 1.1 christos #define NEXTEXTEND(val, p) \
150 1.1 christos do \
151 1.1 christos { \
152 1.1 christos p += 12; \
153 1.1 christos if (!FETCH_DATA (info, p)) \
154 1.7 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
155 1.1 christos floatformat_to_double (& floatformat_m68881_ext, \
156 1.1 christos (char *) p - 12, & val); \
157 1.1 christos } \
158 1.1 christos while (0)
159 1.1 christos
160 1.1 christos /* Need a function to convert from packed to double
161 1.1 christos precision. Actually, it's easier to print a
162 1.1 christos packed number than a double anyway, so maybe
163 1.1 christos there should be a special case to handle this... */
164 1.1 christos #define NEXTPACKED(p, val) \
165 1.1 christos do \
166 1.1 christos { \
167 1.1 christos p += 12; \
168 1.1 christos if (!FETCH_DATA (info, p)) \
169 1.7 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
170 1.1 christos val = 0.0; \
171 1.1 christos } \
172 1.1 christos while (0)
173 1.1 christos
174 1.1 christos
175 1.1 christos /* Maximum length of an instruction. */
177 1.1 christos #define MAXLEN 22
178 1.1 christos
179 1.1 christos struct private
180 1.1 christos {
181 1.1 christos /* Points to first byte not fetched. */
182 1.1 christos bfd_byte *max_fetched;
183 1.1 christos bfd_byte the_buffer[MAXLEN];
184 1.1 christos bfd_vma insn_start;
185 1.1 christos };
186 1.1 christos
187 1.7 christos /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
188 1.7 christos to ADDR (exclusive) are valid. Returns 1 for success, 0 on memory
189 1.1 christos error. */
190 1.1 christos #define FETCH_DATA(info, addr) \
191 1.1 christos ((addr) <= ((struct private *) (info->private_data))->max_fetched \
192 1.1 christos ? 1 : fetch_data ((info), (addr)))
193 1.1 christos
194 1.1 christos static int
195 1.1 christos fetch_data (struct disassemble_info *info, bfd_byte *addr)
196 1.1 christos {
197 1.1 christos int status;
198 1.1 christos struct private *priv = (struct private *)info->private_data;
199 1.1 christos bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
200 1.1 christos
201 1.1 christos status = (*info->read_memory_func) (start,
202 1.1 christos priv->max_fetched,
203 1.1 christos addr - priv->max_fetched,
204 1.1 christos info);
205 1.1 christos if (status != 0)
206 1.1 christos {
207 1.1 christos (*info->memory_error_func) (status, start, info);
208 1.1 christos return 0;
209 1.1 christos }
210 1.1 christos else
211 1.1 christos priv->max_fetched = addr;
212 1.1 christos return 1;
213 1.1 christos }
214 1.1 christos
215 1.1 christos /* This function is used to print to the bit-bucket. */
217 1.1 christos static int
218 1.1 christos dummy_printer (FILE *file ATTRIBUTE_UNUSED,
219 1.1 christos const char *format ATTRIBUTE_UNUSED,
220 1.1 christos ...)
221 1.1 christos {
222 1.1 christos return 0;
223 1.1 christos }
224 1.1 christos
225 1.1 christos static void
226 1.1 christos dummy_print_address (bfd_vma vma ATTRIBUTE_UNUSED,
227 1.1 christos struct disassemble_info *info ATTRIBUTE_UNUSED)
228 1.1 christos {
229 1.1 christos }
230 1.1 christos
231 1.1 christos /* Fetch BITS bits from a position in the instruction specified by CODE.
232 1.1 christos CODE is a "place to put an argument", or 'x' for a destination
233 1.1 christos that is a general address (mode and register).
234 1.1 christos BUFFER contains the instruction.
235 1.1 christos Returns -1 on failure. */
236 1.1 christos
237 1.1 christos static int
238 1.1 christos fetch_arg (unsigned char *buffer,
239 1.1 christos int code,
240 1.1 christos int bits,
241 1.1 christos disassemble_info *info)
242 1.1 christos {
243 1.1 christos int val = 0;
244 1.1 christos
245 1.1 christos switch (code)
246 1.1 christos {
247 1.1 christos case '/': /* MAC/EMAC mask bit. */
248 1.1 christos val = buffer[3] >> 5;
249 1.1 christos break;
250 1.1 christos
251 1.1 christos case 'G': /* EMAC ACC load. */
252 1.1 christos val = ((buffer[3] >> 3) & 0x2) | ((~buffer[1] >> 7) & 0x1);
253 1.1 christos break;
254 1.1 christos
255 1.1 christos case 'H': /* EMAC ACC !load. */
256 1.1 christos val = ((buffer[3] >> 3) & 0x2) | ((buffer[1] >> 7) & 0x1);
257 1.1 christos break;
258 1.1 christos
259 1.1 christos case ']': /* EMAC ACCEXT bit. */
260 1.1 christos val = buffer[0] >> 2;
261 1.1 christos break;
262 1.1 christos
263 1.1 christos case 'I': /* MAC/EMAC scale factor. */
264 1.1 christos val = buffer[2] >> 1;
265 1.1 christos break;
266 1.1 christos
267 1.1 christos case 'F': /* EMAC ACCx. */
268 1.1 christos val = buffer[0] >> 1;
269 1.1 christos break;
270 1.1 christos
271 1.1 christos case 'f':
272 1.1 christos val = buffer[1];
273 1.1 christos break;
274 1.1 christos
275 1.1 christos case 's':
276 1.1 christos val = buffer[1];
277 1.1 christos break;
278 1.1 christos
279 1.1 christos case 'd': /* Destination, for register or quick. */
280 1.1 christos val = (buffer[0] << 8) + buffer[1];
281 1.1 christos val >>= 9;
282 1.1 christos break;
283 1.1 christos
284 1.1 christos case 'x': /* Destination, for general arg. */
285 1.1 christos val = (buffer[0] << 8) + buffer[1];
286 1.1 christos val >>= 6;
287 1.1 christos break;
288 1.1 christos
289 1.1 christos case 'k':
290 1.1 christos if (! FETCH_DATA (info, buffer + 3))
291 1.1 christos return -1;
292 1.1 christos val = (buffer[3] >> 4);
293 1.1 christos break;
294 1.1 christos
295 1.1 christos case 'C':
296 1.1 christos if (! FETCH_DATA (info, buffer + 3))
297 1.1 christos return -1;
298 1.1 christos val = buffer[3];
299 1.1 christos break;
300 1.1 christos
301 1.1 christos case '1':
302 1.1 christos if (! FETCH_DATA (info, buffer + 3))
303 1.1 christos return -1;
304 1.1 christos val = (buffer[2] << 8) + buffer[3];
305 1.1 christos val >>= 12;
306 1.1 christos break;
307 1.1 christos
308 1.1 christos case '2':
309 1.1 christos if (! FETCH_DATA (info, buffer + 3))
310 1.1 christos return -1;
311 1.1 christos val = (buffer[2] << 8) + buffer[3];
312 1.1 christos val >>= 6;
313 1.1 christos break;
314 1.1 christos
315 1.1 christos case '3':
316 1.1 christos case 'j':
317 1.1 christos if (! FETCH_DATA (info, buffer + 3))
318 1.1 christos return -1;
319 1.1 christos val = (buffer[2] << 8) + buffer[3];
320 1.1 christos break;
321 1.1 christos
322 1.1 christos case '4':
323 1.1 christos if (! FETCH_DATA (info, buffer + 5))
324 1.1 christos return -1;
325 1.1 christos val = (buffer[4] << 8) + buffer[5];
326 1.1 christos val >>= 12;
327 1.1 christos break;
328 1.1 christos
329 1.1 christos case '5':
330 1.1 christos if (! FETCH_DATA (info, buffer + 5))
331 1.1 christos return -1;
332 1.1 christos val = (buffer[4] << 8) + buffer[5];
333 1.1 christos val >>= 6;
334 1.1 christos break;
335 1.1 christos
336 1.1 christos case '6':
337 1.1 christos if (! FETCH_DATA (info, buffer + 5))
338 1.1 christos return -1;
339 1.1 christos val = (buffer[4] << 8) + buffer[5];
340 1.1 christos break;
341 1.1 christos
342 1.1 christos case '7':
343 1.1 christos if (! FETCH_DATA (info, buffer + 3))
344 1.1 christos return -1;
345 1.1 christos val = (buffer[2] << 8) + buffer[3];
346 1.1 christos val >>= 7;
347 1.1 christos break;
348 1.1 christos
349 1.1 christos case '8':
350 1.1 christos if (! FETCH_DATA (info, buffer + 3))
351 1.1 christos return -1;
352 1.1 christos val = (buffer[2] << 8) + buffer[3];
353 1.1 christos val >>= 10;
354 1.1 christos break;
355 1.1 christos
356 1.1 christos case '9':
357 1.1 christos if (! FETCH_DATA (info, buffer + 3))
358 1.1 christos return -1;
359 1.1 christos val = (buffer[2] << 8) + buffer[3];
360 1.1 christos val >>= 5;
361 1.1 christos break;
362 1.1 christos
363 1.1 christos case 'e':
364 1.1 christos val = (buffer[1] >> 6);
365 1.1 christos break;
366 1.1 christos
367 1.1 christos case 'E':
368 1.1 christos if (! FETCH_DATA (info, buffer + 3))
369 1.1 christos return -1;
370 1.1 christos val = (buffer[2] >> 1);
371 1.1 christos break;
372 1.1 christos
373 1.1 christos case 'm':
374 1.1 christos val = (buffer[1] & 0x40 ? 0x8 : 0)
375 1.1 christos | ((buffer[0] >> 1) & 0x7)
376 1.1 christos | (buffer[3] & 0x80 ? 0x10 : 0);
377 1.1 christos break;
378 1.1 christos
379 1.1 christos case 'n':
380 1.1 christos val = (buffer[1] & 0x40 ? 0x8 : 0) | ((buffer[0] >> 1) & 0x7);
381 1.1 christos break;
382 1.1 christos
383 1.1 christos case 'o':
384 1.1 christos val = (buffer[2] >> 4) | (buffer[3] & 0x80 ? 0x10 : 0);
385 1.1 christos break;
386 1.1 christos
387 1.1 christos case 'M':
388 1.1 christos val = (buffer[1] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
389 1.1 christos break;
390 1.1 christos
391 1.1 christos case 'N':
392 1.1 christos val = (buffer[3] & 0xf) | (buffer[3] & 0x40 ? 0x10 : 0);
393 1.1 christos break;
394 1.1 christos
395 1.1 christos case 'h':
396 1.1 christos val = buffer[2] >> 2;
397 1.1 christos break;
398 1.1 christos
399 1.1 christos default:
400 1.1 christos abort ();
401 1.1 christos }
402 1.1 christos
403 1.1 christos /* bits is never too big. */
404 1.1 christos return val & ((1 << bits) - 1);
405 1.1 christos }
406 1.1 christos
407 1.1 christos /* Check if an EA is valid for a particular code. This is required
408 1.1 christos for the EMAC instructions since the type of source address determines
409 1.1 christos if it is a EMAC-load instruciton if the EA is mode 2-5, otherwise it
410 1.1 christos is a non-load EMAC instruction and the bits mean register Ry.
411 1.1 christos A similar case exists for the movem instructions where the register
412 1.10 christos mask is interpreted differently for different EAs. */
413 1.1 christos
414 1.1 christos static bool
415 1.1 christos m68k_valid_ea (char code, int val)
416 1.1 christos {
417 1.1 christos int mode, mask;
418 1.1 christos #define M(n0,n1,n2,n3,n4,n5,n6,n70,n71,n72,n73,n74) \
419 1.1 christos (n0 | n1 << 1 | n2 << 2 | n3 << 3 | n4 << 4 | n5 << 5 | n6 << 6 \
420 1.1 christos | n70 << 7 | n71 << 8 | n72 << 9 | n73 << 10 | n74 << 11)
421 1.1 christos
422 1.1 christos switch (code)
423 1.1 christos {
424 1.1 christos case '*':
425 1.1 christos mask = M (1,1,1,1,1,1,1,1,1,1,1,1);
426 1.1 christos break;
427 1.1 christos case '~':
428 1.1 christos mask = M (0,0,1,1,1,1,1,1,1,0,0,0);
429 1.1 christos break;
430 1.1 christos case '%':
431 1.1 christos mask = M (1,1,1,1,1,1,1,1,1,0,0,0);
432 1.1 christos break;
433 1.1 christos case ';':
434 1.1 christos mask = M (1,0,1,1,1,1,1,1,1,1,1,1);
435 1.1 christos break;
436 1.1 christos case '@':
437 1.1 christos mask = M (1,0,1,1,1,1,1,1,1,1,1,0);
438 1.1 christos break;
439 1.1 christos case '!':
440 1.1 christos mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
441 1.1 christos break;
442 1.1 christos case '&':
443 1.1 christos mask = M (0,0,1,0,0,1,1,1,1,0,0,0);
444 1.1 christos break;
445 1.1 christos case '$':
446 1.1 christos mask = M (1,0,1,1,1,1,1,1,1,0,0,0);
447 1.1 christos break;
448 1.1 christos case '?':
449 1.1 christos mask = M (1,0,1,0,0,1,1,1,1,0,0,0);
450 1.1 christos break;
451 1.1 christos case '/':
452 1.1 christos mask = M (1,0,1,0,0,1,1,1,1,1,1,0);
453 1.1 christos break;
454 1.1 christos case '|':
455 1.1 christos mask = M (0,0,1,0,0,1,1,1,1,1,1,0);
456 1.1 christos break;
457 1.1 christos case '>':
458 1.1 christos mask = M (0,0,1,0,1,1,1,1,1,0,0,0);
459 1.1 christos break;
460 1.1 christos case '<':
461 1.1 christos mask = M (0,0,1,1,0,1,1,1,1,1,1,0);
462 1.1 christos break;
463 1.1 christos case 'm':
464 1.1 christos mask = M (1,1,1,1,1,0,0,0,0,0,0,0);
465 1.1 christos break;
466 1.1 christos case 'n':
467 1.1 christos mask = M (0,0,0,0,0,1,0,0,0,1,0,0);
468 1.1 christos break;
469 1.1 christos case 'o':
470 1.1 christos mask = M (0,0,0,0,0,0,1,1,1,0,1,1);
471 1.1 christos break;
472 1.1 christos case 'p':
473 1.1 christos mask = M (1,1,1,1,1,1,0,0,0,0,0,0);
474 1.1 christos break;
475 1.1 christos case 'q':
476 1.1 christos mask = M (1,0,1,1,1,1,0,0,0,0,0,0);
477 1.1 christos break;
478 1.1 christos case 'v':
479 1.1 christos mask = M (1,0,1,1,1,1,0,1,1,0,0,0);
480 1.1 christos break;
481 1.1 christos case 'b':
482 1.1 christos mask = M (1,0,1,1,1,1,0,0,0,1,0,0);
483 1.1 christos break;
484 1.1 christos case 'w':
485 1.1 christos mask = M (0,0,1,1,1,1,0,0,0,1,0,0);
486 1.1 christos break;
487 1.1 christos case 'y':
488 1.1 christos mask = M (0,0,1,0,0,1,0,0,0,0,0,0);
489 1.1 christos break;
490 1.1 christos case 'z':
491 1.1 christos mask = M (0,0,1,0,0,1,0,0,0,1,0,0);
492 1.1 christos break;
493 1.1 christos case '4':
494 1.1 christos mask = M (0,0,1,1,1,1,0,0,0,0,0,0);
495 1.1 christos break;
496 1.1 christos default:
497 1.1 christos abort ();
498 1.1 christos }
499 1.1 christos #undef M
500 1.1 christos
501 1.1 christos mode = (val >> 3) & 7;
502 1.1 christos if (mode == 7)
503 1.1 christos mode += val & 7;
504 1.1 christos return (mask & (1 << mode)) != 0;
505 1.1 christos }
506 1.1 christos
507 1.1 christos /* Print a base register REGNO and displacement DISP, on INFO->STREAM.
508 1.1 christos REGNO = -1 for pc, -2 for none (suppressed). */
509 1.1 christos
510 1.1 christos static void
511 1.1 christos print_base (int regno, bfd_vma disp, disassemble_info *info)
512 1.1 christos {
513 1.1 christos if (regno == -1)
514 1.1 christos {
515 1.1 christos (*info->fprintf_func) (info->stream, "%%pc@(");
516 1.1 christos (*info->print_address_func) (disp, info);
517 1.1 christos }
518 1.1 christos else
519 1.1 christos {
520 1.1 christos if (regno == -2)
521 1.1 christos (*info->fprintf_func) (info->stream, "@(");
522 1.1 christos else if (regno == -3)
523 1.1 christos (*info->fprintf_func) (info->stream, "%%zpc@(");
524 1.10 christos else
525 1.1 christos (*info->fprintf_func) (info->stream, "%s@(", reg_names[regno]);
526 1.1 christos (*info->fprintf_func) (info->stream, "%" PRIx64, (uint64_t) disp);
527 1.1 christos }
528 1.1 christos }
529 1.1 christos
530 1.1 christos /* Print an indexed argument. The base register is BASEREG (-1 for pc).
531 1.1 christos P points to extension word, in buffer.
532 1.1 christos ADDR is the nominal core address of that extension word.
533 1.1 christos Returns NULL upon error. */
534 1.1 christos
535 1.1 christos static unsigned char *
536 1.1 christos print_indexed (int basereg,
537 1.1 christos unsigned char *p,
538 1.1 christos bfd_vma addr,
539 1.1 christos disassemble_info *info)
540 1.1 christos {
541 1.1 christos int word;
542 1.1 christos static char *const scales[] = { "", ":2", ":4", ":8" };
543 1.1 christos bfd_vma base_disp;
544 1.1 christos bfd_vma outer_disp;
545 1.1 christos char buf[40];
546 1.1 christos
547 1.1 christos NEXTWORD (p, word, NULL);
548 1.1 christos
549 1.1 christos /* Generate the text for the index register.
550 1.1 christos Where this will be output is not yet determined. */
551 1.1 christos sprintf (buf, "%s:%c%s",
552 1.1 christos reg_names[(word >> 12) & 0xf],
553 1.1 christos (word & 0x800) ? 'l' : 'w',
554 1.1 christos scales[(word >> 9) & 3]);
555 1.1 christos
556 1.1 christos /* Handle the 68000 style of indexing. */
557 1.1 christos
558 1.1 christos if ((word & 0x100) == 0)
559 1.1 christos {
560 1.1 christos base_disp = word & 0xff;
561 1.1 christos if ((base_disp & 0x80) != 0)
562 1.1 christos base_disp -= 0x100;
563 1.1 christos if (basereg == -1)
564 1.1 christos base_disp += addr;
565 1.1 christos print_base (basereg, base_disp, info);
566 1.1 christos (*info->fprintf_func) (info->stream, ",%s)", buf);
567 1.1 christos return p;
568 1.1 christos }
569 1.1 christos
570 1.1 christos /* Handle the generalized kind. */
571 1.1 christos /* First, compute the displacement to add to the base register. */
572 1.1 christos if (word & 0200)
573 1.1 christos {
574 1.1 christos if (basereg == -1)
575 1.1 christos basereg = -3;
576 1.1 christos else
577 1.1 christos basereg = -2;
578 1.1 christos }
579 1.1 christos if (word & 0100)
580 1.1 christos buf[0] = '\0';
581 1.1 christos base_disp = 0;
582 1.1 christos switch ((word >> 4) & 3)
583 1.1 christos {
584 1.1 christos case 2:
585 1.1 christos NEXTWORD (p, base_disp, NULL);
586 1.1 christos break;
587 1.1 christos case 3:
588 1.1 christos NEXTLONG (p, base_disp, NULL);
589 1.1 christos }
590 1.1 christos if (basereg == -1)
591 1.1 christos base_disp += addr;
592 1.1 christos
593 1.1 christos /* Handle single-level case (not indirect). */
594 1.1 christos if ((word & 7) == 0)
595 1.1 christos {
596 1.1 christos print_base (basereg, base_disp, info);
597 1.1 christos if (buf[0] != '\0')
598 1.1 christos (*info->fprintf_func) (info->stream, ",%s", buf);
599 1.1 christos (*info->fprintf_func) (info->stream, ")");
600 1.1 christos return p;
601 1.1 christos }
602 1.1 christos
603 1.1 christos /* Two level. Compute displacement to add after indirection. */
604 1.1 christos outer_disp = 0;
605 1.1 christos switch (word & 3)
606 1.1 christos {
607 1.1 christos case 2:
608 1.1 christos NEXTWORD (p, outer_disp, NULL);
609 1.1 christos break;
610 1.1 christos case 3:
611 1.1 christos NEXTLONG (p, outer_disp, NULL);
612 1.1 christos }
613 1.1 christos
614 1.1 christos print_base (basereg, base_disp, info);
615 1.1 christos if ((word & 4) == 0 && buf[0] != '\0')
616 1.1 christos {
617 1.1 christos (*info->fprintf_func) (info->stream, ",%s", buf);
618 1.10 christos buf[0] = '\0';
619 1.1 christos }
620 1.1 christos (*info->fprintf_func) (info->stream, ")@(%" PRIx64, (uint64_t) outer_disp);
621 1.1 christos if (buf[0] != '\0')
622 1.1 christos (*info->fprintf_func) (info->stream, ",%s", buf);
623 1.1 christos (*info->fprintf_func) (info->stream, ")");
624 1.1 christos
625 1.1 christos return p;
626 1.1 christos }
627 1.1 christos
628 1.1 christos #define FETCH_ARG(size, val) \
629 1.1 christos do \
630 1.1 christos { \
631 1.7 christos val = fetch_arg (buffer, place, size, info); \
632 1.1 christos if (val < 0) \
633 1.1 christos return PRINT_INSN_ARG_MEMORY_ERROR; \
634 1.1 christos } \
635 1.1 christos while (0)
636 1.7 christos
637 1.7 christos /* Returns number of bytes "eaten" by the operand, or
638 1.1 christos return enum print_insn_arg_error. ADDR is the pc for this arg to be
639 1.1 christos relative to. */
640 1.1 christos
641 1.1 christos static int
642 1.1 christos print_insn_arg (const char *d,
643 1.1 christos unsigned char *buffer,
644 1.1 christos unsigned char *p0,
645 1.1 christos bfd_vma addr,
646 1.1 christos disassemble_info *info)
647 1.1 christos {
648 1.1 christos int val = 0;
649 1.1 christos int place = d[1];
650 1.1 christos unsigned char *p = p0;
651 1.1 christos int regno;
652 1.1 christos const char *regname;
653 1.1 christos unsigned char *p1;
654 1.1 christos double flval;
655 1.1 christos int flt_p;
656 1.1 christos bfd_signed_vma disp;
657 1.1 christos unsigned int uval;
658 1.1 christos
659 1.1 christos switch (*d)
660 1.1 christos {
661 1.1 christos case 'c': /* Cache identifier. */
662 1.1 christos {
663 1.1 christos static char *const cacheFieldName[] = { "nc", "dc", "ic", "bc" };
664 1.1 christos FETCH_ARG (2, val);
665 1.1 christos (*info->fprintf_func) (info->stream, "%s", cacheFieldName[val]);
666 1.1 christos break;
667 1.1 christos }
668 1.1 christos
669 1.1 christos case 'a': /* Address register indirect only. Cf. case '+'. */
670 1.1 christos {
671 1.1 christos FETCH_ARG (3, val);
672 1.1 christos (*info->fprintf_func) (info->stream, "%s@", reg_names[val + 8]);
673 1.1 christos break;
674 1.1 christos }
675 1.1 christos
676 1.1 christos case '_': /* 32-bit absolute address for move16. */
677 1.1 christos {
678 1.1 christos NEXTULONG (p, uval);
679 1.1 christos (*info->print_address_func) (uval, info);
680 1.1 christos break;
681 1.1 christos }
682 1.1 christos
683 1.1 christos case 'C':
684 1.1 christos (*info->fprintf_func) (info->stream, "%%ccr");
685 1.1 christos break;
686 1.1 christos
687 1.1 christos case 'S':
688 1.1 christos (*info->fprintf_func) (info->stream, "%%sr");
689 1.1 christos break;
690 1.1 christos
691 1.1 christos case 'U':
692 1.1 christos (*info->fprintf_func) (info->stream, "%%usp");
693 1.1 christos break;
694 1.1 christos
695 1.1 christos case 'E':
696 1.1 christos (*info->fprintf_func) (info->stream, "%%acc");
697 1.1 christos break;
698 1.1 christos
699 1.1 christos case 'G':
700 1.1 christos (*info->fprintf_func) (info->stream, "%%macsr");
701 1.1 christos break;
702 1.1 christos
703 1.1 christos case 'H':
704 1.1 christos (*info->fprintf_func) (info->stream, "%%mask");
705 1.1 christos break;
706 1.1 christos
707 1.1 christos case 'J':
708 1.1 christos {
709 1.1 christos /* FIXME: There's a problem here, different m68k processors call the
710 1.1 christos same address different names. The tables below try to get it right
711 1.1 christos using info->mach, but only for v4e. */
712 1.1 christos struct regname { char * name; int value; };
713 1.1 christos static const struct regname names[] =
714 1.1 christos {
715 1.1 christos {"%sfc", 0x000}, {"%dfc", 0x001}, {"%cacr", 0x002},
716 1.1 christos {"%tc", 0x003}, {"%itt0",0x004}, {"%itt1", 0x005},
717 1.1 christos {"%dtt0",0x006}, {"%dtt1",0x007}, {"%buscr",0x008},
718 1.1 christos {"%rgpiobar", 0x009}, {"%acr4",0x00c},
719 1.1 christos {"%acr5",0x00d}, {"%acr6",0x00e}, {"%acr7", 0x00f},
720 1.1 christos {"%usp", 0x800}, {"%vbr", 0x801}, {"%caar", 0x802},
721 1.1 christos {"%msp", 0x803}, {"%isp", 0x804},
722 1.1 christos {"%pc", 0x80f},
723 1.1 christos /* Reg c04 is sometimes called flashbar or rambar.
724 1.1 christos Reg c05 is also sometimes called rambar. */
725 1.1 christos {"%rambar0", 0xc04}, {"%rambar1", 0xc05},
726 1.1 christos
727 1.1 christos /* reg c0e is sometimes called mbar2 or secmbar.
728 1.1 christos reg c0f is sometimes called mbar. */
729 1.1 christos {"%mbar0", 0xc0e}, {"%mbar1", 0xc0f},
730 1.1 christos
731 1.1 christos /* Should we be calling this psr like we do in case 'Y'? */
732 1.1 christos {"%mmusr",0x805},
733 1.1 christos
734 1.1 christos {"%urp", 0x806}, {"%srp", 0x807}, {"%pcr", 0x808},
735 1.1 christos
736 1.1 christos /* Fido added these. */
737 1.1 christos {"%cac", 0xffe}, {"%mbo", 0xfff}
738 1.1 christos };
739 1.1 christos /* Alternate names for v4e (MCF5407/5445x/MCF547x/MCF548x), at least. */
740 1.1 christos static const struct regname names_v4e[] =
741 1.1 christos {
742 1.1 christos {"%asid",0x003}, {"%acr0",0x004}, {"%acr1",0x005},
743 1.1 christos {"%acr2",0x006}, {"%acr3",0x007}, {"%mmubar",0x008},
744 1.1 christos };
745 1.1 christos unsigned int arch_mask;
746 1.1 christos
747 1.1 christos arch_mask = bfd_m68k_mach_to_features (info->mach);
748 1.1 christos FETCH_ARG (12, val);
749 1.1 christos if (arch_mask & (mcfisa_b | mcfisa_c))
750 1.1 christos {
751 1.1 christos for (regno = ARRAY_SIZE (names_v4e); --regno >= 0;)
752 1.1 christos if (names_v4e[regno].value == val)
753 1.1 christos {
754 1.1 christos (*info->fprintf_func) (info->stream, "%s", names_v4e[regno].name);
755 1.1 christos break;
756 1.1 christos }
757 1.1 christos if (regno >= 0)
758 1.1 christos break;
759 1.1 christos }
760 1.1 christos for (regno = ARRAY_SIZE (names) - 1; regno >= 0; regno--)
761 1.1 christos if (names[regno].value == val)
762 1.1 christos {
763 1.1 christos (*info->fprintf_func) (info->stream, "%s", names[regno].name);
764 1.1 christos break;
765 1.1 christos }
766 1.1 christos if (regno < 0)
767 1.1 christos (*info->fprintf_func) (info->stream, "0x%x", val);
768 1.1 christos }
769 1.1 christos break;
770 1.1 christos
771 1.1 christos case 'Q':
772 1.1 christos FETCH_ARG (3, val);
773 1.1 christos /* 0 means 8, except for the bkpt instruction... */
774 1.1 christos if (val == 0 && d[1] != 's')
775 1.1 christos val = 8;
776 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
777 1.1 christos break;
778 1.1 christos
779 1.1 christos case 'x':
780 1.1 christos FETCH_ARG (3, val);
781 1.1 christos /* 0 means -1. */
782 1.1 christos if (val == 0)
783 1.1 christos val = -1;
784 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
785 1.1 christos break;
786 1.1 christos
787 1.1 christos case 'j':
788 1.1 christos FETCH_ARG (3, val);
789 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val+1);
790 1.1 christos break;
791 1.1 christos
792 1.1 christos case 'K':
793 1.1 christos FETCH_ARG (9, val);
794 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
795 1.1 christos break;
796 1.1 christos
797 1.1 christos case 'M':
798 1.1 christos if (place == 'h')
799 1.1 christos {
800 1.1 christos static char *const scalefactor_name[] = { "<<", ">>" };
801 1.1 christos
802 1.1 christos FETCH_ARG (1, val);
803 1.1 christos (*info->fprintf_func) (info->stream, "%s", scalefactor_name[val]);
804 1.1 christos }
805 1.1 christos else
806 1.1 christos {
807 1.1 christos FETCH_ARG (8, val);
808 1.1 christos if (val & 0x80)
809 1.1 christos val = val - 0x100;
810 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
811 1.1 christos }
812 1.1 christos break;
813 1.1 christos
814 1.1 christos case 'T':
815 1.1 christos FETCH_ARG (4, val);
816 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
817 1.1 christos break;
818 1.1 christos
819 1.1 christos case 'D':
820 1.1 christos FETCH_ARG (3, val);
821 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
822 1.1 christos break;
823 1.1 christos
824 1.1 christos case 'A':
825 1.1 christos FETCH_ARG (3, val);
826 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg_names[val + 010]);
827 1.1 christos break;
828 1.1 christos
829 1.1 christos case 'R':
830 1.1 christos FETCH_ARG (4, val);
831 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
832 1.1 christos break;
833 1.1 christos
834 1.1 christos case 'r':
835 1.1 christos FETCH_ARG (4, regno);
836 1.1 christos if (regno > 7)
837 1.1 christos (*info->fprintf_func) (info->stream, "%s@", reg_names[regno]);
838 1.1 christos else
839 1.1 christos (*info->fprintf_func) (info->stream, "@(%s)", reg_names[regno]);
840 1.1 christos break;
841 1.1 christos
842 1.1 christos case 'F':
843 1.1 christos FETCH_ARG (3, val);
844 1.1 christos (*info->fprintf_func) (info->stream, "%%fp%d", val);
845 1.1 christos break;
846 1.1 christos
847 1.1 christos case 'O':
848 1.1 christos FETCH_ARG (6, val);
849 1.1 christos if (val & 0x20)
850 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg_names[val & 7]);
851 1.1 christos else
852 1.1 christos (*info->fprintf_func) (info->stream, "%d", val);
853 1.1 christos break;
854 1.1 christos
855 1.1 christos case '+':
856 1.1 christos FETCH_ARG (3, val);
857 1.1 christos (*info->fprintf_func) (info->stream, "%s@+", reg_names[val + 8]);
858 1.1 christos break;
859 1.1 christos
860 1.1 christos case '-':
861 1.1 christos FETCH_ARG (3, val);
862 1.1 christos (*info->fprintf_func) (info->stream, "%s@-", reg_names[val + 8]);
863 1.1 christos break;
864 1.1 christos
865 1.1 christos case 'k':
866 1.1 christos if (place == 'k')
867 1.1 christos {
868 1.1 christos FETCH_ARG (3, val);
869 1.1 christos (*info->fprintf_func) (info->stream, "{%s}", reg_names[val]);
870 1.1 christos }
871 1.1 christos else if (place == 'C')
872 1.1 christos {
873 1.1 christos FETCH_ARG (7, val);
874 1.1 christos if (val > 63) /* This is a signed constant. */
875 1.1 christos val -= 128;
876 1.1 christos (*info->fprintf_func) (info->stream, "{#%d}", val);
877 1.7 christos }
878 1.1 christos else
879 1.1 christos return PRINT_INSN_ARG_INVALID_OPERAND;
880 1.1 christos break;
881 1.1 christos
882 1.1 christos case '#':
883 1.1 christos case '^':
884 1.1 christos p1 = buffer + (*d == '#' ? 2 : 4);
885 1.1 christos if (place == 's')
886 1.1 christos FETCH_ARG (4, val);
887 1.1 christos else if (place == 'C')
888 1.1 christos FETCH_ARG (7, val);
889 1.1 christos else if (place == '8')
890 1.1 christos FETCH_ARG (3, val);
891 1.1 christos else if (place == '3')
892 1.1 christos FETCH_ARG (8, val);
893 1.1 christos else if (place == 'b')
894 1.7 christos NEXTBYTE (p1, val);
895 1.1 christos else if (place == 'w' || place == 'W')
896 1.7 christos NEXTWORD (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
897 1.1 christos else if (place == 'l')
898 1.7 christos NEXTLONG (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
899 1.1 christos else
900 1.1 christos return PRINT_INSN_ARG_INVALID_OP_TABLE;
901 1.1 christos
902 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
903 1.1 christos break;
904 1.1 christos
905 1.1 christos case 'B':
906 1.1 christos if (place == 'b')
907 1.1 christos NEXTBYTE (p, disp);
908 1.1 christos else if (place == 'B')
909 1.7 christos disp = COERCE_SIGNED_CHAR (buffer[1]);
910 1.1 christos else if (place == 'w' || place == 'W')
911 1.7 christos NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
912 1.1 christos else if (place == 'l' || place == 'L' || place == 'C')
913 1.1 christos NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
914 1.1 christos else if (place == 'g')
915 1.1 christos {
916 1.7 christos NEXTBYTE (buffer, disp);
917 1.1 christos if (disp == 0)
918 1.7 christos NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
919 1.1 christos else if (disp == -1)
920 1.1 christos NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
921 1.1 christos }
922 1.1 christos else if (place == 'c')
923 1.7 christos {
924 1.1 christos if (buffer[1] & 0x40) /* If bit six is one, long offset. */
925 1.7 christos NEXTLONG (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
926 1.1 christos else
927 1.1 christos NEXTWORD (p, disp, PRINT_INSN_ARG_MEMORY_ERROR);
928 1.7 christos }
929 1.1 christos else
930 1.1 christos return PRINT_INSN_ARG_INVALID_OP_TABLE;
931 1.1 christos
932 1.1 christos (*info->print_address_func) (addr + disp, info);
933 1.1 christos break;
934 1.1 christos
935 1.1 christos case 'd':
936 1.1 christos {
937 1.7 christos int val1;
938 1.1 christos
939 1.1 christos NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
940 1.1 christos FETCH_ARG (3, val1);
941 1.1 christos (*info->fprintf_func) (info->stream, "%s@(%d)", reg_names[val1 + 8], val);
942 1.1 christos break;
943 1.1 christos }
944 1.1 christos
945 1.1 christos case 's':
946 1.1 christos FETCH_ARG (3, val);
947 1.1 christos (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
948 1.1 christos break;
949 1.1 christos
950 1.1 christos case 'e':
951 1.1 christos FETCH_ARG (2, val);
952 1.1 christos (*info->fprintf_func) (info->stream, "%%acc%d", val);
953 1.1 christos break;
954 1.1 christos
955 1.1 christos case 'g':
956 1.1 christos FETCH_ARG (1, val);
957 1.1 christos (*info->fprintf_func) (info->stream, "%%accext%s", val == 0 ? "01" : "23");
958 1.1 christos break;
959 1.1 christos
960 1.1 christos case 'i':
961 1.1 christos FETCH_ARG (2, val);
962 1.1 christos if (val == 1)
963 1.1 christos (*info->fprintf_func) (info->stream, "<<");
964 1.1 christos else if (val == 3)
965 1.7 christos (*info->fprintf_func) (info->stream, ">>");
966 1.1 christos else
967 1.1 christos return PRINT_INSN_ARG_INVALID_OPERAND;
968 1.1 christos break;
969 1.1 christos
970 1.1 christos case 'I':
971 1.1 christos /* Get coprocessor ID... */
972 1.7 christos val = fetch_arg (buffer, 'd', 3, info);
973 1.1 christos if (val < 0)
974 1.1 christos return PRINT_INSN_ARG_MEMORY_ERROR;
975 1.1 christos if (val != 1) /* Unusual coprocessor ID? */
976 1.1 christos (*info->fprintf_func) (info->stream, "(cpid=%d) ", val);
977 1.1 christos break;
978 1.1 christos
979 1.1 christos case '4':
980 1.1 christos case '*':
981 1.1 christos case '~':
982 1.1 christos case '%':
983 1.1 christos case ';':
984 1.1 christos case '@':
985 1.1 christos case '!':
986 1.1 christos case '$':
987 1.1 christos case '?':
988 1.1 christos case '/':
989 1.1 christos case '&':
990 1.1 christos case '|':
991 1.1 christos case '<':
992 1.1 christos case '>':
993 1.1 christos case 'm':
994 1.1 christos case 'n':
995 1.1 christos case 'o':
996 1.1 christos case 'p':
997 1.1 christos case 'q':
998 1.1 christos case 'v':
999 1.1 christos case 'b':
1000 1.1 christos case 'w':
1001 1.1 christos case 'y':
1002 1.1 christos case 'z':
1003 1.1 christos if (place == 'd')
1004 1.1 christos {
1005 1.7 christos val = fetch_arg (buffer, 'x', 6, info);
1006 1.1 christos if (val < 0)
1007 1.1 christos return PRINT_INSN_ARG_MEMORY_ERROR;
1008 1.1 christos val = ((val & 7) << 3) + ((val >> 3) & 7);
1009 1.1 christos }
1010 1.1 christos else
1011 1.1 christos {
1012 1.7 christos val = fetch_arg (buffer, 's', 6, info);
1013 1.1 christos if (val < 0)
1014 1.1 christos return PRINT_INSN_ARG_MEMORY_ERROR;
1015 1.1 christos }
1016 1.1 christos
1017 1.7 christos /* If the <ea> is invalid for *d, then reject this match. */
1018 1.1 christos if (!m68k_valid_ea (*d, val))
1019 1.1 christos return PRINT_INSN_ARG_INVALID_OPERAND;
1020 1.1 christos
1021 1.1 christos /* Get register number assuming address register. */
1022 1.1 christos regno = (val & 7) + 8;
1023 1.1 christos regname = reg_names[regno];
1024 1.1 christos switch (val >> 3)
1025 1.1 christos {
1026 1.1 christos case 0:
1027 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg_names[val]);
1028 1.1 christos break;
1029 1.1 christos
1030 1.1 christos case 1:
1031 1.1 christos (*info->fprintf_func) (info->stream, "%s", regname);
1032 1.1 christos break;
1033 1.1 christos
1034 1.1 christos case 2:
1035 1.1 christos (*info->fprintf_func) (info->stream, "%s@", regname);
1036 1.1 christos break;
1037 1.1 christos
1038 1.1 christos case 3:
1039 1.1 christos (*info->fprintf_func) (info->stream, "%s@+", regname);
1040 1.1 christos break;
1041 1.1 christos
1042 1.1 christos case 4:
1043 1.1 christos (*info->fprintf_func) (info->stream, "%s@-", regname);
1044 1.1 christos break;
1045 1.7 christos
1046 1.1 christos case 5:
1047 1.1 christos NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1048 1.1 christos (*info->fprintf_func) (info->stream, "%s@(%d)", regname, val);
1049 1.1 christos break;
1050 1.1 christos
1051 1.1 christos case 6:
1052 1.7 christos p = print_indexed (regno, p, addr, info);
1053 1.1 christos if (p == NULL)
1054 1.1 christos return PRINT_INSN_ARG_MEMORY_ERROR;
1055 1.1 christos break;
1056 1.1 christos
1057 1.1 christos case 7:
1058 1.1 christos switch (val & 7)
1059 1.7 christos {
1060 1.1 christos case 0:
1061 1.1 christos NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1062 1.1 christos (*info->print_address_func) (val, info);
1063 1.1 christos break;
1064 1.1 christos
1065 1.1 christos case 1:
1066 1.1 christos NEXTULONG (p, uval);
1067 1.1 christos (*info->print_address_func) (uval, info);
1068 1.1 christos break;
1069 1.7 christos
1070 1.1 christos case 2:
1071 1.1 christos NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1072 1.1 christos (*info->fprintf_func) (info->stream, "%%pc@(");
1073 1.1 christos (*info->print_address_func) (addr + val, info);
1074 1.1 christos (*info->fprintf_func) (info->stream, ")");
1075 1.1 christos break;
1076 1.1 christos
1077 1.1 christos case 3:
1078 1.7 christos p = print_indexed (-1, p, addr, info);
1079 1.1 christos if (p == NULL)
1080 1.1 christos return PRINT_INSN_ARG_MEMORY_ERROR;
1081 1.1 christos break;
1082 1.1 christos
1083 1.1 christos case 4:
1084 1.1 christos flt_p = 1; /* Assume it's a float... */
1085 1.1 christos switch (place)
1086 1.1 christos {
1087 1.1 christos case 'b':
1088 1.1 christos NEXTBYTE (p, val);
1089 1.1 christos flt_p = 0;
1090 1.1 christos break;
1091 1.7 christos
1092 1.1 christos case 'w':
1093 1.1 christos NEXTWORD (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1094 1.1 christos flt_p = 0;
1095 1.1 christos break;
1096 1.7 christos
1097 1.1 christos case 'l':
1098 1.1 christos NEXTLONG (p, val, PRINT_INSN_ARG_MEMORY_ERROR);
1099 1.1 christos flt_p = 0;
1100 1.1 christos break;
1101 1.1 christos
1102 1.1 christos case 'f':
1103 1.1 christos NEXTSINGLE (flval, p);
1104 1.1 christos break;
1105 1.1 christos
1106 1.1 christos case 'F':
1107 1.1 christos NEXTDOUBLE (flval, p);
1108 1.1 christos break;
1109 1.1 christos
1110 1.1 christos case 'x':
1111 1.1 christos NEXTEXTEND (flval, p);
1112 1.1 christos break;
1113 1.1 christos
1114 1.1 christos case 'p':
1115 1.1 christos NEXTPACKED (p, flval);
1116 1.1 christos break;
1117 1.7 christos
1118 1.1 christos default:
1119 1.1 christos return PRINT_INSN_ARG_INVALID_OPERAND;
1120 1.1 christos }
1121 1.1 christos if (flt_p) /* Print a float? */
1122 1.1 christos (*info->fprintf_func) (info->stream, "#0e%g", flval);
1123 1.1 christos else
1124 1.1 christos (*info->fprintf_func) (info->stream, "#%d", val);
1125 1.1 christos break;
1126 1.7 christos
1127 1.1 christos default:
1128 1.1 christos return PRINT_INSN_ARG_INVALID_OPERAND;
1129 1.1 christos }
1130 1.1 christos }
1131 1.1 christos
1132 1.1 christos /* If place is '/', then this is the case of the mask bit for
1133 1.1 christos mac/emac loads. Now that the arg has been printed, grab the
1134 1.1 christos mask bit and if set, add a '&' to the arg. */
1135 1.1 christos if (place == '/')
1136 1.1 christos {
1137 1.1 christos FETCH_ARG (1, val);
1138 1.1 christos if (val)
1139 1.1 christos info->fprintf_func (info->stream, "&");
1140 1.1 christos }
1141 1.1 christos break;
1142 1.1 christos
1143 1.1 christos case 'L':
1144 1.1 christos case 'l':
1145 1.1 christos if (place == 'w')
1146 1.1 christos {
1147 1.7 christos char doneany;
1148 1.1 christos p1 = buffer + 2;
1149 1.1 christos NEXTWORD (p1, val, PRINT_INSN_ARG_MEMORY_ERROR);
1150 1.1 christos /* Move the pointer ahead if this point is farther ahead
1151 1.1 christos than the last. */
1152 1.1 christos p = p1 > p ? p1 : p;
1153 1.1 christos if (val == 0)
1154 1.1 christos {
1155 1.1 christos (*info->fprintf_func) (info->stream, "#0");
1156 1.1 christos break;
1157 1.1 christos }
1158 1.1 christos if (*d == 'l')
1159 1.1 christos {
1160 1.1 christos int newval = 0;
1161 1.1 christos
1162 1.1 christos for (regno = 0; regno < 16; ++regno)
1163 1.1 christos if (val & (0x8000 >> regno))
1164 1.1 christos newval |= 1 << regno;
1165 1.1 christos val = newval;
1166 1.1 christos }
1167 1.1 christos val &= 0xffff;
1168 1.1 christos doneany = 0;
1169 1.1 christos for (regno = 0; regno < 16; ++regno)
1170 1.1 christos if (val & (1 << regno))
1171 1.1 christos {
1172 1.1 christos int first_regno;
1173 1.1 christos
1174 1.1 christos if (doneany)
1175 1.1 christos (*info->fprintf_func) (info->stream, "/");
1176 1.1 christos doneany = 1;
1177 1.1 christos (*info->fprintf_func) (info->stream, "%s", reg_names[regno]);
1178 1.1 christos first_regno = regno;
1179 1.1 christos while (val & (1 << (regno + 1)))
1180 1.1 christos ++regno;
1181 1.1 christos if (regno > first_regno)
1182 1.1 christos (*info->fprintf_func) (info->stream, "-%s",
1183 1.1 christos reg_names[regno]);
1184 1.1 christos }
1185 1.1 christos }
1186 1.1 christos else if (place == '3')
1187 1.1 christos {
1188 1.1 christos /* `fmovem' insn. */
1189 1.1 christos char doneany;
1190 1.1 christos
1191 1.1 christos FETCH_ARG (8, val);
1192 1.1 christos if (val == 0)
1193 1.1 christos {
1194 1.1 christos (*info->fprintf_func) (info->stream, "#0");
1195 1.1 christos break;
1196 1.1 christos }
1197 1.1 christos if (*d == 'l')
1198 1.1 christos {
1199 1.1 christos int newval = 0;
1200 1.1 christos
1201 1.1 christos for (regno = 0; regno < 8; ++regno)
1202 1.1 christos if (val & (0x80 >> regno))
1203 1.1 christos newval |= 1 << regno;
1204 1.1 christos val = newval;
1205 1.1 christos }
1206 1.1 christos val &= 0xff;
1207 1.1 christos doneany = 0;
1208 1.1 christos for (regno = 0; regno < 8; ++regno)
1209 1.1 christos if (val & (1 << regno))
1210 1.1 christos {
1211 1.1 christos int first_regno;
1212 1.1 christos if (doneany)
1213 1.1 christos (*info->fprintf_func) (info->stream, "/");
1214 1.1 christos doneany = 1;
1215 1.1 christos (*info->fprintf_func) (info->stream, "%%fp%d", regno);
1216 1.1 christos first_regno = regno;
1217 1.1 christos while (val & (1 << (regno + 1)))
1218 1.1 christos ++regno;
1219 1.1 christos if (regno > first_regno)
1220 1.1 christos (*info->fprintf_func) (info->stream, "-%%fp%d", regno);
1221 1.1 christos }
1222 1.1 christos }
1223 1.1 christos else if (place == '8')
1224 1.1 christos {
1225 1.1 christos FETCH_ARG (3, val);
1226 1.1 christos /* fmoveml for FP status registers. */
1227 1.1 christos (*info->fprintf_func) (info->stream, "%s", fpcr_names[val]);
1228 1.7 christos }
1229 1.1 christos else
1230 1.1 christos return PRINT_INSN_ARG_INVALID_OP_TABLE;
1231 1.1 christos break;
1232 1.1 christos
1233 1.7 christos case 'X':
1234 1.1 christos place = '8';
1235 1.1 christos /* Fall through. */
1236 1.1 christos case 'Y':
1237 1.1 christos case 'Z':
1238 1.1 christos case 'W':
1239 1.1 christos case '0':
1240 1.1 christos case '1':
1241 1.1 christos case '2':
1242 1.1 christos case '3':
1243 1.1 christos {
1244 1.1 christos char *name = 0;
1245 1.1 christos
1246 1.1 christos FETCH_ARG (5, val);
1247 1.1 christos switch (val)
1248 1.1 christos {
1249 1.1 christos case 2: name = "%tt0"; break;
1250 1.1 christos case 3: name = "%tt1"; break;
1251 1.1 christos case 0x10: name = "%tc"; break;
1252 1.1 christos case 0x11: name = "%drp"; break;
1253 1.1 christos case 0x12: name = "%srp"; break;
1254 1.1 christos case 0x13: name = "%crp"; break;
1255 1.1 christos case 0x14: name = "%cal"; break;
1256 1.1 christos case 0x15: name = "%val"; break;
1257 1.1 christos case 0x16: name = "%scc"; break;
1258 1.1 christos case 0x17: name = "%ac"; break;
1259 1.1 christos case 0x18: name = "%psr"; break;
1260 1.1 christos case 0x19: name = "%pcsr"; break;
1261 1.1 christos case 0x1c:
1262 1.1 christos case 0x1d:
1263 1.1 christos {
1264 1.1 christos int break_reg = ((buffer[3] >> 2) & 7);
1265 1.1 christos
1266 1.1 christos (*info->fprintf_func)
1267 1.1 christos (info->stream, val == 0x1c ? "%%bad%d" : "%%bac%d",
1268 1.1 christos break_reg);
1269 1.1 christos }
1270 1.1 christos break;
1271 1.1 christos default:
1272 1.1 christos (*info->fprintf_func) (info->stream, "<mmu register %d>", val);
1273 1.1 christos }
1274 1.1 christos if (name)
1275 1.1 christos (*info->fprintf_func) (info->stream, "%s", name);
1276 1.1 christos }
1277 1.1 christos break;
1278 1.1 christos
1279 1.1 christos case 'f':
1280 1.1 christos {
1281 1.1 christos int fc;
1282 1.1 christos
1283 1.1 christos FETCH_ARG (5, fc);
1284 1.1 christos if (fc == 1)
1285 1.1 christos (*info->fprintf_func) (info->stream, "%%dfc");
1286 1.1 christos else if (fc == 0)
1287 1.1 christos (*info->fprintf_func) (info->stream, "%%sfc");
1288 1.1 christos else
1289 1.1 christos /* xgettext:c-format */
1290 1.1 christos (*info->fprintf_func) (info->stream, _("<function code %d>"), fc);
1291 1.1 christos }
1292 1.1 christos break;
1293 1.1 christos
1294 1.1 christos case 'V':
1295 1.1 christos (*info->fprintf_func) (info->stream, "%%val");
1296 1.1 christos break;
1297 1.1 christos
1298 1.1 christos case 't':
1299 1.1 christos {
1300 1.1 christos int level;
1301 1.1 christos
1302 1.1 christos FETCH_ARG (3, level);
1303 1.1 christos (*info->fprintf_func) (info->stream, "%d", level);
1304 1.1 christos }
1305 1.1 christos break;
1306 1.1 christos
1307 1.1 christos case 'u':
1308 1.1 christos {
1309 1.1 christos short is_upper = 0;
1310 1.1 christos int reg;
1311 1.1 christos
1312 1.1 christos FETCH_ARG (5, reg);
1313 1.1 christos if (reg & 0x10)
1314 1.1 christos {
1315 1.1 christos is_upper = 1;
1316 1.1 christos reg &= 0xf;
1317 1.1 christos }
1318 1.1 christos (*info->fprintf_func) (info->stream, "%s%s",
1319 1.1 christos reg_half_names[reg],
1320 1.1 christos is_upper ? "u" : "l");
1321 1.1 christos }
1322 1.1 christos break;
1323 1.7 christos
1324 1.1 christos default:
1325 1.1 christos return PRINT_INSN_ARG_INVALID_OP_TABLE;
1326 1.1 christos }
1327 1.1 christos
1328 1.1 christos return p - p0;
1329 1.1 christos }
1330 1.7 christos
1331 1.7 christos /* Try to match the current instruction to best and if so, return the
1332 1.1 christos number of bytes consumed from the instruction stream, else zero.
1333 1.1 christos Return -1 on memory error. */
1334 1.1 christos
1335 1.1 christos static int
1336 1.1 christos match_insn_m68k (bfd_vma memaddr,
1337 1.1 christos disassemble_info * info,
1338 1.1 christos const struct m68k_opcode * best)
1339 1.1 christos {
1340 1.1 christos unsigned char *save_p;
1341 1.1 christos unsigned char *p;
1342 1.1 christos const char *d;
1343 1.1 christos const char *args = best->args;
1344 1.1 christos
1345 1.1 christos struct private *priv = (struct private *) info->private_data;
1346 1.1 christos bfd_byte *buffer = priv->the_buffer;
1347 1.1 christos fprintf_ftype save_printer = info->fprintf_func;
1348 1.1 christos void (* save_print_address) (bfd_vma, struct disassemble_info *)
1349 1.1 christos = info->print_address_func;
1350 1.1 christos
1351 1.6 christos if (*args == '.')
1352 1.1 christos args++;
1353 1.1 christos
1354 1.1 christos /* Point at first word of argument data,
1355 1.1 christos and at descriptor for first argument. */
1356 1.1 christos p = buffer + 2;
1357 1.1 christos
1358 1.1 christos /* Figure out how long the fixed-size portion of the instruction is.
1359 1.1 christos The only place this is stored in the opcode table is
1360 1.1 christos in the arguments--look for arguments which specify fields in the 2nd
1361 1.1 christos or 3rd words of the instruction. */
1362 1.1 christos for (d = args; *d; d += 2)
1363 1.1 christos {
1364 1.1 christos /* I don't think it is necessary to be checking d[0] here;
1365 1.1 christos I suspect all this could be moved to the case statement below. */
1366 1.1 christos if (d[0] == '#')
1367 1.1 christos {
1368 1.1 christos if (d[1] == 'l' && p - buffer < 6)
1369 1.1 christos p = buffer + 6;
1370 1.1 christos else if (p - buffer < 4 && d[1] != 'C' && d[1] != '8')
1371 1.1 christos p = buffer + 4;
1372 1.1 christos }
1373 1.1 christos
1374 1.1 christos if ((d[0] == 'L' || d[0] == 'l') && d[1] == 'w' && p - buffer < 4)
1375 1.1 christos p = buffer + 4;
1376 1.1 christos
1377 1.1 christos switch (d[1])
1378 1.1 christos {
1379 1.1 christos case '1':
1380 1.1 christos case '2':
1381 1.1 christos case '3':
1382 1.1 christos case '7':
1383 1.1 christos case '8':
1384 1.1 christos case '9':
1385 1.1 christos case 'i':
1386 1.1 christos if (p - buffer < 4)
1387 1.1 christos p = buffer + 4;
1388 1.1 christos break;
1389 1.1 christos case '4':
1390 1.1 christos case '5':
1391 1.1 christos case '6':
1392 1.1 christos if (p - buffer < 6)
1393 1.1 christos p = buffer + 6;
1394 1.1 christos break;
1395 1.1 christos default:
1396 1.1 christos break;
1397 1.1 christos }
1398 1.1 christos }
1399 1.1 christos
1400 1.1 christos /* pflusha is an exceptions. It takes no arguments but is two words
1401 1.1 christos long. Recognize it by looking at the lower 16 bits of the mask. */
1402 1.1 christos if (p - buffer < 4 && (best->match & 0xFFFF) != 0)
1403 1.1 christos p = buffer + 4;
1404 1.1 christos
1405 1.1 christos /* lpstop is another exception. It takes a one word argument but is
1406 1.1 christos three words long. */
1407 1.1 christos if (p - buffer < 6
1408 1.1 christos && (best->match & 0xffff) == 0xffff
1409 1.1 christos && args[0] == '#'
1410 1.1 christos && args[1] == 'w')
1411 1.1 christos {
1412 1.1 christos /* Copy the one word argument into the usual location for a one
1413 1.1 christos word argument, to simplify printing it. We can get away with
1414 1.1 christos this because we know exactly what the second word is, and we
1415 1.7 christos aren't going to print anything based on it. */
1416 1.7 christos p = buffer + 6;
1417 1.1 christos if (!FETCH_DATA (info, p))
1418 1.1 christos return -1;
1419 1.1 christos buffer[2] = buffer[4];
1420 1.1 christos buffer[3] = buffer[5];
1421 1.7 christos }
1422 1.7 christos
1423 1.1 christos if (!FETCH_DATA (info, p))
1424 1.1 christos return -1;
1425 1.1 christos
1426 1.1 christos save_p = p;
1427 1.1 christos info->print_address_func = dummy_print_address;
1428 1.1 christos info->fprintf_func = (fprintf_ftype) dummy_printer;
1429 1.1 christos
1430 1.1 christos /* We scan the operands twice. The first time we don't print anything,
1431 1.1 christos but look for errors. */
1432 1.1 christos for (d = args; *d; d += 2)
1433 1.1 christos {
1434 1.1 christos int eaten = print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
1435 1.1 christos
1436 1.7 christos if (eaten >= 0)
1437 1.7 christos p += eaten;
1438 1.1 christos else if (eaten == PRINT_INSN_ARG_INVALID_OPERAND
1439 1.1 christos || eaten == PRINT_INSN_ARG_MEMORY_ERROR)
1440 1.1 christos {
1441 1.7 christos info->fprintf_func = save_printer;
1442 1.1 christos info->print_address_func = save_print_address;
1443 1.1 christos return eaten == PRINT_INSN_ARG_MEMORY_ERROR ? -1 : 0;
1444 1.1 christos }
1445 1.1 christos else
1446 1.1 christos {
1447 1.1 christos /* We must restore the print functions before trying to print the
1448 1.1 christos error message. */
1449 1.1 christos info->fprintf_func = save_printer;
1450 1.1 christos info->print_address_func = save_print_address;
1451 1.1 christos info->fprintf_func (info->stream,
1452 1.1 christos /* xgettext:c-format */
1453 1.1 christos _("<internal error in opcode table: %s %s>\n"),
1454 1.1 christos best->name, best->args);
1455 1.1 christos return 2;
1456 1.1 christos }
1457 1.1 christos }
1458 1.1 christos
1459 1.1 christos p = save_p;
1460 1.1 christos info->fprintf_func = save_printer;
1461 1.1 christos info->print_address_func = save_print_address;
1462 1.1 christos
1463 1.1 christos d = args;
1464 1.1 christos
1465 1.1 christos info->fprintf_func (info->stream, "%s", best->name);
1466 1.1 christos
1467 1.1 christos if (*d)
1468 1.1 christos info->fprintf_func (info->stream, " ");
1469 1.1 christos
1470 1.1 christos while (*d)
1471 1.1 christos {
1472 1.1 christos p += print_insn_arg (d, buffer, p, memaddr + (p - buffer), info);
1473 1.1 christos d += 2;
1474 1.1 christos
1475 1.1 christos if (*d && *(d - 2) != 'I' && *d != 'k')
1476 1.1 christos info->fprintf_func (info->stream, ",");
1477 1.1 christos }
1478 1.1 christos
1479 1.1 christos return p - buffer;
1480 1.1 christos }
1481 1.1 christos
1482 1.1 christos /* Try to interpret the instruction at address MEMADDR as one that
1483 1.7 christos can execute on a processor with the features given by ARCH_MASK.
1484 1.7 christos If successful, print the instruction to INFO->STREAM and return
1485 1.1 christos its length in bytes. Return 0 otherwise. Return -1 on memory
1486 1.1 christos error. */
1487 1.1 christos
1488 1.1 christos static int
1489 1.1 christos m68k_scan_mask (bfd_vma memaddr, disassemble_info *info,
1490 1.1 christos unsigned int arch_mask)
1491 1.1 christos {
1492 1.1 christos int i;
1493 1.1 christos const char *d;
1494 1.1 christos static const struct m68k_opcode **opcodes[16];
1495 1.1 christos static int numopcodes[16];
1496 1.1 christos int val;
1497 1.1 christos int major_opcode;
1498 1.1 christos
1499 1.1 christos struct private *priv = (struct private *) info->private_data;
1500 1.1 christos bfd_byte *buffer = priv->the_buffer;
1501 1.1 christos
1502 1.1 christos if (!opcodes[0])
1503 1.1 christos {
1504 1.1 christos /* Speed up the matching by sorting the opcode
1505 1.1 christos table on the upper four bits of the opcode. */
1506 1.1 christos const struct m68k_opcode **opc_pointer[16];
1507 1.1 christos
1508 1.1 christos /* First count how many opcodes are in each of the sixteen buckets. */
1509 1.1 christos for (i = 0; i < m68k_numopcodes; i++)
1510 1.1 christos numopcodes[(m68k_opcodes[i].opcode >> 28) & 15]++;
1511 1.1 christos
1512 1.1 christos /* Then create a sorted table of pointers
1513 1.1 christos that point into the unsorted table. */
1514 1.1 christos opc_pointer[0] = xmalloc (sizeof (struct m68k_opcode *)
1515 1.1 christos * m68k_numopcodes);
1516 1.1 christos opcodes[0] = opc_pointer[0];
1517 1.1 christos
1518 1.1 christos for (i = 1; i < 16; i++)
1519 1.1 christos {
1520 1.1 christos opc_pointer[i] = opc_pointer[i - 1] + numopcodes[i - 1];
1521 1.1 christos opcodes[i] = opc_pointer[i];
1522 1.1 christos }
1523 1.1 christos
1524 1.1 christos for (i = 0; i < m68k_numopcodes; i++)
1525 1.1 christos *opc_pointer[(m68k_opcodes[i].opcode >> 28) & 15]++ = &m68k_opcodes[i];
1526 1.7 christos }
1527 1.7 christos
1528 1.1 christos if (!FETCH_DATA (info, buffer + 2))
1529 1.1 christos return -1;
1530 1.1 christos major_opcode = (buffer[0] >> 4) & 15;
1531 1.1 christos
1532 1.1 christos for (i = 0; i < numopcodes[major_opcode]; i++)
1533 1.1 christos {
1534 1.1 christos const struct m68k_opcode *opc = opcodes[major_opcode][i];
1535 1.1 christos unsigned long opcode = opc->opcode;
1536 1.1 christos unsigned long match = opc->match;
1537 1.1 christos const char *args = opc->args;
1538 1.1 christos
1539 1.1 christos if (*args == '.')
1540 1.1 christos args++;
1541 1.1 christos
1542 1.1 christos if (((0xff & buffer[0] & (match >> 24)) == (0xff & (opcode >> 24)))
1543 1.1 christos && ((0xff & buffer[1] & (match >> 16)) == (0xff & (opcode >> 16)))
1544 1.1 christos /* Only fetch the next two bytes if we need to. */
1545 1.1 christos && (((0xffff & match) == 0)
1546 1.1 christos ||
1547 1.1 christos (FETCH_DATA (info, buffer + 4)
1548 1.1 christos && ((0xff & buffer[2] & (match >> 8)) == (0xff & (opcode >> 8)))
1549 1.1 christos && ((0xff & buffer[3] & match) == (0xff & opcode)))
1550 1.1 christos )
1551 1.1 christos && (opc->arch & arch_mask) != 0)
1552 1.1 christos {
1553 1.1 christos /* Don't use for printout the variants of divul and divsl
1554 1.1 christos that have the same register number in two places.
1555 1.1 christos The more general variants will match instead. */
1556 1.1 christos for (d = args; *d; d += 2)
1557 1.1 christos if (d[1] == 'D')
1558 1.1 christos break;
1559 1.1 christos
1560 1.1 christos /* Don't use for printout the variants of most floating
1561 1.1 christos point coprocessor instructions which use the same
1562 1.1 christos register number in two places, as above. */
1563 1.1 christos if (*d == '\0')
1564 1.1 christos for (d = args; *d; d += 2)
1565 1.1 christos if (d[1] == 't')
1566 1.1 christos break;
1567 1.1 christos
1568 1.1 christos /* Don't match fmovel with more than one register;
1569 1.1 christos wait for fmoveml. */
1570 1.1 christos if (*d == '\0')
1571 1.1 christos {
1572 1.1 christos for (d = args; *d; d += 2)
1573 1.1 christos {
1574 1.1 christos if (d[0] == 's' && d[1] == '8')
1575 1.1 christos {
1576 1.1 christos val = fetch_arg (buffer, d[1], 3, info);
1577 1.1 christos if (val < 0)
1578 1.1 christos return 0;
1579 1.1 christos if ((val & (val - 1)) != 0)
1580 1.1 christos break;
1581 1.1 christos }
1582 1.1 christos }
1583 1.1 christos }
1584 1.1 christos
1585 1.1 christos /* Don't match FPU insns with non-default coprocessor ID. */
1586 1.1 christos if (*d == '\0')
1587 1.1 christos {
1588 1.1 christos for (d = args; *d; d += 2)
1589 1.1 christos {
1590 1.1 christos if (d[0] == 'I')
1591 1.1 christos {
1592 1.1 christos val = fetch_arg (buffer, 'd', 3, info);
1593 1.1 christos if (val != 1)
1594 1.1 christos break;
1595 1.1 christos }
1596 1.1 christos }
1597 1.1 christos }
1598 1.1 christos
1599 1.1 christos if (*d == '\0')
1600 1.1 christos if ((val = match_insn_m68k (memaddr, info, opc)))
1601 1.1 christos return val;
1602 1.1 christos }
1603 1.6 christos }
1604 1.1 christos return 0;
1605 1.1 christos }
1606 1.1 christos
1607 1.1 christos /* Print the m68k instruction at address MEMADDR in debugged memory,
1608 1.1 christos on INFO->STREAM. Returns length of the instruction, in bytes. */
1609 1.1 christos
1610 1.1 christos int
1611 1.1 christos print_insn_m68k (bfd_vma memaddr, disassemble_info *info)
1612 1.1 christos {
1613 1.1 christos unsigned int arch_mask;
1614 1.1 christos struct private priv;
1615 1.1 christos int val;
1616 1.1 christos
1617 1.1 christos bfd_byte *buffer = priv.the_buffer;
1618 1.1 christos
1619 1.1 christos info->private_data = & priv;
1620 1.1 christos /* Tell objdump to use two bytes per chunk
1621 1.1 christos and six bytes per line for displaying raw data. */
1622 1.1 christos info->bytes_per_chunk = 2;
1623 1.1 christos info->bytes_per_line = 6;
1624 1.1 christos info->display_endian = BFD_ENDIAN_BIG;
1625 1.1 christos priv.max_fetched = priv.the_buffer;
1626 1.1 christos priv.insn_start = memaddr;
1627 1.1 christos
1628 1.1 christos arch_mask = bfd_m68k_mach_to_features (info->mach);
1629 1.1 christos if (!arch_mask)
1630 1.1 christos {
1631 1.1 christos /* First try printing an m680x0 instruction. Try printing a Coldfire
1632 1.7 christos one if that fails. */
1633 1.1 christos val = m68k_scan_mask (memaddr, info, m68k_mask);
1634 1.1 christos if (val <= 0)
1635 1.1 christos val = m68k_scan_mask (memaddr, info, mcf_mask);
1636 1.1 christos }
1637 1.1 christos else
1638 1.1 christos {
1639 1.1 christos val = m68k_scan_mask (memaddr, info, arch_mask);
1640 1.1 christos }
1641 1.1 christos
1642 1.1 christos if (val == 0)
1643 1.1 christos /* Handle undefined instructions. */
1644 1.1 christos info->fprintf_func (info->stream, ".short 0x%04x", (buffer[0] << 8) + buffer[1]);
1645 1.1 christos
1646 return val ? val : 2;
1647 }
1648