1 /* tc-epiphany.c -- Assembler for the Adapteva EPIPHANY
2 Copyright 2009-2013 Free Software Foundation, Inc.
3 Contributed by Embecosm on behalf of Adapteva, Inc.
5 This file is part of GAS, the GNU Assembler.
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)
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.
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. */
25 #include "opcodes/epiphany-desc.h"
26 #include "opcodes/epiphany-opc.h"
28 #include "elf/common.h"
29 #include "elf/epiphany.h"
30 #include "dwarf2dbg.h"
33 /* Structure to hold all of the different components describing
34 an individual instruction. */
37 const CGEN_INSN * insn;
38 const CGEN_INSN * orig_insn;
41 CGEN_INSN_INT buffer [1];
42 #define INSN_VALUE(buf) (*(buf))
44 unsigned char buffer [CGEN_MAX_INSN_SIZE];
45 #define INSN_VALUE(buf) (buf)
50 fixS * fixups [GAS_CGEN_MAX_FIXUPS];
51 int indices [MAX_OPERAND_INSTANCES];
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";
61 /* Flag to detect when switching to code section where insn alignment is
63 static bfd_boolean force_code_align = FALSE;
66 epiphany_elf_section_rtn (int i)
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
76 char *old_input_line_pointer = input_line_pointer;
78 input_line_pointer = "\n";
80 force_code_align = FALSE;
83 input_line_pointer = old_input_line_pointer;
88 epiphany_elf_section_text (int i)
90 char *old_input_line_pointer;
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
98 old_input_line_pointer = input_line_pointer;
99 input_line_pointer = "\n";
101 force_code_align = FALSE;
103 input_line_pointer = old_input_line_pointer;
106 /* The target specific pseudo-ops which we support. */
107 const pseudo_typeS md_pseudo_table[] =
109 { "text", epiphany_elf_section_text, 0 },
110 { "sect", epiphany_elf_section_rtn, 0 },
111 /* .word should be 32 bits. */
113 { "cpu", s_ignore, 0 },
114 { "thumb_func", s_ignore, 0 },
115 { "code", s_ignore, 0 },
123 OPTION_CPU_EPIPHANY = OPTION_MD_BASE,
124 OPTION_CPU_EPIPHANY16
127 struct option md_longopts[] =
129 { "mepiphany ", no_argument, NULL, OPTION_CPU_EPIPHANY },
130 { "mepiphany16", no_argument, NULL, OPTION_CPU_EPIPHANY16 },
131 { NULL, no_argument, NULL, 0 },
134 size_t md_longopts_size = sizeof (md_longopts);
136 const char * md_shortopts = "";
139 md_parse_option (int c ATTRIBUTE_UNUSED, char * arg ATTRIBUTE_UNUSED)
141 return 0; /* No target-specific options. */
145 md_show_usage (FILE * stream)
147 fprintf (stream, _("EPIPHANY specific command line options:\n"));
154 /* Initialize the `cgen' interface. */
156 /* Set the machine number and endian. */
157 gas_cgen_cpu_desc = epiphany_cgen_cpu_open (CGEN_CPU_OPEN_MACHS,
159 CGEN_CPU_OPEN_ENDIAN,
162 epiphany_cgen_init_asm (gas_cgen_cpu_desc);
164 /* This is a callback from cgen to gas to parse operands. */
165 cgen_set_parse_operand_fn (gas_cgen_cpu_desc, gas_cgen_parse_operand);
167 /* Set the machine type. */
168 bfd_default_set_arch_mach (stdoutput, bfd_arch_epiphany, bfd_mach_epiphany32);
172 md_section_align (segT segment, valueT size)
174 int align = bfd_get_section_alignment (stdoutput, segment);
176 return ((size + (1 << align) - 1) & (-1 << align));
180 /* Functions concerning relocs. */
183 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
188 /* Write a value out to the object file, using the appropriate endianness. */
191 md_number_to_chars (char * buf, valueT val, int n)
193 number_to_chars_littleendian (buf, val, n);
197 epiphany_elf_section_flags (int flags,
198 int attr ATTRIBUTE_UNUSED,
199 int type ATTRIBUTE_UNUSED)
201 /* This is used to detect when the section changes to an executable section.
202 This function is called by the elf section processing. When we note an
203 executable section specifier we set an internal flag to denote when
204 word alignment should be forced. */
205 if (flags & SEC_CODE)
206 force_code_align = TRUE;
211 /* Non-zero if we are generating PIC code. */
214 /* Epiphany er_flags. */
215 static int epiphany_flags = 0;
217 /* Relocations against symbols are done in two
218 parts, with a HI relocation and a LO relocation. Each relocation
219 has only 16 bits of space to store an addend. This means that in
220 order for the linker to handle carries correctly, it must be able
221 to locate both the HI and the LO relocation. This means that the
222 relocations must appear in order in the relocation table.
224 In order to implement this, we keep track of each unmatched HI
225 relocation. We then sort them so that they immediately precede the
226 corresponding LO relocation. */
228 struct epiphany_hi_fixup
231 struct epiphany_hi_fixup *next;
236 /* The section this fixup is in. */
241 #define GOT_NAME "_GLOBAL_OFFSET_TABLE_"
242 static symbolS * GOT_symbol;
244 static inline bfd_boolean
245 epiphany_PIC_related_p (symbolS *sym)
252 if (sym == GOT_symbol)
255 exp = symbol_get_value_expression (sym);
257 return (exp->X_op == O_PIC_reloc
258 || exp->X_md == BFD_RELOC_EPIPHANY_SIMM24
259 || exp->X_md == BFD_RELOC_EPIPHANY_SIMM8
260 || epiphany_PIC_related_p (exp->X_add_symbol)
261 || epiphany_PIC_related_p (exp->X_op_symbol));
264 /* Perform target dependent relocations that are done at compile time.
265 There aren't very many of these. */
268 epiphany_apply_fix (fixS *fixP, valueT *valP, segT seg)
270 if (fixP->fx_addsy == (symbolS *) NULL)
273 if (((int) fixP->fx_r_type < (int) BFD_RELOC_UNUSED)
276 /* Install EPIPHANY-dependent relocations HERE because nobody else
278 char *where = fixP->fx_frag->fr_literal + fixP->fx_where;
279 unsigned char *insn = (unsigned char *)where;
280 valueT value = * valP;
282 switch (fixP->fx_r_type)
290 case BFD_RELOC_EPIPHANY_SIMM11:
291 where[0] = where[0] | ((value & 1) << 7);
292 where[1] = where[1] | ((value & 6) >> 1);
293 where[2] = (value >> 3) & 0xff;
296 case BFD_RELOC_EPIPHANY_IMM11:
297 where[0] = where[0] | ((value & 1) << 7);
298 where[1] = where[1] | ((value & 6) >> 1);
299 where[2] = (value >> 3) & 0xff;
302 case BFD_RELOC_EPIPHANY_SIMM8:
303 md_number_to_chars (where+1, value>>1, 1);
306 case BFD_RELOC_EPIPHANY_SIMM24:
307 md_number_to_chars (where+1, value>>1, 3);
310 case BFD_RELOC_EPIPHANY_HIGH:
313 case BFD_RELOC_EPIPHANY_LOW:
314 value = (((value & 0xff) << 5) | insn[0])
316 | ((value & 0xff00) << 12)
318 md_number_to_chars (where, value, 3);
323 /* Just do the default if we can't special case. */
324 return gas_cgen_md_apply_fix (fixP, valP, seg);
328 /* This is called from HANDLE_ALIGN in write.c. Fill in the contents
329 of an rs_align_code fragment. 0x01a2 is 16-bit pattern for a "nop". */
331 static const unsigned char nop_pattern[] = { 0xa2, 0x01 };
334 epiphany_handle_align (fragS *fragp)
339 if (fragp->fr_type != rs_align_code)
342 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
343 p = fragp->fr_literal + fragp->fr_fix;
355 memcpy (p, nop_pattern, 2);
360 fragp->fr_fix += fix;
363 /* Read a comma separated incrementing list of register names
364 and form a bit mask of upto 15 registers 0..14. */
367 parse_reglist (const char * s, int * mask)
378 /* Parse a list with "," or "}" as limiters. */
380 = cgen_parse_keyword (gas_cgen_cpu_desc, &s,
381 &epiphany_cgen_opval_gr_names, &value);
386 return _("register number too large for push/pop");
388 regmask |= 1 << value;
390 return _("register is out of order");
398 else if (*s++ == ',')
401 return _("bad register list");
404 return _("malformed reglist in push/pop");
409 md_assemble (char *str)
413 const char * pperr = 0;
414 int regmask=0, push=0, pop=0;
416 memset (&insn, 0, sizeof (insn));
418 /* Special-case push/pop instruction macros. */
419 if (0 == strncmp (str, "push {", 6))
423 pperr = parse_reglist (s, ®mask);
425 else if (0 == strncmp (str, "pop {", 5))
429 pperr = parse_reglist (s, ®mask);
434 as_bad ("%s", pperr);
441 int i,p ATTRIBUTE_UNUSED;
443 md_assemble ("mov r15,4");
444 md_assemble ("sub sp,sp,r15");
446 for (i = 0, p = 1; i <= 15; ++i, regmask >>= 1)
449 sprintf (buff, "str r%d,[sp]", i); /* Last one. */
450 else if (regmask & 1)
451 sprintf (buff, "str r%d,[sp],-r15", i);
458 else if (pop && regmask)
463 md_assemble ("mov r15,4");
465 for (i = 15, p = 1 << 15; i >= 0; --i, p >>= 1)
468 sprintf (buff, "ldr r%d,[sp],+r15", i);
474 /* Initialize GAS's cgen interface for a new instruction. */
475 gas_cgen_init_parse ();
477 insn.insn = epiphany_cgen_assemble_insn
478 (gas_cgen_cpu_desc, str, &insn.fields, insn.buffer, & errmsg);
482 as_bad ("%s", errmsg);
486 if (CGEN_INSN_BITSIZE (insn.insn) == 32)
488 /* Doesn't really matter what we pass for RELAX_P here. */
489 gas_cgen_finish_insn (insn.insn, insn.buffer,
490 CGEN_FIELDS_BITSIZE (&insn.fields), 1, NULL);
494 if (CGEN_INSN_BITSIZE (insn.insn) != 16)
497 insn.orig_insn = insn.insn;
499 gas_cgen_finish_insn (insn.orig_insn, insn.buffer,
500 CGEN_FIELDS_BITSIZE (&insn.fields),
501 1 /* relax_p */, NULL);
504 /* Checks for behavioral restrictions on LD/ST instructions. */
505 #define DISPMOD _("destination register modified by displacement-post-modified address")
506 #define LDSTODD _("ldrd/strd requires even:odd register pair")
508 /* Helper macros for spliting apart instruction fields. */
509 #define ADDR_POST_MODIFIED(i) (((i) >> 25) & 0x1)
510 #define ADDR_SIZE(i) (((i) >> 5) & 3)
511 #define ADDR_LOADSTORE(i) (((i) >> 4) & 0x1)
513 switch (insn.buffer[0] & 0xf)
515 /* Post-modify registers cannot be destinations. */
518 if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD)
519 if (insn.fields.f_rd == insn.fields.f_rn /* Postmodify dest. */
520 || (insn.fields.f_rd+1 == insn.fields.f_rn
521 && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE))
523 as_bad ("%s", DISPMOD);
526 if ((insn.fields.f_rd & 1) /* Odd-numbered register... */
527 && insn.fields.f_wordsize == OPW_DOUBLE) /* ...and 64 bit transfer. */
529 as_bad ("%s", LDSTODD);
537 if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD) /* A load. */
538 if (insn.fields.f_rd6 == insn.fields.f_rn6 /* Postmodify dest. */
539 /* Check for regpair postindexed. */
540 || (insn.fields.f_rd6 + 1 == insn.fields.f_rn6
541 && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE))
543 as_bad ("%s", DISPMOD);
546 if ((insn.fields.f_rd6 & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
547 /* Lsb of RD odd and 64 bit transfer. */
549 as_bad ("%s", LDSTODD);
558 /* Check for unaligned load/store double. */
559 if ((insn.fields.f_rd & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
560 /* Lsb of RD odd and 64 bit transfer. */
562 as_bad ("%s", LDSTODD);
570 /* Check for load to post-modified register. */
571 if (ADDR_LOADSTORE (insn.buffer[0]) == OP_LOAD /* A load. */
572 && ADDR_POST_MODIFIED (insn.buffer[0]) == PMOD_POST /* Post-mod. */
573 && (insn.fields.f_rd6 == insn.fields.f_rn6
574 || (insn.fields.f_rd6+1 == insn.fields.f_rn6
575 && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)))
577 as_bad ("%s", DISPMOD);
585 /* Check for unaligned load/store double. */
586 if ((insn.fields.f_rd6 & 1) && ADDR_SIZE (insn.buffer[0]) == OPW_DOUBLE)
588 as_bad ("%s", LDSTODD);
599 /* The syntax in the manual says constants begin with '#'.
600 We just ignore it. */
603 md_operand (expressionS *expressionP)
605 if (*input_line_pointer == '#')
607 input_line_pointer++;
608 expression (expressionP);
613 md_undefined_symbol (char *name ATTRIBUTE_UNUSED)
618 /* Interface to relax_segment. */
620 /* FIXME: Build table by hand, get it working, then machine generate. */
622 const relax_typeS md_relax_table[] =
625 1) most positive reach of this state,
626 2) most negative reach of this state,
627 3) how many bytes this mode will add to the size of the current frag
628 4) which index into the table to try if we can't fit into this one. */
630 /* The first entry must be unused because an `rlx_more' value of zero ends
632 {1, 1, 0, EPIPHANY_RELAX_NONE},
633 {0, 0, 0, EPIPHANY_RELAX_NONE}, /* Also a dummy entry to indicate we need to expand codes. */
635 /* The displacement used by GAS is from the end of the 2 byte insn,
636 so we subtract 2 from the following. */
637 /* 16 bit insn, 8 bit disp -> +127 words, -128 words. */
638 {0x00000100 - 1 - 2, -0x00000100 - 2, 0, EPIPHANY_RELAX_BRANCH_LONG },
639 /* 32 bit insn, 24 bit disp -> 25 bit range. */
640 {0x01000000 - 1 - 2, -0x01000000 - 2, 2, EPIPHANY_RELAX_NONE },
642 /* addi/subi 3 bits -4..+3. */
643 { 3, -4,0, EPIPHANY_RELAX_ARITH_SIMM11 },
644 /* addi/subi 11 bits. */
645 { 1023, -1024,2, EPIPHANY_RELAX_NONE },
648 { 255, 0,0, EPIPHANY_RELAX_MOV_IMM16 },
650 { 65535, 0,2, EPIPHANY_RELAX_NONE },
652 /* ld/st rd,[rn,imm3]. */
653 { 7, 0,0, EPIPHANY_RELAX_LDST_IMM11},
654 /* ld/st rd,[rn,imm11]. */
655 { 2047, 0,2, EPIPHANY_RELAX_NONE }
659 static const EPIPHANY_RELAX_TYPES relax_insn[] =
661 EPIPHANY_RELAX_BRANCH_SHORT, /* OP4_BRANCH16 */
662 EPIPHANY_RELAX_NONE, /* OP4_LDSTR16X */
663 EPIPHANY_RELAX_NONE, /* OP4_FLOW16 */
664 EPIPHANY_RELAX_ARITH_SIMM3, /* OP4_IMM16 - special */
665 EPIPHANY_RELAX_LDST_IMM3, /* OP4_LDSTR16D */
666 EPIPHANY_RELAX_NONE, /* OP4_LDSTR126P */
667 EPIPHANY_RELAX_NONE, /* OP4_LSHIFT16 */
668 EPIPHANY_RELAX_NONE, /* OP4_DSP16 */
669 EPIPHANY_RELAX_BRANCH_LONG, /* OP4_BRANCH */
670 EPIPHANY_RELAX_NONE, /* OP4_LDSTRX */
671 EPIPHANY_RELAX_NONE, /* OP4_ALU16 */
672 EPIPHANY_RELAX_ARITH_SIMM11, /* OP4_IMM32 - special */
673 EPIPHANY_RELAX_LDST_IMM11, /* OP4_LDSTRD */
674 EPIPHANY_RELAX_NONE, /* OP4_LDSTRP */
675 EPIPHANY_RELAX_NONE, /* OP4_ASHIFT16 */
676 EPIPHANY_RELAX_NONE /* OP4_MISC */
680 epiphany_relax_frag (segT segment, fragS *fragP, long stretch)
682 /* Address of branch insn. */
683 long address ATTRIBUTE_UNUSED = fragP->fr_address + fragP->fr_fix - 2;
686 if (fragP->fr_subtype == EPIPHANY_RELAX_NEED_RELAXING)
688 EPIPHANY_RELAX_TYPES subtype = relax_insn [*fragP->fr_opcode & 0xf];
690 /* Special cases add/sub vs mov immediates. */
691 if (subtype == EPIPHANY_RELAX_ARITH_SIMM3)
693 if ((*fragP->fr_opcode & 0x10) == 0)
694 subtype = EPIPHANY_RELAX_MOV_IMM8;
696 else if (subtype == EPIPHANY_RELAX_ARITH_SIMM11)
698 if ((*fragP->fr_opcode & 0x10) == 0)
699 subtype = EPIPHANY_RELAX_MOV_IMM16;
702 /* Remember refinements for the future. */
703 fragP->fr_subtype = subtype;
706 growth = relax_frag (segment, fragP, stretch);
711 /* Return an initial guess of the length by which a fragment must grow to
712 hold a branch to reach its destination.
713 Also updates fr_type/fr_subtype as necessary.
715 Called just before doing relaxation.
716 Any symbol that is now undefined will not become defined.
717 The guess for fr_var is ACTUALLY the growth beyond fr_fix.
718 Whatever we do to grow fr_fix or fr_var contributes to our returned value.
719 Although it may not be explicit in the frag, pretend fr_var starts
723 md_estimate_size_before_relax (fragS *fragP, segT segment)
725 /* The only thing we have to handle here are symbols outside of the
726 current segment. They may be undefined or in a different segment in
727 which case linker scripts may place them anywhere.
728 However, we can't finish the fragment here and emit the reloc as insn
729 alignment requirements may move the insn about. */
730 if (S_GET_SEGMENT (fragP->fr_symbol) != segment
731 || S_IS_EXTERNAL (fragP->fr_symbol)
732 || S_IS_WEAK (fragP->fr_symbol))
734 /* The symbol is undefined in this segment. Change the
735 relaxation subtype to the max allowable and leave all further
736 handling to md_convert_frag. */
738 EPIPHANY_RELAX_TYPES subtype;
739 /* We haven't relaxed this at all, so the relaxation type may be
740 completely wrong. Set the subtype correctly. */
741 epiphany_relax_frag (segment, fragP, 0);
742 subtype = fragP->fr_subtype;
746 case EPIPHANY_RELAX_LDST_IMM3:
747 subtype = EPIPHANY_RELAX_LDST_IMM11;
749 case EPIPHANY_RELAX_BRANCH_SHORT:
750 subtype = EPIPHANY_RELAX_BRANCH_LONG;
752 case EPIPHANY_RELAX_MOV_IMM8:
753 subtype = EPIPHANY_RELAX_MOV_IMM16;
755 case EPIPHANY_RELAX_ARITH_SIMM3:
756 subtype = EPIPHANY_RELAX_ARITH_SIMM11;
763 fragP->fr_subtype = subtype;
766 const CGEN_INSN *insn;
769 /* Update the recorded insn. */
771 for (i = 0, insn = fragP->fr_cgen.insn; i < 4; i++, insn++)
773 if ((strcmp (CGEN_INSN_MNEMONIC (insn),
774 CGEN_INSN_MNEMONIC (fragP->fr_cgen.insn))
776 && CGEN_INSN_ATTR_VALUE (insn, CGEN_INSN_RELAXED))
783 fragP->fr_cgen.insn = insn;
787 return md_relax_table[fragP->fr_subtype].rlx_length;
790 /* *FRAGP has been relaxed to its final size, and now needs to have
791 the bytes inside it modified to conform to the new size.
793 Called after relaxation is finished.
794 fragP->fr_type == rs_machine_dependent.
795 fragP->fr_subtype is the subtype of what the address relaxed to. */
798 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED,
810 opcode = fragP->fr_opcode;
812 /* Address opcode resides at in file space. */
813 opcode_address = fragP->fr_address + fragP->fr_fix - 2;
815 displacement = &opcode[1];
817 /* Set up any addend necessary for branches. */
818 if (S_GET_SEGMENT (fragP->fr_symbol) != sec
819 || S_IS_EXTERNAL (fragP->fr_symbol)
820 || S_IS_WEAK (fragP->fr_symbol))
822 /* Symbol must be resolved by linker. */
823 if (fragP->fr_offset & 1)
824 as_warn (_("Addend to unresolved symbol not on word boundary."));
829 /* Address we want to reach in file space. */
830 target_address = S_GET_VALUE (fragP->fr_symbol) + fragP->fr_offset;
831 addend = (target_address - (opcode_address & -2));
834 /* Do all the housekeeping for frag conversions. */
835 switch (fragP->fr_subtype)
837 case EPIPHANY_RELAX_ARITH_SIMM11:
838 *opcode |= OP4_IMM32;
839 displacement = &opcode[0];
843 = (((addend & 0x7) << 7)
845 | ((addend & 0x7f8) << 13)
847 | (opcode[2] << 16));
849 opindx = EPIPHANY_OPERAND_SIMM11;
852 case EPIPHANY_RELAX_BRANCH_LONG:
853 /* Branches differ only in low nibble of instruction being 8 not 0.
854 24 bit displacement goes to bytes 1..3 . */
855 *opcode |= OP4_BRANCH;
858 addend >>= 1; /* Convert to word offset. */
859 opindx = EPIPHANY_OPERAND_SIMM24;
862 case EPIPHANY_RELAX_MOV_IMM16:
863 *opcode |= OP4_IMM32;
867 = (((addend & 0xff00) << 12)
869 | ((addend & 0x00ff) << 5)
872 displacement = &opcode[0];
873 opindx = EPIPHANY_OPERAND_IMM16;
876 case EPIPHANY_RELAX_LDST_IMM11:
877 *opcode |= OP4_LDSTRD;
878 displacement = &opcode[0];
882 /* Convert twos-complement address value to sign-magnitude. */
883 addend = (-addend & 0x7ff) | 0x800;
886 = (((addend & 0x7) << 5)
888 | ((addend & 0xff8) << 13)
890 | (opcode[2] << 16));
892 opindx = EPIPHANY_OPERAND_DISP11;
895 case EPIPHANY_RELAX_ARITH_SIMM3:
896 addend = ((addend & 7) << 5) | opcode[0];
897 opindx = EPIPHANY_OPERAND_SIMM3;
900 case EPIPHANY_RELAX_LDST_IMM3:
901 addend = ((addend & 7) << 5) | opcode[0];
902 opindx = EPIPHANY_OPERAND_DISP3;
905 case EPIPHANY_RELAX_BRANCH_SHORT:
906 addend >>= 1; /* Convert to a word offset. */
907 displacement = & opcode[1];
908 opindx = EPIPHANY_OPERAND_SIMM8;
911 case EPIPHANY_RELAX_MOV_IMM8:
913 = (((addend & 0xff) << 5)
916 opindx = EPIPHANY_OPERAND_IMM8;
919 case EPIPHANY_RELAX_NONE:
920 case EPIPHANY_RELAX_NEED_RELAXING:
921 default: /* Anything else? */
922 as_bad ("unrecognized fragment subtype");
926 /* Create a relocation for symbols that must be resolved by the linker.
927 Otherwise output the completed insn. */
929 if (S_GET_SEGMENT (fragP->fr_symbol) != sec
930 || S_IS_EXTERNAL (fragP->fr_symbol)
931 || S_IS_WEAK (fragP->fr_symbol))
934 const CGEN_OPERAND *operand
935 = cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindx);
936 bfd_reloc_code_real_type reloc_type;
938 gas_assert (fragP->fr_cgen.insn != 0);
940 reloc_type = md_cgen_lookup_reloc (fragP->fr_cgen.insn, operand, NULL);
942 fixP = gas_cgen_record_fixup (fragP,
943 /* Offset of insn in frag. */
944 (opcode - fragP->fr_literal),
946 CGEN_INSN_BITSIZE (fragP->fr_cgen.insn) / 8,
949 fragP->fr_symbol, fragP->fr_offset);
950 fixP->fx_r_type = fixP->fx_cgen.opinfo;
953 md_number_to_chars (displacement, (valueT) addend, extension + 1);
955 fragP->fr_fix += (extension & -2); /* 0,2 or 4 bytes added. */
959 /* Functions concerning relocs. */
961 /* The location from which a PC relative jump should be calculated,
962 given a PC relative reloc. */
965 md_pcrel_from_section (fixS *fixP, segT sec)
967 if (fixP->fx_addsy != (symbolS *) NULL
968 && (!S_IS_DEFINED (fixP->fx_addsy)
969 || (S_GET_SEGMENT (fixP->fx_addsy) != sec)
970 || S_IS_EXTERNAL (fixP->fx_addsy)
971 || S_IS_WEAK (fixP->fx_addsy)))
974 return fixP->fx_frag->fr_address + fixP->fx_where;
977 /* Return the bfd reloc type for OPERAND of INSN at fixup FIXP.
978 Returns BFD_RELOC_NONE if no reloc type can be found.
979 *FIXP may be modified if desired. */
981 bfd_reloc_code_real_type
982 md_cgen_lookup_reloc (const CGEN_INSN *insn ATTRIBUTE_UNUSED,
983 const CGEN_OPERAND *operand,
984 fixS *fixP ATTRIBUTE_UNUSED)
986 switch (operand->type)
988 case EPIPHANY_OPERAND_SIMM11:
989 return BFD_RELOC_EPIPHANY_SIMM11;
990 case EPIPHANY_OPERAND_DISP11:
991 return BFD_RELOC_EPIPHANY_IMM11;
993 case EPIPHANY_OPERAND_SIMM8:
994 return BFD_RELOC_EPIPHANY_SIMM8;
995 case EPIPHANY_OPERAND_SIMM24:
996 return BFD_RELOC_EPIPHANY_SIMM24;
998 case EPIPHANY_OPERAND_IMM8:
999 return BFD_RELOC_EPIPHANY_IMM8;
1001 case EPIPHANY_OPERAND_IMM16:
1002 if (0 == strcmp ("movt", CGEN_INSN_MNEMONIC (insn)))
1003 return BFD_RELOC_EPIPHANY_HIGH;
1004 else if (0 == strcmp ("mov", CGEN_INSN_MNEMONIC (insn)))
1005 return BFD_RELOC_EPIPHANY_LOW;
1007 as_bad ("unknown imm16 operand");
1013 return BFD_RELOC_NONE;
1017 /* Turn a string in input_line_pointer into a floating point constant
1018 of type TYPE, and store the appropriate bytes in *LITP. The number
1019 of LITTLENUMS emitted is stored in *SIZEP. An error message is
1020 returned, or NULL on OK. */
1022 /* Equal to MAX_PRECISION in atof-ieee.c. */
1023 #define MAX_LITTLENUMS 6
1026 md_atof (int type, char *litP, int *sizeP)
1028 return ieee_md_atof (type, litP, sizeP, FALSE);
1031 /* Return true if can adjust the reloc to be relative to its section
1032 (such as .data) instead of relative to some symbol. */
1035 epiphany_fix_adjustable (fixS *fixP)
1037 bfd_reloc_code_real_type reloc_type;
1039 if ((int) fixP->fx_r_type >= (int) BFD_RELOC_UNUSED)
1041 const CGEN_INSN *insn = fixP->fx_cgen.insn;
1042 int opindex = (int) fixP->fx_r_type - (int) BFD_RELOC_UNUSED;
1043 const CGEN_OPERAND *operand =
1044 cgen_operand_lookup_by_num (gas_cgen_cpu_desc, opindex);
1046 reloc_type = md_cgen_lookup_reloc (insn, operand, fixP);
1049 reloc_type = fixP->fx_r_type;
1051 if (fixP->fx_addsy == NULL)
1054 /* Prevent all adjustments to global symbols. */
1055 if (S_IS_EXTERNAL (fixP->fx_addsy))
1058 if (S_IS_WEAK (fixP->fx_addsy))
1062 && (reloc_type == BFD_RELOC_EPIPHANY_SIMM24
1063 || reloc_type == BFD_RELOC_EPIPHANY_SIMM8
1064 || reloc_type == BFD_RELOC_EPIPHANY_HIGH
1065 || reloc_type == BFD_RELOC_EPIPHANY_LOW))
1068 /* Since we don't use partial_inplace, we must not reduce symbols in
1069 mergable sections to their section symbol. */
1070 if ((S_GET_SEGMENT (fixP->fx_addsy)->flags & SEC_MERGE) != 0)
1077 epiphany_elf_final_processing (void)
1079 elf_elfheader (stdoutput)->e_flags |= epiphany_flags;
1083 epiphany_cgen_parse_fix_exp (int opinfo, expressionS *exp ATTRIBUTE_UNUSED)
1085 LITTLENUM_TYPE words[2];
1089 case BFD_RELOC_EPIPHANY_LOW:
1090 case BFD_RELOC_EPIPHANY_HIGH:
1096 /* Doing a %LOW or %HIGH. */
1101 case O_big: /* Bignum. */
1102 if (exp->X_add_number > 0) /* Integer value too large. */
1106 /* Convert to SP number. */
1107 gen_to_words (words, 2, 8L);
1108 exp->X_add_number = words[1] | (words[0] << 16);
1109 exp->X_op = O_constant;