Commit d8864701 authored by pan.deng@intel.com's avatar pan.deng@intel.com Committed by Commit Bot

[csa] Add constant folding more universally to CodeAssembler operators

             
Contributed by kanghua.yu@intel.com.

Bug: None
Change-Id: I5651ef38eb0c08deb97770a5eaa985dba2dab9a9
Reviewed-on: https://chromium-review.googlesource.com/604648Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Reviewed-by: 's avatarIgor Sheludko <ishell@chromium.org>
Commit-Queue: Pan Deng <pan.deng@intel.com>
Cr-Commit-Position: refs/heads/master@{#47968}
parent 6ba92d0f
......@@ -504,6 +504,10 @@ TNode<Smi> CodeStubAssembler::SmiTag(SloppyTNode<IntPtrT> value) {
}
TNode<IntPtrT> CodeStubAssembler::SmiUntag(SloppyTNode<Smi> value) {
intptr_t constant_value;
if (ToIntPtrConstant(value, constant_value)) {
return IntPtrConstant(constant_value >> (kSmiShiftSize + kSmiTagSize));
}
return UncheckedCast<IntPtrT>(
WordSar(BitcastTaggedToWord(value), SmiShiftBitsConstant()));
}
......@@ -5374,12 +5378,24 @@ TNode<IntPtrT> CodeStubAssembler::HashTableComputeCapacity(
TNode<IntPtrT> CodeStubAssembler::IntPtrMax(SloppyTNode<IntPtrT> left,
SloppyTNode<IntPtrT> right) {
intptr_t left_constant;
intptr_t right_constant;
if (ToIntPtrConstant(left, left_constant) &&
ToIntPtrConstant(right, right_constant)) {
return IntPtrConstant(std::max(left_constant, right_constant));
}
return SelectConstant(IntPtrGreaterThanOrEqual(left, right), left, right,
MachineType::PointerRepresentation());
}
TNode<IntPtrT> CodeStubAssembler::IntPtrMin(SloppyTNode<IntPtrT> left,
SloppyTNode<IntPtrT> right) {
intptr_t left_constant;
intptr_t right_constant;
if (ToIntPtrConstant(left, left_constant) &&
ToIntPtrConstant(right, right_constant)) {
return IntPtrConstant(std::min(left_constant, right_constant));
}
return SelectConstant(IntPtrLessThanOrEqual(left, right), left, right,
MachineType::PointerRepresentation());
}
......
......@@ -438,6 +438,27 @@ TNode<WordT> CodeAssembler::IntPtrSub(SloppyTNode<WordT> left,
return UncheckedCast<IntPtrT>(raw_assembler()->IntPtrSub(left, right));
}
TNode<WordT> CodeAssembler::IntPtrMul(SloppyTNode<WordT> left,
SloppyTNode<WordT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(left_constant * right_constant);
}
if (left_constant == 1) {
return right;
}
} else if (is_right_constant) {
if (right_constant == 1) {
return left;
}
}
return UncheckedCast<IntPtrT>(raw_assembler()->IntPtrMul(left, right));
}
TNode<WordT> CodeAssembler::WordShl(SloppyTNode<WordT> value, int shift) {
return (shift != 0) ? WordShl(value, IntPtrConstant(shift)) : value;
}
......@@ -450,6 +471,318 @@ TNode<Word32T> CodeAssembler::Word32Shr(SloppyTNode<Word32T> value, int shift) {
return (shift != 0) ? Word32Shr(value, Int32Constant(shift)) : value;
}
TNode<WordT> CodeAssembler::WordOr(SloppyTNode<WordT> left,
SloppyTNode<WordT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(left_constant | right_constant);
}
if (left_constant == 0) {
return right;
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<WordT>(raw_assembler()->WordOr(left, right));
}
TNode<WordT> CodeAssembler::WordAnd(SloppyTNode<WordT> left,
SloppyTNode<WordT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(left_constant & right_constant);
}
}
return UncheckedCast<WordT>(raw_assembler()->WordAnd(left, right));
}
TNode<WordT> CodeAssembler::WordXor(SloppyTNode<WordT> left,
SloppyTNode<WordT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(left_constant ^ right_constant);
}
}
return UncheckedCast<WordT>(raw_assembler()->WordXor(left, right));
}
TNode<WordT> CodeAssembler::WordShl(SloppyTNode<WordT> left,
SloppyTNode<IntegralT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(left_constant << right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<WordT>(raw_assembler()->WordShl(left, right));
}
TNode<WordT> CodeAssembler::WordShr(SloppyTNode<WordT> left,
SloppyTNode<IntegralT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(static_cast<uintptr_t>(left_constant) >>
right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<WordT>(raw_assembler()->WordShr(left, right));
}
TNode<WordT> CodeAssembler::WordSar(SloppyTNode<WordT> left,
SloppyTNode<IntegralT> right) {
intptr_t left_constant;
bool is_left_constant = ToIntPtrConstant(left, left_constant);
intptr_t right_constant;
bool is_right_constant = ToIntPtrConstant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return IntPtrConstant(left_constant >> right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<WordT>(raw_assembler()->WordSar(left, right));
}
TNode<Word32T> CodeAssembler::Word32Or(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right) {
int32_t left_constant;
bool is_left_constant = ToInt32Constant(left, left_constant);
int32_t right_constant;
bool is_right_constant = ToInt32Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int32Constant(left_constant | right_constant);
}
if (left_constant == 0) {
return right;
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word32T>(raw_assembler()->Word32Or(left, right));
}
TNode<Word32T> CodeAssembler::Word32And(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right) {
int32_t left_constant;
bool is_left_constant = ToInt32Constant(left, left_constant);
int32_t right_constant;
bool is_right_constant = ToInt32Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int32Constant(left_constant & right_constant);
}
}
return UncheckedCast<Word32T>(raw_assembler()->Word32And(left, right));
}
TNode<Word32T> CodeAssembler::Word32Xor(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right) {
int32_t left_constant;
bool is_left_constant = ToInt32Constant(left, left_constant);
int32_t right_constant;
bool is_right_constant = ToInt32Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int32Constant(left_constant ^ right_constant);
}
}
return UncheckedCast<Word32T>(raw_assembler()->Word32Xor(left, right));
}
TNode<Word32T> CodeAssembler::Word32Shl(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right) {
int32_t left_constant;
bool is_left_constant = ToInt32Constant(left, left_constant);
int32_t right_constant;
bool is_right_constant = ToInt32Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int32Constant(left_constant << right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word32T>(raw_assembler()->Word32Shl(left, right));
}
TNode<Word32T> CodeAssembler::Word32Shr(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right) {
int32_t left_constant;
bool is_left_constant = ToInt32Constant(left, left_constant);
int32_t right_constant;
bool is_right_constant = ToInt32Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int32Constant(static_cast<uint32_t>(left_constant) >>
right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word32T>(raw_assembler()->Word32Shr(left, right));
}
TNode<Word32T> CodeAssembler::Word32Sar(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right) {
int32_t left_constant;
bool is_left_constant = ToInt32Constant(left, left_constant);
int32_t right_constant;
bool is_right_constant = ToInt32Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int32Constant(left_constant >> right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word32T>(raw_assembler()->Word32Sar(left, right));
}
TNode<Word64T> CodeAssembler::Word64Or(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right) {
int64_t left_constant;
bool is_left_constant = ToInt64Constant(left, left_constant);
int64_t right_constant;
bool is_right_constant = ToInt64Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int64Constant(left_constant | right_constant);
}
if (left_constant == 0) {
return right;
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word64T>(raw_assembler()->Word64Or(left, right));
}
TNode<Word64T> CodeAssembler::Word64And(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right) {
int64_t left_constant;
bool is_left_constant = ToInt64Constant(left, left_constant);
int64_t right_constant;
bool is_right_constant = ToInt64Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int64Constant(left_constant & right_constant);
}
}
return UncheckedCast<Word64T>(raw_assembler()->Word64And(left, right));
}
TNode<Word64T> CodeAssembler::Word64Xor(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right) {
int64_t left_constant;
bool is_left_constant = ToInt64Constant(left, left_constant);
int64_t right_constant;
bool is_right_constant = ToInt64Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int64Constant(left_constant ^ right_constant);
}
}
return UncheckedCast<Word64T>(raw_assembler()->Word64Xor(left, right));
}
TNode<Word64T> CodeAssembler::Word64Shl(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right) {
int64_t left_constant;
bool is_left_constant = ToInt64Constant(left, left_constant);
int64_t right_constant;
bool is_right_constant = ToInt64Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int64Constant(left_constant << right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word64T>(raw_assembler()->Word64Shl(left, right));
}
TNode<Word64T> CodeAssembler::Word64Shr(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right) {
int64_t left_constant;
bool is_left_constant = ToInt64Constant(left, left_constant);
int64_t right_constant;
bool is_right_constant = ToInt64Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int64Constant(static_cast<uint64_t>(left_constant) >>
right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word64T>(raw_assembler()->Word64Shr(left, right));
}
TNode<Word64T> CodeAssembler::Word64Sar(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right) {
int64_t left_constant;
bool is_left_constant = ToInt64Constant(left, left_constant);
int64_t right_constant;
bool is_right_constant = ToInt64Constant(right, right_constant);
if (is_left_constant) {
if (is_right_constant) {
return Int64Constant(left_constant >> right_constant);
}
} else if (is_right_constant) {
if (right_constant == 0) {
return left;
}
}
return UncheckedCast<Word64T>(raw_assembler()->Word64Sar(left, right));
}
TNode<UintPtrT> CodeAssembler::ChangeUint32ToWord(SloppyTNode<Word32T> value) {
if (raw_assembler()->machine()->Is64()) {
return UncheckedCast<UintPtrT>(
......
......@@ -268,7 +268,6 @@ class SloppyTNode : public TNode<A> {
V(Float64InsertHighWord32, Float64T, Float64T, Word32T) \
V(IntPtrAddWithOverflow, IntPtrT, IntPtrT, IntPtrT) \
V(IntPtrSubWithOverflow, IntPtrT, IntPtrT, IntPtrT) \
V(IntPtrMul, IntPtrT, IntPtrT, IntPtrT) \
V(Int32Add, Word32T, Word32T, Word32T) \
V(Int32AddWithOverflow, Int32T, Int32T, Int32T) \
V(Int32Sub, Word32T, Word32T, Word32T) \
......@@ -276,25 +275,8 @@ class SloppyTNode : public TNode<A> {
V(Int32MulWithOverflow, Int32T, Int32T, Int32T) \
V(Int32Div, Int32T, Int32T, Int32T) \
V(Int32Mod, Int32T, Int32T, Int32T) \
V(WordOr, WordT, WordT, WordT) \
V(WordAnd, WordT, WordT, WordT) \
V(WordXor, WordT, WordT, WordT) \
V(WordShl, WordT, WordT, IntegralT) \
V(WordShr, WordT, WordT, IntegralT) \
V(WordSar, WordT, WordT, IntegralT) \
V(WordRor, WordT, WordT, IntegralT) \
V(Word32Or, Word32T, Word32T, Word32T) \
V(Word32And, Word32T, Word32T, Word32T) \
V(Word32Xor, Word32T, Word32T, Word32T) \
V(Word32Shl, Word32T, Word32T, Word32T) \
V(Word32Shr, Word32T, Word32T, Word32T) \
V(Word32Sar, Word32T, Word32T, Word32T) \
V(Word32Ror, Word32T, Word32T, Word32T) \
V(Word64Or, Word64T, Word64T, Word64T) \
V(Word64And, Word64T, Word64T, Word64T) \
V(Word64Xor, Word64T, Word64T, Word64T) \
V(Word64Shr, Word64T, Word64T, Word64T) \
V(Word64Sar, Word64T, Word64T, Word64T) \
V(Word64Ror, Word64T, Word64T, Word64T)
TNode<Float64T> Float64Add(TNode<Float64T> a, TNode<Float64T> b);
......@@ -625,6 +607,7 @@ class V8_EXPORT_PRIVATE CodeAssembler {
TNode<WordT> IntPtrAdd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> IntPtrSub(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> IntPtrMul(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<IntPtrT> IntPtrAdd(TNode<IntPtrT> left, TNode<IntPtrT> right) {
return Signed(
IntPtrAdd(static_cast<Node*>(left), static_cast<Node*>(right)));
......@@ -633,6 +616,10 @@ class V8_EXPORT_PRIVATE CodeAssembler {
return Signed(
IntPtrSub(static_cast<Node*>(left), static_cast<Node*>(right)));
}
TNode<IntPtrT> IntPtrMul(TNode<IntPtrT> left, TNode<IntPtrT> right) {
return Signed(
IntPtrMul(static_cast<Node*>(left), static_cast<Node*>(right)));
}
TNode<WordT> WordShl(SloppyTNode<WordT> value, int shift);
TNode<WordT> WordShr(SloppyTNode<WordT> value, int shift);
......@@ -641,6 +628,37 @@ class V8_EXPORT_PRIVATE CodeAssembler {
}
TNode<Word32T> Word32Shr(SloppyTNode<Word32T> value, int shift);
TNode<WordT> WordOr(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> WordAnd(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> WordXor(SloppyTNode<WordT> left, SloppyTNode<WordT> right);
TNode<WordT> WordShl(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
TNode<WordT> WordShr(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
TNode<WordT> WordSar(SloppyTNode<WordT> left, SloppyTNode<IntegralT> right);
TNode<Word32T> Word32Or(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right);
TNode<Word32T> Word32And(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right);
TNode<Word32T> Word32Xor(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right);
TNode<Word32T> Word32Shl(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right);
TNode<Word32T> Word32Shr(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right);
TNode<Word32T> Word32Sar(SloppyTNode<Word32T> left,
SloppyTNode<Word32T> right);
TNode<Word64T> Word64Or(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right);
TNode<Word64T> Word64And(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right);
TNode<Word64T> Word64Xor(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right);
TNode<Word64T> Word64Shl(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right);
TNode<Word64T> Word64Shr(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right);
TNode<Word64T> Word64Sar(SloppyTNode<Word64T> left,
SloppyTNode<Word64T> right);
// Unary
#define DECLARE_CODE_ASSEMBLER_UNARY_OP(name, ResType, ArgType) \
TNode<ResType> name(SloppyTNode<ArgType> a);
......
......@@ -343,7 +343,7 @@ static const int kMaxBuiltinRegisterParams = 5;
kStackParameterCount = kArity + 1 \
};
class VoidDescriptor : public CallInterfaceDescriptor {
class V8_EXPORT_PRIVATE VoidDescriptor : public CallInterfaceDescriptor {
public:
DECLARE_DESCRIPTOR(VoidDescriptor, CallInterfaceDescriptor)
};
......
......@@ -41,6 +41,8 @@ v8_executable("unittests") {
"base/utils/random-number-generator-unittest.cc",
"cancelable-tasks-unittest.cc",
"char-predicates-unittest.cc",
"code-stub-assembler-unittest.cc",
"code-stub-assembler-unittest.h",
"compiler-dispatcher/compiler-dispatcher-tracer-unittest.cc",
"compiler-dispatcher/compiler-dispatcher-unittest.cc",
"compiler-dispatcher/optimizing-compile-dispatcher-unittest.cc",
......@@ -48,6 +50,8 @@ v8_executable("unittests") {
"compiler/branch-elimination-unittest.cc",
"compiler/bytecode-analysis-unittest.cc",
"compiler/checkpoint-elimination-unittest.cc",
"compiler/code-assembler-unittest.cc",
"compiler/code-assembler-unittest.h",
"compiler/common-operator-reducer-unittest.cc",
"compiler/common-operator-unittest.cc",
"compiler/compiler-test-utils.h",
......
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "test/unittests/code-stub-assembler-unittest.h"
#include "src/code-factory.h"
#include "src/compiler/node.h"
#include "src/interface-descriptors.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "test/unittests/compiler/compiler-test-utils.h"
#include "test/unittests/compiler/node-test-utils.h"
using ::testing::_;
using v8::internal::compiler::Node;
namespace c = v8::internal::compiler;
namespace v8 {
namespace internal {
#ifdef ENABLE_VERIFY_CSA
#define IS_BITCAST_WORD_TO_TAGGED_SIGNED(x) IsBitcastWordToTaggedSigned(x)
#define IS_BITCAST_TAGGED_TO_WORD(x) IsBitcastTaggedToWord(x)
#else
#define IS_BITCAST_WORD_TO_TAGGED_SIGNED(x) (x)
#define IS_BITCAST_TAGGED_TO_WORD(x) (x)
#endif
CodeStubAssemblerTestState::CodeStubAssemblerTestState(
CodeStubAssemblerTest* test)
: compiler::CodeAssemblerState(test->isolate(), test->zone(),
VoidDescriptor(test->isolate()),
Code::ComputeFlags(Code::STUB), "test") {}
TARGET_TEST_F(CodeStubAssemblerTest, SmiTag) {
CodeStubAssemblerTestState state(this);
CodeStubAssemblerForTest m(&state);
Node* value = m.Int32Constant(44);
EXPECT_THAT(m.SmiTag(value),
IS_BITCAST_WORD_TO_TAGGED_SIGNED(c::IsIntPtrConstant(
static_cast<intptr_t>(44) << (kSmiShiftSize + kSmiTagSize))));
EXPECT_THAT(m.SmiUntag(value),
c::IsIntPtrConstant(static_cast<intptr_t>(44) >>
(kSmiShiftSize + kSmiTagSize)));
}
TARGET_TEST_F(CodeStubAssemblerTest, IntPtrMax) {
CodeStubAssemblerTestState state(this);
CodeStubAssemblerForTest m(&state);
{
Node* a = m.IntPtrConstant(100);
Node* b = m.IntPtrConstant(1);
Node* z = m.IntPtrMax(a, b);
EXPECT_THAT(z, c::IsIntPtrConstant(100));
}
}
TARGET_TEST_F(CodeStubAssemblerTest, IntPtrMin) {
CodeStubAssemblerTestState state(this);
CodeStubAssemblerForTest m(&state);
{
Node* a = m.IntPtrConstant(100);
Node* b = m.IntPtrConstant(1);
Node* z = m.IntPtrMin(a, b);
EXPECT_THAT(z, c::IsIntPtrConstant(1));
}
}
} // namespace internal
} // namespace v8
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_UNITTESTS_CODE_STUB_ASSEMBLER_UNITTEST_H_
#define V8_UNITTESTS_CODE_STUB_ASSEMBLER_UNITTEST_H_
#include "src/code-stub-assembler.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock-support.h"
namespace v8 {
namespace internal {
class CodeStubAssemblerTest : public TestWithIsolateAndZone {
public:
CodeStubAssemblerTest() {}
~CodeStubAssemblerTest() override {}
};
class CodeStubAssemblerTestState : public compiler::CodeAssemblerState {
public:
explicit CodeStubAssemblerTestState(CodeStubAssemblerTest* test);
};
class CodeStubAssemblerForTest : public CodeStubAssembler {
public:
explicit CodeStubAssemblerForTest(CodeStubAssemblerTestState* state)
: CodeStubAssembler(state) {}
};
} // namespace internal
} // namespace v8
#endif // V8_UNITTESTS_CODE_STUB_ASSEMBLER_UNITTEST_H_
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "test/unittests/compiler/code-assembler-unittest.h"
#include "src/code-factory.h"
#include "src/compiler/node.h"
#include "src/interface-descriptors.h"
#include "src/isolate.h"
#include "src/objects-inl.h"
#include "test/unittests/compiler/compiler-test-utils.h"
#include "test/unittests/compiler/node-test-utils.h"
using ::testing::_;
namespace v8 {
namespace internal {
namespace compiler {
CodeAssemblerTestState::CodeAssemblerTestState(CodeAssemblerTest* test)
: CodeAssemblerState(test->isolate(), test->zone(),
VoidDescriptor(test->isolate()),
Code::ComputeFlags(Code::STUB), "test") {}
TARGET_TEST_F(CodeAssemblerTest, IntPtrAdd) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(1);
Node* add = m.IntPtrAdd(a, b);
EXPECT_THAT(add, IsIntPtrAdd(a, b));
}
// x + 0 => x
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(0);
Node* add = m.IntPtrAdd(a, b);
EXPECT_THAT(add, a);
}
// 0 + x => x
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(0);
Node* add = m.IntPtrAdd(b, a);
EXPECT_THAT(add, a);
}
// CONST_a + CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(22);
Node* b = m.IntPtrConstant(33);
Node* c = m.IntPtrAdd(a, b);
EXPECT_THAT(c, IsIntPtrConstant(55));
}
}
TARGET_TEST_F(CodeAssemblerTest, IntPtrSub) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(1);
Node* sub = m.IntPtrSub(a, b);
EXPECT_THAT(sub, IsIntPtrSub(a, b));
}
// x - 0 => x
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(0);
Node* c = m.IntPtrSub(a, b);
EXPECT_THAT(c, a);
}
// CONST_a - CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(100);
Node* b = m.IntPtrConstant(1);
Node* c = m.IntPtrSub(a, b);
EXPECT_THAT(c, IsIntPtrConstant(99));
}
}
TARGET_TEST_F(CodeAssemblerTest, IntPtrMul) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(100);
Node* mul = m.IntPtrMul(a, b);
EXPECT_THAT(mul, IsIntPtrMul(a, b));
}
// x * 1 => x
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(1);
Node* mul = m.IntPtrMul(a, b);
EXPECT_THAT(mul, a);
}
// 1 * x => x
{
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(1);
Node* mul = m.IntPtrMul(b, a);
EXPECT_THAT(mul, a);
}
// CONST_a * CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(100);
Node* b = m.IntPtrConstant(5);
Node* c = m.IntPtrMul(a, b);
EXPECT_THAT(c, IsIntPtrConstant(500));
}
}
TARGET_TEST_F(CodeAssemblerTest, WordShl) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* add = m.WordShl(a, 10);
EXPECT_THAT(add, IsWordShl(a, IsIntPtrConstant(10)));
}
// x << 0 => x
{
Node* a = m.Parameter(0);
Node* add = m.WordShl(a, 0);
EXPECT_THAT(add, a);
}
// CONST_a << CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(1024);
Node* shl = m.WordShl(a, 2);
EXPECT_THAT(shl, IsIntPtrConstant(4096));
}
}
TARGET_TEST_F(CodeAssemblerTest, WordShr) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* shr = m.WordShr(a, 10);
EXPECT_THAT(shr, IsWordShr(a, IsIntPtrConstant(10)));
}
// x >> 0 => x
{
Node* a = m.Parameter(0);
Node* shr = m.WordShr(a, 0);
EXPECT_THAT(shr, a);
}
// +CONST_a >> CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(4096);
Node* shr = m.WordShr(a, 2);
EXPECT_THAT(shr, IsIntPtrConstant(1024));
}
// -CONST_a >> CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(-1234);
Node* shr = m.WordShr(a, 2);
EXPECT_THAT(shr, IsIntPtrConstant(static_cast<uintptr_t>(-1234) >> 2));
}
}
TARGET_TEST_F(CodeAssemblerTest, WordSar) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* sar = m.WordSar(a, m.IntPtrConstant(10));
EXPECT_THAT(sar, IsWordSar(a, IsIntPtrConstant(10)));
}
// x >>> 0 => x
{
Node* a = m.Parameter(0);
Node* sar = m.WordSar(a, m.IntPtrConstant(0));
EXPECT_THAT(sar, a);
}
// +CONST_a >>> CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(4096);
Node* sar = m.WordSar(a, m.IntPtrConstant(2));
EXPECT_THAT(sar, IsIntPtrConstant(1024));
}
// -CONST_a >>> CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(-1234);
Node* sar = m.WordSar(a, m.IntPtrConstant(2));
EXPECT_THAT(sar, IsIntPtrConstant(static_cast<intptr_t>(-1234) >> 2));
}
}
TARGET_TEST_F(CodeAssemblerTest, WordOr) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* z = m.WordOr(a, m.IntPtrConstant(8));
EXPECT_THAT(z, IsWordOr(a, IsIntPtrConstant(8)));
}
// x | 0 => x
{
Node* a = m.Parameter(0);
Node* z = m.WordOr(a, m.IntPtrConstant(0));
EXPECT_THAT(z, a);
}
// 0 | x => x
{
Node* a = m.Parameter(0);
Node* z = m.WordOr(m.IntPtrConstant(0), a);
EXPECT_THAT(z, a);
}
// CONST_a | CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(3);
Node* b = m.WordOr(a, m.IntPtrConstant(7));
EXPECT_THAT(b, IsIntPtrConstant(7));
}
}
TARGET_TEST_F(CodeAssemblerTest, WordAnd) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* z = m.WordAnd(a, m.IntPtrConstant(8));
EXPECT_THAT(z, IsWordAnd(a, IsIntPtrConstant(8)));
}
// CONST_a & CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(3);
Node* b = m.WordAnd(a, m.IntPtrConstant(7));
EXPECT_THAT(b, IsIntPtrConstant(3));
}
}
TARGET_TEST_F(CodeAssemblerTest, WordXor) {
CodeAssemblerTestState state(this);
CodeAssemblerForTest m(&state);
{
Node* a = m.Parameter(0);
Node* z = m.WordXor(a, m.IntPtrConstant(8));
EXPECT_THAT(z, IsWordXor(a, IsIntPtrConstant(8)));
}
// CONST_a ^ CONST_b => CONST_c
{
Node* a = m.IntPtrConstant(3);
Node* b = m.WordXor(a, m.IntPtrConstant(7));
EXPECT_THAT(b, IsIntPtrConstant(4));
}
}
} // namespace compiler
} // namespace internal
} // namespace v8
// Copyright 2017 the V8 project authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#ifndef V8_UNITTESTS_COMPILER_CODE_ASSEMBLER_UNITTEST_H_
#define V8_UNITTESTS_COMPILER_CODE_ASSEMBLER_UNITTEST_H_
#include "src/compiler/code-assembler.h"
#include "test/unittests/test-utils.h"
#include "testing/gmock-support.h"
namespace v8 {
namespace internal {
namespace compiler {
class CodeAssemblerTest : public TestWithIsolateAndZone {
public:
CodeAssemblerTest() {}
~CodeAssemblerTest() override {}
};
class CodeAssemblerTestState : public CodeAssemblerState {
public:
explicit CodeAssemblerTestState(CodeAssemblerTest* test);
};
class CodeAssemblerForTest : public CodeAssembler {
public:
explicit CodeAssemblerForTest(CodeAssemblerTestState* state)
: CodeAssembler(state) {}
};
} // namespace compiler
} // namespace internal
} // namespace v8
#endif // V8_UNITTESTS_COMPILER_CODE_ASSEMBLER_UNITTEST_H_
......@@ -2110,8 +2110,10 @@ IS_BINOP_MATCHER(Word32Ror)
IS_BINOP_MATCHER(Word32Equal)
IS_BINOP_MATCHER(Word64And)
IS_BINOP_MATCHER(Word64Or)
IS_BINOP_MATCHER(Word64Xor)
IS_BINOP_MATCHER(Word64Sar)
IS_BINOP_MATCHER(Word64Shl)
IS_BINOP_MATCHER(Word64Shr)
IS_BINOP_MATCHER(Word64Equal)
IS_BINOP_MATCHER(Int32AddWithOverflow)
IS_BINOP_MATCHER(Int32SubWithOverflow)
......
......@@ -358,8 +358,12 @@ Matcher<Node*> IsWord64And(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Or(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Xor(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Shl(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Shr(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Sar(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher);
Matcher<Node*> IsWord64Equal(const Matcher<Node*>& lhs_matcher,
......@@ -473,6 +477,81 @@ Matcher<Node*> IsWord32ReverseBytes(const Matcher<Node*>& value_matcher);
Matcher<Node*> IsStackSlot();
// Helpers
static inline Matcher<Node*> IsIntPtrConstant(const intptr_t value) {
return kPointerSize == 8 ? IsInt64Constant(static_cast<int64_t>(value))
: IsInt32Constant(static_cast<int32_t>(value));
}
static inline Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsInt64Add(lhs_matcher, rhs_matcher)
: IsInt32Add(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsInt64Sub(lhs_matcher, rhs_matcher)
: IsInt32Sub(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsIntPtrMul(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsInt64Mul(lhs_matcher, rhs_matcher)
: IsInt32Mul(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Shl(lhs_matcher, rhs_matcher)
: IsWord32Shl(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsWordShr(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Shr(lhs_matcher, rhs_matcher)
: IsWord32Shr(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Sar(lhs_matcher, rhs_matcher)
: IsWord32Sar(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsWordAnd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64And(lhs_matcher, rhs_matcher)
: IsWord32And(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Or(lhs_matcher, rhs_matcher)
: IsWord32Or(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsWordXor(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? IsWord64Xor(lhs_matcher, rhs_matcher)
: IsWord32Xor(lhs_matcher, rhs_matcher);
}
static inline Matcher<Node*> IsChangeInt32ToIntPtr(
const Matcher<Node*>& matcher) {
return kPointerSize == 8 ? IsChangeInt32ToInt64(matcher) : matcher;
}
static inline Matcher<Node*> IsChangeUint32ToWord(
const Matcher<Node*>& matcher) {
return kPointerSize == 8 ? IsChangeUint32ToUint64(matcher) : matcher;
}
static inline Matcher<Node*> IsTruncateWordToWord32(
const Matcher<Node*>& matcher) {
return kPointerSize == 8 ? IsTruncateInt64ToInt32(matcher) : matcher;
}
} // namespace compiler
} // namespace internal
} // namespace v8
......
......@@ -19,15 +19,6 @@ namespace c = v8::internal::compiler;
namespace v8 {
namespace internal {
#ifdef ENABLE_VERIFY_CSA
#define IS_BITCAST_WORD_TO_TAGGED_SIGNED(x) IsBitcastWordToTaggedSigned(x)
#define IS_BITCAST_TAGGED_TO_WORD(x) IsBitcastTaggedToWord(x)
#else
#define IS_BITCAST_WORD_TO_TAGGED_SIGNED(x) (x)
#define IS_BITCAST_TAGGED_TO_WORD(x) (x)
#endif
namespace interpreter {
InterpreterAssemblerTestState::InterpreterAssemblerTestState(
......@@ -44,58 +35,6 @@ const interpreter::Bytecode kBytecodes[] = {
#undef DEFINE_BYTECODE
};
Matcher<Node*> IsIntPtrConstant(const intptr_t value) {
return kPointerSize == 8 ? c::IsInt64Constant(static_cast<int64_t>(value))
: c::IsInt32Constant(static_cast<int32_t>(value));
}
Matcher<Node*> IsIntPtrAdd(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? c::IsInt64Add(lhs_matcher, rhs_matcher)
: c::IsInt32Add(lhs_matcher, rhs_matcher);
}
Matcher<Node*> IsIntPtrSub(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? c::IsInt64Sub(lhs_matcher, rhs_matcher)
: c::IsInt32Sub(lhs_matcher, rhs_matcher);
}
Matcher<Node*> IsIntPtrMul(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? c::IsInt64Mul(lhs_matcher, rhs_matcher)
: c::IsInt32Mul(lhs_matcher, rhs_matcher);
}
Matcher<Node*> IsWordShl(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? c::IsWord64Shl(lhs_matcher, rhs_matcher)
: c::IsWord32Shl(lhs_matcher, rhs_matcher);
}
Matcher<Node*> IsWordSar(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? c::IsWord64Sar(lhs_matcher, rhs_matcher)
: c::IsWord32Sar(lhs_matcher, rhs_matcher);
}
Matcher<Node*> IsWordOr(const Matcher<Node*>& lhs_matcher,
const Matcher<Node*>& rhs_matcher) {
return kPointerSize == 8 ? c::IsWord64Or(lhs_matcher, rhs_matcher)
: c::IsWord32Or(lhs_matcher, rhs_matcher);
}
Matcher<Node*> IsChangeInt32ToIntPtr(const Matcher<Node*>& matcher) {
return kPointerSize == 8 ? IsChangeInt32ToInt64(matcher) : matcher;
}
Matcher<Node*> IsChangeUint32ToWord(const Matcher<Node*>& matcher) {
return kPointerSize == 8 ? IsChangeUint32ToUint64(matcher) : matcher;
}
Matcher<Node*> IsTruncateWordToWord32(const Matcher<Node*>& matcher) {
return kPointerSize == 8 ? IsTruncateInt64ToInt32(matcher) : matcher;
}
InterpreterAssemblerTest::InterpreterAssemblerForTest::
~InterpreterAssemblerForTest() {
......@@ -126,21 +65,23 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore(
Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedByteOperand(
int offset) {
return IsLoad(MachineType::Uint8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(c::IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset)));
return IsLoad(
MachineType::Uint8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
c::IsIntPtrConstant(offset)));
}
Matcher<Node*>
InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedByteOperand(
int offset) {
return IsLoad(MachineType::Int8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(c::IsParameter(
InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset)));
return IsLoad(
MachineType::Int8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
c::IsIntPtrConstant(offset)));
}
Matcher<Node*>
......@@ -150,9 +91,9 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand(
return IsLoad(
MachineType::Uint16(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset)));
c::IsIntPtrConstant(offset)));
} else {
#if V8_TARGET_LITTLE_ENDIAN
const int kStep = -1;
......@@ -168,12 +109,12 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand(
bytes[i] = IsLoad(
MachineType::Uint8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
}
return IsWord32Or(IsWord32Shl(bytes[0], c::IsInt32Constant(kBitsPerByte)),
bytes[1]);
return c::IsWord32Or(
c::IsWord32Shl(bytes[0], c::IsInt32Constant(kBitsPerByte)), bytes[1]);
}
}
......@@ -184,9 +125,9 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand(
return IsLoad(
MachineType::Int16(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset)));
c::IsIntPtrConstant(offset)));
} else {
#if V8_TARGET_LITTLE_ENDIAN
const int kStep = -1;
......@@ -202,12 +143,12 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand(
bytes[i] = IsLoad(
(i == 0) ? MachineType::Int8() : MachineType::Uint8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
}
return IsWord32Or(IsWord32Shl(bytes[0], c::IsInt32Constant(kBitsPerByte)),
bytes[1]);
return c::IsWord32Or(
c::IsWord32Shl(bytes[0], c::IsInt32Constant(kBitsPerByte)), bytes[1]);
}
}
......@@ -218,9 +159,9 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand(
return IsLoad(
MachineType::Uint32(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset)));
c::IsIntPtrConstant(offset)));
} else {
#if V8_TARGET_LITTLE_ENDIAN
const int kStep = -1;
......@@ -236,16 +177,17 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand(
bytes[i] = IsLoad(
MachineType::Uint8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
}
return IsWord32Or(
IsWord32Shl(bytes[0], c::IsInt32Constant(3 * kBitsPerByte)),
IsWord32Or(IsWord32Shl(bytes[1], c::IsInt32Constant(2 * kBitsPerByte)),
IsWord32Or(IsWord32Shl(bytes[2],
c::IsInt32Constant(1 * kBitsPerByte)),
bytes[3])));
return c::IsWord32Or(
c::IsWord32Shl(bytes[0], c::IsInt32Constant(3 * kBitsPerByte)),
c::IsWord32Or(
c::IsWord32Shl(bytes[1], c::IsInt32Constant(2 * kBitsPerByte)),
c::IsWord32Or(
c::IsWord32Shl(bytes[2], c::IsInt32Constant(1 * kBitsPerByte)),
bytes[3])));
}
}
......@@ -256,9 +198,9 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand(
return IsLoad(
MachineType::Int32(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset)));
c::IsIntPtrConstant(offset)));
} else {
#if V8_TARGET_LITTLE_ENDIAN
const int kStep = -1;
......@@ -274,16 +216,17 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand(
bytes[i] = IsLoad(
(i == 0) ? MachineType::Int8() : MachineType::Uint8(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrAdd(
c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
c::IsIntPtrConstant(offset + kMsbOffset + kStep * i)));
}
return IsWord32Or(
IsWord32Shl(bytes[0], c::IsInt32Constant(3 * kBitsPerByte)),
IsWord32Or(IsWord32Shl(bytes[1], c::IsInt32Constant(2 * kBitsPerByte)),
IsWord32Or(IsWord32Shl(bytes[2],
c::IsInt32Constant(1 * kBitsPerByte)),
bytes[3])));
return c::IsWord32Or(
c::IsWord32Shl(bytes[0], c::IsInt32Constant(3 * kBitsPerByte)),
c::IsWord32Or(
c::IsWord32Shl(bytes[1], c::IsInt32Constant(2 * kBitsPerByte)),
c::IsWord32Or(
c::IsWord32Shl(bytes[2], c::IsInt32Constant(1 * kBitsPerByte)),
bytes[3])));
}
}
......@@ -332,21 +275,22 @@ TARGET_TEST_F(InterpreterAssemblerTest, Jump) {
InterpreterAssemblerForTest m(&state, bytecode);
Node* tail_call_node = m.Jump(m.IntPtrConstant(jump_offset));
Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd(
Matcher<Node*> next_bytecode_offset_matcher = c::IsIntPtrAdd(
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset),
IsIntPtrConstant(jump_offset));
c::IsIntPtrConstant(jump_offset));
Matcher<Node*> target_bytecode_matcher =
m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher);
target_bytecode_matcher = IsChangeUint32ToWord(target_bytecode_matcher);
target_bytecode_matcher =
c::IsChangeUint32ToWord(target_bytecode_matcher);
Matcher<Node*> code_target_matcher = m.IsLoad(
MachineType::Pointer(),
c::IsParameter(InterpreterDispatchDescriptor::kDispatchTable),
IsWordShl(target_bytecode_matcher,
IsIntPtrConstant(kPointerSizeLog2)));
c::IsWordShl(target_bytecode_matcher,
c::IsIntPtrConstant(kPointerSizeLog2)));
EXPECT_THAT(
tail_call_node,
IsTailCall(
c::IsTailCall(
_, code_target_matcher,
c::IsParameter(InterpreterDispatchDescriptor::kAccumulator),
next_bytecode_offset_matcher, _,
......@@ -383,12 +327,12 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
break;
case interpreter::OperandType::kIdx:
EXPECT_THAT(m.BytecodeOperandIdx(i),
IsChangeUint32ToWord(
c::IsChangeUint32ToWord(
m.IsUnsignedOperand(offset, operand_size)));
break;
case interpreter::OperandType::kNativeContextIndex:
EXPECT_THAT(m.BytecodeOperandNativeContextIndex(i),
IsChangeUint32ToWord(
c::IsChangeUint32ToWord(
m.IsUnsignedOperand(offset, operand_size)));
break;
case interpreter::OperandType::kUImm:
......@@ -407,9 +351,9 @@ TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) {
case interpreter::OperandType::kRegOutPair:
case interpreter::OperandType::kRegOutTriple:
case interpreter::OperandType::kRegPair:
EXPECT_THAT(
m.BytecodeOperandReg(i),
IsChangeInt32ToIntPtr(m.IsSignedOperand(offset, operand_size)));
EXPECT_THAT(m.BytecodeOperandReg(i),
c::IsChangeInt32ToIntPtr(
m.IsSignedOperand(offset, operand_size)));
break;
case interpreter::OperandType::kRuntimeId:
EXPECT_THAT(m.BytecodeOperandRuntimeId(i),
......@@ -435,8 +379,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, GetContext) {
EXPECT_THAT(
m.GetContext(),
m.IsLoad(MachineType::AnyTagged(), c::IsLoadParentFramePointer(),
IsIntPtrConstant(Register::current_context().ToOperand()
<< kPointerSizeLog2)));
c::IsIntPtrConstant(Register::current_context().ToOperand()
<< kPointerSizeLog2)));
}
}
......@@ -444,12 +388,13 @@ TARGET_TEST_F(InterpreterAssemblerTest, RegisterLocation) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* reg_index_node = m.IntPtrConstant(44);
Node* reg_index_node = m.Parameter(0);
Node* reg_location_node = m.RegisterLocation(reg_index_node);
EXPECT_THAT(reg_location_node,
IsIntPtrAdd(c::IsLoadParentFramePointer(),
IsWordShl(reg_index_node,
IsIntPtrConstant(kPointerSizeLog2))));
EXPECT_THAT(
reg_location_node,
c::IsIntPtrAdd(c::IsLoadParentFramePointer(),
c::IsWordShl(reg_index_node,
c::IsIntPtrConstant(kPointerSizeLog2))));
}
}
......@@ -457,13 +402,13 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadRegister) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* reg_index_node = m.IntPtrConstant(44);
Node* reg_index_node = m.Parameter(0);
Node* load_reg_node = m.LoadRegister(reg_index_node);
EXPECT_THAT(
load_reg_node,
m.IsLoad(
MachineType::AnyTagged(), c::IsLoadParentFramePointer(),
IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2))));
m.IsLoad(MachineType::AnyTagged(), c::IsLoadParentFramePointer(),
c::IsWordShl(reg_index_node,
c::IsIntPtrConstant(kPointerSizeLog2))));
}
}
......@@ -472,62 +417,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, StoreRegister) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* store_value = m.Int32Constant(0xdeadbeef);
Node* reg_index_node = m.IntPtrConstant(44);
Node* reg_index_node = m.Parameter(0);
Node* store_reg_node = m.StoreRegister(store_value, reg_index_node);
EXPECT_THAT(
store_reg_node,
m.IsStore(c::StoreRepresentation(MachineRepresentation::kTagged,
kNoWriteBarrier),
c::IsLoadParentFramePointer(),
IsWordShl(reg_index_node, IsIntPtrConstant(kPointerSizeLog2)),
store_value));
}
}
TARGET_TEST_F(InterpreterAssemblerTest, SmiTag) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* value = m.Int32Constant(44);
EXPECT_THAT(
m.SmiTag(value),
IS_BITCAST_WORD_TO_TAGGED_SIGNED(IsIntPtrConstant(
static_cast<intptr_t>(44) << (kSmiShiftSize + kSmiTagSize))));
EXPECT_THAT(m.SmiUntag(value),
IsWordSar(IS_BITCAST_TAGGED_TO_WORD(value),
IsIntPtrConstant(kSmiShiftSize + kSmiTagSize)));
}
}
TARGET_TEST_F(InterpreterAssemblerTest, IntPtrAdd) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(1);
Node* add = m.IntPtrAdd(a, b);
EXPECT_THAT(add, IsIntPtrAdd(a, b));
}
}
TARGET_TEST_F(InterpreterAssemblerTest, IntPtrSub) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* a = m.Parameter(0);
Node* b = m.Int32Constant(1);
Node* add = m.IntPtrSub(a, b);
EXPECT_THAT(add, IsIntPtrSub(a, b));
}
}
TARGET_TEST_F(InterpreterAssemblerTest, WordShl) {
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) {
InterpreterAssemblerTestState state(this, bytecode);
InterpreterAssemblerForTest m(&state, bytecode);
Node* a = m.IntPtrConstant(0);
Node* add = m.WordShl(a, 10);
EXPECT_THAT(add, IsWordShl(a, IsIntPtrConstant(10)));
EXPECT_THAT(store_reg_node,
m.IsStore(c::StoreRepresentation(MachineRepresentation::kTagged,
kNoWriteBarrier),
c::IsLoadParentFramePointer(),
c::IsWordShl(reg_index_node,
c::IsIntPtrConstant(kPointerSizeLog2)),
store_value));
}
}
......@@ -541,12 +439,13 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
Matcher<Node*> constant_pool_matcher = m.IsLoad(
MachineType::AnyTagged(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrConstant(BytecodeArray::kConstantPoolOffset -
kHeapObjectTag));
EXPECT_THAT(load_constant,
m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher,
IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) -
kHeapObjectTag)));
c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset -
kHeapObjectTag));
EXPECT_THAT(
load_constant,
m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher,
c::IsIntPtrConstant(FixedArray::OffsetOfElementAt(2) -
kHeapObjectTag)));
}
{
Node* index = m.Parameter(2);
......@@ -554,15 +453,15 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) {
Matcher<Node*> constant_pool_matcher = m.IsLoad(
MachineType::AnyTagged(),
c::IsParameter(InterpreterDispatchDescriptor::kBytecodeArray),
IsIntPtrConstant(BytecodeArray::kConstantPoolOffset -
kHeapObjectTag));
c::IsIntPtrConstant(BytecodeArray::kConstantPoolOffset -
kHeapObjectTag));
EXPECT_THAT(
load_constant,
m.IsLoad(
MachineType::AnyTagged(), constant_pool_matcher,
IsIntPtrAdd(
IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
IsWordShl(index, IsIntPtrConstant(kPointerSizeLog2)))));
c::IsIntPtrAdd(
c::IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
c::IsWordShl(index, c::IsIntPtrConstant(kPointerSizeLog2)))));
}
}
}
......@@ -576,7 +475,7 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadObjectField) {
Node* load_field = m.LoadObjectField(object, offset);
EXPECT_THAT(load_field,
m.IsLoad(MachineType::AnyTagged(), object,
IsIntPtrConstant(offset - kHeapObjectTag)));
c::IsIntPtrConstant(offset - kHeapObjectTag)));
}
}
......@@ -588,8 +487,8 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime2) {
Node* arg2 = m.Int32Constant(3);
Node* context = m.Int32Constant(4);
Node* call_runtime = m.CallRuntime(Runtime::kAdd, context, arg1, arg2);
EXPECT_THAT(call_runtime, IsCall(_, _, arg1, arg2, _, c::IsInt32Constant(2),
context, _, _));
EXPECT_THAT(call_runtime, c::IsCall(_, _, arg1, arg2, _,
c::IsInt32Constant(2), context, _, _));
}
}
......@@ -610,19 +509,19 @@ TARGET_TEST_F(InterpreterAssemblerTest, CallRuntime) {
Matcher<Node*> function_table = c::IsExternalConstant(
ExternalReference::runtime_function_table_address(isolate()));
Matcher<Node*> function = IsIntPtrAdd(
Matcher<Node*> function = c::IsIntPtrAdd(
function_table,
IsChangeUint32ToWord(IsInt32Mul(
c::IsChangeUint32ToWord(c::IsInt32Mul(
function_id, c::IsInt32Constant(sizeof(Runtime::Function)))));
Matcher<Node*> function_entry =
m.IsLoad(MachineType::Pointer(), function,
IsIntPtrConstant(offsetof(Runtime::Function, entry)));
c::IsIntPtrConstant(offsetof(Runtime::Function, entry)));
Node* call_runtime = m.CallRuntimeN(function_id, context, first_arg,
arg_count, result_size);
EXPECT_THAT(call_runtime,
IsCall(_, c::IsHeapConstant(builtin.code()), arg_count,
first_arg, function_entry, context, _, _));
c::IsCall(_, c::IsHeapConstant(builtin.code()), arg_count,
first_arg, function_entry, context, _, _));
}
}
}
......@@ -636,15 +535,16 @@ TARGET_TEST_F(InterpreterAssemblerTest, LoadFeedbackVector) {
Matcher<Node*> load_function_matcher =
m.IsLoad(MachineType::AnyTagged(), c::IsLoadParentFramePointer(),
IsIntPtrConstant(Register::function_closure().ToOperand()
<< kPointerSizeLog2));
Matcher<Node*> load_vector_cell_matcher = m.IsLoad(
MachineType::AnyTagged(), load_function_matcher,
IsIntPtrConstant(JSFunction::kFeedbackVectorOffset - kHeapObjectTag));
c::IsIntPtrConstant(Register::function_closure().ToOperand()
<< kPointerSizeLog2));
Matcher<Node*> load_vector_cell_matcher =
m.IsLoad(MachineType::AnyTagged(), load_function_matcher,
c::IsIntPtrConstant(JSFunction::kFeedbackVectorOffset -
kHeapObjectTag));
EXPECT_THAT(
feedback_vector,
m.IsLoad(MachineType::AnyTagged(), load_vector_cell_matcher,
IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag)));
c::IsIntPtrConstant(Cell::kValueOffset - kHeapObjectTag)));
}
}
......
......@@ -38,9 +38,13 @@
'base/utils/random-number-generator-unittest.cc',
'cancelable-tasks-unittest.cc',
'char-predicates-unittest.cc',
"code-stub-assembler-unittest.cc",
"code-stub-assembler-unittest.h",
'compiler/branch-elimination-unittest.cc',
'compiler/bytecode-analysis-unittest.cc',
'compiler/checkpoint-elimination-unittest.cc',
"compiler/code-assembler-unittest.cc",
"compiler/code-assembler-unittest.h",
'compiler/common-operator-reducer-unittest.cc',
'compiler/common-operator-unittest.cc',
'compiler/compiler-test-utils.h',
......
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