* elf32-mep.c (config_names): Regenerate configuration.
[deliverable/binutils-gdb.git] / opcodes / mep-dis.c
1 /* Disassembler interface for targets using CGEN. -*- C -*-
2 CGEN: Cpu tools GENerator
3
4 THIS FILE IS MACHINE GENERATED WITH CGEN.
5 - the resultant file is machine generated, cgen-dis.in isn't
6
7 Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2007,
8 2008 Free Software Foundation, Inc.
9
10 This file is part of libopcodes.
11
12 This library is free software; you can redistribute it and/or modify
13 it under the terms of the GNU General Public License as published by
14 the Free Software Foundation; either version 3, or (at your option)
15 any later version.
16
17 It is distributed in the hope that it will be useful, but WITHOUT
18 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
19 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
20 License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software Foundation, Inc.,
24 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
25
26 /* ??? Eventually more and more of this stuff can go to cpu-independent files.
27 Keep that in mind. */
28
29 #include "sysdep.h"
30 #include <stdio.h>
31 #include "ansidecl.h"
32 #include "dis-asm.h"
33 #include "bfd.h"
34 #include "symcat.h"
35 #include "libiberty.h"
36 #include "mep-desc.h"
37 #include "mep-opc.h"
38 #include "opintl.h"
39
40 /* Default text to print if an instruction isn't recognized. */
41 #define UNKNOWN_INSN_MSG _("*unknown*")
42
43 static void print_normal
44 (CGEN_CPU_DESC, void *, long, unsigned int, bfd_vma, int);
45 static void print_address
46 (CGEN_CPU_DESC, void *, bfd_vma, unsigned int, bfd_vma, int) ATTRIBUTE_UNUSED;
47 static void print_keyword
48 (CGEN_CPU_DESC, void *, CGEN_KEYWORD *, long, unsigned int) ATTRIBUTE_UNUSED;
49 static void print_insn_normal
50 (CGEN_CPU_DESC, void *, const CGEN_INSN *, CGEN_FIELDS *, bfd_vma, int);
51 static int print_insn
52 (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, unsigned);
53 static int default_print_insn
54 (CGEN_CPU_DESC, bfd_vma, disassemble_info *) ATTRIBUTE_UNUSED;
55 static int read_insn
56 (CGEN_CPU_DESC, bfd_vma, disassemble_info *, bfd_byte *, int, CGEN_EXTRACT_INFO *,
57 unsigned long *);
58 \f
59 /* -- disassembler routines inserted here. */
60
61 /* -- dis.c */
62
63 #include "elf/mep.h"
64 #include "elf-bfd.h"
65
66 #define CGEN_VALIDATE_INSN_SUPPORTED
67
68 static void print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
69 static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
70
71 static void
72 print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
73 CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
74 unsigned int flags ATTRIBUTE_UNUSED)
75 {
76 disassemble_info *info = (disassemble_info *) dis_info;
77
78 (*info->fprintf_func) (info->stream, "$tp");
79 }
80
81 static void
82 print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
83 CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
84 unsigned int flags ATTRIBUTE_UNUSED)
85 {
86 disassemble_info *info = (disassemble_info *) dis_info;
87
88 (*info->fprintf_func) (info->stream, "$sp");
89 }
90
91 /* begin-cop-ip-print-handlers */
92 /* end-cop-ip-print-handlers */
93
94 /************************************************************\
95 *********************** Experimental *************************
96 \************************************************************/
97
98 #undef CGEN_PRINT_INSN
99 #define CGEN_PRINT_INSN mep_print_insn
100
101 static int
102 mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
103 bfd_byte *buf, int corelength, int copro1length,
104 int copro2length ATTRIBUTE_UNUSED)
105 {
106 int i;
107 int status = 0;
108 /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
109 bfd_byte insnbuf[64];
110
111 /* If corelength > 0 then there is a core insn present. It
112 will be at the beginning of the buffer. After printing
113 the core insn, we need to print the + on the next line. */
114 if (corelength > 0)
115 {
116 int my_status = 0;
117
118 for (i = 0; i < corelength; i++ )
119 insnbuf[i] = buf[i];
120 cd->isas = & MEP_CORE_ISA;
121
122 my_status = print_insn (cd, pc, info, insnbuf, corelength);
123 if (my_status != corelength)
124 {
125 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
126 my_status = corelength;
127 }
128 status += my_status;
129
130 /* Print the + to indicate that the following copro insn is */
131 /* part of a vliw group. */
132 if (copro1length > 0)
133 (*info->fprintf_func) (info->stream, " + ");
134 }
135
136 /* Now all that is left to be processed is the coprocessor insns
137 In vliw mode, there will always be one. Its positioning will
138 be from byte corelength to byte corelength+copro1length -1.
139 No need to check for existence. Also, the first vliw insn,
140 will, as spec'd, always be at least as long as the core insn
141 so we don't need to flush the buffer. */
142 if (copro1length > 0)
143 {
144 int my_status = 0;
145
146 for (i = corelength; i < corelength + copro1length; i++ )
147 insnbuf[i - corelength] = buf[i];
148
149 switch (copro1length)
150 {
151 case 0:
152 break;
153 case 2:
154 cd->isas = & MEP_COP16_ISA;
155 break;
156 case 4:
157 cd->isas = & MEP_COP32_ISA;
158 break;
159 case 6:
160 cd->isas = & MEP_COP48_ISA;
161 break;
162 case 8:
163 cd->isas = & MEP_COP64_ISA;
164 break;
165 default:
166 /* Shouldn't be anything but 16,32,48,64. */
167 break;
168 }
169
170 my_status = print_insn (cd, pc, info, insnbuf, copro1length);
171
172 if (my_status != copro1length)
173 {
174 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
175 my_status = copro1length;
176 }
177 status += my_status;
178 }
179
180 #if 0
181 /* Now we need to process the second copro insn if it exists. We
182 have no guarantee that the second copro insn will be longer
183 than the first, so we have to flush the buffer if we are have
184 a second copro insn to process. If present, this insn will
185 be in the position from byte corelength+copro1length to byte
186 corelength+copro1length+copro2length-1 (which better equal 8
187 or else we're in big trouble. */
188 if (copro2length > 0)
189 {
190 int my_status = 0;
191
192 for (i = 0; i < 64 ; i++)
193 insnbuf[i] = 0;
194
195 for (i = corelength + copro1length; i < 64; i++)
196 insnbuf[i - (corelength + copro1length)] = buf[i];
197
198 switch (copro2length)
199 {
200 case 2:
201 cd->isas = 1 << ISA_EXT_COP1_16;
202 break;
203 case 4:
204 cd->isas = 1 << ISA_EXT_COP1_32;
205 break;
206 case 6:
207 cd->isas = 1 << ISA_EXT_COP1_48;
208 break;
209 case 8:
210 cd->isas = 1 << ISA_EXT_COP1_64;
211 break;
212 default:
213 /* Shouldn't be anything but 16,32,48,64. */
214 break;
215 }
216
217 my_status = print_insn (cd, pc, info, insnbuf, copro2length);
218
219 if (my_status != copro2length)
220 {
221 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
222 my_status = copro2length;
223 }
224
225 status += my_status;
226 }
227 #endif
228
229 /* Status should now be the number of bytes that were printed
230 which should be 4 for VLIW32 mode and 64 for VLIW64 mode. */
231
232 if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
233 return -1;
234 else
235 return status;
236 }
237
238 /* The two functions mep_examine_vliw[32,64]_insns are used find out
239 which vliw combinaion (16 bit core with 48 bit copro, 32 bit core
240 with 32 bit copro, etc.) is present. Later on, when internally
241 parallel coprocessors are handled, only these functions should
242 need to be changed.
243
244 At this time only the following combinations are supported:
245
246 VLIW32 Mode:
247 16 bit core insn (core) and 16 bit coprocessor insn (cop1)
248 32 bit core insn (core)
249 32 bit coprocessor insn (cop1)
250 Note: As of this time, I do not believe we have enough information
251 to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
252 no 16 bit coprocessor insns have been specified.
253
254 VLIW64 Mode:
255 16 bit core insn (core) and 48 bit coprocessor insn (cop1)
256 32 bit core insn (core) and 32 bit coprocessor insn (cop1)
257 64 bit coprocessor insn (cop1)
258
259 The framework for an internally parallel coprocessor is also
260 present (2nd coprocessor insn is cop2), but at this time it
261 is not used. This only appears to be valid in VLIW64 mode. */
262
263 static int
264 mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
265 {
266 int status;
267 int buflength;
268 int corebuflength;
269 int cop1buflength;
270 int cop2buflength;
271 bfd_byte buf[CGEN_MAX_INSN_SIZE];
272 char indicator16[1];
273 char indicatorcop32[2];
274
275 /* At this time we're not supporting internally parallel coprocessors,
276 so cop2buflength will always be 0. */
277 cop2buflength = 0;
278
279 /* Read in 32 bits. */
280 buflength = 4; /* VLIW insn spans 4 bytes. */
281 status = (*info->read_memory_func) (pc, buf, buflength, info);
282
283 if (status != 0)
284 {
285 (*info->memory_error_func) (status, pc, info);
286 return -1;
287 }
288
289 /* Put the big endian representation of the bytes to be examined
290 in the temporary buffers for examination. */
291
292 if (info->endian == BFD_ENDIAN_BIG)
293 {
294 indicator16[0] = buf[0];
295 indicatorcop32[0] = buf[0];
296 indicatorcop32[1] = buf[1];
297 }
298 else
299 {
300 indicator16[0] = buf[1];
301 indicatorcop32[0] = buf[1];
302 indicatorcop32[1] = buf[0];
303 }
304
305 /* If the two high order bits are 00, 01 or 10, we have a 16 bit
306 core insn and a 48 bit copro insn. */
307
308 if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
309 {
310 if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
311 {
312 /* We have a 32 bit copro insn. */
313 corebuflength = 0;
314 /* All 4 4ytes are one copro insn. */
315 cop1buflength = 4;
316 }
317 else
318 {
319 /* We have a 32 bit core. */
320 corebuflength = 4;
321 cop1buflength = 0;
322 }
323 }
324 else
325 {
326 /* We have a 16 bit core insn and a 16 bit copro insn. */
327 corebuflength = 2;
328 cop1buflength = 2;
329 }
330
331 /* Now we have the distrubution set. Print them out. */
332 status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
333 cop1buflength, cop2buflength);
334
335 return status;
336 }
337
338 static int
339 mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
340 {
341 int status;
342 int buflength;
343 int corebuflength;
344 int cop1buflength;
345 int cop2buflength;
346 bfd_byte buf[CGEN_MAX_INSN_SIZE];
347 char indicator16[1];
348 char indicator64[4];
349
350 /* At this time we're not supporting internally parallel
351 coprocessors, so cop2buflength will always be 0. */
352 cop2buflength = 0;
353
354 /* Read in 64 bits. */
355 buflength = 8; /* VLIW insn spans 8 bytes. */
356 status = (*info->read_memory_func) (pc, buf, buflength, info);
357
358 if (status != 0)
359 {
360 (*info->memory_error_func) (status, pc, info);
361 return -1;
362 }
363
364 /* We have all 64 bits in the buffer now. We have to figure out
365 what combination of instruction sizes are present. The two
366 high order bits will indicate whether or not we have a 16 bit
367 core insn or not. If not, then we have to look at the 7,8th
368 bytes to tell whether we have 64 bit copro insn or a 32 bit
369 core insn with a 32 bit copro insn. Endianness will make a
370 difference here. */
371
372 /* Put the big endian representation of the bytes to be examined
373 in the temporary buffers for examination. */
374
375 /* indicator16[0] = buf[0]; */
376 if (info->endian == BFD_ENDIAN_BIG)
377 {
378 indicator16[0] = buf[0];
379 indicator64[0] = buf[0];
380 indicator64[1] = buf[1];
381 indicator64[2] = buf[2];
382 indicator64[3] = buf[3];
383 }
384 else
385 {
386 indicator16[0] = buf[1];
387 indicator64[0] = buf[1];
388 indicator64[1] = buf[0];
389 indicator64[2] = buf[3];
390 indicator64[3] = buf[2];
391 }
392
393 /* If the two high order bits are 00, 01 or 10, we have a 16 bit
394 core insn and a 48 bit copro insn. */
395
396 if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
397 {
398 if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
399 && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
400 {
401 /* We have a 64 bit copro insn. */
402 corebuflength = 0;
403 /* All 8 bytes are one copro insn. */
404 cop1buflength = 8;
405 }
406 else
407 {
408 /* We have a 32 bit core insn and a 32 bit copro insn. */
409 corebuflength = 4;
410 cop1buflength = 4;
411 }
412 }
413 else
414 {
415 /* We have a 16 bit core insn and a 48 bit copro insn. */
416 corebuflength = 2;
417 cop1buflength = 6;
418 }
419
420 /* Now we have the distrubution set. Print them out. */
421 status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
422 cop1buflength, cop2buflength);
423
424 return status;
425 }
426
427 static int
428 mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
429 {
430 int status;
431
432 /* Extract and adapt to configuration number, if available. */
433 if (info->section && info->section->owner)
434 {
435 bfd *abfd = info->section->owner;
436 mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
437 /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
438 }
439
440 /* Picking the right ISA bitmask for the current context is tricky. */
441 if (info->section)
442 {
443 if (info->section->flags & SEC_MEP_VLIW)
444 {
445 /* Are we in 32 or 64 bit vliw mode? */
446 if (MEP_VLIW64)
447 status = mep_examine_vliw64_insns (cd, pc, info);
448 else
449 status = mep_examine_vliw32_insns (cd, pc, info);
450 /* Both the above branches set their own isa bitmasks. */
451 }
452 else
453 {
454 cd->isas = & MEP_CORE_ISA;
455 status = default_print_insn (cd, pc, info);
456 }
457 }
458 else /* sid or gdb */
459 {
460 status = default_print_insn (cd, pc, info);
461 }
462
463 return status;
464 }
465
466
467 /* -- opc.c */
468
469 void mep_cgen_print_operand
470 (CGEN_CPU_DESC, int, PTR, CGEN_FIELDS *, void const *, bfd_vma, int);
471
472 /* Main entry point for printing operands.
473 XINFO is a `void *' and not a `disassemble_info *' to not put a requirement
474 of dis-asm.h on cgen.h.
475
476 This function is basically just a big switch statement. Earlier versions
477 used tables to look up the function to use, but
478 - if the table contains both assembler and disassembler functions then
479 the disassembler contains much of the assembler and vice-versa,
480 - there's a lot of inlining possibilities as things grow,
481 - using a switch statement avoids the function call overhead.
482
483 This function could be moved into `print_insn_normal', but keeping it
484 separate makes clear the interface between `print_insn_normal' and each of
485 the handlers. */
486
487 void
488 mep_cgen_print_operand (CGEN_CPU_DESC cd,
489 int opindex,
490 void * xinfo,
491 CGEN_FIELDS *fields,
492 void const *attrs ATTRIBUTE_UNUSED,
493 bfd_vma pc,
494 int length)
495 {
496 disassemble_info *info = (disassemble_info *) xinfo;
497
498 switch (opindex)
499 {
500 case MEP_OPERAND_ADDR24A4 :
501 print_normal (cd, info, fields->f_24u8a4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
502 break;
503 case MEP_OPERAND_CALLNUM :
504 print_normal (cd, info, fields->f_callnum, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
505 break;
506 case MEP_OPERAND_CCCC :
507 print_normal (cd, info, fields->f_rm, 0, pc, length);
508 break;
509 case MEP_OPERAND_CCRN :
510 print_keyword (cd, info, & mep_cgen_opval_h_ccr, fields->f_ccrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
511 break;
512 case MEP_OPERAND_CDISP8 :
513 print_normal (cd, info, fields->f_8s24, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
514 break;
515 case MEP_OPERAND_CDISP8A2 :
516 print_normal (cd, info, fields->f_8s24a2, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
517 break;
518 case MEP_OPERAND_CDISP8A4 :
519 print_normal (cd, info, fields->f_8s24a4, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
520 break;
521 case MEP_OPERAND_CDISP8A8 :
522 print_normal (cd, info, fields->f_8s24a8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
523 break;
524 case MEP_OPERAND_CIMM4 :
525 print_normal (cd, info, fields->f_rn, 0, pc, length);
526 break;
527 case MEP_OPERAND_CIMM5 :
528 print_normal (cd, info, fields->f_5u24, 0, pc, length);
529 break;
530 case MEP_OPERAND_CODE16 :
531 print_normal (cd, info, fields->f_16u16, 0, pc, length);
532 break;
533 case MEP_OPERAND_CODE24 :
534 print_normal (cd, info, fields->f_24u4n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
535 break;
536 case MEP_OPERAND_CP_FLAG :
537 print_keyword (cd, info, & mep_cgen_opval_h_ccr, 0, 0);
538 break;
539 case MEP_OPERAND_CRN :
540 print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crn, 0);
541 break;
542 case MEP_OPERAND_CRN64 :
543 print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crn, 0);
544 break;
545 case MEP_OPERAND_CRNX :
546 print_keyword (cd, info, & mep_cgen_opval_h_cr, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
547 break;
548 case MEP_OPERAND_CRNX64 :
549 print_keyword (cd, info, & mep_cgen_opval_h_cr64, fields->f_crnx, 0|(1<<CGEN_OPERAND_VIRTUAL));
550 break;
551 case MEP_OPERAND_CSRN :
552 print_keyword (cd, info, & mep_cgen_opval_h_csr, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL));
553 break;
554 case MEP_OPERAND_CSRN_IDX :
555 print_normal (cd, info, fields->f_csrn, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
556 break;
557 case MEP_OPERAND_DBG :
558 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
559 break;
560 case MEP_OPERAND_DEPC :
561 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
562 break;
563 case MEP_OPERAND_EPC :
564 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
565 break;
566 case MEP_OPERAND_EXC :
567 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
568 break;
569 case MEP_OPERAND_HI :
570 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
571 break;
572 case MEP_OPERAND_LO :
573 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
574 break;
575 case MEP_OPERAND_LP :
576 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
577 break;
578 case MEP_OPERAND_MB0 :
579 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
580 break;
581 case MEP_OPERAND_MB1 :
582 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
583 break;
584 case MEP_OPERAND_ME0 :
585 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
586 break;
587 case MEP_OPERAND_ME1 :
588 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
589 break;
590 case MEP_OPERAND_NPC :
591 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
592 break;
593 case MEP_OPERAND_OPT :
594 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
595 break;
596 case MEP_OPERAND_PCABS24A2 :
597 print_address (cd, info, fields->f_24u5a2n, 0|(1<<CGEN_OPERAND_ABS_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
598 break;
599 case MEP_OPERAND_PCREL12A2 :
600 print_address (cd, info, fields->f_12s4a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
601 break;
602 case MEP_OPERAND_PCREL17A2 :
603 print_address (cd, info, fields->f_17s16a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
604 break;
605 case MEP_OPERAND_PCREL24A2 :
606 print_address (cd, info, fields->f_24s5a2n, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_PCREL_ADDR)|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
607 break;
608 case MEP_OPERAND_PCREL8A2 :
609 print_address (cd, info, fields->f_8s8a2, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELAX)|(1<<CGEN_OPERAND_PCREL_ADDR), pc, length);
610 break;
611 case MEP_OPERAND_PSW :
612 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
613 break;
614 case MEP_OPERAND_R0 :
615 print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
616 break;
617 case MEP_OPERAND_R1 :
618 print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
619 break;
620 case MEP_OPERAND_RL :
621 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rl, 0);
622 break;
623 case MEP_OPERAND_RM :
624 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
625 break;
626 case MEP_OPERAND_RMA :
627 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rm, 0);
628 break;
629 case MEP_OPERAND_RN :
630 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
631 break;
632 case MEP_OPERAND_RN3 :
633 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
634 break;
635 case MEP_OPERAND_RN3C :
636 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
637 break;
638 case MEP_OPERAND_RN3L :
639 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
640 break;
641 case MEP_OPERAND_RN3S :
642 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
643 break;
644 case MEP_OPERAND_RN3UC :
645 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
646 break;
647 case MEP_OPERAND_RN3UL :
648 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
649 break;
650 case MEP_OPERAND_RN3US :
651 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn3, 0);
652 break;
653 case MEP_OPERAND_RNC :
654 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
655 break;
656 case MEP_OPERAND_RNL :
657 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
658 break;
659 case MEP_OPERAND_RNS :
660 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
661 break;
662 case MEP_OPERAND_RNUC :
663 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
664 break;
665 case MEP_OPERAND_RNUL :
666 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
667 break;
668 case MEP_OPERAND_RNUS :
669 print_keyword (cd, info, & mep_cgen_opval_h_gpr, fields->f_rn, 0);
670 break;
671 case MEP_OPERAND_SAR :
672 print_keyword (cd, info, & mep_cgen_opval_h_csr, 0, 0);
673 break;
674 case MEP_OPERAND_SDISP16 :
675 print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
676 break;
677 case MEP_OPERAND_SIMM16 :
678 print_normal (cd, info, fields->f_16s16, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
679 break;
680 case MEP_OPERAND_SIMM6 :
681 print_normal (cd, info, fields->f_6s8, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
682 break;
683 case MEP_OPERAND_SIMM8 :
684 print_normal (cd, info, fields->f_8s8, 0|(1<<CGEN_OPERAND_SIGNED)|(1<<CGEN_OPERAND_RELOC_IMPLIES_OVERFLOW), pc, length);
685 break;
686 case MEP_OPERAND_SP :
687 print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
688 break;
689 case MEP_OPERAND_SPR :
690 print_spreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
691 break;
692 case MEP_OPERAND_TP :
693 print_keyword (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
694 break;
695 case MEP_OPERAND_TPR :
696 print_tpreg (cd, info, & mep_cgen_opval_h_gpr, 0, 0);
697 break;
698 case MEP_OPERAND_UDISP2 :
699 print_normal (cd, info, fields->f_2u6, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
700 break;
701 case MEP_OPERAND_UDISP7 :
702 print_normal (cd, info, fields->f_7u9, 0, pc, length);
703 break;
704 case MEP_OPERAND_UDISP7A2 :
705 print_normal (cd, info, fields->f_7u9a2, 0, pc, length);
706 break;
707 case MEP_OPERAND_UDISP7A4 :
708 print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
709 break;
710 case MEP_OPERAND_UIMM16 :
711 print_normal (cd, info, fields->f_16u16, 0, pc, length);
712 break;
713 case MEP_OPERAND_UIMM2 :
714 print_normal (cd, info, fields->f_2u10, 0, pc, length);
715 break;
716 case MEP_OPERAND_UIMM24 :
717 print_normal (cd, info, fields->f_24u8n, 0|(1<<CGEN_OPERAND_VIRTUAL), pc, length);
718 break;
719 case MEP_OPERAND_UIMM3 :
720 print_normal (cd, info, fields->f_3u5, 0, pc, length);
721 break;
722 case MEP_OPERAND_UIMM4 :
723 print_normal (cd, info, fields->f_4u8, 0, pc, length);
724 break;
725 case MEP_OPERAND_UIMM5 :
726 print_normal (cd, info, fields->f_5u8, 0, pc, length);
727 break;
728 case MEP_OPERAND_UIMM7A4 :
729 print_normal (cd, info, fields->f_7u9a4, 0, pc, length);
730 break;
731 case MEP_OPERAND_ZERO :
732 print_normal (cd, info, 0, 0|(1<<CGEN_OPERAND_SIGNED), pc, length);
733 break;
734
735 default :
736 /* xgettext:c-format */
737 fprintf (stderr, _("Unrecognized field %d while printing insn.\n"),
738 opindex);
739 abort ();
740 }
741 }
742
743 cgen_print_fn * const mep_cgen_print_handlers[] =
744 {
745 print_insn_normal,
746 };
747
748
749 void
750 mep_cgen_init_dis (CGEN_CPU_DESC cd)
751 {
752 mep_cgen_init_opcode_table (cd);
753 mep_cgen_init_ibld_table (cd);
754 cd->print_handlers = & mep_cgen_print_handlers[0];
755 cd->print_operand = mep_cgen_print_operand;
756 }
757
758 \f
759 /* Default print handler. */
760
761 static void
762 print_normal (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
763 void *dis_info,
764 long value,
765 unsigned int attrs,
766 bfd_vma pc ATTRIBUTE_UNUSED,
767 int length ATTRIBUTE_UNUSED)
768 {
769 disassemble_info *info = (disassemble_info *) dis_info;
770
771 #ifdef CGEN_PRINT_NORMAL
772 CGEN_PRINT_NORMAL (cd, info, value, attrs, pc, length);
773 #endif
774
775 /* Print the operand as directed by the attributes. */
776 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
777 ; /* nothing to do */
778 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
779 (*info->fprintf_func) (info->stream, "%ld", value);
780 else
781 (*info->fprintf_func) (info->stream, "0x%lx", value);
782 }
783
784 /* Default address handler. */
785
786 static void
787 print_address (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
788 void *dis_info,
789 bfd_vma value,
790 unsigned int attrs,
791 bfd_vma pc ATTRIBUTE_UNUSED,
792 int length ATTRIBUTE_UNUSED)
793 {
794 disassemble_info *info = (disassemble_info *) dis_info;
795
796 #ifdef CGEN_PRINT_ADDRESS
797 CGEN_PRINT_ADDRESS (cd, info, value, attrs, pc, length);
798 #endif
799
800 /* Print the operand as directed by the attributes. */
801 if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SEM_ONLY))
802 ; /* Nothing to do. */
803 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_PCREL_ADDR))
804 (*info->print_address_func) (value, info);
805 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_ABS_ADDR))
806 (*info->print_address_func) (value, info);
807 else if (CGEN_BOOL_ATTR (attrs, CGEN_OPERAND_SIGNED))
808 (*info->fprintf_func) (info->stream, "%ld", (long) value);
809 else
810 (*info->fprintf_func) (info->stream, "0x%lx", (long) value);
811 }
812
813 /* Keyword print handler. */
814
815 static void
816 print_keyword (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
817 void *dis_info,
818 CGEN_KEYWORD *keyword_table,
819 long value,
820 unsigned int attrs ATTRIBUTE_UNUSED)
821 {
822 disassemble_info *info = (disassemble_info *) dis_info;
823 const CGEN_KEYWORD_ENTRY *ke;
824
825 ke = cgen_keyword_lookup_value (keyword_table, value);
826 if (ke != NULL)
827 (*info->fprintf_func) (info->stream, "%s", ke->name);
828 else
829 (*info->fprintf_func) (info->stream, "???");
830 }
831 \f
832 /* Default insn printer.
833
834 DIS_INFO is defined as `void *' so the disassembler needn't know anything
835 about disassemble_info. */
836
837 static void
838 print_insn_normal (CGEN_CPU_DESC cd,
839 void *dis_info,
840 const CGEN_INSN *insn,
841 CGEN_FIELDS *fields,
842 bfd_vma pc,
843 int length)
844 {
845 const CGEN_SYNTAX *syntax = CGEN_INSN_SYNTAX (insn);
846 disassemble_info *info = (disassemble_info *) dis_info;
847 const CGEN_SYNTAX_CHAR_TYPE *syn;
848
849 CGEN_INIT_PRINT (cd);
850
851 for (syn = CGEN_SYNTAX_STRING (syntax); *syn; ++syn)
852 {
853 if (CGEN_SYNTAX_MNEMONIC_P (*syn))
854 {
855 (*info->fprintf_func) (info->stream, "%s", CGEN_INSN_MNEMONIC (insn));
856 continue;
857 }
858 if (CGEN_SYNTAX_CHAR_P (*syn))
859 {
860 (*info->fprintf_func) (info->stream, "%c", CGEN_SYNTAX_CHAR (*syn));
861 continue;
862 }
863
864 /* We have an operand. */
865 mep_cgen_print_operand (cd, CGEN_SYNTAX_FIELD (*syn), info,
866 fields, CGEN_INSN_ATTRS (insn), pc, length);
867 }
868 }
869 \f
870 /* Subroutine of print_insn. Reads an insn into the given buffers and updates
871 the extract info.
872 Returns 0 if all is well, non-zero otherwise. */
873
874 static int
875 read_insn (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED,
876 bfd_vma pc,
877 disassemble_info *info,
878 bfd_byte *buf,
879 int buflen,
880 CGEN_EXTRACT_INFO *ex_info,
881 unsigned long *insn_value)
882 {
883 int status = (*info->read_memory_func) (pc, buf, buflen, info);
884
885 if (status != 0)
886 {
887 (*info->memory_error_func) (status, pc, info);
888 return -1;
889 }
890
891 ex_info->dis_info = info;
892 ex_info->valid = (1 << buflen) - 1;
893 ex_info->insn_bytes = buf;
894
895 *insn_value = bfd_get_bits (buf, buflen * 8, info->endian == BFD_ENDIAN_BIG);
896 return 0;
897 }
898
899 /* Utility to print an insn.
900 BUF is the base part of the insn, target byte order, BUFLEN bytes long.
901 The result is the size of the insn in bytes or zero for an unknown insn
902 or -1 if an error occurs fetching data (memory_error_func will have
903 been called). */
904
905 static int
906 print_insn (CGEN_CPU_DESC cd,
907 bfd_vma pc,
908 disassemble_info *info,
909 bfd_byte *buf,
910 unsigned int buflen)
911 {
912 CGEN_INSN_INT insn_value;
913 const CGEN_INSN_LIST *insn_list;
914 CGEN_EXTRACT_INFO ex_info;
915 int basesize;
916
917 /* Extract base part of instruction, just in case CGEN_DIS_* uses it. */
918 basesize = cd->base_insn_bitsize < buflen * 8 ?
919 cd->base_insn_bitsize : buflen * 8;
920 insn_value = cgen_get_insn_value (cd, buf, basesize);
921
922
923 /* Fill in ex_info fields like read_insn would. Don't actually call
924 read_insn, since the incoming buffer is already read (and possibly
925 modified a la m32r). */
926 ex_info.valid = (1 << buflen) - 1;
927 ex_info.dis_info = info;
928 ex_info.insn_bytes = buf;
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 (cd, (char *) 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 unsigned long insn_value_cropped;
940
941 #ifdef CGEN_VALIDATE_INSN_SUPPORTED
942 /* Not needed as insn shouldn't be in hash lists if not supported. */
943 /* Supported by this cpu? */
944 if (! mep_cgen_insn_supported (cd, insn))
945 {
946 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
947 continue;
948 }
949 #endif
950
951 /* Basic bit mask must be correct. */
952 /* ??? May wish to allow target to defer this check until the extract
953 handler. */
954
955 /* Base size may exceed this instruction's size. Extract the
956 relevant part from the buffer. */
957 if ((unsigned) (CGEN_INSN_BITSIZE (insn) / 8) < buflen &&
958 (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
959 insn_value_cropped = bfd_get_bits (buf, CGEN_INSN_BITSIZE (insn),
960 info->endian == BFD_ENDIAN_BIG);
961 else
962 insn_value_cropped = insn_value;
963
964 if ((insn_value_cropped & CGEN_INSN_BASE_MASK (insn))
965 == CGEN_INSN_BASE_VALUE (insn))
966 {
967 /* Printing is handled in two passes. The first pass parses the
968 machine insn and extracts the fields. The second pass prints
969 them. */
970
971 /* Make sure the entire insn is loaded into insn_value, if it
972 can fit. */
973 if (((unsigned) CGEN_INSN_BITSIZE (insn) > cd->base_insn_bitsize) &&
974 (unsigned) (CGEN_INSN_BITSIZE (insn) / 8) <= sizeof (unsigned long))
975 {
976 unsigned long full_insn_value;
977 int rc = read_insn (cd, pc, info, buf,
978 CGEN_INSN_BITSIZE (insn) / 8,
979 & ex_info, & full_insn_value);
980 if (rc != 0)
981 return rc;
982 length = CGEN_EXTRACT_FN (cd, insn)
983 (cd, insn, &ex_info, full_insn_value, &fields, pc);
984 }
985 else
986 length = CGEN_EXTRACT_FN (cd, insn)
987 (cd, insn, &ex_info, insn_value_cropped, &fields, pc);
988
989 /* Length < 0 -> error. */
990 if (length < 0)
991 return length;
992 if (length > 0)
993 {
994 CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
995 /* Length is in bits, result is in bytes. */
996 return length / 8;
997 }
998 }
999
1000 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1001 }
1002
1003 return 0;
1004 }
1005
1006 /* Default value for CGEN_PRINT_INSN.
1007 The result is the size of the insn in bytes or zero for an unknown insn
1008 or -1 if an error occured fetching bytes. */
1009
1010 #ifndef CGEN_PRINT_INSN
1011 #define CGEN_PRINT_INSN default_print_insn
1012 #endif
1013
1014 static int
1015 default_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1016 {
1017 bfd_byte buf[CGEN_MAX_INSN_SIZE];
1018 int buflen;
1019 int status;
1020
1021 /* Attempt to read the base part of the insn. */
1022 buflen = cd->base_insn_bitsize / 8;
1023 status = (*info->read_memory_func) (pc, buf, buflen, info);
1024
1025 /* Try again with the minimum part, if min < base. */
1026 if (status != 0 && (cd->min_insn_bitsize < cd->base_insn_bitsize))
1027 {
1028 buflen = cd->min_insn_bitsize / 8;
1029 status = (*info->read_memory_func) (pc, buf, buflen, info);
1030 }
1031
1032 if (status != 0)
1033 {
1034 (*info->memory_error_func) (status, pc, info);
1035 return -1;
1036 }
1037
1038 return print_insn (cd, pc, info, buf, buflen);
1039 }
1040
1041 /* Main entry point.
1042 Print one instruction from PC on INFO->STREAM.
1043 Return the size of the instruction (in bytes). */
1044
1045 typedef struct cpu_desc_list
1046 {
1047 struct cpu_desc_list *next;
1048 CGEN_BITSET *isa;
1049 int mach;
1050 int endian;
1051 CGEN_CPU_DESC cd;
1052 } cpu_desc_list;
1053
1054 int
1055 print_insn_mep (bfd_vma pc, disassemble_info *info)
1056 {
1057 static cpu_desc_list *cd_list = 0;
1058 cpu_desc_list *cl = 0;
1059 static CGEN_CPU_DESC cd = 0;
1060 static CGEN_BITSET *prev_isa;
1061 static int prev_mach;
1062 static int prev_endian;
1063 int length;
1064 CGEN_BITSET *isa;
1065 int mach;
1066 int endian = (info->endian == BFD_ENDIAN_BIG
1067 ? CGEN_ENDIAN_BIG
1068 : CGEN_ENDIAN_LITTLE);
1069 enum bfd_architecture arch;
1070
1071 /* ??? gdb will set mach but leave the architecture as "unknown" */
1072 #ifndef CGEN_BFD_ARCH
1073 #define CGEN_BFD_ARCH bfd_arch_mep
1074 #endif
1075 arch = info->arch;
1076 if (arch == bfd_arch_unknown)
1077 arch = CGEN_BFD_ARCH;
1078
1079 /* There's no standard way to compute the machine or isa number
1080 so we leave it to the target. */
1081 #ifdef CGEN_COMPUTE_MACH
1082 mach = CGEN_COMPUTE_MACH (info);
1083 #else
1084 mach = info->mach;
1085 #endif
1086
1087 #ifdef CGEN_COMPUTE_ISA
1088 {
1089 static CGEN_BITSET *permanent_isa;
1090
1091 if (!permanent_isa)
1092 permanent_isa = cgen_bitset_create (MAX_ISAS);
1093 isa = permanent_isa;
1094 cgen_bitset_clear (isa);
1095 cgen_bitset_add (isa, CGEN_COMPUTE_ISA (info));
1096 }
1097 #else
1098 isa = info->insn_sets;
1099 #endif
1100
1101 /* If we've switched cpu's, try to find a handle we've used before */
1102 if (cd
1103 && (cgen_bitset_compare (isa, prev_isa) != 0
1104 || mach != prev_mach
1105 || endian != prev_endian))
1106 {
1107 cd = 0;
1108 for (cl = cd_list; cl; cl = cl->next)
1109 {
1110 if (cgen_bitset_compare (cl->isa, isa) == 0 &&
1111 cl->mach == mach &&
1112 cl->endian == endian)
1113 {
1114 cd = cl->cd;
1115 prev_isa = cd->isas;
1116 break;
1117 }
1118 }
1119 }
1120
1121 /* If we haven't initialized yet, initialize the opcode table. */
1122 if (! cd)
1123 {
1124 const bfd_arch_info_type *arch_type = bfd_lookup_arch (arch, mach);
1125 const char *mach_name;
1126
1127 if (!arch_type)
1128 abort ();
1129 mach_name = arch_type->printable_name;
1130
1131 prev_isa = cgen_bitset_copy (isa);
1132 prev_mach = mach;
1133 prev_endian = endian;
1134 cd = mep_cgen_cpu_open (CGEN_CPU_OPEN_ISAS, prev_isa,
1135 CGEN_CPU_OPEN_BFDMACH, mach_name,
1136 CGEN_CPU_OPEN_ENDIAN, prev_endian,
1137 CGEN_CPU_OPEN_END);
1138 if (!cd)
1139 abort ();
1140
1141 /* Save this away for future reference. */
1142 cl = xmalloc (sizeof (struct cpu_desc_list));
1143 cl->cd = cd;
1144 cl->isa = prev_isa;
1145 cl->mach = mach;
1146 cl->endian = endian;
1147 cl->next = cd_list;
1148 cd_list = cl;
1149
1150 mep_cgen_init_dis (cd);
1151 }
1152
1153 /* We try to have as much common code as possible.
1154 But at this point some targets need to take over. */
1155 /* ??? Some targets may need a hook elsewhere. Try to avoid this,
1156 but if not possible try to move this hook elsewhere rather than
1157 have two hooks. */
1158 length = CGEN_PRINT_INSN (cd, pc, info);
1159 if (length > 0)
1160 return length;
1161 if (length < 0)
1162 return -1;
1163
1164 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1165 return cd->default_insn_bitsize / 8;
1166 }
This page took 0.071851 seconds and 5 git commands to generate.