Spin Bytcodes ------------- The Spin language is compiled into bytecodes that are executed by a Spin interpreter. The Spin interpreter is a stack-based virtual machine that uses a stack to store parameters that are used by operators, such as add, sub, etc. The operators store their results back onto the stack. There are other operators that transfer data back and forth between the stack and hub RAM. The Spin bytecodes are listed below. They are separated into three groups -- lower, hub RAM and math operators. The lower group contains a mix of operators, including those that handle program flow, lookup, lookdown, case, and several other miscellaneous functions. The math operators implement the various math and logic functions that use two arguments. The hub RAM operators implement load, store, effect and reference functions. A load operation reads data from the hub RAM and pushes it onto the stack. A store operation pops a value off the stack and stores it in RAM. The reference operator is used to push the absolute address of a hub RAM location onto the stack. The effect operation is used to execute a unary operation on the referenced RAM location. The result can be pushed to the stack if the unary operator specifies it. The unary operators are not currently described in this document, but will be added at a later date. The format of the hub RAM operators is as follows: operation = {ld, st, ef, re}, size = {b, w, l}, type = {i, l, o, a, v, s} mode = {c, x, 0, 1, t} The operations are load, store, effect and reference as stated earlier. The size refers to byte, word and long. The types are immediate, local, object, absolute, variable and stack. The modes are compact, indexed, zero, one and true (or minus 1). As an example, the instruction ldwi means load-word-immediate. It will load an immediate value onto the stack. The instruction stba will store a byte at the absolute address residing in the stack. There are compact instructions that use a single byte to address the first 8 long values residing in the method's stack frame or in an object's variable space. These use the size, type and mode characters "llc". As an example, the method result value can be set with the "stllc 0" instruction. The fourth long in the objet's variable section could be loaded with "ldllc 3". LOWER OPERATORS --------------- frameret $00 OP_NONE framenoret $01 OP_NONE frameabort $02 OP_NONE frametrash $03 OP_NONE jmp $04 OP_SIGNED_JMP_OFFSET call $05 OP_BYTE_LITERAL callobj $06 OP_OBJ_CALL_PAIR callobjx $07 OP_OBJ_CALL_PAIR tjz $08 OP_SIGNED_JMP_OFFSET djnz $09 OP_SIGNED_JMP_OFFSET jz $0a OP_SIGNED_JMP_OFFSET jnz $0b OP_SIGNED_JMP_OFFSET jmps $0c OP_NONE cmpcase $0d OP_SIGNED_OFFSET cmpcaserange $0e OP_SIGNED_OFFSET lookabort $0f OP_NONE lookupcmp $10 OP_NONE lookdncmp $11 OP_NONE loopuprcmp $12 OP_NONE lookdnrcmp $13 OP_NONE quit $14 OP_NONE mark $15 OP_NONE strsize $16 OP_NONE strcomp $17 OP_NONE bytefill $18 OP_NONE wordfill $19 OP_NONE longfill $1a OP_NONE waitpeq $1b OP_NONE bytemove $1c OP_NONE wordmove $1d OP_NONE longmove $1e OP_NONE waitpne $1f OP_NONE clkset $20 OP_NONE cogstop $21 OP_NONE lockret $22 OP_NONE waitcnt $23 OP_NONE ldlsx $24 OP_NONE stlsx $25 OP_NONE eflsx $26 OP_EFFECT waitvid $27 OP_NONE coginitret $28 OP_NONE locknewret $29 OP_NONE locksetret $2a OP_NONE lockclrret $2b OP_NONE coginit $2c OP_NONE locknew $2d OP_NONE lockset $2e OP_NONE lockclr $2f OP_NONE abort $30 OP_NONE abortret $31 OP_NONE ret $32 OP_NONE popret $33 OP_NONE ldlit $34 OP_NONE ldli0 $35 OP_NONE ldli1 $36 OP_NONE ldlpi $37 OP_PACKED_LITERAL ldbi $38 OP_BYTE_LITERAL ldwi $39 OP_WORD_LITERAL ldmi $3a OP_NEAR_LONG_LITERAL ldli $3b OP_LONG_LITERAL unused $3c OP_NONE rwregx $3d OP_MEMORY_OPCODE rwregx $3d OP_MEMORY_OPCODE rwregrangex $3e OP_MEMORY_OPCODE ldmem $3f OP_MEMORY_OPCODE_READ stmem $3f OP_MEMORY_OPCODE_WRITE HUB RAM OPERATORS ----------------- ldlvc $40 OP_COMPACT_OFFSET stlvc $41 OP_COMPACT_OFFSET eflvc $42 OP_EFFECT reflvc $43 OP_COMPACT_OFFSET ldllc $60 OP_COMPACT_OFFSET stllc $61 OP_COMPACT_OFFSET efllc $62 OP_EFFECT rellc $63 OP_COMPACT_OFFSET ldba $80 OP_NONE stba $81 OP_NONE efba $82 OP_EFFECT reba $83 OP_NONE ldbo $84 OP_UNSIGNED_OFFSET stbo $85 OP_UNSIGNED_OFFSET efbo $86 OP_UNSIGNED_EFFECTED_OFFSET rebo $87 OP_UNSIGNED_OFFSET ldbv $88 OP_UNSIGNED_OFFSET stbv $89 OP_UNSIGNED_OFFSET efbv $8a OP_UNSIGNED_EFFECTED_OFFSET rebv $8b OP_UNSIGNED_OFFSET ldblx $8c OP_UNSIGNED_OFFSET stblx $8d OP_UNSIGNED_OFFSET efblx $8e OP_UNSIGNED_EFFECTED_OFFSET reblx $8f OP_UNSIGNED_OFFSET ldbax $90 OP_NONE stbax $91 OP_NONE efbax $92 OP_EFFECT rebax $93 OP_NONE ldbox $94 OP_UNSIGNED_OFFSET stbox $95 OP_UNSIGNED_OFFSET efbox $96 OP_UNSIGNED_EFFECTED_OFFSET rebox $97 OP_UNSIGNED_OFFSET ldbvx $98 OP_UNSIGNED_OFFSET stbvx $99 OP_UNSIGNED_OFFSET efbvx $9a OP_UNSIGNED_EFFECTED_OFFSET rebvx $9b OP_UNSIGNED_OFFSET ldblx $9c OP_UNSIGNED_OFFSET stblx $9d OP_UNSIGNED_OFFSET efblx $9e OP_UNSIGNED_EFFECTED_OFFSET reblx $9f OP_UNSIGNED_OFFSET ldwa $a0 OP_NONE stwa $a1 OP_NONE efwa $a2 OP_EFFECT rewa $a3 OP_NONE ldwo $a4 OP_UNSIGNED_OFFSET stwo $a5 OP_UNSIGNED_OFFSET efwo $a6 OP_UNSIGNED_EFFECTED_OFFSET rewo $a7 OP_UNSIGNED_OFFSET ldwv $a8 OP_UNSIGNED_OFFSET stwv $a9 OP_UNSIGNED_OFFSET efwv $aa OP_UNSIGNED_EFFECTED_OFFSET rewv $ab OP_UNSIGNED_OFFSET ldwl $ac OP_UNSIGNED_OFFSET stwl $ad OP_UNSIGNED_OFFSET efwl $ae OP_UNSIGNED_EFFECTED_OFFSET rewl $af OP_UNSIGNED_OFFSET ldwax $b0 OP_NONE stwax $b1 OP_NONE efwax $b2 OP_EFFECT rewax $b3 OP_NONE ldwox $b4 OP_UNSIGNED_OFFSET stwox $b5 OP_UNSIGNED_OFFSET efwox $b6 OP_UNSIGNED_EFFECTED_OFFSET rewox $b7 OP_UNSIGNED_OFFSET ldwvx $b8 OP_UNSIGNED_OFFSET stwvx $b9 OP_UNSIGNED_OFFSET efwvx $ba OP_UNSIGNED_EFFECTED_OFFSET rewvx $bb OP_UNSIGNED_OFFSET ldwlx $bc OP_UNSIGNED_OFFSET stwlx $bd OP_UNSIGNED_OFFSET efwlx $be OP_UNSIGNED_EFFECTED_OFFSET rewlx $bf OP_UNSIGNED_OFFSET ldla $c0 OP_NONE stla $c1 OP_NONE efla $c2 OP_EFFECT rela $c3 OP_NONE ldlo $c4 OP_UNSIGNED_OFFSET stlo $c5 OP_UNSIGNED_OFFSET eflo $c6 OP_UNSIGNED_EFFECTED_OFFSET relo $c7 OP_UNSIGNED_OFFSET ldlv $c8 OP_UNSIGNED_OFFSET stlv $c9 OP_UNSIGNED_OFFSET eflv $ca OP_UNSIGNED_EFFECTED_OFFSET relv $cb OP_UNSIGNED_OFFSET ldll $cc OP_UNSIGNED_OFFSET stll $cd OP_UNSIGNED_OFFSET efll $ce OP_UNSIGNED_EFFECTED_OFFSET rell $cf OP_UNSIGNED_OFFSET ldlax $d0 OP_NONE stlax $d1 OP_NONE eflax $d2 OP_EFFECT relax $d3 OP_NONE ldlox $d4 OP_UNSIGNED_OFFSET stlox $d5 OP_UNSIGNED_OFFSET eflox $d6 OP_UNSIGNED_EFFECTED_OFFSET relox $d7 OP_UNSIGNED_OFFSET ldlvx $d8 OP_UNSIGNED_OFFSET stlvx $d9 OP_UNSIGNED_OFFSET eflvx $da OP_UNSIGNED_EFFECTED_OFFSET relvx $db OP_UNSIGNED_OFFSET ldllx $dc OP_UNSIGNED_OFFSET stllx $dd OP_UNSIGNED_OFFSET efllx $de OP_UNSIGNED_EFFECTED_OFFSET rellx $df OP_UNSIGNED_OFFSET MATH OPERATORS -------------- ror $e0 OP_NONE rol $e1 OP_NONE shr $e2 OP_NONE shl $e3 OP_NONE min $e4 OP_NONE max $e5 OP_NONE neg $e6 OP_NONE com $e7 OP_NONE and $e8 OP_NONE abs $e9 OP_NONE or $ea OP_NONE xor $eb OP_NONE add $ec OP_NONE sub $ed OP_NONE sar $ee OP_NONE rev $ef OP_NONE andl $f0 OP_NONE encode $f1 OP_NONE orl $f2 OP_NONE decode $f3 OP_NONE mul $f4 OP_NONE mulh $f5 OP_NONE div $f6 OP_NONE mod $f7 OP_NONE sqrt $f8 OP_NONE cmplt $f9 OP_NONE cmpgt $fa OP_NONE cmpne $fb OP_NONE cmpeq $fc OP_NONE cmple $fd OP_NONE cmpge $fe OP_NONE notl $ff OP_NONE