blob: 66d42e4ab470ab75b448197d0a9aa334709cd4a6 [file] [log] [blame]
Patrick Georgif0bbc952015-03-07 10:57:25 +01001Created from https://github.com/riscv/riscv-gnu-toolchain,
2commit ddce5d17f14831f4957e57c415aca77817c2a82c
3
4diff -urN original-binutils/bfd/archures.c binutils/bfd/archures.c
5--- original-binutils/bfd/archures.c 2014-10-14 09:32:02.000000000 +0200
6+++ binutils-2.25/bfd/archures.c 2015-03-07 09:55:02.355135671 +0100
7@@ -597,6 +597,7 @@
8 extern const bfd_arch_info_type bfd_plugin_arch;
9 extern const bfd_arch_info_type bfd_powerpc_archs[];
10 #define bfd_powerpc_arch bfd_powerpc_archs[0]
11+extern const bfd_arch_info_type bfd_riscv_arch;
12 extern const bfd_arch_info_type bfd_rs6000_arch;
13 extern const bfd_arch_info_type bfd_rl78_arch;
14 extern const bfd_arch_info_type bfd_rx_arch;
15@@ -683,6 +684,7 @@
16 &bfd_or1k_arch,
17 &bfd_pdp11_arch,
18 &bfd_powerpc_arch,
19+ &bfd_riscv_arch,
20 &bfd_rs6000_arch,
21 &bfd_rl78_arch,
22 &bfd_rx_arch,
23diff -urN original-binutils/bfd/bfd-in2.h binutils/bfd/bfd-in2.h
24--- original-binutils/bfd/bfd-in2.h 2014-11-04 10:54:41.000000000 +0100
25+++ binutils-2.25/bfd/bfd-in2.h 2015-03-07 09:55:02.359135671 +0100
26@@ -2043,6 +2043,9 @@
27 #define bfd_mach_ppc_e6500 5007
28 #define bfd_mach_ppc_titan 83
29 #define bfd_mach_ppc_vle 84
30+ bfd_arch_riscv, /* RISC-V */
31+#define bfd_mach_riscv32 132
32+#define bfd_mach_riscv64 164
33 bfd_arch_rs6000, /* IBM RS/6000 */
34 #define bfd_mach_rs6k 6000
35 #define bfd_mach_rs6k_rs1 6001
36@@ -5531,6 +5534,41 @@
37 value in a word. The relocation is relative offset from */
38 BFD_RELOC_MICROBLAZE_32_GOTOFF,
39
40+/* RISC-V relocations */
41+ BFD_RELOC_RISCV_HI20,
42+ BFD_RELOC_RISCV_PCREL_HI20,
43+ BFD_RELOC_RISCV_PCREL_LO12_I,
44+ BFD_RELOC_RISCV_PCREL_LO12_S,
45+ BFD_RELOC_RISCV_LO12_I,
46+ BFD_RELOC_RISCV_LO12_S,
47+ BFD_RELOC_RISCV_GPREL12_I,
48+ BFD_RELOC_RISCV_GPREL12_S,
49+ BFD_RELOC_RISCV_TPREL_HI20,
50+ BFD_RELOC_RISCV_TPREL_LO12_I,
51+ BFD_RELOC_RISCV_TPREL_LO12_S,
52+ BFD_RELOC_RISCV_TPREL_ADD,
53+ BFD_RELOC_RISCV_CALL,
54+ BFD_RELOC_RISCV_CALL_PLT,
55+ BFD_RELOC_RISCV_ADD8,
56+ BFD_RELOC_RISCV_ADD16,
57+ BFD_RELOC_RISCV_ADD32,
58+ BFD_RELOC_RISCV_ADD64,
59+ BFD_RELOC_RISCV_SUB8,
60+ BFD_RELOC_RISCV_SUB16,
61+ BFD_RELOC_RISCV_SUB32,
62+ BFD_RELOC_RISCV_SUB64,
63+ BFD_RELOC_RISCV_GOT_HI20,
64+ BFD_RELOC_RISCV_TLS_GOT_HI20,
65+ BFD_RELOC_RISCV_TLS_GD_HI20,
66+ BFD_RELOC_RISCV_JMP,
67+ BFD_RELOC_RISCV_TLS_DTPMOD32,
68+ BFD_RELOC_RISCV_TLS_DTPREL32,
69+ BFD_RELOC_RISCV_TLS_DTPMOD64,
70+ BFD_RELOC_RISCV_TLS_DTPREL64,
71+ BFD_RELOC_RISCV_TLS_TPREL32,
72+ BFD_RELOC_RISCV_TLS_TPREL64,
73+ BFD_RELOC_RISCV_ALIGN,
74+
75 /* This is used to tell the dynamic linker to copy the value out of
76 the dynamic object into the runtime process image. */
77 BFD_RELOC_MICROBLAZE_COPY,
78diff -urN original-binutils/bfd/config.bfd binutils/bfd/config.bfd
79--- original-binutils/bfd/config.bfd 2014-10-14 09:32:02.000000000 +0200
80+++ binutils-2.25/bfd/config.bfd 2015-03-07 09:55:02.359135671 +0100
81@@ -119,6 +119,7 @@
82 pdp11*) targ_archs=bfd_pdp11_arch ;;
83 pj*) targ_archs="bfd_pj_arch bfd_i386_arch";;
84 powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
85+riscv*) targ_archs=bfd_riscv_arch ;;
86 rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
87 s390*) targ_archs=bfd_s390_arch ;;
88 sh*) targ_archs=bfd_sh_arch ;;
89@@ -1319,6 +1320,14 @@
90 targ_defvec=rl78_elf32_vec
91 ;;
92
93+#ifdef BFD64
94+ riscv*-*-*)
95+ targ_defvec=riscv_elf64_vec
96+ targ_selvecs="riscv_elf32_vec riscv_elf64_vec"
97+ want64=true
98+ ;;
99+#endif
100+
101 rx-*-elf)
102 targ_defvec=rx_elf32_le_vec
103 targ_selvecs="rx_elf32_be_vec rx_elf32_le_vec rx_elf32_be_ns_vec"
104diff -urN original-binutils/bfd/configure binutils/bfd/configure
105--- original-binutils/bfd/configure 2014-12-23 15:22:04.000000000 +0100
106+++ binutils-2.25/bfd/configure 2015-03-07 09:55:02.367135671 +0100
107@@ -15506,6 +15506,8 @@
108 powerpc_pei_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
109 powerpc_pei_le_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
110 powerpc_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
111+ riscv_elf32_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf32.lo $elf" ;;
112+ riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;;
113 rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
114 rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
115 rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
116diff -urN original-binutils/bfd/configure.ac binutils/bfd/configure.ac
117--- original-binutils/bfd/configure.ac 2014-10-14 09:32:02.000000000 +0200
118+++ binutils-2.25/bfd/configure.ac 2015-03-07 09:55:02.367135671 +0100
119@@ -907,6 +907,8 @@
120 powerpc_pei_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
121 powerpc_pei_le_vec) tb="$tb pei-ppc.lo peigen.lo cofflink.lo" ;;
122 powerpc_xcoff_vec) tb="$tb coff-rs6000.lo xcofflink.lo" ;;
123+ riscv_elf32_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf32.lo $elf" ;;
124+ riscv_elf64_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;;
125 rl78_elf32_vec) tb="$tb elf32-rl78.lo elf32.lo $elf" ;;
126 rs6000_xcoff64_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
127 rs6000_xcoff64_aix_vec) tb="$tb coff64-rs6000.lo xcofflink.lo aix5ppc-core.lo"; target_size=64 ;;
128diff -urN original-binutils/bfd/cpu-riscv.c binutils/bfd/cpu-riscv.c
129--- original-binutils/bfd/cpu-riscv.c 1970-01-01 01:00:00.000000000 +0100
130+++ binutils-2.25/bfd/cpu-riscv.c 2015-03-07 09:51:45.655139025 +0100
131@@ -0,0 +1,80 @@
132+/* BFD backend for RISC-V
133+ Copyright 2011-2014 Free Software Foundation, Inc.
134+
135+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
136+ Based on MIPS target.
137+
138+ This file is part of BFD, the Binary File Descriptor library.
139+
140+ This program is free software; you can redistribute it and/or modify
141+ it under the terms of the GNU General Public License as published by
142+ the Free Software Foundation; either version 3 of the License, or
143+ (at your option) any later version.
144+
145+ This program is distributed in the hope that it will be useful,
146+ but WITHOUT ANY WARRANTY; without even the implied warranty of
147+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
148+ GNU General Public License for more details.
149+
150+ You should have received a copy of the GNU General Public License
151+ along with this program; if not, write to the Free Software
152+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
153+ MA 02110-1301, USA. */
154+
155+#include "sysdep.h"
156+#include "bfd.h"
157+#include "libbfd.h"
158+
159+static const bfd_arch_info_type *riscv_compatible
160+ (const bfd_arch_info_type *, const bfd_arch_info_type *);
161+
162+/* The default routine tests bits_per_word, which is wrong on RISC-V, as
163+ RISC-V word size doesn't correlate with reloc size. */
164+
165+static const bfd_arch_info_type *
166+riscv_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
167+{
168+ if (a->arch != b->arch)
169+ return NULL;
170+
171+ /* Machine compatibility is checked in
172+ _bfd_riscv_elf_merge_private_bfd_data. */
173+
174+ return a;
175+}
176+
177+#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \
178+ { \
179+ BITS_WORD, /* bits in a word */ \
180+ BITS_ADDR, /* bits in an address */ \
181+ 8, /* 8 bits in a byte */ \
182+ bfd_arch_riscv, \
183+ NUMBER, \
184+ "riscv", \
185+ PRINT, \
186+ 3, \
187+ DEFAULT, \
188+ riscv_compatible, \
189+ bfd_default_scan, \
190+ bfd_arch_default_fill, \
191+ NEXT, \
192+ }
193+
194+enum
195+{
196+ I_riscv64,
197+ I_riscv32
198+};
199+
200+#define NN(index) (&arch_info_struct[(index) + 1])
201+
202+static const bfd_arch_info_type arch_info_struct[] =
203+{
204+ N (64, 64, bfd_mach_riscv64, "riscv:rv64", FALSE, NN(I_riscv64)),
205+ N (32, 32, bfd_mach_riscv32, "riscv:rv32", FALSE, 0)
206+};
207+
208+/* The default architecture is riscv:rv64. */
209+
210+const bfd_arch_info_type bfd_riscv_arch =
211+N (64, 64, 0, "riscv", TRUE, &arch_info_struct[0]);
212diff -urN original-binutils/bfd/elf-bfd.h binutils/bfd/elf-bfd.h
213--- original-binutils/bfd/elf-bfd.h 2014-12-23 09:47:10.000000000 +0100
214+++ binutils-2.25/bfd/elf-bfd.h 2015-03-07 09:55:02.367135671 +0100
215@@ -433,6 +433,7 @@
216 XGATE_ELF_DATA,
217 TILEGX_ELF_DATA,
218 TILEPRO_ELF_DATA,
219+ RISCV_ELF_DATA,
220 GENERIC_ELF_DATA
221 };
222
223diff -urN original-binutils/bfd/elfnn-riscv.c binutils/bfd/elfnn-riscv.c
224--- original-binutils/bfd/elfnn-riscv.c 1970-01-01 01:00:00.000000000 +0100
225+++ binutils-2.25/bfd/elfnn-riscv.c 2015-03-07 09:51:45.655139025 +0100
226@@ -0,0 +1,2954 @@
227+/* RISC-V-specific support for NN-bit ELF.
228+ Copyright 2011-2014 Free Software Foundation, Inc.
229+
230+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
231+ Based on TILE-Gx and MIPS targets.
232+
233+ This file is part of BFD, the Binary File Descriptor library.
234+
235+ This program is free software; you can redistribute it and/or modify
236+ it under the terms of the GNU General Public License as published by
237+ the Free Software Foundation; either version 3 of the License, or
238+ (at your option) any later version.
239+
240+ This program is distributed in the hope that it will be useful,
241+ but WITHOUT ANY WARRANTY; without even the implied warranty of
242+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
243+ GNU General Public License for more details.
244+
245+ You should have received a copy of the GNU General Public License
246+ along with this program; if not, write to the Free Software
247+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
248+ MA 02110-1301, USA. */
249+
250+
251+/* This file handles RISC-V ELF targets. */
252+
253+#include "sysdep.h"
254+#include "bfd.h"
255+#include "libbfd.h"
256+#include "bfdlink.h"
257+#include "genlink.h"
258+#include "elf-bfd.h"
259+#include "elfxx-riscv.h"
260+#include "elf/riscv.h"
261+#include "opcode/riscv.h"
262+
263+#define ARCH_SIZE NN
264+
265+#define MINUS_ONE ((bfd_vma)0 - 1)
266+
267+#define RISCV_ELF_LOG_WORD_BYTES (ARCH_SIZE == 32 ? 2 : 3)
268+
269+#define RISCV_ELF_WORD_BYTES (1 << RISCV_ELF_LOG_WORD_BYTES)
270+
271+/* The name of the dynamic interpreter. This is put in the .interp
272+ section. */
273+
274+#define ELF64_DYNAMIC_INTERPRETER "/lib/ld.so.1"
275+#define ELF32_DYNAMIC_INTERPRETER "/lib32/ld.so.1"
276+
277+/* The RISC-V linker needs to keep track of the number of relocs that it
278+ decides to copy as dynamic relocs in check_relocs for each symbol.
279+ This is so that it can later discard them if they are found to be
280+ unnecessary. We store the information in a field extending the
281+ regular ELF linker hash table. */
282+
283+struct riscv_elf_dyn_relocs
284+{
285+ struct riscv_elf_dyn_relocs *next;
286+
287+ /* The input section of the reloc. */
288+ asection *sec;
289+
290+ /* Total number of relocs copied for the input section. */
291+ bfd_size_type count;
292+
293+ /* Number of pc-relative relocs copied for the input section. */
294+ bfd_size_type pc_count;
295+};
296+
297+/* RISC-V ELF linker hash entry. */
298+
299+struct riscv_elf_link_hash_entry
300+{
301+ struct elf_link_hash_entry elf;
302+
303+ /* Track dynamic relocs copied for this symbol. */
304+ struct riscv_elf_dyn_relocs *dyn_relocs;
305+
306+#define GOT_UNKNOWN 0
307+#define GOT_NORMAL 1
308+#define GOT_TLS_GD 2
309+#define GOT_TLS_IE 4
310+#define GOT_TLS_LE 8
311+ char tls_type;
312+};
313+
314+#define riscv_elf_hash_entry(ent) \
315+ ((struct riscv_elf_link_hash_entry *)(ent))
316+
317+struct _bfd_riscv_elf_obj_tdata
318+{
319+ struct elf_obj_tdata root;
320+
321+ /* tls_type for each local got entry. */
322+ char *local_got_tls_type;
323+};
324+
325+#define _bfd_riscv_elf_tdata(abfd) \
326+ ((struct _bfd_riscv_elf_obj_tdata *) (abfd)->tdata.any)
327+
328+#define _bfd_riscv_elf_local_got_tls_type(abfd) \
329+ (_bfd_riscv_elf_tdata (abfd)->local_got_tls_type)
330+
331+#define _bfd_riscv_elf_tls_type(abfd, h, symndx) \
332+ (*((h) != NULL ? &riscv_elf_hash_entry(h)->tls_type \
333+ : &_bfd_riscv_elf_local_got_tls_type (abfd) [symndx]))
334+
335+#define is_riscv_elf(bfd) \
336+ (bfd_get_flavour (bfd) == bfd_target_elf_flavour \
337+ && elf_tdata (bfd) != NULL \
338+ && elf_object_id (bfd) == RISCV_ELF_DATA)
339+
340+#include "elf/common.h"
341+#include "elf/internal.h"
342+
343+struct riscv_elf_link_hash_table
344+{
345+ struct elf_link_hash_table elf;
346+
347+ /* Short-cuts to get to dynamic linker sections. */
348+ asection *sdynbss;
349+ asection *srelbss;
350+ asection *sdyntdata;
351+
352+ /* Small local sym to section mapping cache. */
353+ struct sym_cache sym_cache;
354+};
355+
356+
357+/* Get the RISC-V ELF linker hash table from a link_info structure. */
358+#define riscv_elf_hash_table(p) \
359+ (elf_hash_table_id ((struct elf_link_hash_table *) ((p)->hash)) \
360+ == RISCV_ELF_DATA ? ((struct riscv_elf_link_hash_table *) ((p)->hash)) : NULL)
361+
362+static void
363+riscv_info_to_howto_rela (bfd *abfd ATTRIBUTE_UNUSED,
364+ arelent *cache_ptr,
365+ Elf_Internal_Rela *dst)
366+{
367+ cache_ptr->howto = riscv_elf_rtype_to_howto (ELFNN_R_TYPE (dst->r_info));
368+}
369+
370+static void
371+riscv_elf_append_rela (bfd *abfd, asection *s, Elf_Internal_Rela *rel)
372+{
373+ const struct elf_backend_data *bed;
374+ bfd_byte *loc;
375+
376+ bed = get_elf_backend_data (abfd);
377+ loc = s->contents + (s->reloc_count++ * bed->s->sizeof_rela);
378+ bed->s->swap_reloca_out (abfd, rel, loc);
379+}
380+
381+/* PLT/GOT stuff */
382+
383+#define PLT_HEADER_INSNS 8
384+#define PLT_ENTRY_INSNS 4
385+#define PLT_HEADER_SIZE (PLT_HEADER_INSNS * 4)
386+#define PLT_ENTRY_SIZE (PLT_ENTRY_INSNS * 4)
387+
388+#define GOT_ENTRY_SIZE RISCV_ELF_WORD_BYTES
389+
390+#define GOTPLT_HEADER_SIZE (2 * GOT_ENTRY_SIZE)
391+
392+#define sec_addr(sec) ((sec)->output_section->vma + (sec)->output_offset)
393+
394+static bfd_vma
395+riscv_elf_got_plt_val (bfd_vma plt_index, struct bfd_link_info *info)
396+{
397+ return sec_addr (riscv_elf_hash_table (info)->elf.sgotplt)
398+ + GOTPLT_HEADER_SIZE + (plt_index * GOT_ENTRY_SIZE);
399+}
400+
401+#if ARCH_SIZE == 32
402+# define MATCH_LREG MATCH_LW
403+#else
404+# define MATCH_LREG MATCH_LD
405+#endif
406+
407+/* The format of the first PLT entry. */
408+
409+static void
410+riscv_make_plt0_entry(bfd_vma gotplt_addr, bfd_vma addr, uint32_t *entry)
411+{
412+ /* auipc t2, %hi(.got.plt)
413+ sub t1, t1, t0 # shifted .got.plt offset + hdr size + 12
414+ l[w|d] t3, %lo(.got.plt)(t2) # _dl_runtime_resolve
415+ addi t1, t1, -(hdr size + 12) # shifted .got.plt offset
416+ addi t0, t2, %lo(.got.plt) # &.got.plt
417+ srli t1, t1, log2(16/PTRSIZE) # .got.plt offset
418+ l[w|d] t0, PTRSIZE(t0) # link map
419+ jr t3 */
420+
421+ entry[0] = RISCV_UTYPE (AUIPC, X_T2, RISCV_PCREL_HIGH_PART (gotplt_addr, addr));
422+ entry[1] = RISCV_RTYPE (SUB, X_T1, X_T1, X_T0);
423+ entry[2] = RISCV_ITYPE (LREG, X_T3, X_T2, RISCV_PCREL_LOW_PART (gotplt_addr, addr));
424+ entry[3] = RISCV_ITYPE (ADDI, X_T1, X_T1, -(PLT_HEADER_SIZE + 12));
425+ entry[4] = RISCV_ITYPE (ADDI, X_T0, X_T2, RISCV_PCREL_LOW_PART (gotplt_addr, addr));
426+ entry[5] = RISCV_ITYPE (SRLI, X_T1, X_T1, 4 - RISCV_ELF_LOG_WORD_BYTES);
427+ entry[6] = RISCV_ITYPE (LREG, X_T0, X_T0, RISCV_ELF_WORD_BYTES);
428+ entry[7] = RISCV_ITYPE (JALR, 0, X_T3, 0);
429+}
430+
431+/* The format of subsequent PLT entries. */
432+
433+static void
434+riscv_make_plt_entry(bfd_vma got_address, bfd_vma addr, uint32_t *entry)
435+{
436+ /* auipc t1, %hi(.got.plt entry)
437+ l[w|d] t0, %lo(.got.plt entry)(t1)
438+ jalr t1, t0
439+ nop */
440+
441+ entry[0] = RISCV_UTYPE (AUIPC, X_T1, RISCV_PCREL_HIGH_PART (got_address, addr));
442+ entry[1] = RISCV_ITYPE (LREG, X_T0, X_T1, RISCV_PCREL_LOW_PART(got_address, addr));
443+ entry[2] = RISCV_ITYPE (JALR, X_T1, X_T0, 0);
444+ entry[3] = RISCV_NOP;
445+}
446+
447+/* Create an entry in an RISC-V ELF linker hash table. */
448+
449+static struct bfd_hash_entry *
450+link_hash_newfunc (struct bfd_hash_entry *entry,
451+ struct bfd_hash_table *table, const char *string)
452+{
453+ /* Allocate the structure if it has not already been allocated by a
454+ subclass. */
455+ if (entry == NULL)
456+ {
457+ entry =
458+ bfd_hash_allocate (table,
459+ sizeof (struct riscv_elf_link_hash_entry));
460+ if (entry == NULL)
461+ return entry;
462+ }
463+
464+ /* Call the allocation method of the superclass. */
465+ entry = _bfd_elf_link_hash_newfunc (entry, table, string);
466+ if (entry != NULL)
467+ {
468+ struct riscv_elf_link_hash_entry *eh;
469+
470+ eh = (struct riscv_elf_link_hash_entry *) entry;
471+ eh->dyn_relocs = NULL;
472+ eh->tls_type = GOT_UNKNOWN;
473+ }
474+
475+ return entry;
476+}
477+
478+/* Create a RISC-V ELF linker hash table. */
479+
480+static struct bfd_link_hash_table *
481+riscv_elf_link_hash_table_create (bfd *abfd)
482+{
483+ struct riscv_elf_link_hash_table *ret;
484+ bfd_size_type amt = sizeof (struct riscv_elf_link_hash_table);
485+
486+ ret = (struct riscv_elf_link_hash_table *) bfd_zmalloc (amt);
487+ if (ret == NULL)
488+ return NULL;
489+
490+ if (!_bfd_elf_link_hash_table_init (&ret->elf, abfd, link_hash_newfunc,
491+ sizeof (struct riscv_elf_link_hash_entry),
492+ RISCV_ELF_DATA))
493+ {
494+ free (ret);
495+ return NULL;
496+ }
497+
498+ return &ret->elf.root;
499+}
500+
501+/* Create the .got section. */
502+
503+static bfd_boolean
504+riscv_elf_create_got_section (bfd *abfd, struct bfd_link_info *info)
505+{
506+ flagword flags;
507+ asection *s, *s_got;
508+ struct elf_link_hash_entry *h;
509+ const struct elf_backend_data *bed = get_elf_backend_data (abfd);
510+ struct elf_link_hash_table *htab = elf_hash_table (info);
511+
512+ /* This function may be called more than once. */
513+ s = bfd_get_linker_section (abfd, ".got");
514+ if (s != NULL)
515+ return TRUE;
516+
517+ flags = bed->dynamic_sec_flags;
518+
519+ s = bfd_make_section_anyway_with_flags (abfd,
520+ (bed->rela_plts_and_copies_p
521+ ? ".rela.got" : ".rel.got"),
522+ (bed->dynamic_sec_flags
523+ | SEC_READONLY));
524+ if (s == NULL
525+ || ! bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
526+ return FALSE;
527+ htab->srelgot = s;
528+
529+ s = s_got = bfd_make_section_anyway_with_flags (abfd, ".got", flags);
530+ if (s == NULL
531+ || !bfd_set_section_alignment (abfd, s, bed->s->log_file_align))
532+ return FALSE;
533+ htab->sgot = s;
534+
535+ /* The first bit of the global offset table is the header. */
536+ s->size += bed->got_header_size;
537+
538+ if (bed->want_got_plt)
539+ {
540+ s = bfd_make_section_anyway_with_flags (abfd, ".got.plt", flags);
541+ if (s == NULL
542+ || !bfd_set_section_alignment (abfd, s,
543+ bed->s->log_file_align))
544+ return FALSE;
545+ htab->sgotplt = s;
546+
547+ /* Reserve room for the header. */
548+ s->size += GOTPLT_HEADER_SIZE;
549+ }
550+
551+ if (bed->want_got_sym)
552+ {
553+ /* Define the symbol _GLOBAL_OFFSET_TABLE_ at the start of the .got
554+ section. We don't do this in the linker script because we don't want
555+ to define the symbol if we are not creating a global offset
556+ table. */
557+ h = _bfd_elf_define_linkage_sym (abfd, info, s_got,
558+ "_GLOBAL_OFFSET_TABLE_");
559+ elf_hash_table (info)->hgot = h;
560+ if (h == NULL)
561+ return FALSE;
562+ }
563+
564+ return TRUE;
565+}
566+
567+/* Create .plt, .rela.plt, .got, .got.plt, .rela.got, .dynbss, and
568+ .rela.bss sections in DYNOBJ, and set up shortcuts to them in our
569+ hash table. */
570+
571+static bfd_boolean
572+riscv_elf_create_dynamic_sections (bfd *dynobj,
573+ struct bfd_link_info *info)
574+{
575+ struct riscv_elf_link_hash_table *htab;
576+
577+ htab = riscv_elf_hash_table (info);
578+ BFD_ASSERT (htab != NULL);
579+
580+ if (!riscv_elf_create_got_section (dynobj, info))
581+ return FALSE;
582+
583+ if (!_bfd_elf_create_dynamic_sections (dynobj, info))
584+ return FALSE;
585+
586+ htab->sdynbss = bfd_get_linker_section (dynobj, ".dynbss");
587+ if (!info->shared)
588+ {
589+ htab->srelbss = bfd_get_linker_section (dynobj, ".rela.bss");
590+ htab->sdyntdata =
591+ bfd_make_section_anyway_with_flags (dynobj, ".tdata.dyn",
592+ SEC_ALLOC | SEC_THREAD_LOCAL);
593+ }
594+
595+ if (!htab->elf.splt || !htab->elf.srelplt || !htab->sdynbss
596+ || (!info->shared && (!htab->srelbss || !htab->sdyntdata)))
597+ abort ();
598+
599+ return TRUE;
600+}
601+
602+/* Copy the extra info we tack onto an elf_link_hash_entry. */
603+
604+static void
605+riscv_elf_copy_indirect_symbol (struct bfd_link_info *info,
606+ struct elf_link_hash_entry *dir,
607+ struct elf_link_hash_entry *ind)
608+{
609+ struct riscv_elf_link_hash_entry *edir, *eind;
610+
611+ edir = (struct riscv_elf_link_hash_entry *) dir;
612+ eind = (struct riscv_elf_link_hash_entry *) ind;
613+
614+ if (eind->dyn_relocs != NULL)
615+ {
616+ if (edir->dyn_relocs != NULL)
617+ {
618+ struct riscv_elf_dyn_relocs **pp;
619+ struct riscv_elf_dyn_relocs *p;
620+
621+ /* Add reloc counts against the indirect sym to the direct sym
622+ list. Merge any entries against the same section. */
623+ for (pp = &eind->dyn_relocs; (p = *pp) != NULL; )
624+ {
625+ struct riscv_elf_dyn_relocs *q;
626+
627+ for (q = edir->dyn_relocs; q != NULL; q = q->next)
628+ if (q->sec == p->sec)
629+ {
630+ q->pc_count += p->pc_count;
631+ q->count += p->count;
632+ *pp = p->next;
633+ break;
634+ }
635+ if (q == NULL)
636+ pp = &p->next;
637+ }
638+ *pp = edir->dyn_relocs;
639+ }
640+
641+ edir->dyn_relocs = eind->dyn_relocs;
642+ eind->dyn_relocs = NULL;
643+ }
644+
645+ if (ind->root.type == bfd_link_hash_indirect
646+ && dir->got.refcount <= 0)
647+ {
648+ edir->tls_type = eind->tls_type;
649+ eind->tls_type = GOT_UNKNOWN;
650+ }
651+ _bfd_elf_link_hash_copy_indirect (info, dir, ind);
652+}
653+
654+static bfd_boolean
655+riscv_elf_record_tls_type (bfd *abfd, struct elf_link_hash_entry *h,
656+ unsigned long symndx, char tls_type)
657+{
658+ char *new_tls_type = &_bfd_riscv_elf_tls_type (abfd, h, symndx);
659+ *new_tls_type |= tls_type;
660+ if ((*new_tls_type & GOT_NORMAL) && (*new_tls_type & ~GOT_NORMAL))
661+ {
662+ (*_bfd_error_handler)
663+ (_("%B: `%s' accessed both as normal and thread local symbol"),
664+ abfd, h ? h->root.root.string : "<local>");
665+ return FALSE;
666+ }
667+ return TRUE;
668+}
669+
670+static bfd_boolean
671+riscv_elf_record_got_reference (bfd *abfd, struct bfd_link_info *info,
672+ struct elf_link_hash_entry *h, long symndx)
673+{
674+ struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
675+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
676+
677+ if (htab->elf.sgot == NULL)
678+ {
679+ if (!riscv_elf_create_got_section (htab->elf.dynobj, info))
680+ return FALSE;
681+ }
682+
683+ if (h != NULL)
684+ {
685+ h->got.refcount += 1;
686+ return TRUE;
687+ }
688+
689+ /* This is a global offset table entry for a local symbol. */
690+ if (elf_local_got_refcounts (abfd) == NULL)
691+ {
692+ bfd_size_type size = symtab_hdr->sh_info * (sizeof (bfd_vma) + 1);
693+ if (!(elf_local_got_refcounts (abfd) = bfd_zalloc (abfd, size)))
694+ return FALSE;
695+ _bfd_riscv_elf_local_got_tls_type (abfd)
696+ = (char *) (elf_local_got_refcounts (abfd) + symtab_hdr->sh_info);
697+ }
698+ elf_local_got_refcounts (abfd) [symndx] += 1;
699+
700+ return TRUE;
701+}
702+
703+static bfd_boolean
704+bad_static_reloc (bfd *abfd, unsigned r_type, struct elf_link_hash_entry *h)
705+{
706+ (*_bfd_error_handler)
707+ (_("%B: relocation %s against `%s' can not be used when making a shared object; recompile with -fPIC"),
708+ abfd, riscv_elf_rtype_to_howto (r_type)->name,
709+ h != NULL ? h->root.root.string : "a local symbol");
710+ bfd_set_error (bfd_error_bad_value);
711+ return FALSE;
712+}
713+/* Look through the relocs for a section during the first phase, and
714+ allocate space in the global offset table or procedure linkage
715+ table. */
716+
717+static bfd_boolean
718+riscv_elf_check_relocs (bfd *abfd, struct bfd_link_info *info,
719+ asection *sec, const Elf_Internal_Rela *relocs)
720+{
721+ struct riscv_elf_link_hash_table *htab;
722+ Elf_Internal_Shdr *symtab_hdr;
723+ struct elf_link_hash_entry **sym_hashes;
724+ const Elf_Internal_Rela *rel;
725+ asection *sreloc = NULL;
726+
727+ if (info->relocatable)
728+ return TRUE;
729+
730+ htab = riscv_elf_hash_table (info);
731+ symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
732+ sym_hashes = elf_sym_hashes (abfd);
733+
734+ if (htab->elf.dynobj == NULL)
735+ htab->elf.dynobj = abfd;
736+
737+ for (rel = relocs; rel < relocs + sec->reloc_count; rel++)
738+ {
739+ unsigned int r_type;
740+ unsigned long r_symndx;
741+ struct elf_link_hash_entry *h;
742+
743+ r_symndx = ELFNN_R_SYM (rel->r_info);
744+ r_type = ELFNN_R_TYPE (rel->r_info);
745+
746+ if (r_symndx >= NUM_SHDR_ENTRIES (symtab_hdr))
747+ {
748+ (*_bfd_error_handler) (_("%B: bad symbol index: %d"),
749+ abfd, r_symndx);
750+ return FALSE;
751+ }
752+
753+ if (r_symndx < symtab_hdr->sh_info)
754+ h = NULL;
755+ else
756+ {
757+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
758+ while (h->root.type == bfd_link_hash_indirect
759+ || h->root.type == bfd_link_hash_warning)
760+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
761+
762+ /* PR15323, ref flags aren't set for references in the same
763+ object. */
764+ h->root.non_ir_ref = 1;
765+ }
766+
767+ switch (r_type)
768+ {
769+ case R_RISCV_TLS_GD_HI20:
770+ if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
771+ || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_GD))
772+ return FALSE;
773+ break;
774+
775+ case R_RISCV_TLS_GOT_HI20:
776+ if (info->shared)
777+ info->flags |= DF_STATIC_TLS;
778+ if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
779+ || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_IE))
780+ return FALSE;
781+ break;
782+
783+ case R_RISCV_GOT_HI20:
784+ if (!riscv_elf_record_got_reference (abfd, info, h, r_symndx)
785+ || !riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_NORMAL))
786+ return FALSE;
787+ break;
788+
789+ case R_RISCV_CALL_PLT:
790+ /* This symbol requires a procedure linkage table entry. We
791+ actually build the entry in adjust_dynamic_symbol,
792+ because this might be a case of linking PIC code without
793+ linking in any dynamic objects, in which case we don't
794+ need to generate a procedure linkage table after all. */
795+
796+ if (h != NULL)
797+ {
798+ h->needs_plt = 1;
799+ h->plt.refcount += 1;
800+ }
801+ break;
802+
803+ case R_RISCV_CALL:
804+ case R_RISCV_JAL:
805+ case R_RISCV_BRANCH:
806+ case R_RISCV_PCREL_HI20:
807+ /* In shared libs, these relocs are known to bind locally. */
808+ if (info->shared)
809+ break;
810+ goto static_reloc;
811+
812+ case R_RISCV_TPREL_HI20:
813+ if (!info->executable)
814+ return bad_static_reloc (abfd, r_type, h);
815+ if (h != NULL)
816+ riscv_elf_record_tls_type (abfd, h, r_symndx, GOT_TLS_LE);
817+ goto static_reloc;
818+
819+ case R_RISCV_HI20:
820+ if (info->shared)
821+ return bad_static_reloc (abfd, r_type, h);
822+ /* Fall through. */
823+
824+ case R_RISCV_COPY:
825+ case R_RISCV_JUMP_SLOT:
826+ case R_RISCV_RELATIVE:
827+ case R_RISCV_64:
828+ case R_RISCV_32:
829+ /* Fall through. */
830+
831+ static_reloc:
832+ if (h != NULL)
833+ h->non_got_ref = 1;
834+
835+ if (h != NULL && !info->shared)
836+ {
837+ /* We may need a .plt entry if the function this reloc
838+ refers to is in a shared lib. */
839+ h->plt.refcount += 1;
840+ }
841+
842+ /* If we are creating a shared library, and this is a reloc
843+ against a global symbol, or a non PC relative reloc
844+ against a local symbol, then we need to copy the reloc
845+ into the shared library. However, if we are linking with
846+ -Bsymbolic, we do not need to copy a reloc against a
847+ global symbol which is defined in an object we are
848+ including in the link (i.e., DEF_REGULAR is set). At
849+ this point we have not seen all the input files, so it is
850+ possible that DEF_REGULAR is not set now but will be set
851+ later (it is never cleared). In case of a weak definition,
852+ DEF_REGULAR may be cleared later by a strong definition in
853+ a shared library. We account for that possibility below by
854+ storing information in the relocs_copied field of the hash
855+ table entry. A similar situation occurs when creating
856+ shared libraries and symbol visibility changes render the
857+ symbol local.
858+
859+ If on the other hand, we are creating an executable, we
860+ may need to keep relocations for symbols satisfied by a
861+ dynamic library if we manage to avoid copy relocs for the
862+ symbol. */
863+ if ((info->shared
864+ && (sec->flags & SEC_ALLOC) != 0
865+ && (! riscv_elf_rtype_to_howto (r_type)->pc_relative
866+ || (h != NULL
867+ && (! info->symbolic
868+ || h->root.type == bfd_link_hash_defweak
869+ || !h->def_regular))))
870+ || (!info->shared
871+ && (sec->flags & SEC_ALLOC) != 0
872+ && h != NULL
873+ && (h->root.type == bfd_link_hash_defweak
874+ || !h->def_regular)))
875+ {
876+ struct riscv_elf_dyn_relocs *p;
877+ struct riscv_elf_dyn_relocs **head;
878+
879+ /* When creating a shared object, we must copy these
880+ relocs into the output file. We create a reloc
881+ section in dynobj and make room for the reloc. */
882+ if (sreloc == NULL)
883+ {
884+ sreloc = _bfd_elf_make_dynamic_reloc_section
885+ (sec, htab->elf.dynobj, RISCV_ELF_LOG_WORD_BYTES,
886+ abfd, /*rela?*/ TRUE);
887+
888+ if (sreloc == NULL)
889+ return FALSE;
890+ }
891+
892+ /* If this is a global symbol, we count the number of
893+ relocations we need for this symbol. */
894+ if (h != NULL)
895+ head = &((struct riscv_elf_link_hash_entry *) h)->dyn_relocs;
896+ else
897+ {
898+ /* Track dynamic relocs needed for local syms too.
899+ We really need local syms available to do this
900+ easily. Oh well. */
901+
902+ asection *s;
903+ void *vpp;
904+ Elf_Internal_Sym *isym;
905+
906+ isym = bfd_sym_from_r_symndx (&htab->sym_cache,
907+ abfd, r_symndx);
908+ if (isym == NULL)
909+ return FALSE;
910+
911+ s = bfd_section_from_elf_index (abfd, isym->st_shndx);
912+ if (s == NULL)
913+ s = sec;
914+
915+ vpp = &elf_section_data (s)->local_dynrel;
916+ head = (struct riscv_elf_dyn_relocs **) vpp;
917+ }
918+
919+ p = *head;
920+ if (p == NULL || p->sec != sec)
921+ {
922+ bfd_size_type amt = sizeof *p;
923+ p = ((struct riscv_elf_dyn_relocs *)
924+ bfd_alloc (htab->elf.dynobj, amt));
925+ if (p == NULL)
926+ return FALSE;
927+ p->next = *head;
928+ *head = p;
929+ p->sec = sec;
930+ p->count = 0;
931+ p->pc_count = 0;
932+ }
933+
934+ p->count += 1;
935+ p->pc_count += riscv_elf_rtype_to_howto (r_type)->pc_relative;
936+ }
937+
938+ break;
939+
940+ case R_RISCV_GNU_VTINHERIT:
941+ if (!bfd_elf_gc_record_vtinherit (abfd, sec, h, rel->r_offset))
942+ return FALSE;
943+ break;
944+
945+ case R_RISCV_GNU_VTENTRY:
946+ if (!bfd_elf_gc_record_vtentry (abfd, sec, h, rel->r_addend))
947+ return FALSE;
948+ break;
949+
950+ default:
951+ break;
952+ }
953+ }
954+
955+ return TRUE;
956+}
957+
958+static asection *
959+riscv_elf_gc_mark_hook (asection *sec,
960+ struct bfd_link_info *info,
961+ Elf_Internal_Rela *rel,
962+ struct elf_link_hash_entry *h,
963+ Elf_Internal_Sym *sym)
964+{
965+ if (h != NULL)
966+ switch (ELFNN_R_TYPE (rel->r_info))
967+ {
968+ case R_RISCV_GNU_VTINHERIT:
969+ case R_RISCV_GNU_VTENTRY:
970+ return NULL;
971+ }
972+
973+ return _bfd_elf_gc_mark_hook (sec, info, rel, h, sym);
974+}
975+
976+/* Update the got entry reference counts for the section being removed. */
977+static bfd_boolean
978+riscv_elf_gc_sweep_hook (bfd *abfd, struct bfd_link_info *info,
979+ asection *sec, const Elf_Internal_Rela *relocs)
980+{
981+ const Elf_Internal_Rela *rel, *relend;
982+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
983+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
984+ bfd_signed_vma *local_got_refcounts = elf_local_got_refcounts (abfd);
985+
986+ if (info->relocatable)
987+ return TRUE;
988+
989+ elf_section_data (sec)->local_dynrel = NULL;
990+
991+ for (rel = relocs, relend = relocs + sec->reloc_count; rel < relend; rel++)
992+ {
993+ unsigned long r_symndx;
994+ struct elf_link_hash_entry *h = NULL;
995+
996+ r_symndx = ELFNN_R_SYM (rel->r_info);
997+ if (r_symndx >= symtab_hdr->sh_info)
998+ {
999+ struct riscv_elf_link_hash_entry *eh;
1000+ struct riscv_elf_dyn_relocs **pp;
1001+ struct riscv_elf_dyn_relocs *p;
1002+
1003+ h = sym_hashes[r_symndx - symtab_hdr->sh_info];
1004+ while (h->root.type == bfd_link_hash_indirect
1005+ || h->root.type == bfd_link_hash_warning)
1006+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
1007+ eh = (struct riscv_elf_link_hash_entry *) h;
1008+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; pp = &p->next)
1009+ if (p->sec == sec)
1010+ {
1011+ /* Everything must go for SEC. */
1012+ *pp = p->next;
1013+ break;
1014+ }
1015+ }
1016+
1017+ switch (ELFNN_R_TYPE (rel->r_info))
1018+ {
1019+ case R_RISCV_GOT_HI20:
1020+ case R_RISCV_TLS_GOT_HI20:
1021+ case R_RISCV_TLS_GD_HI20:
1022+ if (h != NULL)
1023+ {
1024+ if (h->got.refcount > 0)
1025+ h->got.refcount--;
1026+ }
1027+ else
1028+ {
1029+ if (local_got_refcounts &&
1030+ local_got_refcounts[r_symndx] > 0)
1031+ local_got_refcounts[r_symndx]--;
1032+ }
1033+ break;
1034+
1035+ case R_RISCV_HI20:
1036+ case R_RISCV_PCREL_HI20:
1037+ case R_RISCV_COPY:
1038+ case R_RISCV_JUMP_SLOT:
1039+ case R_RISCV_RELATIVE:
1040+ case R_RISCV_64:
1041+ case R_RISCV_32:
1042+ case R_RISCV_BRANCH:
1043+ case R_RISCV_CALL:
1044+ case R_RISCV_JAL:
1045+ if (info->shared)
1046+ break;
1047+ /* Fall through. */
1048+
1049+ case R_RISCV_CALL_PLT:
1050+ if (h != NULL)
1051+ {
1052+ if (h->plt.refcount > 0)
1053+ h->plt.refcount--;
1054+ }
1055+ break;
1056+
1057+ default:
1058+ break;
1059+ }
1060+ }
1061+
1062+ return TRUE;
1063+}
1064+
1065+/* Adjust a symbol defined by a dynamic object and referenced by a
1066+ regular object. The current definition is in some section of the
1067+ dynamic object, but we're not including those sections. We have to
1068+ change the definition to something the rest of the link can
1069+ understand. */
1070+
1071+static bfd_boolean
1072+riscv_elf_adjust_dynamic_symbol (struct bfd_link_info *info,
1073+ struct elf_link_hash_entry *h)
1074+{
1075+ struct riscv_elf_link_hash_table *htab;
1076+ struct riscv_elf_link_hash_entry * eh;
1077+ struct riscv_elf_dyn_relocs *p;
1078+ bfd *dynobj;
1079+ asection *s;
1080+
1081+ htab = riscv_elf_hash_table (info);
1082+ BFD_ASSERT (htab != NULL);
1083+
1084+ dynobj = htab->elf.dynobj;
1085+
1086+ /* Make sure we know what is going on here. */
1087+ BFD_ASSERT (dynobj != NULL
1088+ && (h->needs_plt
1089+ || h->u.weakdef != NULL
1090+ || (h->def_dynamic
1091+ && h->ref_regular
1092+ && !h->def_regular)));
1093+
1094+ /* If this is a function, put it in the procedure linkage table. We
1095+ will fill in the contents of the procedure linkage table later
1096+ (although we could actually do it here). */
1097+ if (h->type == STT_FUNC || h->needs_plt)
1098+ {
1099+ if (h->plt.refcount <= 0
1100+ || SYMBOL_CALLS_LOCAL (info, h)
1101+ || (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT
1102+ && h->root.type == bfd_link_hash_undefweak))
1103+ {
1104+ /* This case can occur if we saw a R_RISCV_CALL_PLT reloc in an
1105+ input file, but the symbol was never referred to by a dynamic
1106+ object, or if all references were garbage collected. In such
1107+ a case, we don't actually need to build a PLT entry. */
1108+ h->plt.offset = (bfd_vma) -1;
1109+ h->needs_plt = 0;
1110+ }
1111+
1112+ return TRUE;
1113+ }
1114+ else
1115+ h->plt.offset = (bfd_vma) -1;
1116+
1117+ /* If this is a weak symbol, and there is a real definition, the
1118+ processor independent code will have arranged for us to see the
1119+ real definition first, and we can just use the same value. */
1120+ if (h->u.weakdef != NULL)
1121+ {
1122+ BFD_ASSERT (h->u.weakdef->root.type == bfd_link_hash_defined
1123+ || h->u.weakdef->root.type == bfd_link_hash_defweak);
1124+ h->root.u.def.section = h->u.weakdef->root.u.def.section;
1125+ h->root.u.def.value = h->u.weakdef->root.u.def.value;
1126+ return TRUE;
1127+ }
1128+
1129+ /* This is a reference to a symbol defined by a dynamic object which
1130+ is not a function. */
1131+
1132+ /* If we are creating a shared library, we must presume that the
1133+ only references to the symbol are via the global offset table.
1134+ For such cases we need not do anything here; the relocations will
1135+ be handled correctly by relocate_section. */
1136+ if (info->shared)
1137+ return TRUE;
1138+
1139+ /* If there are no references to this symbol that do not use the
1140+ GOT, we don't need to generate a copy reloc. */
1141+ if (!h->non_got_ref)
1142+ return TRUE;
1143+
1144+ /* If -z nocopyreloc was given, we won't generate them either. */
1145+ if (info->nocopyreloc)
1146+ {
1147+ h->non_got_ref = 0;
1148+ return TRUE;
1149+ }
1150+
1151+ eh = (struct riscv_elf_link_hash_entry *) h;
1152+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
1153+ {
1154+ s = p->sec->output_section;
1155+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
1156+ break;
1157+ }
1158+
1159+ /* If we didn't find any dynamic relocs in read-only sections, then
1160+ we'll be keeping the dynamic relocs and avoiding the copy reloc. */
1161+ if (p == NULL)
1162+ {
1163+ h->non_got_ref = 0;
1164+ return TRUE;
1165+ }
1166+
1167+ /* We must allocate the symbol in our .dynbss section, which will
1168+ become part of the .bss section of the executable. There will be
1169+ an entry for this symbol in the .dynsym section. The dynamic
1170+ object will contain position independent code, so all references
1171+ from the dynamic object to this symbol will go through the global
1172+ offset table. The dynamic linker will use the .dynsym entry to
1173+ determine the address it must put in the global offset table, so
1174+ both the dynamic object and the regular object will refer to the
1175+ same memory location for the variable. */
1176+
1177+ /* We must generate a R_RISCV_COPY reloc to tell the dynamic linker
1178+ to copy the initial value out of the dynamic object and into the
1179+ runtime process image. We need to remember the offset into the
1180+ .rel.bss section we are going to use. */
1181+ if ((h->root.u.def.section->flags & SEC_ALLOC) != 0 && h->size != 0)
1182+ {
1183+ htab->srelbss->size += sizeof (ElfNN_External_Rela);
1184+ h->needs_copy = 1;
1185+ }
1186+
1187+ if (eh->tls_type & ~GOT_NORMAL)
1188+ return _bfd_elf_adjust_dynamic_copy (h, htab->sdyntdata);
1189+
1190+ return _bfd_elf_adjust_dynamic_copy (h, htab->sdynbss);
1191+}
1192+
1193+/* Allocate space in .plt, .got and associated reloc sections for
1194+ dynamic relocs. */
1195+
1196+static bfd_boolean
1197+allocate_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1198+{
1199+ struct bfd_link_info *info;
1200+ struct riscv_elf_link_hash_table *htab;
1201+ struct riscv_elf_link_hash_entry *eh;
1202+ struct riscv_elf_dyn_relocs *p;
1203+
1204+ if (h->root.type == bfd_link_hash_indirect)
1205+ return TRUE;
1206+
1207+ info = (struct bfd_link_info *) inf;
1208+ htab = riscv_elf_hash_table (info);
1209+ BFD_ASSERT (htab != NULL);
1210+
1211+ if (htab->elf.dynamic_sections_created
1212+ && h->plt.refcount > 0)
1213+ {
1214+ /* Make sure this symbol is output as a dynamic symbol.
1215+ Undefined weak syms won't yet be marked as dynamic. */
1216+ if (h->dynindx == -1
1217+ && !h->forced_local)
1218+ {
1219+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
1220+ return FALSE;
1221+ }
1222+
1223+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (1, info->shared, h))
1224+ {
1225+ asection *s = htab->elf.splt;
1226+
1227+ if (s->size == 0)
1228+ s->size = PLT_HEADER_SIZE;
1229+
1230+ h->plt.offset = s->size;
1231+
1232+ /* Make room for this entry. */
1233+ s->size += PLT_ENTRY_SIZE;
1234+
1235+ /* We also need to make an entry in the .got.plt section. */
1236+ htab->elf.sgotplt->size += GOT_ENTRY_SIZE;
1237+
1238+ /* We also need to make an entry in the .rela.plt section. */
1239+ htab->elf.srelplt->size += sizeof (ElfNN_External_Rela);
1240+
1241+ /* If this symbol is not defined in a regular file, and we are
1242+ not generating a shared library, then set the symbol to this
1243+ location in the .plt. This is required to make function
1244+ pointers compare as equal between the normal executable and
1245+ the shared library. */
1246+ if (! info->shared
1247+ && !h->def_regular)
1248+ {
1249+ h->root.u.def.section = s;
1250+ h->root.u.def.value = h->plt.offset;
1251+ }
1252+ }
1253+ else
1254+ {
1255+ h->plt.offset = (bfd_vma) -1;
1256+ h->needs_plt = 0;
1257+ }
1258+ }
1259+ else
1260+ {
1261+ h->plt.offset = (bfd_vma) -1;
1262+ h->needs_plt = 0;
1263+ }
1264+
1265+ if (h->got.refcount > 0)
1266+ {
1267+ asection *s;
1268+ bfd_boolean dyn;
1269+ int tls_type = riscv_elf_hash_entry(h)->tls_type;
1270+
1271+ /* Make sure this symbol is output as a dynamic symbol.
1272+ Undefined weak syms won't yet be marked as dynamic. */
1273+ if (h->dynindx == -1
1274+ && !h->forced_local)
1275+ {
1276+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
1277+ return FALSE;
1278+ }
1279+
1280+ s = htab->elf.sgot;
1281+ h->got.offset = s->size;
1282+ dyn = htab->elf.dynamic_sections_created;
1283+ if (tls_type & (GOT_TLS_GD | GOT_TLS_IE))
1284+ {
1285+ /* TLS_GD needs two dynamic relocs and two GOT slots. */
1286+ if (tls_type & GOT_TLS_GD)
1287+ {
1288+ s->size += 2 * RISCV_ELF_WORD_BYTES;
1289+ htab->elf.srelgot->size += 2 * sizeof (ElfNN_External_Rela);
1290+ }
1291+
1292+ /* TLS_IE needs one dynamic reloc and one GOT slot. */
1293+ if (tls_type & GOT_TLS_IE)
1294+ {
1295+ s->size += RISCV_ELF_WORD_BYTES;
1296+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1297+ }
1298+ }
1299+ else
1300+ {
1301+ s->size += RISCV_ELF_WORD_BYTES;
1302+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h))
1303+ htab->elf.srelgot->size += sizeof (ElfNN_External_Rela);
1304+ }
1305+ }
1306+ else
1307+ h->got.offset = (bfd_vma) -1;
1308+
1309+ eh = (struct riscv_elf_link_hash_entry *) h;
1310+ if (eh->dyn_relocs == NULL)
1311+ return TRUE;
1312+
1313+ /* In the shared -Bsymbolic case, discard space allocated for
1314+ dynamic pc-relative relocs against symbols which turn out to be
1315+ defined in regular objects. For the normal shared case, discard
1316+ space for pc-relative relocs that have become local due to symbol
1317+ visibility changes. */
1318+
1319+ if (info->shared)
1320+ {
1321+ if (SYMBOL_CALLS_LOCAL (info, h))
1322+ {
1323+ struct riscv_elf_dyn_relocs **pp;
1324+
1325+ for (pp = &eh->dyn_relocs; (p = *pp) != NULL; )
1326+ {
1327+ p->count -= p->pc_count;
1328+ p->pc_count = 0;
1329+ if (p->count == 0)
1330+ *pp = p->next;
1331+ else
1332+ pp = &p->next;
1333+ }
1334+ }
1335+
1336+ /* Also discard relocs on undefined weak syms with non-default
1337+ visibility. */
1338+ if (eh->dyn_relocs != NULL
1339+ && h->root.type == bfd_link_hash_undefweak)
1340+ {
1341+ if (ELF_ST_VISIBILITY (h->other) != STV_DEFAULT)
1342+ eh->dyn_relocs = NULL;
1343+
1344+ /* Make sure undefined weak symbols are output as a dynamic
1345+ symbol in PIEs. */
1346+ else if (h->dynindx == -1
1347+ && !h->forced_local)
1348+ {
1349+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
1350+ return FALSE;
1351+ }
1352+ }
1353+ }
1354+ else
1355+ {
1356+ /* For the non-shared case, discard space for relocs against
1357+ symbols which turn out to need copy relocs or are not
1358+ dynamic. */
1359+
1360+ if (!h->non_got_ref
1361+ && ((h->def_dynamic
1362+ && !h->def_regular)
1363+ || (htab->elf.dynamic_sections_created
1364+ && (h->root.type == bfd_link_hash_undefweak
1365+ || h->root.type == bfd_link_hash_undefined))))
1366+ {
1367+ /* Make sure this symbol is output as a dynamic symbol.
1368+ Undefined weak syms won't yet be marked as dynamic. */
1369+ if (h->dynindx == -1
1370+ && !h->forced_local)
1371+ {
1372+ if (! bfd_elf_link_record_dynamic_symbol (info, h))
1373+ return FALSE;
1374+ }
1375+
1376+ /* If that succeeded, we know we'll be keeping all the
1377+ relocs. */
1378+ if (h->dynindx != -1)
1379+ goto keep;
1380+ }
1381+
1382+ eh->dyn_relocs = NULL;
1383+
1384+ keep: ;
1385+ }
1386+
1387+ /* Finally, allocate space. */
1388+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
1389+ {
1390+ asection *sreloc = elf_section_data (p->sec)->sreloc;
1391+ sreloc->size += p->count * sizeof (ElfNN_External_Rela);
1392+ }
1393+
1394+ return TRUE;
1395+}
1396+
1397+/* Find any dynamic relocs that apply to read-only sections. */
1398+
1399+static bfd_boolean
1400+readonly_dynrelocs (struct elf_link_hash_entry *h, void *inf)
1401+{
1402+ struct riscv_elf_link_hash_entry *eh;
1403+ struct riscv_elf_dyn_relocs *p;
1404+
1405+ eh = (struct riscv_elf_link_hash_entry *) h;
1406+ for (p = eh->dyn_relocs; p != NULL; p = p->next)
1407+ {
1408+ asection *s = p->sec->output_section;
1409+
1410+ if (s != NULL && (s->flags & SEC_READONLY) != 0)
1411+ {
1412+ ((struct bfd_link_info *) inf)->flags |= DF_TEXTREL;
1413+
1414+ /* Short-circuit the traversal. */
1415+ return FALSE;
1416+ }
1417+ }
1418+ return TRUE;
1419+}
1420+
1421+static bfd_boolean
1422+riscv_elf_size_dynamic_sections (bfd *output_bfd, struct bfd_link_info *info)
1423+{
1424+ struct riscv_elf_link_hash_table *htab;
1425+ bfd *dynobj;
1426+ asection *s;
1427+ bfd *ibfd;
1428+
1429+ htab = riscv_elf_hash_table (info);
1430+ BFD_ASSERT (htab != NULL);
1431+ dynobj = htab->elf.dynobj;
1432+ BFD_ASSERT (dynobj != NULL);
1433+
1434+ if (elf_hash_table (info)->dynamic_sections_created)
1435+ {
1436+ /* Set the contents of the .interp section to the interpreter. */
1437+ if (info->executable)
1438+ {
1439+ s = bfd_get_linker_section (dynobj, ".interp");
1440+ BFD_ASSERT (s != NULL);
1441+ s->size = strlen (ELFNN_DYNAMIC_INTERPRETER) + 1;
1442+ s->contents = (unsigned char *) ELFNN_DYNAMIC_INTERPRETER;
1443+ }
1444+ }
1445+
1446+ /* Set up .got offsets for local syms, and space for local dynamic
1447+ relocs. */
1448+ for (ibfd = info->input_bfds; ibfd != NULL; ibfd = ibfd->link.next)
1449+ {
1450+ bfd_signed_vma *local_got;
1451+ bfd_signed_vma *end_local_got;
1452+ char *local_tls_type;
1453+ bfd_size_type locsymcount;
1454+ Elf_Internal_Shdr *symtab_hdr;
1455+ asection *srel;
1456+
1457+ if (! is_riscv_elf (ibfd))
1458+ continue;
1459+
1460+ for (s = ibfd->sections; s != NULL; s = s->next)
1461+ {
1462+ struct riscv_elf_dyn_relocs *p;
1463+
1464+ for (p = elf_section_data (s)->local_dynrel; p != NULL; p = p->next)
1465+ {
1466+ if (!bfd_is_abs_section (p->sec)
1467+ && bfd_is_abs_section (p->sec->output_section))
1468+ {
1469+ /* Input section has been discarded, either because
1470+ it is a copy of a linkonce section or due to
1471+ linker script /DISCARD/, so we'll be discarding
1472+ the relocs too. */
1473+ }
1474+ else if (p->count != 0)
1475+ {
1476+ srel = elf_section_data (p->sec)->sreloc;
1477+ srel->size += p->count * sizeof (ElfNN_External_Rela);
1478+ if ((p->sec->output_section->flags & SEC_READONLY) != 0)
1479+ info->flags |= DF_TEXTREL;
1480+ }
1481+ }
1482+ }
1483+
1484+ local_got = elf_local_got_refcounts (ibfd);
1485+ if (!local_got)
1486+ continue;
1487+
1488+ symtab_hdr = &elf_symtab_hdr (ibfd);
1489+ locsymcount = symtab_hdr->sh_info;
1490+ end_local_got = local_got + locsymcount;
1491+ local_tls_type = _bfd_riscv_elf_local_got_tls_type (ibfd);
1492+ s = htab->elf.sgot;
1493+ srel = htab->elf.srelgot;
1494+ for (; local_got < end_local_got; ++local_got, ++local_tls_type)
1495+ {
1496+ if (*local_got > 0)
1497+ {
1498+ *local_got = s->size;
1499+ s->size += RISCV_ELF_WORD_BYTES;
1500+ if (*local_tls_type & GOT_TLS_GD)
1501+ s->size += RISCV_ELF_WORD_BYTES;
1502+ if (info->shared
1503+ || (*local_tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
1504+ srel->size += sizeof (ElfNN_External_Rela);
1505+ }
1506+ else
1507+ *local_got = (bfd_vma) -1;
1508+ }
1509+ }
1510+
1511+ /* Allocate global sym .plt and .got entries, and space for global
1512+ sym dynamic relocs. */
1513+ elf_link_hash_traverse (&htab->elf, allocate_dynrelocs, info);
1514+
1515+ if (htab->elf.sgotplt)
1516+ {
1517+ struct elf_link_hash_entry *got;
1518+ got = elf_link_hash_lookup (elf_hash_table (info),
1519+ "_GLOBAL_OFFSET_TABLE_",
1520+ FALSE, FALSE, FALSE);
1521+
1522+ /* Don't allocate .got.plt section if there are no GOT nor PLT
1523+ entries and there is no refeence to _GLOBAL_OFFSET_TABLE_. */
1524+ if ((got == NULL
1525+ || !got->ref_regular_nonweak)
1526+ && (htab->elf.sgotplt->size == GOTPLT_HEADER_SIZE)
1527+ && (htab->elf.splt == NULL
1528+ || htab->elf.splt->size == 0)
1529+ && (htab->elf.sgot == NULL
1530+ || (htab->elf.sgot->size
1531+ == get_elf_backend_data (output_bfd)->got_header_size)))
1532+ htab->elf.sgotplt->size = 0;
1533+ }
1534+
1535+ /* The check_relocs and adjust_dynamic_symbol entry points have
1536+ determined the sizes of the various dynamic sections. Allocate
1537+ memory for them. */
1538+ for (s = dynobj->sections; s != NULL; s = s->next)
1539+ {
1540+ if ((s->flags & SEC_LINKER_CREATED) == 0)
1541+ continue;
1542+
1543+ if (s == htab->elf.splt
1544+ || s == htab->elf.sgot
1545+ || s == htab->elf.sgotplt
1546+ || s == htab->sdynbss)
1547+ {
1548+ /* Strip this section if we don't need it; see the
1549+ comment below. */
1550+ }
1551+ else if (strncmp (s->name, ".rela", 5) == 0)
1552+ {
1553+ if (s->size != 0)
1554+ {
1555+ /* We use the reloc_count field as a counter if we need
1556+ to copy relocs into the output file. */
1557+ s->reloc_count = 0;
1558+ }
1559+ }
1560+ else
1561+ {
1562+ /* It's not one of our sections. */
1563+ continue;
1564+ }
1565+
1566+ if (s->size == 0)
1567+ {
1568+ /* If we don't need this section, strip it from the
1569+ output file. This is mostly to handle .rela.bss and
1570+ .rela.plt. We must create both sections in
1571+ create_dynamic_sections, because they must be created
1572+ before the linker maps input sections to output
1573+ sections. The linker does that before
1574+ adjust_dynamic_symbol is called, and it is that
1575+ function which decides whether anything needs to go
1576+ into these sections. */
1577+ s->flags |= SEC_EXCLUDE;
1578+ continue;
1579+ }
1580+
1581+ if ((s->flags & SEC_HAS_CONTENTS) == 0)
1582+ continue;
1583+
1584+ /* Allocate memory for the section contents. Zero the memory
1585+ for the benefit of .rela.plt, which has 4 unused entries
1586+ at the beginning, and we don't want garbage. */
1587+ s->contents = (bfd_byte *) bfd_zalloc (dynobj, s->size);
1588+ if (s->contents == NULL)
1589+ return FALSE;
1590+ }
1591+
1592+ if (elf_hash_table (info)->dynamic_sections_created)
1593+ {
1594+ /* Add some entries to the .dynamic section. We fill in the
1595+ values later, in riscv_elf_finish_dynamic_sections, but we
1596+ must add the entries now so that we get the correct size for
1597+ the .dynamic section. The DT_DEBUG entry is filled in by the
1598+ dynamic linker and used by the debugger. */
1599+#define add_dynamic_entry(TAG, VAL) \
1600+ _bfd_elf_add_dynamic_entry (info, TAG, VAL)
1601+
1602+ if (info->executable)
1603+ {
1604+ if (!add_dynamic_entry (DT_DEBUG, 0))
1605+ return FALSE;
1606+ }
1607+
1608+ if (htab->elf.srelplt->size != 0)
1609+ {
1610+ if (!add_dynamic_entry (DT_PLTGOT, 0)
1611+ || !add_dynamic_entry (DT_PLTRELSZ, 0)
1612+ || !add_dynamic_entry (DT_PLTREL, DT_RELA)
1613+ || !add_dynamic_entry (DT_JMPREL, 0))
1614+ return FALSE;
1615+ }
1616+
1617+ if (!add_dynamic_entry (DT_RELA, 0)
1618+ || !add_dynamic_entry (DT_RELASZ, 0)
1619+ || !add_dynamic_entry (DT_RELAENT, sizeof (ElfNN_External_Rela)))
1620+ return FALSE;
1621+
1622+ /* If any dynamic relocs apply to a read-only section,
1623+ then we need a DT_TEXTREL entry. */
1624+ if ((info->flags & DF_TEXTREL) == 0)
1625+ elf_link_hash_traverse (&htab->elf, readonly_dynrelocs, info);
1626+
1627+ if (info->flags & DF_TEXTREL)
1628+ {
1629+ if (!add_dynamic_entry (DT_TEXTREL, 0))
1630+ return FALSE;
1631+ }
1632+ }
1633+#undef add_dynamic_entry
1634+
1635+ return TRUE;
1636+}
1637+
1638+#define TP_OFFSET 0
1639+#define DTP_OFFSET 0x800
1640+
1641+/* Return the relocation value for a TLS dtp-relative reloc. */
1642+
1643+static bfd_vma
1644+dtpoff (struct bfd_link_info *info, bfd_vma address)
1645+{
1646+ /* If tls_sec is NULL, we should have signalled an error already. */
1647+ if (elf_hash_table (info)->tls_sec == NULL)
1648+ return 0;
1649+ return address - elf_hash_table (info)->tls_sec->vma - DTP_OFFSET;
1650+}
1651+
1652+/* Return the relocation value for a static TLS tp-relative relocation. */
1653+
1654+static bfd_vma
1655+tpoff (struct bfd_link_info *info, bfd_vma address)
1656+{
1657+ /* If tls_sec is NULL, we should have signalled an error already. */
1658+ if (elf_hash_table (info)->tls_sec == NULL)
1659+ return 0;
1660+ return address - elf_hash_table (info)->tls_sec->vma - TP_OFFSET;
1661+}
1662+
1663+/* Return the global pointer's value, or 0 if it is not in use. */
1664+
1665+static bfd_vma
1666+riscv_global_pointer_value (struct bfd_link_info *info)
1667+{
1668+ struct bfd_link_hash_entry *h;
1669+
1670+ h = bfd_link_hash_lookup (info->hash, "_gp", FALSE, FALSE, TRUE);
1671+ if (h == NULL || h->type != bfd_link_hash_defined)
1672+ return 0;
1673+
1674+ return h->u.def.value + sec_addr (h->u.def.section);
1675+}
1676+
1677+/* Emplace a static relocation. */
1678+
1679+static bfd_reloc_status_type
1680+perform_relocation (const reloc_howto_type *howto,
1681+ const Elf_Internal_Rela *rel,
1682+ bfd_vma value,
1683+ asection *input_section,
1684+ bfd *input_bfd,
1685+ bfd_byte *contents)
1686+{
1687+ if (howto->pc_relative)
1688+ value -= sec_addr (input_section) + rel->r_offset;
1689+ value += rel->r_addend;
1690+
1691+ switch (ELFNN_R_TYPE (rel->r_info))
1692+ {
1693+ case R_RISCV_HI20:
1694+ case R_RISCV_TPREL_HI20:
1695+ case R_RISCV_PCREL_HI20:
1696+ case R_RISCV_GOT_HI20:
1697+ case R_RISCV_TLS_GOT_HI20:
1698+ case R_RISCV_TLS_GD_HI20:
1699+ value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value));
1700+ break;
1701+
1702+ case R_RISCV_LO12_I:
1703+ case R_RISCV_TPREL_LO12_I:
1704+ case R_RISCV_PCREL_LO12_I:
1705+ value = ENCODE_ITYPE_IMM (value);
1706+ break;
1707+
1708+ case R_RISCV_LO12_S:
1709+ case R_RISCV_TPREL_LO12_S:
1710+ case R_RISCV_PCREL_LO12_S:
1711+ value = ENCODE_STYPE_IMM (value);
1712+ break;
1713+
1714+ case R_RISCV_CALL:
1715+ case R_RISCV_CALL_PLT:
1716+ if (!VALID_UTYPE_IMM (RISCV_CONST_HIGH_PART (value)))
1717+ return bfd_reloc_overflow;
1718+ value = ENCODE_UTYPE_IMM (RISCV_CONST_HIGH_PART (value))
1719+ | (ENCODE_ITYPE_IMM (value) << 32);
1720+ break;
1721+
1722+ case R_RISCV_JAL:
1723+ if (!VALID_UJTYPE_IMM (value))
1724+ return bfd_reloc_overflow;
1725+ value = ENCODE_UJTYPE_IMM (value);
1726+ break;
1727+
1728+ case R_RISCV_BRANCH:
1729+ if (!VALID_SBTYPE_IMM (value))
1730+ return bfd_reloc_overflow;
1731+ value = ENCODE_SBTYPE_IMM (value);
1732+ break;
1733+
1734+ case R_RISCV_32:
1735+ case R_RISCV_64:
1736+ case R_RISCV_ADD8:
1737+ case R_RISCV_ADD16:
1738+ case R_RISCV_ADD32:
1739+ case R_RISCV_ADD64:
1740+ case R_RISCV_SUB8:
1741+ case R_RISCV_SUB16:
1742+ case R_RISCV_SUB32:
1743+ case R_RISCV_SUB64:
1744+ case R_RISCV_TLS_DTPREL32:
1745+ case R_RISCV_TLS_DTPREL64:
1746+ break;
1747+
1748+ default:
1749+ return bfd_reloc_notsupported;
1750+ }
1751+
1752+ bfd_vma word = bfd_get (howto->bitsize, input_bfd, contents + rel->r_offset);
1753+ word = (word & ~howto->dst_mask) | (value & howto->dst_mask);
1754+ bfd_put (howto->bitsize, input_bfd, word, contents + rel->r_offset);
1755+
1756+ return bfd_reloc_ok;
1757+}
1758+
1759+/* Remember all PC-relative high-part relocs we've encountered to help us
1760+ later resolve the corresponding low-part relocs. */
1761+
1762+typedef struct {
1763+ bfd_vma address;
1764+ bfd_vma value;
1765+} riscv_pcrel_hi_reloc;
1766+
1767+typedef struct riscv_pcrel_lo_reloc {
1768+ asection *input_section;
1769+ struct bfd_link_info *info;
1770+ reloc_howto_type *howto;
1771+ const Elf_Internal_Rela *reloc;
1772+ bfd_vma addr;
1773+ const char *name;
1774+ bfd_byte *contents;
1775+ struct riscv_pcrel_lo_reloc *next;
1776+} riscv_pcrel_lo_reloc;
1777+
1778+typedef struct {
1779+ htab_t hi_relocs;
1780+ riscv_pcrel_lo_reloc *lo_relocs;
1781+} riscv_pcrel_relocs;
1782+
1783+static hashval_t
1784+riscv_pcrel_reloc_hash (const void *entry)
1785+{
1786+ const riscv_pcrel_hi_reloc *e = entry;
1787+ return (hashval_t)(e->address >> 2);
1788+}
1789+
1790+static bfd_boolean
1791+riscv_pcrel_reloc_eq (const void *entry1, const void *entry2)
1792+{
1793+ const riscv_pcrel_hi_reloc *e1 = entry1, *e2 = entry2;
1794+ return e1->address == e2->address;
1795+}
1796+
1797+static bfd_boolean
1798+riscv_init_pcrel_relocs (riscv_pcrel_relocs *p)
1799+{
1800+
1801+ p->lo_relocs = NULL;
1802+ p->hi_relocs = htab_create (1024, riscv_pcrel_reloc_hash,
1803+ riscv_pcrel_reloc_eq, free);
1804+ return p->hi_relocs != NULL;
1805+}
1806+
1807+static void
1808+riscv_free_pcrel_relocs (riscv_pcrel_relocs *p)
1809+{
1810+ riscv_pcrel_lo_reloc *cur = p->lo_relocs;
1811+ while (cur != NULL)
1812+ {
1813+ riscv_pcrel_lo_reloc *next = cur->next;
1814+ free (cur);
1815+ cur = next;
1816+ }
1817+
1818+ htab_delete (p->hi_relocs);
1819+}
1820+
1821+static bfd_boolean
1822+riscv_record_pcrel_hi_reloc (riscv_pcrel_relocs *p, bfd_vma addr, bfd_vma value)
1823+{
1824+ riscv_pcrel_hi_reloc entry = {addr, value - addr};
1825+ riscv_pcrel_hi_reloc **slot =
1826+ (riscv_pcrel_hi_reloc **) htab_find_slot (p->hi_relocs, &entry, INSERT);
1827+ BFD_ASSERT (*slot == NULL);
1828+ *slot = (riscv_pcrel_hi_reloc *) bfd_malloc (sizeof (riscv_pcrel_hi_reloc));
1829+ if (*slot == NULL)
1830+ return FALSE;
1831+ **slot = entry;
1832+ return TRUE;
1833+}
1834+
1835+static bfd_boolean
1836+riscv_record_pcrel_lo_reloc (riscv_pcrel_relocs *p,
1837+ asection *input_section,
1838+ struct bfd_link_info *info,
1839+ reloc_howto_type *howto,
1840+ const Elf_Internal_Rela *reloc,
1841+ bfd_vma addr,
1842+ const char *name,
1843+ bfd_byte *contents)
1844+{
1845+ riscv_pcrel_lo_reloc *entry;
1846+ entry = (riscv_pcrel_lo_reloc *) bfd_malloc (sizeof (riscv_pcrel_lo_reloc));
1847+ if (entry == NULL)
1848+ return FALSE;
1849+ *entry = (riscv_pcrel_lo_reloc) {input_section, info, howto, reloc, addr,
1850+ name, contents, p->lo_relocs};
1851+ p->lo_relocs = entry;
1852+ return TRUE;
1853+}
1854+
1855+static bfd_boolean
1856+riscv_resolve_pcrel_lo_relocs (riscv_pcrel_relocs *p)
1857+{
1858+ riscv_pcrel_lo_reloc *r;
1859+ for (r = p->lo_relocs; r != NULL; r = r->next)
1860+ {
1861+ bfd *input_bfd = r->input_section->owner;
1862+ riscv_pcrel_hi_reloc search = {r->addr, 0};
1863+ riscv_pcrel_hi_reloc *entry = htab_find (p->hi_relocs, &search);
1864+ if (entry == NULL)
1865+ return ((*r->info->callbacks->reloc_overflow)
1866+ (r->info, NULL, r->name, r->howto->name, (bfd_vma) 0,
1867+ input_bfd, r->input_section, r->reloc->r_offset));
1868+
1869+ perform_relocation (r->howto, r->reloc, entry->value, r->input_section,
1870+ input_bfd, r->contents);
1871+ }
1872+
1873+ return TRUE;
1874+}
1875+
1876+/* Relocate a RISC-V ELF section.
1877+
1878+ The RELOCATE_SECTION function is called by the new ELF backend linker
1879+ to handle the relocations for a section.
1880+
1881+ The relocs are always passed as Rela structures.
1882+
1883+ This function is responsible for adjusting the section contents as
1884+ necessary, and (if generating a relocatable output file) adjusting
1885+ the reloc addend as necessary.
1886+
1887+ This function does not have to worry about setting the reloc
1888+ address or the reloc symbol index.
1889+
1890+ LOCAL_SYMS is a pointer to the swapped in local symbols.
1891+
1892+ LOCAL_SECTIONS is an array giving the section in the input file
1893+ corresponding to the st_shndx field of each local symbol.
1894+
1895+ The global hash table entry for the global symbols can be found
1896+ via elf_sym_hashes (input_bfd).
1897+
1898+ When generating relocatable output, this function must handle
1899+ STB_LOCAL/STT_SECTION symbols specially. The output symbol is
1900+ going to be the section symbol corresponding to the output
1901+ section, which means that the addend must be adjusted
1902+ accordingly. */
1903+
1904+static bfd_boolean
1905+riscv_elf_relocate_section (bfd *output_bfd, struct bfd_link_info *info,
1906+ bfd *input_bfd, asection *input_section,
1907+ bfd_byte *contents, Elf_Internal_Rela *relocs,
1908+ Elf_Internal_Sym *local_syms,
1909+ asection **local_sections)
1910+{
1911+ Elf_Internal_Rela *rel;
1912+ Elf_Internal_Rela *relend;
1913+ riscv_pcrel_relocs pcrel_relocs;
1914+ bfd_boolean ret = FALSE;
1915+ asection *sreloc = elf_section_data (input_section)->sreloc;
1916+ struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
1917+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (input_bfd);
1918+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (input_bfd);
1919+ bfd_vma *local_got_offsets = elf_local_got_offsets (input_bfd);
1920+
1921+ if (!riscv_init_pcrel_relocs (&pcrel_relocs))
1922+ return FALSE;
1923+
1924+ relend = relocs + input_section->reloc_count;
1925+ for (rel = relocs; rel < relend; rel++)
1926+ {
1927+ unsigned long r_symndx;
1928+ struct elf_link_hash_entry *h;
1929+ Elf_Internal_Sym *sym;
1930+ asection *sec;
1931+ bfd_vma relocation;
1932+ bfd_reloc_status_type r = bfd_reloc_ok;
1933+ const char *name;
1934+ bfd_vma off, ie_off;
1935+ bfd_boolean unresolved_reloc, is_ie = FALSE;
1936+ bfd_vma pc = sec_addr (input_section) + rel->r_offset;
1937+ int r_type = ELFNN_R_TYPE (rel->r_info), tls_type;
1938+ reloc_howto_type *howto = riscv_elf_rtype_to_howto (r_type);
1939+ const char *msg = NULL;
1940+
1941+ if (r_type == R_RISCV_GNU_VTINHERIT || r_type == R_RISCV_GNU_VTENTRY)
1942+ continue;
1943+
1944+ /* This is a final link. */
1945+ r_symndx = ELFNN_R_SYM (rel->r_info);
1946+ h = NULL;
1947+ sym = NULL;
1948+ sec = NULL;
1949+ unresolved_reloc = FALSE;
1950+ if (r_symndx < symtab_hdr->sh_info)
1951+ {
1952+ sym = local_syms + r_symndx;
1953+ sec = local_sections[r_symndx];
1954+ relocation = _bfd_elf_rela_local_sym (output_bfd, sym, &sec, rel);
1955+ }
1956+ else
1957+ {
1958+ bfd_boolean warned, ignored;
1959+
1960+ RELOC_FOR_GLOBAL_SYMBOL (info, input_bfd, input_section, rel,
1961+ r_symndx, symtab_hdr, sym_hashes,
1962+ h, sec, relocation,
1963+ unresolved_reloc, warned, ignored);
1964+ if (warned)
1965+ {
1966+ /* To avoid generating warning messages about truncated
1967+ relocations, set the relocation's address to be the same as
1968+ the start of this section. */
1969+ if (input_section->output_section != NULL)
1970+ relocation = input_section->output_section->vma;
1971+ else
1972+ relocation = 0;
1973+ }
1974+ }
1975+
1976+ if (sec != NULL && discarded_section (sec))
1977+ RELOC_AGAINST_DISCARDED_SECTION (info, input_bfd, input_section,
1978+ rel, 1, relend, howto, 0, contents);
1979+
1980+ if (info->relocatable)
1981+ continue;
1982+
1983+ if (h != NULL)
1984+ name = h->root.root.string;
1985+ else
1986+ {
1987+ name = (bfd_elf_string_from_elf_section
1988+ (input_bfd, symtab_hdr->sh_link, sym->st_name));
1989+ if (name == NULL || *name == '\0')
1990+ name = bfd_section_name (input_bfd, sec);
1991+ }
1992+
1993+ switch (r_type)
1994+ {
1995+ case R_RISCV_NONE:
1996+ case R_RISCV_TPREL_ADD:
1997+ case R_RISCV_COPY:
1998+ case R_RISCV_JUMP_SLOT:
1999+ case R_RISCV_RELATIVE:
2000+ /* These require nothing of us at all. */
2001+ continue;
2002+
2003+ case R_RISCV_BRANCH:
2004+ case R_RISCV_HI20:
2005+ /* These require no special handling beyond perform_relocation. */
2006+ break;
2007+
2008+ case R_RISCV_GOT_HI20:
2009+ if (h != NULL)
2010+ {
2011+ bfd_boolean dyn;
2012+
2013+ off = h->got.offset;
2014+ BFD_ASSERT (off != (bfd_vma) -1);
2015+ dyn = elf_hash_table (info)->dynamic_sections_created;
2016+
2017+ if (! WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
2018+ || (info->shared
2019+ && SYMBOL_REFERENCES_LOCAL (info, h)))
2020+ {
2021+ /* This is actually a static link, or it is a
2022+ -Bsymbolic link and the symbol is defined
2023+ locally, or the symbol was forced to be local
2024+ because of a version file. We must initialize
2025+ this entry in the global offset table. Since the
2026+ offset must always be a multiple of the word size,
2027+ we use the least significant bit to record whether
2028+ we have initialized it already.
2029+
2030+ When doing a dynamic link, we create a .rela.got
2031+ relocation entry to initialize the value. This
2032+ is done in the finish_dynamic_symbol routine. */
2033+ if ((off & 1) != 0)
2034+ off &= ~1;
2035+ else
2036+ {
2037+ bfd_put_NN (output_bfd, relocation,
2038+ htab->elf.sgot->contents + off);
2039+ h->got.offset |= 1;
2040+ }
2041+ }
2042+ else
2043+ unresolved_reloc = FALSE;
2044+ }
2045+ else
2046+ {
2047+ BFD_ASSERT (local_got_offsets != NULL
2048+ && local_got_offsets[r_symndx] != (bfd_vma) -1);
2049+
2050+ off = local_got_offsets[r_symndx];
2051+
2052+ /* The offset must always be a multiple of 8 on 64-bit.
2053+ We use the least significant bit to record
2054+ whether we have already processed this entry. */
2055+ if ((off & 1) != 0)
2056+ off &= ~1;
2057+ else
2058+ {
2059+ if (info->shared)
2060+ {
2061+ asection *s;
2062+ Elf_Internal_Rela outrel;
2063+
2064+ /* We need to generate a R_RISCV_RELATIVE reloc
2065+ for the dynamic linker. */
2066+ s = htab->elf.srelgot;
2067+ BFD_ASSERT (s != NULL);
2068+
2069+ outrel.r_offset = sec_addr (htab->elf.sgot) + off;
2070+ outrel.r_info =
2071+ ELFNN_R_INFO (0, R_RISCV_RELATIVE);
2072+ outrel.r_addend = relocation;
2073+ relocation = 0;
2074+ riscv_elf_append_rela (output_bfd, s, &outrel);
2075+ }
2076+
2077+ bfd_put_NN (output_bfd, relocation,
2078+ htab->elf.sgot->contents + off);
2079+ local_got_offsets[r_symndx] |= 1;
2080+ }
2081+ }
2082+ relocation = sec_addr (htab->elf.sgot) + off;
2083+ if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, relocation))
2084+ r = bfd_reloc_overflow;
2085+ break;
2086+
2087+ case R_RISCV_ADD8:
2088+ case R_RISCV_ADD16:
2089+ case R_RISCV_ADD32:
2090+ case R_RISCV_ADD64:
2091+ {
2092+ bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2093+ contents + rel->r_offset);
2094+ relocation = old_value + relocation;
2095+ }
2096+ break;
2097+
2098+ case R_RISCV_SUB8:
2099+ case R_RISCV_SUB16:
2100+ case R_RISCV_SUB32:
2101+ case R_RISCV_SUB64:
2102+ {
2103+ bfd_vma old_value = bfd_get (howto->bitsize, input_bfd,
2104+ contents + rel->r_offset);
2105+ relocation = old_value - relocation;
2106+ }
2107+ break;
2108+
2109+ case R_RISCV_CALL_PLT:
2110+ case R_RISCV_CALL:
2111+ case R_RISCV_JAL:
2112+ if (info->shared && h != NULL && h->plt.offset != MINUS_ONE)
2113+ {
2114+ /* Refer to the PLT entry. */
2115+ relocation = sec_addr (htab->elf.splt) + h->plt.offset;
2116+ unresolved_reloc = FALSE;
2117+ }
2118+ break;
2119+
2120+ case R_RISCV_TPREL_HI20:
2121+ relocation = tpoff (info, relocation);
2122+ break;
2123+
2124+ case R_RISCV_TPREL_LO12_I:
2125+ case R_RISCV_TPREL_LO12_S:
2126+ relocation = tpoff (info, relocation);
2127+ if (VALID_ITYPE_IMM (relocation + rel->r_addend))
2128+ {
2129+ /* We can use tp as the base register. */
2130+ bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
2131+ insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
2132+ insn |= X_TP << OP_SH_RS1;
2133+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
2134+ }
2135+ break;
2136+
2137+ case R_RISCV_LO12_I:
2138+ case R_RISCV_LO12_S:
2139+ {
2140+ bfd_vma gp = riscv_global_pointer_value (info);
2141+ bfd_boolean x0_base = VALID_ITYPE_IMM (relocation + rel->r_addend);
2142+ if (x0_base || VALID_ITYPE_IMM (relocation + rel->r_addend - gp))
2143+ {
2144+ /* We can use x0 or gp as the base register. */
2145+ bfd_vma insn = bfd_get_32 (input_bfd, contents + rel->r_offset);
2146+ insn &= ~(OP_MASK_RS1 << OP_SH_RS1);
2147+ if (!x0_base)
2148+ {
2149+ rel->r_addend -= gp;
2150+ insn |= X_GP << OP_SH_RS1;
2151+ }
2152+ bfd_put_32 (input_bfd, insn, contents + rel->r_offset);
2153+ }
2154+ break;
2155+ }
2156+
2157+ case R_RISCV_PCREL_HI20:
2158+ if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc,
2159+ relocation + rel->r_addend))
2160+ r = bfd_reloc_overflow;
2161+ break;
2162+
2163+ case R_RISCV_PCREL_LO12_I:
2164+ case R_RISCV_PCREL_LO12_S:
2165+ if (riscv_record_pcrel_lo_reloc (&pcrel_relocs, input_section, info,
2166+ howto, rel, relocation, name,
2167+ contents))
2168+ continue;
2169+ r = bfd_reloc_overflow;
2170+ break;
2171+
2172+ case R_RISCV_TLS_DTPREL32:
2173+ case R_RISCV_TLS_DTPREL64:
2174+ relocation = dtpoff (info, relocation);
2175+ break;
2176+
2177+ case R_RISCV_32:
2178+ case R_RISCV_64:
2179+ if ((input_section->flags & SEC_ALLOC) == 0)
2180+ break;
2181+
2182+ if ((info->shared
2183+ && (h == NULL
2184+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2185+ || h->root.type != bfd_link_hash_undefweak)
2186+ && (! howto->pc_relative
2187+ || !SYMBOL_CALLS_LOCAL (info, h)))
2188+ || (!info->shared
2189+ && h != NULL
2190+ && h->dynindx != -1
2191+ && !h->non_got_ref
2192+ && ((h->def_dynamic
2193+ && !h->def_regular)
2194+ || h->root.type == bfd_link_hash_undefweak
2195+ || h->root.type == bfd_link_hash_undefined)))
2196+ {
2197+ Elf_Internal_Rela outrel;
2198+ bfd_boolean skip_static_relocation, skip_dynamic_relocation;
2199+
2200+ /* When generating a shared object, these relocations
2201+ are copied into the output file to be resolved at run
2202+ time. */
2203+
2204+ outrel.r_offset =
2205+ _bfd_elf_section_offset (output_bfd, info, input_section,
2206+ rel->r_offset);
2207+ skip_static_relocation = outrel.r_offset != (bfd_vma) -2;
2208+ skip_dynamic_relocation = outrel.r_offset >= (bfd_vma) -2;
2209+ outrel.r_offset += sec_addr (input_section);
2210+
2211+ if (skip_dynamic_relocation)
2212+ memset (&outrel, 0, sizeof outrel);
2213+ else if (h != NULL && h->dynindx != -1
2214+ && !(info->shared
2215+ && SYMBOLIC_BIND (info, h)
2216+ && h->def_regular))
2217+ {
2218+ outrel.r_info = ELFNN_R_INFO (h->dynindx, r_type);
2219+ outrel.r_addend = rel->r_addend;
2220+ }
2221+ else
2222+ {
2223+ outrel.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
2224+ outrel.r_addend = relocation + rel->r_addend;
2225+ }
2226+
2227+ riscv_elf_append_rela (output_bfd, sreloc, &outrel);
2228+ if (skip_static_relocation)
2229+ continue;
2230+ }
2231+ break;
2232+
2233+ case R_RISCV_TLS_GOT_HI20:
2234+ is_ie = TRUE;
2235+ /* Fall through. */
2236+
2237+ case R_RISCV_TLS_GD_HI20:
2238+ if (h != NULL)
2239+ {
2240+ off = h->got.offset;
2241+ h->got.offset |= 1;
2242+ }
2243+ else
2244+ {
2245+ off = local_got_offsets[r_symndx];
2246+ local_got_offsets[r_symndx] |= 1;
2247+ }
2248+
2249+ tls_type = _bfd_riscv_elf_tls_type (input_bfd, h, r_symndx);
2250+ BFD_ASSERT (tls_type & (GOT_TLS_IE | GOT_TLS_GD));
2251+ /* If this symbol is referenced by both GD and IE TLS, the IE
2252+ reference's GOT slot follows the GD reference's slots. */
2253+ ie_off = 0;
2254+ if ((tls_type & GOT_TLS_GD) && (tls_type & GOT_TLS_IE))
2255+ ie_off = 2 * GOT_ENTRY_SIZE;
2256+
2257+ if ((off & 1) != 0)
2258+ off &= ~1;
2259+ else
2260+ {
2261+ Elf_Internal_Rela outrel;
2262+ int indx = 0;
2263+ bfd_boolean need_relocs = FALSE;
2264+
2265+ if (htab->elf.srelgot == NULL)
2266+ abort ();
2267+
2268+ if (h != NULL)
2269+ {
2270+ bfd_boolean dyn;
2271+ dyn = htab->elf.dynamic_sections_created;
2272+
2273+ if (WILL_CALL_FINISH_DYNAMIC_SYMBOL (dyn, info->shared, h)
2274+ && (!info->shared
2275+ || !SYMBOL_REFERENCES_LOCAL (info, h)))
2276+ {
2277+ indx = h->dynindx;
2278+ }
2279+ }
2280+
2281+ /* The GOT entries have not been initialized yet. Do it
2282+ now, and emit any relocations. */
2283+ if ((info->shared || indx != 0)
2284+ && (h == NULL
2285+ || ELF_ST_VISIBILITY (h->other) == STV_DEFAULT
2286+ || h->root.type != bfd_link_hash_undefweak))
2287+ need_relocs = TRUE;
2288+
2289+ if (tls_type & GOT_TLS_GD)
2290+ {
2291+ if (need_relocs)
2292+ {
2293+ outrel.r_offset = sec_addr (htab->elf.sgot) + off;
2294+ outrel.r_addend = 0;
2295+ outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_DTPMODNN);
2296+ bfd_put_NN (output_bfd, 0,
2297+ htab->elf.sgot->contents + off);
2298+ riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
2299+ if (indx == 0)
2300+ {
2301+ BFD_ASSERT (! unresolved_reloc);
2302+ bfd_put_NN (output_bfd,
2303+ dtpoff (info, relocation),
2304+ (htab->elf.sgot->contents + off +
2305+ RISCV_ELF_WORD_BYTES));
2306+ }
2307+ else
2308+ {
2309+ bfd_put_NN (output_bfd, 0,
2310+ (htab->elf.sgot->contents + off +
2311+ RISCV_ELF_WORD_BYTES));
2312+ outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_DTPRELNN);
2313+ outrel.r_offset += RISCV_ELF_WORD_BYTES;
2314+ riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
2315+ }
2316+ }
2317+ else
2318+ {
2319+ /* If we are not emitting relocations for a
2320+ general dynamic reference, then we must be in a
2321+ static link or an executable link with the
2322+ symbol binding locally. Mark it as belonging
2323+ to module 1, the executable. */
2324+ bfd_put_NN (output_bfd, 1,
2325+ htab->elf.sgot->contents + off);
2326+ bfd_put_NN (output_bfd,
2327+ dtpoff (info, relocation),
2328+ (htab->elf.sgot->contents + off +
2329+ RISCV_ELF_WORD_BYTES));
2330+ }
2331+ }
2332+
2333+ if (tls_type & GOT_TLS_IE)
2334+ {
2335+ if (need_relocs)
2336+ {
2337+ bfd_put_NN (output_bfd, 0,
2338+ htab->elf.sgot->contents + off + ie_off);
2339+ outrel.r_offset = sec_addr (htab->elf.sgot)
2340+ + off + ie_off;
2341+ outrel.r_addend = 0;
2342+ if (indx == 0)
2343+ outrel.r_addend = tpoff (info, relocation);
2344+ outrel.r_info = ELFNN_R_INFO (indx, R_RISCV_TLS_TPRELNN);
2345+ riscv_elf_append_rela (output_bfd, htab->elf.srelgot, &outrel);
2346+ }
2347+ else
2348+ {
2349+ bfd_put_NN (output_bfd, tpoff (info, relocation),
2350+ htab->elf.sgot->contents + off + ie_off);
2351+ }
2352+ }
2353+ }
2354+
2355+ BFD_ASSERT (off < (bfd_vma) -2);
2356+ relocation = sec_addr (htab->elf.sgot) + off + (is_ie ? ie_off : 0);
2357+ if (!riscv_record_pcrel_hi_reloc (&pcrel_relocs, pc, relocation))
2358+ r = bfd_reloc_overflow;
2359+ unresolved_reloc = FALSE;
2360+ break;
2361+
2362+ default:
2363+ r = bfd_reloc_notsupported;
2364+ }
2365+
2366+ /* Dynamic relocs are not propagated for SEC_DEBUGGING sections
2367+ because such sections are not SEC_ALLOC and thus ld.so will
2368+ not process them. */
2369+ if (unresolved_reloc
2370+ && !((input_section->flags & SEC_DEBUGGING) != 0
2371+ && h->def_dynamic)
2372+ && _bfd_elf_section_offset (output_bfd, info, input_section,
2373+ rel->r_offset) != (bfd_vma) -1)
2374+ {
2375+ (*_bfd_error_handler)
2376+ (_("%B(%A+0x%lx): unresolvable %s relocation against symbol `%s'"),
2377+ input_bfd,
2378+ input_section,
2379+ (long) rel->r_offset,
2380+ howto->name,
2381+ h->root.root.string);
2382+ continue;
2383+ }
2384+
2385+ if (r == bfd_reloc_ok)
2386+ r = perform_relocation (howto, rel, relocation, input_section,
2387+ input_bfd, contents);
2388+
2389+ switch (r)
2390+ {
2391+ case bfd_reloc_ok:
2392+ continue;
2393+
2394+ case bfd_reloc_overflow:
2395+ r = info->callbacks->reloc_overflow
2396+ (info, (h ? &h->root : NULL), name, howto->name,
2397+ (bfd_vma) 0, input_bfd, input_section, rel->r_offset);
2398+ break;
2399+
2400+ case bfd_reloc_undefined:
2401+ r = info->callbacks->undefined_symbol
2402+ (info, name, input_bfd, input_section, rel->r_offset,
2403+ TRUE);
2404+ break;
2405+
2406+ case bfd_reloc_outofrange:
2407+ msg = _("internal error: out of range error");
2408+ break;
2409+
2410+ case bfd_reloc_notsupported:
2411+ msg = _("internal error: unsupported relocation error");
2412+ break;
2413+
2414+ case bfd_reloc_dangerous:
2415+ msg = _("internal error: dangerous relocation");
2416+ break;
2417+
2418+ default:
2419+ msg = _("internal error: unknown error");
2420+ break;
2421+ }
2422+
2423+ if (msg)
2424+ r = info->callbacks->warning
2425+ (info, msg, name, input_bfd, input_section, rel->r_offset);
2426+ goto out;
2427+ }
2428+
2429+ ret = riscv_resolve_pcrel_lo_relocs (&pcrel_relocs);
2430+out:
2431+ riscv_free_pcrel_relocs (&pcrel_relocs);
2432+ return ret;
2433+}
2434+
2435+/* Finish up dynamic symbol handling. We set the contents of various
2436+ dynamic sections here. */
2437+
2438+static bfd_boolean
2439+riscv_elf_finish_dynamic_symbol (bfd *output_bfd,
2440+ struct bfd_link_info *info,
2441+ struct elf_link_hash_entry *h,
2442+ Elf_Internal_Sym *sym)
2443+{
2444+ struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
2445+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2446+
2447+ if (h->plt.offset != (bfd_vma) -1)
2448+ {
2449+ /* We've decided to create a PLT entry for this symbol. */
2450+ bfd_byte *loc;
2451+ bfd_vma i, header_address, plt_idx, got_address;
2452+ uint32_t plt_entry[PLT_ENTRY_INSNS];
2453+ Elf_Internal_Rela rela;
2454+
2455+ BFD_ASSERT (h->dynindx != -1);
2456+
2457+ /* Calculate the address of the PLT header. */
2458+ header_address = sec_addr (htab->elf.splt);
2459+
2460+ /* Calculate the index of the entry. */
2461+ plt_idx = (h->plt.offset - PLT_HEADER_SIZE) / PLT_ENTRY_SIZE;
2462+
2463+ /* Calculate the address of the .got.plt entry. */
2464+ got_address = riscv_elf_got_plt_val (plt_idx, info);
2465+
2466+ /* Find out where the .plt entry should go. */
2467+ loc = htab->elf.splt->contents + h->plt.offset;
2468+
2469+ /* Fill in the PLT entry itself. */
2470+ riscv_make_plt_entry (got_address, header_address + h->plt.offset,
2471+ plt_entry);
2472+ for (i = 0; i < PLT_ENTRY_INSNS; i++)
2473+ bfd_put_32 (output_bfd, plt_entry[i], loc + 4*i);
2474+
2475+ /* Fill in the initial value of the .got.plt entry. */
2476+ loc = htab->elf.sgotplt->contents
2477+ + (got_address - sec_addr (htab->elf.sgotplt));
2478+ bfd_put_NN (output_bfd, sec_addr (htab->elf.splt), loc);
2479+
2480+ /* Fill in the entry in the .rela.plt section. */
2481+ rela.r_offset = got_address;
2482+ rela.r_addend = 0;
2483+ rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_JUMP_SLOT);
2484+
2485+ loc = htab->elf.srelplt->contents + plt_idx * sizeof (ElfNN_External_Rela);
2486+ bed->s->swap_reloca_out (output_bfd, &rela, loc);
2487+
2488+ if (!h->def_regular)
2489+ {
2490+ /* Mark the symbol as undefined, rather than as defined in
2491+ the .plt section. Leave the value alone. */
2492+ sym->st_shndx = SHN_UNDEF;
2493+ /* If the symbol is weak, we do need to clear the value.
2494+ Otherwise, the PLT entry would provide a definition for
2495+ the symbol even if the symbol wasn't defined anywhere,
2496+ and so the symbol would never be NULL. */
2497+ if (!h->ref_regular_nonweak)
2498+ sym->st_value = 0;
2499+ }
2500+ }
2501+
2502+ if (h->got.offset != (bfd_vma) -1
2503+ && !(riscv_elf_hash_entry(h)->tls_type & (GOT_TLS_GD | GOT_TLS_IE)))
2504+ {
2505+ asection *sgot;
2506+ asection *srela;
2507+ Elf_Internal_Rela rela;
2508+
2509+ /* This symbol has an entry in the GOT. Set it up. */
2510+
2511+ sgot = htab->elf.sgot;
2512+ srela = htab->elf.srelgot;
2513+ BFD_ASSERT (sgot != NULL && srela != NULL);
2514+
2515+ rela.r_offset = sec_addr (sgot) + (h->got.offset &~ (bfd_vma) 1);
2516+
2517+ /* If this is a -Bsymbolic link, and the symbol is defined
2518+ locally, we just want to emit a RELATIVE reloc. Likewise if
2519+ the symbol was forced to be local because of a version file.
2520+ The entry in the global offset table will already have been
2521+ initialized in the relocate_section function. */
2522+ if (info->shared
2523+ && (info->symbolic || h->dynindx == -1)
2524+ && h->def_regular)
2525+ {
2526+ asection *sec = h->root.u.def.section;
2527+ rela.r_info = ELFNN_R_INFO (0, R_RISCV_RELATIVE);
2528+ rela.r_addend = (h->root.u.def.value
2529+ + sec->output_section->vma
2530+ + sec->output_offset);
2531+ }
2532+ else
2533+ {
2534+ BFD_ASSERT (h->dynindx != -1);
2535+ rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_NN);
2536+ rela.r_addend = 0;
2537+ }
2538+
2539+ bfd_put_NN (output_bfd, 0,
2540+ sgot->contents + (h->got.offset & ~(bfd_vma) 1));
2541+ riscv_elf_append_rela (output_bfd, srela, &rela);
2542+ }
2543+
2544+ if (h->needs_copy)
2545+ {
2546+ Elf_Internal_Rela rela;
2547+
2548+ /* This symbols needs a copy reloc. Set it up. */
2549+ BFD_ASSERT (h->dynindx != -1);
2550+
2551+ rela.r_offset = sec_addr (h->root.u.def.section) + h->root.u.def.value;
2552+ rela.r_info = ELFNN_R_INFO (h->dynindx, R_RISCV_COPY);
2553+ rela.r_addend = 0;
2554+ riscv_elf_append_rela (output_bfd, htab->srelbss, &rela);
2555+ }
2556+
2557+ /* Mark some specially defined symbols as absolute. */
2558+ if (h == htab->elf.hdynamic
2559+ || (h == htab->elf.hgot || h == htab->elf.hplt))
2560+ sym->st_shndx = SHN_ABS;
2561+
2562+ return TRUE;
2563+}
2564+
2565+/* Finish up the dynamic sections. */
2566+
2567+static bfd_boolean
2568+riscv_finish_dyn (bfd *output_bfd, struct bfd_link_info *info,
2569+ bfd *dynobj, asection *sdyn)
2570+{
2571+ struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
2572+ const struct elf_backend_data *bed = get_elf_backend_data (output_bfd);
2573+ size_t dynsize = bed->s->sizeof_dyn;
2574+ bfd_byte *dyncon, *dynconend;
2575+
2576+ dynconend = sdyn->contents + sdyn->size;
2577+ for (dyncon = sdyn->contents; dyncon < dynconend; dyncon += dynsize)
2578+ {
2579+ Elf_Internal_Dyn dyn;
2580+ asection *s;
2581+
2582+ bed->s->swap_dyn_in (dynobj, dyncon, &dyn);
2583+
2584+ switch (dyn.d_tag)
2585+ {
2586+ case DT_PLTGOT:
2587+ s = htab->elf.sgotplt;
2588+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
2589+ break;
2590+ case DT_JMPREL:
2591+ s = htab->elf.srelplt;
2592+ dyn.d_un.d_ptr = s->output_section->vma + s->output_offset;
2593+ break;
2594+ case DT_PLTRELSZ:
2595+ s = htab->elf.srelplt;
2596+ dyn.d_un.d_val = s->size;
2597+ break;
2598+ default:
2599+ continue;
2600+ }
2601+
2602+ bed->s->swap_dyn_out (output_bfd, &dyn, dyncon);
2603+ }
2604+ return TRUE;
2605+}
2606+
2607+static bfd_boolean
2608+riscv_elf_finish_dynamic_sections (bfd *output_bfd,
2609+ struct bfd_link_info *info)
2610+{
2611+ bfd *dynobj;
2612+ asection *sdyn;
2613+ struct riscv_elf_link_hash_table *htab;
2614+
2615+ htab = riscv_elf_hash_table (info);
2616+ BFD_ASSERT (htab != NULL);
2617+ dynobj = htab->elf.dynobj;
2618+
2619+ sdyn = bfd_get_linker_section (dynobj, ".dynamic");
2620+
2621+ if (elf_hash_table (info)->dynamic_sections_created)
2622+ {
2623+ asection *splt;
2624+ bfd_boolean ret;
2625+
2626+ splt = htab->elf.splt;
2627+ BFD_ASSERT (splt != NULL && sdyn != NULL);
2628+
2629+ ret = riscv_finish_dyn (output_bfd, info, dynobj, sdyn);
2630+
2631+ if (ret != TRUE)
2632+ return ret;
2633+
2634+ /* Fill in the head and tail entries in the procedure linkage table. */
2635+ if (splt->size > 0)
2636+ {
2637+ int i;
2638+ uint32_t plt_header[PLT_HEADER_INSNS];
2639+ riscv_make_plt0_entry (sec_addr (htab->elf.sgotplt),
2640+ sec_addr (splt), plt_header);
2641+
2642+ for (i = 0; i < PLT_HEADER_INSNS; i++)
2643+ bfd_put_32 (output_bfd, plt_header[i], splt->contents + 4*i);
2644+ }
2645+
2646+ elf_section_data (splt->output_section)->this_hdr.sh_entsize
2647+ = PLT_ENTRY_SIZE;
2648+ }
2649+
2650+ if (htab->elf.sgotplt)
2651+ {
2652+ if (bfd_is_abs_section (htab->elf.sgotplt->output_section))
2653+ {
2654+ (*_bfd_error_handler)
2655+ (_("discarded output section: `%A'"), htab->elf.sgotplt);
2656+ return FALSE;
2657+ }
2658+
2659+ if (htab->elf.sgotplt->size > 0)
2660+ {
2661+ /* Write the first two entries in .got.plt, needed for the dynamic
2662+ linker. */
2663+ bfd_put_NN (output_bfd, (bfd_vma) -1, htab->elf.sgotplt->contents);
2664+ bfd_put_NN (output_bfd, (bfd_vma) 0,
2665+ htab->elf.sgotplt->contents + GOT_ENTRY_SIZE);
2666+ }
2667+
2668+ elf_section_data (htab->elf.sgotplt->output_section)->this_hdr.sh_entsize =
2669+ GOT_ENTRY_SIZE;
2670+ }
2671+
2672+ if (htab->elf.sgot)
2673+ {
2674+ if (htab->elf.sgot->size > 0)
2675+ {
2676+ /* Set the first entry in the global offset table to the address of
2677+ the dynamic section. */
2678+ bfd_vma val = sdyn ? sec_addr (sdyn) : 0;
2679+ bfd_put_NN (output_bfd, val, htab->elf.sgot->contents);
2680+ }
2681+
2682+ elf_section_data (htab->elf.sgot->output_section)->this_hdr.sh_entsize =
2683+ GOT_ENTRY_SIZE;
2684+ }
2685+
2686+ return TRUE;
2687+}
2688+
2689+/* Return address for Ith PLT stub in section PLT, for relocation REL
2690+ or (bfd_vma) -1 if it should not be included. */
2691+
2692+static bfd_vma
2693+riscv_elf_plt_sym_val (bfd_vma i, const asection *plt,
2694+ const arelent *rel ATTRIBUTE_UNUSED)
2695+{
2696+ return plt->vma + PLT_HEADER_SIZE + i * PLT_ENTRY_SIZE;
2697+}
2698+
2699+static enum elf_reloc_type_class
2700+riscv_reloc_type_class (const struct bfd_link_info *info ATTRIBUTE_UNUSED,
2701+ const asection *rel_sec ATTRIBUTE_UNUSED,
2702+ const Elf_Internal_Rela *rela)
2703+{
2704+ switch (ELFNN_R_TYPE (rela->r_info))
2705+ {
2706+ case R_RISCV_RELATIVE:
2707+ return reloc_class_relative;
2708+ case R_RISCV_JUMP_SLOT:
2709+ return reloc_class_plt;
2710+ case R_RISCV_COPY:
2711+ return reloc_class_copy;
2712+ default:
2713+ return reloc_class_normal;
2714+ }
2715+}
2716+
2717+/* Return true if bfd machine EXTENSION is an extension of machine BASE. */
2718+
2719+static bfd_boolean
2720+riscv_mach_extends_p (unsigned long base, unsigned long extension)
2721+{
2722+ return extension == base;
2723+}
2724+
2725+/* Merge backend specific data from an object file to the output
2726+ object file when linking. */
2727+
2728+static bfd_boolean
2729+_bfd_riscv_elf_merge_private_bfd_data (bfd *ibfd, bfd *obfd)
2730+{
2731+ flagword old_flags;
2732+ flagword new_flags;
2733+
2734+ if (!is_riscv_elf (ibfd) || !is_riscv_elf (obfd))
2735+ return TRUE;
2736+
2737+ if (strcmp (bfd_get_target (ibfd), bfd_get_target (obfd)) != 0)
2738+ {
2739+ (*_bfd_error_handler)
2740+ (_("%B: ABI is incompatible with that of the selected emulation"),
2741+ ibfd);
2742+ return FALSE;
2743+ }
2744+
2745+ if (!_bfd_elf_merge_object_attributes (ibfd, obfd))
2746+ return FALSE;
2747+
2748+ new_flags = elf_elfheader (ibfd)->e_flags;
2749+ old_flags = elf_elfheader (obfd)->e_flags;
2750+
2751+ if (! elf_flags_init (obfd))
2752+ {
2753+ elf_flags_init (obfd) = TRUE;
2754+ elf_elfheader (obfd)->e_flags = new_flags;
2755+ elf_elfheader (obfd)->e_ident[EI_CLASS]
2756+ = elf_elfheader (ibfd)->e_ident[EI_CLASS];
2757+
2758+ if (bfd_get_arch (obfd) == bfd_get_arch (ibfd)
2759+ && (bfd_get_arch_info (obfd)->the_default
2760+ || riscv_mach_extends_p (bfd_get_mach (obfd),
2761+ bfd_get_mach (ibfd))))
2762+ {
2763+ if (! bfd_set_arch_mach (obfd, bfd_get_arch (ibfd),
2764+ bfd_get_mach (ibfd)))
2765+ return FALSE;
2766+ }
2767+
2768+ return TRUE;
2769+ }
2770+
2771+ /* Check flag compatibility. */
2772+
2773+ if (new_flags == old_flags)
2774+ return TRUE;
2775+
2776+ /* Don't link RV32 and RV64. */
2777+ if (elf_elfheader (ibfd)->e_ident[EI_CLASS]
2778+ != elf_elfheader (obfd)->e_ident[EI_CLASS])
2779+ {
2780+ (*_bfd_error_handler)
2781+ (_("%B: ELF class mismatch: can't link 32- and 64-bit modules"), ibfd);
2782+ goto fail;
2783+ }
2784+
2785+ /* Warn about any other mismatches. */
2786+ if (new_flags != old_flags)
2787+ {
2788+ if (!EF_IS_RISCV_EXT_Xcustom (new_flags) &&
2789+ !EF_IS_RISCV_EXT_Xcustom (old_flags))
2790+ {
2791+ (*_bfd_error_handler)
2792+ (_("%B: uses different e_flags (0x%lx) fields than previous modules (0x%lx)"),
2793+ ibfd, (unsigned long) new_flags,
2794+ (unsigned long) old_flags);
2795+ goto fail;
2796+ }
2797+ else if (EF_IS_RISCV_EXT_Xcustom(new_flags))
2798+ EF_SET_RISCV_EXT (elf_elfheader (obfd)->e_flags,
2799+ EF_GET_RISCV_EXT (old_flags));
2800+ }
2801+
2802+ return TRUE;
2803+
2804+fail:
2805+ bfd_set_error (bfd_error_bad_value);
2806+ return FALSE;
2807+}
2808+
2809+/* Delete some bytes from a section while relaxing. */
2810+
2811+static bfd_boolean
2812+riscv_relax_delete_bytes (bfd *abfd, asection *sec, bfd_vma addr, size_t count)
2813+{
2814+ unsigned int i, symcount;
2815+ bfd_vma toaddr = sec->size;
2816+ struct elf_link_hash_entry **sym_hashes = elf_sym_hashes (abfd);
2817+ Elf_Internal_Shdr *symtab_hdr = &elf_tdata (abfd)->symtab_hdr;
2818+ unsigned int sec_shndx = _bfd_elf_section_from_bfd_section (abfd, sec);
2819+ struct bfd_elf_section_data *data = elf_section_data (sec);
2820+ bfd_byte *contents = data->this_hdr.contents;
2821+
2822+ /* Actually delete the bytes. */
2823+ sec->size -= count;
2824+ memmove (contents + addr, contents + addr + count, toaddr - addr - count);
2825+
2826+ /* Adjust the location of all of the relocs. Note that we need not
2827+ adjust the addends, since all PC-relative references must be against
2828+ symbols, which we will adjust below. */
2829+ for (i = 0; i < sec->reloc_count; i++)
2830+ if (data->relocs[i].r_offset > addr && data->relocs[i].r_offset < toaddr)
2831+ data->relocs[i].r_offset -= count;
2832+
2833+ /* Adjust the local symbols defined in this section. */
2834+ for (i = 0; i < symtab_hdr->sh_info; i++)
2835+ {
2836+ Elf_Internal_Sym *sym = (Elf_Internal_Sym *) symtab_hdr->contents + i;
2837+ if (sym->st_shndx == sec_shndx)
2838+ {
2839+ /* If the symbol is in the range of memory we just moved, we
2840+ have to adjust its value. */
2841+ if (sym->st_value > addr && sym->st_value <= toaddr)
2842+ sym->st_value -= count;
2843+
2844+ /* If the symbol *spans* the bytes we just deleted (i.e. its
2845+ *end* is in the moved bytes but its *start* isn't), then we
2846+ must adjust its size. */
2847+ if (sym->st_value <= addr
2848+ && sym->st_value + sym->st_size > addr
2849+ && sym->st_value + sym->st_size <= toaddr)
2850+ sym->st_size -= count;
2851+ }
2852+ }
2853+
2854+ /* Now adjust the global symbols defined in this section. */
2855+ symcount = ((symtab_hdr->sh_size / sizeof(ElfNN_External_Sym))
2856+ - symtab_hdr->sh_info);
2857+
2858+ for (i = 0; i < symcount; i++)
2859+ {
2860+ struct elf_link_hash_entry *sym_hash = sym_hashes[i];
2861+
2862+ if ((sym_hash->root.type == bfd_link_hash_defined
2863+ || sym_hash->root.type == bfd_link_hash_defweak)
2864+ && sym_hash->root.u.def.section == sec)
2865+ {
2866+ /* As above, adjust the value if needed. */
2867+ if (sym_hash->root.u.def.value > addr
2868+ && sym_hash->root.u.def.value <= toaddr)
2869+ sym_hash->root.u.def.value -= count;
2870+
2871+ /* As above, adjust the size if needed. */
2872+ if (sym_hash->root.u.def.value <= addr
2873+ && sym_hash->root.u.def.value + sym_hash->size > addr
2874+ && sym_hash->root.u.def.value + sym_hash->size <= toaddr)
2875+ sym_hash->size -= count;
2876+ }
2877+ }
2878+
2879+ return TRUE;
2880+}
2881+
2882+/* Relax AUIPC + JALR into JAL. */
2883+
2884+static bfd_boolean
2885+_bfd_riscv_relax_call (bfd *abfd, asection *sec,
2886+ struct bfd_link_info *link_info,
2887+ Elf_Internal_Rela *rel,
2888+ bfd_vma symval,
2889+ bfd_boolean *again)
2890+{
2891+ bfd_byte *contents = elf_section_data (sec)->this_hdr.contents;
2892+ bfd_signed_vma foff = symval - (sec_addr (sec) + rel->r_offset);
2893+ bfd_boolean near_zero = !link_info->shared && symval < RISCV_IMM_REACH/2;
2894+ bfd_vma auipc, jalr;
2895+ int r_type;
2896+
2897+ /* See if this function call can be shortened. */
2898+ if (!VALID_UJTYPE_IMM (foff) && !near_zero)
2899+ return TRUE;
2900+
2901+ /* Shorten the function call. */
2902+ BFD_ASSERT (rel->r_offset + 8 <= sec->size);
2903+
2904+ auipc = bfd_get_32 (abfd, contents + rel->r_offset);
2905+ jalr = bfd_get_32 (abfd, contents + rel->r_offset + 4);
2906+
2907+ if (VALID_UJTYPE_IMM (foff))
2908+ {
2909+ /* Relax to JAL rd, addr. */
2910+ r_type = R_RISCV_JAL;
2911+ auipc = (jalr & (OP_MASK_RD << OP_SH_RD)) | MATCH_JAL;
2912+ }
2913+ else /* near_zero */
2914+ {
2915+ /* Relax to JALR rd, x0, addr. */
2916+ r_type = R_RISCV_LO12_I;
2917+ auipc = (jalr & (OP_MASK_RD << OP_SH_RD)) | MATCH_JALR;
2918+ }
2919+
2920+ /* Replace the R_RISCV_CALL reloc. */
2921+ rel->r_info = ELFNN_R_INFO (ELFNN_R_SYM (rel->r_info), r_type);
2922+ /* Replace the AUIPC. */
2923+ bfd_put_32 (abfd, auipc, contents + rel->r_offset);
2924+
2925+ /* Delete unnecessary JALR. */
2926+ *again = TRUE;
2927+ return riscv_relax_delete_bytes (abfd, sec, rel->r_offset + 4, 4);
2928+}
2929+
2930+/* Relax non-PIC global variable references. */
2931+
2932+static bfd_boolean
2933+_bfd_riscv_relax_lui (bfd *abfd, asection *sec,
2934+ struct bfd_link_info *link_info,
2935+ Elf_Internal_Rela *rel,
2936+ bfd_vma symval,
2937+ bfd_boolean *again)
2938+{
2939+ bfd_vma gp = riscv_global_pointer_value (link_info);
2940+
2941+ /* Bail out if this symbol isn't in range of either gp or x0. */
2942+ if (!VALID_ITYPE_IMM (symval - gp) && !(symval < RISCV_IMM_REACH/2))
2943+ return TRUE;
2944+
2945+ /* We can delete the unnecessary AUIPC. The corresponding LO12 reloc
2946+ will be converted to GPREL during relocation. */
2947+ BFD_ASSERT (rel->r_offset + 4 <= sec->size);
2948+ rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
2949+
2950+ *again = TRUE;
2951+ return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
2952+}
2953+
2954+/* Relax non-PIC TLS references. */
2955+
2956+static bfd_boolean
2957+_bfd_riscv_relax_tls_le (bfd *abfd, asection *sec,
2958+ struct bfd_link_info *link_info,
2959+ Elf_Internal_Rela *rel,
2960+ bfd_vma symval,
2961+ bfd_boolean *again)
2962+{
2963+ /* See if this symbol is in range of tp. */
2964+ if (RISCV_CONST_HIGH_PART (tpoff (link_info, symval)) != 0)
2965+ return TRUE;
2966+
2967+ /* We can delete the unnecessary LUI and tp add. The LO12 reloc will be
2968+ made directly tp-relative. */
2969+ BFD_ASSERT (rel->r_offset + 4 <= sec->size);
2970+ rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
2971+
2972+ *again = TRUE;
2973+ return riscv_relax_delete_bytes (abfd, sec, rel->r_offset, 4);
2974+}
2975+
2976+/* Implement R_RISCV_ALIGN by deleting excess alignment NOPs. */
2977+
2978+static bfd_boolean
2979+_bfd_riscv_relax_align (bfd *abfd, asection *sec,
2980+ struct bfd_link_info *link_info ATTRIBUTE_UNUSED,
2981+ Elf_Internal_Rela *rel,
2982+ bfd_vma symval,
2983+ bfd_boolean *again ATTRIBUTE_UNUSED)
2984+{
2985+ bfd_vma alignment = 1;
2986+ while (alignment <= rel->r_addend)
2987+ alignment *= 2;
2988+
2989+ symval -= rel->r_addend;
2990+ bfd_vma aligned_addr = ((symval - 1) & ~(alignment - 1)) + alignment;
2991+ bfd_vma nop_bytes_needed = aligned_addr - symval;
2992+
2993+ /* Make sure there are enough NOPs to actually achieve the alignment. */
2994+ if (rel->r_addend < nop_bytes_needed)
2995+ return FALSE;
2996+
2997+ /* Delete the reloc. */
2998+ rel->r_info = ELFNN_R_INFO (0, R_RISCV_NONE);
2999+
3000+ /* If the number of NOPs is already correct, there's nothing to do. */
3001+ if (nop_bytes_needed == rel->r_addend)
3002+ return TRUE;
3003+
3004+ /* Delete the excess NOPs. */
3005+ return riscv_relax_delete_bytes (abfd, sec, rel->r_offset,
3006+ rel->r_addend - nop_bytes_needed);
3007+}
3008+
3009+/* Relax a section. Pass 0 shortens code sequences unless disabled.
3010+ Pass 1, which cannot be disabled, handles code alignment directives. */
3011+
3012+static bfd_boolean
3013+_bfd_riscv_relax_section (bfd *abfd, asection *sec,
3014+ struct bfd_link_info *info, bfd_boolean *again)
3015+{
3016+ Elf_Internal_Shdr *symtab_hdr = &elf_symtab_hdr (abfd);
3017+ struct riscv_elf_link_hash_table *htab = riscv_elf_hash_table (info);
3018+ struct bfd_elf_section_data *data = elf_section_data (sec);
3019+ Elf_Internal_Rela *relocs;
3020+ bfd_boolean ret = FALSE;
3021+ unsigned int i;
3022+
3023+ *again = FALSE;
3024+
3025+ if (info->relocatable
3026+ || (sec->flags & SEC_RELOC) == 0
3027+ || sec->reloc_count == 0
3028+ || (info->disable_target_specific_optimizations
3029+ && info->relax_pass == 0))
3030+ return TRUE;
3031+
3032+ /* Read this BFD's relocs if we haven't done so already. */
3033+ if (data->relocs)
3034+ relocs = data->relocs;
3035+ else if (!(relocs = _bfd_elf_link_read_relocs (abfd, sec, NULL, NULL,
3036+ info->keep_memory)))
3037+ goto fail;
3038+
3039+ /* Examine and consider relaxing each reloc. */
3040+ for (i = 0; i < sec->reloc_count; i++)
3041+ {
3042+ Elf_Internal_Rela *rel = data->relocs + i;
3043+ typeof(&_bfd_riscv_relax_call) relax_func = NULL;
3044+ int type = ELFNN_R_TYPE (rel->r_info);
3045+ bfd_vma symval;
3046+
3047+ if (info->relax_pass == 0)
3048+ {
3049+ if (type == R_RISCV_CALL || type == R_RISCV_CALL_PLT)
3050+ relax_func = _bfd_riscv_relax_call;
3051+ else if (type == R_RISCV_HI20)
3052+ relax_func = _bfd_riscv_relax_lui;
3053+ else if (type == R_RISCV_TPREL_HI20 || type == R_RISCV_TPREL_ADD)
3054+ relax_func = _bfd_riscv_relax_tls_le;
3055+ }
3056+ else if (type == R_RISCV_ALIGN)
3057+ relax_func = _bfd_riscv_relax_align;
3058+
3059+ if (!relax_func)
3060+ continue;
3061+
3062+ data->relocs = relocs;
3063+
3064+ /* Read this BFD's contents if we haven't done so already. */
3065+ if (!data->this_hdr.contents
3066+ && !bfd_malloc_and_get_section (abfd, sec, &data->this_hdr.contents))
3067+ goto fail;
3068+
3069+ /* Read this BFD's symbols if we haven't done so already. */
3070+ if (symtab_hdr->sh_info != 0
3071+ && !symtab_hdr->contents
3072+ && !(symtab_hdr->contents =
3073+ (unsigned char *) bfd_elf_get_elf_syms (abfd, symtab_hdr,
3074+ symtab_hdr->sh_info,
3075+ 0, NULL, NULL, NULL)))
3076+ goto fail;
3077+
3078+ /* Get the value of the symbol referred to by the reloc. */
3079+ if (ELFNN_R_SYM (rel->r_info) < symtab_hdr->sh_info)
3080+ {
3081+ /* A local symbol. */
3082+ Elf_Internal_Sym *isym = ((Elf_Internal_Sym *) symtab_hdr->contents
3083+ + ELFNN_R_SYM (rel->r_info));
3084+
3085+ if (isym->st_shndx == SHN_UNDEF)
3086+ symval = sec_addr (sec) + rel->r_offset;
3087+ else
3088+ {
3089+ asection *isec;
3090+ BFD_ASSERT (isym->st_shndx < elf_numsections (abfd));
3091+ isec = elf_elfsections (abfd)[isym->st_shndx]->bfd_section;
3092+ if (sec_addr (isec) == 0)
3093+ continue;
3094+ symval = sec_addr (isec) + isym->st_value;
3095+ }
3096+ }
3097+ else
3098+ {
3099+ unsigned long indx;
3100+ struct elf_link_hash_entry *h;
3101+
3102+ indx = ELFNN_R_SYM (rel->r_info) - symtab_hdr->sh_info;
3103+ h = elf_sym_hashes (abfd)[indx];
3104+
3105+ while (h->root.type == bfd_link_hash_indirect
3106+ || h->root.type == bfd_link_hash_warning)
3107+ h = (struct elf_link_hash_entry *) h->root.u.i.link;
3108+
3109+ if (h->plt.offset != MINUS_ONE)
3110+ symval = sec_addr (htab->elf.splt) + h->plt.offset;
3111+ else if (h->root.type == bfd_link_hash_undefweak)
3112+ symval = 0;
3113+ else if (h->root.u.def.section->output_section == NULL
3114+ || (h->root.type != bfd_link_hash_defined
3115+ && h->root.type != bfd_link_hash_defweak))
3116+ continue;
3117+ else
3118+ symval = sec_addr (h->root.u.def.section) + h->root.u.def.value;
3119+ }
3120+
3121+ symval += rel->r_addend;
3122+
3123+ if (!relax_func (abfd, sec, info, rel, symval, again))
3124+ goto fail;
3125+ }
3126+
3127+ ret = TRUE;
3128+
3129+fail:
3130+ if (relocs != data->relocs)
3131+ free (relocs);
3132+
3133+ return ret;
3134+}
3135+
3136+#define ELF_ARCH bfd_arch_riscv
3137+#define ELF_TARGET_ID RISCV_ELF_DATA
3138+#define ELF_MACHINE_CODE EM_RISCV
3139+#define ELF_MAXPAGESIZE 0x2000
3140+#define ELF_COMMONPAGESIZE 0x2000
3141+
3142+#define TARGET_LITTLE_SYM riscv_elfNN_vec
3143+#define TARGET_LITTLE_NAME "elfNN-littleriscv"
3144+
3145+#define elf_backend_reloc_type_class riscv_reloc_type_class
3146+
3147+#define bfd_elfNN_bfd_reloc_name_lookup riscv_reloc_name_lookup
3148+#define bfd_elfNN_bfd_link_hash_table_create riscv_elf_link_hash_table_create
3149+#define bfd_elfNN_bfd_reloc_type_lookup riscv_reloc_type_lookup
3150+#define bfd_elfNN_bfd_merge_private_bfd_data \
3151+ _bfd_riscv_elf_merge_private_bfd_data
3152+
3153+#define elf_backend_copy_indirect_symbol riscv_elf_copy_indirect_symbol
3154+#define elf_backend_create_dynamic_sections riscv_elf_create_dynamic_sections
3155+#define elf_backend_check_relocs riscv_elf_check_relocs
3156+#define elf_backend_adjust_dynamic_symbol riscv_elf_adjust_dynamic_symbol
3157+#define elf_backend_size_dynamic_sections riscv_elf_size_dynamic_sections
3158+#define elf_backend_relocate_section riscv_elf_relocate_section
3159+#define elf_backend_finish_dynamic_symbol riscv_elf_finish_dynamic_symbol
3160+#define elf_backend_finish_dynamic_sections riscv_elf_finish_dynamic_sections
3161+#define elf_backend_gc_mark_hook riscv_elf_gc_mark_hook
3162+#define elf_backend_gc_sweep_hook riscv_elf_gc_sweep_hook
3163+#define elf_backend_plt_sym_val riscv_elf_plt_sym_val
3164+#define elf_info_to_howto_rel NULL
3165+#define elf_info_to_howto riscv_info_to_howto_rela
3166+#define bfd_elfNN_bfd_relax_section _bfd_riscv_relax_section
3167+
3168+#define elf_backend_init_index_section _bfd_elf_init_1_index_section
3169+
3170+#define elf_backend_can_gc_sections 1
3171+#define elf_backend_can_refcount 1
3172+#define elf_backend_want_got_plt 1
3173+#define elf_backend_plt_readonly 1
3174+#define elf_backend_plt_alignment 4
3175+#define elf_backend_want_plt_sym 1
3176+#define elf_backend_got_header_size (ARCH_SIZE / 8)
3177+#define elf_backend_rela_normal 1
3178+#define elf_backend_default_execstack 0
3179+
3180+#include "elfNN-target.h"
3181diff -urN original-binutils/bfd/elfxx-riscv.c binutils/bfd/elfxx-riscv.c
3182--- original-binutils/bfd/elfxx-riscv.c 1970-01-01 01:00:00.000000000 +0100
3183+++ binutils-2.25/bfd/elfxx-riscv.c 2015-03-07 09:51:45.659139025 +0100
3184@@ -0,0 +1,730 @@
3185+/* RISC-V-specific support for ELF.
3186+ Copyright 2011-2014 Free Software Foundation, Inc.
3187+
3188+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
3189+ Based on TILE-Gx and MIPS targets.
3190+
3191+ This file is part of BFD, the Binary File Descriptor library.
3192+
3193+ This program is free software; you can redistribute it and/or modify
3194+ it under the terms of the GNU General Public License as published by
3195+ the Free Software Foundation; either version 3 of the License, or
3196+ (at your option) any later version.
3197+
3198+ This program is distributed in the hope that it will be useful,
3199+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3200+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3201+ GNU General Public License for more details.
3202+
3203+ You should have received a copy of the GNU General Public License
3204+ along with this program; if not, write to the Free Software
3205+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
3206+ MA 02110-1301, USA. */
3207+
3208+#include "sysdep.h"
3209+#include "bfd.h"
3210+#include "libbfd.h"
3211+#include "elf-bfd.h"
3212+#include "elf/riscv.h"
3213+#include "opcode/riscv.h"
3214+#include "libiberty.h"
3215+#include "elfxx-riscv.h"
3216+#include <stdint.h>
3217+
3218+#define MINUS_ONE ((bfd_vma)0 - 1)
3219+
3220+/* The relocation table used for SHT_RELA sections. */
3221+
3222+static reloc_howto_type howto_table[] =
3223+{
3224+ /* No relocation. */
3225+ HOWTO (R_RISCV_NONE, /* type */
3226+ 0, /* rightshift */
3227+ 0, /* size (0 = byte, 1 = short, 2 = long) */
3228+ 0, /* bitsize */
3229+ FALSE, /* pc_relative */
3230+ 0, /* bitpos */
3231+ complain_overflow_dont, /* complain_on_overflow */
3232+ bfd_elf_generic_reloc, /* special_function */
3233+ "R_RISCV_NONE", /* name */
3234+ FALSE, /* partial_inplace */
3235+ 0, /* src_mask */
3236+ 0, /* dst_mask */
3237+ FALSE), /* pcrel_offset */
3238+
3239+ /* 32 bit relocation. */
3240+ HOWTO (R_RISCV_32, /* type */
3241+ 0, /* rightshift */
3242+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3243+ 32, /* bitsize */
3244+ FALSE, /* pc_relative */
3245+ 0, /* bitpos */
3246+ complain_overflow_dont, /* complain_on_overflow */
3247+ bfd_elf_generic_reloc, /* special_function */
3248+ "R_RISCV_32", /* name */
3249+ FALSE, /* partial_inplace */
3250+ 0, /* src_mask */
3251+ 0xffffffff, /* dst_mask */
3252+ FALSE), /* pcrel_offset */
3253+
3254+ /* 64 bit relocation. */
3255+ HOWTO (R_RISCV_64, /* type */
3256+ 0, /* rightshift */
3257+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3258+ 64, /* bitsize */
3259+ FALSE, /* pc_relative */
3260+ 0, /* bitpos */
3261+ complain_overflow_dont, /* complain_on_overflow */
3262+ bfd_elf_generic_reloc, /* special_function */
3263+ "R_RISCV_64", /* name */
3264+ FALSE, /* partial_inplace */
3265+ 0, /* src_mask */
3266+ MINUS_ONE, /* dst_mask */
3267+ FALSE), /* pcrel_offset */
3268+
3269+ /* Relocation against a local symbol in a shared object. */
3270+ HOWTO (R_RISCV_RELATIVE, /* type */
3271+ 0, /* rightshift */
3272+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3273+ 32, /* bitsize */
3274+ FALSE, /* pc_relative */
3275+ 0, /* bitpos */
3276+ complain_overflow_dont, /* complain_on_overflow */
3277+ bfd_elf_generic_reloc, /* special_function */
3278+ "R_RISCV_RELATIVE", /* name */
3279+ FALSE, /* partial_inplace */
3280+ 0, /* src_mask */
3281+ 0xffffffff, /* dst_mask */
3282+ FALSE), /* pcrel_offset */
3283+
3284+ HOWTO (R_RISCV_COPY, /* type */
3285+ 0, /* rightshift */
3286+ 0, /* this one is variable size */
3287+ 0, /* bitsize */
3288+ FALSE, /* pc_relative */
3289+ 0, /* bitpos */
3290+ complain_overflow_bitfield, /* complain_on_overflow */
3291+ bfd_elf_generic_reloc, /* special_function */
3292+ "R_RISCV_COPY", /* name */
3293+ FALSE, /* partial_inplace */
3294+ 0x0, /* src_mask */
3295+ 0x0, /* dst_mask */
3296+ FALSE), /* pcrel_offset */
3297+
3298+ HOWTO (R_RISCV_JUMP_SLOT, /* type */
3299+ 0, /* rightshift */
3300+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3301+ 64, /* bitsize */
3302+ FALSE, /* pc_relative */
3303+ 0, /* bitpos */
3304+ complain_overflow_bitfield, /* complain_on_overflow */
3305+ bfd_elf_generic_reloc, /* special_function */
3306+ "R_RISCV_JUMP_SLOT", /* name */
3307+ FALSE, /* partial_inplace */
3308+ 0x0, /* src_mask */
3309+ 0x0, /* dst_mask */
3310+ FALSE), /* pcrel_offset */
3311+
3312+ /* Dynamic TLS relocations. */
3313+ HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
3314+ 0, /* rightshift */
3315+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3316+ 32, /* bitsize */
3317+ FALSE, /* pc_relative */
3318+ 0, /* bitpos */
3319+ complain_overflow_dont, /* complain_on_overflow */
3320+ bfd_elf_generic_reloc, /* special_function */
3321+ "R_RISCV_TLS_DTPMOD32", /* name */
3322+ FALSE, /* partial_inplace */
3323+ MINUS_ONE, /* src_mask */
3324+ MINUS_ONE, /* dst_mask */
3325+ FALSE), /* pcrel_offset */
3326+
3327+ HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
3328+ 0, /* rightshift */
3329+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3330+ 64, /* bitsize */
3331+ FALSE, /* pc_relative */
3332+ 0, /* bitpos */
3333+ complain_overflow_dont, /* complain_on_overflow */
3334+ bfd_elf_generic_reloc, /* special_function */
3335+ "R_RISCV_TLS_DTPMOD64", /* name */
3336+ FALSE, /* partial_inplace */
3337+ MINUS_ONE, /* src_mask */
3338+ MINUS_ONE, /* dst_mask */
3339+ FALSE), /* pcrel_offset */
3340+
3341+ HOWTO (R_RISCV_TLS_DTPREL32, /* type */
3342+ 0, /* rightshift */
3343+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3344+ 32, /* bitsize */
3345+ FALSE, /* pc_relative */
3346+ 0, /* bitpos */
3347+ complain_overflow_dont, /* complain_on_overflow */
3348+ bfd_elf_generic_reloc, /* special_function */
3349+ "R_RISCV_TLS_DTPREL32", /* name */
3350+ TRUE, /* partial_inplace */
3351+ MINUS_ONE, /* src_mask */
3352+ MINUS_ONE, /* dst_mask */
3353+ FALSE), /* pcrel_offset */
3354+
3355+ HOWTO (R_RISCV_TLS_DTPREL64, /* type */
3356+ 0, /* rightshift */
3357+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3358+ 64, /* bitsize */
3359+ FALSE, /* pc_relative */
3360+ 0, /* bitpos */
3361+ complain_overflow_dont, /* complain_on_overflow */
3362+ bfd_elf_generic_reloc, /* special_function */
3363+ "R_RISCV_TLS_DTPREL64", /* name */
3364+ TRUE, /* partial_inplace */
3365+ MINUS_ONE, /* src_mask */
3366+ MINUS_ONE, /* dst_mask */
3367+ FALSE), /* pcrel_offset */
3368+
3369+ HOWTO (R_RISCV_TLS_TPREL32, /* type */
3370+ 0, /* rightshift */
3371+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3372+ 32, /* bitsize */
3373+ FALSE, /* pc_relative */
3374+ 0, /* bitpos */
3375+ complain_overflow_dont, /* complain_on_overflow */
3376+ bfd_elf_generic_reloc, /* special_function */
3377+ "R_RISCV_TLS_TPREL32", /* name */
3378+ FALSE, /* partial_inplace */
3379+ MINUS_ONE, /* src_mask */
3380+ MINUS_ONE, /* dst_mask */
3381+ FALSE), /* pcrel_offset */
3382+
3383+ HOWTO (R_RISCV_TLS_TPREL64, /* type */
3384+ 0, /* rightshift */
3385+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3386+ 64, /* bitsize */
3387+ FALSE, /* pc_relative */
3388+ 0, /* bitpos */
3389+ complain_overflow_dont, /* complain_on_overflow */
3390+ bfd_elf_generic_reloc, /* special_function */
3391+ "R_RISCV_TLS_TPREL64", /* name */
3392+ FALSE, /* partial_inplace */
3393+ MINUS_ONE, /* src_mask */
3394+ MINUS_ONE, /* dst_mask */
3395+ FALSE), /* pcrel_offset */
3396+
3397+ EMPTY_HOWTO (12),
3398+ EMPTY_HOWTO (13),
3399+ EMPTY_HOWTO (14),
3400+ EMPTY_HOWTO (15),
3401+
3402+ /* 12-bit PC-relative branch offset. */
3403+ HOWTO (R_RISCV_BRANCH, /* type */
3404+ 0, /* rightshift */
3405+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3406+ 32, /* bitsize */
3407+ TRUE, /* pc_relative */
3408+ 0, /* bitpos */
3409+ complain_overflow_signed, /* complain_on_overflow */
3410+ bfd_elf_generic_reloc, /* special_function */
3411+ "R_RISCV_BRANCH", /* name */
3412+ FALSE, /* partial_inplace */
3413+ 0, /* src_mask */
3414+ ENCODE_SBTYPE_IMM(-1U),/* dst_mask */
3415+ TRUE), /* pcrel_offset */
3416+
3417+ /* 20-bit PC-relative jump offset. */
3418+ HOWTO (R_RISCV_JAL, /* type */
3419+ 0, /* rightshift */
3420+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3421+ 32, /* bitsize */
3422+ TRUE, /* pc_relative */
3423+ 0, /* bitpos */
3424+ complain_overflow_dont, /* complain_on_overflow */
3425+ /* This needs complex overflow
3426+ detection, because the upper 36
3427+ bits must match the PC + 4. */
3428+ bfd_elf_generic_reloc, /* special_function */
3429+ "R_RISCV_JAL", /* name */
3430+ FALSE, /* partial_inplace */
3431+ 0, /* src_mask */
3432+ ENCODE_UJTYPE_IMM(-1U), /* dst_mask */
3433+ TRUE), /* pcrel_offset */
3434+
3435+ /* 32-bit PC-relative function call (AUIPC/JALR). */
3436+ HOWTO (R_RISCV_CALL, /* type */
3437+ 0, /* rightshift */
3438+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3439+ 64, /* bitsize */
3440+ TRUE, /* pc_relative */
3441+ 0, /* bitpos */
3442+ complain_overflow_dont, /* complain_on_overflow */
3443+ bfd_elf_generic_reloc, /* special_function */
3444+ "R_RISCV_CALL", /* name */
3445+ FALSE, /* partial_inplace */
3446+ 0, /* src_mask */
3447+ ENCODE_UTYPE_IMM(-1U) | ((bfd_vma) ENCODE_ITYPE_IMM(-1U) << 32), /* dst_mask */
3448+ TRUE), /* pcrel_offset */
3449+
3450+ /* 32-bit PC-relative function call (AUIPC/JALR). */
3451+ HOWTO (R_RISCV_CALL_PLT, /* type */
3452+ 0, /* rightshift */
3453+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3454+ 64, /* bitsize */
3455+ TRUE, /* pc_relative */
3456+ 0, /* bitpos */
3457+ complain_overflow_dont, /* complain_on_overflow */
3458+ bfd_elf_generic_reloc, /* special_function */
3459+ "R_RISCV_CALL_PLT", /* name */
3460+ FALSE, /* partial_inplace */
3461+ 0, /* src_mask */
3462+ ENCODE_UTYPE_IMM(-1U) | ((bfd_vma) ENCODE_ITYPE_IMM(-1U) << 32), /* dst_mask */
3463+ TRUE), /* pcrel_offset */
3464+
3465+ /* High 20 bits of 32-bit PC-relative GOT access. */
3466+ HOWTO (R_RISCV_GOT_HI20, /* type */
3467+ 0, /* rightshift */
3468+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3469+ 32, /* bitsize */
3470+ TRUE, /* pc_relative */
3471+ 0, /* bitpos */
3472+ complain_overflow_dont, /* complain_on_overflow */
3473+ bfd_elf_generic_reloc, /* special_function */
3474+ "R_RISCV_GOT_HI20", /* name */
3475+ FALSE, /* partial_inplace */
3476+ 0, /* src_mask */
3477+ ENCODE_UTYPE_IMM(-1U), /* dst_mask */
3478+ FALSE), /* pcrel_offset */
3479+
3480+ /* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
3481+ HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
3482+ 0, /* rightshift */
3483+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3484+ 32, /* bitsize */
3485+ TRUE, /* pc_relative */
3486+ 0, /* bitpos */
3487+ complain_overflow_dont, /* complain_on_overflow */
3488+ bfd_elf_generic_reloc, /* special_function */
3489+ "R_RISCV_TLS_GOT_HI20", /* name */
3490+ FALSE, /* partial_inplace */
3491+ 0, /* src_mask */
3492+ ENCODE_UTYPE_IMM(-1U), /* dst_mask */
3493+ FALSE), /* pcrel_offset */
3494+
3495+ /* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
3496+ HOWTO (R_RISCV_TLS_GD_HI20, /* type */
3497+ 0, /* rightshift */
3498+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3499+ 32, /* bitsize */
3500+ TRUE, /* pc_relative */
3501+ 0, /* bitpos */
3502+ complain_overflow_dont, /* complain_on_overflow */
3503+ bfd_elf_generic_reloc, /* special_function */
3504+ "R_RISCV_TLS_GD_HI20", /* name */
3505+ FALSE, /* partial_inplace */
3506+ 0, /* src_mask */
3507+ ENCODE_UTYPE_IMM(-1U), /* dst_mask */
3508+ FALSE), /* pcrel_offset */
3509+
3510+ /* High 20 bits of 32-bit PC-relative reference. */
3511+ HOWTO (R_RISCV_PCREL_HI20, /* type */
3512+ 0, /* rightshift */
3513+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3514+ 32, /* bitsize */
3515+ TRUE, /* pc_relative */
3516+ 0, /* bitpos */
3517+ complain_overflow_dont, /* complain_on_overflow */
3518+ bfd_elf_generic_reloc, /* special_function */
3519+ "R_RISCV_PCREL_HI20", /* name */
3520+ FALSE, /* partial_inplace */
3521+ 0, /* src_mask */
3522+ ENCODE_UTYPE_IMM(-1U), /* dst_mask */
3523+ TRUE), /* pcrel_offset */
3524+
3525+ /* Low 12 bits of a 32-bit PC-relative load or add. */
3526+ HOWTO (R_RISCV_PCREL_LO12_I, /* type */
3527+ 0, /* rightshift */
3528+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3529+ 32, /* bitsize */
3530+ FALSE, /* pc_relative */
3531+ 0, /* bitpos */
3532+ complain_overflow_dont, /* complain_on_overflow */
3533+ bfd_elf_generic_reloc, /* special_function */
3534+ "R_RISCV_PCREL_LO12_I",/* name */
3535+ FALSE, /* partial_inplace */
3536+ 0, /* src_mask */
3537+ ENCODE_ITYPE_IMM(-1U), /* dst_mask */
3538+ FALSE), /* pcrel_offset */
3539+
3540+ /* Low 12 bits of a 32-bit PC-relative store. */
3541+ HOWTO (R_RISCV_PCREL_LO12_S, /* type */
3542+ 0, /* rightshift */
3543+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3544+ 32, /* bitsize */
3545+ FALSE, /* pc_relative */
3546+ 0, /* bitpos */
3547+ complain_overflow_dont, /* complain_on_overflow */
3548+ bfd_elf_generic_reloc, /* special_function */
3549+ "R_RISCV_PCREL_LO12_S",/* name */
3550+ FALSE, /* partial_inplace */
3551+ 0, /* src_mask */
3552+ ENCODE_STYPE_IMM(-1U), /* dst_mask */
3553+ FALSE), /* pcrel_offset */
3554+
3555+ /* High 20 bits of 32-bit absolute address. */
3556+ HOWTO (R_RISCV_HI20, /* type */
3557+ 0, /* rightshift */
3558+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3559+ 32, /* bitsize */
3560+ FALSE, /* pc_relative */
3561+ 0, /* bitpos */
3562+ complain_overflow_dont, /* complain_on_overflow */
3563+ bfd_elf_generic_reloc, /* special_function */
3564+ "R_RISCV_HI20", /* name */
3565+ FALSE, /* partial_inplace */
3566+ 0, /* src_mask */
3567+ ENCODE_UTYPE_IMM(-1U), /* dst_mask */
3568+ FALSE), /* pcrel_offset */
3569+
3570+ /* High 12 bits of 32-bit load or add. */
3571+ HOWTO (R_RISCV_LO12_I, /* type */
3572+ 0, /* rightshift */
3573+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3574+ 32, /* bitsize */
3575+ FALSE, /* pc_relative */
3576+ 0, /* bitpos */
3577+ complain_overflow_dont, /* complain_on_overflow */
3578+ bfd_elf_generic_reloc, /* special_function */
3579+ "R_RISCV_LO12_I", /* name */
3580+ FALSE, /* partial_inplace */
3581+ 0, /* src_mask */
3582+ ENCODE_ITYPE_IMM(-1U), /* dst_mask */
3583+ FALSE), /* pcrel_offset */
3584+
3585+ /* High 12 bits of 32-bit store. */
3586+ HOWTO (R_RISCV_LO12_S, /* type */
3587+ 0, /* rightshift */
3588+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3589+ 32, /* bitsize */
3590+ FALSE, /* pc_relative */
3591+ 0, /* bitpos */
3592+ complain_overflow_dont, /* complain_on_overflow */
3593+ bfd_elf_generic_reloc, /* special_function */
3594+ "R_RISCV_LO12_S", /* name */
3595+ FALSE, /* partial_inplace */
3596+ 0, /* src_mask */
3597+ ENCODE_STYPE_IMM(-1U), /* dst_mask */
3598+ FALSE), /* pcrel_offset */
3599+
3600+ /* High 20 bits of TLS LE thread pointer offset. */
3601+ HOWTO (R_RISCV_TPREL_HI20, /* type */
3602+ 0, /* rightshift */
3603+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3604+ 32, /* bitsize */
3605+ FALSE, /* pc_relative */
3606+ 0, /* bitpos */
3607+ complain_overflow_signed, /* complain_on_overflow */
3608+ bfd_elf_generic_reloc, /* special_function */
3609+ "R_RISCV_TPREL_HI20", /* name */
3610+ TRUE, /* partial_inplace */
3611+ 0, /* src_mask */
3612+ ENCODE_UTYPE_IMM(-1U), /* dst_mask */
3613+ FALSE), /* pcrel_offset */
3614+
3615+ /* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
3616+ HOWTO (R_RISCV_TPREL_LO12_I, /* type */
3617+ 0, /* rightshift */
3618+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3619+ 32, /* bitsize */
3620+ FALSE, /* pc_relative */
3621+ 0, /* bitpos */
3622+ complain_overflow_signed, /* complain_on_overflow */
3623+ bfd_elf_generic_reloc, /* special_function */
3624+ "R_RISCV_TPREL_LO12_I",/* name */
3625+ FALSE, /* partial_inplace */
3626+ 0, /* src_mask */
3627+ ENCODE_ITYPE_IMM(-1U), /* dst_mask */
3628+ FALSE), /* pcrel_offset */
3629+
3630+ /* Low 12 bits of TLS LE thread pointer offset for stores. */
3631+ HOWTO (R_RISCV_TPREL_LO12_S, /* type */
3632+ 0, /* rightshift */
3633+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3634+ 32, /* bitsize */
3635+ FALSE, /* pc_relative */
3636+ 0, /* bitpos */
3637+ complain_overflow_signed, /* complain_on_overflow */
3638+ bfd_elf_generic_reloc, /* special_function */
3639+ "R_RISCV_TPREL_LO12_S",/* name */
3640+ FALSE, /* partial_inplace */
3641+ 0, /* src_mask */
3642+ ENCODE_STYPE_IMM(-1U), /* dst_mask */
3643+ FALSE), /* pcrel_offset */
3644+
3645+ /* TLS LE thread pointer usage. */
3646+ HOWTO (R_RISCV_TPREL_ADD, /* type */
3647+ 0, /* rightshift */
3648+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3649+ 32, /* bitsize */
3650+ FALSE, /* pc_relative */
3651+ 0, /* bitpos */
3652+ complain_overflow_dont,/* complain_on_overflow */
3653+ bfd_elf_generic_reloc, /* special_function */
3654+ "R_RISCV_TPREL_ADD", /* name */
3655+ TRUE, /* partial_inplace */
3656+ 0, /* src_mask */
3657+ 0, /* dst_mask */
3658+ FALSE), /* pcrel_offset */
3659+
3660+ /* 8-bit in-place addition, for local label subtraction. */
3661+ HOWTO (R_RISCV_ADD8, /* type */
3662+ 0, /* rightshift */
3663+ 0, /* size (0 = byte, 1 = short, 2 = long) */
3664+ 32, /* bitsize */
3665+ FALSE, /* pc_relative */
3666+ 0, /* bitpos */
3667+ complain_overflow_dont, /* complain_on_overflow */
3668+ bfd_elf_generic_reloc, /* special_function */
3669+ "R_RISCV_ADD8", /* name */
3670+ FALSE, /* partial_inplace */
3671+ 0, /* src_mask */
3672+ MINUS_ONE, /* dst_mask */
3673+ FALSE), /* pcrel_offset */
3674+
3675+ /* 16-bit in-place addition, for local label subtraction. */
3676+ HOWTO (R_RISCV_ADD16, /* type */
3677+ 0, /* rightshift */
3678+ 1, /* size (0 = byte, 1 = short, 2 = long) */
3679+ 16, /* bitsize */
3680+ FALSE, /* pc_relative */
3681+ 0, /* bitpos */
3682+ complain_overflow_dont, /* complain_on_overflow */
3683+ bfd_elf_generic_reloc, /* special_function */
3684+ "R_RISCV_ADD16", /* name */
3685+ FALSE, /* partial_inplace */
3686+ 0, /* src_mask */
3687+ MINUS_ONE, /* dst_mask */
3688+ FALSE), /* pcrel_offset */
3689+
3690+ /* 32-bit in-place addition, for local label subtraction. */
3691+ HOWTO (R_RISCV_ADD32, /* type */
3692+ 0, /* rightshift */
3693+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3694+ 32, /* bitsize */
3695+ FALSE, /* pc_relative */
3696+ 0, /* bitpos */
3697+ complain_overflow_dont, /* complain_on_overflow */
3698+ bfd_elf_generic_reloc, /* special_function */
3699+ "R_RISCV_ADD32", /* name */
3700+ FALSE, /* partial_inplace */
3701+ 0, /* src_mask */
3702+ MINUS_ONE, /* dst_mask */
3703+ FALSE), /* pcrel_offset */
3704+
3705+ /* 64-bit in-place addition, for local label subtraction. */
3706+ HOWTO (R_RISCV_ADD64, /* type */
3707+ 0, /* rightshift */
3708+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3709+ 64, /* bitsize */
3710+ FALSE, /* pc_relative */
3711+ 0, /* bitpos */
3712+ complain_overflow_dont, /* complain_on_overflow */
3713+ bfd_elf_generic_reloc, /* special_function */
3714+ "R_RISCV_ADD64", /* name */
3715+ FALSE, /* partial_inplace */
3716+ 0, /* src_mask */
3717+ MINUS_ONE, /* dst_mask */
3718+ FALSE), /* pcrel_offset */
3719+
3720+ /* 8-bit in-place addition, for local label subtraction. */
3721+ HOWTO (R_RISCV_SUB8, /* type */
3722+ 0, /* rightshift */
3723+ 0, /* size (0 = byte, 1 = short, 2 = long) */
3724+ 8, /* bitsize */
3725+ FALSE, /* pc_relative */
3726+ 0, /* bitpos */
3727+ complain_overflow_dont, /* complain_on_overflow */
3728+ bfd_elf_generic_reloc, /* special_function */
3729+ "R_RISCV_SUB8", /* name */
3730+ FALSE, /* partial_inplace */
3731+ 0, /* src_mask */
3732+ MINUS_ONE, /* dst_mask */
3733+ FALSE), /* pcrel_offset */
3734+
3735+ /* 16-bit in-place addition, for local label subtraction. */
3736+ HOWTO (R_RISCV_SUB16, /* type */
3737+ 0, /* rightshift */
3738+ 1, /* size (0 = byte, 1 = short, 2 = long) */
3739+ 16, /* bitsize */
3740+ FALSE, /* pc_relative */
3741+ 0, /* bitpos */
3742+ complain_overflow_dont, /* complain_on_overflow */
3743+ bfd_elf_generic_reloc, /* special_function */
3744+ "R_RISCV_SUB16", /* name */
3745+ FALSE, /* partial_inplace */
3746+ 0, /* src_mask */
3747+ MINUS_ONE, /* dst_mask */
3748+ FALSE), /* pcrel_offset */
3749+
3750+ /* 32-bit in-place addition, for local label subtraction. */
3751+ HOWTO (R_RISCV_SUB32, /* type */
3752+ 0, /* rightshift */
3753+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3754+ 32, /* bitsize */
3755+ FALSE, /* pc_relative */
3756+ 0, /* bitpos */
3757+ complain_overflow_dont, /* complain_on_overflow */
3758+ bfd_elf_generic_reloc, /* special_function */
3759+ "R_RISCV_SUB32", /* name */
3760+ FALSE, /* partial_inplace */
3761+ 0, /* src_mask */
3762+ MINUS_ONE, /* dst_mask */
3763+ FALSE), /* pcrel_offset */
3764+
3765+ /* 64-bit in-place addition, for local label subtraction. */
3766+ HOWTO (R_RISCV_SUB64, /* type */
3767+ 0, /* rightshift */
3768+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3769+ 64, /* bitsize */
3770+ FALSE, /* pc_relative */
3771+ 0, /* bitpos */
3772+ complain_overflow_dont, /* complain_on_overflow */
3773+ bfd_elf_generic_reloc, /* special_function */
3774+ "R_RISCV_SUB64", /* name */
3775+ FALSE, /* partial_inplace */
3776+ 0, /* src_mask */
3777+ MINUS_ONE, /* dst_mask */
3778+ FALSE), /* pcrel_offset */
3779+
3780+ /* GNU extension to record C++ vtable hierarchy */
3781+ HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
3782+ 0, /* rightshift */
3783+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3784+ 0, /* bitsize */
3785+ FALSE, /* pc_relative */
3786+ 0, /* bitpos */
3787+ complain_overflow_dont,/* complain_on_overflow */
3788+ NULL, /* special_function */
3789+ "R_RISCV_GNU_VTINHERIT", /* name */
3790+ FALSE, /* partial_inplace */
3791+ 0, /* src_mask */
3792+ 0, /* dst_mask */
3793+ FALSE), /* pcrel_offset */
3794+
3795+ /* GNU extension to record C++ vtable member usage */
3796+ HOWTO (R_RISCV_GNU_VTENTRY, /* type */
3797+ 0, /* rightshift */
3798+ 4, /* size (0 = byte, 1 = short, 2 = long) */
3799+ 0, /* bitsize */
3800+ FALSE, /* pc_relative */
3801+ 0, /* bitpos */
3802+ complain_overflow_dont,/* complain_on_overflow */
3803+ _bfd_elf_rel_vtable_reloc_fn, /* special_function */
3804+ "R_RISCV_GNU_VTENTRY", /* name */
3805+ FALSE, /* partial_inplace */
3806+ 0, /* src_mask */
3807+ 0, /* dst_mask */
3808+ FALSE), /* pcrel_offset */
3809+
3810+ /* Indicates an alignment statement. The addend field encodes how many
3811+ bytes of NOPs follow the statement. The desired alignment is the
3812+ addend rounded up to the next power of two. */
3813+ HOWTO (R_RISCV_ALIGN, /* type */
3814+ 0, /* rightshift */
3815+ 2, /* size (0 = byte, 1 = short, 2 = long) */
3816+ 0, /* bitsize */
3817+ FALSE, /* pc_relative */
3818+ 0, /* bitpos */
3819+ complain_overflow_dont, /* complain_on_overflow */
3820+ bfd_elf_generic_reloc, /* special_function */
3821+ "R_RISCV_ALIGN", /* name */
3822+ FALSE, /* partial_inplace */
3823+ 0, /* src_mask */
3824+ 0, /* dst_mask */
3825+ TRUE), /* pcrel_offset */
3826+};
3827+
3828+/* A mapping from BFD reloc types to RISC-V ELF reloc types. */
3829+
3830+struct elf_reloc_map {
3831+ bfd_reloc_code_real_type bfd_val;
3832+ enum elf_riscv_reloc_type elf_val;
3833+};
3834+
3835+static const struct elf_reloc_map riscv_reloc_map[] =
3836+{
3837+ { BFD_RELOC_NONE, R_RISCV_NONE },
3838+ { BFD_RELOC_32, R_RISCV_32 },
3839+ { BFD_RELOC_64, R_RISCV_64 },
3840+ { BFD_RELOC_RISCV_ADD8, R_RISCV_ADD8 },
3841+ { BFD_RELOC_RISCV_ADD16, R_RISCV_ADD16 },
3842+ { BFD_RELOC_RISCV_ADD32, R_RISCV_ADD32 },
3843+ { BFD_RELOC_RISCV_ADD64, R_RISCV_ADD64 },
3844+ { BFD_RELOC_RISCV_SUB8, R_RISCV_SUB8 },
3845+ { BFD_RELOC_RISCV_SUB16, R_RISCV_SUB16 },
3846+ { BFD_RELOC_RISCV_SUB32, R_RISCV_SUB32 },
3847+ { BFD_RELOC_RISCV_SUB64, R_RISCV_SUB64 },
3848+ { BFD_RELOC_CTOR, R_RISCV_64 },
3849+ { BFD_RELOC_12_PCREL, R_RISCV_BRANCH },
3850+ { BFD_RELOC_RISCV_HI20, R_RISCV_HI20 },
3851+ { BFD_RELOC_RISCV_LO12_I, R_RISCV_LO12_I },
3852+ { BFD_RELOC_RISCV_LO12_S, R_RISCV_LO12_S },
3853+ { BFD_RELOC_RISCV_PCREL_LO12_I, R_RISCV_PCREL_LO12_I },
3854+ { BFD_RELOC_RISCV_PCREL_LO12_S, R_RISCV_PCREL_LO12_S },
3855+ { BFD_RELOC_RISCV_CALL, R_RISCV_CALL },
3856+ { BFD_RELOC_RISCV_CALL_PLT, R_RISCV_CALL_PLT },
3857+ { BFD_RELOC_RISCV_PCREL_HI20, R_RISCV_PCREL_HI20 },
3858+ { BFD_RELOC_RISCV_JMP, R_RISCV_JAL },
3859+ { BFD_RELOC_RISCV_GOT_HI20, R_RISCV_GOT_HI20 },
3860+ { BFD_RELOC_RISCV_TLS_DTPMOD32, R_RISCV_TLS_DTPMOD32 },
3861+ { BFD_RELOC_RISCV_TLS_DTPREL32, R_RISCV_TLS_DTPREL32 },
3862+ { BFD_RELOC_RISCV_TLS_DTPMOD64, R_RISCV_TLS_DTPMOD64 },
3863+ { BFD_RELOC_RISCV_TLS_DTPREL64, R_RISCV_TLS_DTPREL64 },
3864+ { BFD_RELOC_RISCV_TLS_TPREL32, R_RISCV_TLS_TPREL32 },
3865+ { BFD_RELOC_RISCV_TLS_TPREL64, R_RISCV_TLS_TPREL64 },
3866+ { BFD_RELOC_RISCV_TPREL_HI20, R_RISCV_TPREL_HI20 },
3867+ { BFD_RELOC_RISCV_TPREL_ADD, R_RISCV_TPREL_ADD },
3868+ { BFD_RELOC_RISCV_TPREL_LO12_S, R_RISCV_TPREL_LO12_S },
3869+ { BFD_RELOC_RISCV_TPREL_LO12_I, R_RISCV_TPREL_LO12_I },
3870+ { BFD_RELOC_RISCV_TLS_GOT_HI20, R_RISCV_TLS_GOT_HI20 },
3871+ { BFD_RELOC_RISCV_TLS_GD_HI20, R_RISCV_TLS_GD_HI20 },
3872+ { BFD_RELOC_RISCV_ALIGN, R_RISCV_ALIGN },
3873+};
3874+
3875+/* Given a BFD reloc type, return a howto structure. */
3876+
3877+reloc_howto_type *
3878+riscv_reloc_type_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3879+ bfd_reloc_code_real_type code)
3880+{
3881+ unsigned int i;
3882+
3883+ for (i = 0; i < ARRAY_SIZE (riscv_reloc_map); i++)
3884+ if (riscv_reloc_map[i].bfd_val == code)
3885+ return &howto_table[(int) riscv_reloc_map[i].elf_val];
3886+
3887+ bfd_set_error (bfd_error_bad_value);
3888+ return NULL;
3889+}
3890+
3891+reloc_howto_type *
3892+riscv_reloc_name_lookup (bfd *abfd ATTRIBUTE_UNUSED,
3893+ const char *r_name)
3894+{
3895+ unsigned int i;
3896+
3897+ for (i = 0; i < ARRAY_SIZE (howto_table); i++)
3898+ if (howto_table[i].name && strcasecmp (howto_table[i].name, r_name) == 0)
3899+ return &howto_table[i];
3900+
3901+ return NULL;
3902+}
3903+
3904+reloc_howto_type *
3905+riscv_elf_rtype_to_howto (unsigned int r_type)
3906+{
3907+ if ((unsigned int)r_type >= ARRAY_SIZE (howto_table))
3908+ {
3909+ (*_bfd_error_handler)(_("unrecognized relocation (0x%x)"), r_type);
3910+ bfd_set_error (bfd_error_bad_value);
3911+ return NULL;
3912+ }
3913+ return &howto_table[r_type];
3914+}
3915diff -urN original-binutils/bfd/elfxx-riscv.h binutils/bfd/elfxx-riscv.h
3916--- original-binutils/bfd/elfxx-riscv.h 1970-01-01 01:00:00.000000000 +0100
3917+++ binutils-2.25/bfd/elfxx-riscv.h 2015-03-07 09:51:45.659139025 +0100
3918@@ -0,0 +1,34 @@
3919+/* RISC-V ELF specific backend routines.
3920+ Copyright 2011-2014 Free Software Foundation, Inc.
3921+
3922+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
3923+ Based on MIPS target.
3924+
3925+ This file is part of BFD, the Binary File Descriptor library.
3926+
3927+ This program is free software; you can redistribute it and/or modify
3928+ it under the terms of the GNU General Public License as published by
3929+ the Free Software Foundation; either version 3 of the License, or
3930+ (at your option) any later version.
3931+
3932+ This program is distributed in the hope that it will be useful,
3933+ but WITHOUT ANY WARRANTY; without even the implied warranty of
3934+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
3935+ GNU General Public License for more details.
3936+
3937+ You should have received a copy of the GNU General Public License
3938+ along with this program; if not, write to the Free Software
3939+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
3940+ MA 02110-1301, USA. */
3941+
3942+#include "elf/common.h"
3943+#include "elf/internal.h"
3944+
3945+extern reloc_howto_type *
3946+riscv_reloc_name_lookup (bfd *, const char *);
3947+
3948+extern reloc_howto_type *
3949+riscv_reloc_type_lookup (bfd *, bfd_reloc_code_real_type);
3950+
3951+extern reloc_howto_type *
3952+riscv_elf_rtype_to_howto (unsigned int r_type);
3953diff -urN original-binutils/bfd/Makefile.am binutils/bfd/Makefile.am
3954--- original-binutils/bfd/Makefile.am 2014-10-14 09:32:02.000000000 +0200
3955+++ binutils-2.25/bfd/Makefile.am 2015-03-07 09:55:02.371135671 +0100
3956@@ -931,6 +931,18 @@
3957 sed -e s/NN/64/g < $(srcdir)/elfnn-ia64.c > elf64-ia64.new
3958 mv -f elf64-ia64.new elf64-ia64.c
3959
3960+elf32-riscv.c : elfnn-riscv.c
3961+ rm -f elf32-riscv.c
3962+ echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf32-riscv.new
3963+ sed -e s/NN/32/g < $(srcdir)/elfnn-riscv.c >> elf32-riscv.new
3964+ mv -f elf32-riscv.new elf32-riscv.c
3965+
3966+elf64-riscv.c : elfnn-riscv.c
3967+ rm -f elf64-riscv.c
3968+ echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf64-riscv.new
3969+ sed -e s/NN/64/g < $(srcdir)/elfnn-riscv.c >> elf64-riscv.new
3970+ mv -f elf64-riscv.new elf64-riscv.c
3971+
3972 peigen.c : peXXigen.c
3973 rm -f peigen.c
3974 sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new
3975diff -urN original-binutils/bfd/Makefile.in binutils/bfd/Makefile.in
3976--- original-binutils/bfd/Makefile.in 2014-10-14 09:32:02.000000000 +0200
3977+++ binutils-2.25/bfd/Makefile.in 2015-03-07 09:55:02.371135671 +0100
3978@@ -2009,6 +2009,18 @@
3979 sed -e s/NN/64/g < $(srcdir)/elfnn-ia64.c > elf64-ia64.new
3980 mv -f elf64-ia64.new elf64-ia64.c
3981
3982+elf32-riscv.c : elfnn-riscv.c
3983+ rm -f elf32-riscv.c
3984+ echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf32-riscv.new
3985+ sed -e s/NN/32/g < $(srcdir)/elfnn-riscv.c >> elf32-riscv.new
3986+ mv -f elf32-riscv.new elf32-riscv.c
3987+
3988+elf64-riscv.c : elfnn-riscv.c
3989+ rm -f elf64-riscv.c
3990+ echo "#line 1 \"$(srcdir)/elfnn-riscv.c\"" > elf64-riscv.new
3991+ sed -e s/NN/64/g < $(srcdir)/elfnn-riscv.c >> elf64-riscv.new
3992+ mv -f elf64-riscv.new elf64-riscv.c
3993+
3994 peigen.c : peXXigen.c
3995 rm -f peigen.c
3996 sed -e s/XX/pe/g < $(srcdir)/peXXigen.c > peigen.new
3997diff -urN original-binutils/bfd/targets.c binutils/bfd/targets.c
3998--- original-binutils/bfd/targets.c 2014-11-04 10:54:41.000000000 +0100
3999+++ binutils-2.25/bfd/targets.c 2015-03-07 09:55:02.371135671 +0100
4000@@ -784,6 +784,8 @@
4001 extern const bfd_target powerpc_pei_vec;
4002 extern const bfd_target powerpc_pei_le_vec;
4003 extern const bfd_target powerpc_xcoff_vec;
4004+extern const bfd_target riscv_elf32_vec;
4005+extern const bfd_target riscv_elf64_vec;
4006 extern const bfd_target rl78_elf32_vec;
4007 extern const bfd_target rs6000_xcoff64_vec;
4008 extern const bfd_target rs6000_xcoff64_aix_vec;
4009diff -urN original-binutils/binutils/readelf.c binutils/binutils/readelf.c
4010--- original-binutils/binutils/readelf.c 2014-12-23 09:47:10.000000000 +0100
4011+++ binutils-2.25/binutils/readelf.c 2015-03-07 09:55:02.375135671 +0100
4012@@ -125,6 +125,7 @@
4013 #include "elf/metag.h"
4014 #include "elf/microblaze.h"
4015 #include "elf/mips.h"
4016+#include "elf/riscv.h"
4017 #include "elf/mmix.h"
4018 #include "elf/mn10200.h"
4019 #include "elf/mn10300.h"
4020@@ -720,6 +721,7 @@
4021 case EM_OR1K:
4022 case EM_PPC64:
4023 case EM_PPC:
4024+ case EM_RISCV:
4025 case EM_RL78:
4026 case EM_RX:
4027 case EM_S390:
4028@@ -1252,6 +1254,10 @@
4029 rtype = elf_mips_reloc_type (type);
4030 break;
4031
4032+ case EM_RISCV:
4033+ rtype = elf_riscv_reloc_type (type);
4034+ break;
4035+
4036 case EM_ALPHA:
4037 rtype = elf_alpha_reloc_type (type);
4038 break;
4039@@ -2164,6 +2170,7 @@
4040 case EM_CR16:
4041 case EM_MICROBLAZE:
4042 case EM_MICROBLAZE_OLD: return "Xilinx MicroBlaze";
4043+ case EM_RISCV: return "RISC-V";
4044 case EM_RL78: return "Renesas RL78";
4045 case EM_RX: return "Renesas RX";
4046 case EM_METAG: return "Imagination Technologies Meta processor architecture";
4047@@ -2951,6 +2958,14 @@
4048 decode_NDS32_machine_flags (e_flags, buf, sizeof buf);
4049 break;
4050
4051+ case EM_RISCV:
4052+ {
4053+ unsigned int riscv_extension = EF_GET_RISCV_EXT(e_flags);
4054+ strcat (buf, ", ");
4055+ strcat (buf, riscv_elf_flag_to_name (riscv_extension));
4056+ }
4057+ break;
4058+
4059 case EM_SH:
4060 switch ((e_flags & EF_SH_MACH_MASK))
4061 {
4062@@ -10789,6 +10804,8 @@
4063 return reloc_type == 1; /* R_PPC64_ADDR32. */
4064 case EM_PPC:
4065 return reloc_type == 1; /* R_PPC_ADDR32. */
4066+ case EM_RISCV:
4067+ return reloc_type == 1; /* R_RISCV_32. */
4068 case EM_RL78:
4069 return reloc_type == 1; /* R_RL78_DIR32. */
4070 case EM_RX:
4071@@ -10924,6 +10941,8 @@
4072 return reloc_type == 80; /* R_PARISC_DIR64. */
4073 case EM_PPC64:
4074 return reloc_type == 38; /* R_PPC64_ADDR64. */
4075+ case EM_RISCV:
4076+ return reloc_type == 2; /* R_RISCV_64. */
4077 case EM_SPARC32PLUS:
4078 case EM_SPARCV9:
4079 case EM_SPARC:
4080@@ -11072,6 +11091,7 @@
4081 case EM_ADAPTEVA_EPIPHANY:
4082 case EM_PPC: /* R_PPC_NONE. */
4083 case EM_PPC64: /* R_PPC64_NONE. */
4084+ case EM_RISCV: /* R_RISCV_NONE. */
4085 case EM_ARM: /* R_ARM_NONE. */
4086 case EM_IA_64: /* R_IA64_NONE. */
4087 case EM_SH: /* R_SH_NONE. */
4088diff -urN original-binutils/config.sub binutils/config.sub
4089--- original-binutils/config.sub 2014-10-14 09:32:02.000000000 +0200
4090+++ binutils-2.25/config.sub 2015-03-07 09:55:02.375135671 +0100
4091@@ -335,6 +335,9 @@
4092 ms1)
4093 basic_machine=mt-unknown
4094 ;;
4095+ riscv)
4096+ basic_machine=riscv-ucb
4097+ ;;
4098
4099 strongarm | thumb | xscale)
4100 basic_machine=arm-unknown
4101diff -urN original-binutils/gas/config/tc-riscv.c binutils/gas/config/tc-riscv.c
4102--- original-binutils/gas/config/tc-riscv.c 1970-01-01 01:00:00.000000000 +0100
4103+++ binutils-2.25/gas/config/tc-riscv.c 2015-03-07 09:51:45.659139025 +0100
4104@@ -0,0 +1,2225 @@
4105+/* tc-riscv.c -- RISC-V assembler
4106+ Copyright 2011-2014 Free Software Foundation, Inc.
4107+
4108+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
4109+ Based on MIPS target.
4110+
4111+ This file is part of GAS.
4112+
4113+ GAS is free software; you can redistribute it and/or modify
4114+ it under the terms of the GNU General Public License as published by
4115+ the Free Software Foundation; either version 3, or (at your option)
4116+ any later version.
4117+
4118+ GAS is distributed in the hope that it will be useful,
4119+ but WITHOUT ANY WARRANTY; without even the implied warranty of
4120+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
4121+ GNU General Public License for more details.
4122+
4123+ You should have received a copy of the GNU General Public License
4124+ along with GAS; see the file COPYING. If not, write to the Free
4125+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
4126+ 02110-1301, USA. */
4127+
4128+#include "as.h"
4129+#include "config.h"
4130+#include "subsegs.h"
4131+#include "safe-ctype.h"
4132+
4133+#include "itbl-ops.h"
4134+#include "dwarf2dbg.h"
4135+#include "dw2gencfi.h"
4136+
4137+#include "elf/riscv.h"
4138+#include "opcode/riscv.h"
4139+
4140+#include <execinfo.h>
4141+#include <stdint.h>
4142+
4143+/* Information about an instruction, including its format, operands
4144+ and fixups. */
4145+struct riscv_cl_insn
4146+{
4147+ /* The opcode's entry in riscv_opcodes. */
4148+ const struct riscv_opcode *insn_mo;
4149+
4150+ /* The encoded instruction bits. */
4151+ insn_t insn_opcode;
4152+
4153+ /* The frag that contains the instruction. */
4154+ struct frag *frag;
4155+
4156+ /* The offset into FRAG of the first instruction byte. */
4157+ long where;
4158+
4159+ /* The relocs associated with the instruction, if any. */
4160+ fixS *fixp;
4161+};
4162+
4163+bfd_boolean rv64 = TRUE; /* RV64 (true) or RV32 (false) */
4164+#define LOAD_ADDRESS_INSN (rv64 ? "ld" : "lw")
4165+#define ADD32_INSN (rv64 ? "addiw" : "addi")
4166+
4167+struct riscv_subset
4168+{
4169+ const char* name;
4170+ int version_major;
4171+ int version_minor;
4172+
4173+ struct riscv_subset* next;
4174+};
4175+
4176+static struct riscv_subset* riscv_subsets;
4177+
4178+static int
4179+riscv_subset_supports(const char* feature)
4180+{
4181+ struct riscv_subset* s;
4182+ bfd_boolean rv64_insn;
4183+
4184+ if ((rv64_insn = !strncmp(feature, "64", 2)) || !strncmp(feature, "32", 2))
4185+ {
4186+ if (rv64 != rv64_insn)
4187+ return 0;
4188+ feature += 2;
4189+ }
4190+
4191+ for (s = riscv_subsets; s != NULL; s = s->next)
4192+ if (strcmp(s->name, feature) == 0)
4193+ /* FIXME: once we support version numbers:
4194+ return major == s->version_major && minor <= s->version_minor; */
4195+ return 1;
4196+
4197+ return 0;
4198+}
4199+
4200+static void
4201+riscv_add_subset(const char* subset)
4202+{
4203+ struct riscv_subset* s = xmalloc(sizeof(struct riscv_subset));
4204+ s->name = xstrdup(subset);
4205+ s->version_major = 1;
4206+ s->version_minor = 0;
4207+ s->next = riscv_subsets;
4208+ riscv_subsets = s;
4209+}
4210+
4211+static void
4212+riscv_set_arch(const char* arg)
4213+{
4214+ /* Formally, ISA subset names begin with RV, RV32, or RV64, but we allow the
4215+ prefix to be omitted. We also allow all-lowercase names if version
4216+ numbers and eXtensions are omitted (i.e. only some combination of imafd
4217+ is supported in this case).
4218+
4219+ FIXME: Version numbers are not supported yet. */
4220+ const char* subsets = "IMAFD";
4221+ const char* p;
4222+
4223+ for (p = arg; *p; p++)
4224+ if (!ISLOWER(*p) || strchr(subsets, TOUPPER(*p)) == NULL)
4225+ break;
4226+
4227+ if (!*p)
4228+ {
4229+ /* Legal all-lowercase name. */
4230+ for (p = arg; *p; p++)
4231+ {
4232+ char subset[2] = {TOUPPER(*p), 0};
4233+ riscv_add_subset(subset);
4234+ }
4235+ return;
4236+ }
4237+
4238+ if (strncmp(arg, "RV32", 4) == 0)
4239+ {
4240+ rv64 = FALSE;
4241+ arg += 4;
4242+ }
4243+ else if (strncmp(arg, "RV64", 4) == 0)
4244+ {
4245+ rv64 = TRUE;
4246+ arg += 4;
4247+ }
4248+ else if (strncmp(arg, "RV", 2) == 0)
4249+ arg += 2;
4250+
4251+ if (*arg && *arg != 'I')
4252+ as_fatal("`I' must be the first ISA subset name specified (got %c)", *arg);
4253+
4254+ for (p = arg; *p; p++)
4255+ {
4256+ if (*p == 'X')
4257+ {
4258+ const char* q = p+1;
4259+ while (ISLOWER(*q))
4260+ q++;
4261+
4262+ char subset[q-p+1];
4263+ memcpy(subset, p, q-p);
4264+ subset[q-p] = 0;
4265+
4266+ riscv_add_subset(subset);
4267+ p = q-1;
4268+ }
4269+ else if (strchr(subsets, *p) != NULL)
4270+ {
4271+ char subset[2] = {*p, 0};
4272+ riscv_add_subset(subset);
4273+ }
4274+ else
4275+ as_fatal("unsupported ISA subset %c", *p);
4276+ }
4277+}
4278+
4279+/* This is the set of options which may be modified by the .set
4280+ pseudo-op. We use a struct so that .set push and .set pop are more
4281+ reliable. */
4282+
4283+struct riscv_set_options
4284+{
4285+ /* Generate position-independent code. */
4286+ int pic;
4287+ /* Generate RVC code. */
4288+ int rvc;
4289+};
4290+
4291+static struct riscv_set_options riscv_opts =
4292+{
4293+ 0, /* pic */
4294+ 0, /* rvc */
4295+};
4296+
4297+/* handle of the OPCODE hash table */
4298+static struct hash_control *op_hash = NULL;
4299+
4300+/* This array holds the chars that always start a comment. If the
4301+ pre-processor is disabled, these aren't very useful */
4302+const char comment_chars[] = "#";
4303+
4304+/* This array holds the chars that only start a comment at the beginning of
4305+ a line. If the line seems to have the form '# 123 filename'
4306+ .line and .file directives will appear in the pre-processed output */
4307+/* Note that input_file.c hand checks for '#' at the beginning of the
4308+ first line of the input file. This is because the compiler outputs
4309+ #NO_APP at the beginning of its output. */
4310+/* Also note that C style comments are always supported. */
4311+const char line_comment_chars[] = "#";
4312+
4313+/* This array holds machine specific line separator characters. */
4314+const char line_separator_chars[] = ";";
4315+
4316+/* Chars that can be used to separate mant from exp in floating point nums */
4317+const char EXP_CHARS[] = "eE";
4318+
4319+/* Chars that mean this number is a floating point constant */
4320+/* As in 0f12.456 */
4321+/* or 0d1.2345e12 */
4322+const char FLT_CHARS[] = "rRsSfFdDxXpP";
4323+
4324+/* Also be aware that MAXIMUM_NUMBER_OF_CHARS_FOR_FLOAT may have to be
4325+ changed in read.c . Ideally it shouldn't have to know about it at all,
4326+ but nothing is ideal around here.
4327+ */
4328+
4329+static char *insn_error;
4330+
4331+#define RELAX_BRANCH_ENCODE(uncond, toofar) \
4332+ ((relax_substateT) \
4333+ (0xc0000000 \
4334+ | ((toofar) ? 1 : 0) \
4335+ | ((uncond) ? 2 : 0)))
4336+#define RELAX_BRANCH_P(i) (((i) & 0xf0000000) == 0xc0000000)
4337+#define RELAX_BRANCH_TOOFAR(i) (((i) & 1) != 0)
4338+#define RELAX_BRANCH_UNCOND(i) (((i) & 2) != 0)
4339+
4340+/* Is the given value a sign-extended 32-bit value? */
4341+#define IS_SEXT_32BIT_NUM(x) \
4342+ (((x) &~ (offsetT) 0x7fffffff) == 0 \
4343+ || (((x) &~ (offsetT) 0x7fffffff) == ~ (offsetT) 0x7fffffff))
4344+
4345+#define IS_SEXT_NBIT_NUM(x,n) \
4346+ ({ int64_t __tmp = (x); \
4347+ __tmp = (__tmp << (64-(n))) >> (64-(n)); \
4348+ __tmp == (x); })
4349+
4350+/* Is the given value a zero-extended 32-bit value? Or a negated one? */
4351+#define IS_ZEXT_32BIT_NUM(x) \
4352+ (((x) &~ (offsetT) 0xffffffff) == 0 \
4353+ || (((x) &~ (offsetT) 0xffffffff) == ~ (offsetT) 0xffffffff))
4354+
4355+/* Replace bits MASK << SHIFT of STRUCT with the equivalent bits in
4356+ VALUE << SHIFT. VALUE is evaluated exactly once. */
4357+#define INSERT_BITS(STRUCT, VALUE, MASK, SHIFT) \
4358+ (STRUCT) = (((STRUCT) & ~((insn_t)(MASK) << (SHIFT))) \
4359+ | ((insn_t)((VALUE) & (MASK)) << (SHIFT)))
4360+
4361+/* Extract bits MASK << SHIFT from STRUCT and shift them right
4362+ SHIFT places. */
4363+#define EXTRACT_BITS(STRUCT, MASK, SHIFT) \
4364+ (((STRUCT) >> (SHIFT)) & (MASK))
4365+
4366+/* Change INSN's opcode so that the operand given by FIELD has value VALUE.
4367+ INSN is a riscv_cl_insn structure and VALUE is evaluated exactly once. */
4368+#define INSERT_OPERAND(FIELD, INSN, VALUE) \
4369+ INSERT_BITS ((INSN).insn_opcode, VALUE, OP_MASK_##FIELD, OP_SH_##FIELD)
4370+
4371+/* Extract the operand given by FIELD from riscv_cl_insn INSN. */
4372+#define EXTRACT_OPERAND(FIELD, INSN) \
4373+ EXTRACT_BITS ((INSN).insn_opcode, OP_MASK_##FIELD, OP_SH_##FIELD)
4374+
4375+/* Determine if an instruction matches an opcode. */
4376+#define OPCODE_MATCHES(OPCODE, OP) \
4377+ (((OPCODE) & MASK_##OP) == MATCH_##OP)
4378+
4379+#define INSN_MATCHES(INSN, OP) \
4380+ (((INSN).insn_opcode & MASK_##OP) == MATCH_##OP)
4381+
4382+/* Prototypes for static functions. */
4383+
4384+#define internalError() \
4385+ as_fatal (_("internal Error, line %d, %s"), __LINE__, __FILE__)
4386+
4387+static char *expr_end;
4388+
4389+/* Expressions which appear in instructions. These are set by
4390+ riscv_ip. */
4391+
4392+static expressionS imm_expr;
4393+static expressionS offset_expr;
4394+
4395+/* Relocs associated with imm_expr and offset_expr. */
4396+
4397+static bfd_reloc_code_real_type imm_reloc = BFD_RELOC_UNUSED;
4398+static bfd_reloc_code_real_type offset_reloc = BFD_RELOC_UNUSED;
4399+
4400+/* The default target format to use. */
4401+
4402+const char *
4403+riscv_target_format (void)
4404+{
4405+ return rv64 ? "elf64-littleriscv" : "elf32-littleriscv";
4406+}
4407+
4408+/* Return the length of instruction INSN. */
4409+
4410+static inline unsigned int
4411+insn_length (const struct riscv_cl_insn *insn)
4412+{
4413+ return riscv_insn_length (insn->insn_opcode);
4414+}
4415+
4416+/* Initialise INSN from opcode entry MO. Leave its position unspecified. */
4417+
4418+static void
4419+create_insn (struct riscv_cl_insn *insn, const struct riscv_opcode *mo)
4420+{
4421+ insn->insn_mo = mo;
4422+ insn->insn_opcode = mo->match;
4423+ insn->frag = NULL;
4424+ insn->where = 0;
4425+ insn->fixp = NULL;
4426+}
4427+
4428+/* Install INSN at the location specified by its "frag" and "where" fields. */
4429+
4430+static void
4431+install_insn (const struct riscv_cl_insn *insn)
4432+{
4433+ char *f = insn->frag->fr_literal + insn->where;
4434+ md_number_to_chars (f, insn->insn_opcode, insn_length(insn));
4435+}
4436+
4437+/* Move INSN to offset WHERE in FRAG. Adjust the fixups accordingly
4438+ and install the opcode in the new location. */
4439+
4440+static void
4441+move_insn (struct riscv_cl_insn *insn, fragS *frag, long where)
4442+{
4443+ insn->frag = frag;
4444+ insn->where = where;
4445+ if (insn->fixp != NULL)
4446+ {
4447+ insn->fixp->fx_frag = frag;
4448+ insn->fixp->fx_where = where;
4449+ }
4450+ install_insn (insn);
4451+}
4452+
4453+/* Add INSN to the end of the output. */
4454+
4455+static void
4456+add_fixed_insn (struct riscv_cl_insn *insn)
4457+{
4458+ char *f = frag_more (insn_length (insn));
4459+ move_insn (insn, frag_now, f - frag_now->fr_literal);
4460+}
4461+
4462+static void
4463+add_relaxed_insn (struct riscv_cl_insn *insn, int max_chars, int var,
4464+ relax_substateT subtype, symbolS *symbol, offsetT offset)
4465+{
4466+ frag_grow (max_chars);
4467+ move_insn (insn, frag_now, frag_more (0) - frag_now->fr_literal);
4468+ frag_var (rs_machine_dependent, max_chars, var,
4469+ subtype, symbol, offset, NULL);
4470+}
4471+
4472+/* Compute the length of a branch sequence, and adjust the
4473+ RELAX_BRANCH_TOOFAR bit accordingly. If FRAGP is NULL, the
4474+ worst-case length is computed. */
4475+static int
4476+relaxed_branch_length (fragS *fragp, asection *sec, int update)
4477+{
4478+ bfd_boolean toofar = TRUE;
4479+
4480+ if (fragp)
4481+ {
4482+ bfd_boolean uncond = RELAX_BRANCH_UNCOND (fragp->fr_subtype);
4483+
4484+ if (S_IS_DEFINED (fragp->fr_symbol)
4485+ && sec == S_GET_SEGMENT (fragp->fr_symbol))
4486+ {
4487+ offsetT val = S_GET_VALUE (fragp->fr_symbol) + fragp->fr_offset;
4488+ bfd_vma range;
4489+ val -= fragp->fr_address + fragp->fr_fix;
4490+
4491+ if (uncond)
4492+ range = RISCV_JUMP_REACH;
4493+ else
4494+ range = RISCV_BRANCH_REACH;
4495+ toofar = (bfd_vma)(val + range/2) >= range;
4496+ }
4497+
4498+ if (update && toofar != RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
4499+ fragp->fr_subtype = RELAX_BRANCH_ENCODE (uncond, toofar);
4500+ }
4501+
4502+ return toofar ? 8 : 4;
4503+}
4504+
4505+struct regname {
4506+ const char *name;
4507+ unsigned int num;
4508+};
4509+
4510+enum reg_class {
4511+ RCLASS_GPR,
4512+ RCLASS_FPR,
4513+ RCLASS_CSR,
4514+ RCLASS_VEC_GPR,
4515+ RCLASS_VEC_FPR,
4516+ RCLASS_MAX
4517+};
4518+
4519+static struct hash_control *reg_names_hash = NULL;
4520+
4521+#define ENCODE_REG_HASH(cls, n) (void*)(uintptr_t)((n)*RCLASS_MAX + (cls) + 1)
4522+#define DECODE_REG_CLASS(hash) (((uintptr_t)(hash) - 1) % RCLASS_MAX)
4523+#define DECODE_REG_NUM(hash) (((uintptr_t)(hash) - 1) / RCLASS_MAX)
4524+
4525+static void
4526+hash_reg_name (enum reg_class class, const char *name, unsigned n)
4527+{
4528+ void *hash = ENCODE_REG_HASH (class, n);
4529+ const char *retval = hash_insert (reg_names_hash, name, hash);
4530+ if (retval != NULL)
4531+ as_fatal (_("internal error: can't hash `%s': %s"), name, retval);
4532+}
4533+
4534+static void
4535+hash_reg_names (enum reg_class class, const char * const names[], unsigned n)
4536+{
4537+ unsigned i;
4538+ for (i = 0; i < n; i++)
4539+ hash_reg_name (class, names[i], i);
4540+}
4541+
4542+static unsigned int
4543+reg_lookup_internal (const char *s, enum reg_class class)
4544+{
4545+ struct regname *r = (struct regname *) hash_find (reg_names_hash, s);
4546+ if (r == NULL || DECODE_REG_CLASS (r) != class)
4547+ return -1;
4548+ return DECODE_REG_NUM (r);
4549+}
4550+
4551+static int
4552+reg_lookup (char **s, enum reg_class class, unsigned int *regnop)
4553+{
4554+ char *e;
4555+ char save_c;
4556+ int reg = -1;
4557+
4558+ /* Find end of name. */
4559+ e = *s;
4560+ if (is_name_beginner (*e))
4561+ ++e;
4562+ while (is_part_of_name (*e))
4563+ ++e;
4564+
4565+ /* Terminate name. */
4566+ save_c = *e;
4567+ *e = '\0';
4568+
4569+ /* Look for the register. Advance to next token if one was recognized. */
4570+ if ((reg = reg_lookup_internal (*s, class)) >= 0)
4571+ *s = e;
4572+
4573+ *e = save_c;
4574+ if (regnop)
4575+ *regnop = reg;
4576+ return reg >= 0;
4577+}
4578+
4579+static int
4580+arg_lookup(char **s, const char* const* array, size_t size, unsigned *regnop)
4581+{
4582+ const char *p = strchr(*s, ',');
4583+ size_t i, len = p ? (size_t)(p - *s) : strlen(*s);
4584+
4585+ for (i = 0; i < size; i++)
4586+ if (array[i] != NULL && strncmp(array[i], *s, len) == 0)
4587+ {
4588+ *regnop = i;
4589+ *s += len;
4590+ return 1;
4591+ }
4592+
4593+ return 0;
4594+}
4595+
4596+/* For consistency checking, verify that all bits are specified either
4597+ by the match/mask part of the instruction definition, or by the
4598+ operand list. */
4599+static int
4600+validate_riscv_insn (const struct riscv_opcode *opc)
4601+{
4602+ const char *p = opc->args;
4603+ char c;
4604+ insn_t required_bits, used_bits = opc->mask;
4605+
4606+ if ((used_bits & opc->match) != opc->match)
4607+ {
4608+ as_bad (_("internal: bad RISC-V opcode (mask error): %s %s"),
4609+ opc->name, opc->args);
4610+ return 0;
4611+ }
4612+ required_bits = ((insn_t)1 << (8 * riscv_insn_length (opc->match))) - 1;
4613+ /* Work around for undefined behavior of uint64_t << 64 */
4614+ if(riscv_insn_length (opc->match) == 8)
4615+ required_bits = 0xffffffffffffffff;
4616+
4617+#define USE_BITS(mask,shift) (used_bits |= ((insn_t)(mask) << (shift)))
4618+ while (*p)
4619+ switch (c = *p++)
4620+ {
4621+ /* Xcustom */
4622+ case '^':
4623+ switch (c = *p++)
4624+ {
4625+ case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
4626+ case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
4627+ case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
4628+ case 'j': USE_BITS (OP_MASK_CUSTOM_IMM, OP_SH_CUSTOM_IMM); break;
4629+ }
4630+ break;
4631+ /* Xhwacha */
4632+ case '#':
4633+ switch (c = *p++)
4634+ {
4635+ case 'g': USE_BITS (OP_MASK_IMMNGPR, OP_SH_IMMNGPR); break;
4636+ case 'f': USE_BITS (OP_MASK_IMMNFPR, OP_SH_IMMNFPR); break;
4637+ case 'n': USE_BITS (OP_MASK_IMMSEGNELM, OP_SH_IMMSEGNELM); break;
4638+ case 'd': USE_BITS (OP_MASK_VRD, OP_SH_VRD); break;
4639+ case 's': USE_BITS (OP_MASK_VRS, OP_SH_VRS); break;
4640+ case 't': USE_BITS (OP_MASK_VRT, OP_SH_VRT); break;
4641+ case 'r': USE_BITS (OP_MASK_VRR, OP_SH_VRR); break;
4642+ case 'D': USE_BITS (OP_MASK_VFD, OP_SH_VFD); break;
4643+ case 'S': USE_BITS (OP_MASK_VFS, OP_SH_VFS); break;
4644+ case 'T': USE_BITS (OP_MASK_VFT, OP_SH_VFT); break;
4645+ case 'R': USE_BITS (OP_MASK_VFR, OP_SH_VFR); break;
4646+
4647+ default:
4648+ as_bad (_("internal: bad RISC-V opcode (unknown extension operand type `#%c'): %s %s"),
4649+ c, opc->name, opc->args);
4650+ return 0;
4651+ }
4652+ break;
4653+ case ',': break;
4654+ case '(': break;
4655+ case ')': break;
4656+ case '<': USE_BITS (OP_MASK_SHAMTW, OP_SH_SHAMTW); break;
4657+ case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break;
4658+ case 'A': break;
4659+ case 'D': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
4660+ case 'Z': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
4661+ case 'E': USE_BITS (OP_MASK_CSR, OP_SH_CSR); break;
4662+ case 'I': break;
4663+ case 'R': USE_BITS (OP_MASK_RS3, OP_SH_RS3); break;
4664+ case 'S': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
4665+ case 'U': USE_BITS (OP_MASK_RS1, OP_SH_RS1); /* fallthru */
4666+ case 'T': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
4667+ case 'd': USE_BITS (OP_MASK_RD, OP_SH_RD); break;
4668+ case 'm': USE_BITS (OP_MASK_RM, OP_SH_RM); break;
4669+ case 's': USE_BITS (OP_MASK_RS1, OP_SH_RS1); break;
4670+ case 't': USE_BITS (OP_MASK_RS2, OP_SH_RS2); break;
4671+ case 'P': USE_BITS (OP_MASK_PRED, OP_SH_PRED); break;
4672+ case 'Q': USE_BITS (OP_MASK_SUCC, OP_SH_SUCC); break;
4673+ case 'o':
4674+ case 'j': used_bits |= ENCODE_ITYPE_IMM(-1U); break;
4675+ case 'a': used_bits |= ENCODE_UJTYPE_IMM(-1U); break;
4676+ case 'p': used_bits |= ENCODE_SBTYPE_IMM(-1U); break;
4677+ case 'q': used_bits |= ENCODE_STYPE_IMM(-1U); break;
4678+ case 'u': used_bits |= ENCODE_UTYPE_IMM(-1U); break;
4679+ case '[': break;
4680+ case ']': break;
4681+ case '0': break;
4682+ default:
4683+ as_bad (_("internal: bad RISC-V opcode (unknown operand type `%c'): %s %s"),
4684+ c, opc->name, opc->args);
4685+ return 0;
4686+ }
4687+#undef USE_BITS
4688+ if (used_bits != required_bits)
4689+ {
4690+ as_bad (_("internal: bad RISC-V opcode (bits 0x%lx undefined): %s %s"),
4691+ ~(long)(used_bits & required_bits), opc->name, opc->args);
4692+ return 0;
4693+ }
4694+ return 1;
4695+}
4696+
4697+struct percent_op_match
4698+{
4699+ const char *str;
4700+ bfd_reloc_code_real_type reloc;
4701+};
4702+
4703+/* This function is called once, at assembler startup time. It should set up
4704+ all the tables, etc. that the MD part of the assembler will need. */
4705+
4706+void
4707+md_begin (void)
4708+{
4709+ const char *retval = NULL;
4710+ int i = 0;
4711+
4712+ if (! bfd_set_arch_mach (stdoutput, bfd_arch_riscv, 0))
4713+ as_warn (_("Could not set architecture and machine"));
4714+
4715+ op_hash = hash_new ();
4716+
4717+ for (i = 0; i < NUMOPCODES;)
4718+ {
4719+ const char *name = riscv_opcodes[i].name;
4720+
4721+ if (riscv_subset_supports(riscv_opcodes[i].subset))
4722+ retval = hash_insert (op_hash, name, (void *) &riscv_opcodes[i]);
4723+
4724+ if (retval != NULL)
4725+ {
4726+ fprintf (stderr, _("internal error: can't hash `%s': %s\n"),
4727+ riscv_opcodes[i].name, retval);
4728+ /* Probably a memory allocation problem? Give up now. */
4729+ as_fatal (_("Broken assembler. No assembly attempted."));
4730+ }
4731+ do
4732+ {
4733+ if (riscv_opcodes[i].pinfo != INSN_MACRO)
4734+ {
4735+ if (!validate_riscv_insn (&riscv_opcodes[i]))
4736+ as_fatal (_("Broken assembler. No assembly attempted."));
4737+ }
4738+ ++i;
4739+ }
4740+ while ((i < NUMOPCODES) && !strcmp (riscv_opcodes[i].name, name));
4741+ }
4742+
4743+ reg_names_hash = hash_new ();
4744+ hash_reg_names (RCLASS_GPR, riscv_gpr_names_numeric, NGPR);
4745+ hash_reg_names (RCLASS_GPR, riscv_gpr_names_abi, NGPR);
4746+ hash_reg_names (RCLASS_FPR, riscv_fpr_names_numeric, NFPR);
4747+ hash_reg_names (RCLASS_FPR, riscv_fpr_names_abi, NFPR);
4748+ hash_reg_names (RCLASS_VEC_GPR, riscv_vec_gpr_names, NVGPR);
4749+ hash_reg_names (RCLASS_VEC_FPR, riscv_vec_fpr_names, NVFPR);
4750+
4751+#define DECLARE_CSR(name, num) hash_reg_name (RCLASS_CSR, #name, num);
4752+#include "opcode/riscv-opc.h"
4753+#undef DECLARE_CSR
4754+
4755+ /* set the default alignment for the text section (2**2) */
4756+ record_alignment (text_section, 2);
4757+}
4758+
4759+/* Output an instruction. IP is the instruction information.
4760+ ADDRESS_EXPR is an operand of the instruction to be used with
4761+ RELOC_TYPE. */
4762+
4763+static void
4764+append_insn (struct riscv_cl_insn *ip, expressionS *address_expr,
4765+ bfd_reloc_code_real_type reloc_type)
4766+{
4767+#ifdef OBJ_ELF
4768+ dwarf2_emit_insn (0);
4769+#endif
4770+
4771+ gas_assert(reloc_type <= BFD_RELOC_UNUSED);
4772+
4773+ if (address_expr != NULL)
4774+ {
4775+ if (address_expr->X_op == O_constant)
4776+ {
4777+ switch (reloc_type)
4778+ {
4779+ case BFD_RELOC_32:
4780+ ip->insn_opcode |= address_expr->X_add_number;
4781+ break;
4782+
4783+ case BFD_RELOC_RISCV_HI20:
4784+ ip->insn_opcode |= ENCODE_UTYPE_IMM (
4785+ RISCV_CONST_HIGH_PART (address_expr->X_add_number));
4786+ break;
4787+
4788+ case BFD_RELOC_RISCV_LO12_S:
4789+ ip->insn_opcode |= ENCODE_STYPE_IMM (address_expr->X_add_number);
4790+ break;
4791+
4792+ case BFD_RELOC_UNUSED:
4793+ case BFD_RELOC_RISCV_LO12_I:
4794+ ip->insn_opcode |= ENCODE_ITYPE_IMM (address_expr->X_add_number);
4795+ break;
4796+
4797+ default:
4798+ internalError ();
4799+ }
4800+ reloc_type = BFD_RELOC_UNUSED;
4801+ }
4802+ else if (reloc_type == BFD_RELOC_12_PCREL)
4803+ {
4804+ add_relaxed_insn (ip, relaxed_branch_length (NULL, NULL, 0), 4,
4805+ RELAX_BRANCH_ENCODE (0, 0),
4806+ address_expr->X_add_symbol,
4807+ address_expr->X_add_number);
4808+ return;
4809+ }
4810+ else if (reloc_type < BFD_RELOC_UNUSED)
4811+ {
4812+ reloc_howto_type *howto;
4813+
4814+ howto = bfd_reloc_type_lookup (stdoutput, reloc_type);
4815+ if (howto == NULL)
4816+ as_bad (_("Unsupported RISC-V relocation number %d"), reloc_type);
4817+
4818+ ip->fixp = fix_new_exp (ip->frag, ip->where,
4819+ bfd_get_reloc_size (howto),
4820+ address_expr,
4821+ reloc_type == BFD_RELOC_12_PCREL ||
4822+ reloc_type == BFD_RELOC_RISCV_CALL ||
4823+ reloc_type == BFD_RELOC_RISCV_JMP,
4824+ reloc_type);
4825+
4826+ /* These relocations can have an addend that won't fit in
4827+ 4 octets for 64bit assembly. */
4828+ if (rv64
4829+ && ! howto->partial_inplace
4830+ && (reloc_type == BFD_RELOC_32
4831+ || reloc_type == BFD_RELOC_64
4832+ || reloc_type == BFD_RELOC_CTOR
4833+ || reloc_type == BFD_RELOC_RISCV_HI20
4834+ || reloc_type == BFD_RELOC_RISCV_LO12_I
4835+ || reloc_type == BFD_RELOC_RISCV_LO12_S))
4836+ ip->fixp->fx_no_overflow = 1;
4837+ }
4838+ }
4839+
4840+ add_fixed_insn (ip);
4841+
4842+ install_insn (ip);
4843+}
4844+
4845+/* Build an instruction created by a macro expansion. This is passed
4846+ a pointer to the count of instructions created so far, an
4847+ expression, the name of the instruction to build, an operand format
4848+ string, and corresponding arguments. */
4849+
4850+static void
4851+macro_build (expressionS *ep, const char *name, const char *fmt, ...)
4852+{
4853+ const struct riscv_opcode *mo;
4854+ struct riscv_cl_insn insn;
4855+ bfd_reloc_code_real_type r;
4856+ va_list args;
4857+
4858+ va_start (args, fmt);
4859+
4860+ r = BFD_RELOC_UNUSED;
4861+ mo = (struct riscv_opcode *) hash_find (op_hash, name);
4862+ gas_assert (mo);
4863+ gas_assert (strcmp (name, mo->name) == 0);
4864+
4865+ create_insn (&insn, mo);
4866+ for (;;)
4867+ {
4868+ switch (*fmt++)
4869+ {
4870+ case 'd':
4871+ INSERT_OPERAND (RD, insn, va_arg (args, int));
4872+ continue;
4873+
4874+ case 's':
4875+ INSERT_OPERAND (RS1, insn, va_arg (args, int));
4876+ continue;
4877+
4878+ case 't':
4879+ INSERT_OPERAND (RS2, insn, va_arg (args, int));
4880+ continue;
4881+
4882+ case '>':
4883+ INSERT_OPERAND (SHAMT, insn, va_arg (args, int));
4884+ continue;
4885+
4886+ case 'j':
4887+ case 'u':
4888+ case 'q':
4889+ gas_assert (ep != NULL);
4890+ r = va_arg (args, int);
4891+ continue;
4892+
4893+ case '\0':
4894+ break;
4895+ case ',':
4896+ continue;
4897+ default:
4898+ internalError ();
4899+ }
4900+ break;
4901+ }
4902+ va_end (args);
4903+ gas_assert (r == BFD_RELOC_UNUSED ? ep == NULL : ep != NULL);
4904+
4905+ append_insn (&insn, ep, r);
4906+}
4907+
4908+/*
4909+ * Sign-extend 32-bit mode constants that have bit 31 set and all
4910+ * higher bits unset.
4911+ */
4912+static void
4913+normalize_constant_expr (expressionS *ex)
4914+{
4915+ if (rv64)
4916+ return;
4917+ if ((ex->X_op == O_constant || ex->X_op == O_symbol)
4918+ && IS_ZEXT_32BIT_NUM (ex->X_add_number))
4919+ ex->X_add_number = (((ex->X_add_number & 0xffffffff) ^ 0x80000000)
4920+ - 0x80000000);
4921+}
4922+
4923+static symbolS *
4924+make_internal_label (void)
4925+{
4926+ return (symbolS *) local_symbol_make (FAKE_LABEL_NAME, now_seg,
4927+ (valueT) frag_now_fix(), frag_now);
4928+}
4929+
4930+/* Load an entry from the GOT. */
4931+static void
4932+pcrel_access (int destreg, int tempreg, expressionS *ep,
4933+ const char* lo_insn, const char* lo_pattern,
4934+ bfd_reloc_code_real_type hi_reloc,
4935+ bfd_reloc_code_real_type lo_reloc)
4936+{
4937+ expressionS ep2;
4938+ ep2.X_op = O_symbol;
4939+ ep2.X_add_symbol = make_internal_label ();
4940+ ep2.X_add_number = 0;
4941+
4942+ macro_build (ep, "auipc", "d,u", tempreg, hi_reloc);
4943+ macro_build (&ep2, lo_insn, lo_pattern, destreg, tempreg, lo_reloc);
4944+}
4945+
4946+static void
4947+pcrel_load (int destreg, int tempreg, expressionS *ep, const char* lo_insn,
4948+ bfd_reloc_code_real_type hi_reloc,
4949+ bfd_reloc_code_real_type lo_reloc)
4950+{
4951+ pcrel_access (destreg, tempreg, ep, lo_insn, "d,s,j", hi_reloc, lo_reloc);
4952+}
4953+
4954+static void
4955+pcrel_store (int srcreg, int tempreg, expressionS *ep, const char* lo_insn,
4956+ bfd_reloc_code_real_type hi_reloc,
4957+ bfd_reloc_code_real_type lo_reloc)
4958+{
4959+ pcrel_access (srcreg, tempreg, ep, lo_insn, "t,s,q", hi_reloc, lo_reloc);
4960+}
4961+
4962+/* PC-relative function call using AUIPC/JALR, relaxed to JAL. */
4963+static void
4964+riscv_call (int destreg, int tempreg, expressionS *ep,
4965+ bfd_reloc_code_real_type reloc)
4966+{
4967+ macro_build (ep, "auipc", "d,u", tempreg, reloc);
4968+ macro_build (NULL, "jalr", "d,s", destreg, tempreg);
4969+}
4970+
4971+/* Warn if an expression is not a constant. */
4972+
4973+static void
4974+check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex)
4975+{
4976+ if (ex->X_op == O_big)
4977+ as_bad (_("unsupported large constant"));
4978+ else if (ex->X_op != O_constant)
4979+ as_bad (_("Instruction %s requires absolute expression"),
4980+ ip->insn_mo->name);
4981+ normalize_constant_expr (ex);
4982+}
4983+
4984+/* Load an integer constant into a register. */
4985+
4986+static void
4987+load_const (int reg, expressionS *ep)
4988+{
4989+ int shift = RISCV_IMM_BITS;
4990+ expressionS upper = *ep, lower = *ep;
4991+ lower.X_add_number = (int32_t) ep->X_add_number << (32-shift) >> (32-shift);
4992+ upper.X_add_number -= lower.X_add_number;
4993+
4994+ gas_assert (ep->X_op == O_constant);
4995+
4996+ if (rv64 && !IS_SEXT_32BIT_NUM(ep->X_add_number))
4997+ {
4998+ /* Reduce to a signed 32-bit constant using SLLI and ADDI, which
4999+ is not optimal but also not so bad. */
5000+ while (((upper.X_add_number >> shift) & 1) == 0)
5001+ shift++;
5002+
5003+ upper.X_add_number = (int64_t) upper.X_add_number >> shift;
5004+ load_const(reg, &upper);
5005+
5006+ macro_build (NULL, "slli", "d,s,>", reg, reg, shift);
5007+ if (lower.X_add_number != 0)
5008+ macro_build (&lower, "addi", "d,s,j", reg, reg, BFD_RELOC_RISCV_LO12_I);
5009+ }
5010+ else
5011+ {
5012+ int hi_reg = 0;
5013+
5014+ if (upper.X_add_number != 0)
5015+ {
5016+ macro_build (ep, "lui", "d,u", reg, BFD_RELOC_RISCV_HI20);
5017+ hi_reg = reg;
5018+ }
5019+
5020+ if (lower.X_add_number != 0 || hi_reg == 0)
5021+ macro_build (ep, ADD32_INSN, "d,s,j", reg, hi_reg,
5022+ BFD_RELOC_RISCV_LO12_I);
5023+ }
5024+}
5025+
5026+/* Expand RISC-V assembly macros into one or more instructions. */
5027+static void
5028+macro (struct riscv_cl_insn *ip)
5029+{
5030+ int rd = (ip->insn_opcode >> OP_SH_RD) & OP_MASK_RD;
5031+ int rs1 = (ip->insn_opcode >> OP_SH_RS1) & OP_MASK_RS1;
5032+ int rs2 = (ip->insn_opcode >> OP_SH_RS2) & OP_MASK_RS2;
5033+ int mask = ip->insn_mo->mask;
5034+
5035+ switch (mask)
5036+ {
5037+ case M_LI:
5038+ load_const (rd, &imm_expr);
5039+ break;
5040+
5041+ case M_LA:
5042+ case M_LLA:
5043+ /* Load the address of a symbol into a register. */
5044+ if (!IS_SEXT_32BIT_NUM (offset_expr.X_add_number))
5045+ as_bad(_("offset too large"));
5046+
5047+ if (offset_expr.X_op == O_constant)
5048+ load_const (rd, &offset_expr);
5049+ else if (riscv_opts.pic && mask == M_LA) /* Global PIC symbol */
5050+ pcrel_load (rd, rd, &offset_expr, LOAD_ADDRESS_INSN,
5051+ BFD_RELOC_RISCV_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5052+ else /* Local PIC symbol, or any non-PIC symbol */
5053+ pcrel_load (rd, rd, &offset_expr, "addi",
5054+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5055+ break;
5056+
5057+ case M_LA_TLS_GD:
5058+ pcrel_load (rd, rd, &offset_expr, "addi",
5059+ BFD_RELOC_RISCV_TLS_GD_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5060+ break;
5061+
5062+ case M_LA_TLS_IE:
5063+ pcrel_load (rd, rd, &offset_expr, LOAD_ADDRESS_INSN,
5064+ BFD_RELOC_RISCV_TLS_GOT_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5065+ break;
5066+
5067+ case M_LB:
5068+ pcrel_load (rd, rd, &offset_expr, "lb",
5069+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5070+ break;
5071+
5072+ case M_LBU:
5073+ pcrel_load (rd, rd, &offset_expr, "lbu",
5074+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5075+ break;
5076+
5077+ case M_LH:
5078+ pcrel_load (rd, rd, &offset_expr, "lh",
5079+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5080+ break;
5081+
5082+ case M_LHU:
5083+ pcrel_load (rd, rd, &offset_expr, "lhu",
5084+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5085+ break;
5086+
5087+ case M_LW:
5088+ pcrel_load (rd, rd, &offset_expr, "lw",
5089+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5090+ break;
5091+
5092+ case M_LWU:
5093+ pcrel_load (rd, rd, &offset_expr, "lwu",
5094+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5095+ break;
5096+
5097+ case M_LD:
5098+ pcrel_load (rd, rd, &offset_expr, "ld",
5099+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5100+ break;
5101+
5102+ case M_FLW:
5103+ pcrel_load (rd, rs1, &offset_expr, "flw",
5104+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5105+ break;
5106+
5107+ case M_FLD:
5108+ pcrel_load (rd, rs1, &offset_expr, "fld",
5109+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_I);
5110+ break;
5111+
5112+ case M_SB:
5113+ pcrel_store (rs2, rs1, &offset_expr, "sb",
5114+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5115+ break;
5116+
5117+ case M_SH:
5118+ pcrel_store (rs2, rs1, &offset_expr, "sh",
5119+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5120+ break;
5121+
5122+ case M_SW:
5123+ pcrel_store (rs2, rs1, &offset_expr, "sw",
5124+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5125+ break;
5126+
5127+ case M_SD:
5128+ pcrel_store (rs2, rs1, &offset_expr, "sd",
5129+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5130+ break;
5131+
5132+ case M_FSW:
5133+ pcrel_store (rs2, rs1, &offset_expr, "fsw",
5134+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5135+ break;
5136+
5137+ case M_FSD:
5138+ pcrel_store (rs2, rs1, &offset_expr, "fsd",
5139+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5140+ break;
5141+
5142+ case M_VF:
5143+ pcrel_access (0, rs1, &offset_expr, "vf", "s,s,q",
5144+ BFD_RELOC_RISCV_PCREL_HI20, BFD_RELOC_RISCV_PCREL_LO12_S);
5145+ break;
5146+
5147+ case M_CALL:
5148+ riscv_call (rd, rs1, &offset_expr, offset_reloc);
5149+ break;
5150+
5151+ default:
5152+ as_bad (_("Macro %s not implemented"), ip->insn_mo->name);
5153+ break;
5154+ }
5155+}
5156+
5157+static const struct percent_op_match percent_op_utype[] =
5158+{
5159+ {"%tprel_hi", BFD_RELOC_RISCV_TPREL_HI20},
5160+ {"%pcrel_hi", BFD_RELOC_RISCV_PCREL_HI20},
5161+ {"%tls_ie_pcrel_hi", BFD_RELOC_RISCV_TLS_GOT_HI20},
5162+ {"%tls_gd_pcrel_hi", BFD_RELOC_RISCV_TLS_GD_HI20},
5163+ {"%hi", BFD_RELOC_RISCV_HI20},
5164+ {0, 0}
5165+};
5166+
5167+static const struct percent_op_match percent_op_itype[] =
5168+{
5169+ {"%lo", BFD_RELOC_RISCV_LO12_I},
5170+ {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_I},
5171+ {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_I},
5172+ {0, 0}
5173+};
5174+
5175+static const struct percent_op_match percent_op_stype[] =
5176+{
5177+ {"%lo", BFD_RELOC_RISCV_LO12_S},
5178+ {"%tprel_lo", BFD_RELOC_RISCV_TPREL_LO12_S},
5179+ {"%pcrel_lo", BFD_RELOC_RISCV_PCREL_LO12_S},
5180+ {0, 0}
5181+};
5182+
5183+static const struct percent_op_match percent_op_rtype[] =
5184+{
5185+ {"%tprel_add", BFD_RELOC_RISCV_TPREL_ADD},
5186+ {0, 0}
5187+};
5188+
5189+/* Return true if *STR points to a relocation operator. When returning true,
5190+ move *STR over the operator and store its relocation code in *RELOC.
5191+ Leave both *STR and *RELOC alone when returning false. */
5192+
5193+static bfd_boolean
5194+parse_relocation (char **str, bfd_reloc_code_real_type *reloc,
5195+ const struct percent_op_match *percent_op)
5196+{
5197+ for ( ; percent_op->str; percent_op++)
5198+ if (strncasecmp (*str, percent_op->str, strlen (percent_op->str)) == 0)
5199+ {
5200+ int len = strlen (percent_op->str);
5201+
5202+ if (!ISSPACE ((*str)[len]) && (*str)[len] != '(')
5203+ continue;
5204+
5205+ *str += strlen (percent_op->str);
5206+ *reloc = percent_op->reloc;
5207+
5208+ /* Check whether the output BFD supports this relocation.
5209+ If not, issue an error and fall back on something safe. */
5210+ if (!bfd_reloc_type_lookup (stdoutput, percent_op->reloc))
5211+ {
5212+ as_bad ("relocation %s isn't supported by the current ABI",
5213+ percent_op->str);
5214+ *reloc = BFD_RELOC_UNUSED;
5215+ }
5216+ return TRUE;
5217+ }
5218+ return FALSE;
5219+}
5220+
5221+static void
5222+my_getExpression (expressionS *ep, char *str)
5223+{
5224+ char *save_in;
5225+
5226+ save_in = input_line_pointer;
5227+ input_line_pointer = str;
5228+ expression (ep);
5229+ expr_end = input_line_pointer;
5230+ input_line_pointer = save_in;
5231+}
5232+
5233+/* Parse string STR as a 16-bit relocatable operand. Store the
5234+ expression in *EP and the relocation, if any, in RELOC.
5235+ Return the number of relocation operators used (0 or 1).
5236+
5237+ On exit, EXPR_END points to the first character after the expression. */
5238+
5239+static size_t
5240+my_getSmallExpression (expressionS *ep, bfd_reloc_code_real_type *reloc,
5241+ char *str, const struct percent_op_match *percent_op)
5242+{
5243+ size_t reloc_index;
5244+ int crux_depth, str_depth;
5245+ char *crux;
5246+
5247+ /* Search for the start of the main expression.
5248+ End the loop with CRUX pointing to the start
5249+ of the main expression and with CRUX_DEPTH containing the number
5250+ of open brackets at that point. */
5251+ reloc_index = -1;
5252+ str_depth = 0;
5253+ do
5254+ {
5255+ reloc_index++;
5256+ crux = str;
5257+ crux_depth = str_depth;
5258+
5259+ /* Skip over whitespace and brackets, keeping count of the number
5260+ of brackets. */
5261+ while (*str == ' ' || *str == '\t' || *str == '(')
5262+ if (*str++ == '(')
5263+ str_depth++;
5264+ }
5265+ while (*str == '%'
5266+ && reloc_index < 1
5267+ && parse_relocation (&str, reloc, percent_op));
5268+
5269+ my_getExpression (ep, crux);
5270+ str = expr_end;
5271+
5272+ /* Match every open bracket. */
5273+ while (crux_depth > 0 && (*str == ')' || *str == ' ' || *str == '\t'))
5274+ if (*str++ == ')')
5275+ crux_depth--;
5276+
5277+ if (crux_depth > 0)
5278+ as_bad ("unclosed '('");
5279+
5280+ expr_end = str;
5281+
5282+ return reloc_index;
5283+}
5284+
5285+/* This routine assembles an instruction into its binary format. As a
5286+ side effect, it sets one of the global variables imm_reloc or
5287+ offset_reloc to the type of relocation to do if one of the operands
5288+ is an address expression. */
5289+
5290+static void
5291+riscv_ip (char *str, struct riscv_cl_insn *ip)
5292+{
5293+ char *s;
5294+ const char *args;
5295+ char c = 0;
5296+ struct riscv_opcode *insn;
5297+ char *argsStart;
5298+ unsigned int regno;
5299+ char save_c = 0;
5300+ int argnum;
5301+ const struct percent_op_match *p;
5302+
5303+ insn_error = NULL;
5304+
5305+ /* If the instruction contains a '.', we first try to match an instruction
5306+ including the '.'. Then we try again without the '.'. */
5307+ insn = NULL;
5308+ for (s = str; *s != '\0' && !ISSPACE (*s); ++s)
5309+ continue;
5310+
5311+ /* If we stopped on whitespace, then replace the whitespace with null for
5312+ the call to hash_find. Save the character we replaced just in case we
5313+ have to re-parse the instruction. */
5314+ if (ISSPACE (*s))
5315+ {
5316+ save_c = *s;
5317+ *s++ = '\0';
5318+ }
5319+
5320+ insn = (struct riscv_opcode *) hash_find (op_hash, str);
5321+
5322+ /* If we didn't find the instruction in the opcode table, try again, but
5323+ this time with just the instruction up to, but not including the
5324+ first '.'. */
5325+ if (insn == NULL)
5326+ {
5327+ /* Restore the character we overwrite above (if any). */
5328+ if (save_c)
5329+ *(--s) = save_c;
5330+
5331+ /* Scan up to the first '.' or whitespace. */
5332+ for (s = str;
5333+ *s != '\0' && *s != '.' && !ISSPACE (*s);
5334+ ++s)
5335+ continue;
5336+
5337+ /* If we did not find a '.', then we can quit now. */
5338+ if (*s != '.')
5339+ {
5340+ insn_error = "unrecognized opcode";
5341+ return;
5342+ }
5343+
5344+ /* Lookup the instruction in the hash table. */
5345+ *s++ = '\0';
5346+ if ((insn = (struct riscv_opcode *) hash_find (op_hash, str)) == NULL)
5347+ {
5348+ insn_error = "unrecognized opcode";
5349+ return;
5350+ }
5351+ }
5352+
5353+ argsStart = s;
5354+ for (;;)
5355+ {
5356+ bfd_boolean ok = TRUE;
5357+ gas_assert (strcmp (insn->name, str) == 0);
5358+
5359+ create_insn (ip, insn);
5360+ insn_error = NULL;
5361+ argnum = 1;
5362+ for (args = insn->args;; ++args)
5363+ {
5364+ s += strspn (s, " \t");
5365+ switch (*args)
5366+ {
5367+ case '\0': /* end of args */
5368+ if (*s == '\0')
5369+ return;
5370+ break;
5371+ /* Xcustom */
5372+ case '^':
5373+ {
5374+ unsigned long max = OP_MASK_RD;
5375+ my_getExpression (&imm_expr, s);
5376+ check_absolute_expr (ip, &imm_expr);
5377+ switch (*++args)
5378+ {
5379+ case 'j':
5380+ max = OP_MASK_CUSTOM_IMM;
5381+ INSERT_OPERAND (CUSTOM_IMM, *ip, imm_expr.X_add_number);
5382+ break;
5383+ case 'd':
5384+ INSERT_OPERAND (RD, *ip, imm_expr.X_add_number);
5385+ break;
5386+ case 's':
5387+ INSERT_OPERAND (RS1, *ip, imm_expr.X_add_number);
5388+ break;
5389+ case 't':
5390+ INSERT_OPERAND (RS2, *ip, imm_expr.X_add_number);
5391+ break;
5392+ }
5393+ imm_expr.X_op = O_absent;
5394+ s = expr_end;
5395+ if ((unsigned long) imm_expr.X_add_number > max)
5396+ as_warn ("Bad custom immediate (%lu), must be at most %lu",
5397+ (unsigned long)imm_expr.X_add_number, max);
5398+ continue;
5399+ }
5400+
5401+ /* Xhwacha */
5402+ case '#':
5403+ switch ( *++args )
5404+ {
5405+ case 'g':
5406+ my_getExpression( &imm_expr, s );
5407+ /* check_absolute_expr( ip, &imm_expr ); */
5408+ if ((unsigned long) imm_expr.X_add_number > 32 )
5409+ as_warn( _( "Improper ngpr amount (%lu)" ),
5410+ (unsigned long) imm_expr.X_add_number );
5411+ INSERT_OPERAND( IMMNGPR, *ip, imm_expr.X_add_number );
5412+ imm_expr.X_op = O_absent;
5413+ s = expr_end;
5414+ continue;
5415+ case 'f':
5416+ my_getExpression( &imm_expr, s );
5417+ /* check_absolute_expr( ip, &imm_expr ); */
5418+ if ((unsigned long) imm_expr.X_add_number > 32 )
5419+ as_warn( _( "Improper nfpr amount (%lu)" ),
5420+ (unsigned long) imm_expr.X_add_number );
5421+ INSERT_OPERAND( IMMNFPR, *ip, imm_expr.X_add_number );
5422+ imm_expr.X_op = O_absent;
5423+ s = expr_end;
5424+ continue;
5425+ case 'n':
5426+ my_getExpression( &imm_expr, s );
5427+ /* check_absolute_expr( ip, &imm_expr ); */
5428+ if ((unsigned long) imm_expr.X_add_number > 8 )
5429+ as_warn( _( "Improper nelm amount (%lu)" ),
5430+ (unsigned long) imm_expr.X_add_number );
5431+ INSERT_OPERAND( IMMSEGNELM, *ip, imm_expr.X_add_number - 1 );
5432+ imm_expr.X_op = O_absent;
5433+ s = expr_end;
5434+ continue;
5435+ case 'd':
5436+ ok = reg_lookup( &s, RCLASS_VEC_GPR, &regno );
5437+ if ( !ok )
5438+ as_bad( _( "Invalid vector register" ) );
5439+ INSERT_OPERAND( VRD, *ip, regno );
5440+ continue;
5441+ case 's':
5442+ ok = reg_lookup( &s, RCLASS_VEC_GPR, &regno );
5443+ if ( !ok )
5444+ as_bad( _( "Invalid vector register" ) );
5445+ INSERT_OPERAND( VRS, *ip, regno );
5446+ continue;
5447+ case 't':
5448+ ok = reg_lookup( &s, RCLASS_VEC_GPR, &regno );
5449+ if ( !ok )
5450+ as_bad( _( "Invalid vector register" ) );
5451+ INSERT_OPERAND( VRT, *ip, regno );
5452+ continue;
5453+ case 'r':
5454+ ok = reg_lookup( &s, RCLASS_VEC_GPR, &regno );
5455+ if ( !ok )
5456+ as_bad( _( "Invalid vector register" ) );
5457+ INSERT_OPERAND( VRR, *ip, regno );
5458+ continue;
5459+ case 'D':
5460+ ok = reg_lookup( &s, RCLASS_VEC_FPR, &regno );
5461+ if ( !ok )
5462+ as_bad( _( "Invalid vector register" ) );
5463+ INSERT_OPERAND( VFD, *ip, regno );
5464+ continue;
5465+ case 'S':
5466+ ok = reg_lookup( &s, RCLASS_VEC_FPR, &regno );
5467+ if ( !ok )
5468+ as_bad( _( "Invalid vector register" ) );
5469+ INSERT_OPERAND( VFS, *ip, regno );
5470+ continue;
5471+ case 'T':
5472+ ok = reg_lookup( &s, RCLASS_VEC_FPR, &regno );
5473+ if ( !ok )
5474+ as_bad( _( "Invalid vector register" ) );
5475+ INSERT_OPERAND( VFT, *ip, regno );
5476+ continue;
5477+ case 'R':
5478+ ok = reg_lookup( &s, RCLASS_VEC_FPR, &regno );
5479+ if ( !ok )
5480+ as_bad( _( "Invalid vector register" ) );
5481+ INSERT_OPERAND( VFR, *ip, regno );
5482+ continue;
5483+ }
5484+ break;
5485+
5486+ case ',':
5487+ ++argnum;
5488+ if (*s++ == *args)
5489+ continue;
5490+ s--;
5491+ break;
5492+
5493+ case '(':
5494+ case ')':
5495+ case '[':
5496+ case ']':
5497+ if (*s++ == *args)
5498+ continue;
5499+ break;
5500+
5501+ case '<': /* shift amount, 0 - 31 */
5502+ my_getExpression (&imm_expr, s);
5503+ check_absolute_expr (ip, &imm_expr);
5504+ if ((unsigned long) imm_expr.X_add_number > 31)
5505+ as_warn (_("Improper shift amount (%lu)"),
5506+ (unsigned long) imm_expr.X_add_number);
5507+ INSERT_OPERAND (SHAMTW, *ip, imm_expr.X_add_number);
5508+ imm_expr.X_op = O_absent;
5509+ s = expr_end;
5510+ continue;
5511+
5512+ case '>': /* shift amount, 0 - (XLEN-1) */
5513+ my_getExpression (&imm_expr, s);
5514+ check_absolute_expr (ip, &imm_expr);
5515+ if ((unsigned long) imm_expr.X_add_number > (rv64 ? 63 : 31))
5516+ as_warn (_("Improper shift amount (%lu)"),
5517+ (unsigned long) imm_expr.X_add_number);
5518+ INSERT_OPERAND (SHAMT, *ip, imm_expr.X_add_number);
5519+ imm_expr.X_op = O_absent;
5520+ s = expr_end;
5521+ continue;
5522+
5523+ case 'Z': /* CSRRxI immediate */
5524+ my_getExpression (&imm_expr, s);
5525+ check_absolute_expr (ip, &imm_expr);
5526+ if ((unsigned long) imm_expr.X_add_number > 31)
5527+ as_warn (_("Improper CSRxI immediate (%lu)"),
5528+ (unsigned long) imm_expr.X_add_number);
5529+ INSERT_OPERAND (RS1, *ip, imm_expr.X_add_number);
5530+ imm_expr.X_op = O_absent;
5531+ s = expr_end;
5532+ continue;
5533+
5534+ case 'E': /* Control register. */
5535+ ok = reg_lookup (&s, RCLASS_CSR, &regno);
5536+ if (ok)
5537+ INSERT_OPERAND (CSR, *ip, regno);
5538+ else
5539+ {
5540+ my_getExpression (&imm_expr, s);
5541+ check_absolute_expr (ip, &imm_expr);
5542+ if ((unsigned long) imm_expr.X_add_number > 0xfff)
5543+ as_warn(_("Improper CSR address (%lu)"),
5544+ (unsigned long) imm_expr.X_add_number);
5545+ INSERT_OPERAND (CSR, *ip, imm_expr.X_add_number);
5546+ imm_expr.X_op = O_absent;
5547+ s = expr_end;
5548+ }
5549+ continue;
5550+
5551+ case 'm': /* rounding mode */
5552+ if (arg_lookup (&s, riscv_rm, ARRAY_SIZE(riscv_rm), &regno))
5553+ {
5554+ INSERT_OPERAND (RM, *ip, regno);
5555+ continue;
5556+ }
5557+ break;
5558+
5559+ case 'P':
5560+ case 'Q': /* fence predecessor/successor */
5561+ if (arg_lookup (&s, riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ), &regno))
5562+ {
5563+ if (*args == 'P')
5564+ INSERT_OPERAND(PRED, *ip, regno);
5565+ else
5566+ INSERT_OPERAND(SUCC, *ip, regno);
5567+ continue;
5568+ }
5569+ break;
5570+
5571+ case 'd': /* destination register */
5572+ case 's': /* source register */
5573+ case 't': /* target register */
5574+ ok = reg_lookup (&s, RCLASS_GPR, &regno);
5575+ if (ok)
5576+ {
5577+ c = *args;
5578+ if (*s == ' ')
5579+ ++s;
5580+
5581+ /* Now that we have assembled one operand, we use the args string
5582+ * to figure out where it goes in the instruction. */
5583+ switch (c)
5584+ {
5585+ case 's':
5586+ INSERT_OPERAND (RS1, *ip, regno);
5587+ break;
5588+ case 'd':
5589+ INSERT_OPERAND (RD, *ip, regno);
5590+ break;
5591+ case 't':
5592+ INSERT_OPERAND (RS2, *ip, regno);
5593+ break;
5594+ }
5595+ continue;
5596+ }
5597+ break;
5598+
5599+ case 'D': /* floating point rd */
5600+ case 'S': /* floating point rs1 */
5601+ case 'T': /* floating point rs2 */
5602+ case 'U': /* floating point rs1 and rs2 */
5603+ case 'R': /* floating point rs3 */
5604+ if (reg_lookup (&s, RCLASS_FPR, &regno))
5605+ {
5606+ c = *args;
5607+ if (*s == ' ')
5608+ ++s;
5609+ switch (c)
5610+ {
5611+ case 'D':
5612+ INSERT_OPERAND (RD, *ip, regno);
5613+ break;
5614+ case 'S':
5615+ INSERT_OPERAND (RS1, *ip, regno);
5616+ break;
5617+ case 'U':
5618+ INSERT_OPERAND (RS1, *ip, regno);
5619+ /* fallthru */
5620+ case 'T':
5621+ INSERT_OPERAND (RS2, *ip, regno);
5622+ break;
5623+ case 'R':
5624+ INSERT_OPERAND (RS3, *ip, regno);
5625+ break;
5626+ }
5627+ continue;
5628+ }
5629+
5630+ break;
5631+
5632+ case 'I':
5633+ my_getExpression (&imm_expr, s);
5634+ if (imm_expr.X_op != O_big
5635+ && imm_expr.X_op != O_constant)
5636+ insn_error = _("absolute expression required");
5637+ normalize_constant_expr (&imm_expr);
5638+ s = expr_end;
5639+ continue;
5640+
5641+ case 'A':
5642+ my_getExpression (&offset_expr, s);
5643+ normalize_constant_expr (&offset_expr);
5644+ imm_reloc = BFD_RELOC_32;
5645+ s = expr_end;
5646+ continue;
5647+
5648+ case 'j': /* sign-extended immediate */
5649+ imm_reloc = BFD_RELOC_RISCV_LO12_I;
5650+ p = percent_op_itype;
5651+ goto alu_op;
5652+ case 'q': /* store displacement */
5653+ p = percent_op_stype;
5654+ offset_reloc = BFD_RELOC_RISCV_LO12_S;
5655+ goto load_store;
5656+ case 'o': /* load displacement */
5657+ p = percent_op_itype;
5658+ offset_reloc = BFD_RELOC_RISCV_LO12_I;
5659+ goto load_store;
5660+ case '0': /* AMO "displacement," which must be zero */
5661+ p = percent_op_rtype;
5662+ offset_reloc = BFD_RELOC_UNUSED;
5663+load_store:
5664+ /* Check whether there is only a single bracketed expression
5665+ left. If so, it must be the base register and the
5666+ constant must be zero. */
5667+ offset_expr.X_op = O_constant;
5668+ offset_expr.X_add_number = 0;
5669+ if (*s == '(' && strchr (s + 1, '(') == 0)
5670+ continue;
5671+alu_op:
5672+ /* If this value won't fit into a 16 bit offset, then go
5673+ find a macro that will generate the 32 bit offset
5674+ code pattern. */
5675+ if (!my_getSmallExpression (&offset_expr, &offset_reloc, s, p))
5676+ {
5677+ normalize_constant_expr (&offset_expr);
5678+ if (offset_expr.X_op != O_constant
5679+ || (*args == '0' && offset_expr.X_add_number != 0)
5680+ || offset_expr.X_add_number >= (signed)RISCV_IMM_REACH/2
5681+ || offset_expr.X_add_number < -(signed)RISCV_IMM_REACH/2)
5682+ break;
5683+ }
5684+
5685+ s = expr_end;
5686+ continue;
5687+
5688+ case 'p': /* pc relative offset */
5689+ offset_reloc = BFD_RELOC_12_PCREL;
5690+ my_getExpression (&offset_expr, s);
5691+ s = expr_end;
5692+ continue;
5693+
5694+ case 'u': /* upper 20 bits */
5695+ p = percent_op_utype;
5696+ if (!my_getSmallExpression (&imm_expr, &imm_reloc, s, p)
5697+ && imm_expr.X_op == O_constant)
5698+ {
5699+ if (imm_expr.X_add_number < 0
5700+ || imm_expr.X_add_number >= (signed)RISCV_BIGIMM_REACH)
5701+ as_bad (_("lui expression not in range 0..1048575"));
5702+
5703+ imm_reloc = BFD_RELOC_RISCV_HI20;
5704+ imm_expr.X_add_number <<= RISCV_IMM_BITS;
5705+ }
5706+ s = expr_end;
5707+ continue;
5708+
5709+ case 'a': /* 26 bit address */
5710+ my_getExpression (&offset_expr, s);
5711+ s = expr_end;
5712+ offset_reloc = BFD_RELOC_RISCV_JMP;
5713+ continue;
5714+
5715+ case 'c':
5716+ my_getExpression (&offset_expr, s);
5717+ s = expr_end;
5718+ offset_reloc = BFD_RELOC_RISCV_CALL;
5719+ if (*s == '@')
5720+ offset_reloc = BFD_RELOC_RISCV_CALL_PLT, s++;
5721+ continue;
5722+
5723+ default:
5724+ as_bad (_("bad char = '%c'\n"), *args);
5725+ internalError ();
5726+ }
5727+ break;
5728+ }
5729+ /* Args don't match. */
5730+ if (insn + 1 < &riscv_opcodes[NUMOPCODES] &&
5731+ !strcmp (insn->name, insn[1].name))
5732+ {
5733+ ++insn;
5734+ s = argsStart;
5735+ insn_error = _("illegal operands");
5736+ continue;
5737+ }
5738+ if (save_c)
5739+ *(--argsStart) = save_c;
5740+ insn_error = _("illegal operands");
5741+ return;
5742+ }
5743+}
5744+
5745+void
5746+md_assemble (char *str)
5747+{
5748+ struct riscv_cl_insn insn;
5749+
5750+ imm_expr.X_op = O_absent;
5751+ offset_expr.X_op = O_absent;
5752+ imm_reloc = BFD_RELOC_UNUSED;
5753+ offset_reloc = BFD_RELOC_UNUSED;
5754+
5755+ riscv_ip (str, &insn);
5756+
5757+ if (insn_error)
5758+ {
5759+ as_bad ("%s `%s'", insn_error, str);
5760+ return;
5761+ }
5762+
5763+ if (insn.insn_mo->pinfo == INSN_MACRO)
5764+ macro (&insn);
5765+ else
5766+ {
5767+ if (imm_expr.X_op != O_absent)
5768+ append_insn (&insn, &imm_expr, imm_reloc);
5769+ else if (offset_expr.X_op != O_absent)
5770+ append_insn (&insn, &offset_expr, offset_reloc);
5771+ else
5772+ append_insn (&insn, NULL, BFD_RELOC_UNUSED);
5773+ }
5774+}
5775+
5776+char *
5777+md_atof (int type, char *litP, int *sizeP)
5778+{
5779+ return ieee_md_atof (type, litP, sizeP, TARGET_BYTES_BIG_ENDIAN);
5780+}
5781+
5782+void
5783+md_number_to_chars (char *buf, valueT val, int n)
5784+{
5785+ number_to_chars_littleendian (buf, val, n);
5786+}
5787+
5788+const char *md_shortopts = "O::g::G:";
5789+
5790+enum options
5791+ {
5792+ OPTION_M32 = OPTION_MD_BASE,
5793+ OPTION_M64,
5794+ OPTION_MARCH,
5795+ OPTION_PIC,
5796+ OPTION_NO_PIC,
5797+ OPTION_MRVC,
5798+ OPTION_MNO_RVC,
5799+ OPTION_END_OF_ENUM
5800+ };
5801+
5802+struct option md_longopts[] =
5803+{
5804+ {"m32", no_argument, NULL, OPTION_M32},
5805+ {"m64", no_argument, NULL, OPTION_M64},
5806+ {"march", required_argument, NULL, OPTION_MARCH},
5807+ {"fPIC", no_argument, NULL, OPTION_PIC},
5808+ {"fpic", no_argument, NULL, OPTION_PIC},
5809+ {"fno-pic", no_argument, NULL, OPTION_NO_PIC},
5810+ {"mrvc", no_argument, NULL, OPTION_MRVC},
5811+ {"mno-rvc", no_argument, NULL, OPTION_MNO_RVC},
5812+
5813+ {NULL, no_argument, NULL, 0}
5814+};
5815+size_t md_longopts_size = sizeof (md_longopts);
5816+
5817+int
5818+md_parse_option (int c, char *arg)
5819+{
5820+ switch (c)
5821+ {
5822+ case OPTION_MRVC:
5823+ riscv_opts.rvc = 1;
5824+ break;
5825+
5826+ case OPTION_MNO_RVC:
5827+ riscv_opts.rvc = 0;
5828+ break;
5829+
5830+ case OPTION_M32:
5831+ rv64 = FALSE;
5832+ break;
5833+
5834+ case OPTION_M64:
5835+ rv64 = TRUE;
5836+ break;
5837+
5838+ case OPTION_MARCH:
5839+ riscv_set_arch(arg);
5840+
5841+ case OPTION_NO_PIC:
5842+ riscv_opts.pic = FALSE;
5843+ break;
5844+
5845+ case OPTION_PIC:
5846+ riscv_opts.pic = TRUE;
5847+ break;
5848+
5849+ default:
5850+ return 0;
5851+ }
5852+
5853+ return 1;
5854+}
5855+
5856+void
5857+riscv_after_parse_args (void)
5858+{
5859+ if (riscv_subsets == NULL)
5860+ riscv_set_arch("RVIMAFDXcustom");
5861+}
5862+
5863+void
5864+riscv_init_after_args (void)
5865+{
5866+ /* initialize opcodes */
5867+ bfd_riscv_num_opcodes = bfd_riscv_num_builtin_opcodes;
5868+ riscv_opcodes = (struct riscv_opcode *) riscv_builtin_opcodes;
5869+}
5870+
5871+long
5872+md_pcrel_from (fixS *fixP)
5873+{
5874+ return fixP->fx_where + fixP->fx_frag->fr_address;
5875+}
5876+
5877+/* Apply a fixup to the object file. */
5878+
5879+void
5880+md_apply_fix (fixS *fixP, valueT *valP, segT seg ATTRIBUTE_UNUSED)
5881+{
5882+ bfd_byte *buf = (bfd_byte *) (fixP->fx_frag->fr_literal + fixP->fx_where);
5883+
5884+ /* Remember value for tc_gen_reloc. */
5885+ fixP->fx_addnumber = *valP;
5886+
5887+ switch (fixP->fx_r_type)
5888+ {
5889+ case BFD_RELOC_RISCV_TLS_GOT_HI20:
5890+ case BFD_RELOC_RISCV_TLS_GD_HI20:
5891+ case BFD_RELOC_RISCV_TLS_DTPREL32:
5892+ case BFD_RELOC_RISCV_TLS_DTPREL64:
5893+ case BFD_RELOC_RISCV_TPREL_HI20:
5894+ case BFD_RELOC_RISCV_TPREL_LO12_I:
5895+ case BFD_RELOC_RISCV_TPREL_LO12_S:
5896+ case BFD_RELOC_RISCV_TPREL_ADD:
5897+ S_SET_THREAD_LOCAL (fixP->fx_addsy);
5898+ /* fall through */
5899+
5900+ case BFD_RELOC_RISCV_GOT_HI20:
5901+ case BFD_RELOC_RISCV_PCREL_HI20:
5902+ case BFD_RELOC_RISCV_HI20:
5903+ case BFD_RELOC_RISCV_LO12_I:
5904+ case BFD_RELOC_RISCV_LO12_S:
5905+ case BFD_RELOC_RISCV_ADD8:
5906+ case BFD_RELOC_RISCV_ADD16:
5907+ case BFD_RELOC_RISCV_ADD32:
5908+ case BFD_RELOC_RISCV_ADD64:
5909+ case BFD_RELOC_RISCV_SUB8:
5910+ case BFD_RELOC_RISCV_SUB16:
5911+ case BFD_RELOC_RISCV_SUB32:
5912+ case BFD_RELOC_RISCV_SUB64:
5913+ gas_assert (fixP->fx_addsy != NULL);
5914+ /* Nothing needed to do. The value comes from the reloc entry. */
5915+ break;
5916+
5917+ case BFD_RELOC_64:
5918+ case BFD_RELOC_32:
5919+ case BFD_RELOC_16:
5920+ case BFD_RELOC_8:
5921+ if (fixP->fx_addsy && fixP->fx_subsy)
5922+ {
5923+ fixP->fx_next = xmemdup (fixP, sizeof (*fixP), sizeof (*fixP));
5924+ fixP->fx_next->fx_addsy = fixP->fx_subsy;
5925+ fixP->fx_next->fx_subsy = NULL;
5926+ fixP->fx_next->fx_offset = 0;
5927+ fixP->fx_subsy = NULL;
5928+
5929+ if (fixP->fx_r_type == BFD_RELOC_64)
5930+ fixP->fx_r_type = BFD_RELOC_RISCV_ADD64,
5931+ fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB64;
5932+ else if (fixP->fx_r_type == BFD_RELOC_32)
5933+ fixP->fx_r_type = BFD_RELOC_RISCV_ADD32,
5934+ fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB32;
5935+ else if (fixP->fx_r_type == BFD_RELOC_16)
5936+ fixP->fx_r_type = BFD_RELOC_RISCV_ADD16,
5937+ fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB16;
5938+ else
5939+ fixP->fx_r_type = BFD_RELOC_RISCV_ADD8,
5940+ fixP->fx_next->fx_r_type = BFD_RELOC_RISCV_SUB8;
5941+ }
5942+ /* fall through */
5943+
5944+ case BFD_RELOC_RVA:
5945+ /* If we are deleting this reloc entry, we must fill in the
5946+ value now. This can happen if we have a .word which is not
5947+ resolved when it appears but is later defined. */
5948+ if (fixP->fx_addsy == NULL)
5949+ {
5950+ gas_assert (fixP->fx_size <= sizeof (valueT));
5951+ md_number_to_chars ((char *) buf, *valP, fixP->fx_size);
5952+ fixP->fx_done = 1;
5953+ }
5954+ break;
5955+
5956+ case BFD_RELOC_RISCV_JMP:
5957+ if (fixP->fx_addsy)
5958+ {
5959+ /* Fill in a tentative value to improve objdump readability. */
5960+ bfd_vma delta = ENCODE_UJTYPE_IMM (S_GET_VALUE (fixP->fx_addsy) + *valP);
5961+ bfd_putl32 (bfd_getl32 (buf) | delta, buf);
5962+ }
5963+ break;
5964+
5965+ case BFD_RELOC_12_PCREL:
5966+ if (fixP->fx_addsy)
5967+ {
5968+ /* Fill in a tentative value to improve objdump readability. */
5969+ bfd_vma delta = ENCODE_SBTYPE_IMM (S_GET_VALUE (fixP->fx_addsy) + *valP);
5970+ bfd_putl32 (bfd_getl32 (buf) | delta, buf);
5971+ }
5972+ break;
5973+
5974+ case BFD_RELOC_RISCV_PCREL_LO12_S:
5975+ case BFD_RELOC_RISCV_PCREL_LO12_I:
5976+ case BFD_RELOC_RISCV_CALL:
5977+ case BFD_RELOC_RISCV_CALL_PLT:
5978+ case BFD_RELOC_RISCV_ALIGN:
5979+ break;
5980+
5981+ default:
5982+ /* We ignore generic BFD relocations we don't know about. */
5983+ if (bfd_reloc_type_lookup (stdoutput, fixP->fx_r_type) != NULL)
5984+ internalError ();
5985+ }
5986+}
5987+
5988+/* This structure is used to hold a stack of .set values. */
5989+
5990+struct riscv_option_stack
5991+{
5992+ struct riscv_option_stack *next;
5993+ struct riscv_set_options options;
5994+};
5995+
5996+static struct riscv_option_stack *riscv_opts_stack;
5997+
5998+/* Handle the .set pseudo-op. */
5999+
6000+static void
6001+s_riscv_option (int x ATTRIBUTE_UNUSED)
6002+{
6003+ char *name = input_line_pointer, ch;
6004+
6005+ while (!is_end_of_line[(unsigned char) *input_line_pointer])
6006+ ++input_line_pointer;
6007+ ch = *input_line_pointer;
6008+ *input_line_pointer = '\0';
6009+
6010+ if (strcmp (name, "rvc") == 0)
6011+ riscv_opts.rvc = 1;
6012+ else if (strcmp (name, "norvc") == 0)
6013+ riscv_opts.rvc = 0;
6014+ else if (strcmp (name, "push") == 0)
6015+ {
6016+ struct riscv_option_stack *s;
6017+
6018+ s = (struct riscv_option_stack *) xmalloc (sizeof *s);
6019+ s->next = riscv_opts_stack;
6020+ s->options = riscv_opts;
6021+ riscv_opts_stack = s;
6022+ }
6023+ else if (strcmp (name, "pop") == 0)
6024+ {
6025+ struct riscv_option_stack *s;
6026+
6027+ s = riscv_opts_stack;
6028+ if (s == NULL)
6029+ as_bad (_(".option pop with no .option push"));
6030+ else
6031+ {
6032+ riscv_opts = s->options;
6033+ riscv_opts_stack = s->next;
6034+ free (s);
6035+ }
6036+ }
6037+ else
6038+ {
6039+ as_warn (_("Unrecognized .option directive: %s\n"), name);
6040+ }
6041+ *input_line_pointer = ch;
6042+ demand_empty_rest_of_line ();
6043+}
6044+
6045+/* Handle the .dtprelword and .dtpreldword pseudo-ops. They generate
6046+ a 32-bit or 64-bit DTP-relative relocation (BYTES says which) for
6047+ use in DWARF debug information. */
6048+
6049+static void
6050+s_dtprel (int bytes)
6051+{
6052+ expressionS ex;
6053+ char *p;
6054+
6055+ expression (&ex);
6056+
6057+ if (ex.X_op != O_symbol)
6058+ {
6059+ as_bad (_("Unsupported use of %s"), (bytes == 8
6060+ ? ".dtpreldword"
6061+ : ".dtprelword"));
6062+ ignore_rest_of_line ();
6063+ }
6064+
6065+ p = frag_more (bytes);
6066+ md_number_to_chars (p, 0, bytes);
6067+ fix_new_exp (frag_now, p - frag_now->fr_literal, bytes, &ex, FALSE,
6068+ (bytes == 8
6069+ ? BFD_RELOC_RISCV_TLS_DTPREL64
6070+ : BFD_RELOC_RISCV_TLS_DTPREL32));
6071+
6072+ demand_empty_rest_of_line ();
6073+}
6074+
6075+/* Handle the .bss pseudo-op. */
6076+
6077+static void
6078+s_bss (int ignore ATTRIBUTE_UNUSED)
6079+{
6080+ subseg_set (bss_section, 0);
6081+ demand_empty_rest_of_line ();
6082+}
6083+
6084+/* Align to a given power of two. */
6085+
6086+static void
6087+s_align (int x ATTRIBUTE_UNUSED)
6088+{
6089+ int alignment, fill_value = 0, fill_value_specified = 0;
6090+
6091+ alignment = get_absolute_expression ();
6092+ if (alignment < 0 || alignment > 31)
6093+ as_bad (_("unsatisfiable alignment: %d"), alignment);
6094+
6095+ if (*input_line_pointer == ',')
6096+ {
6097+ ++input_line_pointer;
6098+ fill_value = get_absolute_expression ();
6099+ fill_value_specified = 1;
6100+ }
6101+
6102+ if (!fill_value_specified && subseg_text_p (now_seg) && alignment > 2)
6103+ {
6104+ /* Emit the worst-case NOP string. The linker will delete any
6105+ unnecessary NOPs. This allows us to support code alignment
6106+ in spite of linker relaxations. */
6107+ bfd_vma i, worst_case_nop_bytes = (1L << alignment) - 4;
6108+ char *nops = frag_more (worst_case_nop_bytes);
6109+ for (i = 0; i < worst_case_nop_bytes; i += 4)
6110+ md_number_to_chars (nops + i, RISCV_NOP, 4);
6111+
6112+ expressionS ex;
6113+ ex.X_op = O_constant;
6114+ ex.X_add_number = worst_case_nop_bytes;
6115+
6116+ fix_new_exp (frag_now, nops - frag_now->fr_literal, 0,
6117+ &ex, TRUE, BFD_RELOC_RISCV_ALIGN);
6118+ }
6119+ else if (alignment)
6120+ frag_align (alignment, fill_value, 0);
6121+
6122+ record_alignment (now_seg, alignment);
6123+
6124+ demand_empty_rest_of_line ();
6125+}
6126+
6127+int
6128+md_estimate_size_before_relax (fragS *fragp, asection *segtype)
6129+{
6130+ return (fragp->fr_var = relaxed_branch_length (fragp, segtype, FALSE));
6131+}
6132+
6133+/* Translate internal representation of relocation info to BFD target
6134+ format. */
6135+
6136+arelent *
6137+tc_gen_reloc (asection *section ATTRIBUTE_UNUSED, fixS *fixp)
6138+{
6139+ arelent *reloc = (arelent *) xmalloc (sizeof (arelent));
6140+
6141+ reloc->sym_ptr_ptr = (asymbol **) xmalloc (sizeof (asymbol *));
6142+ *reloc->sym_ptr_ptr = symbol_get_bfdsym (fixp->fx_addsy);
6143+ reloc->address = fixp->fx_frag->fr_address + fixp->fx_where;
6144+
6145+ if (fixp->fx_pcrel)
6146+ /* At this point, fx_addnumber is "symbol offset - pcrel address".
6147+ Relocations want only the symbol offset. */
6148+ reloc->addend = fixp->fx_addnumber + reloc->address;
6149+ else
6150+ reloc->addend = fixp->fx_addnumber;
6151+
6152+ reloc->howto = bfd_reloc_type_lookup (stdoutput, fixp->fx_r_type);
6153+ if (reloc->howto == NULL)
6154+ {
6155+ if ((fixp->fx_r_type == BFD_RELOC_16 || fixp->fx_r_type == BFD_RELOC_8)
6156+ && fixp->fx_addsy != NULL && fixp->fx_subsy != NULL)
6157+ {
6158+ /* We don't have R_RISCV_8/16, but for this special case,
6159+ we can use R_RISCV_ADD8/16 with R_RISCV_SUB8/16. */
6160+ return reloc;
6161+ }
6162+
6163+ as_bad_where (fixp->fx_file, fixp->fx_line,
6164+ _("cannot represent %s relocation in object file"),
6165+ bfd_get_reloc_code_name (fixp->fx_r_type));
6166+ return NULL;
6167+ }
6168+
6169+ return reloc;
6170+}
6171+
6172+int
6173+riscv_relax_frag (asection *sec, fragS *fragp, long stretch ATTRIBUTE_UNUSED)
6174+{
6175+ if (RELAX_BRANCH_P (fragp->fr_subtype))
6176+ {
6177+ offsetT old_var = fragp->fr_var;
6178+ fragp->fr_var = relaxed_branch_length (fragp, sec, TRUE);
6179+ return fragp->fr_var - old_var;
6180+ }
6181+
6182+ return 0;
6183+}
6184+
6185+/* Convert a machine dependent frag. */
6186+
6187+static void
6188+md_convert_frag_branch (fragS *fragp)
6189+{
6190+ bfd_byte *buf;
6191+ insn_t insn;
6192+ expressionS exp;
6193+ fixS *fixp;
6194+
6195+ buf = (bfd_byte *)fragp->fr_literal + fragp->fr_fix;
6196+
6197+ exp.X_op = O_symbol;
6198+ exp.X_add_symbol = fragp->fr_symbol;
6199+ exp.X_add_number = fragp->fr_offset;
6200+
6201+ if (RELAX_BRANCH_TOOFAR (fragp->fr_subtype))
6202+ {
6203+ gas_assert (fragp->fr_var == 8);
6204+ /* We could relax JAL to AUIPC/JALR, but we don't do this yet. */
6205+ gas_assert (!RELAX_BRANCH_UNCOND (fragp->fr_subtype));
6206+
6207+ /* Invert the branch condition. Branch over the jump. */
6208+ insn = bfd_getl32 (buf);
6209+ insn ^= MATCH_BEQ ^ MATCH_BNE;
6210+ insn |= ENCODE_SBTYPE_IMM (8);
6211+ md_number_to_chars ((char *) buf, insn, 4);
6212+ buf += 4;
6213+
6214+ /* Jump to the target. */
6215+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
6216+ 4, &exp, FALSE, BFD_RELOC_RISCV_JMP);
6217+ md_number_to_chars ((char *) buf, MATCH_JAL, 4);
6218+ buf += 4;
6219+ }
6220+ else
6221+ {
6222+ fixp = fix_new_exp (fragp, buf - (bfd_byte *)fragp->fr_literal,
6223+ 4, &exp, FALSE, BFD_RELOC_12_PCREL);
6224+ buf += 4;
6225+ }
6226+
6227+ fixp->fx_file = fragp->fr_file;
6228+ fixp->fx_line = fragp->fr_line;
6229+ fixp->fx_pcrel = 1;
6230+
6231+ gas_assert (buf == (bfd_byte *)fragp->fr_literal
6232+ + fragp->fr_fix + fragp->fr_var);
6233+
6234+ fragp->fr_fix += fragp->fr_var;
6235+}
6236+
6237+/* Relax a machine dependent frag. This returns the amount by which
6238+ the current size of the frag should change. */
6239+
6240+void
6241+md_convert_frag (bfd *abfd ATTRIBUTE_UNUSED, segT asec ATTRIBUTE_UNUSED,
6242+ fragS *fragp)
6243+{
6244+ gas_assert (RELAX_BRANCH_P (fragp->fr_subtype));
6245+ md_convert_frag_branch (fragp);
6246+}
6247+
6248+void
6249+md_show_usage (FILE *stream)
6250+{
6251+ fprintf (stream, _("\
6252+RISC-V options:\n\
6253+ -m32 assemble RV32 code\n\
6254+ -m64 assemble RV64 code (default)\n\
6255+ -fpic generate position-independent code\n\
6256+ -fno-pic don't generate position-independent code (default)\n\
6257+"));
6258+}
6259+
6260+/* Standard calling conventions leave the CFA at SP on entry. */
6261+void
6262+riscv_cfi_frame_initial_instructions (void)
6263+{
6264+ cfi_add_CFA_def_cfa_register (X_SP);
6265+}
6266+
6267+int
6268+tc_riscv_regname_to_dw2regnum (char *regname)
6269+{
6270+ int reg;
6271+
6272+ if ((reg = reg_lookup_internal (regname, RCLASS_GPR)) >= 0)
6273+ return reg;
6274+
6275+ if ((reg = reg_lookup_internal (regname, RCLASS_FPR)) >= 0)
6276+ return reg + 32;
6277+
6278+ as_bad (_("unknown register `%s'"), regname);
6279+ return -1;
6280+}
6281+
6282+void
6283+riscv_elf_final_processing (void)
6284+{
6285+ struct riscv_subset* s;
6286+
6287+ unsigned int Xlen = 0;
6288+ for (s = riscv_subsets; s != NULL; s = s->next)
6289+ if (s->name[0] == 'X')
6290+ Xlen += strlen(s->name);
6291+
6292+ char extension[Xlen];
6293+ extension[0] = 0;
6294+ for (s = riscv_subsets; s != NULL; s = s->next)
6295+ if (s->name[0] == 'X')
6296+ strcat(extension, s->name);
6297+
6298+ EF_SET_RISCV_EXT(elf_elfheader (stdoutput)->e_flags,
6299+ riscv_elf_name_to_flag (extension));
6300+}
6301+
6302+/* Pseudo-op table. */
6303+
6304+static const pseudo_typeS riscv_pseudo_table[] =
6305+{
6306+ /* RISC-V-specific pseudo-ops. */
6307+ {"option", s_riscv_option, 0},
6308+ {"half", cons, 2},
6309+ {"word", cons, 4},
6310+ {"dword", cons, 8},
6311+ {"dtprelword", s_dtprel, 4},
6312+ {"dtpreldword", s_dtprel, 8},
6313+ {"bss", s_bss, 0},
6314+ {"align", s_align, 0},
6315+
6316+ /* leb128 doesn't work with relaxation; disallow it */
6317+ {"uleb128", s_err, 0},
6318+ {"sleb128", s_err, 0},
6319+
6320+ { NULL, NULL, 0 },
6321+};
6322+
6323+void
6324+riscv_pop_insert (void)
6325+{
6326+ extern void pop_insert (const pseudo_typeS *);
6327+
6328+ pop_insert (riscv_pseudo_table);
6329+}
6330diff -urN original-binutils/gas/config/tc-riscv.h binutils/gas/config/tc-riscv.h
6331--- original-binutils/gas/config/tc-riscv.h 1970-01-01 01:00:00.000000000 +0100
6332+++ binutils-2.25/gas/config/tc-riscv.h 2015-03-07 09:51:45.659139025 +0100
6333@@ -0,0 +1,102 @@
6334+/* tc-riscv.h -- header file for tc-riscv.c.
6335+ Copyright 2011-2014 Free Software Foundation, Inc.
6336+
6337+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
6338+ Based on MIPS target.
6339+
6340+ This file is part of GAS.
6341+
6342+ GAS is free software; you can redistribute it and/or modify
6343+ it under the terms of the GNU General Public License as published by
6344+ the Free Software Foundation; either version 3, or (at your option)
6345+ any later version.
6346+
6347+ GAS is distributed in the hope that it will be useful,
6348+ but WITHOUT ANY WARRANTY; without even the implied warranty of
6349+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6350+ GNU General Public License for more details.
6351+
6352+ You should have received a copy of the GNU General Public License
6353+ along with GAS; see the file COPYING. If not, write to the Free
6354+ Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
6355+ 02110-1301, USA. */
6356+
6357+#ifndef TC_RISCV
6358+#define TC_RISCV
6359+
6360+#include "opcode/riscv.h"
6361+
6362+struct frag;
6363+struct expressionS;
6364+
6365+#define TARGET_BYTES_BIG_ENDIAN 0
6366+
6367+#define TARGET_ARCH bfd_arch_riscv
6368+
6369+#define WORKING_DOT_WORD 1
6370+#define OLD_FLOAT_READS
6371+#define REPEAT_CONS_EXPRESSIONS
6372+#define LOCAL_LABELS_FB 1
6373+#define FAKE_LABEL_NAME ".L0 "
6374+
6375+#define md_relax_frag(segment, fragp, stretch) \
6376+ riscv_relax_frag(segment, fragp, stretch)
6377+extern int riscv_relax_frag (asection *, struct frag *, long);
6378+
6379+#define md_section_align(seg,size) (size)
6380+#define md_undefined_symbol(name) (0)
6381+#define md_operand(x)
6382+
6383+#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
6384+
6385+#define TC_SYMFIELD_TYPE int
6386+
6387+/* The ISA of the target may change based on command-line arguments. */
6388+#define TARGET_FORMAT riscv_target_format()
6389+extern const char *riscv_target_format (void);
6390+
6391+#define md_after_parse_args() riscv_after_parse_args()
6392+extern void riscv_after_parse_args (void);
6393+
6394+#define tc_init_after_args() riscv_init_after_args()
6395+extern void riscv_init_after_args (void);
6396+
6397+#define md_parse_long_option(arg) riscv_parse_long_option (arg)
6398+extern int riscv_parse_long_option (const char *);
6399+
6400+/* Let the linker resolve all the relocs due to relaxation. */
6401+#define tc_fix_adjustable(fixp) 0
6402+#define md_allow_local_subtract(l,r,s) 0
6403+
6404+/* Values passed to md_apply_fix don't include symbol values. */
6405+#define MD_APPLY_SYM_VALUE(FIX) 0
6406+
6407+/* Global syms must not be resolved, to support ELF shared libraries. */
6408+#define EXTERN_FORCE_RELOC \
6409+ (OUTPUT_FLAVOR == bfd_target_elf_flavour)
6410+
6411+#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) ((SEG)->flags & SEC_CODE)
6412+#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1
6413+#define TC_VALIDATE_FIX_SUB(FIX, SEG) 1
6414+#define TC_FORCE_RELOCATION_LOCAL(FIX) 1
6415+#define DIFF_EXPR_OK 1
6416+
6417+extern void riscv_pop_insert (void);
6418+#define md_pop_insert() riscv_pop_insert()
6419+
6420+#define TARGET_USE_CFIPOP 1
6421+
6422+#define tc_cfi_frame_initial_instructions riscv_cfi_frame_initial_instructions
6423+extern void riscv_cfi_frame_initial_instructions (void);
6424+
6425+#define tc_regname_to_dw2regnum tc_riscv_regname_to_dw2regnum
6426+extern int tc_riscv_regname_to_dw2regnum (char *regname);
6427+
6428+extern bfd_boolean rv64;
6429+#define DWARF2_DEFAULT_RETURN_COLUMN X_RA
6430+#define DWARF2_CIE_DATA_ALIGNMENT (rv64 ? 8 : 4)
6431+
6432+#define elf_tc_final_processing riscv_elf_final_processing
6433+extern void riscv_elf_final_processing (void);
6434+
6435+#endif /* TC_RISCV */
6436diff -urN original-binutils/gas/configure.tgt binutils/gas/configure.tgt
6437--- original-binutils/gas/configure.tgt 2014-10-14 09:32:03.000000000 +0200
6438+++ binutils-2.25/gas/configure.tgt 2015-03-07 09:55:02.379135671 +0100
6439@@ -86,6 +86,7 @@
6440 pj*) cpu_type=pj endian=big ;;
6441 powerpc*le*) cpu_type=ppc endian=little ;;
6442 powerpc*) cpu_type=ppc endian=big ;;
6443+ riscv*) cpu_type=riscv endian=little ;;
6444 rs6000*) cpu_type=ppc ;;
6445 rl78*) cpu_type=rl78 ;;
6446 rx) cpu_type=rx ;;
6447@@ -384,6 +385,8 @@
6448 ppc-*-kaos*) fmt=elf ;;
6449 ppc-*-lynxos*) fmt=elf em=lynx ;;
6450
6451+ riscv*-*-*) fmt=elf endian=little em=linux bfd_gas=yes ;;
6452+
6453 s390-*-linux-*) fmt=elf em=linux ;;
6454 s390-*-tpf*) fmt=elf ;;
6455
6456diff -urN original-binutils/gas/Makefile.am binutils/gas/Makefile.am
6457--- original-binutils/gas/Makefile.am 2014-10-14 09:32:02.000000000 +0200
6458+++ binutils-2.25/gas/Makefile.am 2015-03-07 09:55:02.379135671 +0100
6459@@ -171,6 +171,7 @@
6460 config/tc-pdp11.c \
6461 config/tc-pj.c \
6462 config/tc-ppc.c \
6463+ config/tc-riscv.c \
6464 config/tc-rl78.c \
6465 config/tc-rx.c \
6466 config/tc-s390.c \
6467@@ -242,6 +243,7 @@
6468 config/tc-pdp11.h \
6469 config/tc-pj.h \
6470 config/tc-ppc.h \
6471+ config/tc-riscv.h \
6472 config/tc-rl78.h \
6473 config/tc-rx.h \
6474 config/tc-s390.h \
6475diff -urN original-binutils/gas/Makefile.in binutils/gas/Makefile.in
6476--- original-binutils/gas/Makefile.in 2014-10-14 09:32:02.000000000 +0200
6477+++ binutils-2.25/gas/Makefile.in 2015-03-07 09:55:02.379135671 +0100
6478@@ -440,6 +440,7 @@
6479 config/tc-pdp11.c \
6480 config/tc-pj.c \
6481 config/tc-ppc.c \
6482+ config/tc-riscv.c \
6483 config/tc-rl78.c \
6484 config/tc-rx.c \
6485 config/tc-s390.c \
6486@@ -511,6 +512,7 @@
6487 config/tc-pdp11.h \
6488 config/tc-pj.h \
6489 config/tc-ppc.h \
6490+ config/tc-riscv.h \
6491 config/tc-rl78.h \
6492 config/tc-rx.h \
6493 config/tc-s390.h \
6494@@ -866,6 +868,7 @@
6495 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-pdp11.Po@am__quote@
6496 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-pj.Po@am__quote@
6497 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-ppc.Po@am__quote@
6498+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-riscv.Po@am__quote@
6499 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rl78.Po@am__quote@
6500 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rx.Po@am__quote@
6501 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-s390.Po@am__quote@
6502@@ -1571,6 +1574,20 @@
6503 @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
6504 @am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-ppc.obj `if test -f 'config/tc-ppc.c'; then $(CYGPATH_W) 'config/tc-ppc.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-ppc.c'; fi`
6505
6506+tc-riscv.o: config/tc-riscv.c
6507+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-riscv.o -MD -MP -MF $(DEPDIR)/tc-riscv.Tpo -c -o tc-riscv.o `test -f 'config/tc-riscv.c' || echo '$(srcdir)/'`config/tc-riscv.c
6508+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-riscv.Tpo $(DEPDIR)/tc-riscv.Po
6509+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-riscv.c' object='tc-riscv.o' libtool=no @AMDEPBACKSLASH@
6510+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
6511+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-riscv.o `test -f 'config/tc-riscv.c' || echo '$(srcdir)/'`config/tc-riscv.c
6512+
6513+tc-riscv.obj: config/tc-riscv.c
6514+@am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-riscv.obj -MD -MP -MF $(DEPDIR)/tc-riscv.Tpo -c -o tc-riscv.obj `if test -f 'config/tc-riscv.c'; then $(CYGPATH_W) 'config/tc-riscv.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-riscv.c'; fi`
6515+@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-riscv.Tpo $(DEPDIR)/tc-riscv.Po
6516+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-riscv.c' object='tc-riscv.obj' libtool=no @AMDEPBACKSLASH@
6517+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
6518+@am__fastdepCC_FALSE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o tc-riscv.obj `if test -f 'config/tc-riscv.c'; then $(CYGPATH_W) 'config/tc-riscv.c'; else $(CYGPATH_W) '$(srcdir)/config/tc-riscv.c'; fi`
6519+
6520 tc-rl78.o: config/tc-rl78.c
6521 @am__fastdepCC_TRUE@ $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT tc-rl78.o -MD -MP -MF $(DEPDIR)/tc-rl78.Tpo -c -o tc-rl78.o `test -f 'config/tc-rl78.c' || echo '$(srcdir)/'`config/tc-rl78.c
6522 @am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-rl78.Tpo $(DEPDIR)/tc-rl78.Po
6523diff -urN original-binutils/include/dis-asm.h binutils/include/dis-asm.h
6524--- original-binutils/include/dis-asm.h 2014-10-14 09:32:04.000000000 +0200
6525+++ binutils-2.25/include/dis-asm.h 2015-03-07 09:55:02.379135671 +0100
6526@@ -254,6 +254,7 @@
6527 extern int print_insn_little_mips (bfd_vma, disassemble_info *);
6528 extern int print_insn_little_nios2 (bfd_vma, disassemble_info *);
6529 extern int print_insn_little_powerpc (bfd_vma, disassemble_info *);
6530+extern int print_insn_riscv (bfd_vma, disassemble_info *);
6531 extern int print_insn_little_score (bfd_vma, disassemble_info *);
6532 extern int print_insn_lm32 (bfd_vma, disassemble_info *);
6533 extern int print_insn_m32c (bfd_vma, disassemble_info *);
6534@@ -313,6 +314,7 @@
6535 extern void print_i386_disassembler_options (FILE *);
6536 extern void print_mips_disassembler_options (FILE *);
6537 extern void print_ppc_disassembler_options (FILE *);
6538+extern void print_riscv_disassembler_options (FILE *);
6539 extern void print_arm_disassembler_options (FILE *);
6540 extern void parse_arm_disassembler_option (char *);
6541 extern void print_s390_disassembler_options (FILE *);
6542diff -urN original-binutils/include/elf/common.h binutils/include/elf/common.h
6543--- original-binutils/include/elf/common.h 2014-10-14 09:32:04.000000000 +0200
6544+++ binutils-2.25/include/elf/common.h 2015-03-07 09:55:02.383135671 +0100
6545@@ -301,6 +301,7 @@
6546 #define EM_INTEL207 207 /* Reserved by Intel */
6547 #define EM_INTEL208 208 /* Reserved by Intel */
6548 #define EM_INTEL209 209 /* Reserved by Intel */
6549+#define EM_RISCV 243 /* Reserved by Intel */
6550
6551 /* If it is necessary to assign new unofficial EM_* values, please pick large
6552 random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision
6553diff -urN original-binutils/include/elf/riscv.h binutils/include/elf/riscv.h
6554--- original-binutils/include/elf/riscv.h 1970-01-01 01:00:00.000000000 +0100
6555+++ binutils-2.25/include/elf/riscv.h 2015-03-07 09:51:45.659139025 +0100
6556@@ -0,0 +1,138 @@
6557+/* RISC-V ELF support for BFD.
6558+ Copyright 2011-2014 Free Software Foundation, Inc.
6559+
6560+ Contributed by Andrw Waterman <waterman@cs.berkeley.edu> at UC Berkeley.
6561+ Based on MIPS ELF support for BFD, by Ian Lance Taylor.
6562+
6563+ This file is part of BFD, the Binary File Descriptor library.
6564+
6565+ This program is free software; you can redistribute it and/or modify
6566+ it under the terms of the GNU General Public License as published by
6567+ the Free Software Foundation; either version 3 of the License, or
6568+ (at your option) any later version.
6569+
6570+ This program is distributed in the hope that it will be useful,
6571+ but WITHOUT ANY WARRANTY; without even the implied warranty of
6572+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
6573+ GNU General Public License for more details.
6574+
6575+ You should have received a copy of the GNU General Public License
6576+ along with this program; if not, write to the Free Software
6577+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
6578+ MA 02110-1301, USA. */
6579+
6580+/* This file holds definitions specific to the RISCV ELF ABI. Note
6581+ that most of this is not actually implemented by BFD. */
6582+
6583+#ifndef _ELF_RISCV_H
6584+#define _ELF_RISCV_H
6585+
6586+#include "elf/reloc-macros.h"
6587+
6588+/* Relocation types. */
6589+START_RELOC_NUMBERS (elf_riscv_reloc_type)
6590+ /* Relocation types used by the dynamic linker. */
6591+ RELOC_NUMBER (R_RISCV_NONE, 0)
6592+ RELOC_NUMBER (R_RISCV_32, 1)
6593+ RELOC_NUMBER (R_RISCV_64, 2)
6594+ RELOC_NUMBER (R_RISCV_RELATIVE, 3)
6595+ RELOC_NUMBER (R_RISCV_COPY, 4)
6596+ RELOC_NUMBER (R_RISCV_JUMP_SLOT, 5)
6597+ RELOC_NUMBER (R_RISCV_TLS_DTPMOD32, 6)
6598+ RELOC_NUMBER (R_RISCV_TLS_DTPMOD64, 7)
6599+ RELOC_NUMBER (R_RISCV_TLS_DTPREL32, 8)
6600+ RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 9)
6601+ RELOC_NUMBER (R_RISCV_TLS_TPREL32, 10)
6602+ RELOC_NUMBER (R_RISCV_TLS_TPREL64, 11)
6603+
6604+ /* Relocation types not used by the dynamic linker. */
6605+ RELOC_NUMBER (R_RISCV_BRANCH, 16)
6606+ RELOC_NUMBER (R_RISCV_JAL, 17)
6607+ RELOC_NUMBER (R_RISCV_CALL, 18)
6608+ RELOC_NUMBER (R_RISCV_CALL_PLT, 19)
6609+ RELOC_NUMBER (R_RISCV_GOT_HI20, 20)
6610+ RELOC_NUMBER (R_RISCV_TLS_GOT_HI20, 21)
6611+ RELOC_NUMBER (R_RISCV_TLS_GD_HI20, 22)
6612+ RELOC_NUMBER (R_RISCV_PCREL_HI20, 23)
6613+ RELOC_NUMBER (R_RISCV_PCREL_LO12_I, 24)
6614+ RELOC_NUMBER (R_RISCV_PCREL_LO12_S, 25)
6615+ RELOC_NUMBER (R_RISCV_HI20, 26)
6616+ RELOC_NUMBER (R_RISCV_LO12_I, 27)
6617+ RELOC_NUMBER (R_RISCV_LO12_S, 28)
6618+ RELOC_NUMBER (R_RISCV_TPREL_HI20, 29)
6619+ RELOC_NUMBER (R_RISCV_TPREL_LO12_I, 30)
6620+ RELOC_NUMBER (R_RISCV_TPREL_LO12_S, 31)
6621+ RELOC_NUMBER (R_RISCV_TPREL_ADD, 32)
6622+ RELOC_NUMBER (R_RISCV_ADD8, 33)
6623+ RELOC_NUMBER (R_RISCV_ADD16, 34)
6624+ RELOC_NUMBER (R_RISCV_ADD32, 35)
6625+ RELOC_NUMBER (R_RISCV_ADD64, 36)
6626+ RELOC_NUMBER (R_RISCV_SUB8, 37)
6627+ RELOC_NUMBER (R_RISCV_SUB16, 38)
6628+ RELOC_NUMBER (R_RISCV_SUB32, 39)
6629+ RELOC_NUMBER (R_RISCV_SUB64, 40)
6630+ RELOC_NUMBER (R_RISCV_GNU_VTINHERIT, 41)
6631+ RELOC_NUMBER (R_RISCV_GNU_VTENTRY, 42)
6632+ RELOC_NUMBER (R_RISCV_ALIGN, 43)
6633+END_RELOC_NUMBERS (R_RISCV_max)
6634+
6635+/* Processor specific flags for the ELF header e_flags field. */
6636+
6637+/* Custom flag definitions. */
6638+
6639+#define EF_RISCV_EXT_MASK 0xffff
6640+#define EF_RISCV_EXT_SH 16
6641+#define E_RISCV_EXT_Xcustom 0x0000
6642+#define E_RISCV_EXT_Xhwacha 0x0001
6643+#define E_RISCV_EXT_RESERVED 0xffff
6644+
6645+#define EF_GET_RISCV_EXT(x) \
6646+ ((x >> EF_RISCV_EXT_SH) & EF_RISCV_EXT_MASK)
6647+
6648+#define EF_SET_RISCV_EXT(x, ext) \
6649+ do { x |= ((ext & EF_RISCV_EXT_MASK) << EF_RISCV_EXT_SH); } while (0)
6650+
6651+#define EF_IS_RISCV_EXT_Xcustom(x) \
6652+ (EF_GET_RISCV_EXT(x) == E_RISCV_EXT_Xcustom)
6653+
6654+/* A mapping from extension names to elf flags */
6655+
6656+struct riscv_extension_entry
6657+{
6658+ const char* name;
6659+ unsigned int flag;
6660+};
6661+
6662+static const struct riscv_extension_entry riscv_extension_map[] =
6663+{
6664+ {"Xcustom", E_RISCV_EXT_Xcustom},
6665+ {"Xhwacha", E_RISCV_EXT_Xhwacha},
6666+};
6667+
6668+/* Given an extension name, return an elf flag. */
6669+
6670+static inline const char* riscv_elf_flag_to_name(unsigned int flag)
6671+{
6672+ unsigned int i;
6673+
6674+ for (i=0; i<sizeof(riscv_extension_map)/sizeof(riscv_extension_map[0]); i++)
6675+ if (riscv_extension_map[i].flag == flag)
6676+ return riscv_extension_map[i].name;
6677+
6678+ return NULL;
6679+}
6680+
6681+/* Given an elf flag, return an extension name. */
6682+
6683+static inline unsigned int riscv_elf_name_to_flag(const char* name)
6684+{
6685+ unsigned int i;
6686+
6687+ for (i=0; i<sizeof(riscv_extension_map)/sizeof(riscv_extension_map[0]); i++)
6688+ if (strcmp(riscv_extension_map[i].name, name) == 0)
6689+ return riscv_extension_map[i].flag;
6690+
6691+ return E_RISCV_EXT_Xcustom;
6692+}
6693+
6694+#endif /* _ELF_RISCV_H */
6695diff -urN original-binutils/include/opcode/riscv.h binutils/include/opcode/riscv.h
6696--- original-binutils/include/opcode/riscv.h 1970-01-01 01:00:00.000000000 +0100
6697+++ binutils-2.25/include/opcode/riscv.h 2015-03-07 09:51:45.659139025 +0100
6698@@ -0,0 +1,320 @@
6699+/* riscv.h. RISC-V opcode list for GDB, the GNU debugger.
6700+ Copyright 2011
6701+ Free Software Foundation, Inc.
6702+ Contributed by Andrew Waterman
6703+
6704+This file is part of GDB, GAS, and the GNU binutils.
6705+
6706+GDB, GAS, and the GNU binutils are free software; you can redistribute
6707+them and/or modify them under the terms of the GNU General Public
6708+License as published by the Free Software Foundation; either version
6709+1, or (at your option) any later version.
6710+
6711+GDB, GAS, and the GNU binutils are distributed in the hope that they
6712+will be useful, but WITHOUT ANY WARRANTY; without even the implied
6713+warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
6714+the GNU General Public License for more details.
6715+
6716+You should have received a copy of the GNU General Public License
6717+along with this file; see the file COPYING. If not, write to the Free
6718+Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
6719+
6720+#ifndef _RISCV_H_
6721+#define _RISCV_H_
6722+
6723+#include "riscv-opc.h"
6724+#include <stdlib.h>
6725+#include <stdint.h>
6726+
6727+/* RVC fields */
6728+
6729+#define OP_MASK_CRD 0x1f
6730+#define OP_SH_CRD 5
6731+#define OP_MASK_CRS2 0x1f
6732+#define OP_SH_CRS2 5
6733+#define OP_MASK_CRS1 0x1f
6734+#define OP_SH_CRS1 10
6735+#define OP_MASK_CRDS 0x7
6736+#define OP_SH_CRDS 13
6737+#define OP_MASK_CRS2S 0x7
6738+#define OP_SH_CRS2S 13
6739+#define OP_MASK_CRS2BS 0x7
6740+#define OP_SH_CRS2BS 5
6741+#define OP_MASK_CRS1S 0x7
6742+#define OP_SH_CRS1S 10
6743+#define OP_MASK_CIMM6 0x3f
6744+#define OP_SH_CIMM6 10
6745+#define OP_MASK_CIMM5 0x1f
6746+#define OP_SH_CIMM5 5
6747+#define OP_MASK_CIMM10 0x3ff
6748+#define OP_SH_CIMM10 5
6749+
6750+static const char rvc_rs1_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 7 };
6751+#define rvc_rd_regmap rvc_rs1_regmap
6752+#define rvc_rs2b_regmap rvc_rs1_regmap
6753+static const char rvc_rs2_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 0 };
6754+
6755+typedef uint64_t insn_t;
6756+
6757+static inline unsigned int riscv_insn_length (insn_t insn)
6758+{
6759+ if ((insn & 0x3) != 3) /* RVC */
6760+ return 2;
6761+ if ((insn & 0x1f) != 0x1f) /* base ISA and extensions in 32-bit space */
6762+ return 4;
6763+ if ((insn & 0x3f) == 0x1f) /* 48-bit extensions */
6764+ return 6;
6765+ if ((insn & 0x7f) == 0x3f) /* 64-bit extensions */
6766+ return 8;
6767+ /* longer instructions not supported at the moment */
6768+ return 2;
6769+}
6770+
6771+static const char * const riscv_rm[8] = {
6772+ "rne", "rtz", "rdn", "rup", "rmm", 0, 0, "dyn"
6773+};
6774+static const char* const riscv_pred_succ[16] = {
6775+ 0, "w", "r", "rw", "o", "ow", "or", "orw",
6776+ "i", "iw", "ir", "irw", "io", "iow", "ior", "iorw",
6777+};
6778+
6779+#define RVC_JUMP_BITS 10
6780+#define RVC_JUMP_ALIGN_BITS 1
6781+#define RVC_JUMP_ALIGN (1 << RVC_JUMP_ALIGN_BITS)
6782+#define RVC_JUMP_REACH ((1ULL<<RVC_JUMP_BITS)*RVC_JUMP_ALIGN)
6783+
6784+#define RVC_BRANCH_BITS 5
6785+#define RVC_BRANCH_ALIGN_BITS RVC_JUMP_ALIGN_BITS
6786+#define RVC_BRANCH_ALIGN (1 << RVC_BRANCH_ALIGN_BITS)
6787+#define RVC_BRANCH_REACH ((1ULL<<RVC_BRANCH_BITS)*RVC_BRANCH_ALIGN)
6788+
6789+#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
6790+#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
6791+
6792+#define EXTRACT_ITYPE_IMM(x) \
6793+ (RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
6794+#define EXTRACT_STYPE_IMM(x) \
6795+ (RV_X(x, 7, 5) | (RV_X(x, 25, 7) << 5) | (RV_IMM_SIGN(x) << 12))
6796+#define EXTRACT_SBTYPE_IMM(x) \
6797+ ((RV_X(x, 8, 4) << 1) | (RV_X(x, 25, 6) << 5) | (RV_X(x, 7, 1) << 11) | (RV_IMM_SIGN(x) << 12))
6798+#define EXTRACT_UTYPE_IMM(x) \
6799+ ((RV_X(x, 12, 20) << 12) | (RV_IMM_SIGN(x) << 32))
6800+#define EXTRACT_UJTYPE_IMM(x) \
6801+ ((RV_X(x, 21, 10) << 1) | (RV_X(x, 20, 1) << 11) | (RV_X(x, 12, 8) << 12) | (RV_IMM_SIGN(x) << 20))
6802+
6803+#define ENCODE_ITYPE_IMM(x) \
6804+ (RV_X(x, 0, 12) << 20)
6805+#define ENCODE_STYPE_IMM(x) \
6806+ ((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25))
6807+#define ENCODE_SBTYPE_IMM(x) \
6808+ ((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31))
6809+#define ENCODE_UTYPE_IMM(x) \
6810+ (RV_X(x, 12, 20) << 12)
6811+#define ENCODE_UJTYPE_IMM(x) \
6812+ ((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31))
6813+
6814+#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
6815+#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
6816+#define VALID_SBTYPE_IMM(x) (EXTRACT_SBTYPE_IMM(ENCODE_SBTYPE_IMM(x)) == (x))
6817+#define VALID_UTYPE_IMM(x) (EXTRACT_UTYPE_IMM(ENCODE_UTYPE_IMM(x)) == (x))
6818+#define VALID_UJTYPE_IMM(x) (EXTRACT_UJTYPE_IMM(ENCODE_UJTYPE_IMM(x)) == (x))
6819+
6820+#define RISCV_RTYPE(insn, rd, rs1, rs2) \
6821+ ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
6822+#define RISCV_ITYPE(insn, rd, rs1, imm) \
6823+ ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm))
6824+#define RISCV_STYPE(insn, rs1, rs2, imm) \
6825+ ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm))
6826+#define RISCV_SBTYPE(insn, rs1, rs2, target) \
6827+ ((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target))
6828+#define RISCV_UTYPE(insn, rd, bigimm) \
6829+ ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm))
6830+#define RISCV_UJTYPE(insn, rd, target) \
6831+ ((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target))
6832+
6833+#define RISCV_NOP RISCV_ITYPE(ADDI, 0, 0, 0)
6834+
6835+#define RISCV_CONST_HIGH_PART(VALUE) \
6836+ (((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
6837+#define RISCV_CONST_LOW_PART(VALUE) ((VALUE) - RISCV_CONST_HIGH_PART (VALUE))
6838+#define RISCV_PCREL_HIGH_PART(VALUE, PC) RISCV_CONST_HIGH_PART((VALUE) - (PC))
6839+#define RISCV_PCREL_LOW_PART(VALUE, PC) RISCV_CONST_LOW_PART((VALUE) - (PC))
6840+
6841+/* RV fields */
6842+
6843+#define OP_MASK_OP 0x7f
6844+#define OP_SH_OP 0
6845+#define OP_MASK_RS2 0x1f
6846+#define OP_SH_RS2 20
6847+#define OP_MASK_RS1 0x1f
6848+#define OP_SH_RS1 15
6849+#define OP_MASK_RS3 0x1f
6850+#define OP_SH_RS3 27
6851+#define OP_MASK_RD 0x1f
6852+#define OP_SH_RD 7
6853+#define OP_MASK_SHAMT 0x3f
6854+#define OP_SH_SHAMT 20
6855+#define OP_MASK_SHAMTW 0x1f
6856+#define OP_SH_SHAMTW 20
6857+#define OP_MASK_RM 0x7
6858+#define OP_SH_RM 12
6859+#define OP_MASK_PRED 0xf
6860+#define OP_SH_PRED 24
6861+#define OP_MASK_SUCC 0xf
6862+#define OP_SH_SUCC 20
6863+#define OP_MASK_AQ 0x1
6864+#define OP_SH_AQ 26
6865+#define OP_MASK_RL 0x1
6866+#define OP_SH_RL 25
6867+
6868+#define OP_MASK_VRD 0x1f
6869+#define OP_SH_VRD 7
6870+#define OP_MASK_VRS 0x1f
6871+#define OP_SH_VRS 15
6872+#define OP_MASK_VRT 0x1f
6873+#define OP_SH_VRT 20
6874+#define OP_MASK_VRR 0x1f
6875+#define OP_SH_VRR 27
6876+
6877+#define OP_MASK_VFD 0x1f
6878+#define OP_SH_VFD 7
6879+#define OP_MASK_VFS 0x1f
6880+#define OP_SH_VFS 15
6881+#define OP_MASK_VFT 0x1f
6882+#define OP_SH_VFT 20
6883+#define OP_MASK_VFR 0x1f
6884+#define OP_SH_VFR 27
6885+
6886+#define OP_MASK_IMMNGPR 0x3f
6887+#define OP_SH_IMMNGPR 20
6888+#define OP_MASK_IMMNFPR 0x3f
6889+#define OP_SH_IMMNFPR 26
6890+#define OP_MASK_IMMSEGNELM 0x7
6891+#define OP_SH_IMMSEGNELM 29
6892+#define OP_MASK_CUSTOM_IMM 0x7f
6893+#define OP_SH_CUSTOM_IMM 25
6894+#define OP_MASK_CSR 0xfff
6895+#define OP_SH_CSR 20
6896+
6897+#define X_RA 1
6898+#define X_SP 2
6899+#define X_GP 3
6900+#define X_TP 4
6901+#define X_T0 5
6902+#define X_T1 6
6903+#define X_T2 7
6904+#define X_T3 28
6905+
6906+#define NGPR 32
6907+#define NFPR 32
6908+#define NVGPR 32
6909+#define NVFPR 32
6910+
6911+#define RISCV_JUMP_BITS RISCV_BIGIMM_BITS
6912+#define RISCV_JUMP_ALIGN_BITS 1
6913+#define RISCV_JUMP_ALIGN (1 << RISCV_JUMP_ALIGN_BITS)
6914+#define RISCV_JUMP_REACH ((1ULL<<RISCV_JUMP_BITS)*RISCV_JUMP_ALIGN)
6915+
6916+#define RISCV_IMM_BITS 12
6917+#define RISCV_BIGIMM_BITS (32-RISCV_IMM_BITS)
6918+#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
6919+#define RISCV_BIGIMM_REACH (1LL<<RISCV_BIGIMM_BITS)
6920+#define RISCV_BRANCH_BITS RISCV_IMM_BITS
6921+#define RISCV_BRANCH_ALIGN_BITS RISCV_JUMP_ALIGN_BITS
6922+#define RISCV_BRANCH_ALIGN (1 << RISCV_BRANCH_ALIGN_BITS)
6923+#define RISCV_BRANCH_REACH (RISCV_IMM_REACH*RISCV_BRANCH_ALIGN)
6924+
6925+/* This structure holds information for a particular instruction. */
6926+
6927+struct riscv_opcode
6928+{
6929+ /* The name of the instruction. */
6930+ const char *name;
6931+ /* The ISA subset name (I, M, A, F, D, Xextension). */
6932+ const char *subset;
6933+ /* A string describing the arguments for this instruction. */
6934+ const char *args;
6935+ /* The basic opcode for the instruction. When assembling, this
6936+ opcode is modified by the arguments to produce the actual opcode
6937+ that is used. If pinfo is INSN_MACRO, then this is 0. */
6938+ insn_t match;
6939+ /* If pinfo is not INSN_MACRO, then this is a bit mask for the
6940+ relevant portions of the opcode when disassembling. If the
6941+ actual opcode anded with the match field equals the opcode field,
6942+ then we have found the correct instruction. If pinfo is
6943+ INSN_MACRO, then this field is the macro identifier. */
6944+ insn_t mask;
6945+ /* A function to determine if a word corresponds to this instruction.
6946+ Usually, this computes ((word & mask) == match). */
6947+ int (*match_func)(const struct riscv_opcode *op, insn_t word);
6948+ /* For a macro, this is INSN_MACRO. Otherwise, it is a collection
6949+ of bits describing the instruction, notably any relevant hazard
6950+ information. */
6951+ unsigned long pinfo;
6952+};
6953+
6954+#define INSN_WRITE_GPR_D 0x00000001
6955+#define INSN_WRITE_GPR_RA 0x00000004
6956+#define INSN_WRITE_FPR_D 0x00000008
6957+#define INSN_READ_GPR_S 0x00000040
6958+#define INSN_READ_GPR_T 0x00000080
6959+#define INSN_READ_FPR_S 0x00000100
6960+#define INSN_READ_FPR_T 0x00000200
6961+#define INSN_READ_FPR_R 0x00000400
6962+/* Instruction is a simple alias (I.E. "move" for daddu/addu/or) */
6963+#define INSN_ALIAS 0x00001000
6964+/* Instruction is actually a macro. It should be ignored by the
6965+ disassembler, and requires special treatment by the assembler. */
6966+#define INSN_MACRO 0xffffffff
6967+
6968+/* This is a list of macro expanded instructions.
6969+
6970+ _I appended means immediate
6971+ _A appended means address
6972+ _AB appended means address with base register
6973+ _D appended means 64 bit floating point constant
6974+ _S appended means 32 bit floating point constant. */
6975+
6976+enum
6977+{
6978+ M_LA,
6979+ M_LLA,
6980+ M_LA_TLS_GD,
6981+ M_LA_TLS_IE,
6982+ M_LB,
6983+ M_LBU,
6984+ M_LH,
6985+ M_LHU,
6986+ M_LW,
6987+ M_LWU,
6988+ M_LD,
6989+ M_SB,
6990+ M_SH,
6991+ M_SW,
6992+ M_SD,
6993+ M_FLW,
6994+ M_FLD,
6995+ M_FSW,
6996+ M_FSD,
6997+ M_CALL,
6998+ M_J,
6999+ M_LI,
7000+ M_VF,
7001+ M_NUM_MACROS
7002+};
7003+
7004+
7005+extern const char * const riscv_gpr_names_numeric[NGPR];
7006+extern const char * const riscv_gpr_names_abi[NGPR];
7007+extern const char * const riscv_fpr_names_numeric[NFPR];
7008+extern const char * const riscv_fpr_names_abi[NFPR];
7009+extern const char * const riscv_vec_gpr_names[NVGPR];
7010+extern const char * const riscv_vec_fpr_names[NVFPR];
7011+
7012+extern const struct riscv_opcode riscv_builtin_opcodes[];
7013+extern const int bfd_riscv_num_builtin_opcodes;
7014+extern struct riscv_opcode *riscv_opcodes;
7015+extern int bfd_riscv_num_opcodes;
7016+#define NUMOPCODES bfd_riscv_num_opcodes
7017+
7018+#endif /* _RISCV_H_ */
7019diff -urN original-binutils/include/opcode/riscv-opc.h binutils/include/opcode/riscv-opc.h
7020--- original-binutils/include/opcode/riscv-opc.h 1970-01-01 01:00:00.000000000 +0100
7021+++ binutils-2.25/include/opcode/riscv-opc.h 2015-03-07 09:51:45.659139025 +0100
7022@@ -0,0 +1,1216 @@
7023+/* Automatically generated by parse-opcodes */
7024+#ifndef RISCV_ENCODING_H
7025+#define RISCV_ENCODING_H
7026+#define MATCH_CUSTOM3_RD_RS1_RS2 0x707b
7027+#define MASK_CUSTOM3_RD_RS1_RS2 0x707f
7028+#define MATCH_VLSEGSTWU 0xc00305b
7029+#define MASK_VLSEGSTWU 0x1e00707f
7030+#define MATCH_C_LW0 0x12
7031+#define MASK_C_LW0 0x801f
7032+#define MATCH_FMV_D_X 0xf2000053
7033+#define MASK_FMV_D_X 0xfff0707f
7034+#define MATCH_VLH 0x200205b
7035+#define MASK_VLH 0xfff0707f
7036+#define MATCH_C_LI 0x0
7037+#define MASK_C_LI 0x1f
7038+#define MATCH_FADD_D 0x2000053
7039+#define MASK_FADD_D 0xfe00007f
7040+#define MATCH_C_LD 0x9
7041+#define MASK_C_LD 0x1f
7042+#define MATCH_VLD 0x600205b
7043+#define MASK_VLD 0xfff0707f
7044+#define MATCH_FADD_S 0x53
7045+#define MASK_FADD_S 0xfe00007f
7046+#define MATCH_C_LW 0xa
7047+#define MASK_C_LW 0x1f
7048+#define MATCH_VLW 0x400205b
7049+#define MASK_VLW 0xfff0707f
7050+#define MATCH_VSSEGSTW 0x400307b
7051+#define MASK_VSSEGSTW 0x1e00707f
7052+#define MATCH_UTIDX 0x6077
7053+#define MASK_UTIDX 0xfffff07f
7054+#define MATCH_C_FLW 0x14
7055+#define MASK_C_FLW 0x1f
7056+#define MATCH_FSUB_D 0xa000053
7057+#define MASK_FSUB_D 0xfe00007f
7058+#define MATCH_VSSEGSTD 0x600307b
7059+#define MASK_VSSEGSTD 0x1e00707f
7060+#define MATCH_VSSEGSTB 0x307b
7061+#define MASK_VSSEGSTB 0x1e00707f
7062+#define MATCH_DIV 0x2004033
7063+#define MASK_DIV 0xfe00707f
7064+#define MATCH_FMV_H_X 0xf4000053
7065+#define MASK_FMV_H_X 0xfff0707f
7066+#define MATCH_C_FLD 0x15
7067+#define MASK_C_FLD 0x1f
7068+#define MATCH_FRRM 0x202073
7069+#define MASK_FRRM 0xfffff07f
7070+#define MATCH_VFMSV_S 0x1000202b
7071+#define MASK_VFMSV_S 0xfff0707f
7072+#define MATCH_C_LWSP 0x5
7073+#define MASK_C_LWSP 0x1f
7074+#define MATCH_FENCE 0xf
7075+#define MASK_FENCE 0x707f
7076+#define MATCH_FNMSUB_S 0x4b
7077+#define MASK_FNMSUB_S 0x600007f
7078+#define MATCH_FLE_S 0xa0000053
7079+#define MASK_FLE_S 0xfe00707f
7080+#define MATCH_FNMSUB_H 0x400004b
7081+#define MASK_FNMSUB_H 0x600007f
7082+#define MATCH_FLE_H 0xbc000053
7083+#define MASK_FLE_H 0xfe00707f
7084+#define MATCH_FLW 0x2007
7085+#define MASK_FLW 0x707f
7086+#define MATCH_VSETVL 0x600b
7087+#define MASK_VSETVL 0xfff0707f
7088+#define MATCH_VFMSV_D 0x1200202b
7089+#define MASK_VFMSV_D 0xfff0707f
7090+#define MATCH_FLE_D 0xa2000053
7091+#define MASK_FLE_D 0xfe00707f
7092+#define MATCH_FENCE_I 0x100f
7093+#define MASK_FENCE_I 0x707f
7094+#define MATCH_FNMSUB_D 0x200004b
7095+#define MASK_FNMSUB_D 0x600007f
7096+#define MATCH_ADDW 0x3b
7097+#define MASK_ADDW 0xfe00707f
7098+#define MATCH_XOR 0x4033
7099+#define MASK_XOR 0xfe00707f
7100+#define MATCH_SUB 0x40000033
7101+#define MASK_SUB 0xfe00707f
7102+#define MATCH_VSSTW 0x400307b
7103+#define MASK_VSSTW 0xfe00707f
7104+#define MATCH_VSSTH 0x200307b
7105+#define MASK_VSSTH 0xfe00707f
7106+#define MATCH_SC_W 0x1800202f
7107+#define MASK_SC_W 0xf800707f
7108+#define MATCH_VSSTB 0x307b
7109+#define MASK_VSSTB 0xfe00707f
7110+#define MATCH_VSSTD 0x600307b
7111+#define MASK_VSSTD 0xfe00707f
7112+#define MATCH_ADDI 0x13
7113+#define MASK_ADDI 0x707f
7114+#define MATCH_RDTIMEH 0xc8102073
7115+#define MASK_RDTIMEH 0xfffff07f
7116+#define MATCH_MULH 0x2001033
7117+#define MASK_MULH 0xfe00707f
7118+#define MATCH_CSRRSI 0x6073
7119+#define MASK_CSRRSI 0x707f
7120+#define MATCH_FCVT_D_WU 0xd2100053
7121+#define MASK_FCVT_D_WU 0xfff0007f
7122+#define MATCH_MULW 0x200003b
7123+#define MASK_MULW 0xfe00707f
7124+#define MATCH_CUSTOM1_RD_RS1_RS2 0x702b
7125+#define MASK_CUSTOM1_RD_RS1_RS2 0x707f
7126+#define MATCH_VENQIMM1 0xc00302b
7127+#define MASK_VENQIMM1 0xfe007fff
7128+#define MATCH_VENQIMM2 0xe00302b
7129+#define MASK_VENQIMM2 0xfe007fff
7130+#define MATCH_RDINSTRET 0xc0202073
7131+#define MASK_RDINSTRET 0xfffff07f
7132+#define MATCH_C_SWSP 0x8
7133+#define MASK_C_SWSP 0x1f
7134+#define MATCH_VLSTW 0x400305b
7135+#define MASK_VLSTW 0xfe00707f
7136+#define MATCH_VLSTH 0x200305b
7137+#define MASK_VLSTH 0xfe00707f
7138+#define MATCH_VLSTB 0x305b
7139+#define MASK_VLSTB 0xfe00707f
7140+#define MATCH_VLSTD 0x600305b
7141+#define MASK_VLSTD 0xfe00707f
7142+#define MATCH_ANDI 0x7013
7143+#define MASK_ANDI 0x707f
7144+#define MATCH_FMV_X_S 0xe0000053
7145+#define MASK_FMV_X_S 0xfff0707f
7146+#define MATCH_CUSTOM0_RD_RS1_RS2 0x700b
7147+#define MASK_CUSTOM0_RD_RS1_RS2 0x707f
7148+#define MATCH_FNMADD_S 0x4f
7149+#define MASK_FNMADD_S 0x600007f
7150+#define MATCH_LWU 0x6003
7151+#define MASK_LWU 0x707f
7152+#define MATCH_CUSTOM0_RS1 0x200b
7153+#define MASK_CUSTOM0_RS1 0x707f
7154+#define MATCH_VLSEGSTBU 0x800305b
7155+#define MASK_VLSEGSTBU 0x1e00707f
7156+#define MATCH_FNMADD_D 0x200004f
7157+#define MASK_FNMADD_D 0x600007f
7158+#define MATCH_FCVT_W_S 0xc0000053
7159+#define MASK_FCVT_W_S 0xfff0007f
7160+#define MATCH_C_SRAI 0x1019
7161+#define MASK_C_SRAI 0x1c1f
7162+#define MATCH_MULHSU 0x2002033
7163+#define MASK_MULHSU 0xfe00707f
7164+#define MATCH_FCVT_D_LU 0xd2300053
7165+#define MASK_FCVT_D_LU 0xfff0007f
7166+#define MATCH_FCVT_W_D 0xc2000053
7167+#define MASK_FCVT_W_D 0xfff0007f
7168+#define MATCH_FSUB_H 0xc000053
7169+#define MASK_FSUB_H 0xfe00007f
7170+#define MATCH_DIVUW 0x200503b
7171+#define MASK_DIVUW 0xfe00707f
7172+#define MATCH_SLTI 0x2013
7173+#define MASK_SLTI 0x707f
7174+#define MATCH_VLSTBU 0x800305b
7175+#define MASK_VLSTBU 0xfe00707f
7176+#define MATCH_SLTU 0x3033
7177+#define MASK_SLTU 0xfe00707f
7178+#define MATCH_FLH 0x1007
7179+#define MASK_FLH 0x707f
7180+#define MATCH_CUSTOM2_RD_RS1_RS2 0x705b
7181+#define MASK_CUSTOM2_RD_RS1_RS2 0x707f
7182+#define MATCH_FLD 0x3007
7183+#define MASK_FLD 0x707f
7184+#define MATCH_FSUB_S 0x8000053
7185+#define MASK_FSUB_S 0xfe00007f
7186+#define MATCH_FCVT_H_LU 0x6c000053
7187+#define MASK_FCVT_H_LU 0xfff0007f
7188+#define MATCH_CUSTOM0 0xb
7189+#define MASK_CUSTOM0 0x707f
7190+#define MATCH_CUSTOM1 0x2b
7191+#define MASK_CUSTOM1 0x707f
7192+#define MATCH_CUSTOM2 0x5b
7193+#define MASK_CUSTOM2 0x707f
7194+#define MATCH_CUSTOM3 0x7b
7195+#define MASK_CUSTOM3 0x707f
7196+#define MATCH_VXCPTSAVE 0x302b
7197+#define MASK_VXCPTSAVE 0xfff07fff
7198+#define MATCH_VMSV 0x200202b
7199+#define MASK_VMSV 0xfff0707f
7200+#define MATCH_FCVT_LU_S 0xc0300053
7201+#define MASK_FCVT_LU_S 0xfff0007f
7202+#define MATCH_AUIPC 0x17
7203+#define MASK_AUIPC 0x7f
7204+#define MATCH_FRFLAGS 0x102073
7205+#define MASK_FRFLAGS 0xfffff07f
7206+#define MATCH_FCVT_LU_D 0xc2300053
7207+#define MASK_FCVT_LU_D 0xfff0007f
7208+#define MATCH_CSRRWI 0x5073
7209+#define MASK_CSRRWI 0x707f
7210+#define MATCH_FADD_H 0x4000053
7211+#define MASK_FADD_H 0xfe00007f
7212+#define MATCH_FSQRT_S 0x58000053
7213+#define MASK_FSQRT_S 0xfff0007f
7214+#define MATCH_VXCPTKILL 0x400302b
7215+#define MASK_VXCPTKILL 0xffffffff
7216+#define MATCH_STOP 0x5077
7217+#define MASK_STOP 0xffffffff
7218+#define MATCH_FSGNJN_S 0x20001053
7219+#define MASK_FSGNJN_S 0xfe00707f
7220+#define MATCH_FSGNJN_H 0x34000053
7221+#define MASK_FSGNJN_H 0xfe00707f
7222+#define MATCH_FSQRT_D 0x5a000053
7223+#define MASK_FSQRT_D 0xfff0007f
7224+#define MATCH_XORI 0x4013
7225+#define MASK_XORI 0x707f
7226+#define MATCH_DIVU 0x2005033
7227+#define MASK_DIVU 0xfe00707f
7228+#define MATCH_FSGNJN_D 0x22001053
7229+#define MASK_FSGNJN_D 0xfe00707f
7230+#define MATCH_FSQRT_H 0x24000053
7231+#define MASK_FSQRT_H 0xfff0007f
7232+#define MATCH_VSSEGSTH 0x200307b
7233+#define MASK_VSSEGSTH 0x1e00707f
7234+#define MATCH_SW 0x2023
7235+#define MASK_SW 0x707f
7236+#define MATCH_VLSTWU 0xc00305b
7237+#define MASK_VLSTWU 0xfe00707f
7238+#define MATCH_VFSSEGW 0x1400207b
7239+#define MASK_VFSSEGW 0x1ff0707f
7240+#define MATCH_LHU 0x5003
7241+#define MASK_LHU 0x707f
7242+#define MATCH_SH 0x1023
7243+#define MASK_SH 0x707f
7244+#define MATCH_FMSUB_H 0x4000047
7245+#define MASK_FMSUB_H 0x600007f
7246+#define MATCH_VXCPTAUX 0x200402b
7247+#define MASK_VXCPTAUX 0xfffff07f
7248+#define MATCH_FMSUB_D 0x2000047
7249+#define MASK_FMSUB_D 0x600007f
7250+#define MATCH_VFSSEGD 0x1600207b
7251+#define MASK_VFSSEGD 0x1ff0707f
7252+#define MATCH_VLSEGHU 0xa00205b
7253+#define MASK_VLSEGHU 0x1ff0707f
7254+#define MATCH_MOVN 0x2007077
7255+#define MASK_MOVN 0xfe00707f
7256+#define MATCH_CUSTOM1_RS1 0x202b
7257+#define MASK_CUSTOM1_RS1 0x707f
7258+#define MATCH_VLSTHU 0xa00305b
7259+#define MASK_VLSTHU 0xfe00707f
7260+#define MATCH_MOVZ 0x7077
7261+#define MASK_MOVZ 0xfe00707f
7262+#define MATCH_CSRRW 0x1073
7263+#define MASK_CSRRW 0x707f
7264+#define MATCH_LD 0x3003
7265+#define MASK_LD 0x707f
7266+#define MATCH_LB 0x3
7267+#define MASK_LB 0x707f
7268+#define MATCH_VLWU 0xc00205b
7269+#define MASK_VLWU 0xfff0707f
7270+#define MATCH_LH 0x1003
7271+#define MASK_LH 0x707f
7272+#define MATCH_LW 0x2003
7273+#define MASK_LW 0x707f
7274+#define MATCH_CSRRC 0x3073
7275+#define MASK_CSRRC 0x707f
7276+#define MATCH_FCVT_LU_H 0x4c000053
7277+#define MASK_FCVT_LU_H 0xfff0007f
7278+#define MATCH_FCVT_S_D 0x40100053
7279+#define MASK_FCVT_S_D 0xfff0007f
7280+#define MATCH_BGEU 0x7063
7281+#define MASK_BGEU 0x707f
7282+#define MATCH_VFLSTD 0x1600305b
7283+#define MASK_VFLSTD 0xfe00707f
7284+#define MATCH_FCVT_S_L 0xd0200053
7285+#define MASK_FCVT_S_L 0xfff0007f
7286+#define MATCH_FCVT_S_H 0x84000053
7287+#define MASK_FCVT_S_H 0xfff0007f
7288+#define MATCH_FSCSR 0x301073
7289+#define MASK_FSCSR 0xfff0707f
7290+#define MATCH_FCVT_S_W 0xd0000053
7291+#define MASK_FCVT_S_W 0xfff0007f
7292+#define MATCH_VFLSTW 0x1400305b
7293+#define MASK_VFLSTW 0xfe00707f
7294+#define MATCH_VXCPTEVAC 0x600302b
7295+#define MASK_VXCPTEVAC 0xfff07fff
7296+#define MATCH_AMOMINU_D 0xc000302f
7297+#define MASK_AMOMINU_D 0xf800707f
7298+#define MATCH_FSFLAGS 0x101073
7299+#define MASK_FSFLAGS 0xfff0707f
7300+#define MATCH_SRLI 0x5013
7301+#define MASK_SRLI 0xfc00707f
7302+#define MATCH_C_SRLI 0x819
7303+#define MASK_C_SRLI 0x1c1f
7304+#define MATCH_AMOMINU_W 0xc000202f
7305+#define MASK_AMOMINU_W 0xf800707f
7306+#define MATCH_SRLW 0x503b
7307+#define MASK_SRLW 0xfe00707f
7308+#define MATCH_VFLSEGW 0x1400205b
7309+#define MASK_VFLSEGW 0x1ff0707f
7310+#define MATCH_C_LD0 0x8012
7311+#define MASK_C_LD0 0x801f
7312+#define MATCH_VLSEGBU 0x800205b
7313+#define MASK_VLSEGBU 0x1ff0707f
7314+#define MATCH_JALR 0x67
7315+#define MASK_JALR 0x707f
7316+#define MATCH_BLT 0x4063
7317+#define MASK_BLT 0x707f
7318+#define MATCH_CUSTOM2_RD_RS1 0x605b
7319+#define MASK_CUSTOM2_RD_RS1 0x707f
7320+#define MATCH_FCLASS_S 0xe0001053
7321+#define MASK_FCLASS_S 0xfff0707f
7322+#define MATCH_REM 0x2006033
7323+#define MASK_REM 0xfe00707f
7324+#define MATCH_FCLASS_D 0xe2001053
7325+#define MASK_FCLASS_D 0xfff0707f
7326+#define MATCH_FMUL_S 0x10000053
7327+#define MASK_FMUL_S 0xfe00007f
7328+#define MATCH_RDCYCLEH 0xc8002073
7329+#define MASK_RDCYCLEH 0xfffff07f
7330+#define MATCH_VLSEGSTHU 0xa00305b
7331+#define MASK_VLSEGSTHU 0x1e00707f
7332+#define MATCH_FMUL_D 0x12000053
7333+#define MASK_FMUL_D 0xfe00007f
7334+#define MATCH_ORI 0x6013
7335+#define MASK_ORI 0x707f
7336+#define MATCH_FMUL_H 0x14000053
7337+#define MASK_FMUL_H 0xfe00007f
7338+#define MATCH_VFLSEGD 0x1600205b
7339+#define MASK_VFLSEGD 0x1ff0707f
7340+#define MATCH_FEQ_S 0xa0002053
7341+#define MASK_FEQ_S 0xfe00707f
7342+#define MATCH_FSGNJX_D 0x22002053
7343+#define MASK_FSGNJX_D 0xfe00707f
7344+#define MATCH_SRAIW 0x4000501b
7345+#define MASK_SRAIW 0xfe00707f
7346+#define MATCH_FSGNJX_H 0x3c000053
7347+#define MASK_FSGNJX_H 0xfe00707f
7348+#define MATCH_FSGNJX_S 0x20002053
7349+#define MASK_FSGNJX_S 0xfe00707f
7350+#define MATCH_FEQ_D 0xa2002053
7351+#define MASK_FEQ_D 0xfe00707f
7352+#define MATCH_CUSTOM1_RD_RS1 0x602b
7353+#define MASK_CUSTOM1_RD_RS1 0x707f
7354+#define MATCH_FEQ_H 0xac000053
7355+#define MASK_FEQ_H 0xfe00707f
7356+#define MATCH_AMOMAXU_D 0xe000302f
7357+#define MASK_AMOMAXU_D 0xf800707f
7358+#define MATCH_DIVW 0x200403b
7359+#define MASK_DIVW 0xfe00707f
7360+#define MATCH_AMOMAXU_W 0xe000202f
7361+#define MASK_AMOMAXU_W 0xf800707f
7362+#define MATCH_SRAI_RV32 0x40005013
7363+#define MASK_SRAI_RV32 0xfe00707f
7364+#define MATCH_C_SRLI32 0xc19
7365+#define MASK_C_SRLI32 0x1c1f
7366+#define MATCH_VFSSTW 0x1400307b
7367+#define MASK_VFSSTW 0xfe00707f
7368+#define MATCH_CUSTOM0_RD 0x400b
7369+#define MASK_CUSTOM0_RD 0x707f
7370+#define MATCH_C_BEQ 0x10
7371+#define MASK_C_BEQ 0x1f
7372+#define MATCH_VFSSTD 0x1600307b
7373+#define MASK_VFSSTD 0xfe00707f
7374+#define MATCH_CUSTOM3_RD_RS1 0x607b
7375+#define MASK_CUSTOM3_RD_RS1 0x707f
7376+#define MATCH_LR_D 0x1000302f
7377+#define MASK_LR_D 0xf9f0707f
7378+#define MATCH_LR_W 0x1000202f
7379+#define MASK_LR_W 0xf9f0707f
7380+#define MATCH_FCVT_H_WU 0x7c000053
7381+#define MASK_FCVT_H_WU 0xfff0007f
7382+#define MATCH_VMVV 0x200002b
7383+#define MASK_VMVV 0xfff0707f
7384+#define MATCH_SLLW 0x103b
7385+#define MASK_SLLW 0xfe00707f
7386+#define MATCH_SLLI 0x1013
7387+#define MASK_SLLI 0xfc00707f
7388+#define MATCH_BEQ 0x63
7389+#define MASK_BEQ 0x707f
7390+#define MATCH_AND 0x7033
7391+#define MASK_AND 0xfe00707f
7392+#define MATCH_LBU 0x4003
7393+#define MASK_LBU 0x707f
7394+#define MATCH_FSGNJ_S 0x20000053
7395+#define MASK_FSGNJ_S 0xfe00707f
7396+#define MATCH_FMSUB_S 0x47
7397+#define MASK_FMSUB_S 0x600007f
7398+#define MATCH_C_SUB3 0x11c
7399+#define MASK_C_SUB3 0x31f
7400+#define MATCH_FSGNJ_H 0x2c000053
7401+#define MASK_FSGNJ_H 0xfe00707f
7402+#define MATCH_VLB 0x205b
7403+#define MASK_VLB 0xfff0707f
7404+#define MATCH_C_ADDIW 0x1d
7405+#define MASK_C_ADDIW 0x1f
7406+#define MATCH_CUSTOM3_RS1_RS2 0x307b
7407+#define MASK_CUSTOM3_RS1_RS2 0x707f
7408+#define MATCH_FSGNJ_D 0x22000053
7409+#define MASK_FSGNJ_D 0xfe00707f
7410+#define MATCH_VLSEGWU 0xc00205b
7411+#define MASK_VLSEGWU 0x1ff0707f
7412+#define MATCH_FCVT_S_WU 0xd0100053
7413+#define MASK_FCVT_S_WU 0xfff0007f
7414+#define MATCH_CUSTOM3_RS1 0x207b
7415+#define MASK_CUSTOM3_RS1 0x707f
7416+#define MATCH_SC_D 0x1800302f
7417+#define MASK_SC_D 0xf800707f
7418+#define MATCH_VFSW 0x1400207b
7419+#define MASK_VFSW 0xfff0707f
7420+#define MATCH_AMOSWAP_D 0x800302f
7421+#define MASK_AMOSWAP_D 0xf800707f
7422+#define MATCH_SB 0x23
7423+#define MASK_SB 0x707f
7424+#define MATCH_AMOSWAP_W 0x800202f
7425+#define MASK_AMOSWAP_W 0xf800707f
7426+#define MATCH_VFSD 0x1600207b
7427+#define MASK_VFSD 0xfff0707f
7428+#define MATCH_CUSTOM2_RS1 0x205b
7429+#define MASK_CUSTOM2_RS1 0x707f
7430+#define MATCH_SD 0x3023
7431+#define MASK_SD 0x707f
7432+#define MATCH_FMV_S_X 0xf0000053
7433+#define MASK_FMV_S_X 0xfff0707f
7434+#define MATCH_REMUW 0x200703b
7435+#define MASK_REMUW 0xfe00707f
7436+#define MATCH_JAL 0x6f
7437+#define MASK_JAL 0x7f
7438+#define MATCH_C_FSD 0x18
7439+#define MASK_C_FSD 0x1f
7440+#define MATCH_RDCYCLE 0xc0002073
7441+#define MASK_RDCYCLE 0xfffff07f
7442+#define MATCH_C_BNE 0x11
7443+#define MASK_C_BNE 0x1f
7444+#define MATCH_C_ADD 0x1a
7445+#define MASK_C_ADD 0x801f
7446+#define MATCH_VXCPTCAUSE 0x402b
7447+#define MASK_VXCPTCAUSE 0xfffff07f
7448+#define MATCH_VGETCFG 0x400b
7449+#define MASK_VGETCFG 0xfffff07f
7450+#define MATCH_LUI 0x37
7451+#define MASK_LUI 0x7f
7452+#define MATCH_VSETCFG 0x200b
7453+#define MASK_VSETCFG 0x7fff
7454+#define MATCH_C_SDSP 0x6
7455+#define MASK_C_SDSP 0x1f
7456+#define MATCH_C_LDSP 0x4
7457+#define MASK_C_LDSP 0x1f
7458+#define MATCH_FNMADD_H 0x400004f
7459+#define MASK_FNMADD_H 0x600007f
7460+#define MATCH_CUSTOM0_RS1_RS2 0x300b
7461+#define MASK_CUSTOM0_RS1_RS2 0x707f
7462+#define MATCH_SLLI_RV32 0x1013
7463+#define MASK_SLLI_RV32 0xfe00707f
7464+#define MATCH_MUL 0x2000033
7465+#define MASK_MUL 0xfe00707f
7466+#define MATCH_CSRRCI 0x7073
7467+#define MASK_CSRRCI 0x707f
7468+#define MATCH_C_SRAI32 0x1419
7469+#define MASK_C_SRAI32 0x1c1f
7470+#define MATCH_FLT_H 0xb4000053
7471+#define MASK_FLT_H 0xfe00707f
7472+#define MATCH_SRAI 0x40005013
7473+#define MASK_SRAI 0xfc00707f
7474+#define MATCH_AMOAND_D 0x6000302f
7475+#define MASK_AMOAND_D 0xf800707f
7476+#define MATCH_FLT_D 0xa2001053
7477+#define MASK_FLT_D 0xfe00707f
7478+#define MATCH_SRAW 0x4000503b
7479+#define MASK_SRAW 0xfe00707f
7480+#define MATCH_CSRRS 0x2073
7481+#define MASK_CSRRS 0x707f
7482+#define MATCH_FLT_S 0xa0001053
7483+#define MASK_FLT_S 0xfe00707f
7484+#define MATCH_ADDIW 0x1b
7485+#define MASK_ADDIW 0x707f
7486+#define MATCH_AMOAND_W 0x6000202f
7487+#define MASK_AMOAND_W 0xf800707f
7488+#define MATCH_CUSTOM2_RD 0x405b
7489+#define MASK_CUSTOM2_RD 0x707f
7490+#define MATCH_FCVT_WU_D 0xc2100053
7491+#define MASK_FCVT_WU_D 0xfff0007f
7492+#define MATCH_AMOXOR_W 0x2000202f
7493+#define MASK_AMOXOR_W 0xf800707f
7494+#define MATCH_FCVT_D_L 0xd2200053
7495+#define MASK_FCVT_D_L 0xfff0007f
7496+#define MATCH_FCVT_WU_H 0x5c000053
7497+#define MASK_FCVT_WU_H 0xfff0007f
7498+#define MATCH_C_SLLI 0x19
7499+#define MASK_C_SLLI 0x1c1f
7500+#define MATCH_AMOXOR_D 0x2000302f
7501+#define MASK_AMOXOR_D 0xf800707f
7502+#define MATCH_FCVT_WU_S 0xc0100053
7503+#define MASK_FCVT_WU_S 0xfff0007f
7504+#define MATCH_CUSTOM3_RD 0x407b
7505+#define MASK_CUSTOM3_RD 0x707f
7506+#define MATCH_FMAX_H 0xcc000053
7507+#define MASK_FMAX_H 0xfe00707f
7508+#define MATCH_VENQCNT 0x1000302b
7509+#define MASK_VENQCNT 0xfe007fff
7510+#define MATCH_VLBU 0x800205b
7511+#define MASK_VLBU 0xfff0707f
7512+#define MATCH_VLHU 0xa00205b
7513+#define MASK_VLHU 0xfff0707f
7514+#define MATCH_C_SW 0xd
7515+#define MASK_C_SW 0x1f
7516+#define MATCH_C_SD 0xc
7517+#define MASK_C_SD 0x1f
7518+#define MATCH_C_OR3 0x21c
7519+#define MASK_C_OR3 0x31f
7520+#define MATCH_C_AND3 0x31c
7521+#define MASK_C_AND3 0x31f
7522+#define MATCH_VFSSEGSTW 0x1400307b
7523+#define MASK_VFSSEGSTW 0x1e00707f
7524+#define MATCH_SLT 0x2033
7525+#define MASK_SLT 0xfe00707f
7526+#define MATCH_AMOOR_D 0x4000302f
7527+#define MASK_AMOOR_D 0xf800707f
7528+#define MATCH_REMU 0x2007033
7529+#define MASK_REMU 0xfe00707f
7530+#define MATCH_REMW 0x200603b
7531+#define MASK_REMW 0xfe00707f
7532+#define MATCH_SLL 0x1033
7533+#define MASK_SLL 0xfe00707f
7534+#define MATCH_VFSSEGSTD 0x1600307b
7535+#define MASK_VFSSEGSTD 0x1e00707f
7536+#define MATCH_AMOOR_W 0x4000202f
7537+#define MASK_AMOOR_W 0xf800707f
7538+#define MATCH_CUSTOM2_RS1_RS2 0x305b
7539+#define MASK_CUSTOM2_RS1_RS2 0x707f
7540+#define MATCH_VF 0x10202b
7541+#define MASK_VF 0x1f0707f
7542+#define MATCH_VFMVV 0x1000002b
7543+#define MASK_VFMVV 0xfff0707f
7544+#define MATCH_VFLSEGSTW 0x1400305b
7545+#define MASK_VFLSEGSTW 0x1e00707f
7546+#define MATCH_VXCPTRESTORE 0x200302b
7547+#define MASK_VXCPTRESTORE 0xfff07fff
7548+#define MATCH_VXCPTHOLD 0x800302b
7549+#define MASK_VXCPTHOLD 0xffffffff
7550+#define MATCH_SLTIU 0x3013
7551+#define MASK_SLTIU 0x707f
7552+#define MATCH_VFLSEGSTD 0x1600305b
7553+#define MASK_VFLSEGSTD 0x1e00707f
7554+#define MATCH_VFLD 0x1600205b
7555+#define MASK_VFLD 0xfff0707f
7556+#define MATCH_FMADD_S 0x43
7557+#define MASK_FMADD_S 0x600007f
7558+#define MATCH_VFLW 0x1400205b
7559+#define MASK_VFLW 0xfff0707f
7560+#define MATCH_FMADD_D 0x2000043
7561+#define MASK_FMADD_D 0x600007f
7562+#define MATCH_FMADD_H 0x4000043
7563+#define MASK_FMADD_H 0x600007f
7564+#define MATCH_SRET 0x80000073
7565+#define MASK_SRET 0xffffffff
7566+#define MATCH_VSSEGW 0x400207b
7567+#define MASK_VSSEGW 0x1ff0707f
7568+#define MATCH_CUSTOM0_RD_RS1 0x600b
7569+#define MASK_CUSTOM0_RD_RS1 0x707f
7570+#define MATCH_VSSEGH 0x200207b
7571+#define MASK_VSSEGH 0x1ff0707f
7572+#define MATCH_FRCSR 0x302073
7573+#define MASK_FRCSR 0xfffff07f
7574+#define MATCH_VSSEGD 0x600207b
7575+#define MASK_VSSEGD 0x1ff0707f
7576+#define MATCH_VSSEGB 0x207b
7577+#define MASK_VSSEGB 0x1ff0707f
7578+#define MATCH_FMIN_H 0xc4000053
7579+#define MASK_FMIN_H 0xfe00707f
7580+#define MATCH_FMIN_D 0x2a000053
7581+#define MASK_FMIN_D 0xfe00707f
7582+#define MATCH_BLTU 0x6063
7583+#define MASK_BLTU 0x707f
7584+#define MATCH_FMIN_S 0x28000053
7585+#define MASK_FMIN_S 0xfe00707f
7586+#define MATCH_SRLI_RV32 0x5013
7587+#define MASK_SRLI_RV32 0xfe00707f
7588+#define MATCH_SLLIW 0x101b
7589+#define MASK_SLLIW 0xfe00707f
7590+#define MATCH_FMAX_S 0x28001053
7591+#define MASK_FMAX_S 0xfe00707f
7592+#define MATCH_FCVT_D_H 0x8c000053
7593+#define MASK_FCVT_D_H 0xfff0007f
7594+#define MATCH_FCVT_D_W 0xd2000053
7595+#define MASK_FCVT_D_W 0xfff0007f
7596+#define MATCH_ADD 0x33
7597+#define MASK_ADD 0xfe00707f
7598+#define MATCH_FCVT_D_S 0x42000053
7599+#define MASK_FCVT_D_S 0xfff0007f
7600+#define MATCH_FMAX_D 0x2a001053
7601+#define MASK_FMAX_D 0xfe00707f
7602+#define MATCH_BNE 0x1063
7603+#define MASK_BNE 0x707f
7604+#define MATCH_CUSTOM1_RD 0x402b
7605+#define MASK_CUSTOM1_RD 0x707f
7606+#define MATCH_FSRM 0x201073
7607+#define MASK_FSRM 0xfff0707f
7608+#define MATCH_FDIV_D 0x1a000053
7609+#define MASK_FDIV_D 0xfe00007f
7610+#define MATCH_VSW 0x400207b
7611+#define MASK_VSW 0xfff0707f
7612+#define MATCH_FCVT_L_S 0xc0200053
7613+#define MASK_FCVT_L_S 0xfff0007f
7614+#define MATCH_FDIV_H 0x1c000053
7615+#define MASK_FDIV_H 0xfe00007f
7616+#define MATCH_VSB 0x207b
7617+#define MASK_VSB 0xfff0707f
7618+#define MATCH_FDIV_S 0x18000053
7619+#define MASK_FDIV_S 0xfe00007f
7620+#define MATCH_FSRMI 0x205073
7621+#define MASK_FSRMI 0xfff0707f
7622+#define MATCH_FCVT_L_H 0x44000053
7623+#define MASK_FCVT_L_H 0xfff0007f
7624+#define MATCH_VSH 0x200207b
7625+#define MASK_VSH 0xfff0707f
7626+#define MATCH_FCVT_L_D 0xc2200053
7627+#define MASK_FCVT_L_D 0xfff0007f
7628+#define MATCH_FCVT_H_S 0x90000053
7629+#define MASK_FCVT_H_S 0xfff0007f
7630+#define MATCH_SCALL 0x73
7631+#define MASK_SCALL 0xffffffff
7632+#define MATCH_FSFLAGSI 0x105073
7633+#define MASK_FSFLAGSI 0xfff0707f
7634+#define MATCH_FCVT_H_W 0x74000053
7635+#define MASK_FCVT_H_W 0xfff0007f
7636+#define MATCH_FCVT_H_L 0x64000053
7637+#define MASK_FCVT_H_L 0xfff0007f
7638+#define MATCH_SRLIW 0x501b
7639+#define MASK_SRLIW 0xfe00707f
7640+#define MATCH_FCVT_S_LU 0xd0300053
7641+#define MASK_FCVT_S_LU 0xfff0007f
7642+#define MATCH_FCVT_H_D 0x92000053
7643+#define MASK_FCVT_H_D 0xfff0007f
7644+#define MATCH_SBREAK 0x100073
7645+#define MASK_SBREAK 0xffffffff
7646+#define MATCH_RDINSTRETH 0xc8202073
7647+#define MASK_RDINSTRETH 0xfffff07f
7648+#define MATCH_SRA 0x40005033
7649+#define MASK_SRA 0xfe00707f
7650+#define MATCH_BGE 0x5063
7651+#define MASK_BGE 0x707f
7652+#define MATCH_SRL 0x5033
7653+#define MASK_SRL 0xfe00707f
7654+#define MATCH_VENQCMD 0xa00302b
7655+#define MASK_VENQCMD 0xfe007fff
7656+#define MATCH_OR 0x6033
7657+#define MASK_OR 0xfe00707f
7658+#define MATCH_SUBW 0x4000003b
7659+#define MASK_SUBW 0xfe00707f
7660+#define MATCH_FMV_X_D 0xe2000053
7661+#define MASK_FMV_X_D 0xfff0707f
7662+#define MATCH_RDTIME 0xc0102073
7663+#define MASK_RDTIME 0xfffff07f
7664+#define MATCH_AMOADD_D 0x302f
7665+#define MASK_AMOADD_D 0xf800707f
7666+#define MATCH_AMOMAX_W 0xa000202f
7667+#define MASK_AMOMAX_W 0xf800707f
7668+#define MATCH_C_MOVE 0x2
7669+#define MASK_C_MOVE 0x801f
7670+#define MATCH_FMOVN 0x6007077
7671+#define MASK_FMOVN 0xfe00707f
7672+#define MATCH_C_FSW 0x16
7673+#define MASK_C_FSW 0x1f
7674+#define MATCH_AMOADD_W 0x202f
7675+#define MASK_AMOADD_W 0xf800707f
7676+#define MATCH_AMOMAX_D 0xa000302f
7677+#define MASK_AMOMAX_D 0xf800707f
7678+#define MATCH_FMOVZ 0x4007077
7679+#define MASK_FMOVZ 0xfe00707f
7680+#define MATCH_CUSTOM1_RS1_RS2 0x302b
7681+#define MASK_CUSTOM1_RS1_RS2 0x707f
7682+#define MATCH_FMV_X_H 0xe4000053
7683+#define MASK_FMV_X_H 0xfff0707f
7684+#define MATCH_VSD 0x600207b
7685+#define MASK_VSD 0xfff0707f
7686+#define MATCH_VLSEGSTW 0x400305b
7687+#define MASK_VLSEGSTW 0x1e00707f
7688+#define MATCH_C_ADDI 0x1
7689+#define MASK_C_ADDI 0x1f
7690+#define MATCH_C_SLLIW 0x1819
7691+#define MASK_C_SLLIW 0x1c1f
7692+#define MATCH_VLSEGSTB 0x305b
7693+#define MASK_VLSEGSTB 0x1e00707f
7694+#define MATCH_VLSEGSTD 0x600305b
7695+#define MASK_VLSEGSTD 0x1e00707f
7696+#define MATCH_VLSEGSTH 0x200305b
7697+#define MASK_VLSEGSTH 0x1e00707f
7698+#define MATCH_MULHU 0x2003033
7699+#define MASK_MULHU 0xfe00707f
7700+#define MATCH_AMOMIN_W 0x8000202f
7701+#define MASK_AMOMIN_W 0xf800707f
7702+#define MATCH_C_SLLI32 0x419
7703+#define MASK_C_SLLI32 0x1c1f
7704+#define MATCH_C_ADD3 0x1c
7705+#define MASK_C_ADD3 0x31f
7706+#define MATCH_VGETVL 0x200400b
7707+#define MASK_VGETVL 0xfffff07f
7708+#define MATCH_AMOMIN_D 0x8000302f
7709+#define MASK_AMOMIN_D 0xf800707f
7710+#define MATCH_FCVT_W_H 0x54000053
7711+#define MASK_FCVT_W_H 0xfff0007f
7712+#define MATCH_VLSEGB 0x205b
7713+#define MASK_VLSEGB 0x1ff0707f
7714+#define MATCH_FSD 0x3027
7715+#define MASK_FSD 0x707f
7716+#define MATCH_VLSEGD 0x600205b
7717+#define MASK_VLSEGD 0x1ff0707f
7718+#define MATCH_FSH 0x1027
7719+#define MASK_FSH 0x707f
7720+#define MATCH_VLSEGH 0x200205b
7721+#define MASK_VLSEGH 0x1ff0707f
7722+#define MATCH_C_SUB 0x801a
7723+#define MASK_C_SUB 0x801f
7724+#define MATCH_VLSEGW 0x400205b
7725+#define MASK_VLSEGW 0x1ff0707f
7726+#define MATCH_FSW 0x2027
7727+#define MASK_FSW 0x707f
7728+#define MATCH_C_J 0x8002
7729+#define MASK_C_J 0x801f
7730+#define CSR_FFLAGS 0x1
7731+#define CSR_FRM 0x2
7732+#define CSR_FCSR 0x3
7733+#define CSR_STATS 0xc0
7734+#define CSR_SUP0 0x500
7735+#define CSR_SUP1 0x501
7736+#define CSR_EPC 0x502
7737+#define CSR_BADVADDR 0x503
7738+#define CSR_PTBR 0x504
7739+#define CSR_ASID 0x505
7740+#define CSR_COUNT 0x506
7741+#define CSR_COMPARE 0x507
7742+#define CSR_EVEC 0x508
7743+#define CSR_CAUSE 0x509
7744+#define CSR_STATUS 0x50a
7745+#define CSR_HARTID 0x50b
7746+#define CSR_IMPL 0x50c
7747+#define CSR_FATC 0x50d
7748+#define CSR_SEND_IPI 0x50e
7749+#define CSR_CLEAR_IPI 0x50f
7750+#define CSR_RESET 0x51d
7751+#define CSR_TOHOST 0x51e
7752+#define CSR_FROMHOST 0x51f
7753+#define CSR_CYCLE 0xc00
7754+#define CSR_TIME 0xc01
7755+#define CSR_INSTRET 0xc02
7756+#define CSR_UARCH0 0xcc0
7757+#define CSR_UARCH1 0xcc1
7758+#define CSR_UARCH2 0xcc2
7759+#define CSR_UARCH3 0xcc3
7760+#define CSR_UARCH4 0xcc4
7761+#define CSR_UARCH5 0xcc5
7762+#define CSR_UARCH6 0xcc6
7763+#define CSR_UARCH7 0xcc7
7764+#define CSR_UARCH8 0xcc8
7765+#define CSR_UARCH9 0xcc9
7766+#define CSR_UARCH10 0xcca
7767+#define CSR_UARCH11 0xccb
7768+#define CSR_UARCH12 0xccc
7769+#define CSR_UARCH13 0xccd
7770+#define CSR_UARCH14 0xcce
7771+#define CSR_UARCH15 0xccf
7772+#define CSR_COUNTH 0x586
7773+#define CSR_CYCLEH 0xc80
7774+#define CSR_TIMEH 0xc81
7775+#define CSR_INSTRETH 0xc82
7776+#define CAUSE_MISALIGNED_FETCH 0x0
7777+#define CAUSE_FAULT_FETCH 0x1
7778+#define CAUSE_ILLEGAL_INSTRUCTION 0x2
7779+#define CAUSE_PRIVILEGED_INSTRUCTION 0x3
7780+#define CAUSE_FP_DISABLED 0x4
7781+#define CAUSE_SYSCALL 0x6
7782+#define CAUSE_BREAKPOINT 0x7
7783+#define CAUSE_MISALIGNED_LOAD 0x8
7784+#define CAUSE_MISALIGNED_STORE 0x9
7785+#define CAUSE_FAULT_LOAD 0xa
7786+#define CAUSE_FAULT_STORE 0xb
7787+#define CAUSE_ACCELERATOR_DISABLED 0xc
7788+#endif
7789+#ifdef DECLARE_INSN
7790+DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2)
7791+DECLARE_INSN(vlsegstwu, MATCH_VLSEGSTWU, MASK_VLSEGSTWU)
7792+DECLARE_INSN(c_lw0, MATCH_C_LW0, MASK_C_LW0)
7793+DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X)
7794+DECLARE_INSN(vlh, MATCH_VLH, MASK_VLH)
7795+DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI)
7796+DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D)
7797+DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD)
7798+DECLARE_INSN(vld, MATCH_VLD, MASK_VLD)
7799+DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S)
7800+DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW)
7801+DECLARE_INSN(vlw, MATCH_VLW, MASK_VLW)
7802+DECLARE_INSN(vssegstw, MATCH_VSSEGSTW, MASK_VSSEGSTW)
7803+DECLARE_INSN(utidx, MATCH_UTIDX, MASK_UTIDX)
7804+DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW)
7805+DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D)
7806+DECLARE_INSN(vssegstd, MATCH_VSSEGSTD, MASK_VSSEGSTD)
7807+DECLARE_INSN(vssegstb, MATCH_VSSEGSTB, MASK_VSSEGSTB)
7808+DECLARE_INSN(div, MATCH_DIV, MASK_DIV)
7809+DECLARE_INSN(fmv_h_x, MATCH_FMV_H_X, MASK_FMV_H_X)
7810+DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD)
7811+DECLARE_INSN(frrm, MATCH_FRRM, MASK_FRRM)
7812+DECLARE_INSN(vfmsv_s, MATCH_VFMSV_S, MASK_VFMSV_S)
7813+DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP)
7814+DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE)
7815+DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S)
7816+DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S)
7817+DECLARE_INSN(fnmsub_h, MATCH_FNMSUB_H, MASK_FNMSUB_H)
7818+DECLARE_INSN(fle_h, MATCH_FLE_H, MASK_FLE_H)
7819+DECLARE_INSN(flw, MATCH_FLW, MASK_FLW)
7820+DECLARE_INSN(vsetvl, MATCH_VSETVL, MASK_VSETVL)
7821+DECLARE_INSN(vfmsv_d, MATCH_VFMSV_D, MASK_VFMSV_D)
7822+DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D)
7823+DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I)
7824+DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D)
7825+DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW)
7826+DECLARE_INSN(xor, MATCH_XOR, MASK_XOR)
7827+DECLARE_INSN(sub, MATCH_SUB, MASK_SUB)
7828+DECLARE_INSN(vsstw, MATCH_VSSTW, MASK_VSSTW)
7829+DECLARE_INSN(vssth, MATCH_VSSTH, MASK_VSSTH)
7830+DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W)
7831+DECLARE_INSN(vsstb, MATCH_VSSTB, MASK_VSSTB)
7832+DECLARE_INSN(vsstd, MATCH_VSSTD, MASK_VSSTD)
7833+DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI)
7834+DECLARE_INSN(rdtimeh, MATCH_RDTIMEH, MASK_RDTIMEH)
7835+DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH)
7836+DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI)
7837+DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU)
7838+DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW)
7839+DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2)
7840+DECLARE_INSN(venqimm1, MATCH_VENQIMM1, MASK_VENQIMM1)
7841+DECLARE_INSN(venqimm2, MATCH_VENQIMM2, MASK_VENQIMM2)
7842+DECLARE_INSN(rdinstret, MATCH_RDINSTRET, MASK_RDINSTRET)
7843+DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP)
7844+DECLARE_INSN(vlstw, MATCH_VLSTW, MASK_VLSTW)
7845+DECLARE_INSN(vlsth, MATCH_VLSTH, MASK_VLSTH)
7846+DECLARE_INSN(vlstb, MATCH_VLSTB, MASK_VLSTB)
7847+DECLARE_INSN(vlstd, MATCH_VLSTD, MASK_VLSTD)
7848+DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI)
7849+DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S)
7850+DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2)
7851+DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S)
7852+DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU)
7853+DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1)
7854+DECLARE_INSN(vlsegstbu, MATCH_VLSEGSTBU, MASK_VLSEGSTBU)
7855+DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D)
7856+DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S)
7857+DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI)
7858+DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU)
7859+DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU)
7860+DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D)
7861+DECLARE_INSN(fsub_h, MATCH_FSUB_H, MASK_FSUB_H)
7862+DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW)
7863+DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI)
7864+DECLARE_INSN(vlstbu, MATCH_VLSTBU, MASK_VLSTBU)
7865+DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU)
7866+DECLARE_INSN(flh, MATCH_FLH, MASK_FLH)
7867+DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2)
7868+DECLARE_INSN(fld, MATCH_FLD, MASK_FLD)
7869+DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S)
7870+DECLARE_INSN(fcvt_h_lu, MATCH_FCVT_H_LU, MASK_FCVT_H_LU)
7871+DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0)
7872+DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1)
7873+DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2)
7874+DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3)
7875+DECLARE_INSN(vxcptsave, MATCH_VXCPTSAVE, MASK_VXCPTSAVE)
7876+DECLARE_INSN(vmsv, MATCH_VMSV, MASK_VMSV)
7877+DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S)
7878+DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC)
7879+DECLARE_INSN(frflags, MATCH_FRFLAGS, MASK_FRFLAGS)
7880+DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D)
7881+DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI)
7882+DECLARE_INSN(fadd_h, MATCH_FADD_H, MASK_FADD_H)
7883+DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S)
7884+DECLARE_INSN(vxcptkill, MATCH_VXCPTKILL, MASK_VXCPTKILL)
7885+DECLARE_INSN(stop, MATCH_STOP, MASK_STOP)
7886+DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S)
7887+DECLARE_INSN(fsgnjn_h, MATCH_FSGNJN_H, MASK_FSGNJN_H)
7888+DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D)
7889+DECLARE_INSN(xori, MATCH_XORI, MASK_XORI)
7890+DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU)
7891+DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D)
7892+DECLARE_INSN(fsqrt_h, MATCH_FSQRT_H, MASK_FSQRT_H)
7893+DECLARE_INSN(vssegsth, MATCH_VSSEGSTH, MASK_VSSEGSTH)
7894+DECLARE_INSN(sw, MATCH_SW, MASK_SW)
7895+DECLARE_INSN(vlstwu, MATCH_VLSTWU, MASK_VLSTWU)
7896+DECLARE_INSN(vfssegw, MATCH_VFSSEGW, MASK_VFSSEGW)
7897+DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU)
7898+DECLARE_INSN(sh, MATCH_SH, MASK_SH)
7899+DECLARE_INSN(fmsub_h, MATCH_FMSUB_H, MASK_FMSUB_H)
7900+DECLARE_INSN(vxcptaux, MATCH_VXCPTAUX, MASK_VXCPTAUX)
7901+DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D)
7902+DECLARE_INSN(vfssegd, MATCH_VFSSEGD, MASK_VFSSEGD)
7903+DECLARE_INSN(vlseghu, MATCH_VLSEGHU, MASK_VLSEGHU)
7904+DECLARE_INSN(movn, MATCH_MOVN, MASK_MOVN)
7905+DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1)
7906+DECLARE_INSN(vlsthu, MATCH_VLSTHU, MASK_VLSTHU)
7907+DECLARE_INSN(movz, MATCH_MOVZ, MASK_MOVZ)
7908+DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW)
7909+DECLARE_INSN(ld, MATCH_LD, MASK_LD)
7910+DECLARE_INSN(lb, MATCH_LB, MASK_LB)
7911+DECLARE_INSN(vlwu, MATCH_VLWU, MASK_VLWU)
7912+DECLARE_INSN(lh, MATCH_LH, MASK_LH)
7913+DECLARE_INSN(lw, MATCH_LW, MASK_LW)
7914+DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC)
7915+DECLARE_INSN(fcvt_lu_h, MATCH_FCVT_LU_H, MASK_FCVT_LU_H)
7916+DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D)
7917+DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU)
7918+DECLARE_INSN(vflstd, MATCH_VFLSTD, MASK_VFLSTD)
7919+DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L)
7920+DECLARE_INSN(fcvt_s_h, MATCH_FCVT_S_H, MASK_FCVT_S_H)
7921+DECLARE_INSN(fscsr, MATCH_FSCSR, MASK_FSCSR)
7922+DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W)
7923+DECLARE_INSN(vflstw, MATCH_VFLSTW, MASK_VFLSTW)
7924+DECLARE_INSN(vxcptevac, MATCH_VXCPTEVAC, MASK_VXCPTEVAC)
7925+DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D)
7926+DECLARE_INSN(fsflags, MATCH_FSFLAGS, MASK_FSFLAGS)
7927+DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI)
7928+DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI)
7929+DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W)
7930+DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW)
7931+DECLARE_INSN(vflsegw, MATCH_VFLSEGW, MASK_VFLSEGW)
7932+DECLARE_INSN(c_ld0, MATCH_C_LD0, MASK_C_LD0)
7933+DECLARE_INSN(vlsegbu, MATCH_VLSEGBU, MASK_VLSEGBU)
7934+DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR)
7935+DECLARE_INSN(blt, MATCH_BLT, MASK_BLT)
7936+DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1)
7937+DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S)
7938+DECLARE_INSN(rem, MATCH_REM, MASK_REM)
7939+DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D)
7940+DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S)
7941+DECLARE_INSN(rdcycleh, MATCH_RDCYCLEH, MASK_RDCYCLEH)
7942+DECLARE_INSN(vlsegsthu, MATCH_VLSEGSTHU, MASK_VLSEGSTHU)
7943+DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D)
7944+DECLARE_INSN(ori, MATCH_ORI, MASK_ORI)
7945+DECLARE_INSN(fmul_h, MATCH_FMUL_H, MASK_FMUL_H)
7946+DECLARE_INSN(vflsegd, MATCH_VFLSEGD, MASK_VFLSEGD)
7947+DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S)
7948+DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D)
7949+DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW)
7950+DECLARE_INSN(fsgnjx_h, MATCH_FSGNJX_H, MASK_FSGNJX_H)
7951+DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S)
7952+DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D)
7953+DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1)
7954+DECLARE_INSN(feq_h, MATCH_FEQ_H, MASK_FEQ_H)
7955+DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D)
7956+DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW)
7957+DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W)
7958+DECLARE_INSN(srai_rv32, MATCH_SRAI_RV32, MASK_SRAI_RV32)
7959+DECLARE_INSN(c_srli32, MATCH_C_SRLI32, MASK_C_SRLI32)
7960+DECLARE_INSN(vfsstw, MATCH_VFSSTW, MASK_VFSSTW)
7961+DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD)
7962+DECLARE_INSN(c_beq, MATCH_C_BEQ, MASK_C_BEQ)
7963+DECLARE_INSN(vfsstd, MATCH_VFSSTD, MASK_VFSSTD)
7964+DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1)
7965+DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D)
7966+DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W)
7967+DECLARE_INSN(fcvt_h_wu, MATCH_FCVT_H_WU, MASK_FCVT_H_WU)
7968+DECLARE_INSN(vmvv, MATCH_VMVV, MASK_VMVV)
7969+DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW)
7970+DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI)
7971+DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ)
7972+DECLARE_INSN(and, MATCH_AND, MASK_AND)
7973+DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU)
7974+DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S)
7975+DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S)
7976+DECLARE_INSN(c_sub3, MATCH_C_SUB3, MASK_C_SUB3)
7977+DECLARE_INSN(fsgnj_h, MATCH_FSGNJ_H, MASK_FSGNJ_H)
7978+DECLARE_INSN(vlb, MATCH_VLB, MASK_VLB)
7979+DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW)
7980+DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2)
7981+DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D)
7982+DECLARE_INSN(vlsegwu, MATCH_VLSEGWU, MASK_VLSEGWU)
7983+DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU)
7984+DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1)
7985+DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D)
7986+DECLARE_INSN(vfsw, MATCH_VFSW, MASK_VFSW)
7987+DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D)
7988+DECLARE_INSN(sb, MATCH_SB, MASK_SB)
7989+DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W)
7990+DECLARE_INSN(vfsd, MATCH_VFSD, MASK_VFSD)
7991+DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1)
7992+DECLARE_INSN(sd, MATCH_SD, MASK_SD)
7993+DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X)
7994+DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW)
7995+DECLARE_INSN(jal, MATCH_JAL, MASK_JAL)
7996+DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD)
7997+DECLARE_INSN(rdcycle, MATCH_RDCYCLE, MASK_RDCYCLE)
7998+DECLARE_INSN(c_bne, MATCH_C_BNE, MASK_C_BNE)
7999+DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD)
8000+DECLARE_INSN(vxcptcause, MATCH_VXCPTCAUSE, MASK_VXCPTCAUSE)
8001+DECLARE_INSN(vgetcfg, MATCH_VGETCFG, MASK_VGETCFG)
8002+DECLARE_INSN(lui, MATCH_LUI, MASK_LUI)
8003+DECLARE_INSN(vsetcfg, MATCH_VSETCFG, MASK_VSETCFG)
8004+DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP)
8005+DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP)
8006+DECLARE_INSN(fnmadd_h, MATCH_FNMADD_H, MASK_FNMADD_H)
8007+DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2)
8008+DECLARE_INSN(slli_rv32, MATCH_SLLI_RV32, MASK_SLLI_RV32)
8009+DECLARE_INSN(mul, MATCH_MUL, MASK_MUL)
8010+DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI)
8011+DECLARE_INSN(c_srai32, MATCH_C_SRAI32, MASK_C_SRAI32)
8012+DECLARE_INSN(flt_h, MATCH_FLT_H, MASK_FLT_H)
8013+DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI)
8014+DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D)
8015+DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D)
8016+DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW)
8017+DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS)
8018+DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S)
8019+DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW)
8020+DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W)
8021+DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD)
8022+DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D)
8023+DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W)
8024+DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L)
8025+DECLARE_INSN(fcvt_wu_h, MATCH_FCVT_WU_H, MASK_FCVT_WU_H)
8026+DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI)
8027+DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D)
8028+DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S)
8029+DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD)
8030+DECLARE_INSN(fmax_h, MATCH_FMAX_H, MASK_FMAX_H)
8031+DECLARE_INSN(venqcnt, MATCH_VENQCNT, MASK_VENQCNT)
8032+DECLARE_INSN(vlbu, MATCH_VLBU, MASK_VLBU)
8033+DECLARE_INSN(vlhu, MATCH_VLHU, MASK_VLHU)
8034+DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW)
8035+DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD)
8036+DECLARE_INSN(c_or3, MATCH_C_OR3, MASK_C_OR3)
8037+DECLARE_INSN(c_and3, MATCH_C_AND3, MASK_C_AND3)
8038+DECLARE_INSN(vfssegstw, MATCH_VFSSEGSTW, MASK_VFSSEGSTW)
8039+DECLARE_INSN(slt, MATCH_SLT, MASK_SLT)
8040+DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D)
8041+DECLARE_INSN(remu, MATCH_REMU, MASK_REMU)
8042+DECLARE_INSN(remw, MATCH_REMW, MASK_REMW)
8043+DECLARE_INSN(sll, MATCH_SLL, MASK_SLL)
8044+DECLARE_INSN(vfssegstd, MATCH_VFSSEGSTD, MASK_VFSSEGSTD)
8045+DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W)
8046+DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2)
8047+DECLARE_INSN(vf, MATCH_VF, MASK_VF)
8048+DECLARE_INSN(vfmvv, MATCH_VFMVV, MASK_VFMVV)
8049+DECLARE_INSN(vflsegstw, MATCH_VFLSEGSTW, MASK_VFLSEGSTW)
8050+DECLARE_INSN(vxcptrestore, MATCH_VXCPTRESTORE, MASK_VXCPTRESTORE)
8051+DECLARE_INSN(vxcpthold, MATCH_VXCPTHOLD, MASK_VXCPTHOLD)
8052+DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU)
8053+DECLARE_INSN(vflsegstd, MATCH_VFLSEGSTD, MASK_VFLSEGSTD)
8054+DECLARE_INSN(vfld, MATCH_VFLD, MASK_VFLD)
8055+DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S)
8056+DECLARE_INSN(vflw, MATCH_VFLW, MASK_VFLW)
8057+DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D)
8058+DECLARE_INSN(fmadd_h, MATCH_FMADD_H, MASK_FMADD_H)
8059+DECLARE_INSN(sret, MATCH_SRET, MASK_SRET)
8060+DECLARE_INSN(vssegw, MATCH_VSSEGW, MASK_VSSEGW)
8061+DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1)
8062+DECLARE_INSN(vssegh, MATCH_VSSEGH, MASK_VSSEGH)
8063+DECLARE_INSN(frcsr, MATCH_FRCSR, MASK_FRCSR)
8064+DECLARE_INSN(vssegd, MATCH_VSSEGD, MASK_VSSEGD)
8065+DECLARE_INSN(vssegb, MATCH_VSSEGB, MASK_VSSEGB)
8066+DECLARE_INSN(fmin_h, MATCH_FMIN_H, MASK_FMIN_H)
8067+DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D)
8068+DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU)
8069+DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S)
8070+DECLARE_INSN(srli_rv32, MATCH_SRLI_RV32, MASK_SRLI_RV32)
8071+DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW)
8072+DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S)
8073+DECLARE_INSN(fcvt_d_h, MATCH_FCVT_D_H, MASK_FCVT_D_H)
8074+DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W)
8075+DECLARE_INSN(add, MATCH_ADD, MASK_ADD)
8076+DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S)
8077+DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D)
8078+DECLARE_INSN(bne, MATCH_BNE, MASK_BNE)
8079+DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD)
8080+DECLARE_INSN(fsrm, MATCH_FSRM, MASK_FSRM)
8081+DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D)
8082+DECLARE_INSN(vsw, MATCH_VSW, MASK_VSW)
8083+DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S)
8084+DECLARE_INSN(fdiv_h, MATCH_FDIV_H, MASK_FDIV_H)
8085+DECLARE_INSN(vsb, MATCH_VSB, MASK_VSB)
8086+DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S)
8087+DECLARE_INSN(fsrmi, MATCH_FSRMI, MASK_FSRMI)
8088+DECLARE_INSN(fcvt_l_h, MATCH_FCVT_L_H, MASK_FCVT_L_H)
8089+DECLARE_INSN(vsh, MATCH_VSH, MASK_VSH)
8090+DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D)
8091+DECLARE_INSN(fcvt_h_s, MATCH_FCVT_H_S, MASK_FCVT_H_S)
8092+DECLARE_INSN(scall, MATCH_SCALL, MASK_SCALL)
8093+DECLARE_INSN(fsflagsi, MATCH_FSFLAGSI, MASK_FSFLAGSI)
8094+DECLARE_INSN(fcvt_h_w, MATCH_FCVT_H_W, MASK_FCVT_H_W)
8095+DECLARE_INSN(fcvt_h_l, MATCH_FCVT_H_L, MASK_FCVT_H_L)
8096+DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW)
8097+DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU)
8098+DECLARE_INSN(fcvt_h_d, MATCH_FCVT_H_D, MASK_FCVT_H_D)
8099+DECLARE_INSN(sbreak, MATCH_SBREAK, MASK_SBREAK)
8100+DECLARE_INSN(rdinstreth, MATCH_RDINSTRETH, MASK_RDINSTRETH)
8101+DECLARE_INSN(sra, MATCH_SRA, MASK_SRA)
8102+DECLARE_INSN(bge, MATCH_BGE, MASK_BGE)
8103+DECLARE_INSN(srl, MATCH_SRL, MASK_SRL)
8104+DECLARE_INSN(venqcmd, MATCH_VENQCMD, MASK_VENQCMD)
8105+DECLARE_INSN(or, MATCH_OR, MASK_OR)
8106+DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW)
8107+DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D)
8108+DECLARE_INSN(rdtime, MATCH_RDTIME, MASK_RDTIME)
8109+DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D)
8110+DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W)
8111+DECLARE_INSN(c_move, MATCH_C_MOVE, MASK_C_MOVE)
8112+DECLARE_INSN(fmovn, MATCH_FMOVN, MASK_FMOVN)
8113+DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW)
8114+DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W)
8115+DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D)
8116+DECLARE_INSN(fmovz, MATCH_FMOVZ, MASK_FMOVZ)
8117+DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2)
8118+DECLARE_INSN(fmv_x_h, MATCH_FMV_X_H, MASK_FMV_X_H)
8119+DECLARE_INSN(vsd, MATCH_VSD, MASK_VSD)
8120+DECLARE_INSN(vlsegstw, MATCH_VLSEGSTW, MASK_VLSEGSTW)
8121+DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI)
8122+DECLARE_INSN(c_slliw, MATCH_C_SLLIW, MASK_C_SLLIW)
8123+DECLARE_INSN(vlsegstb, MATCH_VLSEGSTB, MASK_VLSEGSTB)
8124+DECLARE_INSN(vlsegstd, MATCH_VLSEGSTD, MASK_VLSEGSTD)
8125+DECLARE_INSN(vlsegsth, MATCH_VLSEGSTH, MASK_VLSEGSTH)
8126+DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU)
8127+DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W)
8128+DECLARE_INSN(c_slli32, MATCH_C_SLLI32, MASK_C_SLLI32)
8129+DECLARE_INSN(c_add3, MATCH_C_ADD3, MASK_C_ADD3)
8130+DECLARE_INSN(vgetvl, MATCH_VGETVL, MASK_VGETVL)
8131+DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D)
8132+DECLARE_INSN(fcvt_w_h, MATCH_FCVT_W_H, MASK_FCVT_W_H)
8133+DECLARE_INSN(vlsegb, MATCH_VLSEGB, MASK_VLSEGB)
8134+DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD)
8135+DECLARE_INSN(vlsegd, MATCH_VLSEGD, MASK_VLSEGD)
8136+DECLARE_INSN(fsh, MATCH_FSH, MASK_FSH)
8137+DECLARE_INSN(vlsegh, MATCH_VLSEGH, MASK_VLSEGH)
8138+DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB)
8139+DECLARE_INSN(vlsegw, MATCH_VLSEGW, MASK_VLSEGW)
8140+DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW)
8141+DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J)
8142+#endif
8143+#ifdef DECLARE_CSR
8144+DECLARE_CSR(fflags, CSR_FFLAGS)
8145+DECLARE_CSR(frm, CSR_FRM)
8146+DECLARE_CSR(fcsr, CSR_FCSR)
8147+DECLARE_CSR(stats, CSR_STATS)
8148+DECLARE_CSR(sup0, CSR_SUP0)
8149+DECLARE_CSR(sup1, CSR_SUP1)
8150+DECLARE_CSR(epc, CSR_EPC)
8151+DECLARE_CSR(badvaddr, CSR_BADVADDR)
8152+DECLARE_CSR(ptbr, CSR_PTBR)
8153+DECLARE_CSR(asid, CSR_ASID)
8154+DECLARE_CSR(count, CSR_COUNT)
8155+DECLARE_CSR(compare, CSR_COMPARE)
8156+DECLARE_CSR(evec, CSR_EVEC)
8157+DECLARE_CSR(cause, CSR_CAUSE)
8158+DECLARE_CSR(status, CSR_STATUS)
8159+DECLARE_CSR(hartid, CSR_HARTID)
8160+DECLARE_CSR(impl, CSR_IMPL)
8161+DECLARE_CSR(fatc, CSR_FATC)
8162+DECLARE_CSR(send_ipi, CSR_SEND_IPI)
8163+DECLARE_CSR(clear_ipi, CSR_CLEAR_IPI)
8164+DECLARE_CSR(reset, CSR_RESET)
8165+DECLARE_CSR(tohost, CSR_TOHOST)
8166+DECLARE_CSR(fromhost, CSR_FROMHOST)
8167+DECLARE_CSR(cycle, CSR_CYCLE)
8168+DECLARE_CSR(time, CSR_TIME)
8169+DECLARE_CSR(instret, CSR_INSTRET)
8170+DECLARE_CSR(uarch0, CSR_UARCH0)
8171+DECLARE_CSR(uarch1, CSR_UARCH1)
8172+DECLARE_CSR(uarch2, CSR_UARCH2)
8173+DECLARE_CSR(uarch3, CSR_UARCH3)
8174+DECLARE_CSR(uarch4, CSR_UARCH4)
8175+DECLARE_CSR(uarch5, CSR_UARCH5)
8176+DECLARE_CSR(uarch6, CSR_UARCH6)
8177+DECLARE_CSR(uarch7, CSR_UARCH7)
8178+DECLARE_CSR(uarch8, CSR_UARCH8)
8179+DECLARE_CSR(uarch9, CSR_UARCH9)
8180+DECLARE_CSR(uarch10, CSR_UARCH10)
8181+DECLARE_CSR(uarch11, CSR_UARCH11)
8182+DECLARE_CSR(uarch12, CSR_UARCH12)
8183+DECLARE_CSR(uarch13, CSR_UARCH13)
8184+DECLARE_CSR(uarch14, CSR_UARCH14)
8185+DECLARE_CSR(uarch15, CSR_UARCH15)
8186+DECLARE_CSR(counth, CSR_COUNTH)
8187+DECLARE_CSR(cycleh, CSR_CYCLEH)
8188+DECLARE_CSR(timeh, CSR_TIMEH)
8189+DECLARE_CSR(instreth, CSR_INSTRETH)
8190+#endif
8191+#ifdef DECLARE_CAUSE
8192+DECLARE_CAUSE("fflags", CAUSE_FFLAGS)
8193+DECLARE_CAUSE("frm", CAUSE_FRM)
8194+DECLARE_CAUSE("fcsr", CAUSE_FCSR)
8195+DECLARE_CAUSE("stats", CAUSE_STATS)
8196+DECLARE_CAUSE("sup0", CAUSE_SUP0)
8197+DECLARE_CAUSE("sup1", CAUSE_SUP1)
8198+DECLARE_CAUSE("epc", CAUSE_EPC)
8199+DECLARE_CAUSE("badvaddr", CAUSE_BADVADDR)
8200+DECLARE_CAUSE("ptbr", CAUSE_PTBR)
8201+DECLARE_CAUSE("asid", CAUSE_ASID)
8202+DECLARE_CAUSE("count", CAUSE_COUNT)
8203+DECLARE_CAUSE("compare", CAUSE_COMPARE)
8204+DECLARE_CAUSE("evec", CAUSE_EVEC)
8205+DECLARE_CAUSE("cause", CAUSE_CAUSE)
8206+DECLARE_CAUSE("status", CAUSE_STATUS)
8207+DECLARE_CAUSE("hartid", CAUSE_HARTID)
8208+DECLARE_CAUSE("impl", CAUSE_IMPL)
8209+DECLARE_CAUSE("fatc", CAUSE_FATC)
8210+DECLARE_CAUSE("send_ipi", CAUSE_SEND_IPI)
8211+DECLARE_CAUSE("clear_ipi", CAUSE_CLEAR_IPI)
8212+DECLARE_CAUSE("reset", CAUSE_RESET)
8213+DECLARE_CAUSE("tohost", CAUSE_TOHOST)
8214+DECLARE_CAUSE("fromhost", CAUSE_FROMHOST)
8215+DECLARE_CAUSE("cycle", CAUSE_CYCLE)
8216+DECLARE_CAUSE("time", CAUSE_TIME)
8217+DECLARE_CAUSE("instret", CAUSE_INSTRET)
8218+DECLARE_CAUSE("uarch0", CAUSE_UARCH0)
8219+DECLARE_CAUSE("uarch1", CAUSE_UARCH1)
8220+DECLARE_CAUSE("uarch2", CAUSE_UARCH2)
8221+DECLARE_CAUSE("uarch3", CAUSE_UARCH3)
8222+DECLARE_CAUSE("uarch4", CAUSE_UARCH4)
8223+DECLARE_CAUSE("uarch5", CAUSE_UARCH5)
8224+DECLARE_CAUSE("uarch6", CAUSE_UARCH6)
8225+DECLARE_CAUSE("uarch7", CAUSE_UARCH7)
8226+DECLARE_CAUSE("uarch8", CAUSE_UARCH8)
8227+DECLARE_CAUSE("uarch9", CAUSE_UARCH9)
8228+DECLARE_CAUSE("uarch10", CAUSE_UARCH10)
8229+DECLARE_CAUSE("uarch11", CAUSE_UARCH11)
8230+DECLARE_CAUSE("uarch12", CAUSE_UARCH12)
8231+DECLARE_CAUSE("uarch13", CAUSE_UARCH13)
8232+DECLARE_CAUSE("uarch14", CAUSE_UARCH14)
8233+DECLARE_CAUSE("uarch15", CAUSE_UARCH15)
8234+DECLARE_CAUSE("counth", CAUSE_COUNTH)
8235+DECLARE_CAUSE("cycleh", CAUSE_CYCLEH)
8236+DECLARE_CAUSE("timeh", CAUSE_TIMEH)
8237+DECLARE_CAUSE("instreth", CAUSE_INSTRETH)
8238+#endif
8239diff -urN original-binutils/ld/configure.tgt binutils/ld/configure.tgt
8240--- original-binutils/ld/configure.tgt 2014-10-14 09:32:04.000000000 +0200
8241+++ binutils-2.25/ld/configure.tgt 2015-03-07 09:55:02.383135671 +0100
8242@@ -604,6 +604,12 @@
8243 powerpc-*-beos*) targ_emul=aixppc ;;
8244 powerpc-*-windiss*) targ_emul=elf32ppcwindiss ;;
8245 powerpc-*-lynxos*) targ_emul=ppclynx ;;
8246+riscv32*-*-*) targ_emul=elf32lriscv
8247+ targ_extra_emuls="elf64lriscv"
8248+ targ_extra_libpath=$targ_extra_emuls ;;
8249+riscv*-*-*) targ_emul=elf64lriscv
8250+ targ_extra_emuls="elf32lriscv"
8251+ targ_extra_libpath=$targ_extra_emuls ;;
8252 rs6000-*-aix[5-9]*) targ_emul=aix5rs6 ;;
8253 rs6000-*-aix*) targ_emul=aixrs6
8254 ;;
8255diff -urN original-binutils/ld/emulparams/elf32lriscv-defs.sh binutils/ld/emulparams/elf32lriscv-defs.sh
8256--- original-binutils/ld/emulparams/elf32lriscv-defs.sh 1970-01-01 01:00:00.000000000 +0100
8257+++ binutils-2.25/ld/emulparams/elf32lriscv-defs.sh 2015-03-07 09:51:45.659139025 +0100
8258@@ -0,0 +1,39 @@
8259+# This is an ELF platform.
8260+SCRIPT_NAME=elf
8261+ARCH=riscv
8262+OUTPUT_FORMAT="elf32-littleriscv"
8263+NO_REL_RELOCS=yes
8264+
8265+TEMPLATE_NAME=elf32
8266+EXTRA_EM_FILE=riscvelf
8267+
8268+case "$EMULATION_NAME" in
8269+elf32*) ELFSIZE=32; LIBPATH_SUFFIX=32 ;;
8270+elf64*) ELFSIZE=64; LIBPATH_SUFFIX= ;;
8271+*) echo $0: unhandled emulation $EMULATION_NAME >&2; exit 1 ;;
8272+esac
8273+
8274+if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then
8275+ case " $EMULATION_LIBPATH " in
8276+ *" ${EMULATION_NAME} "*)
8277+ NATIVE=yes
8278+ ;;
8279+ esac
8280+fi
8281+
8282+GENERATE_SHLIB_SCRIPT=yes
8283+GENERATE_PIE_SCRIPT=yes
8284+
8285+TEXT_START_ADDR=0x800000
8286+MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
8287+COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
8288+
8289+INITIAL_READONLY_SECTIONS=".interp ${RELOCATING-0} : { *(.interp) }"
8290+SDATA_START_SYMBOLS="_gp = . + 0x800;
8291+ *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)"
8292+if test -n "${CREATE_SHLIB}"; then
8293+ INITIAL_READONLY_SECTIONS=
8294+ SDATA_START_SYMBOLS=
8295+ OTHER_READONLY_SECTIONS=".srodata ${RELOCATING-0} : { *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) }"
8296+ unset GOT
8297+fi
8298diff -urN original-binutils/ld/emulparams/elf32lriscv.sh binutils/ld/emulparams/elf32lriscv.sh
8299--- original-binutils/ld/emulparams/elf32lriscv.sh 1970-01-01 01:00:00.000000000 +0100
8300+++ binutils-2.25/ld/emulparams/elf32lriscv.sh 2015-03-07 09:51:45.659139025 +0100
8301@@ -0,0 +1,2 @@
8302+. ${srcdir}/emulparams/elf32lriscv-defs.sh
8303+OUTPUT_FORMAT="elf32-littleriscv"
8304diff -urN original-binutils/ld/emulparams/elf64lriscv-defs.sh binutils/ld/emulparams/elf64lriscv-defs.sh
8305--- original-binutils/ld/emulparams/elf64lriscv-defs.sh 1970-01-01 01:00:00.000000000 +0100
8306+++ binutils-2.25/ld/emulparams/elf64lriscv-defs.sh 2015-03-07 09:51:45.659139025 +0100
8307@@ -0,0 +1 @@
8308+. ${srcdir}/emulparams/elf32lriscv-defs.sh
8309diff -urN original-binutils/ld/emulparams/elf64lriscv.sh binutils/ld/emulparams/elf64lriscv.sh
8310--- original-binutils/ld/emulparams/elf64lriscv.sh 1970-01-01 01:00:00.000000000 +0100
8311+++ binutils-2.25/ld/emulparams/elf64lriscv.sh 2015-03-07 09:51:45.659139025 +0100
8312@@ -0,0 +1,2 @@
8313+. ${srcdir}/emulparams/elf64lriscv-defs.sh
8314+OUTPUT_FORMAT="elf64-littleriscv"
8315diff -urN original-binutils/ld/emultempl/riscvelf.em binutils/ld/emultempl/riscvelf.em
8316--- original-binutils/ld/emultempl/riscvelf.em 1970-01-01 01:00:00.000000000 +0100
8317+++ binutils-2.25/ld/emultempl/riscvelf.em 2015-03-07 09:51:45.659139025 +0100
8318@@ -0,0 +1,68 @@
8319+# This shell script emits a C file. -*- C -*-
8320+# Copyright 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
8321+#
8322+# This file is part of the GNU Binutils.
8323+#
8324+# This program is free software; you can redistribute it and/or modify
8325+# it under the terms of the GNU General Public License as published by
8326+# the Free Software Foundation; either version 3 of the License, or
8327+# (at your option) any later version.
8328+#
8329+# This program is distributed in the hope that it will be useful,
8330+# but WITHOUT ANY WARRANTY; without even the implied warranty of
8331+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
8332+# GNU General Public License for more details.
8333+#
8334+# You should have received a copy of the GNU General Public License
8335+# along with this program; if not, write to the Free Software
8336+# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
8337+# MA 02110-1301, USA.
8338+
8339+fragment <<EOF
8340+
8341+#include "ldmain.h"
8342+#include "ldctor.h"
8343+#include "elf/riscv.h"
8344+#include "elfxx-riscv.h"
8345+
8346+static void
8347+riscv_elf_before_allocation (void)
8348+{
8349+ gld${EMULATION_NAME}_before_allocation ();
8350+
8351+ if (link_info.discard == discard_sec_merge)
8352+ link_info.discard = discard_l;
8353+
8354+ /* We always need at least some relaxation to handle code alignment. */
8355+ if (RELAXATION_DISABLED_BY_USER)
8356+ TARGET_ENABLE_RELAXATION;
8357+ else
8358+ ENABLE_RELAXATION;
8359+
8360+ link_info.relax_pass = 2;
8361+}
8362+
8363+static void
8364+gld${EMULATION_NAME}_after_allocation (void)
8365+{
8366+ int need_layout = 0;
8367+
8368+ /* Don't attempt to discard unused .eh_frame sections until the final link,
8369+ as we can't reliably tell if they're used until after relaxation. */
8370+ if (!link_info.relocatable)
8371+ {
8372+ need_layout = bfd_elf_discard_info (link_info.output_bfd, &link_info);
8373+ if (need_layout < 0)
8374+ {
8375+ einfo ("%X%P: .eh_frame/.stab edit: %E\n");
8376+ return;
8377+ }
8378+ }
8379+
8380+ gld${EMULATION_NAME}_map_segments (need_layout);
8381+}
8382+
8383+EOF
8384+
8385+LDEMUL_BEFORE_ALLOCATION=riscv_elf_before_allocation
8386+LDEMUL_AFTER_ALLOCATION=gld${EMULATION_NAME}_after_allocation
8387diff -urN original-binutils/ld/Makefile.am binutils/ld/Makefile.am
8388--- original-binutils/ld/Makefile.am 2014-10-14 09:32:04.000000000 +0200
8389+++ binutils-2.25/ld/Makefile.am 2015-03-07 09:55:02.383135671 +0100
8390@@ -258,6 +258,7 @@
8391 eelf32ppcsim.c \
8392 eelf32ppcvxworks.c \
8393 eelf32ppcwindiss.c \
8394+ eelf32lriscv.c \
8395 eelf32rl78.c \
8396 eelf32rx.c \
8397 eelf32tilegx.c \
8398@@ -464,6 +465,7 @@
8399 eelf64btsmip_fbsd.c \
8400 eelf64hppa.c \
8401 eelf64lppc.c \
8402+ eelf64lriscv.c \
8403 eelf64ltsmip.c \
8404 eelf64ltsmip_fbsd.c \
8405 eelf64mmix.c \
8406@@ -1104,6 +1106,11 @@
8407 ldemul-list.h \
8408 $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
8409
8410+eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \
8411+ $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
8412+ $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
8413+ ${GEN_DEPENDS}
8414+
8415 eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
8416 $(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
8417 $(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \
8418@@ -1861,6 +1868,12 @@
8419 ldemul-list.h \
8420 $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
8421
8422+eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
8423+ $(srcdir)/emulparams/elf64lriscv-defs.sh \
8424+ $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
8425+ $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
8426+ ${GEN_DEPENDS}
8427+
8428 eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \
8429 $(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \
8430 $(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \
8431diff -urN original-binutils/ld/Makefile.in binutils/ld/Makefile.in
8432--- original-binutils/ld/Makefile.in 2014-10-14 09:32:04.000000000 +0200
8433+++ binutils-2.25/ld/Makefile.in 2015-03-07 09:55:02.383135671 +0100
8434@@ -546,6 +546,7 @@
8435 eelf32lppclinux.c \
8436 eelf32lppcnto.c \
8437 eelf32lppcsim.c \
8438+ eelf32lriscv.c \
8439 eelf32m32c.c \
8440 eelf32mb_linux.c \
8441 eelf32mbel_linux.c \
8442@@ -771,6 +772,7 @@
8443 eelf64btsmip_fbsd.c \
8444 eelf64hppa.c \
8445 eelf64lppc.c \
8446+ eelf64lriscv.c \
8447 eelf64ltsmip.c \
8448 eelf64ltsmip_fbsd.c \
8449 eelf64mmix.c \
8450@@ -1157,6 +1159,7 @@
8451 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppclinux.Po@am__quote@
8452 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@
8453 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@
8454+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@
8455 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900.Po@am__quote@
8456 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lr5900n32.Po@am__quote@
8457 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@
8458@@ -1211,6 +1214,7 @@
8459 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@
8460 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@
8461 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@
8462+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@
8463 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@
8464 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@
8465 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@
8466@@ -2545,6 +2549,11 @@
8467 ldemul-list.h \
8468 $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
8469
8470+eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \
8471+ $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
8472+ $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
8473+ ${GEN_DEPENDS}
8474+
8475 eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
8476 $(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
8477 $(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \
8478@@ -3302,6 +3311,12 @@
8479 ldemul-list.h \
8480 $(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
8481
8482+eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
8483+ $(srcdir)/emulparams/elf64lriscv-defs.sh \
8484+ $(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
8485+ $(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc \
8486+ ${GEN_DEPENDS}
8487+
8488 eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \
8489 $(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \
8490 $(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \
8491diff -urN original-binutils/opcodes/configure binutils/opcodes/configure
8492--- original-binutils/opcodes/configure 2014-12-23 15:22:07.000000000 +0100
8493+++ binutils-2.25/opcodes/configure 2015-03-07 09:55:02.387135671 +0100
8494@@ -12590,6 +12590,7 @@
8495 bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
8496 bfd_powerpc_64_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
8497 bfd_pyramid_arch) ;;
8498+ bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;;
8499 bfd_romp_arch) ;;
8500 bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
8501 bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";;
8502diff -urN original-binutils/opcodes/disassemble.c binutils/opcodes/disassemble.c
8503--- original-binutils/opcodes/disassemble.c 2014-10-14 09:32:04.000000000 +0200
8504+++ binutils-2.25/opcodes/disassemble.c 2015-03-07 09:55:02.391135671 +0100
8505@@ -373,6 +373,11 @@
8506 disassemble = print_insn_little_powerpc;
8507 break;
8508 #endif
8509+#ifdef ARCH_riscv
8510+ case bfd_arch_riscv:
8511+ disassemble = print_insn_riscv;
8512+ break;
8513+#endif
8514 #ifdef ARCH_rs6000
8515 case bfd_arch_rs6000:
8516 if (bfd_get_mach (abfd) == bfd_mach_ppc_620)
8517@@ -545,6 +550,9 @@
8518 #ifdef ARCH_powerpc
8519 print_ppc_disassembler_options (stream);
8520 #endif
8521+#ifdef ARCH_riscv
8522+ print_riscv_disassembler_options (stream);
8523+#endif
8524 #ifdef ARCH_i386
8525 print_i386_disassembler_options (stream);
8526 #endif
8527diff -urN original-binutils/opcodes/riscv-dis.c binutils/opcodes/riscv-dis.c
8528--- original-binutils/opcodes/riscv-dis.c 1970-01-01 01:00:00.000000000 +0100
8529+++ binutils-2.25/opcodes/riscv-dis.c 2015-03-07 09:51:45.659139025 +0100
8530@@ -0,0 +1,492 @@
8531+/* RISC-V disassembler
8532+ Copyright 2011-2014 Free Software Foundation, Inc.
8533+
8534+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
8535+ Based on MIPS target.
8536+
8537+ This file is part of the GNU opcodes library.
8538+
8539+ This library is free software; you can redistribute it and/or modify
8540+ it under the terms of the GNU General Public License as published by
8541+ the Free Software Foundation; either version 3, or (at your option)
8542+ any later version.
8543+
8544+ It is distributed in the hope that it will be useful, but WITHOUT
8545+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
8546+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
8547+ License for more details.
8548+
8549+ You should have received a copy of the GNU General Public License
8550+ along with this program; if not, write to the Free Software
8551+ Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
8552+ MA 02110-1301, USA. */
8553+
8554+#include "sysdep.h"
8555+#include "dis-asm.h"
8556+#include "libiberty.h"
8557+#include "opcode/riscv.h"
8558+#include "opintl.h"
8559+#include "elf-bfd.h"
8560+#include "elf/riscv.h"
8561+
8562+#include <stdint.h>
8563+#include <assert.h>
8564+
8565+struct riscv_private_data
8566+{
8567+ bfd_vma gp;
8568+ bfd_vma print_addr;
8569+ bfd_vma hi_addr[OP_MASK_RD + 1];
8570+};
8571+
8572+static const char * const *riscv_gpr_names;
8573+static const char * const *riscv_fpr_names;
8574+
8575+/* Other options */
8576+static int no_aliases; /* If set disassemble as most general inst. */
8577+
8578+static void
8579+set_default_riscv_dis_options (void)
8580+{
8581+ riscv_gpr_names = riscv_gpr_names_abi;
8582+ riscv_fpr_names = riscv_fpr_names_abi;
8583+ no_aliases = 0;
8584+}
8585+
8586+static void
8587+parse_riscv_dis_option (const char *option)
8588+{
8589+ if (CONST_STRNEQ (option, "no-aliases"))
8590+ no_aliases = 1;
8591+ else if (CONST_STRNEQ (option, "numeric"))
8592+ {
8593+ riscv_gpr_names = riscv_gpr_names_numeric;
8594+ riscv_fpr_names = riscv_fpr_names_numeric;
8595+ }
8596+
8597+ /* Invalid option. */
8598+ fprintf (stderr, _("Unrecognized disassembler option: %s\n"), option);
8599+}
8600+
8601+static void
8602+parse_riscv_dis_options (const char *opts_in)
8603+{
8604+ char *opts = xstrdup (opts_in), *opt = opts, *opt_end = opts;
8605+
8606+ set_default_riscv_dis_options ();
8607+
8608+ for ( ; opt_end != NULL; opt = opt_end + 1)
8609+ {
8610+ if ((opt_end = strchr (opt, ',')) != NULL)
8611+ *opt_end = 0;
8612+ parse_riscv_dis_option (opt);
8613+ }
8614+
8615+ free (opts);
8616+}
8617+
8618+/* Print one argument from an array. */
8619+
8620+static void
8621+arg_print (struct disassemble_info *info, unsigned long val,
8622+ const char* const* array, size_t size)
8623+{
8624+ const char *s = val >= size || array[val] == NULL ? "unknown" : array[val];
8625+ (*info->fprintf_func) (info->stream, "%s", s);
8626+}
8627+
8628+static void
8629+maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset)
8630+{
8631+ if (pd->hi_addr[base_reg] != (bfd_vma)-1)
8632+ {
8633+ pd->print_addr = pd->hi_addr[base_reg] + offset;
8634+ pd->hi_addr[base_reg] = -1;
8635+ }
8636+ else if (base_reg == X_GP && pd->gp != (bfd_vma)-1)
8637+ pd->print_addr = pd->gp + offset;
8638+ else if (base_reg == X_TP)
8639+ pd->print_addr = offset;
8640+}
8641+
8642+/* Print insn arguments for 32/64-bit code. */
8643+
8644+static void
8645+print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info)
8646+{
8647+ struct riscv_private_data *pd = info->private_data;
8648+ int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1;
8649+ int rd = (l >> OP_SH_RD) & OP_MASK_RD;
8650+
8651+ if (*d != '\0')
8652+ (*info->fprintf_func) (info->stream, "\t");
8653+
8654+ for (; *d != '\0'; d++)
8655+ {
8656+ switch (*d)
8657+ {
8658+ /* Xcustom */
8659+ case '^':
8660+ switch (*++d)
8661+ {
8662+ case 'd':
8663+ (*info->fprintf_func) (info->stream, "%d", rd);
8664+ break;
8665+ case 's':
8666+ (*info->fprintf_func) (info->stream, "%d", rs1);
8667+ break;
8668+ case 't':
8669+ (*info->fprintf_func)
8670+ ( info->stream, "%d", (int)((l >> OP_SH_RS2) & OP_MASK_RS2));
8671+ break;
8672+ case 'j':
8673+ (*info->fprintf_func)
8674+ ( info->stream, "%d", (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM));
8675+ break;
8676+ }
8677+ break;
8678+
8679+ /* Xhwacha */
8680+ case '#':
8681+ switch ( *++d ) {
8682+ case 'g':
8683+ (*info->fprintf_func)
8684+ ( info->stream, "%d",
8685+ (int)((l >> OP_SH_IMMNGPR) & OP_MASK_IMMNGPR));
8686+ break;
8687+ case 'f':
8688+ (*info->fprintf_func)
8689+ ( info->stream, "%d",
8690+ (int)((l >> OP_SH_IMMNFPR) & OP_MASK_IMMNFPR));
8691+ break;
8692+ case 'p':
8693+ (*info->fprintf_func)
8694+ ( info->stream, "%d",
8695+ (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM));
8696+ break;
8697+ case 'n':
8698+ (*info->fprintf_func)
8699+ ( info->stream, "%d",
8700+ (int)(((l >> OP_SH_IMMSEGNELM) & OP_MASK_IMMSEGNELM) + 1));
8701+ break;
8702+ case 'd':
8703+ (*info->fprintf_func)
8704+ ( info->stream, "%s",
8705+ riscv_vec_gpr_names[(l >> OP_SH_VRD) & OP_MASK_VRD]);
8706+ break;
8707+ case 's':
8708+ (*info->fprintf_func)
8709+ ( info->stream, "%s",
8710+ riscv_vec_gpr_names[(l >> OP_SH_VRS) & OP_MASK_VRS]);
8711+ break;
8712+ case 't':
8713+ (*info->fprintf_func)
8714+ ( info->stream, "%s",
8715+ riscv_vec_gpr_names[(l >> OP_SH_VRT) & OP_MASK_VRT]);
8716+ break;
8717+ case 'r':
8718+ (*info->fprintf_func)
8719+ ( info->stream, "%s",
8720+ riscv_vec_gpr_names[(l >> OP_SH_VRR) & OP_MASK_VRR]);
8721+ break;
8722+ case 'D':
8723+ (*info->fprintf_func)
8724+ ( info->stream, "%s",
8725+ riscv_vec_fpr_names[(l >> OP_SH_VFD) & OP_MASK_VFD]);
8726+ break;
8727+ case 'S':
8728+ (*info->fprintf_func)
8729+ ( info->stream, "%s",
8730+ riscv_vec_fpr_names[(l >> OP_SH_VFS) & OP_MASK_VFS]);
8731+ break;
8732+ case 'T':
8733+ (*info->fprintf_func)
8734+ ( info->stream, "%s",
8735+ riscv_vec_fpr_names[(l >> OP_SH_VFT) & OP_MASK_VFT]);
8736+ break;
8737+ case 'R':
8738+ (*info->fprintf_func)
8739+ ( info->stream, "%s",
8740+ riscv_vec_fpr_names[(l >> OP_SH_VFR) & OP_MASK_VFR]);
8741+ break;
8742+ }
8743+ break;
8744+
8745+ case ',':
8746+ case '(':
8747+ case ')':
8748+ case '[':
8749+ case ']':
8750+ (*info->fprintf_func) (info->stream, "%c", *d);
8751+ break;
8752+
8753+ case '0':
8754+ break;
8755+
8756+ case 'b':
8757+ case 's':
8758+ (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rs1]);
8759+ break;
8760+
8761+ case 't':
8762+ (*info->fprintf_func) (info->stream, "%s",
8763+ riscv_gpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]);
8764+ break;
8765+
8766+ case 'u':
8767+ (*info->fprintf_func) (info->stream, "0x%x", (unsigned)EXTRACT_UTYPE_IMM (l) >> RISCV_IMM_BITS);
8768+ break;
8769+
8770+ case 'm':
8771+ arg_print(info, (l >> OP_SH_RM) & OP_MASK_RM,
8772+ riscv_rm, ARRAY_SIZE(riscv_rm));
8773+ break;
8774+
8775+ case 'P':
8776+ arg_print(info, (l >> OP_SH_PRED) & OP_MASK_PRED,
8777+ riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ));
8778+ break;
8779+
8780+ case 'Q':
8781+ arg_print(info, (l >> OP_SH_SUCC) & OP_MASK_SUCC,
8782+ riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ));
8783+ break;
8784+
8785+ case 'o':
8786+ maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l));
8787+ case 'j':
8788+ if ((l & MASK_ADDI) == MATCH_ADDI || (l & MASK_JALR) == MATCH_JALR)
8789+ maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l));
8790+ (*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_ITYPE_IMM (l));
8791+ break;
8792+
8793+ case 'q':
8794+ maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l));
8795+ (*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_STYPE_IMM (l));
8796+ break;
8797+
8798+ case 'a':
8799+ info->target = EXTRACT_UJTYPE_IMM (l) + pc;
8800+ (*info->print_address_func) (info->target, info);
8801+ break;
8802+
8803+ case 'p':
8804+ info->target = EXTRACT_SBTYPE_IMM (l) + pc;
8805+ (*info->print_address_func) (info->target, info);
8806+ break;
8807+
8808+ case 'd':
8809+ if ((l & MASK_AUIPC) == MATCH_AUIPC)
8810+ pd->hi_addr[rd] = pc + EXTRACT_UTYPE_IMM (l);
8811+ else if ((l & MASK_LUI) == MATCH_LUI)
8812+ pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l);
8813+ (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rd]);
8814+ break;
8815+
8816+ case 'z':
8817+ (*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[0]);
8818+ break;
8819+
8820+ case '>':
8821+ (*info->fprintf_func) (info->stream, "0x%x",
8822+ (unsigned)((l >> OP_SH_SHAMT) & OP_MASK_SHAMT));
8823+ break;
8824+
8825+ case '<':
8826+ (*info->fprintf_func) (info->stream, "0x%x",
8827+ (unsigned)((l >> OP_SH_SHAMTW) & OP_MASK_SHAMTW));
8828+ break;
8829+
8830+ case 'S':
8831+ case 'U':
8832+ (*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rs1]);
8833+ break;
8834+
8835+ case 'T':
8836+ (*info->fprintf_func) (info->stream, "%s",
8837+ riscv_fpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]);
8838+ break;
8839+
8840+ case 'D':
8841+ (*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rd]);
8842+ break;
8843+
8844+ case 'R':
8845+ (*info->fprintf_func) (info->stream, "%s",
8846+ riscv_fpr_names[(l >> OP_SH_RS3) & OP_MASK_RS3]);
8847+ break;
8848+
8849+ case 'E':
8850+ {
8851+ const char* csr_name = NULL;
8852+ unsigned int csr = (l >> OP_SH_CSR) & OP_MASK_CSR;
8853+ switch (csr)
8854+ {
8855+ #define DECLARE_CSR(name, num) case num: csr_name = #name; break;
8856+ #include "opcode/riscv-opc.h"
8857+ #undef DECLARE_CSR
8858+ }
8859+ if (csr_name)
8860+ (*info->fprintf_func) (info->stream, "%s", csr_name);
8861+ else
8862+ (*info->fprintf_func) (info->stream, "0x%x", csr);
8863+ break;
8864+ }
8865+
8866+ case 'Z':
8867+ (*info->fprintf_func) (info->stream, "%d", rs1);
8868+ break;
8869+
8870+ default:
8871+ /* xgettext:c-format */
8872+ (*info->fprintf_func) (info->stream,
8873+ _("# internal error, undefined modifier (%c)"),
8874+ *d);
8875+ return;
8876+ }
8877+ }
8878+}
8879+
8880+/* Print the RISC-V instruction at address MEMADDR in debugged memory,
8881+ on using INFO. Returns length of the instruction, in bytes.
8882+ BIGENDIAN must be 1 if this is big-endian code, 0 if
8883+ this is little-endian code. */
8884+
8885+static int
8886+riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
8887+{
8888+ const struct riscv_opcode *op;
8889+ static bfd_boolean init = 0;
8890+ static const char *extension = NULL;
8891+ static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
8892+ struct riscv_private_data *pd;
8893+ int insnlen;
8894+
8895+ /* Build a hash table to shorten the search time. */
8896+ if (! init)
8897+ {
8898+ unsigned int i;
8899+ unsigned int e_flags = elf_elfheader (info->section->owner)->e_flags;
8900+ extension = riscv_elf_flag_to_name(EF_GET_RISCV_EXT(e_flags));
8901+
8902+ for (i = 0; i <= OP_MASK_OP; i++)
8903+ for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++)
8904+ if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
8905+ {
8906+ riscv_hash[i] = op;
8907+ break;
8908+ }
8909+
8910+ init = 1;
8911+ }
8912+
8913+ if (info->private_data == NULL)
8914+ {
8915+ int i;
8916+
8917+ pd = info->private_data = calloc(1, sizeof (struct riscv_private_data));
8918+ pd->gp = -1;
8919+ pd->print_addr = -1;
8920+ for (i = 0; i < (int) ARRAY_SIZE(pd->hi_addr); i++)
8921+ pd->hi_addr[i] = -1;
8922+
8923+ for (i = 0; i < info->symtab_size; i++)
8924+ if (strcmp (bfd_asymbol_name (info->symtab[i]), "_gp") == 0)
8925+ pd->gp = bfd_asymbol_value (info->symtab[i]);
8926+ }
8927+ else
8928+ pd = info->private_data;
8929+
8930+ insnlen = riscv_insn_length (word);
8931+
8932+ info->bytes_per_chunk = insnlen % 4 == 0 ? 4 : 2;
8933+ info->bytes_per_line = 8;
8934+ info->display_endian = info->endian;
8935+ info->insn_info_valid = 1;
8936+ info->branch_delay_insns = 0;
8937+ info->data_size = 0;
8938+ info->insn_type = dis_nonbranch;
8939+ info->target = 0;
8940+ info->target2 = 0;
8941+
8942+ op = riscv_hash[(word >> OP_SH_OP) & OP_MASK_OP];
8943+ if (op != NULL)
8944+ {
8945+ for (; op < &riscv_opcodes[NUMOPCODES]; op++)
8946+ {
8947+ if ((op->match_func) (op, word)
8948+ && !(no_aliases && (op->pinfo & INSN_ALIAS))
8949+ && !(op->subset[0] == 'X' && strcmp(op->subset, extension)))
8950+ {
8951+ (*info->fprintf_func) (info->stream, "%s", op->name);
8952+ print_insn_args (op->args, word, memaddr, info);
8953+ if (pd->print_addr != (bfd_vma)-1)
8954+ {
8955+ info->target = pd->print_addr;
8956+ (*info->fprintf_func) (info->stream, " # ");
8957+ (*info->print_address_func) (info->target, info);
8958+ pd->print_addr = -1;
8959+ }
8960+ return insnlen;
8961+ }
8962+ }
8963+ }
8964+
8965+ /* Handle undefined instructions. */
8966+ info->insn_type = dis_noninsn;
8967+ (*info->fprintf_func) (info->stream, "0x%llx", (unsigned long long)word);
8968+ return insnlen;
8969+}
8970+
8971+int
8972+print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
8973+{
8974+ uint16_t i2;
8975+ insn_t insn = 0;
8976+ bfd_vma n;
8977+ int status;
8978+
8979+ if (info->disassembler_options != NULL)
8980+ {
8981+ parse_riscv_dis_options (info->disassembler_options);
8982+ /* Avoid repeatedly parsing the options. */
8983+ info->disassembler_options = NULL;
8984+ }
8985+ else if (riscv_gpr_names == NULL)
8986+ set_default_riscv_dis_options ();
8987+
8988+ /* Instructions are a sequence of 2-byte packets in little-endian order. */
8989+ for (n = 0; n < sizeof(insn) && n < riscv_insn_length (insn); n += 2)
8990+ {
8991+ status = (*info->read_memory_func) (memaddr + n, (bfd_byte*)&i2, 2, info);
8992+ if (status != 0)
8993+ {
8994+ if (n > 0) /* Don't fail just because we fell off the end. */
8995+ break;
8996+ (*info->memory_error_func) (status, memaddr, info);
8997+ return status;
8998+ }
8999+
9000+ i2 = bfd_getl16 (&i2);
9001+ insn |= (insn_t)i2 << (8*n);
9002+ }
9003+
9004+ return riscv_disassemble_insn (memaddr, insn, info);
9005+}
9006+
9007+void
9008+print_riscv_disassembler_options (FILE *stream)
9009+{
9010+ fprintf (stream, _("\n\
9011+The following RISC-V-specific disassembler options are supported for use\n\
9012+with the -M switch (multiple options should be separated by commas):\n"));
9013+
9014+ fprintf (stream, _("\n\
9015+ numeric Print numeric reigster names, rather than ABI names.\n"));
9016+
9017+ fprintf (stream, _("\n\
9018+ no-aliases Disassemble only into canonical instructions, rather\n\
9019+ than into pseudoinstructions.\n"));
9020+
9021+ fprintf (stream, _("\n"));
9022+}
9023diff -urN original-binutils/opcodes/riscv-opc.c binutils/opcodes/riscv-opc.c
9024--- original-binutils/opcodes/riscv-opc.c 1970-01-01 01:00:00.000000000 +0100
9025+++ binutils-2.25/opcodes/riscv-opc.c 2015-03-07 09:51:45.659139025 +0100
9026@@ -0,0 +1,729 @@
9027+/* RISC-V opcode list
9028+ Copyright 2011-2014 Free Software Foundation, Inc.
9029+
9030+ Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
9031+ Based on MIPS target.
9032+
9033+ This file is part of the GNU opcodes library.
9034+
9035+ This library is free software; you can redistribute it and/or modify
9036+ it under the terms of the GNU General Public License as published by
9037+ the Free Software Foundation; either version 3, or (at your option)
9038+ any later version.
9039+
9040+ It is distributed in the hope that it will be useful, but WITHOUT
9041+ ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
9042+ or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
9043+ License for more details.
9044+
9045+ You should have received a copy of the GNU General Public License
9046+ along with this file; see the file COPYING. If not, write to the
9047+ Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
9048+ MA 02110-1301, USA. */
9049+
9050+#include "sysdep.h"
9051+#include "opcode/riscv.h"
9052+#include <stdio.h>
9053+
9054+/* Register names used by gas and objdump. */
9055+
9056+const char * const riscv_gpr_names_numeric[32] =
9057+{
9058+ "x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
9059+ "x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
9060+ "x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
9061+ "x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"
9062+};
9063+
9064+const char * const riscv_gpr_names_abi[32] = {
9065+ "zero", "ra", "sp", "gp", "tp", "t0", "t1", "t2",
9066+ "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5",
9067+ "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7",
9068+ "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6"
9069+};
9070+
9071+const char * const riscv_fpr_names_numeric[32] =
9072+{
9073+ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
9074+ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
9075+ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
9076+ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
9077+};
9078+
9079+const char * const riscv_fpr_names_abi[32] = {
9080+ "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7",
9081+ "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
9082+ "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
9083+ "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11"
9084+};
9085+
9086+const char * const riscv_vec_gpr_names[32] =
9087+{
9088+ "vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7",
9089+ "vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15",
9090+ "vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23",
9091+ "vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31"
9092+};
9093+
9094+const char * const riscv_vec_fpr_names[32] =
9095+{
9096+ "vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7",
9097+ "vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15",
9098+ "vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23",
9099+ "vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31"
9100+};
9101+
9102+/* The order of overloaded instructions matters. Label arguments and
9103+ register arguments look the same. Instructions that can have either
9104+ for arguments must apear in the correct order in this table for the
9105+ assembler to pick the right one. In other words, entries with
9106+ immediate operands must apear after the same instruction with
9107+ registers.
9108+
9109+ Because of the lookup algorithm used, entries with the same opcode
9110+ name must be contiguous. */
9111+
9112+#define WR_xd INSN_WRITE_GPR_D
9113+#define WR_fd INSN_WRITE_FPR_D
9114+#define RD_xs1 INSN_READ_GPR_S
9115+#define RD_xs2 INSN_READ_GPR_T
9116+#define RD_fs1 INSN_READ_FPR_S
9117+#define RD_fs2 INSN_READ_FPR_T
9118+#define RD_fs3 INSN_READ_FPR_R
9119+
9120+#define MASK_RS1 (OP_MASK_RS1 << OP_SH_RS1)
9121+#define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
9122+#define MASK_RD (OP_MASK_RD << OP_SH_RD)
9123+#define MASK_IMM ENCODE_ITYPE_IMM(-1U)
9124+#define MASK_UIMM ENCODE_UTYPE_IMM(-1U)
9125+#define MASK_RM (OP_MASK_RM << OP_SH_RM)
9126+#define MASK_PRED (OP_MASK_PRED << OP_SH_PRED)
9127+#define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC)
9128+#define MASK_AQ (OP_MASK_AQ << OP_SH_AQ)
9129+#define MASK_RL (OP_MASK_RL << OP_SH_RL)
9130+#define MASK_AQRL (MASK_AQ | MASK_RL)
9131+
9132+static int match_opcode(const struct riscv_opcode *op, insn_t insn)
9133+{
9134+ return (insn & op->mask) == op->match;
9135+}
9136+
9137+static int match_never(const struct riscv_opcode *op ATTRIBUTE_UNUSED,
9138+ insn_t insn ATTRIBUTE_UNUSED)
9139+{
9140+ return 0;
9141+}
9142+
9143+static int match_rs1_eq_rs2(const struct riscv_opcode *op, insn_t insn)
9144+{
9145+ return match_opcode(op, insn) &&
9146+ ((insn & MASK_RS1) >> OP_SH_RS1) == ((insn & MASK_RS2) >> OP_SH_RS2);
9147+}
9148+
9149+const struct riscv_opcode riscv_builtin_opcodes[] =
9150+{
9151+/* These instructions appear first so that the disassembler will find
9152+ them first. The assemblers uses a hash table based on the
9153+ instruction name anyhow. */
9154+/* name, isa, operands, match, mask, pinfo */
9155+{"unimp", "I", "", 0, 0xffff, match_opcode, 0 },
9156+{"nop", "I", "", MATCH_ADDI, MASK_ADDI | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
9157+{"li", "I", "d,j", MATCH_ADDI, MASK_ADDI | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd }, /* addi */
9158+{"li", "I", "d,I", 0, (int) M_LI, match_never, INSN_MACRO },
9159+{"mv", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9160+{"move", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9161+{"andi", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, WR_xd|RD_xs1 },
9162+{"and", "I", "d,s,t", MATCH_AND, MASK_AND, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9163+{"and", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9164+{"beqz", "I", "s,p", MATCH_BEQ, MASK_BEQ | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
9165+{"beq", "I", "s,t,p", MATCH_BEQ, MASK_BEQ, match_opcode, RD_xs1|RD_xs2 },
9166+{"blez", "I", "t,p", MATCH_BGE, MASK_BGE | MASK_RS1, match_opcode, INSN_ALIAS|RD_xs2 },
9167+{"bgez", "I", "s,p", MATCH_BGE, MASK_BGE | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
9168+{"ble", "I", "t,s,p", MATCH_BGE, MASK_BGE, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
9169+{"bleu", "I", "t,s,p", MATCH_BGEU, MASK_BGEU, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
9170+{"bge", "I", "s,t,p", MATCH_BGE, MASK_BGE, match_opcode, RD_xs1|RD_xs2 },
9171+{"bgeu", "I", "s,t,p", MATCH_BGEU, MASK_BGEU, match_opcode, RD_xs1|RD_xs2 },
9172+{"bltz", "I", "s,p", MATCH_BLT, MASK_BLT | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
9173+{"bgtz", "I", "t,p", MATCH_BLT, MASK_BLT | MASK_RS1, match_opcode, INSN_ALIAS|RD_xs2 },
9174+{"blt", "I", "s,t,p", MATCH_BLT, MASK_BLT, match_opcode, RD_xs1|RD_xs2 },
9175+{"bltu", "I", "s,t,p", MATCH_BLTU, MASK_BLTU, match_opcode, RD_xs1|RD_xs2 },
9176+{"bgt", "I", "t,s,p", MATCH_BLT, MASK_BLT, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
9177+{"bgtu", "I", "t,s,p", MATCH_BLTU, MASK_BLTU, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
9178+{"bnez", "I", "s,p", MATCH_BNE, MASK_BNE | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
9179+{"bne", "I", "s,t,p", MATCH_BNE, MASK_BNE, match_opcode, RD_xs1|RD_xs2 },
9180+{"addi", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, WR_xd|RD_xs1 },
9181+{"add", "I", "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9182+{"add", "I", "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9183+{"add", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9184+{"la", "I", "d,A", 0, (int) M_LA, match_never, INSN_MACRO },
9185+{"lla", "I", "d,A", 0, (int) M_LLA, match_never, INSN_MACRO },
9186+{"la.tls.gd", "I", "d,A", 0, (int) M_LA_TLS_GD, match_never, INSN_MACRO },
9187+{"la.tls.ie", "I", "d,A", 0, (int) M_LA_TLS_IE, match_never, INSN_MACRO },
9188+{"neg", "I", "d,t", MATCH_SUB, MASK_SUB | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, /* sub 0 */
9189+{"slli", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, WR_xd|RD_xs1 },
9190+{"sll", "I", "d,s,t", MATCH_SLL, MASK_SLL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9191+{"sll", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9192+{"srli", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, WR_xd|RD_xs1 },
9193+{"srl", "I", "d,s,t", MATCH_SRL, MASK_SRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9194+{"srl", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9195+{"srai", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, WR_xd|RD_xs1 },
9196+{"sra", "I", "d,s,t", MATCH_SRA, MASK_SRA, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9197+{"sra", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9198+{"sub", "I", "d,s,t", MATCH_SUB, MASK_SUB, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9199+{"ret", "I", "", MATCH_JALR | (X_RA << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9200+{"j", "I", "a", MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS },
9201+{"jal", "I", "a", MATCH_JAL | (X_RA << OP_SH_RD), MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS|WR_xd },
9202+{"jal", "I", "d,a", MATCH_JAL, MASK_JAL, match_opcode, WR_xd },
9203+{"call", "I", "c", (X_T0 << OP_SH_RS1) | (X_RA << OP_SH_RD), (int) M_CALL, match_never, INSN_MACRO },
9204+{"tail", "I", "c", (X_T0 << OP_SH_RS1), (int) M_CALL, match_never, INSN_MACRO },
9205+{"jump", "I", "c,s", 0, (int) M_CALL, match_never, INSN_MACRO },
9206+{"jr", "I", "s", MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9207+{"jr", "I", "s,j", MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9208+{"jalr", "I", "s", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9209+{"jalr", "I", "s,j", MATCH_JALR | (X_RA << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9210+{"jalr", "I", "d,s", MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9211+{"jalr", "I", "d,s,j", MATCH_JALR, MASK_JALR, match_opcode, WR_xd|RD_xs1 },
9212+{"lb", "I", "d,o(s)", MATCH_LB, MASK_LB, match_opcode, WR_xd|RD_xs1 },
9213+{"lb", "I", "d,A", 0, (int) M_LB, match_never, INSN_MACRO },
9214+{"lbu", "I", "d,o(s)", MATCH_LBU, MASK_LBU, match_opcode, WR_xd|RD_xs1 },
9215+{"lbu", "I", "d,A", 0, (int) M_LBU, match_never, INSN_MACRO },
9216+{"lh", "I", "d,o(s)", MATCH_LH, MASK_LH, match_opcode, WR_xd|RD_xs1 },
9217+{"lh", "I", "d,A", 0, (int) M_LH, match_never, INSN_MACRO },
9218+{"lhu", "I", "d,o(s)", MATCH_LHU, MASK_LHU, match_opcode, WR_xd|RD_xs1 },
9219+{"lhu", "I", "d,A", 0, (int) M_LHU, match_never, INSN_MACRO },
9220+{"lw", "I", "d,o(s)", MATCH_LW, MASK_LW, match_opcode, WR_xd|RD_xs1 },
9221+{"lw", "I", "d,A", 0, (int) M_LW, match_never, INSN_MACRO },
9222+{"lui", "I", "d,u", MATCH_LUI, MASK_LUI, match_opcode, WR_xd },
9223+{"not", "I", "d,s", MATCH_XORI | MASK_IMM, MASK_XORI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9224+{"ori", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, WR_xd|RD_xs1 },
9225+{"or", "I", "d,s,t", MATCH_OR, MASK_OR, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9226+{"or", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9227+{"auipc", "I", "d,u", MATCH_AUIPC, MASK_AUIPC, match_opcode, WR_xd },
9228+{"seqz", "I", "d,s", MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9229+{"snez", "I", "d,t", MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 },
9230+{"sltz", "I", "d,s", MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9231+{"sgtz", "I", "d,t", MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 },
9232+{"slti", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9233+{"slt", "I", "d,s,t", MATCH_SLT, MASK_SLT, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9234+{"slt", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, WR_xd|RD_xs1 },
9235+{"sltiu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, WR_xd|RD_xs1 },
9236+{"sltu", "I", "d,s,t", MATCH_SLTU, MASK_SLTU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9237+{"sltu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9238+{"sgt", "I", "d,t,s", MATCH_SLT, MASK_SLT, match_opcode, INSN_ALIAS|WR_xd|RD_xs1|RD_xs2 },
9239+{"sgtu", "I", "d,t,s", MATCH_SLTU, MASK_SLTU, match_opcode, INSN_ALIAS|WR_xd|RD_xs1|RD_xs2 },
9240+{"sb", "I", "t,q(s)", MATCH_SB, MASK_SB, match_opcode, RD_xs1|RD_xs2 },
9241+{"sb", "I", "t,A,s", 0, (int) M_SB, match_never, INSN_MACRO },
9242+{"sh", "I", "t,q(s)", MATCH_SH, MASK_SH, match_opcode, RD_xs1|RD_xs2 },
9243+{"sh", "I", "t,A,s", 0, (int) M_SH, match_never, INSN_MACRO },
9244+{"sw", "I", "t,q(s)", MATCH_SW, MASK_SW, match_opcode, RD_xs1|RD_xs2 },
9245+{"sw", "I", "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO },
9246+{"fence", "I", "", MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
9247+{"fence", "I", "P,Q", MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
9248+{"fence.i", "I", "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
9249+{"rdcycle", "I", "d", MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, WR_xd },
9250+{"rdinstret", "I", "d", MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, WR_xd },
9251+{"rdtime", "I", "d", MATCH_RDTIME, MASK_RDTIME, match_opcode, WR_xd },
9252+{"rdcycleh", "32I", "d", MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, WR_xd },
9253+{"rdinstreth","32I", "d", MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, WR_xd },
9254+{"rdtimeh", "32I", "d", MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, WR_xd },
9255+{"sbreak", "I", "", MATCH_SBREAK, MASK_SBREAK, match_opcode, 0 },
9256+{"scall", "I", "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
9257+{"xori", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, WR_xd|RD_xs1 },
9258+{"xor", "I", "d,s,t", MATCH_XOR, MASK_XOR, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9259+{"xor", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9260+{"lwu", "64I", "d,o(s)", MATCH_LWU, MASK_LWU, match_opcode, WR_xd|RD_xs1 },
9261+{"lwu", "64I", "d,A", 0, (int) M_LWU, match_never, INSN_MACRO },
9262+{"ld", "64I", "d,o(s)", MATCH_LD, MASK_LD, match_opcode, WR_xd|RD_xs1 },
9263+{"ld", "64I", "d,A", 0, (int) M_LD, match_never, INSN_MACRO },
9264+{"sd", "64I", "t,q(s)", MATCH_SD, MASK_SD, match_opcode, RD_xs1|RD_xs2 },
9265+{"sd", "64I", "t,A,s", 0, (int) M_SD, match_never, INSN_MACRO },
9266+{"sext.w", "64I", "d,s", MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9267+{"addiw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, WR_xd|RD_xs1 },
9268+{"addw", "64I", "d,s,t", MATCH_ADDW, MASK_ADDW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9269+{"addw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9270+{"negw", "64I", "d,t", MATCH_SUBW, MASK_SUBW | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, /* sub 0 */
9271+{"slliw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, WR_xd|RD_xs1 },
9272+{"sllw", "64I", "d,s,t", MATCH_SLLW, MASK_SLLW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9273+{"sllw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9274+{"srliw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, WR_xd|RD_xs1 },
9275+{"srlw", "64I", "d,s,t", MATCH_SRLW, MASK_SRLW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9276+{"srlw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9277+{"sraiw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, WR_xd|RD_xs1 },
9278+{"sraw", "64I", "d,s,t", MATCH_SRAW, MASK_SRAW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9279+{"sraw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
9280+{"subw", "64I", "d,s,t", MATCH_SUBW, MASK_SUBW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9281+
9282+/* Atomic memory operation instruction subset */
9283+{"lr.w", "A", "d,0(s)", MATCH_LR_W, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9284+{"sc.w", "A", "d,t,0(s)", MATCH_SC_W, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9285+{"amoadd.w", "A", "d,t,0(s)", MATCH_AMOADD_W, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9286+{"amoswap.w", "A", "d,t,0(s)", MATCH_AMOSWAP_W, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9287+{"amoand.w", "A", "d,t,0(s)", MATCH_AMOAND_W, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9288+{"amoor.w", "A", "d,t,0(s)", MATCH_AMOOR_W, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9289+{"amoxor.w", "A", "d,t,0(s)", MATCH_AMOXOR_W, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9290+{"amomax.w", "A", "d,t,0(s)", MATCH_AMOMAX_W, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9291+{"amomaxu.w", "A", "d,t,0(s)", MATCH_AMOMAXU_W, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9292+{"amomin.w", "A", "d,t,0(s)", MATCH_AMOMIN_W, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9293+{"amominu.w", "A", "d,t,0(s)", MATCH_AMOMINU_W, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9294+{"lr.w.aq", "A", "d,0(s)", MATCH_LR_W | MASK_AQ, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9295+{"sc.w.aq", "A", "d,t,0(s)", MATCH_SC_W | MASK_AQ, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9296+{"amoadd.w.aq", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_AQ, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9297+{"amoswap.w.aq", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_AQ, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9298+{"amoand.w.aq", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_AQ, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9299+{"amoor.w.aq", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_AQ, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9300+{"amoxor.w.aq", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_AQ, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9301+{"amomax.w.aq", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_AQ, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9302+{"amomaxu.w.aq", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_AQ, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9303+{"amomin.w.aq", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_AQ, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9304+{"amominu.w.aq", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_AQ, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9305+{"lr.w.rl", "A", "d,0(s)", MATCH_LR_W | MASK_RL, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9306+{"sc.w.rl", "A", "d,t,0(s)", MATCH_SC_W | MASK_RL, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9307+{"amoadd.w.rl", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_RL, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9308+{"amoswap.w.rl", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_RL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9309+{"amoand.w.rl", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_RL, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9310+{"amoor.w.rl", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_RL, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9311+{"amoxor.w.rl", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_RL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9312+{"amomax.w.rl", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_RL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9313+{"amomaxu.w.rl", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_RL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9314+{"amomin.w.rl", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_RL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9315+{"amominu.w.rl", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_RL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9316+{"lr.w.sc", "A", "d,0(s)", MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9317+{"sc.w.sc", "A", "d,t,0(s)", MATCH_SC_W | MASK_AQRL, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9318+{"amoadd.w.sc", "A", "d,t,0(s)", MATCH_AMOADD_W | MASK_AQRL, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9319+{"amoswap.w.sc", "A", "d,t,0(s)", MATCH_AMOSWAP_W | MASK_AQRL, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9320+{"amoand.w.sc", "A", "d,t,0(s)", MATCH_AMOAND_W | MASK_AQRL, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9321+{"amoor.w.sc", "A", "d,t,0(s)", MATCH_AMOOR_W | MASK_AQRL, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9322+{"amoxor.w.sc", "A", "d,t,0(s)", MATCH_AMOXOR_W | MASK_AQRL, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9323+{"amomax.w.sc", "A", "d,t,0(s)", MATCH_AMOMAX_W | MASK_AQRL, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9324+{"amomaxu.w.sc", "A", "d,t,0(s)", MATCH_AMOMAXU_W | MASK_AQRL, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9325+{"amomin.w.sc", "A", "d,t,0(s)", MATCH_AMOMIN_W | MASK_AQRL, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9326+{"amominu.w.sc", "A", "d,t,0(s)", MATCH_AMOMINU_W | MASK_AQRL, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9327+{"lr.d", "64A", "d,0(s)", MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9328+{"sc.d", "64A", "d,t,0(s)", MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9329+{"amoadd.d", "64A", "d,t,0(s)", MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9330+{"amoswap.d", "64A", "d,t,0(s)", MATCH_AMOSWAP_D, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9331+{"amoand.d", "64A", "d,t,0(s)", MATCH_AMOAND_D, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9332+{"amoor.d", "64A", "d,t,0(s)", MATCH_AMOOR_D, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9333+{"amoxor.d", "64A", "d,t,0(s)", MATCH_AMOXOR_D, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9334+{"amomax.d", "64A", "d,t,0(s)", MATCH_AMOMAX_D, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9335+{"amomaxu.d", "64A", "d,t,0(s)", MATCH_AMOMAXU_D, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9336+{"amomin.d", "64A", "d,t,0(s)", MATCH_AMOMIN_D, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9337+{"amominu.d", "64A", "d,t,0(s)", MATCH_AMOMINU_D, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9338+{"lr.d.aq", "64A", "d,0(s)", MATCH_LR_D | MASK_AQ, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9339+{"sc.d.aq", "64A", "d,t,0(s)", MATCH_SC_D | MASK_AQ, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9340+{"amoadd.d.aq", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_AQ, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9341+{"amoswap.d.aq", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_AQ, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9342+{"amoand.d.aq", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_AQ, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9343+{"amoor.d.aq", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_AQ, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9344+{"amoxor.d.aq", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_AQ, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9345+{"amomax.d.aq", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_AQ, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9346+{"amomaxu.d.aq", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_AQ, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9347+{"amomin.d.aq", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_AQ, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9348+{"amominu.d.aq", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_AQ, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9349+{"lr.d.rl", "64A", "d,0(s)", MATCH_LR_D | MASK_RL, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9350+{"sc.d.rl", "64A", "d,t,0(s)", MATCH_SC_D | MASK_RL, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9351+{"amoadd.d.rl", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_RL, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9352+{"amoswap.d.rl", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_RL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9353+{"amoand.d.rl", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_RL, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9354+{"amoor.d.rl", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_RL, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9355+{"amoxor.d.rl", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_RL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9356+{"amomax.d.rl", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_RL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9357+{"amomaxu.d.rl", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_RL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9358+{"amomin.d.rl", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_RL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9359+{"amominu.d.rl", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_RL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9360+{"lr.d.sc", "64A", "d,0(s)", MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
9361+{"sc.d.sc", "64A", "d,t,0(s)", MATCH_SC_D | MASK_AQRL, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9362+{"amoadd.d.sc", "64A", "d,t,0(s)", MATCH_AMOADD_D | MASK_AQRL, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9363+{"amoswap.d.sc", "64A", "d,t,0(s)", MATCH_AMOSWAP_D | MASK_AQRL, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9364+{"amoand.d.sc", "64A", "d,t,0(s)", MATCH_AMOAND_D | MASK_AQRL, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9365+{"amoor.d.sc", "64A", "d,t,0(s)", MATCH_AMOOR_D | MASK_AQRL, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9366+{"amoxor.d.sc", "64A", "d,t,0(s)", MATCH_AMOXOR_D | MASK_AQRL, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9367+{"amomax.d.sc", "64A", "d,t,0(s)", MATCH_AMOMAX_D | MASK_AQRL, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9368+{"amomaxu.d.sc", "64A", "d,t,0(s)", MATCH_AMOMAXU_D | MASK_AQRL, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9369+{"amomin.d.sc", "64A", "d,t,0(s)", MATCH_AMOMIN_D | MASK_AQRL, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9370+{"amominu.d.sc", "64A", "d,t,0(s)", MATCH_AMOMINU_D | MASK_AQRL, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9371+
9372+/* Multiply/Divide instruction subset */
9373+{"mul", "M", "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9374+{"mulh", "M", "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9375+{"mulhu", "M", "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9376+{"mulhsu", "M", "d,s,t", MATCH_MULHSU, MASK_MULHSU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9377+{"div", "M", "d,s,t", MATCH_DIV, MASK_DIV, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9378+{"divu", "M", "d,s,t", MATCH_DIVU, MASK_DIVU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9379+{"rem", "M", "d,s,t", MATCH_REM, MASK_REM, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9380+{"remu", "M", "d,s,t", MATCH_REMU, MASK_REMU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9381+{"mulw", "64M", "d,s,t", MATCH_MULW, MASK_MULW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9382+{"divw", "64M", "d,s,t", MATCH_DIVW, MASK_DIVW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9383+{"divuw", "64M", "d,s,t", MATCH_DIVUW, MASK_DIVUW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9384+{"remw", "64M", "d,s,t", MATCH_REMW, MASK_REMW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9385+{"remuw", "64M", "d,s,t", MATCH_REMUW, MASK_REMUW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
9386+
9387+/* Single-precision floating-point instruction subset */
9388+{"frsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, WR_xd },
9389+{"fssr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, RD_xs1 },
9390+{"fssr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, WR_xd|RD_xs1 },
9391+{"frcsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, WR_xd },
9392+{"fscsr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, RD_xs1 },
9393+{"fscsr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, WR_xd|RD_xs1 },
9394+{"frrm", "F", "d", MATCH_FRRM, MASK_FRRM, match_opcode, WR_xd },
9395+{"fsrm", "F", "s", MATCH_FSRM, MASK_FSRM | MASK_RD, match_opcode, RD_xs1 },
9396+{"fsrm", "F", "d,s", MATCH_FSRM, MASK_FSRM, match_opcode, WR_xd|RD_xs1 },
9397+{"frflags", "F", "d", MATCH_FRFLAGS, MASK_FRFLAGS, match_opcode, WR_xd },
9398+{"fsflags", "F", "s", MATCH_FSFLAGS, MASK_FSFLAGS | MASK_RD, match_opcode, RD_xs1 },
9399+{"fsflags", "F", "d,s", MATCH_FSFLAGS, MASK_FSFLAGS, match_opcode, WR_xd|RD_xs1 },
9400+{"flw", "F", "D,o(s)", MATCH_FLW, MASK_FLW, match_opcode, WR_fd|RD_xs1 },
9401+{"flw", "F", "D,A,s", 0, (int) M_FLW, match_never, INSN_MACRO },
9402+{"fsw", "F", "T,q(s)", MATCH_FSW, MASK_FSW, match_opcode, RD_xs1|RD_fs2 },
9403+{"fsw", "F", "T,A,s", 0, (int) M_FSW, match_never, INSN_MACRO },
9404+{"fmv.x.s", "F", "d,S", MATCH_FMV_X_S, MASK_FMV_X_S, match_opcode, WR_xd|RD_fs1 },
9405+{"fmv.s.x", "F", "D,s", MATCH_FMV_S_X, MASK_FMV_S_X, match_opcode, WR_fd|RD_xs1 },
9406+{"fmv.s", "F", "D,U", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
9407+{"fneg.s", "F", "D,U", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
9408+{"fabs.s", "F", "D,U", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
9409+{"fsgnj.s", "F", "D,S,T", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9410+{"fsgnjn.s", "F", "D,S,T", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9411+{"fsgnjx.s", "F", "D,S,T", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9412+{"fadd.s", "F", "D,S,T", MATCH_FADD_S | MASK_RM, MASK_FADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9413+{"fadd.s", "F", "D,S,T,m", MATCH_FADD_S, MASK_FADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9414+{"fsub.s", "F", "D,S,T", MATCH_FSUB_S | MASK_RM, MASK_FSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9415+{"fsub.s", "F", "D,S,T,m", MATCH_FSUB_S, MASK_FSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9416+{"fmul.s", "F", "D,S,T", MATCH_FMUL_S | MASK_RM, MASK_FMUL_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9417+{"fmul.s", "F", "D,S,T,m", MATCH_FMUL_S, MASK_FMUL_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9418+{"fdiv.s", "F", "D,S,T", MATCH_FDIV_S | MASK_RM, MASK_FDIV_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9419+{"fdiv.s", "F", "D,S,T,m", MATCH_FDIV_S, MASK_FDIV_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9420+{"fsqrt.s", "F", "D,S", MATCH_FSQRT_S | MASK_RM, MASK_FSQRT_S | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9421+{"fsqrt.s", "F", "D,S,m", MATCH_FSQRT_S, MASK_FSQRT_S, match_opcode, WR_fd|RD_fs1 },
9422+{"fmin.s", "F", "D,S,T", MATCH_FMIN_S, MASK_FMIN_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9423+{"fmax.s", "F", "D,S,T", MATCH_FMAX_S, MASK_FMAX_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9424+{"fmadd.s", "F", "D,S,T,R", MATCH_FMADD_S | MASK_RM, MASK_FMADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9425+{"fmadd.s", "F", "D,S,T,R,m", MATCH_FMADD_S, MASK_FMADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9426+{"fnmadd.s", "F", "D,S,T,R", MATCH_FNMADD_S | MASK_RM, MASK_FNMADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9427+{"fnmadd.s", "F", "D,S,T,R,m", MATCH_FNMADD_S, MASK_FNMADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9428+{"fmsub.s", "F", "D,S,T,R", MATCH_FMSUB_S | MASK_RM, MASK_FMSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9429+{"fmsub.s", "F", "D,S,T,R,m", MATCH_FMSUB_S, MASK_FMSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9430+{"fnmsub.s", "F", "D,S,T,R", MATCH_FNMSUB_S | MASK_RM, MASK_FNMSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9431+{"fnmsub.s", "F", "D,S,T,R,m", MATCH_FNMSUB_S, MASK_FNMSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9432+{"fcvt.w.s", "F", "d,S", MATCH_FCVT_W_S | MASK_RM, MASK_FCVT_W_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9433+{"fcvt.w.s", "F", "d,S,m", MATCH_FCVT_W_S, MASK_FCVT_W_S, match_opcode, WR_xd|RD_fs1 },
9434+{"fcvt.wu.s", "F", "d,S", MATCH_FCVT_WU_S | MASK_RM, MASK_FCVT_WU_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9435+{"fcvt.wu.s", "F", "d,S,m", MATCH_FCVT_WU_S, MASK_FCVT_WU_S, match_opcode, WR_xd|RD_fs1 },
9436+{"fcvt.s.w", "F", "D,s", MATCH_FCVT_S_W | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9437+{"fcvt.s.w", "F", "D,s,m", MATCH_FCVT_S_W, MASK_FCVT_S_W, match_opcode, WR_fd|RD_xs1 },
9438+{"fcvt.s.wu", "F", "D,s", MATCH_FCVT_S_WU | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9439+{"fcvt.s.wu", "F", "D,s,m", MATCH_FCVT_S_WU, MASK_FCVT_S_WU, match_opcode, WR_fd|RD_xs1 },
9440+{"fclass.s", "F", "d,S", MATCH_FCLASS_S, MASK_FCLASS_S, match_opcode, WR_xd|RD_fs1 },
9441+{"feq.s", "F", "d,S,T", MATCH_FEQ_S, MASK_FEQ_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9442+{"flt.s", "F", "d,S,T", MATCH_FLT_S, MASK_FLT_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9443+{"fle.s", "F", "d,S,T", MATCH_FLE_S, MASK_FLE_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9444+{"fgt.s", "F", "d,T,S", MATCH_FLT_S, MASK_FLT_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9445+{"fge.s", "F", "d,T,S", MATCH_FLE_S, MASK_FLE_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9446+{"fcvt.l.s", "64F", "d,S", MATCH_FCVT_L_S | MASK_RM, MASK_FCVT_L_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9447+{"fcvt.l.s", "64F", "d,S,m", MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, WR_xd|RD_fs1 },
9448+{"fcvt.lu.s", "64F", "d,S", MATCH_FCVT_LU_S | MASK_RM, MASK_FCVT_LU_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9449+{"fcvt.lu.s", "64F", "d,S,m", MATCH_FCVT_LU_S, MASK_FCVT_LU_S, match_opcode, WR_xd|RD_fs1 },
9450+{"fcvt.s.l", "64F", "D,s", MATCH_FCVT_S_L | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9451+{"fcvt.s.l", "64F", "D,s,m", MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, WR_fd|RD_xs1 },
9452+{"fcvt.s.lu", "64F", "D,s", MATCH_FCVT_S_LU | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9453+{"fcvt.s.lu", "64F", "D,s,m", MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, WR_fd|RD_xs1 },
9454+
9455+/* Double-precision floating-point instruction subset */
9456+{"fld", "D", "D,o(s)", MATCH_FLD, MASK_FLD, match_opcode, WR_fd|RD_xs1 },
9457+{"fld", "D", "D,A,s", 0, (int) M_FLD, match_never, INSN_MACRO },
9458+{"fsd", "D", "T,q(s)", MATCH_FSD, MASK_FSD, match_opcode, RD_xs1|RD_fs2 },
9459+{"fsd", "D", "T,A,s", 0, (int) M_FSD, match_never, INSN_MACRO },
9460+{"fmv.d", "D", "D,U", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
9461+{"fneg.d", "D", "D,U", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
9462+{"fabs.d", "D", "D,U", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
9463+{"fsgnj.d", "D", "D,S,T", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9464+{"fsgnjn.d", "D", "D,S,T", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9465+{"fsgnjx.d", "D", "D,S,T", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9466+{"fadd.d", "D", "D,S,T", MATCH_FADD_D | MASK_RM, MASK_FADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9467+{"fadd.d", "D", "D,S,T,m", MATCH_FADD_D, MASK_FADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9468+{"fsub.d", "D", "D,S,T", MATCH_FSUB_D | MASK_RM, MASK_FSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9469+{"fsub.d", "D", "D,S,T,m", MATCH_FSUB_D, MASK_FSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9470+{"fmul.d", "D", "D,S,T", MATCH_FMUL_D | MASK_RM, MASK_FMUL_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9471+{"fmul.d", "D", "D,S,T,m", MATCH_FMUL_D, MASK_FMUL_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9472+{"fdiv.d", "D", "D,S,T", MATCH_FDIV_D | MASK_RM, MASK_FDIV_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9473+{"fdiv.d", "D", "D,S,T,m", MATCH_FDIV_D, MASK_FDIV_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9474+{"fsqrt.d", "D", "D,S", MATCH_FSQRT_D | MASK_RM, MASK_FSQRT_D | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9475+{"fsqrt.d", "D", "D,S,m", MATCH_FSQRT_D, MASK_FSQRT_D, match_opcode, WR_fd|RD_fs1 },
9476+{"fmin.d", "D", "D,S,T", MATCH_FMIN_D, MASK_FMIN_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9477+{"fmax.d", "D", "D,S,T", MATCH_FMAX_D, MASK_FMAX_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9478+{"fmadd.d", "D", "D,S,T,R", MATCH_FMADD_D | MASK_RM, MASK_FMADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9479+{"fmadd.d", "D", "D,S,T,R,m", MATCH_FMADD_D, MASK_FMADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9480+{"fnmadd.d", "D", "D,S,T,R", MATCH_FNMADD_D | MASK_RM, MASK_FNMADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9481+{"fnmadd.d", "D", "D,S,T,R,m", MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9482+{"fmsub.d", "D", "D,S,T,R", MATCH_FMSUB_D | MASK_RM, MASK_FMSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9483+{"fmsub.d", "D", "D,S,T,R,m", MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9484+{"fnmsub.d", "D", "D,S,T,R", MATCH_FNMSUB_D | MASK_RM, MASK_FNMSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9485+{"fnmsub.d", "D", "D,S,T,R,m", MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9486+{"fcvt.w.d", "D", "d,S", MATCH_FCVT_W_D | MASK_RM, MASK_FCVT_W_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9487+{"fcvt.w.d", "D", "d,S,m", MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, WR_xd|RD_fs1 },
9488+{"fcvt.wu.d", "D", "d,S", MATCH_FCVT_WU_D | MASK_RM, MASK_FCVT_WU_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9489+{"fcvt.wu.d", "D", "d,S,m", MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, WR_xd|RD_fs1 },
9490+{"fcvt.d.w", "D", "D,s", MATCH_FCVT_D_W, MASK_FCVT_D_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9491+{"fcvt.d.wu", "D", "D,s", MATCH_FCVT_D_WU, MASK_FCVT_D_WU | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9492+{"fcvt.d.s", "D", "D,S", MATCH_FCVT_D_S, MASK_FCVT_D_S | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9493+{"fcvt.s.d", "D", "D,S", MATCH_FCVT_S_D | MASK_RM, MASK_FCVT_S_D | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9494+{"fcvt.s.d", "D", "D,S,m", MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, WR_fd|RD_fs1 },
9495+{"fclass.d", "D", "d,S", MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, WR_xd|RD_fs1 },
9496+{"feq.d", "D", "d,S,T", MATCH_FEQ_D, MASK_FEQ_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9497+{"flt.d", "D", "d,S,T", MATCH_FLT_D, MASK_FLT_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9498+{"fle.d", "D", "d,S,T", MATCH_FLE_D, MASK_FLE_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9499+{"fgt.d", "D", "d,T,S", MATCH_FLT_D, MASK_FLT_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9500+{"fge.d", "D", "d,T,S", MATCH_FLE_D, MASK_FLE_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9501+{"fmv.x.d", "64D", "d,S", MATCH_FMV_X_D, MASK_FMV_X_D, match_opcode, WR_xd|RD_fs1 },
9502+{"fmv.d.x", "64D", "D,s", MATCH_FMV_D_X, MASK_FMV_D_X, match_opcode, WR_fd|RD_xs1 },
9503+{"fcvt.l.d", "64D", "d,S", MATCH_FCVT_L_D | MASK_RM, MASK_FCVT_L_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9504+{"fcvt.l.d", "64D", "d,S,m", MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, WR_xd|RD_fs1 },
9505+{"fcvt.lu.d", "64D", "d,S", MATCH_FCVT_LU_D | MASK_RM, MASK_FCVT_LU_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9506+{"fcvt.lu.d", "64D", "d,S,m", MATCH_FCVT_LU_D, MASK_FCVT_LU_D, match_opcode, WR_xd|RD_fs1 },
9507+{"fcvt.d.l", "64D", "D,s", MATCH_FCVT_D_L | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9508+{"fcvt.d.l", "64D", "D,s,m", MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, WR_fd|RD_xs1 },
9509+{"fcvt.d.lu", "64D", "D,s", MATCH_FCVT_D_LU | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9510+{"fcvt.d.lu", "64D", "D,s,m", MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, WR_fd|RD_xs1 },
9511+
9512+/* Supervisor instructions */
9513+{"csrr", "I", "d,E", MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, WR_xd },
9514+{"csrwi", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9515+{"csrw", "I", "E,s", MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, RD_xs1 },
9516+{"csrw", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9517+{"csrsi", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9518+{"csrs", "I", "E,s", MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9519+{"csrs", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9520+{"csrci", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9521+{"csrc", "I", "E,s", MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9522+{"csrc", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
9523+{"csrrw", "I", "d,E,s", MATCH_CSRRW, MASK_CSRRW, match_opcode, WR_xd|RD_xs1 },
9524+{"csrrw", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, WR_xd|RD_xs1 },
9525+{"csrrs", "I", "d,E,s", MATCH_CSRRS, MASK_CSRRS, match_opcode, WR_xd|RD_xs1 },
9526+{"csrrs", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, WR_xd|RD_xs1 },
9527+{"csrrc", "I", "d,E,s", MATCH_CSRRC, MASK_CSRRC, match_opcode, WR_xd|RD_xs1 },
9528+{"csrrc", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, WR_xd|RD_xs1 },
9529+{"csrrwi", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, WR_xd|RD_xs1 },
9530+{"csrrsi", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, WR_xd|RD_xs1 },
9531+{"csrrci", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, WR_xd|RD_xs1 },
9532+{"sret", "I", "", MATCH_SRET, MASK_SRET, match_opcode, 0 },
9533+
9534+/* Half-precision floating-point instruction subset */
9535+{"flh", "Xhwacha", "D,o(s)", MATCH_FLH, MASK_FLH, match_opcode, WR_fd|RD_xs1 },
9536+{"fsh", "Xhwacha", "T,q(s)", MATCH_FSH, MASK_FSH, match_opcode, RD_xs1|RD_fs2 },
9537+{"fsgnj.h", "Xhwacha", "D,S,T", MATCH_FSGNJ_H, MASK_FSGNJ_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9538+{"fsgnjn.h", "Xhwacha", "D,S,T", MATCH_FSGNJN_H, MASK_FSGNJN_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9539+{"fsgnjx.h", "Xhwacha", "D,S,T", MATCH_FSGNJX_H, MASK_FSGNJX_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9540+{"fadd.h", "Xhwacha", "D,S,T", MATCH_FADD_H | MASK_RM, MASK_FADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9541+{"fadd.h", "Xhwacha", "D,S,T,m", MATCH_FADD_H, MASK_FADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9542+{"fsub.h", "Xhwacha", "D,S,T", MATCH_FSUB_H | MASK_RM, MASK_FSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9543+{"fsub.h", "Xhwacha", "D,S,T,m", MATCH_FSUB_H, MASK_FSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9544+{"fmul.h", "Xhwacha", "D,S,T", MATCH_FMUL_H | MASK_RM, MASK_FMUL_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9545+{"fmul.h", "Xhwacha", "D,S,T,m", MATCH_FMUL_H, MASK_FMUL_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9546+{"fdiv.h", "Xhwacha", "D,S,T", MATCH_FDIV_H | MASK_RM, MASK_FDIV_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9547+{"fdiv.h", "Xhwacha", "D,S,T,m", MATCH_FDIV_H, MASK_FDIV_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9548+{"fsqrt.h", "Xhwacha", "D,S", MATCH_FSQRT_H | MASK_RM, MASK_FSQRT_H | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9549+{"fsqrt.h", "Xhwacha", "D,S,m", MATCH_FSQRT_H, MASK_FSQRT_H, match_opcode, WR_fd|RD_fs1 },
9550+{"fmin.h", "Xhwacha", "D,S,T", MATCH_FMIN_H, MASK_FMIN_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9551+{"fmax.h", "Xhwacha", "D,S,T", MATCH_FMAX_H, MASK_FMAX_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
9552+{"fmadd.h", "Xhwacha", "D,S,T,R", MATCH_FMADD_H | MASK_RM, MASK_FMADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9553+{"fmadd.h", "Xhwacha", "D,S,T,R,m", MATCH_FMADD_H, MASK_FMADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9554+{"fnmadd.h", "Xhwacha", "D,S,T,R", MATCH_FNMADD_H | MASK_RM, MASK_FNMADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9555+{"fnmadd.h", "Xhwacha", "D,S,T,R,m", MATCH_FNMADD_H, MASK_FNMADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9556+{"fmsub.h", "Xhwacha", "D,S,T,R", MATCH_FMSUB_H | MASK_RM, MASK_FMSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9557+{"fmsub.h", "Xhwacha", "D,S,T,R,m", MATCH_FMSUB_H, MASK_FMSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9558+{"fnmsub.h", "Xhwacha", "D,S,T,R", MATCH_FNMSUB_H | MASK_RM, MASK_FNMSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9559+{"fnmsub.h", "Xhwacha", "D,S,T,R,m", MATCH_FNMSUB_H, MASK_FNMSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
9560+{"fcvt.s.h", "Xhwacha", "D,S", MATCH_FCVT_S_H, MASK_FCVT_S_H | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9561+{"fcvt.h.s", "Xhwacha", "D,S", MATCH_FCVT_H_S | MASK_RM, MASK_FCVT_H_S | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9562+{"fcvt.h.s", "Xhwacha", "D,S,m", MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, WR_fd|RD_fs1 },
9563+{"fcvt.d.h", "Xhwacha", "D,S", MATCH_FCVT_D_H, MASK_FCVT_D_H | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9564+{"fcvt.h.d", "Xhwacha", "D,S", MATCH_FCVT_H_D | MASK_RM, MASK_FCVT_H_D | MASK_RM, match_opcode, WR_fd|RD_fs1 },
9565+{"fcvt.h.d", "Xhwacha", "D,S,m", MATCH_FCVT_H_D, MASK_FCVT_H_D, match_opcode, WR_fd|RD_fs1 },
9566+{"feq.h", "Xhwacha", "d,S,T", MATCH_FEQ_H, MASK_FEQ_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9567+{"flt.h", "Xhwacha", "d,S,T", MATCH_FLT_H, MASK_FLT_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9568+{"fle.h", "Xhwacha", "d,S,T", MATCH_FLE_H, MASK_FLE_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9569+{"fgt.h", "Xhwacha", "d,T,S", MATCH_FLT_H, MASK_FLT_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9570+{"fge.h", "Xhwacha", "d,T,S", MATCH_FLE_H, MASK_FLE_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
9571+{"fmv.x.h", "Xhwacha", "d,S", MATCH_FMV_X_H, MASK_FMV_X_H, match_opcode, WR_xd|RD_fs1 },
9572+{"fmv.h.x", "Xhwacha", "D,s", MATCH_FMV_H_X, MASK_FMV_H_X, match_opcode, WR_fd|RD_xs1 },
9573+{"fcvt.w.h", "Xhwacha", "d,S", MATCH_FCVT_W_H | MASK_RM, MASK_FCVT_W_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9574+{"fcvt.w.h", "Xhwacha", "d,S,m", MATCH_FCVT_W_H, MASK_FCVT_W_H, match_opcode, WR_xd|RD_fs1 },
9575+{"fcvt.wu.h", "Xhwacha", "d,S", MATCH_FCVT_WU_H | MASK_RM, MASK_FCVT_WU_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9576+{"fcvt.wu.h", "Xhwacha", "d,S,m", MATCH_FCVT_WU_H, MASK_FCVT_WU_H, match_opcode, WR_xd|RD_fs1 },
9577+{"fcvt.h.w", "Xhwacha", "D,s", MATCH_FCVT_H_W, MASK_FCVT_H_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9578+{"fcvt.h.wu", "Xhwacha", "D,s", MATCH_FCVT_H_WU, MASK_FCVT_H_WU | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9579+{"fcvt.l.h", "Xhwacha", "d,S", MATCH_FCVT_L_H | MASK_RM, MASK_FCVT_L_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9580+{"fcvt.l.h", "Xhwacha", "d,S,m", MATCH_FCVT_L_H, MASK_FCVT_L_H, match_opcode, WR_xd|RD_fs1 },
9581+{"fcvt.lu.h", "Xhwacha", "d,S", MATCH_FCVT_LU_H | MASK_RM, MASK_FCVT_LU_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
9582+{"fcvt.lu.h", "Xhwacha", "d,S,m", MATCH_FCVT_LU_H, MASK_FCVT_LU_H, match_opcode, WR_xd|RD_fs1 },
9583+{"fcvt.h.l", "Xhwacha", "D,s", MATCH_FCVT_H_L | MASK_RM, MASK_FCVT_H_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9584+{"fcvt.h.l", "Xhwacha", "D,s,m", MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, WR_fd|RD_xs1 },
9585+{"fcvt.h.lu", "Xhwacha", "D,s", MATCH_FCVT_H_LU | MASK_RM, MASK_FCVT_H_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
9586+{"fcvt.h.lu", "Xhwacha", "D,s,m", MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, WR_fd|RD_xs1 },
9587+
9588+/* Rocket Custom Coprocessor extension */
9589+{"custom0", "Xcustom", "d,s,t,^j", MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2, match_opcode, 0},
9590+{"custom0", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1, match_opcode, 0},
9591+{"custom0", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD, match_opcode, 0},
9592+{"custom0", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2, match_opcode, 0},
9593+{"custom0", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1, match_opcode, 0},
9594+{"custom0", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM0, MASK_CUSTOM0, match_opcode, 0},
9595+{"custom1", "Xcustom", "d,s,t,^j", MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2, match_opcode, 0},
9596+{"custom1", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1, match_opcode, 0},
9597+{"custom1", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD, match_opcode, 0},
9598+{"custom1", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2, match_opcode, 0},
9599+{"custom1", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1, match_opcode, 0},
9600+{"custom1", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM1, MASK_CUSTOM1, match_opcode, 0},
9601+{"custom2", "Xcustom", "d,s,t,^j", MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2, match_opcode, 0},
9602+{"custom2", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1, match_opcode, 0},
9603+{"custom2", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD, match_opcode, 0},
9604+{"custom2", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2, match_opcode, 0},
9605+{"custom2", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1, match_opcode, 0},
9606+{"custom2", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM2, MASK_CUSTOM2, match_opcode, 0},
9607+{"custom3", "Xcustom", "d,s,t,^j", MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2, match_opcode, 0},
9608+{"custom3", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1, match_opcode, 0},
9609+{"custom3", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD, match_opcode, 0},
9610+{"custom3", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2, match_opcode, 0},
9611+{"custom3", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1, match_opcode, 0},
9612+{"custom3", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM3, MASK_CUSTOM3, match_opcode, 0},
9613+
9614+/* Xhwacha extension */
9615+{"stop", "Xhwacha", "", MATCH_STOP, MASK_STOP, match_opcode, 0},
9616+{"utidx", "Xhwacha", "d", MATCH_UTIDX, MASK_UTIDX, match_opcode, WR_xd},
9617+{"movz", "Xhwacha", "d,s,t", MATCH_MOVZ, MASK_MOVZ, match_opcode, WR_xd|RD_xs1|RD_xs2},
9618+{"movn", "Xhwacha", "d,s,t", MATCH_MOVN, MASK_MOVN, match_opcode, WR_xd|RD_xs1|RD_xs2},
9619+{"fmovz", "Xhwacha", "D,s,T", MATCH_FMOVZ, MASK_FMOVZ, match_opcode, WR_fd|RD_xs1|RD_fs2},
9620+{"fmovn", "Xhwacha", "D,s,T", MATCH_FMOVN, MASK_FMOVN, match_opcode, WR_fd|RD_xs1|RD_fs2},
9621+
9622+/* unit stride */
9623+/* xloads */
9624+{"vld", "Xhwacha", "#d,s", MATCH_VLD, MASK_VLD, match_opcode, 0},
9625+{"vlw", "Xhwacha", "#d,s", MATCH_VLW, MASK_VLW, match_opcode, 0},
9626+{"vlwu", "Xhwacha", "#d,s", MATCH_VLWU, MASK_VLWU, match_opcode, 0},
9627+{"vlh", "Xhwacha", "#d,s", MATCH_VLH, MASK_VLH, match_opcode, 0},
9628+{"vlhu", "Xhwacha", "#d,s", MATCH_VLHU, MASK_VLHU, match_opcode, 0},
9629+{"vlb", "Xhwacha", "#d,s", MATCH_VLB, MASK_VLB, match_opcode, 0},
9630+{"vlbu", "Xhwacha", "#d,s", MATCH_VLBU, MASK_VLBU, match_opcode, 0},
9631+/* floads */
9632+{"vfld", "Xhwacha", "#D,s", MATCH_VFLD, MASK_VFLD, match_opcode, 0},
9633+{"vflw", "Xhwacha", "#D,s", MATCH_VFLW, MASK_VFLW, match_opcode, 0},
9634+
9635+/* stride */
9636+/* xloads */
9637+{"vlstd", "Xhwacha", "#d,s,t", MATCH_VLSTD, MASK_VLSTD, match_opcode, 0},
9638+{"vlstw", "Xhwacha", "#d,s,t", MATCH_VLSTW, MASK_VLSTW, match_opcode, 0},
9639+{"vlstwu", "Xhwacha", "#d,s,t", MATCH_VLSTWU, MASK_VLSTWU, match_opcode, 0},
9640+{"vlsth", "Xhwacha", "#d,s,t", MATCH_VLSTH, MASK_VLSTH, match_opcode, 0},
9641+{"vlsthu", "Xhwacha", "#d,s,t", MATCH_VLSTHU, MASK_VLSTHU, match_opcode, 0},
9642+{"vlstb", "Xhwacha", "#d,s,t", MATCH_VLSTB, MASK_VLSTB, match_opcode, 0},
9643+{"vlstbu", "Xhwacha", "#d,s,t", MATCH_VLSTBU, MASK_VLSTBU, match_opcode, 0},
9644+/* floads */
9645+{"vflstd", "Xhwacha", "#D,s,t", MATCH_VFLSTD, MASK_VFLSTD, match_opcode, 0},
9646+{"vflstw", "Xhwacha", "#D,s,t", MATCH_VFLSTW, MASK_VFLSTW, match_opcode, 0},
9647+
9648+/* segment */
9649+/* xloads */
9650+{"vlsegd", "Xhwacha", "#d,s,#n", MATCH_VLSEGD, MASK_VLSEGD, match_opcode, 0},
9651+{"vlsegw", "Xhwacha", "#d,s,#n", MATCH_VLSEGW, MASK_VLSEGW, match_opcode, 0},
9652+{"vlsegwu", "Xhwacha", "#d,s,#n", MATCH_VLSEGWU, MASK_VLSEGWU, match_opcode, 0},
9653+{"vlsegh", "Xhwacha", "#d,s,#n", MATCH_VLSEGH, MASK_VLSEGH, match_opcode, 0},
9654+{"vlseghu", "Xhwacha", "#d,s,#n", MATCH_VLSEGHU, MASK_VLSEGHU, match_opcode, 0},
9655+{"vlsegb", "Xhwacha", "#d,s,#n", MATCH_VLSEGB, MASK_VLSEGB, match_opcode, 0},
9656+{"vlsegbu", "Xhwacha", "#d,s,#n", MATCH_VLSEGBU, MASK_VLSEGBU, match_opcode, 0},
9657+/* floads */
9658+{"vflsegd", "Xhwacha", "#D,s,#n", MATCH_VFLSEGD, MASK_VFLSEGD, match_opcode, 0},
9659+{"vflsegw", "Xhwacha", "#D,s,#n", MATCH_VFLSEGW, MASK_VFLSEGW, match_opcode, 0},
9660+
9661+/* stride segment */
9662+/* xloads */
9663+{"vlsegstd", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTD, MASK_VLSEGSTD, match_opcode, 0},
9664+{"vlsegstw", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTW, MASK_VLSEGSTW, match_opcode, 0},
9665+{"vlsegstwu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTWU, MASK_VLSEGSTWU, match_opcode, 0},
9666+{"vlsegsth", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTH, MASK_VLSEGSTH, match_opcode, 0},
9667+{"vlsegsthu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTHU, MASK_VLSEGSTHU, match_opcode, 0},
9668+{"vlsegstb", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTB, MASK_VLSEGSTB, match_opcode, 0},
9669+{"vlsegstbu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTBU, MASK_VLSEGSTBU, match_opcode, 0},
9670+/* floads */
9671+{"vflsegstd", "Xhwacha", "#D,s,t,#n", MATCH_VFLSEGSTD, MASK_VFLSEGSTD, match_opcode, 0},
9672+{"vflsegstw", "Xhwacha", "#D,s,t,#n", MATCH_VFLSEGSTW, MASK_VFLSEGSTW, match_opcode, 0},
9673+
9674+/* unit stride */
9675+/* xstores */
9676+{"vsd", "Xhwacha", "#d,s", MATCH_VSD, MASK_VSD, match_opcode, 0},
9677+{"vsw", "Xhwacha", "#d,s", MATCH_VSW, MASK_VSW, match_opcode, 0},
9678+{"vsh", "Xhwacha", "#d,s", MATCH_VSH, MASK_VSH, match_opcode, 0},
9679+{"vsb", "Xhwacha", "#d,s", MATCH_VSB, MASK_VSB, match_opcode, 0},
9680+/* fstores */
9681+{"vfsd", "Xhwacha", "#D,s", MATCH_VFSD, MASK_VFSD, match_opcode, 0},
9682+{"vfsw", "Xhwacha", "#D,s", MATCH_VFSW, MASK_VFSW, match_opcode, 0},
9683+
9684+/* stride */
9685+/* xstores */
9686+{"vsstd", "Xhwacha", "#d,s,t", MATCH_VSSTD, MASK_VSSTD, match_opcode, 0},
9687+{"vsstw", "Xhwacha", "#d,s,t", MATCH_VSSTW, MASK_VSSTW, match_opcode, 0},
9688+{"vssth", "Xhwacha", "#d,s,t", MATCH_VSSTH, MASK_VSSTH, match_opcode, 0},
9689+{"vsstb", "Xhwacha", "#d,s,t", MATCH_VSSTB, MASK_VSSTB, match_opcode, 0},
9690+/* fstores */
9691+{"vfsstd", "Xhwacha", "#D,s,t", MATCH_VFSSTD, MASK_VFSSTD, match_opcode, 0},
9692+{"vfsstw", "Xhwacha", "#D,s,t", MATCH_VFSSTW, MASK_VFSSTW, match_opcode, 0},
9693+
9694+/* segment */
9695+/* xstores */
9696+{"vssegd", "Xhwacha", "#d,s,#n", MATCH_VSSEGD, MASK_VSSEGD, match_opcode, 0},
9697+{"vssegw", "Xhwacha", "#d,s,#n", MATCH_VSSEGW, MASK_VSSEGW, match_opcode, 0},
9698+{"vssegh", "Xhwacha", "#d,s,#n", MATCH_VSSEGH, MASK_VSSEGH, match_opcode, 0},
9699+{"vssegb", "Xhwacha", "#d,s,#n", MATCH_VSSEGB, MASK_VSSEGB, match_opcode, 0},
9700+/* fstores */
9701+{"vfssegd", "Xhwacha", "#D,s,#n", MATCH_VFSSEGD, MASK_VFSSEGD, match_opcode, 0},
9702+{"vfssegw", "Xhwacha", "#D,s,#n", MATCH_VFSSEGW, MASK_VFSSEGW, match_opcode, 0},
9703+
9704+/* stride segment */
9705+/* xsegstores */
9706+{"vssegstd", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTD, MASK_VSSEGSTD, match_opcode, 0},
9707+{"vssegstw", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTW, MASK_VSSEGSTW, match_opcode, 0},
9708+{"vssegsth", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTH, MASK_VSSEGSTH, match_opcode, 0},
9709+{"vssegstb", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTB, MASK_VSSEGSTB, match_opcode, 0},
9710+/* fsegstores */
9711+{"vfssegstd", "Xhwacha", "#D,s,t,#n", MATCH_VFSSEGSTD, MASK_VFSSEGSTD, match_opcode, 0},
9712+{"vfssegstw", "Xhwacha", "#D,s,t,#n", MATCH_VFSSEGSTW, MASK_VFSSEGSTW, match_opcode, 0},
9713+
9714+{"vsetcfg", "Xhwacha", "s", MATCH_VSETCFG, MASK_VSETCFG | MASK_IMM, match_opcode, 0},
9715+{"vsetcfg", "Xhwacha", "#g,#f", MATCH_VSETCFG, MASK_VSETCFG | MASK_RS1, match_opcode, 0},
9716+{"vsetcfg", "Xhwacha", "s,#g,#f", MATCH_VSETCFG, MASK_VSETCFG, match_opcode, 0},
9717+{"vsetucfg", "Xhwacha", "d,u", MATCH_LUI, MASK_LUI, match_opcode, INSN_ALIAS | WR_xd},
9718+{"vsetvl", "Xhwacha", "d,s", MATCH_VSETVL, MASK_VSETVL, match_opcode, 0},
9719+{"vgetcfg", "Xhwacha", "d", MATCH_VGETCFG, MASK_VGETCFG, match_opcode, 0},
9720+{"vgetvl", "Xhwacha", "d", MATCH_VGETVL, MASK_VGETVL, match_opcode, 0},
9721+
9722+{"vmvv", "Xhwacha", "#d,#s", MATCH_VMVV, MASK_VMVV, match_opcode, 0},
9723+{"vmsv", "Xhwacha", "#d,s", MATCH_VMSV, MASK_VMSV, match_opcode, 0},
9724+{"vfmvv", "Xhwacha", "#D,#S", MATCH_VFMVV, MASK_VFMVV, match_opcode, 0},
9725+{"vfmsv.d", "Xhwacha", "#D,s", MATCH_VFMSV_D, MASK_VFMSV_D, match_opcode, 0},
9726+{"vfmsv.s", "Xhwacha", "#D,s", MATCH_VFMSV_S, MASK_VFMSV_S, match_opcode, 0},
9727+
9728+{"vf", "Xhwacha", "q(s)", MATCH_VF, MASK_VF, match_opcode, 0},
9729+{"vf", "Xhwacha", "A,s", 0, (int) M_VF, match_never, INSN_MACRO },
9730+
9731+{"vxcptcause", "Xhwacha", "d", MATCH_VXCPTCAUSE, MASK_VXCPTCAUSE, match_opcode, 0},
9732+{"vxcptaux", "Xhwacha", "d", MATCH_VXCPTAUX, MASK_VXCPTAUX, match_opcode, 0},
9733+
9734+{"vxcptsave", "Xhwacha", "s", MATCH_VXCPTSAVE, MASK_VXCPTSAVE, match_opcode, 0},
9735+{"vxcptrestore", "Xhwacha", "s", MATCH_VXCPTRESTORE, MASK_VXCPTRESTORE, match_opcode, 0},
9736+{"vxcptkill", "Xhwacha", "", MATCH_VXCPTKILL, MASK_VXCPTKILL, match_opcode, 0},
9737+
9738+{"vxcptevac", "Xhwacha", "s", MATCH_VXCPTEVAC, MASK_VXCPTEVAC, match_opcode, 0},
9739+{"vxcpthold", "Xhwacha", "", MATCH_VXCPTHOLD, MASK_VXCPTHOLD, match_opcode, 0},
9740+{"venqcmd", "Xhwacha", "s,t", MATCH_VENQCMD, MASK_VENQCMD, match_opcode, 0},
9741+{"venqimm1", "Xhwacha", "s,t", MATCH_VENQIMM1, MASK_VENQIMM1, match_opcode, 0},
9742+{"venqimm2", "Xhwacha", "s,t", MATCH_VENQIMM2, MASK_VENQIMM2, match_opcode, 0},
9743+{"venqcnt", "Xhwacha", "s,t", MATCH_VENQCNT, MASK_VENQCNT, match_opcode, 0},
9744+};
9745+
9746+#define RISCV_NUM_OPCODES \
9747+ ((sizeof riscv_builtin_opcodes) / (sizeof (riscv_builtin_opcodes[0])))
9748+const int bfd_riscv_num_builtin_opcodes = RISCV_NUM_OPCODES;
9749+
9750+/* const removed from the following to allow for dynamic extensions to the
9751+ * built-in instruction set. */
9752+struct riscv_opcode *riscv_opcodes =
9753+ (struct riscv_opcode *) riscv_builtin_opcodes;
9754+int bfd_riscv_num_opcodes = RISCV_NUM_OPCODES;
9755+#undef RISCV_NUM_OPCODES