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

Annotation of src/external/gpl3/binutils.old/dist/opcodes/rl78-dis.c, Revision 1.7

1.1       christos    1: /* Disassembler code for Renesas RL78.
1.7     ! christos    2:    Copyright (C) 2011-2020 Free Software Foundation, Inc.
1.1       christos    3:    Contributed by Red Hat.
                      4:    Written by DJ Delorie.
                      5:
                      6:    This file is part of the GNU opcodes library.
                      7:
                      8:    This library is free software; you can redistribute it and/or modify
                      9:    it under the terms of the GNU General Public License as published by
                     10:    the Free Software Foundation; either version 3, or (at your option)
                     11:    any later version.
                     12:
                     13:    It is distributed in the hope that it will be useful, but WITHOUT
                     14:    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
                     15:    or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public
                     16:    License for more details.
                     17:
                     18:    You should have received a copy of the GNU General Public License
                     19:    along with this program; if not, write to the Free Software
                     20:    Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
                     21:    MA 02110-1301, USA.  */
                     22:
                     23: #include "sysdep.h"
                     24: #include <stdio.h>
                     25:
                     26: #include "bfd.h"
1.3       christos   27: #include "elf-bfd.h"
1.6       christos   28: #include "disassemble.h"
1.1       christos   29: #include "opcode/rl78.h"
1.3       christos   30: #include "elf/rl78.h"
1.1       christos   31:
1.6       christos   32: #include <setjmp.h>
                     33:
1.1       christos   34: #define DEBUG_SEMANTICS 0
                     35:
                     36: typedef struct
                     37: {
                     38:   bfd_vma pc;
                     39:   disassemble_info * dis;
                     40: } RL78_Data;
                     41:
1.6       christos   42: struct private
                     43: {
                     44:   OPCODES_SIGJMP_BUF bailout;
                     45: };
                     46:
1.1       christos   47: static int
                     48: rl78_get_byte (void * vdata)
                     49: {
                     50:   bfd_byte buf[1];
                     51:   RL78_Data *rl78_data = (RL78_Data *) vdata;
1.6       christos   52:   int status;
                     53:
                     54:   status = rl78_data->dis->read_memory_func (rl78_data->pc,
                     55:                                             buf,
                     56:                                             1,
                     57:                                             rl78_data->dis);
                     58:   if (status != 0)
                     59:     {
                     60:       struct private *priv = (struct private *) rl78_data->dis->private_data;
1.1       christos   61:
1.6       christos   62:       rl78_data->dis->memory_error_func (status, rl78_data->pc,
                     63:                                         rl78_data->dis);
                     64:       OPCODES_SIGLONGJMP (priv->bailout, 1);
                     65:     }
1.1       christos   66:
                     67:   rl78_data->pc ++;
                     68:   return buf[0];
                     69: }
                     70:
                     71: static char const *
                     72: register_names[] =
                     73: {
                     74:   "",
                     75:   "x", "a", "c", "b", "e", "d", "l", "h",
                     76:   "ax", "bc", "de", "hl",
                     77:   "sp", "psw", "cs", "es", "pmc", "mem"
                     78: };
                     79:
                     80: static char const *
                     81: condition_names[] =
                     82: {
                     83:   "t", "f", "c", "nc", "h", "nh", "z", "nz"
                     84: };
                     85:
                     86: static int
                     87: indirect_type (int t)
                     88: {
                     89:   switch (t)
                     90:     {
                     91:     case RL78_Operand_Indirect:
                     92:     case RL78_Operand_BitIndirect:
                     93:     case RL78_Operand_PostInc:
                     94:     case RL78_Operand_PreDec:
                     95:       return 1;
                     96:     default:
                     97:       return 0;
                     98:     }
                     99: }
                    100:
1.3       christos  101: static int
                    102: print_insn_rl78_common (bfd_vma addr, disassemble_info * dis, RL78_Dis_Isa isa)
