Bug 1175556 - ARM64: Land miscellaneous changes. r=evilpie

This commit is contained in:
Sean Stangl 2015-06-25 11:37:22 -07:00
Родитель e8b350b32d
Коммит 425c550cf5
37 изменённых файлов: 234 добавлений и 84 удалений

Просмотреть файл

@ -131,6 +131,11 @@ static const unsigned PushedRetAddr = 4;
static const unsigned PushedFP = 16;
static const unsigned StoredFP = 20;
static const unsigned PostStorePrePopFP = 4;
#elif defined(JS_CODEGEN_ARM64)
static const unsigned PushedRetAddr = 0;
static const unsigned PushedFP = 0;
static const unsigned StoredFP = 0;
static const unsigned PostStorePrePopFP = 0;
#elif defined(JS_CODEGEN_MIPS)
static const unsigned PushedRetAddr = 8;
static const unsigned PushedFP = 24;
@ -216,7 +221,7 @@ GenerateProfilingEpilogue(MacroAssembler& masm, unsigned framePushed, AsmJSExit:
Label* profilingReturn)
{
Register scratch = ABIArgGenerator::NonReturn_VolatileReg0;
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS)
Register scratch2 = ABIArgGenerator::NonReturn_VolatileReg1;
#endif
@ -240,11 +245,11 @@ GenerateProfilingEpilogue(MacroAssembler& masm, unsigned framePushed, AsmJSExit:
// and the async interrupt exit. Since activation.fp can be read at any
// time and still points to the current frame, be careful to only update
// sp after activation.fp has been repointed to the caller's frame.
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS)
masm.loadPtr(Address(masm.getStackPointer(), 0), scratch2);
masm.storePtr(scratch2, Address(scratch, AsmJSActivation::offsetOfFP()));
DebugOnly<uint32_t> prePop = masm.currentOffset();
masm.add32(Imm32(4), masm.getStackPointer());
masm.addToStackPtr(Imm32(sizeof(void *)));
MOZ_ASSERT(PostStorePrePopFP == masm.currentOffset() - prePop);
#else
masm.pop(Address(scratch, AsmJSActivation::offsetOfFP()));

Просмотреть файл

