/* RISC-V-specific support for ELF.
- Copyright (C) 2011-2022 Free Software Foundation, Inc.
+ Copyright (C) 2011-2023 Free Software Foundation, Inc.
Contributed by Andrew Waterman (andrew@sifive.com).
Based on TILE-Gx and MIPS targets.
relocations for the debug info. */
static bfd_reloc_status_type riscv_elf_add_sub_reloc
(bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
+static bfd_reloc_status_type riscv_elf_ignore_reloc
+ (bfd *, arelent *, asymbol *, void *, asection *, bfd *, char **);
/* The relocation table used for SHT_RELA sections. */
/* No relocation. */
HOWTO (R_RISCV_NONE, /* type */
0, /* rightshift */
- 3, /* size */
+ 0, /* size */
0, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 32 bit relocation. */
HOWTO (R_RISCV_32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 64 bit relocation. */
HOWTO (R_RISCV_64, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* Relocation against a local symbol in a shared object. */
HOWTO (R_RISCV_RELATIVE, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
HOWTO (R_RISCV_JUMP_SLOT, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* Dynamic TLS relocations. */
HOWTO (R_RISCV_TLS_DTPMOD32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
HOWTO (R_RISCV_TLS_DTPMOD64, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
HOWTO (R_RISCV_TLS_DTPREL32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
HOWTO (R_RISCV_TLS_DTPREL64, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
HOWTO (R_RISCV_TLS_TPREL32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
HOWTO (R_RISCV_TLS_TPREL64, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 12-bit PC-relative branch offset. */
HOWTO (R_RISCV_BRANCH, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* 20-bit PC-relative jump offset. */
HOWTO (R_RISCV_JAL, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* 32-bit PC-relative function call (AUIPC/JALR). */
HOWTO (R_RISCV_CALL, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* Like R_RISCV_CALL, but not locally binding. */
HOWTO (R_RISCV_CALL_PLT, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* High 20 bits of 32-bit PC-relative GOT access. */
HOWTO (R_RISCV_GOT_HI20, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* High 20 bits of 32-bit PC-relative TLS IE GOT access. */
HOWTO (R_RISCV_TLS_GOT_HI20, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* High 20 bits of 32-bit PC-relative TLS GD GOT reference. */
HOWTO (R_RISCV_TLS_GD_HI20, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* High 20 bits of 32-bit PC-relative reference. */
HOWTO (R_RISCV_PCREL_HI20, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* Low 12 bits of a 32-bit PC-relative load or add. */
HOWTO (R_RISCV_PCREL_LO12_I, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* Low 12 bits of a 32-bit PC-relative store. */
HOWTO (R_RISCV_PCREL_LO12_S, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* High 20 bits of 32-bit absolute address. */
HOWTO (R_RISCV_HI20, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* High 12 bits of 32-bit load or add. */
HOWTO (R_RISCV_LO12_I, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* High 12 bits of 32-bit store. */
HOWTO (R_RISCV_LO12_S, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* High 20 bits of TLS LE thread pointer offset. */
HOWTO (R_RISCV_TPREL_HI20, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* Low 12 bits of TLS LE thread pointer offset for loads and adds. */
HOWTO (R_RISCV_TPREL_LO12_I, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* Low 12 bits of TLS LE thread pointer offset for stores. */
HOWTO (R_RISCV_TPREL_LO12_S, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* TLS LE thread pointer usage. May be relaxed. */
HOWTO (R_RISCV_TPREL_ADD, /* type */
0, /* rightshift */
- 3, /* size */
+ 0, /* size */
0, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 8-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_ADD8, /* type */
0, /* rightshift */
- 0, /* size */
+ 1, /* size */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 16-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_ADD16, /* type */
0, /* rightshift */
- 1, /* size */
+ 2, /* size */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 32-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_ADD32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 64-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_ADD64, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 8-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_SUB8, /* type */
0, /* rightshift */
- 0, /* size */
+ 1, /* size */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 16-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_SUB16, /* type */
0, /* rightshift */
- 1, /* size */
+ 2, /* size */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 32-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_SUB32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 64-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_SUB64, /* type */
0, /* rightshift */
- 4, /* size */
+ 8, /* size */
64, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
MINUS_ONE, /* dst_mask */
false), /* pcrel_offset */
- /* GNU extension to record C++ vtable hierarchy */
- HOWTO (R_RISCV_GNU_VTINHERIT, /* type */
- 0, /* rightshift */
- 4, /* size */
- 0, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- NULL, /* special_function */
- "R_RISCV_GNU_VTINHERIT", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset */
-
- /* GNU extension to record C++ vtable member usage */
- HOWTO (R_RISCV_GNU_VTENTRY, /* type */
- 0, /* rightshift */
- 4, /* size */
- 0, /* bitsize */
- false, /* pc_relative */
- 0, /* bitpos */
- complain_overflow_dont, /* complain_on_overflow */
- _bfd_elf_rel_vtable_reloc_fn, /* special_function */
- "R_RISCV_GNU_VTENTRY", /* name */
- false, /* partial_inplace */
- 0, /* src_mask */
- 0, /* dst_mask */
- false), /* pcrel_offset */
+ /* 41 and 42 are reserved. */
+ EMPTY_HOWTO (0),
+ EMPTY_HOWTO (0),
/* Indicates an alignment statement. The addend field encodes how many
bytes of NOPs follow the statement. The desired alignment is the
addend rounded up to the next power of two. */
HOWTO (R_RISCV_ALIGN, /* type */
0, /* rightshift */
- 3, /* size */
+ 0, /* size */
0, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 8-bit PC-relative branch offset. */
HOWTO (R_RISCV_RVC_BRANCH, /* type */
0, /* rightshift */
- 1, /* size */
+ 2, /* size */
16, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* 11-bit PC-relative jump offset. */
HOWTO (R_RISCV_RVC_JUMP, /* type */
0, /* rightshift */
- 1, /* size */
+ 2, /* size */
16, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* High 6 bits of 18-bit absolute address. */
HOWTO (R_RISCV_RVC_LUI, /* type */
0, /* rightshift */
- 1, /* size */
+ 2, /* size */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* GP-relative load. */
HOWTO (R_RISCV_GPREL_I, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* GP-relative store. */
HOWTO (R_RISCV_GPREL_S, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* TP-relative TLS LE load. */
HOWTO (R_RISCV_TPREL_I, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* TP-relative TLS LE store. */
HOWTO (R_RISCV_TPREL_S, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* The paired relocation may be relaxed. */
HOWTO (R_RISCV_RELAX, /* type */
0, /* rightshift */
- 3, /* size */
+ 0, /* size */
0, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 6-bit in-place addition, for local label subtraction. */
HOWTO (R_RISCV_SUB6, /* type */
0, /* rightshift */
- 0, /* size */
+ 1, /* size */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 6-bit in-place setting, for local label subtraction. */
HOWTO (R_RISCV_SET6, /* type */
0, /* rightshift */
- 0, /* size */
+ 1, /* size */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 8-bit in-place setting, for local label subtraction. */
HOWTO (R_RISCV_SET8, /* type */
0, /* rightshift */
- 0, /* size */
+ 1, /* size */
8, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 16-bit in-place setting, for local label subtraction. */
HOWTO (R_RISCV_SET16, /* type */
0, /* rightshift */
- 1, /* size */
+ 2, /* size */
16, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 32-bit in-place setting, for local label subtraction. */
HOWTO (R_RISCV_SET32, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
/* 32-bit PC relative. */
HOWTO (R_RISCV_32_PCREL, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
true, /* pc_relative */
0, /* bitpos */
/* Relocation against a local ifunc symbol in a shared object. */
HOWTO (R_RISCV_IRELATIVE, /* type */
0, /* rightshift */
- 2, /* size */
+ 4, /* size */
32, /* bitsize */
false, /* pc_relative */
0, /* bitpos */
0, /* src_mask */
0xffffffff, /* dst_mask */
false), /* pcrel_offset */
+
+ /* Reserved for R_RISCV_PLT32. */
+ EMPTY_HOWTO (59),
+
+ /* N-bit in-place setting, for unsigned-leb128 local label subtraction. */
+ HOWTO (R_RISCV_SET_ULEB128, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ riscv_elf_ignore_reloc, /* special_function */
+ "R_RISCV_SET_ULEB128", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
+
+ /* N-bit in-place addition, for unsigned-leb128 local label subtraction. */
+ HOWTO (R_RISCV_SUB_ULEB128, /* type */
+ 0, /* rightshift */
+ 0, /* size */
+ 0, /* bitsize */
+ false, /* pc_relative */
+ 0, /* bitpos */
+ complain_overflow_dont, /* complain_on_overflow */
+ riscv_elf_ignore_reloc, /* special_function */
+ "R_RISCV_SUB_ULEB128", /* name */
+ false, /* partial_inplace */
+ 0, /* src_mask */
+ 0, /* dst_mask */
+ false), /* pcrel_offset */
};
/* A mapping from BFD reloc types to RISC-V ELF reloc types. */
{ BFD_RELOC_RISCV_SET16, R_RISCV_SET16 },
{ BFD_RELOC_RISCV_SET32, R_RISCV_SET32 },
{ BFD_RELOC_RISCV_32_PCREL, R_RISCV_32_PCREL },
+ { BFD_RELOC_RISCV_SET_ULEB128, R_RISCV_SET_ULEB128 },
+ { BFD_RELOC_RISCV_SUB_ULEB128, R_RISCV_SUB_ULEB128 },
};
/* Given a BFD reloc type, return a howto structure. */
relocation = old_value + relocation;
break;
case R_RISCV_SUB6:
+ relocation = (old_value & ~howto->dst_mask)
+ | (((old_value & howto->dst_mask) - relocation)
+ & howto->dst_mask);
+ break;
case R_RISCV_SUB8:
case R_RISCV_SUB16:
case R_RISCV_SUB32:
return bfd_reloc_ok;
}
+/* Special handler for relocations which don't have to be relocated.
+ This function just simply return bfd_reloc_ok. */
+
+static bfd_reloc_status_type
+riscv_elf_ignore_reloc (bfd *abfd ATTRIBUTE_UNUSED,
+ arelent *reloc_entry,
+ asymbol *symbol ATTRIBUTE_UNUSED,
+ void *data ATTRIBUTE_UNUSED,
+ asection *input_section,
+ bfd *output_bfd,
+ char **error_message ATTRIBUTE_UNUSED)
+{
+ if (output_bfd != NULL)
+ reloc_entry->address += input_section->output_offset;
+ return bfd_reloc_ok;
+}
+
/* Always add the IMPLICIT for the SUBSET. */
static bool
{"g", "d", check_implicit_always},
{"g", "zicsr", check_implicit_always},
{"g", "zifencei", check_implicit_always},
+ {"m", "zmmul", check_implicit_always},
+ {"h", "zicsr", check_implicit_always},
{"q", "d", check_implicit_always},
{"v", "d", check_implicit_always},
{"v", "zve64d", check_implicit_always},
{"v", "zvl128b", check_implicit_always},
+ {"zvfh", "zvfhmin", check_implicit_always},
+ {"zvfh", "zfhmin", check_implicit_always},
+ {"zvfhmin", "zve32f", check_implicit_always},
{"zve64d", "d", check_implicit_always},
{"zve64d", "zve64f", check_implicit_always},
{"zve64f", "zve32f", check_implicit_always},
{"zve64x", "zve32x", check_implicit_always},
{"zve64x", "zvl64b", check_implicit_always},
{"zve32x", "zvl32b", check_implicit_always},
+ {"zve32x", "zicsr", check_implicit_always},
{"zvl65536b", "zvl32768b", check_implicit_always},
{"zvl32768b", "zvl16384b", check_implicit_always},
{"zvl16384b", "zvl8192b", check_implicit_always},
{"zvl256b", "zvl128b", check_implicit_always},
{"zvl128b", "zvl64b", check_implicit_always},
{"zvl64b", "zvl32b", check_implicit_always},
+ {"zcd", "d", check_implicit_always},
+ {"zcf", "f", check_implicit_always},
+ {"zfa", "f", check_implicit_always},
{"d", "f", check_implicit_always},
+ {"zfh", "zfhmin", check_implicit_always},
+ {"zfhmin", "f", check_implicit_always},
{"f", "zicsr", check_implicit_always},
- {"zfh", "f", check_implicit_always},
- {"zfh", "zicsr", check_implicit_always},
{"zqinx", "zdinx", check_implicit_always},
{"zdinx", "zfinx", check_implicit_always},
+ {"zhinx", "zhinxmin", check_implicit_always},
+ {"zhinxmin", "zfinx", check_implicit_always},
{"zfinx", "zicsr", check_implicit_always},
{"zk", "zkn", check_implicit_always},
{"zk", "zkr", check_implicit_always},
{"zks", "zbkx", check_implicit_always},
{"zks", "zksed", check_implicit_always},
{"zks", "zksh", check_implicit_always},
+ {"zvkn", "zvkned", check_implicit_always},
+ {"zvkn", "zvknha", check_implicit_always},
+ {"zvkn", "zvknhb", check_implicit_always},
+ {"zvkn", "zvbb", check_implicit_always},
+ {"zvkn", "zvkt", check_implicit_always},
+ {"zvkng", "zvkn", check_implicit_always},
+ {"zvkng", "zvkg", check_implicit_always},
+ {"zvknc", "zvkn", check_implicit_always},
+ {"zvknc", "zvbc", check_implicit_always},
+ {"zvks", "zvksed", check_implicit_always},
+ {"zvks", "zvksh", check_implicit_always},
+ {"zvks", "zvbb", check_implicit_always},
+ {"zvks", "zvkt", check_implicit_always},
+ {"zvksg", "zvks", check_implicit_always},
+ {"zvksg", "zvkg", check_implicit_always},
+ {"zvksc", "zvks", check_implicit_always},
+ {"zvksc", "zvbc", check_implicit_always},
+ {"zcf", "zca", check_implicit_always},
+ {"zcd", "zca", check_implicit_always},
+ {"zcb", "zca", check_implicit_always},
+ {"smaia", "ssaia", check_implicit_always},
+ {"smcntrpmf", "zicsr", check_implicit_always},
+ {"smstateen", "ssstateen", check_implicit_always},
+ {"smepmp", "zicsr", check_implicit_always},
+ {"ssaia", "zicsr", check_implicit_always},
+ {"sscofpmf", "zicsr", check_implicit_always},
+ {"ssstateen", "zicsr", check_implicit_always},
+ {"sstc", "zicsr", check_implicit_always},
+ {"svadu", "zicsr", check_implicit_always},
{NULL, NULL, NULL}
};
{"c", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
{"c", ISA_SPEC_CLASS_2P2, 2, 0, 0 },
{"v", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"h", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};
{"zicbom", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicbop", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicboz", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zicond", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zicsr", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
{"zicsr", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
{"zifencei", ISA_SPEC_CLASS_20191213, 2, 0, 0 },
{"zifencei", ISA_SPEC_CLASS_20190608, 2, 0, 0 },
- {"zihintpause", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zihintntl", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zihintpause", ISA_SPEC_CLASS_DRAFT, 2, 0, 0 },
+ {"zmmul", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zawrs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zfa", ISA_SPEC_CLASS_DRAFT, 0, 1, 0 },
{"zfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zfinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zdinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zqinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zhinx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zhinxmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zba", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zve32x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zve32f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
- {"zve32d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zve64x", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zve64f", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zve64d", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvbc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvfh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvfhmin", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvkg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvkn", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvkng", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvknc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvkned", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvknha", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvknhb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvksed", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvksh", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvks", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvksg", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvksc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zvkt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl32b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl64b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl128b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl16384b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl32768b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"zvl65536b", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"ztso", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zca", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zcb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zcf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"zcd", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};
static struct riscv_supported_ext riscv_supported_std_s_ext[] =
{
+ {"smaia", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"smcntrpmf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"smepmp", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"smstateen", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"ssaia", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"sscofpmf", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"ssstateen", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"sstc", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"svadu", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{"svinval", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"svnapot", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"svpbmt", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};
-static struct riscv_supported_ext riscv_supported_std_h_ext[] =
+static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
{
{NULL, 0, 0, 0, 0}
};
-static struct riscv_supported_ext riscv_supported_std_zxm_ext[] =
+static struct riscv_supported_ext riscv_supported_vendor_x_ext[] =
{
+ {"xtheadba", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadbb", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadbs", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadcmo", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadcondmov", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadfmemidx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadfmv", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadint", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadmac", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadmemidx", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadmempair", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xtheadsync", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
+ {"xventanacondops", ISA_SPEC_CLASS_DRAFT, 1, 0, 0 },
{NULL, 0, 0, 0, 0}
};
riscv_supported_std_ext,
riscv_supported_std_z_ext,
riscv_supported_std_s_ext,
- riscv_supported_std_h_ext,
riscv_supported_std_zxm_ext,
+ riscv_supported_vendor_x_ext,
NULL
};
{
RV_ISA_CLASS_Z = 1,
RV_ISA_CLASS_S,
- RV_ISA_CLASS_H,
RV_ISA_CLASS_ZXM,
RV_ISA_CLASS_X,
- RV_ISA_CLASS_UNKNOWN
+ RV_ISA_CLASS_SINGLE
};
/* Record the strings of the prefixed extensions, and their corresponding
{RV_ISA_CLASS_ZXM, "zxm"},
{RV_ISA_CLASS_Z, "z"},
{RV_ISA_CLASS_S, "s"},
- {RV_ISA_CLASS_H, "h"},
{RV_ISA_CLASS_X, "x"},
- {RV_ISA_CLASS_UNKNOWN, NULL}
+ {RV_ISA_CLASS_SINGLE, NULL}
};
/* Get the prefixed name class for the extensions, the class also
riscv_get_prefix_class (const char *arch)
{
int i = 0;
- while (parse_config[i].class != RV_ISA_CLASS_UNKNOWN)
+ while (parse_config[i].class != RV_ISA_CLASS_SINGLE)
{
if (strncmp (arch, parse_config[i].prefix,
strlen (parse_config[i].prefix)) == 0)
return parse_config[i].class;
i++;
}
- return RV_ISA_CLASS_UNKNOWN;
+ return RV_ISA_CLASS_SINGLE;
}
/* Check KNOWN_EXTS to see if the EXT is supported. */
return riscv_known_prefixed_ext (ext, riscv_supported_std_zxm_ext);
case RV_ISA_CLASS_S:
return riscv_known_prefixed_ext (ext, riscv_supported_std_s_ext);
- case RV_ISA_CLASS_H:
- return riscv_known_prefixed_ext (ext, riscv_supported_std_h_ext);
case RV_ISA_CLASS_X:
/* Only the single x is unrecognized. */
if (strcmp (ext, "x") != 0)
}
/* Canonical order for single letter extensions. */
-static const char riscv_ext_canonical_order[] = "eigmafdqlcbkjtpvn";
+static const char riscv_ext_canonical_order[] = "eigmafdqlcbkjtpvnh";
/* Array is used to compare the orders of standard extensions quickly. */
static int riscv_ext_order[26] = {0};
enum riscv_prefix_ext_class class1 = riscv_get_prefix_class (subset1);
enum riscv_prefix_ext_class class2 = riscv_get_prefix_class (subset2);
- if (class1 != RV_ISA_CLASS_UNKNOWN)
+ if (class1 != RV_ISA_CLASS_SINGLE)
order1 = - (int) class1;
- if (class2 != RV_ISA_CLASS_UNKNOWN)
+ if (class2 != RV_ISA_CLASS_SINGLE)
order2 = - (int) class2;
if (order1 == order2)
case RV_ISA_CLASS_ZXM: table = riscv_supported_std_zxm_ext; break;
case RV_ISA_CLASS_Z: table = riscv_supported_std_z_ext; break;
case RV_ISA_CLASS_S: table = riscv_supported_std_s_ext; break;
- case RV_ISA_CLASS_H: table = riscv_supported_std_h_ext; break;
- case RV_ISA_CLASS_X:
- break;
+ case RV_ISA_CLASS_X: table = riscv_supported_vendor_x_ext; break;
default:
table = riscv_supported_std_ext;
}
}
subset_list->tail = NULL;
+
+ if (subset_list->arch_str != NULL)
+ {
+ free ((void*) subset_list->arch_str);
+ subset_list->arch_str = NULL;
+ }
}
/* Parsing extension version.
return p;
}
-/* Parsing function for standard extensions.
+/* Parsing function for both standard and prefixed extensions.
Return Value:
Points to the end of extensions.
`p`: Curent parsing position. */
static const char *
-riscv_parse_std_ext (riscv_parse_subset_t *rps,
- const char *arch,
- const char *p)
+riscv_parse_extensions (riscv_parse_subset_t *rps,
+ const char *arch,
+ const char *p)
{
/* First letter must start with i, e or g. */
if (*p != 'e' && *p != 'i' && *p != 'g')
return NULL;
}
- while (p != NULL && *p != '\0')
+ while (*p != '\0')
{
- /* Stop when we parsed the known prefix class. */
- enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
- if (class != RV_ISA_CLASS_UNKNOWN)
- break;
-
if (*p == '_')
{
p++;
continue;
}
- bool implicit = false;
- int major = RISCV_UNKNOWN_VERSION;
- int minor = RISCV_UNKNOWN_VERSION;
- char subset[2] = {0, 0};
-
- subset[0] = *p;
-
- /* Check if the standard extension is supported. */
- if (riscv_ext_order[(subset[0] - 'a')] == 0)
- {
- rps->error_handler
- (_("%s: unknown standard ISA extension `%c'"),
- arch, subset[0]);
- return NULL;
- }
-
- /* Checking canonical order. */
- if (rps->subset_list->tail != NULL
- && riscv_compare_subsets (rps->subset_list->tail->name, subset) > 0)
- {
- rps->error_handler
- (_("%s: standard ISA extension `%c' is not "
- "in canonical order"), arch, subset[0]);
- return NULL;
- }
-
- p = riscv_parsing_subset_version (++p, &major, &minor);
- /* Added g as an implicit extension. */
- if (subset[0] == 'g')
- {
- implicit = true;
- major = RISCV_UNKNOWN_VERSION;
- minor = RISCV_UNKNOWN_VERSION;
- }
- riscv_parse_add_subset (rps, subset, major, minor, implicit);
- }
-
- return p;
-}
-
-/* Parsing function for prefixed extensions.
-
- Return Value:
- Points to the end of extension.
-
- Arguments:
- `rps`: Hooks and status for parsing extensions.
- `arch`: Full ISA string.
- `p`: Curent parsing position. */
-
-static const char *
-riscv_parse_prefixed_ext (riscv_parse_subset_t *rps,
- const char *arch,
- const char *p)
-{
- int major_version;
- int minor_version;
- const char *last_name;
- enum riscv_prefix_ext_class class;
-
- while (*p)
- {
- if (*p == '_')
- {
- p++;
- continue;
- }
-
- class = riscv_get_prefix_class (p);
- if (class == RV_ISA_CLASS_UNKNOWN)
- {
- rps->error_handler
- (_("%s: unknown prefix class for the ISA extension `%s'"),
- arch, p);
- return NULL;
- }
-
char *subset = xstrdup (p);
- char *q = subset;
+ char *q = subset; /* Start of version. */
const char *end_of_version;
+ bool implicit = false;
- /* Extract the whole prefixed extension by '_'. */
- while (*++q != '\0' && *q != '_')
- ;
- /* Look forward to the first letter which is not <major>p<minor>. */
- bool find_any_version = false;
- bool find_minor_version = false;
- while (1)
+ enum riscv_prefix_ext_class class = riscv_get_prefix_class (p);
+ if (class == RV_ISA_CLASS_SINGLE)
{
- q--;
- if (ISDIGIT (*q))
- find_any_version = true;
- else if (find_any_version
- && !find_minor_version
- && *q == 'p'
- && ISDIGIT (*(q - 1)))
- find_minor_version = true;
- else
- break;
+ if (riscv_ext_order[(*subset - 'a')] == 0)
+ {
+ rps->error_handler
+ (_("%s: unknown standard ISA extension or prefix class `%c'"),
+ arch, *subset);
+ free (subset);
+ return NULL;
+ }
+ q++;
}
- q++;
-
- /* Check if the end of extension is 'p' or not. If yes, then
- the second letter from the end cannot be number. */
- if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ else
{
- *q = '\0';
- rps->error_handler
- (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
- arch, subset);
- free (subset);
- return NULL;
+ /* Extract the whole prefixed extension by '_'. */
+ while (*++q != '\0' && *q != '_')
+ ;
+ /* Look forward to the first letter which is not <major>p<minor>. */
+ bool find_any_version = false;
+ bool find_minor_version = false;
+ while (1)
+ {
+ q--;
+ if (ISDIGIT (*q))
+ find_any_version = true;
+ else if (find_any_version
+ && !find_minor_version
+ && *q == 'p'
+ && ISDIGIT (*(q - 1)))
+ find_minor_version = true;
+ else
+ break;
+ }
+ q++;
+
+ /* Check if the end of extension is 'p' or not. If yes, then
+ the second letter from the end cannot be number. */
+ if (*(q - 1) == 'p' && ISDIGIT (*(q - 2)))
+ {
+ *q = '\0';
+ rps->error_handler
+ (_("%s: invalid prefixed ISA extension `%s' ends with <number>p"),
+ arch, subset);
+ free (subset);
+ return NULL;
+ }
}
+ int major_version = RISCV_UNKNOWN_VERSION;
+ int minor_version = RISCV_UNKNOWN_VERSION;
end_of_version =
riscv_parsing_subset_version (q, &major_version, &minor_version);
*q = '\0';
return NULL;
}
- /* Check that the extension name is well-formed. */
- if (rps->check_unknown_prefixed_ext
+ /* Check if the prefixed extension name is well-formed. */
+ if (class != RV_ISA_CLASS_SINGLE
+ && rps->check_unknown_prefixed_ext
&& !riscv_recognized_prefixed_ext (subset))
{
rps->error_handler
return NULL;
}
- /* Check that the extension isn't duplicate. */
- last_name = rps->subset_list->tail->name;
- if (!strcasecmp (last_name, subset))
- {
- rps->error_handler
- (_("%s: duplicate prefixed ISA extension `%s'"),
- arch, subset);
- free (subset);
- return NULL;
- }
-
- /* Check that the extension is in expected order. */
- if (riscv_compare_subsets (last_name, subset) > 0)
+ /* Added g as an implicit extension. */
+ if (class == RV_ISA_CLASS_SINGLE
+ && strcmp (subset, "g") == 0)
{
- rps->error_handler
- (_("%s: prefixed ISA extension `%s' is not in expected "
- "order. It must come before `%s'"),
- arch, subset, last_name);
- free (subset);
- return NULL;
+ implicit = true;
+ major_version = RISCV_UNKNOWN_VERSION;
+ minor_version = RISCV_UNKNOWN_VERSION;
}
-
riscv_parse_add_subset (rps, subset,
major_version,
- minor_version, false);
+ minor_version, implicit);
p += end_of_version - subset;
free (subset);
- if (*p != '\0' && *p != '_')
+ if (class != RV_ISA_CLASS_SINGLE
+ && *p != '\0' && *p != '_')
{
rps->error_handler
(_("%s: prefixed ISA extension must separate with _"),
riscv_parse_add_implicit_subsets (riscv_parse_subset_t *rps)
{
struct riscv_implicit_subset *t = riscv_implicit_subsets;
- for (; t->subset_name; t++)
+ bool finished = false;
+ while (!finished)
{
- riscv_subset_t *subset = NULL;
- if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
- && t->check_func (t->implicit_name, subset))
- riscv_parse_add_subset (rps, t->implicit_name,
- RISCV_UNKNOWN_VERSION,
- RISCV_UNKNOWN_VERSION, true);
+ finished = true;
+ for (; t->subset_name; t++)
+ {
+ riscv_subset_t *subset = NULL;
+ riscv_subset_t *implicit_subset = NULL;
+ if (riscv_lookup_subset (rps->subset_list, t->subset_name, &subset)
+ && !riscv_lookup_subset (rps->subset_list, t->implicit_name,
+ &implicit_subset)
+ && t->check_func (t->implicit_name, subset))
+ {
+ riscv_parse_add_subset (rps, t->implicit_name,
+ RISCV_UNKNOWN_VERSION,
+ RISCV_UNKNOWN_VERSION, true);
+
+ /* Restart the loop and pick up any new implications. */
+ finished = false;
+ t = riscv_implicit_subsets;
+ break;
+ }
+ }
}
}
int xlen = *rps->xlen;
bool no_conflict = true;
- if (riscv_lookup_subset (rps->subset_list, "e", &subset)
- && xlen > 32)
+ if (riscv_subset_supports (rps, "e")
+ && riscv_subset_supports (rps, "h"))
{
rps->error_handler
- (_("rv%d does not support the `e' extension"), xlen);
+ (_("rv%de does not support the `h' extension"), xlen);
no_conflict = false;
}
if (riscv_lookup_subset (rps->subset_list, "q", &subset)
rps->error_handler (_("rv%d does not support the `q' extension"), xlen);
no_conflict = false;
}
- if (riscv_lookup_subset (rps->subset_list, "e", &subset)
- && riscv_lookup_subset (rps->subset_list, "f", &subset))
+ if (riscv_lookup_subset (rps->subset_list, "zcf", &subset)
+ && xlen > 32)
{
rps->error_handler
- (_("rv32e does not support the `f' extension"));
+ (_("rv%d does not support the `zcf' extension"), xlen);
no_conflict = false;
}
if (riscv_lookup_subset (rps->subset_list, "zfinx", &subset)
&& riscv_lookup_subset (rps->subset_list, "f", &subset))
{
rps->error_handler
- (_("`zfinx' is conflict with the `f/d/q' extension"));
+ (_("`zfinx' is conflict with the `f/d/q/zfh/zfhmin' extension"));
no_conflict = false;
}
return false;
}
- /* Parsing standard extension. */
- p = riscv_parse_std_ext (rps, arch, p);
-
- if (p == NULL)
- return false;
-
- /* Parse prefixed extensions. */
- p = riscv_parse_prefixed_ext (rps, arch, p);
-
- if (p == NULL)
+ /* Parse single standard and prefixed extensions. */
+ if (riscv_parse_extensions (rps, arch, p) == NULL)
return false;
/* Finally add implicit extensions according to the current
{
riscv_subset_list_t *new = xmalloc (sizeof *new);
new->head = riscv_copy_subset (new, subset_list->head);
+ new->arch_str = strdup (subset_list->arch_str);
return new;
}
return riscv_subset_supports (rps, "zicbop");
case INSN_CLASS_ZICBOZ:
return riscv_subset_supports (rps, "zicboz");
+ case INSN_CLASS_ZICOND:
+ return riscv_subset_supports (rps, "zicond");
case INSN_CLASS_ZICSR:
return riscv_subset_supports (rps, "zicsr");
case INSN_CLASS_ZIFENCEI:
return riscv_subset_supports (rps, "zifencei");
+ case INSN_CLASS_ZIHINTNTL:
+ return riscv_subset_supports (rps, "zihintntl");
+ case INSN_CLASS_ZIHINTNTL_AND_C:
+ return (riscv_subset_supports (rps, "zihintntl")
+ && (riscv_subset_supports (rps, "c")
+ || riscv_subset_supports (rps, "zca")));
case INSN_CLASS_ZIHINTPAUSE:
return riscv_subset_supports (rps, "zihintpause");
case INSN_CLASS_M:
return riscv_subset_supports (rps, "m");
+ case INSN_CLASS_ZMMUL:
+ return riscv_subset_supports (rps, "zmmul");
case INSN_CLASS_A:
return riscv_subset_supports (rps, "a");
+ case INSN_CLASS_ZAWRS:
+ return riscv_subset_supports (rps, "zawrs");
case INSN_CLASS_F:
return riscv_subset_supports (rps, "f");
case INSN_CLASS_D:
case INSN_CLASS_Q:
return riscv_subset_supports (rps, "q");
case INSN_CLASS_C:
- return riscv_subset_supports (rps, "c");
+ return (riscv_subset_supports (rps, "c")
+ || riscv_subset_supports (rps, "zca"));
case INSN_CLASS_F_AND_C:
return (riscv_subset_supports (rps, "f")
- && riscv_subset_supports (rps, "c"));
+ && (riscv_subset_supports (rps, "c")
+ || riscv_subset_supports (rps, "zcf")));
case INSN_CLASS_D_AND_C:
return (riscv_subset_supports (rps, "d")
- && riscv_subset_supports (rps, "c"));
- case INSN_CLASS_F_OR_ZFINX:
+ && (riscv_subset_supports (rps, "c")
+ || riscv_subset_supports (rps, "zcd")));
+ case INSN_CLASS_F_INX:
return (riscv_subset_supports (rps, "f")
|| riscv_subset_supports (rps, "zfinx"));
- case INSN_CLASS_D_OR_ZDINX:
+ case INSN_CLASS_D_INX:
return (riscv_subset_supports (rps, "d")
|| riscv_subset_supports (rps, "zdinx"));
- case INSN_CLASS_Q_OR_ZQINX:
+ case INSN_CLASS_Q_INX:
return (riscv_subset_supports (rps, "q")
|| riscv_subset_supports (rps, "zqinx"));
- case INSN_CLASS_ZFH:
- return riscv_subset_supports (rps, "zfh");
- case INSN_CLASS_D_AND_ZFH:
- return (riscv_subset_supports (rps, "d")
- && riscv_subset_supports (rps, "zfh") );
- case INSN_CLASS_Q_AND_ZFH:
- return (riscv_subset_supports (rps, "q")
- && riscv_subset_supports (rps, "zfh"));
+ case INSN_CLASS_ZFH_INX:
+ return (riscv_subset_supports (rps, "zfh")
+ || riscv_subset_supports (rps, "zhinx"));
+ case INSN_CLASS_ZFHMIN:
+ return riscv_subset_supports (rps, "zfhmin");
+ case INSN_CLASS_ZFHMIN_INX:
+ return (riscv_subset_supports (rps, "zfhmin")
+ || riscv_subset_supports (rps, "zhinxmin"));
+ case INSN_CLASS_ZFHMIN_AND_D_INX:
+ return ((riscv_subset_supports (rps, "zfhmin")
+ && riscv_subset_supports (rps, "d"))
+ || (riscv_subset_supports (rps, "zhinxmin")
+ && riscv_subset_supports (rps, "zdinx")));
+ case INSN_CLASS_ZFHMIN_AND_Q_INX:
+ return ((riscv_subset_supports (rps, "zfhmin")
+ && riscv_subset_supports (rps, "q"))
+ || (riscv_subset_supports (rps, "zhinxmin")
+ && riscv_subset_supports (rps, "zqinx")));
+ case INSN_CLASS_ZFA:
+ return riscv_subset_supports (rps, "zfa");
+ case INSN_CLASS_D_AND_ZFA:
+ return riscv_subset_supports (rps, "d")
+ && riscv_subset_supports (rps, "zfa");
+ case INSN_CLASS_Q_AND_ZFA:
+ return riscv_subset_supports (rps, "q")
+ && riscv_subset_supports (rps, "zfa");
+ case INSN_CLASS_ZFH_AND_ZFA:
+ return riscv_subset_supports (rps, "zfh")
+ && riscv_subset_supports (rps, "zfa");
+ case INSN_CLASS_ZFH_OR_ZVFH_AND_ZFA:
+ return (riscv_subset_supports (rps, "zfh")
+ || riscv_subset_supports (rps, "zvfh"))
+ && riscv_subset_supports (rps, "zfa");
case INSN_CLASS_ZBA:
return riscv_subset_supports (rps, "zba");
case INSN_CLASS_ZBB:
|| riscv_subset_supports (rps, "zve64d")
|| riscv_subset_supports (rps, "zve64f")
|| riscv_subset_supports (rps, "zve32f"));
+ case INSN_CLASS_ZVBB:
+ return riscv_subset_supports (rps, "zvbb");
+ case INSN_CLASS_ZVBC:
+ return riscv_subset_supports (rps, "zvbc");
+ case INSN_CLASS_ZVKG:
+ return riscv_subset_supports (rps, "zvkg");
+ case INSN_CLASS_ZVKNED:
+ return riscv_subset_supports (rps, "zvkned");
+ case INSN_CLASS_ZVKNHA_OR_ZVKNHB:
+ return (riscv_subset_supports (rps, "zvknha")
+ || riscv_subset_supports (rps, "zvknhb"));
+ case INSN_CLASS_ZVKSED:
+ return riscv_subset_supports (rps, "zvksed");
+ case INSN_CLASS_ZVKSH:
+ return riscv_subset_supports (rps, "zvksh");
+ case INSN_CLASS_ZCB:
+ return riscv_subset_supports (rps, "zcb");
+ case INSN_CLASS_ZCB_AND_ZBB:
+ return (riscv_subset_supports (rps, "zcb")
+ && riscv_subset_supports (rps, "zbb"));
+ case INSN_CLASS_ZCB_AND_ZBA:
+ return (riscv_subset_supports (rps, "zcb")
+ && riscv_subset_supports (rps, "zba"));
+ case INSN_CLASS_ZCB_AND_ZMMUL:
+ return (riscv_subset_supports (rps, "zcb")
+ && riscv_subset_supports (rps, "zmmul"));
case INSN_CLASS_SVINVAL:
return riscv_subset_supports (rps, "svinval");
+ case INSN_CLASS_H:
+ return riscv_subset_supports (rps, "h");
+ case INSN_CLASS_XTHEADBA:
+ return riscv_subset_supports (rps, "xtheadba");
+ case INSN_CLASS_XTHEADBB:
+ return riscv_subset_supports (rps, "xtheadbb");
+ case INSN_CLASS_XTHEADBS:
+ return riscv_subset_supports (rps, "xtheadbs");
+ case INSN_CLASS_XTHEADCMO:
+ return riscv_subset_supports (rps, "xtheadcmo");
+ case INSN_CLASS_XTHEADCONDMOV:
+ return riscv_subset_supports (rps, "xtheadcondmov");
+ case INSN_CLASS_XTHEADFMEMIDX:
+ return riscv_subset_supports (rps, "xtheadfmemidx");
+ case INSN_CLASS_XTHEADFMV:
+ return riscv_subset_supports (rps, "xtheadfmv");
+ case INSN_CLASS_XTHEADINT:
+ return riscv_subset_supports (rps, "xtheadint");
+ case INSN_CLASS_XTHEADMAC:
+ return riscv_subset_supports (rps, "xtheadmac");
+ case INSN_CLASS_XTHEADMEMIDX:
+ return riscv_subset_supports (rps, "xtheadmemidx");
+ case INSN_CLASS_XTHEADMEMPAIR:
+ return riscv_subset_supports (rps, "xtheadmempair");
+ case INSN_CLASS_XTHEADSYNC:
+ return riscv_subset_supports (rps, "xtheadsync");
+ case INSN_CLASS_XVENTANACONDOPS:
+ return riscv_subset_supports (rps, "xventanacondops");
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));
{
case INSN_CLASS_I:
return "i";
+ case INSN_CLASS_ZICBOM:
+ return "zicbom";
+ case INSN_CLASS_ZICBOP:
+ return "zicbop";
+ case INSN_CLASS_ZICBOZ:
+ return "zicboz";
+ case INSN_CLASS_ZICOND:
+ return "zicond";
case INSN_CLASS_ZICSR:
return "zicsr";
case INSN_CLASS_ZIFENCEI:
return "zifencei";
+ case INSN_CLASS_ZIHINTNTL:
+ return "zihintntl";
+ case INSN_CLASS_ZIHINTNTL_AND_C:
+ if (!riscv_subset_supports (rps, "zihintntl"))
+ {
+ if (!riscv_subset_supports (rps, "c")
+ && !riscv_subset_supports (rps, "zca"))
+ return _("zihintntl' and `c', or `zihintntl' and `zca");
+ else
+ return "zihintntl";
+ }
+ else
+ return _("c' or `zca");
case INSN_CLASS_ZIHINTPAUSE:
return "zihintpause";
case INSN_CLASS_M:
return "m";
+ case INSN_CLASS_ZMMUL:
+ return _ ("m' or `zmmul");
case INSN_CLASS_A:
return "a";
+ case INSN_CLASS_ZAWRS:
+ return "zawrs";
case INSN_CLASS_F:
return "f";
case INSN_CLASS_D:
case INSN_CLASS_Q:
return "q";
case INSN_CLASS_C:
- return "c";
+ return _("c' or `zca");
case INSN_CLASS_F_AND_C:
- if (!riscv_subset_supports (rps, "f")
- && !riscv_subset_supports (rps, "c"))
- return "f' and `c";
- else if (!riscv_subset_supports (rps, "f"))
- return "f";
+ if (!riscv_subset_supports (rps, "f"))
+ {
+ if (!riscv_subset_supports (rps, "c")
+ && !riscv_subset_supports (rps, "zcf"))
+ return _("f' and `c', or `f' and `zcf");
+ else
+ return "f";
+ }
else
- return "c";
+ return _("c' or `zcf");
case INSN_CLASS_D_AND_C:
+ if (!riscv_subset_supports (rps, "d"))
+ {
+ if (!riscv_subset_supports (rps, "c")
+ && !riscv_subset_supports (rps, "zcd"))
+ return _("d' and `c', or `d' and `zcd");
+ else
+ return "d";
+ }
+ else
+ return _("c' or `zcd");
+ case INSN_CLASS_F_INX:
+ return _("f' or `zfinx");
+ case INSN_CLASS_D_INX:
+ return _("d' or `zdinx");
+ case INSN_CLASS_Q_INX:
+ return _("q' or `zqinx");
+ case INSN_CLASS_ZFH_INX:
+ return _("zfh' or `zhinx");
+ case INSN_CLASS_ZFHMIN:
+ return "zfhmin";
+ case INSN_CLASS_ZFHMIN_INX:
+ return _("zfhmin' or `zhinxmin");
+ case INSN_CLASS_ZFHMIN_AND_D_INX:
+ if (riscv_subset_supports (rps, "zfhmin"))
+ return "d";
+ else if (riscv_subset_supports (rps, "d"))
+ return "zfhmin";
+ else if (riscv_subset_supports (rps, "zhinxmin"))
+ return "zdinx";
+ else if (riscv_subset_supports (rps, "zdinx"))
+ return "zhinxmin";
+ else
+ return _("zfhmin' and `d', or `zhinxmin' and `zdinx");
+ case INSN_CLASS_ZFHMIN_AND_Q_INX:
+ if (riscv_subset_supports (rps, "zfhmin"))
+ return "q";
+ else if (riscv_subset_supports (rps, "q"))
+ return "zfhmin";
+ else if (riscv_subset_supports (rps, "zhinxmin"))
+ return "zqinx";
+ else if (riscv_subset_supports (rps, "zqinx"))
+ return "zhinxmin";
+ else
+ return _("zfhmin' and `q', or `zhinxmin' and `zqinx");
+ case INSN_CLASS_ZFA:
+ return "zfa";
+ case INSN_CLASS_D_AND_ZFA:
if (!riscv_subset_supports (rps, "d")
- && !riscv_subset_supports (rps, "c"))
- return "d' and `c";
+ && !riscv_subset_supports (rps, "zfa"))
+ return _("d' and `zfa");
else if (!riscv_subset_supports (rps, "d"))
return "d";
else
- return "c";
- case INSN_CLASS_F_OR_ZFINX:
- return "f' or `zfinx";
- case INSN_CLASS_D_OR_ZDINX:
- return "d' or `zdinx";
- case INSN_CLASS_Q_OR_ZQINX:
- return "q' or `zqinx";
+ return "zfa";
+ case INSN_CLASS_Q_AND_ZFA:
+ if (!riscv_subset_supports (rps, "q")
+ && !riscv_subset_supports (rps, "zfa"))
+ return _("q' and `zfa");
+ else if (!riscv_subset_supports (rps, "q"))
+ return "q";
+ else
+ return "zfa";
+ case INSN_CLASS_ZFH_AND_ZFA:
+ if (!riscv_subset_supports (rps, "zfh")
+ && !riscv_subset_supports (rps, "zfa"))
+ return _("zfh' and `zfa");
+ else if (!riscv_subset_supports (rps, "zfh"))
+ return "zfh";
+ else
+ return "zfa";
+ case INSN_CLASS_ZFH_OR_ZVFH_AND_ZFA:
+ if (!riscv_subset_supports (rps, "zfa"))
+ {
+ if (!riscv_subset_supports (rps, "zfh")
+ && !riscv_subset_supports (rps, "zvfh"))
+ return _("zfh' and `zfa', or `zvfh' and `zfa");
+ else
+ return "zfa";
+ }
+ else
+ return _("zfh' or `zvfh");
case INSN_CLASS_ZBA:
return "zba";
case INSN_CLASS_ZBB:
case INSN_CLASS_ZBKX:
return "zbkx";
case INSN_CLASS_ZBB_OR_ZBKB:
- return "zbb' or `zbkb";
+ return _("zbb' or `zbkb");
case INSN_CLASS_ZBC_OR_ZBKC:
- return "zbc' or `zbkc";
+ return _("zbc' or `zbkc");
case INSN_CLASS_ZKND:
return "zknd";
case INSN_CLASS_ZKNE:
case INSN_CLASS_ZKNH:
return "zknh";
case INSN_CLASS_ZKND_OR_ZKNE:
- return "zknd' or `zkne";
+ return _("zknd' or `zkne");
case INSN_CLASS_ZKSED:
return "zksed";
case INSN_CLASS_ZKSH:
return "zksh";
case INSN_CLASS_V:
- return "v' or `zve64x' or `zve32x";
+ return _("v' or `zve64x' or `zve32x");
case INSN_CLASS_ZVEF:
- return "v' or `zve64d' or `zve64f' or `zve32f";
+ return _("v' or `zve64d' or `zve64f' or `zve32f");
+ case INSN_CLASS_ZVBB:
+ return _("zvbb");
+ case INSN_CLASS_ZVBC:
+ return _("zvbc");
+ case INSN_CLASS_ZVKG:
+ return _("zvkg");
+ case INSN_CLASS_ZVKNED:
+ return _("zvkned");
+ case INSN_CLASS_ZVKNHA_OR_ZVKNHB:
+ return _("zvknha' or `zvknhb");
+ case INSN_CLASS_ZVKSED:
+ return _("zvksed");
+ case INSN_CLASS_ZVKSH:
+ return _("zvksh");
+ case INSN_CLASS_ZCB:
+ return "zcb";
+ case INSN_CLASS_ZCB_AND_ZBA:
+ return _("zcb' and `zba");
+ case INSN_CLASS_ZCB_AND_ZBB:
+ return _("zcb' and `zbb");
+ case INSN_CLASS_ZCB_AND_ZMMUL:
+ return _("zcb' and `zmmul', or `zcb' and `m");
case INSN_CLASS_SVINVAL:
return "svinval";
+ case INSN_CLASS_H:
+ return _("h");
+ case INSN_CLASS_XTHEADBA:
+ return "xtheadba";
+ case INSN_CLASS_XTHEADBB:
+ return "xtheadbb";
+ case INSN_CLASS_XTHEADBS:
+ return "xtheadbs";
+ case INSN_CLASS_XTHEADCMO:
+ return "xtheadcmo";
+ case INSN_CLASS_XTHEADCONDMOV:
+ return "xtheadcondmov";
+ case INSN_CLASS_XTHEADFMEMIDX:
+ return "xtheadfmemidx";
+ case INSN_CLASS_XTHEADFMV:
+ return "xtheadfmv";
+ case INSN_CLASS_XTHEADINT:
+ return "xtheadint";
+ case INSN_CLASS_XTHEADMAC:
+ return "xtheadmac";
+ case INSN_CLASS_XTHEADMEMIDX:
+ return "xtheadmemidx";
+ case INSN_CLASS_XTHEADMEMPAIR:
+ return "xtheadmempair";
+ case INSN_CLASS_XTHEADSYNC:
+ return "xtheadsync";
default:
rps->error_handler
(_("internal: unreachable INSN_CLASS_*"));