1 /* tc-mep.c -- Assembler for the Toshiba Media Processor.
2 Copyright (C) 2001, 2002, 2003, 2004, 2005, 2007
3 Free Software Foundation. Inc.
5 This file is part of GAS, the GNU Assembler.
7 GAS is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
12 GAS is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GAS; see the file COPYING. If not, write to
19 the Free Software Foundation, 51 Franklin Street, Fifth Floor,
20 Boston, MA 02110-1301, USA. */
24 #include "dwarf2dbg.h"
27 #include "opcodes/mep-desc.h"
28 #include "opcodes/mep-opc.h"
30 #include "elf/common.h"
35 /* Structure to hold all of the different components describing
36 an individual instruction. */
39 const CGEN_INSN
* insn
;
40 const CGEN_INSN
* orig_insn
;
43 CGEN_INSN_INT buffer
[1];
44 #define INSN_VALUE(buf) (*(buf))
46 unsigned char buffer
[CGEN_MAX_INSN_SIZE
];
47 #define INSN_VALUE(buf) (buf)
52 fixS
* fixups
[GAS_CGEN_MAX_FIXUPS
];
53 int indices
[MAX_OPERAND_INSTANCES
];
56 static int mode
= CORE
; /* Start in core mode. */
57 static int pluspresent
= 0;
58 static int allow_disabled_registers
= 0;
59 static int library_flag
= 0;
61 /* We're going to need to store all of the instructions along with
62 their fixups so that we can parallelization grouping rules. */
64 static mep_insn saved_insns
[MAX_SAVED_FIXUP_CHAINS
];
65 static int num_insns_saved
= 0;
67 const char comment_chars
[] = "#";
68 const char line_comment_chars
[] = ";#";
69 const char line_separator_chars
[] = ";";
70 const char EXP_CHARS
[] = "eE";
71 const char FLT_CHARS
[] = "dD";
73 static void mep_switch_to_vliw_mode (int);
74 static void mep_switch_to_core_mode (int);
75 static void mep_s_vtext (int);
76 static void mep_noregerr (int);
78 /* The target specific pseudo-ops which we support. */
79 const pseudo_typeS md_pseudo_table
[] =
82 { "file", (void (*) (int)) dwarf2_directive_file
, 0 },
83 { "loc", dwarf2_directive_loc
, 0 },
84 { "vliw", mep_switch_to_vliw_mode
, 0 },
85 { "core", mep_switch_to_core_mode
, 0 },
86 { "vtext", mep_s_vtext
, 0 },
87 { "noregerr", mep_noregerr
, 0 },
91 /* Relocations against symbols are done in two
92 parts, with a HI relocation and a LO relocation. Each relocation
93 has only 16 bits of space to store an addend. This means that in
94 order for the linker to handle carries correctly, it must be able
95 to locate both the HI and the LO relocation. This means that the
96 relocations must appear in order in the relocation table.
98 In order to implement this, we keep track of each unmatched HI
99 relocation. We then sort them so that they immediately precede the
100 corresponding LO relocation. */
104 struct mep_hi_fixup
* next
; /* Next HI fixup. */
105 fixS
* fixp
; /* This fixup. */
106 segT seg
; /* The section this fixup is in. */
109 /* The list of unmatched HI relocs. */
110 static struct mep_hi_fixup
* mep_hi_fixup_list
;
113 #define OPTION_EB (OPTION_MD_BASE + 0)
114 #define OPTION_EL (OPTION_MD_BASE + 1)
115 #define OPTION_CONFIG (OPTION_MD_BASE + 2)
116 #define OPTION_AVERAGE (OPTION_MD_BASE + 3)
117 #define OPTION_NOAVERAGE (OPTION_MD_BASE + 4)
118 #define OPTION_MULT (OPTION_MD_BASE + 5)
119 #define OPTION_NOMULT (OPTION_MD_BASE + 6)
120 #define OPTION_DIV (OPTION_MD_BASE + 7)
121 #define OPTION_NODIV (OPTION_MD_BASE + 8)
122 #define OPTION_BITOPS (OPTION_MD_BASE + 9)
123 #define OPTION_NOBITOPS (OPTION_MD_BASE + 10)
124 #define OPTION_LEADZ (OPTION_MD_BASE + 11)
125 #define OPTION_NOLEADZ (OPTION_MD_BASE + 12)
126 #define OPTION_ABSDIFF (OPTION_MD_BASE + 13)
127 #define OPTION_NOABSDIFF (OPTION_MD_BASE + 14)
128 #define OPTION_MINMAX (OPTION_MD_BASE + 15)
129 #define OPTION_NOMINMAX (OPTION_MD_BASE + 16)
130 #define OPTION_CLIP (OPTION_MD_BASE + 17)
131 #define OPTION_NOCLIP (OPTION_MD_BASE + 18)
132 #define OPTION_SATUR (OPTION_MD_BASE + 19)
133 #define OPTION_NOSATUR (OPTION_MD_BASE + 20)
134 #define OPTION_COP32 (OPTION_MD_BASE + 21)
135 #define OPTION_REPEAT (OPTION_MD_BASE + 25)
136 #define OPTION_NOREPEAT (OPTION_MD_BASE + 26)
137 #define OPTION_DEBUG (OPTION_MD_BASE + 27)
138 #define OPTION_NODEBUG (OPTION_MD_BASE + 28)
139 #define OPTION_LIBRARY (OPTION_MD_BASE + 29)
141 struct option md_longopts
[] = {
142 { "EB", no_argument
, NULL
, OPTION_EB
},
143 { "EL", no_argument
, NULL
, OPTION_EL
},
144 { "mconfig", required_argument
, NULL
, OPTION_CONFIG
},
145 { "maverage", no_argument
, NULL
, OPTION_AVERAGE
},
146 { "mno-average", no_argument
, NULL
, OPTION_NOAVERAGE
},
147 { "mmult", no_argument
, NULL
, OPTION_MULT
},
148 { "mno-mult", no_argument
, NULL
, OPTION_NOMULT
},
149 { "mdiv", no_argument
, NULL
, OPTION_DIV
},
150 { "mno-div", no_argument
, NULL
, OPTION_NODIV
},
151 { "mbitops", no_argument
, NULL
, OPTION_BITOPS
},
152 { "mno-bitops", no_argument
, NULL
, OPTION_NOBITOPS
},
153 { "mleadz", no_argument
, NULL
, OPTION_LEADZ
},
154 { "mno-leadz", no_argument
, NULL
, OPTION_NOLEADZ
},
155 { "mabsdiff", no_argument
, NULL
, OPTION_ABSDIFF
},
156 { "mno-absdiff", no_argument
, NULL
, OPTION_NOABSDIFF
},
157 { "mminmax", no_argument
, NULL
, OPTION_MINMAX
},
158 { "mno-minmax", no_argument
, NULL
, OPTION_NOMINMAX
},
159 { "mclip", no_argument
, NULL
, OPTION_CLIP
},
160 { "mno-clip", no_argument
, NULL
, OPTION_NOCLIP
},
161 { "msatur", no_argument
, NULL
, OPTION_SATUR
},
162 { "mno-satur", no_argument
, NULL
, OPTION_NOSATUR
},
163 { "mcop32", no_argument
, NULL
, OPTION_COP32
},
164 { "mdebug", no_argument
, NULL
, OPTION_DEBUG
},
165 { "mno-debug", no_argument
, NULL
, OPTION_NODEBUG
},
166 { "mlibrary", no_argument
, NULL
, OPTION_LIBRARY
},
167 { NULL
, 0, NULL
, 0 } };
168 size_t md_longopts_size
= sizeof (md_longopts
);
170 const char * md_shortopts
= "";
171 static int optbits
= 0;
172 static int optbitset
= 0;
175 md_parse_option (int c
, char *arg ATTRIBUTE_UNUSED
)
181 target_big_endian
= 1;
184 target_big_endian
= 0;
188 for (i
=1; mep_config_map
[i
].name
; i
++)
189 if (strcmp (mep_config_map
[i
].name
, arg
) == 0)
196 fprintf (stderr
, "Error: unknown configuration %s\n", arg
);
199 mep_config_index
= idx
;
200 target_big_endian
= mep_config_map
[idx
].big_endian
;
203 optbits
|= 1 << CGEN_INSN_OPTIONAL_AVE_INSN
;
204 optbitset
|= 1 << CGEN_INSN_OPTIONAL_AVE_INSN
;
206 case OPTION_NOAVERAGE
:
207 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_AVE_INSN
);
208 optbitset
|= 1 << CGEN_INSN_OPTIONAL_AVE_INSN
;
211 optbits
|= 1 << CGEN_INSN_OPTIONAL_MUL_INSN
;
212 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MUL_INSN
;
215 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_MUL_INSN
);
216 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MUL_INSN
;
219 optbits
|= 1 << CGEN_INSN_OPTIONAL_DIV_INSN
;
220 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DIV_INSN
;
223 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_DIV_INSN
);
224 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DIV_INSN
;
227 optbits
|= 1 << CGEN_INSN_OPTIONAL_BIT_INSN
;
228 optbitset
|= 1 << CGEN_INSN_OPTIONAL_BIT_INSN
;
230 case OPTION_NOBITOPS
:
231 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_BIT_INSN
);
232 optbitset
|= 1 << CGEN_INSN_OPTIONAL_BIT_INSN
;
235 optbits
|= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN
;
236 optbitset
|= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN
;
239 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_LDZ_INSN
);
240 optbitset
|= 1 << CGEN_INSN_OPTIONAL_LDZ_INSN
;
243 optbits
|= 1 << CGEN_INSN_OPTIONAL_ABS_INSN
;
244 optbitset
|= 1 << CGEN_INSN_OPTIONAL_ABS_INSN
;
246 case OPTION_NOABSDIFF
:
247 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_ABS_INSN
);
248 optbitset
|= 1 << CGEN_INSN_OPTIONAL_ABS_INSN
;
251 optbits
|= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
;
252 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
;
254 case OPTION_NOMINMAX
:
255 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
);
256 optbitset
|= 1 << CGEN_INSN_OPTIONAL_MINMAX_INSN
;
259 optbits
|= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN
;
260 optbitset
|= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN
;
263 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_CLIP_INSN
);
264 optbitset
|= 1 << CGEN_INSN_OPTIONAL_CLIP_INSN
;
267 optbits
|= 1 << CGEN_INSN_OPTIONAL_SAT_INSN
;
268 optbitset
|= 1 << CGEN_INSN_OPTIONAL_SAT_INSN
;
271 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_SAT_INSN
);
272 optbitset
|= 1 << CGEN_INSN_OPTIONAL_SAT_INSN
;
275 optbits
|= 1 << CGEN_INSN_OPTIONAL_CP_INSN
;
276 optbitset
|= 1 << CGEN_INSN_OPTIONAL_CP_INSN
;
279 optbits
|= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
;
280 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
;
283 optbits
&= ~(1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
);
284 optbitset
|= 1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
;
287 library_flag
= EF_MEP_LIBRARY
;
290 case OPTION_NOREPEAT
:
299 md_show_usage (FILE *stream
)
301 fprintf (stream
, _("MeP specific command line options:\n\
302 -EB assemble for a big endian system (default)\n\
303 -EL assemble for a little endian system\n\
304 -mconfig=<name> specify a chip configuration to use\n\
305 -maverage -mno-average -mmult -mno-mult -mdiv -mno-div\n\
306 -mbitops -mno-bitops -mleadz -mno-leadz -mabsdiff -mno-absdiff\n\
307 -mminmax -mno-minmax -mclip -mno-clip -msatur -mno-satur -mcop32\n\
308 enable/disable the given opcodes\n\
310 If -mconfig is given, the other -m options modify it. Otherwise,\n\
311 if no -m options are given, all core opcodes are enabled;\n\
312 if any enabling -m options are given, only those are enabled;\n\
313 if only disabling -m options are given, only those are disabled.\n\
315 if (mep_config_map
[1].name
)
318 fprintf (stream
, " -mconfig=STR specify the configuration to use\n");
319 fprintf (stream
, " Configurations:");
320 for (i
=0; mep_config_map
[i
].name
; i
++)
321 fprintf (stream
, " %s", mep_config_map
[i
].name
);
322 fprintf (stream
, "\n");
329 mep_check_for_disabled_registers (mep_insn
*insn
)
331 static int initted
= 0;
332 static int has_mul_div
= 0;
333 static int has_cop
= 0;
334 static int has_debug
= 0;
337 if (allow_disabled_registers
)
341 if (target_big_endian
)
342 b
= insn
->buffer
[0] * 256 + insn
->buffer
[1];
344 b
= insn
->buffer
[1] * 256 + insn
->buffer
[0];
349 if ((b
& 0xfffff00e) == 0x7008 /* stc */
350 || (b
& 0xfffff00e) == 0x700a /* ldc */)
355 if ((MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_MUL_INSN
))
356 || (MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_DIV_INSN
)))
358 if (MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_DEBUG_INSN
))
360 if (MEP_OMASK
& (1 << CGEN_INSN_OPTIONAL_CP_INSN
))
364 r
= ((b
& 0x00f0) >> 4) | ((b
& 0x0001) << 4);
370 as_bad ("$hi and $lo are disabled when MUL and DIV are off");
377 as_bad ("$mb0, $me0, $mb1, and $me1 are disabled when COP is off");
382 as_bad ("$dbg and $depc are disabled when DEBUG is off");
394 case EF_MEP_CPU_C2
: return bfd_mach_mep
;
395 case EF_MEP_CPU_C3
: return bfd_mach_mep
;
396 case EF_MEP_CPU_C4
: return bfd_mach_mep
;
397 case EF_MEP_CPU_H1
: return bfd_mach_mep_h1
;
403 /* The MeP version of the cgen parse_operand function. The only difference
404 from the standard version is that we want to avoid treating '$foo' and
405 '($foo...)' as references to a symbol called '$foo'. The chances are
406 that '$foo' is really a misspelt register. */
409 mep_parse_operand (CGEN_CPU_DESC cd
, enum cgen_parse_operand_type want
,
410 const char **strP
, int opindex
, int opinfo
,
411 enum cgen_parse_operand_result
*resultP
, bfd_vma
*valueP
)
413 if (want
== CGEN_PARSE_OPERAND_INTEGER
|| want
== CGEN_PARSE_OPERAND_ADDRESS
)
421 return "Not a valid literal";
423 return gas_cgen_parse_operand (cd
, want
, strP
, opindex
, opinfo
,
430 /* Initialize the `cgen' interface. */
432 /* If the user specifies no options, we default to allowing
433 everything. If the user specifies any enabling options, we
434 default to allowing only what is specified. If the user
435 specifies only disabling options, we only disable what is
436 specified. If the user specifies options and a config, the
437 options modify the config. */
438 if (optbits
&& mep_config_index
== 0)
441 MEP_OMASK
= (MEP_OMASK
& ~optbitset
) | optbits
;
443 /* Set the machine number and endian. */
444 gas_cgen_cpu_desc
= mep_cgen_cpu_open (CGEN_CPU_OPEN_MACHS
, 0,
445 CGEN_CPU_OPEN_ENDIAN
,
448 : CGEN_ENDIAN_LITTLE
,
449 CGEN_CPU_OPEN_ISAS
, 0,
451 mep_cgen_init_asm (gas_cgen_cpu_desc
);
453 /* This is a callback from cgen to gas to parse operands. */
454 cgen_set_parse_operand_fn (gas_cgen_cpu_desc
, mep_parse_operand
);
456 /* Identify the architecture. */
457 bfd_default_set_arch_mach (stdoutput
, bfd_arch_mep
, mep_machine ());
459 /* Store the configuration number and core. */
460 bfd_set_private_flags (stdoutput
, MEP_CPU
| MEP_CONFIG
| library_flag
);
462 /* Initialize the array we'll be using to store fixups. */
463 gas_cgen_initialize_saved_fixups_array();
466 /* Variant of mep_cgen_assemble_insn. Assemble insn STR of cpu CD as a
467 coprocessor instruction, if possible, into FIELDS, BUF, and INSN. */
469 static const CGEN_INSN
*
470 mep_cgen_assemble_cop_insn (CGEN_CPU_DESC cd
,
473 CGEN_INSN_BYTES_PTR buf
,
474 const struct cgen_insn
*pinsn
)
477 CGEN_INSN_LIST
*ilist
;
478 const char *errmsg
= NULL
;
480 /* The instructions are stored in hashed lists. */
481 ilist
= CGEN_ASM_LOOKUP_INSN (gas_cgen_cpu_desc
,
482 CGEN_INSN_MNEMONIC (pinsn
));
485 for ( ; ilist
!= NULL
; ilist
= CGEN_ASM_NEXT_INSN (ilist
))
487 const CGEN_INSN
*insn
= ilist
->insn
;
488 if (strcmp (CGEN_INSN_MNEMONIC (ilist
->insn
),
489 CGEN_INSN_MNEMONIC (pinsn
)) == 0
490 && MEP_INSN_COP_P (ilist
->insn
)
491 && mep_cgen_insn_supported (cd
, insn
))
495 /* skip this insn if str doesn't look right lexically */
496 if (CGEN_INSN_RX (insn
) != NULL
&&
497 regexec ((regex_t
*) CGEN_INSN_RX (insn
), str
, 0, NULL
, 0) == REG_NOMATCH
)
500 /* Allow parse/insert handlers to obtain length of insn. */
501 CGEN_FIELDS_BITSIZE (fields
) = CGEN_INSN_BITSIZE (insn
);
503 errmsg
= CGEN_PARSE_FN (cd
, insn
) (cd
, insn
, & str
, fields
);
507 errmsg
= CGEN_INSERT_FN (cd
, insn
) (cd
, insn
, fields
, buf
,
519 mep_save_insn (mep_insn insn
)
521 /* Consider change MAX_SAVED_FIXUP_CHAINS to MAX_PARALLEL_INSNS. */
522 if (num_insns_saved
< 0 || num_insns_saved
>= MAX_SAVED_FIXUP_CHAINS
)
524 as_fatal("index into saved_insns[] out of bounds.");
527 saved_insns
[num_insns_saved
] = insn
;
528 gas_cgen_save_fixups(num_insns_saved
);
533 mep_check_parallel32_scheduling (void)
535 int insn0iscopro
, insn1iscopro
, insn0length
, insn1length
;
537 /* More than two instructions means that either someone is referring to
538 an internally parallel core or an internally parallel coprocessor,
539 neither of which are supported at this time. */
540 if ( num_insns_saved
> 2 )
541 as_fatal("Internally paralled cores and coprocessors not supported.");
543 /* If there are no insns saved, that's ok. Just return. This will
544 happen when mep_process_saved_insns is called when the end of the
545 source file is reached and there are no insns left to be processed. */
546 if (num_insns_saved
== 0)
549 /* Check some of the attributes of the first insn. */
550 insn0iscopro
= MEP_INSN_COP_P (saved_insns
[0].insn
);
551 insn0length
= CGEN_FIELDS_BITSIZE (& saved_insns
[0].fields
);
553 if (num_insns_saved
== 2)
555 /* Check some of the attributes of the first insn. */
556 insn1iscopro
= MEP_INSN_COP_P (saved_insns
[1].insn
);
557 insn1length
= CGEN_FIELDS_BITSIZE (& saved_insns
[1].fields
);
559 if ((insn0iscopro
&& !insn1iscopro
)
560 || (insn1iscopro
&& !insn0iscopro
))
562 /* We have one core and one copro insn. If their sizes
563 add up to 32, then the combination is valid. */
564 if (insn0length
+ insn1length
== 32)
567 as_bad ("core and copro insn lengths must total 32 bits.");
570 as_bad ("vliw group must consist of 1 core and 1 copro insn.");
574 /* If we arrive here, we have one saved instruction. There are a
575 number of possible cases:
577 1. The instruction is a 32 bit core or coprocessor insn and
578 can be executed by itself. Valid.
580 2. The instrucion is a core instruction for which a cop nop
581 exists. In this case, insert the cop nop into the saved
582 insn array after the core insn and return. Valid.
584 3. The instruction is a coprocessor insn for which a core nop
585 exists. In this case, move the coprocessor insn to the
586 second element of the array and put the nop in the first
587 element then return. Valid.
589 4. The instruction is a core or coprocessor instruction for
590 which there is no matching coprocessor or core nop to use
591 to form a valid vliw insn combination. In this case, we
594 if (insn0length
> 32)
595 as_fatal ("Cannot use 48- or 64-bit insns with a 32 bit datapath.");
597 if (insn0length
== 32)
600 /* Insn is smaller than datapath. If there are no matching
601 nops for this insn, then terminate assembly. */
602 if (CGEN_INSN_ATTR_VALUE (saved_insns
[0].insn
,
603 CGEN_INSN_VLIW32_NO_MATCHING_NOP
))
604 as_fatal ("No valid nop.");
606 /* At this point we know that we have a single 16-bit insn that has
607 a matching nop. We have to assemble it and put it into the saved
608 insn and fixup chain arrays. */
615 /* Move the insn and it's fixups to the second element of the
616 saved insns arrary and insert a 16 bit core nope into the
618 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "nop",
619 &insn
.fields
, insn
.buffer
,
623 as_bad ("%s", errmsg
);
627 /* Move the insn in element 0 to element 1 and insert the
628 nop into element 0. Move the fixups in element 0 to
629 element 1 and save the current fixups to element 0.
630 Really there aren't any fixups at this point because we're
631 inserting a nop but we might as well be general so that
632 if there's ever a need to insert a general insn, we'll
634 saved_insns
[1] = saved_insns
[0];
635 saved_insns
[0] = insn
;
637 gas_cgen_swap_fixups (0);
638 gas_cgen_save_fixups (1);
644 int insn_num
= saved_insns
[0].insn
->base
->num
;
646 /* Use 32 bit branches and skip the nop. */
647 if (insn_num
== MEP_INSN_BSR12
648 || insn_num
== MEP_INSN_BEQZ
649 || insn_num
== MEP_INSN_BNEZ
)
652 /* Insert a 16-bit coprocessor nop. Note that at the time */
653 /* this was done, no 16-bit coprocessor nop was defined. */
654 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop16",
655 &insn
.fields
, insn
.buffer
,
659 as_bad ("%s", errmsg
);
663 /* Now put the insn and fixups into the arrays. */
664 mep_save_insn (insn
);
670 mep_check_parallel64_scheduling (void)
672 int insn0iscopro
, insn1iscopro
, insn0length
, insn1length
;
674 /* More than two instructions means that someone is referring to an
675 internally parallel core or an internally parallel coprocessor. */
676 /* These are not currently supported. */
677 if (num_insns_saved
> 2)
678 as_fatal ("Internally parallel cores of coprocessors not supported.");
680 /* If there are no insns saved, that's ok. Just return. This will
681 happen when mep_process_saved_insns is called when the end of the
682 source file is reached and there are no insns left to be processed. */
683 if (num_insns_saved
== 0)
686 /* Check some of the attributes of the first insn. */
687 insn0iscopro
= MEP_INSN_COP_P (saved_insns
[0].insn
);
688 insn0length
= CGEN_FIELDS_BITSIZE (& saved_insns
[0].fields
);
690 if (num_insns_saved
== 2)
692 /* Check some of the attributes of the first insn. */
693 insn1iscopro
= MEP_INSN_COP_P (saved_insns
[1].insn
);
694 insn1length
= CGEN_FIELDS_BITSIZE (& saved_insns
[1].fields
);
696 if ((insn0iscopro
&& !insn1iscopro
)
697 || (insn1iscopro
&& !insn0iscopro
))
699 /* We have one core and one copro insn. If their sizes
700 add up to 64, then the combination is valid. */
701 if (insn0length
+ insn1length
== 64)
704 as_bad ("core and copro insn lengths must total 64 bits.");
707 as_bad ("vliw group must consist of 1 core and 1 copro insn.");
711 /* If we arrive here, we have one saved instruction. There are a
712 number of possible cases:
714 1. The instruction is a 64 bit coprocessor insn and can be
715 executed by itself. Valid.
717 2. The instrucion is a core instruction for which a cop nop
718 exists. In this case, insert the cop nop into the saved
719 insn array after the core insn and return. Valid.
721 3. The instruction is a coprocessor insn for which a core nop
722 exists. In this case, move the coprocessor insn to the
723 second element of the array and put the nop in the first
724 element then return. Valid.
726 4. The instruction is a core or coprocessor instruction for
727 which there is no matching coprocessor or core nop to use
728 to form a valid vliw insn combination. In this case, we
731 /* If the insn is 64 bits long, it can run alone. The size check
732 is done indepependantly of whether the insn is core or copro
733 in case 64 bit coprocessor insns are added later. */
734 if (insn0length
== 64)
737 /* Insn is smaller than datapath. If there are no matching
738 nops for this insn, then terminate assembly. */
739 if (CGEN_INSN_ATTR_VALUE (saved_insns
[0].insn
,
740 CGEN_INSN_VLIW64_NO_MATCHING_NOP
))
741 as_fatal ("No valid nop.");
749 /* Initialize the insn buffer. */
750 for (i
= 0; i
< 64; i
++)
751 insn
.buffer
[i
] = '\0';
753 /* We have a coprocessor insn. At this point in time there
754 are is 32-bit core nop. There is only a 16-bit core
755 nop. The idea is to allow for a relatively arbitrary
756 coprocessor to be specified. We aren't looking at
757 trying to cover future changes in the core at this time
758 since it is assumed that the core will remain fairly
759 static. If there ever are 32 or 48 bit core nops added,
760 they will require entries below. */
762 if (insn0length
== 48)
764 /* Move the insn and fixups to the second element of the
765 arrays then assemble and insert a 16 bit core nop. */
766 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "nop",
767 & insn
.fields
, insn
.buffer
,
772 /* If this is reached, then we have a single coprocessor
773 insn that is not 48 bits long, but for which the assembler
774 thinks there is a matching core nop. If a 32-bit core
775 nop has been added, then make the necessary changes and
776 handle its assembly and insertion here. Otherwise,
777 go figure out why either:
779 1. The assembler thinks that there is a 32-bit core nop
780 to match a 32-bit coprocessor insn, or
781 2. The assembler thinks that there is a 48-bit core nop
782 to match a 16-bit coprocessor insn. */
784 as_fatal ("Assembler expects a non-existent core nop.");
789 as_bad ("%s", errmsg
);
793 /* Move the insn in element 0 to element 1 and insert the
794 nop into element 0. Move the fixups in element 0 to
795 element 1 and save the current fixups to element 0.
796 Really there aren't any fixups at this point because we're
797 inserting a nop but we might as well be general so that
798 if there's ever a need to insert a general insn, we'll
801 saved_insns
[1] = saved_insns
[0];
802 saved_insns
[0] = insn
;
804 gas_cgen_swap_fixups(0);
805 gas_cgen_save_fixups(1);
814 /* Initialize the insn buffer */
815 for (i
= 0; i
< 64; i
++)
816 insn
.buffer
[i
] = '\0';
818 /* We have a core insn. We have to handle all possible nop
819 lengths. If a coprocessor doesn't have a nop of a certain
820 length but there exists core insns that when combined with
821 a nop of that length would fill the datapath, those core
822 insns will be flagged with the VLIW_NO_CORRESPONDING_NOP
823 attribute. That will ensure that when used in a way that
824 requires a nop to be inserted, assembly will terminate
825 before reaching this section of code. This guarantees
826 that cases below which would result in the attempted
827 insertion of nop that doesn't exist will never be entered. */
828 if (insn0length
== 16)
830 /* Insert 48 bit coprocessor nop. */
831 /* Assemble it and put it into the arrays. */
832 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop48",
833 &insn
.fields
, insn
.buffer
,
836 else if (insn0length
== 32)
838 /* Insert 32 bit coprocessor nop. */
839 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop32",
840 &insn
.fields
, insn
.buffer
,
843 else if (insn0length
== 48)
845 /* Insert 16 bit coprocessor nop. */
846 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, "cpnop16",
847 &insn
.fields
, insn
.buffer
,
851 /* Core insn has an invalid length. Something has gone wrong. */
852 as_fatal ("Core insn has invalid length! Something is wrong!");
856 as_bad ("%s", errmsg
);
860 /* Now put the insn and fixups into the arrays. */
861 mep_save_insn (insn
);
866 /* The scheduling functions are just filters for invalid combinations.
867 If there is a violation, they terminate assembly. Otherise they
868 just fall through. Succesful combinations cause no side effects
869 other than valid nop insertion. */
872 mep_check_parallel_scheduling (void)
874 /* This is where we will eventually read the config information
875 and choose which scheduling checking function to call. */
877 mep_check_parallel64_scheduling ();
879 mep_check_parallel32_scheduling ();
883 mep_process_saved_insns (void)
887 gas_cgen_save_fixups (MAX_SAVED_FIXUP_CHAINS
- 1);
889 /* We have to check for valid scheduling here. */
890 mep_check_parallel_scheduling ();
892 /* If the last call didn't cause assembly to terminate, we have
893 a valid vliw insn/insn pair saved. Restore this instructions'
894 fixups and process the insns. */
895 for (i
= 0;i
<num_insns_saved
;i
++)
897 gas_cgen_restore_fixups (i
);
898 gas_cgen_finish_insn (saved_insns
[i
].insn
, saved_insns
[i
].buffer
,
899 CGEN_FIELDS_BITSIZE (& saved_insns
[i
].fields
),
902 gas_cgen_restore_fixups (MAX_SAVED_FIXUP_CHAINS
- 1);
904 /* Clear the fixups and reset the number insn saved to 0. */
905 gas_cgen_initialize_saved_fixups_array ();
907 listing_prev_line ();
911 md_assemble (char * str
)
913 static CGEN_BITSET
* isas
= NULL
;
916 /* Initialize GAS's cgen interface for a new instruction. */
917 gas_cgen_init_parse ();
919 /* There are two possible modes: core and vliw. We have to assemble
920 differently for each.
922 Core Mode: We assemble normally. All instructions are on a
923 single line and are made up of one mnemonic and one
925 VLIW Mode: Vliw combinations are indicated as follows:
930 We want to handle the general case where more than
931 one instruction can be preceeded by a +. This will
932 happen later if we add support for internally parallel
933 coprocessors. We'll make the parsing nice and general
934 so that it can handle an arbitrary number of insns
935 with leading +'s. The actual checking for valid
936 combinations is done elsewhere. */
938 /* Initialize the isa to refer to the core. */
940 isas
= cgen_bitset_copy (& MEP_CORE_ISA
);
943 cgen_bitset_clear (isas
);
944 cgen_bitset_union (isas
, & MEP_CORE_ISA
, isas
);
946 gas_cgen_cpu_desc
->isas
= isas
;
952 int thisInsnIsCopro
= 0;
956 /* Initialize the insn buffer */
958 if (! CGEN_INT_INSN_P
)
959 for (i
=0; i
< CGEN_MAX_INSN_SIZE
; i
++)
962 /* Can't tell core / copro insns apart at parse time! */
963 cgen_bitset_union (isas
, & MEP_COP_ISA
, isas
);
965 /* Assemble the insn so we can examine its attributes. */
966 insn
.insn
= mep_cgen_assemble_insn (gas_cgen_cpu_desc
, str
,
967 &insn
.fields
, insn
.buffer
,
971 as_bad ("%s", errmsg
);
974 mep_check_for_disabled_registers (&insn
);
976 /* Check to see if it's a coprocessor instruction. */
977 thisInsnIsCopro
= MEP_INSN_COP_P (insn
.insn
);
979 if (!thisInsnIsCopro
)
981 insn
.insn
= mep_cgen_assemble_cop_insn (gas_cgen_cpu_desc
, str
,
982 &insn
.fields
, insn
.buffer
,
984 thisInsnIsCopro
= MEP_INSN_COP_P (insn
.insn
);
985 mep_check_for_disabled_registers (&insn
);
990 /* A plus was present. */
991 /* Check for a + with a core insn and abort if found. */
992 if (!thisInsnIsCopro
)
994 as_fatal("A core insn cannot be preceeded by a +.\n");
998 if (num_insns_saved
> 0)
1000 /* There are insns in the queue. Add this one. */
1001 mep_save_insn (insn
);
1005 /* There are no insns in the queue and a plus is present.
1006 This is a syntax error. Let's not tolerate this.
1007 We can relax this later if necessary. */
1008 as_bad (_("Invalid use of parallelization operator."));
1014 /* No plus was present. */
1015 if (num_insns_saved
> 0)
1017 /* There are insns saved and we came across an insn without a
1018 leading +. That's the signal to process the saved insns
1019 before proceeding then treat the current insn as the first
1020 in a new vliw group. */
1021 mep_process_saved_insns ();
1022 num_insns_saved
= 0;
1023 /* mep_save_insn (insn); */
1025 mep_save_insn (insn
);
1030 /* Core Insn. Add it to the beginning of the queue. */
1031 mep_save_insn (insn
);
1032 /* gas_cgen_save_fixups(num_insns_saved); */
1043 /* Only single instructions are assembled in core mode. */
1046 /* If a leading '+' was present, issue an error.
1047 That's not allowed in core mode. */
1050 as_bad (_("Leading plus sign not allowed in core mode"));
1054 insn
.insn
= mep_cgen_assemble_insn
1055 (gas_cgen_cpu_desc
, str
, & insn
.fields
, insn
.buffer
, & errmsg
);
1059 as_bad ("%s", errmsg
);
1062 gas_cgen_finish_insn (insn
.insn
, insn
.buffer
,
1063 CGEN_FIELDS_BITSIZE (& insn
.fields
), 1, NULL
);
1064 mep_check_for_disabled_registers (&insn
);
1069 md_section_align (segT segment
, valueT size
)
1071 int align
= bfd_get_section_alignment (stdoutput
, segment
);
1072 return ((size
+ (1 << align
) - 1) & (-1 << align
));
1077 md_undefined_symbol (char *name ATTRIBUTE_UNUSED
)
1082 /* Interface to relax_segment. */
1085 const relax_typeS md_relax_table
[] =
1088 1) most positive reach of this state,
1089 2) most negative reach of this state,
1090 3) how many bytes this mode will have in the variable part of the frag
1091 4) which index into the table to try if we can't fit into this one. */
1092 /* Note that we use "beq" because "jmp" has a peculiarity - it cannot
1093 jump to addresses with any bits 27..24 set. So, we use beq as a
1094 17-bit pc-relative branch to avoid using jmp, just in case. */
1096 /* 0 */ { 0, 0, 0, 0 }, /* unused */
1097 /* 1 */ { 0, 0, 0, 0 }, /* marker for "don't know yet" */
1099 /* 2 */ { 2047, -2048, 0, 3 }, /* bsr12 */
1100 /* 3 */ { 0, 0, 2, 0 }, /* bsr16 */
1102 /* 4 */ { 2047, -2048, 0, 5 }, /* bra */
1103 /* 5 */ { 65535, -65536, 2, 6 }, /* beq $0,$0 */
1104 /* 6 */ { 0, 0, 2, 0 }, /* jmp24 */
1106 /* 7 */ { 65535, -65536, 0, 8 }, /* beqi */
1107 /* 8 */ { 0, 0, 4, 0 }, /* bnei/jmp */
1109 /* 9 */ { 127, -128, 0, 10 }, /* beqz */
1110 /* 10 */ { 65535, -65536, 2, 11 }, /* beqi */
1111 /* 11 */ { 0, 0, 4, 0 }, /* bnei/jmp */
1113 /* 12 */ { 65535, -65536, 0, 13 }, /* bnei */
1114 /* 13 */ { 0, 0, 4, 0 }, /* beqi/jmp */
1116 /* 14 */ { 127, -128, 0, 15 }, /* bnez */
1117 /* 15 */ { 65535, -65536, 2, 16 }, /* bnei */
1118 /* 16 */ { 0, 0, 4, 0 }, /* beqi/jmp */
1120 /* 17 */ { 65535, -65536, 0, 13 }, /* bgei */
1121 /* 18 */ { 0, 0, 4, 0 },
1122 /* 19 */ { 65535, -65536, 0, 13 }, /* blti */
1123 /* 20 */ { 0, 0, 4, 0 },
1124 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpeq */
1125 /* 20 */ { 0, 0, 4, 0 },
1126 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpne */
1127 /* 20 */ { 0, 0, 4, 0 },
1128 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpat */
1129 /* 20 */ { 0, 0, 4, 0 },
1130 /* 19 */ { 65535, -65536, 0, 13 }, /* bcpaf */
1131 /* 20 */ { 0, 0, 4, 0 }
1134 /* Pseudo-values for 64 bit "insns" which are combinations of two 32
1138 MEP_PSEUDO64_16BITCC
,
1139 MEP_PSEUDO64_32BITCC
,
1140 } MepPseudo64Values
;
1145 int insn_for_extern
;
1146 } subtype_mappings
[] = {
1149 { MEP_INSN_BSR12
, 0, MEP_INSN_BSR24
},
1150 { MEP_INSN_BSR24
, 2, MEP_INSN_BSR24
},
1151 { MEP_INSN_BRA
, 0, MEP_INSN_BRA
},
1152 { MEP_INSN_BEQ
, 2, MEP_INSN_BEQ
},
1153 { MEP_INSN_JMP
, 2, MEP_INSN_JMP
},
1154 { MEP_INSN_BEQI
, 0, MEP_INSN_BEQI
},
1155 { -1, 4, MEP_PSEUDO64_32BITCC
},
1156 { MEP_INSN_BEQZ
, 0, MEP_INSN_BEQZ
},
1157 { MEP_INSN_BEQI
, 2, MEP_INSN_BEQI
},
1158 { -1, 4, MEP_PSEUDO64_16BITCC
},
1159 { MEP_INSN_BNEI
, 0, MEP_INSN_BNEI
},
1160 { -1, 4, MEP_PSEUDO64_32BITCC
},
1161 { MEP_INSN_BNEZ
, 0, MEP_INSN_BNEZ
},
1162 { MEP_INSN_BNEI
, 2, MEP_INSN_BNEI
},
1163 { -1, 4, MEP_PSEUDO64_16BITCC
},
1164 { MEP_INSN_BGEI
, 0, MEP_INSN_BGEI
},
1165 { -1, 4, MEP_PSEUDO64_32BITCC
},
1166 { MEP_INSN_BLTI
, 0, MEP_INSN_BLTI
},
1167 { -1, 4, MEP_PSEUDO64_32BITCC
},
1168 { MEP_INSN_BCPEQ
, 0, MEP_INSN_BCPEQ
},
1169 { -1, 4, MEP_PSEUDO64_32BITCC
},
1170 { MEP_INSN_BCPNE
, 0, MEP_INSN_BCPNE
},
1171 { -1, 4, MEP_PSEUDO64_32BITCC
},
1172 { MEP_INSN_BCPAT
, 0, MEP_INSN_BCPAT
},
1173 { -1, 4, MEP_PSEUDO64_32BITCC
},
1174 { MEP_INSN_BCPAF
, 0, MEP_INSN_BCPAF
},
1175 { -1, 4, MEP_PSEUDO64_32BITCC
}
1177 #define NUM_MAPPINGS (sizeof (subtype_mappings) / sizeof (subtype_mappings[0]))
1180 mep_prepare_relax_scan (fragS
*fragP
, offsetT
*aim
, relax_substateT this_state
)
1182 symbolS
*symbolP
= fragP
->fr_symbol
;
1183 if (symbolP
&& !S_IS_DEFINED (symbolP
))
1185 /* Adjust for MeP pcrel not being relative to the next opcode. */
1186 *aim
+= 2 + md_relax_table
[this_state
].rlx_length
;
1190 insn_to_subtype (int insn
)
1193 for (i
=0; i
<NUM_MAPPINGS
; i
++)
1194 if (insn
== subtype_mappings
[i
].insn
)
1199 /* Return an initial guess of the length by which a fragment must grow
1200 to hold a branch to reach its destination. Also updates fr_type
1201 and fr_subtype as necessary.
1203 Called just before doing relaxation. Any symbol that is now
1204 undefined will not become defined. The guess for fr_var is
1205 ACTUALLY the growth beyond fr_fix. Whatever we do to grow fr_fix
1206 or fr_var contributes to our returned value. Although it may not
1207 be explicit in the frag, pretend fr_var starts with a 0 value. */
1210 md_estimate_size_before_relax (fragS
* fragP
, segT segment
)
1212 if (fragP
->fr_subtype
== 1)
1213 fragP
->fr_subtype
= insn_to_subtype (fragP
->fr_cgen
.insn
->base
->num
);
1215 if (S_GET_SEGMENT (fragP
->fr_symbol
) != segment
)
1219 new_insn
= subtype_mappings
[fragP
->fr_subtype
].insn_for_extern
;
1220 fragP
->fr_subtype
= insn_to_subtype (new_insn
);
1223 if (MEP_VLIW
&& ! MEP_VLIW64
1224 && (bfd_get_section_flags (stdoutput
, segment
) & SEC_MEP_VLIW
))
1226 /* Use 32 bit branches for vliw32 so the vliw word is not split. */
1227 switch (fragP
->fr_cgen
.insn
->base
->num
)
1229 case MEP_INSN_BSR12
:
1230 fragP
->fr_subtype
= insn_to_subtype
1231 (subtype_mappings
[fragP
->fr_subtype
].insn_for_extern
);
1234 fragP
->fr_subtype
++;
1237 fragP
->fr_subtype
++;
1242 if (fragP
->fr_cgen
.insn
->base
1243 && fragP
->fr_cgen
.insn
->base
->num
1244 != subtype_mappings
[fragP
->fr_subtype
].insn
)
1246 int new_insn
= subtype_mappings
[fragP
->fr_subtype
].insn
;
1249 fragP
->fr_cgen
.insn
= (fragP
->fr_cgen
.insn
1250 - fragP
->fr_cgen
.insn
->base
->num
1255 return subtype_mappings
[fragP
->fr_subtype
].growth
;
1258 /* *fragP has been relaxed to its final size, and now needs to have
1259 the bytes inside it modified to conform to the new size.
1261 Called after relaxation is finished.
1262 fragP->fr_type == rs_machine_dependent.
1263 fragP->fr_subtype is the subtype of what the address relaxed to. */
1266 target_address_for (fragS
*frag
)
1268 int rv
= frag
->fr_offset
;
1269 symbolS
*sym
= frag
->fr_symbol
;
1272 rv
+= S_GET_VALUE (sym
);
1278 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
,
1279 segT sec ATTRIBUTE_UNUSED
,
1282 int addend
, rn
, bit
= 0;
1284 int where
= fragP
->fr_opcode
- fragP
->fr_literal
;
1285 int e
= target_big_endian
? 0 : 1;
1287 addend
= target_address_for (fragP
) - (fragP
->fr_address
+ where
);
1289 if (subtype_mappings
[fragP
->fr_subtype
].insn
== -1)
1291 fragP
->fr_fix
+= subtype_mappings
[fragP
->fr_subtype
].growth
;
1292 switch (subtype_mappings
[fragP
->fr_subtype
].insn_for_extern
)
1294 case MEP_PSEUDO64_16BITCC
:
1295 fragP
->fr_opcode
[1^e
] = ((fragP
->fr_opcode
[1^e
] & 1) ^ 1) | 0x06;
1296 fragP
->fr_opcode
[2^e
] = 0xd8;
1297 fragP
->fr_opcode
[3^e
] = 0x08;
1298 fragP
->fr_opcode
[4^e
] = 0;
1299 fragP
->fr_opcode
[5^e
] = 0;
1302 case MEP_PSEUDO64_32BITCC
:
1303 if (fragP
->fr_opcode
[0^e
] & 0x10)
1304 fragP
->fr_opcode
[1^e
] ^= 0x01;
1306 fragP
->fr_opcode
[1^e
] ^= 0x04;
1307 fragP
->fr_opcode
[2^e
] = 0;
1308 fragP
->fr_opcode
[3^e
] = 4;
1309 fragP
->fr_opcode
[4^e
] = 0xd8;
1310 fragP
->fr_opcode
[5^e
] = 0x08;
1311 fragP
->fr_opcode
[6^e
] = 0;
1312 fragP
->fr_opcode
[7^e
] = 0;
1318 fragP
->fr_cgen
.insn
= (fragP
->fr_cgen
.insn
1319 - fragP
->fr_cgen
.insn
->base
->num
1321 operand
= MEP_OPERAND_PCABS24A2
;
1324 switch (fragP
->fr_cgen
.insn
->base
->num
)
1326 case MEP_INSN_BSR12
:
1327 fragP
->fr_opcode
[0^e
] = 0xb0 | ((addend
>> 8) & 0x0f);
1328 fragP
->fr_opcode
[1^e
] = 0x01 | (addend
& 0xfe);
1329 operand
= MEP_OPERAND_PCREL12A2
;
1332 case MEP_INSN_BSR24
:
1334 fragP
->fr_opcode
[0^e
] = 0xd8 | ((addend
>> 5) & 0x07);
1335 fragP
->fr_opcode
[1^e
] = 0x09 | ((addend
<< 3) & 0xf0);
1336 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>>16) & 0xff);
1337 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 8) & 0xff);
1338 operand
= MEP_OPERAND_PCREL24A2
;
1342 fragP
->fr_opcode
[0^e
] = 0xb0 | ((addend
>> 8) & 0x0f);
1343 fragP
->fr_opcode
[1^e
] = 0x00 | (addend
& 0xfe);
1344 operand
= MEP_OPERAND_PCREL12A2
;
1348 /* The default relax_frag doesn't change the state if there is no
1349 growth, so we must manually handle converting out-of-range BEQ
1350 instructions to JMP. */
1351 if (addend
<= 65535 && addend
>= -65536)
1354 fragP
->fr_opcode
[0^e
] = 0xe0;
1355 fragP
->fr_opcode
[1^e
] = 0x01;
1356 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>> 9) & 0xff);
1357 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 1) & 0xff);
1358 operand
= MEP_OPERAND_PCREL17A2
;
1361 /* ...FALLTHROUGH... */
1364 addend
= target_address_for (fragP
);
1366 fragP
->fr_opcode
[0^e
] = 0xd8 | ((addend
>> 5) & 0x07);
1367 fragP
->fr_opcode
[1^e
] = 0x08 | ((addend
<< 3) & 0xf0);
1368 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>>16) & 0xff);
1369 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 8) & 0xff);
1370 operand
= MEP_OPERAND_PCABS24A2
;
1376 fragP
->fr_opcode
[1^e
] = bit
| (addend
& 0xfe);
1377 operand
= MEP_OPERAND_PCREL8A2
;
1383 if (subtype_mappings
[fragP
->fr_subtype
].growth
)
1385 fragP
->fr_fix
+= subtype_mappings
[fragP
->fr_subtype
].growth
;
1386 rn
= fragP
->fr_opcode
[0^e
] & 0x0f;
1387 fragP
->fr_opcode
[0^e
] = 0xe0 | rn
;
1388 fragP
->fr_opcode
[1^e
] = bit
;
1390 fragP
->fr_opcode
[2^e
] = 0x00 | ((addend
>> 9) & 0xff);
1391 fragP
->fr_opcode
[3^e
] = 0x00 | ((addend
>> 1) & 0xff);
1392 operand
= MEP_OPERAND_PCREL17A2
;
1397 case MEP_INSN_BCPEQ
:
1398 case MEP_INSN_BCPNE
:
1399 case MEP_INSN_BCPAT
:
1400 case MEP_INSN_BCPAF
:
1401 /* No opcode change needed, just operand. */
1402 fragP
->fr_opcode
[2^e
] = (addend
>> 9) & 0xff;
1403 fragP
->fr_opcode
[3^e
] = (addend
>> 1) & 0xff;
1404 operand
= MEP_OPERAND_PCREL17A2
;
1411 if (S_GET_SEGMENT (fragP
->fr_symbol
) != sec
1412 || operand
== MEP_OPERAND_PCABS24A2
)
1414 assert (fragP
->fr_cgen
.insn
!= 0);
1415 gas_cgen_record_fixup (fragP
,
1417 fragP
->fr_cgen
.insn
,
1418 (fragP
->fr_fix
- where
) * 8,
1419 cgen_operand_lookup_by_num (gas_cgen_cpu_desc
,
1421 fragP
->fr_cgen
.opinfo
,
1422 fragP
->fr_symbol
, fragP
->fr_offset
);
1427 /* Functions concerning relocs. */
1430 mep_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
1432 /* If we already know the fixup value, adjust it in the same
1433 way that the linker would have done. */
1434 if (fixP
->fx_addsy
== 0)
1435 switch (fixP
->fx_cgen
.opinfo
)
1437 case BFD_RELOC_MEP_LOW16
:
1438 *valP
= ((long)(*valP
& 0xffff)) << 16 >> 16;
1440 case BFD_RELOC_MEP_HI16U
:
1443 case BFD_RELOC_MEP_HI16S
:
1444 *valP
= (*valP
+ 0x8000) >> 16;
1448 /* Now call cgen's md_aply_fix. */
1449 gas_cgen_md_apply_fix (fixP
, valP
, seg
);
1453 md_pcrel_from_section (fixS
*fixP
, segT sec
)
1455 if (fixP
->fx_addsy
!= (symbolS
*) NULL
1456 && (! S_IS_DEFINED (fixP
->fx_addsy
)
1457 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
1458 /* The symbol is undefined (or is defined but not in this section).
1459 Let the linker figure it out. */
1462 /* Return the address of the opcode - cgen adjusts for opcode size
1463 itself, to be consistent with the disassembler, which must do
1465 return fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1468 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
1469 Returns BFD_RELOC_NONE if no reloc type can be found.
1470 *FIXP may be modified if desired. */
1472 #if defined (__STDC__) || defined (ALMOST_STDC) || defined (HAVE_STRINGIZE)
1473 #define MAP(n) case MEP_OPERAND_##n: return BFD_RELOC_MEP_##n;
1475 #define MAP(n) case MEP_OPERAND_/**/n: return BFD_RELOC_MEP_/**/n;
1478 bfd_reloc_code_real_type
1479 md_cgen_lookup_reloc (const CGEN_INSN
*insn ATTRIBUTE_UNUSED
,
1480 const CGEN_OPERAND
*operand
,
1483 enum bfd_reloc_code_real reloc
= fixP
->fx_cgen
.opinfo
;
1484 static char printed
[MEP_OPERAND_MAX
] = { 0 };
1486 /* If there's a reloc here, it's because the parser saw a %foo() and
1487 is giving us the correct reloc to use, or because we converted to
1488 a different size reloc below and want to avoid "converting" more
1490 if (reloc
&& reloc
!= BFD_RELOC_NONE
)
1493 switch (operand
->type
)
1495 MAP (PCREL8A2
); /* beqz */
1496 MAP (PCREL12A2
); /* bsr16 */
1497 MAP (PCREL17A2
); /* beqi */
1498 MAP (PCREL24A2
); /* bsr24 */
1499 MAP (PCABS24A2
); /* jmp */
1500 MAP (UIMM24
); /* mov */
1501 MAP (ADDR24A4
); /* sw/lw */
1503 /* The rest of the relocs should be generated by the parser,
1504 for things such as %tprel(), etc. */
1505 case MEP_OPERAND_SIMM16
:
1506 #ifdef OBJ_COMPLEX_RELC
1507 /* coalescing this into RELOC_MEP_16 is actually a bug,
1508 since it's a signed operand. let the relc code handle it. */
1509 return BFD_RELOC_RELC
;
1512 case MEP_OPERAND_UIMM16
:
1513 case MEP_OPERAND_SDISP16
:
1514 case MEP_OPERAND_CODE16
:
1515 fixP
->fx_where
+= 2;
1516 /* to avoid doing the above add twice */
1517 fixP
->fx_cgen
.opinfo
= BFD_RELOC_MEP_16
;
1518 return BFD_RELOC_MEP_16
;
1521 #ifdef OBJ_COMPLEX_RELC
1522 /* this is not an error, yet.
1523 pass it to the linker. */
1524 return BFD_RELOC_RELC
;
1526 if (printed
[operand
->type
])
1527 return BFD_RELOC_NONE
;
1528 printed
[operand
->type
] = 1;
1530 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1531 _("Don't know how to relocate plain operands of type %s"),
1534 /* Print some helpful hints for the user. */
1535 switch (operand
->type
)
1537 case MEP_OPERAND_UDISP7
:
1538 case MEP_OPERAND_UDISP7A2
:
1539 case MEP_OPERAND_UDISP7A4
:
1540 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1541 _("Perhaps you are missing %%tpoff()?"));
1546 return BFD_RELOC_NONE
;
1550 /* Called while parsing an instruction to create a fixup.
1551 We need to check for HI16 relocs and queue them up for later sorting. */
1554 mep_cgen_record_fixup_exp (fragS
*frag
,
1556 const CGEN_INSN
*insn
,
1558 const CGEN_OPERAND
*operand
,
1562 fixS
* fixP
= gas_cgen_record_fixup_exp (frag
, where
, insn
, length
,
1563 operand
, opinfo
, exp
);
1567 /* Return BFD reloc type from opinfo field in a fixS.
1568 It's tricky using fx_r_type in mep_frob_file because the values
1569 are BFD_RELOC_UNUSED + operand number. */
1570 #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
1572 /* Sort any unmatched HI16 relocs so that they immediately precede
1573 the corresponding LO16 reloc. This is called before md_apply_fix and
1579 struct mep_hi_fixup
* l
;
1581 for (l
= mep_hi_fixup_list
; l
!= NULL
; l
= l
->next
)
1583 segment_info_type
* seginfo
;
1586 assert (FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_HI16
1587 || FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_LO16
);
1589 /* Check quickly whether the next fixup happens to be a matching low. */
1590 if (l
->fixp
->fx_next
!= NULL
1591 && FX_OPINFO_R_TYPE (l
->fixp
->fx_next
) == BFD_RELOC_LO16
1592 && l
->fixp
->fx_addsy
== l
->fixp
->fx_next
->fx_addsy
1593 && l
->fixp
->fx_offset
== l
->fixp
->fx_next
->fx_offset
)
1596 /* Look through the fixups for this segment for a matching
1597 `low'. When we find one, move the high just in front of it.
1598 We do this in two passes. In the first pass, we try to find
1599 a unique `low'. In the second pass, we permit multiple
1600 high's relocs for a single `low'. */
1601 seginfo
= seg_info (l
->seg
);
1602 for (pass
= 0; pass
< 2; pass
++)
1608 for (f
= seginfo
->fix_root
; f
!= NULL
; f
= f
->fx_next
)
1610 /* Check whether this is a `low' fixup which matches l->fixp. */
1611 if (FX_OPINFO_R_TYPE (f
) == BFD_RELOC_LO16
1612 && f
->fx_addsy
== l
->fixp
->fx_addsy
1613 && f
->fx_offset
== l
->fixp
->fx_offset
1616 || (FX_OPINFO_R_TYPE (prev
) != BFD_RELOC_HI16
)
1617 || prev
->fx_addsy
!= f
->fx_addsy
1618 || prev
->fx_offset
!= f
->fx_offset
))
1622 /* Move l->fixp before f. */
1623 for (pf
= &seginfo
->fix_root
;
1625 pf
= & (* pf
)->fx_next
)
1626 assert (* pf
!= NULL
);
1628 * pf
= l
->fixp
->fx_next
;
1630 l
->fixp
->fx_next
= f
;
1632 seginfo
->fix_root
= l
->fixp
;
1634 prev
->fx_next
= l
->fixp
;
1646 as_warn_where (l
->fixp
->fx_file
, l
->fixp
->fx_line
,
1647 _("Unmatched high relocation"));
1652 /* See whether we need to force a relocation into the output file. */
1655 mep_force_relocation (fixS
*fixp
)
1657 if ( fixp
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
1658 || fixp
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
1661 /* Allow branches to global symbols to be resolved at assembly time.
1662 This is consistent with way relaxable branches are handled, since
1663 branches to both global and local symbols are relaxed. It also
1664 corresponds to the assumptions made in md_pcrel_from_section. */
1665 return S_FORCE_RELOC (fixp
->fx_addsy
, !fixp
->fx_pcrel
);
1668 /* Write a value out to the object file, using the appropriate endianness. */
1671 md_number_to_chars (char *buf
, valueT val
, int n
)
1673 if (target_big_endian
)
1674 number_to_chars_bigendian (buf
, val
, n
);
1676 number_to_chars_littleendian (buf
, val
, n
);
1679 /* Turn a string in input_line_pointer into a floating point constant
1680 of type type, and store the appropriate bytes in *litP. The number
1681 of LITTLENUMS emitted is stored in *sizeP . An error message is
1682 returned, or NULL on OK. */
1684 /* Equal to MAX_PRECISION in atof-ieee.c */
1685 #define MAX_LITTLENUMS 6
1688 md_atof (int type
, char *litP
, int *sizeP
)
1692 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
1711 /* FIXME: Some targets allow other format chars for bigger sizes here. */
1714 return _("Bad call to md_atof()");
1717 t
= atof_ieee (input_line_pointer
, type
, words
);
1719 input_line_pointer
= t
;
1720 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
1722 for (i
= 0; i
< prec
; i
++)
1724 md_number_to_chars (litP
, (valueT
) words
[i
],
1725 sizeof (LITTLENUM_TYPE
));
1726 litP
+= sizeof (LITTLENUM_TYPE
);
1734 mep_fix_adjustable (fixS
*fixP
)
1736 bfd_reloc_code_real_type reloc_type
;
1738 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
1740 const CGEN_INSN
*insn
= NULL
;
1741 int opindex
= (int) fixP
->fx_r_type
- (int) BFD_RELOC_UNUSED
;
1742 const CGEN_OPERAND
*operand
1743 = cgen_operand_lookup_by_num(gas_cgen_cpu_desc
, opindex
);
1744 reloc_type
= md_cgen_lookup_reloc (insn
, operand
, fixP
);
1747 reloc_type
= fixP
->fx_r_type
;
1749 if (fixP
->fx_addsy
== NULL
)
1752 /* Prevent all adjustments to global symbols. */
1753 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
1756 if (S_IS_WEAK (fixP
->fx_addsy
))
1759 /* We need the symbol name for the VTABLE entries */
1760 if (reloc_type
== BFD_RELOC_VTABLE_INHERIT
1761 || reloc_type
== BFD_RELOC_VTABLE_ENTRY
)
1768 mep_elf_section_letter (int letter
, char **ptrmsg
)
1771 return SHF_MEP_VLIW
;
1773 *ptrmsg
= _("Bad .section directive: want a,v,w,x,M,S in string");
1778 mep_elf_section_flags (flagword flags
, int attr
, int type ATTRIBUTE_UNUSED
)
1780 if (attr
& SHF_MEP_VLIW
)
1781 flags
|= SEC_MEP_VLIW
;
1785 /* In vliw mode, the default section is .vtext. We have to be able
1786 to switch into .vtext using only the .vtext directive. */
1789 mep_vtext_section (void)
1791 static segT vtext_section
;
1793 if (! vtext_section
)
1795 flagword applicable
= bfd_applicable_section_flags (stdoutput
);
1796 vtext_section
= subseg_new (VTEXT_SECTION_NAME
, 0);
1797 bfd_set_section_flags (stdoutput
, vtext_section
,
1798 applicable
& (SEC_ALLOC
| SEC_LOAD
| SEC_RELOC
1799 | SEC_CODE
| SEC_READONLY
1803 return vtext_section
;
1807 mep_s_vtext (int ignore ATTRIBUTE_UNUSED
)
1811 /* Record previous_section and previous_subsection. */
1812 obj_elf_section_change_hook ();
1814 temp
= get_absolute_expression ();
1815 subseg_set (mep_vtext_section (), (subsegT
) temp
);
1816 demand_empty_rest_of_line ();
1820 mep_switch_to_core_mode (int dummy ATTRIBUTE_UNUSED
)
1822 mep_process_saved_insns ();
1828 mep_switch_to_vliw_mode (int dummy ATTRIBUTE_UNUSED
)
1831 as_bad (_(".vliw unavailable when VLIW is disabled."));
1833 /* Switch into .vtext here too. */
1834 /* mep_s_vtext(); */
1837 /* This is an undocumented pseudo-op used to disable gas's
1838 "disabled_registers" check. Used for code which checks for those
1839 registers at runtime. */
1841 mep_noregerr (int i ATTRIBUTE_UNUSED
)
1843 allow_disabled_registers
= 1;
1846 /* mep_unrecognized_line: This is called when a line that can't be parsed
1847 is encountered. We use it to check for a leading '+' sign which indicates
1848 that the current instruction is a coprocessor instruction that is to be
1849 parallelized with a previous core insn. This function accepts the '+' and
1850 rejects all other characters that might indicate garbage at the beginning
1851 of the line. The '+' character gets lost as the calling loop continues,
1852 so we need to indicate that we saw it. */
1855 mep_unrecognized_line (int ch
)
1861 return 1; /* '+' indicates an instruction to be parallelized. */
1863 return 0; /* If it's not a '+', the line can't be parsed. */
1870 /* Take care of any insns left to be parallelized when the file ends.
1871 This is mainly here to handle the case where the file ends with an
1872 insn preceeded by a + or the file ends unexpectedly. */
1874 mep_process_saved_insns ();
1878 mep_flush_pending_output (void)
1882 mep_process_saved_insns ();