summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author s.kozub <s.kozub@syntacore.com> 2024-08-15 14:51:38 +0000
committer VladimĂ­r Marko <vmarko@google.com> 2024-08-23 11:52:30 +0000
commitb17478f8e8f1b27dc8994d991cd0e8ec7c249c1b (patch)
tree29261f7411063b2c9046158c710b9de568554fc2
parent389112846cf90ca8e1f49a67ac8ad1df28a551cb (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.h2
-rw-r--r--compiler/utils/riscv64/assembler_riscv64.cc48
-rw-r--r--compiler/utils/riscv64/assembler_riscv64.h12
-rw-r--r--compiler/utils/riscv64/assembler_riscv64_test.cc36
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) {