[BACK]Return to h8300-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/h8300-dis.c, Revision 1.1.1.4

1.1       skrll       1: /* Disassemble h8300 instructions.
1.1.1.4 ! christos    2:    Copyright (C) 1993-2015 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: #define DEFINE_TABLE
                     22:
                     23: #include "sysdep.h"
                     24: #define h8_opcodes h8ops
                     25: #include "opcode/h8300.h"
                     26: #include "dis-asm.h"
                     27: #include "opintl.h"
                     28: #include "libiberty.h"
                     29:
                     30: struct h8_instruction
                     31: {
                     32:   int length;
                     33:   const struct h8_opcode *opcode;
                     34: };
                     35:
                     36: struct h8_instruction *h8_instructions;
                     37:
                     38: /* Run through the opcodes and sort them into order to make them easy
                     39:    to disassemble.  */
                     40:
                     41: static void
                     42: bfd_h8_disassemble_init (void)
                     43: {
                     44:   unsigned int i;
                     45:   unsigned int nopcodes;
                     46:   const struct h8_opcode *p;
                     47:   struct h8_instruction *pi;
                     48:
                     49:   nopcodes = sizeof (h8_opcodes) / sizeof (struct h8_opcode);
                     50:
                     51:   h8_instructions = xmalloc (nopcodes * sizeof (struct h8_instruction));
                     52:
                     53:   for (p = h8_opcodes, pi = h8_instructions; p->name; p++, pi++)
                     54:     {
                     55:       /* Just make sure there are an even number of nibbles in it, and
                     56:         that the count is the same as the length.  */
                     57:       for (i = 0; p->data.nib[i] != (op_type) E; i++)
                     58:        ;
                     59:
                     60:       if (i & 1)
                     61:        {
                     62:          fprintf (stderr, "Internal error, h8_disassemble_init.\n");
                     63:          abort ();
                     64:        }
                     65:
                     66:       pi->length = i / 2;
                     67:       pi->opcode = p;
                     68:     }
                     69:
                     70:   /* Add entry for the NULL vector terminator.  */
                     71:   pi->length = 0;
                     72:   pi->opcode = p;
                     73: }
                     74:
                     75: static void
                     76: extract_immediate (FILE *stream,
                     77:                   op_type looking_for,
                     78:                   int thisnib,
                     79:                   unsigned char *data,
                     80:                   int *cst,
                     81:                   int *len,
                     82:                   const struct h8_opcode *q)
                     83: {
                     84:   switch (looking_for & SIZE)
                     85:     {
                     86:     case L_2:
                     87:       *len = 2;
                     88:       *cst = thisnib & 3;
                     89:
                     90:       /* DISP2 special treatment.  */
                     91:       if ((looking_for & MODE) == DISP)
                     92:        {
                     93:          if (OP_KIND (q->how) == O_MOVAB
                     94:              || OP_KIND (q->how) == O_MOVAW
                     95:              || OP_KIND (q->how) == O_MOVAL)
                     96:            {
                     97:              /* Handling for mova insn.  */
                     98:              switch (q->args.nib[0] & MODE)
                     99:                {
                    100:                case INDEXB:
                    101:                default:
                    102:                  break;
                    103:                case INDEXW:
                    104:                  *cst *= 2;
                    105:                  break;
                    106:                case INDEXL:
                    107:                  *cst *= 4;
                    108:                  break;
                    109:                }
                    110:            }
                    111:          else
                    112:            {
                    113:              /* Handling for non-mova insn.  */
                    114:              switch (OP_SIZE (q->how))
                    115:                {
                    116:                default: break;
                    117:                case SW:
                    118:                  *cst *= 2;
                    119:                  break;
                    120:                case SL:
                    121:                  *cst *= 4;
                    122:                  break;
                    123:                }
                    124:            }
                    125:        }
                    126:       break;
                    127:     case L_8:
                    128:       *len = 8;
                    129:       *cst = data[0];
                    130:       break;
                    131:     case L_16:
                    132:     case L_16U:
                    133:       *len = 16;
                    134:       *cst = (data[0] << 8) + data [1];
                    135: #if 0
                    136:       if ((looking_for & SIZE) == L_16)
                    137:        *cst = (short) *cst;    /* Sign extend.  */
                    138: #endif
                    139:       break;
                    140:     case L_32:
                    141:       *len = 32;
                    142:       *cst = (data[0] << 24) + (data[1] << 16) + (data[2] << 8) + data[3];
                    143:       break;
                    144:     default:
                    145:       *len = 0;
                    146:       *cst = 0;
                    147:       fprintf (stream, "DISP bad size\n");
                    148:       break;
                    149:     }
                    150: }
                    151:
                    152: static const char *regnames[] =
                    153: {
                    154:   "r0h", "r1h", "r2h", "r3h", "r4h", "r5h", "r6h", "r7h",
                    155:   "r0l", "r1l", "r2l", "r3l", "r4l", "r5l", "r6l", "r7l"
                    156: };
                    157: static const char *wregnames[] =
                    158: {
                    159:   "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7",
                    160:   "e0", "e1", "e2", "e3", "e4", "e5", "e6", "e7"
                    161: };
                    162: static const char *lregnames[] =
                    163: {
                    164:   "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7",
                    165:   "er0", "er1", "er2", "er3", "er4", "er5", "er6", "er7"
                    166: };
                    167: static const char *cregnames[] =
                    168: {
                    169:   "ccr", "exr", "mach", "macl", "", "", "vbr", "sbr"
                    170: };
                    171:
                    172: static void
                    173: print_one_arg (disassemble_info *info,
                    174:               bfd_vma addr,
                    175:               op_type x,
                    176:               int cst,
                    177:               int cstlen,
                    178:               int rdisp_n,
                    179:               int rn,
                    180:               const char **pregnames,
                    181:               int len)
                    182: {
                    183:   void * stream = info->stream;
                    184:   fprintf_ftype outfn = info->fprintf_func;
                    185:
                    186:   if ((x & SIZE) == L_3 || (x & SIZE) == L_3NZ)
                    187:     outfn (stream, "#0x%x", (unsigned) cst);
                    188:   else if ((x & MODE) == IMM)
                    189:     outfn (stream, "#0x%x", (unsigned) cst);
                    190:   else if ((x & MODE) == DBIT || (x & MODE) == KBIT)
                    191:     outfn (stream, "#%d", (unsigned) cst);
                    192:   else if ((x & MODE) == CONST_2)
                    193:     outfn (stream, "#2");
                    194:   else if ((x & MODE) == CONST_4)
                    195:     outfn (stream, "#4");
                    196:   else if ((x & MODE) == CONST_8)
                    197:     outfn (stream, "#8");
                    198:   else if ((x & MODE) == CONST_16)
                    199:     outfn (stream, "#16");
                    200:   else if ((x & MODE) == REG)
                    201:     {
                    202:       switch (x & SIZE)
                    203:        {
                    204:        case L_8:
                    205:          outfn (stream, "%s", regnames[rn]);
                    206:          break;
                    207:        case L_16:
                    208:        case L_16U:
                    209:          outfn (stream, "%s", wregnames[rn]);
                    210:          break;
                    211:        case L_P:
                    212:        case L_32:
                    213:          outfn (stream, "%s", lregnames[rn]);
                    214:          break;
                    215:        }
                    216:     }
                    217:   else if ((x & MODE) == LOWREG)
                    218:     {
                    219:       switch (x & SIZE)
                    220:        {
                    221:        case L_8:
                    222:          /* Always take low half of reg.  */
                    223:          outfn (stream, "%s.b", regnames[rn < 8 ? rn + 8 : rn]);
                    224:          break;
                    225:        case L_16:
                    226:        case L_16U:
                    227:          /* Always take low half of reg.  */
                    228:          outfn (stream, "%s.w", wregnames[rn < 8 ? rn : rn - 8]);
                    229:          break;
                    230:        case L_P:
                    231:        case L_32:
                    232:          outfn (stream, "%s.l", lregnames[rn]);
                    233:          break;
                    234:        }
                    235:     }
                    236:   else if ((x & MODE) == POSTINC)
                    237:     outfn (stream, "@%s+", pregnames[rn]);
                    238:
                    239:   else if ((x & MODE) == POSTDEC)
                    240:     outfn (stream, "@%s-", pregnames[rn]);
                    241:
                    242:   else if ((x & MODE) == PREINC)
                    243:     outfn (stream, "@+%s", pregnames[rn]);
                    244:
                    245:   else if ((x & MODE) == PREDEC)
                    246:     outfn (stream, "@-%s", pregnames[rn]);
                    247:
                    248:   else if ((x & MODE) == IND)
                    249:     outfn (stream, "@%s", pregnames[rn]);
                    250:
                    251:   else if ((x & MODE) == ABS || (x & ABSJMP))
                    252:     outfn (stream, "@0x%x:%d", (unsigned) cst, cstlen);
                    253:
                    254:   else if ((x & MODE) == MEMIND)
                    255:     outfn (stream, "@@%d (0x%x)", cst, cst);
                    256:
                    257:   else if ((x & MODE) == VECIND)
                    258:     {
                    259:       /* FIXME Multiplier should be 2 or 4, depending on processor mode,
                    260:         by which is meant "normal" vs. "middle", "advanced", "maximum".  */
                    261:
                    262:       int offset = (cst + 0x80) * 4;
                    263:       outfn (stream, "@@%d (0x%x)", offset, offset);
                    264:     }
                    265:   else if ((x & MODE) == PCREL)
                    266:     {
                    267:       if ((x & SIZE) == L_16 ||
                    268:          (x & SIZE) == L_16U)
                    269:        {
                    270:          outfn (stream, ".%s%d (0x%lx)",
                    271:                   (short) cst > 0 ? "+" : "",
1.1.1.4 ! christos  272:                   (short) cst,
1.1       skrll     273:                   (long)(addr + (short) cst + len));
                    274:        }
                    275:       else
                    276:        {
                    277:          outfn (stream, ".%s%d (0x%lx)",
                    278:                   (char) cst > 0 ? "+" : "",
1.1.1.4 ! christos  279:                   (char) cst,
1.1       skrll     280:                   (long)(addr + (char) cst + len));
                    281:        }
                    282:     }
                    283:   else if ((x & MODE) == DISP)
                    284:     outfn (stream, "@(0x%x:%d,%s)", cst, cstlen, pregnames[rdisp_n]);
                    285:
                    286:   else if ((x & MODE) == INDEXB)
                    287:     /* Always take low half of reg.  */
1.1.1.4 ! christos  288:     outfn (stream, "@(0x%x:%d,%s.b)", cst, cstlen,
1.1       skrll     289:           regnames[rdisp_n < 8 ? rdisp_n + 8 : rdisp_n]);
                    290:
                    291:   else if ((x & MODE) == INDEXW)
                    292:     /* Always take low half of reg.  */
1.1.1.4 ! christos  293:     outfn (stream, "@(0x%x:%d,%s.w)", cst, cstlen,
1.1       skrll     294:           wregnames[rdisp_n < 8 ? rdisp_n : rdisp_n - 8]);
                    295:
                    296:   else if ((x & MODE) == INDEXL)
                    297:     outfn (stream, "@(0x%x:%d,%s.l)", cst, cstlen, lregnames[rdisp_n]);
                    298:
                    299:   else if (x & CTRL)
1.1.1.3   christos  300:     outfn (stream, "%s", cregnames[rn]);
1.1       skrll     301:
                    302:   else if ((x & MODE) == CCR)
                    303:     outfn (stream, "ccr");
                    304:
                    305:   else if ((x & MODE) == EXR)
                    306:     outfn (stream, "exr");
                    307:
                    308:   else if ((x & MODE) == MACREG)
                    309:     outfn (stream, "mac%c", cst ? 'l' : 'h');
                    310:
                    311:   else
                    312:     /* xgettext:c-format */
                    313:     outfn (stream, _("Hmmmm 0x%x"), x);
                    314: }
                    315:
                    316: static unsigned int
                    317: bfd_h8_disassemble (bfd_vma addr, disassemble_info *info, int mach)
                    318: {
                    319:   /* Find the first entry in the table for this opcode.  */
                    320:   int regno[3] = { 0, 0, 0 };
                    321:   int dispregno[3] = { 0, 0, 0 };
                    322:   int cst[3] = { 0, 0, 0 };
                    323:   int cstlen[3] = { 0, 0, 0 };
                    324:   static bfd_boolean init = 0;
                    325:   const struct h8_instruction *qi;
                    326:   char const **pregnames = mach != 0 ? lregnames : wregnames;
                    327:   int status;
                    328:   unsigned int l;
                    329:   unsigned char data[MAX_CODE_NIBBLES];
                    330:   void *stream = info->stream;
                    331:   fprintf_ftype outfn = info->fprintf_func;
                    332:
                    333:   if (!init)
                    334:     {
                    335:       bfd_h8_disassemble_init ();
                    336:       init = 1;
                    337:     }
                    338:
                    339:   status = info->read_memory_func (addr, data, 2, info);
                    340:   if (status != 0)
                    341:     {
                    342:       info->memory_error_func (status, addr, info);
                    343:       return -1;
                    344:     }
                    345:
                    346:   for (l = 2; status == 0 && l < sizeof (data) / 2; l += 2)
                    347:     status = info->read_memory_func (addr + l, data + l, 2, info);
                    348:
                    349:   /* Find the exact opcode/arg combo.  */
                    350:   for (qi = h8_instructions; qi->opcode->name; qi++)
                    351:     {
                    352:       const struct h8_opcode *q = qi->opcode;
                    353:       const op_type *nib = q->data.nib;
                    354:       unsigned int len = 0;
                    355:
                    356:       while (1)
                    357:        {
                    358:          op_type looking_for = *nib;
                    359:          int thisnib = data[len / 2];
                    360:          int opnr;
                    361:
                    362:          thisnib = (len & 1) ? (thisnib & 0xf) : ((thisnib / 16) & 0xf);
                    363:          opnr = ((looking_for & OP3) == OP3 ? 2
                    364:                  : (looking_for & DST) == DST ? 1 : 0);
                    365:
                    366:          if (looking_for < 16 && looking_for >= 0)
                    367:            {
                    368:              if (looking_for != thisnib)
                    369:                goto fail;
                    370:            }
                    371:          else
                    372:            {
                    373:              if ((int) looking_for & (int) B31)
                    374:                {
                    375:                  if (!((thisnib & 0x8) != 0))
                    376:                    goto fail;
                    377:
                    378:                  looking_for = (op_type) ((int) looking_for & ~(int) B31);
                    379:                  thisnib &= 0x7;
                    380:                }
                    381:              else if ((int) looking_for & (int) B30)
                    382:                {
                    383:                  if (!((thisnib & 0x8) == 0))
                    384:                    goto fail;
                    385:
                    386:                  looking_for = (op_type) ((int) looking_for & ~(int) B30);
                    387:                }
                    388:
                    389:              if ((int) looking_for & (int) B21)
                    390:                {
                    391:                  if (!((thisnib & 0x4) != 0))
                    392:                    goto fail;
                    393:
                    394:                  looking_for = (op_type) ((int) looking_for & ~(int) B21);
                    395:                  thisnib &= 0xb;
                    396:                }
                    397:              else if ((int) looking_for & (int) B20)
                    398:                {
                    399:                  if (!((thisnib & 0x4) == 0))
                    400:                    goto fail;
                    401:
                    402:                  looking_for = (op_type) ((int) looking_for & ~(int) B20);
                    403:                }
                    404:              if ((int) looking_for & (int) B11)
                    405:                {
                    406:                  if (!((thisnib & 0x2) != 0))
                    407:                    goto fail;
                    408:
                    409:                  looking_for = (op_type) ((int) looking_for & ~(int) B11);
                    410:                  thisnib &= 0xd;
                    411:                }
                    412:              else if ((int) looking_for & (int) B10)
                    413:                {
                    414:                  if (!((thisnib & 0x2) == 0))
                    415:                    goto fail;
                    416:
                    417:                  looking_for = (op_type) ((int) looking_for & ~(int) B10);
                    418:                }
                    419:
                    420:              if ((int) looking_for & (int) B01)
                    421:                {
                    422:                  if (!((thisnib & 0x1) != 0))
                    423:                    goto fail;
                    424:
                    425:                  looking_for = (op_type) ((int) looking_for & ~(int) B01);
                    426:                  thisnib &= 0xe;
                    427:                }
                    428:              else if ((int) looking_for & (int) B00)
                    429:                {
                    430:                  if (!((thisnib & 0x1) == 0))
                    431:                    goto fail;
                    432:
                    433:                  looking_for = (op_type) ((int) looking_for & ~(int) B00);
                    434:                }
                    435:
                    436:              if (looking_for & IGNORE)
                    437:                {
                    438:                  /* Hitachi has declared that IGNORE must be zero.  */
                    439:                  if (thisnib != 0)
                    440:                    goto fail;
                    441:                }
                    442:              else if ((looking_for & MODE) == DATA)
                    443:                {
                    444:                  ;                     /* Skip embedded data.  */
                    445:                }
                    446:              else if ((looking_for & MODE) == DBIT)
                    447:                {
                    448:                  /* Exclude adds/subs by looking at bit 0 and 2, and
                    449:                      make sure the operand size, either w or l,
                    450:                      matches by looking at bit 1.  */
                    451:                  if ((looking_for & 7) != (thisnib & 7))
                    452:                    goto fail;
                    453:
                    454:                  cst[opnr] = (thisnib & 0x8) ? 2 : 1;
                    455:                }
                    456:              else if ((looking_for & MODE) == DISP
                    457:                       || (looking_for & MODE) == ABS
                    458:                       || (looking_for & MODE) == PCREL
                    459:                       || (looking_for & MODE) == INDEXB
                    460:                       || (looking_for & MODE) == INDEXW
                    461:                       || (looking_for & MODE) == INDEXL)
                    462:                {
1.1.1.4 ! christos  463:                  extract_immediate (stream, looking_for, thisnib,
        !           464:                                     data + len / 2, cst + opnr,
1.1       skrll     465:                                     cstlen + opnr, q);
                    466:                  /* Even address == bra, odd == bra/s.  */
                    467:                  if (q->how == O (O_BRAS, SB))
                    468:                    cst[opnr] -= 1;
                    469:                }
                    470:              else if ((looking_for & MODE) == REG
                    471:                       || (looking_for & MODE) == LOWREG
                    472:                       || (looking_for & MODE) == IND
                    473:                       || (looking_for & MODE) == PREINC
                    474:                       || (looking_for & MODE) == POSTINC
                    475:                       || (looking_for & MODE) == PREDEC
                    476:                       || (looking_for & MODE) == POSTDEC)
                    477:                {
                    478:                  regno[opnr] = thisnib;
                    479:                }
                    480:              else if (looking_for & CTRL)      /* Control Register.  */
                    481:                {
                    482:                  thisnib &= 7;
                    483:                  if (((looking_for & MODE) == CCR  && (thisnib != C_CCR))
                    484:                      || ((looking_for & MODE) == EXR  && (thisnib != C_EXR))
                    485:                      || ((looking_for & MODE) == MACH && (thisnib != C_MACH))
                    486:                      || ((looking_for & MODE) == MACL && (thisnib != C_MACL))
                    487:                      || ((looking_for & MODE) == VBR  && (thisnib != C_VBR))
                    488:                      || ((looking_for & MODE) == SBR  && (thisnib != C_SBR)))
                    489:                    goto fail;
                    490:                  if (((looking_for & MODE) == CCR_EXR
                    491:                       && (thisnib != C_CCR && thisnib != C_EXR))
                    492:                      || ((looking_for & MODE) == VBR_SBR
                    493:                          && (thisnib != C_VBR && thisnib != C_SBR))
                    494:                      || ((looking_for & MODE) == MACREG
                    495:                          && (thisnib != C_MACH && thisnib != C_MACL)))
                    496:                    goto fail;
                    497:                  if (((looking_for & MODE) == CC_EX_VB_SB
                    498:                       && (thisnib != C_CCR && thisnib != C_EXR
                    499:                           && thisnib != C_VBR && thisnib != C_SBR)))
                    500:                    goto fail;
                    501:
                    502:                  regno[opnr] = thisnib;
                    503:                }
                    504:              else if ((looking_for & SIZE) == L_5)
                    505:                {
                    506:                  cst[opnr] = data[len / 2] & 31;
                    507:                  cstlen[opnr] = 5;
                    508:                }
                    509:              else if ((looking_for & SIZE) == L_4)
                    510:                {
                    511:                  cst[opnr] = thisnib;
                    512:                  cstlen[opnr] = 4;
                    513:                }
                    514:              else if ((looking_for & SIZE) == L_16
                    515:                       || (looking_for & SIZE) == L_16U)
                    516:                {
                    517:                  cst[opnr] = (data[len / 2]) * 256 + data[(len + 2) / 2];
                    518:                  cstlen[opnr] = 16;
                    519:                }
                    520:              else if ((looking_for & MODE) == MEMIND)
                    521:                {
                    522:                  cst[opnr] = data[1];
                    523:                }
                    524:              else if ((looking_for & MODE) == VECIND)
                    525:                {
                    526:                  cst[opnr] = data[1] & 0x7f;
                    527:                }
                    528:              else if ((looking_for & SIZE) == L_32)
                    529:                {
                    530:                  int i = len / 2;
                    531:
1.1.1.4 ! christos  532:                  cst[opnr] = ((data[i] << 24)
        !           533:                               | (data[i + 1] << 16)
1.1       skrll     534:                               | (data[i + 2] << 8)
                    535:                               | (data[i + 3]));
                    536:
                    537:                  cstlen[opnr] = 32;
                    538:                }
                    539:              else if ((looking_for & SIZE) == L_24)
                    540:                {
                    541:                  int i = len / 2;
                    542:
1.1.1.4 ! christos  543:                  cst[opnr] =
1.1       skrll     544:                    (data[i] << 16) | (data[i + 1] << 8) | (data[i + 2]);
                    545:                  cstlen[opnr] = 24;
                    546:                }
                    547:              else if (looking_for & IGNORE)
                    548:                {
                    549:                  ;
                    550:                }
                    551:              else if (looking_for & DISPREG)
                    552:                {
                    553:                  dispregno[opnr] = thisnib & 7;
                    554:                }
                    555:              else if ((looking_for & MODE) == KBIT)
                    556:                {
                    557:                  switch (thisnib)
                    558:                    {
                    559:                    case 9:
                    560:                      cst[opnr] = 4;
                    561:                      break;
                    562:                    case 8:
                    563:                      cst[opnr] = 2;
                    564:                      break;
                    565:                    case 0:
                    566:                      cst[opnr] = 1;
                    567:                      break;
                    568:                    default:
                    569:                      goto fail;
                    570:                    }
                    571:                }
                    572:              else if ((looking_for & SIZE) == L_8)
                    573:                {
                    574:                  cstlen[opnr] = 8;
                    575:                  cst[opnr] = data[len / 2];
                    576:                }
                    577:              else if ((looking_for & SIZE) == L_3
                    578:                       || (looking_for & SIZE) == L_3NZ)
                    579:                {
                    580:                  cst[opnr] = thisnib & 0x7;
                    581:                  if (cst[opnr] == 0 && (looking_for & SIZE) == L_3NZ)
                    582:                    goto fail;
                    583:                }
                    584:              else if ((looking_for & SIZE) == L_2)
                    585:                {
                    586:                  cstlen[opnr] = 2;
                    587:                  cst[opnr] = thisnib & 0x3;
                    588:                }
                    589:              else if ((looking_for & MODE) == MACREG)
                    590:                {
                    591:                  cst[opnr] = (thisnib == 3);
                    592:                }
                    593:              else if (looking_for == (op_type) E)
                    594:                {
                    595:                  outfn (stream, "%s\t", q->name);
                    596:
                    597:                  /* Gross.  Disgusting.  */
                    598:                  if (strcmp (q->name, "ldm.l") == 0)
                    599:                    {
                    600:                      int count, high;
                    601:
                    602:                      count = (data[1] / 16) & 0x3;
                    603:                      high = regno[1];
                    604:
                    605:                      outfn (stream, "@sp+,er%d-er%d", high - count, high);
                    606:                      return qi->length;
                    607:                    }
                    608:
                    609:                  if (strcmp (q->name, "stm.l") == 0)
                    610:                    {
                    611:                      int count, low;
                    612:
                    613:                      count = (data[1] / 16) & 0x3;
                    614:                      low = regno[0];
                    615:
                    616:                      outfn (stream, "er%d-er%d,@-sp", low, low + count);
                    617:                      return qi->length;
                    618:                    }
                    619:                  if (strcmp (q->name, "rte/l") == 0
                    620:                      || strcmp (q->name, "rts/l") == 0)
                    621:                    {
                    622:                      if (regno[0] == 0)
                    623:                        outfn (stream, "er%d", regno[1]);
                    624:                      else
                    625:                        outfn (stream, "er%d-er%d", regno[1] - regno[0],
                    626:                               regno[1]);
                    627:                      return qi->length;
                    628:                    }
                    629:                  if (CONST_STRNEQ (q->name, "mova"))
                    630:                    {
                    631:                      const op_type *args = q->args.nib;
                    632:
                    633:                      if (args[1] == (op_type) E)
                    634:                        {
                    635:                          /* Short form.  */
1.1.1.4 ! christos  636:                          print_one_arg (info, addr, args[0], cst[0],
        !           637:                                         cstlen[0], dispregno[0], regno[0],
1.1       skrll     638:                                         pregnames, qi->length);
                    639:                          outfn (stream, ",er%d", dispregno[0]);
                    640:                        }
                    641:                      else
                    642:                        {
                    643:                          outfn (stream, "@(0x%x:%d,", cst[0], cstlen[0]);
1.1.1.4 ! christos  644:                          print_one_arg (info, addr, args[1], cst[1],
        !           645:                                         cstlen[1], dispregno[1], regno[1],
1.1       skrll     646:                                         pregnames, qi->length);
                    647:                          outfn (stream, ".%c),",
                    648:                                 (args[0] & MODE) == INDEXB ? 'b' : 'w');
1.1.1.4 ! christos  649:                          print_one_arg (info, addr, args[2], cst[2],
        !           650:                                         cstlen[2], dispregno[2], regno[2],
1.1       skrll     651:                                         pregnames, qi->length);
                    652:                        }
                    653:                      return qi->length;
                    654:                    }
                    655:                  /* Fill in the args.  */
                    656:                  {
                    657:                    const op_type *args = q->args.nib;
                    658:                    int hadone = 0;
                    659:                    int nargs;
                    660:
                    661:                    /* Special case handling for the adds and subs instructions
                    662:                       since in H8 mode thay can only take the r0-r7 registers
                    663:                       but in other (higher) modes they can take the er0-er7
                    664:                       registers as well.  */
                    665:                    if (strcmp (qi->opcode->name, "adds") == 0
                    666:                        || strcmp (qi->opcode->name, "subs") == 0)
                    667:                      {
                    668:                        outfn (stream, "#%d,%s", cst[0], pregnames[regno[1] & 0x7]);
                    669:                        return qi->length;
                    670:                      }
                    671:
1.1.1.4 ! christos  672:                    for (nargs = 0;
1.1       skrll     673:                         nargs < 3 && args[nargs] != (op_type) E;
                    674:                         nargs++)
                    675:                      {
                    676:                        int x = args[nargs];
                    677:
                    678:                        if (hadone)
                    679:                          outfn (stream, ",");
                    680:
                    681:                        print_one_arg (info, addr, x,
                    682:                                       cst[nargs], cstlen[nargs],
                    683:                                       dispregno[nargs], regno[nargs],
                    684:                                       pregnames, qi->length);
                    685:
                    686:                        hadone = 1;
                    687:                      }
                    688:                  }
                    689:
                    690:                  return qi->length;
                    691:                }
                    692:              else
                    693:                /* xgettext:c-format */
                    694:                outfn (stream, _("Don't understand 0x%x \n"), looking_for);
                    695:            }
                    696:
                    697:          len++;
                    698:          nib++;
                    699:        }
                    700:
                    701:     fail:
                    702:       ;
                    703:     }
                    704:
                    705:   /* Fell off the end.  */
                    706:   outfn (stream, ".word\tH'%x,H'%x", data[0], data[1]);
                    707:   return 2;
                    708: }
                    709:
                    710: int
                    711: print_insn_h8300 (bfd_vma addr, disassemble_info *info)
                    712: {
                    713:   return bfd_h8_disassemble (addr, info, 0);
                    714: }
                    715:
                    716: int
                    717: print_insn_h8300h (bfd_vma addr, disassemble_info *info)
                    718: {
                    719:   return bfd_h8_disassemble (addr, info, 1);
                    720: }
                    721:
                    722: int
                    723: print_insn_h8300s (bfd_vma addr, disassemble_info *info)
                    724: {
                    725:   return bfd_h8_disassemble (addr, info, 2);
                    726: }

CVSweb <webmaster@jp.NetBSD.org>