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