1.1       christos  103: {
                    104:   int rv;
                    105:   RL78_Data rl78_data;
                    106:   RL78_Opcode_Decoded opcode;
                    107:   const char * s;
                    108: #if DEBUG_SEMANTICS
                    109:   static char buf[200];
                    110: #endif
1.6       christos  111:   struct private priv;
1.1       christos  112:
1.6       christos  113:   dis->private_data = (PTR) &priv;
1.1       christos  114:   rl78_data.pc = addr;
                    115:   rl78_data.dis = dis;
                    116:
1.6       christos  117:   if (OPCODES_SIGSETJMP (priv.bailout) != 0)
                    118:     {
                    119:       /* Error return.  */
                    120:       return -1;
                    121:     }
                    122:
1.3       christos  123:   rv = rl78_decode_opcode (addr, &opcode, rl78_get_byte, &rl78_data, isa);
1.1       christos  124:
                    125:   dis->bytes_per_line = 10;
                    126:
                    127: #define PR (dis->fprintf_func)
                    128: #define PS (dis->stream)
                    129: #define PC(c) PR (PS, "%c", c)
                    130:
                    131:   s = opcode.syntax;
                    132:
                    133: #if DEBUG_SEMANTICS
                    134:
                    135:   switch (opcode.id)
                    136:     {
                    137:     case RLO_unknown: s = "uknown"; break;
                    138:     case RLO_add: s = "add: %e0%0 += %e1%1"; break;
                    139:     case RLO_addc: s = "addc: %e0%0 += %e1%1 + CY"; break;
                    140:     case RLO_and: s = "and: %e0%0 &= %e1%1"; break;
                    141:     case RLO_branch: s = "branch: pc = %e0%0"; break;
                    142:     case RLO_branch_cond: s = "branch_cond: pc = %e0%0 if %c1 / %e1%1"; break;
                    143:     case RLO_branch_cond_clear: s = "branch_cond_clear: pc = %e0%0 if %c1 / %e1%1, %e1%1 = 0"; break;
                    144:     case RLO_call: s = "call: pc = %e1%0"; break;
                    145:     case RLO_cmp: s = "cmp: %e0%0 - %e1%1"; break;
                    146:     case RLO_mov: s = "mov: %e0%0 = %e1%1"; break;
                    147:     case RLO_or: s = "or: %e0%0 |= %e1%1"; break;
                    148:     case RLO_rol: s = "rol: %e0%0 <<= %e1%1"; break;
                    149:     case RLO_rolc: s = "rol: %e0%0 <<= %e1%1,CY"; break;
                    150:     case RLO_ror: s = "ror: %e0%0 >>= %e1%1"; break;
                    151:     case RLO_rorc: s = "ror: %e0%0 >>= %e1%1,CY"; break;
                    152:     case RLO_sar: s = "sar: %e0%0 >>= %e1%1 signed"; break;
                    153:     case RLO_sel: s = "sel: rb = %1"; break;
                    154:     case RLO_shr: s = "shr: %e0%0 >>= %e1%1 unsigned"; break;
                    155:     case RLO_shl: s = "shl: %e0%0 <<= %e1%1"; break;
                    156:     case RLO_skip: s = "skip: if %c1"; break;
                    157:     case RLO_sub: s = "sub: %e0%0 -= %e1%1"; break;
                    158:     case RLO_subc: s = "subc: %e0%0 -= %e1%1 - CY"; break;
                    159:     case RLO_xch: s = "xch: %e0%0 <-> %e1%1"; break;
                    160:     case RLO_xor: s = "xor: %e0%0 ^= %e1%1"; break;
                    161:     }
                    162:
                    163:   sprintf(buf, "%s%%W%%f\t\033[32m%s\033[0m", s, opcode.syntax);
                    164:   s = buf;
                    165:
                    166: #endif
                    167:
                    168:   for (; *s; s++)
                    169:     {
                    170:       if (*s != '%')
                    171:        {
                    172:          PC (*s);
                    173:        }
                    174:       else
                    175:        {
                    176:          RL78_Opcode_Operand * oper;
                    177:          int do_hex = 0;
                    178:          int do_addr = 0;
                    179:          int do_es = 0;
                    180:          int do_sfr = 0;
                    181:          int do_cond = 0;
                    182:          int do_bang = 0;
                    183:
1.3       christos  184:          while (1)
1.1       christos  185:            {
1.3       christos  186:              s ++;
                    187:              switch (*s)
                    188:                {
                    189:                case 'x':
                    190:                  do_hex = 1;
                    191:                  break;
                    192:                case '!':
                    193:                  do_bang = 1;
                    194:                  break;
                    195:                case 'e':
                    196:                  do_es = 1;
                    197:                  break;
                    198:                case 'a':
                    199:                  do_addr = 1;
                    200:                  break;
                    201:                case 's':
                    202:                  do_sfr = 1;
                    203:                  break;
                    204:                case 'c':
                    205:                  do_cond = 1;
                    206:                  break;
                    207:                default:
                    208:                  goto no_more_modifiers;
                    209:                }
1.1       christos  210:            }
1.3       christos  211:        no_more_modifiers:;
1.1       christos  212:
                    213:          switch (*s)
                    214:            {
                    215:            case '%':
                    216:              PC ('%');
                    217:              break;
                    218:
                    219: #if DEBUG_SEMANTICS
                    220:
                    221:            case 'W':
                    222:              if (opcode.size == RL78_Word)
                    223:                PR (PS, " \033[33mW\033[0m");
                    224:              break;
                    225:
                    226:            case 'f':
                    227:              if (opcode.flags)
                    228:                {
                    229:                  char *comma = "";
                    230:                  PR (PS, "  \033[35m");
1.3       christos  231:
1.1       christos  232:                  if (opcode.flags & RL78_PSW_Z)
                    233:                    { PR (PS, "Z"); comma = ","; }
                    234:                  if (opcode.flags & RL78_PSW_AC)
                    235:                    { PR (PS, "%sAC", comma); comma = ","; }
                    236:                  if (opcode.flags & RL78_PSW_CY)
                    237:                    { PR (PS, "%sCY", comma); comma = ","; }
                    238:                  PR (PS, "\033[0m");
                    239:                }
                    240:              break;
                    241:
                    242: #endif
                    243:
                    244:            case '0':
                    245:            case '1':
1.3       christos  246:              oper = *s == '0' ? &opcode.op[0] : &opcode.op[1];
                    247:            if (do_es)
                    248:              {
                    249:                if (oper->use_es && indirect_type (oper->type))
                    250:                  PR (PS, "es:");
                    251:              }
                    252:
                    253:            if (do_bang)
1.5       christos  254:              {
                    255:                /* If we are going to display SP by name, we must omit the bang.  */
                    256:                if ((oper->type == RL78_Operand_Indirect
                    257:                     || oper->type == RL78_Operand_BitIndirect)
                    258:                    && oper->reg == RL78_Reg_None
                    259:                    && do_sfr
                    260:                    && ((oper->addend == 0xffff8 && opcode.size == RL78_Word)
                    261:                        || (oper->addend == 0x0fff8 && do_es && opcode.size == RL78_Word)))
                    262:                  ;
                    263:                else
                    264:                  PC ('!');
                    265:              }
1.3       christos  266:
                    267:            if (do_cond)
                    268:              {
                    269:                PR (PS, "%s", condition_names[oper->condition]);
                    270:                break;
                    271:              }
                    272:
                    273:            switch (oper->type)
                    274:              {
                    275:              case RL78_Operand_Immediate:
                    276:                if (do_addr)
                    277:                  dis->print_address_func (oper->addend, dis);
                    278:                else if (do_hex
                    279:                         || oper->addend > 999
                    280:                         || oper->addend < -999)
                    281:                  PR (PS, "%#x", oper->addend);
                    282:                else
                    283:                  PR (PS, "%d", oper->addend);
                    284:                break;
                    285:
                    286:              case RL78_Operand_Register:
                    287:                PR (PS, "%s", register_names[oper->reg]);
                    288:                break;
                    289:
                    290:              case RL78_Operand_Bit:
                    291:                PR (PS, "%s.%d", register_names[oper->reg], oper->bit_number);
                    292:                break;
                    293:
                    294:              case RL78_Operand_Indirect:
                    295:              case RL78_Operand_BitIndirect:
                    296:                switch (oper->reg)
1.1       christos  297:                  {
1.3       christos  298:                  case RL78_Reg_None:
                    299:                    if (oper->addend == 0xffffa && do_sfr && opcode.size == RL78_Byte)
                    300:                      PR (PS, "psw");
                    301:                    else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Word)
                    302:                      PR (PS, "sp");
1.5       christos  303:                    else if (oper->addend == 0x0fff8 && do_sfr && do_es && opcode.size == RL78_Word)
                    304:                      PR (PS, "sp");
1.3       christos  305:                     else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Byte)
                    306:                       PR (PS, "spl");
                    307:                     else if (oper->addend == 0xffff9 && do_sfr && opcode.size == RL78_Byte)
                    308:                       PR (PS, "sph");
                    309:                     else if (oper->addend == 0xffffc && do_sfr && opcode.size == RL78_Byte)
                    310:                       PR (PS, "cs");
                    311:                     else if (oper->addend == 0xffffd && do_sfr && opcode.size == RL78_Byte)
                    312:                       PR (PS, "es");
                    313:                     else if (oper->addend == 0xffffe && do_sfr && opcode.size == RL78_Byte)
                    314:                       PR (PS, "pmc");
                    315:                     else if (oper->addend == 0xfffff && do_sfr && opcode.size == RL78_Byte)
                    316:                       PR (PS, "mem");
                    317:                    else if (oper->addend >= 0xffe20)
1.1       christos  318:                      PR (PS, "%#x", oper->addend);
                    319:                    else
1.3       christos  320:                      {
                    321:                        int faddr = oper->addend;
                    322:                        if (do_es && ! oper->use_es)
                    323:                          faddr += 0xf0000;
                    324:                        dis->print_address_func (faddr, dis);
                    325:                      }
1.1       christos  326:                    break;
                    327:
1.3       christos  328:                  case RL78_Reg_B:
                    329:                  case RL78_Reg_C:
                    330:                  case RL78_Reg_BC:
                    331:                    PR (PS, "%d[%s]", oper->addend, register_names[oper->reg]);
1.1       christos  332:                    break;
                    333:
1.3       christos  334:                  default:
                    335:                    PR (PS, "[%s", register_names[oper->reg]);
                    336:                    if (oper->reg2 != RL78_Reg_None)
                    337:                      PR (PS, "+%s", register_names[oper->reg2]);
                    338:                    if (oper->addend || do_addr)
                    339:                      PR (PS, "+%d", oper->addend);
                    340:                    PC (']');
1.1       christos  341:                    break;
                    342:
1.3       christos  343:                  }
                    344:                if (oper->type == RL78_Operand_BitIndirect)
                    345:                  PR (PS, ".%d", oper->bit_number);
                    346:                break;
1.1       christos  347:
                    348: #if DEBUG_SEMANTICS
1.3       christos  349:                /* Shouldn't happen - push and pop don't print
                    350:                   [SP] directly.  But we *do* use them for
                    351:                   semantic debugging.  */
                    352:              case RL78_Operand_PostInc:
                    353:                PR (PS, "[%s++]", register_names[oper->reg]);
                    354:                break;
                    355:              case RL78_Operand_PreDec:
                    356:                PR (PS, "[--%s]", register_names[oper->reg]);
                    357:                break;
1.1       christos  358: #endif
                    359:
1.3       christos  360:              default:
                    361:                /* If we ever print this, that means the
                    362:                   programmer tried to print an operand with a
                    363:                   type we don't expect.  Print the line and
                    364:                   operand number from rl78-decode.opc for
                    365:                   them.  */
                    366:                PR (PS, "???%d.%d", opcode.lineno, *s - '0');
                    367:                break;
                    368:              }
1.1       christos  369:            }
                    370:        }
                    371:     }
                    372:
                    373: #if DEBUG_SEMANTICS
                    374:
                    375:   PR (PS, "\t\033[34m(line %d)\033[0m", opcode.lineno);
                    376:
                    377: #endif
                    378:
                    379:   return rv;
                    380: }
