Remove the obsolete OverwriteMode optimization.
R=jkummerow@chromium.org Review URL: https://codereview.chromium.org/900193002 Cr-Commit-Position: refs/heads/master@{#26454}
This commit is contained in:
parent
bfe7f4af14
commit
634b0f20f4
@ -2041,19 +2041,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
__ push(r0); // Left operand goes on the stack.
|
||||
VisitForAccumulatorValue(expr->value());
|
||||
|
||||
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
|
||||
? OVERWRITE_RIGHT
|
||||
: NO_OVERWRITE;
|
||||
SetSourcePosition(expr->position() + 1);
|
||||
AccumulatorValueContext context(this);
|
||||
if (ShouldInlineSmiCase(op)) {
|
||||
EmitInlineSmiBinaryOp(expr->binary_operation(),
|
||||
op,
|
||||
mode,
|
||||
expr->target(),
|
||||
expr->value());
|
||||
} else {
|
||||
EmitBinaryOp(expr->binary_operation(), op, mode);
|
||||
EmitBinaryOp(expr->binary_operation(), op);
|
||||
}
|
||||
|
||||
// Deoptimization point in case the binary operation may have side effects.
|
||||
@ -2444,7 +2440,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
|
||||
|
||||
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode,
|
||||
Expression* left_expr,
|
||||
Expression* right_expr) {
|
||||
Label done, smi_case, stub_call;
|
||||
@ -2464,7 +2459,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
patch_site.EmitJumpIfSmi(scratch1, &smi_case);
|
||||
|
||||
__ bind(&stub_call);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
__ jmp(&done);
|
||||
@ -2596,11 +2591,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode) {
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||
__ pop(r1);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
@ -4846,8 +4839,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
// Record position before stub call.
|
||||
SetSourcePosition(expr->position());
|
||||
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
|
||||
CallIC(code, expr->CountBinOpFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
__ bind(&done);
|
||||
|
@ -2184,8 +2184,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
||||
DCHECK(ToRegister(instr->right()).is(r0));
|
||||
DCHECK(ToRegister(instr->result()).is(r0));
|
||||
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
|
||||
// Block literal pool emission to ensure nop indicating no inlined smi code
|
||||
// is in the correct position.
|
||||
Assembler::BlockConstPoolScope block_const_pool(masm());
|
||||
|
@ -2018,19 +2018,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
__ Push(x0); // Left operand goes on the stack.
|
||||
VisitForAccumulatorValue(expr->value());
|
||||
|
||||
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
|
||||
? OVERWRITE_RIGHT
|
||||
: NO_OVERWRITE;
|
||||
SetSourcePosition(expr->position() + 1);
|
||||
AccumulatorValueContext context(this);
|
||||
if (ShouldInlineSmiCase(op)) {
|
||||
EmitInlineSmiBinaryOp(expr->binary_operation(),
|
||||
op,
|
||||
mode,
|
||||
expr->target(),
|
||||
expr->value());
|
||||
} else {
|
||||
EmitBinaryOp(expr->binary_operation(), op, mode);
|
||||
EmitBinaryOp(expr->binary_operation(), op);
|
||||
}
|
||||
|
||||
// Deoptimization point in case the binary operation may have side effects.
|
||||
@ -2120,7 +2116,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
|
||||
|
||||
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode,
|
||||
Expression* left_expr,
|
||||
Expression* right_expr) {
|
||||
Label done, both_smis, stub_call;
|
||||
@ -2138,7 +2133,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
|
||||
__ Bind(&stub_call);
|
||||
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
{
|
||||
Assembler::BlockPoolsScope scope(masm_);
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
@ -2218,11 +2213,9 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode) {
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||
__ Pop(x1);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
JumpPatchSite patch_site(masm_); // Unbound, signals no inlined smi code.
|
||||
{
|
||||
Assembler::BlockPoolsScope scope(masm_);
|
||||
@ -4530,8 +4523,7 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
|
||||
{
|
||||
Assembler::BlockPoolsScope scope(masm_);
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), Token::ADD, NO_OVERWRITE).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), Token::ADD).code();
|
||||
CallIC(code, expr->CountBinOpFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
}
|
||||
|
@ -1803,8 +1803,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
||||
DCHECK(ToRegister(instr->right()).is(x0));
|
||||
DCHECK(ToRegister(instr->result()).is(x0));
|
||||
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
|
||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
|
25
src/ast.cc
25
src/ast.cc
@ -456,31 +456,6 @@ void BinaryOperation::RecordToBooleanTypeFeedback(TypeFeedbackOracle* oracle) {
|
||||
}
|
||||
|
||||
|
||||
bool BinaryOperation::ResultOverwriteAllowed() const {
|
||||
switch (op()) {
|
||||
case Token::COMMA:
|
||||
case Token::OR:
|
||||
case Token::AND:
|
||||
return false;
|
||||
case Token::BIT_OR:
|
||||
case Token::BIT_XOR:
|
||||
case Token::BIT_AND:
|
||||
case Token::SHL:
|
||||
case Token::SAR:
|
||||
case Token::SHR:
|
||||
case Token::ADD:
|
||||
case Token::SUB:
|
||||
case Token::MUL:
|
||||
case Token::DIV:
|
||||
case Token::MOD:
|
||||
return true;
|
||||
default:
|
||||
UNREACHABLE();
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
static bool IsTypeof(Expression* expr) {
|
||||
UnaryOperation* maybe_unary = expr->AsUnaryOperation();
|
||||
return maybe_unary != NULL && maybe_unary->op() == Token::TYPEOF;
|
||||
|
@ -337,10 +337,6 @@ class Expression : public AstNode {
|
||||
// names because [] for string objects is handled only by keyed ICs.
|
||||
virtual bool IsPropertyName() const { return false; }
|
||||
|
||||
// True iff the result can be safely overwritten (to avoid allocation).
|
||||
// False for operations that can return one of their operands.
|
||||
virtual bool ResultOverwriteAllowed() const { return false; }
|
||||
|
||||
// True iff the expression is a literal represented as a smi.
|
||||
bool IsSmiLiteral() const;
|
||||
|
||||
@ -2078,8 +2074,6 @@ class BinaryOperation FINAL : public Expression {
|
||||
public:
|
||||
DECLARE_NODE_TYPE(BinaryOperation)
|
||||
|
||||
bool ResultOverwriteAllowed() const OVERRIDE;
|
||||
|
||||
Token::Value op() const { return static_cast<Token::Value>(op_); }
|
||||
Expression* left() const { return left_; }
|
||||
Expression* right() const { return right_; }
|
||||
|
@ -90,9 +90,8 @@ Callable CodeFactory::CompareIC(Isolate* isolate, Token::Value op) {
|
||||
|
||||
|
||||
// static
|
||||
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op,
|
||||
OverwriteMode mode) {
|
||||
BinaryOpICStub stub(isolate, op, mode);
|
||||
Callable CodeFactory::BinaryOpIC(Isolate* isolate, Token::Value op) {
|
||||
BinaryOpICStub stub(isolate, op);
|
||||
return Callable(stub.GetCode(), stub.GetCallInterfaceDescriptor());
|
||||
}
|
||||
|
||||
|
@ -45,8 +45,7 @@ class CodeFactory FINAL {
|
||||
|
||||
static Callable CompareIC(Isolate* isolate, Token::Value op);
|
||||
|
||||
static Callable BinaryOpIC(Isolate* isolate, Token::Value op,
|
||||
OverwriteMode mode = NO_OVERWRITE);
|
||||
static Callable BinaryOpIC(Isolate* isolate, Token::Value op);
|
||||
|
||||
// Code stubs. Add methods here as needed to reduce dependency on
|
||||
// code-stubs.h.
|
||||
|
@ -1230,21 +1230,6 @@ HValue* CodeStubGraphBuilder<BinaryOpICStub>::BuildCodeInitializedStub() {
|
||||
result = EnforceNumberType(result, result_type);
|
||||
}
|
||||
|
||||
// Reuse the double box of one of the operands if we are allowed to (i.e.
|
||||
// chained binops).
|
||||
if (state.CanReuseDoubleBox()) {
|
||||
HValue* operand = (state.mode() == OVERWRITE_LEFT) ? left : right;
|
||||
IfBuilder if_heap_number(this);
|
||||
if_heap_number.If<HHasInstanceTypeAndBranch>(operand, HEAP_NUMBER_TYPE);
|
||||
if_heap_number.Then();
|
||||
Add<HStoreNamedField>(operand, HObjectAccess::ForHeapNumberValue(), result);
|
||||
Push(operand);
|
||||
if_heap_number.Else();
|
||||
Push(result);
|
||||
if_heap_number.End();
|
||||
result = Pop();
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
@ -268,12 +268,8 @@ MaybeHandle<Code> CodeStub::GetCode(Isolate* isolate, uint32_t key) {
|
||||
void BinaryOpICStub::GenerateAheadOfTime(Isolate* isolate) {
|
||||
// Generate the uninitialized versions of the stub.
|
||||
for (int op = Token::BIT_OR; op <= Token::MOD; ++op) {
|
||||
for (int mode = NO_OVERWRITE; mode <= OVERWRITE_RIGHT; ++mode) {
|
||||
BinaryOpICStub stub(isolate,
|
||||
static_cast<Token::Value>(op),
|
||||
static_cast<OverwriteMode>(mode));
|
||||
stub.GetCode();
|
||||
}
|
||||
BinaryOpICStub stub(isolate, static_cast<Token::Value>(op));
|
||||
stub.GetCode();
|
||||
}
|
||||
|
||||
// Generate special versions of the stub.
|
||||
|
@ -1229,10 +1229,9 @@ class CallApiGetterStub : public PlatformCodeStub {
|
||||
|
||||
class BinaryOpICStub : public HydrogenCodeStub {
|
||||
public:
|
||||
BinaryOpICStub(Isolate* isolate, Token::Value op,
|
||||
OverwriteMode mode = NO_OVERWRITE)
|
||||
BinaryOpICStub(Isolate* isolate, Token::Value op)
|
||||
: HydrogenCodeStub(isolate, UNINITIALIZED) {
|
||||
BinaryOpICState state(isolate, op, mode);
|
||||
BinaryOpICState state(isolate, op);
|
||||
set_sub_minor_key(state.GetExtraICState());
|
||||
}
|
||||
|
||||
@ -1313,10 +1312,8 @@ class BinaryOpICWithAllocationSiteStub FINAL : public PlatformCodeStub {
|
||||
|
||||
class BinaryOpWithAllocationSiteStub FINAL : public BinaryOpICStub {
|
||||
public:
|
||||
BinaryOpWithAllocationSiteStub(Isolate* isolate,
|
||||
Token::Value op,
|
||||
OverwriteMode mode)
|
||||
: BinaryOpICStub(isolate, op, mode) {}
|
||||
BinaryOpWithAllocationSiteStub(Isolate* isolate, Token::Value op)
|
||||
: BinaryOpICStub(isolate, op) {}
|
||||
|
||||
BinaryOpWithAllocationSiteStub(Isolate* isolate, const BinaryOpICState& state)
|
||||
: BinaryOpICStub(isolate, state) {}
|
||||
|
@ -1052,19 +1052,15 @@ void FullCodeGenerator::VisitArithmeticExpression(BinaryOperation* expr) {
|
||||
Comment cmnt(masm_, "[ ArithmeticExpression");
|
||||
Expression* left = expr->left();
|
||||
Expression* right = expr->right();
|
||||
OverwriteMode mode =
|
||||
left->ResultOverwriteAllowed()
|
||||
? OVERWRITE_LEFT
|
||||
: (right->ResultOverwriteAllowed() ? OVERWRITE_RIGHT : NO_OVERWRITE);
|
||||
|
||||
VisitForStackValue(left);
|
||||
VisitForAccumulatorValue(right);
|
||||
|
||||
SetSourcePosition(expr->position());
|
||||
if (ShouldInlineSmiCase(op)) {
|
||||
EmitInlineSmiBinaryOp(expr, op, mode, left, right);
|
||||
EmitInlineSmiBinaryOp(expr, op, left, right);
|
||||
} else {
|
||||
EmitBinaryOp(expr, op, mode);
|
||||
EmitBinaryOp(expr, op);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -584,15 +584,12 @@ class FullCodeGenerator: public AstVisitor {
|
||||
|
||||
// Apply the compound assignment operator. Expects the left operand on top
|
||||
// of the stack and the right one in the accumulator.
|
||||
void EmitBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode);
|
||||
void EmitBinaryOp(BinaryOperation* expr, Token::Value op);
|
||||
|
||||
// Helper functions for generating inlined smi code for certain
|
||||
// binary operations.
|
||||
void EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode,
|
||||
Expression* left,
|
||||
Expression* right);
|
||||
|
||||
|
@ -1964,18 +1964,14 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
__ push(eax); // Left operand goes on the stack.
|
||||
VisitForAccumulatorValue(expr->value());
|
||||
|
||||
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
|
||||
? OVERWRITE_RIGHT
|
||||
: NO_OVERWRITE;
|
||||
SetSourcePosition(expr->position() + 1);
|
||||
if (ShouldInlineSmiCase(op)) {
|
||||
EmitInlineSmiBinaryOp(expr->binary_operation(),
|
||||
op,
|
||||
mode,
|
||||
expr->target(),
|
||||
expr->value());
|
||||
} else {
|
||||
EmitBinaryOp(expr->binary_operation(), op, mode);
|
||||
EmitBinaryOp(expr->binary_operation(), op);
|
||||
}
|
||||
|
||||
// Deoptimization point in case the binary operation may have side effects.
|
||||
@ -2356,7 +2352,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
|
||||
|
||||
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode,
|
||||
Expression* left,
|
||||
Expression* right) {
|
||||
// Do combined smi check of the operands. Left operand is on the
|
||||
@ -2370,7 +2365,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
|
||||
__ bind(&stub_call);
|
||||
__ mov(eax, ecx);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
__ jmp(&done, Label::kNear);
|
||||
@ -2502,11 +2497,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode) {
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||
__ pop(edx);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
@ -4778,8 +4771,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ bind(&stub_call);
|
||||
__ mov(edx, eax);
|
||||
__ mov(eax, Immediate(Smi::FromInt(1)));
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
|
||||
NO_OVERWRITE).code();
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), expr->binary_op()).code();
|
||||
CallIC(code, expr->CountBinOpFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
__ bind(&done);
|
||||
|
@ -2049,8 +2049,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
||||
DCHECK(ToRegister(instr->right()).is(eax));
|
||||
DCHECK(ToRegister(instr->result()).is(eax));
|
||||
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
|
||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
|
@ -48,7 +48,6 @@ BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
|
||||
: isolate_(isolate) {
|
||||
op_ =
|
||||
static_cast<Token::Value>(FIRST_TOKEN + OpField::decode(extra_ic_state));
|
||||
mode_ = OverwriteModeField::decode(extra_ic_state);
|
||||
fixed_right_arg_ =
|
||||
Maybe<int>(HasFixedRightArgField::decode(extra_ic_state),
|
||||
1 << FixedRightArgValueField::decode(extra_ic_state));
|
||||
@ -66,8 +65,7 @@ BinaryOpICState::BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state)
|
||||
|
||||
ExtraICState BinaryOpICState::GetExtraICState() const {
|
||||
ExtraICState extra_ic_state =
|
||||
OpField::encode(op_ - FIRST_TOKEN) | OverwriteModeField::encode(mode_) |
|
||||
LeftKindField::encode(left_kind_) |
|
||||
OpField::encode(op_ - FIRST_TOKEN) | LeftKindField::encode(left_kind_) |
|
||||
ResultKindField::encode(result_kind_) |
|
||||
HasFixedRightArgField::encode(fixed_right_arg_.has_value);
|
||||
if (fixed_right_arg_.has_value) {
|
||||
@ -87,218 +85,124 @@ void BinaryOpICState::GenerateAheadOfTime(
|
||||
// expensive at runtime. When solved we should be able to add most binops to
|
||||
// the snapshot instead of hand-picking them.
|
||||
// Generated list of commonly used stubs
|
||||
#define GENERATE(op, left_kind, right_kind, result_kind, mode) \
|
||||
do { \
|
||||
BinaryOpICState state(isolate, op, mode); \
|
||||
state.left_kind_ = left_kind; \
|
||||
state.fixed_right_arg_.has_value = false; \
|
||||
state.right_kind_ = right_kind; \
|
||||
state.result_kind_ = result_kind; \
|
||||
Generate(isolate, state); \
|
||||
#define GENERATE(op, left_kind, right_kind, result_kind) \
|
||||
do { \
|
||||
BinaryOpICState state(isolate, op); \
|
||||
state.left_kind_ = left_kind; \
|
||||
state.fixed_right_arg_.has_value = false; \
|
||||
state.right_kind_ = right_kind; \
|
||||
state.result_kind_ = result_kind; \
|
||||
Generate(isolate, state); \
|
||||
} while (false)
|
||||
GENERATE(Token::ADD, INT32, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, INT32, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, INT32, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, INT32, INT32, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, INT32, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, NUMBER, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, NUMBER, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, SMI, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, SMI, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, SMI, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, SMI, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, SMI, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::ADD, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, NUMBER, INT32, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, SMI, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, SMI, INT32, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, SMI, NUMBER, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_AND, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_AND, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, INT32, INT32, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, INT32, INT32, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, SMI, INT32, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, SMI, INT32, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_OR, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_XOR, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, SMI, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, SMI, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_XOR, SMI, INT32, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_XOR, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::BIT_XOR, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::DIV, INT32, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, INT32, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, INT32, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, INT32, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, NUMBER, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::DIV, NUMBER, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, SMI, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, SMI, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, SMI, INT32, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, SMI, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::DIV, SMI, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, SMI, SMI, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::DIV, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::DIV, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::MOD, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MOD, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MOD, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, INT32, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, INT32, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, INT32, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, INT32, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, INT32, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, INT32, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, NUMBER, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, NUMBER, INT32, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, NUMBER, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::MUL, SMI, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, SMI, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, SMI, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, SMI, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::MUL, SMI, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, SMI, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, SMI, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MUL, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SAR, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SAR, INT32, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SAR, INT32, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SAR, NUMBER, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SAR, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SAR, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHL, INT32, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::SHL, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHL, INT32, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SHL, INT32, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHL, NUMBER, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHL, SMI, SMI, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SHL, SMI, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHL, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SHL, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHR, INT32, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SHR, INT32, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHR, NUMBER, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SHR, NUMBER, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SHR, NUMBER, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SHR, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SHR, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SUB, INT32, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, INT32, INT32, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, INT32, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, INT32, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, INT32, SMI, INT32, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SUB, NUMBER, INT32, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, NUMBER, INT32, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SUB, NUMBER, SMI, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, NUMBER, SMI, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SUB, SMI, INT32, INT32, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, SMI, NUMBER, NUMBER, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, SMI, NUMBER, NUMBER, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::SUB, SMI, SMI, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::SUB, SMI, SMI, SMI, OVERWRITE_RIGHT);
|
||||
GENERATE(Token::ADD, INT32, INT32, INT32);
|
||||
GENERATE(Token::ADD, INT32, INT32, NUMBER);
|
||||
GENERATE(Token::ADD, INT32, NUMBER, NUMBER);
|
||||
GENERATE(Token::ADD, INT32, SMI, INT32);
|
||||
GENERATE(Token::ADD, NUMBER, INT32, NUMBER);
|
||||
GENERATE(Token::ADD, NUMBER, NUMBER, NUMBER);
|
||||
GENERATE(Token::ADD, NUMBER, SMI, NUMBER);
|
||||
GENERATE(Token::ADD, SMI, INT32, INT32);
|
||||
GENERATE(Token::ADD, SMI, INT32, NUMBER);
|
||||
GENERATE(Token::ADD, SMI, NUMBER, NUMBER);
|
||||
GENERATE(Token::ADD, SMI, SMI, INT32);
|
||||
GENERATE(Token::ADD, SMI, SMI, SMI);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, INT32);
|
||||
GENERATE(Token::BIT_AND, INT32, INT32, SMI);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, INT32);
|
||||
GENERATE(Token::BIT_AND, INT32, SMI, SMI);
|
||||
GENERATE(Token::BIT_AND, NUMBER, INT32, INT32);
|
||||
GENERATE(Token::BIT_AND, NUMBER, SMI, SMI);
|
||||
GENERATE(Token::BIT_AND, SMI, INT32, INT32);
|
||||
GENERATE(Token::BIT_AND, SMI, INT32, SMI);
|
||||
GENERATE(Token::BIT_AND, SMI, NUMBER, SMI);
|
||||
GENERATE(Token::BIT_AND, SMI, SMI, SMI);
|
||||
GENERATE(Token::BIT_OR, INT32, INT32, INT32);
|
||||
GENERATE(Token::BIT_OR, INT32, INT32, SMI);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, INT32);
|
||||
GENERATE(Token::BIT_OR, INT32, SMI, SMI);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, INT32);
|
||||
GENERATE(Token::BIT_OR, NUMBER, SMI, SMI);
|
||||
GENERATE(Token::BIT_OR, SMI, INT32, INT32);
|
||||
GENERATE(Token::BIT_OR, SMI, INT32, SMI);
|
||||
GENERATE(Token::BIT_OR, SMI, SMI, SMI);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, INT32);
|
||||
GENERATE(Token::BIT_XOR, INT32, INT32, SMI);
|
||||
GENERATE(Token::BIT_XOR, INT32, NUMBER, SMI);
|
||||
GENERATE(Token::BIT_XOR, INT32, SMI, INT32);
|
||||
GENERATE(Token::BIT_XOR, NUMBER, INT32, INT32);
|
||||
GENERATE(Token::BIT_XOR, NUMBER, SMI, INT32);
|
||||
GENERATE(Token::BIT_XOR, NUMBER, SMI, SMI);
|
||||
GENERATE(Token::BIT_XOR, SMI, INT32, INT32);
|
||||
GENERATE(Token::BIT_XOR, SMI, INT32, SMI);
|
||||
GENERATE(Token::BIT_XOR, SMI, SMI, SMI);
|
||||
GENERATE(Token::DIV, INT32, INT32, INT32);
|
||||
GENERATE(Token::DIV, INT32, INT32, NUMBER);
|
||||
GENERATE(Token::DIV, INT32, NUMBER, NUMBER);
|
||||
GENERATE(Token::DIV, INT32, SMI, INT32);
|
||||
GENERATE(Token::DIV, INT32, SMI, NUMBER);
|
||||
GENERATE(Token::DIV, NUMBER, INT32, NUMBER);
|
||||
GENERATE(Token::DIV, NUMBER, NUMBER, NUMBER);
|
||||
GENERATE(Token::DIV, NUMBER, SMI, NUMBER);
|
||||
GENERATE(Token::DIV, SMI, INT32, INT32);
|
||||
GENERATE(Token::DIV, SMI, INT32, NUMBER);
|
||||
GENERATE(Token::DIV, SMI, NUMBER, NUMBER);
|
||||
GENERATE(Token::DIV, SMI, SMI, NUMBER);
|
||||
GENERATE(Token::DIV, SMI, SMI, SMI);
|
||||
GENERATE(Token::MOD, NUMBER, SMI, NUMBER);
|
||||
GENERATE(Token::MOD, SMI, SMI, SMI);
|
||||
GENERATE(Token::MUL, INT32, INT32, INT32);
|
||||
GENERATE(Token::MUL, INT32, INT32, NUMBER);
|
||||
GENERATE(Token::MUL, INT32, NUMBER, NUMBER);
|
||||
GENERATE(Token::MUL, INT32, SMI, INT32);
|
||||
GENERATE(Token::MUL, INT32, SMI, NUMBER);
|
||||
GENERATE(Token::MUL, NUMBER, INT32, NUMBER);
|
||||
GENERATE(Token::MUL, NUMBER, NUMBER, NUMBER);
|
||||
GENERATE(Token::MUL, NUMBER, SMI, NUMBER);
|
||||
GENERATE(Token::MUL, SMI, INT32, INT32);
|
||||
GENERATE(Token::MUL, SMI, INT32, NUMBER);
|
||||
GENERATE(Token::MUL, SMI, NUMBER, NUMBER);
|
||||
GENERATE(Token::MUL, SMI, SMI, INT32);
|
||||
GENERATE(Token::MUL, SMI, SMI, NUMBER);
|
||||
GENERATE(Token::MUL, SMI, SMI, SMI);
|
||||
GENERATE(Token::SAR, INT32, SMI, INT32);
|
||||
GENERATE(Token::SAR, INT32, SMI, SMI);
|
||||
GENERATE(Token::SAR, NUMBER, SMI, SMI);
|
||||
GENERATE(Token::SAR, SMI, SMI, SMI);
|
||||
GENERATE(Token::SHL, INT32, SMI, INT32);
|
||||
GENERATE(Token::SHL, INT32, SMI, SMI);
|
||||
GENERATE(Token::SHL, NUMBER, SMI, SMI);
|
||||
GENERATE(Token::SHL, SMI, SMI, INT32);
|
||||
GENERATE(Token::SHL, SMI, SMI, SMI);
|
||||
GENERATE(Token::SHR, INT32, SMI, SMI);
|
||||
GENERATE(Token::SHR, NUMBER, SMI, INT32);
|
||||
GENERATE(Token::SHR, NUMBER, SMI, SMI);
|
||||
GENERATE(Token::SHR, SMI, SMI, SMI);
|
||||
GENERATE(Token::SUB, INT32, INT32, INT32);
|
||||
GENERATE(Token::SUB, INT32, NUMBER, NUMBER);
|
||||
GENERATE(Token::SUB, INT32, SMI, INT32);
|
||||
GENERATE(Token::SUB, NUMBER, INT32, NUMBER);
|
||||
GENERATE(Token::SUB, NUMBER, NUMBER, NUMBER);
|
||||
GENERATE(Token::SUB, NUMBER, SMI, NUMBER);
|
||||
GENERATE(Token::SUB, SMI, INT32, INT32);
|
||||
GENERATE(Token::SUB, SMI, NUMBER, NUMBER);
|
||||
GENERATE(Token::SUB, SMI, SMI, SMI);
|
||||
#undef GENERATE
|
||||
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind, mode) \
|
||||
do { \
|
||||
BinaryOpICState state(isolate, op, mode); \
|
||||
state.left_kind_ = left_kind; \
|
||||
state.fixed_right_arg_.has_value = true; \
|
||||
state.fixed_right_arg_.value = fixed_right_arg_value; \
|
||||
state.right_kind_ = SMI; \
|
||||
state.result_kind_ = result_kind; \
|
||||
Generate(isolate, state); \
|
||||
#define GENERATE(op, left_kind, fixed_right_arg_value, result_kind) \
|
||||
do { \
|
||||
BinaryOpICState state(isolate, op); \
|
||||
state.left_kind_ = left_kind; \
|
||||
state.fixed_right_arg_.has_value = true; \
|
||||
state.fixed_right_arg_.value = fixed_right_arg_value; \
|
||||
state.right_kind_ = SMI; \
|
||||
state.result_kind_ = result_kind; \
|
||||
Generate(isolate, state); \
|
||||
} while (false)
|
||||
GENERATE(Token::MOD, SMI, 2, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MOD, SMI, 4, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MOD, SMI, 4, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MOD, SMI, 8, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MOD, SMI, 16, SMI, OVERWRITE_LEFT);
|
||||
GENERATE(Token::MOD, SMI, 32, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MOD, SMI, 2048, SMI, NO_OVERWRITE);
|
||||
GENERATE(Token::MOD, SMI, 2, SMI);
|
||||
GENERATE(Token::MOD, SMI, 4, SMI);
|
||||
GENERATE(Token::MOD, SMI, 8, SMI);
|
||||
GENERATE(Token::MOD, SMI, 16, SMI);
|
||||
GENERATE(Token::MOD, SMI, 32, SMI);
|
||||
GENERATE(Token::MOD, SMI, 2048, SMI);
|
||||
#undef GENERATE
|
||||
}
|
||||
|
||||
@ -319,10 +223,6 @@ Type* BinaryOpICState::GetResultType(Zone* zone) const {
|
||||
|
||||
std::ostream& operator<<(std::ostream& os, const BinaryOpICState& s) {
|
||||
os << "(" << Token::Name(s.op_);
|
||||
if (s.mode_ == OVERWRITE_LEFT)
|
||||
os << "_ReuseLeft";
|
||||
else if (s.mode_ == OVERWRITE_RIGHT)
|
||||
os << "_ReuseRight";
|
||||
if (s.CouldCreateAllocationMementos()) os << "_CreateAllocationMementos";
|
||||
os << ":" << BinaryOpICState::KindToString(s.left_kind_) << "*";
|
||||
if (s.fixed_right_arg_.has_value) {
|
||||
@ -372,14 +272,6 @@ void BinaryOpICState::Update(Handle<Object> left, Handle<Object> right,
|
||||
left_kind_ = NUMBER;
|
||||
}
|
||||
|
||||
// Reset overwrite mode unless we can actually make use of it, or may be able
|
||||
// to make use of it at some point in the future.
|
||||
if ((mode_ == OVERWRITE_LEFT && left_kind_ > NUMBER) ||
|
||||
(mode_ == OVERWRITE_RIGHT && right_kind_ > NUMBER) ||
|
||||
result_kind_ > NUMBER) {
|
||||
mode_ = NO_OVERWRITE;
|
||||
}
|
||||
|
||||
if (old_extra_ic_state == GetExtraICState()) {
|
||||
// Tagged operations can lead to non-truncating HChanges
|
||||
if (left->IsUndefined() || left->IsBoolean()) {
|
||||
|
@ -54,16 +54,12 @@ class CallICState FINAL BASE_EMBEDDED {
|
||||
std::ostream& operator<<(std::ostream& os, const CallICState& s);
|
||||
|
||||
|
||||
// Mode to overwrite BinaryExpression values.
|
||||
enum OverwriteMode { NO_OVERWRITE, OVERWRITE_LEFT, OVERWRITE_RIGHT };
|
||||
|
||||
class BinaryOpICState FINAL BASE_EMBEDDED {
|
||||
public:
|
||||
BinaryOpICState(Isolate* isolate, ExtraICState extra_ic_state);
|
||||
|
||||
BinaryOpICState(Isolate* isolate, Token::Value op, OverwriteMode mode)
|
||||
BinaryOpICState(Isolate* isolate, Token::Value op)
|
||||
: op_(op),
|
||||
mode_(mode),
|
||||
left_kind_(NONE),
|
||||
right_kind_(NONE),
|
||||
result_kind_(NONE),
|
||||
@ -91,14 +87,6 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
|
||||
void (*Generate)(Isolate*,
|
||||
const BinaryOpICState&));
|
||||
|
||||
bool CanReuseDoubleBox() const {
|
||||
return (result_kind_ > SMI && result_kind_ <= NUMBER) &&
|
||||
((mode_ == OVERWRITE_LEFT && left_kind_ > SMI &&
|
||||
left_kind_ <= NUMBER) ||
|
||||
(mode_ == OVERWRITE_RIGHT && right_kind_ > SMI &&
|
||||
right_kind_ <= NUMBER));
|
||||
}
|
||||
|
||||
// Returns true if the IC _could_ create allocation mementos.
|
||||
bool CouldCreateAllocationMementos() const {
|
||||
if (left_kind_ == STRING || right_kind_ == STRING) {
|
||||
@ -127,7 +115,6 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
|
||||
static const int LAST_TOKEN = Token::MOD;
|
||||
|
||||
Token::Value op() const { return op_; }
|
||||
OverwriteMode mode() const { return mode_; }
|
||||
Maybe<int> fixed_right_arg() const { return fixed_right_arg_; }
|
||||
|
||||
Type* GetLeftType(Zone* zone) const { return KindToType(left_kind_, zone); }
|
||||
@ -154,17 +141,15 @@ class BinaryOpICState FINAL BASE_EMBEDDED {
|
||||
// We truncate the last bit of the token.
|
||||
STATIC_ASSERT(LAST_TOKEN - FIRST_TOKEN < (1 << 4));
|
||||
class OpField : public BitField<int, 0, 4> {};
|
||||
class OverwriteModeField : public BitField<OverwriteMode, 4, 2> {};
|
||||
class ResultKindField : public BitField<Kind, 6, 3> {};
|
||||
class LeftKindField : public BitField<Kind, 9, 3> {};
|
||||
class ResultKindField : public BitField<Kind, 4, 3> {};
|
||||
class LeftKindField : public BitField<Kind, 7, 3> {};
|
||||
// When fixed right arg is set, we don't need to store the right kind.
|
||||
// Thus the two fields can overlap.
|
||||
class HasFixedRightArgField : public BitField<bool, 12, 1> {};
|
||||
class FixedRightArgValueField : public BitField<int, 13, 4> {};
|
||||
class RightKindField : public BitField<Kind, 13, 3> {};
|
||||
class HasFixedRightArgField : public BitField<bool, 10, 1> {};
|
||||
class FixedRightArgValueField : public BitField<int, 11, 4> {};
|
||||
class RightKindField : public BitField<Kind, 11, 3> {};
|
||||
|
||||
Token::Value op_;
|
||||
OverwriteMode mode_;
|
||||
Kind left_kind_;
|
||||
Kind right_kind_;
|
||||
Kind result_kind_;
|
||||
|
@ -1997,19 +1997,15 @@ void FullCodeGenerator::VisitAssignment(Assignment* expr) {
|
||||
__ Push(rax); // Left operand goes on the stack.
|
||||
VisitForAccumulatorValue(expr->value());
|
||||
|
||||
OverwriteMode mode = expr->value()->ResultOverwriteAllowed()
|
||||
? OVERWRITE_RIGHT
|
||||
: NO_OVERWRITE;
|
||||
SetSourcePosition(expr->position() + 1);
|
||||
AccumulatorValueContext context(this);
|
||||
if (ShouldInlineSmiCase(op)) {
|
||||
EmitInlineSmiBinaryOp(expr->binary_operation(),
|
||||
op,
|
||||
mode,
|
||||
expr->target(),
|
||||
expr->value());
|
||||
} else {
|
||||
EmitBinaryOp(expr->binary_operation(), op, mode);
|
||||
EmitBinaryOp(expr->binary_operation(), op);
|
||||
}
|
||||
// Deoptimization point in case the binary operation may have side effects.
|
||||
PrepareForBailout(expr->binary_operation(), TOS_REG);
|
||||
@ -2389,7 +2385,6 @@ void FullCodeGenerator::EmitKeyedSuperPropertyLoad(Property* prop) {
|
||||
|
||||
void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode,
|
||||
Expression* left,
|
||||
Expression* right) {
|
||||
// Do combined smi check of the operands. Left operand is on the
|
||||
@ -2404,7 +2399,7 @@ void FullCodeGenerator::EmitInlineSmiBinaryOp(BinaryOperation* expr,
|
||||
|
||||
__ bind(&stub_call);
|
||||
__ movp(rax, rcx);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
__ jmp(&done, Label::kNear);
|
||||
@ -2504,11 +2499,9 @@ void FullCodeGenerator::EmitClassDefineProperties(ClassLiteral* lit) {
|
||||
}
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr,
|
||||
Token::Value op,
|
||||
OverwriteMode mode) {
|
||||
void FullCodeGenerator::EmitBinaryOp(BinaryOperation* expr, Token::Value op) {
|
||||
__ Pop(rdx);
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op, mode).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), op).code();
|
||||
JumpPatchSite patch_site(masm_); // unbound, signals no inlined smi code.
|
||||
CallIC(code, expr->BinaryOperationFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
@ -4799,8 +4792,8 @@ void FullCodeGenerator::VisitCountOperation(CountOperation* expr) {
|
||||
__ bind(&stub_call);
|
||||
__ movp(rdx, rax);
|
||||
__ Move(rax, Smi::FromInt(1));
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), expr->binary_op(),
|
||||
NO_OVERWRITE).code();
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), expr->binary_op()).code();
|
||||
CallIC(code, expr->CountBinOpFeedbackId());
|
||||
patch_site.EmitPatchInfo();
|
||||
__ bind(&done);
|
||||
|
@ -2065,8 +2065,7 @@ void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
|
||||
DCHECK(ToRegister(instr->right()).is(rax));
|
||||
DCHECK(ToRegister(instr->result()).is(rax));
|
||||
|
||||
Handle<Code> code =
|
||||
CodeFactory::BinaryOpIC(isolate(), instr->op(), NO_OVERWRITE).code();
|
||||
Handle<Code> code = CodeFactory::BinaryOpIC(isolate(), instr->op()).code();
|
||||
CallCode(code, RelocInfo::CODE_TARGET, instr);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user