[BACK]Return to mcore-dis.c CVS log [TXT][DIR] Up to [cvs.NetBSD.org] / src / external / gpl3 / binutils / dist / opcodes

Annotation of src/external/gpl3/binutils/dist/opcodes/mcore-dis.c, Revision 1.1.1.4

1.1       skrll       1: /* Disassemble Motorola M*Core instructions.
1.1.1.4 ! christos    2:    Copyright (C) 1993-2016 Free Software Foundation, Inc.
1.1       skrll       3:
                      4:    This file is part of the GNU opcodes library.
                      5:
                      6:    This library is free software; you can redistribute it and/or modify
                      7:    it under the terms of the GNU General Public License as published by
                      8:    the Free Software Foundation; either version 3, or (at your option)
                      9:    any later version.
                     10:
                     11:    It is distributed in the hope that it will be useful, but WITHOUT
                     12:    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     13:    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
                     14:    License for more details.
                     15:
                     16:    You should have received a copy of the GNU General Public License
                     17:    along with this program; if not, write to the Free Software
                     18:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     19:    MA 02110-1301, USA.  */
                     20:
                     21: #include "sysdep.h"
                     22: #include <stdio.h>
1.1.1.4 ! christos   23: #include "libiberty.h"
1.1       skrll      24: #define STATIC_TABLE
                     25: #define DEFINE_TABLE
                     26:
                     27: #include "mcore-opc.h"
                     28: #include "dis-asm.h"
                     29:
                     30: /* Mask for each mcore_opclass: */
                     31: static const unsigned short imsk[] = {
                     32:     /* O0  */ 0xFFFF,
                     33:     /* OT  */ 0xFFFC,
                     34:     /* O1  */ 0xFFF0,
                     35:     /* OC  */ 0xFE00,
                     36:     /* O2  */ 0xFF00,
                     37:     /* X1  */ 0xFFF0,
                     38:     /* OI  */ 0xFE00,
                     39:     /* OB  */ 0xFE00,
                     40:
                     41:     /* OMa */ 0xFFF0,
                     42:     /* SI  */ 0xFE00,
                     43:     /* I7  */ 0xF800,
                     44:     /* LS  */ 0xF000,
                     45:     /* BR  */ 0xF800,
                     46:     /* BL  */ 0xFF00,
                     47:     /* LR  */ 0xF000,
                     48:     /* LJ  */ 0xFF00,
                     49:
                     50:     /* RM  */ 0xFFF0,
                     51:     /* RQ  */ 0xFFF0,
                     52:     /* JSR */ 0xFFF0,
                     53:     /* JMP */ 0xFFF0,
                     54:     /* OBRa*/ 0xFFF0,
                     55:     /* OBRb*/ 0xFF80,
                     56:     /* OBRc*/ 0xFF00,
                     57:     /* OBR2*/ 0xFE00,
                     58:
                     59:     /* O1R1*/ 0xFFF0,
                     60:     /* OMb */ 0xFF80,
                     61:     /* OMc */ 0xFF00,
                     62:     /* SIa */ 0xFE00,
                     63:
                     64:   /* MULSH */ 0xFF00,
                     65:   /* OPSR  */ 0xFFF8,   /* psrset/psrclr */
                     66:
                     67:     /* JC  */ 0,               /* JC,JU,JL don't appear in object */
                     68:     /* JU  */ 0,
                     69:     /* JL  */ 0,
                     70:     /* RSI */ 0,
                     71:     /* DO21*/ 0,
                     72:     /* OB2 */ 0                /* OB2 won't appear in object.  */
                     73: };
                     74:
                     75: static const char *grname[] = {
                     76:  "r0",  "r1",  "r2",  "r3",  "r4",  "r5",  "r6",  "r7",
                     77:  "r8",  "r9", "r10", "r11", "r12", "r13", "r14", "r15"
                     78: };
                     79:
                     80: static const char X[] = "??";
                     81:
                     82: static const char *crname[] = {
                     83:   "psr",  "vbr", "epsr", "fpsr", "epc",  "fpc",  "ss0",  "ss1",
                     84:   "ss2",  "ss3", "ss4",  "gcr",  "gsr",     X,      X,      X,
                     85:      X,      X,      X,      X,      X,     X,      X,      X,
                     86:      X,      X,      X,      X,      X,     X,      X,      X
                     87: };
                     88:
                     89: static const unsigned isiz[] = { 2, 0, 1, 0 };
                     90:
                     91: int
1.1.1.3   christos   92: print_insn_mcore (bfd_vma memaddr,
                     93:                  struct disassemble_info *info)
