* config/sh/tm-sh.h (BELIEVE_PCC_PROMOTION): Define, so that
[deliverable/binutils-gdb.git] / opcodes / h8500-dis.c
CommitLineData
5d0734a7
JK
1/* Disassemble h8500 instructions.
2 Copyright (C) 1993 Free Software Foundation, Inc.
3
4This program is free software; you can redistribute it and/or modify
5it under the terms of the GNU General Public License as published by
6the Free Software Foundation; either version 2 of the License, or
7(at your option) any later version.
8
9This program is distributed in the hope that it will be useful,
10but WITHOUT ANY WARRANTY; without even the implied warranty of
11MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12GNU General Public License for more details.
13
14You should have received a copy of the GNU General Public License
15along with this program; if not, write to the Free Software
16Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */
17
18#include <stdio.h>
19
20#define DISASSEMBLER_TABLE
21#define DEFINE_TABLE
22
23#include "h8500-opc.h"
24#include "dis-asm.h"
25
26/* Maximum length of an instruction. */
27#define MAXLEN 8
28
29#include <setjmp.h>
30
31struct private
32{
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;
38};
39
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)))
46
47static int
48fetch_data (info, addr)
49 struct disassemble_info *info;
50 bfd_byte *addr;
51{
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);
55
56 status = (*info->read_memory_func) (start,
57 priv->max_fetched,
58 addr - priv->max_fetched,
59 info);
60 if (status != 0)
61 {
62 (*info->memory_error_func) (status, start, info);
63 longjmp (priv->bailout);
64 }
65 else
66 priv->max_fetched = addr;
67 return 1;
68}
69
70static char *crname[] =
71{"sr", "ccr", "*", "br", "ep", "dp", "*", "tp"};
72
73int
74print_insn_h8500 (addr, info)
75 unsigned long addr;
76 disassemble_info *info;
77{
78 h8500_opcode_info *opcode;
79 void *stream = info->stream;
80 fprintf_ftype func = info->fprintf_func;
81
82 struct private priv;
83 bfd_byte *buffer = priv.the_buffer;
84
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;
91
92 /* Run down the table to find the one which matches */
93 for (opcode = h8500_table; opcode->name; opcode++)
94 {
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++)
107 {
108 FETCH_DATA (info, buffer + byte + 1);
109 if ((buffer[byte] & opcode->bytes[byte].mask)
110 != (opcode->bytes[byte].contents))
111 {
112 goto next;
113 }
114 else
115 {
116 /* extract any info parts */
117 switch (opcode->bytes[byte].insert)
118 {
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)
188 {
189 case 0:
190 qim = 1;
191 break;
192 case 1:
193 qim = 2;
194 break;
195 case 4:
196 qim = -1;
197 break;
198 case 5:
199 qim = -2;
200 break;
201 }
202 break;
203
204 }
205 }
206 }
207 /* We get here when all the masks have passed so we can output the
208 operands*/
209 FETCH_DATA (info, buffer + opcode->length);
210 for (i = 0; i < opcode->length; i++)
211 {
212 (func) (stream, "%02x ", buffer[i]);
213 }
214 for (; i < 6; i++)
215 {
216 (func) (stream, " ");
217 }
218 (func) (stream, "%s\t", opcode->name);
219 for (i = 0; i < opcode->nargs; i++)
220 {
221 if (i)
222 (func) (stream, ",");
223 switch (opcode->arg_type[i])
224 {
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:
287 {
288 int i;
289 int nc = 0;
290 func (stream, "(");
291 for (i = 0; i < 8; i++)
292 {
293 if (imm & (1 << i))
294 {
295 if (nc)
296 func (stream, ",");
297 nc += 1;
298 }
299 func (stream, "r%d", i);
300 }
301 func (stream, ")");
302 }
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;
320 }
321 }
322 return opcode->length;
323 next:;
324 }
325
326 /* Couldn't understand anything */
327 func (stream, "%02x\t\t*unknown*", buffer[0]);
328 return 1;
329
330}
This page took 0.218327 seconds and 4 git commands to generate.