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

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

Issue 20781007: Add X87 implementations for Integer32ToDouble, DoubleToI, DoubleToSmi (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: add a test that was still missing in cl Created 7 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 2012 the V8 project authors. All rights reserved. 1 // Copyright 2012 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 341 matching lines...) Expand 10 before | Expand all | Expand 10 after
352 instr->hydrogen_value()->id(), 352 instr->hydrogen_value()->id(),
353 instr->Mnemonic()); 353 instr->Mnemonic());
354 } 354 }
355 355
356 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr); 356 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
357 357
358 RecordAndUpdatePosition(instr->position()); 358 RecordAndUpdatePosition(instr->position());
359 359
360 instr->CompileToNative(this); 360 instr->CompileToNative(this);
361 361
362 if (!CpuFeatures::IsSupported(SSE2)) { 362 if (!CpuFeatures::IsSupported(SSE2) &&
363 if (FLAG_debug_code && FLAG_enable_slow_asserts) { 363 FLAG_debug_code && FLAG_enable_slow_asserts) {
364 __ VerifyX87StackDepth(x87_stack_depth_); 364 __ VerifyX87StackDepth(x87_stack_.depth());
365 }
366 } 365 }
367 } 366 }
368 EnsureSpaceForLazyDeopt(); 367 EnsureSpaceForLazyDeopt();
369 return !is_aborted(); 368 return !is_aborted();
370 } 369 }
371 370
372 371
373 bool LCodeGen::GenerateJumpTable() { 372 bool LCodeGen::GenerateJumpTable() {
374 Label needs_frame; 373 Label needs_frame;
375 if (jump_table_.length() > 0) { 374 if (jump_table_.length() > 0) {
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
490 return X87Register::FromAllocationIndex(index); 489 return X87Register::FromAllocationIndex(index);
491 } 490 }
492 491
493 492
494 XMMRegister LCodeGen::ToDoubleRegister(int index) const { 493 XMMRegister LCodeGen::ToDoubleRegister(int index) const {
495 return XMMRegister::FromAllocationIndex(index); 494 return XMMRegister::FromAllocationIndex(index);
496 } 495 }
497 496
498 497
499 void LCodeGen::X87LoadForUsage(X87Register reg) { 498 void LCodeGen::X87LoadForUsage(X87Register reg) {
500 ASSERT(X87StackContains(reg)); 499 ASSERT(x87_stack_.Contains(reg));
501 X87Fxch(reg); 500 x87_stack_.Fxch(reg);
502 x87_stack_depth_--; 501 x87_stack_.pop();
503 } 502 }
504 503
505 504
506 void LCodeGen::X87Fxch(X87Register reg, int other_slot) { 505 void LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) {
507 ASSERT(X87StackContains(reg) && x87_stack_depth_ > other_slot); 506 ASSERT(Contains(reg) && stack_depth_ > other_slot);
508 int i = X87ArrayIndex(reg); 507 int i = ArrayIndex(reg);
509 int st = x87_st2idx(i); 508 int st = st2idx(i);
510 if (st != other_slot) { 509 if (st != other_slot) {
511 int other_i = x87_st2idx(other_slot); 510 int other_i = st2idx(other_slot);
512 X87Register other = x87_stack_[other_i]; 511 X87Register other = stack_[other_i];
513 x87_stack_[other_i] = reg; 512 stack_[other_i] = reg;
514 x87_stack_[i] = other; 513 stack_[i] = other;
515 if (st == 0) { 514 if (st == 0) {
516 __ fxch(other_slot); 515 __ fxch(other_slot);
517 } else if (other_slot == 0) { 516 } else if (other_slot == 0) {
518 __ fxch(st); 517 __ fxch(st);
519 } else { 518 } else {
520 __ fxch(st); 519 __ fxch(st);
521 __ fxch(other_slot); 520 __ fxch(other_slot);
522 __ fxch(st); 521 __ fxch(st);
523 } 522 }
524 } 523 }
525 } 524 }
526 525
527 526
528 int LCodeGen::x87_st2idx(int pos) { 527 int LCodeGen::X87Stack::st2idx(int pos) {
529 return x87_stack_depth_ - pos - 1; 528 return stack_depth_ - pos - 1;
530 } 529 }
531 530
532 531
533 int LCodeGen::X87ArrayIndex(X87Register reg) { 532 int LCodeGen::X87Stack::ArrayIndex(X87Register reg) {
534 for (int i = 0; i < x87_stack_depth_; i++) { 533 for (int i = 0; i < stack_depth_; i++) {
535 if (x87_stack_[i].is(reg)) return i; 534 if (stack_[i].is(reg)) return i;
536 } 535 }
537 UNREACHABLE(); 536 UNREACHABLE();
538 return -1; 537 return -1;
539 } 538 }
540 539
541 540
542 bool LCodeGen::X87StackContains(X87Register reg) { 541 bool LCodeGen::X87Stack::Contains(X87Register reg) {
543 for (int i = 0; i < x87_stack_depth_; i++) { 542 for (int i = 0; i < stack_depth_; i++) {
544 if (x87_stack_[i].is(reg)) return true; 543 if (stack_[i].is(reg)) return true;
545 } 544 }
546 return false; 545 return false;
547 } 546 }
548 547
549 548
550 void LCodeGen::X87Free(X87Register reg) { 549 void LCodeGen::X87Stack::Free(X87Register reg) {
551 ASSERT(X87StackContains(reg)); 550 ASSERT(Contains(reg));
552 int i = X87ArrayIndex(reg); 551 int i = ArrayIndex(reg);
553 int st = x87_st2idx(i); 552 int st = st2idx(i);
554 if (st > 0) { 553 if (st > 0) {
555 // keep track of how fstp(i) changes the order of elements 554 // keep track of how fstp(i) changes the order of elements
556 int tos_i = x87_st2idx(0); 555 int tos_i = st2idx(0);
557 x87_stack_[i] = x87_stack_[tos_i]; 556 stack_[i] = stack_[tos_i];
558 } 557 }
559 x87_stack_depth_--; 558 pop();
560 __ fstp(st); 559 __ fstp(st);
561 } 560 }
562 561
563 562
564 void LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) { 563 void LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) {
565 if (X87StackContains(dst)) { 564 if (x87_stack_.Contains(dst)) {
566 X87Fxch(dst); 565 x87_stack_.Fxch(dst);
567 __ fstp(0); 566 __ fstp(0);
568 } else { 567 } else {
569 ASSERT(x87_stack_depth_ < X87Register::kNumAllocatableRegisters); 568 x87_stack_.push(dst);
570 x87_stack_[x87_stack_depth_] = dst;
571 x87_stack_depth_++;
572 } 569 }
573 X87Fld(src, opts); 570 X87Fld(src, opts);
574 } 571 }
575 572
576 573
577 void LCodeGen::X87Fld(Operand src, X87OperandType opts) { 574 void LCodeGen::X87Fld(Operand src, X87OperandType opts) {
578 if (opts == kX87DoubleOperand) { 575 ASSERT(!src.is_reg_only());
579 __ fld_d(src); 576 switch (opts) {
580 } else if (opts == kX87FloatOperand) { 577 case kX87DoubleOperand:
581 __ fld_s(src); 578 __ fld_d(src);
582 } else if (opts == kX87IntOperand) { 579 break;
583 __ fild_s(src); 580 case kX87FloatOperand:
584 } else { 581 __ fld_s(src);
585 UNREACHABLE(); 582 break;
583 case kX87IntOperand:
584 __ fild_s(src);
585 break;
586 default:
587 UNREACHABLE();
586 } 588 }
587 } 589 }
588 590
589 591
590 void LCodeGen::X87Mov(Operand dst, X87Register src) { 592 void LCodeGen::X87Mov(Operand dst, X87Register src, X87OperandType opts) {
591 X87Fxch(src); 593 ASSERT(!dst.is_reg_only());
592 __ fst_d(dst); 594 x87_stack_.Fxch(src);
595 switch (opts) {
596 case kX87DoubleOperand:
597 __ fst_d(dst);
598 break;
599 case kX87IntOperand:
600 __ fist_s(dst);
601 break;
602 default:
603 UNREACHABLE();
604 }
593 } 605 }
594 606
595 607
596 void LCodeGen::X87PrepareToWrite(X87Register reg) { 608 void LCodeGen::X87Stack::PrepareToWrite(X87Register reg) {
597 if (X87StackContains(reg)) { 609 if (Contains(reg)) {
598 X87Free(reg); 610 Free(reg);
599 } 611 }
600 // Mark this register as the next register to write to 612 // Mark this register as the next register to write to
601 x87_stack_[x87_stack_depth_] = reg; 613 stack_[stack_depth_] = reg;
602 } 614 }
603 615
604 616
605 void LCodeGen::X87CommitWrite(X87Register reg) { 617 void LCodeGen::X87Stack::CommitWrite(X87Register reg) {
606 // Assert the reg is prepared to write, but not on the virtual stack yet 618 // Assert the reg is prepared to write, but not on the virtual stack yet
607 ASSERT(!X87StackContains(reg) && x87_stack_[x87_stack_depth_].is(reg) && 619 ASSERT(!Contains(reg) && stack_[stack_depth_].is(reg) &&
608 x87_stack_depth_ < X87Register::kNumAllocatableRegisters); 620 stack_depth_ < X87Register::kNumAllocatableRegisters);
609 x87_stack_depth_++; 621 stack_depth_++;
610 } 622 }
611 623
612 624
613 void LCodeGen::X87PrepareBinaryOp( 625 void LCodeGen::X87PrepareBinaryOp(
614 X87Register left, X87Register right, X87Register result) { 626 X87Register left, X87Register right, X87Register result) {
615 // You need to use DefineSameAsFirst for x87 instructions 627 // You need to use DefineSameAsFirst for x87 instructions
616 ASSERT(result.is(left)); 628 ASSERT(result.is(left));
617 X87Fxch(right, 1); 629 x87_stack_.Fxch(right, 1);
618 X87Fxch(left); 630 x87_stack_.Fxch(left);
619 } 631 }
620 632
621 633
622 void LCodeGen::FlushX87StackIfNecessary(LInstruction* instr) { 634 void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
623 if (x87_stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) { 635 if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
624 bool double_inputs = instr->HasDoubleRegisterInput(); 636 bool double_inputs = instr->HasDoubleRegisterInput();
625 637
626 // Flush stack from tos down, since FreeX87() will mess with tos 638 // Flush stack from tos down, since FreeX87() will mess with tos
627 for (int i = x87_stack_depth_-1; i >= 0; i--) { 639 for (int i = stack_depth_-1; i >= 0; i--) {
628 X87Register reg = x87_stack_[i]; 640 X87Register reg = stack_[i];
629 // Skip registers which contain the inputs for the next instruction 641 // Skip registers which contain the inputs for the next instruction
630 // when flushing the stack 642 // when flushing the stack
631 if (double_inputs && instr->IsDoubleInput(reg, this)) { 643 if (double_inputs && instr->IsDoubleInput(reg, cgen)) {
632 continue; 644 continue;
633 } 645 }
634 X87Free(reg); 646 Free(reg);
635 if (i < x87_stack_depth_-1) i++; 647 if (i < stack_depth_-1) i++;
636 } 648 }
637 } 649 }
638 if (instr->IsReturn()) { 650 if (instr->IsReturn()) {
639 while (x87_stack_depth_ > 0) { 651 while (stack_depth_ > 0) {
640 __ fstp(0); 652 __ fstp(0);
641 x87_stack_depth_--; 653 stack_depth_--;
642 } 654 }
643 } 655 }
644 } 656 }
645 657
646 658
647 void LCodeGen::EmitFlushX87ForDeopt() { 659 void LCodeGen::EmitFlushX87ForDeopt() {
648 for (int i = 0; i < x87_stack_depth_; i++) __ fstp(0); 660 // The deoptimizer does not support X87 Registers. But as long as we
661 // deopt from a stub its not a problem, since we will re-materialize the
662 // original stub inputs, which can't be double registers.
663 ASSERT(info()->IsStub());
664 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
665 __ pushfd();
666 __ VerifyX87StackDepth(x87_stack_.depth());
667 __ popfd();
668 }
669 for (int i = 0; i < x87_stack_.depth(); i++) __ fstp(0);
649 } 670 }
650 671
651 672
652 Register LCodeGen::ToRegister(LOperand* op) const { 673 Register LCodeGen::ToRegister(LOperand* op) const {
653 ASSERT(op->IsRegister()); 674 ASSERT(op->IsRegister());
654 return ToRegister(op->index()); 675 return ToRegister(op->index());
655 } 676 }
656 677
657 678
658 X87Register LCodeGen::ToX87Register(LOperand* op) const { 679 X87Register LCodeGen::ToX87Register(LOperand* op) const {
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
996 __ bind(&no_deopt); 1017 __ bind(&no_deopt);
997 __ mov(Operand::StaticVariable(count), eax); 1018 __ mov(Operand::StaticVariable(count), eax);
998 __ pop(eax); 1019 __ pop(eax);
999 __ popfd(); 1020 __ popfd();
1000 } 1021 }
1001 1022
1002 // Before Instructions which can deopt, we normally flush the x87 stack. But 1023 // Before Instructions which can deopt, we normally flush the x87 stack. But
1003 // we can have inputs or outputs of the current instruction on the stack, 1024 // we can have inputs or outputs of the current instruction on the stack,
1004 // thus we need to flush them here from the physical stack to leave it in a 1025 // thus we need to flush them here from the physical stack to leave it in a
1005 // consistent state. 1026 // consistent state.
1006 if (x87_stack_depth_ > 0) { 1027 if (x87_stack_.depth() > 0) {
1007 Label done; 1028 Label done;
1008 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 1029 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
1009 EmitFlushX87ForDeopt(); 1030 EmitFlushX87ForDeopt();
1010 __ bind(&done); 1031 __ bind(&done);
1011 } 1032 }
1012 1033
1013 if (info()->ShouldTrapOnDeopt()) { 1034 if (info()->ShouldTrapOnDeopt()) {
1014 Label done; 1035 Label done;
1015 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 1036 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
1016 __ int3(); 1037 __ int3();
(...skipping 841 matching lines...) Expand 10 before | Expand all | Expand 10 after
1858 void LCodeGen::DoConstantS(LConstantS* instr) { 1879 void LCodeGen::DoConstantS(LConstantS* instr) {
1859 __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1880 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1860 } 1881 }
1861 1882
1862 1883
1863 void LCodeGen::DoConstantD(LConstantD* instr) { 1884 void LCodeGen::DoConstantD(LConstantD* instr) {
1864 double v = instr->value(); 1885 double v = instr->value();
1865 uint64_t int_val = BitCast<uint64_t, double>(v); 1886 uint64_t int_val = BitCast<uint64_t, double>(v);
1866 int32_t lower = static_cast<int32_t>(int_val); 1887 int32_t lower = static_cast<int32_t>(int_val);
1867 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 1888 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
1889 ASSERT(instr->result()->IsDoubleRegister());
1868 1890
1869 if (!CpuFeatures::IsSafeForSnapshot(SSE2)) { 1891 if (!CpuFeatures::IsSafeForSnapshot(SSE2)) {
1870 __ push(Immediate(upper)); 1892 __ push(Immediate(upper));
1871 __ push(Immediate(lower)); 1893 __ push(Immediate(lower));
1872 X87Mov(ToX87Register(instr->result()), Operand(esp, 0)); 1894 X87Register reg = ToX87Register(instr->result());
1895 X87Mov(reg, Operand(esp, 0));
1873 __ add(Operand(esp), Immediate(kDoubleSize)); 1896 __ add(Operand(esp), Immediate(kDoubleSize));
1874 } else { 1897 } else {
1875 CpuFeatureScope scope1(masm(), SSE2); 1898 CpuFeatureScope scope1(masm(), SSE2);
1876 ASSERT(instr->result()->IsDoubleRegister());
1877 XMMRegister res = ToDoubleRegister(instr->result()); 1899 XMMRegister res = ToDoubleRegister(instr->result());
1878 if (int_val == 0) { 1900 if (int_val == 0) {
1879 __ xorps(res, res); 1901 __ xorps(res, res);
1880 } else { 1902 } else {
1881 Register temp = ToRegister(instr->temp()); 1903 Register temp = ToRegister(instr->temp());
1882 if (CpuFeatures::IsSupported(SSE4_1)) { 1904 if (CpuFeatures::IsSupported(SSE4_1)) {
1883 CpuFeatureScope scope2(masm(), SSE4_1); 1905 CpuFeatureScope scope2(masm(), SSE4_1);
1884 if (lower != 0) { 1906 if (lower != 0) {
1885 __ Set(temp, Immediate(lower)); 1907 __ Set(temp, Immediate(lower));
1886 __ movd(res, Operand(temp)); 1908 __ movd(res, Operand(temp));
(...skipping 372 matching lines...) Expand 10 before | Expand all | Expand 10 after
2259 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2281 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2260 factory()->heap_number_map()); 2282 factory()->heap_number_map());
2261 EmitBranch(instr, equal); 2283 EmitBranch(instr, equal);
2262 } 2284 }
2263 } 2285 }
2264 2286
2265 2287
2266 void LCodeGen::DoBranch(LBranch* instr) { 2288 void LCodeGen::DoBranch(LBranch* instr) {
2267 Representation r = instr->hydrogen()->value()->representation(); 2289 Representation r = instr->hydrogen()->value()->representation();
2268 if (r.IsSmiOrInteger32()) { 2290 if (r.IsSmiOrInteger32()) {
2269 ASSERT(!info()->IsStub());
2270 Register reg = ToRegister(instr->value()); 2291 Register reg = ToRegister(instr->value());
2271 __ test(reg, Operand(reg)); 2292 __ test(reg, Operand(reg));
2272 EmitBranch(instr, not_zero); 2293 EmitBranch(instr, not_zero);
2273 } else if (r.IsDouble()) { 2294 } else if (r.IsDouble()) {
2274 ASSERT(!info()->IsStub()); 2295 ASSERT(!info()->IsStub());
2275 CpuFeatureScope scope(masm(), SSE2); 2296 CpuFeatureScope scope(masm(), SSE2);
2276 XMMRegister reg = ToDoubleRegister(instr->value()); 2297 XMMRegister reg = ToDoubleRegister(instr->value());
2277 __ xorps(xmm0, xmm0); 2298 __ xorps(xmm0, xmm0);
2278 __ ucomisd(reg, xmm0); 2299 __ ucomisd(reg, xmm0);
2279 EmitBranch(instr, not_equal); 2300 EmitBranch(instr, not_equal);
(...skipping 2587 matching lines...) Expand 10 before | Expand all | Expand 10 after
4867 4888
4868 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4889 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4869 EmitPushTaggedOperand(instr->left()); 4890 EmitPushTaggedOperand(instr->left());
4870 EmitPushTaggedOperand(instr->right()); 4891 EmitPushTaggedOperand(instr->right());
4871 StringAddStub stub(instr->hydrogen()->flags()); 4892 StringAddStub stub(instr->hydrogen()->flags());
4872 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4893 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4873 } 4894 }
4874 4895
4875 4896
4876 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4897 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4898 LOperand* input = instr->value();
4899 LOperand* output = instr->result();
4900 ASSERT(input->IsRegister() || input->IsStackSlot());
4901 ASSERT(output->IsDoubleRegister());
4877 if (CpuFeatures::IsSupported(SSE2)) { 4902 if (CpuFeatures::IsSupported(SSE2)) {
4878 CpuFeatureScope scope(masm(), SSE2); 4903 CpuFeatureScope scope(masm(), SSE2);
4879 LOperand* input = instr->value();
4880 ASSERT(input->IsRegister() || input->IsStackSlot());
4881 LOperand* output = instr->result();
4882 ASSERT(output->IsDoubleRegister());
4883 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4904 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4905 } else if (input->IsRegister()) {
4906 Register input_reg = ToRegister(input);
4907 __ push(input_reg);
4908 X87Mov(ToX87Register(output), Operand(esp, 0), kX87IntOperand);
4909 __ pop(input_reg);
4884 } else { 4910 } else {
4885 UNREACHABLE(); 4911 X87Mov(ToX87Register(output), ToOperand(input), kX87IntOperand);
4886 } 4912 }
4887 } 4913 }
4888 4914
4889 4915
4890 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { 4916 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4891 Register input = ToRegister(instr->value()); 4917 Register input = ToRegister(instr->value());
4892 __ SmiTag(input); 4918 __ SmiTag(input);
4893 if (!instr->hydrogen()->value()->HasRange() || 4919 if (!instr->hydrogen()->value()->HasRange() ||
4894 !instr->hydrogen()->value()->range()->IsInSmiRange()) { 4920 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4895 DeoptimizeIf(overflow, instr->environment()); 4921 DeoptimizeIf(overflow, instr->environment());
(...skipping 667 matching lines...) Expand 10 before | Expand all | Expand 10 after
5563 mode); 5589 mode);
5564 } 5590 }
5565 } 5591 }
5566 5592
5567 5593
5568 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5594 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5569 LOperand* input = instr->value(); 5595 LOperand* input = instr->value();
5570 ASSERT(input->IsDoubleRegister()); 5596 ASSERT(input->IsDoubleRegister());
5571 LOperand* result = instr->result(); 5597 LOperand* result = instr->result();
5572 ASSERT(result->IsRegister()); 5598 ASSERT(result->IsRegister());
5573 CpuFeatureScope scope(masm(), SSE2);
5574
5575 XMMRegister input_reg = ToDoubleRegister(input);
5576 Register result_reg = ToRegister(result); 5599 Register result_reg = ToRegister(result);
5577 5600
5578 __ cvttsd2si(result_reg, Operand(input_reg)); 5601 Label done;
5602 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5603 CpuFeatureScope scope(masm(), SSE2);
5579 5604
5580 if (instr->truncating()) { 5605 XMMRegister input_reg = ToDoubleRegister(input);
5581 // Performs a truncating conversion of a floating point number as used by 5606
5582 // the JS bitwise operations. 5607 __ cvttsd2si(result_reg, Operand(input_reg));
5583 Label fast_case_succeeded; 5608
5584 __ cmp(result_reg, 0x80000000u); 5609 if (instr->truncating()) {
5585 __ j(not_equal, &fast_case_succeeded); 5610 // Performs a truncating conversion of a floating point number as used by
5586 __ sub(esp, Immediate(kDoubleSize)); 5611 // the JS bitwise operations.
5587 __ movdbl(MemOperand(esp, 0), input_reg); 5612 Label fast_case_succeeded;
5588 DoubleToIStub stub(esp, result_reg, 0, true); 5613 __ cmp(result_reg, 0x80000000u);
5589 __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 5614 __ j(not_equal, &fast_case_succeeded);
5590 __ add(esp, Immediate(kDoubleSize)); 5615 __ sub(esp, Immediate(kDoubleSize));
5591 __ bind(&fast_case_succeeded); 5616 __ movdbl(MemOperand(esp, 0), input_reg);
5617 DoubleToIStub stub(esp, result_reg, 0, true);
5618 __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
5619 __ add(esp, Immediate(kDoubleSize));
5620 __ bind(&fast_case_succeeded);
5621 } else {
5622 __ cvtsi2sd(xmm0, Operand(result_reg));
5623 __ ucomisd(xmm0, input_reg);
5624 DeoptimizeIf(not_equal, instr->environment());
5625 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5626 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5627 // The integer converted back is equal to the original. We
5628 // only have to test if we got -0 as an input.
5629 __ test(result_reg, Operand(result_reg));
5630 __ j(not_zero, &done, Label::kNear);
5631 __ movmskpd(result_reg, input_reg);
5632 // Bit 0 contains the sign of the double in input_reg.
5633 // If input was positive, we are ok and return 0, otherwise
5634 // deoptimize.
5635 __ and_(result_reg, 1);
5636 DeoptimizeIf(not_zero, instr->environment());
5637 }
5638 __ bind(&done);
5639 }
5592 } else { 5640 } else {
5593 Label done; 5641 X87Register input_reg = ToX87Register(input);
5594 __ cvtsi2sd(xmm0, Operand(result_reg)); 5642 __ push(result_reg);
5595 __ ucomisd(xmm0, input_reg); 5643 X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
5596 DeoptimizeIf(not_equal, instr->environment()); 5644 if (instr->truncating()) {
5597 DeoptimizeIf(parity_even, instr->environment()); // NaN. 5645 __ pop(result_reg);
5646 } else {
5647 X87Fxch(input_reg);
5648 __ fld(0);
5649 __ fild_s(Operand(esp, 0));
5650 __ pop(result_reg);
5651 __ FCmp();
5652 DeoptimizeIf(not_equal, instr->environment());
5653 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5654 }
5598 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5655 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5599 // The integer converted back is equal to the original. We
5600 // only have to test if we got -0 as an input.
5601 __ test(result_reg, Operand(result_reg)); 5656 __ test(result_reg, Operand(result_reg));
5602 __ j(not_zero, &done, Label::kNear); 5657 __ j(not_zero, &done, Label::kNear);
5603 __ movmskpd(result_reg, input_reg); 5658 // To check for minus zero, we load the value again as float, and check
5604 // Bit 0 contains the sign of the double in input_reg. 5659 // if that is still 0.
5605 // If input was positive, we are ok and return 0, otherwise 5660 X87Fxch(input_reg);
5606 // deoptimize. 5661 __ push(result_reg);
5607 __ and_(result_reg, 1); 5662 __ fst_s(Operand(esp, 0));
5663 __ pop(result_reg);
5664 __ test(result_reg, Operand(result_reg));
5608 DeoptimizeIf(not_zero, instr->environment()); 5665 DeoptimizeIf(not_zero, instr->environment());
5666 __ bind(&done);
5609 } 5667 }
5610 __ bind(&done);
5611 } 5668 }
5612 } 5669 }
5613 5670
5614 5671
5615 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5672 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5616 LOperand* input = instr->value(); 5673 LOperand* input = instr->value();
5617 ASSERT(input->IsDoubleRegister()); 5674 ASSERT(input->IsDoubleRegister());
5618 LOperand* result = instr->result(); 5675 LOperand* result = instr->result();
5619 ASSERT(result->IsRegister()); 5676 ASSERT(result->IsRegister());
5620 CpuFeatureScope scope(masm(), SSE2);
5621
5622 XMMRegister input_reg = ToDoubleRegister(input);
5623 Register result_reg = ToRegister(result); 5677 Register result_reg = ToRegister(result);
5624 5678
5625 Label done; 5679 Label done;
5626 __ cvttsd2si(result_reg, Operand(input_reg)); 5680 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5627 __ cvtsi2sd(xmm0, Operand(result_reg)); 5681 CpuFeatureScope scope(masm(), SSE2);
5628 __ ucomisd(xmm0, input_reg);
5629 DeoptimizeIf(not_equal, instr->environment());
5630 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5631 5682
5632 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5683 XMMRegister input_reg = ToDoubleRegister(input);
5633 // The integer converted back is equal to the original. We 5684
5634 // only have to test if we got -0 as an input. 5685 __ cvttsd2si(result_reg, Operand(input_reg));
5635 __ test(result_reg, Operand(result_reg)); 5686 __ cvtsi2sd(xmm0, Operand(result_reg));
5636 __ j(not_zero, &done, Label::kNear); 5687 __ ucomisd(xmm0, input_reg);
5637 __ movmskpd(result_reg, input_reg); 5688 DeoptimizeIf(not_equal, instr->environment());
5638 // Bit 0 contains the sign of the double in input_reg. 5689 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5639 // If input was positive, we are ok and return 0, otherwise 5690 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5640 // deoptimize. 5691 // The integer converted back is equal to the original. We
5641 __ and_(result_reg, 1); 5692 // only have to test if we got -0 as an input.
5642 DeoptimizeIf(not_zero, instr->environment()); 5693 __ test(result_reg, Operand(result_reg));
5643 __ bind(&done); 5694 __ j(not_zero, &done, Label::kNear);
5695 __ movmskpd(result_reg, input_reg);
5696 // Bit 0 contains the sign of the double in input_reg.
5697 // If input was positive, we are ok and return 0, otherwise
5698 // deoptimize.
5699 __ and_(result_reg, 1);
5700 DeoptimizeIf(not_zero, instr->environment());
5701 __ bind(&done);
5702 }
5703 } else {
5704 X87Register input_reg = ToX87Register(input);
5705 X87Fxch(input_reg);
5706 __ push(result_reg);
5707 X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
5708 __ fld(0);
5709 __ fild_s(Operand(esp, 0));
5710 __ pop(result_reg);
5711 __ FCmp();
5712 DeoptimizeIf(not_equal, instr->environment());
5713 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5714
5715 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5716 __ test(result_reg, Operand(result_reg));
5717 __ j(not_zero, &done, Label::kNear);
5718 // To check for minus zero, we load the value again as float, and check
5719 // if that is still 0.
5720 __ push(result_reg);
5721 __ fst_s(Operand(esp, 0));
5722 __ pop(result_reg);
5723 __ test(result_reg, Operand(result_reg));
5724 DeoptimizeIf(not_zero, instr->environment());
5725 __ bind(&done);
5726 }
5644 } 5727 }
5645 __ SmiTag(result_reg); 5728 __ SmiTag(result_reg);
5646 DeoptimizeIf(overflow, instr->environment()); 5729 DeoptimizeIf(overflow, instr->environment());
5647 } 5730 }
5648 5731
5649 5732
5650 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5733 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5651 LOperand* input = instr->value(); 5734 LOperand* input = instr->value();
5652 __ test(ToOperand(input), Immediate(kSmiTagMask)); 5735 __ test(ToOperand(input), Immediate(kSmiTagMask));
5653 DeoptimizeIf(not_zero, instr->environment()); 5736 DeoptimizeIf(not_zero, instr->environment());
(...skipping 812 matching lines...) Expand 10 before | Expand all | Expand 10 after
6466 FixedArray::kHeaderSize - kPointerSize)); 6549 FixedArray::kHeaderSize - kPointerSize));
6467 __ bind(&done); 6550 __ bind(&done);
6468 } 6551 }
6469 6552
6470 6553
6471 #undef __ 6554 #undef __
6472 6555
6473 } } // namespace v8::internal 6556 } } // namespace v8::internal
6474 6557
6475 #endif // V8_TARGET_ARCH_IA32 6558 #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