1 /* tc-microblaze.c -- Assemble code for Xilinx MicroBlaze 2 3 Copyright (C) 2009-2018 Free Software Foundation, 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 the Free 19 Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 20 02110-1301, USA. */ 21 22 #include "as.h" 23 #include <stdio.h> 24 #include "bfd.h" 25 #include "subsegs.h" 26 #define DEFINE_TABLE 27 #include "../opcodes/microblaze-opc.h" 28 #include "../opcodes/microblaze-opcm.h" 29 #include "safe-ctype.h" 30 #include <string.h> 31 #include <dwarf2dbg.h> 32 #include "aout/stab_gnu.h" 33 34 #ifndef streq 35 #define streq(a,b) (strcmp (a, b) == 0) 36 #endif 37 38 #define OPTION_EB (OPTION_MD_BASE + 0) 39 #define OPTION_EL (OPTION_MD_BASE + 1) 40 41 void microblaze_generate_symbol (char *sym); 42 static bfd_boolean check_spl_reg (unsigned *); 43 44 /* Several places in this file insert raw instructions into the 45 object. They should generate the instruction 46 and then use these four macros to crack the instruction value into 47 the appropriate byte values. */ 48 #define INST_BYTE0(x) (target_big_endian ? (((x) >> 24) & 0xFF) : ((x) & 0xFF)) 49 #define INST_BYTE1(x) (target_big_endian ? (((x) >> 16) & 0xFF) : (((x) >> 8) & 0xFF)) 50 #define INST_BYTE2(x) (target_big_endian ? (((x) >> 8) & 0xFF) : (((x) >> 16) & 0xFF)) 51 #define INST_BYTE3(x) (target_big_endian ? ((x) & 0xFF) : (((x) >> 24) & 0xFF)) 52 53 /* This array holds the chars that always start a comment. If the 54 pre-processor is disabled, these aren't very useful. */ 55 const char comment_chars[] = "#"; 56 57 const char line_separator_chars[] = ";"; 58 59 /* This array holds the chars that only start a comment at the beginning of 60 a line. */ 61 const char line_comment_chars[] = "#"; 62 63 const int md_reloc_size = 8; /* Size of relocation record. */ 64 65 /* Chars that can be used to separate mant 66 from exp in floating point numbers. */ 67 const char EXP_CHARS[] = "eE"; 68 69 /* Chars that mean this number is a floating point constant 70 As in 0f12.456 71 or 0d1.2345e12. */ 72 const char FLT_CHARS[] = "rRsSfFdDxXpP"; 73 74 /* INST_PC_OFFSET and INST_NO_OFFSET are 0 and 1. */ 75 #define UNDEFINED_PC_OFFSET 2 76 #define DEFINED_ABS_SEGMENT 3 77 #define DEFINED_PC_OFFSET 4 78 #define DEFINED_RO_SEGMENT 5 79 #define DEFINED_RW_SEGMENT 6 80 #define LARGE_DEFINED_PC_OFFSET 7 81 #define GOT_OFFSET 8 82 #define PLT_OFFSET 9 83 #define GOTOFF_OFFSET 10 84 #define TLSGD_OFFSET 11 85 #define TLSLD_OFFSET 12 86 #define TLSDTPMOD_OFFSET 13 87 #define TLSDTPREL_OFFSET 14 88 #define TLSGOTTPREL_OFFSET 15 89 #define TLSTPREL_OFFSET 16 90 91 /* Initialize the relax table. */ 92 const relax_typeS md_relax_table[] = 93 { 94 { 1, 1, 0, 0 }, /* 0: Unused. */ 95 { 1, 1, 0, 0 }, /* 1: Unused. */ 96 { 1, 1, 0, 0 }, /* 2: Unused. */ 97 { 1, 1, 0, 0 }, /* 3: Unused. */ 98 { 32767, -32768, INST_WORD_SIZE, LARGE_DEFINED_PC_OFFSET }, /* 4: DEFINED_PC_OFFSET. */ 99 { 1, 1, 0, 0 }, /* 5: Unused. */ 100 { 1, 1, 0, 0 }, /* 6: Unused. */ 101 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 7: LARGE_DEFINED_PC_OFFSET. */ 102 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 8: GOT_OFFSET. */ 103 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 9: PLT_OFFSET. */ 104 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 10: GOTOFF_OFFSET. */ 105 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 11: TLSGD_OFFSET. */ 106 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 12: TLSLD_OFFSET. */ 107 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*1, 0 }, /* 13: TLSDTPMOD_OFFSET. */ 108 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 14: TLSDTPREL_OFFSET. */ 109 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 }, /* 15: TLSGOTTPREL_OFFSET. */ 110 { 0x7fffffff, 0x80000000, INST_WORD_SIZE*2, 0 } /* 16: TLSTPREL_OFFSET. */ 111 }; 112 113 static struct hash_control * opcode_hash_control; /* Opcode mnemonics. */ 114 115 static segT sbss_segment = 0; /* Small bss section. */ 116 static segT sbss2_segment = 0; /* Section not used. */ 117 static segT sdata_segment = 0; /* Small data section. */ 118 static segT sdata2_segment = 0; /* Small read-only section. */ 119 static segT rodata_segment = 0; /* read-only section. */ 120 121 /* Generate a symbol for stabs information. */ 122 123 void 124 microblaze_generate_symbol (char *sym) 125 { 126 #define MICROBLAZE_FAKE_LABEL_NAME "XL0\001" 127 static int microblaze_label_count; 128 sprintf (sym, "%sL%d", MICROBLAZE_FAKE_LABEL_NAME, microblaze_label_count); 129 ++microblaze_label_count; 130 } 131 132 /* Handle the section changing pseudo-ops. */ 133 134 static void 135 microblaze_s_text (int ignore ATTRIBUTE_UNUSED) 136 { 137 #ifdef OBJ_ELF 138 obj_elf_text (ignore); 139 #else 140 s_text (ignore); 141 #endif 142 } 143 144 static void 145 microblaze_s_data (int ignore ATTRIBUTE_UNUSED) 146 { 147 #ifdef OBJ_ELF 148 obj_elf_change_section (".data", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE, 149 0, 0, 0, 0); 150 #else 151 s_data (ignore); 152 #endif 153 } 154 155 /* Things in the .sdata segment are always considered to be in the small data section. */ 156 157 static void 158 microblaze_s_sdata (int ignore ATTRIBUTE_UNUSED) 159 { 160 #ifdef OBJ_ELF 161 obj_elf_change_section (".sdata", SHT_PROGBITS, 0, SHF_ALLOC+SHF_WRITE, 162 0, 0, 0, 0); 163 #else 164 s_data (ignore); 165 #endif 166 } 167 168 /* Pseudo op to make file scope bss items. */ 169 170 static void 171 microblaze_s_lcomm (int xxx ATTRIBUTE_UNUSED) 172 { 173 char *name; 174 char c; 175 char *p; 176 offsetT size; 177 symbolS *symbolP; 178 offsetT align; 179 char *pfrag; 180 int align2; 181 segT current_seg = now_seg; 182 subsegT current_subseg = now_subseg; 183 184 c = get_symbol_name (&name); 185 186 /* Just after name is now '\0'. */ 187 p = input_line_pointer; 188 (void) restore_line_pointer (c); 189 SKIP_WHITESPACE (); 190 if (*input_line_pointer != ',') 191 { 192 as_bad (_("Expected comma after symbol-name: rest of line ignored.")); 193 ignore_rest_of_line (); 194 return; 195 } 196 197 input_line_pointer++; /* skip ',' */ 198 if ((size = get_absolute_expression ()) < 0) 199 { 200 as_warn (_(".COMMon length (%ld.) <0! Ignored."), (long) size); 201 ignore_rest_of_line (); 202 return; 203 } 204 205 /* The third argument to .lcomm is the alignment. */ 206 if (*input_line_pointer != ',') 207 align = 8; 208 else 209 { 210 ++input_line_pointer; 211 align = get_absolute_expression (); 212 if (align <= 0) 213 { 214 as_warn (_("ignoring bad alignment")); 215 align = 8; 216 } 217 } 218 219 *p = 0; 220 symbolP = symbol_find_or_make (name); 221 *p = c; 222 223 if (S_IS_DEFINED (symbolP) && ! S_IS_COMMON (symbolP)) 224 { 225 as_bad (_("Ignoring attempt to re-define symbol `%s'."), 226 S_GET_NAME (symbolP)); 227 ignore_rest_of_line (); 228 return; 229 } 230 231 if (S_GET_VALUE (symbolP) && S_GET_VALUE (symbolP) != (valueT) size) 232 { 233 as_bad (_("Length of .lcomm \"%s\" is already %ld. Not changed to %ld."), 234 S_GET_NAME (symbolP), 235 (long) S_GET_VALUE (symbolP), 236 (long) size); 237 238 ignore_rest_of_line (); 239 return; 240 } 241 242 /* Allocate_bss. */ 243 if (align) 244 { 245 /* Convert to a power of 2 alignment. */ 246 for (align2 = 0; (align & 1) == 0; align >>= 1, ++align2); 247 if (align != 1) 248 { 249 as_bad (_("Common alignment not a power of 2")); 250 ignore_rest_of_line (); 251 return; 252 } 253 } 254 else 255 align2 = 0; 256 257 record_alignment (current_seg, align2); 258 subseg_set (current_seg, current_subseg); 259 if (align2) 260 frag_align (align2, 0, 0); 261 if (S_GET_SEGMENT (symbolP) == current_seg) 262 symbol_get_frag (symbolP)->fr_symbol = 0; 263 symbol_set_frag (symbolP, frag_now); 264 pfrag = frag_var (rs_org, 1, 1, (relax_substateT) 0, symbolP, size, 265 (char *) 0); 266 *pfrag = 0; 267 S_SET_SIZE (symbolP, size); 268 S_SET_SEGMENT (symbolP, current_seg); 269 subseg_set (current_seg, current_subseg); 270 demand_empty_rest_of_line (); 271 } 272 273 static void 274 microblaze_s_rdata (int localvar) 275 { 276 #ifdef OBJ_ELF 277 if (localvar == 0) 278 { 279 /* rodata. */ 280 obj_elf_change_section (".rodata", SHT_PROGBITS, 0, SHF_ALLOC, 281 0, 0, 0, 0); 282 if (rodata_segment == 0) 283 rodata_segment = subseg_new (".rodata", 0); 284 } 285 else 286 { 287 /* 1 .sdata2. */ 288 obj_elf_change_section (".sdata2", SHT_PROGBITS, 0, SHF_ALLOC, 289 0, 0, 0, 0); 290 } 291 #else 292 s_data (ignore); 293 #endif 294 } 295 296 static void 297 microblaze_s_bss (int localvar) 298 { 299 #ifdef OBJ_ELF 300 if (localvar == 0) /* bss. */ 301 obj_elf_change_section (".bss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE, 302 0, 0, 0, 0); 303 else if (localvar == 1) 304 { 305 /* sbss. */ 306 obj_elf_change_section (".sbss", SHT_NOBITS, 0, SHF_ALLOC+SHF_WRITE, 307 0, 0, 0, 0); 308 if (sbss_segment == 0) 309 sbss_segment = subseg_new (".sbss", 0); 310 } 311 #else 312 s_data (ignore); 313 #endif 314 } 315 316 /* endp_p is always 1 as this func is called only for .end <funcname> 317 This func consumes the <funcname> and calls regular processing 318 s_func(1) with arg 1 (1 for end). */ 319 320 static void 321 microblaze_s_func (int end_p ATTRIBUTE_UNUSED) 322 { 323 char *name; 324 restore_line_pointer (get_symbol_name (&name)); 325 s_func (1); 326 } 327 328 /* Handle the .weakext pseudo-op as defined in Kane and Heinrich. */ 329 330 static void 331 microblaze_s_weakext (int ignore ATTRIBUTE_UNUSED) 332 { 333 char *name; 334 int c; 335 symbolS *symbolP; 336 expressionS exp; 337 338 c = get_symbol_name (&name); 339 symbolP = symbol_find_or_make (name); 340 S_SET_WEAK (symbolP); 341 (void) restore_line_pointer (c); 342 343 SKIP_WHITESPACE (); 344 345 if (!is_end_of_line[(unsigned char) *input_line_pointer]) 346 { 347 if (S_IS_DEFINED (symbolP)) 348 { 349 as_bad ("Ignoring attempt to redefine symbol `%s'.", 350 S_GET_NAME (symbolP)); 351 ignore_rest_of_line (); 352 return; 353 } 354 355 if (*input_line_pointer == ',') 356 { 357 ++input_line_pointer; 358 SKIP_WHITESPACE (); 359 } 360 361 expression (&exp); 362 if (exp.X_op != O_symbol) 363 { 364 as_bad ("bad .weakext directive"); 365 ignore_rest_of_line (); 366 return; 367 } 368 symbol_set_value_expression (symbolP, &exp); 369 } 370 371 demand_empty_rest_of_line (); 372 } 373 374 /* This table describes all the machine specific pseudo-ops the assembler 375 has to support. The fields are: 376 Pseudo-op name without dot 377 Function to call to execute this pseudo-op 378 Integer arg to pass to the function. */ 379 /* If the pseudo-op is not found in this table, it searches in the obj-elf.c, 380 and then in the read.c table. */ 381 const pseudo_typeS md_pseudo_table[] = 382 { 383 {"lcomm", microblaze_s_lcomm, 1}, 384 {"data", microblaze_s_data, 0}, 385 {"data8", cons, 1}, /* Same as byte. */ 386 {"data16", cons, 2}, /* Same as hword. */ 387 {"data32", cons, 4}, /* Same as word. */ 388 {"ent", s_func, 0}, /* Treat ent as function entry point. */ 389 {"end", microblaze_s_func, 1}, /* Treat end as function end point. */ 390 {"gpword", s_rva, 4}, /* gpword label => store resolved label address in data section. */ 391 {"weakext", microblaze_s_weakext, 0}, 392 {"rodata", microblaze_s_rdata, 0}, 393 {"sdata2", microblaze_s_rdata, 1}, 394 {"sdata", microblaze_s_sdata, 0}, 395 {"bss", microblaze_s_bss, 0}, 396 {"sbss", microblaze_s_bss, 1}, 397 {"text", microblaze_s_text, 0}, 398 {"word", cons, 4}, 399 {"frame", s_ignore, 0}, 400 {"mask", s_ignore, 0}, /* Emitted by gcc. */ 401 {NULL, NULL, 0} 402 }; 403 404 /* This function is called once, at assembler startup time. This should 405 set up all the tables, etc that the MD part of the assembler needs. */ 406 407 void 408 md_begin (void) 409 { 410 struct op_code_struct * opcode; 411 412 opcode_hash_control = hash_new (); 413 414 /* Insert unique names into hash table. */ 415 for (opcode = opcodes; opcode->name; opcode ++) 416 hash_insert (opcode_hash_control, opcode->name, (char *) opcode); 417 } 418 419 /* Try to parse a reg name. */ 420 421 static char * 422 parse_reg (char * s, unsigned * reg) 423 { 424 unsigned tmpreg = 0; 425 426 /* Strip leading whitespace. */ 427 while (ISSPACE (* s)) 428 ++ s; 429 430 if (strncasecmp (s, "rpc", 3) == 0) 431 { 432 *reg = REG_PC; 433 return s + 3; 434 } 435 else if (strncasecmp (s, "rmsr", 4) == 0) 436 { 437 *reg = REG_MSR; 438 return s + 4; 439 } 440 else if (strncasecmp (s, "rear", 4) == 0) 441 { 442 *reg = REG_EAR; 443 return s + 4; 444 } 445 else if (strncasecmp (s, "resr", 4) == 0) 446 { 447 *reg = REG_ESR; 448 return s + 4; 449 } 450 else if (strncasecmp (s, "rfsr", 4) == 0) 451 { 452 *reg = REG_FSR; 453 return s + 4; 454 } 455 else if (strncasecmp (s, "rbtr", 4) == 0) 456 { 457 *reg = REG_BTR; 458 return s + 4; 459 } 460 else if (strncasecmp (s, "redr", 4) == 0) 461 { 462 *reg = REG_EDR; 463 return s + 4; 464 } 465 /* MMU registers start. */ 466 else if (strncasecmp (s, "rpid", 4) == 0) 467 { 468 *reg = REG_PID; 469 return s + 4; 470 } 471 else if (strncasecmp (s, "rzpr", 4) == 0) 472 { 473 *reg = REG_ZPR; 474 return s + 4; 475 } 476 else if (strncasecmp (s, "rtlbx", 5) == 0) 477 { 478 *reg = REG_TLBX; 479 return s + 5; 480 } 481 else if (strncasecmp (s, "rtlblo", 6) == 0) 482 { 483 *reg = REG_TLBLO; 484 return s + 6; 485 } 486 else if (strncasecmp (s, "rtlbhi", 6) == 0) 487 { 488 *reg = REG_TLBHI; 489 return s + 6; 490 } 491 else if (strncasecmp (s, "rtlbsx", 6) == 0) 492 { 493 *reg = REG_TLBSX; 494 return s + 6; 495 } 496 /* MMU registers end. */ 497 else if (strncasecmp (s, "rpvr", 4) == 0) 498 { 499 if (ISDIGIT (s[4]) && ISDIGIT (s[5])) 500 { 501 tmpreg = (s[4]-'0')*10 + s[5] - '0'; 502 s += 6; 503 } 504 505 else if (ISDIGIT (s[4])) 506 { 507 tmpreg = s[4] - '0'; 508 s += 5; 509 } 510 else 511 as_bad (_("register expected, but saw '%.6s'"), s); 512 if ((int) tmpreg >= MIN_PVR_REGNUM && tmpreg <= MAX_PVR_REGNUM) 513 *reg = REG_PVR + tmpreg; 514 else 515 { 516 as_bad (_("Invalid register number at '%.6s'"), s); 517 *reg = REG_PVR; 518 } 519 return s; 520 } 521 else if (strncasecmp (s, "rsp", 3) == 0) 522 { 523 *reg = REG_SP; 524 return s + 3; 525 } 526 else if (strncasecmp (s, "rfsl", 4) == 0) 527 { 528 if (ISDIGIT (s[4]) && ISDIGIT (s[5])) 529 { 530 tmpreg = (s[4] - '0') * 10 + s[5] - '0'; 531 s += 6; 532 } 533 else if (ISDIGIT (s[4])) 534 { 535 tmpreg = s[4] - '0'; 536 s += 5; 537 } 538 else 539 as_bad (_("register expected, but saw '%.6s'"), s); 540 541 if ((int) tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM) 542 *reg = tmpreg; 543 else 544 { 545 as_bad (_("Invalid register number at '%.6s'"), s); 546 *reg = 0; 547 } 548 return s; 549 } 550 /* Stack protection registers. */ 551 else if (strncasecmp (s, "rshr", 4) == 0) 552 { 553 *reg = REG_SHR; 554 return s + 4; 555 } 556 else if (strncasecmp (s, "rslr", 4) == 0) 557 { 558 *reg = REG_SLR; 559 return s + 4; 560 } 561 else 562 { 563 if (TOLOWER (s[0]) == 'r') 564 { 565 if (ISDIGIT (s[1]) && ISDIGIT (s[2])) 566 { 567 tmpreg = (s[1] - '0') * 10 + s[2] - '0'; 568 s += 3; 569 } 570 else if (ISDIGIT (s[1])) 571 { 572 tmpreg = s[1] - '0'; 573 s += 2; 574 } 575 else 576 as_bad (_("register expected, but saw '%.6s'"), s); 577 578 if ((int)tmpreg >= MIN_REGNUM && tmpreg <= MAX_REGNUM) 579 *reg = tmpreg; 580 else 581 { 582 as_bad (_("Invalid register number at '%.6s'"), s); 583 *reg = 0; 584 } 585 return s; 586 } 587 } 588 as_bad (_("register expected, but saw '%.6s'"), s); 589 *reg = 0; 590 return s; 591 } 592 593 static char * 594 parse_exp (char *s, expressionS *e) 595 { 596 char *save; 597 char *new_pointer; 598 599 /* Skip whitespace. */ 600 while (ISSPACE (* s)) 601 ++ s; 602 603 save = input_line_pointer; 604 input_line_pointer = s; 605 606 expression (e); 607 608 if (e->X_op == O_absent) 609 as_fatal (_("missing operand")); 610 611 new_pointer = input_line_pointer; 612 input_line_pointer = save; 613 614 return new_pointer; 615 } 616 617 /* Symbol modifiers (@GOT, @PLT, @GOTOFF). */ 618 #define IMM_NONE 0 619 #define IMM_GOT 1 620 #define IMM_PLT 2 621 #define IMM_GOTOFF 3 622 #define IMM_TLSGD 4 623 #define IMM_TLSLD 5 624 #define IMM_TLSDTPMOD 6 625 #define IMM_TLSDTPREL 7 626 #define IMM_TLSTPREL 8 627 #define IMM_MAX 9 628 629 struct imm_type { 630 const char *isuffix; /* Suffix String */ 631 int itype; /* Suffix Type */ 632 int otype; /* Offset Type */ 633 }; 634 635 /* These are NOT in ascending order of type, GOTOFF is ahead to make 636 sure @GOTOFF does not get matched with @GOT */ 637 static struct imm_type imm_types[] = { 638 { "NONE", IMM_NONE , 0 }, 639 { "GOTOFF", IMM_GOTOFF , GOTOFF_OFFSET }, 640 { "GOT", IMM_GOT , GOT_OFFSET }, 641 { "PLT", IMM_PLT , PLT_OFFSET }, 642 { "TLSGD", IMM_TLSGD , TLSGD_OFFSET }, 643 { "TLSLDM", IMM_TLSLD, TLSLD_OFFSET }, 644 { "TLSDTPMOD", IMM_TLSDTPMOD, TLSDTPMOD_OFFSET }, 645 { "TLSDTPREL", IMM_TLSDTPREL, TLSDTPREL_OFFSET }, 646 { "TLSTPREL", IMM_TLSTPREL, TLSTPREL_OFFSET } 647 }; 648 649 static int 650 match_imm (const char *s, int *ilen) 651 { 652 int i; 653 int slen; 654 655 /* Check for matching suffix */ 656 for (i = 1; i < IMM_MAX; i++) 657 { 658 slen = strlen (imm_types[i].isuffix); 659 660 if (strncmp (imm_types[i].isuffix, s, slen) == 0) 661 { 662 *ilen = slen; 663 return imm_types[i].itype; 664 } 665 } /* for */ 666 *ilen = 0; 667 return 0; 668 } 669 670 static int 671 get_imm_otype (int itype) 672 { 673 int i, otype; 674 675 otype = 0; 676 /* Check for matching itype */ 677 for (i = 1; i < IMM_MAX; i++) 678 { 679 if (imm_types[i].itype == itype) 680 { 681 otype = imm_types[i].otype; 682 break; 683 } 684 } 685 return otype; 686 } 687 688 static symbolS * GOT_symbol; 689 690 #define GOT_SYMBOL_NAME "_GLOBAL_OFFSET_TABLE_" 691 692 static char * 693 parse_imm (char * s, expressionS * e, offsetT min, offsetT max) 694 { 695 char *new_pointer; 696 char *atp; 697 int itype, ilen; 698 699 ilen = 0; 700 701 /* Find the start of "@GOT" or "@PLT" suffix (if any) */ 702 for (atp = s; *atp != '@'; atp++) 703 if (is_end_of_line[(unsigned char) *atp]) 704 break; 705 706 if (*atp == '@') 707 { 708 itype = match_imm (atp + 1, &ilen); 709 if (itype != 0) 710 { 711 *atp = 0; 712 e->X_md = itype; 713 } 714 else 715 { 716 atp = NULL; 717 e->X_md = 0; 718 ilen = 0; 719 } 720 *atp = 0; 721 } 722 else 723 { 724 atp = NULL; 725 e->X_md = 0; 726 } 727 728 if (atp && !GOT_symbol) 729 { 730 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME); 731 } 732 733 new_pointer = parse_exp (s, e); 734 735 if (!GOT_symbol && ! strncmp (s, GOT_SYMBOL_NAME, 20)) 736 { 737 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME); 738 } 739 740 if (e->X_op == O_absent) 741 ; /* An error message has already been emitted. */ 742 else if ((e->X_op != O_constant && e->X_op != O_symbol) ) 743 as_fatal (_("operand must be a constant or a label")); 744 else if (e->X_op == O_constant) 745 { 746 /* Special case: sign extend negative 32-bit values to offsetT size. */ 747 if ((e->X_add_number >> 31) == 1) 748 e->X_add_number |= -((addressT) (1U << 31)); 749 750 if (e->X_add_number < min || e->X_add_number > max) 751 { 752 as_fatal (_("operand must be absolute in range %lx..%lx, not %lx"), 753 (long) min, (long) max, (long) e->X_add_number); 754 } 755 } 756 757 if (atp) 758 { 759 *atp = '@'; /* restore back (needed?) */ 760 if (new_pointer >= atp) 761 new_pointer += ilen + 1; /* sizeof (imm_suffix) + 1 for '@' */ 762 } 763 return new_pointer; 764 } 765 766 static char * 767 check_got (int * got_type, int * got_len) 768 { 769 char *new_pointer; 770 char *atp; 771 char *past_got; 772 int first, second; 773 char *tmpbuf; 774 775 /* Find the start of "@GOT" or "@PLT" suffix (if any). */ 776 for (atp = input_line_pointer; *atp != '@'; atp++) 777 if (is_end_of_line[(unsigned char) *atp]) 778 return NULL; 779 780 if (strncmp (atp + 1, "GOTOFF", 5) == 0) 781 { 782 *got_len = 6; 783 *got_type = IMM_GOTOFF; 784 } 785 else if (strncmp (atp + 1, "GOT", 3) == 0) 786 { 787 *got_len = 3; 788 *got_type = IMM_GOT; 789 } 790 else if (strncmp (atp + 1, "PLT", 3) == 0) 791 { 792 *got_len = 3; 793 *got_type = IMM_PLT; 794 } 795 else 796 return NULL; 797 798 if (!GOT_symbol) 799 GOT_symbol = symbol_find_or_make (GOT_SYMBOL_NAME); 800 801 first = atp - input_line_pointer; 802 803 past_got = atp + *got_len + 1; 804 for (new_pointer = past_got; !is_end_of_line[(unsigned char) *new_pointer++];) 805 ; 806 second = new_pointer - past_got; 807 /* One extra byte for ' ' and one for NUL. */ 808 tmpbuf = XNEWVEC (char, first + second + 2); 809 memcpy (tmpbuf, input_line_pointer, first); 810 tmpbuf[first] = ' '; /* @GOTOFF is replaced with a single space. */ 811 memcpy (tmpbuf + first + 1, past_got, second); 812 tmpbuf[first + second + 1] = '\0'; 813 814 return tmpbuf; 815 } 816 817 extern bfd_reloc_code_real_type 818 parse_cons_expression_microblaze (expressionS *exp, int size) 819 { 820 if (size == 4) 821 { 822 /* Handle @GOTOFF et.al. */ 823 char *save, *gotfree_copy; 824 int got_len, got_type; 825 826 save = input_line_pointer; 827 gotfree_copy = check_got (& got_type, & got_len); 828 if (gotfree_copy) 829 input_line_pointer = gotfree_copy; 830 831 expression (exp); 832 833 if (gotfree_copy) 834 { 835 exp->X_md = got_type; 836 input_line_pointer = save + (input_line_pointer - gotfree_copy) 837 + got_len; 838 free (gotfree_copy); 839 } 840 } 841 else 842 expression (exp); 843 return BFD_RELOC_NONE; 844 } 845 846 /* This is the guts of the machine-dependent assembler. STR points to a 847 machine dependent instruction. This function is supposed to emit 848 the frags/bytes it assembles to. */ 849 850 static const char * str_microblaze_ro_anchor = "RO"; 851 static const char * str_microblaze_rw_anchor = "RW"; 852 853 static bfd_boolean 854 check_spl_reg (unsigned * reg) 855 { 856 if ((*reg == REG_MSR) || (*reg == REG_PC) 857 || (*reg == REG_EAR) || (*reg == REG_ESR) 858 || (*reg == REG_FSR) || (*reg == REG_BTR) || (*reg == REG_EDR) 859 || (*reg == REG_PID) || (*reg == REG_ZPR) 860 || (*reg == REG_TLBX) || (*reg == REG_TLBLO) 861 || (*reg == REG_TLBHI) || (*reg == REG_TLBSX) 862 || (*reg == REG_SHR) || (*reg == REG_SLR) 863 || (*reg >= REG_PVR+MIN_PVR_REGNUM && *reg <= REG_PVR+MAX_PVR_REGNUM)) 864 return TRUE; 865 866 return FALSE; 867 } 868 869 /* Here we decide which fixups can be adjusted to make them relative to 870 the beginning of the section instead of the symbol. Basically we need 871 to make sure that the dynamic relocations are done correctly, so in 872 some cases we force the original symbol to be used. */ 873 874 int 875 tc_microblaze_fix_adjustable (struct fix *fixP) 876 { 877 if (GOT_symbol && fixP->fx_subsy == GOT_symbol) 878 return 0; 879 880 if (fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOTOFF 881 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_GOTOFF 882 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_GOT 883 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_PLT 884 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGD 885 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSLD 886 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPMOD 887 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_32_TLSDTPREL 888 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSDTPREL 889 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL 890 || fixP->fx_r_type == BFD_RELOC_MICROBLAZE_64_TLSTPREL) 891 return 0; 892 893 return 1; 894 } 895 896 void 897 md_assemble (char * str) 898 { 899 char * op_start; 900 char * op_end; 901 struct op_code_struct * opcode, *opcode1; 902 char * output = NULL; 903 int nlen = 0; 904 int i; 905 unsigned long inst, inst1; 906 unsigned reg1; 907 unsigned reg2; 908 unsigned reg3; 909 unsigned isize; 910 unsigned int immed, temp; 911 expressionS exp; 912 char name[20]; 913 914 /* Drop leading whitespace. */ 915 while (ISSPACE (* str)) 916 str ++; 917 918 /* Find the op code end. */ 919 for (op_start = op_end = str; 920 *op_end && !is_end_of_line[(unsigned char) *op_end] && *op_end != ' '; 921 op_end++) 922 { 923 name[nlen] = op_start[nlen]; 924 nlen++; 925 if (nlen == sizeof (name) - 1) 926 break; 927 } 928 929 name [nlen] = 0; 930 931 if (nlen == 0) 932 { 933 as_bad (_("can't find opcode ")); 934 return; 935 } 936 937 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, name); 938 if (opcode == NULL) 939 { 940 as_bad (_("unknown opcode \"%s\""), name); 941 return; 942 } 943 944 inst = opcode->bit_sequence; 945 isize = 4; 946 947 switch (opcode->inst_type) 948 { 949 case INST_TYPE_RD_R1_R2: 950 if (strcmp (op_end, "")) 951 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 952 else 953 { 954 as_fatal (_("Error in statement syntax")); 955 reg1 = 0; 956 } 957 if (strcmp (op_end, "")) 958 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ 959 else 960 { 961 as_fatal (_("Error in statement syntax")); 962 reg2 = 0; 963 } 964 if (strcmp (op_end, "")) 965 op_end = parse_reg (op_end + 1, ®3); /* Get r2. */ 966 else 967 { 968 as_fatal (_("Error in statement syntax")); 969 reg3 = 0; 970 } 971 972 /* Check for spl registers. */ 973 if (check_spl_reg (& reg1)) 974 as_fatal (_("Cannot use special register with this instruction")); 975 if (check_spl_reg (& reg2)) 976 as_fatal (_("Cannot use special register with this instruction")); 977 if (check_spl_reg (& reg3)) 978 as_fatal (_("Cannot use special register with this instruction")); 979 980 if (streq (name, "sub")) 981 { 982 /* sub rd, r1, r2 becomes rsub rd, r2, r1. */ 983 inst |= (reg1 << RD_LOW) & RD_MASK; 984 inst |= (reg3 << RA_LOW) & RA_MASK; 985 inst |= (reg2 << RB_LOW) & RB_MASK; 986 } 987 else 988 { 989 inst |= (reg1 << RD_LOW) & RD_MASK; 990 inst |= (reg2 << RA_LOW) & RA_MASK; 991 inst |= (reg3 << RB_LOW) & RB_MASK; 992 } 993 output = frag_more (isize); 994 break; 995 996 case INST_TYPE_RD_R1_IMM: 997 if (strcmp (op_end, "")) 998 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 999 else 1000 { 1001 as_fatal (_("Error in statement syntax")); 1002 reg1 = 0; 1003 } 1004 if (strcmp (op_end, "")) 1005 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ 1006 else 1007 { 1008 as_fatal (_("Error in statement syntax")); 1009 reg2 = 0; 1010 } 1011 if (strcmp (op_end, "")) 1012 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); 1013 else 1014 as_fatal (_("Error in statement syntax")); 1015 1016 /* Check for spl registers. */ 1017 if (check_spl_reg (& reg1)) 1018 as_fatal (_("Cannot use special register with this instruction")); 1019 if (check_spl_reg (& reg2)) 1020 as_fatal (_("Cannot use special register with this instruction")); 1021 1022 if (exp.X_op != O_constant) 1023 { 1024 const char *opc; 1025 relax_substateT subtype; 1026 1027 if (streq (name, "lmi")) 1028 as_fatal (_("lmi pseudo instruction should not use a label in imm field")); 1029 else if (streq (name, "smi")) 1030 as_fatal (_("smi pseudo instruction should not use a label in imm field")); 1031 1032 if (reg2 == REG_ROSDP) 1033 opc = str_microblaze_ro_anchor; 1034 else if (reg2 == REG_RWSDP) 1035 opc = str_microblaze_rw_anchor; 1036 else 1037 opc = NULL; 1038 if (exp.X_md != 0) 1039 subtype = get_imm_otype(exp.X_md); 1040 else 1041 subtype = opcode->inst_offset_type; 1042 1043 output = frag_var (rs_machine_dependent, 1044 isize * 2, /* maxm of 2 words. */ 1045 isize, /* minm of 1 word. */ 1046 subtype, /* PC-relative or not. */ 1047 exp.X_add_symbol, 1048 exp.X_add_number, 1049 (char *) opc); 1050 immed = 0; 1051 } 1052 else 1053 { 1054 output = frag_more (isize); 1055 immed = exp.X_add_number; 1056 } 1057 1058 if (streq (name, "lmi") || streq (name, "smi")) 1059 { 1060 /* Load/store 32-d consecutive registers. Used on exit/entry 1061 to subroutines to save and restore registers to stack. 1062 Generate 32-d insts. */ 1063 int count; 1064 1065 count = 32 - reg1; 1066 if (streq (name, "lmi")) 1067 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "lwi"); 1068 else 1069 opcode = (struct op_code_struct *) hash_find (opcode_hash_control, "swi"); 1070 if (opcode == NULL) 1071 { 1072 as_bad (_("unknown opcode \"%s\""), "lwi"); 1073 return; 1074 } 1075 inst = opcode->bit_sequence; 1076 inst |= (reg1 << RD_LOW) & RD_MASK; 1077 inst |= (reg2 << RA_LOW) & RA_MASK; 1078 inst |= (immed << IMM_LOW) & IMM_MASK; 1079 1080 for (i = 0; i < count - 1; i++) 1081 { 1082 output[0] = INST_BYTE0 (inst); 1083 output[1] = INST_BYTE1 (inst); 1084 output[2] = INST_BYTE2 (inst); 1085 output[3] = INST_BYTE3 (inst); 1086 output = frag_more (isize); 1087 immed = immed + 4; 1088 reg1++; 1089 inst = opcode->bit_sequence; 1090 inst |= (reg1 << RD_LOW) & RD_MASK; 1091 inst |= (reg2 << RA_LOW) & RA_MASK; 1092 inst |= (immed << IMM_LOW) & IMM_MASK; 1093 } 1094 } 1095 else 1096 { 1097 temp = immed & 0xFFFF8000; 1098 if ((temp != 0) && (temp != 0xFFFF8000)) 1099 { 1100 /* Needs an immediate inst. */ 1101 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); 1102 if (opcode1 == NULL) 1103 { 1104 as_bad (_("unknown opcode \"%s\""), "imm"); 1105 return; 1106 } 1107 1108 inst1 = opcode1->bit_sequence; 1109 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; 1110 output[0] = INST_BYTE0 (inst1); 1111 output[1] = INST_BYTE1 (inst1); 1112 output[2] = INST_BYTE2 (inst1); 1113 output[3] = INST_BYTE3 (inst1); 1114 output = frag_more (isize); 1115 } 1116 inst |= (reg1 << RD_LOW) & RD_MASK; 1117 inst |= (reg2 << RA_LOW) & RA_MASK; 1118 inst |= (immed << IMM_LOW) & IMM_MASK; 1119 } 1120 break; 1121 1122 case INST_TYPE_RD_R1_IMM5: 1123 if (strcmp (op_end, "")) 1124 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1125 else 1126 { 1127 as_fatal (_("Error in statement syntax")); 1128 reg1 = 0; 1129 } 1130 if (strcmp (op_end, "")) 1131 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ 1132 else 1133 { 1134 as_fatal (_("Error in statement syntax")); 1135 reg2 = 0; 1136 } 1137 if (strcmp (op_end, "")) 1138 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); 1139 else 1140 as_fatal (_("Error in statement syntax")); 1141 1142 /* Check for spl registers. */ 1143 if (check_spl_reg (®1)) 1144 as_fatal (_("Cannot use special register with this instruction")); 1145 if (check_spl_reg (®2)) 1146 as_fatal (_("Cannot use special register with this instruction")); 1147 1148 if (exp.X_op != O_constant) 1149 as_warn (_("Symbol used as immediate for shift instruction")); 1150 else 1151 { 1152 output = frag_more (isize); 1153 immed = exp.X_add_number; 1154 } 1155 1156 if (immed != (immed % 32)) 1157 { 1158 as_warn (_("Shift value > 32. using <value %% 32>")); 1159 immed = immed % 32; 1160 } 1161 inst |= (reg1 << RD_LOW) & RD_MASK; 1162 inst |= (reg2 << RA_LOW) & RA_MASK; 1163 inst |= (immed << IMM_LOW) & IMM5_MASK; 1164 break; 1165 1166 case INST_TYPE_R1_R2: 1167 if (strcmp (op_end, "")) 1168 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ 1169 else 1170 { 1171 as_fatal (_("Error in statement syntax")); 1172 reg1 = 0; 1173 } 1174 if (strcmp (op_end, "")) 1175 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */ 1176 else 1177 { 1178 as_fatal (_("Error in statement syntax")); 1179 reg2 = 0; 1180 } 1181 1182 /* Check for spl registers. */ 1183 if (check_spl_reg (& reg1)) 1184 as_fatal (_("Cannot use special register with this instruction")); 1185 if (check_spl_reg (& reg2)) 1186 as_fatal (_("Cannot use special register with this instruction")); 1187 1188 inst |= (reg1 << RA_LOW) & RA_MASK; 1189 inst |= (reg2 << RB_LOW) & RB_MASK; 1190 output = frag_more (isize); 1191 break; 1192 1193 case INST_TYPE_RD_R1: 1194 if (strcmp (op_end, "")) 1195 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1196 else 1197 { 1198 as_fatal (_("Error in statement syntax")); 1199 reg1 = 0; 1200 } 1201 if (strcmp (op_end, "")) 1202 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ 1203 else 1204 { 1205 as_fatal (_("Error in statement syntax")); 1206 reg2 =0; 1207 } 1208 1209 /* Check for spl registers. */ 1210 if (check_spl_reg (®1)) 1211 as_fatal (_("Cannot use special register with this instruction")); 1212 if (check_spl_reg (®2)) 1213 as_fatal (_("Cannot use special register with this instruction")); 1214 1215 inst |= (reg1 << RD_LOW) & RD_MASK; 1216 inst |= (reg2 << RA_LOW) & RA_MASK; 1217 output = frag_more (isize); 1218 break; 1219 1220 case INST_TYPE_RD_RFSL: 1221 if (strcmp (op_end, "")) 1222 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1223 else 1224 { 1225 as_fatal (_("Error in statement syntax")); 1226 reg1 = 0; 1227 } 1228 if (strcmp (op_end, "")) 1229 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */ 1230 else 1231 { 1232 as_fatal (_("Error in statement syntax")); 1233 immed = 0; 1234 } 1235 1236 /* Check for spl registers. */ 1237 if (check_spl_reg (®1)) 1238 as_fatal (_("Cannot use special register with this instruction")); 1239 1240 inst |= (reg1 << RD_LOW) & RD_MASK; 1241 inst |= (immed << IMM_LOW) & RFSL_MASK; 1242 output = frag_more (isize); 1243 break; 1244 1245 case INST_TYPE_RD_IMM15: 1246 if (strcmp (op_end, "")) 1247 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1248 else 1249 { 1250 as_fatal (_("Error in statement syntax")); 1251 reg1 = 0; 1252 } 1253 1254 if (strcmp (op_end, "")) 1255 op_end = parse_imm (op_end + 1, & exp, MIN_IMM15, MAX_IMM15); 1256 else 1257 as_fatal (_("Error in statement syntax")); 1258 1259 /* Check for spl registers. */ 1260 if (check_spl_reg (®1)) 1261 as_fatal (_("Cannot use special register with this instruction")); 1262 1263 if (exp.X_op != O_constant) 1264 as_fatal (_("Symbol used as immediate value for msrset/msrclr instructions")); 1265 else 1266 { 1267 output = frag_more (isize); 1268 immed = exp.X_add_number; 1269 } 1270 inst |= (reg1 << RD_LOW) & RD_MASK; 1271 inst |= (immed << IMM_LOW) & IMM15_MASK; 1272 break; 1273 1274 case INST_TYPE_R1_RFSL: 1275 if (strcmp (op_end, "")) 1276 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ 1277 else 1278 { 1279 as_fatal (_("Error in statement syntax")); 1280 reg1 = 0; 1281 } 1282 if (strcmp (op_end, "")) 1283 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */ 1284 else 1285 { 1286 as_fatal (_("Error in statement syntax")); 1287 immed = 0; 1288 } 1289 1290 /* Check for spl registers. */ 1291 if (check_spl_reg (®1)) 1292 as_fatal (_("Cannot use special register with this instruction")); 1293 1294 inst |= (reg1 << RA_LOW) & RA_MASK; 1295 inst |= (immed << IMM_LOW) & RFSL_MASK; 1296 output = frag_more (isize); 1297 break; 1298 1299 case INST_TYPE_RFSL: 1300 if (strcmp (op_end, "")) 1301 op_end = parse_reg (op_end + 1, &immed); /* Get rfslN. */ 1302 else 1303 { 1304 as_fatal (_("Error in statement syntax")); 1305 immed = 0; 1306 } 1307 inst |= (immed << IMM_LOW) & RFSL_MASK; 1308 output = frag_more (isize); 1309 break; 1310 1311 case INST_TYPE_R1: 1312 if (strcmp (op_end, "")) 1313 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ 1314 else 1315 { 1316 as_fatal (_("Error in statement syntax")); 1317 reg1 = 0; 1318 } 1319 1320 /* Check for spl registers. */ 1321 if (check_spl_reg (®1)) 1322 as_fatal (_("Cannot use special register with this instruction")); 1323 1324 inst |= (reg1 << RA_LOW) & RA_MASK; 1325 output = frag_more (isize); 1326 break; 1327 1328 /* For tuqula insn...:) */ 1329 case INST_TYPE_RD: 1330 if (strcmp (op_end, "")) 1331 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1332 else 1333 { 1334 as_fatal (_("Error in statement syntax")); 1335 reg1 = 0; 1336 } 1337 1338 /* Check for spl registers. */ 1339 if (check_spl_reg (®1)) 1340 as_fatal (_("Cannot use special register with this instruction")); 1341 1342 inst |= (reg1 << RD_LOW) & RD_MASK; 1343 output = frag_more (isize); 1344 break; 1345 1346 case INST_TYPE_RD_SPECIAL: 1347 if (strcmp (op_end, "")) 1348 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1349 else 1350 { 1351 as_fatal (_("Error in statement syntax")); 1352 reg1 = 0; 1353 } 1354 if (strcmp (op_end, "")) 1355 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ 1356 else 1357 { 1358 as_fatal (_("Error in statement syntax")); 1359 reg2 = 0; 1360 } 1361 1362 if (reg2 == REG_MSR) 1363 immed = opcode->immval_mask | REG_MSR_MASK; 1364 else if (reg2 == REG_PC) 1365 immed = opcode->immval_mask | REG_PC_MASK; 1366 else if (reg2 == REG_EAR) 1367 immed = opcode->immval_mask | REG_EAR_MASK; 1368 else if (reg2 == REG_ESR) 1369 immed = opcode->immval_mask | REG_ESR_MASK; 1370 else if (reg2 == REG_FSR) 1371 immed = opcode->immval_mask | REG_FSR_MASK; 1372 else if (reg2 == REG_BTR) 1373 immed = opcode->immval_mask | REG_BTR_MASK; 1374 else if (reg2 == REG_EDR) 1375 immed = opcode->immval_mask | REG_EDR_MASK; 1376 else if (reg2 == REG_PID) 1377 immed = opcode->immval_mask | REG_PID_MASK; 1378 else if (reg2 == REG_ZPR) 1379 immed = opcode->immval_mask | REG_ZPR_MASK; 1380 else if (reg2 == REG_TLBX) 1381 immed = opcode->immval_mask | REG_TLBX_MASK; 1382 else if (reg2 == REG_TLBLO) 1383 immed = opcode->immval_mask | REG_TLBLO_MASK; 1384 else if (reg2 == REG_TLBHI) 1385 immed = opcode->immval_mask | REG_TLBHI_MASK; 1386 else if (reg2 == REG_SHR) 1387 immed = opcode->immval_mask | REG_SHR_MASK; 1388 else if (reg2 == REG_SLR) 1389 immed = opcode->immval_mask | REG_SLR_MASK; 1390 else if (reg2 >= (REG_PVR+MIN_PVR_REGNUM) && reg2 <= (REG_PVR+MAX_PVR_REGNUM)) 1391 immed = opcode->immval_mask | REG_PVR_MASK | reg2; 1392 else 1393 as_fatal (_("invalid value for special purpose register")); 1394 inst |= (reg1 << RD_LOW) & RD_MASK; 1395 inst |= (immed << IMM_LOW) & IMM_MASK; 1396 output = frag_more (isize); 1397 break; 1398 1399 case INST_TYPE_SPECIAL_R1: 1400 if (strcmp (op_end, "")) 1401 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1402 else 1403 { 1404 as_fatal (_("Error in statement syntax")); 1405 reg1 = 0; 1406 } 1407 if (strcmp (op_end, "")) 1408 op_end = parse_reg (op_end + 1, ®2); /* Get r1. */ 1409 else 1410 { 1411 as_fatal (_("Error in statement syntax")); 1412 reg2 = 0; 1413 } 1414 1415 if (reg1 == REG_MSR) 1416 immed = opcode->immval_mask | REG_MSR_MASK; 1417 else if (reg1 == REG_PC) 1418 immed = opcode->immval_mask | REG_PC_MASK; 1419 else if (reg1 == REG_EAR) 1420 immed = opcode->immval_mask | REG_EAR_MASK; 1421 else if (reg1 == REG_ESR) 1422 immed = opcode->immval_mask | REG_ESR_MASK; 1423 else if (reg1 == REG_FSR) 1424 immed = opcode->immval_mask | REG_FSR_MASK; 1425 else if (reg1 == REG_BTR) 1426 immed = opcode->immval_mask | REG_BTR_MASK; 1427 else if (reg1 == REG_EDR) 1428 immed = opcode->immval_mask | REG_EDR_MASK; 1429 else if (reg1 == REG_PID) 1430 immed = opcode->immval_mask | REG_PID_MASK; 1431 else if (reg1 == REG_ZPR) 1432 immed = opcode->immval_mask | REG_ZPR_MASK; 1433 else if (reg1 == REG_TLBX) 1434 immed = opcode->immval_mask | REG_TLBX_MASK; 1435 else if (reg1 == REG_TLBLO) 1436 immed = opcode->immval_mask | REG_TLBLO_MASK; 1437 else if (reg1 == REG_TLBHI) 1438 immed = opcode->immval_mask | REG_TLBHI_MASK; 1439 else if (reg1 == REG_TLBSX) 1440 immed = opcode->immval_mask | REG_TLBSX_MASK; 1441 else if (reg1 == REG_SHR) 1442 immed = opcode->immval_mask | REG_SHR_MASK; 1443 else if (reg1 == REG_SLR) 1444 immed = opcode->immval_mask | REG_SLR_MASK; 1445 else 1446 as_fatal (_("invalid value for special purpose register")); 1447 inst |= (reg2 << RA_LOW) & RA_MASK; 1448 inst |= (immed << IMM_LOW) & IMM_MASK; 1449 output = frag_more (isize); 1450 break; 1451 1452 case INST_TYPE_R1_R2_SPECIAL: 1453 if (strcmp (op_end, "")) 1454 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ 1455 else 1456 { 1457 as_fatal (_("Error in statement syntax")); 1458 reg1 = 0; 1459 } 1460 if (strcmp (op_end, "")) 1461 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */ 1462 else 1463 { 1464 as_fatal (_("Error in statement syntax")); 1465 reg2 =0; 1466 } 1467 1468 /* Check for spl registers. */ 1469 if (check_spl_reg (®1)) 1470 as_fatal (_("Cannot use special register with this instruction")); 1471 if (check_spl_reg (®2)) 1472 as_fatal (_("Cannot use special register with this instruction")); 1473 1474 /* insn wic ra, rb => wic ra, ra, rb. */ 1475 inst |= (reg1 << RA_LOW) & RA_MASK; 1476 inst |= (reg2 << RB_LOW) & RB_MASK; 1477 1478 output = frag_more (isize); 1479 break; 1480 1481 case INST_TYPE_RD_R2: 1482 if (strcmp (op_end, "")) 1483 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1484 else 1485 { 1486 as_fatal (_("Error in statement syntax")); 1487 reg1 = 0; 1488 } 1489 if (strcmp (op_end, "")) 1490 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */ 1491 else 1492 { 1493 as_fatal (_("Error in statement syntax")); 1494 reg2 = 0; 1495 } 1496 1497 /* Check for spl registers. */ 1498 if (check_spl_reg (®1)) 1499 as_fatal (_("Cannot use special register with this instruction")); 1500 if (check_spl_reg (®2)) 1501 as_fatal (_("Cannot use special register with this instruction")); 1502 1503 inst |= (reg1 << RD_LOW) & RD_MASK; 1504 inst |= (reg2 << RB_LOW) & RB_MASK; 1505 output = frag_more (isize); 1506 break; 1507 1508 case INST_TYPE_R1_IMM: 1509 if (strcmp (op_end, "")) 1510 op_end = parse_reg (op_end + 1, ®1); /* Get r1. */ 1511 else 1512 { 1513 as_fatal (_("Error in statement syntax")); 1514 reg1 = 0; 1515 } 1516 if (strcmp (op_end, "")) 1517 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); 1518 else 1519 as_fatal (_("Error in statement syntax")); 1520 1521 /* Check for spl registers. */ 1522 if (check_spl_reg (®1)) 1523 as_fatal (_("Cannot use special register with this instruction")); 1524 1525 if (exp.X_op != O_constant) 1526 { 1527 char *opc = NULL; 1528 relax_substateT subtype; 1529 1530 if (exp.X_md != 0) 1531 subtype = get_imm_otype(exp.X_md); 1532 else 1533 subtype = opcode->inst_offset_type; 1534 1535 output = frag_var (rs_machine_dependent, 1536 isize * 2, /* maxm of 2 words. */ 1537 isize, /* minm of 1 word. */ 1538 subtype, /* PC-relative or not. */ 1539 exp.X_add_symbol, 1540 exp.X_add_number, 1541 opc); 1542 immed = 0; 1543 } 1544 else 1545 { 1546 output = frag_more (isize); 1547 immed = exp.X_add_number; 1548 } 1549 1550 temp = immed & 0xFFFF8000; 1551 if ((temp != 0) && (temp != 0xFFFF8000)) 1552 { 1553 /* Needs an immediate inst. */ 1554 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); 1555 if (opcode1 == NULL) 1556 { 1557 as_bad (_("unknown opcode \"%s\""), "imm"); 1558 return; 1559 } 1560 1561 inst1 = opcode1->bit_sequence; 1562 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; 1563 output[0] = INST_BYTE0 (inst1); 1564 output[1] = INST_BYTE1 (inst1); 1565 output[2] = INST_BYTE2 (inst1); 1566 output[3] = INST_BYTE3 (inst1); 1567 output = frag_more (isize); 1568 } 1569 1570 inst |= (reg1 << RA_LOW) & RA_MASK; 1571 inst |= (immed << IMM_LOW) & IMM_MASK; 1572 break; 1573 1574 case INST_TYPE_RD_IMM: 1575 if (strcmp (op_end, "")) 1576 op_end = parse_reg (op_end + 1, ®1); /* Get rd. */ 1577 else 1578 { 1579 as_fatal (_("Error in statement syntax")); 1580 reg1 = 0; 1581 } 1582 if (strcmp (op_end, "")) 1583 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); 1584 else 1585 as_fatal (_("Error in statement syntax")); 1586 1587 /* Check for spl registers. */ 1588 if (check_spl_reg (®1)) 1589 as_fatal (_("Cannot use special register with this instruction")); 1590 1591 if (exp.X_op != O_constant) 1592 { 1593 char *opc = NULL; 1594 relax_substateT subtype; 1595 1596 if (exp.X_md != 0) 1597 subtype = get_imm_otype(exp.X_md); 1598 else 1599 subtype = opcode->inst_offset_type; 1600 1601 output = frag_var (rs_machine_dependent, 1602 isize * 2, /* maxm of 2 words. */ 1603 isize, /* minm of 1 word. */ 1604 subtype, /* PC-relative or not. */ 1605 exp.X_add_symbol, 1606 exp.X_add_number, 1607 opc); 1608 immed = 0; 1609 } 1610 else 1611 { 1612 output = frag_more (isize); 1613 immed = exp.X_add_number; 1614 } 1615 1616 temp = immed & 0xFFFF8000; 1617 if ((temp != 0) && (temp != 0xFFFF8000)) 1618 { 1619 /* Needs an immediate inst. */ 1620 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); 1621 if (opcode1 == NULL) 1622 { 1623 as_bad (_("unknown opcode \"%s\""), "imm"); 1624 return; 1625 } 1626 1627 inst1 = opcode1->bit_sequence; 1628 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; 1629 output[0] = INST_BYTE0 (inst1); 1630 output[1] = INST_BYTE1 (inst1); 1631 output[2] = INST_BYTE2 (inst1); 1632 output[3] = INST_BYTE3 (inst1); 1633 output = frag_more (isize); 1634 } 1635 1636 inst |= (reg1 << RD_LOW) & RD_MASK; 1637 inst |= (immed << IMM_LOW) & IMM_MASK; 1638 break; 1639 1640 case INST_TYPE_R2: 1641 if (strcmp (op_end, "")) 1642 op_end = parse_reg (op_end + 1, ®2); /* Get r2. */ 1643 else 1644 { 1645 as_fatal (_("Error in statement syntax")); 1646 reg2 = 0; 1647 } 1648 1649 /* Check for spl registers. */ 1650 if (check_spl_reg (®2)) 1651 as_fatal (_("Cannot use special register with this instruction")); 1652 1653 inst |= (reg2 << RB_LOW) & RB_MASK; 1654 output = frag_more (isize); 1655 break; 1656 1657 case INST_TYPE_IMM: 1658 if (streq (name, "imm")) 1659 as_fatal (_("An IMM instruction should not be present in the .s file")); 1660 1661 op_end = parse_imm (op_end + 1, & exp, MIN_IMM, MAX_IMM); 1662 1663 if (exp.X_op != O_constant) 1664 { 1665 char *opc = NULL; 1666 relax_substateT subtype; 1667 1668 if (exp.X_md != 0) 1669 subtype = get_imm_otype(exp.X_md); 1670 else 1671 subtype = opcode->inst_offset_type; 1672 1673 output = frag_var (rs_machine_dependent, 1674 isize * 2, /* maxm of 2 words. */ 1675 isize, /* minm of 1 word. */ 1676 subtype, /* PC-relative or not. */ 1677 exp.X_add_symbol, 1678 exp.X_add_number, 1679 opc); 1680 immed = 0; 1681 } 1682 else 1683 { 1684 output = frag_more (isize); 1685 immed = exp.X_add_number; 1686 } 1687 1688 1689 temp = immed & 0xFFFF8000; 1690 if ((temp != 0) && (temp != 0xFFFF8000)) 1691 { 1692 /* Needs an immediate inst. */ 1693 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); 1694 if (opcode1 == NULL) 1695 { 1696 as_bad (_("unknown opcode \"%s\""), "imm"); 1697 return; 1698 } 1699 1700 inst1 = opcode1->bit_sequence; 1701 inst1 |= ((immed & 0xFFFF0000) >> 16) & IMM_MASK; 1702 output[0] = INST_BYTE0 (inst1); 1703 output[1] = INST_BYTE1 (inst1); 1704 output[2] = INST_BYTE2 (inst1); 1705 output[3] = INST_BYTE3 (inst1); 1706 output = frag_more (isize); 1707 } 1708 inst |= (immed << IMM_LOW) & IMM_MASK; 1709 break; 1710 1711 case INST_TYPE_NONE: 1712 output = frag_more (isize); 1713 break; 1714 1715 case INST_TYPE_IMM5: 1716 if (strcmp(op_end, "")) 1717 op_end = parse_imm (op_end + 1, & exp, MIN_IMM5, MAX_IMM5); 1718 else 1719 as_fatal(_("Error in statement syntax")); 1720 if (exp.X_op != O_constant) { 1721 as_warn(_("Symbol used as immediate for mbar instruction")); 1722 } else { 1723 output = frag_more (isize); 1724 immed = exp.X_add_number; 1725 } 1726 if (immed != (immed % 32)) { 1727 as_warn(_("Immediate value for mbar > 32. using <value %% 32>")); 1728 immed = immed % 32; 1729 } 1730 inst |= (immed << IMM_MBAR); 1731 break; 1732 1733 default: 1734 as_fatal (_("unimplemented opcode \"%s\""), name); 1735 } 1736 1737 /* Drop whitespace after all the operands have been parsed. */ 1738 while (ISSPACE (* op_end)) 1739 op_end ++; 1740 1741 /* Give warning message if the insn has more operands than required. */ 1742 if (strcmp (op_end, opcode->name) && strcmp (op_end, "")) 1743 as_warn (_("ignoring operands: %s "), op_end); 1744 1745 output[0] = INST_BYTE0 (inst); 1746 output[1] = INST_BYTE1 (inst); 1747 output[2] = INST_BYTE2 (inst); 1748 output[3] = INST_BYTE3 (inst); 1749 1750 #ifdef OBJ_ELF 1751 dwarf2_emit_insn (4); 1752 #endif 1753 } 1754 1755 symbolS * 1756 md_undefined_symbol (char * name ATTRIBUTE_UNUSED) 1757 { 1758 return NULL; 1759 } 1760 1761 /* Various routines to kill one day. */ 1762 /* Equal to MAX_PRECISION in atof-ieee.c */ 1763 #define MAX_LITTLENUMS 6 1764 1765 /* Turn a string in input_line_pointer into a floating point constant of type 1766 type, and store the appropriate bytes in *litP. The number of LITTLENUMS 1767 emitted is stored in *sizeP. An error message is returned, or NULL on OK.*/ 1768 const char * 1769 md_atof (int type, char * litP, int * sizeP) 1770 { 1771 int prec; 1772 LITTLENUM_TYPE words[MAX_LITTLENUMS]; 1773 int i; 1774 char * t; 1775 1776 switch (type) 1777 { 1778 case 'f': 1779 case 'F': 1780 case 's': 1781 case 'S': 1782 prec = 2; 1783 break; 1784 1785 case 'd': 1786 case 'D': 1787 case 'r': 1788 case 'R': 1789 prec = 4; 1790 break; 1791 1792 case 'x': 1793 case 'X': 1794 prec = 6; 1795 break; 1796 1797 case 'p': 1798 case 'P': 1799 prec = 6; 1800 break; 1801 1802 default: 1803 *sizeP = 0; 1804 return _("Bad call to MD_NTOF()"); 1805 } 1806 1807 t = atof_ieee (input_line_pointer, type, words); 1808 1809 if (t) 1810 input_line_pointer = t; 1811 1812 *sizeP = prec * sizeof (LITTLENUM_TYPE); 1813 1814 if (! target_big_endian) 1815 { 1816 for (i = prec - 1; i >= 0; i--) 1817 { 1818 md_number_to_chars (litP, (valueT) words[i], 1819 sizeof (LITTLENUM_TYPE)); 1820 litP += sizeof (LITTLENUM_TYPE); 1821 } 1822 } 1823 else 1824 for (i = 0; i < prec; i++) 1825 { 1826 md_number_to_chars (litP, (valueT) words[i], 1827 sizeof (LITTLENUM_TYPE)); 1828 litP += sizeof (LITTLENUM_TYPE); 1829 } 1830 1831 return NULL; 1832 } 1833 1834 const char * md_shortopts = ""; 1835 1836 struct option md_longopts[] = 1837 { 1838 {"EB", no_argument, NULL, OPTION_EB}, 1839 {"EL", no_argument, NULL, OPTION_EL}, 1840 { NULL, no_argument, NULL, 0} 1841 }; 1842 1843 size_t md_longopts_size = sizeof (md_longopts); 1844 1845 int md_short_jump_size; 1846 1847 void 1848 md_create_short_jump (char * ptr ATTRIBUTE_UNUSED, 1849 addressT from_Nddr ATTRIBUTE_UNUSED, 1850 addressT to_Nddr ATTRIBUTE_UNUSED, 1851 fragS * frag ATTRIBUTE_UNUSED, 1852 symbolS * to_symbol ATTRIBUTE_UNUSED) 1853 { 1854 as_fatal (_("failed sanity check: short_jump")); 1855 } 1856 1857 void 1858 md_create_long_jump (char * ptr ATTRIBUTE_UNUSED, 1859 addressT from_Nddr ATTRIBUTE_UNUSED, 1860 addressT to_Nddr ATTRIBUTE_UNUSED, 1861 fragS * frag ATTRIBUTE_UNUSED, 1862 symbolS * to_symbol ATTRIBUTE_UNUSED) 1863 { 1864 as_fatal (_("failed sanity check: long_jump")); 1865 } 1866 1867 /* Called after relaxing, change the frags so they know how big they are. */ 1868 1869 void 1870 md_convert_frag (bfd * abfd ATTRIBUTE_UNUSED, 1871 segT sec ATTRIBUTE_UNUSED, 1872 fragS * fragP) 1873 { 1874 fixS *fixP; 1875 1876 switch (fragP->fr_subtype) 1877 { 1878 case UNDEFINED_PC_OFFSET: 1879 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1880 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL); 1881 fragP->fr_fix += INST_WORD_SIZE * 2; 1882 fragP->fr_var = 0; 1883 break; 1884 case DEFINED_ABS_SEGMENT: 1885 if (fragP->fr_symbol == GOT_symbol) 1886 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1887 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_GOTPC); 1888 else 1889 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1890 fragP->fr_offset, FALSE, BFD_RELOC_64); 1891 fragP->fr_fix += INST_WORD_SIZE * 2; 1892 fragP->fr_var = 0; 1893 break; 1894 case DEFINED_RO_SEGMENT: 1895 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol, 1896 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_ROSDA); 1897 fragP->fr_fix += INST_WORD_SIZE; 1898 fragP->fr_var = 0; 1899 break; 1900 case DEFINED_RW_SEGMENT: 1901 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol, 1902 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_32_RWSDA); 1903 fragP->fr_fix += INST_WORD_SIZE; 1904 fragP->fr_var = 0; 1905 break; 1906 case DEFINED_PC_OFFSET: 1907 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE, fragP->fr_symbol, 1908 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_32_LO_PCREL); 1909 fragP->fr_fix += INST_WORD_SIZE; 1910 fragP->fr_var = 0; 1911 break; 1912 case LARGE_DEFINED_PC_OFFSET: 1913 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1914 fragP->fr_offset, TRUE, BFD_RELOC_64_PCREL); 1915 fragP->fr_fix += INST_WORD_SIZE * 2; 1916 fragP->fr_var = 0; 1917 break; 1918 case GOT_OFFSET: 1919 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1920 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOT); 1921 fragP->fr_fix += INST_WORD_SIZE * 2; 1922 fragP->fr_var = 0; 1923 break; 1924 case PLT_OFFSET: 1925 fixP = fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1926 fragP->fr_offset, TRUE, BFD_RELOC_MICROBLAZE_64_PLT); 1927 /* fixP->fx_plt = 1; */ 1928 (void) fixP; 1929 fragP->fr_fix += INST_WORD_SIZE * 2; 1930 fragP->fr_var = 0; 1931 break; 1932 case GOTOFF_OFFSET: 1933 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1934 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_GOTOFF); 1935 fragP->fr_fix += INST_WORD_SIZE * 2; 1936 fragP->fr_var = 0; 1937 break; 1938 case TLSGD_OFFSET: 1939 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1940 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSGD); 1941 fragP->fr_fix += INST_WORD_SIZE * 2; 1942 fragP->fr_var = 0; 1943 break; 1944 case TLSLD_OFFSET: 1945 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1946 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSLD); 1947 fragP->fr_fix += INST_WORD_SIZE * 2; 1948 fragP->fr_var = 0; 1949 break; 1950 case TLSDTPREL_OFFSET: 1951 fix_new (fragP, fragP->fr_fix, INST_WORD_SIZE * 2, fragP->fr_symbol, 1952 fragP->fr_offset, FALSE, BFD_RELOC_MICROBLAZE_64_TLSDTPREL); 1953 fragP->fr_fix += INST_WORD_SIZE * 2; 1954 fragP->fr_var = 0; 1955 break; 1956 1957 default: 1958 abort (); 1959 } 1960 } 1961 1962 /* Applies the desired value to the specified location. 1963 Also sets up addends for 'rela' type relocations. */ 1964 void 1965 md_apply_fix (fixS * fixP, 1966 valueT * valp, 1967 segT segment) 1968 { 1969 char * buf = fixP->fx_where + fixP->fx_frag->fr_literal; 1970 const char * file = fixP->fx_file ? fixP->fx_file : _("unknown"); 1971 const char * symname; 1972 /* Note: use offsetT because it is signed, valueT is unsigned. */ 1973 offsetT val = (offsetT) * valp; 1974 int i; 1975 struct op_code_struct * opcode1; 1976 unsigned long inst1; 1977 1978 symname = fixP->fx_addsy ? S_GET_NAME (fixP->fx_addsy) : _("<unknown>"); 1979 1980 /* fixP->fx_offset is supposed to be set up correctly for all 1981 symbol relocations. */ 1982 if (fixP->fx_addsy == NULL) 1983 { 1984 if (!fixP->fx_pcrel) 1985 fixP->fx_offset = val; /* Absolute relocation. */ 1986 else 1987 fprintf (stderr, "NULL symbol PC-relative relocation? offset = %08x, val = %08x\n", 1988 (unsigned int) fixP->fx_offset, (unsigned int) val); 1989 } 1990 1991 /* If we aren't adjusting this fixup to be against the section 1992 symbol, we need to adjust the value. */ 1993 if (fixP->fx_addsy != NULL) 1994 { 1995 if (S_IS_WEAK (fixP->fx_addsy) 1996 || (symbol_used_in_reloc_p (fixP->fx_addsy) 1997 && (((bfd_get_section_flags (stdoutput, 1998 S_GET_SEGMENT (fixP->fx_addsy)) 1999 & SEC_LINK_ONCE) != 0) 2000 || !strncmp (segment_name (S_GET_SEGMENT (fixP->fx_addsy)), 2001 ".gnu.linkonce", 2002 sizeof (".gnu.linkonce") - 1)))) 2003 { 2004 val -= S_GET_VALUE (fixP->fx_addsy); 2005 if (val != 0 && ! fixP->fx_pcrel) 2006 { 2007 /* In this case, the bfd_install_relocation routine will 2008 incorrectly add the symbol value back in. We just want 2009 the addend to appear in the object file. 2010 FIXME: If this makes VALUE zero, we're toast. */ 2011 val -= S_GET_VALUE (fixP->fx_addsy); 2012 } 2013 } 2014 } 2015 2016 /* If the fix is relative to a symbol which is not defined, or not 2017 in the same segment as the fix, we cannot resolve it here. */ 2018 /* fixP->fx_addsy is NULL if valp contains the entire relocation. */ 2019 if (fixP->fx_addsy != NULL 2020 && (!S_IS_DEFINED (fixP->fx_addsy) 2021 || (S_GET_SEGMENT (fixP->fx_addsy) != segment))) 2022 { 2023 fixP->fx_done = 0; 2024 #ifdef OBJ_ELF 2025 /* For ELF we can just return and let the reloc that will be generated 2026 take care of everything. For COFF we still have to insert 'val' 2027 into the insn since the addend field will be ignored. */ 2028 /* return; */ 2029 #endif 2030 } 2031 /* All fixups in the text section must be handled in the linker. */ 2032 else if (segment->flags & SEC_CODE) 2033 fixP->fx_done = 0; 2034 else if (!fixP->fx_pcrel && fixP->fx_addsy != NULL) 2035 fixP->fx_done = 0; 2036 else 2037 fixP->fx_done = 1; 2038 2039 switch (fixP->fx_r_type) 2040 { 2041 case BFD_RELOC_MICROBLAZE_32_LO: 2042 case BFD_RELOC_MICROBLAZE_32_LO_PCREL: 2043 if (target_big_endian) 2044 { 2045 buf[2] |= ((val >> 8) & 0xff); 2046 buf[3] |= (val & 0xff); 2047 } 2048 else 2049 { 2050 buf[1] |= ((val >> 8) & 0xff); 2051 buf[0] |= (val & 0xff); 2052 } 2053 break; 2054 case BFD_RELOC_MICROBLAZE_32_ROSDA: 2055 case BFD_RELOC_MICROBLAZE_32_RWSDA: 2056 /* Don't do anything if the symbol is not defined. */ 2057 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) 2058 { 2059 if (((val & 0xFFFF8000) != 0) && ((val & 0xFFFF8000) != 0xFFFF8000)) 2060 as_bad_where (file, fixP->fx_line, 2061 _("pcrel for branch to %s too far (0x%x)"), 2062 symname, (int) val); 2063 if (target_big_endian) 2064 { 2065 buf[2] |= ((val >> 8) & 0xff); 2066 buf[3] |= (val & 0xff); 2067 } 2068 else 2069 { 2070 buf[1] |= ((val >> 8) & 0xff); 2071 buf[0] |= (val & 0xff); 2072 } 2073 } 2074 break; 2075 case BFD_RELOC_32: 2076 case BFD_RELOC_RVA: 2077 case BFD_RELOC_32_PCREL: 2078 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: 2079 /* Don't do anything if the symbol is not defined. */ 2080 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) 2081 { 2082 if (target_big_endian) 2083 { 2084 buf[0] |= ((val >> 24) & 0xff); 2085 buf[1] |= ((val >> 16) & 0xff); 2086 buf[2] |= ((val >> 8) & 0xff); 2087 buf[3] |= (val & 0xff); 2088 } 2089 else 2090 { 2091 buf[3] |= ((val >> 24) & 0xff); 2092 buf[2] |= ((val >> 16) & 0xff); 2093 buf[1] |= ((val >> 8) & 0xff); 2094 buf[0] |= (val & 0xff); 2095 } 2096 } 2097 break; 2098 case BFD_RELOC_64_PCREL: 2099 case BFD_RELOC_64: 2100 /* Add an imm instruction. First save the current instruction. */ 2101 for (i = 0; i < INST_WORD_SIZE; i++) 2102 buf[i + INST_WORD_SIZE] = buf[i]; 2103 2104 /* Generate the imm instruction. */ 2105 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); 2106 if (opcode1 == NULL) 2107 { 2108 as_bad (_("unknown opcode \"%s\""), "imm"); 2109 return; 2110 } 2111 2112 inst1 = opcode1->bit_sequence; 2113 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) 2114 inst1 |= ((val & 0xFFFF0000) >> 16) & IMM_MASK; 2115 2116 buf[0] = INST_BYTE0 (inst1); 2117 buf[1] = INST_BYTE1 (inst1); 2118 buf[2] = INST_BYTE2 (inst1); 2119 buf[3] = INST_BYTE3 (inst1); 2120 2121 /* Add the value only if the symbol is defined. */ 2122 if (fixP->fx_addsy == NULL || S_IS_DEFINED (fixP->fx_addsy)) 2123 { 2124 if (target_big_endian) 2125 { 2126 buf[6] |= ((val >> 8) & 0xff); 2127 buf[7] |= (val & 0xff); 2128 } 2129 else 2130 { 2131 buf[5] |= ((val >> 8) & 0xff); 2132 buf[4] |= (val & 0xff); 2133 } 2134 } 2135 break; 2136 2137 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: 2138 case BFD_RELOC_MICROBLAZE_64_TLSGD: 2139 case BFD_RELOC_MICROBLAZE_64_TLSLD: 2140 S_SET_THREAD_LOCAL (fixP->fx_addsy); 2141 /* Fall through. */ 2142 2143 case BFD_RELOC_MICROBLAZE_64_GOTPC: 2144 case BFD_RELOC_MICROBLAZE_64_GOT: 2145 case BFD_RELOC_MICROBLAZE_64_PLT: 2146 case BFD_RELOC_MICROBLAZE_64_GOTOFF: 2147 /* Add an imm instruction. First save the current instruction. */ 2148 for (i = 0; i < INST_WORD_SIZE; i++) 2149 buf[i + INST_WORD_SIZE] = buf[i]; 2150 2151 /* Generate the imm instruction. */ 2152 opcode1 = (struct op_code_struct *) hash_find (opcode_hash_control, "imm"); 2153 if (opcode1 == NULL) 2154 { 2155 as_bad (_("unknown opcode \"%s\""), "imm"); 2156 return; 2157 } 2158 2159 inst1 = opcode1->bit_sequence; 2160 2161 /* We can fixup call to a defined non-global address 2162 within the same section only. */ 2163 buf[0] = INST_BYTE0 (inst1); 2164 buf[1] = INST_BYTE1 (inst1); 2165 buf[2] = INST_BYTE2 (inst1); 2166 buf[3] = INST_BYTE3 (inst1); 2167 return; 2168 2169 default: 2170 break; 2171 } 2172 2173 if (fixP->fx_addsy == NULL) 2174 { 2175 /* This fixup has been resolved. Create a reloc in case the linker 2176 moves code around due to relaxing. */ 2177 if (fixP->fx_r_type == BFD_RELOC_64_PCREL) 2178 fixP->fx_r_type = BFD_RELOC_MICROBLAZE_64_NONE; 2179 else 2180 fixP->fx_r_type = BFD_RELOC_NONE; 2181 fixP->fx_addsy = section_symbol (absolute_section); 2182 } 2183 return; 2184 } 2185 2186 void 2187 md_operand (expressionS * expressionP) 2188 { 2189 /* Ignore leading hash symbol, if present. */ 2190 if (*input_line_pointer == '#') 2191 { 2192 input_line_pointer ++; 2193 expression (expressionP); 2194 } 2195 } 2196 2197 /* Called just before address relaxation, return the length 2198 by which a fragment must grow to reach it's destination. */ 2199 2200 int 2201 md_estimate_size_before_relax (fragS * fragP, 2202 segT segment_type) 2203 { 2204 sbss_segment = bfd_get_section_by_name (stdoutput, ".sbss"); 2205 sbss2_segment = bfd_get_section_by_name (stdoutput, ".sbss2"); 2206 sdata_segment = bfd_get_section_by_name (stdoutput, ".sdata"); 2207 sdata2_segment = bfd_get_section_by_name (stdoutput, ".sdata2"); 2208 2209 switch (fragP->fr_subtype) 2210 { 2211 case INST_PC_OFFSET: 2212 /* Used to be a PC-relative branch. */ 2213 if (!fragP->fr_symbol) 2214 { 2215 /* We know the abs value: Should never happen. */ 2216 as_bad (_("Absolute PC-relative value in relaxation code. Assembler error.....")); 2217 abort (); 2218 } 2219 else if (S_GET_SEGMENT (fragP->fr_symbol) == segment_type && 2220 !S_IS_WEAK (fragP->fr_symbol)) 2221 { 2222 fragP->fr_subtype = DEFINED_PC_OFFSET; 2223 /* Don't know now whether we need an imm instruction. */ 2224 fragP->fr_var = INST_WORD_SIZE; 2225 } 2226 else if (S_IS_DEFINED (fragP->fr_symbol) 2227 && (((S_GET_SEGMENT (fragP->fr_symbol))->flags & SEC_CODE) == 0)) 2228 { 2229 /* Cannot have a PC-relative branch to a diff segment. */ 2230 as_bad (_("PC relative branch to label %s which is not in the instruction space"), 2231 S_GET_NAME (fragP->fr_symbol)); 2232 fragP->fr_subtype = UNDEFINED_PC_OFFSET; 2233 fragP->fr_var = INST_WORD_SIZE*2; 2234 } 2235 else 2236 { 2237 fragP->fr_subtype = UNDEFINED_PC_OFFSET; 2238 fragP->fr_var = INST_WORD_SIZE*2; 2239 } 2240 break; 2241 2242 case INST_NO_OFFSET: 2243 /* Used to be a reference to somewhere which was unknown. */ 2244 if (fragP->fr_symbol) 2245 { 2246 if (fragP->fr_opcode == NULL) 2247 { 2248 /* Used as an absolute value. */ 2249 fragP->fr_subtype = DEFINED_ABS_SEGMENT; 2250 /* Variable part does not change. */ 2251 fragP->fr_var = INST_WORD_SIZE*2; 2252 } 2253 else if (streq (fragP->fr_opcode, str_microblaze_ro_anchor)) 2254 { 2255 /* It is accessed using the small data read only anchor. */ 2256 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr) 2257 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata2_segment) 2258 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss2_segment) 2259 || (! S_IS_DEFINED (fragP->fr_symbol))) 2260 { 2261 fragP->fr_subtype = DEFINED_RO_SEGMENT; 2262 fragP->fr_var = INST_WORD_SIZE; 2263 } 2264 else 2265 { 2266 /* Variable not in small data read only segment accessed 2267 using small data read only anchor. */ 2268 const char *file = fragP->fr_file ? fragP->fr_file : _("unknown"); 2269 2270 as_bad_where (file, fragP->fr_line, 2271 _("Variable is accessed using small data read " 2272 "only anchor, but it is not in the small data " 2273 "read only section")); 2274 fragP->fr_subtype = DEFINED_RO_SEGMENT; 2275 fragP->fr_var = INST_WORD_SIZE; 2276 } 2277 } 2278 else if (streq (fragP->fr_opcode, str_microblaze_rw_anchor)) 2279 { 2280 if ((S_GET_SEGMENT (fragP->fr_symbol) == bfd_com_section_ptr) 2281 || (S_GET_SEGMENT (fragP->fr_symbol) == sdata_segment) 2282 || (S_GET_SEGMENT (fragP->fr_symbol) == sbss_segment) 2283 || (!S_IS_DEFINED (fragP->fr_symbol))) 2284 { 2285 /* It is accessed using the small data read write anchor. */ 2286 fragP->fr_subtype = DEFINED_RW_SEGMENT; 2287 fragP->fr_var = INST_WORD_SIZE; 2288 } 2289 else 2290 { 2291 const char *file = fragP->fr_file ? fragP->fr_file : _("unknown"); 2292 2293 as_bad_where (file, fragP->fr_line, 2294 _("Variable is accessed using small data read " 2295 "write anchor, but it is not in the small data " 2296 "read write section")); 2297 fragP->fr_subtype = DEFINED_RW_SEGMENT; 2298 fragP->fr_var = INST_WORD_SIZE; 2299 } 2300 } 2301 else 2302 { 2303 as_bad (_("Incorrect fr_opcode value in frag. Internal error.....")); 2304 abort (); 2305 } 2306 } 2307 else 2308 { 2309 /* We know the abs value: Should never happen. */ 2310 as_bad (_("Absolute value in relaxation code. Assembler error.....")); 2311 abort (); 2312 } 2313 break; 2314 2315 case UNDEFINED_PC_OFFSET: 2316 case LARGE_DEFINED_PC_OFFSET: 2317 case DEFINED_ABS_SEGMENT: 2318 case GOT_OFFSET: 2319 case PLT_OFFSET: 2320 case GOTOFF_OFFSET: 2321 case TLSGD_OFFSET: 2322 case TLSLD_OFFSET: 2323 case TLSTPREL_OFFSET: 2324 case TLSDTPREL_OFFSET: 2325 fragP->fr_var = INST_WORD_SIZE*2; 2326 break; 2327 case DEFINED_RO_SEGMENT: 2328 case DEFINED_RW_SEGMENT: 2329 case DEFINED_PC_OFFSET: 2330 case TLSDTPMOD_OFFSET: 2331 fragP->fr_var = INST_WORD_SIZE; 2332 break; 2333 default: 2334 abort (); 2335 } 2336 2337 return fragP->fr_var; 2338 } 2339 2340 /* Put number into target byte order. */ 2341 2342 void 2343 md_number_to_chars (char * ptr, valueT use, int nbytes) 2344 { 2345 if (target_big_endian) 2346 number_to_chars_bigendian (ptr, use, nbytes); 2347 else 2348 number_to_chars_littleendian (ptr, use, nbytes); 2349 } 2350 2351 /* Round up a section size to the appropriate boundary. */ 2352 2353 valueT 2354 md_section_align (segT segment ATTRIBUTE_UNUSED, valueT size) 2355 { 2356 return size; /* Byte alignment is fine. */ 2357 } 2358 2359 2360 /* The location from which a PC relative jump should be calculated, 2361 given a PC relative reloc. */ 2362 2363 long 2364 md_pcrel_from_section (fixS * fixp, segT sec ATTRIBUTE_UNUSED) 2365 { 2366 #ifdef OBJ_ELF 2367 /* If the symbol is undefined or defined in another section 2368 we leave the add number alone for the linker to fix it later. 2369 Only account for the PC pre-bump (No PC-pre-bump on the Microblaze). */ 2370 2371 if (fixp->fx_addsy != (symbolS *) NULL 2372 && (!S_IS_DEFINED (fixp->fx_addsy) 2373 || (S_GET_SEGMENT (fixp->fx_addsy) != sec))) 2374 return 0; 2375 else 2376 { 2377 /* The case where we are going to resolve things... */ 2378 if (fixp->fx_r_type == BFD_RELOC_64_PCREL) 2379 return fixp->fx_where + fixp->fx_frag->fr_address + INST_WORD_SIZE; 2380 else 2381 return fixp->fx_where + fixp->fx_frag->fr_address; 2382 } 2383 #endif 2384 } 2385 2386 2387 #define F(SZ,PCREL) (((SZ) << 1) + (PCREL)) 2388 #define MAP(SZ,PCREL,TYPE) case F (SZ, PCREL): code = (TYPE); break 2389 2390 arelent * 2391 tc_gen_reloc (asection * section ATTRIBUTE_UNUSED, fixS * fixp) 2392 { 2393 arelent * rel; 2394 bfd_reloc_code_real_type code; 2395 2396 switch (fixp->fx_r_type) 2397 { 2398 case BFD_RELOC_NONE: 2399 case BFD_RELOC_MICROBLAZE_64_NONE: 2400 case BFD_RELOC_32: 2401 case BFD_RELOC_MICROBLAZE_32_LO: 2402 case BFD_RELOC_MICROBLAZE_32_LO_PCREL: 2403 case BFD_RELOC_RVA: 2404 case BFD_RELOC_64: 2405 case BFD_RELOC_64_PCREL: 2406 case BFD_RELOC_MICROBLAZE_32_ROSDA: 2407 case BFD_RELOC_MICROBLAZE_32_RWSDA: 2408 case BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM: 2409 case BFD_RELOC_MICROBLAZE_64_GOTPC: 2410 case BFD_RELOC_MICROBLAZE_64_GOT: 2411 case BFD_RELOC_MICROBLAZE_64_PLT: 2412 case BFD_RELOC_MICROBLAZE_64_GOTOFF: 2413 case BFD_RELOC_MICROBLAZE_32_GOTOFF: 2414 case BFD_RELOC_MICROBLAZE_64_TLSGD: 2415 case BFD_RELOC_MICROBLAZE_64_TLSLD: 2416 case BFD_RELOC_MICROBLAZE_32_TLSDTPMOD: 2417 case BFD_RELOC_MICROBLAZE_32_TLSDTPREL: 2418 case BFD_RELOC_MICROBLAZE_64_TLSDTPREL: 2419 case BFD_RELOC_MICROBLAZE_64_TLSGOTTPREL: 2420 case BFD_RELOC_MICROBLAZE_64_TLSTPREL: 2421 code = fixp->fx_r_type; 2422 break; 2423 2424 default: 2425 switch (F (fixp->fx_size, fixp->fx_pcrel)) 2426 { 2427 MAP (1, 0, BFD_RELOC_8); 2428 MAP (2, 0, BFD_RELOC_16); 2429 MAP (4, 0, BFD_RELOC_32); 2430 MAP (1, 1, BFD_RELOC_8_PCREL); 2431 MAP (2, 1, BFD_RELOC_16_PCREL); 2432 MAP (4, 1, BFD_RELOC_32_PCREL); 2433 default: 2434 code = fixp->fx_r_type; 2435 as_bad (_("Can not do %d byte %srelocation"), 2436 fixp->fx_size, 2437 fixp->fx_pcrel ? _("pc-relative ") : ""); 2438 } 2439 break; 2440 } 2441 2442 rel = XNEW (arelent); 2443 rel->sym_ptr_ptr = XNEW (asymbol *); 2444 2445 if (code == BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM) 2446 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_subsy); 2447 else 2448 *rel->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 2449 2450 rel->address = fixp->fx_frag->fr_address + fixp->fx_where; 2451 /* Always pass the addend along! */ 2452 rel->addend = fixp->fx_offset; 2453 rel->howto = bfd_reloc_type_lookup (stdoutput, code); 2454 2455 if (rel->howto == NULL) 2456 { 2457 as_bad_where (fixp->fx_file, fixp->fx_line, 2458 _("Cannot represent relocation type %s"), 2459 bfd_get_reloc_code_name (code)); 2460 2461 /* Set howto to a garbage value so that we can keep going. */ 2462 rel->howto = bfd_reloc_type_lookup (stdoutput, BFD_RELOC_32); 2463 gas_assert (rel->howto != NULL); 2464 } 2465 return rel; 2466 } 2467 2468 int 2469 md_parse_option (int c, const char * arg ATTRIBUTE_UNUSED) 2470 { 2471 switch (c) 2472 { 2473 case OPTION_EB: 2474 target_big_endian = 1; 2475 break; 2476 case OPTION_EL: 2477 target_big_endian = 0; 2478 break; 2479 default: 2480 return 0; 2481 } 2482 return 1; 2483 } 2484 2485 void 2486 md_show_usage (FILE * stream ATTRIBUTE_UNUSED) 2487 { 2488 /* fprintf(stream, _("\ 2489 MicroBlaze options:\n\ 2490 -noSmall Data in the comm and data sections do not go into the small data section\n")); */ 2491 } 2492 2493 2494 /* Create a fixup for a cons expression. If parse_cons_expression_microblaze 2495 found a machine specific op in an expression, 2496 then we create relocs accordingly. */ 2497 2498 void 2499 cons_fix_new_microblaze (fragS * frag, 2500 int where, 2501 int size, 2502 expressionS *exp, 2503 bfd_reloc_code_real_type r) 2504 { 2505 if ((exp->X_op == O_subtract) && (exp->X_add_symbol) && 2506 (exp->X_op_symbol) && (now_seg != absolute_section) && (size == 4) 2507 && (!S_IS_LOCAL (exp->X_op_symbol))) 2508 r = BFD_RELOC_MICROBLAZE_32_SYM_OP_SYM; 2509 else if (exp->X_md == IMM_GOTOFF && exp->X_op == O_symbol_rva) 2510 { 2511 exp->X_op = O_symbol; 2512 r = BFD_RELOC_MICROBLAZE_32_GOTOFF; 2513 } 2514 else 2515 { 2516 switch (size) 2517 { 2518 case 1: 2519 r = BFD_RELOC_8; 2520 break; 2521 case 2: 2522 r = BFD_RELOC_16; 2523 break; 2524 case 4: 2525 r = BFD_RELOC_32; 2526 break; 2527 case 8: 2528 r = BFD_RELOC_64; 2529 break; 2530 default: 2531 as_bad (_("unsupported BFD relocation size %u"), size); 2532 r = BFD_RELOC_32; 2533 break; 2534 } 2535 } 2536 fix_new_exp (frag, where, size, exp, 0, r); 2537 } 2538