1.1       skrll      94: {
                     95:   unsigned char ibytes[4];
1.1.1.2   christos   96:   fprintf_ftype print_func = info->fprintf_func;
1.1       skrll      97:   void *stream = info->stream;
                     98:   unsigned short inst;
1.1.1.4 ! christos   99:   unsigned int i;
1.1       skrll     100:   int status;
                    101:
                    102:   info->bytes_per_chunk = 2;
                    103:
                    104:   status = info->read_memory_func (memaddr, ibytes, 2, info);
                    105:
                    106:   if (status != 0)
                    107:     {
                    108:       info->memory_error_func (status, memaddr, info);
                    109:       return -1;
                    110:     }
                    111:
                    112:   if (info->endian == BFD_ENDIAN_BIG)
                    113:     inst = (ibytes[0] << 8) | ibytes[1];
                    114:   else if (info->endian == BFD_ENDIAN_LITTLE)
                    115:     inst = (ibytes[1] << 8) | ibytes[0];
                    116:   else
                    117:     abort ();
                    118:
                    119:   /* Just a linear search of the table.  */
1.1.1.4 ! christos  120:   for (i = 0; i < ARRAY_SIZE (mcore_table); i++)
        !           121:     if (mcore_table[i].inst == (inst & imsk[mcore_table[i].opclass]))
1.1       skrll     122:       break;
                    123:
1.1.1.4 ! christos  124:   if (i == ARRAY_SIZE (mcore_table))
1.1.1.2   christos  125:     (*print_func) (stream, ".short 0x%04x", inst);
1.1       skrll     126:   else
                    127:     {
                    128:       const char *name = grname[inst & 0x0F];
                    129:
1.1.1.4 ! christos  130:       (*print_func) (stream, "%s", mcore_table[i].name);
1.1       skrll     131:
1.1.1.4 ! christos  132:       switch (mcore_table[i].opclass)
1.1       skrll     133:        {
                    134:        case O0:
                    135:          break;
                    136:
                    137:        case OT:
1.1.1.2   christos  138:          (*print_func) (stream, "\t%d", inst & 0x3);
1.1       skrll     139:          break;
                    140:
                    141:        case O1:
                    142:        case JMP:
                    143:        case JSR:
1.1.1.2   christos  144:          (*print_func) (stream, "\t%s", name);
1.1       skrll     145:          break;
                    146:
                    147:        case OC:
1.1.1.2   christos  148:          (*print_func) (stream, "\t%s, %s", name, crname[(inst >> 4) & 0x1F]);
1.1       skrll     149:          break;
                    150:
                    151:        case O1R1:
1.1.1.2   christos  152:          (*print_func) (stream, "\t%s, r1", name);
1.1       skrll     153:          break;
                    154:
                    155:        case MULSH:
                    156:        case O2:
1.1.1.2   christos  157:          (*print_func) (stream, "\t%s, %s", name, grname[(inst >> 4) & 0xF]);
1.1       skrll     158:          break;
                    159:
                    160:        case X1:
1.1.1.2   christos  161:          (*print_func) (stream, "\tr1, %s", name);
1.1       skrll     162:          break;
                    163:
                    164:        case OI:
1.1.1.2   christos  165:          (*print_func) (stream, "\t%s, %d", name, ((inst >> 4) & 0x1F) + 1);
1.1       skrll     166:          break;
                    167:
                    168:        case RM:
1.1.1.2   christos  169:          (*print_func) (stream, "\t%s-r15, (r0)", name);
1.1       skrll     170:          break;
                    171:
                    172:        case RQ:
1.1.1.2   christos  173:          (*print_func) (stream, "\tr4-r7, (%s)", name);
1.1       skrll     174:          break;
                    175:
                    176:        case OB:
                    177:        case OBRa:
                    178:        case OBRb:
                    179:        case OBRc:
                    180:        case SI:
                    181:        case SIa:
                    182:        case OMa:
                    183:        case OMb:
                    184:        case OMc:
1.1.1.2   christos  185:          (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x1F);
1.1       skrll     186:          break;
                    187:
                    188:        case I7:
1.1.1.2   christos  189:          (*print_func) (stream, "\t%s, %d", name, (inst >> 4) & 0x7F);
1.1       skrll     190:          break;
                    191:
                    192:        case LS:
1.1.1.2   christos  193:          (*print_func) (stream, "\t%s, (%s, %d)", grname[(inst >> 8) & 0xF],
                    194:                         name, ((inst >> 4) & 0xF) << isiz[(inst >> 13) & 3]);
1.1       skrll     195:          break;
                    196:
                    197:        case BR:
                    198:          {
                    199:            long val = inst & 0x3FF;
                    200:
                    201:            if (inst & 0x400)
                    202:              val |= 0xFFFFFC00;
                    203:
1.1.1.2   christos  204:            (*print_func) (stream, "\t0x%lx", (long)(memaddr + 2 + (val << 1)));
1.1       skrll     205:
1.1.1.4 ! christos  206:            if (strcmp (mcore_table[i].name, "bsr") == 0)
1.1       skrll     207:              {
                    208:                /* For bsr, we'll try to get a symbol for the target.  */
                    209:                val = memaddr + 2 + (val << 1);
                    210:
                    211:                if (info->print_address_func && val != 0)
                    212:                  {
1.1.1.2   christos  213:                    (*print_func) (stream, "\t// ");
1.1       skrll     214:                    info->print_address_func (val, info);
                    215:                  }
                    216:              }
                    217:          }
                    218:          break;
                    219:
                    220:        case BL:
                    221:          {
                    222:            long val;
                    223:            val = (inst & 0x000F);
1.1.1.2   christos  224:            (*print_func) (stream, "\t%s, 0x%lx",
                    225:                           grname[(inst >> 4) & 0xF],
                    226:                           (long) (memaddr - (val << 1)));
1.1       skrll     227:          }
                    228:          break;
                    229:
                    230:        case LR:
                    231:          {
                    232:            unsigned long val;
                    233:
                    234:            val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
                    235:
1.1.1.3   christos  236:            /* We are not reading an instruction, so allow
                    237:               reads to extend beyond the next symbol.  */
                    238:            info->stop_vma = 0;
1.1       skrll     239:            status = info->read_memory_func (val, ibytes, 4, info);
                    240:            if (status != 0)
                    241:              {
                    242:                info->memory_error_func (status, memaddr, info);
                    243:                break;
                    244:              }
                    245:
                    246:            if (info->endian == BFD_ENDIAN_LITTLE)
                    247:              val = (ibytes[3] << 24) | (ibytes[2] << 16)
                    248:                | (ibytes[1] << 8) | (ibytes[0]);
                    249:            else
                    250:              val = (ibytes[0] << 24) | (ibytes[1] << 16)
                    251:                | (ibytes[2] << 8) | (ibytes[3]);
                    252:
                    253:            /* Removed [] around literal value to match ABI syntax 12/95.  */
1.1.1.2   christos  254:            (*print_func) (stream, "\t%s, 0x%lX", grname[(inst >> 8) & 0xF], val);
1.1       skrll     255:
                    256:            if (val == 0)
1.1.1.2   christos  257:              (*print_func) (stream, "\t// from address pool at 0x%lx",
                    258:                             (long) (memaddr + 2
                    259:                                     + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1.1       skrll     260:          }
                    261:          break;
                    262:
                    263:        case LJ:
                    264:          {
                    265:            unsigned long val;
                    266:
                    267:            val = (memaddr + 2 + ((inst & 0xFF) << 2)) & 0xFFFFFFFC;
                    268:
1.1.1.3   christos  269:            /* We are not reading an instruction, so allow
                    270:               reads to extend beyond the next symbol.  */
                    271:            info->stop_vma = 0;
1.1       skrll     272:            status = info->read_memory_func (val, ibytes, 4, info);
                    273:            if (status != 0)
                    274:              {
                    275:                info->memory_error_func (status, memaddr, info);
                    276:                break;
                    277:              }
                    278:
                    279:            if (info->endian == BFD_ENDIAN_LITTLE)
                    280:              val = (ibytes[3] << 24) | (ibytes[2] << 16)
                    281:                | (ibytes[1] << 8) | (ibytes[0]);
                    282:            else
                    283:              val = (ibytes[0] << 24) | (ibytes[1] << 16)
                    284:                | (ibytes[2] << 8) | (ibytes[3]);
                    285:
                    286:            /* Removed [] around literal value to match ABI syntax 12/95.  */
1.1.1.2   christos  287:            (*print_func) (stream, "\t0x%lX", val);
1.1       skrll     288:            /* For jmpi/jsri, we'll try to get a symbol for the target.  */
                    289:            if (info->print_address_func && val != 0)
                    290:              {
1.1.1.2   christos  291:                (*print_func) (stream, "\t// ");
1.1       skrll     292:                info->print_address_func (val, info);
                    293:              }
                    294:            else
                    295:              {
1.1.1.2   christos  296:                (*print_func) (stream, "\t// from address pool at 0x%lx",
                    297:                               (long) (memaddr + 2
                    298:                                       + ((inst & 0xFF) << 2)) & 0xFFFFFFFC);
1.1       skrll     299:              }
                    300:          }
                    301:          break;
                    302:
                    303:        case OPSR:
                    304:          {
                    305:            static char *fields[] = {
                    306:              "af", "ie",    "fe",    "fe,ie",
                    307:              "ee", "ee,ie", "ee,fe", "ee,fe,ie"
                    308:            };
                    309:
1.1.1.2   christos  310:            (*print_func) (stream, "\t%s", fields[inst & 0x7]);
1.1       skrll     311:          }
                    312:          break;
                    313:
                    314:        default:
                    315:          /* If the disassembler lags the instruction set.  */
1.1.1.2   christos  316:          (*print_func) (stream, "\tundecoded operands, inst is 0x%04x", inst);
1.1       skrll     317:          break;
                    318:        }
                    319:     }
                    320:
                    321:   /* Say how many bytes we consumed.  */
                    322:   return 2;
                    323: }

CVSweb <webmaster@jp.NetBSD.org>