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