summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZhang Le <r0bertz@gentoo.org>2009-12-17 09:57:25 +0800
committerZhang Le <r0bertz@gentoo.org>2009-12-17 09:57:25 +0800
commitb705d5849e115464e78f1795fba68af174ff1462 (patch)
tree8e8c07b4baf09fb777a8100d88af65040d47d827 /www-client
parentadded xulrunner-1.9.2_beta4.ebuild (diff)
downloadloongson-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')
-rw-r--r--www-client/mozilla-firefox/Manifest9
-rw-r--r--www-client/mozilla-firefox/files/000_flex-configure-LANG.patch41
-rw-r--r--www-client/mozilla-firefox/files/firefox-default-prefs.js2
-rw-r--r--www-client/mozilla-firefox/files/icon/iceweasel.desktop9
-rw-r--r--www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5-unbranded.desktop9
-rw-r--r--www-client/mozilla-firefox/files/icon/mozilla-firefox-1.5.desktop9
-rw-r--r--www-client/mozilla-firefox/files/mips-nanojit.patch2222
-rw-r--r--www-client/mozilla-firefox/mozilla-firefox-3.6_beta4.ebuild205
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 &regs)
++ {
++ 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
+}