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 "src/signature.h" | 5 #include "src/signature.h" |
6 | 6 |
7 #include "src/base/platform/elapsed-timer.h" | 7 #include "src/base/platform/elapsed-timer.h" |
8 #include "src/bit-vector.h" | 8 #include "src/bit-vector.h" |
9 #include "src/flags.h" | 9 #include "src/flags.h" |
10 #include "src/handles.h" | 10 #include "src/handles.h" |
(...skipping 477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
488 case kExprF64Const: | 488 case kExprF64Const: |
489 return 9; | 489 return 9; |
490 case kSimdPrefix: { | 490 case kSimdPrefix: { |
491 byte simd_index = decoder->read_u8<true>(pc + 1, "simd_index"); | 491 byte simd_index = decoder->read_u8<true>(pc + 1, "simd_index"); |
492 WasmOpcode opcode = | 492 WasmOpcode opcode = |
493 static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index); | 493 static_cast<WasmOpcode>(kSimdPrefix << 8 | simd_index); |
494 switch (opcode) { | 494 switch (opcode) { |
495 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: | 495 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
496 FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) | 496 FOREACH_SIMD_0_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
497 #undef DECLARE_OPCODE_CASE | 497 #undef DECLARE_OPCODE_CASE |
498 { | 498 return 2; |
499 return 2; | |
500 } | |
501 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: | 499 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
502 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) | 500 FOREACH_SIMD_1_OPERAND_OPCODE(DECLARE_OPCODE_CASE) |
503 #undef DECLARE_OPCODE_CASE | 501 #undef DECLARE_OPCODE_CASE |
| 502 return 3; |
| 503 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
| 504 FOREACH_SIMD_MEM_OPCODE(DECLARE_OPCODE_CASE) |
| 505 #undef DECLARE_OPCODE_CASE |
504 { | 506 { |
505 return 3; | 507 MemoryAccessOperand<true> operand(decoder, pc + 1, UINT32_MAX); |
| 508 return 2 + operand.length; |
506 } | 509 } |
507 // Shuffles require a byte per lane, or 16 immediate bytes. | 510 // Shuffles require a byte per lane, or 16 immediate bytes. |
508 case kExprS8x16Shuffle: | 511 case kExprS8x16Shuffle: |
509 return 2 + kSimd128Size; | 512 return 2 + kSimd128Size; |
510 default: | 513 default: |
511 decoder->error(pc, "invalid SIMD opcode"); | 514 decoder->error(pc, "invalid SIMD opcode"); |
512 return 2; | 515 return 2; |
513 } | 516 } |
514 } | 517 } |
515 default: | 518 default: |
516 return 1; | 519 return 1; |
517 } | 520 } |
518 } | 521 } |
519 | 522 |
520 std::pair<uint32_t, uint32_t> StackEffect(const byte* pc) { | 523 std::pair<uint32_t, uint32_t> StackEffect(const byte* pc) { |
521 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); | 524 WasmOpcode opcode = static_cast<WasmOpcode>(*pc); |
522 // Handle "simple" opcodes with a fixed signature first. | 525 // Handle "simple" opcodes with a fixed signature first. |
523 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 526 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
524 if (!sig) sig = WasmOpcodes::AsmjsSignature(opcode); | 527 if (!sig) sig = WasmOpcodes::AsmjsSignature(opcode); |
525 if (sig) return {sig->parameter_count(), sig->return_count()}; | 528 if (sig) return {sig->parameter_count(), sig->return_count()}; |
| 529 if (WasmOpcodes::IsPrefixOpcode(opcode)) { |
| 530 opcode = static_cast<WasmOpcode>(opcode << 8 | *(pc + 1)); |
| 531 } |
526 | 532 |
527 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: | 533 #define DECLARE_OPCODE_CASE(name, opcode, sig) case kExpr##name: |
528 // clang-format off | 534 // clang-format off |
529 switch (opcode) { | 535 switch (opcode) { |
530 case kExprSelect: | 536 case kExprSelect: |
531 return {3, 1}; | 537 return {3, 1}; |
| 538 case kExprS128StoreMem: |
532 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) | 539 FOREACH_STORE_MEM_OPCODE(DECLARE_OPCODE_CASE) |
533 return {2, 0}; | 540 return {2, 0}; |
| 541 case kExprS128LoadMem: |
534 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) | 542 FOREACH_LOAD_MEM_OPCODE(DECLARE_OPCODE_CASE) |
535 case kExprTeeLocal: | 543 case kExprTeeLocal: |
536 case kExprGrowMemory: | 544 case kExprGrowMemory: |
537 return {1, 1}; | 545 return {1, 1}; |
538 case kExprSetLocal: | 546 case kExprSetLocal: |
539 case kExprSetGlobal: | 547 case kExprSetGlobal: |
540 case kExprDrop: | 548 case kExprDrop: |
541 case kExprBrIf: | 549 case kExprBrIf: |
542 case kExprBrTable: | 550 case kExprBrTable: |
543 case kExprIf: | 551 case kExprIf: |
(...skipping 678 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1222 break; | 1230 break; |
1223 case kExprI64LoadMem: | 1231 case kExprI64LoadMem: |
1224 len = DecodeLoadMem(kWasmI64, MachineType::Int64()); | 1232 len = DecodeLoadMem(kWasmI64, MachineType::Int64()); |
1225 break; | 1233 break; |
1226 case kExprF32LoadMem: | 1234 case kExprF32LoadMem: |
1227 len = DecodeLoadMem(kWasmF32, MachineType::Float32()); | 1235 len = DecodeLoadMem(kWasmF32, MachineType::Float32()); |
1228 break; | 1236 break; |
1229 case kExprF64LoadMem: | 1237 case kExprF64LoadMem: |
1230 len = DecodeLoadMem(kWasmF64, MachineType::Float64()); | 1238 len = DecodeLoadMem(kWasmF64, MachineType::Float64()); |
1231 break; | 1239 break; |
1232 case kExprS128LoadMem: | |
1233 CHECK_PROTOTYPE_OPCODE(simd); | |
1234 len = DecodeLoadMem(kWasmS128, MachineType::Simd128()); | |
1235 break; | |
1236 case kExprI32StoreMem8: | 1240 case kExprI32StoreMem8: |
1237 len = DecodeStoreMem(kWasmI32, MachineType::Int8()); | 1241 len = DecodeStoreMem(kWasmI32, MachineType::Int8()); |
1238 break; | 1242 break; |
1239 case kExprI32StoreMem16: | 1243 case kExprI32StoreMem16: |
1240 len = DecodeStoreMem(kWasmI32, MachineType::Int16()); | 1244 len = DecodeStoreMem(kWasmI32, MachineType::Int16()); |
1241 break; | 1245 break; |
1242 case kExprI32StoreMem: | 1246 case kExprI32StoreMem: |
1243 len = DecodeStoreMem(kWasmI32, MachineType::Int32()); | 1247 len = DecodeStoreMem(kWasmI32, MachineType::Int32()); |
1244 break; | 1248 break; |
1245 case kExprI64StoreMem8: | 1249 case kExprI64StoreMem8: |
1246 len = DecodeStoreMem(kWasmI64, MachineType::Int8()); | 1250 len = DecodeStoreMem(kWasmI64, MachineType::Int8()); |
1247 break; | 1251 break; |
1248 case kExprI64StoreMem16: | 1252 case kExprI64StoreMem16: |
1249 len = DecodeStoreMem(kWasmI64, MachineType::Int16()); | 1253 len = DecodeStoreMem(kWasmI64, MachineType::Int16()); |
1250 break; | 1254 break; |
1251 case kExprI64StoreMem32: | 1255 case kExprI64StoreMem32: |
1252 len = DecodeStoreMem(kWasmI64, MachineType::Int32()); | 1256 len = DecodeStoreMem(kWasmI64, MachineType::Int32()); |
1253 break; | 1257 break; |
1254 case kExprI64StoreMem: | 1258 case kExprI64StoreMem: |
1255 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); | 1259 len = DecodeStoreMem(kWasmI64, MachineType::Int64()); |
1256 break; | 1260 break; |
1257 case kExprF32StoreMem: | 1261 case kExprF32StoreMem: |
1258 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); | 1262 len = DecodeStoreMem(kWasmF32, MachineType::Float32()); |
1259 break; | 1263 break; |
1260 case kExprF64StoreMem: | 1264 case kExprF64StoreMem: |
1261 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); | 1265 len = DecodeStoreMem(kWasmF64, MachineType::Float64()); |
1262 break; | 1266 break; |
1263 case kExprS128StoreMem: | |
1264 CHECK_PROTOTYPE_OPCODE(simd); | |
1265 len = DecodeStoreMem(kWasmS128, MachineType::Simd128()); | |
1266 break; | |
1267 case kExprGrowMemory: { | 1267 case kExprGrowMemory: { |
1268 if (!CheckHasMemory()) break; | 1268 if (!CheckHasMemory()) break; |
1269 MemoryIndexOperand<true> operand(this, pc_); | 1269 MemoryIndexOperand<true> operand(this, pc_); |
1270 DCHECK_NOT_NULL(module_); | 1270 DCHECK_NOT_NULL(module_); |
1271 if (module_->is_wasm()) { | 1271 if (module_->is_wasm()) { |
1272 Value val = Pop(0, kWasmI32); | 1272 Value val = Pop(0, kWasmI32); |
1273 Push(kWasmI32, BUILD(GrowMemory, val.node)); | 1273 Push(kWasmI32, BUILD(GrowMemory, val.node)); |
1274 } else { | 1274 } else { |
1275 error("grow_memory is not supported for asmjs modules"); | 1275 error("grow_memory is not supported for asmjs modules"); |
1276 } | 1276 } |
(...skipping 222 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1499 if (!CheckHasMemory()) return 0; | 1499 if (!CheckHasMemory()) return 0; |
1500 MemoryAccessOperand<true> operand( | 1500 MemoryAccessOperand<true> operand( |
1501 this, pc_, ElementSizeLog2Of(mem_type.representation())); | 1501 this, pc_, ElementSizeLog2Of(mem_type.representation())); |
1502 Value val = Pop(1, type); | 1502 Value val = Pop(1, type); |
1503 Value index = Pop(0, kWasmI32); | 1503 Value index = Pop(0, kWasmI32); |
1504 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, | 1504 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, |
1505 val.node, position()); | 1505 val.node, position()); |
1506 return 1 + operand.length; | 1506 return 1 + operand.length; |
1507 } | 1507 } |
1508 | 1508 |
| 1509 int DecodePrefixedLoadMem(ValueType type, MachineType mem_type) { |
| 1510 if (!CheckHasMemory()) return 0; |
| 1511 MemoryAccessOperand<true> operand( |
| 1512 this, pc_ + 1, ElementSizeLog2Of(mem_type.representation())); |
| 1513 |
| 1514 Value index = Pop(0, kWasmI32); |
| 1515 TFNode* node = BUILD(LoadMem, type, mem_type, index.node, operand.offset, |
| 1516 operand.alignment, position()); |
| 1517 Push(type, node); |
| 1518 return operand.length; |
| 1519 } |
| 1520 |
| 1521 int DecodePrefixedStoreMem(ValueType type, MachineType mem_type) { |
| 1522 if (!CheckHasMemory()) return 0; |
| 1523 MemoryAccessOperand<true> operand( |
| 1524 this, pc_ + 1, ElementSizeLog2Of(mem_type.representation())); |
| 1525 Value val = Pop(1, type); |
| 1526 Value index = Pop(0, kWasmI32); |
| 1527 BUILD(StoreMem, mem_type, index.node, operand.offset, operand.alignment, |
| 1528 val.node, position()); |
| 1529 return operand.length; |
| 1530 } |
| 1531 |
1509 unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) { | 1532 unsigned SimdExtractLane(WasmOpcode opcode, ValueType type) { |
1510 SimdLaneOperand<true> operand(this, pc_); | 1533 SimdLaneOperand<true> operand(this, pc_); |
1511 if (Validate(pc_, opcode, operand)) { | 1534 if (Validate(pc_, opcode, operand)) { |
1512 compiler::NodeVector inputs(1, zone_); | 1535 compiler::NodeVector inputs(1, zone_); |
1513 inputs[0] = Pop(0, ValueType::kSimd128).node; | 1536 inputs[0] = Pop(0, ValueType::kSimd128).node; |
1514 TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs); | 1537 TFNode* node = BUILD(SimdLaneOp, opcode, operand.lane, inputs); |
1515 Push(type, node); | 1538 Push(type, node); |
1516 } | 1539 } |
1517 return operand.length; | 1540 return operand.length; |
1518 } | 1541 } |
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1584 case kExprI8x16Shl: | 1607 case kExprI8x16Shl: |
1585 case kExprI8x16ShrS: | 1608 case kExprI8x16ShrS: |
1586 case kExprI8x16ShrU: { | 1609 case kExprI8x16ShrU: { |
1587 len = SimdShiftOp(opcode); | 1610 len = SimdShiftOp(opcode); |
1588 break; | 1611 break; |
1589 } | 1612 } |
1590 case kExprS8x16Shuffle: { | 1613 case kExprS8x16Shuffle: { |
1591 len = Simd8x16ShuffleOp(); | 1614 len = Simd8x16ShuffleOp(); |
1592 break; | 1615 break; |
1593 } | 1616 } |
| 1617 case kExprS128LoadMem: |
| 1618 CHECK_PROTOTYPE_OPCODE(simd); |
| 1619 len = DecodePrefixedLoadMem(kWasmS128, MachineType::Simd128()); |
| 1620 break; |
| 1621 case kExprS128StoreMem: |
| 1622 CHECK_PROTOTYPE_OPCODE(simd); |
| 1623 len = DecodePrefixedStoreMem(kWasmS128, MachineType::Simd128()); |
| 1624 break; |
1594 default: { | 1625 default: { |
1595 FunctionSig* sig = WasmOpcodes::Signature(opcode); | 1626 FunctionSig* sig = WasmOpcodes::Signature(opcode); |
1596 if (sig != nullptr) { | 1627 if (sig != nullptr) { |
1597 compiler::NodeVector inputs(sig->parameter_count(), zone_); | 1628 compiler::NodeVector inputs(sig->parameter_count(), zone_); |
1598 for (size_t i = sig->parameter_count(); i > 0; i--) { | 1629 for (size_t i = sig->parameter_count(); i > 0; i--) { |
1599 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); | 1630 Value val = Pop(static_cast<int>(i - 1), sig->GetParam(i - 1)); |
1600 inputs[i - 1] = val.node; | 1631 inputs[i - 1] = val.node; |
1601 } | 1632 } |
1602 TFNode* node = BUILD(SimdOp, opcode, inputs); | 1633 TFNode* node = BUILD(SimdOp, opcode, inputs); |
1603 Push(GetReturnType(sig), node); | 1634 Push(GetReturnType(sig), node); |
(...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2263 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, | 2294 BitVector* AnalyzeLoopAssignmentForTesting(Zone* zone, size_t num_locals, |
2264 const byte* start, const byte* end) { | 2295 const byte* start, const byte* end) { |
2265 Decoder decoder(start, end); | 2296 Decoder decoder(start, end); |
2266 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start, | 2297 return WasmDecoder::AnalyzeLoopAssignment(&decoder, start, |
2267 static_cast<int>(num_locals), zone); | 2298 static_cast<int>(num_locals), zone); |
2268 } | 2299 } |
2269 | 2300 |
2270 } // namespace wasm | 2301 } // namespace wasm |
2271 } // namespace internal | 2302 } // namespace internal |
2272 } // namespace v8 | 2303 } // namespace v8 |
OLD | NEW |