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