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