Chapter 7: Instruction Reference
This chapter is normative and is the core of the specification. It documents every instruction in the opcode map, grouped by function. Floating-point instructions are documented in Chapter 8; section 7.10 cross-references them.
7.0 How to read an entry
Every entry pins the same five items, and none is left implementation-defined:
- Operation: the one-line semantics.
- Forms: each addressing-mode opcode (
$xx) and its operand shape. The mode-bit scheme is Chapter 5 section 5.1;regVal/immVal/regAddr/immAddrare the four source forms. Forms not listed for an instruction are reserved encodings. - Flags: the effect on each of C, N, V, Z, and P, by operand width where it differs.
- Encoding: the opcode byte plus operand-byte layout (Chapter 6).
- Traps: which trap cause the instruction can raise, or "none" (Chapter 10).
Flag notation. The five arithmetic/logic flags are C (carry/borrow), N (negative), V (signed overflow), Z (zero), and P (parity/unordered). The flag layout is Chapter 2 section 2.4. P is written by exactly one instruction, FCMP (Chapter 8); every other instruction in this chapter leaves P unaffected, and each entry states so explicitly. "unaffected" means the bit keeps its prior value. Unless an entry's Flags line says otherwise, the flags are computed over the destination operand's selected subregister width (byte / qword / hword / word), and the sign bit N, the overflow test V, and the zero test Z are taken at that width.
Common trap facts. An undefined opcode byte is the illegal-instruction trap (cause 0),
as is the undefined subregister selector $F on any operand (illegal-operand trap, cause 0;
Chapter 3 section 3.3). The undefined immediate-size field 4..7 does not trap; it decodes to
the value-initialized default (Chapter 6 section 6.6). Where an entry says "Traps: none", the
instruction raises no synchronous trap for any defined operand encoding or value.
7.1 Data movement
These instructions move data without arithmetic. None of them affects any flag (C/N/V/Z/P all unaffected), matching x86 MOV / ARM / RISC-V, so a compare and its dependent branch may be separated by data moves. CP / CPZ / LD / ST are the enforced memory boundary (Chapter 5 section 5.5).
RF as a destination in user mode. RF is operand-addressable, so any of these (CP / CPZ / LD / CLR / POP) may name RF as its destination. When such a write executes in user mode (privilege bit clear), the privileged RF.H1 bits (privilege, interrupt-enabled, interrupt-set, running, syscall-guest) are masked: they keep their current values while only the non-privileged RF.H0 condition flags take the written value. A user instruction thus cannot set the privilege bit by writing RF directly; the mask raises no fault (a benign flag write still lands). Supervisor writes are unmasked. See section 7.9 for the full privilege model.
CP (copy)
- Operation: copy the source value into the destination register, sign-extended to the destination subregister width (Chapter 5 section 5.6). Never touches memory.
- Forms:
$01CP regVal reg;$41CP immVal reg. (No address forms: a copy never reads memory. Base slot$01is shared with LD, which owns the address forms.) - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, source operand byte, destination operand byte, then immediate bytes for the immVal form.
- Traps: none.
CPZ (copy, zero-extended)
- Operation: copy the source value into the destination register, zero-extended to the destination width. Never touches memory.
- Forms:
$13CPZ regVal reg;$53CPZ immVal reg. (The address forms$93/$D3are LDZ, the zero-extending load; see the LDZ entry below.) - Flags: C/N/V/Z/P unaffected.
- Encoding: as CP.
- Traps: none.
LDZ (load, zero-extended)
- Operation: read from a memory address into the destination register, exactly like LD
(the number of bytes read is fixed by the destination subregister width), then
zero-extend the result into the full destination register, clearing the bytes above
the loaded value rather than preserving them. Equivalent to
LD dst.<width>followed byCPZ dst.<width> dst, in one instruction (card maize-204). - Forms:
$93LDZ regAddr reg (address in a register);$D3LDZ immAddr reg (immediate address). Shares CPZ's base slot$13the way LD shares CP's$01; only the two address forms are defined. - Flags: C/N/V/Z/P unaffected.
- Encoding: as LD.
- Traps: none. A read of never-written memory returns 0; misaligned reads are defined-allow.
LD (load)
- Operation: read from a memory address into the destination register. The number of bytes read is fixed by the destination subregister width, landing in that field and preserving the rest of the register (Chapter 3 section 3.4). A load never over-reads past its source address, and LD itself never zero-extends (the surrounding bits are preserved); the zero-extending load is a separate instruction, LDZ (see above).
- Forms:
$81LD regAddr reg (address in a register);$C1LD immAddr reg (immediate address). - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, source operand byte (the address register, or immediate-size for the immAddr form), destination operand byte, then immediate address bytes for immAddr.
- Traps: none. A read of never-written memory returns 0 (Chapter 4 section 4.3); misaligned reads are defined-allow (section 4.4).
ST (store)
- Operation: write a register value or immediate to a memory address. The number of bytes written is the source's selected width.
- Forms:
$02ST regVal regAddr (register value to address in a register);$42ST immVal regAddr (immediate value to address in a register). - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, source operand byte, destination (address) operand byte, then immediate bytes for immVal.
- Traps: none. A store to never-written memory allocates a zero-filled block (section 4.3); misaligned stores are defined-allow.
CLR (clear)
- Operation: set the destination to zero. A bare register destination writes the full W0 (a clean 0 with no stale upper bits); an explicit subregister writes only that field and preserves the rest.
- Forms:
$32CLR regVal (register-only; row 0 of base$32). - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, one register operand byte.
- Traps: none.
LEA (load effective address)
- Operation: compute operand1 + operand2 and store the sum in operand3. Address
arithmetic; no memory is dereferenced for the value forms.
LEA $-08 BP RTputsBP - 8in RT. - Forms (three operands):
$12LEA regVal reg reg;$52LEA immVal reg reg;$92LEA regAddr reg reg;$D2LEA immAddr reg reg. Operand1 is the addend (value / immediate / value-at-address), operand2 the base register, operand3 the destination. - Flags: C/N/V/Z/P unaffected (address computation never sets flags).
- Encoding: opcode byte, operand1 byte, operand2 byte, operand3 byte, then immediate bytes for the immediate forms.
- Traps: none.
XCHG (exchange)
- Operation: atomically exchange the values of two registers.
- Forms:
$E0XCHG reg reg (register-only; single encoding). - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, two register operand bytes.
- Traps: none.
PUSH
- Operation: push the source onto the stack. The stack is full-descending: RS (SP) is pre-decremented by the operand's size, then the value is written at RS.
- Forms:
$20PUSH regVal;$60PUSH immVal. - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, source operand byte, then immediate bytes for immVal.
- Traps: none. (See section 7.8 for the stack model.)
POP
- Operation: pop the top of the stack into the destination register: copy the value at RS into the register, then increment RS by the register's size.
- Forms:
$72POP regVal (register-only; row 1 of base$32). - Flags: C/N/V/Z/P unaffected.
- Encoding: opcode byte, one register operand byte.
- Traps: none.
7.2 Integer arithmetic
Unless an entry says otherwise, these set C/N/V/Z over the destination width and leave P
unaffected. Integer overflow wraps two's-complement and is observed through C and V, never
a trap (Chapter 10). All four addressing-mode source forms exist for the binary ALU ops
(regVal $0x, immVal $4x, regAddr $8x, immAddr $Cx) unless noted.
ADD
- Operation: destination = destination + source.
- Forms:
$03regVal reg,$43immVal reg,$83regAddr reg,$C3immAddr reg. - Flags: C = unsigned carry-out; N = sign of result; V = signed overflow; Z = result is zero; P unaffected.
- Encoding: opcode byte, source operand byte, destination register byte, immediate bytes for immediate forms.
- Traps: none.
SUB
- Operation: destination = destination - source.
- Forms:
$04regVal reg,$44immVal reg,$84regAddr reg,$C4immAddr reg. - Flags: C = unsigned borrow (set when destination was unsigned-less-than source); N; V = signed overflow; Z; P unaffected.
- Traps: none.
MUL
- Operation: destination = low half of (destination * source). Keeps only the low half of the product; for the full double-width product use MULW / UMULW.
- Forms:
$05regVal reg,$45immVal reg,$85regAddr reg,$C5immAddr reg. - Flags: V = signed overflow (product does not fit the destination width); C = V (C mirrors the overflow flag); N = sign of the low-half result; Z = result is zero; P unaffected.
- Traps: none.
MULW (signed wide multiply)
- Operation: full double-width signed product of operand2 by the source; low half to operand2, high half to operand3.
- Forms (three operands):
$3DregVal reg reg,$7DimmVal reg reg,$BDregAddr reg reg,$FDimmAddr reg reg. - Flags: C = high half nonzero (the product spilled out of the low register); N = sign bit of the whole double-width product; V = true signed overflow (the product does not fit the low register's signed range); Z = the entire product is zero; P unaffected.
- Traps: none.
UMULW (unsigned wide multiply)
- Operation: full double-width unsigned product of operand2 by the source; low half to operand2, high half to operand3.
- Forms:
$3EregVal reg reg,$7EimmVal reg reg,$BEregAddr reg reg,$FEimmAddr reg reg. - Flags: C = high half nonzero; V = C; N = sign bit of the whole product; Z = entire product is zero; P unaffected.
- Traps: none.
DIV (signed divide)
- Operation: destination = destination / source, signed, truncated toward zero.
- Forms:
$06regVal reg,$46immVal reg,$86regAddr reg,$C6immAddr reg. - Flags: C = 0 (cleared); V = 0 (cleared); N = sign of result; Z = result is zero; P unaffected.
- Traps: divide error (cause 2) on a zero divisor (subcode 0) or the signed
INT_MIN / -1quotient overflow (subcode 1). Fault-class; captures the DIV instruction's PC. Unhandled, the machine halts deterministically with cause 2 surfaced.
MOD (signed remainder)
- Operation: destination = destination mod source, signed; the remainder takes the sign of the dividend.
- Forms:
$07regVal reg,$47immVal reg,$87regAddr reg,$C7immAddr reg. - Flags: C = 0; V = 0; N = sign of result; Z = result is zero; P unaffected.
- Traps: divide error (cause 2), as DIV.
UDIV (unsigned divide)
- Operation: destination = destination / source, unsigned.
- Forms:
$35regVal reg,$75immVal reg,$B5regAddr reg,$F5immAddr reg. - Flags: C = 0; V = 0; N = sign of result (the high bit of the unsigned quotient at the destination width); Z = result is zero; P unaffected.
- Traps: divide error (cause 2) on a zero divisor (subcode 0). Unsigned division has no quotient-overflow case.
UMOD (unsigned remainder)
- Operation: destination = destination mod source, unsigned.
- Forms:
$36regVal reg,$76immVal reg,$B6regAddr reg,$F6immAddr reg. - Flags: C = 0; V = 0; N; Z; P unaffected.
- Traps: divide error (cause 2) on a zero divisor.
INC
- Operation: destination = destination + 1.
- Forms:
$31regVal (register-only; row 0 of base$31). - Flags: C = unsigned carry-out; N; V = signed overflow; Z; P unaffected. (Add-family flags.)
- Traps: none.
DEC
- Operation: destination = destination - 1.
- Forms:
$71regVal (row 1 of base$31). - Flags: C = unsigned borrow; N; V = signed overflow; Z; P unaffected. (Sub-family flags.)
- Traps: none.
NEG (two's-complement negate)
- Operation: destination = 0 - destination.
- Forms:
$F1regVal (row 3 of base$31). - Flags: sub-family flags computed as
0 - value: C is set when the value is non-zero (a borrow occurs for any non-zero operand); N = sign of the result; V is set only for the width's most-negative value (whose negation overflows); Z = result is zero; P unaffected. - Traps: none.
ADC (add with carry)
- Operation: destination = destination + source + C. The low word of a multi-word add runs ADD (which sets C); each higher word runs ADC.
- Forms:
$3BregVal reg,$7BimmVal reg,$BBregAddr reg,$FBimmAddr reg. - Flags: C = unsigned carry-out of the full
dst + src + C; N; V = signed overflow; Z reflects only the current word (a full-width zero test ANDs the per-word Z results across the chain); P unaffected. - Traps: none.
SBB (subtract with borrow)
- Operation: destination = destination - source - C. The low word runs SUB; each higher word runs SBB.
- Forms:
$3CregVal reg,$7CimmVal reg,$BCregAddr reg,$FCimmAddr reg. - Flags: C = unsigned borrow of the full
dst - src - C; N; V = signed overflow; Z reflects only the current word; P unaffected. - Traps: none.
7.3 Logic
Bitwise operations. All set C = 0 and V = 0 (cleared), compute N and Z over the destination width, and leave P unaffected. Full four source forms for the binary ops.
AND
- Operation: destination = destination AND source.
- Forms:
$08regVal reg,$48immVal reg,$88regAddr reg,$C8immAddr reg. - Flags: C = 0; V = 0; N = sign of result; Z = result is zero; P unaffected.
- Traps: none.
OR
- Operation: destination = destination OR source.
- Forms:
$09regVal reg,$49immVal reg,$89regAddr reg,$C9immAddr reg. - Flags: C = 0; V = 0; N; Z; P unaffected.
- Traps: none.
XOR
- Operation: destination = destination XOR source.
- Forms:
$0CregVal reg,$4CimmVal reg,$8CregAddr reg,$CCimmAddr reg. - Flags: C = 0; V = 0; N; Z; P unaffected.
- Traps: none.
NAND
- Operation: destination = NOT (destination AND source).
- Forms:
$0BregVal reg,$4BimmVal reg,$8BregAddr reg,$CBimmAddr reg. - Flags: C = 0; V = 0; N; Z; P unaffected.
- Traps: none.
NOR
- Operation: destination = NOT (destination OR source).
- Forms:
$0AregVal reg,$4AimmVal reg,$8AregAddr reg,$CAimmAddr reg. - Flags: C = 0; V = 0; N; Z; P unaffected.
- Traps: none.
NOT (one's complement)
- Operation: destination = NOT destination (bitwise one's complement).
- Forms:
$B1regVal (register-only; row 2 of base$31). - Flags: C = 0; V = 0; N; Z; P unaffected.
- Traps: none.
7.4 Shift
Shift counts are defined for every value (Chapter 10): a count of 0 leaves all flags unaffected; the over-width behavior is stated per instruction. An out-of-range count never invokes host undefined behavior. All shifts leave P unaffected. Full four source forms.
SHL (shift left)
- Operation: destination = destination << source.
- Forms:
$0DregVal reg,$4DimmVal reg,$8DregAddr reg,$CDimmAddr reg. - Flags: for count
nover operand widthbits:n == 0leaves all flags unaffected;1 <= n <= bitsshifts normally with C = the last bit shifted out, N = sign of result, Z, and V defined only forn == 1(V = the sign bit changed);n > bitsyields result 0 with C = 0, N = 0, V = 0, Z = 1. P unaffected throughout. - Traps: none.
SHR (logical shift right)
- Operation: destination = destination >> source (zero-fill).
- Forms:
$0EregVal reg,$4EimmVal reg,$8EregAddr reg,$CEimmAddr reg. - Flags:
n == 0leaves flags unaffected;1 <= n <= bitsshifts with C = last bit shifted out, N = sign of result, Z, and V defined only forn == 1(V = the prior sign bit);n > bitsyields result 0 with C = N = V = 0, Z = 1. P unaffected. - Traps: none.
SAR (arithmetic shift right)
- Operation: destination = destination >> source with sign replication (the sign bit fills the vacated high bits).
- Forms:
$2EregVal reg,$6EimmVal reg,$AEregAddr reg,$EEimmAddr reg. - Flags:
n == 0leaves flags unaffected;1 <= n <= bits-1shifts right with sign replicated, C = the last bit shifted out (bitn-1of the operand), V = 0 always (an arithmetic shift replicates the sign and can never flip it), N = sign, Z;n >= bitssaturates to the sign fill: all-ones (the width's -1) for a negative operand or 0 for a non-negative one, with C = the operand's sign bit, N = the operand's sign, V = 0, and Z set only for a non-negative operand. P unaffected. This over-width behavior diverges from SHR, whose over-width count returns 0. - Traps: none.
7.5 Compare and test
These compute flags without writing a general register. Full source forms as noted.
CMP
- Operation: set flags by computing destination - source, discarding the difference.
- Forms:
$0FregVal reg,$4FimmVal reg,$8FregAddr reg,$CFimmAddr reg. - Flags: identical to SUB: C = unsigned borrow, N, V = signed overflow, Z; P unaffected. The C borrow convention is what makes JB/JA the correct unsigned branches and V the signed ones (Chapter 2 section 2.4).
- Traps: none.
CMPIND (compare indirect)
- Operation: set flags by computing (value at the address in the destination register) minus the source. Compares against a value in memory.
- Forms:
$2FregVal regAddr;$6FimmVal regAddr. - Flags: SUB-family: C = unsigned borrow, N, V, Z; P unaffected.
- Traps: none.
TEST
- Operation: set flags by computing destination AND source, discarding the result.
- Forms:
$10regVal reg,$50immVal reg,$90regAddr reg,$D0immAddr reg. - Flags: logic-family: C = 0, V = 0, N = sign of the AND, Z = the AND is zero; P unaffected.
- Traps: none.
TSTIND (test indirect)
- Operation: set flags by ANDing the source with the value at the address in the destination register.
- Forms:
$30regVal regAddr;$70immVal regAddr. - Flags: logic-family: C = 0, V = 0, N, Z; P unaffected.
- Traps: none.
CMPXCHG (compare-and-swap)
- Operation: the frozen compare-and-swap primitive. Three operands
CMPXCHG new target expected(operand1 = new value, operand2 = target, operand3 = expected). Compare the target (operand2) against the expected value (operand3) over the selected subregister width. On equality (success): set Z = 1 and copy the new value (operand1) into the target (operand2). On inequality (failure): set Z = 0 and copy the current target (operand2) into the expected register (operand3), handing the caller the observed value for a retry loop. - Forms:
$11regVal reg reg;$51immVal reg reg;$91regAddr reg reg;$D1immAddr reg reg (operand1 varies; target and expected are always registers). - Flags: Z is the sole and authoritative success indicator (1 = swapped, 0 = not swapped). C, N, V, and P are unaffected: the equality test writes no flag and the copy is flag-neutral. A caller tests success with JZ / JNZ.
- Encoding: opcode byte, operand1 byte, operand2 byte, operand3 byte, then immediate bytes for the immediate forms.
- Traps: none. Under single-hart v1.0 the operation is trivially atomic; a conforming multi-hart v1.x implementation must keep it an atomic CAS with exactly these effects (Chapter 12 section 2).
FCMP (floating-point compare) -- the only writer of P
- Operation: compare the destination floating-point value against the source and set the integer flags per the IEEE-754 outcome. Documented fully in Chapter 8; summarized here because it is the sole instruction that writes the P flag.
- Forms:
$2AregVal reg,$6AimmVal reg,$AAregAddr reg,$EAimmAddr reg. - Flags: FCMP computes C, Z, and P together and forces N = 0 and V = 0. The mapping
(x86 UCOMISD convention):
a > src-> C=0 Z=0 P=0;a < src-> C=1 Z=0 P=0;a == src-> C=0 Z=1 P=0; unordered (either operand NaN) -> C=1 Z=1 P=1. P is the unordered / NaN indicator and is written only here; JP and SETP consume it. After FCMP the ordered branch idioms JB/JBE/JA/JAE/JZ work directly, and JP/SETP test the unordered case (Chapter 8). - Traps: none for arithmetic (FP exceptions are sticky, not trapping); illegal FP operand encodings trap cause 0. See Chapter 8.
7.6 Conditional set (SETcc)
SETcc materializes a condition as 0 or 1 in a destination register. It reads the flags and is flag-neutral: it writes no flag (C/N/V/Z/P all unaffected). A bare register destination writes the full W0 (a clean 0/1, no stale upper bits); an explicit subregister writes only that field and preserves the rest, exactly like CLR. Each predicate is identical to the matching Jcc branch (section 7.7), so a SETcc and its branch can never disagree for the same flag state. Each is a register-only instruction, one register operand.
| Mnemonic | Opcode | Condition | Predicate |
|---|---|---|---|
| SETZ | $2B | equal / zero | Z == 1 |
| SETNZ | $2C | not-equal / nonzero | Z == 0 |
| SETLT | $2D | signed < | N != V |
| SETGE | $AB | signed >= | N == V |
| SETGT | $6C | signed > | Z == 0 and N == V |
| SETLE | $AC | signed <= | Z == 1 or N != V |
| SETB | $6B | unsigned < | C == 1 |
| SETAE | $EB | unsigned >= | C == 0 |
| SETA | $6D | unsigned > | C == 0 and Z == 0 |
| SETBE | $AD | unsigned <= | C == 1 or Z == 1 |
| SETP | $EC | unordered (FCMP NaN) | P == 1 |
- Traps: none for the defined encodings. An unallocated condition encoding in the SETcc
family (for example the reserved
$ED) is the illegal-instruction trap (cause 0, subcode 1). SETP ($EC) is defined (it claims one of the reserved spare condition encodings and reads P); the remaining spare$EDstays reserved.
mazm also accepts assembler-only synonyms that emit the identical opcode as their
canonical form (byte-identical after assembly): SETE=SETZ, SETNE=SETNZ, SETL/SETNGE=SETLT,
SETNL=SETGE, SETG/SETNLE=SETGT, SETNG=SETLE, SETC/SETNAE=SETB, SETNC/SETNB=SETAE,
SETNBE=SETA, SETNA=SETBE.
7.7 Control flow
Control-transfer targets are always full 64-bit addresses. Jumps and calls do not affect any flag (C/N/V/Z/P unaffected); the conditional branches read flags but write none.
JMP (unconditional jump)
- Operation: set PC to the target and continue. JMP targets the full 64-bit width
regardless of any operand subregister selection;
mazmrejects a JMP operand carrying a subregister suffix. - Forms:
$16regVal (address in a register),$56immVal (immediate address),$96regAddr (address pointed to by a register),$D6immAddr (address pointed to by an immediate). - Flags: C/N/V/Z/P unaffected.
- Traps: none.
Jcc (conditional branches)
- Operation: if the condition holds, set PC to the immediate target; else fall through. Immediate target only (the register/indirect conditional forms are synthesized as an inverted Jcc over JMP). Each shares its predicate with the matching SETcc (section 7.6).
- Forms and conditions (each
immVal):
| Mnemonic | Opcode | Branch taken when |
|---|---|---|
| JZ | $17 | Z == 1 (equal / zero) |
| JNZ | $18 | Z == 0 |
| JLT | $19 | N != V (signed <) |
| JGE | $97 | N == V (signed >=) |
| JGT | $58 | Z == 0 and N == V (signed >) |
| JLE | $98 | Z == 1 or N != V (signed <=) |
| JB | $57 | C == 1 (unsigned <) |
| JAE | $D7 | C == 0 (unsigned >=) |
| JA | $59 | C == 0 and Z == 0 (unsigned >) |
| JBE | $99 | C == 1 or Z == 1 (unsigned <=) |
| JP | $D8 | P == 1 (FCMP unordered / NaN) |
- Flags: read, none written. C/N/V/Z/P unaffected.
- Encoding: opcode byte, immediate-size source operand byte, immediate target bytes.
- Traps: none for the defined encodings. An unallocated condition encoding in the Jcc
family (for example the reserved
$D9) is the illegal-instruction trap (cause 0, subcode 1). JP ($D8) is defined and reads P;$D9stays reserved.
CALL
- Operation: push the return address (the address of the following instruction, a full 64-bit value) onto the stack (pre-decrementing RS), then jump to the target. Execution continues until a RET. Unlike JMP (which always reads the whole target register), CALL honors the operand subregister: the register form reads the operand's selected subregister and zero-extends it into the full-width PC, and the immediate form zero-extends the immediate at its encoded width. The address forms dereference a full 64-bit target from memory.
- Forms:
$1DregVal,$5DimmVal,$9DregAddr,$DDimmAddr. - Flags: C/N/V/Z/P unaffected.
- Traps: none.
RET
- Operation: pop the return address from the stack into PC and continue there (incrementing RS). Returns from CALL.
- Forms:
$27(zero-operand; row 0 of base$27). - Flags: C/N/V/Z/P unaffected.
- Traps: none.
JP / SETP
JP ($D8) is listed in the Jcc table above and SETP ($EC) in the SETcc table; both read
the P flag set by FCMP (Chapter 8). JNP / SETNP are synthesized by branch inversion (no
dedicated opcode).
7.8 Stack
The stack is full-descending with pre-decrement on push. RS (SP) always points at the last value pushed. The stack instructions are PUSH and POP (section 7.1) and CALL and RET (section 7.7):
- PUSH src: RS -= size(src); write src at RS.
- POP dst: read dst from RS; RS += size(dst).
- CALL target: RS -= 8; write the return address at RS; PC = target.
- RET: PC = value at RS; RS += 8.
Return addresses are 8-byte (full 64-bit). At process start RS points at the process-start block's argc slot; the first push moves RS just below the block (Chapter 4 section 4.5). There is no stack-limit check in the v1.0 flat model; a stack-fault trap (cause 6) is reserved for the future segment/bounds work (Chapter 12).
7.9 System and privileged instructions
Instructions marked (privileged) require the RF privilege bit set. Executed in user mode (privilege bit clear) they raise the privileged-operation fault (cause 4). Enforcement is live (card maize-180): a head-of-dispatch privilege gate is applied at every privileged instruction below, and a trap or interrupt entry raises privilege to supervisor for the handler, so the handler's own IRET runs privileged and drops back to user by restoring a saved RF whose privilege bit is clear. The enforced privileged set is IN / OUT / OUTR, MOVTCR / MOVFCR, TLBINV / TLBINVA, SETINT / CLRINT, SETSYSG / CLRSYSG, IRET, and HALT. INT is privileged but has no active dispatch in v1.0, so its fault applies once its dispatch lands; future segment-write and other control instructions join the set as they land.
The privilege boundary also covers the direct-write vector. RF is an operand-addressable destination register, so the gate above is not enough on its own: a user-mode guest write that names RF as its destination (CP / LD / POP / CPZ / CLR, or an ALU write-back) has its privileged RF.H1 bits (privilege, interrupt-enabled, interrupt-set, running, syscall-guest) masked, they keep their current values while only the non-privileged condition flags (RF.H0: C / N / V / Z / P) take the written value. This is the x86 POPF-in-user model: a user instruction cannot set the privilege bit by writing RF directly, and the masking raises no fault, so a benign user-mode flag write still succeeds. Supervisor-mode RF writes are unmasked (this is what lets a handler's IRET restore the full saved RF).
SYS (system call)
- Operation: enter the kernel syscall dispatcher with the syscall index in the operand. A deliberate synchronous software trap; trap-class (captures the following-instruction PC, so IRET resumes after SYS). SYS is not privileged: it is the deliberate user-to-supervisor entry, so user-mode code calls it to request kernel service. The syscall number and arguments travel in registers per the syscall ABI (Appendix C). Today the reference VM dispatches SYS directly to the BIOS/syscall surface; routing it through the shared trap table at vector 7 is the future path (Chapter 10).
- Forms:
$34regVal (index in a register),$74immVal (immediate index). The index is a single byte (operand.b0). - Flags: the instruction itself sets no arithmetic/logic flag (a syscall's effects on RV and errno are the ABI's, not a flag effect). C/N/V/Z/P unaffected by the dispatch.
- Traps: reserved as cause 7 (SYS / syscall entry). Not a privileged instruction, so it never raises the cause-4 privileged-operation fault.
INT (software interrupt)
- Operation: raise a software interrupt at the given vector index, entering through the shared trap frame (Chapter 10): the entry sequence pushes PC, then the full RF word, then the cause and aux words. Privileged. The dispatch is deferred until the vector-table format exists; INT has no active dispatch case in v1.0.
- Forms:
$24regVal (index in a register),$64immVal (immediate index). - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode. INT has no active dispatch in v1.0, so this fault applies once its dispatch lands.
IRET (interrupt return)
- Operation: the shared return path for both traps and interrupts (there is no TRET).
IRET pops the full RF word (
RF.w0, including the privileged RF.H1 bits) and then PC, the two low words of the shared aux/cause/RF/PC trap frame (the handler having already removed aux and cause). Restoring the full RF, including the interrupt-enable bit, re-enables interrupts on a normal handler return. Privileged. - Forms:
$67(zero-operand; row 1 of base$27). - Flags: RF (and thus C/N/V/Z/P) is restored from the saved frame, not computed.
- Traps: privileged-operation fault (cause 4) in user mode. Making IRET privileged closes the forged-RF escalation: only supervisor code (which every trap/interrupt handler is, since entry raises privilege) can execute it, so user code cannot forge a privileged RF word on its stack and IRET into supervisor mode (card maize-180).
SETINT / CLRINT
- Operation: SETINT sets the RF interrupt-enable bit (enabling maskable external interrupts); CLRINT clears it. Privileged.
- Forms: SETINT
$29(row 0 of base$29); CLRINT$69(row 1). Zero-operand. - Flags: the arithmetic/logic flags C/N/V/Z/P are unaffected (these write RF.H1).
- Traps: privileged-operation fault (cause 4) in user mode.
SETCRY / CLRCRY
- Operation: SETCRY sets the Carry flag to 1; CLRCRY clears it to 0. The direct software controls over C used to seed a multi-word ADC/SBB chain.
- Forms: SETCRY
$A9(row 2 of base$29); CLRCRY$E9(row 3). Zero-operand. - Flags: C = 1 (SETCRY) or C = 0 (CLRCRY); N, V, Z, P unaffected.
- Traps: none. (Not privileged; C is a user-mode arithmetic flag.)
SETSYSG / CLRSYSG (syscall-provider select, privileged)
- Operation: SETSYSG sets the RF syscall-guest bit; CLRSYSG clears it (card maize-24). The
bit selects which provider SYS dispatches to: clear (boot default) calls the native
sys::callprovider byte-identical to v1.0; set routes SYS through the shared trap table at cause 7 into a guest-installed handler (the syscall number rides the frame's aux word; args and result use the R0/R1/R2/RV ABI). A resident guest kernel toggles the bit around a re-issued SYS to pass calls through to the native provider. Privileged. - Forms: SETSYSG
$A4(row 2 of base$24); CLRSYSG$E4(row 3). Zero-operand. - Flags: the arithmetic/logic flags C/N/V/Z/P are unaffected (these write RF.H1).
- Traps: privileged-operation fault (cause 4) in user mode.
IN (port input, privileged)
- Operation: read a value from the device on the selected port into the destination
register. The port id is the low 16 bits (
.q0) of the port operand. An IN from an unpopulated port yields 0 (Chapter 11). - Forms:
$1FregVal reg,$5FimmVal reg,$9FregAddr reg,$DFimmAddr reg (the first operand names the port; the destination is always a register). - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
OUT (port output, immediate port, privileged)
- Operation: write the source value (register / immediate / value-at-address) to the device on the port named by the trailing immediate. Writing to an unpopulated port is discarded (Chapter 11).
- Forms:
$14regVal imm,$54immVal imm,$94regAddr imm,$D4immAddr imm. - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
OUTR (port output, register port, privileged)
- Operation: OUT with the port named by a register operand rather than an immediate. The
port id is the port register's
.q0. - Forms:
$1EregVal reg,$5EimmVal reg,$9EregAddr reg,$DEimmAddr reg. - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
MOVTCR (move to control register, privileged)
- Operation: write a value into the control register named by the immediate CR index
crn. The control-register file is a small, privileged, flat-indexed bank reached only through MOVTCR / MOVFCR, distinct from device ports and the syscall surface: CR0SATP(address-translation control), CR1FAULT_VA, CR2FAULT_ERR(Chapter 12). A write to an undefined CR index (> 2) is discarded, mirroring the unpopulated-port convention. CR0SATPis live (card maize-194): writing MODE = 1 (Sv48) into bits [3:0] with a root page-table PPN in bits [63:12] activates the 4-level Sv48 walk on every subsequent guest memory access; MODE = 0 (Bare, the reset default) is the identity passthrough. A CR0 write also flushes the whole software TLB. Reserved SATP bits [11:4] are forced to 0 on write. - Forms:
$26regVal-imm (MOVTCR Rsrc, crn, source in a register, trailing immediate CR index),$66immVal-imm (MOVTCR imm, crn, immediate source).$E6reserved. - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
MOVFCR (move from control register, privileged)
- Operation: read the control register named by the leading immediate CR index
crninto the destination register. A read from an undefined CR index (> 2) yields 0, mirroring the unpopulated-port read-0 convention. - Forms:
$A6immVal-reg (MOVFCR crn, Rdst, leading immediate CR index, trailing destination register). The opcode is fixed: unlike IN, the$26row bit is a slot selector, not an addressing-mode tag. - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
TLBINV (invalidate all TLB entries, privileged)
- Operation: invalidate every software-TLB entry (card maize-194). The 64-entry direct-mapped software TLB caches successful level-0 (4 KiB) Sv48 leaf translations; this instruction clears every entry, forcing a fresh walk on the next access to any VA. (A CR0 SATP write flushes the whole TLB implicitly; TLBINV is the explicit same-address-space flush after a kernel edits a live page table.)
- Forms:
$28(zero-operand). - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
TLBINVA (invalidate one TLB entry, privileged)
- Operation: invalidate the single software-TLB entry whose tag is the VA in the register operand, shifted right by the page size (card maize-194). Used after a kernel edits one page's mapping, to drop just that VA's cached translation without flushing the whole TLB.
- Forms:
$68regVal (one register operand naming the VA).$A8/$E8reserved. - Flags: C/N/V/Z/P unaffected.
- Traps: privileged-operation fault (cause 4) in user mode.
HALT
- Operation: halt the clock, stopping execution pending an interrupt. With no interrupt
source a halted core has nothing to wake it, so the run loop returns and the host process
exits 0 with no recorded status (distinct from the status-carrying SYS $3C exit; Appendix
C). Pinned at opcode
$00so a run of zeroed memory halts. Privileged. - Forms:
$00(zero-operand). - Flags: C/N/V/Z/P unaffected (the running bit in RF.H1 clears).
- Traps: privileged-operation fault (cause 4) in user mode.
BRK (breakpoint)
- Operation: a defined breakpoint trap. Trap-class: captures the following-instruction
PC, so a debugger that resumes lands after the BRK. Pinned at
$FF, the value that fills erased/uninitialized memory, so a run of$FFbytes reached as code raises a breakpoint rather than wandering, mirroring HALT at$00. - Forms:
$FF(zero-operand). - Flags: C/N/V/Z/P unaffected.
- Traps: breakpoint (cause 3). Unhandled, the machine halts deterministically with cause 3 surfaced and the following instruction does not execute.
NOP
- Operation: no operation; an instruction placeholder.
- Forms:
$A7(zero-operand; row 2 of base$27). - Flags: C/N/V/Z/P unaffected.
- Traps: none.
7.10 Floating-point (cross-reference to Chapter 8)
The floating-point instructions are documented in Chapter 8 (Zfinx, FCSR, NaN/rounding, the FCMP flag mapping): the arithmetic ops FADD / FSUB / FMUL / FDIV; the unary ops FSQRT / FNEG / FABS; the fused multiply ops FMADD / FMSUB; the min/max ops FMIN / FMAX; the compare FCMP (the sole writer of the P flag, summarized in section 7.5); the conversions FCVTFF / FCVTFS / FCVTFU / FCVTSF / FCVTUF; the FCSR-access ops FGETCSR / FSETCSR; and the unordered predicates JP / SETP (listed in sections 7.7 and 7.6). FP arithmetic exceptions are sticky in the FCSR FFLAGS and never trap; only illegal FP encodings/operands trap (cause 0). The integer flags C/N/V/Z are untouched by every FP instruction except FCMP, and P is written only by FCMP.
Sourcing
- Opcode map and forms: README "Instructions" and "Opcodes Sorted Numerically"; Appendix A;
src/maize_cpu.hinstrnamespace (lines ~442-843). - Flag effects: README "Per-instruction flag effects" table and its Notes;
src/cpu.cpprun_aluand its width-case blocks (ADD/SUB/ADC/SBB/MUL/MULW/UMULW/DIV/MOD/shift/logic, lines ~1022 onward),do_fcmpfor P (lines ~1001-1019). The zero-flag-only CMPXCHG contract isdocs/spec/reservations.mdsection 2 and the reference dispatch. - Condition predicates:
src/cpu.cppeval_condition(lines ~781-800), shared by Jcc and SETcc; README SETcc/Jcc tables. - Trap behavior:
docs/spec/trap-model.md(Chapter 10); README "Trap Model". Divide error:raise_divide_error(cpu.cpp ~921). Breakpoint:raise_breakpoint(~935). Privileged and port I/O:docs/spec/device-surface.md(Chapter 11).