| 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 644 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 655 break; | 655 break; |
| 656 case wasm::kExprF64Neg: | 656 case wasm::kExprF64Neg: |
| 657 return BuildF64Neg(input); | 657 return BuildF64Neg(input); |
| 658 case wasm::kExprF64Sqrt: | 658 case wasm::kExprF64Sqrt: |
| 659 op = m->Float64Sqrt(); | 659 op = m->Float64Sqrt(); |
| 660 break; | 660 break; |
| 661 case wasm::kExprI32SConvertF64: | 661 case wasm::kExprI32SConvertF64: |
| 662 return BuildI32SConvertF64(input, position); | 662 return BuildI32SConvertF64(input, position); |
| 663 case wasm::kExprI32UConvertF64: | 663 case wasm::kExprI32UConvertF64: |
| 664 return BuildI32UConvertF64(input, position); | 664 return BuildI32UConvertF64(input, position); |
| 665 case wasm::kExprI32AsmjsSConvertF64: |
| 666 return BuildI32AsmjsSConvertF64(input); |
| 667 case wasm::kExprI32AsmjsUConvertF64: |
| 668 return BuildI32AsmjsUConvertF64(input); |
| 665 case wasm::kExprF32ConvertF64: | 669 case wasm::kExprF32ConvertF64: |
| 666 op = m->TruncateFloat64ToFloat32(); | 670 op = m->TruncateFloat64ToFloat32(); |
| 667 break; | 671 break; |
| 668 case wasm::kExprF64SConvertI32: | 672 case wasm::kExprF64SConvertI32: |
| 669 op = m->ChangeInt32ToFloat64(); | 673 op = m->ChangeInt32ToFloat64(); |
| 670 break; | 674 break; |
| 671 case wasm::kExprF64UConvertI32: | 675 case wasm::kExprF64UConvertI32: |
| 672 op = m->ChangeUint32ToFloat64(); | 676 op = m->ChangeUint32ToFloat64(); |
| 673 break; | 677 break; |
| 674 case wasm::kExprF32SConvertI32: | 678 case wasm::kExprF32SConvertI32: |
| 675 op = m->RoundInt32ToFloat32(); | 679 op = m->RoundInt32ToFloat32(); |
| 676 break; | 680 break; |
| 677 case wasm::kExprF32UConvertI32: | 681 case wasm::kExprF32UConvertI32: |
| 678 op = m->RoundUint32ToFloat32(); | 682 op = m->RoundUint32ToFloat32(); |
| 679 break; | 683 break; |
| 680 case wasm::kExprI32SConvertF32: | 684 case wasm::kExprI32SConvertF32: |
| 681 return BuildI32SConvertF32(input, position); | 685 return BuildI32SConvertF32(input, position); |
| 682 case wasm::kExprI32UConvertF32: | 686 case wasm::kExprI32UConvertF32: |
| 683 return BuildI32UConvertF32(input, position); | 687 return BuildI32UConvertF32(input, position); |
| 688 case wasm::kExprI32AsmjsSConvertF32: |
| 689 return BuildI32AsmjsSConvertF32(input); |
| 690 case wasm::kExprI32AsmjsUConvertF32: |
| 691 return BuildI32AsmjsUConvertF32(input); |
| 684 case wasm::kExprF64ConvertF32: | 692 case wasm::kExprF64ConvertF32: |
| 685 op = m->ChangeFloat32ToFloat64(); | 693 op = m->ChangeFloat32ToFloat64(); |
| 686 break; | 694 break; |
| 687 case wasm::kExprF32ReinterpretI32: | 695 case wasm::kExprF32ReinterpretI32: |
| 688 op = m->BitcastInt32ToFloat32(); | 696 op = m->BitcastInt32ToFloat32(); |
| 689 break; | 697 break; |
| 690 case wasm::kExprI32ReinterpretF32: | 698 case wasm::kExprI32ReinterpretF32: |
| 691 op = m->BitcastFloat32ToInt32(); | 699 op = m->BitcastFloat32ToInt32(); |
| 692 break; | 700 break; |
| 693 case wasm::kExprI32Clz: | 701 case wasm::kExprI32Clz: |
| (...skipping 428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1122 wasm::kAstF64, right, | 1130 wasm::kAstF64, right, |
| 1123 left_is_not_nan.Phi( | 1131 left_is_not_nan.Phi( |
| 1124 wasm::kAstF64, | 1132 wasm::kAstF64, |
| 1125 Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), | 1133 Binop(wasm::kExprF64Mul, right, Float64Constant(1.0)), |
| 1126 Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); | 1134 Binop(wasm::kExprF64Mul, left, Float64Constant(1.0))))); |
| 1127 } | 1135 } |
| 1128 | 1136 |
| 1129 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input, | 1137 Node* WasmGraphBuilder::BuildI32SConvertF32(Node* input, |
| 1130 wasm::WasmCodePosition position) { | 1138 wasm::WasmCodePosition position) { |
| 1131 MachineOperatorBuilder* m = jsgraph()->machine(); | 1139 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1132 if (module_ && module_->asm_js()) { | |
| 1133 // asm.js must use the wacky JS semantics. | |
| 1134 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); | |
| 1135 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); | |
| 1136 } | |
| 1137 | |
| 1138 // Truncation of the input value is needed for the overflow check later. | 1140 // Truncation of the input value is needed for the overflow check later. |
| 1139 Node* trunc = Unop(wasm::kExprF32Trunc, input); | 1141 Node* trunc = Unop(wasm::kExprF32Trunc, input); |
| 1140 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); | 1142 Node* result = graph()->NewNode(m->TruncateFloat32ToInt32(), trunc); |
| 1141 | 1143 |
| 1142 // Convert the result back to f64. If we end up at a different value than the | 1144 // Convert the result back to f64. If we end up at a different value than the |
| 1143 // truncated input value, then there has been an overflow and we trap. | 1145 // truncated input value, then there has been an overflow and we trap. |
| 1144 Node* check = Unop(wasm::kExprF32SConvertI32, result); | 1146 Node* check = Unop(wasm::kExprF32SConvertI32, result); |
| 1145 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 1147 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); |
| 1146 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); | 1148 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1147 | 1149 |
| 1148 return result; | 1150 return result; |
| 1149 } | 1151 } |
| 1150 | 1152 |
| 1151 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input, | 1153 Node* WasmGraphBuilder::BuildI32SConvertF64(Node* input, |
| 1152 wasm::WasmCodePosition position) { | 1154 wasm::WasmCodePosition position) { |
| 1153 MachineOperatorBuilder* m = jsgraph()->machine(); | 1155 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1154 if (module_ && module_->asm_js()) { | |
| 1155 // asm.js must use the wacky JS semantics. | |
| 1156 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); | |
| 1157 } | |
| 1158 // Truncation of the input value is needed for the overflow check later. | 1156 // Truncation of the input value is needed for the overflow check later. |
| 1159 Node* trunc = Unop(wasm::kExprF64Trunc, input); | 1157 Node* trunc = Unop(wasm::kExprF64Trunc, input); |
| 1160 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); | 1158 Node* result = graph()->NewNode(m->ChangeFloat64ToInt32(), trunc); |
| 1161 | 1159 |
| 1162 // Convert the result back to f64. If we end up at a different value than the | 1160 // Convert the result back to f64. If we end up at a different value than the |
| 1163 // truncated input value, then there has been an overflow and we trap. | 1161 // truncated input value, then there has been an overflow and we trap. |
| 1164 Node* check = Unop(wasm::kExprF64SConvertI32, result); | 1162 Node* check = Unop(wasm::kExprF64SConvertI32, result); |
| 1165 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); | 1163 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); |
| 1166 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); | 1164 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1167 | 1165 |
| 1168 return result; | 1166 return result; |
| 1169 } | 1167 } |
| 1170 | 1168 |
| 1171 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input, | 1169 Node* WasmGraphBuilder::BuildI32UConvertF32(Node* input, |
| 1172 wasm::WasmCodePosition position) { | 1170 wasm::WasmCodePosition position) { |
| 1173 MachineOperatorBuilder* m = jsgraph()->machine(); | 1171 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1174 if (module_ && module_->asm_js()) { | |
| 1175 // asm.js must use the wacky JS semantics. | |
| 1176 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); | |
| 1177 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); | |
| 1178 } | |
| 1179 | |
| 1180 // Truncation of the input value is needed for the overflow check later. | 1172 // Truncation of the input value is needed for the overflow check later. |
| 1181 Node* trunc = Unop(wasm::kExprF32Trunc, input); | 1173 Node* trunc = Unop(wasm::kExprF32Trunc, input); |
| 1182 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); | 1174 Node* result = graph()->NewNode(m->TruncateFloat32ToUint32(), trunc); |
| 1183 | 1175 |
| 1184 // Convert the result back to f32. If we end up at a different value than the | 1176 // Convert the result back to f32. If we end up at a different value than the |
| 1185 // truncated input value, then there has been an overflow and we trap. | 1177 // truncated input value, then there has been an overflow and we trap. |
| 1186 Node* check = Unop(wasm::kExprF32UConvertI32, result); | 1178 Node* check = Unop(wasm::kExprF32UConvertI32, result); |
| 1187 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); | 1179 Node* overflow = Binop(wasm::kExprF32Ne, trunc, check); |
| 1188 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); | 1180 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1189 | 1181 |
| 1190 return result; | 1182 return result; |
| 1191 } | 1183 } |
| 1192 | 1184 |
| 1193 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input, | 1185 Node* WasmGraphBuilder::BuildI32UConvertF64(Node* input, |
| 1194 wasm::WasmCodePosition position) { | 1186 wasm::WasmCodePosition position) { |
| 1195 MachineOperatorBuilder* m = jsgraph()->machine(); | 1187 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1196 if (module_ && module_->asm_js()) { | |
| 1197 // asm.js must use the wacky JS semantics. | |
| 1198 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); | |
| 1199 } | |
| 1200 // Truncation of the input value is needed for the overflow check later. | 1188 // Truncation of the input value is needed for the overflow check later. |
| 1201 Node* trunc = Unop(wasm::kExprF64Trunc, input); | 1189 Node* trunc = Unop(wasm::kExprF64Trunc, input); |
| 1202 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc); | 1190 Node* result = graph()->NewNode(m->TruncateFloat64ToUint32(), trunc); |
| 1203 | 1191 |
| 1204 // Convert the result back to f64. If we end up at a different value than the | 1192 // Convert the result back to f64. If we end up at a different value than the |
| 1205 // truncated input value, then there has been an overflow and we trap. | 1193 // truncated input value, then there has been an overflow and we trap. |
| 1206 Node* check = Unop(wasm::kExprF64UConvertI32, result); | 1194 Node* check = Unop(wasm::kExprF64UConvertI32, result); |
| 1207 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); | 1195 Node* overflow = Binop(wasm::kExprF64Ne, trunc, check); |
| 1208 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); | 1196 trap_->AddTrapIfTrue(wasm::kTrapFloatUnrepresentable, overflow, position); |
| 1209 | 1197 |
| 1210 return result; | 1198 return result; |
| 1211 } | 1199 } |
| 1212 | 1200 |
| 1201 Node* WasmGraphBuilder::BuildI32AsmjsSConvertF32(Node* input) { |
| 1202 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1203 // asm.js must use the wacky JS semantics. |
| 1204 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); |
| 1205 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1206 } |
| 1207 |
| 1208 Node* WasmGraphBuilder::BuildI32AsmjsSConvertF64(Node* input) { |
| 1209 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1210 // asm.js must use the wacky JS semantics. |
| 1211 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1212 } |
| 1213 |
| 1214 Node* WasmGraphBuilder::BuildI32AsmjsUConvertF32(Node* input) { |
| 1215 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1216 // asm.js must use the wacky JS semantics. |
| 1217 input = graph()->NewNode(m->ChangeFloat32ToFloat64(), input); |
| 1218 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1219 } |
| 1220 |
| 1221 Node* WasmGraphBuilder::BuildI32AsmjsUConvertF64(Node* input) { |
| 1222 MachineOperatorBuilder* m = jsgraph()->machine(); |
| 1223 // asm.js must use the wacky JS semantics. |
| 1224 return graph()->NewNode(m->TruncateFloat64ToWord32(), input); |
| 1225 } |
| 1226 |
| 1213 Node* WasmGraphBuilder::BuildBitCountingCall(Node* input, ExternalReference ref, | 1227 Node* WasmGraphBuilder::BuildBitCountingCall(Node* input, ExternalReference ref, |
| 1214 MachineRepresentation input_type) { | 1228 MachineRepresentation input_type) { |
| 1215 Node* stack_slot_param = | 1229 Node* stack_slot_param = |
| 1216 graph()->NewNode(jsgraph()->machine()->StackSlot(input_type)); | 1230 graph()->NewNode(jsgraph()->machine()->StackSlot(input_type)); |
| 1217 | 1231 |
| 1218 const Operator* store_op = jsgraph()->machine()->Store( | 1232 const Operator* store_op = jsgraph()->machine()->Store( |
| 1219 StoreRepresentation(input_type, kNoWriteBarrier)); | 1233 StoreRepresentation(input_type, kNoWriteBarrier)); |
| 1220 *effect_ = | 1234 *effect_ = |
| 1221 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), | 1235 graph()->NewNode(store_op, stack_slot_param, jsgraph()->Int32Constant(0), |
| 1222 input, *effect_, *control_); | 1236 input, *effect_, *control_); |
| (...skipping 1871 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3094 const wasm::WasmFunction* function) { | 3108 const wasm::WasmFunction* function) { |
| 3095 WasmCompilationUnit* unit = | 3109 WasmCompilationUnit* unit = |
| 3096 CreateWasmCompilationUnit(thrower, isolate, module_env, function, 0); | 3110 CreateWasmCompilationUnit(thrower, isolate, module_env, function, 0); |
| 3097 ExecuteCompilation(unit); | 3111 ExecuteCompilation(unit); |
| 3098 return FinishCompilation(unit); | 3112 return FinishCompilation(unit); |
| 3099 } | 3113 } |
| 3100 | 3114 |
| 3101 } // namespace compiler | 3115 } // namespace compiler |
| 3102 } // namespace internal | 3116 } // namespace internal |
| 3103 } // namespace v8 | 3117 } // namespace v8 |
| OLD | NEW |