xref: /netbsd-src/external/gpl3/gdb.old/dist/bfd/elfxx-riscv.c (revision 6881a4007f077b54e5f51159c52b9b25f57deb0d)
1 /* RISC-V-specific support for ELF.
2    Copyright (C) 2011-2022 Free Software Foundation, Inc.
3 
4    Contributed by Andrew Waterman (andrew@sifive.com).
5    Based on TILE-Gx and MIPS targets.
6 
7    This file is part of BFD, the Binary File Descriptor library.
8 
9    This program is free software; you can redistribute it and/or modify
10    it under the terms of the GNU General Public License as published by
11    the Free Software Foundation; either version 3 of the License, or
12    (at your option) any later version.
13 
14    This program is distributed in the hope that it will be useful,
15    but WITHOUT ANY WARRANTY; without even the implied warranty of
16    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
17    GNU General Public License for more details.
18 
19    You should have received a copy of the GNU General Public License
20    along with this program; see the file COPYING3. If not,
21    see <http://www.gnu.org/licenses/>.  */
22 
23 #include "sysdep.h"
24 #include "bfd.h"
25 #include "libbfd.h"
26 #include "elf-bfd.h"
27 #include "elf/riscv.h"
28 #include "opcode/riscv.h"
29 #include "libiberty.h"
30 #include "elfxx-riscv.h"
31 #include "safe-ctype.h"
32 
33 #define MINUS_ONE ((bfd_vma)0 - 1)
34 
35 /* Special handler for ADD/SUB relocations that allows them to be filled out
36    both in the pre-linked and post-linked file.  This is necessary to make
37    pre-linked debug info work, as due to linker relaxations we need to emit
38    relocations for the debug info.  */
39 static bfd_reloc_status_type riscv_elf_add_sub_reloc
40   (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
41 
42 /* The relocation table used for SHT_RELA sections.  */
43 
44 static reloc_howto_type howto_table[] =
45 {
46   /* No relocation.  */
47   HOWTO (R_RISCV_NONE,			/* type */
48 	 0,				/* rightshift */
49 	 0,				/* size */
50 	 0,				/* bitsize */
51 	 false,				/* pc_relative */
52 	 0,				/* bitpos */
53 	 complain_overflow_dont,	/* complain_on_overflow */
54 	 bfd_elf_generic_reloc,		/* special_function */
55 	 "R_RISCV_NONE",		/* name */
56 	 false,				/* partial_inplace */
57 	 0,				/* src_mask */
58 	 0,				/* dst_mask */
59 	 false),			/* pcrel_offset */
60 
61   /* 32 bit relocation.  */
62   HOWTO (R_RISCV_32,			/* type */
63 	 0,				/* rightshift */
64 	 4,				/* size */
65 	 32,				/* bitsize */
66 	 false,				/* pc_relative */
67 	 0,				/* bitpos */
68 	 complain_overflow_dont,	/* complain_on_overflow */
69 	 bfd_elf_generic_reloc,		/* special_function */
70 	 "R_RISCV_32",			/* name */
71 	 false,				/* partial_inplace */
72 	 0,				/* src_mask */
73 	 0xffffffff,			/* dst_mask */
74 	 false),			/* pcrel_offset */
75 
76   /* 64 bit relocation.  */
77   HOWTO (R_RISCV_64,			/* type */
78 	 0,				/* rightshift */
79 	 8,				/* size */
80 	 64,				/* bitsize */
81 	 false,				/* pc_relative */
82 	 0,				/* bitpos */
83 	 complain_overflow_dont,	/* complain_on_overflow */
84 	 bfd_elf_generic_reloc,		/* special_function */
85 	 "R_RISCV_64",			/* name */
86 	 false,				/* partial_inplace */
87 	 0,				/* src_mask */
88 	 MINUS_ONE,			/* dst_mask */
89 	 false),			/* pcrel_offset */
90 
91   /* Relocation against a local symbol in a shared object.  */
92   HOWTO (R_RISCV_RELATIVE,		/* type */
93 	 0,				/* rightshift */
94 	 4,				/* size */
95 	 32,				/* bitsize */
96 	 false,				/* pc_relative */
97 	 0,				/* bitpos */
98 	 complain_overflow_dont,	/* complain_on_overflow */
99 	 bfd_elf_generic_reloc,		/* special_function */
100 	 "R_RISCV_RELATIVE",		/* name */
101 	 false,				/* partial_inplace */
102 	 0,				/* src_mask */
103 	 0xffffffff,			/* dst_mask */
104 	 false),			/* pcrel_offset */
105 
106   HOWTO (R_RISCV_COPY,			/* type */
107 	 0,				/* rightshift */
108 	 0,				/* this one is variable size */
109 	 0,				/* bitsize */
110 	 false,				/* pc_relative */
111 	 0,				/* bitpos */
112 	 complain_overflow_bitfield,	/* complain_on_overflow */
113 	 bfd_elf_generic_reloc,		/* special_function */
114 	 "R_RISCV_COPY",		/* name */
115 	 false,				/* partial_inplace */
116 	 0,				/* src_mask */
117 	 0,				/* dst_mask */
118 	 false),			/* pcrel_offset */
119 
120   HOWTO (R_RISCV_JUMP_SLOT,		/* type */
121 	 0,				/* rightshift */
122 	 8,				/* size */
123 	 64,				/* bitsize */
124 	 false,				/* pc_relative */
125 	 0,				/* bitpos */
126 	 complain_overflow_bitfield,	/* complain_on_overflow */
127 	 bfd_elf_generic_reloc,		/* special_function */
128 	 "R_RISCV_JUMP_SLOT",		/* name */
129 	 false,				/* partial_inplace */
130 	 0,				/* src_mask */
131 	 0,				/* dst_mask */
132 	 false),			/* pcrel_offset */
133 
134   /* Dynamic TLS relocations.  */
135   HOWTO (R_RISCV_TLS_DTPMOD32,		/* type */
136 	 0,				/* rightshift */
137 	 4,				/* size */
138 	 32,				/* bitsize */
139 	 false,				/* pc_relative */
140 	 0,				/* bitpos */
141 	 complain_overflow_dont,	/* complain_on_overflow */
142 	 bfd_elf_generic_reloc,		/* special_function */
143 	 "R_RISCV_TLS_DTPMOD32",	/* name */
144 	 false,				/* partial_inplace */
145 	 0,				/* src_mask */
146 	 0xffffffff,			/* dst_mask */
147 	 false),			/* pcrel_offset */
148 
149   HOWTO (R_RISCV_TLS_DTPMOD64,		/* type */
150 	 0,				/* rightshift */
151 	 8,				/* size */
152 	 64,				/* bitsize */
153 	 false,				/* pc_relative */
154 	 0,				/* bitpos */
155 	 complain_overflow_dont,	/* complain_on_overflow */
156 	 bfd_elf_generic_reloc,		/* special_function */
157 	 "R_RISCV_TLS_DTPMOD64",	/* name */
158 	 false,				/* partial_inplace */
159 	 0,				/* src_mask */
160 	 MINUS_ONE,			/* dst_mask */
161 	 false),			/* pcrel_offset */
162 
163   HOWTO (R_RISCV_TLS_DTPREL32,		/* type */
164 	 0,				/* rightshift */
165 	 4,				/* size */
166 	 32,				/* bitsize */
167 	 false,				/* pc_relative */
168 	 0,				/* bitpos */
169 	 complain_overflow_dont,	/* complain_on_overflow */
170 	 bfd_elf_generic_reloc,		/* special_function */
171 	 "R_RISCV_TLS_DTPREL32",	/* name */
172 	 true,				/* partial_inplace */
173 	 0,				/* src_mask */
174 	 0xffffffff,			/* dst_mask */
175 	 false),			/* pcrel_offset */
176 
177   HOWTO (R_RISCV_TLS_DTPREL64,		/* type */
178 	 0,				/* rightshift */
179 	 8,				/* size */
180 	 64,				/* bitsize */
181 	 false,				/* pc_relative */
182 	 0,				/* bitpos */
183 	 complain_overflow_dont,	/* complain_on_overflow */
184 	 bfd_elf_generic_reloc,		/* special_function */
185 	 "R_RISCV_TLS_DTPREL64",	/* name */
186 	 true,				/* partial_inplace */
187 	 0,				/* src_mask */
188 	 MINUS_ONE,			/* dst_mask */
189 	 false),			/* pcrel_offset */
190 
191   HOWTO (R_RISCV_TLS_TPREL32,		/* type */
192 	 0,				/* rightshift */
193 	 4,				/* size */
194 	 32,				/* bitsize */
195 	 false,				/* pc_relative */
196 	 0,				/* bitpos */
197 	 complain_overflow_dont,	/* complain_on_overflow */
198 	 bfd_elf_generic_reloc,		/* special_function */
199 	 "R_RISCV_TLS_TPREL32",		/* name */
200 	 false,				/* partial_inplace */
201 	 0,				/* src_mask */
202 	 0xffffffff,			/* dst_mask */
203 	 false),			/* pcrel_offset */
204 
205   HOWTO (R_RISCV_TLS_TPREL64,		/* type */
206 	 0,				/* rightshift */
207 	 8,				/* size */
208 	 64,				/* bitsize */
209 	 false,				/* pc_relative */
210 	 0,				/* bitpos */
211 	 complain_overflow_dont,	/* complain_on_overflow */
212 	 bfd_elf_generic_reloc,		/* special_function */
213 	 "R_RISCV_TLS_TPREL64",		/* name */
214 	 false,				/* partial_inplace */
215 	 0,				/* src_mask */
216 	 MINUS_ONE,			/* dst_mask */
217 	 false),			/* pcrel_offset */
218 
219   /* Reserved for future relocs that the dynamic linker must understand.  */
220   EMPTY_HOWTO (12),
221   EMPTY_HOWTO (13),
222   EMPTY_HOWTO (14),
223   EMPTY_HOWTO (15),
224 
225   /* 12-bit PC-relative branch offset.  */
226   HOWTO (R_RISCV_BRANCH,		/* type */
227 	 0,				/* rightshift */
228 	 4,				/* size */
229 	 32,				/* bitsize */
230 	 true,				/* pc_relative */
231 	 0,				/* bitpos */
232 	 complain_overflow_signed,	/* complain_on_overflow */
233 	 bfd_elf_generic_reloc,		/* special_function */
234 	 "R_RISCV_BRANCH",		/* name */
235 	 false,				/* partial_inplace */
236 	 0,				/* src_mask */
237 	 ENCODE_BTYPE_IMM (-1U),	/* dst_mask */
238 	 true),				/* pcrel_offset */
239 
240   /* 20-bit PC-relative jump offset.  */
241   HOWTO (R_RISCV_JAL,			/* type */
242 	 0,				/* rightshift */
243 	 4,				/* size */
244 	 32,				/* bitsize */
245 	 true,				/* pc_relative */
246 	 0,				/* bitpos */
247 	 complain_overflow_dont,	/* complain_on_overflow */
248 	 bfd_elf_generic_reloc,		/* special_function */
249 	 "R_RISCV_JAL",			/* name */
250 	 false,				/* partial_inplace */
251 	 0,				/* src_mask */
252 	 ENCODE_JTYPE_IMM (-1U),	/* dst_mask */
253 	 true),				/* pcrel_offset */
254 
255   /* 32-bit PC-relative function call (AUIPC/JALR).  */
256   HOWTO (R_RISCV_CALL,			/* type */
257 	 0,				/* rightshift */
258 	 8,				/* size */
259 	 64,				/* bitsize */
260 	 true,				/* pc_relative */
261 	 0,				/* bitpos */
262 	 complain_overflow_dont,	/* complain_on_overflow */
263 	 bfd_elf_generic_reloc,		/* special_function */
264 	 "R_RISCV_CALL",		/* name */
265 	 false,				/* partial_inplace */
266 	 0,				/* src_mask */
267 	 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
268 					/* dst_mask */
269 	 true),				/* pcrel_offset */
270 
271   /* Like R_RISCV_CALL, but not locally binding.  */
272   HOWTO (R_RISCV_CALL_PLT,		/* type */
273 	 0,				/* rightshift */
274 	 8,				/* size */
275 	 64,				/* bitsize */
276 	 true,				/* pc_relative */
277 	 0,				/* bitpos */
278 	 complain_overflow_dont,	/* complain_on_overflow */
279 	 bfd_elf_generic_reloc,		/* special_function */
280 	 "R_RISCV_CALL_PLT",		/* name */
281 	 false,				/* partial_inplace */
282 	 0,				/* src_mask */
283 	 ENCODE_UTYPE_IMM (-1U) | ((bfd_vma) ENCODE_ITYPE_IMM (-1U) << 32),
284 					/* dst_mask */
285 	 true),				/* pcrel_offset */
286 
287   /* High 20 bits of 32-bit PC-relative GOT access.  */
288   HOWTO (R_RISCV_GOT_HI20,		/* type */
289 	 0,				/* rightshift */
290 	 4,				/* size */
291 	 32,				/* bitsize */
292 	 true,				/* pc_relative */
293 	 0,				/* bitpos */
294 	 complain_overflow_dont,	/* complain_on_overflow */
295 	 bfd_elf_generic_reloc,		/* special_function */
296 	 "R_RISCV_GOT_HI20",		/* name */
297 	 false,				/* partial_inplace */
298 	 0,				/* src_mask */
299 	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
300 	 false),			/* pcrel_offset */
301 
302   /* High 20 bits of 32-bit PC-relative TLS IE GOT access.  */
303   HOWTO (R_RISCV_TLS_GOT_HI20,		/* type */
304 	 0,				/* rightshift */
305 	 4,				/* size */
306 	 32,				/* bitsize */
307 	 true,				/* pc_relative */
308 	 0,				/* bitpos */
309 	 complain_overflow_dont,	/* complain_on_overflow */
310 	 bfd_elf_generic_reloc,		/* special_function */
311 	 "R_RISCV_TLS_GOT_HI20",	/* name */
312 	 false,				/* partial_inplace */
313 	 0,				/* src_mask */
314 	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
315 	 false),			/* pcrel_offset */
316 
317   /* High 20 bits of 32-bit PC-relative TLS GD GOT reference.  */
318   HOWTO (R_RISCV_TLS_GD_HI20,		/* type */
319 	 0,				/* rightshift */
320 	 4,				/* size */
321 	 32,				/* bitsize */
322 	 true,				/* pc_relative */
323 	 0,				/* bitpos */
324 	 complain_overflow_dont,	/* complain_on_overflow */
325 	 bfd_elf_generic_reloc,		/* special_function */
326 	 "R_RISCV_TLS_GD_HI20",		/* name */
327 	 false,				/* partial_inplace */
328 	 0,				/* src_mask */
329 	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
330 	 false),			/* pcrel_offset */
331 
332   /* High 20 bits of 32-bit PC-relative reference.  */
333   HOWTO (R_RISCV_PCREL_HI20,		/* type */
334 	 0,				/* rightshift */
335 	 4,				/* size */
336 	 32,				/* bitsize */
337 	 true,				/* pc_relative */
338 	 0,				/* bitpos */
339 	 complain_overflow_dont,	/* complain_on_overflow */
340 	 bfd_elf_generic_reloc,		/* special_function */
341 	 "R_RISCV_PCREL_HI20",		/* name */
342 	 false,				/* partial_inplace */
343 	 0,				/* src_mask */
344 	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
345 	 true),				/* pcrel_offset */
346 
347   /* Low 12 bits of a 32-bit PC-relative load or add.  */
348   HOWTO (R_RISCV_PCREL_LO12_I,		/* type */
349 	 0,				/* rightshift */
350 	 4,				/* size */
351 	 32,				/* bitsize */
352 	 false,				/* pc_relative */
353 	 0,				/* bitpos */
354 	 complain_overflow_dont,	/* complain_on_overflow */
355 	 bfd_elf_generic_reloc,		/* special_function */
356 	 "R_RISCV_PCREL_LO12_I",	/* name */
357 	 false,				/* partial_inplace */
358 	 0,				/* src_mask */
359 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
360 	 false),			/* pcrel_offset */
361 
362   /* Low 12 bits of a 32-bit PC-relative store.  */
363   HOWTO (R_RISCV_PCREL_LO12_S,		/* type */
364 	 0,				/* rightshift */
365 	 4,				/* size */
366 	 32,				/* bitsize */
367 	 false,				/* pc_relative */
368 	 0,				/* bitpos */
369 	 complain_overflow_dont,	/* complain_on_overflow */
370 	 bfd_elf_generic_reloc,		/* special_function */
371 	 "R_RISCV_PCREL_LO12_S",	/* name */
372 	 false,				/* partial_inplace */
373 	 0,				/* src_mask */
374 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
375 	 false),			/* pcrel_offset */
376 
377   /* High 20 bits of 32-bit absolute address.  */
378   HOWTO (R_RISCV_HI20,			/* type */
379 	 0,				/* rightshift */
380 	 4,				/* size */
381 	 32,				/* bitsize */
382 	 false,				/* pc_relative */
383 	 0,				/* bitpos */
384 	 complain_overflow_dont,	/* complain_on_overflow */
385 	 bfd_elf_generic_reloc,		/* special_function */
386 	 "R_RISCV_HI20",		/* name */
387 	 false,				/* partial_inplace */
388 	 0,				/* src_mask */
389 	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
390 	 false),			/* pcrel_offset */
391 
392   /* High 12 bits of 32-bit load or add.  */
393   HOWTO (R_RISCV_LO12_I,		/* type */
394 	 0,				/* rightshift */
395 	 4,				/* size */
396 	 32,				/* bitsize */
397 	 false,				/* pc_relative */
398 	 0,				/* bitpos */
399 	 complain_overflow_dont,	/* complain_on_overflow */
400 	 bfd_elf_generic_reloc,		/* special_function */
401 	 "R_RISCV_LO12_I",		/* name */
402 	 false,				/* partial_inplace */
403 	 0,				/* src_mask */
404 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
405 	 false),			/* pcrel_offset */
406 
407   /* High 12 bits of 32-bit store.  */
408   HOWTO (R_RISCV_LO12_S,		/* type */
409 	 0,				/* rightshift */
410 	 4,				/* size */
411 	 32,				/* bitsize */
412 	 false,				/* pc_relative */
413 	 0,				/* bitpos */
414 	 complain_overflow_dont,	/* complain_on_overflow */
415 	 bfd_elf_generic_reloc,		/* special_function */
416 	 "R_RISCV_LO12_S",		/* name */
417 	 false,				/* partial_inplace */
418 	 0,				/* src_mask */
419 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
420 	 false),			/* pcrel_offset */
421 
422   /* High 20 bits of TLS LE thread pointer offset.  */
423   HOWTO (R_RISCV_TPREL_HI20,		/* type */
424 	 0,				/* rightshift */
425 	 4,				/* size */
426 	 32,				/* bitsize */
427 	 false,				/* pc_relative */
428 	 0,				/* bitpos */
429 	 complain_overflow_signed,	/* complain_on_overflow */
430 	 bfd_elf_generic_reloc,		/* special_function */
431 	 "R_RISCV_TPREL_HI20",		/* name */
432 	 true,				/* partial_inplace */
433 	 0,				/* src_mask */
434 	 ENCODE_UTYPE_IMM (-1U),	/* dst_mask */
435 	 false),			/* pcrel_offset */
436 
437   /* Low 12 bits of TLS LE thread pointer offset for loads and adds.  */
438   HOWTO (R_RISCV_TPREL_LO12_I,		/* type */
439 	 0,				/* rightshift */
440 	 4,				/* size */
441 	 32,				/* bitsize */
442 	 false,				/* pc_relative */
443 	 0,				/* bitpos */
444 	 complain_overflow_signed,	/* complain_on_overflow */
445 	 bfd_elf_generic_reloc,		/* special_function */
446 	 "R_RISCV_TPREL_LO12_I",	/* name */
447 	 false,				/* partial_inplace */
448 	 0,				/* src_mask */
449 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
450 	 false),			/* pcrel_offset */
451 
452   /* Low 12 bits of TLS LE thread pointer offset for stores.  */
453   HOWTO (R_RISCV_TPREL_LO12_S,		/* type */
454 	 0,				/* rightshift */
455 	 4,				/* size */
456 	 32,				/* bitsize */
457 	 false,				/* pc_relative */
458 	 0,				/* bitpos */
459 	 complain_overflow_signed,	/* complain_on_overflow */
460 	 bfd_elf_generic_reloc,		/* special_function */
461 	 "R_RISCV_TPREL_LO12_S",	/* name */
462 	 false,				/* partial_inplace */
463 	 0,				/* src_mask */
464 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
465 	 false),			/* pcrel_offset */
466 
467   /* TLS LE thread pointer usage.  May be relaxed.  */
468   HOWTO (R_RISCV_TPREL_ADD,		/* type */
469 	 0,				/* rightshift */
470 	 0,				/* size */
471 	 0,				/* bitsize */
472 	 false,				/* pc_relative */
473 	 0,				/* bitpos */
474 	 complain_overflow_dont,	/* complain_on_overflow */
475 	 bfd_elf_generic_reloc,		/* special_function */
476 	 "R_RISCV_TPREL_ADD",		/* name */
477 	 false,				/* partial_inplace */
478 	 0,				/* src_mask */
479 	 0,				/* dst_mask */
480 	 false),			/* pcrel_offset */
481 
482   /* 8-bit in-place addition, for local label subtraction.  */
483   HOWTO (R_RISCV_ADD8,			/* type */
484 	 0,				/* rightshift */
485 	 1,				/* size */
486 	 8,				/* bitsize */
487 	 false,				/* pc_relative */
488 	 0,				/* bitpos */
489 	 complain_overflow_dont,	/* complain_on_overflow */
490 	 riscv_elf_add_sub_reloc,	/* special_function */
491 	 "R_RISCV_ADD8",		/* name */
492 	 false,				/* partial_inplace */
493 	 0,				/* src_mask */
494 	 0xff,				/* dst_mask */
495 	 false),			/* pcrel_offset */
496 
497   /* 16-bit in-place addition, for local label subtraction.  */
498   HOWTO (R_RISCV_ADD16,			/* type */
499 	 0,				/* rightshift */
500 	 2,				/* size */
501 	 16,				/* bitsize */
502 	 false,				/* pc_relative */
503 	 0,				/* bitpos */
504 	 complain_overflow_dont,	/* complain_on_overflow */
505 	 riscv_elf_add_sub_reloc,	/* special_function */
506 	 "R_RISCV_ADD16",		/* name */
507 	 false,				/* partial_inplace */
508 	 0,				/* src_mask */
509 	 0xffff,			/* dst_mask */
510 	 false),			/* pcrel_offset */
511 
512   /* 32-bit in-place addition, for local label subtraction.  */
513   HOWTO (R_RISCV_ADD32,			/* type */
514 	 0,				/* rightshift */
515 	 4,				/* size */
516 	 32,				/* bitsize */
517 	 false,				/* pc_relative */
518 	 0,				/* bitpos */
519 	 complain_overflow_dont,	/* complain_on_overflow */
520 	 riscv_elf_add_sub_reloc,	/* special_function */
521 	 "R_RISCV_ADD32",		/* name */
522 	 false,				/* partial_inplace */
523 	 0,				/* src_mask */
524 	 0xffffffff,			/* dst_mask */
525 	 false),			/* pcrel_offset */
526 
527   /* 64-bit in-place addition, for local label subtraction.  */
528   HOWTO (R_RISCV_ADD64,			/* type */
529 	 0,				/* rightshift */
530 	 8,				/* size */
531 	 64,				/* bitsize */
532 	 false,				/* pc_relative */
533 	 0,				/* bitpos */
534 	 complain_overflow_dont,	/* complain_on_overflow */
535 	 riscv_elf_add_sub_reloc,	/* special_function */
536 	 "R_RISCV_ADD64",		/* name */
537 	 false,				/* partial_inplace */
538 	 0,				/* src_mask */
539 	 MINUS_ONE,			/* dst_mask */
540 	 false),			/* pcrel_offset */
541 
542   /* 8-bit in-place addition, for local label subtraction.  */
543   HOWTO (R_RISCV_SUB8,			/* type */
544 	 0,				/* rightshift */
545 	 1,				/* size */
546 	 8,				/* bitsize */
547 	 false,				/* pc_relative */
548 	 0,				/* bitpos */
549 	 complain_overflow_dont,	/* complain_on_overflow */
550 	 riscv_elf_add_sub_reloc,	/* special_function */
551 	 "R_RISCV_SUB8",		/* name */
552 	 false,				/* partial_inplace */
553 	 0,				/* src_mask */
554 	 0xff,				/* dst_mask */
555 	 false),			/* pcrel_offset */
556 
557   /* 16-bit in-place addition, for local label subtraction.  */
558   HOWTO (R_RISCV_SUB16,			/* type */
559 	 0,				/* rightshift */
560 	 2,				/* size */
561 	 16,				/* bitsize */
562 	 false,				/* pc_relative */
563 	 0,				/* bitpos */
564 	 complain_overflow_dont,	/* complain_on_overflow */
565 	 riscv_elf_add_sub_reloc,	/* special_function */
566 	 "R_RISCV_SUB16",		/* name */
567 	 false,				/* partial_inplace */
568 	 0,				/* src_mask */
569 	 0xffff,			/* dst_mask */
570 	 false),			/* pcrel_offset */
571 
572   /* 32-bit in-place addition, for local label subtraction.  */
573   HOWTO (R_RISCV_SUB32,			/* type */
574 	 0,				/* rightshift */
575 	 4,				/* size */
576 	 32,				/* bitsize */
577 	 false,				/* pc_relative */
578 	 0,				/* bitpos */
579 	 complain_overflow_dont,	/* complain_on_overflow */
580 	 riscv_elf_add_sub_reloc,	/* special_function */
581 	 "R_RISCV_SUB32",		/* name */
582 	 false,				/* partial_inplace */
583 	 0,				/* src_mask */
584 	 0xffffffff,			/* dst_mask */
585 	 false),			/* pcrel_offset */
586 
587   /* 64-bit in-place addition, for local label subtraction.  */
588   HOWTO (R_RISCV_SUB64,			/* type */
589 	 0,				/* rightshift */
590 	 8,				/* size */
591 	 64,				/* bitsize */
592 	 false,				/* pc_relative */
593 	 0,				/* bitpos */
594 	 complain_overflow_dont,	/* complain_on_overflow */
595 	 riscv_elf_add_sub_reloc,	/* special_function */
596 	 "R_RISCV_SUB64",		/* name */
597 	 false,				/* partial_inplace */
598 	 0,				/* src_mask */
599 	 MINUS_ONE,			/* dst_mask */
600 	 false),			/* pcrel_offset */
601 
602   /* 41 and 42 are reserved.  */
603   EMPTY_HOWTO (0),
604   EMPTY_HOWTO (0),
605 
606   /* Indicates an alignment statement.  The addend field encodes how many
607      bytes of NOPs follow the statement.  The desired alignment is the
608      addend rounded up to the next power of two.  */
609   HOWTO (R_RISCV_ALIGN,			/* type */
610 	 0,				/* rightshift */
611 	 0,				/* size */
612 	 0,				/* bitsize */
613 	 false,				/* pc_relative */
614 	 0,				/* bitpos */
615 	 complain_overflow_dont,	/* complain_on_overflow */
616 	 bfd_elf_generic_reloc,		/* special_function */
617 	 "R_RISCV_ALIGN",		/* name */
618 	 false,				/* partial_inplace */
619 	 0,				/* src_mask */
620 	 0,				/* dst_mask */
621 	 false),			/* pcrel_offset */
622 
623   /* 8-bit PC-relative branch offset.  */
624   HOWTO (R_RISCV_RVC_BRANCH,		/* type */
625 	 0,				/* rightshift */
626 	 2,				/* size */
627 	 16,				/* bitsize */
628 	 true,				/* pc_relative */
629 	 0,				/* bitpos */
630 	 complain_overflow_signed,	/* complain_on_overflow */
631 	 bfd_elf_generic_reloc,		/* special_function */
632 	 "R_RISCV_RVC_BRANCH",		/* name */
633 	 false,				/* partial_inplace */
634 	 0,				/* src_mask */
635 	 ENCODE_CBTYPE_IMM (-1U),	/* dst_mask */
636 	 true),				/* pcrel_offset */
637 
638   /* 11-bit PC-relative jump offset.  */
639   HOWTO (R_RISCV_RVC_JUMP,		/* type */
640 	 0,				/* rightshift */
641 	 2,				/* size */
642 	 16,				/* bitsize */
643 	 true,				/* pc_relative */
644 	 0,				/* bitpos */
645 	 complain_overflow_dont,	/* complain_on_overflow */
646 	 bfd_elf_generic_reloc,		/* special_function */
647 	 "R_RISCV_RVC_JUMP",		/* name */
648 	 false,				/* partial_inplace */
649 	 0,				/* src_mask */
650 	 ENCODE_CJTYPE_IMM (-1U),	/* dst_mask */
651 	 true),				/* pcrel_offset */
652 
653   /* High 6 bits of 18-bit absolute address.  */
654   HOWTO (R_RISCV_RVC_LUI,		/* type */
655 	 0,				/* rightshift */
656 	 2,				/* size */
657 	 16,				/* bitsize */
658 	 false,				/* pc_relative */
659 	 0,				/* bitpos */
660 	 complain_overflow_dont,	/* complain_on_overflow */
661 	 bfd_elf_generic_reloc,		/* special_function */
662 	 "R_RISCV_RVC_LUI",		/* name */
663 	 false,				/* partial_inplace */
664 	 0,				/* src_mask */
665 	 ENCODE_CITYPE_IMM (-1U),	/* dst_mask */
666 	 false),			/* pcrel_offset */
667 
668   /* GP-relative load.  */
669   HOWTO (R_RISCV_GPREL_I,		/* type */
670 	 0,				/* rightshift */
671 	 4,				/* size */
672 	 32,				/* bitsize */
673 	 false,				/* pc_relative */
674 	 0,				/* bitpos */
675 	 complain_overflow_dont,	/* complain_on_overflow */
676 	 bfd_elf_generic_reloc,		/* special_function */
677 	 "R_RISCV_GPREL_I",		/* name */
678 	 false,				/* partial_inplace */
679 	 0,				/* src_mask */
680 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
681 	 false),			/* pcrel_offset */
682 
683   /* GP-relative store.  */
684   HOWTO (R_RISCV_GPREL_S,		/* type */
685 	 0,				/* rightshift */
686 	 4,				/* size */
687 	 32,				/* bitsize */
688 	 false,				/* pc_relative */
689 	 0,				/* bitpos */
690 	 complain_overflow_dont,	/* complain_on_overflow */
691 	 bfd_elf_generic_reloc,		/* special_function */
692 	 "R_RISCV_GPREL_S",		/* name */
693 	 false,				/* partial_inplace */
694 	 0,				/* src_mask */
695 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
696 	 false),			/* pcrel_offset */
697 
698   /* TP-relative TLS LE load.  */
699   HOWTO (R_RISCV_TPREL_I,		/* type */
700 	 0,				/* rightshift */
701 	 4,				/* size */
702 	 32,				/* bitsize */
703 	 false,				/* pc_relative */
704 	 0,				/* bitpos */
705 	 complain_overflow_signed,	/* complain_on_overflow */
706 	 bfd_elf_generic_reloc,		/* special_function */
707 	 "R_RISCV_TPREL_I",		/* name */
708 	 false,				/* partial_inplace */
709 	 0,				/* src_mask */
710 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
711 	 false),			/* pcrel_offset */
712 
713   /* TP-relative TLS LE store.  */
714   HOWTO (R_RISCV_TPREL_S,		/* type */
715 	 0,				/* rightshift */
716 	 4,				/* size */
717 	 32,				/* bitsize */
718 	 false,				/* pc_relative */
719 	 0,				/* bitpos */
720 	 complain_overflow_signed,	/* complain_on_overflow */
721 	 bfd_elf_generic_reloc,		/* special_function */
722 	 "R_RISCV_TPREL_S",		/* name */
723 	 false,				/* partial_inplace */
724 	 0,				/* src_mask */
725 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
726 	 false),			/* pcrel_offset */
727 
728   /* The paired relocation may be relaxed.  */
729   HOWTO (R_RISCV_RELAX,			/* type */
730 	 0,				/* rightshift */
731 	 0,				/* size */
732 	 0,				/* bitsize */
733 	 false,				/* pc_relative */
734 	 0,				/* bitpos */
735 	 complain_overflow_dont,	/* complain_on_overflow */
736 	 bfd_elf_generic_reloc,		/* special_function */
737 	 "R_RISCV_RELAX",		/* name */
738 	 false,				/* partial_inplace */
739 	 0,				/* src_mask */
740 	 0,				/* dst_mask */
741 	 false),			/* pcrel_offset */
742 
743   /* 6-bit in-place addition, for local label subtraction.  */
744   HOWTO (R_RISCV_SUB6,			/* type */
745 	 0,				/* rightshift */
746 	 1,				/* size */
747 	 8,				/* bitsize */
748 	 false,				/* pc_relative */
749 	 0,				/* bitpos */
750 	 complain_overflow_dont,	/* complain_on_overflow */
751 	 riscv_elf_add_sub_reloc,	/* special_function */
752 	 "R_RISCV_SUB6",		/* name */
753 	 false,				/* partial_inplace */
754 	 0,				/* src_mask */
755 	 0x3f,				/* dst_mask */
756 	 false),			/* pcrel_offset */
757 
758   /* 6-bit in-place setting, for local label subtraction.  */
759   HOWTO (R_RISCV_SET6,			/* type */
760 	 0,				/* rightshift */
761 	 1,				/* size */
762 	 8,				/* bitsize */
763 	 false,				/* pc_relative */
764 	 0,				/* bitpos */
765 	 complain_overflow_dont,	/* complain_on_overflow */
766 	 bfd_elf_generic_reloc,		/* special_function */
767 	 "R_RISCV_SET6",		/* name */
768 	 false,				/* partial_inplace */
769 	 0,				/* src_mask */
770 	 0x3f,				/* dst_mask */
771 	 false),			/* pcrel_offset */
772 
773   /* 8-bit in-place setting, for local label subtraction.  */
774   HOWTO (R_RISCV_SET8,			/* type */
775 	 0,				/* rightshift */
776 	 1,				/* size */
777 	 8,				/* bitsize */
778 	 false,				/* pc_relative */
779 	 0,				/* bitpos */
780 	 complain_overflow_dont,	/* complain_on_overflow */
781 	 bfd_elf_generic_reloc,		/* special_function */
782 	 "R_RISCV_SET8",		/* name */
783 	 false,				/* partial_inplace */
784 	 0,				/* src_mask */
785 	 0xff,				/* dst_mask */
786 	 false),			/* pcrel_offset */
787 
788   /* 16-bit in-place setting, for local label subtraction.  */
789   HOWTO (R_RISCV_SET16,			/* type */
790 	 0,				/* rightshift */
791 	 2,				/* size */
792 	 16,				/* bitsize */
793 	 false,				/* pc_relative */
794 	 0,				/* bitpos */
795 	 complain_overflow_dont,	/* complain_on_overflow */
796 	 bfd_elf_generic_reloc,		/* special_function */
797 	 "R_RISCV_SET16",		/* name */
798 	 false,				/* partial_inplace */
799 	 0,				/* src_mask */
800 	 0xffff,			/* dst_mask */
801 	 false),			/* pcrel_offset */
802 
803   /* 32-bit in-place setting, for local label subtraction.  */
804   HOWTO (R_RISCV_SET32,			/* type */
805 	 0,				/* rightshift */
806 	 4,				/* size */
807 	 32,				/* bitsize */
808 	 false,				/* pc_relative */
809 	 0,				/* bitpos */
810 	 complain_overflow_dont,	/* complain_on_overflow */
811 	 bfd_elf_generic_reloc,		/* special_function */
812 	 "R_RISCV_SET32",		/* name */
813 	 false,				/* partial_inplace */
814 	 0,				/* src_mask */
815 	 0xffffffff,			/* dst_mask */
816 	 false),			/* pcrel_offset */
817 
818   /* 32-bit PC relative.  */
819   HOWTO (R_RISCV_32_PCREL,		/* type */
820 	 0,				/* rightshift */
821 	 4,				/* size */
822 	 32,				/* bitsize */
823 	 true,				/* pc_relative */
824 	 0,				/* bitpos */
825 	 complain_overflow_dont,	/* complain_on_overflow */
826 	 bfd_elf_generic_reloc,		/* special_function */
827 	 "R_RISCV_32_PCREL",		/* name */
828 	 false,				/* partial_inplace */
829 	 0,				/* src_mask */
830 	 0xffffffff,			/* dst_mask */
831 	 false),			/* pcrel_offset */
832 
833   /* Relocation against a local ifunc symbol in a shared object.  */
834   HOWTO (R_RISCV_IRELATIVE,		/* type */
835 	 0,				/* rightshift */
836 	 4,				/* size */
837 	 32,				/* bitsize */
838 	 false,				/* pc_relative */
839 	 0,				/* bitpos */
840 	 complain_overflow_dont,	/* complain_on_overflow */
841 	 bfd_elf_generic_reloc,		/* special_function */
842 	 "R_RISCV_IRELATIVE",		/* name */
843 	 false,				/* partial_inplace */
844 	 0,				/* src_mask */
845 	 0xffffffff,			/* dst_mask */
846 	 false),			/* pcrel_offset */
847 };
848 
849 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
850 struct elf_reloc_map
851 {
852   bfd_reloc_code_real_type bfd_val;
853   enum elf_riscv_reloc_type elf_val;
854 };
855 
856 static const struct elf_reloc_map riscv_reloc_map[] =
857 {
858   { BFD_RELOC_NONE, R_RISCV_NONE },
859   { BFD_RELOC_32, R_RISCV_32 },
860   { BFD_RELOC_64, R_RISCV_64 },
861   { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
862   { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
863   { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
864   { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
865   { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
866   { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
867   { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
868   { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
869   { BFD_RELOC_CTOR, R_RISCV_64 },
870   { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
871   { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
872   { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
873   { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
874   { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
875   { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
876   { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
877   { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
878   { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
879   { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
880   { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
881   { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
882   { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
883   { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
884   { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
885   { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
886   { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
887   { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
888   { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
889   { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
890   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
891   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
892   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
893   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
894   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
895   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
896   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
897   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
898   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
899   { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
900   { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
901   { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
902   { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
903   { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
904   { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
905   { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
906   { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
907   { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
908 };
909 
910 /* Given a BFD reloc type, return a howto structure.  */
911 
912 reloc_howto_type *
913 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
914 			 bfd_reloc_code_real_type code)
915 {
916   unsigned int i;
917 
918   for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
919     if (riscv_reloc_map[i].bfd_val == code)
920       return &howto_table[(int) riscv_reloc_map[i].elf_val];
921 
922   bfd_set_error (bfd_error_bad_value);
923   return NULL;
924 }
925 
926 reloc_howto_type *
927 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
928 {
929   unsigned int i;
930 
931   for (i = 0; i < ARRAY_SIZE (howto_table); i++)
932     if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
933       return &howto_table[i];
934 
935   return NULL;
936 }
937 
938 reloc_howto_type *
939 riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
940 {
941   if (r_type >= ARRAY_SIZE (howto_table))
942     {
943       (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
944 			     abfd, r_type);
945       bfd_set_error (bfd_error_bad_value);
946       return NULL;
947     }
948   return &howto_table[r_type];
949 }
950 
951 /* Special_function of RISCV_ADD and RISCV_SUB relocations.  */
952 
953 static bfd_reloc_status_type
954 riscv_elf_add_sub_reloc (bfd *abfd,
955 			 arelent *reloc_entry,
956 			 asymbol *symbol,
957 			 void *data,
958 			 asection *input_section,
959 			 bfd *output_bfd,
960 			 char **error_message ATTRIBUTE_UNUSED)
961 {
962   reloc_howto_type *howto = reloc_entry->howto;
963   bfd_vma relocation;
964 
965   if (output_bfd != NULL
966       && (symbol->flags & BSF_SECTION_SYM) == 0
967       && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
968     {
969       reloc_entry->address += input_section->output_offset;
970       return bfd_reloc_ok;
971     }
972 
973   if (output_bfd != NULL)
974     return bfd_reloc_continue;
975 
976   relocation = symbol->value + symbol->section->output_section->vma
977     + symbol->section->output_offset + reloc_entry->addend;
978 
979   bfd_size_type octets = reloc_entry->address
980     * bfd_octets_per_byte (abfd, input_section);
981   if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
982 				  input_section, octets))
983     return bfd_reloc_outofrange;
984 
985   bfd_vma old_value = bfd_get (howto->bitsize, abfd,
986 			       data + reloc_entry->address);
987 
988   switch (howto->type)
989     {
990     case R_RISCV_ADD8:
991     case R_RISCV_ADD16:
992     case R_RISCV_ADD32:
993     case R_RISCV_ADD64:
994       relocation = old_value + relocation;
995       break;
996     case R_RISCV_SUB6:
997       relocation = (old_value & ~howto->dst_mask)
998 		   | (((old_value & howto->dst_mask) - relocation)
999 		      & howto->dst_mask);
1000       break;
1001     case R_RISCV_SUB8:
1002     case R_RISCV_SUB16:
1003     case R_RISCV_SUB32:
1004     case R_RISCV_SUB64:
1005       relocation = old_value - relocation;
1006       break;
1007     }
1008   bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
1009 
1010   return bfd_reloc_ok;
1011 }
1012 
1013 /* Always add the IMPLICIT for the SUBSET.  */
1014 
1015 static bool
1016 check_implicit_always (const char *implicit ATTRIBUTE_UNUSED,
1017 		       riscv_subset_t *subset ATTRIBUTE_UNUSED)
1018 {
1019   return true;
1020 }
1021 
1022 /* Add the IMPLICIT only when the version of SUBSET less than 2.1.  */
1023 
1024 static bool
1025 check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED,
1026 		      riscv_subset_t *subset)
1027 {
1028   return (subset->major_version < 2
1029 	  || (subset->major_version == 2
1030 	      && subset->minor_version < 1));
1031 }
1032 
1033 /* Record all implicit information for the subsets.  */
1034 struct riscv_implicit_subset
1035 {
1036   const char *subset_name;
1037   const char *implicit_name;
1038   /* A function to determine if we need to add the implicit subset.  */
1039   bool (*check_func) (const char *, riscv_subset_t *);
1040 };
1041 static struct riscv_implicit_subset riscv_implicit_subsets[] =
1042 {
1043   {"e", "i",		check_implicit_always},
1044   {"i", "zicsr",	check_implicit_for_i},
1045   {"i", "zifencei",	check_implicit_for_i},
1046   {"g", "i",		check_implicit_always},
1047   {"g", "m",		check_implicit_always},
1048   {"g", "a",		check_implicit_always},
1049   {"g", "f",		check_implicit_always},
1050   {"g", "d",		check_implicit_always},
1051   {"g", "zicsr",	check_implicit_always},
1052   {"g", "zifencei",	check_implicit_always},
1053   {"m", "zmmul",	check_implicit_always},
1054   {"h", "zicsr",	check_implicit_always},
1055   {"q", "d",		check_implicit_always},
1056   {"v", "d",		check_implicit_always},
1057   {"v", "zve64d",	check_implicit_always},
1058   {"v", "zvl128b",	check_implicit_always},
1059   {"zve64d", "d",	check_implicit_always},
1060   {"zve64d", "zve64f",	check_implicit_always},
1061   {"zve64f", "zve32f",	check_implicit_always},
1062   {"zve64f", "zve64x",	check_implicit_always},
1063   {"zve64f", "zvl64b",	check_implicit_always},
1064   {"zve32f", "f",	check_implicit_always},
1065   {"zve32f", "zvl32b",	check_implicit_always},
1066   {"zve32f", "zve32x",	check_implicit_always},
1067   {"zve64x", "zve32x",	check_implicit_always},
1068   {"zve64x", "zvl64b",	check_implicit_always},
1069   {"zve32x", "zvl32b",	check_implicit_always},
1070   {"zvl65536b", "zvl32768b",	check_implicit_always},
1071   {"zvl32768b", "zvl16384b",	check_implicit_always},
1072   {"zvl16384b", "zvl8192b",	check_implicit_always},
1073   {"zvl8192b", "zvl4096b",	check_implicit_always},
1074   {"zvl4096b", "zvl2048b",	check_implicit_always},
1075   {"zvl2048b", "zvl1024b",	check_implicit_always},
1076   {"zvl1024b", "zvl512b",	check_implicit_always},
1077   {"zvl512b", "zvl256b",	check_implicit_always},
1078   {"zvl256b", "zvl128b",	check_implicit_always},
1079   {"zvl128b", "zvl64b",		check_implicit_always},
1080   {"zvl64b", "zvl32b",		check_implicit_always},
1081   {"d", "f",		check_implicit_always},
1082   {"zfh", "zfhmin",	check_implicit_always},
1083   {"zfhmin", "f",	check_implicit_always},
1084   {"f", "zicsr",	check_implicit_always},
1085   {"zqinx", "zdinx",	check_implicit_always},
1086   {"zdinx", "zfinx",	check_implicit_always},
1087   {"zhinx", "zhinxmin",	check_implicit_always},
1088   {"zhinxmin", "zfinx",	check_implicit_always},
1089   {"zfinx", "zicsr",	check_implicit_always},
1090   {"zk", "zkn",		check_implicit_always},
1091   {"zk", "zkr",		check_implicit_always},
1092   {"zk", "zkt",		check_implicit_always},
1093   {"zkn", "zbkb",	check_implicit_always},
1094   {"zkn", "zbkc",	check_implicit_always},
1095   {"zkn", "zbkx",	check_implicit_always},
1096   {"zkn", "zkne",	check_implicit_always},
1097   {"zkn", "zknd",	check_implicit_always},
1098   {"zkn", "zknh",	check_implicit_always},
1099   {"zks", "zbkb",	check_implicit_always},
1100   {"zks", "zbkc",	check_implicit_always},
1101   {"zks", "zbkx",	check_implicit_always},
1102   {"zks", "zksed",	check_implicit_always},
1103   {"zks", "zksh",	check_implicit_always},
1104   {"smaia", "ssaia",		check_implicit_always},
1105   {"smstateen", "ssstateen",	check_implicit_always},
1106   {"smepmp", "zicsr",		check_implicit_always},
1107   {"ssaia", "zicsr",		check_implicit_always},
1108   {"sscofpmf", "zicsr",		check_implicit_always},
1109   {"ssstateen", "zicsr",	check_implicit_always},
1110   {"sstc", "zicsr",		check_implicit_always},
1111   {NULL, NULL, NULL}
1112 };
1113 
1114 /* For default_enable field, decide if the extension should
1115    be enbaled by default.  */
1116 
1117 #define EXT_DEFAULT   0x1
1118 
1119 /* List all extensions that binutils should know about.  */
1120 
1121 struct riscv_supported_ext
1122 {
1123   const char *name;
1124   enum riscv_spec_class isa_spec_class;
1125   int major_version;
1126   int minor_version;
1127   unsigned long default_enable;
1128 };
1129 
1130 /* The standard extensions must be added in canonical order.  */
1131 
1132 static struct riscv_supported_ext riscv_supported_std_ext[] =
1133 {
1134   {"e",		ISA_SPEC_CLASS_20191213,	1, 9, 0 },
1135   {"e",		ISA_SPEC_CLASS_20190608,	1, 9, 0 },
1136   {"e",		ISA_SPEC_CLASS_2P2,		1, 9, 0 },
1137   {"i",		ISA_SPEC_CLASS_20191213,	2, 1, 0 },
1138   {"i",		ISA_SPEC_CLASS_20190608,	2, 1, 0 },
1139   {"i",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1140   /* The g is a special case which we don't want to output it,
1141      but still need it when adding implicit extensions.  */
1142   {"g",		ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
1143   {"m",		ISA_SPEC_CLASS_20191213,	2, 0, 0 },
1144   {"m",		ISA_SPEC_CLASS_20190608,	2, 0, 0 },
1145   {"m",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1146   {"a",		ISA_SPEC_CLASS_20191213,	2, 1, 0 },
1147   {"a",		ISA_SPEC_CLASS_20190608,	2, 0, 0 },
1148   {"a",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1149   {"f",		ISA_SPEC_CLASS_20191213,	2, 2, 0 },
1150   {"f",		ISA_SPEC_CLASS_20190608,	2, 2, 0 },
1151   {"f",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1152   {"d",		ISA_SPEC_CLASS_20191213,	2, 2, 0 },
1153   {"d",		ISA_SPEC_CLASS_20190608,	2, 2, 0 },
1154   {"d",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1155   {"q",		ISA_SPEC_CLASS_20191213,	2, 2, 0 },
1156   {"q",		ISA_SPEC_CLASS_20190608,	2, 2, 0 },
1157   {"q",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1158   {"c",		ISA_SPEC_CLASS_20191213,	2, 0, 0 },
1159   {"c",		ISA_SPEC_CLASS_20190608,	2, 0, 0 },
1160   {"c",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1161   {"v",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1162   {"h",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1163   {NULL, 0, 0, 0, 0}
1164 };
1165 
1166 static struct riscv_supported_ext riscv_supported_std_z_ext[] =
1167 {
1168   {"zicbom",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1169   {"zicbop",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1170   {"zicboz",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1171   {"zicsr",		ISA_SPEC_CLASS_20191213,	2, 0,  0 },
1172   {"zicsr",		ISA_SPEC_CLASS_20190608,	2, 0,  0 },
1173   {"zifencei",		ISA_SPEC_CLASS_20191213,	2, 0,  0 },
1174   {"zifencei",		ISA_SPEC_CLASS_20190608,	2, 0,  0 },
1175   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
1176   {"zmmul",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1177   {"zawrs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1178   {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1179   {"zfhmin",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1180   {"zfinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1181   {"zdinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1182   {"zqinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1183   {"zhinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1184   {"zhinxmin",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1185   {"zbb",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1186   {"zba",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1187   {"zbc",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1188   {"zbs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1189   {"zbkb",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1190   {"zbkc",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1191   {"zbkx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1192   {"zk",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1193   {"zkn",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1194   {"zknd",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1195   {"zkne",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1196   {"zknh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1197   {"zkr",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1198   {"zks",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1199   {"zksed",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1200   {"zksh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1201   {"zkt",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1202   {"zve32x",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1203   {"zve32f",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1204   {"zve32d",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1205   {"zve64x",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1206   {"zve64f",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1207   {"zve64d",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1208   {"zvl32b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1209   {"zvl64b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1210   {"zvl128b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1211   {"zvl256b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1212   {"zvl512b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1213   {"zvl1024b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1214   {"zvl2048b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1215   {"zvl4096b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1216   {"zvl8192b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1217   {"zvl16384b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1218   {"zvl32768b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1219   {"zvl65536b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1220   {"ztso",		ISA_SPEC_CLASS_DRAFT,		0, 1,  0 },
1221   {NULL, 0, 0, 0, 0}
1222 };
1223 
1224 static struct riscv_supported_ext riscv_supported_std_s_ext[] =
1225 {
1226   {"smaia",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1227   {"smepmp",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1228   {"smstateen",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1229   {"ssaia",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1230   {"sscofpmf",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1231   {"ssstateen",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1232   {"sstc",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1233   {"svinval",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1234   {"svnapot",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1235   {"svpbmt",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1236   {NULL, 0, 0, 0, 0}
1237 };
1238 
1239 static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
1240 {
1241   {NULL, 0, 0, 0, 0}
1242 };
1243 
1244 static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
1245 {
1246   {"xtheadba",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1247   {"xtheadbb",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1248   {"xtheadbs",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1249   {"xtheadcmo",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1250   {"xtheadcondmov",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1251   {"xtheadfmemidx",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1252   {"xtheadfmv",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1253   {"xtheadint",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1254   {"xtheadmac",		ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1255   {"xtheadmemidx",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1256   {"xtheadmempair",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1257   {"xtheadsync",	ISA_SPEC_CLASS_DRAFT,	1, 0, 0 },
1258   {NULL, 0, 0, 0, 0}
1259 };
1260 
1261 const struct riscv_supported_ext *riscv_all_supported_ext[] =
1262 {
1263   riscv_supported_std_ext,
1264   riscv_supported_std_z_ext,
1265   riscv_supported_std_s_ext,
1266   riscv_supported_std_zxm_ext,
1267   riscv_supported_vendor_x_ext,
1268   NULL
1269 };
1270 
1271 /* ISA extension prefixed name class.  Must define them in parsing order.  */
1272 enum riscv_prefix_ext_class
1273 {
1274   RV_ISA_CLASS_Z = 1,
1275   RV_ISA_CLASS_S,
1276   RV_ISA_CLASS_ZXM,
1277   RV_ISA_CLASS_X,
1278   RV_ISA_CLASS_UNKNOWN
1279 };
1280 
1281 /* Record the strings of the prefixed extensions, and their corresponding
1282    classes.  The more letters of the prefix string, the more forward it must
1283    be defined.  Otherwise, the riscv_get_prefix_class will map it to the
1284    wrong classes.  */
1285 struct riscv_parse_prefix_config
1286 {
1287   /* Class of the extension. */
1288   enum riscv_prefix_ext_class class;
1289 
1290   /* Prefix string for error printing and internal parser usage.  */
1291   const char *prefix;
1292 };
1293 static const struct riscv_parse_prefix_config parse_config[] =
1294 {
1295   {RV_ISA_CLASS_ZXM, "zxm"},
1296   {RV_ISA_CLASS_Z, "z"},
1297   {RV_ISA_CLASS_S, "s"},
1298   {RV_ISA_CLASS_X, "x"},
1299   {RV_ISA_CLASS_UNKNOWN, NULL}
1300 };
1301 
1302 /* Get the prefixed name class for the extensions, the class also
1303    means the order of the prefixed extensions.  */
1304 
1305 static enum riscv_prefix_ext_class
1306 riscv_get_prefix_class (const char *arch)
1307 {
1308   int i = 0;
1309   while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN)
1310     {
1311       if (strncmp (arch, parse_config[i].prefix,
1312 		   strlen (parse_config[i].prefix)) == 0)
1313 	return parse_config[i].class;
1314       i++;
1315     }
1316   return RV_ISA_CLASS_UNKNOWN;
1317 }
1318 
1319 /* Check KNOWN_EXTS to see if the EXT is supported.  */
1320 
1321 static bool
1322 riscv_known_prefixed_ext (const char *ext,
1323 			  struct riscv_supported_ext *known_exts)
1324 {
1325   size_t i;
1326   for (i = 0; known_exts[i].name != NULL; ++i)
1327     if (strcmp (ext, known_exts[i].name) == 0)
1328       return true;
1329   return false;
1330 }
1331 
1332 /* Check whether the prefixed extension is recognized or not.  Return
1333    true if recognized, otehrwise return false.  */
1334 
1335 static bool
1336 riscv_recognized_prefixed_ext (const char *ext)
1337 {
1338   enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext);
1339   switch (class)
1340   {
1341   case RV_ISA_CLASS_Z:
1342     return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext);
1343   case RV_ISA_CLASS_ZXM:
1344     return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
1345   case RV_ISA_CLASS_S:
1346     return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
1347   case RV_ISA_CLASS_X:
1348     /* Only the single x is unrecognized.  */
1349     if (strcmp (ext, "x") != 0)
1350       return true;
1351   default:
1352     break;
1353   }
1354   return false;
1355 }
1356 
1357 /* Canonical order for single letter extensions.  */
1358 static const char riscv_ext_canonical_order[] = "eigmafdqlcbkjtpvnh";
1359 
1360 /* Array is used to compare the orders of standard extensions quickly.  */
1361 static int riscv_ext_order[26] = {0};
1362 
1363 /* Init the riscv_ext_order array.  */
1364 
1365 static void
1366 riscv_init_ext_order (void)
1367 {
1368   static bool inited = false;
1369   if (inited)
1370     return;
1371 
1372   /* The orders of all standard extensions are positive.  */
1373   int order = 1;
1374 
1375   for (const char *ext = &riscv_ext_canonical_order[0]; *ext; ++ext)
1376     riscv_ext_order[(*ext - 'a')] = order++;
1377 
1378   /* Some of the prefixed keyword are not single letter, so we set
1379      their prefixed orders in the riscv_compare_subsets directly,
1380      not through the riscv_ext_order.  */
1381 
1382   inited = true;
1383 }
1384 
1385 /* Similar to the strcmp.  It returns an integer less than, equal to,
1386    or greater than zero if `subset2` is found, respectively, to be less
1387    than, to match, or be greater than `subset1`.
1388 
1389    The order values,
1390    Zero: Preserved keywords.
1391    Positive number: Standard extensions.
1392    Negative number: Prefixed keywords.  */
1393 
1394 int
1395 riscv_compare_subsets (const char *subset1, const char *subset2)
1396 {
1397   int order1 = riscv_ext_order[(*subset1 - 'a')];
1398   int order2 = riscv_ext_order[(*subset2 - 'a')];
1399 
1400   /* Compare the standard extension first.  */
1401   if (order1 > 0 && order2 > 0)
1402     return order1 - order2;
1403 
1404   /* Set the prefixed orders to negative numbers.  */
1405   enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1);
1406   enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2);
1407 
1408   if (class1 != RV_ISA_CLASS_UNKNOWN)
1409     order1 = - (int) class1;
1410   if (class2 != RV_ISA_CLASS_UNKNOWN)
1411     order2 = - (int) class2;
1412 
1413   if (order1 == order2)
1414     {
1415       /* Compare the standard addition z extensions.  */
1416       if (class1 == RV_ISA_CLASS_Z)
1417 	{
1418 	  order1 = riscv_ext_order[(*++subset1 - 'a')];
1419 	  order2 = riscv_ext_order[(*++subset2 - 'a')];
1420 	  if (order1 != order2)
1421 	    return order1 - order2;
1422 	}
1423       return strcasecmp (++subset1, ++subset2);
1424     }
1425 
1426   return order2 - order1;
1427 }
1428 
1429 /* Find subset in the list.  Return TRUE and set `current` to the subset
1430    if it is found.  Otherwise, return FALSE and set `current` to the place
1431    where we should insert the subset.  However, return FALSE with the NULL
1432    `current` means we should insert the subset at the head of subset list,
1433    if needed.  */
1434 
1435 bool
1436 riscv_lookup_subset (const riscv_subset_list_t *subset_list,
1437 		     const char *subset,
1438 		     riscv_subset_t **current)
1439 {
1440   riscv_subset_t *s, *pre_s = NULL;
1441 
1442   /* If the subset is added in order, then just add it at the tail.  */
1443   if (subset_list->tail != NULL
1444       && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
1445     {
1446       *current = subset_list->tail;
1447       return false;
1448     }
1449 
1450   for (s = subset_list->head;
1451        s != NULL;
1452        pre_s = s, s = s->next)
1453     {
1454       int cmp = riscv_compare_subsets (s->name, subset);
1455       if (cmp == 0)
1456 	{
1457 	  *current = s;
1458 	  return true;
1459 	}
1460       else if (cmp > 0)
1461 	break;
1462     }
1463   *current = pre_s;
1464 
1465   return false;
1466 }
1467 
1468 /* Add the extension to the subset list.  Search the
1469    list first, and then find the right place to add.  */
1470 
1471 void
1472 riscv_add_subset (riscv_subset_list_t *subset_list,
1473 		  const char *subset,
1474 		  int major,
1475 		  int minor)
1476 {
1477   riscv_subset_t *current, *new;
1478 
1479   if (riscv_lookup_subset (subset_list, subset, &current))
1480     return;
1481 
1482   new = xmalloc (sizeof *new);
1483   new->name = xstrdup (subset);
1484   new->major_version = major;
1485   new->minor_version = minor;
1486   new->next = NULL;
1487 
1488   if (current != NULL)
1489     {
1490       new->next = current->next;
1491       current->next = new;
1492     }
1493   else
1494     {
1495       new->next = subset_list->head;
1496       subset_list->head = new;
1497     }
1498 
1499   if (new->next == NULL)
1500     subset_list->tail = new;
1501 }
1502 
1503 /* Get the default versions from the riscv_supported_*ext tables.  */
1504 
1505 static void
1506 riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
1507 			       const char *name,
1508 			       int *major_version,
1509 			       int *minor_version)
1510 {
1511   if (name == NULL
1512       || default_isa_spec == NULL
1513       || *default_isa_spec == ISA_SPEC_CLASS_NONE)
1514     return;
1515 
1516   struct riscv_supported_ext *table = NULL;
1517   enum riscv_prefix_ext_class class = riscv_get_prefix_class (name);
1518   switch (class)
1519     {
1520     case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
1521     case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
1522     case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
1523     case RV_ISA_CLASS_X: table = riscv_supported_vendor_x_ext; break;
1524     default:
1525       table = riscv_supported_std_ext;
1526     }
1527 
1528   int i = 0;
1529   while (table != NULL && table[i].name != NULL)
1530     {
1531       if (strcmp (table[i].name, name) == 0
1532 	  && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
1533 	      || table[i].isa_spec_class == *default_isa_spec))
1534 	{
1535 	  *major_version = table[i].major_version;
1536 	  *minor_version = table[i].minor_version;
1537 	  return;
1538 	}
1539       i++;
1540     }
1541 }
1542 
1543 /* Find the default versions for the extension before adding them to
1544    the subset list, if their versions are RISCV_UNKNOWN_VERSION.
1545    Afterwards, report errors if we can not find their default versions.  */
1546 
1547 static void
1548 riscv_parse_add_subset (riscv_parse_subset_t *rps,
1549 			const char *subset,
1550 			int major,
1551 			int minor,
1552 			bool implicit)
1553 {
1554   int major_version = major;
1555   int minor_version = minor;
1556 
1557   if (major_version == RISCV_UNKNOWN_VERSION
1558        || minor_version == RISCV_UNKNOWN_VERSION)
1559     riscv_get_default_ext_version (rps->isa_spec, subset,
1560 				   &major_version, &minor_version);
1561 
1562   /* We don't care the versions of the implicit extensions.  */
1563   if (!implicit
1564       && (major_version == RISCV_UNKNOWN_VERSION
1565 	  || minor_version == RISCV_UNKNOWN_VERSION))
1566     {
1567       if (subset[0] == 'x')
1568 	rps->error_handler
1569 	  (_("x ISA extension `%s' must be set with the versions"),
1570 	   subset);
1571       /* Allow old ISA spec can recognize zicsr and zifencei.  */
1572       else if (strcmp (subset, "zicsr") != 0
1573 	       && strcmp (subset, "zifencei") != 0)
1574 	rps->error_handler
1575 	  (_("cannot find default versions of the ISA extension `%s'"),
1576 	   subset);
1577       return;
1578     }
1579 
1580   riscv_add_subset (rps->subset_list, subset,
1581 		    major_version, minor_version);
1582 }
1583 
1584 /* Release subset list.  */
1585 
1586 void
1587 riscv_release_subset_list (riscv_subset_list_t *subset_list)
1588 {
1589    while (subset_list->head != NULL)
1590     {
1591       riscv_subset_t *next = subset_list->head->next;
1592       free ((void *)subset_list->head->name);
1593       free (subset_list->head);
1594       subset_list->head = next;
1595     }
1596 
1597   subset_list->tail = NULL;
1598 
1599   if (subset_list->arch_str != NULL)
1600     {
1601       free ((void*) subset_list->arch_str);
1602       subset_list->arch_str = NULL;
1603     }
1604 }
1605 
1606 /* Parsing extension version.
1607 
1608    Return Value:
1609      Points to the end of version
1610 
1611    Arguments:
1612      `p`: Curent parsing position.
1613      `major_version`: Parsed major version.
1614      `minor_version`: Parsed minor version.  */
1615 
1616 static const char *
1617 riscv_parsing_subset_version (const char *p,
1618 			      int *major_version,
1619 			      int *minor_version)
1620 {
1621   bool major_p = true;
1622   int version = 0;
1623   char np;
1624 
1625   *major_version = 0;
1626   *minor_version = 0;
1627   for (; *p; ++p)
1628     {
1629       if (*p == 'p')
1630 	{
1631 	  np = *(p + 1);
1632 
1633 	  /* Might be beginning of `p` extension.  */
1634 	  if (!ISDIGIT (np))
1635 	    break;
1636 
1637 	  *major_version = version;
1638 	  major_p = false;
1639 	  version = 0;
1640 	}
1641       else if (ISDIGIT (*p))
1642 	version = (version * 10) + (*p - '0');
1643       else
1644 	break;
1645     }
1646 
1647   if (major_p)
1648     *major_version = version;
1649   else
1650     *minor_version = version;
1651 
1652   /* We can not find any version in string.  */
1653   if (*major_version == 0 && *minor_version == 0)
1654     {
1655       *major_version = RISCV_UNKNOWN_VERSION;
1656       *minor_version = RISCV_UNKNOWN_VERSION;
1657     }
1658 
1659   return p;
1660 }
1661 
1662 /* Parsing function for standard extensions.
1663 
1664    Return Value:
1665      Points to the end of extensions.
1666 
1667    Arguments:
1668      `rps`: Hooks and status for parsing extensions.
1669      `arch`: Full ISA string.
1670      `p`: Curent parsing position.  */
1671 
1672 static const char *
1673 riscv_parse_std_ext (riscv_parse_subset_t *rps,
1674 		     const char *arch,
1675 		     const char *p)
1676 {
1677   /* First letter must start with i, e or g.  */
1678   if (*p != 'e' && *p != 'i' && *p != 'g')
1679     {
1680       rps->error_handler
1681 	(_("%s: first ISA extension must be `e', `i' or `g'"),
1682 	 arch);
1683       return NULL;
1684     }
1685 
1686   while (p != NULL && *p != '\0')
1687     {
1688       /* Stop when we parsed the known prefix class.  */
1689       enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
1690       if (class != RV_ISA_CLASS_UNKNOWN)
1691 	break;
1692 
1693       if (*p == '_')
1694 	{
1695 	  p++;
1696 	  continue;
1697 	}
1698 
1699       bool implicit = false;
1700       int major = RISCV_UNKNOWN_VERSION;
1701       int minor = RISCV_UNKNOWN_VERSION;
1702       char subset[2] = {0, 0};
1703 
1704       subset[0] = *p;
1705 
1706       /* Check if the standard extension is supported.  */
1707       if (riscv_ext_order[(subset[0] - 'a')] == 0)
1708 	{
1709 	  rps->error_handler
1710 	    (_("%s: unknown standard ISA extension `%c'"),
1711 	     arch, subset[0]);
1712 	  return NULL;
1713 	}
1714 
1715       /* Checking canonical order.  */
1716       if (rps->subset_list->tail != NULL
1717 	  && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
1718 	{
1719 	  rps->error_handler
1720 	    (_("%s: standard ISA extension `%c' is not "
1721 	       "in canonical order"), arch, subset[0]);
1722 	  return NULL;
1723 	}
1724 
1725       p = riscv_parsing_subset_version (++p, &major, &minor);
1726       /* Added g as an implicit extension.  */
1727       if (subset[0] == 'g')
1728 	{
1729 	  implicit = true;
1730 	  major = RISCV_UNKNOWN_VERSION;
1731 	  minor = RISCV_UNKNOWN_VERSION;
1732 	}
1733       riscv_parse_add_subset (rps, subset, major, minor, implicit);
1734     }
1735 
1736   return p;
1737 }
1738 
1739 /* Parsing function for prefixed extensions.
1740 
1741    Return Value:
1742      Points to the end of extension.
1743 
1744    Arguments:
1745      `rps`: Hooks and status for parsing extensions.
1746      `arch`: Full ISA string.
1747      `p`: Curent parsing position.  */
1748 
1749 static const char *
1750 riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
1751 			  const char *arch,
1752 			  const char *p)
1753 {
1754   int major_version;
1755   int minor_version;
1756   enum riscv_prefix_ext_class class;
1757 
1758   while (*p)
1759     {
1760       if (*p == '_')
1761 	{
1762 	  p++;
1763 	  continue;
1764 	}
1765 
1766       class = riscv_get_prefix_class (p);
1767       if (class == RV_ISA_CLASS_UNKNOWN)
1768 	{
1769 	  rps->error_handler
1770 	    (_("%s: unknown prefix class for the ISA extension `%s'"),
1771 	     arch, p);
1772 	  return NULL;
1773 	}
1774 
1775       char *subset = xstrdup (p);
1776       char *q = subset;
1777       const char *end_of_version;
1778 
1779       /* Extract the whole prefixed extension by '_'.  */
1780       while (*++q != '\0' && *q != '_')
1781 	;
1782       /* Look forward to the first letter which is not <major>p<minor>.  */
1783       bool find_any_version = false;
1784       bool find_minor_version = false;
1785       while (1)
1786 	{
1787 	  q--;
1788 	  if (ISDIGIT (*q))
1789 	    find_any_version = true;
1790 	  else if (find_any_version
1791 		   && !find_minor_version
1792 		   && *q == 'p'
1793 		   && ISDIGIT (*(q - 1)))
1794 	    find_minor_version = true;
1795 	  else
1796 	    break;
1797 	}
1798       q++;
1799 
1800       /* Check if the end of extension is 'p' or not.  If yes, then
1801 	 the second letter from the end cannot be number.  */
1802       if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
1803 	{
1804 	  *q = '\0';
1805 	  rps->error_handler
1806 	    (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
1807 	     arch, subset);
1808 	  free (subset);
1809 	  return NULL;
1810 	}
1811 
1812       end_of_version =
1813 	riscv_parsing_subset_version (q, &major_version, &minor_version);
1814       *q = '\0';
1815       if (end_of_version == NULL)
1816 	{
1817 	  free (subset);
1818 	  return NULL;
1819 	}
1820 
1821       /* Check that the extension name is well-formed.  */
1822       if (rps->check_unknown_prefixed_ext
1823 	  && !riscv_recognized_prefixed_ext (subset))
1824 	{
1825 	  rps->error_handler
1826 	    (_("%s: unknown prefixed ISA extension `%s'"),
1827 	     arch, subset);
1828 	  free (subset);
1829 	  return NULL;
1830 	}
1831 
1832       riscv_parse_add_subset (rps, subset,
1833 			      major_version,
1834 			      minor_version, false);
1835       p += end_of_version - subset;
1836       free (subset);
1837 
1838       if (*p != '\0' && *p != '_')
1839 	{
1840 	  rps->error_handler
1841 	    (_("%s: prefixed ISA extension must separate with _"),
1842 	     arch);
1843 	  return NULL;
1844 	}
1845     }
1846 
1847   return p;
1848 }
1849 
1850 /* Add the implicit extensions.  */
1851 
1852 static void
1853 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
1854 {
1855   struct riscv_implicit_subset *t = riscv_implicit_subsets;
1856   for (; t->subset_name; t++)
1857     {
1858       riscv_subset_t *subset = NULL;
1859       if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
1860 	  && t->check_func (t->implicit_name, subset))
1861 	riscv_parse_add_subset (rps, t->implicit_name,
1862 				RISCV_UNKNOWN_VERSION,
1863 				RISCV_UNKNOWN_VERSION, true);
1864     }
1865 }
1866 
1867 /* Check extensions conflicts.  */
1868 
1869 static bool
1870 riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
1871 {
1872   riscv_subset_t *subset = NULL;
1873   int xlen = *rps->xlen;
1874   bool no_conflict = true;
1875 
1876   if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1877       && xlen > 32)
1878     {
1879       rps->error_handler
1880 	(_("rv%d does not support the `e' extension"), xlen);
1881       no_conflict = false;
1882     }
1883   if (riscv_lookup_subset (rps->subset_list, "q", &subset)
1884       && (subset->major_version < 2 || (subset->major_version == 2
1885 					&& subset->minor_version < 2))
1886       && xlen < 64)
1887     {
1888       rps->error_handler (_("rv%d does not support the `q' extension"), xlen);
1889       no_conflict = false;
1890     }
1891   if (riscv_lookup_subset (rps->subset_list, "zfinx", &subset)
1892       && riscv_lookup_subset (rps->subset_list, "f", &subset))
1893     {
1894       rps->error_handler
1895 	(_("`zfinx' is conflict with the `f/d/q/zfh/zfhmin' extension"));
1896       no_conflict = false;
1897     }
1898 
1899   bool support_zve = false;
1900   bool support_zvl = false;
1901   riscv_subset_t *s = rps->subset_list->head;
1902   for (; s != NULL; s = s->next)
1903     {
1904       if (!support_zve
1905 	  && strncmp (s->name, "zve", 3) == 0)
1906 	support_zve = true;
1907       if (!support_zvl
1908 	  && strncmp (s->name, "zvl", 3) == 0)
1909 	support_zvl = true;
1910       if (support_zve && support_zvl)
1911 	break;
1912     }
1913   if (support_zvl && !support_zve)
1914     {
1915       rps->error_handler
1916 	(_("zvl*b extensions need to enable either `v' or `zve' extension"));
1917       no_conflict = false;
1918     }
1919 
1920   return no_conflict;
1921 }
1922 
1923 /* Set the default subset list according to the default_enable field
1924    of riscv_supported_*ext tables.  */
1925 
1926 static void
1927 riscv_set_default_arch (riscv_parse_subset_t *rps)
1928 {
1929   unsigned long enable = EXT_DEFAULT;
1930   int i, j;
1931   for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
1932     {
1933       const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
1934       for (j = 0; table[j].name != NULL; j++)
1935 	{
1936 	  bool implicit = false;
1937 	  if (strcmp (table[j].name, "g") == 0)
1938 	    implicit = true;
1939 	  if (table[j].default_enable & enable)
1940 	    riscv_parse_add_subset (rps, table[j].name,
1941 				    RISCV_UNKNOWN_VERSION,
1942 				    RISCV_UNKNOWN_VERSION, implicit);
1943 	}
1944     }
1945 }
1946 
1947 /* Function for parsing ISA string.
1948 
1949    Return Value:
1950      Return TRUE on success.
1951 
1952    Arguments:
1953      `rps`: Hooks and status for parsing extensions.
1954      `arch`: Full ISA string.  */
1955 
1956 bool
1957 riscv_parse_subset (riscv_parse_subset_t *rps,
1958 		    const char *arch)
1959 {
1960   const char *p;
1961 
1962   /* Init the riscv_ext_order array to compare the order of extensions
1963      quickly.  */
1964   riscv_init_ext_order ();
1965 
1966   if (arch == NULL)
1967     {
1968       riscv_set_default_arch (rps);
1969       riscv_parse_add_implicit_subsets (rps);
1970       return riscv_parse_check_conflicts (rps);
1971     }
1972 
1973   for (p = arch; *p != '\0'; p++)
1974     {
1975       if (ISUPPER (*p))
1976 	{
1977 	  rps->error_handler
1978 	    (_("%s: ISA string cannot contain uppercase letters"),
1979 	     arch);
1980 	  return false;
1981 	}
1982     }
1983 
1984   p = arch;
1985   if (startswith (p, "rv32"))
1986     {
1987       *rps->xlen = 32;
1988       p += 4;
1989     }
1990   else if (startswith (p, "rv64"))
1991     {
1992       *rps->xlen = 64;
1993       p += 4;
1994     }
1995   else
1996     {
1997       /* ISA string shouldn't be NULL or empty here.  For linker,
1998 	 it might be empty when we failed to merge the ISA string
1999 	 in the riscv_merge_attributes.  For assembler, we might
2000 	 give an empty string by .attribute arch, "" or -march=.
2001 	 However, We have already issued the correct error message
2002 	 in another side, so do not issue this error when the ISA
2003 	 string is empty.  */
2004       if (strlen (arch))
2005 	rps->error_handler (
2006 	  _("%s: ISA string must begin with rv32 or rv64"),
2007 	  arch);
2008       return false;
2009     }
2010 
2011   /* Parsing standard extension.  */
2012   p = riscv_parse_std_ext (rps, arch, p);
2013 
2014   if (p == NULL)
2015     return false;
2016 
2017   /* Parse prefixed extensions.  */
2018   p = riscv_parse_prefixed_ext (rps, arch, p);
2019 
2020   if (p == NULL)
2021     return false;
2022 
2023   /* Finally add implicit extensions according to the current
2024      extensions.  */
2025   riscv_parse_add_implicit_subsets (rps);
2026 
2027   /* Check the conflicts.  */
2028   return riscv_parse_check_conflicts (rps);
2029 }
2030 
2031 /* Return the number of digits for the input.  */
2032 
2033 size_t
2034 riscv_estimate_digit (unsigned num)
2035 {
2036   size_t digit = 0;
2037   if (num == 0)
2038     return 1;
2039 
2040   for (digit = 0; num ; num /= 10)
2041     digit++;
2042 
2043   return digit;
2044 }
2045 
2046 /* Auxiliary function to estimate string length of subset list.  */
2047 
2048 static size_t
2049 riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
2050 {
2051   if (subset == NULL)
2052     return 6; /* For rv32/rv64/rv128 and string terminator.  */
2053 
2054   return riscv_estimate_arch_strlen1 (subset->next)
2055 	 + strlen (subset->name)
2056 	 + riscv_estimate_digit (subset->major_version)
2057 	 + 1 /* For version seperator 'p'.  */
2058 	 + riscv_estimate_digit (subset->minor_version)
2059 	 + 1 /* For underscore.  */;
2060 }
2061 
2062 /* Estimate the string length of this subset list.  */
2063 
2064 static size_t
2065 riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
2066 {
2067   return riscv_estimate_arch_strlen1 (subset_list->head);
2068 }
2069 
2070 /* Auxiliary function to convert subset info to string.  */
2071 
2072 static void
2073 riscv_arch_str1 (riscv_subset_t *subset,
2074 		 char *attr_str, char *buf, size_t bufsz)
2075 {
2076   const char *underline = "_";
2077   riscv_subset_t *subset_t = subset;
2078 
2079   if (subset_t == NULL)
2080     return;
2081 
2082   /* No underline between rvXX and i/e.  */
2083   if ((strcasecmp (subset_t->name, "i") == 0)
2084       || (strcasecmp (subset_t->name, "e") == 0))
2085     underline = "";
2086 
2087   snprintf (buf, bufsz, "%s%s%dp%d",
2088 	    underline,
2089 	    subset_t->name,
2090 	    subset_t->major_version,
2091 	    subset_t->minor_version);
2092 
2093   strncat (attr_str, buf, bufsz);
2094 
2095   /* Skip 'i' extension after 'e', or skip extensions which
2096      versions are unknown.  */
2097   while (subset_t->next
2098 	 && ((strcmp (subset_t->name, "e") == 0
2099 	      && strcmp (subset_t->next->name, "i") == 0)
2100 	     || subset_t->next->major_version == RISCV_UNKNOWN_VERSION
2101 	     || subset_t->next->minor_version == RISCV_UNKNOWN_VERSION))
2102     subset_t = subset_t->next;
2103 
2104   riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
2105 }
2106 
2107 /* Convert subset information into string with explicit versions.  */
2108 
2109 char *
2110 riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
2111 {
2112   size_t arch_str_len = riscv_estimate_arch_strlen (subset);
2113   char *attr_str = xmalloc (arch_str_len);
2114   char *buf = xmalloc (arch_str_len);
2115 
2116   snprintf (attr_str, arch_str_len, "rv%u", xlen);
2117 
2118   riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
2119   free (buf);
2120 
2121   return attr_str;
2122 }
2123 
2124 /* Copy the subset in the subset list.  */
2125 
2126 static struct riscv_subset_t *
2127 riscv_copy_subset (riscv_subset_list_t *subset_list,
2128 		   riscv_subset_t *subset)
2129 {
2130   if (subset == NULL)
2131     return NULL;
2132 
2133   riscv_subset_t *new = xmalloc (sizeof *new);
2134   new->name = xstrdup (subset->name);
2135   new->major_version = subset->major_version;
2136   new->minor_version = subset->minor_version;
2137   new->next = riscv_copy_subset (subset_list, subset->next);
2138 
2139   if (subset->next == NULL)
2140     subset_list->tail = new;
2141 
2142   return new;
2143 }
2144 
2145 /* Copy the subset list.  */
2146 
2147 riscv_subset_list_t *
2148 riscv_copy_subset_list (riscv_subset_list_t *subset_list)
2149 {
2150   riscv_subset_list_t *new = xmalloc (sizeof *new);
2151   new->head = riscv_copy_subset (new, subset_list->head);
2152   new->arch_str = strdup (subset_list->arch_str);
2153   return new;
2154 }
2155 
2156 /* Remove the SUBSET from the subset list.  */
2157 
2158 static void
2159 riscv_remove_subset (riscv_subset_list_t *subset_list,
2160 		     const char *subset)
2161 {
2162   riscv_subset_t *current = subset_list->head;
2163   riscv_subset_t *pre = NULL;
2164   for (; current != NULL; pre = current, current = current->next)
2165     {
2166       if (strcmp (current->name, subset) == 0)
2167 	{
2168 	  if (pre == NULL)
2169 	    subset_list->head = current->next;
2170 	  else
2171 	    pre->next = current->next;
2172 	  if (current->next == NULL)
2173 	    subset_list->tail = pre;
2174 	  free ((void *) current->name);
2175 	  free (current);
2176 	  break;
2177 	}
2178     }
2179 }
2180 
2181 /* Add/Remove an extension to/from the subset list.  This is used for
2182    the .option rvc or norvc, and .option arch directives.  */
2183 
2184 bool
2185 riscv_update_subset (riscv_parse_subset_t *rps,
2186 		     const char *str)
2187 {
2188   const char *p = str;
2189 
2190   do
2191     {
2192       int major_version = RISCV_UNKNOWN_VERSION;
2193       int minor_version = RISCV_UNKNOWN_VERSION;
2194 
2195       bool removed = false;
2196       switch (*p)
2197 	{
2198 	case '+': removed = false; break;
2199 	case '-': removed = true; break;
2200 	default:
2201 	  riscv_release_subset_list (rps->subset_list);
2202 	  return riscv_parse_subset (rps, p);
2203 	}
2204       ++p;
2205 
2206       char *subset = xstrdup (p);
2207       char *q = subset;
2208       const char *end_of_version;
2209       /* Extract the whole prefixed extension by ','.  */
2210       while (*q != '\0' && *q != ',')
2211         q++;
2212 
2213       /* Look forward to the first letter which is not <major>p<minor>.  */
2214       bool find_any_version = false;
2215       bool find_minor_version = false;
2216       size_t len = q - subset;
2217       size_t i;
2218       for (i = len; i > 0; i--)
2219         {
2220 	  q--;
2221 	  if (ISDIGIT (*q))
2222 	    find_any_version = true;
2223 	  else if (find_any_version
2224 		   && !find_minor_version
2225 		   && *q == 'p'
2226 		   && ISDIGIT (*(q - 1)))
2227 	    find_minor_version = true;
2228 	  else
2229 	    break;
2230 	}
2231       if (len > 0)
2232 	q++;
2233 
2234       /* Check if the end of extension is 'p' or not.  If yes, then
2235 	 the second letter from the end cannot be number.  */
2236       if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
2237 	{
2238 	  *q = '\0';
2239 	  rps->error_handler
2240 	    (_("invalid ISA extension ends with <number>p "
2241 	       "in .option arch `%s'"), str);
2242 	  free (subset);
2243 	  return false;
2244 	}
2245 
2246       end_of_version =
2247 	riscv_parsing_subset_version (q, &major_version, &minor_version);
2248       *q = '\0';
2249       if (end_of_version == NULL)
2250 	{
2251 	  free (subset);
2252 	  return false;
2253 	}
2254 
2255       if (strlen (subset) == 0
2256 	  || (strlen (subset) == 1
2257 	      && riscv_ext_order[(*subset - 'a')] == 0)
2258 	  || (strlen (subset) > 1
2259 	      && rps->check_unknown_prefixed_ext
2260 	      && !riscv_recognized_prefixed_ext (subset)))
2261 	{
2262 	  rps->error_handler
2263 	    (_("unknown ISA extension `%s' in .option arch `%s'"),
2264 	     subset, str);
2265 	  free (subset);
2266 	  return false;
2267 	}
2268 
2269       if (strcmp (subset, "i") == 0
2270 	  || strcmp (subset, "e") == 0
2271 	  || strcmp (subset, "g") == 0)
2272 	{
2273 	  rps->error_handler
2274 	    (_("cannot + or - base extension `%s' in .option "
2275 	       "arch `%s'"), subset, str);
2276 	  free (subset);
2277 	  return false;
2278 	}
2279 
2280       if (removed)
2281 	riscv_remove_subset (rps->subset_list, subset);
2282       else
2283 	riscv_parse_add_subset (rps, subset, major_version, minor_version, true);
2284       p += end_of_version - subset;
2285       free (subset);
2286     }
2287   while (*p++ == ',');
2288 
2289   riscv_parse_add_implicit_subsets (rps);
2290   return riscv_parse_check_conflicts (rps);
2291 }
2292 
2293 /* Check if the FEATURE subset is supported or not in the subset list.
2294    Return true if it is supported; Otherwise, return false.  */
2295 
2296 bool
2297 riscv_subset_supports (riscv_parse_subset_t *rps,
2298 		       const char *feature)
2299 {
2300   struct riscv_subset_t *subset;
2301   return riscv_lookup_subset (rps->subset_list, feature, &subset);
2302 }
2303 
2304 /* Each instuction is belonged to an instruction class INSN_CLASS_*.
2305    Call riscv_subset_supports to make sure if the instuction is valid.  */
2306 
2307 bool
2308 riscv_multi_subset_supports (riscv_parse_subset_t *rps,
2309 			     enum riscv_insn_class insn_class)
2310 {
2311   switch (insn_class)
2312     {
2313     case INSN_CLASS_I:
2314       return riscv_subset_supports (rps, "i");
2315     case INSN_CLASS_ZICBOM:
2316       return riscv_subset_supports (rps, "zicbom");
2317     case INSN_CLASS_ZICBOP:
2318       return riscv_subset_supports (rps, "zicbop");
2319     case INSN_CLASS_ZICBOZ:
2320       return riscv_subset_supports (rps, "zicboz");
2321     case INSN_CLASS_ZICSR:
2322       return riscv_subset_supports (rps, "zicsr");
2323     case INSN_CLASS_ZIFENCEI:
2324       return riscv_subset_supports (rps, "zifencei");
2325     case INSN_CLASS_ZIHINTPAUSE:
2326       return riscv_subset_supports (rps, "zihintpause");
2327     case INSN_CLASS_M:
2328       return riscv_subset_supports (rps, "m");
2329     case INSN_CLASS_ZMMUL:
2330       return riscv_subset_supports (rps, "zmmul");
2331     case INSN_CLASS_A:
2332       return riscv_subset_supports (rps, "a");
2333     case INSN_CLASS_ZAWRS:
2334       return riscv_subset_supports (rps, "zawrs");
2335     case INSN_CLASS_F:
2336       return riscv_subset_supports (rps, "f");
2337     case INSN_CLASS_D:
2338       return riscv_subset_supports (rps, "d");
2339     case INSN_CLASS_Q:
2340       return riscv_subset_supports (rps, "q");
2341     case INSN_CLASS_C:
2342       return riscv_subset_supports (rps, "c");
2343     case INSN_CLASS_F_AND_C:
2344       return (riscv_subset_supports (rps, "f")
2345 	      && riscv_subset_supports (rps, "c"));
2346     case INSN_CLASS_D_AND_C:
2347       return (riscv_subset_supports (rps, "d")
2348 	      && riscv_subset_supports (rps, "c"));
2349     case INSN_CLASS_F_INX:
2350       return (riscv_subset_supports (rps, "f")
2351 	      || riscv_subset_supports (rps, "zfinx"));
2352     case INSN_CLASS_D_INX:
2353       return (riscv_subset_supports (rps, "d")
2354 	      || riscv_subset_supports (rps, "zdinx"));
2355     case INSN_CLASS_Q_INX:
2356       return (riscv_subset_supports (rps, "q")
2357 	      || riscv_subset_supports (rps, "zqinx"));
2358     case INSN_CLASS_ZFH_INX:
2359       return (riscv_subset_supports (rps, "zfh")
2360 	      || riscv_subset_supports (rps, "zhinx"));
2361     case INSN_CLASS_ZFHMIN:
2362       return riscv_subset_supports (rps, "zfhmin");
2363     case INSN_CLASS_ZFHMIN_INX:
2364       return (riscv_subset_supports (rps, "zfhmin")
2365 	      || riscv_subset_supports (rps, "zhinxmin"));
2366     case INSN_CLASS_ZFHMIN_AND_D_INX:
2367       return ((riscv_subset_supports (rps, "zfhmin")
2368 	       && riscv_subset_supports (rps, "d"))
2369 	      || (riscv_subset_supports (rps, "zhinxmin")
2370 		  && riscv_subset_supports (rps, "zdinx")));
2371     case INSN_CLASS_ZFHMIN_AND_Q_INX:
2372       return ((riscv_subset_supports (rps, "zfhmin")
2373 	       && riscv_subset_supports (rps, "q"))
2374 	      || (riscv_subset_supports (rps, "zhinxmin")
2375 		  && riscv_subset_supports (rps, "zqinx")));
2376     case INSN_CLASS_ZBA:
2377       return riscv_subset_supports (rps, "zba");
2378     case INSN_CLASS_ZBB:
2379       return riscv_subset_supports (rps, "zbb");
2380     case INSN_CLASS_ZBC:
2381       return riscv_subset_supports (rps, "zbc");
2382     case INSN_CLASS_ZBS:
2383       return riscv_subset_supports (rps, "zbs");
2384     case INSN_CLASS_ZBKB:
2385       return riscv_subset_supports (rps, "zbkb");
2386     case INSN_CLASS_ZBKC:
2387       return riscv_subset_supports (rps, "zbkc");
2388     case INSN_CLASS_ZBKX:
2389       return riscv_subset_supports (rps, "zbkx");
2390     case INSN_CLASS_ZBB_OR_ZBKB:
2391       return (riscv_subset_supports (rps, "zbb")
2392 	      || riscv_subset_supports (rps, "zbkb"));
2393     case INSN_CLASS_ZBC_OR_ZBKC:
2394       return (riscv_subset_supports (rps, "zbc")
2395 	      || riscv_subset_supports (rps, "zbkc"));
2396     case INSN_CLASS_ZKND:
2397       return riscv_subset_supports (rps, "zknd");
2398     case INSN_CLASS_ZKNE:
2399       return riscv_subset_supports (rps, "zkne");
2400     case INSN_CLASS_ZKNH:
2401       return riscv_subset_supports (rps, "zknh");
2402     case INSN_CLASS_ZKND_OR_ZKNE:
2403       return (riscv_subset_supports (rps, "zknd")
2404 	      || riscv_subset_supports (rps, "zkne"));
2405     case INSN_CLASS_ZKSED:
2406       return riscv_subset_supports (rps, "zksed");
2407     case INSN_CLASS_ZKSH:
2408       return riscv_subset_supports (rps, "zksh");
2409     case INSN_CLASS_V:
2410       return (riscv_subset_supports (rps, "v")
2411 	      || riscv_subset_supports (rps, "zve64x")
2412 	      || riscv_subset_supports (rps, "zve32x"));
2413     case INSN_CLASS_ZVEF:
2414       return (riscv_subset_supports (rps, "v")
2415 	      || riscv_subset_supports (rps, "zve64d")
2416 	      || riscv_subset_supports (rps, "zve64f")
2417 	      || riscv_subset_supports (rps, "zve32f"));
2418     case INSN_CLASS_SVINVAL:
2419       return riscv_subset_supports (rps, "svinval");
2420     case INSN_CLASS_H:
2421       return riscv_subset_supports (rps, "h");
2422     case INSN_CLASS_XTHEADBA:
2423       return riscv_subset_supports (rps, "xtheadba");
2424     case INSN_CLASS_XTHEADBB:
2425       return riscv_subset_supports (rps, "xtheadbb");
2426     case INSN_CLASS_XTHEADBS:
2427       return riscv_subset_supports (rps, "xtheadbs");
2428     case INSN_CLASS_XTHEADCMO:
2429       return riscv_subset_supports (rps, "xtheadcmo");
2430     case INSN_CLASS_XTHEADCONDMOV:
2431       return riscv_subset_supports (rps, "xtheadcondmov");
2432     case INSN_CLASS_XTHEADFMEMIDX:
2433       return riscv_subset_supports (rps, "xtheadfmemidx");
2434     case INSN_CLASS_XTHEADFMV:
2435       return riscv_subset_supports (rps, "xtheadfmv");
2436     case INSN_CLASS_XTHEADINT:
2437       return riscv_subset_supports (rps, "xtheadint");
2438     case INSN_CLASS_XTHEADMAC:
2439       return riscv_subset_supports (rps, "xtheadmac");
2440     case INSN_CLASS_XTHEADMEMIDX:
2441       return riscv_subset_supports (rps, "xtheadmemidx");
2442     case INSN_CLASS_XTHEADMEMPAIR:
2443       return riscv_subset_supports (rps, "xtheadmempair");
2444     case INSN_CLASS_XTHEADSYNC:
2445       return riscv_subset_supports (rps, "xtheadsync");
2446     default:
2447       rps->error_handler
2448         (_("internal: unreachable INSN_CLASS_*"));
2449       return false;
2450     }
2451 }
2452 
2453 /* Each instuction is belonged to an instruction class INSN_CLASS_*.
2454    Call riscv_subset_supports_ext to determine the missing extension.  */
2455 
2456 const char *
2457 riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
2458 				 enum riscv_insn_class insn_class)
2459 {
2460   switch (insn_class)
2461     {
2462     case INSN_CLASS_I:
2463       return "i";
2464     case INSN_CLASS_ZICBOM:
2465       return "zicbom";
2466     case INSN_CLASS_ZICBOP:
2467       return "zicbop";
2468     case INSN_CLASS_ZICBOZ:
2469       return "zicboz";
2470     case INSN_CLASS_ZICSR:
2471       return "zicsr";
2472     case INSN_CLASS_ZIFENCEI:
2473       return "zifencei";
2474     case INSN_CLASS_ZIHINTPAUSE:
2475       return "zihintpause";
2476     case INSN_CLASS_M:
2477       return "m";
2478     case INSN_CLASS_ZMMUL:
2479       return _ ("m' or `zmmul");
2480     case INSN_CLASS_A:
2481       return "a";
2482     case INSN_CLASS_ZAWRS:
2483       return "zawrs";
2484     case INSN_CLASS_F:
2485       return "f";
2486     case INSN_CLASS_D:
2487       return "d";
2488     case INSN_CLASS_Q:
2489       return "q";
2490     case INSN_CLASS_C:
2491       return "c";
2492     case INSN_CLASS_F_AND_C:
2493       if (!riscv_subset_supports (rps, "f")
2494 	  && !riscv_subset_supports (rps, "c"))
2495 	return _("f' and `c");
2496       else if (!riscv_subset_supports (rps, "f"))
2497 	return "f";
2498       else
2499 	return "c";
2500     case INSN_CLASS_D_AND_C:
2501       if (!riscv_subset_supports (rps, "d")
2502 	  && !riscv_subset_supports (rps, "c"))
2503 	return _("d' and `c");
2504       else if (!riscv_subset_supports (rps, "d"))
2505 	return "d";
2506       else
2507 	return "c";
2508     case INSN_CLASS_F_INX:
2509       return _("f' or `zfinx");
2510     case INSN_CLASS_D_INX:
2511       return _("d' or `zdinx");
2512     case INSN_CLASS_Q_INX:
2513       return _("q' or `zqinx");
2514     case INSN_CLASS_ZFH_INX:
2515       return _("zfh' or `zhinx");
2516     case INSN_CLASS_ZFHMIN:
2517       return "zfhmin";
2518     case INSN_CLASS_ZFHMIN_INX:
2519       return _("zfhmin' or `zhinxmin");
2520     case INSN_CLASS_ZFHMIN_AND_D_INX:
2521       if (riscv_subset_supports (rps, "zfhmin"))
2522 	return "d";
2523       else if (riscv_subset_supports (rps, "d"))
2524 	return "zfhmin";
2525       else if (riscv_subset_supports (rps, "zhinxmin"))
2526 	return "zdinx";
2527       else if (riscv_subset_supports (rps, "zdinx"))
2528 	return "zhinxmin";
2529       else
2530 	return _("zfhmin' and `d', or `zhinxmin' and `zdinx");
2531     case INSN_CLASS_ZFHMIN_AND_Q_INX:
2532       if (riscv_subset_supports (rps, "zfhmin"))
2533 	return "q";
2534       else if (riscv_subset_supports (rps, "q"))
2535 	return "zfhmin";
2536       else if (riscv_subset_supports (rps, "zhinxmin"))
2537 	return "zqinx";
2538       else if (riscv_subset_supports (rps, "zqinx"))
2539 	return "zhinxmin";
2540       else
2541 	return _("zfhmin' and `q', or `zhinxmin' and `zqinx");
2542     case INSN_CLASS_ZBA:
2543       return "zba";
2544     case INSN_CLASS_ZBB:
2545       return "zbb";
2546     case INSN_CLASS_ZBC:
2547       return "zbc";
2548     case INSN_CLASS_ZBS:
2549       return "zbs";
2550     case INSN_CLASS_ZBKB:
2551       return "zbkb";
2552     case INSN_CLASS_ZBKC:
2553       return "zbkc";
2554     case INSN_CLASS_ZBKX:
2555       return "zbkx";
2556     case INSN_CLASS_ZBB_OR_ZBKB:
2557       return _("zbb' or `zbkb");
2558     case INSN_CLASS_ZBC_OR_ZBKC:
2559       return _("zbc' or `zbkc");
2560     case INSN_CLASS_ZKND:
2561       return "zknd";
2562     case INSN_CLASS_ZKNE:
2563       return "zkne";
2564     case INSN_CLASS_ZKNH:
2565       return "zknh";
2566     case INSN_CLASS_ZKND_OR_ZKNE:
2567       return _("zknd' or `zkne");
2568     case INSN_CLASS_ZKSED:
2569       return "zksed";
2570     case INSN_CLASS_ZKSH:
2571       return "zksh";
2572     case INSN_CLASS_V:
2573       return _("v' or `zve64x' or `zve32x");
2574     case INSN_CLASS_ZVEF:
2575       return _("v' or `zve64d' or `zve64f' or `zve32f");
2576     case INSN_CLASS_SVINVAL:
2577       return "svinval";
2578     case INSN_CLASS_H:
2579       return _("h");
2580     case INSN_CLASS_XTHEADBA:
2581       return "xtheadba";
2582     case INSN_CLASS_XTHEADBB:
2583       return "xtheadbb";
2584     case INSN_CLASS_XTHEADBS:
2585       return "xtheadbs";
2586     case INSN_CLASS_XTHEADCMO:
2587       return "xtheadcmo";
2588     case INSN_CLASS_XTHEADCONDMOV:
2589       return "xtheadcondmov";
2590     case INSN_CLASS_XTHEADFMEMIDX:
2591       return "xtheadfmemidx";
2592     case INSN_CLASS_XTHEADFMV:
2593       return "xtheadfmv";
2594     case INSN_CLASS_XTHEADINT:
2595       return "xtheadint";
2596     case INSN_CLASS_XTHEADMAC:
2597       return "xtheadmac";
2598     case INSN_CLASS_XTHEADMEMIDX:
2599       return "xtheadmemidx";
2600     case INSN_CLASS_XTHEADMEMPAIR:
2601       return "xtheadmempair";
2602     case INSN_CLASS_XTHEADSYNC:
2603       return "xtheadsync";
2604     default:
2605       rps->error_handler
2606         (_("internal: unreachable INSN_CLASS_*"));
2607       return NULL;
2608     }
2609 }
2610