mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Implemented side exits in the x64 backend, and merged in tamarin-redux changes (bug 514537, r=gal).
This commit is contained in:
parent
ea4545c24a
commit
19e6272d43
@ -41,6 +41,18 @@
|
||||
#ifndef __nanojit_Native__
|
||||
#define __nanojit_Native__
|
||||
|
||||
// define PEDANTIC=1 to ignore specialized forms, force general forms
|
||||
// for everything, far branches, extra page-linking, etc. This will
|
||||
// flush out many corner cases.
|
||||
|
||||
#define PEDANTIC 0
|
||||
#if PEDANTIC
|
||||
# define UNLESS_PEDANTIC(...)
|
||||
# define IF_PEDANTIC(...) __VA_ARGS__
|
||||
#else
|
||||
# define UNLESS_PEDANTIC(...) __VA_ARGS__
|
||||
# define IF_PEDANTIC(...)
|
||||
#endif
|
||||
|
||||
#ifdef NANOJIT_IA32
|
||||
#include "Nativei386.h"
|
||||
@ -50,8 +62,8 @@
|
||||
#include "NativePpc.h"
|
||||
#elif defined(NANOJIT_SPARC)
|
||||
#include "NativeSparc.h"
|
||||
#elif defined(NANOJIT_AMD64)
|
||||
#include "NativeAMD64.h"
|
||||
#elif defined(NANOJIT_X64)
|
||||
#include "NativeX64.h"
|
||||
#else
|
||||
#error "unknown nanojit architecture"
|
||||
#endif
|
||||
|
@ -243,6 +243,12 @@ namespace nanojit
|
||||
emitrr(X64_movqr, d, s);
|
||||
}
|
||||
|
||||
void Assembler::JMPl(NIns* target) {
|
||||
NanoAssert(!target || isS32(target - _nIns));
|
||||
underrunProtect(8); // must do this before calculating offset
|
||||
emit32(X64_jmp, target ? target - _nIns : 0);
|
||||
}
|
||||
|
||||
void Assembler::JMP(NIns *target) {
|
||||
if (!target || isS32(target - _nIns)) {
|
||||
underrunProtect(8); // must do this before calculating offset
|
||||
@ -899,6 +905,10 @@ namespace nanojit
|
||||
|
||||
void Assembler::asm_ret(LIns *ins) {
|
||||
genEpilogue();
|
||||
|
||||
// Restore RSP from RBP, undoing SUB(RSP,amt) in the prologue
|
||||
MR(RSP,FP);
|
||||
|
||||
assignSavedRegs();
|
||||
LIns *value = ins->oprnd1();
|
||||
Register r = ins->isop(LIR_ret) ? RAX : XMM0;
|
||||
@ -1166,12 +1176,10 @@ namespace nanojit
|
||||
}
|
||||
|
||||
NIns* Assembler::genEpilogue() {
|
||||
// mov rsp, rbp
|
||||
// pop rbp
|
||||
// ret
|
||||
emit(X64_ret);
|
||||
emitr(X64_popr, RBP);
|
||||
MR(RSP, RBP);
|
||||
return _nIns;
|
||||
}
|
||||
|
||||
@ -1229,8 +1237,33 @@ namespace nanojit
|
||||
#endif
|
||||
}
|
||||
|
||||
void Assembler::nFragExit(LIns*) {
|
||||
TODO(nFragExit);
|
||||
void Assembler::nFragExit(LIns *guard) {
|
||||
SideExit *exit = guard->record()->exit;
|
||||
Fragment *frag = exit->target;
|
||||
GuardRecord *lr = 0;
|
||||
bool destKnown = (frag && frag->fragEntry);
|
||||
// Generate jump to epilog and initialize lr.
|
||||
// If the guard is LIR_xtbl, use a jump table with epilog in every entry
|
||||
if (guard->isop(LIR_xtbl)) {
|
||||
NanoAssert(!guard->isop(LIR_xtbl));
|
||||
} else {
|
||||
// If the guard already exists, use a simple jump.
|
||||
if (destKnown) {
|
||||
JMP(frag->fragEntry);
|
||||
lr = 0;
|
||||
} else { // target doesn't exist. Use 0 jump offset and patch later
|
||||
if (!_epilogue)
|
||||
_epilogue = genEpilogue();
|
||||
lr = guard->record();
|
||||
JMPl(_epilogue);
|
||||
lr->jmp = _nIns;
|
||||
}
|
||||
}
|
||||
|
||||
MR(RSP, RBP);
|
||||
|
||||
// return value is GuardRecord*
|
||||
emit_quad(RAX, uintptr_t(lr));
|
||||
}
|
||||
|
||||
void Assembler::nInit(AvmCore*) {
|
||||
|
@ -58,6 +58,7 @@
|
||||
|
||||
namespace nanojit
|
||||
{
|
||||
const int NJ_LOG2_PAGE_SIZE = 12; // 4K
|
||||
#define NJ_MAX_STACK_ENTRY 256
|
||||
#define NJ_ALIGN_STACK 16
|
||||
|
||||
@ -315,6 +316,7 @@ namespace nanojit
|
||||
void asm_qbinop(LIns*); \
|
||||
void MR(Register, Register);\
|
||||
void JMP(NIns*);\
|
||||
void JMPl(NIns*);\
|
||||
void emit(uint64_t op);\
|
||||
void emit8(uint64_t op, int64_t val);\
|
||||
void emit32(uint64_t op, int64_t val);\
|
||||
|
@ -54,7 +54,7 @@
|
||||
#elif AVMPLUS_SPARC
|
||||
#define NANOJIT_SPARC
|
||||
#elif AVMPLUS_AMD64
|
||||
#define NANOJIT_AMD64
|
||||
#define NANOJIT_X64
|
||||
#define NANOJIT_64BIT
|
||||
#else
|
||||
#error "unknown nanojit architecture"
|
||||
|
40
js/src/trace-test/tests/basic/bitops-nsieve-bits.js
Normal file
40
js/src/trace-test/tests/basic/bitops-nsieve-bits.js
Normal file
@ -0,0 +1,40 @@
|
||||
// The Great Computer Language Shootout
|
||||
// http://shootout.alioth.debian.org
|
||||
//
|
||||
// Contributed by Ian Osgood
|
||||
|
||||
var result = [];
|
||||
|
||||
function pad(n,width) {
|
||||
var s = n.toString();
|
||||
while (s.length < width) s = ' ' + s;
|
||||
return s;
|
||||
}
|
||||
|
||||
function primes(isPrime, n) {
|
||||
var i, count = 0, m = 10000<<n, size = m+31>>5;
|
||||
|
||||
for (i=0; i<size; i++) isPrime[i] = 0xffffffff;
|
||||
|
||||
for (i=2; i<m; i++)
|
||||
if (isPrime[i>>5] & 1<<(i&31)) {
|
||||
for (var j=i+i; j<m; j+=i)
|
||||
result.push(isPrime[j>>5] &= ~(1<<(j&31)));
|
||||
count++;
|
||||
}
|
||||
}
|
||||
|
||||
function sieve() {
|
||||
for (var i = 4; i <= 4; i++) {
|
||||
var isPrime = new Array((10000<<i)+31>>5);
|
||||
primes(isPrime, i);
|
||||
}
|
||||
}
|
||||
|
||||
sieve();
|
||||
|
||||
var ret = 0;
|
||||
for (var i = 0; i < result.length; ++i)
|
||||
ret += result[i];
|
||||
|
||||
assertEq(ret, -211235557404919)
|
Loading…
Reference in New Issue
Block a user