From 0468660b13ddc8e94abd692756c4d2c595af5c1e Mon Sep 17 00:00:00 2001 From: "m.m.capewell@googlemail.com" Date: Fri, 21 Feb 2014 11:36:04 +0000 Subject: [PATCH] A64: Tidy up register use in TaggedToI Fix bug where input register was potentially corrupted, tidy up register use in TruncateDoubleToI and rename TryInlineTruncateDoubleToI. BUG= R=ulan@chromium.org Review URL: https://codereview.chromium.org/173663002 git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@19527 ce2b1a6d-e550-0410-aec6-3dcde31c8c00 --- src/a64/code-stubs-a64.cc | 2 +- src/a64/lithium-codegen-a64.cc | 10 ++-------- src/a64/macro-assembler-a64.cc | 28 +++++++++++++++------------- src/a64/macro-assembler-a64.h | 18 ++++++++++-------- test/cctest/test-code-stubs-a64.cc | 2 +- 5 files changed, 29 insertions(+), 31 deletions(-) diff --git a/src/a64/code-stubs-a64.cc b/src/a64/code-stubs-a64.cc index 21bb2f8..919d52f 100644 --- a/src/a64/code-stubs-a64.cc +++ b/src/a64/code-stubs-a64.cc @@ -565,7 +565,7 @@ void DoubleToIStub::Generate(MacroAssembler* masm) { __ Ldr(double_scratch, MemOperand(input, double_offset)); // Try to convert with a FPU convert instruction. This handles all // non-saturating cases. - __ TryInlineTruncateDoubleToI(result, double_scratch, &done); + __ TryConvertDoubleToInt64(result, double_scratch, &done); __ Fmov(result, double_scratch); } else { __ Ldr(result, MemOperand(input, double_offset)); diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc index 6ee4675..462db00 100644 --- a/src/a64/lithium-codegen-a64.cc +++ b/src/a64/lithium-codegen-a64.cc @@ -5346,17 +5346,11 @@ void LCodeGen::DoTaggedToI(LTaggedToI* instr) { Register output = ToRegister(instr->result()); if (instr->hydrogen()->value()->representation().IsSmi()) { - __ SmiUntag(input); + __ SmiUntag(output, input); } else { DeferredTaggedToI* deferred = new(zone()) DeferredTaggedToI(this, instr); - // TODO(jbramley): We can't use JumpIfNotSmi here because the tbz it uses - // doesn't always have enough range. Consider making a variant of it, or a - // TestIsSmi helper. - STATIC_ASSERT(kSmiTag == 0); - __ Tst(input, kSmiTagMask); - __ B(ne, deferred->entry()); - + __ JumpIfNotSmi(input, deferred->entry()); __ SmiUntag(output, input); __ Bind(deferred->exit()); } diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc index 7f5a0d6..5b979c2 100644 --- a/src/a64/macro-assembler-a64.cc +++ b/src/a64/macro-assembler-a64.cc @@ -2806,20 +2806,17 @@ void MacroAssembler::InvokeFunction(Handle function, } -void MacroAssembler::TryInlineTruncateDoubleToI(Register result, - DoubleRegister double_input, - Label* done) { - STATIC_ASSERT(kSmiTag == 0); - STATIC_ASSERT(kSmiValueSize == 32); - - // Try to convert with a FPU convert instruction. It's trivial to compute +void MacroAssembler::TryConvertDoubleToInt64(Register result, + DoubleRegister double_input, + Label* done) { + // Try to convert with an FPU convert instruction. It's trivial to compute // the modulo operation on an integer register so we convert to a 64-bit - // integer, then find the 32-bit result from that. + // integer. // // Fcvtzs will saturate to INT64_MIN (0x800...00) or INT64_MAX (0x7ff...ff) // when the double is out of range. NaNs and infinities will be converted to 0 // (as ECMA-262 requires). - Fcvtzs(result, double_input); + Fcvtzs(result.X(), double_input); // The values INT64_MIN (0x800...00) or INT64_MAX (0x7ff...ff) are not // representable using a double, so if the result is one of those then we know @@ -2827,8 +2824,8 @@ void MacroAssembler::TryInlineTruncateDoubleToI(Register result, // // It is easy to detect INT64_MIN and INT64_MAX because adding or subtracting // 1 will cause signed overflow. - Cmp(result, 1); - Ccmp(result, -1, VFlag, vc); + Cmp(result.X(), 1); + Ccmp(result.X(), -1, VFlag, vc); B(vc, done); } @@ -2839,7 +2836,9 @@ void MacroAssembler::TruncateDoubleToI(Register result, Label done; ASSERT(jssp.Is(StackPointer())); - TryInlineTruncateDoubleToI(result, double_input, &done); + // Try to convert the double to an int64. If successful, the bottom 32 bits + // contain our truncated int32 result. + TryConvertDoubleToInt64(result, double_input, &done); // If we fell through then inline version didn't succeed - call stub instead. Push(lr); @@ -2870,7 +2869,10 @@ void MacroAssembler::TruncateHeapNumberToI(Register result, ASSERT(jssp.Is(StackPointer())); Ldr(fp_scratch, FieldMemOperand(object, HeapNumber::kValueOffset)); - TryInlineTruncateDoubleToI(result, fp_scratch, &done); + + // Try to convert the double to an int64. If successful, the bottom 32 bits + // contain our truncated int32 result. + TryConvertDoubleToInt64(result, fp_scratch, &done); // If we fell through then inline version didn't succeed - call stub instead. Push(lr); diff --git a/src/a64/macro-assembler-a64.h b/src/a64/macro-assembler-a64.h index abdd7e4..153e4d0 100644 --- a/src/a64/macro-assembler-a64.h +++ b/src/a64/macro-assembler-a64.h @@ -1179,16 +1179,18 @@ class MacroAssembler : public Assembler { // ---- Floating point helpers ---- - - // Performs a truncating conversion of a floating point number as used by - // the JS bitwise operations. See ECMA-262 9.5: ToInt32. Goes to 'done' if it - // succeeds, otherwise falls through if result is saturated. On return - // 'result' either holds answer, or is clobbered on fall through. + // Perform a conversion from a double to a signed int64. If the input fits in + // range of the 64-bit result, execution branches to done. Otherwise, + // execution falls through, and the sign of the result can be used to + // determine if overflow was towards positive or negative infinity. + // + // On successful conversion, the least significant 32 bits of the result are + // equivalent to the ECMA-262 operation "ToInt32". // // Only public for the test code in test-code-stubs-a64.cc. - void TryInlineTruncateDoubleToI(Register result, - DoubleRegister input, - Label* done); + void TryConvertDoubleToInt64(Register result, + DoubleRegister input, + Label* done); // Performs a truncating conversion of a floating point number as used by // the JS bitwise operations. See ECMA-262 9.5: ToInt32. diff --git a/test/cctest/test-code-stubs-a64.cc b/test/cctest/test-code-stubs-a64.cc index 9d04cbf..7ddefdd 100644 --- a/test/cctest/test-code-stubs-a64.cc +++ b/test/cctest/test-code-stubs-a64.cc @@ -87,7 +87,7 @@ ConvertDToIFunc MakeConvertDToIFuncTrampoline(Isolate* isolate, // Call through to the actual stub if (inline_fastpath) { __ Ldr(d0, MemOperand(source_reg)); - __ TryInlineTruncateDoubleToI(destination_reg, d0, &done); + __ TryConvertDoubleToInt64(destination_reg, d0, &done); if (destination_reg.is(source_reg)) { // Restore clobbered source_reg. __ add(source_reg, jssp, Operand(source_reg_offset)); -- 2.7.4