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