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