The instruction set of the System X virtual machine is based on Donald Knuth's imaginary MMIX computer architecture. The instructions are interpreted and executed by the System X virtual machine written in C++.
MMIX instructions operate with different kinds of values:
Notation:
MMIX instructions have four bytes:
The instructions have the following formats:
$X, $Y and $Z are register operands. For example LDO $X, $Y, $Z instruction loads an octabyte value from address $Y + $Z and sets it as the value of register $X.
$X and $Y are register operands, and Z is an immediate byte operand. For example LDOI $X, $Y, Z instruction loads an octabyte value from memory address $Y + Z and sets it as the value of register $X.
X, Y and Z byte operands. For example TRAP X, Y, Z instruction calls operating system trap number X, Y, Z where X, Y and Z are interpreted as immediate bytes. Currently in System X bytes X and Z are zeros and Y is the number of virtual operating system function called.
$X and $Z are register operands. For example FIX $X, $Z instruction converts value of register $Z interpreted as a double to an integer octabyte value and places it as the value of register $X.
$X is a register operand and Z is immediate byte operand. For example FLOTI $X, Z instruction converts a integer byte Z to a floating-point number and sets it as the value of register $X.
$X is a register operand, Y is an immediate byte operand, and $Z is a register operand. For example NEG $X, Y, $Z instruction subtracts the value of register $Z from immediate byte Y and sets is as the value of register $X.
$X is a register operand, and Y and Z are an immediate byte operands. For example NEGI $X, Y, Z instruction subtracts immediate byte Z from immediate byte Y and sets is as the value of register $X.
$X is a register operand, and RA = 4 * (256 * Y + Z) is a relative address. For example BN $X, RA instruction branches to an instruction whose address is RA bytes ahead of the current instruction position if the value of register $X is negative.
X is immediate byte operand, $Y and $Z are register operands. For example the STCO X, $Y, $Z instruction stores a constant byte value X to a memory address $Y + $Z, where $Y and $Z are values of registers $Y and $Z respectively.
X and Z are immediate byte operands, and $Y is a register operand For example the STCOI X, $Y, Z instruction stores a constant byte value X to a memoy address $Y + Z, where $Y is the value of register $Y and Z is an immediate byte value.
$X is a register operand and YZ is interpreted as the wyde value 256 * Y + Z. For example the SETH $X, YZ instruction sets the value YZ as the high wyde value of register $X.
Operands X, Y and Z are interpreted as a long relative address LRA = 4 * (256 * 256 * X + 256 * Y + Z). For example the JMP LRA instruction jumps to an instruction whose address is LRA bytes ahead a of the current instruction position.
X is an immediate byte operand and $Z is a register operand. For example the PUT X, $Z instruction puts the value of register $Z as the value of the special registers number X.
X and Z are immediate byte operands. For example PUTI X, Z instruction puts the value Z as the value of the special register number X.
Instruction OP has no operands. For example the SWYM instruction is a no-operation regardless of the operands X, Y, and Z.
Instructions CALL, CALLI and RET have changed semantics with respect to the original PUSHGO, PUSHGOI and POP instructions of MMIX so they have been renamed.
The CALL instruction has format 9: CALL X, $Y, $Z. It
The CALLI instruction has format 10: CALLI X, $Y, Z. It operates the same way as the CALL instruction except it treats the Z as an immediate byte, so it transfers control to memory address $Y + Z.
The RET instruction has format 15: RET. It
MMIX has 256 global registers of which the first 32 are special and have special names. The values of the special registers can be set using the PUT instruction and read using the GET instruction.
MMIX has 256 local registers numbered $0, $1, ..., $255.
Global register:
Register usage:
The number of local registers used in the intermediate language implementation can be configured in the sx.machine.config.xml file that is located in the cmajor/config subdirectory. The default number of local registers used is numLocalRegs=8.
implementation status: Y = implemented, N = not implemented, C = semantics changed
OP | code | implementation status | instruction name | instruction format |
---|---|---|---|---|
TRAP | #00 | Y | operating system trap | 3. |
FCMP | #01 | Y | floating compare | 1. |
FUN | #02 | N | - | |
FEQL | #03 | Y | floating equal | 1. |
FADD | #04 | Y | floating add | 1. |
FIX | #05 | Y | floating to fixed | 4. |
FSUB | #06 | Y | floating subtract | 1. |
FIXU | #07 | Y | floating to fixed unsigned | 4. |
FLOT | #08 | Y | fixed to floating | 4. |
FLOTI | #09 | Y | fixed to floating immediate | 5. |
FLOTU | #0A | Y | fixed to floating unsigned | 4. |
FLOTUI | #0B | Y | fixed to floating unsigned immediate | 5. |
SFLOT | #0C | Y | fixed to short float | 4. |
SFLOTI | #0D | Y | fixed to short float immediate | 5. |
SFLOTU | #0E | Y | fixed to short float unsigned | 4. |
SFLOTUI | #0F | Y | fixed to short float unsigned immediate | 5. |
FMUL | #10 | Y | floating multiply | 1. |
FCMPE | #11 | N | - | |
FUNE | #12 | N | - | |
FEQLE | #13 | N | - | |
FDIV | #14 | Y | floating division | 1. |
FSQRT | #15 | Y | floating square root | 4. |
FREM | #16 | Y | floating remainder | 1. |
FINT | #17 | Y | floating integer | 4. |
MUL | #18 | Y | multiply | 1. |
MULI | #19 | Y | multiply immediate | 2. |
MULU | #1A | Y | multiply unsigned | 1. |
MULUI | #1B | Y | multiply unsigned immediate | 2. |
DIV | #1C | Y | divide | 1. |
DIVI | #1D | Y | divide immediate | 2. |
DIVU | #1E | Y | divide unsigned | 1. |
DIVUI | #1F | Y | divide unsigned immediate | 2. |
ADD | #20 | Y | add | 1. |
ADDI | #21 | Y | add immediate | 2. |
ADDU | #22 | Y | add unsigned | 1. |
ADDUI | #23 | Y | add unsigned immediate | 2. |
SUB | #24 | Y | subtract | 1. |
SUBI | #25 | Y | subtract immediate | 2. |
SUBU | #26 | Y | subtract unsigned | 1. |
SUBUI | #27 | Y | subtract unsigned immediate | 2. |
2ADDU | #28 | Y | times 2 and add unsigned | 1. |
2ADDUI | #29 | Y | times 2 and add unsigned immediate | 2. |
4ADDU | #2A | Y | times 4 and add unsigned | 1. |
4ADDUI | #2B | Y | times 4 and add unsigned immediate | 2. |
8ADDU | #2C | Y | times 8 and add unsigned | 1. |
8ADDUI | #2D | Y | times 8 and add unsigned immediate | 2. |
16ADDU | #2E | Y | times 16 and add unsigned | 1. |
16ADDUI | #2F | Y | times 16 and add unsigned immediate | 2. |
CMP | #30 | Y | compare | 1. |
CMPI | #31 | Y | compare immediate | 2. |
CMPU | #32 | Y | compare unsigned | 1. |
CMPUI | #33 | Y | compare unsigned immediate | 2. |
NEG | #34 | Y | negate | 6. |
NEGI | #35 | Y | negate immediate | 7. |
NEGU | #36 | Y | negate unsigned | 6. |
NEGUI | #37 | Y | negate unsigned immediate | 7. |
SL | #38 | Y | shift left | 1. |
SLI | #39 | Y | shift left immediate | 2. |
SLU | #3A | Y | shift left unsigned | 1. |
SLUI | #3B | Y | shift left unsigned immediate | 2. |
SR | #3C | Y | shift right | 1. |
SRI | #3D | Y | shift right immediate | 2. |
SRU | #3E | Y | shift right unsigned | 1. |
SRUI | #3F | Y | shift right unsigned immediate | 2. |
BN | #40 | Y | branch if negative | 8. |
BNB | #41 | Y | branch if negative backwards | 8. |
BZ | #42 | Y | branch if zero | 8. |
BZB | #43 | Y | branch if zero backwards | 8. |
BP | #44 | Y | branch if positive | 8. |
BPB | #45 | Y | branch if positive backwards | 8. |
BOD | #46 | Y | branch if odd | 8. |
BODB | #47 | Y | branch if odd backwards | 8. |
BNN | #48 | Y | branch if nonnegative | 8. |
BNNB | #49 | Y | branch if nonnegative backwards | 8. |
BNZ | #4A | Y | branch if nonzero | 8. |
BNZB | #4B | Y | branch if nonzero backwards | 8. |
BNP | #4C | Y | branch if nonpositive | 8. |
BNPB | #4D | Y | branch if nonpositive backwards | 8. |
BEV | #4E | Y | branch if even | 8. |
BEVB | #4F | Y | branch if even backwards | 8. |
PBN | #50 | Y | probable branch if negative | 8. |
PBNB | #51 | Y | probable branch if negative backwards | 8. |
PBZ | #52 | Y | probable branch if zero | 8. |
PBZB | #53 | Y | probable branch if zero backwards | 8. |
PBP | #54 | Y | probable branch if positive | 8. |
PBPB | #55 | Y | probable branch if positive backwards | 8. |
PBOD | #56 | Y | probable branch if odd | 8. |
PBODB | #57 | Y | probable branch if odd backwards | 8. |
PBNN | #58 | Y | probable branch if nonnegative | 8. |
PBNNB | #59 | Y | probable branch if nonnegative backwards | 8. |
PBNZ | #5A | Y | probable branch if nonzero | 8. |
PBNZB | #5B | Y | probable branch if nonzero backwards | 8. |
PBNP | #5C | Y | probable branch if nonpositive | 8. |
PBNPB | #5D | Y | probable branch if nonpositive backwards | 8. |
PBEV | #5E | Y | probable branch if even | 8. |
PBEVB | #5F | Y | probable branch if even backwards | 8. |
CSN | #60 | Y | conditional set if negative | 1. |
CSNI | #61 | Y | conditional set if negative immediate | 2. |
CSZ | #62 | Y | conditional set if zero | 1. |
CSZI | #63 | Y | conditional set if zero immediate | 2. |
CSP | #64 | Y | conditional set if positive | 1. |
CSPI | #65 | Y | conditional set if positive immediate | 2. |
CSOD | #66 | Y | conditional set if odd | 1. |
CSODI | #67 | Y | conditional set if odd immediate | 2. |
CSNN | #68 | Y | conditional set if nonnegative | 1. |
CSNNI | #69 | Y | conditional set if nonnegative immediate | 2. |
CSNZ | #6A | Y | conditional set if nonzero | 1. |
CSNZI | #6B | Y | conditional set if nonzero immediate | 2. |
CSNP | #6C | Y | conditional set if nonpositive | 1. |
CSNPI | #6D | Y | conditional set if nonpositive immediate | 2. |
CSEV | #6E | Y | conditional set if even | 1. |
CSEVI | #6F | Y | conditional set if even immediate | 2. |
ZSN | #70 | Y | zero or set if negative | 1. |
ZSNI | #71 | Y | zero or set if negative immediate | 2. |
ZSZ | #72 | Y | zero or set if zero | 1. |
ZSZI | #73 | Y | zero or set if zero immediate | 2. |
ZSP | #74 | Y | zero or set if positive | 1. |
ZSPI | #75 | Y | zero or set if positive immediate | 2. |
ZSOD | #76 | Y | zero or set if odd | 1. |
ZSODI | #77 | Y | zero or set if odd immediate | 2. |
ZSNN | #78 | Y | zero or set if nonnegative | 1. |
ZSNNI | #79 | Y | zero or set if nonnegative immediate | 2. |
ZSNZ | #7A | Y | zero or set if nonzero | 1. |
ZSNZI | #7B | Y | zero or set if nonzero immediate | 2. |
ZSNP | #7C | Y | zero or set if nonpositive | 1. |
ZSNPI | #7D | Y | zero or set if nonpositive immediate | 2. |
ZSEV | #7E | Y | zero or set if even | 1. |
ZSEVI | #7F | Y | zero or set if even immediate | 2. |
LDB | #80 | Y | load byte | 1. |
LDBI | #81 | Y | load byte immediate | 2. |
LDBU | #82 | Y | load byte unsigned | 1. |
LDBUI | #83 | Y | load byte unsigned immediate | 2. |
LDW | #84 | Y | load wyde | 1. |
LDWI | #85 | Y | load wyde immediate | 2. |
LDWU | #86 | Y | load wyde unsigned | 1. |
LDWUI | #87 | Y | load wyde unsigned immediate | 2. |
LDT | #88 | Y | load tetra | 1. |
LDTI | #89 | Y | load tetra immediate | 2. |
LDTU | #8A | Y | load tetra unsigned | 1. |
LDTUI | #8B | Y | load tetra unsigned immediate | 2. |
LDO | #8C | Y | load octa | 1. |
LDOI | #8D | Y | load octa immediate | 2. |
LDOU | #8E | Y | load octa unsigned | 1. |
LDOUI | #8F | Y | load octa unsigned immediate | 2. |
LDSF | #90 | Y | load short float | 1. |
LDSFI | #91 | Y | load short float immediate | 2. |
LDHT | #92 | Y | load high tetra | 1. |
LDHTI | #93 | Y | load high tetra immediate | 2. |
CSWAP | #94 | N | - | |
CSWAPI | #95 | N | - | |
LDUNC | #96 | N | - | |
LDUNCI | #97 | N | - | |
LDVTS | #98 | N | - | |
LDVTSI | #99 | N | - | |
PRELD | #9A | N | - | |
PRELDI | #9B | N | - | |
PREGO | #9C | N | - | |
PREGOI | #9D | N | - | |
GO | #9E | Y | go | 1. |
GOI | #9F | Y | go immediate | 2. |
STB | #A0 | Y | store byte | 1. |
STBI | #A1 | Y | store byte immediate | 2. |
STBU | #A2 | Y | store byte unsigned | 1. |
STBUI | #A3 | Y | store byte unsigned immediate | 2. |
STW | #A4 | Y | store wyde | 1. |
STWI | #A5 | Y | store wyde immediate | 2. |
STWU | #A6 | Y | store wyde unsigned | 1. |
STWUI | #A7 | Y | store wyde unsigned immediate | 2. |
STT | #A8 | Y | store tetra | 1. |
STTI | #A9 | Y | store tetra immediate | 2. |
STTU | #AA | Y | store tetra unsigned | 1. |
STTUI | #AB | Y | store tetra unsigned immediate | 2. |
STO | #AC | Y | store octa | 1. |
STOI | #AD | Y | store octa immediate | 2. |
STOU | #AE | Y | store octa unsigned | 1. |
STOUI | #AF | Y | store octa unsigned immediate | 2. |
STSF | #B0 | Y | store short float | 1. |
STSFI | #B1 | Y | store short float immediate | 2. |
STHT | #B2 | Y | store high tetra | 1. |
STHTI | #B3 | Y | store high tetra immediate | 2. |
STCO | #B4 | Y | store constant | 9. |
STCOI | #B5 | Y | store constant immediate | 10. |
STUNC | #B6 | N | - | |
STUNCI | #B7 | N | - | |
SYNCD | #B8 | N | - | |
SYNCDI | #B9 | N | - | |
PREST | #BA | N | - | |
PRESTI | #BB | N | - | |
SYNCID | #BC | N | - | |
SYNCIDI | #BD | N | - | |
CALL | #BE | C | call subroutine | 9. |
CALLI | #BF | C | call subroutine immediate | 10. |
OR | #C0 | Y | bitwise or | 1. |
ORI | #C1 | Y | bitwise or immediate | 2. |
ORN | #C2 | Y | bitwise or not | 1. |
ORNI | #C3 | Y | bitwise or not immediate | 2. |
NOR | #C4 | Y | bitwise not or | 1. |
NORI | #C5 | Y | bitwise not or immediate | 2. |
XOR | #C6 | Y | bitwise exclusive or | 1. |
XORI | #C7 | Y | bitwise exclusive or immediate | 2. |
AND | #C8 | Y | bitwise and | 1. |
ANDI | #C9 | Y | bitwise and immediate | 2. |
ANDN | #CA | Y | bitwise and not | 1. |
ANDNI | #CB | Y | bitwise and not immediate | 2. |
NAND | #CC | Y | bitwise not and | 1. |
NANDI | #CD | Y | bitwise not and immediate | 2. |
NXOR | #CE | Y | bitwise not exclusive or | 1. |
NXORI | #CF | Y | bitwise not exclusive or immediate | 2. |
BDIF | #D0 | Y | byte difference | 1. |
BDIFI | #D1 | Y | byte difference immediate | 2. |
WDIF | #D2 | Y | wyde difference | 1. |
WDIFI | #D3 | Y | wyde difference immediate | 2. |
TDIF | #D4 | Y | tetra difference | 1. |
TDIFI | #D5 | Y | tetra difference immediate | 2. |
ODIF | #D6 | Y | octa difference | 1. |
ODIFI | #D7 | Y | octa difference immediate | 2. |
MUX | #D8 | Y | bitwise multiplex | 1. |
MUXI | #D9 | Y | bitwise multiplex immediate | 2. |
SADD | #DA | Y | sideways add | 1. |
SADDI | #DB | Y | sideways add immediate | 2. |
MOR | #DC | Y | multiple or | 1. |
MORI | #DD | Y | multiple or immediate | 2. |
MXOR | #DE | Y | multiple excludive or | 1. |
MXORI | #DF | Y | multiple excludive or immediate | 2. |
SETH | #E0 | Y | set high wyde | 11. |
SETMH | #E1 | Y | set medium high wyde | 11. |
SETML | #E2 | Y | set medium low wyde | 11. |
SETL | #E3 | Y | set low wyde | 11. |
INCH | #E4 | Y | increment high wyde | 11. |
INCMH | #E5 | Y | increment medium high wyde | 11. |
INCML | #E6 | Y | increment medium low wyde | 11. |
INCL | #E7 | Y | increment low wyde | 11. |
ORH | #E8 | Y | bitwise or high wyde | 11. |
ORMH | #E9 | Y | bitwise or medium high wyde | 11. |
ORML | #EA | Y | bitwise or medium low wyde | 11. |
ORL | #EB | Y | bitwise or low wyde | 11. |
ANDNH | #EC | Y | bitwise and not high wyde | 11. |
ANDNMH | #ED | Y | bitwise and not medium high wyde | 11. |
ANDNML | #EE | Y | bitwise and not medium low wyde | 11. |
ANDNL | #EF | Y | bitwise and not low wyde | 11. |
JMP | #F0 | Y | jump | 12. |
JMPB | #F1 | Y | jump backwards | 12. |
PUSHJ | #F2 | N | - | |
PUSHJB | #F3 | N | - | |
GETA | #F4 | Y | get address | 8. |
GETAB | #F5 | Y | get address backwards | 8. |
PUT | #F6 | Y | put to special register | 13. |
PUTI | #F7 | N | put special register immediate | 14. |
RET | #F8 | C | return from subroutine | 15. |
RESUME | #F9 | N | - | |
SAVE | #FA | N | - | |
UNSAVE | #FB | N | - | |
SYNC | #FC | N | - | |
SWYM | #FD | Y | sympathize with your machinery | 15. |
GET | #FE | Y | get from special register | 5. |
TRIP | #FF | N | - |