Add RISC-V support.

This commit is contained in:
matt 2014-09-19 17:19:52 +00:00
parent be551d1b14
commit 41b40da6f6
81 changed files with 28282 additions and 4882 deletions

View File

@ -245,6 +245,9 @@ DESCRIPTION
.#define bfd_mach_ppc_e6500 5007
.#define bfd_mach_ppc_titan 83
.#define bfd_mach_ppc_vle 84
. bfd_arch_riscv, {* RISC-V *}
.#define bfd_mach_riscv32 132
.#define bfd_mach_riscv64 164
. bfd_arch_rs6000, {* IBM RS/6000 *}
.#define bfd_mach_rs6k 6000
.#define bfd_mach_rs6k_rs1 6001
@ -562,6 +565,7 @@ extern const bfd_arch_info_type bfd_pj_arch;
extern const bfd_arch_info_type bfd_plugin_arch;
extern const bfd_arch_info_type bfd_powerpc_archs[];
#define bfd_powerpc_arch bfd_powerpc_archs[0]
extern const bfd_arch_info_type bfd_riscv_arch;
extern const bfd_arch_info_type bfd_rs6000_arch;
extern const bfd_arch_info_type bfd_rl78_arch;
extern const bfd_arch_info_type bfd_rx_arch;
@ -645,6 +649,7 @@ static const bfd_arch_info_type * const bfd_archures_list[] =
&bfd_or1k_arch,
&bfd_pdp11_arch,
&bfd_powerpc_arch,
&bfd_riscv_arch,
&bfd_rs6000_arch,
&bfd_rl78_arch,
&bfd_rx_arch,

View File

@ -1976,6 +1976,9 @@ enum bfd_architecture
#define bfd_mach_ppc_e6500 5007
#define bfd_mach_ppc_titan 83
#define bfd_mach_ppc_vle 84
bfd_arch_riscv, /* RISC-V */
#define bfd_mach_riscv32 132
#define bfd_mach_riscv64 164
bfd_arch_rs6000, /* IBM RS/6000 */
#define bfd_mach_rs6k 6000
#define bfd_mach_rs6k_rs1 6001
@ -4831,6 +4834,43 @@ a matching LO8XG part. */
BFD_RELOC_OR1K_TLS_DTPOFF,
BFD_RELOC_OR1K_TLS_DTPMOD,
/* RISC-V relocations. */
BFD_RELOC_RISCV_ADD32,
BFD_RELOC_RISCV_ADD64,
BFD_RELOC_RISCV_SUB32,
BFD_RELOC_RISCV_SUB64,
BFD_RELOC_RISCV_HI20,
BFD_RELOC_RISCV_LO12_I,
BFD_RELOC_RISCV_LO12_S,
BFD_RELOC_RISCV_PCREL_LO12_I,
BFD_RELOC_RISCV_PCREL_LO12_S,
BFD_RELOC_RISCV_CALL,
BFD_RELOC_RISCV_CALL_PLT,
BFD_RELOC_RISCV_PCREL_HI20,
BFD_RELOC_RISCV_JMP,
BFD_RELOC_RISCV_GOT_HI20,
BFD_RELOC_RISCV_GOT_LO12,
BFD_RELOC_RISCV_TLS_DTPMOD32,
BFD_RELOC_RISCV_TLS_DTPREL32,
BFD_RELOC_RISCV_TLS_DTPMOD64,
BFD_RELOC_RISCV_TLS_DTPREL64,
BFD_RELOC_RISCV_TLS_TPREL32,
BFD_RELOC_RISCV_TLS_TPREL64,
BFD_RELOC_RISCV_TPREL_HI20,
BFD_RELOC_RISCV_TPREL_ADD,
BFD_RELOC_RISCV_TPREL_LO12_S,
BFD_RELOC_RISCV_TPREL_LO12_I,
BFD_RELOC_RISCV_TLS_IE_HI20,
BFD_RELOC_RISCV_TLS_IE_LO12,
BFD_RELOC_RISCV_TLS_IE_ADD,
BFD_RELOC_RISCV_TLS_IE_LO12_S,
BFD_RELOC_RISCV_TLS_IE_LO12_I,
BFD_RELOC_RISCV_TLS_GOT_HI20,
BFD_RELOC_RISCV_TLS_GOT_LO12,
BFD_RELOC_RISCV_TLS_GD_HI20,
BFD_RELOC_RISCV_TLS_GD_LO12,
BFD_RELOC_RISCV_TLS_PCREL_LO12,
/* H8 elf Relocations. */
BFD_RELOC_H8_DIR16A8,
BFD_RELOC_H8_DIR16R8,

View File

@ -97,6 +97,7 @@ or1k*) targ_archs=bfd_or1k_arch ;;
pdp11*) targ_archs=bfd_pdp11_arch ;;
pj*) targ_archs="bfd_pj_arch bfd_i386_arch";;
powerpc*) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
riscv*) targ_archs=bfd_riscv_arch ;;
rs6000) targ_archs="bfd_rs6000_arch bfd_powerpc_arch" ;;
s390*) targ_archs=bfd_s390_arch ;;
sh*) targ_archs=bfd_sh_arch ;;
@ -1272,6 +1273,14 @@ case "${targ}" in
targ_defvec=bfd_elf32_rl78_vec
;;
#ifdef BFD64
riscv*-*-*)
targ_defvec=bfd_elf64_riscv_vec
targ_selvecs="bfd_elf32_riscv_vec bfd_elf64_riscv_vec"
want64=true
;;
#endif
rx-*-elf)
targ_defvec=bfd_elf32_rx_le_vec
targ_selvecs="bfd_elf32_rx_be_vec bfd_elf32_rx_le_vec bfd_elf32_rx_be_ns_vec"

View File

@ -15286,6 +15286,7 @@ do
bfd_elf32_powerpcle_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
bfd_elf32_powerpc_freebsd_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
bfd_elf32_powerpc_vxworks_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
bfd_elf32_riscv_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf32.lo $elf" ;;
bfd_elf32_rl78_vec) tb="$tb elf32-rl78.lo $elf" ;;
bfd_elf32_rx_le_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
bfd_elf32_rx_be_vec) tb="$tb elf32-rx.lo elf32.lo $elf" ;;
@ -15356,6 +15357,7 @@ do
bfd_elf64_powerpc_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_powerpcle_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_powerpc_freebsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_riscv_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;;
bfd_elf64_s390_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_sh64_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_sh64l_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;

View File

@ -773,6 +773,7 @@ do
tb="$tb elfn32-mips.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_openrisc_vec) tb="$tb elf32-openrisc.lo elf32.lo $elf" ;;
bfd_elf32_or1k_big_vec) tb="$tb elf32-or1k.lo elf32.lo $elf" ;;
bfd_elf32_riscv_vec) tb="$tb elf32-riscv.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;;
bfd_elf32_pj_vec) tb="$tb elf32-pj.lo elf32.lo $elf";;
bfd_elf32_pjl_vec) tb="$tb elf32-pj.lo elf32.lo $elf";;
bfd_elf32_powerpc_vec) tb="$tb elf32-ppc.lo elf-vxworks.lo elf32.lo $elf" ;;
@ -836,6 +837,7 @@ do
bfd_elf64_bigaarch64_vec) tb="$tb elf64-aarch64.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_big_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_bigmips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_m32c_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
bfd_elf64_hppa_linux_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_hppa_vec) tb="$tb elf64-hppa.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_ia64_big_vec) tb="$tb elf64-ia64.lo elfxx-ia64.lo elf64.lo $elf"; target_size=64 ;;
@ -845,10 +847,12 @@ do
bfd_elf64_littleaarch64_vec)tb="$tb elf64-aarch64.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_little_generic_vec) tb="$tb elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_littlemips_vec) tb="$tb elf64-mips.lo elf64.lo elfxx-mips.lo elf-vxworks.lo elf32.lo $elf ecofflink.lo"; target_size=64 ;;
bfd_elf32_m32c_vec) tb="$tb elf32-m32c.lo elf32.lo $elf" ;;
bfd_elf64_mmix_vec) tb="$tb elf64-mmix.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_powerpc_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_powerpcle_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_powerpc_freebsd_vec) tb="$tb elf64-ppc.lo elf64-gen.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_riscv_vec) tb="$tb elf64-riscv.lo elf64.lo elfxx-riscv.lo elf32.lo $elf"; target_size=64 ;;
bfd_elf64_s390_vec) tb="$tb elf64-s390.lo elf64.lo $elf"; target_size=64 ;;
bfd_elf64_sh64_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;
bfd_elf64_sh64l_vec) tb="$tb elf64-sh64.lo elf64.lo $elf" target_size=64 ;;

View File

@ -0,0 +1,80 @@
/* BFD backend for RISC-V
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
static const bfd_arch_info_type *riscv_compatible
(const bfd_arch_info_type *, const bfd_arch_info_type *);
/* The default routine tests bits_per_word, which is wrong on RISC-V, as
RISC-V word size doesn't correlate with reloc size. */
static const bfd_arch_info_type *
riscv_compatible (const bfd_arch_info_type *a, const bfd_arch_info_type *b)
{
if (a->arch != b->arch)
return NULL;
/* Machine compatibility is checked in
_bfd_riscv_elf_merge_private_bfd_data. */
return a;
}
#define N(BITS_WORD, BITS_ADDR, NUMBER, PRINT, DEFAULT, NEXT) \
{ \
BITS_WORD, /* bits in a word */ \
BITS_ADDR, /* bits in an address */ \
8, /* 8 bits in a byte */ \
bfd_arch_riscv, \
NUMBER, \
"riscv", \
PRINT, \
3, \
DEFAULT, \
riscv_compatible, \
bfd_default_scan, \
bfd_arch_default_fill, \
NEXT, \
}
enum
{
I_riscv64,
I_riscv32
};
#define NN(index) (&arch_info_struct[(index) + 1])
static const bfd_arch_info_type arch_info_struct[] =
{
N (64, 64, bfd_mach_riscv64, "riscv:rv64", FALSE, NN(I_riscv64)),
N (32, 32, bfd_mach_riscv32, "riscv:rv32", FALSE, 0)
};
/* The default architecture is riscv:rv64. */
const bfd_arch_info_type bfd_riscv_arch =
N (64, 64, 0, "riscv", TRUE, &arch_info_struct[0]);

View File

@ -423,6 +423,7 @@ enum elf_target_id
OR1K_ELF_DATA,
PPC32_ELF_DATA,
PPC64_ELF_DATA,
RISCV_ELF_DATA,
S390_ELF_DATA,
SH_ELF_DATA,
SPARC_ELF_DATA,

View File

@ -0,0 +1,193 @@
/* RISC-V-specific support for 32-bit ELF
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* This file handles RISC-V ELF targets. */
#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "bfdlink.h"
#include "genlink.h"
#include "elf-bfd.h"
#include "elfxx-riscv.h"
#include "elf/riscv.h"
#include "opcode/riscv.h"
#include "opcode/riscv.h"
static bfd_boolean riscv_elf32_object_p
(bfd *);
static bfd_boolean elf32_riscv_grok_prstatus
(bfd *, Elf_Internal_Note *);
static bfd_boolean elf32_riscv_grok_psinfo
(bfd *, Elf_Internal_Note *);
/* The number of local .got entries we reserve. */
#define RISCV_RESERVED_GOTNO (2)
/* Set the right machine number for a RISC-V ELF file. */
static bfd_boolean
riscv_elf32_object_p (bfd *abfd)
{
bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv32);
return TRUE;
}
/* Support for core dump NOTE sections. */
static bfd_boolean
elf32_riscv_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
unsigned int size;
switch (note->descsz)
{
default:
return FALSE;
case 440: /* Linux/RISC-V */
/* pr_cursig */
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 24);
/* pr_reg */
offset = 72;
size = 360;
break;
}
/* Make a ".reg/999" section. */
return _bfd_elfcore_make_pseudosection (abfd, ".reg", size,
note->descpos + offset);
}
static bfd_boolean
elf32_riscv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
switch (note->descsz)
{
default:
return FALSE;
case 128: /* Linux/RISC-V elf_prpsinfo */
elf_tdata (abfd)->core_program
= _bfd_elfcore_strndup (abfd, note->descdata + 32, 16);
elf_tdata (abfd)->core_command
= _bfd_elfcore_strndup (abfd, note->descdata + 48, 80);
}
/* Note that for some reason, a spurious space is tacked
onto the end of the args in some (at least one anyway)
implementations, so strip it off if it exists. */
{
char *command = elf_tdata (abfd)->core_command;
int n = strlen (command);
if (0 < n && command[n - 1] == ' ')
command[n - 1] = '\0';
}
return TRUE;
}
#define ELF_ARCH bfd_arch_riscv
#define ELF_TARGET_ID RISCV_ELF_DATA
#define ELF_MACHINE_CODE EM_RISCV
#define elf_backend_collect TRUE
#define elf_backend_type_change_ok TRUE
#define elf_backend_can_gc_sections TRUE
#define elf_info_to_howto riscv_elf_info_to_howto_rela
#define elf_backend_object_p riscv_elf32_object_p
#define elf_backend_symbol_processing _bfd_riscv_elf_symbol_processing
#define elf_backend_create_dynamic_sections \
_bfd_riscv_elf_create_dynamic_sections
#define elf_backend_check_relocs _bfd_riscv_elf_check_relocs
#define elf_backend_merge_symbol_attribute \
_bfd_riscv_elf_merge_symbol_attribute
#define elf_backend_get_target_dtag _bfd_riscv_elf_get_target_dtag
#define elf_backend_adjust_dynamic_symbol \
_bfd_riscv_elf_adjust_dynamic_symbol
#define elf_backend_always_size_sections \
_bfd_riscv_elf_always_size_sections
#define elf_backend_size_dynamic_sections \
_bfd_riscv_elf_size_dynamic_sections
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
#define elf_backend_relocate_section _bfd_riscv_elf_relocate_section
#define elf_backend_finish_dynamic_symbol \
_bfd_riscv_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
_bfd_riscv_elf_finish_dynamic_sections
#define elf_backend_additional_program_headers \
_bfd_riscv_elf_additional_program_headers
#define elf_backend_modify_segment_map _bfd_riscv_elf_modify_segment_map
#define elf_backend_copy_indirect_symbol \
_bfd_riscv_elf_copy_indirect_symbol
#define elf_backend_grok_prstatus elf32_riscv_grok_prstatus
#define elf_backend_grok_psinfo elf32_riscv_grok_psinfo
#define elf_backend_got_header_size (4 * RISCV_RESERVED_GOTNO)
/* RISC-V ELF can use a mixture of REL and RELA, but some Relocations
work better/work only in RELA, so we default to this. */
#define elf_backend_may_use_rel_p 1
#define elf_backend_may_use_rela_p 1
#define elf_backend_default_use_rela_p 1
#define elf_backend_rela_plts_and_copies_p 0
#define elf_backend_sign_extend_vma TRUE
#define elf_backend_plt_readonly 1
#define elf_backend_plt_sym_val _bfd_riscv_elf_plt_sym_val
#define elf_backend_discard_info _bfd_riscv_elf_discard_info
#define elf_backend_ignore_discarded_relocs \
_bfd_riscv_elf_ignore_discarded_relocs
#define elf_backend_write_section _bfd_riscv_elf_write_section
#define bfd_elf32_new_section_hook _bfd_riscv_elf_new_section_hook
#define bfd_elf32_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define bfd_elf32_bfd_link_hash_table_create \
_bfd_riscv_elf_link_hash_table_create
#define bfd_elf32_bfd_final_link _bfd_riscv_elf_final_link
#define bfd_elf32_bfd_merge_private_bfd_data \
_bfd_riscv_elf_merge_private_bfd_data
#define bfd_elf32_bfd_print_private_bfd_data \
_bfd_riscv_elf_print_private_bfd_data
#define bfd_elf32_bfd_relax_section _bfd_riscv_relax_section
#define bfd_elf32_bfd_reloc_type_lookup \
riscv_elf_bfd_reloc_type_lookup
#define bfd_elf32_bfd_reloc_name_lookup \
riscv_elf_bfd_reloc_name_lookup
#define TARGET_LITTLE_SYM bfd_elf32_riscv_vec
#define TARGET_LITTLE_NAME "elf32-littleriscv"
#define ELF_MAXPAGESIZE 0x1000
#define ELF_COMMONPAGESIZE 0x1000
#include "elf32-target.h"

View File

@ -0,0 +1,218 @@
/* RISC-V-specific support for 64-bit ELF
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* This file supports the 64-bit RISC-V ELF ABI. */
#include "sysdep.h"
#include "bfd.h"
#include "libbfd.h"
#include "aout/ar.h"
#include "bfdlink.h"
#include "genlink.h"
#include "elf-bfd.h"
#include "elfxx-riscv.h"
#include "elf/riscv.h"
#include "opcode/riscv.h"
static bfd_boolean riscv_elf64_object_p
(bfd *);
static bfd_boolean elf64_riscv_grok_prstatus
(bfd *, Elf_Internal_Note *);
static bfd_boolean elf64_riscv_grok_psinfo
(bfd *, Elf_Internal_Note *);
/* The number of local .got entries we reserve. */
#define RISCV_RESERVED_GOTNO (2)
/* Set the right machine number for a RISC-V ELF file. */
static bfd_boolean
riscv_elf64_object_p (bfd *abfd)
{
bfd_default_set_arch_mach (abfd, bfd_arch_riscv, bfd_mach_riscv64);
return TRUE;
}
/* Support for core dump NOTE sections. */
static bfd_boolean
elf64_riscv_grok_prstatus (bfd *abfd, Elf_Internal_Note *note)
{
int offset;
unsigned int size;
switch (note->descsz)
{
default:
return FALSE;
case 480: /* Linux/RISC-V - RV64 kernel */
/* pr_cursig */
elf_tdata (abfd)->core_signal = bfd_get_16 (abfd, note->descdata + 12);
/* pr_pid */
elf_tdata (abfd)->core_lwpid = bfd_get_32 (abfd, note->descdata + 32);
/* pr_reg */
offset = 112;
size = 360;
break;
}
/* Make a ".reg/999" section. */
return _bfd_elfcore_make_pseudosection (abfd, ".reg",
size, note->descpos + offset);
}
static bfd_boolean
elf64_riscv_grok_psinfo (bfd *abfd, Elf_Internal_Note *note)
{
switch (note->descsz)
{
default:
return FALSE;
case 136: /* Linux/RISC-V - 64-bit kernel elf_prpsinfo */
elf_tdata (abfd)->core_program
= _bfd_elfcore_strndup (abfd, note->descdata + 40, 16);
elf_tdata (abfd)->core_command
= _bfd_elfcore_strndup (abfd, note->descdata + 56, 80);
}
/* Note that for some reason, a spurious space is tacked
onto the end of the args in some (at least one anyway)
implementations, so strip it off if it exists. */
{
char *command = elf_tdata (abfd)->core_command;
int n = strlen (command);
if (0 < n && command[n - 1] == ' ')
command[n - 1] = '\0';
}
return TRUE;
}
#define ELF_ARCH bfd_arch_riscv
#define ELF_TARGET_ID RISCV_ELF_DATA
#define ELF_MACHINE_CODE EM_RISCV
#define elf_backend_collect TRUE
#define elf_backend_type_change_ok TRUE
#define elf_backend_can_gc_sections TRUE
#define elf_info_to_howto riscv_elf_info_to_howto_rela
#define elf_backend_object_p riscv_elf64_object_p
#define elf_backend_symbol_processing _bfd_riscv_elf_symbol_processing
#define elf_backend_create_dynamic_sections \
_bfd_riscv_elf_create_dynamic_sections
#define elf_backend_check_relocs _bfd_riscv_elf_check_relocs
#define elf_backend_merge_symbol_attribute \
_bfd_riscv_elf_merge_symbol_attribute
#define elf_backend_get_target_dtag _bfd_riscv_elf_get_target_dtag
#define elf_backend_adjust_dynamic_symbol \
_bfd_riscv_elf_adjust_dynamic_symbol
#define elf_backend_always_size_sections \
_bfd_riscv_elf_always_size_sections
#define elf_backend_size_dynamic_sections \
_bfd_riscv_elf_size_dynamic_sections
#define elf_backend_init_index_section _bfd_elf_init_1_index_section
#define elf_backend_relocate_section _bfd_riscv_elf_relocate_section
#define elf_backend_finish_dynamic_symbol \
_bfd_riscv_elf_finish_dynamic_symbol
#define elf_backend_finish_dynamic_sections \
_bfd_riscv_elf_finish_dynamic_sections
#define elf_backend_additional_program_headers \
_bfd_riscv_elf_additional_program_headers
#define elf_backend_modify_segment_map _bfd_riscv_elf_modify_segment_map
#define elf_backend_copy_indirect_symbol \
_bfd_riscv_elf_copy_indirect_symbol
#define elf_backend_ignore_discarded_relocs \
_bfd_riscv_elf_ignore_discarded_relocs
#define elf_backend_grok_prstatus elf64_riscv_grok_prstatus
#define elf_backend_grok_psinfo elf64_riscv_grok_psinfo
#define elf_backend_got_header_size (4 * RISCV_RESERVED_GOTNO)
/* RISC-V ELF64 can use a mixture of REL and RELA, but some Relocations
work better/work only in RELA, so we default to this. */
#define elf_backend_may_use_rel_p 1
#define elf_backend_may_use_rela_p 1
#define elf_backend_default_use_rela_p 1
#define elf_backend_rela_plts_and_copies_p 0
#define elf_backend_plt_readonly 1
#define elf_backend_plt_sym_val _bfd_riscv_elf_plt_sym_val
#define elf_backend_sign_extend_vma TRUE
#define elf_backend_write_section _bfd_riscv_elf_write_section
#define bfd_elf64_new_section_hook _bfd_riscv_elf_new_section_hook
#define bfd_elf64_bfd_get_relocated_section_contents \
bfd_generic_get_relocated_section_contents
#define bfd_elf64_bfd_link_hash_table_create \
_bfd_riscv_elf_link_hash_table_create
#define bfd_elf64_bfd_final_link _bfd_riscv_elf_final_link
#define bfd_elf64_bfd_merge_private_bfd_data \
_bfd_riscv_elf_merge_private_bfd_data
#define bfd_elf64_bfd_print_private_bfd_data \
_bfd_riscv_elf_print_private_bfd_data
#define bfd_elf64_bfd_relax_section _bfd_riscv_relax_section
/* RISC-V ELF64 archive functions. */
#define bfd_elf64_archive_functions
extern bfd_boolean bfd_elf64_archive_slurp_armap
(bfd *);
extern bfd_boolean bfd_elf64_archive_write_armap
(bfd *, unsigned int, struct orl *, unsigned int, int);
#define bfd_elf64_archive_slurp_extended_name_table \
_bfd_archive_coff_slurp_extended_name_table
#define bfd_elf64_archive_construct_extended_name_table \
_bfd_archive_coff_construct_extended_name_table
#define bfd_elf64_archive_truncate_arname \
_bfd_archive_coff_truncate_arname
#define bfd_elf64_archive_read_ar_hdr _bfd_archive_coff_read_ar_hdr
#define bfd_elf64_archive_write_ar_hdr _bfd_archive_coff_write_ar_hdr
#define bfd_elf64_archive_openr_next_archived_file \
_bfd_archive_coff_openr_next_archived_file
#define bfd_elf64_archive_get_elt_at_index \
_bfd_archive_coff_get_elt_at_index
#define bfd_elf64_archive_generic_stat_arch_elt \
_bfd_archive_coff_generic_stat_arch_elt
#define bfd_elf64_archive_update_armap_timestamp \
_bfd_archive_coff_update_armap_timestamp
#define bfd_elf64_bfd_reloc_type_lookup \
riscv_elf_bfd_reloc_type_lookup
#define bfd_elf64_bfd_reloc_name_lookup \
riscv_elf_bfd_reloc_name_lookup
#define TARGET_LITTLE_SYM bfd_elf64_riscv_vec
#define TARGET_LITTLE_NAME "elf64-littleriscv"
#define ELF_MAXPAGESIZE 0x2000
#define ELF_COMMONPAGESIZE 0x2000
#include "elf64-target.h"

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,109 @@
/* RISC-V ELF specific backend routines.
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#include "elf/common.h"
#include "elf/internal.h"
#include "elf/riscv.h"
extern bfd_boolean _bfd_riscv_elf_new_section_hook
(bfd *, asection *);
extern void _bfd_riscv_elf_symbol_processing
(bfd *, asymbol *);
extern unsigned int _bfd_riscv_elf_eh_frame_address_size
(bfd *, asection *);
extern bfd_boolean _bfd_riscv_elf_fake_sections
(bfd *, Elf_Internal_Shdr *, asection *);
extern bfd_boolean _bfd_riscv_elf_create_dynamic_sections
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_riscv_elf_check_relocs
(bfd *, struct bfd_link_info *, asection *, const Elf_Internal_Rela *);
extern bfd_boolean _bfd_riscv_elf_adjust_dynamic_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *);
extern bfd_boolean _bfd_riscv_elf_always_size_sections
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_riscv_elf_size_dynamic_sections
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_riscv_elf_relocate_section
(bfd *, struct bfd_link_info *, bfd *, asection *, bfd_byte *,
Elf_Internal_Rela *, Elf_Internal_Sym *, asection **);
extern bfd_boolean _bfd_riscv_elf_finish_dynamic_symbol
(bfd *, struct bfd_link_info *, struct elf_link_hash_entry *,
Elf_Internal_Sym *);
extern bfd_boolean _bfd_riscv_elf_finish_dynamic_sections
(bfd *, struct bfd_link_info *);
extern int _bfd_riscv_elf_additional_program_headers
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_riscv_elf_modify_segment_map
(bfd *, struct bfd_link_info *);
extern void _bfd_riscv_elf_copy_indirect_symbol
(struct bfd_link_info *, struct elf_link_hash_entry *,
struct elf_link_hash_entry *);
extern bfd_boolean _bfd_riscv_elf_ignore_discarded_relocs
(asection *);
extern bfd_boolean _bfd_riscv_elf_find_nearest_line
(bfd *, asection *, asymbol **, bfd_vma, const char **,
const char **, unsigned int *);
extern bfd_boolean _bfd_riscv_elf_find_inliner_info
(bfd *, const char **, const char **, unsigned int *);
extern bfd_boolean _bfd_riscv_elf_set_section_contents
(bfd *, asection *, const void *, file_ptr, bfd_size_type);
extern struct bfd_link_hash_table *_bfd_riscv_elf_link_hash_table_create
(bfd *);
extern bfd_boolean _bfd_riscv_elf_final_link
(bfd *, struct bfd_link_info *);
extern bfd_boolean _bfd_riscv_elf_merge_private_bfd_data
(bfd *, bfd *);
extern bfd_boolean _bfd_riscv_elf_print_private_bfd_data
(bfd *, void *);
extern bfd_boolean _bfd_riscv_elf_discard_info
(bfd *, struct elf_reloc_cookie *, struct bfd_link_info *);
extern bfd_boolean _bfd_riscv_elf_write_section
(bfd *, struct bfd_link_info *, asection *, bfd_byte *);
extern bfd_reloc_status_type _bfd_riscv_elf_generic_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
extern bfd_boolean _bfd_riscv_relax_section
(bfd *, asection *, struct bfd_link_info *, bfd_boolean *);
extern void _bfd_riscv_elf_merge_symbol_attribute
(struct elf_link_hash_entry *, const Elf_Internal_Sym *, bfd_boolean, bfd_boolean);
extern char *_bfd_riscv_elf_get_target_dtag (bfd_vma);
extern void _bfd_riscv_elf_use_plts_and_copy_relocs
(struct bfd_link_info *);
extern bfd_vma _bfd_riscv_elf_plt_sym_val
(bfd_vma, const asection *, const arelent *rel);
extern const struct bfd_elf_special_section _bfd_riscv_elf_special_sections [];
extern bfd_boolean _bfd_riscv_elf_common_definition (Elf_Internal_Sym *);
extern reloc_howto_type *riscv_elf_bfd_reloc_type_lookup
(bfd *, bfd_reloc_code_real_type);
extern reloc_howto_type *riscv_elf_bfd_reloc_name_lookup (bfd *, const char *);
extern void riscv_elf_info_to_howto_rel
(bfd *, arelent *, Elf_Internal_Rela *);
extern void riscv_elf_info_to_howto_rela
(bfd *, arelent *, Elf_Internal_Rela *);
#define elf_backend_common_definition _bfd_riscv_elf_common_definition
#define elf_backend_special_sections _bfd_riscv_elf_special_sections
#define elf_backend_eh_frame_address_size _bfd_riscv_elf_eh_frame_address_size
#define elf_backend_merge_symbol_attribute _bfd_riscv_elf_merge_symbol_attribute

View File

@ -2319,6 +2319,41 @@ static const char *const bfd_reloc_code_real_names[] = { "@@uninitialized@@",
"BFD_RELOC_OR1K_TLS_TPOFF",
"BFD_RELOC_OR1K_TLS_DTPOFF",
"BFD_RELOC_OR1K_TLS_DTPMOD",
"BFD_RELOC_RISCV_ADD32",
"BFD_RELOC_RISCV_ADD64",
"BFD_RELOC_RISCV_SUB32",
"BFD_RELOC_RISCV_SUB64",
"BFD_RELOC_RISCV_HI20",
"BFD_RELOC_RISCV_LO12_I",
"BFD_RELOC_RISCV_LO12_S",
"BFD_RELOC_RISCV_PCREL_LO12_I",
"BFD_RELOC_RISCV_PCREL_LO12_S",
"BFD_RELOC_RISCV_CALL",
"BFD_RELOC_RISCV_CALL_PLT",
"BFD_RELOC_RISCV_PCREL_HI20",
"BFD_RELOC_RISCV_JMP",
"BFD_RELOC_RISCV_GOT_HI20",
"BFD_RELOC_RISCV_GOT_LO12",
"BFD_RELOC_RISCV_TLS_DTPMOD32",
"BFD_RELOC_RISCV_TLS_DTPREL32",
"BFD_RELOC_RISCV_TLS_DTPMOD64",
"BFD_RELOC_RISCV_TLS_DTPREL64",
"BFD_RELOC_RISCV_TLS_TPREL32",
"BFD_RELOC_RISCV_TLS_TPREL64",
"BFD_RELOC_RISCV_TPREL_HI20",
"BFD_RELOC_RISCV_TPREL_ADD",
"BFD_RELOC_RISCV_TPREL_LO12_S",
"BFD_RELOC_RISCV_TPREL_LO12_I",
"BFD_RELOC_RISCV_TLS_IE_HI20",
"BFD_RELOC_RISCV_TLS_IE_LO12",
"BFD_RELOC_RISCV_TLS_IE_ADD",
"BFD_RELOC_RISCV_TLS_IE_LO12_S",
"BFD_RELOC_RISCV_TLS_IE_LO12_I",
"BFD_RELOC_RISCV_TLS_GOT_HI20",
"BFD_RELOC_RISCV_TLS_GOT_LO12",
"BFD_RELOC_RISCV_TLS_GD_HI20",
"BFD_RELOC_RISCV_TLS_GD_LO12",
"BFD_RELOC_RISCV_TLS_PCREL_LO12",
"BFD_RELOC_H8_DIR16A8",
"BFD_RELOC_H8_DIR16R8",
"BFD_RELOC_H8_DIR24A8",

View File

@ -606,6 +606,7 @@ extern const bfd_target bfd_elf32_bigarm_symbian_vec;
extern const bfd_target bfd_elf32_bigarm_vxworks_vec;
extern const bfd_target bfd_elf32_bigmips_vec;
extern const bfd_target bfd_elf32_bigmips_vxworks_vec;
extern const bfd_target bfd_elf32_bigriscv_vec;
extern const bfd_target bfd_elf32_cr16_vec;
extern const bfd_target bfd_elf32_cr16c_vec;
extern const bfd_target bfd_elf32_cris_vec;
@ -677,6 +678,7 @@ extern const bfd_target bfd_elf32_powerpc_vec;
extern const bfd_target bfd_elf32_powerpcle_vec;
extern const bfd_target bfd_elf32_powerpc_freebsd_vec;
extern const bfd_target bfd_elf32_powerpc_vxworks_vec;
extern const bfd_target bfd_elf32_riscv_vec;
extern const bfd_target bfd_elf32_rl78_vec;
extern const bfd_target bfd_elf32_rx_le_vec;
extern const bfd_target bfd_elf32_rx_be_vec;
@ -729,8 +731,9 @@ extern const bfd_target bfd_elf32_xtensa_le_vec;
extern const bfd_target bfd_elf64_alpha_freebsd_vec;
extern const bfd_target bfd_elf64_alpha_vec;
extern const bfd_target bfd_elf64_big_generic_vec;
extern const bfd_target bfd_elf64_bigmips_vec;
extern const bfd_target bfd_elf64_bigaarch64_vec;
extern const bfd_target bfd_elf64_bigmips_vec;
extern const bfd_target bfd_elf64_bigriscv_vec;
extern const bfd_target bfd_elf64_hppa_linux_vec;
extern const bfd_target bfd_elf64_hppa_vec;
extern const bfd_target bfd_elf64_ia64_big_vec;
@ -738,12 +741,13 @@ extern const bfd_target bfd_elf64_ia64_hpux_big_vec;
extern const bfd_target bfd_elf64_ia64_little_vec;
extern const bfd_target bfd_elf64_ia64_vms_vec;
extern const bfd_target bfd_elf64_little_generic_vec;
extern const bfd_target bfd_elf64_littlemips_vec;
extern const bfd_target bfd_elf64_littleaarch64_vec;
extern const bfd_target bfd_elf64_littlemips_vec;
extern const bfd_target bfd_elf64_mmix_vec;
extern const bfd_target bfd_elf64_powerpc_vec;
extern const bfd_target bfd_elf64_powerpcle_vec;
extern const bfd_target bfd_elf64_powerpc_freebsd_vec;
extern const bfd_target bfd_elf64_riscv_vec;
extern const bfd_target bfd_elf64_s390_vec;
extern const bfd_target bfd_elf64_sh64_vec;
extern const bfd_target bfd_elf64_sh64l_vec;
@ -1053,6 +1057,7 @@ static const bfd_target * const _bfd_target_vector[] =
&bfd_elf32_powerpc_vxworks_vec,
&bfd_elf32_powerpcle_vec,
&bfd_elf32_powerpc_freebsd_vec,
&bfd_elf32_riscv_vec,
&bfd_elf32_rl78_vec,
&bfd_elf32_rx_be_vec,
&bfd_elf32_rx_be_ns_vec,
@ -1106,8 +1111,9 @@ static const bfd_target * const _bfd_target_vector[] =
&bfd_elf64_alpha_freebsd_vec,
&bfd_elf64_alpha_vec,
&bfd_elf64_big_generic_vec,
&bfd_elf64_bigmips_vec,
&bfd_elf64_bigaarch64_vec,
&bfd_elf64_bigmips_vec,
&bfd_elf64_bigriscv_vec,
&bfd_elf64_hppa_linux_vec,
&bfd_elf64_hppa_vec,
&bfd_elf64_ia64_big_vec,
@ -1115,12 +1121,13 @@ static const bfd_target * const _bfd_target_vector[] =
&bfd_elf64_ia64_little_vec,
&bfd_elf64_ia64_vms_vec,
&bfd_elf64_little_generic_vec,
&bfd_elf64_littlemips_vec,
&bfd_elf64_littleaarch64_vec,
&bfd_elf64_littlemips_vec,
&bfd_elf64_mmix_vec,
&bfd_elf64_powerpc_vec,
&bfd_elf64_powerpcle_vec,
&bfd_elf64_powerpc_freebsd_vec,
&bfd_elf64_riscv_vec,
&bfd_elf64_s390_vec,
&bfd_elf64_sh64_vec,
&bfd_elf64_sh64l_vec,

View File

@ -136,6 +136,7 @@
#include "elf/pj.h"
#include "elf/ppc.h"
#include "elf/ppc64.h"
#include "elf/riscv.h"
#include "elf/rl78.h"
#include "elf/rx.h"
#include "elf/s390.h"
@ -603,6 +604,7 @@ guess_is_rela (unsigned int e_machine)
case EM_NIOS32:
case EM_PPC64:
case EM_PPC:
case EM_RISCV:
case EM_RL78:
case EM_RX:
case EM_S390:
@ -1232,6 +1234,10 @@ dump_relocations (FILE * file,
rtype = elf_microblaze_reloc_type (type);
break;
case EM_RISCV:
rtype = elf_riscv_reloc_type (type);
break;
case EM_RL78:
rtype = elf_rl78_reloc_type (type);
break;

View File

@ -339,6 +339,14 @@ case $basic_machine in
basic_machine=mt-unknown
;;
riscv32-*)
basic_machine=riscv32-ucb
;;
riscv*-*)
basic_machine=riscv-ucb
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;

View File

@ -151,6 +151,7 @@ TARGET_CPU_CFILES = \
config/tc-pdp11.c \
config/tc-pj.c \
config/tc-ppc.c \
config/tc-riscv.c \
config/tc-rl78.c \
config/tc-rx.c \
config/tc-s390.c \
@ -219,6 +220,7 @@ TARGET_CPU_HFILES = \
config/tc-pdp11.h \
config/tc-pj.h \
config/tc-ppc.h \
config/tc-riscv.h \
config/tc-rl78.h \
config/tc-rx.h \
config/tc-s390.h \

View File

@ -419,6 +419,7 @@ TARGET_CPU_CFILES = \
config/tc-pdp11.c \
config/tc-pj.c \
config/tc-ppc.c \
config/tc-riscv.c \
config/tc-rl78.c \
config/tc-rx.c \
config/tc-s390.c \
@ -487,6 +488,7 @@ TARGET_CPU_HFILES = \
config/tc-pdp11.h \
config/tc-pj.h \
config/tc-ppc.h \
config/tc-riscv.h \
config/tc-rl78.h \
config/tc-rx.h \
config/tc-s390.h \
@ -837,6 +839,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-pdp11.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-pj.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-ppc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-riscv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rl78.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-rx.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tc-s390.Po@am__quote@
@ -1500,6 +1503,20 @@ tc-ppc.obj: config/tc-ppc.c
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@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`
tc-riscv.o: config/tc-riscv.c
@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
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-riscv.Tpo $(DEPDIR)/tc-riscv.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-riscv.c' object='tc-riscv.o' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@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
tc-riscv.obj: config/tc-riscv.c
@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`
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-riscv.Tpo $(DEPDIR)/tc-riscv.Po
@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='config/tc-riscv.c' object='tc-riscv.obj' libtool=no @AMDEPBACKSLASH@
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@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`
tc-rl78.o: config/tc-rl78.c
@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
@am__fastdepCC_TRUE@ $(am__mv) $(DEPDIR)/tc-rl78.Tpo $(DEPDIR)/tc-rl78.Po

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,129 @@
/* tc-riscv.h -- header file for tc-riscv.c.
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of GAS.
GAS is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GAS is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GAS; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA
02110-1301, USA. */
#ifndef TC_RISCV
#define TC_RISCV
#include "opcode/riscv.h"
struct frag;
struct expressionS;
#define TARGET_BYTES_BIG_ENDIAN 0
#define TARGET_ARCH bfd_arch_riscv
#define WORKING_DOT_WORD 1
#define OLD_FLOAT_READS
#define REPEAT_CONS_EXPRESSIONS
#define RELOC_EXPANSION_POSSIBLE
#define MAX_RELOC_EXPANSION 3
#define LOCAL_LABELS_FB 1
#define md_relax_frag(segment, fragp, stretch) \
riscv_relax_frag(segment, fragp, stretch)
extern int riscv_relax_frag (asection *, struct frag *, long);
#define md_section_align(seg,size) (size)
#define md_undefined_symbol(name) (0)
#define md_operand(x)
#define NOP_OPCODE RISCV_NOP
extern void riscv_handle_align (struct frag *);
#define HANDLE_ALIGN(fragp) riscv_handle_align (fragp)
#define MAX_MEM_FOR_RS_ALIGN_CODE (1 + 2)
struct insn_label_list;
struct riscv_segment_info {
struct insn_label_list *labels;
};
#define TC_SEGMENT_INFO_TYPE struct riscv_segment_info
#define TC_SYMFIELD_TYPE int
/* The ISA of the target may change based on command-line arguments. */
#define TARGET_FORMAT riscv_target_format()
extern const char *riscv_target_format (void);
#define md_after_parse_args() riscv_after_parse_args()
extern void riscv_after_parse_args (void);
#define tc_init_after_args() riscv_init_after_args()
extern void riscv_init_after_args (void);
#define md_parse_long_option(arg) riscv_parse_long_option (arg)
extern int riscv_parse_long_option (const char *);
#define tc_frob_label(sym) riscv_define_label (sym)
extern void riscv_define_label (symbolS *);
/* Let the linker resolve all the relocs due to relaxation. */
#define tc_fix_adjustable(fixp) 0
#define md_allow_local_subtract(l,r,s) 0
/* Values passed to md_apply_fix don't include symbol values. */
#define MD_APPLY_SYM_VALUE(FIX) 0
/* Global syms must not be resolved, to support ELF shared libraries. */
#define EXTERN_FORCE_RELOC \
(OUTPUT_FLAVOR == bfd_target_elf_flavour)
#define TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG) ((SEG)->flags & SEC_CODE)
#define TC_FORCE_RELOCATION_SUB_LOCAL(FIX, SEG) 1
#define TC_VALIDATE_FIX_SUB(FIX, SEG) TC_FORCE_RELOCATION_SUB_SAME(FIX, SEG)
#define DIFF_EXPR_OK 1
extern void riscv_pop_insert (void);
#define md_pop_insert() riscv_pop_insert()
extern void riscv_clear_insn_labels (void);
#define md_flush_pending_output riscv_clear_insn_labels
extern void riscv_enable_auto_align (void);
#define md_elf_section_change_hook() riscv_enable_auto_align()
enum dwarf2_format;
extern enum dwarf2_format riscv_dwarf2_format (asection *);
#define DWARF2_FORMAT(SEC) riscv_dwarf2_format (SEC)
extern int riscv_dwarf2_addr_size (void);
#define DWARF2_ADDR_SIZE(bfd) riscv_dwarf2_addr_size ()
#define DWARF2_FDE_RELOC_SIZE riscv_dwarf2_addr_size ()
#define TARGET_USE_CFIPOP 1
#define tc_cfi_frame_initial_instructions riscv_cfi_frame_initial_instructions
extern void riscv_cfi_frame_initial_instructions (void);
#define tc_regname_to_dw2regnum tc_riscv_regname_to_dw2regnum
extern int tc_riscv_regname_to_dw2regnum (char *regname);
#define DWARF2_DEFAULT_RETURN_COLUMN LINK_REG
#define DWARF2_CIE_DATA_ALIGNMENT (-4)
#define elf_tc_final_processing riscv_elf_final_processing
extern void riscv_elf_final_processing (void);
#endif /* TC_RISCV */

