1 /* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
2    Copyright (C) 2009-2014 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
epiphany_elf_section_rtn(int i)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
epiphany_elf_section_text(int i)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
md_parse_option(int c ATTRIBUTE_UNUSED,char * arg ATTRIBUTE_UNUSED)139 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
140 {
141   return 0;	/* No target-specific options.  */
142 }
143 
144 void
md_show_usage(FILE * stream)145 md_show_usage (FILE * stream)
146 {
147   fprintf (stream, _("EPIPHANY specific command line options:\n"));
148 }
149 
150 
151 void
md_begin(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
md_section_align(segT segment,valueT size)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
md_pcrel_from(fixS * fixP ATTRIBUTE_UNUSED)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
md_number_to_chars(char * buf,valueT val,int n)191 md_number_to_chars (char * buf, valueT val, int n)
192 {
193   number_to_chars_littleendian (buf, val, n);
194 }
195 
196 int
epiphany_elf_section_flags(int flags,int attr ATTRIBUTE_UNUSED,int type ATTRIBUTE_UNUSED)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
epiphany_PIC_related_p(symbolS * sym)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
epiphany_apply_fix(fixS * fixP,valueT * valP,segT seg)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
epiphany_handle_align(fragS * fragp)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 *
parse_reglist(const char * s,int * mask)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
md_assemble(char * str)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
md_operand(expressionS * expressionP)603 md_operand (expressionS *expressionP)
604 {
605   if (*input_line_pointer == '#')
606     {
607       input_line_pointer++;
608       expression (expressionP);
609     }
610 }
611 
612 symbolS *
md_undefined_symbol(char * name ATTRIBUTE_UNUSED)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
epiphany_relax_frag(segT segment,fragS * fragP,long stretch)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
md_estimate_size_before_relax(fragS * fragP,segT segment)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
md_convert_frag(bfd * abfd ATTRIBUTE_UNUSED,segT sec,fragS * fragP)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       break;
904 
905     case EPIPHANY_RELAX_BRANCH_SHORT:
906       addend >>= 1;		/* Convert to a word offset.  */
907       displacement = & opcode[1];
908       opindx = EPIPHANY_OPERAND_SIMM8;
909       break;
910 
911     case EPIPHANY_RELAX_MOV_IMM8:
912       addend
913 	= (((addend & 0xff) << 5)
914 	   | opcode[0]
915 	   | (opcode[1] << 8));
916       opindx = EPIPHANY_OPERAND_IMM8;
917       break;
918 
919     case EPIPHANY_RELAX_NONE:
920     case EPIPHANY_RELAX_NEED_RELAXING:
921     default:			/* Anything else?  */
922       as_bad ("unrecognized fragment subtype");
923       break;
924     }
925 
926   /* Create a relocation for symbols that must be resolved by the linker.
927      Otherwise output the completed insn.  */
928 
929   if (S_GET_SEGMENT (fragP->fr_symbol) != sec
930       || S_IS_EXTERNAL (fragP->fr_symbol)
931       || S_IS_WEAK (fragP->fr_symbol))
932     {
933       fixS *fixP;
934       const CGEN_OPERAND *operand
935 	= cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindx);
936       bfd_reloc_code_real_type reloc_type;
937 
938       gas_assert (fragP->fr_cgen.insn != 0);
939 
940       reloc_type = md_cgen_lookup_reloc (fragP->fr_cgen.insn, operand, NULL);
941 
942       fixP = gas_cgen_record_fixup (fragP,
943 				    /* Offset of insn in frag.  */
944 				    (opcode - fragP->fr_literal),
945 				    fragP->fr_cgen.insn,
946 				    CGEN_INSN_BITSIZE (fragP->fr_cgen.insn) / 8,
947 				    operand,
948 				    reloc_type,
949 				    fragP->fr_symbol, fragP->fr_offset);
950       fixP->fx_r_type = fixP->fx_cgen.opinfo;
951     }
952 
953   md_number_to_chars (displacement, (valueT) addend, extension + 1);
954 
955   fragP->fr_fix += (extension & -2); /* 0,2 or 4 bytes added.  */
956 }
957 
958 
959 /* Functions concerning relocs.  */
960 
961 /* The location from which a PC relative jump should be calculated,
962    given a PC relative reloc.  */
963 
964 long
md_pcrel_from_section(fixS * fixP,segT sec)965 md_pcrel_from_section (fixS *fixP, segT sec)
966 {
967   if (fixP->fx_addsy != (symbolS *) NULL
968       && (!S_IS_DEFINED (fixP->fx_addsy)
969 	  || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
970 	  || S_IS_EXTERNAL (fixP->fx_addsy)
971 	  || S_IS_WEAK (fixP->fx_addsy)))
972     return 0;
973 
974   return fixP->fx_frag->fr_address + fixP->fx_where;
975 }
976 
977 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
978    Returns BFD_RELOC_NONE if no reloc type can be found.
979    *FIXP may be modified if desired.  */
980 
981 bfd_reloc_code_real_type
md_cgen_lookup_reloc(const CGEN_INSN * insn ATTRIBUTE_UNUSED,const CGEN_OPERAND * operand,fixS * fixP ATTRIBUTE_UNUSED)982 md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
983 		      const CGEN_OPERAND *operand,
984 		      fixS *fixP ATTRIBUTE_UNUSED)
985 {
986   switch (operand->type)
987     {
988     case EPIPHANY_OPERAND_SIMM11:
989       return BFD_RELOC_EPIPHANY_SIMM11;
990     case EPIPHANY_OPERAND_DISP11:
991       return BFD_RELOC_EPIPHANY_IMM11;
992 
993     case EPIPHANY_OPERAND_SIMM8:
994       return BFD_RELOC_EPIPHANY_SIMM8;
995     case EPIPHANY_OPERAND_SIMM24:
996       return BFD_RELOC_EPIPHANY_SIMM24;
997 
998     case EPIPHANY_OPERAND_IMM8:
999       return BFD_RELOC_EPIPHANY_IMM8;
1000 
1001     case EPIPHANY_OPERAND_IMM16:
1002       if (0 == strcmp ("movt", CGEN_INSN_MNEMONIC (insn)))
1003 	return BFD_RELOC_EPIPHANY_HIGH;
1004       else if (0 == strcmp ("mov", CGEN_INSN_MNEMONIC (insn)))
1005 	return BFD_RELOC_EPIPHANY_LOW;
1006       else
1007 	as_bad ("unknown imm16 operand");
1008       /* fall-thru */
1009 
1010     default:
1011       break;
1012     }
1013   return BFD_RELOC_NONE;
1014 }
1015 
1016 
1017 /* Turn a string in input_line_pointer into a floating point constant
1018    of type TYPE, and store the appropriate bytes in *LITP.  The number
1019    of LITTLENUMS emitted is stored in *SIZEP.  An error message is
1020    returned, or NULL on OK.  */
1021 
1022 /* Equal to MAX_PRECISION in atof-ieee.c.  */
1023 #define MAX_LITTLENUMS 6
1024 
1025 char *
md_atof(int type,char * litP,int * sizeP)1026 md_atof (int type, char *litP, int *sizeP)
1027 {
1028   return ieee_md_atof (type, litP, sizeP, FALSE);
1029 }
1030 
1031 /* Return true if can adjust the reloc to be relative to its section
1032    (such as .data) instead of relative to some symbol.  */
1033 
1034 bfd_boolean
epiphany_fix_adjustable(fixS * fixP)1035 epiphany_fix_adjustable (fixS *fixP)
1036 {
1037  bfd_reloc_code_real_type reloc_type;
1038 
1039   if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1040     {
1041       const CGEN_INSN *insn = fixP->fx_cgen.insn;
1042       int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1043       const CGEN_OPERAND *operand =
1044 	cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindex);
1045 
1046       reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
1047     }
1048   else
1049     reloc_type = fixP->fx_r_type;
1050 
1051   if (fixP->fx_addsy == NULL)
1052     return TRUE;
1053 
1054   /* Prevent all adjustments to global symbols.  */
1055   if (S_IS_EXTERNAL (fixP->fx_addsy))
1056     return FALSE;
1057 
1058   if (S_IS_WEAK (fixP->fx_addsy))
1059     return FALSE;
1060 
1061   if (pic_code
1062       && (reloc_type == BFD_RELOC_EPIPHANY_SIMM24
1063 	  || reloc_type == BFD_RELOC_EPIPHANY_SIMM8
1064 	  || reloc_type == BFD_RELOC_EPIPHANY_HIGH
1065 	  || reloc_type == BFD_RELOC_EPIPHANY_LOW))
1066     return FALSE;
1067 
1068   /* Since we don't use partial_inplace, we must not reduce symbols in
1069      mergable sections to their section symbol.  */
1070   if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
1071     return FALSE;
1072 
1073   return TRUE;
1074 }
1075 
1076 void
epiphany_elf_final_processing(void)1077 epiphany_elf_final_processing (void)
1078 {
1079   elf_elfheader (stdoutput)->e_flags |= epiphany_flags;
1080 }
1081 
1082 int
epiphany_cgen_parse_fix_exp(int opinfo,expressionS * exp ATTRIBUTE_UNUSED)1083 epiphany_cgen_parse_fix_exp (int opinfo, expressionS *exp ATTRIBUTE_UNUSED)
1084 {
1085   LITTLENUM_TYPE words[2];
1086 
1087   switch (opinfo)
1088     {
1089     case BFD_RELOC_EPIPHANY_LOW:
1090     case BFD_RELOC_EPIPHANY_HIGH:
1091       break;
1092     default:
1093       return opinfo;
1094     }
1095 
1096   /* Doing a %LOW or %HIGH.  */
1097   switch (exp->X_op)
1098     {
1099     default:
1100       return opinfo;
1101     case O_big:				/* Bignum.  */
1102       if (exp->X_add_number > 0)	/* Integer value too large.  */
1103 	return opinfo;
1104     }
1105 
1106   /* Convert to SP number.  */
1107   gen_to_words (words, 2, 8L);
1108   exp->X_add_number = words[1] | (words[0] << 16);
1109   exp->X_op = O_constant;
1110   return opinfo;
1111 }
1112