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