Skip to content

Commit 2bddaaa

Browse files
rmacnak-googleCommit Bot
authored and
Commit Bot
committed
[vm, compiler] Implement Smi_bitLength intrinsic on RV.
TEST=ci Change-Id: Ica3cace6cf6ac416e9db8c1b682df429aaf595e4 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/244740 Commit-Queue: Ryan Macnak <rmacnak@google.com> Reviewed-by: Alexander Markov <alexmarkov@google.com>
1 parent 4b08b7d commit 2bddaaa

File tree

3 files changed

+66
-2
lines changed

3 files changed

+66
-2
lines changed

runtime/vm/compiler/asm_intrinsifier_riscv.cc

+13-2
Original file line numberDiff line numberDiff line change
@@ -151,8 +151,19 @@ void AsmIntrinsifier::Integer_equal(Assembler* assembler,
151151

152152
void AsmIntrinsifier::Smi_bitLength(Assembler* assembler,
153153
Label* normal_ir_body) {
154-
// TODO(riscv)
155-
__ Bind(normal_ir_body);
154+
__ lx(A0, Address(SP, 0 * target::kWordSize));
155+
__ SmiUntag(A0);
156+
157+
// XOR with sign bit to complement bits if value is negative.
158+
__ srai(A1, A0, XLEN - 1);
159+
__ xor_(A0, A0, A1);
160+
161+
__ CountLeadingZeroes(A0, A0);
162+
163+
__ li(TMP, XLEN);
164+
__ sub(A0, TMP, A0);
165+
__ SmiTag(A0);
166+
__ ret();
156167
}
157168

158169
void AsmIntrinsifier::Bigint_lsh(Assembler* assembler, Label* normal_ir_body) {

runtime/vm/compiler/assembler/assembler_riscv.cc

+50
Original file line numberDiff line numberDiff line change
@@ -4470,6 +4470,56 @@ void Assembler::MultiplyBranchOverflow(Register rd,
44704470
bne(TMP, TMP2, overflow);
44714471
}
44724472

4473+
void Assembler::CountLeadingZeroes(Register rd, Register rs) {
4474+
// Note: clz will appear in the Zbb extension.
4475+
// if (Supports(RV_Zbb)) {
4476+
// clz(rd, rs);
4477+
// }
4478+
4479+
// n = XLEN
4480+
// y = x >>32; if (y != 0) { n = n - 32; x = y; }
4481+
// y = x >>16; if (y != 0) { n = n - 16; x = y; }
4482+
// y = x >> 8; if (y != 0) { n = n - 8; x = y; }
4483+
// y = x >> 4; if (y != 0) { n = n - 4; x = y; }
4484+
// y = x >> 2; if (y != 0) { n = n - 2; x = y; }
4485+
// y = x >> 1; if (y != 0) { return n - 2; }
4486+
// return n - x;
4487+
Label l0, l1, l2, l3, l4, l5;
4488+
li(TMP2, XLEN);
4489+
#if XLEN == 64
4490+
srli(TMP, rs, 32);
4491+
beqz(TMP, &l0, Assembler::kNearJump);
4492+
subi(TMP2, TMP2, 32);
4493+
mv(rs, TMP);
4494+
Bind(&l0);
4495+
#endif
4496+
srli(TMP, rs, 16);
4497+
beqz(TMP, &l1, Assembler::kNearJump);
4498+
subi(TMP2, TMP2, 16);
4499+
mv(rs, TMP);
4500+
Bind(&l1);
4501+
srli(TMP, rs, 8);
4502+
beqz(TMP, &l2, Assembler::kNearJump);
4503+
subi(TMP2, TMP2, 8);
4504+
mv(rs, TMP);
4505+
Bind(&l2);
4506+
srli(TMP, rs, 4);
4507+
beqz(TMP, &l3, Assembler::kNearJump);
4508+
subi(TMP2, TMP2, 4);
4509+
mv(rs, TMP);
4510+
Bind(&l3);
4511+
srli(TMP, rs, 2);
4512+
beqz(TMP, &l4, Assembler::kNearJump);
4513+
subi(TMP2, TMP2, 2);
4514+
mv(rs, TMP);
4515+
Bind(&l4);
4516+
srli(TMP, rs, 1);
4517+
sub(rd, TMP2, rs);
4518+
beqz(TMP, &l5, Assembler::kNearJump);
4519+
subi(rd, TMP2, 2);
4520+
Bind(&l5);
4521+
}
4522+
44734523
} // namespace compiler
44744524

44754525
} // namespace dart

runtime/vm/compiler/assembler/assembler_riscv.h

+3
Original file line numberDiff line numberDiff line change
@@ -1412,6 +1412,9 @@ class Assembler : public MicroAssembler {
14121412
Register rs2,
14131413
Label* overflow);
14141414

1415+
// Clobbers [rs].
1416+
void CountLeadingZeroes(Register rd, Register rs);
1417+
14151418
private:
14161419
bool constant_pool_allowed_;
14171420

0 commit comments

Comments
 (0)