diff --git a/src/maglev/maglev-graph-builder.cc b/src/maglev/maglev-graph-builder.cc index 46148a3b056b..720b10c89e2b 100644 --- a/src/maglev/maglev-graph-builder.cc +++ b/src/maglev/maglev-graph-builder.cc @@ -1265,7 +1265,21 @@ void MaglevGraphBuilder::VisitBitwiseNot() { } MAGLEV_UNIMPLEMENTED_BYTECODE(ToBooleanLogicalNot) -MAGLEV_UNIMPLEMENTED_BYTECODE(LogicalNot) + +void MaglevGraphBuilder::VisitLogicalNot() { + // Invariant: accumulator must already be a boolean value. + ValueNode* value = GetAccumulatorTagged(); + if (RootConstant* constant = value->TryCast()) { + if (constant->index() == RootIndex::kTrueValue) { + SetAccumulator(GetRootConstant(RootIndex::kFalseValue)); + } else { + DCHECK_EQ(constant->index(), RootIndex::kFalseValue); + SetAccumulator(GetRootConstant(RootIndex::kTrueValue)); + } + } + SetAccumulator(AddNewNode({value})); +} + MAGLEV_UNIMPLEMENTED_BYTECODE(TypeOf) MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertyStrict) MAGLEV_UNIMPLEMENTED_BYTECODE(DeletePropertySloppy) diff --git a/src/maglev/maglev-graph-verifier.h b/src/maglev/maglev-graph-verifier.h index b3da4813f05c..96005e743533 100644 --- a/src/maglev/maglev-graph-verifier.h +++ b/src/maglev/maglev-graph-verifier.h @@ -105,6 +105,7 @@ class MaglevGraphVerifier { case Opcode::kCreateFunctionContext: case Opcode::kCreateClosure: case Opcode::kFastCreateClosure: + case Opcode::kLogicalNot: case Opcode::kTestUndetectable: case Opcode::kReturn: DCHECK_EQ(node->input_count(), 1); diff --git a/src/maglev/maglev-ir.cc b/src/maglev/maglev-ir.cc index 9da7409fae22..2a84c8784bfe 100644 --- a/src/maglev/maglev-ir.cc +++ b/src/maglev/maglev-ir.cc @@ -1718,6 +1718,35 @@ void CheckedFloat64Unbox::GenerateCode(MaglevCodeGenState* code_gen_state, __ bind(&done); } +void LogicalNot::AllocateVreg(MaglevVregAllocationState* vreg_state) { + UseRegister(value()); + DefineAsRegister(vreg_state, this); +} +void LogicalNot::GenerateCode(MaglevCodeGenState* code_gen_state, + const ProcessingState& state) { + Register object = ToRegister(value()); + Register return_value = ToRegister(result()); + Label not_equal_true; + // We load the constant true to the return value and we return it if the + // object is not equal to it. Otherwise we load the constant false. + __ LoadRoot(return_value, RootIndex::kTrueValue); + __ cmp_tagged(return_value, object); + __ j(not_equal, ¬_equal_true); + __ LoadRoot(return_value, RootIndex::kFalseValue); + if (FLAG_debug_code) { + Label is_equal_true; + __ jmp(&is_equal_true); + __ bind(¬_equal_true); + // LogicalNot expects either the constants true or false. + // We know it is not true, so it must be false! + __ CompareRoot(object, RootIndex::kFalseValue); + __ Check(equal, AbortReason::kUnexpectedValue); + __ bind(&is_equal_true); + } else { + __ bind(¬_equal_true); + } +} + void TaggedEqual::AllocateVreg(MaglevVregAllocationState* vreg_state) { UseRegister(lhs()); UseRegister(rhs()); diff --git a/src/maglev/maglev-ir.h b/src/maglev/maglev-ir.h index 3a7fc1c90334..d020223f6d32 100644 --- a/src/maglev/maglev-ir.h +++ b/src/maglev/maglev-ir.h @@ -145,6 +145,7 @@ class CompactInterpreterFrameState; V(ChangeInt32ToFloat64) \ V(Float64Box) \ V(CheckedFloat64Unbox) \ + V(LogicalNot) \ V(TaggedEqual) \ V(TestInstanceOf) \ V(TestUndetectable) \ @@ -1544,6 +1545,19 @@ class CheckedFloat64Unbox void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} }; +class LogicalNot : public FixedInputValueNodeT<1, LogicalNot> { + using Base = FixedInputValueNodeT<1, LogicalNot>; + + public: + explicit LogicalNot(uint64_t bitfield) : Base(bitfield) {} + + Input& value() { return Node::input(0); } + + void AllocateVreg(MaglevVregAllocationState*); + void GenerateCode(MaglevCodeGenState*, const ProcessingState&); + void PrintParams(std::ostream&, MaglevGraphLabeller*) const {} +}; + class TaggedEqual : public FixedInputValueNodeT<2, TaggedEqual> { using Base = FixedInputValueNodeT<2, TaggedEqual>;