From b0284f1645191d8458c80755f8049c799e63d689 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 29 May 2023 17:24:14 +0800 Subject: [PATCH 01/34] RV64: Added skeleton code for encoder --- core/ir/riscv64/codec.c | 9 ++++++ core/ir/riscv64/codec.h | 4 +++ core/ir/riscv64/decode_private.h | 2 +- core/ir/riscv64/encode.c | 51 ++++++++++++++++++++++++++++---- 4 files changed, 59 insertions(+), 7 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 61ecd735c1c..0ecb026e9a8 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -1401,3 +1401,12 @@ decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr) instr_set_opcode(instr, OP_INVALID); return NULL; } + +uint +encode_common(byte *pc, instr_t *i, decode_info_t *di) +{ + ASSERT(((ptr_int_t)pc & 1) == 0); + + /* FIXME i#3544: Not implemented */ + return ENCFAIL; +} diff --git a/core/ir/riscv64/codec.h b/core/ir/riscv64/codec.h index fc09bc11d50..019c2335f0a 100644 --- a/core/ir/riscv64/codec.h +++ b/core/ir/riscv64/codec.h @@ -45,6 +45,8 @@ * (which might be used as vendor ISA extensions). */ +#define ENCFAIL (uint)0x0 /* An invalid instruction (a.k.a c.unimp). */ + /* List of ISA extensions handled by the codec. */ typedef enum { RISCV64_ISA_EXT_RV32A, @@ -278,5 +280,7 @@ get_instruction_info(uint opc); byte * decode_common(dcontext_t *dc, byte *pc, byte *orig_pc, instr_t *instr); +uint +encode_common(byte *pc, instr_t *i, decode_info_t *di); #endif /* CODEC_H */ diff --git a/core/ir/riscv64/decode_private.h b/core/ir/riscv64/decode_private.h index 9dc26fb70bd..c3da8546a53 100644 --- a/core/ir/riscv64/decode_private.h +++ b/core/ir/riscv64/decode_private.h @@ -34,7 +34,7 @@ #define DECODE_PRIVATE_H 1 struct _decode_info_t { - /* FIXME i#3544: Add decoding info. */ + bool check_reachable; /* This is used by the encoder, not the decoder. */ }; #endif /* DECODE_PRIVATE_H */ diff --git a/core/ir/riscv64/encode.c b/core/ir/riscv64/encode.c index bf8debe9f2a..76aa13c29c1 100644 --- a/core/ir/riscv64/encode.c +++ b/core/ir/riscv64/encode.c @@ -31,7 +31,11 @@ */ #include "../globals.h" +#include "arch.h" #include "decode.h" +#include "decode_private.h" +#include "disassemble.h" +#include "codec.h" /* Order corresponds to DR_REG_ enum. */ /* clang-format off */ @@ -96,16 +100,51 @@ instr_encode_arch(dcontext_t *dcontext, instr_t *instr, byte *copy_pc, byte *fin bool *has_instr_opnds /*OUT OPTIONAL*/ _IF_DEBUG(bool assert_reachable)) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); - return NULL; + decode_info_t di; + uint enc; + + if (has_instr_opnds != NULL) { + *has_instr_opnds = false; + } + + if (instr_is_label(instr)) { + return copy_pc; + } + + /* First, handle the already-encoded instructions. */ + if (instr_raw_bits_valid(instr)) { + CLIENT_ASSERT(check_reachable, + "internal encode error: cannot encode raw " + "bits and ignore reachability"); + /* Copy raw bits, possibly re-relativizing */ + return copy_and_re_relativize_raw_instr(dcontext, instr, copy_pc, final_pc); + } + CLIENT_ASSERT(instr_operands_valid(instr), "instr_encode error: operands invalid"); + di.check_reachable = check_reachable; + enc = encode_common(final_pc, instr, &di); + if (enc == ENCFAIL) { + IF_DEBUG({ + if (assert_reachable) { + char disas_instr[MAX_INSTR_DIS_SZ]; + instr_disassemble_to_buffer(dcontext, instr, disas_instr, + MAX_INSTR_DIS_SZ); + SYSLOG_INTERNAL_ERROR("Internal Error: Failed to encode instruction:" + " '%s'\n", + disas_instr); + } + }); + return NULL; + } + *(uint *)copy_pc = enc; + return copy_pc + 4; } byte * copy_and_re_relativize_raw_instr(dcontext_t *dcontext, instr_t *instr, byte *dst_pc, byte *final_pc) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); - return NULL; + /* TODO i#3544: re-relativizing is NYI */ + ASSERT(instr_raw_bits_valid(instr)); + memcpy(dst_pc, instr->bytes, instr->length); + return dst_pc + instr->length; } From 8e3e355bb43fbb7c3b3512a73f63d9902e045c2c Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 29 May 2023 22:24:48 +0800 Subject: [PATCH 02/34] RV64: Fixed disassemble Register names and DR_REG enums are 1-to-1 mapped, must correspond strictly. --- core/ir/opnd_api.h | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index 5d75497bcd1..c2060a05eba 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1174,7 +1174,6 @@ enum { DR_REG_X29, /**< The x29(t4) register. */ DR_REG_X30, /**< The x30(t5) register. */ DR_REG_X31, /**< The x31(t6) register. */ - DR_REG_PC, /**< The program counter. */ /* GPR aliases */ DR_REG_ZERO = DR_REG_X0, /**< The hard-wired zero (x0) register. */ DR_REG_RA = DR_REG_X1, /**< The return address (x1) register. */ @@ -1209,6 +1208,7 @@ enum { DR_REG_T4 = DR_REG_X29, /**< The 5th temporary (x29) register. */ DR_REG_T5 = DR_REG_X30, /**< The 6th temporary (x30) register. */ DR_REG_T6 = DR_REG_X31, /**< The 7th temporary (x31) register. */ + DR_REG_PC, /**< The program counter. */ /* Floating point registers */ DR_REG_F0, /**< The f0(ft0) floating-point register. */ DR_REG_F1, /**< The f1(ft1) floating-point register. */ @@ -1908,6 +1908,12 @@ struct _opnd_t { } base_disp; /* BASE_DISP_kind */ void *addr; /* REL_ADDR_kind and ABS_ADDR_kind */ } value; +# ifdef RISCV64 + /* Used by disassemble, indicates whether an immediate value should be formatted + * in decimal or hexadecimal, valid iff opnd is an IMMED_INTEGER_kind. + */ + bool decimal; +# endif }; #endif /* DR_FAST_IR */ From 160a962b61197c3b1cb1e4834e606fe6425ae248 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Mon, 29 May 2023 22:26:05 +0800 Subject: [PATCH 03/34] RV64: Optimize disassembled immediates format --- core/ir/riscv64/codec.c | 19 +++++++++++++++++++ core/ir/riscv64/disassemble.c | 19 ++----------------- 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 0ecb026e9a8..704a9e0358f 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -257,6 +257,7 @@ decode_fm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc { int32_t imm = GET_FIELD(inst, 31, 28); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -272,6 +273,7 @@ decode_pred_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_ { int32_t imm = GET_FIELD(inst, 27, 24); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -287,6 +289,7 @@ decode_succ_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_ { int32_t imm = GET_FIELD(inst, 23, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -302,6 +305,7 @@ decode_aqrl_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_ { int32_t imm = GET_FIELD(inst, 26, 25); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -321,6 +325,7 @@ decode_csr_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_p */ int32_t imm = GET_FIELD(inst, 31, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -338,6 +343,7 @@ decode_rm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc { int32_t imm = GET_FIELD(inst, 14, 12); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -353,6 +359,7 @@ decode_shamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = GET_FIELD(inst, 25, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -368,6 +375,7 @@ decode_shamt5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori { int32_t imm = GET_FIELD(inst, 24, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -384,6 +392,7 @@ decode_shamt6_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori /* shamt6 >= 64 only makes sense on RV128 but let user take care of it. */ int32_t imm = GET_FIELD(inst, 26, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -402,6 +411,7 @@ decode_i_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -421,6 +431,7 @@ decode_s_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | (GET_FIELD(inst, 11, 7)); imm = SIGN_EXTEND(imm, 12); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -444,6 +455,7 @@ decode_b_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig imm = SIGN_EXTEND(imm, 13); opnd_t opnd = opnd_create_pc(orig_pc + imm); + opnd.decimal = false; instr_set_target(out, opnd); return true; } @@ -462,6 +474,7 @@ decode_u_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { uint uimm = GET_FIELD(inst, 31, 12); opnd_t opnd = opnd_create_immed_int(uimm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -676,6 +689,7 @@ decode_cshamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori { int32_t imm = (BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -694,6 +708,7 @@ decode_csr_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or { int32_t imm = GET_FIELD(inst, 19, 15); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -717,6 +732,7 @@ decode_caddi16sp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, imm |= (BIT(inst, 6) << 4); imm = SIGN_EXTEND(imm, 10); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -775,6 +791,7 @@ decode_clui_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *o { int32_t imm = (BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -832,6 +849,7 @@ decode_ciw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or imm |= BIT(inst, 5) << 3; imm |= BIT(inst, 6) << 2; opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } @@ -934,6 +952,7 @@ decode_cimm5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = SIGN_EXTEND((BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2), 6); opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd.decimal = true; instr_set_src(out, idx, opnd); return true; } diff --git a/core/ir/riscv64/disassemble.c b/core/ir/riscv64/disassemble.c index fe8f9d523e1..e201c27e110 100644 --- a/core/ir/riscv64/disassemble.c +++ b/core/ir/riscv64/disassemble.c @@ -64,14 +64,6 @@ opnd_base_disp_scale_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, ASSERT_NOT_REACHED(); } -static inline const char * -immed_prefix(void) -{ - return (TEST(DR_DISASM_INTEL, DYNAMO_OPTION(disasm_mask)) - ? "" - : (TEST(DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask)) ? "#" : "$")); -} - bool opnd_disassemble_arch(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t opnd) { @@ -79,13 +71,8 @@ opnd_disassemble_arch(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t opnd) case IMMED_INTEGER_kind: { /* Immediates are sign-extended at the decode time. */ ptr_int_t val = opnd_get_immed_int(opnd); - const char *sign = val < 0 ? "-" : ""; - if (val < 0) - val = -val; - /* FIXME i#3544: objdump shows some immediates in decimal (i.e. addi). - * Should we try to differentiate those here too? - */ - print_to_buffer(buf, bufsz, sofar, "%s%s0x%x", immed_prefix(), sign, val); + const char *fmt = opnd.decimal ? "%d" : "0x%x"; + print_to_buffer(buf, bufsz, sofar, fmt, val); return true; } } @@ -107,8 +94,6 @@ void print_instr_prefixes(dcontext_t *dcontext, instr_t *instr, char *buf, size_t bufsz, size_t *sofar INOUT) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); } void From 126170c189b65f5e00618f3992fbe49a3480724a Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Tue, 30 May 2023 18:50:39 +0800 Subject: [PATCH 04/34] RV64: Added an encoder --- core/ir/riscv64/codec.c | 962 +++++++++++++++++++++++++++++++++++++++- core/ir/riscv64/codec.h | 1 + 2 files changed, 953 insertions(+), 10 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 704a9e0358f..ab0281fbeb7 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -920,7 +920,7 @@ decode_csw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or /* Decode the base register and offset immediate of c.sd and c.fsd * instructions: - * |15 13|12 10|9 7|6 5|4 2|1 0| + * |15 13|12 10|9 7|6 5|4 2|1 0| * | ... | imm[5:3] | rs1' | imm[7:6] | ... | opcode | * ^--------^ ^----^ ^--------^ * Into: @@ -982,12 +982,12 @@ decode_cb_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori } /* Decode the immediate field of the CJ-type format as a pc-relative offset: - * |15 13|12 10|9 7|6 2|1 0| - * | ... | imm[8|4:3] | ... | imm[7:6|2:1|5] | opcode | - * ^----------^ ^--------------^ + * |15 13|12 2|1 0| + * | ... | [11|4|9:8|10|6|7|3:1|5] | opcode | + * ^-----------------------^ * Into: - * |31 8|7 1| 0 | - * | imm[8] | imm[7:1] | 0 | + * |31 11|10 1| 0 | + * | imm[11] | imm[10:1] | 0 | */ static bool decode_cj_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc, @@ -1421,11 +1421,953 @@ decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr) return NULL; } -uint -encode_common(byte *pc, instr_t *i, decode_info_t *di) + +/* Instruction operand encoder function. + * + * Encodes an operand from a given instr_t into the instruction. + */ +typedef bool (*opnd_enc_func_t)(instr_t *instr, byte *pc, int idx, uint32_t *out); + +/********************************************************** + * Format encoding functions. + */ + +/* Dummy function for catching invalid operand values. Should never be called. + */ +static bool +encode_none_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { - ASSERT(((ptr_int_t)pc & 1) == 0); + ASSERT_NOT_REACHED(); + return false; +} + +/* Encode the destination fixed-point register field: + * |31 12|11 7|6 0| + * | ... | rd | opcode | + * ^----^ + * Applies to R, R4, I, U and J uncompressed formats. + */ +static bool +encode_rd_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 11, 7); + return true; +} + +/* Encode the destination floating-point register field: + * |31 12|11 7|6 0| + * | ... | rd | opcode | + * ^----^ + * Applies to R, R4, I, U and J uncompressed formats. + */ +static bool +encode_rdfp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; + *out |= SET_FIELD(rd, 11, 7); + return true; +} + +/* Encode the 1st source fixed-point register field: + * |31 20|19 15|14 7|6 0| + * | ... | rs1 | ... | opcode | + * ^-----^ + * Applies to R, R4, I, S and B uncompressed formats. + */ +static bool +encode_rs1_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 19, 15); + return true; +} + +/* Encode the 1st source floating-point register field: + * |31 20|19 15|14 7|6 0| + * | ... | rs1 | ... | opcode | + * ^-----^ + * Applies to R, R4, I, S and B uncompressed formats. + */ +static bool +encode_rs1fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; + *out |= SET_FIELD(rd, 19, 15); + return true; +} + +/* Encode the rs1 field as a base register: + * |31 20|19 15|14 7|6 0| + * | ... | base | ... | opcode | + * ^------^ + * Applies to instructions of the Zicbom and Zicbop extensions. + */ +static bool +encode_base_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_base(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 19, 15); + return true; +} + +/* Encode the 2nd source fixed-point register field: + * |31 25|24 20|19 7|6 0| + * | ... | rs2 | ... | opcode | + * ^-----^ + * Applies to R, R4, S and B uncompressed formats. + */ +static bool +encode_rs2_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 24, 20); + return true; +} + +/* Encode the 2nd source floating-point register field: + * |31 25|24 20|19 7|6 0| + * | ... | rs2 | ... | opcode | + * ^-----^ + * Applies to R, R4, S and B uncompressed formats. + */ +static bool +encode_rs2fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; + *out |= SET_FIELD(rd, 24, 20); + return true; +} + +/* Encode the 3rd source fixed-point register field: + * |31 27|26 7|6 0| + * | rs3 | ... | opcode | + * ^---^ + * Applies to the R4 uncompressed format. + */ +static bool +encode_rs3_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; + *out |= SET_FIELD(rd, 31, 27); + return true; +} + +/* Encode the fence mode field of the "fence" instruction: + * |31 28| 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |19 15|14 12|11 7|6 0| + * | fm | PI | PO | PR | PW | SI | SO | SR | SW | rs1 | funct3 | rd | 0xF | + * ^----^ + */ +static bool +encode_fm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 31, 28); + return true; +} + +/* Encode all predecessor bits of the "fence" instruction: + * |31 28| 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |19 15|14 12|11 7|6 0| + * | fm | PI | PO | PR | PW | SI | SO | SR | SW | rs1 | funct3 | rd | 0xF | + * ^-----------------^ + */ +static bool +encode_pred_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 27, 24); + return true; +} + +/* Encode all successor bits of the "fence" instruction: + * |31 28| 27 | 26 | 25 | 24 | 23 | 22 | 21 | 20 |19 15|14 12|11 7|6 0| + * | fm | PI | PO | PR | PW | SI | SO | SR | SW | rs1 | funct3 | rd | 0xF | + * ^-----------------^ + */ +static bool +encode_succ_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 23, 20); + return true; +} + +/* Encode acquire-release semantics of an atomic instruction (A extension): + * |31 27| 26 | 25 |24 7|6 0| + * | ... | aq | rl | ... | opcode | + * ^-------^ + */ +static bool +encode_aqrl_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 26, 25); + return true; +} + +/* Encode the CSR number in instructions from the Zicsr extension: + * |31 20|19 7|6 0| + * | csr | ... | opcode | + * ^---^ + */ +static bool +encode_csr_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 31, 20); + return true; +} + +/* Encode the rounding mode in floating-point instructions: + * |31 15|14 12|11 7|6 0| + * | ... | rm | ... | opcode | + * ^----^ + * The valid values can be found in Table 11.1 in the RISC-V + * Instruction Set Manual Volume I: Unprivileged ISA (ver. 20191213). + */ +static bool +encode_rm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 14, 12); + return true; +} + +/* Encode the 6-bit (6th bit always 0 in rv32) shift amount: + * |31 26|25 20|19 7|6 0| + * | ... | shamt | ... | opcode | + * ^-----^ + */ +static bool +encode_shamt_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 25, 20); + return true; +} + +/* Encode the 5-bit shift amount in rv64: + * |31 25|24 20|19 7|6 0| + * | ... | shamt5 | ... | opcode | + * ^------^ + */ +static bool +encode_shamt5_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 24, 20); + return true; +} + +/* Encode the 7-bit (7th bit always 0 in rv64) shift amount in rv64: + * |31 27|26 20|19 7|6 0| + * | ... | shamt6 | ... | opcode | + * ^------^ + */ +static bool +encode_shamt6_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + /* shamt6 >= 64 only makes sense on RV128 but let user take care of it. */ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 26, 20); + return true; +} + +/* Encode the immediate field of the I-type format: + * |31 20|19 15|14 12|11 7|6 0| + * | imm[11:0] | rs1 | funct3 | rd | opcode | + * ^---------^ + * From: + * |31 11|10 0| + * | imm[11] | imm[10:0] | + */ +static bool +encode_i_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 31, 20); + return true; +} + +/* Encode the immediate field of the S-type format: + * |31 25|24 20|19 15|14 12|11 7|6 0| + * | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | + * ^---------^ ^--------^ + * From: + * |31 11|10 5|4 0| + * | imm[11] | imm[10:5] | imm[4:0] | + */ +static bool +encode_s_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm >> 5, 31, 25) | SET_FIELD(imm, 11, 7); + return true; +} + +/* Encode the immediate field of the B-type format as a pc-relative offset: + * | 31 |30 25|24 20|19 15|14 12|11 8| 7 |6 0| + * |imm[12]|imm[10:5]| rs2 | rs1 | funct3 |imm[4:1]|imm[11]| opcode | + * ^---------------^ ^--------------^ + * From: + * |31 12| 11 |10 5|4 1| 0 | + * | imm[12] |imm[11]| imm[10:5] | imm[4:1] | 0 | + */ +static bool +encode_b_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_target(instr); + int32_t imm = opnd_get_pc(opnd) - pc; + *out |= SET_FIELD(imm >> 11, 7, 7) | SET_FIELD(imm, 11, 8) | SET_FIELD(imm >> 5, 30, 25) | + SET_FIELD(imm >> 12, 31, 31); + return true; +} + +/* Encode the immediate field of the U-type format: + * |31 12|11 7|6 0| + * | imm[31:12] | rd | opcode | + * ^----------^ + * From: + * |31 12|11 0| + * | imm[31:12] | 0 | + */ +static bool +encode_u_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 31, 12); + return true; +} + +/* Encode the immediate field of the J-type format as a pc-relative offset: + * | 31 |30 21| 20 |19 12|11 7|6 0| + * | imm[20] | imm[10:1] | imm[11] | imm[19:12] | rd | opcode | + * ^------------------------------------------^ + * From: + * |31 20|19 12| 11 |10 1| 0 | + * | imm[20] | imm[19:12] | imm[11] | imm[10:1] | 0 | + */ +static bool +encode_j_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_target(instr); + int32_t imm = opnd_get_pc(opnd) - pc; + *out |= SET_FIELD(imm >> 1, 31, 21) | SET_FIELD(imm >> 11, 20, 20) | SET_FIELD(imm >> 12, 19, 12) | SET_FIELD(imm >> 20, 31, 31); + return true; +} + +/* Encode the destination fixed-point register field: + * |31 12|11 7|6 2|1 0| + * | ... | rd | ... | opcode | + * ^----^ + * Applies to CR and CI compressed formats. + */ +static bool +encode_crd_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 11, 7); + return true; +} + +/* Encode the destination floating-point register field: + * |31 12|11 7|6 2|1 0| + * | ... | rd | ... | opcode | + * ^----^ + * Applies to CR and CI compressed formats. + */ +static bool +encode_crdfp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; + *out |= SET_FIELD(rd, 11, 7); + return true; +} + +/* Encode the 1st source fixed-point register field: + * |31 12|11 7|6 2|1 0| + * | ... | rd | ... | opcode | + * ^----^ + * Applies to CR and CI compressed formats. + */ +static bool +encode_crs1_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 11, 7); + return true; +} + +/* Encode the 2nd source fixed-point register field: + * |31 7|6 2|1 0| + * | ... | rs2 | opcode | + * ^---^ + * Applies to CR and CSS compressed formats. + */ +static bool +encode_crs2_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X0; + *out |= SET_FIELD(rd, 6, 2); + return true; +} + +/* Encode the 2nd source floating-point register field: + * |31 7|6 2|1 0| + * | ... | rs2 | opcode | + * ^---^ + * Applies to CR and CSS compressed formats. + */ +static bool +encode_crs2fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; + *out |= SET_FIELD(rd, 6, 2); + return true; +} + +/* Encode the limited range (x8-x15) destination fixed-point register field: + * |31 5|4 2|1 0| + * | ... | rd' | opcode | + * ^---^ + * Applies to CIW and CL compressed formats. + */ +static bool +encode_crd__opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X8; + *out |= SET_FIELD(rd, 4, 2); + return true; +} + +/* Encode the limited range (x8-x15) destination floating-point register field: + * |31 5|4 2|1 0| + * | ... | rd' | opcode | + * ^---^ + * Applies to CIW and CL compressed formats. + */ +static bool +encode_crd_fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F8; + *out |= SET_FIELD(rd, 4, 2); + return true; +} + +/* Encode the limited range (x8-x15) 1st source fixed-point register field: + * |31 10|9 7|6 2|1 0| + * | ... | rs1' | ... | opcode | + * ^---^ + * Applies to CL, CS, CA and CB compressed formats. + */ +static bool +encode_crs1__opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X8; + *out |= SET_FIELD(rd, 9, 7); + return true; +} + +/* Encode the limited range (x8-x15) 2nd source fixed-point register field: + * |31 5|4 2|1 0| + * | ... | rs2' | opcode | + * ^---^ + * Applies to CS and CA compressed formats. + */ +static bool +encode_crs2__opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X8; + *out |= SET_FIELD(rd, 4, 2); + return true; +} + +/* Encode the limited range (x8-x15) 2nd source floating-point register field: + * |31 5|4 2|1 0| + * | ... | rs2' | opcode | + * ^---^ + * Applies to CS and CA compressed formats. + */ +static bool +encode_crs2_fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_F8; + *out |= SET_FIELD(rd, 4, 2); + return true; +} + +/* Encode the limited range (x8-x15) destination fixed-point register field: + * |31 5|4 2|1 0| + * | ... | rd' | opcode | + * ^---^ + * Applies to the CA compressed format. + */ +static bool +encode_crd___opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t rd = opnd_get_reg(opnd) - DR_REG_X8; + *out |= SET_FIELD(rd, 9, 7); + return true; +} + +/* Encode the 6-bit (6th bit always 0 in rv32) shift amount: + * |15 13| 12 |11 10|9 7|6 2|1 0| + * | funct3 | imm[5] | funct2 | rs1' | imm[4:0] | opcode | + * ^------^ ^--------^ + */ +static bool +encode_cshamt_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 6, 2) | SET_FIELD(imm >> 5, 12, 12); + return true; +} + +/* Encode the CSR immediate in instructions from the Zicsr extension: + * |31 20|19 15|14 7|6 0| + * | csr | imm[4:0] | ... | opcode | + * ^--------^ + * From: + * |31 5|4 0| + * | 0 | imm[4:0] | + */ +static bool +encode_csr_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 19, 15); + return true; +} + +/* Encode the immediate of the caddi16sp instruction: + * |15 13| 12 |11 7|6 2|1 0| + * | ... | imm[9] | ... | imm[4|6|8:7|5] | opcode | + * ^------^ ^--------------^ + * From: + * |31 9|8 4|3 0| + * | imm[9] | imm[8:4] | 0 | + */ +static bool +encode_caddi16sp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 7, 4, 3) | SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 4, 6, 6) | SET_FIELD(imm >> 9, 12, 12); + return true; +} + +/* Encode the SP-based immediate offset of c.lwsp and c.flwsp instructions: + * |15 13| 12 |11 7|6 2|1 0| + * | ... | imm[5] | ... | imm[4:2|7:6] | opcode | + * ^------^ ^------------^ + * From: + * |31 8|7 2|3 0| + * sp + | 0 | imm[7:2] | 0 | + */ +static bool +encode_clwsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 3, 2) | SET_FIELD(imm >> 2, 6, 4) | SET_FIELD(imm >> 5, 12, 12); + return true; +} + +/* Encode the SP-based immediate offset of c.ldsp and c.fldsp instructions: + * |15 13| 12 |11 7|6 2|1 0| + * | ... | imm[5] | ... | imm[4:3|8:6] | opcode | + * ^------^ ^------------^ + * From: + * |31 9|8 2|3 0| + * sp + | 0 | imm[8:3] | 0 | + */ +static bool +encode_cldsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 4, 2) | SET_FIELD(imm >> 3, 6, 5) | SET_FIELD(imm >> 5, 12, 12); + return true; +} + +/* Encode the immediate of the c.lui instruction: + * |15 13| 12 |11 7|6 2|1 0| + * | ... | imm[17] | ... | imm[16:12] | opcode | + * ^-------^ ^----------^ + * From: + * |31 17|16 12|11 0| + * | imm[17] | imm[16:12] | 0 | + */ +static bool +encode_clui_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 6, 2) | SET_FIELD(imm >> 5, 12, 12); + return true; +} + +/* Encode the SP-based offset immediate of c.swsp and c.fswsp instructions: + * |15 13|12 7|6 2|1 0| + * | ... | imm[5:2|7:6] | ... | opcode | + * ^------------^ + * From: + * |31 8|7 2|1 0| + * sp + | 0 | imm[7:2] | 0 | + */ +static bool +encode_cswsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 8, 7) | SET_FIELD(imm >> 2, 12, 9); + return true; +} + +/* Encode the SP-based offset immediate of c.sdsp and c.fsdsp instructions: + * |15 13|12 7|6 2|1 0| + * | ... | imm[5:3|8:6] | ... | opcode | + * ^------------^ + * From: + * |31 9|8 3|2 0| + * sp + | 0 | imm[7:3] | 0 | + */ +static bool +encode_csdsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 9, 7) | SET_FIELD(imm >> 3, 12, 10); + return true; +} + +/* Encode the immediate of the c.addi4spn instruction: + * |15 13|12 5|4 2|1 0| + * | ... | imm[5:4|9:6|2|3] | ... | opcode | + * ^----------------^ + * From: + * |31 10|9 2|1 0| + * | 0 | imm[9:2] | 0 | + */ +static bool +encode_ciw_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm >> 3, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | SET_FIELD(imm >> 6, 10, 7) | SET_FIELD(imm >> 4, 12, 11); + return true; +} + +/* Encode the base register and offset immediate of c.lw and c.flw + * instructions: + * |15 13|12 10|9 7|6 5|4 2|1 0| + * | ... | imm[5:3] | rs1' | imm[2|6] | ... | opcode | + * ^--------^ ^----^ ^--------^ + * From: + * |31 7|6 2|1 0| + * rs1' + | 0 | imm[6:2] | 0 | + */ +static bool +encode_clw_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t reg = opnd_get_base(opnd) - DR_REG_X8; + *out |= SET_FIELD(reg, 9, 7); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | SET_FIELD(imm >> 3, 12, 10); + return true; +} + +/* Encode the base register and offset immediate of c.ld and c.fld + * instructions: + * |15 13|12 10|9 7|6 5|4 2|1 0| + * | ... | imm[5:3] | rs1' | imm[7:6] | ... | opcode | + * ^--------^ ^----^ ^--------^ + * From: + * |31 8|7 3|2 0| + * rs1' + | 0 | imm[7:3] | 0 | + */ +static bool +encode_cld_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t reg = opnd_get_base(opnd) - DR_REG_X8; + *out |= SET_FIELD(reg, 9, 7); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 6, 5) | SET_FIELD(imm >> 3, 12, 10); + return true; +} + +/* Encode the base register and offset immediate of c.sw and c.fsw + * instructions: + * |15 13|12 10|9 7|6 5|4 2|1 0| + * | ... | imm[5:3] | rs1' | imm[2|6] | ... | opcode | + * ^--------^ ^----^ ^--------^ + * From: + * |31 7|6 2|1 0| + * rs1' + | 0 | imm[6:2] | 0 | + */ +static bool +encode_csw_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t reg = opnd_get_base(opnd) - DR_REG_X8; + *out |= SET_FIELD(reg, 9, 7); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | SET_FIELD(imm >> 3, 12, 10); + return true; +} + +/* Encode the base register and offset immediate of c.sd and c.fsd + * instructions: + * |15 13|12 10|9 7|6 5|4 2|1 0| + * | ... | imm[5:3] | rs1' | imm[7:6] | ... | opcode | + * ^--------^ ^----^ ^--------^ + * From: + * |31 8|7 3|2 0| + * rs1' + | 0 | imm[7:3] | 0 | + */ +static bool +encode_csd_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t reg = opnd_get_base(opnd) - DR_REG_X8; + *out |= SET_FIELD(reg, 9, 7); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm >> 6, 6, 5) | SET_FIELD(imm >> 3, 12, 10); + return true; +} + +/* Encode the base immediate of c.addi, c.addiw, c.li, c.andi instructions: + * |15 13| 12 |11 7|6 2|1 0| + * | ... | imm[5] | ... | imm[4:0] | opcode | + * ^------^ ^--------^ + * From: + * |31 5|4 0| + * | imm[5] | imm[4:0] | + */ +static bool +encode_cimm5_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + int32_t imm = opnd_get_immed_int(opnd); + *out |= SET_FIELD(imm, 6, 2) | SET_FIELD(imm >> 5, 12, 12); + return true; +} + +/* Encode the immediate field of the CB-type format as a pc-relative offset: + * |15 13|12 10|9 7|6 2|1 0| + * | ... | imm[8|4:3] | ... | imm[7:6|2:1|5] | opcode | + * ^----------^ ^--------------^ + * From: + * |31 8|7 1| 0 | + * | imm[8] | imm[7:1] | 0 | + */ +static bool +encode_cb_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_target(instr); + int32_t imm = opnd_get_pc(opnd) - pc; + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 4, 3) | SET_FIELD(imm >> 6, 6, 5) | SET_FIELD(imm >> 3, 11, 10) | SET_FIELD(imm >> 8, 12, 12); + return true; +} + + +/* Encode the immediate field of the CJ-type format as a pc-relative offset: + * |15 13|12 2|1 0| + * | ... | [11|4|9:8|10|6|7|3:1|5] | opcode | + * ^-----------------------^ + * From: + * |31 11|10 1| 0 | + * | imm[11] | imm[10:1] | 0 | + */ +static bool +encode_cj_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_target(instr); + int32_t imm = opnd_get_pc(opnd) - pc; + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 5, 3) | SET_FIELD(imm >> 7, 6, 6) | SET_FIELD(imm >> 6, 7, 7) | SET_FIELD(imm >> 10, 8, 8) | SET_FIELD(imm >> 8, 10, 9) | + SET_FIELD(imm >> 4, 11, 11) | SET_FIELD(imm >> 11, 12, 12); + return true; +} + +/* Encode the base register and immediate offset of a virtual load-like field: + * |31 20|19 15|14 7|6 0| + * | imm[11:0] | rs1 | ... | opcode | + * ^---------^ ^-----^ + * From: + * |31 11|7 0| + * rs1 + | imm[11] | imm[10:0] | + * + * Note that this is a virtual field injected by codec.py into instructions + * which share the immediate field type with other non-base+disp instructions. + */ +static bool +encode_v_l_rs1_disp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_src(instr, idx); + uint32_t reg = opnd_get_base(opnd) - DR_REG_X0; + *out |= SET_FIELD(reg, 19, 15); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm, 31, 20); + return true; +} + +/* Encode the base register and immediate offset of a virtual store-like field: + * |31 25|24 20|19 15|14 12|11 7|6 0| + * | imm[11:5] | rs2 | rs1 | funct3 | imm[4:0] | opcode | + * ^---------^ ^-----^ ^--------^ + * From: + * |31 11|7 0| + * rs1 + | imm[11] | imm[10:0] | + * + * Note that this is a virtual field injected by codec.py into instructions + * which share the immediate field type with other non-base+disp instructions. + */ +static bool +encode_v_s_rs1_disp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +{ + opnd_t opnd = instr_get_dst(instr, idx); + uint32_t reg = opnd_get_base(opnd) - DR_REG_X0; + *out |= SET_FIELD(reg, 19, 15); + int32_t imm = opnd_get_disp(opnd); + *out |= SET_FIELD(imm, 11, 7) | SET_FIELD(imm >> 5, 31, 25); + return true; +} + + +/* Array of operand encode functions indexed by riscv64_fld_t. */ +opnd_enc_func_t opnd_encoders[] = { + [RISCV64_FLD_NONE] = encode_none_opnd, + [RISCV64_FLD_RD] = encode_rd_opnd, + [RISCV64_FLD_RDFP] = encode_rdfp_opnd, + [RISCV64_FLD_RS1] = encode_rs1_opnd, + [RISCV64_FLD_RS1FP] = encode_rs1fp_opnd, + [RISCV64_FLD_BASE] = encode_base_opnd, + [RISCV64_FLD_RS2] = encode_rs2_opnd, + [RISCV64_FLD_RS2FP] = encode_rs2fp_opnd, + [RISCV64_FLD_RS3] = encode_rs3_opnd, + [RISCV64_FLD_FM] = encode_fm_opnd, + [RISCV64_FLD_PRED] = encode_pred_opnd, + [RISCV64_FLD_SUCC] = encode_succ_opnd, + [RISCV64_FLD_AQRL] = encode_aqrl_opnd, + [RISCV64_FLD_CSR] = encode_csr_opnd, + [RISCV64_FLD_RM] = encode_rm_opnd, + [RISCV64_FLD_SHAMT] = encode_shamt_opnd, + [RISCV64_FLD_SHAMT5] = encode_shamt5_opnd, + [RISCV64_FLD_SHAMT6] = encode_shamt6_opnd, + [RISCV64_FLD_I_IMM] = encode_i_imm_opnd, + [RISCV64_FLD_S_IMM] = encode_s_imm_opnd, + [RISCV64_FLD_B_IMM] = encode_b_imm_opnd, + [RISCV64_FLD_U_IMM] = encode_u_imm_opnd, + [RISCV64_FLD_J_IMM] = encode_j_imm_opnd, + [RISCV64_FLD_CRD] = encode_crd_opnd, + [RISCV64_FLD_CRDFP] = encode_crdfp_opnd, + [RISCV64_FLD_CRS1] = encode_crs1_opnd, + [RISCV64_FLD_CRS2] = encode_crs2_opnd, + [RISCV64_FLD_CRS2FP] = encode_crs2fp_opnd, + [RISCV64_FLD_CRD_] = encode_crd__opnd, + [RISCV64_FLD_CRD_FP] = encode_crd_fp_opnd, + [RISCV64_FLD_CRS1_] = encode_crs1__opnd, + [RISCV64_FLD_CRS2_] = encode_crs2__opnd, + [RISCV64_FLD_CRS2_FP] = encode_crs2_fp_opnd, + [RISCV64_FLD_CRD__] = encode_crd___opnd, + [RISCV64_FLD_CSHAMT] = encode_cshamt_opnd, + [RISCV64_FLD_CSR_IMM] = encode_csr_imm_opnd, + [RISCV64_FLD_CADDI16SP_IMM] = encode_caddi16sp_imm_opnd, + [RISCV64_FLD_CLWSP_IMM] = encode_clwsp_imm_opnd, + [RISCV64_FLD_CLDSP_IMM] = encode_cldsp_imm_opnd, + [RISCV64_FLD_CLUI_IMM] = encode_clui_imm_opnd, + [RISCV64_FLD_CSWSP_IMM] = encode_cswsp_imm_opnd, + [RISCV64_FLD_CSDSP_IMM] = encode_csdsp_imm_opnd, + [RISCV64_FLD_CIW_IMM] = encode_ciw_imm_opnd, + [RISCV64_FLD_CLW_IMM] = encode_clw_imm_opnd, + [RISCV64_FLD_CLD_IMM] = encode_cld_imm_opnd, + [RISCV64_FLD_CSW_IMM] = encode_csw_imm_opnd, + [RISCV64_FLD_CSD_IMM] = encode_csd_imm_opnd, + [RISCV64_FLD_CIMM5] = encode_cimm5_opnd, + [RISCV64_FLD_CB_IMM] = encode_cb_imm_opnd, + [RISCV64_FLD_CJ_IMM] = encode_cj_imm_opnd, + [RISCV64_FLD_V_L_RS1_DISP] = encode_v_l_rs1_disp_opnd, + [RISCV64_FLD_V_S_RS1_DISP] = encode_v_s_rs1_disp_opnd, +}; + +uint +encode_common(byte *pc, instr_t *instr, decode_info_t *di) +{ + ASSERT(((ptr_int_t)pc & 1) == 0); + ASSERT(instr->opcode < sizeof(instr_infos) / sizeof(rv_instr_info_t)); + + rv_instr_info_t *info = &instr_infos[instr->opcode]; + int ndst = INFO_NDST(info->info.opcode); + int nsrc = INFO_NSRC(info->info.opcode); + uint inst = info->info.code >> 32; + + CLIENT_ASSERT(ndst >= 0 || ndst <= 1, "Invalid number of destination operands."); + CLIENT_ASSERT(nsrc >= 0 || nsrc <= 4, "Invalid number of source operands."); + + CLIENT_ASSERT(info->info.dst1_type < RISCV64_FLD_CNT, "Invalid dst1_type."); + if (ndst > 0 && !opnd_encoders[info->info.dst1_type](instr, pc, 0, &inst)) + goto encode_failure; + switch (nsrc) { + case 4: + CLIENT_ASSERT(info->info.dst2_type < RISCV64_FLD_CNT, "Invalid dst2_type."); + if (!opnd_encoders[info->info.dst2_type](instr, pc, 3, &inst)) + goto encode_failure; + case 3: + CLIENT_ASSERT(info->info.src3_type < RISCV64_FLD_CNT, "Invalid src3_type."); + if (!opnd_encoders[info->info.src3_type](instr, pc, 2, &inst)) + goto encode_failure; + case 2: + CLIENT_ASSERT(info->info.src2_type < RISCV64_FLD_CNT, "Invalid src2_type."); + if (!opnd_encoders[info->info.src2_type](instr, pc, 1, &inst)) + goto encode_failure; + case 1: + CLIENT_ASSERT(info->info.src1_type < RISCV64_FLD_CNT, "Invalid src1_type."); + if (!opnd_encoders[info->info.src1_type](instr, pc, 0, &inst)) + goto encode_failure; + case 0: break; + default: ASSERT_NOT_REACHED(); + } + + if (info->ext == RISCV64_ISA_EXT_RVC) { + inst &= 0xFFFF; + } + return inst; - /* FIXME i#3544: Not implemented */ +encode_failure: return ENCFAIL; } diff --git a/core/ir/riscv64/codec.h b/core/ir/riscv64/codec.h index 019c2335f0a..148ad6a2678 100644 --- a/core/ir/riscv64/codec.h +++ b/core/ir/riscv64/codec.h @@ -245,6 +245,7 @@ typedef enum { #define BIT(v, b) (((v) >> b) & 1) #define GET_FIELD(v, high, low) (((v) >> low) & ((1ULL << (high - low + 1)) - 1)) +#define SET_FIELD(v, high, low) (((v) & ((1ULL << (high - low + 1)) - 1)) << low) #define SIGN_EXTEND(val, val_sz) (((int32_t)(val) << (32 - (val_sz))) >> (32 - (val_sz))) /* Calculate instruction width. From d9d162a329b5f0baccd32c4410fc52f8ed0711bf Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Tue, 30 May 2023 19:06:07 +0800 Subject: [PATCH 05/34] Clang format --- core/ir/opnd_api.h | 10 +++++----- core/ir/riscv64/codec.c | 39 ++++++++++++++++++++++++--------------- 2 files changed, 29 insertions(+), 20 deletions(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index c2060a05eba..56751d3ed2f 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1208,7 +1208,7 @@ enum { DR_REG_T4 = DR_REG_X29, /**< The 5th temporary (x29) register. */ DR_REG_T5 = DR_REG_X30, /**< The 6th temporary (x30) register. */ DR_REG_T6 = DR_REG_X31, /**< The 7th temporary (x31) register. */ - DR_REG_PC, /**< The program counter. */ + DR_REG_PC, /**< The program counter. */ /* Floating point registers */ DR_REG_F0, /**< The f0(ft0) floating-point register. */ DR_REG_F1, /**< The f1(ft1) floating-point register. */ @@ -1909,10 +1909,10 @@ struct _opnd_t { void *addr; /* REL_ADDR_kind and ABS_ADDR_kind */ } value; # ifdef RISCV64 - /* Used by disassemble, indicates whether an immediate value should be formatted - * in decimal or hexadecimal, valid iff opnd is an IMMED_INTEGER_kind. - */ - bool decimal; + /* Used by disassemble, indicates whether an immediate value should be formatted + * in decimal or hexadecimal, valid iff opnd is an IMMED_INTEGER_kind. + */ + bool decimal; # endif }; #endif /* DR_FAST_IR */ diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index ab0281fbeb7..ebeb33428f6 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -1421,7 +1421,6 @@ decode_common(dcontext_t *dcontext, byte *pc, byte *orig_pc, instr_t *instr) return NULL; } - /* Instruction operand encoder function. * * Encodes an operand from a given instr_t into the instruction. @@ -1737,8 +1736,8 @@ encode_b_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); int32_t imm = opnd_get_pc(opnd) - pc; - *out |= SET_FIELD(imm >> 11, 7, 7) | SET_FIELD(imm, 11, 8) | SET_FIELD(imm >> 5, 30, 25) | - SET_FIELD(imm >> 12, 31, 31); + *out |= SET_FIELD(imm >> 11, 7, 7) | SET_FIELD(imm, 11, 8) | + SET_FIELD(imm >> 5, 30, 25) | SET_FIELD(imm >> 12, 31, 31); return true; } @@ -1772,7 +1771,8 @@ encode_j_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); int32_t imm = opnd_get_pc(opnd) - pc; - *out |= SET_FIELD(imm >> 1, 31, 21) | SET_FIELD(imm >> 11, 20, 20) | SET_FIELD(imm >> 12, 19, 12) | SET_FIELD(imm >> 20, 31, 31); + *out |= SET_FIELD(imm >> 1, 31, 21) | SET_FIELD(imm >> 11, 20, 20) | + SET_FIELD(imm >> 12, 19, 12) | SET_FIELD(imm >> 20, 31, 31); return true; } @@ -1985,7 +1985,9 @@ encode_caddi16sp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_immed_int(opnd); - *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 7, 4, 3) | SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 4, 6, 6) | SET_FIELD(imm >> 9, 12, 12); + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 7, 4, 3) | + SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 4, 6, 6) | + SET_FIELD(imm >> 9, 12, 12); return true; } @@ -2002,7 +2004,8 @@ encode_clwsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_disp(opnd); - *out |= SET_FIELD(imm >> 6, 3, 2) | SET_FIELD(imm >> 2, 6, 4) | SET_FIELD(imm >> 5, 12, 12); + *out |= SET_FIELD(imm >> 6, 3, 2) | SET_FIELD(imm >> 2, 6, 4) | + SET_FIELD(imm >> 5, 12, 12); return true; } @@ -2019,7 +2022,8 @@ encode_cldsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_disp(opnd); - *out |= SET_FIELD(imm >> 6, 4, 2) | SET_FIELD(imm >> 3, 6, 5) | SET_FIELD(imm >> 5, 12, 12); + *out |= SET_FIELD(imm >> 6, 4, 2) | SET_FIELD(imm >> 3, 6, 5) | + SET_FIELD(imm >> 5, 12, 12); return true; } @@ -2087,7 +2091,8 @@ encode_ciw_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_immed_int(opnd); - *out |= SET_FIELD(imm >> 3, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | SET_FIELD(imm >> 6, 10, 7) | SET_FIELD(imm >> 4, 12, 11); + *out |= SET_FIELD(imm >> 3, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | + SET_FIELD(imm >> 6, 10, 7) | SET_FIELD(imm >> 4, 12, 11); return true; } @@ -2107,7 +2112,8 @@ encode_clw_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) uint32_t reg = opnd_get_base(opnd) - DR_REG_X8; *out |= SET_FIELD(reg, 9, 7); int32_t imm = opnd_get_disp(opnd); - *out |= SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | SET_FIELD(imm >> 3, 12, 10); + *out |= SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | + SET_FIELD(imm >> 3, 12, 10); return true; } @@ -2147,7 +2153,8 @@ encode_csw_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) uint32_t reg = opnd_get_base(opnd) - DR_REG_X8; *out |= SET_FIELD(reg, 9, 7); int32_t imm = opnd_get_disp(opnd); - *out |= SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | SET_FIELD(imm >> 3, 12, 10); + *out |= SET_FIELD(imm >> 6, 5, 5) | SET_FIELD(imm >> 2, 6, 6) | + SET_FIELD(imm >> 3, 12, 10); return true; } @@ -2201,11 +2208,12 @@ encode_cb_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); int32_t imm = opnd_get_pc(opnd) - pc; - *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 4, 3) | SET_FIELD(imm >> 6, 6, 5) | SET_FIELD(imm >> 3, 11, 10) | SET_FIELD(imm >> 8, 12, 12); + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 4, 3) | + SET_FIELD(imm >> 6, 6, 5) | SET_FIELD(imm >> 3, 11, 10) | + SET_FIELD(imm >> 8, 12, 12); return true; } - /* Encode the immediate field of the CJ-type format as a pc-relative offset: * |15 13|12 2|1 0| * | ... | [11|4|9:8|10|6|7|3:1|5] | opcode | @@ -2219,8 +2227,10 @@ encode_cj_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); int32_t imm = opnd_get_pc(opnd) - pc; - *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 5, 3) | SET_FIELD(imm >> 7, 6, 6) | SET_FIELD(imm >> 6, 7, 7) | SET_FIELD(imm >> 10, 8, 8) | SET_FIELD(imm >> 8, 10, 9) | - SET_FIELD(imm >> 4, 11, 11) | SET_FIELD(imm >> 11, 12, 12); + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 5, 3) | + SET_FIELD(imm >> 7, 6, 6) | SET_FIELD(imm >> 6, 7, 7) | + SET_FIELD(imm >> 10, 8, 8) | SET_FIELD(imm >> 8, 10, 9) | + SET_FIELD(imm >> 4, 11, 11) | SET_FIELD(imm >> 11, 12, 12); return true; } @@ -2268,7 +2278,6 @@ encode_v_s_rs1_disp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) return true; } - /* Array of operand encode functions indexed by riscv64_fld_t. */ opnd_enc_func_t opnd_encoders[] = { [RISCV64_FLD_NONE] = encode_none_opnd, From 4e2d8f68d20ead61da6aa806be91063e7f92456e Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 31 May 2023 18:17:55 +0800 Subject: [PATCH 06/34] RV64: Fixed sizeof(opnd_t) --- core/ir/opnd_api.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index 56751d3ed2f..00e97749f9f 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1820,6 +1820,12 @@ struct _opnd_t { /* Used for ARM: REG_kind, BASE_DISP_kind, and IMMED_INTEGER_kind */ ushort /*dr_opnd_flags_t*/ flags; } aux; +# ifdef RISCV64 + /* Used by disassemble, indicates whether an immediate value should be formatted + * in decimal or hexadecimal, valid iff opnd is an IMMED_INTEGER_kind. + */ + bool decimal; +# endif union { /* all are 64 bits or less */ /* NULL_kind has no value */ @@ -1908,12 +1914,6 @@ struct _opnd_t { } base_disp; /* BASE_DISP_kind */ void *addr; /* REL_ADDR_kind and ABS_ADDR_kind */ } value; -# ifdef RISCV64 - /* Used by disassemble, indicates whether an immediate value should be formatted - * in decimal or hexadecimal, valid iff opnd is an IMMED_INTEGER_kind. - */ - bool decimal; -# endif }; #endif /* DR_FAST_IR */ From 754110a5bfbb0289e5b3bc2ccf37bc4f237b79d5 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 31 May 2023 19:15:42 +0800 Subject: [PATCH 07/34] RV64: Supported instr target for branch instr --- core/ir/riscv64/codec.c | 38 ++++++++++++++++++++++++++++++++++---- 1 file changed, 34 insertions(+), 4 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index ebeb33428f6..627571a5563 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -1735,7 +1735,14 @@ static bool encode_b_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); - int32_t imm = opnd_get_pc(opnd) - pc; + int32_t imm; + if (opnd.kind == PC_kind) + imm = opnd_get_pc(opnd) - pc; + else if (opnd.kind == INSTR_kind) + imm = (byte *)opnd_get_instr(opnd)->offset - (byte *)instr->offset; + else + return false; + *out |= SET_FIELD(imm >> 11, 7, 7) | SET_FIELD(imm, 11, 8) | SET_FIELD(imm >> 5, 30, 25) | SET_FIELD(imm >> 12, 31, 31); return true; @@ -1770,7 +1777,14 @@ static bool encode_j_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); - int32_t imm = opnd_get_pc(opnd) - pc; + int32_t imm; + if (opnd.kind == PC_kind) + imm = opnd_get_pc(opnd) - pc; + else if (opnd.kind == INSTR_kind) + imm = (byte *)opnd_get_instr(opnd)->offset - (byte *)instr->offset; + else + return false; + *out |= SET_FIELD(imm >> 1, 31, 21) | SET_FIELD(imm >> 11, 20, 20) | SET_FIELD(imm >> 12, 19, 12) | SET_FIELD(imm >> 20, 31, 31); return true; @@ -2207,7 +2221,15 @@ static bool encode_cb_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); - int32_t imm = opnd_get_pc(opnd) - pc; + + int32_t imm; + if (opnd.kind == PC_kind) + imm = opnd_get_pc(opnd) - pc; + else if (opnd.kind == INSTR_kind) + imm = (byte *)opnd_get_instr(opnd)->offset - (byte *)instr->offset; + else + return false; + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 4, 3) | SET_FIELD(imm >> 6, 6, 5) | SET_FIELD(imm >> 3, 11, 10) | SET_FIELD(imm >> 8, 12, 12); @@ -2226,7 +2248,15 @@ static bool encode_cj_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_target(instr); - int32_t imm = opnd_get_pc(opnd) - pc; + + int32_t imm; + if (opnd.kind == PC_kind) + imm = opnd_get_pc(opnd) - pc; + else if (opnd.kind == INSTR_kind) + imm = (byte *)opnd_get_instr(opnd)->offset - (byte *)instr->offset; + else + return false; + *out |= SET_FIELD(imm >> 5, 2, 2) | SET_FIELD(imm >> 1, 5, 3) | SET_FIELD(imm >> 7, 6, 6) | SET_FIELD(imm >> 6, 7, 7) | SET_FIELD(imm >> 10, 8, 8) | SET_FIELD(imm >> 8, 10, 9) | From be310ddce731ee8b8b593dddde989534837c6828 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Thu, 1 Jun 2023 19:28:16 +0800 Subject: [PATCH 08/34] i#3544 RV64: Fixed codec issue This patch fixes the instr create API for store instructions. Destination register needs to be last, not first. Issue: #3544 --- core/ir/riscv64/codec.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/core/ir/riscv64/codec.py b/core/ir/riscv64/codec.py index 585c3b44e41..127db092f2d 100755 --- a/core/ir/riscv64/codec.py +++ b/core/ir/riscv64/codec.py @@ -621,8 +621,8 @@ def __fixup_uncompressed_inst(self, inst: Instruction): dbg(f' -> {" " * len(inst.name)} {[f.name for f in inst.flds]}') elif opc in [0b0100011, 0b0100111]: # STORE instructions dbg(f'fixup: {inst.name} {[f.name for f in inst.flds]}') - inst.flds[0] = Field.V_S_RS1_DISP - inst.flds.pop(2) + inst.flds[2] = Field.V_S_RS1_DISP + inst.flds.pop(0) dbg(f' -> {" " * len(inst.name)} {[f.name for f in inst.flds]}') elif inst.mask == 0x1f07fff and inst.match in [0x6013, 0x106013, 0x306013]: # prefetch.[irw] instructions From 2f2d61574fbd3569e463c11555389b17009d1642 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 7 Jun 2023 17:11:34 +0800 Subject: [PATCH 09/34] Added DR_OPND_IMM_PRINT_DECIMAL --- core/ir/disassemble_shared.c | 5 +++++ core/ir/instr_inline_api.h | 4 ++-- core/ir/opnd_api.h | 11 +++++----- core/ir/riscv64/codec.c | 38 +++++++++++++++++------------------ core/ir/riscv64/disassemble.c | 2 +- 5 files changed, 32 insertions(+), 28 deletions(-) diff --git a/core/ir/disassemble_shared.c b/core/ir/disassemble_shared.c index 4f7da227da3..d5e7d4440aa 100644 --- a/core/ir/disassemble_shared.c +++ b/core/ir/disassemble_shared.c @@ -399,6 +399,10 @@ opnd_base_disp_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t print_to_buffer(buf, bufsz, sofar, "-"); } } +#if defined(RISCV64) + const char *fmt = TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; + print_to_buffer(buf, bufsz, sofar, fmt, disp); +#else if (TEST(DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask))) print_to_buffer(buf, bufsz, sofar, "%d", disp); else if ((unsigned)disp <= 0xff && !opnd_is_disp_force_full(opnd)) @@ -407,6 +411,7 @@ opnd_base_disp_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t print_to_buffer(buf, bufsz, sofar, "0x%04x", disp); else /* there are no 64-bit displacements */ print_to_buffer(buf, bufsz, sofar, "0x%08x", disp); +#endif } if (!TESTANY(DR_DISASM_INTEL | DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask))) { diff --git a/core/ir/instr_inline_api.h b/core/ir/instr_inline_api.h index a90f08f7b52..85a3d0c58a6 100644 --- a/core/ir/instr_inline_api.h +++ b/core/ir/instr_inline_api.h @@ -343,12 +343,12 @@ opnd_create_pc(app_pc pc) .value.reg_and_element_size.reg) # define opnd_get_reg OPND_GET_REG -# if defined(X86) || defined(RISCV64) +# if defined(X86) # define OPND_GET_FLAGS(opnd) \ (CLIENT_ASSERT_( \ opnd_is_reg(opnd) || opnd_is_base_disp(opnd) || opnd_is_immed_int(opnd), \ "opnd_get_flags called on non-reg non-base-disp non-immed-int opnd") 0) -# elif defined(AARCHXX) +# elif defined(AARCHXX) || defined(RISCV64) # define OPND_GET_FLAGS(opnd) \ (CLIENT_ASSERT_( \ opnd_is_reg(opnd) || opnd_is_base_disp(opnd) || \ diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index 00e97749f9f..efc173c41da 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1780,6 +1780,11 @@ typedef enum _dr_opnd_flags_t { * SVE predicate constraint */ DR_OPND_IS_PREDICATE_CONSTRAINT = 0x800, + + /** + * This is used by RISCV64 for immediates display format. + */ + DR_OPND_IMM_PRINT_DECIMAL = 0x1000, } dr_opnd_flags_t; #ifdef DR_FAST_IR @@ -1820,12 +1825,6 @@ struct _opnd_t { /* Used for ARM: REG_kind, BASE_DISP_kind, and IMMED_INTEGER_kind */ ushort /*dr_opnd_flags_t*/ flags; } aux; -# ifdef RISCV64 - /* Used by disassemble, indicates whether an immediate value should be formatted - * in decimal or hexadecimal, valid iff opnd is an IMMED_INTEGER_kind. - */ - bool decimal; -# endif union { /* all are 64 bits or less */ /* NULL_kind has no value */ diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 627571a5563..1790db94f6f 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -257,7 +257,6 @@ decode_fm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc { int32_t imm = GET_FIELD(inst, 31, 28); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -273,7 +272,6 @@ decode_pred_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_ { int32_t imm = GET_FIELD(inst, 27, 24); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -289,7 +287,6 @@ decode_succ_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_ { int32_t imm = GET_FIELD(inst, 23, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -305,7 +302,6 @@ decode_aqrl_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_ { int32_t imm = GET_FIELD(inst, 26, 25); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -325,7 +321,6 @@ decode_csr_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_p */ int32_t imm = GET_FIELD(inst, 31, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -343,7 +338,6 @@ decode_rm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc { int32_t imm = GET_FIELD(inst, 14, 12); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -359,7 +353,7 @@ decode_shamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = GET_FIELD(inst, 25, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -375,7 +369,7 @@ decode_shamt5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori { int32_t imm = GET_FIELD(inst, 24, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -392,7 +386,7 @@ decode_shamt6_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori /* shamt6 >= 64 only makes sense on RV128 but let user take care of it. */ int32_t imm = GET_FIELD(inst, 26, 20); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -411,7 +405,7 @@ decode_i_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -431,7 +425,7 @@ decode_s_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | (GET_FIELD(inst, 11, 7)); imm = SIGN_EXTEND(imm, 12); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -455,7 +449,6 @@ decode_b_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig imm = SIGN_EXTEND(imm, 13); opnd_t opnd = opnd_create_pc(orig_pc + imm); - opnd.decimal = false; instr_set_target(out, opnd); return true; } @@ -474,7 +467,6 @@ decode_u_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { uint uimm = GET_FIELD(inst, 31, 12); opnd_t opnd = opnd_create_immed_int(uimm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -689,7 +681,7 @@ decode_cshamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori { int32_t imm = (BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -708,7 +700,6 @@ decode_csr_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or { int32_t imm = GET_FIELD(inst, 19, 15); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -732,7 +723,7 @@ decode_caddi16sp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, imm |= (BIT(inst, 6) << 4); imm = SIGN_EXTEND(imm, 10); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -753,6 +744,7 @@ decode_clwsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * imm |= BIT(inst, 12) << 5; imm |= GET_FIELD(inst, 6, 4) << 2; opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -773,6 +765,7 @@ decode_cldsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * imm |= BIT(inst, 12) << 5; imm |= GET_FIELD(inst, 6, 5) << 3; opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -791,7 +784,6 @@ decode_clui_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *o { int32_t imm = (BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = false; instr_set_src(out, idx, opnd); return true; } @@ -810,6 +802,7 @@ decode_cswsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * { int32_t imm = (GET_FIELD(inst, 8, 7) << 6) | (GET_FIELD(inst, 12, 9) << 2); opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_dst(out, idx, opnd); return true; } @@ -828,6 +821,7 @@ decode_csdsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * { int32_t imm = (GET_FIELD(inst, 9, 7) << 6) | (GET_FIELD(inst, 12, 10) << 3); opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_dst(out, idx, opnd); return true; } @@ -849,7 +843,7 @@ decode_ciw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or imm |= BIT(inst, 5) << 3; imm |= BIT(inst, 6) << 2; opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -872,6 +866,7 @@ decode_clw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or imm |= GET_FIELD(inst, 12, 10) << 3; imm |= BIT(inst, 6) << 2; opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_4); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -892,6 +887,7 @@ decode_cld_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or reg_t reg = DR_REG_X8 + GET_FIELD(inst, 9, 7); int32_t imm = (GET_FIELD(inst, 6, 5) << 6) | (GET_FIELD(inst, 12, 10) << 3); opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_8); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -914,6 +910,7 @@ decode_csw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or imm |= GET_FIELD(inst, 12, 10) << 3; imm |= BIT(inst, 6) << 2; opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_4); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_dst(out, idx, opnd); return true; } @@ -934,6 +931,7 @@ decode_csd_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or reg_t reg = DR_REG_X8 + GET_FIELD(inst, 9, 7); int32_t imm = (GET_FIELD(inst, 6, 5) << 6) | (GET_FIELD(inst, 12, 10) << 3); opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_8); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_dst(out, idx, opnd); return true; } @@ -952,7 +950,7 @@ decode_cimm5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = SIGN_EXTEND((BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2), 6); opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.decimal = true; + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -1026,6 +1024,7 @@ decode_v_l_rs1_disp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, reg_t reg = DR_REG_X0 + GET_FIELD(inst, 19, 15); int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, op_sz); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_src(out, idx, opnd); return true; } @@ -1049,6 +1048,7 @@ decode_v_s_rs1_disp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | GET_FIELD(inst, 11, 7); imm = SIGN_EXTEND(imm, 12); opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, op_sz); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; instr_set_dst(out, idx, opnd); return true; } diff --git a/core/ir/riscv64/disassemble.c b/core/ir/riscv64/disassemble.c index e201c27e110..96be7caa617 100644 --- a/core/ir/riscv64/disassemble.c +++ b/core/ir/riscv64/disassemble.c @@ -71,7 +71,7 @@ opnd_disassemble_arch(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t opnd) case IMMED_INTEGER_kind: { /* Immediates are sign-extended at the decode time. */ ptr_int_t val = opnd_get_immed_int(opnd); - const char *fmt = opnd.decimal ? "%d" : "0x%x"; + const char *fmt = TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; print_to_buffer(buf, bufsz, sofar, fmt, val); return true; } From 97b0d158f7b211ba1539c5f8423ea90f0fa439b0 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 7 Jun 2023 17:16:26 +0800 Subject: [PATCH 10/34] Clang format --- core/ir/disassemble_shared.c | 3 ++- core/ir/riscv64/disassemble.c | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/core/ir/disassemble_shared.c b/core/ir/disassemble_shared.c index d5e7d4440aa..befc9a385ce 100644 --- a/core/ir/disassemble_shared.c +++ b/core/ir/disassemble_shared.c @@ -400,7 +400,8 @@ opnd_base_disp_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t } } #if defined(RISCV64) - const char *fmt = TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; + const char *fmt = + TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; print_to_buffer(buf, bufsz, sofar, fmt, disp); #else if (TEST(DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask))) diff --git a/core/ir/riscv64/disassemble.c b/core/ir/riscv64/disassemble.c index 96be7caa617..842ba8b2343 100644 --- a/core/ir/riscv64/disassemble.c +++ b/core/ir/riscv64/disassemble.c @@ -71,7 +71,8 @@ opnd_disassemble_arch(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t opnd) case IMMED_INTEGER_kind: { /* Immediates are sign-extended at the decode time. */ ptr_int_t val = opnd_get_immed_int(opnd); - const char *fmt = TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; + const char *fmt = + TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; print_to_buffer(buf, bufsz, sofar, fmt, val); return true; } From 2fe186b3b09a9721712669d4676dfb4a964f6db4 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 7 Jun 2023 17:19:53 +0800 Subject: [PATCH 11/34] Clang format --- core/ir/opnd_api.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index efc173c41da..b633ffa5b9c 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1783,7 +1783,7 @@ typedef enum _dr_opnd_flags_t { /** * This is used by RISCV64 for immediates display format. - */ + */ DR_OPND_IMM_PRINT_DECIMAL = 0x1000, } dr_opnd_flags_t; From da65effbfc1e4992f0cb4e18729e55e7aefc0e9f Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 14 Jun 2023 20:12:24 +0800 Subject: [PATCH 12/34] Start working on tests --- suite/tests/CMakeLists.txt | 19 +++++++---- suite/tests/api/ir_riscv64.c | 54 +++++++++++++++++++++++++++++++ suite/tests/api/ir_riscv64.expect | 1 + 3 files changed, 67 insertions(+), 7 deletions(-) create mode 100644 suite/tests/api/ir_riscv64.c create mode 100644 suite/tests/api/ir_riscv64.expect diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index 43f2419b3a1..51eadcaa861 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -714,6 +714,7 @@ function(configure_app_api_build_flags test decoder use_static_DR) string(REGEX REPLACE "DR_HOST_AARCH64" "" prop_defs "${prop_defs}") string(REGEX REPLACE "DR_HOST_X86" "" prop_defs "${prop_defs}") string(REGEX REPLACE "DR_HOST_X64" "" prop_defs "${prop_defs}") + string(REGEX REPLACE "DR_HOST_RISCV64" "" prop_defs "${prop_defs}") string(REGEX REPLACE "DR_HOST_NOT_TARGET" "" prop_defs "${prop_defs}") # Append to properties set by configure_DynamoRIO_standalone. get_target_property(prop_cflags ${test} COMPILE_FLAGS) @@ -1850,16 +1851,16 @@ elseif (RISCV64) else () set(sfx "x86") endif () -if (NOT ANDROID AND NOT RISCV64) # TODO i#3544: Port tests to RISC-V 64 +if (NOT ANDROID) # XXX i#1874: get working on Android tobuild_api(api.ir api/ir_${sfx}.c "" "" OFF OFF OFF) - if (AARCH64) + if (AARCH64 OR RISCV64) # The ir_aarch64.expect file is too large for CMake's regexes. set(api.ir_runcmp "${CMAKE_CURRENT_SOURCE_DIR}/runcmp.cmake") set(api.ir_runcmp_capture "stderr") endif () # XXX i#1686: add ARM's headers too once they are all created - if (NOT ARM AND NOT AARCH64 AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") + if (NOT ARM AND NOT AARCH64 AND NOT RISCV64 AND "${CMAKE_GENERATOR}" MATCHES "Unix Makefiles") # CMake's Unix Makefiles dependence analysis doesn't run the preprocessor # and so doesn't find headers named via macros # (http://www.cmake.org/Bug/view.php?id=13718) @@ -1897,10 +1898,7 @@ if (NOT ANDROID AND NOT RISCV64) # TODO i#3544: Port tests to RISC-V 64 endif () # test static decoder library -if (NOT RISCV64) - # TODO i#3544: Port tests to RISC-V 64 - tobuild_api(api.ir-static api/ir_${sfx}.c "" "" ON OFF OFF) -endif (NOT RISCV64) +tobuild_api(api.ir-static api/ir_${sfx}.c "" "" ON OFF OFF) if (AARCH64) # The ir_aarch64.expect file is too large for CMake's regexes. set(api.ir-static_runcmp "${CMAKE_CURRENT_SOURCE_DIR}/runcmp.cmake") @@ -5586,3 +5584,10 @@ if (LINUX AND X64 AND HAVE_RSEQ AND NOT RISCV64) # TODO i#3544: Port tests to RI code_api|tool.drcacheoff.rseq PROPERTIES LABELS UBUNTU_22) endif () + +# XXX i#4719: Support for running riscv64 Linux tests under QEMU. +if (RISCV64) +set_tests_properties( + code_api|api.ir + PROPERTIES LABELS RUNS_ON_QEMU) +endif () \ No newline at end of file diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c new file mode 100644 index 00000000000..55dff06c446 --- /dev/null +++ b/suite/tests/api/ir_riscv64.c @@ -0,0 +1,54 @@ +/* ********************************************************** + * Copyright (c) 2023 Institue of Software Chinese Academy of Sciences (ISCAS). + * All rights reserved. + * **********************************************************/ + +/* + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * * Neither the name of ISCAS nor the names of its contributors may be + * used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL ISCAS OR CONTRIBUTORS BE LIABLE + * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER + * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + */ + +/* Define DR_FAST_IR to verify that everything compiles when we call the inline + * versions of these routines. + */ +#ifndef STANDALONE_DECODER +# define DR_FAST_IR 1 +#endif + +/* Uses the DR API, using DR as a standalone library, rather than + * being a client library working with DR on a target program. + */ + +#include "configure.h" +#include "dr_api.h" +#include "tools.h" + +int +main(int argc, char *argv[]) +{ + print("All tests complete\n"); + return 0; +} diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect new file mode 100644 index 00000000000..ad3b0a3ddba --- /dev/null +++ b/suite/tests/api/ir_riscv64.expect @@ -0,0 +1 @@ +All tests complete From 8de5d59e33e9f6589dd624b16156d3990fffb7b8 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Thu, 15 Jun 2023 14:23:05 +0800 Subject: [PATCH 13/34] Added a simple case --- clients/drdisas/drdisas.cpp | 2 +- suite/tests/CMakeLists.txt | 4 +-- suite/tests/api/ir_riscv64.c | 61 ++++++++++++++++++++++++++++++++++++ 3 files changed, 64 insertions(+), 3 deletions(-) diff --git a/clients/drdisas/drdisas.cpp b/clients/drdisas/drdisas.cpp index 1e758a372c6..215060870be 100644 --- a/clients/drdisas/drdisas.cpp +++ b/clients/drdisas/drdisas.cpp @@ -67,7 +67,7 @@ droption_t op_show_bytes(DROPTION_SCOPE_FRONTEND, "show_bytes", true, "Display the instruction encoding bytes.", "Display the instruction encoding bytes."); -#if defined(AARCH64) || defined(ARM) +#if defined(AARCH64) || defined(ARM) || defined(RISCV64) # define MAX_INSTR_LENGTH 4 #else # define MAX_INSTR_LENGTH 17 diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index 51eadcaa861..1ee413e23d2 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -5585,9 +5585,9 @@ if (LINUX AND X64 AND HAVE_RSEQ AND NOT RISCV64) # TODO i#3544: Port tests to RI PROPERTIES LABELS UBUNTU_22) endif () -# XXX i#4719: Support for running riscv64 Linux tests under QEMU. +# XXX i#3544: Enable passed tests on riscv64. if (RISCV64) set_tests_properties( code_api|api.ir - PROPERTIES LABELS RUNS_ON_QEMU) + PROPERTIES LABELS RISCV64) endif () \ No newline at end of file diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index 55dff06c446..75f013149fb 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -46,9 +46,70 @@ #include "dr_api.h" #include "tools.h" +static byte buf[8192]; + +#ifdef STANDALONE_DECODER +# define ASSERT(x) \ + ((void)((!(x)) ? (fprintf(stderr, "ASSERT FAILURE (standalone): %s:%d: %s\n", \ + __FILE__, __LINE__, #x), \ + abort(), 0) \ + : 0)) +#else +# define ASSERT(x) \ + ((void)((!(x)) ? (dr_fprintf(STDERR, "ASSERT FAILURE (client): %s:%d: %s\n", \ + __FILE__, __LINE__, #x), \ + dr_abort(), 0) \ + : 0)) +#endif + +static void +test_instr_encoding(void *dc, uint opcode, instr_t *instr) +{ + instr_t *decin; + byte *pc; + + ASSERT(instr_get_opcode(instr) == opcode); + instr_disassemble(dc, instr, STDERR); + print("\n"); + ASSERT(instr_is_encoding_possible(instr)); + pc = instr_encode(dc, instr, buf); + decin = instr_create(dc); + decode(dc, buf, decin); + if (!instr_same(instr, decin)) { + print("Disassembled as:\n"); + instr_disassemble(dc, decin, STDERR); + print("\n"); + ASSERT(instr_same(instr, decin)); + } + + instr_destroy(dc, instr); + instr_destroy(dc, decin); +} + +static void +test_load_store(void *dc) +{ + byte *pc; + instr_t *instr; + + instr = + INSTR_CREATE_lb(dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_12b)); + test_instr_encoding(dc, OP_lb, instr); +} + int main(int argc, char *argv[]) { +#ifdef STANDALONE_DECODER + void *dcontext = GLOBAL_DCONTEXT; +#else + void *dcontext = dr_standalone_init(); +#endif + + test_load_store(dcontext); + print("test_load complete\n"); + print("All tests complete\n"); return 0; } From fc35f0e29195657ca2c0e615d1e7e1ee0fd9b86d Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 16 Jun 2023 00:13:06 +0800 Subject: [PATCH 14/34] Always use init_array for RISC-V --- core/unix/os.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/unix/os.c b/core/unix/os.c index a923c6da54e..ac91ba57951 100644 --- a/core/unix/os.c +++ b/core/unix/os.c @@ -762,7 +762,7 @@ our_init(int argc, char **argv, char **envp) return 0; } -#if defined(STATIC_LIBRARY) || defined(STANDALONE_UNIT_TEST) +#if defined(STATIC_LIBRARY) || defined(STANDALONE_UNIT_TEST) || defined(RISCV64) /* If we're getting linked into a binary that already has an _init definition * like the app's exe or unit_tests, we add a pointer to our_init() to the * .init_array section. We can't use the constructor attribute because not all From 330c996980d5d874080c1956642e73815fafb6c7 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 16 Jun 2023 15:47:51 +0800 Subject: [PATCH 15/34] A simple test works --- core/ir/encode_shared.c | 2 +- core/ir/opnd_api.h | 35 ++++++++++++++++++- core/ir/opnd_shared.c | 21 ++++++++++++ core/ir/riscv64/codec.c | 57 +++++++++++-------------------- core/ir/riscv64/decode.c | 3 +- core/ir/riscv64/encode.c | 11 +++--- core/ir/riscv64/instr.c | 4 +-- suite/tests/CMakeLists.txt | 8 ++--- suite/tests/api/ir_riscv64.c | 6 ++-- suite/tests/api/ir_riscv64.expect | 2 ++ 10 files changed, 92 insertions(+), 57 deletions(-) diff --git a/core/ir/encode_shared.c b/core/ir/encode_shared.c index 0562d4345a6..26957c4278d 100644 --- a/core/ir/encode_shared.c +++ b/core/ir/encode_shared.c @@ -69,7 +69,7 @@ instr_encode_arch(dcontext_t *dcontext, instr_t *instr, byte *copy_pc, byte *fin bool *has_instr_opnds /*OUT OPTIONAL*/ _IF_DEBUG(bool assert_reachable)); -#ifdef AARCH64 +#if defined(AARCH64) || defined(RISCV64) /* exported */ bool diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index b633ffa5b9c..f786750913a 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -2008,6 +2008,18 @@ DR_API opnd_t opnd_create_immed_int(ptr_int_t i, opnd_size_t data_size); +#ifdef RISCV64 +DR_API +/** + * Returns a signed immediate integer operand with value \p i and size + * \p data_size; \p data_size must be a OPSZ_ constant. + * + * The integer will be formatted as a decimal when disassemble. + */ +opnd_t +opnd_create_immed_int_decimal(ptr_int_t i, opnd_size_t data_size); +#endif + DR_API /** * Returns an unsigned immediate integer operand with value \p i and size @@ -2152,6 +2164,26 @@ opnd_t opnd_create_base_disp(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, opnd_size_t data_size); +#ifdef RISCV64 +DR_API +/** + * Returns a memory reference operand that refers to the address: + * - disp(base_reg, index_reg, scale) + * + * or, in other words, + * - base_reg + index_reg*scale + disp + * + * The operand has data size data_size (must be a OPSZ_ constant). + * Both \p base_reg and \p index_reg must be DR_REG_ constants. + * \p scale must be either 0, 1, 2, 4, or 8. + * + * The integer will be formatted as a decimal when disassemble. + */ +opnd_t +opnd_create_base_disp_decimal(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, + opnd_size_t data_size); +#endif + DR_API /** * Returns a memory reference operand that refers to the address: @@ -2176,7 +2208,8 @@ DR_API * needs to be specified for an absolute address; otherwise, simply * use the desired short registers for base and/or index). * - * (The encoding optimization flags are all false when using opnd_create_base_disp()). + * (The encoding optimization flags are all false when using + * opnd_create_base_disp()). */ opnd_t opnd_create_base_disp_ex(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, diff --git a/core/ir/opnd_shared.c b/core/ir/opnd_shared.c index 8b9a0997ce6..7f3eee13391 100644 --- a/core/ir/opnd_shared.c +++ b/core/ir/opnd_shared.c @@ -374,6 +374,16 @@ opnd_create_immed_int(ptr_int_t i, opnd_size_t size) return opnd; } +#ifdef RISCV64 +opnd_t +opnd_create_immed_int_decimal(ptr_int_t i, opnd_size_t size) +{ + opnd_t opnd = opnd_create_immed_int(i, size); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + return opnd; +} +#endif + opnd_t opnd_create_immed_uint(ptr_uint_t i, opnd_size_t size) { @@ -653,6 +663,17 @@ opnd_create_base_disp(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp false, false, false); } +#ifdef RISCV64 +opnd_t +opnd_create_base_disp_decimal(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, + opnd_size_t size) +{ + opnd_t opnd = opnd_create_base_disp(base_reg, index_reg, scale, disp, size); + opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + return opnd; +} +#endif + static inline void opnd_set_disp_helper(opnd_t *opnd, int disp) { diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 1790db94f6f..c70224fdcb2 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -352,8 +352,7 @@ decode_shamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int idx, instr_t *out) { int32_t imm = GET_FIELD(inst, 25, 20); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -368,8 +367,7 @@ decode_shamt5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori int idx, instr_t *out) { int32_t imm = GET_FIELD(inst, 24, 20); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -385,8 +383,7 @@ decode_shamt6_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori { /* shamt6 >= 64 only makes sense on RV128 but let user take care of it. */ int32_t imm = GET_FIELD(inst, 26, 20); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -404,8 +401,7 @@ decode_i_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int idx, instr_t *out) { int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -424,8 +420,7 @@ decode_s_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | (GET_FIELD(inst, 11, 7)); imm = SIGN_EXTEND(imm, 12); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -680,8 +675,7 @@ decode_cshamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori int idx, instr_t *out) { int32_t imm = (BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -722,8 +716,7 @@ decode_caddi16sp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, imm |= (BIT(inst, 2) << 5); imm |= (BIT(inst, 6) << 4); imm = SIGN_EXTEND(imm, 10); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -743,8 +736,7 @@ decode_clwsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int32_t imm = GET_FIELD(inst, 3, 2) << 6; imm |= BIT(inst, 12) << 5; imm |= GET_FIELD(inst, 6, 4) << 2; - opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); instr_set_src(out, idx, opnd); return true; } @@ -764,8 +756,7 @@ decode_cldsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int32_t imm = GET_FIELD(inst, 4, 2) << 6; imm |= BIT(inst, 12) << 5; imm |= GET_FIELD(inst, 6, 5) << 3; - opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); instr_set_src(out, idx, opnd); return true; } @@ -801,8 +792,7 @@ decode_cswsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int idx, instr_t *out) { int32_t imm = (GET_FIELD(inst, 8, 7) << 6) | (GET_FIELD(inst, 12, 9) << 2); - opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); instr_set_dst(out, idx, opnd); return true; } @@ -820,8 +810,7 @@ decode_csdsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int idx, instr_t *out) { int32_t imm = (GET_FIELD(inst, 9, 7) << 6) | (GET_FIELD(inst, 12, 10) << 3); - opnd_t opnd = opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); instr_set_dst(out, idx, opnd); return true; } @@ -842,8 +831,7 @@ decode_ciw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or imm |= GET_FIELD(inst, 12, 11) << 4; imm |= BIT(inst, 5) << 3; imm |= BIT(inst, 6) << 2; - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -865,8 +853,7 @@ decode_clw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or int32_t imm = BIT(inst, 5) << 6; imm |= GET_FIELD(inst, 12, 10) << 3; imm |= BIT(inst, 6) << 2; - opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_4); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_4); instr_set_src(out, idx, opnd); return true; } @@ -886,8 +873,7 @@ decode_cld_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or { reg_t reg = DR_REG_X8 + GET_FIELD(inst, 9, 7); int32_t imm = (GET_FIELD(inst, 6, 5) << 6) | (GET_FIELD(inst, 12, 10) << 3); - opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_8); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_8); instr_set_src(out, idx, opnd); return true; } @@ -909,8 +895,7 @@ decode_csw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or int32_t imm = BIT(inst, 5) << 6; imm |= GET_FIELD(inst, 12, 10) << 3; imm |= BIT(inst, 6) << 2; - opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_4); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_4); instr_set_dst(out, idx, opnd); return true; } @@ -930,8 +915,7 @@ decode_csd_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or { reg_t reg = DR_REG_X8 + GET_FIELD(inst, 9, 7); int32_t imm = (GET_FIELD(inst, 6, 5) << 6) | (GET_FIELD(inst, 12, 10) << 3); - opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_8); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_8); instr_set_dst(out, idx, opnd); return true; } @@ -949,8 +933,7 @@ decode_cimm5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int idx, instr_t *out) { int32_t imm = SIGN_EXTEND((BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2), 6); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -1023,8 +1006,7 @@ decode_v_l_rs1_disp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, { reg_t reg = DR_REG_X0 + GET_FIELD(inst, 19, 15); int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); - opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -1047,8 +1029,7 @@ decode_v_s_rs1_disp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, reg_t reg = DR_REG_X0 + GET_FIELD(inst, 19, 15); int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | GET_FIELD(inst, 11, 7); imm = SIGN_EXTEND(imm, 12); - opnd_t opnd = opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, op_sz); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; + opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, op_sz); instr_set_dst(out, idx, opnd); return true; } diff --git a/core/ir/riscv64/decode.c b/core/ir/riscv64/decode.c index f31ae59670f..d8b56e03ad0 100644 --- a/core/ir/riscv64/decode.c +++ b/core/ir/riscv64/decode.c @@ -244,8 +244,7 @@ check_encode_decode_consistency(dcontext_t *dcontext, instrlist_t *ilist) void decode_debug_checks_arch(void) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); + /* FIXME i#3544: NYI */ } #endif /* DEBUG */ diff --git a/core/ir/riscv64/encode.c b/core/ir/riscv64/encode.c index 76aa13c29c1..c3a4ee50faf 100644 --- a/core/ir/riscv64/encode.c +++ b/core/ir/riscv64/encode.c @@ -74,17 +74,18 @@ const reg_id_t dr_reg_fixer[] = { REG_NULL, void encode_debug_checks(void) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); + /* FIXME i#3544: NYI */ } #endif bool encoding_possible(decode_info_t *di, instr_t *in, const instr_info_t *ii) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); - return false; + uint enc; + + byte tmp[RISCV64_INSTR_SIZE]; + enc = encode_common(&tmp[0], in, di); + return enc != ENCFAIL; } void diff --git a/core/ir/riscv64/instr.c b/core/ir/riscv64/instr.c index 0d7049e3046..2110ea84d3a 100644 --- a/core/ir/riscv64/instr.c +++ b/core/ir/riscv64/instr.c @@ -439,9 +439,7 @@ instr_is_nop(instr_t *instr) bool opnd_same_sizes_ok(opnd_size_t s1, opnd_size_t s2, bool is_reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); - return false; + return (s1 == s2); } instr_t * diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index 1ee413e23d2..305122cb2c6 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -1899,7 +1899,7 @@ endif () # test static decoder library tobuild_api(api.ir-static api/ir_${sfx}.c "" "" ON OFF OFF) -if (AARCH64) +if (AARCH64 OR RISCV64) # The ir_aarch64.expect file is too large for CMake's regexes. set(api.ir-static_runcmp "${CMAKE_CURRENT_SOURCE_DIR}/runcmp.cmake") set(api.ir-static_runcmp_capture "stderr") @@ -5587,7 +5587,7 @@ endif () # XXX i#3544: Enable passed tests on riscv64. if (RISCV64) -set_tests_properties( - code_api|api.ir - PROPERTIES LABELS RISCV64) + set_tests_properties( + code_api|api.ir-static + PROPERTIES LABELS RISCV64) endif () \ No newline at end of file diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index 75f013149fb..e90916abcb6 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -92,9 +92,9 @@ test_load_store(void *dc) byte *pc; instr_t *instr; - instr = - INSTR_CREATE_lb(dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_12b)); + instr = INSTR_CREATE_lb( + dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 8, OPSZ_1)); test_instr_encoding(dc, OP_lb, instr); } diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index ad3b0a3ddba..4482892f566 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -1 +1,3 @@ +lb +8(%a1)[1byte] -> %a0 +test_load complete All tests complete From 6d8b730fed7064af4cf61dbd6d562e68482484f7 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Fri, 16 Jun 2023 17:14:44 +0800 Subject: [PATCH 16/34] Dynamic linking test works --- core/drlibc/drlibc_module_elf.c | 3 ++- core/ir/riscv64/instr.c | 22 ---------------------- core/unix/signal_linux_riscv64.c | 3 +-- suite/tests/CMakeLists.txt | 1 + 4 files changed, 4 insertions(+), 25 deletions(-) diff --git a/core/drlibc/drlibc_module_elf.c b/core/drlibc/drlibc_module_elf.c index d5d27882e6d..9118c4e6a6c 100644 --- a/core/drlibc/drlibc_module_elf.c +++ b/core/drlibc/drlibc_module_elf.c @@ -130,7 +130,8 @@ is_elf_so_header_common(app_pc base, size_t size, bool memory) ASSERT_CURIOSITY(!memory || #ifdef X64 elf_header.e_machine == EM_X86_64 || - elf_header.e_machine == EM_AARCH64 + elf_header.e_machine == EM_AARCH64 || + elf_header.e_machine == EM_RISCV #else elf_header.e_machine == EM_386 || elf_header.e_machine == EM_ARM #endif diff --git a/core/ir/riscv64/instr.c b/core/ir/riscv64/instr.c index 2110ea84d3a..c11f56c0571 100644 --- a/core/ir/riscv64/instr.c +++ b/core/ir/riscv64/instr.c @@ -330,88 +330,66 @@ reg_is_gpr(reg_id_t reg) bool reg_is_simd(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_vector_simd(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_opmask(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_bnd(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_strictly_zmm(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_ymm(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_strictly_ymm(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_xmm(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_strictly_xmm(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool reg_is_mmx(reg_id_t reg) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool instr_is_opmask(instr_t *instr) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } diff --git a/core/unix/signal_linux_riscv64.c b/core/unix/signal_linux_riscv64.c index 8e3d1106711..0e66a8d646a 100644 --- a/core/unix/signal_linux_riscv64.c +++ b/core/unix/signal_linux_riscv64.c @@ -87,6 +87,5 @@ signal_frame_extra_size(bool include_alignment) void signal_arch_init(void) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); + /* Nothing. */ } diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index 305122cb2c6..ea77e1e659b 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -5588,6 +5588,7 @@ endif () # XXX i#3544: Enable passed tests on riscv64. if (RISCV64) set_tests_properties( + code_api|api.ir code_api|api.ir-static PROPERTIES LABELS RISCV64) endif () \ No newline at end of file From 57e48a011117b32fbde47aa7fbd3e65268fa4bba Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 01:27:23 +0800 Subject: [PATCH 17/34] Added integer load/store tests --- core/ir/riscv64/codec.py | 6 +- suite/tests/api/ir_riscv64.c | 93 +++++++++++++++++++++++++++++-- suite/tests/api/ir_riscv64.expect | 22 +++++++- 3 files changed, 113 insertions(+), 8 deletions(-) diff --git a/core/ir/riscv64/codec.py b/core/ir/riscv64/codec.py index 127db092f2d..f8495b7855d 100755 --- a/core/ir/riscv64/codec.py +++ b/core/ir/riscv64/codec.py @@ -599,10 +599,12 @@ def __init__(self) -> None: def __fixup_compressed_inst(self, inst: Instruction): opc = (inst.match & inst.mask) & 0x3 funct3 = (inst.match & inst.mask) >> 13 - if opc == 0 and funct3 not in [0, 0b100]: # LOAD/STORE instructions + if (opc == 0b00 or opc == 0b10) and funct3 not in [0, 0b100]: # LOAD/STORE instructions dbg(f'fixup: {inst.name} {[f.name for f in inst.flds]}') # Immediate argument will handle the base+disp. - inst.flds.pop(1) + if opc == 0b00: + inst.flds.pop(1) + inst.flds.reverse() dbg(f' -> {" " * len(inst.name)} {[f.name for f in inst.flds]}') elif Field.CB_IMM in inst.flds: # Compare-and-branch instructions need their branch operand moved diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index e90916abcb6..7d5fba7fb63 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -87,15 +87,100 @@ test_instr_encoding(void *dc, uint opcode, instr_t *instr) } static void -test_load_store(void *dc) +test_integer_load_store(void *dc) { byte *pc; instr_t *instr; + /* Load */ instr = INSTR_CREATE_lb( dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 8, OPSZ_1)); + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_1)); test_instr_encoding(dc, OP_lb, instr); + instr = INSTR_CREATE_lbu( + dc, opnd_create_reg(DR_REG_X0), + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, -1, OPSZ_1)); + test_instr_encoding(dc, OP_lbu, instr); + instr = INSTR_CREATE_lh( + dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_2)); + test_instr_encoding(dc, OP_lh, instr); + instr = INSTR_CREATE_lhu( + dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, 0, OPSZ_2)); + test_instr_encoding(dc, OP_lhu, instr); + instr = INSTR_CREATE_lw( + dc, opnd_create_reg(DR_REG_X31), + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, -1, OPSZ_4)); + test_instr_encoding(dc, OP_lw, instr); + instr = INSTR_CREATE_lwu( + dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, 0, OPSZ_4)); + test_instr_encoding(dc, OP_lwu, instr); + instr = INSTR_CREATE_ld( + dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 42, OPSZ_8)); + test_instr_encoding(dc, OP_ld, instr); + + /* Store */ + instr = INSTR_CREATE_sb( + dc, opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_1), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_sb, instr); + instr = INSTR_CREATE_sh( + dc, opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_2), + opnd_create_reg(DR_REG_X31)); + test_instr_encoding(dc, OP_sh, instr); + instr = INSTR_CREATE_sw( + dc, + opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_4), + opnd_create_reg(DR_REG_X0)); + test_instr_encoding(dc, OP_sw, instr); + instr = INSTR_CREATE_sd( + dc, opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 42, OPSZ_8), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_sd, instr); + + /* Compressed Load */ + instr = INSTR_CREATE_c_ldsp( + dc, opnd_create_reg(DR_REG_A0), + opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8)); + test_instr_encoding(dc, OP_c_ldsp, instr); + instr = INSTR_CREATE_c_ld(dc, opnd_create_reg(DR_REG_X8), + opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8)); + test_instr_encoding(dc, OP_c_ld, instr); + instr = + INSTR_CREATE_c_lwsp(dc, opnd_create_reg(DR_REG_X0), + opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, + ((1 << 5) - 1) << 2, OPSZ_4)); + test_instr_encoding(dc, OP_c_lwsp, instr); + instr = INSTR_CREATE_c_lw(dc, opnd_create_reg(DR_REG_X8), + opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 2, OPSZ_4)); + test_instr_encoding(dc, OP_c_lw, instr); + + /* Compressed Store */ + instr = INSTR_CREATE_c_sdsp( + dc, opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_c_sdsp, instr); + instr = INSTR_CREATE_c_sd(dc, + opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8), + opnd_create_reg(DR_REG_X8)); + test_instr_encoding(dc, OP_c_sd, instr); + instr = + INSTR_CREATE_c_swsp(dc, + opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, + ((1 << 5) - 1) << 2, OPSZ_4), + opnd_create_reg(DR_REG_X0)); + test_instr_encoding(dc, OP_c_swsp, instr); + instr = INSTR_CREATE_c_sw(dc, + opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 2, OPSZ_4), + opnd_create_reg(DR_REG_X8)); + test_instr_encoding(dc, OP_c_sw, instr); } int @@ -107,8 +192,8 @@ main(int argc, char *argv[]) void *dcontext = dr_standalone_init(); #endif - test_load_store(dcontext); - print("test_load complete\n"); + test_integer_load_store(dcontext); + print("test_integer_load_store complete\n"); print("All tests complete\n"); return 0; diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index 4482892f566..fdcc9f76376 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -1,3 +1,21 @@ -lb +8(%a1)[1byte] -> %a0 -test_load complete +lb (%a1)[1byte] -> %a0 +lbu -1(%a1)[1byte] -> %zero +lh +2047(%a1)[2byte] -> %a0 +lhu (%zero)[2byte] -> %a0 +lw -1(%a1)[4byte] -> %t6 +lwu (%t6)[4byte] -> %a0 +ld +42(%a1)[8byte] -> %a0 +sb %a0 -> (%a1)[1byte] +sh %t6 -> -1(%zero)[2byte] +sw %zero -> +2047(%t6)[4byte] +sd %a0 -> +42(%a1)[8byte] +c.ldsp (%sp)[8byte] -> %a0 +c.ld +248(%a5)[8byte] -> %fp +c.lwsp +124(%sp)[4byte] -> %zero +c.lw +124(%a5)[4byte] -> %fp +c.sdsp %a0 -> (%sp)[8byte] +c.sd %fp -> +248(%a5)[8byte] +c.swsp %zero -> +124(%sp)[4byte] +c.sw %fp -> +124(%a5)[4byte] +test_integer_load_store complete All tests complete From eab93f1bc461db0254222d8cbbc6a03c5eddb55a Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 05:25:55 +0000 Subject: [PATCH 18/34] Added float load/store tests --- core/ir/opnd_api.h | 8 ++--- core/ir/riscv64/codec.c | 4 +++ core/ir/riscv64/codec.py | 6 ++-- suite/tests/api/ir_riscv64.c | 56 ++++++++++++++++++++++++++++++- suite/tests/api/ir_riscv64.expect | 9 +++++ 5 files changed, 76 insertions(+), 7 deletions(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index f786750913a..2955bfeb24b 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1284,10 +1284,10 @@ enum { DR_REG_LAST_VALID_ENUM = DR_REG_FCSR, /**< Last valid register enum. */ DR_REG_LAST_ENUM = DR_REG_FCSR, /**< Last value of register enums. */ - DR_REG_START_64 = DR_REG_X0, /**< Start of 64-bit general register enum values. */ - DR_REG_STOP_64 = DR_REG_X31, /**< End of 64-bit general register enum values. */ - DR_REG_START_32 = DR_REG_X0, /**< Start of 32-bit general register enum values. */ - DR_REG_STOP_32 = DR_REG_X31, /**< End of 32-bit general register enum values. */ + DR_REG_START_64 = DR_REG_X0, /**< Start of 64-bit register enum values. */ + DR_REG_STOP_64 = DR_REG_F31, /**< End of 64-bit register enum values. */ + DR_REG_START_32 = DR_REG_X0, /**< Start of 32-bit register enum values. */ + DR_REG_STOP_32 = DR_REG_F31, /**< End of 32-bit register enum values. */ DR_REG_START_GPR = DR_REG_X0, /**< Start of general register registers. */ DR_REG_STOP_GPR = DR_REG_X31, /**< End of general register registers. */ DR_REG_XSP = DR_REG_SP, /**< Platform-independent way to refer to stack pointer. */ diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index c70224fdcb2..e1b8da5e2da 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -1999,6 +1999,7 @@ encode_clwsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_disp(opnd); + ASSERT(opnd_get_base(opnd) == DR_REG_SP); *out |= SET_FIELD(imm >> 6, 3, 2) | SET_FIELD(imm >> 2, 6, 4) | SET_FIELD(imm >> 5, 12, 12); return true; @@ -2017,6 +2018,7 @@ encode_cldsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_disp(opnd); + ASSERT(opnd_get_base(opnd) == DR_REG_SP); *out |= SET_FIELD(imm >> 6, 4, 2) | SET_FIELD(imm >> 3, 6, 5) | SET_FIELD(imm >> 5, 12, 12); return true; @@ -2052,6 +2054,7 @@ encode_cswsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_dst(instr, idx); int32_t imm = opnd_get_disp(opnd); + ASSERT(opnd_get_base(opnd) == DR_REG_SP); *out |= SET_FIELD(imm >> 6, 8, 7) | SET_FIELD(imm >> 2, 12, 9); return true; } @@ -2069,6 +2072,7 @@ encode_csdsp_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_dst(instr, idx); int32_t imm = opnd_get_disp(opnd); + ASSERT(opnd_get_base(opnd) == DR_REG_SP); *out |= SET_FIELD(imm >> 6, 9, 7) | SET_FIELD(imm >> 3, 12, 10); return true; } diff --git a/core/ir/riscv64/codec.py b/core/ir/riscv64/codec.py index f8495b7855d..8c155c4b550 100755 --- a/core/ir/riscv64/codec.py +++ b/core/ir/riscv64/codec.py @@ -472,7 +472,8 @@ def __new__(cls, value: int, arg_name: str, is_dest: bool, { '': 'OPSZ_0', 'lb': 'OPSZ_1', 'lh': 'OPSZ_2', 'lw': 'OPSZ_4', 'ld': 'OPSZ_8', 'lbu': 'OPSZ_1', 'lhu': 'OPSZ_2', 'lwu': 'OPSZ_4', - 'sb': 'OPSZ_1', 'sh': 'OPSZ_2', 'sw': 'OPSZ_4', 'sd': 'OPSZ_8' + 'sb': 'OPSZ_1', 'sh': 'OPSZ_2', 'sw': 'OPSZ_4', 'sd': 'OPSZ_8', + 'flw': 'OPSZ_4', 'fld': 'OPSZ_8', 'fsw': 'OPSZ_4', 'fsd': 'OPSZ_8' }, 'im(rs1)', 'The register-relative memory source location (reg+imm).' @@ -483,7 +484,8 @@ def __new__(cls, value: int, arg_name: str, is_dest: bool, { '': 'OPSZ_0', 'lb': 'OPSZ_1', 'lh': 'OPSZ_2', 'lw': 'OPSZ_4', 'ld': 'OPSZ_8', 'lbu': 'OPSZ_1', 'lhu': 'OPSZ_2', 'lwu': 'OPSZ_4', - 'sb': 'OPSZ_1', 'sh': 'OPSZ_2', 'sw': 'OPSZ_4', 'sd': 'OPSZ_8' + 'sb': 'OPSZ_1', 'sh': 'OPSZ_2', 'sw': 'OPSZ_4', 'sd': 'OPSZ_8', + 'flw': 'OPSZ_4', 'fld': 'OPSZ_8', 'fsw': 'OPSZ_4', 'fsd': 'OPSZ_8' }, 'im(rs1)', 'The register-relative memory target location (reg+imm).' diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index 7d5fba7fb63..e373d42f0c5 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -89,7 +89,6 @@ test_instr_encoding(void *dc, uint opcode, instr_t *instr) static void test_integer_load_store(void *dc) { - byte *pc; instr_t *instr; /* Load */ @@ -183,6 +182,58 @@ test_integer_load_store(void *dc) test_instr_encoding(dc, OP_c_sw, instr); } +static void +test_float_load_store(void *dc) +{ + instr_t *instr; + + /* Load */ + instr = INSTR_CREATE_flw( + dc, opnd_create_reg(DR_REG_F0), + opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_4)); + test_instr_encoding(dc, OP_flw, instr); + instr = INSTR_CREATE_fld( + dc, opnd_create_reg(DR_REG_F31), + opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_8)); + test_instr_encoding(dc, OP_fld, instr); + + /* Store */ + instr = INSTR_CREATE_fsw( + dc, + opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_4), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fsw, instr); + instr = INSTR_CREATE_fsd( + dc, + opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_8), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsd, instr); + + /* Compressed Load */ + instr = INSTR_CREATE_c_fldsp( + dc, opnd_create_reg(DR_REG_F0), + opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8)); + test_instr_encoding(dc, OP_c_fldsp, instr); + instr = + INSTR_CREATE_c_fld(dc, opnd_create_reg(DR_REG_F8), + opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8)); + test_instr_encoding(dc, OP_c_fld, instr); + /* There is no c.flw* instructions in RV64. */ + + /* Compressed Store */ + instr = INSTR_CREATE_c_fsdsp( + dc, opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_c_fsdsp, instr); + instr = INSTR_CREATE_c_fsd(dc, + opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8), + opnd_create_reg(DR_REG_F8)); + test_instr_encoding(dc, OP_c_fsd, instr); + /* There is no c.fsw* instructions in RV64. */ +} + int main(int argc, char *argv[]) { @@ -195,6 +246,9 @@ main(int argc, char *argv[]) test_integer_load_store(dcontext); print("test_integer_load_store complete\n"); + test_float_load_store(dcontext); + print("test_float_load_store complete\n"); + print("All tests complete\n"); return 0; } diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index fdcc9f76376..3adcc7e45ce 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -18,4 +18,13 @@ c.sd %fp -> +248(%a5)[8byte] c.swsp %zero -> +124(%sp)[4byte] c.sw %fp -> +124(%a5)[4byte] test_integer_load_store complete +flw (%a1)[4byte] -> %ft0 +fld -1(%zero)[8byte] -> %ft11 +fsw %ft1 -> +2047(%t6)[4byte] +fsd %ft11 -> +2047(%t6)[8byte] +c.fldsp (%sp)[8byte] -> %ft0 +c.fld +248(%a5)[8byte] -> %fs0 +c.fsdsp %ft11 -> (%sp)[8byte] +c.fsd %fs0 -> +248(%a5)[8byte] +test_float_load_store complete All tests complete From 4d15ec10641810c2ad074830d539a23905d4f941 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 06:19:08 +0000 Subject: [PATCH 19/34] Added atomic tests --- suite/tests/api/ir_riscv64.c | 101 +++++++++++++++++++++++++++++++++++ 1 file changed, 101 insertions(+) diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index e373d42f0c5..0a9311268db 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -234,6 +234,104 @@ test_float_load_store(void *dc) /* There is no c.fsw* instructions in RV64. */ } +static void +test_atomic(void *dc) +{ + instr_t *instr; + + /* FIXME i#3544: Use [aq][rl] instead of hex number when disassembling. */ + + /* LR/SC */ + instr = INSTR_CREATE_lr_w(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int(0b00, OPSZ_2b)); + test_instr_encoding(dc, OP_lr_w, instr); + instr = INSTR_CREATE_lr_d(dc, opnd_create_reg(DR_REG_X0), opnd_create_reg(DR_REG_X31), + opnd_create_immed_int(0b10, OPSZ_2b)); + test_instr_encoding(dc, OP_lr_d, instr); + instr = INSTR_CREATE_sc_w(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_sc_w, instr); + instr = INSTR_CREATE_sc_d(dc, opnd_create_reg(DR_REG_X0), opnd_create_reg(DR_REG_X31), + opnd_create_reg(DR_REG_A1), + opnd_create_immed_int(0b11, OPSZ_2b)); + test_instr_encoding(dc, OP_sc_d, instr); + + /* AMO */ + instr = INSTR_CREATE_amoswap_w( + dc, opnd_create_reg(DR_REG_X0), opnd_create_reg(DR_REG_X1), + opnd_create_reg(DR_REG_X31), opnd_create_immed_int(0b00, OPSZ_2b)); + test_instr_encoding(dc, OP_amoswap_w, instr); + instr = INSTR_CREATE_amoswap_d(dc, opnd_create_reg(DR_REG_X31), + opnd_create_reg(DR_REG_X1), opnd_create_reg(DR_REG_X0), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoswap_d, instr); + instr = INSTR_CREATE_amoadd_w(dc, opnd_create_reg(DR_REG_X0), + opnd_create_reg(DR_REG_X31), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b10, OPSZ_2b)); + test_instr_encoding(dc, OP_amoadd_w, instr); + instr = INSTR_CREATE_amoadd_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b11, OPSZ_2b)); + test_instr_encoding(dc, OP_amoadd_d, instr); + instr = INSTR_CREATE_amoxor_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoxor_w, instr); + instr = INSTR_CREATE_amoxor_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoxor_d, instr); + instr = INSTR_CREATE_amoand_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoand_w, instr); + instr = INSTR_CREATE_amoand_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoand_d, instr); + instr = INSTR_CREATE_amoor_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoor_w, instr); + instr = INSTR_CREATE_amoor_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amoor_d, instr); + instr = INSTR_CREATE_amomin_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amomin_w, instr); + instr = INSTR_CREATE_amomin_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amomin_d, instr); + instr = INSTR_CREATE_amomax_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amomax_w, instr); + instr = INSTR_CREATE_amomax_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amomax_d, instr); + instr = INSTR_CREATE_amominu_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amominu_w, instr); + instr = INSTR_CREATE_amominu_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amominu_d, instr); + instr = INSTR_CREATE_amomaxu_w(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amomaxu_w, instr); + instr = INSTR_CREATE_amomaxu_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2), + opnd_create_immed_int(0b01, OPSZ_2b)); + test_instr_encoding(dc, OP_amomaxu_d, instr); +} + int main(int argc, char *argv[]) { @@ -249,6 +347,9 @@ main(int argc, char *argv[]) test_float_load_store(dcontext); print("test_float_load_store complete\n"); + test_atomic(dcontext); + print("test_atomic complete\n"); + print("All tests complete\n"); return 0; } From e143945e3c78c34e62b5d14cbf696ed6ab7da097 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 07:10:19 +0000 Subject: [PATCH 20/34] Added fcvt tests --- core/ir/riscv64/codec.c | 7 ++ core/ir/riscv64/isl/rv32f.txt | 4 +- core/ir/riscv64/isl/rv64d.txt | 4 +- core/ir/riscv64/isl/rv64f.txt | 4 +- core/ir/riscv64/isl/rv64q.txt | 4 +- suite/tests/api/ir_riscv64.c | 144 ++++++++++++++++++++++++++++++ suite/tests/api/ir_riscv64.expect | 54 +++++++++++ 7 files changed, 213 insertions(+), 8 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index e1b8da5e2da..010ec06da89 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -337,6 +337,8 @@ decode_rm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc instr_t *out) { int32_t imm = GET_FIELD(inst, 14, 12); + /* Invalid. Reserved for future use. */ + ASSERT(imm != 0b101 && imm != 0b110); opnd_t opnd = opnd_create_immed_int(imm, op_sz); instr_set_src(out, idx, opnd); return true; @@ -1446,6 +1448,7 @@ static bool encode_rdfp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_dst(instr, idx); + ASSERT(opnd_get_reg(opnd) >= DR_REG_F0); uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; *out |= SET_FIELD(rd, 11, 7); return true; @@ -1476,6 +1479,7 @@ static bool encode_rs1fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); + ASSERT(opnd_get_reg(opnd) >= DR_REG_F0); uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; *out |= SET_FIELD(rd, 19, 15); return true; @@ -1521,6 +1525,7 @@ static bool encode_rs2fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); + ASSERT(opnd_get_reg(opnd) >= DR_REG_F0); uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; *out |= SET_FIELD(rd, 24, 20); return true; @@ -1623,6 +1628,8 @@ encode_rm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); int32_t imm = opnd_get_immed_int(opnd); + /* Invalid. Reserved for future use. */ + ASSERT(imm != 0b101 && imm != 0b110); *out |= SET_FIELD(imm, 14, 12); return true; } diff --git a/core/ir/riscv64/isl/rv32f.txt b/core/ir/riscv64/isl/rv32f.txt index d3f96270809..b2303e1c072 100644 --- a/core/ir/riscv64/isl/rv32f.txt +++ b/core/ir/riscv64/isl/rv32f.txt @@ -18,12 +18,12 @@ fsgnjx.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........010.....101001 fmin.s | r | rs2(fp) rs1(fp) rd(fp) | 0010100..........000.....1010011 fmax.s | r | rs2(fp) rs1(fp) rd(fp) | 0010100..........001.....1010011 fcvt.w.s | r | rs1(fp) rm rd | 110000000000.............1010011 -fcvt.wu.s | r | rs1 rm rd | 110000000001.............1010011 +fcvt.wu.s | r | rs1(fp) rm rd | 110000000001.............1010011 fmv.x.w | r | rs1(fp) rd | 111000000000.....000.....1010011 feq.s | r | rs2(fp) rs1(fp) rd | 1010000..........010.....1010011 flt.s | r | rs2(fp) rs1(fp) rd | 1010000..........001.....1010011 fle.s | r | rs2(fp) rs1(fp) rd | 1010000..........000.....1010011 fclass.s | r | rs1(fp) rd | 111000000000.....001.....1010011 fcvt.s.w | r | rs1 rm rd(fp) | 110100000000.............1010011 -fcvt.s.wu | r | rs1 rm rd | 110100000001.............1010011 +fcvt.s.wu | r | rs1 rm rd(fp) | 110100000001.............1010011 fmv.w.x | r | rs1 rd(fp) | 111100000000.....000.....1010011 diff --git a/core/ir/riscv64/isl/rv64d.txt b/core/ir/riscv64/isl/rv64d.txt index edcccdc8b25..9a90b889660 100644 --- a/core/ir/riscv64/isl/rv64d.txt +++ b/core/ir/riscv64/isl/rv64d.txt @@ -2,8 +2,8 @@ # Version 2.2 fcvt.l.d | r | rs1(fp) rm rd | 110000100010.............1010011 -fcvt.lu.d | r | rs1 rm rd | 110000100011.............1010011 +fcvt.lu.d | r | rs1(fp) rm rd | 110000100011.............1010011 fmv.x.d | r | rs1(fp) rd | 111000100000.....000.....1010011 fcvt.d.l | r | rs1 rm rd(fp) | 110100100010.............1010011 -fcvt.d.lu | r | rs1 rm rd | 110100100011.............1010011 +fcvt.d.lu | r | rs1 rm rd(fp) | 110100100011.............1010011 fmv.d.x | r | rs1 rd(fp) | 111100100000.....000.....1010011 diff --git a/core/ir/riscv64/isl/rv64f.txt b/core/ir/riscv64/isl/rv64f.txt index 81db3ddead9..20b2c5c5ba2 100644 --- a/core/ir/riscv64/isl/rv64f.txt +++ b/core/ir/riscv64/isl/rv64f.txt @@ -2,6 +2,6 @@ # Version 2.2 fcvt.l.s | r | rs1(fp) rm rd | 110000000010.............1010011 -fcvt.lu.s | r | rs1 rm rd | 110000000011.............1010011 +fcvt.lu.s | r | rs1(fp) rm rd | 110000000011.............1010011 fcvt.s.l | r | rs1 rm rd(fp) | 110100000010.............1010011 -fcvt.s.lu | r | rs1 rm rd | 110100000011.............1010011 +fcvt.s.lu | r | rs1 rm rd(fp) | 110100000011.............1010011 diff --git a/core/ir/riscv64/isl/rv64q.txt b/core/ir/riscv64/isl/rv64q.txt index 48bd171d177..377790db936 100644 --- a/core/ir/riscv64/isl/rv64q.txt +++ b/core/ir/riscv64/isl/rv64q.txt @@ -2,6 +2,6 @@ # Version 2.2 fcvt.l.q | r | rs1(fp) rm rd | 110001100010.............1010011 -fcvt.lu.q | r | rs1 rm rd | 110001100011.............1010011 +fcvt.lu.q | r | rs1(fp) rm rd | 110001100011.............1010011 fcvt.q.l | r | rs1 rm rd(fp) | 110101100010.............1010011 -fcvt.q.lu | r | rs1 rm rd | 110101100011.............1010011 +fcvt.q.lu | r | rs1 rm rd(fp) | 110101100011.............1010011 diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index 0a9311268db..b66bf43034b 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -332,6 +332,147 @@ test_atomic(void *dc) test_instr_encoding(dc, OP_amomaxu_d, instr); } +static void +test_fcvt(void *dc) +{ + instr_t *instr; + + instr = INSTR_CREATE_fcvt_l_s(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_l_s, instr); + instr = INSTR_CREATE_fcvt_lu_s(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_lu_s, instr); + + instr = INSTR_CREATE_fcvt_s_l(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_s_l, instr); + instr = INSTR_CREATE_fcvt_s_lu(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_s_lu, instr); + + instr = INSTR_CREATE_fcvt_l_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_l_d, instr); + instr = INSTR_CREATE_fcvt_lu_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_lu_d, instr); + + instr = INSTR_CREATE_fcvt_d_l(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_d_l, instr); + instr = INSTR_CREATE_fcvt_d_lu(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_d_lu, instr); + + instr = INSTR_CREATE_fcvt_d_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_d_s, instr); + instr = INSTR_CREATE_fcvt_s_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_s_d, instr); + + instr = INSTR_CREATE_fcvt_w_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_w_d, instr); + instr = INSTR_CREATE_fcvt_wu_d(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_wu_d, instr); + + instr = INSTR_CREATE_fcvt_d_w(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_d_w, instr); + instr = INSTR_CREATE_fcvt_d_wu(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_d_wu, instr); + + instr = INSTR_CREATE_fcvt_s_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_s_q, instr); + instr = INSTR_CREATE_fcvt_q_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_q_s, instr); + + instr = INSTR_CREATE_fcvt_d_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_d_q, instr); + instr = INSTR_CREATE_fcvt_q_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_q_d, instr); + + instr = INSTR_CREATE_fcvt_w_q(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_w_q, instr); + instr = INSTR_CREATE_fcvt_q_w(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_q_w, instr); + + instr = INSTR_CREATE_fcvt_wu_q(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_wu_q, instr); + instr = INSTR_CREATE_fcvt_q_wu(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_q_wu, instr); + + instr = INSTR_CREATE_fcvt_w_s(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_w_s, instr); + instr = INSTR_CREATE_fcvt_s_w(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_s_w, instr); + + instr = INSTR_CREATE_fcvt_wu_s(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_wu_s, instr); + instr = INSTR_CREATE_fcvt_s_wu(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_s_wu, instr); + + instr = INSTR_CREATE_fcvt_l_q(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_l_q, instr); + instr = INSTR_CREATE_fcvt_lu_q(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fcvt_lu_q, instr); + + instr = INSTR_CREATE_fcvt_q_l(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_q_l, instr); + instr = INSTR_CREATE_fcvt_q_lu(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fcvt_q_lu, instr); +} + int main(int argc, char *argv[]) { @@ -350,6 +491,9 @@ main(int argc, char *argv[]) test_atomic(dcontext); print("test_atomic complete\n"); + test_fcvt(dcontext); + print("test_fcvt complete\n"); + print("All tests complete\n"); return 0; } diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index 3adcc7e45ce..9dbb925278b 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -27,4 +27,58 @@ c.fld +248(%a5)[8byte] -> %fs0 c.fsdsp %ft11 -> (%sp)[8byte] c.fsd %fs0 -> +248(%a5)[8byte] test_float_load_store complete +lr.w %a1 0x0 -> %a0 +lr.d %t6 0x2 -> %zero +sc.w %a1 %a2 0x1 -> %a0 +sc.d %t6 %a1 0x3 -> %zero +amoswap.w %ra %t6 0x0 -> %zero +amoswap.d %ra %zero 0x1 -> %t6 +amoadd.w %t6 %a2 0x2 -> %zero +amoadd.d %a1 %a2 0x3 -> %a0 +amoxor.w %a1 %a2 0x1 -> %a0 +amoxor.d %a1 %a2 0x1 -> %a0 +amoand.w %a1 %a2 0x1 -> %a0 +amoand.d %a1 %a2 0x1 -> %a0 +amoor.w %a1 %a2 0x1 -> %a0 +amoor.d %a1 %a2 0x1 -> %a0 +amomin.w %a1 %a2 0x1 -> %a0 +amomin.d %a1 %a2 0x1 -> %a0 +amomax.w %a1 %a2 0x1 -> %a0 +amomax.d %a1 %a2 0x1 -> %a0 +amominu.w %a1 %a2 0x1 -> %a0 +amominu.d %a1 %a2 0x1 -> %a0 +amomaxu.w %a1 %a2 0x1 -> %a0 +amomaxu.d %a1 %a2 0x1 -> %a0 +test_atomic complete +fcvt.l.s 0x0 %ft0 -> %a0 +fcvt.lu.s 0x0 %ft0 -> %a0 +fcvt.s.l 0x0 %a0 -> %ft0 +fcvt.s.lu 0x0 %a0 -> %ft0 +fcvt.l.d 0x0 %ft0 -> %a0 +fcvt.lu.d 0x0 %ft0 -> %a0 +fcvt.d.l 0x0 %a0 -> %ft0 +fcvt.d.lu 0x0 %a0 -> %ft0 +fcvt.d.s 0x0 %ft0 -> %ft0 +fcvt.s.d 0x0 %ft0 -> %ft0 +fcvt.w.d 0x0 %ft0 -> %a0 +fcvt.wu.d 0x0 %ft0 -> %a0 +fcvt.d.w 0x0 %a0 -> %ft0 +fcvt.d.wu 0x0 %a0 -> %ft0 +fcvt.s.q 0x0 %ft0 -> %ft0 +fcvt.q.s 0x0 %ft0 -> %ft0 +fcvt.d.q 0x0 %ft0 -> %ft0 +fcvt.q.d 0x0 %ft0 -> %ft0 +fcvt.w.q 0x0 %ft0 -> %a0 +fcvt.q.w 0x0 %a0 -> %ft0 +fcvt.wu.q 0x0 %ft0 -> %a0 +fcvt.q.wu 0x0 %a0 -> %ft0 +fcvt.w.s 0x0 %ft0 -> %a0 +fcvt.s.w 0x0 %a0 -> %ft0 +fcvt.wu.s 0x0 %ft0 -> %a0 +fcvt.s.wu 0x0 %a0 -> %ft0 +fcvt.l.q 0x0 %ft0 -> %a0 +fcvt.lu.q 0x0 %ft0 -> %a0 +fcvt.q.l 0x0 %a0 -> %ft0 +fcvt.q.lu 0x0 %a0 -> %ft0 +test_fcvt complete All tests complete From 5a9d242e22e35ed36eda6ed66fb262ef17b0352c Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 07:20:14 +0000 Subject: [PATCH 21/34] Added fmv tests --- suite/tests/api/ir_riscv64.c | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index b66bf43034b..d0b115ad42e 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -342,25 +342,25 @@ test_fcvt(void *dc) opnd_create_reg(DR_REG_F0)); test_instr_encoding(dc, OP_fcvt_l_s, instr); instr = INSTR_CREATE_fcvt_lu_s(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_immed_int(0b001, OPSZ_3b), opnd_create_reg(DR_REG_F0)); test_instr_encoding(dc, OP_fcvt_lu_s, instr); instr = INSTR_CREATE_fcvt_s_l(dc, opnd_create_reg(DR_REG_F0), - opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_immed_int(0b010, OPSZ_3b), opnd_create_reg(DR_REG_A0)); test_instr_encoding(dc, OP_fcvt_s_l, instr); instr = INSTR_CREATE_fcvt_s_lu(dc, opnd_create_reg(DR_REG_F0), - opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_immed_int(0b011, OPSZ_3b), opnd_create_reg(DR_REG_A0)); test_instr_encoding(dc, OP_fcvt_s_lu, instr); instr = INSTR_CREATE_fcvt_l_d(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_immed_int(0b100, OPSZ_3b), opnd_create_reg(DR_REG_F0)); test_instr_encoding(dc, OP_fcvt_l_d, instr); instr = INSTR_CREATE_fcvt_lu_d(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_immed_int(0b111, OPSZ_3b), opnd_create_reg(DR_REG_F0)); test_instr_encoding(dc, OP_fcvt_lu_d, instr); @@ -473,6 +473,24 @@ test_fcvt(void *dc) test_instr_encoding(dc, OP_fcvt_q_lu, instr); } +static void +test_fmv(void *dc) +{ + instr_t *instr; + instr = + INSTR_CREATE_fmv_x_d(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fmv_x_d, instr); + instr = + INSTR_CREATE_fmv_d_x(dc, opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_X0)); + test_instr_encoding(dc, OP_fmv_d_x, instr); + instr = + INSTR_CREATE_fmv_x_w(dc, opnd_create_reg(DR_REG_X0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fmv_x_w, instr); + instr = + INSTR_CREATE_fmv_w_x(dc, opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_fmv_w_x, instr); +} + int main(int argc, char *argv[]) { @@ -494,6 +512,9 @@ main(int argc, char *argv[]) test_fcvt(dcontext); print("test_fcvt complete\n"); + test_fmv(dcontext); + print("test_fmv complete\n"); + print("All tests complete\n"); return 0; } From ab114b269131a85aeb77ee02d04976ebe6808f42 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 09:01:52 +0000 Subject: [PATCH 22/34] Added float arith tests --- core/ir/riscv64/codec.c | 10 +- core/ir/riscv64/codec.h | 2 +- core/ir/riscv64/codec.py | 2 +- core/ir/riscv64/isl/rv32d.txt | 52 ++++---- core/ir/riscv64/isl/rv32f.txt | 52 ++++---- core/ir/riscv64/isl/rv32q.txt | 56 ++++---- suite/tests/api/ir_riscv64.c | 208 ++++++++++++++++++++++++++++++ suite/tests/api/ir_riscv64.expect | 64 ++++++++- 8 files changed, 354 insertions(+), 92 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 010ec06da89..104e1b1b9c6 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -237,8 +237,8 @@ decode_rs2fp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig * Applies to the R4 uncompressed format. */ static bool -decode_rs3_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc, - int idx, instr_t *out) +decode_rs3fp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig_pc, + int idx, instr_t *out) { reg_t reg = DR_REG_F0 + GET_FIELD(inst, 31, 27); opnd_t opnd = opnd_create_reg(reg); @@ -1050,7 +1050,7 @@ opnd_dec_func_t opnd_decoders[] = { [RISCV64_FLD_BASE] = decode_base_opnd, [RISCV64_FLD_RS2] = decode_rs2_opnd, [RISCV64_FLD_RS2FP] = decode_rs2fp_opnd, - [RISCV64_FLD_RS3] = decode_rs3_opnd, + [RISCV64_FLD_RS3FP] = decode_rs3fp_opnd, [RISCV64_FLD_FM] = decode_fm_opnd, [RISCV64_FLD_PRED] = decode_pred_opnd, [RISCV64_FLD_SUCC] = decode_succ_opnd, @@ -1538,7 +1538,7 @@ encode_rs2fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) * Applies to the R4 uncompressed format. */ static bool -encode_rs3_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) +encode_rs3fp_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) { opnd_t opnd = instr_get_src(instr, idx); uint32_t rd = opnd_get_reg(opnd) - DR_REG_F0; @@ -2310,7 +2310,7 @@ opnd_enc_func_t opnd_encoders[] = { [RISCV64_FLD_BASE] = encode_base_opnd, [RISCV64_FLD_RS2] = encode_rs2_opnd, [RISCV64_FLD_RS2FP] = encode_rs2fp_opnd, - [RISCV64_FLD_RS3] = encode_rs3_opnd, + [RISCV64_FLD_RS3FP] = encode_rs3fp_opnd, [RISCV64_FLD_FM] = encode_fm_opnd, [RISCV64_FLD_PRED] = encode_pred_opnd, [RISCV64_FLD_SUCC] = encode_succ_opnd, diff --git a/core/ir/riscv64/codec.h b/core/ir/riscv64/codec.h index 148ad6a2678..d4532f36125 100644 --- a/core/ir/riscv64/codec.h +++ b/core/ir/riscv64/codec.h @@ -194,7 +194,7 @@ typedef enum { RISCV64_FLD_BASE, RISCV64_FLD_RS2, RISCV64_FLD_RS2FP, - RISCV64_FLD_RS3, + RISCV64_FLD_RS3FP, RISCV64_FLD_FM, RISCV64_FLD_PRED, RISCV64_FLD_SUCC, diff --git a/core/ir/riscv64/codec.py b/core/ir/riscv64/codec.py index 8c155c4b550..f8c1e77df13 100755 --- a/core/ir/riscv64/codec.py +++ b/core/ir/riscv64/codec.py @@ -171,7 +171,7 @@ def __new__(cls, value: int, arg_name: str, is_dest: bool, '', 'The second input floating-point register (inst[24:20]).' ) - RS3 = (8, + RS3FP = (8, 'rs3', False, 'OPSZ_PTR', diff --git a/core/ir/riscv64/isl/rv32d.txt b/core/ir/riscv64/isl/rv32d.txt index 2324cd419e0..37279c833b8 100644 --- a/core/ir/riscv64/isl/rv32d.txt +++ b/core/ir/riscv64/isl/rv32d.txt @@ -1,29 +1,29 @@ # "D" Standard Extension for Double-Precision Floating-Point. # Version 2.2 -fld | i | i_imm rs1 rd(fp) | .................011.....0000111 -fsd | s | s_imm rs2(fp) rs1 | .................011.....0100111 -fmadd.d | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....01..................1000011 -fmsub.d | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....01..................1000111 -fnmsub.d | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....01..................1001011 -fnmadd.d | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....01..................1001111 -fadd.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0000001..................1010011 -fsub.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0000101..................1010011 -fmul.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0001001..................1010011 -fdiv.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0001101..................1010011 -fsqrt.d | r | rs1(fp) rm rd(fp) | 010110100000.............1010011 -fsgnj.d | r | rs2(fp) rs1(fp) rd(fp) | 0010001..........000.....1010011 -fsgnjn.d | r | rs2(fp) rs1(fp) rd(fp) | 0010001..........001.....1010011 -fsgnjx.d | r | rs2(fp) rs1(fp) rd(fp) | 0010001..........010.....1010011 -fmin.d | r | rs2(fp) rs1(fp) rd(fp) | 0010101..........000.....1010011 -fmax.d | r | rs2(fp) rs1(fp) rd(fp) | 0010101..........001.....1010011 -fcvt.s.d | r | rs1(fp) rm rd(fp) | 010000000001.............1010011 -fcvt.d.s | r | rs1(fp) rm rd(fp) | 010000100000.............1010011 -feq.d | r | rs2(fp) rs1(fp) rd | 1010001..........010.....1010011 -flt.d | r | rs2(fp) rs1(fp) rd | 1010001..........001.....1010011 -fle.d | r | rs2(fp) rs1(fp) rd | 1010001..........000.....1010011 -fclass.d | r | rs1(fp) rd | 111000100000.....001.....1010011 -fcvt.w.d | r | rs1(fp) rm rd | 110000100000.............1010011 -fcvt.wu.d | r | rs1(fp) rm rd | 110000100001.............1010011 -fcvt.d.w | r | rs1 rm rd(fp) | 110100100000.............1010011 -fcvt.d.wu | r | rs1 rm rd(fp) | 110100100001.............1010011 +fld | i | i_imm rs1 rd(fp) | .................011.....0000111 +fsd | s | s_imm rs2(fp) rs1 | .................011.....0100111 +fmadd.d | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....01..................1000011 +fmsub.d | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....01..................1000111 +fnmsub.d | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....01..................1001011 +fnmadd.d | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....01..................1001111 +fadd.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0000001..................1010011 +fsub.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0000101..................1010011 +fmul.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0001001..................1010011 +fdiv.d | r | rs2(fp) rs1(fp) rm rd(fp) | 0001101..................1010011 +fsqrt.d | r | rs1(fp) rm rd(fp) | 010110100000.............1010011 +fsgnj.d | r | rs2(fp) rs1(fp) rd(fp) | 0010001..........000.....1010011 +fsgnjn.d | r | rs2(fp) rs1(fp) rd(fp) | 0010001..........001.....1010011 +fsgnjx.d | r | rs2(fp) rs1(fp) rd(fp) | 0010001..........010.....1010011 +fmin.d | r | rs2(fp) rs1(fp) rd(fp) | 0010101..........000.....1010011 +fmax.d | r | rs2(fp) rs1(fp) rd(fp) | 0010101..........001.....1010011 +fcvt.s.d | r | rs1(fp) rm rd(fp) | 010000000001.............1010011 +fcvt.d.s | r | rs1(fp) rm rd(fp) | 010000100000.............1010011 +feq.d | r | rs2(fp) rs1(fp) rd | 1010001..........010.....1010011 +flt.d | r | rs2(fp) rs1(fp) rd | 1010001..........001.....1010011 +fle.d | r | rs2(fp) rs1(fp) rd | 1010001..........000.....1010011 +fclass.d | r | rs1(fp) rd | 111000100000.....001.....1010011 +fcvt.w.d | r | rs1(fp) rm rd | 110000100000.............1010011 +fcvt.wu.d | r | rs1(fp) rm rd | 110000100001.............1010011 +fcvt.d.w | r | rs1 rm rd(fp) | 110100100000.............1010011 +fcvt.d.wu | r | rs1 rm rd(fp) | 110100100001.............1010011 diff --git a/core/ir/riscv64/isl/rv32f.txt b/core/ir/riscv64/isl/rv32f.txt index b2303e1c072..3358a53f303 100644 --- a/core/ir/riscv64/isl/rv32f.txt +++ b/core/ir/riscv64/isl/rv32f.txt @@ -1,29 +1,29 @@ # "F" Standard Extension for Single-Precision Floating-Point. # Version 2.2 -flw | i | i_imm rs1 rd(fp) | .................010.....0000111 -fsw | s | s_imm rs2(fp) rs1 | .................010.....0100111 -fmadd.s | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....00..................1000011 -fmsub.s | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....00..................1000111 -fnmsub.s | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....00..................1001011 -fnmadd.s | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....00..................1001111 -fadd.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0000000..................1010011 -fsub.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0000100..................1010011 -fmul.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0001000..................1010011 -fdiv.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0001100..................1010011 -fsqrt.s | r | rs1(fp) rm rd(fp) | 010110000000.............1010011 -fsgnj.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........000.....1010011 -fsgnjn.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........001.....1010011 -fsgnjx.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........010.....1010011 -fmin.s | r | rs2(fp) rs1(fp) rd(fp) | 0010100..........000.....1010011 -fmax.s | r | rs2(fp) rs1(fp) rd(fp) | 0010100..........001.....1010011 -fcvt.w.s | r | rs1(fp) rm rd | 110000000000.............1010011 -fcvt.wu.s | r | rs1(fp) rm rd | 110000000001.............1010011 -fmv.x.w | r | rs1(fp) rd | 111000000000.....000.....1010011 -feq.s | r | rs2(fp) rs1(fp) rd | 1010000..........010.....1010011 -flt.s | r | rs2(fp) rs1(fp) rd | 1010000..........001.....1010011 -fle.s | r | rs2(fp) rs1(fp) rd | 1010000..........000.....1010011 -fclass.s | r | rs1(fp) rd | 111000000000.....001.....1010011 -fcvt.s.w | r | rs1 rm rd(fp) | 110100000000.............1010011 -fcvt.s.wu | r | rs1 rm rd(fp) | 110100000001.............1010011 -fmv.w.x | r | rs1 rd(fp) | 111100000000.....000.....1010011 +flw | i | i_imm rs1 rd(fp) | .................010.....0000111 +fsw | s | s_imm rs2(fp) rs1 | .................010.....0100111 +fmadd.s | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....00..................1000011 +fmsub.s | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....00..................1000111 +fnmsub.s | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....00..................1001011 +fnmadd.s | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....00..................1001111 +fadd.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0000000..................1010011 +fsub.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0000100..................1010011 +fmul.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0001000..................1010011 +fdiv.s | r | rs2(fp) rs1(fp) rm rd(fp) | 0001100..................1010011 +fsqrt.s | r | rs1(fp) rm rd(fp) | 010110000000.............1010011 +fsgnj.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........000.....1010011 +fsgnjn.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........001.....1010011 +fsgnjx.s | r | rs2(fp) rs1(fp) rd(fp) | 0010000..........010.....1010011 +fmin.s | r | rs2(fp) rs1(fp) rd(fp) | 0010100..........000.....1010011 +fmax.s | r | rs2(fp) rs1(fp) rd(fp) | 0010100..........001.....1010011 +fcvt.w.s | r | rs1(fp) rm rd | 110000000000.............1010011 +fcvt.wu.s | r | rs1(fp) rm rd | 110000000001.............1010011 +fmv.x.w | r | rs1(fp) rd | 111000000000.....000.....1010011 +feq.s | r | rs2(fp) rs1(fp) rd | 1010000..........010.....1010011 +flt.s | r | rs2(fp) rs1(fp) rd | 1010000..........001.....1010011 +fle.s | r | rs2(fp) rs1(fp) rd | 1010000..........000.....1010011 +fclass.s | r | rs1(fp) rd | 111000000000.....001.....1010011 +fcvt.s.w | r | rs1 rm rd(fp) | 110100000000.............1010011 +fcvt.s.wu | r | rs1 rm rd(fp) | 110100000001.............1010011 +fmv.w.x | r | rs1 rd(fp) | 111100000000.....000.....1010011 diff --git a/core/ir/riscv64/isl/rv32q.txt b/core/ir/riscv64/isl/rv32q.txt index e822eb5eeed..cb483b68c22 100644 --- a/core/ir/riscv64/isl/rv32q.txt +++ b/core/ir/riscv64/isl/rv32q.txt @@ -1,31 +1,31 @@ # "Q" Standard Extension for Quad-Precision Floating-Point. # Version 2.2 -flq | i | i_imm rs1 rd(fp) | .................100.....0000111 -fsq | s | s_imm rs2(fp) rs1 | .................100.....0100111 -fmadd.q | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....11..................1000011 -fmsub.q | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....11..................1000111 -fnmsub.q | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....11..................1001011 -fnmadd.q | r4 | rs3 rs2(fp) rs1(fp) rm rd(fp) | .....11..................1001111 -fadd.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0000011..................1010011 -fsub.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0000111..................1010011 -fmul.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0001011..................1010011 -fdiv.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0001111..................1010011 -fsqrt.q | r | rs1(fp) rm rd(fp) | 010111100000.............1010011 -fsgnj.q | r | rs2(fp) rs1(fp) rd(fp) | 0010011..........000.....1010011 -fsgnjn.q | r | rs2(fp) rs1(fp) rd(fp) | 0010011..........001.....1010011 -fsgnjx.q | r | rs2(fp) rs1(fp) rd(fp) | 0010011..........010.....1010011 -fmin.q | r | rs2(fp) rs1(fp) rd(fp) | 0010111..........000.....1010011 -fmax.q | r | rs2(fp) rs1(fp) rd(fp) | 0010111..........001.....1010011 -fcvt.s.q | r | rs1(fp) rm rd(fp) | 010000000011.............1010011 -fcvt.q.s | r | rs1(fp) rm rd(fp) | 010001100000.............1010011 -fcvt.d.q | r | rs1(fp) rm rd(fp) | 010000100011.............1010011 -fcvt.q.d | r | rs1(fp) rm rd(fp) | 010001100001.............1010011 -feq.q | r | rs2(fp) rs1(fp) rd | 1010011..........010.....1010011 -flt.q | r | rs2(fp) rs1(fp) rd | 1010011..........001.....1010011 -fle.q | r | rs2(fp) rs1(fp) rd | 1010011..........000.....1010011 -fclass.q | r | rs1(fp) rd | 111001100000.....001.....1010011 -fcvt.w.q | r | rs1(fp) rm rd | 110001100000.............1010011 -fcvt.wu.q | r | rs1(fp) rm rd | 110001100001.............1010011 -fcvt.q.w | r | rs1 rm rd(fp) | 110101100000.............1010011 -fcvt.q.wu | r | rs1 rm rd(fp) | 110101100001.............1010011 +flq | i | i_imm rs1 rd(fp) | .................100.....0000111 +fsq | s | s_imm rs2(fp) rs1 | .................100.....0100111 +fmadd.q | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....11..................1000011 +fmsub.q | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....11..................1000111 +fnmsub.q | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....11..................1001011 +fnmadd.q | r4 | rs3(fp) rs2(fp) rs1(fp) rm rd(fp) | .....11..................1001111 +fadd.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0000011..................1010011 +fsub.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0000111..................1010011 +fmul.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0001011..................1010011 +fdiv.q | r | rs2(fp) rs1(fp) rm rd(fp) | 0001111..................1010011 +fsqrt.q | r | rs1(fp) rm rd(fp) | 010111100000.............1010011 +fsgnj.q | r | rs2(fp) rs1(fp) rd(fp) | 0010011..........000.....1010011 +fsgnjn.q | r | rs2(fp) rs1(fp) rd(fp) | 0010011..........001.....1010011 +fsgnjx.q | r | rs2(fp) rs1(fp) rd(fp) | 0010011..........010.....1010011 +fmin.q | r | rs2(fp) rs1(fp) rd(fp) | 0010111..........000.....1010011 +fmax.q | r | rs2(fp) rs1(fp) rd(fp) | 0010111..........001.....1010011 +fcvt.s.q | r | rs1(fp) rm rd(fp) | 010000000011.............1010011 +fcvt.q.s | r | rs1(fp) rm rd(fp) | 010001100000.............1010011 +fcvt.d.q | r | rs1(fp) rm rd(fp) | 010000100011.............1010011 +fcvt.q.d | r | rs1(fp) rm rd(fp) | 010001100001.............1010011 +feq.q | r | rs2(fp) rs1(fp) rd | 1010011..........010.....1010011 +flt.q | r | rs2(fp) rs1(fp) rd | 1010011..........001.....1010011 +fle.q | r | rs2(fp) rs1(fp) rd | 1010011..........000.....1010011 +fclass.q | r | rs1(fp) rd | 111001100000.....001.....1010011 +fcvt.w.q | r | rs1(fp) rm rd | 110001100000.............1010011 +fcvt.wu.q | r | rs1(fp) rm rd | 110001100001.............1010011 +fcvt.q.w | r | rs1 rm rd(fp) | 110101100000.............1010011 +fcvt.q.wu | r | rs1 rm rd(fp) | 110101100001.............1010011 diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index d0b115ad42e..c2daea8192d 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -491,6 +491,211 @@ test_fmv(void *dc) test_instr_encoding(dc, OP_fmv_w_x, instr); } +static void +test_float_arith(void *dc) +{ + instr_t *instr; + + instr = INSTR_CREATE_fmadd_d(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F2), + opnd_create_reg(DR_REG_F3)); + test_instr_encoding(dc, OP_fmadd_d, instr); + instr = INSTR_CREATE_fmsub_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b001, OPSZ_3b), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F3)); + test_instr_encoding(dc, OP_fmsub_d, instr); + instr = INSTR_CREATE_fnmadd_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b010, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fnmadd_d, instr); + instr = INSTR_CREATE_fnmsub_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b011, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fnmsub_d, instr); + + instr = INSTR_CREATE_fmadd_q(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F2), + opnd_create_reg(DR_REG_F3)); + test_instr_encoding(dc, OP_fmadd_q, instr); + instr = INSTR_CREATE_fmsub_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b001, OPSZ_3b), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F3)); + test_instr_encoding(dc, OP_fmsub_q, instr); + instr = INSTR_CREATE_fnmadd_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b010, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fnmadd_q, instr); + instr = INSTR_CREATE_fnmsub_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b011, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fnmsub_q, instr); + + instr = INSTR_CREATE_fmadd_s(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F2), + opnd_create_reg(DR_REG_F3)); + test_instr_encoding(dc, OP_fmadd_s, instr); + instr = INSTR_CREATE_fmsub_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b001, OPSZ_3b), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F3)); + test_instr_encoding(dc, OP_fmsub_s, instr); + instr = INSTR_CREATE_fnmadd_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b010, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fnmadd_s, instr); + instr = INSTR_CREATE_fnmsub_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b011, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fnmsub_s, instr); + + instr = INSTR_CREATE_fadd_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b100, OPSZ_3b), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fadd_d, instr); + instr = INSTR_CREATE_fsub_d(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b111, OPSZ_3b), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsub_d, instr); + instr = INSTR_CREATE_fmul_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fmul_d, instr); + instr = INSTR_CREATE_fdiv_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fdiv_d, instr); + + instr = INSTR_CREATE_fadd_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b100, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fadd_q, instr); + instr = INSTR_CREATE_fsub_q(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b111, OPSZ_3b), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsub_q, instr); + instr = INSTR_CREATE_fmul_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fmul_q, instr); + instr = INSTR_CREATE_fdiv_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fdiv_q, instr); + + instr = INSTR_CREATE_fadd_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b100, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fadd_s, instr); + instr = INSTR_CREATE_fsub_s(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b111, OPSZ_3b), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsub_s, instr); + instr = INSTR_CREATE_fmul_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fmul_s, instr); + instr = INSTR_CREATE_fdiv_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fdiv_s, instr); + + instr = INSTR_CREATE_fsqrt_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsqrt_d, instr); + instr = INSTR_CREATE_fsqrt_q(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsqrt_q, instr); + instr = INSTR_CREATE_fsqrt_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fsqrt_s, instr); + + instr = INSTR_CREATE_fsqrt_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsqrt_d, instr); + instr = INSTR_CREATE_fsqrt_q(dc, opnd_create_reg(DR_REG_F31), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsqrt_q, instr); + instr = INSTR_CREATE_fsqrt_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_immed_int(0b000, OPSZ_3b), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fsqrt_s, instr); + + instr = INSTR_CREATE_fsgnj_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsgnj_d, instr); + instr = INSTR_CREATE_fsgnjn_d(dc, opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsgnjn_d, instr); + instr = INSTR_CREATE_fsgnjx_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fsgnjx_d, instr); + + instr = INSTR_CREATE_fsgnj_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsgnj_q, instr); + instr = INSTR_CREATE_fsgnjn_q(dc, opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsgnjn_q, instr); + instr = INSTR_CREATE_fsgnjx_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fsgnjx_q, instr); + + instr = INSTR_CREATE_fsgnj_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsgnj_s, instr); + instr = INSTR_CREATE_fsgnjn_s(dc, opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fsgnjn_s, instr); + instr = INSTR_CREATE_fsgnjx_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fsgnjx_s, instr); + + instr = INSTR_CREATE_fmax_d(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fmax_d, instr); + instr = INSTR_CREATE_fmin_d(dc, opnd_create_reg(DR_REG_F31), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_fmin_d, instr); + instr = INSTR_CREATE_fmax_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fmax_q, instr); + instr = INSTR_CREATE_fmin_q(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fmin_q, instr); + instr = INSTR_CREATE_fmax_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fmax_s, instr); + instr = INSTR_CREATE_fmin_s(dc, opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F2)); + test_instr_encoding(dc, OP_fmin_s, instr); + + instr = + INSTR_CREATE_fclass_d(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fclass_d, instr); + instr = + INSTR_CREATE_fclass_q(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fclass_q, instr); + instr = + INSTR_CREATE_fclass_s(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_fclass_s, instr); +} + int main(int argc, char *argv[]) { @@ -515,6 +720,9 @@ main(int argc, char *argv[]) test_fmv(dcontext); print("test_fmv complete\n"); + test_float_arith(dcontext); + print("test_float_arith complete\n"); + print("All tests complete\n"); return 0; } diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index 9dbb925278b..65ddef9bb9c 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -51,11 +51,11 @@ amomaxu.w %a1 %a2 0x1 -> %a0 amomaxu.d %a1 %a2 0x1 -> %a0 test_atomic complete fcvt.l.s 0x0 %ft0 -> %a0 -fcvt.lu.s 0x0 %ft0 -> %a0 -fcvt.s.l 0x0 %a0 -> %ft0 -fcvt.s.lu 0x0 %a0 -> %ft0 -fcvt.l.d 0x0 %ft0 -> %a0 -fcvt.lu.d 0x0 %ft0 -> %a0 +fcvt.lu.s 0x1 %ft0 -> %a0 +fcvt.s.l 0x2 %a0 -> %ft0 +fcvt.s.lu 0x3 %a0 -> %ft0 +fcvt.l.d 0x4 %ft0 -> %a0 +fcvt.lu.d 0x7 %ft0 -> %a0 fcvt.d.l 0x0 %a0 -> %ft0 fcvt.d.lu 0x0 %a0 -> %ft0 fcvt.d.s 0x0 %ft0 -> %ft0 @@ -81,4 +81,58 @@ fcvt.lu.q 0x0 %ft0 -> %a0 fcvt.q.l 0x0 %a0 -> %ft0 fcvt.q.lu 0x0 %a0 -> %ft0 test_fcvt complete +fmv.x.d %ft0 -> %a0 +fmv.d.x %zero -> %ft11 +fmv.x.w %ft11 -> %zero +fmv.w.x %a0 -> %ft0 +test_fmv complete +fmadd.d 0x0 %ft0 %ft2 %ft3 -> %ft11 +fmsub.d 0x1 %ft11 %ft0 %ft3 -> %ft0 +fnmadd.d 0x2 %ft1 %ft11 %ft0 -> %ft0 +fnmsub.d 0x3 %ft1 %ft2 %ft11 -> %ft0 +fmadd.q 0x0 %ft0 %ft2 %ft3 -> %ft11 +fmsub.q 0x1 %ft11 %ft0 %ft3 -> %ft0 +fnmadd.q 0x2 %ft1 %ft11 %ft0 -> %ft0 +fnmsub.q 0x3 %ft1 %ft2 %ft11 -> %ft0 +fmadd.s 0x0 %ft0 %ft2 %ft3 -> %ft11 +fmsub.s 0x1 %ft11 %ft0 %ft3 -> %ft0 +fnmadd.s 0x2 %ft1 %ft11 %ft0 -> %ft0 +fnmsub.s 0x3 %ft1 %ft2 %ft11 -> %ft0 +fadd.d 0x4 %ft11 %ft2 -> %ft0 +fsub.d 0x7 %ft0 %ft0 -> %ft11 +fmul.d 0x0 %ft1 %ft11 -> %ft0 +fdiv.d 0x0 %ft1 %ft2 -> %ft0 +fadd.q 0x4 %ft1 %ft2 -> %ft0 +fsub.q 0x7 %ft11 %ft0 -> %ft11 +fmul.q 0x0 %ft0 %ft11 -> %ft0 +fdiv.q 0x0 %ft1 %ft2 -> %ft0 +fadd.s 0x4 %ft1 %ft2 -> %ft0 +fsub.s 0x7 %ft11 %ft0 -> %ft11 +fmul.s 0x0 %ft0 %ft11 -> %ft0 +fdiv.s 0x0 %ft1 %ft2 -> %ft0 +fsqrt.d 0x0 %ft11 -> %ft0 +fsqrt.q 0x0 %ft0 -> %ft11 +fsqrt.s 0x0 %ft1 -> %ft0 +fsqrt.d 0x0 %ft11 -> %ft0 +fsqrt.q 0x0 %ft0 -> %ft11 +fsqrt.s 0x0 %ft1 -> %ft0 +fsgnj.d %ft0 %ft11 -> %ft0 +fsgnjn.d %ft0 %ft0 -> %ft11 +fsgnjx.d %ft0 %ft1 -> %ft0 +fsgnj.q %ft0 %ft11 -> %ft0 +fsgnjn.q %ft0 %ft0 -> %ft11 +fsgnjx.q %ft0 %ft1 -> %ft0 +fsgnj.s %ft0 %ft11 -> %ft0 +fsgnjn.s %ft0 %ft0 -> %ft11 +fsgnjx.s %ft0 %ft1 -> %ft0 +fmax.d %ft11 %ft2 -> %ft0 +fmin.d %ft1 %ft0 -> %ft11 +fmax.q %ft0 %ft11 -> %ft0 +fmin.q %ft1 %ft2 -> %ft0 +fmax.s %ft1 %ft2 -> %ft0 +fmin.s %ft1 %ft2 -> %ft0 +fclass.d %ft1 -> %a0 +fclass.q %ft1 -> %a0 +fclass.s %ft1 -> %a0 +test_float_arith complete All tests complete From f8f264d69c364f0dc5c0fc294ff410f09b6f60eb Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sat, 17 Jun 2023 15:54:20 +0000 Subject: [PATCH 23/34] Added more tests --- core/ir/riscv64/codec.c | 4 +- core/ir/riscv64/codec.py | 6 +- core/ir/riscv64/instr.c | 22 +- core/ir/riscv64/isl/rv32i.txt | 76 ++-- core/ir/riscv64/isl/rvc.txt | 4 +- suite/tests/api/ir_riscv64.c | 604 +++++++++++++++++++++++++++++- suite/tests/api/ir_riscv64.expect | 178 +++++++++ 7 files changed, 832 insertions(+), 62 deletions(-) diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index 104e1b1b9c6..de0e2720628 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -695,7 +695,7 @@ decode_csr_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or int idx, instr_t *out) { int32_t imm = GET_FIELD(inst, 19, 15); - opnd_t opnd = opnd_create_immed_int(imm, op_sz); + opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); instr_set_src(out, idx, opnd); return true; } @@ -1731,7 +1731,7 @@ encode_b_imm_opnd(instr_t *instr, byte *pc, int idx, uint32_t *out) else return false; - *out |= SET_FIELD(imm >> 11, 7, 7) | SET_FIELD(imm, 11, 8) | + *out |= SET_FIELD(imm >> 11, 7, 7) | SET_FIELD(imm >> 1, 11, 8) | SET_FIELD(imm >> 5, 30, 25) | SET_FIELD(imm >> 12, 31, 31); return true; } diff --git a/core/ir/riscv64/codec.py b/core/ir/riscv64/codec.py index f8c1e77df13..66291ca198e 100755 --- a/core/ir/riscv64/codec.py +++ b/core/ir/riscv64/codec.py @@ -473,7 +473,8 @@ def __new__(cls, value: int, arg_name: str, is_dest: bool, '': 'OPSZ_0', 'lb': 'OPSZ_1', 'lh': 'OPSZ_2', 'lw': 'OPSZ_4', 'ld': 'OPSZ_8', 'lbu': 'OPSZ_1', 'lhu': 'OPSZ_2', 'lwu': 'OPSZ_4', 'sb': 'OPSZ_1', 'sh': 'OPSZ_2', 'sw': 'OPSZ_4', 'sd': 'OPSZ_8', - 'flw': 'OPSZ_4', 'fld': 'OPSZ_8', 'fsw': 'OPSZ_4', 'fsd': 'OPSZ_8' + 'flw': 'OPSZ_4', 'fld': 'OPSZ_8', 'fsw': 'OPSZ_4', 'fsd': 'OPSZ_8', + 'flq': 'OPSZ_16', 'fsq': 'OPSZ_16' }, 'im(rs1)', 'The register-relative memory source location (reg+imm).' @@ -485,7 +486,8 @@ def __new__(cls, value: int, arg_name: str, is_dest: bool, '': 'OPSZ_0', 'lb': 'OPSZ_1', 'lh': 'OPSZ_2', 'lw': 'OPSZ_4', 'ld': 'OPSZ_8', 'lbu': 'OPSZ_1', 'lhu': 'OPSZ_2', 'lwu': 'OPSZ_4', 'sb': 'OPSZ_1', 'sh': 'OPSZ_2', 'sw': 'OPSZ_4', 'sd': 'OPSZ_8', - 'flw': 'OPSZ_4', 'fld': 'OPSZ_8', 'fsw': 'OPSZ_4', 'fsd': 'OPSZ_8' + 'flw': 'OPSZ_4', 'fld': 'OPSZ_8', 'fsw': 'OPSZ_4', 'fsd': 'OPSZ_8', + 'flq': 'OPSZ_16', 'fsq': 'OPSZ_16' }, 'im(rs1)', 'The register-relative memory target location (reg+imm).' diff --git a/core/ir/riscv64/instr.c b/core/ir/riscv64/instr.c index c11f56c0571..bb80153e255 100644 --- a/core/ir/riscv64/instr.c +++ b/core/ir/riscv64/instr.c @@ -101,9 +101,9 @@ instr_is_mov(instr_t *instr) bool instr_is_call_arch(instr_t *instr) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); - return false; + int opc = instr_get_opcode(instr); + return (opc == OP_jal || opc == OP_jalr || opc == OP_c_j || opc == OP_c_jal || + opc == OP_c_jr || opc == OP_c_jalr); } bool @@ -149,15 +149,19 @@ instr_is_cbr_arch(instr_t *instr) { int opc = instr_get_opcode(instr); return opc == OP_beq || opc == OP_bne || opc == OP_blt || opc == OP_bltu || - opc == OP_bge || opc == OP_bgeu; + opc == OP_bge || opc == OP_bgeu || opc == OP_c_beqz || opc == OP_c_bnez; } bool instr_is_mbr_arch(instr_t *instr) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); - return false; + int opc = instr->opcode; /* caller ensures opcode is valid */ + switch (opc) { + case OP_jalr: + case OP_c_jalr: + case OP_c_jr: return true; + default: return false; + } } bool @@ -192,16 +196,12 @@ instr_is_cti_short(instr_t *instr) bool instr_is_cti_loop(instr_t *instr) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } bool instr_is_cti_short_rewrite(instr_t *instr, byte *pc) { - /* FIXME i#3544: Not implemented */ - ASSERT_NOT_IMPLEMENTED(false); return false; } diff --git a/core/ir/riscv64/isl/rv32i.txt b/core/ir/riscv64/isl/rv32i.txt index 58ebe3abf84..9f7f2d652ab 100644 --- a/core/ir/riscv64/isl/rv32i.txt +++ b/core/ir/riscv64/isl/rv32i.txt @@ -1,41 +1,41 @@ # RV32I Base Integer Instruction Set. # Version 2.1 -lui | u | u_imm rd | .........................0110111 -auipc | u | u_imm rd | .........................0010111 -jal | j | j_imm rd | .........................1101111 -jalr | i | i_imm rs1 rd | .................000.....1100111 -beq | b | b_imm rs2 rs1 | .................000.....1100011 -bne | b | b_imm rs2 rs1 | .................001.....1100011 -blt | b | b_imm rs2 rs1 | .................100.....1100011 -bge | b | b_imm rs2 rs1 | .................101.....1100011 -bltu | b | b_imm rs2 rs1 | .................110.....1100011 -bgeu | b | b_imm rs2 rs1 | .................111.....1100011 -lb | i | i_imm rs1 rd | .................000.....0000011 -lh | i | i_imm rs1 rd | .................001.....0000011 -lw | i | i_imm rs1 rd | .................010.....0000011 -lbu | i | i_imm rs1 rd | .................100.....0000011 -lhu | i | i_imm rs1 rd | .................101.....0000011 -sb | s | s_imm rs2 rs1 | .................000.....0100011 -sh | s | s_imm rs2 rs1 | .................001.....0100011 -sw | s | s_imm rs2 rs1 | .................010.....0100011 -addi | i | i_imm rs1 rd | .................000.....0010011 -slti | i | i_imm rs1 rd | .................010.....0010011 -sltiu | i | i_imm rs1 rd | .................011.....0010011 -xori | i | i_imm rs1 rd | .................100.....0010011 -ori | i | i_imm rs1 rd | .................110.....0010011 -andi | i | i_imm rs1 rd | .................111.....0010011 -slli | i | shamt rs1 rd | 000000...........001.....0010011 -srli | i | shamt rs1 rd | 000000...........101.....0010011 -srai | i | shamt rs1 rd | 010000...........101.....0010011 -add | r | rs2 rs1 rd | 0000000..........000.....0110011 -sub | r | rs2 rs1 rd | 0100000..........000.....0110011 -sll | r | rs2 rs1 rd | 0000000..........001.....0110011 -slt | r | rs2 rs1 rd | 0000000..........010.....0110011 -sltu | r | rs2 rs1 rd | 0000000..........011.....0110011 -xor | r | rs2 rs1 rd | 0000000..........100.....0110011 -srl | r | rs2 rs1 rd | 0000000..........101.....0110011 -sra | r | rs2 rs1 rd | 0100000..........101.....0110011 -or | r | rs2 rs1 rd | 0000000..........110.....0110011 -and | r | rs2 rs1 rd | 0000000..........111.....0110011 -fence | i | fm pred succ rs1 rd | .................000.....0001111 +lui | u | u_imm rd | .........................0110111 +auipc | u | u_imm rd | .........................0010111 +jal | j | j_imm rd | .........................1101111 +jalr | i | i_imm rs1 rd | .................000.....1100111 +beq | b | b_imm rs2 rs1 | .................000.....1100011 +bne | b | b_imm rs2 rs1 | .................001.....1100011 +blt | b | b_imm rs2 rs1 | .................100.....1100011 +bge | b | b_imm rs2 rs1 | .................101.....1100011 +bltu | b | b_imm rs2 rs1 | .................110.....1100011 +bgeu | b | b_imm rs2 rs1 | .................111.....1100011 +lb | i | i_imm rs1 rd | .................000.....0000011 +lh | i | i_imm rs1 rd | .................001.....0000011 +lw | i | i_imm rs1 rd | .................010.....0000011 +lbu | i | i_imm rs1 rd | .................100.....0000011 +lhu | i | i_imm rs1 rd | .................101.....0000011 +sb | s | s_imm rs2 rs1 | .................000.....0100011 +sh | s | s_imm rs2 rs1 | .................001.....0100011 +sw | s | s_imm rs2 rs1 | .................010.....0100011 +addi | i | i_imm rs1 rd | .................000.....0010011 +slti | i | i_imm rs1 rd | .................010.....0010011 +sltiu | i | i_imm rs1 rd | .................011.....0010011 +xori | i | i_imm rs1 rd | .................100.....0010011 +ori | i | i_imm rs1 rd | .................110.....0010011 +andi | i | i_imm rs1 rd | .................111.....0010011 +slli | i | shamt rs1 rd | 000000...........001.....0010011 +srli | i | shamt rs1 rd | 000000...........101.....0010011 +srai | i | shamt rs1 rd | 010000...........101.....0010011 +add | r | rs2 rs1 rd | 0000000..........000.....0110011 +sub | r | rs2 rs1 rd | 0100000..........000.....0110011 +sll | r | rs2 rs1 rd | 0000000..........001.....0110011 +slt | r | rs2 rs1 rd | 0000000..........010.....0110011 +sltu | r | rs2 rs1 rd | 0000000..........011.....0110011 +xor | r | rs2 rs1 rd | 0000000..........100.....0110011 +srl | r | rs2 rs1 rd | 0000000..........101.....0110011 +sra | r | rs2 rs1 rd | 0100000..........101.....0110011 +or | r | rs2 rs1 rd | 0000000..........110.....0110011 +and | r | rs2 rs1 rd | 0000000..........111.....0110011 +fence | i | fm pred succ | ............00000000000000001111 diff --git a/core/ir/riscv64/isl/rvc.txt b/core/ir/riscv64/isl/rvc.txt index 0b38d98a0ac..4a3f4a7b428 100644 --- a/core/ir/riscv64/isl/rvc.txt +++ b/core/ir/riscv64/isl/rvc.txt @@ -10,8 +10,8 @@ c.fld | cl | cld_imm crs1_ crd_(fp) | 001...........00 c.sw | cs | csw_imm crs1_ crs2_ | 110...........00 c.fsd | cs | csd_imm crs1_ crs2_(fp) | 101...........00 c.j | cj | cj_imm | 101...........01 -c.jr | cr | crs1 crs2 | 1000.....0000010 -c.jalr | cr | crs1 crs2 | 1001.....0000010 +c.jr | cr | crs1 | 1000.....0000010 +c.jalr | cr | crs1 | 1001.....0000010 c.beqz | cb | cb_imm crs1_ | 110...........01 c.bnez | cb | cb_imm crs1_ | 111...........01 c.li | ci | cimm5 crd | 010...........01 diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index c2daea8192d..187ca44c7ca 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -62,7 +62,7 @@ static byte buf[8192]; : 0)) #endif -static void +static byte * test_instr_encoding(void *dc, uint opcode, instr_t *instr) { instr_t *decin; @@ -84,6 +84,7 @@ test_instr_encoding(void *dc, uint opcode, instr_t *instr) instr_destroy(dc, instr); instr_destroy(dc, decin); + return pc; } static void @@ -187,7 +188,6 @@ test_float_load_store(void *dc) { instr_t *instr; - /* Load */ instr = INSTR_CREATE_flw( dc, opnd_create_reg(DR_REG_F0), opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_4)); @@ -196,8 +196,10 @@ test_float_load_store(void *dc) dc, opnd_create_reg(DR_REG_F31), opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_8)); test_instr_encoding(dc, OP_fld, instr); - - /* Store */ + instr = INSTR_CREATE_flq( + dc, opnd_create_reg(DR_REG_F31), + opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_16)); + test_instr_encoding(dc, OP_flq, instr); instr = INSTR_CREATE_fsw( dc, opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_4), @@ -208,8 +210,13 @@ test_float_load_store(void *dc) opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_8), opnd_create_reg(DR_REG_F31)); test_instr_encoding(dc, OP_fsd, instr); + instr = INSTR_CREATE_fsq( + dc, + opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_16), + opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_fsq, instr); - /* Compressed Load */ + /* Compressed */ instr = INSTR_CREATE_c_fldsp( dc, opnd_create_reg(DR_REG_F0), opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8)); @@ -220,8 +227,6 @@ test_float_load_store(void *dc) ((1 << 5) - 1) << 3, OPSZ_8)); test_instr_encoding(dc, OP_c_fld, instr); /* There is no c.flw* instructions in RV64. */ - - /* Compressed Store */ instr = INSTR_CREATE_c_fsdsp( dc, opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), opnd_create_reg(DR_REG_F31)); @@ -337,6 +342,8 @@ test_fcvt(void *dc) { instr_t *instr; + /* FIXME i#3544: Use rounding mode string instead of hex number when disassembling. */ + instr = INSTR_CREATE_fcvt_l_s(dc, opnd_create_reg(DR_REG_A0), opnd_create_immed_int(0b000, OPSZ_3b), opnd_create_reg(DR_REG_F0)); @@ -496,6 +503,8 @@ test_float_arith(void *dc) { instr_t *instr; + /* FIXME i#3544: Use rounding mode string instead of hex number when disassembling. */ + instr = INSTR_CREATE_fmadd_d(dc, opnd_create_reg(DR_REG_F31), opnd_create_immed_int(0b000, OPSZ_3b), opnd_create_reg(DR_REG_F0), opnd_create_reg(DR_REG_F2), @@ -696,6 +705,563 @@ test_float_arith(void *dc) test_instr_encoding(dc, OP_fclass_s, instr); } +static void +test_float_compare(void *dc) +{ + instr_t *instr; + instr = INSTR_CREATE_feq_d(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F0), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_feq_d, instr); + instr = INSTR_CREATE_flt_d(dc, opnd_create_reg(DR_REG_X0), + opnd_create_reg(DR_REG_F31), opnd_create_reg(DR_REG_F31)); + test_instr_encoding(dc, OP_flt_d, instr); + instr = INSTR_CREATE_flt_d(dc, opnd_create_reg(DR_REG_X31), + opnd_create_reg(DR_REG_F1), opnd_create_reg(DR_REG_F0)); + test_instr_encoding(dc, OP_flt_d, instr); + + instr = INSTR_CREATE_feq_q(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_feq_q, instr); + instr = INSTR_CREATE_flt_q(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_flt_q, instr); + instr = INSTR_CREATE_flt_q(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_flt_q, instr); + + instr = INSTR_CREATE_feq_s(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_feq_s, instr); + instr = INSTR_CREATE_flt_s(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_flt_s, instr); + instr = INSTR_CREATE_flt_s(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_F1), + opnd_create_reg(DR_REG_F1)); + test_instr_encoding(dc, OP_flt_s, instr); +} + +static void +test_hypervisor(void *dc) +{ + instr_t *instr; + + instr = + INSTR_CREATE_hlv_b(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_b, instr); + instr = + INSTR_CREATE_hlv_bu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_bu, instr); + instr = + INSTR_CREATE_hlv_h(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_h, instr); + instr = + INSTR_CREATE_hlv_hu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_hu, instr); + instr = + INSTR_CREATE_hlvx_hu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlvx_hu, instr); + instr = + INSTR_CREATE_hlv_w(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_w, instr); + instr = + INSTR_CREATE_hlv_wu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_wu, instr); + instr = + INSTR_CREATE_hlvx_wu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlvx_wu, instr); + instr = + INSTR_CREATE_hlv_d(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hlv_d, instr); + instr = + INSTR_CREATE_hsv_b(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hsv_b, instr); + instr = + INSTR_CREATE_hsv_h(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hsv_h, instr); + instr = + INSTR_CREATE_hsv_w(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hsv_w, instr); + instr = + INSTR_CREATE_hsv_d(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hsv_d, instr); + instr = INSTR_CREATE_hinval_vvma(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hinval_vvma, instr); + instr = INSTR_CREATE_hinval_gvma(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hinval_gvma, instr); + instr = INSTR_CREATE_hfence_vvma(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hfence_vvma, instr); + instr = INSTR_CREATE_hfence_gvma(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_hfence_gvma, instr); +} + +static void +test_integer(void *dc) +{ + instr_t *instr; + instr = INSTR_CREATE_addi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal(0, OPSZ_12b)); + test_instr_encoding(dc, OP_addi, instr); + instr = INSTR_CREATE_addiw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal(0, OPSZ_12b)); + test_instr_encoding(dc, OP_addiw, instr); + instr = INSTR_CREATE_slti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal(-1, OPSZ_12b)); + test_instr_encoding(dc, OP_slti, instr); + instr = INSTR_CREATE_sltiu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + test_instr_encoding(dc, OP_sltiu, instr); + instr = INSTR_CREATE_xori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + test_instr_encoding(dc, OP_xori, instr); + instr = INSTR_CREATE_ori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + test_instr_encoding(dc, OP_ori, instr); + instr = INSTR_CREATE_andi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + test_instr_encoding(dc, OP_andi, instr); + instr = INSTR_CREATE_slli(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_slli, instr); + instr = INSTR_CREATE_slliw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + test_instr_encoding(dc, OP_slliw, instr); + instr = INSTR_CREATE_srli(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_srli, instr); + instr = INSTR_CREATE_srliw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + test_instr_encoding(dc, OP_srliw, instr); + instr = INSTR_CREATE_srai(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_srai, instr); + instr = INSTR_CREATE_sraiw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + test_instr_encoding(dc, OP_sraiw, instr); + + instr = INSTR_CREATE_add(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_add, instr); + instr = INSTR_CREATE_addw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_addw, instr); + instr = INSTR_CREATE_sub(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sub, instr); + instr = INSTR_CREATE_subw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_subw, instr); + instr = INSTR_CREATE_sll(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sll, instr); + instr = INSTR_CREATE_sllw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sllw, instr); + instr = INSTR_CREATE_slt(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_slt, instr); + instr = INSTR_CREATE_sltu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sltu, instr); + instr = INSTR_CREATE_xor(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_xor, instr); + instr = INSTR_CREATE_srl(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_srl, instr); + instr = INSTR_CREATE_srlw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_srlw, instr); + instr = INSTR_CREATE_sra(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sra, instr); + instr = INSTR_CREATE_sraw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sraw, instr); + instr = INSTR_CREATE_or(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_or, instr); + instr = INSTR_CREATE_and(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_and, instr); + + instr = INSTR_CREATE_mul(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_mul, instr); + instr = INSTR_CREATE_mulw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_mulw, instr); + instr = INSTR_CREATE_mulh(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_mulh, instr); + instr = INSTR_CREATE_mulhsu(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_mulhsu, instr); + instr = INSTR_CREATE_mulhu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_mulhu, instr); + instr = INSTR_CREATE_div(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_div, instr); + instr = INSTR_CREATE_divw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_divw, instr); + instr = INSTR_CREATE_divu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_divu, instr); + instr = INSTR_CREATE_divuw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_divuw, instr); + instr = INSTR_CREATE_rem(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_rem, instr); + instr = INSTR_CREATE_remw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_remw, instr); + instr = INSTR_CREATE_remu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_remu, instr); + instr = INSTR_CREATE_remuw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_remuw, instr); + + /* Compressed */ + instr = INSTR_CREATE_c_addiw(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + test_instr_encoding(dc, OP_c_addiw, instr); + instr = + INSTR_CREATE_c_addw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_c_addw, instr); + instr = + INSTR_CREATE_c_subw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_c_subw, instr); + + instr = INSTR_CREATE_c_slli(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_c_slli, instr); + instr = INSTR_CREATE_c_srli(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_c_srli, instr); + instr = INSTR_CREATE_c_srai(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_c_srai, instr); + instr = INSTR_CREATE_c_andi(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal(-1, OPSZ_6b)); + test_instr_encoding(dc, OP_c_andi, instr); + + instr = INSTR_CREATE_c_mv(dc, opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_c_mv, instr); + instr = + INSTR_CREATE_c_add(dc, opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_c_add, instr); + instr = + INSTR_CREATE_c_and(dc, opnd_create_reg(DR_REG_X8), opnd_create_reg(DR_REG_X15)); + test_instr_encoding(dc, OP_c_and, instr); + instr = + INSTR_CREATE_c_or(dc, opnd_create_reg(DR_REG_X8), opnd_create_reg(DR_REG_X15)); + test_instr_encoding(dc, OP_c_or, instr); + instr = + INSTR_CREATE_c_xor(dc, opnd_create_reg(DR_REG_X8), opnd_create_reg(DR_REG_X15)); + test_instr_encoding(dc, OP_c_xor, instr); + instr = + INSTR_CREATE_c_sub(dc, opnd_create_reg(DR_REG_X8), opnd_create_reg(DR_REG_X15)); + test_instr_encoding(dc, OP_c_sub, instr); +} + +static void +test_jump_and_branch(void *dc) +{ + byte *pc; + instr_t *instr; + + /* FIXME i#3544: Need to be better formatted. */ + instr = INSTR_CREATE_lui(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(42, OPSZ_20b)); + pc = test_instr_encoding(dc, OP_lui, instr); + instr = INSTR_CREATE_auipc(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int(42, OPSZ_20b)); + test_instr_encoding(dc, OP_auipc, instr); + instr = INSTR_CREATE_jal(dc, opnd_create_reg(DR_REG_A0), opnd_create_pc(pc)); + test_instr_encoding(dc, OP_jal, instr); + instr = INSTR_CREATE_jalr(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int(42, OPSZ_12b)); + test_instr_encoding(dc, OP_jalr, instr); + + instr = INSTR_CREATE_beq(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_beq, instr); + instr = INSTR_CREATE_bne(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bne, instr); + instr = INSTR_CREATE_blt(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_blt, instr); + instr = INSTR_CREATE_bge(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bge, instr); + instr = INSTR_CREATE_bltu(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bltu, instr); + instr = INSTR_CREATE_bgeu(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bgeu, instr); + + /* Compressed */ + instr = INSTR_CREATE_c_j(dc, opnd_create_pc(pc)); + test_instr_encoding(dc, OP_c_j, instr); + instr = INSTR_CREATE_c_jr(dc, opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_c_jr, instr); + /* There is no c.jal in RV64. */ + instr = INSTR_CREATE_c_jalr(dc, opnd_create_reg(DR_REG_A0)); + test_instr_encoding(dc, OP_c_jalr, instr); + instr = INSTR_CREATE_c_beqz(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); + test_instr_encoding(dc, OP_c_beqz, instr); + instr = INSTR_CREATE_c_bnez(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); + test_instr_encoding(dc, OP_c_bnez, instr); + instr = INSTR_CREATE_c_li(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + test_instr_encoding(dc, OP_c_li, instr); + + /* FIXME i#3544: Need to be better formatted. */ + instr = INSTR_CREATE_c_lui(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal(1, OPSZ_6b)); + test_instr_encoding(dc, OP_c_lui, instr); + instr = INSTR_CREATE_c_addi(dc, opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + test_instr_encoding(dc, OP_c_addi, instr); + instr = INSTR_CREATE_c_addi16sp(dc, opnd_create_immed_int_decimal(1 << 4, OPSZ_10b)); + test_instr_encoding(dc, OP_c_addi16sp, instr); + instr = INSTR_CREATE_c_addi4spn(dc, opnd_create_reg(DR_REG_X8), + opnd_create_immed_int_decimal(1 << 2, OPSZ_10b)); + test_instr_encoding(dc, OP_c_addi4spn, instr); +} + +static void +test_csr(void *dc) +{ + instr_t *instr; + instr = INSTR_CREATE_csrrw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int(0x42, OPSZ_12b)); + test_instr_encoding(dc, OP_csrrw, instr); + instr = INSTR_CREATE_csrrs(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int(0x42, OPSZ_12b)); + test_instr_encoding(dc, OP_csrrs, instr); + instr = INSTR_CREATE_csrrc(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int(0x42, OPSZ_12b)); + test_instr_encoding(dc, OP_csrrc, instr); + instr = INSTR_CREATE_csrrwi(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int_decimal(1, OPSZ_5b), + opnd_create_immed_int(0x42, OPSZ_12b)); + test_instr_encoding(dc, OP_csrrwi, instr); + instr = INSTR_CREATE_csrrsi(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int_decimal(1, OPSZ_5b), + opnd_create_immed_int(0x42, OPSZ_12b)); + test_instr_encoding(dc, OP_csrrsi, instr); + instr = INSTR_CREATE_csrrci(dc, opnd_create_reg(DR_REG_A0), + opnd_create_immed_int_decimal(1, OPSZ_5b), + opnd_create_immed_int(0x42, OPSZ_12b)); + test_instr_encoding(dc, OP_csrrci, instr); +} + +static void +test_bit(void *dc) +{ + instr_t *instr; + instr = INSTR_CREATE_add_uw(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_add_uw, instr); + instr = INSTR_CREATE_sh1add(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_sh1add, instr); + instr = INSTR_CREATE_sh2add(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_sh2add, instr); + instr = INSTR_CREATE_sh3add(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_sh3add, instr); + instr = + INSTR_CREATE_sh1add_uw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_sh1add_uw, instr); + instr = + INSTR_CREATE_sh2add_uw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_sh2add_uw, instr); + instr = + INSTR_CREATE_sh3add_uw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A2)); + test_instr_encoding(dc, OP_sh3add_uw, instr); + instr = + INSTR_CREATE_slli_uw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_slli_uw, instr); + + instr = INSTR_CREATE_andn(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_andn, instr); + instr = INSTR_CREATE_orn(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_orn, instr); + instr = INSTR_CREATE_xnor(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_xnor, instr); + instr = INSTR_CREATE_clz(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_clz, instr); + instr = INSTR_CREATE_clzw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_clzw, instr); + instr = INSTR_CREATE_ctz(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_ctz, instr); + instr = INSTR_CREATE_ctzw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_ctzw, instr); + instr = INSTR_CREATE_cpop(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_cpop, instr); + instr = + INSTR_CREATE_cpopw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_cpopw, instr); + instr = INSTR_CREATE_max(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_max, instr); + instr = INSTR_CREATE_maxu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_maxu, instr); + instr = INSTR_CREATE_min(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_min, instr); + instr = INSTR_CREATE_minu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_minu, instr); + instr = + INSTR_CREATE_sext_b(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sext_b, instr); + instr = + INSTR_CREATE_sext_h(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sext_h, instr); + instr = + INSTR_CREATE_zext_h(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_zext_h, instr); + instr = INSTR_CREATE_rol(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_rol, instr); + instr = INSTR_CREATE_rolw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_rolw, instr); + instr = INSTR_CREATE_ror(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_ror, instr); + instr = INSTR_CREATE_rorw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_rorw, instr); + instr = INSTR_CREATE_rori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_rori, instr); + instr = + INSTR_CREATE_orc_b(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_orc_b, instr); + instr = INSTR_CREATE_clmul(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_clmul, instr); + instr = INSTR_CREATE_clmulh(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_clmulh, instr); + instr = INSTR_CREATE_clmulr(dc, opnd_create_reg(DR_REG_A0), + opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_clmulr, instr); + instr = INSTR_CREATE_rev8(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_rev8, instr); + instr = INSTR_CREATE_bclr(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bclr, instr); + instr = INSTR_CREATE_bclri(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_bclri, instr); + instr = INSTR_CREATE_bext(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bext, instr); + instr = INSTR_CREATE_bexti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_bexti, instr); + instr = INSTR_CREATE_binv(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_binv, instr); + instr = INSTR_CREATE_binvi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_binvi, instr); + instr = INSTR_CREATE_bset(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_bset, instr); + instr = INSTR_CREATE_bseti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + test_instr_encoding(dc, OP_bseti, instr); +} + +static void +test_prefetch(void *dc) +{ + instr_t *instr; + instr = INSTR_CREATE_prefetch_i( + dc, opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, 3 << 5, OPSZ_0)); + test_instr_encoding(dc, OP_prefetch_i, instr); + instr = INSTR_CREATE_prefetch_r( + dc, opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, 5 << 5, OPSZ_0)); + test_instr_encoding(dc, OP_prefetch_r, instr); + instr = INSTR_CREATE_prefetch_w( + dc, opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0)); + test_instr_encoding(dc, OP_prefetch_w, instr); +} + +static void +test_misc(void *dc) +{ + instr_t *instr; + instr = INSTR_CREATE_c_nop(dc); + test_instr_encoding(dc, OP_c_nop, instr); + instr = INSTR_CREATE_c_ebreak(dc); + test_instr_encoding(dc, OP_c_ebreak, instr); + instr = INSTR_CREATE_ecall(dc); + test_instr_encoding(dc, OP_ecall, instr); + instr = INSTR_CREATE_ebreak(dc); + test_instr_encoding(dc, OP_ebreak, instr); + instr = INSTR_CREATE_sret(dc); + test_instr_encoding(dc, OP_sret, instr); + instr = INSTR_CREATE_mret(dc); + test_instr_encoding(dc, OP_mret, instr); + instr = INSTR_CREATE_wfi(dc); + test_instr_encoding(dc, OP_wfi, instr); + + /* FIXME i#3544: Need to be better formatted. */ + instr = INSTR_CREATE_fence(dc, opnd_create_immed_int(0x0, OPSZ_4b), + opnd_create_immed_int(0x0, OPSZ_4b), + opnd_create_immed_int(0x0, OPSZ_4b)); + test_instr_encoding(dc, OP_fence, instr); + instr = INSTR_CREATE_fence_i(dc); + test_instr_encoding(dc, OP_fence_i, instr); + instr = INSTR_CREATE_sfence_vma(dc, opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sfence_vma, instr); + instr = INSTR_CREATE_sfence_w_inval(dc); + test_instr_encoding(dc, OP_sfence_w_inval, instr); + instr = INSTR_CREATE_sinval_vma(dc, opnd_create_reg(DR_REG_A1), + opnd_create_reg(DR_REG_A1)); + test_instr_encoding(dc, OP_sinval_vma, instr); + instr = INSTR_CREATE_sfence_inval_ir(dc); + test_instr_encoding(dc, OP_sfence_inval_ir, instr); + instr = INSTR_CREATE_cbo_zero( + dc, opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0)); + test_instr_encoding(dc, OP_cbo_zero, instr); + instr = INSTR_CREATE_cbo_clean( + dc, opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0)); + test_instr_encoding(dc, OP_cbo_clean, instr); + instr = INSTR_CREATE_cbo_flush( + dc, opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0)); + test_instr_encoding(dc, OP_cbo_flush, instr); + instr = INSTR_CREATE_cbo_inval( + dc, opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0)); + test_instr_encoding(dc, OP_cbo_inval, instr); +} + int main(int argc, char *argv[]) { @@ -723,6 +1289,30 @@ main(int argc, char *argv[]) test_float_arith(dcontext); print("test_float_arith complete\n"); + test_float_compare(dcontext); + print("test_float_compare complete\n"); + + test_hypervisor(dcontext); + print("test_hypervisor complete\n"); + + test_integer(dcontext); + print("test_integer_arith complete\n"); + + test_jump_and_branch(dcontext); + print("test_jump_and_branch complete\n"); + + test_csr(dcontext); + print("test_csr complete\n"); + + test_bit(dcontext); + print("print_bit complete\n"); + + test_prefetch(dcontext); + print("test_prefetch complete\n"); + + test_misc(dcontext); + print("test_misc complete\n"); + print("All tests complete\n"); return 0; } diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index 65ddef9bb9c..d0b827ccc4d 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -20,8 +20,10 @@ c.sw %fp -> +124(%a5)[4byte] test_integer_load_store complete flw (%a1)[4byte] -> %ft0 fld -1(%zero)[8byte] -> %ft11 +flq -1(%zero)[16byte] -> %ft11 fsw %ft1 -> +2047(%t6)[4byte] fsd %ft11 -> +2047(%t6)[8byte] +fsq %ft11 -> +2047(%t6)[16byte] c.fldsp (%sp)[8byte] -> %ft0 c.fld +248(%a5)[8byte] -> %fs0 c.fsdsp %ft11 -> (%sp)[8byte] @@ -135,4 +137,180 @@ fclass.d %ft1 -> %a0 fclass.q %ft1 -> %a0 fclass.s %ft1 -> %a0 test_float_arith complete +feq.d %ft0 %ft1 -> %a0 +flt.d %ft11 %ft11 -> %zero +flt.d %ft1 %ft0 -> %t6 +feq.q %ft1 %ft1 -> %a0 +flt.q %ft1 %ft1 -> %a0 +flt.q %ft1 %ft1 -> %a0 +feq.s %ft1 %ft1 -> %a0 +flt.s %ft1 %ft1 -> %a0 +flt.s %ft1 %ft1 -> %a0 +test_float_compare complete +hlv.b %a1 -> %a0 +hlv.bu %a1 -> %a0 +hlv.h %a1 -> %a0 +hlv.hu %a1 -> %a0 +hlvx.hu %a1 -> %a0 +hlv.w %a1 -> %a0 +hlv.wu %a1 -> %a0 +hlvx.wu %a1 -> %a0 +hlv.d %a1 -> %a0 +hsv.b %a0 %a1 +hsv.h %a0 %a1 +hsv.w %a0 %a1 +hsv.d %a0 %a1 +hinval.vvma %a0 %a1 +hinval.gvma %a0 %a1 +hfence.vvma %a0 %a1 +hfence.gvma %a0 %a1 +test_hypervisor complete +addi %a1 0 -> %a0 +addiw %a1 0 -> %a0 +slti %a1 -1 -> %a0 +sltiu %a1 2047 -> %a0 +xori %a1 2047 -> %a0 +ori %a1 2047 -> %a0 +andi %a1 2047 -> %a0 +slli %a1 63 -> %a0 +slliw %a1 31 -> %a0 +srli %a1 63 -> %a0 +srliw %a1 31 -> %a0 +srai %a1 63 -> %a0 +sraiw %a1 31 -> %a0 +add %a1 %a1 -> %a0 +addw %a1 %a1 -> %a0 +sub %a1 %a1 -> %a0 +subw %a1 %a1 -> %a0 +sll %a1 %a1 -> %a0 +sllw %a1 %a1 -> %a0 +slt %a1 %a1 -> %a0 +sltu %a1 %a1 -> %a0 +xor %a1 %a1 -> %a0 +srl %a1 %a1 -> %a0 +srlw %a1 %a1 -> %a0 +sra %a1 %a1 -> %a0 +sraw %a1 %a1 -> %a0 +or %a1 %a1 -> %a0 +and %a1 %a1 -> %a0 +mul %a1 %a1 -> %a0 +mulw %a1 %a1 -> %a0 +mulh %a1 %a1 -> %a0 +mulhsu %a1 %a1 -> %a0 +mulhu %a1 %a1 -> %a0 +div %a1 %a1 -> %a0 +divw %a1 %a1 -> %a0 +divu %a1 %a1 -> %a0 +divuw %a1 %a1 -> %a0 +rem %a1 %a1 -> %a0 +remw %a1 %a1 -> %a0 +remu %a1 %a1 -> %a0 +remuw %a1 %a1 -> %a0 +c.addiw 31 -> %a0 +c.addw %a1 -> %a0 +c.subw %a1 -> %a0 +c.slli 63 -> %a1 +c.srli 63 -> %a1 +c.srai 63 -> %a1 +c.andi -1 -> %a1 +c.mv %a1 -> %a1 +c.add %a1 -> %a1 +c.and %a5 -> %fp +c.or %a5 -> %fp +c.xor %a5 -> %fp +c.sub %a5 -> %fp +test_integer_arith complete +lui 0x2a -> %a0 +auipc 0x2a -> %a0 +jal $0x000000400000e1ec -> %a0 +jalr %a1 0x2a -> %a0 +beq $0x000000400000e1ec %a0 %a1 +bne $0x000000400000e1ec %a0 %a1 +blt $0x000000400000e1ec %a0 %a1 +bge $0x000000400000e1ec %a0 %a1 +bltu $0x000000400000e1ec %a0 %a1 +bgeu $0x000000400000e1ec %a0 %a1 +c.j $0x000000400000e1ec +c.jr %a0 +c.jalr %a0 +c.beqz $0x000000400000e1ec %fp +c.bnez $0x000000400000e1ec %fp +c.li 31 -> %a1 +c.lui 1 -> %a1 +c.addi 31 -> %a1 +c.addi16sp 16 +c.addi4spn 4 -> %fp +test_jump_and_branch complete +csrrw %a1 0x42 -> %a0 +csrrs %a1 0x42 -> %a0 +csrrc %a1 0x42 -> %a0 +csrrwi 1 0x42 -> %a0 +csrrsi 1 0x42 -> %a0 +csrrci 1 0x42 -> %a0 +test_csr complete +add.uw %a1 %a2 -> %a0 +sh1add %a1 %a2 -> %a0 +sh2add %a1 %a2 -> %a0 +sh3add %a1 %a2 -> %a0 +sh1add.uw %a1 %a2 -> %a0 +sh2add.uw %a1 %a2 -> %a0 +sh3add.uw %a1 %a2 -> %a0 +slli.uw %a1 63 -> %a0 +andn %a1 %a1 -> %a0 +orn %a1 %a1 -> %a0 +xnor %a1 %a1 -> %a0 +clz %a1 -> %a0 +clzw %a1 -> %a0 +ctz %a1 -> %a0 +ctzw %a1 -> %a0 +cpop %a1 -> %a0 +cpopw %a1 -> %a0 +max %a1 %a1 -> %a0 +maxu %a1 %a1 -> %a0 +min %a1 %a1 -> %a0 +minu %a1 %a1 -> %a0 +sext.b %a1 -> %a0 +sext.h %a1 -> %a0 +zext.h %a1 -> %a0 +rol %a1 %a1 -> %a0 +rolw %a1 %a1 -> %a0 +ror %a1 %a1 -> %a0 +rorw %a1 %a1 -> %a0 +rori %a1 63 -> %a0 +orc.b %a1 -> %a0 +clmul %a1 %a1 -> %a0 +clmulh %a1 %a1 -> %a0 +clmulr %a1 %a1 -> %a0 +rev8 %a1 -> %a0 +bclr %a1 %a1 -> %a0 +bclri %a1 63 -> %a0 +bext %a1 %a1 -> %a0 +bexti %a1 63 -> %a0 +binv %a1 %a1 -> %a0 +binvi %a1 63 -> %a0 +bset %a1 %a1 -> %a0 +bseti %a1 63 -> %a0 +print_bit complete +prefetch.i -> +96(%zero) +prefetch.r -> +160(%t6) +prefetch.w -> (%a1) +test_prefetch complete +c.nop +c.ebreak +ecall +ebreak +sret +mret +wfi +fence 0x0 0x0 0x0 +fence.i +sfence.vma %a1 %a1 +sfence.w.inval +sinval.vma %a1 %a1 +sfence.inval.ir +cbo.zero (%a1) +cbo.clean (%a1) +cbo.flush (%a1) +cbo.inval (%a1) +test_misc complete All tests complete From 7c922cece6a9e2cdf5154df94b8e06760918b4f3 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sun, 18 Jun 2023 00:45:20 +0800 Subject: [PATCH 24/34] Fixed branch tests --- suite/tests/api/ir_riscv64.c | 41 +++++++++++++++++++++---------- suite/tests/api/ir_riscv64.expect | 13 ---------- 2 files changed, 28 insertions(+), 26 deletions(-) diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index 187ca44c7ca..abb77d825ef 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -87,6 +87,21 @@ test_instr_encoding(void *dc, uint opcode, instr_t *instr) return pc; } +static void +test_instr_encoding_branch(void *dc, uint opcode, instr_t *instr) +{ + instr_t *decin; + + ASSERT(instr_get_opcode(instr) == opcode); + ASSERT(instr_is_encoding_possible(instr)); + instr_encode(dc, instr, buf); + decin = instr_create(dc); + decode(dc, buf, decin); + ASSERT(instr_same(instr, decin)); + instr_destroy(dc, instr); + instr_destroy(dc, decin); +} + static void test_integer_load_store(void *dc) { @@ -985,42 +1000,42 @@ test_jump_and_branch(void *dc) opnd_create_immed_int(42, OPSZ_20b)); test_instr_encoding(dc, OP_auipc, instr); instr = INSTR_CREATE_jal(dc, opnd_create_reg(DR_REG_A0), opnd_create_pc(pc)); - test_instr_encoding(dc, OP_jal, instr); + test_instr_encoding_branch(dc, OP_jal, instr); instr = INSTR_CREATE_jalr(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_immed_int(42, OPSZ_12b)); - test_instr_encoding(dc, OP_jalr, instr); + test_instr_encoding_branch(dc, OP_jalr, instr); instr = INSTR_CREATE_beq(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding(dc, OP_beq, instr); + test_instr_encoding_branch(dc, OP_beq, instr); instr = INSTR_CREATE_bne(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding(dc, OP_bne, instr); + test_instr_encoding_branch(dc, OP_bne, instr); instr = INSTR_CREATE_blt(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding(dc, OP_blt, instr); + test_instr_encoding_branch(dc, OP_blt, instr); instr = INSTR_CREATE_bge(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding(dc, OP_bge, instr); + test_instr_encoding_branch(dc, OP_bge, instr); instr = INSTR_CREATE_bltu(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding(dc, OP_bltu, instr); + test_instr_encoding_branch(dc, OP_bltu, instr); instr = INSTR_CREATE_bgeu(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding(dc, OP_bgeu, instr); + test_instr_encoding_branch(dc, OP_bgeu, instr); /* Compressed */ instr = INSTR_CREATE_c_j(dc, opnd_create_pc(pc)); - test_instr_encoding(dc, OP_c_j, instr); + test_instr_encoding_branch(dc, OP_c_j, instr); instr = INSTR_CREATE_c_jr(dc, opnd_create_reg(DR_REG_A0)); - test_instr_encoding(dc, OP_c_jr, instr); + test_instr_encoding_branch(dc, OP_c_jr, instr); /* There is no c.jal in RV64. */ instr = INSTR_CREATE_c_jalr(dc, opnd_create_reg(DR_REG_A0)); - test_instr_encoding(dc, OP_c_jalr, instr); + test_instr_encoding_branch(dc, OP_c_jalr, instr); instr = INSTR_CREATE_c_beqz(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); - test_instr_encoding(dc, OP_c_beqz, instr); + test_instr_encoding_branch(dc, OP_c_beqz, instr); instr = INSTR_CREATE_c_bnez(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); - test_instr_encoding(dc, OP_c_bnez, instr); + test_instr_encoding_branch(dc, OP_c_bnez, instr); instr = INSTR_CREATE_c_li(dc, opnd_create_reg(DR_REG_A1), opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); test_instr_encoding(dc, OP_c_li, instr); diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index d0b827ccc4d..f51d7f0b8b1 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -222,19 +222,6 @@ c.sub %a5 -> %fp test_integer_arith complete lui 0x2a -> %a0 auipc 0x2a -> %a0 -jal $0x000000400000e1ec -> %a0 -jalr %a1 0x2a -> %a0 -beq $0x000000400000e1ec %a0 %a1 -bne $0x000000400000e1ec %a0 %a1 -blt $0x000000400000e1ec %a0 %a1 -bge $0x000000400000e1ec %a0 %a1 -bltu $0x000000400000e1ec %a0 %a1 -bgeu $0x000000400000e1ec %a0 %a1 -c.j $0x000000400000e1ec -c.jr %a0 -c.jalr %a0 -c.beqz $0x000000400000e1ec %fp -c.bnez $0x000000400000e1ec %fp c.li 31 -> %a1 c.lui 1 -> %a1 c.addi 31 -> %a1 From 4b854faea36f620108d664041214fd242b4ed03d Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sun, 18 Jun 2023 00:53:55 +0800 Subject: [PATCH 25/34] Open RISCV64 tests --- suite/runsuite.cmake | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/suite/runsuite.cmake b/suite/runsuite.cmake index a1f0a78b27d..9c498c3c97d 100644 --- a/suite/runsuite.cmake +++ b/suite/runsuite.cmake @@ -555,9 +555,10 @@ endif () if (ARCH_IS_X86 AND UNIX) # TODO i#3544: Run tests under QEMU set(orig_extra_ctest_args ${extra_ctest_args}) + set(extra_ctest_args INCLUDE_LABEL RISCV64) set(prev_optional_cross_compile ${optional_cross_compile}) set(prev_run_tests ${run_tests}) - set(run_tests OFF) + set(run_tests ON) if (NOT cross_riscv64_linux_only) set(optional_cross_compile ON) endif () From 4d6ff7965a416f6201f54b7a8aac2c58df688a63 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Sun, 18 Jun 2023 01:01:52 +0800 Subject: [PATCH 26/34] Setup QEMU_LD_PREFIX --- .github/workflows/ci-riscv64.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/ci-riscv64.yml b/.github/workflows/ci-riscv64.yml index d9580a768b5..7ae5566f191 100644 --- a/.github/workflows/ci-riscv64.yml +++ b/.github/workflows/ci-riscv64.yml @@ -94,6 +94,7 @@ jobs: DYNAMORIO_CROSS_RISCV64_LINUX_ONLY: yes CI_TRIGGER: ${{ github.event_name }} CI_BRANCH: ${{ github.ref }} + QEMU_LD_PREFIX: /usr/riscv64-linux-gnu/ - name: Send failure mail to dynamorio-devs if: failure() && github.ref == 'refs/heads/master' From 09399327a52f14082f4275c07f4d47f3a352f3eb Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 13:10:37 +0800 Subject: [PATCH 27/34] Added DR_DISASM_RISCV for syntax control --- api/docs/bt.dox | 5 +- api/docs/deployment.dox | 5 + clients/drcachesim/common/options.cpp | 9 +- clients/drcachesim/tests/view_test.cpp | 4 +- clients/drcachesim/tools/view.cpp | 7 +- clients/drdisas/drdisas.cpp | 4 + core/ir/disassemble_api.h | 10 +- core/ir/disassemble_shared.c | 20 +- core/optionsx.h | 1 + suite/tests/api/ir_riscv64.c | 2 + suite/tests/api/ir_riscv64.expect | 552 ++++++++++++------------- 11 files changed, 323 insertions(+), 296 deletions(-) diff --git a/api/docs/bt.dox b/api/docs/bt.dox index 6f23e9a3e9f..88188d19d7f 100644 --- a/api/docs/bt.dox +++ b/api/docs/bt.dox @@ -731,8 +731,9 @@ disassemble_from_copy(), and disassemble_to_buffer(). The style of disassembly can be controlled through the \ref op_syntax_intel "-syntax_intel" (for Intel-style disassembly), -\ref op_syntax_att "-syntax_att" (for AT&T-style disassembly), and -\ref op_syntax_arm "-syntax_arm" (for ARM-style disassembly) runtime +\ref op_syntax_att "-syntax_att" (for AT&T-style disassembly), +\ref op_syntax_arm "-syntax_arm" (for ARM-style disassembly), and +\ref op_syntax_riscv "-syntax_riscv" (for RISC-V-style disassembly) runtime options, or the disassemble_set_syntax() function. The default disassembly style is DynamoRIO's custom style, which lists all operands (both implicit and explicit). The sources are listed first, followed by "->", and then diff --git a/api/docs/deployment.dox b/api/docs/deployment.dox index 71bee883fe9..be86a146fbc 100644 --- a/api/docs/deployment.dox +++ b/api/docs/deployment.dox @@ -920,6 +920,11 @@ they want to shrink memory usage ARM assembler syntax rather than the default show-implicit-operands syntax. This can also be set using disassemble_set_syntax(). + - \b -syntax_riscv: \anchor op_syntax_riscv + This option causes DynamoRIO to output all disassembly using + RISC-V assembler syntax rather than the default show-implicit-operands + syntax. This can also be set using disassemble_set_syntax(). + - \b -disasm_mask: This option sets the disassembly style to the specified bitmask of dr_disasm_flags_t values. This option overlaps with -syntax_intel, diff --git a/clients/drcachesim/common/options.cpp b/clients/drcachesim/common/options.cpp index 8a434e58b8b..cac8aa3bf13 100644 --- a/clients/drcachesim/common/options.cpp +++ b/clients/drcachesim/common/options.cpp @@ -540,15 +540,16 @@ droption_t "and the references following the simulated ones are dropped."); droption_t - op_view_syntax(DROPTION_SCOPE_FRONTEND, "view_syntax", "att/arm/dr", + op_view_syntax(DROPTION_SCOPE_FRONTEND, "view_syntax", "att/arm/dr/riscv", "Syntax to use for disassembly.", "Specifies the syntax to use when viewing disassembled offline traces." // TODO i#4382: Add aarch64 syntax support. " The option can be set to one of \"att\" (AT&T style), \"intel\"" " (Intel style), \"dr\" (DynamoRIO's native style with all implicit" - " operands listed), and \"arm\" (32-bit ARM style). An invalid" - " specification falls back to the default, which is \"att\" for x86," - " \"arm\" for ARM (32-bit), and \"dr\" for AArch64."); + " operands listed), \"arm\" (32-bit ARM style), and \"riscv\" (RISC-V " + "style). An invalid specification falls back to the default, which is " + "\"att\" for x86, \"arm\" for ARM (32-bit), \"dr\" for AArch64, " + "and \"riscv\" for RISC-V."); droption_t op_config_file(DROPTION_SCOPE_FRONTEND, "config_file", "", diff --git a/clients/drcachesim/tests/view_test.cpp b/clients/drcachesim/tests/view_test.cpp index 4067bb76d49..6d56e498f46 100644 --- a/clients/drcachesim/tests/view_test.cpp +++ b/clients/drcachesim/tests/view_test.cpp @@ -105,7 +105,9 @@ class view_test_t : public view_t { { module_mapper_->get_loaded_modules(); dr_disasm_flags_t flags = - IF_X86_ELSE(DR_DISASM_ATT, IF_AARCH64_ELSE(DR_DISASM_DR, DR_DISASM_ARM)); + IF_X86_ELSE(DR_DISASM_ATT, + IF_AARCH64_ELSE(DR_DISASM_DR, + IF_RISCV64_ELSE(DR_DISASM_RISCV, DR_DISASM_ARM))); disassemble_set_syntax(flags); return ""; } diff --git a/clients/drcachesim/tools/view.cpp b/clients/drcachesim/tools/view.cpp index a5fe46dc15b..6df1d496242 100644 --- a/clients/drcachesim/tools/view.cpp +++ b/clients/drcachesim/tools/view.cpp @@ -101,14 +101,17 @@ view_t::initialize_stream(memtrace_stream_t *serial_stream) std::string error = module_mapper_->get_last_error(); if (!error.empty()) return "Failed to load binaries: " + error; - dr_disasm_flags_t flags = - IF_X86_ELSE(DR_DISASM_ATT, IF_AARCH64_ELSE(DR_DISASM_DR, DR_DISASM_ARM)); + dr_disasm_flags_t flags = IF_X86_ELSE( + DR_DISASM_ATT, + IF_AARCH64_ELSE(DR_DISASM_DR, IF_RISCV64_ELSE(DR_DISASM_RISCV, DR_DISASM_ARM))); if (knob_syntax_ == "intel") { flags = DR_DISASM_INTEL; } else if (knob_syntax_ == "dr") { flags = DR_DISASM_DR; } else if (knob_syntax_ == "arm") { flags = DR_DISASM_ARM; + } else if (knob_syntax_ == "riscv") { + flags = DR_DISASM_RISCV; } disassemble_set_syntax(flags); return ""; diff --git a/clients/drdisas/drdisas.cpp b/clients/drdisas/drdisas.cpp index 215060870be..32a15041e3e 100644 --- a/clients/drdisas/drdisas.cpp +++ b/clients/drdisas/drdisas.cpp @@ -165,6 +165,10 @@ main(int argc, const char *argv[]) } #endif +#ifdef RISCV64 + disassemble_set_syntax(DR_DISASM_RISCV); +#endif + // Turn the arguments into a series of hex values. std::vector bytes; for (int i = last_index; i < argc; ++i) { diff --git a/core/ir/disassemble_api.h b/core/ir/disassemble_api.h index d9fd1c1b29f..751cb22a051 100644 --- a/core/ir/disassemble_api.h +++ b/core/ir/disassemble_api.h @@ -86,6 +86,12 @@ typedef enum { * \p -syntax_arm. Implicit operands are not displayed. */ DR_DISASM_ARM = 0x10, + /** + * Requests RISC-V assembler syntax for disassembly. This set the same option that + * is controlled by the runtime option \p -syntax_riscv. Implicit oprands are not + * displayed. + */ + DR_DISASM_RISCV = 0x20, } dr_disasm_flags_t; /* TODO i#4382: Add DR_DISASM_AARCH64. */ @@ -93,8 +99,8 @@ DR_API /** * Sets the disassembly style and decoding options. * The default is to use DR's custom syntax, unless one of the \ref op_syntax_intel - * "-syntax_intel", \ref op_syntax_att "-syntax_att", or \ref op_syntax_arm - * "-syntax_arm" runtime options is specified. + * "-syntax_intel", \ref op_syntax_att "-syntax_att", \ref op_syntax_arm + * "-syntax_arm", or \ref op_syntax_riscv "-syntax_riscv" runtime options is specified. */ void disassemble_set_syntax(dr_disasm_flags_t flags); diff --git a/core/ir/disassemble_shared.c b/core/ir/disassemble_shared.c index befc9a385ce..936bad963b6 100644 --- a/core/ir/disassemble_shared.c +++ b/core/ir/disassemble_shared.c @@ -129,6 +129,9 @@ disassemble_options_init(void) if (DYNAMO_OPTION(syntax_arm)) { flags |= DR_DISASM_ARM; } + if (DYNAMO_OPTION(syntax_riscv)) { + flags |= DR_DISASM_RISCV; + } /* This option is separate as it's not strictly a disasm style */ dynamo_options.decode_strict = TEST(DR_DISASM_STRICT_INVALID, flags); if (DYNAMO_OPTION(decode_strict)) @@ -154,7 +157,8 @@ disassemble_set_syntax(dr_disasm_flags_t flags) static inline bool dsts_first(void) { - return TESTANY(DR_DISASM_INTEL | DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask)); + return TESTANY(DR_DISASM_INTEL | DR_DISASM_ARM | DR_DISASM_RISCV, + DYNAMO_OPTION(disasm_mask)); } static inline bool @@ -170,7 +174,7 @@ internal_instr_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, static inline const char * immed_prefix(void) { - return (TEST(DR_DISASM_INTEL, DYNAMO_OPTION(disasm_mask)) + return (TEST(DR_DISASM_INTEL | DR_DISASM_RISCV, DYNAMO_OPTION(disasm_mask)) ? "" : (TEST(DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask)) ? "#" : "$")); } @@ -180,7 +184,8 @@ reg_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, reg_id_t reg, dr_opnd_flags_t flags, const char *prefix, const char *suffix) { print_to_buffer(buf, bufsz, sofar, - TESTANY(DR_DISASM_INTEL | DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask)) + TESTANY(DR_DISASM_INTEL | DR_DISASM_ARM | DR_DISASM_RISCV, + DYNAMO_OPTION(disasm_mask)) ? "%s%s%s%s" : "%s%s%%%s%s", prefix, TEST(DR_OPND_NEGATED, flags) ? "-" : "", reg_names[reg], @@ -399,20 +404,17 @@ opnd_base_disp_disassemble(char *buf, size_t bufsz, size_t *sofar INOUT, opnd_t print_to_buffer(buf, bufsz, sofar, "-"); } } -#if defined(RISCV64) - const char *fmt = - TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL) ? "%d" : "0x%x"; - print_to_buffer(buf, bufsz, sofar, fmt, disp); -#else if (TEST(DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask))) print_to_buffer(buf, bufsz, sofar, "%d", disp); + else if (TEST(DR_DISASM_RISCV, DYNAMO_OPTION(disasm_mask)) && + TEST(opnd_get_flags(opnd), DR_OPND_IMM_PRINT_DECIMAL)) + print_to_buffer(buf, bufsz, sofar, "%d", disp); else if ((unsigned)disp <= 0xff && !opnd_is_disp_force_full(opnd)) print_to_buffer(buf, bufsz, sofar, "0x%02x", disp); else if ((unsigned)disp <= 0xffff IF_X86(&&opnd_is_disp_short_addr(opnd))) print_to_buffer(buf, bufsz, sofar, "0x%04x", disp); else /* there are no 64-bit displacements */ print_to_buffer(buf, bufsz, sofar, "0x%08x", disp); -#endif } if (!TESTANY(DR_DISASM_INTEL | DR_DISASM_ARM, DYNAMO_OPTION(disasm_mask))) { diff --git a/core/optionsx.h b/core/optionsx.h index 4217cc3abdd..848d31d9adb 100644 --- a/core/optionsx.h +++ b/core/optionsx.h @@ -229,6 +229,7 @@ OPTION_INTERNAL(bool, tracedump_origins, "write out original instructions for ea OPTION(bool, syntax_intel, "use Intel disassembly syntax") OPTION(bool, syntax_att, "use AT&T disassembly syntax") OPTION(bool, syntax_arm, "use ARM (32-bit) disassembly syntax") +OPTION(bool, syntax_riscv, "use RISC-V disassembly syntax") /* TODO i#4382: Add syntax_aarch64. */ /* whether to mark gray-area instrs as invalid when we know the length (i#1118) */ OPTION(bool, decode_strict, "mark all known-invalid instructions as invalid") diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index abb77d825ef..d55ff066bd3 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -1286,6 +1286,8 @@ main(int argc, char *argv[]) void *dcontext = dr_standalone_init(); #endif + disassemble_set_syntax(DR_DISASM_RISCV); + test_integer_load_store(dcontext); print("test_integer_load_store complete\n"); diff --git a/suite/tests/api/ir_riscv64.expect b/suite/tests/api/ir_riscv64.expect index f51d7f0b8b1..902130454ba 100644 --- a/suite/tests/api/ir_riscv64.expect +++ b/suite/tests/api/ir_riscv64.expect @@ -1,286 +1,286 @@ -lb (%a1)[1byte] -> %a0 -lbu -1(%a1)[1byte] -> %zero -lh +2047(%a1)[2byte] -> %a0 -lhu (%zero)[2byte] -> %a0 -lw -1(%a1)[4byte] -> %t6 -lwu (%t6)[4byte] -> %a0 -ld +42(%a1)[8byte] -> %a0 -sb %a0 -> (%a1)[1byte] -sh %t6 -> -1(%zero)[2byte] -sw %zero -> +2047(%t6)[4byte] -sd %a0 -> +42(%a1)[8byte] -c.ldsp (%sp)[8byte] -> %a0 -c.ld +248(%a5)[8byte] -> %fp -c.lwsp +124(%sp)[4byte] -> %zero -c.lw +124(%a5)[4byte] -> %fp -c.sdsp %a0 -> (%sp)[8byte] -c.sd %fp -> +248(%a5)[8byte] -c.swsp %zero -> +124(%sp)[4byte] -c.sw %fp -> +124(%a5)[4byte] +lb (a1)[1byte] -> a0 +lbu -1(a1)[1byte] -> zero +lh +2047(a1)[2byte] -> a0 +lhu (zero)[2byte] -> a0 +lw -1(a1)[4byte] -> t6 +lwu (t6)[4byte] -> a0 +ld +42(a1)[8byte] -> a0 +sb a0 -> (a1)[1byte] +sh t6 -> -1(zero)[2byte] +sw zero -> +2047(t6)[4byte] +sd a0 -> +42(a1)[8byte] +c.ldsp (sp)[8byte] -> a0 +c.ld +248(a5)[8byte] -> fp +c.lwsp +124(sp)[4byte] -> zero +c.lw +124(a5)[4byte] -> fp +c.sdsp a0 -> (sp)[8byte] +c.sd fp -> +248(a5)[8byte] +c.swsp zero -> +124(sp)[4byte] +c.sw fp -> +124(a5)[4byte] test_integer_load_store complete -flw (%a1)[4byte] -> %ft0 -fld -1(%zero)[8byte] -> %ft11 -flq -1(%zero)[16byte] -> %ft11 -fsw %ft1 -> +2047(%t6)[4byte] -fsd %ft11 -> +2047(%t6)[8byte] -fsq %ft11 -> +2047(%t6)[16byte] -c.fldsp (%sp)[8byte] -> %ft0 -c.fld +248(%a5)[8byte] -> %fs0 -c.fsdsp %ft11 -> (%sp)[8byte] -c.fsd %fs0 -> +248(%a5)[8byte] +flw (a1)[4byte] -> ft0 +fld -1(zero)[8byte] -> ft11 +flq -1(zero)[16byte] -> ft11 +fsw ft1 -> +2047(t6)[4byte] +fsd ft11 -> +2047(t6)[8byte] +fsq ft11 -> +2047(t6)[16byte] +c.fldsp (sp)[8byte] -> ft0 +c.fld +248(a5)[8byte] -> fs0 +c.fsdsp ft11 -> (sp)[8byte] +c.fsd fs0 -> +248(a5)[8byte] test_float_load_store complete -lr.w %a1 0x0 -> %a0 -lr.d %t6 0x2 -> %zero -sc.w %a1 %a2 0x1 -> %a0 -sc.d %t6 %a1 0x3 -> %zero -amoswap.w %ra %t6 0x0 -> %zero -amoswap.d %ra %zero 0x1 -> %t6 -amoadd.w %t6 %a2 0x2 -> %zero -amoadd.d %a1 %a2 0x3 -> %a0 -amoxor.w %a1 %a2 0x1 -> %a0 -amoxor.d %a1 %a2 0x1 -> %a0 -amoand.w %a1 %a2 0x1 -> %a0 -amoand.d %a1 %a2 0x1 -> %a0 -amoor.w %a1 %a2 0x1 -> %a0 -amoor.d %a1 %a2 0x1 -> %a0 -amomin.w %a1 %a2 0x1 -> %a0 -amomin.d %a1 %a2 0x1 -> %a0 -amomax.w %a1 %a2 0x1 -> %a0 -amomax.d %a1 %a2 0x1 -> %a0 -amominu.w %a1 %a2 0x1 -> %a0 -amominu.d %a1 %a2 0x1 -> %a0 -amomaxu.w %a1 %a2 0x1 -> %a0 -amomaxu.d %a1 %a2 0x1 -> %a0 +lr.w a1 0x0 -> a0 +lr.d t6 0x2 -> zero +sc.w a1 a2 0x1 -> a0 +sc.d t6 a1 0x3 -> zero +amoswap.w ra t6 0x0 -> zero +amoswap.d ra zero 0x1 -> t6 +amoadd.w t6 a2 0x2 -> zero +amoadd.d a1 a2 0x3 -> a0 +amoxor.w a1 a2 0x1 -> a0 +amoxor.d a1 a2 0x1 -> a0 +amoand.w a1 a2 0x1 -> a0 +amoand.d a1 a2 0x1 -> a0 +amoor.w a1 a2 0x1 -> a0 +amoor.d a1 a2 0x1 -> a0 +amomin.w a1 a2 0x1 -> a0 +amomin.d a1 a2 0x1 -> a0 +amomax.w a1 a2 0x1 -> a0 +amomax.d a1 a2 0x1 -> a0 +amominu.w a1 a2 0x1 -> a0 +amominu.d a1 a2 0x1 -> a0 +amomaxu.w a1 a2 0x1 -> a0 +amomaxu.d a1 a2 0x1 -> a0 test_atomic complete -fcvt.l.s 0x0 %ft0 -> %a0 -fcvt.lu.s 0x1 %ft0 -> %a0 -fcvt.s.l 0x2 %a0 -> %ft0 -fcvt.s.lu 0x3 %a0 -> %ft0 -fcvt.l.d 0x4 %ft0 -> %a0 -fcvt.lu.d 0x7 %ft0 -> %a0 -fcvt.d.l 0x0 %a0 -> %ft0 -fcvt.d.lu 0x0 %a0 -> %ft0 -fcvt.d.s 0x0 %ft0 -> %ft0 -fcvt.s.d 0x0 %ft0 -> %ft0 -fcvt.w.d 0x0 %ft0 -> %a0 -fcvt.wu.d 0x0 %ft0 -> %a0 -fcvt.d.w 0x0 %a0 -> %ft0 -fcvt.d.wu 0x0 %a0 -> %ft0 -fcvt.s.q 0x0 %ft0 -> %ft0 -fcvt.q.s 0x0 %ft0 -> %ft0 -fcvt.d.q 0x0 %ft0 -> %ft0 -fcvt.q.d 0x0 %ft0 -> %ft0 -fcvt.w.q 0x0 %ft0 -> %a0 -fcvt.q.w 0x0 %a0 -> %ft0 -fcvt.wu.q 0x0 %ft0 -> %a0 -fcvt.q.wu 0x0 %a0 -> %ft0 -fcvt.w.s 0x0 %ft0 -> %a0 -fcvt.s.w 0x0 %a0 -> %ft0 -fcvt.wu.s 0x0 %ft0 -> %a0 -fcvt.s.wu 0x0 %a0 -> %ft0 -fcvt.l.q 0x0 %ft0 -> %a0 -fcvt.lu.q 0x0 %ft0 -> %a0 -fcvt.q.l 0x0 %a0 -> %ft0 -fcvt.q.lu 0x0 %a0 -> %ft0 +fcvt.l.s 0x0 ft0 -> a0 +fcvt.lu.s 0x1 ft0 -> a0 +fcvt.s.l 0x2 a0 -> ft0 +fcvt.s.lu 0x3 a0 -> ft0 +fcvt.l.d 0x4 ft0 -> a0 +fcvt.lu.d 0x7 ft0 -> a0 +fcvt.d.l 0x0 a0 -> ft0 +fcvt.d.lu 0x0 a0 -> ft0 +fcvt.d.s 0x0 ft0 -> ft0 +fcvt.s.d 0x0 ft0 -> ft0 +fcvt.w.d 0x0 ft0 -> a0 +fcvt.wu.d 0x0 ft0 -> a0 +fcvt.d.w 0x0 a0 -> ft0 +fcvt.d.wu 0x0 a0 -> ft0 +fcvt.s.q 0x0 ft0 -> ft0 +fcvt.q.s 0x0 ft0 -> ft0 +fcvt.d.q 0x0 ft0 -> ft0 +fcvt.q.d 0x0 ft0 -> ft0 +fcvt.w.q 0x0 ft0 -> a0 +fcvt.q.w 0x0 a0 -> ft0 +fcvt.wu.q 0x0 ft0 -> a0 +fcvt.q.wu 0x0 a0 -> ft0 +fcvt.w.s 0x0 ft0 -> a0 +fcvt.s.w 0x0 a0 -> ft0 +fcvt.wu.s 0x0 ft0 -> a0 +fcvt.s.wu 0x0 a0 -> ft0 +fcvt.l.q 0x0 ft0 -> a0 +fcvt.lu.q 0x0 ft0 -> a0 +fcvt.q.l 0x0 a0 -> ft0 +fcvt.q.lu 0x0 a0 -> ft0 test_fcvt complete -fmv.x.d %ft0 -> %a0 -fmv.d.x %zero -> %ft11 -fmv.x.w %ft11 -> %zero -fmv.w.x %a0 -> %ft0 +fmv.x.d ft0 -> a0 +fmv.d.x zero -> ft11 +fmv.x.w ft11 -> zero +fmv.w.x a0 -> ft0 test_fmv complete -fmadd.d 0x0 %ft0 %ft2 %ft3 -> %ft11 -fmsub.d 0x1 %ft11 %ft0 %ft3 -> %ft0 -fnmadd.d 0x2 %ft1 %ft11 %ft0 -> %ft0 -fnmsub.d 0x3 %ft1 %ft2 %ft11 -> %ft0 -fmadd.q 0x0 %ft0 %ft2 %ft3 -> %ft11 -fmsub.q 0x1 %ft11 %ft0 %ft3 -> %ft0 -fnmadd.q 0x2 %ft1 %ft11 %ft0 -> %ft0 -fnmsub.q 0x3 %ft1 %ft2 %ft11 -> %ft0 -fmadd.s 0x0 %ft0 %ft2 %ft3 -> %ft11 -fmsub.s 0x1 %ft11 %ft0 %ft3 -> %ft0 -fnmadd.s 0x2 %ft1 %ft11 %ft0 -> %ft0 -fnmsub.s 0x3 %ft1 %ft2 %ft11 -> %ft0 -fadd.d 0x4 %ft11 %ft2 -> %ft0 -fsub.d 0x7 %ft0 %ft0 -> %ft11 -fmul.d 0x0 %ft1 %ft11 -> %ft0 -fdiv.d 0x0 %ft1 %ft2 -> %ft0 -fadd.q 0x4 %ft1 %ft2 -> %ft0 -fsub.q 0x7 %ft11 %ft0 -> %ft11 -fmul.q 0x0 %ft0 %ft11 -> %ft0 -fdiv.q 0x0 %ft1 %ft2 -> %ft0 -fadd.s 0x4 %ft1 %ft2 -> %ft0 -fsub.s 0x7 %ft11 %ft0 -> %ft11 -fmul.s 0x0 %ft0 %ft11 -> %ft0 -fdiv.s 0x0 %ft1 %ft2 -> %ft0 -fsqrt.d 0x0 %ft11 -> %ft0 -fsqrt.q 0x0 %ft0 -> %ft11 -fsqrt.s 0x0 %ft1 -> %ft0 -fsqrt.d 0x0 %ft11 -> %ft0 -fsqrt.q 0x0 %ft0 -> %ft11 -fsqrt.s 0x0 %ft1 -> %ft0 -fsgnj.d %ft0 %ft11 -> %ft0 -fsgnjn.d %ft0 %ft0 -> %ft11 -fsgnjx.d %ft0 %ft1 -> %ft0 -fsgnj.q %ft0 %ft11 -> %ft0 -fsgnjn.q %ft0 %ft0 -> %ft11 -fsgnjx.q %ft0 %ft1 -> %ft0 -fsgnj.s %ft0 %ft11 -> %ft0 -fsgnjn.s %ft0 %ft0 -> %ft11 -fsgnjx.s %ft0 %ft1 -> %ft0 -fmax.d %ft11 %ft2 -> %ft0 -fmin.d %ft1 %ft0 -> %ft11 -fmax.q %ft0 %ft11 -> %ft0 -fmin.q %ft1 %ft2 -> %ft0 -fmax.s %ft1 %ft2 -> %ft0 -fmin.s %ft1 %ft2 -> %ft0 -fclass.d %ft1 -> %a0 -fclass.q %ft1 -> %a0 -fclass.s %ft1 -> %a0 +fmadd.d 0x0 ft0 ft2 ft3 -> ft11 +fmsub.d 0x1 ft11 ft0 ft3 -> ft0 +fnmadd.d 0x2 ft1 ft11 ft0 -> ft0 +fnmsub.d 0x3 ft1 ft2 ft11 -> ft0 +fmadd.q 0x0 ft0 ft2 ft3 -> ft11 +fmsub.q 0x1 ft11 ft0 ft3 -> ft0 +fnmadd.q 0x2 ft1 ft11 ft0 -> ft0 +fnmsub.q 0x3 ft1 ft2 ft11 -> ft0 +fmadd.s 0x0 ft0 ft2 ft3 -> ft11 +fmsub.s 0x1 ft11 ft0 ft3 -> ft0 +fnmadd.s 0x2 ft1 ft11 ft0 -> ft0 +fnmsub.s 0x3 ft1 ft2 ft11 -> ft0 +fadd.d 0x4 ft11 ft2 -> ft0 +fsub.d 0x7 ft0 ft0 -> ft11 +fmul.d 0x0 ft1 ft11 -> ft0 +fdiv.d 0x0 ft1 ft2 -> ft0 +fadd.q 0x4 ft1 ft2 -> ft0 +fsub.q 0x7 ft11 ft0 -> ft11 +fmul.q 0x0 ft0 ft11 -> ft0 +fdiv.q 0x0 ft1 ft2 -> ft0 +fadd.s 0x4 ft1 ft2 -> ft0 +fsub.s 0x7 ft11 ft0 -> ft11 +fmul.s 0x0 ft0 ft11 -> ft0 +fdiv.s 0x0 ft1 ft2 -> ft0 +fsqrt.d 0x0 ft11 -> ft0 +fsqrt.q 0x0 ft0 -> ft11 +fsqrt.s 0x0 ft1 -> ft0 +fsqrt.d 0x0 ft11 -> ft0 +fsqrt.q 0x0 ft0 -> ft11 +fsqrt.s 0x0 ft1 -> ft0 +fsgnj.d ft0 ft11 -> ft0 +fsgnjn.d ft0 ft0 -> ft11 +fsgnjx.d ft0 ft1 -> ft0 +fsgnj.q ft0 ft11 -> ft0 +fsgnjn.q ft0 ft0 -> ft11 +fsgnjx.q ft0 ft1 -> ft0 +fsgnj.s ft0 ft11 -> ft0 +fsgnjn.s ft0 ft0 -> ft11 +fsgnjx.s ft0 ft1 -> ft0 +fmax.d ft11 ft2 -> ft0 +fmin.d ft1 ft0 -> ft11 +fmax.q ft0 ft11 -> ft0 +fmin.q ft1 ft2 -> ft0 +fmax.s ft1 ft2 -> ft0 +fmin.s ft1 ft2 -> ft0 +fclass.d ft1 -> a0 +fclass.q ft1 -> a0 +fclass.s ft1 -> a0 test_float_arith complete -feq.d %ft0 %ft1 -> %a0 -flt.d %ft11 %ft11 -> %zero -flt.d %ft1 %ft0 -> %t6 -feq.q %ft1 %ft1 -> %a0 -flt.q %ft1 %ft1 -> %a0 -flt.q %ft1 %ft1 -> %a0 -feq.s %ft1 %ft1 -> %a0 -flt.s %ft1 %ft1 -> %a0 -flt.s %ft1 %ft1 -> %a0 +feq.d ft0 ft1 -> a0 +flt.d ft11 ft11 -> zero +flt.d ft1 ft0 -> t6 +feq.q ft1 ft1 -> a0 +flt.q ft1 ft1 -> a0 +flt.q ft1 ft1 -> a0 +feq.s ft1 ft1 -> a0 +flt.s ft1 ft1 -> a0 +flt.s ft1 ft1 -> a0 test_float_compare complete -hlv.b %a1 -> %a0 -hlv.bu %a1 -> %a0 -hlv.h %a1 -> %a0 -hlv.hu %a1 -> %a0 -hlvx.hu %a1 -> %a0 -hlv.w %a1 -> %a0 -hlv.wu %a1 -> %a0 -hlvx.wu %a1 -> %a0 -hlv.d %a1 -> %a0 -hsv.b %a0 %a1 -hsv.h %a0 %a1 -hsv.w %a0 %a1 -hsv.d %a0 %a1 -hinval.vvma %a0 %a1 -hinval.gvma %a0 %a1 -hfence.vvma %a0 %a1 -hfence.gvma %a0 %a1 +hlv.b a1 -> a0 +hlv.bu a1 -> a0 +hlv.h a1 -> a0 +hlv.hu a1 -> a0 +hlvx.hu a1 -> a0 +hlv.w a1 -> a0 +hlv.wu a1 -> a0 +hlvx.wu a1 -> a0 +hlv.d a1 -> a0 +hsv.b a0 a1 +hsv.h a0 a1 +hsv.w a0 a1 +hsv.d a0 a1 +hinval.vvma a0 a1 +hinval.gvma a0 a1 +hfence.vvma a0 a1 +hfence.gvma a0 a1 test_hypervisor complete -addi %a1 0 -> %a0 -addiw %a1 0 -> %a0 -slti %a1 -1 -> %a0 -sltiu %a1 2047 -> %a0 -xori %a1 2047 -> %a0 -ori %a1 2047 -> %a0 -andi %a1 2047 -> %a0 -slli %a1 63 -> %a0 -slliw %a1 31 -> %a0 -srli %a1 63 -> %a0 -srliw %a1 31 -> %a0 -srai %a1 63 -> %a0 -sraiw %a1 31 -> %a0 -add %a1 %a1 -> %a0 -addw %a1 %a1 -> %a0 -sub %a1 %a1 -> %a0 -subw %a1 %a1 -> %a0 -sll %a1 %a1 -> %a0 -sllw %a1 %a1 -> %a0 -slt %a1 %a1 -> %a0 -sltu %a1 %a1 -> %a0 -xor %a1 %a1 -> %a0 -srl %a1 %a1 -> %a0 -srlw %a1 %a1 -> %a0 -sra %a1 %a1 -> %a0 -sraw %a1 %a1 -> %a0 -or %a1 %a1 -> %a0 -and %a1 %a1 -> %a0 -mul %a1 %a1 -> %a0 -mulw %a1 %a1 -> %a0 -mulh %a1 %a1 -> %a0 -mulhsu %a1 %a1 -> %a0 -mulhu %a1 %a1 -> %a0 -div %a1 %a1 -> %a0 -divw %a1 %a1 -> %a0 -divu %a1 %a1 -> %a0 -divuw %a1 %a1 -> %a0 -rem %a1 %a1 -> %a0 -remw %a1 %a1 -> %a0 -remu %a1 %a1 -> %a0 -remuw %a1 %a1 -> %a0 -c.addiw 31 -> %a0 -c.addw %a1 -> %a0 -c.subw %a1 -> %a0 -c.slli 63 -> %a1 -c.srli 63 -> %a1 -c.srai 63 -> %a1 -c.andi -1 -> %a1 -c.mv %a1 -> %a1 -c.add %a1 -> %a1 -c.and %a5 -> %fp -c.or %a5 -> %fp -c.xor %a5 -> %fp -c.sub %a5 -> %fp +addi a1 0 -> a0 +addiw a1 0 -> a0 +slti a1 -1 -> a0 +sltiu a1 2047 -> a0 +xori a1 2047 -> a0 +ori a1 2047 -> a0 +andi a1 2047 -> a0 +slli a1 63 -> a0 +slliw a1 31 -> a0 +srli a1 63 -> a0 +srliw a1 31 -> a0 +srai a1 63 -> a0 +sraiw a1 31 -> a0 +add a1 a1 -> a0 +addw a1 a1 -> a0 +sub a1 a1 -> a0 +subw a1 a1 -> a0 +sll a1 a1 -> a0 +sllw a1 a1 -> a0 +slt a1 a1 -> a0 +sltu a1 a1 -> a0 +xor a1 a1 -> a0 +srl a1 a1 -> a0 +srlw a1 a1 -> a0 +sra a1 a1 -> a0 +sraw a1 a1 -> a0 +or a1 a1 -> a0 +and a1 a1 -> a0 +mul a1 a1 -> a0 +mulw a1 a1 -> a0 +mulh a1 a1 -> a0 +mulhsu a1 a1 -> a0 +mulhu a1 a1 -> a0 +div a1 a1 -> a0 +divw a1 a1 -> a0 +divu a1 a1 -> a0 +divuw a1 a1 -> a0 +rem a1 a1 -> a0 +remw a1 a1 -> a0 +remu a1 a1 -> a0 +remuw a1 a1 -> a0 +c.addiw 31 -> a0 +c.addw a1 -> a0 +c.subw a1 -> a0 +c.slli 63 -> a1 +c.srli 63 -> a1 +c.srai 63 -> a1 +c.andi -1 -> a1 +c.mv a1 -> a1 +c.add a1 -> a1 +c.and a5 -> fp +c.or a5 -> fp +c.xor a5 -> fp +c.sub a5 -> fp test_integer_arith complete -lui 0x2a -> %a0 -auipc 0x2a -> %a0 -c.li 31 -> %a1 -c.lui 1 -> %a1 -c.addi 31 -> %a1 +lui 0x2a -> a0 +auipc 0x2a -> a0 +c.li 31 -> a1 +c.lui 1 -> a1 +c.addi 31 -> a1 c.addi16sp 16 -c.addi4spn 4 -> %fp +c.addi4spn 4 -> fp test_jump_and_branch complete -csrrw %a1 0x42 -> %a0 -csrrs %a1 0x42 -> %a0 -csrrc %a1 0x42 -> %a0 -csrrwi 1 0x42 -> %a0 -csrrsi 1 0x42 -> %a0 -csrrci 1 0x42 -> %a0 +csrrw a1 0x42 -> a0 +csrrs a1 0x42 -> a0 +csrrc a1 0x42 -> a0 +csrrwi 1 0x42 -> a0 +csrrsi 1 0x42 -> a0 +csrrci 1 0x42 -> a0 test_csr complete -add.uw %a1 %a2 -> %a0 -sh1add %a1 %a2 -> %a0 -sh2add %a1 %a2 -> %a0 -sh3add %a1 %a2 -> %a0 -sh1add.uw %a1 %a2 -> %a0 -sh2add.uw %a1 %a2 -> %a0 -sh3add.uw %a1 %a2 -> %a0 -slli.uw %a1 63 -> %a0 -andn %a1 %a1 -> %a0 -orn %a1 %a1 -> %a0 -xnor %a1 %a1 -> %a0 -clz %a1 -> %a0 -clzw %a1 -> %a0 -ctz %a1 -> %a0 -ctzw %a1 -> %a0 -cpop %a1 -> %a0 -cpopw %a1 -> %a0 -max %a1 %a1 -> %a0 -maxu %a1 %a1 -> %a0 -min %a1 %a1 -> %a0 -minu %a1 %a1 -> %a0 -sext.b %a1 -> %a0 -sext.h %a1 -> %a0 -zext.h %a1 -> %a0 -rol %a1 %a1 -> %a0 -rolw %a1 %a1 -> %a0 -ror %a1 %a1 -> %a0 -rorw %a1 %a1 -> %a0 -rori %a1 63 -> %a0 -orc.b %a1 -> %a0 -clmul %a1 %a1 -> %a0 -clmulh %a1 %a1 -> %a0 -clmulr %a1 %a1 -> %a0 -rev8 %a1 -> %a0 -bclr %a1 %a1 -> %a0 -bclri %a1 63 -> %a0 -bext %a1 %a1 -> %a0 -bexti %a1 63 -> %a0 -binv %a1 %a1 -> %a0 -binvi %a1 63 -> %a0 -bset %a1 %a1 -> %a0 -bseti %a1 63 -> %a0 +add.uw a1 a2 -> a0 +sh1add a1 a2 -> a0 +sh2add a1 a2 -> a0 +sh3add a1 a2 -> a0 +sh1add.uw a1 a2 -> a0 +sh2add.uw a1 a2 -> a0 +sh3add.uw a1 a2 -> a0 +slli.uw a1 63 -> a0 +andn a1 a1 -> a0 +orn a1 a1 -> a0 +xnor a1 a1 -> a0 +clz a1 -> a0 +clzw a1 -> a0 +ctz a1 -> a0 +ctzw a1 -> a0 +cpop a1 -> a0 +cpopw a1 -> a0 +max a1 a1 -> a0 +maxu a1 a1 -> a0 +min a1 a1 -> a0 +minu a1 a1 -> a0 +sext.b a1 -> a0 +sext.h a1 -> a0 +zext.h a1 -> a0 +rol a1 a1 -> a0 +rolw a1 a1 -> a0 +ror a1 a1 -> a0 +rorw a1 a1 -> a0 +rori a1 63 -> a0 +orc.b a1 -> a0 +clmul a1 a1 -> a0 +clmulh a1 a1 -> a0 +clmulr a1 a1 -> a0 +rev8 a1 -> a0 +bclr a1 a1 -> a0 +bclri a1 63 -> a0 +bext a1 a1 -> a0 +bexti a1 63 -> a0 +binv a1 a1 -> a0 +binvi a1 63 -> a0 +bset a1 a1 -> a0 +bseti a1 63 -> a0 print_bit complete -prefetch.i -> +96(%zero) -prefetch.r -> +160(%t6) -prefetch.w -> (%a1) +prefetch.i -> +96(zero) +prefetch.r -> +160(t6) +prefetch.w -> (a1) test_prefetch complete c.nop c.ebreak @@ -291,13 +291,13 @@ mret wfi fence 0x0 0x0 0x0 fence.i -sfence.vma %a1 %a1 +sfence.vma a1 a1 sfence.w.inval -sinval.vma %a1 %a1 +sinval.vma a1 a1 sfence.inval.ir -cbo.zero (%a1) -cbo.clean (%a1) -cbo.flush (%a1) -cbo.inval (%a1) +cbo.zero (a1) +cbo.clean (a1) +cbo.flush (a1) +cbo.inval (a1) test_misc complete All tests complete From 4dc5fb5ebcab5db0f70080a3ebd3f4a404457d1f Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 13:15:15 +0800 Subject: [PATCH 28/34] Minor fixes --- core/ir/opnd_api.h | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index 2955bfeb24b..b77dbccf59f 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -1284,10 +1284,10 @@ enum { DR_REG_LAST_VALID_ENUM = DR_REG_FCSR, /**< Last valid register enum. */ DR_REG_LAST_ENUM = DR_REG_FCSR, /**< Last value of register enums. */ - DR_REG_START_64 = DR_REG_X0, /**< Start of 64-bit register enum values. */ - DR_REG_STOP_64 = DR_REG_F31, /**< End of 64-bit register enum values. */ - DR_REG_START_32 = DR_REG_X0, /**< Start of 32-bit register enum values. */ - DR_REG_STOP_32 = DR_REG_F31, /**< End of 32-bit register enum values. */ + DR_REG_START_64 = DR_REG_X0, /**< Start of 64-bit general register enum values. */ + DR_REG_STOP_64 = DR_REG_F31, /**< End of 64-bit general register enum values. */ + DR_REG_START_32 = DR_REG_X0, /**< Start of 32-bit general register enum values. */ + DR_REG_STOP_32 = DR_REG_F31, /**< End of 32-bit general register enum values. */ DR_REG_START_GPR = DR_REG_X0, /**< Start of general register registers. */ DR_REG_STOP_GPR = DR_REG_X31, /**< End of general register registers. */ DR_REG_XSP = DR_REG_SP, /**< Platform-independent way to refer to stack pointer. */ @@ -2014,7 +2014,7 @@ DR_API * Returns a signed immediate integer operand with value \p i and size * \p data_size; \p data_size must be a OPSZ_ constant. * - * The integer will be formatted as a decimal when disassemble. + * The integer will be formatted as a decimal when disassembled. */ opnd_t opnd_create_immed_int_decimal(ptr_int_t i, opnd_size_t data_size); @@ -2177,7 +2177,7 @@ DR_API * Both \p base_reg and \p index_reg must be DR_REG_ constants. * \p scale must be either 0, 1, 2, 4, or 8. * - * The integer will be formatted as a decimal when disassemble. + * The integer will be formatted as a decimal when disassembled. */ opnd_t opnd_create_base_disp_decimal(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, From f6aacbe145f8f671760d4f1639f4d0994937b3ea Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 13:29:19 +0800 Subject: [PATCH 29/34] Use opnd_add_flags instead --- core/ir/opnd_api.h | 32 ---- core/ir/opnd_shared.c | 21 -- core/ir/riscv64/codec.c | 64 +++++-- suite/tests/api/ir_riscv64.c | 359 ++++++++++++++++++++++------------- 4 files changed, 274 insertions(+), 202 deletions(-) diff --git a/core/ir/opnd_api.h b/core/ir/opnd_api.h index b77dbccf59f..31c6a9fd2e0 100644 --- a/core/ir/opnd_api.h +++ b/core/ir/opnd_api.h @@ -2008,18 +2008,6 @@ DR_API opnd_t opnd_create_immed_int(ptr_int_t i, opnd_size_t data_size); -#ifdef RISCV64 -DR_API -/** - * Returns a signed immediate integer operand with value \p i and size - * \p data_size; \p data_size must be a OPSZ_ constant. - * - * The integer will be formatted as a decimal when disassembled. - */ -opnd_t -opnd_create_immed_int_decimal(ptr_int_t i, opnd_size_t data_size); -#endif - DR_API /** * Returns an unsigned immediate integer operand with value \p i and size @@ -2164,26 +2152,6 @@ opnd_t opnd_create_base_disp(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, opnd_size_t data_size); -#ifdef RISCV64 -DR_API -/** - * Returns a memory reference operand that refers to the address: - * - disp(base_reg, index_reg, scale) - * - * or, in other words, - * - base_reg + index_reg*scale + disp - * - * The operand has data size data_size (must be a OPSZ_ constant). - * Both \p base_reg and \p index_reg must be DR_REG_ constants. - * \p scale must be either 0, 1, 2, 4, or 8. - * - * The integer will be formatted as a decimal when disassembled. - */ -opnd_t -opnd_create_base_disp_decimal(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, - opnd_size_t data_size); -#endif - DR_API /** * Returns a memory reference operand that refers to the address: diff --git a/core/ir/opnd_shared.c b/core/ir/opnd_shared.c index 7f3eee13391..8b9a0997ce6 100644 --- a/core/ir/opnd_shared.c +++ b/core/ir/opnd_shared.c @@ -374,16 +374,6 @@ opnd_create_immed_int(ptr_int_t i, opnd_size_t size) return opnd; } -#ifdef RISCV64 -opnd_t -opnd_create_immed_int_decimal(ptr_int_t i, opnd_size_t size) -{ - opnd_t opnd = opnd_create_immed_int(i, size); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; - return opnd; -} -#endif - opnd_t opnd_create_immed_uint(ptr_uint_t i, opnd_size_t size) { @@ -663,17 +653,6 @@ opnd_create_base_disp(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp false, false, false); } -#ifdef RISCV64 -opnd_t -opnd_create_base_disp_decimal(reg_id_t base_reg, reg_id_t index_reg, int scale, int disp, - opnd_size_t size) -{ - opnd_t opnd = opnd_create_base_disp(base_reg, index_reg, scale, disp, size); - opnd.aux.flags |= DR_OPND_IMM_PRINT_DECIMAL; - return opnd; -} -#endif - static inline void opnd_set_disp_helper(opnd_t *opnd, int disp) { diff --git a/core/ir/riscv64/codec.c b/core/ir/riscv64/codec.c index de0e2720628..69fa91db804 100644 --- a/core/ir/riscv64/codec.c +++ b/core/ir/riscv64/codec.c @@ -354,7 +354,8 @@ decode_shamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int idx, instr_t *out) { int32_t imm = GET_FIELD(inst, 25, 20); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -369,7 +370,8 @@ decode_shamt5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori int idx, instr_t *out) { int32_t imm = GET_FIELD(inst, 24, 20); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -385,7 +387,8 @@ decode_shamt6_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori { /* shamt6 >= 64 only makes sense on RV128 but let user take care of it. */ int32_t imm = GET_FIELD(inst, 26, 20); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -403,7 +406,8 @@ decode_i_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int idx, instr_t *out) { int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -422,7 +426,8 @@ decode_s_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig { int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | (GET_FIELD(inst, 11, 7)); imm = SIGN_EXTEND(imm, 12); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -677,7 +682,8 @@ decode_cshamt_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *ori int idx, instr_t *out) { int32_t imm = (BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -695,7 +701,8 @@ decode_csr_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or int idx, instr_t *out) { int32_t imm = GET_FIELD(inst, 19, 15); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -718,7 +725,8 @@ decode_caddi16sp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, imm |= (BIT(inst, 2) << 5); imm |= (BIT(inst, 6) << 4); imm = SIGN_EXTEND(imm, 10); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -738,7 +746,9 @@ decode_clwsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int32_t imm = GET_FIELD(inst, 3, 2) << 6; imm |= BIT(inst, 12) << 5; imm |= GET_FIELD(inst, 6, 4) << 2; - opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); + opnd_t opnd = + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -758,7 +768,9 @@ decode_cldsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int32_t imm = GET_FIELD(inst, 4, 2) << 6; imm |= BIT(inst, 12) << 5; imm |= GET_FIELD(inst, 6, 5) << 3; - opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); + opnd_t opnd = + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -794,7 +806,9 @@ decode_cswsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int idx, instr_t *out) { int32_t imm = (GET_FIELD(inst, 8, 7) << 6) | (GET_FIELD(inst, 12, 9) << 2); - opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4); + opnd_t opnd = + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_dst(out, idx, opnd); return true; } @@ -812,7 +826,9 @@ decode_csdsp_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte * int idx, instr_t *out) { int32_t imm = (GET_FIELD(inst, 9, 7) << 6) | (GET_FIELD(inst, 12, 10) << 3); - opnd_t opnd = opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8); + opnd_t opnd = + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, imm, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_dst(out, idx, opnd); return true; } @@ -833,7 +849,8 @@ decode_ciw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or imm |= GET_FIELD(inst, 12, 11) << 4; imm |= BIT(inst, 5) << 3; imm |= BIT(inst, 6) << 2; - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -855,7 +872,8 @@ decode_clw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or int32_t imm = BIT(inst, 5) << 6; imm |= GET_FIELD(inst, 12, 10) << 3; imm |= BIT(inst, 6) << 2; - opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_4); + opnd_t opnd = opnd_add_flags(opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -875,7 +893,8 @@ decode_cld_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or { reg_t reg = DR_REG_X8 + GET_FIELD(inst, 9, 7); int32_t imm = (GET_FIELD(inst, 6, 5) << 6) | (GET_FIELD(inst, 12, 10) << 3); - opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_8); + opnd_t opnd = opnd_add_flags(opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -897,7 +916,8 @@ decode_csw_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or int32_t imm = BIT(inst, 5) << 6; imm |= GET_FIELD(inst, 12, 10) << 3; imm |= BIT(inst, 6) << 2; - opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_4); + opnd_t opnd = opnd_add_flags(opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_dst(out, idx, opnd); return true; } @@ -917,7 +937,8 @@ decode_csd_imm_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *or { reg_t reg = DR_REG_X8 + GET_FIELD(inst, 9, 7); int32_t imm = (GET_FIELD(inst, 6, 5) << 6) | (GET_FIELD(inst, 12, 10) << 3); - opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, OPSZ_8); + opnd_t opnd = opnd_add_flags(opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_dst(out, idx, opnd); return true; } @@ -935,7 +956,8 @@ decode_cimm5_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, byte *orig int idx, instr_t *out) { int32_t imm = SIGN_EXTEND((BIT(inst, 12) << 5) | GET_FIELD(inst, 6, 2), 6); - opnd_t opnd = opnd_create_immed_int_decimal(imm, op_sz); + opnd_t opnd = + opnd_add_flags(opnd_create_immed_int(imm, op_sz), DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -1008,7 +1030,8 @@ decode_v_l_rs1_disp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, { reg_t reg = DR_REG_X0 + GET_FIELD(inst, 19, 15); int32_t imm = SIGN_EXTEND(GET_FIELD(inst, 31, 20), 12); - opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, op_sz); + opnd_t opnd = opnd_add_flags(opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, op_sz), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_src(out, idx, opnd); return true; } @@ -1031,7 +1054,8 @@ decode_v_s_rs1_disp_opnd(dcontext_t *dc, uint32_t inst, int op_sz, byte *pc, reg_t reg = DR_REG_X0 + GET_FIELD(inst, 19, 15); int32_t imm = (GET_FIELD(inst, 31, 25) << 5) | GET_FIELD(inst, 11, 7); imm = SIGN_EXTEND(imm, 12); - opnd_t opnd = opnd_create_base_disp_decimal(reg, DR_REG_NULL, 0, imm, op_sz); + opnd_t opnd = opnd_add_flags(opnd_create_base_disp(reg, DR_REG_NULL, 0, imm, op_sz), + DR_OPND_IMM_PRINT_DECIMAL); instr_set_dst(out, idx, opnd); return true; } diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index d55ff066bd3..43ed07309d7 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -110,91 +110,120 @@ test_integer_load_store(void *dc) /* Load */ instr = INSTR_CREATE_lb( dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_1)); + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_1), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_lb, instr); instr = INSTR_CREATE_lbu( dc, opnd_create_reg(DR_REG_X0), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, -1, OPSZ_1)); + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, -1, OPSZ_1), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_lbu, instr); - instr = INSTR_CREATE_lh( - dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_2)); + instr = + INSTR_CREATE_lh(dc, opnd_create_reg(DR_REG_A0), + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, + (1 << 11) - 1, OPSZ_2), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_lh, instr); instr = INSTR_CREATE_lhu( dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, 0, OPSZ_2)); + opnd_add_flags(opnd_create_base_disp(DR_REG_X0, DR_REG_NULL, 0, 0, OPSZ_2), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_lhu, instr); instr = INSTR_CREATE_lw( dc, opnd_create_reg(DR_REG_X31), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, -1, OPSZ_4)); + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, -1, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_lw, instr); instr = INSTR_CREATE_lwu( dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, 0, OPSZ_4)); + opnd_add_flags(opnd_create_base_disp(DR_REG_X31, DR_REG_NULL, 0, 0, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_lwu, instr); instr = INSTR_CREATE_ld( dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 42, OPSZ_8)); + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 42, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_ld, instr); /* Store */ instr = INSTR_CREATE_sb( - dc, opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_1), + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_1), + DR_OPND_IMM_PRINT_DECIMAL), opnd_create_reg(DR_REG_A0)); test_instr_encoding(dc, OP_sb, instr); instr = INSTR_CREATE_sh( - dc, opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_2), + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_2), + DR_OPND_IMM_PRINT_DECIMAL), opnd_create_reg(DR_REG_X31)); test_instr_encoding(dc, OP_sh, instr); - instr = INSTR_CREATE_sw( - dc, - opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_4), - opnd_create_reg(DR_REG_X0)); + instr = + INSTR_CREATE_sw(dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X31, DR_REG_NULL, 0, + (1 << 11) - 1, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_X0)); test_instr_encoding(dc, OP_sw, instr); instr = INSTR_CREATE_sd( - dc, opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 42, OPSZ_8), + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 42, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL), opnd_create_reg(DR_REG_A0)); test_instr_encoding(dc, OP_sd, instr); /* Compressed Load */ instr = INSTR_CREATE_c_ldsp( dc, opnd_create_reg(DR_REG_A0), - opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8)); + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_ldsp, instr); - instr = INSTR_CREATE_c_ld(dc, opnd_create_reg(DR_REG_X8), - opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, - ((1 << 5) - 1) << 3, OPSZ_8)); + instr = INSTR_CREATE_c_ld( + dc, opnd_create_reg(DR_REG_X8), + opnd_add_flags(opnd_create_base_disp(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_ld, instr); - instr = - INSTR_CREATE_c_lwsp(dc, opnd_create_reg(DR_REG_X0), - opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, - ((1 << 5) - 1) << 2, OPSZ_4)); + instr = INSTR_CREATE_c_lwsp( + dc, opnd_create_reg(DR_REG_X0), + opnd_add_flags( + opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, ((1 << 5) - 1) << 2, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_lwsp, instr); - instr = INSTR_CREATE_c_lw(dc, opnd_create_reg(DR_REG_X8), - opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, - ((1 << 5) - 1) << 2, OPSZ_4)); + instr = INSTR_CREATE_c_lw( + dc, opnd_create_reg(DR_REG_X8), + opnd_add_flags(opnd_create_base_disp(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 2, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_lw, instr); /* Compressed Store */ instr = INSTR_CREATE_c_sdsp( - dc, opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL), opnd_create_reg(DR_REG_A0)); test_instr_encoding(dc, OP_c_sdsp, instr); - instr = INSTR_CREATE_c_sd(dc, - opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, - ((1 << 5) - 1) << 3, OPSZ_8), - opnd_create_reg(DR_REG_X8)); + instr = INSTR_CREATE_c_sd( + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_X8)); test_instr_encoding(dc, OP_c_sd, instr); - instr = - INSTR_CREATE_c_swsp(dc, - opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, - ((1 << 5) - 1) << 2, OPSZ_4), - opnd_create_reg(DR_REG_X0)); + instr = INSTR_CREATE_c_swsp( + dc, + opnd_add_flags( + opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, ((1 << 5) - 1) << 2, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_X0)); test_instr_encoding(dc, OP_c_swsp, instr); - instr = INSTR_CREATE_c_sw(dc, - opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, - ((1 << 5) - 1) << 2, OPSZ_4), - opnd_create_reg(DR_REG_X8)); + instr = INSTR_CREATE_c_sw( + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 2, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_X8)); test_instr_encoding(dc, OP_c_sw, instr); } @@ -205,51 +234,66 @@ test_float_load_store(void *dc) instr = INSTR_CREATE_flw( dc, opnd_create_reg(DR_REG_F0), - opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_4)); + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_flw, instr); instr = INSTR_CREATE_fld( dc, opnd_create_reg(DR_REG_F31), - opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_8)); + opnd_add_flags(opnd_create_base_disp(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_fld, instr); instr = INSTR_CREATE_flq( dc, opnd_create_reg(DR_REG_F31), - opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_16)); + opnd_add_flags(opnd_create_base_disp(DR_REG_X0, DR_REG_NULL, 0, -1, OPSZ_16), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_flq, instr); - instr = INSTR_CREATE_fsw( - dc, - opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_4), - opnd_create_reg(DR_REG_F1)); + instr = + INSTR_CREATE_fsw(dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X31, DR_REG_NULL, 0, + (1 << 11) - 1, OPSZ_4), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_F1)); test_instr_encoding(dc, OP_fsw, instr); - instr = INSTR_CREATE_fsd( - dc, - opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_8), - opnd_create_reg(DR_REG_F31)); + instr = + INSTR_CREATE_fsd(dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X31, DR_REG_NULL, 0, + (1 << 11) - 1, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_F31)); test_instr_encoding(dc, OP_fsd, instr); - instr = INSTR_CREATE_fsq( - dc, - opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, (1 << 11) - 1, OPSZ_16), - opnd_create_reg(DR_REG_F31)); + instr = + INSTR_CREATE_fsq(dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X31, DR_REG_NULL, 0, + (1 << 11) - 1, OPSZ_16), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_F31)); test_instr_encoding(dc, OP_fsq, instr); /* Compressed */ instr = INSTR_CREATE_c_fldsp( dc, opnd_create_reg(DR_REG_F0), - opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8)); + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_fldsp, instr); - instr = - INSTR_CREATE_c_fld(dc, opnd_create_reg(DR_REG_F8), - opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, - ((1 << 5) - 1) << 3, OPSZ_8)); + instr = INSTR_CREATE_c_fld( + dc, opnd_create_reg(DR_REG_F8), + opnd_add_flags(opnd_create_base_disp(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_fld, instr); /* There is no c.flw* instructions in RV64. */ instr = INSTR_CREATE_c_fsdsp( - dc, opnd_create_base_disp_decimal(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_SP, DR_REG_NULL, 0, 0, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL), opnd_create_reg(DR_REG_F31)); test_instr_encoding(dc, OP_c_fsdsp, instr); - instr = INSTR_CREATE_c_fsd(dc, - opnd_create_base_disp_decimal(DR_REG_X15, DR_REG_NULL, 0, - ((1 << 5) - 1) << 3, OPSZ_8), - opnd_create_reg(DR_REG_F8)); + instr = INSTR_CREATE_c_fsd( + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X15, DR_REG_NULL, 0, + ((1 << 5) - 1) << 3, OPSZ_8), + DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_reg(DR_REG_F8)); test_instr_encoding(dc, OP_c_fsd, instr); /* There is no c.fsw* instructions in RV64. */ } @@ -817,44 +861,64 @@ static void test_integer(void *dc) { instr_t *instr; - instr = INSTR_CREATE_addi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal(0, OPSZ_12b)); + instr = INSTR_CREATE_addi( + dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int(0, OPSZ_12b), DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_addi, instr); - instr = INSTR_CREATE_addiw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal(0, OPSZ_12b)); + instr = INSTR_CREATE_addiw( + dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int(0, OPSZ_12b), DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_addiw, instr); - instr = INSTR_CREATE_slti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal(-1, OPSZ_12b)); + instr = INSTR_CREATE_slti( + dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int(-1, OPSZ_12b), DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_slti, instr); - instr = INSTR_CREATE_sltiu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + instr = + INSTR_CREATE_sltiu(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 11) - 1, OPSZ_12b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_sltiu, instr); - instr = INSTR_CREATE_xori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + instr = + INSTR_CREATE_xori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 11) - 1, OPSZ_12b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_xori, instr); - instr = INSTR_CREATE_ori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + instr = + INSTR_CREATE_ori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 11) - 1, OPSZ_12b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_ori, instr); - instr = INSTR_CREATE_andi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 11) - 1, OPSZ_12b)); + instr = + INSTR_CREATE_andi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 11) - 1, OPSZ_12b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_andi, instr); instr = INSTR_CREATE_slli(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_slli, instr); - instr = INSTR_CREATE_slliw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + instr = + INSTR_CREATE_slliw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_slliw, instr); instr = INSTR_CREATE_srli(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_srli, instr); - instr = INSTR_CREATE_srliw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + instr = + INSTR_CREATE_srliw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_srliw, instr); instr = INSTR_CREATE_srai(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_srai, instr); - instr = INSTR_CREATE_sraiw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + instr = + INSTR_CREATE_sraiw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_sraiw, instr); instr = INSTR_CREATE_add(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), @@ -944,8 +1008,10 @@ test_integer(void *dc) test_instr_encoding(dc, OP_remuw, instr); /* Compressed */ - instr = INSTR_CREATE_c_addiw(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + instr = + INSTR_CREATE_c_addiw(dc, opnd_create_reg(DR_REG_A0), + opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_addiw, instr); instr = INSTR_CREATE_c_addw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); @@ -954,17 +1020,24 @@ test_integer(void *dc) INSTR_CREATE_c_subw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); test_instr_encoding(dc, OP_c_subw, instr); - instr = INSTR_CREATE_c_slli(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_c_slli(dc, opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_slli, instr); - instr = INSTR_CREATE_c_srli(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_c_srli(dc, opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_srli, instr); - instr = INSTR_CREATE_c_srai(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_c_srai(dc, opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_srai, instr); - instr = INSTR_CREATE_c_andi(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal(-1, OPSZ_6b)); + instr = INSTR_CREATE_c_andi( + dc, opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int(-1, OPSZ_6b), DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_andi, instr); instr = INSTR_CREATE_c_mv(dc, opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); @@ -1037,20 +1110,29 @@ test_jump_and_branch(void *dc) instr = INSTR_CREATE_c_bnez(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); test_instr_encoding_branch(dc, OP_c_bnez, instr); instr = INSTR_CREATE_c_li(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_li, instr); /* FIXME i#3544: Need to be better formatted. */ - instr = INSTR_CREATE_c_lui(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal(1, OPSZ_6b)); + instr = INSTR_CREATE_c_lui( + dc, opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int(1, OPSZ_6b), DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_lui, instr); - instr = INSTR_CREATE_c_addi(dc, opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 5) - 1, OPSZ_5b)); + instr = + INSTR_CREATE_c_addi(dc, opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_addi, instr); - instr = INSTR_CREATE_c_addi16sp(dc, opnd_create_immed_int_decimal(1 << 4, OPSZ_10b)); + instr = + INSTR_CREATE_c_addi16sp(dc, + opnd_add_flags(opnd_create_immed_int(1 << 4, OPSZ_10b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_addi16sp, instr); - instr = INSTR_CREATE_c_addi4spn(dc, opnd_create_reg(DR_REG_X8), - opnd_create_immed_int_decimal(1 << 2, OPSZ_10b)); + instr = + INSTR_CREATE_c_addi4spn(dc, opnd_create_reg(DR_REG_X8), + opnd_add_flags(opnd_create_immed_int(1 << 2, OPSZ_10b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_c_addi4spn, instr); } @@ -1067,17 +1149,20 @@ test_csr(void *dc) instr = INSTR_CREATE_csrrc(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_immed_int(0x42, OPSZ_12b)); test_instr_encoding(dc, OP_csrrc, instr); - instr = INSTR_CREATE_csrrwi(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int_decimal(1, OPSZ_5b), - opnd_create_immed_int(0x42, OPSZ_12b)); + instr = INSTR_CREATE_csrrwi( + dc, opnd_create_reg(DR_REG_A0), + opnd_add_flags(opnd_create_immed_int(1, OPSZ_5b), DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_immed_int(0x42, OPSZ_12b)); test_instr_encoding(dc, OP_csrrwi, instr); - instr = INSTR_CREATE_csrrsi(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int_decimal(1, OPSZ_5b), - opnd_create_immed_int(0x42, OPSZ_12b)); + instr = INSTR_CREATE_csrrsi( + dc, opnd_create_reg(DR_REG_A0), + opnd_add_flags(opnd_create_immed_int(1, OPSZ_5b), DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_immed_int(0x42, OPSZ_12b)); test_instr_encoding(dc, OP_csrrsi, instr); - instr = INSTR_CREATE_csrrci(dc, opnd_create_reg(DR_REG_A0), - opnd_create_immed_int_decimal(1, OPSZ_5b), - opnd_create_immed_int(0x42, OPSZ_12b)); + instr = INSTR_CREATE_csrrci( + dc, opnd_create_reg(DR_REG_A0), + opnd_add_flags(opnd_create_immed_int(1, OPSZ_5b), DR_OPND_IMM_PRINT_DECIMAL), + opnd_create_immed_int(0x42, OPSZ_12b)); test_instr_encoding(dc, OP_csrrci, instr); } @@ -1111,7 +1196,8 @@ test_bit(void *dc) test_instr_encoding(dc, OP_sh3add_uw, instr); instr = INSTR_CREATE_slli_uw(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_slli_uw, instr); instr = INSTR_CREATE_andn(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), @@ -1170,7 +1256,8 @@ test_bit(void *dc) opnd_create_reg(DR_REG_A1)); test_instr_encoding(dc, OP_rorw, instr); instr = INSTR_CREATE_rori(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_rori, instr); instr = INSTR_CREATE_orc_b(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); @@ -1189,26 +1276,34 @@ test_bit(void *dc) instr = INSTR_CREATE_bclr(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); test_instr_encoding(dc, OP_bclr, instr); - instr = INSTR_CREATE_bclri(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_bclri(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_bclri, instr); instr = INSTR_CREATE_bext(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); test_instr_encoding(dc, OP_bext, instr); - instr = INSTR_CREATE_bexti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_bexti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_bexti, instr); instr = INSTR_CREATE_binv(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); test_instr_encoding(dc, OP_binv, instr); - instr = INSTR_CREATE_binvi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_binvi(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_binvi, instr); instr = INSTR_CREATE_bset(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_reg(DR_REG_A1)); test_instr_encoding(dc, OP_bset, instr); - instr = INSTR_CREATE_bseti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), - opnd_create_immed_int_decimal((1 << 6) - 1, OPSZ_6b)); + instr = + INSTR_CREATE_bseti(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), + opnd_add_flags(opnd_create_immed_int((1 << 6) - 1, OPSZ_6b), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_bseti, instr); } @@ -1217,13 +1312,19 @@ test_prefetch(void *dc) { instr_t *instr; instr = INSTR_CREATE_prefetch_i( - dc, opnd_create_base_disp_decimal(DR_REG_X0, DR_REG_NULL, 0, 3 << 5, OPSZ_0)); + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X0, DR_REG_NULL, 0, 3 << 5, OPSZ_0), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_prefetch_i, instr); instr = INSTR_CREATE_prefetch_r( - dc, opnd_create_base_disp_decimal(DR_REG_X31, DR_REG_NULL, 0, 5 << 5, OPSZ_0)); + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_X31, DR_REG_NULL, 0, 5 << 5, OPSZ_0), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_prefetch_r, instr); instr = INSTR_CREATE_prefetch_w( - dc, opnd_create_base_disp_decimal(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0)); + dc, + opnd_add_flags(opnd_create_base_disp(DR_REG_A1, DR_REG_NULL, 0, 0, OPSZ_0), + DR_OPND_IMM_PRINT_DECIMAL)); test_instr_encoding(dc, OP_prefetch_w, instr); } From b127d66452df89e4ec84e81d7c04bbd09cf5937f Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 13:43:11 +0800 Subject: [PATCH 30/34] Added comments --- core/unix/os.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/core/unix/os.c b/core/unix/os.c index ac91ba57951..b9ee8e3500e 100644 --- a/core/unix/os.c +++ b/core/unix/os.c @@ -767,6 +767,9 @@ our_init(int argc, char **argv, char **envp) * like the app's exe or unit_tests, we add a pointer to our_init() to the * .init_array section. We can't use the constructor attribute because not all * toolchains pass the args and environment to the constructor. + * + * RISC-V, as a new ISA, does not support obsolete .init section, so we always use + * .init_array section for RISC-V. */ static init_fn_t # ifdef MACOS From 9b7072f023b6b424c6c770cc8e461f74876d1df9 Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 14:00:13 +0800 Subject: [PATCH 31/34] Minor fixes --- suite/runsuite.cmake | 1 + suite/tests/CMakeLists.txt | 2 +- suite/tests/api/ir_riscv64.c | 48 ++++++++++++++++++++++-------------- 3 files changed, 32 insertions(+), 19 deletions(-) diff --git a/suite/runsuite.cmake b/suite/runsuite.cmake index 9c498c3c97d..b7110f8349d 100644 --- a/suite/runsuite.cmake +++ b/suite/runsuite.cmake @@ -555,6 +555,7 @@ endif () if (ARCH_IS_X86 AND UNIX) # TODO i#3544: Run tests under QEMU set(orig_extra_ctest_args ${extra_ctest_args}) + # TODO i#3544: Get all the tests working. set(extra_ctest_args INCLUDE_LABEL RISCV64) set(prev_optional_cross_compile ${optional_cross_compile}) set(prev_run_tests ${run_tests}) diff --git a/suite/tests/CMakeLists.txt b/suite/tests/CMakeLists.txt index ea77e1e659b..8d533b95757 100644 --- a/suite/tests/CMakeLists.txt +++ b/suite/tests/CMakeLists.txt @@ -5591,4 +5591,4 @@ if (RISCV64) code_api|api.ir code_api|api.ir-static PROPERTIES LABELS RISCV64) -endif () \ No newline at end of file +endif () diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index 43ed07309d7..ad40d0ef8d2 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -66,15 +66,17 @@ static byte * test_instr_encoding(void *dc, uint opcode, instr_t *instr) { instr_t *decin; - byte *pc; + byte *pc, next_pc; ASSERT(instr_get_opcode(instr) == opcode); instr_disassemble(dc, instr, STDERR); print("\n"); ASSERT(instr_is_encoding_possible(instr)); pc = instr_encode(dc, instr, buf); + ASSERT(pc != NULL); decin = instr_create(dc); - decode(dc, buf, decin); + next_pc = decode(dc, buf, decin); + ASSERT(next_pc != NULL); if (!instr_same(instr, decin)) { print("Disassembled as:\n"); instr_disassemble(dc, decin, STDERR); @@ -88,15 +90,25 @@ test_instr_encoding(void *dc, uint opcode, instr_t *instr) } static void -test_instr_encoding_branch(void *dc, uint opcode, instr_t *instr) +test_instr_encoding_jump_or_branch(void *dc, uint opcode, instr_t *instr) { + /* XXX i#3544: For jump and branch instructions, current disassembler will print + * the complete jump address, that is, a address relative to `buf`. But the + * value of `buf` is indeterminate at runtime, so we skip checking the disassembled + * format for jump and branch instructions. + * + * FIXME i#3544: For branch instructions, we should use relative offsets instead. + */ instr_t *decin; + byte *pc, next_pc; ASSERT(instr_get_opcode(instr) == opcode); ASSERT(instr_is_encoding_possible(instr)); - instr_encode(dc, instr, buf); + pc = instr_encode(dc, instr, buf); + ASSERT(pc != NULL); decin = instr_create(dc); - decode(dc, buf, decin); + next_pc = decode(dc, buf, decin); + ASSERT(next_pc != NULL); ASSERT(instr_same(instr, decin)); instr_destroy(dc, instr); instr_destroy(dc, decin); @@ -1073,42 +1085,42 @@ test_jump_and_branch(void *dc) opnd_create_immed_int(42, OPSZ_20b)); test_instr_encoding(dc, OP_auipc, instr); instr = INSTR_CREATE_jal(dc, opnd_create_reg(DR_REG_A0), opnd_create_pc(pc)); - test_instr_encoding_branch(dc, OP_jal, instr); + test_instr_encoding_jump_or_branch(dc, OP_jal, instr); instr = INSTR_CREATE_jalr(dc, opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1), opnd_create_immed_int(42, OPSZ_12b)); - test_instr_encoding_branch(dc, OP_jalr, instr); + test_instr_encoding_jump_or_branch(dc, OP_jalr, instr); instr = INSTR_CREATE_beq(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding_branch(dc, OP_beq, instr); + test_instr_encoding_jump_or_branch(dc, OP_beq, instr); instr = INSTR_CREATE_bne(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding_branch(dc, OP_bne, instr); + test_instr_encoding_jump_or_branch(dc, OP_bne, instr); instr = INSTR_CREATE_blt(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding_branch(dc, OP_blt, instr); + test_instr_encoding_jump_or_branch(dc, OP_blt, instr); instr = INSTR_CREATE_bge(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding_branch(dc, OP_bge, instr); + test_instr_encoding_jump_or_branch(dc, OP_bge, instr); instr = INSTR_CREATE_bltu(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding_branch(dc, OP_bltu, instr); + test_instr_encoding_jump_or_branch(dc, OP_bltu, instr); instr = INSTR_CREATE_bgeu(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_A0), opnd_create_reg(DR_REG_A1)); - test_instr_encoding_branch(dc, OP_bgeu, instr); + test_instr_encoding_jump_or_branch(dc, OP_bgeu, instr); /* Compressed */ instr = INSTR_CREATE_c_j(dc, opnd_create_pc(pc)); - test_instr_encoding_branch(dc, OP_c_j, instr); + test_instr_encoding_jump_or_branch(dc, OP_c_j, instr); instr = INSTR_CREATE_c_jr(dc, opnd_create_reg(DR_REG_A0)); - test_instr_encoding_branch(dc, OP_c_jr, instr); + test_instr_encoding_jump_or_branch(dc, OP_c_jr, instr); /* There is no c.jal in RV64. */ instr = INSTR_CREATE_c_jalr(dc, opnd_create_reg(DR_REG_A0)); - test_instr_encoding_branch(dc, OP_c_jalr, instr); + test_instr_encoding_jump_or_branch(dc, OP_c_jalr, instr); instr = INSTR_CREATE_c_beqz(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); - test_instr_encoding_branch(dc, OP_c_beqz, instr); + test_instr_encoding_jump_or_branch(dc, OP_c_beqz, instr); instr = INSTR_CREATE_c_bnez(dc, opnd_create_pc(pc), opnd_create_reg(DR_REG_X8)); - test_instr_encoding_branch(dc, OP_c_bnez, instr); + test_instr_encoding_jump_or_branch(dc, OP_c_bnez, instr); instr = INSTR_CREATE_c_li(dc, opnd_create_reg(DR_REG_A1), opnd_add_flags(opnd_create_immed_int((1 << 5) - 1, OPSZ_5b), DR_OPND_IMM_PRINT_DECIMAL)); From 746285cc792b5f608bd81a575cb89f285ce2cf2a Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 14:03:30 +0800 Subject: [PATCH 32/34] Removed trailling spaces --- api/docs/bt.dox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/api/docs/bt.dox b/api/docs/bt.dox index 88188d19d7f..78a6697a400 100644 --- a/api/docs/bt.dox +++ b/api/docs/bt.dox @@ -732,7 +732,7 @@ disassemble_from_copy(), and disassemble_to_buffer(). The style of disassembly can be controlled through the \ref op_syntax_intel "-syntax_intel" (for Intel-style disassembly), \ref op_syntax_att "-syntax_att" (for AT&T-style disassembly), -\ref op_syntax_arm "-syntax_arm" (for ARM-style disassembly), and +\ref op_syntax_arm "-syntax_arm" (for ARM-style disassembly), and \ref op_syntax_riscv "-syntax_riscv" (for RISC-V-style disassembly) runtime options, or the disassemble_set_syntax() function. The default disassembly style is DynamoRIO's custom style, which lists all operands (both implicit From 2d92a74206c779ab2ebd79d7fc84b663de244a5f Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Wed, 21 Jun 2023 14:19:47 +0800 Subject: [PATCH 33/34] Fixed a typo --- suite/tests/api/ir_riscv64.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index ad40d0ef8d2..d32f9071e4f 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -66,7 +66,7 @@ static byte * test_instr_encoding(void *dc, uint opcode, instr_t *instr) { instr_t *decin; - byte *pc, next_pc; + byte *pc, *next_pc; ASSERT(instr_get_opcode(instr) == opcode); instr_disassemble(dc, instr, STDERR); @@ -100,7 +100,7 @@ test_instr_encoding_jump_or_branch(void *dc, uint opcode, instr_t *instr) * FIXME i#3544: For branch instructions, we should use relative offsets instead. */ instr_t *decin; - byte *pc, next_pc; + byte *pc, *next_pc; ASSERT(instr_get_opcode(instr) == opcode); ASSERT(instr_is_encoding_possible(instr)); From 38927e83fa083295f391ca9b79cdc139be26efcc Mon Sep 17 00:00:00 2001 From: Yang Liu Date: Thu, 22 Jun 2023 02:10:52 +0000 Subject: [PATCH 34/34] Fixed a typo --- suite/tests/api/ir_riscv64.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/suite/tests/api/ir_riscv64.c b/suite/tests/api/ir_riscv64.c index d32f9071e4f..8e1d7005504 100644 --- a/suite/tests/api/ir_riscv64.c +++ b/suite/tests/api/ir_riscv64.c @@ -93,7 +93,7 @@ static void test_instr_encoding_jump_or_branch(void *dc, uint opcode, instr_t *instr) { /* XXX i#3544: For jump and branch instructions, current disassembler will print - * the complete jump address, that is, a address relative to `buf`. But the + * the complete jump address, that is, an address relative to `buf`. But the * value of `buf` is indeterminate at runtime, so we skip checking the disassembled * format for jump and branch instructions. *