@ -1787,6 +1787,9 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext* cx)
BOffImm calleeOffset;
callerInsn->as<InstBLImm>()->extractImm(&calleeOffset);
void* callee = calleeOffset.getDest(callerInsn);
#elif defined(JS_CODEGEN_ARM64)
MOZ_CRASH();
void* callee = nullptr;
#elif defined(JS_CODEGEN_MIPS)
Instruction* instr = (Instruction*)(callerRetAddr - 4 * sizeof(uint32_t));
void* callee = (void*)Assembler::ExtractLuiOriValue(instr, instr->next());
@ -1811,6 +1814,8 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext* cx)
X86Encoding::SetRel32(callerRetAddr, newCallee);
#elif defined(JS_CODEGEN_ARM)
new (caller) InstBLImm(BOffImm(newCallee - caller), Assembler::Always);
#elif defined(JS_CODEGEN_ARM64)
MOZ_CRASH();
#elif defined(JS_CODEGEN_MIPS)
Assembler::WriteLuiOriInstructions(instr, instr->next(),
ScratchRegister, (uint32_t)newCallee);
@ -1874,6 +1879,8 @@ AsmJSModule::setProfilingEnabled(bool enabled, JSContext* cx)
MOZ_ASSERT(reinterpret_cast<Instruction*>(jump)->is<InstBImm>());
new (jump) InstNOP();
}
#elif defined(JS_CODEGEN_ARM64)
MOZ_CRASH();
#elif defined(JS_CODEGEN_MIPS)
Instruction* instr = (Instruction*)jump;
if (enabled) {

Просмотреть файл

@ -1164,8 +1164,8 @@ RedirectJitCodeToInterruptCheck(JSRuntime* rt, CONTEXT* context)
const AsmJSModule& module = activation->module();
#ifdef JS_SIMULATOR
if (module.containsFunctionPC((void*)rt->simulator()->get_pc()))
rt->simulator()->set_resume_pc(int32_t(module.interruptExit()));
if (module.containsFunctionPC(rt->simulator()->get_pc_as<void*>()))
rt->simulator()->set_resume_pc(module.interruptExit());
#endif
uint8_t** ppc = ContextToPC(context);

Просмотреть файл

@ -9080,7 +9080,8 @@ GenerateAsyncInterruptExit(ModuleCompiler& m, Label* throwLabel)
masm.transferReg(lr);
masm.finishDataTransfer();
masm.ret();
#elif defined(JS_CODEGEN_ARM64)
MOZ_CRASH();
#elif defined (JS_CODEGEN_NONE)
MOZ_CRASH();
#else

Просмотреть файл

@ -112,6 +112,14 @@ GetBuildConfiguration(JSContext* cx, unsigned argc, jsval* vp)
if (!JS_SetProperty(cx, info, "arm-simulator", value))
return false;
#ifdef JS_SIMULATOR_ARM64
value = BooleanValue(true);
#else
value = BooleanValue(false);
#endif
if (!JS_SetProperty(cx, info, "arm64-simulator", value))
return false;
#ifdef MOZ_ASAN
value = BooleanValue(true);
#else

Просмотреть файл

@ -120,6 +120,12 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
// registers we need.
masm.bind(&entry_label_);
#ifdef JS_CODEGEN_ARM64
// ARM64 communicates stack address via sp, but uses a pseudo-sp for addressing.
MOZ_ASSERT(!masm.GetStackPointer64().Is(sp));
masm.moveStackPtrTo(masm.getStackPointer());
#endif
// Push non-volatile registers which might be modified by jitcode.
size_t pushedNonVolatileRegisters = 0;
for (GeneralRegisterForwardIterator iter(savedNonVolatileRegisters); iter.more(); ++iter) {
@ -387,7 +393,7 @@ NativeRegExpMacroAssembler::GenerateCode(JSContext* cx, bool match_only)
// Save registers before calling C function
LiveGeneralRegisterSet volatileRegs(GeneralRegisterSet::Volatile());
#if defined(JS_CODEGEN_ARM)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
volatileRegs.add(Register::FromCode(Registers::lr));
#elif defined(JS_CODEGEN_MIPS)
volatileRegs.add(Register::FromCode(Registers::ra));

Просмотреть файл

@ -9,6 +9,8 @@
#if defined(JS_CODEGEN_ARM)
# include "jit/arm/AtomicOperations-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/AtomicOperations-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/AtomicOperations-mips.h"
#elif defined(JS_CODEGEN_NONE)
@ -19,4 +21,4 @@
# error "Atomic operations must be defined for this platform"
#endif
#endif // jit_AtomicOperations_inl_h
#endif // jit_AtomicOperations_inl_h

Просмотреть файл

@ -18,6 +18,8 @@
# include "jit/x64/CodeGenerator-x64.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/CodeGenerator-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/CodeGenerator-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/CodeGenerator-mips.h"
#elif defined(JS_CODEGEN_NONE)

Просмотреть файл

@ -9,6 +9,8 @@
#if defined(JS_CODEGEN_ARM)
# include "jit/arm/Assembler-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/Assembler-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/Assembler-mips.h"
#endif

Просмотреть файл

@ -11,11 +11,13 @@
#if defined(JS_SIMULATOR_ARM)
#include "jit/arm/Simulator-arm.h"
#elif defined(JS_SIMULATOR_ARM64)
# include "jit/arm64/vixl/Simulator-vixl.h"
#elif defined(JS_SIMULATOR_MIPS)
#include "jit/mips/Simulator-mips.h"
#endif
#if defined(JS_SIMULATOR_ARM) || defined(JS_SIMULATOR_MIPS)
#ifdef JS_SIMULATOR
// Call into cross-jitted code by following the ABI of the simulated architecture.
#define CALL_GENERATED_CODE(entry, p0, p1, p2, p3, p4, p5, p6, p7) \
(js::jit::Simulator::Current()->call( \

Просмотреть файл

@ -2593,6 +2593,12 @@ MachineState::FromBailout(RegisterDump::GPRArray& regs, RegisterDump::FPUArray&
machine.setRegisterLocation(FloatRegister(i, FloatRegisters::Int32x4), &fpregs[i]);
machine.setRegisterLocation(FloatRegister(i, FloatRegisters::Float32x4), &fpregs[i]);
}
#elif defined(JS_CODEGEN_ARM64)
for (unsigned i = 0; i < FloatRegisters::TotalPhys; i++) {
machine.setRegisterLocation(FloatRegister(i, FloatRegisters::Single), &fpregs[i]);
machine.setRegisterLocation(FloatRegister(i, FloatRegisters::Double), &fpregs[i]);
}
#elif defined(JS_CODEGEN_NONE)
MOZ_CRASH();
#else

Просмотреть файл

@ -1825,6 +1825,8 @@ LAllocation::toRegister() const
# include "jit/x86-shared/LIR-x86-shared.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/LIR-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/LIR-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/LIR-mips.h"
#elif defined(JS_CODEGEN_NONE)

Просмотреть файл

@ -359,6 +359,8 @@
# include "jit/x64/LOpcodes-x64.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/LOpcodes-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/LOpcodes-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/LOpcodes-mips.h"
#elif defined(JS_CODEGEN_NONE)

Просмотреть файл

@ -17,6 +17,8 @@
# include "jit/x64/Lowering-x64.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/Lowering-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/Lowering-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/Lowering-mips.h"
#elif defined(JS_CODEGEN_NONE)

Просмотреть файл

@ -1594,8 +1594,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
regs.take(bailoutInfo);
// Reset SP to the point where clobbering starts.
loadPtr(Address(bailoutInfo, offsetof(BaselineBailoutInfo, incomingStack)),
BaselineStackReg);
loadStackPtr(Address(bailoutInfo, offsetof(BaselineBailoutInfo, incomingStack)));
Register copyCur = regs.takeAny();
Register copyEnd = regs.takeAny();
@ -1610,7 +1609,7 @@ MacroAssembler::generateBailoutTail(Register scratch, Register bailoutInfo)
bind(&copyLoop);
branchPtr(Assembler::BelowOrEqual, copyCur, copyEnd, &endOfCopy);
subPtr(Imm32(4), copyCur);
subPtr(Imm32(4), BaselineStackReg);
subFromStackPtr(Imm32(4));
load32(Address(copyCur, 0), temp);
store32(temp, Address(BaselineStackReg, 0));
jump(&copyLoop);
@ -2510,9 +2509,12 @@ MacroAssembler::MacroAssembler(JSContext* cx, IonScript* ion,
jitContext_.emplace(cx, (js::jit::TempAllocator*)nullptr);
alloc_.emplace(cx);
moveResolver_.setAllocator(*jitContext_->temp);
#ifdef JS_CODEGEN_ARM
#if defined(JS_CODEGEN_ARM)
initWithAllocator();
m_buffer.id = GetJitContext()->getNextAssemblerId();
#elif defined(JS_CODEGEN_ARM64)
initWithAllocator();
armbuffer_.id = GetJitContext()->getNextAssemblerId();
#endif
if (ion) {
setFramePushed(ion->frameSize());
@ -2707,12 +2709,12 @@ MacroAssembler::freeStack(uint32_t amount)
{
MOZ_ASSERT(amount <= framePushed_);
if (amount)
addPtr(Imm32(amount), StackPointer);
addToStackPtr(Imm32(amount));
framePushed_ -= amount;
}
void
MacroAssembler::freeStack(Register amount)
{
addPtr(amount, StackPointer);
addToStackPtr(amount);
}

Просмотреть файл

@ -17,6 +17,8 @@
# include "jit/x64/MacroAssembler-x64.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/MacroAssembler-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/MacroAssembler-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/MacroAssembler-mips.h"
#elif defined(JS_CODEGEN_NONE)
@ -44,6 +46,8 @@
# define ONLY_X86_X64
#elif defined(JS_CODEGEN_ARM)
# define ONLY_X86_X64 = delete
#elif defined(JS_CODEGEN_ARM64)
# define ONLY_X86_X64 = delete
#elif defined(JS_CODEGEN_MIPS)
# define ONLY_X86_X64 = delete
#elif defined(JS_CODEGEN_NONE)
@ -233,9 +237,13 @@ class MacroAssembler : public MacroAssemblerSpecific
}
moveResolver_.setAllocator(*jcx->temp);
#ifdef JS_CODEGEN_ARM
#if defined(JS_CODEGEN_ARM)
initWithAllocator();
m_buffer.id = jcx->getNextAssemblerId();
#elif defined(JS_CODEGEN_ARM64)
initWithAllocator();
armbuffer_.id = jcx->getNextAssemblerId();
#endif
}
@ -250,9 +258,12 @@ class MacroAssembler : public MacroAssemblerSpecific
: emitProfilingInstrumentation_(false),
framePushed_(0)
{
#ifdef JS_CODEGEN_ARM
#if defined(JS_CODEGEN_ARM)
initWithAllocator();
m_buffer.id = 0;
#elif defined(JS_CODEGEN_ARM64)
initWithAllocator();
armbuffer_.id = 0;
#endif
}
@ -572,7 +583,7 @@ class MacroAssembler : public MacroAssemblerSpecific
}
#elif defined(JS_PUNBOX64)
if (dest.valueReg() != JSReturnReg)
movq(JSReturnReg, dest.valueReg());
mov(JSReturnReg, dest.valueReg());
#else
#error "Bad architecture"
#endif

Просмотреть файл

@ -11,6 +11,8 @@
# include "jit/x86-shared/MoveEmitter-x86-shared.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/MoveEmitter-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/MoveEmitter-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/MoveEmitter-mips.h"
#elif defined(JS_CODEGEN_NONE)

Просмотреть файл

@ -278,6 +278,10 @@ class RegisterAllocator
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
allRegisters_.take(AnyRegister(HeapReg));
allRegisters_.take(AnyRegister(GlobalReg));
#elif defined(JS_CODEGEN_ARM64)
allRegisters_.take(AnyRegister(HeapReg));
allRegisters_.take(AnyRegister(HeapLenReg));
allRegisters_.take(AnyRegister(GlobalReg));
#endif
} else {
if (FramePointer != InvalidReg && mir->instrumentedProfiling())

Просмотреть файл

@ -14,6 +14,8 @@
# include "jit/x86-shared/Architecture-x86-shared.h"
#elif defined(JS_CODEGEN_ARM)
# include "jit/arm/Architecture-arm.h"
#elif defined(JS_CODEGEN_ARM64)
# include "jit/arm64/Architecture-arm64.h"
#elif defined(JS_CODEGEN_MIPS)
# include "jit/mips/Architecture-mips.h"
#elif defined(JS_CODEGEN_NONE)
@ -42,8 +44,7 @@ struct Register {
Register r = { Encoding(code) };
return r;
}
Code code() const {
MOZ_ASSERT(Code(reg_) < Registers::Total);
MOZ_CONSTEXPR Code code() const {
return Code(reg_);
}
Encoding encoding() const {

Просмотреть файл

@ -161,8 +161,11 @@ class Simulator
void set_pc(int32_t value);
int32_t get_pc() const;
void set_resume_pc(int32_t value) {
resume_pc_ = value;
template <typename T>
T get_pc_as() const { return reinterpret_cast<T>(get_pc()); }
void set_resume_pc(void* value) {
resume_pc_ = int32_t(value);
}
void enable_single_stepping(SingleStepCallback cb, void* arg);

Просмотреть файл

@ -323,7 +323,7 @@ Assembler::addPatchableJump(BufferOffset src, Relocation::Kind reloc)
}
void
PatchJump(CodeLocationJump& jump_, CodeLocationLabel label)
PatchJump(CodeLocationJump& jump_, CodeLocationLabel label, ReprotectCode reprotect)
{
MOZ_CRASH("PatchJump");
}

Просмотреть файл

@ -553,10 +553,10 @@ GetTempRegForIntArg(uint32_t usedIntArgs, uint32_t usedFloatArgs, Register* out)
return false;
*out = CallTempNonArgRegs[usedIntArgs];
return true;
}
void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label);
void PatchJump(CodeLocationJump& jump_, CodeLocationLabel label,
ReprotectCode reprotect = DontReprotect);
static inline void
PatchBackedge(CodeLocationJump& jump_, CodeLocationLabel label, JitRuntime::BackedgeTarget target)

Просмотреть файл

@ -6,7 +6,7 @@
#include "jit/arm64/MacroAssembler-arm64.h"
// TODO #include "jit/arm64/MoveEmitter-arm64.h"
#include "jit/arm64/MoveEmitter-arm64.h"
#include "jit/arm64/SharedICRegisters-arm64.h"
#include "jit/Bailouts.h"
#include "jit/BaselineFrame.h"

Просмотреть файл

@ -179,9 +179,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
vixl::MacroAssembler::Push(scratch64);
}
}
void push(ImmMaybeNurseryPtr imm) {
push(noteMaybeNurseryPtr(imm));
}
void push(ARMRegister reg) {
vixl::MacroAssembler::Push(reg);
}
@ -809,13 +806,19 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
BufferOffset load = movePatchablePtr(ImmPtr(imm.value), dest);
writeDataRelocation(imm, load);
}
void movePtr(ImmMaybeNurseryPtr imm, Register dest) {
movePtr(noteMaybeNurseryPtr(imm), dest);
}
void mov(ImmWord imm, Register dest) {
movePtr(imm, dest);
}
void mov(ImmPtr imm, Register dest) {
movePtr(imm, dest);
}
void mov(AsmJSImmPtr imm, Register dest) {
movePtr(imm, dest);
}
void mov(Register src, Register dest) {
movePtr(src, dest);
}
void move32(Imm32 imm, Register dest) {
Mov(ARMRegister(dest, 32), (int64_t)imm.value);
@ -1218,9 +1221,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
movePtr(rhs, scratch);
cmpPtr(lhs, scratch);
}
void cmpPtr(Register lhs, ImmMaybeNurseryPtr rhs) {
cmpPtr(lhs, noteMaybeNurseryPtr(rhs));
}
void cmpPtr(const Address& lhs, Register rhs) {
vixl::UseScratchRegisterScope temps(this);
@ -1794,9 +1794,6 @@ class MacroAssemblerCompat : public vixl::MacroAssembler
B(cond, label);
}
void branchPtr(Condition cond, Address lhs, ImmMaybeNurseryPtr ptr, Label* label) {
branchPtr(cond, lhs, noteMaybeNurseryPtr(ptr), label);
}
void branchPtr(Condition cond, Register lhs, Register rhs, Label* label) {
Cmp(ARMRegister(lhs, 64), ARMRegister(rhs, 64));
B(label, cond);

Просмотреть файл

@ -215,6 +215,12 @@ class Register : public CPURegister {
return IsValidRegister();
}
js::jit::Register asUnsized() const {
if (code_ == kSPRegInternalCode)
return js::jit::Register::FromCode((js::jit::Register::Code)kZeroRegCode);
return js::jit::Register::FromCode((js::jit::Register::Code)code_);
}
static const Register& WRegFromCode(unsigned code);
static const Register& XRegFromCode(unsigned code);
@ -497,6 +503,19 @@ class Operand {
// <shift_amount> is uint2_t.
explicit Operand(Register reg, Extend extend, unsigned shift_amount = 0);
// FIXME: Temporary constructors for compilation.
// FIXME: These should be removed -- Operand should not leak into shared code.
// FIXME: Something like an LAllocationUnion for {gpreg, fpreg, Address} is wanted.
explicit Operand(js::jit::Register) {
MOZ_CRASH("Operand with Register");
}
explicit Operand(js::jit::FloatRegister) {
MOZ_CRASH("Operand with FloatRegister");
}
explicit Operand(js::jit::Register, int32_t) {
MOZ_CRASH("Operand with implicit Address");
}
bool IsImmediate() const;
bool IsShiftedRegister() const;
bool IsExtendedRegister() const;
@ -565,8 +584,10 @@ class MemOperand {
AddrMode addrmode = Offset);
// Adapter constructors using C++11 delegating.
// TODO: If sp == kSPRegInternalCode, the xzr check isn't necessary.
explicit MemOperand(js::jit::Address addr)
: MemOperand(Register(addr.base, 64), (ptrdiff_t)addr.offset) {
: MemOperand(addr.base.code() == 31 ? sp : Register(addr.base, 64),
(ptrdiff_t)addr.offset) {
}
const Register& base() const {
@ -673,6 +694,29 @@ class Assembler : public MozBaseAssembler {
// called before executing or copying code from the buffer.
void FinalizeCode();
#define COPYENUM(v) static const Condition v = vixl::v
#define COPYENUM_(v) static const Condition v = vixl::v##_
COPYENUM(Equal);
COPYENUM(Zero);
COPYENUM(NotEqual);
COPYENUM(NonZero);
COPYENUM(AboveOrEqual);
COPYENUM(Below);
COPYENUM(Signed);
COPYENUM(NotSigned);
COPYENUM(Overflow);
COPYENUM(NoOverflow);
COPYENUM(Above);
COPYENUM(BelowOrEqual);
COPYENUM_(GreaterThanOrEqual);
COPYENUM_(LessThan);
COPYENUM_(GreaterThan);
COPYENUM_(LessThanOrEqual);
COPYENUM(Always);
COPYENUM(Never);
#undef COPYENUM
#undef COPYENUM_
// Bit set when a DoubleCondition does not map to a single ARM condition.
// The MacroAssembler must special-case these conditions, or else
// ConditionFromDoubleCondition will complain.

Просмотреть файл

@ -1204,7 +1204,7 @@ void MacroAssembler::PrintfNoPreserve(const char * format, const CPURegister& ar
Adr(x0, &format_address);
// Emit the format string directly in the instruction stream.
{
{
flushBuffer();
Label after_data;
B(&after_data);

Просмотреть файл

@ -61,16 +61,16 @@ ptrdiff_t Assembler::LinkAndGetOffsetTo(BufferOffset branch, Label* label) {
if (armbuffer_.oom())
return js::jit::LabelBase::INVALID_OFFSET;
// The label is bound: all uses are already linked.
if (label->bound()) {
// The label is bound: all uses are already linked.
ptrdiff_t branch_offset = ptrdiff_t(branch.getOffset() / element_size);
ptrdiff_t label_offset = ptrdiff_t(label->offset() / element_size);
return label_offset - branch_offset;
}
// The label is unbound and unused: store the offset in the label itself
// for patching by bind().
if (!label->used()) {
// The label is unbound and unused: store the offset in the label itself
// for patching by bind().
label->use(branch.getOffset());
return js::jit::LabelBase::INVALID_OFFSET;
}
@ -120,7 +120,7 @@ void Assembler::b(Instruction* at, int imm19, Condition cond) {
BufferOffset Assembler::b(Label* label) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0);
Instruction* ins = getInstructionAt(branch);
VIXL_ASSERT(ins->IsUncondBranchImm());
@ -132,7 +132,7 @@ BufferOffset Assembler::b(Label* label) {
BufferOffset Assembler::b(Label* label, Condition cond) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0, Always);
Instruction* ins = getInstructionAt(branch);
VIXL_ASSERT(ins->IsCondBranchImm());
@ -154,7 +154,7 @@ void Assembler::bl(Instruction* at, int imm26) {
void Assembler::bl(Label* label) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0);
Instruction* ins = getInstructionAt(branch);
@ -174,7 +174,7 @@ void Assembler::cbz(Instruction* at, const Register& rt, int imm19) {
void Assembler::cbz(const Register& rt, Label* label) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0);
Instruction* ins = getInstructionAt(branch);
@ -194,7 +194,7 @@ void Assembler::cbnz(Instruction* at, const Register& rt, int imm19) {
void Assembler::cbnz(const Register& rt, Label* label) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0);
Instruction* ins = getInstructionAt(branch);
@ -216,7 +216,7 @@ void Assembler::tbz(Instruction* at, const Register& rt, unsigned bit_pos, int i
void Assembler::tbz(const Register& rt, unsigned bit_pos, Label* label) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0);
Instruction* ins = getInstructionAt(branch);
@ -238,7 +238,7 @@ void Assembler::tbnz(Instruction* at, const Register& rt, unsigned bit_pos, int
void Assembler::tbnz(const Register& rt, unsigned bit_pos, Label* label) {
// Flush the instruction buffer before calculating relative offset.
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset branch = b(0);
Instruction* ins = getInstructionAt(branch);
@ -260,8 +260,8 @@ void Assembler::adr(Instruction* at, const Register& rd, int imm21) {
void Assembler::adr(const Register& rd, Label* label) {
// Flush the instruction buffer before calculating relative offset.
// ADR is not a branch.
// Flush the instruction buffer if necessary before getting an offset.
// Note that ADR is not a branch, but it encodes an offset like a branch.
BufferOffset offset = Emit(0);
Instruction* ins = getInstructionAt(offset);
@ -285,6 +285,7 @@ void Assembler::adrp(Instruction* at, const Register& rd, int imm21) {
void Assembler::adrp(const Register& rd, Label* label) {
VIXL_ASSERT(AllowPageOffsetDependentCode());
// Flush the instruction buffer if necessary before getting an offset.
BufferOffset offset = Emit(0);
Instruction* ins = getInstructionAt(offset);
@ -401,7 +402,8 @@ bool MozBaseAssembler::PatchConstantPoolLoad(void* loadAddr, void* constPoolAddr
// as written by InsertIndexIntoTag().
uint32_t index = load->ImmLLiteral();
// Each entry in the literal pool is uint32_t-sized.
// Each entry in the literal pool is uint32_t-sized,
// but literals may use multiple entries.
uint32_t* constPool = reinterpret_cast<uint32_t*>(constPoolAddr);
Instruction* source = reinterpret_cast<Instruction*>(&constPool[index]);
@ -424,6 +426,10 @@ struct PoolHeader {
union {
struct {
uint32_t size : 15;
// "Natural" guards are part of the normal instruction stream,
// while "non-natural" guards are inserted for the sole purpose
// of skipping around a pool.
bool isNatural : 1;
uint32_t ONES : 16;
};
@ -469,14 +475,13 @@ void MozBaseAssembler::WritePoolHeader(uint8_t* start, js::jit::Pool* p, bool is
JS_STATIC_ASSERT(sizeof(PoolHeader) == 4);
// Get the total size of the pool.
uint8_t* pool = start + sizeof(PoolHeader) + p->getPoolSize();
const uintptr_t totalPoolSize = sizeof(PoolHeader) + p->getPoolSize();
const uintptr_t totalPoolInstructions = totalPoolSize / sizeof(Instruction);
uintptr_t size = pool - start;
VIXL_ASSERT((size & 3) == 0);
size = size >> 2;
VIXL_ASSERT(size < (1 << 15));
VIXL_ASSERT((totalPoolSize & 0x3) == 0);
VIXL_ASSERT(totalPoolInstructions < (1 << 15));
PoolHeader header(size, isNatural);
PoolHeader header(totalPoolInstructions, isNatural);
*(PoolHeader*)start = header;
}

Просмотреть файл

@ -157,7 +157,7 @@ Simulator* Simulator::Create() {
sim->init(decoder, stdout);
return sim;
}
}
void Simulator::Destroy(Simulator* sim) {
@ -207,8 +207,8 @@ bool Simulator::overRecursedWithExtra(uint32_t extra) const {
}
void Simulator::set_resume_pc(const Instruction* new_resume_pc) {
resume_pc_ = AddressUntag(new_resume_pc);
void Simulator::set_resume_pc(void* new_resume_pc) {
resume_pc_ = AddressUntag(reinterpret_cast<Instruction*>(new_resume_pc));
}

Просмотреть файл

@ -29,6 +29,7 @@
#include "mozilla/Vector.h"
#include "js-config.h"
#include "jsalloc.h"
#include "jit/arm64/vixl/Assembler-vixl.h"
@ -40,6 +41,8 @@
#include "jit/IonTypes.h"
#include "vm/PosixNSPR.h"
#ifdef JS_SIMULATOR_ARM64
#define JS_CHECK_SIMULATOR_RECURSION_WITH_EXTRA(cx, extra, onerror) \
JS_BEGIN_MACRO \
if (cx->mainThread().simulator()->overRecursedWithExtra(extra)) { \
@ -338,17 +341,26 @@ class Simulator : public DecoderVisitor {
void ResetState();
static inline uintptr_t StackLimit() {
return Simulator::Current()->stackLimit();
}
// Run the simulator.
virtual void Run();
void RunFrom(const Instruction* first);
// Simulation helpers.
const Instruction* pc() const { return pc_; }
const Instruction* get_pc() const { return pc_; }
template <typename T>
T get_pc_as() const { return reinterpret_cast<T>(const_cast<Instruction*>(pc())); }
void set_pc(const Instruction* new_pc) {
pc_ = AddressUntag(new_pc);
pc_modified_ = true;
}
void set_resume_pc(const Instruction* new_resume_pc);
void set_resume_pc(void* new_resume_pc);
void increment_pc() {
if (!pc_modified_) {
@ -930,9 +942,8 @@ class Simulator : public DecoderVisitor {
// Stack
byte* stack_;
static const int stack_protection_size_ = 256;
// 2 KB stack.
static const int stack_size_ = 2 * 1024 + 2 * stack_protection_size_;
static const int stack_protection_size_ = 128 * KBytes;
static const int stack_size_ = (2 * MBytes) + (2 * stack_protection_size_);
byte* stack_limit_;
Decoder* decoder_;
@ -974,4 +985,5 @@ class Simulator : public DecoderVisitor {
};
} // namespace vixl
#endif // JS_SIMULATOR_ARM64
#endif // VIXL_A64_SIMULATOR_A64_H_

Просмотреть файл

@ -184,8 +184,11 @@ class Simulator {
void set_pc(int32_t value);
int32_t get_pc() const;
void set_resume_pc(int32_t value) {
resume_pc_ = value;
template <typename T>
T get_pc_as() const { return reinterpret_cast<T>(get_pc()); }
void set_resume_pc(void* value) {
resume_pc_ = int32_t(value);
}
// Accessor to the internal simulator stack area.

Просмотреть файл

@ -18,15 +18,17 @@
#include "jit/RegisterSets.h"
#include "vm/HelperThreads.h"
#if defined(JS_CODEGEN_ARM)
#define JS_USE_LINK_REGISTER
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
// Push return addresses callee-side.
# define JS_USE_LINK_REGISTER
#endif
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM)
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
// JS_SMALL_BRANCH means the range on a branch instruction
// is smaller than the whole address space
# define JS_SMALL_BRANCH
# define JS_SMALL_BRANCH
#endif
namespace js {
namespace jit {
@ -706,9 +708,13 @@ static const uint32_t AsmJSFrameBytesAfterReturnAddress = sizeof(void*);
// everywhere. Values are asserted in AsmJSModule.h.
static const unsigned AsmJSActivationGlobalDataOffset = 0;
static const unsigned AsmJSHeapGlobalDataOffset = sizeof(void*);
static const unsigned AsmJSNaN64GlobalDataOffset = 2 * sizeof(void*);
static const unsigned AsmJSNaN32GlobalDataOffset = 2 * sizeof(void*) + sizeof(double);
#if defined(JS_CODEGEN_X64) || defined(JS_CODEGEN_ARM64)
static const unsigned AsmJSNaN64GlobalDataOffset = 3 * sizeof(void*);
static const unsigned AsmJSNaN32GlobalDataOffset = 3 * sizeof(void*) + sizeof(double);
#else
static const unsigned AsmJSNaN64GlobalDataOffset = 4 * sizeof(void*);
static const unsigned AsmJSNaN32GlobalDataOffset = 4 * sizeof(void*) + sizeof(double);
#endif
// Summarizes a heap access made by asm.js code that needs to be patched later
// and/or looked up by the asm.js signal handlers. Different architectures need
// to know different things (x64: offset and length, ARM: where to patch in
@ -769,7 +775,7 @@ class AsmJSHeapAccess
cmpDelta_ = cmp == NoLengthCheck ? 0 : insnOffset - cmp;
MOZ_ASSERT(offsetWithinWholeSimdVector_ == offsetWithinWholeSimdVector);
}
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_MIPS)
#elif defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64) || defined(JS_CODEGEN_MIPS)
explicit AsmJSHeapAccess(uint32_t insnOffset)
{
mozilla::PodZero(this); // zero padding for Valgrind

Просмотреть файл

@ -221,7 +221,7 @@ CodeGeneratorShared::ToOperand(const LAllocation& a)
return Operand(a.toGeneralReg()->reg());
if (a.isFloatReg())
return Operand(a.toFloatReg()->reg());
return Operand(StackPointer, ToStackOffset(&a));
return Operand(masm.getStackPointer(), ToStackOffset(&a));
}
Operand

Просмотреть файл

@ -1385,12 +1385,12 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow* ool)
Register dest = ool->dest();
saveVolatile(dest);
#if defined(JS_CODEGEN_ARM)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
if (ool->needFloat32Conversion()) {
masm.convertFloat32ToDouble(src, ScratchDoubleReg);
src = ScratchDoubleReg;
}
#else
FloatRegister srcSingle = src.asSingle();
if (ool->needFloat32Conversion()) {
@ -1400,6 +1400,7 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow* ool)
src = src.asDouble();
}
#endif
masm.setupUnalignedABICall(1, dest);
masm.passABIArg(src, MoveOp::DOUBLE);
if (gen->compilingAsmJS())
@ -1408,12 +1409,12 @@ CodeGeneratorShared::visitOutOfLineTruncateSlow(OutOfLineTruncateSlow* ool)
masm.callWithABI(BitwiseCast<void*, int32_t(*)(double)>(JS::ToInt32));
masm.storeCallResult(dest);
#if !defined(JS_CODEGEN_ARM)
#if !defined(JS_CODEGEN_ARM) && !defined(JS_CODEGEN_ARM64)
if (ool->needFloat32Conversion())
masm.pop(srcSingle);
#endif
restoreVolatile(dest);
restoreVolatile(dest);
masm.jump(ool->rejoin());
}

Просмотреть файл

@ -823,7 +823,7 @@ struct AssemblerBufferWithConstantPools : public AssemblerBuffer<SliceSize, Inst
return;
unsigned destOffset = branch.getOffset() + offset;
if (offset > 0) {
while (curpool < numDumps_ && poolInfo_[curpool].offset <= destOffset) {
while (curpool < numDumps_ && poolInfo_[curpool].offset <= (size_t)destOffset) {
offset += poolInfo_[curpool].size;
curpool++;
}

Просмотреть файл

@ -311,7 +311,7 @@ LIRGeneratorShared::useRegisterOrNonDoubleConstant(MDefinition* mir)
return useRegister(mir);
}
#if defined(JS_CODEGEN_ARM)
#if defined(JS_CODEGEN_ARM) || defined(JS_CODEGEN_ARM64)
LAllocation
LIRGeneratorShared::useAnyOrConstant(MDefinition* mir)
{

Просмотреть файл

@ -32,6 +32,7 @@
#include "asmjs/AsmJSSignalHandlers.h"
#include "jit/arm/Simulator-arm.h"
#include "jit/arm64/vixl/Simulator-vixl.h"
#include "jit/JitCompartment.h"
#include "jit/mips/Simulator-mips.h"
#include "jit/PcScriptCache.h"

Просмотреть файл

@ -65,6 +65,12 @@ extern mozilla::ThreadLocal<PerThreadData*> TlsPerThreadData;
struct DtoaState;
#ifdef JS_SIMULATOR_ARM64
namespace vixl {
class Simulator;
}
#endif
namespace js {
extern MOZ_COLD void
@ -86,9 +92,14 @@ namespace jit {
class JitRuntime;
class JitActivation;
struct PcScriptCache;
class Simulator;
struct AutoFlushICache;
class CompileRuntime;
#ifdef JS_SIMULATOR_ARM64
typedef vixl::Simulator Simulator;
#elif defined(JS_SIMULATOR)
class Simulator;
#endif
}
/*