1 /* Disassembler code for Renesas RL78. 2 Copyright (C) 2011-2015 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 PC ('!'); 231 232 if (do_cond) 233 { 234 PR (PS, "%s", condition_names[oper->condition]); 235 break; 236 } 237 238 switch (oper->type) 239 { 240 case RL78_Operand_Immediate: 241 if (do_addr) 242 dis->print_address_func (oper->addend, dis); 243 else if (do_hex 244 || oper->addend > 999 245 || oper->addend < -999) 246 PR (PS, "%#x", oper->addend); 247 else 248 PR (PS, "%d", oper->addend); 249 break; 250 251 case RL78_Operand_Register: 252 PR (PS, "%s", register_names[oper->reg]); 253 break; 254 255 case RL78_Operand_Bit: 256 PR (PS, "%s.%d", register_names[oper->reg], oper->bit_number); 257 break; 258 259 case RL78_Operand_Indirect: 260 case RL78_Operand_BitIndirect: 261 switch (oper->reg) 262 { 263 case RL78_Reg_None: 264 if (oper->addend == 0xffffa && do_sfr && opcode.size == RL78_Byte) 265 PR (PS, "psw"); 266 else if (oper->addend == 0xffff8 && do_sfr && opcode.size == RL78_Word) 267 PR (PS, "sp"); 268 else if (oper->addend >= 0xffe20) 269 PR (PS, "%#x", oper->addend); 270 else 271 { 272 int faddr = oper->addend; 273 if (do_es && ! oper->use_es) 274 faddr += 0xf0000; 275 dis->print_address_func (faddr, dis); 276 } 277 break; 278 279 case RL78_Reg_B: 280 case RL78_Reg_C: 281 case RL78_Reg_BC: 282 PR (PS, "%d[%s]", oper->addend, register_names[oper->reg]); 283 break; 284 285 default: 286 PR (PS, "[%s", register_names[oper->reg]); 287 if (oper->reg2 != RL78_Reg_None) 288 PR (PS, "+%s", register_names[oper->reg2]); 289 if (oper->addend || do_addr) 290 PR (PS, "+%d", oper->addend); 291 PC (']'); 292 break; 293 294 } 295 if (oper->type == RL78_Operand_BitIndirect) 296 PR (PS, ".%d", oper->bit_number); 297 break; 298 299 #if DEBUG_SEMANTICS 300 /* Shouldn't happen - push and pop don't print 301 [SP] directly. But we *do* use them for 302 semantic debugging. */ 303 case RL78_Operand_PostInc: 304 PR (PS, "[%s++]", register_names[oper->reg]); 305 break; 306 case RL78_Operand_PreDec: 307 PR (PS, "[--%s]", register_names[oper->reg]); 308 break; 309 #endif 310 311 default: 312 /* If we ever print this, that means the 313 programmer tried to print an operand with a 314 type we don't expect. Print the line and 315 operand number from rl78-decode.opc for 316 them. */ 317 PR (PS, "???%d.%d", opcode.lineno, *s - '0'); 318 break; 319 } 320 } 321 } 322 } 323 324 #if DEBUG_SEMANTICS 325 326 PR (PS, "\t\033[34m(line %d)\033[0m", opcode.lineno); 327 328 #endif 329 330 return rv; 331 } 332 333 int 334 print_insn_rl78 (bfd_vma addr, disassemble_info * dis) 335 { 336 return print_insn_rl78_common (addr, dis, RL78_ISA_DEFAULT); 337 } 338 339 int 340 print_insn_rl78_g10 (bfd_vma addr, disassemble_info * dis) 341 { 342 return print_insn_rl78_common (addr, dis, RL78_ISA_G10); 343 } 344 345 int 346 print_insn_rl78_g13 (bfd_vma addr, disassemble_info * dis) 347 { 348 return print_insn_rl78_common (addr, dis, RL78_ISA_G13); 349 } 350 351 int 352 print_insn_rl78_g14 (bfd_vma addr, disassemble_info * dis) 353 { 354 return print_insn_rl78_common (addr, dis, RL78_ISA_G14); 355 } 356 357 disassembler_ftype 358 rl78_get_disassembler (bfd *abfd) 359 { 360 int cpu = abfd->tdata.elf_obj_data->elf_header->e_flags & E_FLAG_RL78_CPU_MASK; 361 switch (cpu) 362 { 363 case E_FLAG_RL78_G10: 364 return print_insn_rl78_g10; 365 case E_FLAG_RL78_G13: 366 return print_insn_rl78_g13; 367 case E_FLAG_RL78_G14: 368 return print_insn_rl78_g14; 369 default: 370 return print_insn_rl78; 371 } 372 } 373