From f7d0808a5c87a7ca3349bc3e68bb33a4fe912d3c Mon Sep 17 00:00:00 2001 From: Roger Chang Date: Wed, 30 Nov 2022 16:36:05 +0800 Subject: [PATCH] arch-riscv: Fork Zba, Zbb, Zbc, Zbs instructions into rv32 / rv64 The following instructions will be supported for both rv32 and rv64 Zba extensions: SLLI.UW SH1ADD SH2ADD SH3ADD ADD.UW SH1ADD.UW SH2ADD.UW SH3ADD.UW Zbb extensions: CLZ CTZ CPOP SEXT.B SEXT.H ORC.B RORI REV8 CLZW CTZW CPOPW RORIW ROL MIN XNOR MINU ROR MAX ORN MAXU ANDN ROLW ZEXT.H RORW Zbc extensions: CLMUL CLMULR CLMULH Zbs extensions: BSETI BCLRI BINVI BEXTI BSET BCLR BINV BEXT Change-Id: I3f489a3a1bab8799e2d95218740e495313b9961d Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/66211 Maintainer: Jason Lowe-Power Reviewed-by: Jason Lowe-Power Tested-by: kokoro --- src/arch/riscv/isa/bitfields.isa | 1 + src/arch/riscv/isa/decoder.isa | 320 +++++++++++++++++-------------- 2 files changed, 174 insertions(+), 147 deletions(-) diff --git a/src/arch/riscv/isa/bitfields.isa b/src/arch/riscv/isa/bitfields.isa index 863982cfec..4f58416237 100644 --- a/src/arch/riscv/isa/bitfields.isa +++ b/src/arch/riscv/isa/bitfields.isa @@ -129,6 +129,7 @@ def bitfield M5FUNC <31:25>; // Cryptography instructions def bitfield BIT24 <24>; +def bitfield BIT25 <25>; def bitfield RNUM <23:20>; def bitfield KFUNCT5 <29:25>; def bitfield BS <31:30>; diff --git a/src/arch/riscv/isa/decoder.isa b/src/arch/riscv/isa/decoder.isa index 885794032a..458327e5ec 100644 --- a/src/arch/riscv/isa/decoder.isa +++ b/src/arch/riscv/isa/decoder.isa @@ -577,8 +577,12 @@ decode QUADRANT default Unknown::unknown() { }}); } 0x05: bseti({{ - uint64_t index = imm & (64 - 1); - Rd = Rs1 | (UINT64_C(1) << index); + if (rvSelect((bool)SHAMT6BIT5, false)) { + return std::make_shared( + "shmat[5] != 0", machInst); + } + uint64_t index = imm & rvSelect(32 - 1, 64 - 1); + Rd = rvSext(Rs1 | (UINT64_C(1) << index)); }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); 0x06: decode BIT24 { 0x0: aes64im({{ @@ -589,24 +593,32 @@ decode QUADRANT default Unknown::unknown() { }}, imm_type = int32_t, imm_code={{ imm = RNUM; }}); } 0x09: bclri({{ - uint64_t index = imm & (64 - 1); - Rd = Rs1 & (~(UINT64_C(1) << index)); + if (rvSelect((bool)SHAMT6BIT5, false)) { + return std::make_shared( + "shmat[5] != 0", machInst); + } + uint64_t index = imm & rvSelect(32 - 1, 64 - 1); + Rd = rvSext(Rs1 & (~(UINT64_C(1) << index))); }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); 0x0d: binvi({{ - uint64_t index = imm & (64 - 1); - Rd = Rs1 ^ (UINT64_C(1) << index); + if (rvSelect((bool)SHAMT6BIT5, false)) { + return std::make_shared( + "shmat[5] != 0", machInst); + } + uint64_t index = imm & rvSelect(32 - 1, 64 - 1); + Rd = rvSext(Rs1 ^ (UINT64_C(1) << index)); }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); } format ROp { 0x0c: decode RS2 { 0x00: clz({{ - Rd = clz64(Rs1); + Rd = (machInst.rv_type == RV32) ? clz32(Rs1) : clz64(Rs1); }}); 0x01: ctz({{ - Rd = ctz64(Rs1); + Rd = (machInst.rv_type == RV32) ? ctz32(Rs1) : ctz64(Rs1); }}); 0x02: cpop({{ - Rd = popCount(Rs1); + Rd = (machInst.rv_type == RV32) ? popCount(Rs1<31:0>) : popCount(Rs1); }}); 0x04: sext_b({{ Rd = sext<8>(Rs1_ub); @@ -649,7 +661,7 @@ decode QUADRANT default Unknown::unknown() { result |= (Rs1<47:40> ? UINT64_C(0xff) : 0x0) << 40; result |= (Rs1<55:48> ? UINT64_C(0xff) : 0x0) << 48; result |= (Rs1<63:56> ? UINT64_C(0xff) : 0x0) << 56; - Rd = result; + Rd = rvSext(result); }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); 0x8: srai({{ if (rvSelect((bool)SHAMT6BIT5, false)) { @@ -659,30 +671,53 @@ decode QUADRANT default Unknown::unknown() { Rd_sd = rvSext(Rs1_sd) >> imm; }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); 0x9: bexti({{ - uint64_t index = imm & (64 - 1); + if (rvSelect((bool)SHAMT6BIT5, false)) { + return std::make_shared( + "shmat[5] != 0", machInst); + } + uint64_t index = imm & rvSelect(32 - 1, 64 - 1); Rd = (Rs1 >> index) & 0x1; }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); 0xc: rori({{ - Rd = (Rs1 >> imm) | (Rs1 << ((64 - imm) & (64 - 1))); + if (rvSelect((bool)SHAMT6BIT5, false)) { + return std::make_shared( + "shmat[5] != 0", machInst); + } + uint64_t xlen = rvSelect(32, 64); + Rd = rvSext((rvZext(Rs1) >> imm) + | (Rs1 << ((xlen - imm) & (xlen - 1)))); }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); 0xd: decode RS2 { - 0x18: rev8({{ - uint64_t result = 0; - result |= - ((Rs1 & 0xffULL) << 56) - | (((Rs1 >> 56) & 0xffULL)); - result |= - (((Rs1 >> 8) & 0xffULL) << 48) - | (((Rs1 >> 48) & 0xffULL) << 8); - result |= - (((Rs1 >> 16) & 0xffULL) << 40) - | (((Rs1 >> 40) & 0xffULL) << 16); - result |= - (((Rs1 >> 24) & 0xffULL) << 32) - | (((Rs1 >> 32) & 0xffULL) << 24); - Rd = result; - }}, - imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); + 0x18: decode BIT25 { + 0x0: rv32_rev8({{ + uint32_t result = 0; + result |= + ((Rs1_uw & 0xffUL) << 24) + | (((Rs1_uw >> 24) & 0xffUL)); + result |= + (((Rs1_uw >> 8) & 0xffUL) << 16) + | (((Rs1_uw >> 16) & 0xffUL) << 8); + Rd = rvSext(result); + }}, + imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); + 0x1: rev8({{ + uint64_t result = 0; + result |= + ((Rs1 & 0xffULL) << 56) + | (((Rs1 >> 56) & 0xffULL)); + result |= + (((Rs1 >> 8) & 0xffULL) << 48) + | (((Rs1 >> 48) & 0xffULL) << 8); + result |= + (((Rs1 >> 16) & 0xffULL) << 40) + | (((Rs1 >> 40) & 0xffULL) << 16); + result |= + (((Rs1 >> 24) & 0xffULL) << 32) + | (((Rs1 >> 32) & 0xffULL) << 24); + Rd = result; + }}, + imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); + } } } 0x6: ori({{ @@ -698,48 +733,42 @@ decode QUADRANT default Unknown::unknown() { Rd = rvSext(PC + (sext<20>(imm) << 12)); }}); - 0x06: decode FUNCT3 { - format IOp { - 0x0: decode RVTYPE { - 0x1: addiw({{ + 0x06: decode RVTYPE { + 0x1: decode FUNCT3 { + format IOp { + 0x0: addiw({{ Rd_sw = (int32_t)(Rs1_sw + imm); }}, int32_t); - } - 0x1: decode FS3 { - 0x0: decode RVTYPE { - 0x1: slliw({{ + 0x1: decode FS3 { + 0x0: slliw({{ Rd_sd = Rs1_sw << imm; }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); + 0x1: slli_uw({{ + Rd = ((uint64_t)(Rs1_uw)) << imm; + }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT6; }}); + 0xc: decode FS2 { + 0x0: clzw({{ + Rd = clz32(Rs1); + }}); + 0x1: ctzw({{ + Rd = ctz32(Rs1); + }}); + 0x2: cpopw({{ + Rd = popCount(Rs1<31:0>); + }}); + } } - 0x1: slli_uw({{ - Rd = ((uint64_t)(Rs1_uw)) << imm; - }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); - 0xc: decode FS2 { - 0x0: clzw({{ - Rd = clz32(Rs1); - }}); - 0x1: ctzw({{ - Rd = ctz32(Rs1); - }}); - 0x2: cpopw({{ - Rd = popCount(Rs1<31:0>); - }}); - } - } - 0x5: decode FS3 { - 0x0: decode RVTYPE { - 0x1: srliw({{ + 0x5: decode FS3 { + 0x0: srliw({{ Rd_sd = (int32_t)(Rs1_uw >> imm); }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); - } - 0x8: decode RVTYPE { - 0x1: sraiw({{ + 0x8: sraiw({{ Rd_sd = Rs1_sw >> imm; }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); + 0xc: roriw({{ + Rd = (int32_t) ((Rs1_uw >> imm) | (Rs1_uw << ((32 - imm) & (32 - 1)))); + }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); } - 0xc: roriw({{ - Rd = (int32_t) ((Rs1_uw >> imm) | (Rs1_uw << ((32 - imm) & (32 - 1)))); - }}, imm_type = uint64_t, imm_code = {{ imm = SHAMT5; }}); } } } @@ -1026,28 +1055,30 @@ decode QUADRANT default Unknown::unknown() { } 0x5: clmul({{ uint64_t result = 0; - for (int i = 0; i < 64; i++) { + for (int i = 0; i < rvSelect(32, 64); i++) { if ((Rs2 >> i) & 1) { result ^= Rs1 << i; } } - Rd = result; + Rd = rvSext(result); }}); 0x14: bset({{ - Rs2 &= (64 - 1); - Rd = Rs1 | (UINT64_C(1) << Rs2); + Rs2 &= rvSelect(32 - 1, 64 - 1); + Rd = rvSext(Rs1 | (UINT64_C(1) << Rs2)); }}); 0x24: bclr({{ - Rs2 &= (64 - 1); - Rd = Rs1 & (~(UINT64_C(1) << Rs2)); + Rs2 &= rvSelect(32 - 1, 64 - 1); + Rd = rvSext(Rs1 & (~(UINT64_C(1) << Rs2))); }}); 0x30: rol({{ - int shamt = Rs2 & (64 - 1); - Rd = (Rs1 << shamt) | (Rs1 >> ((64 - shamt) & (64 - 1))); + uint64_t xlen = rvSelect(32, 64); + int shamt = Rs2 & (xlen - 1); + Rd = rvSext((Rs1 << shamt) + | (rvZext(Rs1) >> ((xlen - shamt) & (xlen - 1)))); }}); 0x34: binv({{ - Rs2 &= (64 - 1); - Rd = Rs1 ^ (UINT64_C(1) << Rs2); + Rs2 &= rvSelect(32 - 1, 64 - 1); + Rd = rvSext(Rs1 ^ (UINT64_C(1) << Rs2)); }}); } 0x2: decode FUNCT7 { @@ -1082,15 +1113,17 @@ decode QUADRANT default Unknown::unknown() { } 0x5: clmulr({{ uint64_t result = 0; - for (int i = 0; i < 64; i++) { + uint64_t xlen = rvSelect(32, 64); + uint64_t zextRs1 = rvZext(Rs1); + for (int i = 0; i < xlen; i++) { if ((Rs2 >> i) & 1) { - result ^= Rs1 >> (64-i-1); + result ^= zextRs1 >> (xlen-i-1); } } - Rd = result; + Rd = rvSext(result); }}); 0x10: sh1add({{ - Rd = (Rs1 << 1) + Rs2; + Rd = rvSext((Rs1 << 1) + Rs2); }}); 0x14: xperm4({{ Rd_sd = _rvk_emu_xperm4_64(Rs1_sd, Rs2_sd); @@ -1123,11 +1156,14 @@ decode QUADRANT default Unknown::unknown() { } 0x5: clmulh({{ uint64_t result = 0; - for (int i = 1; i < 64; i++) { + uint64_t xlen = rvSelect(32, 64); + uint64_t zextRs1 = rvZext(Rs1); + for (int i = 1; i < xlen; i++) { if ((Rs2 >> i) & 1) { - result ^= (Rs1 >> (64-i)); + result ^= zextRs1 >> (xlen-i); } } + // The MSB can never be 1, no need to sign extend. Rd = result; }}); } @@ -1159,17 +1195,22 @@ decode QUADRANT default Unknown::unknown() { } }}, IntDivOp); } + 0x4: decode RVTYPE { + 0x0: rv32_zext_h({{ + Rd = Rs1_uh; + }}); + } 0x5: min({{ - Rd = (((int64_t) Rs1) < ((int64_t) Rs2)) ? Rs1 : Rs2; + Rd_sd = std::min(rvSext(Rs1_sd), rvSext(Rs2_sd)); }}); 0x10: sh2add({{ - Rd = (Rs1 << 2) + Rs2; + Rd = rvSext((Rs1 << 2) + Rs2); }}); 0x14: xperm8({{ Rd_sd = _rvk_emu_xperm8_64(Rs1_sd, Rs2_sd); }}); 0x20: xnor({{ - Rd = ~(Rs1 ^ Rs2); + Rd = rvSext(~(Rs1 ^ Rs2)); }}); } 0x5: decode FUNCT7 { @@ -1197,15 +1238,18 @@ decode QUADRANT default Unknown::unknown() { Rd = rvSext(Rs1_sd) >> rvSelect(Rs2<4:0>, Rs2<5:0>); }}); 0x5: minu({{ - Rd = Rs1 < Rs2 ? Rs1 : Rs2; + Rd = rvSext(std::min(rvZext(Rs1), rvZext(Rs2))); }}); 0x24: bext({{ - Rs2 &= (64 - 1); + Rs2 &= (rvSelect(32, 64) - 1); + // It doesn't need to sign ext because MSB is always 0 Rd = (Rs1 >> Rs2) & 0x1; }}); 0x30: ror({{ - int shamt = Rs2 & (64 - 1); - Rd = (Rs1 >> shamt) | (Rs1 << ((64 - shamt) & (64 - 1))); + uint64_t xlen = rvSelect(32, 64); + int shamt = Rs2 & (xlen - 1); + Rd = rvSext((rvZext(Rs1) >> shamt) + | (Rs1 << ((xlen - shamt) & (xlen - 1)))); }}); } 0x6: decode FUNCT7 { @@ -1237,13 +1281,13 @@ decode QUADRANT default Unknown::unknown() { }}, IntDivOp); } 0x5: max({{ - Rd = (((int64_t) Rs1) > ((int64_t) Rs2)) ? Rs1 : Rs2; + Rd_sd = std::max(rvSext(Rs1_sd), rvSext(Rs2_sd)); }}); 0x10: sh3add({{ - Rd = (Rs1 << 3) + Rs2; + Rd = rvSext((Rs1 << 3) + Rs2); }}); 0x20: orn({{ - Rd = Rs1 | (~Rs2); + Rd = rvSext(Rs1 | (~Rs2)); }}); } 0x7: decode FUNCT7 { @@ -1267,10 +1311,10 @@ decode QUADRANT default Unknown::unknown() { }}, IntDivOp); } 0x5: maxu({{ - Rd = Rs1 > Rs2 ? Rs1 : Rs2; + Rd = rvSext(std::max(rvZext(Rs1), rvZext(Rs2))); }}); 0x20: andn({{ - Rd = Rs1 & (~Rs2); + Rd = rvSext(Rs1 & (~Rs2)); }}); } } @@ -1280,46 +1324,38 @@ decode QUADRANT default Unknown::unknown() { Rd = (sext<20>(imm) << 12); }}); - 0x0e: decode FUNCT3 { - format ROp { - 0x0: decode FUNCT7 { - 0x0: decode RVTYPE { - 0x1: addw({{ + 0x0e: decode RVTYPE { + 0x1: decode FUNCT3 { + format ROp { + 0x0: decode FUNCT7 { + 0x0: addw({{ Rd_sd = Rs1_sw + Rs2_sw; }}); - } - 0x1: decode RVTYPE { 0x1: mulw({{ Rd_sd = (int32_t)(Rs1_sw*Rs2_sw); }}, IntMultOp); - } - 0x4: add_uw({{ - Rd = Rs1_uw + Rs2; - }}); - 0x20: decode RVTYPE { - 0x1: subw({{ + 0x4: add_uw({{ + Rd = Rs1_uw + Rs2; + }}); + 0x20: subw({{ Rd_sd = Rs1_sw - Rs2_sw; }}); } - } - 0x1: decode FUNCT7 { - 0x0: decode RVTYPE { - 0x1: sllw({{ + 0x1: decode FUNCT7 { + 0x0: sllw({{ Rd_sd = Rs1_sw << Rs2<4:0>; }}); + 0x30: rolw({{ + int shamt = Rs2 & (32 - 1); + Rd = (int32_t) ((Rs1_uw << shamt) | (Rs1_uw >> ((32 - shamt) & (32 - 1)))); + }}); } - 0x30: rolw({{ - int shamt = Rs2 & (32 - 1); - Rd = (int32_t) ((Rs1_uw << shamt) | (Rs1_uw >> ((32 - shamt) & (32 - 1)))); - }}); - } - 0x2: decode FUNCT7 { - 0x10: sh1add_uw({{ - Rd = (((uint64_t)Rs1_uw) << 1) + Rs2; - }}); - } - 0x4: decode FUNCT7 { - 0x1: decode RVTYPE { + 0x2: decode FUNCT7 { + 0x10: sh1add_uw({{ + Rd = (((uint64_t)Rs1_uw) << 1) + Rs2; + }}); + } + 0x4: decode FUNCT7 { 0x1: divw({{ constexpr int32_t kRsMin = \ std::numeric_limits::min(); @@ -1331,21 +1367,17 @@ decode QUADRANT default Unknown::unknown() { Rd_sd = Rs1_sw/Rs2_sw; } }}, IntDivOp); - } - 0x4: zext_h({{ - Rd = Rs1_uh; - }}); - 0x10: sh2add_uw({{ - Rd = (((uint64_t)Rs1_uw) << 2) + Rs2; - }}); - } - 0x5: decode FUNCT7 { - 0x0: decode RVTYPE { - 0x1: srlw({{ - Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>); + 0x4: zext_h({{ + Rd = Rs1_uh; + }}); + 0x10: sh2add_uw({{ + Rd = (((uint64_t)Rs1_uw) << 2) + Rs2; }}); } - 0x1: decode RVTYPE { + 0x5: decode FUNCT7 { + 0x0: srlw({{ + Rd_sd = (int32_t)(Rs1_uw >> Rs2<4:0>); + }}); 0x1: divuw({{ if (Rs2_uw == 0) { Rd_sd = std::numeric_limits::max(); @@ -1353,19 +1385,15 @@ decode QUADRANT default Unknown::unknown() { Rd_sd = (int32_t)(Rs1_uw/Rs2_uw); } }}, IntDivOp); - } - 0x20: decode RVTYPE { - 0x1: sraw({{ + 0x20: sraw({{ Rd_sd = Rs1_sw >> Rs2<4:0>; }}); + 0x30: rorw({{ + int shamt = Rs2 & (32 - 1); + Rd = (int32_t) ((Rs1_uw >> shamt) | (Rs1_uw << ((32 - shamt) & (32 - 1)))); + }}); } - 0x30: rorw({{ - int shamt = Rs2 & (32 - 1); - Rd = (int32_t) ((Rs1_uw >> shamt) | (Rs1_uw << ((32 - shamt) & (32 - 1)))); - }}); - } - 0x6: decode FUNCT7 { - 0x1: decode RVTYPE { + 0x6: decode FUNCT7 { 0x1: remw({{ constexpr int32_t kRsMin = \ std::numeric_limits::min(); @@ -1377,13 +1405,11 @@ decode QUADRANT default Unknown::unknown() { Rd_sd = Rs1_sw%Rs2_sw; } }}, IntDivOp); + 0x10: sh3add_uw({{ + Rd = (((uint64_t)Rs1_uw) << 3) + Rs2; + }}); } - 0x10: sh3add_uw({{ - Rd = (((uint64_t)Rs1_uw) << 3) + Rs2; - }}); - } - 0x7: decode RVTYPE { - 0x1: remuw({{ + 0x7: remuw({{ if (Rs2_uw == 0) { Rd_sd = (int32_t)Rs1_uw; } else {