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