#ifndef xx #define xx(op, name, mode) OP_##op #endif xx(NOP, nop, NOP), // no operation // 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(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(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 (B=regtype, C=regnum) xx(PARAMI, parami, I24), // push immediate, signed integer for function call xx(CALL, call, RPI8I8), // Call function pkA with parameter count B and expected result count C xx(CALL_K, call, KPI8I8), xx(TAIL, tail, RPI8), // Call+Ret in a single instruction xx(TAIL_K, tail, KPI8), 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(RETI, reti, I8I16), // Copy immediate from 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 == 1: Throw exception object pkB // A >= 2: Throw VM exception of type BC 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 == ) then pc++ ; next instruction must JMP to another CATCH // A == 3: (pkB == ) then pc++ ; next instruction must JMP to another CATCH // for A > 0, exception is stored in pC xx(BOUND, bound, RII16), // if rA >= BC, throw exception // 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, addi, 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, beq, CIRR), // if ((dB == dkC) != A) then pc++ xx(EQ_K, beq, CIRK), xx(LT_RR, blt, CIRR), // if ((dkB < dkC) != A) then pc++ xx(LT_RK, blt, CIRK), xx(LT_KR, blt, CIKR), xx(LE_RR, ble, CIRR), // if ((dkB <= dkC) != A) then pc++ xx(LE_RK, ble, CIRK), xx(LE_KR, ble, CIKR), xx(LTU_RR, bltu, CIRR), // if ((dkB < dkC) != A) then pc++ -- unsigned xx(LTU_RK, bltu, CIRK), xx(LTU_KR, bltu, CIKR), xx(LEU_RR, bleu, CIRR), // if ((dkB <= dkC) != A) then pc++ -- unsigned xx(LEU_RK, bleu, CIRK), xx(LEU_KR, bleu, CIKR), // 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(ATAN2, atan2, RFRFRF), // fA = atan2(fB,fC), result is in degrees xx(FLOP, flop, RFRFI8), // fA = f(fB), where function is selected by C xx(EQF_R, beq, CFRR), // if ((fB == fkC) != (A & 1)) then pc++ xx(EQF_K, beq, CFRK), xx(LTF_RR, blt, CFRR), // if ((fkB < fkC) != (A & 1)) then pc++ xx(LTF_RK, blt, CFRK), xx(LTF_KR, blt, CFKR), xx(LEF_RR, ble, CFRR), // if ((fkb <= fkC) != (A & 1)) then pc++ xx(LEF_RK, ble, CFRK), xx(LEF_KR, ble, CFKR), // 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, beqv, CVRR), // if ((vB == vkC) != A) then pc++ (inexact if A & 32) xx(EQV_K, beqv, CVRK), // 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, beq, CPRR), // if ((pB == pkC) != A) then pc++ xx(EQA_K, beq, CPRK), #undef xx