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