OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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/code-stubs.h" | 5 #include "src/code-stubs.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #include "src/bootstrapper.h" | 9 #include "src/bootstrapper.h" |
10 #include "src/code-factory.h" | 10 #include "src/code-factory.h" |
(...skipping 1049 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1060 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, | 1060 compiler::Node* MultiplyStub::Generate(CodeStubAssembler* assembler, |
1061 compiler::Node* left, | 1061 compiler::Node* left, |
1062 compiler::Node* right, | 1062 compiler::Node* right, |
1063 compiler::Node* context) { | 1063 compiler::Node* context) { |
1064 using compiler::Node; | 1064 using compiler::Node; |
1065 typedef CodeStubAssembler::Label Label; | 1065 typedef CodeStubAssembler::Label Label; |
1066 typedef CodeStubAssembler::Variable Variable; | 1066 typedef CodeStubAssembler::Variable Variable; |
1067 | 1067 |
1068 // Shared entry point for floating point multiplication. | 1068 // Shared entry point for floating point multiplication. |
1069 Label do_fmul(assembler); | 1069 Label do_fmul(assembler); |
1070 Label end(assembler); | |
Benedikt Meurer
2016/07/12 04:09:28
Nit: Can you rename this to return_result and add
mvstanton
2016/07/12 08:52:49
Done.
| |
1070 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), | 1071 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), |
1071 var_rhs_float64(assembler, MachineRepresentation::kFloat64); | 1072 var_rhs_float64(assembler, MachineRepresentation::kFloat64); |
1072 | 1073 |
1073 Node* number_map = assembler->HeapNumberMapConstant(); | 1074 Node* number_map = assembler->HeapNumberMapConstant(); |
1074 | 1075 |
1075 // We might need to loop one or two times due to ToNumber conversions. | 1076 // We might need to loop one or two times due to ToNumber conversions. |
1076 Variable var_lhs(assembler, MachineRepresentation::kTagged), | 1077 Variable var_lhs(assembler, MachineRepresentation::kTagged), |
1077 var_rhs(assembler, MachineRepresentation::kTagged); | 1078 var_rhs(assembler, MachineRepresentation::kTagged), |
1079 var_result(assembler, MachineRepresentation::kTagged); | |
1078 Variable* loop_variables[] = {&var_lhs, &var_rhs}; | 1080 Variable* loop_variables[] = {&var_lhs, &var_rhs}; |
1079 Label loop(assembler, 2, loop_variables); | 1081 Label loop(assembler, 2, loop_variables); |
1080 var_lhs.Bind(left); | 1082 var_lhs.Bind(left); |
1081 var_rhs.Bind(right); | 1083 var_rhs.Bind(right); |
1082 assembler->Goto(&loop); | 1084 assembler->Goto(&loop); |
1083 assembler->Bind(&loop); | 1085 assembler->Bind(&loop); |
1084 { | 1086 { |
1085 Node* lhs = var_lhs.value(); | 1087 Node* lhs = var_lhs.value(); |
1086 Node* rhs = var_rhs.value(); | 1088 Node* rhs = var_rhs.value(); |
1087 | 1089 |
1088 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); | 1090 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); |
1089 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); | 1091 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); |
1090 | 1092 |
1091 assembler->Bind(&lhs_is_smi); | 1093 assembler->Bind(&lhs_is_smi); |
1092 { | 1094 { |
1093 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); | 1095 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); |
1094 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, | 1096 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, |
1095 &rhs_is_not_smi); | 1097 &rhs_is_not_smi); |
1096 | 1098 |
1097 assembler->Bind(&rhs_is_smi); | 1099 assembler->Bind(&rhs_is_smi); |
1098 { | 1100 { |
1099 // Both {lhs} and {rhs} are Smis. Convert them to double and multiply. | 1101 // Both {lhs} and {rhs} are Smis. Convert them to double and multiply. |
1100 // TODO(epertoso): use SmiMulWithOverflow once available. | 1102 // TODO(epertoso): use SmiMulWithOverflow once available. |
Benedikt Meurer
2016/07/12 04:09:28
Remove this TODO.
mvstanton
2016/07/12 08:52:49
Done.
| |
1103 Node* lhs32 = assembler->SmiToWord32(lhs); | |
1104 Node* rhs32 = assembler->SmiToWord32(rhs); | |
1105 Node* pair = assembler->Int32MulWithOverflow(lhs32, rhs32); | |
1106 | |
1107 Node* overflow = assembler->Projection(1, pair); | |
1108 | |
1109 // Check if the multiplication overflowed. | |
1110 Label if_overflow(assembler), if_notoverflow(assembler); | |
Benedikt Meurer
2016/07/12 04:09:28
Make the if_overflow label deferred.
mvstanton
2016/07/12 08:52:49
Done.
| |
1111 assembler->Branch(overflow, &if_overflow, &if_notoverflow); | |
1112 | |
1113 assembler->Bind(&if_notoverflow); | |
Benedikt Meurer
2016/07/12 04:09:28
Add braces around the actual blocks for improved r
mvstanton
2016/07/12 08:52:49
Done.
| |
1114 // If the answer is zero, we may need to return -0.0, depending on the | |
1115 // input. | |
1116 Label answer_zero(assembler), answer_not_zero(assembler); | |
1117 Node* answer = assembler->Projection(0, pair); | |
1118 Node* zero = assembler->Int32Constant(0); | |
1119 assembler->Branch(assembler->WordEqual(answer, zero), &answer_zero, | |
1120 &answer_not_zero); | |
1121 | |
1122 assembler->Bind(&answer_not_zero); | |
1123 var_result.Bind(assembler->ChangeInt32ToTagged(answer)); | |
1124 assembler->Goto(&end); | |
1125 | |
1126 assembler->Bind(&answer_zero); | |
1127 Node* or_result = assembler->Word32Or(lhs32, rhs32); | |
1128 Label if_should_be_negative_zero(assembler), | |
1129 if_should_be_zero(assembler); | |
1130 assembler->Branch(assembler->Int32LessThan(or_result, zero), | |
1131 &if_should_be_negative_zero, &if_should_be_zero); | |
1132 assembler->Bind(&if_should_be_negative_zero); | |
1133 var_result.Bind(assembler->MinusZeroConstant()); | |
1134 assembler->Goto(&end); | |
1135 | |
1136 assembler->Bind(&if_should_be_zero); | |
1137 var_result.Bind(zero); | |
1138 assembler->Goto(&end); | |
1139 | |
1140 assembler->Bind(&if_overflow); | |
1101 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); | 1141 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); |
1102 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); | 1142 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); |
1103 assembler->Goto(&do_fmul); | 1143 assembler->Goto(&do_fmul); |
1104 } | 1144 } |
1105 | 1145 |
1106 assembler->Bind(&rhs_is_not_smi); | 1146 assembler->Bind(&rhs_is_not_smi); |
1107 { | 1147 { |
1108 Node* rhs_map = assembler->LoadMap(rhs); | 1148 Node* rhs_map = assembler->LoadMap(rhs); |
1109 | 1149 |
1110 // Check if {rhs} is a HeapNumber. | 1150 // Check if {rhs} is a HeapNumber. |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1194 assembler->Goto(&loop); | 1234 assembler->Goto(&loop); |
1195 } | 1235 } |
1196 } | 1236 } |
1197 } | 1237 } |
1198 | 1238 |
1199 assembler->Bind(&do_fmul); | 1239 assembler->Bind(&do_fmul); |
1200 { | 1240 { |
1201 Node* value = | 1241 Node* value = |
1202 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); | 1242 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); |
1203 Node* result = assembler->ChangeFloat64ToTagged(value); | 1243 Node* result = assembler->ChangeFloat64ToTagged(value); |
1204 return result; | 1244 var_result.Bind(result); |
1245 assembler->Goto(&end); | |
1205 } | 1246 } |
1247 | |
1248 assembler->Bind(&end); | |
1249 return var_result.value(); | |
1206 } | 1250 } |
1207 | 1251 |
1208 // static | 1252 // static |
1209 compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler, | 1253 compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler, |
1210 compiler::Node* left, | 1254 compiler::Node* left, |
1211 compiler::Node* right, | 1255 compiler::Node* right, |
1212 compiler::Node* context) { | 1256 compiler::Node* context) { |
1213 using compiler::Node; | 1257 using compiler::Node; |
1214 typedef CodeStubAssembler::Label Label; | 1258 typedef CodeStubAssembler::Label Label; |
1215 typedef CodeStubAssembler::Variable Variable; | 1259 typedef CodeStubAssembler::Variable Variable; |
(...skipping 3714 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
4930 if (type->Is(Type::UntaggedPointer())) { | 4974 if (type->Is(Type::UntaggedPointer())) { |
4931 return Representation::External(); | 4975 return Representation::External(); |
4932 } | 4976 } |
4933 | 4977 |
4934 DCHECK(!type->Is(Type::Untagged())); | 4978 DCHECK(!type->Is(Type::Untagged())); |
4935 return Representation::Tagged(); | 4979 return Representation::Tagged(); |
4936 } | 4980 } |
4937 | 4981 |
4938 } // namespace internal | 4982 } // namespace internal |
4939 } // namespace v8 | 4983 } // namespace v8 |
OLD | NEW |