Bug 1336027 - wasm baseline, move platform functionality into MacroAssembler layer. r=nbp

--HG--
extra : rebase_source : 9a79fc2b7631a142a5ce0792d520f5be7f54df02
extra : intermediate-source : b0cea1505a204dca0d9ce68820653a3c57b08dd7
extra : source : 55842d0468fc8fcc7d7d3964a3ecdc83cb1990b6
This commit is contained in:
Lars T Hansen 2017-10-13 07:59:54 +02:00
parent c8a9b504ed
commit 3f402ae78d
8 changed files with 315 additions and 108 deletions

View File

@ -746,9 +746,22 @@ class MacroAssembler : public MacroAssemblerSpecific
inline void moveFloat32ToGPR(FloatRegister src, Register dest) PER_SHARED_ARCH;
inline void moveGPRToFloat32(Register src, FloatRegister dest) PER_SHARED_ARCH;
inline void moveDoubleToGPR64(FloatRegister src, Register64 dest) PER_ARCH;
inline void moveGPR64ToDouble(Register64 src, FloatRegister dest) PER_ARCH;
inline void move8SignExtend(Register src, Register dest) PER_SHARED_ARCH;
inline void move16SignExtend(Register src, Register dest) PER_SHARED_ARCH;
// move64To32 will clear the high bits of `dest` on 64-bit systems.
inline void move64To32(Register64 src, Register dest) PER_ARCH;
inline void move32To64ZeroExtend(Register src, Register64 dest) PER_ARCH;
// On x86, `dest` must be edx:eax for the sign extend operations.
inline void move8To64SignExtend(Register src, Register64 dest) PER_ARCH;
inline void move16To64SignExtend(Register src, Register64 dest) PER_ARCH;
inline void move32To64SignExtend(Register src, Register64 dest) PER_ARCH;
// Copy a constant, typed-register, or a ValueOperand into a ValueOperand
// destination.
inline void moveValue(const ConstantOrRegister& src, const ValueOperand& dest);

View File

@ -52,6 +52,55 @@ MacroAssembler::move16SignExtend(Register src, Register dest)
as_sxth(dest, src, 0);
}
void
MacroAssembler::moveDoubleToGPR64(FloatRegister src, Register64 dest)
{
ma_vxfer(src, dest.low, dest.high);
}
void
MacroAssembler::moveGPR64ToDouble(Register64 src, FloatRegister dest)
{
ma_vxfer(src.low, src.high, dest);
}
void
MacroAssembler::move64To32(Register64 src, Register dest)
{
if (src.low != dest)
move32(src.low, dest);
}
void
MacroAssembler::move32To64ZeroExtend(Register src, Register64 dest)
{
if (src != dest.low)
move32(src, dest.low);
move32(Imm32(0), dest.high);
}
void
MacroAssembler::move8To64SignExtend(Register src, Register64 dest)
{
as_sxtb(dest.low, src, 0);
ma_asr(Imm32(31), dest.low, dest.high);
}
void
MacroAssembler::move16To64SignExtend(Register src, Register64 dest)
{
as_sxth(dest.low, src, 0);
ma_asr(Imm32(31), dest.low, dest.high);
}
void
MacroAssembler::move32To64SignExtend(Register src, Register64 dest)
{
if (src != dest.low)
move32(src, dest.low);
ma_asr(Imm32(31), dest.low, dest.high);
}
// ===============================================================
// Logical instructions

View File

@ -50,6 +50,48 @@ MacroAssembler::move16SignExtend(Register src, Register dest)
MOZ_CRASH("NYI: move16SignExtend");
}
void
MacroAssembler::moveDoubleToGPR64(FloatRegister src, Register64 dest)
{
MOZ_CRASH("NYI: moveDoubleToGPR64");
}
void
MacroAssembler::moveGPR64ToDouble(Register64 src, FloatRegister dest)
{
MOZ_CRASH("NYI: moveGPR64ToDouble");
}
void
MacroAssembler::move64To32(Register64 src, Register dest)
{
MOZ_CRASH("NYI: move64To32");
}
void
MacroAssembler::move32To64ZeroExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move32To64ZeroExtend");
}
void
MacroAssembler::move8To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move8To64SignExtend");
}
void
MacroAssembler::move16To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move16To64SignExtend");
}
void
MacroAssembler::move32To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move32To64SignExtend");
}
// ===============================================================
// Logical instructions

