1 /* Disassemble h8500 instructions. 2 Copyright (C) 1993-2014 Free Software Foundation, Inc. 3 4 This file is part of the GNU opcodes library. 5 6 This library is free software; you can redistribute it and/or modify 7 it under the terms of the GNU General Public License as published by 8 the Free Software Foundation; either version 3, or (at your option) 9 any later version. 10 11 It is distributed in the hope that it will be useful, but WITHOUT 12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY 13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public 14 License for more details. 15 16 You should have received a copy of the GNU General Public License 17 along with this program; if not, write to the Free Software 18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 19 MA 02110-1301, USA. */ 20 21 #include "sysdep.h" 22 #include <stdio.h> 23 24 #define DISASSEMBLER_TABLE 25 #define DEFINE_TABLE 26 27 #include "h8500-opc.h" 28 #include "dis-asm.h" 29 #include "opintl.h" 30 31 /* Maximum length of an instruction. */ 32 #define MAXLEN 8 33 34 #include <setjmp.h> 35 36 struct private 37 { 38 /* Points to first byte not fetched. */ 39 bfd_byte *max_fetched; 40 bfd_byte the_buffer[MAXLEN]; 41 bfd_vma insn_start; 42 OPCODES_SIGJMP_BUF bailout; 43 }; 44 45 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive) 46 to ADDR (exclusive) are valid. Returns 1 for success, longjmps 47 on error. */ 48 #define FETCH_DATA(info, addr) \ 49 ((addr) <= ((struct private *)(info->private_data))->max_fetched \ 50 ? 1 : fetch_data ((info), (addr))) 51 52 static int 53 fetch_data (struct disassemble_info *info, bfd_byte *addr) 54 { 55 int status; 56 struct private *priv = (struct private *) info->private_data; 57 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer); 58 59 status = (*info->read_memory_func) (start, 60 priv->max_fetched, 61 addr - priv->max_fetched, 62 info); 63 if (status != 0) 64 { 65 (*info->memory_error_func) (status, start, info); 66 OPCODES_SIGLONGJMP (priv->bailout, 1); 67 } 68 else 69 priv->max_fetched = addr; 70 return 1; 71 } 72 73 static char *crname[] = { "sr", "ccr", "*", "br", "ep", "dp", "*", "tp" }; 74 75 int 76 print_insn_h8500 (bfd_vma addr, disassemble_info *info) 77 { 78 const h8500_opcode_info *opcode; 79 void *stream = info->stream; 80 fprintf_ftype func = info->fprintf_func; 81 struct private priv; 82 bfd_byte *buffer = priv.the_buffer; 83 84 info->private_data = (PTR) & priv; 85 priv.max_fetched = priv.the_buffer; 86 priv.insn_start = addr; 87 if (OPCODES_SIGSETJMP (priv.bailout) != 0) 88 /* Error return. */ 89 return -1; 90 91 /* Run down the table to find the one which matches. */ 92 for (opcode = h8500_table; opcode->name; opcode++) 93 { 94 int byte; 95 int rn = 0; 96 int rd = 0; 97 int rs = 0; 98 int disp = 0; 99 int abs_val = 0; 100 int imm = 0; 101 int pcrel = 0; 102 int qim = 0; 103 int i; 104 int cr = 0; 105 106 for (byte = 0; byte < opcode->length; byte++) 107 { 108 FETCH_DATA (info, buffer + byte + 1); 109 if ((buffer[byte] & opcode->bytes[byte].mask) 110 != (opcode->bytes[byte].contents)) 111 goto next; 112 113 else 114 { 115 /* Extract any info parts. */ 116 switch (opcode->bytes[byte].insert) 117 { 118 case 0: 119 case FP: 120 break; 121 default: 122 /* xgettext:c-format */ 123 func (stream, _("can't cope with insert %d\n"), 124 opcode->bytes[byte].insert); 125 break; 126 case RN: 127 rn = buffer[byte] & 0x7; 128 break; 129 case RS: 130 rs = buffer[byte] & 0x7; 131 break; 132 case CRB: 133 cr = buffer[byte] & 0x7; 134 if (cr == 0) 135 goto next; 136 break; 137 case CRW: 138 cr = buffer[byte] & 0x7; 139 if (cr != 0) 140 goto next; 141 break; 142 case DISP16: 143 FETCH_DATA (info, buffer + byte + 2); 144 disp = (buffer[byte] << 8) | (buffer[byte + 1]); 145 break; 146 case FPIND_D8: 147 case DISP8: 148 disp = ((char) (buffer[byte])); 149 break; 150 case RD: 151 case RDIND: 152 rd = buffer[byte] & 0x7; 153 break; 154 case ABS24: 155 FETCH_DATA (info, buffer + byte + 3); 156 abs_val = 157 (buffer[byte] << 16) 158 | (buffer[byte + 1] << 8) 159 | (buffer[byte + 2]); 160 break; 161 case ABS16: 162 FETCH_DATA (info, buffer + byte + 2); 163 abs_val = (buffer[byte] << 8) | (buffer[byte + 1]); 164 break; 165 case ABS8: 166 abs_val = (buffer[byte]); 167 break; 168 case IMM16: 169 FETCH_DATA (info, buffer + byte + 2); 170 imm = (buffer[byte] << 8) | (buffer[byte + 1]); 171 break; 172 case IMM4: 173 imm = (buffer[byte]) & 0xf; 174 break; 175 case IMM8: 176 case RLIST: 177 imm = (buffer[byte]); 178 break; 179 case PCREL16: 180 FETCH_DATA (info, buffer + byte + 2); 181 pcrel = (buffer[byte] << 8) | (buffer[byte + 1]); 182 break; 183 case PCREL8: 184 pcrel = (buffer[byte]); 185 break; 186 case QIM: 187 switch (buffer[byte] & 0x7) 188 { 189 case 0: 190 qim = 1; 191 break; 192 case 1: 193 qim = 2; 194 break; 195 case 4: 196 qim = -1; 197 break; 198 case 5: 199 qim = -2; 200 break; 201 } 202 break; 203 204 } 205 } 206 } 207 /* We get here when all the masks have passed so we can output 208 the operands. */ 209 FETCH_DATA (info, buffer + opcode->length); 210 (func) (stream, "%s\t", opcode->name); 211 for (i = 0; i < opcode->nargs; i++) 212 { 213 if (i) 214 (func) (stream, ","); 215 switch (opcode->arg_type[i]) 216 { 217 case FP: 218 func (stream, "fp"); 219 break; 220 case RNIND_D16: 221 func (stream, "@(0x%x:16,r%d)", disp, rn); 222 break; 223 case RNIND_D8: 224 func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn); 225 break; 226 case RDIND_D16: 227 func (stream, "@(0x%x:16,r%d)", disp, rd); 228 break; 229 case RDIND_D8: 230 func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd); 231 break; 232 case FPIND_D8: 233 func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp); 234 break; 235 case CRB: 236 case CRW: 237 func (stream, "%s", crname[cr]); 238 break; 239 case RN: 240 func (stream, "r%d", rn); 241 break; 242 case RD: 243 func (stream, "r%d", rd); 244 break; 245 case RS: 246 func (stream, "r%d", rs); 247 break; 248 case RNDEC: 249 func (stream, "@-r%d", rn); 250 break; 251 case RNINC: 252 func (stream, "@r%d+", rn); 253 break; 254 case RNIND: 255 func (stream, "@r%d", rn); 256 break; 257 case RDIND: 258 func (stream, "@r%d", rd); 259 break; 260 case SPINC: 261 func (stream, "@sp+"); 262 break; 263 case SPDEC: 264 func (stream, "@-sp"); 265 break; 266 case ABS24: 267 func (stream, "@0x%0x:24", abs_val); 268 break; 269 case ABS16: 270 func (stream, "@0x%0x:16", abs_val & 0xffff); 271 break; 272 case ABS8: 273 func (stream, "@0x%0x:8", abs_val & 0xff); 274 break; 275 case IMM16: 276 func (stream, "#0x%0x:16", imm & 0xffff); 277 break; 278 case RLIST: 279 { 280 int j; 281 int nc = 0; 282 283 func (stream, "("); 284 for (j = 0; j < 8; j++) 285 { 286 if (imm & (1 << j)) 287 { 288 func (stream, "r%d", j); 289 if (nc) 290 func (stream, ","); 291 nc = 1; 292 } 293 } 294 func (stream, ")"); 295 } 296 break; 297 case IMM8: 298 func (stream, "#0x%0x:8", imm & 0xff); 299 break; 300 case PCREL16: 301 func (stream, "0x%0x:16", 302 (int)(pcrel + addr + opcode->length) & 0xffff); 303 break; 304 case PCREL8: 305 func (stream, "#0x%0x:8", 306 (int)((char) pcrel + addr + opcode->length) & 0xffff); 307 break; 308 case QIM: 309 func (stream, "#%d:q", qim); 310 break; 311 case IMM4: 312 func (stream, "#%d:4", imm); 313 break; 314 } 315 } 316 return opcode->length; 317 next: 318 ; 319 } 320 321 /* Couldn't understand anything. */ 322 /* xgettext:c-format */ 323 func (stream, _("%02x\t\t*unknown*"), buffer[0]); 324 return 1; 325 } 326