[vm, compiler] Some shorter load immediate sequences for RISC-V.

TEST=ci
Change-Id: I34e72727b5560da88916f996f92b33ddc1ff6dff
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/468980
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
This commit is contained in:
Ryan Macnak
2026-01-05 16:31:30 -08:00
committed by Commit Queue
parent 3ebbaf08fb
commit 0e9676ea1f
2 changed files with 101 additions and 0 deletions
@@ -4592,6 +4592,11 @@ void Assembler::LoadIsolateGroup(Register dst) {
void Assembler::LoadImmediate(Register reg, intx_t imm) {
#if XLEN > 32
if (!Utils::IsInt(32, imm)) {
if (Supports(RV_Zbs) && Utils::IsPowerOfTwo(imm)) {
bseti(reg, ZR, Utils::ShiftForPowerOfTwo(imm));
return;
}
int shift = Utils::CountTrailingZeros64(imm);
if (IsITypeImm(imm >> shift)) {
li(reg, imm >> shift);
@@ -4651,6 +4656,22 @@ void Assembler::LoadSImmediate(FRegister reg, float imms) {
return;
}
}
uint32_t nimm = imm ^ 0x80000000;
for (intptr_t i = 0; i < 32; i++) {
if (kFlisConstants[i] == nimm) {
flis(reg, i);
fnegs(reg, reg);
return;
}
}
}
int32_t immi = imms;
if (IsITypeImm(immi) &&
imm == bit_cast<uint32_t, float>(static_cast<float>(immi))) {
li(TMP2, immi);
fcvtsw(reg, TMP2); // static_cast int32_t -> float
return;
}
ASSERT(constant_pool_allowed());
@@ -4676,6 +4697,22 @@ void Assembler::LoadDImmediate(FRegister reg, double immd) {
return;
}
}
uint64_t nimm = imm ^ 0x8000000000000000;
for (intptr_t i = 0; i < 32; i++) {
if (kFlidConstants[i] == nimm) {
flid(reg, i);
fnegd(reg, reg);
return;
}
}
}
int32_t immi = immd;
if (IsITypeImm(immi) &&
imm == bit_cast<uint64_t, double>(static_cast<double>(immi))) {
li(TMP2, immi);
fcvtdw(reg, TMP2); // static_cast int32_t -> double
return;
}
ASSERT(constant_pool_allowed());
@@ -9324,6 +9324,18 @@ ASSEMBLER_TEST_RUN(LoadImmediate_LiSlliAddi, test) {
" 8082 ret\n");
EXPECT_EQ(static_cast<int64_t>(0xFF000000000000FF), Call(test->entry()));
}
ASSEMBLER_TEST_GENERATE(LoadImmediate_Bseti, assembler) {
__ SetExtensions(RV_GCB);
__ LoadImmediate(A0, static_cast<intx_t>(1) << 62);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadImmediate_Bseti, test) {
EXPECT_DISASSEMBLY(
"2be01513 bseti a0, zero, 0x3e\n"
" 8082 ret\n");
EXPECT_EQ(static_cast<intx_t>(1) << 62, Call(test->entry()));
}
#endif
ASSEMBLER_TEST_GENERATE(BitwiseImmediates_GC, assembler) {
@@ -9372,6 +9384,58 @@ ASSEMBLER_TEST_RUN(BitwiseImmediates_GCB, test) {
" 8082 ret\n");
}
ASSEMBLER_TEST_GENERATE(LoadSImmediate_IntCast, assembler) {
__ SetExtensions(RV_GC);
__ LoadSImmediate(FA0, 10.0);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadSImmediate_IntCast, test) {
EXPECT_DISASSEMBLY(
" 4729 li tmp2, 10\n"
"d0070553 fcvt.s.w fa0, tmp2\n"
" 8082 ret\n");
EXPECT_EQ(10.0f, CallF(test->entry(), 0.0f));
}
ASSEMBLER_TEST_GENERATE(LoadSImmediate_NegLi, assembler) {
__ SetExtensions(RV_GC | RV_Zfa);
__ LoadSImmediate(FA0, -2.0);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadSImmediate_NegLi, test) {
EXPECT_DISASSEMBLY(
"f01a0553 flis fa0, 2.000000\n"
"20a51553 fneg.s fa0, fa0\n"
" 8082 ret\n");
EXPECT_EQ(-2.0f, CallF(test->entry(), 0.0f));
}
ASSEMBLER_TEST_GENERATE(LoadDImmediate_IntCast, assembler) {
__ SetExtensions(RV_GC);
__ LoadDImmediate(FA0, 10.0);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadDImmediate_IntCast, test) {
EXPECT_DISASSEMBLY(
" 4729 li tmp2, 10\n"
"d2070553 fcvt.d.w fa0, tmp2\n"
" 8082 ret\n");
EXPECT_EQ(10.0, CallD(test->entry(), 0.0));
}
ASSEMBLER_TEST_GENERATE(LoadDImmediate_NegLi, assembler) {
__ SetExtensions(RV_GC | RV_Zfa);
__ LoadDImmediate(FA0, -2.0);
__ ret();
}
ASSEMBLER_TEST_RUN(LoadDImmediate_NegLi, test) {
EXPECT_DISASSEMBLY(
"f21a0553 flid fa0, 2.000000\n"
"22a51553 fneg.d fa0, fa0\n"
" 8082 ret\n");
EXPECT_EQ(-2.0, CallD(test->entry(), 0.0));
}
ASSEMBLER_TEST_GENERATE(AddImmediateBranchOverflow, assembler) {
__ SetExtensions(RV_GC);
Label overflow;