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

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

Issue 1865293003: [stubs] Introduce DivideStub. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Updated: make sure labels are bound. Created 4 years, 8 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-stubs.h ('k') | src/compiler/code-stub-assembler.h » ('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 1151 matching lines...) Expand 10 before | Expand all | Expand 10 after
1162 1162
1163 assembler->Bind(&do_fmul); 1163 assembler->Bind(&do_fmul);
1164 { 1164 {
1165 Node* value = 1165 Node* value =
1166 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value()); 1166 assembler->Float64Mul(var_lhs_float64.value(), var_rhs_float64.value());
1167 Node* result = assembler->ChangeFloat64ToTagged(value); 1167 Node* result = assembler->ChangeFloat64ToTagged(value);
1168 assembler->Return(result); 1168 assembler->Return(result);
1169 } 1169 }
1170 } 1170 }
1171 1171
1172 void DivideStub::GenerateAssembly(
1173 compiler::CodeStubAssembler* assembler) const {
1174 using compiler::Node;
1175 typedef compiler::CodeStubAssembler::Label Label;
1176 typedef compiler::CodeStubAssembler::Variable Variable;
1177
1178 Node* context = assembler->Parameter(2);
1179
1180 // Shared entry point for floating point division.
1181 Label do_fdiv(assembler);
1182 Variable var_dividend_float64(assembler, MachineRepresentation::kFloat64),
1183 var_divisor_float64(assembler, MachineRepresentation::kFloat64);
1184
1185 Node* number_map = assembler->HeapNumberMapConstant();
1186
1187 // We might need to loop one or two times due to ToNumber conversions.
1188 Variable var_dividend(assembler, MachineRepresentation::kTagged),
1189 var_divisor(assembler, MachineRepresentation::kTagged);
1190 Variable* loop_variables[] = {&var_dividend, &var_divisor};
1191 Label loop(assembler, 2, loop_variables);
1192 var_dividend.Bind(assembler->Parameter(0));
1193 var_divisor.Bind(assembler->Parameter(1));
1194 assembler->Goto(&loop);
1195 assembler->Bind(&loop);
1196 {
1197 Node* dividend = var_dividend.value();
1198 Node* divisor = var_divisor.value();
1199
1200 Label dividend_is_smi(assembler), dividend_is_not_smi(assembler);
1201 assembler->Branch(assembler->WordIsSmi(dividend), &dividend_is_smi,
1202 &dividend_is_not_smi);
1203
1204 assembler->Bind(&dividend_is_smi);
1205 {
1206 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
1207 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
1208 &divisor_is_not_smi);
1209
1210 assembler->Bind(&divisor_is_smi);
1211 {
1212 Label bailout(assembler);
1213
1214 // Do floating point division if {divisor} is zero.
1215 assembler->GotoIf(
1216 assembler->Word32Equal(divisor, assembler->Int32Constant(0)),
1217 &bailout);
1218
1219 // Do floating point division {dividend} is zero and {divisor} is
1220 // negative.
1221 Label dividend_is_zero(assembler), dividend_is_not_zero(assembler);
1222 assembler->Branch(
1223 assembler->WordNotEqual(dividend, assembler->IntPtrConstant(0)),
1224 &dividend_is_zero, &dividend_is_not_zero);
1225
1226 assembler->Bind(&dividend_is_zero);
1227 {
1228 assembler->GotoIf(
1229 assembler->IntPtrLessThan(divisor, assembler->IntPtrConstant(0)),
1230 &bailout);
1231 assembler->Goto(&dividend_is_not_zero);
1232 }
1233 assembler->Bind(&dividend_is_not_zero);
1234
1235 Node* untagged_divisor = assembler->WordSar(
1236 divisor, assembler->IntPtrConstant(kSmiTagSize + kSmiShiftSize));
1237
1238 // Do floating point division if {dividend} is kMinInt and {divisor} is
1239 // -1
1240 Label divisor_is_minus_one(assembler),
1241 divisor_is_not_minus_one(assembler);
1242 assembler->Branch(assembler->Word32Equal(untagged_divisor,
1243 assembler->Int32Constant(-1)),
1244 &divisor_is_minus_one, &divisor_is_not_minus_one);
1245
1246 assembler->Bind(&divisor_is_minus_one);
1247 {
1248 assembler->GotoIf(
1249 assembler->Word32Equal(assembler->SmiUntag(dividend),
1250 assembler->Int32Constant(kMinInt)),
1251 &bailout);
1252 assembler->Goto(&divisor_is_not_minus_one);
1253 }
1254 assembler->Bind(&divisor_is_not_minus_one);
1255
1256 // TODO(epertoso): consider adding a machine instruction that returns
1257 // both the result and the remainder.
1258 Node* result = assembler->IntPtrDiv(dividend, untagged_divisor);
1259 Node* truncated = assembler->IntPtrMul(result, untagged_divisor);
1260 // Do floating point division if the remainder is not 0.
1261 assembler->GotoIf(assembler->WordNotEqual(dividend, truncated),
1262 &bailout);
1263 assembler->Return(result);
1264
1265 // Bailout: convert {dividend} and {divisor} to double and do double
1266 // division.
1267 assembler->Bind(&bailout);
Benedikt Meurer 2016/04/08 04:25:03 Nit: Add { and } around the bailout code lines bel
epertoso 2016/04/08 08:25:17 Done.
1268 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
1269 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
1270 assembler->Goto(&do_fdiv);
1271 }
1272
1273 assembler->Bind(&divisor_is_not_smi);
1274 {
1275 Node* divisor_map = assembler->LoadMap(divisor);
1276
1277 // Check if {divisor} is a HeapNumber.
1278 Label divisor_is_number(assembler),
1279 divisor_is_not_number(assembler, Label::kDeferred);
1280 assembler->Branch(assembler->WordEqual(divisor_map, number_map),
1281 &divisor_is_number, &divisor_is_not_number);
1282
1283 assembler->Bind(&divisor_is_number);
1284 {
1285 // Convert {dividend} to a double and divide it with the value of
1286 // {divisor}.
1287 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
1288 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
1289 assembler->Goto(&do_fdiv);
1290 }
1291
1292 assembler->Bind(&divisor_is_not_number);
1293 {
1294 // Convert {divisor} to a number and loop.
1295 Callable callable = CodeFactory::NonNumberToNumber(isolate());
1296 var_divisor.Bind(assembler->CallStub(callable, context, divisor));
1297 assembler->Goto(&loop);
1298 }
1299 }
1300 }
1301
1302 assembler->Bind(&dividend_is_not_smi);
1303 {
1304 Node* dividend_map = assembler->LoadMap(dividend);
1305
1306 // Check if {dividend} is a HeapNumber.
1307 Label dividend_is_number(assembler),
1308 dividend_is_not_number(assembler, Label::kDeferred);
1309 assembler->Branch(assembler->WordEqual(dividend_map, number_map),
1310 &dividend_is_number, &dividend_is_not_number);
1311
1312 assembler->Bind(&dividend_is_number);
1313 {
1314 // Check if {divisor} is a Smi.
1315 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
1316 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
1317 &divisor_is_not_smi);
1318
1319 assembler->Bind(&divisor_is_smi);
1320 {
1321 // Convert {divisor} to a double and divide it with the value of
1322 // {dividend}.
1323 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
1324 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
1325 assembler->Goto(&do_fdiv);
1326 }
1327
1328 assembler->Bind(&divisor_is_not_smi);
1329 {
1330 Node* divisor_map = assembler->LoadMap(divisor);
1331
1332 // Check if {divisor} is a HeapNumber.
1333 Label divisor_is_number(assembler),
1334 divisor_is_not_number(assembler, Label::kDeferred);
1335 assembler->Branch(assembler->WordEqual(divisor_map, number_map),
1336 &divisor_is_number, &divisor_is_not_number);
1337
1338 assembler->Bind(&divisor_is_number);
1339 {
1340 // Both {dividend} and {divisor} are HeapNumbers. Load their values
1341 // and
1342 // divide them.
1343 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
1344 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
1345 assembler->Goto(&do_fdiv);
1346 }
1347
1348 assembler->Bind(&divisor_is_not_number);
1349 {
1350 // Convert {divisor} to a number and loop.
1351 Callable callable = CodeFactory::NonNumberToNumber(isolate());
1352 var_divisor.Bind(assembler->CallStub(callable, context, divisor));
1353 assembler->Goto(&loop);
1354 }
1355 }
1356 }
1357
1358 assembler->Bind(&dividend_is_not_number);
1359 {
1360 // Convert {dividend} to a Number and loop.
1361 Callable callable = CodeFactory::NonNumberToNumber(isolate());
1362 var_dividend.Bind(assembler->CallStub(callable, context, dividend));
1363 assembler->Goto(&loop);
1364 }
1365 }
1366 }
1367
1368 assembler->Bind(&do_fdiv);
1369 {
1370 Node* value = assembler->Float64Div(var_dividend_float64.value(),
1371 var_divisor_float64.value());
1372 Node* result = assembler->ChangeFloat64ToTagged(value);
1373 assembler->Return(result);
1374 }
1375 }
1376
1172 void BitwiseAndStub::GenerateAssembly( 1377 void BitwiseAndStub::GenerateAssembly(
1173 compiler::CodeStubAssembler* assembler) const { 1378 compiler::CodeStubAssembler* assembler) const {
1174 using compiler::Node; 1379 using compiler::Node;
1175 1380
1176 Node* lhs = assembler->Parameter(0); 1381 Node* lhs = assembler->Parameter(0);
1177 Node* rhs = assembler->Parameter(1); 1382 Node* rhs = assembler->Parameter(1);
1178 Node* context = assembler->Parameter(2); 1383 Node* context = assembler->Parameter(2);
1179 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); 1384 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs);
1180 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); 1385 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs);
1181 Node* value = assembler->Word32And(lhs_value, rhs_value); 1386 Node* value = assembler->Word32And(lhs_value, rhs_value);
(...skipping 2470 matching lines...) Expand 10 before | Expand all | Expand 10 after
3652 if (type->Is(Type::UntaggedPointer())) { 3857 if (type->Is(Type::UntaggedPointer())) {
3653 return Representation::External(); 3858 return Representation::External();
3654 } 3859 }
3655 3860
3656 DCHECK(!type->Is(Type::Untagged())); 3861 DCHECK(!type->Is(Type::Untagged()));
3657 return Representation::Tagged(); 3862 return Representation::Tagged();
3658 } 3863 }
3659 3864
3660 } // namespace internal 3865 } // namespace internal
3661 } // namespace v8 3866 } // namespace v8
OLDNEW
« no previous file with comments | « src/code-stubs.h ('k') | src/compiler/code-stub-assembler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698