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