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

Side by Side Diff: src/x64/lithium-codegen-x64.cc

Issue 6366010: X64 Crankshaft: Added a bunch of operations. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge/build-x64
Patch Set: Address review comments. Created 9 years, 11 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 | Annotate | Revision Log
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.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 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 the V8 project authors. All rights reserved.
2 // Redistribution and use in source and binary forms, with or without 2 // Redistribution and use in source and binary forms, with or without
3 // modification, are permitted provided that the following conditions are 3 // modification, are permitted provided that the following conditions are
4 // met: 4 // met:
5 // 5 //
6 // * Redistributions of source code must retain the above copyright 6 // * Redistributions of source code must retain the above copyright
7 // notice, this list of conditions and the following disclaimer. 7 // notice, this list of conditions and the following disclaimer.
8 // * Redistributions in binary form must reproduce the above 8 // * Redistributions in binary form must reproduce the above
9 // copyright notice, this list of conditions and the following 9 // copyright notice, this list of conditions and the following
10 // disclaimer in the documentation and/or other materials provided 10 // disclaimer in the documentation and/or other materials provided
(...skipping 1142 matching lines...) Expand 10 before | Expand all | Expand 10 after
1153 } else { 1153 } else {
1154 EmitCmpI(left, right); 1154 EmitCmpI(left, right);
1155 } 1155 }
1156 1156
1157 Condition cc = TokenToCondition(instr->op(), instr->is_double()); 1157 Condition cc = TokenToCondition(instr->op(), instr->is_double());
1158 EmitBranch(true_block, false_block, cc); 1158 EmitBranch(true_block, false_block, cc);
1159 } 1159 }
1160 1160
1161 1161
1162 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) { 1162 void LCodeGen::DoCmpJSObjectEq(LCmpJSObjectEq* instr) {
1163 Abort("Unimplemented: %s", "DoCmpJSObjectEq"); 1163 Register left = ToRegister(instr->InputAt(0));
1164 Register right = ToRegister(instr->InputAt(1));
1165 Register result = ToRegister(instr->result());
1166
1167 NearLabel different, done;
1168 __ cmpq(left, right);
1169 __ j(not_equal, &different);
1170 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1171 __ jmp(&done);
1172 __ bind(&different);
1173 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1174 __ bind(&done);
1164 } 1175 }
1165 1176
1166 1177
1167 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) { 1178 void LCodeGen::DoCmpJSObjectEqAndBranch(LCmpJSObjectEqAndBranch* instr) {
1168 Register left = ToRegister(instr->InputAt(0)); 1179 Register left = ToRegister(instr->InputAt(0));
1169 Register right = ToRegister(instr->InputAt(1)); 1180 Register right = ToRegister(instr->InputAt(1));
1170 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1181 int false_block = chunk_->LookupDestination(instr->false_block_id());
1171 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1182 int true_block = chunk_->LookupDestination(instr->true_block_id());
1172 1183
1173 __ cmpq(left, right); 1184 __ cmpq(left, right);
1174 EmitBranch(true_block, false_block, equal); 1185 EmitBranch(true_block, false_block, equal);
1175 } 1186 }
1176 1187
1177 1188
1178 void LCodeGen::DoIsNull(LIsNull* instr) { 1189 void LCodeGen::DoIsNull(LIsNull* instr) {
1179 Abort("Unimplemented: %s", "DoIsNull"); 1190 Register reg = ToRegister(instr->InputAt(0));
1191 Register result = ToRegister(instr->result());
1192
1193 // If the expression is known to be a smi, then it's
1194 // definitely not null. Materialize false.
1195 // Consider adding other type and representation tests too.
1196 if (instr->hydrogen()->value()->type().IsSmi()) {
1197 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1198 return;
1199 }
1200
1201 __ CompareRoot(reg, Heap::kNullValueRootIndex);
1202 if (instr->is_strict()) {
1203 __ movl(result, Immediate(Heap::kTrueValueRootIndex));
1204 NearLabel load;
1205 __ j(equal, &load);
1206 __ movl(result, Immediate(Heap::kFalseValueRootIndex));
1207 __ bind(&load);
1208 __ movq(result, Operand(kRootRegister, result, times_pointer_size, 0));
1209 } else {
1210 NearLabel true_value, false_value, done;
1211 __ j(equal, &true_value);
1212 __ CompareRoot(reg, Heap::kUndefinedValueRootIndex);
1213 __ j(equal, &true_value);
1214 __ JumpIfSmi(reg, &false_value);
1215 // Check for undetectable objects by looking in the bit field in
1216 // the map. The object has already been smi checked.
1217 Register scratch = result;
1218 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1219 __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
1220 Immediate(1 << Map::kIsUndetectable));
1221 __ j(not_zero, &true_value);
1222 __ bind(&false_value);
1223 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1224 __ jmp(&done);
1225 __ bind(&true_value);
1226 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1227 __ bind(&done);
1228 }
1180 } 1229 }
1181 1230
1182 1231
1183 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) { 1232 void LCodeGen::DoIsNullAndBranch(LIsNullAndBranch* instr) {
1184 Register reg = ToRegister(instr->InputAt(0)); 1233 Register reg = ToRegister(instr->InputAt(0));
1185 1234
1186 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1235 int false_block = chunk_->LookupDestination(instr->false_block_id());
1187 1236
1188 if (instr->hydrogen()->representation().IsSpecialization() || 1237 if (instr->hydrogen()->representation().IsSpecialization() ||
1189 instr->hydrogen()->type().IsSmi()) { 1238 instr->hydrogen()->type().IsSmi()) {
(...skipping 21 matching lines...) Expand all
1211 Register scratch = ToRegister(instr->TempAt(0)); 1260 Register scratch = ToRegister(instr->TempAt(0));
1212 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset)); 1261 __ movq(scratch, FieldOperand(reg, HeapObject::kMapOffset));
1213 __ testb(FieldOperand(scratch, Map::kBitFieldOffset), 1262 __ testb(FieldOperand(scratch, Map::kBitFieldOffset),
1214 Immediate(1 << Map::kIsUndetectable)); 1263 Immediate(1 << Map::kIsUndetectable));
1215 EmitBranch(true_block, false_block, not_zero); 1264 EmitBranch(true_block, false_block, not_zero);
1216 } 1265 }
1217 } 1266 }
1218 1267
1219 1268
1220 Condition LCodeGen::EmitIsObject(Register input, 1269 Condition LCodeGen::EmitIsObject(Register input,
1221 Register temp1,
1222 Register temp2,
1223 Label* is_not_object, 1270 Label* is_not_object,
1224 Label* is_object) { 1271 Label* is_object) {
1225 ASSERT(!input.is(temp1)); 1272 ASSERT(!input.is(kScratchRegister));
1226 ASSERT(!input.is(temp2));
1227 ASSERT(!temp1.is(temp2));
1228 1273
1229 __ JumpIfSmi(input, is_not_object); 1274 __ JumpIfSmi(input, is_not_object);
1230 1275
1231 __ Cmp(input, Factory::null_value()); 1276 __ CompareRoot(input, Heap::kNullValueRootIndex);
1232 __ j(equal, is_object); 1277 __ j(equal, is_object);
1233 1278
1234 __ movq(temp1, FieldOperand(input, HeapObject::kMapOffset)); 1279 __ movq(kScratchRegister, FieldOperand(input, HeapObject::kMapOffset));
1235 // Undetectable objects behave like undefined. 1280 // Undetectable objects behave like undefined.
1236 __ testb(FieldOperand(temp1, Map::kBitFieldOffset), 1281 __ testb(FieldOperand(kScratchRegister, Map::kBitFieldOffset),
1237 Immediate(1 << Map::kIsUndetectable)); 1282 Immediate(1 << Map::kIsUndetectable));
1238 __ j(not_zero, is_not_object); 1283 __ j(not_zero, is_not_object);
1239 1284
1240 __ movzxbl(temp2, FieldOperand(temp1, Map::kInstanceTypeOffset)); 1285 __ movzxbl(kScratchRegister,
1241 __ cmpb(temp2, Immediate(FIRST_JS_OBJECT_TYPE)); 1286 FieldOperand(kScratchRegister, Map::kInstanceTypeOffset));
1287 __ cmpb(kScratchRegister, Immediate(FIRST_JS_OBJECT_TYPE));
1242 __ j(below, is_not_object); 1288 __ j(below, is_not_object);
1243 __ cmpb(temp2, Immediate(LAST_JS_OBJECT_TYPE)); 1289 __ cmpb(kScratchRegister, Immediate(LAST_JS_OBJECT_TYPE));
1244 return below_equal; 1290 return below_equal;
1245 } 1291 }
1246 1292
1247 1293
1248 void LCodeGen::DoIsObject(LIsObject* instr) { 1294 void LCodeGen::DoIsObject(LIsObject* instr) {
1249 Abort("Unimplemented: %s", "DoIsObject"); 1295 Register reg = ToRegister(instr->InputAt(0));
1296 Register result = ToRegister(instr->result());
1297 Label is_false, is_true, done;
1298
1299 Condition true_cond = EmitIsObject(reg, &is_false, &is_true);
1300 __ j(true_cond, &is_true);
1301
1302 __ bind(&is_false);
1303 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1304 __ jmp(&done);
1305
1306 __ bind(&is_true);
1307 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1308
1309 __ bind(&done);
1250 } 1310 }
1251 1311
1252 1312
1253 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) { 1313 void LCodeGen::DoIsObjectAndBranch(LIsObjectAndBranch* instr) {
1254 Register reg = ToRegister(instr->InputAt(0)); 1314 Register reg = ToRegister(instr->InputAt(0));
1255 Register temp = ToRegister(instr->TempAt(0));
1256 Register temp2 = ToRegister(instr->TempAt(1));
1257 1315
1258 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1316 int true_block = chunk_->LookupDestination(instr->true_block_id());
1259 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1317 int false_block = chunk_->LookupDestination(instr->false_block_id());
1260 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1318 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1261 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1319 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1262 1320
1263 Condition true_cond = EmitIsObject(reg, temp, temp2, false_label, true_label); 1321 Condition true_cond = EmitIsObject(reg, false_label, true_label);
1264 1322
1265 EmitBranch(true_block, false_block, true_cond); 1323 EmitBranch(true_block, false_block, true_cond);
1266 } 1324 }
1267 1325
1268 1326
1269 void LCodeGen::DoIsSmi(LIsSmi* instr) { 1327 void LCodeGen::DoIsSmi(LIsSmi* instr) {
1270 Abort("Unimplemented: %s", "DoIsSmi"); 1328 LOperand* input_operand = instr->InputAt(0);
1329 Register result = ToRegister(instr->result());
1330 if (input_operand->IsRegister()) {
1331 Register input = ToRegister(input_operand);
1332 __ CheckSmiToIndicator(result, input);
1333 } else {
1334 Operand input = ToOperand(instr->InputAt(0));
1335 __ CheckSmiToIndicator(result, input);
1336 }
1337 // result is zero if input is a smi, and one otherwise.
1338 ASSERT(Heap::kFalseValueRootIndex == Heap::kTrueValueRootIndex + 1);
1339 __ movq(result, Operand(kRootRegister, result, times_pointer_size,
1340 Heap::kTrueValueRootIndex * kPointerSize));
1271 } 1341 }
1272 1342
1273 1343
1274 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) { 1344 void LCodeGen::DoIsSmiAndBranch(LIsSmiAndBranch* instr) {
1275 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1345 int true_block = chunk_->LookupDestination(instr->true_block_id());
1276 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1346 int false_block = chunk_->LookupDestination(instr->false_block_id());
1277 1347
1278 Condition is_smi; 1348 Condition is_smi;
1279 if (instr->InputAt(0)->IsRegister()) { 1349 if (instr->InputAt(0)->IsRegister()) {
1280 Register input = ToRegister(instr->InputAt(0)); 1350 Register input = ToRegister(instr->InputAt(0));
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1393 // classes and it doesn't have to because you can't access it with natives 1463 // classes and it doesn't have to because you can't access it with natives
1394 // syntax. Since both sides are symbols it is sufficient to use an identity 1464 // syntax. Since both sides are symbols it is sufficient to use an identity
1395 // comparison. 1465 // comparison.
1396 ASSERT(class_name->IsSymbol()); 1466 ASSERT(class_name->IsSymbol());
1397 __ Cmp(temp, class_name); 1467 __ Cmp(temp, class_name);
1398 // End with the answer in the z flag. 1468 // End with the answer in the z flag.
1399 } 1469 }
1400 1470
1401 1471
1402 void LCodeGen::DoClassOfTest(LClassOfTest* instr) { 1472 void LCodeGen::DoClassOfTest(LClassOfTest* instr) {
1403 Abort("Unimplemented: %s", "DoClassOfTest"); 1473 Register input = ToRegister(instr->InputAt(0));
1474 Register result = ToRegister(instr->result());
1475 ASSERT(input.is(result));
1476 Register temp = ToRegister(instr->TempAt(0));
1477 Handle<String> class_name = instr->hydrogen()->class_name();
1478 NearLabel done;
1479 Label is_true, is_false;
1480
1481 EmitClassOfTest(&is_true, &is_false, class_name, input, temp);
1482
1483 __ j(not_equal, &is_false);
1484
1485 __ bind(&is_true);
1486 __ LoadRoot(result, Heap::kTrueValueRootIndex);
1487 __ jmp(&done);
1488
1489 __ bind(&is_false);
1490 __ LoadRoot(result, Heap::kFalseValueRootIndex);
1491 __ bind(&done);
1404 } 1492 }
1405 1493
1406 1494
1407 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) { 1495 void LCodeGen::DoClassOfTestAndBranch(LClassOfTestAndBranch* instr) {
1408 Register input = ToRegister(instr->InputAt(0)); 1496 Register input = ToRegister(instr->InputAt(0));
1409 Register temp = ToRegister(instr->TempAt(0)); 1497 Register temp = ToRegister(instr->TempAt(0));
1410 Handle<String> class_name = instr->hydrogen()->class_name(); 1498 Handle<String> class_name = instr->hydrogen()->class_name();
1411 1499
1412 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1500 int true_block = chunk_->LookupDestination(instr->true_block_id());
1413 int false_block = chunk_->LookupDestination(instr->false_block_id()); 1501 int false_block = chunk_->LookupDestination(instr->false_block_id());
1414 1502
1415 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1503 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1416 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1504 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1417 1505
1418 EmitClassOfTest(true_label, false_label, class_name, input, temp); 1506 EmitClassOfTest(true_label, false_label, class_name, input, temp);
1419 1507
1420 EmitBranch(true_block, false_block, equal); 1508 EmitBranch(true_block, false_block, equal);
1421 } 1509 }
1422 1510
1423 1511
1424 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) { 1512 void LCodeGen::DoCmpMapAndBranch(LCmpMapAndBranch* instr) {
1425 Abort("Unimplemented: %s", "DoCmpMapAndBranch"); 1513 Register reg = ToRegister(instr->InputAt(0));
1514 int true_block = instr->true_block_id();
1515 int false_block = instr->false_block_id();
1516
1517 __ Cmp(FieldOperand(reg, HeapObject::kMapOffset), instr->map());
1518 EmitBranch(true_block, false_block, equal);
1426 } 1519 }
1427 1520
1428 1521
1429 void LCodeGen::DoInstanceOf(LInstanceOf* instr) { 1522 void LCodeGen::DoInstanceOf(LInstanceOf* instr) {
1430 Abort("Unimplemented: %s", "DoInstanceOf"); 1523 Abort("Unimplemented: %s", "DoInstanceOf");
1431 } 1524 }
1432 1525
1433 1526
1434 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) { 1527 void LCodeGen::DoInstanceOfAndBranch(LInstanceOfAndBranch* instr) {
1435 int true_block = chunk_->LookupDestination(instr->true_block_id()); 1528 int true_block = chunk_->LookupDestination(instr->true_block_id());
(...skipping 271 matching lines...) Expand 10 before | Expand all | Expand 10 after
1707 Abort("Unimplemented: %s", "DoStoreKeyedFastElement"); 1800 Abort("Unimplemented: %s", "DoStoreKeyedFastElement");
1708 } 1801 }
1709 1802
1710 1803
1711 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 1804 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
1712 Abort("Unimplemented: %s", "DoStoreKeyedGeneric"); 1805 Abort("Unimplemented: %s", "DoStoreKeyedGeneric");
1713 } 1806 }
1714 1807
1715 1808
1716 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 1809 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
1717 Abort("Unimplemented: %s", "DoInteger32ToDouble"); 1810 LOperand* input = instr->InputAt(0);
1811 ASSERT(input->IsRegister() || input->IsStackSlot());
1812 LOperand* output = instr->result();
1813 ASSERT(output->IsDoubleRegister());
1814 __ cvtlsi2sd(ToDoubleRegister(output), ToOperand(input));
1718 } 1815 }
1719 1816
1720 1817
1721 void LCodeGen::DoNumberTagI(LNumberTagI* instr) { 1818 void LCodeGen::DoNumberTagI(LNumberTagI* instr) {
1722 Abort("Unimplemented: %s", "DoNumberTagI"); 1819 LOperand* input = instr->InputAt(0);
1723 } 1820 ASSERT(input->IsRegister() && input->Equals(instr->result()));
1821 Register reg = ToRegister(input);
1724 1822
1725 1823 __ Integer32ToSmi(reg, reg);
1726 void LCodeGen::DoDeferredNumberTagI(LNumberTagI* instr) {
1727 Abort("Unimplemented: %s", "DoDeferredNumberTagI");
1728 } 1824 }
1729 1825
1730 1826
1731 void LCodeGen::DoNumberTagD(LNumberTagD* instr) { 1827 void LCodeGen::DoNumberTagD(LNumberTagD* instr) {
1732 Abort("Unimplemented: %s", "DoNumberTagD"); 1828 class DeferredNumberTagD: public LDeferredCode {
1829 public:
1830 DeferredNumberTagD(LCodeGen* codegen, LNumberTagD* instr)
1831 : LDeferredCode(codegen), instr_(instr) { }
1832 virtual void Generate() { codegen()->DoDeferredNumberTagD(instr_); }
1833 private:
1834 LNumberTagD* instr_;
1835 };
1836
1837 XMMRegister input_reg = ToDoubleRegister(instr->InputAt(0));
1838 Register reg = ToRegister(instr->result());
1839 Register tmp = ToRegister(instr->TempAt(0));
1840
1841 DeferredNumberTagD* deferred = new DeferredNumberTagD(this, instr);
1842 if (FLAG_inline_new) {
1843 __ AllocateHeapNumber(reg, tmp, deferred->entry());
1844 } else {
1845 __ jmp(deferred->entry());
1846 }
1847 __ bind(deferred->exit());
1848 __ movsd(FieldOperand(reg, HeapNumber::kValueOffset), input_reg);
1733 } 1849 }
1734 1850
1735 1851
1736 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) { 1852 void LCodeGen::DoDeferredNumberTagD(LNumberTagD* instr) {
1737 Abort("Unimplemented: %s", "DoDeferredNumberTagD"); 1853 // TODO(3095996): Get rid of this. For now, we need to make the
1854 // result register contain a valid pointer because it is already
1855 // contained in the register pointer map.
1856 Register reg = ToRegister(instr->result());
1857 __ Move(reg, Smi::FromInt(0));
1858
1859 __ PushSafepointRegisters();
1860 __ CallRuntimeSaveDoubles(Runtime::kAllocateHeapNumber);
1861 RecordSafepointWithRegisters(
1862 instr->pointer_map(), 0, Safepoint::kNoDeoptimizationIndex);
1863 // Ensure that value in rax survives popping registers.
1864 __ movq(kScratchRegister, rax);
1865 __ PopSafepointRegisters();
1866 __ movq(reg, kScratchRegister);
1738 } 1867 }
1739 1868
1740 1869
1741 void LCodeGen::DoSmiTag(LSmiTag* instr) { 1870 void LCodeGen::DoSmiTag(LSmiTag* instr) {
1742 Abort("Unimplemented: %s", "DoSmiTag"); 1871 Abort("Unimplemented: %s", "DoSmiTag");
1743 } 1872 }
1744 1873
1745 1874
1746 void LCodeGen::DoSmiUntag(LSmiUntag* instr) { 1875 void LCodeGen::DoSmiUntag(LSmiUntag* instr) {
1747 Abort("Unimplemented: %s", "DoSmiUntag"); 1876 Abort("Unimplemented: %s", "DoSmiUntag");
1748 } 1877 }
1749 1878
1750 1879
1751 void LCodeGen::EmitNumberUntagD(Register input_reg, 1880 void LCodeGen::EmitNumberUntagD(Register input_reg,
1752 XMMRegister result_reg, 1881 XMMRegister result_reg,
1753 LEnvironment* env) { 1882 LEnvironment* env) {
1754 Abort("Unimplemented: %s", "EmitNumberUntagD"); 1883 NearLabel load_smi, heap_number, done;
1884
1885 // Smi check.
1886 __ JumpIfSmi(input_reg, &load_smi);
1887
1888 // Heap number map check.
1889 __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
1890 Heap::kHeapNumberMapRootIndex);
1891 __ j(equal, &heap_number);
1892
1893 __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
1894 DeoptimizeIf(not_equal, env);
1895
1896 // Convert undefined to NaN. Compute NaN as 0/0.
1897 __ xorpd(result_reg, result_reg);
1898 __ divsd(result_reg, result_reg);
1899 __ jmp(&done);
1900
1901 // Heap number to XMM conversion.
1902 __ bind(&heap_number);
1903 __ movsd(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
1904 __ jmp(&done);
1905
1906 // Smi to XMM conversion
1907 __ bind(&load_smi);
1908 __ SmiToInteger32(kScratchRegister, input_reg); // Untag smi first.
1909 __ cvtlsi2sd(result_reg, kScratchRegister);
1910 __ bind(&done);
1755 } 1911 }
1756 1912
1757 1913
1758 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) { 1914 void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
1759 Abort("Unimplemented: %s", "DoDeferredTaggedToI"); 1915 Abort("Unimplemented: %s", "DoDeferredTaggedToI");
1760 } 1916 }
1761 1917
1762 1918
1763 void LCodeGen::DoTaggedToI(LTaggedToI* instr) { 1919 void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
1764 Abort("Unimplemented: %s", "DoTaggedToI"); 1920 Abort("Unimplemented: %s", "DoTaggedToI");
(...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after
1946 2102
1947 void LCodeGen::DoOsrEntry(LOsrEntry* instr) { 2103 void LCodeGen::DoOsrEntry(LOsrEntry* instr) {
1948 Abort("Unimplemented: %s", "DoOsrEntry"); 2104 Abort("Unimplemented: %s", "DoOsrEntry");
1949 } 2105 }
1950 2106
1951 #undef __ 2107 #undef __
1952 2108
1953 } } // namespace v8::internal 2109 } } // namespace v8::internal
1954 2110
1955 #endif // V8_TARGET_ARCH_X64 2111 #endif // V8_TARGET_ARCH_X64
OLDNEW
« no previous file with comments | « src/x64/lithium-codegen-x64.h ('k') | src/x64/lithium-x64.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698