1/* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
2   Copyright (C) 2009-2017 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.  */
34typedef 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}
52epiphany_insn;
53
54const char comment_chars[]        = ";";
55const char line_comment_chars[]   = "#";
56const char line_separator_chars[] = "`";
57const char EXP_CHARS[]            = "eE";
58const char FLT_CHARS[]            = "fFdD";
59
60/* Flag to detect when switching to code section where insn alignment is
61   implied.  */
62static bfd_boolean force_code_align = FALSE;
63
64static void
65epiphany_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
76static void
77epiphany_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.  */
86const pseudo_typeS md_pseudo_table[] =
87{
88    { "text",   epiphany_elf_section_text,  0 },
89    { "sect",   epiphany_elf_section_rtn,   0 },
90    /* .word should be 32 bits.  */
91    { "word",       cons, 4 },
92    { "cpu",        s_ignore,         0 },
93    { "thumb_func", s_ignore,         0 },
94    { "code",       s_ignore,         0 },
95    { NULL,         NULL,             0 }
96};
97
98
99
100enum options
101{
102  OPTION_CPU_EPIPHANY = OPTION_MD_BASE,
103  OPTION_CPU_EPIPHANY16
104};
105
106struct 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
113size_t md_longopts_size = sizeof (md_longopts);
114
115const char * md_shortopts = "";
116
117int
118md_parse_option (int c ATTRIBUTE_UNUSED, const char * arg ATTRIBUTE_UNUSED)
119{
120  return 0;	/* No target-specific options.  */
121}
122
123void
124md_show_usage (FILE * stream)
125{
126  fprintf (stream, _("EPIPHANY specific command line options:\n"));
127}
128
129
130void
131md_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
150valueT
151md_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
159/* Functions concerning relocs.  */
160
161long
162md_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
169void
170md_number_to_chars (char * buf, valueT val, int n)
171{
172  number_to_chars_littleendian (buf, val, n);
173}
174
175int
176epiphany_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.  */
191int pic_code;
192
193/* Epiphany er_flags.  */
194static 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
207struct 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
220#define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
221static symbolS * GOT_symbol;
222
223static inline bfd_boolean
224epiphany_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
246void
247epiphany_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
310static const unsigned char nop_pattern[] = { 0xa2, 0x01 };
311
312void
313epiphany_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
342/* Read a comma separated incrementing list of register names
343   and form a bit mask of up to 15 registers 0..14.  */
344
345static const char *
346parse_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
387/* Assemble an instruction,  push and pop pseudo instructions should have
388   already been expanded.  */
389
390static void
391epiphany_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
523void
524md_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
591void
592md_operand (expressionS *expressionP)
593{
594  if (*input_line_pointer == '#')
595    {
596      input_line_pointer++;
597      expression (expressionP);
598    }
599}
600
601symbolS *
602md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
603{
604  return NULL;
605}
606
607/* Interface to relax_segment.  */
608
609/* FIXME: Build table by hand, get it working, then machine generate.  */
610
611const 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
648static 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
668long
669epiphany_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
711int
712md_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
786void
787md_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
948/* Functions concerning relocs.  */
949
950/* The location from which a PC relative jump should be calculated,
951   given a PC relative reloc.  */
952
953long
954md_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
970bfd_reloc_code_real_type
971md_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
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
1014const char *
1015md_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
1023bfd_boolean
1024epiphany_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
1065void
1066epiphany_elf_final_processing (void)
1067{
1068  elf_elfheader (stdoutput)->e_flags |= epiphany_flags;
1069}
1070
1071int
1072epiphany_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}
1101