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