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

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

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 4 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/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.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 1328 matching lines...) Expand 10 before | Expand all | Expand 10 after
1339 1339
1340 1340
1341 void LCodeGen::DoArithmeticT(LArithmeticT* instr) { 1341 void LCodeGen::DoArithmeticT(LArithmeticT* instr) {
1342 ASSERT(ToRegister(instr->context()).is(esi)); 1342 ASSERT(ToRegister(instr->context()).is(esi));
1343 ASSERT(ToRegister(instr->left()).is(edx)); 1343 ASSERT(ToRegister(instr->left()).is(edx));
1344 ASSERT(ToRegister(instr->right()).is(eax)); 1344 ASSERT(ToRegister(instr->right()).is(eax));
1345 ASSERT(ToRegister(instr->result()).is(eax)); 1345 ASSERT(ToRegister(instr->result()).is(eax));
1346 1346
1347 BinaryOpStub stub(instr->op(), NO_OVERWRITE); 1347 BinaryOpStub stub(instr->op(), NO_OVERWRITE);
1348 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr); 1348 CallCode(stub.GetCode(), RelocInfo::CODE_TARGET, instr);
1349 __ nop(); // Signals no inlined code.
1349 } 1350 }
1350 1351
1351 1352
1352 int LCodeGen::GetNextEmittedBlock(int block) { 1353 int LCodeGen::GetNextEmittedBlock(int block) {
1353 for (int i = block + 1; i < graph()->blocks()->length(); ++i) { 1354 for (int i = block + 1; i < graph()->blocks()->length(); ++i) {
1354 LLabel* label = chunk_->GetLabel(i); 1355 LLabel* label = chunk_->GetLabel(i);
1355 if (!label->HasReplacement()) return i; 1356 if (!label->HasReplacement()) return i;
1356 } 1357 }
1357 return -1; 1358 return -1;
1358 } 1359 }
(...skipping 27 matching lines...) Expand all
1386 __ test(reg, Operand(reg)); 1387 __ test(reg, Operand(reg));
1387 EmitBranch(true_block, false_block, not_zero); 1388 EmitBranch(true_block, false_block, not_zero);
1388 } else if (r.IsDouble()) { 1389 } else if (r.IsDouble()) {
1389 XMMRegister reg = ToDoubleRegister(instr->InputAt(0)); 1390 XMMRegister reg = ToDoubleRegister(instr->InputAt(0));
1390 __ xorps(xmm0, xmm0); 1391 __ xorps(xmm0, xmm0);
1391 __ ucomisd(reg, xmm0); 1392 __ ucomisd(reg, xmm0);
1392 EmitBranch(true_block, false_block, not_equal); 1393 EmitBranch(true_block, false_block, not_equal);
1393 } else { 1394 } else {
1394 ASSERT(r.IsTagged()); 1395 ASSERT(r.IsTagged());
1395 Register reg = ToRegister(instr->InputAt(0)); 1396 Register reg = ToRegister(instr->InputAt(0));
1396 if (instr->hydrogen()->value()->type().IsBoolean()) { 1397 HType type = instr->hydrogen()->value()->type();
1398 if (type.IsBoolean()) {
1397 __ cmp(reg, factory()->true_value()); 1399 __ cmp(reg, factory()->true_value());
1398 EmitBranch(true_block, false_block, equal); 1400 EmitBranch(true_block, false_block, equal);
1401 } else if (type.IsSmi()) {
1402 __ test(reg, Operand(reg));
1403 EmitBranch(true_block, false_block, not_equal);
1399 } else { 1404 } else {
1400 Label* true_label = chunk_->GetAssemblyLabel(true_block); 1405 Label* true_label = chunk_->GetAssemblyLabel(true_block);
1401 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1406 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1402 1407
1403 __ cmp(reg, factory()->undefined_value()); 1408 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1404 __ j(equal, false_label); 1409 // Avoid deopts in the case where we've never executed this path before.
1405 __ cmp(reg, factory()->true_value()); 1410 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
1406 __ j(equal, true_label);
1407 __ cmp(reg, factory()->false_value());
1408 __ j(equal, false_label);
1409 __ test(reg, Operand(reg));
1410 __ j(equal, false_label);
1411 __ JumpIfSmi(reg, true_label);
1412 1411
1413 // Test for double values. Zero is false. 1412 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
1414 Label call_stub; 1413 // undefined -> false.
1415 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1414 __ cmp(reg, factory()->undefined_value());
1416 factory()->heap_number_map()); 1415 __ j(equal, false_label);
1417 __ j(not_equal, &call_stub, Label::kNear); 1416 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1418 __ fldz(); 1417 // We've seen undefined for the first time -> deopt.
1419 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 1418 __ cmp(reg, factory()->undefined_value());
1420 __ FCmp(); 1419 DeoptimizeIf(equal, instr->environment());
1421 __ j(zero, false_label); 1420 }
1422 __ jmp(true_label);
1423 1421
1424 // The conversion stub doesn't cause garbage collections so it's 1422 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1425 // safe to not record a safepoint after the call. 1423 // true -> true.
1426 __ bind(&call_stub); 1424 __ cmp(reg, factory()->true_value());
1427 ToBooleanStub stub(eax); 1425 __ j(equal, true_label);
1428 __ pushad(); 1426 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1429 __ push(reg); 1427 // We've seen a boolean for the first time -> deopt.
1430 __ CallStub(&stub); 1428 __ cmp(reg, factory()->true_value());
1431 __ test(eax, Operand(eax)); 1429 DeoptimizeIf(equal, instr->environment());
1432 __ popad(); 1430 }
1433 EmitBranch(true_block, false_block, not_zero); 1431
1432 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1433 // false -> false.
1434 __ cmp(reg, factory()->false_value());
1435 __ j(equal, false_label);
1436 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1437 // We've seen a boolean for the first time -> deopt.
1438 __ cmp(reg, factory()->false_value());
1439 DeoptimizeIf(equal, instr->environment());
1440 }
1441
1442 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
1443 // 'null' -> false.
1444 __ cmp(reg, factory()->null_value());
1445 __ j(equal, false_label);
1446 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1447 // We've seen null for the first time -> deopt.
1448 __ cmp(reg, factory()->null_value());
1449 DeoptimizeIf(equal, instr->environment());
1450 }
1451
1452 if (expected.Contains(ToBooleanStub::SMI)) {
1453 // Smis: 0 -> false, all other -> true.
1454 __ test(reg, Operand(reg));
1455 __ j(equal, false_label);
1456 __ JumpIfSmi(reg, true_label);
1457 } else if (expected.NeedsMap()) {
1458 // If we need a map later and have a Smi -> deopt.
1459 __ test(reg, Immediate(kSmiTagMask));
1460 DeoptimizeIf(zero, instr->environment());
1461 }
1462
1463 Register map;
1464 if (expected.NeedsMap()) {
1465 map = ToRegister(instr->TempAt(0));
1466 ASSERT(!map.is(reg));
1467 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
1468 // Everything with a map could be undetectable, so check this now.
1469 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
1470 1 << Map::kIsUndetectable);
1471 // Undetectable -> false.
1472 __ j(not_zero, false_label);
1473 }
1474
1475 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
1476 // spec object -> true.
1477 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1478 __ j(above_equal, true_label);
1479 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1480 // We've seen a spec object for the first time -> deopt.
1481 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1482 DeoptimizeIf(above_equal, instr->environment());
1483 }
1484
1485 if (expected.Contains(ToBooleanStub::STRING)) {
1486 // String value -> false iff empty.
1487 Label not_string;
1488 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1489 __ j(above_equal, &not_string, Label::kNear);
1490 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
1491 __ j(not_zero, true_label);
1492 __ jmp(false_label);
1493 __ bind(&not_string);
1494 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1495 // We've seen a string for the first time -> deopt
1496 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1497 DeoptimizeIf(below, instr->environment());
1498 }
1499
1500 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
1501 // heap number -> false iff +0, -0, or NaN.
1502 Label not_heap_number;
1503 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1504 factory()->heap_number_map());
1505 __ j(not_equal, &not_heap_number, Label::kNear);
1506 __ fldz();
1507 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
1508 __ FCmp();
1509 __ j(zero, false_label);
1510 __ jmp(true_label);
1511 __ bind(&not_heap_number);
1512 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1513 // We've seen a heap number for the first time -> deopt.
1514 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1515 factory()->heap_number_map());
1516 DeoptimizeIf(equal, instr->environment());
1517 }
1518
1519 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1520 // internal objects -> true
1521 __ jmp(true_label);
1522 } else {
1523 // We've seen something for the first time -> deopt.
1524 DeoptimizeIf(no_condition, instr->environment());
1525 }
1434 } 1526 }
1435 } 1527 }
1436 } 1528 }
1437 1529
1438 1530
1439 void LCodeGen::EmitGoto(int block) { 1531 void LCodeGen::EmitGoto(int block) {
1440 block = chunk_->LookupDestination(block); 1532 block = chunk_->LookupDestination(block);
1441 int next_block = GetNextEmittedBlock(current_block_); 1533 int next_block = GetNextEmittedBlock(current_block_);
1442 if (block != next_block) { 1534 if (block != next_block) {
1443 __ jmp(chunk_->GetAssemblyLabel(block)); 1535 __ jmp(chunk_->GetAssemblyLabel(block));
(...skipping 793 matching lines...) Expand 10 before | Expand all | Expand 10 after
2237 FixedArray::kHeaderSize)); 2329 FixedArray::kHeaderSize));
2238 2330
2239 // Check for the hole value. 2331 // Check for the hole value.
2240 if (instr->hydrogen()->RequiresHoleCheck()) { 2332 if (instr->hydrogen()->RequiresHoleCheck()) {
2241 __ cmp(result, factory()->the_hole_value()); 2333 __ cmp(result, factory()->the_hole_value());
2242 DeoptimizeIf(equal, instr->environment()); 2334 DeoptimizeIf(equal, instr->environment());
2243 } 2335 }
2244 } 2336 }
2245 2337
2246 2338
2247 Operand LCodeGen::BuildExternalArrayOperand( 2339 void LCodeGen::DoLoadKeyedFastDoubleElement(
2340 LLoadKeyedFastDoubleElement* instr) {
2341 XMMRegister result = ToDoubleRegister(instr->result());
2342
2343 if (instr->hydrogen()->RequiresHoleCheck()) {
2344 int offset = FixedDoubleArray::kHeaderSize - kHeapObjectTag +
2345 sizeof(kHoleNanLower32);
2346 Operand hole_check_operand = BuildFastArrayOperand(
2347 instr->elements(), instr->key(),
2348 JSObject::FAST_DOUBLE_ELEMENTS,
2349 offset);
2350 __ cmp(hole_check_operand, Immediate(kHoleNanUpper32));
2351 DeoptimizeIf(equal, instr->environment());
2352 }
2353
2354 Operand double_load_operand = BuildFastArrayOperand(
2355 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
2356 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2357 __ movdbl(result, double_load_operand);
2358 }
2359
2360
2361 Operand LCodeGen::BuildFastArrayOperand(
2248 LOperand* external_pointer, 2362 LOperand* external_pointer,
2249 LOperand* key, 2363 LOperand* key,
2250 JSObject::ElementsKind elements_kind) { 2364 JSObject::ElementsKind elements_kind,
2365 uint32_t offset) {
2251 Register external_pointer_reg = ToRegister(external_pointer); 2366 Register external_pointer_reg = ToRegister(external_pointer);
2252 int shift_size = ElementsKindToShiftSize(elements_kind); 2367 int shift_size = ElementsKindToShiftSize(elements_kind);
2253 if (key->IsConstantOperand()) { 2368 if (key->IsConstantOperand()) {
2254 int constant_value = ToInteger32(LConstantOperand::cast(key)); 2369 int constant_value = ToInteger32(LConstantOperand::cast(key));
2255 if (constant_value & 0xF0000000) { 2370 if (constant_value & 0xF0000000) {
2256 Abort("array index constant value too big"); 2371 Abort("array index constant value too big");
2257 } 2372 }
2258 return Operand(external_pointer_reg, constant_value * (1 << shift_size)); 2373 return Operand(external_pointer_reg,
2374 constant_value * (1 << shift_size) + offset);
2259 } else { 2375 } else {
2260 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 2376 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2261 return Operand(external_pointer_reg, ToRegister(key), scale_factor, 0); 2377 return Operand(external_pointer_reg, ToRegister(key), scale_factor, offset);
2262 } 2378 }
2263 } 2379 }
2264 2380
2265 2381
2266 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2382 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2267 LLoadKeyedSpecializedArrayElement* instr) { 2383 LLoadKeyedSpecializedArrayElement* instr) {
2268 JSObject::ElementsKind elements_kind = instr->elements_kind(); 2384 JSObject::ElementsKind elements_kind = instr->elements_kind();
2269 Operand operand(BuildExternalArrayOperand(instr->external_pointer(), 2385 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
2270 instr->key(), elements_kind)); 2386 instr->key(), elements_kind, 0));
2271 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { 2387 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
2272 XMMRegister result(ToDoubleRegister(instr->result())); 2388 XMMRegister result(ToDoubleRegister(instr->result()));
2273 __ movss(result, operand); 2389 __ movss(result, operand);
2274 __ cvtss2sd(result, result); 2390 __ cvtss2sd(result, result);
2275 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { 2391 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
2276 __ movdbl(ToDoubleRegister(instr->result()), operand); 2392 __ movdbl(ToDoubleRegister(instr->result()), operand);
2277 } else { 2393 } else {
2278 Register result(ToRegister(instr->result())); 2394 Register result(ToRegister(instr->result()));
2279 switch (elements_kind) { 2395 switch (elements_kind) {
2280 case JSObject::EXTERNAL_BYTE_ELEMENTS: 2396 case JSObject::EXTERNAL_BYTE_ELEMENTS:
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
2797 2913
2798 2914
2799 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) { 2915 void LCodeGen::DoMathLog(LUnaryMathOperation* instr) {
2800 ASSERT(instr->value()->Equals(instr->result())); 2916 ASSERT(instr->value()->Equals(instr->result()));
2801 XMMRegister input_reg = ToDoubleRegister(instr->value()); 2917 XMMRegister input_reg = ToDoubleRegister(instr->value());
2802 Label positive, done, zero; 2918 Label positive, done, zero;
2803 __ xorps(xmm0, xmm0); 2919 __ xorps(xmm0, xmm0);
2804 __ ucomisd(input_reg, xmm0); 2920 __ ucomisd(input_reg, xmm0);
2805 __ j(above, &positive, Label::kNear); 2921 __ j(above, &positive, Label::kNear);
2806 __ j(equal, &zero, Label::kNear); 2922 __ j(equal, &zero, Label::kNear);
2807 ExternalReference nan = ExternalReference::address_of_nan(); 2923 ExternalReference nan =
2924 ExternalReference::address_of_canonical_non_hole_nan();
2808 __ movdbl(input_reg, Operand::StaticVariable(nan)); 2925 __ movdbl(input_reg, Operand::StaticVariable(nan));
2809 __ jmp(&done, Label::kNear); 2926 __ jmp(&done, Label::kNear);
2810 __ bind(&zero); 2927 __ bind(&zero);
2811 __ push(Immediate(0xFFF00000)); 2928 __ push(Immediate(0xFFF00000));
2812 __ push(Immediate(0)); 2929 __ push(Immediate(0));
2813 __ movdbl(input_reg, Operand(esp, 0)); 2930 __ movdbl(input_reg, Operand(esp, 0));
2814 __ add(Operand(esp), Immediate(kDoubleSize)); 2931 __ add(Operand(esp), Immediate(kDoubleSize));
2815 __ jmp(&done, Label::kNear); 2932 __ jmp(&done, Label::kNear);
2816 __ bind(&positive); 2933 __ bind(&positive);
2817 __ fldln2(); 2934 __ fldln2();
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
3007 3124
3008 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 3125 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
3009 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 3126 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
3010 DeoptimizeIf(above_equal, instr->environment()); 3127 DeoptimizeIf(above_equal, instr->environment());
3011 } 3128 }
3012 3129
3013 3130
3014 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3131 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3015 LStoreKeyedSpecializedArrayElement* instr) { 3132 LStoreKeyedSpecializedArrayElement* instr) {
3016 JSObject::ElementsKind elements_kind = instr->elements_kind(); 3133 JSObject::ElementsKind elements_kind = instr->elements_kind();
3017 Operand operand(BuildExternalArrayOperand(instr->external_pointer(), 3134 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
3018 instr->key(), elements_kind)); 3135 instr->key(), elements_kind, 0));
3019 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { 3136 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3020 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 3137 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
3021 __ movss(operand, xmm0); 3138 __ movss(operand, xmm0);
3022 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) { 3139 } else if (elements_kind == JSObject::EXTERNAL_DOUBLE_ELEMENTS) {
3023 __ movdbl(operand, ToDoubleRegister(instr->value())); 3140 __ movdbl(operand, ToDoubleRegister(instr->value()));
3024 } else { 3141 } else {
3025 Register value = ToRegister(instr->value()); 3142 Register value = ToRegister(instr->value());
3026 switch (elements_kind) { 3143 switch (elements_kind) {
3027 case JSObject::EXTERNAL_PIXEL_ELEMENTS: 3144 case JSObject::EXTERNAL_PIXEL_ELEMENTS:
3028 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS: 3145 case JSObject::EXTERNAL_UNSIGNED_BYTE_ELEMENTS:
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after
3075 __ lea(key, 3192 __ lea(key,
3076 FieldOperand(elements, 3193 FieldOperand(elements,
3077 key, 3194 key,
3078 times_pointer_size, 3195 times_pointer_size,
3079 FixedArray::kHeaderSize)); 3196 FixedArray::kHeaderSize));
3080 __ RecordWrite(elements, key, value, kSaveFPRegs); 3197 __ RecordWrite(elements, key, value, kSaveFPRegs);
3081 } 3198 }
3082 } 3199 }
3083 3200
3084 3201
3202 void LCodeGen::DoStoreKeyedFastDoubleElement(
3203 LStoreKeyedFastDoubleElement* instr) {
3204 XMMRegister value = ToDoubleRegister(instr->value());
3205 Register key = instr->key()->IsRegister() ? ToRegister(instr->key()) : no_reg;
3206 Label have_value;
3207
3208 __ ucomisd(value, value);
3209 __ j(parity_odd, &have_value); // NaN.
3210
3211 ExternalReference canonical_nan_reference =
3212 ExternalReference::address_of_canonical_non_hole_nan();
3213 __ movdbl(value, Operand::StaticVariable(canonical_nan_reference));
3214 __ bind(&have_value);
3215
3216 Operand double_store_operand = BuildFastArrayOperand(
3217 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
3218 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
3219 __ movdbl(double_store_operand, value);
3220 }
3221
3222
3085 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) { 3223 void LCodeGen::DoStoreKeyedGeneric(LStoreKeyedGeneric* instr) {
3086 ASSERT(ToRegister(instr->context()).is(esi)); 3224 ASSERT(ToRegister(instr->context()).is(esi));
3087 ASSERT(ToRegister(instr->object()).is(edx)); 3225 ASSERT(ToRegister(instr->object()).is(edx));
3088 ASSERT(ToRegister(instr->key()).is(ecx)); 3226 ASSERT(ToRegister(instr->key()).is(ecx));
3089 ASSERT(ToRegister(instr->value()).is(eax)); 3227 ASSERT(ToRegister(instr->value()).is(eax));
3090 3228
3091 Handle<Code> ic = instr->strict_mode() 3229 Handle<Code> ic = instr->strict_mode()
3092 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict() 3230 ? isolate()->builtins()->KeyedStoreIC_Initialize_Strict()
3093 : isolate()->builtins()->KeyedStoreIC_Initialize(); 3231 : isolate()->builtins()->KeyedStoreIC_Initialize();
3094 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3232 CallCode(ic, RelocInfo::CODE_TARGET, instr);
(...skipping 363 matching lines...) Expand 10 before | Expand all | Expand 10 after
3458 if (deoptimize_on_undefined) { 3596 if (deoptimize_on_undefined) {
3459 DeoptimizeIf(not_equal, env); 3597 DeoptimizeIf(not_equal, env);
3460 } else { 3598 } else {
3461 Label heap_number; 3599 Label heap_number;
3462 __ j(equal, &heap_number, Label::kNear); 3600 __ j(equal, &heap_number, Label::kNear);
3463 3601
3464 __ cmp(input_reg, factory()->undefined_value()); 3602 __ cmp(input_reg, factory()->undefined_value());
3465 DeoptimizeIf(not_equal, env); 3603 DeoptimizeIf(not_equal, env);
3466 3604
3467 // Convert undefined to NaN. 3605 // Convert undefined to NaN.
3468 ExternalReference nan = ExternalReference::address_of_nan(); 3606 ExternalReference nan =
3607 ExternalReference::address_of_canonical_non_hole_nan();
3469 __ movdbl(result_reg, Operand::StaticVariable(nan)); 3608 __ movdbl(result_reg, Operand::StaticVariable(nan));
3470 __ jmp(&done, Label::kNear); 3609 __ jmp(&done, Label::kNear);
3471 3610
3472 __ bind(&heap_number); 3611 __ bind(&heap_number);
3473 } 3612 }
3474 // Heap number to XMM conversion. 3613 // Heap number to XMM conversion.
3475 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset)); 3614 __ movdbl(result_reg, FieldOperand(input_reg, HeapNumber::kValueOffset));
3476 __ jmp(&done, Label::kNear); 3615 __ jmp(&done, Label::kNear);
3477 3616
3478 // Smi to XMM conversion 3617 // Smi to XMM conversion
(...skipping 796 matching lines...) Expand 10 before | Expand all | Expand 10 after
4275 env->deoptimization_index()); 4414 env->deoptimization_index());
4276 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4415 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4277 } 4416 }
4278 4417
4279 4418
4280 #undef __ 4419 #undef __
4281 4420
4282 } } // namespace v8::internal 4421 } } // namespace v8::internal
4283 4422
4284 #endif // V8_TARGET_ARCH_IA32 4423 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/lithium-codegen-ia32.h ('k') | src/ia32/lithium-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698