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