Reviewers: ulan, jochen,
Description:
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=
Please review this at https://codereview.chromium.org/173663002/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files (+29, -31 lines):
M src/a64/code-stubs-a64.cc
M src/a64/lithium-codegen-a64.cc
M src/a64/macro-assembler-a64.h
M src/a64/macro-assembler-a64.cc
M test/cctest/test-code-stubs-a64.cc
Index: src/a64/code-stubs-a64.cc
diff --git a/src/a64/code-stubs-a64.cc b/src/a64/code-stubs-a64.cc
index
21bb2f85bb722d0a9f964b01481384d1c5d07434..919d52faa33489bd6de1d12b936f2748e2fdbc70
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));
Index: src/a64/lithium-codegen-a64.cc
diff --git a/src/a64/lithium-codegen-a64.cc b/src/a64/lithium-codegen-a64.cc
index
2052a27c9743e5a5b238d688bae06b619a0c9d28..ace96598a8c1931ee41ef10ba2bc2b72bd6dec5b
100644
--- a/src/a64/lithium-codegen-a64.cc
+++ b/src/a64/lithium-codegen-a64.cc
@@ -5368,17 +5368,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());
}
Index: src/a64/macro-assembler-a64.cc
diff --git a/src/a64/macro-assembler-a64.cc b/src/a64/macro-assembler-a64.cc
index
2d55294b75bf8cb0d462965e6ad2d441a4da145c..b25a269113c6ce11d764f14d2e83fc209ce0db9a
100644
--- a/src/a64/macro-assembler-a64.cc
+++ b/src/a64/macro-assembler-a64.cc
@@ -2806,20 +2806,17 @@ void
MacroAssembler::InvokeFunction(Handle<JSFunction> 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);
Index: src/a64/macro-assembler-a64.h
diff --git a/src/a64/macro-assembler-a64.h b/src/a64/macro-assembler-a64.h
index
7aa08eefa7386977fa2fe5c5af3530afc0704c8b..097d6e94a81f4885fd64e731c9f86ab22e16da43
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.
Index: test/cctest/test-code-stubs-a64.cc
diff --git a/test/cctest/test-code-stubs-a64.cc
b/test/cctest/test-code-stubs-a64.cc
index
9d04cbf944a7fe5128b037d66dc7bb3955d84d2c..7ddefdde14e604e63cfdfc164b47ec50241979d9
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));
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.