View File

@ -66,6 +66,8 @@ case ${cpu} in
pj*) cpu_type=pj endian=big ;;
powerpc*le*) cpu_type=ppc endian=little ;;
powerpc*) cpu_type=ppc endian=big ;;
riscv*eb) cpu_type=riscv endian=big ;;
riscv*) cpu_type=riscv endian=little ;;
rs6000*) cpu_type=ppc ;;
rl78*) cpu_type=rl78 ;;
rx) cpu_type=rx ;;
@ -359,6 +361,11 @@ case ${generic_target} in
ppc-*-kaos*) fmt=elf ;;
ppc-*-lynxos*) fmt=elf em=lynx ;;
riscv*eb-*-linux*) fmt=elf endian=big em=linux ;;
riscv*eb-*-netbsd*) fmt=elf endian=big em=nbsd ;;
riscv*-*-linux*) fmt=elf endian=little em=linux ;;
riscv*-*-netbsd*) fmt=elf endian=little em=nbsd ;;
s390-*-linux-*) fmt=elf em=linux ;;
s390-*-tpf*) fmt=elf ;;
@ -453,7 +460,7 @@ case ${generic_target} in
esac
case ${cpu_type} in
aarch64 | alpha | arm | i386 | ia64 | microblaze | mips | ns32k | or1k | or1knd | pdp11 | ppc | sparc | z80 | z8k)
aarch64 | alpha | arm | i386 | ia64 | microblaze | mips | ns32k | or1k | or1knd | pdp11 | ppc | riscv | sparc | z80 | z8k)
bfd_gas=yes
;;
esac

View File

@ -276,6 +276,7 @@ extern int print_insn_ns32k (bfd_vma, disassemble_info *);
extern int print_insn_or1k (bfd_vma, disassemble_info *);
extern int print_insn_pdp11 (bfd_vma, disassemble_info *);
extern int print_insn_pj (bfd_vma, disassemble_info *);
extern int print_insn_riscv (bfd_vma, disassemble_info *);
extern int print_insn_rs6000 (bfd_vma, disassemble_info *);
extern int print_insn_s390 (bfd_vma, disassemble_info *);
extern int print_insn_sh (bfd_vma, disassemble_info *);

View File

