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 1035 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1046 return node; | 1046 return node; |
1047 break; | 1047 break; |
1048 default: | 1048 default: |
1049 UNREACHABLE(); | 1049 UNREACHABLE(); |
1050 break; | 1050 break; |
1051 } | 1051 } |
1052 | 1052 |
1053 int i; | 1053 int i; |
1054 uint32_t shiftCount; | 1054 uint32_t shiftCount; |
1055 | 1055 |
1056 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2; | 1056 if (jsgraph()->machine()->ReverseBytesSupported( |
1057 i += 8, shiftCount -= 16) { | 1057 valueSizeInBytes < 4 ? 4 : valueSizeInBytes)) { |
1058 Node* shiftLower; | 1058 switch (valueSizeInBytes) { |
1059 Node* shiftHigher; | 1059 case 1: |
1060 Node* lowerByte; | 1060 break; |
1061 Node* higherByte; | 1061 case 2: |
1062 result = | |
1063 graph()->NewNode(m->Word32ReverseBytes().op(), | |
ahaas
2016/07/28 14:12:59
Why do you sometimes use jsgraph()->machine()->...
john.yan
2016/07/28 18:03:50
Acknowledged.
| |
1064 graph()->NewNode(shiftLeftOpcode, value, | |
1065 jsgraph()->Int32Constant(16))); | |
1066 break; | |
1067 case 4: | |
1068 result = graph()->NewNode( | |
1069 jsgraph()->machine()->Word32ReverseBytes().op(), value); | |
1070 break; | |
1071 case 8: | |
1072 result = graph()->NewNode( | |
1073 jsgraph()->machine()->Word64ReverseBytes().op(), value); | |
1074 break; | |
1075 default: | |
1076 UNREACHABLE(); | |
1077 } | |
1078 } else { | |
1079 for (i = 0, shiftCount = valueSizeInBits - 8; i < valueSizeInBits / 2; | |
1080 i += 8, shiftCount -= 16) { | |
1081 Node* shiftLower; | |
1082 Node* shiftHigher; | |
1083 Node* lowerByte; | |
1084 Node* higherByte; | |
1062 | 1085 |
1063 DCHECK(shiftCount > 0); | 1086 DCHECK(shiftCount > 0); |
1064 DCHECK((shiftCount + 8) % 16 == 0); | 1087 DCHECK((shiftCount + 8) % 16 == 0); |
1065 | 1088 |
1066 if (valueSizeInBits > 32) { | 1089 if (valueSizeInBits > 32) { |
1067 shiftLower = graph()->NewNode(shiftLeftOpcode, value, | 1090 shiftLower = graph()->NewNode(shiftLeftOpcode, value, |
1068 jsgraph()->Int64Constant(shiftCount)); | 1091 jsgraph()->Int64Constant(shiftCount)); |
1069 shiftHigher = graph()->NewNode(shiftRightOpcode, value, | 1092 shiftHigher = graph()->NewNode(shiftRightOpcode, value, |
1070 jsgraph()->Int64Constant(shiftCount)); | 1093 jsgraph()->Int64Constant(shiftCount)); |
1071 lowerByte = graph()->NewNode( | 1094 lowerByte = graph()->NewNode( |
1072 andOpcode, shiftLower, | 1095 andOpcode, shiftLower, |
1073 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) | 1096 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) |
1074 << (valueSizeInBits - 8 - i))); | 1097 << (valueSizeInBits - 8 - i))); |
1075 higherByte = graph()->NewNode( | 1098 higherByte = graph()->NewNode( |
1076 andOpcode, shiftHigher, | 1099 andOpcode, shiftHigher, |
1077 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); | 1100 jsgraph()->Int64Constant(static_cast<uint64_t>(0xFF) << i)); |
1078 } else { | 1101 } else { |
1079 shiftLower = graph()->NewNode(shiftLeftOpcode, value, | 1102 shiftLower = graph()->NewNode(shiftLeftOpcode, value, |
1080 jsgraph()->Int32Constant(shiftCount)); | 1103 jsgraph()->Int32Constant(shiftCount)); |
1081 shiftHigher = graph()->NewNode(shiftRightOpcode, value, | 1104 shiftHigher = graph()->NewNode(shiftRightOpcode, value, |
1082 jsgraph()->Int32Constant(shiftCount)); | 1105 jsgraph()->Int32Constant(shiftCount)); |
1083 lowerByte = graph()->NewNode( | 1106 lowerByte = graph()->NewNode( |
1084 andOpcode, shiftLower, | 1107 andOpcode, shiftLower, |
1085 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) | 1108 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) |
1086 << (valueSizeInBits - 8 - i))); | 1109 << (valueSizeInBits - 8 - i))); |
1087 higherByte = graph()->NewNode( | 1110 higherByte = graph()->NewNode( |
1088 andOpcode, shiftHigher, | 1111 andOpcode, shiftHigher, |
1089 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); | 1112 jsgraph()->Int32Constant(static_cast<uint32_t>(0xFF) << i)); |
1113 } | |
1114 | |
1115 result = graph()->NewNode(orOpcode, result, lowerByte); | |
1116 result = graph()->NewNode(orOpcode, result, higherByte); | |
1090 } | 1117 } |
1091 | |
1092 result = graph()->NewNode(orOpcode, result, lowerByte); | |
1093 result = graph()->NewNode(orOpcode, result, higherByte); | |
1094 } | 1118 } |
1095 | 1119 |
1096 if (isFloat) { | 1120 if (isFloat) { |
1097 switch (memtype.representation()) { | 1121 switch (memtype.representation()) { |
1098 case MachineRepresentation::kFloat64: | 1122 case MachineRepresentation::kFloat64: |
1099 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result); | 1123 result = graph()->NewNode(m->BitcastInt64ToFloat64(), result); |
1100 break; | 1124 break; |
1101 case MachineRepresentation::kFloat32: | 1125 case MachineRepresentation::kFloat32: |
1102 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result); | 1126 result = graph()->NewNode(m->BitcastInt32ToFloat32(), result); |
1103 break; | 1127 break; |
1104 default: | 1128 default: |
1105 UNREACHABLE(); | 1129 UNREACHABLE(); |
1106 break; | 1130 break; |
1107 } | 1131 } |
1108 } | 1132 } |
1109 | 1133 |
1110 // We need to sign extend the value | 1134 // We need to sign extend the value |
1111 if (memtype.IsSigned()) { | 1135 if (memtype.IsSigned()) { |
1112 DCHECK(!isFloat); | 1136 DCHECK(!isFloat); |
1113 if (valueSizeInBits < 32) { | 1137 if (valueSizeInBits < 32) { |
1114 Node* shiftBitCount; | 1138 Node* shiftBitCount; |
1115 // Perform sign extension using following trick | 1139 // Perform sign extension using following trick |
1116 // result = (x << machine_width - type_width) >> (machine_width - | 1140 // result = (x << machine_width - type_width) >> (machine_width - |
1117 // type_width) | 1141 // type_width) |
1118 if (wasmtype == wasm::kAstI64) { | 1142 if (wasmtype == wasm::kAstI64) { |
1119 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits); | 1143 shiftBitCount = jsgraph()->Int32Constant(64 - valueSizeInBits); |
1120 result = graph()->NewNode( | 1144 result = graph()->NewNode( |
1121 m->Word64Sar(), | 1145 m->Word64Sar(), |
1122 graph()->NewNode(m->Word64Shl(), result, shiftBitCount), | 1146 graph()->NewNode( |
1147 m->Word64Shl(), | |
1148 graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), | |
1149 result), | |
1150 shiftBitCount), | |
1123 shiftBitCount); | 1151 shiftBitCount); |
1124 } else if (wasmtype == wasm::kAstI32) { | 1152 } else if (wasmtype == wasm::kAstI32) { |
1125 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits); | 1153 shiftBitCount = jsgraph()->Int32Constant(32 - valueSizeInBits); |
1126 result = graph()->NewNode( | 1154 result = graph()->NewNode( |
1127 m->Word32Sar(), | 1155 m->Word32Sar(), |
1128 graph()->NewNode(m->Word32Shl(), result, shiftBitCount), | 1156 graph()->NewNode(m->Word32Shl(), result, shiftBitCount), |
1129 shiftBitCount); | 1157 shiftBitCount); |
1130 } | 1158 } |
1131 } | 1159 } |
1132 } | 1160 } |
(...skipping 1942 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3075 | 3103 |
3076 if (aligned || | 3104 if (aligned || |
3077 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { | 3105 jsgraph()->machine()->UnalignedLoadSupported(memtype, alignment)) { |
3078 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), | 3106 load = graph()->NewNode(jsgraph()->machine()->Load(memtype), |
3079 MemBuffer(offset), index, *effect_, *control_); | 3107 MemBuffer(offset), index, *effect_, *control_); |
3080 *effect_ = load; | 3108 *effect_ = load; |
3081 } else { | 3109 } else { |
3082 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); | 3110 load = BuildUnalignedLoad(type, memtype, index, offset, alignment); |
3083 } | 3111 } |
3084 #if defined(V8_TARGET_BIG_ENDIAN) | 3112 #if defined(V8_TARGET_BIG_ENDIAN) |
3085 // TODO(john.yan) Implement byte swap turbofan operator | |
3086 // and use it if available for better performance | |
3087 load = BuildChangeEndianness(load, memtype, type); | 3113 load = BuildChangeEndianness(load, memtype, type); |
3088 #endif | 3114 #endif |
3089 | 3115 |
3090 if (type == wasm::kAstI64 && | 3116 if (type == wasm::kAstI64 && |
3091 ElementSizeLog2Of(memtype.representation()) < 3) { | 3117 ElementSizeLog2Of(memtype.representation()) < 3) { |
3092 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. | 3118 // TODO(titzer): TF zeroes the upper bits of 64-bit loads for subword sizes. |
3093 if (memtype.IsSigned()) { | 3119 if (memtype.IsSigned()) { |
3094 // sign extend | 3120 // sign extend |
3095 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); | 3121 load = graph()->NewNode(jsgraph()->machine()->ChangeInt32ToInt64(), load); |
3096 } else { | 3122 } else { |
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3196 } | 3222 } |
3197 | 3223 |
3198 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, | 3224 Node* WasmGraphBuilder::StoreMem(MachineType memtype, Node* index, |
3199 uint32_t offset, uint32_t alignment, Node* val, | 3225 uint32_t offset, uint32_t alignment, Node* val, |
3200 wasm::WasmCodePosition position) { | 3226 wasm::WasmCodePosition position) { |
3201 Node* store; | 3227 Node* store; |
3202 | 3228 |
3203 // WASM semantics throw on OOB. Introduce explicit bounds check. | 3229 // WASM semantics throw on OOB. Introduce explicit bounds check. |
3204 BoundsCheckMem(memtype, index, offset, position); | 3230 BoundsCheckMem(memtype, index, offset, position); |
3205 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 3231 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
3232 | |
3206 bool aligned = static_cast<int>(alignment) >= | 3233 bool aligned = static_cast<int>(alignment) >= |
3207 ElementSizeLog2Of(memtype.representation()); | 3234 ElementSizeLog2Of(memtype.representation()); |
3208 | 3235 |
3209 #if defined(V8_TARGET_BIG_ENDIAN) | 3236 #if defined(V8_TARGET_BIG_ENDIAN) |
3210 // TODO(john.yan) Implement byte swap turbofan operator | |
3211 // and use it if available for better performance | |
3212 val = BuildChangeEndianness(val, memtype); | 3237 val = BuildChangeEndianness(val, memtype); |
3213 #endif | 3238 #endif |
3214 | 3239 |
3215 if (aligned || | 3240 if (aligned || |
3216 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { | 3241 jsgraph()->machine()->UnalignedStoreSupported(memtype, alignment)) { |
3217 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); | 3242 StoreRepresentation rep(memtype.representation(), kNoWriteBarrier); |
3218 store = | 3243 store = |
3219 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), | 3244 graph()->NewNode(jsgraph()->machine()->Store(rep), MemBuffer(offset), |
3220 index, val, *effect_, *control_); | 3245 index, val, *effect_, *control_); |
3221 *effect_ = store; | 3246 *effect_ = store; |
(...skipping 439 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3661 function_->code_start_offset), | 3686 function_->code_start_offset), |
3662 compile_ms); | 3687 compile_ms); |
3663 } | 3688 } |
3664 | 3689 |
3665 return code; | 3690 return code; |
3666 } | 3691 } |
3667 | 3692 |
3668 } // namespace compiler | 3693 } // namespace compiler |
3669 } // namespace internal | 3694 } // namespace internal |
3670 } // namespace v8 | 3695 } // namespace v8 |
OLD | NEW |