ubsan: m32r: left shift of negative value
[deliverable/binutils-gdb.git] / opcodes / ns32k-dis.c
CommitLineData
252b5132 1/* Print National Semiconductor 32000 instructions.
b3adc24a 2 Copyright (C) 1986-2020 Free Software Foundation, Inc.
252b5132 3
9b201bb5 4 This file is part of the GNU opcodes library.
252b5132 5
9b201bb5 6 This library is free software; you can redistribute it and/or modify
47b0e7ad 7 it under the terms of the GNU General Public License as published by
9b201bb5
NC
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
252b5132 10
9b201bb5
NC
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
252b5132 15
47b0e7ad
NC
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
252b5132 20
252b5132 21#include "sysdep.h"
3db64b00 22#include "bfd.h"
88c1242d 23#include "disassemble.h"
252b5132
RH
24#if !defined(const) && !defined(__STDC__)
25#define const
26#endif
27#include "opcode/ns32k.h"
28#include "opintl.h"
29
30static disassemble_info *dis_info;
31
47b0e7ad
NC
32/* Hacks to get it to compile <= READ THESE AS FIXES NEEDED. */
33#define INVALID_FLOAT(val, size) invalid_float ((bfd_byte *) val, size)
34
35static long
36read_memory_integer (unsigned char * addr, int nr)
252b5132
RH
37{
38 long val;
39 int i;
47b0e7ad
NC
40
41 for (val = 0, i = nr - 1; i >= 0; i--)
42 {
43 val = (val << 8);
44 val |= (0xff & *(addr + i));
45 }
252b5132
RH
46 return val;
47}
48
49/* 32000 instructions are never longer than this. */
50#define MAXLEN 62
51
252b5132
RH
52#include <setjmp.h>
53
54struct private
55{
56 /* Points to first byte not fetched. */
57 bfd_byte *max_fetched;
58 bfd_byte the_buffer[MAXLEN];
59 bfd_vma insn_start;
8df14d78 60 OPCODES_SIGJMP_BUF bailout;
252b5132
RH
61};
62
63
64/* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
65 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
66 on error. */
67#define FETCH_DATA(info, addr) \
68 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
69 ? 1 : fetch_data ((info), (addr)))
70
71static int
47b0e7ad 72fetch_data (struct disassemble_info *info, bfd_byte *addr)
252b5132
RH
73{
74 int status;
47b0e7ad 75 struct private *priv = (struct private *) info->private_data;
252b5132
RH
76 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
77
78 status = (*info->read_memory_func) (start,
79 priv->max_fetched,
80 addr - priv->max_fetched,
81 info);
82 if (status != 0)
83 {
84 (*info->memory_error_func) (status, start, info);
8df14d78 85 OPCODES_SIGLONGJMP (priv->bailout, 1);
252b5132
RH
86 }
87 else
88 priv->max_fetched = addr;
89 return 1;
90}
47b0e7ad 91
252b5132
RH
92/* Number of elements in the opcode table. */
93#define NOPCODES (sizeof ns32k_opcodes / sizeof ns32k_opcodes[0])
94
95#define NEXT_IS_ADDR '|'
96
97\f
47b0e7ad
NC
98struct ns32k_option
99{
100 char *pattern; /* The option itself. */
101 unsigned long value; /* Binary value of the option. */
102 unsigned long match; /* These bits must match. */
252b5132
RH
103};
104
105\f
47b0e7ad 106static const struct ns32k_option opt_u[]= /* Restore, exit. */
252b5132
RH
107{
108 { "r0", 0x80, 0x80 },
109 { "r1", 0x40, 0x40 },
110 { "r2", 0x20, 0x20 },
111 { "r3", 0x10, 0x10 },
112 { "r4", 0x08, 0x08 },
113 { "r5", 0x04, 0x04 },
114 { "r6", 0x02, 0x02 },
115 { "r7", 0x01, 0x01 },
116 { 0 , 0x00, 0x00 }
117};
118
47b0e7ad 119static const struct ns32k_option opt_U[]= /* Save, enter. */
252b5132
RH
120{
121 { "r0", 0x01, 0x01 },
122 { "r1", 0x02, 0x02 },
123 { "r2", 0x04, 0x04 },
124 { "r3", 0x08, 0x08 },
125 { "r4", 0x10, 0x10 },
126 { "r5", 0x20, 0x20 },
127 { "r6", 0x40, 0x40 },
128 { "r7", 0x80, 0x80 },
129 { 0 , 0x00, 0x00 }
130};
131
47b0e7ad 132static const struct ns32k_option opt_O[]= /* Setcfg. */
252b5132
RH
133{
134 { "c", 0x8, 0x8 },
135 { "m", 0x4, 0x4 },
136 { "f", 0x2, 0x2 },
137 { "i", 0x1, 0x1 },
138 { 0 , 0x0, 0x0 }
139};
140
47b0e7ad 141static const struct ns32k_option opt_C[]= /* Cinv. */
252b5132
RH
142{
143 { "a", 0x4, 0x4 },
144 { "i", 0x2, 0x2 },
145 { "d", 0x1, 0x1 },
146 { 0 , 0x0, 0x0 }
147};
148
47b0e7ad 149static const struct ns32k_option opt_S[]= /* String inst. */
252b5132
RH
150{
151 { "b", 0x1, 0x1 },
152 { "u", 0x6, 0x6 },
153 { "w", 0x2, 0x2 },
154 { 0 , 0x0, 0x0 }
155};
156
47b0e7ad 157static const struct ns32k_option list_P532[]= /* Lpr spr. */
252b5132
RH
158{
159 { "us", 0x0, 0xf },
160 { "dcr", 0x1, 0xf },
161 { "bpc", 0x2, 0xf },
162 { "dsr", 0x3, 0xf },
163 { "car", 0x4, 0xf },
164 { "fp", 0x8, 0xf },
165 { "sp", 0x9, 0xf },
166 { "sb", 0xa, 0xf },
167 { "usp", 0xb, 0xf },
168 { "cfg", 0xc, 0xf },
169 { "psr", 0xd, 0xf },
170 { "intbase", 0xe, 0xf },
171 { "mod", 0xf, 0xf },
172 { 0 , 0x00, 0xf }
173};
174
47b0e7ad 175static const struct ns32k_option list_M532[]= /* Lmr smr. */
252b5132
RH
176{
177 { "mcr", 0x9, 0xf },
178 { "msr", 0xa, 0xf },
179 { "tear", 0xb, 0xf },
180 { "ptb0", 0xc, 0xf },
181 { "ptb1", 0xd, 0xf },
182 { "ivar0", 0xe, 0xf },
183 { "ivar1", 0xf, 0xf },
184 { 0 , 0x0, 0xf }
185};
186
47b0e7ad 187static const struct ns32k_option list_P032[]= /* Lpr spr. */
252b5132
RH
188{
189 { "upsr", 0x0, 0xf },
190 { "fp", 0x8, 0xf },
191 { "sp", 0x9, 0xf },
192 { "sb", 0xa, 0xf },
193 { "psr", 0xb, 0xf },
194 { "intbase", 0xe, 0xf },
195 { "mod", 0xf, 0xf },
196 { 0 , 0x0, 0xf }
197};
198
47b0e7ad 199static const struct ns32k_option list_M032[]= /* Lmr smr. */
252b5132
RH
200{
201 { "bpr0", 0x0, 0xf },
202 { "bpr1", 0x1, 0xf },
203 { "pf0", 0x4, 0xf },
204 { "pf1", 0x5, 0xf },
205 { "sc", 0x8, 0xf },
206 { "msr", 0xa, 0xf },
207 { "bcnt", 0xb, 0xf },
208 { "ptb0", 0xc, 0xf },
209 { "ptb1", 0xd, 0xf },
210 { "eia", 0xf, 0xf },
211 { 0 , 0x0, 0xf }
212};
213
214
47b0e7ad
NC
215/* Figure out which options are present. */
216
252b5132 217static void
47b0e7ad 218optlist (int options, const struct ns32k_option * optionP, char * result)
252b5132 219{
47b0e7ad
NC
220 if (options == 0)
221 {
222 sprintf (result, "[]");
223 return;
252b5132 224 }
47b0e7ad
NC
225
226 sprintf (result, "[");
227
228 for (; (options != 0) && optionP->pattern; optionP++)
229 {
230 if ((options & optionP->match) == optionP->value)
231 {
232 /* We found a match, update result and options. */
233 strcat (result, optionP->pattern);
234 options &= ~optionP->value;
235 if (options != 0) /* More options to come. */
236 strcat (result, ",");
252b5132
RH
237 }
238 }
252b5132 239
47b0e7ad
NC
240 if (options != 0)
241 strcat (result, "undefined");
242
243 strcat (result, "]");
252b5132
RH
244}
245
246static void
47b0e7ad 247list_search (int reg_value, const struct ns32k_option *optionP, char *result)
252b5132 248{
47b0e7ad
NC
249 for (; optionP->pattern; optionP++)
250 {
251 if ((reg_value & optionP->match) == optionP->value)
252 {
253 sprintf (result, "%s", optionP->pattern);
254 return;
252b5132
RH
255 }
256 }
47b0e7ad 257 sprintf (result, "undefined");
252b5132
RH
258}
259\f
47b0e7ad 260/* Extract "count" bits starting "offset" bits into buffer. */
252b5132
RH
261
262static int
47b0e7ad 263bit_extract (bfd_byte *buffer, int offset, int count)
252b5132 264{
fb4cb4e2
AM
265 unsigned int result;
266 unsigned int bit;
252b5132 267
d1e304bc
NC
268 if (offset < 0 || count < 0)
269 return 0;
252b5132
RH
270 buffer += offset >> 3;
271 offset &= 7;
272 bit = 1;
273 result = 0;
274 while (count--)
275 {
47b0e7ad 276 FETCH_DATA (dis_info, buffer + 1);
252b5132
RH
277 if ((*buffer & (1 << offset)))
278 result |= bit;
279 if (++offset == 8)
280 {
281 offset = 0;
282 buffer++;
283 }
284 bit <<= 1;
285 }
286 return result;
287}
288
47b0e7ad
NC
289/* Like bit extract but the buffer is valid and doen't need to be fetched. */
290
252b5132 291static int
47b0e7ad 292bit_extract_simple (bfd_byte *buffer, int offset, int count)
252b5132 293{
fb4cb4e2
AM
294 unsigned int result;
295 unsigned int bit;
252b5132 296
d1e304bc
NC
297 if (offset < 0 || count < 0)
298 return 0;
252b5132
RH
299 buffer += offset >> 3;
300 offset &= 7;
301 bit = 1;
302 result = 0;
303 while (count--)
304 {
305 if ((*buffer & (1 << offset)))
306 result |= bit;
307 if (++offset == 8)
308 {
309 offset = 0;
310 buffer++;
311 }
312 bit <<= 1;
313 }
314 return result;
315}
316
317static void
47b0e7ad 318bit_copy (bfd_byte *buffer, int offset, int count, char *to)
252b5132 319{
d1e304bc
NC
320 if (offset < 0 || count < 0)
321 return;
47b0e7ad 322 for (; count > 8; count -= 8, to++, offset += 8)
252b5132
RH
323 *to = bit_extract (buffer, offset, 8);
324 *to = bit_extract (buffer, offset, count);
325}
326
252b5132 327static int
fb4cb4e2 328sign_extend (unsigned int value, unsigned int bits)
252b5132 329{
5afa80e9
AM
330 unsigned int sign = 1u << (bits - 1);
331 return ((value & (sign + sign - 1)) ^ sign) - sign;
252b5132
RH
332}
333
334static void
47b0e7ad 335flip_bytes (char *ptr, int count)
252b5132
RH
336{
337 char tmp;
338
339 while (count > 0)
340 {
341 tmp = ptr[0];
47b0e7ad
NC
342 ptr[0] = ptr[count - 1];
343 ptr[count - 1] = tmp;
252b5132
RH
344 ptr++;
345 count -= 2;
346 }
347}
348\f
349/* Given a character C, does it represent a general addressing mode? */
350#define Is_gen(c) \
351 ((c) == 'F' || (c) == 'L' || (c) == 'B' \
352 || (c) == 'W' || (c) == 'D' || (c) == 'A' || (c) == 'I' || (c) == 'Z')
353
354/* Adressing modes. */
47b0e7ad
NC
355#define Adrmod_index_byte 0x1c
356#define Adrmod_index_word 0x1d
357#define Adrmod_index_doubleword 0x1e
358#define Adrmod_index_quadword 0x1f
252b5132
RH
359
360/* Is MODE an indexed addressing mode? */
361#define Adrmod_is_index(mode) \
47b0e7ad 362 ( mode == Adrmod_index_byte \
252b5132
RH
363 || mode == Adrmod_index_word \
364 || mode == Adrmod_index_doubleword \
365 || mode == Adrmod_index_quadword)
366
367\f
47b0e7ad
NC
368static int
369get_displacement (bfd_byte *buffer, int *aoffsetp)
252b5132 370{
47b0e7ad
NC
371 int Ivalue;
372 short Ivalue2;
252b5132 373
47b0e7ad
NC
374 Ivalue = bit_extract (buffer, *aoffsetp, 8);
375 switch (Ivalue & 0xc0)
252b5132 376 {
47b0e7ad
NC
377 case 0x00:
378 case 0x40:
379 Ivalue = sign_extend (Ivalue, 7);
380 *aoffsetp += 8;
381 break;
382 case 0x80:
383 Ivalue2 = bit_extract (buffer, *aoffsetp, 16);
384 flip_bytes ((char *) & Ivalue2, 2);
385 Ivalue = sign_extend (Ivalue2, 14);
386 *aoffsetp += 16;
387 break;
388 case 0xc0:
389 Ivalue = bit_extract (buffer, *aoffsetp, 32);
390 flip_bytes ((char *) & Ivalue, 4);
391 Ivalue = sign_extend (Ivalue, 30);
392 *aoffsetp += 32;
393 break;
394 }
395 return Ivalue;
396}
252b5132 397
47b0e7ad
NC
398#if 1 /* A version that should work on ns32k f's&d's on any machine. */
399static int
400invalid_float (bfd_byte *p, int len)
401{
402 int val;
403
404 if (len == 4)
405 val = (bit_extract_simple (p, 23, 8)/*exponent*/ == 0xff
406 || (bit_extract_simple (p, 23, 8)/*exponent*/ == 0
407 && bit_extract_simple (p, 0, 23)/*mantisa*/ != 0));
408 else if (len == 8)
409 val = (bit_extract_simple (p, 52, 11)/*exponent*/ == 0x7ff
410 || (bit_extract_simple (p, 52, 11)/*exponent*/ == 0
411 && (bit_extract_simple (p, 0, 32)/*low mantisa*/ != 0
412 || bit_extract_simple (p, 32, 20)/*high mantisa*/ != 0)));
413 else
414 val = 1;
415 return (val);
416}
417#else
418/* Assumes the bytes have been swapped to local order. */
419typedef union
43e65147 420{
47b0e7ad
NC
421 double d;
422 float f;
423 struct { unsigned m:23, e:8, :1;} sf;
424 struct { unsigned lm; unsigned m:20, e:11, :1;} sd;
425} float_type_u;
252b5132 426
47b0e7ad
NC
427static int
428invalid_float (float_type_u *p, int len)
429{
430 int val;
252b5132 431
47b0e7ad
NC
432 if (len == sizeof (float))
433 val = (p->sf.e == 0xff
434 || (p->sf.e == 0 && p->sf.m != 0));
435 else if (len == sizeof (double))
436 val = (p->sd.e == 0x7ff
437 || (p->sd.e == 0 && (p->sd.m != 0 || p->sd.lm != 0)));
438 else
439 val = 1;
440 return val;
252b5132 441}
47b0e7ad 442#endif
252b5132
RH
443
444/* Print an instruction operand of category given by d. IOFFSET is
445 the bit position below which small (<1 byte) parts of the operand can
446 be found (usually in the basic instruction, but for indexed
447 addressing it can be in the index byte). AOFFSETP is a pointer to the
448 bit position of the addressing extension. BUFFER contains the
449 instruction. ADDR is where BUFFER was read from. Put the disassembled
450 version of the operand in RESULT. INDEX_OFFSET is the bit position
451 of the index byte (it contains garbage if this operand is not a
452 general operand using scaled indexed addressing mode). */
453
454static int
47b0e7ad
NC
455print_insn_arg (int d,
456 int ioffset,
457 int *aoffsetp,
458 bfd_byte *buffer,
459 bfd_vma addr,
460 char *result,
461 int index_offset)
252b5132 462{
47b0e7ad
NC
463 union
464 {
6a51a8a8
AM
465 float f;
466 double d;
467 int i[2];
468 } value;
252b5132 469 int Ivalue;
6a51a8a8 470 int addr_mode;
252b5132 471 int disp1, disp2;
252b5132
RH
472 int size;
473
474 switch (d)
475 {
476 case 'f':
47b0e7ad 477 /* A "gen" operand but 5 bits from the end of instruction. */
252b5132 478 ioffset -= 5;
1a0670f3 479 /* Fall through. */
252b5132
RH
480 case 'Z':
481 case 'F':
482 case 'L':
483 case 'I':
484 case 'B':
485 case 'W':
486 case 'D':
487 case 'A':
47b0e7ad 488 addr_mode = bit_extract (buffer, ioffset - 5, 5);
252b5132
RH
489 ioffset -= 5;
490 switch (addr_mode)
491 {
492 case 0x0: case 0x1: case 0x2: case 0x3:
493 case 0x4: case 0x5: case 0x6: case 0x7:
47b0e7ad 494 /* Register mode R0 -- R7. */
252b5132
RH
495 switch (d)
496 {
497 case 'F':
498 case 'L':
499 case 'Z':
500 sprintf (result, "f%d", addr_mode);
501 break;
502 default:
503 sprintf (result, "r%d", addr_mode);
504 }
505 break;
506 case 0x8: case 0x9: case 0xa: case 0xb:
507 case 0xc: case 0xd: case 0xe: case 0xf:
47b0e7ad 508 /* Register relative disp(R0 -- R7). */
252b5132
RH
509 disp1 = get_displacement (buffer, aoffsetp);
510 sprintf (result, "%d(r%d)", disp1, addr_mode & 7);
511 break;
512 case 0x10:
513 case 0x11:
514 case 0x12:
47b0e7ad 515 /* Memory relative disp2(disp1(FP, SP, SB)). */
252b5132
RH
516 disp1 = get_displacement (buffer, aoffsetp);
517 disp2 = get_displacement (buffer, aoffsetp);
518 sprintf (result, "%d(%d(%s))", disp2, disp1,
47b0e7ad 519 addr_mode == 0x10 ? "fp" : addr_mode == 0x11 ? "sp" : "sb");
252b5132
RH
520 break;
521 case 0x13:
47b0e7ad 522 /* Reserved. */
252b5132
RH
523 sprintf (result, "reserved");
524 break;
525 case 0x14:
47b0e7ad 526 /* Immediate. */
252b5132
RH
527 switch (d)
528 {
47b0e7ad
NC
529 case 'I':
530 case 'Z':
531 case 'A':
252b5132 532 /* I and Z are output operands and can`t be immediate
47b0e7ad
NC
533 A is an address and we can`t have the address of
534 an immediate either. We don't know how much to increase
535 aoffsetp by since whatever generated this is broken
536 anyway! */
252b5132
RH
537 sprintf (result, _("$<undefined>"));
538 break;
539 case 'B':
540 Ivalue = bit_extract (buffer, *aoffsetp, 8);
541 Ivalue = sign_extend (Ivalue, 8);
542 *aoffsetp += 8;
543 sprintf (result, "$%d", Ivalue);
544 break;
545 case 'W':
546 Ivalue = bit_extract (buffer, *aoffsetp, 16);
fc05c67f 547 flip_bytes ((char *) & Ivalue, 2);
252b5132
RH
548 *aoffsetp += 16;
549 Ivalue = sign_extend (Ivalue, 16);
550 sprintf (result, "$%d", Ivalue);
551 break;
552 case 'D':
553 Ivalue = bit_extract (buffer, *aoffsetp, 32);
fc05c67f 554 flip_bytes ((char *) & Ivalue, 4);
252b5132
RH
555 *aoffsetp += 32;
556 sprintf (result, "$%d", Ivalue);
557 break;
558 case 'F':
6a51a8a8
AM
559 bit_copy (buffer, *aoffsetp, 32, (char *) &value.f);
560 flip_bytes ((char *) &value.f, 4);
252b5132 561 *aoffsetp += 32;
6a51a8a8
AM
562 if (INVALID_FLOAT (&value.f, 4))
563 sprintf (result, "<<invalid float 0x%.8x>>", value.i[0]);
47b0e7ad 564 else /* Assume host has ieee float. */
6a51a8a8 565 sprintf (result, "$%g", value.f);
252b5132
RH
566 break;
567 case 'L':
6a51a8a8
AM
568 bit_copy (buffer, *aoffsetp, 64, (char *) &value.d);
569 flip_bytes ((char *) &value.d, 8);
252b5132 570 *aoffsetp += 64;
6a51a8a8
AM
571 if (INVALID_FLOAT (&value.d, 8))
572 sprintf (result, "<<invalid double 0x%.8x%.8x>>",
573 value.i[1], value.i[0]);
47b0e7ad 574 else /* Assume host has ieee float. */
6a51a8a8 575 sprintf (result, "$%g", value.d);
252b5132
RH
576 break;
577 }
578 break;
579 case 0x15:
47b0e7ad 580 /* Absolute @disp. */
252b5132
RH
581 disp1 = get_displacement (buffer, aoffsetp);
582 sprintf (result, "@|%d|", disp1);
583 break;
584 case 0x16:
47b0e7ad 585 /* External EXT(disp1) + disp2 (Mod table stuff). */
252b5132
RH
586 disp1 = get_displacement (buffer, aoffsetp);
587 disp2 = get_displacement (buffer, aoffsetp);
588 sprintf (result, "EXT(%d) + %d", disp1, disp2);
589 break;
590 case 0x17:
47b0e7ad 591 /* Top of stack tos. */
252b5132
RH
592 sprintf (result, "tos");
593 break;
594 case 0x18:
47b0e7ad 595 /* Memory space disp(FP). */
252b5132
RH
596 disp1 = get_displacement (buffer, aoffsetp);
597 sprintf (result, "%d(fp)", disp1);
598 break;
599 case 0x19:
47b0e7ad 600 /* Memory space disp(SP). */
252b5132
RH
601 disp1 = get_displacement (buffer, aoffsetp);
602 sprintf (result, "%d(sp)", disp1);
603 break;
604 case 0x1a:
47b0e7ad 605 /* Memory space disp(SB). */
252b5132
RH
606 disp1 = get_displacement (buffer, aoffsetp);
607 sprintf (result, "%d(sb)", disp1);
608 break;
609 case 0x1b:
47b0e7ad 610 /* Memory space disp(PC). */
252b5132
RH
611 disp1 = get_displacement (buffer, aoffsetp);
612 *result++ = NEXT_IS_ADDR;
613 sprintf_vma (result, addr + disp1);
614 result += strlen (result);
615 *result++ = NEXT_IS_ADDR;
616 *result = '\0';
617 break;
618 case 0x1c:
619 case 0x1d:
620 case 0x1e:
621 case 0x1f:
252b5132 622 {
91d6fa6a 623 int bit_index;
252b5132
RH
624 static const char *ind = "bwdq";
625 char *off;
43e65147 626
91d6fa6a
NC
627 /* Scaled index basemode[R0 -- R7:B,W,D,Q]. */
628 bit_index = bit_extract (buffer, index_offset - 8, 3);
629 print_insn_arg (d, index_offset, aoffsetp, buffer, addr,
630 result, 0);
252b5132 631 off = result + strlen (result);
91d6fa6a 632 sprintf (off, "[r%d:%c]", bit_index, ind[addr_mode & 3]);
252b5132
RH
633 }
634 break;
635 }
636 break;
637 case 'H':
638 case 'q':
639 Ivalue = bit_extract (buffer, ioffset-4, 4);
640 Ivalue = sign_extend (Ivalue, 4);
641 sprintf (result, "%d", Ivalue);
642 ioffset -= 4;
643 break;
644 case 'r':
645 Ivalue = bit_extract (buffer, ioffset-3, 3);
646 sprintf (result, "r%d", Ivalue&7);
647 ioffset -= 3;
648 break;
649 case 'd':
650 sprintf (result, "%d", get_displacement (buffer, aoffsetp));
651 break;
652 case 'b':
653 Ivalue = get_displacement (buffer, aoffsetp);
47b0e7ad
NC
654 /* Warning!! HACK ALERT!
655 Operand type 'b' is only used by the cmp{b,w,d} and
656 movm{b,w,d} instructions; we need to know whether
657 it's a `b' or `w' or `d' instruction; and for both
658 cmpm and movm it's stored at the same place so we
659 just grab two bits of the opcode and look at it... */
252b5132 660 size = bit_extract(buffer, ioffset-6, 2);
47b0e7ad 661 if (size == 0) /* 00 => b. */
252b5132 662 size = 1;
47b0e7ad 663 else if (size == 1) /* 01 => w. */
252b5132
RH
664 size = 2;
665 else
47b0e7ad 666 size = 4; /* 11 => d. */
252b5132
RH
667
668 sprintf (result, "%d", (Ivalue / size) + 1);
669 break;
670 case 'p':
671 *result++ = NEXT_IS_ADDR;
672 sprintf_vma (result, addr + get_displacement (buffer, aoffsetp));
673 result += strlen (result);
674 *result++ = NEXT_IS_ADDR;
675 *result = '\0';
676 break;
677 case 'i':
678 Ivalue = bit_extract (buffer, *aoffsetp, 8);
679 *aoffsetp += 8;
680 sprintf (result, "0x%x", Ivalue);
681 break;
682 case 'u':
683 Ivalue = bit_extract (buffer, *aoffsetp, 8);
47b0e7ad 684 optlist (Ivalue, opt_u, result);
252b5132
RH
685 *aoffsetp += 8;
686 break;
687 case 'U':
47b0e7ad
NC
688 Ivalue = bit_extract (buffer, *aoffsetp, 8);
689 optlist (Ivalue, opt_U, result);
252b5132
RH
690 *aoffsetp += 8;
691 break;
692 case 'O':
47b0e7ad
NC
693 Ivalue = bit_extract (buffer, ioffset - 9, 9);
694 optlist (Ivalue, opt_O, result);
252b5132
RH
695 ioffset -= 9;
696 break;
697 case 'C':
47b0e7ad
NC
698 Ivalue = bit_extract (buffer, ioffset - 4, 4);
699 optlist (Ivalue, opt_C, result);
252b5132
RH
700 ioffset -= 4;
701 break;
702 case 'S':
47b0e7ad
NC
703 Ivalue = bit_extract (buffer, ioffset - 8, 8);
704 optlist (Ivalue, opt_S, result);
252b5132
RH
705 ioffset -= 8;
706 break;
707 case 'M':
47b0e7ad
NC
708 Ivalue = bit_extract (buffer, ioffset - 4, 4);
709 list_search (Ivalue, 0 ? list_M032 : list_M532, result);
252b5132
RH
710 ioffset -= 4;
711 break;
712 case 'P':
47b0e7ad
NC
713 Ivalue = bit_extract (buffer, ioffset - 4, 4);
714 list_search (Ivalue, 0 ? list_P032 : list_P532, result);
252b5132
RH
715 ioffset -= 4;
716 break;
717 case 'g':
47b0e7ad
NC
718 Ivalue = bit_extract (buffer, *aoffsetp, 3);
719 sprintf (result, "%d", Ivalue);
252b5132
RH
720 *aoffsetp += 3;
721 break;
722 case 'G':
723 Ivalue = bit_extract(buffer, *aoffsetp, 5);
47b0e7ad 724 sprintf (result, "%d", Ivalue + 1);
252b5132
RH
725 *aoffsetp += 5;
726 break;
727 }
728 return ioffset;
729}
730
47b0e7ad
NC
731\f
732/* Print the 32000 instruction at address MEMADDR in debugged memory,
733 on STREAM. Returns length of the instruction, in bytes. */
734
735int
736print_insn_ns32k (bfd_vma memaddr, disassemble_info *info)
252b5132 737{
47b0e7ad
NC
738 unsigned int i;
739 const char *d;
740 unsigned short first_word;
741 int ioffset; /* Bits into instruction. */
742 int aoffset; /* Bits into arguments. */
743 char arg_bufs[MAX_ARGS+1][ARG_LEN];
744 int argnum;
745 int maxarg;
746 struct private priv;
747 bfd_byte *buffer = priv.the_buffer;
748 dis_info = info;
252b5132 749
47b0e7ad
NC
750 info->private_data = & priv;
751 priv.max_fetched = priv.the_buffer;
752 priv.insn_start = memaddr;
8df14d78 753 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
47b0e7ad
NC
754 /* Error return. */
755 return -1;
756
757 /* Look for 8bit opcodes first. Other wise, fetching two bytes could take
758 us over the end of accessible data unnecessarilly. */
759 FETCH_DATA (info, buffer + 1);
760 for (i = 0; i < NOPCODES; i++)
761 if (ns32k_opcodes[i].opcode_id_size <= 8
762 && ((buffer[0]
763 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
764 == ns32k_opcodes[i].opcode_seed))
252b5132 765 break;
47b0e7ad
NC
766 if (i == NOPCODES)
767 {
768 /* Maybe it is 9 to 16 bits big. */
769 FETCH_DATA (info, buffer + 2);
770 first_word = read_memory_integer(buffer, 2);
771
772 for (i = 0; i < NOPCODES; i++)
773 if ((first_word
774 & (((unsigned long) 1 << ns32k_opcodes[i].opcode_id_size) - 1))
775 == ns32k_opcodes[i].opcode_seed)
776 break;
777
778 /* Handle undefined instructions. */
779 if (i == NOPCODES)
780 {
781 (*dis_info->fprintf_func)(dis_info->stream, "0%o", buffer[0]);
782 return 1;
783 }
252b5132 784 }
252b5132 785
47b0e7ad 786 (*dis_info->fprintf_func)(dis_info->stream, "%s", ns32k_opcodes[i].name);
252b5132 787
47b0e7ad
NC
788 ioffset = ns32k_opcodes[i].opcode_size;
789 aoffset = ns32k_opcodes[i].opcode_size;
790 d = ns32k_opcodes[i].operands;
252b5132 791
47b0e7ad
NC
792 if (*d)
793 {
794 /* Offset in bits of the first thing beyond each index byte.
795 Element 0 is for operand A and element 1 is for operand B.
796 The rest are irrelevant, but we put them here so we don't
797 index outside the array. */
798 int index_offset[MAX_ARGS];
799
800 /* 0 for operand A, 1 for operand B, greater for other args. */
801 int whicharg = 0;
43e65147 802
47b0e7ad
NC
803 (*dis_info->fprintf_func)(dis_info->stream, "\t");
804
805 maxarg = 0;
806
807 /* First we have to find and keep track of the index bytes,
808 if we are using scaled indexed addressing mode, since the index
809 bytes occur right after the basic instruction, not as part
810 of the addressing extension. */
811 if (Is_gen(d[1]))
812 {
813 int addr_mode = bit_extract (buffer, ioffset - 5, 5);
814
815 if (Adrmod_is_index (addr_mode))
816 {
817 aoffset += 8;
818 index_offset[0] = aoffset;
819 }
820 }
821
822 if (d[2] && Is_gen(d[3]))
823 {
824 int addr_mode = bit_extract (buffer, ioffset - 10, 5);
825
826 if (Adrmod_is_index (addr_mode))
827 {
828 aoffset += 8;
829 index_offset[1] = aoffset;
830 }
831 }
832
833 while (*d)
834 {
835 argnum = *d - '1';
836 d++;
837 if (argnum > maxarg && argnum < MAX_ARGS)
838 maxarg = argnum;
839 ioffset = print_insn_arg (*d, ioffset, &aoffset, buffer,
840 memaddr, arg_bufs[argnum],
841 index_offset[whicharg]);
842 d++;
d1e304bc
NC
843 if (whicharg++ >= 1)
844 break;
47b0e7ad 845 }
d1e304bc 846
47b0e7ad
NC
847 for (argnum = 0; argnum <= maxarg; argnum++)
848 {
849 bfd_vma addr;
850 char *ch;
851
852 for (ch = arg_bufs[argnum]; *ch;)
853 {
854 if (*ch == NEXT_IS_ADDR)
855 {
856 ++ch;
857 addr = bfd_scan_vma (ch, NULL, 16);
858 (*dis_info->print_address_func) (addr, dis_info);
859 while (*ch && *ch != NEXT_IS_ADDR)
860 ++ch;
861 if (*ch)
862 ++ch;
863 }
864 else
865 (*dis_info->fprintf_func)(dis_info->stream, "%c", *ch++);
866 }
867 if (argnum < maxarg)
868 (*dis_info->fprintf_func)(dis_info->stream, ", ");
869 }
870 }
871 return aoffset / 8;
252b5132 872}
This page took 1.186597 seconds and 4 git commands to generate.