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