1.3       christos  381:
                    382: int
                    383: print_insn_rl78 (bfd_vma addr, disassemble_info * dis)
                    384: {
                    385:   return print_insn_rl78_common (addr, dis, RL78_ISA_DEFAULT);
                    386: }
                    387:
                    388: int
                    389: print_insn_rl78_g10 (bfd_vma addr, disassemble_info * dis)
                    390: {
                    391:   return print_insn_rl78_common (addr, dis, RL78_ISA_G10);
                    392: }
                    393:
                    394: int
                    395: print_insn_rl78_g13 (bfd_vma addr, disassemble_info * dis)
                    396: {
                    397:   return print_insn_rl78_common (addr, dis, RL78_ISA_G13);
                    398: }
                    399:
                    400: int
                    401: print_insn_rl78_g14 (bfd_vma addr, disassemble_info * dis)
                    402: {
                    403:   return print_insn_rl78_common (addr, dis, RL78_ISA_G14);
                    404: }
                    405:
                    406: disassembler_ftype
                    407: rl78_get_disassembler (bfd *abfd)
                    408: {
1.6       christos  409:   int cpu = E_FLAG_RL78_ANY_CPU;
                    410:
                    411:   if (abfd != NULL)
                    412:     cpu = abfd->tdata.elf_obj_data->elf_header->e_flags & E_FLAG_RL78_CPU_MASK;
                    413:
1.3       christos  414:   switch (cpu)
                    415:     {
                    416:     case E_FLAG_RL78_G10:
                    417:       return print_insn_rl78_g10;
                    418:     case E_FLAG_RL78_G13:
                    419:       return print_insn_rl78_g13;
                    420:     case E_FLAG_RL78_G14:
                    421:       return print_insn_rl78_g14;
                    422:     default:
                    423:       return print_insn_rl78;
                    424:     }
                    425: }

CVSweb <webmaster@jp.NetBSD.org>