From 956ac1220db329ed6ad022711e63995e370c7aa6 Mon Sep 17 00:00:00 2001 From: Leon Sha Date: Mon, 18 Apr 2011 20:17:21 -0700 Subject: [PATCH] Bug 610323 - [TraceMonkey] Implement Jaegermonkey Sparc back-end. Part II. r=dvander. --- js/src/Makefile.in | 5 +- js/src/assembler/assembler/MacroAssembler.h | 4 ++ js/src/assembler/jit/ExecutableAllocator.h | 21 +++++++ js/src/assembler/wtf/Platform.h | 5 +- js/src/configure.in | 5 ++ js/src/jsinterp.cpp | 3 +- js/src/methodjit/BaseAssembler.h | 20 ++++++- js/src/methodjit/Compiler.cpp | 6 +- js/src/methodjit/FastArithmetic.cpp | 2 +- js/src/methodjit/FastOps.cpp | 14 ++--- js/src/methodjit/FrameState-inl.h | 2 +- js/src/methodjit/ICLabels.h | 11 +++- js/src/methodjit/ICRepatcher.h | 6 +- js/src/methodjit/MachineRegs.h | 66 +++++++++++++++++++++ js/src/methodjit/MethodJIT.cpp | 1 + js/src/methodjit/MethodJIT.h | 41 +++++++++++++ js/src/methodjit/MonoIC.h | 8 +-- js/src/methodjit/NunboxAssembler.h | 28 ++++++--- js/src/methodjit/PolyIC.cpp | 2 +- js/src/methodjit/PolyIC.h | 10 ++-- js/src/methodjit/TypedArrayIC.h | 2 +- js/src/yarr/yarr/RegexCompiler.cpp | 8 ++- js/src/yarr/yarr/RegexJIT.cpp | 22 +++++++ 23 files changed, 247 insertions(+), 45 deletions(-) diff --git a/js/src/Makefile.in b/js/src/Makefile.in index 0eb95006b700..306aca91388d 100644 --- a/js/src/Makefile.in +++ b/js/src/Makefile.in @@ -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 \ diff --git a/js/src/assembler/assembler/MacroAssembler.h b/js/src/assembler/assembler/MacroAssembler.h index 5f249811cecf..73bda22a8ee2 100644 --- a/js/src/assembler/assembler/MacroAssembler.h +++ b/js/src/assembler/assembler/MacroAssembler.h @@ -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 diff --git a/js/src/assembler/jit/ExecutableAllocator.h b/js/src/assembler/jit/ExecutableAllocator.h index 323261e5cbbe..78f0002e7330 100644 --- a/js/src/assembler/jit/ExecutableAllocator.h +++ b/js/src/assembler/jit/ExecutableAllocator.h @@ -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 #include @@ -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 diff --git a/js/src/assembler/wtf/Platform.h b/js/src/assembler/wtf/Platform.h index 3dfad2a8ae46..ce3b9491c555 100644 --- a/js/src/assembler/wtf/Platform.h +++ b/js/src/assembler/wtf/Platform.h @@ -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) diff --git a/js/src/configure.in b/js/src/configure.in index 346009182530..79925cba3198 100644 --- a/js/src/configure.in +++ b/js/src/configure.in @@ -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 diff --git a/js/src/jsinterp.cpp b/js/src/jsinterp.cpp index cf1673f65cb3..52c68e5bfd0c 100644 --- a/js/src/jsinterp.cpp +++ b/js/src/jsinterp.cpp @@ -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" diff --git a/js/src/methodjit/BaseAssembler.h b/js/src/methodjit/BaseAssembler.h index bc7cd9748c2c..400e373a932b 100644 --- a/js/src/methodjit/BaseAssembler.h +++ b/js/src/methodjit/BaseAssembler.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. diff --git a/js/src/methodjit/Compiler.cpp b/js/src/methodjit/Compiler.cpp index ed27e5626d6f..ce3f85002754 100644 --- a/js/src/methodjit/Compiler.cpp +++ b/js/src/methodjit/Compiler.cpp @@ -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); diff --git a/js/src/methodjit/FastArithmetic.cpp b/js/src/methodjit/FastArithmetic.cpp index 653581d63ed9..3eb151b3a82e 100644 --- a/js/src/methodjit/FastArithmetic.cpp +++ b/js/src/methodjit/FastArithmetic.cpp @@ -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 diff --git a/js/src/methodjit/FastOps.cpp b/js/src/methodjit/FastOps.cpp index 43c2785d948b..dfed09f70e3a 100644 --- a/js/src/methodjit/FastOps.cpp +++ b/js/src/methodjit/FastOps.cpp @@ -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()) { diff --git a/js/src/methodjit/FrameState-inl.h b/js/src/methodjit/FrameState-inl.h index 9dfeb82143bd..7764a3fb9392 100644 --- a/js/src/methodjit/FrameState-inl.h +++ b/js/src/methodjit/FrameState-inl.h @@ -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 diff --git a/js/src/methodjit/ICLabels.h b/js/src/methodjit/ICLabels.h index cddcf7a68f95..2edaead2d23f 100644 --- a/js/src/methodjit/ICLabels.h +++ b/js/src/methodjit/ICLabels.h @@ -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 diff --git a/js/src/methodjit/ICRepatcher.h b/js/src/methodjit/ICRepatcher.h index 59d8e78a0ccc..24b08b9634d0 100644 --- a/js/src/methodjit/ICRepatcher.h +++ b/js/src/methodjit/ICRepatcher.h @@ -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 diff --git a/js/src/methodjit/MachineRegs.h b/js/src/methodjit/MachineRegs.h index cc5064d09260..7783529c98b7 100644 --- a/js/src/methodjit/MachineRegs.h +++ b/js/src/methodjit/MachineRegs.h @@ -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 diff --git a/js/src/methodjit/MethodJIT.cpp b/js/src/methodjit/MethodJIT.cpp index 9e1915abb3c1..c2af0ec5f0f7 100644 --- a/js/src/methodjit/MethodJIT.cpp +++ b/js/src/methodjit/MethodJIT.cpp @@ -506,6 +506,7 @@ SYMBOL_STRING(JaegerStubVeneer) ":" "\n" " pop {ip,pc}" "\n" ); +# elif defined(JS_CPU_SPARC) # else # error "Unsupported CPU!" # endif diff --git a/js/src/methodjit/MethodJIT.h b/js/src/methodjit/MethodJIT.h index 54ae53532cbd..e1741e95731f 100644 --- a/js/src/methodjit/MethodJIT.h +++ b/js/src/methodjit/MethodJIT.h @@ -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(this) - 1; } +#elif defined(JS_CPU_SPARC) + JSStackFrame *topRetrunAddr; + void* veneerReturn; + void* _align; + inline void** returnAddressLocation() { + return reinterpret_cast(&this->veneerReturn); + } #else # error "The VMFrame layout isn't defined for your processor architecture!" #endif diff --git a/js/src/methodjit/MonoIC.h b/js/src/methodjit/MonoIC.h index 66254b1fb301..ec33db7e7bd0 100644 --- a/js/src/methodjit/MonoIC.h +++ b/js/src/methodjit/MonoIC.h @@ -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. */ diff --git a/js/src/methodjit/NunboxAssembler.h b/js/src/methodjit/NunboxAssembler.h index 6ce0ac8bc912..fbac37f9909b 100644 --- a/js/src/methodjit/NunboxAssembler.h +++ b/js/src/methodjit/NunboxAssembler.h @@ -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 - 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 diff --git a/js/src/methodjit/PolyIC.cpp b/js/src/methodjit/PolyIC.cpp index d8c440bfd90a..b18e672435cd 100644 --- a/js/src/methodjit/PolyIC.cpp +++ b/js/src/methodjit/PolyIC.cpp @@ -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)) diff --git a/js/src/methodjit/PolyIC.h b/js/src/methodjit/PolyIC.h index 6b69a26b33bd..9fa7bcfb02aa 100644 --- a/js/src/methodjit/PolyIC.h +++ b/js/src/methodjit/PolyIC.h @@ -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. diff --git a/js/src/methodjit/TypedArrayIC.h b/js/src/methodjit/TypedArrayIC.h index 88f817570a6d..a31e6bcc5ea2 100644 --- a/js/src/methodjit/TypedArrayIC.h +++ b/js/src/methodjit/TypedArrayIC.h @@ -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; diff --git a/js/src/yarr/yarr/RegexCompiler.cpp b/js/src/yarr/yarr/RegexCompiler.cpp index 46b3e91e230c..9b60cbd4a78b 100644 --- a/js/src/yarr/yarr/RegexCompiler.cpp +++ b/js/src/yarr/yarr/RegexCompiler.cpp @@ -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. diff --git a/js/src/yarr/yarr/RegexJIT.cpp b/js/src/yarr/yarr/RegexJIT.cpp index c43d2a9494ff..1571c35b7125 100644 --- a/js/src/yarr/yarr/RegexJIT.cpp +++ b/js/src/yarr/yarr/RegexJIT.cpp @@ -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