notes-computer-programming-programmingLanguagesBook-programmingLanguagesParallaxPropellerIsa

Parallax Propeller multicore MCU ISA and SPIN bytecode

A multicore MCU, the Propeller has 8 32-bit MCUs.

Has a ~64-instruction ISA and a bytecode-interpreted language called SPIN.

SPIN bytecode

The entire SPIN interpreter fits into 2k ( https://en.wikipedia.org/wiki/Parallax_Propeller#Built_in_SPIN_byte_code_interpreter ).

Links:

there are 256 opcodes in SPIN:

FRAME_CALL_RETURN FRAME_CALL_NORETURN FRAME_CALL_ABORT FRAME_CALL_TRASHABORT BRANCH CALL OBJCALL OBJCALL_INDEXED LOOP_START LOOP_CONTINUE JUMP_IF_FALSE JUMP_IF_TRUE JUMP_FROM_STACK COMPARE_CASE COMPARE_CASE_RANGE LOOK_ABORT LOOKUP_COMPARE LOOKDOWN_COMPARE LOOKUPRANGE_COMPARE LOOKDOWNRANGE_COMPARE QUIT MARK_INTERPRETED STRSIZE STRCOMP BYTEFILL WORDFILL LONGFILL WAITPEQ BYTEMOVE WORDMOVE LONGMOVE WAITPNE CLKSET COGSTOP LOCKRET WAITCNT READ_INDEXED_SPR WRITE_INDEXED_SPR EFFECT_INDEXED_SPR WAITVID COGINIT_RETURNS LOCKNEW_RETURNS LOCKSET_RETURNS LOCKCLR_RETURNS COGINIT LOCKNEW LOCKSET LOCKCLR ABORT ABORT_WITH_RETURN RETURN POP_RETURN PUSH_NEG1 PUSH_0 PUSH_1 PUSH_PACKED_LIT PUSH_BYTE_LIT PUSH_WORD_LIT PUSH_MID_LIT PUSH_LONG_LIT UNKNOWN OP $3C INDEXED_MEM_OP INDEXED_RANGE_MEM_OP MEMORY_OP PUSH_VARMEM_LONG_0 POP_VARMEM_LONG_0 EFFECT_VARMEM_LONG_0 REFERENCE_VARMEM_LONG_0 PUSH_VARMEM_LONG_1 POP_VARMEM_LONG_1 EFFECT_VARMEM_LONG_1 REFERENCE_VARMEM_LONG_1 PUSH_VARMEM_LONG_2 POP_VARMEM_LONG_2 EFFECT_VARMEM_LONG_2 REFERENCE_VARMEM_LONG_2 PUSH_VARMEM_LONG_3 POP_VARMEM_LONG_3 EFFECT_VARMEM_LONG_3 REFERENCE_VARMEM_LONG_3 PUSH_VARMEM_LONG_4 POP_VARMEM_LONG_4 EFFECT_VARMEM_LONG_4 REFERENCE_VARMEM_LONG_4 PUSH_VARMEM_LONG_5 POP_VARMEM_LONG_5 EFFECT_VARMEM_LONG_5 REFERENCE_VARMEM_LONG_5 PUSH_VARMEM_LONG_6 POP_VARMEM_LONG_6 EFFECT_VARMEM_LONG_6 REFERENCE_VARMEM_LONG_6 PUSH_VARMEM_LONG_7 POP_VARMEM_LONG_7 EFFECT_VARMEM_LONG_7 REFERENCE_VARMEM_LONG_7 PUSH_LOCALMEM_LONG_0 POP_LOCALMEM_LONG_0 EFFECT_LOCALMEM_LONG_0 REFERENCE_LOCALMEM_LONG_0 PUSH_LOCALMEM_LONG_1 POP_LOCALMEM_LONG_1 EFFECT_LOCALMEM_LONG_1 REFERENCE_LOCALMEM_LONG_1 PUSH_LOCALMEM_LONG_2 POP_LOCALMEM_LONG_2 EFFECT_LOCALMEM_LONG_2 REFERENCE_LOCALMEM_LONG_2 PUSH_LOCALMEM_LONG_3 POP_LOCALMEM_LONG_3 EFFECT_LOCALMEM_LONG_3 REFERENCE_LOCALMEM_LONG_3 PUSH_LOCALMEM_LONG_4 POP_LOCALMEM_LONG_4 EFFECT_LOCALMEM_LONG_4 REFERENCE_LOCALMEM_LONG_4 PUSH_LOCALMEM_LONG_5 POP_LOCALMEM_LONG_5 EFFECT_LOCALMEM_LONG_5 REFERENCE_LOCALMEM_LONG_5 PUSH_LOCALMEM_LONG_6 POP_LOCALMEM_LONG_6 EFFECT_LOCALMEM_LONG_6 REFERENCE_LOCALMEM_LONG_6 PUSH_LOCALMEM_LONG_7 POP_LOCALMEM_LONG_7 EFFECT_LOCALMEM_LONG_7 REFERENCE_LOCALMEM_LONG_7 PUSH_MAINMEM_BYTE POP_MAINMEM_BYTE EFFECT_MAINMEM_BYTE REFERENCE_MAINMEM_BYTE PUSH_OBJECTMEM_BYTE POP_OBJECTMEM_BYTE EFFECT_OBJECTMEM_BYTE REFERENCE_OBJECTMEM_BYTE PUSH_VARIABLEMEM_BYTE POP_VARIABLEMEM_BYTE EFFECT_VARIABLEMEM_BYTE REFERENCE_VARIABLEMEM_BYTE PUSH_LOCALMEM_BYTE POP_LOCALMEM_BYTE EFFECT_LOCALMEM_BYTE REFERENCE_LOCALMEM_BYTE PUSH_INDEXED_MAINMEM_BYTE POP_INDEXED_MAINMEM_BYTE EFFECT_INDEXED_MAINMEM_BYTE REFERENCE_INDEXED_MAINMEM_BYTE PUSH_INDEXED_OBJECTMEM_BYTE POP_INDEXED_OBJECTMEM_BYTE EFFECT_INDEXED_OBJECTMEM_BYTE REFERENCE_INDEXED_OBJECTMEM_BYTE PUSH_INDEXED_VARIABLEMEM_BYTE POP_INDEXED_VARIABLEMEM_BYTE EFFECT_INDEXED_VARIABLEMEM_BYTE REFERENCE_INDEXED_VARIABLEMEM_BYTE PUSH_INDEXED_LOCALMEM_BYTE POP_INDEXED_LOCALMEM_BYTE EFFECT_INDEXED_LOCALMEM_BYTE REFERENCE_INDEXED_LOCALMEM_BYTE PUSH_MAINMEM_WORD POP_MAINMEM_WORD EFFECT_MAINMEM_WORD REFERENCE_MAINMEM_WORD PUSH_OBJECTMEM_WORD POP_OBJECTMEM_WORD EFFECT_OBJECTMEM_WORD REFERENCE_OBJECTMEM_WORD PUSH_VARIABLEMEM_WORD POP_VARIABLEMEM_WORD EFFECT_VARIABLEMEM_WORD REFERENCE_VARIABLEMEM_WORD PUSH_LOCALMEM_WORD POP_LOCALMEM_WORD EFFECT_LOCALMEM_WORD REFERENCE_LOCALMEM_WORD PUSH_INDEXED_MAINMEM_WORD POP_INDEXED_MAINMEM_WORD EFFECT_INDEXED_MAINMEM_WORD REFERENCE_INDEXED_MAINMEM_WORD PUSH_INDEXED_OBJECTMEM_WORD POP_INDEXED_OBJECTMEM_WORD EFFECT_INDEXED_OBJECTMEM_WORD REFERENCE_INDEXED_OBJECTMEM_WORD PUSH_INDEXED_VARIABLEMEM_WORD POP_INDEXED_VARIABLEMEM_WORD EFFECT_INDEXED_VARIABLEMEM_WORD REFERENCE_INDEXED_VARIABLEMEM_WORD PUSH_INDEXED_LOCALMEM_WORD POP_INDEXED_LOCALMEM_WORD EFFECT_INDEXED_LOCALMEM_WORD REFERENCE_INDEXED_LOCALMEM_WORD PUSH_MAINMEM_LONG POP_MAINMEM_LONG EFFECT_MAINMEM_LONG REFERENCE_MAINMEM_LONG PUSH_OBJECTMEM_LONG POP_OBJECTMEM_LONG EFFECT_OBJECTMEM_LONG REFERENCE_OBJECTMEM_LONG PUSH_VARIABLEMEM_LONG POP_VARIABLEMEM_LONG EFFECT_VARIABLEMEM_LONG REFERENCE_VARIABLEMEM_LONG PUSH_LOCALMEM_LONG POP_LOCALMEM_LONG EFFECT_LOCALMEM_LONG REFERENCE_LOCALMEM_LONG PUSH_INDEXED_MAINMEM_LONG POP_INDEXED_MAINMEM_LONG EFFECT_INDEXED_MAINMEM_LONG REFERENCE_INDEXED_MAINMEM_LONG PUSH_INDEXED_OBJECTMEM_LONG POP_INDEXED_OBJECTMEM_LONG EFFECT_INDEXED_OBJECTMEM_LONG REFERENCE_INDEXED_OBJECTMEM_LONG PUSH_INDEXED_VARIABLEMEM_LONG POP_INDEXED_VARIABLEMEM_LONG EFFECT_INDEXED_VARIABLEMEM_LONG REFERENCE_INDEXED_VARIABLEMEM_LONG PUSH_INDEXED_LOCALMEM_LONG POP_INDEXED_LOCALMEM_LONG EFFECT_INDEXED_LOCALMEM_LONG REFERENCE_INDEXED_LOCALMEM_LONG ROTATE_RIGHT ROTATE_LEFT SHIFT_RIGHT SHIFT_LEFT LIMIT_MIN LIMIT_MAX NEGATE COMPLEMENT BIT_AND ABSOLUTE_VALUE BIT_OR BIT_XOR ADD SUBTRACT ARITH_SHIFT_RIGHT BIT_REVERSE LOGICAL_AND ENCODE LOGICAL_OR DECODE MULTIPLY MULTIPLY_HI DIVIDE MODULO SQUARE_ROOT LESS GREATER NOT_EQUAL EQUAL LESS_EQUAL GREATER_EQUAL LOGICAL_NOT

-- from http://propeller.wikispaces.com/Spin+Byte+Code

Propeller assembly

Addressing modes: immediate and register.

Note: due to the lack of an indirect addressing mode you must use self-modifying code on the propeller to substitute:

" Technically speaking, the Prop has a “two address instruction set” sporting a systematic “option for immediate addressing” (0...511). There are no other systematic addressing modes as known from other processors (indexed, pre/post-in/decrementing). Should we need this (and we shall!) , we shall have to “modify” instructions, in that we compute the requested address and “implant it” into an existing instruction. This has been turned down by computer science for decades. The great Edsgar Dijkstra is supposed to have written an article titled “Self modifying code considered harmful”, but the manuscript has got lost. The Propeller however cannot live without this; there are even three handy instructions to support this, called MOVI, MOVS and MOVD. We will work through examples in Chapter 5. " -- http://www.cp.eng.chula.ac.th/~piak/project/propeller/machinelanguage.pdf

note: MOVS moves to the SOURCE field of the destination instruction; MOVD moves to the DEST field of the destination instruction

this shows the deep necessitity of pointers or references or something to substitute for them (like self-modifying code) in any paradigm of computation

Instruction size: 32 bits

Instruction format: opcode (6 bits), set flags and result (3 bits), immediate addressing (1 bit), execution condition (4 bits), dest register (9 bits), source register or immediate value (9 bits)

Arithmetic: ABS (Get absolute value of a number), ABSNEG (Get the negative of a number’s absolute value), ADD (Add unsigned values), ADDABS (Add absolute value to another value), ADDS (Add signed values), ADDSX (Add signed values plus C), ADDX (Add unsigned values plus C) MAX (Limit maximum of unsigned value to another unsigned value) MAXS (Limit maximum of signed value to another signed value) MIN (Limit minimum of unsigned value to another unsigned value) MINS (Limit minimum of signed value to another signed value) NEG (Get negative of a number) NEGC (Get value, or its additive inverse, based on C) NEGNC (Get value, or its additive inverse, based on !C) NEGNZ (Get value, or its additive inverse, based on !Z) NEGZ (Get value, or its additive inverse, based on Z) SUB (Subtract unsigned values) SUBABS (Subtract absolute value from another value) SUBS (Subtract signed values) SUBSX (Subtract signed value plus C from another signed value) SUBX (Subtract unsigned value plus C from another unsigned value) SUMC (Sum signed value with another whose sign is inverted based on C) SUMNC (Sum signed value with another whose sign is inverted based on !C) SUMNZ (Sum signed value with another whose sign is inverted based on !Z) SUMZ (Sum signed value with another whose sign is inverted based on Z)

Logic: CMP (Compare unsigned values) CMPS (Compare signed values) CMPSUB (Compare unsigned values, subtract second if it is lesser or equal) CMPSX (Compare signed values plus C) CMPX (Compare unsigned values plus C) TEST (Bitwise AND values to affect flags only) TESTN (Bitwise AND value with NOT of another to affect flags only)

Control: CALL (Jump to address with intention to return to next instruction)

DJNZ (Decrement value and jump to address if not zero) JMP (Jump to address unconditionally) JMPRET (Jump to address with intention to “return” to another address) RET (Return to address) TJNZ (Test value and jump to address if not zero) TJZ (Test value and jump to address if zero)

Concurrency: CLKSET (Set clock mode at run time), COGID (Get current cog’s ID), COGINIT (Re/start cog, ID optional, to run Propeller Assembly or Spin code), COGSTOP (Start a cog by ID) LOCKCLR (Clear semaphore to False and get its previous state) LOCKNEW (Check out new semaphore and get its ID) LOCKRET (Return semaphore back for future “new semaphore” requests) LOCKSET (Set semaphore to true and get its previous state) WAITCNT (Pause execution temporarily) WAITPEQ (Pause execution until I/O pin(s) match designated state(s)) WAITPNE (Pause execution until I/O pin(s) don’t match designated state(s)) WAITVID (Pause execution until Video Generator can take pixel data)

General:

MUXC (Set discrete bits of value to state of C) MOV (Set register to a value) MOVD (Set register’s destination field to a value) MOVI (Set register’s instruction field to a value) MOVS (Set register’s source field to a value) NOP (No operation, just elapse four clock cycles) RDBYTE (Read byte of main memory) RDLONG (Read long of main memory) RDWORD (Read word of main memory) WRBYTE (Write byte to main memory) WRLONG (Write long to main memory) WRWORD (Write word to main memory)

Misc: HUBOP (Perform a hub operation)

Bitwise: AND (Bitwise AND values), ANDN (Bitwise AND value with NOT of another) MUXNC (Set discrete bits of value to state of !C) MUXNZ (Set discrete bits of value to state of !Z) MUXZ (Set discrete bits of value to state of Z) REV (Reverse LSBs of value and zero-extend) ROL (Rotate value left by specified number of bits) ROR (Rotate value right by specified number of bits) SAR (Shift value arithmetically right by specified number of bits) SHL (Shift value left by specified number of bits) SHR (Shift value right by specified number of bits) OR RCL (Rotate C left into value by specified number of bits) RCR (Rotate C right into value by specified number of bits XOR (Bitwise XOR values)

note: Notice that many opcodes have a negated form which negates an argument before applying the instruction.

Links:

Links