xref: /netbsd-src/external/gpl3/binutils.old/dist/gas/config/tc-epiphany.c (revision 04028aa9310ca9c619eca5cf58ddf1e58624d1d7)
1 /* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
2    Copyright 2009, 2011 Free Software Foundation, Inc.
3    Contributed by Embecosm on behalf of Adapteva, 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 "subsegs.h"
24 #include "symcat.h"
25 #include "opcodes/epiphany-desc.h"
26 #include "opcodes/epiphany-opc.h"
27 #include "cgen.h"
28 #include "elf/common.h"
29 #include "elf/epiphany.h"
30 #include "dwarf2dbg.h"
31 #include "libbfd.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 epiphany_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[]            = "fFdD";
60 
61 /* Flag to detect when switching to code section where insn alignment is
62    implied.  */
63 static bfd_boolean force_code_align = FALSE;
64 
65 static void
66 epiphany_elf_section_rtn (int i)
67 {
68   obj_elf_section (i);
69 
70   if (force_code_align)
71     {
72       /* The s_align_ptwo function expects that we are just after a .align
73 	 directive and it will either try and read the align value or stop
74 	 if end of line so we must fake it out so it thinks we are at the
75 	 end of the line.  */
76       char *old_input_line_pointer = input_line_pointer;
77 
78       input_line_pointer = "\n";
79       s_align_ptwo (1);
80       force_code_align = FALSE;
81 
82       /* Restore.  */
83       input_line_pointer = old_input_line_pointer;
84     }
85 }
86 
87 static void
88 epiphany_elf_section_text (int i)
89 {
90   char *old_input_line_pointer;
91 
92   obj_elf_text (i);
93 
94   /* The s_align_ptwo function expects that we are just after a .align
95      directive and it will either try and read the align value or stop if
96      end of line so we must fake it out so it thinks we are at the end of
97      the line.  */
98   old_input_line_pointer = input_line_pointer;
99   input_line_pointer = "\n";
100   s_align_ptwo (1);
101   force_code_align = FALSE;
102   /* Restore.  */
103   input_line_pointer = old_input_line_pointer;
104 }
105 
106 /* The target specific pseudo-ops which we support.  */
107 const pseudo_typeS md_pseudo_table[] =
108 {
109     { "text",   epiphany_elf_section_text,  0 },
110     { "sect",   epiphany_elf_section_rtn,   0 },
111     /* .word should be 32 bits.  */
112     { "word",       cons, 4 },
113     { "cpu",        s_ignore,         0 },
114     { "thumb_func", s_ignore,         0 },
115     { "code",       s_ignore,         0 },
116     { NULL,         NULL,             0 }
117 };
118 
119 
120 
121 enum options
122 {
123   OPTION_CPU_EPIPHANY = OPTION_MD_BASE,
124   OPTION_CPU_EPIPHANY16
125 };
126 
127 struct option md_longopts[] =
128 {
129   { "mepiphany ",  no_argument, NULL, OPTION_CPU_EPIPHANY },
130   { "mepiphany16", no_argument, NULL, OPTION_CPU_EPIPHANY16 },
131   { NULL,          no_argument, NULL, 0 },
132 };
133 
134 size_t md_longopts_size = sizeof (md_longopts);
135 
136 const char * md_shortopts = "";
137 
138 int
139 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
140 {
141   return 0;	/* No target-specific options.  */
142 }
143 
144 void
145 md_show_usage (FILE * stream)
146 {
147   fprintf (stream, _("EPIPHANY specific command line options:\n"));
148 }
149 
150 
151 void
152 md_begin (void)
153 {
154   /* Initialize the `cgen' interface.  */
155 
156   /* Set the machine number and endian.  */
157   gas_cgen_cpu_desc = epiphany_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
158 					   bfd_mach_epiphany32,
159 					   CGEN_CPU_OPEN_ENDIAN,
160 					   CGEN_ENDIAN_LITTLE,
161 					   CGEN_CPU_OPEN_END);
162   epiphany_cgen_init_asm (gas_cgen_cpu_desc);
163 
164   /* This is a callback from cgen to gas to parse operands.  */
165   cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
166 
167   /* Set the machine type.  */
168   bfd_default_set_arch_mach (stdoutput, bfd_arch_epiphany, bfd_mach_epiphany32);
169 }
170 
171 valueT
172 md_section_align (segT segment, valueT size)
173 {
174   int align = bfd_get_section_alignment (stdoutput, segment);
175 
176   return ((size + (1 << align) - 1) & (-1 << align));
177 }
178 
179 
180 /* Functions concerning relocs.  */
181 
182 long
183 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
184 {
185   abort ();
186 }
187 
188 /* Write a value out to the object file, using the appropriate endianness.  */
189 
190 void
191 md_number_to_chars (char * buf, valueT val, int n)
192 {
193   number_to_chars_littleendian (buf, val, n);
194 }
195 
196 int
197 epiphany_elf_section_flags (int flags,
198 			    int attr ATTRIBUTE_UNUSED,
199 			    int type ATTRIBUTE_UNUSED)
200 {
201   /* This is used to detect when the section changes to an executable section.
202      This function is called by the elf section processing.  When we note an
203      executable section specifier we set an internal flag to denote when
204      word alignment should be forced.  */
205   if (flags & SEC_CODE)
206     force_code_align = TRUE;
207 
208   return flags;
209 }
210 
211 /* Non-zero if we are generating PIC code.  */
212 int pic_code;
213 
214 /* Epiphany er_flags.  */
215 static int epiphany_flags = 0;
216 
217 /* Relocations against symbols are done in two
218    parts, with a HI relocation and a LO relocation.  Each relocation
219    has only 16 bits of space to store an addend.  This means that in
220    order for the linker to handle carries correctly, it must be able
221    to locate both the HI and the LO relocation.  This means that the
222    relocations must appear in order in the relocation table.
223 
224    In order to implement this, we keep track of each unmatched HI
225    relocation.  We then sort them so that they immediately precede the
226    corresponding LO relocation.  */
227 
228 struct epiphany_hi_fixup
229 {
230   /* Next HI fixup.  */
231   struct epiphany_hi_fixup *next;
232 
233   /* This fixup.  */
234   fixS *fixp;
235 
236   /* The section this fixup is in.  */
237   segT seg;
238 };
239 
240 
241 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
242 static symbolS * GOT_symbol;
243 
244 static inline bfd_boolean
245 epiphany_PIC_related_p (symbolS *sym)
246 {
247   expressionS *exp;
248 
249   if (! sym)
250     return FALSE;
251 
252   if (sym == GOT_symbol)
253     return TRUE;
254 
255   exp = symbol_get_value_expression (sym);
256 
257   return (exp->X_op == O_PIC_reloc
258 	  || exp->X_md == BFD_RELOC_EPIPHANY_SIMM24
259 	  || exp->X_md == BFD_RELOC_EPIPHANY_SIMM8
260 	  || epiphany_PIC_related_p (exp->X_add_symbol)
261 	  || epiphany_PIC_related_p (exp->X_op_symbol));
262 }
263 
264 /* Perform target dependent relocations that are done at compile time.
265    There aren't very many of these.  */
266 
267 void
268 epiphany_apply_fix (fixS *fixP, valueT *valP, segT seg)
269 {
270   if (fixP->fx_addsy == (symbolS *) NULL)
271     fixP->fx_done = 1;
272 
273   if (((int) fixP->fx_r_type < (int) BFD_RELOC_UNUSED)
274       && fixP->fx_done)
275     {
276       /* Install EPIPHANY-dependent relocations HERE because nobody else
277 	 will.  */
278       char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
279       unsigned char *insn = (unsigned char *)where;
280       valueT value = * valP;
281 
282       switch (fixP->fx_r_type)
283 	{
284 	default:
285 	  break;
286 
287 	case BFD_RELOC_NONE:
288 	  return;
289 
290 	case BFD_RELOC_EPIPHANY_SIMM11:
291 	  where[0] = where[0] | ((value & 1) << 7);
292 	  where[1] = where[1] | ((value & 6) >> 1);
293 	  where[2] = (value >> 3) & 0xff;
294 	  return;
295 
296 	case BFD_RELOC_EPIPHANY_IMM11:
297 	  where[0] = where[0] | ((value & 1) << 7);
298 	  where[1] = where[1] | ((value & 6) >> 1);
299 	  where[2] = (value >> 3) & 0xff;
300 	  return;
301 
302 	case BFD_RELOC_EPIPHANY_SIMM8:
303 	  md_number_to_chars (where+1, value>>1, 1);
304 	  return;
305 
306 	case BFD_RELOC_EPIPHANY_SIMM24:
307 	  md_number_to_chars (where+1, value>>1, 3);
308 	  return;
309 
310 	case BFD_RELOC_EPIPHANY_HIGH:
311 	  value >>= 16;
312 	  /* fall thru */
313 	case BFD_RELOC_EPIPHANY_LOW:
314 	  value = (((value & 0xff) << 5) | insn[0])
315 	    | (insn[1] << 8)
316 	    | ((value & 0xff00) << 12)
317 	    | (insn[2] << 16);
318 	  md_number_to_chars (where, value, 3);
319 	  return;
320 	}
321     }
322 
323   /* Just do the default if we can't special case.  */
324   return gas_cgen_md_apply_fix (fixP, valP, seg);
325 }
326 
327 
328 /* This is called from HANDLE_ALIGN in write.c.  Fill in the contents
329    of an rs_align_code fragment.  0x01a2 is 16-bit pattern for a "nop".  */
330 
331 static const unsigned char nop_pattern[] = { 0xa2, 0x01 };
332 
333 void
334 epiphany_handle_align (fragS *fragp)
335 {
336   int bytes, fix;
337   char *p;
338 
339   if (fragp->fr_type != rs_align_code)
340     return;
341 
342   bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
343   p = fragp->fr_literal + fragp->fr_fix;
344   fix = 0;
345 
346   if (bytes & 1)
347     {
348       fix = 1;
349       *p++ = 0;
350       bytes--;
351     }
352 
353   if (bytes & 2)
354     {
355       memcpy (p, nop_pattern, 2);
356       p += 2;
357       bytes -= 2;
358       fix += 2;
359     }
360   fragp->fr_fix += fix;
361 }
362 
363 /* Read a comma separated incrementing list of register names
364    and form a bit mask of upto 15 registers 0..14.  */
365 
366 static const char *
367 parse_reglist (const char * s, int * mask)
368 {
369   int regmask = 0;
370 
371   while (*s)
372     {
373       long value;
374 
375       while (*s == ' ')
376 	++s;
377 
378       /* Parse a list with "," or "}" as limiters.  */
379       const char *errmsg
380 	= cgen_parse_keyword (gas_cgen_cpu_desc, &s,
381 			      &epiphany_cgen_opval_gr_names, &value);
382       if (errmsg)
383 	return errmsg;
384 
385       if (value > 15)
386 	return _("register number too large for push/pop");
387 
388       regmask |= 1 << value;
389       if (regmask < *mask)
390 	return _("register is out of order");
391       *mask |= regmask;
392 
393       while (*s==' ')
394 	++s;
395 
396       if (*s == '}')
397 	return NULL;
398       else if (*s++ == ',')
399 	continue;
400       else
401 	return _("bad register list");
402     }
403 
404   return _("malformed reglist in push/pop");
405 }
406 
407 
408 void
409 md_assemble (char *str)
410 {
411   epiphany_insn insn;
412   char *errmsg = 0;
413   const char * pperr = 0;
414   int regmask=0, push=0, pop=0;
415 
416   memset (&insn, 0, sizeof (insn));
417 
418   /* Special-case push/pop instruction macros.  */
419   if (0 == strncmp (str, "push {", 6))
420     {
421       char * s = str + 6;
422       push = 1;
423       pperr = parse_reglist (s, &regmask);
424     }
425   else if (0 == strncmp (str, "pop {", 5))
426     {
427       char * s = str + 5;
428       pop = 1;
429       pperr = parse_reglist (s, &regmask);
430     }
431 
432   if (pperr)
433     {
434       as_bad ("%s", pperr);
435       return;
436     }
437 
438   if (push && regmask)
439     {
440       char buff[20];
441       int i,p ATTRIBUTE_UNUSED;
442 
443       md_assemble ("mov r15,4");
444       md_assemble ("sub sp,sp,r15");
445 
446       for (i = 0, p = 1; i <= 15; ++i, regmask >>= 1)
447 	{
448 	  if (regmask == 1)
449 	    sprintf (buff, "str r%d,[sp]", i); /* Last one.  */
450 	  else if (regmask & 1)
451 	    sprintf (buff, "str r%d,[sp],-r15", i);
452 	  else
453 	    continue;
454 	  md_assemble (buff);
455 	}
456       return;
457     }
458   else if (pop && regmask)
459     {
460       char buff[20];
461       int i,p;
462 
463       md_assemble ("mov r15,4");
464 
465       for (i = 15, p = 1 << 15; i >= 0; --i, p >>= 1)
466 	if (regmask & p)
467 	  {
468 	    sprintf (buff, "ldr r%d,[sp],+r15", i);
469 	    md_assemble (buff);
470 	  }
471       return;
472     }
473 
474   /* Initialize GAS's cgen interface for a new instruction.  */
475   gas_cgen_init_parse ();
476 
477   insn.insn = epiphany_cgen_assemble_insn
478     (gas_cgen_cpu_desc, str, &insn.fields, insn.buffer, & errmsg);
479 
480   if (!insn.insn)
481     {
482       as_bad ("%s", errmsg);
483       return;
484     }
485 
486   if (CGEN_INSN_BITSIZE (insn.insn) == 32)
487     {
488       /* Doesn't really matter what we pass for RELAX_P here.  */
489       gas_cgen_finish_insn (insn.insn, insn.buffer,
490 			    CGEN_FIELDS_BITSIZE (&insn.fields), 1, NULL);
491     }
492   else
493     {
494       if (CGEN_INSN_BITSIZE (insn.insn) != 16)
495 	abort ();
496 
497       insn.orig_insn = insn.insn;
498 
499       gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
500 			    CGEN_FIELDS_BITSIZE (&insn.fields),
501 			    1 /* relax_p  */, NULL);
502     }
503 
504   /* Checks for behavioral restrictions on LD/ST instructions.  */
505 #define DISPMOD _("destination register modified by displacement-post-modified address")
506 #define LDSTODD _("ldrd/strd requires even:odd register pair")
507 
508   /* Helper macros for spliting apart instruction fields.  */
509 #define ADDR_POST_MODIFIED(i) (((i) >> 25) & 0x1)
510 #define ADDR_SIZE(i)          (((i) >>  5) &   3)
511 #define ADDR_LOADSTORE(i)     (((i) >>  4) & 0x1)
512 
513   switch (insn.buffer[0] & 0xf)
514     {
515       /* Post-modify registers cannot be destinations.  */
516     case OP4_LDSTR16P:
517       {
518 	if (ADDR_LOADSTORE (insn.buffer[0]) ==  OP_LOAD)
519 	  if (insn.fields.f_rd == insn.fields.f_rn /* Postmodify dest.  */
520 	      || (insn.fields.f_rd+1 == insn.fields.f_rn
521 		  && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE))
522 	    {
523 	      as_bad ("%s", DISPMOD);
524 	      return;
525 	    }
526 	if ((insn.fields.f_rd & 1) /* Odd-numbered register...  */
527 	    && insn.fields.f_wordsize == OPW_DOUBLE) /* ...and 64 bit transfer.  */
528 	  {
529 	    as_bad ("%s", LDSTODD);
530 	    return;
531 	  }
532 	break;
533       }
534 
535     case OP4_LDSTRP:
536       {
537 	if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD) /* A load.  */
538 	  if (insn.fields.f_rd6 == insn.fields.f_rn6 /* Postmodify dest.  */
539 	      /* Check for regpair postindexed.  */
540 	      || (insn.fields.f_rd6 + 1 == insn.fields.f_rn6
541 		  && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE))
542 	    {
543 	      as_bad ("%s", DISPMOD);
544 	      return;
545 	    }
546 	if ((insn.fields.f_rd6 & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
547 	  /* Lsb of RD odd and 64 bit transfer.  */
548 	  {
549 	    as_bad ("%s", LDSTODD);
550 	    return;
551 	  }
552 	break;
553       }
554 
555     case OP4_LDSTR16X:
556     case OP4_LDSTR16D:
557       {
558 	/* Check for unaligned load/store double.  */
559 	if ((insn.fields.f_rd & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
560 	  /* Lsb of RD odd and 64 bit transfer.  */
561 	  {
562 	    as_bad ("%s", LDSTODD);
563 	    return;
564 	  }
565 	break;
566       }
567 
568     case OP4_LDSTRD:
569       {
570 	/* Check for load to post-modified register.  */
571 	if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD /* A load.  */
572 	    && ADDR_POST_MODIFIED (insn.buffer[0]) == PMOD_POST /* Post-mod.  */
573 	    && (insn.fields.f_rd6 == insn.fields.f_rn6
574 		|| (insn.fields.f_rd6+1 == insn.fields.f_rn6
575 		    && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)))
576 	  {
577 	    as_bad ("%s", DISPMOD);
578 	    return;
579 	  }
580       }
581       /* fall-thru.  */
582 
583     case OP4_LDSTRX:
584       {
585 	/* Check for unaligned load/store double.  */
586 	if ((insn.fields.f_rd6 & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
587 	  {
588 	    as_bad ("%s", LDSTODD);
589 	    return;
590 	  }
591 	break;
592       }
593 
594     default:
595       break;
596     }
597 }
598 
599 /* The syntax in the manual says constants begin with '#'.
600    We just ignore it.  */
601 
602 void
603 md_operand (expressionS *expressionP)
604 {
605   if (*input_line_pointer == '#')
606     {
607       input_line_pointer++;
608       expression (expressionP);
609     }
610 }
611 
612 symbolS *
613 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
614 {
615   return NULL;
616 }
617 
618 /* Interface to relax_segment.  */
619 
620 /* FIXME: Build table by hand, get it working, then machine generate.  */
621 
622 const relax_typeS md_relax_table[] =
623 {
624   /* The fields are:
625      1) most positive reach of this state,
626      2) most negative reach of this state,
627      3) how many bytes this mode will add to the size of the current frag
628      4) which index into the table to try if we can't fit into this one.  */
629 
630   /* The first entry must be unused because an `rlx_more' value of zero ends
631      each list.  */
632   {1, 1, 0, EPIPHANY_RELAX_NONE},
633   {0, 0, 0, EPIPHANY_RELAX_NONE},    /* Also a dummy entry to indicate we need to expand codes.  */
634 
635   /* The displacement used by GAS is from the end of the 2 byte insn,
636      so we subtract 2 from the following.  */
637   /* 16 bit insn, 8 bit disp -> +127 words, -128 words.  */
638   {0x00000100 - 1 - 2, -0x00000100 - 2, 0, EPIPHANY_RELAX_BRANCH_LONG },
639   /* 32 bit insn, 24 bit disp -> 25 bit range.  */
640   {0x01000000 - 1 - 2, -0x01000000 - 2, 2, EPIPHANY_RELAX_NONE },
641 
642   /* addi/subi 3 bits -4..+3.  */
643   {    3,           -4,0, EPIPHANY_RELAX_ARITH_SIMM11 },
644   /* addi/subi 11 bits.  */
645   {  1023,       -1024,2, EPIPHANY_RELAX_NONE },
646 
647   /* mov r,imm8.  */
648   {   255,           0,0, EPIPHANY_RELAX_MOV_IMM16 },
649   /* mov r,imm16. */
650   { 65535,           0,2, EPIPHANY_RELAX_NONE },
651 
652   /* ld/st rd,[rn,imm3].  */
653   {     7,           0,0, EPIPHANY_RELAX_LDST_IMM11},
654   /* ld/st rd,[rn,imm11].  */
655   {  2047,           0,2, EPIPHANY_RELAX_NONE }
656 
657 };
658 
659 static const EPIPHANY_RELAX_TYPES relax_insn[] =
660 {
661   EPIPHANY_RELAX_BRANCH_SHORT,	/* OP4_BRANCH16 */
662   EPIPHANY_RELAX_NONE,		/* OP4_LDSTR16X */
663   EPIPHANY_RELAX_NONE,		/* OP4_FLOW16 */
664   EPIPHANY_RELAX_ARITH_SIMM3,	/* OP4_IMM16 - special */
665   EPIPHANY_RELAX_LDST_IMM3,	/* OP4_LDSTR16D */
666   EPIPHANY_RELAX_NONE,		/* OP4_LDSTR126P */
667   EPIPHANY_RELAX_NONE,		/* OP4_LSHIFT16 */
668   EPIPHANY_RELAX_NONE,		/* OP4_DSP16 */
669   EPIPHANY_RELAX_BRANCH_LONG,	/* OP4_BRANCH */
670   EPIPHANY_RELAX_NONE,		/* OP4_LDSTRX */
671   EPIPHANY_RELAX_NONE,		/* OP4_ALU16 */
672   EPIPHANY_RELAX_ARITH_SIMM11,	/* OP4_IMM32 - special */
673   EPIPHANY_RELAX_LDST_IMM11,	/* OP4_LDSTRD */
674   EPIPHANY_RELAX_NONE,		/* OP4_LDSTRP */
675   EPIPHANY_RELAX_NONE,		/* OP4_ASHIFT16 */
676   EPIPHANY_RELAX_NONE		/* OP4_MISC */
677 };
678 
679 long
680 epiphany_relax_frag (segT segment, fragS *fragP, long stretch)
681 {
682   /* Address of branch insn.  */
683   long address ATTRIBUTE_UNUSED = fragP->fr_address + fragP->fr_fix - 2;
684   long growth = 0;
685 
686   if (fragP->fr_subtype == EPIPHANY_RELAX_NEED_RELAXING)
687     {
688       EPIPHANY_RELAX_TYPES subtype = relax_insn [*fragP->fr_opcode & 0xf];
689 
690       /* Special cases add/sub vs mov immediates.  */
691       if (subtype == EPIPHANY_RELAX_ARITH_SIMM3)
692 	{
693 	  if ((*fragP->fr_opcode & 0x10) == 0)
694 	    subtype = EPIPHANY_RELAX_MOV_IMM8;
695 	}
696       else if (subtype == EPIPHANY_RELAX_ARITH_SIMM11)
697 	{
698 	  if ((*fragP->fr_opcode & 0x10) == 0)
699 	    subtype = EPIPHANY_RELAX_MOV_IMM16;
700 	}
701 
702       /* Remember refinements for the future.  */
703       fragP->fr_subtype = subtype;
704     }
705 
706   growth = relax_frag (segment, fragP, stretch);
707 
708   return growth;
709 }
710 
711 /* Return an initial guess of the length by which a fragment must grow to
712    hold a branch to reach its destination.
713    Also updates fr_type/fr_subtype as necessary.
714 
715    Called just before doing relaxation.
716    Any symbol that is now undefined will not become defined.
717    The guess for fr_var is ACTUALLY the growth beyond fr_fix.
718    Whatever we do to grow fr_fix or fr_var contributes to our returned value.
719    Although it may not be explicit in the frag, pretend fr_var starts
720    with a 0 value.  */
721 
722 int
723 md_estimate_size_before_relax (fragS *fragP, segT segment)
724 {
725   /* The only thing we have to handle here are symbols outside of the
726      current segment.  They may be undefined or in a different segment in
727      which case linker scripts may place them anywhere.
728      However, we can't finish the fragment here and emit the reloc as insn
729      alignment requirements may move the insn about.  */
730   if (S_GET_SEGMENT (fragP->fr_symbol) != segment
731       || S_IS_EXTERNAL (fragP->fr_symbol)
732       || S_IS_WEAK (fragP->fr_symbol))
733     {
734       /* The symbol is undefined in this segment.  Change the
735 	 relaxation subtype to the max allowable and leave all further
736 	 handling to md_convert_frag.  */
737 
738       EPIPHANY_RELAX_TYPES subtype;
739       /* We haven't relaxed this at all, so the relaxation type may be
740 	 completely wrong.  Set the subtype correctly.  */
741       epiphany_relax_frag (segment, fragP, 0);
742       subtype = fragP->fr_subtype;
743 
744       switch (subtype)
745 	{
746 	case EPIPHANY_RELAX_LDST_IMM3:
747 	  subtype = EPIPHANY_RELAX_LDST_IMM11;
748 	  break;
749 	case EPIPHANY_RELAX_BRANCH_SHORT:
750 	  subtype = EPIPHANY_RELAX_BRANCH_LONG;
751 	  break;
752 	case EPIPHANY_RELAX_MOV_IMM8:
753 	  subtype = EPIPHANY_RELAX_MOV_IMM16;
754 	  break;
755 	case EPIPHANY_RELAX_ARITH_SIMM3:
756 	  subtype = EPIPHANY_RELAX_ARITH_SIMM11;
757 	  break;
758 
759 	default:
760 	  break;
761 	}
762 
763       fragP->fr_subtype = subtype;
764 
765       {
766 	const CGEN_INSN *insn;
767 	int i;
768 
769 	/* Update the recorded insn.  */
770 
771 	for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
772 	  {
773 	    if ((strcmp (CGEN_INSN_MNEMONIC (insn),
774 			 CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
775 		 == 0)
776 		&& CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
777 	      break;
778 	  }
779 
780 	if (i == 4)
781 	  abort ();
782 
783 	fragP->fr_cgen.insn = insn;
784       }
785     }
786 
787   return md_relax_table[fragP->fr_subtype].rlx_length;
788 }
789 
790 /* *FRAGP has been relaxed to its final size, and now needs to have
791    the bytes inside it modified to conform to the new size.
792 
793    Called after relaxation is finished.
794    fragP->fr_type == rs_machine_dependent.
795    fragP->fr_subtype is the subtype of what the address relaxed to.  */
796 
797 void
798 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
799 		 segT sec,
800 		 fragS *fragP)
801 {
802   char *opcode;
803   char *displacement;
804   int target_address;
805   int opcode_address;
806   int extension;
807   int addend;
808   int opindx = -1;
809 
810   opcode = fragP->fr_opcode;
811 
812   /* Address opcode resides at in file space.  */
813   opcode_address = fragP->fr_address + fragP->fr_fix - 2;
814   extension = 0;
815   displacement = &opcode[1];
816 
817   /* Set up any addend necessary for branches.  */
818   if (S_GET_SEGMENT (fragP->fr_symbol) != sec
819       || S_IS_EXTERNAL (fragP->fr_symbol)
820       || S_IS_WEAK (fragP->fr_symbol))
821     {
822       /* Symbol must be resolved by linker.  */
823       if (fragP->fr_offset & 1)
824 	as_warn (_("Addend to unresolved symbol not on word boundary."));
825       addend = 0;
826     }
827   else
828     {
829       /* Address we want to reach in file space.  */
830       target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
831       addend = (target_address - (opcode_address & -2));
832     }
833 
834   /* Do all the housekeeping for frag conversions. */
835   switch (fragP->fr_subtype)
836     {
837     case EPIPHANY_RELAX_ARITH_SIMM11:
838       *opcode |= OP4_IMM32;
839       displacement = &opcode[0];
840       extension += 3;
841 
842       addend
843 	= (((addend & 0x7) << 7)
844 	   | opcode[0]
845 	   | ((addend & 0x7f8) << 13)
846 	   | (opcode[1] << 8)
847 	   | (opcode[2] << 16));
848 
849       opindx = EPIPHANY_OPERAND_SIMM11;
850       break;
851 
852     case EPIPHANY_RELAX_BRANCH_LONG:
853       /* Branches differ only in low nibble of instruction being 8 not 0.
854 	 24 bit displacement goes to bytes 1..3 .  */
855       *opcode |= OP4_BRANCH;
856       extension += 2;
857 
858       addend >>= 1;		/* Convert to word offset.  */
859       opindx = EPIPHANY_OPERAND_SIMM24;
860       break;
861 
862     case EPIPHANY_RELAX_MOV_IMM16:
863       *opcode |=  OP4_IMM32;
864       extension += 3;
865 
866       addend
867 	= (((addend & 0xff00) << 12)
868 	   | (opcode[2] << 16)
869 	   | ((addend & 0x00ff) << 5)
870 	   | (opcode[1] << 8)
871 	   | opcode[0]);
872       displacement = &opcode[0];
873       opindx = EPIPHANY_OPERAND_IMM16;
874       break;
875 
876     case EPIPHANY_RELAX_LDST_IMM11:
877       *opcode |= OP4_LDSTRD;
878       displacement = &opcode[0];
879       extension += 3;
880 
881       if (addend < 0)
882 	/* Convert twos-complement address value to sign-magnitude.  */
883 	addend = (-addend & 0x7ff) | 0x800;
884 
885       addend
886 	= (((addend & 0x7) << 5)
887 	   | opcode[0]
888 	   | ((addend & 0xff8) << 13)
889 	   | (opcode[1] << 8)
890 	   | (opcode[2] << 16));
891 
892       opindx = EPIPHANY_OPERAND_DISP11;
893       break;
894 
895     case EPIPHANY_RELAX_ARITH_SIMM3:
896       addend = ((addend & 7) << 5) | opcode[0];
897       opindx = EPIPHANY_OPERAND_SIMM3;
898       break;
899 
900     case EPIPHANY_RELAX_LDST_IMM3:
901       addend = ((addend & 7) << 5) | opcode[0];
902       opindx = EPIPHANY_OPERAND_DISP3;
903 
904     case EPIPHANY_RELAX_BRANCH_SHORT:
905       addend >>= 1;		/* Convert to a word offset.  */
906       displacement = & opcode[1];
907       opindx = EPIPHANY_OPERAND_SIMM8;
908       break;
909 
910     case EPIPHANY_RELAX_MOV_IMM8:
911       addend
912 	= (((addend & 0xff) << 5)
913 	   | opcode[0]
914 	   | (opcode[1] << 8));
915       opindx = EPIPHANY_OPERAND_IMM8;
916       break;
917 
918     case EPIPHANY_RELAX_NONE:
919     case EPIPHANY_RELAX_NEED_RELAXING:
920     default:			/* Anything else?  */
921       as_bad ("unrecognized fragment subtype");
922       break;
923     }
924 
925   /* Create a relocation for symbols that must be resolved by the linker.
926      Otherwise output the completed insn.  */
927 
928   if (S_GET_SEGMENT (fragP->fr_symbol) != sec
929       || S_IS_EXTERNAL (fragP->fr_symbol)
930       || S_IS_WEAK (fragP->fr_symbol))
931     {
932       fixS *fixP;
933       const CGEN_OPERAND *operand
934 	= cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindx);
935       bfd_reloc_code_real_type reloc_type;
936 
937       gas_assert (fragP->fr_cgen.insn != 0);
938 
939       reloc_type = md_cgen_lookup_reloc (fragP->fr_cgen.insn, operand, NULL);
940 
941       fixP = gas_cgen_record_fixup (fragP,
942 				    /* Offset of insn in frag.  */
943 				    (opcode - fragP->fr_literal),
944 				    fragP->fr_cgen.insn,
945 				    CGEN_INSN_BITSIZE (fragP->fr_cgen.insn) / 8,
946 				    operand,
947 				    reloc_type,
948 				    fragP->fr_symbol, fragP->fr_offset);
949       fixP->fx_r_type = fixP->fx_cgen.opinfo;
950     }
951 
952   md_number_to_chars (displacement, (valueT) addend, extension + 1);
953 
954   fragP->fr_fix += (extension & -2); /* 0,2 or 4 bytes added.  */
955 }
956 
957 
958 /* Functions concerning relocs.  */
959 
960 /* The location from which a PC relative jump should be calculated,
961    given a PC relative reloc.  */
962 
963 long
964 md_pcrel_from_section (fixS *fixP, segT sec)
965 {
966   if (fixP->fx_addsy != (symbolS *) NULL
967       && (!S_IS_DEFINED (fixP->fx_addsy)
968 	  || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
969 	  || S_IS_EXTERNAL (fixP->fx_addsy)
970 	  || S_IS_WEAK (fixP->fx_addsy)))
971     return 0;
972 
973   return fixP->fx_frag->fr_address + fixP->fx_where;
974 }
975 
976 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
977    Returns BFD_RELOC_NONE if no reloc type can be found.
978    *FIXP may be modified if desired.  */
979 
980 bfd_reloc_code_real_type
981 md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
982 		      const CGEN_OPERAND *operand,
983 		      fixS *fixP ATTRIBUTE_UNUSED)
984 {
985   switch (operand->type)
986     {
987     case EPIPHANY_OPERAND_SIMM11:
988       return BFD_RELOC_EPIPHANY_SIMM11;
989     case EPIPHANY_OPERAND_DISP11:
990       return BFD_RELOC_EPIPHANY_IMM11;
991 
992     case EPIPHANY_OPERAND_SIMM8:
993       return BFD_RELOC_EPIPHANY_SIMM8;
994     case EPIPHANY_OPERAND_SIMM24:
995       return BFD_RELOC_EPIPHANY_SIMM24;
996 
997     case EPIPHANY_OPERAND_IMM8:
998       return BFD_RELOC_EPIPHANY_IMM8;
999 
1000     case EPIPHANY_OPERAND_IMM16:
1001       if (0 == strcmp ("movt", CGEN_INSN_MNEMONIC (insn)))
1002 	return BFD_RELOC_EPIPHANY_HIGH;
1003       else if (0 == strcmp ("mov", CGEN_INSN_MNEMONIC (insn)))
1004 	return BFD_RELOC_EPIPHANY_LOW;
1005       else
1006 	as_bad ("unknown imm16 operand");
1007       /* fall-thru */
1008 
1009     default:
1010       break;
1011     }
1012   return BFD_RELOC_NONE;
1013 }
1014 
1015 
1016 /* Turn a string in input_line_pointer into a floating point constant
1017    of type TYPE, and store the appropriate bytes in *LITP.  The number
1018    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
1019    returned, or NULL on OK.  */
1020 
1021 /* Equal to MAX_PRECISION in atof-ieee.c.  */
1022 #define MAX_LITTLENUMS 6
1023 
1024 char *
1025 md_atof (int type, char *litP, int *sizeP)
1026 {
1027   return ieee_md_atof (type, litP, sizeP, FALSE);
1028 }
1029 
1030 /* Return true if can adjust the reloc to be relative to its section
1031    (such as .data) instead of relative to some symbol.  */
1032 
1033 bfd_boolean
1034 epiphany_fix_adjustable (fixS *fixP)
1035 {
1036  bfd_reloc_code_real_type reloc_type;
1037 
1038   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1039     {
1040       const CGEN_INSN *insn = fixP->fx_cgen.insn;
1041       int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1042       const CGEN_OPERAND *operand =
1043 	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindex);
1044 
1045       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
1046     }
1047   else
1048     reloc_type = fixP->fx_r_type;
1049 
1050   if (fixP->fx_addsy == NULL)
1051     return TRUE;
1052 
1053   /* Prevent all adjustments to global symbols.  */
1054   if (S_IS_EXTERNAL (fixP->fx_addsy))
1055     return FALSE;
1056 
1057   if (S_IS_WEAK (fixP->fx_addsy))
1058     return FALSE;
1059 
1060   if (pic_code
1061       && (reloc_type == BFD_RELOC_EPIPHANY_SIMM24
1062 	  || reloc_type == BFD_RELOC_EPIPHANY_SIMM8
1063 	  || reloc_type == BFD_RELOC_EPIPHANY_HIGH
1064 	  || reloc_type == BFD_RELOC_EPIPHANY_LOW))
1065     return FALSE;
1066 
1067   /* Since we don't use partial_inplace, we must not reduce symbols in
1068      mergable sections to their section symbol.  */
1069   if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
1070     return FALSE;
1071 
1072   return TRUE;
1073 }
1074 
1075 void
1076 epiphany_elf_final_processing (void)
1077 {
1078   elf_elfheader (stdoutput)->e_flags |= epiphany_flags;
1079 }
1080 
1081 int
1082 epiphany_cgen_parse_fix_exp (int opinfo, expressionS *exp ATTRIBUTE_UNUSED)
1083 {
1084   LITTLENUM_TYPE words[2];
1085 
1086   switch (opinfo)
1087     {
1088     case BFD_RELOC_EPIPHANY_LOW:
1089     case BFD_RELOC_EPIPHANY_HIGH:
1090       break;
1091     default:
1092       return opinfo;
1093     }
1094 
1095   /* Doing a %LOW or %HIGH.  */
1096   switch (exp->X_op)
1097     {
1098     default:
1099       return opinfo;
1100     case O_big:				/* Bignum.  */
1101       if (exp->X_add_number > 0)	/* Integer value too large.  */
1102 	return opinfo;
1103     }
1104 
1105   /* Convert to SP number.  */
1106   gen_to_words (words, 2, 8L);
1107   exp->X_add_number = words[1] | (words[0] << 16);
1108   exp->X_op = O_constant;
1109   return opinfo;
1110 }
1111