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