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, ®mask); 430 } 431 else if (0 == strncmp (str, "pop {", 5)) 432 { 433 char * s = str + 5; 434 pop = 1; 435 pperr = parse_reglist (s, ®mask); 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