| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "test/unittests/interpreter/interpreter-assembler-unittest.h" | 5 #include "test/unittests/interpreter/interpreter-assembler-unittest.h" |
| 6 | 6 |
| 7 #include "src/code-factory.h" | 7 #include "src/code-factory.h" |
| 8 #include "src/compiler/graph.h" | 8 #include "src/compiler/graph.h" |
| 9 #include "src/compiler/node.h" | 9 #include "src/compiler/node.h" |
| 10 #include "src/interface-descriptors.h" | 10 #include "src/interface-descriptors.h" |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 86 const Matcher<Node*>& value_matcher) { | 86 const Matcher<Node*>& value_matcher) { |
| 87 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, | 87 return ::i::compiler::IsStore(rep_matcher, base_matcher, index_matcher, |
| 88 value_matcher, _, _); | 88 value_matcher, _, _); |
| 89 } | 89 } |
| 90 | 90 |
| 91 Matcher<Node*> | 91 Matcher<Node*> |
| 92 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedByteOperand( | 92 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedByteOperand( |
| 93 int offset) { | 93 int offset) { |
| 94 return IsLoad( | 94 return IsLoad( |
| 95 MachineType::Uint8(), | 95 MachineType::Uint8(), |
| 96 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 96 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 97 IsIntPtrAdd( | 97 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 98 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | 98 IsIntPtrConstant(offset))); |
| 99 IsIntPtrConstant(offset))); | |
| 100 } | 99 } |
| 101 | 100 |
| 102 Matcher<Node*> | 101 Matcher<Node*> |
| 103 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedByteOperand( | 102 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedByteOperand( |
| 104 int offset) { | 103 int offset) { |
| 105 Matcher<Node*> load_matcher = IsLoad( | 104 Matcher<Node*> load_matcher = IsLoad( |
| 106 MachineType::Int8(), | 105 MachineType::Int8(), |
| 107 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 106 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 108 IsIntPtrAdd( | 107 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 109 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | 108 IsIntPtrConstant(offset))); |
| 110 IsIntPtrConstant(offset))); | |
| 111 if (kPointerSize == 8) { | 109 if (kPointerSize == 8) { |
| 112 load_matcher = IsChangeInt32ToInt64(load_matcher); | 110 load_matcher = IsChangeInt32ToInt64(load_matcher); |
| 113 } | 111 } |
| 114 return load_matcher; | 112 return load_matcher; |
| 115 } | 113 } |
| 116 | 114 |
| 117 Matcher<Node*> | 115 Matcher<Node*> |
| 118 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand( | 116 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedShortOperand( |
| 119 int offset) { | 117 int offset) { |
| 120 if (TargetSupportsUnalignedAccess()) { | 118 if (TargetSupportsUnalignedAccess()) { |
| 121 return IsLoad( | 119 return IsLoad( |
| 122 MachineType::Uint16(), | 120 MachineType::Uint16(), |
| 123 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 121 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 124 IsIntPtrAdd( | 122 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 125 IsParameter( | 123 IsIntPtrConstant(offset))); |
| 126 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 127 IsIntPtrConstant(offset))); | |
| 128 } else { | 124 } else { |
| 129 #if V8_TARGET_LITTLE_ENDIAN | 125 #if V8_TARGET_LITTLE_ENDIAN |
| 130 const int kStep = -1; | 126 const int kStep = -1; |
| 131 const int kMsbOffset = 1; | 127 const int kMsbOffset = 1; |
| 132 #elif V8_TARGET_BIG_ENDIAN | 128 #elif V8_TARGET_BIG_ENDIAN |
| 133 const int kStep = 1; | 129 const int kStep = 1; |
| 134 const int kMsbOffset = 0; | 130 const int kMsbOffset = 0; |
| 135 #else | 131 #else |
| 136 #error "Unknown Architecture" | 132 #error "Unknown Architecture" |
| 137 #endif | 133 #endif |
| 138 Matcher<Node*> bytes[2]; | 134 Matcher<Node*> bytes[2]; |
| 139 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { | 135 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
| 140 bytes[i] = IsLoad( | 136 bytes[i] = IsLoad( |
| 141 MachineType::Uint8(), | 137 MachineType::Uint8(), |
| 142 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 138 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 143 IsIntPtrAdd( | 139 IsIntPtrAdd( |
| 144 IsParameter( | 140 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 145 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 146 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); | 141 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
| 147 } | 142 } |
| 148 return IsWord32Or(IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), | 143 return IsWord32Or(IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), |
| 149 bytes[1]); | 144 bytes[1]); |
| 150 } | 145 } |
| 151 } | 146 } |
| 152 | 147 |
| 153 Matcher<Node*> | 148 Matcher<Node*> |
| 154 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand( | 149 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedShortOperand( |
| 155 int offset) { | 150 int offset) { |
| 156 Matcher<Node*> load_matcher; | 151 Matcher<Node*> load_matcher; |
| 157 if (TargetSupportsUnalignedAccess()) { | 152 if (TargetSupportsUnalignedAccess()) { |
| 158 load_matcher = IsLoad( | 153 load_matcher = IsLoad( |
| 159 MachineType::Int16(), | 154 MachineType::Int16(), |
| 160 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 155 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 161 IsIntPtrAdd( | 156 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 162 IsParameter( | 157 IsIntPtrConstant(offset))); |
| 163 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 164 IsIntPtrConstant(offset))); | |
| 165 } else { | 158 } else { |
| 166 #if V8_TARGET_LITTLE_ENDIAN | 159 #if V8_TARGET_LITTLE_ENDIAN |
| 167 const int kStep = -1; | 160 const int kStep = -1; |
| 168 const int kMsbOffset = 1; | 161 const int kMsbOffset = 1; |
| 169 #elif V8_TARGET_BIG_ENDIAN | 162 #elif V8_TARGET_BIG_ENDIAN |
| 170 const int kStep = 1; | 163 const int kStep = 1; |
| 171 const int kMsbOffset = 0; | 164 const int kMsbOffset = 0; |
| 172 #else | 165 #else |
| 173 #error "Unknown Architecture" | 166 #error "Unknown Architecture" |
| 174 #endif | 167 #endif |
| 175 Matcher<Node*> bytes[2]; | 168 Matcher<Node*> bytes[2]; |
| 176 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { | 169 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
| 177 bytes[i] = IsLoad( | 170 bytes[i] = IsLoad( |
| 178 (i == 0) ? MachineType::Int8() : MachineType::Uint8(), | 171 (i == 0) ? MachineType::Int8() : MachineType::Uint8(), |
| 179 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 172 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 180 IsIntPtrAdd( | 173 IsIntPtrAdd( |
| 181 IsParameter( | 174 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 182 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 183 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); | 175 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
| 184 } | 176 } |
| 185 load_matcher = IsWord32Or( | 177 load_matcher = IsWord32Or( |
| 186 IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), bytes[1]); | 178 IsWord32Shl(bytes[0], IsInt32Constant(kBitsPerByte)), bytes[1]); |
| 187 } | 179 } |
| 188 | 180 |
| 189 if (kPointerSize == 8) { | 181 if (kPointerSize == 8) { |
| 190 load_matcher = IsChangeInt32ToInt64(load_matcher); | 182 load_matcher = IsChangeInt32ToInt64(load_matcher); |
| 191 } | 183 } |
| 192 return load_matcher; | 184 return load_matcher; |
| 193 } | 185 } |
| 194 | 186 |
| 195 Matcher<Node*> | 187 Matcher<Node*> |
| 196 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand( | 188 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsUnsignedQuadOperand( |
| 197 int offset) { | 189 int offset) { |
| 198 if (TargetSupportsUnalignedAccess()) { | 190 if (TargetSupportsUnalignedAccess()) { |
| 199 return IsLoad( | 191 return IsLoad( |
| 200 MachineType::Uint32(), | 192 MachineType::Uint32(), |
| 201 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 193 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 202 IsIntPtrAdd( | 194 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 203 IsParameter( | 195 IsIntPtrConstant(offset))); |
| 204 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 205 IsIntPtrConstant(offset))); | |
| 206 } else { | 196 } else { |
| 207 #if V8_TARGET_LITTLE_ENDIAN | 197 #if V8_TARGET_LITTLE_ENDIAN |
| 208 const int kStep = -1; | 198 const int kStep = -1; |
| 209 const int kMsbOffset = 3; | 199 const int kMsbOffset = 3; |
| 210 #elif V8_TARGET_BIG_ENDIAN | 200 #elif V8_TARGET_BIG_ENDIAN |
| 211 const int kStep = 1; | 201 const int kStep = 1; |
| 212 const int kMsbOffset = 0; | 202 const int kMsbOffset = 0; |
| 213 #else | 203 #else |
| 214 #error "Unknown Architecture" | 204 #error "Unknown Architecture" |
| 215 #endif | 205 #endif |
| 216 Matcher<Node*> bytes[4]; | 206 Matcher<Node*> bytes[4]; |
| 217 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { | 207 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
| 218 bytes[i] = IsLoad( | 208 bytes[i] = IsLoad( |
| 219 MachineType::Uint8(), | 209 MachineType::Uint8(), |
| 220 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 210 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 221 IsIntPtrAdd( | 211 IsIntPtrAdd( |
| 222 IsParameter( | 212 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 223 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 224 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); | 213 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
| 225 } | 214 } |
| 226 return IsWord32Or( | 215 return IsWord32Or( |
| 227 IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)), | 216 IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)), |
| 228 IsWord32Or( | 217 IsWord32Or( |
| 229 IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)), | 218 IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)), |
| 230 IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)), | 219 IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)), |
| 231 bytes[3]))); | 220 bytes[3]))); |
| 232 } | 221 } |
| 233 } | 222 } |
| 234 | 223 |
| 235 Matcher<Node*> | 224 Matcher<Node*> |
| 236 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand( | 225 InterpreterAssemblerTest::InterpreterAssemblerForTest::IsSignedQuadOperand( |
| 237 int offset) { | 226 int offset) { |
| 238 Matcher<Node*> load_matcher; | 227 Matcher<Node*> load_matcher; |
| 239 if (TargetSupportsUnalignedAccess()) { | 228 if (TargetSupportsUnalignedAccess()) { |
| 240 load_matcher = IsLoad( | 229 load_matcher = IsLoad( |
| 241 MachineType::Int32(), | 230 MachineType::Int32(), |
| 242 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 231 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 243 IsIntPtrAdd( | 232 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 244 IsParameter( | 233 IsIntPtrConstant(offset))); |
| 245 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 246 IsIntPtrConstant(offset))); | |
| 247 } else { | 234 } else { |
| 248 #if V8_TARGET_LITTLE_ENDIAN | 235 #if V8_TARGET_LITTLE_ENDIAN |
| 249 const int kStep = -1; | 236 const int kStep = -1; |
| 250 int kMsbOffset = 3; | 237 int kMsbOffset = 3; |
| 251 #elif V8_TARGET_BIG_ENDIAN | 238 #elif V8_TARGET_BIG_ENDIAN |
| 252 const int kStep = 1; | 239 const int kStep = 1; |
| 253 int kMsbOffset = 0; | 240 int kMsbOffset = 0; |
| 254 #else | 241 #else |
| 255 #error "Unknown Architecture" | 242 #error "Unknown Architecture" |
| 256 #endif | 243 #endif |
| 257 Matcher<Node*> bytes[4]; | 244 Matcher<Node*> bytes[4]; |
| 258 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { | 245 for (int i = 0; i < static_cast<int>(arraysize(bytes)); i++) { |
| 259 bytes[i] = IsLoad( | 246 bytes[i] = IsLoad( |
| 260 (i == 0) ? MachineType::Int8() : MachineType::Uint8(), | 247 (i == 0) ? MachineType::Int8() : MachineType::Uint8(), |
| 261 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 248 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 262 IsIntPtrAdd( | 249 IsIntPtrAdd( |
| 263 IsParameter( | 250 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 264 InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | |
| 265 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); | 251 IsIntPtrConstant(offset + kMsbOffset + kStep * i))); |
| 266 } | 252 } |
| 267 load_matcher = IsWord32Or( | 253 load_matcher = IsWord32Or( |
| 268 IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)), | 254 IsWord32Shl(bytes[0], IsInt32Constant(3 * kBitsPerByte)), |
| 269 IsWord32Or( | 255 IsWord32Or( |
| 270 IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)), | 256 IsWord32Shl(bytes[1], IsInt32Constant(2 * kBitsPerByte)), |
| 271 IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)), | 257 IsWord32Or(IsWord32Shl(bytes[2], IsInt32Constant(1 * kBitsPerByte)), |
| 272 bytes[3]))); | 258 bytes[3]))); |
| 273 } | 259 } |
| 274 | 260 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 } | 295 } |
| 310 return nullptr; | 296 return nullptr; |
| 311 } | 297 } |
| 312 | 298 |
| 313 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { | 299 TARGET_TEST_F(InterpreterAssemblerTest, Dispatch) { |
| 314 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 300 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 315 InterpreterAssemblerForTest m(this, bytecode); | 301 InterpreterAssemblerForTest m(this, bytecode); |
| 316 Node* tail_call_node = m.Dispatch(); | 302 Node* tail_call_node = m.Dispatch(); |
| 317 | 303 |
| 318 OperandScale operand_scale = OperandScale::kSingle; | 304 OperandScale operand_scale = OperandScale::kSingle; |
| 319 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( | 305 Matcher<Node*> next_bytecode_offset_matcher = |
| 320 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | 306 IsIntPtrAdd(IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 321 IsIntPtrConstant( | 307 IsIntPtrConstant( |
| 322 interpreter::Bytecodes::Size(bytecode, operand_scale))); | 308 interpreter::Bytecodes::Size(bytecode, operand_scale))); |
| 323 Matcher<Node*> target_bytecode_matcher = m.IsLoad( | 309 Matcher<Node*> target_bytecode_matcher = |
| 324 MachineType::Uint8(), | 310 m.IsLoad(MachineType::Uint8(), |
| 325 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 311 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 326 next_bytecode_offset_matcher); | 312 next_bytecode_offset_matcher); |
| 327 if (kPointerSize == 8) { | 313 if (kPointerSize == 8) { |
| 328 target_bytecode_matcher = IsChangeUint32ToUint64(target_bytecode_matcher); | 314 target_bytecode_matcher = IsChangeUint32ToUint64(target_bytecode_matcher); |
| 329 } | 315 } |
| 330 Matcher<Node*> code_target_matcher = m.IsLoad( | 316 Matcher<Node*> code_target_matcher = m.IsLoad( |
| 331 MachineType::Pointer(), | 317 MachineType::Pointer(), |
| 332 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 318 IsParameter(InterpreterDispatchDescriptor::kDispatchTable), |
| 333 IsWordShl(target_bytecode_matcher, IsIntPtrConstant(kPointerSizeLog2))); | 319 IsWordShl(target_bytecode_matcher, IsIntPtrConstant(kPointerSizeLog2))); |
| 334 | 320 |
| 335 if (interpreter::Bytecodes::IsStarLookahead(bytecode, operand_scale)) { | 321 if (interpreter::Bytecodes::IsStarLookahead(bytecode, operand_scale)) { |
| 336 Matcher<Node*> after_lookahead_offset = | 322 Matcher<Node*> after_lookahead_offset = |
| 337 IsIntPtrAdd(next_bytecode_offset_matcher, | 323 IsIntPtrAdd(next_bytecode_offset_matcher, |
| 338 IsIntPtrConstant(interpreter::Bytecodes::Size( | 324 IsIntPtrConstant(interpreter::Bytecodes::Size( |
| 339 Bytecode::kStar, operand_scale))); | 325 Bytecode::kStar, operand_scale))); |
| 340 next_bytecode_offset_matcher = | 326 next_bytecode_offset_matcher = |
| 341 IsPhi(MachineType::PointerRepresentation(), | 327 IsPhi(MachineType::PointerRepresentation(), |
| 342 next_bytecode_offset_matcher, after_lookahead_offset, _); | 328 next_bytecode_offset_matcher, after_lookahead_offset, _); |
| 343 Matcher<Node*> after_lookahead_bytecode = m.IsLoad( | 329 Matcher<Node*> after_lookahead_bytecode = |
| 344 MachineType::Uint8(), | 330 m.IsLoad(MachineType::Uint8(), |
| 345 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 331 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 346 after_lookahead_offset); | 332 after_lookahead_offset); |
| 347 if (kPointerSize == 8) { | 333 if (kPointerSize == 8) { |
| 348 after_lookahead_bytecode = | 334 after_lookahead_bytecode = |
| 349 IsChangeUint32ToUint64(after_lookahead_bytecode); | 335 IsChangeUint32ToUint64(after_lookahead_bytecode); |
| 350 } | 336 } |
| 351 target_bytecode_matcher = | 337 target_bytecode_matcher = |
| 352 IsPhi(MachineRepresentation::kWord8, target_bytecode_matcher, | 338 IsPhi(MachineRepresentation::kWord8, target_bytecode_matcher, |
| 353 after_lookahead_bytecode, _); | 339 after_lookahead_bytecode, _); |
| 354 code_target_matcher = m.IsLoad( | 340 code_target_matcher = |
| 355 MachineType::Pointer(), | 341 m.IsLoad(MachineType::Pointer(), |
| 356 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 342 IsParameter(InterpreterDispatchDescriptor::kDispatchTable), |
| 357 IsWordShl(target_bytecode_matcher, | 343 IsWordShl(target_bytecode_matcher, |
| 358 IsIntPtrConstant(kPointerSizeLog2))); | 344 IsIntPtrConstant(kPointerSizeLog2))); |
| 359 } | 345 } |
| 360 | 346 |
| 361 EXPECT_THAT( | 347 EXPECT_THAT( |
| 362 tail_call_node, | 348 tail_call_node, |
| 363 IsTailCall( | 349 IsTailCall(_, code_target_matcher, |
| 364 _, code_target_matcher, | 350 IsParameter(InterpreterDispatchDescriptor::kAccumulator), |
| 365 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), | 351 next_bytecode_offset_matcher, |
| 366 next_bytecode_offset_matcher, | 352 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 367 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 353 IsParameter(InterpreterDispatchDescriptor::kDispatchTable), |
| 368 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 354 _, _)); |
| 369 _, _)); | |
| 370 } | 355 } |
| 371 } | 356 } |
| 372 | 357 |
| 373 TARGET_TEST_F(InterpreterAssemblerTest, Jump) { | 358 TARGET_TEST_F(InterpreterAssemblerTest, Jump) { |
| 374 // If debug code is enabled we emit extra code in Jump. | 359 // If debug code is enabled we emit extra code in Jump. |
| 375 if (FLAG_debug_code) return; | 360 if (FLAG_debug_code) return; |
| 376 | 361 |
| 377 int jump_offsets[] = {-9710, -77, 0, +3, +97109}; | 362 int jump_offsets[] = {-9710, -77, 0, +3, +97109}; |
| 378 TRACED_FOREACH(int, jump_offset, jump_offsets) { | 363 TRACED_FOREACH(int, jump_offset, jump_offsets) { |
| 379 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 364 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 380 if (!interpreter::Bytecodes::IsJump(bytecode)) return; | 365 if (!interpreter::Bytecodes::IsJump(bytecode)) return; |
| 381 | 366 |
| 382 InterpreterAssemblerForTest m(this, bytecode); | 367 InterpreterAssemblerForTest m(this, bytecode); |
| 383 Node* tail_call_node = m.Jump(m.IntPtrConstant(jump_offset)); | 368 Node* tail_call_node = m.Jump(m.IntPtrConstant(jump_offset)); |
| 384 | 369 |
| 385 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( | 370 Matcher<Node*> next_bytecode_offset_matcher = IsIntPtrAdd( |
| 386 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffsetParameter), | 371 IsParameter(InterpreterDispatchDescriptor::kBytecodeOffset), |
| 387 IsIntPtrConstant(jump_offset)); | 372 IsIntPtrConstant(jump_offset)); |
| 388 Matcher<Node*> target_bytecode_matcher = | 373 Matcher<Node*> target_bytecode_matcher = |
| 389 m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher); | 374 m.IsLoad(MachineType::Uint8(), _, next_bytecode_offset_matcher); |
| 390 if (kPointerSize == 8) { | 375 if (kPointerSize == 8) { |
| 391 target_bytecode_matcher = | 376 target_bytecode_matcher = |
| 392 IsChangeUint32ToUint64(target_bytecode_matcher); | 377 IsChangeUint32ToUint64(target_bytecode_matcher); |
| 393 } | 378 } |
| 394 Matcher<Node*> code_target_matcher = m.IsLoad( | 379 Matcher<Node*> code_target_matcher = |
| 395 MachineType::Pointer(), | 380 m.IsLoad(MachineType::Pointer(), |
| 396 IsParameter(InterpreterDispatchDescriptor::kDispatchTableParameter), | 381 IsParameter(InterpreterDispatchDescriptor::kDispatchTable), |
| 397 IsWordShl(target_bytecode_matcher, | 382 IsWordShl(target_bytecode_matcher, |
| 398 IsIntPtrConstant(kPointerSizeLog2))); | 383 IsIntPtrConstant(kPointerSizeLog2))); |
| 399 | 384 |
| 400 EXPECT_THAT( | 385 EXPECT_THAT( |
| 401 tail_call_node, | 386 tail_call_node, |
| 402 IsTailCall( | 387 IsTailCall(_, code_target_matcher, |
| 403 _, code_target_matcher, | 388 IsParameter(InterpreterDispatchDescriptor::kAccumulator), |
| 404 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter), | 389 next_bytecode_offset_matcher, _, |
| 405 next_bytecode_offset_matcher, _, | 390 IsParameter(InterpreterDispatchDescriptor::kDispatchTable), |
| 406 IsParameter( | 391 _, _)); |
| 407 InterpreterDispatchDescriptor::kDispatchTableParameter), | |
| 408 _, _)); | |
| 409 } | 392 } |
| 410 } | 393 } |
| 411 } | 394 } |
| 412 | 395 |
| 413 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { | 396 TARGET_TEST_F(InterpreterAssemblerTest, BytecodeOperand) { |
| 414 static const OperandScale kOperandScales[] = { | 397 static const OperandScale kOperandScales[] = { |
| 415 OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple}; | 398 OperandScale::kSingle, OperandScale::kDouble, OperandScale::kQuadruple}; |
| 416 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 399 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 417 TRACED_FOREACH(interpreter::OperandScale, operand_scale, kOperandScales) { | 400 TRACED_FOREACH(interpreter::OperandScale, operand_scale, kOperandScales) { |
| 418 InterpreterAssemblerForTest m(this, bytecode, operand_scale); | 401 InterpreterAssemblerForTest m(this, bytecode, operand_scale); |
| (...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 471 | 454 |
| 472 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { | 455 TARGET_TEST_F(InterpreterAssemblerTest, GetSetAccumulator) { |
| 473 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 456 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 474 if (!interpreter::Bytecodes::ReadsAccumulator(bytecode) || | 457 if (!interpreter::Bytecodes::ReadsAccumulator(bytecode) || |
| 475 !interpreter::Bytecodes::WritesAccumulator(bytecode)) { | 458 !interpreter::Bytecodes::WritesAccumulator(bytecode)) { |
| 476 continue; | 459 continue; |
| 477 } | 460 } |
| 478 | 461 |
| 479 InterpreterAssemblerForTest m(this, bytecode); | 462 InterpreterAssemblerForTest m(this, bytecode); |
| 480 // Should be incoming accumulator if not set. | 463 // Should be incoming accumulator if not set. |
| 481 EXPECT_THAT( | 464 EXPECT_THAT(m.GetAccumulator(), |
| 482 m.GetAccumulator(), | 465 IsParameter(InterpreterDispatchDescriptor::kAccumulator)); |
| 483 IsParameter(InterpreterDispatchDescriptor::kAccumulatorParameter)); | |
| 484 // Should be set by SetAccumulator. | 466 // Should be set by SetAccumulator. |
| 485 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); | 467 Node* accumulator_value_1 = m.Int32Constant(0xdeadbeef); |
| 486 m.SetAccumulator(accumulator_value_1); | 468 m.SetAccumulator(accumulator_value_1); |
| 487 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); | 469 EXPECT_THAT(m.GetAccumulator(), accumulator_value_1); |
| 488 Node* accumulator_value_2 = m.Int32Constant(42); | 470 Node* accumulator_value_2 = m.Int32Constant(42); |
| 489 m.SetAccumulator(accumulator_value_2); | 471 m.SetAccumulator(accumulator_value_2); |
| 490 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); | 472 EXPECT_THAT(m.GetAccumulator(), accumulator_value_2); |
| 491 | 473 |
| 492 // Should be passed to next bytecode handler on dispatch. | 474 // Should be passed to next bytecode handler on dispatch. |
| 493 Node* tail_call_node = m.Dispatch(); | 475 Node* tail_call_node = m.Dispatch(); |
| (...skipping 96 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 590 } | 572 } |
| 591 } | 573 } |
| 592 | 574 |
| 593 TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { | 575 TARGET_TEST_F(InterpreterAssemblerTest, LoadConstantPoolEntry) { |
| 594 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { | 576 TRACED_FOREACH(interpreter::Bytecode, bytecode, kBytecodes) { |
| 595 InterpreterAssemblerForTest m(this, bytecode); | 577 InterpreterAssemblerForTest m(this, bytecode); |
| 596 Node* index = m.IntPtrConstant(2); | 578 Node* index = m.IntPtrConstant(2); |
| 597 Node* load_constant = m.LoadConstantPoolEntry(index); | 579 Node* load_constant = m.LoadConstantPoolEntry(index); |
| 598 Matcher<Node*> constant_pool_matcher = m.IsLoad( | 580 Matcher<Node*> constant_pool_matcher = m.IsLoad( |
| 599 MachineType::AnyTagged(), | 581 MachineType::AnyTagged(), |
| 600 IsParameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter), | 582 IsParameter(InterpreterDispatchDescriptor::kBytecodeArray), |
| 601 IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag)); | 583 IsIntPtrConstant(BytecodeArray::kConstantPoolOffset - kHeapObjectTag)); |
| 602 EXPECT_THAT( | 584 EXPECT_THAT( |
| 603 load_constant, | 585 load_constant, |
| 604 m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher, | 586 m.IsLoad(MachineType::AnyTagged(), constant_pool_matcher, |
| 605 IsIntPtrAdd( | 587 IsIntPtrAdd( |
| 606 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), | 588 IsIntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), |
| 607 IsWordShl(index, IsIntPtrConstant(kPointerSizeLog2))))); | 589 IsWordShl(index, IsIntPtrConstant(kPointerSizeLog2))))); |
| 608 } | 590 } |
| 609 } | 591 } |
| 610 | 592 |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 731 EXPECT_THAT(feedback_vector, | 713 EXPECT_THAT(feedback_vector, |
| 732 m.IsLoad(MachineType::AnyTagged(), load_literals_matcher, | 714 m.IsLoad(MachineType::AnyTagged(), load_literals_matcher, |
| 733 IsIntPtrConstant(LiteralsArray::kFeedbackVectorOffset - | 715 IsIntPtrConstant(LiteralsArray::kFeedbackVectorOffset - |
| 734 kHeapObjectTag))); | 716 kHeapObjectTag))); |
| 735 } | 717 } |
| 736 } | 718 } |
| 737 | 719 |
| 738 } // namespace interpreter | 720 } // namespace interpreter |
| 739 } // namespace internal | 721 } // namespace internal |
| 740 } // namespace v8 | 722 } // namespace v8 |
| OLD | NEW |