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

Unified Diff: src/x64/macro-assembler-x64.cc

Issue 269004: X64: Convert doubles to int32 inline (without calling runtime).
Patch Set: Created 11 years, 2 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
Index: src/x64/macro-assembler-x64.cc
diff --git a/src/x64/macro-assembler-x64.cc b/src/x64/macro-assembler-x64.cc
index 2689e388b6ea6cdff1d9e236df8438922c52ae0a..224b0f4fbe9cf4e69b1fd532c3d8a7b3f4101c76 100644
--- a/src/x64/macro-assembler-x64.cc
+++ b/src/x64/macro-assembler-x64.cc
@@ -255,6 +255,66 @@ void MacroAssembler::NegativeZeroTest(Register result,
}
+void MacroAssembler::DoubleToInteger32(Register dst,
+ Register src,
+ Register scratch) {
+ Label no_bits_in_range, left_shift, apply_sign, positive_sign, done;
+ ASSERT(!src.is(scratch));
+ ASSERT(!src.is(kScratchRegister));
+ ASSERT(!scratch.is(kScratchRegister));
+
+ movq(scratch, src);
+ movq(rcx, src);
+ shr(rcx, Immediate(52)); // Move exponent to bottom of register.
+ andl(rcx, Immediate(0x7ff)); // sign bit be gone.
+ subl(rcx, Immediate(0x3ff)); // bias substracted.
+ // If exponent in range 0..83, there is a significant bit in
+ // the 0..2^32 range.
+ cmpl(rcx, Immediate(52 + 31));
+ j(above, &no_bits_in_range);
+ subl(rcx, Immediate(52));
+ j(greater_equal, &left_shift);
+ // right shift by 52-(e-bias)
+ negl(rcx);
+ shr(scratch);
+ cmpl(rcx, Immediate(20));
+ j(less_equal, &apply_sign);
+
+ // Add implicit leading one.
+ subl(rcx, Immediate(52)); // Get back original exponent.
+ negl(rcx);
+ movl(kScratchRegister, Immediate(1));
+ shll(kScratchRegister);
+ orl(scratch, kScratchRegister);
+ // Mask away exponent and sign bits.
+ addl(kScratchRegister, kScratchRegister);
+ subl(kScratchRegister, Immediate(1));
Lasse Reichstein 2009/10/07 16:54:24 Just noticed that the previous two lines could be
+ andl(scratch, kScratchRegister);
+ jmp(&apply_sign);
+
+ bind(&no_bits_in_range);
+ // All significant digits of the number is either below the
+ // decimal point or at or above 2^32 (or the value is an infinity
+ // or NaN). Return zero in all these cases.
+ xor_(dst, dst);
+ jmp(&done);
+
+ bind(&left_shift);
+ // Shift left by e-bias-52.
+ shll(scratch);
+
+ bind(&apply_sign);
+ testq(src, src);
+ j(positive, &positive_sign);
+ neg(scratch);
+ bind(&positive_sign);
+ if (!dst.is(scratch)) {
+ movl(dst, scratch);
+ }
+ bind(&done);
+}
+
+
void MacroAssembler::Abort(const char* msg) {
// We want to pass the msg string like a smi to avoid GC
// problems, however msg is not guaranteed to be aligned

Powered by Google App Engine
This is Rietveld 408576698