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 static bool call36
= 0;
121 /* The lowest 4-bit is the bytes of instructions. */
122 #define RELAX_BRANCH_16 0xc0000014
123 #define RELAX_BRANCH_21 0xc0000024
124 #define RELAX_BRANCH_26 0xc0000048
126 #define RELAX_BRANCH(x) \
127 (((x) & 0xf0000000) == 0xc0000000)
128 #define RELAX_BRANCH_ENCODE(x) \
129 (BFD_RELOC_LARCH_B16 == (x) ? RELAX_BRANCH_16 : RELAX_BRANCH_21)
131 #define ALIGN_MAX_ADDEND(n, max) ((max << 8) | n)
132 #define ALIGN_MAX_NOP_BYTES(addend) ((1 << (addend & 0xff)) - 4)
133 #define FRAG_AT_START_OF_SECTION(frag) \
134 (0 == frag->fr_address && 0 == frag->fr_fix)
138 OPTION_IGNORE
= OPTION_MD_BASE
,
144 OPTION_LA_LOCAL_WITH_ABS
,
145 OPTION_LA_GLOBAL_WITH_PCREL
,
146 OPTION_LA_GLOBAL_WITH_ABS
,
152 OPTION_IGNORE_START_ALIGN
,
157 struct option md_longopts
[] =
159 { "mabi", required_argument
, NULL
, OPTION_ABI
},
161 { "mfpu", required_argument
, NULL
, OPTION_FLOAT_ISA
},
163 { "mla-local-with-abs", no_argument
, NULL
, OPTION_LA_LOCAL_WITH_ABS
},
164 { "mla-global-with-pcrel", no_argument
, NULL
, OPTION_LA_GLOBAL_WITH_PCREL
},
165 { "mla-global-with-abs", no_argument
, NULL
, OPTION_LA_GLOBAL_WITH_ABS
},
167 { "mrelax", no_argument
, NULL
, OPTION_RELAX
},
168 { "mno-relax", no_argument
, NULL
, OPTION_NO_RELAX
},
169 { "mthin-add-sub", no_argument
, NULL
, OPTION_THIN_ADD_SUB
},
170 { "mignore-start-align", no_argument
, NULL
, OPTION_IGNORE_START_ALIGN
},
172 { NULL
, no_argument
, NULL
, 0 }
175 size_t md_longopts_size
= sizeof (md_longopts
);
178 md_parse_option (int c
, const char *arg
)
182 char ilp32
[256] = "";
183 unsigned char *suf
= (unsigned char *)arg
;
185 lp64
['s'] = lp64
['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT
;
186 lp64
['f'] = lp64
['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT
;
187 lp64
['d'] = lp64
['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT
;
189 ilp32
['s'] = ilp32
['S'] = EF_LOONGARCH_ABI_SOFT_FLOAT
;
190 ilp32
['f'] = ilp32
['F'] = EF_LOONGARCH_ABI_SINGLE_FLOAT
;
191 ilp32
['d'] = ilp32
['D'] = EF_LOONGARCH_ABI_DOUBLE_FLOAT
;
196 if (strncasecmp (arg
, "lp64", 4) == 0 && lp64
[suf
[4]] != 0)
198 LARCH_opts
.ase_ilp32
= 1;
199 LARCH_opts
.ase_lp64
= 1;
200 LARCH_opts
.ase_lsx
= 1;
201 LARCH_opts
.ase_lasx
= 1;
202 LARCH_opts
.ase_lvz
= 1;
203 LARCH_opts
.ase_lbt
= 1;
204 LARCH_opts
.ase_abi
= lp64
[suf
[4]];
206 else if (strncasecmp (arg
, "ilp32", 5) == 0 && ilp32
[suf
[5]] != 0)
208 LARCH_opts
.ase_abi
= ilp32
[suf
[5]];
209 LARCH_opts
.ase_ilp32
= 1;
215 case OPTION_FLOAT_ISA
:
216 if (strcasecmp (arg
, "soft") == 0)
217 LARCH_opts
.ase_nf
= 1;
218 else if (strcasecmp (arg
, "single") == 0)
219 LARCH_opts
.ase_sf
= 1;
220 else if (strcasecmp (arg
, "double") == 0)
222 LARCH_opts
.ase_sf
= 1;
223 LARCH_opts
.ase_df
= 1;
229 case OPTION_LA_LOCAL_WITH_ABS
:
230 LARCH_opts
.ase_labs
= 1;
233 case OPTION_LA_GLOBAL_WITH_PCREL
:
234 LARCH_opts
.ase_gpcr
= 1;
237 case OPTION_LA_GLOBAL_WITH_ABS
:
238 LARCH_opts
.ase_gabs
= 1;
242 LARCH_opts
.relax
= 1;
245 case OPTION_NO_RELAX
:
246 LARCH_opts
.relax
= 0;
249 case OPTION_THIN_ADD_SUB
:
250 LARCH_opts
.thin_add_sub
= 1;
253 case OPTION_IGNORE_START_ALIGN
:
254 LARCH_opts
.ignore_start_align
= 1;
267 static const char *const *r_abi_names
= NULL
;
268 static const char *const *f_abi_names
= NULL
;
269 static struct htab
*r_htab
= NULL
;
270 static struct htab
*r_deprecated_htab
= NULL
;
271 static struct htab
*f_htab
= NULL
;
272 static struct htab
*f_deprecated_htab
= NULL
;
273 static struct htab
*fc_htab
= NULL
;
274 static struct htab
*fcn_htab
= NULL
;
275 static struct htab
*c_htab
= NULL
;
276 static struct htab
*cr_htab
= NULL
;
277 static struct htab
*v_htab
= NULL
;
278 static struct htab
*x_htab
= NULL
;
281 loongarch_after_parse_args ()
283 /* Set default ABI/ISA LP64D. */
284 if (!LARCH_opts
.ase_ilp32
)
286 if (strcmp (default_arch
, "loongarch64") == 0)
288 LARCH_opts
.ase_abi
= EF_LOONGARCH_ABI_DOUBLE_FLOAT
;
289 LARCH_opts
.ase_ilp32
= 1;
290 LARCH_opts
.ase_lp64
= 1;
291 LARCH_opts
.ase_lsx
= 1;
292 LARCH_opts
.ase_lasx
= 1;
293 LARCH_opts
.ase_lvz
= 1;
294 LARCH_opts
.ase_lbt
= 1;
296 else if (strcmp (default_arch
, "loongarch32") == 0)
298 LARCH_opts
.ase_abi
= EF_LOONGARCH_ABI_DOUBLE_FLOAT
;
299 LARCH_opts
.ase_ilp32
= 1;
302 as_bad ("unknown default architecture `%s'", default_arch
);
305 LARCH_opts
.ase_abi
|= EF_LOONGARCH_OBJABI_V1
;
306 /* Set default ISA double-float. */
307 if (!LARCH_opts
.ase_nf
308 && !LARCH_opts
.ase_sf
309 && !LARCH_opts
.ase_df
)
311 LARCH_opts
.ase_sf
= 1;
312 LARCH_opts
.ase_df
= 1;
317 assert(LARCH_opts
.ase_ilp32
);
319 /* Init ilp32/lp64 registers names. */
321 r_htab
= str_htab_create (), str_hash_insert (r_htab
, "", 0, 0);
322 if (!r_deprecated_htab
)
323 r_deprecated_htab
= str_htab_create (),
324 str_hash_insert (r_deprecated_htab
, "", 0, 0);
326 r_abi_names
= loongarch_r_normal_name
;
327 for (i
= 0; i
< ARRAY_SIZE (loongarch_r_normal_name
); i
++)
328 str_hash_insert (r_htab
, loongarch_r_normal_name
[i
], (void *) (i
+ 1), 0);
330 /* Init ilp32/lp64 registers alias. */
331 r_abi_names
= loongarch_r_alias
;
332 for (i
= 0; i
< ARRAY_SIZE (loongarch_r_alias
); i
++)
333 str_hash_insert (r_htab
, loongarch_r_alias
[i
], (void *) (i
+ 1), 0);
335 for (i
= 0; i
< ARRAY_SIZE (loongarch_r_alias_1
); i
++)
336 str_hash_insert (r_htab
, loongarch_r_alias_1
[i
], (void *) (i
+ 1), 0);
338 for (i
= 0; i
< ARRAY_SIZE (loongarch_r_alias_deprecated
); i
++)
339 str_hash_insert (r_deprecated_htab
, loongarch_r_alias_deprecated
[i
],
340 (void *) (i
+ 1), 0);
343 cr_htab
= str_htab_create (), str_hash_insert (cr_htab
, "", 0, 0);
345 for (i
= 0; i
< ARRAY_SIZE (loongarch_cr_normal_name
); i
++)
346 str_hash_insert (cr_htab
, loongarch_cr_normal_name
[i
], (void *) (i
+ 1), 0);
348 /* Init single/double float registers names. */
349 if (LARCH_opts
.ase_sf
|| LARCH_opts
.ase_df
)
352 f_htab
= str_htab_create (), str_hash_insert (f_htab
, "", 0, 0);
353 if (!f_deprecated_htab
)
354 f_deprecated_htab
= str_htab_create (),
355 str_hash_insert (f_deprecated_htab
, "", 0, 0);
357 f_abi_names
= loongarch_f_normal_name
;
358 for (i
= 0; i
< ARRAY_SIZE (loongarch_f_normal_name
); i
++)
359 str_hash_insert (f_htab
, loongarch_f_normal_name
[i
], (void *) (i
+ 1),
362 /* Init float-ilp32/lp64 registers alias. */
363 f_abi_names
= loongarch_f_alias
;
364 for (i
= 0; i
< ARRAY_SIZE (loongarch_f_alias
); i
++)
365 str_hash_insert (f_htab
, loongarch_f_alias
[i
],
366 (void *) (i
+ 1), 0);
367 for (i
= 0; i
< ARRAY_SIZE (loongarch_f_alias_deprecated
); i
++)
368 str_hash_insert (f_deprecated_htab
, loongarch_f_alias_deprecated
[i
],
369 (void *) (i
+ 1), 0);
372 fc_htab
= str_htab_create (), str_hash_insert (fc_htab
, "", 0, 0);
374 for (i
= 0; i
< ARRAY_SIZE (loongarch_fc_normal_name
); i
++)
375 str_hash_insert (fc_htab
, loongarch_fc_normal_name
[i
], (void *) (i
+ 1),
379 fcn_htab
= str_htab_create (), str_hash_insert (fcn_htab
, "", 0, 0);
381 for (i
= 0; i
< ARRAY_SIZE (loongarch_fc_numeric_name
); i
++)
382 str_hash_insert (fcn_htab
, loongarch_fc_numeric_name
[i
], (void *) (i
+ 1),
386 c_htab
= str_htab_create (), str_hash_insert (c_htab
, "", 0, 0);
388 for (i
= 0; i
< ARRAY_SIZE (loongarch_c_normal_name
); i
++)
389 str_hash_insert (c_htab
, loongarch_c_normal_name
[i
], (void *) (i
+ 1),
394 /* Init lsx registers names. */
395 if (LARCH_opts
.ase_lsx
)
398 v_htab
= str_htab_create (), str_hash_insert (v_htab
, "", 0, 0);
399 for (i
= 0; i
< ARRAY_SIZE (loongarch_v_normal_name
); i
++)
400 str_hash_insert (v_htab
, loongarch_v_normal_name
[i
], (void *) (i
+ 1),
404 /* Init lasx registers names. */
405 if (LARCH_opts
.ase_lasx
)
408 x_htab
= str_htab_create (), str_hash_insert (x_htab
, "", 0, 0);
409 for (i
= 0; i
< ARRAY_SIZE (loongarch_x_normal_name
); i
++)
410 str_hash_insert (x_htab
, loongarch_x_normal_name
[i
], (void *) (i
+ 1),
417 loongarch_target_format ()
419 return LARCH_opts
.ase_lp64
? "elf64-loongarch" : "elf32-loongarch";
428 static htab_t align_hash
;
431 align_sec_sym_hash (const void *entry
)
433 const align_sec_sym
*e
= entry
;
434 return (hashval_t
) (e
->sec_id
);
438 align_sec_sym_eq (const void *entry1
, const void *entry2
)
440 const align_sec_sym
*e1
= entry1
, *e2
= entry2
;
441 return e1
->sec_id
== e2
->sec_id
;
444 /* Make align symbol be in same section with alignment directive.
445 If the symbol is only created at the first time to handle alignment
446 directive. This means that all other sections may use this symbol.
447 If the section of this symbol is discarded, there may be problems. */
449 static symbolS
*get_align_symbol (segT sec
)
451 align_sec_sym search
= { sec
->id
, NULL
};
452 align_sec_sym
*pentry
= htab_find (align_hash
, &search
);
456 /* If we not find the symbol in this section. Create and insert it. */
457 symbolS
*s
= (symbolS
*)local_symbol_make (".Lla-relax-align", sec
,
458 &zero_address_frag
, 0);
459 align_sec_sym entry
= { sec
->id
, s
};
460 align_sec_sym
**slot
= (align_sec_sym
**) htab_find_slot (align_hash
,
464 *slot
= (align_sec_sym
*) xmalloc (sizeof (align_sec_sym
));
474 const struct loongarch_opcode
*it
;
475 struct loongarch_ase
*ase
;
476 for (ase
= loongarch_ASEs
; ase
->enabled
; ase
++)
477 for (it
= ase
->opcodes
; it
->name
; it
++)
479 if (loongarch_check_format (it
->format
) != 0)
480 as_fatal (_("insn name: %s\tformat: %s\tsyntax error"),
481 it
->name
, it
->format
);
482 if (it
->mask
== 0 && it
->macro
== 0)
483 as_fatal (_("insn name: %s\nformat: %s\nwe want macro but "
485 it
->name
, it
->format
);
487 && loongarch_check_macro (it
->format
, it
->macro
) != 0)
488 as_fatal (_("insn name: %s\nformat: %s\nmacro: %s\tsyntax error"),
489 it
->name
, it
->format
, it
->macro
);
492 align_hash
= htab_create (10, align_sec_sym_hash
, align_sec_sym_eq
, free
);
494 /* FIXME: expressionS use 'offsetT' as constant,
495 * we want this is 64-bit type. */
496 assert (8 <= sizeof (offsetT
));
499 /* Called just before the assembler exits. */
502 loongarch_md_end (void)
504 htab_delete (align_hash
);
508 loongarch_mach (void)
510 return LARCH_opts
.ase_lp64
? bfd_mach_loongarch64
: bfd_mach_loongarch32
;
513 static const expressionS const_0
= { .X_op
= O_constant
, .X_add_number
= 0 };
515 /* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
516 a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
517 use in DWARF debug information. */
527 if (ex
.X_op
!= O_symbol
)
529 as_bad (_("Unsupported use of %s"),
530 (bytes
== 8 ? ".dtpreldword" : ".dtprelword"));
531 ignore_rest_of_line ();
534 p
= frag_more (bytes
);
535 md_number_to_chars (p
, 0, bytes
);
536 fix_new_exp (frag_now
, p
- frag_now
->fr_literal
, bytes
, &ex
, FALSE
,
538 ? BFD_RELOC_LARCH_TLS_DTPREL64
539 : BFD_RELOC_LARCH_TLS_DTPREL32
));
541 demand_empty_rest_of_line ();
544 struct LARCH_option_stack
546 struct LARCH_option_stack
*next
;
547 struct loongarch_ASEs_option options
;
550 static struct LARCH_option_stack
*LARCH_opts_stack
= NULL
;
552 /* Handle the .option pseudo-op.
553 The alignment of .align is done by R_LARCH_ALIGN at link time.
554 If the .align directive is within the range controlled by
555 .option norelax, that is, relax is turned off, R_LARCH_ALIGN
556 cannot be generated, which may cause ld to be unable to handle
559 s_loongarch_option (int x ATTRIBUTE_UNUSED
)
561 char *name
= input_line_pointer
, ch
;
562 while (!is_end_of_line
[(unsigned char) *input_line_pointer
])
563 ++input_line_pointer
;
564 ch
= *input_line_pointer
;
565 *input_line_pointer
= '\0';
567 if (strcmp (name
, "relax") == 0)
568 LARCH_opts
.relax
= 1;
569 else if (strcmp (name
, "norelax") == 0)
570 LARCH_opts
.relax
= 0;
571 else if (strcmp (name
, "push") == 0)
573 struct LARCH_option_stack
*s
;
575 s
= XNEW (struct LARCH_option_stack
);
576 s
->next
= LARCH_opts_stack
;
577 s
->options
= LARCH_opts
;
578 LARCH_opts_stack
= s
;
580 else if (strcmp (name
, "pop") == 0)
582 struct LARCH_option_stack
*s
;
584 s
= LARCH_opts_stack
;
586 as_bad (_(".option pop with no .option push"));
589 LARCH_opts_stack
= s
->next
;
590 LARCH_opts
= s
->options
;
596 as_warn (_("unrecognized .option directive: %s"), name
);
598 *input_line_pointer
= ch
;
599 demand_empty_rest_of_line ();
602 static const pseudo_typeS loongarch_pseudo_table
[] =
604 { "dword", cons
, 8 },
607 { "dtprelword", s_dtprel
, 4 },
608 { "dtpreldword", s_dtprel
, 8 },
609 { "option", s_loongarch_option
, 0},
614 loongarch_pop_insert (void)
616 pop_insert (loongarch_pseudo_table
);
619 #define INTERNAL_LABEL_SPECIAL 10
620 static unsigned long internal_label_count
[INTERNAL_LABEL_SPECIAL
] = { 0 };
623 loongarch_internal_label_name (unsigned long label
, int augend
)
625 static char symbol_name_build
[24];
626 unsigned long want_label
;
629 want_label
= internal_label_count
[label
] + augend
;
631 p
= symbol_name_build
;
632 #ifdef LOCAL_LABEL_PREFIX
633 *p
++ = LOCAL_LABEL_PREFIX
;
636 for (; label
; label
/= 10)
637 *p
++ = label
% 10 + '0';
638 /* Make sure internal label never belong to normal label namespace. */
640 for (; want_label
; want_label
/= 10)
641 *p
++ = want_label
% 10 + '0';
643 return symbol_name_build
;
647 setup_internal_label_here (unsigned long label
)
649 assert (label
< INTERNAL_LABEL_SPECIAL
);
650 internal_label_count
[label
]++;
651 colon (loongarch_internal_label_name (label
, 0));
655 get_internal_label (expressionS
*label_expr
, unsigned long label
,
656 int augend
/* 0 for previous, 1 for next. */)
658 assert (label
< INTERNAL_LABEL_SPECIAL
);
659 as_fatal (_("internal error: we have no internal label yet"));
660 label_expr
->X_op
= O_symbol
;
661 label_expr
->X_add_symbol
=
662 symbol_find_or_make (loongarch_internal_label_name (label
, augend
));
663 label_expr
->X_add_number
= 0;
667 is_internal_label (const char *c_str
)
674 if (!('0' <= *c_str
&& *c_str
<= '9'))
676 while ('0' <= *c_str
&& *c_str
<= '9')
678 if (*c_str
!= 'b' && *c_str
!= 'f')
681 return *c_str
== '\0';
688 is_label (const char *c_str
)
690 if (is_internal_label (c_str
))
692 else if ('0' <= *c_str
&& *c_str
<= '9')
695 while ('0' <= *c_str
&& *c_str
<= '9')
697 return *c_str
== 'b' || *c_str
== 'f';
699 else if (is_name_beginner (*c_str
))
701 /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */
703 while (is_part_of_name (*c_str
))
705 return *c_str
== '\0';
712 is_label_with_addend (const char *c_str
)
714 if (is_internal_label (c_str
))
716 else if ('0' <= *c_str
&& *c_str
<= '9')
719 while ('0' <= *c_str
&& *c_str
<= '9')
721 if (*c_str
== 'b' || *c_str
== 'f')
725 return *c_str
== '\0'
726 || ((*c_str
== '-' || *c_str
== '+')
727 && is_unsigned (c_str
+ 1));
729 else if (is_name_beginner (*c_str
))
731 /* [a-zA-Z\._\$][0-9a-zA-Z\._\$]* */
733 while (is_part_of_name (*c_str
))
735 return *c_str
== '\0'
736 || ((*c_str
== '-' || *c_str
== '+')
737 && is_unsigned (c_str
+ 1));
744 loongarch_args_parser_can_match_arg_helper (char esc_ch1
, char esc_ch2
,
745 const char *bit_field
,
746 const char *arg
, void *context
)
748 struct loongarch_cl_insn
*ip
= context
;
749 offsetT imm
, ret
= 0;
750 size_t reloc_num_we_have
= MAX_RELOC_NUMBER_A_INSN
- ip
->reloc_num
;
751 size_t reloc_num
= 0;
762 ip
->match_now
= is_label (arg
);
763 if (!ip
->match_now
&& is_label_with_addend (arg
))
764 as_fatal (_("This label shouldn't be with addend."));
767 ip
->match_now
= is_label_with_addend (arg
);
771 /* This is used for TLS, where the fourth operand is %le_add_r,
772 to get a relocation applied to an add instruction, for relaxation to use.
773 Two conditions, ip->match_now and reloc_num, are used to check tls insn
774 to prevent cases like add.d $a0,$a0,$a0,8. */
776 ip
->match_now
= loongarch_parse_expr (arg
, ip
->reloc_info
+ ip
->reloc_num
,
777 reloc_num_we_have
, &reloc_num
, &imm
) == 0;
782 bfd_reloc_code_real_type tls_reloc_type
= BFD_RELOC_LARCH_TLS_LE_ADD_R
;
785 && (ip
->reloc_info
[ip
->reloc_num
].type
== tls_reloc_type
))
787 ip
->reloc_num
+= reloc_num
;
788 ip
->reloc_info
[ip
->reloc_num
].type
= BFD_RELOC_LARCH_RELAX
;
789 ip
->reloc_info
[ip
->reloc_num
].value
= const_0
;
798 loongarch_parse_expr (arg
, ip
->reloc_info
+ ip
->reloc_num
,
799 reloc_num_we_have
, &reloc_num
, &imm
) == 0;
807 bfd_reloc_code_real_type reloc_type
= BFD_RELOC_NONE
;
808 reloc_num_we_have
-= reloc_num
;
809 if (reloc_num_we_have
== 0)
810 as_fatal (_("expr too huge") /* Want one more reloc. */);
813 if (strncmp (bit_field
, "10:12", strlen ("10:12")) == 0)
814 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_U_10_12
;
816 else if (esc_ch1
== 's')
818 if (strncmp (bit_field
, "10:16<<2", strlen ("10:16<<2")) == 0)
819 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2
;
820 else if (strncmp (bit_field
, "0:5|10:16<<2",
821 strlen ("0:5|10:16<<2")) == 0)
822 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2
;
823 else if (strncmp (bit_field
, "0:10|10:16<<2",
824 strlen ("0:10|10:16<<2")) == 0)
825 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2
;
826 else if (strncmp (bit_field
, "10:12", strlen ("10:12")) == 0)
827 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_10_12
;
828 else if (strncmp (bit_field
, "5:20", strlen ("5:20")) == 0)
829 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_5_20
;
830 else if (strncmp (bit_field
, "10:16", strlen ("10:16")) == 0)
831 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_10_16
;
832 else if (strncmp (bit_field
, "10:5", strlen ("10:5")) == 0)
833 reloc_type
= BFD_RELOC_LARCH_SOP_POP_32_S_10_5
;
835 if (reloc_type
== BFD_RELOC_NONE
)
837 _("not support reloc bit-field\nfmt: %c%c %s\nargs: %s"),
838 esc_ch1
, esc_ch2
, bit_field
, arg
);
840 if (ip
->reloc_info
[0].type
>= BFD_RELOC_LARCH_B16
841 && ip
->reloc_info
[0].type
<= BFD_RELOC_LARCH_TLS_DESC_PCREL20_S2
)
843 /* As we compact stack-relocs, it is no need for pop operation.
844 But break out until here in order to check the imm field.
845 May be reloc_num > 1 if implement relax? */
846 ip
->reloc_num
+= reloc_num
;
847 reloc_type
= ip
->reloc_info
[0].type
;
850 && (BFD_RELOC_LARCH_TLS_LE_HI20_R
== reloc_type
851 || BFD_RELOC_LARCH_TLS_LE_LO12_R
== reloc_type
852 || BFD_RELOC_LARCH_TLS_LE_HI20
== reloc_type
853 || BFD_RELOC_LARCH_TLS_LE_LO12
== reloc_type
854 || BFD_RELOC_LARCH_TLS_LE64_LO20
== reloc_type
855 || BFD_RELOC_LARCH_TLS_LE64_HI12
== reloc_type
856 || BFD_RELOC_LARCH_CALL36
== reloc_type
))
858 ip
->reloc_info
[ip
->reloc_num
].type
= BFD_RELOC_LARCH_RELAX
;
859 ip
->reloc_info
[ip
->reloc_num
].value
= const_0
;
863 /* Only one register macros (used in normal code model)
865 LARCH_opts.ase_labs and LARCH_opts.ase_gabs are used
866 to generate the code model of absolute addresses, and
867 we do not relax this code model. */
868 if (LARCH_opts
.relax
&& (ip
->expand_from_macro
& 1)
869 && !(LARCH_opts
.ase_labs
| LARCH_opts
.ase_gabs
)
870 && (BFD_RELOC_LARCH_PCALA_HI20
== reloc_type
871 || BFD_RELOC_LARCH_PCALA_LO12
== reloc_type
872 || BFD_RELOC_LARCH_GOT_PC_HI20
== reloc_type
873 || BFD_RELOC_LARCH_GOT_PC_LO12
== reloc_type
874 || BFD_RELOC_LARCH_TLS_LD_PC_HI20
== reloc_type
875 || BFD_RELOC_LARCH_TLS_GD_PC_HI20
== reloc_type
876 || BFD_RELOC_LARCH_TLS_DESC_PC_HI20
== reloc_type
877 || BFD_RELOC_LARCH_TLS_DESC_PC_LO12
== reloc_type
878 || BFD_RELOC_LARCH_TLS_DESC_LD
== reloc_type
879 || BFD_RELOC_LARCH_TLS_DESC_CALL
== reloc_type
880 || BFD_RELOC_LARCH_TLS_IE_PC_HI20
== reloc_type
881 || BFD_RELOC_LARCH_TLS_IE_PC_LO12
== reloc_type
))
883 ip
->reloc_info
[ip
->reloc_num
].type
= BFD_RELOC_LARCH_RELAX
;
884 ip
->reloc_info
[ip
->reloc_num
].value
= const_0
;
890 ip
->reloc_num
+= reloc_num
;
891 ip
->reloc_info
[ip
->reloc_num
- 1].type
= reloc_type
;
892 ip
->reloc_info
[ip
->reloc_num
- 1].value
= const_0
;
896 imm
= (intptr_t) str_hash_find (r_htab
, arg
);
897 ip
->match_now
= 0 < imm
;
901 /* Handle potential usage of deprecated register aliases. */
902 imm
= (intptr_t) str_hash_find (r_deprecated_htab
, arg
);
903 ip
->match_now
= 0 < imm
;
905 /* !ip->expand_from_macro: avoiding duplicate output warnings,
906 only the first macro output warning. */
907 if (ip
->match_now
&& !ip
->expand_from_macro
)
908 as_warn (_("register alias %s is deprecated, use %s instead"),
909 arg
, r_abi_names
[ret
]);
915 imm
= (intptr_t) str_hash_find (fc_htab
, arg
);
918 imm
= (intptr_t) str_hash_find (fcn_htab
, arg
);
922 imm
= (intptr_t) str_hash_find (f_htab
, arg
);
924 ip
->match_now
= 0 < imm
;
926 if (ip
->match_now
&& !ip
->expand_from_macro
)
928 /* Handle potential usage of deprecated register aliases. */
929 imm
= (intptr_t) str_hash_find (f_deprecated_htab
, arg
);
930 ip
->match_now
= 0 < imm
;
933 as_warn (_("register alias %s is deprecated, use %s instead"),
934 arg
, f_abi_names
[ret
]);
940 imm
= (intptr_t) str_hash_find (cr_htab
, arg
);
943 imm
= (intptr_t) str_hash_find (c_htab
, arg
);
945 ip
->match_now
= 0 < imm
;
949 imm
= (intptr_t) str_hash_find (v_htab
, arg
);
950 ip
->match_now
= 0 < imm
;
954 imm
= (intptr_t) str_hash_find (x_htab
, arg
);
955 ip
->match_now
= 0 < imm
;
959 ip
->all_match
= ip
->match_now
;
961 ip
->insn
->mask
? loongarch_insn_length (ip
->insn
->match
) : 0;
962 /* FIXME: now we have no relax insn. */
963 ip
->relax_max_length
= ip
->insn_length
;
966 as_fatal (_("unknown escape"));
971 /* Check imm overflow. */
972 int bit_width
, bits_needed_s
, bits_needed_u
;
981 bit_width
= loongarch_get_bit_field_width (bit_field
, &t
);
984 /* No specify bit width. */
988 if (t
[0] == '<' && t
[1] == '<')
990 int i
= strtol (t
+= 2, &t
, 10), j
;
991 for (j
= i
; 0 < j
; j
--, imm
>>= 1)
993 as_fatal (_("require imm low %d bit is 0."), i
);
997 imm
-= strtol (t
, &t
, 10);
999 bits_needed_s
= loongarch_bits_imm_needed (imm
, 1);
1000 bits_needed_u
= loongarch_bits_imm_needed (imm
, 0);
1002 if ((esc_ch1
== 's' && bit_width
< bits_needed_s
)
1003 || (esc_ch1
!= 's' && bit_width
< bits_needed_u
))
1004 /* How to do after we detect overflow. */
1005 as_fatal (_("Immediate overflow.\n"
1008 esc_ch1
, esc_ch2
, bit_field
, arg
);
1012 if (esc_ch1
!= '\0')
1014 ip
->args
[ip
->arg_num
] = ret
;
1021 get_loongarch_opcode (struct loongarch_cl_insn
*insn
)
1023 const struct loongarch_opcode
*it
;
1024 struct loongarch_ase
*ase
;
1025 for (ase
= loongarch_ASEs
; ase
->enabled
; ase
++)
1027 if (!*ase
->enabled
|| (ase
->include
&& !*ase
->include
)
1028 || (ase
->exclude
&& *ase
->exclude
))
1031 if (!ase
->name_hash_entry
)
1033 ase
->name_hash_entry
= str_htab_create ();
1034 for (it
= ase
->opcodes
; it
->name
; it
++)
1036 if ((!it
->include
|| (it
->include
&& *it
->include
))
1037 && (!it
->exclude
|| (it
->exclude
&& !(*it
->exclude
)))
1038 && !(it
->pinfo
& INSN_DIS_ALIAS
))
1039 str_hash_insert (ase
->name_hash_entry
, it
->name
,
1044 if ((it
= str_hash_find (ase
->name_hash_entry
, insn
->name
)) == NULL
)
1050 insn
->match_now
= 1;
1051 insn
->all_match
= 0;
1053 insn
->reloc_num
= 0;
1054 insn
->insn_bin
= (loongarch_foreach_args
1055 (it
->format
, insn
->arg_strs
,
1056 loongarch_args_parser_can_match_arg_helper
,
1058 if (insn
->all_match
&& !(it
->include
&& !*it
->include
)
1059 && !(it
->exclude
&& *it
->exclude
))
1061 insn
->insn_bin
|= it
->match
;
1066 while (it
->name
&& strcasecmp (it
->name
, insn
->name
) == 0);
1071 check_this_insn_before_appending (struct loongarch_cl_insn
*ip
)
1075 if (strncmp (ip
->name
, "la.abs", 6) == 0)
1077 ip
->reloc_info
[ip
->reloc_num
].type
= BFD_RELOC_LARCH_MARK_LA
;
1078 ip
->reloc_info
[ip
->reloc_num
].value
= const_0
;
1081 /* check all atomic memory insns */
1082 else if (ip
->insn
->mask
== LARCH_MK_ATOMIC_MEM
1083 && LARCH_INSN_ATOMIC_MEM(ip
->insn_bin
))
1085 /* For AMO insn amswap.[wd], amadd.[wd], etc. */
1086 if (ip
->args
[0] != 0
1087 && (ip
->args
[0] == ip
->args
[1] || ip
->args
[0] == ip
->args
[2]))
1088 as_bad (_("atomic memory operations insns require rd != rj"
1089 " && rd != rk when rd isn't r0"));
1091 else if ((ip
->insn
->mask
== LARCH_MK_BSTRINS_W
1092 /* bstr(ins|pick).w rd, rj, msbw, lsbw */
1093 && (LARCH_INSN_BSTRINS_W(ip
->insn_bin
)
1094 || LARCH_INSN_BSTRPICK_W(ip
->insn_bin
)))
1095 || (ip
->insn
->mask
== LARCH_MK_BSTRINS_D
1096 /* bstr(ins|pick).d rd, rj, msbd, lsbd */
1097 && (LARCH_INSN_BSTRINS_D(ip
->insn_bin
)
1098 || LARCH_INSN_BSTRPICK_D(ip
->insn_bin
))))
1100 /* For bstr(ins|pick).[wd]. */
1101 if (ip
->args
[2] < ip
->args
[3])
1102 as_bad (_("bstr(ins|pick).[wd] require msbd >= lsbd"));
1104 else if (ip
->insn
->mask
!= 0
1105 && (LARCH_INSN_CSRXCHG(ip
->insn_bin
)
1106 || LARCH_INSN_GCSRXCHG(ip
->insn_bin
))
1107 && (LARCH_GET_RJ(ip
->insn_bin
) == 0
1108 || LARCH_GET_RJ(ip
->insn_bin
) == 1)
1109 /* csrxchg rd, rj, csr_num */
1110 && (strcmp ("csrxchg", ip
->name
) == 0
1111 || strcmp ("gcsrxchg", ip
->name
) == 0))
1112 as_bad (_("g?csrxchg require rj != r0 && rj != r1"));
1118 install_insn (const struct loongarch_cl_insn
*insn
)
1120 char *f
= insn
->frag
->fr_literal
+ insn
->where
;
1121 if (0 < insn
->insn_length
)
1122 md_number_to_chars (f
, insn
->insn_bin
, insn
->insn_length
);
1126 move_insn (struct loongarch_cl_insn
*insn
, fragS
*frag
, long where
)
1130 insn
->where
= where
;
1131 for (i
= 0; i
< insn
->reloc_num
; i
++)
1135 insn
->fixp
[i
]->fx_frag
= frag
;
1136 insn
->fixp
[i
]->fx_where
= where
;
1139 install_insn (insn
);
1142 /* Add INSN to the end of the output. */
1144 append_fixed_insn (struct loongarch_cl_insn
*insn
)
1146 /* Ensure the jirl is emitted to the same frag as the pcaddu18i. */
1147 if (BFD_RELOC_LARCH_CALL36
== insn
->reloc_info
[0].type
)
1150 char *f
= frag_more (insn
->insn_length
);
1151 move_insn (insn
, frag_now
, f
- frag_now
->fr_literal
);
1155 if (strcmp (insn
->name
, "jirl") == 0)
1157 /* See comment at end of append_fixp_and_insn. */
1158 frag_wane (frag_now
);
1164 if (BFD_RELOC_LARCH_CALL36
== insn
->reloc_info
[0].type
)
1168 /* Add instructions based on the worst-case scenario firstly. */
1170 append_relaxed_branch_insn (struct loongarch_cl_insn
*insn
, int max_chars
,
1171 int var
, relax_substateT subtype
, symbolS
*symbol
, offsetT offset
)
1173 frag_grow (max_chars
);
1174 move_insn (insn
, frag_now
, frag_more (0) - frag_now
->fr_literal
);
1175 frag_var (rs_machine_dependent
, max_chars
, var
,
1176 subtype
, symbol
, offset
, NULL
);
1180 append_fixp_and_insn (struct loongarch_cl_insn
*ip
)
1182 reloc_howto_type
*howto
;
1183 bfd_reloc_code_real_type r_type
;
1184 struct reloc_info
*reloc_info
= ip
->reloc_info
;
1187 dwarf2_emit_insn (0);
1189 for (i
= 0; i
< ip
->reloc_num
; i
++)
1191 r_type
= reloc_info
[i
].type
;
1193 if (r_type
!= BFD_RELOC_UNUSED
)
1196 gas_assert (&(reloc_info
[i
].value
));
1197 if (BFD_RELOC_LARCH_B16
== r_type
|| BFD_RELOC_LARCH_B21
== r_type
)
1199 int min_bytes
= 4; /* One branch instruction. */
1200 unsigned max_bytes
= 8; /* Branch and jump instructions. */
1202 if (now_seg
== absolute_section
)
1204 as_bad (_("relaxable branches not supported in absolute section"));
1208 append_relaxed_branch_insn (ip
, max_bytes
, min_bytes
,
1209 RELAX_BRANCH_ENCODE (r_type
),
1210 reloc_info
[i
].value
.X_add_symbol
,
1211 reloc_info
[i
].value
.X_add_number
);
1216 howto
= bfd_reloc_type_lookup (stdoutput
, r_type
);
1218 as_fatal (_("no HOWTO loong relocation number %d"), r_type
);
1220 ip
->fixp
[i
] = fix_new_exp (ip
->frag
, ip
->where
,
1221 bfd_get_reloc_size (howto
),
1222 &reloc_info
[i
].value
, FALSE
, r_type
);
1224 /* Allow LoongArch 64 to use 64-bit addends. */
1225 if (LARCH_opts
.ase_lp64
)
1226 ip
->fixp
[i
]->fx_no_overflow
= 1;
1230 if (ip
->insn_length
< ip
->relax_max_length
)
1231 as_fatal (_("Internal error: not support relax now"));
1233 append_fixed_insn (ip
);
1235 /* We need to start a new frag after any instruction that can be
1236 optimized away or compressed by the linker during relaxation, to prevent
1237 the assembler from computing static offsets across such an instruction.
1239 This is necessary to get correct .eh_frame FDE DW_CFA_advance_loc info.
1240 If one cfi_insn_data's two symbols are not in the same frag, it will
1241 generate ADD and SUB relocations pairs to calculate DW_CFA_advance_loc.
1242 (gas/dw2gencfi.c: output_cfi_insn:
1243 if (symbol_get_frag (to) == symbol_get_frag (from)))
1245 For macro instructions, only the first instruction expanded from macro
1246 need to start a new frag.
1247 Since the relocations of the normal code model and the extreme code model
1248 of the old LE instruction sequence are the same, it is impossible to
1249 distinguish which code model it is based on relocation alone, so the
1250 extreme code model has to be relaxed. */
1251 if (LARCH_opts
.relax
1252 && (BFD_RELOC_LARCH_PCALA_HI20
== reloc_info
[0].type
1253 || BFD_RELOC_LARCH_GOT_PC_HI20
== reloc_info
[0].type
1254 || BFD_RELOC_LARCH_TLS_LE_HI20_R
== reloc_info
[0].type
1255 || BFD_RELOC_LARCH_TLS_LE_ADD_R
== reloc_info
[0].type
1256 || BFD_RELOC_LARCH_TLS_LD_PC_HI20
== reloc_info
[0].type
1257 || BFD_RELOC_LARCH_TLS_GD_PC_HI20
== reloc_info
[0].type
1258 || BFD_RELOC_LARCH_TLS_DESC_PC_HI20
== reloc_info
[0].type
1259 || BFD_RELOC_LARCH_TLS_IE_PC_HI20
== reloc_info
[0].type
1260 || BFD_RELOC_LARCH_TLS_LE_HI20
== reloc_info
[0].type
1261 || BFD_RELOC_LARCH_TLS_LE_LO12
== reloc_info
[0].type
1262 || BFD_RELOC_LARCH_TLS_LE64_LO20
== reloc_info
[0].type
1263 || BFD_RELOC_LARCH_TLS_LE64_HI12
== reloc_info
[0].type
))
1265 frag_wane (frag_now
);
1270 /* Ask helper for returning a malloced c_str or NULL. */
1272 assember_macro_helper (const char *const args
[], void *context_ptr
)
1274 struct loongarch_cl_insn
*insn
= context_ptr
;
1276 if ( strcmp (insn
->name
, "li.w") == 0 || strcmp (insn
->name
, "li.d") == 0)
1278 char args_buf
[50], insns_buf
[200];
1279 const char *arg_strs
[6];
1280 uint32_t hi32
, lo32
;
1282 /* We pay attention to sign extend beacause it is chance of reduce insn.
1283 The exception is 12-bit and hi-12-bit unsigned,
1284 we need a 'ori' or a 'lu52i.d' accordingly. */
1285 char all0_bit_vec
, sign_bit_vec
, allf_bit_vec
, paritial_is_sext_of_prev
;
1287 lo32
= insn
->args
[1] & 0xffffffff;
1288 hi32
= insn
->args
[1] >> 32;
1290 if (strcmp (insn
->name
, "li.w") == 0)
1292 if (hi32
!= 0 && hi32
!= 0xffffffff)
1293 as_fatal (_("li overflow: hi32:0x%x lo32:0x%x"), hi32
, lo32
);
1294 hi32
= lo32
& 0x80000000 ? 0xffffffff : 0;
1297 if (strcmp (insn
->name
, "li.d") == 0 && !LARCH_opts
.ase_lp64
)
1298 as_fatal (_("we can't li.d on 32bit-arch"));
1300 snprintf (args_buf
, sizeof (args_buf
), "0x%x,0x%x,0x%x,0x%x,%s",
1301 (hi32
>> 20) & 0xfff, hi32
& 0xfffff, (lo32
>> 12) & 0xfffff,
1302 lo32
& 0xfff, args
[0]);
1303 loongarch_split_args_by_comma (args_buf
, arg_strs
);
1306 ((((hi32
& 0xfff00000) == 0) << 3) | (((hi32
& 0x000fffff) == 0) << 2)
1307 | (((lo32
& 0xfffff000) == 0) << 1) | ((lo32
& 0x00000fff) == 0));
1309 ((((hi32
& 0x80000000) != 0) << 3) | (((hi32
& 0x00080000) != 0) << 2)
1310 | (((lo32
& 0x80000000) != 0) << 1) | ((lo32
& 0x00000800) != 0));
1312 ((((hi32
& 0xfff00000) == 0xfff00000) << 3)
1313 | (((hi32
& 0x000fffff) == 0x000fffff) << 2)
1314 | (((lo32
& 0xfffff000) == 0xfffff000) << 1)
1315 | ((lo32
& 0x00000fff) == 0x00000fff));
1316 paritial_is_sext_of_prev
=
1317 (all0_bit_vec
^ allf_bit_vec
) & (all0_bit_vec
^ (sign_bit_vec
<< 1));
1319 static const char *const li_32bit
[] =
1321 "lu12i.w %5,%3&0x80000?%3-0x100000:%3;ori %5,%5,%4;",
1322 "lu12i.w %5,%3&0x80000?%3-0x100000:%3;",
1323 "addi.w %5,$r0,%4&0x800?%4-0x1000:%4;",
1326 static const char *const li_hi_32bit
[] =
1328 "lu32i.d %5,%2&0x80000?%2-0x100000:%2;"
1329 "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
1330 "lu52i.d %5,%5,%1&0x800?%1-0x1000:%1;",
1331 "lu32i.d %5,%2&0x80000?%2-0x100000:%2;",
1336 insns_buf
[0] = '\0';
1337 if (paritial_is_sext_of_prev
== 0x7)
1339 strcat (insns_buf
, "lu52i.d %5,$r0,%1&0x800?%1-0x1000:%1;");
1342 if ((all0_bit_vec
& 0x3) == 0x2)
1343 strcat (insns_buf
, "ori %5,$r0,%4;");
1345 strcat (insns_buf
, li_32bit
[paritial_is_sext_of_prev
& 0x3]);
1346 strcat (insns_buf
, li_hi_32bit
[paritial_is_sext_of_prev
>> 2]);
1350 ret
= loongarch_expand_macro (insns_buf
, arg_strs
, NULL
, NULL
,
1357 /* Accept instructions separated by ';'
1358 * assuming 'not starting with space and not ending with space' or pass in
1361 loongarch_assemble_INSNs (char *str
, unsigned int expand_from_macro
)
1364 size_t len_str
= strlen(str
);
1366 for (rest
= str
; *rest
!= ';' && *rest
!= '\0'; rest
++);
1373 setup_internal_label_here (strtol (str
, &str
, 10));
1382 struct loongarch_cl_insn the_one
= { 0 };
1384 the_one
.expand_from_macro
= expand_from_macro
;
1386 for (; *str
&& *str
!= ' '; str
++)
1391 loongarch_split_args_by_comma (str
, the_one
.arg_strs
);
1392 get_loongarch_opcode (&the_one
);
1394 if (!the_one
.all_match
)
1396 char *ss
= loongarch_cat_splited_strs (the_one
.arg_strs
);
1397 as_bad (_("no match insn: %s\t%s"), the_one
.name
, ss
? ss
: "");
1402 if (check_this_insn_before_appending (&the_one
) != 0)
1405 append_fixp_and_insn (&the_one
);
1407 /* Expanding macro instructions. */
1408 if (the_one
.insn_length
== 0 && the_one
.insn
->macro
)
1410 unsigned int new_expand_from_macro
= 0;
1411 if (2 == the_one
.arg_num
)
1412 new_expand_from_macro
|= 1;
1413 else if (3 == the_one
.arg_num
)
1414 new_expand_from_macro
|= 2;
1416 char *c_str
= loongarch_expand_macro (the_one
.insn
->macro
,
1418 assember_macro_helper
,
1420 /* The first instruction expanded from macro. */
1421 loongarch_assemble_INSNs (c_str
, new_expand_from_macro
);
1427 /* The rest instructions expanded from macro, split by semicolon(;),
1428 assembly one by one. */
1430 loongarch_assemble_INSNs (rest
, expand_from_macro
);
1434 md_assemble (char *str
)
1436 loongarch_assemble_INSNs (str
, 0);
1440 md_atof (int type
, char *litP
, int *sizeP
)
1442 return ieee_md_atof (type
, litP
, sizeP
, FALSE
);
1446 md_number_to_chars (char *buf
, valueT val
, int n
)
1448 number_to_chars_littleendian (buf
, val
, n
);
1451 /* The location from which a PC relative jump should be calculated,
1452 given a PC relative reloc. */
1454 md_pcrel_from (fixS
*fixP ATTRIBUTE_UNUSED
)
1459 static void fix_reloc_insn (fixS
*fixP
, bfd_vma reloc_val
, char *buf
)
1461 reloc_howto_type
*howto
;
1463 howto
= bfd_reloc_type_lookup (stdoutput
, fixP
->fx_r_type
);
1465 insn
= bfd_getl32 (buf
);
1467 if (!loongarch_adjust_reloc_bitsfield (NULL
, howto
, &reloc_val
))
1468 as_bad_where (fixP
->fx_file
, fixP
->fx_line
, "Reloc overflow");
1470 insn
= (insn
& (insn_t
)howto
->src_mask
)
1471 | ((insn
& (~(insn_t
)howto
->dst_mask
)) | reloc_val
);
1473 bfd_putl32 (insn
, buf
);
1477 md_apply_fix (fixS
*fixP
, valueT
*valP
, segT seg ATTRIBUTE_UNUSED
)
1479 static int64_t stack_top
;
1480 static int last_reloc_is_sop_push_pcrel_1
= 0;
1481 int last_reloc_is_sop_push_pcrel
= last_reloc_is_sop_push_pcrel_1
;
1483 last_reloc_is_sop_push_pcrel_1
= 0;
1485 char *buf
= fixP
->fx_frag
->fr_literal
+ fixP
->fx_where
;
1486 switch (fixP
->fx_r_type
)
1488 case BFD_RELOC_LARCH_SOP_PUSH_TLS_TPREL
:
1489 case BFD_RELOC_LARCH_SOP_PUSH_TLS_GD
:
1490 case BFD_RELOC_LARCH_SOP_PUSH_TLS_GOT
:
1491 case BFD_RELOC_LARCH_TLS_LE_HI20
:
1492 case BFD_RELOC_LARCH_TLS_LE_LO12
:
1493 case BFD_RELOC_LARCH_TLS_LE64_LO20
:
1494 case BFD_RELOC_LARCH_TLS_LE64_HI12
:
1495 case BFD_RELOC_LARCH_TLS_IE_PC_HI20
:
1496 case BFD_RELOC_LARCH_TLS_IE_PC_LO12
:
1497 case BFD_RELOC_LARCH_TLS_IE64_PC_LO20
:
1498 case BFD_RELOC_LARCH_TLS_IE64_PC_HI12
:
1499 case BFD_RELOC_LARCH_TLS_IE_HI20
:
1500 case BFD_RELOC_LARCH_TLS_IE_LO12
:
1501 case BFD_RELOC_LARCH_TLS_IE64_LO20
:
1502 case BFD_RELOC_LARCH_TLS_IE64_HI12
:
1503 case BFD_RELOC_LARCH_TLS_LD_PC_HI20
:
1504 case BFD_RELOC_LARCH_TLS_LD_HI20
:
1505 case BFD_RELOC_LARCH_TLS_GD_PC_HI20
:
1506 case BFD_RELOC_LARCH_TLS_GD_HI20
:
1507 case BFD_RELOC_LARCH_TLS_DESC_PC_HI20
:
1508 case BFD_RELOC_LARCH_TLS_DESC_PC_LO12
:
1509 case BFD_RELOC_LARCH_TLS_DESC64_PC_LO20
:
1510 case BFD_RELOC_LARCH_TLS_DESC64_PC_HI12
:
1511 case BFD_RELOC_LARCH_TLS_DESC_HI20
:
1512 case BFD_RELOC_LARCH_TLS_DESC_LO12
:
1513 case BFD_RELOC_LARCH_TLS_DESC64_LO20
:
1514 case BFD_RELOC_LARCH_TLS_DESC64_HI12
:
1515 case BFD_RELOC_LARCH_TLS_LE_ADD_R
:
1516 case BFD_RELOC_LARCH_TLS_LE_HI20_R
:
1517 case BFD_RELOC_LARCH_TLS_LE_LO12_R
:
1518 /* Add tls lo (got_lo reloc type). */
1519 if (fixP
->fx_addsy
== NULL
)
1520 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1521 _("Relocation against a constant"));
1522 S_SET_THREAD_LOCAL (fixP
->fx_addsy
);
1525 case BFD_RELOC_LARCH_SOP_PUSH_PCREL
:
1526 if (fixP
->fx_addsy
== NULL
)
1527 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1528 _("Relocation against a constant"));
1530 last_reloc_is_sop_push_pcrel_1
= 1;
1531 if (S_GET_SEGMENT (fixP
->fx_addsy
) == seg
)
1532 stack_top
= (S_GET_VALUE (fixP
->fx_addsy
) + fixP
->fx_offset
1533 - (fixP
->fx_where
+ fixP
->fx_frag
->fr_address
));
1538 case BFD_RELOC_LARCH_TLS_DESC_LD
:
1539 case BFD_RELOC_LARCH_TLS_DESC_CALL
:
1542 case BFD_RELOC_LARCH_SOP_POP_32_S_10_5
:
1543 case BFD_RELOC_LARCH_SOP_POP_32_S_10_12
:
1544 case BFD_RELOC_LARCH_SOP_POP_32_U_10_12
:
1545 case BFD_RELOC_LARCH_SOP_POP_32_S_10_16
:
1546 case BFD_RELOC_LARCH_SOP_POP_32_S_10_16_S2
:
1547 case BFD_RELOC_LARCH_SOP_POP_32_S_5_20
:
1548 case BFD_RELOC_LARCH_SOP_POP_32_U
:
1549 case BFD_RELOC_LARCH_SOP_POP_32_S_0_5_10_16_S2
:
1550 case BFD_RELOC_LARCH_SOP_POP_32_S_0_10_10_16_S2
:
1551 if (!last_reloc_is_sop_push_pcrel
)
1554 fix_reloc_insn (fixP
, (bfd_vma
)stack_top
, buf
);
1557 /* LARCH only has R_LARCH_64/32, not has R_LARCH_24/16/8.
1558 For BFD_RELOC_64/32, if fx_addsy and fx_subsy not null, wer need
1559 generate BFD_RELOC_LARCH_ADD64/32 and BFD_RELOC_LARCH_SUB64/32 here.
1560 Then will parse howto table bfd_reloc_code_real_type to generate
1561 R_LARCH_ADD64/32 and R_LARCH_SUB64/32 reloc at tc_gen_reloc function.
1562 If only fx_addsy not null, skip here directly, then generate
1565 For BFD_RELOC_24/16/8, if fx_addsy and fx_subsy not null, wer need
1566 generate BFD_RELOC_LARCH_ADD24/16/8 and BFD_RELOC_LARCH_SUB24/16/8 here.
1567 Then will parse howto table bfd_reloc_code_real_type to generate
1568 R_LARCH_ADD24/16/8 and R_LARCH_SUB24/16/8 reloc at tc_gen_reloc
1569 function. If only fx_addsy not null, we generate
1570 BFD_RELOC_LARCH_ADD24/16/8 only, then generate R_LARCH_24/16/8.
1571 To avoid R_LARCH_ADDxx add extra value, we write 0 first
1572 (use md_number_to_chars (buf, 0, fixP->fx_size)). */
1577 switch (fixP
->fx_r_type
)
1580 fixP
->fx_r_type
= BFD_RELOC_LARCH_64_PCREL
;
1583 fixP
->fx_r_type
= BFD_RELOC_LARCH_32_PCREL
;
1590 /* If symbol in .eh_frame the address may be adjusted, and contents of
1591 .eh_frame will be adjusted, so use pc-relative relocation for FDE
1593 The Option of mthin-add-sub does not affect the generation of
1594 R_LARCH_32_PCREL relocation in .eh_frame. */
1595 if (fixP
->fx_r_type
== BFD_RELOC_32
1596 && fixP
->fx_addsy
&& fixP
->fx_subsy
1597 && (sub_segment
= S_GET_SEGMENT (fixP
->fx_subsy
))
1598 && strcmp (sub_segment
->name
, ".eh_frame") == 0
1599 && S_GET_VALUE (fixP
->fx_subsy
)
1600 == fixP
->fx_frag
->fr_address
+ fixP
->fx_where
)
1602 fixP
->fx_r_type
= BFD_RELOC_LARCH_32_PCREL
;
1603 fixP
->fx_subsy
= NULL
;
1607 if (fixP
->fx_addsy
&& fixP
->fx_subsy
)
1609 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
1610 fixP
->fx_next
->fx_addsy
= fixP
->fx_subsy
;
1611 fixP
->fx_next
->fx_subsy
= NULL
;
1612 fixP
->fx_next
->fx_offset
= 0;
1613 fixP
->fx_subsy
= NULL
;
1615 switch (fixP
->fx_r_type
)
1618 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD64
;
1619 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB64
;
1622 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD32
;
1623 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB32
;
1629 md_number_to_chars (buf
, 0, fixP
->fx_size
);
1632 if (fixP
->fx_addsy
== NULL
)
1635 md_number_to_chars (buf
, *valP
, fixP
->fx_size
);
1644 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
1645 fixP
->fx_next
->fx_addsy
= fixP
->fx_subsy
;
1646 fixP
->fx_next
->fx_subsy
= NULL
;
1647 fixP
->fx_next
->fx_offset
= 0;
1648 fixP
->fx_subsy
= NULL
;
1650 switch (fixP
->fx_r_type
)
1653 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD24
;
1654 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB24
;
1657 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD16
;
1658 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB16
;
1661 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD8
;
1662 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB8
;
1668 md_number_to_chars (buf
, 0, fixP
->fx_size
);
1670 if (fixP
->fx_next
->fx_addsy
== NULL
)
1671 fixP
->fx_next
->fx_done
= 1;
1674 if (fixP
->fx_addsy
== NULL
)
1677 md_number_to_chars (buf
, *valP
, fixP
->fx_size
);
1681 case BFD_RELOC_LARCH_CFA
:
1682 if (fixP
->fx_addsy
&& fixP
->fx_subsy
)
1684 fixP
->fx_next
= xmemdup (fixP
, sizeof (*fixP
), sizeof (*fixP
));
1685 fixP
->fx_next
->fx_addsy
= fixP
->fx_subsy
;
1686 fixP
->fx_next
->fx_subsy
= NULL
;
1687 fixP
->fx_next
->fx_offset
= 0;
1688 fixP
->fx_subsy
= NULL
;
1690 unsigned int subtype
;
1692 subtype
= bfd_get_8 (NULL
, &((fragS
*)
1693 (fixP
->fx_frag
->fr_opcode
))->fr_literal
[fixP
->fx_where
]);
1694 loc
= fixP
->fx_frag
->fr_fix
- (subtype
& 7);
1697 case DW_CFA_advance_loc1
:
1698 fixP
->fx_where
= loc
+ 1;
1699 fixP
->fx_next
->fx_where
= loc
+ 1;
1700 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD8
;
1701 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB8
;
1702 md_number_to_chars (buf
+1, 0, fixP
->fx_size
);
1705 case DW_CFA_advance_loc2
:
1707 fixP
->fx_next
->fx_size
= 2;
1708 fixP
->fx_where
= loc
+ 1;
1709 fixP
->fx_next
->fx_where
= loc
+ 1;
1710 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD16
;
1711 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB16
;
1712 md_number_to_chars (buf
+1, 0, fixP
->fx_size
);
1715 case DW_CFA_advance_loc4
:
1717 fixP
->fx_next
->fx_size
= 4;
1718 fixP
->fx_where
= loc
;
1719 fixP
->fx_next
->fx_where
= loc
;
1720 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD32
;
1721 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB32
;
1722 md_number_to_chars (buf
+1, 0, fixP
->fx_size
);
1726 if (subtype
< 0x80 && (subtype
& 0x40))
1728 /* DW_CFA_advance_loc. */
1729 fixP
->fx_frag
= (fragS
*) fixP
->fx_frag
->fr_opcode
;
1730 fixP
->fx_next
->fx_frag
= fixP
->fx_frag
;
1731 fixP
->fx_r_type
= BFD_RELOC_LARCH_ADD6
;
1732 fixP
->fx_next
->fx_r_type
= BFD_RELOC_LARCH_SUB6
;
1733 md_number_to_chars (buf
, 0x40, fixP
->fx_size
);
1736 as_fatal (_("internal: bad CFA value #%d"), subtype
);
1742 case BFD_RELOC_LARCH_B16
:
1743 case BFD_RELOC_LARCH_B21
:
1744 case BFD_RELOC_LARCH_B26
:
1745 if (fixP
->fx_addsy
== NULL
)
1747 as_bad_where (fixP
->fx_file
, fixP
->fx_line
,
1748 _ ("Relocation against a constant."));
1750 if (S_GET_SEGMENT (fixP
->fx_addsy
) == seg
1751 && !S_FORCE_RELOC (fixP
->fx_addsy
, 1))
1753 int64_t sym_addend
= S_GET_VALUE (fixP
->fx_addsy
) + fixP
->fx_offset
;
1754 int64_t pc
= fixP
->fx_where
+ fixP
->fx_frag
->fr_address
;
1755 fix_reloc_insn (fixP
, sym_addend
- pc
, buf
);
1757 /* If relax, symbol value may change at link time, so reloc need to
1759 if (!LARCH_opts
.relax
)
1764 /* Because ADD_ULEB128/SUB_ULEB128 always occur in pairs.
1765 So just deal with one is ok.
1766 case BFD_RELOC_LARCH_ADD_ULEB128: */
1767 case BFD_RELOC_LARCH_SUB_ULEB128
:
1769 unsigned int len
= 0;
1770 len
= loongarch_get_uleb128_length ((bfd_byte
*)buf
);
1771 bfd_byte
*endp
= (bfd_byte
*) buf
+ len
-1;
1772 /* Clean the uleb128 value to 0. Do not reduce the length. */
1773 memset (buf
, 0x80, len
- 1);
1783 /* Estimate the size of a frag before relaxing. */
1786 md_estimate_size_before_relax (fragS
*fragp
, asection
*sec
)
1788 /* align pseudo instunctions. */
1789 if (rs_align_code
== fragp
->fr_subtype
)
1792 if (NULL
== fragp
->fr_symbol
)
1793 nop_bytes
= fragp
->fr_offset
;
1795 nop_bytes
= ALIGN_MAX_NOP_BYTES (fragp
->fr_offset
);
1797 /* Normally, nop_bytes should be >= 4. */
1798 gas_assert (nop_bytes
> 0);
1800 if (FRAG_AT_START_OF_SECTION (fragp
)
1801 && 0 == ((1 << sec
->alignment_power
) % (nop_bytes
+ 4)))
1802 return (fragp
->fr_var
= 0);
1804 return (fragp
->fr_var
= nop_bytes
);
1807 /* branch instructions and other instructions.
1808 branch instructions may become 8 bytes after relaxing. */
1809 return (fragp
->fr_var
= 4);
1812 /* Translate internal representation of relocation info to BFD target
1815 tc_gen_reloc (asection
*section ATTRIBUTE_UNUSED
, fixS
*fixp
)
1817 arelent
*reloc
= (arelent
*) xmalloc (sizeof (arelent
));
1819 reloc
->sym_ptr_ptr
= (asymbol
**) xmalloc (sizeof (asymbol
*));
1820 *reloc
->sym_ptr_ptr
= symbol_get_bfdsym (fixp
->fx_addsy
);
1821 reloc
->address
= fixp
->fx_frag
->fr_address
+ fixp
->fx_where
;
1822 reloc
->addend
= fixp
->fx_offset
;
1824 reloc
->howto
= bfd_reloc_type_lookup (stdoutput
, fixp
->fx_r_type
);
1825 if (reloc
->howto
== NULL
)
1827 as_bad_where (fixp
->fx_file
, fixp
->fx_line
,
1828 _("cannot represent %s relocation in object file"),
1829 bfd_get_reloc_code_name (fixp
->fx_r_type
));
1836 /* Standard calling conventions leave the CFA at SP on entry. */
1838 loongarch_cfi_frame_initial_instructions (void)
1840 cfi_add_CFA_def_cfa_register (3 /* $sp */);
1844 loongarch_pre_output_hook (void)
1846 const frchainS
*frch
;
1849 if (!LARCH_opts
.relax
)
1852 /* Save the current segment info. */
1854 subsegT subseg
= now_subseg
;
1856 for (s
= stdoutput
->sections
; s
; s
= s
->next
)
1857 for (frch
= seg_info (s
)->frchainP
; frch
; frch
= frch
->frch_next
)
1861 for (frag
= frch
->frch_root
; frag
; frag
= frag
->fr_next
)
1863 if (frag
->fr_type
== rs_cfa
)
1866 expressionS
*symval
;
1868 symval
= symbol_get_value_expression (frag
->fr_symbol
);
1869 exp
.X_op
= O_subtract
;
1870 exp
.X_add_symbol
= symval
->X_add_symbol
;
1871 exp
.X_add_number
= 0;
1872 exp
.X_op_symbol
= symval
->X_op_symbol
;
1874 /* We must set the segment before creating a frag after all
1875 frag chains have been chained together. */
1876 subseg_set (s
, frch
->frch_subseg
);
1878 fix_new_exp (frag
, (int) frag
->fr_offset
, 1, &exp
, 0,
1879 BFD_RELOC_LARCH_CFA
);
1884 /* Restore the original segment info. */
1885 subseg_set (seg
, subseg
);
1889 tc_loongarch_parse_to_dw2regnum (expressionS
*exp
)
1891 expression_and_evaluate (exp
);
1895 md_show_usage (FILE *stream
)
1897 fprintf (stream
, _("LARCH options:\n"));
1899 fprintf (stream
, _("\
1900 -mthin-add-sub Convert a pair of R_LARCH_ADD32/64 and R_LARCH_SUB32/64 to\n\
1901 R_LARCH_32/64_PCREL as much as possible\n\
1902 The option does not affect the generation of R_LARCH_32_PCREL\n\
1903 relocations in .eh_frame\n\
1904 -mignore-start-align Ignore .align if it is at the start of a section. This option\n\
1905 can't be used when partial linking (ld -r).\n"));
1909 loongarch_make_nops (char *buf
, bfd_vma bytes
)
1913 /* Fill with 4-byte NOPs. */
1914 for ( ; i
< bytes
; i
+= 4)
1915 number_to_chars_littleendian (buf
+ i
, LARCH_NOP
, 4);
1918 /* Called from md_do_align. Used to create an alignment frag in a
1919 code section by emitting a worst-case NOP sequence that the linker
1920 will later relax to the correct number of NOPs. We can't compute
1921 the correct alignment now because of other linker relaxations. */
1924 loongarch_frag_align_code (int n
, int max
)
1930 /* When not relaxing, loongarch_handle_align handles code alignment. */
1931 if (!LARCH_opts
.relax
)
1934 bfd_vma align_bytes
= (bfd_vma
) 1 << n
;
1935 bfd_vma worst_case_bytes
= align_bytes
- 4;
1936 bfd_vma addend
= worst_case_bytes
;
1937 bool align_max
= max
> 0 && (bfd_vma
) max
< worst_case_bytes
;
1939 /* If we are moving to a smaller alignment than the instruction size, then no
1940 alignment is required. */
1941 if (align_bytes
<= 4)
1944 /* If max <= 0, ignore max.
1945 If max >= worst_case_bytes, max has no effect.
1946 Similar to gas/write.c relax_segment function rs_align_code case:
1947 if (fragP->fr_subtype != 0 && offset > fragP->fr_subtype). */
1950 s
= get_align_symbol (now_seg
);
1952 as_fatal (_("internal error: cannot get align symbol"));
1953 addend
= ALIGN_MAX_ADDEND (n
, max
);
1956 if (LARCH_opts
.ignore_start_align
)
1958 frag_grow (worst_case_bytes
);
1959 /* Use relaxable frag for .align.
1960 If .align at the start of section, do nothing. Section alignment can
1961 ensure correct alignment.
1962 If .align is not at the start of a section, reserve NOP instructions
1963 and R_LARCH_ALIGN relocation. */
1964 nops
= frag_var (rs_machine_dependent
, worst_case_bytes
, worst_case_bytes
,
1965 rs_align_code
, s
, addend
, NULL
);
1969 nops
= frag_more (worst_case_bytes
);
1972 ex
.X_add_symbol
= s
;
1976 ex
.X_op
= O_constant
;
1978 ex
.X_add_number
= addend
;
1980 fix_new_exp (frag_now
, nops
- frag_now
->fr_literal
, 0,
1981 &ex
, false, BFD_RELOC_LARCH_ALIGN
);
1984 /* Default write NOP for aligned bytes. */
1985 loongarch_make_nops (nops
, worst_case_bytes
);
1987 /* We need to start a new frag after the alignment which may be removed by
1988 the linker, to prevent the assembler from computing static offsets.
1989 This is necessary to get correct EH info. */
1990 frag_wane (frag_now
);
1996 /* Fill in an rs_align_code fragment. We want to fill 'andi $r0,$r0,0'. */
1998 loongarch_handle_align (fragS
*fragp
)
2000 /* char nop_opcode; */
2002 int bytes
, size
, excess
;
2005 if (fragp
->fr_type
!= rs_align_code
)
2008 struct loongarch_cl_insn nop
=
2009 { .name
= "andi", .arg_strs
= { "$r0", "$r0", "0", NULL
} };
2011 get_loongarch_opcode (&nop
);
2012 gas_assert (nop
.all_match
);
2014 p
= fragp
->fr_literal
+ fragp
->fr_fix
;
2015 opcode
= nop
.insn_bin
;
2018 bytes
= fragp
->fr_next
->fr_address
- fragp
->fr_address
- fragp
->fr_fix
;
2019 excess
= bytes
% size
;
2021 gas_assert (excess
< 4);
2022 fragp
->fr_fix
+= excess
;
2024 while (excess
-- != 0)
2027 md_number_to_chars (p
, opcode
, size
);
2028 fragp
->fr_var
= size
;
2031 /* Scan uleb128 subtraction expressions and insert fixups for them.
2032 e.g., .uleb128 .L1 - .L0
2033 Because relaxation may change the value of the subtraction, we
2034 must resolve them at link-time. */
2037 loongarch_insert_uleb128_fixes (bfd
*abfd ATTRIBUTE_UNUSED
,
2038 asection
*sec
, void *xxx ATTRIBUTE_UNUSED
)
2040 segment_info_type
*seginfo
= seg_info (sec
);
2043 subseg_set (sec
, 0);
2045 for (fragP
= seginfo
->frchainP
->frch_root
;
2046 fragP
; fragP
= fragP
->fr_next
)
2048 expressionS
*exp
, *exp_dup
;
2050 if (fragP
->fr_type
!= rs_leb128
|| fragP
->fr_symbol
== NULL
)
2053 exp
= symbol_get_value_expression (fragP
->fr_symbol
);
2055 if (exp
->X_op
!= O_subtract
)
2058 /* FIXME: Skip for .sleb128. */
2059 if (fragP
->fr_subtype
!= 0)
2062 exp_dup
= xmemdup (exp
, sizeof (*exp
), sizeof (*exp
));
2063 exp_dup
->X_op
= O_symbol
;
2064 exp_dup
->X_op_symbol
= NULL
;
2066 exp_dup
->X_add_symbol
= exp
->X_add_symbol
;
2067 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
2068 exp_dup
, 0, BFD_RELOC_LARCH_ADD_ULEB128
);
2070 /* From binutils/testsuite/binutils-all/dw5.S
2071 section .debug_rnglists
2072 .uleb128 .Letext0-.Ltext0 Range length (*.LLRL2)
2073 Offset Info Type Symbol's Value Symbol's Name + Addend
2074 0000000000000015 0000000200000079 R_LARCH_ADD_ULEB128 0000000000000000 .text + 2
2075 0000000000000015 000000020000007a R_LARCH_SUB_ULEB128 0000000000000000 .text + 0. */
2077 /* Only the ADD_ULEB128 has X_add_number (Addend)? */
2078 exp_dup
->X_add_number
= 0;
2079 exp_dup
->X_add_symbol
= exp
->X_op_symbol
;
2080 fix_new_exp (fragP
, fragP
->fr_fix
, 0,
2081 exp_dup
, 0, BFD_RELOC_LARCH_SUB_ULEB128
);
2086 loongarch_md_finish (void)
2088 /* Insert relocations for uleb128 directives, so the values can be recomputed
2090 if (LARCH_opts
.relax
)
2091 bfd_map_over_sections (stdoutput
, loongarch_insert_uleb128_fixes
, NULL
);
2095 loongarch_elf_final_processing (void)
2097 elf_elfheader (stdoutput
)->e_flags
= LARCH_opts
.ase_abi
;
2100 /* Compute the length of a branch sequence, and adjust the stored length
2101 accordingly. If FRAGP is NULL, the worst-case length is returned. */
2103 loongarch_relaxed_branch_length (fragS
*fragp
, asection
*sec
, int update
)
2110 if (fragp
->fr_symbol
!= NULL
2111 && S_IS_DEFINED (fragp
->fr_symbol
)
2112 && !S_IS_WEAK (fragp
->fr_symbol
)
2113 && sec
== S_GET_SEGMENT (fragp
->fr_symbol
))
2115 offsetT val
= S_GET_VALUE (fragp
->fr_symbol
) + fragp
->fr_offset
;
2117 val
-= fragp
->fr_address
+ fragp
->fr_fix
;
2119 if (RELAX_BRANCH_16
== fragp
->fr_subtype
2120 && OUT_OF_RANGE (val
, 16, 2))
2124 fragp
->fr_subtype
= RELAX_BRANCH_26
;
2127 if (RELAX_BRANCH_21
== fragp
->fr_subtype
2128 && OUT_OF_RANGE (val
, 21, 2))
2132 fragp
->fr_subtype
= RELAX_BRANCH_26
;
2135 if (RELAX_BRANCH_26
== fragp
->fr_subtype
)
2143 loongarch_relax_frag (asection
*sec
, fragS
*fragp
,
2144 long stretch ATTRIBUTE_UNUSED
)
2146 if (RELAX_BRANCH (fragp
->fr_subtype
))
2148 offsetT old_var
= fragp
->fr_var
;
2149 fragp
->fr_var
= loongarch_relaxed_branch_length (fragp
, sec
, true);
2150 return fragp
->fr_var
- old_var
;
2152 else if (rs_align_code
== fragp
->fr_subtype
)
2155 if (NULL
== fragp
->fr_symbol
)
2156 nop_bytes
= fragp
->fr_offset
;
2158 nop_bytes
= ALIGN_MAX_NOP_BYTES (fragp
->fr_offset
);
2160 /* Normally, nop_bytes should be >= 4. */
2161 gas_assert (nop_bytes
> 0);
2163 offsetT old_var
= fragp
->fr_var
;
2164 /* If .align at the start of a section, do nothing. Section alignment
2165 * can ensure correct alignment. */
2166 if (FRAG_AT_START_OF_SECTION (fragp
)
2167 && 0 == ((1 << sec
->alignment_power
) % (nop_bytes
+ 4)))
2170 fragp
->fr_var
= nop_bytes
;
2171 return fragp
->fr_var
- old_var
;
2176 /* Expand far branches to multi-instruction sequences.
2177 Branch instructions:
2178 beq, bne, blt, bgt, bltz, bgtz, ble, bge, blez, bgez
2179 bltu, bgtu, bleu, bgeu
2180 beqz, bnez, bceqz, bcnez. */
2183 loongarch_convert_frag_branch (fragS
*fragp
)
2190 buf
= (bfd_byte
*)fragp
->fr_literal
+ fragp
->fr_fix
;
2192 exp
.X_op
= O_symbol
;
2193 exp
.X_add_symbol
= fragp
->fr_symbol
;
2194 exp
.X_add_number
= fragp
->fr_offset
;
2196 gas_assert ((fragp
->fr_subtype
& 0xf) == fragp
->fr_var
);
2198 /* blt $t0, $t1, .L1
2205 switch (fragp
->fr_subtype
)
2207 case RELAX_BRANCH_26
:
2208 insn
= bfd_getl32 (buf
);
2209 /* Invert the branch condition. */
2210 if (LARCH_INSN_FLOAT_BRANCH(insn
))
2211 insn
^= LARCH_FLOAT_BRANCH_INVERT_BIT
;
2213 insn
^= LARCH_BRANCH_INVERT_BIT
;
2214 insn
|= ENCODE_BRANCH16_IMM (8); /* Set target to PC + 8. */
2215 bfd_putl32 (insn
, buf
);
2218 /* Add the B instruction and jump to the original target. */
2219 bfd_putl32 (LARCH_B
, buf
);
2220 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2221 4, &exp
, false, BFD_RELOC_LARCH_B26
);
2224 case RELAX_BRANCH_21
:
2225 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2226 4, &exp
, false, BFD_RELOC_LARCH_B21
);
2229 case RELAX_BRANCH_16
:
2230 fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2231 4, &exp
, false, BFD_RELOC_LARCH_B16
);
2239 fixp
->fx_file
= fragp
->fr_file
;
2240 fixp
->fx_line
= fragp
->fr_line
;
2242 gas_assert (buf
== (bfd_byte
*)fragp
->fr_literal
2243 + fragp
->fr_fix
+ fragp
->fr_var
);
2245 fragp
->fr_fix
+= fragp
->fr_var
;
2248 /* Relax .align frag. */
2251 loongarch_convert_frag_align (fragS
*fragp
, asection
*sec
)
2253 bfd_byte
*buf
= (bfd_byte
*)fragp
->fr_literal
+ fragp
->fr_fix
;
2256 if (NULL
== fragp
->fr_symbol
)
2257 nop_bytes
= fragp
->fr_offset
;
2259 nop_bytes
= ALIGN_MAX_NOP_BYTES (fragp
->fr_offset
);
2261 /* Normally, nop_bytes should be >= 4. */
2262 gas_assert (nop_bytes
> 0);
2264 if (!(FRAG_AT_START_OF_SECTION (fragp
)
2265 && 0 == ((1 << sec
->alignment_power
) % (nop_bytes
+ 4))))
2268 exp
.X_op
= O_symbol
;
2269 exp
.X_add_symbol
= fragp
->fr_symbol
;
2270 exp
.X_add_number
= fragp
->fr_offset
;
2272 fixS
*fixp
= fix_new_exp (fragp
, buf
- (bfd_byte
*)fragp
->fr_literal
,
2273 nop_bytes
, &exp
, false, BFD_RELOC_LARCH_ALIGN
);
2274 fixp
->fx_file
= fragp
->fr_file
;
2275 fixp
->fx_line
= fragp
->fr_line
;
2280 gas_assert (buf
== (bfd_byte
*)fragp
->fr_literal
2281 + fragp
->fr_fix
+ fragp
->fr_var
);
2283 fragp
->fr_fix
+= fragp
->fr_var
;
2286 /* Relax a machine dependent frag. */
2289 md_convert_frag (bfd
*abfd ATTRIBUTE_UNUSED
, segT asec
, fragS
*fragp
)
2291 gas_assert (RELAX_BRANCH (fragp
->fr_subtype
)
2292 || rs_align_code
== fragp
->fr_subtype
);
2293 if (RELAX_BRANCH (fragp
->fr_subtype
))
2294 loongarch_convert_frag_branch (fragp
);
2295 else if (rs_align_code
== fragp
->fr_subtype
)
2296 loongarch_convert_frag_align (fragp
, asec
);