1 /* tc-loongarch.c -- Assemble for the LoongArch ISA
3 Copyright (C) 2021-2024 Free Software Foundation, Inc.
4 Contributed by Loongson Ltd.
6 This file is part of GAS.
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.
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.
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/>. */
24 #include "dw2gencfi.h"
25 #include "loongarch-lex.h"
26 #include "elf/loongarch.h"
27 #include "opcode/loongarch.h"
29 #include "bfd/elfxx-loongarch.h"
35 /* All information about an instruction during assemble. */
36 struct loongarch_cl_insn
38 /* First split string. */
40 const char *arg_strs[MAX_ARG_NUM_PLUS_2];
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. */
51 const struct loongarch_opcode *insn;
54 offsetT args[MAX_ARG_NUM_PLUS_2];
55 struct reloc_info reloc_info[MAX_RELOC_NUMBER_A_INSN];
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;
64 /* Then we get the binary representation of insn
65 and write it in to section. */
68 /* The frag that contains the instruction. */
70 /* The offset into FRAG of the first instruction byte. */
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.
82 The macros or instructions expanded from macros do not output register
83 deprecated warning. */
84 unsigned int expand_from_macro;
88 #define DEFAULT_ARCH "loongarch64"
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[] = "#";
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[] = "#";
104 /* This array holds machine specific line separator characters. */
105 const char line_separator_chars[] = ";";
107 /* Chars that can be used to separate mant from exp in floating point nums. */
108 const char EXP_CHARS[] = "eE";
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";
115 const char *md_shortopts = "O::g::G:";
117 static const char default_arch[] = DEFAULT_ARCH;
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
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)
131 OPTION_IGNORE = OPTION_MD_BASE,
138 OPTION_LA_LOCAL_WITH_ABS,
139 OPTION_LA_GLOBAL_WITH_PCREL,
140 OPTION_LA_GLOBAL_WITH_ABS,
148 struct option md_longopts[] =
150 { "mabi", required_argument, NULL, OPTION_ABI },
152 { "mfpu", required_argument, NULL, OPTION_FLOAT_ISA },
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 },
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},
162 { NULL, no_argument, NULL, 0 }
165 size_t md_longopts_size = sizeof (md_longopts);
168 md_parse_option (int c, const char *arg)
172 char ilp32[256] = "";
173 unsigned char *suf = (unsigned char *)arg;
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;
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;
186 if (strncasecmp (arg, "lp64", 4) == 0 && lp64[suf[4]] != 0)
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]];
196 else if (strncasecmp (arg, "ilp32", 5) == 0 && ilp32[suf[5]] != 0)
198 LARCH_opts.ase_abi = ilp32[suf[5]];
199 LARCH_opts.ase_ilp32 = 1;
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)
212 LARCH_opts.ase_sf = 1;
213 LARCH_opts.ase_df = 1;
219 case OPTION_LA_LOCAL_WITH_ABS:
220 LARCH_opts.ase_labs = 1;
223 case OPTION_LA_GLOBAL_WITH_PCREL:
224 LARCH_opts.ase_gpcr = 1;
227 case OPTION_LA_GLOBAL_WITH_ABS:
228 LARCH_opts.ase_gabs = 1;
232 LARCH_opts.relax = 1;
235 case OPTION_NO_RELAX:
236 LARCH_opts.relax = 0;
239 case OPTION_THIN_ADD_SUB:
240 LARCH_opts.thin_add_sub = 1;
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;
267 loongarch_after_parse_args ()
269 /* Set default ABI/ISA LP64D. */
270 if (!LARCH_opts.ase_ilp32)
272 if (strcmp (default_arch, "loongarch64") == 0)
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;
282 else if (strcmp (default_arch, "loongarch32") == 0)
284 LARCH_opts.ase_abi = EF_LOONGARCH_ABI_DOUBLE_FLOAT;
285 LARCH_opts.ase_ilp32 = 1;
288 as_bad ("unknown default architecture `%s'", default_arch);
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)
297 LARCH_opts.ase_sf = 1;
298 LARCH_opts.ase_df = 1;
303 assert(LARCH_opts.ase_ilp32);
305 /* Init ilp32/lp64 registers names. */
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);
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);
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);
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);
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);
329 cr_htab = str_htab_create (), str_hash_insert (cr_htab, "", 0, 0);
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);
334 /* Init single/double float registers names. */
335 if (LARCH_opts.ase_sf || LARCH_opts.ase_df)
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);
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),
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);
358 fc_htab = str_htab_create (), str_hash_insert (fc_htab, "", 0, 0);
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),
365 fcn_htab = str_htab_create (), str_hash_insert (fcn_htab, "", 0, 0);
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),
372 c_htab = str_htab_create (), str_hash_insert (c_htab, "", 0, 0);
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),
380 /* Init lsx registers names. */
381 if (LARCH_opts.ase_lsx)
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),
390 /* Init lasx registers names. */
391 if (LARCH_opts.ase_lasx)
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),
403 loongarch_target_format ()
405 return LARCH_opts.ase_lp64 ? "elf64-loongarch" : "elf32-loongarch";
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++)
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 "
422 it->name, it->format);
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);
429 /* FIXME: expressionS use 'offsetT' as constant,
430 * we want this is 64-bit type. */
431 assert (8 <= sizeof (offsetT));
435 loongarch_mach (void)
437 return LARCH_opts.ase_lp64 ? bfd_mach_loongarch64 : bfd_mach_loongarch32;
440 static const expressionS const_0 = { .X_op = O_constant, .X_add_number = 0 };
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. */
454 if (ex.X_op != O_symbol)
456 as_bad (_("Unsupported use of %s"),
457 (bytes == 8 ? ".dtpreldword" : ".dtprelword"));
458 ignore_rest_of_line ();
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,
465 ? BFD_RELOC_LARCH_TLS_DTPREL64
466 : BFD_RELOC_LARCH_TLS_DTPREL32));
468 demand_empty_rest_of_line ();
471 static const pseudo_typeS loongarch_pseudo_table[] =
473 { "dword", cons, 8 },
476 { "dtprelword", s_dtprel, 4 },
477 { "dtpreldword", s_dtprel, 8 },
482 loongarch_pop_insert (void)
484 pop_insert (loongarch_pseudo_table);
487 #define INTERNAL_LABEL_SPECIAL 10
488 static unsigned long internal_label_count[INTERNAL_LABEL_SPECIAL] = { 0 };
491 loongarch_internal_label_name (unsigned long label, int augend)
493 static char symbol_name_build[24];
494 unsigned long want_label;
497 want_label = internal_label_count[label] + augend;
499 p = symbol_name_build;
500 #ifdef LOCAL_LABEL_PREFIX
501 *p++ = LOCAL_LABEL_PREFIX;
504 for (; label; label /= 10)
505 *p++ = label % 10 + '0';
506 /* Make sure internal label never belong to normal label namespace. */
508 for (; want_label; want_label /= 10)
509 *p++ = want_label % 10 + '0';
511 return symbol_name_build;
515 setup_internal_label_here (unsigned long label)
517 assert (label < INTERNAL_LABEL_SPECIAL);
518 internal_label_count[label]++;
519 colon (loongarch_internal_label_name (label, 0));
523 get_internal_label (expressionS *label_expr, unsigned long label,
524 int augend /* 0 for previous, 1 for next. */)
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;
535 is_internal_label (const char *c_str)
542 if (!('0' <= *c_str && *c_str <= '9'))
544 while ('0' <= *c_str && *c_str <= '9')
546 if (*c_str != 'b' && *c_str != 'f')
549 return *c_str == '\0';
556 is_label (const char *c_str)
558 if (is_internal_label (c_str))
560 else if ('0' <= *c_str && *c_str <= '9')
563 while ('0' <= *c_str && *c_str <= '9')
565 return *c_str == 'b' || *c_str == 'f';
567 else if (is_name_beginner (*c_str))
569 /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */
571 while (is_part_of_name (*c_str))
573 return *c_str == '\0';
580 is_label_with_addend (const char *c_str)
582 if (is_internal_label (c_str))
584 else if ('0' <= *c_str && *c_str <= '9')
587 while ('0' <= *c_str && *c_str <= '9')
589 if (*c_str == 'b' || *c_str == 'f')
593 return *c_str == '\0'
594 || ((*c_str == '-' || *c_str == '+')
595 && is_unsigned (c_str + 1));
597 else if (is_name_beginner (*c_str))
599 /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */
601 while (is_part_of_name (*c_str))
603 return *c_str == '\0'
604 || ((*c_str == '-' || *c_str == '+')
605 && is_unsigned (c_str + 1));
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)
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;
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."));
635 ip->match_now = is_label_with_addend (arg);
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. */
644 ip->match_now = loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
645 reloc_num_we_have, &reloc_num, &imm) == 0;
650 bfd_reloc_code_real_type tls_reloc_type = BFD_RELOC_LARCH_TLS_LE_ADD_R;
653 && (ip->reloc_info[ip->reloc_num].type == tls_reloc_type))
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;
666 loongarch_parse_expr (arg, ip->reloc_info + ip->reloc_num,
667 reloc_num_we_have, &reloc_num, &imm) == 0;
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. */);
681 if (strncmp (bit_field, "10:12", strlen ("10:12")) == 0)
682 reloc_type = BFD_RELOC_LARCH_SOP_POP_32_U_10_12;
684 else if (esc_ch1 == 's')
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;
703 if (reloc_type == BFD_RELOC_NONE)
705 _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
706 esc_ch1, esc_ch2, bit_field, arg);
708 if (ip->reloc_info[0].type >= BFD_RELOC_LARCH_B16
709 && ip->reloc_info[0].type <= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2)
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;
718 && (BFD_RELOC_LARCH_TLS_LE_HI20_R == reloc_type
719 || BFD_RELOC_LARCH_TLS_LE_LO12_R == reloc_type))
721 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
722 ip->reloc_info[ip->reloc_num].value = const_0;
726 /* Only one register macros (used in normal code model)
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))
746 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_RELAX;
747 ip->reloc_info[ip->reloc_num].value = const_0;
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;
759 imm = (intptr_t) str_hash_find (r_htab, arg);
760 ip->match_now = 0 < imm;
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;
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]);
778 imm = (intptr_t) str_hash_find (fc_htab, arg);
781 imm = (intptr_t) str_hash_find (fcn_htab, arg);
785 imm = (intptr_t) str_hash_find (f_htab, arg);
787 ip->match_now = 0 < imm;
789 if (ip->match_now && !ip->expand_from_macro)
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;
796 as_warn (_("register alias %s is deprecated, use %s instead"),
797 arg, f_abi_names[ret]);
803 imm = (intptr_t) str_hash_find (cr_htab, arg);
806 imm = (intptr_t) str_hash_find (c_htab, arg);
808 ip->match_now = 0 < imm;
812 imm = (intptr_t) str_hash_find (v_htab, arg);
813 ip->match_now = 0 < imm;
817 imm = (intptr_t) str_hash_find (x_htab, arg);
818 ip->match_now = 0 < imm;
822 ip->all_match = ip->match_now;
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;
829 as_fatal (_("unknown escape"));
834 /* Check imm overflow. */
835 int bit_width, bits_needed_s, bits_needed_u;
844 bit_width = loongarch_get_bit_field_width (bit_field, &t);
847 /* No specify bit width. */
851 if (t[0] == '<' && t[1] == '<')
853 int i = strtol (t += 2, &t, 10), j;
854 for (j = i; 0 < j; j--, imm >>= 1)
856 as_fatal (_("require imm low %d bit is 0."), i);
860 imm -= strtol (t, &t, 10);
862 bits_needed_s = loongarch_bits_imm_needed (imm, 1);
863 bits_needed_u = loongarch_bits_imm_needed (imm, 0);
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"
871 esc_ch1, esc_ch2, bit_field, arg);
877 ip->args[ip->arg_num] = ret;
884 get_loongarch_opcode (struct loongarch_cl_insn *insn)
886 const struct loongarch_opcode *it;
887 struct loongarch_ase *ase;
888 for (ase = loongarch_ASEs; ase->enabled; ase++)
890 if (!*ase->enabled || (ase->include && !*ase->include)
891 || (ase->exclude && *ase->exclude))
894 if (!ase->name_hash_entry)
896 ase->name_hash_entry = str_htab_create ();
897 for (it = ase->opcodes; it->name; it++)
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,
907 if ((it = str_hash_find (ase->name_hash_entry, insn->name)) == NULL)
917 insn->insn_bin = (loongarch_foreach_args
918 (it->format, insn->arg_strs,
919 loongarch_args_parser_can_match_arg_helper,
921 if (insn->all_match && !(it->include && !*it->include)
922 && !(it->exclude && *it->exclude))
924 insn->insn_bin |= it->match;
929 while (it->name && strcasecmp (it->name, insn->name) == 0);
934 check_this_insn_before_appending (struct loongarch_cl_insn *ip)
938 if (strncmp (ip->name, "la.abs", 6) == 0)
940 ip->reloc_info[ip->reloc_num].type = BFD_RELOC_LARCH_MARK_LA;
941 ip->reloc_info[ip->reloc_num].value = const_0;
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))
954 /* For AMO insn amswap.[wd], amadd.[wd], etc. */
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"));
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))
967 /* For bstr(ins|pick).[wd]. */
968 if (ip->args[2] < ip->args[3])
969 as_fatal (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
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"));
980 install_insn (const struct loongarch_cl_insn *insn)
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);
988 move_insn (struct loongarch_cl_insn *insn, fragS *frag, long where)
993 for (i = 0; i < insn->reloc_num; i++)
997 insn->fixp[i]->fx_frag = frag;
998 insn->fixp[i]->fx_where = where;
1001 install_insn (insn);
1004 /* Add INSN to the end of the output. */
1006 append_fixed_insn (struct loongarch_cl_insn *insn)
1008 /* Ensure the jirl is emitted to the same frag as the pcaddu18i. */
1009 if (BFD_RELOC_LARCH_CALL36 == insn->reloc_info[0].type)
1012 char *f = frag_more (insn->insn_length);
1013 move_insn (insn, frag_now, f - frag_now->fr_literal);
1016 /* Add instructions based on the worst-case scenario firstly. */
1018 append_relaxed_branch_insn (struct loongarch_cl_insn *insn, int max_chars,
1019 int var, relax_substateT subtype, symbolS *symbol, offsetT offset)
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);
1028 append_fixp_and_insn (struct loongarch_cl_insn *ip)
1030 reloc_howto_type *howto;
1031 bfd_reloc_code_real_type r_type;
1032 struct reloc_info *reloc_info = ip->reloc_info;
1035 dwarf2_emit_insn (0);
1037 for (i = 0; i < ip->reloc_num; i++)
1039 r_type = reloc_info[i].type;
1041 if (r_type != BFD_RELOC_UNUSED)
1044 gas_assert (&(reloc_info[i].value));
1045 if (BFD_RELOC_LARCH_B16 == r_type || BFD_RELOC_LARCH_B21 == r_type)
1047 int min_bytes = 4; /* One branch instruction. */
1048 unsigned max_bytes = 8; /* Branch and jump instructions. */
1050 if (now_seg == absolute_section)
1052 as_bad (_("relaxable branches not supported in absolute section"));
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);
1064 howto = bfd_reloc_type_lookup (stdoutput, r_type);
1066 as_fatal (_("no HOWTO loong relocation number %d"), r_type);
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);
1075 if (ip->insn_length < ip->relax_max_length)
1076 as_fatal (_("Internal error: not support relax now"));
1078 append_fixed_insn (ip);
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.
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)))
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))
1106 frag_wane (frag_now);
1111 /* Ask helper for returning a malloced c_str or NULL. */
1113 assember_macro_helper (const char *const args[], void *context_ptr)
1115 struct loongarch_cl_insn *insn = context_ptr;
1117 if ( strcmp (insn->name, "li.w") == 0 || strcmp (insn->name, "li.d") == 0)
1119 char args_buf[50], insns_buf[200];
1120 const char *arg_strs[6];
1121 uint32_t hi32, lo32;
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;
1128 lo32 = insn->args[1] & 0xffffffff;
1129 hi32 = insn->args[1] >> 32;
1131 if (strcmp (insn->name, "li.w") == 0)
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;
1138 if (strcmp (insn->name, "li.d") == 0 && !LARCH_opts.ase_lp64)
1139 as_fatal (_("we can't li.d on 32bit-arch"));
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);
1147 ((((hi32 & 0xfff00000) == 0) << 3) | (((hi32 & 0x000fffff) == 0) << 2)
1148 | (((lo32 & 0xfffff000) == 0) << 1) | ((lo32 & 0x00000fff) == 0));
1150 ((((hi32 & 0x80000000) != 0) << 3) | (((hi32 & 0x00080000) != 0) << 2)
1151 | (((lo32 & 0x80000000) != 0) << 1) | ((lo32 & 0x00000800) != 0));
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));
1160 static const char *const li_32bit[] =
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;",
1167 static const char *const li_hi_32bit[] =
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;",
1177 insns_buf[0] = '\0';
1178 if (paritial_is_sext_of_prev == 0x7)
1180 strcat (insns_buf, "lu52i.d %5,$r0,%1&0x800?%1-0x1000:%1;");
1183 if ((all0_bit_vec & 0x3) == 0x2)
1184 strcat (insns_buf, "ori %5,$r0,%4;");
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]);
1191 ret = loongarch_expand_macro (insns_buf, arg_strs, NULL, NULL,
1198 /* Accept instructions separated by ';'
1199 * assuming 'not starting with space and not ending with space' or pass in
1202 loongarch_assemble_INSNs (char *str, unsigned int expand_from_macro)
1205 size_t len_str = strlen(str);
1207 for (rest = str; *rest != ';' && *rest != '\0'; rest++);
1214 setup_internal_label_here (strtol (str, &str, 10));
1223 struct loongarch_cl_insn the_one = { 0 };
1225 the_one.expand_from_macro = expand_from_macro;
1227 for (; *str && *str != ' '; str++)
1232 loongarch_split_args_by_comma (str, the_one.arg_strs);
1233 get_loongarch_opcode (&the_one);
1235 if (!the_one.all_match)
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 : "");
1243 if (check_this_insn_before_appending (&the_one) != 0)
1246 append_fixp_and_insn (&the_one);
1248 /* Expanding macro instructions. */
1249 if (the_one.insn_length == 0 && the_one.insn->macro)
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;
1257 char *c_str = loongarch_expand_macro (the_one.insn->macro,
1259 assember_macro_helper,
1261 /* The first instruction expanded from macro. */
1262 loongarch_assemble_INSNs (c_str, new_expand_from_macro);
1268 /* The rest instructions expanded from macro, split by semicolon(;),
1269 assembly one by one. */
1271 loongarch_assemble_INSNs (rest, expand_from_macro);
1275 md_assemble (char *str)
1277 loongarch_assemble_INSNs (str, 0);
1281 md_atof (int type, char *litP, int *sizeP)
1283 return ieee_md_atof (type, litP, sizeP, FALSE);
1287 md_number_to_chars (char *buf, valueT val, int n)
1289 number_to_chars_littleendian (buf, val, n);
1292 /* The location from which a PC relative jump should be calculated,
1293 given a PC relative reloc. */
1295 md_pcrel_from (fixS *fixP ATTRIBUTE_UNUSED)
1300 static void fix_reloc_insn (fixS *fixP, bfd_vma reloc_val, char *buf)
1302 reloc_howto_type *howto;
1304 howto = bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type);
1306 insn = bfd_getl32 (buf);
1308 if (!loongarch_adjust_reloc_bitsfield (NULL, howto, &reloc_val))
1309 as_bad_where (fixP->fx_file, fixP->fx_line, "Reloc overflow");
1311 insn = (insn & (insn_t)howto->src_mask)
1312 | ((insn & (~(insn_t)howto->dst_mask)) | reloc_val);
1314 bfd_putl32 (insn, buf);
1318 md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
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;
1324 last_reloc_is_sop_push_pcrel_1 = 0;
1326 char *buf = fixP->fx_frag->fr_literal + fixP->fx_where;
1327 switch (fixP->fx_r_type)
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);
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"));
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));
1376 case BFD_RELOC_LARCH_TLS_DESC_LD:
1377 case BFD_RELOC_LARCH_TLS_DESC_CALL:
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)
1392 fix_reloc_insn (fixP, (bfd_vma)stack_top, buf);
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
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)). */
1415 switch (fixP->fx_r_type)
1418 fixP->fx_r_type = BFD_RELOC_LARCH_64_PCREL;
1421 fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
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
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)
1440 fixP->fx_r_type = BFD_RELOC_LARCH_32_PCREL;
1441 fixP->fx_subsy = NULL;
1445 if (fixP->fx_addsy && fixP->fx_subsy)
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;
1453 switch (fixP->fx_r_type)
1456 fixP->fx_r_type = BFD_RELOC_LARCH_ADD64;
1457 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB64;
1460 fixP->fx_r_type = BFD_RELOC_LARCH_ADD32;
1461 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB32;
1467 md_number_to_chars (buf, 0, fixP->fx_size);
1470 if (fixP->fx_addsy == NULL)
1473 md_number_to_chars (buf, *valP, fixP->fx_size);
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;
1488 switch (fixP->fx_r_type)
1491 fixP->fx_r_type = BFD_RELOC_LARCH_ADD24;
1492 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB24;
1495 fixP->fx_r_type = BFD_RELOC_LARCH_ADD16;
1496 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB16;
1499 fixP->fx_r_type = BFD_RELOC_LARCH_ADD8;
1500 fixP->fx_next->fx_r_type = BFD_RELOC_LARCH_SUB8;
1506 md_number_to_chars (buf, 0, fixP->fx_size);
1508 if (fixP->fx_next->fx_addsy == NULL)
1509 fixP->fx_next->fx_done = 1;
1512 if (fixP->fx_addsy == NULL)
1515 md_number_to_chars (buf, *valP, fixP->fx_size);
1519 case BFD_RELOC_LARCH_CFA:
1520 if (fixP->fx_addsy && fixP->fx_subsy)
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;
1528 unsigned int subtype;
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);
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);
1543 case DW_CFA_advance_loc2:
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);
1553 case DW_CFA_advance_loc4:
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);
1564 if (subtype < 0x80 && (subtype & 0x40))
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);
1574 as_fatal (_("internal: bad CFA value #%d"), subtype);
1580 case BFD_RELOC_LARCH_B16:
1581 case BFD_RELOC_LARCH_B21:
1582 case BFD_RELOC_LARCH_B26:
1583 if (fixP->fx_addsy == NULL)
1585 as_bad_where (fixP->fx_file, fixP->fx_line,
1586 _ ("Relocation against a constant."));
1588 if (S_GET_SEGMENT (fixP->fx_addsy) == seg
1589 && !S_FORCE_RELOC (fixP->fx_addsy, 1))
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);
1595 /* If relax, symbol value may change at link time, so reloc need to
1597 if (!LARCH_opts.relax)
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:
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);
1622 md_estimate_size_before_relax (fragS *fragp ATTRIBUTE_UNUSED,
1623 asection *segtype ATTRIBUTE_UNUSED)
1625 return (fragp->fr_var = 4);
1628 /* Translate internal representation of relocation info to BFD target
1631 tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
1633 arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
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;
1640 reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
1641 if (reloc->howto == NULL)
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));
1652 /* Standard calling conventions leave the CFA at SP on entry. */
1654 loongarch_cfi_frame_initial_instructions (void)
1656 cfi_add_CFA_def_cfa_register (3 /* $sp */);
1660 loongarch_pre_output_hook (void)
1662 const frchainS *frch;
1665 if (!LARCH_opts.relax)
1668 /* Save the current segment info. */
1670 subsegT subseg = now_subseg;
1672 for (s = stdoutput->sections; s; s = s->next)
1673 for (frch = seg_info (s)->frchainP; frch; frch = frch->frch_next)
1677 for (frag = frch->frch_root; frag; frag = frag->fr_next)
1679 if (frag->fr_type == rs_cfa)
1682 expressionS *symval;
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;
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);
1694 fix_new_exp (frag, (int) frag->fr_offset, 1, &exp, 0,
1695 BFD_RELOC_LARCH_CFA);
1700 /* Restore the original segment info. */
1701 subseg_set (seg, subseg);
1705 tc_loongarch_parse_to_dw2regnum (expressionS *exp)
1707 expression_and_evaluate (exp);
1711 md_show_usage (FILE *stream)
1713 fprintf (stream, _("LARCH options:\n"));
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"));
1723 loongarch_make_nops (char *buf, bfd_vma bytes)
1727 /* Fill with 4-byte NOPs. */
1728 for ( ; i < bytes; i += 4)
1729 number_to_chars_littleendian (buf + i, LARCH_NOP, 4);
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. */
1738 loongarch_frag_align_code (int n, int max)
1744 bfd_vma insn_alignment = 4;
1745 bfd_vma bytes = (bfd_vma) 1 << n;
1746 bfd_vma worst_case_bytes = bytes - insn_alignment;
1748 /* If we are moving to a smaller alignment than the instruction size, then no
1749 alignment is required. */
1750 if (bytes <= insn_alignment)
1753 /* When not relaxing, loongarch_handle_align handles code alignment. */
1754 if (!LARCH_opts.relax)
1757 nops = frag_more (worst_case_bytes);
1759 s = symbol_find (".Lla-relax-align");
1761 s = (symbolS *)local_symbol_make (".Lla-relax-align", now_seg,
1762 &zero_address_frag, 0);
1764 ex.X_add_symbol = s;
1766 ex.X_add_number = (max << 8) | n;
1768 loongarch_make_nops (nops, worst_case_bytes);
1770 fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
1771 &ex, false, BFD_RELOC_LARCH_ALIGN);
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);
1782 /* Fill in an rs_align_code fragment. We want to fill 'andi $r0,$r0,0'. */
1784 loongarch_handle_align (fragS *fragp)
1786 /* char nop_opcode; */
1788 int bytes, size, excess;
1791 if (fragp->fr_type != rs_align_code)
1794 struct loongarch_cl_insn nop =
1795 { .name = "andi", .arg_strs = { "$r0", "$r0", "0", NULL } };
1797 get_loongarch_opcode (&nop);
1798 gas_assert (nop.all_match);
1800 p = fragp->fr_literal + fragp->fr_fix;
1801 opcode = nop.insn_bin;
1804 bytes = fragp->fr_next->fr_address - fragp->fr_address - fragp->fr_fix;
1805 excess = bytes % size;
1807 gas_assert (excess < 4);
1808 fragp->fr_fix += excess;
1810 while (excess-- != 0)
1813 md_number_to_chars (p, opcode, size);
1814 fragp->fr_var = size;
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. */
1823 loongarch_insert_uleb128_fixes (bfd *abfd ATTRIBUTE_UNUSED,
1824 asection *sec, void *xxx ATTRIBUTE_UNUSED)
1826 segment_info_type *seginfo = seg_info (sec);
1829 subseg_set (sec, 0);
1831 for (fragP = seginfo->frchainP->frch_root;
1832 fragP; fragP = fragP->fr_next)
1834 expressionS *exp, *exp_dup;
1836 if (fragP->fr_type != rs_leb128 || fragP->fr_symbol == NULL)
1839 exp = symbol_get_value_expression (fragP->fr_symbol);
1841 if (exp->X_op != O_subtract)
1844 /* FIXME: Skip for .sleb128. */
1845 if (fragP->fr_subtype != 0)
1848 exp_dup = xmemdup (exp, sizeof (*exp), sizeof (*exp));
1849 exp_dup->X_op = O_symbol;
1850 exp_dup->X_op_symbol = NULL;
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);
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. */
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);
1872 loongarch_md_finish (void)
1874 /* Insert relocations for uleb128 directives, so the values can be recomputed
1876 if (LARCH_opts.relax)
1877 bfd_map_over_sections (stdoutput, loongarch_insert_uleb128_fixes, NULL);
1881 loongarch_elf_final_processing (void)
1883 elf_elfheader (stdoutput)->e_flags = LARCH_opts.ase_abi;
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. */
1889 loongarch_relaxed_branch_length (fragS *fragp, asection *sec, int update)
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))
1901 offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
1903 val -= fragp->fr_address + fragp->fr_fix;
1905 if (RELAX_BRANCH_16 == fragp->fr_subtype
1906 && OUT_OF_RANGE (val, 16, 2))
1910 fragp->fr_subtype = RELAX_BRANCH_26;
1913 if (RELAX_BRANCH_21 == fragp->fr_subtype
1914 && OUT_OF_RANGE (val, 21, 2))
1918 fragp->fr_subtype = RELAX_BRANCH_26;
1921 if (RELAX_BRANCH_26 == fragp->fr_subtype)
1929 loongarch_relax_frag (asection *sec ATTRIBUTE_UNUSED,
1930 fragS *fragp ATTRIBUTE_UNUSED,
1931 long stretch ATTRIBUTE_UNUSED)
1933 if (RELAX_BRANCH (fragp->fr_subtype))
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;
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. */
1949 loongarch_convert_frag_branch (fragS *fragp)
1956 buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
1958 exp.X_op = O_symbol;
1959 exp.X_add_symbol = fragp->fr_symbol;
1960 exp.X_add_number = fragp->fr_offset;
1962 gas_assert ((fragp->fr_subtype & 0xf) == fragp->fr_var);
1964 /* blt $t0, $t1, .L1
1971 switch (fragp->fr_subtype)
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;
1979 insn ^= LARCH_BRANCH_INVERT_BIT;
1980 insn |= ENCODE_BRANCH16_IMM (8); /* Set target to PC + 8. */
1981 bfd_putl32 (insn, buf);
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);
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);
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);
2005 fixp->fx_file = fragp->fr_file;
2006 fixp->fx_line = fragp->fr_line;
2008 gas_assert (buf == (bfd_byte *)fragp->fr_literal
2009 + fragp->fr_fix + fragp->fr_var);
2011 fragp->fr_fix += fragp->fr_var;
2014 /* Relax a machine dependent frag. This returns the amount by which
2015 the current size of the frag should change. */
2018 md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
2021 gas_assert (RELAX_BRANCH (fragp->fr_subtype));
2022 loongarch_convert_frag_branch (fragp);