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

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

Issue 7778013: NewGC: Merge bleeding edge up to 9009. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 3 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 1194 matching lines...) Expand 10 before | Expand all | Expand 10 after
1205 } 1205 }
1206 1206
1207 1207
1208 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) { 1208 void LCodeGen::DoJSArrayLength(LJSArrayLength* instr) {
1209 Register result = ToRegister(instr->result()); 1209 Register result = ToRegister(instr->result());
1210 Register array = ToRegister(instr->InputAt(0)); 1210 Register array = ToRegister(instr->InputAt(0));
1211 __ mov(result, FieldOperand(array, JSArray::kLengthOffset)); 1211 __ mov(result, FieldOperand(array, JSArray::kLengthOffset));
1212 } 1212 }
1213 1213
1214 1214
1215 void LCodeGen::DoFixedArrayLength(LFixedArrayLength* instr) { 1215 void LCodeGen::DoFixedArrayBaseLength(
1216 LFixedArrayBaseLength* instr) {
1216 Register result = ToRegister(instr->result()); 1217 Register result = ToRegister(instr->result());
1217 Register array = ToRegister(instr->InputAt(0)); 1218 Register array = ToRegister(instr->InputAt(0));
1218 __ mov(result, FieldOperand(array, FixedArray::kLengthOffset)); 1219 __ mov(result, FieldOperand(array, FixedArrayBase::kLengthOffset));
1219 }
1220
1221
1222 void LCodeGen::DoExternalArrayLength(LExternalArrayLength* instr) {
1223 Register result = ToRegister(instr->result());
1224 Register array = ToRegister(instr->InputAt(0));
1225 __ mov(result, FieldOperand(array, ExternalArray::kLengthOffset));
1226 } 1220 }
1227 1221
1228 1222
1229 void LCodeGen::DoElementsKind(LElementsKind* instr) { 1223 void LCodeGen::DoElementsKind(LElementsKind* instr) {
1230 Register result = ToRegister(instr->result()); 1224 Register result = ToRegister(instr->result());
1231 Register input = ToRegister(instr->InputAt(0)); 1225 Register input = ToRegister(instr->InputAt(0));
1232 1226
1233 // Load map into |result|. 1227 // Load map into |result|.
1234 __ mov(result, FieldOperand(input, HeapObject::kMapOffset)); 1228 __ mov(result, FieldOperand(input, HeapObject::kMapOffset));
1235 // Load the map's "bit field 2" into |result|. We only need the first byte, 1229 // Load the map's "bit field 2" into |result|. We only need the first byte,
(...skipping 170 matching lines...) Expand 10 before | Expand all | Expand 10 after
1406 Label* false_label = chunk_->GetAssemblyLabel(false_block); 1400 Label* false_label = chunk_->GetAssemblyLabel(false_block);
1407 1401
1408 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types(); 1402 ToBooleanStub::Types expected = instr->hydrogen()->expected_input_types();
1409 // Avoid deopts in the case where we've never executed this path before. 1403 // Avoid deopts in the case where we've never executed this path before.
1410 if (expected.IsEmpty()) expected = ToBooleanStub::all_types(); 1404 if (expected.IsEmpty()) expected = ToBooleanStub::all_types();
1411 1405
1412 if (expected.Contains(ToBooleanStub::UNDEFINED)) { 1406 if (expected.Contains(ToBooleanStub::UNDEFINED)) {
1413 // undefined -> false. 1407 // undefined -> false.
1414 __ cmp(reg, factory()->undefined_value()); 1408 __ cmp(reg, factory()->undefined_value());
1415 __ j(equal, false_label); 1409 __ j(equal, false_label);
1416 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1417 // We've seen undefined for the first time -> deopt.
1418 __ cmp(reg, factory()->undefined_value());
1419 DeoptimizeIf(equal, instr->environment());
1420 } 1410 }
1421
1422 if (expected.Contains(ToBooleanStub::BOOLEAN)) { 1411 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1423 // true -> true. 1412 // true -> true.
1424 __ cmp(reg, factory()->true_value()); 1413 __ cmp(reg, factory()->true_value());
1425 __ j(equal, true_label); 1414 __ j(equal, true_label);
1426 } else if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) {
1427 // We've seen a boolean for the first time -> deopt.
1428 __ cmp(reg, factory()->true_value());
1429 DeoptimizeIf(equal, instr->environment());
1430 }
1431
1432 if (expected.Contains(ToBooleanStub::BOOLEAN)) {
1433 // false -> false. 1415 // false -> false.
1434 __ cmp(reg, factory()->false_value()); 1416 __ cmp(reg, factory()->false_value());
1435 __ j(equal, false_label); 1417 __ 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 } 1418 }
1441
1442 if (expected.Contains(ToBooleanStub::NULL_TYPE)) { 1419 if (expected.Contains(ToBooleanStub::NULL_TYPE)) {
1443 // 'null' -> false. 1420 // 'null' -> false.
1444 __ cmp(reg, factory()->null_value()); 1421 __ cmp(reg, factory()->null_value());
1445 __ j(equal, false_label); 1422 __ 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 } 1423 }
1451 1424
1452 if (expected.Contains(ToBooleanStub::SMI)) { 1425 if (expected.Contains(ToBooleanStub::SMI)) {
1453 // Smis: 0 -> false, all other -> true. 1426 // Smis: 0 -> false, all other -> true.
1454 __ test(reg, Operand(reg)); 1427 __ test(reg, Operand(reg));
1455 __ j(equal, false_label); 1428 __ j(equal, false_label);
1456 __ JumpIfSmi(reg, true_label); 1429 __ JumpIfSmi(reg, true_label);
1457 } else if (expected.NeedsMap()) { 1430 } else if (expected.NeedsMap()) {
1458 // If we need a map later and have a Smi -> deopt. 1431 // If we need a map later and have a Smi -> deopt.
1459 __ test(reg, Immediate(kSmiTagMask)); 1432 __ test(reg, Immediate(kSmiTagMask));
1460 DeoptimizeIf(zero, instr->environment()); 1433 DeoptimizeIf(zero, instr->environment());
1461 } 1434 }
1462 1435
1463 Register map = no_reg; 1436 Register map = no_reg; // Keep the compiler happy.
1464 if (expected.NeedsMap()) { 1437 if (expected.NeedsMap()) {
1465 map = ToRegister(instr->TempAt(0)); 1438 map = ToRegister(instr->TempAt(0));
1466 ASSERT(!map.is(reg)); 1439 ASSERT(!map.is(reg));
1467 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset)); 1440 __ mov(map, FieldOperand(reg, HeapObject::kMapOffset));
1468 // Everything with a map could be undetectable, so check this now. 1441
1469 __ test_b(FieldOperand(map, Map::kBitFieldOffset), 1442 if (expected.CanBeUndetectable()) {
1470 1 << Map::kIsUndetectable); 1443 // Undetectable -> false.
1471 // Undetectable -> false. 1444 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
1472 __ j(not_zero, false_label); 1445 1 << Map::kIsUndetectable);
1446 __ j(not_zero, false_label);
1447 }
1473 } 1448 }
1474 1449
1475 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) { 1450 if (expected.Contains(ToBooleanStub::SPEC_OBJECT)) {
1476 // spec object -> true. 1451 // spec object -> true.
1477 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 1452 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
1478 __ j(above_equal, true_label); 1453 __ 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 } 1454 }
1484 1455
1485 if (expected.Contains(ToBooleanStub::STRING)) { 1456 if (expected.Contains(ToBooleanStub::STRING)) {
1486 // String value -> false iff empty. 1457 // String value -> false iff empty.
1487 Label not_string; 1458 Label not_string;
1488 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 1459 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
1489 __ j(above_equal, &not_string, Label::kNear); 1460 __ j(above_equal, &not_string, Label::kNear);
1490 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0)); 1461 __ cmp(FieldOperand(reg, String::kLengthOffset), Immediate(0));
1491 __ j(not_zero, true_label); 1462 __ j(not_zero, true_label);
1492 __ jmp(false_label); 1463 __ jmp(false_label);
1493 __ bind(&not_string); 1464 __ 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 } 1465 }
1499 1466
1500 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) { 1467 if (expected.Contains(ToBooleanStub::HEAP_NUMBER)) {
1501 // heap number -> false iff +0, -0, or NaN. 1468 // heap number -> false iff +0, -0, or NaN.
1502 Label not_heap_number; 1469 Label not_heap_number;
1503 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 1470 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
1504 factory()->heap_number_map()); 1471 factory()->heap_number_map());
1505 __ j(not_equal, &not_heap_number, Label::kNear); 1472 __ j(not_equal, &not_heap_number, Label::kNear);
1506 __ fldz(); 1473 __ fldz();
1507 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset)); 1474 __ fld_d(FieldOperand(reg, HeapNumber::kValueOffset));
1508 __ FCmp(); 1475 __ FCmp();
1509 __ j(zero, false_label); 1476 __ j(zero, false_label);
1510 __ jmp(true_label); 1477 __ jmp(true_label);
1511 __ bind(&not_heap_number); 1478 __ 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 } 1479 }
1518 1480
1519 if (expected.Contains(ToBooleanStub::INTERNAL_OBJECT)) { 1481 // We've seen something for the first time -> deopt.
1520 // internal objects -> true 1482 DeoptimizeIf(no_condition, instr->environment());
1521 __ jmp(true_label);
1522 } else {
1523 // We've seen something for the first time -> deopt.
1524 DeoptimizeIf(no_condition, instr->environment());
1525 }
1526 } 1483 }
1527 } 1484 }
1528 } 1485 }
1529 1486
1530 1487
1531 void LCodeGen::EmitGoto(int block) { 1488 void LCodeGen::EmitGoto(int block) {
1532 block = chunk_->LookupDestination(block); 1489 block = chunk_->LookupDestination(block);
1533 int next_block = GetNextEmittedBlock(current_block_); 1490 int next_block = GetNextEmittedBlock(current_block_);
1534 if (block != next_block) { 1491 if (block != next_block) {
1535 __ jmp(chunk_->GetAssemblyLabel(block)); 1492 __ jmp(chunk_->GetAssemblyLabel(block));
(...skipping 774 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 __ sub(length, index); 2267 __ sub(length, index);
2311 DeoptimizeIf(below_equal, instr->environment()); 2268 DeoptimizeIf(below_equal, instr->environment());
2312 2269
2313 // There are two words between the frame pointer and the last argument. 2270 // There are two words between the frame pointer and the last argument.
2314 // Subtracting from length accounts for one of them add one more. 2271 // Subtracting from length accounts for one of them add one more.
2315 __ mov(result, Operand(arguments, length, times_4, kPointerSize)); 2272 __ mov(result, Operand(arguments, length, times_4, kPointerSize));
2316 } 2273 }
2317 2274
2318 2275
2319 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) { 2276 void LCodeGen::DoLoadKeyedFastElement(LLoadKeyedFastElement* instr) {
2320 Register elements = ToRegister(instr->elements());
2321 Register key = ToRegister(instr->key());
2322 Register result = ToRegister(instr->result()); 2277 Register result = ToRegister(instr->result());
2323 ASSERT(result.is(elements));
2324 2278
2325 // Load the result. 2279 // Load the result.
2326 __ mov(result, FieldOperand(elements, 2280 __ mov(result,
2327 key, 2281 BuildFastArrayOperand(instr->elements(), instr->key(),
2328 times_pointer_size, 2282 JSObject::FAST_ELEMENTS,
2329 FixedArray::kHeaderSize)); 2283 FixedArray::kHeaderSize - kHeapObjectTag));
2330 2284
2331 // Check for the hole value. 2285 // Check for the hole value.
2332 if (instr->hydrogen()->RequiresHoleCheck()) { 2286 if (instr->hydrogen()->RequiresHoleCheck()) {
2333 __ cmp(result, factory()->the_hole_value()); 2287 __ cmp(result, factory()->the_hole_value());
2334 DeoptimizeIf(equal, instr->environment()); 2288 DeoptimizeIf(equal, instr->environment());
2335 } 2289 }
2336 } 2290 }
2337 2291
2338 2292
2339 void LCodeGen::DoLoadKeyedFastDoubleElement( 2293 void LCodeGen::DoLoadKeyedFastDoubleElement(
(...skipping 12 matching lines...) Expand all
2352 } 2306 }
2353 2307
2354 Operand double_load_operand = BuildFastArrayOperand( 2308 Operand double_load_operand = BuildFastArrayOperand(
2355 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS, 2309 instr->elements(), instr->key(), JSObject::FAST_DOUBLE_ELEMENTS,
2356 FixedDoubleArray::kHeaderSize - kHeapObjectTag); 2310 FixedDoubleArray::kHeaderSize - kHeapObjectTag);
2357 __ movdbl(result, double_load_operand); 2311 __ movdbl(result, double_load_operand);
2358 } 2312 }
2359 2313
2360 2314
2361 Operand LCodeGen::BuildFastArrayOperand( 2315 Operand LCodeGen::BuildFastArrayOperand(
2362 LOperand* external_pointer, 2316 LOperand* elements_pointer,
2363 LOperand* key, 2317 LOperand* key,
2364 JSObject::ElementsKind elements_kind, 2318 JSObject::ElementsKind elements_kind,
2365 uint32_t offset) { 2319 uint32_t offset) {
2366 Register external_pointer_reg = ToRegister(external_pointer); 2320 Register elements_pointer_reg = ToRegister(elements_pointer);
2367 int shift_size = ElementsKindToShiftSize(elements_kind); 2321 int shift_size = ElementsKindToShiftSize(elements_kind);
2368 if (key->IsConstantOperand()) { 2322 if (key->IsConstantOperand()) {
2369 int constant_value = ToInteger32(LConstantOperand::cast(key)); 2323 int constant_value = ToInteger32(LConstantOperand::cast(key));
2370 if (constant_value & 0xF0000000) { 2324 if (constant_value & 0xF0000000) {
2371 Abort("array index constant value too big"); 2325 Abort("array index constant value too big");
2372 } 2326 }
2373 return Operand(external_pointer_reg, 2327 return Operand(elements_pointer_reg,
2374 constant_value * (1 << shift_size) + offset); 2328 constant_value * (1 << shift_size) + offset);
2375 } else { 2329 } else {
2376 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size); 2330 ScaleFactor scale_factor = static_cast<ScaleFactor>(shift_size);
2377 return Operand(external_pointer_reg, ToRegister(key), scale_factor, offset); 2331 return Operand(elements_pointer_reg, ToRegister(key), scale_factor, offset);
2378 } 2332 }
2379 } 2333 }
2380 2334
2381 2335
2382 void LCodeGen::DoLoadKeyedSpecializedArrayElement( 2336 void LCodeGen::DoLoadKeyedSpecializedArrayElement(
2383 LLoadKeyedSpecializedArrayElement* instr) { 2337 LLoadKeyedSpecializedArrayElement* instr) {
2384 JSObject::ElementsKind elements_kind = instr->elements_kind(); 2338 JSObject::ElementsKind elements_kind = instr->elements_kind();
2385 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 2339 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
2386 instr->key(), elements_kind, 0)); 2340 instr->key(), elements_kind, 0));
2387 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { 2341 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
(...skipping 376 matching lines...) Expand 10 before | Expand all | Expand 10 after
2764 EmitIntegerMathAbs(instr); 2718 EmitIntegerMathAbs(instr);
2765 __ bind(deferred->exit()); 2719 __ bind(deferred->exit());
2766 } 2720 }
2767 } 2721 }
2768 2722
2769 2723
2770 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) { 2724 void LCodeGen::DoMathFloor(LUnaryMathOperation* instr) {
2771 XMMRegister xmm_scratch = xmm0; 2725 XMMRegister xmm_scratch = xmm0;
2772 Register output_reg = ToRegister(instr->result()); 2726 Register output_reg = ToRegister(instr->result());
2773 XMMRegister input_reg = ToDoubleRegister(instr->value()); 2727 XMMRegister input_reg = ToDoubleRegister(instr->value());
2774 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2775 __ ucomisd(input_reg, xmm_scratch);
2776 2728
2777 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 2729 if (CpuFeatures::IsSupported(SSE4_1)) {
2778 DeoptimizeIf(below_equal, instr->environment()); 2730 CpuFeatures::Scope scope(SSE4_1);
2731 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2732 // Deoptimize on negative zero.
2733 Label non_zero;
2734 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2735 __ ucomisd(input_reg, xmm_scratch);
2736 __ j(not_equal, &non_zero, Label::kNear);
2737 __ movmskpd(output_reg, input_reg);
2738 __ test(output_reg, Immediate(1));
2739 DeoptimizeIf(not_zero, instr->environment());
2740 __ bind(&non_zero);
2741 }
2742 __ roundsd(xmm_scratch, input_reg, Assembler::kRoundDown);
2743 __ cvttsd2si(output_reg, Operand(xmm_scratch));
2744 // Overflow is signalled with minint.
2745 __ cmp(output_reg, 0x80000000u);
2746 DeoptimizeIf(equal, instr->environment());
2779 } else { 2747 } else {
2748 Label done;
2749 // Deoptimize on negative numbers.
2750 __ xorps(xmm_scratch, xmm_scratch); // Zero the register.
2751 __ ucomisd(input_reg, xmm_scratch);
2780 DeoptimizeIf(below, instr->environment()); 2752 DeoptimizeIf(below, instr->environment());
2753
2754 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
2755 // Check for negative zero.
2756 Label positive_sign;
2757 __ j(above, &positive_sign, Label::kNear);
2758 __ movmskpd(output_reg, input_reg);
2759 __ test(output_reg, Immediate(1));
2760 DeoptimizeIf(not_zero, instr->environment());
2761 __ Set(output_reg, Immediate(0));
2762 __ jmp(&done, Label::kNear);
2763 __ bind(&positive_sign);
2764 }
2765
2766 // Use truncating instruction (OK because input is positive).
2767 __ cvttsd2si(output_reg, Operand(input_reg));
2768
2769 // Overflow is signalled with minint.
2770 __ cmp(output_reg, 0x80000000u);
2771 DeoptimizeIf(equal, instr->environment());
2772 __ bind(&done);
2781 } 2773 }
2782
2783 // Use truncating instruction (OK because input is positive).
2784 __ cvttsd2si(output_reg, Operand(input_reg));
2785
2786 // Overflow is signalled with minint.
2787 __ cmp(output_reg, 0x80000000u);
2788 DeoptimizeIf(equal, instr->environment());
2789 } 2774 }
2790 2775
2791
2792 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) { 2776 void LCodeGen::DoMathRound(LUnaryMathOperation* instr) {
2793 XMMRegister xmm_scratch = xmm0; 2777 XMMRegister xmm_scratch = xmm0;
2794 Register output_reg = ToRegister(instr->result()); 2778 Register output_reg = ToRegister(instr->result());
2795 XMMRegister input_reg = ToDoubleRegister(instr->value()); 2779 XMMRegister input_reg = ToDoubleRegister(instr->value());
2796 2780
2797 Label below_half, done; 2781 Label below_half, done;
2798 // xmm_scratch = 0.5 2782 // xmm_scratch = 0.5
2799 ExternalReference one_half = ExternalReference::address_of_one_half(); 2783 ExternalReference one_half = ExternalReference::address_of_one_half();
2800 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half)); 2784 __ movdbl(xmm_scratch, Operand::StaticVariable(one_half));
2801
2802 __ ucomisd(xmm_scratch, input_reg); 2785 __ ucomisd(xmm_scratch, input_reg);
2803 __ j(above, &below_half); 2786 __ j(above, &below_half);
2804 // input = input + 0.5 2787 // input = input + 0.5
2805 __ addsd(input_reg, xmm_scratch); 2788 __ addsd(input_reg, xmm_scratch);
2806 2789
2807
2808 // Compute Math.floor(value + 0.5). 2790 // Compute Math.floor(value + 0.5).
2809 // Use truncating instruction (OK because input is positive). 2791 // Use truncating instruction (OK because input is positive).
2810 __ cvttsd2si(output_reg, Operand(input_reg)); 2792 __ cvttsd2si(output_reg, Operand(input_reg));
2811 2793
2812 // Overflow is signalled with minint. 2794 // Overflow is signalled with minint.
2813 __ cmp(output_reg, 0x80000000u); 2795 __ cmp(output_reg, 0x80000000u);
2814 DeoptimizeIf(equal, instr->environment()); 2796 DeoptimizeIf(equal, instr->environment());
2815 __ jmp(&done); 2797 __ jmp(&done);
2816 2798
2817 __ bind(&below_half); 2799 __ bind(&below_half);
(...skipping 298 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 3098
3117 __ mov(ecx, instr->name()); 3099 __ mov(ecx, instr->name());
3118 Handle<Code> ic = instr->strict_mode() 3100 Handle<Code> ic = instr->strict_mode()
3119 ? isolate()->builtins()->StoreIC_Initialize_Strict() 3101 ? isolate()->builtins()->StoreIC_Initialize_Strict()
3120 : isolate()->builtins()->StoreIC_Initialize(); 3102 : isolate()->builtins()->StoreIC_Initialize();
3121 CallCode(ic, RelocInfo::CODE_TARGET, instr); 3103 CallCode(ic, RelocInfo::CODE_TARGET, instr);
3122 } 3104 }
3123 3105
3124 3106
3125 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) { 3107 void LCodeGen::DoBoundsCheck(LBoundsCheck* instr) {
3126 __ cmp(ToRegister(instr->index()), ToOperand(instr->length())); 3108 if (instr->index()->IsConstantOperand()) {
3127 DeoptimizeIf(above_equal, instr->environment()); 3109 __ cmp(ToOperand(instr->length()),
3110 ToImmediate(LConstantOperand::cast(instr->index())));
3111 DeoptimizeIf(below_equal, instr->environment());
3112 } else {
3113 __ cmp(ToRegister(instr->index()), ToOperand(instr->length()));
3114 DeoptimizeIf(above_equal, instr->environment());
3115 }
3128 } 3116 }
3129 3117
3130 3118
3131 void LCodeGen::DoStoreKeyedSpecializedArrayElement( 3119 void LCodeGen::DoStoreKeyedSpecializedArrayElement(
3132 LStoreKeyedSpecializedArrayElement* instr) { 3120 LStoreKeyedSpecializedArrayElement* instr) {
3133 JSObject::ElementsKind elements_kind = instr->elements_kind(); 3121 JSObject::ElementsKind elements_kind = instr->elements_kind();
3134 Operand operand(BuildFastArrayOperand(instr->external_pointer(), 3122 Operand operand(BuildFastArrayOperand(instr->external_pointer(),
3135 instr->key(), elements_kind, 0)); 3123 instr->key(), elements_kind, 0));
3136 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) { 3124 if (elements_kind == JSObject::EXTERNAL_FLOAT_ELEMENTS) {
3137 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value())); 3125 __ cvtsd2ss(xmm0, ToDoubleRegister(instr->value()));
(...skipping 1070 matching lines...) Expand 10 before | Expand all | Expand 10 after
4208 __ test_b(FieldOperand(input, Map::kBitFieldOffset), 4196 __ test_b(FieldOperand(input, Map::kBitFieldOffset),
4209 1 << Map::kIsUndetectable); 4197 1 << Map::kIsUndetectable);
4210 final_branch_condition = zero; 4198 final_branch_condition = zero;
4211 4199
4212 } else if (type_name->Equals(heap()->boolean_symbol())) { 4200 } else if (type_name->Equals(heap()->boolean_symbol())) {
4213 __ cmp(input, factory()->true_value()); 4201 __ cmp(input, factory()->true_value());
4214 __ j(equal, true_label); 4202 __ j(equal, true_label);
4215 __ cmp(input, factory()->false_value()); 4203 __ cmp(input, factory()->false_value());
4216 final_branch_condition = equal; 4204 final_branch_condition = equal;
4217 4205
4206 } else if (FLAG_harmony_typeof && type_name->Equals(heap()->null_symbol())) {
4207 __ cmp(input, factory()->null_value());
4208 final_branch_condition = equal;
4209
4218 } else if (type_name->Equals(heap()->undefined_symbol())) { 4210 } else if (type_name->Equals(heap()->undefined_symbol())) {
4219 __ cmp(input, factory()->undefined_value()); 4211 __ cmp(input, factory()->undefined_value());
4220 __ j(equal, true_label); 4212 __ j(equal, true_label);
4221 __ JumpIfSmi(input, false_label); 4213 __ JumpIfSmi(input, false_label);
4222 // Check for undetectable objects => true. 4214 // Check for undetectable objects => true.
4223 __ mov(input, FieldOperand(input, HeapObject::kMapOffset)); 4215 __ mov(input, FieldOperand(input, HeapObject::kMapOffset));
4224 __ test_b(FieldOperand(input, Map::kBitFieldOffset), 4216 __ test_b(FieldOperand(input, Map::kBitFieldOffset),
4225 1 << Map::kIsUndetectable); 4217 1 << Map::kIsUndetectable);
4226 final_branch_condition = not_zero; 4218 final_branch_condition = not_zero;
4227 4219
4228 } else if (type_name->Equals(heap()->function_symbol())) { 4220 } else if (type_name->Equals(heap()->function_symbol())) {
4229 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE); 4221 STATIC_ASSERT(LAST_TYPE == LAST_CALLABLE_SPEC_OBJECT_TYPE);
4230 __ JumpIfSmi(input, false_label); 4222 __ JumpIfSmi(input, false_label);
4231 __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input); 4223 __ CmpObjectType(input, FIRST_CALLABLE_SPEC_OBJECT_TYPE, input);
4232 final_branch_condition = above_equal; 4224 final_branch_condition = above_equal;
4233 4225
4234 } else if (type_name->Equals(heap()->object_symbol())) { 4226 } else if (type_name->Equals(heap()->object_symbol())) {
4235 __ JumpIfSmi(input, false_label); 4227 __ JumpIfSmi(input, false_label);
4236 __ cmp(input, factory()->null_value()); 4228 if (!FLAG_harmony_typeof) {
4237 __ j(equal, true_label); 4229 __ cmp(input, factory()->null_value());
4230 __ j(equal, true_label);
4231 }
4238 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input); 4232 __ CmpObjectType(input, FIRST_NONCALLABLE_SPEC_OBJECT_TYPE, input);
4239 __ j(below, false_label); 4233 __ j(below, false_label);
4240 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE); 4234 __ CmpInstanceType(input, LAST_NONCALLABLE_SPEC_OBJECT_TYPE);
4241 __ j(above, false_label); 4235 __ j(above, false_label);
4242 // Check for undetectable objects => false. 4236 // Check for undetectable objects => false.
4243 __ test_b(FieldOperand(input, Map::kBitFieldOffset), 4237 __ test_b(FieldOperand(input, Map::kBitFieldOffset),
4244 1 << Map::kIsUndetectable); 4238 1 << Map::kIsUndetectable);
4245 final_branch_condition = zero; 4239 final_branch_condition = zero;
4246 4240
4247 } else { 4241 } else {
(...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after
4414 env->deoptimization_index()); 4408 env->deoptimization_index());
4415 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator); 4409 __ InvokeBuiltin(Builtins::IN, CALL_FUNCTION, safepoint_generator);
4416 } 4410 }
4417 4411
4418 4412
4419 #undef __ 4413 #undef __
4420 4414
4421 } } // namespace v8::internal 4415 } } // namespace v8::internal
4422 4416
4423 #endif // V8_TARGET_ARCH_IA32 4417 #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