Commit a5f6daab authored by epertoso's avatar epertoso Committed by Commit bot

[stubs] Introduce LeftShift, SignedRightShift and UnsignedRightShift stubs.

Add the stubs for JavaScript's '<<', '>>' and '>>>' operators and lets Ignition make use of them in the respective bytecode handlers.

Committed: https://crrev.com/599369d6b8e1a5ccdca857def06eebcbacf47dd4
Cr-Commit-Position: refs/heads/master@{#35433}

Review URL: https://codereview.chromium.org/1881003002

Cr-Commit-Position: refs/heads/master@{#35446}
parent 1383d001
......@@ -239,6 +239,24 @@ Callable CodeFactory::Modulus(Isolate* isolate) {
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::ShiftRight(Isolate* isolate) {
ShiftRightStub stub(isolate);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::ShiftRightLogical(Isolate* isolate) {
ShiftRightLogicalStub stub(isolate);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::ShiftLeft(Isolate* isolate) {
ShiftLeftStub stub(isolate);
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
}
// static
Callable CodeFactory::BitwiseAnd(Isolate* isolate) {
BitwiseAndStub stub(isolate);
......
......@@ -85,6 +85,9 @@ class CodeFactory final {
static Callable Multiply(Isolate* isolate);
static Callable Divide(Isolate* isolate);
static Callable Modulus(Isolate* isolate);
static Callable ShiftRight(Isolate* isolate);
static Callable ShiftRightLogical(Isolate* isolate);
static Callable ShiftLeft(Isolate* isolate);
static Callable BitwiseAnd(Isolate* isolate);
static Callable BitwiseOr(Isolate* isolate);
static Callable BitwiseXor(Isolate* isolate);
......
......@@ -1542,6 +1542,54 @@ void ModulusStub::GenerateAssembly(
}
}
void ShiftLeftStub::GenerateAssembly(
compiler::CodeStubAssembler* assembler) const {
using compiler::Node;
Node* lhs = assembler->Parameter(0);
Node* rhs = assembler->Parameter(1);
Node* context = assembler->Parameter(2);
Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs);
Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs);
Node* shift_count =
assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f));
Node* value = assembler->Word32Shl(lhs_value, shift_count);
Node* result = assembler->ChangeInt32ToTagged(value);
assembler->Return(result);
}
void ShiftRightStub::GenerateAssembly(
compiler::CodeStubAssembler* assembler) const {
using compiler::Node;
Node* lhs = assembler->Parameter(0);
Node* rhs = assembler->Parameter(1);
Node* context = assembler->Parameter(2);
Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs);
Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs);
Node* shift_count =
assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f));
Node* value = assembler->Word32Sar(lhs_value, shift_count);
Node* result = assembler->ChangeInt32ToTagged(value);
assembler->Return(result);
}
void ShiftRightLogicalStub::GenerateAssembly(
compiler::CodeStubAssembler* assembler) const {
using compiler::Node;
Node* lhs = assembler->Parameter(0);
Node* rhs = assembler->Parameter(1);
Node* context = assembler->Parameter(2);
Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs);
Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs);
Node* shift_count =
assembler->Word32And(rhs_value, assembler->Int32Constant(0x1f));
Node* value = assembler->Word32Shr(lhs_value, shift_count);
Node* result = assembler->ChangeUint32ToTagged(value);
assembler->Return(result);
}
void BitwiseOrStub::GenerateAssembly(
compiler::CodeStubAssembler* assembler) const {
using compiler::Node;
......
......@@ -115,6 +115,9 @@ namespace internal {
V(Multiply) \
V(Divide) \
V(Modulus) \
V(ShiftRight) \
V(ShiftRightLogical) \
V(ShiftLeft) \
V(BitwiseAnd) \
V(BitwiseOr) \
V(BitwiseXor) \
......@@ -713,6 +716,31 @@ class ModulusStub final : public TurboFanCodeStub {
DEFINE_TURBOFAN_CODE_STUB(Modulus, TurboFanCodeStub);
};
class ShiftRightStub final : public TurboFanCodeStub {
public:
explicit ShiftRightStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
DEFINE_TURBOFAN_CODE_STUB(ShiftRight, TurboFanCodeStub);
};
class ShiftRightLogicalStub final : public TurboFanCodeStub {
public:
explicit ShiftRightLogicalStub(Isolate* isolate)
: TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
DEFINE_TURBOFAN_CODE_STUB(ShiftRightLogical, TurboFanCodeStub);
};
class ShiftLeftStub final : public TurboFanCodeStub {
public:
explicit ShiftLeftStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
DEFINE_CALL_INTERFACE_DESCRIPTOR(BinaryOp);
DEFINE_TURBOFAN_CODE_STUB(ShiftLeft, TurboFanCodeStub);
};
class BitwiseAndStub final : public TurboFanCodeStub {
public:
explicit BitwiseAndStub(Isolate* isolate) : TurboFanCodeStub(isolate) {}
......@@ -2512,7 +2540,7 @@ class ScriptContextFieldStub : public HandlerStub {
private:
static const int kContextIndexBits = 9;
static const int kSlotIndexBits = 13;
static const int kSlotIndexBits = 12;
class ContextIndexBits : public BitField<int, 0, kContextIndexBits> {};
class SlotIndexBits
: public BitField<int, kContextIndexBits, kSlotIndexBits> {};
......
......@@ -883,6 +883,41 @@ Node* CodeStubAssembler::ChangeInt32ToTagged(Node* value) {
return var_result.value();
}
Node* CodeStubAssembler::ChangeUint32ToTagged(Node* value) {
Label if_overflow(this, Label::kDeferred), if_not_overflow(this),
if_join(this);
Variable var_result(this, MachineRepresentation::kTagged);
// If {value} > 2^31 - 1, we need to store it in a HeapNumber.
Branch(Int32LessThan(value, Int32Constant(0)), &if_overflow,
&if_not_overflow);
Bind(&if_not_overflow);
{
if (raw_assembler_->machine()->Is64()) {
var_result.Bind(SmiTag(ChangeUint32ToUint64(value)));
} else {
// If tagging {value} results in an overflow, we need to use a HeapNumber
// to represent it.
Node* pair = Int32AddWithOverflow(value, value);
Node* overflow = Projection(1, pair);
GotoIf(overflow, &if_overflow);
Node* result = Projection(0, pair);
var_result.Bind(result);
}
}
Goto(&if_join);
Bind(&if_overflow);
{
Node* float64_value = ChangeUint32ToFloat64(value);
var_result.Bind(AllocateHeapNumberWithValue(float64_value));
}
Goto(&if_join);
Bind(&if_join);
return var_result.value();
}
Node* CodeStubAssembler::TruncateTaggedToFloat64(Node* context, Node* value) {
// We might need to loop once due to ToNumber conversion.
Variable var_value(this, MachineRepresentation::kTagged),
......
......@@ -389,6 +389,7 @@ class CodeStubAssembler {
// Conversions.
Node* ChangeFloat64ToTagged(Node* value);
Node* ChangeInt32ToTagged(Node* value);
Node* ChangeUint32ToTagged(Node* value);
Node* TruncateTaggedToFloat64(Node* context, Node* value);
Node* TruncateTaggedToWord32(Node* context, Node* value);
......
......@@ -769,7 +769,7 @@ void Interpreter::DoBitwiseAnd(InterpreterAssembler* assembler) {
// before the operation. 5 lsb bits from the accumulator are used as count
// i.e. <src> << (accumulator & 0x1F).
void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kShiftLeft, assembler);
DoBinaryOp(CodeFactory::ShiftLeft(isolate_), assembler);
}
......@@ -780,7 +780,7 @@ void Interpreter::DoShiftLeft(InterpreterAssembler* assembler) {
// accumulator to uint32 before the operation. 5 lsb bits from the accumulator
// are used as count i.e. <src> >> (accumulator & 0x1F).
void Interpreter::DoShiftRight(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kShiftRight, assembler);
DoBinaryOp(CodeFactory::ShiftRight(isolate_), assembler);
}
......@@ -791,7 +791,7 @@ void Interpreter::DoShiftRight(InterpreterAssembler* assembler) {
// uint32 before the operation 5 lsb bits from the accumulator are used as
// count i.e. <src> << (accumulator & 0x1F).
void Interpreter::DoShiftRightLogical(InterpreterAssembler* assembler) {
DoBinaryOp(Runtime::kShiftRightLogical, assembler);
DoBinaryOp(CodeFactory::ShiftRightLogical(isolate_), assembler);
}
void Interpreter::DoCountOp(Runtime::FunctionId function_id,
......
......@@ -309,7 +309,7 @@ const int kVariableSizeSentinel = 0;
// We may store the unsigned bit field as signed Smi value and do not
// use the sign bit.
const int kStubMajorKeyBits = 7;
const int kStubMajorKeyBits = 8;
const int kStubMinorKeyBits = kSmiValueSize - kStubMajorKeyBits - 1;
// All Maps have a field instance_type containing a InstanceType.
......
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