mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-14 22:41:53 +00:00
f343d36ea9
This will store class meta properties in a separate memory block so that it won't have to muck around with PClass - which made the implementation from the scripting branch relatively useless because extending the data wasn't particularly easy and also not well implemented. This can now be handled just like the defaults.
264 lines
14 KiB
C
264 lines
14 KiB
C
#ifndef xx
|
|
#define xx(op, name, mode, alt, kreg, ktype) OP_##op
|
|
#endif
|
|
|
|
// first row is the opcode
|
|
// second row is the disassembly name
|
|
// third row is the disassembly flags
|
|
// fourth row is the alternative opcode if all 256 constant registers are exhausted.
|
|
// fifth row is the constant register index in the opcode
|
|
// sixth row is the constant register type.
|
|
// OP_PARAM and OP_CMPS need special treatment because they encode this information in the instruction.
|
|
|
|
xx(NOP, nop, NOP, NOP, 0, 0), // no operation
|
|
|
|
// Load constants.
|
|
xx(LI, li, LI, NOP, 0, 0), // load immediate signed 16-bit constant
|
|
xx(LK, lk, LKI, NOP, 0, 0), // load integer constant
|
|
xx(LKF, lk, LKF, NOP, 0, 0), // load float constant
|
|
xx(LKS, lk, LKS, NOP, 0, 0), // load string constant
|
|
xx(LKP, lk, LKP, NOP, 0, 0), // load pointer constant
|
|
xx(LK_R, lk, RIRII8, NOP, 0, 0), // load integer constant indexed
|
|
xx(LKF_R, lk, RFRII8, NOP, 0, 0), // load float constant indexed
|
|
xx(LKS_R, lk, RSRII8, NOP, 0, 0), // load string constant indexed
|
|
xx(LKP_R, lk, RPRII8, NOP, 0, 0), // load pointer constant indexed
|
|
xx(LFP, lf, LFP, NOP, 0, 0), // load frame pointer
|
|
xx(META, meta, RPRP, NOP, 0, 0), // load a class's meta data address
|
|
xx(CLSS, clss, RPRP, NOP, 0, 0), // load a class's descriptor address
|
|
|
|
// Load from memory. rA = *(rB + rkC)
|
|
xx(LB, lb, RIRPKI, LB_R, 4, REGT_INT), // load byte
|
|
xx(LB_R, lb, RIRPRI, NOP, 0, 0),
|
|
xx(LH, lh, RIRPKI, LH_R, 4, REGT_INT), // load halfword
|
|
xx(LH_R, lh, RIRPRI, NOP, 0, 0),
|
|
xx(LW, lw, RIRPKI, LW_R, 4, REGT_INT), // load word
|
|
xx(LW_R, lw, RIRPRI, NOP, 0, 0),
|
|
xx(LBU, lbu, RIRPKI, LBU_R, 4, REGT_INT), // load byte unsigned
|
|
xx(LBU_R, lbu, RIRPRI, NOP, 0, 0),
|
|
xx(LHU, lhu, RIRPKI, LHU_R, 4, REGT_INT), // load halfword unsigned
|
|
xx(LHU_R, lhu, RIRPRI, NOP, 0, 0),
|
|
xx(LSP, lsp, RFRPKI, LSP_R, 4, REGT_INT), // load single-precision fp
|
|
xx(LSP_R, lsp, RFRPRI, NOP, 0, 0),
|
|
xx(LDP, ldp, RFRPKI, LDP_R, 4, REGT_INT), // load double-precision fp
|
|
xx(LDP_R, ldp, RFRPRI, NOP, 0, 0),
|
|
xx(LS, ls, RSRPKI, LS_R, 4, REGT_INT), // load string
|
|
xx(LS_R, ls, RSRPRI, NOP, 0, 0),
|
|
xx(LO, lo, RPRPKI, LO_R, 4, REGT_INT), // load object
|
|
xx(LO_R, lo, RPRPRI, NOP, 0, 0),
|
|
xx(LOS, los, RPRPKI, LOS_R, 4, REGT_INT), // load object (stack version without read barrier)
|
|
xx(LOS_R, lo, RPRPRI, NOP, 0, 0),
|
|
xx(LP, lp, RPRPKI, LP_R, 4, REGT_INT), // load pointer
|
|
xx(LP_R, lp, RPRPRI, NOP, 0, 0),
|
|
xx(LV2, lv2, RVRPKI, LV2_R, 4, REGT_INT), // load vector2
|
|
xx(LV2_R, lv2, RVRPRI, NOP, 0, 0),
|
|
xx(LV3, lv3, RVRPKI, LV3_R, 4, REGT_INT), // load vector3
|
|
xx(LV3_R, lv3, RVRPRI, NOP, 0, 0),
|
|
xx(LCS, lcs, RSRPKI, LCS_R, 4, REGT_INT), // load string from char ptr.
|
|
xx(LCS_R, lcs, RSRPRI, NOP, 0, 0),
|
|
|
|
xx(LBIT, lbit, RIRPI8, NOP, 0, 0), // rA = !!(*rB & C) -- *rB is a byte
|
|
|
|
// Store instructions. *(rA + rkC) = rB
|
|
xx(SB, sb, RPRIKI, SB_R, 4, REGT_INT), // store byte
|
|
xx(SB_R, sb, RPRIRI, NOP, 0, 0),
|
|
xx(SH, sh, RPRIKI, SH_R, 4, REGT_INT), // store halfword
|
|
xx(SH_R, sh, RPRIRI, NOP, 0, 0),
|
|
xx(SW, sw, RPRIKI, SW_R, 4, REGT_INT), // store word
|
|
xx(SW_R, sw, RPRIRI, NOP, 0, 0),
|
|
xx(SSP, ssp, RPRFKI, SSP_R, 4, REGT_INT), // store single-precision fp
|
|
xx(SSP_R, ssp, RPRFRI, NOP, 0, 0),
|
|
xx(SDP, sdp, RPRFKI, SDP_R, 4, REGT_INT), // store double-precision fp
|
|
xx(SDP_R, sdp, RPRFRI, NOP, 0, 0),
|
|
xx(SS, ss, RPRSKI, SS_R, 4, REGT_INT), // store string
|
|
xx(SS_R, ss, RPRSRI, NOP, 0, 0),
|
|
xx(SP, sp, RPRPKI, SP_R, 4, REGT_INT), // store pointer
|
|
xx(SP_R, sp, RPRPRI, NOP, 0, 0),
|
|
xx(SO, so, RPRPKI, SO_R, 4, REGT_INT), // store object pointer with write barrier (only needed for non thinkers and non types)
|
|
xx(SO_R, so, RPRPRI, NOP, 0, 0),
|
|
xx(SV2, sv2, RPRVKI, SV2_R, 4, REGT_INT), // store vector2
|
|
xx(SV2_R, sv2, RPRVRI, NOP, 0, 0),
|
|
xx(SV3, sv3, RPRVKI, SV3_R, 4, REGT_INT), // store vector3
|
|
xx(SV3_R, sv3, RPRVRI, NOP, 0, 0),
|
|
|
|
xx(SBIT, sbit, RPRII8, NOP, 0, 0), // *rA |= C if rB is true, *rA &= ~C otherwise
|
|
|
|
// Move instructions.
|
|
xx(MOVE, mov, RIRI, NOP, 0, 0), // dA = dB
|
|
xx(MOVEF, mov, RFRF, NOP, 0, 0), // fA = fB
|
|
xx(MOVES, mov, RSRS, NOP, 0, 0), // sA = sB
|
|
xx(MOVEA, mov, RPRP, NOP, 0, 0), // aA = aB
|
|
xx(MOVEV2, mov2, RFRF, NOP, 0, 0), // fA = fB (2 elements)
|
|
xx(MOVEV3, mov3, RFRF, NOP, 0, 0), // fA = fB (3 elements)
|
|
xx(CAST, cast, CAST, NOP, 0, 0), // xA = xB, conversion specified by C
|
|
xx(CASTB, castb, CAST, NOP, 0, 0), // xA = !!xB, type specified by C
|
|
xx(DYNCAST_R, dyncast, RPRPRP, NOP, 0, 0), // aA = dyn_cast<aC>(aB);
|
|
xx(DYNCAST_K, dyncast, RPRPKP, NOP, 0, 0), // aA = dyn_cast<aKC>(aB);
|
|
xx(DYNCASTC_R, dyncastc, RPRPRP, NOP, 0, 0), // aA = dyn_cast<aC>(aB); for class types
|
|
xx(DYNCASTC_K, dyncastc, RPRPKP, NOP, 0, 0), // aA = dyn_cast<aKC>(aB);
|
|
|
|
// Control flow.
|
|
xx(TEST, test, RII16, NOP, 0, 0), // if (dA != BC) then pc++
|
|
xx(TESTN, testn, RII16, NOP, 0, 0), // if (dA != -BC) then pc++
|
|
xx(JMP, jmp, I24, NOP, 0, 0), // pc += ABC -- The ABC fields contain a signed 24-bit offset.
|
|
xx(IJMP, ijmp, RII16, NOP, 0, 0), // pc += dA + BC -- BC is a signed offset. The target instruction must be a JMP.
|
|
xx(PARAM, param, __BCP, NOP, 0, 0), // push parameter encoded in BC for function call (B=regtype, C=regnum)
|
|
xx(PARAMI, parami, I24, NOP, 0, 0), // push immediate, signed integer for function call
|
|
xx(CALL, call, RPI8I8, NOP, 0, 0), // Call function pkA with parameter count B and expected result count C
|
|
xx(CALL_K, call, KPI8I8, CALL, 1, REGT_POINTER),
|
|
xx(VTBL, vtbl, RPRPI8, NOP, 0, 0), // dereferences a virtual method table.
|
|
xx(TAIL, tail, RPI8, NOP, 0, 0), // Call+Ret in a single instruction
|
|
xx(TAIL_K, tail, KPI8, TAIL, 1, REGT_POINTER),
|
|
xx(RESULT, result, __BCP, NOP, 0, 0), // Result should go in register encoded in BC (in caller, after CALL)
|
|
xx(RET, ret, I8BCP, NOP, 0, 0), // Copy value from register encoded in BC to return value A, possibly returning
|
|
xx(RETI, reti, I8I16, NOP, 0, 0), // Copy immediate from BC to return value A, possibly returning
|
|
xx(NEW, new, RPRP, NOP, 0, 0),
|
|
xx(NEW_K, new, RPKP, NOP, 0, 0),
|
|
xx(TRY, try, I24, NOP, 0, 0), // When an exception is thrown, start searching for a handler at pc + ABC
|
|
xx(UNTRY, untry, I8, NOP, 0, 0), // Pop A entries off the exception stack
|
|
xx(THROW, throw, THROW, NOP, 0, 0), // A == 0: Throw exception object pB
|
|
// A == 1: Throw exception object pkB
|
|
// A >= 2: Throw VM exception of type BC
|
|
xx(CATCH, catch, CATCH, NOP, 0, 0), // 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
|
|
xx(BOUND, bound, RII16, NOP, 0, 0), // if rA >= BC, throw exception
|
|
xx(BOUND_K, bound, LKI, NOP, 0, 0), // if rA >= const[BC], throw exception
|
|
xx(BOUND_R, bound, RIRI, NOP, 0, 0), // if rA >= rB, throw exception
|
|
|
|
// String instructions.
|
|
xx(CONCAT, concat, RSRSRS, NOP, 0, 0), // sA = sB..sC
|
|
xx(LENS, lens, RIRS, NOP, 0, 0), // dA = sB.Length
|
|
xx(CMPS, cmps, I8RXRX, NOP, 0, 0), // if ((skB op skC) != (A & 1)) then pc++
|
|
|
|
// Integer math.
|
|
xx(SLL_RR, sll, RIRIRI, NOP, 0, 0), // dA = dkB << diC
|
|
xx(SLL_RI, sll, RIRII8, NOP, 0, 0),
|
|
xx(SLL_KR, sll, RIKIRI, SLL_RR, 2, REGT_INT),
|
|
xx(SRL_RR, srl, RIRIRI, NOP, 0, 0), // dA = dkB >> diC -- unsigned
|
|
xx(SRL_RI, srl, RIRII8, NOP, 0, 0),
|
|
xx(SRL_KR, srl, RIKIRI, SRL_RR, 2, REGT_INT),
|
|
xx(SRA_RR, sra, RIRIRI, NOP, 0, 0), // dA = dkB >> diC -- signed
|
|
xx(SRA_RI, sra, RIRII8, NOP, 0, 0),
|
|
xx(SRA_KR, sra, RIKIRI, SRA_RR, 2, REGT_INT),
|
|
xx(ADD_RR, add, RIRIRI, NOP, 0, 0), // dA = dB + dkC
|
|
xx(ADD_RK, add, RIRIKI, ADD_RR, 4, REGT_INT),
|
|
xx(ADDI, addi, RIRIIs, NOP, 0, 0), // dA = dB + C -- C is a signed 8-bit constant
|
|
xx(SUB_RR, sub, RIRIRI, NOP, 0, 0), // dA = dkB - dkC
|
|
xx(SUB_RK, sub, RIRIKI, SUB_RR, 4, REGT_INT),
|
|
xx(SUB_KR, sub, RIKIRI, SUB_RR, 2, REGT_INT),
|
|
xx(MUL_RR, mul, RIRIRI, NOP, 0, 0), // dA = dB * dkC
|
|
xx(MUL_RK, mul, RIRIKI, MUL_RR, 4, REGT_INT),
|
|
xx(DIV_RR, div, RIRIRI, NOP, 0, 0), // dA = dkB / dkC (signed)
|
|
xx(DIV_RK, div, RIRIKI, DIV_RR, 4, REGT_INT),
|
|
xx(DIV_KR, div, RIKIRI, DIV_RR, 2, REGT_INT),
|
|
xx(DIVU_RR, divu, RIRIRI, NOP, 0, 0), // dA = dkB / dkC (unsigned)
|
|
xx(DIVU_RK, divu, RIRIKI, DIVU_RR,4, REGT_INT),
|
|
xx(DIVU_KR, divu, RIKIRI, DIVU_RR,2, REGT_INT),
|
|
xx(MOD_RR, mod, RIRIRI, NOP, 0, 0), // dA = dkB % dkC (signed)
|
|
xx(MOD_RK, mod, RIRIKI, MOD_RR, 4, REGT_INT),
|
|
xx(MOD_KR, mod, RIKIRI, MOD_RR, 2, REGT_INT),
|
|
xx(MODU_RR, modu, RIRIRI, NOP, 0, 0), // dA = dkB % dkC (unsigned)
|
|
xx(MODU_RK, modu, RIRIKI, MODU_RR,4, REGT_INT),
|
|
xx(MODU_KR, modu, RIKIRI, MODU_RR,2, REGT_INT),
|
|
xx(AND_RR, and, RIRIRI, NOP, 0, 0), // dA = dB & dkC
|
|
xx(AND_RK, and, RIRIKI, AND_RR, 4, REGT_INT),
|
|
xx(OR_RR, or, RIRIRI, NOP, 0, 0), // dA = dB | dkC
|
|
xx(OR_RK, or, RIRIKI, OR_RR, 4, REGT_INT),
|
|
xx(XOR_RR, xor, RIRIRI, NOP, 0, 0), // dA = dB ^ dkC
|
|
xx(XOR_RK, xor, RIRIKI, XOR_RR, 4, REGT_INT),
|
|
xx(MIN_RR, min, RIRIRI, NOP, 0, 0), // dA = min(dB,dkC)
|
|
xx(MIN_RK, min, RIRIKI, MIN_RR, 4, REGT_INT),
|
|
xx(MAX_RR, max, RIRIRI, NOP, 0, 0), // dA = max(dB,dkC)
|
|
xx(MAX_RK, max, RIRIKI, MAX_RR, 4, REGT_INT),
|
|
xx(ABS, abs, RIRI, NOP, 0, 0), // dA = abs(dB)
|
|
xx(NEG, neg, RIRI, NOP, 0, 0), // dA = -dB
|
|
xx(NOT, not, RIRI, NOP, 0, 0), // dA = ~dB
|
|
xx(SEXT, sext, RIRII8, NOP, 0, 0), // dA = dB, sign extended by shifting left then right by C
|
|
xx(ZAP_R, zap, RIRIRI, NOP, 0, 0), // dA = dB, with bytes zeroed where bits in C/dC are one
|
|
xx(ZAP_I, zap, RIRII8, NOP, 0, 0),
|
|
xx(ZAPNOT_R, zapnot, RIRIRI, NOP, 0, 0), // dA = dB, with bytes zeroed where bits in C/dC are zero
|
|
xx(ZAPNOT_I, zapnot, RIRII8, NOP, 0, 0),
|
|
xx(EQ_R, beq, CIRR, NOP, 0, 0), // if ((dB == dkC) != A) then pc++
|
|
xx(EQ_K, beq, CIRK, EQ_R, 4, REGT_INT),
|
|
xx(LT_RR, blt, CIRR, NOP, 0, 0), // if ((dkB < dkC) != A) then pc++
|
|
xx(LT_RK, blt, CIRK, LT_RR, 4, REGT_INT),
|
|
xx(LT_KR, blt, CIKR, LT_RR, 2, REGT_INT),
|
|
xx(LE_RR, ble, CIRR, NOP, 0, 0), // if ((dkB <= dkC) != A) then pc++
|
|
xx(LE_RK, ble, CIRK, LE_RR, 4, REGT_INT),
|
|
xx(LE_KR, ble, CIKR, LE_RR, 2, REGT_INT),
|
|
xx(LTU_RR, bltu, CIRR, NOP, 0, 0), // if ((dkB < dkC) != A) then pc++ -- unsigned
|
|
xx(LTU_RK, bltu, CIRK, LTU_RR, 4, REGT_INT),
|
|
xx(LTU_KR, bltu, CIKR, LTU_RR, 2, REGT_INT),
|
|
xx(LEU_RR, bleu, CIRR, NOP, 0, 0), // if ((dkB <= dkC) != A) then pc++ -- unsigned
|
|
xx(LEU_RK, bleu, CIRK, LEU_RR, 4, REGT_INT),
|
|
xx(LEU_KR, bleu, CIKR, LEU_RR, 2, REGT_INT),
|
|
|
|
// Double-precision floating point math.
|
|
xx(ADDF_RR, add, RFRFRF, NOP, 0, 0), // fA = fB + fkC
|
|
xx(ADDF_RK, add, RFRFKF, ADDF_RR,4, REGT_FLOAT),
|
|
xx(SUBF_RR, sub, RFRFRF, NOP, 0, 0), // fA = fkB - fkC
|
|
xx(SUBF_RK, sub, RFRFKF, SUBF_RR,4, REGT_FLOAT),
|
|
xx(SUBF_KR, sub, RFKFRF, SUBF_RR,2, REGT_FLOAT),
|
|
xx(MULF_RR, mul, RFRFRF, NOP, 0, 0), // fA = fB * fkC
|
|
xx(MULF_RK, mul, RFRFKF, MULF_RR,4, REGT_FLOAT),
|
|
xx(DIVF_RR, div, RFRFRF, NOP, 0, 0), // fA = fkB / fkC
|
|
xx(DIVF_RK, div, RFRFKF, DIVF_RR,4, REGT_FLOAT),
|
|
xx(DIVF_KR, div, RFKFRF, DIVF_RR,2, REGT_FLOAT),
|
|
xx(MODF_RR, mod, RFRFRF, NOP, 0, 0), // fA = fkB % fkC
|
|
xx(MODF_RK, mod, RFRFKF, MODF_RR,4, REGT_FLOAT),
|
|
xx(MODF_KR, mod, RFKFRF, MODF_RR,4, REGT_FLOAT),
|
|
xx(POWF_RR, pow, RFRFRF, NOP, 0, 0), // fA = fkB ** fkC
|
|
xx(POWF_RK, pow, RFRFKF, POWF_RR,4, REGT_FLOAT),
|
|
xx(POWF_KR, pow, RFKFRF, POWF_RR,2, REGT_FLOAT),
|
|
xx(MINF_RR, min, RFRFRF, NOP, 0, 0), // fA = min(fB),fkC)
|
|
xx(MINF_RK, min, RFRFKF, MINF_RR,4, REGT_FLOAT),
|
|
xx(MAXF_RR, max, RFRFRF, NOP, 0, 0), // fA = max(fB),fkC)
|
|
xx(MAXF_RK, max, RFRFKF, MAXF_RR,4, REGT_FLOAT),
|
|
xx(ATAN2, atan2, RFRFRF, NOP, 0, 0), // fA = atan2(fB,fC), result is in degrees
|
|
xx(FLOP, flop, RFRFI8, NOP, 0, 0), // fA = f(fB), where function is selected by C
|
|
xx(EQF_R, beq, CFRR, NOP, 0, 0), // if ((fB == fkC) != (A & 1)) then pc++
|
|
xx(EQF_K, beq, CFRK, EQF_R, 4, REGT_FLOAT),
|
|
xx(LTF_RR, blt, CFRR, NOP, 0, 0), // if ((fkB < fkC) != (A & 1)) then pc++
|
|
xx(LTF_RK, blt, CFRK, LTF_RR, 4, REGT_FLOAT),
|
|
xx(LTF_KR, blt, CFKR, LTF_RR, 2, REGT_FLOAT),
|
|
xx(LEF_RR, ble, CFRR, NOP, 0, 0), // if ((fkb <= fkC) != (A & 1)) then pc++
|
|
xx(LEF_RK, ble, CFRK, LEF_RR, 4, REGT_FLOAT),
|
|
xx(LEF_KR, ble, CFKR, LEF_RR, 2, REGT_FLOAT),
|
|
|
|
// Vector math. (2D)
|
|
xx(NEGV2, negv2, RVRV, NOP, 0, 0), // vA = -vB
|
|
xx(ADDV2_RR, addv2, RVRVRV, NOP, 0, 0), // vA = vB + vkC
|
|
xx(SUBV2_RR, subv2, RVRVRV, NOP, 0, 0), // vA = vkB - vkC
|
|
xx(DOTV2_RR, dotv2, RVRVRV, NOP, 0, 0), // va = vB dot vkC
|
|
xx(MULVF2_RR, mulv2, RVRVRF, NOP, 0, 0), // vA = vkB * fkC
|
|
xx(MULVF2_RK, mulv2, RVRVKF, MULVF2_RR,4, REGT_FLOAT),
|
|
xx(DIVVF2_RR, divv2, RVRVRF, NOP, 0, 0), // vA = vkB / fkC
|
|
xx(DIVVF2_RK, divv2, RVRVKF, DIVVF2_RR,4, REGT_FLOAT),
|
|
xx(LENV2, lenv2, RFRV, NOP, 0, 0), // fA = vB.Length
|
|
xx(EQV2_R, beqv2, CVRR, NOP, 0, 0), // if ((vB == vkC) != A) then pc++ (inexact if A & 32)
|
|
xx(EQV2_K, beqv2, CVRK, NOP, 0, 0), // this will never be used.
|
|
|
|
// Vector math (3D)
|
|
xx(NEGV3, negv3, RVRV, NOP, 0, 0), // vA = -vB
|
|
xx(ADDV3_RR, addv3, RVRVRV, NOP, 0, 0), // vA = vB + vkC
|
|
xx(SUBV3_RR, subv3, RVRVRV, NOP, 0, 0), // vA = vkB - vkC
|
|
xx(DOTV3_RR, dotv3, RVRVRV, NOP, 0, 0), // va = vB dot vkC
|
|
xx(CROSSV_RR, crossv, RVRVRV, NOP, 0, 0), // vA = vkB cross vkC
|
|
xx(MULVF3_RR, mulv3, RVRVRF, NOP, 0, 0), // vA = vkB * fkC
|
|
xx(MULVF3_RK, mulv3, RVRVKF, MULVF3_RR,4, REGT_FLOAT),
|
|
xx(DIVVF3_RR, divv3, RVRVRF, NOP, 0, 0), // vA = vkB / fkC
|
|
xx(DIVVF3_RK, divv3, RVRVKF, DIVVF3_RR,4, REGT_FLOAT),
|
|
xx(LENV3, lenv3, RFRV, NOP, 0, 0), // fA = vB.Length
|
|
xx(EQV3_R, beqv3, CVRR, NOP, 0, 0), // if ((vB == vkC) != A) then pc++ (inexact if A & 33)
|
|
xx(EQV3_K, beqv3, CVRK, NOP, 0, 0), // this will never be used.
|
|
|
|
// Pointer math.
|
|
xx(ADDA_RR, add, RPRPRI, NOP, 0, 0), // pA = pB + dkC
|
|
xx(ADDA_RK, add, RPRPKI, ADDA_RR,4, REGT_POINTER),
|
|
xx(SUBA, sub, RIRPRP, NOP, 0, 0), // dA = pB - pC
|
|
xx(EQA_R, beq, CPRR, NOP, 0, 0), // if ((pB == pkC) != A) then pc++
|
|
xx(EQA_K, beq, CPRK, EQA_R, 4, REGT_POINTER),
|
|
|
|
#undef xx
|