View File

@ -30,6 +30,48 @@ MacroAssembler::move64(Imm64 imm, Register64 dest)
move32(Imm32((imm.value >> 32) & 0xFFFFFFFFL), dest.high);
}
void
MacroAssembler::moveDoubleToGPR64(FloatRegister src, Register64 dest)
{
MOZ_CRASH("NYI: moveDoubleToGPR64");
}
void
MacroAssembler::moveGPR64ToDouble(Register64 src, FloatRegister dest)
{
MOZ_CRASH("NYI: moveGPR64ToDouble");
}
void
MacroAssembler::move64To32(Register64 src, Register dest)
{
MOZ_CRASH("NYI: move64To32");
}
void
MacroAssembler::move32To64ZeroExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move32To64ZeroExtend");
}
void
MacroAssembler::move8To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move8To64SignExtend");
}
void
MacroAssembler::move16To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move16To64SignExtend");
}
void
MacroAssembler::move32To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move32To64SignExtend");
}
// ===============================================================
// Logical instructions

View File

@ -28,6 +28,48 @@ MacroAssembler::move64(Imm64 imm, Register64 dest)
movePtr(ImmWord(imm.value), dest.reg);
}
void
MacroAssembler::moveDoubleToGPR64(FloatRegister src, Register64 dest)
{
MOZ_CRASH("NYI: moveDoubleToGPR64");
}
void
MacroAssembler::moveGPR64ToDouble(Register64 src, FloatRegister dest)
{
MOZ_CRASH("NYI: moveGPR64ToDouble");
}
void
MacroAssembler::move64To32(Register64 src, Register dest)
{
MOZ_CRASH("NYI: move64To32");
}
void
MacroAssembler::move32To64ZeroExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move32To64ZeroExtend");
}
void
MacroAssembler::move8To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move8To64SignExtend");
}
void
MacroAssembler::move16To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move16To64SignExtend");
}
void
MacroAssembler::move32To64SignExtend(Register src, Register64 dest)
{
MOZ_CRASH("NYI: move32To64SignExtend");
}
// ===============================================================
// Logical instructions

View File

@ -29,6 +29,48 @@ MacroAssembler::move64(Register64 src, Register64 dest)
movq(src.reg, dest.reg);
}
void
MacroAssembler::moveDoubleToGPR64(FloatRegister src, Register64 dest)
{
vmovq(src, dest.reg);
}
void
MacroAssembler::moveGPR64ToDouble(Register64 src, FloatRegister dest)
{
vmovq(src.reg, dest);
}
void
MacroAssembler::move64To32(Register64 src, Register dest)
{
movl(src.reg, dest);
}
void
MacroAssembler::move32To64ZeroExtend(Register src, Register64 dest)
{
movl(src, dest.reg);
}
void
MacroAssembler::move8To64SignExtend(Register src, Register64 dest)
{
movsbq(Operand(src), dest.reg);
}
void
MacroAssembler::move16To64SignExtend(Register src, Register64 dest)
{
movswq(Operand(src), dest.reg);
}
void
MacroAssembler::move32To64SignExtend(Register src, Register64 dest)
{
movslq(src, dest.reg);
}
void
MacroAssembler::andPtr(Register src, Register dest)
{

View File

@ -30,6 +30,80 @@ MacroAssembler::move64(Register64 src, Register64 dest)
movl(src.high, dest.high);
}
void
MacroAssembler::moveDoubleToGPR64(FloatRegister src, Register64 dest)
{
ScratchDoubleScope scratch(*this);
if (Assembler::HasSSE41()) {
vmovd(src, dest.low);
vpextrd(1, src, dest.high);
} else {
vmovd(src, dest.low);
moveDouble(src, scratch);
vpsrldq(Imm32(4), scratch, scratch);
vmovd(scratch, dest.high);
}
}
void
MacroAssembler::moveGPR64ToDouble(Register64 src, FloatRegister dest)
{
ScratchDoubleScope scratch(*this);
if (Assembler::HasSSE41()) {
vmovd(src.low, dest);
vpinsrd(1, src.high, dest, dest);
} else {
vmovd(src.low, dest);
vmovd(src.high, ScratchDoubleReg);
vunpcklps(ScratchDoubleReg, dest, dest);
}
}
void
MacroAssembler::move64To32(Register64 src, Register dest)
{
if (src.low != dest)
movl(src.low, dest);
}
void
MacroAssembler::move32To64ZeroExtend(Register src, Register64 dest)
{
if (src != dest.low)
movl(src, dest.low);
movl(Imm32(0), dest.high);
}
void
MacroAssembler::move8To64SignExtend(Register src, Register64 dest)
{
MOZ_ASSERT(dest.low == eax);
MOZ_ASSERT(dest.high == edx);
move8SignExtend(src, eax);
masm.cdq();
}
void
MacroAssembler::move16To64SignExtend(Register src, Register64 dest)
{
MOZ_ASSERT(dest.low == eax);
MOZ_ASSERT(dest.high == edx);
move16SignExtend(src, eax);
masm.cdq();
}
void
MacroAssembler::move32To64SignExtend(Register src, Register64 dest)
{
MOZ_ASSERT(dest.low == eax);
MOZ_ASSERT(dest.high == edx);
if (src != eax)
movl(src, eax);
masm.cdq();
}
// ===============================================================
// Logical functions

