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 |