1 /* tc-iq2000.c -- Assembler for the Sitera IQ2000.
2 Copyright (C) 2003-2020 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)
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. */
22 #include "safe-ctype.h"
25 #include "opcodes/iq2000-desc.h"
26 #include "opcodes/iq2000-opc.h"
28 #include "elf/common.h"
29 #include "elf/iq2000.h"
33 /* Structure to hold all of the different components describing
34 an individual instruction. */
37 const CGEN_INSN
* insn
;
38 const CGEN_INSN
* orig_insn
;
41 CGEN_INSN_INT buffer
[1];
42 #define INSN_VALUE(buf) (*(buf))
44 unsigned char buffer
[CGEN_MAX_INSN_SIZE
];
45 #define INSN_VALUE(buf) (buf)
50 fixS
* fixups
[GAS_CGEN_MAX_FIXUPS
];
51 int indices
[MAX_OPERAND_INSTANCES
];
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
;
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
;
83 static procS cur_proc
;
84 static procS
*cur_proc_ptr
;
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 htab
*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
)
126 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
130 /* Automatically enter conditional branch macros. */
134 const char * mnemonic
;
135 const char ** expansion
;
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\
170 andoui \\rt,\\rs,%uhi(\\imm)\n\
171 andoi \\rt,\\rt,%lo(\\imm)\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\
179 orui \\rt,\\rs,%uhi(\\imm)\n\
180 ori \\rt,\\rt,%lo(\\imm)\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\
190 .elseif (\\imm & 0xffff0000 == 0xffff0000)\n\
191 addi \\rt,%0,\\imm\n\
192 .elseif (\\imm & 0x0000ffff == 0)\n\
193 lui \\rt,%uhi(\\imm)\n\
195 lui \\rt,%uhi(\\imm)\n\
196 ori \\rt,\\rt,%lo(\\imm)\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
},
227 iq2000_add_macro (const char * name
,
228 const char * semantics
,
229 const char ** arguments
)
235 macro
= XNEW (macro_entry
);
236 sb_new (& macro
->sub
);
237 sb_new (& macro_name
);
239 macro
->formal_count
= 0;
242 sb_add_string (& macro
->sub
, semantics
);
244 if (arguments
!= NULL
)
246 formal_entry
** p
= ¯o
->formals
;
248 macro
->formal_count
= 0;
249 macro
->formal_hash
= htab_create_alloc (7, hash_formal_entry
,
251 NULL
, xcalloc
, free
);
254 while (*arguments
!= NULL
)
256 formal_entry
*formal
;
258 formal
= XNEW (formal_entry
);
260 sb_new (& formal
->name
);
261 sb_new (& formal
->def
);
262 sb_new (& formal
->actual
);
264 /* chlm: Added the following to allow defaulted args. */
265 if (strchr (*arguments
,'='))
267 char * tt_args
= strdup (*arguments
);
268 char * tt_dflt
= strchr (tt_args
,'=');
271 sb_add_string (& formal
->name
, tt_args
);
272 sb_add_string (& formal
->def
, tt_dflt
+ 1);
275 sb_add_string (& formal
->name
, *arguments
);
277 /* Add to macro's hash table. */
278 htab_insert (macro
->formal_hash
,
279 formal_entry_alloc (sb_terminate (& formal
->name
),
281 formal
->index
= macro
->formal_count
;
282 macro
->formal_count
++;
290 sb_add_string (¯o_name
, name
);
291 namestr
= sb_terminate (¯o_name
);
292 htab_insert (macro_hash
, macro_entry_alloc (namestr
, macro
));
298 iq2000_load_macros (void)
301 int mcnt
= ARRAY_SIZE (iq2000_macro_defs
);
303 for (i
= 0; i
< mcnt
; i
++)
304 iq2000_add_macro (iq2000_macro_defs
[i
].mnemonic
,
305 *iq2000_macro_defs
[i
].expansion
,
306 iq2000_macro_defs
[i
].args
);
312 /* Initialize the `cgen' interface. */
314 /* Set the machine number and endian. */
315 gas_cgen_cpu_desc
= iq2000_cgen_cpu_open (CGEN_CPU_OPEN_MACHS
, cpu_mach
,
316 CGEN_CPU_OPEN_ENDIAN
,
319 iq2000_cgen_init_asm (gas_cgen_cpu_desc
);
321 /* This is a callback from cgen to gas to parse operands. */
322 cgen_set_parse_operand_fn (gas_cgen_cpu_desc
, gas_cgen_parse_operand
);
324 /* Set the ELF flags if desired. */
326 bfd_set_private_flags (stdoutput
, iq2000_flags
);
328 /* Set the machine type */
329 bfd_default_set_arch_mach (stdoutput
, bfd_arch_iq2000
, iq2000_mach
);
331 iq2000_load_macros ();
335 md_assemble (char * str
)
337 static long delayed_load_register
= 0;
338 static int last_insn_had_delay_slot
= 0;
339 static int last_insn_has_load_delay
= 0;
340 static int last_insn_unconditional_jump
= 0;
341 static int last_insn_was_ldw
= 0;
346 /* Initialize GAS's cgen interface for a new instruction. */
347 gas_cgen_init_parse ();
349 insn
.insn
= iq2000_cgen_assemble_insn
350 (gas_cgen_cpu_desc
, str
, & insn
.fields
, insn
.buffer
, & errmsg
);
354 as_bad ("%s", errmsg
);
358 /* Doesn't really matter what we pass for RELAX_P here. */
359 gas_cgen_finish_insn (insn
.insn
, insn
.buffer
,
360 CGEN_FIELDS_BITSIZE (& insn
.fields
), 1, NULL
);
362 /* We need to generate an error if there's a yielding instruction in the delay
363 slot of a control flow modifying instruction (jump (yes), load (no)) */
364 if ((last_insn_had_delay_slot
&& !last_insn_has_load_delay
) &&
365 CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_YIELD_INSN
))
366 as_bad (_("the yielding instruction %s may not be in a delay slot."),
367 CGEN_INSN_NAME (insn
.insn
));
369 /* Warn about odd numbered base registers for paired-register
370 instructions like LDW. On iq2000, result is always rt. */
371 if (iq2000_mach
== bfd_mach_iq2000
372 && CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_EVEN_REG_NUM
)
373 && (insn
.fields
.f_rt
% 2))
374 as_bad (_("Register number (R%ld) for double word access must be even."),
377 /* Warn about insns that reference the target of a previous load. */
378 /* NOTE: R0 is a special case and is not subject to load delays (except for ldw). */
379 if (delayed_load_register
&& (last_insn_has_load_delay
|| last_insn_was_ldw
))
381 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RD
) &&
382 insn
.fields
.f_rd
== delayed_load_register
)
383 as_warn (_("operand references R%ld of previous load."),
386 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RS
) &&
387 insn
.fields
.f_rs
== delayed_load_register
)
388 as_warn (_("operand references R%ld of previous load."),
391 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RT
) &&
392 insn
.fields
.f_rt
== delayed_load_register
)
393 as_warn (_("operand references R%ld of previous load."),
396 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_R31
) &&
397 delayed_load_register
== 31)
398 as_warn (_("instruction implicitly accesses R31 of previous load."));
401 /* Warn about insns that reference the (target + 1) of a previous ldw. */
402 if (last_insn_was_ldw
)
404 if ((CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RD
)
405 && insn
.fields
.f_rd
== delayed_load_register
+ 1)
406 || (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RS
)
407 && insn
.fields
.f_rs
== delayed_load_register
+ 1)
408 || (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RT
)
409 && insn
.fields
.f_rt
== delayed_load_register
+ 1))
410 as_warn (_("operand references R%ld of previous load."),
411 delayed_load_register
+ 1);
414 last_insn_had_delay_slot
=
415 CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_DELAY_SLOT
);
417 last_insn_has_load_delay
=
418 CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_LOAD_DELAY
);
420 if (last_insn_unconditional_jump
)
421 last_insn_has_load_delay
= last_insn_unconditional_jump
= 0;
422 else if (! strcmp (CGEN_INSN_MNEMONIC (insn
.insn
), "j")
423 || ! strcmp (CGEN_INSN_MNEMONIC (insn
.insn
), "jal"))
424 last_insn_unconditional_jump
= 1;
426 /* The meaning of EVEN_REG_NUM was overloaded to also imply LDW. Since
427 that's not true for IQ10, let's make the above logic specific to LDW. */
428 last_insn_was_ldw
= ! strcmp ("ldw", CGEN_INSN_NAME (insn
.insn
));
430 /* The assumption here is that the target of a load is always rt. */
431 delayed_load_register
= insn
.fields
.f_rt
;
435 md_section_align (segT segment
, valueT size
)
437 int align
= bfd_section_alignment (segment
);
438 return ((size
+ (1 << align
) - 1) & -(1 << align
));
442 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
447 /* Interface to relax_segment. */
449 /* Return an initial guess of the length by which a fragment must grow to
450 hold a branch to reach its destination.
451 Also updates fr_type/fr_subtype as necessary.
453 Called just before doing relaxation.
454 Any symbol that is now undefined will not become defined.
455 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
456 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
457 Although it may not be explicit in the frag, pretend fr_var starts with a
461 md_estimate_size_before_relax (fragS
* fragP
,
462 segT segment ATTRIBUTE_UNUSED
)
464 int old_fr_fix
= fragP
->fr_fix
;
466 /* The only thing we have to handle here are symbols outside of the
467 current segment. They may be undefined or in a different segment in
468 which case linker scripts may place them anywhere.
469 However, we can't finish the fragment here and emit the reloc as insn
470 alignment requirements may move the insn about. */
472 return (fragP
->fr_var
+ fragP
->fr_fix
- old_fr_fix
);
475 /* *fragP has been relaxed to its final size, and now needs to have
476 the bytes inside it modified to conform to the new size.
478 Called after relaxation is finished.
479 fragP->fr_type == rs_machine_dependent.
480 fragP->fr_subtype is the subtype of what the address relaxed to. */
483 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
484 segT sec ATTRIBUTE_UNUSED
,
485 fragS
* fragP ATTRIBUTE_UNUSED
)
490 /* Functions concerning relocs. */
493 md_pcrel_from_section (fixS
* fixP
, segT sec
)
495 if (fixP
->fx_addsy
!= (symbolS
*) NULL
496 && (! S_IS_DEFINED (fixP
->fx_addsy
)
497 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
499 /* The symbol is undefined (or is defined but not in this section).
500 Let the linker figure it out. */
504 /* Return the address of the delay slot. */
505 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
508 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
509 Returns BFD_RELOC_NONE if no reloc type can be found.
510 *FIXP may be modified if desired. */
512 bfd_reloc_code_real_type
513 md_cgen_lookup_reloc (const CGEN_INSN
* insn ATTRIBUTE_UNUSED
,
514 const CGEN_OPERAND
* operand
,
515 fixS
* fixP ATTRIBUTE_UNUSED
)
517 switch (operand
->type
)
519 case IQ2000_OPERAND_OFFSET
: return BFD_RELOC_16_PCREL_S2
;
520 case IQ2000_OPERAND_JMPTARG
: return BFD_RELOC_IQ2000_OFFSET_16
;
521 case IQ2000_OPERAND_JMPTARGQ10
: return BFD_RELOC_NONE
;
522 case IQ2000_OPERAND_HI16
: return BFD_RELOC_HI16
;
523 case IQ2000_OPERAND_LO16
: return BFD_RELOC_LO16
;
527 return BFD_RELOC_NONE
;
530 /* Record a HI16 reloc for later matching with its LO16 cousin. */
533 iq2000_record_hi16 (int reloc_type
,
535 segT seg ATTRIBUTE_UNUSED
)
537 struct iq2000_hi_fixup
* hi_fixup
;
539 gas_assert (reloc_type
== BFD_RELOC_HI16
);
541 hi_fixup
= XNEW (struct iq2000_hi_fixup
);
542 hi_fixup
->fixp
= fixP
;
543 hi_fixup
->seg
= now_seg
;
544 hi_fixup
->next
= iq2000_hi_fixup_list
;
546 iq2000_hi_fixup_list
= hi_fixup
;
549 /* Called while parsing an instruction to create a fixup.
550 We need to check for HI16 relocs and queue them up for later sorting. */
553 iq2000_cgen_record_fixup_exp (fragS
* frag
,
555 const CGEN_INSN
* insn
,
557 const CGEN_OPERAND
* operand
,
561 fixS
* fixP
= gas_cgen_record_fixup_exp (frag
, where
, insn
, length
,
562 operand
, opinfo
, exp
);
564 if (operand
->type
== IQ2000_OPERAND_HI16
565 /* If low/high was used, it is recorded in `opinfo'. */
566 && (fixP
->fx_cgen
.opinfo
== BFD_RELOC_HI16
567 || fixP
->fx_cgen
.opinfo
== BFD_RELOC_LO16
))
568 iq2000_record_hi16 (fixP
->fx_cgen
.opinfo
, fixP
, now_seg
);
573 /* Return BFD reloc type from opinfo field in a fixS.
574 It's tricky using fx_r_type in iq2000_frob_file because the values
575 are BFD_RELOC_UNUSED + operand number. */
576 #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
578 /* Sort any unmatched HI16 relocs so that they immediately precede
579 the corresponding LO16 reloc. This is called before md_apply_fix and
583 iq2000_frob_file (void)
585 struct iq2000_hi_fixup
* l
;
587 for (l
= iq2000_hi_fixup_list
; l
!= NULL
; l
= l
->next
)
589 segment_info_type
* seginfo
;
592 gas_assert (FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_HI16
593 || FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_LO16
);
595 /* Check quickly whether the next fixup happens to be a matching low. */
596 if (l
->fixp
->fx_next
!= NULL
597 && FX_OPINFO_R_TYPE (l
->fixp
->fx_next
) == BFD_RELOC_LO16
598 && l
->fixp
->fx_addsy
== l
->fixp
->fx_next
->fx_addsy
599 && l
->fixp
->fx_offset
== l
->fixp
->fx_next
->fx_offset
)
602 /* Look through the fixups for this segment for a matching
603 `low'. When we find one, move the high just in front of it.
604 We do this in two passes. In the first pass, we try to find
605 a unique `low'. In the second pass, we permit multiple
606 high's relocs for a single `low'. */
607 seginfo
= seg_info (l
->seg
);
608 for (pass
= 0; pass
< 2; pass
++)
614 for (f
= seginfo
->fix_root
; f
!= NULL
; f
= f
->fx_next
)
616 /* Check whether this is a `low' fixup which matches l->fixp. */
617 if (FX_OPINFO_R_TYPE (f
) == BFD_RELOC_LO16
618 && f
->fx_addsy
== l
->fixp
->fx_addsy
619 && f
->fx_offset
== l
->fixp
->fx_offset
622 || (FX_OPINFO_R_TYPE (prev
) != BFD_RELOC_HI16
)
623 || prev
->fx_addsy
!= f
->fx_addsy
624 || prev
->fx_offset
!= f
->fx_offset
))
628 /* Move l->fixp before f. */
629 for (pf
= &seginfo
->fix_root
;
631 pf
= & (* pf
)->fx_next
)
632 gas_assert (* pf
!= NULL
);
634 * pf
= l
->fixp
->fx_next
;
636 l
->fixp
->fx_next
= f
;
638 seginfo
->fix_root
= l
->fixp
;
640 prev
->fx_next
= l
->fixp
;
652 as_warn_where (l
->fixp
->fx_file
, l
->fixp
->fx_line
,
653 _("Unmatched high relocation"));
658 /* See whether we need to force a relocation into the output file. */
661 iq2000_force_relocation (fixS
* fix
)
663 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
664 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
670 /* Handle the .set pseudo-op. */
673 s_iq2000_set (int x ATTRIBUTE_UNUSED
)
675 static const char * ignored_arguments
[] =
691 const char ** ignored
;
692 char *name
= input_line_pointer
, ch
;
693 char *save_ILP
= input_line_pointer
;
695 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
696 input_line_pointer
++;
697 ch
= *input_line_pointer
;
698 *input_line_pointer
= '\0';
700 for (ignored
= ignored_arguments
; * ignored
; ignored
++)
701 if (strcmp (* ignored
, name
) == 0)
703 if (* ignored
== NULL
)
705 /* We'd like to be able to use .set symbol, expn */
706 input_line_pointer
= save_ILP
;
710 *input_line_pointer
= ch
;
711 demand_empty_rest_of_line ();
714 /* Write a value out to the object file, using the appropriate endianness. */
717 md_number_to_chars (char * buf
, valueT val
, int n
)
719 number_to_chars_bigendian (buf
, val
, n
);
723 md_operand (expressionS
* exp
)
725 /* In case of a syntax error, escape back to try next syntax combo. */
726 if (exp
->X_op
== O_absent
)
727 gas_cgen_md_operand (exp
);
731 md_atof (int type
, char * litP
, int * sizeP
)
733 return ieee_md_atof (type
, litP
, sizeP
, TRUE
);
737 iq2000_fix_adjustable (fixS
* fixP
)
739 bfd_reloc_code_real_type reloc_type
;
741 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
743 const CGEN_INSN
*insn
= NULL
;
744 int opindex
= (int) fixP
->fx_r_type
- (int) BFD_RELOC_UNUSED
;
745 const CGEN_OPERAND
*operand
= cgen_operand_lookup_by_num(gas_cgen_cpu_desc
, opindex
);
747 reloc_type
= md_cgen_lookup_reloc (insn
, operand
, fixP
);
750 reloc_type
= fixP
->fx_r_type
;
752 if (fixP
->fx_addsy
== NULL
)
755 /* Prevent all adjustments to global symbols. */
756 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
759 if (S_IS_WEAK (fixP
->fx_addsy
))
762 /* We need the symbol name for the VTABLE entries. */
763 if ( reloc_type
== BFD_RELOC_VTABLE_INHERIT
764 || reloc_type
== BFD_RELOC_VTABLE_ENTRY
)
771 s_change_sec (int sec
)
774 /* The ELF backend needs to know that we are changing sections, so
775 that .previous works correctly. We could do something like check
776 for a obj_section_change_hook macro, but that might be confusing
777 as it would not be appropriate to use it in the section changing
778 functions in read.c, since obj-elf.c intercepts those. FIXME:
779 This should be cleaner, somehow. */
780 obj_elf_section_change_hook ();
802 c
= get_symbol_name (&name
);
803 p
= (symbolS
*) symbol_find_or_make (name
);
804 (void) restore_line_pointer (c
);
808 /* The .end directive. */
811 s_iq2000_end (int x ATTRIBUTE_UNUSED
)
816 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
819 demand_empty_rest_of_line ();
824 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
830 as_warn (_(".end not in text section"));
834 as_warn (_(".end directive without a preceding .ent directive."));
835 demand_empty_rest_of_line ();
841 gas_assert (S_GET_NAME (p
));
842 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
843 as_warn (_(".end symbol does not match .ent symbol."));
846 as_warn (_(".end directive missing or unknown symbol"));
857 if (*input_line_pointer
== '-')
859 ++input_line_pointer
;
863 if (! ISDIGIT (*input_line_pointer
))
864 as_bad (_("Expected simple number."));
866 if (input_line_pointer
[0] == '0')
868 if (input_line_pointer
[1] == 'x')
870 input_line_pointer
+= 2;
871 while (ISXDIGIT (*input_line_pointer
))
874 val
|= hex_value (*input_line_pointer
++);
876 return negative
? -val
: val
;
880 ++input_line_pointer
;
882 while (ISDIGIT (*input_line_pointer
))
885 val
|= *input_line_pointer
++ - '0';
887 return negative
? -val
: val
;
891 if (! ISDIGIT (*input_line_pointer
))
893 printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
894 *input_line_pointer
, *input_line_pointer
);
895 as_warn (_("Invalid number"));
899 while (ISDIGIT (*input_line_pointer
))
902 val
+= *input_line_pointer
++ - '0';
905 return negative
? -val
: val
;
908 /* The .aent and .ent directives. */
911 s_iq2000_ent (int aent
)
916 symbolP
= get_symbol ();
917 if (*input_line_pointer
== ',')
918 input_line_pointer
++;
920 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
923 if ((bfd_section_flags (now_seg
) & SEC_CODE
) != 0)
929 as_warn (_(".ent or .aent not in text section."));
931 if (!aent
&& cur_proc_ptr
)
932 as_warn (_("missing `.end'"));
936 cur_proc_ptr
= &cur_proc
;
937 memset (cur_proc_ptr
, '\0', sizeof (procS
));
939 cur_proc_ptr
->isym
= symbolP
;
941 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
946 demand_empty_rest_of_line ();
949 /* The .frame directive. If the mdebug section is present (IRIX 5 native)
950 then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
951 s_iq2000_frame is used so that we can set the PDR information correctly.
952 We can't use the ecoff routines because they make reference to the ecoff
953 symbol table (in the mdebug section). */
956 s_iq2000_frame (int ignore
)
961 /* The .fmask and .mask directives. If the mdebug section is present
962 (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
963 embedded targets, s_iq2000_mask is used so that we can set the PDR
964 information correctly. We can't use the ecoff routines because they
965 make reference to the ecoff symbol table (in the mdebug section). */
968 s_iq2000_mask (int reg_type
)
973 /* The target specific pseudo-ops which we support. */
974 const pseudo_typeS md_pseudo_table
[] =
976 { "align", s_align_bytes
, 0 },
978 { "rdata", s_change_sec
, 'r'},
979 { "sdata", s_change_sec
, 's'},
980 { "set", s_iq2000_set
, 0 },
981 { "ent", s_iq2000_ent
, 0 },
982 { "end", s_iq2000_end
, 0 },
983 { "frame", s_iq2000_frame
, 0 },
984 { "fmask", s_iq2000_mask
, 'F'},
985 { "mask", s_iq2000_mask
, 'R'},
986 { "dword", cons
, 8 },