xref: /netbsd-src/external/gpl3/binutils.old/dist/bfd/elfxx-riscv.c (revision 32d1c65c71fbdb65a012e8392a62a757dd6853e9)
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   /* GNU extension to record C++ vtable hierarchy */
603   HOWTO (R_RISCV_GNU_VTINHERIT,		/* type */
604 	 0,				/* rightshift */
605 	 8,				/* size */
606 	 0,				/* bitsize */
607 	 false,				/* pc_relative */
608 	 0,				/* bitpos */
609 	 complain_overflow_dont,	/* complain_on_overflow */
610 	 NULL,				/* special_function */
611 	 "R_RISCV_GNU_VTINHERIT",	/* name */
612 	 false,				/* partial_inplace */
613 	 0,				/* src_mask */
614 	 0,				/* dst_mask */
615 	 false),			/* pcrel_offset */
616 
617   /* GNU extension to record C++ vtable member usage */
618   HOWTO (R_RISCV_GNU_VTENTRY,		/* type */
619 	 0,				/* rightshift */
620 	 8,				/* size */
621 	 0,				/* bitsize */
622 	 false,				/* pc_relative */
623 	 0,				/* bitpos */
624 	 complain_overflow_dont,	/* complain_on_overflow */
625 	 _bfd_elf_rel_vtable_reloc_fn,	/* special_function */
626 	 "R_RISCV_GNU_VTENTRY",		/* name */
627 	 false,				/* partial_inplace */
628 	 0,				/* src_mask */
629 	 0,				/* dst_mask */
630 	 false),			/* pcrel_offset */
631 
632   /* Indicates an alignment statement.  The addend field encodes how many
633      bytes of NOPs follow the statement.  The desired alignment is the
634      addend rounded up to the next power of two.  */
635   HOWTO (R_RISCV_ALIGN,			/* type */
636 	 0,				/* rightshift */
637 	 0,				/* size */
638 	 0,				/* bitsize */
639 	 false,				/* pc_relative */
640 	 0,				/* bitpos */
641 	 complain_overflow_dont,	/* complain_on_overflow */
642 	 bfd_elf_generic_reloc,		/* special_function */
643 	 "R_RISCV_ALIGN",		/* name */
644 	 false,				/* partial_inplace */
645 	 0,				/* src_mask */
646 	 0,				/* dst_mask */
647 	 false),			/* pcrel_offset */
648 
649   /* 8-bit PC-relative branch offset.  */
650   HOWTO (R_RISCV_RVC_BRANCH,		/* type */
651 	 0,				/* rightshift */
652 	 2,				/* size */
653 	 16,				/* bitsize */
654 	 true,				/* pc_relative */
655 	 0,				/* bitpos */
656 	 complain_overflow_signed,	/* complain_on_overflow */
657 	 bfd_elf_generic_reloc,		/* special_function */
658 	 "R_RISCV_RVC_BRANCH",		/* name */
659 	 false,				/* partial_inplace */
660 	 0,				/* src_mask */
661 	 ENCODE_CBTYPE_IMM (-1U),	/* dst_mask */
662 	 true),				/* pcrel_offset */
663 
664   /* 11-bit PC-relative jump offset.  */
665   HOWTO (R_RISCV_RVC_JUMP,		/* type */
666 	 0,				/* rightshift */
667 	 2,				/* size */
668 	 16,				/* bitsize */
669 	 true,				/* pc_relative */
670 	 0,				/* bitpos */
671 	 complain_overflow_dont,	/* complain_on_overflow */
672 	 bfd_elf_generic_reloc,		/* special_function */
673 	 "R_RISCV_RVC_JUMP",		/* name */
674 	 false,				/* partial_inplace */
675 	 0,				/* src_mask */
676 	 ENCODE_CJTYPE_IMM (-1U),	/* dst_mask */
677 	 true),				/* pcrel_offset */
678 
679   /* High 6 bits of 18-bit absolute address.  */
680   HOWTO (R_RISCV_RVC_LUI,		/* type */
681 	 0,				/* rightshift */
682 	 2,				/* size */
683 	 16,				/* bitsize */
684 	 false,				/* pc_relative */
685 	 0,				/* bitpos */
686 	 complain_overflow_dont,	/* complain_on_overflow */
687 	 bfd_elf_generic_reloc,		/* special_function */
688 	 "R_RISCV_RVC_LUI",		/* name */
689 	 false,				/* partial_inplace */
690 	 0,				/* src_mask */
691 	 ENCODE_CITYPE_IMM (-1U),	/* dst_mask */
692 	 false),			/* pcrel_offset */
693 
694   /* GP-relative load.  */
695   HOWTO (R_RISCV_GPREL_I,		/* type */
696 	 0,				/* rightshift */
697 	 4,				/* size */
698 	 32,				/* bitsize */
699 	 false,				/* pc_relative */
700 	 0,				/* bitpos */
701 	 complain_overflow_dont,	/* complain_on_overflow */
702 	 bfd_elf_generic_reloc,		/* special_function */
703 	 "R_RISCV_GPREL_I",		/* name */
704 	 false,				/* partial_inplace */
705 	 0,				/* src_mask */
706 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
707 	 false),			/* pcrel_offset */
708 
709   /* GP-relative store.  */
710   HOWTO (R_RISCV_GPREL_S,		/* type */
711 	 0,				/* rightshift */
712 	 4,				/* size */
713 	 32,				/* bitsize */
714 	 false,				/* pc_relative */
715 	 0,				/* bitpos */
716 	 complain_overflow_dont,	/* complain_on_overflow */
717 	 bfd_elf_generic_reloc,		/* special_function */
718 	 "R_RISCV_GPREL_S",		/* name */
719 	 false,				/* partial_inplace */
720 	 0,				/* src_mask */
721 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
722 	 false),			/* pcrel_offset */
723 
724   /* TP-relative TLS LE load.  */
725   HOWTO (R_RISCV_TPREL_I,		/* type */
726 	 0,				/* rightshift */
727 	 4,				/* size */
728 	 32,				/* bitsize */
729 	 false,				/* pc_relative */
730 	 0,				/* bitpos */
731 	 complain_overflow_signed,	/* complain_on_overflow */
732 	 bfd_elf_generic_reloc,		/* special_function */
733 	 "R_RISCV_TPREL_I",		/* name */
734 	 false,				/* partial_inplace */
735 	 0,				/* src_mask */
736 	 ENCODE_ITYPE_IMM (-1U),	/* dst_mask */
737 	 false),			/* pcrel_offset */
738 
739   /* TP-relative TLS LE store.  */
740   HOWTO (R_RISCV_TPREL_S,		/* type */
741 	 0,				/* rightshift */
742 	 4,				/* size */
743 	 32,				/* bitsize */
744 	 false,				/* pc_relative */
745 	 0,				/* bitpos */
746 	 complain_overflow_signed,	/* complain_on_overflow */
747 	 bfd_elf_generic_reloc,		/* special_function */
748 	 "R_RISCV_TPREL_S",		/* name */
749 	 false,				/* partial_inplace */
750 	 0,				/* src_mask */
751 	 ENCODE_STYPE_IMM (-1U),	/* dst_mask */
752 	 false),			/* pcrel_offset */
753 
754   /* The paired relocation may be relaxed.  */
755   HOWTO (R_RISCV_RELAX,			/* type */
756 	 0,				/* rightshift */
757 	 0,				/* size */
758 	 0,				/* bitsize */
759 	 false,				/* pc_relative */
760 	 0,				/* bitpos */
761 	 complain_overflow_dont,	/* complain_on_overflow */
762 	 bfd_elf_generic_reloc,		/* special_function */
763 	 "R_RISCV_RELAX",		/* name */
764 	 false,				/* partial_inplace */
765 	 0,				/* src_mask */
766 	 0,				/* dst_mask */
767 	 false),			/* pcrel_offset */
768 
769   /* 6-bit in-place addition, for local label subtraction.  */
770   HOWTO (R_RISCV_SUB6,			/* type */
771 	 0,				/* rightshift */
772 	 1,				/* size */
773 	 8,				/* bitsize */
774 	 false,				/* pc_relative */
775 	 0,				/* bitpos */
776 	 complain_overflow_dont,	/* complain_on_overflow */
777 	 riscv_elf_add_sub_reloc,	/* special_function */
778 	 "R_RISCV_SUB6",		/* name */
779 	 false,				/* partial_inplace */
780 	 0,				/* src_mask */
781 	 0x3f,				/* dst_mask */
782 	 false),			/* pcrel_offset */
783 
784   /* 6-bit in-place setting, for local label subtraction.  */
785   HOWTO (R_RISCV_SET6,			/* type */
786 	 0,				/* rightshift */
787 	 1,				/* size */
788 	 8,				/* bitsize */
789 	 false,				/* pc_relative */
790 	 0,				/* bitpos */
791 	 complain_overflow_dont,	/* complain_on_overflow */
792 	 bfd_elf_generic_reloc,		/* special_function */
793 	 "R_RISCV_SET6",		/* name */
794 	 false,				/* partial_inplace */
795 	 0,				/* src_mask */
796 	 0x3f,				/* dst_mask */
797 	 false),			/* pcrel_offset */
798 
799   /* 8-bit in-place setting, for local label subtraction.  */
800   HOWTO (R_RISCV_SET8,			/* type */
801 	 0,				/* rightshift */
802 	 1,				/* size */
803 	 8,				/* bitsize */
804 	 false,				/* pc_relative */
805 	 0,				/* bitpos */
806 	 complain_overflow_dont,	/* complain_on_overflow */
807 	 bfd_elf_generic_reloc,		/* special_function */
808 	 "R_RISCV_SET8",		/* name */
809 	 false,				/* partial_inplace */
810 	 0,				/* src_mask */
811 	 0xff,				/* dst_mask */
812 	 false),			/* pcrel_offset */
813 
814   /* 16-bit in-place setting, for local label subtraction.  */
815   HOWTO (R_RISCV_SET16,			/* type */
816 	 0,				/* rightshift */
817 	 2,				/* size */
818 	 16,				/* bitsize */
819 	 false,				/* pc_relative */
820 	 0,				/* bitpos */
821 	 complain_overflow_dont,	/* complain_on_overflow */
822 	 bfd_elf_generic_reloc,		/* special_function */
823 	 "R_RISCV_SET16",		/* name */
824 	 false,				/* partial_inplace */
825 	 0,				/* src_mask */
826 	 0xffff,			/* dst_mask */
827 	 false),			/* pcrel_offset */
828 
829   /* 32-bit in-place setting, for local label subtraction.  */
830   HOWTO (R_RISCV_SET32,			/* type */
831 	 0,				/* rightshift */
832 	 4,				/* size */
833 	 32,				/* bitsize */
834 	 false,				/* pc_relative */
835 	 0,				/* bitpos */
836 	 complain_overflow_dont,	/* complain_on_overflow */
837 	 bfd_elf_generic_reloc,		/* special_function */
838 	 "R_RISCV_SET32",		/* name */
839 	 false,				/* partial_inplace */
840 	 0,				/* src_mask */
841 	 0xffffffff,			/* dst_mask */
842 	 false),			/* pcrel_offset */
843 
844   /* 32-bit PC relative.  */
845   HOWTO (R_RISCV_32_PCREL,		/* type */
846 	 0,				/* rightshift */
847 	 4,				/* size */
848 	 32,				/* bitsize */
849 	 true,				/* pc_relative */
850 	 0,				/* bitpos */
851 	 complain_overflow_dont,	/* complain_on_overflow */
852 	 bfd_elf_generic_reloc,		/* special_function */
853 	 "R_RISCV_32_PCREL",		/* name */
854 	 false,				/* partial_inplace */
855 	 0,				/* src_mask */
856 	 0xffffffff,			/* dst_mask */
857 	 false),			/* pcrel_offset */
858 
859   /* Relocation against a local ifunc symbol in a shared object.  */
860   HOWTO (R_RISCV_IRELATIVE,		/* type */
861 	 0,				/* rightshift */
862 	 4,				/* size */
863 	 32,				/* bitsize */
864 	 false,				/* pc_relative */
865 	 0,				/* bitpos */
866 	 complain_overflow_dont,	/* complain_on_overflow */
867 	 bfd_elf_generic_reloc,		/* special_function */
868 	 "R_RISCV_IRELATIVE",		/* name */
869 	 false,				/* partial_inplace */
870 	 0,				/* src_mask */
871 	 0xffffffff,			/* dst_mask */
872 	 false),			/* pcrel_offset */
873 };
874 
875 /* A mapping from BFD reloc types to RISC-V ELF reloc types.  */
876 struct elf_reloc_map
877 {
878   bfd_reloc_code_real_type bfd_val;
879   enum elf_riscv_reloc_type elf_val;
880 };
881 
882 static const struct elf_reloc_map riscv_reloc_map[] =
883 {
884   { BFD_RELOC_NONE, R_RISCV_NONE },
885   { BFD_RELOC_32, R_RISCV_32 },
886   { BFD_RELOC_64, R_RISCV_64 },
887   { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
888   { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
889   { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
890   { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
891   { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
892   { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
893   { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
894   { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
895   { BFD_RELOC_CTOR, R_RISCV_64 },
896   { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
897   { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
898   { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
899   { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
900   { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
901   { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
902   { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
903   { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
904   { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
905   { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
906   { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
907   { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
908   { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
909   { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
910   { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
911   { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
912   { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
913   { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
914   { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
915   { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
916   { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
917   { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
918   { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
919   { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
920   { BFD_RELOC_RISCV_RVC_BRANCH, R_RISCV_RVC_BRANCH },
921   { BFD_RELOC_RISCV_RVC_JUMP, R_RISCV_RVC_JUMP },
922   { BFD_RELOC_RISCV_RVC_LUI, R_RISCV_RVC_LUI },
923   { BFD_RELOC_RISCV_GPREL_I, R_RISCV_GPREL_I },
924   { BFD_RELOC_RISCV_GPREL_S, R_RISCV_GPREL_S },
925   { BFD_RELOC_RISCV_TPREL_I, R_RISCV_TPREL_I },
926   { BFD_RELOC_RISCV_TPREL_S, R_RISCV_TPREL_S },
927   { BFD_RELOC_RISCV_RELAX, R_RISCV_RELAX },
928   { BFD_RELOC_RISCV_SUB6, R_RISCV_SUB6 },
929   { BFD_RELOC_RISCV_SET6, R_RISCV_SET6 },
930   { BFD_RELOC_RISCV_SET8, R_RISCV_SET8 },
931   { BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
932   { BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
933   { BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
934 };
935 
936 /* Given a BFD reloc type, return a howto structure.  */
937 
938 reloc_howto_type *
939 riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
940 			 bfd_reloc_code_real_type code)
941 {
942   unsigned int i;
943 
944   for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
945     if (riscv_reloc_map[i].bfd_val == code)
946       return &howto_table[(int) riscv_reloc_map[i].elf_val];
947 
948   bfd_set_error (bfd_error_bad_value);
949   return NULL;
950 }
951 
952 reloc_howto_type *
953 riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED, const char *r_name)
954 {
955   unsigned int i;
956 
957   for (i = 0; i < ARRAY_SIZE (howto_table); i++)
958     if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
959       return &howto_table[i];
960 
961   return NULL;
962 }
963 
964 reloc_howto_type *
965 riscv_elf_rtype_to_howto (bfd *abfd, unsigned int r_type)
966 {
967   if (r_type >= ARRAY_SIZE (howto_table))
968     {
969       (*_bfd_error_handler) (_("%pB: unsupported relocation type %#x"),
970 			     abfd, r_type);
971       bfd_set_error (bfd_error_bad_value);
972       return NULL;
973     }
974   return &howto_table[r_type];
975 }
976 
977 /* Special_function of RISCV_ADD and RISCV_SUB relocations.  */
978 
979 static bfd_reloc_status_type
980 riscv_elf_add_sub_reloc (bfd *abfd,
981 			 arelent *reloc_entry,
982 			 asymbol *symbol,
983 			 void *data,
984 			 asection *input_section,
985 			 bfd *output_bfd,
986 			 char **error_message ATTRIBUTE_UNUSED)
987 {
988   reloc_howto_type *howto = reloc_entry->howto;
989   bfd_vma relocation;
990 
991   if (output_bfd != NULL
992       && (symbol->flags & BSF_SECTION_SYM) == 0
993       && (!reloc_entry->howto->partial_inplace || reloc_entry->addend == 0))
994     {
995       reloc_entry->address += input_section->output_offset;
996       return bfd_reloc_ok;
997     }
998 
999   if (output_bfd != NULL)
1000     return bfd_reloc_continue;
1001 
1002   relocation = symbol->value + symbol->section->output_section->vma
1003     + symbol->section->output_offset + reloc_entry->addend;
1004 
1005   bfd_size_type octets = reloc_entry->address
1006     * bfd_octets_per_byte (abfd, input_section);
1007   if (!bfd_reloc_offset_in_range (reloc_entry->howto, abfd,
1008 				  input_section, octets))
1009     return bfd_reloc_outofrange;
1010 
1011   bfd_vma old_value = bfd_get (howto->bitsize, abfd,
1012 			       data + reloc_entry->address);
1013 
1014   switch (howto->type)
1015     {
1016     case R_RISCV_ADD8:
1017     case R_RISCV_ADD16:
1018     case R_RISCV_ADD32:
1019     case R_RISCV_ADD64:
1020       relocation = old_value + relocation;
1021       break;
1022     case R_RISCV_SUB6:
1023     case R_RISCV_SUB8:
1024     case R_RISCV_SUB16:
1025     case R_RISCV_SUB32:
1026     case R_RISCV_SUB64:
1027       relocation = old_value - relocation;
1028       break;
1029     }
1030   bfd_put (howto->bitsize, abfd, relocation, data + reloc_entry->address);
1031 
1032   return bfd_reloc_ok;
1033 }
1034 
1035 /* Always add the IMPLICIT for the SUBSET.  */
1036 
1037 static bool
1038 check_implicit_always (const char *implicit ATTRIBUTE_UNUSED,
1039 		       riscv_subset_t *subset ATTRIBUTE_UNUSED)
1040 {
1041   return true;
1042 }
1043 
1044 /* Add the IMPLICIT only when the version of SUBSET less than 2.1.  */
1045 
1046 static bool
1047 check_implicit_for_i (const char *implicit ATTRIBUTE_UNUSED,
1048 		      riscv_subset_t *subset)
1049 {
1050   return (subset->major_version < 2
1051 	  || (subset->major_version == 2
1052 	      && subset->minor_version < 1));
1053 }
1054 
1055 /* Record all implicit information for the subsets.  */
1056 struct riscv_implicit_subset
1057 {
1058   const char *subset_name;
1059   const char *implicit_name;
1060   /* A function to determine if we need to add the implicit subset.  */
1061   bool (*check_func) (const char *, riscv_subset_t *);
1062 };
1063 static struct riscv_implicit_subset riscv_implicit_subsets[] =
1064 {
1065   {"e", "i",		check_implicit_always},
1066   {"i", "zicsr",	check_implicit_for_i},
1067   {"i", "zifencei",	check_implicit_for_i},
1068   {"g", "i",		check_implicit_always},
1069   {"g", "m",		check_implicit_always},
1070   {"g", "a",		check_implicit_always},
1071   {"g", "f",		check_implicit_always},
1072   {"g", "d",		check_implicit_always},
1073   {"g", "zicsr",	check_implicit_always},
1074   {"g", "zifencei",	check_implicit_always},
1075   {"q", "d",		check_implicit_always},
1076   {"v", "d",		check_implicit_always},
1077   {"v", "zve64d",	check_implicit_always},
1078   {"v", "zvl128b",	check_implicit_always},
1079   {"zve64d", "d",	check_implicit_always},
1080   {"zve64d", "zve64f",	check_implicit_always},
1081   {"zve64f", "zve32f",	check_implicit_always},
1082   {"zve64f", "zve64x",	check_implicit_always},
1083   {"zve64f", "zvl64b",	check_implicit_always},
1084   {"zve32f", "f",	check_implicit_always},
1085   {"zve32f", "zvl32b",	check_implicit_always},
1086   {"zve32f", "zve32x",	check_implicit_always},
1087   {"zve64x", "zve32x",	check_implicit_always},
1088   {"zve64x", "zvl64b",	check_implicit_always},
1089   {"zve32x", "zvl32b",	check_implicit_always},
1090   {"zvl65536b", "zvl32768b",	check_implicit_always},
1091   {"zvl32768b", "zvl16384b",	check_implicit_always},
1092   {"zvl16384b", "zvl8192b",	check_implicit_always},
1093   {"zvl8192b", "zvl4096b",	check_implicit_always},
1094   {"zvl4096b", "zvl2048b",	check_implicit_always},
1095   {"zvl2048b", "zvl1024b",	check_implicit_always},
1096   {"zvl1024b", "zvl512b",	check_implicit_always},
1097   {"zvl512b", "zvl256b",	check_implicit_always},
1098   {"zvl256b", "zvl128b",	check_implicit_always},
1099   {"zvl128b", "zvl64b",		check_implicit_always},
1100   {"zvl64b", "zvl32b",		check_implicit_always},
1101   {"d", "f",		check_implicit_always},
1102   {"zfh", "zfhmin",	check_implicit_always},
1103   {"zfhmin", "f",	check_implicit_always},
1104   {"f", "zicsr",	check_implicit_always},
1105   {"zqinx", "zdinx",	check_implicit_always},
1106   {"zdinx", "zfinx",	check_implicit_always},
1107   {"zhinx", "zhinxmin",	check_implicit_always},
1108   {"zhinxmin", "zfinx",	check_implicit_always},
1109   {"zfinx", "zicsr",	check_implicit_always},
1110   {"zk", "zkn",		check_implicit_always},
1111   {"zk", "zkr",		check_implicit_always},
1112   {"zk", "zkt",		check_implicit_always},
1113   {"zkn", "zbkb",	check_implicit_always},
1114   {"zkn", "zbkc",	check_implicit_always},
1115   {"zkn", "zbkx",	check_implicit_always},
1116   {"zkn", "zkne",	check_implicit_always},
1117   {"zkn", "zknd",	check_implicit_always},
1118   {"zkn", "zknh",	check_implicit_always},
1119   {"zks", "zbkb",	check_implicit_always},
1120   {"zks", "zbkc",	check_implicit_always},
1121   {"zks", "zbkx",	check_implicit_always},
1122   {"zks", "zksed",	check_implicit_always},
1123   {"zks", "zksh",	check_implicit_always},
1124   {NULL, NULL, NULL}
1125 };
1126 
1127 /* For default_enable field, decide if the extension should
1128    be enbaled by default.  */
1129 
1130 #define EXT_DEFAULT   0x1
1131 
1132 /* List all extensions that binutils should know about.  */
1133 
1134 struct riscv_supported_ext
1135 {
1136   const char *name;
1137   enum riscv_spec_class isa_spec_class;
1138   int major_version;
1139   int minor_version;
1140   unsigned long default_enable;
1141 };
1142 
1143 /* The standard extensions must be added in canonical order.  */
1144 
1145 static struct riscv_supported_ext riscv_supported_std_ext[] =
1146 {
1147   {"e",		ISA_SPEC_CLASS_20191213,	1, 9, 0 },
1148   {"e",		ISA_SPEC_CLASS_20190608,	1, 9, 0 },
1149   {"e",		ISA_SPEC_CLASS_2P2,		1, 9, 0 },
1150   {"i",		ISA_SPEC_CLASS_20191213,	2, 1, 0 },
1151   {"i",		ISA_SPEC_CLASS_20190608,	2, 1, 0 },
1152   {"i",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1153   /* The g is a special case which we don't want to output it,
1154      but still need it when adding implicit extensions.  */
1155   {"g",		ISA_SPEC_CLASS_NONE, RISCV_UNKNOWN_VERSION, RISCV_UNKNOWN_VERSION, EXT_DEFAULT },
1156   {"m",		ISA_SPEC_CLASS_20191213,	2, 0, 0 },
1157   {"m",		ISA_SPEC_CLASS_20190608,	2, 0, 0 },
1158   {"m",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1159   {"a",		ISA_SPEC_CLASS_20191213,	2, 1, 0 },
1160   {"a",		ISA_SPEC_CLASS_20190608,	2, 0, 0 },
1161   {"a",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1162   {"f",		ISA_SPEC_CLASS_20191213,	2, 2, 0 },
1163   {"f",		ISA_SPEC_CLASS_20190608,	2, 2, 0 },
1164   {"f",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1165   {"d",		ISA_SPEC_CLASS_20191213,	2, 2, 0 },
1166   {"d",		ISA_SPEC_CLASS_20190608,	2, 2, 0 },
1167   {"d",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1168   {"q",		ISA_SPEC_CLASS_20191213,	2, 2, 0 },
1169   {"q",		ISA_SPEC_CLASS_20190608,	2, 2, 0 },
1170   {"q",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1171   {"c",		ISA_SPEC_CLASS_20191213,	2, 0, 0 },
1172   {"c",		ISA_SPEC_CLASS_20190608,	2, 0, 0 },
1173   {"c",		ISA_SPEC_CLASS_2P2,		2, 0, 0 },
1174   {"v",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1175   {"h",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1176   {NULL, 0, 0, 0, 0}
1177 };
1178 
1179 static struct riscv_supported_ext riscv_supported_std_z_ext[] =
1180 {
1181   {"zicbom",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1182   {"zicbop",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1183   {"zicboz",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1184   {"zicsr",		ISA_SPEC_CLASS_20191213,	2, 0,  0 },
1185   {"zicsr",		ISA_SPEC_CLASS_20190608,	2, 0,  0 },
1186   {"zifencei",		ISA_SPEC_CLASS_20191213,	2, 0,  0 },
1187   {"zifencei",		ISA_SPEC_CLASS_20190608,	2, 0,  0 },
1188   {"zihintpause",	ISA_SPEC_CLASS_DRAFT,		2, 0,  0 },
1189   {"zfh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1190   {"zfhmin",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1191   {"zfinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1192   {"zdinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1193   {"zqinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1194   {"zhinx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1195   {"zhinxmin",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1196   {"zbb",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1197   {"zba",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1198   {"zbc",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1199   {"zbs",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1200   {"zbkb",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1201   {"zbkc",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1202   {"zbkx",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1203   {"zk",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1204   {"zkn",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1205   {"zknd",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1206   {"zkne",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1207   {"zknh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1208   {"zkr",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1209   {"zks",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1210   {"zksed",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1211   {"zksh",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1212   {"zkt",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1213   {"zve32x",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1214   {"zve32f",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1215   {"zve32d",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1216   {"zve64x",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1217   {"zve64f",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1218   {"zve64d",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1219   {"zvl32b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1220   {"zvl64b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1221   {"zvl128b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1222   {"zvl256b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1223   {"zvl512b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1224   {"zvl1024b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1225   {"zvl2048b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1226   {"zvl4096b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1227   {"zvl8192b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1228   {"zvl16384b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1229   {"zvl32768b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1230   {"zvl65536b",		ISA_SPEC_CLASS_DRAFT,		1, 0,  0 },
1231   {NULL, 0, 0, 0, 0}
1232 };
1233 
1234 static struct riscv_supported_ext riscv_supported_std_s_ext[] =
1235 {
1236   {"smstateen",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1237   {"sscofpmf",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1238   {"sstc",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1239   {"svinval",		ISA_SPEC_CLASS_DRAFT,		1, 0, 0 },
1240   {NULL, 0, 0, 0, 0}
1241 };
1242 
1243 static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
1244 {
1245   {NULL, 0, 0, 0, 0}
1246 };
1247 
1248 const struct riscv_supported_ext *riscv_all_supported_ext[] =
1249 {
1250   riscv_supported_std_ext,
1251   riscv_supported_std_z_ext,
1252   riscv_supported_std_s_ext,
1253   riscv_supported_std_zxm_ext,
1254   NULL
1255 };
1256 
1257 /* ISA extension prefixed name class.  Must define them in parsing order.  */
1258 enum riscv_prefix_ext_class
1259 {
1260   RV_ISA_CLASS_Z = 1,
1261   RV_ISA_CLASS_S,
1262   RV_ISA_CLASS_ZXM,
1263   RV_ISA_CLASS_X,
1264   RV_ISA_CLASS_UNKNOWN
1265 };
1266 
1267 /* Record the strings of the prefixed extensions, and their corresponding
1268    classes.  The more letters of the prefix string, the more forward it must
1269    be defined.  Otherwise, the riscv_get_prefix_class will map it to the
1270    wrong classes.  */
1271 struct riscv_parse_prefix_config
1272 {
1273   /* Class of the extension. */
1274   enum riscv_prefix_ext_class class;
1275 
1276   /* Prefix string for error printing and internal parser usage.  */
1277   const char *prefix;
1278 };
1279 static const struct riscv_parse_prefix_config parse_config[] =
1280 {
1281   {RV_ISA_CLASS_ZXM, "zxm"},
1282   {RV_ISA_CLASS_Z, "z"},
1283   {RV_ISA_CLASS_S, "s"},
1284   {RV_ISA_CLASS_X, "x"},
1285   {RV_ISA_CLASS_UNKNOWN, NULL}
1286 };
1287 
1288 /* Get the prefixed name class for the extensions, the class also
1289    means the order of the prefixed extensions.  */
1290 
1291 static enum riscv_prefix_ext_class
1292 riscv_get_prefix_class (const char *arch)
1293 {
1294   int i = 0;
1295   while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN)
1296     {
1297       if (strncmp (arch, parse_config[i].prefix,
1298 		   strlen (parse_config[i].prefix)) == 0)
1299 	return parse_config[i].class;
1300       i++;
1301     }
1302   return RV_ISA_CLASS_UNKNOWN;
1303 }
1304 
1305 /* Check KNOWN_EXTS to see if the EXT is supported.  */
1306 
1307 static bool
1308 riscv_known_prefixed_ext (const char *ext,
1309 			  struct riscv_supported_ext *known_exts)
1310 {
1311   size_t i;
1312   for (i = 0; known_exts[i].name != NULL; ++i)
1313     if (strcmp (ext, known_exts[i].name) == 0)
1314       return true;
1315   return false;
1316 }
1317 
1318 /* Check whether the prefixed extension is recognized or not.  Return
1319    true if recognized, otehrwise return false.  */
1320 
1321 static bool
1322 riscv_recognized_prefixed_ext (const char *ext)
1323 {
1324   enum riscv_prefix_ext_class class = riscv_get_prefix_class (ext);
1325   switch (class)
1326   {
1327   case RV_ISA_CLASS_Z:
1328     return riscv_known_prefixed_ext (ext, riscv_supported_std_z_ext);
1329   case RV_ISA_CLASS_ZXM:
1330     return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
1331   case RV_ISA_CLASS_S:
1332     return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
1333   case RV_ISA_CLASS_X:
1334     /* Only the single x is unrecognized.  */
1335     if (strcmp (ext, "x") != 0)
1336       return true;
1337   default:
1338     break;
1339   }
1340   return false;
1341 }
1342 
1343 /* Canonical order for single letter extensions.  */
1344 static const char riscv_ext_canonical_order[] = "eigmafdqlcbkjtpvnh";
1345 
1346 /* Array is used to compare the orders of standard extensions quickly.  */
1347 static int riscv_ext_order[26] = {0};
1348 
1349 /* Init the riscv_ext_order array.  */
1350 
1351 static void
1352 riscv_init_ext_order (void)
1353 {
1354   static bool inited = false;
1355   if (inited)
1356     return;
1357 
1358   /* The orders of all standard extensions are positive.  */
1359   int order = 1;
1360 
1361   for (const char *ext = &riscv_ext_canonical_order[0]; *ext; ++ext)
1362     riscv_ext_order[(*ext - 'a')] = order++;
1363 
1364   /* Some of the prefixed keyword are not single letter, so we set
1365      their prefixed orders in the riscv_compare_subsets directly,
1366      not through the riscv_ext_order.  */
1367 
1368   inited = true;
1369 }
1370 
1371 /* Similar to the strcmp.  It returns an integer less than, equal to,
1372    or greater than zero if `subset2` is found, respectively, to be less
1373    than, to match, or be greater than `subset1`.
1374 
1375    The order values,
1376    Zero: Preserved keywords.
1377    Positive number: Standard extensions.
1378    Negative number: Prefixed keywords.  */
1379 
1380 int
1381 riscv_compare_subsets (const char *subset1, const char *subset2)
1382 {
1383   int order1 = riscv_ext_order[(*subset1 - 'a')];
1384   int order2 = riscv_ext_order[(*subset2 - 'a')];
1385 
1386   /* Compare the standard extension first.  */
1387   if (order1 > 0 && order2 > 0)
1388     return order1 - order2;
1389 
1390   /* Set the prefixed orders to negative numbers.  */
1391   enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1);
1392   enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2);
1393 
1394   if (class1 != RV_ISA_CLASS_UNKNOWN)
1395     order1 = - (int) class1;
1396   if (class2 != RV_ISA_CLASS_UNKNOWN)
1397     order2 = - (int) class2;
1398 
1399   if (order1 == order2)
1400     {
1401       /* Compare the standard addition z extensions.  */
1402       if (class1 == RV_ISA_CLASS_Z)
1403 	{
1404 	  order1 = riscv_ext_order[(*++subset1 - 'a')];
1405 	  order2 = riscv_ext_order[(*++subset2 - 'a')];
1406 	  if (order1 != order2)
1407 	    return order1 - order2;
1408 	}
1409       return strcasecmp (++subset1, ++subset2);
1410     }
1411 
1412   return order2 - order1;
1413 }
1414 
1415 /* Find subset in the list.  Return TRUE and set `current` to the subset
1416    if it is found.  Otherwise, return FALSE and set `current` to the place
1417    where we should insert the subset.  However, return FALSE with the NULL
1418    `current` means we should insert the subset at the head of subset list,
1419    if needed.  */
1420 
1421 bool
1422 riscv_lookup_subset (const riscv_subset_list_t *subset_list,
1423 		     const char *subset,
1424 		     riscv_subset_t **current)
1425 {
1426   riscv_subset_t *s, *pre_s = NULL;
1427 
1428   /* If the subset is added in order, then just add it at the tail.  */
1429   if (subset_list->tail != NULL
1430       && riscv_compare_subsets (subset_list->tail->name, subset) < 0)
1431     {
1432       *current = subset_list->tail;
1433       return false;
1434     }
1435 
1436   for (s = subset_list->head;
1437        s != NULL;
1438        pre_s = s, s = s->next)
1439     {
1440       int cmp = riscv_compare_subsets (s->name, subset);
1441       if (cmp == 0)
1442 	{
1443 	  *current = s;
1444 	  return true;
1445 	}
1446       else if (cmp > 0)
1447 	break;
1448     }
1449   *current = pre_s;
1450 
1451   return false;
1452 }
1453 
1454 /* Add the extension to the subset list.  Search the
1455    list first, and then find the right place to add.  */
1456 
1457 void
1458 riscv_add_subset (riscv_subset_list_t *subset_list,
1459 		  const char *subset,
1460 		  int major,
1461 		  int minor)
1462 {
1463   riscv_subset_t *current, *new;
1464 
1465   if (riscv_lookup_subset (subset_list, subset, &current))
1466     return;
1467 
1468   new = xmalloc (sizeof *new);
1469   new->name = xstrdup (subset);
1470   new->major_version = major;
1471   new->minor_version = minor;
1472   new->next = NULL;
1473 
1474   if (current != NULL)
1475     {
1476       new->next = current->next;
1477       current->next = new;
1478     }
1479   else
1480     {
1481       new->next = subset_list->head;
1482       subset_list->head = new;
1483     }
1484 
1485   if (new->next == NULL)
1486     subset_list->tail = new;
1487 }
1488 
1489 /* Get the default versions from the riscv_supported_*ext tables.  */
1490 
1491 static void
1492 riscv_get_default_ext_version (enum riscv_spec_class *default_isa_spec,
1493 			       const char *name,
1494 			       int *major_version,
1495 			       int *minor_version)
1496 {
1497   if (name == NULL
1498       || default_isa_spec == NULL
1499       || *default_isa_spec == ISA_SPEC_CLASS_NONE)
1500     return;
1501 
1502   struct riscv_supported_ext *table = NULL;
1503   enum riscv_prefix_ext_class class = riscv_get_prefix_class (name);
1504   switch (class)
1505     {
1506     case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
1507     case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
1508     case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
1509     case RV_ISA_CLASS_X:
1510       break;
1511     default:
1512       table = riscv_supported_std_ext;
1513     }
1514 
1515   int i = 0;
1516   while (table != NULL && table[i].name != NULL)
1517     {
1518       if (strcmp (table[i].name, name) == 0
1519 	  && (table[i].isa_spec_class == ISA_SPEC_CLASS_DRAFT
1520 	      || table[i].isa_spec_class == *default_isa_spec))
1521 	{
1522 	  *major_version = table[i].major_version;
1523 	  *minor_version = table[i].minor_version;
1524 	  return;
1525 	}
1526       i++;
1527     }
1528 }
1529 
1530 /* Find the default versions for the extension before adding them to
1531    the subset list, if their versions are RISCV_UNKNOWN_VERSION.
1532    Afterwards, report errors if we can not find their default versions.  */
1533 
1534 static void
1535 riscv_parse_add_subset (riscv_parse_subset_t *rps,
1536 			const char *subset,
1537 			int major,
1538 			int minor,
1539 			bool implicit)
1540 {
1541   int major_version = major;
1542   int minor_version = minor;
1543 
1544   if (major_version == RISCV_UNKNOWN_VERSION
1545        || minor_version == RISCV_UNKNOWN_VERSION)
1546     riscv_get_default_ext_version (rps->isa_spec, subset,
1547 				   &major_version, &minor_version);
1548 
1549   /* We don't care the versions of the implicit extensions.  */
1550   if (!implicit
1551       && (major_version == RISCV_UNKNOWN_VERSION
1552 	  || minor_version == RISCV_UNKNOWN_VERSION))
1553     {
1554       if (subset[0] == 'x')
1555 	rps->error_handler
1556 	  (_("x ISA extension `%s' must be set with the versions"),
1557 	   subset);
1558       /* Allow old ISA spec can recognize zicsr and zifencei.  */
1559       else if (strcmp (subset, "zicsr") != 0
1560 	       && strcmp (subset, "zifencei") != 0)
1561 	rps->error_handler
1562 	  (_("cannot find default versions of the ISA extension `%s'"),
1563 	   subset);
1564       return;
1565     }
1566 
1567   riscv_add_subset (rps->subset_list, subset,
1568 		    major_version, minor_version);
1569 }
1570 
1571 /* Release subset list.  */
1572 
1573 void
1574 riscv_release_subset_list (riscv_subset_list_t *subset_list)
1575 {
1576    while (subset_list->head != NULL)
1577     {
1578       riscv_subset_t *next = subset_list->head->next;
1579       free ((void *)subset_list->head->name);
1580       free (subset_list->head);
1581       subset_list->head = next;
1582     }
1583 
1584   subset_list->tail = NULL;
1585 }
1586 
1587 /* Parsing extension version.
1588 
1589    Return Value:
1590      Points to the end of version
1591 
1592    Arguments:
1593      `p`: Curent parsing position.
1594      `major_version`: Parsed major version.
1595      `minor_version`: Parsed minor version.  */
1596 
1597 static const char *
1598 riscv_parsing_subset_version (const char *p,
1599 			      int *major_version,
1600 			      int *minor_version)
1601 {
1602   bool major_p = true;
1603   int version = 0;
1604   char np;
1605 
1606   *major_version = 0;
1607   *minor_version = 0;
1608   for (; *p; ++p)
1609     {
1610       if (*p == 'p')
1611 	{
1612 	  np = *(p + 1);
1613 
1614 	  /* Might be beginning of `p` extension.  */
1615 	  if (!ISDIGIT (np))
1616 	    break;
1617 
1618 	  *major_version = version;
1619 	  major_p = false;
1620 	  version = 0;
1621 	}
1622       else if (ISDIGIT (*p))
1623 	version = (version * 10) + (*p - '0');
1624       else
1625 	break;
1626     }
1627 
1628   if (major_p)
1629     *major_version = version;
1630   else
1631     *minor_version = version;
1632 
1633   /* We can not find any version in string.  */
1634   if (*major_version == 0 && *minor_version == 0)
1635     {
1636       *major_version = RISCV_UNKNOWN_VERSION;
1637       *minor_version = RISCV_UNKNOWN_VERSION;
1638     }
1639 
1640   return p;
1641 }
1642 
1643 /* Parsing function for standard extensions.
1644 
1645    Return Value:
1646      Points to the end of extensions.
1647 
1648    Arguments:
1649      `rps`: Hooks and status for parsing extensions.
1650      `arch`: Full ISA string.
1651      `p`: Curent parsing position.  */
1652 
1653 static const char *
1654 riscv_parse_std_ext (riscv_parse_subset_t *rps,
1655 		     const char *arch,
1656 		     const char *p)
1657 {
1658   /* First letter must start with i, e or g.  */
1659   if (*p != 'e' && *p != 'i' && *p != 'g')
1660     {
1661       rps->error_handler
1662 	(_("%s: first ISA extension must be `e', `i' or `g'"),
1663 	 arch);
1664       return NULL;
1665     }
1666 
1667   while (p != NULL && *p != '\0')
1668     {
1669       /* Stop when we parsed the known prefix class.  */
1670       enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
1671       if (class != RV_ISA_CLASS_UNKNOWN)
1672 	break;
1673 
1674       if (*p == '_')
1675 	{
1676 	  p++;
1677 	  continue;
1678 	}
1679 
1680       bool implicit = false;
1681       int major = RISCV_UNKNOWN_VERSION;
1682       int minor = RISCV_UNKNOWN_VERSION;
1683       char subset[2] = {0, 0};
1684 
1685       subset[0] = *p;
1686 
1687       /* Check if the standard extension is supported.  */
1688       if (riscv_ext_order[(subset[0] - 'a')] == 0)
1689 	{
1690 	  rps->error_handler
1691 	    (_("%s: unknown standard ISA extension `%c'"),
1692 	     arch, subset[0]);
1693 	  return NULL;
1694 	}
1695 
1696       /* Checking canonical order.  */
1697       if (rps->subset_list->tail != NULL
1698 	  && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
1699 	{
1700 	  rps->error_handler
1701 	    (_("%s: standard ISA extension `%c' is not "
1702 	       "in canonical order"), arch, subset[0]);
1703 	  return NULL;
1704 	}
1705 
1706       p = riscv_parsing_subset_version (++p, &major, &minor);
1707       /* Added g as an implicit extension.  */
1708       if (subset[0] == 'g')
1709 	{
1710 	  implicit = true;
1711 	  major = RISCV_UNKNOWN_VERSION;
1712 	  minor = RISCV_UNKNOWN_VERSION;
1713 	}
1714       riscv_parse_add_subset (rps, subset, major, minor, implicit);
1715     }
1716 
1717   return p;
1718 }
1719 
1720 /* Parsing function for prefixed extensions.
1721 
1722    Return Value:
1723      Points to the end of extension.
1724 
1725    Arguments:
1726      `rps`: Hooks and status for parsing extensions.
1727      `arch`: Full ISA string.
1728      `p`: Curent parsing position.  */
1729 
1730 static const char *
1731 riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
1732 			  const char *arch,
1733 			  const char *p)
1734 {
1735   int major_version;
1736   int minor_version;
1737   enum riscv_prefix_ext_class class;
1738 
1739   while (*p)
1740     {
1741       if (*p == '_')
1742 	{
1743 	  p++;
1744 	  continue;
1745 	}
1746 
1747       class = riscv_get_prefix_class (p);
1748       if (class == RV_ISA_CLASS_UNKNOWN)
1749 	{
1750 	  rps->error_handler
1751 	    (_("%s: unknown prefix class for the ISA extension `%s'"),
1752 	     arch, p);
1753 	  return NULL;
1754 	}
1755 
1756       char *subset = xstrdup (p);
1757       char *q = subset;
1758       const char *end_of_version;
1759 
1760       /* Extract the whole prefixed extension by '_'.  */
1761       while (*++q != '\0' && *q != '_')
1762 	;
1763       /* Look forward to the first letter which is not <major>p<minor>.  */
1764       bool find_any_version = false;
1765       bool find_minor_version = false;
1766       while (1)
1767 	{
1768 	  q--;
1769 	  if (ISDIGIT (*q))
1770 	    find_any_version = true;
1771 	  else if (find_any_version
1772 		   && !find_minor_version
1773 		   && *q == 'p'
1774 		   && ISDIGIT (*(q - 1)))
1775 	    find_minor_version = true;
1776 	  else
1777 	    break;
1778 	}
1779       q++;
1780 
1781       /* Check if the end of extension is 'p' or not.  If yes, then
1782 	 the second letter from the end cannot be number.  */
1783       if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
1784 	{
1785 	  *q = '\0';
1786 	  rps->error_handler
1787 	    (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
1788 	     arch, subset);
1789 	  free (subset);
1790 	  return NULL;
1791 	}
1792 
1793       end_of_version =
1794 	riscv_parsing_subset_version (q, &major_version, &minor_version);
1795       *q = '\0';
1796       if (end_of_version == NULL)
1797 	{
1798 	  free (subset);
1799 	  return NULL;
1800 	}
1801 
1802       /* Check that the extension name is well-formed.  */
1803       if (rps->check_unknown_prefixed_ext
1804 	  && !riscv_recognized_prefixed_ext (subset))
1805 	{
1806 	  rps->error_handler
1807 	    (_("%s: unknown prefixed ISA extension `%s'"),
1808 	     arch, subset);
1809 	  free (subset);
1810 	  return NULL;
1811 	}
1812 
1813       riscv_parse_add_subset (rps, subset,
1814 			      major_version,
1815 			      minor_version, false);
1816       p += end_of_version - subset;
1817       free (subset);
1818 
1819       if (*p != '\0' && *p != '_')
1820 	{
1821 	  rps->error_handler
1822 	    (_("%s: prefixed ISA extension must separate with _"),
1823 	     arch);
1824 	  return NULL;
1825 	}
1826     }
1827 
1828   return p;
1829 }
1830 
1831 /* Add the implicit extensions.  */
1832 
1833 static void
1834 riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
1835 {
1836   struct riscv_implicit_subset *t = riscv_implicit_subsets;
1837   for (; t->subset_name; t++)
1838     {
1839       riscv_subset_t *subset = NULL;
1840       if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
1841 	  && t->check_func (t->implicit_name, subset))
1842 	riscv_parse_add_subset (rps, t->implicit_name,
1843 				RISCV_UNKNOWN_VERSION,
1844 				RISCV_UNKNOWN_VERSION, true);
1845     }
1846 }
1847 
1848 /* Check extensions conflicts.  */
1849 
1850 static bool
1851 riscv_parse_check_conflicts (riscv_parse_subset_t *rps)
1852 {
1853   riscv_subset_t *subset = NULL;
1854   int xlen = *rps->xlen;
1855   bool no_conflict = true;
1856 
1857   if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1858       && xlen > 32)
1859     {
1860       rps->error_handler
1861 	(_("rv%d does not support the `e' extension"), xlen);
1862       no_conflict = false;
1863     }
1864   if (riscv_lookup_subset (rps->subset_list, "q", &subset)
1865       && (subset->major_version < 2 || (subset->major_version == 2
1866 					&& subset->minor_version < 2))
1867       && xlen < 64)
1868     {
1869       rps->error_handler (_("rv%d does not support the `q' extension"), xlen);
1870       no_conflict = false;
1871     }
1872   if (riscv_lookup_subset (rps->subset_list, "e", &subset)
1873       && riscv_lookup_subset (rps->subset_list, "f", &subset))
1874     {
1875       rps->error_handler
1876         (_("rv32e does not support the `f' extension"));
1877       no_conflict = false;
1878     }
1879   if (riscv_lookup_subset (rps->subset_list, "zfinx", &subset)
1880       && riscv_lookup_subset (rps->subset_list, "f", &subset))
1881     {
1882       rps->error_handler
1883 	(_("`zfinx' is conflict with the `f/d/q/zfh/zfhmin' extension"));
1884       no_conflict = false;
1885     }
1886 
1887   bool support_zve = false;
1888   bool support_zvl = false;
1889   riscv_subset_t *s = rps->subset_list->head;
1890   for (; s != NULL; s = s->next)
1891     {
1892       if (!support_zve
1893 	  && strncmp (s->name, "zve", 3) == 0)
1894 	support_zve = true;
1895       if (!support_zvl
1896 	  && strncmp (s->name, "zvl", 3) == 0)
1897 	support_zvl = true;
1898       if (support_zve && support_zvl)
1899 	break;
1900     }
1901   if (support_zvl && !support_zve)
1902     {
1903       rps->error_handler
1904 	(_("zvl*b extensions need to enable either `v' or `zve' extension"));
1905       no_conflict = false;
1906     }
1907 
1908   return no_conflict;
1909 }
1910 
1911 /* Set the default subset list according to the default_enable field
1912    of riscv_supported_*ext tables.  */
1913 
1914 static void
1915 riscv_set_default_arch (riscv_parse_subset_t *rps)
1916 {
1917   unsigned long enable = EXT_DEFAULT;
1918   int i, j;
1919   for (i = 0; riscv_all_supported_ext[i] != NULL; i++)
1920     {
1921       const struct riscv_supported_ext *table = riscv_all_supported_ext[i];
1922       for (j = 0; table[j].name != NULL; j++)
1923 	{
1924 	  bool implicit = false;
1925 	  if (strcmp (table[j].name, "g") == 0)
1926 	    implicit = true;
1927 	  if (table[j].default_enable & enable)
1928 	    riscv_parse_add_subset (rps, table[j].name,
1929 				    RISCV_UNKNOWN_VERSION,
1930 				    RISCV_UNKNOWN_VERSION, implicit);
1931 	}
1932     }
1933 }
1934 
1935 /* Function for parsing ISA string.
1936 
1937    Return Value:
1938      Return TRUE on success.
1939 
1940    Arguments:
1941      `rps`: Hooks and status for parsing extensions.
1942      `arch`: Full ISA string.  */
1943 
1944 bool
1945 riscv_parse_subset (riscv_parse_subset_t *rps,
1946 		    const char *arch)
1947 {
1948   const char *p;
1949 
1950   /* Init the riscv_ext_order array to compare the order of extensions
1951      quickly.  */
1952   riscv_init_ext_order ();
1953 
1954   if (arch == NULL)
1955     {
1956       riscv_set_default_arch (rps);
1957       riscv_parse_add_implicit_subsets (rps);
1958       return riscv_parse_check_conflicts (rps);
1959     }
1960 
1961   for (p = arch; *p != '\0'; p++)
1962     {
1963       if (ISUPPER (*p))
1964 	{
1965 	  rps->error_handler
1966 	    (_("%s: ISA string cannot contain uppercase letters"),
1967 	     arch);
1968 	  return false;
1969 	}
1970     }
1971 
1972   p = arch;
1973   if (startswith (p, "rv32"))
1974     {
1975       *rps->xlen = 32;
1976       p += 4;
1977     }
1978   else if (startswith (p, "rv64"))
1979     {
1980       *rps->xlen = 64;
1981       p += 4;
1982     }
1983   else
1984     {
1985       /* ISA string shouldn't be NULL or empty here.  For linker,
1986 	 it might be empty when we failed to merge the ISA string
1987 	 in the riscv_merge_attributes.  For assembler, we might
1988 	 give an empty string by .attribute arch, "" or -march=.
1989 	 However, We have already issued the correct error message
1990 	 in another side, so do not issue this error when the ISA
1991 	 string is empty.  */
1992       if (strlen (arch))
1993 	rps->error_handler (
1994 	  _("%s: ISA string must begin with rv32 or rv64"),
1995 	  arch);
1996       return false;
1997     }
1998 
1999   /* Parsing standard extension.  */
2000   p = riscv_parse_std_ext (rps, arch, p);
2001 
2002   if (p == NULL)
2003     return false;
2004 
2005   /* Parse prefixed extensions.  */
2006   p = riscv_parse_prefixed_ext (rps, arch, p);
2007 
2008   if (p == NULL)
2009     return false;
2010 
2011   /* Finally add implicit extensions according to the current
2012      extensions.  */
2013   riscv_parse_add_implicit_subsets (rps);
2014 
2015   /* Check the conflicts.  */
2016   return riscv_parse_check_conflicts (rps);
2017 }
2018 
2019 /* Return the number of digits for the input.  */
2020 
2021 size_t
2022 riscv_estimate_digit (unsigned num)
2023 {
2024   size_t digit = 0;
2025   if (num == 0)
2026     return 1;
2027 
2028   for (digit = 0; num ; num /= 10)
2029     digit++;
2030 
2031   return digit;
2032 }
2033 
2034 /* Auxiliary function to estimate string length of subset list.  */
2035 
2036 static size_t
2037 riscv_estimate_arch_strlen1 (const riscv_subset_t *subset)
2038 {
2039   if (subset == NULL)
2040     return 6; /* For rv32/rv64/rv128 and string terminator.  */
2041 
2042   return riscv_estimate_arch_strlen1 (subset->next)
2043 	 + strlen (subset->name)
2044 	 + riscv_estimate_digit (subset->major_version)
2045 	 + 1 /* For version seperator 'p'.  */
2046 	 + riscv_estimate_digit (subset->minor_version)
2047 	 + 1 /* For underscore.  */;
2048 }
2049 
2050 /* Estimate the string length of this subset list.  */
2051 
2052 static size_t
2053 riscv_estimate_arch_strlen (const riscv_subset_list_t *subset_list)
2054 {
2055   return riscv_estimate_arch_strlen1 (subset_list->head);
2056 }
2057 
2058 /* Auxiliary function to convert subset info to string.  */
2059 
2060 static void
2061 riscv_arch_str1 (riscv_subset_t *subset,
2062 		 char *attr_str, char *buf, size_t bufsz)
2063 {
2064   const char *underline = "_";
2065   riscv_subset_t *subset_t = subset;
2066 
2067   if (subset_t == NULL)
2068     return;
2069 
2070   /* No underline between rvXX and i/e.  */
2071   if ((strcasecmp (subset_t->name, "i") == 0)
2072       || (strcasecmp (subset_t->name, "e") == 0))
2073     underline = "";
2074 
2075   snprintf (buf, bufsz, "%s%s%dp%d",
2076 	    underline,
2077 	    subset_t->name,
2078 	    subset_t->major_version,
2079 	    subset_t->minor_version);
2080 
2081   strncat (attr_str, buf, bufsz);
2082 
2083   /* Skip 'i' extension after 'e', or skip extensions which
2084      versions are unknown.  */
2085   while (subset_t->next
2086 	 && ((strcmp (subset_t->name, "e") == 0
2087 	      && strcmp (subset_t->next->name, "i") == 0)
2088 	     || subset_t->next->major_version == RISCV_UNKNOWN_VERSION
2089 	     || subset_t->next->minor_version == RISCV_UNKNOWN_VERSION))
2090     subset_t = subset_t->next;
2091 
2092   riscv_arch_str1 (subset_t->next, attr_str, buf, bufsz);
2093 }
2094 
2095 /* Convert subset information into string with explicit versions.  */
2096 
2097 char *
2098 riscv_arch_str (unsigned xlen, const riscv_subset_list_t *subset)
2099 {
2100   size_t arch_str_len = riscv_estimate_arch_strlen (subset);
2101   char *attr_str = xmalloc (arch_str_len);
2102   char *buf = xmalloc (arch_str_len);
2103 
2104   snprintf (attr_str, arch_str_len, "rv%u", xlen);
2105 
2106   riscv_arch_str1 (subset->head, attr_str, buf, arch_str_len);
2107   free (buf);
2108 
2109   return attr_str;
2110 }
2111 
2112 /* Copy the subset in the subset list.  */
2113 
2114 static struct riscv_subset_t *
2115 riscv_copy_subset (riscv_subset_list_t *subset_list,
2116 		   riscv_subset_t *subset)
2117 {
2118   if (subset == NULL)
2119     return NULL;
2120 
2121   riscv_subset_t *new = xmalloc (sizeof *new);
2122   new->name = xstrdup (subset->name);
2123   new->major_version = subset->major_version;
2124   new->minor_version = subset->minor_version;
2125   new->next = riscv_copy_subset (subset_list, subset->next);
2126 
2127   if (subset->next == NULL)
2128     subset_list->tail = new;
2129 
2130   return new;
2131 }
2132 
2133 /* Copy the subset list.  */
2134 
2135 riscv_subset_list_t *
2136 riscv_copy_subset_list (riscv_subset_list_t *subset_list)
2137 {
2138   riscv_subset_list_t *new = xmalloc (sizeof *new);
2139   new->head = riscv_copy_subset (new, subset_list->head);
2140   return new;
2141 }
2142 
2143 /* Remove the SUBSET from the subset list.  */
2144 
2145 static void
2146 riscv_remove_subset (riscv_subset_list_t *subset_list,
2147 		     const char *subset)
2148 {
2149   riscv_subset_t *current = subset_list->head;
2150   riscv_subset_t *pre = NULL;
2151   for (; current != NULL; pre = current, current = current->next)
2152     {
2153       if (strcmp (current->name, subset) == 0)
2154 	{
2155 	  if (pre == NULL)
2156 	    subset_list->head = current->next;
2157 	  else
2158 	    pre->next = current->next;
2159 	  if (current->next == NULL)
2160 	    subset_list->tail = pre;
2161 	  free ((void *) current->name);
2162 	  free (current);
2163 	  break;
2164 	}
2165     }
2166 }
2167 
2168 /* Add/Remove an extension to/from the subset list.  This is used for
2169    the .option rvc or norvc, and .option arch directives.  */
2170 
2171 bool
2172 riscv_update_subset (riscv_parse_subset_t *rps,
2173 		     const char *str)
2174 {
2175   const char *p = str;
2176 
2177   do
2178     {
2179       int major_version = RISCV_UNKNOWN_VERSION;
2180       int minor_version = RISCV_UNKNOWN_VERSION;
2181 
2182       bool removed = false;
2183       switch (*p)
2184 	{
2185 	case '+': removed = false; break;
2186 	case '-': removed = true; break;
2187 	default:
2188 	  riscv_release_subset_list (rps->subset_list);
2189 	  return riscv_parse_subset (rps, p);
2190 	}
2191       ++p;
2192 
2193       char *subset = xstrdup (p);
2194       char *q = subset;
2195       const char *end_of_version;
2196       /* Extract the whole prefixed extension by ','.  */
2197       while (*q != '\0' && *q != ',')
2198         q++;
2199 
2200       /* Look forward to the first letter which is not <major>p<minor>.  */
2201       bool find_any_version = false;
2202       bool find_minor_version = false;
2203       size_t len = q - subset;
2204       size_t i;
2205       for (i = len; i > 0; i--)
2206         {
2207 	  q--;
2208 	  if (ISDIGIT (*q))
2209 	    find_any_version = true;
2210 	  else if (find_any_version
2211 		   && !find_minor_version
2212 		   && *q == 'p'
2213 		   && ISDIGIT (*(q - 1)))
2214 	    find_minor_version = true;
2215 	  else
2216 	    break;
2217 	}
2218       if (len > 0)
2219 	q++;
2220 
2221       /* Check if the end of extension is 'p' or not.  If yes, then
2222 	 the second letter from the end cannot be number.  */
2223       if (len > 1 && *(q - 1) == 'p' && ISDIGIT (*(q - 2)))
2224 	{
2225 	  *q = '\0';
2226 	  rps->error_handler
2227 	    (_("invalid ISA extension ends with <number>p "
2228 	       "in .option arch `%s'"), str);
2229 	  free (subset);
2230 	  return false;
2231 	}
2232 
2233       end_of_version =
2234 	riscv_parsing_subset_version (q, &major_version, &minor_version);
2235       *q = '\0';
2236       if (end_of_version == NULL)
2237 	{
2238 	  free (subset);
2239 	  return false;
2240 	}
2241 
2242       if (strlen (subset) == 0
2243 	  || (strlen (subset) == 1
2244 	      && riscv_ext_order[(*subset - 'a')] == 0)
2245 	  || (strlen (subset) > 1
2246 	      && rps->check_unknown_prefixed_ext
2247 	      && !riscv_recognized_prefixed_ext (subset)))
2248 	{
2249 	  rps->error_handler
2250 	    (_("unknown ISA extension `%s' in .option arch `%s'"),
2251 	     subset, str);
2252 	  free (subset);
2253 	  return false;
2254 	}
2255 
2256       if (strcmp (subset, "i") == 0
2257 	  || strcmp (subset, "e") == 0
2258 	  || strcmp (subset, "g") == 0)
2259 	{
2260 	  rps->error_handler
2261 	    (_("cannot + or - base extension `%s' in .option "
2262 	       "arch `%s'"), subset, str);
2263 	  free (subset);
2264 	  return false;
2265 	}
2266 
2267       if (removed)
2268 	riscv_remove_subset (rps->subset_list, subset);
2269       else
2270 	riscv_parse_add_subset (rps, subset, major_version, minor_version, true);
2271       p += end_of_version - subset;
2272       free (subset);
2273     }
2274   while (*p++ == ',');
2275 
2276   riscv_parse_add_implicit_subsets (rps);
2277   return riscv_parse_check_conflicts (rps);
2278 }
2279 
2280 /* Check if the FEATURE subset is supported or not in the subset list.
2281    Return true if it is supported; Otherwise, return false.  */
2282 
2283 bool
2284 riscv_subset_supports (riscv_parse_subset_t *rps,
2285 		       const char *feature)
2286 {
2287   struct riscv_subset_t *subset;
2288   return riscv_lookup_subset (rps->subset_list, feature, &subset);
2289 }
2290 
2291 /* Each instuction is belonged to an instruction class INSN_CLASS_*.
2292    Call riscv_subset_supports to make sure if the instuction is valid.  */
2293 
2294 bool
2295 riscv_multi_subset_supports (riscv_parse_subset_t *rps,
2296 			     enum riscv_insn_class insn_class)
2297 {
2298   switch (insn_class)
2299     {
2300     case INSN_CLASS_I:
2301       return riscv_subset_supports (rps, "i");
2302     case INSN_CLASS_ZICBOM:
2303       return riscv_subset_supports (rps, "zicbom");
2304     case INSN_CLASS_ZICBOP:
2305       return riscv_subset_supports (rps, "zicbop");
2306     case INSN_CLASS_ZICBOZ:
2307       return riscv_subset_supports (rps, "zicboz");
2308     case INSN_CLASS_ZICSR:
2309       return riscv_subset_supports (rps, "zicsr");
2310     case INSN_CLASS_ZIFENCEI:
2311       return riscv_subset_supports (rps, "zifencei");
2312     case INSN_CLASS_ZIHINTPAUSE:
2313       return riscv_subset_supports (rps, "zihintpause");
2314     case INSN_CLASS_M:
2315       return riscv_subset_supports (rps, "m");
2316     case INSN_CLASS_A:
2317       return riscv_subset_supports (rps, "a");
2318     case INSN_CLASS_F:
2319       return riscv_subset_supports (rps, "f");
2320     case INSN_CLASS_D:
2321       return riscv_subset_supports (rps, "d");
2322     case INSN_CLASS_Q:
2323       return riscv_subset_supports (rps, "q");
2324     case INSN_CLASS_C:
2325       return riscv_subset_supports (rps, "c");
2326     case INSN_CLASS_F_AND_C:
2327       return (riscv_subset_supports (rps, "f")
2328 	      && riscv_subset_supports (rps, "c"));
2329     case INSN_CLASS_D_AND_C:
2330       return (riscv_subset_supports (rps, "d")
2331 	      && riscv_subset_supports (rps, "c"));
2332     case INSN_CLASS_F_OR_ZFINX:
2333       return (riscv_subset_supports (rps, "f")
2334 	      || riscv_subset_supports (rps, "zfinx"));
2335     case INSN_CLASS_D_OR_ZDINX:
2336       return (riscv_subset_supports (rps, "d")
2337 	      || riscv_subset_supports (rps, "zdinx"));
2338     case INSN_CLASS_Q_OR_ZQINX:
2339       return (riscv_subset_supports (rps, "q")
2340 	      || riscv_subset_supports (rps, "zqinx"));
2341     case INSN_CLASS_ZFH_OR_ZHINX:
2342       return (riscv_subset_supports (rps, "zfh")
2343 	      || riscv_subset_supports (rps, "zhinx"));
2344     case INSN_CLASS_ZFHMIN:
2345       return riscv_subset_supports (rps, "zfhmin");
2346     case INSN_CLASS_ZFHMIN_OR_ZHINXMIN:
2347       return (riscv_subset_supports (rps, "zfhmin")
2348 	      || riscv_subset_supports (rps, "zhinxmin"));
2349     case INSN_CLASS_ZFHMIN_AND_D:
2350       return ((riscv_subset_supports (rps, "zfhmin")
2351 	       && riscv_subset_supports (rps, "d"))
2352 	      || (riscv_subset_supports (rps, "zhinxmin")
2353 		  && riscv_subset_supports (rps, "zdinx")));
2354     case INSN_CLASS_ZFHMIN_AND_Q:
2355       return ((riscv_subset_supports (rps, "zfhmin")
2356 	       && riscv_subset_supports (rps, "q"))
2357 	      || (riscv_subset_supports (rps, "zhinxmin")
2358 		  && riscv_subset_supports (rps, "zqinx")));
2359     case INSN_CLASS_ZBA:
2360       return riscv_subset_supports (rps, "zba");
2361     case INSN_CLASS_ZBB:
2362       return riscv_subset_supports (rps, "zbb");
2363     case INSN_CLASS_ZBC:
2364       return riscv_subset_supports (rps, "zbc");
2365     case INSN_CLASS_ZBS:
2366       return riscv_subset_supports (rps, "zbs");
2367     case INSN_CLASS_ZBKB:
2368       return riscv_subset_supports (rps, "zbkb");
2369     case INSN_CLASS_ZBKC:
2370       return riscv_subset_supports (rps, "zbkc");
2371     case INSN_CLASS_ZBKX:
2372       return riscv_subset_supports (rps, "zbkx");
2373     case INSN_CLASS_ZBB_OR_ZBKB:
2374       return (riscv_subset_supports (rps, "zbb")
2375 	      || riscv_subset_supports (rps, "zbkb"));
2376     case INSN_CLASS_ZBC_OR_ZBKC:
2377       return (riscv_subset_supports (rps, "zbc")
2378 	      || riscv_subset_supports (rps, "zbkc"));
2379     case INSN_CLASS_ZKND:
2380       return riscv_subset_supports (rps, "zknd");
2381     case INSN_CLASS_ZKNE:
2382       return riscv_subset_supports (rps, "zkne");
2383     case INSN_CLASS_ZKNH:
2384       return riscv_subset_supports (rps, "zknh");
2385     case INSN_CLASS_ZKND_OR_ZKNE:
2386       return (riscv_subset_supports (rps, "zknd")
2387 	      || riscv_subset_supports (rps, "zkne"));
2388     case INSN_CLASS_ZKSED:
2389       return riscv_subset_supports (rps, "zksed");
2390     case INSN_CLASS_ZKSH:
2391       return riscv_subset_supports (rps, "zksh");
2392     case INSN_CLASS_V:
2393       return (riscv_subset_supports (rps, "v")
2394 	      || riscv_subset_supports (rps, "zve64x")
2395 	      || riscv_subset_supports (rps, "zve32x"));
2396     case INSN_CLASS_ZVEF:
2397       return (riscv_subset_supports (rps, "v")
2398 	      || riscv_subset_supports (rps, "zve64d")
2399 	      || riscv_subset_supports (rps, "zve64f")
2400 	      || riscv_subset_supports (rps, "zve32f"));
2401     case INSN_CLASS_SVINVAL:
2402       return riscv_subset_supports (rps, "svinval");
2403     case INSN_CLASS_H:
2404       return riscv_subset_supports (rps, "h");
2405     default:
2406       rps->error_handler
2407         (_("internal: unreachable INSN_CLASS_*"));
2408       return false;
2409     }
2410 }
2411 
2412 /* Each instuction is belonged to an instruction class INSN_CLASS_*.
2413    Call riscv_subset_supports_ext to determine the missing extension.  */
2414 
2415 const char *
2416 riscv_multi_subset_supports_ext (riscv_parse_subset_t *rps,
2417 				 enum riscv_insn_class insn_class)
2418 {
2419   switch (insn_class)
2420     {
2421     case INSN_CLASS_I:
2422       return "i";
2423     case INSN_CLASS_ZICSR:
2424       return "zicsr";
2425     case INSN_CLASS_ZIFENCEI:
2426       return "zifencei";
2427     case INSN_CLASS_ZIHINTPAUSE:
2428       return "zihintpause";
2429     case INSN_CLASS_M:
2430       return "m";
2431     case INSN_CLASS_A:
2432       return "a";
2433     case INSN_CLASS_F:
2434       return "f";
2435     case INSN_CLASS_D:
2436       return "d";
2437     case INSN_CLASS_Q:
2438       return "q";
2439     case INSN_CLASS_C:
2440       return "c";
2441     case INSN_CLASS_F_AND_C:
2442       if (!riscv_subset_supports (rps, "f")
2443 	  && !riscv_subset_supports (rps, "c"))
2444 	return _("f' and `c");
2445       else if (!riscv_subset_supports (rps, "f"))
2446 	return "f";
2447       else
2448 	return "c";
2449     case INSN_CLASS_D_AND_C:
2450       if (!riscv_subset_supports (rps, "d")
2451 	  && !riscv_subset_supports (rps, "c"))
2452 	return _("d' and `c");
2453       else if (!riscv_subset_supports (rps, "d"))
2454 	return "d";
2455       else
2456 	return "c";
2457     case INSN_CLASS_F_OR_ZFINX:
2458       /* i18n: Formatted like "extension `f' or `zfinx' required".  */
2459       return _("f' or `zfinx");
2460     case INSN_CLASS_D_OR_ZDINX:
2461       return _("d' or `zdinx");
2462     case INSN_CLASS_Q_OR_ZQINX:
2463       return _("q' or `zqinx");
2464     case INSN_CLASS_ZFH_OR_ZHINX:
2465       return _("zfh' or `zhinx");
2466     case INSN_CLASS_ZFHMIN:
2467       return "zfhmin";
2468     case INSN_CLASS_ZFHMIN_OR_ZHINXMIN:
2469       return _("zfhmin' or `zhinxmin");
2470     case INSN_CLASS_ZFHMIN_AND_D:
2471       if (riscv_subset_supports (rps, "zfhmin"))
2472 	return "d";
2473       else if (riscv_subset_supports (rps, "d"))
2474 	return "zfhmin";
2475       else if (riscv_subset_supports (rps, "zhinxmin"))
2476 	return "zdinx";
2477       else if (riscv_subset_supports (rps, "zdinx"))
2478 	return "zhinxmin";
2479       else
2480 	return _("zfhmin' and `d', or `zhinxmin' and `zdinx");
2481     case INSN_CLASS_ZFHMIN_AND_Q:
2482       if (riscv_subset_supports (rps, "zfhmin"))
2483 	return "q";
2484       else if (riscv_subset_supports (rps, "q"))
2485 	return "zfhmin";
2486       else if (riscv_subset_supports (rps, "zhinxmin"))
2487 	return "zqinx";
2488       else if (riscv_subset_supports (rps, "zqinx"))
2489 	return "zhinxmin";
2490       else
2491 	return _("zfhmin' and `q', or `zhinxmin' and `zqinx");
2492     case INSN_CLASS_ZBA:
2493       return "zba";
2494     case INSN_CLASS_ZBB:
2495       return "zbb";
2496     case INSN_CLASS_ZBC:
2497       return "zbc";
2498     case INSN_CLASS_ZBS:
2499       return "zbs";
2500     case INSN_CLASS_ZBKB:
2501       return "zbkb";
2502     case INSN_CLASS_ZBKC:
2503       return "zbkc";
2504     case INSN_CLASS_ZBKX:
2505       return "zbkx";
2506     case INSN_CLASS_ZBB_OR_ZBKB:
2507       return _("zbb' or `zbkb");
2508     case INSN_CLASS_ZBC_OR_ZBKC:
2509       return _("zbc' or `zbkc");
2510     case INSN_CLASS_ZKND:
2511       return "zknd";
2512     case INSN_CLASS_ZKNE:
2513       return "zkne";
2514     case INSN_CLASS_ZKNH:
2515       return "zknh";
2516     case INSN_CLASS_ZKND_OR_ZKNE:
2517       return _("zknd' or `zkne");
2518     case INSN_CLASS_ZKSED:
2519       return "zksed";
2520     case INSN_CLASS_ZKSH:
2521       return "zksh";
2522     case INSN_CLASS_V:
2523       return _("v' or `zve64x' or `zve32x");
2524     case INSN_CLASS_ZVEF:
2525       return _("v' or `zve64d' or `zve64f' or `zve32f");
2526     case INSN_CLASS_SVINVAL:
2527       return "svinval";
2528     case INSN_CLASS_H:
2529       return _("h");
2530     default:
2531       rps->error_handler
2532         (_("internal: unreachable INSN_CLASS_*"));
2533       return NULL;
2534     }
2535 }
2536