Port dw2gencfi.c to str_htab.
[deliverable/binutils-gdb.git] / gas / config / tc-iq2000.c
CommitLineData
1c53c80d 1/* tc-iq2000.c -- Assembler for the Sitera IQ2000.
b3adc24a 2 Copyright (C) 2003-2020 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"
96f989c2 30#include "sb.h"
1c53c80d
SC
31#include "macro.h"
32
33/* Structure to hold all of the different components describing
34 an individual instruction. */
35typedef struct
36{
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];
52}
53iq2000_insn;
54
55const char comment_chars[] = "#";
406a7f05 56const char line_comment_chars[] = "#";
5515a510 57const char line_separator_chars[] = ";";
1c53c80d
SC
58const char EXP_CHARS[] = "eE";
59const char FLT_CHARS[] = "dD";
60
5515a510 61/* Default machine. */
1c53c80d
SC
62#define DEFAULT_MACHINE bfd_mach_iq2000
63#define DEFAULT_FLAGS EF_IQ2000_CPU_IQ2000
64
65static unsigned long iq2000_mach = bfd_mach_iq2000;
66static int cpu_mach = (1 << MACH_IQ2000);
67
5515a510 68/* Flags to set in the elf header. */
1c53c80d
SC
69static flagword iq2000_flags = DEFAULT_FLAGS;
70
5515a510
NC
71typedef struct proc
72{
1c53c80d
SC
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;
82
83static procS cur_proc;
84static procS *cur_proc_ptr;
85static int numprocs;
86
1c53c80d
SC
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.
93
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. */
97
98struct iq2000_hi_fixup
99{
100 struct iq2000_hi_fixup * next; /* Next HI fixup. */
5515a510
NC
101 fixS * fixp; /* This fixup. */
102 segT seg; /* The section this fixup is in. */
1c53c80d
SC
103};
104
105/* The list of unmatched HI relocs. */
106static struct iq2000_hi_fixup * iq2000_hi_fixup_list;
107
5515a510 108/* Macro hash table, which we will add to. */
2b272f44 109extern struct htab *macro_hash;
1c53c80d 110\f
5515a510 111const char *md_shortopts = "";
1c53c80d 112struct option md_longopts[] =
5515a510
NC
113{
114 {NULL, no_argument, NULL, 0}
1c53c80d 115};
1c53c80d
SC
116size_t md_longopts_size = sizeof (md_longopts);
117
1c53c80d 118int
5515a510 119md_parse_option (int c ATTRIBUTE_UNUSED,
17b9d67d 120 const char * arg ATTRIBUTE_UNUSED)
1c53c80d 121{
5515a510 122 return 0;
1c53c80d
SC
123}
124
125void
5515a510 126md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
1c53c80d 127{
1c53c80d 128}
5515a510 129\f
1c53c80d
SC
130/* Automatically enter conditional branch macros. */
131
5515a510
NC
132typedef struct
133{
1c53c80d
SC
134 const char * mnemonic;
135 const char ** expansion;
136 const char ** args;
137} iq2000_macro_defs_s;
138
139static const char * abs_args[] = { "rd", "rs", "scratch=%1", NULL };
140static const char * abs_expn = "\n sra \\rd,\\rs,31\n xor \\scratch,\\rd,\\rs\n sub \\rd,\\scratch,\\rd\n";
1c53c80d
SC
141static const char * la_expn = "\n lui \\reg,%hi(\\label)\n ori \\reg,\\reg,%lo(\\label)\n";
142static const char * la_args[] = { "reg", "label", NULL };
1c53c80d
SC
143static const char * bxx_args[] = { "rs", "rt", "label", "scratch=%1", NULL };
144static const char * bge_expn = "\n slt \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
145static const char * bgeu_expn = "\n sltu \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
146static const char * bgt_expn = "\n slt \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
147static const char * bgtu_expn = "\n sltu \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
148static const char * ble_expn = "\n slt \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
149static const char * bleu_expn = "\n sltu \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
150static const char * blt_expn = "\n slt \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
151static const char * bltu_expn = "\n sltu \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
1c53c80d
SC
152static const char * sxx_args[] = { "rd", "rs", "rt", NULL };
153static const char * sge_expn = "\n slt \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
154static const char * sgeu_expn = "\n sltu \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
155static const char * sle_expn = "\n slt \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
156static const char * sleu_expn = "\n sltu \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
157static const char * sgt_expn = "\n slt \\rd,\\rt,\\rs\n";
158static const char * sgtu_expn = "\n sltu \\rd,\\rt,\\rs\n";
159static const char * sne_expn = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n";
160static const char * seq_expn = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n xori \\rd,\\rd,1\n";
1c53c80d
SC
161static const char * ai32_args[] = { "rt", "rs", "imm", NULL };
162static 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";
173static 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";
182
183static const char * neg_args[] = { "rd", "rs", NULL };
184static const char * neg_expn = "\n sub \\rd,%0,\\rs\n";
185static const char * negu_expn = "\n subu \\rd,%0,\\rs\n";
1c53c80d
SC
186static const char * li_args[] = { "rt", "imm", NULL };
187static 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\
95385380 192 .elseif (\\imm & 0x0000ffff == 0)\n\
1c53c80d
SC
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";
5515a510
NC
198
199static iq2000_macro_defs_s iq2000_macro_defs[] =
200{
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},
1c53c80d
SC
224};
225
226static void
5515a510
NC
227iq2000_add_macro (const char * name,
228 const char * semantics,
229 const char ** arguments)
230{
231 macro_entry *macro;
232 sb macro_name;
233 const char *namestr;
234
325801bd 235 macro = XNEW (macro_entry);
5515a510
NC
236 sb_new (& macro->sub);
237 sb_new (& macro_name);
238
239 macro->formal_count = 0;
240 macro->formals = 0;
241
242 sb_add_string (& macro->sub, semantics);
243
244 if (arguments != NULL)
245 {
246 formal_entry ** p = &macro->formals;
247
248 macro->formal_count = 0;
2b272f44
ML
249 macro->formal_hash = htab_create_alloc (7, hash_formal_entry,
250 eq_formal_entry,
251 NULL, xcalloc, free);
252
5515a510
NC
253
254 while (*arguments != NULL)
255 {
256 formal_entry *formal;
257
325801bd 258 formal = XNEW (formal_entry);
5515a510
NC
259
260 sb_new (& formal->name);
261 sb_new (& formal->def);
262 sb_new (& formal->actual);
263
264 /* chlm: Added the following to allow defaulted args. */
265 if (strchr (*arguments,'='))
266 {
267 char * tt_args = strdup (*arguments);
268 char * tt_dflt = strchr (tt_args,'=');
269
270 *tt_dflt = 0;
271 sb_add_string (& formal->name, tt_args);
272 sb_add_string (& formal->def, tt_dflt + 1);
273 }
274 else
275 sb_add_string (& formal->name, *arguments);
276
277 /* Add to macro's hash table. */
2b272f44
ML
278 htab_insert (macro->formal_hash,
279 formal_entry_alloc (sb_terminate (& formal->name),
280 formal));
5515a510
NC
281 formal->index = macro->formal_count;
282 macro->formal_count++;
283 *p = formal;
284 p = & formal->next;
285 *p = NULL;
286 ++arguments;
287 }
288 }
289
290 sb_add_string (&macro_name, name);
291 namestr = sb_terminate (&macro_name);
2b272f44 292 htab_insert (macro_hash, macro_entry_alloc (namestr, macro));
5515a510
NC
293
294 macro_defined = 1;
295}
296
297static void
298iq2000_load_macros (void)
1c53c80d
SC
299{
300 int i;
5515a510 301 int mcnt = ARRAY_SIZE (iq2000_macro_defs);
1c53c80d
SC
302
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);
307}
308
5515a510
NC
309void
310md_begin (void)
1c53c80d 311{
5515a510 312 /* Initialize the `cgen' interface. */
1c53c80d 313
5515a510
NC
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,
317 CGEN_ENDIAN_BIG,
318 CGEN_CPU_OPEN_END);
319 iq2000_cgen_init_asm (gas_cgen_cpu_desc);
1c53c80d 320
5515a510
NC
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);
323
324 /* Set the ELF flags if desired. */
325 if (iq2000_flags)
326 bfd_set_private_flags (stdoutput, iq2000_flags);
1c53c80d 327
5515a510
NC
328 /* Set the machine type */
329 bfd_default_set_arch_mach (stdoutput, bfd_arch_iq2000, iq2000_mach);
330
331 iq2000_load_macros ();
332}
1c53c80d
SC
333
334void
5515a510 335md_assemble (char * str)
1c53c80d
SC
336{
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;
342
343 iq2000_insn insn;
344 char * errmsg;
345
346 /* Initialize GAS's cgen interface for a new instruction. */
347 gas_cgen_init_parse ();
348
349 insn.insn = iq2000_cgen_assemble_insn
350 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
351
352 if (!insn.insn)
353 {
354 as_bad ("%s", errmsg);
355 return;
356 }
357
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);
361
5515a510
NC
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)) */
1c53c80d
SC
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));
368
369 /* Warn about odd numbered base registers for paired-register
5515a510 370 instructions like LDW. On iq2000, result is always rt. */
1c53c80d
SC
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."),
375 insn.fields.f_rt);
376
1c53c80d
SC
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))
380 {
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."),
384 insn.fields.f_rd);
5515a510 385
1c53c80d
SC
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."),
389 insn.fields.f_rs);
5515a510 390
1c53c80d
SC
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."),
394 insn.fields.f_rt);
5515a510 395
1c53c80d
SC
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."));
399 }
400
5515a510
NC
401 /* Warn about insns that reference the (target + 1) of a previous ldw. */
402 if (last_insn_was_ldw)
403 {
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);
412 }
1c53c80d
SC
413
414 last_insn_had_delay_slot =
415 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
416
417 last_insn_has_load_delay =
418 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
419
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;
425
5515a510
NC
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. */
1c53c80d
SC
428 last_insn_was_ldw = ! strcmp ("ldw", CGEN_INSN_NAME (insn.insn));
429
5515a510 430 /* The assumption here is that the target of a load is always rt. */
1c53c80d
SC
431 delayed_load_register = insn.fields.f_rt;
432}
433
434valueT
5515a510 435md_section_align (segT segment, valueT size)
1c53c80d 436{
fd361982 437 int align = bfd_section_alignment (segment);
8d3842cd 438 return ((size + (1 << align) - 1) & -(1 << align));
1c53c80d
SC
439}
440
1c53c80d 441symbolS *
5515a510 442md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1c53c80d
SC
443{
444 return 0;
445}
446\f
447/* Interface to relax_segment. */
448
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.
452
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
458 0 value. */
459
460int
5515a510
NC
461md_estimate_size_before_relax (fragS * fragP,
462 segT segment ATTRIBUTE_UNUSED)
1c53c80d
SC
463{
464 int old_fr_fix = fragP->fr_fix;
465
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. */
471
472 return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
5515a510 473}
1c53c80d
SC
474
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.
477
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. */
481
482void
5515a510
NC
483md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
484 segT sec ATTRIBUTE_UNUSED,
485 fragS * fragP ATTRIBUTE_UNUSED)
1c53c80d
SC
486{
487}
488
489\f
490/* Functions concerning relocs. */
491
492long
5515a510 493md_pcrel_from_section (fixS * fixP, segT sec)
1c53c80d
SC
494{
495 if (fixP->fx_addsy != (symbolS *) NULL
496 && (! S_IS_DEFINED (fixP->fx_addsy)
497 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
498 {
499 /* The symbol is undefined (or is defined but not in this section).
500 Let the linker figure it out. */
501 return 0;
502 }
503
5515a510 504 /* Return the address of the delay slot. */
1c53c80d
SC
505 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
506}
507
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. */
511
512bfd_reloc_code_real_type
5515a510
NC
513md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
514 const CGEN_OPERAND * operand,
515 fixS * fixP ATTRIBUTE_UNUSED)
1c53c80d
SC
516{
517 switch (operand->type)
518 {
5515a510
NC
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;
524 default: break;
1c53c80d
SC
525 }
526
527 return BFD_RELOC_NONE;
528}
529
530/* Record a HI16 reloc for later matching with its LO16 cousin. */
531
532static void
5515a510
NC
533iq2000_record_hi16 (int reloc_type,
534 fixS * fixP,
535 segT seg ATTRIBUTE_UNUSED)
1c53c80d
SC
536{
537 struct iq2000_hi_fixup * hi_fixup;
538
9c2799c2 539 gas_assert (reloc_type == BFD_RELOC_HI16);
1c53c80d 540
325801bd 541 hi_fixup = XNEW (struct iq2000_hi_fixup);
1c53c80d
SC
542 hi_fixup->fixp = fixP;
543 hi_fixup->seg = now_seg;
544 hi_fixup->next = iq2000_hi_fixup_list;
5515a510 545
1c53c80d
SC
546 iq2000_hi_fixup_list = hi_fixup;
547}
548
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. */
551
552fixS *
5515a510
NC
553iq2000_cgen_record_fixup_exp (fragS * frag,
554 int where,
555 const CGEN_INSN * insn,
556 int length,
557 const CGEN_OPERAND * operand,
558 int opinfo,
559 expressionS * exp)
1c53c80d
SC
560{
561 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
562 operand, opinfo, exp);
563
5515a510 564 if (operand->type == IQ2000_OPERAND_HI16
1c53c80d 565 /* If low/high was used, it is recorded in `opinfo'. */
5515a510
NC
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);
1c53c80d
SC
569
570 return fixP;
571}
572
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)
577
578/* Sort any unmatched HI16 relocs so that they immediately precede
55cf6793 579 the corresponding LO16 reloc. This is called before md_apply_fix and
1c53c80d
SC
580 tc_gen_reloc. */
581
582void
5515a510 583iq2000_frob_file (void)
1c53c80d
SC
584{
585 struct iq2000_hi_fixup * l;
586
587 for (l = iq2000_hi_fixup_list; l != NULL; l = l->next)
588 {
589 segment_info_type * seginfo;
590 int pass;
5515a510 591
9c2799c2 592 gas_assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_HI16
1c53c80d 593 || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_LO16);
5515a510 594
1c53c80d
SC
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)
600 continue;
601
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++)
609 {
610 fixS * f;
611 fixS * prev;
612
613 prev = NULL;
614 for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
615 {
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
620 && (pass == 1
621 || prev == NULL
622 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16)
623 || prev->fx_addsy != f->fx_addsy
624 || prev->fx_offset != f->fx_offset))
625 {
626 fixS ** pf;
627
628 /* Move l->fixp before f. */
629 for (pf = &seginfo->fix_root;
630 * pf != l->fixp;
631 pf = & (* pf)->fx_next)
9c2799c2 632 gas_assert (* pf != NULL);
1c53c80d
SC
633
634 * pf = l->fixp->fx_next;
635
636 l->fixp->fx_next = f;
637 if (prev == NULL)
638 seginfo->fix_root = l->fixp;
639 else
640 prev->fx_next = l->fixp;
641
642 break;
643 }
644
645 prev = f;
646 }
647
648 if (f != NULL)
649 break;
650
651 if (pass == 1)
652 as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
653 _("Unmatched high relocation"));
654 }
655 }
656}
657
658/* See whether we need to force a relocation into the output file. */
659
660int
5515a510 661iq2000_force_relocation (fixS * fix)
1c53c80d
SC
662{
663 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
664 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
665 return 1;
666
667 return 0;
668}
669\f
670/* Handle the .set pseudo-op. */
671
672static void
5515a510 673s_iq2000_set (int x ATTRIBUTE_UNUSED)
1c53c80d 674{
5515a510
NC
675 static const char * ignored_arguments [] =
676 {
677 "reorder",
678 "noreorder",
679 "at",
680 "noat",
681 "macro",
682 "nomacro",
683 "move",
684 "novolatile",
685 "nomove",
686 "volatile",
687 "bopt",
688 "nobopt",
689 NULL
690 };
b8b80cf7 691 const char ** ignored;
1c53c80d
SC
692 char *name = input_line_pointer, ch;
693 char *save_ILP = input_line_pointer;
694
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';
699
b8b80cf7
NC
700 for (ignored = ignored_arguments; * ignored; ignored ++)
701 if (strcmp (* ignored, name) == 0)
5515a510 702 break;
b8b80cf7 703 if (* ignored == NULL)
1c53c80d
SC
704 {
705 /* We'd like to be able to use .set symbol, expn */
706 input_line_pointer = save_ILP;
707 s_set (0);
708 return;
1c53c80d
SC
709 }
710 *input_line_pointer = ch;
711 demand_empty_rest_of_line ();
712}
713\f
714/* Write a value out to the object file, using the appropriate endianness. */
715
716void
5515a510 717md_number_to_chars (char * buf, valueT val, int n)
1c53c80d
SC
718{
719 number_to_chars_bigendian (buf, val, n);
720}
721
722void
5515a510 723md_operand (expressionS * exp)
1c53c80d 724{
5515a510 725 /* In case of a syntax error, escape back to try next syntax combo. */
1c53c80d
SC
726 if (exp->X_op == O_absent)
727 gas_cgen_md_operand (exp);
728}
729
6d4af3c2 730const char *
5515a510 731md_atof (int type, char * litP, int * sizeP)
1c53c80d 732{
499ac353 733 return ieee_md_atof (type, litP, sizeP, TRUE);
1c53c80d
SC
734}
735
1c53c80d 736bfd_boolean
5515a510 737iq2000_fix_adjustable (fixS * fixP)
1c53c80d
SC
738{
739 bfd_reloc_code_real_type reloc_type;
740
741 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
742 {
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);
5515a510 746
1c53c80d
SC
747 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
748 }
749 else
750 reloc_type = fixP->fx_r_type;
751
752 if (fixP->fx_addsy == NULL)
753 return TRUE;
5515a510 754
1c53c80d 755 /* Prevent all adjustments to global symbols. */
e97b3f28 756 if (S_IS_EXTERNAL (fixP->fx_addsy))
1c53c80d 757 return FALSE;
5515a510 758
1c53c80d
SC
759 if (S_IS_WEAK (fixP->fx_addsy))
760 return FALSE;
5515a510 761
1c53c80d
SC
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)
765 return FALSE;
766
767 return TRUE;
768}
769
770static void
5515a510 771s_change_sec (int sec)
1c53c80d 772{
1c53c80d
SC
773#ifdef OBJ_ELF
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 ();
781#endif
782
1c53c80d
SC
783 switch (sec)
784 {
785 case 't':
786 s_text (0);
787 break;
788 case 'd':
789 case 'r':
790 s_data (0);
791 break;
792 }
793}
794
5515a510
NC
795static symbolS *
796get_symbol (void)
797{
798 int c;
799 char *name;
800 symbolS *p;
801
d02603dc 802 c = get_symbol_name (&name);
5515a510 803 p = (symbolS *) symbol_find_or_make (name);
d02603dc 804 (void) restore_line_pointer (c);
5515a510
NC
805 return p;
806}
807
1c53c80d
SC
808/* The .end directive. */
809
810static void
5515a510 811s_iq2000_end (int x ATTRIBUTE_UNUSED)
1c53c80d
SC
812{
813 symbolS *p;
814 int maybe_text;
815
816 if (!is_end_of_line[(unsigned char) *input_line_pointer])
817 {
818 p = get_symbol ();
819 demand_empty_rest_of_line ();
820 }
821 else
822 p = NULL;
823
fd361982 824 if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
5515a510
NC
825 maybe_text = 1;
826 else
827 maybe_text = 0;
1c53c80d 828
5515a510
NC
829 if (!maybe_text)
830 as_warn (_(".end not in text section"));
1c53c80d 831
5515a510
NC
832 if (!cur_proc_ptr)
833 {
834 as_warn (_(".end directive without a preceding .ent directive."));
835 demand_empty_rest_of_line ();
836 return;
837 }
1c53c80d 838
5515a510 839 if (p != NULL)
1c53c80d 840 {
9c2799c2 841 gas_assert (S_GET_NAME (p));
5515a510
NC
842 if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
843 as_warn (_(".end symbol does not match .ent symbol."));
1c53c80d
SC
844 }
845 else
5515a510 846 as_warn (_(".end directive missing or unknown symbol"));
1c53c80d 847
5515a510 848 cur_proc_ptr = NULL;
1c53c80d
SC
849}
850
851static int
5515a510 852get_number (void)
1c53c80d
SC
853{
854 int negative = 0;
855 long val = 0;
856
857 if (*input_line_pointer == '-')
858 {
859 ++input_line_pointer;
860 negative = 1;
861 }
862
863 if (! ISDIGIT (*input_line_pointer))
864 as_bad (_("Expected simple number."));
865
866 if (input_line_pointer[0] == '0')
867 {
868 if (input_line_pointer[1] == 'x')
869 {
870 input_line_pointer += 2;
871 while (ISXDIGIT (*input_line_pointer))
872 {
873 val <<= 4;
874 val |= hex_value (*input_line_pointer++);
875 }
876 return negative ? -val : val;
877 }
878 else
879 {
880 ++input_line_pointer;
881
882 while (ISDIGIT (*input_line_pointer))
883 {
884 val <<= 3;
885 val |= *input_line_pointer++ - '0';
886 }
887 return negative ? -val : val;
888 }
889 }
890
891 if (! ISDIGIT (*input_line_pointer))
892 {
893 printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
894 *input_line_pointer, *input_line_pointer);
895 as_warn (_("Invalid number"));
896 return -1;
897 }
898
899 while (ISDIGIT (*input_line_pointer))
900 {
901 val *= 10;
902 val += *input_line_pointer++ - '0';
903 }
904
905 return negative ? -val : val;
906}
907
5515a510
NC
908/* The .aent and .ent directives. */
909
910static void
911s_iq2000_ent (int aent)
912{
5515a510
NC
913 symbolS *symbolP;
914 int maybe_text;
915
916 symbolP = get_symbol ();
917 if (*input_line_pointer == ',')
918 input_line_pointer++;
919 SKIP_WHITESPACE ();
920 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
87975d2a 921 get_number ();
5515a510 922
fd361982 923 if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
5515a510
NC
924 maybe_text = 1;
925 else
926 maybe_text = 0;
927
928 if (!maybe_text)
929 as_warn (_(".ent or .aent not in text section."));
930
931 if (!aent && cur_proc_ptr)
932 as_warn (_("missing `.end'"));
933
934 if (!aent)
935 {
936 cur_proc_ptr = &cur_proc;
937 memset (cur_proc_ptr, '\0', sizeof (procS));
938
939 cur_proc_ptr->isym = symbolP;
940
941 symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
942
943 numprocs++;
944 }
945
946 demand_empty_rest_of_line ();
947}
948
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). */
954
955static void
956s_iq2000_frame (int ignore)
957{
958 s_ignore (ignore);
959}
960
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). */
966
967static void
968s_iq2000_mask (int reg_type)
969{
970 s_ignore (reg_type);
971}
972
973/* The target specific pseudo-ops which we support. */
974const pseudo_typeS md_pseudo_table[] =
975{
976 { "align", s_align_bytes, 0 },
977 { "word", cons, 4 },
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 },
987 { "half", cons, 2 },
988 { NULL, NULL, 0 }
989};
This page took 0.796111 seconds and 4 git commands to generate.