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