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

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: Taking the SMI size into account. 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->WordEqual(divisor, assembler->IntPtrConstant(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->WordEqual(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->SmiUntag(divisor);
1236 Node* untagged_dividend = assembler->SmiUntag(dividend);
1237
1238 // Do floating point division if {dividend} is kMinInt (or kMinInt - 1
1239 // if the Smi size is 31) and {divisor} is -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(
1250 untagged_dividend,
1251 assembler->Int32Constant(
1252 kSmiValueSize == 32 ? kMinInt : (kMinInt >> 1))),
1253 &bailout);
1254 assembler->Goto(&divisor_is_not_minus_one);
1255 }
1256 assembler->Bind(&divisor_is_not_minus_one);
1257
1258 // TODO(epertoso): consider adding a machine instruction that returns
1259 // both the result and the remainder.
1260 Node* untagged_result =
1261 assembler->Int32Div(untagged_dividend, untagged_divisor);
1262 Node* truncated =
1263 assembler->IntPtrMul(untagged_result, untagged_divisor);
1264 // Do floating point division if the remainder is not 0.
1265 assembler->GotoIf(
1266 assembler->Word32NotEqual(untagged_dividend, truncated), &bailout);
1267 assembler->Return(assembler->SmiTag(untagged_result));
1268
1269 // Bailout: convert {dividend} and {divisor} to double and do double
1270 // division.
1271 assembler->Bind(&bailout);
1272 {
1273 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
1274 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
1275 assembler->Goto(&do_fdiv);
1276 }
1277 }
1278
1279 assembler->Bind(&divisor_is_not_smi);
1280 {
1281 Node* divisor_map = assembler->LoadMap(divisor);
1282
1283 // Check if {divisor} is a HeapNumber.
1284 Label divisor_is_number(assembler),
1285 divisor_is_not_number(assembler, Label::kDeferred);
1286 assembler->Branch(assembler->WordEqual(divisor_map, number_map),
1287 &divisor_is_number, &divisor_is_not_number);
1288
1289 assembler->Bind(&divisor_is_number);
1290 {
1291 // Convert {dividend} to a double and divide it with the value of
1292 // {divisor}.
1293 var_dividend_float64.Bind(assembler->SmiToFloat64(dividend));
1294 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
1295 assembler->Goto(&do_fdiv);
1296 }
1297
1298 assembler->Bind(&divisor_is_not_number);
1299 {
1300 // Convert {divisor} to a number and loop.
1301 Callable callable = CodeFactory::NonNumberToNumber(isolate());
1302 var_divisor.Bind(assembler->CallStub(callable, context, divisor));
1303 assembler->Goto(&loop);
1304 }
1305 }
1306 }
1307
1308 assembler->Bind(&dividend_is_not_smi);
1309 {
1310 Node* dividend_map = assembler->LoadMap(dividend);
1311
1312 // Check if {dividend} is a HeapNumber.
1313 Label dividend_is_number(assembler),
1314 dividend_is_not_number(assembler, Label::kDeferred);
1315 assembler->Branch(assembler->WordEqual(dividend_map, number_map),
1316 &dividend_is_number, &dividend_is_not_number);
1317
1318 assembler->Bind(&dividend_is_number);
1319 {
1320 // Check if {divisor} is a Smi.
1321 Label divisor_is_smi(assembler), divisor_is_not_smi(assembler);
1322 assembler->Branch(assembler->WordIsSmi(divisor), &divisor_is_smi,
1323 &divisor_is_not_smi);
1324
1325 assembler->Bind(&divisor_is_smi);
1326 {
1327 // Convert {divisor} to a double and divide it with the value of
1328 // {dividend}.
1329 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
1330 var_divisor_float64.Bind(assembler->SmiToFloat64(divisor));
1331 assembler->Goto(&do_fdiv);
1332 }
1333
1334 assembler->Bind(&divisor_is_not_smi);
1335 {
1336 Node* divisor_map = assembler->LoadMap(divisor);
1337
1338 // Check if {divisor} is a HeapNumber.
1339 Label divisor_is_number(assembler),
1340 divisor_is_not_number(assembler, Label::kDeferred);
1341 assembler->Branch(assembler->WordEqual(divisor_map, number_map),
1342 &divisor_is_number, &divisor_is_not_number);
1343
1344 assembler->Bind(&divisor_is_number);
1345 {
1346 // Both {dividend} and {divisor} are HeapNumbers. Load their values
1347 // and
1348 // divide them.
1349 var_dividend_float64.Bind(assembler->LoadHeapNumberValue(dividend));
1350 var_divisor_float64.Bind(assembler->LoadHeapNumberValue(divisor));
1351 assembler->Goto(&do_fdiv);
1352 }
1353
1354 assembler->Bind(&divisor_is_not_number);
1355 {
1356 // Convert {divisor} to a number and loop.
1357 Callable callable = CodeFactory::NonNumberToNumber(isolate());
1358 var_divisor.Bind(assembler->CallStub(callable, context, divisor));
1359 assembler->Goto(&loop);
1360 }
1361 }
1362 }
1363
1364 assembler->Bind(&dividend_is_not_number);
1365 {
1366 // Convert {dividend} to a Number and loop.
1367 Callable callable = CodeFactory::NonNumberToNumber(isolate());
1368 var_dividend.Bind(assembler->CallStub(callable, context, dividend));
1369 assembler->Goto(&loop);
1370 }
1371 }
1372 }
1373
1374 assembler->Bind(&do_fdiv);
1375 {
1376 Node* value = assembler->Float64Div(var_dividend_float64.value(),
1377 var_divisor_float64.value());
1378 Node* result = assembler->ChangeFloat64ToTagged(value);
1379 assembler->Return(result);
1380 }
1381 }
1382
1172 void BitwiseAndStub::GenerateAssembly( 1383 void BitwiseAndStub::GenerateAssembly(
1173 compiler::CodeStubAssembler* assembler) const { 1384 compiler::CodeStubAssembler* assembler) const {
1174 using compiler::Node; 1385 using compiler::Node;
1175 1386
1176 Node* lhs = assembler->Parameter(0); 1387 Node* lhs = assembler->Parameter(0);
1177 Node* rhs = assembler->Parameter(1); 1388 Node* rhs = assembler->Parameter(1);
1178 Node* context = assembler->Parameter(2); 1389 Node* context = assembler->Parameter(2);
1179 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs); 1390 Node* lhs_value = assembler->TruncateTaggedToWord32(context, lhs);
1180 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs); 1391 Node* rhs_value = assembler->TruncateTaggedToWord32(context, rhs);
1181 Node* value = assembler->Word32And(lhs_value, rhs_value); 1392 Node* value = assembler->Word32And(lhs_value, rhs_value);
(...skipping 2538 matching lines...) Expand 10 before | Expand all | Expand 10 after
3720 if (type->Is(Type::UntaggedPointer())) { 3931 if (type->Is(Type::UntaggedPointer())) {
3721 return Representation::External(); 3932 return Representation::External();
3722 } 3933 }
3723 3934
3724 DCHECK(!type->Is(Type::Untagged())); 3935 DCHECK(!type->Is(Type::Untagged()));
3725 return Representation::Tagged(); 3936 return Representation::Tagged();
3726 } 3937 }
3727 3938
3728 } // namespace internal 3939 } // namespace internal
3729 } // namespace v8 3940 } // 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