Harden gdb.base/coredump-filter.exp
[deliverable/binutils-gdb.git] / opcodes / h8500-dis.c
1 /* Disassemble h8500 instructions.
2 Copyright (C) 1993-2015 Free Software Foundation, Inc.
3
4 This file is part of the GNU opcodes library.
5
6 This library is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
10
11 It is distributed in the hope that it will be useful, but WITHOUT
12 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
13 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
14 License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
19 MA 02110-1301, USA. */
20
21 #include "sysdep.h"
22 #include <stdio.h>
23
24 #define DISASSEMBLER_TABLE
25 #define DEFINE_TABLE
26
27 #include "h8500-opc.h"
28 #include "dis-asm.h"
29 #include "opintl.h"
30
31 /* Maximum length of an instruction. */
32 #define MAXLEN 8
33
34 #include <setjmp.h>
35
36 struct private
37 {
38 /* Points to first byte not fetched. */
39 bfd_byte *max_fetched;
40 bfd_byte the_buffer[MAXLEN];
41 bfd_vma insn_start;
42 OPCODES_SIGJMP_BUF bailout;
43 };
44
45 /* Make sure that bytes from INFO->PRIVATE_DATA->BUFFER (inclusive)
46 to ADDR (exclusive) are valid. Returns 1 for success, longjmps
47 on error. */
48 #define FETCH_DATA(info, addr) \
49 ((addr) <= ((struct private *)(info->private_data))->max_fetched \
50 ? 1 : fetch_data ((info), (addr)))
51
52 static int
53 fetch_data (struct disassemble_info *info, bfd_byte *addr)
54 {
55 int status;
56 struct private *priv = (struct private *) info->private_data;
57 bfd_vma start = priv->insn_start + (priv->max_fetched - priv->the_buffer);
58
59 status = (*info->read_memory_func) (start,
60 priv->max_fetched,
61 addr - priv->max_fetched,
62 info);
63 if (status != 0)
64 {
65 (*info->memory_error_func) (status, start, info);
66 OPCODES_SIGLONGJMP (priv->bailout, 1);
67 }
68 else
69 priv->max_fetched = addr;
70 return 1;
71 }
72
73 static char *crname[] = { "sr", "ccr", "*", "br", "ep", "dp", "*", "tp" };
74
75 int
76 print_insn_h8500 (bfd_vma addr, disassemble_info *info)
77 {
78 const h8500_opcode_info *opcode;
79 void *stream = info->stream;
80 fprintf_ftype func = info->fprintf_func;
81 struct private priv;
82 bfd_byte *buffer = priv.the_buffer;
83
84 info->private_data = (PTR) & priv;
85 priv.max_fetched = priv.the_buffer;
86 priv.insn_start = addr;
87 if (OPCODES_SIGSETJMP (priv.bailout) != 0)
88 /* Error return. */
89 return -1;
90
91 /* Run down the table to find the one which matches. */
92 for (opcode = h8500_table; opcode->name; opcode++)
93 {
94 int byte;
95 int rn = 0;
96 int rd = 0;
97 int rs = 0;
98 int disp = 0;
99 int abs_val = 0;
100 int imm = 0;
101 int pcrel = 0;
102 int qim = 0;
103 int i;
104 int cr = 0;
105
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 goto next;
112
113 else
114 {
115 /* Extract any info parts. */
116 switch (opcode->bytes[byte].insert)
117 {
118 case 0:
119 case FP:
120 break;
121 default:
122 /* xgettext:c-format */
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_val =
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_val = (buffer[byte] << 8) | (buffer[byte + 1]);
164 break;
165 case ABS8:
166 abs_val = (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
208 the operands. */
209 FETCH_DATA (info, buffer + opcode->length);
210 (func) (stream, "%s\t", opcode->name);
211 for (i = 0; i < opcode->nargs; i++)
212 {
213 if (i)
214 (func) (stream, ",");
215 switch (opcode->arg_type[i])
216 {
217 case FP:
218 func (stream, "fp");
219 break;
220 case RNIND_D16:
221 func (stream, "@(0x%x:16,r%d)", disp, rn);
222 break;
223 case RNIND_D8:
224 func (stream, "@(0x%x:8 (%d),r%d)", disp & 0xff, disp, rn);
225 break;
226 case RDIND_D16:
227 func (stream, "@(0x%x:16,r%d)", disp, rd);
228 break;
229 case RDIND_D8:
230 func (stream, "@(0x%x:8 (%d), r%d)", disp & 0xff, disp, rd);
231 break;
232 case FPIND_D8:
233 func (stream, "@(0x%x:8 (%d), fp)", disp & 0xff, disp);
234 break;
235 case CRB:
236 case CRW:
237 func (stream, "%s", crname[cr]);
238 break;
239 case RN:
240 func (stream, "r%d", rn);
241 break;
242 case RD:
243 func (stream, "r%d", rd);
244 break;
245 case RS:
246 func (stream, "r%d", rs);
247 break;
248 case RNDEC:
249 func (stream, "@-r%d", rn);
250 break;
251 case RNINC:
252 func (stream, "@r%d+", rn);
253 break;
254 case RNIND:
255 func (stream, "@r%d", rn);
256 break;
257 case RDIND:
258 func (stream, "@r%d", rd);
259 break;
260 case SPINC:
261 func (stream, "@sp+");
262 break;
263 case SPDEC:
264 func (stream, "@-sp");
265 break;
266 case ABS24:
267 func (stream, "@0x%0x:24", abs_val);
268 break;
269 case ABS16:
270 func (stream, "@0x%0x:16", abs_val & 0xffff);
271 break;
272 case ABS8:
273 func (stream, "@0x%0x:8", abs_val & 0xff);
274 break;
275 case IMM16:
276 func (stream, "#0x%0x:16", imm & 0xffff);
277 break;
278 case RLIST:
279 {
280 int j;
281 int nc = 0;
282
283 func (stream, "(");
284 for (j = 0; j < 8; j++)
285 {
286 if (imm & (1 << j))
287 {
288 func (stream, "r%d", j);
289 if (nc)
290 func (stream, ",");
291 nc = 1;
292 }
293 }
294 func (stream, ")");
295 }
296 break;
297 case IMM8:
298 func (stream, "#0x%0x:8", imm & 0xff);
299 break;
300 case PCREL16:
301 func (stream, "0x%0x:16",
302 (int)(pcrel + addr + opcode->length) & 0xffff);
303 break;
304 case PCREL8:
305 func (stream, "#0x%0x:8",
306 (int)((char) pcrel + addr + opcode->length) & 0xffff);
307 break;
308 case QIM:
309 func (stream, "#%d:q", qim);
310 break;
311 case IMM4:
312 func (stream, "#%d:4", imm);
313 break;
314 }
315 }
316 return opcode->length;
317 next:
318 ;
319 }
320
321 /* Couldn't understand anything. */
322 /* xgettext:c-format */
323 func (stream, _("%02x\t\t*unknown*"), buffer[0]);
324 return 1;
325 }
This page took 0.036351 seconds and 4 git commands to generate.