@ -298,6 +298,7 @@
#define EM_TILEGX 191 /* Tilera TILE-Gx multicore architecture family */
#define EM_RL78 197 /* Renesas RL78 family. */
#define EM_78K0R 199 /* Renesas 78K0R. */
#define EM_RISCV 243 /* RISC-V */
/* If it is necessary to assign new unofficial EM_* values, please pick large
random numbers (0x8523, 0xa7f2, etc.) to minimize the chances of collision

View File

@ -0,0 +1,174 @@
/* RISC-V ELF support for BFD.
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrw Waterman <waterman@cs.berkeley.edu> at UC Berkeley.
Based on MIPS ELF support for BFD, by Ian Lance Taylor.
This file is part of BFD, the Binary File Descriptor library.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
/* This file holds definitions specific to the RISCV ELF ABI. Note
that most of this is not actually implemented by BFD. */
#ifndef _ELF_RISCV_H
#define _ELF_RISCV_H
#include "elf/reloc-macros.h"
/* Relocation types. */
START_RELOC_NUMBERS (elf_riscv_reloc_type)
RELOC_NUMBER (R_RISCV_NONE, 0)
RELOC_NUMBER (R_RISCV_32, 2)
RELOC_NUMBER (R_RISCV_REL32, 3)
RELOC_NUMBER (R_RISCV_JAL, 4)
RELOC_NUMBER (R_RISCV_HI20, 5)
RELOC_NUMBER (R_RISCV_LO12_I, 6)
RELOC_NUMBER (R_RISCV_LO12_S, 7)
RELOC_NUMBER (R_RISCV_PCREL_LO12_I, 8)
RELOC_NUMBER (R_RISCV_PCREL_LO12_S, 9)
RELOC_NUMBER (R_RISCV_BRANCH, 10)
RELOC_NUMBER (R_RISCV_CALL, 11)
RELOC_NUMBER (R_RISCV_PCREL_HI20, 12)
RELOC_NUMBER (R_RISCV_CALL_PLT, 13)
RELOC_NUMBER (R_RISCV_64, 18)
RELOC_NUMBER (R_RISCV_GOT_HI20, 22)
RELOC_NUMBER (R_RISCV_GOT_LO12, 23)
RELOC_NUMBER (R_RISCV_COPY, 24)
RELOC_NUMBER (R_RISCV_JUMP_SLOT, 25)
/* TLS relocations. */
RELOC_NUMBER (R_RISCV_TLS_IE_HI20, 29)
RELOC_NUMBER (R_RISCV_TLS_IE_LO12, 30)
RELOC_NUMBER (R_RISCV_TLS_IE_ADD, 31)
RELOC_NUMBER (R_RISCV_TLS_IE_LO12_I, 32)
RELOC_NUMBER (R_RISCV_TLS_IE_LO12_S, 33)
RELOC_NUMBER (R_RISCV_TPREL_HI20, 34)
RELOC_NUMBER (R_RISCV_TPREL_LO12_I, 35)
RELOC_NUMBER (R_RISCV_TPREL_LO12_S, 36)
RELOC_NUMBER (R_RISCV_TPREL_ADD, 37)
RELOC_NUMBER (R_RISCV_TLS_DTPMOD32, 38)
RELOC_NUMBER (R_RISCV_TLS_DTPREL32, 39)
RELOC_NUMBER (R_RISCV_TLS_DTPMOD64, 40)
RELOC_NUMBER (R_RISCV_TLS_DTPREL64, 41)
RELOC_NUMBER (R_RISCV_TLS_TPREL32, 47)
RELOC_NUMBER (R_RISCV_TLS_TPREL64, 48)
RELOC_NUMBER (R_RISCV_TLS_PCREL_LO12, 50)
RELOC_NUMBER (R_RISCV_TLS_GOT_HI20, 51)
RELOC_NUMBER (R_RISCV_TLS_GOT_LO12, 52)
RELOC_NUMBER (R_RISCV_TLS_GD_HI20, 53)
RELOC_NUMBER (R_RISCV_TLS_GD_LO12, 54)
RELOC_NUMBER (R_RISCV_GLOB_DAT, 57)
RELOC_NUMBER (R_RISCV_ADD32, 58)
RELOC_NUMBER (R_RISCV_ADD64, 59)
RELOC_NUMBER (R_RISCV_SUB32, 60)
RELOC_NUMBER (R_RISCV_SUB64, 61)
FAKE_RELOC (R_RISCV_max, 62)
END_RELOC_NUMBERS (R_RISCV_maxext)
/* Processor specific flags for the ELF header e_flags field. */
/* Custom flag definitions. */
#define EF_RISCV_EXT_MASK 0xffff
#define EF_RISCV_EXT_SH 16
#define E_RISCV_EXT_Xcustom 0x0000
#define E_RISCV_EXT_Xhwacha 0x0001
#define E_RISCV_EXT_RESERVED 0xffff
#define EF_GET_RISCV_EXT(x) \
((x >> EF_RISCV_EXT_SH) & EF_RISCV_EXT_MASK)
#define EF_SET_RISCV_EXT(x, ext) \
do { x |= ((ext & EF_RISCV_EXT_MASK) << EF_RISCV_EXT_SH); } while (0)
#define EF_IS_RISCV_EXT_Xcustom(x) \
(EF_GET_RISCV_EXT(x) == E_RISCV_EXT_Xcustom)
/* A mapping from extension names to elf flags */
struct riscv_extension_entry
{
const char* name;
unsigned int flag;
};
static const struct riscv_extension_entry riscv_extension_map[] =
{
{"Xcustom", E_RISCV_EXT_Xcustom},
{"Xhwacha", E_RISCV_EXT_Xhwacha},
};
/* Given an extension name, return an elf flag. */
static inline const char* riscv_elf_flag_to_name(unsigned int flag)
{
unsigned int i;
for (i=0; i<sizeof(riscv_extension_map)/sizeof(riscv_extension_map[0]); i++)
if (riscv_extension_map[i].flag == flag)
return riscv_extension_map[i].name;
return NULL;
}
/* Given an elf flag, return an extension name. */
static inline unsigned int riscv_elf_name_to_flag(const char* name)
{
unsigned int i;
for (i=0; i<sizeof(riscv_extension_map)/sizeof(riscv_extension_map[0]); i++)
if (strcmp(riscv_extension_map[i].name, name) == 0)
return riscv_extension_map[i].flag;
return E_RISCV_EXT_Xcustom;
}
/* Processor specific section indices. These sections do not actually
exist. Symbols with a st_shndx field corresponding to one of these
values have a special meaning. */
/* Defined and allocated common symbol. Value is virtual address. If
relocated, alignment must be preserved. */
#define SHN_RISCV_ACOMMON SHN_LORESERVE
/* Defined and allocated text symbol. Value is virtual address.
Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */
#define SHN_RISCV_TEXT (SHN_LORESERVE + 1)
/* Defined and allocated data symbol. Value is virtual address.
Occur in the dynamic symbol table of Alpha OSF/1 and Irix 5 executables. */
#define SHN_RISCV_DATA (SHN_LORESERVE + 2)
/* Small common symbol. */
#define SHN_RISCV_SCOMMON (SHN_LORESERVE + 3)
/* Small undefined symbol. */
#define SHN_RISCV_SUNDEFINED (SHN_LORESERVE + 4)
/* Number of local global offset table entries. */
#define DT_RISCV_LOCAL_GOTNO 0x70000000
/* Number of entries in the .dynsym section. */
#define DT_RISCV_SYMTABNO 0x70000001
/* Index of first dynamic symbol in global offset table. */
#define DT_RISCV_GOTSYM 0x70000002
/* Address of the base of the PLTGOT. */
#define DT_RISCV_PLTGOT 0x70000003
#endif /* _ELF_RISCV_H */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,317 @@
/* riscv.h. RISC-V opcode list for GDB, the GNU debugger.
Copyright 2011
Free Software Foundation, Inc.
Contributed by Andrew Waterman
This file is part of GDB, GAS, and the GNU binutils.
GDB, GAS, and the GNU binutils are free software; you can redistribute
them and/or modify them under the terms of the GNU General Public
License as published by the Free Software Foundation; either version
1, or (at your option) any later version.
GDB, GAS, and the GNU binutils are distributed in the hope that they
will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _RISCV_H_
#define _RISCV_H_
#include "riscv-opc.h"
#include <stdlib.h>
#include <stdint.h>
/* RVC fields */
#define OP_MASK_COP 0x1f
#define OP_SH_COP 0
#define OP_MASK_CRD 0x1f
#define OP_SH_CRD 5
#define OP_MASK_CRS2 0x1f
#define OP_SH_CRS2 5
#define OP_MASK_CRS1 0x1f
#define OP_SH_CRS1 10
#define OP_MASK_CRDS 0x7
#define OP_SH_CRDS 13
#define OP_MASK_CRS2S 0x7
#define OP_SH_CRS2S 13
#define OP_MASK_CRS2BS 0x7
#define OP_SH_CRS2BS 5
#define OP_MASK_CRS1S 0x7
#define OP_SH_CRS1S 10
#define OP_MASK_CIMM6 0x3f
#define OP_SH_CIMM6 10
#define OP_MASK_CIMM5 0x1f
#define OP_SH_CIMM5 5
#define OP_MASK_CIMM10 0x3ff
#define OP_SH_CIMM10 5
static const char rvc_rs1_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 7 };
#define rvc_rd_regmap rvc_rs1_regmap
#define rvc_rs2b_regmap rvc_rs1_regmap
static const char rvc_rs2_regmap[8] = { 20, 21, 2, 3, 4, 5, 6, 0 };
typedef uint64_t insn_t;
static inline unsigned int riscv_insn_length (insn_t insn)
{
if ((insn & 0x3) != 3) /* RVC */
return 2;
if ((insn & 0x1f) != 0x1f) /* base ISA and extensions in 32-bit space */
return 4;
if ((insn & 0x3f) == 0x1f) /* 48-bit extensions */
return 6;
if ((insn & 0x7f) == 0x3f) /* 64-bit extensions */
return 8;
/* longer instructions not supported at the moment */
return 2;
}
static const char * const riscv_rm[8] = {
"rne", "rtz", "rdn", "rup", "rmm", 0, 0, "dyn"
};
static const char* const riscv_pred_succ[16] = {
0, "w", "r", "rw", "o", "ow", "or", "orw",
"i", "iw", "ir", "irw", "io", "iow", "ior", "iorw",
};
#define RVC_JUMP_BITS 10
#define RVC_JUMP_ALIGN_BITS 1
#define RVC_JUMP_ALIGN (1 << RVC_JUMP_ALIGN_BITS)
#define RVC_JUMP_REACH ((1ULL<<RVC_JUMP_BITS)*RVC_JUMP_ALIGN)
#define RVC_BRANCH_BITS 5
#define RVC_BRANCH_ALIGN_BITS RVC_JUMP_ALIGN_BITS
#define RVC_BRANCH_ALIGN (1 << RVC_BRANCH_ALIGN_BITS)
#define RVC_BRANCH_REACH ((1ULL<<RVC_BRANCH_BITS)*RVC_BRANCH_ALIGN)
#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
#define EXTRACT_ITYPE_IMM(x) \
(RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
#define EXTRACT_STYPE_IMM(x) \
(RV_X(x, 7, 5) | (RV_X(x, 25, 7) << 5) | (RV_IMM_SIGN(x) << 12))
#define EXTRACT_SBTYPE_IMM(x) \
((RV_X(x, 8, 4) << 1) | (RV_X(x, 25, 6) << 5) | (RV_X(x, 7, 1) << 11) | (RV_IMM_SIGN(x) << 12))
#define EXTRACT_UTYPE_IMM(x) \
(RV_X(x, 12, 20) | (RV_IMM_SIGN(x) << 20))
#define EXTRACT_UJTYPE_IMM(x) \
((RV_X(x, 21, 10) << 1) | (RV_X(x, 20, 1) << 11) | (RV_X(x, 12, 8) << 12) | (RV_IMM_SIGN(x) << 20))
#define ENCODE_ITYPE_IMM(x) \
(RV_X(x, 0, 12) << 20)
#define ENCODE_STYPE_IMM(x) \
((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25))
#define ENCODE_SBTYPE_IMM(x) \
((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31))
#define ENCODE_UTYPE_IMM(x) \
(RV_X(x, 0, 20) << 12)
#define ENCODE_UJTYPE_IMM(x) \
((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31))
#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
#define VALID_SBTYPE_IMM(x) (EXTRACT_SBTYPE_IMM(ENCODE_SBTYPE_IMM(x)) == (x))
#define VALID_UTYPE_IMM(x) (EXTRACT_UTYPE_IMM(ENCODE_UTYPE_IMM(x)) == (x))
#define VALID_UJTYPE_IMM(x) (EXTRACT_UJTYPE_IMM(ENCODE_UJTYPE_IMM(x)) == (x))
#define RISCV_RTYPE(insn, rd, rs1, rs2) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
#define RISCV_ITYPE(insn, rd, rs1, imm) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm))
#define RISCV_STYPE(insn, rs1, rs2, imm) \
((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm))
#define RISCV_SBTYPE(insn, rs1, rs2, target) \
((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target))
#define RISCV_UTYPE(insn, rd, bigimm) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm))
#define RISCV_UJTYPE(insn, rd, target) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target))
#define RISCV_NOP RISCV_ITYPE(ADDI, 0, 0, 0)
#define RISCV_CONST_HIGH_PART(VALUE) \
(((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
#define RISCV_CONST_LOW_PART(VALUE) ((VALUE) - RISCV_CONST_HIGH_PART (VALUE))
#define RISCV_LUI_HIGH_PART(VALUE) (RISCV_CONST_HIGH_PART(VALUE) >> RISCV_IMM_BITS)
#define RISCV_PCREL_HIGH_PART(VALUE, PC) RISCV_LUI_HIGH_PART((VALUE) - (PC))
#define RISCV_PCREL_LOW_PART(VALUE, PC) RISCV_CONST_LOW_PART((VALUE) - (PC))
/* RV fields */
#define OP_MASK_OP 0x7f
#define OP_SH_OP 0
#define OP_MASK_RS2 0x1f
#define OP_SH_RS2 20
#define OP_MASK_RS1 0x1f
#define OP_SH_RS1 15
#define OP_MASK_RS3 0x1f
#define OP_SH_RS3 27
#define OP_MASK_RD 0x1f
#define OP_SH_RD 7
#define OP_MASK_SHAMT 0x3f
#define OP_SH_SHAMT 20
#define OP_MASK_SHAMTW 0x1f
#define OP_SH_SHAMTW 20
#define OP_MASK_RM 0x7
#define OP_SH_RM 12
#define OP_MASK_PRED 0xf
#define OP_SH_PRED 24
#define OP_MASK_SUCC 0xf
#define OP_SH_SUCC 20
#define OP_MASK_AQ 0x1
#define OP_SH_AQ 26
#define OP_MASK_RL 0x1
#define OP_SH_RL 25
#define OP_MASK_VRD 0x1f
#define OP_SH_VRD 7
#define OP_MASK_VRS 0x1f
#define OP_SH_VRS 15
#define OP_MASK_VRT 0x1f
#define OP_SH_VRT 20
#define OP_MASK_VRR 0x1f
#define OP_SH_VRR 27
#define OP_MASK_VFD 0x1f
#define OP_SH_VFD 7
#define OP_MASK_VFS 0x1f
#define OP_SH_VFS 15
#define OP_MASK_VFT 0x1f
#define OP_SH_VFT 20
#define OP_MASK_VFR 0x1f
#define OP_SH_VFR 27
#define OP_MASK_IMMNGPR 0x3f
#define OP_SH_IMMNGPR 20
#define OP_MASK_IMMNFPR 0x3f
#define OP_SH_IMMNFPR 26
#define OP_MASK_IMMSEGNELM 0x7
#define OP_SH_IMMSEGNELM 29
#define OP_MASK_CUSTOM_IMM 0x7f
#define OP_SH_CUSTOM_IMM 25
#define OP_MASK_CSR 0xfff
#define OP_SH_CSR 20
#define LINK_REG 1
#define TP_REG 15
#define GP_REG 31
#define RISCV_JUMP_BITS RISCV_BIGIMM_BITS
#define RISCV_JUMP_ALIGN_BITS 1
#define RISCV_JUMP_ALIGN (1 << RISCV_JUMP_ALIGN_BITS)
#define RISCV_JUMP_REACH ((1ULL<<RISCV_JUMP_BITS)*RISCV_JUMP_ALIGN)
#define RISCV_IMM_BITS 12
#define RISCV_BIGIMM_BITS (32-RISCV_IMM_BITS)
#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
#define RISCV_BIGIMM_REACH (1LL<<RISCV_BIGIMM_BITS)
#define RISCV_BRANCH_BITS RISCV_IMM_BITS
#define RISCV_BRANCH_ALIGN_BITS RISCV_JUMP_ALIGN_BITS
#define RISCV_BRANCH_ALIGN (1 << RISCV_BRANCH_ALIGN_BITS)
#define RISCV_BRANCH_REACH (RISCV_IMM_REACH*RISCV_BRANCH_ALIGN)
/* This structure holds information for a particular instruction. */
struct riscv_opcode
{
/* The name of the instruction. */
const char *name;
/* The ISA subset name (I, M, A, F, D, Xextension). */
const char *subset;
/* A string describing the arguments for this instruction. */
const char *args;
/* The basic opcode for the instruction. When assembling, this
opcode is modified by the arguments to produce the actual opcode
that is used. If pinfo is INSN_MACRO, then this is 0. */
insn_t match;
/* If pinfo is not INSN_MACRO, then this is a bit mask for the
relevant portions of the opcode when disassembling. If the
actual opcode anded with the match field equals the opcode field,
then we have found the correct instruction. If pinfo is
INSN_MACRO, then this field is the macro identifier. */
insn_t mask;
/* A function to determine if a word corresponds to this instruction.
Usually, this computes ((word & mask) == match). */
int (*match_func)(const struct riscv_opcode *op, insn_t word);
/* For a macro, this is INSN_MACRO. Otherwise, it is a collection
of bits describing the instruction, notably any relevant hazard
information. */
unsigned long pinfo;
};
#define INSN_WRITE_GPR_D 0x00000001
#define INSN_WRITE_GPR_RA 0x00000004
#define INSN_WRITE_FPR_D 0x00000008
#define INSN_READ_GPR_S 0x00000040
#define INSN_READ_GPR_T 0x00000080
#define INSN_READ_FPR_S 0x00000100
#define INSN_READ_FPR_T 0x00000200
#define INSN_READ_FPR_R 0x00000400
/* Instruction is a simple alias (I.E. "move" for daddu/addu/or) */
#define INSN_ALIAS 0x00001000
/* Instruction is actually a macro. It should be ignored by the
disassembler, and requires special treatment by the assembler. */
#define INSN_MACRO 0xffffffff
/* This is a list of macro expanded instructions.
_I appended means immediate
_A appended means address
_AB appended means address with base register
_D appended means 64 bit floating point constant
_S appended means 32 bit floating point constant. */
enum
{
M_LA,
M_LLA,
M_LA_TLS_GD,
M_LA_TLS_IE,
M_LB,
M_LBU,
M_LH,
M_LHU,
M_LW,
M_LWU,
M_LD,
M_SB,
M_SH,
M_SW,
M_SD,
M_FLW,
M_FLD,
M_FSW,
M_FSD,
M_CALL,
M_JUMP,
M_J,
M_LI,
M_VF,
M_NUM_MACROS
};
/* The order of overloaded instructions matters. Label arguments and
register arguments look the same. Instructions that can have either
for arguments must apear in the correct order in this table for the
assembler to pick the right one. In other words, entries with
immediate operands must apear after the same instruction with
registers.
Many instructions are short hand for other instructions (i.e., The
jal <register> instruction is short for jalr <register>). */
extern const struct riscv_opcode riscv_builtin_opcodes[];
extern const int bfd_riscv_num_builtin_opcodes;
extern struct riscv_opcode *riscv_opcodes;
extern int bfd_riscv_num_opcodes;
#define NUMOPCODES bfd_riscv_num_opcodes
#endif /* _RISCV_H_ */

View File

@ -232,6 +232,7 @@ ALL_EMULATION_SOURCES = \
eelf32lppc.c \
eelf32lppcnto.c \
eelf32lppcsim.c \
eelf32lriscv.c \
eelf32lsmip.c \
eelf32ltsmip.c \
eelf32ltsmip_fbsd.c \
@ -494,6 +495,7 @@ ALL_64_EMULATION_SOURCES = \
eelf64btsmip_fbsd.c \
eelf64hppa.c \
eelf64lppc.c \
eelf64lriscv.c \
eelf64ltsmip.c \
eelf64ltsmip_fbsd.c \
eelf64mmix.c \
@ -1112,6 +1114,10 @@ eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \
ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)"
eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \
$(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
$(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lriscv "$(tdir_elf32lriscv)"
eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
$(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
$(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \
@ -2083,6 +2089,11 @@ eelf64lppc.c: $(srcdir)/emulparams/elf64lppc.sh \
ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf64lppc "$(tdir_elf64lppc)"
eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
$(srcdir)/emulparams/elf64lriscv-defs.sh \
$(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
$(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf64lriscv "$(tdir_elf64lriscv)"
eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \
$(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \
$(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \

View File

@ -539,6 +539,7 @@ ALL_EMULATION_SOURCES = \
eelf32lppc.c \
eelf32lppcnto.c \
eelf32lppcsim.c \
eelf32lriscv.c \
eelf32lsmip.c \
eelf32ltsmip.c \
eelf32ltsmip_fbsd.c \
@ -800,6 +801,7 @@ ALL_64_EMULATION_SOURCES = \
eelf64btsmip_fbsd.c \
eelf64hppa.c \
eelf64lppc.c \
eelf64lriscv.c \
eelf64ltsmip.c \
eelf64ltsmip_fbsd.c \
eelf64mmix.c \
@ -1169,6 +1171,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcnto.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lppcsim.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lriscv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32lsmip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf32ltsmip_fbsd.Po@am__quote@
@ -1220,6 +1223,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64btsmip_fbsd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64hppa.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lppc.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64lriscv.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64ltsmip_fbsd.Po@am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/eelf64mmix.Po@am__quote@
@ -2592,6 +2596,10 @@ eelf32lppcsim.c: $(srcdir)/emulparams/elf32lppcsim.sh \
ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lppcsim "$(tdir_elf32lppcsim)"
eelf32lriscv.c: $(srcdir)/emulparams/elf32lriscv.sh \
$(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
$(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf32lriscv "$(tdir_elf32lriscv)"
eelf32lsmip.c: $(srcdir)/emulparams/elf32lsmip.sh \
$(srcdir)/emulparams/elf32lmip.sh $(srcdir)/emulparams/elf32bmip.sh \
$(ELF_DEPS) $(srcdir)/emultempl/mipself.em $(srcdir)/scripttempl/elf.sc \
@ -3557,6 +3565,11 @@ eelf64lppc.c: $(srcdir)/emulparams/elf64lppc.sh \
ldemul-list.h \
$(ELF_DEPS) $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf64lppc "$(tdir_elf64lppc)"
eelf64lriscv.c: $(srcdir)/emulparams/elf64lriscv.sh \
$(srcdir)/emulparams/elf64lriscv-defs.sh \
$(srcdir)/emulparams/elf32lriscv-defs.sh $(ELF_DEPS) \
$(srcdir)/emultempl/riscvelf.em $(srcdir)/scripttempl/elf.sc ${GEN_DEPENDS}
${GENSCRIPTS} elf64lriscv "$(tdir_elf64lriscv)"
eelf64ltsmip.c: $(srcdir)/emulparams/elf64ltsmip.sh \
$(srcdir)/emulparams/elf64btsmip.sh $(srcdir)/emulparams/elf64bmip-defs.sh \
$(srcdir)/emulparams/elf32bmipn32-defs.sh $(ELF_DEPS) \

View File

@ -590,6 +590,12 @@ powerpc-*-aix*) targ_emul=aixppc ;;
powerpc-*-beos*) targ_emul=aixppc ;;
powerpc-*-windiss*) targ_emul=elf32ppcwindiss ;;
powerpc-*-lynxos*) targ_emul=ppclynx ;;
riscv32-*-*) targ_emul=elf32lriscv
targ_extra_emuls="elf64lriscv"
targ_extra_libpath=$targ_extra_emuls ;;
riscv*-*-*) targ_emul=elf64lriscv
targ_extra_emuls="elf32lriscv"
targ_extra_libpath=$targ_extra_emuls ;;
rs6000-*-aix[5-9]*) targ_emul=aix5rs6 ;;
rs6000-*-aix*) targ_emul=aixrs6
;;

View File

@ -0,0 +1,59 @@
# This is an ELF platform.
SCRIPT_NAME=elf
# Handle both little-ended 32-bit RISC-V objects.
ARCH=riscv
OUTPUT_FORMAT="elf32-littleriscv"
TEMPLATE_NAME=elf32
EXTRA_EM_FILE=riscvelf
case "$EMULATION_NAME" in
elf32*) ELFSIZE=32; LIBPATH_SUFFIX=32 ;;
elf64*) ELFSIZE=64; LIBPATH_SUFFIX= ;;
*) echo $0: unhandled emulation $EMULATION_NAME >&2; exit 1 ;;
esac
if test `echo "$host" | sed -e s/64//` = `echo "$target" | sed -e s/64//`; then
case " $EMULATION_LIBPATH " in
*" ${EMULATION_NAME} "*)
NATIVE=yes
;;
esac
fi
GENERATE_SHLIB_SCRIPT=yes
GENERATE_PIE_SCRIPT=yes
TEXT_START_ADDR=0x10000000
SHLIB_TEXT_START_ADDR=0x1000000
MAXPAGESIZE="CONSTANT (MAXPAGESIZE)"
ENTRY=_start
# Unlike most targets, the RISC-V backend puts all dynamic relocations
# in a single dynobj section, which it also calls ".rel.dyn". It does
# this so that it can easily sort all dynamic relocations before the
# output section has been populated.
OTHER_GOT_RELOC_SECTIONS="
.rel.dyn ${RELOCATING-0} : { *(.rel.dyn) }
"
GOT=".got ${RELOCATING-0} : { *(.got) }"
unset OTHER_READWRITE_SECTIONS
unset OTHER_RELRO_SECTIONS
# Magic symbols.
TEXT_START_SYMBOLS='_ftext = . ;'
DATA_START_SYMBOLS='_fdata = . ;'
OTHER_BSS_SYMBOLS='_fbss = .;'
INITIAL_READONLY_SECTIONS=".interp ${RELOCATING-0} : { *(.interp) }"
SDATA_START_SYMBOLS="_gp = . + 0x800;
*(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*)"
if test -n "${CREATE_SHLIB}"; then
INITIAL_READONLY_SECTIONS=
SDATA_START_SYMBOLS=
OTHER_READONLY_SECTIONS=".srodata ${RELOCATING-0} : { *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) }"
unset GOT
fi
TEXT_DYNAMIC=

View File

@ -0,0 +1,9 @@
. ${srcdir}/emulparams/elf32lriscv-defs.sh
OUTPUT_FORMAT="elf32-littleriscv"
COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"
# Magic sections.
OTHER_SECTIONS='
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
'

View File

@ -0,0 +1,2 @@
. ${srcdir}/emulparams/elf32lriscv-defs.sh
COMMONPAGESIZE="CONSTANT (COMMONPAGESIZE)"

View File

@ -0,0 +1,8 @@
. ${srcdir}/emulparams/elf64lriscv-defs.sh
OUTPUT_FORMAT="elf64-littleriscv"
# Magic sections.
OTHER_SECTIONS='
.gptab.sdata : { *(.gptab.data) *(.gptab.sdata) }
.gptab.sbss : { *(.gptab.bss) *(.gptab.sbss) }
'

View File

@ -0,0 +1,63 @@
# This shell script emits a C file. -*- C -*-
# Copyright 2004, 2006, 2007, 2008 Free Software Foundation, Inc.
#
# This file is part of the GNU Binutils.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
# MA 02110-1301, USA.
fragment <<EOF
#include "ldmain.h"
#include "ldctor.h"
#include "elf/riscv.h"
#include "elfxx-riscv.h"
#define is_riscv_elf(bfd) \
(bfd_get_flavour (bfd) == bfd_target_elf_flavour \
&& elf_tdata (bfd) != NULL \
&& elf_object_id (bfd) == RISCV_ELF_DATA)
static void
riscv_after_parse (void)
{
/* .gnu.hash and the RISC-V ABI require .dynsym to be sorted in different
ways. .gnu.hash needs symbols to be grouped by hash code whereas the
RISC-V ABI requires a mapping between the GOT and the symbol table. */
if (link_info.emit_gnu_hash)
{
einfo ("%X%P: .gnu.hash is incompatible with the RISC-V ABI\n");
link_info.emit_hash = TRUE;
link_info.emit_gnu_hash = FALSE;
}
after_parse_default ();
}
static void
riscv_before_allocation (void)
{
gld${EMULATION_NAME}_before_allocation ();
if (link_info.discard == discard_sec_merge)
link_info.discard = discard_l;
if (RELAXATION_DISABLED_BY_DEFAULT)
ENABLE_RELAXATION;
}
EOF
LDEMUL_AFTER_PARSE=riscv_after_parse
LDEMUL_BEFORE_ALLOCATION=riscv_before_allocation

File diff suppressed because it is too large Load Diff

View File

@ -1,307 +1,136 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* Skeleton interface for Bison's Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
under terms of your choice, so long as that work isn't itself a
parser generator using the skeleton or a modified version thereof
as a parser skeleton. Alternatively, if you modify or redistribute
the parser skeleton itself, you may (at your option) remove this
special exception, which will cause the skeleton and the resulting
Bison output files to be licensed under the GNU General Public
License without this special exception.
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
INT = 258,
NAME = 259,
LNAME = 260,
OREQ = 261,
ANDEQ = 262,
RSHIFTEQ = 263,
LSHIFTEQ = 264,
DIVEQ = 265,
MULTEQ = 266,
MINUSEQ = 267,
PLUSEQ = 268,
OROR = 269,
ANDAND = 270,
NE = 271,
EQ = 272,
GE = 273,
LE = 274,
RSHIFT = 275,
LSHIFT = 276,
UNARY = 277,
END = 278,
ALIGN_K = 279,
BLOCK = 280,
BIND = 281,
QUAD = 282,
SQUAD = 283,
LONG = 284,
SHORT = 285,
BYTE = 286,
SECTIONS = 287,
PHDRS = 288,
INSERT_K = 289,
AFTER = 290,
BEFORE = 291,
DATA_SEGMENT_ALIGN = 292,
DATA_SEGMENT_RELRO_END = 293,
DATA_SEGMENT_END = 294,
SORT_BY_NAME = 295,
SORT_BY_ALIGNMENT = 296,
SORT_NONE = 297,
SORT_BY_INIT_PRIORITY = 298,
SIZEOF_HEADERS = 299,
OUTPUT_FORMAT = 300,
FORCE_COMMON_ALLOCATION = 301,
OUTPUT_ARCH = 302,
INHIBIT_COMMON_ALLOCATION = 303,
SEGMENT_START = 304,
INCLUDE = 305,
MEMORY = 306,
REGION_ALIAS = 307,
LD_FEATURE = 308,
NOLOAD = 309,
DSECT = 310,
COPY = 311,
INFO = 312,
OVERLAY = 313,
DEFINED = 314,
TARGET_K = 315,
SEARCH_DIR = 316,
MAP = 317,
ENTRY = 318,
NEXT = 319,
SIZEOF = 320,
ALIGNOF = 321,
ADDR = 322,
LOADADDR = 323,
MAX_K = 324,
MIN_K = 325,
STARTUP = 326,
HLL = 327,
SYSLIB = 328,
FLOAT = 329,
NOFLOAT = 330,
NOCROSSREFS = 331,
ORIGIN = 332,
FILL = 333,
LENGTH = 334,
CREATE_OBJECT_SYMBOLS = 335,
INPUT = 336,
GROUP = 337,
OUTPUT = 338,
CONSTRUCTORS = 339,
ALIGNMOD = 340,
AT = 341,
SUBALIGN = 342,
HIDDEN = 343,
PROVIDE = 344,
PROVIDE_HIDDEN = 345,
AS_NEEDED = 346,
CHIP = 347,
LIST = 348,
SECT = 349,
ABSOLUTE = 350,
LOAD = 351,
NEWLINE = 352,
ENDWORD = 353,
ORDER = 354,
NAMEWORD = 355,
ASSERT_K = 356,
FORMAT = 357,
PUBLIC = 358,
DEFSYMEND = 359,
BASE = 360,
ALIAS = 361,
TRUNCATE = 362,
REL = 363,
INPUT_SCRIPT = 364,
INPUT_MRI_SCRIPT = 365,
INPUT_DEFSYM = 366,
CASE = 367,
EXTERN = 368,
START = 369,
VERS_TAG = 370,
VERS_IDENTIFIER = 371,
GLOBAL = 372,
LOCAL = 373,
VERSIONK = 374,
INPUT_VERSION_SCRIPT = 375,
KEEP = 376,
ONLY_IF_RO = 377,
ONLY_IF_RW = 378,
SPECIAL = 379,
INPUT_SECTION_FLAGS = 380,
EXCLUDE_FILE = 381,
CONSTANT = 382,
INPUT_DYNAMIC_LIST = 383
};
#endif
/* Tokens. */
#define INT 258
#define NAME 259
#define LNAME 260
#define OREQ 261
#define ANDEQ 262
#define RSHIFTEQ 263
#define INT 257
#define NAME 258
#define LNAME 259
#define PLUSEQ 260
#define MINUSEQ 261
#define MULTEQ 262
#define DIVEQ 263
#define LSHIFTEQ 264
#define DIVEQ 265
#define MULTEQ 266
#define MINUSEQ 267
#define PLUSEQ 268
#define OROR 269
#define ANDAND 270
#define RSHIFTEQ 265
#define ANDEQ 266
#define OREQ 267
#define OROR 268
#define ANDAND 269
#define EQ 270
#define NE 271
#define EQ 272
#define LE 272
#define GE 273
#define LE 274
#define LSHIFT 274
#define RSHIFT 275
#define LSHIFT 276
#define UNARY 277
#define END 278
#define ALIGN_K 279
#define BLOCK 280
#define BIND 281
#define QUAD 282
#define SQUAD 283
#define LONG 284
#define SHORT 285
#define BYTE 286
#define SECTIONS 287
#define PHDRS 288
#define INSERT_K 289
#define AFTER 290
#define BEFORE 291
#define DATA_SEGMENT_ALIGN 292
#define DATA_SEGMENT_RELRO_END 293
#define DATA_SEGMENT_END 294
#define SORT_BY_NAME 295
#define SORT_BY_ALIGNMENT 296
#define SORT_NONE 297
#define SORT_BY_INIT_PRIORITY 298
#define SIZEOF_HEADERS 299
#define OUTPUT_FORMAT 300
#define FORCE_COMMON_ALLOCATION 301
#define OUTPUT_ARCH 302
#define INHIBIT_COMMON_ALLOCATION 303
#define SEGMENT_START 304
#define INCLUDE 305
#define MEMORY 306
#define REGION_ALIAS 307
#define LD_FEATURE 308
#define NOLOAD 309
#define DSECT 310
#define COPY 311
#define INFO 312
#define OVERLAY 313
#define DEFINED 314
#define TARGET_K 315
#define SEARCH_DIR 316
#define MAP 317
#define ENTRY 318
#define NEXT 319
#define SIZEOF 320
#define ALIGNOF 321
#define ADDR 322
#define LOADADDR 323
#define MAX_K 324
#define MIN_K 325
#define STARTUP 326
#define HLL 327
#define SYSLIB 328
#define FLOAT 329
#define NOFLOAT 330
#define NOCROSSREFS 331
#define ORIGIN 332
#define FILL 333
#define LENGTH 334
#define CREATE_OBJECT_SYMBOLS 335
#define INPUT 336
#define GROUP 337
#define OUTPUT 338
#define CONSTRUCTORS 339
#define ALIGNMOD 340
#define AT 341
#define SUBALIGN 342
#define HIDDEN 343
#define PROVIDE 344
#define PROVIDE_HIDDEN 345
#define AS_NEEDED 346
#define CHIP 347
#define LIST 348
#define SECT 349
#define ABSOLUTE 350
#define LOAD 351
#define NEWLINE 352
#define ENDWORD 353
#define ORDER 354
#define NAMEWORD 355
#define ASSERT_K 356
#define FORMAT 357
#define PUBLIC 358
#define DEFSYMEND 359
#define BASE 360
#define ALIAS 361
#define TRUNCATE 362
#define REL 363
#define INPUT_SCRIPT 364
#define INPUT_MRI_SCRIPT 365
#define INPUT_DEFSYM 366
#define CASE 367
#define EXTERN 368
#define START 369
#define VERS_TAG 370
#define VERS_IDENTIFIER 371
#define GLOBAL 372
#define LOCAL 373
#define VERSIONK 374
#define INPUT_VERSION_SCRIPT 375
#define KEEP 376
#define ONLY_IF_RO 377
#define ONLY_IF_RW 378
#define SPECIAL 379
#define INPUT_SECTION_FLAGS 380
#define EXCLUDE_FILE 381
#define CONSTANT 382
#define INPUT_DYNAMIC_LIST 383
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 62 "ldgram.y"
{
#define UNARY 276
#define END 277
#define ALIGN_K 278
#define BLOCK 279
#define BIND 280
#define QUAD 281
#define SQUAD 282
#define LONG 283
#define SHORT 284
#define BYTE 285
#define SECTIONS 286
#define PHDRS 287
#define INSERT_K 288
#define AFTER 289
#define BEFORE 290
#define DATA_SEGMENT_ALIGN 291
#define DATA_SEGMENT_RELRO_END 292
#define DATA_SEGMENT_END 293
#define SORT_BY_NAME 294
#define SORT_BY_ALIGNMENT 295
#define SORT_NONE 296
#define SORT_BY_INIT_PRIORITY 297
#define SIZEOF_HEADERS 298
#define OUTPUT_FORMAT 299
#define FORCE_COMMON_ALLOCATION 300
#define OUTPUT_ARCH 301
#define INHIBIT_COMMON_ALLOCATION 302
#define SEGMENT_START 303
#define INCLUDE 304
#define MEMORY 305
#define REGION_ALIAS 306
#define LD_FEATURE 307
#define NOLOAD 308
#define DSECT 309
#define COPY 310
#define INFO 311
#define OVERLAY 312
#define DEFINED 313
#define TARGET_K 314
#define SEARCH_DIR 315
#define MAP 316
#define ENTRY 317
#define NEXT 318
#define SIZEOF 319
#define ALIGNOF 320
#define ADDR 321
#define LOADADDR 322
#define MAX_K 323
#define MIN_K 324
#define STARTUP 325
#define HLL 326
#define SYSLIB 327
#define FLOAT 328
#define NOFLOAT 329
#define NOCROSSREFS 330
#define ORIGIN 331
#define FILL 332
#define LENGTH 333
#define CREATE_OBJECT_SYMBOLS 334
#define INPUT 335
#define GROUP 336
#define OUTPUT 337
#define CONSTRUCTORS 338
#define ALIGNMOD 339
#define AT 340
#define SUBALIGN 341
#define HIDDEN 342
#define PROVIDE 343
#define PROVIDE_HIDDEN 344
#define AS_NEEDED 345
#define CHIP 346
#define LIST 347
#define SECT 348
#define ABSOLUTE 349
#define LOAD 350
#define NEWLINE 351
#define ENDWORD 352
#define ORDER 353
#define NAMEWORD 354
#define ASSERT_K 355
#define FORMAT 356
#define PUBLIC 357
#define DEFSYMEND 358
#define BASE 359
#define ALIAS 360
#define TRUNCATE 361
#define REL 362
#define INPUT_SCRIPT 363
#define INPUT_MRI_SCRIPT 364
#define INPUT_DEFSYM 365
#define CASE 366
#define EXTERN 367
#define START 368
#define VERS_TAG 369
#define VERS_IDENTIFIER 370
#define GLOBAL 371
#define LOCAL 372
#define VERSIONK 373
#define INPUT_VERSION_SCRIPT 374
#define KEEP 375
#define ONLY_IF_RO 376
#define ONLY_IF_RW 377
#define SPECIAL 378
#define INPUT_SECTION_FLAGS 379
#define EXCLUDE_FILE 380
#define CONSTANT 381
#define INPUT_DYNAMIC_LIST 382
#ifdef YYSTYPE
#undef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
#endif
#ifndef YYSTYPE_IS_DECLARED
#define YYSTYPE_IS_DECLARED 1
typedef union {
bfd_vma integer;
struct big_int
{
@ -330,14 +159,6 @@ typedef union YYSTYPE
struct bfd_elf_version_deps *deflist;
struct bfd_elf_version_expr *versyms;
struct bfd_elf_version_tree *versnode;
}
/* Line 1529 of yacc.c. */
#line 336 "ldgram.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
# define YYSTYPE_IS_TRIVIAL 1
#endif
} YYSTYPE;
#endif /* !YYSTYPE_IS_DECLARED */
extern YYSTYPE yylval;

View File

@ -12538,6 +12538,7 @@ if test x${all_targets} = xfalse ; then
bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
bfd_powerpc_64_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
bfd_pyramid_arch) ;;
bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;;
bfd_romp_arch) ;;
bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";;

View File

@ -283,6 +283,7 @@ if test x${all_targets} = xfalse ; then
bfd_powerpc_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
bfd_powerpc_64_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
bfd_pyramid_arch) ;;
bfd_riscv_arch) ta="$ta riscv-dis.lo riscv-opc.lo" ;;
bfd_romp_arch) ;;
bfd_rs6000_arch) ta="$ta ppc-dis.lo ppc-opc.lo" ;;
bfd_rl78_arch) ta="$ta rl78-dis.lo rl78-decode.lo";;

View File

@ -71,6 +71,7 @@
#define ARCH_pdp11
#define ARCH_pj
#define ARCH_powerpc
#define ARCH_riscv
#define ARCH_rs6000
#define ARCH_rl78
#define ARCH_rx
@ -354,6 +355,11 @@ disassembler (abfd)
disassemble = print_insn_little_powerpc;
break;
#endif
#ifdef ARCH_riscv
case bfd_arch_riscv:
disassemble = print_insn_riscv;
break;
#endif
#ifdef ARCH_rs6000
case bfd_arch_rs6000:
if (bfd_get_mach (abfd) == bfd_mach_ppc_620)

View File

