1 /* tc-iq2000.c -- Assembler for the Sitera IQ2000.
2 Copyright (C) 2003, 2004, 2005, 2006, 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. */
23 #include "safe-ctype.h"
26 #include "opcodes/iq2000-desc.h"
27 #include "opcodes/iq2000-opc.h"
29 #include "elf/common.h"
30 #include "elf/iq2000.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
];
57 const char comment_chars
[] = "#";
58 const char line_comment_chars
[] = "#";
59 const char line_separator_chars
[] = ";";
60 const char EXP_CHARS
[] = "eE";
61 const char FLT_CHARS
[] = "dD";
63 /* Default machine. */
64 #define DEFAULT_MACHINE bfd_mach_iq2000
65 #define DEFAULT_FLAGS EF_IQ2000_CPU_IQ2000
67 static unsigned long iq2000_mach
= bfd_mach_iq2000
;
68 static int cpu_mach
= (1 << MACH_IQ2000
);
70 /* Flags to set in the elf header. */
71 static flagword iq2000_flags
= DEFAULT_FLAGS
;
76 unsigned long reg_mask
;
77 unsigned long reg_offset
;
78 unsigned long fpreg_mask
;
79 unsigned long fpreg_offset
;
80 unsigned long frame_offset
;
81 unsigned long frame_reg
;
85 static procS cur_proc
;
86 static procS
*cur_proc_ptr
;
89 /* Relocations against symbols are done in two
90 parts, with a HI relocation and a LO relocation. Each relocation
91 has only 16 bits of space to store an addend. This means that in
92 order for the linker to handle carries correctly, it must be able
93 to locate both the HI and the LO relocation. This means that the
94 relocations must appear in order in the relocation table.
96 In order to implement this, we keep track of each unmatched HI
97 relocation. We then sort them so that they immediately precede the
98 corresponding LO relocation. */
100 struct iq2000_hi_fixup
102 struct iq2000_hi_fixup
* next
; /* Next HI fixup. */
103 fixS
* fixp
; /* This fixup. */
104 segT seg
; /* The section this fixup is in. */
107 /* The list of unmatched HI relocs. */
108 static struct iq2000_hi_fixup
* iq2000_hi_fixup_list
;
110 /* Macro hash table, which we will add to. */
111 extern struct hash_control
*macro_hash
;
113 const char *md_shortopts
= "";
114 struct option md_longopts
[] =
116 {NULL
, no_argument
, NULL
, 0}
118 size_t md_longopts_size
= sizeof (md_longopts
);
121 md_parse_option (int c ATTRIBUTE_UNUSED
,
122 char * arg ATTRIBUTE_UNUSED
)
128 md_show_usage (FILE * stream ATTRIBUTE_UNUSED
)
132 /* Automatically enter conditional branch macros. */
136 const char * mnemonic
;
137 const char ** expansion
;
139 } iq2000_macro_defs_s
;
141 static const char * abs_args
[] = { "rd", "rs", "scratch=%1", NULL
};
142 static const char * abs_expn
= "\n sra \\rd,\\rs,31\n xor \\scratch,\\rd,\\rs\n sub \\rd,\\scratch,\\rd\n";
143 static const char * la_expn
= "\n lui \\reg,%hi(\\label)\n ori \\reg,\\reg,%lo(\\label)\n";
144 static const char * la_args
[] = { "reg", "label", NULL
};
145 static const char * bxx_args
[] = { "rs", "rt", "label", "scratch=%1", NULL
};
146 static const char * bge_expn
= "\n slt \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
147 static const char * bgeu_expn
= "\n sltu \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
148 static const char * bgt_expn
= "\n slt \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
149 static const char * bgtu_expn
= "\n sltu \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
150 static const char * ble_expn
= "\n slt \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
151 static const char * bleu_expn
= "\n sltu \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
152 static const char * blt_expn
= "\n slt \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
153 static const char * bltu_expn
= "\n sltu \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
154 static const char * sxx_args
[] = { "rd", "rs", "rt", NULL
};
155 static const char * sge_expn
= "\n slt \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
156 static const char * sgeu_expn
= "\n sltu \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
157 static const char * sle_expn
= "\n slt \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
158 static const char * sleu_expn
= "\n sltu \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
159 static const char * sgt_expn
= "\n slt \\rd,\\rt,\\rs\n";
160 static const char * sgtu_expn
= "\n sltu \\rd,\\rt,\\rs\n";
161 static const char * sne_expn
= "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n";
162 static const char * seq_expn
= "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n xori \\rd,\\rd,1\n";
163 static const char * ai32_args
[] = { "rt", "rs", "imm", NULL
};
164 static const char * andi32_expn
= "\n\
165 .if (\\imm & 0xffff0000 == 0xffff0000)\n\
166 andoi \\rt,\\rs,%lo(\\imm)\n\
167 .elseif (\\imm & 0x0000ffff == 0x0000ffff)\n\
168 andoui \\rt,\\rs,%uhi(\\imm)\n\
169 .elseif (\\imm & 0xffff0000 == 0x00000000)\n\
170 andi \\rt,\\rs,%lo(\\imm)\n\
172 andoui \\rt,\\rs,%uhi(\\imm)\n\
173 andoi \\rt,\\rt,%lo(\\imm)\n\
175 static const char * ori32_expn
= "\n\
176 .if (\\imm & 0xffff == 0)\n\
177 orui \\rt,\\rs,%uhi(\\imm)\n\
178 .elseif (\\imm & 0xffff0000 == 0)\n\
179 ori \\rt,\\rs,%lo(\\imm)\n\
181 orui \\rt,\\rs,%uhi(\\imm)\n\
182 ori \\rt,\\rt,%lo(\\imm)\n\
185 static const char * neg_args
[] = { "rd", "rs", NULL
};
186 static const char * neg_expn
= "\n sub \\rd,%0,\\rs\n";
187 static const char * negu_expn
= "\n subu \\rd,%0,\\rs\n";
188 static const char * li_args
[] = { "rt", "imm", NULL
};
189 static const char * li_expn
= "\n\
190 .if (\\imm & 0xffff0000 == 0x0)\n\
192 .elseif (\\imm & 0xffff0000 == 0xffff0000)\n\
193 addi \\rt,%0,\\imm\n\
194 .elseif (\\imm & 0x0000ffff == 0)\n\
195 lui \\rt,%uhi(\\imm)\n\
197 lui \\rt,%uhi(\\imm)\n\
198 ori \\rt,\\rt,%lo(\\imm)\n\
201 static iq2000_macro_defs_s iq2000_macro_defs
[] =
203 {"abs", (const char **) & abs_expn
, (const char **) & abs_args
},
204 {"la", (const char **) & la_expn
, (const char **) & la_args
},
205 {"bge", (const char **) & bge_expn
, (const char **) & bxx_args
},
206 {"bgeu", (const char **) & bgeu_expn
, (const char **) & bxx_args
},
207 {"bgt", (const char **) & bgt_expn
, (const char **) & bxx_args
},
208 {"bgtu", (const char **) & bgtu_expn
, (const char **) & bxx_args
},
209 {"ble", (const char **) & ble_expn
, (const char **) & bxx_args
},
210 {"bleu", (const char **) & bleu_expn
, (const char **) & bxx_args
},
211 {"blt", (const char **) & blt_expn
, (const char **) & bxx_args
},
212 {"bltu", (const char **) & bltu_expn
, (const char **) & bxx_args
},
213 {"sge", (const char **) & sge_expn
, (const char **) & sxx_args
},
214 {"sgeu", (const char **) & sgeu_expn
, (const char **) & sxx_args
},
215 {"sle", (const char **) & sle_expn
, (const char **) & sxx_args
},
216 {"sleu", (const char **) & sleu_expn
, (const char **) & sxx_args
},
217 {"sgt", (const char **) & sgt_expn
, (const char **) & sxx_args
},
218 {"sgtu", (const char **) & sgtu_expn
, (const char **) & sxx_args
},
219 {"seq", (const char **) & seq_expn
, (const char **) & sxx_args
},
220 {"sne", (const char **) & sne_expn
, (const char **) & sxx_args
},
221 {"neg", (const char **) & neg_expn
, (const char **) & neg_args
},
222 {"negu", (const char **) & negu_expn
, (const char **) & neg_args
},
223 {"li", (const char **) & li_expn
, (const char **) & li_args
},
224 {"ori32", (const char **) & ori32_expn
, (const char **) & ai32_args
},
225 {"andi32",(const char **) & andi32_expn
,(const char **) & ai32_args
},
229 iq2000_add_macro (const char * name
,
230 const char * semantics
,
231 const char ** arguments
)
237 macro
= xmalloc (sizeof (macro_entry
));
238 sb_new (& macro
->sub
);
239 sb_new (& macro_name
);
241 macro
->formal_count
= 0;
244 sb_add_string (& macro
->sub
, semantics
);
246 if (arguments
!= NULL
)
248 formal_entry
** p
= ¯o
->formals
;
250 macro
->formal_count
= 0;
251 macro
->formal_hash
= hash_new ();
253 while (*arguments
!= NULL
)
255 formal_entry
*formal
;
257 formal
= xmalloc (sizeof (formal_entry
));
259 sb_new (& formal
->name
);
260 sb_new (& formal
->def
);
261 sb_new (& formal
->actual
);
263 /* chlm: Added the following to allow defaulted args. */
264 if (strchr (*arguments
,'='))
266 char * tt_args
= strdup (*arguments
);
267 char * tt_dflt
= strchr (tt_args
,'=');
270 sb_add_string (& formal
->name
, tt_args
);
271 sb_add_string (& formal
->def
, tt_dflt
+ 1);
274 sb_add_string (& formal
->name
, *arguments
);
276 /* Add to macro's hash table. */
277 hash_jam (macro
->formal_hash
, sb_terminate (& formal
->name
), formal
);
279 formal
->index
= macro
->formal_count
;
280 macro
->formal_count
++;
288 sb_add_string (¯o_name
, name
);
289 namestr
= sb_terminate (¯o_name
);
290 hash_jam (macro_hash
, namestr
, macro
);
296 iq2000_load_macros (void)
299 int mcnt
= ARRAY_SIZE (iq2000_macro_defs
);
301 for (i
= 0; i
< mcnt
; i
++)
302 iq2000_add_macro (iq2000_macro_defs
[i
].mnemonic
,
303 *iq2000_macro_defs
[i
].expansion
,
304 iq2000_macro_defs
[i
].args
);
310 /* Initialize the `cgen' interface. */
312 /* Set the machine number and endian. */
313 gas_cgen_cpu_desc
= iq2000_cgen_cpu_open (CGEN_CPU_OPEN_MACHS
, cpu_mach
,
314 CGEN_CPU_OPEN_ENDIAN
,
317 iq2000_cgen_init_asm (gas_cgen_cpu_desc
);
319 /* This is a callback from cgen to gas to parse operands. */
320 cgen_set_parse_operand_fn (gas_cgen_cpu_desc
, gas_cgen_parse_operand
);
322 /* Set the ELF flags if desired. */
324 bfd_set_private_flags (stdoutput
, iq2000_flags
);
326 /* Set the machine type */
327 bfd_default_set_arch_mach (stdoutput
, bfd_arch_iq2000
, iq2000_mach
);
329 iq2000_load_macros ();
333 md_assemble (char * str
)
335 static long delayed_load_register
= 0;
336 static int last_insn_had_delay_slot
= 0;
337 static int last_insn_has_load_delay
= 0;
338 static int last_insn_unconditional_jump
= 0;
339 static int last_insn_was_ldw
= 0;
344 /* Initialize GAS's cgen interface for a new instruction. */
345 gas_cgen_init_parse ();
347 insn
.insn
= iq2000_cgen_assemble_insn
348 (gas_cgen_cpu_desc
, str
, & insn
.fields
, insn
.buffer
, & errmsg
);
352 as_bad ("%s", errmsg
);
356 /* Doesn't really matter what we pass for RELAX_P here. */
357 gas_cgen_finish_insn (insn
.insn
, insn
.buffer
,
358 CGEN_FIELDS_BITSIZE (& insn
.fields
), 1, NULL
);
360 /* We need to generate an error if there's a yielding instruction in the delay
361 slot of a control flow modifying instruction (jump (yes), load (no)) */
362 if ((last_insn_had_delay_slot
&& !last_insn_has_load_delay
) &&
363 CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_YIELD_INSN
))
364 as_bad (_("the yielding instruction %s may not be in a delay slot."),
365 CGEN_INSN_NAME (insn
.insn
));
367 /* Warn about odd numbered base registers for paired-register
368 instructions like LDW. On iq2000, result is always rt. */
369 if (iq2000_mach
== bfd_mach_iq2000
370 && CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_EVEN_REG_NUM
)
371 && (insn
.fields
.f_rt
% 2))
372 as_bad (_("Register number (R%ld) for double word access must be even."),
375 /* Warn about insns that reference the target of a previous load. */
376 /* NOTE: R0 is a special case and is not subject to load delays (except for ldw). */
377 if (delayed_load_register
&& (last_insn_has_load_delay
|| last_insn_was_ldw
))
379 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RD
) &&
380 insn
.fields
.f_rd
== delayed_load_register
)
381 as_warn (_("operand references R%ld of previous load."),
384 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RS
) &&
385 insn
.fields
.f_rs
== delayed_load_register
)
386 as_warn (_("operand references R%ld of previous load."),
389 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RT
) &&
390 insn
.fields
.f_rt
== delayed_load_register
)
391 as_warn (_("operand references R%ld of previous load."),
394 if (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_R31
) &&
395 delayed_load_register
== 31)
396 as_warn (_("instruction implicitly accesses R31 of previous load."));
399 /* Warn about insns that reference the (target + 1) of a previous ldw. */
400 if (last_insn_was_ldw
)
402 if ((CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RD
)
403 && insn
.fields
.f_rd
== delayed_load_register
+ 1)
404 || (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RS
)
405 && insn
.fields
.f_rs
== delayed_load_register
+ 1)
406 || (CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_USES_RT
)
407 && insn
.fields
.f_rt
== delayed_load_register
+ 1))
408 as_warn (_("operand references R%ld of previous load."),
409 delayed_load_register
+ 1);
412 last_insn_had_delay_slot
=
413 CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_DELAY_SLOT
);
415 last_insn_has_load_delay
=
416 CGEN_INSN_ATTR_VALUE (insn
.insn
, CGEN_INSN_LOAD_DELAY
);
418 if (last_insn_unconditional_jump
)
419 last_insn_has_load_delay
= last_insn_unconditional_jump
= 0;
420 else if (! strcmp (CGEN_INSN_MNEMONIC (insn
.insn
), "j")
421 || ! strcmp (CGEN_INSN_MNEMONIC (insn
.insn
), "jal"))
422 last_insn_unconditional_jump
= 1;
424 /* The meaning of EVEN_REG_NUM was overloaded to also imply LDW. Since
425 that's not true for IQ10, let's make the above logic specific to LDW. */
426 last_insn_was_ldw
= ! strcmp ("ldw", CGEN_INSN_NAME (insn
.insn
));
428 /* The assumption here is that the target of a load is always rt. */
429 delayed_load_register
= insn
.fields
.f_rt
;
433 md_section_align (segT segment
, valueT size
)
435 int align
= bfd_get_section_alignment (stdoutput
, segment
);
436 return ((size
+ (1 << align
) - 1) & (-1 << align
));
440 md_undefined_symbol (char * name ATTRIBUTE_UNUSED
)
445 /* Interface to relax_segment. */
447 /* Return an initial guess of the length by which a fragment must grow to
448 hold a branch to reach its destination.
449 Also updates fr_type/fr_subtype as necessary.
451 Called just before doing relaxation.
452 Any symbol that is now undefined will not become defined.
453 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
454 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
455 Although it may not be explicit in the frag, pretend fr_var starts with a
459 md_estimate_size_before_relax (fragS
* fragP
,
460 segT segment ATTRIBUTE_UNUSED
)
462 int old_fr_fix
= fragP
->fr_fix
;
464 /* The only thing we have to handle here are symbols outside of the
465 current segment. They may be undefined or in a different segment in
466 which case linker scripts may place them anywhere.
467 However, we can't finish the fragment here and emit the reloc as insn
468 alignment requirements may move the insn about. */
470 return (fragP
->fr_var
+ fragP
->fr_fix
- old_fr_fix
);
473 /* *fragP has been relaxed to its final size, and now needs to have
474 the bytes inside it modified to conform to the new size.
476 Called after relaxation is finished.
477 fragP->fr_type == rs_machine_dependent.
478 fragP->fr_subtype is the subtype of what the address relaxed to. */
481 md_convert_frag (bfd
* abfd ATTRIBUTE_UNUSED
,
482 segT sec ATTRIBUTE_UNUSED
,
483 fragS
* fragP ATTRIBUTE_UNUSED
)
488 /* Functions concerning relocs. */
491 md_pcrel_from_section (fixS
* fixP
, segT sec
)
493 if (fixP
->fx_addsy
!= (symbolS
*) NULL
494 && (! S_IS_DEFINED (fixP
->fx_addsy
)
495 || S_GET_SEGMENT (fixP
->fx_addsy
) != sec
))
497 /* The symbol is undefined (or is defined but not in this section).
498 Let the linker figure it out. */
502 /* Return the address of the delay slot. */
503 return fixP
->fx_size
+ fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
506 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
507 Returns BFD_RELOC_NONE if no reloc type can be found.
508 *FIXP may be modified if desired. */
510 bfd_reloc_code_real_type
511 md_cgen_lookup_reloc (const CGEN_INSN
* insn ATTRIBUTE_UNUSED
,
512 const CGEN_OPERAND
* operand
,
513 fixS
* fixP ATTRIBUTE_UNUSED
)
515 switch (operand
->type
)
517 case IQ2000_OPERAND_OFFSET
: return BFD_RELOC_16_PCREL_S2
;
518 case IQ2000_OPERAND_JMPTARG
: return BFD_RELOC_IQ2000_OFFSET_16
;
519 case IQ2000_OPERAND_JMPTARGQ10
: return BFD_RELOC_NONE
;
520 case IQ2000_OPERAND_HI16
: return BFD_RELOC_HI16
;
521 case IQ2000_OPERAND_LO16
: return BFD_RELOC_LO16
;
525 return BFD_RELOC_NONE
;
528 /* Record a HI16 reloc for later matching with its LO16 cousin. */
531 iq2000_record_hi16 (int reloc_type
,
533 segT seg ATTRIBUTE_UNUSED
)
535 struct iq2000_hi_fixup
* hi_fixup
;
537 assert (reloc_type
== BFD_RELOC_HI16
);
539 hi_fixup
= xmalloc (sizeof * hi_fixup
);
540 hi_fixup
->fixp
= fixP
;
541 hi_fixup
->seg
= now_seg
;
542 hi_fixup
->next
= iq2000_hi_fixup_list
;
544 iq2000_hi_fixup_list
= hi_fixup
;
547 /* Called while parsing an instruction to create a fixup.
548 We need to check for HI16 relocs and queue them up for later sorting. */
551 iq2000_cgen_record_fixup_exp (fragS
* frag
,
553 const CGEN_INSN
* insn
,
555 const CGEN_OPERAND
* operand
,
559 fixS
* fixP
= gas_cgen_record_fixup_exp (frag
, where
, insn
, length
,
560 operand
, opinfo
, exp
);
562 if (operand
->type
== IQ2000_OPERAND_HI16
563 /* If low/high was used, it is recorded in `opinfo'. */
564 && (fixP
->fx_cgen
.opinfo
== BFD_RELOC_HI16
565 || fixP
->fx_cgen
.opinfo
== BFD_RELOC_LO16
))
566 iq2000_record_hi16 (fixP
->fx_cgen
.opinfo
, fixP
, now_seg
);
571 /* Return BFD reloc type from opinfo field in a fixS.
572 It's tricky using fx_r_type in iq2000_frob_file because the values
573 are BFD_RELOC_UNUSED + operand number. */
574 #define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
576 /* Sort any unmatched HI16 relocs so that they immediately precede
577 the corresponding LO16 reloc. This is called before md_apply_fix and
581 iq2000_frob_file (void)
583 struct iq2000_hi_fixup
* l
;
585 for (l
= iq2000_hi_fixup_list
; l
!= NULL
; l
= l
->next
)
587 segment_info_type
* seginfo
;
590 assert (FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_HI16
591 || FX_OPINFO_R_TYPE (l
->fixp
) == BFD_RELOC_LO16
);
593 /* Check quickly whether the next fixup happens to be a matching low. */
594 if (l
->fixp
->fx_next
!= NULL
595 && FX_OPINFO_R_TYPE (l
->fixp
->fx_next
) == BFD_RELOC_LO16
596 && l
->fixp
->fx_addsy
== l
->fixp
->fx_next
->fx_addsy
597 && l
->fixp
->fx_offset
== l
->fixp
->fx_next
->fx_offset
)
600 /* Look through the fixups for this segment for a matching
601 `low'. When we find one, move the high just in front of it.
602 We do this in two passes. In the first pass, we try to find
603 a unique `low'. In the second pass, we permit multiple
604 high's relocs for a single `low'. */
605 seginfo
= seg_info (l
->seg
);
606 for (pass
= 0; pass
< 2; pass
++)
612 for (f
= seginfo
->fix_root
; f
!= NULL
; f
= f
->fx_next
)
614 /* Check whether this is a `low' fixup which matches l->fixp. */
615 if (FX_OPINFO_R_TYPE (f
) == BFD_RELOC_LO16
616 && f
->fx_addsy
== l
->fixp
->fx_addsy
617 && f
->fx_offset
== l
->fixp
->fx_offset
620 || (FX_OPINFO_R_TYPE (prev
) != BFD_RELOC_HI16
)
621 || prev
->fx_addsy
!= f
->fx_addsy
622 || prev
->fx_offset
!= f
->fx_offset
))
626 /* Move l->fixp before f. */
627 for (pf
= &seginfo
->fix_root
;
629 pf
= & (* pf
)->fx_next
)
630 assert (* pf
!= NULL
);
632 * pf
= l
->fixp
->fx_next
;
634 l
->fixp
->fx_next
= f
;
636 seginfo
->fix_root
= l
->fixp
;
638 prev
->fx_next
= l
->fixp
;
650 as_warn_where (l
->fixp
->fx_file
, l
->fixp
->fx_line
,
651 _("Unmatched high relocation"));
656 /* See whether we need to force a relocation into the output file. */
659 iq2000_force_relocation (fixS
* fix
)
661 if (fix
->fx_r_type
== BFD_RELOC_VTABLE_INHERIT
662 || fix
->fx_r_type
== BFD_RELOC_VTABLE_ENTRY
)
668 /* Handle the .set pseudo-op. */
671 s_iq2000_set (int x ATTRIBUTE_UNUSED
)
673 static const char * ignored_arguments
[] =
689 const char ** ignored
;
690 char *name
= input_line_pointer
, ch
;
691 char *save_ILP
= input_line_pointer
;
693 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
694 input_line_pointer
++;
695 ch
= *input_line_pointer
;
696 *input_line_pointer
= '\0';
698 for (ignored
= ignored_arguments
; * ignored
; ignored
++)
699 if (strcmp (* ignored
, name
) == 0)
701 if (* ignored
== NULL
)
703 /* We'd like to be able to use .set symbol, expn */
704 input_line_pointer
= save_ILP
;
708 *input_line_pointer
= ch
;
709 demand_empty_rest_of_line ();
712 /* Write a value out to the object file, using the appropriate endianness. */
715 md_number_to_chars (char * buf
, valueT val
, int n
)
717 number_to_chars_bigendian (buf
, val
, n
);
721 md_operand (expressionS
* exp
)
723 /* In case of a syntax error, escape back to try next syntax combo. */
724 if (exp
->X_op
== O_absent
)
725 gas_cgen_md_operand (exp
);
728 /* Turn a string in input_line_pointer into a floating point constant
729 of type type, and store the appropriate bytes in *litP. The number
730 of LITTLENUMS emitted is stored in *sizeP . An error message is
731 returned, or NULL on OK. */
733 /* Equal to MAX_PRECISION in atof-ieee.c */
734 #define MAX_LITTLENUMS 6
737 md_atof (int type
, char * litP
, int * sizeP
)
741 LITTLENUM_TYPE words
[MAX_LITTLENUMS
];
760 /* FIXME: Some targets allow other format chars for bigger sizes here. */
764 return _("Bad call to md_atof()");
767 t
= atof_ieee (input_line_pointer
, type
, words
);
769 input_line_pointer
= t
;
770 * sizeP
= prec
* sizeof (LITTLENUM_TYPE
);
772 for (i
= 0; i
< prec
; i
++)
774 md_number_to_chars (litP
, (valueT
) words
[i
],
775 sizeof (LITTLENUM_TYPE
));
776 litP
+= sizeof (LITTLENUM_TYPE
);
784 iq2000_fix_adjustable (fixS
* fixP
)
786 bfd_reloc_code_real_type reloc_type
;
788 if ((int) fixP
->fx_r_type
>= (int) BFD_RELOC_UNUSED
)
790 const CGEN_INSN
*insn
= NULL
;
791 int opindex
= (int) fixP
->fx_r_type
- (int) BFD_RELOC_UNUSED
;
792 const CGEN_OPERAND
*operand
= cgen_operand_lookup_by_num(gas_cgen_cpu_desc
, opindex
);
794 reloc_type
= md_cgen_lookup_reloc (insn
, operand
, fixP
);
797 reloc_type
= fixP
->fx_r_type
;
799 if (fixP
->fx_addsy
== NULL
)
802 /* Prevent all adjustments to global symbols. */
803 if (S_IS_EXTERNAL (fixP
->fx_addsy
))
806 if (S_IS_WEAK (fixP
->fx_addsy
))
809 /* We need the symbol name for the VTABLE entries. */
810 if ( reloc_type
== BFD_RELOC_VTABLE_INHERIT
811 || reloc_type
== BFD_RELOC_VTABLE_ENTRY
)
818 s_change_sec (int sec
)
821 /* The ELF backend needs to know that we are changing sections, so
822 that .previous works correctly. We could do something like check
823 for a obj_section_change_hook macro, but that might be confusing
824 as it would not be appropriate to use it in the section changing
825 functions in read.c, since obj-elf.c intercepts those. FIXME:
826 This should be cleaner, somehow. */
827 obj_elf_section_change_hook ();
849 name
= input_line_pointer
;
850 c
= get_symbol_end ();
851 p
= (symbolS
*) symbol_find_or_make (name
);
852 *input_line_pointer
= c
;
856 /* The .end directive. */
859 s_iq2000_end (int x ATTRIBUTE_UNUSED
)
864 if (!is_end_of_line
[(unsigned char) *input_line_pointer
])
867 demand_empty_rest_of_line ();
872 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
878 as_warn (_(".end not in text section"));
882 as_warn (_(".end directive without a preceding .ent directive."));
883 demand_empty_rest_of_line ();
889 assert (S_GET_NAME (p
));
890 if (strcmp (S_GET_NAME (p
), S_GET_NAME (cur_proc_ptr
->isym
)))
891 as_warn (_(".end symbol does not match .ent symbol."));
894 as_warn (_(".end directive missing or unknown symbol"));
905 if (*input_line_pointer
== '-')
907 ++input_line_pointer
;
911 if (! ISDIGIT (*input_line_pointer
))
912 as_bad (_("Expected simple number."));
914 if (input_line_pointer
[0] == '0')
916 if (input_line_pointer
[1] == 'x')
918 input_line_pointer
+= 2;
919 while (ISXDIGIT (*input_line_pointer
))
922 val
|= hex_value (*input_line_pointer
++);
924 return negative
? -val
: val
;
928 ++input_line_pointer
;
930 while (ISDIGIT (*input_line_pointer
))
933 val
|= *input_line_pointer
++ - '0';
935 return negative
? -val
: val
;
939 if (! ISDIGIT (*input_line_pointer
))
941 printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
942 *input_line_pointer
, *input_line_pointer
);
943 as_warn (_("Invalid number"));
947 while (ISDIGIT (*input_line_pointer
))
950 val
+= *input_line_pointer
++ - '0';
953 return negative
? -val
: val
;
956 /* The .aent and .ent directives. */
959 s_iq2000_ent (int aent
)
965 symbolP
= get_symbol ();
966 if (*input_line_pointer
== ',')
967 input_line_pointer
++;
969 if (ISDIGIT (*input_line_pointer
) || *input_line_pointer
== '-')
970 number
= get_number ();
972 if ((bfd_get_section_flags (stdoutput
, now_seg
) & SEC_CODE
) != 0)
978 as_warn (_(".ent or .aent not in text section."));
980 if (!aent
&& cur_proc_ptr
)
981 as_warn (_("missing `.end'"));
985 cur_proc_ptr
= &cur_proc
;
986 memset (cur_proc_ptr
, '\0', sizeof (procS
));
988 cur_proc_ptr
->isym
= symbolP
;
990 symbol_get_bfdsym (symbolP
)->flags
|= BSF_FUNCTION
;
995 demand_empty_rest_of_line ();
998 /* The .frame directive. If the mdebug section is present (IRIX 5 native)
999 then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
1000 s_iq2000_frame is used so that we can set the PDR information correctly.
1001 We can't use the ecoff routines because they make reference to the ecoff
1002 symbol table (in the mdebug section). */
1005 s_iq2000_frame (int ignore
)
1010 /* The .fmask and .mask directives. If the mdebug section is present
1011 (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
1012 embedded targets, s_iq2000_mask is used so that we can set the PDR
1013 information correctly. We can't use the ecoff routines because they
1014 make reference to the ecoff symbol table (in the mdebug section). */
1017 s_iq2000_mask (int reg_type
)
1019 s_ignore (reg_type
);
1022 /* The target specific pseudo-ops which we support. */
1023 const pseudo_typeS md_pseudo_table
[] =
1025 { "align", s_align_bytes
, 0 },
1026 { "word", cons
, 4 },
1027 { "rdata", s_change_sec
, 'r'},
1028 { "sdata", s_change_sec
, 's'},
1029 { "set", s_iq2000_set
, 0 },
1030 { "ent", s_iq2000_ent
, 0 },
1031 { "end", s_iq2000_end
, 0 },
1032 { "frame", s_iq2000_frame
, 0 },
1033 { "fmask", s_iq2000_mask
, 'F'},
1034 { "mask", s_iq2000_mask
, 'R'},
1035 { "dword", cons
, 8 },
1036 { "half", cons
, 2 },