diff options
author | 2024-08-15 14:51:38 +0000 | |
---|---|---|
committer | 2024-08-23 11:52:30 +0000 | |
commit | b17478f8e8f1b27dc8994d991cd0e8ec7c249c1b (patch) | |
tree | 29261f7411063b2c9046158c710b9de568554fc2 | |
parent | 389112846cf90ca8e1f49a67ac8ad1df28a551cb (diff) |
riscv64: Support Zbs ISA extension in ART assembler
ISA extension support implemented in assembler
Test: m test-art-host-gtest
Test: run-gtests.sh
Change-Id: Ib21e6768c18b90419068e1389d6a8c61f5033f92
-rw-r--r-- | compiler/utils/assembler_test_base.h | 2 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.cc | 48 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64.h | 12 | ||||
-rw-r--r-- | compiler/utils/riscv64/assembler_riscv64_test.cc | 36 |
4 files changed, 96 insertions, 2 deletions
diff --git a/compiler/utils/assembler_test_base.h b/compiler/utils/assembler_test_base.h index d41928af9e..0a89ad1299 100644 --- a/compiler/utils/assembler_test_base.h +++ b/compiler/utils/assembler_test_base.h @@ -150,7 +150,7 @@ class AssemblerTestBase : public testing::Test { "--compile", "-target", "riscv64-linux-gnu", - "-march=rv64imafdcv_zba_zbb_zca_zcd_zcb", + "-march=rv64imafdcv_zba_zbb_zbs_zca_zcd_zcb", // Force the assembler to fully emit branch instructions instead of leaving // offsets unresolved with relocation information for the linker. "-mno-relax"}; diff --git a/compiler/utils/riscv64/assembler_riscv64.cc b/compiler/utils/riscv64/assembler_riscv64.cc index 69f54e8ded..3a776648e1 100644 --- a/compiler/utils/riscv64/assembler_riscv64.cc +++ b/compiler/utils/riscv64/assembler_riscv64.cc @@ -1724,6 +1724,54 @@ void Riscv64Assembler::ZbbZextH(XRegister rd, XRegister rs1) { /////////////////////////////// RV64 "Zbb" Instructions END ////////////////////////////// +////////////////////////////// RV64 "Zbs" Instructions START ///////////////////////////// + +void Riscv64Assembler::Bclr(XRegister rd, XRegister rs1, XRegister rs2) { + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitR(0x24, rs2, rs1, 0x1, rd, 0x33); +} + +void Riscv64Assembler::Bclri(XRegister rd, XRegister rs1, int32_t shamt) { + CHECK_LT(static_cast<uint32_t>(shamt), 64u); + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitI6(0x12, shamt, rs1, 0x1, rd, 0x13); +} + +void Riscv64Assembler::Bext(XRegister rd, XRegister rs1, XRegister rs2) { + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitR(0x24, rs2, rs1, 0x5, rd, 0x33); +} + +void Riscv64Assembler::Bexti(XRegister rd, XRegister rs1, int32_t shamt) { + CHECK_LT(static_cast<uint32_t>(shamt), 64u); + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitI6(0x12, shamt, rs1, 0x5, rd, 0x13); +} + +void Riscv64Assembler::Binv(XRegister rd, XRegister rs1, XRegister rs2) { + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitR(0x34, rs2, rs1, 0x1, rd, 0x33); +} + +void Riscv64Assembler::Binvi(XRegister rd, XRegister rs1, int32_t shamt) { + CHECK_LT(static_cast<uint32_t>(shamt), 64u); + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitI6(0x1A, shamt, rs1, 0x1, rd, 0x13); +} + +void Riscv64Assembler::Bset(XRegister rd, XRegister rs1, XRegister rs2) { + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitR(0x14, rs2, rs1, 0x1, rd, 0x33); +} + +void Riscv64Assembler::Bseti(XRegister rd, XRegister rs1, int32_t shamt) { + CHECK_LT(static_cast<uint32_t>(shamt), 64u); + AssertExtensionsEnabled(Riscv64Extension::kZbs); + EmitI6(0xA, shamt, rs1, 0x1, rd, 0x13); +} + +/////////////////////////////// RV64 "Zbs" Instructions END ////////////////////////////// + /////////////////////////////// RVV "VSet" Instructions START //////////////////////////// void Riscv64Assembler::VSetvli(XRegister rd, XRegister rs1, uint32_t vtypei) { diff --git a/compiler/utils/riscv64/assembler_riscv64.h b/compiler/utils/riscv64/assembler_riscv64.h index c28764b64e..7586064a91 100644 --- a/compiler/utils/riscv64/assembler_riscv64.h +++ b/compiler/utils/riscv64/assembler_riscv64.h @@ -57,7 +57,7 @@ enum class Riscv64Extension : uint32_t { kD, kZba, kZbb, - kZbs, // TODO(riscv64): Implement "Zbs" instructions. + kZbs, kV, kZca, // "C" extension instructions except floating point loads/stores. kZcd, // "C" extension double loads/stores. @@ -637,6 +637,16 @@ class Riscv64Assembler final : public Assembler { void ZbbSextH(XRegister rd, XRegister rs1); void ZbbZextH(XRegister rd, XRegister rs1); + // "Zbs" Standard Extension, opcode = 0x13, or 0x33, funct3 and funct7 varies. + void Bclr(XRegister rd, XRegister rs1, XRegister rs2); + void Bclri(XRegister rd, XRegister rs1, int32_t shamt); + void Bext(XRegister rd, XRegister rs1, XRegister rs2); + void Bexti(XRegister rd, XRegister rs1, int32_t shamt); + void Binv(XRegister rd, XRegister rs1, XRegister rs2); + void Binvi(XRegister rd, XRegister rs1, int32_t shamt); + void Bset(XRegister rd, XRegister rs1, XRegister rs2); + void Bseti(XRegister rd, XRegister rs1, int32_t shamt); + ////////////////////////////// RISC-V Vector Instructions START /////////////////////////////// enum class LengthMultiplier : uint32_t { kM1Over8 = 0b101, diff --git a/compiler/utils/riscv64/assembler_riscv64_test.cc b/compiler/utils/riscv64/assembler_riscv64_test.cc index 3169f75e0f..aebb8f6b17 100644 --- a/compiler/utils/riscv64/assembler_riscv64_test.cc +++ b/compiler/utils/riscv64/assembler_riscv64_test.cc @@ -4048,6 +4048,42 @@ TEST_F(AssemblerRISCV64Test, ZbbZextH) { DriverStr(RepeatRR(&Riscv64Assembler::ZbbZextH, "zext.h {reg1}, {reg2}"), "ZbbZextH"); } +TEST_F(AssemblerRISCV64Test, Bclr) { + DriverStr(RepeatRRR(&Riscv64Assembler::Bclr, "bclr {reg1}, {reg2}, {reg3}"), "Bclr"); +} + +TEST_F(AssemblerRISCV64Test, Bclri) { + DriverStr(RepeatRRIb(&Riscv64Assembler::Bclri, /*imm_bits=*/6, "bclri {reg1}, {reg2}, {imm}"), + "Bclri"); +} + +TEST_F(AssemblerRISCV64Test, Bext) { + DriverStr(RepeatRRR(&Riscv64Assembler::Bext, "bext {reg1}, {reg2}, {reg3}"), "Bext"); +} + +TEST_F(AssemblerRISCV64Test, Bexti) { + DriverStr(RepeatRRIb(&Riscv64Assembler::Bexti, /*imm_bits=*/6, "bexti {reg1}, {reg2}, {imm}"), + "Bexti"); +} + +TEST_F(AssemblerRISCV64Test, Binv) { + DriverStr(RepeatRRR(&Riscv64Assembler::Binv, "binv {reg1}, {reg2}, {reg3}"), "Binv"); +} + +TEST_F(AssemblerRISCV64Test, Binvi) { + DriverStr(RepeatRRIb(&Riscv64Assembler::Binvi, /*imm_bits=*/6, "binvi {reg1}, {reg2}, {imm}"), + "Binvi"); +} + +TEST_F(AssemblerRISCV64Test, Bset) { + DriverStr(RepeatRRR(&Riscv64Assembler::Bset, "bset {reg1}, {reg2}, {reg3}"), "Bset"); +} + +TEST_F(AssemblerRISCV64Test, Bseti) { + DriverStr(RepeatRRIb(&Riscv64Assembler::Bseti, /*imm_bits=*/6, "bseti {reg1}, {reg2}, {imm}"), + "Bseti"); +} + // Vector Instructions TEST_F(AssemblerRISCV64Test, VSetvl) { |