From 6841e87e31c51c92f5aeb86ac8033ed53bd67a45 Mon Sep 17 00:00:00 2001 From: "max.ma" Date: Tue, 6 Dec 2022 23:05:47 -0800 Subject: [PATCH 7/7] add customer pref insn support --- gas/config/tc-riscv.c | 42 ++++++++++++++++++++++++++++++++++++++ include/opcode/riscv-opc.h | 1 + include/opcode/riscv.h | 9 ++++++++ opcodes/riscv-dis.c | 7 +++++++ opcodes/riscv-opc.c | 1 + 5 files changed, 60 insertions(+) diff --git a/gas/config/tc-riscv.c b/gas/config/tc-riscv.c index bb5f6e4aed..5112322c4a 100644 --- a/gas/config/tc-riscv.c +++ b/gas/config/tc-riscv.c @@ -1154,6 +1154,8 @@ validate_riscv_insn (const struct riscv_opcode *opc, int length) case ')': break; case '<': USE_BITS (OP_MASK_SHAMTW, OP_SH_SHAMTW); break; case '>': USE_BITS (OP_MASK_SHAMT, OP_SH_SHAMT); break; + case '#': used_bits |= ENCODE_PREF_TIMM (-1U); break; + case '+': used_bits |= ENCODE_PREF_SIMM (-1U); break; case 'A': break; /* Macro operand, must be symbol. */ case 'B': break; /* Macro operand, must be symbol or constant. */ case 'I': break; /* Macro operand, must be constant. */ @@ -1553,6 +1555,27 @@ check_absolute_expr (struct riscv_cl_insn *ip, expressionS *ex, normalize_constant_expr (ex); } +/* The pref type should be one of the following: + 0000 - scalar prefetch L1, fetch data as if for a normal scalar load, + and imply load into all lower cache destination levels. + 0001 - scalar prefetch L2, fetch data and place the cache-line into L2, + and imply load into all lower cache destination levels. + 0010 - scalar prefetch L3, fetch data and place the cache-line into L3, + and imply load into all lower cache destination levels. + 0011 - scalar prefetch L4, fetch data and place the cache-line into L4, + and imply load into all lower cache destination levels + (if the L5 is in the cache heirarchy). + 1000 - vector prefetch L1, fetch data as if for a normal scalar load + but place the cache-line into vector buffer (vector L1) , + and imply load into all lower cache destination levels. +*/ + +static bfd_boolean check_pref_type(unsigned long type) +{ + if (type != 0 && type != 1 && type != 2 && type != 3 && type != 8) + as_bad (_("Improper pref type (%lu)"), type); +} + static symbolS * make_internal_label (void) { @@ -2850,6 +2873,25 @@ riscv_ip (char *str, struct riscv_cl_insn *ip, expressionS *imm_expr, asarg = expr_end; continue; + case '#': + my_getExpression (imm_expr, asarg); + check_pref_type((unsigned long)imm_expr->X_add_number); + INSERT_OPERAND (PREF_TYPE, *ip, imm_expr->X_add_number); + imm_expr->X_op = O_absent; + asarg = expr_end; + continue; + + case '+': + my_getExpression (imm_expr, asarg); + check_absolute_expr (ip, imm_expr, FALSE); + if (imm_expr->X_add_number > 127 || imm_expr->X_add_number < -128) + as_bad (_("Improper pref offset value (%d)"), + (long) imm_expr->X_add_number); + INSERT_OPERAND (PREF_OFFSET, *ip, imm_expr->X_add_number); + imm_expr->X_op = O_absent; + asarg = expr_end; + continue; + case 'E': /* Control register. */ insn_with_csr = true; explicit_priv_attr = true; diff --git a/include/opcode/riscv-opc.h b/include/opcode/riscv-opc.h index 3eea33a5da..d8635b6fc3 100644 --- a/include/opcode/riscv-opc.h +++ b/include/opcode/riscv-opc.h @@ -255,6 +255,7 @@ #define MASK_SFENCE_VMA 0xfe007fff #define MATCH_WFI 0x10500073 #define MASK_WFI 0xffffffff +#define MASK_CUSTOMER_PREF 0x7fff #define MATCH_CSRRW 0x1073 #define MASK_CSRRW 0x707f #define MATCH_CSRRS 0x2073 diff --git a/include/opcode/riscv.h b/include/opcode/riscv.h index b769769b4e..d748e271e6 100644 --- a/include/opcode/riscv.h +++ b/include/opcode/riscv.h @@ -156,6 +156,10 @@ static const char * const riscv_pred_succ[16] = (RV_X(x, 0, 10) << 20) #define ENCODE_RVV_VC_IMM(x) \ (RV_X(x, 0, 11) << 20) +#define ENCODE_PREF_TIMM(x) \ + (RV_X(x, 0, 4) << 20) +#define ENCODE_PREF_SIMM(x) \ + (RV_X(x, 0, 8) << 24) #define VALID_ITYPE_IMM(x) (EXTRACT_ITYPE_IMM(ENCODE_ITYPE_IMM(x)) == (x)) #define VALID_STYPE_IMM(x) (EXTRACT_STYPE_IMM(ENCODE_STYPE_IMM(x)) == (x)) @@ -256,6 +260,11 @@ static const char * const riscv_pred_succ[16] = #define OP_MASK_FUNCT2 0x3 #define OP_SH_FUNCT2 25 +#define OP_MASK_PREF_TYPE 0x0f +#define OP_SH_PREF_TYPE 20 +#define OP_MASK_PREF_OFFSET 0xff +#define OP_SH_PREF_OFFSET 24 + /* RVC fields. */ #define OP_MASK_OP2 0x3 diff --git a/opcodes/riscv-dis.c b/opcodes/riscv-dis.c index 57b798d8e1..68ba1ee103 100644 --- a/opcodes/riscv-dis.c +++ b/opcodes/riscv-dis.c @@ -464,6 +464,13 @@ print_insn_args (const char *oparg, insn_t l, bfd_vma pc, disassemble_info *info print (info->stream, "0x%x", (int)EXTRACT_OPERAND (SHAMTW, l)); break; + case '#': + print (info->stream, "0x%x", (int)EXTRACT_OPERAND (PREF_TYPE, l)); + break; + + case '+': + print (info->stream, "0x%x", (int)EXTRACT_OPERAND (PREF_OFFSET, l)); + case 'S': case 'U': print (info->stream, "%s", riscv_fpr_names[rs1]); diff --git a/opcodes/riscv-opc.c b/opcodes/riscv-opc.c index 523d165226..3704461a4a 100644 --- a/opcodes/riscv-opc.c +++ b/opcodes/riscv-opc.c @@ -401,6 +401,7 @@ const struct riscv_opcode riscv_opcodes[] = {"snez", 0, INSN_CLASS_I, "d,t", MATCH_SLTU, MASK_SLTU|MASK_RS1, match_opcode, INSN_ALIAS }, {"sltz", 0, INSN_CLASS_I, "d,s", MATCH_SLT, MASK_SLT|MASK_RS2, match_opcode, INSN_ALIAS }, {"sgtz", 0, INSN_CLASS_I, "d,t", MATCH_SLT, MASK_SLT|MASK_RS1, match_opcode, INSN_ALIAS }, +{"pref", 0, INSN_CLASS_I, "#,+(s)", MATCH_SLTI, MASK_CUSTOMER_PREF, match_opcode, INSN_ALIAS }, {"slti", 0, INSN_CLASS_I, "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, 0 }, {"slt", 0, INSN_CLASS_I, "d,s,t", MATCH_SLT, MASK_SLT, match_opcode, 0 }, {"slt", 0, INSN_CLASS_I, "d,s,j", MATCH_SLTI, MASK_SLTI, match_opcode, INSN_ALIAS }, -- 2.25.1