Skip to content

Commit e841793

Browse files
rmacnak-googleCommit Queue
authored andcommitted
[vm] Add the RISC-V Zicond extension.
TEST=ci, local qemu Change-Id: I0d367b762d989b3f9bae0937c7670b175d111453 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/394620 Reviewed-by: Alexander Aprelev <[email protected]> Commit-Queue: Ryan Macnak <[email protected]>
1 parent f3d8167 commit e841793

File tree

7 files changed

+92
-2
lines changed

7 files changed

+92
-2
lines changed

runtime/vm/compiler/assembler/assembler_riscv.cc

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1634,6 +1634,16 @@ void MicroAssembler::bseti(Register rd, Register rs1, intx_t shamt) {
16341634
EmitRType(BSET, shamt, rs1, F3_BSET, rd, OPIMM);
16351635
}
16361636

1637+
void MicroAssembler::czeroeqz(Register rd, Register rs1, Register rs2) {
1638+
ASSERT(Supports(RV_Zicond));
1639+
EmitRType(CZERO, rs2, rs1, CZEROEQZ, rd, OP);
1640+
}
1641+
1642+
void MicroAssembler::czeronez(Register rd, Register rs1, Register rs2) {
1643+
ASSERT(Supports(RV_Zicond));
1644+
EmitRType(CZERO, rs2, rs1, CZERONEZ, rd, OP);
1645+
}
1646+
16371647
void MicroAssembler::lb(Register rd, Address addr, std::memory_order order) {
16381648
ASSERT(addr.offset() == 0);
16391649
ASSERT((order == std::memory_order_acquire) ||

runtime/vm/compiler/assembler/assembler_riscv.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -606,6 +606,12 @@ class MicroAssembler : public AssemblerBase {
606606
void bset(Register rd, Register rs1, Register rs2);
607607
void bseti(Register rd, Register rs1, intx_t shamt);
608608

609+
// ==== Zicond: Integer conditional operations ====
610+
// rd := rs2 == 0 ? 0 : rs1
611+
void czeroeqz(Register rd, Register rs1, Register rs2);
612+
// rd := rs2 != 0 ? 0 : rs1
613+
void czeronez(Register rd, Register rs1, Register rs2);
614+
609615
// ==== Zalasr: Load-acquire, store-release ====
610616
void lb(Register rd, Address addr, std::memory_order order);
611617
void lh(Register rd, Address addr, std::memory_order order);

runtime/vm/compiler/assembler/assembler_riscv_test.cc

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6924,6 +6924,36 @@ ASSEMBLER_TEST_RUN(BitSetImmediate2, test) {
69246924
EXPECT_EQ(-1, Call(test->entry(), -1));
69256925
}
69266926

6927+
ASSEMBLER_TEST_GENERATE(ConditionalZeroIfEqualsZero, assembler) {
6928+
__ SetExtensions(RV_GC | RV_Zicond);
6929+
__ czeroeqz(A0, A0, A1);
6930+
__ ret();
6931+
}
6932+
ASSEMBLER_TEST_RUN(ConditionalZeroIfEqualsZero, test) {
6933+
EXPECT_DISASSEMBLY(
6934+
"0eb55533 czero.eqz a0, a0, a1\n"
6935+
" 8082 ret\n");
6936+
6937+
EXPECT_EQ(0, Call(test->entry(), 42, 0));
6938+
EXPECT_EQ(42, Call(test->entry(), 42, 1));
6939+
EXPECT_EQ(42, Call(test->entry(), 42, -1));
6940+
}
6941+
6942+
ASSEMBLER_TEST_GENERATE(ConditionalZeroIfNotEqualsZero, assembler) {
6943+
__ SetExtensions(RV_GC | RV_Zicond);
6944+
__ czeronez(A0, A0, A1);
6945+
__ ret();
6946+
}
6947+
ASSEMBLER_TEST_RUN(ConditionalZeroIfNotEqualsZero, test) {
6948+
EXPECT_DISASSEMBLY(
6949+
"0eb57533 czero.nez a0, a0, a1\n"
6950+
" 8082 ret\n");
6951+
6952+
EXPECT_EQ(42, Call(test->entry(), 42, 0));
6953+
EXPECT_EQ(0, Call(test->entry(), 42, 1));
6954+
EXPECT_EQ(0, Call(test->entry(), 42, -1));
6955+
}
6956+
69276957
ASSEMBLER_TEST_GENERATE(LoadByteAcquire, assembler) {
69286958
__ SetExtensions(RV_GC | RV_Zalasr);
69296959
__ lb(A0, Address(A1), std::memory_order_acquire);

runtime/vm/compiler/assembler/disassembler_riscv.cc

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ class RISCVDisassembler {
6969
void DisassembleOP_MINMAXCLMUL(Instr instr);
7070
void DisassembleOP_ROTATE(Instr instr);
7171
void DisassembleOP_BCLRBEXT(Instr instr);
72+
void DisassembleOP_CZERO(Instr instr);
7273
void DisassembleOP32(Instr instr);
7374
void DisassembleOP32_0(Instr instr);
7475
void DisassembleOP32_SUB(Instr instr);
@@ -713,6 +714,9 @@ void RISCVDisassembler::DisassembleOP(Instr instr) {
713714
Print("zext.h 'rd, 'rs1", instr, RV_Zbb);
714715
break;
715716
#endif
717+
case CZERO:
718+
DisassembleOP_CZERO(instr);
719+
break;
716720
default:
717721
UnknownInstruction(instr);
718722
}
@@ -886,6 +890,19 @@ void RISCVDisassembler::DisassembleOP_BCLRBEXT(Instr instr) {
886890
}
887891
}
888892

893+
void RISCVDisassembler::DisassembleOP_CZERO(Instr instr) {
894+
switch (instr.funct3()) {
895+
case CZEROEQZ:
896+
Print("czero.eqz 'rd, 'rs1, 'rs2", instr, RV_Zicond);
897+
break;
898+
case CZERONEZ:
899+
Print("czero.nez 'rd, 'rs1, 'rs2", instr, RV_Zicond);
900+
break;
901+
default:
902+
UnknownInstruction(instr);
903+
}
904+
}
905+
889906
void RISCVDisassembler::DisassembleOP32(Instr instr) {
890907
switch (instr.funct7()) {
891908
case 0:

runtime/vm/constants_riscv.h

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -838,6 +838,9 @@ enum Funct3 {
838838
BEXT = 0b101,
839839
F3_BINV = 0b001,
840840
F3_BSET = 0b001,
841+
842+
CZEROEQZ = 0b101,
843+
CZERONEZ = 0b111,
841844
};
842845

843846
enum Funct7 {
@@ -885,6 +888,8 @@ enum Funct7 {
885888
BCLRBEXT = 0b0100100,
886889
BINV = 0b0110100,
887890
BSET = 0b0010100,
891+
892+
CZERO = 0b0000111,
888893
};
889894

890895
enum Funct5 {
@@ -1617,10 +1622,11 @@ static constexpr ExtensionSet RV_GC = RV_G | RV_C;
16171622
static constexpr Extension RV_Zba(6); // Address generation
16181623
static constexpr Extension RV_Zbb(7); // Basic bit-manipulation
16191624
static constexpr Extension RV_Zbs(8); // Single-bit instructions
1625+
static constexpr Extension RV_Zbc(9); // Carry-less multiplication
16201626
static constexpr ExtensionSet RV_B = RV_Zba | RV_Zbb | RV_Zbs;
16211627
static constexpr ExtensionSet RV_GCB = RV_GC | RV_B;
1622-
static constexpr Extension RV_Zbc(9); // Carry-less multiplication
1623-
static constexpr Extension RV_Zalasr(10); // Load-acquire, store-release
1628+
static constexpr Extension RV_Zicond(10); // Integer conditional operations
1629+
static constexpr Extension RV_Zalasr(11); // Load-acquire, store-release
16241630

16251631
#if defined(DART_TARGET_OS_FUCHSIA) || defined(DART_TARGET_OS_ANDROID)
16261632
static constexpr ExtensionSet RV_baseline = RV_GCB;

runtime/vm/simulator_riscv.cc

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1332,6 +1332,9 @@ void Simulator::InterpretOP(Instr instr) {
13321332
pc_ += instr.length();
13331333
break;
13341334
#endif
1335+
case CZERO:
1336+
InterpretOP_CZERO(instr);
1337+
break;
13351338
default:
13361339
IllegalInstruction(instr);
13371340
}
@@ -1663,6 +1666,23 @@ void Simulator::InterpretOP_BCLRBEXT(Instr instr) {
16631666
pc_ += instr.length();
16641667
}
16651668

1669+
DART_FORCE_INLINE
1670+
void Simulator::InterpretOP_CZERO(Instr instr) {
1671+
switch (instr.funct3()) {
1672+
case CZEROEQZ:
1673+
set_xreg(instr.rd(),
1674+
get_xreg(instr.rs2()) == 0 ? 0 : get_xreg(instr.rs1()));
1675+
break;
1676+
case CZERONEZ:
1677+
set_xreg(instr.rd(),
1678+
get_xreg(instr.rs2()) != 0 ? 0 : get_xreg(instr.rs1()));
1679+
break;
1680+
default:
1681+
IllegalInstruction(instr);
1682+
}
1683+
pc_ += instr.length();
1684+
}
1685+
16661686
DART_FORCE_INLINE
16671687
void Simulator::InterpretOP32(Instr instr) {
16681688
switch (instr.funct7()) {

runtime/vm/simulator_riscv.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -211,6 +211,7 @@ class Simulator {
211211
void InterpretOP_MINMAXCLMUL(Instr instr);
212212
void InterpretOP_ROTATE(Instr instr);
213213
void InterpretOP_BCLRBEXT(Instr instr);
214+
void InterpretOP_CZERO(Instr instr);
214215
void InterpretOP32(Instr instr);
215216
void InterpretOP32_0(Instr instr);
216217
void InterpretOP32_SUB(Instr instr);

0 commit comments

Comments
 (0)