Bug 1112164 part 7 - Add common architecture functions to query/convert a register type. r=mjrosenb

This commit is contained in:
Nicolas B. Pierron 2015-02-26 12:18:23 +01:00
parent 5aaec30202
commit 602486a0c0
11 changed files with 94 additions and 15 deletions

View File

@ -492,13 +492,15 @@ class LDefinition
}
bool isCompatibleReg(const AnyRegister &r) const {
if (isFloatReg() && r.isFloat()) {
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
if (type() == FLOAT32)
return r.fpu().isSingle();
return r.fpu().isDouble();
#else
return true;
#endif
if (type() == DOUBLE)
return r.fpu().isDouble();
if (type() == INT32X4)
return r.fpu().isInt32x4();
if (type() == FLOAT32X4)
return r.fpu().isFloat32x4();
MOZ_CRASH("Unexpected MDefinition type");
}
return !isFloatReg() && !r.isFloat();
}

View File

@ -368,8 +368,11 @@ class VFPRegister
MOZ_ASSERT(!other.isInvalid());
return kind == other.kind && code_ == other.code_;
}
bool isDouble() const { return kind == Double; }
bool isSingle() const { return kind == Single; }
bool isDouble() const { return kind == Double; }
bool isInt32x4() const { return false; }
bool isFloat32x4() const { return false; }
bool isFloat() const { return (kind == Double) || (kind == Single); }
bool isInt() const { return (kind == UInt) || (kind == Int); }
bool isSInt() const { return kind == Int; }
@ -384,6 +387,11 @@ class VFPRegister
VFPRegister sintOverlay(unsigned int which = 0) const;
VFPRegister uintOverlay(unsigned int which = 0) const;
VFPRegister asSingle() const { return singleOverlay(); }
VFPRegister asDouble() const { return doubleOverlay(); }
VFPRegister asInt32x4() const { MOZ_CRASH("NYI"); }
VFPRegister asFloat32x4() const { MOZ_CRASH("NYI"); }
struct VFPRegIndexSplit;
VFPRegIndexSplit encode();

View File

@ -373,19 +373,27 @@ class FloatRegister
MOZ_ASSERT(!other.isInvalid());
return kind_ == other.kind_ && code_ == other.code_;
}
bool isDouble() const { return kind_ == Double; }
bool isSingle() const { return kind_ == Single; }
bool equiv(const FloatRegister &other) const { return other.kind_ == kind_; }
size_t size() const { return (kind_ == Double) ? 8 : 4; }
bool isInvalid() const {
return code_ == FloatRegisters::invalid_freg;
}
bool isSingle() const { return kind_ == Single; }
bool isDouble() const { return kind_ == Double; }
bool isInt32x4() const { return false; }
bool isFloat32x4() const { return false; }
FloatRegister doubleOverlay(unsigned int which = 0) const;
FloatRegister singleOverlay(unsigned int which = 0) const;
FloatRegister sintOverlay(unsigned int which = 0) const;
FloatRegister uintOverlay(unsigned int which = 0) const;
FloatRegister asSingle() const { return singleOverlay(); }
FloatRegister asDouble() const { return doubleOverlay(); }
FloatRegister asInt32x4() const { MOZ_CRASH("NYI"); }
FloatRegister asFloat32x4() const { MOZ_CRASH("NYI"); }
Code code() const {
MOZ_ASSERT(!isInvalid());
return Code(code_ | (kind_ << 5));

View File

@ -94,6 +94,14 @@ struct FloatRegister
static uint32_t FirstBit(SetType) { MOZ_CRASH(); }
static uint32_t LastBit(SetType) { MOZ_CRASH(); }
static FloatRegister FromCode(uint32_t) { MOZ_CRASH(); }
bool isSingle() const { MOZ_CRASH(); }
bool isDouble() const { MOZ_CRASH(); }
bool isInt32x4() const { MOZ_CRASH(); }
bool isFloat32x4() const { MOZ_CRASH(); }
FloatRegister asSingle() const { MOZ_CRASH(); }
FloatRegister asDouble() const { MOZ_CRASH(); }
FloatRegister asInt32x4() const { MOZ_CRASH(); }
FloatRegister asFloat32x4() const { MOZ_CRASH(); }
Code code() const { MOZ_CRASH(); }
const char *name() const { MOZ_CRASH(); }
bool volatile_() const { MOZ_CRASH(); }

View File

@ -1366,16 +1366,19 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool)
Register dest = ool->dest();
saveVolatile(dest);
#ifdef JS_CODEGEN_ARM
#if defined(JS_CODEGEN_ARM)
if (ool->needFloat32Conversion()) {
masm.convertFloat32ToDouble(src, ScratchDoubleReg);
src = ScratchDoubleReg;
}
#else
FloatRegister srcSingle = src.asSingle();
if (ool->needFloat32Conversion()) {
MOZ_ASSERT(src.isSingle());
masm.push(src);
masm.convertFloat32ToDouble(src, src);
src = src.asDouble();
}
#endif
masm.setupUnalignedABICall(1, dest);
@ -1386,9 +1389,9 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow *ool)
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32));
masm.storeCallResult(dest);
#ifndef JS_CODEGEN_ARM
#if !defined(JS_CODEGEN_ARM)
if (ool->needFloat32Conversion())
masm.pop(src);
masm.pop(srcSingle);
#endif
restoreVolatile(dest);

View File

