diff options
author | Robert Mustacchi <rm@joyent.com> | 2018-07-15 16:02:36 +0000 |
---|---|---|
committer | Robert Mustacchi <rm@joyent.com> | 2018-09-24 18:35:18 +0000 |
commit | 1f1540205fa6366266184180654434272c425ac2 (patch) | |
tree | dbb354f00033a4b7c2db6b1ec88ba02ad977bf19 | |
parent | 856f620e96e5413932a6607aea5094db2ece172f (diff) | |
download | illumos-joyent-1f1540205fa6366266184180654434272c425ac2.tar.gz |
9820 Want risc-v disassembler
Reviewed by: Dan McDonald <danmcd@joyent.com>
Reviewed by: Richard Lowe <richlowe@richlowe.net>
Approved by: Garrett D'Amore <garrett@damore.org>
48 files changed, 4377 insertions, 199 deletions
diff --git a/usr/src/cmd/dis/dis_main.c b/usr/src/cmd/dis/dis_main.c index 2886f412c9..db785eff7b 100644 --- a/usr/src/cmd/dis/dis_main.c +++ b/usr/src/cmd/dis/dis_main.c @@ -26,6 +26,7 @@ * Copyright 2011 Jason King. All rights reserved. * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright 2018, Joyent, Inc. */ #include <ctype.h> @@ -579,6 +580,29 @@ dis_file(const char *filename) } break; + case EM_RISCV: + /* + * RISC-V is defined to be litle endian. The current ISA + * makes it clear that the 64-bit instructions can + * co-exist with the 32-bit ones and therefore we don't + * need a separate elf class at this time. + */ + if (ehdr.e_ident[EI_DATA] != ELFDATA2LSB) { + warn("invalid EI_DATA field for RISC-V object"); + return; + } + + if (ehdr.e_ident[EI_CLASS] == ELFCLASS32) { + g_flags |= DIS_RISCV_32; + } else if (ehdr.e_ident[EI_CLASS] == ELFCLASS64) { + g_flags |= DIS_RISCV_64; + } else { + warn("invalid EI_CLASS field for RISC-V " + "object"); + return; + } + break; + default: die("%s: unsupported ELF machine 0x%x", filename, ehdr.e_machine); diff --git a/usr/src/lib/libdisasm/Makefile.com b/usr/src/lib/libdisasm/Makefile.com index b465f56752..2afa0e3499 100644 --- a/usr/src/lib/libdisasm/Makefile.com +++ b/usr/src/lib/libdisasm/Makefile.com @@ -23,6 +23,7 @@ # Use is subject to license terms. # Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> # Copyright 2015 Nexenta Systems, Inc. All rights reserved. +# Copyright (c) 2018, Joyent, Inc. # # @@ -58,6 +59,7 @@ SRCS_sparc= $(COMDIR)/dis_sparc.c \ $(COMDIR)/dis_sparc_fmt.c \ $(COMDIR)/dis_sparc_instr.c SRCS_s390x= $(COMDIR)/dis_s390x.c +SRCS_riscv= $(COMDIR)/dis_riscv.c OBJECTS_i386= dis_i386.o \ dis_tables.o @@ -65,6 +67,7 @@ OBJECTS_sparc= dis_sparc.o \ dis_sparc_fmt.o \ dis_sparc_instr.o OBJECTS_s390x= dis_s390x.o +OBJECTS_riscv= dis_riscv.o # # We build the regular shared library with support for all architectures. @@ -74,7 +77,8 @@ OBJECTS_s390x= dis_s390x.o OBJECTS_library= $(OBJECTS_common) \ $(OBJECTS_i386) \ $(OBJECTS_sparc) \ - $(OBJECTS_s390x) + $(OBJECTS_s390x) \ + $(OBJECTS_riscv) OBJECTS_standalone= $(OBJECTS_common) \ $(OBJECTS_$(MACH)) OBJECTS= $(OBJECTS_$(CURTYPE)) @@ -84,7 +88,8 @@ include $(SRC)/lib/Makefile.lib SRCS_library= $(SRCS_common) \ $(SRCS_i386) \ $(SRCS_sparc) \ - $(SRCS_s390x) + $(SRCS_s390x) \ + $(SRCS_riscv) SRCS_standalone= $(SRCS_common) \ $(SRCS_$(MACH)) SRCS= $(SRCS_$(CURTYPE)) diff --git a/usr/src/lib/libdisasm/common/dis_riscv.c b/usr/src/lib/libdisasm/common/dis_riscv.c new file mode 100644 index 0000000000..fa7cc30610 --- /dev/null +++ b/usr/src/lib/libdisasm/common/dis_riscv.c @@ -0,0 +1,2000 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright (c) 2018, Joyent, Inc. + */ + +/* + * RISC-V Instruction set decoder + */ + +#include <libdisasm.h> +#include <sys/byteorder.h> +#include <sys/debug.h> + +#include "libdisasm_impl.h" + +#include <stdio.h> + +extern int strcmp(const char *, const char *); + +/* + * Register names based on their ABI name. + */ +static const char *dis_riscv_regs[32] = { + "x0", "ra", "sp", "gp", "tp", "t0", "t1", "t2", + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5", + "a6", "a7", "s2", "s3", "s4", "s5", "s6", "s7", + "s8", "s9", "s10", "s11", "t3", "t4", "t5", "t6" +}; + +static const char *dis_riscv_fpregs[32] = { + "ft0", "ft1", "ft2", "ft3", "ft4", "ft5", "ft6", "ft7", + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5", + "fa6", "fa7", "fs2", "fs3", "fs4", "fs5", "fs6", "fs7", + "fs8", "fs9", "fs10", "fs11", "ft8", "ft9", "ft10", "ft11", +}; + +static const char *dis_riscv_c_regs[8] = { + "s0", "s1", "a0", "a1", "a2", "a3", "a4", "a5" +}; + +static const char *dis_riscv_c_fpregs[8] = { + "fs0", "fs1", "fa0", "fa1", "fa2", "fa3", "fa4", "fa5" +}; + +/* + * RM names have the leading comma in them because the last value represents + * that the hardware register decides the rounding mode and therefore nothing + * should be appended to the instruction. + */ +static const char *dis_riscv_rm[8] = { + ",rne", ",rtz", ",rdn", ",rup", ",rmm", ",???", ",???", "" +}; + +typedef struct dis_riscv_csr { + uint_t drc_val; + const char *drc_name; +} dis_riscv_csr_t; + +/* + * The current set of CSR names as per Table 2.2-2.5 from RISC-V Privileged + * Architectures V1.10. These include all of the ones in the User-Level ISA. + * These are ordered per the doc. + */ +static dis_riscv_csr_t dis_riscv_csr_map[] = { + /* User Trap */ + { 0x000, "ustatus" }, { 0x004, "uie" }, { 0x005, "utvec" }, + /* User Trap Handling */ + { 0x040, "uscratch" }, { 0x041, "uepc" }, { 0x042, "ucause" }, + { 0x043, "utval" }, { 0x044, "uip" }, + /* User Floating-Point CSRs */ + { 0x001, "fflags" }, { 0x002, "frm" }, { 0x003, "fcsr" }, + /* User Counters/Timers */ + { 0xc00, "cycle" }, { 0xc01, "time" }, { 0xc02, "instret" }, + { 0xc03, "hpmcounter3" }, { 0xc04, "hpmcounter4" }, + { 0xc05, "hpmcounter5" }, { 0xc06, "hpmcounter6" }, + { 0xc07, "hpmcounter7" }, { 0xc08, "hpmcounter8" }, + { 0xc09, "hpmcounter9" }, { 0xc0a, "hpmcounter10" }, + { 0xc0b, "hpmcounter11" }, { 0xc0c, "hpmcounter12" }, + { 0xc0d, "hpmcounter13" }, { 0xc0e, "hpmcounter14" }, + { 0xc0f, "hpmcounter15" }, { 0xc10, "hpmcounter16" }, + { 0xc11, "hpmcounter17" }, { 0xc12, "hpmcounter18" }, + { 0xc13, "hpmcounter19" }, { 0xc14, "hpmcounter20" }, + { 0xc15, "hpmcounter21" }, { 0xc16, "hpmcounter22" }, + { 0xc17, "hpmcounter23" }, { 0xc18, "hpmcounter24" }, + { 0xc19, "hpmcounter25" }, { 0xc1a, "hpmcounter26" }, + { 0xc1b, "hpmcounter27" }, { 0xc1c, "hpmcounter28" }, + { 0xc1d, "hpmcounter29" }, { 0xc1e, "hpmcounter30" }, + { 0xc1f, "hpmcounter31" }, + { 0xc80, "cycleh" }, { 0xc81, "timeh" }, { 0xc82, "instreth" }, + { 0xc83, "hpmcounter3h" }, { 0xc84, "hpmcounter4h" }, + { 0xc85, "hpmcounter5h" }, { 0xc86, "hpmcounter6h" }, + { 0xc87, "hpmcounter7h" }, { 0xc88, "hpmcounter8h" }, + { 0xc89, "hpmcounter9h" }, { 0xc8a, "hpmcounter10h" }, + { 0xc8b, "hpmcounter11h" }, { 0xc8c, "hpmcounter12h" }, + { 0xc8d, "hpmcounter13h" }, { 0xc8e, "hpmcounter14h" }, + { 0xc8f, "hpmcounter15h" }, { 0xc90, "hpmcounter16h" }, + { 0xc91, "hpmcounter17h" }, { 0xc92, "hpmcounter18h" }, + { 0xc93, "hpmcounter19h" }, { 0xc94, "hpmcounter20h" }, + { 0xc95, "hpmcounter21h" }, { 0xc96, "hpmcounter22h" }, + { 0xc97, "hpmcounter23h" }, { 0xc98, "hpmcounter24h" }, + { 0xc99, "hpmcounter25h" }, { 0xc9a, "hpmcounter26h" }, + { 0xc9b, "hpmcounter27h" }, { 0xc9c, "hpmcounter28h" }, + { 0xc9d, "hpmcounter29h" }, { 0xc9e, "hpmcounter30h" }, + { 0xc9f, "hpmcounter31h" }, + /* Supervisor Trap Status */ + { 0x100, "sstatus" }, { 0x102, "sedeleg" }, { 0x103, "sideleg" }, + { 0x104, "sie" }, { 0x105, "stvec" }, { 0x106, "scounteren" }, + /* Supervisor Trap Handling */ + { 0x140, "sscratch" }, { 0x141, "sepc" }, { 0x142, "scause" }, + { 0x143, "stval" }, { 0x144, "sip" }, + /* Supervisor Protection and Translation */ + { 0x180, "satp" }, + /* Machine Information Registers */ + { 0xf11, "mvendorid" }, { 0xf12, "marchid" }, + { 0xf13, "mimpid" }, { 0xf14, "mhartid" }, + /* Machine Trap Setup */ + { 0x300, "mstatus" }, { 0x301, "misa" }, { 0x302, "medeleg" }, + { 0x303, "mideleg" }, { 0x304, "mie" }, { 0x305, "mtvec" }, + { 0x306, "mcounteren" }, + /* Machine Trap Handling */ + { 0x340, "mscratch" }, { 0x341, "mepc" }, { 0x342, "mcause" }, + { 0x343, "mtval" }, { 0x344, "mip" }, + /* Machine Protection and Translation */ + { 0x3a0, "pmpcfg0" }, { 0x3a1, "pmpcfg1" }, + { 0x3a2, "pmpcfg2" }, { 0x3a3, "pmpcfg3" }, + { 0x3b0, "pmpaddr0" }, { 0x3b1, "pmpaddr1" }, + { 0x3b2, "pmpaddr2" }, { 0x3b3, "pmpaddr3" }, + { 0x3b4, "pmpaddr4" }, { 0x3b5, "pmpaddr5" }, + { 0x3b6, "pmpaddr6" }, { 0x3b7, "pmpaddr7" }, + { 0x3b8, "pmpaddr8" }, { 0x3b9, "pmpaddr9" }, + { 0x3ba, "pmpaddr10" }, { 0x3bb, "pmpaddr11" }, + { 0x3bc, "pmpaddr12" }, { 0x3bd, "pmpaddr13" }, + { 0x3be, "pmpaddr14" }, { 0x3bf, "pmpaddr15" } +}; + +typedef enum dis_riscv_csr_alias_type { + DIS_RISCV_CSR_READ, + DIS_RISCV_CSR_READ_GEN, + DIS_RISCV_CSR_SWAP, + DIS_RISCV_CSR_SWAP_IMM, + DIS_RISCV_CSR_WRITE, + DIS_RISCV_CSR_WRITE_GEN, + DIS_RISCV_CSR_WRITE_IMM, + DIS_RISCV_CSR_WRITE_IMM_GEN +} dis_riscv_csr_alias_type_t; + +typedef struct dis_riscv_csr_alias { + const char *drca_alias; + dis_riscv_csr_alias_type_t drca_type; + const char *drca_base; + const char *drca_csr; + int drca_rd; + int drca_rs; +} dis_riscv_csr_alias_t; + +/* + * Table of aliases. A NULL or -1 indicates a don't care. + */ +static dis_riscv_csr_alias_t dis_riscv_csr_alias[] = { + { "rdinstret", DIS_RISCV_CSR_READ, "csrrs", "instret", -1, 0 }, + { "rdinstreth", DIS_RISCV_CSR_READ, "csrrs", "instreth", -1, 0 }, + { "rdcycle", DIS_RISCV_CSR_READ, "csrrs", "cycle", -1, 0 }, + { "rdcycleh", DIS_RISCV_CSR_READ, "csrrs", "cycleh", -1, 0 }, + { "rdtime", DIS_RISCV_CSR_READ, "csrrs", "time", -1, 0 }, + { "rdtimeh", DIS_RISCV_CSR_READ, "csrrs", "timeh", -1, 0 }, + { "frcsr", DIS_RISCV_CSR_READ, "csrrs", "fcsr", -1, 0 }, + { "fscsr", DIS_RISCV_CSR_WRITE, "csrrw", "fcsr", 0, -1 }, + { "fscsr", DIS_RISCV_CSR_SWAP, "csrrw", "fcsr", -1, -1 }, + { "frrm", DIS_RISCV_CSR_READ, "csrrs", "frm", -1, 0 }, + { "fsrm", DIS_RISCV_CSR_WRITE, "csrrw", "frm", 0, -1 }, + { "fsrm", DIS_RISCV_CSR_SWAP, "csrrw", "frm", -1, -1 }, + { "fsrmi", DIS_RISCV_CSR_WRITE_IMM, "csrrwi", "frm", 0, -1 }, + { "fsrmi", DIS_RISCV_CSR_SWAP_IMM, "csrrwi", "frm", -1, -1 }, + { "frflags", DIS_RISCV_CSR_READ, "csrrs", "fflags", -1, 0 }, + { "fsflags", DIS_RISCV_CSR_WRITE, "csrrw", "fflags", 0, -1 }, + { "fsflags", DIS_RISCV_CSR_SWAP, "csrrw", "fflags", -1, -1 }, + { "fsflagsi", DIS_RISCV_CSR_WRITE_IMM, "csrrwi", "fflags", 0, -1 }, + { "fsflagsi", DIS_RISCV_CSR_SWAP_IMM, "csrrwi", "fflags", -1, -1 }, + /* + * These are the generic aliases that aren't based on the CSR. Keep + * them last. + */ + { "csrr", DIS_RISCV_CSR_READ_GEN, "csrrs", NULL, -1, 0 }, + { "csrw", DIS_RISCV_CSR_WRITE_GEN, "csrrw", NULL, 0, -1 }, + { "csrs", DIS_RISCV_CSR_WRITE_GEN, "csrrs", NULL, 0, -1 }, + { "csrc", DIS_RISCV_CSR_WRITE_GEN, "csrrc", NULL, 0, -1 }, + { "csrwi", DIS_RISCV_CSR_WRITE_IMM_GEN, "csrrwi", NULL, 0, -1 }, + { "csrsi", DIS_RISCV_CSR_WRITE_IMM_GEN, "csrrsi", NULL, 0, -1 }, + { "csrci", DIS_RISCV_CSR_WRITE_IMM_GEN, "csrrci", NULL, 0, -1 }, +}; + +/* + * Take an n-bit value whose sign bit is indicated by the big sign and convert + * to a signed type. + */ +static uint_t +dis_riscv_sign_extend(uint_t val, uint_t sbit, const char **sign) +{ + VERIFY3U(sbit, <=, 31); + + if (val >= 1 << sbit) { + *sign = "-"; + return ((1 << (sbit + 1)) - val); + } else { + *sign = ""; + return (val); + } +} + +/* + * Four byte decode tables. This is derived from the RV32/64G Instruction Set + * Listings. We describe a table entry based on the opcode and optional opcodes + * based on the type of instruction that it is and its encoding format. Most + * sets of instructions have one of several uniform encoding types. + * + * 31 25 24 20 19 15 14 12 11 7 6 0 + * | funct7 | r2 | rs1 | funct3 | rd | opcode | R-type + * | imm[11:0] | rs1 | funct3 | rd | opcode | I-type + * | imm[11:5] | r2 | rs1 | funct3 | imm[4:0] | opcode | S-type + * | imm[12|10:5] | r2 | rs1 | funct3 | imm[4:1|11] | opcode | B-type + * | imm[31:12] | rd | opcode | U-type + * | imm[10|10:1|11|19:12] | rd | opcode | J-type + */ +typedef enum dis_riscv_itype { + DIS_RISCV_I_R_TYPE, + DIS_RISCV_I_I_TYPE, + DIS_RISCV_I_S_TYPE, + DIS_RISCV_I_B_TYPE, + DIS_RISCV_I_U_TYPE, + DIS_RISCV_I_J_TYPE, + DIS_RISCV_I_R4_TYPE, + /* + * This is a variant of the standard R type where the first bit of + * funct7 is actually used for this shift. + */ + DIS_RISCV_I_SHIFT64_TYPE, + /* + * This type isn't explicitly defined in the ISA doc; however, it is a + * standard format that is for all of the Atomic class instructions. + * This is treated like an R-type, except the funct7 is really a funct5. + * The load variant is similar; however, rs2 must be zero. + */ + DIS_RISCV_I_RV32A_TYPE, + DIS_RISCV_I_RV32A_LOAD_TYPE, + /* + * This is a custom type we've defined where the first value is the + * instruction mask and the second value is the value of the bits in it. + * This is used for a few irregular instructions ala FENCE and ECALL. + */ + DIS_RISCV_I_MASK_TYPE, + /* + * This type is used for FP arguments that use rs2 as an opcode. + */ + DIS_RISCV_I_FP_RS2OP_TYPE, + /* + * This type uses the opcode and funct7 and uses funct3 as a rounding + * mode argument. + */ + DIS_RISCV_I_FP_RM_TYPE, + /* + * This fp type uses the opcode, funct7, funct3, and rs2 as an op type. + */ + DIS_RISCV_I_FP_R_RS2_TYPE, +} dis_riscv_itype_t; + +#define DIS_RISCV_OPCODE(x) ((x) & 0x7f) +#define DIS_RISCV_FUNCT3(x) (((x) >> 12) & 0x7) +#define DIS_RISCV_FUNCT7(x) (((x) >> 25) & 0x7f) +#define DIS_RISCV_RD(x) (((x) >> 7) & 0x1f) +#define DIS_RISCV_RS1(x) (((x) >> 15) & 0x1f) +#define DIS_RISCV_RS2(x) (((x) >> 20) & 0x1f) +#define DIS_RISCV_FP_RS3(x) (((x) >> 27) & 0x1f) +#define DIS_RISCV_FUNCT2(x) (((x) >> 25) & 0x03) + +/* + * SHIFT funct7 variant. + */ +#define DIS_RISCV_SFUNCT7(x) (((x) >> 26) & 0x3f) + +#define DIS_RISCV_UIMM(x) (((x) >> 12) & 0xfffff) + +#define DIS_RISCV_IIMM(x) (((x) >> 20) & 0xfff) + +#define DIS_RISCV_BIMM_12(x) (((x) >> 19) & 0x1000) +#define DIS_RISCV_BIMM_11(x) (((x) & 0x80) << 4) +#define DIS_RISCV_BIMM_10_5(x) (((x) >> 20) & 0x7e0) +#define DIS_RISCV_BIMM_4_1(x) (((x) >> 7) & 0x1e) + +#define DIS_RISCV_SIMM_UP(x) ((((x) >> 25) & 0x7f) << 5) +#define DIS_RISCV_SIMM_LOW(x) (((x) >> 7) & 0x1f) + +#define DIS_RISCV_JIMM_20(x) (((x) & 0x80000000) >> 11) +#define DIS_RISCV_JIMM_19_12(x) ((x) & 0xff000) +#define DIS_RISCV_JIMM_11(x) (((x) & 100000) >> 9) +#define DIS_RISCV_JIMM_10_1(x) (((x) & 0x7fe00000) >> 20) + +#define DIS_RISCV_RVA_FUNCT5(x) (((x) >> 27) & 0x1f) +#define DIS_RISCV_RVA_AQ(x) (((x) >> 26) & 0x1) +#define DIS_RISCV_RVA_RL(x) (((x) >> 25) & 0x1) + +struct dis_riscv_instr; +typedef void (*dis_riscv_func_t)(dis_handle_t *, uint32_t, + struct dis_riscv_instr *, char *, size_t); + +typedef struct dis_riscv_instr { + const char *drv_name; + dis_riscv_itype_t drv_type; + dis_riscv_func_t drv_print; + uint_t drv_opcode; + uint_t drv_funct3; + uint_t drv_funct7; + uint_t drv_funct2; +} dis_riscv_instr_t; + +/*ARGSUSED*/ +static void +dis_riscv_rtype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, + dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], + dis_riscv_regs[DIS_RISCV_RS2(instr)]); +} + +static void +dis_riscv_itype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t imm = dis_riscv_sign_extend(DIS_RISCV_IIMM(instr), 11, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0%o", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0x%x", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); + } +} + +static void +dis_riscv_btype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t bimm = DIS_RISCV_BIMM_12(instr) | DIS_RISCV_BIMM_11(instr) | + DIS_RISCV_BIMM_10_5(instr) | DIS_RISCV_BIMM_4_1(instr); + uint_t imm = dis_riscv_sign_extend(bimm, 12, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0%o", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s0x%x", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], s, imm); + } +} + +static void +dis_riscv_load(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t imm = dis_riscv_sign_extend(DIS_RISCV_IIMM(instr), 11, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } +} + +static void +dis_riscv_stype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t simm = DIS_RISCV_SIMM_UP(instr) | DIS_RISCV_SIMM_LOW(instr); + uint_t val = dis_riscv_sign_extend(simm, 11, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", + table->drv_name, dis_riscv_regs[DIS_RISCV_RS2(instr)], + s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", + table->drv_name, dis_riscv_regs[DIS_RISCV_RS2(instr)], + s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } +} + +/*ARGSUSED*/ +static void +dis_riscv_utype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,0x%x", table->drv_name, + dis_riscv_regs[DIS_RISCV_RD(instr)], DIS_RISCV_UIMM(instr)); +} + +static void +dis_riscv_jtype_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t jimm = DIS_RISCV_JIMM_20(instr) | DIS_RISCV_JIMM_19_12(instr) | + DIS_RISCV_JIMM_11(instr) | DIS_RISCV_JIMM_10_1(instr); + uint_t imm = dis_riscv_sign_extend(jimm, 20, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s0%o", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + s, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + s, imm); + } +} + +/* + * The shift instructions are a variant on the R-type instructions where RS2 is + * an immediate to perform the shift by as opposed to a register. + */ +static void +dis_riscv_shift_32(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s,0%o", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], DIS_RISCV_RS2(instr)); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s,0x%x", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], DIS_RISCV_RS2(instr)); + } +} + +/* + * The 64-bit version of shift instructions steals an extra bit from funct7 to + * construct the shift amount. + */ +static void +dis_riscv_shift_64(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + uint_t shift = DIS_RISCV_RS2(instr) | ((instr & (1UL << 25)) >> 20); + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s,0%o", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], shift); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s,0x%x", + table->drv_name, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], shift); + } +} + +/*ARGSUSED*/ +static void +dis_riscv_csr(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + uint_t rd, csr, rs, i; + const char *csrstr = NULL; + char csrval[32]; + dis_riscv_csr_alias_t *alias = NULL; + + rd = DIS_RISCV_RD(instr); + rs = DIS_RISCV_RS1(instr); + csr = DIS_RISCV_IIMM(instr); + + for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_map); i++) { + if (csr == dis_riscv_csr_map[i].drc_val) { + csrstr = dis_riscv_csr_map[i].drc_name; + break; + } + } + + if (csrstr == NULL) { + (void) dis_snprintf(csrval, sizeof (csrval), "0x%x", csr); + csrstr = csrval; + } + + for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_alias); i++) { + dis_riscv_csr_alias_t *a = &dis_riscv_csr_alias[i]; + if (strcmp(a->drca_base, table->drv_name) != 0) + continue; + if (a->drca_csr != NULL && strcmp(a->drca_csr, csrstr) != 0) + continue; + if (a->drca_rd != -1 && a->drca_rd != rd) + continue; + if (a->drca_rs != -1 && a->drca_rs != rs) + continue; + alias = a; + break; + } + + if (alias == NULL) { + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, + dis_riscv_regs[rd], csrstr, dis_riscv_regs[rs]); + return; + } + + switch (alias->drca_type) { + case DIS_RISCV_CSR_READ: + (void) dis_snprintf(buf, buflen, "%s %s", alias->drca_alias, + dis_riscv_regs[rd]); + break; + case DIS_RISCV_CSR_READ_GEN: + (void) dis_snprintf(buf, buflen, "%s %s,%s", alias->drca_alias, + dis_riscv_regs[rd], csrstr); + break; + case DIS_RISCV_CSR_SWAP: + (void) dis_snprintf(buf, buflen, "%s %s,%s", alias->drca_alias, + dis_riscv_regs[rd], dis_riscv_regs[rs]); + break; + case DIS_RISCV_CSR_WRITE: + (void) dis_snprintf(buf, buflen, "%s %s", alias->drca_alias, + dis_riscv_regs[rs]); + break; + case DIS_RISCV_CSR_WRITE_GEN: + (void) dis_snprintf(buf, buflen, "%s %s,%s", alias->drca_alias, + csrstr, dis_riscv_regs[rs]); + break; + default: + (void) dis_snprintf(buf, buflen, "<unknown>"); + break; + } +} + +static void +dis_riscv_csri(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + uint_t rd, csr, imm, i; + const char *csrstr = NULL; + char csrval[32]; + dis_riscv_csr_alias_t *alias = NULL; + + rd = DIS_RISCV_RD(instr); + imm = DIS_RISCV_RS1(instr); + csr = DIS_RISCV_IIMM(instr); + + for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_map); i++) { + if (csr == dis_riscv_csr_map[i].drc_val) { + csrstr = dis_riscv_csr_map[i].drc_name; + break; + } + } + + if (csrstr == NULL) { + (void) dis_snprintf(csrval, sizeof (csrval), "0x%x", csr); + csrstr = csrval; + } + + for (i = 0; i < ARRAY_SIZE(dis_riscv_csr_alias); i++) { + dis_riscv_csr_alias_t *a = &dis_riscv_csr_alias[i]; + if (strcmp(a->drca_base, table->drv_name) != 0) + continue; + if (a->drca_csr != NULL && strcmp(a->drca_csr, csrstr) != 0) + continue; + if (a->drca_rd != -1 && a->drca_rd != rd) + continue; + if (a->drca_rs != -1) + continue; + alias = a; + break; + } + + if (alias == NULL) { + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s,0%o", + table->drv_name, dis_riscv_regs[rd], csrstr, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s,0x%x", + table->drv_name, dis_riscv_regs[rd], csrstr, imm); + } + return; + } + + switch (alias->drca_type) { + case DIS_RISCV_CSR_SWAP_IMM: + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,0%o", + alias->drca_alias, dis_riscv_regs[rd], imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,0x%x", + alias->drca_alias, dis_riscv_regs[rd], imm); + } + break; + case DIS_RISCV_CSR_WRITE_IMM: + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s 0%o", + alias->drca_alias, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s 0x%x", + alias->drca_alias, imm); + } + break; + case DIS_RISCV_CSR_WRITE_IMM_GEN: + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,0%o", + alias->drca_alias, csrstr, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,0x%x", + alias->drca_alias, csrstr, imm); + } + break; + default: + (void) dis_snprintf(buf, buflen, "<unknown>"); + break; + } +} + +#define DIS_RISCV_FENCE_PRED(x) (((x) >> 24) & 0xf) +#define DIS_RISCV_FENCE_SUCC(x) (((x) >> 20) & 0xf) +#define DIS_RISCV_FENCE_I 0x8 +#define DIS_RISCV_FENCE_O 0x4 +#define DIS_RISCV_FENCE_R 0x2 +#define DIS_RISCV_FENCE_W 0x1 +#define DIS_RISCV_FENCE_IORW 0xf + +/*ARGSUSED*/ +static void +dis_riscv_fence(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + uint_t pred, succ; + + pred = DIS_RISCV_FENCE_PRED(instr); + succ = DIS_RISCV_FENCE_SUCC(instr); + + /* + * If both halves are iorw that is aliased to just an empty fence + * instruction per Chapter 20 - RISC-V Assembly Programmer's Handbook in + * the RISC-V user spec. + */ + if (pred == DIS_RISCV_FENCE_IORW && succ == DIS_RISCV_FENCE_IORW) { + (void) dis_snprintf(buf, buflen, "%s", table->drv_name); + return; + } + + (void) dis_snprintf(buf, buflen, "%s %s%s%s%s, %s%s%s%s", + table->drv_name, + pred & DIS_RISCV_FENCE_I ? "i" : "", + pred & DIS_RISCV_FENCE_O ? "o" : "", + pred & DIS_RISCV_FENCE_R ? "r" : "", + pred & DIS_RISCV_FENCE_W ? "w" : "", + succ & DIS_RISCV_FENCE_I ? "i" : "", + succ & DIS_RISCV_FENCE_O ? "o" : "", + succ & DIS_RISCV_FENCE_R ? "r" : "", + succ & DIS_RISCV_FENCE_W ? "w" : ""); +} + +/*ARGSUSED*/ +static void +dis_riscv_name(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s", table->drv_name); +} + +/*ARGSUSED*/ +static void +dis_riscv_rs1_rs2(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, + dis_riscv_regs[DIS_RISCV_RS1(instr)], + dis_riscv_regs[DIS_RISCV_RS2(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_rv32a_load(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + const char *suffix = ""; + + if (DIS_RISCV_RVA_AQ(instr) && DIS_RISCV_RVA_RL(instr)) { + suffix = ".aqrl"; + } else if (DIS_RISCV_RVA_AQ(instr)) { + suffix = ".aq"; + } else if (DIS_RISCV_RVA_RL(instr)) { + suffix = ".rl"; + } + + (void) dis_snprintf(buf, buflen, "%s%s %s,(%s)", table->drv_name, + suffix, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_rv32a(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *suffix = ""; + + if (DIS_RISCV_RVA_AQ(instr) && DIS_RISCV_RVA_RL(instr)) { + suffix = ".aqrl"; + } else if (DIS_RISCV_RVA_AQ(instr)) { + suffix = ".aq"; + } else if (DIS_RISCV_RVA_RL(instr)) { + suffix = ".rl"; + } + + (void) dis_snprintf(buf, buflen, "%s%s %s,%s,(%s)", table->drv_name, + suffix, dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS2(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)]); +} + +static void +dis_riscv_fp_load(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t imm = dis_riscv_sign_extend(DIS_RISCV_IIMM(instr), 11, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", + table->drv_name, dis_riscv_fpregs[DIS_RISCV_RD(instr)], + s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", + table->drv_name, dis_riscv_fpregs[DIS_RISCV_RD(instr)], + s, imm, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } +} + +static void +dis_riscv_fp_store(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + const char *s; + uint_t simm = DIS_RISCV_SIMM_UP(instr) | DIS_RISCV_SIMM_LOW(instr); + uint_t val = dis_riscv_sign_extend(simm, 11, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s0%o(%s)", + table->drv_name, dis_riscv_fpregs[DIS_RISCV_RS2(instr)], + s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x(%s)", + table->drv_name, dis_riscv_fpregs[DIS_RISCV_RS2(instr)], + s, val, dis_riscv_regs[DIS_RISCV_RS1(instr)]); + } +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_r(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)], + dis_riscv_fpregs[DIS_RISCV_RS2(instr)]); +} + +/* + * Variant of fp_r type that goes to integer destination registers. + */ +/*ARGSUSED*/ +static void +dis_riscv_fp_r_fpi(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s", table->drv_name, + dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)], + dis_riscv_fpregs[DIS_RISCV_RS2(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_r4(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s,%s%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)], + dis_riscv_fpregs[DIS_RISCV_RS2(instr)], + dis_riscv_fpregs[DIS_RISCV_FP_RS3(instr)], + dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_rs2_fp(dis_handle_t *dhp, uint32_t instr, dis_riscv_instr_t *table, + char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)], + dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_rs2_fp_nr(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_rs2_fpi(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s%s", table->drv_name, + dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)], + dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_rs2_ifp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)], + dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_rs2_fpi_nr(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, + dis_riscv_regs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)]); +} + +/*ARGSUSED*/ +static void +dis_riscv_fp_rs2_ifp_nr(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_regs[DIS_RISCV_RS1(instr)]); +} + + +/*ARGSUSED*/ +static void +dis_riscv_fp_rm(dis_handle_t *dhp, uint32_t instr, + dis_riscv_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s,%s%s", table->drv_name, + dis_riscv_fpregs[DIS_RISCV_RD(instr)], + dis_riscv_fpregs[DIS_RISCV_RS1(instr)], + dis_riscv_fpregs[DIS_RISCV_RS2(instr)], + dis_riscv_rm[DIS_RISCV_FUNCT3(instr)]); +} + +#define DIS_RISCV_R32(str, op, f3, f7) \ + { str, DIS_RISCV_I_R_TYPE, dis_riscv_rtype_32, op, f3, f7 } +#define DIS_RISCV_I32(str, op, f3) \ + { str, DIS_RISCV_I_I_TYPE, dis_riscv_itype_32, op, f3 } +#define DIS_RISCV_S32(str, op, f3) \ + { str, DIS_RISCV_I_S_TYPE, dis_riscv_stype_32, op, f3 } +#define DIS_RISCV_B32(str, op, f3) \ + { str, DIS_RISCV_I_B_TYPE, dis_riscv_btype_32, op, f3 } +#define DIS_RISCV_U32(str, op) \ + { str, DIS_RISCV_I_U_TYPE, dis_riscv_utype_32, op } +#define DIS_RISCV_J32(str, op) \ + { str, DIS_RISCV_I_J_TYPE, dis_riscv_jtype_32, op } + +/* + * These are non-standard types that we've defined because they require + * different handling. + */ +#define DIS_RISCV_SHIFT32(str, op, f3, f7) \ + { str, DIS_RISCV_I_R_TYPE, dis_riscv_shift_32, op, f3, f7 } +#define DIS_RISCV_SHIFT64(str, op, f3, f7) \ + { str, DIS_RISCV_I_SHIFT64_TYPE, dis_riscv_shift_64, op, f3, f7 } +#define DIS_RISCV_CSR(str, op, f3) \ + { str, DIS_RISCV_I_I_TYPE, dis_riscv_csr, op, f3 } +#define DIS_RISCV_CSRI(str, op, f3) \ + { str, DIS_RISCV_I_I_TYPE, dis_riscv_csri, op, f3 } +#define DIS_RISCV_LOAD(str, op, f3) \ + { str, DIS_RISCV_I_I_TYPE, dis_riscv_load, op, f3 } + +#define DIS_RISCV_MASK(str, mask, val, func) \ + { str, DIS_RISCV_I_MASK_TYPE, func, mask, val } + + +/* + * Atomic-extension specific entries + */ +#define DIS_RISCV_A32(str, op, f3, f5) \ + { str, DIS_RISCV_I_RV32A_TYPE, dis_riscv_rv32a, op, f3, f5 } +#define DIS_RISCV_A32LOAD(str, op, f3, f5, f2) \ + { str, DIS_RISCV_I_RV32A_LOAD_TYPE, dis_riscv_rv32a_load, op, f3, \ + f5, f2 } + +/* + * Floating-point specific entries + */ +#define DIS_RISCV_FP_LOAD(str, op, f3) \ + { str, DIS_RISCV_I_I_TYPE, dis_riscv_fp_load, op, f3 } +#define DIS_RISCV_FP_STORE(str, op, f3) \ + { str, DIS_RISCV_I_S_TYPE, dis_riscv_fp_store, op, f3 } +#define DIS_RISCV_FP_R(str, op, f3, f7) \ + { str, DIS_RISCV_I_R_TYPE, dis_riscv_fp_r, op, f3, f7 } +#define DIS_RISCV_FP_R4(str, op, f2) \ + { str, DIS_RISCV_I_R4_TYPE, dis_riscv_fp_r4, op, 0, 0, f2 } +#define DIS_RISCV_FP_RS2_FP(str, op, rs2, f7) \ + { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_fp, op, rs2, f7 } +#define DIS_RISCV_FP_RS2_FP_NR(str, op, rs2, f7) \ + { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_fp_nr, op, rs2, f7 } +#define DIS_RISCV_FP_RS2_FPI(str, op, rs2, f7) \ + { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_fpi, op, rs2, f7 } +#define DIS_RISCV_FP_RS2_IFP(str, op, rs2, f7) \ + { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_ifp, op, rs2, f7 } +#define DIS_RISCV_FP_RS2_IFP_NR(str, op, rs2, f7) \ + { str, DIS_RISCV_I_FP_RS2OP_TYPE, dis_riscv_fp_rs2_ifp_nr, op, rs2, f7 } +#define DIS_RISCV_FP_RM(str, op, f7) \ + { str, DIS_RISCV_I_FP_RM_TYPE, dis_riscv_fp_rm, op, 0, f7 } +#define DIS_RISCV_FP_R_RS2_FPI(str, op, f3, rs2, f7) \ + { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_fpi, op, f3, f7, \ + rs2 } +#define DIS_RISCV_FP_R_RS2_IFP(str, op, f3, rs2, f7) \ + { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_ifp, op, f3, f7, \ + rs2 } +#define DIS_RISCV_FP_R_RS2_FPI_NR(str, op, f3, rs2, f7) \ + { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_fpi_nr, op, f3, \ + f7, rs2 } +#define DIS_RISCV_FP_R_RS2_IFP_NR(str, op, f3, rs2, f7) \ + { str, DIS_RISCV_I_FP_R_RS2_TYPE, dis_riscv_fp_rs2_ifp_nr, op, f3, \ + f7, rs2 } +#define DIS_RISCV_FP_RI(str, op, f3, f7) \ + { str, DIS_RISCV_I_R_TYPE, dis_riscv_fp_r_fpi, op, f3, f7 } + +/* + * This table is ordered such that it follows the ordering in the RISC-V ISA + * Manual. + */ +static dis_riscv_instr_t dis_riscv_4byte[] = { + /* + * RV32I + */ + DIS_RISCV_U32("lui", 0x37), + DIS_RISCV_U32("auipc", 0x17), + DIS_RISCV_J32("jal", 0x6f), + /* ret is a special case of jalr */ + DIS_RISCV_MASK("ret", 0xffffffff, 0x00008067, dis_riscv_name), + DIS_RISCV_I32("jalr", 0x67, 0x0), + DIS_RISCV_B32("beq", 0x63, 0x0), + DIS_RISCV_B32("bne", 0x63, 0x1), + DIS_RISCV_B32("blt", 0x63, 0x4), + DIS_RISCV_B32("bge", 0x63, 0x5), + DIS_RISCV_B32("bltu", 0x63, 0x6), + DIS_RISCV_B32("bgeu", 0x63, 0x7), + DIS_RISCV_LOAD("lb", 0x03, 0x0), + DIS_RISCV_LOAD("lh", 0x03, 0x1), + DIS_RISCV_LOAD("lw", 0x03, 0x2), + DIS_RISCV_LOAD("lbu", 0x03, 0x4), + DIS_RISCV_LOAD("lhu", 0x03, 0x5), + DIS_RISCV_S32("sb", 0x23, 0x0), + DIS_RISCV_S32("sh", 0x23, 0x1), + DIS_RISCV_S32("sw", 0x23, 0x2), + /* nop is addi x0, x0, 0 */ + DIS_RISCV_MASK("nop", 0xffffffff, 0x00000013, dis_riscv_name), + DIS_RISCV_I32("addi", 0x13, 0x0), + DIS_RISCV_I32("slti", 0x13, 0x2), + DIS_RISCV_I32("sltiu", 0x13, 0x3), + DIS_RISCV_I32("xori", 0x13, 0x4), + DIS_RISCV_I32("ori", 0x13, 0x6), + DIS_RISCV_I32("andi", 0x13, 0x7), + DIS_RISCV_SHIFT32("slli", 0x13, 0x1, 0x00), + DIS_RISCV_SHIFT32("srli", 0x13, 0x5, 0x00), + DIS_RISCV_SHIFT32("srai", 0x13, 0x5, 0x20), + DIS_RISCV_R32("add", 0x33, 0x0, 0x00), + DIS_RISCV_R32("sub", 0x33, 0x0, 0x20), + DIS_RISCV_R32("sll", 0x33, 0x1, 0x00), + DIS_RISCV_R32("slt", 0x33, 0x2, 0x00), + DIS_RISCV_R32("sltu", 0x33, 0x3, 0x00), + DIS_RISCV_R32("xor", 0x33, 0x4, 0x00), + DIS_RISCV_R32("srl", 0x33, 0x5, 0x00), + DIS_RISCV_R32("sra", 0x33, 0x5, 0x20), + DIS_RISCV_R32("or", 0x33, 0x6, 0x00), + DIS_RISCV_R32("and", 0x33, 0x7, 0x00), + DIS_RISCV_MASK("fence", 0xf00fffff, 0xf, dis_riscv_fence), + DIS_RISCV_MASK("fence.i", 0xfffff00f, 0x100f, dis_riscv_name), + DIS_RISCV_MASK("ecall", 0xffffffff, 0x73, dis_riscv_name), + DIS_RISCV_MASK("ebreak", 0xffffffff, 0x100073, dis_riscv_name), + DIS_RISCV_CSR("csrrw", 0x73, 0x1), + DIS_RISCV_CSR("csrrs", 0x73, 0x2), + DIS_RISCV_CSR("csrrc", 0x73, 0x3), + DIS_RISCV_CSRI("csrrwi", 0x73, 0x5), + DIS_RISCV_CSRI("csrrsi", 0x73, 0x6), + DIS_RISCV_CSRI("csrrci", 0x73, 0x7), + /* + * RV64I + */ + DIS_RISCV_LOAD("lwu", 0x03, 0x6), + DIS_RISCV_LOAD("ld", 0x03, 0x3), + DIS_RISCV_S32("sd", 0x23, 0x3), + DIS_RISCV_SHIFT64("slli", 0x13, 0x1, 0x0), + DIS_RISCV_SHIFT64("srli", 0x13, 0x5, 0x0), + DIS_RISCV_SHIFT64("srai", 0x13, 0x5, 0x10), + DIS_RISCV_I32("addiw", 0x1b, 0x0), + DIS_RISCV_SHIFT32("slliw", 0x1b, 0x1, 0x0), + DIS_RISCV_SHIFT32("srliw", 0x1b, 0x5, 0x0), + DIS_RISCV_SHIFT32("sraiw", 0x1b, 0x5, 0x20), + DIS_RISCV_R32("addw", 0x3b, 0x0, 0x00), + DIS_RISCV_R32("subw", 0x3b, 0x0, 0x20), + DIS_RISCV_R32("sllw", 0x3b, 0x1, 0x00), + DIS_RISCV_R32("srlw", 0x3b, 0x5, 0x00), + DIS_RISCV_R32("sraw", 0x3b, 0x5, 0x20), + /* + * RV32M + */ + DIS_RISCV_R32("mul", 0x33, 0x0, 0x01), + DIS_RISCV_R32("mulh", 0x33, 0x1, 0x01), + DIS_RISCV_R32("mulhsu", 0x33, 0x2, 0x01), + DIS_RISCV_R32("mulhu", 0x33, 0x3, 0x01), + DIS_RISCV_R32("div", 0x33, 0x4, 0x01), + DIS_RISCV_R32("divu", 0x33, 0x5, 0x01), + DIS_RISCV_R32("rem", 0x33, 0x6, 0x01), + DIS_RISCV_R32("remu", 0x33, 0x7, 0x01), + /* + * RV64M + */ + DIS_RISCV_R32("mulw", 0x3b, 0x0, 0x01), + DIS_RISCV_R32("divw", 0x3b, 0x4, 0x01), + DIS_RISCV_R32("divuw", 0x3b, 0x5, 0x01), + DIS_RISCV_R32("remw", 0x3b, 0x6, 0x01), + DIS_RISCV_R32("remuw", 0x3b, 0x7, 0x01), + /* + * RV32A + */ + DIS_RISCV_A32LOAD("lr.w", 0x2f, 0x2, 0x02, 0x0), + DIS_RISCV_A32("sc.w", 0x2f, 0x2, 0x03), + DIS_RISCV_A32("amoswap.w", 0x2f, 0x2, 0x01), + DIS_RISCV_A32("amoadd.w", 0x2f, 0x2, 0x00), + DIS_RISCV_A32("amoxor.w", 0x2f, 0x2, 0x04), + DIS_RISCV_A32("amoand.w", 0x2f, 0x2, 0x0c), + DIS_RISCV_A32("amoor.w", 0x2f, 0x2, 0x08), + DIS_RISCV_A32("amomin.w", 0x2f, 0x2, 0x10), + DIS_RISCV_A32("amomax.w", 0x2f, 0x2, 0x14), + DIS_RISCV_A32("amominu.w", 0x2f, 0x2, 0x18), + DIS_RISCV_A32("amomaxu.w", 0x2f, 0x2, 0x1c), + /* + * RV64A + */ + DIS_RISCV_A32LOAD("lr.d", 0x2f, 0x3, 0x02, 0x0), + DIS_RISCV_A32("sc.d", 0x2f, 0x3, 0x03), + DIS_RISCV_A32("amoswap.d", 0x2f, 0x3, 0x01), + DIS_RISCV_A32("amoadd.d", 0x2f, 0x3, 0x00), + DIS_RISCV_A32("amoxor.d", 0x2f, 0x3, 0x04), + DIS_RISCV_A32("amoand.d", 0x2f, 0x3, 0x0c), + DIS_RISCV_A32("amoor.d", 0x2f, 0x3, 0x08), + DIS_RISCV_A32("amomin.d", 0x2f, 0x3, 0x10), + DIS_RISCV_A32("amomax.d", 0x2f, 0x3, 0x14), + DIS_RISCV_A32("amominu.d", 0x2f, 0x3, 0x18), + DIS_RISCV_A32("amomaxu.d", 0x2f, 0x3, 0x1c), + /* + * RV32F + */ + DIS_RISCV_FP_LOAD("flw", 0x07, 0x2), + DIS_RISCV_FP_STORE("fsw", 0x27, 0x2), + DIS_RISCV_FP_R4("fmadd.s", 0x43, 0x0), + DIS_RISCV_FP_R4("fmsub.s", 0x47, 0x0), + DIS_RISCV_FP_R4("fnmsub.s", 0x4b, 0x0), + DIS_RISCV_FP_R4("fnmadd.s", 0x4f, 0x0), + DIS_RISCV_FP_RM("fadd.s", 0x53, 0x00), + DIS_RISCV_FP_RM("fsub.s", 0x53, 0x04), + DIS_RISCV_FP_RM("fmul.s", 0x53, 0x08), + DIS_RISCV_FP_RM("fdiv.s", 0x53, 0xc), + DIS_RISCV_FP_RS2_FP("fsqrt.s", 0x53, 0x00, 0x2c), + DIS_RISCV_FP_R("fsgnj.s", 0x53, 0x0, 0x10), + DIS_RISCV_FP_R("fsgnjn.s", 0x53, 0x1, 0x10), + DIS_RISCV_FP_R("fsgnjx.s", 0x53, 0x2, 0x10), + DIS_RISCV_FP_R("fmin.s", 0x53, 0x0, 0x14), + DIS_RISCV_FP_R("fmax.s", 0x53, 0x1, 0x14), + DIS_RISCV_FP_RS2_FPI("fcvt.w.s", 0x53, 0x00, 0x60), + DIS_RISCV_FP_RS2_FPI("fcvt.wu.s", 0x53, 0x01, 0x60), + DIS_RISCV_FP_R_RS2_FPI_NR("fmv.x.w", 0x53, 0x00, 0x00, 0x70), + DIS_RISCV_FP_RI("feq.s", 0x53, 0x2, 0x50), + DIS_RISCV_FP_RI("flt.s", 0x53, 0x1, 0x50), + DIS_RISCV_FP_RI("fle.s", 0x53, 0x0, 0x50), + DIS_RISCV_FP_R_RS2_FPI_NR("fclass.s", 0x53, 0x1, 0x00, 0x70), + DIS_RISCV_FP_RS2_IFP("fcvt.s.w", 0x53, 0x00, 0x68), + DIS_RISCV_FP_RS2_IFP("fcvt.s.wu", 0x53, 0x01, 0x68), + DIS_RISCV_FP_R_RS2_IFP_NR("fmv.w.x", 0x53, 0x0, 0x00, 0x78), + /* + * RV64F + */ + DIS_RISCV_FP_RS2_FPI("fcvt.l.s", 0x53, 0x02, 0x60), + DIS_RISCV_FP_RS2_FPI("fcvt.lu.s", 0x53, 0x03, 0x60), + DIS_RISCV_FP_RS2_IFP("fcvt.s.l", 0x53, 0x02, 0x68), + DIS_RISCV_FP_RS2_IFP("fcvt.s.lu", 0x53, 0x03, 0x68), + /* + * RV32D + */ + DIS_RISCV_FP_LOAD("fld", 0x07, 0x3), + DIS_RISCV_FP_STORE("fsd", 0x27, 0x3), + DIS_RISCV_FP_R4("fmadd.d", 0x43, 0x1), + DIS_RISCV_FP_R4("fmsub.d", 0x47, 0x1), + DIS_RISCV_FP_R4("fnmsub.d", 0x4b, 0x1), + DIS_RISCV_FP_R4("fnmadd.d", 0x4f, 0x1), + DIS_RISCV_FP_RM("fadd.d", 0x53, 0x01), + DIS_RISCV_FP_RM("fsub.d", 0x53, 0x05), + DIS_RISCV_FP_RM("fmul.d", 0x53, 0x09), + DIS_RISCV_FP_RM("fdiv.d", 0x53, 0xd), + DIS_RISCV_FP_RS2_FP("fsqrt.d", 0x53, 0x00, 0x2d), + DIS_RISCV_FP_R("fsgnj.d", 0x53, 0x0, 0x11), + DIS_RISCV_FP_R("fsgnjn.d", 0x53, 0x1, 0x11), + DIS_RISCV_FP_R("fsgnjx.d", 0x53, 0x2, 0x11), + DIS_RISCV_FP_R("fmin.d", 0x53, 0x0, 0x15), + DIS_RISCV_FP_R("fmax.d", 0x53, 0x1, 0x15), + DIS_RISCV_FP_RS2_FP("fcvt.s.d", 0x53, 0x01, 0x20), + DIS_RISCV_FP_RS2_FP_NR("fcvt.d.s", 0x53, 0x00, 0x21), + DIS_RISCV_FP_RI("feq.d", 0x53, 0x2, 0x51), + DIS_RISCV_FP_RI("flt.d", 0x53, 0x1, 0x51), + DIS_RISCV_FP_RI("fle.d", 0x53, 0x0, 0x51), + DIS_RISCV_FP_R_RS2_FPI_NR("fclass.d", 0x53, 0x1, 0x00, 0x71), + DIS_RISCV_FP_RS2_FPI("fcvt.w.d", 0x53, 0x00, 0x61), + DIS_RISCV_FP_RS2_FPI("fcvt.wu.d", 0x53, 0x01, 0x61), + DIS_RISCV_FP_RS2_IFP_NR("fcvt.d.w", 0x53, 0x00, 0x69), + DIS_RISCV_FP_RS2_IFP_NR("fcvt.d.wu", 0x53, 0x01, 0x69), + /* + * RV64D + */ + DIS_RISCV_FP_RS2_FPI("fcvt.l.d", 0x53, 0x02, 0x61), + DIS_RISCV_FP_RS2_FPI("fcvt.lu.d", 0x53, 0x03, 0x61), + DIS_RISCV_FP_R_RS2_FPI_NR("fmv.x.d", 0x53, 0x0, 0x00, 0x71), + DIS_RISCV_FP_RS2_IFP("fcvt.d.l", 0x53, 0x02, 0x69), + DIS_RISCV_FP_RS2_IFP("fcvt.d.lu", 0x53, 0x03, 0x69), + DIS_RISCV_FP_R_RS2_IFP_NR("fmv.d.x", 0x53, 0x0, 0x00, 0x79), + /* + * Privileged Instructions from RISC-V Privileged Architectures V1.10. + */ + DIS_RISCV_MASK("uret", 0xffffffff, 0x00200073, dis_riscv_name), + DIS_RISCV_MASK("sret", 0xffffffff, 0x10200073, dis_riscv_name), + DIS_RISCV_MASK("mret", 0xffffffff, 0x30200073, dis_riscv_name), + DIS_RISCV_MASK("wfi", 0xffffffff, 0x10500073, dis_riscv_name), + DIS_RISCV_MASK("sfence.vma", 0xfe007fff, 0x12000073, dis_riscv_rs1_rs2) +}; + +static void +dis_riscv_decode_4byte(dis_handle_t *dhp, uint32_t instr, char *buf, + size_t buflen) +{ + uint_t i; + + for (i = 0; i < ARRAY_SIZE(dis_riscv_4byte); i++) { + dis_riscv_instr_t *t = &dis_riscv_4byte[i]; + switch (t->drv_type) { + case DIS_RISCV_I_R_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && + DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { + break; + } + continue; + case DIS_RISCV_I_I_TYPE: + case DIS_RISCV_I_S_TYPE: + case DIS_RISCV_I_B_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT3(instr) == t->drv_funct3) { + break; + } + continue; + case DIS_RISCV_I_U_TYPE: + case DIS_RISCV_I_J_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode) { + break; + } + continue; + case DIS_RISCV_I_R4_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT2(instr) == t->drv_funct2) { + break; + } + continue; + case DIS_RISCV_I_MASK_TYPE: + if ((instr & t->drv_opcode) == t->drv_funct3) { + break; + } + continue; + case DIS_RISCV_I_SHIFT64_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && + DIS_RISCV_SFUNCT7(instr) == t->drv_funct7) { + break; + } + continue; + + case DIS_RISCV_I_RV32A_LOAD_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && + DIS_RISCV_RVA_FUNCT5(instr) == t->drv_funct7 && + DIS_RISCV_RS2(instr) == t->drv_funct2) { + break; + } + continue; + case DIS_RISCV_I_RV32A_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && + DIS_RISCV_RVA_FUNCT5(instr) == t->drv_funct7) { + break; + } + continue; + case DIS_RISCV_I_FP_RS2OP_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_RS2(instr) == t->drv_funct3 && + DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { + break; + } + continue; + case DIS_RISCV_I_FP_RM_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { + break; + } + continue; + case DIS_RISCV_I_FP_R_RS2_TYPE: + if (DIS_RISCV_OPCODE(instr) == t->drv_opcode && + DIS_RISCV_FUNCT3(instr) == t->drv_funct3 && + DIS_RISCV_RS2(instr) == t->drv_funct2 && + DIS_RISCV_FUNCT7(instr) == t->drv_funct7) { + break; + } + continue; + default: + continue; + } + + t->drv_print(dhp, instr, t, buf, buflen); + return; + } + + (void) dis_snprintf(buf, buflen, "<unknown>"); +} + +/* + * Two byte decode table types. + */ +typedef enum dis_riscv_ctype { + /* + * Indicates that we should match based on the opcode and funct3. + */ + DIS_RISCV_C_FUNCT3, + /* + * Indicates that we should match the instruction based on a mask. + */ + DIS_RISCV_C_MATCH +} dis_riscv_ctype_t; + +/* + * The compact forms are depending on the elf class. This is used to keep track + * of the class and match it. + */ +typedef enum dis_riscv_c_class { + DIS_RISCV_CL_ALL, + DIS_RISCV_CL_32, + DIS_RISCV_CL_64, + DIS_RISCV_CL_32_64, + DIS_RISCV_CL_64_128 +} dis_riscv_c_class_t; + +struct dis_riscv_c_instr; +typedef void (*dis_riscv_c_func_t)(dis_handle_t *, uint32_t, + struct dis_riscv_c_instr *, char *, size_t); + +typedef struct dis_riscv_c_instr { + const char *drv_c_name; + dis_riscv_ctype_t drv_c_type; + dis_riscv_c_func_t drv_c_print; + dis_riscv_c_class_t drv_c_class; + uint_t drv_c_opcode; + uint_t drv_c_funct; + uint_t drv_c_mask; + uint_t drv_c_match; +} dis_riscv_c_instr_t; + +#define DIS_RISCV_C_OPCODE(x) ((x) & 0x03) +#define DIS_RISCV_C_FUNCT3(x) (((x) & 0xe000) >> 13) + +#define DIS_RISCV_C_RS1(x) (((x) & 0x0f80) >> 7) +#define DIS_RISCV_C_RS2(x) (((x) & 0x007c) >> 2) +#define DIS_RISCV_C_RD(x) DIS_RISCV_C_RS1(x) + +#define DIS_RISCV_C_RS1P(x) (((x) & 0x0380) >> 7) +#define DIS_RISCV_C_RS2P(x) DIS_RISCV_C_RDP(x) +#define DIS_RISCV_C_RDP(x) (((x) & 0x001c) >> 2) + +/* + * CJ format immediate extractor + */ +#define DIS_RISCV_C_J_11(x) (((x) & 0x1000) >> 1) +#define DIS_RISCV_C_J_4(x) (((x) & 0x0800) >> 7) +#define DIS_RISCV_C_J_9_8(x) (((x) & 0x0600) >> 1) +#define DIS_RISCV_C_J_10(x) (((x) & 0x0100) << 2) +#define DIS_RISCV_C_J_6(x) (((x) & 0x0080) >> 1) +#define DIS_RISCV_C_J_7(x) (((x) & 0x0040) << 1) +#define DIS_RISCV_C_J_3_1(x) (((x) & 0x0038) >> 3) +#define DIS_RISCV_C_J_5(x) (((x) & 0x0004) << 3) + +/* + * Compact Branch extractor + */ +#define DIS_RISCV_C_B_8(x) (((x) & 0x1000) >> 4) +#define DIS_RISCV_C_B_4_3(x) (((x) & 0x0c00) >> 7) +#define DIS_RISCV_C_B_7_6(x) (((x) & 0x0060) << 1) +#define DIS_RISCV_C_B_2_1(x) (((x) & 0x0018) >> 2) +#define DIS_RISCV_C_B_5(x) (((x) & 0x0004) << 3) + +/* + * c.addi16spn extractor + */ +#define DIS_RISCV_C_A16_9(x) (((x) & 0x1000) >> 3) +#define DIS_RISCV_C_A16_4(x) (((x) & 0x0040) >> 2) +#define DIS_RISCV_C_A16_6(x) (((x) & 0x0020) << 1) +#define DIS_RISCV_C_A16_8_7(x) (((x) & 0x0018) << 4) +#define DIS_RISCV_C_A16_5(x) (((x) & 0x0004) << 3) + +/* + * c.addi4spn extractor + */ +#define DIS_RISCV_C_A4_5_4(x) (((x) & 0x1800) >> 7) +#define DIS_RISCV_C_A4_9_6(x) (((x) & 0x0700) >> 2) +#define DIS_RISCV_C_A4_2(x) (((x) & 0x0040) >> 4) +#define DIS_RISCV_C_A4_3(x) (((x) & 0x0020) >> 2) + +/*ARGSUSED*/ +static void +dis_riscv_c_name(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s", table->drv_c_name); +} + +static void +dis_riscv_c_loadstore(dis_handle_t *dhp, const char *name, const char *dreg, + const char *sreg, uint32_t off, char *buf, size_t buflen) +{ + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,0%o(%s)", name, dreg, + off, sreg); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,0x%x(%s)", name, dreg, + off, sreg); + } +} + +static void +dis_riscv_c_lwsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x000c) << 4) | + ((instr & 0x1000) >> 7) | ((instr & 0x0070) >> 2); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], imm, buf, + buflen); +} + +static void +dis_riscv_c_ldsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x001c) << 4) | + ((instr & 0x1000) >> 7) | ((instr & 0x0060) >> 2); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], + imm, buf, buflen); +} + +static void +dis_riscv_c_flwsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x000c) << 4) | + ((instr & 0x1000) >> 7) | ((instr & 0x0070) >> 2); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_fpregs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], + imm, buf, buflen); +} + +static void +dis_riscv_c_fldsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x001c) << 4) | + ((instr & 0x1000) >> 7) | ((instr & 0x0060) >> 2); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_fpregs[DIS_RISCV_C_RD(instr)], dis_riscv_regs[2], + imm, buf, buflen); +} + +static void +dis_riscv_c_swsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0180) >> 1) | ((instr & 0x1e00) >> 7); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, + buf, buflen); +} + +static void +dis_riscv_c_sdsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0380) >> 1) | ((instr & 0x1c00) >> 7); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, + buf, buflen); +} + +static void +dis_riscv_c_fswsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0180) >> 1) | ((instr & 0x1e00) >> 7); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_fpregs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, + buf, buflen); +} + +static void +dis_riscv_c_fsdsp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0380) >> 1) | ((instr & 0x1c00) >> 7); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_fpregs[DIS_RISCV_C_RS2(instr)], dis_riscv_regs[2], imm, + buf, buflen); +} + +static void +dis_riscv_c_lw(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0020) << 1) | ((instr & 0x1c) >> 7) | + ((instr & 0x0040) >> 3); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], + imm, buf, buflen); +} + +static void +dis_riscv_c_ld(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0060) << 1) | ((instr & 0x1c) >> 7); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], + imm, buf, buflen); +} + +static void +dis_riscv_c_flw(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0020) << 1) | ((instr & 0x1c) >> 7) | + ((instr & 0x0040) >> 3); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_c_fpregs[DIS_RISCV_C_RDP(instr)], + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], + imm, buf, buflen); +} + +static void +dis_riscv_c_fld(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint32_t imm = ((instr & 0x0060) << 1) | ((instr & 0x1c) >> 7); + + dis_riscv_c_loadstore(dhp, table->drv_c_name, + dis_riscv_c_fpregs[DIS_RISCV_C_RDP(instr)], + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], + imm, buf, buflen); +} + +/* + * The J type has the 11 bit immediate arranged as: + * + * offset[11|4|9:8|10|6|7|3:1|5] going from bits 2 to 12. + */ +static void +dis_riscv_c_j(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + const char *s; + uint_t jimm = DIS_RISCV_C_J_11(instr) | DIS_RISCV_C_J_10(instr) | + DIS_RISCV_C_J_9_8(instr) | DIS_RISCV_C_J_7(instr) | + DIS_RISCV_C_J_6(instr) | DIS_RISCV_C_J_5(instr) | + DIS_RISCV_C_J_4(instr) | DIS_RISCV_C_J_3_1(instr); + uint_t imm = dis_riscv_sign_extend(jimm, 11, &s); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s0%o", table->drv_c_name, + s, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s0x%x", table->drv_c_name, + s, imm); + } +} + +/*ARGSUSED*/ +static void +dis_riscv_c_jr(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s", table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RS1(instr)]); +} + +static void +dis_riscv_c_regimm(dis_handle_t *dhp, const char *instr, const char *dreg, + const char *sign, uint_t imm, char *buf, size_t buflen) +{ + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,%s0%o", instr, dreg, + sign, imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,%s0x%x", instr, dreg, + sign, imm); + } +} + +static void +dis_riscv_c_branch(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + const char *s; + uint_t bimm = DIS_RISCV_C_B_8(instr) | DIS_RISCV_C_B_7_6(instr) | + DIS_RISCV_C_B_5(instr) | DIS_RISCV_C_B_4_3(instr) | + DIS_RISCV_C_B_2_1(instr); + uint_t imm = dis_riscv_sign_extend(bimm, 8, &s); + + dis_riscv_c_regimm(dhp, table->drv_c_name, + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], s, imm, buf, buflen); +} + +static void +dis_riscv_c_bigimmint(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + const char *s; + uint_t limm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); + uint_t imm = dis_riscv_sign_extend(limm, 5, &s); + + dis_riscv_c_regimm(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RD(instr)], s, imm, buf, buflen); +} + +static void +dis_riscv_c_zext_bigimmint(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint_t imm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); + + dis_riscv_c_regimm(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RD(instr)], "", imm, buf, buflen); +} + +static void +dis_riscv_c_addi16sp(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + const char *s; + uint_t aimm = DIS_RISCV_C_A16_9(instr) | DIS_RISCV_C_A16_8_7(instr) | + DIS_RISCV_C_A16_6(instr) | DIS_RISCV_C_A16_5(instr) | + DIS_RISCV_C_A16_4(instr); + int imm = dis_riscv_sign_extend(aimm, 9, &s); + + dis_riscv_c_regimm(dhp, table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RD(instr)], s, imm, buf, buflen); +} + +static void +dis_riscv_c_addi4spn(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint_t imm = DIS_RISCV_C_A4_9_6(instr) | DIS_RISCV_C_A4_5_4(instr) | + DIS_RISCV_C_A4_3(instr) | DIS_RISCV_C_A4_2(instr); + + if ((dhp->dh_flags & DIS_OCTAL) != 0) { + (void) dis_snprintf(buf, buflen, "%s %s,sp,0%o", + table->drv_c_name, dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], + imm); + } else { + (void) dis_snprintf(buf, buflen, "%s %s,sp,0x%x", + table->drv_c_name, dis_riscv_c_regs[DIS_RISCV_C_RDP(instr)], + imm); + } +} + +static void +dis_riscv_c_immint(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + const char *s; + uint_t limm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); + uint_t imm = dis_riscv_sign_extend(limm, 5, &s); + + dis_riscv_c_regimm(dhp, table->drv_c_name, + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], s, imm, buf, buflen); +} + +static void +dis_riscv_c_zext_immint(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + uint_t imm = ((instr & 0x1000) >> 7) | ((instr & 0x007c) >> 2); + + dis_riscv_c_regimm(dhp, table->drv_c_name, + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], "", imm, buf, buflen); +} + +/*ARGSUSED*/ +static void +dis_riscv_c_bigint(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_c_name, + dis_riscv_regs[DIS_RISCV_C_RD(instr)], + dis_riscv_regs[DIS_RISCV_C_RS2(instr)]); +} + + +/*ARGSUSED*/ +static void +dis_riscv_c_int(dis_handle_t *dhp, uint32_t instr, + dis_riscv_c_instr_t *table, char *buf, size_t buflen) +{ + (void) dis_snprintf(buf, buflen, "%s %s,%s", table->drv_c_name, + dis_riscv_c_regs[DIS_RISCV_C_RS1P(instr)], + dis_riscv_c_regs[DIS_RISCV_C_RS2P(instr)]); +} + +#define DIS_RISCV_CFUNCT3(name, class, op, funct, print) \ + { name, DIS_RISCV_C_FUNCT3, print, class, op, funct, 0, 0 } +#define DIS_RISCV_CMATCH(name, class, op, funct, mask, match, print) \ + { name, DIS_RISCV_C_MATCH, print, class, op, funct, mask, match } + +static dis_riscv_c_instr_t dis_riscv_2byte[] = { + /* Quadrant 0 */ + DIS_RISCV_CFUNCT3("c.addi4spn", DIS_RISCV_CL_32_64, 0x0, 0x0, + dis_riscv_c_addi4spn), + DIS_RISCV_CFUNCT3("c.fld", DIS_RISCV_CL_32_64, 0x0, 0x01, + dis_riscv_c_fld), + DIS_RISCV_CFUNCT3("c.lw", DIS_RISCV_CL_ALL, 0x0, 0x2, + dis_riscv_c_lw), + DIS_RISCV_CFUNCT3("c.flw", DIS_RISCV_CL_32, 0x0, 0x3, + dis_riscv_c_flw), + DIS_RISCV_CFUNCT3("f.ld", DIS_RISCV_CL_64_128, 0x0, 0x3, + dis_riscv_c_ld), + DIS_RISCV_CFUNCT3("c.fsd", DIS_RISCV_CL_32_64, 0x0, 0x5, + dis_riscv_c_fld), + DIS_RISCV_CFUNCT3("c.sw", DIS_RISCV_CL_ALL, 0x0, 0x6, + dis_riscv_c_lw), + DIS_RISCV_CFUNCT3("c.fsw", DIS_RISCV_CL_32, 0x0, 0x7, + dis_riscv_c_flw), + DIS_RISCV_CFUNCT3("c.sd", DIS_RISCV_CL_64_128, 0x0, 0x7, + dis_riscv_c_ld), + /* Quadrant 1 */ + DIS_RISCV_CMATCH("c.nop", DIS_RISCV_CL_ALL, 0x01, 0x00, 0x1ffc, 0x0, + dis_riscv_c_name), + DIS_RISCV_CFUNCT3("c.addi", DIS_RISCV_CL_ALL, 0x01, 0x00, + dis_riscv_c_bigimmint), + DIS_RISCV_CFUNCT3("c.jal", DIS_RISCV_CL_32, 0x01, 0x01, + dis_riscv_c_j), + DIS_RISCV_CFUNCT3("c.addiw", DIS_RISCV_CL_64_128, 0x01, 0x01, + dis_riscv_c_bigimmint), + DIS_RISCV_CFUNCT3("c.li", DIS_RISCV_CL_ALL, 0x01, 0x02, + dis_riscv_c_bigimmint), + DIS_RISCV_CMATCH("c.addi16sp", DIS_RISCV_CL_ALL, 0x01, 0x03, 0x0f80, + 0x0100, dis_riscv_c_addi16sp), + DIS_RISCV_CFUNCT3("c.lui", DIS_RISCV_CL_ALL, 0x01, 0x03, + dis_riscv_c_zext_bigimmint), + DIS_RISCV_CMATCH("c.srli", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x0c00, 0x0000, + dis_riscv_c_zext_immint), + DIS_RISCV_CMATCH("c.srai", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x0c00, 0x0400, + dis_riscv_c_zext_immint), + DIS_RISCV_CMATCH("c.andi", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x0c00, 0x0800, + dis_riscv_c_immint), + DIS_RISCV_CMATCH("c.sub", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c00, + dis_riscv_c_int), + DIS_RISCV_CMATCH("c.xor", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c20, + dis_riscv_c_int), + DIS_RISCV_CMATCH("c.or", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c40, + dis_riscv_c_int), + DIS_RISCV_CMATCH("c.and", DIS_RISCV_CL_ALL, 0x1, 0x4, 0x1c60, 0x0c60, + dis_riscv_c_int), + DIS_RISCV_CMATCH("c.subw", DIS_RISCV_CL_64_128, 0x1, 0x4, 0x1c60, + 0x1c00, dis_riscv_c_int), + DIS_RISCV_CMATCH("c.addw", DIS_RISCV_CL_64_128, 0x1, 0x4, 0x1c60, + 0x1c20, dis_riscv_c_int), + DIS_RISCV_CFUNCT3("c.j", DIS_RISCV_CL_ALL, 0x1, 0x5, + dis_riscv_c_j), + DIS_RISCV_CFUNCT3("c.beqz", DIS_RISCV_CL_ALL, 0x1, 0x6, + dis_riscv_c_branch), + DIS_RISCV_CFUNCT3("c.bnez", DIS_RISCV_CL_ALL, 0x1, 0x7, + dis_riscv_c_branch), + /* Quadrant 2 */ + DIS_RISCV_CFUNCT3("c.slli", DIS_RISCV_CL_ALL, 0x2, 0x0, + dis_riscv_c_zext_bigimmint), + DIS_RISCV_CFUNCT3("c.fldsp", DIS_RISCV_CL_32_64, 0x2, 0x1, + dis_riscv_c_fldsp), + DIS_RISCV_CFUNCT3("c.lwsp", DIS_RISCV_CL_ALL, 0x2, 0x2, + dis_riscv_c_lwsp), + DIS_RISCV_CFUNCT3("c.flwsp", DIS_RISCV_CL_32, 0x2, 0x3, + dis_riscv_c_flwsp), + DIS_RISCV_CFUNCT3("c.ldsp", DIS_RISCV_CL_64_128, 0x2, 0x3, + dis_riscv_c_ldsp), + DIS_RISCV_CMATCH("c.jr", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x107c, 0x0, + dis_riscv_c_jr), + DIS_RISCV_CMATCH("c.mv", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x1000, 0x0, + dis_riscv_c_bigint), + DIS_RISCV_CMATCH("c.ebreak", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x1ffc, 0x1000, + dis_riscv_c_name), + DIS_RISCV_CMATCH("c.jalr", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x107c, 0x1000, + dis_riscv_c_jr), + DIS_RISCV_CMATCH("c.add", DIS_RISCV_CL_ALL, 0x2, 0x4, 0x1000, 0x1000, + dis_riscv_c_bigint), + DIS_RISCV_CFUNCT3("c.fsdsp", DIS_RISCV_CL_32_64, 0x2, 0x5, + dis_riscv_c_fsdsp), + DIS_RISCV_CFUNCT3("c.swsp", DIS_RISCV_CL_ALL, 0x2, 0x6, + dis_riscv_c_swsp), + DIS_RISCV_CFUNCT3("c.fswsp", DIS_RISCV_CL_32, 0x2, 0x7, + dis_riscv_c_fswsp), + DIS_RISCV_CFUNCT3("c.sdsp", DIS_RISCV_CL_64_128, 0x2, 0x7, + dis_riscv_c_sdsp), +}; + +static void +dis_riscv_decode_2byte(dis_handle_t *dhp, uint32_t instr, char *buf, + size_t buflen) +{ + uint_t i; + + for (i = 0; i < ARRAY_SIZE(dis_riscv_2byte); i++) { + dis_riscv_c_instr_t *t = &dis_riscv_2byte[i]; + switch (t->drv_c_class) { + case DIS_RISCV_CL_ALL: + break; + case DIS_RISCV_CL_32: + if ((dhp->dh_flags & DIS_RISCV_32) == 0) + continue; + break; + case DIS_RISCV_CL_64: + if ((dhp->dh_flags & DIS_RISCV_64) == 0) + continue; + break; + case DIS_RISCV_CL_32_64: + if ((dhp->dh_flags & + (DIS_RISCV_32 | DIS_RISCV_64)) == 0) { + continue; + } + break; + case DIS_RISCV_CL_64_128: + if ((dhp->dh_flags & DIS_RISCV_64) == 0) + continue; + break; + } + + switch (t->drv_c_type) { + case DIS_RISCV_C_FUNCT3: + if (DIS_RISCV_C_OPCODE(instr) == t->drv_c_opcode && + DIS_RISCV_C_FUNCT3(instr) == t->drv_c_funct) { + break; + } + continue; + case DIS_RISCV_C_MATCH: + if (DIS_RISCV_C_OPCODE(instr) == t->drv_c_opcode && + DIS_RISCV_C_FUNCT3(instr) == t->drv_c_funct && + ((instr & t->drv_c_mask) == t->drv_c_match)) { + break; + } + continue; + default: + continue; + } + + t->drv_c_print(dhp, instr, t, buf, buflen); + return; + } + + (void) dis_snprintf(buf, buflen, "<unknown>"); +} + + +/* + * RISC-V instructions always come in parcels of two bytes. Read the next two + * byte parcel and advance the address in the handle. Also, take care of endian + * issues if required. + */ +static int +dis_riscv_read_parcel(dis_handle_t *dhp, uint16_t *valp) +{ + if ((dhp->dh_addr % 2) != 0) + return (-1); + + if (dhp->dh_read(dhp->dh_data, dhp->dh_addr, valp, sizeof (*valp)) != + sizeof (*valp)) + return (-1); + + *valp = LE_16(*valp); + + dhp->dh_addr += 2; + + return (0); +} + +/* + * The first 'parcel' (uint16_t) of any instruction can be used to determine the + * instruction length. This is derived from Section 1.2 Instruction Length + * Encoding of Volume I: RISC-V User-Level ISA V2.2. + * + * | xxxxxxxxxxxxxxaa | 16-bit iff aa != 11 + * | xxxxxxxxxxxbbb11 | 32-bit iff bbb != 111 + * | xxxxxxxxxx011111 | 48-bit iff bbb != 111 + * | xxxxxxxxx0111111 | 64-bit iff bbb != 111 + * | xnnnxxxxx1111111 | (80 + 16*nnn)-bit iff nnn != 111 + */ +#define RISCV_LEN_16_MASK 0x0003 +#define RISCV_LEN_32_MASK 0x001c +#define RISCV_LEN_48_MASK 0x0020 +#define RISCV_LEN_64_MASK 0x0040 +#define RISCV_LEN_80_MASK 0x7000 +#define RISCV_LEN_80_SHIFT 12 + +static int +dis_riscv_decode_len(uint16_t instr) +{ + if ((instr & RISCV_LEN_16_MASK) != RISCV_LEN_16_MASK) + return (2); + + if ((instr & RISCV_LEN_32_MASK) != RISCV_LEN_32_MASK) + return (4); + + if ((instr & RISCV_LEN_48_MASK) != RISCV_LEN_48_MASK) + return (6); + + if ((instr & RISCV_LEN_64_MASK) != RISCV_LEN_64_MASK) + return (8); + + if ((instr & RISCV_LEN_80_MASK) != RISCV_LEN_80_MASK) { + uint_t factor = (instr & RISCV_LEN_80_MASK) >> + RISCV_LEN_80_SHIFT; + return ((10 + 2 * factor)); + } + + return (-1); +} + +static int +dis_riscv_supports_flags(int flags) +{ + int archflags = flags & DIS_ARCH_MASK; + + return (archflags == DIS_RISCV_32 || archflags == DIS_RISCV_64); +} + +static int +dis_riscv_disassemble(dis_handle_t *dhp, uint64_t addr, char *buf, + size_t buflen) +{ + int len; + uint16_t parcel; + uint32_t instr; + + + dhp->dh_addr = addr; + + /* + * All instructions have to be 2-byte aligned. Most have to be four byte + * aligned, but we determine that after we decode the instruction size. + * The 2-byte alignment check is done when we read the parcel. + */ + if (dis_riscv_read_parcel(dhp, &parcel) != 0) + return (-1); + + len = dis_riscv_decode_len(parcel); + if (len < 2 || (len % 2) != 0) + return (-1); + switch (len) { + case 2: + instr = parcel; + dis_riscv_decode_2byte(dhp, instr, buf, buflen); + break; + case 4: + instr = parcel; + if (dis_riscv_read_parcel(dhp, &parcel) != 0) + return (-1); + instr |= parcel << 16; + dis_riscv_decode_4byte(dhp, instr, buf, buflen); + break; + default: + /* + * This case represents a valid instruction length, but + * something we don't understand. Treat this as an unknown + * instruction. However, read the rest of the length of the + * instruction to make sure that we read things correctly. + */ + (void) dis_snprintf(buf, buflen, "<unknown>"); + for (; len > 0; len -= 2) { + if (dis_riscv_read_parcel(dhp, &parcel) != 0) { + return (-1); + } + } + break; + } + + return (0); +} + +/*ARGSUSED*/ +static int +dis_riscv_min_instrlen(dis_handle_t *dhp) +{ + return (2); +} + +/*ARGSUSED*/ +static int +dis_riscv_max_instrlen(dis_handle_t *dhp) +{ + return (22); +} + +static int +dis_riscv_instrlen(dis_handle_t *dhp, uint64_t addr) +{ + int ret; + uint16_t parcel; + + dhp->dh_addr = addr; + + if (dis_riscv_read_parcel(dhp, &parcel) != 0) + return (-1); + + /* + * Get length based on this parcel. Check for required alignment. 2-byte + * alignment was already taken care of when we read the parcel. + */ + ret = dis_riscv_decode_len(parcel); + if (ret >= 4 && (addr % 4) != 0) + return (-1); + + return (ret); +} + +dis_arch_t dis_arch_riscv = { + .da_supports_flags = dis_riscv_supports_flags, + .da_disassemble = dis_riscv_disassemble, + .da_min_instrlen = dis_riscv_min_instrlen, + .da_max_instrlen = dis_riscv_max_instrlen, + .da_instrlen = dis_riscv_instrlen +}; diff --git a/usr/src/lib/libdisasm/common/libdisasm.c b/usr/src/lib/libdisasm/common/libdisasm.c index 97e64c8937..7e5f545cc8 100644 --- a/usr/src/lib/libdisasm/common/libdisasm.c +++ b/usr/src/lib/libdisasm/common/libdisasm.c @@ -24,6 +24,7 @@ * Use is subject to license terms. * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> * Copyright 2015 Nexenta Systems, Inc. All rights reserved. + * Copyright 2018, Joyent, Inc. */ #include <libdisasm.h> @@ -55,6 +56,9 @@ extern dis_arch_t dis_arch_sparc; #if !defined(DIS_STANDALONE) || defined(__s390) || defined(__s390x) extern dis_arch_t dis_arch_s390; #endif +#if !defined(DIS_STANDALONE) || defined(__riscv) +extern dis_arch_t dis_arch_riscv; +#endif static dis_arch_t *dis_archs[] = { #if !defined(DIS_STANDALONE) || defined(__i386) || defined(__amd64) @@ -66,6 +70,9 @@ static dis_arch_t *dis_archs[] = { #if !defined(DIS_STANDALONE) || defined(__s390) || defined(__s390x) &dis_arch_s390, #endif +#if !defined(DIS_STANDALONE) || defined(__riscv) + &dis_arch_riscv, +#endif NULL }; diff --git a/usr/src/lib/libdisasm/common/libdisasm.h b/usr/src/lib/libdisasm/common/libdisasm.h index 7c35db4a81..374daf4161 100644 --- a/usr/src/lib/libdisasm/common/libdisasm.h +++ b/usr/src/lib/libdisasm/common/libdisasm.h @@ -24,6 +24,7 @@ * Use is subject to license terms. * Copyright 2012 Joshua M. Clulow <josh@sysmgr.org> * Copyright 2015 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> + * Copyright 2018, Joyent, Inc. */ #ifndef _LIBDISASM_H @@ -55,6 +56,10 @@ typedef struct dis_handle dis_handle_t; #define DIS_S390_31 0x400 #define DIS_S390_64 0x800 +/* risc-v disassembler flags */ +#define DIS_RISCV_32 0x2000 +#define DIS_RISCV_64 0x4000 + /* generic disassembler flags */ #define DIS_OCTAL 0x040 #define DIS_NOIMMSYM 0x080 @@ -62,7 +67,8 @@ typedef struct dis_handle dis_handle_t; #define DIS_ARCH_MASK (DIS_SPARC_V8 | \ DIS_SPARC_V9 | DIS_SPARC_V9_SGI | DIS_SPARC_V9_OPL | \ DIS_X86_SIZE16 | DIS_X86_SIZE32 | DIS_X86_SIZE64 | \ - DIS_S370 | DIS_S390_31 | DIS_S390_64) + DIS_S370 | DIS_S390_31 | DIS_S390_64 | DIS_RISCV_32 | \ + DIS_RISCV_64) typedef int (*dis_lookup_f)(void *, uint64_t, char *, size_t, uint64_t *, size_t *); diff --git a/usr/src/pkg/manifests/system-test-utiltest.mf b/usr/src/pkg/manifests/system-test-utiltest.mf index 714efb203a..5d32bf889b 100644 --- a/usr/src/pkg/manifests/system-test-utiltest.mf +++ b/usr/src/pkg/manifests/system-test-utiltest.mf @@ -28,6 +28,8 @@ dir path=opt/util-tests/runfiles dir path=opt/util-tests/tests dir path=opt/util-tests/tests/dis dir path=opt/util-tests/tests/dis/i386 +dir path=opt/util-tests/tests/dis/risc-v +dir path=opt/util-tests/tests/dis/risc-v-c dir path=opt/util-tests/tests/dis/sparc dir path=opt/util-tests/tests/files dir path=opt/util-tests/tests/libnvpair_json @@ -39,124 +41,168 @@ file path=opt/util-tests/runfiles/default.run mode=0444 file path=opt/util-tests/tests/allowed-ips mode=0555 file path=opt/util-tests/tests/date_test mode=0555 file path=opt/util-tests/tests/dis/distest mode=0555 -file path=opt/util-tests/tests/dis/i386/32.adx.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.adx.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.aes.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.aes.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.avx.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.avx.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.avx2.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.avx2.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.avx512.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.avx512.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.bmi1.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.bmi1.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.bmi2.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.bmi2.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.f16c.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.f16c.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-pd.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-pd.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-ps.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-ps.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-sd.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-sd.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-ss.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.fma-ss.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.lzcnt.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.lzcnt.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.movbe.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.movbe.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.opmask.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.opmask.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.pclmulqdq.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.pclmulqdq.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.popcnt.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.popcnt.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sha.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sha.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sse-3.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sse-3.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sse-4.1.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sse-4.1.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sse-4.2.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.sse-4.2.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.ssse3.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.ssse3.s mode=0555 -file path=opt/util-tests/tests/dis/i386/32.xsave.out mode=0555 -file path=opt/util-tests/tests/dis/i386/32.xsave.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.adx.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.adx.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.aes.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.aes.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.avx.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.avx.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.avx2.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.avx2.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.avx512.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.avx512.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.bmi1.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.bmi1.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.bmi2.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.bmi2.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.ept.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.ept.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.f16c.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.f16c.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-pd.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-pd.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-ps.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-ps.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-sd.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-sd.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-ss.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.fma-ss.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.lzcnt.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.lzcnt.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.movbe.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.movbe.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.opmask.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.opmask.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.pclmulqdq.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.pclmulqdq.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.popcnt.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.popcnt.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.random.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.random.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sha.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sha.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sse-3.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sse-3.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sse-4.1.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sse-4.1.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sse-4.2.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.sse-4.2.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.ssse3.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.ssse3.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.vmx.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.vmx.s mode=0555 -file path=opt/util-tests/tests/dis/i386/64.xsave.out mode=0555 -file path=opt/util-tests/tests/dis/i386/64.xsave.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.cpuid.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.cpuid.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.fence.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.fence.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.msr.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.msr.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.mwait.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.mwait.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.random.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.random.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.sep.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.sep.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.smap.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.smap.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.tsc.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.tsc.s mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.vmx.out mode=0555 -file path=opt/util-tests/tests/dis/i386/tst.vmx.s mode=0555 -file path=opt/util-tests/tests/dis/sparc/tst.regs.out mode=0555 -file path=opt/util-tests/tests/dis/sparc/tst.regs.s mode=0555 +file path=opt/util-tests/tests/dis/i386/32.adx.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.adx.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.aes.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.aes.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx2-gather.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx2-gather.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx2.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx2.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx512.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.avx512.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.bmi1.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.bmi1.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.bmi2.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.bmi2.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.f16c.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.f16c.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-pd.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-pd.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-ps.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-ps.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-sd.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-sd.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-ss.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.fma-ss.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.lzcnt.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.lzcnt.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.movbe.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.movbe.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.opmask.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.opmask.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.pclmulqdq.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.pclmulqdq.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.popcnt.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.popcnt.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sha.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sha.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sse-3.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sse-3.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sse-4.1.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sse-4.1.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sse-4.2.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.sse-4.2.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.ssse3.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.ssse3.s mode=0444 +file path=opt/util-tests/tests/dis/i386/32.xsave.out mode=0444 +file path=opt/util-tests/tests/dis/i386/32.xsave.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.adx.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.adx.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.aes.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.aes.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx2-gather.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx2-gather.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx2.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx2.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx512.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.avx512.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.bmi1.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.bmi1.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.bmi2.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.bmi2.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.ept.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.ept.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.f16c.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.f16c.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-pd.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-pd.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-ps.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-ps.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-sd.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-sd.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-ss.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.fma-ss.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.lzcnt.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.lzcnt.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.movbe.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.movbe.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.opmask.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.opmask.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.pclmulqdq.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.pclmulqdq.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.popcnt.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.popcnt.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.random.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.random.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sha.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sha.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sse-3.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sse-3.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sse-4.1.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sse-4.1.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sse-4.2.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.sse-4.2.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.ssse3.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.ssse3.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.vmx.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.vmx.s mode=0444 +file path=opt/util-tests/tests/dis/i386/64.xsave.out mode=0444 +file path=opt/util-tests/tests/dis/i386/64.xsave.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.cpuid.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.cpuid.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.fence.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.fence.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.msr.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.msr.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.mwait.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.mwait.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.random.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.random.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.sep.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.sep.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.smap.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.smap.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.tsc.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.tsc.s mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.vmx.out mode=0444 +file path=opt/util-tests/tests/dis/i386/tst.vmx.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/32.ldsr.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/32.ldsr.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/64.int.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/64.int.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/64.ldsr.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/64.ldsr.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/tst.int.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/tst.int.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/tst.ldsr.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v-c/tst.ldsr.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64a.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64a.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64d.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64d.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64f.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64f.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64i.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64i.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64m.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/64.rv64m.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.csr.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.csr.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.fpregs.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.fpregs.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.pseudo.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.pseudo.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.regs.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.regs.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32a.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32a.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32d.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32d.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32f.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32f.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32i.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32i.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32m.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.rv32m.s mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.supervisor.out mode=0444 +file path=opt/util-tests/tests/dis/risc-v/tst.supervisor.s mode=0444 +file path=opt/util-tests/tests/dis/sparc/tst.regs.out mode=0444 +file path=opt/util-tests/tests/dis/sparc/tst.regs.s mode=0444 file path=opt/util-tests/tests/files/gout0 mode=0444 file path=opt/util-tests/tests/files/gout1 mode=0444 file path=opt/util-tests/tests/files/gout10 mode=0444 diff --git a/usr/src/test/util-tests/tests/dis/Makefile b/usr/src/test/util-tests/tests/dis/Makefile index 53cf7ccd40..3c4c8a5773 100644 --- a/usr/src/test/util-tests/tests/dis/Makefile +++ b/usr/src/test/util-tests/tests/dis/Makefile @@ -10,94 +10,37 @@ # # -# Copyright 2017 Joyent, Inc. +# Copyright 2018 Joyent, Inc. # include $(SRC)/Makefile.master ROOTOPTPKG = $(ROOT)/opt/util-tests TESTDIR = $(ROOTOPTPKG)/tests/dis -ARCHS = i386 sparc +ARCHS = i386 risc-v risc-v-c sparc PROG = distest -SPARC_TESTS = \ - tst.regs - -I386_TESTS = \ - 32.adx \ - 32.avx \ - 32.avx2 \ - 32.avx512 \ - 32.aes \ - 32.bmi1 \ - 32.bmi2 \ - 32.f16c \ - 32.fma-pd \ - 32.fma-ps \ - 32.fma-sd \ - 32.fma-ss \ - 32.lzcnt \ - 32.movbe \ - 32.opmask \ - 32.pclmulqdq \ - 32.popcnt \ - 32.sha \ - 32.sse-3 \ - 32.sse-4.1 \ - 32.sse-4.2 \ - 32.ssse3 \ - 32.xsave \ - 64.avx \ - 64.avx2 \ - 64.avx512 \ - 64.adx \ - 64.aes \ - 64.bmi1 \ - 64.bmi2 \ - 64.ept \ - 64.f16c \ - 64.fma-pd \ - 64.fma-ps \ - 64.fma-sd \ - 64.fma-ss \ - 64.lzcnt \ - 64.movbe \ - 64.opmask \ - 64.pclmulqdq \ - 64.popcnt \ - 64.random \ - 64.sha \ - 64.sse-3 \ - 64.sse-4.1 \ - 64.sse-4.2 \ - 64.ssse3 \ - 64.vmx \ - 64.xsave \ - tst.cpuid \ - tst.fence \ - tst.msr \ - tst.mwait \ - tst.random \ - tst.smap \ - tst.sep \ - tst.tsc \ - tst.vmx - -I386_FILES = $(I386_TESTS:%=%.s) $(I386_TESTS:%=%.out) -ROOTI386 = $(I386_FILES:%=$(TESTDIR)/i386/%) - -SPARC_FILES = $(SPARC_TESTS:%=%.s) $(SPARC_TESTS:%=%.out) -ROOTSPARC = $(SPARC_FILES:%=$(TESTDIR)/sparc/%) +I386_FILES :sh= (cd i386; print *) +RISCV_FILES :sh= (cd risc-v; print *) +RISCV_C_FILES :sh= (cd risc-v-c; print *) +SPARC_FILES :sh= (cd sparc; print *) + +ROOTFILES = \ + $(I386_FILES:%=$(TESTDIR)/i386/%) \ + $(RISCV_FILES:%=$(TESTDIR)/risc-v/%) \ + $(RISCV_C_FILES:%=$(TESTDIR)/risc-v-c/%) \ + $(SPARC_FILES:%=$(TESTDIR)/sparc/%) include $(SRC)/cmd/Makefile.cmd include $(SRC)/test/Makefile.com ARCHDIRS = $(ARCHS:%=$(TESTDIR)/%) CMDS = $(PROG:%=$(TESTDIR)/%) +FILEMODE=0444 $(CMDS) := FILEMODE = 0555 -install: $(CMDS) $(ROOTI386) $(ROOTSPARC) +install: $(CMDS) $(ROOTFILES) lint: @@ -105,7 +48,7 @@ clobber: clean clean: -$(CMDS) $(ROOTI386) $(ROOTSPARC): $(TESTDIR) $(ARCHDIRS) +$(CMDS) $(ROOTFILES): $(TESTDIR) $(ARCHDIRS) $(TESTDIR) $(ARCHDIRS): $(INS.dir) diff --git a/usr/src/test/util-tests/tests/dis/distest.ksh b/usr/src/test/util-tests/tests/dis/distest.ksh index 21b39a69bc..37a5dd231a 100644 --- a/usr/src/test/util-tests/tests/dis/distest.ksh +++ b/usr/src/test/util-tests/tests/dis/distest.ksh @@ -11,7 +11,7 @@ # # -# Copyright 2016 Joyent, Inc. +# Copyright 2018 Joyent, Inc. # # @@ -78,6 +78,7 @@ Usage: $dt_arg0 [-n] [ -p platform=pathtoas ]... [ test ]... either be an absolute path or a command on the path. USAGE + exit 2 } # @@ -196,6 +197,7 @@ test_one() run_single_file() { typeset sfile base cmpfile prefix arch gas p flags + typeset asflags32 asflags64 sfile=$1 base=${sfile##*/} @@ -207,16 +209,31 @@ run_single_file() gas=${dt_platforms[$arch]} [[ -n $gas ]] || fatal "encountered test $sfile, but missing assembler" + case "$arch" in + "risc-v") + asflags32="-march=rv32g" + asflags64="-march=rv64g" + ;; + "risc-v-c") + asflags32="-march=rv32gc" + asflags64="-march=rv64gc" + ;; + *) + asflags32="-32" + asflags64="-64" + ;; + esac + case "$prefix" in 32) - test_one "-32" $sfile $cmpfile + test_one $asflags32 $sfile $cmpfile ;; 64) - test_one "-64" $sfile $cmpfile + test_one $asflags64 $sfile $cmpfile ;; tst) - test_one "-32" $sfile $cmpfile "(32-bit)" - test_one "-64" $sfile $cmpfile "(64-bit)" + test_one $asflags32 $sfile $cmpfile "(32-bit)" + test_one $asflags64 $sfile $cmpfile "(64-bit)" ;; esac } @@ -270,9 +287,10 @@ while getopts ":np:" c $@; do dt_nodefault="y" ;; p) + OLDIFS=$IFS IFS="=" set -A split $OPTARG - IFS=" " + IFS=$OLDIFS [[ ${#split[@]} -eq 2 ]] || usage "malformed -p option: $OPTARG" dt_platforms[${split[0]}]=${split[1]} ;; diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/32.ldsr.out b/usr/src/test/util-tests/tests/dis/risc-v-c/32.ldsr.out new file mode 100644 index 0000000000..cfd34d3949 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/32.ldsr.out @@ -0,0 +1,7 @@ + libdis_test: 04 61 c.flw fs1,0x0(a0) + libdis_test+0x2: b4 62 c.flw fa3,0x40(a3) + libdis_test+0x4: 82 64 c.flwsp fs1,0x0(sp) + libdis_test+0x6: 06 6e c.flwsp ft8,0x40(sp) + libdis_test+0x8: d2 77 c.flwsp fa5,0x34(sp) + libdis_test+0xa: 0a e0 c.fswsp ft2,0x0(sp) + libdis_test+0xc: 36 f0 c.fswsp fa3,0x20(sp) diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/32.ldsr.s b/usr/src/test/util-tests/tests/dis/risc-v-c/32.ldsr.s new file mode 100644 index 0000000000..75959ea63a --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/32.ldsr.s @@ -0,0 +1,32 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test RV32C-specific loads and stores. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + c.flw fs1,(a0) + c.flw fa3,0x40(a3) + c.flwsp fs1,(sp) + c.flwsp ft8,0x40(sp) + c.flwsp fa5,0x34(sp) + c.fswsp ft2,(sp) + c.fswsp fa3,0x20(sp) +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/64.int.out b/usr/src/test/util-tests/tests/dis/risc-v-c/64.int.out new file mode 100644 index 0000000000..4c7abf745d --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/64.int.out @@ -0,0 +1,5 @@ + libdis_test: fd 24 c.addiw s1,0x1f + libdis_test+0x2: 8d 24 c.addiw s1,0x3 + libdis_test+0x4: 81 34 c.addiw s1,-0x20 + libdis_test+0x6: b1 9d c.addw a1,a2 + libdis_test+0x8: 15 9c c.subw s0,a3 diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/64.int.s b/usr/src/test/util-tests/tests/dis/risc-v-c/64.int.s new file mode 100644 index 0000000000..25a19b1540 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/64.int.s @@ -0,0 +1,30 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test RV64C-specific integer instructions + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + c.addiw s1, 0x1f + c.addiw s1, 0x3 + c.addiw s1, -0x20 + c.addw a1, a2 + c.subw s0, a3 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/64.ldsr.out b/usr/src/test/util-tests/tests/dis/risc-v-c/64.ldsr.out new file mode 100644 index 0000000000..af6302d361 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/64.ldsr.out @@ -0,0 +1,10 @@ + libdis_test: 82 64 c.ldsp s1,0x0(sp) + libdis_test+0x2: 06 67 c.ldsp a4,0x40(sp) + libdis_test+0x4: 62 7e c.ldsp t3,0x38(sp) + libdis_test+0x6: 82 24 c.fldsp fs1,0x0(sp) + libdis_test+0x8: 06 2e c.fldsp ft8,0x40(sp) + libdis_test+0xa: e2 37 c.fldsp fa5,0x38(sp) + libdis_test+0xc: 76 e0 c.sdsp t4,0x0(sp) + libdis_test+0xe: 12 f0 c.sdsp tp,0x20(sp) + libdis_test+0x10: 0a a0 c.fsdsp ft2,0x0(sp) + libdis_test+0x12: 36 b0 c.fsdsp fa3,0x20(sp) diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/64.ldsr.s b/usr/src/test/util-tests/tests/dis/risc-v-c/64.ldsr.s new file mode 100644 index 0000000000..95cccda8f5 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/64.ldsr.s @@ -0,0 +1,35 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test RV64C-specific loads and stores. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + c.ldsp s1,(sp) + c.ldsp a4,0x40(sp) + c.ldsp t3,0x38(sp) + c.fldsp fs1,(sp) + c.fldsp ft8,0x40(sp) + c.fldsp fa5,0x38(sp) + c.sdsp t4,(sp) + c.sdsp tp,0x20(sp) + c.fsdsp ft2,(sp) + c.fsdsp fa3,0x20(sp) +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/tst.int.out b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.int.out new file mode 100644 index 0000000000..a6a480225f --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.int.out @@ -0,0 +1,30 @@ + libdis_test: d5 40 c.li ra,0x15 + libdis_test+0x2: b5 5d c.li s11,-0x13 + libdis_test+0x4: 89 64 c.lui s1,0x2 + libdis_test+0x6: cd 64 c.lui s1,0x13 + libdis_test+0x8: fd 04 c.addi s1,0x1f + libdis_test+0xa: 8d 04 c.addi s1,0x3 + libdis_test+0xc: 81 14 c.addi s1,-0x20 + libdis_test+0xe: 45 61 c.addi16sp sp,0x30 + libdis_test+0x10: 39 71 c.addi16sp sp,-0x40 + libdis_test+0x12: 0c 08 c.addi4spn a1,sp,0x10 + libdis_test+0x14: 6c 10 c.addi4spn a1,sp,0x2c + libdis_test+0x16: 16 0d c.slli s10,0x5 + libdis_test+0x18: ce 0e c.slli t4,0x13 + libdis_test+0x1a: 0a 04 c.slli s0,0x2 + libdis_test+0x1c: 11 82 c.srli a2,0x4 + libdis_test+0x1e: d5 80 c.srli s1,0x15 + libdis_test+0x20: 91 86 c.srai a3,0x4 + libdis_test+0x22: e5 87 c.srai a5,0x19 + libdis_test+0x24: 0d 8b c.andi a4,0x3 + libdis_test+0x26: e5 9a c.andi a3,-0x7 + libdis_test+0x28: ba 84 c.mv s1,a4 + libdis_test+0x2a: 3e 85 c.mv a0,a5 + libdis_test+0x2c: b6 95 c.add a1,a3 + libdis_test+0x2e: 32 96 c.add a2,a2 + libdis_test+0x30: 6d 8d c.and a0,a1 + libdis_test+0x32: d1 8d c.or a1,a2 + libdis_test+0x34: 35 8e c.xor a2,a3 + libdis_test+0x36: 99 8e c.sub a3,a4 + libdis_test+0x38: 01 00 c.nop + libdis_test+0x3a: 02 90 c.ebreak diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/tst.int.s b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.int.s new file mode 100644 index 0000000000..9afab25d34 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.int.s @@ -0,0 +1,59 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test common compact integer instructions + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + c.li ra, 0x15 + c.li s11, -0x13 + c.lui s1, 0x2 + c.lui s1, 0x13 + + c.addi s1, 0x1f + c.addi s1, 0x3 + c.addi s1, -0x20 + + c.addi16sp sp, 0x30 + c.addi16sp sp, -0x40 + c.addi4spn a1, sp, 0x10 + c.addi4spn a1, sp, 0x2c + + c.slli s10, 0x5 + c.slli t4, 0x13 + c.slli s0, 0x2 + c.srli a2, 0x4 + c.srli s1, 0x15 + c.srai a3, 0x4 + c.srai a5, 0x19 + c.andi a4, 0x3 + c.andi a3, -0x7 + c.mv s1, a4 + c.mv a0, a5 + c.add a1, a3 + c.add a2, a2 + c.and a0, a1 + c.or a1, a2 + c.xor a2, a3 + c.sub a3, a4 + + c.nop + c.ebreak +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/tst.ldsr.out b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.ldsr.out new file mode 100644 index 0000000000..f69ae6d64e --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.ldsr.out @@ -0,0 +1,9 @@ + libdis_test: 82 44 c.lwsp s1,0x0(sp) + libdis_test+0x2: 06 47 c.lwsp a4,0x40(sp) + libdis_test+0x4: 52 5e c.lwsp t3,0x34(sp) + libdis_test+0x6: 76 c0 c.swsp t4,0x0(sp) + libdis_test+0x8: 12 d0 c.swsp tp,0x20(sp) + libdis_test+0xa: 04 41 c.lw s1,0x0(a0) + libdis_test+0xc: b0 42 c.lw a2,0x40(a3) + libdis_test+0xe: 04 21 c.fld fs1,0x0(a0) + libdis_test+0x10: b4 22 c.fld fa3,0x40(a3) diff --git a/usr/src/test/util-tests/tests/dis/risc-v-c/tst.ldsr.s b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.ldsr.s new file mode 100644 index 0000000000..7a4ef323bd --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v-c/tst.ldsr.s @@ -0,0 +1,38 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test common compact loads and stores. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + c.lwsp s1,(sp) + c.lwsp a4,0x40(sp) + c.lwsp t3,0x34(sp) + c.swsp t4,(sp) + c.swsp tp,0x20(sp) + /* + * gas 2.30 doesn't support using the ABI aliases. However, that's how + * we disassemble these. + */ + c.lw x9,(x10) + c.lw x12,0x40(x13) + c.fld fs1,(a0) + c.fld fa3,0x40(a3) +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64a.out b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64a.out new file mode 100644 index 0000000000..2bb69ce37a --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64a.out @@ -0,0 +1,44 @@ + libdis_test: 2f b4 04 10 lr.d s0,(s1) + libdis_test+0x4: af 34 09 14 lr.d.aq s1,(s2) + libdis_test+0x8: 2f b9 09 12 lr.d.rl s2,(s3) + libdis_test+0xc: af 39 0a 16 lr.d.aqrl s3,(s4) + libdis_test+0x10: 2f b4 24 19 sc.d s0,s2,(s1) + libdis_test+0x14: af b4 34 1d sc.d.aq s1,s3,(s1) + libdis_test+0x18: 2f b9 44 1b sc.d.rl s2,s4,(s1) + libdis_test+0x1c: af b9 54 1f sc.d.aqrl s3,s5,(s1) + libdis_test+0x20: af b2 63 08 amoswap.d t0,t1,(t2) + libdis_test+0x24: 2f 33 7e 0c amoswap.d.aq t1,t2,(t3) + libdis_test+0x28: af b3 ce 0b amoswap.d.rl t2,t3,(t4) + libdis_test+0x2c: 2f 3e df 0f amoswap.d.aqrl t3,t4,(t5) + libdis_test+0x30: af b2 63 00 amoadd.d t0,t1,(t2) + libdis_test+0x34: 2f 33 7e 04 amoadd.d.aq t1,t2,(t3) + libdis_test+0x38: af b3 ce 03 amoadd.d.rl t2,t3,(t4) + libdis_test+0x3c: 2f 3e df 07 amoadd.d.aqrl t3,t4,(t5) + libdis_test+0x40: af b2 63 20 amoxor.d t0,t1,(t2) + libdis_test+0x44: 2f 33 7e 24 amoxor.d.aq t1,t2,(t3) + libdis_test+0x48: af b3 ce 23 amoxor.d.rl t2,t3,(t4) + libdis_test+0x4c: 2f 3e df 27 amoxor.d.aqrl t3,t4,(t5) + libdis_test+0x50: af b2 63 60 amoand.d t0,t1,(t2) + libdis_test+0x54: 2f 33 7e 64 amoand.d.aq t1,t2,(t3) + libdis_test+0x58: af b3 ce 63 amoand.d.rl t2,t3,(t4) + libdis_test+0x5c: 2f 3e df 67 amoand.d.aqrl t3,t4,(t5) + libdis_test+0x60: af b2 63 40 amoor.d t0,t1,(t2) + libdis_test+0x64: 2f 33 7e 44 amoor.d.aq t1,t2,(t3) + libdis_test+0x68: af b3 ce 43 amoor.d.rl t2,t3,(t4) + libdis_test+0x6c: 2f 3e df 47 amoor.d.aqrl t3,t4,(t5) + libdis_test+0x70: af b2 63 80 amomin.d t0,t1,(t2) + libdis_test+0x74: 2f 33 7e 84 amomin.d.aq t1,t2,(t3) + libdis_test+0x78: af b3 ce 83 amomin.d.rl t2,t3,(t4) + libdis_test+0x7c: 2f 3e df 87 amomin.d.aqrl t3,t4,(t5) + libdis_test+0x80: af b2 63 a0 amomax.d t0,t1,(t2) + libdis_test+0x84: 2f 33 7e a4 amomax.d.aq t1,t2,(t3) + libdis_test+0x88: af b3 ce a3 amomax.d.rl t2,t3,(t4) + libdis_test+0x8c: 2f 3e df a7 amomax.d.aqrl t3,t4,(t5) + libdis_test+0x90: af b2 63 c0 amominu.d t0,t1,(t2) + libdis_test+0x94: 2f 33 7e c4 amominu.d.aq t1,t2,(t3) + libdis_test+0x98: af b3 ce c3 amominu.d.rl t2,t3,(t4) + libdis_test+0x9c: 2f 3e df c7 amominu.d.aqrl t3,t4,(t5) + libdis_test+0xa0: af b2 63 e0 amomaxu.d t0,t1,(t2) + libdis_test+0xa4: 2f 33 7e e4 amomaxu.d.aq t1,t2,(t3) + libdis_test+0xa8: af b3 ce e3 amomaxu.d.rl t2,t3,(t4) + libdis_test+0xac: 2f 3e df e7 amomaxu.d.aqrl t3,t4,(t5) diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64a.s b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64a.s new file mode 100644 index 0000000000..02f4c4ceca --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64a.s @@ -0,0 +1,70 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV64A instructions. Instructions are ordered per the + * ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + lr.d s0, (s1) + lr.d.aq s1, (s2) + lr.d.rl s2, (s3) + lr.d.aqrl s3, (s4) + sc.d s0, s2, (s1) + sc.d.aq s1, s3, (s1) + sc.d.rl s2, s4, (s1) + sc.d.aqrl s3, s5, (s1) + amoswap.d t0, t1, (t2) + amoswap.d.aq t1, t2, (t3) + amoswap.d.rl t2, t3, (t4) + amoswap.d.aqrl t3, t4, (t5) + amoadd.d t0, t1, (t2) + amoadd.d.aq t1, t2, (t3) + amoadd.d.rl t2, t3, (t4) + amoadd.d.aqrl t3, t4, (t5) + amoxor.d t0, t1, (t2) + amoxor.d.aq t1, t2, (t3) + amoxor.d.rl t2, t3, (t4) + amoxor.d.aqrl t3, t4, (t5) + amoand.d t0, t1, (t2) + amoand.d.aq t1, t2, (t3) + amoand.d.rl t2, t3, (t4) + amoand.d.aqrl t3, t4, (t5) + amoor.d t0, t1, (t2) + amoor.d.aq t1, t2, (t3) + amoor.d.rl t2, t3, (t4) + amoor.d.aqrl t3, t4, (t5) + amomin.d t0, t1, (t2) + amomin.d.aq t1, t2, (t3) + amomin.d.rl t2, t3, (t4) + amomin.d.aqrl t3, t4, (t5) + amomax.d t0, t1, (t2) + amomax.d.aq t1, t2, (t3) + amomax.d.rl t2, t3, (t4) + amomax.d.aqrl t3, t4, (t5) + amominu.d t0, t1, (t2) + amominu.d.aq t1, t2, (t3) + amominu.d.rl t2, t3, (t4) + amominu.d.aqrl t3, t4, (t5) + amomaxu.d t0, t1, (t2) + amomaxu.d.aq t1, t2, (t3) + amomaxu.d.rl t2, t3, (t4) + amomaxu.d.aqrl t3, t4, (t5) +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64d.out b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64d.out new file mode 100644 index 0000000000..3d54aff0a5 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64d.out @@ -0,0 +1,26 @@ + libdis_test: d3 f2 20 c2 fcvt.l.d t0,ft1 + libdis_test+0x4: 53 03 21 c2 fcvt.l.d t1,ft2,rne + libdis_test+0x8: d3 93 21 c2 fcvt.l.d t2,ft3,rtz + libdis_test+0xc: 53 2e 22 c2 fcvt.l.d t3,ft4,rdn + libdis_test+0x10: d3 be 22 c2 fcvt.l.d t4,ft5,rup + libdis_test+0x14: 53 4f 23 c2 fcvt.l.d t5,ft6,rmm + libdis_test+0x18: 53 73 30 c2 fcvt.lu.d t1,ft0 + libdis_test+0x1c: d3 83 30 c2 fcvt.lu.d t2,ft1,rne + libdis_test+0x20: 53 1e 31 c2 fcvt.lu.d t3,ft2,rtz + libdis_test+0x24: d3 ae 31 c2 fcvt.lu.d t4,ft3,rdn + libdis_test+0x28: 53 3f 32 c2 fcvt.lu.d t5,ft4,rup + libdis_test+0x2c: d3 cf 32 c2 fcvt.lu.d t6,ft5,rmm + libdis_test+0x30: 53 8e 05 e2 fmv.x.d t3,fa1 + libdis_test+0x34: d3 f0 22 d2 fcvt.d.l ft1,t0 + libdis_test+0x38: 53 01 23 d2 fcvt.d.l ft2,t1,rne + libdis_test+0x3c: d3 91 23 d2 fcvt.d.l ft3,t2,rtz + libdis_test+0x40: 53 22 2e d2 fcvt.d.l ft4,t3,rdn + libdis_test+0x44: d3 b2 2e d2 fcvt.d.l ft5,t4,rup + libdis_test+0x48: 53 43 2f d2 fcvt.d.l ft6,t5,rmm + libdis_test+0x4c: d3 f0 32 d2 fcvt.d.lu ft1,t0 + libdis_test+0x50: 53 01 33 d2 fcvt.d.lu ft2,t1,rne + libdis_test+0x54: d3 91 33 d2 fcvt.d.lu ft3,t2,rtz + libdis_test+0x58: 53 22 3e d2 fcvt.d.lu ft4,t3,rdn + libdis_test+0x5c: d3 b2 3e d2 fcvt.d.lu ft5,t4,rup + libdis_test+0x60: 53 43 3f d2 fcvt.d.lu ft6,t5,rmm + libdis_test+0x64: 53 06 0e f2 fmv.d.x fa2,t3 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64d.s b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64d.s new file mode 100644 index 0000000000..6a3c3b2385 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64d.s @@ -0,0 +1,57 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV64F instructions. Instructions are ordered per + * the ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + fcvt.l.d t0, ft1 + fcvt.l.d t1, ft2, rne + fcvt.l.d t2, ft3, rtz + fcvt.l.d t3, ft4, rdn + fcvt.l.d t4, ft5, rup + fcvt.l.d t5, ft6, rmm + + fcvt.lu.d t1, ft0 + fcvt.lu.d t2, ft1, rne + fcvt.lu.d t3, ft2, rtz + fcvt.lu.d t4, ft3, rdn + fcvt.lu.d t5, ft4, rup + fcvt.lu.d t6, ft5, rmm + + fmv.x.d t3, fa1 + + fcvt.d.l ft1, t0 + fcvt.d.l ft2, t1, rne + fcvt.d.l ft3, t2, rtz + fcvt.d.l ft4, t3, rdn + fcvt.d.l ft5, t4, rup + fcvt.d.l ft6, t5, rmm + + fcvt.d.lu ft1, t0 + fcvt.d.lu ft2, t1, rne + fcvt.d.lu ft3, t2, rtz + fcvt.d.lu ft4, t3, rdn + fcvt.d.lu ft5, t4, rup + fcvt.d.lu ft6, t5, rmm + + fmv.d.x fa2, t3 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64f.out b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64f.out new file mode 100644 index 0000000000..985cc1e1b1 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64f.out @@ -0,0 +1,24 @@ + libdis_test: d3 f2 20 c0 fcvt.l.s t0,ft1 + libdis_test+0x4: 53 03 21 c0 fcvt.l.s t1,ft2,rne + libdis_test+0x8: d3 93 21 c0 fcvt.l.s t2,ft3,rtz + libdis_test+0xc: 53 2e 22 c0 fcvt.l.s t3,ft4,rdn + libdis_test+0x10: d3 be 22 c0 fcvt.l.s t4,ft5,rup + libdis_test+0x14: 53 4f 23 c0 fcvt.l.s t5,ft6,rmm + libdis_test+0x18: 53 73 30 c0 fcvt.lu.s t1,ft0 + libdis_test+0x1c: d3 83 30 c0 fcvt.lu.s t2,ft1,rne + libdis_test+0x20: 53 1e 31 c0 fcvt.lu.s t3,ft2,rtz + libdis_test+0x24: d3 ae 31 c0 fcvt.lu.s t4,ft3,rdn + libdis_test+0x28: 53 3f 32 c0 fcvt.lu.s t5,ft4,rup + libdis_test+0x2c: d3 cf 32 c0 fcvt.lu.s t6,ft5,rmm + libdis_test+0x30: d3 f0 22 d0 fcvt.s.l ft1,t0 + libdis_test+0x34: 53 01 23 d0 fcvt.s.l ft2,t1,rne + libdis_test+0x38: d3 91 23 d0 fcvt.s.l ft3,t2,rtz + libdis_test+0x3c: 53 22 2e d0 fcvt.s.l ft4,t3,rdn + libdis_test+0x40: d3 b2 2e d0 fcvt.s.l ft5,t4,rup + libdis_test+0x44: 53 43 2f d0 fcvt.s.l ft6,t5,rmm + libdis_test+0x48: d3 f0 32 d0 fcvt.s.lu ft1,t0 + libdis_test+0x4c: 53 01 33 d0 fcvt.s.lu ft2,t1,rne + libdis_test+0x50: d3 91 33 d0 fcvt.s.lu ft3,t2,rtz + libdis_test+0x54: 53 22 3e d0 fcvt.s.lu ft4,t3,rdn + libdis_test+0x58: d3 b2 3e d0 fcvt.s.lu ft5,t4,rup + libdis_test+0x5c: 53 43 3f d0 fcvt.s.lu ft6,t5,rmm diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64f.s b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64f.s new file mode 100644 index 0000000000..1e1418dd2d --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64f.s @@ -0,0 +1,53 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV64F instructions. Instructions are ordered per + * the ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + fcvt.l.s t0, ft1 + fcvt.l.s t1, ft2, rne + fcvt.l.s t2, ft3, rtz + fcvt.l.s t3, ft4, rdn + fcvt.l.s t4, ft5, rup + fcvt.l.s t5, ft6, rmm + + fcvt.lu.s t1, ft0 + fcvt.lu.s t2, ft1, rne + fcvt.lu.s t3, ft2, rtz + fcvt.lu.s t4, ft3, rdn + fcvt.lu.s t5, ft4, rup + fcvt.lu.s t6, ft5, rmm + + fcvt.s.l ft1, t0 + fcvt.s.l ft2, t1, rne + fcvt.s.l ft3, t2, rtz + fcvt.s.l ft4, t3, rdn + fcvt.s.l ft5, t4, rup + fcvt.s.l ft6, t5, rmm + + fcvt.s.lu ft1, t0 + fcvt.s.lu ft2, t1, rne + fcvt.s.lu ft3, t2, rtz + fcvt.s.lu ft4, t3, rdn + fcvt.s.lu ft5, t4, rup + fcvt.s.lu ft6, t5, rmm +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64i.out b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64i.out new file mode 100644 index 0000000000..331ac70962 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64i.out @@ -0,0 +1,25 @@ + libdis_test: 83 eb f4 7f lwu s7,0x7ff(s1) + libdis_test+0x4: 03 eb 04 00 lwu s6,0x0(s1) + libdis_test+0x8: 83 ea 04 80 lwu s5,-0x800(s1) + libdis_test+0xc: 03 ba f4 7f ld s4,0x7ff(s1) + libdis_test+0x10: 83 b9 04 00 ld s3,0x0(s1) + libdis_test+0x14: 03 b9 04 80 ld s2,-0x800(s1) + libdis_test+0x18: a3 3f 53 7e sd t0,0x7ff(t1) + libdis_test+0x1c: 23 b0 63 00 sd t1,0x0(t2) + libdis_test+0x20: 23 30 7e 80 sd t2,-0x800(t3) + libdis_test+0x24: 13 94 24 00 slli s0,s1,0x2 + libdis_test+0x28: 13 94 f4 03 slli s0,s1,0x3f + libdis_test+0x2c: 13 d4 24 00 srli s0,s1,0x2 + libdis_test+0x30: 13 d4 f4 03 srli s0,s1,0x3f + libdis_test+0x34: 13 d4 24 40 srai s0,s1,0x2 + libdis_test+0x38: 13 d4 f4 43 srai s0,s1,0x3f + libdis_test+0x3c: 9b 80 42 00 addiw ra,t0,0x4 + libdis_test+0x40: 9b 80 c2 ff addiw ra,t0,-0x4 + libdis_test+0x44: 9b 1e 2f 01 slliw t4,t5,0x12 + libdis_test+0x48: 9b 5e 3f 01 srliw t4,t5,0x13 + libdis_test+0x4c: 9b 5e 4f 41 sraiw t4,t5,0x14 + libdis_test+0x50: 3b 84 24 01 addw s0,s1,s2 + libdis_test+0x54: bb 04 39 41 subw s1,s2,s3 + libdis_test+0x58: bb 19 5a 01 sllw s3,s4,s5 + libdis_test+0x5c: bb 59 5a 01 srlw s3,s4,s5 + libdis_test+0x60: bb 59 5a 41 sraw s3,s4,s5 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64i.s b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64i.s new file mode 100644 index 0000000000..31d6d699c6 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64i.s @@ -0,0 +1,52 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV64I instructions. Instructions are ordered per the + * ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + lwu s7, 0x7ff(s1) + lwu s6, (s1) + lwu s5, -0x800(s1) + ld s4, 0x7ff(s1) + ld s3, (s1) + ld s2, -0x800(s1) + sd t0, 0x7ff(t1) + sd t1, (t2) + sd t2, -0x800(t3) + slli s0, s1, 2 + slli s0, s1, 63 + srli s0, s1, 2 + srli s0, s1, 63 + srai s0, s1, 2 + srai s0, s1, 63 + addiw ra, t0, 0x4 + addiw ra, t0, -0x4 + slliw t4, t5, 0x12 + srliw t4, t5, 0x13 + sraiw t4, t5, 0x14 + addw s0, s1, s2 + subw s1, s2, s3 + sllw s3, s4, s5 + srlw s3, s4, s5 + sraw s3, s4, s5 + +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64m.out b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64m.out new file mode 100644 index 0000000000..c807d0cf8d --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64m.out @@ -0,0 +1,5 @@ + libdis_test: 3b 84 24 03 mulw s0,s1,s2 + libdis_test+0x4: 3b ca 6a 03 divw s4,s5,s6 + libdis_test+0x8: bb 5a 7b 03 divuw s5,s6,s7 + libdis_test+0xc: 3b eb 8b 03 remw s6,s7,s8 + libdis_test+0x10: bb 7b 9c 03 remuw s7,s8,s9 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/64.rv64m.s b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64m.s new file mode 100644 index 0000000000..b31daca180 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/64.rv64m.s @@ -0,0 +1,31 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV64M instructions. Instructions are ordered per the + * ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + mulw s0, s1, s2 + divw s4, s5, s6 + divuw s5, s6, s7 + remw s6, s7, s8 + remuw s7, s8, s9 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.csr.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.csr.out new file mode 100644 index 0000000000..9d8fc9113b --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.csr.out @@ -0,0 +1,129 @@ + libdis_test: 73 a3 03 00 csrrs t1,ustatus,t2 + libdis_test+0x4: 73 a3 43 00 csrrs t1,uie,t2 + libdis_test+0x8: 73 a3 53 00 csrrs t1,utvec,t2 + libdis_test+0xc: 73 a3 03 04 csrrs t1,uscratch,t2 + libdis_test+0x10: 73 a3 13 04 csrrs t1,uepc,t2 + libdis_test+0x14: 73 a3 23 04 csrrs t1,ucause,t2 + libdis_test+0x18: 73 a3 33 04 csrrs t1,utval,t2 + libdis_test+0x1c: 73 a3 43 04 csrrs t1,uip,t2 + libdis_test+0x20: 73 a3 13 00 csrrs t1,fflags,t2 + libdis_test+0x24: 73 a3 23 00 csrrs t1,frm,t2 + libdis_test+0x28: 73 a3 33 00 csrrs t1,fcsr,t2 + libdis_test+0x2c: 73 a3 03 c0 csrrs t1,cycle,t2 + libdis_test+0x30: 73 a3 13 c0 csrrs t1,time,t2 + libdis_test+0x34: 73 a3 23 c0 csrrs t1,instret,t2 + libdis_test+0x38: 73 a3 33 c0 csrrs t1,hpmcounter3,t2 + libdis_test+0x3c: 73 a3 43 c0 csrrs t1,hpmcounter4,t2 + libdis_test+0x40: 73 a3 53 c0 csrrs t1,hpmcounter5,t2 + libdis_test+0x44: 73 a3 63 c0 csrrs t1,hpmcounter6,t2 + libdis_test+0x48: 73 a3 73 c0 csrrs t1,hpmcounter7,t2 + libdis_test+0x4c: 73 a3 83 c0 csrrs t1,hpmcounter8,t2 + libdis_test+0x50: 73 a3 93 c0 csrrs t1,hpmcounter9,t2 + libdis_test+0x54: 73 a3 a3 c0 csrrs t1,hpmcounter10,t2 + libdis_test+0x58: 73 a3 b3 c0 csrrs t1,hpmcounter11,t2 + libdis_test+0x5c: 73 a3 c3 c0 csrrs t1,hpmcounter12,t2 + libdis_test+0x60: 73 a3 d3 c0 csrrs t1,hpmcounter13,t2 + libdis_test+0x64: 73 a3 e3 c0 csrrs t1,hpmcounter14,t2 + libdis_test+0x68: 73 a3 f3 c0 csrrs t1,hpmcounter15,t2 + libdis_test+0x6c: 73 a3 03 c1 csrrs t1,hpmcounter16,t2 + libdis_test+0x70: 73 a3 13 c1 csrrs t1,hpmcounter17,t2 + libdis_test+0x74: 73 a3 23 c1 csrrs t1,hpmcounter18,t2 + libdis_test+0x78: 73 a3 33 c1 csrrs t1,hpmcounter19,t2 + libdis_test+0x7c: 73 a3 43 c1 csrrs t1,hpmcounter20,t2 + libdis_test+0x80: 73 a3 53 c1 csrrs t1,hpmcounter21,t2 + libdis_test+0x84: 73 a3 63 c1 csrrs t1,hpmcounter22,t2 + libdis_test+0x88: 73 a3 73 c1 csrrs t1,hpmcounter23,t2 + libdis_test+0x8c: 73 a3 83 c1 csrrs t1,hpmcounter24,t2 + libdis_test+0x90: 73 a3 93 c1 csrrs t1,hpmcounter25,t2 + libdis_test+0x94: 73 a3 a3 c1 csrrs t1,hpmcounter26,t2 + libdis_test+0x98: 73 a3 b3 c1 csrrs t1,hpmcounter27,t2 + libdis_test+0x9c: 73 a3 c3 c1 csrrs t1,hpmcounter28,t2 + libdis_test+0xa0: 73 a3 d3 c1 csrrs t1,hpmcounter29,t2 + libdis_test+0xa4: 73 a3 e3 c1 csrrs t1,hpmcounter30,t2 + libdis_test+0xa8: 73 a3 f3 c1 csrrs t1,hpmcounter31,t2 + libdis_test+0xac: 73 a3 03 c8 csrrs t1,cycleh,t2 + libdis_test+0xb0: 73 a3 13 c8 csrrs t1,timeh,t2 + libdis_test+0xb4: 73 a3 23 c8 csrrs t1,instreth,t2 + libdis_test+0xb8: 73 a3 33 c8 csrrs t1,hpmcounter3h,t2 + libdis_test+0xbc: 73 a3 43 c8 csrrs t1,hpmcounter4h,t2 + libdis_test+0xc0: 73 a3 53 c8 csrrs t1,hpmcounter5h,t2 + libdis_test+0xc4: 73 a3 63 c8 csrrs t1,hpmcounter6h,t2 + libdis_test+0xc8: 73 a3 73 c8 csrrs t1,hpmcounter7h,t2 + libdis_test+0xcc: 73 a3 83 c8 csrrs t1,hpmcounter8h,t2 + libdis_test+0xd0: 73 a3 93 c8 csrrs t1,hpmcounter9h,t2 + libdis_test+0xd4: 73 a3 a3 c8 csrrs t1,hpmcounter10h,t2 + libdis_test+0xd8: 73 a3 b3 c8 csrrs t1,hpmcounter11h,t2 + libdis_test+0xdc: 73 a3 c3 c8 csrrs t1,hpmcounter12h,t2 + libdis_test+0xe0: 73 a3 d3 c8 csrrs t1,hpmcounter13h,t2 + libdis_test+0xe4: 73 a3 e3 c8 csrrs t1,hpmcounter14h,t2 + libdis_test+0xe8: 73 a3 f3 c8 csrrs t1,hpmcounter15h,t2 + libdis_test+0xec: 73 a3 03 c9 csrrs t1,hpmcounter16h,t2 + libdis_test+0xf0: 73 a3 13 c9 csrrs t1,hpmcounter17h,t2 + libdis_test+0xf4: 73 a3 23 c9 csrrs t1,hpmcounter18h,t2 + libdis_test+0xf8: 73 a3 33 c9 csrrs t1,hpmcounter19h,t2 + libdis_test+0xfc: 73 a3 43 c9 csrrs t1,hpmcounter20h,t2 + libdis_test+0x100: 73 a3 53 c9 csrrs t1,hpmcounter21h,t2 + libdis_test+0x104: 73 a3 63 c9 csrrs t1,hpmcounter22h,t2 + libdis_test+0x108: 73 a3 73 c9 csrrs t1,hpmcounter23h,t2 + libdis_test+0x10c: 73 a3 83 c9 csrrs t1,hpmcounter24h,t2 + libdis_test+0x110: 73 a3 93 c9 csrrs t1,hpmcounter25h,t2 + libdis_test+0x114: 73 a3 a3 c9 csrrs t1,hpmcounter26h,t2 + libdis_test+0x118: 73 a3 b3 c9 csrrs t1,hpmcounter27h,t2 + libdis_test+0x11c: 73 a3 c3 c9 csrrs t1,hpmcounter28h,t2 + libdis_test+0x120: 73 a3 d3 c9 csrrs t1,hpmcounter29h,t2 + libdis_test+0x124: 73 a3 e3 c9 csrrs t1,hpmcounter30h,t2 + libdis_test+0x128: 73 a3 f3 c9 csrrs t1,hpmcounter31h,t2 + libdis_test+0x12c: 73 a3 03 10 csrrs t1,sstatus,t2 + libdis_test+0x130: 73 a3 23 10 csrrs t1,sedeleg,t2 + libdis_test+0x134: 73 a3 33 10 csrrs t1,sideleg,t2 + libdis_test+0x138: 73 a3 43 10 csrrs t1,sie,t2 + libdis_test+0x13c: 73 a3 53 10 csrrs t1,stvec,t2 + libdis_test+0x140: 73 a3 63 10 csrrs t1,scounteren,t2 + libdis_test+0x144: 73 a3 03 14 csrrs t1,sscratch,t2 + libdis_test+0x148: 73 a3 13 14 csrrs t1,sepc,t2 + libdis_test+0x14c: 73 a3 23 14 csrrs t1,scause,t2 + libdis_test+0x150: 73 a3 33 14 csrrs t1,stval,t2 + libdis_test+0x154: 73 a3 43 14 csrrs t1,sip,t2 + libdis_test+0x158: 73 a3 03 18 csrrs t1,satp,t2 + libdis_test+0x15c: 73 a3 13 f1 csrrs t1,mvendorid,t2 + libdis_test+0x160: 73 a3 23 f1 csrrs t1,marchid,t2 + libdis_test+0x164: 73 a3 33 f1 csrrs t1,mimpid,t2 + libdis_test+0x168: 73 a3 43 f1 csrrs t1,mhartid,t2 + libdis_test+0x16c: 73 a3 03 30 csrrs t1,mstatus,t2 + libdis_test+0x170: 73 a3 13 30 csrrs t1,misa,t2 + libdis_test+0x174: 73 a3 23 30 csrrs t1,medeleg,t2 + libdis_test+0x178: 73 a3 33 30 csrrs t1,mideleg,t2 + libdis_test+0x17c: 73 a3 43 30 csrrs t1,mie,t2 + libdis_test+0x180: 73 a3 53 30 csrrs t1,mtvec,t2 + libdis_test+0x184: 73 a3 63 30 csrrs t1,mcounteren,t2 + libdis_test+0x188: 73 a3 03 34 csrrs t1,mscratch,t2 + libdis_test+0x18c: 73 a3 13 34 csrrs t1,mepc,t2 + libdis_test+0x190: 73 a3 23 34 csrrs t1,mcause,t2 + libdis_test+0x194: 73 a3 33 34 csrrs t1,mtval,t2 + libdis_test+0x198: 73 a3 43 34 csrrs t1,mip,t2 + libdis_test+0x19c: 73 a3 03 3a csrrs t1,pmpcfg0,t2 + libdis_test+0x1a0: 73 a3 13 3a csrrs t1,pmpcfg1,t2 + libdis_test+0x1a4: 73 a3 23 3a csrrs t1,pmpcfg2,t2 + libdis_test+0x1a8: 73 a3 33 3a csrrs t1,pmpcfg3,t2 + libdis_test+0x1ac: 73 a3 03 3b csrrs t1,pmpaddr0,t2 + libdis_test+0x1b0: 73 a3 13 3b csrrs t1,pmpaddr1,t2 + libdis_test+0x1b4: 73 a3 23 3b csrrs t1,pmpaddr2,t2 + libdis_test+0x1b8: 73 a3 33 3b csrrs t1,pmpaddr3,t2 + libdis_test+0x1bc: 73 a3 43 3b csrrs t1,pmpaddr4,t2 + libdis_test+0x1c0: 73 a3 53 3b csrrs t1,pmpaddr5,t2 + libdis_test+0x1c4: 73 a3 63 3b csrrs t1,pmpaddr6,t2 + libdis_test+0x1c8: 73 a3 73 3b csrrs t1,pmpaddr7,t2 + libdis_test+0x1cc: 73 a3 83 3b csrrs t1,pmpaddr8,t2 + libdis_test+0x1d0: 73 a3 93 3b csrrs t1,pmpaddr9,t2 + libdis_test+0x1d4: 73 a3 a3 3b csrrs t1,pmpaddr10,t2 + libdis_test+0x1d8: 73 a3 b3 3b csrrs t1,pmpaddr11,t2 + libdis_test+0x1dc: 73 a3 c3 3b csrrs t1,pmpaddr12,t2 + libdis_test+0x1e0: 73 a3 d3 3b csrrs t1,pmpaddr13,t2 + libdis_test+0x1e4: 73 a3 e3 3b csrrs t1,pmpaddr14,t2 + libdis_test+0x1e8: 73 a3 f3 3b csrrs t1,pmpaddr15,t2 + libdis_test+0x1ec: 73 a3 03 00 csrrs t1,ustatus,t2 + libdis_test+0x1f0: 73 93 43 00 csrrw t1,uie,t2 + libdis_test+0x1f4: 73 b3 53 00 csrrc t1,utvec,t2 + libdis_test+0x1f8: 73 d3 0b 04 csrrwi t1,uscratch,0x17 + libdis_test+0x1fc: 73 63 1b 04 csrrsi t1,uepc,0x16 + libdis_test+0x200: 73 f3 2a 04 csrrci t1,ucause,0x15 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.csr.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.csr.s new file mode 100644 index 0000000000..6fb5dd1d2f --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.csr.s @@ -0,0 +1,168 @@ +/* + * This file and its contents are supplied under the terms of the + csrrs t1, CDDL, t2), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of csr instructions and csr names. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + /* User Trap */ + csrrs t1, ustatus, t2 + csrrs t1, uie, t2 + csrrs t1, utvec, t2 + /* User Trap Handling */ + csrrs t1, uscratch, t2 + csrrs t1, uepc, t2 + csrrs t1, ucause, t2 + csrrs t1, utval, t2 + csrrs t1, uip, t2 + /* User Floating-Point CSRs */ + csrrs t1, fflags, t2 + csrrs t1, frm, t2 + csrrs t1, fcsr, t2 + /* User Counters/Timers */ + csrrs t1, cycle, t2 + csrrs t1, time, t2 + csrrs t1, instret, t2 + csrrs t1, hpmcounter3, t2 + csrrs t1, hpmcounter4, t2 + csrrs t1, hpmcounter5, t2 + csrrs t1, hpmcounter6, t2 + csrrs t1, hpmcounter7, t2 + csrrs t1, hpmcounter8, t2 + csrrs t1, hpmcounter9, t2 + csrrs t1, hpmcounter10, t2 + csrrs t1, hpmcounter11, t2 + csrrs t1, hpmcounter12, t2 + csrrs t1, hpmcounter13, t2 + csrrs t1, hpmcounter14, t2 + csrrs t1, hpmcounter15, t2 + csrrs t1, hpmcounter16, t2 + csrrs t1, hpmcounter17, t2 + csrrs t1, hpmcounter18, t2 + csrrs t1, hpmcounter19, t2 + csrrs t1, hpmcounter20, t2 + csrrs t1, hpmcounter21, t2 + csrrs t1, hpmcounter22, t2 + csrrs t1, hpmcounter23, t2 + csrrs t1, hpmcounter24, t2 + csrrs t1, hpmcounter25, t2 + csrrs t1, hpmcounter26, t2 + csrrs t1, hpmcounter27, t2 + csrrs t1, hpmcounter28, t2 + csrrs t1, hpmcounter29, t2 + csrrs t1, hpmcounter30, t2 + csrrs t1, hpmcounter31, t2 + csrrs t1, cycleh, t2 + csrrs t1, timeh, t2 + csrrs t1, instreth, t2 + csrrs t1, hpmcounter3h, t2 + csrrs t1, hpmcounter4h, t2 + csrrs t1, hpmcounter5h, t2 + csrrs t1, hpmcounter6h, t2 + csrrs t1, hpmcounter7h, t2 + csrrs t1, hpmcounter8h, t2 + csrrs t1, hpmcounter9h, t2 + csrrs t1, hpmcounter10h, t2 + csrrs t1, hpmcounter11h, t2 + csrrs t1, hpmcounter12h, t2 + csrrs t1, hpmcounter13h, t2 + csrrs t1, hpmcounter14h, t2 + csrrs t1, hpmcounter15h, t2 + csrrs t1, hpmcounter16h, t2 + csrrs t1, hpmcounter17h, t2 + csrrs t1, hpmcounter18h, t2 + csrrs t1, hpmcounter19h, t2 + csrrs t1, hpmcounter20h, t2 + csrrs t1, hpmcounter21h, t2 + csrrs t1, hpmcounter22h, t2 + csrrs t1, hpmcounter23h, t2 + csrrs t1, hpmcounter24h, t2 + csrrs t1, hpmcounter25h, t2 + csrrs t1, hpmcounter26h, t2 + csrrs t1, hpmcounter27h, t2 + csrrs t1, hpmcounter28h, t2 + csrrs t1, hpmcounter29h, t2 + csrrs t1, hpmcounter30h, t2 + csrrs t1, hpmcounter31h, t2 + /* Supervisor Trap Status */ + csrrs t1, sstatus, t2 + csrrs t1, sedeleg, t2 + csrrs t1, sideleg, t2 + csrrs t1, sie, t2 + csrrs t1, stvec, t2 + csrrs t1, scounteren, t2 + /* Supervisor Trap Handling */ + csrrs t1, sscratch, t2 + csrrs t1, sepc, t2 + csrrs t1, scause, t2 + csrrs t1, stval, t2 + csrrs t1, sip, t2 + /* Supervisor Protection and Translation */ + csrrs t1, satp, t2 + /* Machine Information Registers */ + csrrs t1, mvendorid, t2 + csrrs t1, marchid, t2 + csrrs t1, mimpid, t2 + csrrs t1, mhartid, t2 + /* Machine Trap Setup */ + csrrs t1, mstatus, t2 + csrrs t1, misa, t2 + csrrs t1, medeleg, t2 + csrrs t1, mideleg, t2 + csrrs t1, mie, t2 + csrrs t1, mtvec, t2 + csrrs t1, mcounteren, t2 + /* Machine Trap Handling */ + csrrs t1, mscratch, t2 + csrrs t1, mepc, t2 + csrrs t1, mcause, t2 + csrrs t1, mtval, t2 + csrrs t1, mip, t2 + /* Machine Protection and Translation */ + csrrs t1, pmpcfg0, t2 + csrrs t1, pmpcfg1, t2 + csrrs t1, pmpcfg2, t2 + csrrs t1, pmpcfg3, t2 + csrrs t1, pmpaddr0, t2 + csrrs t1, pmpaddr1, t2 + csrrs t1, pmpaddr2, t2 + csrrs t1, pmpaddr3, t2 + csrrs t1, pmpaddr4, t2 + csrrs t1, pmpaddr5, t2 + csrrs t1, pmpaddr6, t2 + csrrs t1, pmpaddr7, t2 + csrrs t1, pmpaddr8, t2 + csrrs t1, pmpaddr9, t2 + csrrs t1, pmpaddr10, t2 + csrrs t1, pmpaddr11, t2 + csrrs t1, pmpaddr12, t2 + csrrs t1, pmpaddr13, t2 + csrrs t1, pmpaddr14, t2 + csrrs t1, pmpaddr15, t2 + /* + * Various instr variants + */ + csrrs t1, ustatus, t2 + csrrw t1, uie, t2 + csrrc t1, utvec, t2 + csrrwi t1, uscratch, 0x17 + csrrsi t1, uepc, 0x16 + csrrci t1, ucause, 0x15 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.fpregs.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.fpregs.out new file mode 100644 index 0000000000..0eb8fd165b --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.fpregs.out @@ -0,0 +1,64 @@ + libdis_test: 53 70 00 00 fadd.s ft0,ft0,ft0 + libdis_test+0x4: d3 f0 10 00 fadd.s ft1,ft1,ft1 + libdis_test+0x8: 53 71 21 00 fadd.s ft2,ft2,ft2 + libdis_test+0xc: d3 f1 31 00 fadd.s ft3,ft3,ft3 + libdis_test+0x10: 53 72 42 00 fadd.s ft4,ft4,ft4 + libdis_test+0x14: d3 f2 52 00 fadd.s ft5,ft5,ft5 + libdis_test+0x18: 53 73 63 00 fadd.s ft6,ft6,ft6 + libdis_test+0x1c: d3 f3 73 00 fadd.s ft7,ft7,ft7 + libdis_test+0x20: 53 74 84 00 fadd.s fs0,fs0,fs0 + libdis_test+0x24: d3 f4 94 00 fadd.s fs1,fs1,fs1 + libdis_test+0x28: 53 75 a5 00 fadd.s fa0,fa0,fa0 + libdis_test+0x2c: d3 f5 b5 00 fadd.s fa1,fa1,fa1 + libdis_test+0x30: 53 76 c6 00 fadd.s fa2,fa2,fa2 + libdis_test+0x34: d3 f6 d6 00 fadd.s fa3,fa3,fa3 + libdis_test+0x38: 53 77 e7 00 fadd.s fa4,fa4,fa4 + libdis_test+0x3c: d3 f7 f7 00 fadd.s fa5,fa5,fa5 + libdis_test+0x40: 53 78 08 01 fadd.s fa6,fa6,fa6 + libdis_test+0x44: d3 f8 18 01 fadd.s fa7,fa7,fa7 + libdis_test+0x48: 53 79 29 01 fadd.s fs2,fs2,fs2 + libdis_test+0x4c: d3 f9 39 01 fadd.s fs3,fs3,fs3 + libdis_test+0x50: 53 7a 4a 01 fadd.s fs4,fs4,fs4 + libdis_test+0x54: d3 fa 5a 01 fadd.s fs5,fs5,fs5 + libdis_test+0x58: 53 7b 6b 01 fadd.s fs6,fs6,fs6 + libdis_test+0x5c: d3 fb 7b 01 fadd.s fs7,fs7,fs7 + libdis_test+0x60: 53 7c 8c 01 fadd.s fs8,fs8,fs8 + libdis_test+0x64: d3 fc 9c 01 fadd.s fs9,fs9,fs9 + libdis_test+0x68: 53 7d ad 01 fadd.s fs10,fs10,fs10 + libdis_test+0x6c: d3 fd bd 01 fadd.s fs11,fs11,fs11 + libdis_test+0x70: 53 7e ce 01 fadd.s ft8,ft8,ft8 + libdis_test+0x74: d3 fe de 01 fadd.s ft9,ft9,ft9 + libdis_test+0x78: 53 7f ef 01 fadd.s ft10,ft10,ft10 + libdis_test+0x7c: d3 ff ff 01 fadd.s ft11,ft11,ft11 + libdis_test+0x80: 53 f0 20 00 fadd.s ft0,ft1,ft2 + libdis_test+0x84: d3 70 31 00 fadd.s ft1,ft2,ft3 + libdis_test+0x88: 53 f1 41 00 fadd.s ft2,ft3,ft4 + libdis_test+0x8c: d3 71 52 00 fadd.s ft3,ft4,ft5 + libdis_test+0x90: 53 f2 62 00 fadd.s ft4,ft5,ft6 + libdis_test+0x94: d3 72 73 00 fadd.s ft5,ft6,ft7 + libdis_test+0x98: 53 f3 83 00 fadd.s ft6,ft7,fs0 + libdis_test+0x9c: d3 73 94 00 fadd.s ft7,fs0,fs1 + libdis_test+0xa0: 53 f4 a4 00 fadd.s fs0,fs1,fa0 + libdis_test+0xa4: d3 74 b5 00 fadd.s fs1,fa0,fa1 + libdis_test+0xa8: 53 f5 c5 00 fadd.s fa0,fa1,fa2 + libdis_test+0xac: d3 75 d6 00 fadd.s fa1,fa2,fa3 + libdis_test+0xb0: 53 f6 e6 00 fadd.s fa2,fa3,fa4 + libdis_test+0xb4: d3 76 f7 00 fadd.s fa3,fa4,fa5 + libdis_test+0xb8: 53 f7 07 01 fadd.s fa4,fa5,fa6 + libdis_test+0xbc: d3 77 18 01 fadd.s fa5,fa6,fa7 + libdis_test+0xc0: 53 f8 28 01 fadd.s fa6,fa7,fs2 + libdis_test+0xc4: d3 78 39 01 fadd.s fa7,fs2,fs3 + libdis_test+0xc8: 53 f9 49 01 fadd.s fs2,fs3,fs4 + libdis_test+0xcc: d3 79 5a 01 fadd.s fs3,fs4,fs5 + libdis_test+0xd0: 53 fa 6a 01 fadd.s fs4,fs5,fs6 + libdis_test+0xd4: d3 7a 7b 01 fadd.s fs5,fs6,fs7 + libdis_test+0xd8: 53 fb 8b 01 fadd.s fs6,fs7,fs8 + libdis_test+0xdc: d3 7b 9c 01 fadd.s fs7,fs8,fs9 + libdis_test+0xe0: 53 fc ac 01 fadd.s fs8,fs9,fs10 + libdis_test+0xe4: d3 7c bd 01 fadd.s fs9,fs10,fs11 + libdis_test+0xe8: 53 fd cd 01 fadd.s fs10,fs11,ft8 + libdis_test+0xec: d3 7d de 01 fadd.s fs11,ft8,ft9 + libdis_test+0xf0: 53 fe ee 01 fadd.s ft8,ft9,ft10 + libdis_test+0xf4: d3 7e ff 01 fadd.s ft9,ft10,ft11 + libdis_test+0xf8: 53 ff 0f 00 fadd.s ft10,ft11,ft0 + libdis_test+0xfc: d3 7f 10 00 fadd.s ft11,ft0,ft1 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.fpregs.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.fpregs.s new file mode 100644 index 0000000000..e85179cde5 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.fpregs.s @@ -0,0 +1,92 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of all of the fp register names. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + +libdifs_tefst: + fadd.s ft0, ft0, ft0 + fadd.s ft1, ft1, ft1 + fadd.s ft2, ft2, ft2 + fadd.s ft3, ft3, ft3 + fadd.s ft4, ft4, ft4 + fadd.s ft5, ft5, ft5 + fadd.s ft6, ft6, ft6 + fadd.s ft7, ft7, ft7 + fadd.s fs0, fs0, fs0 + fadd.s fs1, fs1, fs1 + fadd.s fa0, fa0, fa0 + fadd.s fa1, fa1, fa1 + fadd.s fa2, fa2, fa2 + fadd.s fa3, fa3, fa3 + fadd.s fa4, fa4, fa4 + fadd.s fa5, fa5, fa5 + fadd.s fa6, fa6, fa6 + fadd.s fa7, fa7, fa7 + fadd.s fs2, fs2, fs2 + fadd.s fs3, fs3, fs3 + fadd.s fs4, fs4, fs4 + fadd.s fs5, fs5, fs5 + fadd.s fs6, fs6, fs6 + fadd.s fs7, fs7, fs7 + fadd.s fs8, fs8, fs8 + fadd.s fs9, fs9, fs9 + fadd.s fs10, fs10, fs10 + fadd.s fs11, fs11, fs11 + fadd.s ft8, ft8, ft8 + fadd.s ft9, ft9, ft9 + fadd.s ft10, ft10, ft10 + fadd.s ft11, ft11, ft11 + + fadd.s ft0, ft1, ft2 + fadd.s ft1, ft2, ft3 + fadd.s ft2, ft3, ft4 + fadd.s ft3, ft4, ft5 + fadd.s ft4, ft5, ft6 + fadd.s ft5, ft6, ft7 + fadd.s ft6, ft7, fs0 + fadd.s ft7, fs0, fs1 + fadd.s fs0, fs1, fa0 + fadd.s fs1, fa0, fa1 + fadd.s fa0, fa1, fa2 + fadd.s fa1, fa2, fa3 + fadd.s fa2, fa3, fa4 + fadd.s fa3, fa4, fa5 + fadd.s fa4, fa5, fa6 + fadd.s fa5, fa6, fa7 + fadd.s fa6, fa7, fs2 + fadd.s fa7, fs2, fs3 + fadd.s fs2, fs3, fs4 + fadd.s fs3, fs4, fs5 + fadd.s fs4, fs5, fs6 + fadd.s fs5, fs6, fs7 + fadd.s fs6, fs7, fs8 + fadd.s fs7, fs8, fs9 + fadd.s fs8, fs9, fs10 + fadd.s fs9, fs10, fs11 + fadd.s fs10, fs11, ft8 + fadd.s fs11, ft8, ft9 + fadd.s ft8, ft9, ft10 + fadd.s ft9, ft10, ft11 + fadd.s ft10, ft11, ft0 + fadd.s ft11, ft0, ft1 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.pseudo.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.pseudo.out new file mode 100644 index 0000000000..e983ca4ab6 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.pseudo.out @@ -0,0 +1,26 @@ + libdis_test: 13 00 00 00 nop + libdis_test+0x4: 67 80 00 00 ret + libdis_test+0x8: 0f 00 f0 0f fence + libdis_test+0xc: f3 22 20 c0 rdinstret t0 + libdis_test+0x10: 73 23 00 c0 rdcycle t1 + libdis_test+0x14: f3 23 10 c0 rdtime t2 + libdis_test+0x18: 73 23 00 00 csrr t1,ustatus + libdis_test+0x1c: 73 10 03 00 csrw ustatus,t1 + libdis_test+0x20: 73 a0 03 00 csrs ustatus,t2 + libdis_test+0x24: 73 30 0e 00 csrc ustatus,t3 + libdis_test+0x28: 73 50 42 00 csrwi uie,0x4 + libdis_test+0x2c: 73 e0 42 00 csrsi uie,0x5 + libdis_test+0x30: 73 70 43 00 csrci uie,0x6 + libdis_test+0x34: 73 24 30 00 frcsr s0 + libdis_test+0x38: 73 94 34 00 fscsr s0,s1 + libdis_test+0x3c: 73 90 34 00 fscsr s1 + libdis_test+0x40: 73 25 20 00 frrm a0 + libdis_test+0x44: 73 95 25 00 fsrm a0,a1 + libdis_test+0x48: 73 90 25 00 fsrm a1 + libdis_test+0x4c: f3 52 22 00 fsrmi t0,0x4 + libdis_test+0x50: 73 d0 22 00 fsrmi 0x5 + libdis_test+0x54: 73 25 10 00 frflags a0 + libdis_test+0x58: 73 95 15 00 fsflags a0,a1 + libdis_test+0x5c: 73 90 15 00 fsflags a1 + libdis_test+0x60: f3 52 12 00 fsflagsi t0,0x4 + libdis_test+0x64: 73 d0 12 00 fsflagsi 0x5 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.pseudo.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.pseudo.s new file mode 100644 index 0000000000..623ad89b61 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.pseudo.s @@ -0,0 +1,54 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of various supported pseudo instructions. We only + * support disassembling a subset of the common pseudo instructions that map + * directly to a single asm instruction. Several of the pseudo-instructions + * transform into more than one instruction so we don't support them. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + nop + ret + fence + rdinstret t0 + rdcycle t1 + rdtime t2 + csrr t1, ustatus + csrw ustatus, t1 + csrs ustatus, t2 + csrc ustatus, t3 + csrwi uie, 0x4 + csrsi uie, 0x5 + csrci uie, 0x6 + frcsr s0 + fscsr s0, s1 + fscsr s1 + frrm a0 + fsrm a0, a1 + fsrm a1 + fsrmi t0, 0x4 + fsrmi 0x5 + frflags a0 + fsflags a0, a1 + fsflags a1 + fsflagsi t0, 0x4 + fsflagsi 0x5 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.regs.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.regs.out new file mode 100644 index 0000000000..a754c51024 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.regs.out @@ -0,0 +1,64 @@ + libdis_test: 33 00 00 00 add x0,x0,x0 + libdis_test+0x4: b3 80 10 00 add ra,ra,ra + libdis_test+0x8: 33 01 21 00 add sp,sp,sp + libdis_test+0xc: b3 81 31 00 add gp,gp,gp + libdis_test+0x10: 33 02 42 00 add tp,tp,tp + libdis_test+0x14: b3 82 52 00 add t0,t0,t0 + libdis_test+0x18: 33 03 63 00 add t1,t1,t1 + libdis_test+0x1c: b3 83 73 00 add t2,t2,t2 + libdis_test+0x20: 33 04 84 00 add s0,s0,s0 + libdis_test+0x24: b3 84 94 00 add s1,s1,s1 + libdis_test+0x28: 33 05 a5 00 add a0,a0,a0 + libdis_test+0x2c: b3 85 b5 00 add a1,a1,a1 + libdis_test+0x30: 33 06 c6 00 add a2,a2,a2 + libdis_test+0x34: b3 86 d6 00 add a3,a3,a3 + libdis_test+0x38: 33 07 e7 00 add a4,a4,a4 + libdis_test+0x3c: b3 87 f7 00 add a5,a5,a5 + libdis_test+0x40: 33 08 08 01 add a6,a6,a6 + libdis_test+0x44: b3 88 18 01 add a7,a7,a7 + libdis_test+0x48: 33 09 29 01 add s2,s2,s2 + libdis_test+0x4c: b3 89 39 01 add s3,s3,s3 + libdis_test+0x50: 33 0a 4a 01 add s4,s4,s4 + libdis_test+0x54: b3 8a 5a 01 add s5,s5,s5 + libdis_test+0x58: 33 0b 6b 01 add s6,s6,s6 + libdis_test+0x5c: b3 8b 7b 01 add s7,s7,s7 + libdis_test+0x60: 33 0c 8c 01 add s8,s8,s8 + libdis_test+0x64: b3 8c 9c 01 add s9,s9,s9 + libdis_test+0x68: 33 0d ad 01 add s10,s10,s10 + libdis_test+0x6c: b3 8d bd 01 add s11,s11,s11 + libdis_test+0x70: 33 0e ce 01 add t3,t3,t3 + libdis_test+0x74: b3 8e de 01 add t4,t4,t4 + libdis_test+0x78: 33 0f ef 01 add t5,t5,t5 + libdis_test+0x7c: b3 8f ff 01 add t6,t6,t6 + libdis_test+0x80: 33 80 20 00 add x0,ra,sp + libdis_test+0x84: b3 00 31 00 add ra,sp,gp + libdis_test+0x88: 33 81 41 00 add sp,gp,tp + libdis_test+0x8c: b3 01 52 00 add gp,tp,t0 + libdis_test+0x90: 33 82 62 00 add tp,t0,t1 + libdis_test+0x94: b3 02 73 00 add t0,t1,t2 + libdis_test+0x98: 33 83 83 00 add t1,t2,s0 + libdis_test+0x9c: b3 03 94 00 add t2,s0,s1 + libdis_test+0xa0: 33 84 a4 00 add s0,s1,a0 + libdis_test+0xa4: b3 04 b5 00 add s1,a0,a1 + libdis_test+0xa8: 33 85 c5 00 add a0,a1,a2 + libdis_test+0xac: b3 05 d6 00 add a1,a2,a3 + libdis_test+0xb0: 33 86 e6 00 add a2,a3,a4 + libdis_test+0xb4: b3 06 f7 00 add a3,a4,a5 + libdis_test+0xb8: 33 87 07 01 add a4,a5,a6 + libdis_test+0xbc: b3 07 18 01 add a5,a6,a7 + libdis_test+0xc0: 33 88 28 01 add a6,a7,s2 + libdis_test+0xc4: b3 08 39 01 add a7,s2,s3 + libdis_test+0xc8: 33 89 49 01 add s2,s3,s4 + libdis_test+0xcc: b3 09 5a 01 add s3,s4,s5 + libdis_test+0xd0: 33 8a 6a 01 add s4,s5,s6 + libdis_test+0xd4: b3 0a 7b 01 add s5,s6,s7 + libdis_test+0xd8: 33 8b 8b 01 add s6,s7,s8 + libdis_test+0xdc: b3 0b 9c 01 add s7,s8,s9 + libdis_test+0xe0: 33 8c ac 01 add s8,s9,s10 + libdis_test+0xe4: b3 0c bd 01 add s9,s10,s11 + libdis_test+0xe8: 33 8d cd 01 add s10,s11,t3 + libdis_test+0xec: b3 0d de 01 add s11,t3,t4 + libdis_test+0xf0: 33 8e ee 01 add t3,t4,t5 + libdis_test+0xf4: b3 0e ff 01 add t4,t5,t6 + libdis_test+0xf8: 33 8f 0f 00 add t5,t6,x0 + libdis_test+0xfc: b3 0f 10 00 add t6,x0,ra diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.regs.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.regs.s new file mode 100644 index 0000000000..7ccfd71924 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.regs.s @@ -0,0 +1,90 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test that we properly name all registers in their place. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + add x0, x0, x0 + add ra, ra, ra + add sp, sp, sp + add gp, gp, gp + add tp, tp, tp + add t0, t0, t0 + add t1, t1, t1 + add t2, t2, t2 + add s0, s0, s0 + add s1, s1, s1 + add a0, a0, a0 + add a1, a1, a1 + add a2, a2, a2 + add a3, a3, a3 + add a4, a4, a4 + add a5, a5, a5 + add a6, a6, a6 + add a7, a7, a7 + add s2, s2, s2 + add s3, s3, s3 + add s4, s4, s4 + add s5, s5, s5 + add s6, s6, s6 + add s7, s7, s7 + add s8, s8, s8 + add s9, s9, s9 + add s10, s10, s10 + add s11, s11, s11 + add t3, t3, t3 + add t4, t4, t4 + add t5, t5, t5 + add t6, t6, t6 + + add x0, ra, sp + add ra, sp, gp + add sp, gp, tp + add gp, tp, t0 + add tp, t0, t1 + add t0, t1, t2 + add t1, t2, s0 + add t2, s0, s1 + add s0, s1, a0 + add s1, a0, a1 + add a0, a1, a2 + add a1, a2, a3 + add a2, a3, a4 + add a3, a4, a5 + add a4, a5, a6 + add a5, a6, a7 + add a6, a7, s2 + add a7, s2, s3 + add s2, s3, s4 + add s3, s4, s5 + add s4, s5, s6 + add s5, s6, s7 + add s6, s7, s8 + add s7, s8, s9 + add s8, s9, s10 + add s9, s10, s11 + add s10, s11, t3 + add s11, t3, t4 + add t3, t4, t5 + add t4, t5, t6 + add t5, t6, x0 + add t6, x0, ra +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32a.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32a.out new file mode 100644 index 0000000000..9eb8112851 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32a.out @@ -0,0 +1,44 @@ + libdis_test: 2f a4 04 10 lr.w s0,(s1) + libdis_test+0x4: af 24 09 14 lr.w.aq s1,(s2) + libdis_test+0x8: 2f a9 09 12 lr.w.rl s2,(s3) + libdis_test+0xc: af 29 0a 16 lr.w.aqrl s3,(s4) + libdis_test+0x10: 2f a4 24 19 sc.w s0,s2,(s1) + libdis_test+0x14: af a4 34 1d sc.w.aq s1,s3,(s1) + libdis_test+0x18: 2f a9 44 1b sc.w.rl s2,s4,(s1) + libdis_test+0x1c: af a9 54 1f sc.w.aqrl s3,s5,(s1) + libdis_test+0x20: af a2 63 08 amoswap.w t0,t1,(t2) + libdis_test+0x24: 2f 23 7e 0c amoswap.w.aq t1,t2,(t3) + libdis_test+0x28: af a3 ce 0b amoswap.w.rl t2,t3,(t4) + libdis_test+0x2c: 2f 2e df 0f amoswap.w.aqrl t3,t4,(t5) + libdis_test+0x30: af a2 63 00 amoadd.w t0,t1,(t2) + libdis_test+0x34: 2f 23 7e 04 amoadd.w.aq t1,t2,(t3) + libdis_test+0x38: af a3 ce 03 amoadd.w.rl t2,t3,(t4) + libdis_test+0x3c: 2f 2e df 07 amoadd.w.aqrl t3,t4,(t5) + libdis_test+0x40: af a2 63 20 amoxor.w t0,t1,(t2) + libdis_test+0x44: 2f 23 7e 24 amoxor.w.aq t1,t2,(t3) + libdis_test+0x48: af a3 ce 23 amoxor.w.rl t2,t3,(t4) + libdis_test+0x4c: 2f 2e df 27 amoxor.w.aqrl t3,t4,(t5) + libdis_test+0x50: af a2 63 60 amoand.w t0,t1,(t2) + libdis_test+0x54: 2f 23 7e 64 amoand.w.aq t1,t2,(t3) + libdis_test+0x58: af a3 ce 63 amoand.w.rl t2,t3,(t4) + libdis_test+0x5c: 2f 2e df 67 amoand.w.aqrl t3,t4,(t5) + libdis_test+0x60: af a2 63 40 amoor.w t0,t1,(t2) + libdis_test+0x64: 2f 23 7e 44 amoor.w.aq t1,t2,(t3) + libdis_test+0x68: af a3 ce 43 amoor.w.rl t2,t3,(t4) + libdis_test+0x6c: 2f 2e df 47 amoor.w.aqrl t3,t4,(t5) + libdis_test+0x70: af a2 63 80 amomin.w t0,t1,(t2) + libdis_test+0x74: 2f 23 7e 84 amomin.w.aq t1,t2,(t3) + libdis_test+0x78: af a3 ce 83 amomin.w.rl t2,t3,(t4) + libdis_test+0x7c: 2f 2e df 87 amomin.w.aqrl t3,t4,(t5) + libdis_test+0x80: af a2 63 a0 amomax.w t0,t1,(t2) + libdis_test+0x84: 2f 23 7e a4 amomax.w.aq t1,t2,(t3) + libdis_test+0x88: af a3 ce a3 amomax.w.rl t2,t3,(t4) + libdis_test+0x8c: 2f 2e df a7 amomax.w.aqrl t3,t4,(t5) + libdis_test+0x90: af a2 63 c0 amominu.w t0,t1,(t2) + libdis_test+0x94: 2f 23 7e c4 amominu.w.aq t1,t2,(t3) + libdis_test+0x98: af a3 ce c3 amominu.w.rl t2,t3,(t4) + libdis_test+0x9c: 2f 2e df c7 amominu.w.aqrl t3,t4,(t5) + libdis_test+0xa0: af a2 63 e0 amomaxu.w t0,t1,(t2) + libdis_test+0xa4: 2f 23 7e e4 amomaxu.w.aq t1,t2,(t3) + libdis_test+0xa8: af a3 ce e3 amomaxu.w.rl t2,t3,(t4) + libdis_test+0xac: 2f 2e df e7 amomaxu.w.aqrl t3,t4,(t5) diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32a.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32a.s new file mode 100644 index 0000000000..147319db74 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32a.s @@ -0,0 +1,70 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV32A instructions. Instructions are ordered per the + * ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + lr.w s0, (s1) + lr.w.aq s1, (s2) + lr.w.rl s2, (s3) + lr.w.aqrl s3, (s4) + sc.w s0, s2, (s1) + sc.w.aq s1, s3, (s1) + sc.w.rl s2, s4, (s1) + sc.w.aqrl s3, s5, (s1) + amoswap.w t0, t1, (t2) + amoswap.w.aq t1, t2, (t3) + amoswap.w.rl t2, t3, (t4) + amoswap.w.aqrl t3, t4, (t5) + amoadd.w t0, t1, (t2) + amoadd.w.aq t1, t2, (t3) + amoadd.w.rl t2, t3, (t4) + amoadd.w.aqrl t3, t4, (t5) + amoxor.w t0, t1, (t2) + amoxor.w.aq t1, t2, (t3) + amoxor.w.rl t2, t3, (t4) + amoxor.w.aqrl t3, t4, (t5) + amoand.w t0, t1, (t2) + amoand.w.aq t1, t2, (t3) + amoand.w.rl t2, t3, (t4) + amoand.w.aqrl t3, t4, (t5) + amoor.w t0, t1, (t2) + amoor.w.aq t1, t2, (t3) + amoor.w.rl t2, t3, (t4) + amoor.w.aqrl t3, t4, (t5) + amomin.w t0, t1, (t2) + amomin.w.aq t1, t2, (t3) + amomin.w.rl t2, t3, (t4) + amomin.w.aqrl t3, t4, (t5) + amomax.w t0, t1, (t2) + amomax.w.aq t1, t2, (t3) + amomax.w.rl t2, t3, (t4) + amomax.w.aqrl t3, t4, (t5) + amominu.w t0, t1, (t2) + amominu.w.aq t1, t2, (t3) + amominu.w.rl t2, t3, (t4) + amominu.w.aqrl t3, t4, (t5) + amomaxu.w t0, t1, (t2) + amomaxu.w.aq t1, t2, (t3) + amomaxu.w.rl t2, t3, (t4) + amomaxu.w.aqrl t3, t4, (t5) +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32d.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32d.out new file mode 100644 index 0000000000..bef10b7f9e --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32d.out @@ -0,0 +1,90 @@ + libdis_test: 87 30 09 00 fld ft1,0x0(s2) + libdis_test+0x4: 87 30 c9 ff fld ft1,-0x4(s2) + libdis_test+0x8: 87 30 29 04 fld ft1,0x42(s2) + libdis_test+0xc: 27 30 19 00 fsd ft1,0x0(s2) + libdis_test+0x10: 27 3e 19 fe fsd ft1,-0x4(s2) + libdis_test+0x14: 27 31 19 04 fsd ft1,0x42(s2) + libdis_test+0x18: c3 70 31 22 fmadd.d ft1,ft2,ft3,ft4 + libdis_test+0x1c: c3 00 31 22 fmadd.d ft1,ft2,ft3,ft4,rne + libdis_test+0x20: c3 10 31 22 fmadd.d ft1,ft2,ft3,ft4,rtz + libdis_test+0x24: c3 20 31 22 fmadd.d ft1,ft2,ft3,ft4,rdn + libdis_test+0x28: c3 30 31 22 fmadd.d ft1,ft2,ft3,ft4,rup + libdis_test+0x2c: c3 40 31 22 fmadd.d ft1,ft2,ft3,ft4,rmm + libdis_test+0x30: c7 70 31 22 fmsub.d ft1,ft2,ft3,ft4 + libdis_test+0x34: c7 00 31 22 fmsub.d ft1,ft2,ft3,ft4,rne + libdis_test+0x38: c7 10 31 22 fmsub.d ft1,ft2,ft3,ft4,rtz + libdis_test+0x3c: c7 20 31 22 fmsub.d ft1,ft2,ft3,ft4,rdn + libdis_test+0x40: c7 30 31 22 fmsub.d ft1,ft2,ft3,ft4,rup + libdis_test+0x44: c7 40 31 22 fmsub.d ft1,ft2,ft3,ft4,rmm + libdis_test+0x48: cb 70 31 22 fnmsub.d ft1,ft2,ft3,ft4 + libdis_test+0x4c: cb 00 31 22 fnmsub.d ft1,ft2,ft3,ft4,rne + libdis_test+0x50: cb 10 31 22 fnmsub.d ft1,ft2,ft3,ft4,rtz + libdis_test+0x54: cb 20 31 22 fnmsub.d ft1,ft2,ft3,ft4,rdn + libdis_test+0x58: cb 30 31 22 fnmsub.d ft1,ft2,ft3,ft4,rup + libdis_test+0x5c: cb 40 31 22 fnmsub.d ft1,ft2,ft3,ft4,rmm + libdis_test+0x60: cf 70 31 22 fnmadd.d ft1,ft2,ft3,ft4 + libdis_test+0x64: cf 00 31 22 fnmadd.d ft1,ft2,ft3,ft4,rne + libdis_test+0x68: cf 10 31 22 fnmadd.d ft1,ft2,ft3,ft4,rtz + libdis_test+0x6c: cf 20 31 22 fnmadd.d ft1,ft2,ft3,ft4,rdn + libdis_test+0x70: cf 30 31 22 fnmadd.d ft1,ft2,ft3,ft4,rup + libdis_test+0x74: cf 40 31 22 fnmadd.d ft1,ft2,ft3,ft4,rmm + libdis_test+0x78: 53 f4 24 03 fadd.d fs0,fs1,fs2 + libdis_test+0x7c: d3 04 39 03 fadd.d fs1,fs2,fs3,rne + libdis_test+0x80: 53 99 49 03 fadd.d fs2,fs3,fs4,rtz + libdis_test+0x84: d3 29 5a 03 fadd.d fs3,fs4,fs5,rdn + libdis_test+0x88: 53 ba 6a 03 fadd.d fs4,fs5,fs6,rup + libdis_test+0x8c: d3 4a 7b 03 fadd.d fs5,fs6,fs7,rmm + libdis_test+0x90: 53 f4 24 0b fsub.d fs0,fs1,fs2 + libdis_test+0x94: d3 04 39 0b fsub.d fs1,fs2,fs3,rne + libdis_test+0x98: 53 99 49 0b fsub.d fs2,fs3,fs4,rtz + libdis_test+0x9c: d3 29 5a 0b fsub.d fs3,fs4,fs5,rdn + libdis_test+0xa0: 53 ba 6a 0b fsub.d fs4,fs5,fs6,rup + libdis_test+0xa4: d3 4a 7b 0b fsub.d fs5,fs6,fs7,rmm + libdis_test+0xa8: 53 f4 24 13 fmul.d fs0,fs1,fs2 + libdis_test+0xac: d3 04 39 13 fmul.d fs1,fs2,fs3,rne + libdis_test+0xb0: 53 99 49 13 fmul.d fs2,fs3,fs4,rtz + libdis_test+0xb4: d3 29 5a 13 fmul.d fs3,fs4,fs5,rdn + libdis_test+0xb8: 53 ba 6a 13 fmul.d fs4,fs5,fs6,rup + libdis_test+0xbc: d3 4a 7b 13 fmul.d fs5,fs6,fs7,rmm + libdis_test+0xc0: 53 f4 24 1b fdiv.d fs0,fs1,fs2 + libdis_test+0xc4: d3 04 39 1b fdiv.d fs1,fs2,fs3,rne + libdis_test+0xc8: 53 99 49 1b fdiv.d fs2,fs3,fs4,rtz + libdis_test+0xcc: d3 29 5a 1b fdiv.d fs3,fs4,fs5,rdn + libdis_test+0xd0: 53 ba 6a 1b fdiv.d fs4,fs5,fs6,rup + libdis_test+0xd4: d3 4a 7b 1b fdiv.d fs5,fs6,fs7,rmm + libdis_test+0xd8: 53 f4 04 5a fsqrt.d fs0,fs1 + libdis_test+0xdc: d3 04 09 5a fsqrt.d fs1,fs2,rne + libdis_test+0xe0: 53 99 09 5a fsqrt.d fs2,fs3,rtz + libdis_test+0xe4: d3 29 0a 5a fsqrt.d fs3,fs4,rdn + libdis_test+0xe8: 53 ba 0a 5a fsqrt.d fs4,fs5,rup + libdis_test+0xec: d3 4a 0b 5a fsqrt.d fs5,fs6,rmm + libdis_test+0xf0: 53 85 c5 22 fsgnj.d fa0,fa1,fa2 + libdis_test+0xf4: 53 95 c5 22 fsgnjn.d fa0,fa1,fa2 + libdis_test+0xf8: 53 a5 c5 22 fsgnjx.d fa0,fa1,fa2 + libdis_test+0xfc: 53 85 c5 2a fmin.d fa0,fa1,fa2 + libdis_test+0x100: 53 95 c5 2a fmax.d fa0,fa1,fa2 + libdis_test+0x104: 53 f4 14 40 fcvt.s.d fs0,fs1 + libdis_test+0x108: d3 04 19 40 fcvt.s.d fs1,fs2,rne + libdis_test+0x10c: 53 99 19 40 fcvt.s.d fs2,fs3,rtz + libdis_test+0x110: d3 29 1a 40 fcvt.s.d fs3,fs4,rdn + libdis_test+0x114: 53 ba 1a 40 fcvt.s.d fs4,fs5,rup + libdis_test+0x118: d3 4a 1b 40 fcvt.s.d fs5,fs6,rmm + libdis_test+0x11c: 53 85 05 42 fcvt.d.s fa0,fa1 + libdis_test+0x120: 53 25 7e a2 feq.d a0,ft8,ft7 + libdis_test+0x124: d3 15 7e a2 flt.d a1,ft8,ft7 + libdis_test+0x128: 53 06 7e a2 fle.d a2,ft8,ft7 + libdis_test+0x12c: d3 16 0e e2 fclass.d a3,ft8 + libdis_test+0x130: d3 f2 00 c2 fcvt.w.d t0,ft1 + libdis_test+0x134: 53 03 01 c2 fcvt.w.d t1,ft2,rne + libdis_test+0x138: d3 93 01 c2 fcvt.w.d t2,ft3,rtz + libdis_test+0x13c: 53 2e 02 c2 fcvt.w.d t3,ft4,rdn + libdis_test+0x140: d3 be 02 c2 fcvt.w.d t4,ft5,rup + libdis_test+0x144: 53 4f 03 c2 fcvt.w.d t5,ft6,rmm + libdis_test+0x148: d3 f2 10 c2 fcvt.wu.d t0,ft1 + libdis_test+0x14c: 53 03 11 c2 fcvt.wu.d t1,ft2,rne + libdis_test+0x150: d3 93 11 c2 fcvt.wu.d t2,ft3,rtz + libdis_test+0x154: 53 2e 12 c2 fcvt.wu.d t3,ft4,rdn + libdis_test+0x158: d3 be 12 c2 fcvt.wu.d t4,ft5,rup + libdis_test+0x15c: 53 4f 13 c2 fcvt.wu.d t5,ft6,rmm + libdis_test+0x160: d3 80 03 d2 fcvt.d.w ft1,t2 + libdis_test+0x164: d3 80 13 d2 fcvt.d.wu ft1,t2 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32d.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32d.s new file mode 100644 index 0000000000..9cbb0404f4 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32d.s @@ -0,0 +1,132 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV32D instructions. Instructions are ordered per + * the ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + fld ft1, (s2) + fld ft1, -0x4(s2) + fld ft1, 0x42(s2) + fsd ft1, (s2) + fsd ft1, -0x4(s2) + fsd ft1, 0x42(s2) + + fmadd.d ft1, ft2, ft3, ft4 + fmadd.d ft1, ft2, ft3, ft4, rne + fmadd.d ft1, ft2, ft3, ft4, rtz + fmadd.d ft1, ft2, ft3, ft4, rdn + fmadd.d ft1, ft2, ft3, ft4, rup + fmadd.d ft1, ft2, ft3, ft4, rmm + + fmsub.d ft1, ft2, ft3, ft4 + fmsub.d ft1, ft2, ft3, ft4, rne + fmsub.d ft1, ft2, ft3, ft4, rtz + fmsub.d ft1, ft2, ft3, ft4, rdn + fmsub.d ft1, ft2, ft3, ft4, rup + fmsub.d ft1, ft2, ft3, ft4, rmm + + fnmsub.d ft1, ft2, ft3, ft4 + fnmsub.d ft1, ft2, ft3, ft4, rne + fnmsub.d ft1, ft2, ft3, ft4, rtz + fnmsub.d ft1, ft2, ft3, ft4, rdn + fnmsub.d ft1, ft2, ft3, ft4, rup + fnmsub.d ft1, ft2, ft3, ft4, rmm + + fnmadd.d ft1, ft2, ft3, ft4 + fnmadd.d ft1, ft2, ft3, ft4, rne + fnmadd.d ft1, ft2, ft3, ft4, rtz + fnmadd.d ft1, ft2, ft3, ft4, rdn + fnmadd.d ft1, ft2, ft3, ft4, rup + fnmadd.d ft1, ft2, ft3, ft4, rmm + + fadd.d fs0, fs1, fs2 + fadd.d fs1, fs2, fs3, rne + fadd.d fs2, fs3, fs4, rtz + fadd.d fs3, fs4, fs5, rdn + fadd.d fs4, fs5, fs6, rup + fadd.d fs5, fs6, fs7, rmm + + fsub.d fs0, fs1, fs2 + fsub.d fs1, fs2, fs3, rne + fsub.d fs2, fs3, fs4, rtz + fsub.d fs3, fs4, fs5, rdn + fsub.d fs4, fs5, fs6, rup + fsub.d fs5, fs6, fs7, rmm + + fmul.d fs0, fs1, fs2 + fmul.d fs1, fs2, fs3, rne + fmul.d fs2, fs3, fs4, rtz + fmul.d fs3, fs4, fs5, rdn + fmul.d fs4, fs5, fs6, rup + fmul.d fs5, fs6, fs7, rmm + + fdiv.d fs0, fs1, fs2 + fdiv.d fs1, fs2, fs3, rne + fdiv.d fs2, fs3, fs4, rtz + fdiv.d fs3, fs4, fs5, rdn + fdiv.d fs4, fs5, fs6, rup + fdiv.d fs5, fs6, fs7, rmm + + fsqrt.d fs0, fs1 + fsqrt.d fs1, fs2, rne + fsqrt.d fs2, fs3, rtz + fsqrt.d fs3, fs4, rdn + fsqrt.d fs4, fs5, rup + fsqrt.d fs5, fs6, rmm + + fsgnj.d fa0, fa1, fa2 + fsgnjn.d fa0, fa1, fa2 + fsgnjx.d fa0, fa1, fa2 + fmin.d fa0, fa1, fa2 + fmax.d fa0, fa1, fa2 + + fcvt.s.d fs0, fs1 + fcvt.s.d fs1, fs2, rne + fcvt.s.d fs2, fs3, rtz + fcvt.s.d fs3, fs4, rdn + fcvt.s.d fs4, fs5, rup + fcvt.s.d fs5, fs6, rmm + + fcvt.d.s fa0, fa1 + + feq.d a0, ft8, ft7 + flt.d a1, ft8, ft7 + fle.d a2, ft8, ft7 + fclass.d a3, ft8 + + fcvt.w.d t0, ft1 + fcvt.w.d t1, ft2, rne + fcvt.w.d t2, ft3, rtz + fcvt.w.d t3, ft4, rdn + fcvt.w.d t4, ft5, rup + fcvt.w.d t5, ft6, rmm + + fcvt.wu.d t0, ft1 + fcvt.wu.d t1, ft2, rne + fcvt.wu.d t2, ft3, rtz + fcvt.wu.d t3, ft4, rdn + fcvt.wu.d t4, ft5, rup + fcvt.wu.d t5, ft6, rmm + + fcvt.d.w ft1, t2 + fcvt.d.wu ft1, t2 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32f.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32f.out new file mode 100644 index 0000000000..15264cfdde --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32f.out @@ -0,0 +1,95 @@ + libdis_test: 87 20 09 00 flw ft1,0x0(s2) + libdis_test+0x4: 87 20 c9 ff flw ft1,-0x4(s2) + libdis_test+0x8: 87 20 29 04 flw ft1,0x42(s2) + libdis_test+0xc: 27 20 19 00 fsw ft1,0x0(s2) + libdis_test+0x10: 27 2e 19 fe fsw ft1,-0x4(s2) + libdis_test+0x14: 27 21 19 04 fsw ft1,0x42(s2) + libdis_test+0x18: c3 70 31 20 fmadd.s ft1,ft2,ft3,ft4 + libdis_test+0x1c: c3 00 31 20 fmadd.s ft1,ft2,ft3,ft4,rne + libdis_test+0x20: c3 10 31 20 fmadd.s ft1,ft2,ft3,ft4,rtz + libdis_test+0x24: c3 20 31 20 fmadd.s ft1,ft2,ft3,ft4,rdn + libdis_test+0x28: c3 30 31 20 fmadd.s ft1,ft2,ft3,ft4,rup + libdis_test+0x2c: c3 40 31 20 fmadd.s ft1,ft2,ft3,ft4,rmm + libdis_test+0x30: c7 70 31 20 fmsub.s ft1,ft2,ft3,ft4 + libdis_test+0x34: c7 00 31 20 fmsub.s ft1,ft2,ft3,ft4,rne + libdis_test+0x38: c7 10 31 20 fmsub.s ft1,ft2,ft3,ft4,rtz + libdis_test+0x3c: c7 20 31 20 fmsub.s ft1,ft2,ft3,ft4,rdn + libdis_test+0x40: c7 30 31 20 fmsub.s ft1,ft2,ft3,ft4,rup + libdis_test+0x44: c7 40 31 20 fmsub.s ft1,ft2,ft3,ft4,rmm + libdis_test+0x48: cb 70 31 20 fnmsub.s ft1,ft2,ft3,ft4 + libdis_test+0x4c: cb 00 31 20 fnmsub.s ft1,ft2,ft3,ft4,rne + libdis_test+0x50: cb 10 31 20 fnmsub.s ft1,ft2,ft3,ft4,rtz + libdis_test+0x54: cb 20 31 20 fnmsub.s ft1,ft2,ft3,ft4,rdn + libdis_test+0x58: cb 30 31 20 fnmsub.s ft1,ft2,ft3,ft4,rup + libdis_test+0x5c: cb 40 31 20 fnmsub.s ft1,ft2,ft3,ft4,rmm + libdis_test+0x60: cf 70 31 20 fnmadd.s ft1,ft2,ft3,ft4 + libdis_test+0x64: cf 00 31 20 fnmadd.s ft1,ft2,ft3,ft4,rne + libdis_test+0x68: cf 10 31 20 fnmadd.s ft1,ft2,ft3,ft4,rtz + libdis_test+0x6c: cf 20 31 20 fnmadd.s ft1,ft2,ft3,ft4,rdn + libdis_test+0x70: cf 30 31 20 fnmadd.s ft1,ft2,ft3,ft4,rup + libdis_test+0x74: cf 40 31 20 fnmadd.s ft1,ft2,ft3,ft4,rmm + libdis_test+0x78: 53 f4 24 01 fadd.s fs0,fs1,fs2 + libdis_test+0x7c: d3 04 39 01 fadd.s fs1,fs2,fs3,rne + libdis_test+0x80: 53 99 49 01 fadd.s fs2,fs3,fs4,rtz + libdis_test+0x84: d3 29 5a 01 fadd.s fs3,fs4,fs5,rdn + libdis_test+0x88: 53 ba 6a 01 fadd.s fs4,fs5,fs6,rup + libdis_test+0x8c: d3 4a 7b 01 fadd.s fs5,fs6,fs7,rmm + libdis_test+0x90: 53 f4 24 09 fsub.s fs0,fs1,fs2 + libdis_test+0x94: d3 04 39 09 fsub.s fs1,fs2,fs3,rne + libdis_test+0x98: 53 99 49 09 fsub.s fs2,fs3,fs4,rtz + libdis_test+0x9c: d3 29 5a 09 fsub.s fs3,fs4,fs5,rdn + libdis_test+0xa0: 53 ba 6a 09 fsub.s fs4,fs5,fs6,rup + libdis_test+0xa4: d3 4a 7b 09 fsub.s fs5,fs6,fs7,rmm + libdis_test+0xa8: 53 f4 24 11 fmul.s fs0,fs1,fs2 + libdis_test+0xac: d3 04 39 11 fmul.s fs1,fs2,fs3,rne + libdis_test+0xb0: 53 99 49 11 fmul.s fs2,fs3,fs4,rtz + libdis_test+0xb4: d3 29 5a 11 fmul.s fs3,fs4,fs5,rdn + libdis_test+0xb8: 53 ba 6a 11 fmul.s fs4,fs5,fs6,rup + libdis_test+0xbc: d3 4a 7b 11 fmul.s fs5,fs6,fs7,rmm + libdis_test+0xc0: 53 f4 24 19 fdiv.s fs0,fs1,fs2 + libdis_test+0xc4: d3 04 39 19 fdiv.s fs1,fs2,fs3,rne + libdis_test+0xc8: 53 99 49 19 fdiv.s fs2,fs3,fs4,rtz + libdis_test+0xcc: d3 29 5a 19 fdiv.s fs3,fs4,fs5,rdn + libdis_test+0xd0: 53 ba 6a 19 fdiv.s fs4,fs5,fs6,rup + libdis_test+0xd4: d3 4a 7b 19 fdiv.s fs5,fs6,fs7,rmm + libdis_test+0xd8: 53 f4 04 58 fsqrt.s fs0,fs1 + libdis_test+0xdc: d3 04 09 58 fsqrt.s fs1,fs2,rne + libdis_test+0xe0: 53 99 09 58 fsqrt.s fs2,fs3,rtz + libdis_test+0xe4: d3 29 0a 58 fsqrt.s fs3,fs4,rdn + libdis_test+0xe8: 53 ba 0a 58 fsqrt.s fs4,fs5,rup + libdis_test+0xec: d3 4a 0b 58 fsqrt.s fs5,fs6,rmm + libdis_test+0xf0: 53 85 c5 20 fsgnj.s fa0,fa1,fa2 + libdis_test+0xf4: 53 95 c5 20 fsgnjn.s fa0,fa1,fa2 + libdis_test+0xf8: 53 a5 c5 20 fsgnjx.s fa0,fa1,fa2 + libdis_test+0xfc: 53 85 c5 28 fmin.s fa0,fa1,fa2 + libdis_test+0x100: 53 95 c5 28 fmax.s fa0,fa1,fa2 + libdis_test+0x104: d3 f2 00 c0 fcvt.w.s t0,ft1 + libdis_test+0x108: 53 03 01 c0 fcvt.w.s t1,ft2,rne + libdis_test+0x10c: d3 93 01 c0 fcvt.w.s t2,ft3,rtz + libdis_test+0x110: 53 2e 02 c0 fcvt.w.s t3,ft4,rdn + libdis_test+0x114: d3 be 02 c0 fcvt.w.s t4,ft5,rup + libdis_test+0x118: 53 4f 03 c0 fcvt.w.s t5,ft6,rmm + libdis_test+0x11c: d3 f2 10 c0 fcvt.wu.s t0,ft1 + libdis_test+0x120: 53 03 11 c0 fcvt.wu.s t1,ft2,rne + libdis_test+0x124: d3 93 11 c0 fcvt.wu.s t2,ft3,rtz + libdis_test+0x128: 53 2e 12 c0 fcvt.wu.s t3,ft4,rdn + libdis_test+0x12c: d3 be 12 c0 fcvt.wu.s t4,ft5,rup + libdis_test+0x130: 53 4f 13 c0 fcvt.wu.s t5,ft6,rmm + libdis_test+0x134: d3 82 00 e0 fmv.x.w t0,ft1 + libdis_test+0x138: 53 25 7e a0 feq.s a0,ft8,ft7 + libdis_test+0x13c: d3 15 7e a0 flt.s a1,ft8,ft7 + libdis_test+0x140: 53 06 7e a0 fle.s a2,ft8,ft7 + libdis_test+0x144: d3 16 0e e0 fclass.s a3,ft8 + libdis_test+0x148: d3 f0 03 d0 fcvt.s.w ft1,t2 + libdis_test+0x14c: 53 01 0e d0 fcvt.s.w ft2,t3,rne + libdis_test+0x150: d3 91 0e d0 fcvt.s.w ft3,t4,rtz + libdis_test+0x154: 53 22 0f d0 fcvt.s.w ft4,t5,rdn + libdis_test+0x158: d3 b2 0f d0 fcvt.s.w ft5,t6,rup + libdis_test+0x15c: 53 c3 0f d0 fcvt.s.w ft6,t6,rmm + libdis_test+0x160: d3 f0 13 d0 fcvt.s.wu ft1,t2 + libdis_test+0x164: 53 01 1e d0 fcvt.s.wu ft2,t3,rne + libdis_test+0x168: d3 91 1e d0 fcvt.s.wu ft3,t4,rtz + libdis_test+0x16c: 53 22 1f d0 fcvt.s.wu ft4,t5,rdn + libdis_test+0x170: d3 b2 1f d0 fcvt.s.wu ft5,t6,rup + libdis_test+0x174: 53 c3 1f d0 fcvt.s.wu ft6,t6,rmm + libdis_test+0x178: 53 0d 0d f0 fmv.w.x fs10,s10 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32f.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32f.s new file mode 100644 index 0000000000..cc3dfd2cc6 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32f.s @@ -0,0 +1,137 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV32F instructions. Instructions are ordered per + * the ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + flw ft1, (s2) + flw ft1, -0x4(s2) + flw ft1, 0x42(s2) + fsw ft1, (s2) + fsw ft1, -0x4(s2) + fsw ft1, 0x42(s2) + + fmadd.s ft1, ft2, ft3, ft4 + fmadd.s ft1, ft2, ft3, ft4, rne + fmadd.s ft1, ft2, ft3, ft4, rtz + fmadd.s ft1, ft2, ft3, ft4, rdn + fmadd.s ft1, ft2, ft3, ft4, rup + fmadd.s ft1, ft2, ft3, ft4, rmm + + fmsub.s ft1, ft2, ft3, ft4 + fmsub.s ft1, ft2, ft3, ft4, rne + fmsub.s ft1, ft2, ft3, ft4, rtz + fmsub.s ft1, ft2, ft3, ft4, rdn + fmsub.s ft1, ft2, ft3, ft4, rup + fmsub.s ft1, ft2, ft3, ft4, rmm + + fnmsub.s ft1, ft2, ft3, ft4 + fnmsub.s ft1, ft2, ft3, ft4, rne + fnmsub.s ft1, ft2, ft3, ft4, rtz + fnmsub.s ft1, ft2, ft3, ft4, rdn + fnmsub.s ft1, ft2, ft3, ft4, rup + fnmsub.s ft1, ft2, ft3, ft4, rmm + + fnmadd.s ft1, ft2, ft3, ft4 + fnmadd.s ft1, ft2, ft3, ft4, rne + fnmadd.s ft1, ft2, ft3, ft4, rtz + fnmadd.s ft1, ft2, ft3, ft4, rdn + fnmadd.s ft1, ft2, ft3, ft4, rup + fnmadd.s ft1, ft2, ft3, ft4, rmm + + fadd.s fs0, fs1, fs2 + fadd.s fs1, fs2, fs3, rne + fadd.s fs2, fs3, fs4, rtz + fadd.s fs3, fs4, fs5, rdn + fadd.s fs4, fs5, fs6, rup + fadd.s fs5, fs6, fs7, rmm + + fsub.s fs0, fs1, fs2 + fsub.s fs1, fs2, fs3, rne + fsub.s fs2, fs3, fs4, rtz + fsub.s fs3, fs4, fs5, rdn + fsub.s fs4, fs5, fs6, rup + fsub.s fs5, fs6, fs7, rmm + + fmul.s fs0, fs1, fs2 + fmul.s fs1, fs2, fs3, rne + fmul.s fs2, fs3, fs4, rtz + fmul.s fs3, fs4, fs5, rdn + fmul.s fs4, fs5, fs6, rup + fmul.s fs5, fs6, fs7, rmm + + fdiv.s fs0, fs1, fs2 + fdiv.s fs1, fs2, fs3, rne + fdiv.s fs2, fs3, fs4, rtz + fdiv.s fs3, fs4, fs5, rdn + fdiv.s fs4, fs5, fs6, rup + fdiv.s fs5, fs6, fs7, rmm + + fsqrt.s fs0, fs1 + fsqrt.s fs1, fs2, rne + fsqrt.s fs2, fs3, rtz + fsqrt.s fs3, fs4, rdn + fsqrt.s fs4, fs5, rup + fsqrt.s fs5, fs6, rmm + + fsgnj.s fa0, fa1, fa2 + fsgnjn.s fa0, fa1, fa2 + fsgnjx.s fa0, fa1, fa2 + fmin.s fa0, fa1, fa2 + fmax.s fa0, fa1, fa2 + + fcvt.w.s t0, ft1 + fcvt.w.s t1, ft2, rne + fcvt.w.s t2, ft3, rtz + fcvt.w.s t3, ft4, rdn + fcvt.w.s t4, ft5, rup + fcvt.w.s t5, ft6, rmm + + fcvt.wu.s t0, ft1 + fcvt.wu.s t1, ft2, rne + fcvt.wu.s t2, ft3, rtz + fcvt.wu.s t3, ft4, rdn + fcvt.wu.s t4, ft5, rup + fcvt.wu.s t5, ft6, rmm + + fmv.x.w t0, ft1 + feq.s a0, ft8, ft7 + flt.s a1, ft8, ft7 + fle.s a2, ft8, ft7 + fclass.s a3, ft8 + + fcvt.s.w ft1, t2 + fcvt.s.w ft2, t3, rne + fcvt.s.w ft3, t4, rtz + fcvt.s.w ft4, t5, rdn + fcvt.s.w ft5, t6, rup + fcvt.s.w ft6, t6, rmm + + fcvt.s.wu ft1, t2 + fcvt.s.wu ft2, t3, rne + fcvt.s.wu ft3, t4, rtz + fcvt.s.wu ft4, t5, rdn + fcvt.s.wu ft5, t6, rup + fcvt.s.wu ft6, t6, rmm + + fmv.w.x fs10, s10 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32i.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32i.out new file mode 100644 index 0000000000..833a04c99c --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32i.out @@ -0,0 +1,60 @@ + libdis_test: b7 00 00 00 lui ra,0x0 + libdis_test+0x4: b7 30 02 00 lui ra,0x23 + libdis_test+0x8: b7 f0 ff ff lui ra,0xfffff + libdis_test+0xc: 97 00 00 00 auipc ra,0x0 + libdis_test+0x10: 97 30 02 00 auipc ra,0x23 + libdis_test+0x14: 97 f0 ff ff auipc ra,0xfffff + libdis_test+0x18: 03 84 f4 7f lb s0,0x7ff(s1) + libdis_test+0x1c: 83 84 04 00 lb s1,0x0(s1) + libdis_test+0x20: 03 89 04 80 lb s2,-0x800(s1) + libdis_test+0x24: 83 99 f4 7f lh s3,0x7ff(s1) + libdis_test+0x28: 03 9a 04 00 lh s4,0x0(s1) + libdis_test+0x2c: 83 9a 04 80 lh s5,-0x800(s1) + libdis_test+0x30: 03 ab f4 7f lw s6,0x7ff(s1) + libdis_test+0x34: 83 ab 04 00 lw s7,0x0(s1) + libdis_test+0x38: 03 ac 04 80 lw s8,-0x800(s1) + libdis_test+0x3c: 83 cb f4 7f lbu s7,0x7ff(s1) + libdis_test+0x40: 03 cb 04 00 lbu s6,0x0(s1) + libdis_test+0x44: 83 ca 04 80 lbu s5,-0x800(s1) + libdis_test+0x48: 03 da f4 7f lhu s4,0x7ff(s1) + libdis_test+0x4c: 83 d9 04 00 lhu s3,0x0(s1) + libdis_test+0x50: 03 d9 04 80 lhu s2,-0x800(s1) + libdis_test+0x54: a3 0f 53 7e sb t0,0x7ff(t1) + libdis_test+0x58: 23 80 63 00 sb t1,0x0(t2) + libdis_test+0x5c: 23 00 7e 80 sb t2,-0x800(t3) + libdis_test+0x60: a3 1f c3 7f sh t3,0x7ff(t1) + libdis_test+0x64: 23 90 d3 01 sh t4,0x0(t2) + libdis_test+0x68: 23 10 ee 81 sh t5,-0x800(t3) + libdis_test+0x6c: a3 2f d3 7f sw t4,0x7ff(t1) + libdis_test+0x70: 23 a0 c3 01 sw t3,0x0(t2) + libdis_test+0x74: 23 20 7e 80 sw t2,-0x800(t3) + libdis_test+0x78: 93 80 42 00 addi ra,t0,0x4 + libdis_test+0x7c: 93 80 c2 ff addi ra,t0,-0x4 + libdis_test+0x80: 93 a0 42 00 slti ra,t0,0x4 + libdis_test+0x84: 93 a0 c2 ff slti ra,t0,-0x4 + libdis_test+0x88: 93 b0 42 00 sltiu ra,t0,0x4 + libdis_test+0x8c: 93 b0 c2 ff sltiu ra,t0,-0x4 + libdis_test+0x90: 93 c0 42 00 xori ra,t0,0x4 + libdis_test+0x94: 93 c0 c2 ff xori ra,t0,-0x4 + libdis_test+0x98: 93 e0 42 00 ori ra,t0,0x4 + libdis_test+0x9c: 93 e0 c2 ff ori ra,t0,-0x4 + libdis_test+0xa0: 93 f0 42 00 andi ra,t0,0x4 + libdis_test+0xa4: 93 f0 c2 ff andi ra,t0,-0x4 + libdis_test+0xa8: 93 1e 2f 01 slli t4,t5,0x12 + libdis_test+0xac: 93 5e 3f 01 srli t4,t5,0x13 + libdis_test+0xb0: 93 5e 4f 41 srai t4,t5,0x14 + libdis_test+0xb4: 33 84 24 01 add s0,s1,s2 + libdis_test+0xb8: b3 04 39 41 sub s1,s2,s3 + libdis_test+0xbc: b3 19 5a 01 sll s3,s4,s5 + libdis_test+0xc0: 33 aa 6a 01 slt s4,s5,s6 + libdis_test+0xc4: 33 b5 15 00 sltu a0,a1,ra + libdis_test+0xc8: b3 4a 7b 01 xor s5,s6,s7 + libdis_test+0xcc: 33 db 8b 01 srl s6,s7,s8 + libdis_test+0xd0: b3 5b 9c 41 sra s7,s8,s9 + libdis_test+0xd4: 33 ec ac 01 or s8,s9,s10 + libdis_test+0xd8: b3 7c bd 01 and s9,s10,s11 + libdis_test+0xdc: 0f 00 f0 0f fence + libdis_test+0xe0: 0f 00 a0 05 fence ow, ir + libdis_test+0xe4: 0f 00 50 0a fence ir, ow + libdis_test+0xe8: 0f 00 f0 0e fence ior, iorw + libdis_test+0xec: 0f 10 00 00 fence.i diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32i.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32i.s new file mode 100644 index 0000000000..98938cf3cb --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32i.s @@ -0,0 +1,91 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV32I instructions. Instructions are ordered per + * the ISA manual. Supervisor and CSR instructions are elsewhere. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + lui ra, 0x00 + lui ra, 0x23 + lui ra, 0xfffff + auipc ra, 0x00 + auipc ra, 0x23 + auipc ra, 0xfffff + /* + * Branches are not tested at this time as they basially always end up + * wanting to create which ends up not really lending itself to + * automated testing here. + */ + lb s0, 0x7ff(s1) + lb s1, (s1) + lb s2, -0x800(s1) + lh s3, 0x7ff(s1) + lh s4, (s1) + lh s5, -0x800(s1) + lw s6, 0x7ff(s1) + lw s7, (s1) + lw s8, -0x800(s1) + lbu s7, 0x7ff(s1) + lbu s6, (s1) + lbu s5, -0x800(s1) + lhu s4, 0x7ff(s1) + lhu s3, (s1) + lhu s2, -0x800(s1) + sb t0, 0x7ff(t1) + sb t1, (t2) + sb t2, -0x800(t3) + sh t3, 0x7ff(t1) + sh t4, (t2) + sh t5, -0x800(t3) + sw t4, 0x7ff(t1) + sw t3, (t2) + sw t2, -0x800(t3) + addi ra, t0, 0x4 + addi ra, t0, -0x4 + slti ra, t0, 0x4 + slti ra, t0, -0x4 + sltiu ra, t0, 0x4 + sltiu ra, t0, -0x4 + xori ra, t0, 0x4 + xori ra, t0, -0x4 + ori ra, t0, 0x4 + ori ra, t0, -0x4 + andi ra, t0, 0x4 + andi ra, t0, -0x4 + slli t4, t5, 0x12 + srli t4, t5, 0x13 + srai t4, t5, 0x14 + add s0, s1, s2 + sub s1, s2, s3 + sll s3, s4, s5 + slt s4, s5, s6 + sltu a0, a1, ra + xor s5, s6, s7 + srl s6, s7, s8 + sra s7, s8, s9 + or s8, s9, s10 + and s9, s10, s11 + fence + fence ow, ir + fence ir, ow + fence ior, iorw + fence.i +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32m.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32m.out new file mode 100644 index 0000000000..87aa4e5da6 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32m.out @@ -0,0 +1,8 @@ + libdis_test: 33 84 24 03 mul s0,s1,s2 + libdis_test+0x4: b3 14 39 03 mulh s1,s2,s3 + libdis_test+0x8: 33 a9 49 03 mulhsu s2,s3,s4 + libdis_test+0xc: b3 39 5a 03 mulhu s3,s4,s5 + libdis_test+0x10: 33 ca 6a 03 div s4,s5,s6 + libdis_test+0x14: b3 5a 7b 03 divu s5,s6,s7 + libdis_test+0x18: 33 eb 8b 03 rem s6,s7,s8 + libdis_test+0x1c: b3 7b 9c 03 remu s7,s8,s9 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32m.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32m.s new file mode 100644 index 0000000000..241fd5a7bd --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.rv32m.s @@ -0,0 +1,34 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of the RV32M instructions. Instructions are ordered per the + * ISA manual. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + mul s0, s1, s2 + mulh s1, s2, s3 + mulhsu s2, s3, s4 + mulhu s3, s4, s5 + div s4, s5, s6 + divu s5, s6, s7 + rem s6, s7, s8 + remu s7, s8, s9 +.size libdis_test, [.-libdis_test] diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.supervisor.out b/usr/src/test/util-tests/tests/dis/risc-v/tst.supervisor.out new file mode 100644 index 0000000000..26299cce28 --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.supervisor.out @@ -0,0 +1,7 @@ + libdis_test: 73 00 00 00 ecall + libdis_test+0x4: 73 00 10 00 ebreak + libdis_test+0x8: 73 00 20 00 uret + libdis_test+0xc: 73 00 20 10 sret + libdis_test+0x10: 73 00 20 30 mret + libdis_test+0x14: 73 00 50 10 wfi + libdis_test+0x18: 73 80 62 12 sfence.vma t0,t1 diff --git a/usr/src/test/util-tests/tests/dis/risc-v/tst.supervisor.s b/usr/src/test/util-tests/tests/dis/risc-v/tst.supervisor.s new file mode 100644 index 0000000000..883a08648b --- /dev/null +++ b/usr/src/test/util-tests/tests/dis/risc-v/tst.supervisor.s @@ -0,0 +1,32 @@ +/* + * This file and its contents are supplied under the terms of the + * Common Development and Distribution License ("CDDL"), version 1.0. + * You may only use this file in accordance with the terms of version + * 1.0 of the CDDL. + * + * A full copy of the text of the CDDL should have accompanied this + * source. A copy of the CDDL is also available via the Internet at + * http://www.illumos.org/license/CDDL. + */ + +/* + * Copyright 2018, Joyent, Inc. + */ + +/* + * Test our disassembly of supervisor instructions. + */ + +.text +.align 16 +.globl libdis_test +.type libdis_test, @function +libdis_test: + ecall + ebreak + uret + sret + mret + wfi + sfence.vma t0, t1 +.size libdis_test, [.-libdis_test] |