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 |