mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-06 09:05:45 +00:00
Bug 610323 - [TraceMonkey] Implement Jaegermonkey Sparc back-end. Part II. r=dvander.
This commit is contained in:
parent
bacce83b01
commit
956ac1220d
@ -367,6 +367,9 @@ endif
|
||||
ifeq (arm, $(TARGET_CPU))
|
||||
#CPPSRCS += only_on_arm.cpp
|
||||
endif
|
||||
ifeq (sparc, $(findstring sparc,$(TARGET_CPU)))
|
||||
ASFILES += TrampolineSparc.s
|
||||
endif
|
||||
#
|
||||
# END enclude sources for the method JIT
|
||||
#############################################
|
||||
@ -392,7 +395,7 @@ CPPSRCS += checks.cc \
|
||||
# END enclude sources for V8 dtoa
|
||||
#############################################
|
||||
|
||||
ifeq (,$(filter-out powerpc sparc,$(TARGET_CPU)))
|
||||
ifeq (,$(filter-out powerpc,$(TARGET_CPU)))
|
||||
|
||||
VPATH += $(srcdir)/assembler \
|
||||
$(srcdir)/assembler/wtf \
|
||||
|
@ -54,6 +54,10 @@ namespace JSC { typedef MacroAssemblerX86 MacroAssemblerBase; }
|
||||
#include "MacroAssemblerX86_64.h"
|
||||
namespace JSC { typedef MacroAssemblerX86_64 MacroAssemblerBase; }
|
||||
|
||||
#elif WTF_CPU_SPARC
|
||||
#include "MacroAssemblerSparc.h"
|
||||
namespace JSC { typedef MacroAssemblerSparc MacroAssemblerBase; }
|
||||
|
||||
#else
|
||||
#error "The MacroAssembler is not supported on this platform."
|
||||
#endif
|
||||
|
@ -35,6 +35,22 @@
|
||||
#include "jsvector.h"
|
||||
#include "jslock.h"
|
||||
|
||||
#if WTF_CPU_SPARC
|
||||
#ifdef linux // bugzilla 502369
|
||||
static void sync_instruction_memory(caddr_t v, u_int len)
|
||||
{
|
||||
caddr_t end = v + len;
|
||||
caddr_t p = v;
|
||||
while (p < end) {
|
||||
asm("flush %0" : : "r" (p));
|
||||
p += 32;
|
||||
}
|
||||
}
|
||||
#else
|
||||
extern "C" void sync_instruction_memory(caddr_t v, u_int len);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if WTF_PLATFORM_IPHONE
|
||||
#include <libkern/OSCacheControl.h>
|
||||
#include <sys/mman.h>
|
||||
@ -394,6 +410,11 @@ public:
|
||||
{
|
||||
CacheRangeFlush(code, size, CACHE_SYNC_ALL);
|
||||
}
|
||||
#elif WTF_CPU_SPARC
|
||||
static void cacheFlush(void* code, size_t size)
|
||||
{
|
||||
sync_instruction_memory((caddr_t)code, size);
|
||||
}
|
||||
#else
|
||||
#error "The cacheFlush support is missing on this platform."
|
||||
#endif
|
||||
|
@ -159,7 +159,7 @@
|
||||
|
||||
/* CPU(SPARC) - any SPARC, true for CPU(SPARC32) and CPU(SPARC64) */
|
||||
#if WTF_CPU_SPARC32 || WTF_CPU_SPARC64
|
||||
#define WTF_CPU_SPARC
|
||||
#define WTF_CPU_SPARC 1
|
||||
#endif
|
||||
|
||||
/* CPU(X86) - i386 / x86 32-bit */
|
||||
@ -857,6 +857,8 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
|
||||
/* The JIT is tested & working on x86 Windows */
|
||||
#elif WTF_CPU_X86 && WTF_PLATFORM_WIN
|
||||
#define ENABLE_JIT 1
|
||||
#elif WTF_CPU_SPARC
|
||||
#define ENABLE_JIT 1
|
||||
#endif
|
||||
|
||||
#if WTF_PLATFORM_QT
|
||||
@ -920,6 +922,7 @@ on MinGW. See https://bugs.webkit.org/show_bug.cgi?id=29268 */
|
||||
/* YARR supports x86 & x86-64, and has been tested on Mac and Windows. */
|
||||
#if (WTF_CPU_X86 \
|
||||
|| WTF_CPU_X86_64 \
|
||||
|| WTF_CPU_SPARC \
|
||||
|| WTF_CPU_ARM_TRADITIONAL \
|
||||
|| WTF_CPU_ARM_THUMB2 \
|
||||
|| WTF_CPU_X86)
|
||||
|
@ -2872,7 +2872,12 @@ arm*-*)
|
||||
sparc*-*)
|
||||
ENABLE_TRACEJIT=1
|
||||
NANOJIT_ARCH=Sparc
|
||||
ENABLE_METHODJIT=1
|
||||
ENABLE_MONOIC=1
|
||||
ENABLE_POLYIC=1
|
||||
ENABLE_POLYIC_TYPED_ARRAY=1
|
||||
AC_DEFINE(JS_CPU_SPARC)
|
||||
AC_DEFINE(JS_NUNBOX32)
|
||||
;;
|
||||
esac
|
||||
|
||||
|
@ -74,10 +74,11 @@
|
||||
#include "jstracer.h"
|
||||
#include "jslibmath.h"
|
||||
#include "jsvector.h"
|
||||
#ifdef JS_METHODJIT
|
||||
#include "methodjit/MethodJIT.h"
|
||||
#include "methodjit/MethodJIT-inl.h"
|
||||
#include "methodjit/Logging.h"
|
||||
|
||||
#endif
|
||||
#include "jsatominlines.h"
|
||||
#include "jscntxtinlines.h"
|
||||
#include "jsinterpinlines.h"
|
||||
|
@ -176,6 +176,8 @@ class Assembler : public ValueAssembler
|
||||
static const RegisterID ClobberInCall = JSC::X86Registers::ecx;
|
||||
#elif defined(JS_CPU_ARM)
|
||||
static const RegisterID ClobberInCall = JSC::ARMRegisters::r2;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const RegisterID ClobberInCall = JSC::SparcRegisters::l1;
|
||||
#endif
|
||||
|
||||
/* :TODO: OOM */
|
||||
@ -225,6 +227,10 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::X86Registe
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = JSC::ARMRegisters::r2;
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::ARMRegisters::r1;
|
||||
static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegisters::r1;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Type = JSC::SparcRegisters::i0;
|
||||
static const JSC::MacroAssembler::RegisterID JSReturnReg_Data = JSC::SparcRegisters::i1;
|
||||
static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::SparcRegisters::i2;
|
||||
#endif
|
||||
|
||||
size_t distanceOf(Label l) {
|
||||
@ -364,10 +370,18 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
|
||||
// Windows x64 requires extra space in between calls.
|
||||
#ifdef _WIN64
|
||||
static const uint32 ShadowStackSpace = 32;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const uint32 ShadowStackSpace = 92;
|
||||
#else
|
||||
static const uint32 ShadowStackSpace = 0;
|
||||
#endif
|
||||
|
||||
#if defined(JS_CPU_SPARC)
|
||||
static const uint32 BaseStackSpace = 104;
|
||||
#else
|
||||
static const uint32 BaseStackSpace = 0;
|
||||
#endif
|
||||
|
||||
// Prepare the stack for a call sequence. This must be called AFTER all
|
||||
// volatile regs have been saved, and BEFORE pushArg() is used. The stack
|
||||
// is assumed to be aligned to 16-bytes plus any pushes that occured via
|
||||
@ -426,7 +440,7 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
|
||||
//
|
||||
// Note that it's not required we're in a call - stackAdjust can be 0.
|
||||
JS_ASSERT(marker.base <= extraStackSpace);
|
||||
return Address(stackPointerRegister, stackAdjust + extraStackSpace - marker.base);
|
||||
return Address(stackPointerRegister, BaseStackSpace + stackAdjust + extraStackSpace - marker.base);
|
||||
}
|
||||
|
||||
// This is an internal function only for use inside a setupABICall(),
|
||||
@ -651,9 +665,9 @@ static const JSC::MacroAssembler::RegisterID JSParamReg_Argc = JSC::ARMRegiste
|
||||
Address capacity(objReg, offsetof(JSObject, capacity));
|
||||
if (key.isConstant()) {
|
||||
JS_ASSERT(key.index() >= 0);
|
||||
return branch32(BelowOrEqual, payloadOf(capacity), Imm32(key.index()));
|
||||
return branch32(BelowOrEqual, capacity, Imm32(key.index()));
|
||||
}
|
||||
return branch32(BelowOrEqual, payloadOf(capacity), key.reg());
|
||||
return branch32(BelowOrEqual, capacity, key.reg());
|
||||
}
|
||||
|
||||
// Load a jsval from an array slot, given a key. |objReg| is clobbered.
|
||||
|
@ -3625,7 +3625,7 @@ mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
|
||||
masm.loadPtr(Address(JSFrameReg, JSStackFrame::offsetOfScopeChain()), pic.objReg);
|
||||
|
||||
pic.shapeGuard = masm.label();
|
||||
Jump inlineJump = masm.branchPtr(Assembler::NotEqual, masm.payloadOf(parent), ImmPtr(0));
|
||||
Jump inlineJump = masm.branchPtr(Assembler::NotEqual, parent, ImmPtr(0));
|
||||
{
|
||||
RESERVE_OOL_SPACE(stubcc.masm);
|
||||
pic.slowPathStart = stubcc.linkExit(inlineJump, Uses(0));
|
||||
@ -3694,7 +3694,7 @@ mjit::Compiler::jsop_bindname(JSAtom *atom, bool usePropCache)
|
||||
|
||||
Address address(reg, offsetof(JSObject, parent));
|
||||
|
||||
Jump j = masm.branchPtr(Assembler::NotEqual, masm.payloadOf(address), ImmPtr(0));
|
||||
Jump j = masm.branchPtr(Assembler::NotEqual, address, ImmPtr(0));
|
||||
|
||||
stubcc.linkExit(j, Uses(0));
|
||||
stubcc.leave();
|
||||
@ -4634,7 +4634,7 @@ mjit::Compiler::jsop_instanceof()
|
||||
Label loop = masm.label();
|
||||
|
||||
/* Walk prototype chain, break out on NULL or hit. */
|
||||
masm.loadPayload(protoAddr, obj);
|
||||
masm.loadPtr(protoAddr, obj);
|
||||
Jump isFalse2 = masm.branchTestPtr(Assembler::Zero, obj, obj);
|
||||
Jump isTrue = masm.branchPtr(Assembler::NotEqual, obj, proto);
|
||||
isTrue.linkTo(loop, &masm);
|
||||
|
@ -771,7 +771,7 @@ mjit::Compiler::jsop_neg()
|
||||
#if defined JS_CPU_X86 || defined JS_CPU_X64
|
||||
masm.loadDouble(&DoubleNegMask, FPRegisters::Second);
|
||||
masm.xorDouble(FPRegisters::Second, fpreg);
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
masm.negDouble(fpreg, fpreg);
|
||||
#endif
|
||||
|
||||
|
@ -1556,13 +1556,13 @@ mjit::Compiler::jsop_stricteq(JSOp op)
|
||||
|
||||
Assembler::Condition oppositeCond = (op == JSOP_STRICTEQ) ? Assembler::NotEqual : Assembler::Equal;
|
||||
|
||||
#if defined JS_CPU_X86 || defined JS_CPU_ARM
|
||||
#ifndef JS_CPU_X64
|
||||
static const int CanonicalNaNType = 0x7FF80000;
|
||||
masm.setPtr(oppositeCond, treg, Imm32(CanonicalNaNType), result);
|
||||
#elif defined JS_CPU_X64
|
||||
#else
|
||||
static const void *CanonicalNaNType = (void *)0x7FF8000000000000;
|
||||
masm.move(ImmPtr(CanonicalNaNType), JSC::X86Registers::r11);
|
||||
masm.setPtr(oppositeCond, treg, JSC::X86Registers::r11, result);
|
||||
masm.move(ImmPtr(CanonicalNaNType), Registers::ScratchReg);
|
||||
masm.setPtr(oppositeCond, treg, Registers::ScratchReg, result);
|
||||
#endif
|
||||
|
||||
frame.popn(2);
|
||||
@ -1585,13 +1585,13 @@ mjit::Compiler::jsop_stricteq(JSOp op)
|
||||
|
||||
/* This is only true if the other side is |null|. */
|
||||
RegisterID result = frame.allocReg(Registers::SingleByteRegs);
|
||||
#if defined JS_CPU_X86 || defined JS_CPU_ARM
|
||||
#ifndef JS_CPU_X64
|
||||
JSValueTag mask = known->getKnownTag();
|
||||
if (frame.shouldAvoidTypeRemat(test))
|
||||
masm.set32(cond, masm.tagOf(frame.addressOf(test)), Imm32(mask), result);
|
||||
else
|
||||
masm.set32(cond, frame.tempRegForType(test), Imm32(mask), result);
|
||||
#elif defined JS_CPU_X64
|
||||
#else
|
||||
RegisterID maskReg = frame.allocReg();
|
||||
masm.move(ImmTag(known->getKnownTag()), maskReg);
|
||||
|
||||
@ -1667,7 +1667,7 @@ mjit::Compiler::jsop_stricteq(JSOp op)
|
||||
return;
|
||||
}
|
||||
|
||||
#ifndef JS_CPU_ARM
|
||||
#if !defined JS_CPU_ARM && !defined JS_CPU_SPARC
|
||||
/* Try an integer fast-path. */
|
||||
bool needStub = false;
|
||||
if (!lhs->isTypeKnown()) {
|
||||
|
@ -137,7 +137,7 @@ FrameState::convertInt32ToDouble(Assembler &masm, FrameEntry *fe, FPRegisterID f
|
||||
if (fe->data.inRegister())
|
||||
masm.convertInt32ToDouble(fe->data.reg(), fpreg);
|
||||
else
|
||||
masm.convertInt32ToDouble(addressOf(fe), fpreg);
|
||||
masm.convertInt32ToDouble(masm.payloadOf(addressOf(fe)), fpreg);
|
||||
}
|
||||
|
||||
inline bool
|
||||
|
@ -64,7 +64,7 @@ namespace ic {
|
||||
* implementation.
|
||||
*/
|
||||
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_ARM
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
# define JS_HAS_IC_LABELS
|
||||
#endif
|
||||
|
||||
@ -172,7 +172,7 @@ struct GetPropLabels : MacroAssemblerTypedefs {
|
||||
int getInlineTypeJumpOffset() {
|
||||
#if defined JS_CPU_X86 || defined JS_CPU_X64
|
||||
return INLINE_TYPE_JUMP;
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return POST_INST_OFFSET(inlineTypeJumpOffset);
|
||||
#endif
|
||||
}
|
||||
@ -180,7 +180,7 @@ struct GetPropLabels : MacroAssemblerTypedefs {
|
||||
void setInlineTypeJumpOffset(int offset) {
|
||||
#if defined JS_CPU_X86 || defined JS_CPU_X64
|
||||
JS_ASSERT(INLINE_TYPE_JUMP == offset);
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
inlineTypeJumpOffset = offset;
|
||||
JS_ASSERT(offset == inlineTypeJumpOffset);
|
||||
#endif
|
||||
@ -223,6 +223,11 @@ struct GetPropLabels : MacroAssemblerTypedefs {
|
||||
/* Offset from the shape guard start to the shape guard jump. */
|
||||
static const int32 INLINE_SHAPE_JUMP = 12;
|
||||
|
||||
/* Offset from the fast path to the type guard jump. */
|
||||
int32 inlineTypeJumpOffset : 8;
|
||||
#elif defined JS_CPU_SPARC
|
||||
static const int32 INLINE_SHAPE_JUMP = 48;
|
||||
static const int32 INLINE_TYPE_JUMP = 48;
|
||||
/* Offset from the fast path to the type guard jump. */
|
||||
int32 inlineTypeJumpOffset : 8;
|
||||
#endif
|
||||
|
@ -72,7 +72,7 @@ class Repatcher : public JSC::RepatchBuffer
|
||||
|
||||
/* Patch a stub call. */
|
||||
void relink(CodeLocationCall call, FunctionPtr stub) {
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_X86
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_X86 || defined JS_CPU_SPARC
|
||||
JSC::RepatchBuffer::relink(call, stub);
|
||||
#elif defined JS_CPU_ARM
|
||||
/*
|
||||
@ -95,7 +95,7 @@ class Repatcher : public JSC::RepatchBuffer
|
||||
|
||||
/* Patch the offset of a Value load emitted by loadValueWithAddressOffsetPatch. */
|
||||
void patchAddressOffsetForValueLoad(CodeLocationLabel label, uint32 offset) {
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_ARM
|
||||
#if defined JS_CPU_X64 || defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
repatch(label.dataLabel32AtOffset(0), offset);
|
||||
#elif defined JS_CPU_X86
|
||||
static const unsigned LOAD_TYPE_OFFSET = 6;
|
||||
@ -115,7 +115,7 @@ class Repatcher : public JSC::RepatchBuffer
|
||||
}
|
||||
|
||||
void patchAddressOffsetForValueStore(CodeLocationLabel label, uint32 offset, bool typeConst) {
|
||||
#if defined JS_CPU_ARM || defined JS_CPU_X64
|
||||
#if defined JS_CPU_ARM || defined JS_CPU_X64 || defined JS_CPU_SPARC
|
||||
(void) typeConst;
|
||||
repatch(label.dataLabel32AtOffset(0), offset);
|
||||
#elif defined JS_CPU_X86
|
||||
|
@ -67,6 +67,8 @@ struct Registers {
|
||||
static const RegisterID JSFrameReg = JSC::X86Registers::ebx;
|
||||
#elif defined(JS_CPU_ARM)
|
||||
static const RegisterID JSFrameReg = JSC::ARMRegisters::r11;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const RegisterID JSFrameReg = JSC::SparcRegisters::l0;
|
||||
#endif
|
||||
|
||||
#if defined(JS_CPU_X86) || defined(JS_CPU_X64)
|
||||
@ -87,6 +89,14 @@ struct Registers {
|
||||
static const RegisterID ArgReg0 = JSC::ARMRegisters::r0;
|
||||
static const RegisterID ArgReg1 = JSC::ARMRegisters::r1;
|
||||
static const RegisterID ArgReg2 = JSC::ARMRegisters::r2;
|
||||
#elif JS_CPU_SPARC
|
||||
static const RegisterID ReturnReg = JSC::SparcRegisters::o0;
|
||||
static const RegisterID ArgReg0 = JSC::SparcRegisters::o0;
|
||||
static const RegisterID ArgReg1 = JSC::SparcRegisters::o1;
|
||||
static const RegisterID ArgReg2 = JSC::SparcRegisters::o2;
|
||||
static const RegisterID ArgReg3 = JSC::SparcRegisters::o3;
|
||||
static const RegisterID ArgReg4 = JSC::SparcRegisters::o4;
|
||||
static const RegisterID ArgReg5 = JSC::SparcRegisters::o5;
|
||||
#endif
|
||||
|
||||
static const RegisterID StackPointer = JSC::MacroAssembler::stackPointerRegister;
|
||||
@ -167,6 +177,30 @@ struct Registers {
|
||||
// r14 is LR and is used for return sequences.
|
||||
// r15 is PC (program counter).
|
||||
|
||||
static const uint32 SingleByteRegs = TempRegs | SavedRegs;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const uint32 TempRegs =
|
||||
(1 << JSC::SparcRegisters::o0)
|
||||
| (1 << JSC::SparcRegisters::o1)
|
||||
| (1 << JSC::SparcRegisters::o2)
|
||||
| (1 << JSC::SparcRegisters::o3)
|
||||
| (1 << JSC::SparcRegisters::o4)
|
||||
| (1 << JSC::SparcRegisters::o5);
|
||||
|
||||
static const uint32 SavedRegs =
|
||||
(1 << JSC::SparcRegisters::l2)
|
||||
| (1 << JSC::SparcRegisters::l3)
|
||||
| (1 << JSC::SparcRegisters::l4)
|
||||
| (1 << JSC::SparcRegisters::l5)
|
||||
| (1 << JSC::SparcRegisters::l6)
|
||||
| (1 << JSC::SparcRegisters::l7)
|
||||
| (1 << JSC::SparcRegisters::i0)
|
||||
| (1 << JSC::SparcRegisters::i1)
|
||||
| (1 << JSC::SparcRegisters::i2)
|
||||
| (1 << JSC::SparcRegisters::i3)
|
||||
| (1 << JSC::SparcRegisters::i4)
|
||||
| (1 << JSC::SparcRegisters::i5);
|
||||
|
||||
static const uint32 SingleByteRegs = TempRegs | SavedRegs;
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
@ -195,6 +229,8 @@ struct Registers {
|
||||
# endif
|
||||
#elif defined(JS_CPU_ARM)
|
||||
return 4;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
return 6;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -236,6 +272,15 @@ struct Registers {
|
||||
JSC::ARMRegisters::r2,
|
||||
JSC::ARMRegisters::r3
|
||||
};
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const RegisterID regs[] = {
|
||||
JSC::SparcRegisters::o0,
|
||||
JSC::SparcRegisters::o1,
|
||||
JSC::SparcRegisters::o2,
|
||||
JSC::SparcRegisters::o3,
|
||||
JSC::SparcRegisters::o4,
|
||||
JSC::SparcRegisters::o5
|
||||
};
|
||||
#endif
|
||||
JS_ASSERT(numArgRegs(conv) == JS_ARRAY_LENGTH(regs));
|
||||
if (i > JS_ARRAY_LENGTH(regs))
|
||||
@ -362,6 +407,27 @@ struct FPRegisters {
|
||||
static const FPRegisterID Second = JSC::ARMRegisters::d1;
|
||||
static const FPRegisterID Temp0 = JSC::ARMRegisters::d2;
|
||||
static const FPRegisterID Temp1 = JSC::ARMRegisters::d3;
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
static const uint32 TotalFPRegisters = 16;
|
||||
static const uint32 TempFPRegs =
|
||||
(1 << JSC::SparcRegisters::f0)
|
||||
| (1 << JSC::SparcRegisters::f2)
|
||||
| (1 << JSC::SparcRegisters::f4)
|
||||
| (1 << JSC::SparcRegisters::f6)
|
||||
| (1 << JSC::SparcRegisters::f8)
|
||||
| (1 << JSC::SparcRegisters::f10)
|
||||
| (1 << JSC::SparcRegisters::f12)
|
||||
| (1 << JSC::SparcRegisters::f14)
|
||||
| (1 << JSC::SparcRegisters::f16)
|
||||
| (1 << JSC::SparcRegisters::f18)
|
||||
| (1 << JSC::SparcRegisters::f20)
|
||||
| (1 << JSC::SparcRegisters::f22)
|
||||
| (1 << JSC::SparcRegisters::f24)
|
||||
| (1 << JSC::SparcRegisters::f26)
|
||||
| (1 << JSC::SparcRegisters::f28);
|
||||
/* FIXME: Temporary hack until FPRegister allocation exists. */
|
||||
static const FPRegisterID First = JSC::SparcRegisters::f0;
|
||||
static const FPRegisterID Second = JSC::SparcRegisters::f2;
|
||||
#else
|
||||
# error "Unsupported platform"
|
||||
#endif
|
||||
|
@ -506,6 +506,7 @@ SYMBOL_STRING(JaegerStubVeneer) ":" "\n"
|
||||
" pop {ip,pc}" "\n"
|
||||
);
|
||||
|
||||
# elif defined(JS_CPU_SPARC)
|
||||
# else
|
||||
# error "Unsupported CPU!"
|
||||
# endif
|
||||
|
@ -45,6 +45,7 @@
|
||||
|
||||
#if !defined JS_CPU_X64 && \
|
||||
!defined JS_CPU_X86 && \
|
||||
!defined JS_CPU_SPARC && \
|
||||
!defined JS_CPU_ARM
|
||||
# error "Oh no, you should define a platform so this compiles."
|
||||
#endif
|
||||
@ -59,6 +60,39 @@ namespace mjit { struct JITScript; }
|
||||
|
||||
struct VMFrame
|
||||
{
|
||||
#if defined(JS_CPU_SPARC)
|
||||
void *savedL0;
|
||||
void *savedL1;
|
||||
void *savedL2;
|
||||
void *savedL3;
|
||||
void *savedL4;
|
||||
void *savedL5;
|
||||
void *savedL6;
|
||||
void *savedL7;
|
||||
void *savedI0;
|
||||
void *savedI1;
|
||||
void *savedI2;
|
||||
void *savedI3;
|
||||
void *savedI4;
|
||||
void *savedI5;
|
||||
void *savedI6;
|
||||
void *savedI7;
|
||||
|
||||
void *str_p;
|
||||
|
||||
void *outgoing_p0;
|
||||
void *outgoing_p1;
|
||||
void *outgoing_p2;
|
||||
void *outgoing_p3;
|
||||
void *outgoing_p4;
|
||||
void *outgoing_p5;
|
||||
|
||||
void *outgoing_p6;
|
||||
|
||||
void *reserve_0;
|
||||
void *reserve_1;
|
||||
#endif
|
||||
|
||||
union Arguments {
|
||||
struct {
|
||||
void *ptr;
|
||||
@ -131,6 +165,13 @@ struct VMFrame
|
||||
inline void** returnAddressLocation() {
|
||||
return reinterpret_cast<void**>(this) - 1;
|
||||
}
|
||||
#elif defined(JS_CPU_SPARC)
|
||||
JSStackFrame *topRetrunAddr;
|
||||
void* veneerReturn;
|
||||
void* _align;
|
||||
inline void** returnAddressLocation() {
|
||||
return reinterpret_cast<void**>(&this->veneerReturn);
|
||||
}
|
||||
#else
|
||||
# error "The VMFrame layout isn't defined for your processor architecture!"
|
||||
#endif
|
||||
|
@ -125,15 +125,15 @@ struct SetGlobalNameIC : public GlobalNameIC
|
||||
JSC::JITCode extraStub;
|
||||
|
||||
/* SET only, if we had to generate an out-of-line path. */
|
||||
int inlineShapeJump : 10; /* Offset into inline path for shape jump. */
|
||||
int extraShapeGuard : 6; /* Offset into stub for shape guard. */
|
||||
int32 inlineShapeJump : 10; /* Offset into inline path for shape jump. */
|
||||
int32 extraShapeGuard : 6; /* Offset into stub for shape guard. */
|
||||
bool objConst : 1; /* True if the object is constant. */
|
||||
RegisterID objReg : 5; /* Register for object, if objConst is false. */
|
||||
RegisterID shapeReg : 5; /* Register for shape; volatile. */
|
||||
bool hasExtraStub : 1; /* Extra stub is preset. */
|
||||
|
||||
int fastRejoinOffset : 16; /* Offset from fastPathStart to rejoin. */
|
||||
int extraStoreOffset : 16; /* Offset into store code. */
|
||||
int32 fastRejoinOffset : 16; /* Offset from fastPathStart to rejoin. */
|
||||
int32 extraStoreOffset : 16; /* Offset into store code. */
|
||||
|
||||
/* SET only. */
|
||||
ValueRemat vr; /* RHS value. */
|
||||
|
@ -72,16 +72,24 @@ struct ImmPayload : JSC::MacroAssembler::Imm32
|
||||
|
||||
class NunboxAssembler : public JSC::MacroAssembler
|
||||
{
|
||||
public:
|
||||
#ifdef IS_BIG_ENDIAN
|
||||
static const uint32 PAYLOAD_OFFSET = 4;
|
||||
static const uint32 TAG_OFFSET = 0;
|
||||
#else
|
||||
static const uint32 PAYLOAD_OFFSET = 0;
|
||||
static const uint32 TAG_OFFSET = 4;
|
||||
#endif
|
||||
|
||||
public:
|
||||
static const JSC::MacroAssembler::Scale JSVAL_SCALE = JSC::MacroAssembler::TimesEight;
|
||||
|
||||
template <typename T>
|
||||
T payloadOf(T address) {
|
||||
JS_ASSERT(PAYLOAD_OFFSET == 0);
|
||||
return address;
|
||||
Address payloadOf(Address address) {
|
||||
return Address(address.base, address.offset + PAYLOAD_OFFSET);
|
||||
}
|
||||
|
||||
BaseIndex payloadOf(BaseIndex address) {
|
||||
return BaseIndex(address.base, address.index, address.scale, address.offset + PAYLOAD_OFFSET);
|
||||
}
|
||||
|
||||
Address tagOf(Address address) {
|
||||
@ -185,7 +193,7 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
JS_ASSERT(differenceBetween(start, endType) == 6);
|
||||
JS_ASSERT(differenceBetween(endType, endPayload) == 6);
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
/*
|
||||
* On ARM, the first instruction loads the offset from a literal pool, so the label
|
||||
* returned points at that instruction.
|
||||
@ -217,7 +225,7 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
JS_ASSERT(differenceBetween(start, endType) == 6);
|
||||
JS_ASSERT(differenceBetween(endType, endPayload) == 6);
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return store64WithAddressOffsetPatch(treg, dreg, address);
|
||||
#endif
|
||||
}
|
||||
@ -233,7 +241,7 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
JS_ASSERT(differenceBetween(start, endType) == 10);
|
||||
JS_ASSERT(differenceBetween(endType, endPayload) == 6);
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return store64WithAddressOffsetPatch(type, dreg, address);
|
||||
#endif
|
||||
}
|
||||
@ -253,7 +261,7 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
JS_ASSERT(differenceBetween(start, endType) == 10);
|
||||
JS_ASSERT(differenceBetween(endType, endPayload) == 10);
|
||||
return start;
|
||||
#elif defined JS_CPU_ARM
|
||||
#elif defined JS_CPU_ARM || defined JS_CPU_SPARC
|
||||
return store64WithAddressOffsetPatch(type, payload, address);
|
||||
#endif
|
||||
}
|
||||
@ -320,7 +328,7 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
}
|
||||
|
||||
void loadPrivate(Address privAddr, RegisterID to) {
|
||||
loadPtr(privAddr, to);
|
||||
loadPtr(payloadOf(privAddr), to);
|
||||
}
|
||||
|
||||
void loadObjPrivate(RegisterID base, RegisterID to) {
|
||||
@ -435,6 +443,8 @@ class NunboxAssembler : public JSC::MacroAssembler
|
||||
m_assembler.movd_rr(srcDest, dataReg);
|
||||
m_assembler.psrldq_rr(srcDest, 4);
|
||||
m_assembler.movd_rr(srcDest, typeReg);
|
||||
#elif defined JS_CPU_SPARC
|
||||
breakDoubleTo32(srcDest, typeReg, dataReg);
|
||||
#else
|
||||
JS_NOT_REACHED("implement this - push double, pop pop is easiest");
|
||||
#endif
|
||||
|
@ -339,7 +339,7 @@ class SetPropCompiler : public PICStubCompiler
|
||||
} else {
|
||||
/* Check capacity. */
|
||||
Address capacity(pic.objReg, offsetof(JSObject, capacity));
|
||||
masm.load32(masm.payloadOf(capacity), pic.shapeReg);
|
||||
masm.load32(capacity, pic.shapeReg);
|
||||
Jump overCapacity = masm.branch32(Assembler::LessThanOrEqual, pic.shapeReg,
|
||||
Imm32(shape->slot));
|
||||
if (!slowExits.append(overCapacity))
|
||||
|
@ -94,7 +94,7 @@ struct BaseIC : public MacroAssemblerTypedefs {
|
||||
// Offset from start of stub to jump target of second shape guard as Nitro
|
||||
// asm data location. This is 0 if there is only one shape guard in the
|
||||
// last stub.
|
||||
int secondShapeGuard : 11;
|
||||
int32 secondShapeGuard : 11;
|
||||
|
||||
// Opcode this was compiled for.
|
||||
JSOp op : 9;
|
||||
@ -255,9 +255,9 @@ struct GetElementIC : public BasePolyIC {
|
||||
// These offsets are used for string-key dependent stubs, such as named
|
||||
// property accesses. They are separated from the int-key dependent stubs,
|
||||
// in order to guarantee that the id type needs only one guard per type.
|
||||
int atomGuard : 8; // optional, non-zero if present
|
||||
int firstShapeGuard : 8; // always set
|
||||
int secondShapeGuard : 8; // optional, non-zero if present
|
||||
int32 atomGuard : 8; // optional, non-zero if present
|
||||
int32 firstShapeGuard : 11; // always set
|
||||
int32 secondShapeGuard : 11; // optional, non-zero if present
|
||||
|
||||
bool hasLastStringStub : 1;
|
||||
JITCode lastStringStub;
|
||||
@ -336,7 +336,7 @@ struct SetElementIC : public BaseIC {
|
||||
|
||||
// A bitmask of registers that are volatile and must be preserved across
|
||||
// stub calls inside the IC.
|
||||
uint32 volatileMask : 16;
|
||||
uint32 volatileMask;
|
||||
|
||||
// If true, then keyValue contains a constant index value >= 0. Otherwise,
|
||||
// keyReg contains a dynamic integer index in any range.
|
||||
|
@ -46,7 +46,7 @@
|
||||
namespace js {
|
||||
namespace mjit {
|
||||
|
||||
#if defined(JS_POLYIC) && (defined JS_CPU_X86 || defined JS_CPU_X64)
|
||||
#ifdef JS_POLYIC_TYPED_ARRAY
|
||||
|
||||
typedef JSC::MacroAssembler::RegisterID RegisterID;
|
||||
typedef JSC::MacroAssembler::FPRegisterID FPRegisterID;
|
||||
|
@ -34,6 +34,12 @@ namespace JSC { namespace Yarr {
|
||||
|
||||
#include "RegExpJitTables.h"
|
||||
|
||||
#if WTF_CPU_SPARC
|
||||
#define BASE_FRAME_SIZE 24
|
||||
#else
|
||||
#define BASE_FRAME_SIZE 0
|
||||
#endif
|
||||
|
||||
class CharacterClassConstructor {
|
||||
public:
|
||||
CharacterClassConstructor(bool isCaseInsensitive = false)
|
||||
@ -592,7 +598,7 @@ public:
|
||||
|
||||
void setupOffsets()
|
||||
{
|
||||
setupDisjunctionOffsets(m_pattern.m_body, 0, 0);
|
||||
setupDisjunctionOffsets(m_pattern.m_body, BASE_FRAME_SIZE, 0);
|
||||
}
|
||||
|
||||
// This optimization identifies sets of parentheses that we will never need to backtrack.
|
||||
|
@ -62,6 +62,16 @@ class RegexGenerator : private MacroAssembler {
|
||||
static const RegisterID regT1 = MIPSRegisters::t5;
|
||||
|
||||
static const RegisterID returnRegister = MIPSRegisters::v0;
|
||||
#elif WTF_CPU_SPARC
|
||||
static const RegisterID input = SparcRegisters::i0;
|
||||
static const RegisterID index = SparcRegisters::i1;
|
||||
static const RegisterID length = SparcRegisters::i2;
|
||||
static const RegisterID output = SparcRegisters::i3;
|
||||
|
||||
static const RegisterID regT0 = SparcRegisters::i4;
|
||||
static const RegisterID regT1 = SparcRegisters::i5;
|
||||
|
||||
static const RegisterID returnRegister = SparcRegisters::i0;
|
||||
#elif WTF_CPU_X86
|
||||
static const RegisterID input = X86Registers::eax;
|
||||
static const RegisterID index = X86Registers::edx;
|
||||
@ -564,8 +574,13 @@ class RegexGenerator : private MacroAssembler {
|
||||
void generatePatternCharacterPair(TermGenerationState& state)
|
||||
{
|
||||
const RegisterID character = regT0;
|
||||
#if WTF_CPU_BIG_ENDIAN
|
||||
UChar ch2 = state.term().patternCharacter;
|
||||
UChar ch1 = state.lookaheadTerm().patternCharacter;
|
||||
#else
|
||||
UChar ch1 = state.term().patternCharacter;
|
||||
UChar ch2 = state.lookaheadTerm().patternCharacter;
|
||||
#endif
|
||||
|
||||
int mask = 0;
|
||||
int chPair = ch1 | (ch2 << 16);
|
||||
@ -1449,6 +1464,10 @@ class RegexGenerator : private MacroAssembler {
|
||||
push(ARMRegisters::r8); // scratch register
|
||||
#endif
|
||||
move(ARMRegisters::r3, output);
|
||||
#elif WTF_CPU_SPARC
|
||||
save(Imm32(-m_pattern.m_body->m_callFrameSize * sizeof(void*)));
|
||||
// set m_callFrameSize to 0 avoid and stack movement later.
|
||||
m_pattern.m_body->m_callFrameSize = 0;
|
||||
#elif WTF_CPU_MIPS
|
||||
// Do nothing.
|
||||
#endif
|
||||
@ -1471,6 +1490,9 @@ class RegexGenerator : private MacroAssembler {
|
||||
pop(ARMRegisters::r6);
|
||||
pop(ARMRegisters::r5);
|
||||
pop(ARMRegisters::r4);
|
||||
#elif WTF_CPU_SPARC
|
||||
ret_and_restore();
|
||||
return;
|
||||
#elif WTF_CPU_MIPS
|
||||
// Do nothing
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user