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

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: REBASE. 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
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 1048 matching lines...) Expand 10 before | Expand all | Expand 10 after
1059 // static 1059 // static
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), return_result(assembler);
1070 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64), 1070 Variable var_lhs_float64(assembler, MachineRepresentation::kFloat64),
1071 var_rhs_float64(assembler, MachineRepresentation::kFloat64); 1071 var_rhs_float64(assembler, MachineRepresentation::kFloat64);
1072 1072
1073 Node* number_map = assembler->HeapNumberMapConstant(); 1073 Node* number_map = assembler->HeapNumberMapConstant();
1074 1074
1075 // We might need to loop one or two times due to ToNumber conversions. 1075 // We might need to loop one or two times due to ToNumber conversions.
1076 Variable var_lhs(assembler, MachineRepresentation::kTagged), 1076 Variable var_lhs(assembler, MachineRepresentation::kTagged),
1077 var_rhs(assembler, MachineRepresentation::kTagged); 1077 var_rhs(assembler, MachineRepresentation::kTagged),
1078 var_result(assembler, MachineRepresentation::kTagged);
1078 Variable* loop_variables[] = {&var_lhs, &var_rhs}; 1079 Variable* loop_variables[] = {&var_lhs, &var_rhs};
1079 Label loop(assembler, 2, loop_variables); 1080 Label loop(assembler, 2, loop_variables);
1080 var_lhs.Bind(left); 1081 var_lhs.Bind(left);
1081 var_rhs.Bind(right); 1082 var_rhs.Bind(right);
1082 assembler->Goto(&loop); 1083 assembler->Goto(&loop);
1083 assembler->Bind(&loop); 1084 assembler->Bind(&loop);
1084 { 1085 {
1085 Node* lhs = var_lhs.value(); 1086 Node* lhs = var_lhs.value();
1086 Node* rhs = var_rhs.value(); 1087 Node* rhs = var_rhs.value();
1087 1088
1088 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler); 1089 Label lhs_is_smi(assembler), lhs_is_not_smi(assembler);
1089 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi); 1090 assembler->Branch(assembler->WordIsSmi(lhs), &lhs_is_smi, &lhs_is_not_smi);
1090 1091
1091 assembler->Bind(&lhs_is_smi); 1092 assembler->Bind(&lhs_is_smi);
1092 { 1093 {
1093 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler); 1094 Label rhs_is_smi(assembler), rhs_is_not_smi(assembler);
1094 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi, 1095 assembler->Branch(assembler->WordIsSmi(rhs), &rhs_is_smi,
1095 &rhs_is_not_smi); 1096 &rhs_is_not_smi);
1096 1097
1097 assembler->Bind(&rhs_is_smi); 1098 assembler->Bind(&rhs_is_smi);
1098 { 1099 {
1099 // Both {lhs} and {rhs} are Smis. Convert them to double and multiply. 1100 // Both {lhs} and {rhs} are Smis. Convert them to integers and multiply.
1100 // TODO(epertoso): use SmiMulWithOverflow once available. 1101 Node* lhs32 = assembler->SmiToWord32(lhs);
1101 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs)); 1102 Node* rhs32 = assembler->SmiToWord32(rhs);
1102 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs)); 1103 Node* pair = assembler->Int32MulWithOverflow(lhs32, rhs32);
1103 assembler->Goto(&do_fmul); 1104
1105 Node* overflow = assembler->Projection(1, pair);
1106
1107 // Check if the multiplication overflowed.
1108 Label if_overflow(assembler, Label::kDeferred),
1109 if_notoverflow(assembler);
1110 assembler->Branch(overflow, &if_overflow, &if_notoverflow);
1111 assembler->Bind(&if_notoverflow);
1112 {
1113 // If the answer is zero, we may need to return -0.0, depending on the
1114 // input.
1115 Label answer_zero(assembler), answer_not_zero(assembler);
1116 Node* answer = assembler->Projection(0, pair);
1117 Node* zero = assembler->Int32Constant(0);
1118 assembler->Branch(assembler->WordEqual(answer, zero), &answer_zero,
1119 &answer_not_zero);
1120 assembler->Bind(&answer_not_zero);
1121 {
1122 var_result.Bind(assembler->ChangeInt32ToTagged(answer));
1123 assembler->Goto(&return_result);
1124 }
1125 assembler->Bind(&answer_zero);
1126 {
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 {
1134 var_result.Bind(assembler->MinusZeroConstant());
1135 assembler->Goto(&return_result);
1136 }
1137 assembler->Bind(&if_should_be_zero);
1138 {
1139 var_result.Bind(zero);
1140 assembler->Goto(&return_result);
1141 }
1142 }
1143 }
1144 assembler->Bind(&if_overflow);
1145 {
1146 var_lhs_float64.Bind(assembler->SmiToFloat64(lhs));
1147 var_rhs_float64.Bind(assembler->SmiToFloat64(rhs));
1148 assembler->Goto(&do_fmul);
1149 }
1104 } 1150 }
1105 1151
1106 assembler->Bind(&rhs_is_not_smi); 1152 assembler->Bind(&rhs_is_not_smi);
1107 { 1153 {
1108 Node* rhs_map = assembler->LoadMap(rhs); 1154 Node* rhs_map = assembler->LoadMap(rhs);
1109 1155
1110 // Check if {rhs} is a HeapNumber. 1156 // Check if {rhs} is a HeapNumber.
1111 Label rhs_is_number(assembler), 1157 Label rhs_is_number(assembler),
1112 rhs_is_not_number(assembler, Label::kDeferred); 1158 rhs_is_not_number(assembler, Label::kDeferred);
1113 assembler->Branch(assembler->WordEqual(rhs_map, number_map), 1159 assembler->Branch(assembler->WordEqual(rhs_map, number_map),
(...skipping 80 matching lines...) Expand 10 before | Expand all | Expand 10 after
1194 assembler->Goto(&loop); 1240 assembler->Goto(&loop);
1195 } 1241 }
1196 } 1242 }
1197 } 1243 }
1198 1244
1199 assembler->Bind(&do_fmul); 1245 assembler->Bind(&do_fmul);
1200 { 1246 {
1201 Node* value = 1247 Node* value =
1202 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); 1248 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value());
1203 Node* result = assembler->ChangeFloat64ToTagged(value); 1249 Node* result = assembler->ChangeFloat64ToTagged(value);
1204 return result; 1250 var_result.Bind(result);
1251 assembler->Goto(&return_result);
1205 } 1252 }
1253
1254 assembler->Bind(&return_result);
1255 return var_result.value();
1206 } 1256 }
1207 1257
1208 // static 1258 // static
1209 compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler, 1259 compiler::Node* DivideStub::Generate(CodeStubAssembler* assembler,
1210 compiler::Node* left, 1260 compiler::Node* left,
1211 compiler::Node* right, 1261 compiler::Node* right,
1212 compiler::Node* context) { 1262 compiler::Node* context) {
1213 using compiler::Node; 1263 using compiler::Node;
1214 typedef CodeStubAssembler::Label Label; 1264 typedef CodeStubAssembler::Label Label;
1215 typedef CodeStubAssembler::Variable Variable; 1265 typedef CodeStubAssembler::Variable Variable;
(...skipping 3714 matching lines...) Expand 10 before | Expand all | Expand 10 after
4930 if (type->Is(Type::UntaggedPointer())) { 4980 if (type->Is(Type::UntaggedPointer())) {
4931 return Representation::External(); 4981 return Representation::External();
4932 } 4982 }
4933 4983
4934 DCHECK(!type->Is(Type::Untagged())); 4984 DCHECK(!type->Is(Type::Untagged()));
4935 return Representation::Tagged(); 4985 return Representation::Tagged();
4936 } 4986 }
4937 4987
4938 } // namespace internal 4988 } // namespace internal
4939 } // namespace v8 4989 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stub-assembler.h ('k') | src/compiler/arm/code-generator-arm.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698