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