| OLD | NEW |
| 1 /* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly | 1 /* m68hc11-dis.c -- Motorola 68HC11 & 68HC12 disassembly |
| 2 Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007 | 2 Copyright 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2007, 2012 |
| 3 Free Software Foundation, Inc. | 3 Free Software Foundation, Inc. |
| 4 Written by Stephane Carrez (stcarrez@nerim.fr) | 4 Written by Stephane Carrez (stcarrez@nerim.fr) |
| 5 XGATE and S12X added by James Murray (jsm@jsm-net.demon.co.uk) |
| 5 | 6 |
| 6 This file is part of the GNU opcodes library. | 7 This file is part of the GNU opcodes library. |
| 7 | 8 |
| 8 This library is free software; you can redistribute it and/or modify | 9 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 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 the Free Software Foundation; either version 3, or (at your option) |
| 11 any later version. | 12 any later version. |
| 12 | 13 |
| 13 It is distributed in the hope that it will be useful, but WITHOUT | 14 It is distributed in the hope that it will be useful, but WITHOUT |
| 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY | 15 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY |
| 15 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public | 16 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public |
| 16 License for more details. | 17 License for more details. |
| 17 | 18 |
| 18 You should have received a copy of the GNU General Public License | 19 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 along with this program; if not, write to the Free Software |
| 20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, | 21 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, |
| 21 MA 02110-1301, USA. */ | 22 MA 02110-1301, USA. */ |
| 22 | 23 |
| 24 #include "sysdep.h" |
| 23 #include <stdio.h> | 25 #include <stdio.h> |
| 24 | 26 |
| 25 #include "ansidecl.h" | |
| 26 #include "opcode/m68hc11.h" | 27 #include "opcode/m68hc11.h" |
| 27 #include "dis-asm.h" | 28 #include "dis-asm.h" |
| 28 | 29 |
| 29 #define PC_REGNUM 3 | 30 #define PC_REGNUM 3 |
| 30 | 31 |
| 31 static const char *const reg_name[] = { | 32 static const char *const reg_name[] = |
| 33 { |
| 32 "X", "Y", "SP", "PC" | 34 "X", "Y", "SP", "PC" |
| 33 }; | 35 }; |
| 34 | 36 |
| 35 static const char *const reg_src_table[] = { | 37 static const char *const reg_src_table[] = |
| 38 { |
| 36 "A", "B", "CCR", "TMP3", "D", "X", "Y", "SP" | 39 "A", "B", "CCR", "TMP3", "D", "X", "Y", "SP" |
| 37 }; | 40 }; |
| 38 | 41 |
| 39 static const char *const reg_dst_table[] = { | 42 static const char *const reg_dst_table[] = |
| 43 { |
| 40 "A", "B", "CCR", "TMP2", "D", "X", "Y", "SP" | 44 "A", "B", "CCR", "TMP2", "D", "X", "Y", "SP" |
| 41 }; | 45 }; |
| 42 | 46 |
| 43 #define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4) | 47 #define OP_PAGE_MASK (M6811_OP_PAGE2|M6811_OP_PAGE3|M6811_OP_PAGE4) |
| 44 | 48 |
| 45 /* Prototypes for local functions. */ | 49 /* Prototypes for local functions. */ |
| 46 static int read_memory (bfd_vma, bfd_byte *, int, struct disassemble_info *); | 50 static int read_memory (bfd_vma, bfd_byte *, int, struct disassemble_info *); |
| 47 static int print_indexed_operand (bfd_vma, struct disassemble_info *, | 51 static int print_indexed_operand (bfd_vma, struct disassemble_info *, |
| 48 int*, int, int, bfd_vma); | 52 int*, int, int, bfd_vma, int); |
| 49 static int print_insn (bfd_vma, struct disassemble_info *, int); | 53 static int print_insn (bfd_vma, struct disassemble_info *, int); |
| 50 | 54 |
| 51 static int | 55 static int |
| 52 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, | 56 read_memory (bfd_vma memaddr, bfd_byte* buffer, int size, |
| 53 struct disassemble_info* info) | 57 struct disassemble_info* info) |
| 54 { | 58 { |
| 55 int status; | 59 int status; |
| 56 | 60 |
| 57 /* Get first byte. Only one at a time because we don't know the | 61 /* Get first byte. Only one at a time because we don't know the |
| 58 size of the insn. */ | 62 size of the insn. */ |
| 59 status = (*info->read_memory_func) (memaddr, buffer, size, info); | 63 status = (*info->read_memory_func) (memaddr, buffer, size, info); |
| 60 if (status != 0) | 64 if (status != 0) |
| 61 { | 65 { |
| 62 (*info->memory_error_func) (status, memaddr, info); | 66 (*info->memory_error_func) (status, memaddr, info); |
| 63 return -1; | 67 return -1; |
| 64 } | 68 } |
| 65 return 0; | 69 return 0; |
| 66 } | 70 } |
| 67 | 71 |
| 68 | 72 |
| 69 /* Read the 68HC12 indexed operand byte and print the corresponding mode. | 73 /* Read the 68HC12 indexed operand byte and print the corresponding mode. |
| 70 Returns the number of bytes read or -1 if failure. */ | 74 Returns the number of bytes read or -1 if failure. */ |
| 71 static int | 75 static int |
| 72 print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info, | 76 print_indexed_operand (bfd_vma memaddr, struct disassemble_info* info, |
| 73 int* indirect, int mov_insn, int pc_offset, | 77 int* indirect, int mov_insn, int pc_offset, |
| 74 bfd_vma endaddr) | 78 bfd_vma endaddr, int arch) |
| 75 { | 79 { |
| 76 bfd_byte buffer[4]; | 80 bfd_byte buffer[4]; |
| 77 int reg; | 81 int reg; |
| 78 int status; | 82 int status; |
| 79 short sval; | 83 short sval; |
| 80 int pos = 1; | 84 int pos = 1; |
| 81 | 85 |
| 82 if (indirect) | 86 if (indirect) |
| 83 *indirect = 0; | 87 *indirect = 0; |
| 84 | 88 |
| 85 status = read_memory (memaddr, &buffer[0], 1, info); | 89 status = read_memory (memaddr, &buffer[0], 1, info); |
| 86 if (status != 0) | 90 if (status != 0) |
| 87 { | 91 { |
| 88 return status; | 92 return status; |
| 89 } | 93 } |
| 90 | 94 |
| 91 /* n,r with 5-bits signed constant. */ | 95 /* n,r with 5-bits signed constant. */ |
| 92 if ((buffer[0] & 0x20) == 0) | 96 if ((buffer[0] & 0x20) == 0) |
| 93 { | 97 { |
| 94 reg = (buffer[0] >> 6) & 3; | 98 reg = (buffer[0] >> 6) & 3; |
| 95 sval = (buffer[0] & 0x1f); | 99 sval = (buffer[0] & 0x1f); |
| 96 if (sval & 0x10) | 100 if (sval & 0x10) |
| 97 sval |= 0xfff0; | 101 sval |= 0xfff0; |
| 98 /* 68HC12 requires an adjustment for movb/movw pc relative modes. */ | 102 /* 68HC12 requires an adjustment for movb/movw pc relative modes. */ |
| 99 if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn) | 103 if (reg == PC_REGNUM && info->mach == bfd_mach_m6812 && mov_insn) |
| 100 sval += pc_offset; | 104 sval += pc_offset; |
| 101 (*info->fprintf_func) (info->stream, "%d,%s", | 105 (*info->fprintf_func) (info->stream, "0x%x,%s", |
| 102 » » » (int) sval, reg_name[reg]); | 106 » » » (unsigned short) sval, reg_name[reg]); |
| 103 | 107 |
| 104 if (reg == PC_REGNUM) | 108 if (reg == PC_REGNUM) |
| 105 { | 109 { |
| 106 (* info->fprintf_func) (info->stream, " {"); | 110 (* info->fprintf_func) (info->stream, " {"); |
| 111 if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutil
s. */ |
| 112 (*info->fprintf_func) (info->stream, "0x"); |
| 107 (* info->print_address_func) (endaddr + sval, info); | 113 (* info->print_address_func) (endaddr + sval, info); |
| 108 (* info->fprintf_func) (info->stream, "}"); | 114 (* info->fprintf_func) (info->stream, "}"); |
| 109 } | 115 } |
| 110 } | 116 } |
| 111 | 117 |
| 112 /* Auto pre/post increment/decrement. */ | 118 /* Auto pre/post increment/decrement. */ |
| 113 else if ((buffer[0] & 0xc0) != 0xc0) | 119 else if ((buffer[0] & 0xc0) != 0xc0) |
| 114 { | 120 { |
| 115 const char *mode; | 121 const char *mode; |
| 116 | 122 |
| 117 reg = (buffer[0] >> 6) & 3; | 123 reg = (buffer[0] >> 6) & 3; |
| 118 sval = (buffer[0] & 0x0f); | 124 sval = (buffer[0] & 0x0f); |
| 119 if (sval & 0x8) | 125 if (sval & 0x8) |
| 120 { | 126 { |
| 121 sval |= 0xfff0; | 127 sval |= 0xfff0; |
| 122 sval = -sval; | 128 sval = -sval; |
| 123 mode = "-"; | 129 mode = "-"; |
| 124 } | 130 } |
| 125 else | 131 else |
| 126 { | 132 { |
| 127 sval = sval + 1; | 133 sval = sval + 1; |
| 128 mode = "+"; | 134 mode = "+"; |
| 129 } | 135 } |
| 130 (*info->fprintf_func) (info->stream, "%d,%s%s%s", | 136 (*info->fprintf_func) (info->stream, "%d,%s%s%s", |
| 131 » » » (int) sval, | 137 » » » (unsigned short) sval, |
| 132 (buffer[0] & 0x10 ? "" : mode), | 138 (buffer[0] & 0x10 ? "" : mode), |
| 133 reg_name[reg], (buffer[0] & 0x10 ? mode : "")); | 139 reg_name[reg], (buffer[0] & 0x10 ? mode : "")); |
| 134 } | 140 } |
| 135 | 141 |
| 136 /* [n,r] 16-bits offset indexed indirect. */ | 142 /* [n,r] 16-bits offset indexed indirect. */ |
| 137 else if ((buffer[0] & 0x07) == 3) | 143 else if ((buffer[0] & 0x07) == 3) |
| 138 { | 144 { |
| 139 if (mov_insn) | 145 if ((mov_insn) && (!(arch & cpu9s12x))) |
| 140 » { | 146 » { |
| 141 » (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>", | 147 » (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>", |
| 142 » » » » buffer[0] & 0x0ff); | 148 » » » » buffer[0] & 0x0ff); |
| 143 » return 0; | 149 » return 0; |
| 144 » } | 150 » } |
| 145 reg = (buffer[0] >> 3) & 0x03; | 151 reg = (buffer[0] >> 3) & 0x03; |
| 146 status = read_memory (memaddr + pos, &buffer[0], 2, info); | 152 status = read_memory (memaddr + pos, &buffer[0], 2, info); |
| 147 if (status != 0) | 153 if (status != 0) |
| 148 { | 154 { |
| 149 return status; | 155 return status; |
| 150 } | 156 } |
| 151 | 157 |
| 152 pos += 2; | 158 pos += 2; |
| 153 sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); | 159 sval = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); |
| 154 (*info->fprintf_func) (info->stream, "[%u,%s]", | 160 (*info->fprintf_func) (info->stream, "[0x%x,%s]", |
| 155 sval & 0x0ffff, reg_name[reg]); | 161 sval & 0x0ffff, reg_name[reg]); |
| 156 if (indirect) | 162 if (indirect) |
| 157 *indirect = 1; | 163 *indirect = 1; |
| 158 } | 164 } |
| 159 | 165 |
| 160 /* n,r with 9 and 16 bit signed constant. */ | 166 /* n,r with 9 and 16 bit signed constant. */ |
| 161 else if ((buffer[0] & 0x4) == 0) | 167 else if ((buffer[0] & 0x4) == 0) |
| 162 { | 168 { |
| 163 if (mov_insn) | 169 if ((mov_insn) && (!(arch & cpu9s12x))) |
| 164 » { | 170 » { |
| 165 » (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>", | 171 » (*info->fprintf_func) (info->stream, "<invalid op: 0x%x>", |
| 166 » » » » buffer[0] & 0x0ff); | 172 » » » » buffer[0] & 0x0ff); |
| 167 » return 0; | 173 » return 0; |
| 168 » } | 174 » } |
| 175 |
| 169 reg = (buffer[0] >> 3) & 0x03; | 176 reg = (buffer[0] >> 3) & 0x03; |
| 170 status = read_memory (memaddr + pos, | 177 status = read_memory (memaddr + pos, |
| 171 &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info); | 178 &buffer[1], (buffer[0] & 0x2 ? 2 : 1), info); |
| 172 if (status != 0) | 179 if (status != 0) |
| 173 { | 180 { |
| 174 return status; | 181 return status; |
| 175 } | 182 } |
| 176 if (buffer[0] & 2) | 183 if (buffer[0] & 2) |
| 177 { | 184 { |
| 178 sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF)); | 185 sval = ((buffer[1] << 8) | (buffer[2] & 0x0FF)); |
| 179 sval &= 0x0FFFF; | 186 sval &= 0x0FFFF; |
| 180 pos += 2; | 187 pos += 2; |
| 181 endaddr += 2; | 188 endaddr += 2; |
| 182 } | 189 } |
| 183 else | 190 else |
| 184 { | 191 { |
| 185 sval = buffer[1] & 0x00ff; | 192 sval = buffer[1] & 0x00ff; |
| 186 if (buffer[0] & 0x01) | 193 if (buffer[0] & 0x01) |
| 187 sval |= 0xff00; | 194 sval |= 0xff00; |
| 188 pos++; | 195 pos++; |
| 189 endaddr++; | 196 endaddr++; |
| 190 } | 197 } |
| 191 (*info->fprintf_func) (info->stream, "%d,%s", | 198 (*info->fprintf_func) (info->stream, "0x%x,%s", |
| 192 » » » (int) sval, reg_name[reg]); | 199 » » » (unsigned short) sval, reg_name[reg]); |
| 193 if (reg == PC_REGNUM) | 200 if (reg == PC_REGNUM) |
| 194 { | 201 { |
| 195 (* info->fprintf_func) (info->stream, " {"); | 202 (* info->fprintf_func) (info->stream, " {0x"); |
| 196 (* info->print_address_func) (endaddr + sval, info); | 203 (* info->print_address_func) (endaddr + sval, info); |
| 197 (* info->fprintf_func) (info->stream, "}"); | 204 (* info->fprintf_func) (info->stream, "}"); |
| 198 } | 205 } |
| 199 } | 206 } |
| 200 else | 207 else |
| 201 { | 208 { |
| 202 reg = (buffer[0] >> 3) & 0x03; | 209 reg = (buffer[0] >> 3) & 0x03; |
| 203 switch (buffer[0] & 3) | 210 switch (buffer[0] & 3) |
| 204 { | 211 { |
| 205 case 0: | 212 case 0: |
| (...skipping 17 matching lines...) Expand all Loading... |
| 223 return pos; | 230 return pos; |
| 224 } | 231 } |
| 225 | 232 |
| 226 /* Disassemble one instruction at address 'memaddr'. Returns the number | 233 /* Disassemble one instruction at address 'memaddr'. Returns the number |
| 227 of bytes used by that instruction. */ | 234 of bytes used by that instruction. */ |
| 228 static int | 235 static int |
| 229 print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) | 236 print_insn (bfd_vma memaddr, struct disassemble_info* info, int arch) |
| 230 { | 237 { |
| 231 int status; | 238 int status; |
| 232 bfd_byte buffer[4]; | 239 bfd_byte buffer[4]; |
| 233 unsigned char code; | 240 unsigned int code; |
| 234 long format, pos, i; | 241 long format, pos, i; |
| 235 short sval; | 242 short sval; |
| 236 const struct m68hc11_opcode *opcode; | 243 const struct m68hc11_opcode *opcode; |
| 237 | 244 |
| 245 if (arch & cpuxgate) |
| 246 { |
| 247 int val; |
| 248 /* Get two bytes as all XGATE instructions are 16bit. */ |
| 249 status = read_memory (memaddr, buffer, 2, info); |
| 250 if (status != 0) |
| 251 return status; |
| 252 |
| 253 format = 0; |
| 254 code = (buffer[0] << 8) + buffer[1]; |
| 255 |
| 256 /* Scan the opcode table until we find the opcode |
| 257 with the corresponding page. */ |
| 258 opcode = m68hc11_opcodes; |
| 259 for (i = 0; i < m68hc11_num_opcodes; i++, opcode++) |
| 260 { |
| 261 if ((opcode->opcode != (code & opcode->xg_mask)) || (opcode->arch != c
puxgate)) |
| 262 continue; |
| 263 /* We have found the opcode. Extract the operand and print it. */ |
| 264 (*info->fprintf_func) (info->stream, "%s", opcode->name); |
| 265 format = opcode->format; |
| 266 if (format & (M68XG_OP_NONE)) |
| 267 { |
| 268 /* Nothing to print. */ |
| 269 } |
| 270 else if (format & M68XG_OP_IMM3) |
| 271 (*info->fprintf_func) (info->stream, " #0x%x", (code >> 8) & 0x7); |
| 272 else if (format & M68XG_OP_R_R) |
| 273 (*info->fprintf_func) (info->stream, " R%x, R%x", |
| 274 (code >> 8) & 0x7, (code >> 5) & 0x7); |
| 275 else if (format & M68XG_OP_R_R_R) |
| 276 (*info->fprintf_func) (info->stream, " R%x, R%x, R%x", |
| 277 (code >> 8) & 0x7, (code >> 5) & 0x7, (code >
> 2) & 0x7); |
| 278 else if (format & M68XG_OP_RD_RB_RI) |
| 279 (*info->fprintf_func) (info->stream, " R%x, (R%x, R%x)", |
| 280 (code >> 8) & 0x7, (code >> 5) & 0x7, (code >
> 2) & 0x7); |
| 281 else if (format & M68XG_OP_RD_RB_RIp) |
| 282 (*info->fprintf_func) (info->stream, " R%x, (R%x, R%x+)", |
| 283 (code >> 8) & 0x7, (code >> 5) & 0x7, (code >
> 2) & 0x7); |
| 284 else if (format & M68XG_OP_RD_RB_mRI) |
| 285 (*info->fprintf_func) (info->stream, " R%x, (R%x, -R%x)", |
| 286 (code >> 8) & 0x7, (code >> 5) & 0x7, (code >
> 2) & 0x7); |
| 287 else if (format & M68XG_OP_R_R_OFFS5) |
| 288 (*info->fprintf_func) (info->stream, " R%x, (R%x, #0x%x)", |
| 289 (code >> 8) & 0x7, (code >> 5) & 0x7, code &
0x1f); |
| 290 else if (format & M68XG_OP_R_IMM8) |
| 291 (*info->fprintf_func) (info->stream, " R%x, #0x%02x", |
| 292 (code >> 8) & 0x7, code & 0xff); |
| 293 else if (format & M68XG_OP_R_IMM4) |
| 294 (*info->fprintf_func) (info->stream, " R%x, #0x%x", |
| 295 (code >> 8) & 0x7, (code & 0xf0) >> 4); |
| 296 else if (format & M68XG_OP_REL9) |
| 297 { |
| 298 (*info->fprintf_func) (info->stream, " 0x"); |
| 299 val = (buffer[0] & 0x1) ? buffer[1] | 0xFFFFFF00 : buffer[1]; |
| 300 (*info->print_address_func) (memaddr + (val << 1) + 2, info); |
| 301 } |
| 302 else if (format & M68XG_OP_REL10) |
| 303 { |
| 304 (*info->fprintf_func) (info->stream, " 0x"); |
| 305 val = (buffer[0] << 8) | (unsigned int) buffer[1]; |
| 306 if (val & 0x200) |
| 307 val |= 0xfffffc00; |
| 308 else |
| 309 val &= 0x000001ff; |
| 310 (*info->print_address_func) (memaddr + (val << 1) + 2, info); |
| 311 } |
| 312 else if ((code & 0x00ff) == 0x00f8) |
| 313 (*info->fprintf_func) (info->stream, " R%x, CCR", (code >> 8) & 0x7)
; |
| 314 else if ((code & 0x00ff) == 0x00f9) |
| 315 (*info->fprintf_func) (info->stream, " CCR, R%x", (code >> 8) & 0x7)
; |
| 316 else if ((code & 0x00ff) == 0x0) |
| 317 (*info->fprintf_func) (info->stream, " R%x, PC", (code >> 8) & 0x7); |
| 318 else if (format & M68XG_OP_R) |
| 319 { |
| 320 /* Special cases for TFR. */ |
| 321 if ((code & 0xf8ff) == 0x00f8) |
| 322 (*info->fprintf_func) (info->stream, " R%x, CCR", (code >> 8) &
0x7); |
| 323 else if ((code & 0xf8ff) == 0x00f9) |
| 324 (*info->fprintf_func) (info->stream, " CCR, R%x", (code >> 8) &
0x7); |
| 325 else if ((code & 0xf8ff) == 0x00fa) |
| 326 (*info->fprintf_func) (info->stream, " R%x, PC", (code >> 8) &
0x7); |
| 327 else |
| 328 (*info->fprintf_func) (info->stream, " R%x", (code >> 8) & 0x7); |
| 329 } |
| 330 else |
| 331 /* Opcode not recognized. */ |
| 332 (*info->fprintf_func) (info->stream, "Not yet handled TEST .byte\t0x
%04x", code); |
| 333 return 2; |
| 334 } |
| 335 |
| 336 /* Opcode not recognized. */ |
| 337 (*info->fprintf_func) (info->stream, ".byte\t0x%04x", code); |
| 338 return 2; /* Everything is two bytes. */ |
| 339 } |
| 340 |
| 341 /* HC11 and HC12. */ |
| 342 |
| 238 /* Get first byte. Only one at a time because we don't know the | 343 /* Get first byte. Only one at a time because we don't know the |
| 239 size of the insn. */ | 344 size of the insn. */ |
| 240 status = read_memory (memaddr, buffer, 1, info); | 345 status = read_memory (memaddr, buffer, 1, info); |
| 241 if (status != 0) | 346 if (status != 0) |
| 242 { | 347 return status; |
| 243 return status; | |
| 244 } | |
| 245 | 348 |
| 246 format = 0; | 349 format = 0; |
| 247 code = buffer[0]; | 350 code = buffer[0]; |
| 248 pos = 0; | 351 pos = 0; |
| 249 | 352 |
| 250 /* Look for page2,3,4 opcodes. */ | 353 /* Look for page2,3,4 opcodes. */ |
| 251 if (code == M6811_OPCODE_PAGE2) | 354 if (code == M6811_OPCODE_PAGE2) |
| 252 { | 355 { |
| 253 pos++; | 356 pos++; |
| 254 format = M6811_OP_PAGE2; | 357 format = M6811_OP_PAGE2; |
| 255 } | 358 } |
| 256 else if (code == M6811_OPCODE_PAGE3 && arch == cpu6811) | 359 else if (code == M6811_OPCODE_PAGE3 && arch == cpu6811) |
| 257 { | 360 { |
| 258 pos++; | 361 pos++; |
| 259 format = M6811_OP_PAGE3; | 362 format = M6811_OP_PAGE3; |
| 260 } | 363 } |
| 261 else if (code == M6811_OPCODE_PAGE4 && arch == cpu6811) | 364 else if (code == M6811_OPCODE_PAGE4 && arch == cpu6811) |
| 262 { | 365 { |
| 263 pos++; | 366 pos++; |
| 264 format = M6811_OP_PAGE4; | 367 format = M6811_OP_PAGE4; |
| 265 } | 368 } |
| 266 | 369 |
| 267 /* We are in page2,3,4; get the real opcode. */ | 370 /* We are in page2,3,4; get the real opcode. */ |
| 268 if (pos == 1) | 371 if (pos == 1) |
| 269 { | 372 { |
| 270 status = read_memory (memaddr + pos, &buffer[1], 1, info); | 373 status = read_memory (memaddr + pos, &buffer[1], 1, info); |
| 271 if (status != 0) | 374 if (status != 0) |
| 272 » { | 375 » return status; |
| 273 » return status; | 376 |
| 274 » } | |
| 275 code = buffer[1]; | 377 code = buffer[1]; |
| 276 } | 378 } |
| 277 | 379 |
| 278 | |
| 279 /* Look first for a 68HC12 alias. All of them are 2-bytes long and | 380 /* Look first for a 68HC12 alias. All of them are 2-bytes long and |
| 280 in page 1. There is no operand to print. We read the second byte | 381 in page 1. There is no operand to print. We read the second byte |
| 281 only when we have a possible match. */ | 382 only when we have a possible match. */ |
| 282 if ((arch & cpu6812) && format == 0) | 383 if ((arch & cpu6812) && format == 0) |
| 283 { | 384 { |
| 284 int must_read = 1; | 385 int must_read = 1; |
| 285 | 386 |
| 286 /* Walk the alias table to find a code1+code2 match. */ | 387 /* Walk the alias table to find a code1+code2 match. */ |
| 287 for (i = 0; i < m68hc12_num_alias; i++) | 388 for (i = 0; i < m68hc12_num_alias; i++) |
| 288 { | 389 { |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 367 && (buffer[0] & 0x20) != 0) | 468 && (buffer[0] & 0x20) != 0) |
| 368 break; | 469 break; |
| 369 continue; | 470 continue; |
| 370 } | 471 } |
| 371 if (opcode[j].format & M6812_OP_EXG_MARKER && buffer[0] & 0x80) | 472 if (opcode[j].format & M6812_OP_EXG_MARKER && buffer[0] & 0x80) |
| 372 break; | 473 break; |
| 373 if ((opcode[j].format & M6812_OP_SEX_MARKER) | 474 if ((opcode[j].format & M6812_OP_SEX_MARKER) |
| 374 && (((buffer[0] & 0x07) >= 3 && (buffer[0] & 7) <= 7)) | 475 && (((buffer[0] & 0x07) >= 3 && (buffer[0] & 7) <= 7)) |
| 375 && ((buffer[0] & 0x0f0) <= 0x20)) | 476 && ((buffer[0] & 0x0f0) <= 0x20)) |
| 376 break; | 477 break; |
| 478 if ((opcode[j].format & M6812_OP_SEX_MARKER) |
| 479 && (arch & cpu9s12x) |
| 480 && ((buffer[0] == 0x4d) || (buffer[0] == 0x4e))) |
| 481 break; |
| 377 if (opcode[j].format & M6812_OP_TFR_MARKER | 482 if (opcode[j].format & M6812_OP_TFR_MARKER |
| 378 && !(buffer[0] & 0x80)) | 483 && !(buffer[0] & 0x80)) |
| 379 break; | 484 break; |
| 380 } | 485 } |
| 381 if (i + j < m68hc11_num_opcodes) | 486 if (i + j < m68hc11_num_opcodes) |
| 382 opcode = &opcode[j]; | 487 opcode = &opcode[j]; |
| 383 } | 488 } |
| 384 | 489 |
| 385 /* We have found the opcode. Extract the operand and print it. */ | 490 /* We have found the opcode. Extract the operand and print it. */ |
| 386 (*info->fprintf_func) (info->stream, "%s", opcode->name); | 491 (*info->fprintf_func) (info->stream, "%s", opcode->name); |
| 387 | 492 |
| 388 format = opcode->format; | 493 format = opcode->format; |
| 389 if (format & (M6811_OP_MASK | M6811_OP_BITMASK | 494 if (format & (M6811_OP_MASK | M6811_OP_BITMASK |
| 390 | M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) | 495 | M6811_OP_JUMP_REL | M6812_OP_JUMP_REL16)) |
| 391 { | 496 { |
| 392 (*info->fprintf_func) (info->stream, "\t"); | 497 (*info->fprintf_func) (info->stream, "\t"); |
| 393 } | 498 } |
| 394 | 499 |
| 395 /* The movb and movw must be handled in a special way... | 500 /* The movb and movw must be handled in a special way... |
| 396 The source constant 'ii' is not always at the same place. | 501 » The source constant 'ii' is not always at the same place. |
| 397 This is the same for the destination for the post-indexed byte. | 502 » This is the same for the destination for the post-indexed byte. |
| 398 The 'offset' is used to do the appropriate correction. | 503 » The 'offset' is used to do the appropriate correction. |
| 399 | 504 |
| 400 offset offset | 505 » offset offset |
| 401 for constant for destination | 506 » for constant for destination |
| 402 movb 18 OB ii hh ll 0 0 | 507 » movb 18 OB ii hh ll 0 0 |
| 403 18 08 xb ii 1 -1 | 508 » 18 08 xb ii 1 -1 |
| 404 18 0C hh ll hh ll 0 0 | 509 » 18 08 xb ff ii 2 1 9 bit |
| 405 18 09 xb hh ll 1 -1 | 510 » 18 08 xb ee ff ii 3 1 16 bit |
| 406 18 0D xb hh ll 0 0 | 511 » 18 0C hh ll hh ll 0 0 |
| 407 18 0A xb xb 0 0 | 512 » 18 09 xb hh ll 1 -1 |
| 513 » 18 0D xb hh ll 0 0 |
| 514 » 18 0A xb xb 0 0 |
| 408 | 515 |
| 409 movw 18 03 jj kk hh ll 0 0 | 516 » movw 18 03 jj kk hh ll 0 0 |
| 410 18 00 xb jj kk 1 -1 | 517 » 18 00 xb jj kk 1 -1 |
| 411 18 04 hh ll hh ll 0 0 | 518 » 18 04 hh ll hh ll 0 0 |
| 412 18 01 xb hh ll 1 -1 | 519 » 18 01 xb hh ll 1 -1 |
| 413 18 05 xb hh ll 0 0 | 520 » 18 05 xb hh ll 0 0 |
| 414 18 02 xb xb 0 0 | 521 » 18 02 xb xb 0 0 |
| 415 | 522 |
| 416 After the source operand is read, the position 'pos' is incremented | 523 » After the source operand is read, the position 'pos' is incremented |
| 417 this explains the negative offset for destination. | 524 » this explains the negative offset for destination. |
| 418 | 525 |
| 419 movb/movw above are the only instructions with this matching | 526 » movb/movw above are the only instructions with this matching |
| 420 format. */ | 527 » format. */ |
| 421 offset = ((format & M6812_OP_IDX_P2) | 528 offset = ((format & M6812_OP_IDX_P2) |
| 422 && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 | | 529 » » && (format & (M6811_OP_IMM8 | M6811_OP_IMM16 | |
| 423 M6811_OP_IND16))); | 530 » » » M6811_OP_IND16))); |
| 531 |
| 532 if (offset) |
| 533 » { |
| 534 » /* Check xb to see position of data. */ |
| 535 » status = read_memory (memaddr + pos, &buffer[0], 1, info); |
| 536 » if (status != 0) |
| 537 » { |
| 538 » return status; |
| 539 » } |
| 540 |
| 541 » if (((buffer[0] & 0xe0) == 0xe0) && ((buffer[0] & 0x04) == 0)) |
| 542 » { |
| 543 » /* 9 or 16 bit. */ |
| 544 » if ((buffer[0] & 0x02) == 0) |
| 545 » » { |
| 546 » » /* 9 bit. */ |
| 547 » » offset = 2; |
| 548 » » } |
| 549 » else |
| 550 » » { |
| 551 » » /* 16 bit. */ |
| 552 » » offset = 3; |
| 553 » » } |
| 554 » } |
| 555 » } |
| 424 | 556 |
| 425 /* Operand with one more byte: - immediate, offset, | 557 /* Operand with one more byte: - immediate, offset, |
| 426 direct-low address. */ | 558 » direct-low address. */ |
| 427 if (format & | 559 if (format & |
| 428 (M6811_OP_IMM8 | M6811_OP_IX | M6811_OP_IY | M6811_OP_DIRECT)) | 560 (M6811_OP_IMM8 | M6811_OP_IX | M6811_OP_IY | M6811_OP_DIRECT)) |
| 429 { | 561 { |
| 430 status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); | 562 status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); |
| 431 if (status != 0) | 563 if (status != 0) |
| 564 return status; |
| 565 |
| 566 /* This movb/movw is special (see above). */ |
| 567 if (offset < 2) |
| 432 { | 568 { |
| 433 » return status; | 569 » offset = -offset; |
| 570 » pc_dst_offset = 2; |
| 434 } | 571 } |
| 435 | 572 » else |
| 573 » { |
| 574 » offset = -1; |
| 575 » pc_dst_offset = 5; |
| 576 » } |
| 436 pos++; | 577 pos++; |
| 437 | 578 |
| 438 /* This movb/movw is special (see above). */ | |
| 439 offset = -offset; | |
| 440 | |
| 441 pc_dst_offset = 2; | |
| 442 if (format & M6811_OP_IMM8) | 579 if (format & M6811_OP_IMM8) |
| 443 { | 580 { |
| 444 » (*info->fprintf_func) (info->stream, "#%d", (int) buffer[0]); | 581 » (*info->fprintf_func) (info->stream, "#0x%x", (int) buffer[0]); |
| 445 format &= ~M6811_OP_IMM8; | 582 format &= ~M6811_OP_IMM8; |
| 446 /* Set PC destination offset. */ | 583 » /* Set PC destination offset. */ |
| 447 pc_dst_offset = 1; | 584 » pc_dst_offset = 1; |
| 448 } | 585 } |
| 449 else if (format & M6811_OP_IX) | 586 else if (format & M6811_OP_IX) |
| 450 { | 587 { |
| 451 /* Offsets are in range 0..255, print them unsigned. */ | 588 /* Offsets are in range 0..255, print them unsigned. */ |
| 452 » (*info->fprintf_func) (info->stream, "%u,x", buffer[0] & 0x0FF); | 589 » (*info->fprintf_func) (info->stream, "0x%x,x", buffer[0] & 0x0FF); |
| 453 format &= ~M6811_OP_IX; | 590 format &= ~M6811_OP_IX; |
| 454 } | 591 } |
| 455 else if (format & M6811_OP_IY) | 592 else if (format & M6811_OP_IY) |
| 456 { | 593 { |
| 457 » (*info->fprintf_func) (info->stream, "%u,y", buffer[0] & 0x0FF); | 594 » (*info->fprintf_func) (info->stream, "0x%x,y", buffer[0] & 0x0FF); |
| 458 format &= ~M6811_OP_IY; | 595 format &= ~M6811_OP_IY; |
| 459 } | 596 } |
| 460 else if (format & M6811_OP_DIRECT) | 597 else if (format & M6811_OP_DIRECT) |
| 461 { | 598 { |
| 462 (*info->fprintf_func) (info->stream, "*"); | 599 (*info->fprintf_func) (info->stream, "*"); |
| 600 if (info->symtab_size > 0) /* Avoid duplicate 0x. */ |
| 601 (*info->fprintf_func) (info->stream, "0x"); |
| 463 (*info->print_address_func) (buffer[0] & 0x0FF, info); | 602 (*info->print_address_func) (buffer[0] & 0x0FF, info); |
| 464 format &= ~M6811_OP_DIRECT; | 603 format &= ~M6811_OP_DIRECT; |
| 465 } | 604 } |
| 466 } | 605 } |
| 467 | 606 |
| 468 #define M6812_DST_MOVE (M6812_OP_IND16_P2 | M6812_OP_IDX_P2) | 607 #define M6812_DST_MOVE (M6812_OP_IND16_P2 | M6812_OP_IDX_P2) |
| 469 #define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2) | 608 #define M6812_INDEXED_FLAGS (M6812_OP_IDX|M6812_OP_IDX_1|M6812_OP_IDX_2) |
| 470 /* Analyze the 68HC12 indexed byte. */ | 609 /* Analyze the 68HC12 indexed byte. */ |
| 471 if (format & M6812_INDEXED_FLAGS) | 610 if (format & M6812_INDEXED_FLAGS) |
| 472 { | 611 { |
| 473 int indirect; | 612 » int indirect; |
| 474 bfd_vma endaddr; | 613 » bfd_vma endaddr; |
| 475 | 614 |
| 476 endaddr = memaddr + pos + 1; | 615 » endaddr = memaddr + pos + 1; |
| 477 if (format & M6811_OP_IND16) | 616 » if (format & M6811_OP_IND16) |
| 478 endaddr += 2; | 617 » endaddr += 2; |
| 479 pc_src_offset = -1; | 618 » pc_src_offset = -1; |
| 480 pc_dst_offset = 1; | 619 » pc_dst_offset = 1; |
| 481 status = print_indexed_operand (memaddr + pos, info, &indirect, | 620 status = print_indexed_operand (memaddr + pos, info, &indirect, |
| 482 (format & M6812_DST_MOVE), | 621 » » » » » (format & M6812_DST_MOVE), |
| 483 pc_src_offset, endaddr); | 622 » » » » » pc_src_offset, endaddr, arch); |
| 484 if (status < 0) | 623 if (status < 0) |
| 485 » { | 624 » return status; |
| 486 » return status; | 625 |
| 487 » } | |
| 488 pos += status; | 626 pos += status; |
| 489 | 627 |
| 490 /* The indirect addressing mode of the call instruction does | 628 » /* The indirect addressing mode of the call instruction does |
| 491 not need the page code. */ | 629 » not need the page code. */ |
| 492 if ((format & M6812_OP_PAGE) && indirect) | 630 » if ((format & M6812_OP_PAGE) && indirect) |
| 493 format &= ~M6812_OP_PAGE; | 631 » format &= ~M6812_OP_PAGE; |
| 494 } | 632 } |
| 495 | 633 |
| 496 /* 68HC12 dbcc/ibcc/tbcc operands. */ | 634 /* 68HC12 dbcc/ibcc/tbcc operands. */ |
| 497 if ((format & M6812_OP_REG) && (format & M6811_OP_JUMP_REL)) | 635 if ((format & M6812_OP_REG) && (format & M6811_OP_JUMP_REL)) |
| 498 { | 636 { |
| 499 status = read_memory (memaddr + pos, &buffer[0], 2, info); | 637 status = read_memory (memaddr + pos, &buffer[0], 2, info); |
| 500 if (status != 0) | 638 if (status != 0) |
| 501 » { | 639 » return status; |
| 502 » return status; | 640 |
| 503 » } | |
| 504 (*info->fprintf_func) (info->stream, "%s,", | 641 (*info->fprintf_func) (info->stream, "%s,", |
| 505 reg_src_table[buffer[0] & 0x07]); | 642 reg_src_table[buffer[0] & 0x07]); |
| 506 sval = buffer[1] & 0x0ff; | 643 sval = buffer[1] & 0x0ff; |
| 507 if (buffer[0] & 0x10) | 644 if (buffer[0] & 0x10) |
| 508 sval |= 0xff00; | 645 sval |= 0xff00; |
| 509 | 646 |
| 510 pos += 2; | 647 pos += 2; |
| 648 (*info->fprintf_func) (info->stream, "0x"); |
| 511 (*info->print_address_func) (memaddr + pos + sval, info); | 649 (*info->print_address_func) (memaddr + pos + sval, info); |
| 512 format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL); | 650 format &= ~(M6812_OP_REG | M6811_OP_JUMP_REL); |
| 513 } | 651 } |
| 514 else if (format & (M6812_OP_REG | M6812_OP_REG_2)) | 652 else if (format & (M6812_OP_REG | M6812_OP_REG_2)) |
| 515 { | 653 { |
| 516 status = read_memory (memaddr + pos, &buffer[0], 1, info); | 654 status = read_memory (memaddr + pos, &buffer[0], 1, info); |
| 517 if (status != 0) | 655 if (status != 0) |
| 518 » { | 656 » return status; |
| 519 » return status; | |
| 520 » } | |
| 521 | 657 |
| 522 pos++; | 658 pos++; |
| 523 (*info->fprintf_func) (info->stream, "%s,%s", | 659 (*info->fprintf_func) (info->stream, "%s,%s", |
| 524 reg_src_table[(buffer[0] >> 4) & 7], | 660 reg_src_table[(buffer[0] >> 4) & 7], |
| 525 reg_dst_table[(buffer[0] & 7)]); | 661 reg_dst_table[(buffer[0] & 7)]); |
| 526 } | 662 } |
| 527 | 663 |
| 528 if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) | 664 if (format & (M6811_OP_IMM16 | M6811_OP_IND16)) |
| 529 { | 665 { |
| 530 int val; | 666 int val; |
| 531 bfd_vma addr; | 667 » bfd_vma addr; |
| 532 unsigned page = 0; | 668 » unsigned page = 0; |
| 533 | 669 |
| 534 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); | 670 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); |
| 535 if (status != 0) | 671 if (status != 0) |
| 536 » { | 672 » return status; |
| 537 » return status; | 673 |
| 538 » } | |
| 539 if (format & M6812_OP_IDX_P2) | 674 if (format & M6812_OP_IDX_P2) |
| 540 offset = -2; | 675 offset = -2; |
| 541 else | 676 else |
| 542 offset = 0; | 677 offset = 0; |
| 543 pos += 2; | 678 pos += 2; |
| 544 | 679 |
| 545 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); | 680 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); |
| 546 val &= 0x0FFFF; | 681 val &= 0x0FFFF; |
| 547 addr = val; | 682 » addr = val; |
| 548 pc_dst_offset = 2; | 683 » pc_dst_offset = 2; |
| 549 if (format & M6812_OP_PAGE) | 684 » if (format & M6812_OP_PAGE) |
| 550 { | 685 » { |
| 551 status = read_memory (memaddr + pos + offset, buffer, 1, info); | 686 » status = read_memory (memaddr + pos + offset, buffer, 1, info); |
| 552 if (status != 0) | 687 » if (status != 0) |
| 553 return status; | 688 » » return status; |
| 554 | 689 |
| 555 page = (unsigned) buffer[0]; | 690 » page = (unsigned) buffer[0]; |
| 556 if (addr >= M68HC12_BANK_BASE && addr < 0x0c000) | 691 » if (addr >= M68HC12_BANK_BASE && addr < 0x0c000) |
| 557 addr = ((val - M68HC12_BANK_BASE) | 692 » » addr = ((val - M68HC12_BANK_BASE) |
| 558 | (page << M68HC12_BANK_SHIFT)) | 693 » » » | (page << M68HC12_BANK_SHIFT)) |
| 559 + M68HC12_BANK_VIRT; | 694 » » + M68HC12_BANK_VIRT; |
| 560 } | 695 » } |
| 561 else if ((arch & cpu6812) | 696 » else if ((arch & cpu6812) |
| 562 && addr >= M68HC12_BANK_BASE && addr < 0x0c000) | 697 » » && addr >= M68HC12_BANK_BASE && addr < 0x0c000) |
| 563 { | 698 » { |
| 564 int cur_page; | 699 » int cur_page; |
| 565 bfd_vma vaddr; | 700 » bfd_vma vaddr; |
| 566 | 701 |
| 567 if (memaddr >= M68HC12_BANK_VIRT) | 702 » if (memaddr >= M68HC12_BANK_VIRT) |
| 568 cur_page = ((memaddr - M68HC12_BANK_VIRT) | 703 » » cur_page = ((memaddr - M68HC12_BANK_VIRT) |
| 569 >> M68HC12_BANK_SHIFT); | 704 » » » >> M68HC12_BANK_SHIFT); |
| 570 else | 705 » else |
| 571 cur_page = 0; | 706 » » cur_page = 0; |
| 572 | 707 |
| 573 vaddr = ((addr - M68HC12_BANK_BASE) | 708 » vaddr = ((addr - M68HC12_BANK_BASE) |
| 574 + (cur_page << M68HC12_BANK_SHIFT)) | 709 » » + (cur_page << M68HC12_BANK_SHIFT)) |
| 575 + M68HC12_BANK_VIRT; | 710 » » + M68HC12_BANK_VIRT; |
| 576 if (!info->symbol_at_address_func (addr, info) | 711 » if (!info->symbol_at_address_func (addr, info) |
| 577 && info->symbol_at_address_func (vaddr, info)) | 712 » » && info->symbol_at_address_func (vaddr, info)) |
| 578 addr = vaddr; | 713 » » addr = vaddr; |
| 579 } | 714 » } |
| 580 if (format & M6811_OP_IMM16) | 715 if (format & M6811_OP_IMM16) |
| 581 { | 716 { |
| 582 format &= ~M6811_OP_IMM16; | 717 format &= ~M6811_OP_IMM16; |
| 583 (*info->fprintf_func) (info->stream, "#"); | 718 (*info->fprintf_func) (info->stream, "#"); |
| 584 } | 719 } |
| 585 else | 720 else |
| 586 » format &= ~M6811_OP_IND16; | 721 » { |
| 722 » format &= ~M6811_OP_IND16; |
| 723 » } |
| 724 |
| 725 » if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutils. *
/ |
| 726 » (*info->fprintf_func) (info->stream, "0x"); |
| 587 | 727 |
| 588 (*info->print_address_func) (addr, info); | 728 (*info->print_address_func) (addr, info); |
| 589 if (format & M6812_OP_PAGE) | 729 » if (format & M6812_OP_PAGE) |
| 590 { | 730 » { |
| 591 (* info->fprintf_func) (info->stream, " {"); | 731 » (* info->fprintf_func) (info->stream, " {"); |
| 592 (* info->print_address_func) (val, info); | 732 » if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutil
s. */ |
| 593 (* info->fprintf_func) (info->stream, ", %d}", page); | 733 » » (*info->fprintf_func) (info->stream, "0x"); |
| 594 format &= ~M6812_OP_PAGE; | 734 » (* info->print_address_func) (val, info); |
| 595 pos += 1; | 735 » (* info->fprintf_func) (info->stream, ", 0x%x}", page); |
| 596 } | 736 » format &= ~M6812_OP_PAGE; |
| 737 » pos += 1; |
| 738 » } |
| 597 } | 739 } |
| 598 | 740 |
| 599 if (format & M6812_OP_IDX_P2) | 741 if (format & M6812_OP_IDX_P2) |
| 600 { | 742 { |
| 601 (*info->fprintf_func) (info->stream, ", "); | 743 (*info->fprintf_func) (info->stream, ", "); |
| 602 status = print_indexed_operand (memaddr + pos + offset, info, | 744 status = print_indexed_operand (memaddr + pos + offset, info, |
| 603 0, 1, pc_dst_offset, | 745 » » » » » 0, 1, pc_dst_offset, |
| 604 memaddr + pos + offset + 1); | 746 » » » » » memaddr + pos + offset + 1, arch); |
| 605 if (status < 0) | 747 if (status < 0) |
| 606 return status; | 748 return status; |
| 607 pos += status; | 749 pos += status; |
| 608 } | 750 } |
| 609 | 751 |
| 610 if (format & M6812_OP_IND16_P2) | 752 if (format & M6812_OP_IND16_P2) |
| 611 { | 753 { |
| 612 int val; | 754 int val; |
| 613 | 755 |
| 614 (*info->fprintf_func) (info->stream, ", "); | 756 (*info->fprintf_func) (info->stream, ", "); |
| 615 | 757 |
| 616 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); | 758 status = read_memory (memaddr + pos + offset, &buffer[0], 2, info); |
| 617 if (status != 0) | 759 if (status != 0) |
| 618 » { | 760 » return status; |
| 619 » return status; | 761 |
| 620 » } | |
| 621 pos += 2; | 762 pos += 2; |
| 622 | 763 |
| 623 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); | 764 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); |
| 624 val &= 0x0FFFF; | 765 val &= 0x0FFFF; |
| 766 if (info->symtab_size > 0) /* Avoid duplicate 0x from core binutils. *
/ |
| 767 (*info->fprintf_func) (info->stream, "0x"); |
| 625 (*info->print_address_func) (val, info); | 768 (*info->print_address_func) (val, info); |
| 626 } | 769 } |
| 627 | 770 |
| 628 /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately | 771 /* M6811_OP_BITMASK and M6811_OP_JUMP_REL must be treated separately |
| 629 and in that order. The brset/brclr insn have a bitmask and then | 772 » and in that order. The brset/brclr insn have a bitmask and then |
| 630 a relative branch offset. */ | 773 » a relative branch offset. */ |
| 631 if (format & M6811_OP_BITMASK) | 774 if (format & M6811_OP_BITMASK) |
| 632 { | 775 { |
| 633 status = read_memory (memaddr + pos, &buffer[0], 1, info); | 776 status = read_memory (memaddr + pos, &buffer[0], 1, info); |
| 634 if (status != 0) | 777 if (status != 0) |
| 635 » { | 778 » return status; |
| 636 » return status; | 779 |
| 637 » } | |
| 638 pos++; | 780 pos++; |
| 639 » (*info->fprintf_func) (info->stream, " #$%02x%s", | 781 » (*info->fprintf_func) (info->stream, ", #0x%02x%s", |
| 640 buffer[0] & 0x0FF, | 782 buffer[0] & 0x0FF, |
| 641 » » » » (format & M6811_OP_JUMP_REL ? " " : "")); | 783 » » » » (format & M6811_OP_JUMP_REL ? ", " : "")); |
| 642 format &= ~M6811_OP_BITMASK; | 784 format &= ~M6811_OP_BITMASK; |
| 643 } | 785 } |
| 644 if (format & M6811_OP_JUMP_REL) | 786 if (format & M6811_OP_JUMP_REL) |
| 645 { | 787 { |
| 646 int val; | 788 int val; |
| 647 | 789 |
| 648 status = read_memory (memaddr + pos, &buffer[0], 1, info); | 790 status = read_memory (memaddr + pos, &buffer[0], 1, info); |
| 649 if (status != 0) | 791 if (status != 0) |
| 650 » { | 792 » return status; |
| 651 » return status; | |
| 652 » } | |
| 653 | 793 |
| 794 (*info->fprintf_func) (info->stream, "0x"); |
| 654 pos++; | 795 pos++; |
| 655 val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0]; | 796 val = (buffer[0] & 0x80) ? buffer[0] | 0xFFFFFF00 : buffer[0]; |
| 656 (*info->print_address_func) (memaddr + pos + val, info); | 797 (*info->print_address_func) (memaddr + pos + val, info); |
| 657 format &= ~M6811_OP_JUMP_REL; | 798 format &= ~M6811_OP_JUMP_REL; |
| 658 } | 799 } |
| 659 else if (format & M6812_OP_JUMP_REL16) | 800 else if (format & M6812_OP_JUMP_REL16) |
| 660 { | 801 { |
| 661 int val; | 802 int val; |
| 662 | 803 |
| 663 status = read_memory (memaddr + pos, &buffer[0], 2, info); | 804 status = read_memory (memaddr + pos, &buffer[0], 2, info); |
| 664 if (status != 0) | 805 if (status != 0) |
| 665 » { | 806 » return status; |
| 666 » return status; | |
| 667 » } | |
| 668 | 807 |
| 669 pos += 2; | 808 pos += 2; |
| 670 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); | 809 val = ((buffer[0] << 8) | (buffer[1] & 0x0FF)); |
| 671 if (val & 0x8000) | 810 if (val & 0x8000) |
| 672 val |= 0xffff0000; | 811 val |= 0xffff0000; |
| 673 | 812 |
| 813 (*info->fprintf_func) (info->stream, "0x"); |
| 674 (*info->print_address_func) (memaddr + pos + val, info); | 814 (*info->print_address_func) (memaddr + pos + val, info); |
| 675 format &= ~M6812_OP_JUMP_REL16; | 815 format &= ~M6812_OP_JUMP_REL16; |
| 676 } | 816 } |
| 677 | 817 |
| 678 if (format & M6812_OP_PAGE) | 818 if (format & M6812_OP_PAGE) |
| 679 { | 819 { |
| 680 int val; | 820 int val; |
| 681 | 821 |
| 682 status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); | 822 status = read_memory (memaddr + pos + offset, &buffer[0], 1, info); |
| 683 if (status != 0) | 823 if (status != 0) |
| 684 » { | 824 » return status; |
| 685 » return status; | 825 |
| 686 » } | |
| 687 pos += 1; | 826 pos += 1; |
| 688 | 827 |
| 689 val = buffer[0] & 0x0ff; | 828 val = buffer[0] & 0x0ff; |
| 690 » (*info->fprintf_func) (info->stream, ", %d", val); | 829 » (*info->fprintf_func) (info->stream, ", 0x%x", val); |
| 691 } | 830 } |
| 692 | 831 |
| 693 #ifdef DEBUG | 832 #ifdef DEBUG |
| 694 /* Consistency check. 'format' must be 0, so that we have handled | 833 /* Consistency check. 'format' must be 0, so that we have handled |
| 695 all formats; and the computed size of the insn must match the | 834 » all formats; and the computed size of the insn must match the |
| 696 opcode table content. */ | 835 » opcode table content. */ |
| 697 if (format & ~(M6811_OP_PAGE4 | M6811_OP_PAGE3 | M6811_OP_PAGE2)) | 836 if (format & ~(M6811_OP_PAGE4 | M6811_OP_PAGE3 | M6811_OP_PAGE2)) |
| 698 » { | 837 » (*info->fprintf_func) (info->stream, "; Error, format: %lx", format); |
| 699 » (*info->fprintf_func) (info->stream, "; Error, format: %lx", format); | 838 |
| 700 » } | |
| 701 if (pos != opcode->size) | 839 if (pos != opcode->size) |
| 702 » { | 840 » (*info->fprintf_func) (info->stream, "; Error, size: %ld expect %d", |
| 703 » (*info->fprintf_func) (info->stream, "; Error, size: %ld expect %d", | 841 » » » pos, opcode->size); |
| 704 » » » » pos, opcode->size); | |
| 705 » } | |
| 706 #endif | 842 #endif |
| 707 return pos; | 843 return pos; |
| 708 } | 844 } |
| 709 | 845 |
| 710 /* Opcode not recognized. */ | 846 /* Opcode not recognized. */ |
| 711 if (format == M6811_OP_PAGE2 && arch & cpu6812 | 847 if (format == M6811_OP_PAGE2 && arch & cpu6812 |
| 712 && ((code >= 0x30 && code <= 0x39) || (code >= 0x40))) | 848 && ((code >= 0x30 && code <= 0x39) || (code >= 0x40))) |
| 713 (*info->fprintf_func) (info->stream, "trap\t#%d", code & 0x0ff); | 849 (*info->fprintf_func) (info->stream, "trap\t#0x%02x", code & 0x0ff); |
| 714 | 850 |
| 715 else if (format == M6811_OP_PAGE2) | 851 else if (format == M6811_OP_PAGE2) |
| 716 (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x", | 852 (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x", |
| 717 M6811_OPCODE_PAGE2, code); | 853 M6811_OPCODE_PAGE2, code); |
| 718 else if (format == M6811_OP_PAGE3) | 854 else if (format == M6811_OP_PAGE3) |
| 719 (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x", | 855 (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x", |
| 720 M6811_OPCODE_PAGE3, code); | 856 M6811_OPCODE_PAGE3, code); |
| 721 else if (format == M6811_OP_PAGE4) | 857 else if (format == M6811_OP_PAGE4) |
| 722 (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x", | 858 (*info->fprintf_func) (info->stream, ".byte\t0x%02x, 0x%02x", |
| 723 M6811_OPCODE_PAGE4, code); | 859 M6811_OPCODE_PAGE4, code); |
| 724 else | 860 else |
| 725 (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code); | 861 (*info->fprintf_func) (info->stream, ".byte\t0x%02x", code); |
| 726 | 862 |
| 727 return pos; | 863 return pos; |
| 728 } | 864 } |
| 729 | 865 |
| 730 /* Disassemble one instruction at address 'memaddr'. Returns the number | 866 /* Disassemble one instruction at address 'memaddr'. Returns the number |
| 731 of bytes used by that instruction. */ | 867 of bytes used by that instruction. */ |
| 732 int | 868 int |
| 733 print_insn_m68hc11 (bfd_vma memaddr, struct disassemble_info* info) | 869 print_insn_m68hc11 (bfd_vma memaddr, struct disassemble_info* info) |
| 734 { | 870 { |
| 735 return print_insn (memaddr, info, cpu6811); | 871 return print_insn (memaddr, info, cpu6811); |
| 736 } | 872 } |
| 737 | 873 |
| 738 int | 874 int |
| 739 print_insn_m68hc12 (bfd_vma memaddr, struct disassemble_info* info) | 875 print_insn_m68hc12 (bfd_vma memaddr, struct disassemble_info* info) |
| 740 { | 876 { |
| 741 return print_insn (memaddr, info, cpu6812); | 877 return print_insn (memaddr, info, cpu6812); |
| 742 } | 878 } |
| 879 |
| 880 int |
| 881 print_insn_m9s12x (bfd_vma memaddr, struct disassemble_info* info) |
| 882 { |
| 883 return print_insn (memaddr, info, cpu6812|cpu9s12x); |
| 884 } |
| 885 |
| 886 int |
| 887 print_insn_m9s12xg (bfd_vma memaddr, struct disassemble_info* info) |
| 888 { |
| 889 return print_insn (memaddr, info, cpuxgate); |
| 890 } |
| OLD | NEW |