Fix the gdb build with GCC 7
[deliverable/binutils-gdb.git] / cpu / mep.opc
1 /* MeP opcode support. -*- C -*-
2 Copyright 2011 Free Software Foundation, Inc.
3
4 Contributed by Red Hat Inc;
5
6 This file is part of the GNU Binutils.
7
8 This program is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 3 of the License, or
11 (at your option) any later version.
12
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
17
18 You should have received a copy of the GNU General Public License
19 along with this program; if not, write to the Free Software
20 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
21 MA 02110-1301, USA. */
22
23 /* -- opc.h */
24
25 #undef CGEN_DIS_HASH_SIZE
26 #define CGEN_DIS_HASH_SIZE 1
27
28 #undef CGEN_DIS_HASH
29 #define CGEN_DIS_HASH(buffer, insn) 0
30
31 #define CGEN_VERBOSE_ASSEMBLER_ERRORS
32
33 typedef struct
34 {
35 char * name;
36 int config_enum;
37 unsigned cpu_flag;
38 int big_endian;
39 int vliw_bits;
40 CGEN_ATTR_VALUE_BITSET_TYPE cop16_isa;
41 CGEN_ATTR_VALUE_BITSET_TYPE cop32_isa;
42 CGEN_ATTR_VALUE_BITSET_TYPE cop48_isa;
43 CGEN_ATTR_VALUE_BITSET_TYPE cop64_isa;
44 CGEN_ATTR_VALUE_BITSET_TYPE cop_isa;
45 CGEN_ATTR_VALUE_BITSET_TYPE core_isa;
46 unsigned int option_mask;
47 } mep_config_map_struct;
48
49 extern mep_config_map_struct mep_config_map[];
50 extern int mep_config_index;
51
52 extern void init_mep_all_core_isas_mask (void);
53 extern void init_mep_all_cop_isas_mask (void);
54 extern CGEN_ATTR_VALUE_BITSET_TYPE mep_cop_isa (void);
55
56 #define MEP_CONFIG (mep_config_map[mep_config_index].config_enum)
57 #define MEP_CPU (mep_config_map[mep_config_index].cpu_flag)
58 #define MEP_OMASK (mep_config_map[mep_config_index].option_mask)
59 #define MEP_VLIW (mep_config_map[mep_config_index].vliw_bits > 0)
60 #define MEP_VLIW32 (mep_config_map[mep_config_index].vliw_bits == 32)
61 #define MEP_VLIW64 (mep_config_map[mep_config_index].vliw_bits == 64)
62 #define MEP_COP16_ISA (mep_config_map[mep_config_index].cop16_isa)
63 #define MEP_COP32_ISA (mep_config_map[mep_config_index].cop32_isa)
64 #define MEP_COP48_ISA (mep_config_map[mep_config_index].cop48_isa)
65 #define MEP_COP64_ISA (mep_config_map[mep_config_index].cop64_isa)
66 #define MEP_COP_ISA (mep_config_map[mep_config_index].cop_isa)
67 #define MEP_CORE_ISA (mep_config_map[mep_config_index].core_isa)
68
69 /* begin-cop-ip-supported-defines */
70 #define MEP_IVC2_SUPPORTED 1
71 /* end-cop-ip-supported-defines */
72
73 extern int mep_insn_supported_by_isa (const CGEN_INSN *, CGEN_ATTR_VALUE_BITSET_TYPE *);
74
75 /* A mask for all ISAs executed by the core. */
76 #define MEP_ALL_CORE_ISAS_MASK mep_all_core_isas_mask
77 extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask;
78
79 #define MEP_INSN_CORE_P(insn) ( \
80 init_mep_all_core_isas_mask (), \
81 mep_insn_supported_by_isa (insn, & MEP_ALL_CORE_ISAS_MASK) \
82 )
83
84 /* A mask for all ISAs executed by a VLIW coprocessor. */
85 #define MEP_ALL_COP_ISAS_MASK mep_all_cop_isas_mask
86 extern CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask;
87
88 #define MEP_INSN_COP_P(insn) ( \
89 init_mep_all_cop_isas_mask (), \
90 mep_insn_supported_by_isa (insn, & MEP_ALL_COP_ISAS_MASK) \
91 )
92
93 extern int mep_cgen_insn_supported (CGEN_CPU_DESC, const CGEN_INSN *);
94 extern int mep_cgen_insn_supported_asm (CGEN_CPU_DESC, const CGEN_INSN *);
95
96 /* -- asm.c */
97
98 #include "elf/mep.h"
99
100 #define CGEN_VALIDATE_INSN_SUPPORTED
101 #define mep_cgen_insn_supported mep_cgen_insn_supported_asm
102
103 const char * parse_csrn (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
104 const char * parse_tpreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
105 const char * parse_spreg (CGEN_CPU_DESC, const char **, CGEN_KEYWORD *, long *);
106 const char * parse_mep_align (CGEN_CPU_DESC, const char **, enum cgen_operand_type, long *);
107 const char * parse_mep_alignu (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
108 static const char * parse_signed16 (CGEN_CPU_DESC, const char **, int, long *);
109 static const char * parse_signed16_range (CGEN_CPU_DESC, const char **, int, long *) ATTRIBUTE_UNUSED;
110 static const char * parse_unsigned16 (CGEN_CPU_DESC, const char **, int, unsigned long *);
111 static const char * parse_unsigned16_range (CGEN_CPU_DESC, const char **, int, unsigned long *) ATTRIBUTE_UNUSED;
112 static const char * parse_lo16 (CGEN_CPU_DESC, const char **, int, long *, long);
113 static const char * parse_unsigned7 (CGEN_CPU_DESC, const char **, enum cgen_operand_type, unsigned long *);
114 static const char * parse_zero (CGEN_CPU_DESC, const char **, int, long *);
115
116 const char *
117 parse_csrn (CGEN_CPU_DESC cd, const char **strp,
118 CGEN_KEYWORD *keyword_table, long *field)
119 {
120 const char *err;
121 unsigned long value;
122
123 err = cgen_parse_keyword (cd, strp, keyword_table, field);
124 if (!err)
125 return NULL;
126
127 err = cgen_parse_unsigned_integer (cd, strp, MEP_OPERAND_CSRN_IDX, & value);
128 if (err)
129 return err;
130 *field = value;
131 return NULL;
132 }
133
134 /* begin-cop-ip-parse-handlers */
135 static const char *
136 parse_ivc2_cr (CGEN_CPU_DESC,
137 const char **,
138 CGEN_KEYWORD *,
139 long *) ATTRIBUTE_UNUSED;
140 static const char *
141 parse_ivc2_cr (CGEN_CPU_DESC cd,
142 const char **strp,
143 CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
144 long *field)
145 {
146 return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_cr_ivc2, field);
147 }
148 static const char *
149 parse_ivc2_ccr (CGEN_CPU_DESC,
150 const char **,
151 CGEN_KEYWORD *,
152 long *) ATTRIBUTE_UNUSED;
153 static const char *
154 parse_ivc2_ccr (CGEN_CPU_DESC cd,
155 const char **strp,
156 CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
157 long *field)
158 {
159 return cgen_parse_keyword (cd, strp, & mep_cgen_opval_h_ccr_ivc2, field);
160 }
161 /* end-cop-ip-parse-handlers */
162
163 const char *
164 parse_tpreg (CGEN_CPU_DESC cd, const char ** strp,
165 CGEN_KEYWORD *keyword_table, long *field)
166 {
167 const char *err;
168
169 err = cgen_parse_keyword (cd, strp, keyword_table, field);
170 if (err)
171 return err;
172 if (*field != 13)
173 return _("Only $tp or $13 allowed for this opcode");
174 return NULL;
175 }
176
177 const char *
178 parse_spreg (CGEN_CPU_DESC cd, const char ** strp,
179 CGEN_KEYWORD *keyword_table, long *field)
180 {
181 const char *err;
182
183 err = cgen_parse_keyword (cd, strp, keyword_table, field);
184 if (err)
185 return err;
186 if (*field != 15)
187 return _("Only $sp or $15 allowed for this opcode");
188 return NULL;
189 }
190
191 const char *
192 parse_mep_align (CGEN_CPU_DESC cd, const char ** strp,
193 enum cgen_operand_type type, long *field)
194 {
195 long lsbs = 0;
196 const char *err;
197
198 switch (type)
199 {
200 case MEP_OPERAND_PCREL8A2:
201 case MEP_OPERAND_PCREL12A2:
202 case MEP_OPERAND_PCREL17A2:
203 case MEP_OPERAND_PCREL24A2:
204 err = cgen_parse_signed_integer (cd, strp, type, field);
205 break;
206 case MEP_OPERAND_PCABS24A2:
207 case MEP_OPERAND_UDISP7:
208 case MEP_OPERAND_UDISP7A2:
209 case MEP_OPERAND_UDISP7A4:
210 case MEP_OPERAND_UIMM7A4:
211 case MEP_OPERAND_ADDR24A4:
212 err = cgen_parse_unsigned_integer (cd, strp, type, (unsigned long *) field);
213 break;
214 default:
215 abort();
216 }
217 if (err)
218 return err;
219 switch (type)
220 {
221 case MEP_OPERAND_UDISP7:
222 lsbs = 0;
223 break;
224 case MEP_OPERAND_PCREL8A2:
225 case MEP_OPERAND_PCREL12A2:
226 case MEP_OPERAND_PCREL17A2:
227 case MEP_OPERAND_PCREL24A2:
228 case MEP_OPERAND_PCABS24A2:
229 case MEP_OPERAND_UDISP7A2:
230 lsbs = *field & 1;
231 break;
232 case MEP_OPERAND_UDISP7A4:
233 case MEP_OPERAND_UIMM7A4:
234 case MEP_OPERAND_ADDR24A4:
235 lsbs = *field & 3;
236 break;
237 lsbs = *field & 7;
238 break;
239 default:
240 /* Safe assumption? */
241 abort ();
242 }
243 if (lsbs)
244 return "Value is not aligned enough";
245 return NULL;
246 }
247
248 const char *
249 parse_mep_alignu (CGEN_CPU_DESC cd, const char ** strp,
250 enum cgen_operand_type type, unsigned long *field)
251 {
252 return parse_mep_align (cd, strp, type, (long *) field);
253 }
254
255
256 /* Handle %lo(), %tpoff(), %sdaoff(), %hi(), and other signed
257 constants in a signed context. */
258
259 static const char *
260 parse_signed16 (CGEN_CPU_DESC cd,
261 const char **strp,
262 int opindex,
263 long *valuep)
264 {
265 return parse_lo16 (cd, strp, opindex, valuep, 1);
266 }
267
268 static const char *
269 parse_lo16 (CGEN_CPU_DESC cd,
270 const char **strp,
271 int opindex,
272 long *valuep,
273 long signedp)
274 {
275 const char *errmsg;
276 enum cgen_parse_operand_result result_type;
277 bfd_vma value;
278
279 if (strncasecmp (*strp, "%lo(", 4) == 0)
280 {
281 *strp += 4;
282 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
283 & result_type, & value);
284 if (**strp != ')')
285 return _("missing `)'");
286 ++*strp;
287 if (errmsg == NULL
288 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
289 value &= 0xffff;
290 if (signedp)
291 *valuep = (long)(short) value;
292 else
293 *valuep = value;
294 return errmsg;
295 }
296
297 if (strncasecmp (*strp, "%hi(", 4) == 0)
298 {
299 *strp += 4;
300 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
301 & result_type, & value);
302 if (**strp != ')')
303 return _("missing `)'");
304 ++*strp;
305 if (errmsg == NULL
306 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
307 value = (value + 0x8000) >> 16;
308 *valuep = value;
309 return errmsg;
310 }
311
312 if (strncasecmp (*strp, "%uhi(", 5) == 0)
313 {
314 *strp += 5;
315 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
316 & result_type, & value);
317 if (**strp != ')')
318 return _("missing `)'");
319 ++*strp;
320 if (errmsg == NULL
321 && result_type == CGEN_PARSE_OPERAND_RESULT_NUMBER)
322 value = value >> 16;
323 *valuep = value;
324 return errmsg;
325 }
326
327 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
328 {
329 *strp += 8;
330 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
331 NULL, & value);
332 if (**strp != ')')
333 return _("missing `)'");
334 ++*strp;
335 *valuep = value;
336 return errmsg;
337 }
338
339 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
340 {
341 *strp += 7;
342 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
343 NULL, & value);
344 if (**strp != ')')
345 return _("missing `)'");
346 ++*strp;
347 *valuep = value;
348 return errmsg;
349 }
350
351 if (**strp == '%')
352 return _("invalid %function() here");
353
354 return cgen_parse_signed_integer (cd, strp, opindex, valuep);
355 }
356
357 static const char *
358 parse_unsigned16 (CGEN_CPU_DESC cd,
359 const char **strp,
360 int opindex,
361 unsigned long *valuep)
362 {
363 return parse_lo16 (cd, strp, opindex, (long *) valuep, 0);
364 }
365
366 static const char *
367 parse_signed16_range (CGEN_CPU_DESC cd,
368 const char **strp,
369 int opindex,
370 signed long *valuep)
371 {
372 const char *errmsg = 0;
373 signed long value;
374
375 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
376 if (errmsg)
377 return errmsg;
378
379 if (value < -32768 || value > 32767)
380 return _("Immediate is out of range -32768 to 32767");
381
382 *valuep = value;
383 return 0;
384 }
385
386 static const char *
387 parse_unsigned16_range (CGEN_CPU_DESC cd,
388 const char **strp,
389 int opindex,
390 unsigned long *valuep)
391 {
392 const char *errmsg = 0;
393 unsigned long value;
394
395 errmsg = cgen_parse_unsigned_integer (cd, strp, opindex, & value);
396 if (errmsg)
397 return errmsg;
398
399 if (value > 65535)
400 return _("Immediate is out of range 0 to 65535");
401
402 *valuep = value;
403 return 0;
404 }
405
406 /* A special case of parse_signed16 which accepts only the value zero. */
407
408 static const char *
409 parse_zero (CGEN_CPU_DESC cd, const char **strp, int opindex, long *valuep)
410 {
411 const char *errmsg;
412 enum cgen_parse_operand_result result_type;
413 bfd_vma value;
414
415 /*fprintf(stderr, "dj: signed parse opindex `%s'\n", *strp);*/
416
417 /* Prevent ($ry) from being attempted as an expression on 'sw $rx,($ry)'.
418 It will fail and cause ry to be listed as an undefined symbol in the
419 listing. */
420 if (strncmp (*strp, "($", 2) == 0)
421 return "not zero"; /* any string will do -- will never be seen. */
422
423 if (strncasecmp (*strp, "%lo(", 4) == 0)
424 {
425 *strp += 4;
426 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_LOW16,
427 &result_type, &value);
428 if (**strp != ')')
429 return "missing `)'";
430 ++*strp;
431 if (errmsg == NULL
432 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
433 return "not zero"; /* any string will do -- will never be seen. */
434 *valuep = value;
435 return errmsg;
436 }
437
438 if (strncasecmp (*strp, "%hi(", 4) == 0)
439 {
440 *strp += 4;
441 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16S,
442 &result_type, &value);
443 if (**strp != ')')
444 return "missing `)'";
445 ++*strp;
446 if (errmsg == NULL
447 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
448 return "not zero"; /* any string will do -- will never be seen. */
449 *valuep = value;
450 return errmsg;
451 }
452
453 if (strncasecmp (*strp, "%uhi(", 5) == 0)
454 {
455 *strp += 5;
456 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_HI16U,
457 &result_type, &value);
458 if (**strp != ')')
459 return "missing `)'";
460 ++*strp;
461 if (errmsg == NULL
462 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
463 return "not zero"; /* any string will do -- will never be seen. */
464 *valuep = value;
465 return errmsg;
466 }
467
468 if (strncasecmp (*strp, "%sdaoff(", 8) == 0)
469 {
470 *strp += 8;
471 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_GPREL,
472 &result_type, &value);
473 if (**strp != ')')
474 return "missing `)'";
475 ++*strp;
476 if (errmsg == NULL
477 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
478 return "not zero"; /* any string will do -- will never be seen. */
479 *valuep = value;
480 return errmsg;
481 }
482
483 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
484 {
485 *strp += 7;
486 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_MEP_TPREL,
487 &result_type, &value);
488 if (**strp != ')')
489 return "missing `)'";
490 ++*strp;
491 if (errmsg == NULL
492 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
493 return "not zero"; /* any string will do -- will never be seen. */
494 *valuep = value;
495 return errmsg;
496 }
497
498 if (**strp == '%')
499 return "invalid %function() here";
500
501 errmsg = cgen_parse_address (cd, strp, opindex, BFD_RELOC_NONE,
502 &result_type, &value);
503 if (errmsg == NULL
504 && (result_type != CGEN_PARSE_OPERAND_RESULT_NUMBER || value != 0))
505 return "not zero"; /* any string will do -- will never be seen. */
506
507 return errmsg;
508 }
509
510 static const char *
511 parse_unsigned7 (CGEN_CPU_DESC cd, const char **strp,
512 enum cgen_operand_type opindex, unsigned long *valuep)
513 {
514 const char *errmsg;
515 bfd_vma value;
516
517 /* fprintf(stderr, "dj: unsigned7 parse `%s'\n", *strp); */
518
519 if (strncasecmp (*strp, "%tpoff(", 7) == 0)
520 {
521 int reloc;
522 *strp += 7;
523 switch (opindex)
524 {
525 case MEP_OPERAND_UDISP7:
526 reloc = BFD_RELOC_MEP_TPREL7;
527 break;
528 case MEP_OPERAND_UDISP7A2:
529 reloc = BFD_RELOC_MEP_TPREL7A2;
530 break;
531 case MEP_OPERAND_UDISP7A4:
532 reloc = BFD_RELOC_MEP_TPREL7A4;
533 break;
534 default:
535 /* Safe assumption? */
536 abort ();
537 }
538 errmsg = cgen_parse_address (cd, strp, opindex, reloc,
539 NULL, &value);
540 if (**strp != ')')
541 return "missing `)'";
542 ++*strp;
543 *valuep = value;
544 return errmsg;
545 }
546
547 if (**strp == '%')
548 return _("invalid %function() here");
549
550 return parse_mep_alignu (cd, strp, opindex, valuep);
551 }
552
553 static ATTRIBUTE_UNUSED const char *
554 parse_cdisp10 (CGEN_CPU_DESC cd,
555 const char **strp,
556 int opindex,
557 long *valuep)
558 {
559 const char *errmsg = 0;
560 signed long value;
561 long have_zero = 0;
562 int wide = 0;
563 int alignment;
564
565 switch (opindex)
566 {
567 case MEP_OPERAND_CDISP10A4:
568 alignment = 2;
569 break;
570 case MEP_OPERAND_CDISP10A2:
571 alignment = 1;
572 break;
573 case MEP_OPERAND_CDISP10:
574 default:
575 alignment = 0;
576 break;
577 }
578
579 if ((MEP_CPU & EF_MEP_CPU_MASK) == EF_MEP_CPU_C5)
580 wide = 1;
581
582 if (strncmp (*strp, "0x0", 3) == 0
583 || (**strp == '0' && *(*strp + 1) != 'x'))
584 have_zero = 1;
585
586 errmsg = cgen_parse_signed_integer (cd, strp, opindex, & value);
587 if (errmsg)
588 return errmsg;
589
590 if (wide)
591 {
592 if (value < -512 || value > 511)
593 return _("Immediate is out of range -512 to 511");
594 }
595 else
596 {
597 if (value < -128 || value > 127)
598 return _("Immediate is out of range -128 to 127");
599 }
600
601 if (value & ((1<<alignment)-1))
602 return _("Value is not aligned enough");
603
604 /* If this field may require a relocation then use larger dsp16. */
605 if (! have_zero && value == 0)
606 return (wide ? _("Immediate is out of range -512 to 511")
607 : _("Immediate is out of range -128 to 127"));
608
609 *valuep = value;
610 return 0;
611 }
612
613 /* BEGIN LIGHTWEIGHT MACRO PROCESSOR. */
614
615 #define MAXARGS 9
616
617 typedef struct
618 {
619 char *name;
620 char *expansion;
621 } macro;
622
623 typedef struct
624 {
625 const char *start;
626 int len;
627 } arg;
628
629 macro macros[] =
630 {
631 { "sizeof", "(`1.end + (- `1))"},
632 { "startof", "(`1 | 0)" },
633 { "align4", "(`1&(~3))"},
634 /*{ "hi", "(((`1+0x8000)>>16) & 0xffff)" }, */
635 /*{ "lo", "(`1 & 0xffff)" }, */
636 /*{ "sdaoff", "((`1-__sdabase) & 0x7f)"}, */
637 /*{ "tpoff", "((`1-__tpbase) & 0x7f)"}, */
638 { 0,0 }
639 };
640
641 static char * expand_string (const char *, int);
642
643 static const char *
644 mep_cgen_expand_macros_and_parse_operand
645 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
646
647 static char *
648 str_append (char *dest, const char *input, int len)
649 {
650 char *new_dest;
651 int oldlen;
652
653 if (len == 0)
654 return dest;
655 /* printf("str_append: <<%s>>, <<%s>>, %d\n", dest, input, len); */
656 oldlen = (dest ? strlen(dest) : 0);
657 new_dest = realloc (dest, oldlen + len + 1);
658 memset (new_dest + oldlen, 0, len + 1);
659 return strncat (new_dest, input, len);
660 }
661
662 static macro *
663 lookup_macro (const char *name)
664 {
665 macro *m;
666
667 for (m = macros; m->name; ++m)
668 if (strncmp (m->name, name, strlen(m->name)) == 0)
669 return m;
670
671 return 0;
672 }
673
674 static char *
675 expand_macro (arg *args, int narg, macro *mac)
676 {
677 char *result = 0, *rescanned_result = 0;
678 char *e = mac->expansion;
679 char *mark = e;
680 int mac_arg = 0;
681
682 /* printf("expanding macro %s with %d args\n", mac->name, narg + 1); */
683 while (*e)
684 {
685 if (*e == '`' &&
686 (*e+1) &&
687 ((*(e + 1) - '1') <= MAXARGS) &&
688 ((*(e + 1) - '1') <= narg))
689 {
690 result = str_append (result, mark, e - mark);
691 mac_arg = (*(e + 1) - '1');
692 /* printf("replacing `%d with %s\n", mac_arg+1, args[mac_arg].start); */
693 result = str_append (result, args[mac_arg].start, args[mac_arg].len);
694 ++e;
695 mark = e+1;
696 }
697 ++e;
698 }
699
700 if (mark != e)
701 result = str_append (result, mark, e - mark);
702
703 if (result)
704 {
705 rescanned_result = expand_string (result, 0);
706 free (result);
707 return rescanned_result;
708 }
709 else
710 return result;
711 }
712
713 #define IN_TEXT 0
714 #define IN_ARGS 1
715
716 static char *
717 expand_string (const char *in, int first_only)
718 {
719 int num_expansions = 0;
720 int depth = 0;
721 int narg = -1;
722 arg args[MAXARGS];
723 int state = IN_TEXT;
724 const char *mark = in;
725 macro *pmacro = NULL;
726 char *expansion = 0;
727 char *result = 0;
728
729 while (*in)
730 {
731 switch (state)
732 {
733 case IN_TEXT:
734 if (*in == '%' && *(in + 1) && (!first_only || num_expansions == 0))
735 {
736 pmacro = lookup_macro (in + 1);
737 if (pmacro)
738 {
739 /* printf("entering state %d at '%s'...\n", state, in); */
740 result = str_append (result, mark, in - mark);
741 mark = in;
742 in += 1 + strlen (pmacro->name);
743 while (*in == ' ') ++in;
744 if (*in != '(')
745 {
746 state = IN_TEXT;
747 pmacro = NULL;
748 }
749 else
750 {
751 state = IN_ARGS;
752 narg = 0;
753 args[narg].start = in + 1;
754 args[narg].len = 0;
755 mark = in + 1;
756 }
757 }
758 }
759 break;
760 case IN_ARGS:
761 if (depth == 0)
762 {
763 switch (*in)
764 {
765 case ',':
766 narg++;
767 args[narg].start = (in + 1);
768 args[narg].len = 0;
769 break;
770 case ')':
771 state = IN_TEXT;
772 /* printf("entering state %d at '%s'...\n", state, in); */
773 if (pmacro)
774 {
775 expansion = 0;
776 expansion = expand_macro (args, narg, pmacro);
777 num_expansions++;
778 if (expansion)
779 {
780 result = str_append (result, expansion, strlen (expansion));
781 free (expansion);
782 }
783 }
784 else
785 {
786 result = str_append (result, mark, in - mark);
787 }
788 pmacro = NULL;
789 mark = in + 1;
790 break;
791 case '(':
792 depth++;
793 /* Fall through. */
794 default:
795 args[narg].len++;
796 break;
797 }
798 }
799 else
800 {
801 if (*in == ')')
802 depth--;
803 if (narg > -1)
804 args[narg].len++;
805 }
806
807 }
808 ++in;
809 }
810
811 if (mark != in)
812 result = str_append (result, mark, in - mark);
813
814 return result;
815 }
816
817 #undef IN_ARGS
818 #undef IN_TEXT
819 #undef MAXARGS
820
821
822 /* END LIGHTWEIGHT MACRO PROCESSOR. */
823
824 const char * mep_cgen_parse_operand
825 (CGEN_CPU_DESC, int, const char **, CGEN_FIELDS *);
826
827 const char *
828 mep_cgen_expand_macros_and_parse_operand (CGEN_CPU_DESC cd, int opindex,
829 const char ** strp_in, CGEN_FIELDS * fields)
830 {
831 const char * errmsg = NULL;
832 char *str = 0, *hold = 0;
833 const char **strp = 0;
834
835 /* Set up a new pointer to macro-expanded string. */
836 str = expand_string (*strp_in, 1);
837 /* fprintf (stderr, " expanded <<%s>> to <<%s>>\n", *strp_in, str); */
838
839 hold = str;
840 strp = (const char **)(&str);
841
842 errmsg = mep_cgen_parse_operand (cd, opindex, strp, fields);
843
844 /* Now work out the advance. */
845 if (strlen (str) == 0)
846 *strp_in += strlen (*strp_in);
847
848 else
849 {
850 if (strstr (*strp_in, str))
851 /* A macro-expansion was pulled off the front. */
852 *strp_in = strstr (*strp_in, str);
853 else
854 /* A non-macro-expansion was pulled off the front. */
855 *strp_in += (str - hold);
856 }
857
858 if (hold)
859 free (hold);
860
861 return errmsg;
862 }
863
864 #define CGEN_ASM_INIT_HOOK (cd->parse_operand = mep_cgen_expand_macros_and_parse_operand);
865
866 /* -- dis.c */
867
868 #include "elf/mep.h"
869 #include "elf-bfd.h"
870
871 #define CGEN_VALIDATE_INSN_SUPPORTED
872
873 static void print_tpreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
874 static void print_spreg (CGEN_CPU_DESC, PTR, CGEN_KEYWORD *, long, unsigned int);
875
876 static void
877 print_tpreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
878 CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
879 unsigned int flags ATTRIBUTE_UNUSED)
880 {
881 disassemble_info *info = (disassemble_info *) dis_info;
882
883 (*info->fprintf_func) (info->stream, "$tp");
884 }
885
886 static void
887 print_spreg (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, PTR dis_info,
888 CGEN_KEYWORD *table ATTRIBUTE_UNUSED, long val ATTRIBUTE_UNUSED,
889 unsigned int flags ATTRIBUTE_UNUSED)
890 {
891 disassemble_info *info = (disassemble_info *) dis_info;
892
893 (*info->fprintf_func) (info->stream, "$sp");
894 }
895
896 /* begin-cop-ip-print-handlers */
897 static void
898 print_ivc2_cr (CGEN_CPU_DESC,
899 void *,
900 CGEN_KEYWORD *,
901 long,
902 unsigned int) ATTRIBUTE_UNUSED;
903 static void
904 print_ivc2_cr (CGEN_CPU_DESC cd,
905 void *dis_info,
906 CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
907 long value,
908 unsigned int attrs)
909 {
910 print_keyword (cd, dis_info, & mep_cgen_opval_h_cr_ivc2, value, attrs);
911 }
912 static void
913 print_ivc2_ccr (CGEN_CPU_DESC,
914 void *,
915 CGEN_KEYWORD *,
916 long,
917 unsigned int) ATTRIBUTE_UNUSED;
918 static void
919 print_ivc2_ccr (CGEN_CPU_DESC cd,
920 void *dis_info,
921 CGEN_KEYWORD *keyword_table ATTRIBUTE_UNUSED,
922 long value,
923 unsigned int attrs)
924 {
925 print_keyword (cd, dis_info, & mep_cgen_opval_h_ccr_ivc2, value, attrs);
926 }
927 /* end-cop-ip-print-handlers */
928
929 /************************************************************\
930 *********************** Experimental *************************
931 \************************************************************/
932
933 #undef CGEN_PRINT_INSN
934 #define CGEN_PRINT_INSN mep_print_insn
935
936 static int
937 mep_print_vliw_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info,
938 bfd_byte *buf, int corelength, int copro1length,
939 int copro2length ATTRIBUTE_UNUSED)
940 {
941 int i;
942 int status = 0;
943 /* char insnbuf[CGEN_MAX_INSN_SIZE]; */
944 bfd_byte insnbuf[64];
945
946 /* If corelength > 0 then there is a core insn present. It
947 will be at the beginning of the buffer. After printing
948 the core insn, we need to print the + on the next line. */
949 if (corelength > 0)
950 {
951 int my_status = 0;
952
953 for (i = 0; i < corelength; i++ )
954 insnbuf[i] = buf[i];
955 cd->isas = & MEP_CORE_ISA;
956
957 my_status = print_insn (cd, pc, info, insnbuf, corelength);
958 if (my_status != corelength)
959 {
960 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
961 my_status = corelength;
962 }
963 status += my_status;
964
965 /* Print the + to indicate that the following copro insn is */
966 /* part of a vliw group. */
967 if (copro1length > 0)
968 (*info->fprintf_func) (info->stream, " + ");
969 }
970
971 /* Now all that is left to be processed is the coprocessor insns
972 In vliw mode, there will always be one. Its positioning will
973 be from byte corelength to byte corelength+copro1length -1.
974 No need to check for existence. Also, the first vliw insn,
975 will, as spec'd, always be at least as long as the core insn
976 so we don't need to flush the buffer. */
977 if (copro1length > 0)
978 {
979 int my_status = 0;
980
981 for (i = corelength; i < corelength + copro1length; i++ )
982 insnbuf[i - corelength] = buf[i];
983
984 switch (copro1length)
985 {
986 case 0:
987 break;
988 case 2:
989 cd->isas = & MEP_COP16_ISA;
990 break;
991 case 4:
992 cd->isas = & MEP_COP32_ISA;
993 break;
994 case 6:
995 cd->isas = & MEP_COP48_ISA;
996 break;
997 case 8:
998 cd->isas = & MEP_COP64_ISA;
999 break;
1000 default:
1001 /* Shouldn't be anything but 16,32,48,64. */
1002 break;
1003 }
1004
1005 my_status = print_insn (cd, pc, info, insnbuf, copro1length);
1006
1007 if (my_status != copro1length)
1008 {
1009 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1010 my_status = copro1length;
1011 }
1012 status += my_status;
1013 }
1014
1015 #if 0
1016 /* Now we need to process the second copro insn if it exists. We
1017 have no guarantee that the second copro insn will be longer
1018 than the first, so we have to flush the buffer if we are have
1019 a second copro insn to process. If present, this insn will
1020 be in the position from byte corelength+copro1length to byte
1021 corelength+copro1length+copro2length-1 (which better equal 8
1022 or else we're in big trouble. */
1023 if (copro2length > 0)
1024 {
1025 int my_status = 0;
1026
1027 for (i = 0; i < 64 ; i++)
1028 insnbuf[i] = 0;
1029
1030 for (i = corelength + copro1length; i < 64; i++)
1031 insnbuf[i - (corelength + copro1length)] = buf[i];
1032
1033 switch (copro2length)
1034 {
1035 case 2:
1036 cd->isas = 1 << ISA_EXT_COP1_16;
1037 break;
1038 case 4:
1039 cd->isas = 1 << ISA_EXT_COP1_32;
1040 break;
1041 case 6:
1042 cd->isas = 1 << ISA_EXT_COP1_48;
1043 break;
1044 case 8:
1045 cd->isas = 1 << ISA_EXT_COP1_64;
1046 break;
1047 default:
1048 /* Shouldn't be anything but 16,32,48,64. */
1049 break;
1050 }
1051
1052 my_status = print_insn (cd, pc, info, insnbuf, copro2length);
1053
1054 if (my_status != copro2length)
1055 {
1056 (*info->fprintf_func) (info->stream, UNKNOWN_INSN_MSG);
1057 my_status = copro2length;
1058 }
1059
1060 status += my_status;
1061 }
1062 #endif
1063
1064 /* Status should now be the number of bytes that were printed
1065 which should be 4 for VLIW32 mode and 64 for VLIW64 mode. */
1066
1067 if ((!MEP_VLIW64 && (status != 4)) || (MEP_VLIW64 && (status != 8)))
1068 return -1;
1069 else
1070 return status;
1071 }
1072
1073 /* The two functions mep_examine_vliw[32,64]_insns are used find out
1074 which vliw combinaion (16 bit core with 48 bit copro, 32 bit core
1075 with 32 bit copro, etc.) is present. Later on, when internally
1076 parallel coprocessors are handled, only these functions should
1077 need to be changed.
1078
1079 At this time only the following combinations are supported:
1080
1081 VLIW32 Mode:
1082 16 bit core insn (core) and 16 bit coprocessor insn (cop1)
1083 32 bit core insn (core)
1084 32 bit coprocessor insn (cop1)
1085 Note: As of this time, I do not believe we have enough information
1086 to distinguish a 32 bit core insn from a 32 bit cop insn. Also,
1087 no 16 bit coprocessor insns have been specified.
1088
1089 VLIW64 Mode:
1090 16 bit core insn (core) and 48 bit coprocessor insn (cop1)
1091 32 bit core insn (core) and 32 bit coprocessor insn (cop1)
1092 64 bit coprocessor insn (cop1)
1093
1094 The framework for an internally parallel coprocessor is also
1095 present (2nd coprocessor insn is cop2), but at this time it
1096 is not used. This only appears to be valid in VLIW64 mode. */
1097
1098 static int
1099 mep_examine_vliw32_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1100 {
1101 int status;
1102 int buflength;
1103 int corebuflength;
1104 int cop1buflength;
1105 int cop2buflength;
1106 bfd_byte buf[CGEN_MAX_INSN_SIZE];
1107 char indicator16[1];
1108 char indicatorcop32[2];
1109
1110 /* At this time we're not supporting internally parallel coprocessors,
1111 so cop2buflength will always be 0. */
1112 cop2buflength = 0;
1113
1114 /* Read in 32 bits. */
1115 buflength = 4; /* VLIW insn spans 4 bytes. */
1116 status = (*info->read_memory_func) (pc, buf, buflength, info);
1117
1118 if (status != 0)
1119 {
1120 (*info->memory_error_func) (status, pc, info);
1121 return -1;
1122 }
1123
1124 /* Put the big endian representation of the bytes to be examined
1125 in the temporary buffers for examination. */
1126
1127 if (info->endian == BFD_ENDIAN_BIG)
1128 {
1129 indicator16[0] = buf[0];
1130 indicatorcop32[0] = buf[0];
1131 indicatorcop32[1] = buf[1];
1132 }
1133 else
1134 {
1135 indicator16[0] = buf[1];
1136 indicatorcop32[0] = buf[1];
1137 indicatorcop32[1] = buf[0];
1138 }
1139
1140 /* If the two high order bits are 00, 01 or 10, we have a 16 bit
1141 core insn and a 48 bit copro insn. */
1142
1143 if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
1144 {
1145 if ((indicatorcop32[0] & 0xf0) == 0xf0 && (indicatorcop32[1] & 0x07) == 0x07)
1146 {
1147 /* We have a 32 bit copro insn. */
1148 corebuflength = 0;
1149 /* All 4 4ytes are one copro insn. */
1150 cop1buflength = 4;
1151 }
1152 else
1153 {
1154 /* We have a 32 bit core. */
1155 corebuflength = 4;
1156 cop1buflength = 0;
1157 }
1158 }
1159 else
1160 {
1161 /* We have a 16 bit core insn and a 16 bit copro insn. */
1162 corebuflength = 2;
1163 cop1buflength = 2;
1164 }
1165
1166 /* Now we have the distrubution set. Print them out. */
1167 status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
1168 cop1buflength, cop2buflength);
1169
1170 return status;
1171 }
1172
1173 static int
1174 mep_examine_vliw64_insns (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1175 {
1176 int status;
1177 int buflength;
1178 int corebuflength;
1179 int cop1buflength;
1180 int cop2buflength;
1181 bfd_byte buf[CGEN_MAX_INSN_SIZE];
1182 char indicator16[1];
1183 char indicator64[4];
1184
1185 /* At this time we're not supporting internally parallel
1186 coprocessors, so cop2buflength will always be 0. */
1187 cop2buflength = 0;
1188
1189 /* Read in 64 bits. */
1190 buflength = 8; /* VLIW insn spans 8 bytes. */
1191 status = (*info->read_memory_func) (pc, buf, buflength, info);
1192
1193 if (status != 0)
1194 {
1195 (*info->memory_error_func) (status, pc, info);
1196 return -1;
1197 }
1198
1199 /* We have all 64 bits in the buffer now. We have to figure out
1200 what combination of instruction sizes are present. The two
1201 high order bits will indicate whether or not we have a 16 bit
1202 core insn or not. If not, then we have to look at the 7,8th
1203 bytes to tell whether we have 64 bit copro insn or a 32 bit
1204 core insn with a 32 bit copro insn. Endianness will make a
1205 difference here. */
1206
1207 /* Put the big endian representation of the bytes to be examined
1208 in the temporary buffers for examination. */
1209
1210 /* indicator16[0] = buf[0]; */
1211 if (info->endian == BFD_ENDIAN_BIG)
1212 {
1213 indicator16[0] = buf[0];
1214 indicator64[0] = buf[0];
1215 indicator64[1] = buf[1];
1216 indicator64[2] = buf[2];
1217 indicator64[3] = buf[3];
1218 }
1219 else
1220 {
1221 indicator16[0] = buf[1];
1222 indicator64[0] = buf[1];
1223 indicator64[1] = buf[0];
1224 indicator64[2] = buf[3];
1225 indicator64[3] = buf[2];
1226 }
1227
1228 /* If the two high order bits are 00, 01 or 10, we have a 16 bit
1229 core insn and a 48 bit copro insn. */
1230
1231 if ((indicator16[0] & 0x80) && (indicator16[0] & 0x40))
1232 {
1233 if ((indicator64[0] & 0xf0) == 0xf0 && (indicator64[1] & 0x07) == 0x07
1234 && ((indicator64[2] & 0xfe) != 0xf0 || (indicator64[3] & 0xf4) != 0))
1235 {
1236 /* We have a 64 bit copro insn. */
1237 corebuflength = 0;
1238 /* All 8 bytes are one copro insn. */
1239 cop1buflength = 8;
1240 }
1241 else
1242 {
1243 /* We have a 32 bit core insn and a 32 bit copro insn. */
1244 corebuflength = 4;
1245 cop1buflength = 4;
1246 }
1247 }
1248 else
1249 {
1250 /* We have a 16 bit core insn and a 48 bit copro insn. */
1251 corebuflength = 2;
1252 cop1buflength = 6;
1253 }
1254
1255 /* Now we have the distrubution set. Print them out. */
1256 status = mep_print_vliw_insns (cd, pc, info, buf, corebuflength,
1257 cop1buflength, cop2buflength);
1258
1259 return status;
1260 }
1261
1262 #ifdef MEP_IVC2_SUPPORTED
1263
1264 static int
1265 print_slot_insn (CGEN_CPU_DESC cd,
1266 bfd_vma pc,
1267 disassemble_info *info,
1268 SLOTS_ATTR slot,
1269 bfd_byte *buf)
1270 {
1271 const CGEN_INSN_LIST *insn_list;
1272 CGEN_INSN_INT insn_value;
1273 CGEN_EXTRACT_INFO ex_info;
1274
1275 insn_value = cgen_get_insn_value (cd, buf, 32);
1276
1277 /* Fill in ex_info fields like read_insn would. Don't actually call
1278 read_insn, since the incoming buffer is already read (and possibly
1279 modified a la m32r). */
1280 ex_info.valid = (1 << 8) - 1;
1281 ex_info.dis_info = info;
1282 ex_info.insn_bytes = buf;
1283
1284 /* The instructions are stored in hash lists.
1285 Pick the first one and keep trying until we find the right one. */
1286
1287 insn_list = CGEN_DIS_LOOKUP_INSN (cd, (char *) buf, insn_value);
1288 while (insn_list != NULL)
1289 {
1290 const CGEN_INSN *insn = insn_list->insn;
1291 CGEN_FIELDS fields;
1292 int length;
1293
1294 if ((CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG)
1295 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG) != MEP_CONFIG)
1296 || ! (CGEN_ATTR_CGEN_INSN_SLOTS_VALUE (CGEN_INSN_ATTRS (insn)) & (1 << slot)))
1297 {
1298 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1299 continue;
1300 }
1301
1302 if ((insn_value & CGEN_INSN_BASE_MASK (insn))
1303 == CGEN_INSN_BASE_VALUE (insn))
1304 {
1305 /* Printing is handled in two passes. The first pass parses the
1306 machine insn and extracts the fields. The second pass prints
1307 them. */
1308
1309 length = CGEN_EXTRACT_FN (cd, insn)
1310 (cd, insn, &ex_info, insn_value, &fields, pc);
1311
1312 /* Length < 0 -> error. */
1313 if (length < 0)
1314 return length;
1315 if (length > 0)
1316 {
1317 CGEN_PRINT_FN (cd, insn) (cd, info, insn, &fields, pc, length);
1318 /* Length is in bits, result is in bytes. */
1319 return length / 8;
1320 }
1321 }
1322
1323 insn_list = CGEN_DIS_NEXT_INSN (insn_list);
1324 }
1325
1326 if (slot == SLOTS_P0S)
1327 (*info->fprintf_func) (info->stream, "*unknown-p0s*");
1328 else if (slot == SLOTS_P0)
1329 (*info->fprintf_func) (info->stream, "*unknown-p0*");
1330 else if (slot == SLOTS_P1)
1331 (*info->fprintf_func) (info->stream, "*unknown-p1*");
1332 else if (slot == SLOTS_C3)
1333 (*info->fprintf_func) (info->stream, "*unknown-c3*");
1334 return 0;
1335 }
1336
1337 static int
1338 mep_examine_ivc2_insns (CGEN_CPU_DESC cd ATTRIBUTE_UNUSED, bfd_vma pc ATTRIBUTE_UNUSED, disassemble_info *info ATTRIBUTE_UNUSED)
1339 {
1340 int status;
1341 int buflength;
1342 bfd_byte buf[8];
1343 bfd_byte insn[8];
1344 int e;
1345
1346 /* Read in 64 bits. */
1347 buflength = 8; /* VLIW insn spans 8 bytes. */
1348 status = (*info->read_memory_func) (pc, buf, buflength, info);
1349
1350 if (status != 0)
1351 {
1352 (*info->memory_error_func) (status, pc, info);
1353 return -1;
1354 }
1355
1356 if (info->endian == BFD_ENDIAN_LITTLE)
1357 e = 1;
1358 else
1359 e = 0;
1360
1361 if (((unsigned char)buf[0^e] & 0xf0) < 0xc0)
1362 {
1363 /* <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
1364 /* V1 [-----core-----][--------p0s-------][------------p1------------] */
1365
1366 print_insn (cd, pc, info, buf, 2);
1367
1368 insn[0^e] = 0;
1369 insn[1^e] = buf[2^e];
1370 insn[2^e] = buf[3^e];
1371 insn[3^e] = buf[4^e] & 0xf0;
1372 (*info->fprintf_func) (info->stream, " + ");
1373 print_slot_insn (cd, pc, info, SLOTS_P0S, insn);
1374
1375 insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
1376 insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
1377 insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
1378 insn[3^e] = buf[7^e] << 4;
1379 (*info->fprintf_func) (info->stream, " + ");
1380 print_slot_insn (cd, pc, info, SLOTS_P1, insn);
1381 }
1382 else if ((buf[0^e] & 0xf0) == 0xf0 && (buf[1^e] & 0x0f) == 0x07)
1383 {
1384 /* <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
1385 /* V3 1111[--p0--]0111[--------p0--------][------------p1------------] */
1386 /* 00000000111111112222222233333333 */
1387
1388 insn[0^e] = buf[0^e] << 4 | buf[1^e] >> 4;
1389 insn[1^e] = buf[2^e];
1390 insn[2^e] = buf[3^e];
1391 insn[3^e] = buf[4^e] & 0xf0;
1392 print_slot_insn (cd, pc, info, SLOTS_P0, insn);
1393
1394 insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
1395 insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
1396 insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
1397 insn[3^e] = buf[7^e] << 4;
1398 (*info->fprintf_func) (info->stream, " + ");
1399 print_slot_insn (cd, pc, info, SLOTS_P1, insn);
1400 }
1401 else
1402 {
1403 /* <--00--><--11--><--22--><--33--><--44--><--55--><--66--><--77--> */
1404 /* V2 [-------------core-------------]xxxx[------------p1------------] */
1405 print_insn (cd, pc, info, buf, 4);
1406
1407 insn[0^e] = buf[4^e] << 4 | buf[5^e] >> 4;
1408 insn[1^e] = buf[5^e] << 4 | buf[6^e] >> 4;
1409 insn[2^e] = buf[6^e] << 4 | buf[7^e] >> 4;
1410 insn[3^e] = buf[7^e] << 4;
1411 (*info->fprintf_func) (info->stream, " + ");
1412 print_slot_insn (cd, pc, info, SLOTS_P1, insn);
1413 }
1414
1415 return 8;
1416 }
1417
1418 #endif /* MEP_IVC2_SUPPORTED */
1419
1420 /* This is a hack. SID calls this to update the disassembler as the
1421 CPU changes modes. */
1422 static int mep_ivc2_disassemble_p = 0;
1423 static int mep_ivc2_vliw_disassemble_p = 0;
1424
1425 void
1426 mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx);
1427 void
1428 mep_print_insn_set_ivc2_mode (int ivc2_p, int vliw_p, int cfg_idx)
1429 {
1430 mep_ivc2_disassemble_p = ivc2_p;
1431 mep_ivc2_vliw_disassemble_p = vliw_p;
1432 mep_config_index = cfg_idx;
1433 }
1434
1435 static int
1436 mep_print_insn (CGEN_CPU_DESC cd, bfd_vma pc, disassemble_info *info)
1437 {
1438 int status;
1439 int cop_type;
1440 int ivc2 = 0;
1441 static CGEN_ATTR_VALUE_BITSET_TYPE *ivc2_core_isa = NULL;
1442
1443 if (ivc2_core_isa == NULL)
1444 {
1445 /* IVC2 has some core-only coprocessor instructions. We
1446 use COP32 to flag those, and COP64 for the VLIW ones,
1447 since they have the same names. */
1448 ivc2_core_isa = cgen_bitset_create (MAX_ISAS);
1449 }
1450
1451 /* Extract and adapt to configuration number, if available. */
1452 if (info->section && info->section->owner)
1453 {
1454 bfd *abfd = info->section->owner;
1455 mep_config_index = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_INDEX_MASK;
1456 /* This instantly redefines MEP_CONFIG, MEP_OMASK, .... MEP_VLIW64 */
1457
1458 cop_type = abfd->tdata.elf_obj_data->elf_header->e_flags & EF_MEP_COP_MASK;
1459 if (cop_type == EF_MEP_COP_IVC2)
1460 ivc2 = 1;
1461 }
1462
1463 /* Picking the right ISA bitmask for the current context is tricky. */
1464 if (info->section)
1465 {
1466 if (info->section->flags & SEC_MEP_VLIW)
1467 {
1468 #ifdef MEP_IVC2_SUPPORTED
1469 if (ivc2)
1470 {
1471 /* ivc2 has its own way of selecting its functions. */
1472 cd->isas = & MEP_CORE_ISA;
1473 status = mep_examine_ivc2_insns (cd, pc, info);
1474 }
1475 else
1476 #endif
1477 /* Are we in 32 or 64 bit vliw mode? */
1478 if (MEP_VLIW64)
1479 status = mep_examine_vliw64_insns (cd, pc, info);
1480 else
1481 status = mep_examine_vliw32_insns (cd, pc, info);
1482 /* Both the above branches set their own isa bitmasks. */
1483 }
1484 else
1485 {
1486 if (ivc2)
1487 {
1488 cgen_bitset_clear (ivc2_core_isa);
1489 cgen_bitset_union (ivc2_core_isa, &MEP_CORE_ISA, ivc2_core_isa);
1490 cgen_bitset_union (ivc2_core_isa, &MEP_COP32_ISA, ivc2_core_isa);
1491 cd->isas = ivc2_core_isa;
1492 }
1493 else
1494 cd->isas = & MEP_CORE_ISA;
1495 status = default_print_insn (cd, pc, info);
1496 }
1497 }
1498 else /* sid or gdb */
1499 {
1500 #ifdef MEP_IVC2_SUPPORTED
1501 if (mep_ivc2_disassemble_p)
1502 {
1503 if (mep_ivc2_vliw_disassemble_p)
1504 {
1505 cd->isas = & MEP_CORE_ISA;
1506 status = mep_examine_ivc2_insns (cd, pc, info);
1507 return status;
1508 }
1509 else
1510 {
1511 if (ivc2)
1512 cd->isas = ivc2_core_isa;
1513 }
1514 }
1515 #endif
1516
1517 status = default_print_insn (cd, pc, info);
1518 }
1519
1520 return status;
1521 }
1522
1523
1524 /* -- opc.c */
1525 #include "elf/mep.h"
1526
1527 /* A mask for all ISAs executed by the core. */
1528 CGEN_ATTR_VALUE_BITSET_TYPE mep_all_core_isas_mask = {0, 0};
1529
1530 void
1531 init_mep_all_core_isas_mask (void)
1532 {
1533 if (mep_all_core_isas_mask.length != 0)
1534 return;
1535 cgen_bitset_init (& mep_all_core_isas_mask, ISA_MAX);
1536 cgen_bitset_set (& mep_all_core_isas_mask, ISA_MEP);
1537 /* begin-all-core-isas */
1538 cgen_bitset_add (& mep_all_core_isas_mask, ISA_EXT_CORE1);
1539 /* end-all-core-isas */
1540 }
1541
1542 CGEN_ATTR_VALUE_BITSET_TYPE mep_all_cop_isas_mask = {0, 0};
1543
1544 void
1545 init_mep_all_cop_isas_mask (void)
1546 {
1547 if (mep_all_cop_isas_mask.length != 0)
1548 return;
1549 cgen_bitset_init (& mep_all_cop_isas_mask, ISA_MAX);
1550 /* begin-all-cop-isas */
1551 cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_16);
1552 cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_32);
1553 cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_48);
1554 cgen_bitset_add (& mep_all_cop_isas_mask, ISA_EXT_COP1_64);
1555 /* end-all-cop-isas */
1556 }
1557
1558 int
1559 mep_insn_supported_by_isa (const CGEN_INSN *insn, CGEN_ATTR_VALUE_BITSET_TYPE *isa_mask)
1560 {
1561 CGEN_BITSET insn_isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
1562 return cgen_bitset_intersect_p (& insn_isas, isa_mask);
1563 }
1564
1565 #define OPTION_MASK \
1566 ( (1 << CGEN_INSN_OPTIONAL_BIT_INSN) \
1567 | (1 << CGEN_INSN_OPTIONAL_MUL_INSN) \
1568 | (1 << CGEN_INSN_OPTIONAL_DIV_INSN) \
1569 | (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN) \
1570 | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN) \
1571 | (1 << CGEN_INSN_OPTIONAL_ABS_INSN) \
1572 | (1 << CGEN_INSN_OPTIONAL_AVE_INSN) \
1573 | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN) \
1574 | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN) \
1575 | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) \
1576 | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) \
1577 | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) \
1578 | (1 << CGEN_INSN_OPTIONAL_CP_INSN) \
1579 | (1 << CGEN_INSN_OPTIONAL_CP64_INSN) )
1580
1581
1582 mep_config_map_struct mep_config_map[] =
1583 {
1584 /* config-map-start */
1585 /* Default entry: first module, with all options enabled. */
1586 { "", 0, EF_MEP_COP_IVC2 | EF_MEP_CPU_C5,0, 64, { 1, "\x20" }, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x3c" }, { 1, "\xc0" }, OPTION_MASK | (1 << CGEN_INSN_OPTIONAL_DSP_INSN) | (1 << CGEN_INSN_OPTIONAL_UCI_INSN) },
1587 { "default", CONFIG_DEFAULT, EF_MEP_COP_IVC2 | EF_MEP_CPU_C5, 0, 64, { 1, "\x20" }, { 1, "\x10" }, { 1, "\x8" }, { 1, "\x4" }, { 1, "\x3c" }, { 1, "\xc0" },
1588 0
1589 | (1 << CGEN_INSN_OPTIONAL_CP_INSN)
1590 | (1 << CGEN_INSN_OPTIONAL_CP64_INSN)
1591 | (1 << CGEN_INSN_OPTIONAL_MUL_INSN)
1592 | (1 << CGEN_INSN_OPTIONAL_DIV_INSN)
1593 | (1 << CGEN_INSN_OPTIONAL_BIT_INSN)
1594 | (1 << CGEN_INSN_OPTIONAL_LDZ_INSN)
1595 | (1 << CGEN_INSN_OPTIONAL_ABS_INSN)
1596 | (1 << CGEN_INSN_OPTIONAL_AVE_INSN)
1597 | (1 << CGEN_INSN_OPTIONAL_MINMAX_INSN)
1598 | (1 << CGEN_INSN_OPTIONAL_CLIP_INSN)
1599 | (1 << CGEN_INSN_OPTIONAL_SAT_INSN) },
1600 /* config-map-end */
1601 { 0, 0, 0, 0, 0, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, {0, 0}, 0 }
1602 };
1603
1604 int mep_config_index = 0;
1605
1606 static int
1607 check_configured_mach (int machs)
1608 {
1609 /* All base insns are supported. */
1610 int mach = 1 << MACH_BASE;
1611 switch (MEP_CPU & EF_MEP_CPU_MASK)
1612 {
1613 case EF_MEP_CPU_C2:
1614 case EF_MEP_CPU_C3:
1615 mach |= (1 << MACH_MEP);
1616 break;
1617 case EF_MEP_CPU_H1:
1618 mach |= (1 << MACH_H1);
1619 break;
1620 case EF_MEP_CPU_C5:
1621 mach |= (1 << MACH_MEP);
1622 mach |= (1 << MACH_C5);
1623 break;
1624 default:
1625 break;
1626 }
1627 return machs & mach;
1628 }
1629
1630 int
1631 mep_cgen_insn_supported (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
1632 {
1633 int iconfig = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_CONFIG);
1634 int machs = CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_MACH);
1635 CGEN_BITSET isas = CGEN_INSN_BITSET_ATTR_VALUE (insn, CGEN_INSN_ISA);
1636 int ok1;
1637 int ok2;
1638 int ok3;
1639
1640 /* If the insn has an option bit set that we don't want,
1641 reject it. */
1642 if (CGEN_INSN_ATTRS (insn)->bool_ & OPTION_MASK & ~MEP_OMASK)
1643 return 0;
1644
1645 /* If attributes are absent, assume no restriction. */
1646 if (machs == 0)
1647 machs = ~0;
1648
1649 ok1 = ((machs & cd->machs) && cgen_bitset_intersect_p (& isas, cd->isas));
1650 /* If the insn is config-specific, make sure it matches. */
1651 ok2 = (iconfig == 0 || iconfig == MEP_CONFIG);
1652 /* Make sure the insn is supported by the configured mach */
1653 ok3 = check_configured_mach (machs);
1654
1655 return (ok1 && ok2 && ok3);
1656 }
1657
1658 int
1659 mep_cgen_insn_supported_asm (CGEN_CPU_DESC cd, const CGEN_INSN *insn)
1660 {
1661 #ifdef MEP_IVC2_SUPPORTED
1662 /* If we're assembling VLIW packets, ignore the 12-bit BSR as we
1663 can't relax that. The 24-bit BSR is matched instead. */
1664 if (insn->base->num == MEP_INSN_BSR12
1665 && cgen_bitset_contains (cd->isas, ISA_EXT_COP1_64))
1666 return 0;
1667 #endif
1668
1669 return mep_cgen_insn_supported (cd, insn);
1670 }
This page took 0.063659 seconds and 4 git commands to generate.