Commit aeb1d787 authored by Pierre Langlois's avatar Pierre Langlois Committed by Commit Bot

[csa] Do not generate '& 0x1f' for shifts if possible

The CodeStubAssembler's BitwiseOp method used by the interpreter and Number
related builtins would unconditionnaly mask the shift amount operand with
0x1f. However some targets' shift implementation may already do it.

This removes 24 `and` instructions from the snapshot on Arm64.

Bug: 
Change-Id: If0a720c7ea69fea46c9b31dd55903603f058d481
Reviewed-on: https://chromium-review.googlesource.com/765971Reviewed-by: 's avatarJakob Kummerow <jkummerow@chromium.org>
Reviewed-by: 's avatarBenedikt Meurer <bmeurer@chromium.org>
Commit-Queue: Pierre Langlois <pierre.langlois@arm.com>
Cr-Commit-Position: refs/heads/master@{#49371}
parent 1abeb0ca
......@@ -10144,14 +10144,20 @@ Node* CodeStubAssembler::BitwiseOp(Node* left32, Node* right32,
case Operation::kBitwiseXor:
return ChangeInt32ToTagged(Signed(Word32Xor(left32, right32)));
case Operation::kShiftLeft:
return ChangeInt32ToTagged(
Signed(Word32Shl(left32, Word32And(right32, Int32Constant(0x1f)))));
if (!Word32ShiftIsSafe()) {
right32 = Word32And(right32, Int32Constant(0x1f));
}
return ChangeInt32ToTagged(Signed(Word32Shl(left32, right32)));
case Operation::kShiftRight:
return ChangeInt32ToTagged(
Signed(Word32Sar(left32, Word32And(right32, Int32Constant(0x1f)))));
if (!Word32ShiftIsSafe()) {
right32 = Word32And(right32, Int32Constant(0x1f));
}
return ChangeInt32ToTagged(Signed(Word32Sar(left32, right32)));
case Operation::kShiftRightLogical:
return ChangeUint32ToTagged(
Unsigned(Word32Shr(left32, Word32And(right32, Int32Constant(0x1f)))));
if (!Word32ShiftIsSafe()) {
right32 = Word32And(right32, Int32Constant(0x1f));
}
return ChangeUint32ToTagged(Unsigned(Word32Shr(left32, right32)));
default:
break;
}
......
......@@ -163,6 +163,10 @@ void CodeAssembler::CallEpilogue() {
}
}
bool CodeAssembler::Word32ShiftIsSafe() const {
return raw_assembler()->machine()->Word32ShiftIsSafe();
}
// static
Handle<Code> CodeAssembler::GenerateCode(CodeAssemblerState* state) {
DCHECK(!state->code_generated_);
......
......@@ -1045,6 +1045,8 @@ class V8_EXPORT_PRIVATE CodeAssembler {
const CodeAssemblerCallback& call_epilogue);
void UnregisterCallGenerationCallbacks();
bool Word32ShiftIsSafe() const;
private:
RawMachineAssembler* raw_assembler() const;
......
......@@ -250,6 +250,10 @@ class V8_EXPORT_PRIVATE MachineOperatorBuilder final
const OptionalOperator Word64ReverseBytes();
const OptionalOperator Int32AbsWithOverflow();
const OptionalOperator Int64AbsWithOverflow();
// Return true if the target's Word32 shift implementation is directly
// compatible with JavaScript's specification. Otherwise, we have to manually
// generate a mask with 0x1f on the amount ahead of generating the shift.
bool Word32ShiftIsSafe() const { return flags_ & kWord32ShiftIsSafe; }
const Operator* Word64And();
......
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