Bug 503990: make isStmt() table-driven. r=gal.

This commit is contained in:
Nicholas Nethercote 2009-07-14 13:08:38 +10:00
Родитель 73ba7d6897
Коммит cc0bab4b9f
5 изменённых файлов: 198 добавлений и 188 удалений

Просмотреть файл

@ -643,9 +643,9 @@ assemble(istream &in,
map<string,LIns*> labels;
map<string,pair<LOpcode,size_t> > op_map;
#define OPDEF(op, number, args, repkind) \
#define OPDEF(op, number, args, repkind, isStmt) \
op_map[#op] = make_pair(LIR_##op, args);
#define OPDEF64(op, number, args, repkind) \
#define OPDEF64(op, number, args, repkind, isStmt) \
op_map[#op] = make_pair(LIR_##op, args);
#include "nanojit/LIRopcode.tbl"
#undef OPDEF

Просмотреть файл

@ -85,10 +85,10 @@ namespace nanojit
/* Opcodes must be strictly increasing without holes. */
uint32_t count = 0;
#define OPDEF(op, number, operands, repkind) \
#define OPDEF(op, number, operands, repkind, isStmt) \
NanoAssertMsg(LIR_##op == count++, "misnumbered opcode");
#define OPDEF64(op, number, operands, repkind) \
OPDEF(op, number, operands, repkind)
#define OPDEF64(op, number, operands, repkind, isStmt) \
OPDEF(op, number, operands, repkind, isStmt)
#include "LIRopcode.tbl"
#undef OPDEF
#undef OPDEF64

Просмотреть файл

@ -52,9 +52,9 @@ namespace nanojit
#ifdef FEATURE_NANOJIT
const uint8_t operandCount[] = {
#define OPDEF(op, number, operands, repkind) \
#define OPDEF(op, number, operands, repkind, isStmt) \
operands,
#define OPDEF64(op, number, operands, repkind) \
#define OPDEF64(op, number, operands, repkind, isStmt) \
operands,
#include "LIRopcode.tbl"
#undef OPDEF
@ -62,35 +62,47 @@ namespace nanojit
0
};
const uint8_t repKinds[] = {
#define OPDEF(op, number, operands, repkind) \
const uint8_t repKind[] = {
#define OPDEF(op, number, operands, repkind, isStmt) \
LRK_##repkind,
#define OPDEF64(op, number, operands, repkind, isStmt) \
LRK_##repkind,
#define OPDEF64(op, number, operands, repkind) \
OPDEF(op, number, operands, repkind)
#include "LIRopcode.tbl"
#undef OPDEF
#undef OPDEF64
0
};
const uint8_t insSizes[] = {
#define OPDEF(op, number, operands, repkind) \
sizeof(LIns##repkind),
#define OPDEF64(op, number, operands, repkind) \
OPDEF(op, number, operands, repkind)
const uint8_t insSize[] = {
#define OPDEF(op, number, operands, repkind, isStmt) \
sizeof(LIns##repkind),
#define OPDEF64(op, number, operands, repkind, isStmt) \
sizeof(LIns##repkind),
#include "LIRopcode.tbl"
#undef OPDEF
#undef OPDEF64
0
};
0
};
// This isn't called 'isStmt' because there's a function of that name.
const uint8_t isStmtArray[] = {
#define OPDEF(op, number, operands, repkind, isStmt) \
isStmt,
#define OPDEF64(op, number, operands, repkind, isStmt) \
isStmt,
#include "LIRopcode.tbl"
#undef OPDEF
#undef OPDEF64
0
};
// LIR verbose specific
#ifdef NJ_VERBOSE
const char* lirNames[] = {
#define OPDEF(op, number, operands, repkind) \
#define OPDEF(op, number, operands, repkind, isStmt) \
#op,
#define OPDEF64(op, number, operands, repkind) \
#define OPDEF64(op, number, operands, repkind, isStmt) \
#op,
#include "LIRopcode.tbl"
#undef OPDEF
@ -376,7 +388,7 @@ namespace nanojit
switch (iop)
{
default:
i -= insSizes[((LInsp)i)->opcode()];
i -= insSize[((LInsp)i)->opcode()];
break;
#if defined NANOJIT_64BIT
@ -427,53 +439,53 @@ namespace nanojit
}
bool LIns::isLInsOp0() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Op0 == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_Op0 == repKind[opcode()];
}
bool LIns::isLInsOp1() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Op1 == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_Op1 == repKind[opcode()];
}
bool LIns::isLInsOp2() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Op2 == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_Op2 == repKind[opcode()];
}
bool LIns::isLInsLd() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Ld == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_Ld == repKind[opcode()];
}
bool LIns::isLInsSti() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Sti == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_Sti == repKind[opcode()];
}
bool LIns::isLInsSk() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_Sk == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_Sk == repKind[opcode()];
}
bool LIns::isLInsC() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_C == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_C == repKind[opcode()];
}
bool LIns::isLInsP() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_P == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_P == repKind[opcode()];
}
bool LIns::isLInsI() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_I == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_I == repKind[opcode()];
}
bool LIns::isLInsI64() const {
NanoAssert(LRK_None != repKinds[opcode()]);
return LRK_I64 == repKinds[opcode()];
NanoAssert(LRK_None != repKind[opcode()]);
return LRK_I64 == repKind[opcode()];
}
bool LIns::isCmp() const {
@ -520,6 +532,11 @@ namespace nanojit
return nanojit::isCseOpcode(opcode()) || (isCall() && callInfo()->_cse);
}
bool LIns::isStmt()
{
return 1 == isStmtArray[opcode()];
}
void LIns::setTarget(LInsp label)
{
NanoAssert(label && label->isop(LIR_label));

Просмотреть файл

@ -59,9 +59,9 @@ namespace nanojit
// flags; upper bits reserved
LIR64 = 0x40, // result is double or quad
#define OPDEF(op, number, args, repkind) \
#define OPDEF(op, number, args, repkind, isStmt) \
LIR_##op = (number),
#define OPDEF64(op, number, args, repkind) \
#define OPDEF64(op, number, args, repkind, isStmt) \
LIR_##op = ((number) | LIR64),
#include "LIRopcode.tbl"
LIR_sentinel
@ -680,20 +680,7 @@ namespace nanojit
bool isBranch() const {
return isop(LIR_jt) || isop(LIR_jf) || isop(LIR_j);
}
// Return true if removal of 'ins' from a LIR fragment could
// possibly change the behaviour of that fragment, even if any
// value computed by 'ins' is not used later in the fragment.
// In other words, can 'ins' possible alter control flow or memory?
// Note, this assumes that loads will never fault and hence cannot
// affect the control flow.
bool isStmt() {
return isGuard() || isBranch() ||
(isCall() && !isCse()) ||
isStore() ||
isop(LIR_loop) || isop(LIR_label) || isop(LIR_live) ||
isRet();
}
bool isStmt();
void setTarget(LIns* t);
LIns* getTarget();

Просмотреть файл

@ -39,8 +39,8 @@
* ***** END LICENSE BLOCK ***** */
/*
* Definitions of LIR opcodes. If you need to allocate an opcode, look
* for a name of the form unused* and claim it.
* Definitions of LIR opcodes. If you need to allocate an opcode, claim one
* starting with "__".
*
* Includers must define OPDEF and OPDEF64 macros of the following forms:
*
@ -60,6 +60,12 @@
* that it needs changing if the opcode becomes used.
* repkind Indicates how the instruction is represented in memory; XYZ
* corresponds to LInsXYZ and LRK_XYZ.
* isStmt If 1, the removal of the instruction from a LIR fragment could
* change the behaviour of that fragment, even if any value
* computed by the instruction is not used later in the fragment.
* In other words, can the instruction possibly alter control
* flow or memory? Note, we assume that loads will never fault
* and hence cannot affect the control flow.
*
* This file is best viewed with 128 columns:
12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678
@ -68,36 +74,36 @@
/* op val name operands */
/* special operations (must be 0..N) */
OPDEF(start, 0, 0, Op0) // start of a fragment
OPDEF(unused1, 1,-1, None)
OPDEF(skip, 2, 1, Sk) // holds blobs ("payloads") of data; also links pages
OPDEF(unused3, 3,-1, None)
OPDEF(unused4, 4,-1, None)
OPDEF(unused5, 5,-1, None)
OPDEF(unused6, 6,-1, None)
OPDEF(start, 0, 0, Op0, 0) // start of a fragment
OPDEF(__1, 1,-1, None, 0)
OPDEF(skip, 2, 1, Sk, 0) // holds blobs ("payloads") of data; also links pages
OPDEF(__3, 3,-1, None, 0)
OPDEF(__4, 4,-1, None, 0)
OPDEF(__5, 5,-1, None, 0)
OPDEF(__6, 6,-1, None, 0)
/* non-pure operations */
OPDEF(addp, 7, 2, Op2) // integer addition for temporary pointer calculations
OPDEF(param, 8, 0, P) // load a parameter
OPDEF(unused9, 9,-1, None)
OPDEF(ld, 10, 1, Ld) // 32-bit load
OPDEF(alloc, 11, 0, I) // alloca some stack space
OPDEF(sti, 12, 2, Sti) // 32-bit store
OPDEF(ret, 13, 1, Op1) // return a word-sized value
OPDEF(live, 14, 1, Op1) // extend live range of reference
OPDEF(unused15, 15, 0, C)
OPDEF(call, 16, 0, C) // subroutine call returning a 32-bit value
OPDEF(addp, 7, 2, Op2, 0) // integer addition for temporary pointer calculations
OPDEF(param, 8, 0, P, 0) // load a parameter
OPDEF(__9, 9,-1, None, 0)
OPDEF(ld, 10, 2, Ld, 0) // 32-bit load
OPDEF(alloc, 11, 0, I, 0) // alloca some stack space
OPDEF(sti, 12, 2, Sti, 1) // 32-bit store
OPDEF(ret, 13, 1, Op1, 1) // return a word-sized value
OPDEF(live, 14, 1, Op1, 1) // extend live range of reference
OPDEF(__15, 15, 0, C, 0)
OPDEF(call, 16, 0, C, 1) // subroutine call returning a 32-bit value
/* guards */
OPDEF(loop, 17, 0, Op2) // loop fragment
OPDEF(x, 18, 0, Op2) // exit always
OPDEF(loop, 17, 0, Op2, 1) // loop fragment
OPDEF(x, 18, 0, Op2, 1) // exit always
/* branches */
OPDEF(j, 19, 0, Op2) // jump always
OPDEF(jt, 20, 1, Op2) // jump if true
OPDEF(jf, 21, 1, Op2) // jump if false
OPDEF(label, 22, 0, Op0) // a jump target (no machine code is emitted for this)
OPDEF(ji, 23,-1, None) // indirect jump (currently not implemented)
OPDEF(j, 19, 0, Op2, 1) // jump always
OPDEF(jt, 20, 1, Op2, 1) // jump if true
OPDEF(jf, 21, 1, Op2, 1) // jump if false
OPDEF(label, 22, 0, Op0, 1) // a jump target (no machine code is emitted for this)
OPDEF(ji, 23,-1, None, 0) // indirect jump (currently not implemented)
/* operators */
@ -106,12 +112,12 @@ OPDEF(ji, 23,-1, None) // indirect jump (currently not implemented)
* common-subexpression-elimination detection code.
*/
OPDEF(int, 24, 0, I) // constant 32-bit integer
OPDEF(cmov, 25, 2, Op2) // conditional move (op1=cond, op2=LIR_2(iftrue,iffalse))
OPDEF(int, 24, 0, I, 0) // constant 32-bit integer
OPDEF(cmov, 25, 2, Op2, 0) // conditional move (op1=cond, op2=LIR_2(iftrue,iffalse))
#if defined(NANOJIT_64BIT)
OPDEF(callh, 26,-1, None) // unused on 64-bit machines
OPDEF(callh, 26,-1, None, 0) // unused on 64-bit machines
#else
OPDEF(callh, 26, 1, Op1) // get the high 32 bits of a call returning a 64-bit value
OPDEF(callh, 26, 1, Op1, 0) // get the high 32 bits of a call returning a 64-bit value
#endif
/*
@ -123,44 +129,44 @@ OPDEF(callh, 26, 1, Op1) // get the high 32 bits of a call returning a 64
* with 3. NB: These opcodes must remain continuous so that comparison-opcode
* detection works correctly.
*/
OPDEF(feq, 27, 2, Op2) // floating-point equality
OPDEF(flt, 28, 2, Op2) // floating-point less-than
OPDEF(fgt, 29, 2, Op2) // floating-point greater-than
OPDEF(fle, 30, 2, Op2) // floating-point less-than-or-equal
OPDEF(fge, 31, 2, Op2) // floating-point greater-than-or-equal
OPDEF(feq, 27, 2, Op2, 0) // floating-point equality
OPDEF(flt, 28, 2, Op2, 0) // floating-point less-than
OPDEF(fgt, 29, 2, Op2, 0) // floating-point greater-than
OPDEF(fle, 30, 2, Op2, 0) // floating-point less-than-or-equal
OPDEF(fge, 31, 2, Op2, 0) // floating-point greater-than-or-equal
OPDEF(ldcb, 32, 1, Ld) // non-volatile 8-bit load
OPDEF(ldcs, 33, 1, Ld) // non-volatile 16-bit load
OPDEF(ldc, 34, 1, Ld) // non-volatile 32-bit load
OPDEF(ldcb, 32, 2, Ld, 0) // non-volatile 8-bit load
OPDEF(ldcs, 33, 2, Ld, 0) // non-volatile 16-bit load
OPDEF(ldc, 34, 2, Ld, 0) // non-volatile 32-bit load
OPDEF(neg, 35, 1, Op1) // integer negation
OPDEF(add, 36, 2, Op2) // integer addition
OPDEF(sub, 37, 2, Op2) // integer subtraction
OPDEF(mul, 38, 2, Op2) // integer multiplication
OPDEF(div, 39, 2, Op2) // integer division
OPDEF(mod, 40, 1, Op1) // hack: get the modulus from a LIR_div result, for x86 only
OPDEF(neg, 35, 1, Op1, 0) // integer negation
OPDEF(add, 36, 2, Op2, 0) // integer addition
OPDEF(sub, 37, 2, Op2, 0) // integer subtraction
OPDEF(mul, 38, 2, Op2, 0) // integer multiplication
OPDEF(div, 39, 2, Op2, 0) // integer division
OPDEF(mod, 40, 1, Op1, 0) // hack: get the modulus from a LIR_div result, for x86 only
OPDEF(and, 41, 2, Op2) // 32-bit bitwise AND
OPDEF(or, 42, 2, Op2) // 32-bit bitwise OR
OPDEF(xor, 43, 2, Op2) // 32-bit bitwise XOR
OPDEF(not, 44, 1, Op1) // 32-bit bitwise NOT
OPDEF(lsh, 45, 2, Op2) // 32-bit left shift
OPDEF(rsh, 46, 2, Op2) // 32-bit right shift with sign-extend (>>)
OPDEF(ush, 47, 2, Op2) // 32-bit unsigned right shift (>>>)
OPDEF(and, 41, 2, Op2, 0) // 32-bit bitwise AND
OPDEF(or, 42, 2, Op2, 0) // 32-bit bitwise OR
OPDEF(xor, 43, 2, Op2, 0) // 32-bit bitwise XOR
OPDEF(not, 44, 1, Op1, 0) // 32-bit bitwise NOT
OPDEF(lsh, 45, 2, Op2, 0) // 32-bit left shift
OPDEF(rsh, 46, 2, Op2, 0) // 32-bit right shift with sign-extend (>>)
OPDEF(ush, 47, 2, Op2, 0) // 32-bit unsigned right shift (>>>)
// conditional guards, op^1 to complement. Only things that are
// isCond() can be passed to these.
OPDEF(xt, 48, 1, Op2) // exit if true (0x30 0011 0000)
OPDEF(xf, 49, 1, Op2) // exit if false (0x31 0011 0001)
OPDEF(xt, 48, 1, Op2, 1) // exit if true (0x30 0011 0000)
OPDEF(xf, 49, 1, Op2, 1) // exit if false (0x31 0011 0001)
OPDEF(qlo, 50, 1, Op1) // get the low 32 bits of a 64-bit value
OPDEF(qhi, 51, 1, Op1) // get the high 32 bits of a 64-bit value
OPDEF(qlo, 50, 1, Op1, 0) // get the low 32 bits of a 64-bit value
OPDEF(qhi, 51, 1, Op1, 0) // get the high 32 bits of a 64-bit value
OPDEF(unused52, 52,-1, None)
OPDEF(__52, 52,-1, None, 0)
OPDEF(ov, 53, 1, Op1) // test for overflow; value must have just been computed
OPDEF(ov, 53, 1, Op1, 0) // test for overflow; value must have just been computed
OPDEF(unused53, 54,-1, None)
OPDEF(__53, 54,-1, None, 0)
// Integer (all sizes) relational operators. (op ^ 1) is the op which flips the
// left and right sides of the comparison, so (lt ^ 1) == gt, or the operator
@ -169,96 +175,96 @@ OPDEF(unused53, 54,-1, None)
// with 3. 'u' prefix indicates the unsigned integer variant.
// NB: These opcodes must remain continuous so that comparison-opcode detection
// works correctly.
OPDEF(eq, 55, 2, Op2) // integer equality
OPDEF(lt, 56, 2, Op2) // signed integer less-than (0x38 0011 1000)
OPDEF(gt, 57, 2, Op2) // signed integer greater-than (0x39 0011 1001)
OPDEF(le, 58, 2, Op2) // signed integer less-than-or-equal (0x3A 0011 1010)
OPDEF(ge, 59, 2, Op2) // signed integer greater-than-or-equal (0x3B 0011 1011)
OPDEF(ult, 60, 2, Op2) // unsigned integer less-than (0x3C 0011 1100)
OPDEF(ugt, 61, 2, Op2) // unsigned integer greater-than (0x3D 0011 1101)
OPDEF(ule, 62, 2, Op2) // unsigned integer less-than-or-equal (0x3E 0011 1110)
OPDEF(uge, 63, 2, Op2) // unsigned integer greater-than-or-equal (0x3F 0011 1111)
OPDEF(eq, 55, 2, Op2, 0) // integer equality
OPDEF(lt, 56, 2, Op2, 0) // signed integer less-than (0x38 0011 1000)
OPDEF(gt, 57, 2, Op2, 0) // signed integer greater-than (0x39 0011 1001)
OPDEF(le, 58, 2, Op2, 0) // signed integer less-than-or-equal (0x3A 0011 1010)
OPDEF(ge, 59, 2, Op2, 0) // signed integer greater-than-or-equal (0x3B 0011 1011)
OPDEF(ult, 60, 2, Op2, 0) // unsigned integer less-than (0x3C 0011 1100)
OPDEF(ugt, 61, 2, Op2, 0) // unsigned integer greater-than (0x3D 0011 1101)
OPDEF(ule, 62, 2, Op2, 0) // unsigned integer less-than-or-equal (0x3E 0011 1110)
OPDEF(uge, 63, 2, Op2, 0) // unsigned integer greater-than-or-equal (0x3F 0011 1111)
OPDEF64(2, 0, 2, Op2) // wraps a pair of refs, for LIR_cmov or LIR_qcmov
OPDEF64(file, 1, 2, Op1) // source filename for debug symbols
OPDEF64(line, 2, 2, Op1) // source line number for debug symbols
OPDEF64(xbarrier, 3, 1, Op2) // memory barrier; doesn't exit, but flushes all values to the stack
OPDEF64(xtbl, 4, 1, Op2) // exit via indirect jump
OPDEF64(2, 0, 2, Op2, 0) // wraps a pair of refs, for LIR_cmov or LIR_qcmov
OPDEF64(file, 1, 2, Op1, 0) // source filename for debug symbols
OPDEF64(line, 2, 2, Op1, 0) // source line number for debug symbols
OPDEF64(xbarrier,3, 1, Op2, 1) // memory barrier; doesn't exit, but flushes all values to the stack
OPDEF64(xtbl, 4, 1, Op2, 1) // exit via indirect jump
OPDEF64(unused5_64, 5,-1, None)
OPDEF64(unused6_64, 6,-1, None)
OPDEF64(unused7_64, 7,-1, None)
OPDEF64(unused8_64, 8,-1, None)
OPDEF64(unused9_64, 9,-1, None)
OPDEF64(__5b, 5,-1, None, 0)
OPDEF64(__6b, 6,-1, None, 0)
OPDEF64(__7b, 7,-1, None, 0)
OPDEF64(__8b, 8,-1, None, 0)
OPDEF64(__9b, 9,-1, None, 0)
OPDEF64(ldq, LIR_ld, 1, Ld) // 64-bit (quad) load
OPDEF64(ldq, LIR_ld, 2, Ld, 0) // 64-bit (quad) load
OPDEF64(unused11_64, 11,-1, None)
OPDEF64(__11b, 11,-1, None, 0)
OPDEF64(stqi, LIR_sti, 2, Sti) // 64-bit (quad) store
OPDEF64(fret, LIR_ret, 1, Op1)
OPDEF64(stqi, LIR_sti, 2, Sti, 1) // 64-bit (quad) store
OPDEF64(fret, LIR_ret, 1, Op1, 1)
OPDEF64(unused14_64, 14,-1, None)
OPDEF64(unused15_64, 15,-1, None)
OPDEF64(__14b, 14,-1, None, 0)
OPDEF64(__15b, 15,-1, None, 0)
OPDEF64(fcall, LIR_call, 0, C) // subroutine call returning 64-bit (quad) value
OPDEF64(fcall, LIR_call, 0, C, 1) // subroutine call returning 64-bit (quad) value
OPDEF64(unused17_64, 17,-1, None)
OPDEF64(unused18_64, 18,-1, None)
OPDEF64(unused19_64, 19,-1, None)
OPDEF64(unused20_64, 20,-1, None)
OPDEF64(unused21_64, 21,-1, None)
OPDEF64(unused22_64, 22,-1, None)
OPDEF64(unused23_64, 23,-1, None)
OPDEF64(__17b, 17,-1, None, 0)
OPDEF64(__18b, 18,-1, None, 0)
OPDEF64(__19b, 19,-1, None, 0)
OPDEF64(__20b, 20,-1, None, 0)
OPDEF64(__21b, 21,-1, None, 0)
OPDEF64(__22b, 22,-1, None, 0)
OPDEF64(__23b, 23,-1, None, 0)
// We strip off the 64 bit flag and compare that the opcode is between LIR_int
// and LIR_uge to decide whether we can CSE the opcode. All opcodes below
// this marker are subject to CSE.
OPDEF64(quad, LIR_int, 0, I64) // 64-bit (quad) constant value
OPDEF64(qcmov, LIR_cmov, 2, Op2) // 64-bit conditional move
OPDEF64(quad, LIR_int, 0, I64, 0) // 64-bit (quad) constant value
OPDEF64(qcmov, LIR_cmov, 2, Op2, 0) // 64-bit conditional move
OPDEF64(unused26_64, 26,-1, None)
OPDEF64(unused27_64, 27,-1, None)
OPDEF64(unused28_64, 28,-1, None)
OPDEF64(unused29_64, 29,-1, None)
OPDEF64(unused30_64, 30,-1, None)
OPDEF64(unused31_64, 31,-1, None)
OPDEF64(unused32_64, 32,-1, None)
OPDEF64(unused33_64, 33,-1, None)
OPDEF64(__26b, 26,-1, None, 0)
OPDEF64(__27b, 27,-1, None, 0)
OPDEF64(__28b, 28,-1, None, 0)
OPDEF64(__29b, 29,-1, None, 0)
OPDEF64(__30b, 30,-1, None, 0)
OPDEF64(__31b, 31,-1, None, 0)
OPDEF64(__32b, 32,-1, None, 0)
OPDEF64(__33b, 33,-1, None, 0)
OPDEF64(ldqc, LIR_ldc, 1, Ld) // non-volatile 64-bit load
OPDEF64(ldqc, LIR_ldc, 2, Ld, 0) // non-volatile 64-bit load
OPDEF64(fneg, LIR_neg, 1, Op1) // floating-point negation
OPDEF64(fadd, LIR_add, 2, Op2) // floating-point addition
OPDEF64(fsub, LIR_sub, 2, Op2) // floating-point subtraction
OPDEF64(fmul, LIR_mul, 2, Op2) // floating-point multiplication
OPDEF64(fdiv, LIR_div, 2, Op2) // floating-point division
OPDEF64(fmod, LIR_mod, 2, Op2) // floating-point modulus(?)
OPDEF64(fneg, LIR_neg, 1, Op1, 0) // floating-point negation
OPDEF64(fadd, LIR_add, 2, Op2, 0) // floating-point addition
OPDEF64(fsub, LIR_sub, 2, Op2, 0) // floating-point subtraction
OPDEF64(fmul, LIR_mul, 2, Op2, 0) // floating-point multiplication
OPDEF64(fdiv, LIR_div, 2, Op2, 0) // floating-point division
OPDEF64(fmod, LIR_mod, 2, Op2, 0) // floating-point modulus(?)
OPDEF64(qiand, 41, 2, Op2) // 64-bit bitwise AND
OPDEF64(qiadd, 42, 2, Op2) // 64-bit bitwise ADD
OPDEF64(qior, 43, 2, Op2) // 64-bit bitwise OR
OPDEF64(qiand, 41, 2, Op2, 0) // 64-bit bitwise AND
OPDEF64(qiadd, 42, 2, Op2, 0) // 64-bit bitwise ADD
OPDEF64(qior, 43, 2, Op2, 0) // 64-bit bitwise OR
OPDEF64(qilsh, 44, 2, Op2) // 64-bit left shift
OPDEF64(qjoin, 45, 2, Op2) // join two 32-bit values (1st arg is low bits, 2nd is high)
OPDEF64(qilsh, 44, 2, Op2, 0) // 64-bit left shift
OPDEF64(qjoin, 45, 2, Op2, 0) // join two 32-bit values (1st arg is low bits, 2nd is high)
OPDEF64(i2f, 46, 1, Op1) // convert a signed 32-bit integer to a float
OPDEF64(u2f, 47, 1, Op1) // convert an unsigned 32-bit integer to a float
OPDEF64(i2f, 46, 1, Op1, 0) // convert a signed 32-bit integer to a float
OPDEF64(u2f, 47, 1, Op1, 0) // convert an unsigned 32-bit integer to a float
OPDEF64(unused48_64, 48,-1, None)
OPDEF64(unused49_64, 49,-1, None)
OPDEF64(unused50_64, 50,-1, None)
OPDEF64(unused51_64, 51,-1, None)
OPDEF64(unused52_64, 52,-1, None)
OPDEF64(unused53_64, 53,-1, None)
OPDEF64(unused54_64, 54,-1, None)
OPDEF64(unused55_64, 55,-1, None)
OPDEF64(unused56_64, 56,-1, None)
OPDEF64(unused57_64, 57,-1, None)
OPDEF64(unused58_64, 58,-1, None)
OPDEF64(unused59_64, 59,-1, None)
OPDEF64(unused60_64, 60,-1, None)
OPDEF64(unused61_64, 61,-1, None)
OPDEF64(unused62_64, 62,-1, None)
OPDEF64(unused63_64, 63,-1, None)
OPDEF64(__48b, 48,-1, None, 0)
OPDEF64(__49b, 49,-1, None, 0)
OPDEF64(__50b, 50,-1, None, 0)
OPDEF64(__51b, 51,-1, None, 0)
OPDEF64(__52b, 52,-1, None, 0)
OPDEF64(__53b, 53,-1, None, 0)
OPDEF64(__54b, 54,-1, None, 0)
OPDEF64(__55b, 55,-1, None, 0)
OPDEF64(__56b, 56,-1, None, 0)
OPDEF64(__57b, 57,-1, None, 0)
OPDEF64(__58b, 58,-1, None, 0)
OPDEF64(__59b, 59,-1, None, 0)
OPDEF64(__60b, 60,-1, None, 0)
OPDEF64(__61b, 61,-1, None, 0)
OPDEF64(__62b, 62,-1, None, 0)
OPDEF64(__63b, 63,-1, None, 0)