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 |