RRR (OP u 8) (X u 8) (Y u 8) (Z u 8) RSR (OP u 8) (X u 8) (Y s 8) (Z u 8) J26 (OP u 8) (XYZ j 24) U16R (OP u 8) (XY u 16) (Z u 8) J18R (OP u 8) (XY j 16) (Z u 8) 0x01 RRR : halt %X ulm_halt(ulm_regVal(X)); 0x02 RRR : getc %X ulm_setReg(ulm_readChar() & 0xFF, X); 0x03 RRR : putc %X ulm_printChar(ulm_regVal(X) & 0xFF); 0x04 J26 : jmp XYZ ulm_unconditionalRelJump(XYZ); 0x05 RRR : subq X, %Y, %Z ulm_sub64(X, ulm_regVal(Y), Z); 0x06 J26 : jnz XYZ : jne XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0, XYZ); 0x07 J26 : jz XYZ : je XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 1, XYZ); 0x08 U16R : ldzwq XY, %Z ulm_setReg(XY, Z); 0x09 RSR : movzbq Y(%X), %Z : movzbq (%X), %Z ulm_fetch64(Y, X, 0, 0, ULM_ZERO_EXT, 1, Z); 0x0A RRR : addq X, %Y, %Z ulm_add64(X, ulm_regVal(Y), Z); 0x0B RRR : imulq %X, %Y, %Z ulm_mul64(ulm_regVal(X), ulm_regVal(Y), Z); 0x0C J26 : ja XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_ZF] == 0 && ulm_statusReg[ULM_CF] == 0, XYZ); 0x0D J26 : jb XYZ ulm_conditionalRelJump(ulm_statusReg[ULM_CF] == 1, XYZ); 0x0E RRR : addq %X, %Y, %Z : movq %X, %Z ulm_add64(ulm_regVal(X), ulm_regVal(Y), Z); 0x0F RRR : imulq X, %Y, %Z ulm_mul64(X, ulm_regVal(Y), Z); 0x10 RRR # Uses the 128-bit unsigned integer divider. The 64-bits stored in %Y are # therefore zero extended with %0 to 128 bits and then used as numerator. # The immediate value X is used as unsigned denominator. # # The result of the operation is the quotient and the remainder. These results # will be stored in a register pair: The quotient is stored in %Z and the # remainder in %{Z + 1}. : divq X, %Y, %Z ulm_div128(X, ulm_regVal(Y), ulm_regVal(0), Z, 0, Z + 1); 0x11 RSR # The least significant byte in %X gets stored at address %Z. : movb %X, Y(%Z) : movb %X, (%Z) ulm_store64(Y, Z, 0, 0, 1, X); 0x12 RSR # Fetches a quad word from address %X into register %Z : movq Y(%X), %Z : movq (%X), %Z ulm_fetch64(Y, X, 0, 0, ULM_ZERO_EXT, 8, Z); 0x13 RRR : putc X ulm_printChar(X & 0xFF); # void ulm_absJump(uint64_t destAddr, ulm_Reg ret); 0x14 RRR : jmp %X, %Y : call %X, %Y : ret %X ulm_absJump(ulm_regVal(X), Y); 0x15 U16R : shldwq XY, %Z ulm_setReg(ulm_regVal(Z) << 16 | XY, Z); 0x16 J18R : ldpa XY, %Z ulm_setReg(ulm_ipVal() + XY, Z); 0x17 RRR : ldfp Y(%X), %Z : ldfp (%X), %Z ulm_fetch64(Y * 8, X, 0, 0, ULM_ZERO_EXT, 8, Z); 0x18 RRR : subq %X, %Y, %Z ulm_sub64(ulm_regVal(X), ulm_regVal(Y), Z); 0x19 RSR : movq %X, Y(%Z) : movq %X, (%Z) ulm_store64(Y, Z, 0, 0, 8, X); 0x1A RRR # Uses the 128-bit unsigned integer divider. The 64-bits stored in %Y are # therefore zero extended with %0 to 128 bits and then used as numerator. # The value %X is used as unsigned denominator. # # The result of the operation is the quotient and the remainder. These results # will be stored in a register pair: The quotient is stored in %Z and the # remainder in %{Z + 1}. : divq %X, %Y, %Z ulm_div128(ulm_regVal(X), ulm_regVal(Y), ulm_regVal(0), Z, 0, Z + 1); # General meaning of the mnemonics @addq # Integer addition. @getc # Get character @divq # 64-bit unsigned integer division @halt # Halt program @imulq # 64-bit unsigned and signed integer multiplication. @ja # Jump if above (conditional jump). @jb # Jump if below (conditional jump). @je # Jump if equal (conditional jump). @jmp # Jump (unconditional jump). @jne # Jump if not equal (conditional jump). @jnz # Jump if not zero (conditional jump). @jz # Jump if zero (conditional jump). @ldzwq # Load zero extended word to quad word register. @putc # Put character @subq # Integer subtraction. @movb # Move a byte from a register to memory (store instruction). @movzbq # Move zero extended byte to quad word register (fetch instruction). @movq # Move quad word @shldwq # Shift (destination register) and load word @ldpa # Load Pool Address @ldfp # Load from Pool