1 1.1 christos /* Disassembly routines for TMS320C54X architecture 2 1.1.1.10 christos Copyright (C) 1999-2025 Free Software Foundation, Inc. 3 1.1 christos Contributed by Timothy Wall (twall (at) cygnus.com) 4 1.1 christos 5 1.1 christos This file is part of the GNU opcodes library. 6 1.1 christos 7 1.1 christos This library is free software; you can redistribute it and/or modify 8 1.1 christos it under the terms of the GNU General Public License as published by 9 1.1 christos the Free Software Foundation; either version 3, or (at your option) 10 1.1 christos any later version. 11 1.1 christos 12 1.1 christos It is distributed in the hope that it will be useful, but WITHOUT 13 1.1 christos ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 14 1.1 christos or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 15 1.1 christos License for more details. 16 1.1 christos 17 1.1 christos You should have received a copy of the GNU General Public License 18 1.1 christos along with this file; see the file COPYING. If not, write to the 19 1.1 christos Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston, 20 1.1 christos MA 02110-1301, USA. */ 21 1.1 christos 22 1.1.1.2 christos #include "sysdep.h" 23 1.1 christos #include <errno.h> 24 1.1 christos #include <math.h> 25 1.1 christos #include <stdlib.h> 26 1.1.1.6 christos #include "disassemble.h" 27 1.1 christos #include "opcode/tic54x.h" 28 1.1 christos #include "coff/tic54x.h" 29 1.1 christos 30 1.1 christos static int has_lkaddr (unsigned short, const insn_template *); 31 1.1 christos static int get_insn_size (unsigned short, const insn_template *); 32 1.1 christos static int print_instruction (disassemble_info *, bfd_vma, 33 1.1 christos unsigned short, const char *, 34 1.1 christos const enum optype [], int, int); 35 1.1 christos static int print_parallel_instruction (disassemble_info *, bfd_vma, 36 1.1 christos unsigned short, 37 1.1 christos const insn_template *, int); 38 1.1 christos static int sprint_dual_address (disassemble_info *,char [], 39 1.1 christos unsigned short); 40 1.1 christos static int sprint_indirect_address (disassemble_info *,char [], 41 1.1 christos unsigned short); 42 1.1 christos static int sprint_direct_address (disassemble_info *,char [], 43 1.1 christos unsigned short); 44 1.1 christos static int sprint_mmr (disassemble_info *,char [],int); 45 1.1 christos static int sprint_condition (disassemble_info *,char *,unsigned short); 46 1.1 christos static int sprint_cc2 (disassemble_info *,char *,unsigned short); 47 1.1 christos 48 1.1 christos int 49 1.1 christos print_insn_tic54x (bfd_vma memaddr, disassemble_info *info) 50 1.1 christos { 51 1.1 christos bfd_byte opbuf[2]; 52 1.1 christos unsigned short opcode; 53 1.1 christos int status, size; 54 1.1 christos const insn_template* tm; 55 1.1 christos 56 1.1 christos status = (*info->read_memory_func) (memaddr, opbuf, 2, info); 57 1.1 christos if (status != 0) 58 1.1 christos { 59 1.1 christos (*info->memory_error_func) (status, memaddr, info); 60 1.1 christos return -1; 61 1.1 christos } 62 1.1 christos 63 1.1 christos opcode = bfd_getl16 (opbuf); 64 1.1 christos tm = tic54x_get_insn (info, memaddr, opcode, &size); 65 1.1 christos 66 1.1 christos info->bytes_per_line = 2; 67 1.1 christos info->bytes_per_chunk = 2; 68 1.1 christos info->octets_per_byte = 2; 69 1.1 christos info->display_endian = BFD_ENDIAN_LITTLE; 70 1.1 christos 71 1.1 christos if (tm->flags & FL_PAR) 72 1.1 christos { 73 1.1 christos if (!print_parallel_instruction (info, memaddr, opcode, tm, size)) 74 1.1 christos return -1; 75 1.1 christos } 76 1.1 christos else 77 1.1 christos { 78 1.1 christos if (!print_instruction (info, memaddr, opcode, 79 1.1 christos (char *) tm->name, 80 1.1 christos tm->operand_types, 81 1.1 christos size, (tm->flags & FL_EXT))) 82 1.1 christos return -1; 83 1.1 christos } 84 1.1 christos 85 1.1 christos return size * 2; 86 1.1 christos } 87 1.1 christos 88 1.1 christos static int 89 1.1 christos has_lkaddr (unsigned short memdata, const insn_template *tm) 90 1.1 christos { 91 1.1 christos return (IS_LKADDR (memdata) 92 1.1 christos && (OPTYPE (tm->operand_types[0]) == OP_Smem 93 1.1 christos || OPTYPE (tm->operand_types[1]) == OP_Smem 94 1.1 christos || OPTYPE (tm->operand_types[2]) == OP_Smem 95 1.1 christos || OPTYPE (tm->operand_types[1]) == OP_Sind 96 1.1 christos || OPTYPE (tm->operand_types[0]) == OP_Lmem 97 1.1 christos || OPTYPE (tm->operand_types[1]) == OP_Lmem)); 98 1.1 christos } 99 1.1 christos 100 1.1 christos /* always returns 1 (whether an insn template was found) since we provide an 101 1.1 christos "unknown instruction" template */ 102 1.1 christos const insn_template* 103 1.1 christos tic54x_get_insn (disassemble_info *info, bfd_vma addr, 104 1.1 christos unsigned short memdata, int *size) 105 1.1 christos { 106 1.1 christos const insn_template *tm = NULL; 107 1.1 christos 108 1.1 christos for (tm = tic54x_optab; tm->name; tm++) 109 1.1 christos { 110 1.1 christos if (tm->opcode == (memdata & tm->mask)) 111 1.1 christos { 112 1.1 christos /* a few opcodes span two words */ 113 1.1 christos if (tm->flags & FL_EXT) 114 1.1 christos { 115 1.1 christos /* if lk addressing is used, the second half of the opcode gets 116 1.1 christos pushed one word later */ 117 1.1 christos bfd_byte opbuf[2]; 118 1.1 christos bfd_vma addr2 = addr + 1 + has_lkaddr (memdata, tm); 119 1.1 christos int status = (*info->read_memory_func) (addr2, opbuf, 2, info); 120 1.1.1.7 christos /* FIXME handle errors. */ 121 1.1 christos if (status == 0) 122 1.1 christos { 123 1.1 christos unsigned short data2 = bfd_getl16 (opbuf); 124 1.1 christos if (tm->opcode2 == (data2 & tm->mask2)) 125 1.1 christos { 126 1.1 christos if (size) *size = get_insn_size (memdata, tm); 127 1.1 christos return tm; 128 1.1 christos } 129 1.1 christos } 130 1.1 christos } 131 1.1 christos else 132 1.1 christos { 133 1.1 christos if (size) *size = get_insn_size (memdata, tm); 134 1.1 christos return tm; 135 1.1 christos } 136 1.1 christos } 137 1.1 christos } 138 1.1 christos for (tm = (insn_template *) tic54x_paroptab; tm->name; tm++) 139 1.1 christos { 140 1.1 christos if (tm->opcode == (memdata & tm->mask)) 141 1.1 christos { 142 1.1 christos if (size) *size = get_insn_size (memdata, tm); 143 1.1 christos return tm; 144 1.1 christos } 145 1.1 christos } 146 1.1 christos 147 1.1 christos if (size) *size = 1; 148 1.1 christos return &tic54x_unknown_opcode; 149 1.1 christos } 150 1.1 christos 151 1.1 christos static int 152 1.1 christos get_insn_size (unsigned short memdata, const insn_template *insn) 153 1.1 christos { 154 1.1 christos int size; 155 1.1 christos 156 1.1 christos if (insn->flags & FL_PAR) 157 1.1 christos { 158 1.1 christos /* only non-parallel instructions support lk addressing */ 159 1.1 christos size = insn->words; 160 1.1 christos } 161 1.1 christos else 162 1.1 christos { 163 1.1 christos size = insn->words + has_lkaddr (memdata, insn); 164 1.1 christos } 165 1.1 christos 166 1.1 christos return size; 167 1.1 christos } 168 1.1 christos 169 1.1 christos int 170 1.1.1.2 christos print_instruction (disassemble_info *info, 171 1.1.1.2 christos bfd_vma memaddr, 172 1.1.1.2 christos unsigned short opcode, 173 1.1.1.2 christos const char *tm_name, 174 1.1.1.2 christos const enum optype tm_operands[], 175 1.1.1.2 christos int size, 176 1.1.1.2 christos int ext) 177 1.1 christos { 178 1.1 christos static int n; 179 1.1 christos /* string storage for multiple operands */ 180 1.1 christos char operand[4][64] = { {0},{0},{0},{0}, }; 181 1.1 christos bfd_byte buf[2]; 182 1.1 christos unsigned long opcode2 = 0; 183 1.1 christos unsigned long lkaddr = 0; 184 1.1 christos enum optype src = OP_None; 185 1.1 christos enum optype dst = OP_None; 186 1.1 christos int i, shift; 187 1.1 christos char *comma = ""; 188 1.1 christos 189 1.1 christos info->fprintf_func (info->stream, "%-7s", tm_name); 190 1.1 christos 191 1.1 christos if (size > 1) 192 1.1 christos { 193 1.1 christos int status = (*info->read_memory_func) (memaddr + 1, buf, 2, info); 194 1.1 christos if (status != 0) 195 1.1 christos return 0; 196 1.1 christos lkaddr = opcode2 = bfd_getl16 (buf); 197 1.1 christos if (size > 2) 198 1.1 christos { 199 1.1 christos status = (*info->read_memory_func) (memaddr + 2, buf, 2, info); 200 1.1 christos if (status != 0) 201 1.1 christos return 0; 202 1.1 christos opcode2 = bfd_getl16 (buf); 203 1.1 christos } 204 1.1 christos } 205 1.1 christos 206 1.1 christos for (i = 0; i < MAX_OPERANDS && OPTYPE (tm_operands[i]) != OP_None; i++) 207 1.1 christos { 208 1.1 christos char *next_comma = ","; 209 1.1 christos int optional = (tm_operands[i] & OPT) != 0; 210 1.1 christos 211 1.1 christos switch (OPTYPE (tm_operands[i])) 212 1.1 christos { 213 1.1 christos case OP_Xmem: 214 1.1 christos sprint_dual_address (info, operand[i], XMEM (opcode)); 215 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 216 1.1 christos break; 217 1.1 christos case OP_Ymem: 218 1.1 christos sprint_dual_address (info, operand[i], YMEM (opcode)); 219 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 220 1.1 christos break; 221 1.1 christos case OP_Smem: 222 1.1 christos case OP_Sind: 223 1.1 christos case OP_Lmem: 224 1.1 christos info->fprintf_func (info->stream, "%s", comma); 225 1.1 christos if (INDIRECT (opcode)) 226 1.1 christos { 227 1.1 christos if (MOD (opcode) >= 12) 228 1.1 christos { 229 1.1 christos bfd_vma addr = lkaddr; 230 1.1 christos int arf = ARF (opcode); 231 1.1 christos int mod = MOD (opcode); 232 1.1 christos if (mod == 15) 233 1.1 christos info->fprintf_func (info->stream, "*("); 234 1.1 christos else 235 1.1 christos info->fprintf_func (info->stream, "*%sar%d(", 236 1.1 christos (mod == 13 || mod == 14 ? "+" : ""), 237 1.1 christos arf); 238 1.1 christos (*(info->print_address_func)) ((bfd_vma) addr, info); 239 1.1 christos info->fprintf_func (info->stream, ")%s", 240 1.1 christos mod == 14 ? "%" : ""); 241 1.1 christos } 242 1.1 christos else 243 1.1 christos { 244 1.1 christos sprint_indirect_address (info, operand[i], opcode); 245 1.1 christos info->fprintf_func (info->stream, "%s", operand[i]); 246 1.1 christos } 247 1.1 christos } 248 1.1 christos else 249 1.1 christos { 250 1.1 christos /* FIXME -- use labels (print_address_func) */ 251 1.1 christos /* in order to do this, we need to guess what DP is */ 252 1.1 christos sprint_direct_address (info, operand[i], opcode); 253 1.1 christos info->fprintf_func (info->stream, "%s", operand[i]); 254 1.1 christos } 255 1.1 christos break; 256 1.1 christos case OP_dmad: 257 1.1 christos info->fprintf_func (info->stream, "%s", comma); 258 1.1 christos (*(info->print_address_func)) ((bfd_vma) opcode2, info); 259 1.1 christos break; 260 1.1 christos case OP_xpmad: 261 1.1 christos /* upper 7 bits of address are in the opcode */ 262 1.1 christos opcode2 += ((unsigned long) opcode & 0x7F) << 16; 263 1.1 christos /* fall through */ 264 1.1 christos case OP_pmad: 265 1.1 christos info->fprintf_func (info->stream, "%s", comma); 266 1.1 christos (*(info->print_address_func)) ((bfd_vma) opcode2, info); 267 1.1 christos break; 268 1.1 christos case OP_MMRX: 269 1.1 christos sprint_mmr (info, operand[i], MMRX (opcode)); 270 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 271 1.1 christos break; 272 1.1 christos case OP_MMRY: 273 1.1 christos sprint_mmr (info, operand[i], MMRY (opcode)); 274 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 275 1.1 christos break; 276 1.1 christos case OP_MMR: 277 1.1 christos sprint_mmr (info, operand[i], MMR (opcode)); 278 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 279 1.1 christos break; 280 1.1 christos case OP_PA: 281 1.1 christos sprintf (operand[i], "pa%d", (unsigned) opcode2); 282 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 283 1.1 christos break; 284 1.1 christos case OP_SRC: 285 1.1 christos src = SRC (ext ? opcode2 : opcode) ? OP_B : OP_A; 286 1.1 christos sprintf (operand[i], (src == OP_B) ? "b" : "a"); 287 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 288 1.1 christos break; 289 1.1 christos case OP_SRC1: 290 1.1 christos src = SRC1 (ext ? opcode2 : opcode) ? OP_B : OP_A; 291 1.1 christos sprintf (operand[i], (src == OP_B) ? "b" : "a"); 292 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 293 1.1 christos break; 294 1.1 christos case OP_RND: 295 1.1 christos dst = DST (opcode) ? OP_B : OP_A; 296 1.1 christos sprintf (operand[i], (dst == OP_B) ? "a" : "b"); 297 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 298 1.1 christos break; 299 1.1 christos case OP_DST: 300 1.1 christos dst = DST (ext ? opcode2 : opcode) ? OP_B : OP_A; 301 1.1 christos if (!optional || dst != src) 302 1.1 christos { 303 1.1 christos sprintf (operand[i], (dst == OP_B) ? "b" : "a"); 304 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 305 1.1 christos } 306 1.1 christos else 307 1.1 christos next_comma = comma; 308 1.1 christos break; 309 1.1 christos case OP_B: 310 1.1 christos sprintf (operand[i], "b"); 311 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 312 1.1 christos break; 313 1.1 christos case OP_A: 314 1.1 christos sprintf (operand[i], "a"); 315 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 316 1.1 christos break; 317 1.1 christos case OP_ARX: 318 1.1 christos sprintf (operand[i], "ar%d", (int) ARX (opcode)); 319 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 320 1.1 christos break; 321 1.1 christos case OP_SHIFT: 322 1.1 christos shift = SHIFT (ext ? opcode2 : opcode); 323 1.1 christos if (!optional || shift != 0) 324 1.1 christos { 325 1.1 christos sprintf (operand[i], "%d", shift); 326 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 327 1.1 christos } 328 1.1 christos else 329 1.1 christos next_comma = comma; 330 1.1 christos break; 331 1.1 christos case OP_SHFT: 332 1.1 christos shift = SHFT (opcode); 333 1.1 christos if (!optional || shift != 0) 334 1.1 christos { 335 1.1 christos sprintf (operand[i], "%d", (unsigned) shift); 336 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 337 1.1 christos } 338 1.1 christos else 339 1.1 christos next_comma = comma; 340 1.1 christos break; 341 1.1 christos case OP_lk: 342 1.1 christos sprintf (operand[i], "#%d", (int) (short) opcode2); 343 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 344 1.1 christos break; 345 1.1 christos case OP_T: 346 1.1 christos sprintf (operand[i], "t"); 347 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 348 1.1 christos break; 349 1.1 christos case OP_TS: 350 1.1 christos sprintf (operand[i], "ts"); 351 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 352 1.1 christos break; 353 1.1 christos case OP_k8: 354 1.1 christos sprintf (operand[i], "%d", (int) ((signed char) (opcode & 0xFF))); 355 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 356 1.1 christos break; 357 1.1 christos case OP_16: 358 1.1 christos sprintf (operand[i], "16"); 359 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 360 1.1 christos break; 361 1.1 christos case OP_ASM: 362 1.1 christos sprintf (operand[i], "asm"); 363 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 364 1.1 christos break; 365 1.1 christos case OP_BITC: 366 1.1 christos sprintf (operand[i], "%d", (int) (opcode & 0xF)); 367 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 368 1.1 christos break; 369 1.1 christos case OP_CC: 370 1.1 christos /* put all CC operands in the same operand */ 371 1.1 christos sprint_condition (info, operand[i], opcode); 372 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 373 1.1 christos i = MAX_OPERANDS; 374 1.1 christos break; 375 1.1 christos case OP_CC2: 376 1.1 christos sprint_cc2 (info, operand[i], opcode); 377 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 378 1.1 christos break; 379 1.1 christos case OP_CC3: 380 1.1 christos { 381 1.1 christos const char *code[] = { "eq", "lt", "gt", "neq" }; 382 1.1 christos 383 1.1 christos /* Do not use sprintf with only two parameters as a 384 1.1 christos compiler warning could be generated in such conditions. */ 385 1.1 christos sprintf (operand[i], "%s", code[CC3 (opcode)]); 386 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 387 1.1 christos break; 388 1.1 christos } 389 1.1 christos case OP_123: 390 1.1 christos { 391 1.1 christos int code = (opcode >> 8) & 0x3; 392 1.1 christos sprintf (operand[i], "%d", (code == 0) ? 1 : (code == 2) ? 2 : 3); 393 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 394 1.1 christos break; 395 1.1 christos } 396 1.1 christos case OP_k5: 397 1.1.1.7 christos sprintf (operand[i], "#%d", ((opcode & 0x1F) ^ 0x10) - 0x10); 398 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 399 1.1 christos break; 400 1.1 christos case OP_k8u: 401 1.1 christos sprintf (operand[i], "#%d", (unsigned) (opcode & 0xFF)); 402 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 403 1.1 christos break; 404 1.1 christos case OP_k3: 405 1.1 christos sprintf (operand[i], "#%d", (int) (opcode & 0x7)); 406 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 407 1.1 christos break; 408 1.1 christos case OP_lku: 409 1.1 christos sprintf (operand[i], "#%d", (unsigned) opcode2); 410 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 411 1.1 christos break; 412 1.1 christos case OP_N: 413 1.1 christos n = (opcode >> 9) & 0x1; 414 1.1 christos sprintf (operand[i], "st%d", n); 415 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 416 1.1 christos break; 417 1.1 christos case OP_SBIT: 418 1.1 christos { 419 1.1 christos const char *status0[] = { 420 1.1 christos "0", "1", "2", "3", "4", "5", "6", "7", "8", 421 1.1 christos "ovb", "ova", "c", "tc", "13", "14", "15" 422 1.1 christos }; 423 1.1 christos const char *status1[] = { 424 1.1 christos "0", "1", "2", "3", "4", 425 1.1 christos "cmpt", "frct", "c16", "sxm", "ovm", "10", 426 1.1 christos "intm", "hm", "xf", "cpl", "braf" 427 1.1 christos }; 428 1.1 christos sprintf (operand[i], "%s", 429 1.1 christos n ? status1[SBIT (opcode)] : status0[SBIT (opcode)]); 430 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 431 1.1 christos break; 432 1.1 christos } 433 1.1 christos case OP_12: 434 1.1 christos sprintf (operand[i], "%d", (int) ((opcode >> 9) & 1) + 1); 435 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 436 1.1 christos break; 437 1.1 christos case OP_TRN: 438 1.1 christos sprintf (operand[i], "trn"); 439 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 440 1.1 christos break; 441 1.1 christos case OP_DP: 442 1.1 christos sprintf (operand[i], "dp"); 443 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 444 1.1 christos break; 445 1.1 christos case OP_k9: 446 1.1 christos /* FIXME-- this is DP, print the original address? */ 447 1.1 christos sprintf (operand[i], "#%d", (int) (opcode & 0x1FF)); 448 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 449 1.1 christos break; 450 1.1 christos case OP_ARP: 451 1.1 christos sprintf (operand[i], "arp"); 452 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 453 1.1 christos break; 454 1.1 christos case OP_031: 455 1.1 christos sprintf (operand[i], "%d", (int) (opcode & 0x1F)); 456 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 457 1.1 christos break; 458 1.1 christos default: 459 1.1 christos sprintf (operand[i], "??? (0x%x)", tm_operands[i]); 460 1.1 christos info->fprintf_func (info->stream, "%s%s", comma, operand[i]); 461 1.1 christos break; 462 1.1 christos } 463 1.1 christos comma = next_comma; 464 1.1 christos } 465 1.1 christos return 1; 466 1.1 christos } 467 1.1 christos 468 1.1 christos static int 469 1.1.1.2 christos print_parallel_instruction (disassemble_info *info, 470 1.1.1.2 christos bfd_vma memaddr, 471 1.1.1.2 christos unsigned short opcode, 472 1.1.1.2 christos const insn_template *ptm, 473 1.1.1.2 christos int size) 474 1.1 christos { 475 1.1 christos print_instruction (info, memaddr, opcode, 476 1.1 christos ptm->name, ptm->operand_types, size, 0); 477 1.1 christos info->fprintf_func (info->stream, " || "); 478 1.1 christos return print_instruction (info, memaddr, opcode, 479 1.1 christos ptm->parname, ptm->paroperand_types, size, 0); 480 1.1 christos } 481 1.1 christos 482 1.1 christos static int 483 1.1.1.2 christos sprint_dual_address (disassemble_info *info ATTRIBUTE_UNUSED, 484 1.1.1.2 christos char buf[], 485 1.1.1.2 christos unsigned short code) 486 1.1 christos { 487 1.1 christos const char *formats[] = { 488 1.1 christos "*ar%d", 489 1.1 christos "*ar%d-", 490 1.1 christos "*ar%d+", 491 1.1 christos "*ar%d+0%%", 492 1.1 christos }; 493 1.1 christos return sprintf (buf, formats[XMOD (code)], XARX (code)); 494 1.1 christos } 495 1.1 christos 496 1.1 christos static int 497 1.1.1.2 christos sprint_indirect_address (disassemble_info *info ATTRIBUTE_UNUSED, 498 1.1.1.2 christos char buf[], 499 1.1.1.2 christos unsigned short opcode) 500 1.1 christos { 501 1.1 christos const char *formats[] = { 502 1.1 christos "*ar%d", 503 1.1 christos "*ar%d-", 504 1.1 christos "*ar%d+", 505 1.1 christos "*+ar%d", 506 1.1 christos "*ar%d-0B", 507 1.1 christos "*ar%d-0", 508 1.1 christos "*ar%d+0", 509 1.1 christos "*ar%d+0B", 510 1.1 christos "*ar%d-%%", 511 1.1 christos "*ar%d-0%%", 512 1.1 christos "*ar%d+%%", 513 1.1 christos "*ar%d+0%%", 514 1.1 christos }; 515 1.1 christos return sprintf (buf, formats[MOD (opcode)], ARF (opcode)); 516 1.1 christos } 517 1.1 christos 518 1.1 christos static int 519 1.1.1.2 christos sprint_direct_address (disassemble_info *info ATTRIBUTE_UNUSED, 520 1.1.1.2 christos char buf[], 521 1.1.1.2 christos unsigned short opcode) 522 1.1 christos { 523 1.1 christos /* FIXME -- look up relocation if available */ 524 1.1 christos return sprintf (buf, "DP+0x%02x", (int) (opcode & 0x7F)); 525 1.1 christos } 526 1.1 christos 527 1.1 christos static int 528 1.1.1.2 christos sprint_mmr (disassemble_info *info ATTRIBUTE_UNUSED, 529 1.1.1.2 christos char buf[], 530 1.1.1.2 christos int mmr) 531 1.1 christos { 532 1.1.1.8 christos const tic54x_symbol *reg = tic54x_mmregs; 533 1.1 christos while (reg->name != NULL) 534 1.1 christos { 535 1.1 christos if (mmr == reg->value) 536 1.1 christos { 537 1.1 christos sprintf (buf, "%s", (reg + 1)->name); 538 1.1 christos return 1; 539 1.1 christos } 540 1.1 christos ++reg; 541 1.1 christos } 542 1.1 christos sprintf (buf, "MMR(%d)", mmr); /* FIXME -- different targets. */ 543 1.1 christos return 0; 544 1.1 christos } 545 1.1 christos 546 1.1 christos static int 547 1.1.1.2 christos sprint_cc2 (disassemble_info *info ATTRIBUTE_UNUSED, 548 1.1.1.2 christos char *buf, 549 1.1.1.2 christos unsigned short opcode) 550 1.1 christos { 551 1.1 christos const char *cc2[] = { 552 1.1 christos "??", "??", "ageq", "alt", "aneq", "aeq", "agt", "aleq", 553 1.1 christos "??", "??", "bgeq", "blt", "bneq", "beq", "bgt", "bleq", 554 1.1 christos }; 555 1.1 christos return sprintf (buf, "%s", cc2[opcode & 0xF]); 556 1.1 christos } 557 1.1 christos 558 1.1 christos static int 559 1.1.1.2 christos sprint_condition (disassemble_info *info ATTRIBUTE_UNUSED, 560 1.1.1.2 christos char *buf, 561 1.1.1.2 christos unsigned short opcode) 562 1.1 christos { 563 1.1 christos char *start = buf; 564 1.1 christos const char *cmp[] = { 565 1.1 christos "??", "??", "geq", "lt", "neq", "eq", "gt", "leq" 566 1.1 christos }; 567 1.1 christos if (opcode & 0x40) 568 1.1 christos { 569 1.1 christos char acc = (opcode & 0x8) ? 'b' : 'a'; 570 1.1 christos if (opcode & 0x7) 571 1.1 christos buf += sprintf (buf, "%c%s%s", acc, cmp[(opcode & 0x7)], 572 1.1 christos (opcode & 0x20) ? ", " : ""); 573 1.1 christos if (opcode & 0x20) 574 1.1 christos buf += sprintf (buf, "%c%s", acc, (opcode & 0x10) ? "ov" : "nov"); 575 1.1 christos } 576 1.1 christos else if (opcode & 0x3F) 577 1.1 christos { 578 1.1 christos if (opcode & 0x30) 579 1.1 christos buf += sprintf (buf, "%s%s", 580 1.1 christos ((opcode & 0x30) == 0x30) ? "tc" : "ntc", 581 1.1 christos (opcode & 0x0F) ? ", " : ""); 582 1.1 christos if (opcode & 0x0C) 583 1.1 christos buf += sprintf (buf, "%s%s", 584 1.1 christos ((opcode & 0x0C) == 0x0C) ? "c" : "nc", 585 1.1 christos (opcode & 0x03) ? ", " : ""); 586 1.1 christos if (opcode & 0x03) 587 1.1 christos buf += sprintf (buf, "%s", 588 1.1 christos ((opcode & 0x03) == 0x03) ? "bio" : "nbio"); 589 1.1 christos } 590 1.1 christos else 591 1.1 christos buf += sprintf (buf, "unc"); 592 1.1 christos 593 1.1 christos return buf - start; 594 1.1 christos } 595