source: trunk/binutils/gas/config/tc-iq2000.c@ 2562

Last change on this file since 2562 was 607, checked in by bird, 22 years ago

Initial revision

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