Revision: 21156
Author: [email protected]
Date: Tue May 6 08:05:27 2014 UTC
Log: ARM64: Use default-NaN mode to canonicalize NaNs.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/255343004
http://code.google.com/p/v8/source/detail?r=21156
Modified:
/branches/bleeding_edge/src/arm64/code-stubs-arm64.cc
/branches/bleeding_edge/src/arm64/ic-arm64.cc
/branches/bleeding_edge/src/arm64/lithium-arm64.h
/branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc
/branches/bleeding_edge/src/arm64/macro-assembler-arm64-inl.h
/branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc
/branches/bleeding_edge/src/arm64/macro-assembler-arm64.h
/branches/bleeding_edge/src/objects.h
/branches/bleeding_edge/test/cctest/test-assembler-arm64.cc
=======================================
--- /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc Wed Apr 30
14:33:35 2014 UTC
+++ /branches/bleeding_edge/src/arm64/code-stubs-arm64.cc Tue May 6
08:05:27 2014 UTC
@@ -1577,6 +1577,7 @@
// jssp[8]: Preserved x22 (used for argc).
// jssp[0]: Preserved x21 (used for argv).
__ Drop(x11);
+ __ AssertFPCRState();
__ Ret();
// The stack pointer is still csp if we aren't returning, and the frame
@@ -1660,6 +1661,11 @@
__ Mov(jssp, csp);
__ SetStackPointer(jssp);
+ // Configure the FPCR. We don't restore it, so this is technically not
allowed
+ // according to AAPCS64. However, we only set default-NaN mode and this
will
+ // be harmless for most C code. Also, it works for ARM.
+ __ ConfigureFPCR();
+
ProfileEntryHookStub::MaybeCallEntryHook(masm);
// Set up the reserved register for 0.0.
@@ -4633,7 +4639,7 @@
__ Bind(&double_elements);
__ Ldr(x10, FieldMemOperand(array, JSObject::kElementsOffset));
- __ StoreNumberToDoubleElements(value, index_smi, x10, x11, d0, d1,
+ __ StoreNumberToDoubleElements(value, index_smi, x10, x11, d0,
&slow_elements);
__ Ret();
}
@@ -4735,6 +4741,7 @@
__ Blr(x10);
// Return to calling code.
__ Peek(lr, 0);
+ __ AssertFPCRState();
__ Ret();
__ SetStackPointer(old_stack_pointer);
=======================================
--- /branches/bleeding_edge/src/arm64/ic-arm64.cc Tue Apr 29 06:42:26 2014
UTC
+++ /branches/bleeding_edge/src/arm64/ic-arm64.cc Tue May 6 08:05:27 2014
UTC
@@ -1021,7 +1021,6 @@
elements,
x10,
d0,
- d1,
&transition_double_elements);
if (increment_length == kIncrementLength) {
// Add 1 to receiver->length.
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-arm64.h Mon May 5 11:03:14
2014 UTC
+++ /branches/bleeding_edge/src/arm64/lithium-arm64.h Tue May 6 08:05:27
2014 UTC
@@ -2386,6 +2386,10 @@
}
bool NeedsCanonicalization() {
+ if (hydrogen()->value()->IsAdd() || hydrogen()->value()->IsSub() ||
+ hydrogen()->value()->IsMul() || hydrogen()->value()->IsDiv()) {
+ return false;
+ }
return this->hydrogen()->NeedsCanonicalization();
}
uint32_t additional_index() const { return
this->hydrogen()->index_offset(); }
=======================================
--- /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Tue May 6
07:05:07 2014 UTC
+++ /branches/bleeding_edge/src/arm64/lithium-codegen-arm64.cc Tue May 6
08:05:27 2014 UTC
@@ -5174,11 +5174,8 @@
}
if (instr->NeedsCanonicalization()) {
- DoubleRegister dbl_scratch = double_scratch();
- __ Fmov(dbl_scratch,
- FixedDoubleArray::canonical_not_the_hole_nan_as_double());
- __ Fmaxnm(dbl_scratch, dbl_scratch, value);
- __ Str(dbl_scratch, FieldMemOperand(store_base, offset));
+ __ CanonicalizeNaN(double_scratch(), value);
+ __ Str(double_scratch(), FieldMemOperand(store_base, offset));
} else {
__ Str(value, FieldMemOperand(store_base, offset));
}
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64-inl.h Tue Apr
29 06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64-inl.h Tue May
6 08:05:27 2014 UTC
@@ -977,7 +977,6 @@
void MacroAssembler::Msr(SystemRegister sysreg, const Register& rt) {
ASSERT(allow_macro_instructions_);
- ASSERT(!rt.IsZero());
msr(sysreg, rt);
}
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Wed Apr 30
09:50:58 2014 UTC
+++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.cc Tue May 6
08:05:27 2014 UTC
@@ -1220,6 +1220,64 @@
}
}
}
+
+
+void MacroAssembler::AssertFPCRState(Register fpcr) {
+ if (emit_debug_code()) {
+ Label unexpected_mode, done;
+ UseScratchRegisterScope temps(this);
+ if (fpcr.IsNone()) {
+ fpcr = temps.AcquireX();
+ Mrs(fpcr, FPCR);
+ }
+
+ // Settings overridden by ConfiugreFPCR():
+ // - Assert that default-NaN mode is set.
+ Tbz(fpcr, DN_offset, &unexpected_mode);
+
+ // Settings left to their default values:
+ // - Assert that flush-to-zero is not set.
+ Tbnz(fpcr, FZ_offset, &unexpected_mode);
+ // - Assert that the rounding mode is nearest-with-ties-to-even.
+ STATIC_ASSERT(FPTieEven == 0);
+ Tst(fpcr, RMode_mask);
+ B(eq, &done);
+
+ Bind(&unexpected_mode);
+ Abort(kUnexpectedFPCRMode);
+
+ Bind(&done);
+ }
+}
+
+
+void MacroAssembler::ConfigureFPCR() {
+ UseScratchRegisterScope temps(this);
+ Register fpcr = temps.AcquireX();
+ Mrs(fpcr, FPCR);
+
+ // If necessary, enable default-NaN mode. The default values of the
other FPCR
+ // options should be suitable, and AssertFPCRState will verify that.
+ Label no_write_required;
+ Tbnz(fpcr, DN_offset, &no_write_required);
+
+ Orr(fpcr, fpcr, DN_mask);
+ Msr(FPCR, fpcr);
+
+ Bind(&no_write_required);
+ AssertFPCRState(fpcr);
+}
+
+
+void MacroAssembler::CanonicalizeNaN(const FPRegister& dst,
+ const FPRegister& src) {
+ AssertFPCRState();
+
+ // With DN=1 and RMode=FPTieEven, subtracting 0.0 preserves all inputs
except
+ // for NaNs, which become the default NaN. We use fsub rather than fadd
+ // because sub preserves -0.0 inputs: -0.0 + 0.0 = 0.0, but -0.0 - 0.0 =
-0.0.
+ Fsub(dst, src, fp_zero);
+}
void MacroAssembler::LoadRoot(CPURegister destination,
@@ -3888,7 +3946,6 @@
Register elements_reg,
Register scratch1,
FPRegister fpscratch1,
- FPRegister fpscratch2,
Label* fail,
int elements_offset) {
ASSERT(!AreAliased(value_reg, key_reg, elements_reg, scratch1));
@@ -3906,12 +3963,9 @@
fail, DONT_DO_SMI_CHECK);
Ldr(fpscratch1, FieldMemOperand(value_reg, HeapNumber::kValueOffset));
- Fmov(fpscratch2,
FixedDoubleArray::canonical_not_the_hole_nan_as_double());
- // Check for NaN by comparing the number to itself: NaN comparison will
- // report unordered, indicated by the overflow flag being set.
- Fcmp(fpscratch1, fpscratch1);
- Fcsel(fpscratch1, fpscratch2, fpscratch1, vs);
+ // Canonicalize NaNs.
+ CanonicalizeNaN(fpscratch1);
// Store the result.
Bind(&store_num);
=======================================
--- /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Tue Apr 29
06:42:26 2014 UTC
+++ /branches/bleeding_edge/src/arm64/macro-assembler-arm64.h Tue May 6
08:05:27 2014 UTC
@@ -787,6 +787,13 @@
// Helpers
------------------------------------------------------------------
// Root register.
inline void InitializeRootRegister();
+
+ void AssertFPCRState(Register fpcr = NoReg);
+ void ConfigureFPCR();
+ void CanonicalizeNaN(const FPRegister& dst, const FPRegister& src);
+ void CanonicalizeNaN(const FPRegister& reg) {
+ CanonicalizeNaN(reg, reg);
+ }
// Load an object from the root table.
void LoadRoot(CPURegister destination,
@@ -1533,7 +1540,6 @@
Register elements_reg,
Register scratch1,
FPRegister fpscratch1,
- FPRegister fpscratch2,
Label* fail,
int elements_offset = 0);
=======================================
--- /branches/bleeding_edge/src/objects.h Mon May 5 18:27:57 2014 UTC
+++ /branches/bleeding_edge/src/objects.h Tue May 6 08:05:27 2014 UTC
@@ -1291,6 +1291,7 @@
V(kUnexpectedNegativeValue, "Unexpected negative
value") \
V(kUnexpectedNumberOfPreAllocatedPropertyFields,
\
"Unexpected number of pre-allocated property
fields") \
+ V(kUnexpectedFPCRMode, "Unexpected FPCR
mode.") \
V(kUnexpectedSmi, "Unexpected smi
value") \
V(kUnexpectedStringFunction, "Unexpected String
function") \
V(kUnexpectedStringType, "Unexpected string
type") \
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-arm64.cc Tue Apr 29
10:58:16 2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-assembler-arm64.cc Tue May 6
08:05:27 2014 UTC
@@ -177,7 +177,11 @@
CpuFeatures::Probe(false);
#define
RESET() \
- __ Reset();
+ __
Reset(); \
+ /* Reset the machine state (like simulator.ResetState()).
*/ \
+ __ Msr(NZCV,
xzr); \
+ __ Msr(FPCR, xzr);
+
#define
START_AFTER_RESET() \
__
SetStackPointer(csp); \
--
--
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/d/optout.