1/* tc-iq2000.c -- Assembler for the Sitera IQ2000.
2   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2009, 2010
3   Free Software Foundation. Inc.
4
5   This file is part of GAS, the GNU Assembler.
6
7   GAS is free software; you can redistribute it and/or modify
8   it under the terms of the GNU General Public License as published by
9   the Free Software Foundation; either version 3, or (at your option)
10   any later version.
11
12   GAS is distributed in the hope that it will be useful,
13   but WITHOUT ANY WARRANTY; without even the implied warranty of
14   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15   GNU General Public License for more details.
16
17   You should have received a copy of the GNU General Public License
18   along with GAS; see the file COPYING.  If not, write to
19   the Free Software Foundation, 51 Franklin Street - Fifth Floor,
20   Boston, MA 02110-1301, USA.  */
21
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 "sb.h"
33#include "macro.h"
34
35/* Structure to hold all of the different components describing
36   an individual instruction.  */
37typedef struct
38{
39  const CGEN_INSN *	insn;
40  const CGEN_INSN *	orig_insn;
41  CGEN_FIELDS		fields;
42#if CGEN_INT_INSN_P
43  CGEN_INSN_INT         buffer [1];
44#define INSN_VALUE(buf) (*(buf))
45#else
46  unsigned char         buffer [CGEN_MAX_INSN_SIZE];
47#define INSN_VALUE(buf) (buf)
48#endif
49  char *		addr;
50  fragS *		frag;
51  int                   num_fixups;
52  fixS *                fixups [GAS_CGEN_MAX_FIXUPS];
53  int                   indices [MAX_OPERAND_INSTANCES];
54}
55iq2000_insn;
56
57const char comment_chars[]        = "#";
58const char line_comment_chars[]   = "#";
59const char line_separator_chars[] = ";";
60const char EXP_CHARS[]            = "eE";
61const char FLT_CHARS[]            = "dD";
62
63/* Default machine.  */
64#define DEFAULT_MACHINE bfd_mach_iq2000
65#define DEFAULT_FLAGS	EF_IQ2000_CPU_IQ2000
66
67static unsigned long iq2000_mach = bfd_mach_iq2000;
68static int cpu_mach = (1 << MACH_IQ2000);
69
70/* Flags to set in the elf header.  */
71static flagword iq2000_flags = DEFAULT_FLAGS;
72
73typedef 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
85static procS cur_proc;
86static procS *cur_proc_ptr;
87static 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
100struct 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.  */
108static struct iq2000_hi_fixup * iq2000_hi_fixup_list;
109
110/* Macro hash table, which we will add to.  */
111extern struct hash_control *macro_hash;
112
113const char *md_shortopts = "";
114struct option md_longopts[] =
115{
116  {NULL, no_argument, NULL, 0}
117};
118size_t md_longopts_size = sizeof (md_longopts);
119
120int
121md_parse_option (int c ATTRIBUTE_UNUSED,
122		 char * arg ATTRIBUTE_UNUSED)
123{
124  return 0;
125}
126
127void
128md_show_usage (FILE * stream ATTRIBUTE_UNUSED)
129{
130}
131
132/* Automatically enter conditional branch macros.  */
133
134typedef struct
135{
136  const char * mnemonic;
137  const char ** expansion;
138  const char ** args;
139} iq2000_macro_defs_s;
140
141static const char * abs_args[] = { "rd", "rs", "scratch=%1", NULL };
142static const char * abs_expn   = "\n sra \\rd,\\rs,31\n xor \\scratch,\\rd,\\rs\n sub \\rd,\\scratch,\\rd\n";
143static const char * la_expn    = "\n lui \\reg,%hi(\\label)\n ori \\reg,\\reg,%lo(\\label)\n";
144static const char * la_args[]  = { "reg", "label", NULL };
145static const char * bxx_args[] = { "rs", "rt", "label", "scratch=%1", NULL };
146static const char * bge_expn   = "\n slt \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
147static const char * bgeu_expn  = "\n sltu \\scratch,\\rs,\\rt\n beq %0,\\scratch,\\label\n";
148static const char * bgt_expn   = "\n slt \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
149static const char * bgtu_expn  = "\n sltu \\scratch,\\rt,\\rs\n bne %0,\\scratch,\\label\n";
150static const char * ble_expn   = "\n slt \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
151static const char * bleu_expn  = "\n sltu \\scratch,\\rt,\\rs\n beq %0,\\scratch,\\label\n";
152static const char * blt_expn   = "\n slt \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
153static const char * bltu_expn  = "\n sltu \\scratch,\\rs,\\rt\n bne %0,\\scratch,\\label\n";
154static const char * sxx_args[] = { "rd", "rs", "rt", NULL };
155static const char * sge_expn   = "\n slt \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
156static const char * sgeu_expn  = "\n sltu \\rd,\\rs,\\rt\n xori \\rd,\\rd,1\n";
157static const char * sle_expn   = "\n slt \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
158static const char * sleu_expn  = "\n sltu \\rd,\\rt,\\rs\n xori \\rd,\\rd,1\n";
159static const char * sgt_expn   = "\n slt \\rd,\\rt,\\rs\n";
160static const char * sgtu_expn  = "\n sltu \\rd,\\rt,\\rs\n";
161static const char * sne_expn   = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n";
162static const char * seq_expn   = "\n xor \\rd,\\rt,\\rs\n sltu \\rd,%0,\\rd\n xori \\rd,\\rd,1\n";
163static const char * ai32_args[] = { "rt", "rs", "imm", NULL };
164static 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";
175static 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
185static const char * neg_args[] = { "rd", "rs", NULL };
186static const char * neg_expn   = "\n sub \\rd,%0,\\rs\n";
187static const char * negu_expn  = "\n subu \\rd,%0,\\rs\n";
188static const char * li_args[]  = { "rt", "imm", NULL };
189static 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
201static 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
228static void
229iq2000_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
295static void
296iq2000_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
307void
308md_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
332void
333md_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
432valueT
433md_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
439symbolS *
440md_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
458int
459md_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
480void
481md_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
490long
491md_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
510bfd_reloc_code_real_type
511md_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
530static void
531iq2000_record_hi16 (int    reloc_type,
532		    fixS * fixP,
533		    segT   seg ATTRIBUTE_UNUSED)
534{
535  struct iq2000_hi_fixup * hi_fixup;
536
537  gas_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
550fixS *
551iq2000_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_fix and
578   tc_gen_reloc.  */
579
580void
581iq2000_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      gas_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		    gas_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
658int
659iq2000_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
670static void
671s_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
714void
715md_number_to_chars (char * buf, valueT val, int n)
716{
717  number_to_chars_bigendian (buf, val, n);
718}
719
720void
721md_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
728char *
729md_atof (int type, char * litP, int * sizeP)
730{
731  return ieee_md_atof (type, litP, sizeP, TRUE);
732}
733
734bfd_boolean
735iq2000_fix_adjustable (fixS * fixP)
736{
737  bfd_reloc_code_real_type reloc_type;
738
739  if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
740    {
741      const CGEN_INSN *insn = NULL;
742      int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
743      const CGEN_OPERAND *operand = cgen_operand_lookup_by_num(gas_cgen_cpu_desc, opindex);
744
745      reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
746    }
747  else
748    reloc_type = fixP->fx_r_type;
749
750  if (fixP->fx_addsy == NULL)
751    return TRUE;
752
753  /* Prevent all adjustments to global symbols.  */
754  if (S_IS_EXTERNAL (fixP->fx_addsy))
755    return FALSE;
756
757  if (S_IS_WEAK (fixP->fx_addsy))
758    return FALSE;
759
760  /* We need the symbol name for the VTABLE entries.  */
761  if (   reloc_type == BFD_RELOC_VTABLE_INHERIT
762      || reloc_type == BFD_RELOC_VTABLE_ENTRY)
763    return FALSE;
764
765  return TRUE;
766}
767
768static void
769s_change_sec (int sec)
770{
771#ifdef OBJ_ELF
772  /* The ELF backend needs to know that we are changing sections, so
773     that .previous works correctly.  We could do something like check
774     for a obj_section_change_hook macro, but that might be confusing
775     as it would not be appropriate to use it in the section changing
776     functions in read.c, since obj-elf.c intercepts those.  FIXME:
777     This should be cleaner, somehow.  */
778  obj_elf_section_change_hook ();
779#endif
780
781  switch (sec)
782    {
783    case 't':
784      s_text (0);
785      break;
786    case 'd':
787    case 'r':
788      s_data (0);
789      break;
790    }
791}
792
793static symbolS *
794get_symbol (void)
795{
796  int c;
797  char *name;
798  symbolS *p;
799
800  name = input_line_pointer;
801  c = get_symbol_end ();
802  p = (symbolS *) symbol_find_or_make (name);
803  *input_line_pointer = c;
804  return p;
805}
806
807/* The .end directive.  */
808
809static void
810s_iq2000_end (int x ATTRIBUTE_UNUSED)
811{
812  symbolS *p;
813  int maybe_text;
814
815  if (!is_end_of_line[(unsigned char) *input_line_pointer])
816    {
817      p = get_symbol ();
818      demand_empty_rest_of_line ();
819    }
820  else
821    p = NULL;
822
823  if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
824    maybe_text = 1;
825  else
826    maybe_text = 0;
827
828  if (!maybe_text)
829    as_warn (_(".end not in text section"));
830
831  if (!cur_proc_ptr)
832    {
833      as_warn (_(".end directive without a preceding .ent directive."));
834      demand_empty_rest_of_line ();
835      return;
836    }
837
838  if (p != NULL)
839    {
840      gas_assert (S_GET_NAME (p));
841      if (strcmp (S_GET_NAME (p), S_GET_NAME (cur_proc_ptr->isym)))
842	as_warn (_(".end symbol does not match .ent symbol."));
843    }
844  else
845    as_warn (_(".end directive missing or unknown symbol"));
846
847  cur_proc_ptr = NULL;
848}
849
850static int
851get_number (void)
852{
853  int negative = 0;
854  long val = 0;
855
856  if (*input_line_pointer == '-')
857    {
858      ++input_line_pointer;
859      negative = 1;
860    }
861
862  if (! ISDIGIT (*input_line_pointer))
863    as_bad (_("Expected simple number."));
864
865  if (input_line_pointer[0] == '0')
866    {
867      if (input_line_pointer[1] == 'x')
868	{
869	  input_line_pointer += 2;
870	  while (ISXDIGIT (*input_line_pointer))
871	    {
872	      val <<= 4;
873	      val |= hex_value (*input_line_pointer++);
874	    }
875	  return negative ? -val : val;
876	}
877      else
878	{
879	  ++input_line_pointer;
880
881	  while (ISDIGIT (*input_line_pointer))
882	    {
883	      val <<= 3;
884	      val |= *input_line_pointer++ - '0';
885	    }
886	  return negative ? -val : val;
887	}
888    }
889
890  if (! ISDIGIT (*input_line_pointer))
891    {
892      printf (_(" *input_line_pointer == '%c' 0x%02x\n"),
893	      *input_line_pointer, *input_line_pointer);
894      as_warn (_("Invalid number"));
895      return -1;
896    }
897
898  while (ISDIGIT (*input_line_pointer))
899    {
900      val *= 10;
901      val += *input_line_pointer++ - '0';
902    }
903
904  return negative ? -val : val;
905}
906
907/* The .aent and .ent directives.  */
908
909static void
910s_iq2000_ent (int aent)
911{
912  symbolS *symbolP;
913  int maybe_text;
914
915  symbolP = get_symbol ();
916  if (*input_line_pointer == ',')
917    input_line_pointer++;
918  SKIP_WHITESPACE ();
919  if (ISDIGIT (*input_line_pointer) || *input_line_pointer == '-')
920    get_number ();
921
922  if ((bfd_get_section_flags (stdoutput, now_seg) & SEC_CODE) != 0)
923    maybe_text = 1;
924  else
925    maybe_text = 0;
926
927  if (!maybe_text)
928    as_warn (_(".ent or .aent not in text section."));
929
930  if (!aent && cur_proc_ptr)
931    as_warn (_("missing `.end'"));
932
933  if (!aent)
934    {
935      cur_proc_ptr = &cur_proc;
936      memset (cur_proc_ptr, '\0', sizeof (procS));
937
938      cur_proc_ptr->isym = symbolP;
939
940      symbol_get_bfdsym (symbolP)->flags |= BSF_FUNCTION;
941
942      numprocs++;
943    }
944
945  demand_empty_rest_of_line ();
946}
947
948/* The .frame directive. If the mdebug section is present (IRIX 5 native)
949   then ecoff.c (ecoff_directive_frame) is used. For embedded targets,
950   s_iq2000_frame is used so that we can set the PDR information correctly.
951   We can't use the ecoff routines because they make reference to the ecoff
952   symbol table (in the mdebug section).  */
953
954static void
955s_iq2000_frame (int ignore)
956{
957  s_ignore (ignore);
958}
959
960/* The .fmask and .mask directives. If the mdebug section is present
961   (IRIX 5 native) then ecoff.c (ecoff_directive_mask) is used. For
962   embedded targets, s_iq2000_mask is used so that we can set the PDR
963   information correctly. We can't use the ecoff routines because they
964   make reference to the ecoff symbol table (in the mdebug section).  */
965
966static void
967s_iq2000_mask (int reg_type)
968{
969  s_ignore (reg_type);
970}
971
972/* The target specific pseudo-ops which we support.  */
973const pseudo_typeS md_pseudo_table[] =
974{
975    { "align",  s_align_bytes,           0 },
976    { "word",   cons,                    4 },
977    { "rdata",  s_change_sec, 		'r'},
978    { "sdata",  s_change_sec, 		's'},
979    { "set",	s_iq2000_set,		 0 },
980    { "ent",    s_iq2000_ent, 		 0 },
981    { "end",    s_iq2000_end,            0 },
982    { "frame",  s_iq2000_frame, 	 0 },
983    { "fmask",  s_iq2000_mask, 		'F'},
984    { "mask",   s_iq2000_mask, 		'R'},
985    { "dword",	cons, 			 8 },
986    { "half",	cons, 			 2 },
987    { NULL, 	NULL,			 0 }
988};
989