Commit d9e37a84 authored by Clemens Backes's avatar Clemens Backes Committed by Commit Bot

[Liftoff] Emit better code for clz and ctz

The {TurboAssembler} already has logic to use the {lzcnt} and {tzcnt}
instructions if available, and otherwise falls back to a slightly
optimized variant of the previous code. Thus, we just call these
methods.

Drive-by: Use {movl} instead of {Set} for constant values, for
          consistency, readability and performance.

R=jkummerow@chromium.org

Bug: v8:9919
Change-Id: I6028fa63c0adc70e8b4a3e61b8377a1eacce5040
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1891350Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Commit-Queue: Clemens Backes <clemensb@chromium.org>
Cr-Commit-Position: refs/heads/master@{#64674}
parent 8edda904
......@@ -1591,7 +1591,7 @@ void TurboAssembler::Lzcnt(Register dst, Operand src) {
Label not_zero_src;
bsr(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Move(dst, Immediate(63)); // 63^31 == 32
mov(dst, 63); // 63^31 == 32
bind(&not_zero_src);
xor_(dst, Immediate(31)); // for x in [0..31], 31^x == 31-x.
}
......@@ -1605,7 +1605,7 @@ void TurboAssembler::Tzcnt(Register dst, Operand src) {
Label not_zero_src;
bsf(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Move(dst, Immediate(32)); // The result of tzcnt is 32 if src = 0.
mov(dst, 32); // The result of tzcnt is 32 if src = 0.
bind(&not_zero_src);
}
......
......@@ -1921,7 +1921,7 @@ void TurboAssembler::Lzcntl(Register dst, Register src) {
Label not_zero_src;
bsrl(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Set(dst, 63); // 63^31 == 32
movl(dst, Immediate(63)); // 63^31 == 32
bind(&not_zero_src);
xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x
}
......@@ -1935,7 +1935,7 @@ void TurboAssembler::Lzcntl(Register dst, Operand src) {
Label not_zero_src;
bsrl(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Set(dst, 63); // 63^31 == 32
movl(dst, Immediate(63)); // 63^31 == 32
bind(&not_zero_src);
xorl(dst, Immediate(31)); // for x in [0..31], 31^x == 31 - x
}
......@@ -1949,7 +1949,7 @@ void TurboAssembler::Lzcntq(Register dst, Register src) {
Label not_zero_src;
bsrq(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Set(dst, 127); // 127^63 == 64
movl(dst, Immediate(127)); // 127^63 == 64
bind(&not_zero_src);
xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x
}
......@@ -1963,7 +1963,7 @@ void TurboAssembler::Lzcntq(Register dst, Operand src) {
Label not_zero_src;
bsrq(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Set(dst, 127); // 127^63 == 64
movl(dst, Immediate(127)); // 127^63 == 64
bind(&not_zero_src);
xorl(dst, Immediate(63)); // for x in [0..63], 63^x == 63 - x
}
......@@ -1978,7 +1978,7 @@ void TurboAssembler::Tzcntq(Register dst, Register src) {
bsfq(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
// Define the result of tzcnt(0) separately, because bsf(0) is undefined.
Set(dst, 64);
movl(dst, Immediate(64));
bind(&not_zero_src);
}
......@@ -1992,7 +1992,7 @@ void TurboAssembler::Tzcntq(Register dst, Operand src) {
bsfq(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
// Define the result of tzcnt(0) separately, because bsf(0) is undefined.
Set(dst, 64);
movl(dst, Immediate(64));
bind(&not_zero_src);
}
......@@ -2005,7 +2005,7 @@ void TurboAssembler::Tzcntl(Register dst, Register src) {
Label not_zero_src;
bsfl(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Set(dst, 32); // The result of tzcnt is 32 if src = 0.
movl(dst, Immediate(32)); // The result of tzcnt is 32 if src = 0.
bind(&not_zero_src);
}
......@@ -2018,7 +2018,7 @@ void TurboAssembler::Tzcntl(Register dst, Operand src) {
Label not_zero_src;
bsfl(dst, src);
j(not_zero, &not_zero_src, Label::kNear);
Set(dst, 32); // The result of tzcnt is 32 if src = 0.
movl(dst, Immediate(32)); // The result of tzcnt is 32 if src = 0.
bind(&not_zero_src);
}
......
......@@ -778,36 +778,12 @@ void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
}
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
test(src, src);
j(not_zero, &nonzero_input, Label::kNear);
mov(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get most significant bit set (MSBS).
bsr(dst, src);
// CLZ = 31 - MSBS = MSBS ^ 31.
xor_(dst, 31);
bind(&continuation);
Lzcnt(dst, src);
return true;
}
bool LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
test(src, src);
j(not_zero, &nonzero_input, Label::kNear);
mov(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get least significant bit set, which equals number of trailing zeros.
bsf(dst, src);
bind(&continuation);
Tzcnt(dst, src);
return true;
}
......
......@@ -741,36 +741,12 @@ void LiftoffAssembler::emit_i32_shr(Register dst, Register src, int amount) {
}
bool LiftoffAssembler::emit_i32_clz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
testl(src, src);
j(not_zero, &nonzero_input, Label::kNear);
movl(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get most significant bit set (MSBS).
bsrl(dst, src);
// CLZ = 31 - MSBS = MSBS ^ 31.
xorl(dst, Immediate(31));
bind(&continuation);
Lzcntl(dst, src);
return true;
}
bool LiftoffAssembler::emit_i32_ctz(Register dst, Register src) {
Label nonzero_input;
Label continuation;
testl(src, src);
j(not_zero, &nonzero_input, Label::kNear);
movl(dst, Immediate(32));
jmp(&continuation, Label::kNear);
bind(&nonzero_input);
// Get least significant bit set, which equals number of trailing zeros.
bsfl(dst, src);
bind(&continuation);
Tzcntl(dst, src);
return true;
}
......
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