@ -426,6 +426,9 @@ MoveEmitterX86::emitGeneralMove(const MoveOperand &from, const MoveOperand &to)
void
MoveEmitterX86::emitFloat32Move(const MoveOperand &from, const MoveOperand &to)
{
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isSingle());
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isSingle());
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.moveFloat32(from.floatReg(), to.floatReg());
@ -444,6 +447,9 @@ MoveEmitterX86::emitFloat32Move(const MoveOperand &from, const MoveOperand &to)
void
MoveEmitterX86::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
{
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isDouble());
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isDouble());
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.moveDouble(from.floatReg(), to.floatReg());
@ -462,6 +468,9 @@ MoveEmitterX86::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
void
MoveEmitterX86::emitInt32X4Move(const MoveOperand &from, const MoveOperand &to)
{
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isInt32x4());
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isInt32x4());
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.moveInt32x4(from.floatReg(), to.floatReg());
@ -480,6 +489,9 @@ MoveEmitterX86::emitInt32X4Move(const MoveOperand &from, const MoveOperand &to)
void
MoveEmitterX86::emitFloat32X4Move(const MoveOperand &from, const MoveOperand &to)
{
MOZ_ASSERT_IF(from.isFloatReg(), from.floatReg().isFloat32x4());
MOZ_ASSERT_IF(to.isFloatReg(), to.floatReg().isFloat32x4());
if (from.isFloatReg()) {
if (to.isFloatReg())
masm.moveFloat32x4(from.floatReg(), to.floatReg());

View File

@ -196,6 +196,17 @@ struct FloatRegister {
FloatRegister r = { Code(i) };
return r;
}
bool isSingle() const { return true; }
bool isDouble() const { return true; }
bool isInt32x4() const { return true; }
bool isFloat32x4() const { return true; }
FloatRegister asSingle() const { return *this; }
FloatRegister asDouble() const { return *this; }
FloatRegister asInt32x4() const { return *this; }
FloatRegister asFloat32x4() const { return *this; }
Code code() const {
MOZ_ASSERT(uint32_t(code_) < FloatRegisters::Total);
return code_;

View File

@ -49,15 +49,22 @@ ABIArgGenerator::next(MIRType type)
current_ = ABIArg(IntArgRegs[regIndex_++]);
break;
case MIRType_Float32:
current_ = ABIArg(FloatArgRegs[regIndex_++].asSingle());
break;
case MIRType_Double:
current_ = ABIArg(FloatArgRegs[regIndex_++]);
break;
case MIRType_Int32x4:
// On Win64, >64 bit args need to be passed by reference, but asm.js
// doesn't allow passing SIMD values to FFIs. The only way to reach
// here is asm to asm calls, so we can break the ABI here.
current_ = ABIArg(FloatArgRegs[regIndex_++].asInt32x4());
break;
case MIRType_Float32x4:
// On Win64, >64 bit args need to be passed by reference, but asm.js
// doesn't allow passing SIMD values to FFIs. The only way to reach
// here is asm to asm calls, so we can break the ABI here.
current_ = ABIArg(FloatArgRegs[regIndex_++]);
current_ = ABIArg(FloatArgRegs[regIndex_++].asFloat32x4());
break;
default:
MOZ_CRASH("Unexpected argument type");
@ -81,7 +88,10 @@ ABIArgGenerator::next(MIRType type)
stackOffset_ += sizeof(uint64_t);
break;
}
current_ = ABIArg(FloatArgRegs[floatRegIndex_++]);
if (type == MIRType_Float32)
current_ = ABIArg(FloatArgRegs[floatRegIndex_++].asSingle());
else
current_ = ABIArg(FloatArgRegs[floatRegIndex_++]);
break;
case MIRType_Int32x4:
case MIRType_Float32x4:
@ -91,7 +101,10 @@ ABIArgGenerator::next(MIRType type)
stackOffset_ += Simd128DataSize;
break;
}
current_ = ABIArg(FloatArgRegs[floatRegIndex_++]);
if (type == MIRType_Int32x4)
current_ = ABIArg(FloatArgRegs[floatRegIndex_++].asInt32x4());
else
current_ = ABIArg(FloatArgRegs[floatRegIndex_++].asFloat32x4());
break;
default:
MOZ_CRASH("Unexpected argument type");

View File

@ -213,6 +213,9 @@ MacroAssemblerX64::passABIArg(const MoveOperand &from, MoveOp::Type type)
case MoveOp::DOUBLE: {
FloatRegister dest;
if (GetFloatArgReg(passedIntArgs_, passedFloatArgs_++, &dest)) {
// Convert to the right type of register.
if (type == MoveOp::FLOAT32)
dest = dest.asSingle();
if (from.isFloatReg() && from.floatReg() == dest) {
// Nothing to do; the value is in the right register already
return;

View File

@ -173,6 +173,17 @@ struct FloatRegister {
FloatRegister r = { Code(i) };
return r;
}
bool isSingle() const { return true; }
bool isDouble() const { return true; }
bool isInt32x4() const { return true; }
bool isFloat32x4() const { return true; }
FloatRegister asSingle() const { return *this; }
FloatRegister asDouble() const { return *this; }
FloatRegister asInt32x4() const { return *this; }
FloatRegister asFloat32x4() const { return *this; }
Code code() const {
MOZ_ASSERT(uint32_t(code_) < FloatRegisters::Total);
return code_;

View File

@ -1066,7 +1066,7 @@ CodeGeneratorX86::visitOutOfLineTruncateFloat32(OutOfLineTruncateFloat32 *ool)
masm.push(input);
masm.setupUnalignedABICall(1, output);
masm.vcvtss2sd(input, input, input);
masm.passABIArg(input, MoveOp::DOUBLE);
masm.passABIArg(input.asDouble(), MoveOp::DOUBLE);
if (gen->compilingAsmJS())
masm.callWithABI(AsmJSImm_ToInt32);