Home | History | Annotate | Line # | Download | only in opcodes
      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