Commit e250cc16 authored by Lu Yahan's avatar Lu Yahan Committed by Commit Bot

[riscv64] Optimize add/sub with immediate

When add/sub with immm in [-4096, -2049] || [2048, 4094],
it can be split two addi/subi instr.

Change-Id: I94b93763c33fa5ef31c5ec4d23cbc5580a93ed1e
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/2848732
Commit-Queue: Yahan Lu <yahan@iscas.ac.cn>
Reviewed-by: 's avatarBrice Dobry <brice.dobry@futurewei.com>
Cr-Commit-Position: refs/heads/master@{#74199}
parent 6807a126
......@@ -394,6 +394,10 @@ void TurboAssembler::Add32(Register rd, Register rs, const Operand& rt) {
} else {
if (is_int12(rt.immediate()) && !MustUseReg(rt.rmode())) {
addiw(rd, rs, static_cast<int32_t>(rt.immediate()));
} else if ((-4096 <= rt.immediate() && rt.immediate() <= -2049) ||
(2048 <= rt.immediate() && rt.immediate() <= 4094)) {
addiw(rd, rs, rt.immediate() / 2);
addiw(rd, rd, rt.immediate() - (rt.immediate() / 2));
} else {
// li handles the relocation.
UseScratchRegisterScope temps(this);
......@@ -410,6 +414,10 @@ void TurboAssembler::Add64(Register rd, Register rs, const Operand& rt) {
} else {
if (is_int12(rt.immediate()) && !MustUseReg(rt.rmode())) {
addi(rd, rs, static_cast<int32_t>(rt.immediate()));
} else if ((-4096 <= rt.immediate() && rt.immediate() <= -2049) ||
(2048 <= rt.immediate() && rt.immediate() <= 4094)) {
addi(rd, rs, rt.immediate() / 2);
addi(rd, rd, rt.immediate() - (rt.immediate() / 2));
} else {
// li handles the relocation.
UseScratchRegisterScope temps(this);
......@@ -430,6 +438,10 @@ void TurboAssembler::Sub32(Register rd, Register rs, const Operand& rt) {
addiw(rd, rs,
static_cast<int32_t>(
-rt.immediate())); // No subiw instr, use addiw(x, y, -imm).
} else if ((-4096 <= -rt.immediate() && -rt.immediate() <= -2049) ||
(2048 <= -rt.immediate() && -rt.immediate() <= 4094)) {
addiw(rd, rs, -rt.immediate() / 2);
addiw(rd, rd, -rt.immediate() - (-rt.immediate() / 2));
} else {
UseScratchRegisterScope temps(this);
Register scratch = temps.Acquire();
......@@ -453,6 +465,10 @@ void TurboAssembler::Sub64(Register rd, Register rs, const Operand& rt) {
addi(rd, rs,
static_cast<int32_t>(
-rt.immediate())); // No subi instr, use addi(x, y, -imm).
} else if ((-4096 <= -rt.immediate() && -rt.immediate() <= -2049) ||
(2048 <= -rt.immediate() && -rt.immediate() <= 4094)) {
addi(rd, rs, -rt.immediate() / 2);
addi(rd, rd, -rt.immediate() - (-rt.immediate() / 2));
} else {
int li_count = InstrCountForLi64Bit(rt.immediate());
int li_neg_count = InstrCountForLi64Bit(-rt.immediate());
......
......@@ -1550,6 +1550,21 @@ TEST(DeoptExitSizeIsFixed) {
}
}
TEST(AddWithImm) {
CcTest::InitializeVM();
#define Test(Op, Input, Expected) \
{ \
auto fn = [](MacroAssembler& masm) { __ Op(a0, zero_reg, Input); }; \
CHECK_EQ(static_cast<int64_t>(Expected), GenAndRunTest(fn)); \
}
Test(Add64, 4095, 4095);
Test(Add32, 4095, 4095);
Test(Sub64, 4095, -4095);
Test(Sub32, 4095, -4095);
#undef Test
}
#undef __
} // namespace internal
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment