Index: test/unittests/interpreter/interpreter-assembler-unittest.cc |
diff --git a/test/unittests/interpreter/interpreter-assembler-unittest.cc b/test/unittests/interpreter/interpreter-assembler-unittest.cc |
index f8edd83d893aacad054a3bc45c54d0692032c290..79626ea9b49bd2f98be578083d67fab7d65c7c8f 100644 |
--- a/test/unittests/interpreter/interpreter-assembler-unittest.cc |
+++ b/test/unittests/interpreter/interpreter-assembler-unittest.cc |
@@ -77,7 +77,7 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest::IsStore( |
} |
Matcher<Node*> |
-InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedByteOperand( |
int offset) { |
return IsLoad( |
MachineType::Uint8(), |
@@ -87,8 +87,9 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperand( |
IsIntPtrConstant(offset))); |
} |
-Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
- IsBytecodeOperandSignExtended(int offset) { |
+Matcher<Node*> |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedByteOperand( |
+ int offset) { |
Matcher<Node*> load_matcher = IsLoad( |
MachineType::Int8(), |
IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
@@ -102,7 +103,7 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
} |
Matcher<Node*> |
-InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand( |
int offset) { |
if (TargetSupportsUnalignedAccess()) { |
return IsLoad( |
@@ -113,34 +114,33 @@ InterpreterAssemblerTest::InterpreterAssemblerForTest::IsBytecodeOperandShort( |
InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
IsIntPtrConstant(offset))); |
} else { |
- Matcher<Node*> first_byte = IsLoad( |
- MachineType::Uint8(), |
- IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
- IsIntPtrAdd( |
- IsParameter( |
- InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
- IsIntPtrConstant(offset))); |
- Matcher<Node*> second_byte = IsLoad( |
- MachineType::Uint8(), |
- IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
- IsIntPtrAdd( |
- IsParameter( |
- InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
- IsIntPtrConstant(offset + 1))); |
#if V8_TARGET_LITTLE_ENDIAN |
- return IsWordOr(IsWordShl(second_byte, IsIntPtrConstant(kBitsPerByte)), |
- first_byte); |
+ const int kStep = -1; |
+ const int kMsbOffset = 1; |
#elif V8_TARGET_BIG_ENDIAN |
- return IsWordOr(IsWordShl(first_byte, IsIntPtrConstant(kBitsPerByte)), |
- second_byte); |
+ const int kStep = 1; |
+ const int kMsbOffset = 0; |
#else |
#error "Unknown Architecture" |
#endif |
+ Matcher<Node*> bytes[2]; |
+ for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
+ bytes[i] = IsLoad( |
+ MachineType::Uint8(), |
+ IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
+ IsIntPtrAdd( |
+ IsParameter( |
+ InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
+ IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
+ } |
+ return IsWord32Or(IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), |
+ bytes[1]); |
} |
} |
-Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
- IsBytecodeOperandShortSignExtended(int offset) { |
+Matcher<Node*> |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand( |
+ int offset) { |
Matcher<Node*> load_matcher; |
if (TargetSupportsUnalignedAccess()) { |
load_matcher = IsLoad( |
@@ -152,31 +152,112 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
IsIntPtrConstant(offset))); |
} else { |
#if V8_TARGET_LITTLE_ENDIAN |
- int hi_byte_offset = offset + 1; |
- int lo_byte_offset = offset; |
- |
+ const int kStep = -1; |
+ const int kMsbOffset = 1; |
#elif V8_TARGET_BIG_ENDIAN |
- int hi_byte_offset = offset; |
- int lo_byte_offset = offset + 1; |
+ const int kStep = 1; |
+ const int kMsbOffset = 0; |
#else |
#error "Unknown Architecture" |
#endif |
- Matcher<Node*> hi_byte = IsLoad( |
- MachineType::Int8(), |
+ Matcher<Node*> bytes[2]; |
+ for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
+ bytes[i] = IsLoad( |
+ (i == 0) ? MachineType::Int8() : MachineType::Uint8(), |
+ IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
+ IsIntPtrAdd( |
+ IsParameter( |
+ InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
+ IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
+ } |
+ load_matcher = IsWord32Or( |
+ IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), bytes[1]); |
+ } |
+ |
+ if (kPointerSize == 8) { |
+ load_matcher = IsChangeInt32ToInt64(load_matcher); |
+ } |
+ return load_matcher; |
+} |
+ |
+Matcher<Node*> |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand( |
+ int offset) { |
+ if (TargetSupportsUnalignedAccess()) { |
+ return IsLoad( |
+ MachineType::Uint32(), |
IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
IsIntPtrAdd( |
IsParameter( |
InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
- IsIntPtrConstant(hi_byte_offset))); |
- hi_byte = IsWord32Shl(hi_byte, IsInt32Constant(kBitsPerByte)); |
- Matcher<Node*> lo_byte = IsLoad( |
- MachineType::Uint8(), |
+ IsIntPtrConstant(offset))); |
+ } else { |
+#if V8_TARGET_LITTLE_ENDIAN |
+ const int kStep = -1; |
+ const int kMsbOffset = 3; |
+#elif V8_TARGET_BIG_ENDIAN |
+ const int kStep = 1; |
+ const int kMsbOffset = 0; |
+#else |
+#error "Unknown Architecture" |
+#endif |
+ Matcher<Node*> bytes[4]; |
+ for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
+ bytes[i] = IsLoad( |
+ MachineType::Uint8(), |
+ IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
+ IsIntPtrAdd( |
+ IsParameter( |
+ InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
+ IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
+ } |
+ return IsWord32Or( |
+ IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)), |
+ IsWord32Or( |
+ IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)), |
+ IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)), |
+ bytes[3]))); |
+ } |
+} |
+ |
+Matcher<Node*> |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand( |
+ int offset) { |
+ Matcher<Node*> load_matcher; |
+ if (TargetSupportsUnalignedAccess()) { |
+ load_matcher = IsLoad( |
+ MachineType::Int32(), |
IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
IsIntPtrAdd( |
IsParameter( |
InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
- IsIntPtrConstant(lo_byte_offset))); |
- load_matcher = IsWord32Or(hi_byte, lo_byte); |
+ IsIntPtrConstant(offset))); |
+ } else { |
+#if V8_TARGET_LITTLE_ENDIAN |
+ const int kStep = -1; |
+ int kMsbOffset = 3; |
+#elif V8_TARGET_BIG_ENDIAN |
+ const int kStep = 1; |
+ int kMsbOffset = 0; |
+#else |
+#error "Unknown Architecture" |
+#endif |
+ Matcher<Node*> bytes[4]; |
+ for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
+ bytes[i] = IsLoad( |
+ (i == 0) ? MachineType::Int8() : MachineType::Uint8(), |
+ IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
+ IsIntPtrAdd( |
+ IsParameter( |
+ InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
+ IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
+ } |
+ load_matcher = IsWord32Or( |
+ IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)), |
+ IsWord32Or( |
+ IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)), |
+ IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)), |
+ bytes[3]))); |
} |
if (kPointerSize == 8) { |
@@ -185,6 +266,38 @@ Matcher<Node*> InterpreterAssemblerTest::InterpreterAssemblerForTest:: |
return load_matcher; |
} |
+Matcher<Node*> |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedOperand( |
+ int offset, OperandSize operand_size) { |
+ switch (operand_size) { |
+ case OperandSize::kByte: |
+ return IsSignedByteOperand(offset); |
+ case OperandSize::kShort: |
+ return IsSignedShortOperand(offset); |
+ case OperandSize::kQuad: |
+ return IsSignedQuadOperand(offset); |
+ case OperandSize::kNone: |
+ UNREACHABLE(); |
+ } |
+ return nullptr; |
+} |
+ |
+Matcher<Node*> |
+InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedOperand( |
+ int offset, OperandSize operand_size) { |
+ switch (operand_size) { |
+ case OperandSize::kByte: |
+ return IsUnsignedByteOperand(offset); |
+ case OperandSize::kShort: |
+ return IsUnsignedShortOperand(offset); |
+ case OperandSize::kQuad: |
+ return IsUnsignedQuadOperand(offset); |
+ case OperandSize::kNone: |
+ UNREACHABLE(); |
+ } |
+ return nullptr; |
+} |
+ |
TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { |
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
InterpreterAssemblerForTest m(this, bytecode); |
@@ -195,9 +308,11 @@ TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { |
EXPECT_EQ(1, end->InputCount()); |
Node* tail_call_node = end->InputAt(0); |
+ OperandScale operand_scale = OperandScale::kSingle; |
Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( |
IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
- IsIntPtrConstant(interpreter::Bytecodes::Size(bytecode))); |
+ IsIntPtrConstant( |
+ interpreter::Bytecodes::Size(bytecode, operand_scale))); |
Matcher<Node*> target_bytecode_matcher = m.IsLoad( |
MachineType::Uint8(), |
IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), |
@@ -286,8 +401,9 @@ TARGET_TEST_F(InterpreterAssemblerTest, JumpIfWordEqual) { |
Node* end = graph->end(); |
EXPECT_EQ(2, end->InputCount()); |
- int jump_offsets[] = {kJumpIfTrueOffset, |
- interpreter::Bytecodes::Size(bytecode)}; |
+ OperandScale operand_scale = OperandScale::kSingle; |
+ int jump_offsets[] = {kJumpIfTrueOffset, interpreter::Bytecodes::Size( |
+ bytecode, operand_scale)}; |
for (int i = 0; i < static_cast<int>(arraysize(jump_offsets)); i++) { |
Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( |
IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), |
@@ -352,51 +468,55 @@ TARGET_TEST_F(InterpreterAssemblerTest, InterpreterReturn) { |
} |
TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { |
+ static const OperandScale kOperandScales[] = { |
+ OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple}; |
TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
- InterpreterAssemblerForTest m(this, bytecode); |
- int number_of_operands = interpreter::Bytecodes::NumberOfOperands(bytecode); |
- for (int i = 0; i < number_of_operands; i++) { |
- int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i); |
- switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { |
- case interpreter::OperandType::kRegCount8: |
- EXPECT_THAT(m.BytecodeOperandCount(i), m.IsBytecodeOperand(offset)); |
- break; |
- case interpreter::OperandType::kIdx8: |
- EXPECT_THAT(m.BytecodeOperandIdx(i), m.IsBytecodeOperand(offset)); |
- break; |
- case interpreter::OperandType::kImm8: |
- EXPECT_THAT(m.BytecodeOperandImm(i), |
- m.IsBytecodeOperandSignExtended(offset)); |
- break; |
- case interpreter::OperandType::kMaybeReg8: |
- case interpreter::OperandType::kReg8: |
- case interpreter::OperandType::kRegOut8: |
- case interpreter::OperandType::kRegOutPair8: |
- case interpreter::OperandType::kRegOutTriple8: |
- case interpreter::OperandType::kRegPair8: |
- EXPECT_THAT(m.BytecodeOperandReg(i), |
- m.IsBytecodeOperandSignExtended(offset)); |
- break; |
- case interpreter::OperandType::kRegCount16: |
- EXPECT_THAT(m.BytecodeOperandCount(i), |
- m.IsBytecodeOperandShort(offset)); |
- break; |
- case interpreter::OperandType::kIdx16: |
- EXPECT_THAT(m.BytecodeOperandIdx(i), |
- m.IsBytecodeOperandShort(offset)); |
- break; |
- case interpreter::OperandType::kMaybeReg16: |
- case interpreter::OperandType::kReg16: |
- case interpreter::OperandType::kRegOut16: |
- case interpreter::OperandType::kRegOutPair16: |
- case interpreter::OperandType::kRegOutTriple16: |
- case interpreter::OperandType::kRegPair16: |
- EXPECT_THAT(m.BytecodeOperandReg(i), |
- m.IsBytecodeOperandShortSignExtended(offset)); |
- break; |
- case interpreter::OperandType::kNone: |
- UNREACHABLE(); |
- break; |
+ TRACED_FOREACH(interpreter::OperandScale, operand_scale, kOperandScales) { |
+ InterpreterAssemblerForTest m(this, bytecode, operand_scale); |
+ int number_of_operands = |
+ interpreter::Bytecodes::NumberOfOperands(bytecode); |
+ for (int i = 0; i < number_of_operands; i++) { |
+ int offset = interpreter::Bytecodes::GetOperandOffset(bytecode, i, |
+ operand_scale); |
+ OperandType operand_type = |
+ interpreter::Bytecodes::GetOperandType(bytecode, i); |
+ OperandSize operand_size = |
+ Bytecodes::SizeOfOperand(operand_type, operand_scale); |
+ switch (interpreter::Bytecodes::GetOperandType(bytecode, i)) { |
+ case interpreter::OperandType::kRegCount: |
+ EXPECT_THAT(m.BytecodeOperandCount(i), |
+ m.IsUnsignedOperand(offset, operand_size)); |
+ break; |
+ case interpreter::OperandType::kFlag8: |
+ EXPECT_THAT(m.BytecodeOperandFlag(i), |
+ m.IsUnsignedOperand(offset, operand_size)); |
+ break; |
+ case interpreter::OperandType::kIdx: |
+ EXPECT_THAT(m.BytecodeOperandIdx(i), |
+ m.IsUnsignedOperand(offset, operand_size)); |
+ break; |
+ case interpreter::OperandType::kImm: { |
+ EXPECT_THAT(m.BytecodeOperandImm(i), |
+ m.IsSignedOperand(offset, operand_size)); |
+ break; |
+ } |
+ case interpreter::OperandType::kMaybeReg: |
+ case interpreter::OperandType::kReg: |
+ case interpreter::OperandType::kRegOut: |
+ case interpreter::OperandType::kRegOutPair: |
+ case interpreter::OperandType::kRegOutTriple: |
+ case interpreter::OperandType::kRegPair: |
+ EXPECT_THAT(m.BytecodeOperandReg(i), |
+ m.IsSignedOperand(offset, operand_size)); |
+ break; |
+ case interpreter::OperandType::kRuntimeId: |
+ EXPECT_THAT(m.BytecodeOperandRuntimeId(i), |
+ m.IsUnsignedOperand(offset, operand_size)); |
+ break; |
+ case interpreter::OperandType::kNone: |
+ UNREACHABLE(); |
+ break; |
+ } |
} |
} |
} |