diff options
author | 2009-12-17 09:57:25 +0800 | |
---|---|---|
committer | 2009-12-17 09:57:25 +0800 | |
commit | b705d5849e115464e78f1795fba68af174ff1462 (patch) | |
tree | 8e8c07b4baf09fb777a8100d88af65040d47d827 /www-client | |
parent | added xulrunner-1.9.2_beta4.ebuild (diff) | |
download | loongson-b705d5849e115464e78f1795fba68af174ff1462.tar.gz loongson-b705d5849e115464e78f1795fba68af174ff1462.tar.bz2 loongson-b705d5849e115464e78f1795fba68af174ff1462.zip |
added mozilla-firefox-3.6_beta4.ebuild with native nanojit
Signed-off-by: Zhang Le <r0bertz@gentoo.org>
Diffstat (limited to 'www-client')
8 files changed, 2506 insertions, 0 deletions
diff --git a/www-client/mozilla-firefox/Manifest b/www-client/mozilla-firefox/Manifest new file mode 100644 index 0000000..1ecc707 --- /dev/null +++ b/www-client/mozilla-firefox/Manifest @@ -0,0 +1,9 @@ +AUX 000_flex-configure-LANG.patch 1761 RMD160 638ae47607f582d6d264f7b6f4c3626ff60dbcb6 SHA1 db6d868d034b46b63ad292ab2e1c9b889fbeef75 SHA256 88719f2b3ab2be74a4d27173f7464f6fbc8e7697b84e3c32d19cf6e16170e532 +AUX firefox-default-prefs.js 95 RMD160 805cdfec6fb31c224322cb71125547ad7a515f49 SHA1 7fab69d85b12a9f1b0c87fbb1821bdafd7485ac9 SHA256 8bc4cb870bc402db1f20b135a689f8c5dbfa5de8f1755b1926198d627c12c5f1 +AUX icon/iceweasel.desktop 251 RMD160 56a1e32c06c3bd460d15f5fc56d23293cffd62bd SHA1 51f9c9e098e2ce565569b220987b714ebed27e38 SHA256 04b952df4b80af25ea9cfb93fc992f921120c491f52640680e2b70b96ebc7dd7 +AUX icon/mozilla-firefox-1.5-unbranded.desktop 258 RMD160 32ebb016d6a4d3d2728c031f3b3762796e02f5d3 SHA1 69820d445d06b90d7ac35ffd39dad5926caa0862 SHA256 f2bf5c237a5c56b443c20fd16d3da429bf3b99e9fe27b661a1a462aa46ed25d3 +AUX icon/mozilla-firefox-1.5.desktop 255 RMD160 4ef1cf548f11057274620b82f0728958a3424bea SHA1 6a440f817072fb60516c1a1d999dffb6d3fa1583 SHA256 9bf6e1264d986c68d64831d166ed6b506bff6df8b56d21bfc166aee09cbc753f +AUX mips-nanojit.patch 72977 RMD160 07f1bd89b81a132121b314734cf29533968b81f1 SHA1 1a38ce306f29ffb08c9232e985ec07455378b22b SHA256 3f7eb95f0caa3c3315d0a914a530df43bdab16aee192aa494d3595bb3c8a84e1 +DIST firefox-3.6b4.source.tar.bz2 48323922 RMD160 b6f74b639bfcb3d34a9f8e8c4cb58bb58e511f6f SHA1 de3b649b54fb9b40b58c2f1b432c0beea39ad732 SHA256 b4d371cc4abf3df36c8cb9738b35ad8d3c4ff57d31c00085a29141fff4c407d7 +DIST mozilla-firefox-3.6-patches-0.3.tar.bz2 4203 RMD160 406b24f82ab948ac35815f7c8884f4d938ecc428 SHA1 269282cdd3cc732cc74878cd95bf3157b128c6ee SHA256 28f7f666f5b80b5c8adb926bd7cc4b2772c6d96f112c68871c98405e9ab53653 +EBUILD mozilla-firefox-3.6_beta4.ebuild 6325 RMD160 d570751e288b5fb4c821e97280abf07b2e8163bc SHA1 550cae64d9528d41acc0400fcb87817731d3b5b5 SHA256 de29c3bd7f43d4a00ed99ac3f3fe85b02d314afaed4196dcbf34471b38adf580 diff --git a/www-client/mozilla-firefox/files/000_flex-configure-LANG.patch b/www-client/mozilla-firefox/files/000_flex-configure-LANG.patch new file mode 100644 index 0000000..6d32a85 --- /dev/null +++ b/www-client/mozilla-firefox/files/000_flex-configure-LANG.patch @@ -0,0 +1,41 @@ +The LANG vars aren't reset early enough so when sed tries to use [a-zA-Z] in +option parsing, it may break. + +http://bugs.gentoo.org/103483 + +--- configure~ 2009-07-31 20:07:25.087663220 -0500 ++++ configure 2009-07-31 20:07:37.987684452 -0500 +@@ -468,6 +468,16 @@ + infodir='${prefix}/info' + mandir='${prefix}/man' + ++# NLS nuisances. ++# Only set these to C if already set. These must not be set unconditionally ++# because not all systems understand e.g. LANG=C (notably SCO). ++# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! ++# Non-C LC_CTYPE values break the ctype check. ++if test "${LANG+set}" = set; then LANG=C; export LANG; fi ++if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi ++if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi ++if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi ++ + # Initialize some other variables. + subdirs= + MFLAGS= MAKEFLAGS= +@@ -856,16 +866,6 @@ + esac + done + +-# NLS nuisances. +-# Only set these to C if already set. These must not be set unconditionally +-# because not all systems understand e.g. LANG=C (notably SCO). +-# Fixing LC_MESSAGES prevents Solaris sh from translating var values in `set'! +-# Non-C LC_CTYPE values break the ctype check. +-if test "${LANG+set}" = set; then LANG=C; export LANG; fi +-if test "${LC_ALL+set}" = set; then LC_ALL=C; export LC_ALL; fi +-if test "${LC_MESSAGES+set}" = set; then LC_MESSAGES=C; export LC_MESSAGES; fi +-if test "${LC_CTYPE+set}" = set; then LC_CTYPE=C; export LC_CTYPE; fi +- + # confdefs.h avoids OS command line length limits that DEFS can exceed. + rm -rf conftest* confdefs.h + # AIX cpp loses on an empty file, so make sure it contains at least a newline. diff --git a/www-client/mozilla-firefox/files/firefox-default-prefs.js b/www-client/mozilla-firefox/files/firefox-default-prefs.js new file mode 100644 index 0000000..f7c031e --- /dev/null +++ b/www-client/mozilla-firefox/files/firefox-default-prefs.js @@ -0,0 +1,2 @@ +pref("browser.tabs.tabMinWidth", 15); +pref("browser.backspace_action", 0); diff --git a/www-client/mozilla-firefox/files/icon/iceweasel.desktop b/www-client/mozilla-firefox/files/icon/iceweasel.desktop new file mode 100644 index 0000000..8a037dc --- /dev/null +++ b/www-client/mozilla-firefox/files/icon/iceweasel.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Iceweasel +Comment=Web Browser +Exec=/usr/bin/firefox %U +Icon=iceweasel-icon +Terminal=false +Type=Application +MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml; +Categories=Network;WebBrowser; diff --git a/www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5-unbranded.desktop b/www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5-unbranded.desktop new file mode 100644 index 0000000..dff2d63 --- /dev/null +++ b/www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5-unbranded.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Bon Echo +Comment=Web Browser +Exec=/usr/bin/firefox %U +Icon=firefox-icon-unbranded +Terminal=false +Type=Application +MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml; +Categories=Network;WebBrowser; diff --git a/www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5.desktop b/www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5.desktop new file mode 100644 index 0000000..98d5fdf --- /dev/null +++ b/www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5.desktop @@ -0,0 +1,9 @@ +[Desktop Entry] +Name=Mozilla Firefox +Comment=Web Browser +Exec=/usr/bin/firefox %U +Icon=firefox-icon +Terminal=false +Type=Application +MimeType=text/html;text/xml;application/xhtml+xml;application/vnd.mozilla.xul+xml;text/mml; +Categories=Network;WebBrowser; diff --git a/www-client/mozilla-firefox/files/mips-nanojit.patch b/www-client/mozilla-firefox/files/mips-nanojit.patch new file mode 100644 index 0000000..e4c8f25 --- /dev/null +++ b/www-client/mozilla-firefox/files/mips-nanojit.patch @@ -0,0 +1,2222 @@ +diff -r 4c7acf580717 js/src/configure.in +--- a/js/src/configure.in Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/configure.in Thu Dec 10 08:37:44 2009 +0800 +@@ -2528,6 +2528,10 @@ + ENABLE_JIT=1 + NANOJIT_ARCH=Sparc + ;; ++mips*-*) ++ ENABLE_JIT=1 ++ NANOJIT_ARCH=Mips ++ ;; + esac + + MOZ_ARG_DISABLE_BOOL(jit, +@@ -2553,6 +2557,9 @@ + sparc-*) + AC_DEFINE(AVMPLUS_SPARC) + ;; ++mips*-*) ++ AC_DEFINE(AVMPLUS_MIPS) ++ ;; + esac + + case "$target_os" in +diff -r 4c7acf580717 js/src/jitstats.tbl +--- a/js/src/jitstats.tbl Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/jitstats.tbl Thu Dec 10 08:37:44 2009 +0800 +@@ -85,6 +85,7 @@ + JITSTAT(archIsARM) + JITSTAT(archIsSPARC) + JITSTAT(archIsPPC) ++JITSTAT(archIsMIPS) + + #ifdef DEFINED_MONITOR_JITSTAT + #undef DEFINED_MONITOR_JITSTAT +diff -r 4c7acf580717 js/src/jstracer.cpp +--- a/js/src/jstracer.cpp Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/jstracer.cpp Thu Dec 10 08:37:44 2009 +0800 +@@ -7525,6 +7525,7 @@ + jitstats.archIsARM = 0; + jitstats.archIsSPARC = 0; + jitstats.archIsPPC = 0; ++ jitstats.archIsMIPS = 0; + #if defined NANOJIT_IA32 + jitstats.archIsIA32 = 1; + #endif +@@ -7543,6 +7544,9 @@ + #if defined NANOJIT_X64 + jitstats.archIsAMD64 = 1; + #endif ++#if defined NANOJIT_MIPS ++ jitstats.archIsMIPS = 1; ++#endif + #endif + } + +diff -r 4c7acf580717 js/src/nanojit/CodeAlloc.cpp +--- a/js/src/nanojit/CodeAlloc.cpp Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/nanojit/CodeAlloc.cpp Thu Dec 10 08:37:44 2009 +0800 +@@ -54,7 +54,11 @@ + #else + static const int pagesPerAlloc = 16; + #endif ++#if defined(NANOJIT_MIPS) ++ static const int bytesPerPage = 16384; ++#else + static const int bytesPerPage = 4096; ++#endif + static const int bytesPerAlloc = pagesPerAlloc * bytesPerPage; + + CodeAlloc::CodeAlloc() +diff -r 4c7acf580717 js/src/nanojit/Native.h +--- a/js/src/nanojit/Native.h Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/nanojit/Native.h Thu Dec 10 08:37:44 2009 +0800 +@@ -117,6 +117,8 @@ + #include "NativeSparc.h" + #elif defined(NANOJIT_X64) + #include "NativeX64.h" ++#elif defined(NANOJIT_MIPS) ++#include "NativeMips.h" + #else + #error "unknown nanojit architecture" + #endif +diff -r 4c7acf580717 js/src/nanojit/NativeMips.cpp +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/js/src/nanojit/NativeMips.cpp Thu Dec 10 08:37:44 2009 +0800 +@@ -0,0 +1,1518 @@ ++/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 4 -*- */ ++/* vi: set ts=4 sw=4 expandtab: (add to ~/.vimrc: set modeline modelines=5) */ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is [Open Source Virtual Machine]. ++ * ++ * The Initial Developer of the Original Code is ++ * Adobe System Incorporated. ++ * Portions created by the Initial Developer are Copyright (C) 2008 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Adobe AS3 Team ++ * Zhou Shuchang <shuchang.zhou at gmail.com> ++ * Ling Kun <erlv5241 at gmail.com> ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++#include "nanojit.h" ++#if defined FEATURE_NANOJIT && defined NANOJIT_MIPS ++ ++/** ++ * We assume the target platform is at least MIPS III and with 64-bit GP and ++ * FP registers. When holding a 32-bit value in GP register, We always sign-extend it. ++*/ ++ ++namespace nanojit ++{ ++#ifdef NJ_VERBOSE ++ const char *regNames[] = { ++ "r0", "r1", "r2", "r3", "r4", "r5", "r6", "r7", ++ "r8", "r9", "r10", "r11", "r12", "r13", "r14", "r15", ++ "r16", "r17", "r18", "r19", "r20", "r21", "r22", "r23", ++ "r24", "r25", "r26", "r27", "gp", "sp", "fp", "ra", ++ "f0", "f1", "f2", "f3", "f4", "f5", "f6", "f7", ++ "f8", "f9", "f10", "f11", "f12", "f13", "f14", "f15", ++ "f16", "f17", "f18", "f19", "f20", "f21", "f22", "f23", ++ "f24", "f25", "f26", "f27", "f28", "f29", "f30", "f31" ++ }; ++#endif ++ ++ const Register Assembler::retRegs[] = { R2, R3 }; ++ const Register Assembler::retFpRegs[] = { D0, D2 }; ++ const RegisterMask allowGpRegs = AllowableFlagRegs; ++#ifdef N32ABI ++ const RegisterMask allowFpRegs = FpRegs; ++#else ++ const RegisterMask allowFpRegs = 0x5555500000000LL; ++#endif ++#ifdef N32ABI ++ const Register Assembler::argRegs[] = { R4, R5, R6, R7, R8, R9, R10, R11 }; ++ const Register Assembler::fpArgRegs[] = { D12, D13, D14, D15, D16, D17, D18, D19 }; ++ const Register lastArgReg = R11; ++ const Register lastFloatArgReg = D19; ++#else ++ const Register Assembler::argRegs[] = { R4, R5, R6, R7 }; ++ const Register Assembler::fpArgRegs[] = { D12, D14 }; ++ const Register lastArgReg = R7; ++ const Register lastFloatArgReg = D14; ++#endif ++ // callee-save and not special ++ const Register Assembler::savedRegs[] = { ++ R16, R17, R18, R19, R20, R21, R22, R23, ++// D20, D22, D24, D26, D28, D30, ++ }; ++ ++ /** ++ low address ++ sp -> arguments to pass to what I call ++ locals and temporaries ++ FP register save area, doubleword aligned ++ GP register save area, doubleword aligned ++ old sp -> incoming arguments if any ++ high address ++ */ ++ ++ #define TODO(x) do{ avmplus::AvmLog(#x); NanoAssertMsgf(false, "%s", #x); } while(0) ++ ++#ifdef N32ABI ++ #define MIPS_STACK_GRANULARITY 8 ++#else ++ #define MIPS_STACK_GRANULARITY 4 ++#endif ++ const int linkage_size = 16; // save RA, FP, GP ++ ++ const int GP_position = -12; ++ const int FP_position = -8; ++ const int RA_position = -4; ++ ++ void Assembler::addiu(Register dst,Register src,int32_t imm) ++ { ++ DADDIU(dst,src,imm); ++ } ++ ++ void Assembler::check_is_sign_extend(Register r) ++ { ++ Register t = registerAllocTmp(allowGpRegs & ~(rmask(r))); ++ SLTU(r,R0,r); ++ XOR(r,r,t); ++ DSRA32(t,t,0); ++ DSLL32(t,r,0); ++ } ++ ++ void Assembler::asm_CC0(Register rs) ++ { ++ ANDI(rs,rs,1); ++ DSRL(rs,rs,23); ++ READFCR(rs); ++ } ++ ++ void Assembler::asm_set_cc(Register r){ ++// Register t = registerAllocTmp(allowGpRegs&~rmask(r)); ++// WRITEFCR(t); ++// OR(t,t,r); ++// NOR(r,r,R0); ++// AND(t,t,r); ++// NOR(r,r,R0); ++// READFCR(t); ++// SLL(r,r,23); ++// SLTIU(r,r,1); ++// SLTIU(r,r,1); ++ Register fr = registerAllocTmp(allowFpRegs); ++ Register fr2 = registerAllocTmp(allowFpRegs&~rmask(fr)); ++ C_EQ_D(fr,fr2); ++ DMTC1(R0,fr2); ++ DMTC1(r,fr); ++ } ++ ++ void Assembler::asm_li(Register r, int32_t imm) ++ { ++ #if !PEDANTIC ++ if (isU16(imm)) { ++ ORI(r, R0, imm); ++ return; ++ } ++ if (isS16(imm)) { ++ addiu(r, R0, imm); // imm is sign extended ++ return; ++ } ++ if ((uint32_t(imm) & 0xffff) == 0) { ++ imm = uint32_t(imm) >> 16; ++ LUI(r, imm); ++ return; ++ } ++ #endif ++ asm_li32(r, imm); ++ } ++ ++ void Assembler::asm_li32(Register r, int32_t imm) ++ { ++ // general case ++ ORI(r, r, uint32_t(imm) & 0xffff); ++ LUI(r, uint32_t(imm)>>16); // on MIPS, this sign extends ++ } ++ ++ void Assembler::nInit(AvmCore*) ++ {} ++ ++ void Assembler::nBeginAssembly() ++ { ++ max_param_size = 0; ++ } ++ ++ NIns* Assembler::genPrologue() ++ { ++#ifdef N32ABI ++ uint32_t reserved = max_param_size - NUMARGREGS >0? (max_param_size - NUMARGREGS) * 8 : 0; ++#else ++ uint32_t reserved = (max_param_size>4?max_param_size:4) * 4; ++#endif ++ uint32_t stackNeeded = reserved + _activation.tos * MIPS_STACK_GRANULARITY; ++ ++ uint32_t aligned = alignUp(stackNeeded, NJ_ALIGN_STACK); ++ int frame_size = aligned; ++ ++ if (isS16(frame_size)) { ++ addiu(SP, SP, -frame_size); ++ } else { ++ TODO(large frame size); ++ } ++ verbose_only( asm_output("[frag entry]"); ) ++ NIns *fragEntry = _nIns; ++ MR(FP, SP); ++ addiu(SP,SP,-linkage_size); ++ ++ SW(GP,GP_position,SP); ++ SW(FP,FP_position,SP); ++ SW(RA,RA_position,SP); ++ return fragEntry; ++ } ++ ++ void Assembler::nFragExit(LInsp guard) ++ { ++ SideExit* exit = guard->record()->exit; ++ Fragment *frag = exit->target; ++ GuardRecord *lr = 0; ++ bool destKnown = (frag && frag->fragEntry); ++ ++ if (destKnown) { ++ JMP(frag->fragEntry); ++ lr = 0; ++ } else { ++ // target doesn't exit yet. emit jump to epilog, and set up to patch later. ++ if (!_epilogue) ++ _epilogue = genEpilogue(); ++ lr = guard->record(); ++ JMP(_epilogue); ++ lr->jmp = _nIns; ++ } ++ ++ // profiling for the exit ++ verbose_only( ++ if (_logc->lcbits & LC_FragProfile) { ++ asm_inc_m32( &guard->record()->profCount ); ++ } ++ ) ++ ++ // pop the stack frame first ++ MOV(SP, FP); ++ Register r = registerAllocTmp(rmask(retRegs[0])); ++ // return value is GuardRecord* ++ asm_li(r,(int)lr); ++ } ++ ++ NIns* Assembler::genEpilogue() ++ { ++ NOP(); ++ JR(RA); ++ ++ LW(GP,GP_position,SP); ++ LW(FP,FP_position,SP); ++ LW(RA,RA_position,SP); ++ addiu(SP,SP,linkage_size); ++ return _nIns; ++ } ++ ++ void Assembler::asm_qjoin(LIns *ins) ++ { ++ Register d = prepResultReg(ins, allowFpRegs); ++ Register t = registerAllocTmp(allowGpRegs); ++ LIns* lo = ins->oprnd1(); ++ LIns* hi = ins->oprnd2(); ++ Register r,r2; ++ findRegFor2(allowGpRegs&~rmask(t),lo,r2,hi,r); ++ asm_nongp_copy(d,t); ++ OR(t,t,r2); ++ DSLL32(t,r,0); ++ } ++ ++ void Assembler::asm_load32(LInsp ins) ++ { ++ LOpcode op = ins->opcode(); ++ LIns* base = ins->oprnd1(); ++ int32_t d = ins->disp(); ++ Register rr = prepResultReg(ins, ins->isQuad()?allowFpRegs: allowGpRegs); ++ Register ra = getBaseReg(op, base, d, allowGpRegs&~rmask(rr)); ++ ++ #if !PEDANTIC ++ if (isS16(d)) { ++ switch(op){ ++ case LIR_ldcb: ++ LB(rr, d, ra); ++ break; ++ case LIR_ldcs: ++ LH(rr, d, ra); ++ break; ++ case LIR_ld: ++ case LIR_ldc: ++ LW(rr, d, ra); ++ break; ++ case LIR_ldq: ++ case LIR_ldqc: ++ LDC1(rr, d, ra); ++ break; ++ default: ++ TODO(asm_load32); ++ break; ++ } ++ return; ++ } ++ #endif ++ Register t = registerAllocTmp(allowGpRegs & ~(rmask(ra)|rmask(rr))); ++ // general case ++ switch(ins->opcode()){ ++ case LIR_ldcb: ++ LB(rr, 0, t); ++ break; ++ case LIR_ldcs: ++ LH(rr, 0, t); ++ break; ++ case LIR_ld: ++ case LIR_ldc: ++ LW(rr, 0, t); ++ break; ++ case LIR_ldq: ++ case LIR_ldqc: ++ LDC1(rr, 0, t); ++ break; ++ default: ++ TODO(asm_load32); ++ break; ++ } ++ DADDU(t,t,ra); ++ asm_li(t,d); ++ } ++ ++ void Assembler::asm_load64(LIns *ins) ++ { ++ asm_load32(ins); ++ } ++ ++ void Assembler::asm_save_word(Register value, int32_t dr, Register base) ++ { ++ NanoAssert(IsGpReg(value) && IsGpReg(base)); ++ if ((dr&3)!=0) { ++ SWR(value,dr,base); ++ SWL(value,(dr+3),base); ++ } else ++ SW(value,dr,base); ++ } ++ ++ void Assembler::asm_save_dword(Register value, int32_t dr, Register base) ++ { ++ NanoAssert(IsGpReg(base)); ++ ++ if ((dr&7)!=0) { ++ NanoAssert(IsGpReg(value)); ++ Register r; ++ if (IsGpReg(value)) ++ r = value; ++ else ++ r = registerAllocTmp(allowGpRegs&~rmask(base)); ++ SDR(r,dr,base); ++ SDL(r,(dr+7),base); ++ if (!IsGpReg(value)) ++ asm_nongp_copy(r,value); ++ } else if (IsGpReg(value)) ++ SD(value,dr,base); ++ else ++ SDC1(value,dr,base); ++ } ++ ++ void Assembler::asm_store32(LOpcode op, LIns *value, int32_t dr, LIns *base) ++ { ++ switch (op) { ++ case LIR_sti: ++ // handled by mainline code below for now ++ break; ++ case LIR_stb: ++ case LIR_sts: ++ NanoAssertMsg(0, "NJ_EXPANDED_LOADSTORE_SUPPORTED not yet supported for this architecture"); ++ return; ++ default: ++ NanoAssertMsg(0, "asm_store32 should never receive this LIR opcode"); ++ return; ++ } ++ ++ Register ra, rb; ++ if (base->isop(LIR_alloc)) { ++ rb = FP; ++ dr += findMemFor(base); ++ ra = findRegFor(value, allowGpRegs); ++ } else { ++ findRegFor2(allowGpRegs, value, ra, base, rb); ++ } ++ #if !PEDANTIC ++ if (isS16(dr)) { ++ asm_save_word(ra, dr, rb); ++ return; ++ } ++ #endif ++ Register t = registerAllocTmp(allowGpRegs & ~(rmask(ra)|rmask(rb))); ++ // general case store, any offset size ++ asm_save_word(ra, 0,t); ++ DADDU(t,t,rb); ++ asm_li(t,dr); ++ } ++ ++ /** minor difference from store32 */ ++ void Assembler::asm_store64(LOpcode op, LIns *value, int32_t dr, LIns *base) ++ { ++ switch (op) { ++ case LIR_stqi: ++ // handled by mainline code below for now ++ break; ++ case LIR_st32f: ++ NanoAssertMsg(0, "NJ_EXPANDED_LOADSTORE_SUPPORTED not yet supported for this architecture"); ++ return; ++ default: ++ NanoAssertMsg(0, "asm_store64 should never receive this LIR opcode"); ++ return; ++ } ++ ++ Register ra, rb; ++ ra = findRegFor(value, allowFpRegs); ++ if (base->isop(LIR_alloc)) { ++ rb = FP; ++ dr += findMemFor(base); ++ } else { ++ rb = findRegFor(base, allowGpRegs); ++ } ++#if !PEDANTIC ++ if (isS16(dr)) { ++ asm_save_dword(ra, dr, rb); ++ return; ++ } ++#endif ++ Register t = registerAllocTmp(allowGpRegs & ~(rmask(ra)|rmask(rb))); ++ // general case store, any offset size ++ asm_save_dword(ra, 0,t); ++ DADDU(t,t,rb); ++ asm_li(t,dr); ++ } ++ ++ // cannot use two asm_li here, as LUI will sign extend the immediate ++ void Assembler::asm_li64(Register r, uint64_t imm) ++ { ++ NanoAssert(IsGpReg(r)); ++ uint32_t lo = imm&0xffffffff; ++ if (lo) { ++ if (lo>>16) { ++ if (lo&0xffff) { ++ ORI(r,r,lo&0xffff); ++ } ++ DSLL(r,r,16); ++ ORI(r,r,lo>>16); ++ DSLL(r,r,16); ++ } else { ++ ORI(r,r,lo&0xffff); ++ DSLL32(r,r,0); ++ } ++ } else ++ DSLL32(r,r,0); ++ asm_li(r, (uint32_t)(imm>>32)); ++ } ++ ++ void Assembler::asm_cond(LInsp ins) ++ { ++ LOpcode op = ins->opcode(); ++ NanoAssert(!(op >= LIR_feq && op <= LIR_fge)); ++ ++ Register r = prepResultReg(ins, AllowableFlagRegs); ++ asm_cmp(r, ins, false); ++ } ++ ++ void Assembler::asm_cmp(Register r, LIns *ins, bool flipped) ++ { ++ LOpcode op = ins->opcode(); ++ NanoAssert(!(op >= LIR_feq && op <= LIR_fge)); ++ ++ if (ins->isLInsOp1()) { ++ LIns *value = ins->oprnd1(); ++ LOpcode value_op = value->opcode(); ++ switch (op) { ++ case LIR_ov: ++ if (value_op == LIR_neg) { ++ Register rs = findRegFor(ins->oprnd1(),allowGpRegs&~rmask(r)); ++ Register t = registerAllocTmp(allowGpRegs & ~(rmask(r)|rmask(rs))); ++ MOVN(r,R0,t); //r=1 if t=0 ++ SLL(t,rs,1); //lower 31 bit all 0 ++ ANDI(r,r,1); ++ SRL(r,rs,31); //MSB is 1 ++ return; ++ } else if (value->isLInsOp2()) { ++ Register rs,rt; ++ Register t = findRegFor(value,allowGpRegs&~rmask(r)); ++ findRegFor2(allowGpRegs&~(rmask(r)|rmask(t)),value->oprnd1(),rs,value->oprnd2(),rt); ++ Register tt = registerAllocTmp(allowGpRegs & ~(rmask(rs)|rmask(rt)|rmask(r)|rmask(t))); ++ switch(value_op){ ++ // overflow if in rs + rt = t, s(rs), s(rt), s(t) = 1,1,0/0,0,1 ++ case LIR_add: ++ ANDI(r,r,1); ++ SRL(r,r,31); ++ AND(r,r,tt); ++ XOR(tt,t,rs); ++ XOR(r,t,rt); ++ return; ++ case LIR_sub: ++ // s(rs) - s(rt), s(t) = 1,0,0/0,1,1 ++ ANDI(r,r,1); ++ SRL(r,r,31); ++ AND(r,r,tt); ++ XOR(tt,rs,t); ++ XOR(r,rs,rt); ++ return; ++ case LIR_mul: ++ // overflow if the result is either (not an signed-extension) or (wrong signed bit) ++ SLTU(r,R0,r); ++ OR(r,r,tt); ++ ANDI(tt,tt,1); // tt should be zero ++ DSRL(tt,tt,31); ++ XOR(tt,t,tt); ++ XOR(tt,rs,rt); ++ XOR(r,t,tt); // r should be 0 ++ DSRA32(tt,tt,0); ++ DSLL32(tt,t,0); ++ return; ++ default: ++ TODO(LIR_ov); ++ break; ++ } ++ } else if (value_op==LIR_ld) { ++ LInsp base = value->oprnd1(); ++ int d = value->disp(); ++ Register ra = getBaseReg(value_op, base,d,allowGpRegs&~rmask(r)); ++ Register fr = registerAllocTmp(allowFpRegs); ++ check_is_sign_extend(r); ++ asm_nongp_copy(r,fr); ++ LDC1(fr,d,ra); ++ return; ++ } else if (value_op==LIR_int) { ++ Register t = findRegFor(value,allowGpRegs&~rmask(r)); ++ check_is_sign_extend(r); ++ MR(r,t); ++ return; ++ } ++ break; ++ default: ++ NanoAssert ( 0 && "asm_cond"); ++ break; ++ } ++ } else if (ins->isLInsOp2()) { ++ Register rs,rt; ++ findRegFor2(allowGpRegs&~rmask(r),ins->oprnd1(),rs,ins->oprnd2(),rt); ++ switch (op) { ++ case LIR_qeq: ++ case LIR_eq: ++ if (!flipped) SLTIU(r,r,1); ++ XOR(r,rs,rt); ++ break; ++ case LIR_qlt: ++ case LIR_lt: ++ SLT(r,rs,rt); ++ break; ++ case LIR_qult: ++ case LIR_ult: ++ SLTU(r,rs,rt); ++ break; ++ case LIR_qgt: ++ case LIR_gt: ++ SGT(r,rs,rt); ++ break; ++ case LIR_qugt: ++ case LIR_ugt: ++ SGTU(r,rs,rt); ++ break; ++ case LIR_qle: ++ case LIR_le: ++ if (!flipped) SLTIU(r,r,1); ++ SGT(r,rs,rt); ++ break; ++ case LIR_qule: ++ case LIR_ule: ++ if (!flipped) SLTIU(r,r,1); ++ SGTU(r,rs,rt); ++ break; ++ case LIR_qge: ++ case LIR_ge: ++ if (!flipped) SLTIU(r,r,1); ++ SLT(r,rs,rt); ++ break; ++ case LIR_quge: ++ case LIR_uge: ++ if (!flipped) SLTIU(r,r,1); ++ SLTU(r,rs,rt); ++ break; ++ default: ++ TODO(asm_cmp); ++ break; ++ } ++ return; ++ } ++ TODO(asm_cond); ++ } ++ ++ void Assembler::asm_fcmp(LInsp ins) { ++ LOpcode op = ins->opcode(); ++ Register rs,rt; ++ findRegFor2(allowFpRegs,ins->oprnd1(),rs,ins->oprnd2(),rt); ++ switch (op) { ++ case LIR_feq: ++ C_EQ_D(rs,rt); ++ return; ++ case LIR_flt: ++ C_LT_D(rs,rt); ++ return; ++ case LIR_fle: ++ C_LE_D(rs,rt); ++ return; ++ case LIR_fgt: ++ C_GT_D(rs,rt); ++ return; ++ case LIR_fge: ++ C_GE_D(rs,rt); ++ return; ++ default: ++ break; ++ } ++ debug_only(outputf("%s",lirNames[ins->opcode()]);) ++ TODO(asm_fcmp); ++ } ++ ++ void Assembler::asm_fcond(LIns *ins) ++ { ++ LOpcode op = ins->opcode(); ++ NanoAssert(op >= LIR_feq && op <= LIR_fge); ++ ++ Register r = prepResultReg(ins, AllowableFlagRegs); ++ asm_CC0(r); ++ asm_fcmp(ins); ++ } ++ ++ NIns *Assembler::asm_branch(bool onfalse, LIns *cond, NIns * targ) ++ { ++ // we branch around a long jump ++ LOpcode op = cond->opcode(); ++ bool fcond = (op >= LIR_feq && op <= LIR_fge); ++ Register flagScratchReg = UnknownReg; ++ ++ bool canMerge = (op == LIR_eq || op == LIR_qeq); ++ ++ if (!fcond && !canMerge) ++ flagScratchReg = prepResultReg(cond, AllowableFlagRegs); ++ NIns *patch = 0; ++ underrunProtect(4*(JMP_LENGTH+1)); ++ intptr_t tt = ((intptr_t)targ - (intptr_t)_nIns + 4) >> 2; ++ ++ // !targ means that it needs patch. ++ bool canJOpt = ((((uint32_t)targ)>>28) == ((uint32_t)((intptr_t)_nIns - 4)>>28)) && targ; ++ if (isS16((int32_t)tt) && targ) ++ NOP_nochk(); ++ else if (canJOpt) { ++ NOP_nochk(); ++ J_nochk((uint32_t)targ &0xfffffff); ++ NOP_nochk(); ++ tt = 3; ++ onfalse = !onfalse; ++ } else { ++ JMP_nochk((intptr_t)targ); ++ patch = _nIns; ++ tt = JMP_LENGTH; ++ onfalse = !onfalse; ++ } ++ bool flipped = false; ++ switch (op) { ++ case LIR_le: ++ case LIR_ule: ++ case LIR_qle: ++ case LIR_qule: ++ flipped = true; ++ onfalse = !onfalse; ++ break; ++ default: ++ break; ++ } ++ if (!onfalse) { ++ if (fcond) ++ BC1T_nochk(tt); ++ else { ++ if (canMerge) { ++ Register rs,rt; ++ findRegFor2(allowGpRegs,cond->oprnd1(),rs,cond->oprnd2(),rt); ++ NanoAssert(op==LIR_eq); ++ BEQ_nochk(rs,rt,tt); ++ } else ++ BNE_nochk(flagScratchReg,R0,tt); ++ } ++ } else { ++ if (fcond) ++ BC1F_nochk(tt); ++ else { ++ if (canMerge) { ++ Register rs,rt; ++ findRegFor2(allowGpRegs,cond->oprnd1(),rs,cond->oprnd2(),rt); ++ NanoAssert(op==LIR_eq); ++ BNE_nochk(rs,rt,tt); ++ } else ++ BEQ_nochk(flagScratchReg,R0,tt); ++ } ++ } ++ if (fcond) ++ asm_fcmp(cond); ++ else if (!canMerge) ++ asm_cmp(flagScratchReg, cond, flipped); ++ debug_only( asm_output("[asm_branch]: targ = %p\n",(void*)targ)); ++ return patch; ++ } ++ ++ void Assembler::asm_ret(LInsp ins) ++ { ++ genEpilogue(); ++ ++ MOV(SP,FP); ++ assignSavedRegs(); ++ LIns *value = ins->oprnd1(); ++ ++ if (ins->isop(LIR_ret)) { ++ NanoAssert(!ins->isQuad()); ++ findSpecificRegFor(value, retRegs[0]); ++ } ++ else { ++ NanoAssert(ins->isQuad()); ++ NanoAssert(ins->isop(LIR_fret)); ++ findSpecificRegFor(value, retFpRegs[0]); ++ } ++ } ++ ++ void Assembler::asm_nongp_copy(Register r, Register s) ++ { ++ if ((rmask(r) & FpRegs) && (rmask(s) & FpRegs)) { ++ MOV_D(r, s); ++ } else if ((rmask(r) & FpRegs) && (rmask(s) & GpRegs)) { ++ DMTC1(s,r); ++ } else if ((rmask(r) & GpRegs) && (rmask(s) & FpRegs)) { ++ DMFC1(r,s); ++ } else ++ NanoAssert(0 && "asm_nongp_copy"); ++ } ++ ++ void Assembler::asm_restore(LInsp i, Register r) ++ { ++ if (i->isop(LIR_alloc)) { ++ addiu(r, FP, disp(i)); ++ } ++ else if (i->isconst()) { ++ if (!i->getArIndex()) { ++ i->markAsClear(); ++ } ++ asm_li(r, i->imm32()); ++ } ++ else { ++ int d = findMemFor(i); ++ if (IsFpReg(r)) { ++ NanoAssert(i->isQuad()); ++ LDC1(r, d, FP); ++ } else if (i->isQuad()) { ++ LD(r, d, FP); ++ } else { ++ LW(r, d, FP); ++ } ++ } ++ } ++ ++ void Assembler::asm_int(LIns *ins) ++ { ++ Register rr = prepResultReg(ins, allowGpRegs); ++ asm_li(rr, ins->imm32()); ++ } ++ ++ void Assembler::asm_fneg(LIns *ins) ++ { ++ Register rr = prepResultReg(ins, allowFpRegs); ++ Register ra = findRegFor(ins->oprnd1(), allowFpRegs); ++ NEG_D(rr,ra); ++ } ++ ++ void Assembler::asm_param(LIns *ins) ++ { ++ uint32_t a = ins->paramArg(); ++ uint32_t kind = ins->paramKind(); ++ if (kind == 0) { ++ if (a < NUMARGREGS) { ++ // incoming arg in register ++ prepResultReg(ins, rmask(argRegs[a])); ++ } else { ++ TODO(asm_param_stk); ++ } ++ } ++ else { ++ // saved param ++ prepResultReg(ins, rmask(savedRegs[a])); ++ } ++ } ++ ++ void Assembler::asm_stkarg(LInsp arg, int stkd) ++ { ++#ifdef N32ABI ++ TODO(asm_stkarg); ++#else ++ bool isQuad = arg->isQuad(); ++ ++ Register rr; ++ ++ if (arg->isUsed() && (rr = arg->getReg(), isKnownReg(rr))) { ++ // The argument resides somewhere in registers, so we simply need to ++ // push it onto the stack. ++ if (!isQuad) { ++ NanoAssert(IsGpReg(rr)); ++ ++ SW(rr, stkd * MIPS_STACK_GRANULARITY, SP); ++ } else { ++ NanoAssert((stkd&1)==0); ++ asm_save_dword(rr, stkd*MIPS_STACK_GRANULARITY, SP); ++ } ++ } else { ++ // The argument does not reside in registers, so we need to get some ++ // memory for it and then copy it onto the stack. ++ int d = findMemFor(arg); ++ if (!isQuad) { ++ Register t = registerAllocTmp(allowGpRegs); ++ SW(t, stkd*MIPS_STACK_GRANULARITY, SP); ++ if (arg->isop(LIR_alloc)) { ++ addiu(t, FP, d); ++ } else { ++ LW(t, d, FP); ++ } ++ } else { ++ Register t = registerAllocTmp(allowFpRegs); ++ NanoAssert((stkd&1)==0); ++ SDC1(t, stkd*MIPS_STACK_GRANULARITY, SP); ++ LDC1(t, d, FP); ++ } ++ } ++#endif ++ } ++ ++ void Assembler::asm_call(LIns *ins) ++ { ++ if (ins->isop(LIR_fcall)) { ++ prepResultReg(ins, rmask(retFpRegs[0])); ++ } else { ++ prepResultReg(ins, rmask(retRegs[0])); ++ } ++ evictScratchRegs(); ++ ++ const CallInfo* call = ins->callInfo(); ++ ArgSize sizes[MAXARGS]; ++ uint32_t argc = call->get_sizes(sizes); ++ ++ bool indirect = call->isIndirect(); ++ ++ Register t = registerAllocTmp(rmask(R25)); ++ verbose_only(if (_logc->lcbits & LC_Assembly) ++ outputf(" %p:", _nIns); ++ ) ++ NOP(); ++ JALR(RA,t); ++ if (!indirect) { ++ asm_li(t,call->_address); ++ } else { ++ asm_regarg(ARGSIZE_P, ins->arg(--argc), RA); ++ } ++ ++ int param_size = 0; ++#ifndef N32ABI ++ bool isFpLeading = true; ++#endif ++ Register r = argRegs[0]; ++ Register fr = fpArgRegs[0]; ++ for(uint32_t i = 0; i < argc; i++) { ++ uint32_t j = argc - i - 1; ++ ArgSize sz = sizes[j]; ++ LInsp arg = ins->arg(j); ++ if (sz & ARGSIZE_MASK_INT) { ++ if (sz==ARGSIZE_Q) { ++ TODO(how are int64 arguments passed?); ++ } ++ NanoAssert(sz==ARGSIZE_I); ++ // GP arg ++ if (r <= lastArgReg) { ++ asm_regarg(sz, arg, r); ++ r = nextreg(r); ++ fr = nextreg(fr); ++ } else { ++ asm_stkarg(arg, param_size); ++ } ++#ifndef N32ABI ++ isFpLeading = false; ++#endif ++ param_size += 1; ++ } else if (sz == ARGSIZE_F) { ++ if (param_size&1) ++ param_size += 1; ++#ifndef N32ABI ++ if (!isFpLeading) { ++ if ((r-argRegs[0]) & 1) ++ r = nextreg(r); ++ if (r <= lastArgReg) { ++ asm_regarg(sz, arg, r); ++ r = nextreg(nextreg(r)); ++ } else { ++ asm_stkarg(arg ,param_size); ++ } ++ } else ++#endif ++ { ++ if (fr <= lastFloatArgReg) { ++ asm_regarg(sz, arg, fr); ++ #ifdef N32ABI ++ r = nextreg(r); ++ fr = nextreg(fr); ++ #else ++ r = nextreg(nextreg(r)); // skip 2 gpr's ++ fr = nextreg(nextreg(fr)); ++ #endif ++ } else { ++ asm_stkarg(arg ,param_size); ++ } ++ } ++ param_size+=2; ++ } else { ++ TODO(ARGSIZE_UNK); ++ } ++ } ++ if (param_size > max_param_size ) ++ max_param_size = param_size; ++ } ++ ++ void Assembler::asm_regarg(ArgSize sz, LInsp p, Register r) ++ { ++ // TODO: how are int64 arguments passed? ++ NanoAssert(isKnownReg(r)); ++ if (sz & ARGSIZE_MASK_INT) ++ { ++ #if defined NANOJIT_64BIT && !defined N32ABI ++ if (sz == ARGSIZE_LO) { ++ // sign extend 32->64 ++ DSRA32(r, r,0); ++ DSLL32(r, r,0); ++ } else if (sz == ARGSIZE_U) { ++ // zero extend 32->64 ++ DSRL32(r, r,0); ++ DSLL32(r, r,0); ++ } ++ #endif ++ // arg goes in specific register ++ if (p->isconst()) { ++ asm_li(r, p->imm32()); ++ } else { ++ if (p->isUsed()) { ++ if (!p->hasKnownReg()) { ++ // load it into the arg reg ++ int d = findMemFor(p); ++ if (p->isop(LIR_alloc)) { ++ NanoAssert(isS16(d)); ++ addiu(r, FP, d); ++ } else if (p->isQuad()) { ++ LD(r, d, FP); ++ } else { ++ LW(r, d, FP); ++ } ++ } else { ++ // it must be in a saved reg ++ MR(r, p->getReg()); ++ } ++ } ++ 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 if (sz == ARGSIZE_F) { ++ if (p->isUsed()) { ++ Register rr = p->getReg(); ++ if (!isKnownReg(rr) || !IsFpReg(rr)) { ++ // load it into the arg reg ++ int d = findMemFor(p); ++ if (IsFpReg(r)) ++ LDC1(r, d, FP); ++ else { ++#ifdef N32ABI ++ NanoAssert ( 0 && "asm_regarg"); ++#else ++ LW(r,d,FP); ++ LW(nextreg(r),d+4,FP); ++#endif ++ } ++ } else { ++#ifdef N32ABI ++ NanoAssert(IsFpReg(r) && IsFpReg(rr)); ++ asm_nongp_copy(r,rr); ++#else ++ NanoAssert(IsFpReg(rr)); ++ Register fr = rr; ++ if (IsFpReg(r)) { ++ NanoAssert(r>=fpArgRegs[0]&&r<=lastFloatArgReg); ++ asm_nongp_copy(r,fr); ++ } ++ else { ++ NanoAssert((r==R4) || (r==R6)); ++ MFC1(r,fr); ++ MFC1(nextreg(r),nextreg(fr)); ++ } ++#endif ++ } ++ } ++ else { ++ // this is the last use, so fine to assign it ++ // to the scratch reg, it's dead after this point. ++#ifdef N32ABI ++ findSpecificRegFor(p, r); ++#else ++ Register fr = findRegFor(p,allowFpRegs); ++ if (IsFpReg(r)) ++ asm_nongp_copy(r,fr); ++ else { ++ MFC1(r,fr); ++ MFC1(nextreg(r),nextreg(fr)); ++ } ++#endif ++ } ++ } ++ else { ++ TODO(ARGSIZE_UNK); ++ } ++ } ++ ++ void Assembler::asm_spill(Register rr, int d, bool /* pop */, bool quad) ++ { ++ NanoAssert((d<=0) && "asm_spill d<=0"); ++ (void)quad; ++ if (d) { ++ if (IsFpReg(rr)) { ++ NanoAssert(quad); ++ SDC1(rr, d, FP); ++ } ++ else if (quad) { ++ SD(rr, d, FP); ++ } ++ else { ++ NanoAssert(!quad); ++ SW(rr, d, FP); ++ } ++ } ++ } ++ ++ void Assembler::asm_arith(LIns *ins) ++ { ++ LOpcode op = ins->opcode(); ++ LInsp lhs,rhs; ++ lhs = ins->oprnd1(); ++ rhs = ins->oprnd2(); ++ ++ RegisterMask allow = allowGpRegs; ++ Register rr = prepResultReg(ins, allow); ++ Register ra = findRegFor(lhs, allowGpRegs & ~rmask(rr)); ++ ++ if (rhs->isconst()) { ++ int32_t rhsc = rhs->imm32(); ++ if (isS16(rhsc)) { ++ // MIPS arith immediate ops sign-extend the imm16 value ++ switch (op) { ++ case LIR_add: ++ case LIR_iaddp: ++ IF_64BIT(case LIR_qiadd:) ++ IF_64BIT(case LIR_qaddp:) ++ addiu(rr, ra, rhsc); ++ return; ++ // we cannot optimize LIR_sub as it will change the way we test for overflow ++ default: ++ break; ++ } ++ } ++ if (isU16(rhsc)) { ++ // MIPS logical immediate zero-extend the imm16 value ++ switch (op) { ++ IF_64BIT(case LIR_qior:) ++ case LIR_or: ++ ORI(rr, ra, rhsc); ++ return; ++ IF_64BIT(case LIR_qiand:) ++ case LIR_and: ++ ANDI(rr, ra, rhsc); ++ return; ++ IF_64BIT(case LIR_qxor:) ++ case LIR_xor: ++ XORI(rr, ra, rhsc); ++ return; ++ default: ++ break; ++ } ++ } ++ ++ // LIR shift ops only use last 5bits of shift const ++ switch (op) { ++ case LIR_lsh: ++ SLL(rr, ra, rhsc&31); ++ return; ++ case LIR_ush: ++ SRL(rr, ra, rhsc&31); ++ return; ++ case LIR_rsh: ++ SRA(rr, ra, rhsc&31); ++ return; ++ #ifdef NANOJIT_64BIT ++ case LIR_qilsh: ++ rhsc = rhsc &63; ++ if(rhsc>=32) ++ DSLL32(rr, ra, rhsc-32); ++ else ++ DSLL(rr, ra, rhsc); ++ return; ++ case LIR_qirsh: ++ rhsc = rhsc &63; ++ if(rhsc>=32) ++ DSRA32(rr, ra, rhsc-32); ++ else ++ DSRA(rr, ra, rhsc); ++ return; ++ case LIR_qursh: ++ rhsc = rhsc &63; ++ if(rhsc>=32) ++ DSRL32(rr, ra, rhsc-32); ++ else ++ DSRL(rr, ra, rhsc); ++ return; ++ #endif ++ default: ++ break; ++ } ++ } ++ ++ // general case, put rhs in register ++ Register rb = rhs==lhs ? ra : findRegFor(rhs, allowGpRegs&~(rmask(ra)|rmask(rr))); ++ switch (op) { ++ IF_64BIT(case LIR_qiadd:) ++ IF_64BIT(case LIR_qaddp:) ++ case LIR_add: ++ case LIR_iaddp: ++ DADDU(rr, ra, rb); ++ break; ++ IF_64BIT(case LIR_qiand:) ++ case LIR_and: ++ AND(rr, ra, rb); ++ break; ++ IF_64BIT(case LIR_qior:) ++ case LIR_or: ++ OR(rr, ra, rb); ++ break; ++ IF_64BIT(case LIR_qxor:) ++ case LIR_xor: ++ XOR(rr, ra, rb); ++ break; ++ case LIR_sub: ++ SUBU(rr, ra, rb); ++ break; ++ case LIR_lsh: ++ SLLV(rr, ra, rr); ++ ANDI(rr, rb, 31); ++ break; ++ case LIR_rsh: ++ SRAV(rr, ra, rr); ++ ANDI(rr, rb, 31); ++ break; ++ case LIR_ush: ++ SRLV(rr, ra, rr); ++ ANDI(rr, rb, 31); ++ break; ++ case LIR_mul: ++ MFLO(rr); ++ DMULT(ra, rb); ++ break; ++ #ifdef NANOJIT_64BIT ++ case LIR_qilsh: ++ t = registerAllocTmp(allowGpRegs & ~(rmask(rr)|rmask(ra)|rmask(rb))); ++ DSLLV(rr, t, rr); ++ ANDI(rr, rb, 31); ++ MOVZ(t,ra,rr); // if <32, restore ra ++ DSLL32(t,ra,0); ++ DSRL(rr,rb,5); ++ break; ++ case LIR_qursh: ++ t = registerAllocTmp(allowGpRegs & ~(rmask(rr)|rmask(ra)|rmask(rb))); ++ DSRLV(rr, t, rr); ++ ANDI(rr, rb, 31); ++ MOVZ(t,ra,rr); // if <32, restore ra ++ DSRL32(t,ra,0); ++ DSRL(rr,rb,5); ++ break; ++ case LIR_qirsh: ++ t = registerAllocTmp(allowGpRegs & ~(rmask(rr)|rmask(ra)|rmask(rb))); ++ DSRAV(rr, t, rr); ++ ANDI(rr, rb, 31); ++ MOVZ(t,ra,rr); // if <32, restore ra ++ DSRA32(t,ra,0); ++ DSRL(rr,rb,5); ++ break; ++ #endif ++ default: ++ debug_only(outputf("%s",lirNames[op]);) ++ TODO(asm_arith); ++ } ++ } ++ ++ void Assembler::asm_fop(LIns *ins) ++ { ++ LOpcode op = ins->opcode(); ++ LInsp lhs = ins->oprnd1(); ++ LInsp rhs = ins->oprnd2(); ++ ++ NanoAssert(op >= LIR_fadd && op <= LIR_fdiv); ++ ++ Register rr = prepResultReg(ins, allowFpRegs); ++ ++ Register ra = findRegFor(lhs, allowFpRegs); ++ Register rb = (rhs == lhs) ? ra : findRegFor(rhs, allowFpRegs & ~rmask(ra)); ++ ++ // XXX special-case 1.0 and 0.0 ++ ++ switch (op) { ++ case LIR_fadd: ADD_D(rr, ra, rb); break; ++ case LIR_fsub: SUB_D(rr, ra, rb); break; ++ case LIR_fmul: MUL_D(rr, ra, rb); break; ++ case LIR_fdiv: DIV_D(rr, ra, rb); break; ++ default: ++ debug_only(outputf("%s",lirNames[op]);) ++ TODO(asm_fop); ++ break; ++ } ++ } ++ ++ void Assembler::asm_i2f(LIns *ins) ++ { ++ Register fr = prepResultReg(ins, allowFpRegs); ++ Register v = findRegFor(ins->oprnd1(), allowGpRegs); ++ Register r = registerAllocTmp(allowGpRegs & ~(rmask(v))); ++ CVT_D_L(fr,fr); ++ DMTC1(r,fr); ++ DSRA32(r,r,0); ++ DSLL32(r,v,0); ++ } ++ ++ void Assembler::asm_u2f(LIns *ins) ++ { ++ Register fr = prepResultReg(ins, allowFpRegs); ++ Register v = findRegFor(ins->oprnd1(), allowGpRegs); ++ Register r = registerAllocTmp(allowGpRegs & ~(rmask(v))); ++ CVT_D_L(fr,fr); ++ DMTC1(r,fr); ++ DSRL32(r,r,0); ++ DSLL32(r,v,0); ++ } ++ ++ void Assembler::asm_promote(LIns *ins) ++ { ++ LOpcode op = ins->opcode(); ++ Register r = prepResultReg(ins, allowGpRegs); ++ Register v = findRegFor(ins->oprnd1(), allowGpRegs); ++ switch (op) { ++ default: ++ debug_only(outputf("%s",lirNames[op])); ++ TODO(asm_promote); ++ case LIR_u2q: ++ DSRL32(r,r,0); ++ DSLL32(r,v,0); // clears the top 32 bits ++ break; ++ case LIR_i2q: ++ DSRA32(r,r,0); ++ DSLL32(r,v,0); ++ break; ++ } ++ } ++ ++ void Assembler::asm_quad(LIns *ins) ++ { ++ Register fr = prepResultReg(ins, allowFpRegs); ++ NanoAssert(IsFpReg(fr)); ++ Register r = registerAllocTmp(allowGpRegs); ++ asm_nongp_copy(fr,r); ++ uint64_t imm = ins->imm64(); ++ uint32_t lo = imm&0xffffffff; ++ ORI(r,r,lo&0xffff); ++ DSLL(r,r,16); ++ ORI(r,r,lo>>16); ++ DSLL(r,r,16); ++ asm_li(r, (uint32_t)(imm>>32)); ++ } ++ ++ // enough room for n bytes ++ void Assembler::underrunProtect(int n) ++ { ++ NIns *eip = _nIns; ++ NanoAssertMsg(n<=LARGEST_UNDERRUN_PROT, "constant LARGEST_UNDERRUN_PROT is too small"); ++ // This may be in a normal code chunk or an exit code chunk. ++ if (eip - n < codeStart) { ++ codeAlloc(codeStart, codeEnd, _nIns verbose_only(, codeBytes)); ++ JMP_nochk(eip); ++ } ++ } ++ ++ void Assembler::asm_cmov(LIns *ins) ++ { ++ NanoAssert(ins->isop(LIR_cmov) || ins->isop(LIR_qcmov)); ++ LIns* cond = ins->oprnd1(); ++ LIns* iftrue = ins->oprnd2(); ++ LIns* iffalse = ins->oprnd3(); ++ ++ NanoAssert(cond->isCmp()); ++ NanoAssert(iftrue->isQuad() == iffalse->isQuad()); ++ ++ Register rr = prepResultReg(ins, allowGpRegs); ++ Register rt,rf; ++ findRegFor2(allowGpRegs&~rmask(rr),iftrue,rt,iffalse,rf); ++ Register rcond = findRegFor(cond, allowGpRegs & ~rmask(rr) & ~rmask(rt)& ~rmask(rf)); ++ MOVN(rr,rt,rcond); ++ MR(rr, rf); ++ } ++ ++ RegisterMask Assembler::hint(LIns *i, RegisterMask allow) ++ { ++ LOpcode op = i->opcode(); ++ RegisterMask prefer = ~0LL; ++ prefer &= (allowFpRegs | allowGpRegs); ++ if (op == LIR_icall || op == LIR_qcall) ++ prefer = rmask(retRegs[0]); ++ else if (op == LIR_fcall) ++ prefer = rmask(retFpRegs[0]); ++ else if (op == LIR_callh) { ++ TODO(callh); ++ prefer = rmask(retRegs[1]); ++ } ++ else if (op == LIR_param) { ++ if (i->paramKind() == 0) { ++ if (i->paramArg() < MAXARGS) { ++ prefer = rmask(argRegs[i->paramArg()]); ++ } else ++ TODO(hint); ++ } else { ++ if (i->paramArg() < NumSavedRegs) ++ prefer &= rmask(savedRegs[i->paramArg()]); ++ } ++ } ++ else if (i->isCmp()) { ++ prefer &= AllowableFlagRegs; ++ } ++ ++ // narrow the allow set to whatever is preferred and also free ++ if (_allocator.free & allow & prefer) ++ allow &= prefer; ++ return allow; ++ } ++ ++ void Assembler::asm_neg_not(LIns *ins) ++ { ++ Register rr = prepResultReg(ins, allowGpRegs); ++ Register ra = findRegFor(ins->oprnd1(), allowGpRegs); //result can be in the same reg ++ if (ins->isop(LIR_neg)) { ++ NEG(rr, ra); ++ } else { ++ NanoAssert(ins->opcode()==LIR_not); ++ NOR(rr, ra, R0); ++ } ++ } ++ ++ void Assembler::asm_qlo(LIns *ins) ++ { ++ Register rr = prepResultReg(ins, allowGpRegs); ++ int rs = findRegFor(ins->oprnd1(), allowGpRegs); ++ DSRL32(rr,rr,0); ++ DSLL32(rr,rs,0); ++ } ++ ++ void Assembler::asm_qhi(LIns *ins) ++ { ++ Register rr = prepResultReg(ins, allowGpRegs); ++ int rs = findRegFor(ins->oprnd1(), allowGpRegs); ++ DSRL32(rr,rs,0); ++ } ++ ++ void ++ Assembler::nativePageSetup() ++ { ++ NanoAssert(!_inExit); ++ if (!_nIns) ++ codeAlloc(codeStart, codeEnd, _nIns verbose_only(, codeBytes)); ++ if (!_nExitIns) ++ codeAlloc(exitStart, exitEnd, _nExitIns verbose_only(, exitBytes)); ++ } ++ ++ void Assembler::nativePageReset() ++ {} ++ ++ void Assembler::nPatchBranch(NIns *branch, NIns *targ) ++ { ++// debug_only( printf("[nPatchBranch]: targ = %p\n",targ);) ++ //LUI ++ NanoAssert(((*branch) & (0x7ff<<21)) == (0x1e0<<21)); ++ *branch = ((*branch) & 0xffff0000) | ((uintptr_t)targ >> 16); ++ //ORI ++ NanoAssert(((branch[1]) & (0x3f<<26)) == (ORI_<<26)); ++ branch[1] = ((branch[1]) & 0xffff0000) | ((uintptr_t)targ & 0xffff); ++ ++ } ++ ++ Register Assembler::nRegisterAllocFromSet(RegisterMask set) ++ { ++ if (set & GpRegs) { ++ int i= R1; // skip R0 ++ while (!(set & rmask((Register)i))) ++ i ++; ++ _allocator.free &= ~rmask((Register)i); ++ return (Register) i; ++ } else { ++ int i= D0; ++ while (!(set & rmask((Register)i))) { ++#ifdef N32ABI ++ i ++; ++#else ++ i += 2; ++#endif ++ } ++ _allocator.free &= ~rmask((Register)i); ++ return (Register) i; ++ } ++ } ++ ++ void Assembler::nRegisterResetAll(RegAlloc ®s) ++ { ++ regs.clear(); ++ regs.free = allowGpRegs | allowFpRegs; ++ debug_only(regs.managed = regs.free); ++ } ++ ++#ifdef NANOJIT_64BIT ++ void Assembler::asm_qbinop(LIns *ins) ++ { ++ LOpcode op = ins->opcode(); ++ switch (op) { ++ case LIR_qiadd: ++ case LIR_qior: ++ case LIR_qiand: ++ case LIR_qilsh: ++ case LIR_qaddp: ++ case LIR_qursh: ++ case LIR_qirsh: ++ case LIR_qxor: ++ asm_arith(ins); ++ break; ++ default: ++ debug_only(outputf("%s",lirNames[op])); ++ TODO(asm_qbinop); ++ } ++ } ++ ++#endif // NANOJIT_64BIT ++ ++ /** ++ * copy 64 bits: (rd+dd) <- (rs+ds) ++ */ ++ void Assembler::asm_mmq(Register rd, int dd, Register rs, int ds) ++ { ++ // value is either a 64bit struct or maybe a float ++ // that isn't live in an FPU reg. Either way, don't ++ // put it in an FPU reg just to load & store it. ++ Register t = registerAllocTmp(allowGpRegs & ~(rmask(rd)|rmask(rs))); ++ NanoAssert (IsGpReg(rd) && IsGpReg(rs)); ++ ++ SDR(t,dd,rd); ++ SDL(t,(dd+7),rd); ++ LDR(t,ds,rs); ++ LDL(t,(ds+7),rs); ++ } ++ ++ verbose_only( ++ void Assembler::asm_inc_m32(uint32_t* pCtr) ++ { ++ Register t = registerAllocTmp(allowGpRegs); ++ Register t2 = registerAllocTmp(allowGpRegs&~rmask(t)); ++ SW(t2,0,t); ++ addiu(t2,t2,1); ++ LW(t2,0,t); ++ asm_li(t,(uint64_t)pCtr); ++ } ++ ) ++ ++ void Assembler::asm_jtbl(LIns* ins, NIns** native_table) ++ { ++ // R0 = index*4, R2 = table, CTR = computed address to jump to. ++ // must ensure no page breaks in here because R2 & CTR can get clobbered. ++ Register indexreg = findRegFor(ins->oprnd1(), allowGpRegs); ++ Register t = registerAllocTmp(allowGpRegs&~rmask(indexreg)); ++ Register t2 = registerAllocTmp(allowGpRegs&~rmask(t)); ++ ++ NOP(); ++ JR(t); ++ LW(t,0,t); ++ addiu(t,t,t2); ++ SLL(t2,indexreg,2); ++ asm_li(t, int32_t(native_table)); ++ ++ } ++ ++ void Assembler::swapCodeChunks() ++ { ++ SWAP(NIns*, _nIns, _nExitIns); ++ SWAP(NIns*, codeStart, exitStart); ++ SWAP(NIns*, codeEnd, exitEnd); ++ verbose_only( SWAP(size_t, codeBytes, exitBytes); ) ++ } ++ ++} // namespace nanojit ++ ++#endif // FEATURE_NANOJIT && NANOJIT_MIPS +diff -r 4c7acf580717 js/src/nanojit/NativeMips.h +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/js/src/nanojit/NativeMips.h Thu Dec 10 08:37:44 2009 +0800 +@@ -0,0 +1,579 @@ ++/* -*- Mode: C++; c-basic-offset: 4; indent-tabs-mode: nil; tab-width: 40 -*- */ ++/* ***** BEGIN LICENSE BLOCK ***** ++ * Version: MPL 1.1/GPL 2.0/LGPL 2.1 ++ * ++ * The contents of this file are subject to the Mozilla Public License Version ++ * 1.1 (the "License"); you may not use this file except in compliance with ++ * the License. You may obtain a copy of the License at ++ * http://www.mozilla.org/MPL/ ++ * ++ * Software distributed under the License is distributed on an "AS IS" basis, ++ * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License ++ * for the specific language governing rights and limitations under the ++ * License. ++ * ++ * The Original Code is [Open Source Virtual Machine]. ++ * ++ * The Initial Developer of the Original Code is ++ * Adobe System Incorporated. ++ * Portions created by the Initial Developer are Copyright (C) 2004-2007 ++ * the Initial Developer. All Rights Reserved. ++ * ++ * Contributor(s): ++ * Adobe AS3 Team ++ * Vladimir Vukicevic <vladimir@pobox.com> ++ * Zhou Shuchang <shuchang.zhou at gmail.com> ++ * Ling Kun <erlv5241 at gmail.com> ++ * ++ * Alternatively, the contents of this file may be used under the terms of ++ * either the GNU General Public License Version 2 or later (the "GPL"), or ++ * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), ++ * in which case the provisions of the GPL or the LGPL are applicable instead ++ * of those above. If you wish to allow use of your version of this file only ++ * under the terms of either the GPL or the LGPL, and not to allow others to ++ * use your version of this file under the terms of the MPL, indicate your ++ * decision by deleting the provisions above and replace them with the notice ++ * and other provisions required by the GPL or the LGPL. If you do not delete ++ * the provisions above, a recipient may use your version of this file under ++ * the terms of any one of the MPL, the GPL or the LGPL. ++ * ++ * ***** END LICENSE BLOCK ***** */ ++ ++ ++#ifndef __nanojit_NativeMips__ ++#define __nanojit_NativeMips__ ++ ++ ++#ifdef PERFM ++#include "../vprof/vprof.h" ++#define count_instr() _nvprof("mips",1) ++#define count_prolog() _nvprof("mips-prolog",1); count_instr(); ++#define count_imt() _nvprof("mips-imt",1) count_instr() ++#else ++#define count_instr() ++#define count_prolog() ++#define count_imt() ++#endif ++ ++#define PEDANTIC 0 ++#ifdef N32ABI ++#define NANOJIT_64BIT ++#endif ++ ++namespace nanojit ++{ ++ ++const int NJ_LOG2_PAGE_SIZE = 14; // 16K ++ ++#define NJ_MAX_REGISTERS 64 ++#define NJ_MAX_STACK_ENTRY 256 ++ ++#ifdef N32ABI ++#define NUMARGREGS 8 ++#define NUMFPARGREGS 8 ++#else ++#define NUMARGREGS 4 ++#define NUMFPARGREGS 2 ++#endif ++ ++#define NJ_MAX_PARAMETERS NUMARGREGS ++ ++#ifdef N32ABI ++#define NJ_ALIGN_STACK 16 //for N32 ++#else ++#define NJ_ALIGN_STACK 16 // be safe ++#endif ++const int NJ_STACK_OFFSET = 0; ++#define NJ_JTBL_SUPPORTED 1 ++ ++const int LARGEST_UNDERRUN_PROT = 32; // largest value passed to underrunProtect ++ ++typedef int NIns; ++ ++// Bytes of icache to flush after Assembler::patch ++const size_t LARGEST_BRANCH_PATCH = 2 * sizeof(NIns); ++ ++/* Mips registers */ ++typedef enum { ++ R0 = 0, ++ R1 = 1, ++ R2 = 2, ++ R3 = 3, ++ R4 = 4, ++ R5 = 5, ++ R6 = 6, ++ R7 = 7, ++ R8 = 8, ++ R9 = 9, ++ R10 = 10, ++ R11 = 11, ++ R12 = 12, ++ R13 = 13, ++ R14 = 14, ++ R15 = 15, ++ R16 = 16, ++ R17 = 17, ++ R18 = 18, ++ R19 = 19, ++ R20 = 20, ++ R21 = 21, ++ R22 = 22, ++ R23 = 23, ++ R24 = 24, ++ R25 = 25, ++ //26 and 27 are reserved for kernel ++ GP = 28, ++ SP = 29, ++ FP = 30, ++ RA = 31, ++ R28 = GP, ++ R29 = SP, ++ R30 = FP, ++ R31 = RA, ++ ++ // FP regs ++ D0 = 32, ++ D1 = 33, ++ D2 = 34, ++ D3 = 35, ++ D4 = 36, ++ D5 = 37, ++ D6 = 38, ++ D7 = 39, ++ D8 = 40, ++ D9 = 41, ++ D10 = 42, ++ D11 = 43, ++ D12 = 44, ++ D13 = 45, ++ D14 = 46, ++ D15 = 47, ++ D16 = 48, ++ D17 = 49, ++ D18 = 50, ++ D19 = 51, ++ D20 = 52, ++ D21 = 53, ++ D22 = 54, ++ D23 = 55, ++ D24 = 56, ++ D25 = 57, ++ D26 = 58, ++ D27 = 59, ++ D28 = 60, ++ D29 = 61, ++ D30 = 62, ++ D31 = 63, ++ FirstFloatReg = 32, ++ LastFloatReg = 63, ++ FirstReg = 0, ++ LastReg = 63, ++ UnknownReg = 64 ++ ++} Register; ++ ++typedef unsigned long long RegisterMask; ++ ++static const RegisterMask SavedFpRegs = 0x5555000000000000LL; ++static const RegisterMask SavedRegs = 0xff0000; ++ ++static const int NumSavedRegs = 8; ++ ++static const RegisterMask FpRegs = 0xffffffff00000000LL; ++static const RegisterMask GpRegs = 0xffffffff; ++static const RegisterMask AllowableFlagRegs = 0x3fffffe; ++ ++static inline bool isValidDisplacement(LOpcode , int32_t d) { ++ return isS16(d); ++} ++ ++#define IsFpReg(_r) ((rmask((Register)_r) & (FpRegs)) != 0) ++#define IsGpReg(_r) ((rmask((Register)_r) & (GpRegs)) != 0) ++#define FpRegNum(_fpr) ((_fpr) - FirstFloatReg) ++ ++// only good for normal regs ++#define imm2register(c) (Register)(c-1) ++ ++verbose_only( extern const char* regNames[]; ) ++ ++#define DECLARE_PLATFORM_STATS() ++ ++#define DECLARE_PLATFORM_REGALLOC() ++ ++#define DECLARE_PLATFORM_ASSEMBLER() \ ++ const static Register argRegs[NUMARGREGS], retRegs[2]; \ ++ const static Register fpArgRegs[NUMFPARGREGS], retFpRegs[2]; \ ++ void addiu(Register dst,Register src,int32_t imm); \ ++ void check_is_sign_extend(Register r); \ ++ void nativePageReset(); \ ++ void nativePageSetup(); \ ++ void underrunProtect(int bytes); \ ++ void asm_CC0(Register); \ ++ void asm_li(Register,int32_t); \ ++ void asm_li32(Register,int32_t); \ ++ void asm_li64(Register,uint64_t); \ ++ void asm_save_word(Register value, int32_t dr, Register base); \ ++ void asm_save_dword(Register value, int32_t dr, Register base); \ ++ void asm_qbinop(LIns *); \ ++ void asm_regarg(ArgSize, LInsp, Register); \ ++ void asm_stkarg(LInsp arg, int stkd); \ ++ void asm_fcmp(LIns *cond);\ ++ void asm_cmp(Register r,LIns *cond, bool flipped); \ ++ void asm_set_cc(Register); \ ++ int max_param_size; ++ ++// The trailing FUNCT part ++typedef enum { ++ ADDU_=0x21, ++ SUBU_=0x23, ++ AND_= 0x24, ++ OR_= 0x25, ++ XOR_= 0x26, ++ NOR_= 0x27, ++ SLT_= 0x2a, ++ SLTU_= 0x2b, ++ DADDU_= 0x2d, ++ DSUBU_= 0x2f, ++ ++ DMULT_= 0x1c, ++ DDIV_= 0x1e, ++ ++ SLL_=0x0, ++ SRL_=0x2, ++ SRA_=0x3, ++ SLLV_=0x4, ++ SRLV_=0x6, ++ SRAV_=0x7, ++ DSLLV_= 0x14, ++ DSRLV_= 0x16, ++ DSRAV_= 0x17, ++ DSLL_= 0x38, ++ DSRL_= 0x3a, ++ DSRA_= 0x3b, ++ DSLL32_= 0x3c, ++ DSRL32_= 0x3e, ++ DSRA32_= 0x3f, ++ MOVN_ = 0xb, ++ MOVZ_ = 0xa, ++ ++ JR_ = 0x8, ++ JALR_ = 0x9, ++ ++ MFHI_ = 0x10, ++ MFLO_ = 0x12 ++ ++#ifdef LOONGSON2F ++ DMULTG_ = 0x11, ++ MULTUG_ = 0x12, ++ DMULTUG_ = 0x13, ++ DIVUG_ = 0x16, ++ DDIVUG_ = 0x17, ++ MODUG_ = 0x1e, ++ DMODUG_ = 0x1f ++#endif ++} func_mips; ++ ++typedef enum { ++ SLTI_= 0xa, ++ SLTIU_= 0xb, ++ ANDI_= 0xc, ++ ORI_= 0xd, ++ XORI_= 0xe, ++ LUI_= 0xf, ++// DADDI_ = 0x18, ++ DADDIU_ = 0x19, ++ ADDIU_ = 0x9, ++ ++ LDL_= 0x1a, ++ LDR_= 0x1b, ++ LB_= 0x20, ++ LH_= 0x21, ++ LW_= 0x23, ++ LBU_= 0x24, ++ LHU_= 0x25, ++ LWU_= 0x27, ++ SWL_= 0x2a, ++ SW_= 0x2b, ++ SDL_= 0x2c, ++ SDR_= 0x2d, ++ SWR_= 0x2e, ++ LDC1_= 0x35, ++ LD_= 0x37, ++ SDC1_ = 0x3d, ++ SD_= 0x3f, ++ ++ BEQ_ = 0x4, ++ BNE_ = 0x5, ++ ++ J_ = 0x2, ++ JAL_ = 0x3, ++ ++ COP1_ = 0x11 ++} special_mips; ++ ++inline bool isLoadStore(int op) ++{ ++ return (op==LDL_)||(op==LDR_)||(op>=LB_ && op<=SWR_) ||(op>=LDC1_ && op<=SD_); ++} ++ ++inline bool isU5(int imm) ++{ ++ return ((imm&0x1f)==imm); ++} ++ ++inline bool isU26(int imm) ++{ ++ return ((imm&0x3ffffff)==imm); ++} ++ ++#define formatI_may_chk(op, rs1, rs2, imm,chk) do {\ ++ if(chk) underrunProtect(4);\ ++ NanoAssert(IsGpReg(rs1) && IsGpReg(rs2));\ ++ NanoAssert(isS16(imm));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (rs1)<<21 | (rs2)<<16 | (uint32_t(imm)&0xffff));\ ++ if (isLoadStore(op)) {\ ++ asm_output("%s %s,%d(%s)", #op, gpn(rs2), (imm), gpn(rs1));\ ++ }\ ++ else {\ ++ asm_output("%s %s,%s,%d", #op, gpn(rs2), gpn(rs1), (imm));\ ++ }\ ++ } while (0) ++#define formatI_U16_may_chk(op, rs1, rs2, imm,chk) do {\ ++ if(chk) underrunProtect(4);\ ++ NanoAssert(IsGpReg(rs1) && IsGpReg(rs2));\ ++ NanoAssert(isU16(imm));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (rs1)<<21 | (rs2)<<16 | (imm));\ ++ asm_output("%s %s,%s,0x%x", #op, gpn(rs2), gpn(rs1), (imm));\ ++} while (0) ++ ++#define formatI(op,rs1,rs2,imm) formatI_may_chk(op, rs1, rs2, imm, 1) ++#define formatI_nochk(op,rs1,rs2,imm) formatI_may_chk(op, rs1, rs2, imm, 0) ++#define formatI_U16(op,rs1,rs2,imm) formatI_U16_may_chk(op, rs1, rs2, imm, 1) ++#define formatI_U16_nochk(op,rs1,rs2,imm) formatI_U16_may_chk(op, rs1, rs2, imm, 0) ++#define formatI_F(op, base, ft, imm) do {\ ++ underrunProtect(4);\ ++ NanoAssert(IsGpReg(base) && IsFpReg(ft));\ ++ NanoAssert(isS16(imm));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (base)<<21 | ((ft)-32)<<16 | (uint32_t(imm)&0xffff));\ ++ asm_output("%s %s,%d(%s)", #op, fpn(ft), (imm), gpn(base));\ ++} while (0) ++ ++#define formatR(op, rs, rt, rd, sa, funct) formatR_may_chk(op, rs, rt, rd, sa, funct,1) ++#define formatR_nochk(op, rs, rt, rd, sa, funct) formatR_may_chk(op, rs, rt, rd, sa, funct,0) ++#define formatR_may_chk(op, rs, rt, rd, sa, funct,chk) do {\ ++ if (chk) underrunProtect(4);\ ++ NanoAssert(IsGpReg(rs) && IsGpReg(rt) && IsGpReg(rd));\ ++ NanoAssert(isU5(sa));\ ++ NanoAssert((op==0));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (rs)<<21 | (rt)<<16 | (rd)<<11 | (sa)<<6 | (funct));\ ++ asm_output("%s %s,%s,%s", #funct, gpn(rd), gpn(rs), gpn(rt));\ ++ } while (0) ++#define formatR_G(op, rs, rt, rd, sa, funct) do {\ ++ underrunProtect(4);\ ++ NanoAssert(IsGpReg(rs) && IsGpReg(rt) && IsGpReg(rd));\ ++ NanoAssert(sa==0);\ ++ NanoAssert((op==0x1c));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (rs)<<21 | (rt)<<16 | (rd)<<11 | (sa)<<6 | (funct));\ ++ asm_output("%s %s,%s,%s", #funct, gpn(rd), gpn(rs), gpn(rt));\ ++} while (0) ++#define formatShift_may_chk(op, rs, rt, rd, sa, funct, chk) do {\ ++ if(chk) underrunProtect(4);\ ++ NanoAssert((rs)==0);\ ++ NanoAssert(isU5(sa));\ ++ NanoAssert(op==0);\ ++ NanoAssert(IsGpReg(rt) && IsGpReg(rd));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (rt)<<16 | (rd)<<11 | (sa)<<6 | (funct));\ ++ asm_output("%s %s,%s,%d", #funct, gpn(rd), gpn(rt), sa);\ ++ } while (0) ++#define formatShiftV_may_chk(op, rs, rt, rd, sa, funct, chk) do {\ ++ if(chk) underrunProtect(4);\ ++ NanoAssert((sa)==0);\ ++ NanoAssert(isU5(sa));\ ++ NanoAssert(op==0);\ ++ NanoAssert(IsGpReg(rs) && IsGpReg(rt) && IsGpReg(rd));\ ++ *(--_nIns) = (NIns) ((op)<<26 | (rs)<<21 | (rt)<<16 | (rd)<<11 | (sa)<<6 | (funct));\ ++ asm_output("%s %s,%s,%s", #funct, gpn(rd), gpn(rt), gpn(rs));\ ++} while (0) ++#define formatShiftV(op,rs,rt,rd,sa,funct) formatShiftV_may_chk(op,rs,rt,rd,sa,funct,1) ++#define formatShift(op, rs, rt, rd, sa, funct) formatShift_may_chk(op, rs, rt, rd, sa, funct, 1) ++#define formatShift_nochk(op, rs, rt, rd, sa, funct) formatShift_may_chk(op, rs, rt, rd, sa, funct, 0) ++#define formatJ_may_chk(chk,op, target) do {\ ++ if (chk) underrunProtect(4);\ ++ NanoAssert(isU26(target));\ ++ *(--_nIns) = (NIns) ((op)<<26| (target));\ ++ asm_output("%s 0x%x", #op, (target));\ ++ } while (0) ++#define formatJ_nochk(op,target) formatJ_may_chk(0,op,target) ++#define formatJ(op,target) formatJ_may_chk(1,op,target) ++#define formatIns1(code, str, rt) do{\ ++ underrunProtect(4);\ ++ NanoAssert(IsGpReg(rt));\ ++ *(--_nIns) = (NIns) (code);\ ++ asm_output("%s %s", #str, gpn(rt));\ ++ } while (0) ++#define formatIns2_G_F(code, str, rt, fs) do{\ ++ underrunProtect(4);\ ++ NanoAssert(IsGpReg(rt) && IsFpReg(fs));\ ++ *(--_nIns) = (NIns) (code);\ ++ asm_output("%s %s,%s", #str, gpn(rt), fpn(fs));\ ++ } while (0) ++#define formatIns2_F_F(code, str, fs, ft) do{\ ++ underrunProtect(4);\ ++ NanoAssert(IsFpReg(fs) && IsFpReg(ft));\ ++ *(--_nIns) = (NIns) (code);\ ++ asm_output("%s %s,%s", #str, fpn(ft), fpn(fs));\ ++} while (0) ++#define formatIns3(code, str, fs, ft, fd) do{\ ++ underrunProtect(4);\ ++ NanoAssert(IsFpReg(fs) && IsFpReg(ft) && IsFpReg(fd));\ ++ *(--_nIns) = (NIns) (code);\ ++ asm_output("%s %s,%s,%s", #str, fpn(fd), fpn(fs), fpn(ft));\ ++ } while (0) ++ ++#define AND(rd,rs,rt) formatR(0,rs,rt,rd,0,AND_) ++#define OR(rd,rs,rt) formatR(0,rs,rt,rd,0,OR_) ++#define MR(rd,rs) OR(rd,rs,0) ++#define MOV(rd,rs) OR(rd,rs,0) ++#define XOR(rd,rs,rt) formatR(0,rs,rt,rd,0,XOR_) ++#define NOR(rd,rs,rt) formatR(0,rs,rt,rd,0,NOR_) ++#define SLT(rd,rs,rt) formatR(0,rs,rt,rd,0,SLT_) ++#define SGT(rd,rs,rt) SLT(rd,rt,rs) ++#define SLTU(rd,rs,rt) formatR(0,rs,rt,rd,0,SLTU_) ++#define SGTU(rd,rs,rt) SLTU(rd,rt,rs) ++#define ADDU(rd,rs,rt) formatR(0,rs,rt,rd,0,ADDU_) ++#define SUBU(rd,rs,rt) formatR(0,rs,rt,rd,0,SUBU_) ++#define DADDU(rd,rs,rt) formatR(0,rs,rt,rd,0,DADDU_) ++#define DSUBU(rd,rs,rt) formatR(0,rs,rt,rd,0,DSUBU_) ++#define NEG(rd,rt) DSUBU(rd,0,rt) ++ ++#define DMULT(rs,rt) formatR(0,rs,rt,0,0,DMULT_) ++#define DDIV(rs,rt) formatR(0,rs,rt,0,0,DDIV_) ++#define MFHI(rd) formatR(0,0,0,rd,0,MFHI_) ++#define MFLO(rd) formatR(0,0,0,rd,0,MFLO_) ++ ++#define MOVZ(rd,rs,rt) formatR(0,rs,rt,rd,0,MOVZ_) ++#define MOVN(rd,rs,rt) formatR(0,rs,rt,rd,0,MOVN_) ++#define JR(rs) formatR(0,rs,0,0,0,JR_) ++#define JR_nochk(rs) formatR_nochk(0,rs,0,0,0,JR_) ++#define JALR(rd,rs) formatR(0,rs,0,rd,0,JALR_) ++ ++#define SLL(rd,rt,sa) formatShift(0,0,rt,rd,sa,SLL_) ++#define SRA(rd,rt,sa) formatShift(0,0,rt,rd,sa,SRA_) ++#define SRL(rd,rt,sa) formatShift(0,0,rt,rd,sa,SRL_) ++#define DSRL(rd,rt,sa) formatShift(0,0,rt,rd,sa,DSRL_) ++#define DSRA(rd,rt,sa) formatShift(0,0,rt,rd,sa,DSRA_) ++#define DSLL(rd,rt,sa) formatShift(0,0,rt,rd,sa,DSLL_) ++#define DSRL32(rd,rt,sa) formatShift(0,0,rt,rd,sa,DSRL32_) ++#define DSRA32(rd,rt,sa) formatShift(0,0,rt,rd,sa,DSRA32_) ++#define DSLL32(rd,rt,sa) formatShift(0,0,rt,rd,sa,DSLL32_) ++#define DSLLV(rd,rt,rs) formatShiftV(0,rs,rt,rd,0,DSLLV_) ++#define DSRAV(rd,rt,rs) formatShiftV(0,rs,rt,rd,0,DSRAV_) ++#define DSRLV(rd,rt,rs) formatShiftV(0,rs,rt,rd,0,DSRLV_) ++#define SLLV(rd,rt,rs) formatShiftV(0,rs,rt,rd,0,SLLV_) ++#define SRAV(rd,rt,rs) formatShiftV(0,rs,rt,rd,0,SRAV_) ++#define SRLV(rd,rt,rs) formatShiftV(0,rs,rt,rd,0,SRLV_) ++#define NOP() SLL(0,0,0) ++#define NOP_nochk() formatShift_nochk(0,0,0,0,0,SLL_) ++ ++#ifdef LOONGSON2F ++#define DMULTG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,DMULTG_) ++#define MULTUG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,MULTUG_) ++#define DMULTUG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,DMULTUG_) ++#define DIVUG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,DIVUG_) ++#define DDIVUG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,DDIVUG_) ++#define MODUG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,MODUG_) ++#define DMODUG(rd,rs,rt) formatR_G(0x1c,rs,rt,rd,0,DMODUG_) ++#endif ++ ++#define JAL(addr) formatJ(JAL_,(((int)addr)>>2)& 0x3ffffff) ++#define JAL_nochk(addr) formatJ_nochk(JAL_,(((int)addr)>>2)& 0x3ffffff) ++#define J(addr) formatJ(J_,(((int)addr)>>2)& 0x3ffffff) ++#define J_nochk(addr) formatJ_nochk(J_,(((int)addr)>>2)& 0x3ffffff) ++ ++// The pc-relative length to skip a JMP ++#define JMP_LENGTH 4 ++ ++//TODO JMP requires a sratch register ++#define JMP(addr) do { \ ++ unsigned int u = (unsigned int)addr; \ ++ underrunProtect(4*JMP_LENGTH);\ ++ NOP_nochk();\ ++ JR_nochk(R31);\ ++ ORI_nochk(R31,R31,u&0xffff);\ ++ LUI_nochk(R31,u>>16); \ ++ } while (0) ++#define JMP_nochk(addr) do { \ ++ unsigned int u = (unsigned int)addr; \ ++ NOP_nochk();\ ++ JR_nochk(R31);\ ++ ORI_nochk(R31,R31,u&0xffff);\ ++ LUI_nochk(R31,u>>16); \ ++} while (0) ++ ++#define ORI(rt,rs,imm) formatI_U16(ORI_,rs,rt,imm) ++#define ORI_nochk(rt,rs,imm) formatI_U16_nochk(ORI_,rs,rt,imm) ++#define ANDI(rt,rs,imm) formatI_U16(ANDI_,rs,rt,imm) ++#define XORI(rt,rs,imm) formatI_U16(XORI_,rs,rt,imm) ++ ++#define LUI(rt,imm) formatI_U16(LUI_,0,rt,imm) ++#define LUI_nochk(rt,imm) formatI_U16_nochk(LUI_,0,rt,imm) ++// #define DADDI(rt,rs,imm) formatI(DADDI_,rs,rt,((unsigned int)imm)&0xffff) ++#define DADDIU(rt,rs,imm) formatI(DADDIU_,rs,rt,imm) ++#define ADDIU(rt,rs,imm) formatI(ADDIU_,rs,rt,imm) ++ ++#define SLTI(rt,rs,imm) formatI(SLTI_,rs,rt,imm) ++#define SLTIU(rt,rs,imm) formatI(SLTIU_,rs,rt,imm) ++ ++#define LB(rt,offset,base) formatI(LB_,base,rt,offset) ++#define LH(rt,offset,base) formatI(LH_,base,rt,offset) ++#define LW(rt,offset,base) formatI(LW_,base,rt,offset) ++#define LBU(rt,offset,base) formatI(LBU_,base,rt,offset) ++#define LHU(rt,offset,base) formatI(LHU_,base,rt,offset) ++#define LWU(rt,offset,base) formatI(LWU_,base,rt,offset) ++#define LD(rt,offset,base) formatI(LD_,base,rt,offset) ++#define LDC1(ft,offset,base) formatI_F(LDC1_,base,ft,offset) ++#define LDL(rt,offset,base) formatI(LDL_,base,rt,offset) ++#define LDR(rt,offset,base) formatI(LDR_,base,rt,offset) ++#define SW(rt,offset,base) formatI(SW_,base,rt,offset) ++#define SWL(rt,offset,base) formatI(SWL_,base,rt,offset) ++#define SWR(rt,offset,base) formatI(SWR_,base,rt,offset) ++#define SD(rt,offset,base) formatI(SD_,base,rt,offset) ++#define SDL(rt,offset,base) formatI(SDL_,base,rt,offset) ++#define SDR(rt,offset,base) formatI(SDR_,base,rt,offset) ++#define SDC1(ft,offset,base) formatI_F(SDC1_,base,ft,offset) ++ ++#define BEQ(rs,rt,offset) formatI(BEQ_,rs,rt,offset) ++#define BEQ_nochk(rs,rt,offset) formatI_nochk(BEQ_,rs,rt,offset) ++#define BNE(rs,rt,offset) formatI(BNE_,rs,rt,offset) ++#define BNE_nochk(rs,rt,offset) formatI_nochk(BNE_,rs,rt,offset) ++#define BC1T(offset) formatI(COP1_,8,1,offset) ++#define BC1T_nochk(offset) formatI_nochk(COP1_,8,1,offset) ++#define BC1F(offset) formatI(COP1_,8,0,offset) ++#define BC1F_nochk(offset) formatI_nochk(COP1_,8,0,offset) ++ ++#define DMFC1(rt,fs) formatIns2_G_F((0x44200000| rt<<16| ((fs)-32)<<11),DMFC1,rt,fs) ++#define MFC1(rt,fs) formatIns2_G_F((0x44000000| rt<<16| ((fs)-32)<<11),MFC1,rt,fs) ++#define DMTC1(rt,fs) formatIns2_G_F((0x44a00000| rt<<16| ((fs)-32)<<11),DMTC1,rt,fs) ++#define MTC1(rt,fs) formatIns2_G_F((0x44800000| rt<<16| ((fs)-32)<<11),MTC1,rt,fs) ++ ++#define C_EQ_D(fs,ft) formatIns2_F_F(((0x46200032)| (((ft)-32)<<16)|(((fs)-32)<<11)),C.EQ.D,fs,ft) ++// #define C_UN_D(fs,ft) formatIns2_F_F(((0x46200031)| (((ft)-32)<<16)|(((fs)-32)<<11)),"c.un.d",fs,ft) ++#define C_LT_D(fs,ft) formatIns2_F_F(((0x4620003c)| (((ft)-32)<<16)|(((fs)-32)<<11)),C.LT.D,fs,ft) ++#define C_GT_D(fs,ft) C_LT_D(ft,fs) ++#define C_LE_D(fs,ft) formatIns2_F_F(((0x4620003e)| (((ft)-32)<<16)|(((fs)-32)<<11)),C.LE.D,fs,ft) ++#define C_GE_D(fs,ft) C_LE_D(ft,fs) ++ ++#define MOV_D(fd,fs) formatIns2_F_F(((0x46200006)| (((fs)-32)<<11)|(((fd)-32)<<6)),MOV.D,fs,fd) ++#define NEG_D(fd,fs) formatIns2_F_F(((0x46200007)| (((fs)-32)<<11)|(((fd)-32)<<6)),NEG.D,fs,fd) ++#define CVT_D_W(fd,fs) formatIns2_F_F(((0x46800021)| (((fs)-32)<<11)|(((fd)-32)<<6)),CVT.D.W,fs,fd) ++#define CVT_D_L(fd,fs) formatIns2_F_F(((0x46a00021)| (((fs)-32)<<11)|(((fd)-32)<<6)),CVT.D.L,fs,fd) ++ ++#define ADD_D(fd,fs,ft) formatIns3(((0x46200000)| (((ft)-32)<<16)|(((fs)-32)<<11)|(((fd)-32)<<6)),ADD.D,fs,ft,fd) ++#define SUB_D(fd,fs,ft) formatIns3(((0x46200001)| (((ft)-32)<<16)|(((fs)-32)<<11)|(((fd)-32)<<6)),SUB.D,fs,ft,fd) ++#define MUL_D(fd,fs,ft) formatIns3(((0x46200002)| (((ft)-32)<<16)|(((fs)-32)<<11)|(((fd)-32)<<6)),MUL.D,fs,ft,fd) ++#define DIV_D(fd,fs,ft) formatIns3(((0x46200003)| (((ft)-32)<<16)|(((fs)-32)<<11)|(((fd)-32)<<6)),DIV.D,fs,ft,fd) ++ ++#define READFCR(rt) formatIns1(((0x44400000)| ((rt)<<16) | (31<<11)),"CFC1 31,",rt) ++#define WRITEFCR(rt) formatIns1(((0x44c00000)| ((rt)<<16) | (31<<11)),"CTC1 31,",rt) ++} ++#endif // __nanojit_NativeMips__ +diff -r 4c7acf580717 js/src/nanojit/nanojit.h +--- a/js/src/nanojit/nanojit.h Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/nanojit/nanojit.h Thu Dec 10 08:37:44 2009 +0800 +@@ -54,6 +54,8 @@ + #define NANOJIT_SPARC + #elif defined AVMPLUS_AMD64 + #define NANOJIT_X64 ++#elif defined AVMPLUS_MIPS ++ #define NANOJIT_MIPS + #else + #error "unknown nanojit architecture" + #endif +diff -r 4c7acf580717 js/src/trace-test/tests/basic/jitstatsArchFlags.js +--- a/js/src/trace-test/tests/basic/jitstatsArchFlags.js Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/trace-test/tests/basic/jitstatsArchFlags.js Thu Dec 10 08:37:44 2009 +0800 +@@ -9,6 +9,7 @@ + jitstats.archIsARM || + jitstats.archIsSPARC || + jitstats.archIsPPC || ++ jitstats.archIsMIPS || + jitstats.archIsAMD64, + 1); + } +diff -r 4c7acf580717 js/src/trace-test/tests/basic/testEliminatedGuardWithinAnchor.js +--- a/js/src/trace-test/tests/basic/testEliminatedGuardWithinAnchor.js Sat Dec 05 06:58:42 2009 +1100 ++++ b/js/src/trace-test/tests/basic/testEliminatedGuardWithinAnchor.js Thu Dec 10 08:37:44 2009 +0800 +@@ -7,6 +7,6 @@ + + if (HAVE_TM) { + checkStats({ +- sideExitIntoInterpreter: (jitstats.archIsARM ? 1 : 3) ++ sideExitIntoInterpreter: (jitstats.archIsARM || jitstats.archIsMIPS? 1 : 3) + }); + } diff --git a/www-client/mozilla-firefox/mozilla-firefox-3.6_beta4.ebuild b/www-client/mozilla-firefox/mozilla-firefox-3.6_beta4.ebuild new file mode 100644 index 0000000..c6e590c --- /dev/null +++ b/www-client/mozilla-firefox/mozilla-firefox-3.6_beta4.ebuild @@ -0,0 +1,205 @@ +# Copyright 1999-2009 Gentoo Foundation +# Distributed under the terms of the GNU General Public License v2 +# $Header: /var/cvsroot/gentoo-x86/www-client/mozilla-firefox/mozilla-firefox-3.5.3.ebuild,v 1.2 2009/09/13 11:58:22 nirbheek Exp $ +EAPI="2" +WANT_AUTOCONF="2.1" + +inherit flag-o-matic toolchain-funcs eutils mozconfig-3 makeedit multilib pax-utils fdo-mime autotools + +XUL_PV="1.9.2_beta4" +MAJ_XUL_PV="1.9.2" +MAJ_PV="${PV/_*/}" # Without the _rc and _beta stuff +DESKTOP_PV="3.6" +MY_PV="${PV/_beta/b}" # Handle beta for SRC_URI +PATCH="${PN}-3.6-patches-0.3" + +DESCRIPTION="Firefox Web Browser" +HOMEPAGE="http://www.mozilla.com/firefox" + +KEYWORDS="~alpha ~amd64 ~arm ~hppa ~ia64 ~ppc ~ppc64 -sparc ~x86" +SLOT="0" +LICENSE="|| ( MPL-1.1 GPL-2 LGPL-2.1 )" +IUSE="+alsa bindist java libnotify mozdevelop sqlite +networkmanager" + +REL_URI="http://releases.mozilla.org/pub/mozilla.org/firefox/releases" +SRC_URI="http://dev.gentoo.org/~anarchy/dist/firefox-${MY_PV}.source.tar.bz2 + http://dev.gentoo.org/~anarchy/dist/${PATCH}.tar.bz2" + +RDEPEND=" + >=sys-devel/binutils-2.16.1 + >=dev-libs/nss-3.12.4 + >=dev-libs/nspr-4.8 + >=app-text/hunspell-1.2 + sqlite? ( >=dev-db/sqlite-3.6.10 ) + alsa? ( media-libs/alsa-lib ) + >=net-libs/xulrunner-${XUL_PV}[java=,sqlite=] + >=x11-libs/cairo-1.8.8[X] + x11-libs/pango[X] + networkmanager? ( net-wireless/wireless-tools ) + libnotify? ( >=x11-libs/libnotify-0.4 ) + ~net-libs/xulrunner-${XUL_PV}[java=,networkmanager=,libnotify=,mozdevelop=]" + +DEPEND="${RDEPEND} + dev-util/pkgconfig" + +S="${WORKDIR}/mozilla-1.9.2" + +pkg_setup() { + if ! use bindist ; then + einfo + elog "You are enabling official branding. You may not redistribute this build" + elog "to any users on your network or the internet. Doing so puts yourself into" + elog "a legal problem with Mozilla Foundation" + elog "You can disable it by emerging ${PN} _with_ the bindist USE-flag" + fi +} + +src_prepare() { + # Apply our patches + EPATCH_SUFFIX="patch" \ + EPATCH_FORCE="yes" \ + epatch "${WORKDIR}" + + eautoreconf + + cd "${S}" + epatch "${FILESDIR}/mips-nanojit.patch" + + cd js/src + eautoreconf + + cd "${S}" + # We need to re-patch this because autoreconf overwrites it + epatch "${FILESDIR}/000_flex-configure-LANG.patch" +} + +src_configure() { + MOZILLA_FIVE_HOME="/usr/$(get_libdir)/${PN}" + MEXTENSIONS="default" + + #################################### + # + # mozconfig, CFLAGS and CXXFLAGS setup + # + #################################### + + mozconfig_init + mozconfig_config + + # It doesn't compile on alpha without this LDFLAGS + use alpha && append-ldflags "-Wl,--no-relax" + + mozconfig_annotate '' --enable-extensions="${MEXTENSIONS}" + mozconfig_annotate '' --enable-application=browser + mozconfig_annotate '' --disable-mailnews + mozconfig_annotate 'broken' --disable-crashreporter + mozconfig_annotate '' --enable-image-encoder=all + mozconfig_annotate '' --enable-canvas + mozconfig_annotate 'gtk' --enable-default-toolkit=cairo-gtk2 + # Bug 60668: Galeon doesn't build without oji enabled, so enable it + # regardless of java setting. + mozconfig_annotate '' --enable-oji --enable-mathml + mozconfig_annotate 'places' --enable-storage --enable-places + mozconfig_annotate '' --enable-safe-browsing + + # System-wide install specs + mozconfig_annotate '' --disable-installer + mozconfig_annotate '' --disable-updater + mozconfig_annotate '' --disable-strip + mozconfig_annotate '' --disable-install-strip + + # Use system libraries + mozconfig_annotate '' --enable-system-cairo + mozconfig_annotate '' --enable-system-hunspell + mozconfig_annotate '' --with-system-nspr + mozconfig_annotate '' --with-system-nss + mozconfig_annotate '' --enable-system-lcms + mozconfig_annotate '' --with-system-bz2 + mozconfig_annotate '' --with-system-libxul + mozconfig_annotate '' --with-libxul-sdk=/usr/$(get_libdir)/xulrunner-devel-${MAJ_XUL_PV} + + mozconfig_use_enable sqlite system-sqlite + mozconfig_use_enable libnotify + mozconfig_use_enable java javaxpcom + mozconfig_use_enable networkmanager necko-wifi + mozconfig_use_enable mozdevelop jsd + mozconfig_use_enable mozdevelop xpctools + mozconfig_use_enable alsa ogg + mozconfig_use_enable alsa wave + + # Other ff-specific settings + mozconfig_annotate '' --with-default-mozilla-five-home=${MOZILLA_FIVE_HOME} + + # Enable/Disable audio in firefox + mozconfig_use_enable alsa ogg + mozconfig_use_enable alsa wave + + if ! use bindist ; then + mozconfig_annotate '' --enable-official-branding + fi + + # Finalize and report settings + mozconfig_final + + if [[ $(gcc-major-version) -lt 4 ]]; then + append-cxxflags -fno-stack-protector + fi + + #################################### + # + # Configure and build + # + #################################### + + CC="$(tc-getCC)" CXX="$(tc-getCXX)" LD="$(tc-getLD)" econf +} + +src_compile() { + # Should the build use multiprocessing? Not enabled by default, as it tends to break + [ "${WANT_MP}" = "true" ] && jobs=${MAKEOPTS} || jobs="-j1" + emake ${jobs} || die +} + +src_install() { + MOZILLA_FIVE_HOME="/usr/$(get_libdir)/${PN}" + + emake DESTDIR="${D}" install || die "emake install failed" + + # Install icon and .desktop for menu entry + if ! use bindist ; then + newicon "${S}"/other-licenses/branding/firefox/content/icon48.png firefox-icon.png + newmenu "${FILESDIR}"/icon/mozilla-firefox-1.5.desktop \ + ${PN}-${DESKTOP_PV}.desktop + else + newicon "${S}"/browser/base/branding/icon48.png firefox-icon-unbranded.png + newmenu "${FILESDIR}"/icon/mozilla-firefox-1.5-unbranded.desktop \ + ${PN}-${DESKTOP_PV}.desktop + sed -i -e "s:Bon Echo:Shiretoko:" \ + "${D}"/usr/share/applications/${PN}-${DESKTOP_PV}.desktop || die "sed failed!" + fi + + # Add StartupNotify=true bug 237317 + if use startup-notification ; then + echo "StartupNotify=true" >> "${D}"/usr/share/applications/${PN}-${DESKTOP_PV}.desktop + fi + + pax-mark m "${D}"/${MOZILLA_FIVE_HOME}/firefox + + # Enable very specific settings not inherited from xulrunner + cp "${FILESDIR}"/firefox-default-prefs.js \ + "${D}/${MOZILLA_FIVE_HOME}/defaults/preferences/all-gentoo.js" || \ + die "failed to cp firefox-default-prefs.js" + + # Plugins dir + dosym ../nsbrowser/plugins "${MOZILLA_FIVE_HOME}"/plugins \ + || die "failed to symlink" +} + +pkg_postinst() { + ewarn "All the packages built against ${PN} won't compile," + ewarn "any package that fails to build warrants a bug report." + elog + + # Update mimedb for the new .desktop file + fdo-mime_desktop_database_update +} |