mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 00:55:37 +00:00
Bug 1001346 - IonMonkey MIPS: Adding MIPS OdinMonkey code part 2 (shared code). r=luke
This commit is contained in:
parent
b74b3c6b14
commit
59f1d2895e
@ -1574,12 +1574,14 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
// instruction.
|
||||
while (labelOffset != LabelBase::INVALID_OFFSET) {
|
||||
size_t patchAtOffset = masm_.labelOffsetToPatchOffset(labelOffset);
|
||||
AsmJSModule::RelativeLink link;
|
||||
AsmJSModule::RelativeLink link(AsmJSModule::RelativeLink::CodeLabel);
|
||||
link.patchAtOffset = patchAtOffset;
|
||||
link.targetOffset = targetOffset;
|
||||
if (!module_->addRelativeLink(link))
|
||||
return false;
|
||||
labelOffset = *(uintptr_t *)(module_->codeBase() + patchAtOffset);
|
||||
|
||||
labelOffset = Assembler::extractCodeLabelOffset(module_->codeBase() +
|
||||
patchAtOffset);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1588,7 +1590,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
FuncPtrTable &table = funcPtrTables_[tableIndex];
|
||||
unsigned tableBaseOffset = module_->offsetOfGlobalData() + table.globalDataOffset();
|
||||
for (unsigned elemIndex = 0; elemIndex < table.numElems(); elemIndex++) {
|
||||
AsmJSModule::RelativeLink link;
|
||||
AsmJSModule::RelativeLink link(AsmJSModule::RelativeLink::RawPointer);
|
||||
link.patchAtOffset = tableBaseOffset + elemIndex * sizeof(uint8_t*);
|
||||
link.targetOffset = masm_.actualOffset(table.elem(elemIndex).code()->offset());
|
||||
if (!module_->addRelativeLink(link))
|
||||
@ -1602,7 +1604,7 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
// code section so we can just use an RelativeLink.
|
||||
for (unsigned i = 0; i < masm_.numAsmJSGlobalAccesses(); i++) {
|
||||
AsmJSGlobalAccess a = masm_.asmJSGlobalAccess(i);
|
||||
AsmJSModule::RelativeLink link;
|
||||
AsmJSModule::RelativeLink link(AsmJSModule::RelativeLink::InstructionImmediate);
|
||||
link.patchAtOffset = masm_.labelOffsetToPatchOffset(a.patchAt.offset());
|
||||
link.targetOffset = module_->offsetOfGlobalData() + a.globalDataOffset;
|
||||
if (!module_->addRelativeLink(link))
|
||||
@ -1620,6 +1622,24 @@ class MOZ_STACK_CLASS ModuleCompiler
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
// On MIPS we need to update all the long jumps because they contain an
|
||||
// absolute adress.
|
||||
for (size_t i = 0; i < masm_.numLongJumps(); i++) {
|
||||
uint32_t patchAtOffset = masm_.longJump(i);
|
||||
|
||||
AsmJSModule::RelativeLink link(AsmJSModule::RelativeLink::InstructionImmediate);
|
||||
link.patchAtOffset = patchAtOffset;
|
||||
|
||||
InstImm *inst = (InstImm *)(module_->codeBase() + patchAtOffset);
|
||||
link.targetOffset = Assembler::extractLuiOriValue(inst, inst->next()) -
|
||||
(uint32_t)module_->codeBase();
|
||||
|
||||
if (!module_->addRelativeLink(link))
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
|
||||
// Absolute links
|
||||
for (size_t i = 0; i < masm_.numAsmJSAbsoluteLinks(); i++) {
|
||||
AsmJSAbsoluteLink src = masm_.asmJSAbsoluteLink(i);
|
||||
@ -6055,14 +6075,22 @@ StackDecrementForCall(MacroAssembler &masm, const VectorT &argTypes, unsigned ex
|
||||
return StackDecrementForCall(masm, StackArgBytes(argTypes) + extraBytes);
|
||||
}
|
||||
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
// Mips is using one more double slot due to stack alignment for double values.
|
||||
// Look at MacroAssembler::PushRegsInMask(RegisterSet set)
|
||||
static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * sizeof(intptr_t) +
|
||||
NonVolatileRegs.fpus().size() * sizeof(double) +
|
||||
sizeof(double);
|
||||
#else
|
||||
static const unsigned FramePushedAfterSave = NonVolatileRegs.gprs().size() * sizeof(intptr_t) +
|
||||
NonVolatileRegs.fpus().size() * sizeof(double);
|
||||
#endif
|
||||
|
||||
// On arm, we need to include an extra word of space at the top of the stack so
|
||||
// we can explicitly store the return address before making the call to C++ or
|
||||
// Ion. On x86/x64, this isn't necessary since the call instruction pushes the
|
||||
// return address.
|
||||
#ifdef JS_CODEGEN_ARM
|
||||
// On ARM/MIPS, we need to include an extra word of space at the top of the
|
||||
// stack so we can explicitly store the return address before making the call
|
||||
// to C++ or Ion. On x86/x64, this isn't necessary since the call instruction
|
||||
// pushes the return address.
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
static const unsigned MaybeRetAddr = sizeof(void*);
|
||||
#else
|
||||
static const unsigned MaybeRetAddr = 0;
|
||||
@ -6087,6 +6115,9 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
|
||||
// pop.
|
||||
masm.push(lr);
|
||||
#endif // JS_CODEGEN_ARM
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
masm.push(ra);
|
||||
#endif
|
||||
|
||||
masm.PushRegsInMask(NonVolatileRegs);
|
||||
JS_ASSERT(masm.framePushed() == FramePushedAfterSave);
|
||||
@ -6099,17 +6130,17 @@ GenerateEntry(ModuleCompiler &m, const AsmJSModule::ExportedFunction &exportedFu
|
||||
LoadAsmJSActivationIntoRegister(masm, activation);
|
||||
masm.storePtr(StackPointer, Address(activation, AsmJSActivation::offsetOfErrorRejoinSP()));
|
||||
|
||||
// ARM has a globally-pinned GlobalReg (x64 uses RIP-relative addressing,
|
||||
// x86 uses immediates in effective addresses) and NaN register (used as
|
||||
// part of the out-of-bounds handling in heap loads/stores).
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
// ARM and MIPS have a globally-pinned GlobalReg (x64 uses RIP-relative
|
||||
// addressing, x86 uses immediates in effective addresses) and NaN register
|
||||
// (used as part of the out-of-bounds handling in heap loads/stores).
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
masm.movePtr(IntArgReg1, GlobalReg);
|
||||
masm.ma_vimm(GenericNaN(), NANReg);
|
||||
masm.loadConstantDouble(GenericNaN(), NANReg);
|
||||
#endif
|
||||
|
||||
// ARM and x64 have a globally-pinned HeapReg (x86 uses immediates in
|
||||
// ARM, MIPS and x64 have a globally-pinned HeapReg (x86 uses immediates in
|
||||
// effective addresses).
|
||||
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM)
|
||||
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
masm.loadPtr(Address(IntArgReg1, m.module().heapOffset()), HeapReg);
|
||||
#endif
|
||||
|
||||
@ -6345,6 +6376,9 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
// pop.
|
||||
masm.push(lr);
|
||||
#endif
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
masm.push(ra);
|
||||
#endif
|
||||
|
||||
MIRType typeArray[] = { MIRType_Pointer, // cx
|
||||
MIRType_Pointer, // exitDatum
|
||||
@ -6353,15 +6387,17 @@ GenerateFFIInterpreterExit(ModuleCompiler &m, const ModuleCompiler::ExitDescript
|
||||
MIRTypeVector invokeArgTypes(m.cx());
|
||||
invokeArgTypes.infallibleAppend(typeArray, ArrayLength(typeArray));
|
||||
|
||||
// The stack layout looks like:
|
||||
// | return address | stack arguments | array of values |
|
||||
unsigned arraySize = Max<size_t>(1, exit.sig().args().length()) * sizeof(Value);
|
||||
unsigned stackDec = StackDecrementForCall(masm, invokeArgTypes, arraySize + MaybeRetAddr);
|
||||
// At the point of the call, the stack layout shall be (sp grows to the left):
|
||||
// | retaddr | stack args | padding | Value argv[] | padding | retaddr | caller stack args |
|
||||
// The first padding ensures double-alignment of argv; the second ensures
|
||||
// sp is aligned.
|
||||
unsigned offsetToArgv = AlignBytes(StackArgBytes(invokeArgTypes) + MaybeRetAddr, StackAlignment);
|
||||
unsigned argvBytes = Max<size_t>(1, exit.sig().args().length()) * sizeof(Value);
|
||||
unsigned stackDec = StackDecrementForCall(masm, offsetToArgv + argvBytes);
|
||||
masm.reserveStack(stackDec);
|
||||
|
||||
// Fill the argument array.
|
||||
unsigned offsetToCallerStackArgs = AlignmentAtAsmJSPrologue + masm.framePushed();
|
||||
unsigned offsetToArgv = StackArgBytes(invokeArgTypes) + MaybeRetAddr;
|
||||
Register scratch = ABIArgGenerator::NonArgReturnVolatileReg0;
|
||||
FillArgumentArray(m, exit.sig().args(), offsetToArgv, offsetToCallerStackArgs, scratch);
|
||||
|
||||
@ -6523,6 +6559,9 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
// The NANReg also needs to be restored, but is a constant and is reloaded before
|
||||
// returning to asm.js code.
|
||||
masm.PushRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
masm.push(ra);
|
||||
masm.PushRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
|
||||
#endif
|
||||
|
||||
// The stack frame is used for the call into Ion and also for calls into C for OOL
|
||||
@ -6625,7 +6664,15 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
LoadAsmJSActivationIntoRegister(masm, reg0);
|
||||
|
||||
// Record sp in the AsmJSActivation for stack-walking.
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
// Add a flag to indicate to AsmJSFrameIterator that we are calling
|
||||
// into Ion, since the offset from SP to the return address is
|
||||
// different when calling Ion vs. the native ABI.
|
||||
masm.ma_or(reg1, StackPointer, Imm32(0x1));
|
||||
masm.storePtr(reg1, Address(reg0, AsmJSActivation::offsetOfExitSP()));
|
||||
#else
|
||||
masm.storePtr(StackPointer, Address(reg0, AsmJSActivation::offsetOfExitSP()));
|
||||
#endif
|
||||
|
||||
// The following is inlined:
|
||||
// JSContext *cx = activation->cx();
|
||||
@ -6719,8 +6766,8 @@ GenerateFFIIonExit(ModuleCompiler &m, const ModuleCompiler::ExitDescriptor &exit
|
||||
#if defined(JS_CODEGEN_X64)
|
||||
masm.Pop(HeapReg);
|
||||
#endif
|
||||
#if defined(JS_CODEGEN_ARM)
|
||||
masm.ma_vimm(GenericNaN(), NANReg);
|
||||
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
masm.loadConstantDouble(GenericNaN(), NANReg);
|
||||
masm.PopRegsInMask(GeneralRegisterSet((1<<GlobalReg.code()) | (1<<HeapReg.code())));
|
||||
#endif
|
||||
masm.ret();
|
||||
@ -6811,7 +6858,7 @@ GenerateInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.align(CodeAlignment);
|
||||
masm.bind(&m.interruptLabel());
|
||||
|
||||
#ifndef JS_CODEGEN_ARM
|
||||
#if defined(JS_CODEGEN_X86) || defined(JS_CODEGEN_X64)
|
||||
// Be very careful here not to perturb the machine state before saving it
|
||||
// to the stack. In particular, add/sub instructions may set conditions in
|
||||
// the flags register.
|
||||
@ -6857,7 +6904,47 @@ GenerateInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.PopRegsInMask(AllRegsExceptSP); // restore all GP/FP registers (except SP)
|
||||
masm.popFlags(); // after this, nothing that sets conditions
|
||||
masm.ret(); // pop resumePC into PC
|
||||
#else
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
// Reserve space to store resumePC.
|
||||
masm.subPtr(Imm32(sizeof(intptr_t)), StackPointer);
|
||||
// set to zero so we can use masm.framePushed() below.
|
||||
masm.setFramePushed(0);
|
||||
// save all registers,except sp. After this stack is alligned.
|
||||
masm.PushRegsInMask(AllRegsExceptSP);
|
||||
|
||||
// Save the stack pointer in a non-volatile register.
|
||||
masm.movePtr(StackPointer, s0);
|
||||
// Align the stack.
|
||||
masm.ma_and(StackPointer, StackPointer, Imm32(~(StackAlignment - 1)));
|
||||
|
||||
// Store resumePC into the reserved space.
|
||||
LoadAsmJSActivationIntoRegister(masm, IntArgReg0);
|
||||
masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfResumePC()), IntArgReg1);
|
||||
masm.storePtr(IntArgReg1, Address(s0, masm.framePushed()));
|
||||
|
||||
// argument 0: cx
|
||||
masm.loadPtr(Address(IntArgReg0, AsmJSActivation::offsetOfContext()), IntArgReg0);
|
||||
|
||||
// MIPS ABI requires rewserving stack for registes $a0 to $a3.
|
||||
masm.subPtr(Imm32(4 * sizeof(intptr_t)), StackPointer);
|
||||
|
||||
masm.call(AsmJSImm_HandleExecutionInterrupt);
|
||||
|
||||
masm.addPtr(Imm32(4 * sizeof(intptr_t)), StackPointer);
|
||||
|
||||
masm.branchIfFalseBool(ReturnReg, throwLabel);
|
||||
|
||||
// This will restore stack to the address before the call.
|
||||
masm.movePtr(s0, StackPointer);
|
||||
masm.PopRegsInMask(AllRegsExceptSP);
|
||||
|
||||
// Pop resumePC into PC. Clobber HeapReg to make the jump and restore it
|
||||
// during jump delay slot.
|
||||
JS_ASSERT(Imm16::isInSignedRange(m.module().heapOffset()));
|
||||
masm.pop(HeapReg);
|
||||
masm.as_jr(HeapReg);
|
||||
masm.loadPtr(Address(GlobalReg, m.module().heapOffset()), HeapReg);
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
masm.setFramePushed(0); // set to zero so we can use masm.framePushed() below
|
||||
masm.PushRegsInMask(RegisterSet(GeneralRegisterSet(Registers::AllMask & ~(1<<Registers::sp)), FloatRegisterSet(uint32_t(0)))); // save all GP registers,excep sp
|
||||
|
||||
@ -6905,6 +6992,8 @@ GenerateInterruptExit(ModuleCompiler &m, Label *throwLabel)
|
||||
masm.finishDataTransfer();
|
||||
masm.ret();
|
||||
|
||||
#else
|
||||
# error "Unknown architecture!"
|
||||
#endif
|
||||
|
||||
return !masm.oom();
|
||||
|
@ -52,13 +52,29 @@ AsmJSFrameIterator::AsmJSFrameIterator(const AsmJSActivation *activation)
|
||||
// to C++. Since the call instruction pushes the return address, we know
|
||||
// that the return address is 1 word below exitSP.
|
||||
returnAddress_ = *(uint8_t**)(sp_ - sizeof(void*));
|
||||
#else
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
// For calls to Ion/C++ on ARM, the *caller* pushes the return address on
|
||||
// the stack. For Ion, this is just part of the ABI. For C++, the return
|
||||
// address is explicitly pushed before the call since we cannot expect the
|
||||
// callee to immediately push lr. This means that exitSP points to the
|
||||
// return address.
|
||||
returnAddress_ = *(uint8_t**)sp_;
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
// On MIPS we have two cases. Exit to C++ will store return addres at
|
||||
// sp + 16, While on exits to Ion, the return address will be stored at
|
||||
// sp + 0. We indicate exits to ion by setting the lowest bit of stored sp.
|
||||
|
||||
// Check if this is the exit to Ion.
|
||||
if (uint32_t(sp_) & 0x1) {
|
||||
// Clear the low bit.
|
||||
sp_ -= 0x1;
|
||||
returnAddress_ = *(uint8_t**)sp_;
|
||||
} else {
|
||||
// This is exit to C++
|
||||
returnAddress_ = *(uint8_t**)(sp_ + ShadowStackSpace);
|
||||
}
|
||||
#else
|
||||
# error "Unknown architecture!"
|
||||
#endif
|
||||
|
||||
settle();
|
||||
|
@ -313,7 +313,12 @@ AsmJSModule::staticallyLink(ExclusiveContext *cx)
|
||||
|
||||
for (size_t i = 0; i < staticLinkData_.relativeLinks.length(); i++) {
|
||||
RelativeLink link = staticLinkData_.relativeLinks[i];
|
||||
*(void **)(code_ + link.patchAtOffset) = code_ + link.targetOffset;
|
||||
uint8_t *patchAt = code_ + link.patchAtOffset;
|
||||
uint8_t *target = code_ + link.targetOffset;
|
||||
if (link.isRawPointerPatch())
|
||||
*(uint8_t **)(patchAt) = target;
|
||||
else
|
||||
Assembler::patchInstructionImmediate(patchAt, PatchedImmPtr(target));
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < staticLinkData_.absoluteLinks.length(); i++) {
|
||||
@ -1013,7 +1018,8 @@ GetCPUID(uint32_t *cpuId)
|
||||
X86 = 0x1,
|
||||
X64 = 0x2,
|
||||
ARM = 0x3,
|
||||
ARCH_BITS = 2
|
||||
MIPS = 0x4,
|
||||
ARCH_BITS = 3
|
||||
};
|
||||
|
||||
#if defined(JS_CODEGEN_X86)
|
||||
@ -1028,6 +1034,10 @@ GetCPUID(uint32_t *cpuId)
|
||||
JS_ASSERT(GetARMFlags() <= (UINT32_MAX >> ARCH_BITS));
|
||||
*cpuId = ARM | (GetARMFlags() << ARCH_BITS);
|
||||
return true;
|
||||
#elif defined(JS_CODEGEN_MIPS)
|
||||
JS_ASSERT(GetMIPSFlags() <= (UINT32_MAX >> ARCH_BITS));
|
||||
*cpuId = MIPS | (GetMIPSFlags() << ARCH_BITS);
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
|
@ -370,6 +370,39 @@ class AsmJSModule
|
||||
|
||||
struct RelativeLink
|
||||
{
|
||||
enum Kind
|
||||
{
|
||||
RawPointer,
|
||||
CodeLabel,
|
||||
InstructionImmediate
|
||||
};
|
||||
|
||||
RelativeLink()
|
||||
{ }
|
||||
|
||||
RelativeLink(Kind kind)
|
||||
{
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
kind_ = kind;
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
// On ARM, CodeLabels are only used to label raw pointers, so in
|
||||
// all cases on ARM, a RelativePatch means patching a raw pointer.
|
||||
JS_ASSERT(kind == CodeLabel || kind == RawPointer);
|
||||
#endif
|
||||
// On X64 and X86, all RelativePatch-es are patched as raw pointers.
|
||||
}
|
||||
|
||||
bool isRawPointerPatch() {
|
||||
#if defined(JS_CODEGEN_MIPS)
|
||||
return kind_ == RawPointer;
|
||||
#else
|
||||
return true;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef JS_CODEGEN_MIPS
|
||||
Kind kind_;
|
||||
#endif
|
||||
uint32_t patchAtOffset;
|
||||
uint32_t targetOffset;
|
||||
};
|
||||
@ -727,7 +760,8 @@ class AsmJSModule
|
||||
// The global data section is placed after the executable code (i.e., at
|
||||
// offset codeBytes_) in the module's linear allocation. The global data
|
||||
// are laid out in this order:
|
||||
// 0. a pointer/descriptor for the heap that was linked to the module
|
||||
// 0. a pointer (padded up to 8 bytes to ensure double-alignment of
|
||||
// globals) for the heap that was linked to the module.
|
||||
// 1. global variable state (elements are sizeof(uint64_t))
|
||||
// 2. interleaved function-pointer tables and exits. These are allocated
|
||||
// while type checking function bodies (as exits and uses of
|
||||
@ -740,7 +774,7 @@ class AsmJSModule
|
||||
return code_ + offsetOfGlobalData();
|
||||
}
|
||||
size_t globalDataBytes() const {
|
||||
return sizeof(void*) +
|
||||
return sizeof(uint64_t) +
|
||||
pod.numGlobalVars_ * sizeof(uint64_t) +
|
||||
pod.funcPtrTableAndExitBytes_;
|
||||
}
|
||||
@ -752,7 +786,7 @@ class AsmJSModule
|
||||
}
|
||||
unsigned globalVarIndexToGlobalDataOffset(unsigned i) const {
|
||||
JS_ASSERT(i < pod.numGlobalVars_);
|
||||
return sizeof(void*) +
|
||||
return sizeof(uint64_t) +
|
||||
i * sizeof(uint64_t);
|
||||
}
|
||||
void *globalVarIndexToGlobalDatum(unsigned i) const {
|
||||
|
@ -86,6 +86,11 @@ using JS::GenericNaN;
|
||||
# else
|
||||
# define R15_sig(p) ((p)->uc_mcontext.gregs[REG_R15])
|
||||
# endif
|
||||
# if defined(__linux__) && defined(__mips__)
|
||||
# define EPC_sig(p) ((p)->uc_mcontext.pc)
|
||||
# define RSP_sig(p) ((p)->uc_mcontext.gregs[29])
|
||||
# define RFP_sig(p) ((p)->uc_mcontext.gregs[30])
|
||||
# endif
|
||||
#elif defined(__NetBSD__)
|
||||
# define XMM_sig(p,i) (((struct fxsave64 *)(p)->uc_mcontext.__fpregs)->fx_xmm[i])
|
||||
# define EIP_sig(p) ((p)->uc_mcontext.__gregs[_REG_EIP])
|
||||
@ -282,6 +287,37 @@ typedef struct ucontext {
|
||||
// Other fields are not used so don't define them here.
|
||||
} ucontext_t;
|
||||
|
||||
# elif defined(__mips__)
|
||||
|
||||
typedef struct {
|
||||
uint32_t regmask;
|
||||
uint32_t status;
|
||||
uint64_t pc;
|
||||
uint64_t gregs[32];
|
||||
uint64_t fpregs[32];
|
||||
uint32_t acx;
|
||||
uint32_t fpc_csr;
|
||||
uint32_t fpc_eir;
|
||||
uint32_t used_math;
|
||||
uint32_t dsp;
|
||||
uint64_t mdhi;
|
||||
uint64_t mdlo;
|
||||
uint32_t hi1;
|
||||
uint32_t lo1;
|
||||
uint32_t hi2;
|
||||
uint32_t lo2;
|
||||
uint32_t hi3;
|
||||
uint32_t lo3;
|
||||
} mcontext_t;
|
||||
|
||||
typedef struct ucontext {
|
||||
uint32_t uc_flags;
|
||||
struct ucontext* uc_link;
|
||||
stack_t uc_stack;
|
||||
mcontext_t uc_mcontext;
|
||||
// Other fields are not used so don't define them here.
|
||||
} ucontext_t;
|
||||
|
||||
# elif defined(__i386__)
|
||||
// x86 version for Android.
|
||||
typedef struct {
|
||||
@ -326,6 +362,8 @@ static bool IsSignalHandlingBroken() { return false; }
|
||||
# define PC_sig(p) EIP_sig(p)
|
||||
#elif defined(JS_CPU_ARM)
|
||||
# define PC_sig(p) R15_sig(p)
|
||||
#elif defined(JS_CPU_MIPS)
|
||||
# define PC_sig(p) EPC_sig(p)
|
||||
#endif
|
||||
|
||||
static bool
|
||||
@ -355,7 +393,6 @@ HandleSimulatorInterrupt(JSRuntime *rt, AsmJSActivation *activation, void *fault
|
||||
static uint8_t **
|
||||
ContextToPC(CONTEXT *context)
|
||||
{
|
||||
JS_STATIC_ASSERT(sizeof(PC_sig(context)) == sizeof(void*));
|
||||
return reinterpret_cast<uint8_t**>(&PC_sig(context));
|
||||
}
|
||||
|
||||
|
@ -15,10 +15,10 @@
|
||||
|
||||
#include "jit/arm/Assembler-arm.h"
|
||||
|
||||
#define HWCAP_USE_HARDFP_ABI (1 << 28)
|
||||
#define HWCAP_USE_HARDFP_ABI (1 << 27)
|
||||
|
||||
#if !(defined(ANDROID) || defined(MOZ_B2G)) && !defined(JS_ARM_SIMULATOR)
|
||||
#define HWCAP_ARMv7 (1 << 29)
|
||||
#define HWCAP_ARMv7 (1 << 28)
|
||||
#include <asm/hwcap.h>
|
||||
#else
|
||||
#define HWCAP_VFP (1<<0)
|
||||
|
@ -1798,6 +1798,11 @@ class Assembler : public AssemblerShared
|
||||
static void patchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
|
||||
ImmPtr expectedValue);
|
||||
static void patchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
|
||||
|
||||
static void patchInstructionImmediate(uint8_t *code, PatchedImmPtr imm) {
|
||||
MOZ_ASSUME_UNREACHABLE("Unused.");
|
||||
}
|
||||
|
||||
static uint32_t alignDoubleArg(uint32_t offset) {
|
||||
return (offset+1)&~1;
|
||||
}
|
||||
@ -1811,6 +1816,10 @@ class Assembler : public AssemblerShared
|
||||
|
||||
static void updateBoundsCheck(uint32_t logHeapSize, Instruction *inst);
|
||||
void processCodeLabels(uint8_t *rawCode);
|
||||
static int32_t extractCodeLabelOffset(uint8_t *code) {
|
||||
return *(uintptr_t *)code;
|
||||
}
|
||||
|
||||
bool bailed() {
|
||||
return m_buffer.bail();
|
||||
}
|
||||
|
@ -28,7 +28,7 @@ namespace js {
|
||||
namespace jit {
|
||||
|
||||
// Shadow stack space is not required on MIPS.
|
||||
static const uint32_t ShadowStackSpace = 0;
|
||||
static const uint32_t ShadowStackSpace = 4 * sizeof(uintptr_t);
|
||||
|
||||
// These offsets are specific to nunboxing, and capture offsets into the
|
||||
// components of a js::Value.
|
||||
|
@ -329,6 +329,12 @@ Assembler::processCodeLabels(uint8_t *rawCode)
|
||||
}
|
||||
}
|
||||
|
||||
int32_t
|
||||
Assembler::extractCodeLabelOffset(uint8_t *code) {
|
||||
InstImm *inst = (InstImm *)code;
|
||||
return Assembler::extractLuiOriValue(inst, inst->next());
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::Bind(uint8_t *rawCode, AbsoluteLabel *label, const void *address)
|
||||
{
|
||||
@ -1450,6 +1456,13 @@ Assembler::patchWrite_Imm32(CodeLocationLabel label, Imm32 imm)
|
||||
*(raw - 1) = imm.value;
|
||||
}
|
||||
|
||||
void
|
||||
Assembler::patchInstructionImmediate(uint8_t *code, PatchedImmPtr imm)
|
||||
{
|
||||
InstImm *inst = (InstImm *)code;
|
||||
Assembler::updateLuiOriValue(inst, inst->next(), (uint32_t)imm.value);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
Assembler::nextInstruction(uint8_t *inst_, uint32_t *count)
|
||||
{
|
||||
|
@ -89,7 +89,7 @@ class ABIArgGenerator
|
||||
|
||||
uint32_t stackBytesConsumedSoFar() const {
|
||||
if (usedArgSlots_ <= 4)
|
||||
return 4 * sizeof(intptr_t);
|
||||
return ShadowStackSpace;
|
||||
|
||||
return usedArgSlots_ * sizeof(intptr_t);
|
||||
}
|
||||
@ -1033,6 +1033,9 @@ class Assembler : public AssemblerShared
|
||||
static void patchDataWithValueCheck(CodeLocationLabel label, ImmPtr newValue,
|
||||
ImmPtr expectedValue);
|
||||
static void patchWrite_Imm32(CodeLocationLabel label, Imm32 imm);
|
||||
|
||||
static void patchInstructionImmediate(uint8_t *code, PatchedImmPtr imm);
|
||||
|
||||
static uint32_t alignDoubleArg(uint32_t offset) {
|
||||
return (offset + 1U) &~ 1U;
|
||||
}
|
||||
@ -1046,6 +1049,7 @@ class Assembler : public AssemblerShared
|
||||
|
||||
static void updateBoundsCheck(uint32_t logHeapSize, Instruction *inst);
|
||||
void processCodeLabels(uint8_t *rawCode);
|
||||
static int32_t extractCodeLabelOffset(uint8_t *code);
|
||||
|
||||
bool bailed() {
|
||||
return m_buffer.bail();
|
||||
|
@ -691,7 +691,7 @@ class AsmJSHeapAccess
|
||||
isFloat32Load_(false),
|
||||
loadedReg_(UINT8_MAX)
|
||||
{}
|
||||
#elif defined(JS_CODEGEN_ARM)
|
||||
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
|
||||
explicit AsmJSHeapAccess(uint32_t offset)
|
||||
: offset_(offset)
|
||||
{}
|
||||
|
@ -288,6 +288,9 @@ class AssemblerX86Shared : public AssemblerShared
|
||||
|
||||
void executableCopy(void *buffer);
|
||||
void processCodeLabels(uint8_t *rawCode);
|
||||
static int32_t extractCodeLabelOffset(uint8_t *code) {
|
||||
return *(uintptr_t *)code;
|
||||
}
|
||||
void copyJumpRelocationTable(uint8_t *dest);
|
||||
void copyDataRelocationTable(uint8_t *dest);
|
||||
void copyPreBarrierTable(uint8_t *dest);
|
||||
@ -1677,6 +1680,11 @@ class AssemblerX86Shared : public AssemblerShared
|
||||
static void patchDataWithValueCheck(CodeLocationLabel data, ImmPtr newData, ImmPtr expectedData) {
|
||||
patchDataWithValueCheck(data, PatchedImmPtr(newData.value), PatchedImmPtr(expectedData.value));
|
||||
}
|
||||
|
||||
static void patchInstructionImmediate(uint8_t *code, PatchedImmPtr imm) {
|
||||
MOZ_ASSUME_UNREACHABLE("Unused.");
|
||||
}
|
||||
|
||||
static uint32_t nopSize() {
|
||||
return 1;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user