mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Bug 972836 - IonMonkey MIPS: Add odd float registers to the enum, but don't allocate them yet. r=froydnj,nbp
This commit is contained in:
parent
83e2568195
commit
20985e40e8
@ -113,7 +113,7 @@ class Registers
|
|||||||
return Names[code];
|
return Names[code];
|
||||||
}
|
}
|
||||||
static const char *GetName(uint32_t i) {
|
static const char *GetName(uint32_t i) {
|
||||||
MOZ_ASSERT(i < Total);
|
JS_ASSERT(i < Total);
|
||||||
return GetName(Code(i));
|
return GetName(Code(i));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -191,38 +191,62 @@ class Registers
|
|||||||
typedef uint32_t PackedRegisterMask;
|
typedef uint32_t PackedRegisterMask;
|
||||||
|
|
||||||
|
|
||||||
// MIPS32 uses pairs of even and odd float registers as double precision
|
// MIPS32 can have two types of floating-point coprocessors:
|
||||||
// registers. Example: f0 (double) is composed of f0 and f1 (single).
|
// - 32 bit floating-point coprocessor - In this case, there are 32 single
|
||||||
// This port only uses even registers to avoid allocation problems.
|
// precision registers and pairs of even and odd float registers are used as
|
||||||
|
// double precision registers. Example: f0 (double) is composed of
|
||||||
|
// f0 and f1 (single).
|
||||||
|
// - 64 bit floating-point coprocessor - In this case, there are 32 double
|
||||||
|
// precision register which can also be used as single precision registers.
|
||||||
|
|
||||||
|
// When using O32 ABI, floating-point coprocessor is 32 bit
|
||||||
|
// When using N32 ABI, floating-point coprocessor is 64 bit.
|
||||||
class FloatRegisters
|
class FloatRegisters
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
enum FPRegisterID {
|
enum FPRegisterID {
|
||||||
f0 = 0, // f0, f2 - Return values
|
f0 = 0,
|
||||||
|
f1,
|
||||||
f2,
|
f2,
|
||||||
f4, // f4 - f10, f16, f18 - Temporaries
|
f3,
|
||||||
|
f4,
|
||||||
|
f5,
|
||||||
f6,
|
f6,
|
||||||
|
f7,
|
||||||
f8,
|
f8,
|
||||||
|
f9,
|
||||||
f10,
|
f10,
|
||||||
f12, // f12, f14 - Arguments
|
f11,
|
||||||
|
f12,
|
||||||
|
f13,
|
||||||
f14,
|
f14,
|
||||||
|
f15,
|
||||||
f16,
|
f16,
|
||||||
|
f17,
|
||||||
f18,
|
f18,
|
||||||
f20, // f20 - f30 - Saved registers
|
f19,
|
||||||
|
f20,
|
||||||
|
f21,
|
||||||
f22,
|
f22,
|
||||||
|
f23,
|
||||||
f24,
|
f24,
|
||||||
|
f25,
|
||||||
f26,
|
f26,
|
||||||
|
f27,
|
||||||
f28,
|
f28,
|
||||||
|
f29,
|
||||||
f30,
|
f30,
|
||||||
|
f31,
|
||||||
invalid_freg
|
invalid_freg
|
||||||
};
|
};
|
||||||
typedef FPRegisterID Code;
|
typedef FPRegisterID Code;
|
||||||
|
|
||||||
static const char *GetName(Code code) {
|
static const char *GetName(Code code) {
|
||||||
static const char * const Names[] = { "f0", "f2", "f4", "f6",
|
static const char * const Names[] = { "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7",
|
||||||
"f8", "f10", "f12", "f14",
|
"f8", "f9", "f10", "f11", "f12", "f13",
|
||||||
"f16", "f18", "f20", "f22",
|
"f14", "f15", "f16", "f17", "f18", "f19",
|
||||||
"f24", "f26", "f28", "f30"};
|
"f20", "f21", "f22", "f23", "f24", "f25",
|
||||||
|
"f26", "f27", "f28", "f29", "f30", "f31"};
|
||||||
return Names[code];
|
return Names[code];
|
||||||
}
|
}
|
||||||
static const char *GetName(uint32_t i) {
|
static const char *GetName(uint32_t i) {
|
||||||
@ -234,10 +258,12 @@ class FloatRegisters
|
|||||||
|
|
||||||
static const Code Invalid = invalid_freg;
|
static const Code Invalid = invalid_freg;
|
||||||
|
|
||||||
static const uint32_t Total = 16;
|
static const uint32_t Total = 32;
|
||||||
|
// :TODO: (Bug 972836) // Fix this once odd regs can be used as float32
|
||||||
|
// only. For now we don't allocate odd regs for O32 ABI.
|
||||||
static const uint32_t Allocatable = 14;
|
static const uint32_t Allocatable = 14;
|
||||||
|
|
||||||
static const uint32_t AllMask = 0xffff;
|
static const uint32_t AllMask = 0xffffffff;
|
||||||
|
|
||||||
static const uint32_t VolatileMask =
|
static const uint32_t VolatileMask =
|
||||||
(1 << FloatRegisters::f0) |
|
(1 << FloatRegisters::f0) |
|
||||||
@ -260,10 +286,28 @@ class FloatRegisters
|
|||||||
|
|
||||||
static const uint32_t WrapperMask = VolatileMask;
|
static const uint32_t WrapperMask = VolatileMask;
|
||||||
|
|
||||||
// f18 and f16 are MIPS scratch float registers.
|
// :TODO: (Bug 972836) // Fix this once odd regs can be used as float32
|
||||||
|
// only. For now we don't allocate odd regs for O32 ABI.
|
||||||
static const uint32_t NonAllocatableMask =
|
static const uint32_t NonAllocatableMask =
|
||||||
(1 << f16) |
|
(1 << FloatRegisters::f1) |
|
||||||
(1 << f18);
|
(1 << FloatRegisters::f3) |
|
||||||
|
(1 << FloatRegisters::f5) |
|
||||||
|
(1 << FloatRegisters::f7) |
|
||||||
|
(1 << FloatRegisters::f9) |
|
||||||
|
(1 << FloatRegisters::f11) |
|
||||||
|
(1 << FloatRegisters::f13) |
|
||||||
|
(1 << FloatRegisters::f15) |
|
||||||
|
(1 << FloatRegisters::f17) |
|
||||||
|
(1 << FloatRegisters::f19) |
|
||||||
|
(1 << FloatRegisters::f21) |
|
||||||
|
(1 << FloatRegisters::f23) |
|
||||||
|
(1 << FloatRegisters::f25) |
|
||||||
|
(1 << FloatRegisters::f27) |
|
||||||
|
(1 << FloatRegisters::f29) |
|
||||||
|
(1 << FloatRegisters::f31) |
|
||||||
|
// f18 and f16 are MIPS scratch float registers.
|
||||||
|
(1 << FloatRegisters::f16) |
|
||||||
|
(1 << FloatRegisters::f18);
|
||||||
|
|
||||||
// Registers that can be allocated without being saved, generally.
|
// Registers that can be allocated without being saved, generally.
|
||||||
static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
|
static const uint32_t TempMask = VolatileMask & ~NonAllocatableMask;
|
||||||
|
@ -56,16 +56,7 @@ uint32_t
|
|||||||
js::jit::RT(FloatRegister r)
|
js::jit::RT(FloatRegister r)
|
||||||
{
|
{
|
||||||
JS_ASSERT(r.code() < FloatRegisters::Total);
|
JS_ASSERT(r.code() < FloatRegisters::Total);
|
||||||
return (2 * r.code()) << RTShift;
|
return r.code() << RTShift;
|
||||||
}
|
|
||||||
|
|
||||||
// Use to code odd float registers.
|
|
||||||
// :TODO: Bug 972836, It will be removed once we can use odd regs.
|
|
||||||
uint32_t
|
|
||||||
js::jit::RT(uint32_t regCode)
|
|
||||||
{
|
|
||||||
JS_ASSERT((regCode & ~RegMask) == 0);
|
|
||||||
return regCode << RTShift;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
@ -79,16 +70,7 @@ uint32_t
|
|||||||
js::jit::RD(FloatRegister r)
|
js::jit::RD(FloatRegister r)
|
||||||
{
|
{
|
||||||
JS_ASSERT(r.code() < FloatRegisters::Total);
|
JS_ASSERT(r.code() < FloatRegisters::Total);
|
||||||
return (2 * r.code()) << RDShift;
|
return r.code() << RDShift;
|
||||||
}
|
|
||||||
|
|
||||||
// Use to code odd float registers.
|
|
||||||
// :TODO: Bug 972836, It will be removed once we can use odd regs.
|
|
||||||
uint32_t
|
|
||||||
js::jit::RD(uint32_t regCode)
|
|
||||||
{
|
|
||||||
JS_ASSERT((regCode & ~RegMask) == 0);
|
|
||||||
return regCode << RDShift;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
uint32_t
|
uint32_t
|
||||||
@ -102,7 +84,7 @@ uint32_t
|
|||||||
js::jit::SA(FloatRegister r)
|
js::jit::SA(FloatRegister r)
|
||||||
{
|
{
|
||||||
JS_ASSERT(r.code() < FloatRegisters::Total);
|
JS_ASSERT(r.code() < FloatRegisters::Total);
|
||||||
return (2 * r.code()) << SAShift;
|
return r.code() << SAShift;
|
||||||
}
|
}
|
||||||
|
|
||||||
Register
|
Register
|
||||||
@ -973,39 +955,6 @@ Assembler::as_mfc1(Register rt, FloatRegister fs)
|
|||||||
return writeInst(InstReg(op_cop1, rs_mfc1, rt, fs).encode());
|
return writeInst(InstReg(op_cop1, rs_mfc1, rt, fs).encode());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// :TODO: Bug 972836, Remove _Odd functions once we can use odd regs.
|
|
||||||
BufferOffset
|
|
||||||
Assembler::as_ls_Odd(FloatRegister fd, Register base, int32_t off)
|
|
||||||
{
|
|
||||||
JS_ASSERT(Imm16::isInSignedRange(off));
|
|
||||||
// Hardcoded because it will be removed once we can use odd regs.
|
|
||||||
return writeInst(op_lwc1 | RS(base) | RT(fd.code() * 2 + 1) | Imm16(off).encode());
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferOffset
|
|
||||||
Assembler::as_ss_Odd(FloatRegister fd, Register base, int32_t off)
|
|
||||||
{
|
|
||||||
JS_ASSERT(Imm16::isInSignedRange(off));
|
|
||||||
// Hardcoded because it will be removed once we can use odd regs.
|
|
||||||
return writeInst(op_swc1 | RS(base) | RT(fd.code() * 2 + 1) | Imm16(off).encode());
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferOffset
|
|
||||||
Assembler::as_mtc1_Odd(Register rt, FloatRegister fs)
|
|
||||||
{
|
|
||||||
// Hardcoded because it will be removed once we can use odd regs.
|
|
||||||
return writeInst(op_cop1 | rs_mtc1 | RT(rt) | RD(fs.code() * 2 + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
BufferOffset
|
|
||||||
Assembler::as_mfc1_Odd(Register rt, FloatRegister fs)
|
|
||||||
{
|
|
||||||
// Hardcoded because it will be removed once we can use odd regs.
|
|
||||||
return writeInst(op_cop1 | rs_mfc1 | RT(rt) | RD(fs.code() * 2 + 1));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// FP convert instructions
|
// FP convert instructions
|
||||||
BufferOffset
|
BufferOffset
|
||||||
Assembler::as_ceilws(FloatRegister fd, FloatRegister fs)
|
Assembler::as_ceilws(FloatRegister fd, FloatRegister fs)
|
||||||
|
@ -861,16 +861,14 @@ class Assembler
|
|||||||
BufferOffset as_mfc1(Register rt, FloatRegister fs);
|
BufferOffset as_mfc1(Register rt, FloatRegister fs);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
// These instructions should only be used to access the odd part of
|
// This is used to access the odd regiter form the pair of single
|
||||||
// 64-bit register pair. Do not use odd registers as 32-bit registers.
|
// precision registers that make one double register.
|
||||||
// :TODO: Bug 972836, Remove _Odd functions once we can use odd regs.
|
FloatRegister getOddPair(FloatRegister reg) {
|
||||||
BufferOffset as_ls_Odd(FloatRegister fd, Register base, int32_t off);
|
JS_ASSERT(reg.code() % 2 == 0);
|
||||||
BufferOffset as_ss_Odd(FloatRegister fd, Register base, int32_t off);
|
return FloatRegister::FromCode(reg.code() + 1);
|
||||||
BufferOffset as_mtc1_Odd(Register rt, FloatRegister fs);
|
}
|
||||||
public:
|
|
||||||
// Made public because CodeGenerator uses it to check for -0
|
|
||||||
BufferOffset as_mfc1_Odd(Register rt, FloatRegister fs);
|
|
||||||
|
|
||||||
|
public:
|
||||||
// FP convert instructions
|
// FP convert instructions
|
||||||
BufferOffset as_ceilws(FloatRegister fd, FloatRegister fs);
|
BufferOffset as_ceilws(FloatRegister fd, FloatRegister fs);
|
||||||
BufferOffset as_floorws(FloatRegister fd, FloatRegister fs);
|
BufferOffset as_floorws(FloatRegister fd, FloatRegister fs);
|
||||||
|
@ -114,7 +114,7 @@ MacroAssemblerMIPS::convertDoubleToInt32(const FloatRegister &src, const Registe
|
|||||||
// Test and bail for -0.0, when integer result is 0
|
// Test and bail for -0.0, when integer result is 0
|
||||||
// Move the top word of the double into the output reg, if it is
|
// Move the top word of the double into the output reg, if it is
|
||||||
// non-zero, then the original value was -0.0
|
// non-zero, then the original value was -0.0
|
||||||
as_mfc1_Odd(dest, src);
|
moveFromDoubleHi(src, dest);
|
||||||
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
|
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
|
||||||
bind(¬Zero);
|
bind(¬Zero);
|
||||||
}
|
}
|
||||||
@ -141,7 +141,7 @@ MacroAssemblerMIPS::convertFloat32ToInt32(const FloatRegister &src, const Regist
|
|||||||
// Test and bail for -0.0, when integer result is 0
|
// Test and bail for -0.0, when integer result is 0
|
||||||
// Move the top word of the double into the output reg,
|
// Move the top word of the double into the output reg,
|
||||||
// if it is non-zero, then the original value was -0.0
|
// if it is non-zero, then the original value was -0.0
|
||||||
as_mfc1_Odd(dest, src);
|
moveFromDoubleHi(src, dest);
|
||||||
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
|
ma_b(dest, Imm32(INT32_MIN), fail, Assembler::Equal);
|
||||||
bind(¬Zero);
|
bind(¬Zero);
|
||||||
}
|
}
|
||||||
@ -1296,7 +1296,7 @@ MacroAssemblerMIPS::ma_lis(FloatRegister dest, float value)
|
|||||||
Imm32 imm(mozilla::BitwiseCast<uint32_t>(value));
|
Imm32 imm(mozilla::BitwiseCast<uint32_t>(value));
|
||||||
|
|
||||||
ma_li(ScratchRegister, imm);
|
ma_li(ScratchRegister, imm);
|
||||||
as_mtc1(ScratchRegister, dest);
|
moveToFloat32(ScratchRegister, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1310,41 +1310,41 @@ MacroAssemblerMIPS::ma_lid(FloatRegister dest, double value)
|
|||||||
|
|
||||||
// put hi part of 64 bit value into the odd register
|
// put hi part of 64 bit value into the odd register
|
||||||
if (intStruct.hi == 0) {
|
if (intStruct.hi == 0) {
|
||||||
as_mtc1_Odd(zero, dest);
|
moveToDoubleHi(zero, dest);
|
||||||
} else {
|
} else {
|
||||||
ma_li(ScratchRegister, Imm32(intStruct.hi));
|
ma_li(ScratchRegister, Imm32(intStruct.hi));
|
||||||
as_mtc1_Odd(ScratchRegister, dest);
|
moveToDoubleHi(ScratchRegister, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
// put low part of 64 bit value into the even register
|
// put low part of 64 bit value into the even register
|
||||||
if (intStruct.lo == 0) {
|
if (intStruct.lo == 0) {
|
||||||
as_mtc1(zero, dest);
|
moveToDoubleLo(zero, dest);
|
||||||
} else {
|
} else {
|
||||||
ma_li(ScratchRegister, Imm32(intStruct.lo));
|
ma_li(ScratchRegister, Imm32(intStruct.lo));
|
||||||
as_mtc1(ScratchRegister, dest);
|
moveToDoubleLo(ScratchRegister, dest);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerMIPS::ma_liNegZero(FloatRegister dest)
|
MacroAssemblerMIPS::ma_liNegZero(FloatRegister dest)
|
||||||
{
|
{
|
||||||
as_mtc1(zero, dest);
|
moveToDoubleLo(zero, dest);
|
||||||
ma_li(ScratchRegister, Imm32(INT_MIN));
|
ma_li(ScratchRegister, Imm32(INT_MIN));
|
||||||
as_mtc1_Odd(ScratchRegister, dest);
|
moveToDoubleHi(ScratchRegister, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerMIPS::ma_mv(FloatRegister src, ValueOperand dest)
|
MacroAssemblerMIPS::ma_mv(FloatRegister src, ValueOperand dest)
|
||||||
{
|
{
|
||||||
as_mfc1(dest.payloadReg(), src);
|
moveFromDoubleLo(src, dest.payloadReg());
|
||||||
as_mfc1_Odd(dest.typeReg(), src);
|
moveFromDoubleHi(src, dest.typeReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerMIPS::ma_mv(ValueOperand src, FloatRegister dest)
|
MacroAssemblerMIPS::ma_mv(ValueOperand src, FloatRegister dest)
|
||||||
{
|
{
|
||||||
as_mtc1(src.payloadReg(), dest);
|
moveToDoubleLo(src.payloadReg(), dest);
|
||||||
as_mtc1_Odd(src.typeReg(), dest);
|
moveToDoubleHi(src.typeReg(), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -1369,12 +1369,12 @@ MacroAssemblerMIPS::ma_ld(FloatRegister ft, Address address)
|
|||||||
int32_t off2 = address.offset + TAG_OFFSET;
|
int32_t off2 = address.offset + TAG_OFFSET;
|
||||||
if (Imm16::isInSignedRange(address.offset) && Imm16::isInSignedRange(off2)) {
|
if (Imm16::isInSignedRange(address.offset) && Imm16::isInSignedRange(off2)) {
|
||||||
as_ls(ft, address.base, Imm16(address.offset).encode());
|
as_ls(ft, address.base, Imm16(address.offset).encode());
|
||||||
as_ls_Odd(ft, address.base, Imm16(off2).encode());
|
as_ls(getOddPair(ft), address.base, Imm16(off2).encode());
|
||||||
} else {
|
} else {
|
||||||
ma_li(ScratchRegister, Imm32(address.offset));
|
ma_li(ScratchRegister, Imm32(address.offset));
|
||||||
as_addu(ScratchRegister, address.base, ScratchRegister);
|
as_addu(ScratchRegister, address.base, ScratchRegister);
|
||||||
as_ls(ft, ScratchRegister, PAYLOAD_OFFSET);
|
as_ls(ft, ScratchRegister, PAYLOAD_OFFSET);
|
||||||
as_ls_Odd(ft, ScratchRegister, TAG_OFFSET);
|
as_ls(getOddPair(ft), ScratchRegister, TAG_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1384,12 +1384,12 @@ MacroAssemblerMIPS::ma_sd(FloatRegister ft, Address address)
|
|||||||
int32_t off2 = address.offset + TAG_OFFSET;
|
int32_t off2 = address.offset + TAG_OFFSET;
|
||||||
if (Imm16::isInSignedRange(address.offset) && Imm16::isInSignedRange(off2)) {
|
if (Imm16::isInSignedRange(address.offset) && Imm16::isInSignedRange(off2)) {
|
||||||
as_ss(ft, address.base, Imm16(address.offset).encode());
|
as_ss(ft, address.base, Imm16(address.offset).encode());
|
||||||
as_ss_Odd(ft, address.base, Imm16(off2).encode());
|
as_ss(getOddPair(ft), address.base, Imm16(off2).encode());
|
||||||
} else {
|
} else {
|
||||||
ma_li(ScratchRegister, Imm32(address.offset));
|
ma_li(ScratchRegister, Imm32(address.offset));
|
||||||
as_addu(ScratchRegister, address.base, ScratchRegister);
|
as_addu(ScratchRegister, address.base, ScratchRegister);
|
||||||
as_ss(ft, ScratchRegister, PAYLOAD_OFFSET);
|
as_ss(ft, ScratchRegister, PAYLOAD_OFFSET);
|
||||||
as_ss_Odd(ft, ScratchRegister, TAG_OFFSET);
|
as_ss(getOddPair(ft), ScratchRegister, TAG_OFFSET);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1540,6 +1540,72 @@ MacroAssemblerMIPSCompat::freeStack(Register amount)
|
|||||||
as_addu(StackPointer, StackPointer, amount);
|
as_addu(StackPointer, StackPointer, amount);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MacroAssembler::PushRegsInMask(RegisterSet set)
|
||||||
|
{
|
||||||
|
int32_t diffF = set.fpus().size() * sizeof(double);
|
||||||
|
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||||
|
|
||||||
|
reserveStack(diffG);
|
||||||
|
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||||
|
diffG -= sizeof(intptr_t);
|
||||||
|
storePtr(*iter, Address(StackPointer, diffG));
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(diffG == 0);
|
||||||
|
|
||||||
|
// Double values have to be aligned. We reserve extra space so that we can
|
||||||
|
// start writing from the first aligned location.
|
||||||
|
// We reserve a whole extra double so that the buffer has even size.
|
||||||
|
ma_and(SecondScratchReg, sp, Imm32(~(StackAlignment - 1)));
|
||||||
|
reserveStack(diffF + sizeof(double));
|
||||||
|
|
||||||
|
for (FloatRegisterForwardIterator iter(set.fpus()); iter.more(); iter++) {
|
||||||
|
// Use assembly s.d because we have alligned the stack.
|
||||||
|
// :TODO: (Bug 972836) Fix this once odd regs can be used as
|
||||||
|
// float32 only. For now we skip saving odd regs for O32 ABI.
|
||||||
|
|
||||||
|
// :TODO: (Bug 985881) Make a switch for N32 ABI.
|
||||||
|
if ((*iter).code() % 2 == 0)
|
||||||
|
as_sd(*iter, SecondScratchReg, -diffF);
|
||||||
|
diffF -= sizeof(double);
|
||||||
|
}
|
||||||
|
MOZ_ASSERT(diffF == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
MacroAssembler::PopRegsInMaskIgnore(RegisterSet set, RegisterSet ignore)
|
||||||
|
{
|
||||||
|
int32_t diffG = set.gprs().size() * sizeof(intptr_t);
|
||||||
|
int32_t diffF = set.fpus().size() * sizeof(double);
|
||||||
|
const int32_t reservedG = diffG;
|
||||||
|
const int32_t reservedF = diffF;
|
||||||
|
|
||||||
|
// Read the buffer form the first aligned location.
|
||||||
|
ma_addu(SecondScratchReg, sp, Imm32(reservedF + sizeof(double)));
|
||||||
|
ma_and(SecondScratchReg, SecondScratchReg, Imm32(~(StackAlignment - 1)));
|
||||||
|
|
||||||
|
for (FloatRegisterForwardIterator iter(set.fpus()); iter.more(); iter++) {
|
||||||
|
// :TODO: (Bug 972836) Fix this once odd regs can be used as
|
||||||
|
// float32 only. For now we skip loading odd regs for O32 ABI.
|
||||||
|
|
||||||
|
// :TODO: (Bug 985881) Make a switch for N32 ABI.
|
||||||
|
if (!ignore.has(*iter) && ((*iter).code() % 2 == 0))
|
||||||
|
// Use assembly l.d because we have alligned the stack.
|
||||||
|
as_ld(*iter, SecondScratchReg, -diffF);
|
||||||
|
diffF -= sizeof(double);
|
||||||
|
}
|
||||||
|
freeStack(reservedF + sizeof(double));
|
||||||
|
MOZ_ASSERT(diffF == 0);
|
||||||
|
|
||||||
|
for (GeneralRegisterBackwardIterator iter(set.gprs()); iter.more(); iter++) {
|
||||||
|
diffG -= sizeof(intptr_t);
|
||||||
|
if (!ignore.has(*iter))
|
||||||
|
loadPtr(Address(StackPointer, diffG), *iter);
|
||||||
|
}
|
||||||
|
freeStack(reservedG);
|
||||||
|
MOZ_ASSERT(diffG == 0);
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerMIPSCompat::add32(Register src, Register dest)
|
MacroAssemblerMIPSCompat::add32(Register src, Register dest)
|
||||||
{
|
{
|
||||||
@ -2324,17 +2390,17 @@ void
|
|||||||
MacroAssemblerMIPSCompat::unboxDouble(const ValueOperand &operand, const FloatRegister &dest)
|
MacroAssemblerMIPSCompat::unboxDouble(const ValueOperand &operand, const FloatRegister &dest)
|
||||||
{
|
{
|
||||||
MOZ_ASSERT(dest != ScratchFloatReg);
|
MOZ_ASSERT(dest != ScratchFloatReg);
|
||||||
as_mtc1(operand.payloadReg(), dest);
|
moveToDoubleLo(operand.payloadReg(), dest);
|
||||||
as_mtc1_Odd(operand.typeReg(), dest);
|
moveToDoubleHi(operand.typeReg(), dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
MacroAssemblerMIPSCompat::unboxDouble(const Address &src, const FloatRegister &dest)
|
MacroAssemblerMIPSCompat::unboxDouble(const Address &src, const FloatRegister &dest)
|
||||||
{
|
{
|
||||||
ma_lw(ScratchRegister, Address(src.base, src.offset + PAYLOAD_OFFSET));
|
ma_lw(ScratchRegister, Address(src.base, src.offset + PAYLOAD_OFFSET));
|
||||||
as_mtc1(ScratchRegister, dest);
|
moveToDoubleLo(ScratchRegister, dest);
|
||||||
ma_lw(ScratchRegister, Address(src.base, src.offset + TAG_OFFSET));
|
ma_lw(ScratchRegister, Address(src.base, src.offset + TAG_OFFSET));
|
||||||
as_mtc1_Odd(ScratchRegister, dest);
|
moveToDoubleHi(ScratchRegister, dest);
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -2380,8 +2446,8 @@ MacroAssemblerMIPSCompat::unboxPrivate(const ValueOperand &src, Register dest)
|
|||||||
void
|
void
|
||||||
MacroAssemblerMIPSCompat::boxDouble(const FloatRegister &src, const ValueOperand &dest)
|
MacroAssemblerMIPSCompat::boxDouble(const FloatRegister &src, const ValueOperand &dest)
|
||||||
{
|
{
|
||||||
as_mfc1(dest.payloadReg(), src);
|
moveFromDoubleLo(src, dest.payloadReg());
|
||||||
as_mfc1_Odd(dest.typeReg(), src);
|
moveFromDoubleHi(src, dest.typeReg());
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -234,6 +234,32 @@ class MacroAssemblerMIPS : public Assembler
|
|||||||
void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label *label, DoubleCondition c,
|
void ma_bc1d(FloatRegister lhs, FloatRegister rhs, Label *label, DoubleCondition c,
|
||||||
JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
|
JumpKind jumpKind = LongJump, FPConditionBit fcc = FCC0);
|
||||||
|
|
||||||
|
|
||||||
|
// These fuctions abstract the access to high part of the double precision
|
||||||
|
// float register. It is intended to work on both 32 bit and 64 bit
|
||||||
|
// floating point coprocessor.
|
||||||
|
// :TODO: (Bug 985881) Modify this for N32 ABI to use mthc1 and mfhc1
|
||||||
|
void moveToDoubleHi(Register src, FloatRegister dest) {
|
||||||
|
as_mtc1(src, getOddPair(dest));
|
||||||
|
}
|
||||||
|
void moveFromDoubleHi(FloatRegister src, Register dest) {
|
||||||
|
as_mfc1(dest, getOddPair(src));
|
||||||
|
}
|
||||||
|
|
||||||
|
void moveToDoubleLo(Register src, FloatRegister dest) {
|
||||||
|
as_mtc1(src, dest);
|
||||||
|
}
|
||||||
|
void moveFromDoubleLo(FloatRegister src, Register dest) {
|
||||||
|
as_mfc1(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
|
void moveToFloat32(Register src, FloatRegister dest) {
|
||||||
|
as_mtc1(src, dest);
|
||||||
|
}
|
||||||
|
void moveFromFloat32(FloatRegister src, Register dest) {
|
||||||
|
as_mfc1(dest, src);
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void branchWithCode(InstImm code, Label *label, JumpKind jumpKind);
|
void branchWithCode(InstImm code, Label *label, JumpKind jumpKind);
|
||||||
Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c);
|
Condition ma_cmp(Register rd, Register lhs, Register rhs, Condition c);
|
||||||
@ -993,8 +1019,8 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
void zeroDouble(FloatRegister reg) {
|
void zeroDouble(FloatRegister reg) {
|
||||||
as_mtc1(zero, reg);
|
moveToDoubleLo(zero, reg);
|
||||||
as_mtc1_Odd(zero, reg);
|
moveToDoubleHi(zero, reg);
|
||||||
}
|
}
|
||||||
|
|
||||||
void clampIntToUint8(Register reg) {
|
void clampIntToUint8(Register reg) {
|
||||||
|
@ -212,7 +212,7 @@ MoveEmitterMIPS::emitFloat32Move(const MoveOperand &from, const MoveOperand &to)
|
|||||||
} else if (to.isGeneralReg()) {
|
} else if (to.isGeneralReg()) {
|
||||||
// This should only be used when passing float parameter in a1,a2,a3
|
// This should only be used when passing float parameter in a1,a2,a3
|
||||||
MOZ_ASSERT(to.reg() == a1 || to.reg() == a2 || to.reg() == a3);
|
MOZ_ASSERT(to.reg() == a1 || to.reg() == a2 || to.reg() == a3);
|
||||||
masm.as_mfc1(to.reg(), from.floatReg());
|
masm.moveFromFloat32(from.floatReg(), to.reg());
|
||||||
} else {
|
} else {
|
||||||
MOZ_ASSERT(to.isMemory());
|
MOZ_ASSERT(to.isMemory());
|
||||||
masm.storeFloat32(from.floatReg(), getAdjustedAddress(to));
|
masm.storeFloat32(from.floatReg(), getAdjustedAddress(to));
|
||||||
@ -248,9 +248,9 @@ MoveEmitterMIPS::emitDoubleMove(const MoveOperand &from, const MoveOperand &to)
|
|||||||
// Two moves are added for one double parameter by
|
// Two moves are added for one double parameter by
|
||||||
// MacroAssemblerMIPSCompat::passABIArg
|
// MacroAssemblerMIPSCompat::passABIArg
|
||||||
if(to.reg() == a2)
|
if(to.reg() == a2)
|
||||||
masm.as_mfc1(a2, from.floatReg());
|
masm.moveFromDoubleLo(from.floatReg(), a2);
|
||||||
else if(to.reg() == a3)
|
else if(to.reg() == a3)
|
||||||
masm.as_mfc1_Odd(a3, from.floatReg());
|
masm.moveFromDoubleHi(from.floatReg(), a3);
|
||||||
else
|
else
|
||||||
MOZ_ASSUME_UNREACHABLE("Invalid emitDoubleMove arguments.");
|
MOZ_ASSUME_UNREACHABLE("Invalid emitDoubleMove arguments.");
|
||||||
} else {
|
} else {
|
||||||
|
Loading…
Reference in New Issue
Block a user