Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(387)

Side by Side Diff: src/code-stubs.cc

Issue 2101123005: [turbofan] Introduce integer multiplication with overflow. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix compile error. Created 4 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698