Chromium Code Reviews| 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/compiler/wasm-compiler.h" | 5 #include "src/compiler/wasm-compiler.h" |
| 6 | 6 |
| 7 #include "src/isolate-inl.h" | 7 #include "src/isolate-inl.h" |
| 8 | 8 |
| 9 #include "src/base/platform/elapsed-timer.h" | 9 #include "src/base/platform/elapsed-timer.h" |
| 10 #include "src/base/platform/platform.h" | 10 #include "src/base/platform/platform.h" |
| (...skipping 974 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 985 int64_t masked = (match.Value() & kMask64); | 985 int64_t masked = (match.Value() & kMask64); |
| 986 if (match.Value() != masked) node = jsgraph()->Int64Constant(masked); | 986 if (match.Value() != masked) node = jsgraph()->Int64Constant(masked); |
| 987 } else { | 987 } else { |
| 988 node = graph()->NewNode(jsgraph()->machine()->Word64And(), node, | 988 node = graph()->NewNode(jsgraph()->machine()->Word64And(), node, |
| 989 jsgraph()->Int64Constant(kMask64)); | 989 jsgraph()->Int64Constant(kMask64)); |
| 990 } | 990 } |
| 991 } | 991 } |
| 992 return node; | 992 return node; |
| 993 } | 993 } |
| 994 | 994 |
| 995 Node* WasmGraphBuilder::BuildChangeEndianness(Node* node, MachineType memtype, | |
| 996 wasm::LocalType wasmtype) { | |
| 997 Node* result; | |
| 998 Node* value = node; | |
| 999 wasm::WasmOpcode shiftLeftOpcode; | |
| 1000 wasm::WasmOpcode shiftRightOpcode; | |
| 1001 wasm::WasmOpcode andOpcode, orOpcode; | |
| 1002 int valueSizeInBytes = 1 << ElementSizeLog2Of(memtype.representation()); | |
| 1003 int valueSizeInBits = 8 * valueSizeInBytes; | |
| 1004 bool isFloat = false; | |
| 1005 | |
| 1006 switch (memtype.representation()) { | |
| 1007 case MachineRepresentation::kFloat64: | |
| 1008 value = Unop(wasm::kExprI64ReinterpretF64, node); | |
| 1009 isFloat = true; | |
| 1010 case MachineRepresentation::kWord64: | |
| 1011 shiftLeftOpcode = wasm::kExprI64Shl; | |
| 1012 shiftRightOpcode = wasm::kExprI64ShrU; | |
| 1013 andOpcode = wasm::kExprI64And; | |
| 1014 orOpcode = wasm::kExprI64Ior; | |
| 1015 result = jsgraph()->Int64Constant(0); | |
| 1016 break; | |
| 1017 case MachineRepresentation::kFloat32: | |
| 1018 value = Unop(wasm::kExprI32ReinterpretF32, node); | |
| 1019 isFloat = true; | |
| 1020 case MachineRepresentation::kWord32: | |
| 1021 case MachineRepresentation::kWord16: | |
| 1022 shiftLeftOpcode = wasm::kExprI32Shl; | |
| 1023 shiftRightOpcode = wasm::kExprI32ShrU; | |
| 1024 andOpcode = wasm::kExprI32And; | |
| 1025 orOpcode = wasm::kExprI32Ior; | |
| 1026 result = jsgraph()->Int32Constant(0); | |
| 1027 break; | |
| 1028 case MachineRepresentation::kWord8: | |
| 1029 // No need to change endianness for byte size, return original node | |
| 1030 return node; | |
| 1031 break; | |
| 1032 default: | |
| 1033 UNREACHABLE(); | |
| 1034 break; | |
| 1035 } | |
| 1036 | |
| 1037 int i; | |
| 1038 uint32_t shiftCount; | |
| 1039 | |
| 1040 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2; | |
| 1041 i += 8, shiftCount -= 16) { | |
| 1042 DCHECK(shiftCount > 0); | |
| 1043 DCHECK((shiftCount + 8) % 16 == 0); | |
| 1044 | |
| 1045 Node* shiftLower = | |
| 1046 Binop(shiftLeftOpcode, value, jsgraph()->Int32Constant(shiftCount)); | |
|
titzer
2016/06/06 07:44:00
Reusing the Binop() routine is a little inefficien
| |
| 1047 Node* shiftHigher = | |
| 1048 Binop(shiftRightOpcode, value, jsgraph()->Int32Constant(shiftCount)); | |
| 1049 | |
| 1050 Node* lowerByte; | |
| 1051 Node* higherByte; | |
| 1052 | |
| 1053 if (valueSizeInBits > 32) { | |
| 1054 lowerByte = | |
| 1055 Binop(andOpcode, shiftLower, | |
| 1056 jsgraph()->Int64Constant(0xFFl << (valueSizeInBits - 8 - i))); | |
| 1057 higherByte = | |
| 1058 Binop(andOpcode, shiftHigher, jsgraph()->Int64Constant(0xFFl << i)); | |
| 1059 } else { | |
| 1060 lowerByte = | |
| 1061 Binop(andOpcode, shiftLower, | |
| 1062 jsgraph()->Int32Constant(0xFF << (valueSizeInBits - 8 - i))); | |
| 1063 higherByte = | |
| 1064 Binop(andOpcode, shiftHigher, jsgraph()->Int32Constant(0xFF << i)); | |
| 1065 } | |
| 1066 | |
| 1067 result = Binop(orOpcode, result, lowerByte); | |
| 1068 result = Binop(orOpcode, result, higherByte); | |
| 1069 } | |
| 1070 | |
| 1071 if (isFloat) { | |
| 1072 switch (memtype.representation()) { | |
| 1073 case MachineRepresentation::kFloat64: | |
| 1074 result = Unop(wasm::kExprF64ReinterpretI64, result); | |
| 1075 break; | |
| 1076 case MachineRepresentation::kFloat32: | |
| 1077 result = Unop(wasm::kExprF32ReinterpretI32, result); | |
| 1078 break; | |
| 1079 default: | |
| 1080 UNREACHABLE(); | |
| 1081 break; | |
| 1082 } | |
| 1083 } | |
| 1084 | |
| 1085 // We need to sign extend the value | |
| 1086 if (memtype.IsSigned()) { | |
| 1087 DCHECK(!isFloat); | |
| 1088 if ((wasmtype == wasm::kAstI64 || wasmtype == wasm::kAstI32) && | |
| 1089 valueSizeInBits < 32) { | |
| 1090 uint32_t mask = 1 << (valueSizeInBits - 1); | |
| 1091 | |
| 1092 Node* signBit = | |
| 1093 Binop(wasm::kExprI32And, result, jsgraph()->Int32Constant(mask)); | |
| 1094 Diamond d(graph(), jsgraph()->common(), Unop(wasm::kExprI32Eqz, signBit)); | |
|
titzer
2016/06/06 07:44:00
What about using (x << machine_width - width) >> (
| |
| 1095 | |
| 1096 result = | |
| 1097 d.Phi(MachineRepresentation::kWord32, result, | |
| 1098 Binop(wasm::kExprI32Ior, result, | |
| 1099 jsgraph()->Int32Constant(0xFFFFFFFF << valueSizeInBits))); | |
| 1100 } | |
| 1101 } | |
| 1102 | |
| 1103 return result; | |
| 1104 } | |
| 1105 | |
| 995 Node* WasmGraphBuilder::BuildF32Neg(Node* input) { | 1106 Node* WasmGraphBuilder::BuildF32Neg(Node* input) { |
| 996 Node* result = | 1107 Node* result = |
| 997 Unop(wasm::kExprF32ReinterpretI32, | 1108 Unop(wasm::kExprF32ReinterpretI32, |
| 998 Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input), | 1109 Binop(wasm::kExprI32Xor, Unop(wasm::kExprI32ReinterpretF32, input), |
| 999 jsgraph()->Int32Constant(0x80000000))); | 1110 jsgraph()->Int32Constant(0x80000000))); |
| 1000 | 1111 |
| 1001 return result; | 1112 return result; |
| 1002 } | 1113 } |
| 1003 | 1114 |
| 1004 Node* WasmGraphBuilder::BuildF64Neg(Node* input) { | 1115 Node* WasmGraphBuilder::BuildF64Neg(Node* input) { |
| (...skipping 1756 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2761 ElementSizeLog2Of(memtype.representation()); | 2872 ElementSizeLog2Of(memtype.representation()); |
| 2762 | 2873 |
| 2763 if (aligned || | 2874 if (aligned || |
| 2764 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { | 2875 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { |
| 2765 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 2876 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), |
| 2766 MemBuffer(offset), index, *effect_, *control_); | 2877 MemBuffer(offset), index, *effect_, *control_); |
| 2767 *effect_ = load; | 2878 *effect_ = load; |
| 2768 } else { | 2879 } else { |
| 2769 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); | 2880 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); |
| 2770 } | 2881 } |
| 2882 #if defined(V8_TARGET_BIG_ENDIAN) | |
| 2883 // TODO(mips-team) Implement byte swap turbofan operator | |
|
john.yan
2016/06/07 17:47:00
FYI: https://codereview.chromium.org/2045943002/
| |
| 2884 // and use it if available for better performance | |
| 2885 load = BuildChangeEndianness(load, memtype, type); | |
| 2886 #endif | |
| 2771 | 2887 |
| 2772 if (type == wasm::kAstI64 && | 2888 if (type == wasm::kAstI64 && |
| 2773 ElementSizeLog2Of(memtype.representation()) < 3) { | 2889 ElementSizeLog2Of(memtype.representation()) < 3) { |
| 2774 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. | 2890 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. |
| 2775 if (memtype.IsSigned()) { | 2891 if (memtype.IsSigned()) { |
| 2776 // sign extend | 2892 // sign extend |
| 2777 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); | 2893 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); |
| 2778 } else { | 2894 } else { |
| 2779 // zero extend | 2895 // zero extend |
| 2780 load = | 2896 load = |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 2881 uint32_t offset, uint32_t alignment, Node* val, | 2997 uint32_t offset, uint32_t alignment, Node* val, |
| 2882 wasm::WasmCodePosition position) { | 2998 wasm::WasmCodePosition position) { |
| 2883 Node* store; | 2999 Node* store; |
| 2884 | 3000 |
| 2885 // WASM semantics throw on OOB. Introduce explicit bounds check. | 3001 // WASM semantics throw on OOB. Introduce explicit bounds check. |
| 2886 BoundsCheckMem(memtype, index, offset, position); | 3002 BoundsCheckMem(memtype, index, offset, position); |
| 2887 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 3003 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
| 2888 bool aligned = static_cast<int>(alignment) >= | 3004 bool aligned = static_cast<int>(alignment) >= |
| 2889 ElementSizeLog2Of(memtype.representation()); | 3005 ElementSizeLog2Of(memtype.representation()); |
| 2890 | 3006 |
| 3007 #if defined(V8_TARGET_BIG_ENDIAN) | |
| 3008 // TODO(mips-team) Implement byte swap turbofan operator | |
| 3009 // and use it if available for better performance | |
| 3010 val = BuildChangeEndianness(val, memtype); | |
| 3011 #endif | |
| 3012 | |
| 2891 if (aligned || | 3013 if (aligned || |
| 2892 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { | 3014 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { |
| 2893 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 3015 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
| 2894 store = | 3016 store = |
| 2895 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), | 3017 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), |
| 2896 index, val, *effect_, *control_); | 3018 index, val, *effect_, *control_); |
| 2897 *effect_ = store; | 3019 *effect_ = store; |
| 2898 } else { | 3020 } else { |
| 2899 store = BuildUnalignedStore(memtype, index, offset, alignment, val); | 3021 store = BuildUnalignedStore(memtype, index, offset, alignment, val); |
| 2900 } | 3022 } |
| (...skipping 404 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 3305 function_->code_start_offset), | 3427 function_->code_start_offset), |
| 3306 compile_ms); | 3428 compile_ms); |
| 3307 } | 3429 } |
| 3308 | 3430 |
| 3309 return code; | 3431 return code; |
| 3310 } | 3432 } |
| 3311 | 3433 |
| 3312 } // namespace compiler | 3434 } // namespace compiler |
| 3313 } // namespace internal | 3435 } // namespace internal |
| 3314 } // namespace v8 | 3436 } // namespace v8 |
| OLD | NEW |