]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gas/config/tc-iq2000.c
Update year range in copyright notice of binutils files
[thirdparty/binutils-gdb.git] / gas / config / tc-iq2000.c
CommitLineData
1c53c80d 1/* tc-iq2000.c -- Assembler for the Sitera IQ2000.
250d07de 2 Copyright (C) 2003-2021 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),
fe0e921f
AM
280 formal),
281 1);
5515a510
NC
282 formal->index = macro->formal_count;
283 macro->formal_count++;
284 *p = formal;
285 p = & formal->next;
286 *p = NULL;
287 ++arguments;
288 }
289 }
290
291 sb_add_string (&macro_name, name);
292 namestr = sb_terminate (&macro_name);
fe0e921f 293 htab_insert (macro_hash, macro_entry_alloc (namestr, macro), 1);
5515a510
NC
294
295 macro_defined = 1;
296}
297
298static void
299iq2000_load_macros (void)
1c53c80d
SC
300{
301 int i;
5515a510 302 int mcnt = ARRAY_SIZE (iq2000_macro_defs);
1c53c80d
SC
303
304 for (i = 0; i < mcnt; i++)
305 iq2000_add_macro (iq2000_macro_defs[i].mnemonic,
306 *iq2000_macro_defs[i].expansion,
307 iq2000_macro_defs[i].args);
308}
309
5515a510
NC
310void
311md_begin (void)
1c53c80d 312{
5515a510 313 /* Initialize the `cgen' interface. */
1c53c80d 314
5515a510
NC
315 /* Set the machine number and endian. */
316 gas_cgen_cpu_desc = iq2000_cgen_cpu_open (CGEN_CPU_OPEN_MACHS, cpu_mach,
317 CGEN_CPU_OPEN_ENDIAN,
318 CGEN_ENDIAN_BIG,
319 CGEN_CPU_OPEN_END);
320 iq2000_cgen_init_asm (gas_cgen_cpu_desc);
1c53c80d 321
5515a510
NC
322 /* This is a callback from cgen to gas to parse operands. */
323 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
324
325 /* Set the ELF flags if desired. */
326 if (iq2000_flags)
327 bfd_set_private_flags (stdoutput, iq2000_flags);
1c53c80d 328
5515a510
NC
329 /* Set the machine type */
330 bfd_default_set_arch_mach (stdoutput, bfd_arch_iq2000, iq2000_mach);
331
332 iq2000_load_macros ();
333}
1c53c80d
SC
334
335void
5515a510 336md_assemble (char * str)
1c53c80d
SC
337{
338 static long delayed_load_register = 0;
339 static int last_insn_had_delay_slot = 0;
340 static int last_insn_has_load_delay = 0;
341 static int last_insn_unconditional_jump = 0;
342 static int last_insn_was_ldw = 0;
343
344 iq2000_insn insn;
345 char * errmsg;
346
347 /* Initialize GAS's cgen interface for a new instruction. */
348 gas_cgen_init_parse ();
349
350 insn.insn = iq2000_cgen_assemble_insn
351 (gas_cgen_cpu_desc, str, & insn.fields, insn.buffer, & errmsg);
352
353 if (!insn.insn)
354 {
355 as_bad ("%s", errmsg);
356 return;
357 }
358
359 /* Doesn't really matter what we pass for RELAX_P here. */
360 gas_cgen_finish_insn (insn.insn, insn.buffer,
361 CGEN_FIELDS_BITSIZE (& insn.fields), 1, NULL);
362
5515a510
NC
363 /* We need to generate an error if there's a yielding instruction in the delay
364 slot of a control flow modifying instruction (jump (yes), load (no)) */
1c53c80d
SC
365 if ((last_insn_had_delay_slot && !last_insn_has_load_delay) &&
366 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_YIELD_INSN))
367 as_bad (_("the yielding instruction %s may not be in a delay slot."),
368 CGEN_INSN_NAME (insn.insn));
369
370 /* Warn about odd numbered base registers for paired-register
5515a510 371 instructions like LDW. On iq2000, result is always rt. */
1c53c80d
SC
372 if (iq2000_mach == bfd_mach_iq2000
373 && CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_EVEN_REG_NUM)
374 && (insn.fields.f_rt % 2))
375 as_bad (_("Register number (R%ld) for double word access must be even."),
376 insn.fields.f_rt);
377
1c53c80d
SC
378 /* Warn about insns that reference the target of a previous load. */
379 /* NOTE: R0 is a special case and is not subject to load delays (except for ldw). */
380 if (delayed_load_register && (last_insn_has_load_delay || last_insn_was_ldw))
381 {
382 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RD) &&
383 insn.fields.f_rd == delayed_load_register)
384 as_warn (_("operand references R%ld of previous load."),
385 insn.fields.f_rd);
5515a510 386
1c53c80d
SC
387 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RS) &&
388 insn.fields.f_rs == delayed_load_register)
389 as_warn (_("operand references R%ld of previous load."),
390 insn.fields.f_rs);
5515a510 391
1c53c80d
SC
392 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RT) &&
393 insn.fields.f_rt == delayed_load_register)
394 as_warn (_("operand references R%ld of previous load."),
395 insn.fields.f_rt);
5515a510 396
1c53c80d
SC
397 if (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_R31) &&
398 delayed_load_register == 31)
399 as_warn (_("instruction implicitly accesses R31 of previous load."));
400 }
401
5515a510
NC
402 /* Warn about insns that reference the (target + 1) of a previous ldw. */
403 if (last_insn_was_ldw)
404 {
405 if ((CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RD)
406 && insn.fields.f_rd == delayed_load_register + 1)
407 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RS)
408 && insn.fields.f_rs == delayed_load_register + 1)
409 || (CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_USES_RT)
410 && insn.fields.f_rt == delayed_load_register + 1))
411 as_warn (_("operand references R%ld of previous load."),
412 delayed_load_register + 1);
413 }
1c53c80d
SC
414
415 last_insn_had_delay_slot =
416 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_DELAY_SLOT);
417
418 last_insn_has_load_delay =
419 CGEN_INSN_ATTR_VALUE (insn.insn, CGEN_INSN_LOAD_DELAY);
420
421 if (last_insn_unconditional_jump)
422 last_insn_has_load_delay = last_insn_unconditional_jump = 0;
423 else if (! strcmp (CGEN_INSN_MNEMONIC (insn.insn), "j")
424 || ! strcmp (CGEN_INSN_MNEMONIC (insn.insn), "jal"))
425 last_insn_unconditional_jump = 1;
426
5515a510
NC
427 /* The meaning of EVEN_REG_NUM was overloaded to also imply LDW. Since
428 that's not true for IQ10, let's make the above logic specific to LDW. */
1c53c80d
SC
429 last_insn_was_ldw = ! strcmp ("ldw", CGEN_INSN_NAME (insn.insn));
430
5515a510 431 /* The assumption here is that the target of a load is always rt. */
1c53c80d
SC
432 delayed_load_register = insn.fields.f_rt;
433}
434
435valueT
5515a510 436md_section_align (segT segment, valueT size)
1c53c80d 437{
fd361982 438 int align = bfd_section_alignment (segment);
8d3842cd 439 return ((size + (1 << align) - 1) & -(1 << align));
1c53c80d
SC
440}
441
1c53c80d 442symbolS *
5515a510 443md_undefined_symbol (char * name ATTRIBUTE_UNUSED)
1c53c80d
SC
444{
445 return 0;
446}
447\f
448/* Interface to relax_segment. */
449
450/* Return an initial guess of the length by which a fragment must grow to
451 hold a branch to reach its destination.
452 Also updates fr_type/fr_subtype as necessary.
453
454 Called just before doing relaxation.
455 Any symbol that is now undefined will not become defined.
456 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
457 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
458 Although it may not be explicit in the frag, pretend fr_var starts with a
459 0 value. */
460
461int
5515a510
NC
462md_estimate_size_before_relax (fragS * fragP,
463 segT segment ATTRIBUTE_UNUSED)
1c53c80d
SC
464{
465 int old_fr_fix = fragP->fr_fix;
466
467 /* The only thing we have to handle here are symbols outside of the
468 current segment. They may be undefined or in a different segment in
469 which case linker scripts may place them anywhere.
470 However, we can't finish the fragment here and emit the reloc as insn
471 alignment requirements may move the insn about. */
472
473 return (fragP->fr_var + fragP->fr_fix - old_fr_fix);
5515a510 474}
1c53c80d
SC
475
476/* *fragP has been relaxed to its final size, and now needs to have
477 the bytes inside it modified to conform to the new size.
478
479 Called after relaxation is finished.
480 fragP->fr_type == rs_machine_dependent.
481 fragP->fr_subtype is the subtype of what the address relaxed to. */
482
483void
5515a510
NC
484md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED,
485 segT sec ATTRIBUTE_UNUSED,
486 fragS * fragP ATTRIBUTE_UNUSED)
1c53c80d
SC
487{
488}
489
490\f
491/* Functions concerning relocs. */
492
493long
5515a510 494md_pcrel_from_section (fixS * fixP, segT sec)
1c53c80d
SC
495{
496 if (fixP->fx_addsy != (symbolS *) NULL
497 && (! S_IS_DEFINED (fixP->fx_addsy)
498 || S_GET_SEGMENT (fixP->fx_addsy) != sec))
499 {
500 /* The symbol is undefined (or is defined but not in this section).
501 Let the linker figure it out. */
502 return 0;
503 }
504
5515a510 505 /* Return the address of the delay slot. */
1c53c80d
SC
506 return fixP->fx_size + fixP->fx_where + fixP->fx_frag->fr_address;
507}
508
509/* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
510 Returns BFD_RELOC_NONE if no reloc type can be found.
511 *FIXP may be modified if desired. */
512
513bfd_reloc_code_real_type
5515a510
NC
514md_cgen_lookup_reloc (const CGEN_INSN * insn ATTRIBUTE_UNUSED,
515 const CGEN_OPERAND * operand,
516 fixS * fixP ATTRIBUTE_UNUSED)
1c53c80d
SC
517{
518 switch (operand->type)
519 {
5515a510
NC
520 case IQ2000_OPERAND_OFFSET: return BFD_RELOC_16_PCREL_S2;
521 case IQ2000_OPERAND_JMPTARG: return BFD_RELOC_IQ2000_OFFSET_16;
522 case IQ2000_OPERAND_JMPTARGQ10: return BFD_RELOC_NONE;
523 case IQ2000_OPERAND_HI16: return BFD_RELOC_HI16;
524 case IQ2000_OPERAND_LO16: return BFD_RELOC_LO16;
525 default: break;
1c53c80d
SC
526 }
527
528 return BFD_RELOC_NONE;
529}
530
531/* Record a HI16 reloc for later matching with its LO16 cousin. */
532
533static void
5515a510
NC
534iq2000_record_hi16 (int reloc_type,
535 fixS * fixP,
536 segT seg ATTRIBUTE_UNUSED)
1c53c80d
SC
537{
538 struct iq2000_hi_fixup * hi_fixup;
539
9c2799c2 540 gas_assert (reloc_type == BFD_RELOC_HI16);
1c53c80d 541
325801bd 542 hi_fixup = XNEW (struct iq2000_hi_fixup);
1c53c80d
SC
543 hi_fixup->fixp = fixP;
544 hi_fixup->seg = now_seg;
545 hi_fixup->next = iq2000_hi_fixup_list;
5515a510 546
1c53c80d
SC
547 iq2000_hi_fixup_list = hi_fixup;
548}
549
550/* Called while parsing an instruction to create a fixup.
551 We need to check for HI16 relocs and queue them up for later sorting. */
552
553fixS *
5515a510
NC
554iq2000_cgen_record_fixup_exp (fragS * frag,
555 int where,
556 const CGEN_INSN * insn,
557 int length,
558 const CGEN_OPERAND * operand,
559 int opinfo,
560 expressionS * exp)
1c53c80d
SC
561{
562 fixS * fixP = gas_cgen_record_fixup_exp (frag, where, insn, length,
563 operand, opinfo, exp);
564
5515a510 565 if (operand->type == IQ2000_OPERAND_HI16
1c53c80d 566 /* If low/high was used, it is recorded in `opinfo'. */
5515a510
NC
567 && (fixP->fx_cgen.opinfo == BFD_RELOC_HI16
568 || fixP->fx_cgen.opinfo == BFD_RELOC_LO16))
569 iq2000_record_hi16 (fixP->fx_cgen.opinfo, fixP, now_seg);
1c53c80d
SC
570
571 return fixP;
572}
573
574/* Return BFD reloc type from opinfo field in a fixS.
575 It's tricky using fx_r_type in iq2000_frob_file because the values
576 are BFD_RELOC_UNUSED + operand number. */
577#define FX_OPINFO_R_TYPE(f) ((f)->fx_cgen.opinfo)
578
579/* Sort any unmatched HI16 relocs so that they immediately precede
55cf6793 580 the corresponding LO16 reloc. This is called before md_apply_fix and
1c53c80d
SC
581 tc_gen_reloc. */
582
583void
5515a510 584iq2000_frob_file (void)
1c53c80d
SC
585{
586 struct iq2000_hi_fixup * l;
587
588 for (l = iq2000_hi_fixup_list; l != NULL; l = l->next)
589 {
590 segment_info_type * seginfo;
591 int pass;
5515a510 592
9c2799c2 593 gas_assert (FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_HI16
1c53c80d 594 || FX_OPINFO_R_TYPE (l->fixp) == BFD_RELOC_LO16);
5515a510 595
1c53c80d
SC
596 /* Check quickly whether the next fixup happens to be a matching low. */
597 if (l->fixp->fx_next != NULL
598 && FX_OPINFO_R_TYPE (l->fixp->fx_next) == BFD_RELOC_LO16
599 && l->fixp->fx_addsy == l->fixp->fx_next->fx_addsy
600 && l->fixp->fx_offset == l->fixp->fx_next->fx_offset)
601 continue;
602
603 /* Look through the fixups for this segment for a matching
604 `low'. When we find one, move the high just in front of it.
605 We do this in two passes. In the first pass, we try to find
606 a unique `low'. In the second pass, we permit multiple
607 high's relocs for a single `low'. */
608 seginfo = seg_info (l->seg);
609 for (pass = 0; pass < 2; pass++)
610 {
611 fixS * f;
612 fixS * prev;
613
614 prev = NULL;
615 for (f = seginfo->fix_root; f != NULL; f = f->fx_next)
616 {
617 /* Check whether this is a `low' fixup which matches l->fixp. */
618 if (FX_OPINFO_R_TYPE (f) == BFD_RELOC_LO16
619 && f->fx_addsy == l->fixp->fx_addsy
620 && f->fx_offset == l->fixp->fx_offset
621 && (pass == 1
622 || prev == NULL
623 || (FX_OPINFO_R_TYPE (prev) != BFD_RELOC_HI16)
624 || prev->fx_addsy != f->fx_addsy
625 || prev->fx_offset != f->fx_offset))
626 {
627 fixS ** pf;
628
629 /* Move l->fixp before f. */
630 for (pf = &seginfo->fix_root;
631 * pf != l->fixp;
632 pf = & (* pf)->fx_next)
9c2799c2 633 gas_assert (* pf != NULL);
1c53c80d
SC
634
635 * pf = l->fixp->fx_next;
636
637 l->fixp->fx_next = f;
638 if (prev == NULL)
639 seginfo->fix_root = l->fixp;
640 else
641 prev->fx_next = l->fixp;
642
643 break;
644 }
645
646 prev = f;
647 }
648
649 if (f != NULL)
650 break;
651
652 if (pass == 1)
653 as_warn_where (l->fixp->fx_file, l->fixp->fx_line,
654 _("Unmatched high relocation"));
655 }
656 }
657}
658
659/* See whether we need to force a relocation into the output file. */
660
661int
5515a510 662iq2000_force_relocation (fixS * fix)
1c53c80d
SC
663{
664 if (fix->fx_r_type == BFD_RELOC_VTABLE_INHERIT
665 || fix->fx_r_type == BFD_RELOC_VTABLE_ENTRY)
666 return 1;
667
668 return 0;
669}
670\f
671/* Handle the .set pseudo-op. */
672
673static void
5515a510 674s_iq2000_set (int x ATTRIBUTE_UNUSED)
1c53c80d 675{
5515a510
NC
676 static const char * ignored_arguments [] =
677 {
678 "reorder",
679 "noreorder",
680 "at",
681 "noat",
682 "macro",
683 "nomacro",
684 "move",
685 "novolatile",
686 "nomove",
687 "volatile",
688 "bopt",
689 "nobopt",
690 NULL
691 };
b8b80cf7 692 const char ** ignored;
1c53c80d
SC
693 char *name = input_line_pointer, ch;
694 char *save_ILP = input_line_pointer;
695
696 while (!is_end_of_line[(unsigned char) *input_line_pointer])
697 input_line_pointer++;
698 ch = *input_line_pointer;
699 *input_line_pointer = '\0';
700
b8b80cf7
NC
701 for (ignored = ignored_arguments; * ignored; ignored ++)
702 if (strcmp (* ignored, name) == 0)
5515a510 703 break;
b8b80cf7 704 if (* ignored == NULL)
1c53c80d
SC
705 {
706 /* We'd like to be able to use .set symbol, expn */
707 input_line_pointer = save_ILP;
708 s_set (0);
709 return;
1c53c80d
SC
710 }
711 *input_line_pointer = ch;
712 demand_empty_rest_of_line ();
713}
714\f
715/* Write a value out to the object file, using the appropriate endianness. */
716
717void
5515a510 718md_number_to_chars (char * buf, valueT val, int n)
1c53c80d
SC
719{
720 number_to_chars_bigendian (buf, val, n);
721}
722
723void
5515a510 724md_operand (expressionS * exp)
1c53c80d 725{
5515a510 726 /* In case of a syntax error, escape back to try next syntax combo. */
1c53c80d
SC
727 if (exp->X_op == O_absent)
728 gas_cgen_md_operand (exp);
729}
730
6d4af3c2 731const char *
5515a510 732md_atof (int type, char * litP, int * sizeP)
1c53c80d 733{
499ac353 734 return ieee_md_atof (type, litP, sizeP, TRUE);
1c53c80d
SC
735}
736
1c53c80d 737bfd_boolean
5515a510 738iq2000_fix_adjustable (fixS * fixP)
1c53c80d
SC
739{
740 bfd_reloc_code_real_type reloc_type;
741
742 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
743 {
744 const CGEN_INSN *insn = NULL;
745 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
746 const CGEN_OPERAND *operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
5515a510 747
1c53c80d
SC
748 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
749 }
750 else
751 reloc_type = fixP->fx_r_type;
752
753 if (fixP->fx_addsy == NULL)
754 return TRUE;
5515a510 755
1c53c80d 756 /* Prevent all adjustments to global symbols. */
e97b3f28 757 if (S_IS_EXTERNAL (fixP->fx_addsy))
1c53c80d 758 return FALSE;
5515a510 759
1c53c80d
SC
760 if (S_IS_WEAK (fixP->fx_addsy))
761 return FALSE;
5515a510 762
1c53c80d
SC
763 /* We need the symbol name for the VTABLE entries. */
764 if ( reloc_type == BFD_RELOC_VTABLE_INHERIT
765 || reloc_type == BFD_RELOC_VTABLE_ENTRY)
766 return FALSE;
767
768 return TRUE;
769}
770
771static void
5515a510 772s_change_sec (int sec)
1c53c80d 773{
1c53c80d
SC
774#ifdef OBJ_ELF
775 /* The ELF backend needs to know that we are changing sections, so
776 that .previous works correctly. We could do something like check
777 for a obj_section_change_hook macro, but that might be confusing
778 as it would not be appropriate to use it in the section changing
779 functions in read.c, since obj-elf.c intercepts those. FIXME:
780 This should be cleaner, somehow. */
781 obj_elf_section_change_hook ();
782#endif
783
1c53c80d
SC
784 switch (sec)
785 {
786 case 't':
787 s_text (0);
788 break;
789 case 'd':
790 case 'r':
791 s_data (0);
792 break;
793 }
794}
795
5515a510
NC
796static symbolS *
797get_symbol (void)
798{
799 int c;
800 char *name;
801 symbolS *p;
802
d02603dc 803 c = get_symbol_name (&name);
5515a510 804 p = (symbolS *) symbol_find_or_make (name);
d02603dc 805 (void) restore_line_pointer (c);
5515a510
NC
806 return p;
807}
808
1c53c80d
SC
809/* The .end directive. */
810
811static void
5515a510 812s_iq2000_end (int x ATTRIBUTE_UNUSED)
1c53c80d
SC
813{
814 symbolS *p;
815 int maybe_text;
816
817 if (!is_end_of_line[(unsigned char) *input_line_pointer])
818 {
819 p = get_symbol ();
820 demand_empty_rest_of_line ();
821 }
822 else
823 p = NULL;
824
fd361982 825 if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
5515a510
NC
826 maybe_text = 1;
827 else
828 maybe_text = 0;
1c53c80d 829
5515a510
NC
830 if (!maybe_text)
831 as_warn (_(".end not in text section"));
1c53c80d 832
5515a510
NC
833 if (!cur_proc_ptr)
834 {
835 as_warn (_(".end directive without a preceding .ent directive."));
836 demand_empty_rest_of_line ();
837 return;
838 }
1c53c80d 839
5515a510 840 if (p != NULL)
1c53c80d 841 {
9c2799c2 842 gas_assert (S_GET_NAME (p));
5515a510
NC
843 if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
844 as_warn (_(".end symbol does not match .ent symbol."));
1c53c80d
SC
845 }
846 else
5515a510 847 as_warn (_(".end directive missing or unknown symbol"));
1c53c80d 848
5515a510 849 cur_proc_ptr = NULL;
1c53c80d
SC
850}
851
852static int
5515a510 853get_number (void)
1c53c80d
SC
854{
855 int negative = 0;
856 long val = 0;
857
858 if (*input_line_pointer == '-')
859 {
860 ++input_line_pointer;
861 negative = 1;
862 }
863
864 if (! ISDIGIT (*input_line_pointer))
865 as_bad (_("Expected simple number."));
866
867 if (input_line_pointer[0] == '0')
868 {
869 if (input_line_pointer[1] == 'x')
870 {
871 input_line_pointer += 2;
872 while (ISXDIGIT (*input_line_pointer))
873 {
874 val <<= 4;
875 val |= hex_value (*input_line_pointer++);
876 }
877 return negative ? -val : val;
878 }
879 else
880 {
881 ++input_line_pointer;
882
883 while (ISDIGIT (*input_line_pointer))
884 {
885 val <<= 3;
886 val |= *input_line_pointer++ - '0';
887 }
888 return negative ? -val : val;
889 }
890 }
891
892 if (! ISDIGIT (*input_line_pointer))
893 {
894 printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
895 *input_line_pointer, *input_line_pointer);
896 as_warn (_("Invalid number"));
897 return -1;
898 }
899
900 while (ISDIGIT (*input_line_pointer))
901 {
902 val *= 10;
903 val += *input_line_pointer++ - '0';
904 }
905
906 return negative ? -val : val;
907}
908
5515a510
NC
909/* The .aent and .ent directives. */
910
911static void
912s_iq2000_ent (int aent)
913{
5515a510
NC
914 symbolS *symbolP;
915 int maybe_text;
916
917 symbolP = get_symbol ();
918 if (*input_line_pointer == ',')
919 input_line_pointer++;
920 SKIP_WHITESPACE ();
921 if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
87975d2a 922 get_number ();
5515a510 923
fd361982 924 if ((bfd_section_flags (now_seg) & SEC_CODE) != 0)
5515a510
NC
925 maybe_text = 1;
926 else
927 maybe_text = 0;
928
929 if (!maybe_text)
930 as_warn (_(".ent or .aent not in text section."));
931
932 if (!aent && cur_proc_ptr)
933 as_warn (_("missing `.end'"));
934
935 if (!aent)
936 {
937 cur_proc_ptr = &cur_proc;
938 memset (cur_proc_ptr, '\0', sizeof (procS));
939
940 cur_proc_ptr->isym = symbolP;
941
942 symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
943
944 numprocs++;
945 }
946
947 demand_empty_rest_of_line ();
948}
949
950/* The .frame directive. If the mdebug section is present (IRIX 5 native)
951 then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
952 s_iq2000_frame is used so that we can set the PDR information correctly.
953 We can't use the ecoff routines because they make reference to the ecoff
954 symbol table (in the mdebug section). */
955
956static void
957s_iq2000_frame (int ignore)
958{
959 s_ignore (ignore);
960}
961
962/* The .fmask and .mask directives. If the mdebug section is present
963 (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
964 embedded targets, s_iq2000_mask is used so that we can set the PDR
965 information correctly. We can't use the ecoff routines because they
966 make reference to the ecoff symbol table (in the mdebug section). */
967
968static void
969s_iq2000_mask (int reg_type)
970{
971 s_ignore (reg_type);
972}
973
974/* The target specific pseudo-ops which we support. */
975const pseudo_typeS md_pseudo_table[] =
976{
977 { "align", s_align_bytes, 0 },
978 { "word", cons, 4 },
979 { "rdata", s_change_sec, 'r'},
980 { "sdata", s_change_sec, 's'},
981 { "set", s_iq2000_set, 0 },
982 { "ent", s_iq2000_ent, 0 },
983 { "end", s_iq2000_end, 0 },
984 { "frame", s_iq2000_frame, 0 },
985 { "fmask", s_iq2000_mask, 'F'},
986 { "mask", s_iq2000_mask, 'R'},
987 { "dword", cons, 8 },
988 { "half", cons, 2 },
989 { NULL, NULL, 0 }
990};