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