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

Side by Side Diff: src/ia32/macro-assembler-ia32.cc

Issue 1584663007: [turbofan] Implement rounding of floats on x64 and ia32 without sse4.1. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: reduced generated code. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/snapshot/serialize.cc » ('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 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #if V8_TARGET_ARCH_IA32 5 #if V8_TARGET_ARCH_IA32
6 6
7 #include "src/base/bits.h" 7 #include "src/base/bits.h"
8 #include "src/base/division-by-constant.h" 8 #include "src/base/division-by-constant.h"
9 #include "src/bootstrapper.h" 9 #include "src/bootstrapper.h"
10 #include "src/codegen.h" 10 #include "src/codegen.h"
(...skipping 563 matching lines...) Expand 10 before | Expand all | Expand 10 after
574 574
575 void MacroAssembler::DebugBreak() { 575 void MacroAssembler::DebugBreak() {
576 Move(eax, Immediate(0)); 576 Move(eax, Immediate(0));
577 mov(ebx, Immediate(ExternalReference(Runtime::kHandleDebuggerStatement, 577 mov(ebx, Immediate(ExternalReference(Runtime::kHandleDebuggerStatement,
578 isolate()))); 578 isolate())));
579 CEntryStub ces(isolate(), 1); 579 CEntryStub ces(isolate(), 1);
580 call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT); 580 call(ces.GetCode(), RelocInfo::DEBUGGER_STATEMENT);
581 } 581 }
582 582
583 583
584 void MacroAssembler::Cvtsi2ss(XMMRegister dst, const Operand& src) {
585 xorps(dst, dst);
586 cvtsi2ss(dst, src);
587 }
588
589
584 void MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) { 590 void MacroAssembler::Cvtsi2sd(XMMRegister dst, const Operand& src) {
585 xorps(dst, dst); 591 xorps(dst, dst);
586 cvtsi2sd(dst, src); 592 cvtsi2sd(dst, src);
587 } 593 }
588 594
589 595
596 void MacroAssembler::Roundss(XMMRegister dst, XMMRegister src, Register tmp,
597 XMMRegister xtmp, RoundingMode mode) {
598 if (CpuFeatures::IsSupported(SSE4_1)) {
599 CpuFeatureScope sse_scope(this, SSE4_1);
600 roundss(dst, src, mode);
601 } else {
602 // We have to store the original rounding mode to restore it later.
603 {
604 sub(esp, Immediate(kPointerSize * 2));
605 stmxcsr(Operand(esp, 0));
606 mov(tmp, Operand(esp, 0));
607 and_(tmp, Immediate(0xffff9fff));
608 or_(tmp, Immediate(mode << 13));
609 mov(Operand(esp, kPointerSize), tmp);
610 ldmxcsr(Operand(esp, kPointerSize));
611 }
612
613 // Do rounding by conversion to int.
614 cvtss2si(tmp, src);
615
616 Label out_of_range;
617 Label done;
618 // Check whether the input is within int32 range.
619 cmp(tmp, Immediate(1));
620 j(overflow, &out_of_range);
621 // Saving the sign bit.
622 // Initialize xtmp with 0x80000000.
623 pcmpeqd(xtmp, xtmp);
624 pslld(xtmp, 31);
625 andps(xtmp, src);
626 // If the conversion results in INT_MIN, then the input is outside
627 // int range, and due to the limited precision of float32 this means
628 // that the input must have been an integer already. We are therefore
629 // done already.
630 cvtsi2ss(dst, tmp);
631 // Restore the sign bit.
632 orps(dst, xtmp);
633
634 if (!dst.is(src)) {
635 jmp(&done);
636 }
637
638 bind(&out_of_range);
639 if (!dst.is(src)) {
640 movss(dst, src);
641 }
642
643 bind(&done);
644 // Restore the original rounding mode.
645 ldmxcsr(Operand(esp, 0));
646 add(esp, Immediate(kPointerSize * 2));
647 }
648 }
649
650
651 void MacroAssembler::Roundsd(XMMRegister dst, XMMRegister src, Register tmp,
652 XMMRegister xtmp, RoundingMode mode) {
653 if (CpuFeatures::IsSupported(SSE4_1)) {
654 CpuFeatureScope sse_scope(this, SSE4_1);
655 roundsd(dst, src, mode);
656 } else {
657 // We have to store the original rounding mode to restore it later.
658 {
659 sub(esp, Immediate(kPointerSize * 2));
660 stmxcsr(Operand(esp, 0));
661 mov(tmp, Operand(esp, 0));
662 and_(tmp, Immediate(0xffff9fff));
663 or_(tmp, Immediate(mode << 13));
664 mov(Operand(esp, kPointerSize), tmp);
665 ldmxcsr(Operand(esp, kPointerSize));
666 }
667
668 // Convert the input to int32.
669 cvtsd2si(tmp, src);
670
671 Label out_of_range;
672 Label done;
673 // Check whether the input is within int32 range.
674 cmp(tmp, Immediate(1));
675 j(overflow, &out_of_range);
676 // Saving the sign bit.
677 // Initialize xtmp with 0x8000000000000000.
678 pcmpeqd(xtmp, xtmp);
679 psllq(xtmp, 63);
680 andpd(xtmp, src);
681 // The input is within int32 range. We achieve rounding by converting
682 // back to float.
683 Cvtsi2sd(dst, tmp);
684 // Restore the sign bit.
685 orpd(dst, xtmp);
686 jmp(&done);
687
688 bind(&out_of_range);
689 if (!dst.is(src)) {
690 movsd(dst, src);
691 }
692
693 // xtmp=abs(src)
694 pcmpeqd(xtmp, xtmp);
695 psrlq(xtmp, 1);
696 andpd(xtmp, src);
697
698 // If abs(src) >= 2^52, then float64 precision guarantees that the input is
699 // an integer already.
700 ucomisd(xtmp, Operand::StaticVariable(
701 ExternalReference::address_of_rounding_limit()));
702 j(above_equal, &done);
703
704 // If abs(src) != src, then src contains a negative number. For negative
705 // numbers we calculate src - 2^52 + 2^52 instead of src + 2^52 - 2^52.
706 ucomisd(xtmp, src);
707
708 movsd(xtmp, Operand::StaticVariable(
709 ExternalReference::address_of_rounding_limit()));
710
711 Label below_zero;
712 j(not_equal, &below_zero);
713
714 addsd(dst, xtmp);
715 subsd(dst, xtmp);
716 jmp(&done);
717
718 bind(&below_zero);
719 subsd(dst, xtmp);
720 addsd(dst, xtmp);
721
722 bind(&done);
723 // Restore the original rounding mode.
724 ldmxcsr(Operand(esp, 0));
725 add(esp, Immediate(kPointerSize * 2));
726 }
727 }
728
729
590 bool MacroAssembler::IsUnsafeImmediate(const Immediate& x) { 730 bool MacroAssembler::IsUnsafeImmediate(const Immediate& x) {
591 static const int kMaxImmediateBits = 17; 731 static const int kMaxImmediateBits = 17;
592 if (!RelocInfo::IsNone(x.rmode_)) return false; 732 if (!RelocInfo::IsNone(x.rmode_)) return false;
593 return !is_intn(x.x_, kMaxImmediateBits); 733 return !is_intn(x.x_, kMaxImmediateBits);
594 } 734 }
595 735
596 736
597 void MacroAssembler::SafeMove(Register dst, const Immediate& x) { 737 void MacroAssembler::SafeMove(Register dst, const Immediate& x) {
598 if (IsUnsafeImmediate(x) && jit_cookie() != 0) { 738 if (IsUnsafeImmediate(x) && jit_cookie() != 0) {
599 Move(dst, Immediate(x.x_ ^ jit_cookie())); 739 Move(dst, Immediate(x.x_ ^ jit_cookie()));
(...skipping 2516 matching lines...) Expand 10 before | Expand all | Expand 10 after
3116 mov(eax, dividend); 3256 mov(eax, dividend);
3117 shr(eax, 31); 3257 shr(eax, 31);
3118 add(edx, eax); 3258 add(edx, eax);
3119 } 3259 }
3120 3260
3121 3261
3122 } // namespace internal 3262 } // namespace internal
3123 } // namespace v8 3263 } // namespace v8
3124 3264
3125 #endif // V8_TARGET_ARCH_IA32 3265 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.h ('k') | src/snapshot/serialize.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698