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