qzdoom/src/zscript/vmops.h

211 lines
8.1 KiB
C
Raw Normal View History

#ifndef xx
#define xx(op, name, mode) OP_##op
#endif
// Load constants.
xx(LI, li, LI), // load immediate signed 16-bit constant
xx(LK, lk, LKI), // load integer constant
xx(LKF, lk, LKF), // load float constant
xx(LKS, lk, LKS), // load string constant
xx(LKP, lk, LKP), // load pointer constant
xx(LFP, lf, LFP), // load frame pointer
// Load from memory. rA = *(rB + rkC)
xx(LB, lb, RIRPKI), // load byte
xx(LB_R, lb, RIRPRI),
xx(LH, lh, RIRPKI), // load halfword
xx(LH_R, lh, RIRPRI),
xx(LW, lw, RIRPKI), // load word
xx(LW_R, lw, RIRPRI),
xx(LBU, lbu, RIRPKI), // load byte unsigned
xx(LBU_R, lbu, RIRPRI),
xx(LHU, lhu, RIRPKI), // load halfword unsigned
xx(LHU_R, lhu, RIRPRI),
xx(LSP, lsp, RFRPKI), // load single-precision fp
xx(LSP_R, lsp, RFRPRI),
xx(LDP, ldp, RFRPKI), // load double-precision fp
xx(LDP_R, ldp, RFRPRI),
xx(LS, ls, RSRPKI), // load string
xx(LS_R, ls, RSRPRI),
xx(LO, lo, RPRPKI), // load object
xx(LO_R, lo, RPRPRI),
xx(LP, lp, RPRPKI), // load pointer
xx(LP_R, lp, RPRPRI),
xx(LV, lv, RVRPKI), // load vector
xx(LV_R, lv, RVRPRI),
xx(LX, lx, RFRPKI), // load fixed point
xx(LX_R, lx, RFRPRI),
xx(LBIT, lbit, RIRPI8), // rA = !!(*rB & C) -- *rB is a byte
// Store instructions. *(rA + rkC) = rB
xx(SB, sb, RPRIKI), // store byte
xx(SB_R, sb, RPRIRI),
xx(SH, sh, RPRIKI), // store halfword
xx(SH_R, sh, RPRIRI),
xx(SW, sw, RPRIKI), // store word
xx(SW_R, sw, RPRIRI),
xx(SSP, ssp, RPRFKI), // store single-precision fp
xx(SSP_R, ssp, RPRFRI),
xx(SDP, sdp, RPRFKI), // store double-precision fp
xx(SDP_R, sdp, RPRFRI),
xx(SS, ss, RPRSKI), // store string
xx(SS_R, ss, RPRSRI),
xx(SP, sp, RPRPKI), // store pointer
xx(SP_R, sp, RPRPRI),
xx(SV, sv, RPRVKI), // store vector
xx(SV_R, sv, RPRVRI),
xx(SX, sx, RPRFKI), // store fixed point
xx(SX_R, sx, RPRFRI),
xx(SBIT, sbit, RPRII8), // *rA |= C if rB is true, *rA &= ~C otherwise
// Move instructions.
xx(MOVE, mov, RIRI), // dA = dB
xx(MOVEF, mov, RFRF), // fA = fB
xx(MOVES, mov, RSRS), // sA = sB
xx(MOVEA, mov, RPRP), // aA = aB
xx(CAST, cast, CAST), // xA = xB, conversion specified by C
xx(DYNCAST_R, dyncast,RPRPRP), // aA = aB after casting to rkC (specifying a class)
xx(DYNCAST_K, dyncast,RPRPKP),
// Control flow.
xx(TEST, test, RII16), // if (dA != BC) then pc++
xx(JMP, jmp, I24), // pc += ABC -- The ABC fields contain a signed 24-bit offset.
xx(IJMP, ijmp, RII16), // pc += dA + BC -- BC is a signed offset. The target instruction must be a JMP.
xx(PARAM, param, __BCP), // push parameter encoded in BC for function call or result for return
xx(CALL, call, RPI8I8), // Call function pkA with parameter count B and expected result count C
xx(CALL_K, call, KPI8I8),
xx(RESULT, result, __BCP), // Result should go in register encoded in BC (in caller, after CALL)
xx(RET, ret, I8BCP), // Copy value from register encoded in BC to return value A, possibly returning
xx(TRY, try, I24), // When an exception is thrown, start searching for a handler at pc + ABC
xx(UNTRY, untry, I8), // Pop A entries off the exception stack
xx(THROW, throw, THROW), // A == 0: Throw exception object pB
// A != 0: Throw exception object pkB
xx(CATCH, catch, CATCH), // A == 0: continue search on next try
// A == 1: continue execution at instruction immediately following CATCH (catches any exception)
// A == 2: (pB == <type of exception thrown>) then pc++ ; next instruction must JMP to another CATCH
// A == 3: (pkB == <type of exception thrown>) then pc++ ; next instruction must JMP to another CATCH
// for A > 0, exception is stored in pC
// String instructions.
xx(CONCAT, concat, RSRSRS), // sA = sB.. ... ..sC
xx(LENS, lens, RIRS), // dA = sB.Length
xx(CMPS, cmps, I8RXRX), // if ((skB op skC) != (A & 1)) then pc++
// Integer math.
xx(SLL_RR, sll, RIRIRI), // dA = dkB << diC
xx(SLL_RI, sll, RIRII8),
xx(SLL_KR, sll, RIKIRI),
xx(SRL_RR, srl, RIRIRI), // dA = dkB >> diC -- unsigned
xx(SRL_RI, srl, RIRII8),
xx(SRL_KR, srl, RIKIRI),
xx(SRA_RR, sra, RIRIRI), // dA = dkB >> diC -- signed
xx(SRA_RI, sra, RIRII8),
xx(SRA_KR, sra, RIKIRI),
xx(ADD_RR, add, RIRIRI), // dA = dB + dkC
xx(ADD_RK, add, RIRIKI),
xx(ADDI, add, RIRIIs), // dA = dB + C -- C is a signed 8-bit constant
xx(SUB_RR, sub, RIRIRI), // dA = dkB - dkC
xx(SUB_RK, sub, RIRIKI),
xx(SUB_KR, sub, RIKIRI),
xx(MUL_RR, mul, RIRIRI), // dA = dB * dkC
xx(MUL_RK, mul, RIRIKI),
xx(DIV_RR, div, RIRIRI), // dA = dkB / dkC
xx(DIV_RK, div, RIRIKI),
xx(DIV_KR, div, RIKIRI),
xx(MOD_RR, mod, RIRIRI), // dA = dkB % dkC
xx(MOD_RK, mod, RIRIKI),
xx(MOD_KR, mod, RIKIRI),
xx(AND_RR, and, RIRIRI), // dA = dB & dkC
xx(AND_RK, and, RIRIKI),
xx(OR_RR, or, RIRIRI), // dA = dB | dkC
xx(OR_RK, or, RIRIKI),
xx(XOR_RR, xor, RIRIRI), // dA = dB ^ dkC
xx(XOR_RK, xor, RIRIKI),
xx(MIN_RR, min, RIRIRI), // dA = min(dB,dkC)
xx(MIN_RK, min, RIRIKI),
xx(MAX_RR, max, RIRIRI), // dA = max(dB,dkC)
xx(MAX_RK, max, RIRIKI),
xx(ABS, abs, RIRI), // dA = abs(dB)
xx(NEG, neg, RIRI), // dA = -dB
xx(NOT, not, RIRI), // dA = !dB
xx(SEXT, sext, RIRII8), // dA = dB, sign extended by shifting left then right by C
xx(ZAP_R, zap, RIRIRI), // dA = dB, with bytes zeroed where bits in C/dC are one
xx(ZAP_I, zap, RIRII8),
xx(ZAPNOT_R, zapnot, RIRIRI), // dA = dB, with bytes zeroed where bits in C/dC are zero
xx(ZAPNOT_I, zapnot, RIRII8),
xx(EQ_R, eq, I8RIRI), // if ((dB == dkC) != A) then pc++
xx(EQ_K, eq, I8RIKI),
xx(LT_RR, lt, I8RIRI), // if ((dkB < dkC) != A) then pc++
xx(LT_RK, lt, I8RIKI),
xx(LT_KR, lt, I8KIRI),
xx(LE_RR, le, I8RIRI), // if ((dkB <= dkC) != A) then pc++
xx(LE_RK, le, I8RIKI),
xx(LE_KR, le, I8KIRI),
xx(LTU_RR, ltu, I8RIRI), // if ((dkB < dkC) != A) then pc++ -- unsigned
xx(LTU_RK, ltu, I8RIKI),
xx(LTU_KR, ltu, I8KIRI),
xx(LEU_RR, leu, I8RIRI), // if ((dkB <= dkC) != A) then pc++ -- unsigned
xx(LEU_RK, leu, I8RIKI),
xx(LEU_KR, leu, I8KIRI),
// Double-precision floating point math.
xx(ADDF_RR, add, RFRFRF), // fA = fB + fkC
xx(ADDF_RK, add, RFRFKF),
xx(SUBF_RR, sub, RFRFRF), // fA = fkB - fkC
xx(SUBF_RK, sub, RFRFKF),
xx(SUBF_KR, sub, RFKFRF),
xx(MULF_RR, mul, RFRFRF), // fA = fB * fkC
xx(MULF_RK, mul, RFRFKF),
xx(DIVF_RR, div, RFRFRF), // fA = fkB / fkC
xx(DIVF_RK, div, RFRFKF),
xx(DIVF_KR, div, RFKFRF),
xx(MODF_RR, mod, RFRFRF), // fA = fkB % fkC
xx(MODF_RK, mod, RFRFKF),
xx(MODF_KR, mod, RFKFRF),
xx(POWF_RR, pow, RFRFRF), // fA = fkB ** fkC
xx(POWF_RK, pow, RFRFKF),
xx(POWF_KR, pow, RFKFRF),
xx(MINF_RR, min, RFRFRF), // fA = min(fB),fkC)
xx(MINF_RK, min, RFRFKF),
xx(MAXF_RR, max, RFRFRF), // fA = max(fB),fkC)
xx(MAXF_RK, max, RFRFKF),
xx(FLOP, flop, RFRFI8), // fA = f(fB), where function is selected by C
xx(EQF_R, eq, I8RFRF), // if ((fB == fkC) != (A & 1)) then pc++
xx(EQF_K, eq, I8RFKF),
xx(LTF_RR, lt, I8RFRF), // if ((fkB < fkC) != (A & 1)) then pc++
xx(LTF_RK, lt, I8RFKF),
xx(LTF_KR, lt, I8KFRF),
xx(LEF_RR, le, I8RFRF), // if ((fkb <= fkC) != (A & 1)) then pc++
xx(LEF_RK, le, I8RFKF),
xx(LEF_KR, le, I8KFRF),
// Vector math.
xx(NEGV, negv, RVRV), // vA = -vB
xx(ADDV_RR, addv, RVRVRV), // vA = vB + vkC
xx(ADDV_RK, addv, RVRVKV),
xx(SUBV_RR, subv, RVRVRV), // vA = vkB - vkC
xx(SUBV_RK, subv, RVRVKV),
xx(SUBV_KR, subv, RVKVRV),
xx(DOTV_RR, dotv, RVRVRV), // va = vB dot vkC
xx(DOTV_RK, dotv, RVRVKV),
xx(CROSSV_RR, crossv, RVRVRV), // vA = vkB cross vkC
xx(CROSSV_RK, crossv, RVRVKV),
xx(CROSSV_KR, crossv, RVKVRV),
xx(MULVF_RR, mulv, RVRVRV), // vA = vkB * fkC
xx(MULVF_RK, mulv, RVRVKV),
xx(MULVF_KR, mulv, RVKVRV),
xx(LENV, lenv, RFRV), // fA = vB.Length
xx(EQV_R, eqv, I8RVRV), // if ((vB == vkC) != A) then pc++ (inexact if A & 32)
xx(EQV_K, eqv, I8RVKV),
// Pointer math.
xx(ADDA_RR, add, RPRPRI), // pA = pB + dkC
xx(ADDA_RK, add, RPRPKI),
xx(SUBA, sub, RIRPRP), // dA = pB - pC
xx(EQA_R, eq, I8RPRP), // if ((pB == pkC) != A) then pc++
xx(EQA_K, eq, I8RPKP),
#undef xx