@ -0,0 +1,761 @@
/* RISC-V disassembler
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of the GNU opcodes library.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#include "sysdep.h"
#include "dis-asm.h"
#include "libiberty.h"
#include "opcode/riscv.h"
#include "opintl.h"
#include "elf-bfd.h"
#include "elf/riscv.h"
#include <stdint.h>
#include <assert.h>
/* FIXME: These should be shared with gdb somehow. */
static const char * const riscv_gpr_names_numeric[32] =
{
"x0", "x1", "x2", "x3", "x4", "x5", "x6", "x7",
"x8", "x9", "x10", "x11", "x12", "x13", "x14", "x15",
"x16", "x17", "x18", "x19", "x20", "x21", "x22", "x23",
"x24", "x25", "x26", "x27", "x28", "x29", "x30", "x31"
};
static const char * const riscv_gpr_names_abi[32] = {
"zero", "ra", "s0", "s1", "s2", "s3", "s4", "s5",
"s6", "s7", "s8", "s9", "s10", "s11", "sp", "tp",
"v0", "v1", "a0", "a1", "a2", "a3", "a4", "a5",
"a6", "a7", "t0", "t1", "t2", "t3", "t4", "gp"
};
static const char * const riscv_fpr_names_numeric[32] =
{
"f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
"f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15",
"f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23",
"f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31"
};
static const char * const riscv_fpr_names_abi[32] = {
"fs0", "fs1", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7",
"fs8", "fs9", "fs10", "fs11", "fs12", "fs13", "fs14", "fs15",
"fv0", "fv1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5",
"fa6", "fa7", "ft0", "ft1", "ft2", "ft3", "ft4", "ft5"
};
static const char * const riscv_vgr_reg_names_riscv[32] =
{
"vx0", "vx1", "vx2", "vx3", "vx4", "vx5", "vx6", "vx7",
"vx8", "vx9", "vx10", "vx11", "vx12", "vx13", "vx14", "vx15",
"vx16", "vx17", "vx18", "vx19", "vx20", "vx21", "vx22", "vx23",
"vx24", "vx25", "vx26", "vx27", "vx28", "vx29", "vx30", "vx31"
};
static const char * const riscv_vfp_reg_names_riscv[32] =
{
"vf0", "vf1", "vf2", "vf3", "vf4", "vf5", "vf6", "vf7",
"vf8", "vf9", "vf10", "vf11", "vf12", "vf13", "vf14", "vf15",
"vf16", "vf17", "vf18", "vf19", "vf20", "vf21", "vf22", "vf23",
"vf24", "vf25", "vf26", "vf27", "vf28", "vf29", "vf30", "vf31"
};
struct riscv_abi_choice
{
const char * name;
const char * const *gpr_names;
const char * const *fpr_names;
};
struct riscv_abi_choice riscv_abi_choices[] =
{
{ "numeric", riscv_gpr_names_numeric, riscv_fpr_names_numeric },
{ "32", riscv_gpr_names_abi, riscv_fpr_names_abi },
{ "64", riscv_gpr_names_abi, riscv_fpr_names_abi },
};
struct riscv_arch_choice
{
const char *name;
int bfd_mach_valid;
unsigned long bfd_mach;
};
const struct riscv_arch_choice riscv_arch_choices[] =
{
{ "numeric", 0, 0 },
{ "rv32", 1, bfd_mach_riscv32 },
{ "rv64", 1, bfd_mach_riscv64 },
};
struct riscv_private_data
{
bfd_vma gp;
bfd_vma print_addr;
bfd_vma hi_addr[OP_MASK_RD + 1];
};
/* ISA and processor type to disassemble for, and register names to use.
set_default_riscv_dis_options and parse_riscv_dis_options fill in these
values. */
static const char * const *riscv_gpr_names;
static const char * const *riscv_fpr_names;
/* Other options */
static int no_aliases; /* If set disassemble as most general inst. */
static const struct riscv_abi_choice *
choose_abi_by_name (const char *name, unsigned int namelen)
{
const struct riscv_abi_choice *c;
unsigned int i;
for (i = 0, c = NULL; i < ARRAY_SIZE (riscv_abi_choices) && c == NULL; i++)
if (strncmp (riscv_abi_choices[i].name, name, namelen) == 0
&& strlen (riscv_abi_choices[i].name) == namelen)
c = &riscv_abi_choices[i];
return c;
}
static void
set_default_riscv_dis_options (struct disassemble_info *info ATTRIBUTE_UNUSED)
{
riscv_gpr_names = riscv_gpr_names_abi;
riscv_fpr_names = riscv_fpr_names_abi;
no_aliases = 0;
}
static void
parse_riscv_dis_option (const char *option, unsigned int len)
{
unsigned int i, optionlen, vallen;
const char *val;
const struct riscv_abi_choice *chosen_abi;
/* Try to match options that are simple flags */
if (CONST_STRNEQ (option, "no-aliases"))
{
no_aliases = 1;
return;
}
/* Look for the = that delimits the end of the option name. */
for (i = 0; i < len; i++)
if (option[i] == '=')
break;
if (i == 0) /* Invalid option: no name before '='. */
return;
if (i == len) /* Invalid option: no '='. */
return;
if (i == (len - 1)) /* Invalid option: no value after '='. */
return;
optionlen = i;
val = option + (optionlen + 1);
vallen = len - (optionlen + 1);
if (strncmp ("gpr-names", option, optionlen) == 0
&& strlen ("gpr-names") == optionlen)
{
chosen_abi = choose_abi_by_name (val, vallen);
if (chosen_abi != NULL)
riscv_gpr_names = chosen_abi->gpr_names;
return;
}
if (strncmp ("fpr-names", option, optionlen) == 0
&& strlen ("fpr-names") == optionlen)
{
chosen_abi = choose_abi_by_name (val, vallen);
if (chosen_abi != NULL)
riscv_fpr_names = chosen_abi->fpr_names;
return;
}
/* Invalid option. */
}
static void
parse_riscv_dis_options (const char *options)
{
const char *option_end;
if (options == NULL)
return;
while (*options != '\0')
{
/* Skip empty options. */
if (*options == ',')
{
options++;
continue;
}
/* We know that *options is neither NUL or a comma. */
option_end = options + 1;
while (*option_end != ',' && *option_end != '\0')
option_end++;
parse_riscv_dis_option (options, option_end - options);
/* Go on to the next one. If option_end points to a comma, it
will be skipped above. */
options = option_end;
}
}
/* Print one argument from an array. */
static void
arg_print (struct disassemble_info *info, unsigned long val,
const char* const* array, size_t size)
{
const char *s = val >= size || array[val] == NULL ? "unknown" : array[val];
(*info->fprintf_func) (info->stream, "%s", s);
}
static void
maybe_print_address (struct riscv_private_data *pd, int base_reg, int offset)
{
if (pd->hi_addr[base_reg] != (bfd_vma)-1)
{
pd->print_addr = pd->hi_addr[base_reg] + offset;
pd->hi_addr[base_reg] = -1;
}
else if (base_reg == GP_REG && pd->gp != (bfd_vma)-1)
pd->print_addr = pd->gp + offset;
else if (base_reg == TP_REG)
pd->print_addr = offset;
}
/* Print insn arguments for 32/64-bit code. */
static void
print_insn_args (const char *d, insn_t l, bfd_vma pc, disassemble_info *info)
{
struct riscv_private_data *pd = info->private_data;
int rs1 = (l >> OP_SH_RS1) & OP_MASK_RS1;
int rd = (l >> OP_SH_RD) & OP_MASK_RD;
if (*d != '\0')
(*info->fprintf_func) (info->stream, "\t");
for (; *d != '\0'; d++)
{
switch (*d)
{
/* Xcustom */
case '^':
switch (*++d)
{
case 'd':
(*info->fprintf_func) (info->stream, "%d", rd);
break;
case 's':
(*info->fprintf_func) (info->stream, "%d", rs1);
break;
case 't':
(*info->fprintf_func)
( info->stream, "%d", (int)((l >> OP_SH_RS2) & OP_MASK_RS2));
break;
case 'j':
(*info->fprintf_func)
( info->stream, "%d", (int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM));
break;
}
break;
/* Xhwacha */
case '#':
switch ( *++d ) {
case 'g':
(*info->fprintf_func)
( info->stream, "%d",
(int)((l >> OP_SH_IMMNGPR) & OP_MASK_IMMNGPR));
break;
case 'f':
(*info->fprintf_func)
( info->stream, "%d",
(int)((l >> OP_SH_IMMNFPR) & OP_MASK_IMMNFPR));
break;
case 'p':
(*info->fprintf_func)
( info->stream, "%d",
(int)((l >> OP_SH_CUSTOM_IMM) & OP_MASK_CUSTOM_IMM));
break;
case 'n':
(*info->fprintf_func)
( info->stream, "%d",
(int)(((l >> OP_SH_IMMSEGNELM) & OP_MASK_IMMSEGNELM) + 1));
break;
case 'd':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vgr_reg_names_riscv[(l >> OP_SH_VRD) & OP_MASK_VRD]);
break;
case 's':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vgr_reg_names_riscv[(l >> OP_SH_VRS) & OP_MASK_VRS]);
break;
case 't':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vgr_reg_names_riscv[(l >> OP_SH_VRT) & OP_MASK_VRT]);
break;
case 'r':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vgr_reg_names_riscv[(l >> OP_SH_VRR) & OP_MASK_VRR]);
break;
case 'D':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vfp_reg_names_riscv[(l >> OP_SH_VFD) & OP_MASK_VFD]);
break;
case 'S':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vfp_reg_names_riscv[(l >> OP_SH_VFS) & OP_MASK_VFS]);
break;
case 'T':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vfp_reg_names_riscv[(l >> OP_SH_VFT) & OP_MASK_VFT]);
break;
case 'R':
(*info->fprintf_func)
( info->stream, "%s",
riscv_vfp_reg_names_riscv[(l >> OP_SH_VFR) & OP_MASK_VFR]);
break;
}
break;
case ',':
case '(':
case ')':
case '[':
case ']':
(*info->fprintf_func) (info->stream, "%c", *d);
break;
case '0':
break;
case 'b':
case 's':
(*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rs1]);
break;
case 't':
(*info->fprintf_func) (info->stream, "%s",
riscv_gpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]);
break;
case 'u':
(*info->fprintf_func) (info->stream, "0x%x", (unsigned)EXTRACT_UTYPE_IMM (l) << RISCV_IMM_BITS >> RISCV_IMM_BITS);
break;
case 'm':
arg_print(info, (l >> OP_SH_RM) & OP_MASK_RM,
riscv_rm, ARRAY_SIZE(riscv_rm));
break;
case 'P':
arg_print(info, (l >> OP_SH_PRED) & OP_MASK_PRED,
riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ));
break;
case 'Q':
arg_print(info, (l >> OP_SH_SUCC) & OP_MASK_SUCC,
riscv_pred_succ, ARRAY_SIZE(riscv_pred_succ));
break;
case 'o':
maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l));
case 'j':
if ((l & MASK_ADDI) == MATCH_ADDI)
maybe_print_address (pd, rs1, EXTRACT_ITYPE_IMM (l));
(*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_ITYPE_IMM (l));
break;
case 'q':
maybe_print_address (pd, rs1, EXTRACT_STYPE_IMM (l));
(*info->fprintf_func) (info->stream, "%d", (int)EXTRACT_STYPE_IMM (l));
break;
case 'a':
info->target = EXTRACT_UJTYPE_IMM (l) + pc;
(*info->print_address_func) (info->target, info);
break;
case 'p':
info->target = EXTRACT_SBTYPE_IMM (l) + pc;
(*info->print_address_func) (info->target, info);
break;
case 'd':
if ((l & MASK_AUIPC) == MATCH_AUIPC)
pd->hi_addr[rd] = pc + (EXTRACT_UTYPE_IMM (l) << RISCV_IMM_BITS);
else if ((l & MASK_LUI) == MATCH_LUI)
pd->hi_addr[rd] = EXTRACT_UTYPE_IMM (l) << RISCV_IMM_BITS;
(*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[rd]);
break;
case 'z':
(*info->fprintf_func) (info->stream, "%s", riscv_gpr_names[0]);
break;
case '>':
(*info->fprintf_func) (info->stream, "0x%x",
(unsigned)((l >> OP_SH_SHAMT) & OP_MASK_SHAMT));
break;
case '<':
(*info->fprintf_func) (info->stream, "0x%x",
(unsigned)((l >> OP_SH_SHAMTW) & OP_MASK_SHAMTW));
break;
case 'S':
case 'U':
(*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rs1]);
break;
case 'T':
(*info->fprintf_func) (info->stream, "%s",
riscv_fpr_names[(l >> OP_SH_RS2) & OP_MASK_RS2]);
break;
case 'D':
(*info->fprintf_func) (info->stream, "%s", riscv_fpr_names[rd]);
break;
case 'R':
(*info->fprintf_func) (info->stream, "%s",
riscv_fpr_names[(l >> OP_SH_RS3) & OP_MASK_RS3]);
break;
case 'E':
{
const char* csr_name = "unknown";
switch ((l >> OP_SH_CSR) & OP_MASK_CSR)
{
#define DECLARE_CSR(name, num) case num: csr_name = #name; break;
#include "opcode/riscv-opc.h"
#undef DECLARE_CSR
}
(*info->fprintf_func) (info->stream, "%s", csr_name);
break;
}
case 'Z':
(*info->fprintf_func) (info->stream, "%d", rs1);
break;
default:
/* xgettext:c-format */
(*info->fprintf_func) (info->stream,
_("# internal error, undefined modifier (%c)"),
*d);
return;
}
}
}
#if 0
static unsigned long
riscv_rvc_uncompress(unsigned long rvc_insn)
{
#define IS_INSN(x, op) (((x) & MASK_##op) == MATCH_##op)
#define EXTRACT_OPERAND(x, op) (((x) >> OP_SH_##op) & OP_MASK_##op)
int crd = EXTRACT_OPERAND(rvc_insn, CRD);
int crs1 = EXTRACT_OPERAND(rvc_insn, CRS1);
int crs2 = EXTRACT_OPERAND(rvc_insn, CRS2);
int crds = EXTRACT_OPERAND(rvc_insn, CRDS);
int crs1s = EXTRACT_OPERAND(rvc_insn, CRS1S);
int crs2s = EXTRACT_OPERAND(rvc_insn, CRS2S);
int crs2bs = EXTRACT_OPERAND(rvc_insn, CRS2BS);
int cimm6 = EXTRACT_OPERAND(rvc_insn, CIMM6);
int imm6 = ((int32_t)cimm6 << 26 >> 26) & (RISCV_IMM_REACH-1);
int imm6x4 = (((int32_t)cimm6 << 26 >> 26)*4) & (RISCV_IMM_REACH-1);
int imm6x4lo = imm6x4 & ((1<<RISCV_IMMLO_BITS)-1);
int imm6x4hi = (imm6x4 >> RISCV_IMMLO_BITS) & ((1<<RISCV_IMMHI_BITS)-1);
int imm6x8 = (((int32_t)cimm6 << 26 >> 26)*8) & (RISCV_IMM_REACH-1);
int imm6x8lo = imm6x8 & ((1<<RISCV_IMMLO_BITS)-1);
int imm6x8hi = (imm6x8 >> RISCV_IMMLO_BITS) & ((1<<RISCV_IMMHI_BITS)-1);
int cimm5 = EXTRACT_OPERAND(rvc_insn, CIMM5);
int imm5 = ((int32_t)cimm5 << 27 >> 27) & (RISCV_IMM_REACH-1);
int imm5lo = imm5 & ((1<<RISCV_IMMLO_BITS)-1);
int imm5hi = (imm5 >> RISCV_IMMLO_BITS) & ((1<<RISCV_IMMHI_BITS)-1);
int imm5x4 = (((int32_t)cimm5 << 27 >> 27)*4) & (RISCV_IMM_REACH-1);
int imm5x4lo = imm5x4 & ((1<<RISCV_IMMLO_BITS)-1);
int imm5x4hi = (imm5x4 >> RISCV_IMMLO_BITS) & ((1<<RISCV_IMMHI_BITS)-1);
int imm5x8 = (((int32_t)cimm5 << 27 >> 27)*8) & (RISCV_IMM_REACH-1);
int imm5x8lo = imm5x8 & ((1<<RISCV_IMMLO_BITS)-1);
int imm5x8hi = (imm5x8 >> RISCV_IMMLO_BITS) & ((1<<RISCV_IMMHI_BITS)-1);
int cimm10 = EXTRACT_OPERAND(rvc_insn, CIMM10);
int jt10 = ((int32_t)cimm10 << 22 >> 22) & ((1<<RISCV_JUMP_BITS)-1);
if(IS_INSN(rvc_insn, C_ADDI))
{
if(crd == 0)
{
if(imm6 & 0x20)
return MATCH_JALR | (LINK_REG << OP_SH_RD) | (crs1 << OP_SH_RS1);
else
return MATCH_JALR | (crs1 << OP_SH_RS1);
}
return MATCH_ADDI | (crd << OP_SH_RD) | (crd << OP_SH_RS1) |
(imm6 << OP_SH_IMMEDIATE);
}
if(IS_INSN(rvc_insn, C_ADDIW))
return MATCH_ADDIW | (crd << OP_SH_RD) | (crd << OP_SH_RS1) | (imm6 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_LI))
return MATCH_ADDI | (crd << OP_SH_RD) | (imm6 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_MOVE))
return MATCH_ADDI | (crd << OP_SH_RD) | (crs1 << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SLLI))
return MATCH_SLLI | (cimm5 << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SLLI32))
return MATCH_SLLI | ((cimm5+32) << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SRLI))
return MATCH_SRLI | (cimm5 << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SRLI32))
return MATCH_SRLI | ((cimm5+32) << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SRAI))
return MATCH_SRAI | (cimm5 << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SRAI32))
return MATCH_SRAI | ((cimm5+32) << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_SLLIW))
return MATCH_SLLIW | (cimm5 << OP_SH_SHAMT) | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rd_regmap[crds] << OP_SH_RS1);
if(IS_INSN(rvc_insn, C_ADD))
return MATCH_ADD | (crd << OP_SH_RD) | (crs1 << OP_SH_RS1) | (crd << OP_SH_RS2);
if(IS_INSN(rvc_insn, C_SUB))
return MATCH_SUB | (crd << OP_SH_RD) | (crs1 << OP_SH_RS1) | (crd << OP_SH_RS2);
if(IS_INSN(rvc_insn, C_ADD3))
return MATCH_ADD | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2b_regmap[crs2bs] << OP_SH_RS2);
if(IS_INSN(rvc_insn, C_SUB3))
return MATCH_SUB | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2b_regmap[crs2bs] << OP_SH_RS2);
if(IS_INSN(rvc_insn, C_AND3))
return MATCH_AND | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2b_regmap[crs2bs] << OP_SH_RS2);
if(IS_INSN(rvc_insn, C_OR3))
return MATCH_OR | (rvc_rd_regmap[crds] << OP_SH_RD) | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2b_regmap[crs2bs] << OP_SH_RS2);
if(IS_INSN(rvc_insn, C_J))
return MATCH_JAL | (jt10 << OP_SH_TARGET);
if(IS_INSN(rvc_insn, C_BEQ))
return MATCH_BEQ | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2_regmap[crs2s] << OP_SH_RS2) | (imm5lo << OP_SH_IMMLO) | (imm5hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_BNE))
return MATCH_BNE | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2_regmap[crs2s] << OP_SH_RS2) | (imm5lo << OP_SH_IMMLO) | (imm5hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_LDSP))
return MATCH_LD | (30 << OP_SH_RS1) | (crd << OP_SH_RD) | (imm6x8 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_LWSP))
return MATCH_LW | (30 << OP_SH_RS1) | (crd << OP_SH_RD) | (imm6x4 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_SDSP))
return MATCH_SD | (30 << OP_SH_RS1) | (crs2 << OP_SH_RS2) | (imm6x8lo << OP_SH_IMMLO) | (imm6x8hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_SWSP))
return MATCH_SW | (30 << OP_SH_RS1) | (crs2 << OP_SH_RS2) | (imm6x4lo << OP_SH_IMMLO) | (imm6x4hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_LD))
return MATCH_LD | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rd_regmap[crds] << OP_SH_RD) | (imm5x8 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_LW))
return MATCH_LW | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rd_regmap[crds] << OP_SH_RD) | (imm5x4 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_SD))
return MATCH_SD | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2_regmap[crs2s] << OP_SH_RS2) | (imm5x8lo << OP_SH_IMMLO) | (imm5x8hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_SW))
return MATCH_SW | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2_regmap[crs2s] << OP_SH_RS2) | (imm5x4lo << OP_SH_IMMLO) | (imm5x4hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_LD0))
return MATCH_LD | (crs1 << OP_SH_RS1) | (crd << OP_SH_RD);
if(IS_INSN(rvc_insn, C_LW0))
return MATCH_LW | (crs1 << OP_SH_RS1) | (crd << OP_SH_RD);
if(IS_INSN(rvc_insn, C_FLD))
return MATCH_FLD | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rd_regmap[crds] << OP_SH_RD) | (imm5x8 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_FLW))
return MATCH_FLW | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rd_regmap[crds] << OP_SH_RD) | (imm5x4 << OP_SH_IMMEDIATE);
if(IS_INSN(rvc_insn, C_FSD))
return MATCH_FSD | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2_regmap[crs2s] << OP_SH_RS2) | (imm5x8lo << OP_SH_IMMLO) | (imm5x8hi << OP_SH_IMMHI);
if(IS_INSN(rvc_insn, C_FSW))
return MATCH_FSW | (rvc_rs1_regmap[crs1s] << OP_SH_RS1) | (rvc_rs2_regmap[crs2s] << OP_SH_RS2) | (imm5x4lo << OP_SH_IMMLO) | (imm5x4hi << OP_SH_IMMHI);
return rvc_insn;
}
#endif
/* Print the RISC-V instruction at address MEMADDR in debugged memory,
on using INFO. Returns length of the instruction, in bytes.
BIGENDIAN must be 1 if this is big-endian code, 0 if
this is little-endian code. */
static int
riscv_disassemble_insn (bfd_vma memaddr, insn_t word, disassemble_info *info)
{
const struct riscv_opcode *op;
static bfd_boolean init = 0;
static const char *extension = NULL;
static const struct riscv_opcode *riscv_hash[OP_MASK_OP + 1];
struct riscv_private_data *pd;
int insnlen;
/* Build a hash table to shorten the search time. */
if (! init)
{
unsigned int i;
unsigned int e_flags = elf_elfheader (info->section->owner)->e_flags;
extension = riscv_elf_flag_to_name(EF_GET_RISCV_EXT(e_flags));
for (i = 0; i <= OP_MASK_OP; i++)
for (op = riscv_opcodes; op < &riscv_opcodes[NUMOPCODES]; op++)
if (i == ((op->match >> OP_SH_OP) & OP_MASK_OP))
{
riscv_hash[i] = op;
break;
}
init = 1;
}
if (info->private_data == NULL)
{
int i;
pd = info->private_data = calloc(1, sizeof (struct riscv_private_data));
pd->gp = -1;
pd->print_addr = -1;
for (i = 0; i < (int) ARRAY_SIZE(pd->hi_addr); i++)
pd->hi_addr[i] = -1;
for (i = 0; i < info->symtab_size; i++)
if (strcmp (bfd_asymbol_name (info->symtab[i]), "_gp") == 0)
pd->gp = bfd_asymbol_value (info->symtab[i]);
}
else
pd = info->private_data;
insnlen = riscv_insn_length (word);
#if 0
if (insnlen == 2)
word = riscv_rvc_uncompress(word);
#endif
info->bytes_per_chunk = insnlen % 4 == 0 ? 4 : 2;
info->bytes_per_line = 8;
info->display_endian = info->endian;
info->insn_info_valid = 1;
info->branch_delay_insns = 0;
info->data_size = 0;
info->insn_type = dis_nonbranch;
info->target = 0;
info->target2 = 0;
op = riscv_hash[(word >> OP_SH_OP) & OP_MASK_OP];
if (op != NULL)
{
for (; op < &riscv_opcodes[NUMOPCODES]; op++)
{
if ((op->match_func) (op, word)
&& !(no_aliases && (op->pinfo & INSN_ALIAS))
&& !(op->subset[0] == 'X' && strcmp(op->subset, extension)))
{
(*info->fprintf_func) (info->stream, "%s", op->name);
print_insn_args (op->args, word, memaddr, info);
if (pd->print_addr != (bfd_vma)-1)
{
info->target = pd->print_addr;
(*info->fprintf_func) (info->stream, " # ");
(*info->print_address_func) (info->target, info);
pd->print_addr = -1;
}
return insnlen;
}
}
}
/* Handle undefined instructions. */
info->insn_type = dis_noninsn;
(*info->fprintf_func) (info->stream, "0x%llx", (unsigned long long)word);
return insnlen;
}
int
print_insn_riscv (bfd_vma memaddr, struct disassemble_info *info)
{
uint16_t i2;
insn_t insn = 0;
bfd_vma n;
int status;
set_default_riscv_dis_options (info);
parse_riscv_dis_options (info->disassembler_options);
/* Instructions are a sequence of 2-byte packets in little-endian order. */
for (n = 0; n < sizeof(insn) && n < riscv_insn_length (insn); n += 2)
{
status = (*info->read_memory_func) (memaddr + n, (bfd_byte*)&i2, 2, info);
if (status != 0)
{
if (n > 0) /* Don't fail just because we fell off the end. */
break;
(*info->memory_error_func) (status, memaddr, info);
return status;
}
i2 = bfd_getl16 (&i2);
insn |= (insn_t)i2 << (8*n);
}
return riscv_disassemble_insn (memaddr, insn, info);
}
void
print_riscv_disassembler_options (FILE *stream)
{
unsigned int i;
fprintf (stream, _("\n\
The following RISC-V-specific disassembler options are supported for use\n\
with the -M switch (multiple options should be separated by commas):\n"));
fprintf (stream, _("\n\
gpr-names=ABI Print GPR names according to specified ABI.\n\
Default: based on binary being disassembled.\n"));
fprintf (stream, _("\n\
fpr-names=ABI Print FPR names according to specified ABI.\n\
Default: numeric.\n"));
fprintf (stream, _("\n\
For the options above, the following values are supported for \"ABI\":\n\
"));
for (i = 0; i < ARRAY_SIZE (riscv_abi_choices); i++)
fprintf (stream, " %s", riscv_abi_choices[i].name);
fprintf (stream, _("\n"));
fprintf (stream, _("\n"));
}

View File

