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