[PATCH 40/57][Arm][OBJDUMP] Add support for MVE instructions: vdup, veor, vfma, vfms...
[binutils-gdb.git] / gas / config / tc-iq2000.c
blob3275d301f7c8d4fdbb37fa67f37ad569fefe42e8
1 /* tc-iq2000.c -- Assembler for the Sitera IQ2000.
2 Copyright (C) 2003-2019 Free Software Foundation, Inc.
4 This file is part of GAS, the GNU Assembler.
6 GAS is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GAS is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GAS; see the file COPYING. If not, write to
18 the Free Software Foundation, 51 Franklin Street - Fifth Floor,
19 Boston, MA 02110-1301, USA. */
21 #include "as.h"
22 #include "safe-ctype.h"
23 #include "subsegs.h"
24 #include "symcat.h"
25 #include "opcodes/iq2000-desc.h"
26 #include "opcodes/iq2000-opc.h"
27 #include "cgen.h"
28 #include "elf/common.h"
29 #include "elf/iq2000.h"
30 #include "sb.h"
31 #include "macro.h"
33 /* Structure to hold all of the different components describing
34 an individual instruction. */
35 typedef struct
37 const CGEN_INSN * insn;
38 const CGEN_INSN * orig_insn;
39 CGEN_FIELDS fields;
40 #if CGEN_INT_INSN_P
41 CGEN_INSN_INT buffer [1];
42 #define INSN_VALUE(buf) (*(buf))
43 #else
44 unsigned char buffer [CGEN_MAX_INSN_SIZE];
45 #define INSN_VALUE(buf) (buf)
46 #endif
47 char * addr;
48 fragS * frag;
49 int num_fixups;
50 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
51 int indices [MAX_OPERAND_INSTANCES];
53 iq2000_insn;
55 const char comment_chars[] = "#";
56 const char line_comment_chars[] = "#";
57 const char line_separator_chars[] = ";";
58 const char EXP_CHARS[] = "eE";
59 const char FLT_CHARS[] = "dD";
61 /* Default machine. */
62 #define DEFAULT_MACHINE bfd_mach_iq2000
63 #define DEFAULT_FLAGS EF_IQ2000_CPU_IQ2000
65 static unsigned long iq2000_mach = bfd_mach_iq2000;
66 static int cpu_mach = (1 << MACH_IQ2000);
68 /* Flags to set in the elf header. */
69 static flagword iq2000_flags = DEFAULT_FLAGS;
71 typedef struct proc
73 symbolS *isym;
74 unsigned long reg_mask;
75 unsigned long reg_offset;
76 unsigned long fpreg_mask;
77 unsigned long fpreg_offset;
78 unsigned long frame_offset;
79 unsigned long frame_reg;
80 unsigned long pc_reg;
81 } procS;
83 static procS cur_proc;
84 static procS *cur_proc_ptr;
85 static int numprocs;
87 /* Relocations against symbols are done in two
88 parts, with a HI relocation and a LO relocation. Each relocation
89 has only 16 bits of space to store an addend. This means that in
90 order for the linker to handle carries correctly, it must be able
91 to locate both the HI and the LO relocation. This means that the
92 relocations must appear in order in the relocation table.
94 In order to implement this, we keep track of each unmatched HI
95 relocation. We then sort them so that they immediately precede the
96 corresponding LO relocation. */
98 struct iq2000_hi_fixup
100 struct iq2000_hi_fixup * next; /* Next HI fixup. */
101 fixS * fixp; /* This fixup. */
102 segT seg; /* The section this fixup is in. */
105 /* The list of unmatched HI relocs. */
106 static struct iq2000_hi_fixup * iq2000_hi_fixup_list;
108 /* Macro hash table, which we will add to. */
109 extern struct hash_control *macro_hash;
111 const char *md_shortopts = "";
112 struct option md_longopts[] =
114 {NULL, no_argument, NULL, 0}
116 size_t md_longopts_size = sizeof (md_longopts);
119 md_parse_option (int c ATTRIBUTE_UNUSED,
120 const char * arg ATTRIBUTE_UNUSED)
122 return 0;
125 void
126 md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
130 /* Automatically enter conditional branch macros. */
132 typedef struct
134 const char * mnemonic;
135 const char ** expansion;
136 const char ** args;
137 } iq2000_macro_defs_s;
139 static const char * abs_args[] = { "rd", "rs", "scratch=%1", NULL };
140 static const char * abs_expn = "\n sra \\rd,\\rs,31\n xor \\scratch,\\rd,\\rs\n sub \\rd,\\scratch,\\rd\n";
141 static const char * la_expn = "\n lui \\reg,%hi(\\label)\n ori \\reg,\\reg,%lo(\\label)\n";
142 static const char * la_args[] = { "reg", "label", NULL };
143 static const char * bxx_args[] = { "rs", "rt", "label", "scratch=%1", NULL };
144 static const char * bge_expn = "\n slt \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
145 static const char * bgeu_expn = "\n sltu \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
146 static const char * bgt_expn = "\n slt \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
147 static const char * bgtu_expn = "\n sltu \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
148 static const char * ble_expn = "\n slt \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
149 static const char * bleu_expn = "\n sltu \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
150 static const char * blt_expn = "\n slt \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
151 static const char * bltu_expn = "\n sltu \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
152 static const char * sxx_args[] = { "rd", "rs", "rt", NULL };
153 static const char * sge_expn = "\n slt \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
154 static const char * sgeu_expn = "\n sltu \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
155 static const char * sle_expn = "\n slt \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
156 static const char * sleu_expn = "\n sltu \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
157 static const char * sgt_expn = "\n slt \\rd,\\rt,\\rs\n";
158 static const char * sgtu_expn = "\n sltu \\rd,\\rt,\\rs\n";
159 static const char * sne_expn = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n";
160 static const char * seq_expn = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n xori \\rd,\\rd,1\n";
161 static const char * ai32_args[] = { "rt", "rs", "imm", NULL };
162 static const char * andi32_expn = "\n\
163 .if (\\imm & 0xffff0000 == 0xffff0000)\n\
164 andoi \\rt,\\rs,%lo(\\imm)\n\
165 .elseif (\\imm & 0x0000ffff == 0x0000ffff)\n\
166 andoui \\rt,\\rs,%uhi(\\imm)\n\
167 .elseif (\\imm & 0xffff0000 == 0x00000000)\n\
168 andi \\rt,\\rs,%lo(\\imm)\n\
169 .else\n\
170 andoui \\rt,\\rs,%uhi(\\imm)\n\
171 andoi \\rt,\\rt,%lo(\\imm)\n\
172 .endif\n";
173 static const char * ori32_expn = "\n\
174 .if (\\imm & 0xffff == 0)\n\
175 orui \\rt,\\rs,%uhi(\\imm)\n\
176 .elseif (\\imm & 0xffff0000 == 0)\n\
177 ori \\rt,\\rs,%lo(\\imm)\n\
178 .else\n\
179 orui \\rt,\\rs,%uhi(\\imm)\n\
180 ori \\rt,\\rt,%lo(\\imm)\n\
181 .endif\n";
183 static const char * neg_args[] = { "rd", "rs", NULL };
184 static const char * neg_expn = "\n sub \\rd,%0,\\rs\n";
185 static const char * negu_expn = "\n subu \\rd,%0,\\rs\n";
186 static const char * li_args[] = { "rt", "imm", NULL };
187 static const char * li_expn = "\n\
188 .if (\\imm & 0xffff0000 == 0x0)\n\
189 ori \\rt,%0,\\imm\n\
190 .elseif (\\imm & 0xffff0000 == 0xffff0000)\n\
191 addi \\rt,%0,\\imm\n\
192 .elseif (\\imm & 0x0000ffff == 0)\n\
193 lui \\rt,%uhi(\\imm)\n\
194 .else\n\
195 lui \\rt,%uhi(\\imm)\n\
196 ori \\rt,\\rt,%lo(\\imm)\n\
197 .endif\n";
199 static iq2000_macro_defs_s iq2000_macro_defs[] =
201 {"abs", (const char **) & abs_expn, (const char **) & abs_args},
202 {"la", (const char **) & la_expn, (const char **) & la_args},
203 {"bge", (const char **) & bge_expn, (const char **) & bxx_args},
204 {"bgeu", (const char **) & bgeu_expn, (const char **) & bxx_args},
205 {"bgt", (const char **) & bgt_expn, (const char **) & bxx_args},
206 {"bgtu", (const char **) & bgtu_expn, (const char **) & bxx_args},
207 {"ble", (const char **) & ble_expn, (const char **) & bxx_args},
208 {"bleu", (const char **) & bleu_expn, (const char **) & bxx_args},
209 {"blt", (const char **) & blt_expn, (const char **) & bxx_args},
210 {"bltu", (const char **) & bltu_expn, (const char **) & bxx_args},
211 {"sge", (const char **) & sge_expn, (const char **) & sxx_args},
212 {"sgeu", (const char **) & sgeu_expn, (const char **) & sxx_args},
213 {"sle", (const char **) & sle_expn, (const char **) & sxx_args},
214 {"sleu", (const char **) & sleu_expn, (const char **) & sxx_args},
215 {"sgt", (const char **) & sgt_expn, (const char **) & sxx_args},
216 {"sgtu", (const char **) & sgtu_expn, (const char **) & sxx_args},
217 {"seq", (const char **) & seq_expn, (const char **) & sxx_args},
218 {"sne", (const char **) & sne_expn, (const char **) & sxx_args},
219 {"neg", (const char **) & neg_expn, (const char **) & neg_args},
220 {"negu", (const char **) & negu_expn, (const char **) & neg_args},
221 {"li", (const char **) & li_expn, (const char **) & li_args},
222 {"ori32", (const char **) & ori32_expn, (const char **) & ai32_args},
223 {"andi32",(const char **) & andi32_expn,(const char **) & ai32_args},
226 static void
227 iq2000_add_macro (const char * name,
228 const char * semantics,
229 const char ** arguments)
231 macro_entry *macro;
232 sb macro_name;
233 const char *namestr;
235 macro = XNEW (macro_entry);
236 sb_new (& macro->sub);
237 sb_new (& macro_name);
239 macro->formal_count = 0;
240 macro->formals = 0;
242 sb_add_string (& macro->sub, semantics);
244 if (arguments != NULL)
246 formal_entry ** p = &macro->formals;
248 macro->formal_count = 0;
249 macro->formal_hash = hash_new ();
251 while (*arguments != NULL)
253 formal_entry *formal;
255 formal = XNEW (formal_entry);
257 sb_new (& formal->name);
258 sb_new (& formal->def);
259 sb_new (& formal->actual);
261 /* chlm: Added the following to allow defaulted args. */
262 if (strchr (*arguments,'='))
264 char * tt_args = strdup (*arguments);
265 char * tt_dflt = strchr (tt_args,'=');
267 *tt_dflt = 0;
268 sb_add_string (& formal->name, tt_args);
269 sb_add_string (& formal->def, tt_dflt + 1);
271 else
272 sb_add_string (& formal->name, *arguments);
274 /* Add to macro's hash table. */
275 hash_jam (macro->formal_hash, sb_terminate (& formal->name), formal);
277 formal->index = macro->formal_count;
278 macro->formal_count++;
279 *p = formal;
280 p = & formal->next;
281 *p = NULL;
282 ++arguments;
286 sb_add_string (&macro_name, name);
287 namestr = sb_terminate (&macro_name);
288 hash_jam (macro_hash, namestr, macro);
290 macro_defined = 1;
293 static void
294 iq2000_load_macros (void)
296 int i;
297 int mcnt = ARRAY_SIZE (iq2000_macro_defs);
299 for (i = 0; i < mcnt; i++)
300 iq2000_add_macro (iq2000_macro_defs[i].mnemonic,
301 *iq2000_macro_defs[i].expansion,
302 iq2000_macro_defs[i].args);
305 void
306 md_begin (void)
308 /* Initialize the `cgen' interface. */
310 /* Set the machine number and endian. */
311 gas_cgen_cpu_desc = iq2000_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach,
312 CGEN_CPU_OPEN_ENDIAN,
313 CGEN_ENDIAN_BIG,
314 CGEN_CPU_OPEN_END);
315 iq2000_cgen_init_asm (gas_cgen_cpu_desc);
317 /* This is a callback from cgen to gas to parse operands. */
318 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
320 /* Set the ELF flags if desired. */
321 if (iq2000_flags)
322 bfd_set_private_flags (stdoutput, iq2000_flags);
324 /* Set the machine type */
325 bfd_default_set_arch_mach (stdoutput, bfd_arch_iq2000, iq2000_mach);
327 iq2000_load_macros ();
330 void
331 md_assemble (char * str)
333 static long delayed_load_register = 0;
334 static int last_insn_had_delay_slot = 0;
335 static int last_insn_has_load_delay = 0;
336 static int last_insn_unconditional_jump = 0;
337 static int last_insn_was_ldw = 0;
339 iq2000_insn insn;
340 char * errmsg;
342 /* Initialize GAS's cgen interface for a new instruction. */
343 gas_cgen_init_parse ();
345 insn.insn = iq2000_cgen_assemble_insn
346 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
348 if (!insn.insn)
350 as_bad ("%s", errmsg);
351 return;
354 /* Doesn't really matter what we pass for RELAX_P here. */
355 gas_cgen_finish_insn (insn.insn, insn.buffer,
356 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
358 /* We need to generate an error if there's a yielding instruction in the delay
359 slot of a control flow modifying instruction (jump (yes), load (no)) */
360 if ((last_insn_had_delay_slot && !last_insn_has_load_delay) &&
361 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_YIELD_INSN))
362 as_bad (_("the yielding instruction %s may not be in a delay slot."),
363 CGEN_INSN_NAME (insn.insn));
365 /* Warn about odd numbered base registers for paired-register
366 instructions like LDW. On iq2000, result is always rt. */
367 if (iq2000_mach == bfd_mach_iq2000
368 && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_EVEN_REG_NUM)
369 && (insn.fields.f_rt % 2))
370 as_bad (_("Register number (R%ld) for double word access must be even."),
371 insn.fields.f_rt);
373 /* Warn about insns that reference the target of a previous load. */
374 /* NOTE: R0 is a special case and is not subject to load delays (except for ldw). */
375 if (delayed_load_register && (last_insn_has_load_delay || last_insn_was_ldw))
377 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RD) &&
378 insn.fields.f_rd == delayed_load_register)
379 as_warn (_("operand references R%ld of previous load."),
380 insn.fields.f_rd);
382 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RS) &&
383 insn.fields.f_rs == delayed_load_register)
384 as_warn (_("operand references R%ld of previous load."),
385 insn.fields.f_rs);
387 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RT) &&
388 insn.fields.f_rt == delayed_load_register)
389 as_warn (_("operand references R%ld of previous load."),
390 insn.fields.f_rt);
392 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_R31) &&
393 delayed_load_register == 31)
394 as_warn (_("instruction implicitly accesses R31 of previous load."));
397 /* Warn about insns that reference the (target + 1) of a previous ldw. */
398 if (last_insn_was_ldw)
400 if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RD)
401 && insn.fields.f_rd == delayed_load_register + 1)
402 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RS)
403 && insn.fields.f_rs == delayed_load_register + 1)
404 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RT)
405 && insn.fields.f_rt == delayed_load_register + 1))
406 as_warn (_("operand references R%ld of previous load."),
407 delayed_load_register + 1);
410 last_insn_had_delay_slot =
411 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
413 last_insn_has_load_delay =
414 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
416 if (last_insn_unconditional_jump)
417 last_insn_has_load_delay = last_insn_unconditional_jump = 0;
418 else if (! strcmp (CGEN_INSN_MNEMONIC (insn.insn), "j")
419 || ! strcmp (CGEN_INSN_MNEMONIC (insn.insn), "jal"))
420 last_insn_unconditional_jump = 1;
422 /* The meaning of EVEN_REG_NUM was overloaded to also imply LDW. Since
423 that's not true for IQ10, let's make the above logic specific to LDW. */
424 last_insn_was_ldw = ! strcmp ("ldw", CGEN_INSN_NAME (insn.insn));
426 /* The assumption here is that the target of a load is always rt. */
427 delayed_load_register = insn.fields.f_rt;
430 valueT
431 md_section_align (segT segment, valueT size)
433 int align = bfd_get_section_alignment (stdoutput, segment);
434 return ((size + (1 << align) - 1) & -(1 << align));
437 symbolS *
438 md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
440 return 0;
443 /* Interface to relax_segment. */
445 /* Return an initial guess of the length by which a fragment must grow to
446 hold a branch to reach its destination.
447 Also updates fr_type/fr_subtype as necessary.
449 Called just before doing relaxation.
450 Any symbol that is now undefined will not become defined.
451 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
452 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
453 Although it may not be explicit in the frag, pretend fr_var starts with a
454 0 value. */
457 md_estimate_size_before_relax (fragS * fragP,
458 segT segment ATTRIBUTE_UNUSED)
460 int old_fr_fix = fragP->fr_fix;
462 /* The only thing we have to handle here are symbols outside of the
463 current segment. They may be undefined or in a different segment in
464 which case linker scripts may place them anywhere.
465 However, we can't finish the fragment here and emit the reloc as insn
466 alignment requirements may move the insn about. */
468 return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
471 /* *fragP has been relaxed to its final size, and now needs to have
472 the bytes inside it modified to conform to the new size.
474 Called after relaxation is finished.
475 fragP->fr_type == rs_machine_dependent.
476 fragP->fr_subtype is the subtype of what the address relaxed to. */
478 void
479 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
480 segT sec ATTRIBUTE_UNUSED,
481 fragS * fragP ATTRIBUTE_UNUSED)
486 /* Functions concerning relocs. */
488 long
489 md_pcrel_from_section (fixS * fixP, segT sec)
491 if (fixP->fx_addsy != (symbolS *) NULL
492 && (! S_IS_DEFINED (fixP->fx_addsy)
493 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
495 /* The symbol is undefined (or is defined but not in this section).
496 Let the linker figure it out. */
497 return 0;
500 /* Return the address of the delay slot. */
501 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
504 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
505 Returns BFD_RELOC_NONE if no reloc type can be found.
506 *FIXP may be modified if desired. */
508 bfd_reloc_code_real_type
509 md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
510 const CGEN_OPERAND * operand,
511 fixS * fixP ATTRIBUTE_UNUSED)
513 switch (operand->type)
515 case IQ2000_OPERAND_OFFSET: return BFD_RELOC_16_PCREL_S2;
516 case IQ2000_OPERAND_JMPTARG: return BFD_RELOC_IQ2000_OFFSET_16;
517 case IQ2000_OPERAND_JMPTARGQ10: return BFD_RELOC_NONE;
518 case IQ2000_OPERAND_HI16: return BFD_RELOC_HI16;
519 case IQ2000_OPERAND_LO16: return BFD_RELOC_LO16;
520 default: break;
523 return BFD_RELOC_NONE;
526 /* Record a HI16 reloc for later matching with its LO16 cousin. */
528 static void
529 iq2000_record_hi16 (int reloc_type,
530 fixS * fixP,
531 segT seg ATTRIBUTE_UNUSED)
533 struct iq2000_hi_fixup * hi_fixup;
535 gas_assert (reloc_type == BFD_RELOC_HI16);
537 hi_fixup = XNEW (struct iq2000_hi_fixup);
538 hi_fixup->fixp = fixP;
539 hi_fixup->seg = now_seg;
540 hi_fixup->next = iq2000_hi_fixup_list;
542 iq2000_hi_fixup_list = hi_fixup;
545 /* Called while parsing an instruction to create a fixup.
546 We need to check for HI16 relocs and queue them up for later sorting. */
548 fixS *
549 iq2000_cgen_record_fixup_exp (fragS * frag,
550 int where,
551 const CGEN_INSN * insn,
552 int length,
553 const CGEN_OPERAND * operand,
554 int opinfo,
555 expressionS * exp)
557 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
558 operand, opinfo, exp);
560 if (operand->type == IQ2000_OPERAND_HI16
561 /* If low/high was used, it is recorded in `opinfo'. */
562 && (fixP->fx_cgen.opinfo == BFD_RELOC_HI16
563 || fixP->fx_cgen.opinfo == BFD_RELOC_LO16))
564 iq2000_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);
566 return fixP;
569 /* Return BFD reloc type from opinfo field in a fixS.
570 It's tricky using fx_r_type in iq2000_frob_file because the values
571 are BFD_RELOC_UNUSED + operand number. */
572 #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
574 /* Sort any unmatched HI16 relocs so that they immediately precede
575 the corresponding LO16 reloc. This is called before md_apply_fix and
576 tc_gen_reloc. */
578 void
579 iq2000_frob_file (void)
581 struct iq2000_hi_fixup * l;
583 for (l = iq2000_hi_fixup_list; l != NULL; l = l->next)
585 segment_info_type * seginfo;
586 int pass;
588 gas_assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_HI16
589 || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_LO16);
591 /* Check quickly whether the next fixup happens to be a matching low. */
592 if (l->fixp->fx_next != NULL
593 && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_LO16
594 && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
595 && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
596 continue;
598 /* Look through the fixups for this segment for a matching
599 `low'. When we find one, move the high just in front of it.
600 We do this in two passes. In the first pass, we try to find
601 a unique `low'. In the second pass, we permit multiple
602 high's relocs for a single `low'. */
603 seginfo = seg_info (l->seg);
604 for (pass = 0; pass < 2; pass++)
606 fixS * f;
607 fixS * prev;
609 prev = NULL;
610 for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
612 /* Check whether this is a `low' fixup which matches l->fixp. */
613 if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_LO16
614 && f->fx_addsy == l->fixp->fx_addsy
615 && f->fx_offset == l->fixp->fx_offset
616 && (pass == 1
617 || prev == NULL
618 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16)
619 || prev->fx_addsy != f->fx_addsy
620 || prev->fx_offset != f->fx_offset))
622 fixS ** pf;
624 /* Move l->fixp before f. */
625 for (pf = &seginfo->fix_root;
626 * pf != l->fixp;
627 pf = & (* pf)->fx_next)
628 gas_assert (* pf != NULL);
630 * pf = l->fixp->fx_next;
632 l->fixp->fx_next = f;
633 if (prev == NULL)
634 seginfo->fix_root = l->fixp;
635 else
636 prev->fx_next = l->fixp;
638 break;
641 prev = f;
644 if (f != NULL)
645 break;
647 if (pass == 1)
648 as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
649 _("Unmatched high relocation"));
654 /* See whether we need to force a relocation into the output file. */
657 iq2000_force_relocation (fixS * fix)
659 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
660 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
661 return 1;
663 return 0;
666 /* Handle the .set pseudo-op. */
668 static void
669 s_iq2000_set (int x ATTRIBUTE_UNUSED)
671 static const char * ignored_arguments [] =
673 "reorder",
674 "noreorder",
675 "at",
676 "noat",
677 "macro",
678 "nomacro",
679 "move",
680 "novolatile",
681 "nomove",
682 "volatile",
683 "bopt",
684 "nobopt",
685 NULL
687 const char ** ignored;
688 char *name = input_line_pointer, ch;
689 char *save_ILP = input_line_pointer;
691 while (!is_end_of_line[(unsigned char) *input_line_pointer])
692 input_line_pointer++;
693 ch = *input_line_pointer;
694 *input_line_pointer = '\0';
696 for (ignored = ignored_arguments; * ignored; ignored ++)
697 if (strcmp (* ignored, name) == 0)
698 break;
699 if (* ignored == NULL)
701 /* We'd like to be able to use .set symbol, expn */
702 input_line_pointer = save_ILP;
703 s_set (0);
704 return;
706 *input_line_pointer = ch;
707 demand_empty_rest_of_line ();
710 /* Write a value out to the object file, using the appropriate endianness. */
712 void
713 md_number_to_chars (char * buf, valueT val, int n)
715 number_to_chars_bigendian (buf, val, n);
718 void
719 md_operand (expressionS * exp)
721 /* In case of a syntax error, escape back to try next syntax combo. */
722 if (exp->X_op == O_absent)
723 gas_cgen_md_operand (exp);
726 const char *
727 md_atof (int type, char * litP, int * sizeP)
729 return ieee_md_atof (type, litP, sizeP, TRUE);
732 bfd_boolean
733 iq2000_fix_adjustable (fixS * fixP)
735 bfd_reloc_code_real_type reloc_type;
737 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
739 const CGEN_INSN *insn = NULL;
740 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
741 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
743 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
745 else
746 reloc_type = fixP->fx_r_type;
748 if (fixP->fx_addsy == NULL)
749 return TRUE;
751 /* Prevent all adjustments to global symbols. */
752 if (S_IS_EXTERNAL (fixP->fx_addsy))
753 return FALSE;
755 if (S_IS_WEAK (fixP->fx_addsy))
756 return FALSE;
758 /* We need the symbol name for the VTABLE entries. */
759 if ( reloc_type == BFD_RELOC_VTABLE_INHERIT
760 || reloc_type == BFD_RELOC_VTABLE_ENTRY)
761 return FALSE;
763 return TRUE;
766 static void
767 s_change_sec (int sec)
769 #ifdef OBJ_ELF
770 /* The ELF backend needs to know that we are changing sections, so
771 that .previous works correctly. We could do something like check
772 for a obj_section_change_hook macro, but that might be confusing
773 as it would not be appropriate to use it in the section changing
774 functions in read.c, since obj-elf.c intercepts those. FIXME:
775 This should be cleaner, somehow. */
776 obj_elf_section_change_hook ();
777 #endif
779 switch (sec)
781 case 't':
782 s_text (0);
783 break;
784 case 'd':
785 case 'r':
786 s_data (0);
787 break;
791 static symbolS *
792 get_symbol (void)
794 int c;
795 char *name;
796 symbolS *p;
798 c = get_symbol_name (&name);
799 p = (symbolS *) symbol_find_or_make (name);
800 (void) restore_line_pointer (c);
801 return p;
804 /* The .end directive. */
806 static void
807 s_iq2000_end (int x ATTRIBUTE_UNUSED)
809 symbolS *p;
810 int maybe_text;
812 if (!is_end_of_line[(unsigned char) *input_line_pointer])
814 p = get_symbol ();
815 demand_empty_rest_of_line ();
817 else
818 p = NULL;
820 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
821 maybe_text = 1;
822 else
823 maybe_text = 0;
825 if (!maybe_text)
826 as_warn (_(".end not in text section"));
828 if (!cur_proc_ptr)
830 as_warn (_(".end directive without a preceding .ent directive."));
831 demand_empty_rest_of_line ();
832 return;
835 if (p != NULL)
837 gas_assert (S_GET_NAME (p));
838 if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
839 as_warn (_(".end symbol does not match .ent symbol."));
841 else
842 as_warn (_(".end directive missing or unknown symbol"));
844 cur_proc_ptr = NULL;
847 static int
848 get_number (void)
850 int negative = 0;
851 long val = 0;
853 if (*input_line_pointer == '-')
855 ++input_line_pointer;
856 negative = 1;
859 if (! ISDIGIT (*input_line_pointer))
860 as_bad (_("Expected simple number."));
862 if (input_line_pointer[0] == '0')
864 if (input_line_pointer[1] == 'x')
866 input_line_pointer += 2;
867 while (ISXDIGIT (*input_line_pointer))
869 val <<= 4;
870 val |= hex_value (*input_line_pointer++);
872 return negative ? -val : val;
874 else
876 ++input_line_pointer;
878 while (ISDIGIT (*input_line_pointer))
880 val <<= 3;
881 val |= *input_line_pointer++ - '0';
883 return negative ? -val : val;
887 if (! ISDIGIT (*input_line_pointer))
889 printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
890 *input_line_pointer, *input_line_pointer);
891 as_warn (_("Invalid number"));
892 return -1;
895 while (ISDIGIT (*input_line_pointer))
897 val *= 10;
898 val += *input_line_pointer++ - '0';
901 return negative ? -val : val;
904 /* The .aent and .ent directives. */
906 static void
907 s_iq2000_ent (int aent)
909 symbolS *symbolP;
910 int maybe_text;
912 symbolP = get_symbol ();
913 if (*input_line_pointer == ',')
914 input_line_pointer++;
915 SKIP_WHITESPACE ();
916 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
917 get_number ();
919 if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
920 maybe_text = 1;
921 else
922 maybe_text = 0;
924 if (!maybe_text)
925 as_warn (_(".ent or .aent not in text section."));
927 if (!aent && cur_proc_ptr)
928 as_warn (_("missing `.end'"));
930 if (!aent)
932 cur_proc_ptr = &cur_proc;
933 memset (cur_proc_ptr, '\0', sizeof (procS));
935 cur_proc_ptr->isym = symbolP;
937 symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
939 numprocs++;
942 demand_empty_rest_of_line ();
945 /* The .frame directive. If the mdebug section is present (IRIX 5 native)
946 then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
947 s_iq2000_frame is used so that we can set the PDR information correctly.
948 We can't use the ecoff routines because they make reference to the ecoff
949 symbol table (in the mdebug section). */
951 static void
952 s_iq2000_frame (int ignore)
954 s_ignore (ignore);
957 /* The .fmask and .mask directives. If the mdebug section is present
958 (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
959 embedded targets, s_iq2000_mask is used so that we can set the PDR
960 information correctly. We can't use the ecoff routines because they
961 make reference to the ecoff symbol table (in the mdebug section). */
963 static void
964 s_iq2000_mask (int reg_type)
966 s_ignore (reg_type);
969 /* The target specific pseudo-ops which we support. */
970 const pseudo_typeS md_pseudo_table[] =
972 { "align", s_align_bytes, 0 },
973 { "word", cons, 4 },
974 { "rdata", s_change_sec, 'r'},
975 { "sdata", s_change_sec, 's'},
976 { "set", s_iq2000_set, 0 },
977 { "ent", s_iq2000_ent, 0 },
978 { "end", s_iq2000_end, 0 },
979 { "frame", s_iq2000_frame, 0 },
980 { "fmask", s_iq2000_mask, 'F'},
981 { "mask", s_iq2000_mask, 'R'},
982 { "dword", cons, 8 },
983 { "half", cons, 2 },
984 { NULL, NULL, 0 }