mirror of
https://gitlab.winehq.org/wine/wine-gecko.git
synced 2024-09-13 09:24:08 -07:00
Added LIR.h from TT.
This commit is contained in:
parent
0e152648fe
commit
0c21fdbd7e
636
js/src/nanojit/LIR.h
Normal file
636
js/src/nanojit/LIR.h
Normal file
@ -0,0 +1,636 @@
|
||||
/* ***** 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
|
||||
*
|
||||
* 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_LIR__
|
||||
#define __nanojit_LIR__
|
||||
|
||||
namespace avmplus { class RegionTracker; }
|
||||
|
||||
namespace nanojit
|
||||
{
|
||||
#define is_trace_skip_tramp(op) ((op) <= LIR_tramp)
|
||||
|
||||
enum LOpcode __msvc_only(: unsigned)
|
||||
{
|
||||
// flags; upper bits reserved
|
||||
LIR64 = 0x40, // result is double or quad
|
||||
|
||||
// special operations (must be 0..N)
|
||||
LIR_trace = 2,
|
||||
LIR_skip = 3,
|
||||
LIR_tramp = 4,
|
||||
|
||||
// non-pure operations
|
||||
LIR_arg = 9,
|
||||
LIR_param = 10,
|
||||
LIR_st = 11,
|
||||
LIR_ld = 12,
|
||||
LIR_ref = 13, // ref arg
|
||||
LIR_sti = 14,
|
||||
LIR_call = 18,
|
||||
|
||||
// guards
|
||||
LIR_loop = 19, // loop fragment
|
||||
LIR_x = 20, // exit always
|
||||
|
||||
/**
|
||||
* Integer operations
|
||||
*/
|
||||
LIR_cmov = 31, // conditional move (op1=cond, op2=cond(iftrue,iffalse))
|
||||
LIR_short = 32,
|
||||
LIR_int = 33,
|
||||
LIR_ldc = 34, // non-volatile load
|
||||
LIR_2 = 35, // wraps a pair of refs
|
||||
LIR_neg = 36, // [ 1 integer input / integer output ]
|
||||
LIR_add = 37, // [ 2 operand integer intputs / integer output ]
|
||||
LIR_sub = 38,
|
||||
LIR_mul = 39,
|
||||
LIR_callh = 40,
|
||||
LIR_and = 41,
|
||||
LIR_or = 42,
|
||||
LIR_xor = 43,
|
||||
LIR_not = 44,
|
||||
LIR_lsh = 45,
|
||||
LIR_rsh = 46, // >>
|
||||
LIR_ush = 47, // >>>
|
||||
// conditional guards, op^1 to complement
|
||||
LIR_xt = 48, // exit if true 0x30 0011 0000
|
||||
LIR_xf = 49, // exit if false 0x31 0011 0001
|
||||
LIR_qlo = 50,
|
||||
LIR_qhi = 51,
|
||||
LIR_ldcb = 52, // non-volatile 8-bit load
|
||||
|
||||
LIR_eq = 55,
|
||||
// relational operators. op^1 to swap left/right, op^3 to complement.
|
||||
LIR_lt = 56, // 0x38 0011 1000
|
||||
LIR_gt = 57, // 0x39 0011 1001
|
||||
LIR_le = 58, // 0x3A 0011 1010
|
||||
LIR_ge = 59, // 0x3B 0011 1011
|
||||
LIR_ult = 60, // 0x3C 0011 1100
|
||||
LIR_ugt = 61, // 0x3D 0011 1101
|
||||
LIR_ule = 62, // 0x3E 0011 1110
|
||||
LIR_uge = 63, // 0x3F 0011 1111
|
||||
|
||||
/**
|
||||
* Floating point operations
|
||||
*/
|
||||
LIR_quad = LIR_int | LIR64,
|
||||
LIR_ldq = LIR_ld | LIR64,
|
||||
|
||||
LIR_farg = LIR_arg | LIR64,
|
||||
LIR_fcall = LIR_call | LIR64,
|
||||
LIR_fneg = LIR_neg | LIR64,
|
||||
LIR_fadd = LIR_add | LIR64,
|
||||
LIR_fsub = LIR_sub | LIR64,
|
||||
LIR_fmul = LIR_mul | LIR64,
|
||||
LIR_fdiv = 8 | LIR64,
|
||||
|
||||
LIR_qjoin = 41 | LIR64,
|
||||
LIR_i2f = 42 | LIR64,
|
||||
LIR_u2f = 43 | LIR64,
|
||||
|
||||
LIR_last = 56 | LIR64 // highest ordinal value possible ( must be <127 )
|
||||
};
|
||||
|
||||
struct SideExit;
|
||||
struct Page;
|
||||
struct CallInfo;
|
||||
|
||||
// Low-level Instruction 4B
|
||||
// had to lay it our as a union with duplicate code fields since msvc couldn't figure out how to compact it otherwise.
|
||||
class LIns
|
||||
{
|
||||
// 3-operand form (backwards reach only)
|
||||
struct u_type
|
||||
{
|
||||
LOpcode code:8;
|
||||
uint32_t oprnd_1:8; // 256 ins window and since they only point backwards this is sufficient.
|
||||
uint32_t oprnd_2:8;
|
||||
uint32_t oprnd_3:8; // only used for store, since this location gets clobbered during generation
|
||||
};
|
||||
|
||||
struct sti_type
|
||||
{
|
||||
LOpcode code:8;
|
||||
uint32_t oprnd_1:8; // 256 ins window and since they only point backwards this is sufficient.
|
||||
uint32_t oprnd_2:8;
|
||||
int32_t disp:8;
|
||||
};
|
||||
|
||||
// imm8 form
|
||||
struct c_type
|
||||
{
|
||||
LOpcode code:8;
|
||||
uint32_t imm8a:8;
|
||||
uint32_t imm8b:8;
|
||||
uint32_t resv:8; // cobberred during assembly
|
||||
};
|
||||
|
||||
// imm16 form
|
||||
struct i_type
|
||||
{
|
||||
LOpcode code:8;
|
||||
int32_t imm16:16;
|
||||
uint32_t resv:8; // cobberred during assembly
|
||||
};
|
||||
|
||||
// tramp form (imm24)
|
||||
struct t_type
|
||||
{
|
||||
LOpcode code:8;
|
||||
int32_t imm24:24; // +/- 8MB
|
||||
};
|
||||
|
||||
// overlay used during code generation ( note that last byte is reserved for allocation )
|
||||
struct g_type
|
||||
{
|
||||
LOpcode code:8;
|
||||
uint32_t unused:16;
|
||||
uint32_t resv:8; // cobberred during assembly
|
||||
};
|
||||
|
||||
/**
|
||||
* Various forms of the instruction.
|
||||
*
|
||||
* In general the oprnd_x entries contain an uint value 0-255 that identifies a previous
|
||||
* instruction, where 0 means the previous instruction and 255 means the instruction two
|
||||
* hundred and fifty five prior to this one.
|
||||
*
|
||||
* For pointing to instructions further than this range LIR_tramp is used.
|
||||
*/
|
||||
union
|
||||
{
|
||||
u_type u;
|
||||
c_type c;
|
||||
i_type i;
|
||||
t_type t;
|
||||
g_type g;
|
||||
sti_type sti;
|
||||
};
|
||||
|
||||
uint32_t reference(LIns*);
|
||||
|
||||
public:
|
||||
LIns* FASTCALL oprnd1() const;
|
||||
LIns* FASTCALL oprnd2() const;
|
||||
LIns* FASTCALL oprnd3() const;
|
||||
|
||||
inline LOpcode opcode() const { return u.code; }
|
||||
inline uint8_t imm8() const { return c.imm8a; }
|
||||
inline uint8_t imm8b() const { return c.imm8b; }
|
||||
inline int16_t imm16() const { return i.imm16; }
|
||||
inline int32_t imm24() const { return t.imm24; }
|
||||
inline int32_t imm32() const { return *(int32_t*)(this-1); }
|
||||
inline uint8_t resv() const { return g.resv; }
|
||||
void* payload() const;
|
||||
inline Page* page() { return (Page*) alignTo(this,NJ_PAGE_SIZE); }
|
||||
|
||||
inline int32_t immdisp()const
|
||||
{
|
||||
return u.code == LIR_sti ? sti.disp : oprnd3()->constval();
|
||||
}
|
||||
|
||||
inline static bool sameop(LIns* a, LIns* b)
|
||||
{
|
||||
// hacky but more efficient than opcode() == opcode() due to bit masking of 7-bit field
|
||||
union {
|
||||
uint32_t x;
|
||||
u_type u;
|
||||
} tmp;
|
||||
tmp.x = *(uint32_t*)a ^ *(uint32_t*)b;
|
||||
return tmp.u.code == 0;
|
||||
}
|
||||
|
||||
inline int32_t constval() const
|
||||
{
|
||||
NanoAssert(isconst());
|
||||
return isop(LIR_short) ? imm16() : imm32();
|
||||
}
|
||||
|
||||
inline uint64_t constvalq() const
|
||||
{
|
||||
NanoAssert(isconstq());
|
||||
#ifdef AVMPLUS_UNALIGNED_ACCESS
|
||||
return *(const uint64_t*)(this-2);
|
||||
#else
|
||||
uint64_t tmp;
|
||||
const int32_t* src = (const int32_t*)(this-2);
|
||||
int32_t* dst = (int32_t*)&tmp;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
return tmp;
|
||||
#endif
|
||||
}
|
||||
|
||||
inline double constvalf() const
|
||||
{
|
||||
NanoAssert(isconstq());
|
||||
#ifdef AVMPLUS_UNALIGNED_ACCESS
|
||||
return *(const double*)(this-2);
|
||||
#else
|
||||
union { uint64_t tmp; double tmpf; } u;
|
||||
const int32_t* src = (const int32_t*)(this-2);
|
||||
int32_t* dst = (int32_t*)&u;
|
||||
dst[0] = src[0];
|
||||
dst[1] = src[1];
|
||||
return u.tmpf;
|
||||
#endif
|
||||
}
|
||||
|
||||
bool isCse(const CallInfo *functions) const;
|
||||
bool isop(LOpcode o) const { return u.code == o; }
|
||||
bool isQuad() const { return (u.code & LIR64) != 0; }
|
||||
bool isArg() const { return (u.code & ~LIR64)==LIR_arg || u.code == LIR_ref; }
|
||||
bool isCmp() const;
|
||||
bool isCall() const;
|
||||
bool isStore() const;
|
||||
bool isLoad() const;
|
||||
bool isGuard() const;
|
||||
bool isconst() const;
|
||||
bool isconstval(int32_t val) const;
|
||||
bool isconstq() const;
|
||||
|
||||
void setimm8(int32_t a, int32_t b);
|
||||
void setimm16(int32_t i);
|
||||
void setimm24(int32_t i);
|
||||
void setresv(uint32_t resv);
|
||||
void initOpcode(LOpcode);
|
||||
void setOprnd1(LIns*);
|
||||
void setOprnd2(LIns*);
|
||||
void setOprnd3(LIns*);
|
||||
void setDisp(int8_t d);
|
||||
|
||||
SideExit *exit();
|
||||
};
|
||||
typedef LIns* LInsp;
|
||||
|
||||
bool FASTCALL isCse(LOpcode v);
|
||||
bool FASTCALL isCmp(LOpcode v);
|
||||
LIns* FASTCALL callArgN(LInsp i, uint32_t n);
|
||||
uint32_t FASTCALL operandCount(LOpcode op);
|
||||
|
||||
class Fragmento; // @todo remove this ; needed for minbuild for some reason?!? Should not be compiling this code at all
|
||||
class LirFilter;
|
||||
struct CallInfo;
|
||||
|
||||
class LirWriter
|
||||
{
|
||||
protected:
|
||||
LirWriter *out;
|
||||
public:
|
||||
const CallInfo *_functions;
|
||||
|
||||
virtual ~LirWriter() {}
|
||||
LirWriter(LirWriter* out)
|
||||
: out(out), _functions(out?out->_functions : 0) {}
|
||||
|
||||
virtual LInsp ins0(LOpcode v) {
|
||||
return out->ins0(v);
|
||||
}
|
||||
virtual LInsp ins1(LOpcode v, LIns* a) {
|
||||
return out->ins1(v, a);
|
||||
}
|
||||
virtual LInsp ins2(LOpcode v, LIns* a, LIns* b) {
|
||||
return out->ins2(v, a, b);
|
||||
}
|
||||
virtual LInsp insGuard(LOpcode v, LIns *c, SideExit *x) {
|
||||
return out->insGuard(v, c, x);
|
||||
}
|
||||
virtual LInsp insImm8(LOpcode v, int32_t a, int32_t b) {
|
||||
return out->insImm8(v, a, b);
|
||||
}
|
||||
virtual LInsp insImm(int32_t imm) {
|
||||
return out->insImm(imm);
|
||||
}
|
||||
virtual LInsp insImmq(uint64_t imm) {
|
||||
return out->insImmq(imm);
|
||||
}
|
||||
virtual LInsp insLoad(LOpcode op, LIns* base, LIns* d) {
|
||||
return out->insLoad(op, base, d);
|
||||
}
|
||||
virtual LInsp insStore(LIns* value, LIns* base, LIns* disp) {
|
||||
return out->insStore(value, base, disp);
|
||||
}
|
||||
virtual LInsp insStorei(LIns* value, LIns* base, int32_t d) {
|
||||
return isS8(d) ? out->insStorei(value, base, d)
|
||||
: out->insStore(value, base, insImm(d));
|
||||
}
|
||||
virtual LInsp insCall(int32_t fid, LInsp args[]) {
|
||||
return out->insCall(fid, args);
|
||||
}
|
||||
|
||||
// convenience
|
||||
LIns* insLoadi(LIns *base, int disp);
|
||||
LIns* insLoad(LOpcode op, LIns *base, int disp);
|
||||
LIns* ins_choose(LIns* cond, LIns* iftrue, LIns* iffalse, bool);
|
||||
LIns* ins_eq0(LIns* oprnd1);
|
||||
LIns* ins2i(LOpcode op, LIns *oprnd1, int32_t);
|
||||
LIns* qjoin(LInsp lo, LInsp hi);
|
||||
};
|
||||
|
||||
#ifdef NJ_VERBOSE
|
||||
class Lir
|
||||
{
|
||||
public:
|
||||
static void initEngine();
|
||||
verbose_only( static const char* _lirNames[LIR_last]; )
|
||||
verbose_only( static void initVerboseStructures(); )
|
||||
private:
|
||||
Lir() { NanoAssertMsg(1, "Cannot instantiate this singleton"); }
|
||||
};
|
||||
|
||||
/**
|
||||
* map address ranges to meaningful names.
|
||||
*/
|
||||
class LabelMap
|
||||
{
|
||||
LabelMap* parent;
|
||||
class Entry {
|
||||
public:
|
||||
Entry(int) : name(0), size(0), align(0) {}
|
||||
Entry(avmplus::String *n, size_t s, size_t a) : name(n),size(s),align(a) {}
|
||||
DRCWB(avmplus::String*) name;
|
||||
size_t size:29, align:3;
|
||||
};
|
||||
avmplus::SortedMap<const void*, Entry*, avmplus::LIST_GCObjects> names;
|
||||
bool addrs, pad[3];
|
||||
char buf[1000], *end;
|
||||
void formatAddr(const void *p, char *buf);
|
||||
public:
|
||||
AvmCore *core;
|
||||
LabelMap(AvmCore *, LabelMap* parent);
|
||||
void add(const void *p, size_t size, size_t align, const char *name);
|
||||
void add(const void *p, size_t size, size_t align, avmplus::String*);
|
||||
const char *dup(const char *);
|
||||
const char *format(const void *p);
|
||||
};
|
||||
|
||||
class LirNameMap
|
||||
{
|
||||
class CountMap: public avmplus::SortedMap<int, int, avmplus::LIST_NonGCObjects> {
|
||||
public:
|
||||
CountMap(GC*gc) : avmplus::SortedMap<int, int, avmplus::LIST_NonGCObjects>(gc) {};
|
||||
int add(int i) {
|
||||
int c = 1;
|
||||
if (containsKey(i)) {
|
||||
c = 1+get(i);
|
||||
}
|
||||
put(i,c);
|
||||
return c;
|
||||
}
|
||||
} lircounts, funccounts;
|
||||
class Entry {
|
||||
public:
|
||||
Entry(int) : name(0) {}
|
||||
Entry(avmplus::String *n) : name(n) {}
|
||||
DRCWB(avmplus::String*) name;
|
||||
};
|
||||
avmplus::SortedMap<LInsp, Entry*, avmplus::LIST_GCObjects> names;
|
||||
const CallInfo *_functions;
|
||||
LabelMap *labels;
|
||||
void formatImm(int32_t c, char *buf);
|
||||
public:
|
||||
const uint16_t* codepool;
|
||||
|
||||
LirNameMap(GC *gc, const CallInfo *_functions, LabelMap *r)
|
||||
: lircounts(gc),
|
||||
funccounts(gc),
|
||||
names(gc),
|
||||
_functions(_functions),
|
||||
labels(r)
|
||||
{}
|
||||
|
||||
const char *nameof(LInsp i) {
|
||||
return Lir::_lirNames[i->opcode()];
|
||||
}
|
||||
|
||||
void addName(LInsp i, const char *s);
|
||||
void addName(LInsp i, avmplus::String *s);
|
||||
void copyName(LInsp i, const char *s, int suffix);
|
||||
const char *formatRef(LIns *ref);
|
||||
const char *formatIns(LInsp i);
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
class ExprFilter: public LirWriter
|
||||
{
|
||||
public:
|
||||
ExprFilter(LirWriter *out) : LirWriter(out) {}
|
||||
LIns* ins1(LOpcode v, LIns* a);
|
||||
LIns* ins2(LOpcode v, LIns* a, LIns* b);
|
||||
LIns* insGuard(LOpcode v, LIns *c, SideExit *x);
|
||||
};
|
||||
|
||||
// @todo, this could be replaced by a generic HashMap or HashSet, if we had one
|
||||
class LInsHashSet
|
||||
{
|
||||
// must be a power of 2.
|
||||
// don't start too small, or we'll waste time growing and rehashing.
|
||||
// don't start too large, will waste memory.
|
||||
static const uint32_t kInitialCap = 2048;
|
||||
|
||||
InsList m_list;
|
||||
uint32_t m_used;
|
||||
GC* m_gc;
|
||||
|
||||
static uint32_t FASTCALL hashcode(LInsp i);
|
||||
uint32_t FASTCALL find(LInsp name, uint32_t hash, const InsList& list, uint32_t cap);
|
||||
static bool FASTCALL equals(LInsp a, LInsp b);
|
||||
void FASTCALL grow();
|
||||
|
||||
public:
|
||||
|
||||
LInsHashSet(GC* gc);
|
||||
LInsp find32(int32_t a, uint32_t &i);
|
||||
LInsp find64(uint64_t a, uint32_t &i);
|
||||
LInsp find1(LOpcode v, LInsp a, uint32_t &i);
|
||||
LInsp find2(LOpcode v, LInsp a, LInsp b, uint32_t &i);
|
||||
LInsp findcall(int32_t fid, uint32_t argc, LInsp args[], uint32_t &i);
|
||||
LInsp add(LInsp i, uint32_t k);
|
||||
|
||||
static uint32_t FASTCALL hashimm(int32_t);
|
||||
static uint32_t FASTCALL hashimmq(uint64_t);
|
||||
static uint32_t FASTCALL hash1(LOpcode v, LInsp);
|
||||
static uint32_t FASTCALL hash2(LOpcode v, LInsp, LInsp);
|
||||
static uint32_t FASTCALL hashcall(int32_t fid, uint32_t argc, LInsp args[]);
|
||||
};
|
||||
|
||||
class CseFilter: public LirWriter
|
||||
{
|
||||
LInsHashSet exprs;
|
||||
public:
|
||||
CseFilter(LirWriter *out, GC *gc);
|
||||
LIns* insImm(int32_t imm);
|
||||
LIns* insImmq(uint64_t q);
|
||||
LIns* ins1(LOpcode v, LInsp);
|
||||
LIns* ins2(LOpcode v, LInsp, LInsp);
|
||||
LIns* insLoad(LOpcode v, LInsp b, LInsp d);
|
||||
LIns* insCall(int32_t fid, LInsp args[]);
|
||||
LIns* insGuard(LOpcode op, LInsp cond, SideExit *x);
|
||||
};
|
||||
|
||||
struct Page;
|
||||
class LirBuffer : public GCFinalizedObject
|
||||
{
|
||||
public:
|
||||
DWB(Fragmento*) _frago;
|
||||
public:
|
||||
LirBuffer(Fragmento* frago, const CallInfo* functions);
|
||||
virtual ~LirBuffer();
|
||||
|
||||
uint32_t size();
|
||||
void clear();
|
||||
|
||||
// extensions
|
||||
LInsp next();
|
||||
LInsp commit(uint32_t count);
|
||||
bool addPage();
|
||||
bool outOmem() { return _noMem != 0; }
|
||||
debug_only (void validate() const;)
|
||||
verbose_only(DWB(LirNameMap*) names);
|
||||
|
||||
// stats
|
||||
struct
|
||||
{
|
||||
uint32_t lir; // # instructions
|
||||
uint32_t pages; // pages consumed
|
||||
}
|
||||
_stats;
|
||||
|
||||
const CallInfo* _functions;
|
||||
|
||||
private:
|
||||
Page* pageAlloc();
|
||||
|
||||
Page* _start; // first page
|
||||
LInsp _unused; // next unused instruction slot
|
||||
int _noMem; // set if ran out of memory when writing to buffer
|
||||
};
|
||||
|
||||
class LirBufWriter : public LirWriter
|
||||
{
|
||||
DWB(LirBuffer*) _buf; // underlying buffer housing the instructions
|
||||
|
||||
public:
|
||||
LirBufWriter(LirBuffer* buf)
|
||||
: LirWriter(0), _buf(buf) {
|
||||
_functions = buf->_functions;
|
||||
}
|
||||
|
||||
// LirWriter interface
|
||||
LInsp insLoad(LOpcode op, LInsp base, LInsp off);
|
||||
LInsp insStore(LInsp o1, LInsp o2, LInsp o3);
|
||||
LInsp insStorei(LInsp o1, LInsp o2, int32_t imm);
|
||||
LInsp ins0(LOpcode op);
|
||||
LInsp ins1(LOpcode op, LInsp o1);
|
||||
LInsp ins2(LOpcode op, LInsp o1, LInsp o2);
|
||||
LInsp insImm8(LOpcode op, int32_t a, int32_t b);
|
||||
LInsp insImm(int32_t imm);
|
||||
LInsp insImmq(uint64_t imm);
|
||||
LInsp insCall(int32_t fid, LInsp args[]);
|
||||
LInsp insGuard(LOpcode op, LInsp cond, SideExit *x);
|
||||
|
||||
// buffer mgmt
|
||||
LInsp skip(size_t);
|
||||
LInsp insFar(LOpcode op, int32_t imm);
|
||||
LInsp ensureReferenceable(LInsp i, int32_t addedDistance);
|
||||
bool ensureRoom(uint32_t count);
|
||||
bool canReference(LInsp from, LInsp to) {
|
||||
return isU8(from-to-1);
|
||||
}
|
||||
};
|
||||
|
||||
class LirFilter
|
||||
{
|
||||
public:
|
||||
LirFilter *in;
|
||||
LirFilter(LirFilter *in) : in(in) {}
|
||||
virtual ~LirFilter() {}
|
||||
|
||||
virtual LInsp read() {
|
||||
return in->read();
|
||||
}
|
||||
virtual LInsp pos() {
|
||||
return in->pos();
|
||||
}
|
||||
|
||||
LInsp previous() {
|
||||
read();
|
||||
return pos();
|
||||
}
|
||||
};
|
||||
|
||||
// concrete
|
||||
class LirReader : public LirFilter
|
||||
{
|
||||
LInsp _i; // current instruction that this decoder is operating on.
|
||||
|
||||
public:
|
||||
LirReader(LirBuffer* buf) : LirFilter(0), _i(buf->next()-1) { }
|
||||
LirReader(LInsp i) : LirFilter(0), _i(i) { }
|
||||
virtual ~LirReader() {}
|
||||
|
||||
// LirReader i/f
|
||||
LInsp read(); // advance to the prior instruction
|
||||
LInsp pos() {
|
||||
return _i;
|
||||
}
|
||||
};
|
||||
|
||||
class Assembler;
|
||||
|
||||
void compile(Assembler *assm, Fragment *frag);
|
||||
void trackersAtExit(SideExit* exit, avmplus::RegionTracker& rtrk, avmplus::RegionTracker& strk, Assembler *assm);
|
||||
verbose_only( void printTracker(const char* s, avmplus::RegionTracker& trk, Assembler* assm); )
|
||||
verbose_only(void live(GC *gc, Assembler *assm, Fragment *frag);)
|
||||
|
||||
class StoreFilter: public LirFilter
|
||||
{
|
||||
GC *gc;
|
||||
Assembler *assm;
|
||||
LInsp param0, sp, rp;
|
||||
avmplus::BitSet rstk, stk;
|
||||
int stop, rtop;
|
||||
public:
|
||||
StoreFilter(LirFilter *in, GC *gc, Assembler *assm,
|
||||
LInsp p0, LInsp sp, LInsp rp);
|
||||
virtual ~StoreFilter() {}
|
||||
LInsp read();
|
||||
};
|
||||
}
|
||||
#endif // __nanojit_LIR__
|
@ -56,6 +56,16 @@ class GC
|
||||
{
|
||||
};
|
||||
|
||||
class GCObject
|
||||
{
|
||||
};
|
||||
|
||||
class GCFinalizedObject
|
||||
{
|
||||
};
|
||||
|
||||
#define DWB(x) x
|
||||
|
||||
namespace avmplus
|
||||
{
|
||||
class AvmCore
|
||||
@ -66,10 +76,6 @@ namespace avmplus
|
||||
{
|
||||
};
|
||||
|
||||
class GCObject
|
||||
{
|
||||
};
|
||||
|
||||
/**
|
||||
* The List<T> template implements a simple List, which can
|
||||
* be templated to support different types.
|
||||
|
@ -158,8 +158,8 @@ namespace nanojit
|
||||
#define samepage(x,y) (pageTop(x) == pageTop(y))
|
||||
|
||||
#include "Native.h"
|
||||
/*#include "LIR.h"
|
||||
#include "RegAlloc.h"
|
||||
#include "LIR.h"
|
||||
/*#include "RegAlloc.h"
|
||||
#include "Fragmento.h"
|
||||
#include "Assembler.h"*/
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user