mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 1112164 part 7 - Add common architecture functions to query/convert a register type. r=mjrosenb
This commit is contained in:
parent
5aaec30202
commit
602486a0c0
@ -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();
|
||||
}
|
||||
|
@ -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();
|
||||
|
||||
|
@ -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));
|
||||
|
@ -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(); }
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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_;
|
||||
|
@ -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");
|
||||
|
@ -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;
|
||||
|
@ -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_;
|
||||
|
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user