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