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

Unified Diff: src/x64/lithium-codegen-x64.cc

Issue 6368097: X64 Crankshaft: Port TaggedToI to X64. (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: Created 9 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/x64/disasm-x64.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/x64/lithium-codegen-x64.cc
===================================================================
--- src/x64/lithium-codegen-x64.cc (revision 6635)
+++ src/x64/lithium-codegen-x64.cc (working copy)
@@ -1954,13 +1954,108 @@
}
+class DeferredTaggedToI: public LDeferredCode {
+ public:
+ DeferredTaggedToI(LCodeGen* codegen, LTaggedToI* instr)
+ : LDeferredCode(codegen), instr_(instr) { }
+ virtual void Generate() { codegen()->DoDeferredTaggedToI(instr_); }
+ private:
+ LTaggedToI* instr_;
+};
+
+
void LCodeGen::DoDeferredTaggedToI(LTaggedToI* instr) {
- Abort("Unimplemented: %s", "DoDeferredTaggedToI");
+ NearLabel done, heap_number;
+ Register input_reg = ToRegister(instr->InputAt(0));
+
+ // Heap number map check.
+ __ CompareRoot(FieldOperand(input_reg, HeapObject::kMapOffset),
+ Heap::kHeapNumberMapRootIndex);
Lasse Reichstein 2011/02/04 12:57:55 indentation.
William Hesse 2011/02/04 13:16:39 Done.
+
+ if (instr->truncating()) {
+ __ j(equal, &heap_number);
+ // Check for undefined. Undefined is converted to zero for truncating
+ // conversions.
+ __ CompareRoot(input_reg, Heap::kUndefinedValueRootIndex);
+ DeoptimizeIf(not_equal, instr->environment());
+ __ movl(input_reg, Immediate(0));
+ __ jmp(&done);
+
+ __ bind(&heap_number);
+ if (CpuFeatures::IsSupported(SSE3)) {
+ CpuFeatures::Scope scope(SSE3);
Lasse Reichstein 2011/02/04 12:57:55 Fisttp isn't any "more powerful" than cvttsd2si in
William Hesse 2011/02/04 13:16:39 Done.
+ NearLabel convert;
+ // Use more powerful conversion when sse3 is available.
+ // Load x87 register with heap number.
+ __ fld_d(FieldOperand(input_reg, HeapNumber::kValueOffset));
+ // Get exponent alone and check for too-big exponent.
+ __ movl(input_reg, FieldOperand(input_reg, HeapNumber::kExponentOffset));
+ __ andl(input_reg, Immediate(HeapNumber::kExponentMask));
+ const uint32_t kTooBigExponent =
+ (HeapNumber::kExponentBias + 63) << HeapNumber::kExponentShift;
+ __ cmpl(input_reg, Immediate(kTooBigExponent));
+ __ j(less, &convert);
+ // Pop FPU stack before deoptimizing.
+ __ ffree(0);
+ __ fincstp();
Lasse Reichstein 2011/02/04 12:57:55 Use __ fstp(0); to drop the top of the FPU stack
William Hesse 2011/02/04 13:16:39 Entire block of code deleted. On 2011/02/04 12:57:
+ DeoptimizeIf(no_condition, instr->environment());
+
+ // Reserve space for 64 bit answer.
+ __ bind(&convert);
+ __ subq(rsp, Immediate(kDoubleSize));
+ // Do conversion, which cannot fail because we checked the exponent.
+ __ fisttp_d(Operand(rsp, 0));
+ __ movl(input_reg, Operand(rsp, 0)); // Low word of answer is the result.
+ __ addq(rsp, Immediate(kDoubleSize));
+ } else {
+ NearLabel deopt;
+ XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
+ __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ __ cvttsd2si(input_reg, xmm0);
Lasse Reichstein 2011/02/04 12:57:55 Use the 64-bit version and compare to 0x8000000000
William Hesse 2011/02/04 13:16:39 Done.
+ __ cmpl(input_reg, Immediate(0x80000000u));
+ __ j(not_equal, &done);
+ // Check if the input was 0x8000000 (kMinInt).
+ // If no, then we got an overflow and we deoptimize.
+ ExternalReference min_int = ExternalReference::address_of_min_int();
+ __ movq(kScratchRegister, min_int);
+ __ movsd(xmm_temp, Operand(kScratchRegister, 0));
+ __ ucomisd(xmm_temp, xmm0);
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ }
+ } else {
+ // Deoptimize if we don't have a heap number.
+ DeoptimizeIf(not_equal, instr->environment());
+
+ XMMRegister xmm_temp = ToDoubleRegister(instr->TempAt(0));
+ __ movsd(xmm0, FieldOperand(input_reg, HeapNumber::kValueOffset));
+ __ cvttsd2si(input_reg, xmm0);
+ __ cvtlsi2sd(xmm_temp, input_reg);
+ __ ucomisd(xmm0, xmm_temp);
+ DeoptimizeIf(not_equal, instr->environment());
+ DeoptimizeIf(parity_even, instr->environment()); // NaN.
+ if (instr->hydrogen()->CheckFlag(HValue::kBailoutOnMinusZero)) {
+ __ testl(input_reg, input_reg);
+ __ j(not_zero, &done);
+ __ movmskpd(input_reg, xmm0);
+ __ andl(input_reg, Immediate(1));
+ DeoptimizeIf(not_zero, instr->environment());
+ }
+ }
+ __ bind(&done);
}
void LCodeGen::DoTaggedToI(LTaggedToI* instr) {
- Abort("Unimplemented: %s", "DoTaggedToI");
+ LOperand* input = instr->InputAt(0);
+ ASSERT(input->IsRegister());
+ ASSERT(input->Equals(instr->result()));
+
+ Register input_reg = ToRegister(input);
+ DeferredTaggedToI* deferred = new DeferredTaggedToI(this, instr);
+ __ JumpIfNotSmi(input_reg, deferred->entry());
+ __ SmiToInteger32(input_reg, input_reg);
+ __ bind(deferred->exit());
}
@@ -2217,7 +2312,6 @@
void LCodeGen::DoStackCheck(LStackCheck* instr) {
// Perform stack overflow check.
NearLabel done;
- ExternalReference stack_limit = ExternalReference::address_of_stack_limit();
__ CompareRoot(rsp, Heap::kStackLimitRootIndex);
__ j(above_equal, &done);
« no previous file with comments | « src/x64/disasm-x64.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698