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.  */
39static 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
44static 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.  */
876struct elf_reloc_map
877{
878  bfd_reloc_code_real_type bfd_val;
879  enum elf_riscv_reloc_type elf_val;
880};
881
882static 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
938reloc_howto_type *
939riscv_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
952reloc_howto_type *
953riscv_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
964reloc_howto_type *
965riscv_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
979static bfd_reloc_status_type
980riscv_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
1037static bool
1038check_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
1046static bool
1047check_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.  */
1056struct 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};
1063static 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
1134struct 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
1145static 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
1179static 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
1234static 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
1243static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
1244{
1245  {NULL, 0, 0, 0, 0}
1246};
1247
1248const 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.  */
1258enum 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.  */
1271struct 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};
1279static 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
1291static enum riscv_prefix_ext_class
1292riscv_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
1307static bool
1308riscv_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
1321static bool
1322riscv_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.  */
1344static const char riscv_ext_canonical_order[] = "eigmafdqlcbkjtpvnh";
1345
1346/* Array is used to compare the orders of standard extensions quickly.  */
1347static int riscv_ext_order[26] = {0};
1348
1349/* Init the riscv_ext_order array.  */
1350
1351static void
1352riscv_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
1380int
1381riscv_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
1421bool
1422riscv_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
1457void
1458riscv_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
1491static void
1492riscv_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
1534static void
1535riscv_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
1573void
1574riscv_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
1597static const char *
1598riscv_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
1653static const char *
1654riscv_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
1730static const char *
1731riscv_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
1833static void
1834riscv_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
1850static bool
1851riscv_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
1914static void
1915riscv_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
1944bool
1945riscv_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
2021size_t
2022riscv_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
2036static size_t
2037riscv_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
2052static size_t
2053riscv_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
2060static void
2061riscv_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
2097char *
2098riscv_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
2114static struct riscv_subset_t *
2115riscv_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
2135riscv_subset_list_t *
2136riscv_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
2145static void
2146riscv_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
2171bool
2172riscv_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
2283bool
2284riscv_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
2294bool
2295riscv_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
2415const char *
2416riscv_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