View File

@ -2935,48 +2935,6 @@ class BaseCompiler
#endif
}
void reinterpretI64AsF64(RegI64 src, RegF64 dest) {
#if defined(JS_CODEGEN_X64)
masm.vmovq(src.reg, dest);
#elif defined(JS_CODEGEN_X86)
masm.Push(src.high);
masm.Push(src.low);
masm.vmovq(Operand(esp, 0), dest);
masm.freeStack(sizeof(uint64_t));
#elif defined(JS_CODEGEN_ARM)
masm.ma_vxfer(src.low, src.high, dest);
#else
MOZ_CRASH("BaseCompiler platform hook: reinterpretI64AsF64");
#endif
}
void reinterpretF64AsI64(RegF64 src, RegI64 dest) {
#if defined(JS_CODEGEN_X64)
masm.vmovq(src, dest.reg);
#elif defined(JS_CODEGEN_X86)
masm.reserveStack(sizeof(uint64_t));
masm.vmovq(src, Operand(esp, 0));
masm.Pop(dest.low);
masm.Pop(dest.high);
#elif defined(JS_CODEGEN_ARM)
masm.ma_vxfer(src, dest.low, dest.high);
#else
MOZ_CRASH("BaseCompiler platform hook: reinterpretF64AsI64");
#endif
}
void wrapI64ToI32(RegI64 src, RegI32 dest) {
#if defined(JS_CODEGEN_X64)
// movl clears the high bits if the two registers are the same.
masm.movl(src.reg, dest);
#elif defined(JS_NUNBOX32)
if (src.low != dest)
masm.move32(src.low, dest);
#else
MOZ_CRASH("BaseCompiler platform hook: wrapI64ToI32");
#endif
}
RegI64 popI32ForSignExtendI64() {
#if defined(JS_CODEGEN_X86)
need2xI32(specific_edx, specific_eax);
@ -3000,56 +2958,6 @@ class BaseCompiler
#endif
}
void signExtendI64_8(RegI64 r) {
#if defined(JS_CODEGEN_X64)
masm.movsbq(Operand(r.reg), r.reg);
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
masm.move8SignExtend(r.low, r.low);
signExtendI32ToI64(RegI32(r.low), r);
#else
MOZ_CRASH("Basecompiler platform hook: signExtendI64_8");
#endif
}
void signExtendI64_16(RegI64 r) {
#if defined(JS_CODEGEN_X64)
masm.movswq(Operand(r.reg), r.reg);
#elif defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_ARM)
masm.move16SignExtend(r.low, r.low);
signExtendI32ToI64(RegI32(r.low), r);
#else
MOZ_CRASH("Basecompiler platform hook: signExtendI64_16");
#endif
}
void signExtendI32ToI64(RegI32 src, RegI64 dest) {
#if defined(JS_CODEGEN_X64)
masm.movslq(src, dest.reg);
#elif defined(JS_CODEGEN_X86)
MOZ_ASSERT(dest.low == src);
MOZ_ASSERT(dest.low == eax);
MOZ_ASSERT(dest.high == edx);
masm.cdq();
#elif defined(JS_CODEGEN_ARM)
masm.ma_mov(src, dest.low);
masm.ma_asr(Imm32(31), src, dest.high);
#else
MOZ_CRASH("BaseCompiler platform hook: signExtendI32ToI64");
#endif
}
void extendU32ToI64(RegI32 src, RegI64 dest) {
#if defined(JS_CODEGEN_X64)
masm.movl(src, dest.reg);
#elif defined(JS_NUNBOX32)
if (src != dest.low)
masm.move32(src, dest.low);
masm.move32(Imm32(0), dest.high);
#else
MOZ_CRASH("BaseCompiler platform hook: extendU32ToI64");
#endif
}
class OutOfLineTruncateF32OrF64ToI32 : public OutOfLineCode
{
AnyReg src;
@ -4481,12 +4389,12 @@ BaseCompiler::emitCopysignF64()
pop2xF64(&r0, &r1);
RegI64 x0 = needI64();
RegI64 x1 = needI64();
reinterpretF64AsI64(r0, x0);
reinterpretF64AsI64(r1, x1);
masm.moveDoubleToGPR64(r0, x0);
masm.moveDoubleToGPR64(r1, x1);
masm.and64(Imm64(INT64_MAX), x0);
masm.and64(Imm64(INT64_MIN), x1);
masm.or64(x1, x0);
reinterpretI64AsF64(x0, r0);
masm.moveGPR64ToDouble(x0, r0);
freeI64(x0);
freeI64(x1);
freeF64(r1);
@ -4985,7 +4893,7 @@ BaseCompiler::emitWrapI64ToI32()
{
RegI64 r0 = popI64();
RegI32 i0 = fromI64(r0);
wrapI64ToI32(r0, i0);
masm.move64To32(r0, i0);
freeI64Except(r0, i0);
pushI32(i0);
}
@ -5010,7 +4918,7 @@ void
BaseCompiler::emitExtendI64_8()
{
RegI64 r = popI64ForSignExtendI64();
signExtendI64_8(r);
masm.move8To64SignExtend(lowPart(r), r);
pushI64(r);
}
@ -5018,7 +4926,7 @@ void
BaseCompiler::emitExtendI64_16()
{
RegI64 r = popI64ForSignExtendI64();
signExtendI64_16(r);
masm.move16To64SignExtend(lowPart(r), r);
pushI64(r);
}
@ -5026,20 +4934,16 @@ void
BaseCompiler::emitExtendI64_32()
{
RegI64 x0 = popI64ForSignExtendI64();
RegI32 r0 = RegI32(lowPart(x0));
signExtendI32ToI64(r0, x0);
masm.move32To64SignExtend(lowPart(x0), x0);
pushI64(x0);
// Note: no need to free r0, since it is part of x0
}
void
BaseCompiler::emitExtendI32ToI64()
{
RegI64 x0 = popI32ForSignExtendI64();
RegI32 r0 = RegI32(lowPart(x0));
signExtendI32ToI64(r0, x0);
masm.move32To64SignExtend(lowPart(x0), x0);
pushI64(x0);
// Note: no need to free r0, since it is part of x0
}
void
@ -5047,9 +4951,8 @@ BaseCompiler::emitExtendU32ToI64()
{
RegI32 r0 = popI32();
RegI64 x0 = widenI32(r0);
extendU32ToI64(r0, x0);
masm.move32To64ZeroExtend(r0, x0);
pushI64(x0);
// Note: no need to free r0, since it is part of x0
}
void
@ -5067,7 +4970,7 @@ BaseCompiler::emitReinterpretF64AsI64()
{
RegF64 r0 = popF64();
RegI64 x0 = needI64();
reinterpretF64AsI64(r0, x0);
masm.moveDoubleToGPR64(r0, x0);
freeF64(r0);
pushI64(x0);
}
@ -5201,7 +5104,7 @@ BaseCompiler::emitReinterpretI64AsF64()
{
RegI64 r0 = popI64();
RegF64 d0 = needF64();
reinterpretI64AsF64(r0, d0);
masm.moveGPR64ToDouble(r0, d0);
freeI64(r0);
pushF64(d0);
}