[ppc] use Double instead of double in ppc compiler
The use of double variables to store bit patterns may lead to bit flips when the stored bit pattern is a signaling NaN (sNaN). Operations on a sNaN variable (even just returning the variable from a function) may turn it into a quiet NaN (qNaN), flipping the signaling bit and affecting the information stored in the variable. We observed this behaviour on ia32 architectures and therefore in the simulator builds for other platforms. The use of the wrapper class Double should prevent this behaviour. R=ahaas@chromium.org Change-Id: Ibd1119924a59db771fd4c250689ad9c2a35fff75 Reviewed-on: https://chromium-review.googlesource.com/562771 Reviewed-by: Jaideep Bajwa <bjaideep@ca.ibm.com> Reviewed-by: Andreas Haas <ahaas@chromium.org> Commit-Queue: Enrico Bacis <enricobacis@google.com> Cr-Commit-Position: refs/heads/master@{#46533}
This commit is contained in:
parent
b618aa8106
commit
5457e8a9b5
@ -1213,11 +1213,16 @@ class ConstantPoolBuilder BASE_EMBEDDED {
|
||||
}
|
||||
|
||||
// Add double constant to the embedded constant pool
|
||||
ConstantPoolEntry::Access AddEntry(int position, double value) {
|
||||
ConstantPoolEntry entry(position, Double(value));
|
||||
ConstantPoolEntry::Access AddEntry(int position, Double value) {
|
||||
ConstantPoolEntry entry(position, value);
|
||||
return AddEntry(entry, ConstantPoolEntry::DOUBLE);
|
||||
}
|
||||
|
||||
// Add double constant to the embedded constant pool
|
||||
ConstantPoolEntry::Access AddEntry(int position, double value) {
|
||||
return AddEntry(position, Double(value));
|
||||
}
|
||||
|
||||
// Previews the access type required for the next new entry to be added.
|
||||
ConstantPoolEntry::Access NextAccess(ConstantPoolEntry::Type type) const;
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/compiler/gap-resolver.h"
|
||||
#include "src/compiler/node-matchers.h"
|
||||
#include "src/compiler/osr.h"
|
||||
#include "src/double.h"
|
||||
#include "src/ppc/macro-assembler-ppc.h"
|
||||
|
||||
namespace v8 {
|
||||
@ -124,8 +125,8 @@ class OutOfLineLoadNAN32 final : public OutOfLineCode {
|
||||
: OutOfLineCode(gen), result_(result) {}
|
||||
|
||||
void Generate() final {
|
||||
__ LoadDoubleLiteral(result_, std::numeric_limits<float>::quiet_NaN(),
|
||||
kScratchReg);
|
||||
__ LoadDoubleLiteral(
|
||||
result_, Double(std::numeric_limits<double>::quiet_NaN()), kScratchReg);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -139,8 +140,8 @@ class OutOfLineLoadNAN64 final : public OutOfLineCode {
|
||||
: OutOfLineCode(gen), result_(result) {}
|
||||
|
||||
void Generate() final {
|
||||
__ LoadDoubleLiteral(result_, std::numeric_limits<double>::quiet_NaN(),
|
||||
kScratchReg);
|
||||
__ LoadDoubleLiteral(
|
||||
result_, Double(std::numeric_limits<double>::quiet_NaN()), kScratchReg);
|
||||
}
|
||||
|
||||
private:
|
||||
@ -2450,31 +2451,27 @@ void CodeGenerator::AssembleMove(InstructionOperand* source,
|
||||
DoubleRegister dst = destination->IsFPRegister()
|
||||
? g.ToDoubleRegister(destination)
|
||||
: kScratchDoubleReg;
|
||||
double value;
|
||||
Double value;
|
||||
#if V8_HOST_ARCH_IA32 || V8_HOST_ARCH_X64
|
||||
// casting double precision snan to single precision
|
||||
// converts it to qnan on ia32/x64
|
||||
if (src.type() == Constant::kFloat32) {
|
||||
int32_t val = src.ToFloat32AsInt();
|
||||
uint32_t val = src.ToFloat32AsInt();
|
||||
if ((val & 0x7f800000) == 0x7f800000) {
|
||||
int64_t dval = static_cast<int64_t>(val);
|
||||
uint64_t dval = static_cast<uint64_t>(val);
|
||||
dval = ((dval & 0xc0000000) << 32) | ((dval & 0x40000000) << 31) |
|
||||
((dval & 0x40000000) << 30) | ((dval & 0x7fffffff) << 29);
|
||||
value = bit_cast<double, int64_t>(dval);
|
||||
value = Double(dval);
|
||||
} else {
|
||||
value = src.ToFloat32();
|
||||
value = Double(static_cast<double>(src.ToFloat32()));
|
||||
}
|
||||
} else {
|
||||
int64_t val = src.ToFloat64AsInt();
|
||||
if ((val & 0x7f80000000000000) == 0x7f80000000000000) {
|
||||
value = bit_cast<double, int64_t>(val);
|
||||
} else {
|
||||
value = src.ToFloat64();
|
||||
}
|
||||
value = Double(src.ToFloat64AsInt());
|
||||
}
|
||||
#else
|
||||
value = (src.type() == Constant::kFloat32) ? src.ToFloat32()
|
||||
: src.ToFloat64();
|
||||
value = Double((src.type() == Constant::kFloat32)
|
||||
? static_cast<double>(src.ToFloat32())
|
||||
: src.ToFloat64());
|
||||
#endif
|
||||
__ LoadDoubleLiteral(dst, value, kScratchReg);
|
||||
if (destination->IsFPStackSlot()) {
|
||||
|
@ -174,7 +174,9 @@ class Double {
|
||||
static const int kMaxExponent = 0x7FF - kExponentBias;
|
||||
static const uint64_t kInfinity = V8_2PART_UINT64_C(0x7FF00000, 00000000);
|
||||
|
||||
const uint64_t d64_;
|
||||
// The field d64_ is not marked as const to permit the usage of the copy
|
||||
// constructor.
|
||||
uint64_t d64_;
|
||||
|
||||
static uint64_t DiyFpToUint64(DiyFp diy_fp) {
|
||||
uint64_t significand = diy_fp.f();
|
||||
|
@ -44,6 +44,7 @@
|
||||
#include <vector>
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/double.h"
|
||||
#include "src/ppc/constants-ppc.h"
|
||||
|
||||
#if V8_HOST_ARCH_PPC && \
|
||||
@ -1374,7 +1375,7 @@ class Assembler : public AssemblerBase {
|
||||
is_constant_pool_entry_sharing_blocked());
|
||||
return constant_pool_builder_.AddEntry(pc_offset(), value, sharing_ok);
|
||||
}
|
||||
ConstantPoolEntry::Access ConstantPoolAddEntry(double value) {
|
||||
ConstantPoolEntry::Access ConstantPoolAddEntry(Double value) {
|
||||
return constant_pool_builder_.AddEntry(pc_offset(), value);
|
||||
}
|
||||
|
||||
|
@ -9,6 +9,7 @@
|
||||
#include "src/base/bits.h"
|
||||
#include "src/bootstrapper.h"
|
||||
#include "src/codegen.h"
|
||||
#include "src/double.h"
|
||||
#include "src/ic/handler-compiler.h"
|
||||
#include "src/ic/ic.h"
|
||||
#include "src/ic/stub-cache.h"
|
||||
@ -1060,7 +1061,7 @@ void JSEntryStub::Generate(MacroAssembler* masm) {
|
||||
// Save callee-saved double registers.
|
||||
__ MultiPushDoubles(kCalleeSavedDoubles);
|
||||
// Set up the reserved register for 0.0.
|
||||
__ LoadDoubleLiteral(kDoubleRegZero, 0.0, r0);
|
||||
__ LoadDoubleLiteral(kDoubleRegZero, Double(0.0), r0);
|
||||
|
||||
// Push a frame with special values setup to mark it as an entry frame.
|
||||
// r3: code entry
|
||||
|
@ -3071,7 +3071,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
|
||||
Label done;
|
||||
Label in_bounds;
|
||||
|
||||
LoadDoubleLiteral(double_scratch, 0.0, result_reg);
|
||||
LoadDoubleLiteral(double_scratch, Double(0.0), result_reg);
|
||||
fcmpu(input_reg, double_scratch);
|
||||
bgt(&above_zero);
|
||||
|
||||
@ -3081,7 +3081,7 @@ void MacroAssembler::ClampDoubleToUint8(Register result_reg,
|
||||
|
||||
// Double value is >= 255, return 255.
|
||||
bind(&above_zero);
|
||||
LoadDoubleLiteral(double_scratch, 255.0, result_reg);
|
||||
LoadDoubleLiteral(double_scratch, Double(255.0), result_reg);
|
||||
fcmpu(input_reg, double_scratch);
|
||||
ble(&in_bounds);
|
||||
LoadIntLiteral(result_reg, 255);
|
||||
@ -3191,8 +3191,7 @@ void MacroAssembler::LoadSmiLiteral(Register dst, Smi* smi) {
|
||||
mov(dst, Operand(smi));
|
||||
}
|
||||
|
||||
|
||||
void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value,
|
||||
void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, Double value,
|
||||
Register scratch) {
|
||||
if (FLAG_enable_embedded_constant_pool && is_constant_pool_available() &&
|
||||
!(scratch.is(r0) && ConstantPoolAccessIsInOverflow())) {
|
||||
@ -3208,7 +3207,7 @@ void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value,
|
||||
|
||||
// avoid gcc strict aliasing error using union cast
|
||||
union {
|
||||
double dval;
|
||||
uint64_t dval;
|
||||
#if V8_TARGET_ARCH_PPC64
|
||||
intptr_t ival;
|
||||
#else
|
||||
@ -3216,7 +3215,7 @@ void MacroAssembler::LoadDoubleLiteral(DoubleRegister result, double value,
|
||||
#endif
|
||||
} litVal;
|
||||
|
||||
litVal.dval = value;
|
||||
litVal.dval = value.AsUint64();
|
||||
|
||||
#if V8_TARGET_ARCH_PPC64
|
||||
if (CpuFeatures::IsSupported(FPR_GPR_MOV)) {
|
||||
|
@ -7,6 +7,7 @@
|
||||
|
||||
#include "src/assembler.h"
|
||||
#include "src/bailout-reason.h"
|
||||
#include "src/double.h"
|
||||
#include "src/frames.h"
|
||||
#include "src/globals.h"
|
||||
|
||||
@ -494,7 +495,7 @@ class MacroAssembler : public Assembler {
|
||||
void LoadSmiLiteral(Register dst, Smi* smi);
|
||||
|
||||
// load a literal double value <value> to FPR <result>
|
||||
void LoadDoubleLiteral(DoubleRegister result, double value, Register scratch);
|
||||
void LoadDoubleLiteral(DoubleRegister result, Double value, Register scratch);
|
||||
|
||||
void LoadWord(Register dst, const MemOperand& mem, Register scratch);
|
||||
void LoadWordArith(Register dst, const MemOperand& mem,
|
||||
|
Loading…
Reference in New Issue
Block a user