mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-25 05:21:02 +00:00
Changed binary int ops to use a temporary register, fixed some opcodes.
For some reason, binary ops might reuse one of the input registers as the output register. This is a problem for very obvious reasons.
This commit is contained in:
parent
1a52c2ba00
commit
591783087d
1 changed files with 70 additions and 72 deletions
|
@ -61,6 +61,13 @@ static asmjit::JitRuntime jit;
|
|||
|
||||
// [pbeta] TODO: VM aborts
|
||||
#define NULL_POINTER_CHECK(a,o,x)
|
||||
#define BINARY_OP_INT(op,out,r,l) \
|
||||
{ \
|
||||
auto tmp = cc.newInt32(); \
|
||||
cc.mov(tmp, r); \
|
||||
cc.op(tmp, l); \
|
||||
cc.mov(out, tmp); \
|
||||
}
|
||||
|
||||
static bool CanJit(VMScriptFunction *sfunc)
|
||||
{
|
||||
|
@ -400,7 +407,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
break;
|
||||
case OP_LB_R:
|
||||
NULL_POINTER_CHECK (PB, RC, X_READ_NIL);
|
||||
cc.movsx (regD[a], x86::byte_ptr (PB, KC));
|
||||
cc.movsx (regD[a], x86::byte_ptr (PB, RC));
|
||||
break;
|
||||
case OP_LH: // load halfword
|
||||
NULL_POINTER_CHECK (PB, KC, X_READ_NIL);
|
||||
|
@ -408,15 +415,15 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
break;
|
||||
case OP_LH_R:
|
||||
NULL_POINTER_CHECK (PB, RC, X_READ_NIL);
|
||||
cc.movsx (regD[a], x86::word_ptr (PB, KC));
|
||||
cc.movsx (regD[a], x86::word_ptr (PB, RC));
|
||||
break;
|
||||
case OP_LW: // load word
|
||||
NULL_POINTER_CHECK (PB, KC, X_READ_NIL);
|
||||
cc.movsx (regD[a], x86::dword_ptr (PB, KC));
|
||||
cc.mov (regD[a], x86::dword_ptr (PB, KC));
|
||||
break;
|
||||
case OP_LW_R:
|
||||
NULL_POINTER_CHECK (PB, RC, X_READ_NIL);
|
||||
cc.movsx (regD[a], x86::dword_ptr (PB, KC));
|
||||
cc.mov (regD[a], x86::dword_ptr (PB, RC));
|
||||
break;
|
||||
case OP_LBU: // load byte unsigned
|
||||
NULL_POINTER_CHECK (PB, KC, X_READ_NIL);
|
||||
|
@ -424,7 +431,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
break;
|
||||
case OP_LBU_R:
|
||||
NULL_POINTER_CHECK (PB, RC, X_READ_NIL);
|
||||
cc.mov (regD[a], x86::byte_ptr (PB, KC));
|
||||
cc.mov (regD[a], x86::byte_ptr (PB, RC));
|
||||
break;
|
||||
case OP_LHU: // load halfword unsigned
|
||||
NULL_POINTER_CHECK (PB, KC, X_READ_NIL);
|
||||
|
@ -432,7 +439,7 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
break;
|
||||
case OP_LHU_R:
|
||||
NULL_POINTER_CHECK (PB, RC, X_READ_NIL);
|
||||
cc.mov (regD[a], x86::word_ptr (PB, KC));
|
||||
cc.mov (regD[a], x86::word_ptr (PB, RC));
|
||||
break;
|
||||
case OP_LSP: // load single-precision fp
|
||||
NULL_POINTER_CHECK (PB, KC, X_READ_NIL);
|
||||
|
@ -787,102 +794,83 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
|
||||
// Integer math.
|
||||
case OP_SLL_RR: // dA = dkB << diC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.shl(regD[a], regD[C]);
|
||||
BINARY_OP_INT(shl, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_SLL_RI:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.shl(regD[a], C);
|
||||
BINARY_OP_INT(shl, regD[a], regD[B], C);
|
||||
break;
|
||||
case OP_SLL_KR:
|
||||
cc.mov(regD[a], konstd[B]);
|
||||
cc.shl(regD[a], C);
|
||||
BINARY_OP_INT(shl, regD[a], konstd[B], regD[C]);
|
||||
break;
|
||||
|
||||
case OP_SRL_RR: // dA = dkB >> diC -- unsigned
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.shr(regD[a], regD[C]);
|
||||
BINARY_OP_INT(shr, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_SRL_RI:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.shr(regD[a], C);
|
||||
BINARY_OP_INT(shr, regD[a], regD[B], C);
|
||||
break;
|
||||
case OP_SRL_KR:
|
||||
cc.mov(regD[a], konstd[B]);
|
||||
cc.shr(regD[a], C);
|
||||
BINARY_OP_INT(shr, regD[a], regD[B], C);
|
||||
break;
|
||||
|
||||
case OP_SRA_RR: // dA = dkB >> diC -- signed
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.sar(regD[a], regD[C]);
|
||||
BINARY_OP_INT(sar, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_SRA_RI:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.sar(regD[a], C);
|
||||
BINARY_OP_INT(sar, regD[a], regD[B], C);
|
||||
break;
|
||||
case OP_SRA_KR:
|
||||
cc.mov(regD[a], konstd[B]);
|
||||
cc.sar(regD[a], regD[C]);
|
||||
BINARY_OP_INT(sar, regD[a], konstd[B], regD[C]);
|
||||
break;
|
||||
|
||||
case OP_ADD_RR: // dA = dB + dkC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.add(regD[a], regD[C]);
|
||||
BINARY_OP_INT(add, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_ADD_RK:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.add(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(add, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_ADDI: // dA = dB + C -- C is a signed 8-bit constant
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.add(regD[a], Cs);
|
||||
BINARY_OP_INT(add, regD[a], regD[B], Cs);
|
||||
break;
|
||||
|
||||
case OP_SUB_RR: // dA = dkB - dkC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.sub(regD[a], regD[C]);
|
||||
BINARY_OP_INT(sub, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_SUB_RK:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.sub(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(sub, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_SUB_KR:
|
||||
cc.mov(regD[a], konstd[B]);
|
||||
cc.sub(regD[a], regD[C]);
|
||||
BINARY_OP_INT(sub, regD[a], konstd[B], regD[C]);
|
||||
break;
|
||||
case OP_MUL_RR: // dA = dB * dkC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.mul(regD[a], regD[C]);
|
||||
BINARY_OP_INT(mul, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_MUL_RK:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.mul(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(mul, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_DIV_RR: // dA = dkB / dkC (signed)
|
||||
// To do: ThrowAbortException(X_DIVISION_BY_ZERO, nullptr);
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.idiv(regD[a], regD[C]);
|
||||
BINARY_OP_INT(idiv, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_DIV_RK:
|
||||
// To do: ThrowAbortException(X_DIVISION_BY_ZERO, nullptr);
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.div(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(idiv, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_DIV_KR:
|
||||
// To do: ThrowAbortException(X_DIVISION_BY_ZERO, nullptr);
|
||||
cc.mov(regD[a], konstd[B]);
|
||||
cc.idiv(regD[a], regD[C]);
|
||||
BINARY_OP_INT(idiv, regD[a], konstd[B], regD[C]);
|
||||
break;
|
||||
case OP_DIVU_RR: // dA = dkB / dkC (unsigned)
|
||||
// To do: ThrowAbortException(X_DIVISION_BY_ZERO, nullptr);
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.div(regD[a], regD[C]);
|
||||
BINARY_OP_INT(div, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_DIVU_RK:
|
||||
// To do: ThrowAbortException(X_DIVISION_BY_ZERO, nullptr);
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.div(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(div, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_DIVU_KR:
|
||||
// To do: ThrowAbortException(X_DIVISION_BY_ZERO, nullptr);
|
||||
cc.mov(regD[a], konstd[B]);
|
||||
cc.div(regD[a], regD[C]);
|
||||
BINARY_OP_INT(div, regD[a], konstd[B], regD[C]);
|
||||
break;
|
||||
case OP_MOD_RR: // dA = dkB % dkC (signed)
|
||||
case OP_MOD_RK:
|
||||
|
@ -892,28 +880,22 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
case OP_MODU_KR:
|
||||
break;
|
||||
case OP_AND_RR: // dA = dB & dkC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.and_(regD[a], regD[C]);
|
||||
BINARY_OP_INT(and_, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_AND_RK:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.and_(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(and_, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_OR_RR: // dA = dB | dkC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.or_(regD[a], regD[C]);
|
||||
BINARY_OP_INT(or_, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_OR_RK:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.or_(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(or_, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_XOR_RR: // dA = dB ^ dkC
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.xor_(regD[a], regD[C]);
|
||||
BINARY_OP_INT(xor_, regD[a], regD[B], regD[C]);
|
||||
break;
|
||||
case OP_XOR_RK:
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.xor_(regD[a], konstd[C]);
|
||||
BINARY_OP_INT(xor_, regD[a], regD[B], konstd[C]);
|
||||
break;
|
||||
case OP_MIN_RR: // dA = min(dB,dkC)
|
||||
case OP_MIN_RK:
|
||||
|
@ -922,9 +904,13 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
case OP_ABS: // dA = abs(dB)
|
||||
break;
|
||||
case OP_NEG: // dA = -dB
|
||||
cc.xor_(regD[a], regD[a]);
|
||||
cc.sub(regD[a], regD[B]);
|
||||
{
|
||||
auto tmp = cc.newInt32 ();
|
||||
cc.xor_(tmp, tmp);
|
||||
cc.sub(tmp, regD[B]);
|
||||
cc.mov(regD[a], tmp);
|
||||
break;
|
||||
}
|
||||
case OP_NOT: // dA = ~dB
|
||||
cc.mov(regD[a], regD[B]);
|
||||
cc.not_(regD[a]);
|
||||
|
@ -1473,19 +1459,31 @@ JitFuncPtr JitCompile(VMScriptFunction *sfunc)
|
|||
|
||||
// Pointer math.
|
||||
case OP_ADDA_RR: // pA = pB + dkC
|
||||
cc.mov(regA[a], regA[B]);
|
||||
cc.add(regA[a], regD[C]);
|
||||
{
|
||||
auto tmp = cc.newIntPtr();
|
||||
cc.mov(tmp, regA[B]);
|
||||
cc.add(tmp, regD[C]);
|
||||
cc.mov(regA[a], tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_ADDA_RK:
|
||||
cc.mov(regA[a], regA[B]);
|
||||
cc.add(regA[a], konstd[C]);
|
||||
{
|
||||
auto tmp = cc.newIntPtr();
|
||||
cc.mov(tmp, regA[B]);
|
||||
cc.add(tmp, konstd[C]);
|
||||
cc.mov(regA[a], tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_SUBA: // dA = pB - pC
|
||||
cc.mov(regA[a], regA[B]);
|
||||
cc.sub(regA[a], regD[C]);
|
||||
{
|
||||
auto tmp = cc.newIntPtr();
|
||||
cc.mov(tmp, regA[B]);
|
||||
cc.sub(tmp, regD[C]);
|
||||
cc.mov(regA[a], tmp);
|
||||
break;
|
||||
}
|
||||
|
||||
case OP_EQA_R: // if ((pB == pkC) != A) then pc++
|
||||
case OP_EQA_K:
|
||||
|
|
Loading…
Reference in a new issue