add docs for r5900 arg characters
[deliverable/binutils-gdb.git] / opcodes / fr30-dis.c
CommitLineData
a86481d3
DB
1/* Disassembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4THIS FILE IS USED TO GENERATE fr30-dis.c.
5
6Copyright (C) 1996, 1997, 1998 Free Software Foundation, Inc.
7
8This file is part of the GNU Binutils and GDB, the GNU debugger.
9
10This program is free software; you can redistribute it and/or modify
11it under the terms of the GNU General Public License as published by
12the Free Software Foundation; either version 2, or (at your option)
13any later version.
14
15This program is distributed in the hope that it will be useful,
16but WITHOUT ANY WARRANTY; without even the implied warranty of
17MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18GNU General Public License for more details.
19
20You should have received a copy of the GNU General Public License
21along with this program; if not, write to the Free Software Foundation, Inc.,
2259 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
23
24#include "sysdep.h"
25#include <stdio.h>
26#include "ansidecl.h"
27#include "dis-asm.h"
28#include "bfd.h"
29#include "symcat.h"
30#include "fr30-opc.h"
31#include "opintl.h"
32
33#undef INLINE
34#ifdef __GNUC__
35#define INLINE __inline__
36#else
37#define INLINE
38#endif
39
40/* Default text to print if an instruction isn't recognized. */
41#define UNKNOWN_INSN_MSG _("*unknown*")
42
43static int extract_normal
95b03313
DE
44 PARAMS ((CGEN_OPCODE_DESC, CGEN_EXTRACT_INFO *, CGEN_INSN_INT,
45 unsigned int, int, int, int, bfd_vma, long *));
a86481d3
DB
46static void print_normal
47 PARAMS ((CGEN_OPCODE_DESC, PTR, long, unsigned int, bfd_vma, int));
48static void print_address
49 PARAMS ((CGEN_OPCODE_DESC, PTR, bfd_vma, unsigned int, bfd_vma, int));
50static void print_keyword
51 PARAMS ((CGEN_OPCODE_DESC, PTR, CGEN_KEYWORD *, long, unsigned int));
52static int extract_insn_normal
53 PARAMS ((CGEN_OPCODE_DESC, const CGEN_INSN *, CGEN_EXTRACT_INFO *,
95b03313 54 CGEN_INSN_INT, CGEN_FIELDS *, bfd_vma));
a86481d3
DB
55static void print_insn_normal
56 PARAMS ((CGEN_OPCODE_DESC, PTR, const CGEN_INSN *, CGEN_FIELDS *,
57 bfd_vma, int));
58static int print_insn PARAMS ((CGEN_OPCODE_DESC, bfd_vma,
59 disassemble_info *, char *, int));
60static int default_print_insn
61 PARAMS ((CGEN_OPCODE_DESC, bfd_vma, disassemble_info *));
62\f
63/* -- disassembler routines inserted here */
e17387a5
DB
64/* -- dis.c */
65
66static void
67print_register_list (dis_info, value, offset)
68 PTR dis_info;
69 long value;
70 long offset;
71{
72 disassemble_info *info = dis_info;
73 int mask = 1;
74 int index;
75
76 if (value & mask)
77 (*info->fprintf_func) (info->stream, "r%i", index + offset);
78
79 for (index = 1; index <= 7; ++index)
80 {
81 mask <<= 1;
82 if (value & mask)
83 (*info->fprintf_func) (info->stream, ",r%i", index + offset);
84 }
85}
86
87static void
b42d4375 88print_hi_register_list (od, dis_info, value, attrs, pc, length)
e17387a5
DB
89 CGEN_OPCODE_DESC od;
90 PTR dis_info;
91 long value;
92 unsigned int attrs;
93 bfd_vma pc;
94 int length;
95{
96 print_register_list (dis_info, value, 8);
97}
98
99static void
b42d4375 100print_low_register_list (od, dis_info, value, attrs, pc, length)
e17387a5
DB
101 CGEN_OPCODE_DESC od;
102 PTR dis_info;
103 long value;
104 unsigned int attrs;
105 bfd_vma pc;
106 int length;
107{
108 print_register_list (dis_info, value, 0);
109}
110
e1aa8a63
DB
111static void
112print_label9 (od, dis_info, value, attrs, pc, length)
113 CGEN_OPCODE_DESC od;
114 PTR dis_info;
115 long value;
116 unsigned int attrs;
117 bfd_vma pc;
118 int length;
119{
120 disassemble_info *info = (disassemble_info *) dis_info;
121 (*info->fprintf_func) (info->stream, "0x%lx", value);
122}
123
e17387a5 124/* -- */
a86481d3
DB
125
126/* Main entry point for operand extraction.
127
128 This function is basically just a big switch statement. Earlier versions
129 used tables to look up the function to use, but
130 - if the table contains both assembler and disassembler functions then
131 the disassembler contains much of the assembler and vice-versa,
132 - there's a lot of inlining possibilities as things grow,
133 - using a switch statement avoids the function call overhead.
134
135 This function could be moved into `print_insn_normal', but keeping it
136 separate makes clear the interface between `print_insn_normal' and each of
137 the handlers.
138*/
139
140int
141fr30_cgen_extract_operand (od, opindex, ex_info, insn_value, fields, pc)
142 CGEN_OPCODE_DESC od;
143 int opindex;
144 CGEN_EXTRACT_INFO *ex_info;
95b03313 145 CGEN_INSN_INT insn_value;
a86481d3
DB
146 CGEN_FIELDS * fields;
147 bfd_vma pc;
148{
149 int length;
150
151 switch (opindex)
152 {
153 case FR30_OPERAND_RI :
95b03313 154 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ri);
a86481d3
DB
155 break;
156 case FR30_OPERAND_RJ :
95b03313 157 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rj);
a86481d3 158 break;
e17387a5
DB
159 case FR30_OPERAND_RIC :
160 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Ric);
161 break;
162 case FR30_OPERAND_RJC :
163 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rjc);
164 break;
165 case FR30_OPERAND_CRI :
166 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 28, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_CRi);
167 break;
168 case FR30_OPERAND_CRJ :
169 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 24, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_CRj);
170 break;
7a0737c8 171 case FR30_OPERAND_RS1 :
95b03313 172 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs1);
7a0737c8
DB
173 break;
174 case FR30_OPERAND_RS2 :
95b03313 175 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_Rs2);
7a0737c8 176 break;
6a1254af 177 case FR30_OPERAND_R13 :
95b03313 178 length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
6a1254af
DB
179 break;
180 case FR30_OPERAND_R14 :
95b03313 181 length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
6a1254af
DB
182 break;
183 case FR30_OPERAND_R15 :
95b03313 184 length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
6a1254af
DB
185 break;
186 case FR30_OPERAND_PS :
95b03313 187 length = extract_normal (od, ex_info, insn_value, 0, 0, 0, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_nil);
6a1254af 188 break;
7a0737c8 189 case FR30_OPERAND_U4 :
95b03313 190 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4);
7a0737c8 191 break;
e17387a5
DB
192 case FR30_OPERAND_U4C :
193 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 12, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u4c);
194 break;
7a0737c8
DB
195 case FR30_OPERAND_M4 :
196 {
197 long value;
95b03313 198 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
7a0737c8
DB
199 value = ((value) | ((! (15))));
200 fields->f_m4 = value;
201 }
202 break;
6a1254af 203 case FR30_OPERAND_U8 :
95b03313 204 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_u8);
6a1254af 205 break;
7a0737c8 206 case FR30_OPERAND_I8 :
95b03313 207 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i8);
7a0737c8 208 break;
6a1254af
DB
209 case FR30_OPERAND_UDISP6 :
210 {
211 long value;
95b03313 212 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 4, CGEN_FIELDS_BITSIZE (fields), pc, & value);
6a1254af
DB
213 value = ((value) << (2));
214 fields->f_udisp6 = value;
215 }
216 break;
217 case FR30_OPERAND_DISP8 :
95b03313 218 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_disp8);
7a0737c8 219 break;
6a1254af
DB
220 case FR30_OPERAND_DISP9 :
221 {
222 long value;
95b03313 223 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
6a1254af
DB
224 value = ((value) << (1));
225 fields->f_disp9 = value;
226 }
227 break;
228 case FR30_OPERAND_DISP10 :
229 {
230 long value;
95b03313 231 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 4, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
6a1254af
DB
232 value = ((value) << (2));
233 fields->f_disp10 = value;
234 }
7a0737c8
DB
235 break;
236 case FR30_OPERAND_S10 :
237 {
238 long value;
95b03313 239 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
7a0737c8
DB
240 value = ((value) << (2));
241 fields->f_s10 = value;
242 }
243 break;
244 case FR30_OPERAND_U10 :
245 {
246 long value;
95b03313 247 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
7a0737c8
DB
248 value = ((value) << (2));
249 fields->f_u10 = value;
250 }
251 break;
95b03313
DE
252 case FR30_OPERAND_I32 :
253 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), 16, 32, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_i32);
254 break;
7a0737c8 255 case FR30_OPERAND_DIR8 :
95b03313 256 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_dir8);
7a0737c8
DB
257 break;
258 case FR30_OPERAND_DIR9 :
259 {
260 long value;
95b03313 261 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
7a0737c8
DB
262 value = ((value) << (1));
263 fields->f_dir9 = value;
264 }
265 break;
266 case FR30_OPERAND_DIR10 :
267 {
268 long value;
95b03313 269 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
7a0737c8
DB
270 value = ((value) << (2));
271 fields->f_dir10 = value;
272 }
273 break;
274 case FR30_OPERAND_LABEL9 :
275 {
276 long value;
988fcc4b 277 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & value);
b42d4375 278 value = ((((value) << (1))) + (((pc) + (2))));
6a1254af 279 fields->f_rel9 = value;
7a0737c8
DB
280 }
281 break;
282 case FR30_OPERAND_LABEL12 :
283 {
284 long value;
b42d4375 285 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), 5, 11, CGEN_FIELDS_BITSIZE (fields), pc, & value);
6a1254af
DB
286 value = ((((value) << (1))) + (((pc) & (-2))));
287 fields->f_rel12 = value;
7a0737c8
DB
288 }
289 break;
e17387a5
DB
290 case FR30_OPERAND_REGLIST_LOW :
291 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_reglist_low);
292 break;
293 case FR30_OPERAND_REGLIST_HI :
294 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 8, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_reglist_hi);
295 break;
7a0737c8 296 case FR30_OPERAND_CC :
95b03313 297 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_UNSIGNED), 4, 4, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_cc);
7a0737c8 298 break;
e17387a5
DB
299 case FR30_OPERAND_CCC :
300 length = extract_normal (od, ex_info, insn_value, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), 16, 8, CGEN_FIELDS_BITSIZE (fields), pc, & fields->f_ccc);
301 break;
a86481d3
DB
302
303 default :
304 /* xgettext:c-format */
305 fprintf (stderr, _("Unrecognized field %d while decoding insn.\n"),
306 opindex);
307 abort ();
308 }
309
310 return length;
311}
312
313/* Main entry point for printing operands.
314
315 This function is basically just a big switch statement. Earlier versions
316 used tables to look up the function to use, but
317 - if the table contains both assembler and disassembler functions then
318 the disassembler contains much of the assembler and vice-versa,
319 - there's a lot of inlining possibilities as things grow,
320 - using a switch statement avoids the function call overhead.
321
322 This function could be moved into `print_insn_normal', but keeping it
323 separate makes clear the interface between `print_insn_normal' and each of
324 the handlers.
325*/
326
327void
328fr30_cgen_print_operand (od, opindex, info, fields, attrs, pc, length)
329 CGEN_OPCODE_DESC od;
330 int opindex;
331 disassemble_info * info;
332 CGEN_FIELDS * fields;
333 void const * attrs;
334 bfd_vma pc;
335 int length;
336{
337 switch (opindex)
338 {
339 case FR30_OPERAND_RI :
340 print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ri, 0|(1<<CGEN_OPERAND_UNSIGNED));
341 break;
342 case FR30_OPERAND_RJ :
343 print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rj, 0|(1<<CGEN_OPERAND_UNSIGNED));
344 break;
e17387a5
DB
345 case FR30_OPERAND_RIC :
346 print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Ric, 0|(1<<CGEN_OPERAND_UNSIGNED));
347 break;
348 case FR30_OPERAND_RJC :
349 print_keyword (od, info, & fr30_cgen_opval_h_gr, fields->f_Rjc, 0|(1<<CGEN_OPERAND_UNSIGNED));
350 break;
351 case FR30_OPERAND_CRI :
352 print_keyword (od, info, & fr30_cgen_opval_h_cr, fields->f_CRi, 0|(1<<CGEN_OPERAND_UNSIGNED));
353 break;
354 case FR30_OPERAND_CRJ :
355 print_keyword (od, info, & fr30_cgen_opval_h_cr, fields->f_CRj, 0|(1<<CGEN_OPERAND_UNSIGNED));
356 break;
7a0737c8
DB
357 case FR30_OPERAND_RS1 :
358 print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs1, 0|(1<<CGEN_OPERAND_UNSIGNED));
359 break;
360 case FR30_OPERAND_RS2 :
361 print_keyword (od, info, & fr30_cgen_opval_h_dr, fields->f_Rs2, 0|(1<<CGEN_OPERAND_UNSIGNED));
362 break;
6a1254af
DB
363 case FR30_OPERAND_R13 :
364 print_keyword (od, info, & fr30_cgen_opval_h_r13, fields->f_nil, 0);
365 break;
366 case FR30_OPERAND_R14 :
367 print_keyword (od, info, & fr30_cgen_opval_h_r14, fields->f_nil, 0);
368 break;
369 case FR30_OPERAND_R15 :
370 print_keyword (od, info, & fr30_cgen_opval_h_r15, fields->f_nil, 0);
371 break;
372 case FR30_OPERAND_PS :
373 print_keyword (od, info, & fr30_cgen_opval_h_ps, fields->f_nil, 0);
374 break;
7a0737c8
DB
375 case FR30_OPERAND_U4 :
376 print_normal (od, info, fields->f_u4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
377 break;
e17387a5
DB
378 case FR30_OPERAND_U4C :
379 print_normal (od, info, fields->f_u4c, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
380 break;
7a0737c8
DB
381 case FR30_OPERAND_M4 :
382 print_normal (od, info, fields->f_m4, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
383 break;
6a1254af
DB
384 case FR30_OPERAND_U8 :
385 print_normal (od, info, fields->f_u8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
386 break;
7a0737c8
DB
387 case FR30_OPERAND_I8 :
388 print_normal (od, info, fields->f_i8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
389 break;
6a1254af
DB
390 case FR30_OPERAND_UDISP6 :
391 print_normal (od, info, fields->f_udisp6, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
392 break;
393 case FR30_OPERAND_DISP8 :
394 print_normal (od, info, fields->f_disp8, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
395 break;
396 case FR30_OPERAND_DISP9 :
397 print_normal (od, info, fields->f_disp9, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
7a0737c8 398 break;
6a1254af
DB
399 case FR30_OPERAND_DISP10 :
400 print_normal (od, info, fields->f_disp10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
7a0737c8
DB
401 break;
402 case FR30_OPERAND_S10 :
403 print_normal (od, info, fields->f_s10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGNED), pc, length);
404 break;
405 case FR30_OPERAND_U10 :
406 print_normal (od, info, fields->f_u10, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
407 break;
95b03313
DE
408 case FR30_OPERAND_I32 :
409 print_normal (od, info, fields->f_i32, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_SIGN_OPT)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
410 break;
7a0737c8
DB
411 case FR30_OPERAND_DIR8 :
412 print_normal (od, info, fields->f_dir8, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
413 break;
414 case FR30_OPERAND_DIR9 :
415 print_normal (od, info, fields->f_dir9, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
416 break;
417 case FR30_OPERAND_DIR10 :
418 print_normal (od, info, fields->f_dir10, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
419 break;
420 case FR30_OPERAND_LABEL9 :
e1aa8a63 421 print_label9 (od, info, fields->f_rel9, 0|(1<<CGEN_OPERAND_RELOC)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
7a0737c8
DB
422 break;
423 case FR30_OPERAND_LABEL12 :
b42d4375 424 print_normal (od, info, fields->f_rel12, 0|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_SIGNED), pc, length);
7a0737c8 425 break;
e17387a5 426 case FR30_OPERAND_REGLIST_LOW :
b42d4375 427 print_low_register_list (od, info, fields->f_reglist_low, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
e17387a5
DB
428 break;
429 case FR30_OPERAND_REGLIST_HI :
b42d4375 430 print_hi_register_list (od, info, fields->f_reglist_hi, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
e17387a5 431 break;
7a0737c8
DB
432 case FR30_OPERAND_CC :
433 print_normal (od, info, fields->f_cc, 0|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
434 break;
e17387a5
DB
435 case FR30_OPERAND_CCC :
436 print_normal (od, info, fields->f_ccc, 0|(1<<CGEN_OPERAND_HASH_PREFIX)|(1<<CGEN_OPERAND_UNSIGNED), pc, length);
437 break;
a86481d3
DB
438
439 default :
440 /* xgettext:c-format */
441 fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
442 opindex);
443 abort ();
444 }
445}
446
447cgen_extract_fn * const fr30_cgen_extract_handlers[] =
448{
449 0, /* default */
450 extract_insn_normal,
451};
452
453cgen_print_fn * const fr30_cgen_print_handlers[] =
454{
455 0, /* default */
456 print_insn_normal,
457};
458
459
460void
461fr30_cgen_init_dis (od)
462 CGEN_OPCODE_DESC od;
463{
464}
465
466\f
467#if ! CGEN_INT_INSN_P
468
95b03313
DE
469/* Subroutine of extract_normal.
470 Ensure sufficient bytes are cached in EX_INFO.
471 Returns 1 for success, 0 for failure. */
472
473static INLINE int
474fill_cache (od, ex_info, offset, bytes, pc)
475 CGEN_OPCODE_DESC od;
476 CGEN_EXTRACT_INFO *ex_info;
477 int offset, bytes;
478 bfd_vma pc;
479{
480 /* It's doubtful that the middle part has already been fetched so
481 we don't optimize that case. kiss. */
482 int mask;
483 disassemble_info *info = (disassemble_info *) ex_info->dis_info;
484
485 /* First do a quick check. */
486 mask = (1 << bytes) - 1;
487 if (((ex_info->valid >> offset) & mask) == mask)
488 return 1;
489
490 /* Search for the first byte we need to read. */
491 for (mask = 1 << offset; bytes > 0; --bytes, ++offset, mask <<= 1)
492 if (! (mask & ex_info->valid))
493 break;
494
495 if (bytes)
496 {
497 int status;
498
499 pc += offset;
500 status = (*info->read_memory_func)
501 (pc, ex_info->insn_bytes + offset, bytes, info);
502
503 if (status != 0)
504 {
505 (*info->memory_error_func) (status, pc, info);
506 return 0;
507 }
508
509 ex_info->valid |= ((1 << bytes) - 1) << offset;
510 }
511
512 return 1;
513}
514
a86481d3
DB
515/* Subroutine of extract_normal. */
516
517static INLINE long
95b03313 518extract_1 (od, ex_info, start, length, word_length, bufp, pc)
a86481d3 519 CGEN_OPCODE_DESC od;
95b03313 520 CGEN_EXTRACT_INFO *ex_info;
a86481d3
DB
521 int start,length,word_length;
522 unsigned char *bufp;
95b03313 523 bfd_vma pc;
a86481d3
DB
524{
525 unsigned long x,mask;
526 int shift;
527 int big_p = CGEN_OPCODE_INSN_ENDIAN (od) == CGEN_ENDIAN_BIG;
528
a86481d3
DB
529 switch (word_length)
530 {
531 case 8:
532 x = *bufp;
533 break;
534 case 16:
535 if (big_p)
536 x = bfd_getb16 (bufp);
537 else
538 x = bfd_getl16 (bufp);
539 break;
540 case 24:
541 /* ??? This may need reworking as these cases don't necessarily
542 want the first byte and the last two bytes handled like this. */
543 if (big_p)
95b03313 544 x = (bufp[0] << 16) | bfd_getb16 (bufp + 1);
a86481d3 545 else
95b03313 546 x = bfd_getl16 (bufp) | (bufp[2] << 16);
a86481d3
DB
547 break;
548 case 32:
549 if (big_p)
550 x = bfd_getb32 (bufp);
551 else
552 x = bfd_getl32 (bufp);
553 break;
554 default :
555 abort ();
556 }
557
558 /* Written this way to avoid undefined behaviour. */
559 mask = (((1L << (length - 1)) - 1) << 1) | 1;
560 if (CGEN_INSN_LSB0_P)
561 shift = start;
562 else
563 shift = (word_length - (start + length));
564 return (x >> shift) & mask;
565}
566
567#endif /* ! CGEN_INT_INSN_P */
568
569/* Default extraction routine.
570
95b03313
DE
571 INSN_VALUE is the first CGEN_BASE_INSN_SIZE bits of the insn in host order,
572 or sometimes less for cases like the m32r where the base insn size is 32
573 but some insns are 16 bits.
a86481d3 574 ATTRS is a mask of the boolean attributes. We only need `unsigned',
95b03313
DE
575 but for generality we take a bitmask of all of them.
576 TOTAL_LENGTH is the length of the insn in bits.
577
578 Returns 1 for success, 0 for failure. */
a86481d3
DB
579
580/* ??? This doesn't handle bfd_vma's. Create another function when
581 necessary. */
582
583static int
95b03313 584extract_normal (od, ex_info, insn_value, attrs, start, length, total_length, pc, valuep)
a86481d3
DB
585 CGEN_OPCODE_DESC od;
586 CGEN_EXTRACT_INFO *ex_info;
95b03313 587 CGEN_INSN_INT insn_value;
a86481d3
DB
588 unsigned int attrs;
589 int start, length, total_length;
95b03313 590 bfd_vma pc;
a86481d3
DB
591 long *valuep;
592{
593 unsigned long value;
594
595 /* If LENGTH is zero, this operand doesn't contribute to the value
596 so give it a standard value of zero. */
597 if (length == 0)
598 {
599 *valuep = 0;
600 return 1;
601 }
602
95b03313
DE
603 if (CGEN_INT_INSN_P
604 || (CGEN_INSN_LSB0_P
605 ? ((total_length - start) <= CGEN_BASE_INSN_BITSIZE)
606 : ((start + length) <= CGEN_BASE_INSN_BITSIZE)))
607 {
608 /* Written this way to avoid undefined behaviour. */
609 unsigned long mask = (((1L << (length - 1)) - 1) << 1) | 1;
a86481d3 610
95b03313
DE
611 if (CGEN_INSN_LSB0_P)
612 value = insn_value >> start;
613 else
614 value = insn_value >> (total_length - (start + length));
615 value &= mask;
616 /* sign extend? */
617 if (! (attrs & CGEN_ATTR_MASK (CGEN_OPERAND_UNSIGNED))
618 && (value & (1L << (length - 1))))
619 value |= ~mask;
620 }
621
622#if ! CGEN_INT_INSN_P
a86481d3
DB
623
624 /* The hard case is probably too slow for the normal cases.
625 It's certainly more difficult to understand than the normal case.
95b03313 626 Thus this is split into two. The hard case is defined
a86481d3
DB
627 to be when a field straddles a (loosely defined) word boundary
628 (??? which may require target specific help to determine). */
629
a86481d3
DB
630#define HARD_CASE_P 0 /* FIXME:wip */
631
95b03313 632 else if (HARD_CASE_P)
a86481d3
DB
633 {
634 }
95b03313 635
a86481d3
DB
636 else
637 {
95b03313
DE
638 unsigned char *bufp = ex_info->insn_bytes;
639 int offset = 0;
a86481d3
DB
640
641 if (length > 32)
642 abort ();
643
644 /* Adjust start,total_length,bufp to point to the pseudo-word that holds
645 the value. For example in a 48 bit insn where the value to insert
95b03313 646 (say an immediate value) is the last 16 bits then fetch_length here
a86481d3 647 would be 16. To handle a 24 bit insn with an 18 bit immediate,
95b03313 648 extract_1 handles 24 bits. */
a86481d3
DB
649
650 if (total_length > 32)
651 {
652 int needed_width = start % 8 + length;
653 int fetch_length = (needed_width <= 8 ? 8
654 : needed_width <= 16 ? 16
655 : 32);
656
657 if (CGEN_INSN_LSB0_P)
658 {
659 if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
660 {
661 abort (); /* wip */
662 }
663 else
664 {
95b03313 665 offset = start & ~7;
a86481d3
DB
666
667 bufp += offset / 8;
668 start -= offset;
95b03313 669 total_length = fetch_length;
a86481d3
DB
670 }
671 }
672 else
673 {
674 if (CGEN_INSN_WORD_ENDIAN (od) == CGEN_ENDIAN_BIG)
675 {
95b03313 676 offset = start & ~7;
a86481d3
DB
677
678 bufp += offset / 8;
679 start -= offset;
95b03313 680 total_length = fetch_length;
a86481d3
DB
681 }
682 else
683 {
684 abort (); /* wip */
685 }
686 }
687 }
688
95b03313
DE
689 if (fill_cache (od, ex_info, offset / 8, total_length / 8, pc) == 0)
690 return 0;
691
692 value = extract_1 (od, ex_info, start, length, total_length, bufp, pc);
a86481d3
DB
693 }
694
695#endif /* ! CGEN_INT_INSN_P */
696
697 *valuep = value;
698
a86481d3
DB
699 return 1;
700}
701
702/* Default print handler. */
703
704static void
705print_normal (od, dis_info, value, attrs, pc, length)
706 CGEN_OPCODE_DESC od;
707 PTR dis_info;
708 long value;
709 unsigned int attrs;
710 bfd_vma pc;
711 int length;
712{
713 disassemble_info *info = (disassemble_info *) dis_info;
714
715#ifdef CGEN_PRINT_NORMAL
716 CGEN_PRINT_NORMAL (od, info, value, attrs, pc, length);
717#endif
718
719 /* Print the operand as directed by the attributes. */
1c8f439e 720 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
a86481d3
DB
721 ; /* nothing to do */
722 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
723 (*info->fprintf_func) (info->stream, "0x%lx", value);
724 else
725 (*info->fprintf_func) (info->stream, "%ld", value);
726}
727
728/* Default address handler. */
729
730static void
731print_address (od, dis_info, value, attrs, pc, length)
732 CGEN_OPCODE_DESC od;
733 PTR dis_info;
734 bfd_vma value;
735 unsigned int attrs;
736 bfd_vma pc;
737 int length;
738{
739 disassemble_info *info = (disassemble_info *) dis_info;
740
741#ifdef CGEN_PRINT_ADDRESS
742 CGEN_PRINT_ADDRESS (od, info, value, attrs, pc, length);
743#endif
744
745 /* Print the operand as directed by the attributes. */
1c8f439e 746 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
a86481d3
DB
747 ; /* nothing to do */
748 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
749 (*info->print_address_func) (value, info);
750 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
751 (*info->print_address_func) (value, info);
752 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_UNSIGNED))
753 (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
754 else
755 (*info->fprintf_func) (info->stream, "%ld", (long) value);
756}
757
758/* Keyword print handler. */
759
760static void
761print_keyword (od, dis_info, keyword_table, value, attrs)
762 CGEN_OPCODE_DESC od;
763 PTR dis_info;
764 CGEN_KEYWORD *keyword_table;
765 long value;
766 unsigned int attrs;
767{
768 disassemble_info *info = (disassemble_info *) dis_info;
769 const CGEN_KEYWORD_ENTRY *ke;
770
771 ke = cgen_keyword_lookup_value (keyword_table, value);
772 if (ke != NULL)
773 (*info->fprintf_func) (info->stream, "%s", ke->name);
774 else
775 (*info->fprintf_func) (info->stream, "???");
776}
777\f
778/* Default insn extractor.
779
780 INSN_VALUE is the first CGEN_BASE_INSN_SIZE bytes, translated to host order.
781 The extracted fields are stored in FIELDS.
782 EX_INFO is used to handle reading variable length insns.
783 Return the length of the insn in bits, or 0 if no match,
784 or -1 if an error occurs fetching data (memory_error_func will have
785 been called). */
786
787static int
788extract_insn_normal (od, insn, ex_info, insn_value, fields, pc)
789 CGEN_OPCODE_DESC od;
790 const CGEN_INSN *insn;
791 CGEN_EXTRACT_INFO *ex_info;
95b03313 792 CGEN_INSN_INT insn_value;
a86481d3
DB
793 CGEN_FIELDS *fields;
794 bfd_vma pc;
795{
796 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
797 const unsigned char *syn;
798
799 CGEN_FIELDS_BITSIZE (fields) = CGEN_INSN_BITSIZE (insn);
800
801 CGEN_INIT_EXTRACT (od);
802
803 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
804 {
805 int length;
806
807 if (CGEN_SYNTAX_CHAR_P (*syn))
808 continue;
809
810 length = fr30_cgen_extract_operand (od, CGEN_SYNTAX_FIELD (*syn),
811 ex_info, insn_value, fields, pc);
812 if (length <= 0)
813 return length;
814 }
815
816 /* We recognized and successfully extracted this insn. */
817 return CGEN_INSN_BITSIZE (insn);
818}
819
820/* Default insn printer.
821
822 DIS_INFO is defined as `PTR' so the disassembler needn't know anything
823 about disassemble_info. */
824
825static void
826print_insn_normal (od, dis_info, insn, fields, pc, length)
827 CGEN_OPCODE_DESC od;
828 PTR dis_info;
829 const CGEN_INSN *insn;
830 CGEN_FIELDS *fields;
831 bfd_vma pc;
832 int length;
833{
834 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
835 disassemble_info *info = (disassemble_info *) dis_info;
836 const unsigned char *syn;
837
838 CGEN_INIT_PRINT (od);
839
840 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
841 {
842 if (CGEN_SYNTAX_MNEMONIC_P (*syn))
843 {
844 (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
845 continue;
846 }
847 if (CGEN_SYNTAX_CHAR_P (*syn))
848 {
849 (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
850 continue;
851 }
852
853 /* We have an operand. */
854 fr30_cgen_print_operand (od, CGEN_SYNTAX_FIELD (*syn), info,
855 fields, CGEN_INSN_ATTRS (insn), pc, length);
856 }
857}
858\f
859/* Utility to print an insn.
860 BUF is the base part of the insn, target byte order, BUFLEN bytes long.
861 The result is the size of the insn in bytes or zero for an unknown insn
862 or -1 if an error occurs fetching data (memory_error_func will have
863 been called). */
864
865static int
866print_insn (od, pc, info, buf, buflen)
867 CGEN_OPCODE_DESC od;
868 bfd_vma pc;
869 disassemble_info *info;
870 char *buf;
871 int buflen;
872{
873 unsigned long insn_value;
874 const CGEN_INSN_LIST *insn_list;
875 CGEN_EXTRACT_INFO ex_info;
876
877 ex_info.dis_info = info;
878 ex_info.valid = (1 << CGEN_BASE_INSN_SIZE) - 1;
95b03313 879 ex_info.insn_bytes = buf;
a86481d3
DB
880
881 switch (buflen)
882 {
883 case 1:
884 insn_value = buf[0];
885 break;
886 case 2:
887 insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb16 (buf) : bfd_getl16 (buf);
888 break;
889 case 4:
890 insn_value = info->endian == BFD_ENDIAN_BIG ? bfd_getb32 (buf) : bfd_getl32 (buf);
891 break;
892 default:
893 abort ();
894 }
895
896 /* The instructions are stored in hash lists.
897 Pick the first one and keep trying until we find the right one. */
898
899 insn_list = CGEN_DIS_LOOKUP_INSN (od, buf, insn_value);
900 while (insn_list != NULL)
901 {
902 const CGEN_INSN *insn = insn_list->insn;
903 CGEN_FIELDS fields;
904 int length;
905
906#if 0 /* not needed as insn shouldn't be in hash lists if not supported */
907 /* Supported by this cpu? */
908 if (! fr30_cgen_insn_supported (od, insn))
909 continue;
910#endif
911
912 /* Basic bit mask must be correct. */
913 /* ??? May wish to allow target to defer this check until the extract
914 handler. */
915 if ((insn_value & CGEN_INSN_MASK (insn)) == CGEN_INSN_VALUE (insn))
916 {
917 /* Printing is handled in two passes. The first pass parses the
918 machine insn and extracts the fields. The second pass prints
919 them. */
920
921 length = (*CGEN_EXTRACT_FN (insn)) (od, insn, &ex_info, insn_value,
922 &fields, pc);
923 /* length < 0 -> error */
924 if (length < 0)
925 return length;
926 if (length > 0)
927 {
928 (*CGEN_PRINT_FN (insn)) (od, info, insn, &fields, pc, length);
929 /* length is in bits, result is in bytes */
930 return length / 8;
931 }
932 }
933
934 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
935 }
936
937 return 0;
938}
939
940/* Default value for CGEN_PRINT_INSN.
941 The result is the size of the insn in bytes or zero for an unknown insn
942 or -1 if an error occured fetching bytes. */
943
944#ifndef CGEN_PRINT_INSN
945#define CGEN_PRINT_INSN default_print_insn
946#endif
947
948static int
949default_print_insn (od, pc, info)
950 CGEN_OPCODE_DESC od;
951 bfd_vma pc;
952 disassemble_info *info;
953{
954 char buf[CGEN_MAX_INSN_SIZE];
955 int status;
956
957 /* Read the base part of the insn. */
958
959 status = (*info->read_memory_func) (pc, buf, CGEN_BASE_INSN_SIZE, info);
960 if (status != 0)
961 {
962 (*info->memory_error_func) (status, pc, info);
963 return -1;
964 }
965
966 return print_insn (od, pc, info, buf, CGEN_BASE_INSN_SIZE);
967}
968
969/* Main entry point.
970 Print one instruction from PC on INFO->STREAM.
971 Return the size of the instruction (in bytes). */
972
973int
974print_insn_fr30 (pc, info)
975 bfd_vma pc;
976 disassemble_info *info;
977{
978 int length;
979 static CGEN_OPCODE_DESC od = 0;
980 int mach = info->mach;
981 int big_p = info->endian == BFD_ENDIAN_BIG;
982
983 /* If we haven't initialized yet, initialize the opcode table. */
984 if (! od)
985 {
986 od = fr30_cgen_opcode_open (mach,
987 big_p ?
988 CGEN_ENDIAN_BIG
989 : CGEN_ENDIAN_LITTLE);
990 fr30_cgen_init_dis (od);
991 }
992 /* If we've switched cpu's, re-initialize. */
993 /* ??? Perhaps we should use BFD_ENDIAN. */
994 else if (mach != CGEN_OPCODE_MACH (od)
995 || (CGEN_OPCODE_ENDIAN (od)
996 != (big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE)))
997 {
998 cgen_set_cpu (od, mach, big_p ? CGEN_ENDIAN_BIG : CGEN_ENDIAN_LITTLE);
999 }
1000
1001 /* We try to have as much common code as possible.
1002 But at this point some targets need to take over. */
1003 /* ??? Some targets may need a hook elsewhere. Try to avoid this,
1004 but if not possible try to move this hook elsewhere rather than
1005 have two hooks. */
1006 length = CGEN_PRINT_INSN (od, pc, info);
1007 if (length > 0)
1008 return length;
1009 if (length < 0)
1010 return -1;
1011
1012 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1013 return CGEN_DEFAULT_INSN_SIZE;
1014}
This page took 0.065057 seconds and 4 git commands to generate.