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