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

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: 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 334 matching lines...) Expand 10 before | Expand all | Expand 10 after
345 Comment(";;; <@%d,#%d> %s", 345 Comment(";;; <@%d,#%d> %s",
346 current_instruction_, 346 current_instruction_,
347 instr->hydrogen_value()->id(), 347 instr->hydrogen_value()->id(),
348 instr->Mnemonic()); 348 instr->Mnemonic());
349 } 349 }
350 350
351 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr); 351 if (!CpuFeatures::IsSupported(SSE2)) FlushX87StackIfNecessary(instr);
352 352
353 instr->CompileToNative(this); 353 instr->CompileToNative(this);
354 354
355 if (!CpuFeatures::IsSupported(SSE2)) { 355 if (!CpuFeatures::IsSupported(SSE2) &&
356 if (FLAG_debug_code && FLAG_enable_slow_asserts) { 356 FLAG_debug_code && FLAG_enable_slow_asserts) {
357 __ VerifyX87StackDepth(x87_stack_depth_); 357 __ VerifyX87StackDepth(x87_stack_.depth());
358 }
359 } 358 }
360 } 359 }
361 EnsureSpaceForLazyDeopt(); 360 EnsureSpaceForLazyDeopt();
362 return !is_aborted(); 361 return !is_aborted();
363 } 362 }
364 363
365 364
366 bool LCodeGen::GenerateJumpTable() { 365 bool LCodeGen::GenerateJumpTable() {
367 Label needs_frame; 366 Label needs_frame;
368 if (jump_table_.length() > 0) { 367 if (jump_table_.length() > 0) {
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 return X87Register::FromAllocationIndex(index); 478 return X87Register::FromAllocationIndex(index);
480 } 479 }
481 480
482 481
483 XMMRegister LCodeGen::ToDoubleRegister(int index) const { 482 XMMRegister LCodeGen::ToDoubleRegister(int index) const {
484 return XMMRegister::FromAllocationIndex(index); 483 return XMMRegister::FromAllocationIndex(index);
485 } 484 }
486 485
487 486
488 void LCodeGen::X87LoadForUsage(X87Register reg) { 487 void LCodeGen::X87LoadForUsage(X87Register reg) {
489 ASSERT(X87StackContains(reg)); 488 ASSERT(x87_stack_.Contains(reg));
490 X87Fxch(reg); 489 x87_stack_.Fxch(reg);
491 x87_stack_depth_--; 490 x87_stack_.pop();
492 } 491 }
493 492
494 493
495 void LCodeGen::X87Fxch(X87Register reg, int other_slot) { 494 void LCodeGen::X87Stack::Fxch(X87Register reg, int other_slot) {
496 ASSERT(X87StackContains(reg) && x87_stack_depth_ > other_slot); 495 ASSERT(Contains(reg) && stack_depth_ > other_slot);
497 int i = X87ArrayIndex(reg); 496 int i = ArrayIndex(reg);
498 int st = x87_st2idx(i); 497 int st = st2idx(i);
499 if (st != other_slot) { 498 if (st != other_slot) {
500 int other_i = x87_st2idx(other_slot); 499 int other_i = st2idx(other_slot);
501 X87Register other = x87_stack_[other_i]; 500 X87Register other = stack_[other_i];
502 x87_stack_[other_i] = reg; 501 stack_[other_i] = reg;
503 x87_stack_[i] = other; 502 stack_[i] = other;
504 if (st == 0) { 503 if (st == 0) {
505 __ fxch(other_slot); 504 __ fxch(other_slot);
506 } else if (other_slot == 0) { 505 } else if (other_slot == 0) {
507 __ fxch(st); 506 __ fxch(st);
508 } else { 507 } else {
509 __ fxch(st); 508 __ fxch(st);
510 __ fxch(other_slot); 509 __ fxch(other_slot);
511 __ fxch(st); 510 __ fxch(st);
512 } 511 }
513 } 512 }
514 } 513 }
515 514
516 515
517 int LCodeGen::x87_st2idx(int pos) { 516 int LCodeGen::X87Stack::st2idx(int pos) {
518 return x87_stack_depth_ - pos - 1; 517 return stack_depth_ - pos - 1;
519 } 518 }
520 519
521 520
522 int LCodeGen::X87ArrayIndex(X87Register reg) { 521 int LCodeGen::X87Stack::ArrayIndex(X87Register reg) {
523 for (int i = 0; i < x87_stack_depth_; i++) { 522 for (int i = 0; i < stack_depth_; i++) {
524 if (x87_stack_[i].is(reg)) return i; 523 if (stack_[i].is(reg)) return i;
525 } 524 }
526 UNREACHABLE(); 525 UNREACHABLE();
527 return -1; 526 return -1;
528 } 527 }
529 528
530 529
531 bool LCodeGen::X87StackContains(X87Register reg) { 530 bool LCodeGen::X87Stack::Contains(X87Register reg) {
532 for (int i = 0; i < x87_stack_depth_; i++) { 531 for (int i = 0; i < stack_depth_; i++) {
533 if (x87_stack_[i].is(reg)) return true; 532 if (stack_[i].is(reg)) return true;
534 } 533 }
535 return false; 534 return false;
536 } 535 }
537 536
538 537
539 void LCodeGen::X87Free(X87Register reg) { 538 void LCodeGen::X87Stack::Free(X87Register reg) {
540 ASSERT(X87StackContains(reg)); 539 ASSERT(Contains(reg));
541 int i = X87ArrayIndex(reg); 540 int i = ArrayIndex(reg);
542 int st = x87_st2idx(i); 541 int st = st2idx(i);
543 if (st > 0) { 542 if (st > 0) {
544 // keep track of how fstp(i) changes the order of elements 543 // keep track of how fstp(i) changes the order of elements
545 int tos_i = x87_st2idx(0); 544 int tos_i = st2idx(0);
546 x87_stack_[i] = x87_stack_[tos_i]; 545 stack_[i] = stack_[tos_i];
547 } 546 }
548 x87_stack_depth_--; 547 pop();
549 __ fstp(st); 548 __ fstp(st);
550 } 549 }
551 550
552 551
553 void LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) { 552 void LCodeGen::X87Mov(X87Register dst, Operand src, X87OperandType opts) {
554 if (X87StackContains(dst)) { 553 if (x87_stack_.Contains(dst)) {
555 X87Fxch(dst); 554 x87_stack_.Fxch(dst);
556 __ fstp(0); 555 __ fstp(0);
557 } else { 556 } else {
558 ASSERT(x87_stack_depth_ < X87Register::kNumAllocatableRegisters); 557 x87_stack_.push(dst);
559 x87_stack_[x87_stack_depth_] = dst;
560 x87_stack_depth_++;
561 } 558 }
562 X87Fld(src, opts); 559 X87Fld(src, opts);
563 } 560 }
564 561
565 562
566 void LCodeGen::X87Fld(Operand src, X87OperandType opts) { 563 void LCodeGen::X87Fld(Operand src, X87OperandType opts) {
567 if (opts == kX87DoubleOperand) { 564 ASSERT(!src.is_reg_only());
568 __ fld_d(src); 565 switch (opts) {
569 } else if (opts == kX87FloatOperand) { 566 case kX87DoubleOperand:
570 __ fld_s(src); 567 __ fld_d(src);
571 } else if (opts == kX87IntOperand) { 568 break;
572 __ fild_s(src); 569 case kX87FloatOperand:
573 } else { 570 __ fld_s(src);
574 UNREACHABLE(); 571 break;
572 case kX87IntOperand:
573 __ fild_s(src);
574 break;
575 default:
576 UNREACHABLE();
575 } 577 }
576 } 578 }
577 579
578 580
579 void LCodeGen::X87Mov(Operand dst, X87Register src) { 581 void LCodeGen::X87Mov(Operand dst, X87Register src, X87OperandType opts) {
580 X87Fxch(src); 582 ASSERT(!dst.is_reg_only());
581 __ fst_d(dst); 583 x87_stack_.Fxch(src);
584 switch (opts) {
585 case kX87DoubleOperand:
586 __ fst_d(dst);
587 break;
588 case kX87IntOperand:
589 __ fist_s(dst);
590 break;
591 default:
592 UNREACHABLE();
593 }
582 } 594 }
583 595
584 596
585 void LCodeGen::X87PrepareToWrite(X87Register reg) { 597 void LCodeGen::X87Stack::PrepareToWrite(X87Register reg) {
586 if (X87StackContains(reg)) { 598 if (Contains(reg)) {
587 X87Free(reg); 599 Free(reg);
588 } 600 }
589 // Mark this register as the next register to write to 601 // Mark this register as the next register to write to
590 x87_stack_[x87_stack_depth_] = reg; 602 stack_[stack_depth_] = reg;
591 } 603 }
592 604
593 605
594 void LCodeGen::X87CommitWrite(X87Register reg) { 606 void LCodeGen::X87Stack::CommitWrite(X87Register reg) {
595 // Assert the reg is prepared to write, but not on the virtual stack yet 607 // Assert the reg is prepared to write, but not on the virtual stack yet
596 ASSERT(!X87StackContains(reg) && x87_stack_[x87_stack_depth_].is(reg) && 608 ASSERT(!Contains(reg) && stack_[stack_depth_].is(reg) &&
597 x87_stack_depth_ < X87Register::kNumAllocatableRegisters); 609 stack_depth_ < X87Register::kNumAllocatableRegisters);
598 x87_stack_depth_++; 610 stack_depth_++;
599 } 611 }
600 612
601 613
602 void LCodeGen::X87PrepareBinaryOp( 614 void LCodeGen::X87PrepareBinaryOp(
603 X87Register left, X87Register right, X87Register result) { 615 X87Register left, X87Register right, X87Register result) {
604 // You need to use DefineSameAsFirst for x87 instructions 616 // You need to use DefineSameAsFirst for x87 instructions
605 ASSERT(result.is(left)); 617 ASSERT(result.is(left));
606 X87Fxch(right, 1); 618 x87_stack_.Fxch(right, 1);
607 X87Fxch(left); 619 x87_stack_.Fxch(left);
608 } 620 }
609 621
610 622
611 void LCodeGen::FlushX87StackIfNecessary(LInstruction* instr) { 623 void LCodeGen::X87Stack::FlushIfNecessary(LInstruction* instr, LCodeGen* cgen) {
612 if (x87_stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) { 624 if (stack_depth_ > 0 && instr->ClobbersDoubleRegisters()) {
613 bool double_inputs = instr->HasDoubleRegisterInput(); 625 bool double_inputs = instr->HasDoubleRegisterInput();
614 626
615 // Flush stack from tos down, since FreeX87() will mess with tos 627 // Flush stack from tos down, since FreeX87() will mess with tos
616 for (int i = x87_stack_depth_-1; i >= 0; i--) { 628 for (int i = stack_depth_-1; i >= 0; i--) {
617 X87Register reg = x87_stack_[i]; 629 X87Register reg = stack_[i];
618 // Skip registers which contain the inputs for the next instruction 630 // Skip registers which contain the inputs for the next instruction
619 // when flushing the stack 631 // when flushing the stack
620 if (double_inputs && instr->IsDoubleInput(reg, this)) { 632 if (double_inputs && instr->IsDoubleInput(reg, cgen)) {
621 continue; 633 continue;
622 } 634 }
623 X87Free(reg); 635 Free(reg);
624 if (i < x87_stack_depth_-1) i++; 636 if (i < stack_depth_-1) i++;
625 } 637 }
626 } 638 }
627 if (instr->IsReturn()) { 639 if (instr->IsReturn()) {
628 while (x87_stack_depth_ > 0) { 640 while (stack_depth_ > 0) {
629 __ fstp(0); 641 __ fstp(0);
630 x87_stack_depth_--; 642 stack_depth_--;
631 } 643 }
632 } 644 }
633 } 645 }
634 646
635 647
636 void LCodeGen::EmitFlushX87ForDeopt() { 648 void LCodeGen::EmitFlushX87ForDeopt() {
637 for (int i = 0; i < x87_stack_depth_; i++) __ fstp(0); 649 // The deoptimizer does not support X87 Registers. But as long as we
650 // deopt from a stub its not a problem, since we will re-materialize the
651 // original stub inputs, which can't be double registers.
652 ASSERT(info()->IsStub());
653 if (FLAG_debug_code && FLAG_enable_slow_asserts) {
654 __ pushfd();
655 __ VerifyX87StackDepth(x87_stack_.depth());
656 __ popfd();
657 }
658 for (int i = 0; i < x87_stack_.depth(); i++) __ fstp(0);
638 } 659 }
639 660
640 661
641 Register LCodeGen::ToRegister(LOperand* op) const { 662 Register LCodeGen::ToRegister(LOperand* op) const {
642 ASSERT(op->IsRegister()); 663 ASSERT(op->IsRegister());
643 return ToRegister(op->index()); 664 return ToRegister(op->index());
644 } 665 }
645 666
646 667
647 X87Register LCodeGen::ToX87Register(LOperand* op) const { 668 X87Register LCodeGen::ToX87Register(LOperand* op) const {
(...skipping 317 matching lines...) Expand 10 before | Expand all | Expand 10 after
965 __ bind(&no_deopt); 986 __ bind(&no_deopt);
966 __ mov(Operand::StaticVariable(count), eax); 987 __ mov(Operand::StaticVariable(count), eax);
967 __ pop(eax); 988 __ pop(eax);
968 __ popfd(); 989 __ popfd();
969 } 990 }
970 991
971 // Before Instructions which can deopt, we normally flush the x87 stack. But 992 // Before Instructions which can deopt, we normally flush the x87 stack. But
972 // we can have inputs or outputs of the current instruction on the stack, 993 // we can have inputs or outputs of the current instruction on the stack,
973 // thus we need to flush them here from the physical stack to leave it in a 994 // thus we need to flush them here from the physical stack to leave it in a
974 // consistent state. 995 // consistent state.
975 if (x87_stack_depth_ > 0) { 996 if (x87_stack_.depth() > 0) {
976 Label done; 997 Label done;
977 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 998 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
978 EmitFlushX87ForDeopt(); 999 EmitFlushX87ForDeopt();
979 __ bind(&done); 1000 __ bind(&done);
980 } 1001 }
981 1002
982 if (FLAG_trap_on_deopt && info()->IsOptimizing()) { 1003 if (FLAG_trap_on_deopt && info()->IsOptimizing()) {
983 Label done; 1004 Label done;
984 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear); 1005 if (cc != no_condition) __ j(NegateCondition(cc), &done, Label::kNear);
985 __ int3(); 1006 __ int3();
(...skipping 828 matching lines...) Expand 10 before | Expand all | Expand 10 after
1814 void LCodeGen::DoConstantS(LConstantS* instr) { 1835 void LCodeGen::DoConstantS(LConstantS* instr) {
1815 __ Set(ToRegister(instr->result()), Immediate(instr->value())); 1836 __ Set(ToRegister(instr->result()), Immediate(instr->value()));
1816 } 1837 }
1817 1838
1818 1839
1819 void LCodeGen::DoConstantD(LConstantD* instr) { 1840 void LCodeGen::DoConstantD(LConstantD* instr) {
1820 double v = instr->value(); 1841 double v = instr->value();
1821 uint64_t int_val = BitCast<uint64_t, double>(v); 1842 uint64_t int_val = BitCast<uint64_t, double>(v);
1822 int32_t lower = static_cast<int32_t>(int_val); 1843 int32_t lower = static_cast<int32_t>(int_val);
1823 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt)); 1844 int32_t upper = static_cast<int32_t>(int_val >> (kBitsPerInt));
1845 ASSERT(instr->result()->IsDoubleRegister());
1824 1846
1825 if (!CpuFeatures::IsSafeForSnapshot(SSE2)) { 1847 if (!CpuFeatures::IsSafeForSnapshot(SSE2)) {
1826 __ push(Immediate(upper)); 1848 __ push(Immediate(upper));
1827 __ push(Immediate(lower)); 1849 __ push(Immediate(lower));
1828 X87Mov(ToX87Register(instr->result()), Operand(esp, 0)); 1850 X87Register reg = ToX87Register(instr->result());
1851 X87Mov(reg, Operand(esp, 0));
1829 __ add(Operand(esp), Immediate(kDoubleSize)); 1852 __ add(Operand(esp), Immediate(kDoubleSize));
1830 } else { 1853 } else {
1831 CpuFeatureScope scope1(masm(), SSE2); 1854 CpuFeatureScope scope1(masm(), SSE2);
1832 ASSERT(instr->result()->IsDoubleRegister());
1833 XMMRegister res = ToDoubleRegister(instr->result()); 1855 XMMRegister res = ToDoubleRegister(instr->result());
1834 if (int_val == 0) { 1856 if (int_val == 0) {
1835 __ xorps(res, res); 1857 __ xorps(res, res);
1836 } else { 1858 } else {
1837 Register temp = ToRegister(instr->temp()); 1859 Register temp = ToRegister(instr->temp());
1838 if (CpuFeatures::IsSupported(SSE4_1)) { 1860 if (CpuFeatures::IsSupported(SSE4_1)) {
1839 CpuFeatureScope scope2(masm(), SSE4_1); 1861 CpuFeatureScope scope2(masm(), SSE4_1);
1840 if (lower != 0) { 1862 if (lower != 0) {
1841 __ Set(temp, Immediate(lower)); 1863 __ Set(temp, Immediate(lower));
1842 __ movd(res, Operand(temp)); 1864 __ movd(res, Operand(temp));
(...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after
2211 __ cmp(FieldOperand(reg, HeapObject::kMapOffset), 2233 __ cmp(FieldOperand(reg, HeapObject::kMapOffset),
2212 factory()->heap_number_map()); 2234 factory()->heap_number_map());
2213 EmitBranch(instr, equal); 2235 EmitBranch(instr, equal);
2214 } 2236 }
2215 } 2237 }
2216 2238
2217 2239
2218 void LCodeGen::DoBranch(LBranch* instr) { 2240 void LCodeGen::DoBranch(LBranch* instr) {
2219 Representation r = instr->hydrogen()->value()->representation(); 2241 Representation r = instr->hydrogen()->value()->representation();
2220 if (r.IsSmiOrInteger32()) { 2242 if (r.IsSmiOrInteger32()) {
2221 ASSERT(!info()->IsStub());
2222 Register reg = ToRegister(instr->value()); 2243 Register reg = ToRegister(instr->value());
2223 __ test(reg, Operand(reg)); 2244 __ test(reg, Operand(reg));
2224 EmitBranch(instr, not_zero); 2245 EmitBranch(instr, not_zero);
2225 } else if (r.IsDouble()) { 2246 } else if (r.IsDouble()) {
2226 ASSERT(!info()->IsStub()); 2247 ASSERT(!info()->IsStub());
2227 CpuFeatureScope scope(masm(), SSE2); 2248 CpuFeatureScope scope(masm(), SSE2);
2228 XMMRegister reg = ToDoubleRegister(instr->value()); 2249 XMMRegister reg = ToDoubleRegister(instr->value());
2229 __ xorps(xmm0, xmm0); 2250 __ xorps(xmm0, xmm0);
2230 __ ucomisd(reg, xmm0); 2251 __ ucomisd(reg, xmm0);
2231 EmitBranch(instr, not_equal); 2252 EmitBranch(instr, not_equal);
(...skipping 2632 matching lines...) Expand 10 before | Expand all | Expand 10 after
4864 4885
4865 void LCodeGen::DoStringAdd(LStringAdd* instr) { 4886 void LCodeGen::DoStringAdd(LStringAdd* instr) {
4866 EmitPushTaggedOperand(instr->left()); 4887 EmitPushTaggedOperand(instr->left());
4867 EmitPushTaggedOperand(instr->right()); 4888 EmitPushTaggedOperand(instr->right());
4868 StringAddStub stub(instr->hydrogen()->flags()); 4889 StringAddStub stub(instr->hydrogen()->flags());
4869 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr); 4890 CallCode(stub.GetCode(isolate()), RelocInfo::CODE_TARGET, instr);
4870 } 4891 }
4871 4892
4872 4893
4873 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) { 4894 void LCodeGen::DoInteger32ToDouble(LInteger32ToDouble* instr) {
4895 LOperand* input = instr->value();
4896 LOperand* output = instr->result();
4897 ASSERT(input->IsRegister() || input->IsStackSlot());
4898 ASSERT(output->IsDoubleRegister());
4874 if (CpuFeatures::IsSupported(SSE2)) { 4899 if (CpuFeatures::IsSupported(SSE2)) {
4875 CpuFeatureScope scope(masm(), SSE2); 4900 CpuFeatureScope scope(masm(), SSE2);
4876 LOperand* input = instr->value();
4877 ASSERT(input->IsRegister() || input->IsStackSlot());
4878 LOperand* output = instr->result();
4879 ASSERT(output->IsDoubleRegister());
4880 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input)); 4901 __ cvtsi2sd(ToDoubleRegister(output), ToOperand(input));
4881 } else { 4902 } else {
Toon Verwaest 2013/08/01 11:19:36 else if
4882 UNREACHABLE(); 4903 if (input->IsRegister()) {
4904 Register input_reg = ToRegister(input);
4905 __ push(input_reg);
4906 X87Mov(ToX87Register(output), Operand(esp, 0), kX87IntOperand);
4907 __ pop(input_reg);
4908 } else {
4909 X87Mov(ToX87Register(output), ToOperand(input), kX87IntOperand);
4910 }
4883 } 4911 }
4884 } 4912 }
4885 4913
4886 4914
4887 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) { 4915 void LCodeGen::DoInteger32ToSmi(LInteger32ToSmi* instr) {
4888 Register input = ToRegister(instr->value()); 4916 Register input = ToRegister(instr->value());
4889 __ SmiTag(input); 4917 __ SmiTag(input);
4890 if (!instr->hydrogen()->value()->HasRange() || 4918 if (!instr->hydrogen()->value()->HasRange() ||
4891 !instr->hydrogen()->value()->range()->IsInSmiRange()) { 4919 !instr->hydrogen()->value()->range()->IsInSmiRange()) {
4892 DeoptimizeIf(overflow, instr->environment()); 4920 DeoptimizeIf(overflow, instr->environment());
(...skipping 516 matching lines...) Expand 10 before | Expand all | Expand 10 after
5409 virtual LInstruction* instr() { return instr_; } 5437 virtual LInstruction* instr() { return instr_; }
5410 private: 5438 private:
5411 LTaggedToI* instr_; 5439 LTaggedToI* instr_;
5412 }; 5440 };
5413 5441
5414 LOperand* input = instr->value(); 5442 LOperand* input = instr->value();
5415 ASSERT(input->IsRegister()); 5443 ASSERT(input->IsRegister());
5416 Register input_reg = ToRegister(input); 5444 Register input_reg = ToRegister(input);
5417 ASSERT(input_reg.is(ToRegister(instr->result()))); 5445 ASSERT(input_reg.is(ToRegister(instr->result())));
5418 5446
5419 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); 5447 if (instr->hydrogen()->value()->representation().IsSmi()) {
Toon Verwaest 2013/08/01 11:19:36 This is probably also relevant on other platforms?
5448 __ SmiUntag(input_reg);
5449 } else {
5450 DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr);
5420 5451
5421 __ JumpIfNotSmi(input_reg, deferred->entry()); 5452 __ JumpIfNotSmi(input_reg, deferred->entry());
5422 __ SmiUntag(input_reg); 5453 __ SmiUntag(input_reg);
5423 __ bind(deferred->exit()); 5454 __ bind(deferred->exit());
5455 }
5424 } 5456 }
5425 5457
5426 5458
5427 void LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) { 5459 void LCodeGen::DoDeferredTaggedToINoSSE2(LTaggedToINoSSE2* instr) {
5428 Label done, heap_number; 5460 Label done, heap_number;
5429 Register result_reg = ToRegister(instr->result()); 5461 Register result_reg = ToRegister(instr->result());
5430 Register input_reg = ToRegister(instr->value()); 5462 Register input_reg = ToRegister(instr->value());
5431 5463
5432 // Heap number map check. 5464 // Heap number map check.
5433 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset), 5465 __ cmp(FieldOperand(input_reg, HeapObject::kMapOffset),
(...skipping 195 matching lines...) Expand 10 before | Expand all | Expand 10 after
5629 mode); 5661 mode);
5630 } 5662 }
5631 } 5663 }
5632 5664
5633 5665
5634 void LCodeGen::DoDoubleToI(LDoubleToI* instr) { 5666 void LCodeGen::DoDoubleToI(LDoubleToI* instr) {
5635 LOperand* input = instr->value(); 5667 LOperand* input = instr->value();
5636 ASSERT(input->IsDoubleRegister()); 5668 ASSERT(input->IsDoubleRegister());
5637 LOperand* result = instr->result(); 5669 LOperand* result = instr->result();
5638 ASSERT(result->IsRegister()); 5670 ASSERT(result->IsRegister());
5639 CpuFeatureScope scope(masm(), SSE2);
5640
5641 XMMRegister input_reg = ToDoubleRegister(input);
5642 Register result_reg = ToRegister(result); 5671 Register result_reg = ToRegister(result);
5643 5672
5644 __ cvttsd2si(result_reg, Operand(input_reg)); 5673 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5674 CpuFeatureScope scope(masm(), SSE2);
5645 5675
5646 if (instr->truncating()) { 5676 XMMRegister input_reg = ToDoubleRegister(input);
5647 // Performs a truncating conversion of a floating point number as used by 5677
5648 // the JS bitwise operations. 5678 __ cvttsd2si(result_reg, Operand(input_reg));
5649 Label fast_case_succeeded; 5679
5650 __ cmp(result_reg, 0x80000000u); 5680 if (instr->truncating()) {
5651 __ j(not_equal, &fast_case_succeeded); 5681 // Performs a truncating conversion of a floating point number as used by
5652 __ sub(esp, Immediate(kDoubleSize)); 5682 // the JS bitwise operations.
5653 __ movdbl(MemOperand(esp, 0), input_reg); 5683 Label fast_case_succeeded;
5654 DoubleToIStub stub(esp, result_reg, 0, true); 5684 __ cmp(result_reg, 0x80000000u);
5655 __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET); 5685 __ j(not_equal, &fast_case_succeeded);
5656 __ add(esp, Immediate(kDoubleSize)); 5686 __ sub(esp, Immediate(kDoubleSize));
5657 __ bind(&fast_case_succeeded); 5687 __ movdbl(MemOperand(esp, 0), input_reg);
5688 DoubleToIStub stub(esp, result_reg, 0, true);
5689 __ call(stub.GetCode(isolate()), RelocInfo::CODE_TARGET);
5690 __ add(esp, Immediate(kDoubleSize));
5691 __ bind(&fast_case_succeeded);
5692 } else {
5693 Label done;
5694 __ cvtsi2sd(xmm0, Operand(result_reg));
5695 __ ucomisd(xmm0, input_reg);
5696 DeoptimizeIf(not_equal, instr->environment());
5697 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5698 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5699 // The integer converted back is equal to the original. We
5700 // only have to test if we got -0 as an input.
5701 __ test(result_reg, Operand(result_reg));
5702 __ j(not_zero, &done, Label::kNear);
5703 __ movmskpd(result_reg, input_reg);
5704 // Bit 0 contains the sign of the double in input_reg.
5705 // If input was positive, we are ok and return 0, otherwise
5706 // deoptimize.
5707 __ and_(result_reg, 1);
5708 DeoptimizeIf(not_zero, instr->environment());
5709 }
5710 __ bind(&done);
Toon Verwaest 2013/08/01 11:19:36 Make the done label available in the top-level sco
5711 }
5658 } else { 5712 } else {
5713 X87Register input_reg = ToX87Register(input);
5714 __ push(result_reg);
5715 X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
5716 if (instr->truncating()) {
5717 __ pop(result_reg);
5718 } else {
5719 X87Fxch(input_reg);
5720 __ fld(0);
5721 __ fild_s(Operand(esp, 0));
5722 __ pop(result_reg);
5723 __ FCmp();
5724 DeoptimizeIf(not_equal, instr->environment());
5725 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5726 }
5727 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5728 Label done;
5729 __ test(result_reg, Operand(result_reg));
5730 __ j(not_zero, &done, Label::kNear);
5731 X87Fxch(input_reg);
5732 // Check if 1/result is + or - inf
5733 __ fld1();
5734 __ fld(1);
5735 __ fdivp();
5736 __ fldz();
5737 __ FCmp();
5738 DeoptimizeIf(greater, instr->environment());
5739 __ bind(&done);
5740 }
5741 }
5742 }
5743
5744
5745 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) {
5746 LOperand* input = instr->value();
5747 ASSERT(input->IsDoubleRegister());
5748 LOperand* result = instr->result();
5749 ASSERT(result->IsRegister());
5750 Register result_reg = ToRegister(result);
5751
5752 if (CpuFeatures::IsSafeForSnapshot(SSE2)) {
5753 CpuFeatureScope scope(masm(), SSE2);
5754
5755 XMMRegister input_reg = ToDoubleRegister(input);
5756
5659 Label done; 5757 Label done;
5758 __ cvttsd2si(result_reg, Operand(input_reg));
5660 __ cvtsi2sd(xmm0, Operand(result_reg)); 5759 __ cvtsi2sd(xmm0, Operand(result_reg));
5661 __ ucomisd(xmm0, input_reg); 5760 __ ucomisd(xmm0, input_reg);
5662 DeoptimizeIf(not_equal, instr->environment()); 5761 DeoptimizeIf(not_equal, instr->environment());
5663 DeoptimizeIf(parity_even, instr->environment()); // NaN. 5762 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5664 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) { 5763 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5665 // The integer converted back is equal to the original. We 5764 // The integer converted back is equal to the original. We
5666 // only have to test if we got -0 as an input. 5765 // only have to test if we got -0 as an input.
5667 __ test(result_reg, Operand(result_reg)); 5766 __ test(result_reg, Operand(result_reg));
5668 __ j(not_zero, &done, Label::kNear); 5767 __ j(not_zero, &done, Label::kNear);
5669 __ movmskpd(result_reg, input_reg); 5768 __ movmskpd(result_reg, input_reg);
5670 // Bit 0 contains the sign of the double in input_reg. 5769 // Bit 0 contains the sign of the double in input_reg.
5671 // If input was positive, we are ok and return 0, otherwise 5770 // If input was positive, we are ok and return 0, otherwise
5672 // deoptimize. 5771 // deoptimize.
5673 __ and_(result_reg, 1); 5772 __ and_(result_reg, 1);
5674 DeoptimizeIf(not_zero, instr->environment()); 5773 DeoptimizeIf(not_zero, instr->environment());
5774 __ bind(&done);
5675 } 5775 }
5676 __ bind(&done); 5776 } else {
5677 } 5777 X87Register input_reg = ToX87Register(input);
5678 } 5778 X87Fxch(input_reg);
5779 __ push(result_reg);
5780 X87Mov(Operand(esp, 0), input_reg, kX87IntOperand);
5781 __ fld(0);
5782 __ fild_s(Operand(esp, 0));
5783 __ pop(result_reg);
5784 __ FCmp();
5785 DeoptimizeIf(not_equal, instr->environment());
5786 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5679 5787
5680 5788 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5681 void LCodeGen::DoDoubleToSmi(LDoubleToSmi* instr) { 5789 Label done;
5682 LOperand* input = instr->value(); 5790 __ test(result_reg, Operand(result_reg));
5683 ASSERT(input->IsDoubleRegister()); 5791 __ j(not_zero, &done, Label::kNear);
5684 LOperand* result = instr->result(); 5792 // Check if 1/result is + or - inf
5685 ASSERT(result->IsRegister()); 5793 __ fld1();
5686 CpuFeatureScope scope(masm(), SSE2); 5794 __ fld(1);
5687 5795 __ fdivp();
5688 XMMRegister input_reg = ToDoubleRegister(input); 5796 __ fldz();
5689 Register result_reg = ToRegister(result); 5797 __ FCmp();
5690 5798 DeoptimizeIf(greater, instr->environment());
5691 Label done; 5799 __ bind(&done);
5692 __ cvttsd2si(result_reg, Operand(input_reg)); 5800 }
5693 __ cvtsi2sd(xmm0, Operand(result_reg));
5694 __ ucomisd(xmm0, input_reg);
5695 DeoptimizeIf(not_equal, instr->environment());
5696 DeoptimizeIf(parity_even, instr->environment()); // NaN.
5697
5698 if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
5699 // The integer converted back is equal to the original. We
5700 // only have to test if we got -0 as an input.
5701 __ test(result_reg, Operand(result_reg));
5702 __ j(not_zero, &done, Label::kNear);
5703 __ movmskpd(result_reg, input_reg);
5704 // Bit 0 contains the sign of the double in input_reg.
5705 // If input was positive, we are ok and return 0, otherwise
5706 // deoptimize.
5707 __ and_(result_reg, 1);
5708 DeoptimizeIf(not_zero, instr->environment());
5709 __ bind(&done);
5710 } 5801 }
5711 __ SmiTag(result_reg); 5802 __ SmiTag(result_reg);
5712 DeoptimizeIf(overflow, instr->environment()); 5803 DeoptimizeIf(overflow, instr->environment());
5713 } 5804 }
5714 5805
5715 5806
5716 void LCodeGen::DoCheckSmi(LCheckSmi* instr) { 5807 void LCodeGen::DoCheckSmi(LCheckSmi* instr) {
5717 LOperand* input = instr->value(); 5808 LOperand* input = instr->value();
5718 __ test(ToOperand(input), Immediate(kSmiTagMask)); 5809 __ test(ToOperand(input), Immediate(kSmiTagMask));
5719 DeoptimizeIf(not_zero, instr->environment()); 5810 DeoptimizeIf(not_zero, instr->environment());
(...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after
6506 FixedArray::kHeaderSize - kPointerSize)); 6597 FixedArray::kHeaderSize - kPointerSize));
6507 __ bind(&done); 6598 __ bind(&done);
6508 } 6599 }
6509 6600
6510 6601
6511 #undef __ 6602 #undef __
6512 6603
6513 } } // namespace v8::internal 6604 } } // namespace v8::internal
6514 6605
6515 #endif // V8_TARGET_ARCH_IA32 6606 #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