From 627b88fb8ff3e8ab314146ea25c99602c199681a Mon Sep 17 00:00:00 2001 From: Edwin Smith Date: Mon, 20 Oct 2008 10:15:07 -0700 Subject: [PATCH] fixes to enable ARM nanojit to build, at least --- js/src/nanojit/Assembler.cpp | 56 +++++++++++------ js/src/nanojit/Assembler.h | 7 ++- js/src/nanojit/LIR.cpp | 15 ++--- js/src/nanojit/NativeARM.cpp | 109 +++++++++++++++++++++++---------- js/src/nanojit/NativeARM.h | 27 +++++--- js/src/nanojit/NativeThumb.cpp | 5 -- js/src/nanojit/NativeThumb.h | 37 +++++------ js/src/nanojit/Nativei386.cpp | 30 +-------- 8 files changed, 162 insertions(+), 124 deletions(-) diff --git a/js/src/nanojit/Assembler.cpp b/js/src/nanojit/Assembler.cpp index 2c74e651b8be..813c5ed0c2e1 100755 --- a/js/src/nanojit/Assembler.cpp +++ b/js/src/nanojit/Assembler.cpp @@ -214,7 +214,7 @@ namespace nanojit // nothing free, steal one // LSRA says pick the one with the furthest use - LIns* vic = findVictim(regs,allow); + LIns* vic = findVictim(regs, allow); NanoAssert(vic != NULL); Reservation* resv = getresv(vic); @@ -527,6 +527,16 @@ namespace nanojit { return findRegFor(i, rmask(w)); } + + Register Assembler::getBaseReg(LIns *i, int &d, RegisterMask allow) + { + if (i->isop(LIR_alloc)) { + d += findMemFor(i); + return FP; + } else { + return findRegFor(i, allow); + } + } Register Assembler::findRegFor(LIns* i, RegisterMask allow) { @@ -554,6 +564,8 @@ namespace nanojit resv = reserveAlloc(i); r = resv->reg; + +#ifdef AVMPLUS_IA32 if (r != UnknownReg && ((rmask(r)&XmmRegs) && !(allow&XmmRegs) || (rmask(r)&x87Regs) && !(allow&x87Regs))) @@ -563,6 +575,7 @@ namespace nanojit evict(r); r = UnknownReg; } +#endif if (r == UnknownReg) { @@ -610,6 +623,20 @@ namespace nanojit return rr; } + void Assembler::asm_spilli(LInsp i, Reservation *resv, bool pop) + { + int d = disp(resv); + Register rr = resv->reg; + bool quad = i->opcode() == LIR_param || i->isQuad(); + asm_spill(rr, d, pop, quad); + if (d) + { + verbose_only(if (_verbose) { + outputf(" spill %s",_thisfrag->lirbuf->names->formatRef(i)); + }) + } + } + void Assembler::freeRsrcOf(LIns *i, bool pop) { Reservation* resv = getresv(i); @@ -667,13 +694,7 @@ namespace nanojit // No 64-bit immediates so fall-back to below } else if (!rhs->isQuad()) { - Register r; - if (lhs->isop(LIR_alloc)) { - r = FP; - c += findMemFor(lhs); - } else { - r = findRegFor(lhs, GpRegs); - } + Register r = getBaseReg(lhs, c, GpRegs); CMPi(r, c); } } @@ -1070,7 +1091,11 @@ namespace nanojit JMP(_epilogue); } assignSavedParams(); +#ifdef NANOJIT_IA32 findSpecificRegFor(ins->oprnd1(), FST0); +#else + NanoAssert(false); +#endif fpu_pop(); break; } @@ -1135,13 +1160,12 @@ namespace nanojit // incoming arg in register prepResultReg(ins, rmask(argRegs[a])); } else { - // incoming arg is on stack, and EAX points nearby (see genPrologue) - //_nvprof("param-evict-eax",1); - Register r = prepResultReg(ins, GpRegs & ~rmask(EAX)); + // incoming arg is on stack, and EBP points nearby (see genPrologue) + Register r = prepResultReg(ins, GpRegs); int d = (a - abi_regcount) * sizeof(intptr_t) + 8; LD(r, d, FP); } - } + } else { // saved param prepResultReg(ins, rmask(savedRegs[a])); @@ -1243,14 +1267,8 @@ namespace nanojit LIns* base = ins->oprnd1(); LIns* disp = ins->oprnd2(); Register rr = prepResultReg(ins, GpRegs); - Register ra; int d = disp->constval(); - if (base->isop(LIR_alloc)) { - ra = FP; - d += findMemFor(base); - } else { - ra = findRegFor(base, GpRegs); - } + Register ra = getBaseReg(base, d, GpRegs); if (op == LIR_ldcb) LD8Z(rr, d, ra); else diff --git a/js/src/nanojit/Assembler.h b/js/src/nanojit/Assembler.h index f522c688599f..29b204486f1b 100644 --- a/js/src/nanojit/Assembler.h +++ b/js/src/nanojit/Assembler.h @@ -226,8 +226,9 @@ namespace nanojit void unionRegisterState(RegAlloc& saved); void assignSaved(RegAlloc &saved, RegisterMask skip); LInsp findVictim(RegAlloc& regs, RegisterMask allow); - - int findMemFor(LIns* i); + + Register getBaseReg(LIns *i, int &d, RegisterMask allow); + int findMemFor(LIns* i); Register findRegFor(LIns* i, RegisterMask allow); void findRegFor2(RegisterMask allow, LIns* ia, Reservation* &ra, LIns *ib, Reservation* &rb); Register findSpecificRegFor(LIns* i, Register w); @@ -290,7 +291,7 @@ namespace nanojit void asm_restore(LInsp, Reservation*, Register); void asm_load(int d, Register r); void asm_spilli(LInsp i, Reservation *resv, bool pop); - void asm_spill(Register rr, int d, bool pop=false, bool quad=false); + void asm_spill(Register rr, int d, bool pop, bool quad); void asm_load64(LInsp i); void asm_pusharg(LInsp p); NIns* asm_adjustBranch(NIns* at, NIns* target); diff --git a/js/src/nanojit/LIR.cpp b/js/src/nanojit/LIR.cpp index b2744524ed8e..2662b1f9dbc3 100755 --- a/js/src/nanojit/LIR.cpp +++ b/js/src/nanojit/LIR.cpp @@ -1049,22 +1049,23 @@ namespace nanojit NanoAssert(op != LIR_skip); // LIR_skip here is just an error condition ArgSize sizes[2*MAXARGS]; - uint32_t argc = ci->get_sizes(sizes); + int32_t argc = ci->get_sizes(sizes); #ifdef NJ_SOFTFLOAT if (op == LIR_fcall) op = LIR_callh; LInsp args2[MAXARGS*2]; // arm could require 2 args per double int32_t j = 0; - for (int32_t i = 0; i < MAXARGS; i++) { + int32_t i = 0; + while (j < argc) { argt >>= 2; ArgSize a = ArgSize(argt&3); if (a == ARGSIZE_F) { - LInsp q = args[i]; + LInsp q = args[i++]; args2[j++] = ins1(LIR_qhi, q); args2[j++] = ins1(LIR_qlo, q); - } else if (a != ARGSIZE_NONE) { - args2[j++] = args[i]; + } else { + args2[j++] = args[i++]; } } args = args2; @@ -1074,13 +1075,13 @@ namespace nanojit NanoAssert(argc <= MAXARGS); uint32_t words = argwords(argc); ensureRoom(words+LIns::callInfoWords+1+argc); // ins size + possible tramps - for (uint32_t i=0; i < argc; i++) + for (int32_t i=0; i < argc; i++) args[i] = ensureReferenceable(args[i], argc-i); uint8_t* offs = (uint8_t*)_buf->next(); LIns *l = _buf->next() + words; *(const CallInfo **)l = ci; l += LIns::callInfoWords; - for (uint32_t i=0; i < argc; i++) + for (int32_t i=0; i < argc; i++) offs[i] = (uint8_t) l->reference(args[i]); #if defined NANOJIT_64BIT l->initOpcode(op); diff --git a/js/src/nanojit/NativeARM.cpp b/js/src/nanojit/NativeARM.cpp index fb695d1b24ba..d5fdcb717fe8 100644 --- a/js/src/nanojit/NativeARM.cpp +++ b/js/src/nanojit/NativeARM.cpp @@ -64,16 +64,15 @@ const char* regNames[] = {"r0","r1","r2","r3","r4","r5","r6","r7","r8","r9","r10 const Register Assembler::argRegs[] = { R0, R1, R2, R3 }; const Register Assembler::retRegs[] = { R0, R1 }; +const Register Assembler::savedRegs[] = { R4, R5, R6, R7, R8, R9, R10 }; void Assembler::nInit(AvmCore*) { - // all ARMs have conditional move - avmplus::AvmCore::cmov_available = true; } NIns* -Assembler::genPrologue(RegisterMask needSaving) +Assembler::genPrologue() { /** * Prologue @@ -81,16 +80,14 @@ Assembler::genPrologue(RegisterMask needSaving) // NJ_RESV_OFFSET is space at the top of the stack for us // to use for parameter passing (8 bytes at the moment) - uint32_t stackNeeded = 4 * _activation.highwatermark + NJ_STACK_OFFSET; + uint32_t stackNeeded = STACK_GRANULARITY * _activation.highwatermark + NJ_STACK_OFFSET; uint32_t savingCount = 0; - uint32_t savingMask = 0; - savingCount = 9; //R4-R10,R11,LR - savingMask = SavedRegs | rmask(FRAME_PTR); - (void)needSaving; + uint32_t savingMask = SavedRegs | rmask(FP) | rmask(LR); + savingCount = NumSavedRegs+2; // so for alignment purposes we've pushed return addr, fp, and savingCount registers - uint32_t stackPushed = 4 * (2+savingCount); + uint32_t stackPushed = STACK_GRANULARITY * savingCount; uint32_t aligned = alignUp(stackNeeded + stackPushed, NJ_ALIGN_STACK); int32_t amt = aligned - stackPushed; @@ -102,8 +99,8 @@ Assembler::genPrologue(RegisterMask needSaving) verbose_only( verbose_output(" patch entry"); ) NIns *patchEntry = _nIns; - MR(FRAME_PTR, SP); - PUSH_mask(savingMask|rmask(LR)); + MR(FP, SP); + PUSH_mask(savingMask); return patchEntry; } @@ -130,7 +127,7 @@ Assembler::nFragExit(LInsp guard) } // pop the stack frame first - MR(SP, FRAME_PTR); + MR(SP, FP); #ifdef NJ_VERBOSE if (_frago->core()->config.show_stats) { @@ -146,11 +143,14 @@ Assembler::nFragExit(LInsp guard) } NIns* -Assembler::genEpilogue(RegisterMask restore) +Assembler::genEpilogue() { BX(LR); // return - MR(R0,R2); // return LinkRecord* - RegisterMask savingMask = restore | rmask(FRAME_PTR) | rmask(LR); + + // this is needed if we jump here from nFragExit + //MR(R0,R2); // return LinkRecord* + + RegisterMask savingMask = SavedRegs | rmask(FP) | rmask(LR); POP_mask(savingMask); // regs return _nIns; } @@ -252,6 +252,62 @@ Assembler::asm_call(LInsp ins) roffset = 1; } } + + void Assembler::asm_arg(ArgSize sz, LInsp p, Register r) + { + if (sz == ARGSIZE_Q) + { + // ref arg - use lea + if (r != UnknownReg) + { + // arg in specific reg + int da = findMemFor(p); + LEA(r, da, FP); + } + else + { + NanoAssert(0); // not supported + } + } + else if (sz == ARGSIZE_LO) + { + if (r != UnknownReg) { + // arg goes in specific register + if (p->isconst()) { + LDi(r, p->constval()); + } else { + Reservation* rA = getresv(p); + if (rA) { + if (rA->reg == UnknownReg) { + // load it into the arg reg + int d = findMemFor(p); + if (p->isop(LIR_alloc)) { + LEA(r, d, FP); + } else { + LD(r, d, FP); + } + } else { + // it must be in a saved reg + MR(r, rA->reg); + } + } + else { + // this is the last use, so fine to assign it + // to the scratch reg, it's dead after this point. + findSpecificRegFor(p, r); + } + } + } + else { + asm_pusharg(p); + } + } + else + { + NanoAssert(sz == ARGSIZE_F); + asm_farg(p); + } + } void Assembler::nMarkExecute(Page* page, int32_t count, bool enable) @@ -399,15 +455,11 @@ Assembler::asm_restore(LInsp i, Reservation *resv, Register r) } void -Assembler::asm_spill(LInsp i, Reservation *resv, bool pop) +Assembler::asm_spill(Register rr, int d, bool pop, bool quad) { - (void)i; - (void)pop; - //fprintf (stderr, "resv->arIndex: %d\n", resv->arIndex); - if (resv->arIndex) { - int d = disp(resv); - // save to spill location - Register rr = resv->reg; + (void) pop; + (void) quad; + if (d) { if (IsFpReg(rr)) { if (isS8(d >> 2)) { FSTD(rr, FP, d); @@ -418,11 +470,6 @@ Assembler::asm_spill(LInsp i, Reservation *resv, bool pop) } else { STR(rr, FP, d); } - - verbose_only(if (_verbose){ - outputf(" spill %s",_thisfrag->lirbuf->names->formatRef(i)); - } - ) } } @@ -623,7 +670,7 @@ Assembler::asm_nongp_copy(Register r, Register s) } Register -Assembler::asm_binop_rhs_reg(LInsp ins) +Assembler::asm_binop_rhs_reg(LInsp) { return UnknownReg; } @@ -871,7 +918,7 @@ Assembler::LD32_nochk(Register r, int32_t imm) void Assembler::B_cond_chk(ConditionCode _c, NIns* _t, bool _chk) { - int32 offs = PC_OFFSET_FROM(_t,_nIns-1); + int32_t offs = PC_OFFSET_FROM(_t,_nIns-1); //fprintf(stderr, "B_cond_chk target: 0x%08x offset: %d @0x%08x\n", _t, offs, _nIns-1); if (isS24(offs)) { if (_chk) underrunProtect(4); @@ -1094,7 +1141,7 @@ Assembler::asm_fcmp(LInsp ins) } Register -Assembler::asm_prep_fcall(Reservation* rR, LInsp ins) +Assembler::asm_prep_fcall(Reservation*, LInsp) { // We have nothing to do here; we do it all in asm_call. return UnknownReg; diff --git a/js/src/nanojit/NativeARM.h b/js/src/nanojit/NativeARM.h index 7f6bfefdc28e..a7474d9da197 100644 --- a/js/src/nanojit/NativeARM.h +++ b/js/src/nanojit/NativeARM.h @@ -42,6 +42,17 @@ #define __nanojit_NativeArm__ +#ifdef PERFM +#include "../vprof/vprof.h" +#define count_instr() _nvprof("arm",1) +#define count_prolog() _nvprof("arm-prolog",1); count_instr(); +#define count_imt() _nvprof("arm-imt",1) count_instr() +#else +#define count_instr() +#define count_prolog() +#define count_imt() +#endif + namespace nanojit { @@ -50,7 +61,7 @@ const int NJ_LOG2_PAGE_SIZE = 12; // 4K // If NJ_ARM_VFP is defined, then VFP is assumed to // be present. If it's not defined, then softfloat // is used, and NJ_SOFTFLOAT is defined. -#define NJ_ARM_VFP +//#define NJ_ARM_VFP #ifdef NJ_ARM_VFP @@ -107,10 +118,6 @@ typedef enum { FirstFloatReg = 16, LastFloatReg = 22, - - // helpers - FRAME_PTR = 11, - ESP = SP, FirstReg = 0, #ifdef NJ_ARM_VFP @@ -152,13 +159,15 @@ typedef struct _FragInfo { NIns* epilogue; } FragInfo; -#ifdef ARM_VFP +#ifdef NJ_ARM_VFP static const RegisterMask SavedFpRegs = 1<isconst()) { - Register rb; - if (base->isop(LIR_alloc)) { - rb = FP; - dr += findMemFor(base); - } else { - rb = findRegFor(base, GpRegs); - } + Register rb = getBaseReg(base, dr, GpRegs); int c = value->constval(); STi(rb, dr, c); } @@ -616,20 +610,6 @@ namespace nanojit #endif } - void Assembler::asm_spilli(LInsp i, Reservation *resv, bool pop) - { - int d = disp(resv); - Register rr = resv->reg; - bool quad = i->opcode() == LIR_param || i->isQuad(); - asm_spill(rr, d, pop, quad); - if (d) - { - verbose_only(if (_verbose) { - outputf(" spill %s",_thisfrag->lirbuf->names->formatRef(i)); - }) - } - } - void Assembler::asm_load64(LInsp ins) { LIns* base = ins->oprnd1(); @@ -640,13 +620,7 @@ namespace nanojit if (rr != UnknownReg && rmask(rr) & XmmRegs) { freeRsrcOf(ins, false); - Register rb; - if (base->isop(LIR_alloc)) { - rb = FP; - db += findMemFor(base); - } else { - rb = findRegFor(base, GpRegs); - } + Register rb = getBaseReg(base, db, GpRegs); SSE_LDQ(rr, db, rb); } #if defined NANOJIT_AMD64