1 /* tc-loongarch.c -- Assemble for the LoongArch ISA 2 3 Copyright (C) 2021-2024 Free Software Foundation, Inc. 4 Contributed by Loongson Ltd. 5 6 This file is part of GAS. 7 8 GAS is free software; you can redistribute it and/or modify 9 it under the terms of the GNU General Public License as published by 10 the Free Software Foundation; either version 3 of the license, or 11 (at your option) any later version. 12 13 GAS is distributed in the hope that it will be useful, 14 but WITHOUT ANY WARRANTY; without even the implied warranty of 15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 GNU General Public License for more details. 17 18 You should have received a copy of the GNU General Public License 19 along with this program; see the file COPYING3. If not, 20 see <http://www.gnu.org/licenses/>. */ 21 22 #include "as.h" 23 #include "subsegs.h" 24 #include "dw2gencfi.h" 25 #include "loongarch-lex.h" 26 #include "elf/loongarch.h" 27 #include "opcode/loongarch.h" 28 #include "obj-elf.h" 29 #include "bfd/elfxx-loongarch.h" 30 #include <stdlib.h> 31 #include <string.h> 32 #include <stdio.h> 33 #include <assert.h> 34 35 /* All information about an instruction during assemble. */ 36 struct loongarch_cl_insn 37 { 38 /* First split string. */ 39 const char *name; 40 const char *arg_strs[MAX_ARG_NUM_PLUS_2]; 41 size_t arg_num; 42 43 /* Second analyze name_str and each actual args string to match the insn 44 in 'loongarch-opc.c'. And actual args may need be relocated. 45 We get length of insn. If 'insn_length == 0 && insn_mo->macro != NULL', 46 it's a macro insntruction and we call 'md_assemble' recursively 47 after expanding it. */ 48 int match_now; 49 int all_match; 50 51 const struct loongarch_opcode *insn; 52 size_t insn_length; 53 54 offsetT args[MAX_ARG_NUM_PLUS_2]; 55 struct reloc_info reloc_info[MAX_RELOC_NUMBER_A_INSN]; 56 size_t reloc_num; 57 58 /* For relax reserved. We not support relax now. 59 'insn_length < relax_max_length' means need to relax. 60 And 'insn_length == relax_max_length' means no need to relax. */ 61 size_t relax_max_length; 62 relax_substateT subtype; 63 64 /* Then we get the binary representation of insn 65 and write it in to section. */ 66 insn_t insn_bin; 67 68 /* The frag that contains the instruction. */ 69 struct frag *frag; 70 /* The offset into FRAG of the first instruction byte. */ 71 long where; 72 /* The relocs associated with the instruction, if any. */ 73 fixS *fixp[MAX_RELOC_NUMBER_A_INSN]; 74 /* Represents macros or instructions expanded from macro. 75 For la.local -> la.pcrel or la.pcrel -> pcalau12i + addi.d, la.pcrel, 76 pcalau12i and addi.d are expanded from macro. 77 The first bit represents expanded from one register macro (e.g. 78 la.local $t0, symbol) and emit R_LARCH_RELAX relocations. 79 The second bit represents expanded from two registers macro (e.g. 80 la.local $t0, $t1, symbol) and not emit R_LARCH_RELAX relocations. 81 82 The macros or instructions expanded from macros do not output register 83 deprecated warning. */ 84 unsigned int expand_from_macro; 85 }; 86 87 #ifndef DEFAULT_ARCH 88 #define DEFAULT_ARCH "loongarch64" 89 #endif 90 91 /* This array holds the chars that always start a comment. If the 92 pre-processor is disabled, these aren't very useful. */ 93 const char comment_chars[] = "#"; 94 95 /* This array holds the chars that only start a comment at the beginning of 96 a line. If the line seems to have the form '# 123 filename' 97 .line and .file directives will appear in the pre-processed output. */ 98 /* Note that input_file.c hand checks for '#' at the beginning of the 99 first line of the input file. This is because the compiler outputs 100 #NO_APP at the beginning of its output. */ 101 /* Also note that C style comments are always supported. */ 102 const char line_comment_chars[] = "#"; 103 104 /* This array holds machine specific line separator characters. */ 105 const char line_separator_chars[] = ";"; 106 107 /* Chars that can be used to separate mant from exp in floating point nums. */ 108 const char EXP_CHARS[] = "eE"; 109 110 /* Chars that mean this number is a floating point constant. */ 111 /* As in 0f12.456. */ 112 /* or 0d1.2345e12. */ 113 const char FLT_CHARS[] = "rRsSfFdDxXpP"; 114 115 const char *md_shortopts = "O::g::G:"; 116 117 static const char default_arch[] = DEFAULT_ARCH; 118 119 /* The lowest 4-bit is the bytes of instructions. */ 120 #define RELAX_BRANCH_16 0xc0000014 121 #define RELAX_BRANCH_21 0xc0000024 122 #define RELAX_BRANCH_26 0xc0000048 123 124 #define RELAX_BRANCH(x) \ 125 (((x) & 0xf0000000) == 0xc0000000) 126 #define RELAX_BRANCH_ENCODE(x) \ 127 (BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21) 128 129 enum options 130 { 131 OPTION_IGNORE = OPTION_MD_BASE, 132 133 OPTION_ABI, 134 OPTION_FLOAT_ABI, 135 136 OPTION_FLOAT_ISA, 137 138 OPTION_LA_LOCAL_WITH_ABS, 139 OPTION_LA_GLOBAL_WITH_PCREL, 140 OPTION_LA_GLOBAL_WITH_ABS, 141 OPTION_RELAX, 142 OPTION_NO_RELAX, 143 OPTION_THIN_ADD_SUB, 144 145 OPTION_END_OF_ENUM, 146 }; 147 148 struct option md_longopts[] = 149 { 150 { "mabi", required_argument, NULL, OPTION_ABI }, 151 152 { "mfpu", required_argument, NULL, OPTION_FLOAT_ISA }, 153 154 { "mla-local-with-abs", no_argument, NULL, OPTION_LA_LOCAL_WITH_ABS }, 155 { "mla-global-with-pcrel", no_argument, NULL, OPTION_LA_GLOBAL_WITH_PCREL }, 156 { "mla-global-with-abs", no_argument, NULL, OPTION_LA_GLOBAL_WITH_ABS }, 157 158 { "mrelax", no_argument, NULL, OPTION_RELAX }, 159 { "mno-relax", no_argument, NULL, OPTION_NO_RELAX }, 160 { "mthin-add-sub", no_argument, NULL, OPTION_THIN_ADD_SUB}, 161 162 { NULL, no_argument, NULL, 0 } 163 }; 164 165 size_t md_longopts_size = sizeof (md_longopts); 166 167 int 168 md_parse_option (int c, const char *arg) 169 { 170 int ret = 1; 171 char lp64[256] = ""; 172 char ilp32[256] = ""; 173 unsigned char *suf = (unsigned char *)arg; 174 175 lp64['s'] = lp64['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT; 176 lp64['f'] = lp64['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT; 177 lp64['d'] = lp64['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT; 178 179 ilp32['s'] = ilp32['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT; 180 ilp32['f'] = ilp32['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT; 181 ilp32['d'] = ilp32['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT; 182 183 switch (c) 184 { 185 case OPTION_ABI: 186 if (strncasecmp (arg, "lp64", 4) == 0 && lp64[suf[4]] != 0) 187 { 188 LARCH_opts.ase_ilp32 = 1; 189 LARCH_opts.ase_lp64 = 1; 190 LARCH_opts.ase_lsx = 1; 191 LARCH_opts.ase_lasx = 1; 192 LARCH_opts.ase_lvz = 1; 193 LARCH_opts.ase_lbt = 1; 194 LARCH_opts.ase_abi = lp64[suf[4]]; 195 } 196 else if (strncasecmp (arg, "ilp32", 5) == 0 && ilp32[suf[5]] != 0) 197 { 198 LARCH_opts.ase_abi = ilp32[suf[5]]; 199 LARCH_opts.ase_ilp32 = 1; 200 } 201 else 202 ret = 0; 203 break; 204 205 case OPTION_FLOAT_ISA: 206 if (strcasecmp (arg, "soft") == 0) 207 LARCH_opts.ase_nf = 1; 208 else if (strcasecmp (arg, "single") == 0) 209 LARCH_opts.ase_sf = 1; 210 else if (strcasecmp (arg, "double") == 0) 211 { 212 LARCH_opts.ase_sf = 1; 213 LARCH_opts.ase_df = 1; 214 } 215 else 216 ret = 0; 217 break; 218 219 case OPTION_LA_LOCAL_WITH_ABS: 220 LARCH_opts.ase_labs = 1; 221 break; 222 223 case OPTION_LA_GLOBAL_WITH_PCREL: 224 LARCH_opts.ase_gpcr = 1; 225 break; 226 227 case OPTION_LA_GLOBAL_WITH_ABS: 228 LARCH_opts.ase_gabs = 1; 229 break; 230 231 case OPTION_RELAX: 232 LARCH_opts.relax = 1; 233 break; 234 235 case OPTION_NO_RELAX: 236 LARCH_opts.relax = 0; 237 break; 238 239 case OPTION_THIN_ADD_SUB: 240 LARCH_opts.thin_add_sub = 1; 241 break; 242 243 case OPTION_IGNORE: 244 break; 245 246 default: 247 ret = 0; 248 break; 249 } 250 return ret; 251 } 252 253 static const char *const *r_abi_names = NULL; 254 static const char *const *f_abi_names = NULL; 255 static struct htab *r_htab = NULL; 256 static struct htab *r_deprecated_htab = NULL; 257 static struct htab *f_htab = NULL; 258 static struct htab *f_deprecated_htab = NULL; 259 static struct htab *fc_htab = NULL; 260 static struct htab *fcn_htab = NULL; 261 static struct htab *c_htab = NULL; 262 static struct htab *cr_htab = NULL; 263 static struct htab *v_htab = NULL; 264 static struct htab *x_htab = NULL; 265 266 void 267 loongarch_after_parse_args () 268 { 269 /* Set default ABI/ISA LP64D. */ 270 if (!LARCH_opts.ase_ilp32) 271 { 272 if (strcmp (default_arch, "loongarch64") == 0) 273 { 274 LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT; 275 LARCH_opts.ase_ilp32 = 1; 276 LARCH_opts.ase_lp64 = 1; 277 LARCH_opts.ase_lsx = 1; 278 LARCH_opts.ase_lasx = 1; 279 LARCH_opts.ase_lvz = 1; 280 LARCH_opts.ase_lbt = 1; 281 } 282 else if (strcmp (default_arch, "loongarch32") == 0) 283 { 284 LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT; 285 LARCH_opts.ase_ilp32 = 1; 286 } 287 else 288 as_bad ("unknown default architecture `%s'", default_arch); 289 } 290 291 LARCH_opts.ase_abi |= EF_LOONGARCH_OBJABI_V1; 292 /* Set default ISA double-float. */ 293 if (!LARCH_opts.ase_nf 294 && !LARCH_opts.ase_sf 295 && !LARCH_opts.ase_df) 296 { 297 LARCH_opts.ase_sf = 1; 298 LARCH_opts.ase_df = 1; 299 } 300 301 size_t i; 302 303 assert(LARCH_opts.ase_ilp32); 304 305 /* Init ilp32/lp64 registers names. */ 306 if (!r_htab) 307 r_htab = str_htab_create (), str_hash_insert (r_htab, "", 0, 0); 308 if (!r_deprecated_htab) 309 r_deprecated_htab = str_htab_create (), 310 str_hash_insert (r_deprecated_htab, "", 0, 0); 311 312 r_abi_names = loongarch_r_normal_name; 313 for (i = 0; i < ARRAY_SIZE (loongarch_r_normal_name); i++) 314 str_hash_insert (r_htab, loongarch_r_normal_name[i], (void *) (i + 1), 0); 315 316 /* Init ilp32/lp64 registers alias. */ 317 r_abi_names = loongarch_r_alias; 318 for (i = 0; i < ARRAY_SIZE (loongarch_r_alias); i++) 319 str_hash_insert (r_htab, loongarch_r_alias[i], (void *) (i + 1), 0); 320 321 for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_1); i++) 322 str_hash_insert (r_htab, loongarch_r_alias_1[i], (void *) (i + 1), 0); 323 324 for (i = 0; i < ARRAY_SIZE (loongarch_r_alias_deprecated); i++) 325 str_hash_insert (r_deprecated_htab, loongarch_r_alias_deprecated[i], 326 (void *) (i + 1), 0); 327 328 if (!cr_htab) 329 cr_htab = str_htab_create (), str_hash_insert (cr_htab, "", 0, 0); 330 331 for (i = 0; i < ARRAY_SIZE (loongarch_cr_normal_name); i++) 332 str_hash_insert (cr_htab, loongarch_cr_normal_name[i], (void *) (i + 1), 0); 333 334 /* Init single/double float registers names. */ 335 if (LARCH_opts.ase_sf || LARCH_opts.ase_df) 336 { 337 if (!f_htab) 338 f_htab = str_htab_create (), str_hash_insert (f_htab, "", 0, 0); 339 if (!f_deprecated_htab) 340 f_deprecated_htab = str_htab_create (), 341 str_hash_insert (f_deprecated_htab, "", 0, 0); 342 343 f_abi_names = loongarch_f_normal_name; 344 for (i = 0; i < ARRAY_SIZE (loongarch_f_normal_name); i++) 345 str_hash_insert (f_htab, loongarch_f_normal_name[i], (void *) (i + 1), 346 0); 347 348 /* Init float-ilp32/lp64 registers alias. */ 349 f_abi_names = loongarch_f_alias; 350 for (i = 0; i < ARRAY_SIZE (loongarch_f_alias); i++) 351 str_hash_insert (f_htab, loongarch_f_alias[i], 352 (void *) (i + 1), 0); 353 for (i = 0; i < ARRAY_SIZE (loongarch_f_alias_deprecated); i++) 354 str_hash_insert (f_deprecated_htab, loongarch_f_alias_deprecated[i], 355 (void *) (i + 1), 0); 356 357 if (!fc_htab) 358 fc_htab = str_htab_create (), str_hash_insert (fc_htab, "", 0, 0); 359 360 for (i = 0; i < ARRAY_SIZE (loongarch_fc_normal_name); i++) 361 str_hash_insert (fc_htab, loongarch_fc_normal_name[i], (void *) (i + 1), 362 0); 363 364 if (!fcn_htab) 365 fcn_htab = str_htab_create (), str_hash_insert (fcn_htab, "", 0, 0); 366 367 for (i = 0; i < ARRAY_SIZE (loongarch_fc_numeric_name); i++) 368 str_hash_insert (fcn_htab, loongarch_fc_numeric_name[i], (void *) (i + 1), 369 0); 370 371 if (!c_htab) 372 c_htab = str_htab_create (), str_hash_insert (c_htab, "", 0, 0); 373 374 for (i = 0; i < ARRAY_SIZE (loongarch_c_normal_name); i++) 375 str_hash_insert (c_htab, loongarch_c_normal_name[i], (void *) (i + 1), 376 0); 377 378 } 379 380 /* Init lsx registers names. */ 381 if (LARCH_opts.ase_lsx) 382 { 383 if (!v_htab) 384 v_htab = str_htab_create (), str_hash_insert (v_htab, "", 0, 0); 385 for (i = 0; i < ARRAY_SIZE (loongarch_v_normal_name); i++) 386 str_hash_insert (v_htab, loongarch_v_normal_name[i], (void *) (i + 1), 387 0); 388 } 389 390 /* Init lasx registers names. */ 391 if (LARCH_opts.ase_lasx) 392 { 393 if (!x_htab) 394 x_htab = str_htab_create (), str_hash_insert (x_htab, "", 0, 0); 395 for (i = 0; i < ARRAY_SIZE (loongarch_x_normal_name); i++) 396 str_hash_insert (x_htab, loongarch_x_normal_name[i], (void *) (i + 1), 397 0); 398 } 399 400 } 401 402 const char * 403 loongarch_target_format () 404 { 405 return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch"; 406 } 407 408 void 409 md_begin () 410 { 411 const struct loongarch_opcode *it; 412 struct loongarch_ase *ase; 413 for (ase = loongarch_ASEs; ase->enabled; ase++) 414 for (it = ase->opcodes; it->name; it++) 415 { 416 if (loongarch_check_format (it->format) != 0) 417 as_fatal (_("insn name: %s\tformat: %s\tsyntax error"), 418 it->name, it->format); 419 if (it->mask == 0 && it->macro == 0) 420 as_fatal (_("insn name: %s\nformat: %s\nwe want macro but " 421 "macro is NULL"), 422 it->name, it->format); 423 if (it->macro 424 && loongarch_check_macro (it->format, it->macro) != 0) 425 as_fatal (_("insn name: %s\nformat: %s\nmacro: %s\tsyntax error"), 426 it->name, it->format, it->macro); 427 } 428 429 /* FIXME: expressionS use 'offsetT' as constant, 430 * we want this is 64-bit type. */ 431 assert (8 <= sizeof (offsetT)); 432 } 433 434 unsigned long 435 loongarch_mach (void) 436 { 437 return LARCH_opts.ase_lp64 ? bfd_mach_loongarch64 : bfd_mach_loongarch32; 438 } 439 440 static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 }; 441 442 /* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate 443 a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for 444 use in DWARF debug information. */ 445 446 static void 447 s_dtprel (int bytes) 448 { 449 expressionS ex; 450 char *p; 451 452 expression (&ex); 453 454 if (ex.X_op != O_symbol) 455 { 456 as_bad (_("Unsupported use of %s"), 457 (bytes == 8 ? ".dtpreldword" : ".dtprelword")); 458 ignore_rest_of_line (); 459 } 460 461 p = frag_more (bytes); 462 md_number_to_chars (p, 0, bytes); 463 fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE, 464 (bytes == 8 465 ? BFD_RELOC_LARCH_TLS_DTPREL64 466 : BFD_RELOC_LARCH_TLS_DTPREL32)); 467 468 demand_empty_rest_of_line (); 469 } 470 471 static const pseudo_typeS loongarch_pseudo_table[] = 472 { 473 { "dword", cons, 8 }, 474 { "word", cons, 4 }, 475 { "half", cons, 2 }, 476 { "dtprelword", s_dtprel, 4 }, 477 { "dtpreldword", s_dtprel, 8 }, 478 { NULL, NULL, 0 }, 479 }; 480 481 void 482 loongarch_pop_insert (void) 483 { 484 pop_insert (loongarch_pseudo_table); 485 } 486 487 #define INTERNAL_LABEL_SPECIAL 10 488 static unsigned long internal_label_count[INTERNAL_LABEL_SPECIAL] = { 0 }; 489 490 static const char * 491 loongarch_internal_label_name (unsigned long label, int augend) 492 { 493 static char symbol_name_build[24]; 494 unsigned long want_label; 495 char *p; 496 497 want_label = internal_label_count[label] + augend; 498 499 p = symbol_name_build; 500 #ifdef LOCAL_LABEL_PREFIX 501 *p++ = LOCAL_LABEL_PREFIX; 502 #endif 503 *p++ = 'L'; 504 for (; label; label /= 10) 505 *p++ = label % 10 + '0'; 506 /* Make sure internal label never belong to normal label namespace. */ 507 *p++ = ':'; 508 for (; want_label; want_label /= 10) 509 *p++ = want_label % 10 + '0'; 510 *p++ = '\0'; 511 return symbol_name_build; 512 } 513 514 static void 515 setup_internal_label_here (unsigned long label) 516 { 517 assert (label < INTERNAL_LABEL_SPECIAL); 518 internal_label_count[label]++; 519 colon (loongarch_internal_label_name (label, 0)); 520 } 521 522 void 523 get_internal_label (expressionS *label_expr, unsigned long label, 524 int augend /* 0 for previous, 1 for next. */) 525 { 526 assert (label < INTERNAL_LABEL_SPECIAL); 527 as_fatal (_("internal error: we have no internal label yet")); 528 label_expr->X_op = O_symbol; 529 label_expr->X_add_symbol = 530 symbol_find_or_make (loongarch_internal_label_name (label, augend)); 531 label_expr->X_add_number = 0; 532 } 533 534 static int 535 is_internal_label (const char *c_str) 536 { 537 do 538 { 539 if (*c_str != ':') 540 break; 541 c_str++; 542 if (!('0' <= *c_str && *c_str <= '9')) 543 break; 544 while ('0' <= *c_str && *c_str <= '9') 545 c_str++; 546 if (*c_str != 'b' && *c_str != 'f') 547 break; 548 c_str++; 549 return *c_str == '\0'; 550 } 551 while (0); 552 return 0; 553 } 554 555 static int 556 is_label (const char *c_str) 557 { 558 if (is_internal_label (c_str)) 559 return 1; 560 else if ('0' <= *c_str && *c_str <= '9') 561 { 562 /* [0-9]+[bf] */ 563 while ('0' <= *c_str && *c_str <= '9') 564 c_str++; 565 return *c_str == 'b' || *c_str == 'f'; 566 } 567 else if (is_name_beginner (*c_str)) 568 { 569 /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */ 570 c_str++; 571 while (is_part_of_name (*c_str)) 572 c_str++; 573 return *c_str == '\0'; 574 } 575 else 576 return 0; 577 } 578 579 static int 580 is_label_with_addend (const char *c_str) 581 { 582 if (is_internal_label (c_str)) 583 return 1; 584 else if ('0' <= *c_str && *c_str <= '9') 585 { 586 /* [0-9]+[bf] */ 587 while ('0' <= *c_str && *c_str <= '9') 588 c_str++; 589 if (*c_str == 'b' || *c_str == 'f') 590 c_str++; 591 else 592 return 0; 593 return *c_str == '\0' 594 || ((*c_str == '-' || *c_str == '+') 595 && is_unsigned (c_str + 1)); 596 } 597 else if (is_name_beginner (*c_str)) 598 { 599 /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */ 600 c_str++; 601 while (is_part_of_name (*c_str)) 602 c_str++; 603 return *c_str == '\0' 604 || ((*c_str == '-' || *c_str == '+') 605 && is_unsigned (c_str + 1)); 606 } 607 else 608 return 0; 609 } 610 611 static int32_t 612 loongarch_args_parser_can_match_arg_helper (char esc_ch1, char esc_ch2, 613 const char *bit_field, 614 const char *arg, void *context) 615 { 616 struct loongarch_cl_insn *ip = context; 617 offsetT imm, ret = 0; 618 size_t reloc_num_we_have = MAX_RELOC_NUMBER_A_INSN - ip->reloc_num; 619 size_t reloc_num = 0; 620 621 if (!ip->match_now) 622 return 0; 623 624 switch (esc_ch1) 625 { 626 case 'l': 627 switch (esc_ch2) 628 { 629 default: 630 ip->match_now = is_label (arg); 631 if (!ip->match_now && is_label_with_addend (arg)) 632 as_fatal (_("This label shouldn't be with addend.")); 633 break; 634 case 'a': 635 ip->match_now = is_label_with_addend (arg); 636 break; 637 } 638 break; 639 /* This is used for TLS, where the fourth operand is %le_add_r, 640 to get a relocation applied to an add instruction, for relaxation to use. 641 Two conditions, ip->match_now and reloc_num, are used to check tls insn 642 to prevent cases like add.d $a0,$a0,$a0,8. */ 643 case 't': 644 ip->match_now = loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num, 645 reloc_num_we_have, &reloc_num, &imm) == 0; 646 647 if (!ip->match_now) 648 break; 649 650 bfd_reloc_code_real_type tls_reloc_type = BFD_RELOC_LARCH_TLS_LE_ADD_R; 651 652 if (reloc_num 653 && (ip->reloc_info[ip->reloc_num].type == tls_reloc_type)) 654 { 655 ip->reloc_num += reloc_num; 656 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; 657 ip->reloc_info[ip->reloc_num].value = const_0; 658 ip->reloc_num++; 659 } 660 else 661 ip->match_now = 0; 662 break; 663 case 's': 664 case 'u': 665 ip->match_now = 666 loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num, 667 reloc_num_we_have, &reloc_num, &imm) == 0; 668 669 if (!ip->match_now) 670 break; 671 672 ret = imm; 673 if (reloc_num) 674 { 675 bfd_reloc_code_real_type reloc_type = BFD_RELOC_NONE; 676 reloc_num_we_have -= reloc_num; 677 if (reloc_num_we_have == 0) 678 as_fatal (_("expr too huge") /* Want one more reloc. */); 679 if (esc_ch1 == 'u') 680 { 681 if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0) 682 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_U_10_12; 683 } 684 else if (esc_ch1 == 's') 685 { 686 if (strncmp (bit_field, "10:16<<2", strlen ("10:16<<2")) == 0) 687 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2; 688 else if (strncmp (bit_field, "0:5|10:16<<2", 689 strlen ("0:5|10:16<<2")) == 0) 690 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2; 691 else if (strncmp (bit_field, "0:10|10:16<<2", 692 strlen ("0:10|10:16<<2")) == 0) 693 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2; 694 else if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0) 695 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_12; 696 else if (strncmp (bit_field, "5:20", strlen ("5:20")) == 0) 697 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_5_20; 698 else if (strncmp (bit_field, "10:16", strlen ("10:16")) == 0) 699 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_16; 700 else if (strncmp (bit_field, "10:5", strlen ("10:5")) == 0) 701 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_S_10_5; 702 } 703 if (reloc_type == BFD_RELOC_NONE) 704 as_fatal ( 705 _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"), 706 esc_ch1, esc_ch2, bit_field, arg); 707 708 if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16 709 && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2) 710 { 711 /* As we compact stack-relocs, it is no need for pop operation. 712 But break out until here in order to check the imm field. 713 May be reloc_num > 1 if implement relax? */ 714 ip->reloc_num += reloc_num; 715 reloc_type = ip->reloc_info[0].type; 716 717 if (LARCH_opts.relax 718 && (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type 719 || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type)) 720 { 721 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; 722 ip->reloc_info[ip->reloc_num].value = const_0; 723 ip->reloc_num++; 724 } 725 726 /* Only one register macros (used in normal code model) 727 emit R_LARCH_RELAX. 728 LARCH_opts.ase_labs and LARCH_opts.ase_gabs are used 729 to generate the code model of absolute addresses, and 730 we do not relax this code model. */ 731 if (LARCH_opts.relax && (ip->expand_from_macro & 1) 732 && ! (LARCH_opts.ase_labs | LARCH_opts.ase_gabs) 733 && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_type 734 || BFD_RELOC_LARCH_PCALA_LO12 == reloc_type 735 || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_type 736 || BFD_RELOC_LARCH_GOT_PC_LO12 == reloc_type 737 || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_type 738 || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_type 739 || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_type 740 || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_type 741 || BFD_RELOC_LARCH_TLS_DESC_LD == reloc_type 742 || BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_type 743 || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_type 744 || BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_type)) 745 { 746 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX; 747 ip->reloc_info[ip->reloc_num].value = const_0; 748 ip->reloc_num++; 749 } 750 break; 751 } 752 reloc_num++; 753 ip->reloc_num += reloc_num; 754 ip->reloc_info[ip->reloc_num - 1].type = reloc_type; 755 ip->reloc_info[ip->reloc_num - 1].value = const_0; 756 } 757 break; 758 case 'r': 759 imm = (intptr_t) str_hash_find (r_htab, arg); 760 ip->match_now = 0 < imm; 761 ret = imm - 1; 762 if (ip->match_now) 763 break; 764 /* Handle potential usage of deprecated register aliases. */ 765 imm = (intptr_t) str_hash_find (r_deprecated_htab, arg); 766 ip->match_now = 0 < imm; 767 ret = imm - 1; 768 /* !ip->expand_from_macro: avoiding duplicate output warnings, 769 only the first macro output warning. */ 770 if (ip->match_now && !ip->expand_from_macro) 771 as_warn (_("register alias %s is deprecated, use %s instead"), 772 arg, r_abi_names[ret]); 773 break; 774 case 'f': 775 switch (esc_ch2) 776 { 777 case 'c': 778 imm = (intptr_t) str_hash_find (fc_htab, arg); 779 if (0 >= imm) 780 { 781 imm = (intptr_t) str_hash_find (fcn_htab, arg); 782 } 783 break; 784 default: 785 imm = (intptr_t) str_hash_find (f_htab, arg); 786 } 787 ip->match_now = 0 < imm; 788 ret = imm - 1; 789 if (ip->match_now && !ip->expand_from_macro) 790 break; 791 /* Handle potential usage of deprecated register aliases. */ 792 imm = (intptr_t) str_hash_find (f_deprecated_htab, arg); 793 ip->match_now = 0 < imm; 794 ret = imm - 1; 795 if (ip->match_now) 796 as_warn (_("register alias %s is deprecated, use %s instead"), 797 arg, f_abi_names[ret]); 798 break; 799 case 'c': 800 switch (esc_ch2) 801 { 802 case 'r': 803 imm = (intptr_t) str_hash_find (cr_htab, arg); 804 break; 805 default: 806 imm = (intptr_t) str_hash_find (c_htab, arg); 807 } 808 ip->match_now = 0 < imm; 809 ret = imm - 1; 810 break; 811 case 'v': 812 imm = (intptr_t) str_hash_find (v_htab, arg); 813 ip->match_now = 0 < imm; 814 ret = imm - 1; 815 break; 816 case 'x': 817 imm = (intptr_t) str_hash_find (x_htab, arg); 818 ip->match_now = 0 < imm; 819 ret = imm - 1; 820 break; 821 case '\0': 822 ip->all_match = ip->match_now; 823 ip->insn_length = 824 ip->insn->mask ? loongarch_insn_length (ip->insn->match) : 0; 825 /* FIXME: now we have no relax insn. */ 826 ip->relax_max_length = ip->insn_length; 827 break; 828 default: 829 as_fatal (_("unknown escape")); 830 } 831 832 do 833 { 834 /* Check imm overflow. */ 835 int bit_width, bits_needed_s, bits_needed_u; 836 char *t; 837 838 if (!ip->match_now) 839 break; 840 841 if (0 < reloc_num) 842 break; 843 844 bit_width = loongarch_get_bit_field_width (bit_field, &t); 845 846 if (bit_width == -1) 847 /* No specify bit width. */ 848 break; 849 850 imm = ret; 851 if (t[0] == '<' && t[1] == '<') 852 { 853 int i = strtol (t += 2, &t, 10), j; 854 for (j = i; 0 < j; j--, imm >>= 1) 855 if (imm & 1) 856 as_fatal (_("require imm low %d bit is 0."), i); 857 } 858 859 if (*t == '+') 860 imm -= strtol (t, &t, 10); 861 862 bits_needed_s = loongarch_bits_imm_needed (imm, 1); 863 bits_needed_u = loongarch_bits_imm_needed (imm, 0); 864 865 if ((esc_ch1 == 's' && bit_width < bits_needed_s) 866 || (esc_ch1 != 's' && bit_width < bits_needed_u)) 867 /* How to do after we detect overflow. */ 868 as_fatal (_("Immediate overflow.\n" 869 "format: %c%c%s\n" 870 "arg: %s"), 871 esc_ch1, esc_ch2, bit_field, arg); 872 } 873 while (0); 874 875 if (esc_ch1 != '\0') 876 { 877 ip->args[ip->arg_num] = ret; 878 ip->arg_num++; 879 } 880 return ret; 881 } 882 883 static void 884 get_loongarch_opcode (struct loongarch_cl_insn *insn) 885 { 886 const struct loongarch_opcode *it; 887 struct loongarch_ase *ase; 888 for (ase = loongarch_ASEs; ase->enabled; ase++) 889 { 890 if (!*ase->enabled || (ase->include && !*ase->include) 891 || (ase->exclude && *ase->exclude)) 892 continue; 893 894 if (!ase->name_hash_entry) 895 { 896 ase->name_hash_entry = str_htab_create (); 897 for (it = ase->opcodes; it->name; it++) 898 { 899 if ((!it->include || (it->include && *it->include)) 900 && (!it->exclude || (it->exclude && !(*it->exclude))) 901 && !(it->pinfo & INSN_DIS_ALIAS)) 902 str_hash_insert (ase->name_hash_entry, it->name, 903 (void *) it, 0); 904 } 905 } 906 907 if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL) 908 continue; 909 910 do 911 { 912 insn->insn = it; 913 insn->match_now = 1; 914 insn->all_match = 0; 915 insn->arg_num = 0; 916 insn->reloc_num = 0; 917 insn->insn_bin = (loongarch_foreach_args 918 (it->format, insn->arg_strs, 919 loongarch_args_parser_can_match_arg_helper, 920 insn)); 921 if (insn->all_match && !(it->include && !*it->include) 922 && !(it->exclude && *it->exclude)) 923 { 924 insn->insn_bin |= it->match; 925 return; 926 } 927 it++; 928 } 929 while (it->name && strcasecmp (it->name, insn->name) == 0); 930 } 931 } 932 933 static int 934 check_this_insn_before_appending (struct loongarch_cl_insn *ip) 935 { 936 int ret = 0; 937 938 if (strncmp (ip->name, "la.abs", 6) == 0) 939 { 940 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA; 941 ip->reloc_info[ip->reloc_num].value = const_0; 942 ip->reloc_num++; 943 } 944 else if (ip->insn->mask == 0xffff8000 945 /* amcas.b rd, rk, rj */ 946 && ((ip->insn_bin & 0xfff80000) == 0x38580000 947 /* amswap.w rd, rk, rj */ 948 || (ip->insn_bin & 0xfff00000) == 0x38600000 949 /* ammax_db.wu rd, rk, rj */ 950 || (ip->insn_bin & 0xffff0000) == 0x38700000 951 /* ammin_db.wu rd, rk, rj */ 952 || (ip->insn_bin & 0xffff0000) == 0x38710000)) 953 { 954 /* For AMO insn amswap.[wd], amadd.[wd], etc. */ 955 if (ip->args[0] != 0 956 && (ip->args[0] == ip->args[1] || ip->args[0] == ip->args[2])) 957 as_fatal (_("AMO insns require rd != base && rd != rt" 958 " when rd isn't $r0")); 959 } 960 else if ((ip->insn->mask == 0xffe08000 961 /* bstrins.w rd, rj, msbw, lsbw */ 962 && (ip->insn_bin & 0xffe00000) == 0x00600000) 963 || (ip->insn->mask == 0xffc00000 964 /* bstrins.d rd, rj, msbd, lsbd */ 965 && (ip->insn_bin & 0xff800000) == 0x00800000)) 966 { 967 /* For bstr(ins|pick).[wd]. */ 968 if (ip->args[2] < ip->args[3]) 969 as_fatal (_("bstr(ins|pick).[wd] require msbd >= lsbd")); 970 } 971 else if (ip->insn->mask != 0 && (ip->insn_bin & 0xfe0003c0) == 0x04000000 972 /* csrxchg rd, rj, csr_num */ 973 && (strcmp ("csrxchg", ip->name) == 0)) 974 as_fatal (_("csrxchg require rj != $r0 && rj != $r1")); 975 976 return ret; 977 } 978 979 static void 980 install_insn (const struct loongarch_cl_insn *insn) 981 { 982 char *f = insn->frag->fr_literal + insn->where; 983 if (0 < insn->insn_length) 984 md_number_to_chars (f, insn->insn_bin, insn->insn_length); 985 } 986 987 static void 988 move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where) 989 { 990 size_t i; 991 insn->frag = frag; 992 insn->where = where; 993 for (i = 0; i < insn->reloc_num; i++) 994 { 995 if (insn->fixp[i]) 996 { 997 insn->fixp[i]->fx_frag = frag; 998 insn->fixp[i]->fx_where = where; 999 } 1000 } 1001 install_insn (insn); 1002 } 1003 1004 /* Add INSN to the end of the output. */ 1005 static void 1006 append_fixed_insn (struct loongarch_cl_insn *insn) 1007 { 1008 /* Ensure the jirl is emitted to the same frag as the pcaddu18i. */ 1009 if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type) 1010 frag_grow (8); 1011 1012 char *f = frag_more (insn->insn_length); 1013 move_insn (insn, frag_now, f - frag_now->fr_literal); 1014 } 1015 1016 /* Add instructions based on the worst-case scenario firstly. */ 1017 static void 1018 append_relaxed_branch_insn (struct loongarch_cl_insn *insn, int max_chars, 1019 int var, relax_substateT subtype, symbolS *symbol, offsetT offset) 1020 { 1021 frag_grow (max_chars); 1022 move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal); 1023 frag_var (rs_machine_dependent, max_chars, var, 1024 subtype, symbol, offset, NULL); 1025 } 1026 1027 static void 1028 append_fixp_and_insn (struct loongarch_cl_insn *ip) 1029 { 1030 reloc_howto_type *howto; 1031 bfd_reloc_code_real_type r_type; 1032 struct reloc_info *reloc_info = ip->reloc_info; 1033 size_t i; 1034 1035 dwarf2_emit_insn (0); 1036 1037 for (i = 0; i < ip->reloc_num; i++) 1038 { 1039 r_type = reloc_info[i].type; 1040 1041 if (r_type != BFD_RELOC_UNUSED) 1042 { 1043 1044 gas_assert (&(reloc_info[i].value)); 1045 if (BFD_RELOC_LARCH_B16 == r_type || BFD_RELOC_LARCH_B21 == r_type) 1046 { 1047 int min_bytes = 4; /* One branch instruction. */ 1048 unsigned max_bytes = 8; /* Branch and jump instructions. */ 1049 1050 if (now_seg == absolute_section) 1051 { 1052 as_bad (_("relaxable branches not supported in absolute section")); 1053 return; 1054 } 1055 1056 append_relaxed_branch_insn (ip, max_bytes, min_bytes, 1057 RELAX_BRANCH_ENCODE (r_type), 1058 reloc_info[i].value.X_add_symbol, 1059 reloc_info[i].value.X_add_number); 1060 return; 1061 } 1062 else 1063 { 1064 howto = bfd_reloc_type_lookup (stdoutput, r_type); 1065 if (howto == NULL) 1066 as_fatal (_("no HOWTO loong relocation number %d"), r_type); 1067 1068 ip->fixp[i] = fix_new_exp (ip->frag, ip->where, 1069 bfd_get_reloc_size (howto), 1070 &reloc_info[i].value, FALSE, r_type); 1071 } 1072 } 1073 } 1074 1075 if (ip->insn_length < ip->relax_max_length) 1076 as_fatal (_("Internal error: not support relax now")); 1077 else 1078 append_fixed_insn (ip); 1079 1080 /* We need to start a new frag after any instruction that can be 1081 optimized away or compressed by the linker during relaxation, to prevent 1082 the assembler from computing static offsets across such an instruction. 1083 1084 This is necessary to get correct .eh_frame FDE DW_CFA_advance_loc info. 1085 If one cfi_insn_data's two symbols are not in the same frag, it will 1086 generate ADD and SUB relocations pairs to calculate DW_CFA_advance_loc. 1087 (gas/dw2gencfi.c: output_cfi_insn: 1088 if (symbol_get_frag (to) == symbol_get_frag (from))) 1089 1090 For macro instructions, only the first instruction expanded from macro 1091 need to start a new frag. */ 1092 if (LARCH_opts.relax 1093 && (BFD_RELOC_LARCH_PCALA_HI20 == reloc_info[0].type 1094 || BFD_RELOC_LARCH_GOT_PC_HI20 == reloc_info[0].type 1095 || BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_info[0].type 1096 || BFD_RELOC_LARCH_TLS_LE_ADD_R == reloc_info[0].type 1097 || BFD_RELOC_LARCH_TLS_LD_PC_HI20 == reloc_info[0].type 1098 || BFD_RELOC_LARCH_TLS_GD_PC_HI20 == reloc_info[0].type 1099 || BFD_RELOC_LARCH_TLS_DESC_PC_HI20 == reloc_info[0].type 1100 || BFD_RELOC_LARCH_TLS_DESC_PC_LO12 == reloc_info[0].type 1101 || BFD_RELOC_LARCH_TLS_DESC_LD == reloc_info[0].type 1102 || BFD_RELOC_LARCH_TLS_DESC_CALL == reloc_info[0].type 1103 || BFD_RELOC_LARCH_TLS_IE_PC_HI20 == reloc_info[0].type 1104 || BFD_RELOC_LARCH_TLS_IE_PC_LO12 == reloc_info[0].type)) 1105 { 1106 frag_wane (frag_now); 1107 frag_new (0); 1108 } 1109 } 1110 1111 /* Ask helper for returning a malloced c_str or NULL. */ 1112 static char * 1113 assember_macro_helper (const char *const args[], void *context_ptr) 1114 { 1115 struct loongarch_cl_insn *insn = context_ptr; 1116 char *ret = NULL; 1117 if ( strcmp (insn->name, "li.w") == 0 || strcmp (insn->name, "li.d") == 0) 1118 { 1119 char args_buf[50], insns_buf[200]; 1120 const char *arg_strs[6]; 1121 uint32_t hi32, lo32; 1122 1123 /* We pay attention to sign extend beacause it is chance of reduce insn. 1124 The exception is 12-bit and hi-12-bit unsigned, 1125 we need a 'ori' or a 'lu52i.d' accordingly. */ 1126 char all0_bit_vec, sign_bit_vec, allf_bit_vec, paritial_is_sext_of_prev; 1127 1128 lo32 = insn->args[1] & 0xffffffff; 1129 hi32 = insn->args[1] >> 32; 1130 1131 if (strcmp (insn->name, "li.w") == 0) 1132 { 1133 if (hi32 != 0 && hi32 != 0xffffffff) 1134 as_fatal (_("li overflow: hi32:0x%x lo32:0x%x"), hi32, lo32); 1135 hi32 = lo32 & 0x80000000 ? 0xffffffff : 0; 1136 } 1137 1138 if (strcmp (insn->name, "li.d") == 0 && !LARCH_opts.ase_lp64) 1139 as_fatal (_("we can't li.d on 32bit-arch")); 1140 1141 snprintf (args_buf, sizeof (args_buf), "0x%x,0x%x,0x%x,0x%x,%s", 1142 (hi32 >> 20) & 0xfff, hi32 & 0xfffff, (lo32 >> 12) & 0xfffff, 1143 lo32 & 0xfff, args[0]); 1144 loongarch_split_args_by_comma (args_buf, arg_strs); 1145 1146 all0_bit_vec = 1147 ((((hi32 & 0xfff00000) == 0) << 3) | (((hi32 & 0x000fffff) == 0) << 2) 1148 | (((lo32 & 0xfffff000) == 0) << 1) | ((lo32 & 0x00000fff) == 0)); 1149 sign_bit_vec = 1150 ((((hi32 & 0x80000000) != 0) << 3) | (((hi32 & 0x00080000) != 0) << 2) 1151 | (((lo32 & 0x80000000) != 0) << 1) | ((lo32 & 0x00000800) != 0)); 1152 allf_bit_vec = 1153 ((((hi32 & 0xfff00000) == 0xfff00000) << 3) 1154 | (((hi32 & 0x000fffff) == 0x000fffff) << 2) 1155 | (((lo32 & 0xfffff000) == 0xfffff000) << 1) 1156 | ((lo32 & 0x00000fff) == 0x00000fff)); 1157 paritial_is_sext_of_prev = 1158 (all0_bit_vec ^ allf_bit_vec) & (all0_bit_vec ^ (sign_bit_vec << 1)); 1159 1160 static const char *const li_32bit[] = 1161 { 1162 "lu12i.w %5,%3&0x80000?%3-0x100000:%3;ori %5,%5,%4;", 1163 "lu12i.w %5,%3&0x80000?%3-0x100000:%3;", 1164 "addi.w %5,$r0,%4&0x800?%4-0x1000:%4;", 1165 "or %5,$r0,$r0;", 1166 }; 1167 static const char *const li_hi_32bit[] = 1168 { 1169 "lu32i.d %5,%2&0x80000?%2-0x100000:%2;" 1170 "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;", 1171 "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;", 1172 "lu32i.d %5,%2&0x80000?%2-0x100000:%2;", 1173 "", 1174 }; 1175 do 1176 { 1177 insns_buf[0] = '\0'; 1178 if (paritial_is_sext_of_prev == 0x7) 1179 { 1180 strcat (insns_buf, "lu52i.d %5,$r0,%1&0x800?%1-0x1000:%1;"); 1181 break; 1182 } 1183 if ((all0_bit_vec & 0x3) == 0x2) 1184 strcat (insns_buf, "ori %5,$r0,%4;"); 1185 else 1186 strcat (insns_buf, li_32bit[paritial_is_sext_of_prev & 0x3]); 1187 strcat (insns_buf, li_hi_32bit[paritial_is_sext_of_prev >> 2]); 1188 } 1189 while (0); 1190 1191 ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL, 1192 sizeof (args_buf)); 1193 } 1194 1195 return ret; 1196 } 1197 1198 /* Accept instructions separated by ';' 1199 * assuming 'not starting with space and not ending with space' or pass in 1200 * empty c_str. */ 1201 static void 1202 loongarch_assemble_INSNs (char *str, unsigned int expand_from_macro) 1203 { 1204 char *rest; 1205 size_t len_str = strlen(str); 1206 1207 for (rest = str; *rest != ';' && *rest != '\0'; rest++); 1208 if (*rest == ';') 1209 *rest++ = '\0'; 1210 1211 if (*str == ':') 1212 { 1213 str++; 1214 setup_internal_label_here (strtol (str, &str, 10)); 1215 str++; 1216 } 1217 1218 do 1219 { 1220 if (*str == '\0') 1221 break; 1222 1223 struct loongarch_cl_insn the_one = { 0 }; 1224 the_one.name = str; 1225 the_one.expand_from_macro = expand_from_macro; 1226 1227 for (; *str && *str != ' '; str++) 1228 ; 1229 if (*str == ' ') 1230 *str++ = '\0'; 1231 1232 loongarch_split_args_by_comma (str, the_one.arg_strs); 1233 get_loongarch_opcode (&the_one); 1234 1235 if (!the_one.all_match) 1236 { 1237 char *ss = loongarch_cat_splited_strs (the_one.arg_strs); 1238 as_bad (_("no match insn: %s\t%s"), the_one.name, ss ? ss : ""); 1239 free(ss); 1240 return; 1241 } 1242 1243 if (check_this_insn_before_appending (&the_one) != 0) 1244 break; 1245 1246 append_fixp_and_insn (&the_one); 1247 1248 /* Expanding macro instructions. */ 1249 if (the_one.insn_length == 0 && the_one.insn->macro) 1250 { 1251 unsigned int new_expand_from_macro = 0; 1252 if (2 == the_one.arg_num) 1253 new_expand_from_macro |= 1; 1254 else if (3 == the_one.arg_num) 1255 new_expand_from_macro |= 2; 1256 1257 char *c_str = loongarch_expand_macro (the_one.insn->macro, 1258 the_one.arg_strs, 1259 assember_macro_helper, 1260 &the_one, len_str); 1261 /* The first instruction expanded from macro. */ 1262 loongarch_assemble_INSNs (c_str, new_expand_from_macro); 1263 free (c_str); 1264 } 1265 } 1266 while (0); 1267 1268 /* The rest instructions expanded from macro, split by semicolon(;), 1269 assembly one by one. */ 1270 if (*rest != '\0') 1271 loongarch_assemble_INSNs (rest, expand_from_macro); 1272 } 1273 1274 void 1275 md_assemble (char *str) 1276 { 1277 loongarch_assemble_INSNs (str, 0); 1278 } 1279 1280 const char * 1281 md_atof (int type, char *litP, int *sizeP) 1282 { 1283 return ieee_md_atof (type, litP, sizeP, FALSE); 1284 } 1285 1286 void 1287 md_number_to_chars (char *buf, valueT val, int n) 1288 { 1289 number_to_chars_littleendian (buf, val, n); 1290 } 1291 1292 /* The location from which a PC relative jump should be calculated, 1293 given a PC relative reloc. */ 1294 long 1295 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED) 1296 { 1297 return 0; 1298 } 1299 1300 static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf) 1301 { 1302 reloc_howto_type *howto; 1303 insn_t insn; 1304 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type); 1305 1306 insn = bfd_getl32 (buf); 1307 1308 if (!loongarch_adjust_reloc_bitsfield (NULL, howto, &reloc_val)) 1309 as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow"); 1310 1311 insn = (insn & (insn_t)howto->src_mask) 1312 | ((insn & (~(insn_t)howto->dst_mask)) | reloc_val); 1313 1314 bfd_putl32 (insn, buf); 1315 } 1316 1317 void 1318 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED) 1319 { 1320 static int64_t stack_top; 1321 static int last_reloc_is_sop_push_pcrel_1 = 0; 1322 int last_reloc_is_sop_push_pcrel = last_reloc_is_sop_push_pcrel_1; 1323 segT sub_segment; 1324 last_reloc_is_sop_push_pcrel_1 = 0; 1325 1326 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where; 1327 switch (fixP->fx_r_type) 1328 { 1329 case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL: 1330 case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD: 1331 case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT: 1332 case BFD_RELOC_LARCH_TLS_LE_HI20: 1333 case BFD_RELOC_LARCH_TLS_LE_LO12: 1334 case BFD_RELOC_LARCH_TLS_LE64_LO20: 1335 case BFD_RELOC_LARCH_TLS_LE64_HI12: 1336 case BFD_RELOC_LARCH_TLS_IE_PC_HI20: 1337 case BFD_RELOC_LARCH_TLS_IE_PC_LO12: 1338 case BFD_RELOC_LARCH_TLS_IE64_PC_LO20: 1339 case BFD_RELOC_LARCH_TLS_IE64_PC_HI12: 1340 case BFD_RELOC_LARCH_TLS_IE_HI20: 1341 case BFD_RELOC_LARCH_TLS_IE_LO12: 1342 case BFD_RELOC_LARCH_TLS_IE64_LO20: 1343 case BFD_RELOC_LARCH_TLS_IE64_HI12: 1344 case BFD_RELOC_LARCH_TLS_LD_PC_HI20: 1345 case BFD_RELOC_LARCH_TLS_LD_HI20: 1346 case BFD_RELOC_LARCH_TLS_GD_PC_HI20: 1347 case BFD_RELOC_LARCH_TLS_GD_HI20: 1348 case BFD_RELOC_LARCH_TLS_DESC_PC_HI20: 1349 case BFD_RELOC_LARCH_TLS_DESC_PC_LO12: 1350 case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20: 1351 case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12: 1352 case BFD_RELOC_LARCH_TLS_DESC_HI20: 1353 case BFD_RELOC_LARCH_TLS_DESC_LO12: 1354 case BFD_RELOC_LARCH_TLS_DESC64_LO20: 1355 case BFD_RELOC_LARCH_TLS_DESC64_HI12: 1356 /* Add tls lo (got_lo reloc type). */ 1357 if (fixP->fx_addsy == NULL) 1358 as_bad_where (fixP->fx_file, fixP->fx_line, 1359 _("Relocation against a constant")); 1360 S_SET_THREAD_LOCAL (fixP->fx_addsy); 1361 break; 1362 1363 case BFD_RELOC_LARCH_SOP_PUSH_PCREL: 1364 if (fixP->fx_addsy == NULL) 1365 as_bad_where (fixP->fx_file, fixP->fx_line, 1366 _("Relocation against a constant")); 1367 1368 last_reloc_is_sop_push_pcrel_1 = 1; 1369 if (S_GET_SEGMENT (fixP->fx_addsy) == seg) 1370 stack_top = (S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset 1371 - (fixP->fx_where + fixP->fx_frag->fr_address)); 1372 else 1373 stack_top = 0; 1374 break; 1375 1376 case BFD_RELOC_LARCH_TLS_DESC_LD: 1377 case BFD_RELOC_LARCH_TLS_DESC_CALL: 1378 break; 1379 1380 case BFD_RELOC_LARCH_SOP_POP_32_S_10_5: 1381 case BFD_RELOC_LARCH_SOP_POP_32_S_10_12: 1382 case BFD_RELOC_LARCH_SOP_POP_32_U_10_12: 1383 case BFD_RELOC_LARCH_SOP_POP_32_S_10_16: 1384 case BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2: 1385 case BFD_RELOC_LARCH_SOP_POP_32_S_5_20: 1386 case BFD_RELOC_LARCH_SOP_POP_32_U: 1387 case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2: 1388 case BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2: 1389 if (!last_reloc_is_sop_push_pcrel) 1390 break; 1391 1392 fix_reloc_insn (fixP, (bfd_vma)stack_top, buf); 1393 break; 1394 1395 /* LARCH only has R_LARCH_64/32, not has R_LARCH_24/16/8. 1396 For BFD_RELOC_64/32, if fx_addsy and fx_subsy not null, wer need 1397 generate BFD_RELOC_LARCH_ADD64/32 and BFD_RELOC_LARCH_SUB64/32 here. 1398 Then will parse howto table bfd_reloc_code_real_type to generate 1399 R_LARCH_ADD64/32 and R_LARCH_SUB64/32 reloc at tc_gen_reloc function. 1400 If only fx_addsy not null, skip here directly, then generate 1401 R_LARCH_64/32. 1402 1403 For BFD_RELOC_24/16/8, if fx_addsy and fx_subsy not null, wer need 1404 generate BFD_RELOC_LARCH_ADD24/16/8 and BFD_RELOC_LARCH_SUB24/16/8 here. 1405 Then will parse howto table bfd_reloc_code_real_type to generate 1406 R_LARCH_ADD24/16/8 and R_LARCH_SUB24/16/8 reloc at tc_gen_reloc 1407 function. If only fx_addsy not null, we generate 1408 BFD_RELOC_LARCH_ADD24/16/8 only, then generate R_LARCH_24/16/8. 1409 To avoid R_LARCH_ADDxx add extra value, we write 0 first 1410 (use md_number_to_chars (buf, 0, fixP->fx_size)). */ 1411 case BFD_RELOC_64: 1412 case BFD_RELOC_32: 1413 if (fixP->fx_pcrel) 1414 { 1415 switch (fixP->fx_r_type) 1416 { 1417 case BFD_RELOC_64: 1418 fixP->fx_r_type = BFD_RELOC_LARCH_64_PCREL; 1419 break; 1420 case BFD_RELOC_32: 1421 fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL; 1422 break; 1423 default: 1424 break; 1425 } 1426 } 1427 1428 /* If symbol in .eh_frame the address may be adjusted, and contents of 1429 .eh_frame will be adjusted, so use pc-relative relocation for FDE 1430 initial location. 1431 The Option of mthin-add-sub does not affect the generation of 1432 R_LARCH_32_PCREL relocation in .eh_frame. */ 1433 if (fixP->fx_r_type == BFD_RELOC_32 1434 && fixP->fx_addsy && fixP->fx_subsy 1435 && (sub_segment = S_GET_SEGMENT (fixP->fx_subsy)) 1436 && strcmp (sub_segment->name, ".eh_frame") == 0 1437 && S_GET_VALUE (fixP->fx_subsy) 1438 == fixP->fx_frag->fr_address + fixP->fx_where) 1439 { 1440 fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL; 1441 fixP->fx_subsy = NULL; 1442 break; 1443 } 1444 1445 if (fixP->fx_addsy && fixP->fx_subsy) 1446 { 1447 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP)); 1448 fixP->fx_next->fx_addsy = fixP->fx_subsy; 1449 fixP->fx_next->fx_subsy = NULL; 1450 fixP->fx_next->fx_offset = 0; 1451 fixP->fx_subsy = NULL; 1452 1453 switch (fixP->fx_r_type) 1454 { 1455 case BFD_RELOC_64: 1456 fixP->fx_r_type = BFD_RELOC_LARCH_ADD64; 1457 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB64; 1458 break; 1459 case BFD_RELOC_32: 1460 fixP->fx_r_type = BFD_RELOC_LARCH_ADD32; 1461 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32; 1462 break; 1463 default: 1464 break; 1465 } 1466 1467 md_number_to_chars (buf, 0, fixP->fx_size); 1468 } 1469 1470 if (fixP->fx_addsy == NULL) 1471 { 1472 fixP->fx_done = 1; 1473 md_number_to_chars (buf, *valP, fixP->fx_size); 1474 } 1475 break; 1476 1477 case BFD_RELOC_24: 1478 case BFD_RELOC_16: 1479 case BFD_RELOC_8: 1480 if (fixP->fx_addsy) 1481 { 1482 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP)); 1483 fixP->fx_next->fx_addsy = fixP->fx_subsy; 1484 fixP->fx_next->fx_subsy = NULL; 1485 fixP->fx_next->fx_offset = 0; 1486 fixP->fx_subsy = NULL; 1487 1488 switch (fixP->fx_r_type) 1489 { 1490 case BFD_RELOC_24: 1491 fixP->fx_r_type = BFD_RELOC_LARCH_ADD24; 1492 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24; 1493 break; 1494 case BFD_RELOC_16: 1495 fixP->fx_r_type = BFD_RELOC_LARCH_ADD16; 1496 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16; 1497 break; 1498 case BFD_RELOC_8: 1499 fixP->fx_r_type = BFD_RELOC_LARCH_ADD8; 1500 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8; 1501 break; 1502 default: 1503 break; 1504 } 1505 1506 md_number_to_chars (buf, 0, fixP->fx_size); 1507 1508 if (fixP->fx_next->fx_addsy == NULL) 1509 fixP->fx_next->fx_done = 1; 1510 } 1511 1512 if (fixP->fx_addsy == NULL) 1513 { 1514 fixP->fx_done = 1; 1515 md_number_to_chars (buf, *valP, fixP->fx_size); 1516 } 1517 break; 1518 1519 case BFD_RELOC_LARCH_CFA: 1520 if (fixP->fx_addsy && fixP->fx_subsy) 1521 { 1522 fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP)); 1523 fixP->fx_next->fx_addsy = fixP->fx_subsy; 1524 fixP->fx_next->fx_subsy = NULL; 1525 fixP->fx_next->fx_offset = 0; 1526 fixP->fx_subsy = NULL; 1527 1528 unsigned int subtype; 1529 offsetT loc; 1530 subtype = bfd_get_8 (NULL, &((fragS *) 1531 (fixP->fx_frag->fr_opcode))->fr_literal[fixP->fx_where]); 1532 loc = fixP->fx_frag->fr_fix - (subtype & 7); 1533 switch (subtype) 1534 { 1535 case DW_CFA_advance_loc1: 1536 fixP->fx_where = loc + 1; 1537 fixP->fx_next->fx_where = loc + 1; 1538 fixP->fx_r_type = BFD_RELOC_LARCH_ADD8; 1539 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8; 1540 md_number_to_chars (buf+1, 0, fixP->fx_size); 1541 break; 1542 1543 case DW_CFA_advance_loc2: 1544 fixP->fx_size = 2; 1545 fixP->fx_next->fx_size = 2; 1546 fixP->fx_where = loc + 1; 1547 fixP->fx_next->fx_where = loc + 1; 1548 fixP->fx_r_type = BFD_RELOC_LARCH_ADD16; 1549 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16; 1550 md_number_to_chars (buf+1, 0, fixP->fx_size); 1551 break; 1552 1553 case DW_CFA_advance_loc4: 1554 fixP->fx_size = 4; 1555 fixP->fx_next->fx_size = 4; 1556 fixP->fx_where = loc; 1557 fixP->fx_next->fx_where = loc; 1558 fixP->fx_r_type = BFD_RELOC_LARCH_ADD32; 1559 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32; 1560 md_number_to_chars (buf+1, 0, fixP->fx_size); 1561 break; 1562 1563 default: 1564 if (subtype < 0x80 && (subtype & 0x40)) 1565 { 1566 /* DW_CFA_advance_loc. */ 1567 fixP->fx_frag = (fragS *) fixP->fx_frag->fr_opcode; 1568 fixP->fx_next->fx_frag = fixP->fx_frag; 1569 fixP->fx_r_type = BFD_RELOC_LARCH_ADD6; 1570 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB6; 1571 md_number_to_chars (buf, 0x40, fixP->fx_size); 1572 } 1573 else 1574 as_fatal (_("internal: bad CFA value #%d"), subtype); 1575 break; 1576 } 1577 } 1578 break; 1579 1580 case BFD_RELOC_LARCH_B16: 1581 case BFD_RELOC_LARCH_B21: 1582 case BFD_RELOC_LARCH_B26: 1583 if (fixP->fx_addsy == NULL) 1584 { 1585 as_bad_where (fixP->fx_file, fixP->fx_line, 1586 _ ("Relocation against a constant.")); 1587 } 1588 if (S_GET_SEGMENT (fixP->fx_addsy) == seg 1589 && !S_FORCE_RELOC (fixP->fx_addsy, 1)) 1590 { 1591 int64_t sym_addend = S_GET_VALUE (fixP->fx_addsy) + fixP->fx_offset; 1592 int64_t pc = fixP->fx_where + fixP->fx_frag->fr_address; 1593 fix_reloc_insn (fixP, sym_addend - pc, buf); 1594 1595 /* If relax, symbol value may change at link time, so reloc need to 1596 be saved. */ 1597 if (!LARCH_opts.relax) 1598 fixP->fx_done = 1; 1599 } 1600 break; 1601 1602 /* Because ADD_ULEB128/SUB_ULEB128 always occur in pairs. 1603 So just deal with one is ok. 1604 case BFD_RELOC_LARCH_ADD_ULEB128: */ 1605 case BFD_RELOC_LARCH_SUB_ULEB128: 1606 { 1607 unsigned int len = 0; 1608 len = loongarch_get_uleb128_length ((bfd_byte *)buf); 1609 bfd_byte *endp = (bfd_byte*) buf + len -1; 1610 /* Clean the uleb128 value to 0. Do not reduce the length. */ 1611 memset (buf, 0x80, len - 1); 1612 *endp = 0; 1613 break; 1614 } 1615 1616 default: 1617 break; 1618 } 1619 } 1620 1621 int 1622 md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED, 1623 asection *segtype ATTRIBUTE_UNUSED) 1624 { 1625 return (fragp->fr_var = 4); 1626 } 1627 1628 /* Translate internal representation of relocation info to BFD target 1629 format. */ 1630 arelent * 1631 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp) 1632 { 1633 arelent *reloc = (arelent *) xmalloc (sizeof (arelent)); 1634 1635 reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *)); 1636 *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy); 1637 reloc->address = fixp->fx_frag->fr_address + fixp->fx_where; 1638 reloc->addend = fixp->fx_offset; 1639 1640 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type); 1641 if (reloc->howto == NULL) 1642 { 1643 as_bad_where (fixp->fx_file, fixp->fx_line, 1644 _("cannot represent %s relocation in object file"), 1645 bfd_get_reloc_code_name (fixp->fx_r_type)); 1646 return NULL; 1647 } 1648 1649 return reloc; 1650 } 1651 1652 /* Standard calling conventions leave the CFA at SP on entry. */ 1653 void 1654 loongarch_cfi_frame_initial_instructions (void) 1655 { 1656 cfi_add_CFA_def_cfa_register (3 /* $sp */); 1657 } 1658 1659 void 1660 loongarch_pre_output_hook (void) 1661 { 1662 const frchainS *frch; 1663 segT s; 1664 1665 if (!LARCH_opts.relax) 1666 return; 1667 1668 /* Save the current segment info. */ 1669 segT seg = now_seg; 1670 subsegT subseg = now_subseg; 1671 1672 for (s = stdoutput->sections; s; s = s->next) 1673 for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next) 1674 { 1675 fragS *frag; 1676 1677 for (frag = frch->frch_root; frag; frag = frag->fr_next) 1678 { 1679 if (frag->fr_type == rs_cfa) 1680 { 1681 expressionS exp; 1682 expressionS *symval; 1683 1684 symval = symbol_get_value_expression (frag->fr_symbol); 1685 exp.X_op = O_subtract; 1686 exp.X_add_symbol = symval->X_add_symbol; 1687 exp.X_add_number = 0; 1688 exp.X_op_symbol = symval->X_op_symbol; 1689 1690 /* We must set the segment before creating a frag after all 1691 frag chains have been chained together. */ 1692 subseg_set (s, frch->frch_subseg); 1693 1694 fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0, 1695 BFD_RELOC_LARCH_CFA); 1696 } 1697 } 1698 } 1699 1700 /* Restore the original segment info. */ 1701 subseg_set (seg, subseg); 1702 } 1703 1704 void 1705 tc_loongarch_parse_to_dw2regnum (expressionS *exp) 1706 { 1707 expression_and_evaluate (exp); 1708 } 1709 1710 void 1711 md_show_usage (FILE *stream) 1712 { 1713 fprintf (stream, _("LARCH options:\n")); 1714 /* FIXME */ 1715 fprintf (stream, _("\ 1716 -mthin-add-sub Convert a pair of R_LARCH_ADD32/64 and R_LARCH_SUB32/64 to\n\ 1717 R_LARCH_32/64_PCREL as much as possible\n\ 1718 The option does not affect the generation of R_LARCH_32_PCREL\n\ 1719 relocations in .eh_frame\n")); 1720 } 1721 1722 static void 1723 loongarch_make_nops (char *buf, bfd_vma bytes) 1724 { 1725 bfd_vma i = 0; 1726 1727 /* Fill with 4-byte NOPs. */ 1728 for ( ; i < bytes; i += 4) 1729 number_to_chars_littleendian (buf + i, LARCH_NOP, 4); 1730 } 1731 1732 /* Called from md_do_align. Used to create an alignment frag in a 1733 code section by emitting a worst-case NOP sequence that the linker 1734 will later relax to the correct number of NOPs. We can't compute 1735 the correct alignment now because of other linker relaxations. */ 1736 1737 bool 1738 loongarch_frag_align_code (int n, int max) 1739 { 1740 char *nops; 1741 symbolS *s; 1742 expressionS ex; 1743 1744 bfd_vma insn_alignment = 4; 1745 bfd_vma bytes = (bfd_vma) 1 << n; 1746 bfd_vma worst_case_bytes = bytes - insn_alignment; 1747 1748 /* If we are moving to a smaller alignment than the instruction size, then no 1749 alignment is required. */ 1750 if (bytes <= insn_alignment) 1751 return true; 1752 1753 /* When not relaxing, loongarch_handle_align handles code alignment. */ 1754 if (!LARCH_opts.relax) 1755 return false; 1756 1757 nops = frag_more (worst_case_bytes); 1758 1759 s = symbol_find (".Lla-relax-align"); 1760 if (s == NULL) 1761 s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg, 1762 &zero_address_frag, 0); 1763 1764 ex.X_add_symbol = s; 1765 ex.X_op = O_symbol; 1766 ex.X_add_number = (max << 8) | n; 1767 1768 loongarch_make_nops (nops, worst_case_bytes); 1769 1770 fix_new_exp (frag_now, nops - frag_now->fr_literal, 0, 1771 &ex, false, BFD_RELOC_LARCH_ALIGN); 1772 1773 /* We need to start a new frag after the alignment which may be removed by 1774 the linker, to prevent the assembler from computing static offsets. 1775 This is necessary to get correct EH info. */ 1776 frag_wane (frag_now); 1777 frag_new (0); 1778 1779 return true; 1780 } 1781 1782 /* Fill in an rs_align_code fragment. We want to fill 'andi $r0,$r0,0'. */ 1783 void 1784 loongarch_handle_align (fragS *fragp) 1785 { 1786 /* char nop_opcode; */ 1787 char *p; 1788 int bytes, size, excess; 1789 valueT opcode; 1790 1791 if (fragp->fr_type != rs_align_code) 1792 return; 1793 1794 struct loongarch_cl_insn nop = 1795 { .name = "andi", .arg_strs = { "$r0", "$r0", "0", NULL } }; 1796 1797 get_loongarch_opcode (&nop); 1798 gas_assert (nop.all_match); 1799 1800 p = fragp->fr_literal + fragp->fr_fix; 1801 opcode = nop.insn_bin; 1802 size = 4; 1803 1804 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix; 1805 excess = bytes % size; 1806 1807 gas_assert (excess < 4); 1808 fragp->fr_fix += excess; 1809 1810 while (excess-- != 0) 1811 *p++ = 0; 1812 1813 md_number_to_chars (p, opcode, size); 1814 fragp->fr_var = size; 1815 } 1816 1817 /* Scan uleb128 subtraction expressions and insert fixups for them. 1818 e.g., .uleb128 .L1 - .L0 1819 Because relaxation may change the value of the subtraction, we 1820 must resolve them at link-time. */ 1821 1822 static void 1823 loongarch_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED, 1824 asection *sec, void *xxx ATTRIBUTE_UNUSED) 1825 { 1826 segment_info_type *seginfo = seg_info (sec); 1827 struct frag *fragP; 1828 1829 subseg_set (sec, 0); 1830 1831 for (fragP = seginfo->frchainP->frch_root; 1832 fragP; fragP = fragP->fr_next) 1833 { 1834 expressionS *exp, *exp_dup; 1835 1836 if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL) 1837 continue; 1838 1839 exp = symbol_get_value_expression (fragP->fr_symbol); 1840 1841 if (exp->X_op != O_subtract) 1842 continue; 1843 1844 /* FIXME: Skip for .sleb128. */ 1845 if (fragP->fr_subtype != 0) 1846 continue; 1847 1848 exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp)); 1849 exp_dup->X_op = O_symbol; 1850 exp_dup->X_op_symbol = NULL; 1851 1852 exp_dup->X_add_symbol = exp->X_add_symbol; 1853 fix_new_exp (fragP, fragP->fr_fix, 0, 1854 exp_dup, 0, BFD_RELOC_LARCH_ADD_ULEB128); 1855 1856 /* From binutils/testsuite/binutils-all/dw5.S 1857 section .debug_rnglists 1858 .uleb128 .Letext0-.Ltext0 Range length (*.LLRL2) 1859 Offset Info Type Symbol's Value Symbol's Name + Addend 1860 0000000000000015 0000000200000079 R_LARCH_ADD_ULEB128 0000000000000000 .text + 2 1861 0000000000000015 000000020000007a R_LARCH_SUB_ULEB128 0000000000000000 .text + 0. */ 1862 1863 /* Only the ADD_ULEB128 has X_add_number (Addend)? */ 1864 exp_dup->X_add_number = 0; 1865 exp_dup->X_add_symbol = exp->X_op_symbol; 1866 fix_new_exp (fragP, fragP->fr_fix, 0, 1867 exp_dup, 0, BFD_RELOC_LARCH_SUB_ULEB128); 1868 } 1869 } 1870 1871 void 1872 loongarch_md_finish (void) 1873 { 1874 /* Insert relocations for uleb128 directives, so the values can be recomputed 1875 at link time. */ 1876 if (LARCH_opts.relax) 1877 bfd_map_over_sections (stdoutput, loongarch_insert_uleb128_fixes, NULL); 1878 } 1879 1880 void 1881 loongarch_elf_final_processing (void) 1882 { 1883 elf_elfheader (stdoutput)->e_flags = LARCH_opts.ase_abi; 1884 } 1885 1886 /* Compute the length of a branch sequence, and adjust the stored length 1887 accordingly. If FRAGP is NULL, the worst-case length is returned. */ 1888 static unsigned 1889 loongarch_relaxed_branch_length (fragS *fragp, asection *sec, int update) 1890 { 1891 int length = 4; 1892 1893 if (!fragp) 1894 return 8; 1895 1896 if (fragp->fr_symbol != NULL 1897 && S_IS_DEFINED (fragp->fr_symbol) 1898 && !S_IS_WEAK (fragp->fr_symbol) 1899 && sec == S_GET_SEGMENT (fragp->fr_symbol)) 1900 { 1901 offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset; 1902 1903 val -= fragp->fr_address + fragp->fr_fix; 1904 1905 if (RELAX_BRANCH_16 == fragp->fr_subtype 1906 && OUT_OF_RANGE (val, 16, 2)) 1907 { 1908 length = 8; 1909 if (update) 1910 fragp->fr_subtype = RELAX_BRANCH_26; 1911 } 1912 1913 if (RELAX_BRANCH_21 == fragp->fr_subtype 1914 && OUT_OF_RANGE (val, 21, 2)) 1915 { 1916 length = 8; 1917 if (update) 1918 fragp->fr_subtype = RELAX_BRANCH_26; 1919 } 1920 1921 if (RELAX_BRANCH_26 == fragp->fr_subtype) 1922 length = 8; 1923 } 1924 1925 return length; 1926 } 1927 1928 int 1929 loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED, 1930 fragS *fragp ATTRIBUTE_UNUSED, 1931 long stretch ATTRIBUTE_UNUSED) 1932 { 1933 if (RELAX_BRANCH (fragp->fr_subtype)) 1934 { 1935 offsetT old_var = fragp->fr_var; 1936 fragp->fr_var = loongarch_relaxed_branch_length (fragp, sec, true); 1937 return fragp->fr_var - old_var; 1938 } 1939 return 0; 1940 } 1941 1942 /* Expand far branches to multi-instruction sequences. 1943 Branch instructions: 1944 beq, bne, blt, bgt, bltz, bgtz, ble, bge, blez, bgez 1945 bltu, bgtu, bleu, bgeu 1946 beqz, bnez, bceqz, bcnez. */ 1947 1948 static void 1949 loongarch_convert_frag_branch (fragS *fragp) 1950 { 1951 bfd_byte *buf; 1952 expressionS exp; 1953 fixS *fixp; 1954 insn_t insn; 1955 1956 buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix; 1957 1958 exp.X_op = O_symbol; 1959 exp.X_add_symbol = fragp->fr_symbol; 1960 exp.X_add_number = fragp->fr_offset; 1961 1962 gas_assert ((fragp->fr_subtype & 0xf) == fragp->fr_var); 1963 1964 /* blt $t0, $t1, .L1 1965 nop 1966 change to: 1967 bge $t0, $t1, .L2 1968 b .L1 1969 .L2: 1970 nop */ 1971 switch (fragp->fr_subtype) 1972 { 1973 case RELAX_BRANCH_26: 1974 insn = bfd_getl32 (buf); 1975 /* Invert the branch condition. */ 1976 if (LARCH_FLOAT_BRANCH == (insn & LARCH_BRANCH_OPCODE_MASK)) 1977 insn ^= LARCH_FLOAT_BRANCH_INVERT_BIT; 1978 else 1979 insn ^= LARCH_BRANCH_INVERT_BIT; 1980 insn |= ENCODE_BRANCH16_IMM (8); /* Set target to PC + 8. */ 1981 bfd_putl32 (insn, buf); 1982 buf += 4; 1983 1984 /* Add the B instruction and jump to the original target. */ 1985 bfd_putl32 (LARCH_B, buf); 1986 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, 1987 4, &exp, false, BFD_RELOC_LARCH_B26); 1988 buf += 4; 1989 break; 1990 case RELAX_BRANCH_21: 1991 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, 1992 4, &exp, false, BFD_RELOC_LARCH_B21); 1993 buf += 4; 1994 break; 1995 case RELAX_BRANCH_16: 1996 fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal, 1997 4, &exp, false, BFD_RELOC_LARCH_B16); 1998 buf += 4; 1999 break; 2000 2001 default: 2002 abort(); 2003 } 2004 2005 fixp->fx_file = fragp->fr_file; 2006 fixp->fx_line = fragp->fr_line; 2007 2008 gas_assert (buf == (bfd_byte *)fragp->fr_literal 2009 + fragp->fr_fix + fragp->fr_var); 2010 2011 fragp->fr_fix += fragp->fr_var; 2012 } 2013 2014 /* Relax a machine dependent frag. This returns the amount by which 2015 the current size of the frag should change. */ 2016 2017 void 2018 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED, 2019 fragS *fragp) 2020 { 2021 gas_assert (RELAX_BRANCH (fragp->fr_subtype)); 2022 loongarch_convert_frag_branch (fragp); 2023 } 2024