@ -0,0 +1,683 @@
/* RISC-V opcode list
Copyright 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target.
This file is part of the GNU opcodes library.
This library is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
It is distributed in the hope that it will be useful, but WITHOUT
ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
License for more details.
You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, write to the
Free Software Foundation, 51 Franklin Street - Fifth Floor, Boston,
MA 02110-1301, USA. */
#include "sysdep.h"
#include "opcode/riscv.h"
#include <stdio.h>
/* Short hand so the lines aren't too long. */
/* The order of overloaded instructions matters. Label arguments and
register arguments look the same. Instructions that can have either
for arguments must apear in the correct order in this table for the
assembler to pick the right one. In other words, entries with
immediate operands must apear after the same instruction with
registers.
Because of the lookup algorithm used, entries with the same opcode
name must be contiguous. */
#define WR_xd INSN_WRITE_GPR_D
#define WR_fd INSN_WRITE_FPR_D
#define RD_xs1 INSN_READ_GPR_S
#define RD_xs2 INSN_READ_GPR_T
#define RD_fs1 INSN_READ_FPR_S
#define RD_fs2 INSN_READ_FPR_T
#define RD_fs3 INSN_READ_FPR_R
#define MASK_RS1 (OP_MASK_RS1 << OP_SH_RS1)
#define MASK_RS2 (OP_MASK_RS2 << OP_SH_RS2)
#define MASK_RD (OP_MASK_RD << OP_SH_RD)
#define MASK_IMM ENCODE_ITYPE_IMM(-1U)
#define MASK_UIMM ENCODE_UTYPE_IMM(-1U)
#define MASK_RM (OP_MASK_RM << OP_SH_RM)
#define MASK_PRED (OP_MASK_PRED << OP_SH_PRED)
#define MASK_SUCC (OP_MASK_SUCC << OP_SH_SUCC)
#define MASK_AQ (OP_MASK_AQ << OP_SH_AQ)
#define MASK_RL (OP_MASK_RL << OP_SH_RL)
#define MASK_AQRL (MASK_AQ | MASK_RL)
static int match_opcode(const struct riscv_opcode *op, insn_t insn)
{
return (insn & op->mask) == op->match;
}
static int match_never(const struct riscv_opcode *op ATTRIBUTE_UNUSED,
insn_t insn ATTRIBUTE_UNUSED)
{
return 0;
}
static int match_rs1_eq_rs2(const struct riscv_opcode *op, insn_t insn)
{
return match_opcode(op, insn) &&
((insn & MASK_RS1) >> OP_SH_RS1) == ((insn & MASK_RS2) >> OP_SH_RS2);
}
const struct riscv_opcode riscv_builtin_opcodes[] =
{
/* These instructions appear first so that the disassembler will find
them first. The assemblers uses a hash table based on the
instruction name anyhow. */
/* name, isa, operands, match, mask, pinfo */
{"unimp", "I", "", 0, 0xffff, match_opcode, 0 },
{"nop", "I", "", MATCH_ADDI, MASK_ADDI | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
{"li", "I", "d,j", MATCH_ADDI, MASK_ADDI | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd }, /* addi */
{"li", "I", "d,I", 0, (int) M_LI, match_never, INSN_MACRO },
{"mv", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"move", "I", "d,s", MATCH_ADDI, MASK_ADDI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"b", "I", "p", MATCH_BEQ, MASK_BEQ | MASK_RS1 | MASK_RS2, match_opcode, 0 },/* beq 0,0 */
{"andi", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, WR_xd|RD_xs1 },
{"and", "I", "d,s,t", MATCH_AND, MASK_AND, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"and", "I", "d,s,j", MATCH_ANDI, MASK_ANDI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"beqz", "I", "s,p", MATCH_BEQ, MASK_BEQ | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
{"beq", "I", "s,t,p", MATCH_BEQ, MASK_BEQ, match_opcode, RD_xs1|RD_xs2 },
{"blez", "I", "t,p", MATCH_BGE, MASK_BGE | MASK_RS1, match_opcode, INSN_ALIAS|RD_xs2 },
{"bgez", "I", "s,p", MATCH_BGE, MASK_BGE | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
{"ble", "I", "t,s,p", MATCH_BGE, MASK_BGE, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
{"bleu", "I", "t,s,p", MATCH_BGEU, MASK_BGEU, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
{"bge", "I", "s,t,p", MATCH_BGE, MASK_BGE, match_opcode, RD_xs1|RD_xs2 },
{"bgeu", "I", "s,t,p", MATCH_BGEU, MASK_BGEU, match_opcode, RD_xs1|RD_xs2 },
{"bltz", "I", "s,p", MATCH_BLT, MASK_BLT | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
{"bgtz", "I", "t,p", MATCH_BLT, MASK_BLT | MASK_RS1, match_opcode, INSN_ALIAS|RD_xs2 },
{"blt", "I", "s,t,p", MATCH_BLT, MASK_BLT, match_opcode, RD_xs1|RD_xs2 },
{"bltu", "I", "s,t,p", MATCH_BLTU, MASK_BLTU, match_opcode, RD_xs1|RD_xs2 },
{"bgt", "I", "t,s,p", MATCH_BLT, MASK_BLT, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
{"bgtu", "I", "t,s,p", MATCH_BLTU, MASK_BLTU, match_opcode, INSN_ALIAS|RD_xs1|RD_xs2 },
{"bnez", "I", "s,p", MATCH_BNE, MASK_BNE | MASK_RS2, match_opcode, INSN_ALIAS|RD_xs1 },
{"bne", "I", "s,t,p", MATCH_BNE, MASK_BNE, match_opcode, RD_xs1|RD_xs2 },
{"addi", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, WR_xd|RD_xs1 },
{"add", "I", "d,s,t", MATCH_ADD, MASK_ADD, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"add", "I", "d,s,t,0",MATCH_ADD, MASK_ADD, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"add", "I", "d,s,j", MATCH_ADDI, MASK_ADDI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"la", "I", "d,A", 0, (int) M_LA, match_never, INSN_MACRO },
{"lla", "I", "d,A", 0, (int) M_LLA, match_never, INSN_MACRO },
{"la.tls.gd", "I", "d,A", 0, (int) M_LA_TLS_GD, match_never, INSN_MACRO },
{"la.tls.ie", "I", "d,A", 0, (int) M_LA_TLS_IE, match_never, INSN_MACRO },
{"neg", "I", "d,t", MATCH_SUB, MASK_SUB | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, /* sub 0 */
{"slli", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, WR_xd|RD_xs1 },
{"sll", "I", "d,s,t", MATCH_SLL, MASK_SLL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"sll", "I", "d,s,>", MATCH_SLLI, MASK_SLLI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"srli", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, WR_xd|RD_xs1 },
{"srl", "I", "d,s,t", MATCH_SRL, MASK_SRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"srl", "I", "d,s,>", MATCH_SRLI, MASK_SRLI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"srai", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, WR_xd|RD_xs1 },
{"sra", "I", "d,s,t", MATCH_SRA, MASK_SRA, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"sra", "I", "d,s,>", MATCH_SRAI, MASK_SRAI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"sub", "I", "d,s,t", MATCH_SUB, MASK_SUB, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"ret", "I", "", MATCH_JALR | (LINK_REG << OP_SH_RS1), MASK_JALR | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"j", "I", "a", MATCH_JAL, MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS },
{"jal", "I", "a", MATCH_JAL | (LINK_REG << OP_SH_RD), MASK_JAL | MASK_RD, match_opcode, INSN_ALIAS|WR_xd },
{"jal", "I", "d,a", MATCH_JAL, MASK_JAL, match_opcode, WR_xd },
{"call", "I", "c", 0, (int) M_CALL, match_never, INSN_MACRO },
{"jump", "I", "c", 0, (int) M_JUMP, match_never, INSN_MACRO },
{"jr", "I", "s", MATCH_JALR, MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"jr", "I", "s,j", MATCH_JALR, MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"jalr", "I", "s", MATCH_JALR | (LINK_REG << OP_SH_RD), MASK_JALR | MASK_RD | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"jalr", "I", "s,j", MATCH_JALR | (LINK_REG << OP_SH_RD), MASK_JALR | MASK_RD, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"jalr", "I", "d,s", MATCH_JALR, MASK_JALR | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"jalr", "I", "d,s,j", MATCH_JALR, MASK_JALR, match_opcode, WR_xd|RD_xs1 },
{"lb", "I", "d,o(s)", MATCH_LB, MASK_LB, match_opcode, WR_xd|RD_xs1 },
{"lb", "I", "d,A", 0, (int) M_LB, match_never, INSN_MACRO },
{"lbu", "I", "d,o(s)", MATCH_LBU, MASK_LBU, match_opcode, WR_xd|RD_xs1 },
{"lbu", "I", "d,A", 0, (int) M_LBU, match_never, INSN_MACRO },
{"lh", "I", "d,o(s)", MATCH_LH, MASK_LH, match_opcode, WR_xd|RD_xs1 },
{"lh", "I", "d,A", 0, (int) M_LH, match_never, INSN_MACRO },
{"lhu", "I", "d,o(s)", MATCH_LHU, MASK_LHU, match_opcode, WR_xd|RD_xs1 },
{"lhu", "I", "d,A", 0, (int) M_LHU, match_never, INSN_MACRO },
{"lw", "I", "d,o(s)", MATCH_LW, MASK_LW, match_opcode, WR_xd|RD_xs1 },
{"lw", "I", "d,A", 0, (int) M_LW, match_never, INSN_MACRO },
{"lui", "I", "d,u", MATCH_LUI, MASK_LUI, match_opcode, WR_xd },
{"not", "I", "d,s", MATCH_XORI | MASK_IMM, MASK_XORI | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"ori", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, WR_xd|RD_xs1 },
{"or", "I", "d,s,t", MATCH_OR, MASK_OR, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"or", "I", "d,s,j", MATCH_ORI, MASK_ORI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"auipc", "I", "d,u", MATCH_AUIPC, MASK_AUIPC, match_opcode, WR_xd },
{"seqz", "I", "d,s", MATCH_SLTIU | ENCODE_ITYPE_IMM(1), MASK_SLTIU | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"snez", "I", "d,t", MATCH_SLTU, MASK_SLTU | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 },
{"sltz", "I", "d,s", MATCH_SLT, MASK_SLT | MASK_RS2, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"sgtz", "I", "d,t", MATCH_SLT, MASK_SLT | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 },
{"slti", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"slt", "I", "d,s,t", MATCH_SLT, MASK_SLT, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"slt", "I", "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, WR_xd|RD_xs1 },
{"sltiu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, WR_xd|RD_xs1 },
{"sltu", "I", "d,s,t", MATCH_SLTU, MASK_SLTU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"sltu", "I", "d,s,j", MATCH_SLTIU, MASK_SLTIU, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"sgt", "I", "d,t,s", MATCH_SLT, MASK_SLT, match_opcode, INSN_ALIAS|WR_xd|RD_xs1|RD_xs2 },
{"sgtu", "I", "d,t,s", MATCH_SLTU, MASK_SLTU, match_opcode, INSN_ALIAS|WR_xd|RD_xs1|RD_xs2 },
{"sb", "I", "t,q(s)", MATCH_SB, MASK_SB, match_opcode, RD_xs1|RD_xs2 },
{"sb", "I", "t,A,s", 0, (int) M_SB, match_never, INSN_MACRO },
{"sh", "I", "t,q(s)", MATCH_SH, MASK_SH, match_opcode, RD_xs1|RD_xs2 },
{"sh", "I", "t,A,s", 0, (int) M_SH, match_never, INSN_MACRO },
{"sw", "I", "t,q(s)", MATCH_SW, MASK_SW, match_opcode, RD_xs1|RD_xs2 },
{"sw", "I", "t,A,s", 0, (int) M_SW, match_never, INSN_MACRO },
{"fence", "I", "", MATCH_FENCE | MASK_PRED | MASK_SUCC, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, INSN_ALIAS },
{"fence", "I", "P,Q", MATCH_FENCE, MASK_FENCE | MASK_RD | MASK_RS1 | (MASK_IMM & ~MASK_PRED & ~MASK_SUCC), match_opcode, 0 },
{"fence.i", "I", "", MATCH_FENCE_I, MASK_FENCE | MASK_RD | MASK_RS1 | MASK_IMM, match_opcode, 0 },
{"rdcycle", "I", "d", MATCH_RDCYCLE, MASK_RDCYCLE, match_opcode, WR_xd },
{"rdinstret", "I", "d", MATCH_RDINSTRET, MASK_RDINSTRET, match_opcode, WR_xd },
{"rdtime", "I", "d", MATCH_RDTIME, MASK_RDTIME, match_opcode, WR_xd },
{"rdcycleh", "32I", "d", MATCH_RDCYCLEH, MASK_RDCYCLEH, match_opcode, WR_xd },
{"rdinstreth","32I", "d", MATCH_RDINSTRETH, MASK_RDINSTRETH, match_opcode, WR_xd },
{"rdtimeh", "32I", "d", MATCH_RDTIMEH, MASK_RDTIMEH, match_opcode, WR_xd },
{"sbreak", "I", "", MATCH_SBREAK, MASK_SBREAK, match_opcode, 0 },
{"scall", "I", "", MATCH_SCALL, MASK_SCALL, match_opcode, 0 },
{"xori", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, WR_xd|RD_xs1 },
{"xor", "I", "d,s,t", MATCH_XOR, MASK_XOR, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"xor", "I", "d,s,j", MATCH_XORI, MASK_XORI, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"lwu", "64I", "d,o(s)", MATCH_LWU, MASK_LWU, match_opcode, WR_xd|RD_xs1 },
{"lwu", "64I", "d,A", 0, (int) M_LWU, match_never, INSN_MACRO },
{"ld", "64I", "d,o(s)", MATCH_LD, MASK_LD, match_opcode, WR_xd|RD_xs1 },
{"ld", "64I", "d,A", 0, (int) M_LD, match_never, INSN_MACRO },
{"sd", "64I", "t,q(s)", MATCH_SD, MASK_SD, match_opcode, RD_xs1|RD_xs2 },
{"sd", "64I", "t,A,s", 0, (int) M_SD, match_never, INSN_MACRO },
{"sext.w", "64I", "d,s", MATCH_ADDIW, MASK_ADDIW | MASK_IMM, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"addiw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, WR_xd|RD_xs1 },
{"addw", "64I", "d,s,t", MATCH_ADDW, MASK_ADDW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"addw", "64I", "d,s,j", MATCH_ADDIW, MASK_ADDIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"negw", "64I", "d,t", MATCH_SUBW, MASK_SUBW | MASK_RS1, match_opcode, INSN_ALIAS|WR_xd|RD_xs2 }, /* sub 0 */
{"slliw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, WR_xd|RD_xs1 },
{"sllw", "64I", "d,s,t", MATCH_SLLW, MASK_SLLW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"sllw", "64I", "d,s,<", MATCH_SLLIW, MASK_SLLIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"srliw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, WR_xd|RD_xs1 },
{"srlw", "64I", "d,s,t", MATCH_SRLW, MASK_SRLW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"srlw", "64I", "d,s,<", MATCH_SRLIW, MASK_SRLIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"sraiw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, WR_xd|RD_xs1 },
{"sraw", "64I", "d,s,t", MATCH_SRAW, MASK_SRAW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"sraw", "64I", "d,s,<", MATCH_SRAIW, MASK_SRAIW, match_opcode, INSN_ALIAS|WR_xd|RD_xs1 },
{"subw", "64I", "d,s,t", MATCH_SUBW, MASK_SUBW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
/* Atomic memory operation instruction subset */
{"lr.w", "A", "d,0(s)", MATCH_LR_W, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"sc.w", "A", "d,t,0(s)", MATCH_SC_W, MASK_SC_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoadd.w", "A", "d,t,0(s)", MATCH_AMOADD_W, MASK_AMOADD_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoswap.w", "A", "d,t,0(s)", MATCH_AMOSWAP_W, MASK_AMOSWAP_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoand.w", "A", "d,t,0(s)", MATCH_AMOAND_W, MASK_AMOAND_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoor.w", "A", "d,t,0(s)", MATCH_AMOOR_W, MASK_AMOOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoxor.w", "A", "d,t,0(s)", MATCH_AMOXOR_W, MASK_AMOXOR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amomax.w", "A", "d,t,0(s)", MATCH_AMOMAX_W, MASK_AMOMAX_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amomaxu.w", "A", "d,t,0(s)", MATCH_AMOMAXU_W, MASK_AMOMAXU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amomin.w", "A", "d,t,0(s)", MATCH_AMOMIN_W, MASK_AMOMIN_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amominu.w", "A", "d,t,0(s)", MATCH_AMOMINU_W, MASK_AMOMINU_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"lr.w.aq", "A", "d,0(s)", MATCH_LR_W | MASK_AQ, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"lr.w.rl", "A", "d,0(s)", MATCH_LR_W | MASK_RL, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"lr.w.sc", "A", "d,0(s)", MATCH_LR_W | MASK_AQRL, MASK_LR_W | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"lr.d", "64A", "d,0(s)", MATCH_LR_D, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"sc.d", "64A", "d,t,0(s)", MATCH_SC_D, MASK_SC_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoadd.d", "64A", "d,t,0(s)", MATCH_AMOADD_D, MASK_AMOADD_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoswap.d", "64A", "d,t,0(s)", MATCH_AMOSWAP_D, MASK_AMOSWAP_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoand.d", "64A", "d,t,0(s)", MATCH_AMOAND_D, MASK_AMOAND_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoor.d", "64A", "d,t,0(s)", MATCH_AMOOR_D, MASK_AMOOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amoxor.d", "64A", "d,t,0(s)", MATCH_AMOXOR_D, MASK_AMOXOR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amomax.d", "64A", "d,t,0(s)", MATCH_AMOMAX_D, MASK_AMOMAX_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amomaxu.d", "64A", "d,t,0(s)", MATCH_AMOMAXU_D, MASK_AMOMAXU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amomin.d", "64A", "d,t,0(s)", MATCH_AMOMIN_D, MASK_AMOMIN_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"amominu.d", "64A", "d,t,0(s)", MATCH_AMOMINU_D, MASK_AMOMINU_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"lr.d.aq", "64A", "d,0(s)", MATCH_LR_D | MASK_AQ, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"lr.d.rl", "64A", "d,0(s)", MATCH_LR_D | MASK_RL, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"lr.d.sc", "64A", "d,0(s)", MATCH_LR_D | MASK_AQRL, MASK_LR_D | MASK_AQRL, match_opcode, WR_xd|RD_xs1 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
{"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 },
/* Multiply/Divide instruction subset */
{"mul", "M", "d,s,t", MATCH_MUL, MASK_MUL, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"mulh", "M", "d,s,t", MATCH_MULH, MASK_MULH, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"mulhu", "M", "d,s,t", MATCH_MULHU, MASK_MULHU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"mulhsu", "M", "d,s,t", MATCH_MULHSU, MASK_MULHSU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"div", "M", "d,s,t", MATCH_DIV, MASK_DIV, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"divu", "M", "d,s,t", MATCH_DIVU, MASK_DIVU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"rem", "M", "d,s,t", MATCH_REM, MASK_REM, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"remu", "M", "d,s,t", MATCH_REMU, MASK_REMU, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"mulw", "64M", "d,s,t", MATCH_MULW, MASK_MULW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"divw", "64M", "d,s,t", MATCH_DIVW, MASK_DIVW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"divuw", "64M", "d,s,t", MATCH_DIVUW, MASK_DIVUW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"remw", "64M", "d,s,t", MATCH_REMW, MASK_REMW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
{"remuw", "64M", "d,s,t", MATCH_REMUW, MASK_REMUW, match_opcode, WR_xd|RD_xs1|RD_xs2 },
/* Single-precision floating-point instruction subset */
{"frsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, WR_xd },
{"fssr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, RD_xs1 },
{"fssr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, WR_xd|RD_xs1 },
{"frcsr", "F", "d", MATCH_FRCSR, MASK_FRCSR, match_opcode, WR_xd },
{"fscsr", "F", "s", MATCH_FSCSR, MASK_FSCSR | MASK_RD, match_opcode, RD_xs1 },
{"fscsr", "F", "d,s", MATCH_FSCSR, MASK_FSCSR, match_opcode, WR_xd|RD_xs1 },
{"frrm", "F", "d", MATCH_FRRM, MASK_FRRM, match_opcode, WR_xd },
{"fsrm", "F", "s", MATCH_FSRM, MASK_FSRM | MASK_RD, match_opcode, RD_xs1 },
{"fsrm", "F", "d,s", MATCH_FSRM, MASK_FSRM, match_opcode, WR_xd|RD_xs1 },
{"frflags", "F", "d", MATCH_FRFLAGS, MASK_FRFLAGS, match_opcode, WR_xd },
{"fsflags", "F", "s", MATCH_FSFLAGS, MASK_FSFLAGS | MASK_RD, match_opcode, RD_xs1 },
{"fsflags", "F", "d,s", MATCH_FSFLAGS, MASK_FSFLAGS, match_opcode, WR_xd|RD_xs1 },
{"flw", "F", "D,o(s)", MATCH_FLW, MASK_FLW, match_opcode, WR_fd|RD_xs1 },
{"flw", "F", "D,A,s", 0, (int) M_FLW, match_never, INSN_MACRO },
{"fsw", "F", "T,q(s)", MATCH_FSW, MASK_FSW, match_opcode, RD_xs1|RD_fs2 },
{"fsw", "F", "T,A,s", 0, (int) M_FSW, match_never, INSN_MACRO },
{"fmv.x.s", "F", "d,S", MATCH_FMV_X_S, MASK_FMV_X_S, match_opcode, WR_xd|RD_fs1 },
{"fmv.s.x", "F", "D,s", MATCH_FMV_S_X, MASK_FMV_S_X, match_opcode, WR_fd|RD_xs1 },
{"fmv.s", "F", "D,U", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
{"fneg.s", "F", "D,U", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
{"fabs.s", "F", "D,U", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
{"fsgnj.s", "F", "D,S,T", MATCH_FSGNJ_S, MASK_FSGNJ_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsgnjn.s", "F", "D,S,T", MATCH_FSGNJN_S, MASK_FSGNJN_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsgnjx.s", "F", "D,S,T", MATCH_FSGNJX_S, MASK_FSGNJX_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fadd.s", "F", "D,S,T", MATCH_FADD_S | MASK_RM, MASK_FADD_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fadd.s", "F", "D,S,T,m", MATCH_FADD_S, MASK_FADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsub.s", "F", "D,S,T", MATCH_FSUB_S | MASK_RM, MASK_FSUB_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsub.s", "F", "D,S,T,m", MATCH_FSUB_S, MASK_FSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmul.s", "F", "D,S,T", MATCH_FMUL_S | MASK_RM, MASK_FMUL_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmul.s", "F", "D,S,T,m", MATCH_FMUL_S, MASK_FMUL_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fdiv.s", "F", "D,S,T", MATCH_FDIV_S | MASK_RM, MASK_FDIV_S | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fdiv.s", "F", "D,S,T,m", MATCH_FDIV_S, MASK_FDIV_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsqrt.s", "F", "D,S", MATCH_FSQRT_S | MASK_RM, MASK_FSQRT_S | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fsqrt.s", "F", "D,S,m", MATCH_FSQRT_S, MASK_FSQRT_S, match_opcode, WR_fd|RD_fs1 },
{"fmin.s", "F", "D,S,T", MATCH_FMIN_S, MASK_FMIN_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmax.s", "F", "D,S,T", MATCH_FMAX_S, MASK_FMAX_S, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"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 },
{"fmadd.s", "F", "D,S,T,R,m", MATCH_FMADD_S, MASK_FMADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fnmadd.s", "F", "D,S,T,R,m", MATCH_FNMADD_S, MASK_FNMADD_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fmsub.s", "F", "D,S,T,R,m", MATCH_FMSUB_S, MASK_FMSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fnmsub.s", "F", "D,S,T,R,m", MATCH_FNMSUB_S, MASK_FNMSUB_S, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"fcvt.w.s", "F", "d,S", MATCH_FCVT_W_S | MASK_RM, MASK_FCVT_W_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.w.s", "F", "d,S,m", MATCH_FCVT_W_S, MASK_FCVT_W_S, match_opcode, WR_xd|RD_fs1 },
{"fcvt.wu.s", "F", "d,S", MATCH_FCVT_WU_S | MASK_RM, MASK_FCVT_WU_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.wu.s", "F", "d,S,m", MATCH_FCVT_WU_S, MASK_FCVT_WU_S, match_opcode, WR_xd|RD_fs1 },
{"fcvt.s.w", "F", "D,s", MATCH_FCVT_S_W | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.s.w", "F", "D,s,m", MATCH_FCVT_S_W, MASK_FCVT_S_W, match_opcode, WR_fd|RD_xs1 },
{"fcvt.s.wu", "F", "D,s", MATCH_FCVT_S_WU | MASK_RM, MASK_FCVT_S_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.s.wu", "F", "D,s,m", MATCH_FCVT_S_WU, MASK_FCVT_S_WU, match_opcode, WR_fd|RD_xs1 },
{"fclass.s", "F", "d,S", MATCH_FCLASS_S, MASK_FCLASS_S, match_opcode, WR_xd|RD_fs1 },
{"feq.s", "F", "d,S,T", MATCH_FEQ_S, MASK_FEQ_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"flt.s", "F", "d,S,T", MATCH_FLT_S, MASK_FLT_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fle.s", "F", "d,S,T", MATCH_FLE_S, MASK_FLE_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fgt.s", "F", "d,T,S", MATCH_FLT_S, MASK_FLT_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fge.s", "F", "d,T,S", MATCH_FLE_S, MASK_FLE_S, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fcvt.l.s", "64F", "d,S", MATCH_FCVT_L_S | MASK_RM, MASK_FCVT_L_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.l.s", "64F", "d,S,m", MATCH_FCVT_L_S, MASK_FCVT_L_S, match_opcode, WR_xd|RD_fs1 },
{"fcvt.lu.s", "64F", "d,S", MATCH_FCVT_LU_S | MASK_RM, MASK_FCVT_LU_S | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.lu.s", "64F", "d,S,m", MATCH_FCVT_LU_S, MASK_FCVT_LU_S, match_opcode, WR_xd|RD_fs1 },
{"fcvt.s.l", "64F", "D,s", MATCH_FCVT_S_L | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.s.l", "64F", "D,s,m", MATCH_FCVT_S_L, MASK_FCVT_S_L, match_opcode, WR_fd|RD_xs1 },
{"fcvt.s.lu", "64F", "D,s", MATCH_FCVT_S_LU | MASK_RM, MASK_FCVT_S_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.s.lu", "64F", "D,s,m", MATCH_FCVT_S_LU, MASK_FCVT_S_LU, match_opcode, WR_fd|RD_xs1 },
/* Double-precision floating-point instruction subset */
{"fld", "D", "D,o(s)", MATCH_FLD, MASK_FLD, match_opcode, WR_fd|RD_xs1 },
{"fld", "D", "D,A,s", 0, (int) M_FLD, match_never, INSN_MACRO },
{"fsd", "D", "T,q(s)", MATCH_FSD, MASK_FSD, match_opcode, RD_xs1|RD_fs2 },
{"fsd", "D", "T,A,s", 0, (int) M_FSD, match_never, INSN_MACRO },
{"fmv.d", "D", "D,U", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
{"fneg.d", "D", "D,U", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
{"fabs.d", "D", "D,U", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_rs1_eq_rs2, INSN_ALIAS|WR_fd|RD_fs1|RD_fs2 },
{"fsgnj.d", "D", "D,S,T", MATCH_FSGNJ_D, MASK_FSGNJ_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsgnjn.d", "D", "D,S,T", MATCH_FSGNJN_D, MASK_FSGNJN_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsgnjx.d", "D", "D,S,T", MATCH_FSGNJX_D, MASK_FSGNJX_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fadd.d", "D", "D,S,T", MATCH_FADD_D | MASK_RM, MASK_FADD_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fadd.d", "D", "D,S,T,m", MATCH_FADD_D, MASK_FADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsub.d", "D", "D,S,T", MATCH_FSUB_D | MASK_RM, MASK_FSUB_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsub.d", "D", "D,S,T,m", MATCH_FSUB_D, MASK_FSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmul.d", "D", "D,S,T", MATCH_FMUL_D | MASK_RM, MASK_FMUL_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmul.d", "D", "D,S,T,m", MATCH_FMUL_D, MASK_FMUL_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fdiv.d", "D", "D,S,T", MATCH_FDIV_D | MASK_RM, MASK_FDIV_D | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fdiv.d", "D", "D,S,T,m", MATCH_FDIV_D, MASK_FDIV_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsqrt.d", "D", "D,S", MATCH_FSQRT_D | MASK_RM, MASK_FSQRT_D | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fsqrt.d", "D", "D,S,m", MATCH_FSQRT_D, MASK_FSQRT_D, match_opcode, WR_fd|RD_fs1 },
{"fmin.d", "D", "D,S,T", MATCH_FMIN_D, MASK_FMIN_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmax.d", "D", "D,S,T", MATCH_FMAX_D, MASK_FMAX_D, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"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 },
{"fmadd.d", "D", "D,S,T,R,m", MATCH_FMADD_D, MASK_FMADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fnmadd.d", "D", "D,S,T,R,m", MATCH_FNMADD_D, MASK_FNMADD_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fmsub.d", "D", "D,S,T,R,m", MATCH_FMSUB_D, MASK_FMSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fnmsub.d", "D", "D,S,T,R,m", MATCH_FNMSUB_D, MASK_FNMSUB_D, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"fcvt.w.d", "D", "d,S", MATCH_FCVT_W_D | MASK_RM, MASK_FCVT_W_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.w.d", "D", "d,S,m", MATCH_FCVT_W_D, MASK_FCVT_W_D, match_opcode, WR_xd|RD_fs1 },
{"fcvt.wu.d", "D", "d,S", MATCH_FCVT_WU_D | MASK_RM, MASK_FCVT_WU_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.wu.d", "D", "d,S,m", MATCH_FCVT_WU_D, MASK_FCVT_WU_D, match_opcode, WR_xd|RD_fs1 },
{"fcvt.d.w", "D", "D,s", MATCH_FCVT_D_W, MASK_FCVT_D_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.d.wu", "D", "D,s", MATCH_FCVT_D_WU, MASK_FCVT_D_WU | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.d.s", "D", "D,S", MATCH_FCVT_D_S, MASK_FCVT_D_S | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fcvt.s.d", "D", "D,S", MATCH_FCVT_S_D | MASK_RM, MASK_FCVT_S_D | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fcvt.s.d", "D", "D,S,m", MATCH_FCVT_S_D, MASK_FCVT_S_D, match_opcode, WR_fd|RD_fs1 },
{"fclass.d", "D", "d,S", MATCH_FCLASS_D, MASK_FCLASS_D, match_opcode, WR_xd|RD_fs1 },
{"feq.d", "D", "d,S,T", MATCH_FEQ_D, MASK_FEQ_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"flt.d", "D", "d,S,T", MATCH_FLT_D, MASK_FLT_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fle.d", "D", "d,S,T", MATCH_FLE_D, MASK_FLE_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fgt.d", "D", "d,T,S", MATCH_FLT_D, MASK_FLT_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fge.d", "D", "d,T,S", MATCH_FLE_D, MASK_FLE_D, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fmv.x.d", "64D", "d,S", MATCH_FMV_X_D, MASK_FMV_X_D, match_opcode, WR_xd|RD_fs1 },
{"fmv.d.x", "64D", "D,s", MATCH_FMV_D_X, MASK_FMV_D_X, match_opcode, WR_fd|RD_xs1 },
{"fcvt.l.d", "64D", "d,S", MATCH_FCVT_L_D | MASK_RM, MASK_FCVT_L_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.l.d", "64D", "d,S,m", MATCH_FCVT_L_D, MASK_FCVT_L_D, match_opcode, WR_xd|RD_fs1 },
{"fcvt.lu.d", "64D", "d,S", MATCH_FCVT_LU_D | MASK_RM, MASK_FCVT_LU_D | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.lu.d", "64D", "d,S,m", MATCH_FCVT_LU_D, MASK_FCVT_LU_D, match_opcode, WR_xd|RD_fs1 },
{"fcvt.d.l", "64D", "D,s", MATCH_FCVT_D_L | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.d.l", "64D", "D,s,m", MATCH_FCVT_D_L, MASK_FCVT_D_L, match_opcode, WR_fd|RD_xs1 },
{"fcvt.d.lu", "64D", "D,s", MATCH_FCVT_D_LU | MASK_RM, MASK_FCVT_D_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.d.lu", "64D", "D,s,m", MATCH_FCVT_D_LU, MASK_FCVT_D_LU, match_opcode, WR_fd|RD_xs1 },
/* Supervisor instructions */
{"csrr", "I", "d,E", MATCH_CSRRS, MASK_CSRRS | MASK_RS1, match_opcode, WR_xd },
{"csrwi", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrw", "I", "E,s", MATCH_CSRRW, MASK_CSRRW | MASK_RD, match_opcode, RD_xs1 },
{"csrw", "I", "E,Z", MATCH_CSRRWI, MASK_CSRRWI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrsi", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrs", "I", "E,s", MATCH_CSRRS, MASK_CSRRS | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrs", "I", "E,Z", MATCH_CSRRSI, MASK_CSRRSI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrci", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrc", "I", "E,s", MATCH_CSRRC, MASK_CSRRC | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrc", "I", "E,Z", MATCH_CSRRCI, MASK_CSRRCI | MASK_RD, match_opcode, WR_xd|RD_xs1 },
{"csrrw", "I", "d,E,s", MATCH_CSRRW, MASK_CSRRW, match_opcode, WR_xd|RD_xs1 },
{"csrrw", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, WR_xd|RD_xs1 },
{"csrrs", "I", "d,E,s", MATCH_CSRRS, MASK_CSRRS, match_opcode, WR_xd|RD_xs1 },
{"csrrs", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, WR_xd|RD_xs1 },
{"csrrc", "I", "d,E,s", MATCH_CSRRC, MASK_CSRRC, match_opcode, WR_xd|RD_xs1 },
{"csrrc", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, WR_xd|RD_xs1 },
{"csrrwi", "I", "d,E,Z", MATCH_CSRRWI, MASK_CSRRWI, match_opcode, WR_xd|RD_xs1 },
{"csrrsi", "I", "d,E,Z", MATCH_CSRRSI, MASK_CSRRSI, match_opcode, WR_xd|RD_xs1 },
{"csrrci", "I", "d,E,Z", MATCH_CSRRCI, MASK_CSRRCI, match_opcode, WR_xd|RD_xs1 },
{"sret", "I", "", MATCH_SRET, MASK_SRET, match_opcode, 0 },
/* Half-precision floating-point instruction subset */
{"flh", "Xhwacha", "D,o(s)", MATCH_FLH, MASK_FLH, match_opcode, WR_fd|RD_xs1 },
{"fsh", "Xhwacha", "T,q(s)", MATCH_FSH, MASK_FSH, match_opcode, RD_xs1|RD_fs2 },
{"fsgnj.h", "Xhwacha", "D,S,T", MATCH_FSGNJ_H, MASK_FSGNJ_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsgnjn.h", "Xhwacha", "D,S,T", MATCH_FSGNJN_H, MASK_FSGNJN_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsgnjx.h", "Xhwacha", "D,S,T", MATCH_FSGNJX_H, MASK_FSGNJX_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fadd.h", "Xhwacha", "D,S,T", MATCH_FADD_H | MASK_RM, MASK_FADD_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fadd.h", "Xhwacha", "D,S,T,m", MATCH_FADD_H, MASK_FADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsub.h", "Xhwacha", "D,S,T", MATCH_FSUB_H | MASK_RM, MASK_FSUB_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsub.h", "Xhwacha", "D,S,T,m", MATCH_FSUB_H, MASK_FSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmul.h", "Xhwacha", "D,S,T", MATCH_FMUL_H | MASK_RM, MASK_FMUL_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmul.h", "Xhwacha", "D,S,T,m", MATCH_FMUL_H, MASK_FMUL_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fdiv.h", "Xhwacha", "D,S,T", MATCH_FDIV_H | MASK_RM, MASK_FDIV_H | MASK_RM, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fdiv.h", "Xhwacha", "D,S,T,m", MATCH_FDIV_H, MASK_FDIV_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fsqrt.h", "Xhwacha", "D,S", MATCH_FSQRT_H | MASK_RM, MASK_FSQRT_H | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fsqrt.h", "Xhwacha", "D,S,m", MATCH_FSQRT_H, MASK_FSQRT_H, match_opcode, WR_fd|RD_fs1 },
{"fmin.h", "Xhwacha", "D,S,T", MATCH_FMIN_H, MASK_FMIN_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"fmax.h", "Xhwacha", "D,S,T", MATCH_FMAX_H, MASK_FMAX_H, match_opcode, WR_fd|RD_fs1|RD_fs2 },
{"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 },
{"fmadd.h", "Xhwacha", "D,S,T,R,m", MATCH_FMADD_H, MASK_FMADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fnmadd.h", "Xhwacha", "D,S,T,R,m", MATCH_FNMADD_H, MASK_FNMADD_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fmsub.h", "Xhwacha", "D,S,T,R,m", MATCH_FMSUB_H, MASK_FMSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"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 },
{"fnmsub.h", "Xhwacha", "D,S,T,R,m", MATCH_FNMSUB_H, MASK_FNMSUB_H, match_opcode, WR_fd|RD_fs1|RD_fs2|RD_fs3 },
{"fcvt.s.h", "Xhwacha", "D,S", MATCH_FCVT_S_H, MASK_FCVT_S_H | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fcvt.h.s", "Xhwacha", "D,S", MATCH_FCVT_H_S | MASK_RM, MASK_FCVT_H_S | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fcvt.h.s", "Xhwacha", "D,S,m", MATCH_FCVT_H_S, MASK_FCVT_H_S, match_opcode, WR_fd|RD_fs1 },
{"fcvt.d.h", "Xhwacha", "D,S", MATCH_FCVT_D_H, MASK_FCVT_D_H | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fcvt.h.d", "Xhwacha", "D,S", MATCH_FCVT_H_D | MASK_RM, MASK_FCVT_H_D | MASK_RM, match_opcode, WR_fd|RD_fs1 },
{"fcvt.h.d", "Xhwacha", "D,S,m", MATCH_FCVT_H_D, MASK_FCVT_H_D, match_opcode, WR_fd|RD_fs1 },
{"feq.h", "Xhwacha", "d,S,T", MATCH_FEQ_H, MASK_FEQ_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"flt.h", "Xhwacha", "d,S,T", MATCH_FLT_H, MASK_FLT_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fle.h", "Xhwacha", "d,S,T", MATCH_FLE_H, MASK_FLE_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fgt.h", "Xhwacha", "d,T,S", MATCH_FLT_H, MASK_FLT_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fge.h", "Xhwacha", "d,T,S", MATCH_FLE_H, MASK_FLE_H, match_opcode, WR_xd|RD_fs1|RD_fs2 },
{"fmv.x.h", "Xhwacha", "d,S", MATCH_FMV_X_H, MASK_FMV_X_H, match_opcode, WR_xd|RD_fs1 },
{"fmv.h.x", "Xhwacha", "D,s", MATCH_FMV_H_X, MASK_FMV_H_X, match_opcode, WR_fd|RD_xs1 },
{"fcvt.w.h", "Xhwacha", "d,S", MATCH_FCVT_W_H | MASK_RM, MASK_FCVT_W_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.w.h", "Xhwacha", "d,S,m", MATCH_FCVT_W_H, MASK_FCVT_W_H, match_opcode, WR_xd|RD_fs1 },
{"fcvt.wu.h", "Xhwacha", "d,S", MATCH_FCVT_WU_H | MASK_RM, MASK_FCVT_WU_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.wu.h", "Xhwacha", "d,S,m", MATCH_FCVT_WU_H, MASK_FCVT_WU_H, match_opcode, WR_xd|RD_fs1 },
{"fcvt.h.w", "Xhwacha", "D,s", MATCH_FCVT_H_W, MASK_FCVT_H_W | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.h.wu", "Xhwacha", "D,s", MATCH_FCVT_H_WU, MASK_FCVT_H_WU | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.l.h", "Xhwacha", "d,S", MATCH_FCVT_L_H | MASK_RM, MASK_FCVT_L_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.l.h", "Xhwacha", "d,S,m", MATCH_FCVT_L_H, MASK_FCVT_L_H, match_opcode, WR_xd|RD_fs1 },
{"fcvt.lu.h", "Xhwacha", "d,S", MATCH_FCVT_LU_H | MASK_RM, MASK_FCVT_LU_H | MASK_RM, match_opcode, WR_xd|RD_fs1 },
{"fcvt.lu.h", "Xhwacha", "d,S,m", MATCH_FCVT_LU_H, MASK_FCVT_LU_H, match_opcode, WR_xd|RD_fs1 },
{"fcvt.h.l", "Xhwacha", "D,s", MATCH_FCVT_H_L | MASK_RM, MASK_FCVT_H_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.h.l", "Xhwacha", "D,s,m", MATCH_FCVT_H_L, MASK_FCVT_H_L, match_opcode, WR_fd|RD_xs1 },
{"fcvt.h.lu", "Xhwacha", "D,s", MATCH_FCVT_H_LU | MASK_RM, MASK_FCVT_H_L | MASK_RM, match_opcode, WR_fd|RD_xs1 },
{"fcvt.h.lu", "Xhwacha", "D,s,m", MATCH_FCVT_H_LU, MASK_FCVT_H_LU, match_opcode, WR_fd|RD_xs1 },
/* Rocket Custom Coprocessor extension */
{"custom0", "Xcustom", "d,s,t,^j", MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2, match_opcode, 0},
{"custom0", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1, match_opcode, 0},
{"custom0", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD, match_opcode, 0},
{"custom0", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2, match_opcode, 0},
{"custom0", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1, match_opcode, 0},
{"custom0", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM0, MASK_CUSTOM0, match_opcode, 0},
{"custom1", "Xcustom", "d,s,t,^j", MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2, match_opcode, 0},
{"custom1", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1, match_opcode, 0},
{"custom1", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD, match_opcode, 0},
{"custom1", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2, match_opcode, 0},
{"custom1", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1, match_opcode, 0},
{"custom1", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM1, MASK_CUSTOM1, match_opcode, 0},
{"custom2", "Xcustom", "d,s,t,^j", MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2, match_opcode, 0},
{"custom2", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1, match_opcode, 0},
{"custom2", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD, match_opcode, 0},
{"custom2", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2, match_opcode, 0},
{"custom2", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1, match_opcode, 0},
{"custom2", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM2, MASK_CUSTOM2, match_opcode, 0},
{"custom3", "Xcustom", "d,s,t,^j", MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2, match_opcode, 0},
{"custom3", "Xcustom", "d,s,^t,^j", MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1, match_opcode, 0},
{"custom3", "Xcustom", "d,^s,^t,^j", MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD, match_opcode, 0},
{"custom3", "Xcustom", "^d,s,t,^j", MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2, match_opcode, 0},
{"custom3", "Xcustom", "^d,s,^t,^j", MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1, match_opcode, 0},
{"custom3", "Xcustom", "^d,^s,^t,^j", MATCH_CUSTOM3, MASK_CUSTOM3, match_opcode, 0},
/* Xhwacha extension */
{"stop", "Xhwacha", "", MATCH_STOP, MASK_STOP, match_opcode, 0},
{"utidx", "Xhwacha", "d", MATCH_UTIDX, MASK_UTIDX, match_opcode, WR_xd},
{"movz", "Xhwacha", "d,s,t", MATCH_MOVZ, MASK_MOVZ, match_opcode, WR_xd|RD_xs1|RD_xs2},
{"movn", "Xhwacha", "d,s,t", MATCH_MOVN, MASK_MOVN, match_opcode, WR_xd|RD_xs1|RD_xs2},
{"fmovz", "Xhwacha", "D,s,T", MATCH_FMOVZ, MASK_FMOVZ, match_opcode, WR_fd|RD_xs1|RD_fs2},
{"fmovn", "Xhwacha", "D,s,T", MATCH_FMOVN, MASK_FMOVN, match_opcode, WR_fd|RD_xs1|RD_fs2},
/* unit stride */
/* xloads */
{"vld", "Xhwacha", "#d,s", MATCH_VLD, MASK_VLD, match_opcode, 0},
{"vlw", "Xhwacha", "#d,s", MATCH_VLW, MASK_VLW, match_opcode, 0},
{"vlwu", "Xhwacha", "#d,s", MATCH_VLWU, MASK_VLWU, match_opcode, 0},
{"vlh", "Xhwacha", "#d,s", MATCH_VLH, MASK_VLH, match_opcode, 0},
{"vlhu", "Xhwacha", "#d,s", MATCH_VLHU, MASK_VLHU, match_opcode, 0},
{"vlb", "Xhwacha", "#d,s", MATCH_VLB, MASK_VLB, match_opcode, 0},
{"vlbu", "Xhwacha", "#d,s", MATCH_VLBU, MASK_VLBU, match_opcode, 0},
/* floads */
{"vfld", "Xhwacha", "#D,s", MATCH_VFLD, MASK_VFLD, match_opcode, 0},
{"vflw", "Xhwacha", "#D,s", MATCH_VFLW, MASK_VFLW, match_opcode, 0},
/* stride */
/* xloads */
{"vlstd", "Xhwacha", "#d,s,t", MATCH_VLSTD, MASK_VLSTD, match_opcode, 0},
{"vlstw", "Xhwacha", "#d,s,t", MATCH_VLSTW, MASK_VLSTW, match_opcode, 0},
{"vlstwu", "Xhwacha", "#d,s,t", MATCH_VLSTWU, MASK_VLSTWU, match_opcode, 0},
{"vlsth", "Xhwacha", "#d,s,t", MATCH_VLSTH, MASK_VLSTH, match_opcode, 0},
{"vlsthu", "Xhwacha", "#d,s,t", MATCH_VLSTHU, MASK_VLSTHU, match_opcode, 0},
{"vlstb", "Xhwacha", "#d,s,t", MATCH_VLSTB, MASK_VLSTB, match_opcode, 0},
{"vlstbu", "Xhwacha", "#d,s,t", MATCH_VLSTBU, MASK_VLSTBU, match_opcode, 0},
/* floads */
{"vflstd", "Xhwacha", "#D,s,t", MATCH_VFLSTD, MASK_VFLSTD, match_opcode, 0},
{"vflstw", "Xhwacha", "#D,s,t", MATCH_VFLSTW, MASK_VFLSTW, match_opcode, 0},
/* segment */
/* xloads */
{"vlsegd", "Xhwacha", "#d,s,#n", MATCH_VLSEGD, MASK_VLSEGD, match_opcode, 0},
{"vlsegw", "Xhwacha", "#d,s,#n", MATCH_VLSEGW, MASK_VLSEGW, match_opcode, 0},
{"vlsegwu", "Xhwacha", "#d,s,#n", MATCH_VLSEGWU, MASK_VLSEGWU, match_opcode, 0},
{"vlsegh", "Xhwacha", "#d,s,#n", MATCH_VLSEGH, MASK_VLSEGH, match_opcode, 0},
{"vlseghu", "Xhwacha", "#d,s,#n", MATCH_VLSEGHU, MASK_VLSEGHU, match_opcode, 0},
{"vlsegb", "Xhwacha", "#d,s,#n", MATCH_VLSEGB, MASK_VLSEGB, match_opcode, 0},
{"vlsegbu", "Xhwacha", "#d,s,#n", MATCH_VLSEGBU, MASK_VLSEGBU, match_opcode, 0},
/* floads */
{"vflsegd", "Xhwacha", "#D,s,#n", MATCH_VFLSEGD, MASK_VFLSEGD, match_opcode, 0},
{"vflsegw", "Xhwacha", "#D,s,#n", MATCH_VFLSEGW, MASK_VFLSEGW, match_opcode, 0},
/* stride segment */
/* xloads */
{"vlsegstd", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTD, MASK_VLSEGSTD, match_opcode, 0},
{"vlsegstw", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTW, MASK_VLSEGSTW, match_opcode, 0},
{"vlsegstwu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTWU, MASK_VLSEGSTWU, match_opcode, 0},
{"vlsegsth", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTH, MASK_VLSEGSTH, match_opcode, 0},
{"vlsegsthu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTHU, MASK_VLSEGSTHU, match_opcode, 0},
{"vlsegstb", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTB, MASK_VLSEGSTB, match_opcode, 0},
{"vlsegstbu", "Xhwacha", "#d,s,t,#n", MATCH_VLSEGSTBU, MASK_VLSEGSTBU, match_opcode, 0},
/* floads */
{"vflsegstd", "Xhwacha", "#D,s,t,#n", MATCH_VFLSEGSTD, MASK_VFLSEGSTD, match_opcode, 0},
{"vflsegstw", "Xhwacha", "#D,s,t,#n", MATCH_VFLSEGSTW, MASK_VFLSEGSTW, match_opcode, 0},
/* unit stride */
/* xstores */
{"vsd", "Xhwacha", "#d,s", MATCH_VSD, MASK_VSD, match_opcode, 0},
{"vsw", "Xhwacha", "#d,s", MATCH_VSW, MASK_VSW, match_opcode, 0},
{"vsh", "Xhwacha", "#d,s", MATCH_VSH, MASK_VSH, match_opcode, 0},
{"vsb", "Xhwacha", "#d,s", MATCH_VSB, MASK_VSB, match_opcode, 0},
/* fstores */
{"vfsd", "Xhwacha", "#D,s", MATCH_VFSD, MASK_VFSD, match_opcode, 0},
{"vfsw", "Xhwacha", "#D,s", MATCH_VFSW, MASK_VFSW, match_opcode, 0},
/* stride */
/* xstores */
{"vsstd", "Xhwacha", "#d,s,t", MATCH_VSSTD, MASK_VSSTD, match_opcode, 0},
{"vsstw", "Xhwacha", "#d,s,t", MATCH_VSSTW, MASK_VSSTW, match_opcode, 0},
{"vssth", "Xhwacha", "#d,s,t", MATCH_VSSTH, MASK_VSSTH, match_opcode, 0},
{"vsstb", "Xhwacha", "#d,s,t", MATCH_VSSTB, MASK_VSSTB, match_opcode, 0},
/* fstores */
{"vfsstd", "Xhwacha", "#D,s,t", MATCH_VFSSTD, MASK_VFSSTD, match_opcode, 0},
{"vfsstw", "Xhwacha", "#D,s,t", MATCH_VFSSTW, MASK_VFSSTW, match_opcode, 0},
/* segment */
/* xstores */
{"vssegd", "Xhwacha", "#d,s,#n", MATCH_VSSEGD, MASK_VSSEGD, match_opcode, 0},
{"vssegw", "Xhwacha", "#d,s,#n", MATCH_VSSEGW, MASK_VSSEGW, match_opcode, 0},
{"vssegh", "Xhwacha", "#d,s,#n", MATCH_VSSEGH, MASK_VSSEGH, match_opcode, 0},
{"vssegb", "Xhwacha", "#d,s,#n", MATCH_VSSEGB, MASK_VSSEGB, match_opcode, 0},
/* fstores */
{"vfssegd", "Xhwacha", "#D,s,#n", MATCH_VFSSEGD, MASK_VFSSEGD, match_opcode, 0},
{"vfssegw", "Xhwacha", "#D,s,#n", MATCH_VFSSEGW, MASK_VFSSEGW, match_opcode, 0},
/* stride segment */
/* xsegstores */
{"vssegstd", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTD, MASK_VSSEGSTD, match_opcode, 0},
{"vssegstw", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTW, MASK_VSSEGSTW, match_opcode, 0},
{"vssegsth", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTH, MASK_VSSEGSTH, match_opcode, 0},
{"vssegstb", "Xhwacha", "#d,s,t,#n", MATCH_VSSEGSTB, MASK_VSSEGSTB, match_opcode, 0},
/* fsegstores */
{"vfssegstd", "Xhwacha", "#D,s,t,#n", MATCH_VFSSEGSTD, MASK_VFSSEGSTD, match_opcode, 0},
{"vfssegstw", "Xhwacha", "#D,s,t,#n", MATCH_VFSSEGSTW, MASK_VFSSEGSTW, match_opcode, 0},
{"vsetcfg", "Xhwacha", "s", MATCH_VSETCFG, MASK_VSETCFG | MASK_IMM, match_opcode, 0},
{"vsetcfg", "Xhwacha", "#g,#f", MATCH_VSETCFG, MASK_VSETCFG | MASK_RS1, match_opcode, 0},
{"vsetcfg", "Xhwacha", "s,#g,#f", MATCH_VSETCFG, MASK_VSETCFG, match_opcode, 0},
{"vsetucfg", "Xhwacha", "d,u", MATCH_LUI, MASK_LUI, match_opcode, INSN_ALIAS | WR_xd},
{"vsetvl", "Xhwacha", "d,s", MATCH_VSETVL, MASK_VSETVL, match_opcode, 0},
{"vgetcfg", "Xhwacha", "d", MATCH_VGETCFG, MASK_VGETCFG, match_opcode, 0},
{"vgetvl", "Xhwacha", "d", MATCH_VGETVL, MASK_VGETVL, match_opcode, 0},
{"vmvv", "Xhwacha", "#d,#s", MATCH_VMVV, MASK_VMVV, match_opcode, 0},
{"vmsv", "Xhwacha", "#d,s", MATCH_VMSV, MASK_VMSV, match_opcode, 0},
{"vfmvv", "Xhwacha", "#D,#S", MATCH_VFMVV, MASK_VFMVV, match_opcode, 0},
{"vfmsv.d", "Xhwacha", "#D,s", MATCH_VFMSV_D, MASK_VFMSV_D, match_opcode, 0},
{"vfmsv.s", "Xhwacha", "#D,s", MATCH_VFMSV_S, MASK_VFMSV_S, match_opcode, 0},
{"vf", "Xhwacha", "q(s)", MATCH_VF, MASK_VF, match_opcode, 0},
{"vf", "Xhwacha", "A,s", 0, (int) M_VF, match_never, INSN_MACRO },
{"vxcptcause", "Xhwacha", "d", MATCH_VXCPTCAUSE, MASK_VXCPTCAUSE, match_opcode, 0},
{"vxcptaux", "Xhwacha", "d", MATCH_VXCPTAUX, MASK_VXCPTAUX, match_opcode, 0},
{"vxcptsave", "Xhwacha", "s", MATCH_VXCPTSAVE, MASK_VXCPTSAVE, match_opcode, 0},
{"vxcptrestore", "Xhwacha", "s", MATCH_VXCPTRESTORE, MASK_VXCPTRESTORE, match_opcode, 0},
{"vxcptkill", "Xhwacha", "", MATCH_VXCPTKILL, MASK_VXCPTKILL, match_opcode, 0},
{"vxcptevac", "Xhwacha", "s", MATCH_VXCPTEVAC, MASK_VXCPTEVAC, match_opcode, 0},
{"vxcpthold", "Xhwacha", "", MATCH_VXCPTHOLD, MASK_VXCPTHOLD, match_opcode, 0},
{"venqcmd", "Xhwacha", "s,t", MATCH_VENQCMD, MASK_VENQCMD, match_opcode, 0},
{"venqimm1", "Xhwacha", "s,t", MATCH_VENQIMM1, MASK_VENQIMM1, match_opcode, 0},
{"venqimm2", "Xhwacha", "s,t", MATCH_VENQIMM2, MASK_VENQIMM2, match_opcode, 0},
{"venqcnt", "Xhwacha", "s,t", MATCH_VENQCNT, MASK_VENQCNT, match_opcode, 0},
};
#define RISCV_NUM_OPCODES \
((sizeof riscv_builtin_opcodes) / (sizeof (riscv_builtin_opcodes[0])))
const int bfd_riscv_num_builtin_opcodes = RISCV_NUM_OPCODES;
/* const removed from the following to allow for dynamic extensions to the
* built-in instruction set. */
struct riscv_opcode *riscv_opcodes =
(struct riscv_opcode *) riscv_builtin_opcodes;
int bfd_riscv_num_opcodes = RISCV_NUM_OPCODES;
#undef RISCV_NUM_OPCODES

View File

@ -336,6 +336,14 @@ case $basic_machine in
basic_machine=mt-unknown
;;
riscv32-*)
basic_machine=riscv32-ucb
;;
riscv*-*)
basic_machine=riscv-ucb
;;
strongarm | thumb | xscale)
basic_machine=arm-unknown
;;

View File

@ -0,0 +1,59 @@
/* Common hooks for RISC-V.
Copyright (C) 1989-2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "common/common-target.h"
#include "common/common-target-def.h"
#include "opts.h"
#include "flags.h"
/* Implement TARGET_HANDLE_OPTION. */
static bool
riscv_handle_option (struct gcc_options *opts ATTRIBUTE_UNUSED,
struct gcc_options *opts_set ATTRIBUTE_UNUSED,
const struct cl_decoded_option *decoded ATTRIBUTE_UNUSED,
location_t loc ATTRIBUTE_UNUSED)
{
return true;
}
/* Implement TARGET_OPTION_OPTIMIZATION_TABLE. */
static const struct default_options riscv_option_optimization_table[] =
{
{ OPT_LEVELS_1_PLUS, OPT_fsection_anchors, NULL, 1 },
{ OPT_LEVELS_1_PLUS, OPT_fomit_frame_pointer, NULL, 1 },
{ OPT_LEVELS_NONE, 0, NULL, 0 }
};
#undef TARGET_OPTION_OPTIMIZATION_TABLE
#define TARGET_OPTION_OPTIMIZATION_TABLE riscv_option_optimization_table
#undef TARGET_DEFAULT_TARGET_FLAGS
#define TARGET_DEFAULT_TARGET_FLAGS \
(TARGET_DEFAULT \
| TARGET_CPU_DEFAULT \
| (TARGET_64BIT_DEFAULT ? 0 : MASK_32BIT))
#undef TARGET_HANDLE_OPTION
#define TARGET_HANDLE_OPTION riscv_handle_option
struct gcc_targetm_common targetm_common = TARGETM_COMMON_INITIALIZER;

View File

@ -446,6 +446,10 @@ powerpc*-*-*)
esac
extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
;;
riscv*-*-*)
cpu_type=riscv
need_64bit_hwint=yes
;;
rs6000*-*-*)
need_64bit_hwint=yes
extra_options="${extra_options} g.opt fused-madd.opt rs6000/rs6000-tables.opt"
@ -2328,6 +2332,31 @@ powerpcle-*-eabi*)
extra_options="${extra_options} rs6000/sysv4.opt"
use_gcc_stdint=wrap
;;
riscv*-*-linux*) # Linux RISC-V
tm_file="elfos.h gnu-user.h linux.h glibc-stdint.h ${tm_file} riscv/linux.h riscv/linux64.h"
tmake_file="${tmake_file} riscv/t-linux64"
gnu_ld=yes
gas=yes
gcc_cv_initfini_array=yes
;;
riscv*-*-elf*) # Linux RISC-V
tm_file="elfos.h newlib-stdint.h ${tm_file} riscv/elf.h"
tmake_file="${tmake_file} riscv/t-elf"
gnu_ld=yes
gas=yes
gcc_cv_initfini_array=yes
;;
riscv*-*-netbsd*) # NetBSD RISC-V
tm_file="elfos.h ${tm_file} netbsd.h netbsd-elf.h riscv/netbsd.h"
case ${target} in
riscv32*) tm_defines="${tm_defines} TARGET_64BIT_DEFAULT=0" ;;
*) tmake_file="${tmake_file} riscv/t-netbsd64" ;;
esac
extra_options="${extra_options} netbsd.opt netbsd-elf.opt"
gnu_ld=yes
gas=yes
gcc_cv_initfini_array=yes
;;
rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
tm_file="rs6000/biarch64.h ${tm_file} rs6000/aix.h rs6000/aix43.h rs6000/xcoff.h rs6000/aix-stdint.h"
tmake_file="rs6000/t-aix43 t-slibgcc"
@ -3730,6 +3759,30 @@ case "${target}" in
esac
;;
riscv*-*-*)
supported_defaults="abi arch arch_32 arch_64 float tune tune_32 tune_64"
case ${with_float} in
"" | soft | hard)
# OK
;;
*)
echo "Unknown floating point type used in --with-float=$with_float" 1>&2
exit 1
;;
esac
case ${with_abi} in
"" | 32 | 64)
# OK
;;
*)
echo "Unknown ABI used in --with-abi=$with_abi" 1>&2
exit 1
;;
esac
;;
s390*-*-*)
supported_defaults="arch mode tune"

View File

@ -0,0 +1,95 @@
;; Constraint definitions for RISC-V target.
;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
;; Based on MIPS target for GNU compiler.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; Register constraints
(define_register_constraint "f" "TARGET_HARD_FLOAT ? FP_REGS : NO_REGS"
"A floating-point register (if available).")
(define_register_constraint "b" "ALL_REGS"
"@internal")
(define_register_constraint "j" "T_REGS"
"@internal")
;; Integer constraints
(define_constraint "Z"
"@internal"
(and (match_code "const_int")
(match_test "1")))
(define_constraint "I"
"An I-type 12-bit signed immediate."
(and (match_code "const_int")
(match_test "SMALL_OPERAND (ival)")))
(define_constraint "J"
"Integer zero."
(and (match_code "const_int")
(match_test "ival == 0")))
;; Floating-point constraints
(define_constraint "G"
"Floating-point zero."
(and (match_code "const_double")
(match_test "op == CONST0_RTX (mode)")))
;; General constraints
(define_constraint "Q"
"@internal"
(match_operand 0 "const_arith_operand"))
(define_memory_constraint "YR"
"An address that is held in a general-purpose register."
(and (match_code "mem")
(match_test "GET_CODE(XEXP(op,0)) == REG")))
(define_memory_constraint "R"
"An address that can be used in a non-macro load or store."
(and (match_code "mem")
(match_test "riscv_address_insns (XEXP (op, 0), mode, false) == 1")))
(define_constraint "S"
"@internal
A constant call address."
(and (match_operand 0 "call_insn_operand")
(match_test "CONSTANT_P (op)")))
(define_constraint "T"
"@internal
A constant @code{move_operand}."
(and (match_operand 0 "move_operand")
(match_test "CONSTANT_P (op)")))
(define_memory_constraint "W"
"@internal
A memory address based on a member of @code{BASE_REG_CLASS}."
(and (match_code "mem")
(match_operand 0 "memory_operand")))
(define_constraint "YG"
"@internal
A vector zero."
(and (match_code "const_vector")
(match_test "op == CONST0_RTX (mode)")))

View File

@ -0,0 +1,42 @@
/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef __riscv64
# define SR sd
#else
# define SR sw
#endif
.section .init,"ax",@progbits
.globl _init
.type _init,@function
_init:
add sp, sp, -8
SR ra, 0(sp)
.section .fini,"ax",@progbits
.globl _fini
.type _fini,@function
_fini:
add sp, sp, -8
SR ra, 0(sp)

View File

@ -0,0 +1,38 @@
/* Copyright (C) 2001, 2002 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARraNTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifdef __riscv64
# define LR ld
#else
# define LR lw
#endif
.section .init,"ax",@progbits
LR ra, 0(sp)
addi sp, sp, 8
ret
.section .fini,"ax",@progbits
LR ra, 0(sp)
addi sp, sp, 8
ret

View File

@ -0,0 +1,121 @@
.text
.align 2
#ifndef __riscv64
/* Our RV64 64-bit routines are equivalent to our RV32 32-bit routines. */
# define __udivdi3 __udivsi3
# define __umoddi3 __umodsi3
# define __divdi3 __divsi3
# define __moddi3 __modsi3
#else
.globl __udivsi3
__udivsi3:
/* Compute __udivdi3(a0 << 32, a1 << 32); cast result to uint32_t. */
sll a0, a0, 32
sll a1, a1, 32
move t0, ra
jal __udivdi3
sext.w v0, v0
jr t0
.globl __umodsi3
__umodsi3:
/* Compute __udivdi3((uint32_t)a0, (uint32_t)a1); cast v1 to uint32_t. */
sll a0, a0, 32
sll a1, a1, 32
srl a0, a0, 32
srl a1, a1, 32
move t0, ra
jal __udivdi3
sext.w v0, v1
jr t0
.globl __modsi3
__modsi3 = __moddi3
.globl __divsi3
__divsi3:
/* Check for special case of INT_MIN/-1. Otherwise, fall into __divdi3. */
li t0, -1
beq a1, t0, .L20
#endif
.globl __divdi3
__divdi3:
bltz a0, .L10
bltz a1, .L11
/* Since the quotient is positive, fall into __udivdi3. */
.globl __udivdi3
__udivdi3:
move v1, a0
li v0, -1
beqz a1, .L5
li a0, 1
bgeu a1, v1, .L2
.L1:
blez a1, .L2
slli a1, a1, 1
slli a0, a0, 1
bgtu v1, a1, .L1
.L2:
li v0, 0
.L3:
bltu v1, a1, .L4
sub v1, v1, a1
or v0, v0, a0
.L4:
srli a0, a0, 1
srli a1, a1, 1
bnez a0, .L3
.L5:
ret
.globl __umoddi3
__umoddi3:
/* Call __udivdi3(a0, a1), then return the remainder, which is in v1. */
move t0, ra
jal __udivdi3
move v0, v1
jr t0
/* Handle negative arguments to __divdi3. */
.L10:
neg a0, a0
bgez a1, .L12 /* Compute __udivdi3(-a0, a1), then negate the result. */
neg a1, a1
j __divdi3 /* Compute __udivdi3(-a0, -a1). */
.L11: /* Compute __udivdi3(a0, -a1), then negate the result. */
neg a1, a1
.L12:
move t0, ra
jal __divdi3
neg v0, v0
jr t0
.globl __moddi3
__moddi3:
move t0, ra
bltz a1, .L31
bltz a0, .L32
.L30:
jal __udivdi3 /* The dividend is not negative. */
move v0, v1
jr t0
.L31:
neg a1, a1
bgez a0, .L30
.L32:
neg a0, a0
jal __udivdi3 /* The dividend is hella negative. */
neg v0, v1
jr t0
#ifdef __riscv64
/* continuation of __divsi3 */
.L20:
sll t0, t0, 31
bne a0, t0, __divdi3
move v0, a0
ret
#endif

View File

@ -0,0 +1,31 @@
/* Target macros for mips*-elf targets.
Copyright (C) 1994, 1997, 1999, 2000, 2002, 2003, 2004, 2007, 2010
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Leave the linker script to choose the appropriate libraries. */
#undef LIB_SPEC
#define LIB_SPEC ""
#undef STARTFILE_SPEC
#define STARTFILE_SPEC "crt0%O%s crtbegin%O%s"
#undef ENDFILE_SPEC
#define ENDFILE_SPEC "crtend%O%s"
#define NO_IMPLICIT_EXTERN_C 1

View File

@ -0,0 +1,98 @@
;; Generic DFA-based pipeline description for RISC-V targets.
;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
;; Based on MIPS target for GNU compiler.
;; This file is part of GCC.
;; GCC is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published
;; by the Free Software Foundation; either version 3, or (at your
;; option) any later version.
;; GCC is distributed in the hope that it will be useful, but WITHOUT
;; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
;; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
;; License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
;; This file is derived from the old define_function_unit description.
;; Each reservation can be overridden on a processor-by-processor basis.
(define_insn_reservation "generic_alu" 1
(eq_attr "type" "unknown,const,arith,shift,slt,multi,nop,logical,move")
"alu")
(define_insn_reservation "generic_load" 3
(eq_attr "type" "load,fpload,fpidxload")
"alu")
(define_insn_reservation "generic_store" 1
(eq_attr "type" "store,fpstore,fpidxstore")
"alu")
(define_insn_reservation "generic_xfer" 2
(eq_attr "type" "mfc,mtc")
"alu")
(define_insn_reservation "generic_branch" 1
(eq_attr "type" "branch,jump,call")
"alu")
(define_insn_reservation "generic_imul" 17
(eq_attr "type" "imul")
"imuldiv*17")
(define_insn_reservation "generic_idiv" 38
(eq_attr "type" "idiv")
"imuldiv*38")
(define_insn_reservation "generic_fcvt" 1
(eq_attr "type" "fcvt")
"alu")
(define_insn_reservation "generic_fmove" 2
(eq_attr "type" "fmove")
"alu")
(define_insn_reservation "generic_fcmp" 3
(eq_attr "type" "fcmp")
"alu")
(define_insn_reservation "generic_fadd" 4
(eq_attr "type" "fadd")
"alu")
(define_insn_reservation "generic_fmul_single" 7
(and (eq_attr "type" "fmul,fmadd")
(eq_attr "mode" "SF"))
"alu")
(define_insn_reservation "generic_fmul_double" 8
(and (eq_attr "type" "fmul,fmadd")
(eq_attr "mode" "DF"))
"alu")
(define_insn_reservation "generic_fdiv_single" 23
(and (eq_attr "type" "fdiv")
(eq_attr "mode" "SF"))
"alu")
(define_insn_reservation "generic_fdiv_double" 36
(and (eq_attr "type" "fdiv")
(eq_attr "mode" "DF"))
"alu")
(define_insn_reservation "generic_fsqrt_single" 54
(and (eq_attr "type" "fsqrt")
(eq_attr "mode" "SF"))
"alu")
(define_insn_reservation "generic_fsqrt_double" 112
(and (eq_attr "type" "fsqrt")
(eq_attr "mode" "DF"))
"alu")

View File

@ -0,0 +1,50 @@
/* DWARF2 EH unwinding support for RISC-V Linux.
Copyright (C) 2014 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#ifndef inhibit_libc
/* Examine the code and attempt to identify a signal frame. */
#include <stdlib.h>
#include <asm-generic/unistd.h>
#define MD_FALLBACK_FRAME_STATE_FOR riscv_fallback_frame_state
static _Unwind_Reason_Code
riscv_fallback_frame_state (struct _Unwind_Context *context,
_Unwind_FrameState *fs)
{
unsigned int *pc = (unsigned int *) context->ra;
/* Signal frames begin with the following code sequence:
li v0, __NR_rt_sigreturn
scall */
if (((unsigned long)pc & 0x3) != 0
|| pc[0] != RISCV_ITYPE (ADDI, GP_RETURN, 0, __NR_rt_sigreturn)
|| pc[1] != RISCV_ITYPE (SCALL, 0, 0, 0))
return _URC_END_OF_STACK;
/* TODO: Actually implement this. */
abort();
}
#endif

View File

@ -0,0 +1,60 @@
/* Definitions for MIPS running Linux-based GNU systems with ELF format.
Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
2007, 2008, 2010, 2011 Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#undef WCHAR_TYPE
#define WCHAR_TYPE "int"
#undef WCHAR_TYPE_SIZE
#define WCHAR_TYPE_SIZE 32
#define TARGET_OS_CPP_BUILTINS() \
do { \
GNU_USER_TARGET_OS_CPP_BUILTINS(); \
/* The GNU C++ standard library requires this. */ \
if (c_dialect_cxx ()) \
builtin_define ("_GNU_SOURCE"); \
} while (0)
#undef SUBTARGET_CPP_SPEC
#define SUBTARGET_CPP_SPEC "%{posix:-D_POSIX_SOURCE} %{pthread:-D_REENTRANT}"
#define GLIBC_DYNAMIC_LINKER "/lib/ld.so.1"
/* Borrowed from sparc/linux.h */
#undef LINK_SPEC
#define LINK_SPEC \
"%{shared:-shared} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
-dynamic-linker " GNU_USER_DYNAMIC_LINKER "} \
%{static:-static}}"
#undef LIB_SPEC
#define LIB_SPEC "\
%{pthread:-lpthread} \
%{shared:-lc} \
%{!shared: \
%{profile:-lc_p} %{!profile:-lc}}"
/* Similar to standard Linux, but adding -ffast-math support. */
#undef ENDFILE_SPEC
#define ENDFILE_SPEC \
"%{shared|pie:crtendS.o%s;:crtend.o%s} crtn.o%s"

View File

@ -0,0 +1,44 @@
/* Definitions for MIPS running Linux-based GNU systems with ELF format
using n32/64 abi.
Copyright 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
Free Software Foundation, Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Force the default ABI flags onto the command line
in order to make the other specs easier to write. */
#undef LIB_SPEC
#define LIB_SPEC "\
%{pthread:-lpthread} \
%{shared:-lc} \
%{!shared: \
%{profile:-lc_p} %{!profile:-lc}}"
#define GLIBC_DYNAMIC_LINKER32 "/lib32/ld.so.1"
#define GLIBC_DYNAMIC_LINKER64 "/lib/ld.so.1"
#undef LINK_SPEC
#define LINK_SPEC "\
%{shared} \
%{!shared: \
%{!static: \
%{rdynamic:-export-dynamic} \
%{" OPT_ARCH64 ": -dynamic-linker " GNU_USER_DYNAMIC_LINKER64 "} \
%{" OPT_ARCH32 ": -dynamic-linker " GNU_USER_DYNAMIC_LINKER32 "}} \
%{static:-static}} \
%{" OPT_ARCH64 ":-melf64lriscv} \
%{" OPT_ARCH32 ":-melf32lriscv}"

View File

@ -0,0 +1,111 @@
/* Definitions for RISCV running NetBSD systems using ELF
Copyright (C) 2014
Free Software Foundation, Inc.
Contributed by Matt Thomas <matt@netbsd.org>
This file is part of GNU CC.
GNU CC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2, or (at your option)
any later version.
GNU CC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; see the file COPYING. If not, write to
the Free Software Foundation, 59 Temple Place - Suite 330,
Boston, MA 02111-1307, USA. */
#undef TARGET_USE_GP
#define TARGET_USE_GP 0
#undef DRIVER_SELF_SPECS
#define DRIVER_SELF_SPECS ""
#undef TARGET_DEFAULT
#define TARGET_DEFAULT MASK_FDIV
#define TARGET_OS_CPP_BUILTINS() \
do { \
NETBSD_OS_CPP_BUILTINS_ELF(); \
/* The GNU C++ standard library requires this. */ \
if (c_dialect_cxx ()) \
builtin_define ("_GNU_SOURCE"); \
if (!TARGET_HARD_FLOAT_ABI) \
builtin_define ("_SOFT_FLOAT"); \
} while (0)
#undef CPP_SPEC
#define CPP_SPEC NETBSD_CPP_SPEC
#undef LIB_SPEC
#define LIB_SPEC NETBSD_LIB_SPEC
#undef LINK_SPEC
#define LINK_SPEC NETBSD_LINK_SPEC_ELF
/* Provide a LINK_SPEC appropriate for a NetBSD/mips target.
This is a copy of LINK_SPEC from <netbsd-elf.h> tweaked for
the MIPS target. */
#undef LINK_SPEC
#define LINK_SPEC \
"%{m64:-m elf64lriscv} \
%{m32:-m elf32lriscv} \
%(netbsd_link_spec)"
#undef NETBSD_ENTRY_POINT
#define NETBSD_ENTRY_POINT "_start"
#undef SUBTARGET_EXTRA_SPECS
#define SUBTARGET_EXTRA_SPECS \
{ "netbsd_link_spec", NETBSD_LINK_SPEC_ELF }, \
{ "netbsd_entry_point", NETBSD_ENTRY_POINT }, \
{ "netbsd_endfile_spec", NETBSD_ENDFILE_SPEC },
#define SIG_ATOMIC_TYPE "int"
#define INT8_TYPE "signed char"
#define INT16_TYPE "short int"
#define INT32_TYPE "int"
#define INT64_TYPE "long long int"
#define UINT8_TYPE "unsigned char"
#define UINT16_TYPE "short unsigned int"
#define UINT32_TYPE "unsigned int"
#define UINT64_TYPE "long long unsigned int"
#define INT_LEAST8_TYPE "signed char"
#define INT_LEAST16_TYPE "short int"
#define INT_LEAST32_TYPE "int"
#define INT_LEAST64_TYPE "long long int"
#define UINT_LEAST8_TYPE "unsigned char"
#define UINT_LEAST16_TYPE "short unsigned int"
#define UINT_LEAST32_TYPE "unsigned int"
#define UINT_LEAST64_TYPE "long long unsigned int"
#define INT_FAST8_TYPE "signed char"
#define INT_FAST16_TYPE "short int"
#define INT_FAST32_TYPE "int"
#define INT_FAST64_TYPE "long long int"
#define UINT_FAST8_TYPE "unsigned char"
#define UINT_FAST16_TYPE "short unsigned int"
#define UINT_FAST32_TYPE "unsigned int"
#define UINT_FAST64_TYPE "long long unsigned int"
#undef PTRDIFF_TYPE
#define PTRDIFF_TYPE "long int"
#undef SIZE_TYPE
#define SIZE_TYPE "long unsigned int"
#define INTPTR_TYPE PTRDIFF_TYPE
#define UINTPTR_TYPE SIZE_TYPE
#undef INTMAX_TYPE
#define INTMAX_TYPE "long long int"
#undef UINTMAX_TYPE
#define UINTMAX_TYPE "long long unsigned int"

View File

@ -0,0 +1,150 @@
/* RISC-V ISA encoding.
Copyright (C) 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target for GNU compiler.
This file is part of GDB, GAS, and the GNU binutils.
GDB, GAS, and the GNU binutils are free software; you can redistribute
them and/or modify them under the terms of the GNU General Public
License as published by the Free Software Foundation; either version
1, or (at your option) any later version.
GDB, GAS, and the GNU binutils are distributed in the hope that they
will be useful, but WITHOUT ANY WARRANTY; without even the implied
warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this file; see the file COPYING. If not, write to the Free
Software Foundation, 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */
#ifndef _RISCV_H_
#define _RISCV_H_
#define RV_X(x, s, n) (((x) >> (s)) & ((1<<(n))-1))
#define RV_IMM_SIGN(x) (-(((x) >> 31) & 1))
#define EXTRACT_ITYPE_IMM(x) \
(RV_X(x, 20, 12) | (RV_IMM_SIGN(x) << 12))
#define EXTRACT_STYPE_IMM(x) \
(RV_X(x, 7, 5) | (RV_X(x, 25, 7) << 5) | (RV_IMM_SIGN(x) << 12))
#define EXTRACT_SBTYPE_IMM(x) \
((RV_X(x, 8, 4) << 1) | (RV_X(x, 25, 6) << 5) | (RV_X(x, 7, 1) << 11) | (RV_IMM_SIGN(x) << 12))
#define EXTRACT_UTYPE_IMM(x) \
(RV_X(x, 12, 20) | (RV_IMM_SIGN(x) << 20))
#define EXTRACT_UJTYPE_IMM(x) \
((RV_X(x, 21, 10) << 1) | (RV_X(x, 20, 1) << 11) | (RV_X(x, 12, 8) << 12) | (RV_IMM_SIGN(x) << 20))
#define ENCODE_ITYPE_IMM(x) \
(RV_X(x, 0, 12) << 20)
#define ENCODE_STYPE_IMM(x) \
((RV_X(x, 0, 5) << 7) | (RV_X(x, 5, 7) << 25))
#define ENCODE_SBTYPE_IMM(x) \
((RV_X(x, 1, 4) << 8) | (RV_X(x, 5, 6) << 25) | (RV_X(x, 11, 1) << 7) | (RV_X(x, 12, 1) << 31))
#define ENCODE_UTYPE_IMM(x) \
(RV_X(x, 0, 20) << 12)
#define ENCODE_UJTYPE_IMM(x) \
((RV_X(x, 1, 10) << 21) | (RV_X(x, 11, 1) << 20) | (RV_X(x, 12, 8) << 12) | (RV_X(x, 20, 1) << 31))
#define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x))
#define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x))
#define VALID_SBTYPE_IMM(x) (EXTRACT_SBTYPE_IMM(ENCODE_SBTYPE_IMM(x)) == (x))
#define VALID_UTYPE_IMM(x) (EXTRACT_UTYPE_IMM(ENCODE_UTYPE_IMM(x)) == (x))
#define VALID_UJTYPE_IMM(x) (EXTRACT_UJTYPE_IMM(ENCODE_UJTYPE_IMM(x)) == (x))
#define RISCV_RTYPE(insn, rd, rs1, rs2) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2))
#define RISCV_ITYPE(insn, rd, rs1, imm) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ((rs1) << OP_SH_RS1) | ENCODE_ITYPE_IMM(imm))
#define RISCV_STYPE(insn, rs1, rs2, imm) \
((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_STYPE_IMM(imm))
#define RISCV_SBTYPE(insn, rs1, rs2, target) \
((MATCH_ ## insn) | ((rs1) << OP_SH_RS1) | ((rs2) << OP_SH_RS2) | ENCODE_SBTYPE_IMM(target))
#define RISCV_UTYPE(insn, rd, bigimm) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UTYPE_IMM(bigimm))
#define RISCV_UJTYPE(insn, rd, target) \
((MATCH_ ## insn) | ((rd) << OP_SH_RD) | ENCODE_UJTYPE_IMM(target))
#define RISCV_NOP RISCV_ITYPE(ADDI, 0, 0, 0)
#define RISCV_CONST_HIGH_PART(VALUE) \
(((VALUE) + (RISCV_IMM_REACH/2)) & ~(RISCV_IMM_REACH-1))
#define RISCV_CONST_LOW_PART(VALUE) ((VALUE) - RISCV_CONST_HIGH_PART (VALUE))
#define RISCV_LUI_HIGH_PART(VALUE) (RISCV_CONST_HIGH_PART(VALUE) >> RISCV_IMM_BITS)
/* RV fields */
#define OP_MASK_OP 0x7f
#define OP_SH_OP 0
#define OP_MASK_RS2 0x1f
#define OP_SH_RS2 20
#define OP_MASK_RS1 0x1f
#define OP_SH_RS1 15
#define OP_MASK_RS3 0x1f
#define OP_SH_RS3 27
#define OP_MASK_RD 0x1f
#define OP_SH_RD 7
#define OP_MASK_SHAMT 0x3f
#define OP_SH_SHAMT 20
#define OP_MASK_SHAMTW 0x1f
#define OP_SH_SHAMTW 20
#define OP_MASK_RM 0x7
#define OP_SH_RM 12
#define OP_MASK_PRED 0xf
#define OP_SH_PRED 24
#define OP_MASK_SUCC 0xf
#define OP_SH_SUCC 20
#define OP_MASK_AQ 0x1
#define OP_SH_AQ 26
#define OP_MASK_RL 0x1
#define OP_SH_RL 25
#define OP_MASK_VRD 0x1f
#define OP_SH_VRD 7
#define OP_MASK_VRS 0x1f
#define OP_SH_VRS 15
#define OP_MASK_VRT 0x1f
#define OP_SH_VRT 20
#define OP_MASK_VRR 0x1f
#define OP_SH_VRR 25
#define OP_MASK_VFD 0x1f
#define OP_SH_VFD 7
#define OP_MASK_VFS 0x1f
#define OP_SH_VFS 15
#define OP_MASK_VFT 0x1f
#define OP_SH_VFT 20
#define OP_MASK_VFR 0x1f
#define OP_SH_VFR 25
#define OP_MASK_IMMNGPR 0x3f
#define OP_SH_IMMNGPR 20
#define OP_MASK_IMMNFPR 0x3f
#define OP_SH_IMMNFPR 26
#define OP_MASK_IMMSEGNELM 0x1f
#define OP_SH_IMMSEGNELM 17
#define OP_MASK_IMMSEGSTNELM 0x1f
#define OP_SH_IMMSEGSTNELM 12
#define OP_MASK_CUSTOM_IMM 0x7f
#define OP_SH_CUSTOM_IMM 25
#define LINK_REG 1
#define RISCV_JUMP_BITS RISCV_BIGIMM_BITS
#define RISCV_JUMP_ALIGN_BITS 1
#define RISCV_JUMP_ALIGN (1 << RISCV_JUMP_ALIGN_BITS)
#define RISCV_JUMP_REACH ((1ULL<<RISCV_JUMP_BITS)*RISCV_JUMP_ALIGN)
#define RISCV_IMM_BITS 12
#define RISCV_BIGIMM_BITS (32-RISCV_IMM_BITS)
#define RISCV_IMM_REACH (1LL<<RISCV_IMM_BITS)
#define RISCV_BIGIMM_REACH (1LL<<RISCV_BIGIMM_BITS)
#define RISCV_BRANCH_BITS RISCV_IMM_BITS
#define RISCV_BRANCH_ALIGN_BITS RISCV_JUMP_ALIGN_BITS
#define RISCV_BRANCH_ALIGN (1 << RISCV_BRANCH_ALIGN_BITS)
#define RISCV_BRANCH_REACH (RISCV_IMM_REACH*RISCV_BRANCH_ALIGN)
#include "riscv-opc.h"
#endif /* _RISCV_H_ */

View File

@ -0,0 +1,122 @@
;;........................
;; DI -> SI optimizations
;;........................
;; Simplify (int)(a + 1), etc.
(define_peephole2
[(set (match_operand:DI 0 "register_operand")
(match_operator:DI 4 "modular_operator"
[(match_operand:DI 1 "register_operand")
(match_operand:DI 2 "arith_operand")]))
(set (match_operand:SI 3 "register_operand")
(truncate:SI (match_dup 0)))]
"TARGET_64BIT && (REGNO (operands[0]) == REGNO (operands[3]) || peep2_reg_dead_p (2, operands[0]))"
[(set (match_dup 3)
(truncate:SI
(match_op_dup:DI 4
[(match_operand:DI 1 "register_operand")
(match_operand:DI 2 "arith_operand")])))])
;; Simplify (int)a + 1, etc.
(define_peephole2
[(set (match_operand:SI 0 "register_operand")
(truncate:SI (match_operand:DI 1 "register_operand")))
(set (match_operand:SI 3 "register_operand")
(match_operator:SI 4 "modular_operator"
[(match_dup 0)
(match_operand:SI 2 "arith_operand")]))]
"TARGET_64BIT && (REGNO (operands[0]) == REGNO (operands[3]) || peep2_reg_dead_p (2, operands[0]))"
[(set (match_dup 3)
(match_op_dup:SI 4 [(match_dup 1) (match_dup 2)]))])
;; Simplify -(int)a, etc.
(define_peephole2
[(set (match_operand:SI 0 "register_operand")
(truncate:SI (match_operand:DI 2 "register_operand")))
(set (match_operand:SI 3 "register_operand")
(match_operator:SI 4 "modular_operator"
[(match_operand:SI 1 "reg_or_0_operand")
(match_dup 0)]))]
"TARGET_64BIT && (REGNO (operands[0]) == REGNO (operands[3]) || peep2_reg_dead_p (2, operands[0]))"
[(set (match_dup 3)
(match_op_dup:SI 4 [(match_dup 1) (match_dup 2)]))])
;; Simplify PIC loads to static variables.
(define_peephole2
[(set (match_operand:P 0 "register_operand")
(match_operand:P 1 "absolute_symbolic_operand"))
(set (match_operand:ANYI 2 "register_operand")
(mem:ANYI (match_dup 0)))]
"(flag_pic && SYMBOL_REF_LOCAL_P (operands[1])) && (REGNO (operands[0]) == REGNO (operands[2]) || peep2_reg_dead_p (2, operands[0]))"
[(set (match_dup 2) (mem:ANYI (match_dup 1)))])
(define_peephole2
[(set (match_operand:P 0 "register_operand")
(match_operand:P 1 "absolute_symbolic_operand"))
(set (match_operand:ANYF 2 "register_operand")
(mem:ANYF (match_dup 0)))]
"(flag_pic && SYMBOL_REF_LOCAL_P (operands[1])) && peep2_reg_dead_p (2, operands[0])"
[(set (match_dup 2) (mem:ANYF (match_dup 1)))
(clobber (match_dup 0))])
(define_peephole2
[(set (match_operand:DI 0 "register_operand")
(match_operand:DI 1 "absolute_symbolic_operand"))
(set (mem:ANYIF (match_dup 0))
(match_operand:ANYIF 2 "reg_or_0_operand"))]
"TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[1])) && peep2_reg_dead_p (2, operands[0])"
[(set (mem:ANYIF (match_dup 1)) (match_dup 2))
(clobber (match_dup 0))])
(define_peephole2
[(set (match_operand:SI 0 "register_operand")
(match_operand:SI 1 "absolute_symbolic_operand"))
(set (mem:ANYIF (match_dup 0))
(match_operand:ANYIF 2 "register_operand"))]
"!TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[1])) && peep2_reg_dead_p (2, operands[0])"
[(set (mem:ANYIF (match_dup 1)) (match_dup 2))
(clobber (match_dup 0))])
(define_insn "*local_pic_load<mode>"
[(set (match_operand:ANYI 0 "register_operand" "=r")
(mem:ANYI (match_operand 1 "absolute_symbolic_operand" "")))]
"flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
"<load>\t%0,%1"
[(set (attr "length") (const_int 8))])
(define_insn "*local_pic_load<mode>"
[(set (match_operand:ANYF 0 "register_operand" "=f")
(mem:ANYF (match_operand 1 "absolute_symbolic_operand" "")))
(clobber (match_scratch:DI 2 "=&r"))]
"flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
"<load>\t%0,%1,%2"
[(set (attr "length") (const_int 8))])
(define_insn "*local_pic_loadu<mode>"
[(set (match_operand:SUPERQI 0 "register_operand" "=r")
(zero_extend:SUPERQI (mem:SUBDI (match_operand 1 "absolute_symbolic_operand" ""))))]
"flag_pic && SYMBOL_REF_LOCAL_P (operands[1])"
"<load>u\t%0,%1"
[(set (attr "length") (const_int 8))])
(define_insn "*local_pic_storedi<mode>"
[(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
(match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
(clobber (match_scratch:DI 2 "=&r"))]
"TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
"<store>\t%z1,%0,%2"
[(set (attr "length") (const_int 8))])
(define_insn "*local_pic_storesi<mode>"
[(set (mem:ANYI (match_operand 0 "absolute_symbolic_operand" ""))
(match_operand:ANYI 1 "reg_or_0_operand" "rJ"))
(clobber (match_scratch:SI 2 "=&r"))]
"!TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
"<store>\t%z1,%0,%2"
[(set (attr "length") (const_int 8))])
(define_insn "*local_pic_storedi<mode>"
[(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
(match_operand:ANYF 1 "register_operand" "f"))
(clobber (match_scratch:DI 2 "=&r"))]
"TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
"<store>\t%1,%0,%2"
[(set (attr "length") (const_int 8))])
(define_insn "*local_pic_storesi<mode>"
[(set (mem:ANYF (match_operand 0 "absolute_symbolic_operand" ""))
(match_operand:ANYF 1 "register_operand" "f"))
(clobber (match_scratch:SI 2 "=&r"))]
"!TARGET_64BIT && (flag_pic && SYMBOL_REF_LOCAL_P (operands[0]))"
"<store>\t%1,%0,%2"
[(set (attr "length") (const_int 8))])

View File

@ -0,0 +1,182 @@
;; Predicate description for RISC-V target.
;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
;; Based on MIPS target for GNU compiler.
;;
;; This file is part of GCC.
;;
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;;
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;;
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_predicate "const_arith_operand"
(and (match_code "const_int")
(match_test "SMALL_OPERAND (INTVAL (op))")))
(define_predicate "arith_operand"
(ior (match_operand 0 "const_arith_operand")
(match_operand 0 "register_operand")))
(define_predicate "sle_operand"
(and (match_code "const_int")
(match_test "SMALL_OPERAND (INTVAL (op) + 1)")))
(define_predicate "sleu_operand"
(and (match_operand 0 "sle_operand")
(match_test "INTVAL (op) + 1 != 0")))
(define_predicate "const_0_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST0_RTX (GET_MODE (op))")))
(define_predicate "reg_or_0_operand"
(ior (match_operand 0 "const_0_operand")
(match_operand 0 "register_operand")))
(define_predicate "const_1_operand"
(and (match_code "const_int,const_double,const_vector")
(match_test "op == CONST1_RTX (GET_MODE (op))")))
(define_predicate "reg_or_1_operand"
(ior (match_operand 0 "const_1_operand")
(match_operand 0 "register_operand")))
;; This is used for indexing into vectors, and hence only accepts const_int.
(define_predicate "const_0_or_1_operand"
(and (match_code "const_int")
(ior (match_test "op == CONST0_RTX (GET_MODE (op))")
(match_test "op == CONST1_RTX (GET_MODE (op))"))))
(define_special_predicate "pc_or_label_operand"
(match_code "pc,label_ref"))
;; A legitimate CONST_INT operand that takes more than one instruction
;; to load.
(define_predicate "splittable_const_int_operand"
(match_code "const_int")
{
/* Don't handle multi-word moves this way; we don't want to introduce
the individual word-mode moves until after reload. */
if (GET_MODE_SIZE (mode) > UNITS_PER_WORD)
return false;
/* Otherwise check whether the constant can be loaded in a single
instruction. */
return !LUI_INT (op) && !SMALL_INT (op);
})
(define_predicate "move_operand"
(match_operand 0 "general_operand")
{
enum riscv_symbol_type symbol_type;
/* The thinking here is as follows:
(1) The move expanders should split complex load sequences into
individual instructions. Those individual instructions can
then be optimized by all rtl passes.
(2) The target of pre-reload load sequences should not be used
to store temporary results. If the target register is only
assigned one value, reload can rematerialize that value
on demand, rather than spill it to the stack.
(3) If we allowed pre-reload passes like combine and cse to recreate
complex load sequences, we would want to be able to split the
sequences before reload as well, so that the pre-reload scheduler
can see the individual instructions. This falls foul of (2);
the splitter would be forced to reuse the target register for
intermediate results.
(4) We want to define complex load splitters for combine. These
splitters can request a temporary scratch register, which avoids
the problem in (2). They allow things like:
(set (reg T1) (high SYM))
(set (reg T2) (low (reg T1) SYM))
(set (reg X) (plus (reg T2) (const_int OFFSET)))
to be combined into:
(set (reg T3) (high SYM+OFFSET))
(set (reg X) (lo_sum (reg T3) SYM+OFFSET))
if T2 is only used this once. */
switch (GET_CODE (op))
{
case CONST_INT:
return !splittable_const_int_operand (op, mode);
case CONST:
case SYMBOL_REF:
case LABEL_REF:
return (riscv_symbolic_constant_p (op, &symbol_type)
&& !riscv_hi_relocs[symbol_type]);
case HIGH:
op = XEXP (op, 0);
return riscv_symbolic_constant_p (op, &symbol_type);
default:
return true;
}
})
(define_predicate "consttable_operand"
(match_test "CONSTANT_P (op)"))
(define_predicate "symbolic_operand"
(match_code "const,symbol_ref,label_ref")
{
enum riscv_symbol_type type;
return riscv_symbolic_constant_p (op, &type);
})
(define_predicate "absolute_symbolic_operand"
(match_code "const,symbol_ref,label_ref")
{
enum riscv_symbol_type type;
return (riscv_symbolic_constant_p (op, &type)
&& type == SYMBOL_ABSOLUTE);
})
(define_predicate "plt_symbolic_operand"
(match_code "const,symbol_ref,label_ref")
{
enum riscv_symbol_type type;
return (riscv_symbolic_constant_p (op, &type)
&& type == SYMBOL_GOT_DISP && !SYMBOL_REF_WEAK (op) && TARGET_PLT);
})
(define_predicate "call_insn_operand"
(ior (match_operand 0 "absolute_symbolic_operand")
(match_operand 0 "plt_symbolic_operand")
(match_operand 0 "register_operand")))
(define_predicate "symbol_ref_operand"
(match_code "symbol_ref"))
(define_predicate "modular_operator"
(match_code "plus,minus,mult,ashift"))
(define_predicate "equality_operator"
(match_code "eq,ne"))
(define_predicate "order_operator"
(match_code "eq,ne,lt,ltu,le,leu,ge,geu,gt,gtu"))
(define_predicate "fp_order_operator"
(match_code "eq,lt,le,gt,ge"))
(define_predicate "fp_unorder_operator"
(match_code "ordered,unordered"))

View File

@ -0,0 +1,178 @@
/* Functions needed for soft-float on riscv-linux. Based on
rs6000/ppc64-fp.c with TF types removed.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation,
Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if defined(__riscv64)
#include "config/fp-bit.h"
extern DItype __fixdfdi (DFtype);
extern DItype __fixsfdi (SFtype);
extern USItype __fixunsdfsi (DFtype);
extern USItype __fixunssfsi (SFtype);
extern DFtype __floatdidf (DItype);
extern DFtype __floatundidf (UDItype);
extern SFtype __floatdisf (DItype);
extern SFtype __floatundisf (UDItype);
static DItype local_fixunssfdi (SFtype);
static DItype local_fixunsdfdi (DFtype);
DItype
__fixdfdi (DFtype a)
{
if (a < 0)
return - local_fixunsdfdi (-a);
return local_fixunsdfdi (a);
}
DItype
__fixsfdi (SFtype a)
{
if (a < 0)
return - local_fixunssfdi (-a);
return local_fixunssfdi (a);
}
USItype
__fixunsdfsi (DFtype a)
{
if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
return (SItype) a;
}
USItype
__fixunssfsi (SFtype a)
{
if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
return (SItype) a;
}
DFtype
__floatdidf (DItype u)
{
DFtype d;
d = (SItype) (u >> (sizeof (SItype) * 8));
d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
}
DFtype
__floatundidf (UDItype u)
{
DFtype d;
d = (USItype) (u >> (sizeof (SItype) * 8));
d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
}
SFtype
__floatdisf (DItype u)
{
DFtype f;
if (53 < (sizeof (DItype) * 8)
&& 53 > ((sizeof (DItype) * 8) - 53 + 24))
{
if (! (- ((DItype) 1 << 53) < u
&& u < ((DItype) 1 << 53)))
{
if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
{
u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
}
}
}
f = (SItype) (u >> (sizeof (SItype) * 8));
f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
SFtype
__floatundisf (UDItype u)
{
DFtype f;
if (53 < (sizeof (DItype) * 8)
&& 53 > ((sizeof (DItype) * 8) - 53 + 24))
{
if (u >= ((UDItype) 1 << 53))
{
if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
{
u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
}
}
}
f = (USItype) (u >> (sizeof (SItype) * 8));
f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
/* This version is needed to prevent recursion; fixunsdfdi in libgcc
calls fixdfdi, which in turn calls calls fixunsdfdi. */
static DItype
local_fixunsdfdi (DFtype a)
{
USItype hi, lo;
hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
}
/* This version is needed to prevent recursion; fixunssfdi in libgcc
calls fixsfdi, which in turn calls calls fixunssfdi. */
static DItype
local_fixunssfdi (SFtype original_a)
{
DFtype a = original_a;
USItype hi, lo;
hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
}
#endif

View File

@ -0,0 +1,39 @@
/* Definitions of prototypes for RISC-V built-in functions.
Copyright (C) 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target for GNU compiler.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
/* Invoke DEF_RISCV_FTYPE (NARGS, LIST) for each prototype used by
MIPS built-in functions, where:
NARGS is the number of arguments.
LIST contains the return-type code followed by the codes for each
argument type.
Argument- and return-type codes are either modes or one of the following:
VOID for void_type_node
INT for integer_type_node
POINTER for ptr_type_node
(we don't use PTR because that's a ANSI-compatibillity macro).
Please keep this list lexicographically sorted by the LIST argument. */
DEF_RISCV_FTYPE (1, (VOID, VOID))

View File

@ -0,0 +1,26 @@
/* Extra machine modes for RISC-V target.
Copyright (C) 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target for GNU compiler.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
FLOAT_MODE (TF, 16, ieee_quad_format);
/* Vector modes. */
VECTOR_MODES (INT, 4); /* V8QI V4HI V2SI */
VECTOR_MODES (FLOAT, 4); /* V4HF V2SF */

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,90 @@
/* Definition of RISC-V target for GNU compiler.
Copyright (C) 2011-2014 Free Software Foundation, Inc.
Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
Based on MIPS target for GNU compiler.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 3, or (at your option)
any later version.
GCC is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3. If not see
<http://www.gnu.org/licenses/>. */
#ifndef GCC_RISCV_PROTOS_H
#define GCC_RISCV_PROTOS_H
enum riscv_symbol_type {
SYMBOL_ABSOLUTE,
SYMBOL_GOT_DISP,
SYMBOL_TLS,
SYMBOL_TLS_LE,
SYMBOL_TLS_IE
};
#define NUM_SYMBOL_TYPES (SYMBOL_TLS_IE + 1)
extern bool riscv_symbolic_constant_p (rtx, enum riscv_symbol_type *);
extern int riscv_regno_mode_ok_for_base_p (int, enum machine_mode, bool);
extern int riscv_address_insns (rtx, enum machine_mode, bool);
extern int riscv_const_insns (rtx);
extern int riscv_split_const_insns (rtx);
extern int riscv_load_store_insns (rtx, rtx);
extern rtx riscv_emit_move (rtx, rtx);
extern bool riscv_split_symbol (rtx, rtx, enum machine_mode, rtx *);
extern rtx riscv_unspec_address (rtx, enum riscv_symbol_type);
extern void riscv_move_integer (rtx, rtx, HOST_WIDE_INT);
extern bool riscv_legitimize_move (enum machine_mode, rtx, rtx);
extern bool riscv_legitimize_vector_move (enum machine_mode, rtx, rtx);
extern rtx riscv_subword (rtx, bool);
extern bool riscv_split_64bit_move_p (rtx, rtx);
extern void riscv_split_doubleword_move (rtx, rtx);
extern const char *riscv_output_move (rtx, rtx);
extern const char *riscv_riscv_output_vector_move (enum machine_mode, rtx, rtx);
#ifdef RTX_CODE
extern void riscv_expand_scc (rtx *);
extern void riscv_expand_conditional_branch (rtx *);
#endif
extern rtx riscv_expand_call (bool, rtx, rtx, rtx);
extern void riscv_expand_fcc_reload (rtx, rtx, rtx);
extern void riscv_set_return_address (rtx, rtx);
extern bool riscv_expand_block_move (rtx, rtx, rtx);
extern void riscv_expand_synci_loop (rtx, rtx);
extern bool riscv_expand_ext_as_unaligned_load (rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT);
extern bool riscv_expand_ins_as_unaligned_store (rtx, rtx, HOST_WIDE_INT,
HOST_WIDE_INT);
extern void riscv_order_regs_for_local_alloc (void);
extern rtx riscv_return_addr (int, rtx);
extern HOST_WIDE_INT riscv_initial_elimination_offset (int, int);
extern void riscv_expand_prologue (void);
extern void riscv_expand_epilogue (bool);
extern bool riscv_can_use_return_insn (void);
extern rtx riscv_function_value (const_tree, const_tree, enum machine_mode);
extern enum reg_class riscv_secondary_reload_class (enum reg_class,
enum machine_mode,
rtx, bool);
extern int riscv_class_max_nregs (enum reg_class, enum machine_mode);
extern unsigned int riscv_hard_regno_nregs (int, enum machine_mode);
extern void irix_asm_output_align (FILE *, unsigned);
extern const char *current_section_name (void);
extern unsigned int current_section_flags (void);
extern void riscv_expand_vector_init (rtx, rtx);
extern bool riscv_size_ok_for_small_data_p (int size);
#endif /* ! GCC_RISCV_PROTOS_H */

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,63 @@
; Options for the MIPS port of the compiler
;
; Copyright (C) 2005, 2007, 2008, 2010, 2011 Free Software Foundation, Inc.
;
; This file is part of GCC.
;
; GCC is free software; you can redistribute it and/or modify it under
; the terms of the GNU General Public License as published by the Free
; Software Foundation; either version 3, or (at your option) any later
; version.
;
; GCC is distributed in the hope that it will be useful, but WITHOUT
; ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
; or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
; License for more details.
;
; You should have received a copy of the GNU General Public License
; along with GCC; see the file COPYING3. If not see
; <http://www.gnu.org/licenses/>.
m32
Target RejectNegative Mask(32BIT)
Generate RV32 code
m64
Target RejectNegative InverseMask(32BIT, 64BIT)
Generate RV64 code
mbranch-cost=
Target RejectNegative Joined UInteger Var(riscv_branch_cost)
-mbranch-cost=COST Set the cost of branches to roughly COST instructions
mhard-float
Target Report RejectNegative InverseMask(SOFT_FLOAT_ABI, HARD_FLOAT_ABI)
Allow the use of hardware floating-point ABI and instructions
mmemcpy
Target Report Mask(MEMCPY)
Don't optimize block moves
mplt
Target Report Var(TARGET_PLT) Init(1)
When generating -fpic code, allow the use of PLTs. Ignored for fno-pic.
msoft-float
Target Report RejectNegative Mask(SOFT_FLOAT_ABI)
Prevent the use of all hardware floating-point instructions
mfdiv
Target Report RejectNegative Mask(FDIV)
Use hardware floating-point divide and square root instructions
mtune=
Target RejectNegative Joined Var(riscv_tune_string)
-mtune=PROCESSOR Optimize the output for PROCESSOR
msmall-data-limit=
Target Joined Separate UInteger Var(g_switch_value) Init(8)
-msmall-data-limit=<number> Put global and static data smaller than <number> bytes into a special section (on some targets)
matomic
Target Report Mask(ATOMIC)
Use hardware atomic memory instructions. Enabled by default, use -mno-atomic to disable

View File

@ -0,0 +1,197 @@
;; Machine description for RISC-V atomic operations.
;; Copyright (C) 2011-2014 Free Software Foundation, Inc.
;; Contributed by Andrew Waterman (waterman@cs.berkeley.edu) at UC Berkeley.
;; Based on MIPS target for GNU compiler.
;; This file is part of GCC.
;; GCC is free software; you can redistribute it and/or modify
;; it under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 3, or (at your option)
;; any later version.
;; GCC is distributed in the hope that it will be useful,
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
;; GNU General Public License for more details.
;; You should have received a copy of the GNU General Public License
;; along with GCC; see the file COPYING3. If not see
;; <http://www.gnu.org/licenses/>.
(define_c_enum "unspec" [
UNSPEC_COMPARE_AND_SWAP
UNSPEC_SYNC_OLD_OP
UNSPEC_SYNC_EXCHANGE
UNSPEC_ATOMIC_STORE
UNSPEC_MEMORY_BARRIER
])
(define_code_iterator any_atomic [plus ior xor and])
(define_code_attr atomic_optab
[(plus "add") (ior "or") (xor "xor") (and "and")])
;; Memory barriers.
(define_expand "mem_thread_fence"
[(match_operand:SI 0 "const_int_operand" "")] ;; model
""
{
if (INTVAL (operands[0]) != MEMMODEL_RELAXED)
{
rtx mem = gen_rtx_MEM (BLKmode, gen_rtx_SCRATCH (Pmode));
MEM_VOLATILE_P (mem) = 1;
emit_insn (gen_mem_thread_fence_1 (mem, operands[0]));
}
DONE;
})
(define_insn "mem_thread_fence_1"
[(set (match_operand:BLK 0 "" "")
(unspec:BLK [(match_dup 0)] UNSPEC_MEMORY_BARRIER))
(match_operand:SI 1 "const_int_operand" "")] ;; model
""
{
switch (INTVAL (operands[1]))
{
case MEMMODEL_SEQ_CST:
case MEMMODEL_ACQ_REL:
return "fence rw,rw";
case MEMMODEL_ACQUIRE:
case MEMMODEL_CONSUME:
return "fence r,rw";
case MEMMODEL_RELEASE:
return "fence rw,w";
default:
gcc_unreachable();
}
})
;; Atomic memory operations.
;; Implement atomic stores with amoswap. Fall back to fences for atomic loads.
(define_insn "atomic_store<mode>"
[(set (match_operand:GPR 0 "memory_operand" "=YR")
(unspec_volatile:GPR
[(match_operand:GPR 1 "reg_or_0_operand" "rJ")
(match_operand:SI 2 "const_int_operand")] ;; model
UNSPEC_ATOMIC_STORE))]
"TARGET_ATOMIC"
"amoswap.<amo>%A2 zero,%z1,%0")
(define_insn "sync_<optab><mode>"
[(set (match_operand:GPR 0 "memory_operand" "+YR")
(unspec_volatile:GPR
[(any_atomic:GPR (match_dup 0)
(match_operand:GPR 1 "reg_or_0_operand" "rJ"))]
UNSPEC_SYNC_OLD_OP))]
"TARGET_ATOMIC"
"amo<insn>.<amo>.sc zero,%z1,%0")
(define_insn "atomic_fetch_<atomic_optab><mode>"
[(set (match_operand:GPR 0 "register_operand" "=&r")
(match_operand:GPR 1 "memory_operand" "+YR"))
(set (match_dup 1)
(unspec_volatile:GPR
[(any_atomic:GPR (match_dup 1)
(match_operand:GPR 2 "reg_or_0_operand" "rJ"))
(match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_SYNC_OLD_OP))]
"TARGET_ATOMIC"
"amo<insn>.<amo>%A3 %0,%z2,%1")
(define_insn "atomic_exchange<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&r")
(unspec_volatile:GPR
[(match_operand:GPR 1 "memory_operand" "+YR")
(match_operand:SI 3 "const_int_operand")] ;; model
UNSPEC_SYNC_EXCHANGE))
(set (match_dup 1)
(match_operand:GPR 2 "register_operand" "0"))]
"TARGET_ATOMIC"
"amoswap.<amo>%A3 %0,%z2,%1")
(define_insn "atomic_cas_value_strong<mode>"
[(set (match_operand:GPR 0 "register_operand" "=&r")
(match_operand:GPR 1 "memory_operand" "+YR"))
(set (match_dup 1)
(unspec_volatile:GPR [(match_operand:GPR 2 "reg_or_0_operand" "rJ")
(match_operand:GPR 3 "reg_or_0_operand" "rJ")
(match_operand:SI 4 "const_int_operand") ;; mod_s
(match_operand:SI 5 "const_int_operand")] ;; mod_f
UNSPEC_COMPARE_AND_SWAP))
(clobber (match_scratch:GPR 6 "=&r"))]
"TARGET_ATOMIC"
"1: lr.<amo>%A5 %0,%1; bne %0,%z2,1f; sc.<amo>%A4 %6,%z3,%1; bnez %6,1b; 1:"
[(set (attr "length") (const_int 16))])
(define_expand "atomic_compare_and_swap<mode>"
[(match_operand:SI 0 "register_operand" "") ;; bool output
(match_operand:GPR 1 "register_operand" "") ;; val output
(match_operand:GPR 2 "memory_operand" "") ;; memory
(match_operand:GPR 3 "reg_or_0_operand" "") ;; expected value
(match_operand:GPR 4 "reg_or_0_operand" "") ;; desired value
(match_operand:SI 5 "const_int_operand" "") ;; is_weak
(match_operand:SI 6 "const_int_operand" "") ;; mod_s
(match_operand:SI 7 "const_int_operand" "")] ;; mod_f
"TARGET_ATOMIC"
{
emit_insn (gen_atomic_cas_value_strong<mode> (operands[1], operands[2],
operands[3], operands[4],
operands[6], operands[7]));
rtx compare = operands[1];
if (operands[3] != const0_rtx)
{
rtx difference = gen_rtx_MINUS (<MODE>mode, operands[1], operands[3]);
compare = gen_reg_rtx (<MODE>mode);
emit_insn (gen_rtx_SET (VOIDmode, compare, difference));
}
rtx eq = gen_rtx_EQ (<MODE>mode, compare, const0_rtx);
rtx result = gen_reg_rtx (<MODE>mode);
emit_insn (gen_rtx_SET (VOIDmode, result, eq));
emit_insn (gen_rtx_SET (VOIDmode, operands[0], gen_lowpart (SImode, result)));
DONE;
})
(define_expand "atomic_test_and_set"
[(match_operand:QI 0 "register_operand" "") ;; bool output
(match_operand:QI 1 "memory_operand" "+YR") ;; memory
(match_operand:SI 2 "const_int_operand" "")] ;; model
"TARGET_ATOMIC"
{
/* We have no QImode atomics, so use the address LSBs to form a mask,
then use an aligned SImode atomic. */
rtx result = operands[0];
rtx mem = operands[1];
rtx model = operands[2];
rtx addr = XEXP (mem, 0);
rtx aligned_addr = gen_reg_rtx (Pmode);
emit_move_insn (aligned_addr, gen_rtx_AND (Pmode, addr, GEN_INT (-4)));
rtx aligned_mem = change_address (mem, SImode, aligned_addr);
set_mem_alias_set (aligned_mem, 0);
rtx offset = gen_reg_rtx (SImode);
emit_move_insn (offset, gen_rtx_AND (SImode, gen_lowpart (SImode, addr),
GEN_INT (3)));
rtx tmp = gen_reg_rtx (SImode);
emit_move_insn (tmp, GEN_INT (1));
rtx shmt = gen_reg_rtx (SImode);
emit_move_insn (shmt, gen_rtx_ASHIFT (SImode, offset, GEN_INT (3)));
rtx word = gen_reg_rtx (SImode);
emit_move_insn (word, gen_rtx_ASHIFT (SImode, tmp, shmt));
tmp = gen_reg_rtx (SImode);
emit_insn (gen_atomic_fetch_orsi (tmp, aligned_mem, word, model));
emit_move_insn (gen_lowpart (SImode, result),
gen_rtx_LSHIFTRT (SImode, tmp,
gen_lowpart (SImode, shmt)));
DONE;
})

View File

@ -0,0 +1,5 @@
# Build the libraries for both hard and soft floating point
MULTILIB_OPTIONS = msoft-float m64/m32 mfdiv mno-atomic
MULTILIB_DIRNAMES = soft-float 64 32 fdiv no-atomic
MULTILIB_EXCEPTIONS = *msoft-float*/*mfdiv*

View File

@ -0,0 +1,6 @@
# Build the libraries for both hard and soft floating point
MULTILIB_OPTIONS = m64/m32 msoft-float mfdiv mno-atomic
MULTILIB_DIRNAMES = 64 32 soft-float fdiv no-atomic
MULTILIB_EXCEPTIONS = *msoft-float*/*mfdiv*
MULTILIB_OSDIRNAMES = ../lib ../lib32

View File

@ -0,0 +1,21 @@
# Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
#
# This file is part of GCC.
#
# GCC is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3, or (at your option)
# any later version.
#
# GCC is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GCC; see the file COPYING3. If not see
# <http://www.gnu.org/licenses/>.
MULTILIB_OPTIONS = m64/m32
MULTILIB_DIRNAMES = 64 32
MULTILIB_OSDIRNAMES = . ../lib/rv32

View File

@ -23351,6 +23351,25 @@ x3: .space 4
tls_first_minor=14
tls_as_opt="-a32 --fatal-warnings"
;;
riscv*-*-*)
conftest_s='
.section .tdata,"awT",@progbits
x:
.word 2
.text
la.tls.gd a0,x
la.tls.ie a1,x
lui v0,%tls_ie_hi(x)
lw v0,%tls_ie_lo(x)(v0)
add v0,v0,tp,%tls_ie_add(x)
lw v0,%tls_ie_off(x)(v0)
lui v0,%tprel_hi(x)
add v0,v0,tp,%tprel_add(x)
lw v0,%tprel_lo(x)(v0)'
tls_first_major=2
tls_first_minor=21
tls_as_opt='-m32 --fatal-warnings'
;;
s390-*-*)
conftest_s='
.section ".tdata","awT",@progbits

View File

@ -3108,6 +3108,25 @@ x3: .space 4
tls_first_minor=14
tls_as_opt="-a32 --fatal-warnings"
;;
riscv*-*-*)
conftest_s='
.section .tdata,"awT",@progbits
x:
.word 2
.text
la.tls.gd a0,x
la.tls.ie a1,x
lui v0,%tls_ie_hi(x)
lw v0,%tls_ie_lo(x)(v0)
add v0,v0,tp,%tls_ie_add(x)
lw v0,%tls_ie_off(x)(v0)
lui v0,%tprel_hi(x)
add v0,v0,tp,%tprel_add(x)
lw v0,%tprel_lo(x)(v0)'
tls_first_major=2
tls_first_minor=21
tls_as_opt='-m32 --fatal-warnings'
;;
s390-*-*)
conftest_s='
.section ".tdata","awT",@progbits

View File

@ -2540,7 +2540,8 @@ struct gimple_opt_pass pass_fold_builtins =
*/
#if defined(__alpha__) || defined(__amd64__) || defined(__sparc64__) \
|| (defined(__arm__) && defined(__ARM_EABI)) || defined(__powerpc__)
|| (defined(__arm__) && defined(__ARM_EABI)) || defined(__powerpc__) \
|| ((defined(__mips__) || defined(__riscv__)) && defined(_LP64))
#define JEMALLOC_TINY_MIN_2POW 3
#endif

View File

@ -143,6 +143,9 @@ or1k-*-* | or1knd-*-*)
powerpc*-*-*)
cpu_type=rs6000
;;
riscv*-*-*)
cpu_type=riscv
;;
rs6000*-*-*)
;;
score*-*-*)
@ -925,6 +928,17 @@ powerpcle-*-eabi*)
tmake_file="${tmake_file} rs6000/t-ppccomm rs6000/t-crtstuff t-crtstuff-pic t-fdpbit"
extra_parts="$extra_parts crtbegin.o crtend.o crtbeginS.o crtendS.o crtbeginT.o ecrti.o ecrtn.o ncrti.o ncrtn.o"
;;
riscv*-*-linux*)
tmake_file="${tmake_file} riscv/t-fpbit riscv/t-dpbit riscv/t-tpbit riscv/t-linux"
extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o crtendS.o crtbeginT.o"
;;
riscv*-*-netbsd*)
# nothing needed for NetBSD
;;
riscv*-*-*)
tmake_file="${tmake_file} riscv/t-fpbit riscv/t-dpbit riscv/t-elf"
extra_parts="$extra_parts crtbegin.o crtend.o crti.o crtn.o"
;;
rs6000-ibm-aix4.[3456789]* | powerpc-ibm-aix4.[3456789]*)
md_unwind_header=rs6000/aix-unwind.h
tmake_file="t-fdpbit rs6000/t-ppc64-fp rs6000/t-slibgcc-aix rs6000/t-ibm-ldouble"

View File

@ -0,0 +1 @@
/* crti.S is empty because .init_array/.fini_array are used exclusively. */

View File

@ -0,0 +1 @@
/* crtn.S is empty because .init_array/.fini_array are used exclusively. */

View File

@ -0,0 +1,178 @@
/* Functions needed for soft-float on riscv-linux. Based on
rs6000/ppc64-fp.c with TF types removed.
Copyright (C) 1989, 1992, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
2000, 2001, 2002, 2003, 2004, 2006, 2009 Free Software Foundation,
Inc.
This file is part of GCC.
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
for more details.
Under Section 7 of GPL version 3, you are granted additional
permissions described in the GCC Runtime Library Exception, version
3.1, as published by the Free Software Foundation.
You should have received a copy of the GNU General Public License and
a copy of the GCC Runtime Library Exception along with this program;
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
<http://www.gnu.org/licenses/>. */
#if defined(__riscv64)
#include "fp-bit.h"
extern DItype __fixdfdi (DFtype);
extern DItype __fixsfdi (SFtype);
extern USItype __fixunsdfsi (DFtype);
extern USItype __fixunssfsi (SFtype);
extern DFtype __floatdidf (DItype);
extern DFtype __floatundidf (UDItype);
extern SFtype __floatdisf (DItype);
extern SFtype __floatundisf (UDItype);
static DItype local_fixunssfdi (SFtype);
static DItype local_fixunsdfdi (DFtype);
DItype
__fixdfdi (DFtype a)
{
if (a < 0)
return - local_fixunsdfdi (-a);
return local_fixunsdfdi (a);
}
DItype
__fixsfdi (SFtype a)
{
if (a < 0)
return - local_fixunssfdi (-a);
return local_fixunssfdi (a);
}
USItype
__fixunsdfsi (DFtype a)
{
if (a >= - (DFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
return (SItype) a;
}
USItype
__fixunssfsi (SFtype a)
{
if (a >= - (SFtype) (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
return (SItype) (a + (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1))
- (- ((SItype)(((USItype)1 << ((4 * 8) - 1)) - 1)) - 1);
return (SItype) a;
}
DFtype
__floatdidf (DItype u)
{
DFtype d;
d = (SItype) (u >> (sizeof (SItype) * 8));
d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
}
DFtype
__floatundidf (UDItype u)
{
DFtype d;
d = (USItype) (u >> (sizeof (SItype) * 8));
d *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
d += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return d;
}
SFtype
__floatdisf (DItype u)
{
DFtype f;
if (53 < (sizeof (DItype) * 8)
&& 53 > ((sizeof (DItype) * 8) - 53 + 24))
{
if (! (- ((DItype) 1 << 53) < u
&& u < ((DItype) 1 << 53)))
{
if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
{
u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
}
}
}
f = (SItype) (u >> (sizeof (SItype) * 8));
f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
SFtype
__floatundisf (UDItype u)
{
DFtype f;
if (53 < (sizeof (DItype) * 8)
&& 53 > ((sizeof (DItype) * 8) - 53 + 24))
{
if (u >= ((UDItype) 1 << 53))
{
if ((UDItype) u & (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1))
{
u &= ~ (((UDItype) 1 << ((sizeof (DItype) * 8) - 53)) - 1);
u |= ((UDItype) 1 << ((sizeof (DItype) * 8) - 53));
}
}
}
f = (USItype) (u >> (sizeof (SItype) * 8));
f *= 2.0 * (((UDItype) 1) << ((sizeof (SItype) * 8) - 1));
f += (USItype) (u & ((((UDItype) 1) << (sizeof (SItype) * 8)) - 1));
return (SFtype) f;
}
/* This version is needed to prevent recursion; fixunsdfdi in libgcc
calls fixdfdi, which in turn calls calls fixunsdfdi. */
static DItype
local_fixunsdfdi (DFtype a)
{
USItype hi, lo;
hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
}
/* This version is needed to prevent recursion; fixunssfdi in libgcc
calls fixsfdi, which in turn calls calls fixunssfdi. */
static DItype
local_fixunssfdi (SFtype original_a)
{
DFtype a = original_a;
USItype hi, lo;
hi = a / (((UDItype) 1) << (sizeof (SItype) * 8));
lo = (a - ((DFtype) hi) * (((UDItype) 1) << (sizeof (SItype) * 8)));
return ((UDItype) hi << (sizeof (SItype) * 8)) | lo;
}
#endif

View File

@ -0,0 +1,4 @@
LIB2ADD += dp-bit.c
dp-bit.c: $(srcdir)/fp-bit.c
cat $(srcdir)/fp-bit.c > dp-bit.c

View File

@ -0,0 +1,2 @@
# Assemble startup files.
LIB2ADD += $(srcdir)/config/riscv/riscv-fp.c

View File

@ -0,0 +1,5 @@
LIB2ADD += fp-bit.c
fp-bit.c: $(srcdir)/fp-bit.c
echo '#define FLOAT' > fp-bit.c
cat $(srcdir)/fp-bit.c >> fp-bit.c

View File

@ -0,0 +1 @@
LIB2ADD += $(srcdir)/config/riscv/riscv-fp.c

View File

@ -0,0 +1,10 @@
LIB2ADD += tp-bit.c
tp-bit.c: $(srcdir)/fp-bit.c
echo '#ifdef _RISCVEL' > tp-bit.c
echo '# define FLOAT_BIT_ORDER_MISMATCH' >> tp-bit.c
echo '#endif' >> tp-bit.c
echo '#if __LDBL_MANT_DIG__ == 113' >> tp-bit.c
echo '# define TFLOAT' >> tp-bit.c
cat $(srcdir)/fp-bit.c >> tp-bit.c
echo '#endif' >> tp-bit.c