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