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