[AArch64] Define LP64 BE linker name.
[platform/upstream/binutils.git] / gas / config / tc-epiphany.c
1 /* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
2    Copyright 2009-2013 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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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 \f
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       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 \f
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
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
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 \f
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 *
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
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
1077 epiphany_elf_final_processing (void)
1078 {
1079   elf_elfheader (stdoutput)->e_flags |= epiphany_flags;
1080 }
1081
1082 int
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 }