286 lines
10 KiB
Diff
286 lines
10 KiB
Diff
# HG changeset patch
|
|
# User Cameron Kaiser <spectre@floodgap.com>
|
|
# Date 1695240514 25200
|
|
# Wed Sep 20 13:08:34 2023 -0700
|
|
# Node ID bd8eea54a76bd887fd7741eb252ee8bc09bf79f2
|
|
# Parent 3ac07c6a65bceaeb75d59aafa7728388c31ea11d
|
|
Ion fixes
|
|
|
|
diff -r 3ac07c6a65bc -r bd8eea54a76b js/src/jit/JitFrames.cpp
|
|
--- a/js/src/jit/JitFrames.cpp Fri Sep 15 12:44:43 2023 -0700
|
|
+++ b/js/src/jit/JitFrames.cpp Wed Sep 20 13:08:34 2023 -0700
|
|
@@ -1701,17 +1701,25 @@
|
|
|
|
case RValueAllocation::CST_NULL:
|
|
return NullValue();
|
|
|
|
case RValueAllocation::DOUBLE_REG:
|
|
return DoubleValue(fromRegister<double>(alloc.fpuReg()));
|
|
|
|
case RValueAllocation::ANY_FLOAT_REG:
|
|
+#if defined(JS_CODEGEN_PPC64)
|
|
+ // There is no (simple) way from the ISA to determine if an arbitrary
|
|
+ // FPR contains a float or a double since the ISA treats them largely
|
|
+ // synonymously, so the MachineState will always contain a double even
|
|
+ // if it's encoding a float.
|
|
+ return Float32Value((float)fromRegister<double>(alloc.fpuReg()));
|
|
+#else
|
|
return Float32Value(fromRegister<float>(alloc.fpuReg()));
|
|
+#endif
|
|
|
|
case RValueAllocation::ANY_FLOAT_STACK:
|
|
return Float32Value(ReadFrameFloat32Slot(fp_, alloc.stackOffset()));
|
|
|
|
case RValueAllocation::TYPED_REG:
|
|
return FromTypedPayload(alloc.knownType(), fromRegister(alloc.reg2()));
|
|
|
|
case RValueAllocation::TYPED_STACK: {
|
|
@@ -2316,20 +2324,21 @@
|
|
uintptr_t* addr = state_.as<SafepointState>().addressOfRegister(reg);
|
|
return *addr;
|
|
}
|
|
MOZ_CRASH("Invalid state");
|
|
}
|
|
|
|
template <typename T>
|
|
T MachineState::read(FloatRegister reg) const {
|
|
-#if !defined(JS_CODEGEN_RISCV64)
|
|
+#if !defined(JS_CODEGEN_RISCV64) && !defined(JS_CODEGEN_PPC64)
|
|
MOZ_ASSERT(reg.size() == sizeof(T));
|
|
#else
|
|
// RISCV64 always store FloatRegister as 64bit.
|
|
+ // So does Power ISA (see SnapshotIterator::allocationValue).
|
|
MOZ_ASSERT(reg.size() == sizeof(double));
|
|
#endif
|
|
|
|
#if !defined(JS_CODEGEN_NONE) && !defined(JS_CODEGEN_WASM32)
|
|
if (state_.is<BailoutState>()) {
|
|
uint32_t offset = reg.getRegisterDumpOffsetInBytes();
|
|
MOZ_ASSERT((offset % sizeof(T)) == 0);
|
|
MOZ_ASSERT((offset + sizeof(T)) <= sizeof(RegisterDump::FPUArray));
|
|
diff -r 3ac07c6a65bc -r bd8eea54a76b js/src/jit/LIR.h
|
|
--- a/js/src/jit/LIR.h Fri Sep 15 12:44:43 2023 -0700
|
|
+++ b/js/src/jit/LIR.h Wed Sep 20 13:08:34 2023 -0700
|
|
@@ -547,17 +547,17 @@
|
|
static LDefinition BogusTemp() { return LDefinition(); }
|
|
|
|
Policy policy() const {
|
|
return (Policy)((bits_ >> POLICY_SHIFT) & POLICY_MASK);
|
|
}
|
|
Type type() const { return (Type)((bits_ >> TYPE_SHIFT) & TYPE_MASK); }
|
|
|
|
static bool isFloatRegCompatible(Type type, FloatRegister reg) {
|
|
-#ifdef JS_CODEGEN_RISCV64
|
|
+#if defined(JS_CODEGEN_RISCV64) || defined(JS_CODEGEN_PPC64)
|
|
if (type == FLOAT32 || type == DOUBLE) {
|
|
return reg.isSingle() || reg.isDouble();
|
|
}
|
|
#else
|
|
if (type == FLOAT32) {
|
|
return reg.isSingle();
|
|
}
|
|
if (type == DOUBLE) {
|
|
diff -r 3ac07c6a65bc -r bd8eea54a76b js/src/jit/ppc64/CodeGenerator-ppc64.cpp
|
|
--- a/js/src/jit/ppc64/CodeGenerator-ppc64.cpp Fri Sep 15 12:44:43 2023 -0700
|
|
+++ b/js/src/jit/ppc64/CodeGenerator-ppc64.cpp Wed Sep 20 13:08:34 2023 -0700
|
|
@@ -1364,18 +1364,17 @@
|
|
MOZ_ASSERT(shift == 1);
|
|
masm.x_srwi(tmp, lhs, 31);
|
|
masm.add32(lhs, tmp);
|
|
}
|
|
|
|
// Do the shift.
|
|
masm.as_srawi(dest, tmp, shift);
|
|
} else {
|
|
- if (lhs != dest)
|
|
- masm.move32(lhs, dest);
|
|
+ masm.move32(lhs, dest);
|
|
}
|
|
}
|
|
|
|
void
|
|
CodeGenerator::visitModI(LModI* ins)
|
|
{
|
|
ADBlock();
|
|
|
|
@@ -1627,45 +1626,35 @@
|
|
Register dest = ToRegister(ins->output());
|
|
|
|
if (rhs->isConstant()) {
|
|
int32_t shift = ToInt32(rhs) & 0x1F;
|
|
switch (ins->bitop()) {
|
|
case JSOp::Lsh:
|
|
if (shift)
|
|
masm.x_slwi(dest, lhs, shift);
|
|
- else if (dest != lhs)
|
|
+ else
|
|
masm.move32(lhs, dest);
|
|
break;
|
|
case JSOp::Rsh:
|
|
if (shift)
|
|
masm.as_srawi(dest, lhs, shift);
|
|
- else if (dest != lhs)
|
|
+ else
|
|
masm.move32(lhs, dest);
|
|
break;
|
|
case JSOp::Ursh:
|
|
if (shift) {
|
|
masm.x_srwi(dest, lhs, shift);
|
|
-#if(0)
|
|
- } else if (ins->mir()->toUrsh()->fallible()) {
|
|
+ } else {
|
|
// x >>> 0 can overflow.
|
|
- masm.as_extsw(ScratchRegister, lhs);
|
|
- bailoutCmp32(Assembler::LessThan, ScratchRegister, Imm32(0), ins->snapshot());
|
|
- } else {
|
|
+ if (ins->mir()->toUrsh()->fallible()) {
|
|
+ bailoutCmp32(Assembler::LessThan, lhs, Imm32(0), ins->snapshot());
|
|
+ }
|
|
masm.move32(lhs, dest);
|
|
}
|
|
-#else
|
|
- } else {
|
|
- // x >>> 0 can overflow.
|
|
- if (ins->mir()->toUrsh()->fallible())
|
|
- bailoutCmp32(Assembler::LessThan, lhs, Imm32(0), ins->snapshot());
|
|
- if (dest != lhs)
|
|
- masm.move32(lhs, dest);
|
|
- }
|
|
-#endif
|
|
break;
|
|
default:
|
|
MOZ_CRASH("Unexpected shift op");
|
|
}
|
|
} else {
|
|
// The shift amounts should be AND'ed into the 0-31 range.
|
|
masm.as_andi_rc(dest, ToRegister(rhs), 0x1f);
|
|
|
|
@@ -1675,22 +1664,17 @@
|
|
break;
|
|
case JSOp::Rsh:
|
|
masm.as_sraw(dest, lhs, dest);
|
|
break;
|
|
case JSOp::Ursh:
|
|
masm.as_srw(dest, lhs, dest);
|
|
if (ins->mir()->toUrsh()->fallible()) {
|
|
// x >>> 0 can overflow.
|
|
-#if(0)
|
|
- masm.as_extsw(ScratchRegister, lhs);
|
|
- bailoutCmp32(Assembler::LessThan, ScratchRegister, Imm32(0), ins->snapshot());
|
|
-#else
|
|
bailoutCmp32(Assembler::LessThan, dest, Imm32(0), ins->snapshot());
|
|
-#endif
|
|
}
|
|
break;
|
|
default:
|
|
MOZ_CRASH("Unexpected shift op");
|
|
}
|
|
}
|
|
}
|
|
|
|
diff -r 3ac07c6a65bc -r bd8eea54a76b js/src/jit/ppc64/MacroAssembler-ppc64-inl.h
|
|
--- a/js/src/jit/ppc64/MacroAssembler-ppc64-inl.h Fri Sep 15 12:44:43 2023 -0700
|
|
+++ b/js/src/jit/ppc64/MacroAssembler-ppc64-inl.h Wed Sep 20 13:08:34 2023 -0700
|
|
@@ -369,21 +369,29 @@
|
|
MacroAssembler::mulBy3(Register src, Register dest)
|
|
{
|
|
// I guess this *is* better than mulli.
|
|
MOZ_ASSERT(src != ScratchRegister);
|
|
as_add(ScratchRegister, src, src);
|
|
as_add(dest, ScratchRegister, src);
|
|
}
|
|
|
|
+// This is used in MacroAssembler::loadInt32ToStringWithBase. Instead of
|
|
+// letting us use our superior arithmetic instructions, the JIT has reduced
|
|
+// us to faffing around with magic constants because that's what x86* does.
|
|
+// This leads to sign extension hazards.
|
|
void MacroAssembler::mulHighUnsigned32(Imm32 imm, Register src, Register dest) {
|
|
MOZ_ASSERT(src != ScratchRegister);
|
|
+ // Compensate for (likely) sign extension by always clearing upper bits.
|
|
move32(imm, ScratchRegister);
|
|
- as_mulhw(dest, ScratchRegister, src);
|
|
- x_sldi(dest, dest, 32);
|
|
+ as_rldicl(ScratchRegister, ScratchRegister, 0, 32); // "clrldi"
|
|
+ // loadInt32ToStringWithBase expects what is effectively unsigned multiply.
|
|
+ as_mulhwu(dest, ScratchRegister, src);
|
|
+ // Clear upper bits again, as they are undefined by the spec.
|
|
+ as_rldicl(dest, dest, 0, 32); // "clrldi"
|
|
}
|
|
|
|
void
|
|
MacroAssembler::inc64(AbsoluteAddress dest)
|
|
{
|
|
ma_li(SecondScratchReg, ImmWord(uintptr_t(dest.addr)));
|
|
as_ld(ThirdScratchReg, SecondScratchReg, 0);
|
|
as_addi(ScratchRegister, ThirdScratchReg, 1);
|
|
diff -r 3ac07c6a65bc -r bd8eea54a76b js/src/jit/ppc64/MacroAssembler-ppc64.cpp
|
|
--- a/js/src/jit/ppc64/MacroAssembler-ppc64.cpp Fri Sep 15 12:44:43 2023 -0700
|
|
+++ b/js/src/jit/ppc64/MacroAssembler-ppc64.cpp Wed Sep 20 13:08:34 2023 -0700
|
|
@@ -4769,21 +4769,23 @@
|
|
void
|
|
MacroAssembler::branchPtrInNurseryChunk(Condition cond, Register ptr, Register temp,
|
|
Label* label)
|
|
{
|
|
ADBlock();
|
|
MOZ_ASSERT(cond == Assembler::Equal || cond == Assembler::NotEqual);
|
|
MOZ_ASSERT(ptr != temp);
|
|
MOZ_ASSERT(ptr != ScratchRegister); // Both may be used internally.
|
|
- MOZ_ASSERT(temp != ScratchRegister);
|
|
- MOZ_ASSERT(temp != InvalidReg);
|
|
-
|
|
- ma_and(temp, ptr, Imm32(int32_t(~gc::ChunkMask)));
|
|
- branchPtr(InvertCondition(cond), Address(temp, gc::ChunkStoreBufferOffset),
|
|
+ MOZ_ASSERT(ptr != SecondScratchReg);
|
|
+ MOZ_ASSERT(temp != ScratchRegister); // probably unpossible
|
|
+ MOZ_ASSERT(temp != SecondScratchReg);
|
|
+ MOZ_ASSERT(gc::ChunkStoreBufferOffset < 32767);
|
|
+
|
|
+ ma_and(SecondScratchReg, ptr, Imm32(int32_t(~gc::ChunkMask)));
|
|
+ branchPtr(InvertCondition(cond), Address(SecondScratchReg, gc::ChunkStoreBufferOffset),
|
|
ImmWord(0), label);
|
|
}
|
|
|
|
void
|
|
MacroAssembler::comment(const char* msg)
|
|
{
|
|
Assembler::comment(msg);
|
|
}
|
|
diff -r 3ac07c6a65bc -r bd8eea54a76b js/src/wasm/WasmFrameIter.cpp
|
|
--- a/js/src/wasm/WasmFrameIter.cpp Fri Sep 15 12:44:43 2023 -0700
|
|
+++ b/js/src/wasm/WasmFrameIter.cpp Wed Sep 20 13:08:34 2023 -0700
|
|
@@ -1286,17 +1286,33 @@
|
|
#elif defined(JS_CODEGEN_ARM)
|
|
if (offsetFromEntry == BeforePushRetAddr || codeRange->isThunk()) {
|
|
// The return address is still in lr and fp holds the caller's fp.
|
|
fixedPC = (uint8_t*)registers.lr;
|
|
fixedFP = fp;
|
|
AssertMatchesCallSite(fixedPC, fixedFP);
|
|
} else
|
|
#elif defined(JS_CODEGEN_PPC64)
|
|
- MOZ_ASSERT(0);
|
|
+ if (codeRange->isThunk()) {
|
|
+ // The FarJumpIsland sequence temporarily scrambles LR.
|
|
+ // Don't unwind to the caller.
|
|
+ fixedPC = pc;
|
|
+ fixedFP = fp;
|
|
+ *unwoundCaller = false;
|
|
+ AssertMatchesCallSite(
|
|
+ Frame::fromUntaggedWasmExitFP(fp)->returnAddress(),
|
|
+ Frame::fromUntaggedWasmExitFP(fp)->rawCaller());
|
|
+ } else if (offsetFromEntry < PushedFP) {
|
|
+ // On ppc64 we rely on register state instead of state saved on
|
|
+ // stack until the wasm::Frame is completely built.
|
|
+ // On entry the return address is in LR and fp holds the caller's fp.
|
|
+ fixedPC = (uint8_t*)registers.lr;
|
|
+ fixedFP = fp;
|
|
+ AssertMatchesCallSite(fixedPC, fixedFP);
|
|
+ } else
|
|
#endif
|
|
if (offsetFromEntry == PushedRetAddr || codeRange->isThunk()) {
|
|
// The return address has been pushed on the stack but fp still
|
|
// points to the caller's fp.
|
|
fixedPC = sp[0];
|
|
fixedFP = fp;
|
|
AssertMatchesCallSite(fixedPC, fixedFP);
|
|
} else if (offsetFromEntry == PushedFP) {
|