Revision: 19885
Author: [email protected]
Date: Thu Mar 13 09:45:02 2014 UTC
Log: A64: Fix Fmov with signalling NaN literals.
BUG=
[email protected]
Review URL: https://codereview.chromium.org/194753002
http://code.google.com/p/v8/source/detail?r=19885
Modified:
/branches/bleeding_edge/src/a64/assembler-a64.cc
/branches/bleeding_edge/src/a64/assembler-a64.h
/branches/bleeding_edge/src/a64/macro-assembler-a64-inl.h
/branches/bleeding_edge/src/a64/macro-assembler-a64.h
/branches/bleeding_edge/test/cctest/test-assembler-a64.cc
/branches/bleeding_edge/test/cctest/test-disasm-a64.cc
=======================================
--- /branches/bleeding_edge/src/a64/assembler-a64.cc Wed Mar 12 15:40:41
2014 UTC
+++ /branches/bleeding_edge/src/a64/assembler-a64.cc Thu Mar 13 09:45:02
2014 UTC
@@ -1419,18 +1419,26 @@
void Assembler::ldr(const Register& rt, uint64_t imm) {
// TODO(all): Constant pool may be garbage collected. Hence we cannot
store
- // TODO(all): arbitrary values in them. Manually move it for now.
- // TODO(all): Fix MacroAssembler::Fmov when this is implemented.
+ // arbitrary values in them. Manually move it for now. Fix
+ // MacroAssembler::Fmov when this is implemented.
UNIMPLEMENTED();
}
void Assembler::ldr(const FPRegister& ft, double imm) {
// TODO(all): Constant pool may be garbage collected. Hence we cannot
store
- // TODO(all): arbitrary values in them. Manually move it for now.
- // TODO(all): Fix MacroAssembler::Fmov when this is implemented.
+ // arbitrary values in them. Manually move it for now. Fix
+ // MacroAssembler::Fmov when this is implemented.
UNIMPLEMENTED();
}
+
+
+void Assembler::ldr(const FPRegister& ft, float imm) {
+ // TODO(all): Constant pool may be garbage collected. Hence we cannot
store
+ // arbitrary values in them. Manually move it for now. Fix
+ // MacroAssembler::Fmov when this is implemented.
+ UNIMPLEMENTED();
+}
void Assembler::mov(const Register& rd, const Register& rm) {
@@ -1483,16 +1491,16 @@
void Assembler::fmov(FPRegister fd, double imm) {
- if (fd.Is64Bits() && IsImmFP64(imm)) {
- Emit(FMOV_d_imm | Rd(fd) | ImmFP64(imm));
- } else if (fd.Is32Bits() && IsImmFP32(imm)) {
- Emit(FMOV_s_imm | Rd(fd) | ImmFP32(static_cast<float>(imm)));
- } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
- Register zr = AppropriateZeroRegFor(fd);
- fmov(fd, zr);
- } else {
- ldr(fd, imm);
- }
+ ASSERT(fd.Is64Bits());
+ ASSERT(IsImmFP64(imm));
+ Emit(FMOV_d_imm | Rd(fd) | ImmFP64(imm));
+}
+
+
+void Assembler::fmov(FPRegister fd, float imm) {
+ ASSERT(fd.Is32Bits());
+ ASSERT(IsImmFP32(imm));
+ Emit(FMOV_s_imm | Rd(fd) | ImmFP32(imm));
}
=======================================
--- /branches/bleeding_edge/src/a64/assembler-a64.h Wed Mar 12 15:40:41
2014 UTC
+++ /branches/bleeding_edge/src/a64/assembler-a64.h Thu Mar 13 09:45:02
2014 UTC
@@ -1418,6 +1418,7 @@
// Load literal to FP register.
void ldr(const FPRegister& ft, double imm);
+ void ldr(const FPRegister& ft, float imm);
// Move instructions. The default shift of -1 indicates that the move
// instruction will calculate an appropriate 16-bit immediate and left
shift
@@ -1496,6 +1497,7 @@
// FP instructions.
// Move immediate to FP register.
void fmov(FPRegister fd, double imm);
+ void fmov(FPRegister fd, float imm);
// Move FP register to register.
void fmov(Register rd, FPRegister fn);
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64-inl.h Wed Mar 12
15:18:40 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64-inl.h Thu Mar 13
09:45:02 2014 UTC
@@ -737,26 +737,44 @@
void MacroAssembler::Fmov(FPRegister fd, double imm) {
ASSERT(allow_macro_instructions_);
- if ((fd.Is64Bits() && IsImmFP64(imm)) ||
- (fd.Is32Bits() && IsImmFP32(imm)) ||
- ((imm == 0.0) && (copysign(1.0, imm) == 1.0))) {
- // These cases can be handled by the Assembler.
+ if (fd.Is32Bits()) {
+ Fmov(fd, static_cast<float>(imm));
+ return;
+ }
+
+ ASSERT(fd.Is64Bits());
+ if (IsImmFP64(imm)) {
fmov(fd, imm);
+ } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
+ fmov(fd, xzr);
} else {
UseScratchRegisterScope temps(this);
- // TODO(all): The Assembler would try to relocate the immediate with
- // Assembler::ldr(const FPRegister& ft, double imm) but it is not
- // implemented yet.
- if (fd.SizeInBits() == kDRegSizeInBits) {
- Register tmp = temps.AcquireX();
- Mov(tmp, double_to_rawbits(imm));
- Fmov(fd, tmp);
- } else {
- ASSERT(fd.SizeInBits() == kSRegSizeInBits);
- Register tmp = temps.AcquireW();
- Mov(tmp, float_to_rawbits(static_cast<float>(imm)));
- Fmov(fd, tmp);
- }
+ Register tmp = temps.AcquireX();
+ // TODO(all): Use Assembler::ldr(const FPRegister& ft, double imm).
+ Mov(tmp, double_to_rawbits(imm));
+ Fmov(fd, tmp);
+ }
+}
+
+
+void MacroAssembler::Fmov(FPRegister fd, float imm) {
+ ASSERT(allow_macro_instructions_);
+ if (fd.Is64Bits()) {
+ Fmov(fd, static_cast<double>(imm));
+ return;
+ }
+
+ ASSERT(fd.Is32Bits());
+ if (IsImmFP32(imm)) {
+ fmov(fd, imm);
+ } else if ((imm == 0.0) && (copysign(1.0, imm) == 1.0)) {
+ fmov(fd, wzr);
+ } else {
+ UseScratchRegisterScope temps(this);
+ Register tmp = temps.AcquireW();
+ // TODO(all): Use Assembler::ldr(const FPRegister& ft, float imm).
+ Mov(tmp, float_to_rawbits(imm));
+ Fmov(fd, tmp);
}
}
=======================================
--- /branches/bleeding_edge/src/a64/macro-assembler-a64.h Wed Mar 12
15:18:40 2014 UTC
+++ /branches/bleeding_edge/src/a64/macro-assembler-a64.h Thu Mar 13
09:45:02 2014 UTC
@@ -357,7 +357,18 @@
const FPRegister& fm);
inline void Fmov(FPRegister fd, FPRegister fn);
inline void Fmov(FPRegister fd, Register rn);
+ // Provide explicit double and float interfaces for FP immediate moves,
rather
+ // than relying on implicit C++ casts. This allows signalling NaNs to be
+ // preserved when the immediate matches the format of fd. Most systems
convert
+ // signalling NaNs to quiet NaNs when converting between float and
double.
inline void Fmov(FPRegister fd, double imm);
+ inline void Fmov(FPRegister fd, float imm);
+ // Provide a template to allow other types to be converted automatically.
+ template<typename T>
+ void Fmov(FPRegister fd, T imm) {
+ ASSERT(allow_macro_instructions_);
+ Fmov(fd, static_cast<double>(imm));
+ }
inline void Fmov(Register rd, FPRegister fn);
inline void Fmsub(const FPRegister& fd,
const FPRegister& fn,
@@ -394,7 +405,12 @@
inline void Ldpsw(const Register& rt,
const Register& rt2,
const MemOperand& src);
+ // Provide both double and float interfaces for FP immediate loads,
rather
+ // than relying on implicit C++ casts. This allows signalling NaNs to be
+ // preserved when the immediate matches the format of fd. Most systems
convert
+ // signalling NaNs to quiet NaNs when converting between float and
double.
inline void Ldr(const FPRegister& ft, double imm);
+ inline void Ldr(const FPRegister& ft, float imm);
inline void Ldr(const Register& rt, uint64_t imm);
inline void Lsl(const Register& rd, const Register& rn, unsigned shift);
inline void Lsl(const Register& rd, const Register& rn, const Register&
rm);
=======================================
--- /branches/bleeding_edge/test/cctest/test-assembler-a64.cc Wed Mar 12
15:40:41 2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-assembler-a64.cc Thu Mar 13
09:45:02 2014 UTC
@@ -5473,14 +5473,8 @@
SETUP();
START();
- // TODO(all): Signalling NaNs are sometimes converted by the C compiler
to
- // quiet NaNs on implicit casts from float to double. Here, we move the
raw
- // bits into a W register first, so we get the correct value. Fix Fmov
so this
- // additional step is no longer needed.
- __ Mov(w0, float_to_rawbits(n));
- __ Fmov(s0, w0);
- __ Mov(w0, float_to_rawbits(m));
- __ Fmov(s1, w0);
+ __ Fmov(s0, n);
+ __ Fmov(s1, m);
__ Fmin(s28, s0, s1);
__ Fmax(s29, s0, s1);
__ Fminnm(s30, s0, s1);
=======================================
--- /branches/bleeding_edge/test/cctest/test-disasm-a64.cc Fri Mar 7
15:20:32 2014 UTC
+++ /branches/bleeding_edge/test/cctest/test-disasm-a64.cc Thu Mar 13
09:45:02 2014 UTC
@@ -1273,7 +1273,7 @@
COMPARE_PREFIX(ldr(x10, 0x1234567890abcdefUL), "ldr x10, pc+8");
COMPARE_PREFIX(ldr(w20, 0xfedcba09), "ldr w20, pc+8");
COMPARE_PREFIX(ldr(d11, 1.234), "ldr d11, pc+8");
- COMPARE_PREFIX(ldr(s22, 2.5), "ldr s22, pc+8");
+ COMPARE_PREFIX(ldr(s22, 2.5f), "ldr s22, pc+8");
CLEANUP();
}
@@ -1361,8 +1361,8 @@
TEST_(fmov_imm) {
SET_UP();
- COMPARE(fmov(s0, 1.0), "fmov s0, #0x70 (1.0000)");
- COMPARE(fmov(s31, -13.0), "fmov s31, #0xaa (-13.0000)");
+ COMPARE(fmov(s0, 1.0f), "fmov s0, #0x70 (1.0000)");
+ COMPARE(fmov(s31, -13.0f), "fmov s31, #0xaa (-13.0000)");
COMPARE(fmov(d1, 1.0), "fmov d1, #0x70 (1.0000)");
COMPARE(fmov(d29, -13.0), "fmov d29, #0xaa (-13.0000)");
--
--
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.