User Tools

Site Tools


sd:isa

Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revisionPrevious revision
Next revision
Previous revision
sd:isa [2026/06/16 08:10] appledogsd:isa [2026/06/18 04:53] (current) appledog
Line 3: Line 3:
 == ISA Overview == ISA Overview
 The SD-8516 instruction set is organized into four tiers. Numbering is canonical The SD-8516 instruction set is organized into four tiers. Numbering is canonical
-in decimal (as defined in ''arch.h''); hex is given alongside for convenience.+in decimal (as defined in ''arch.h'' and ''arch.ts''); hex is given alongside for convenience.
  
 * **Tier 1 - Core** behaves like a RISC instruction set: small, orthogonal, and complete on its own. Target this first. Everything above it can be synthesized from the core if you have to. * **Tier 1 - Core** behaves like a RISC instruction set: small, orthogonal, and complete on its own. Target this first. Everything above it can be synthesized from the core if you have to.
 * **Tier 2 - Extended** are quality-of-life instructions for hand assemblers. ''ADD reg, imm'' is the canonical example: you do not need it (load the immediate and ''ADD''), but it is provided for convenience. ''MUL'' is in the same spirit, since you can loop with ''ADD''. * **Tier 2 - Extended** are quality-of-life instructions for hand assemblers. ''ADD reg, imm'' is the canonical example: you do not need it (load the immediate and ''ADD''), but it is provided for convenience. ''MUL'' is in the same spirit, since you can loop with ''ADD''.
 * **Tier 3 - CISC** are heavier, mostly VAX- and 680x0-flavored instructions: block memory, queue management, character scanning, jump tables. Each one folds a small loop into a single fetch-execute. * **Tier 3 - CISC** are heavier, mostly VAX- and 680x0-flavored instructions: block memory, queue management, character scanning, jump tables. Each one folds a small loop into a single fetch-execute.
-* **Tier 4 - Acceleration** are instructions added primarily to speed up a specific consumer: the LLVM backend (''MOVSX''/''MOVZX'', indexed addressing), the Forth system (''LSTEP'' and friends), or the hardware (PPU). They exist to remove instructions from a hot path, not to add expressiveness.+* **Tier 4 - Acceleration** are instructions added primarily to speed up a specific consumer: the LLVM backend (''MOVSX''/''MOVZX'', indexed addressing), the Forth system (''LSTEP'' and friends), or the hardware (PPU/ASU). They exist to remove instructions from a hot path, not to add expressiveness.
  
 A handful of opcodes carry aliases (e.g. ''JC''/''JAE'', ''BC''/''BAE'', ''CMPC''/''CMPC3''); both names assemble to the same byte. A handful of opcodes carry aliases (e.g. ''JC''/''JAE'', ''BC''/''BAE'', ''CMPC''/''CMPC3''); both names assemble to the same byte.
Line 27: Line 27:
 | 7   | $07  | [[#ld|ST_REG]]   | STA [X]       | Store register to memory (register pointer)  |         | | 7   | $07  | [[#ld|ST_REG]]   | STA [X]       | Store register to memory (register pointer)  |         |
 | 9   | $09  | [[#mov|MOV]]     | MOV Y, A      | Copy register to register (//same width//          | | 9   | $09  | [[#mov|MOV]]     | MOV Y, A      | Copy register to register (//same width//          |
-| 11  | $0B  | PUSH     | PUSH A        | Push register onto stack                             | +| 11  | $0B  | [[#PUSH]]     | PUSH A        | Push register onto stack                             | 
-| 12  | $0C  | POP      | POP Y         | Pop stack into register                      |         | +| 12  | $0C  | [[#POP]]      | POP Y         | Pop stack into register                      |         | 
-| 15  | $0F  | PUSHF    | PUSHF         | Push flags                                           | +| 15  | $0F  | [[#PUSHF]]    | PUSHF         | Push flags                                           | 
-| 16  | $10  | POPF     | POPF          | Pop flags                                    | *       | +| 16  | $10  | [[#POPF]]     | POPF          | Pop flags                                    | *       | 
-| 23  | $17  | INC      | INC X         | Increment register by 1 (any width)          |         | +| 23  | $17  | [[#INC]]      | INC X         | Increment register by 1 (any width)          |         | 
-| 24  | $18  | DEC      | DEC Y         | Decrement register by 1 (any width)          |         | +| 24  | $18  | [[#DEC]]      | DEC Y         | Decrement register by 1 (any width)          |         | 
-| 30  | $1E  | ADD      | ADD X, Y      | X = X + Y                                             | +| 30  | $1E  | [[#ADD]]      | ADD X, Y      | X = X + Y                                             | 
-| 31  | $1F  | SUB      | SUB X, Y      | X = X - Y                                             | +| 31  | $1F  | [[#SUB]]      | SUB X, Y      | X = X - Y                                             | 
-| 50  | $32  | AND      | AND dst, src  | Bitwise AND                                  |         | +| 50  | $32  | [[#AND]]      | AND dst, src  | Bitwise AND                                  |         | 
-| 51  | $33  | OR       | OR dst, src   | Bitwise OR                                           | +| 51  | $33  | [[#OR]]       | OR dst, src   | Bitwise OR                                           | 
-| 52  | $34  | XOR      | XOR dst, src  | Bitwise XOR                                  |         | +| 52  | $34  | [[#XOR]]      | XOR dst, src  | Bitwise XOR                                  |         | 
-| 53  | $35  | NOT      | NOT reg       | Bitwise NOT (invert all bits)                |         | +| 53  | $35  | [[#NOT]]      | NOT reg       | Bitwise NOT (invert all bits)                |         | 
-| 70  | $46  | SHL      | SHL A         | Shift left                                   | Z N C   | +| 70  | $46  | [[#SHL]]      | SHL A         | Shift left                                   | Z N C   | 
-| 71  | $47  | SHR      | SHR A         | Shift right                                  | Z N C   | +| 71  | $47  | [[#SHR]]      | SHR A         | Shift right                                  | Z N C   | 
-| 90  | $5A  | CMP      | CMP A, B      | Compare (subtract, discard result)           | Z N C V | +| 90  | $5A  | [[#CMP]]      | CMP A, B      | Compare (subtract, discard result)           | Z N C V | 
-| 91  | $5B  | CMP_IMM  | CMP A, $1     | Compare against immediate                    | Z N C V | +| 91  | $5B  | [[#CMP_IMM]]  | CMP A, $1     | Compare against immediate                    | Z N C V | 
-| 100 | $64  | JMP      | JMP @label    | Unconditional jump                                   | +| 100 | $64  | [[#JMP]]      | JMP @label    | Unconditional jump                                   | 
-| 101 | $65  | JZ       | JZ @label     | Jump if zero                                         | +| 101 | $65  | [[#JZ]]       | JZ @label     | Jump if zero                                         | 
-| 102 | $66  | JNZ      | JNZ @label    | Jump if not zero                                     | +| 102 | $66  | [[#JNZ]]      | JNZ @label    | Jump if not zero                                     | 
-| 105 | $69  | JC       | JC @label     | Jump if carry set (alias //JAE//           |         | +| 105 | $69  | [[#JC]]       | JC @label     | Jump if carry set (alias //JAE//           |         | 
-| 106 | $6A  | JNC      | JNC @label    | Jump if carry clear (alias //JNAE//                |+| 106 | $6A  | [[#JNC]]      | JNC @label    | Jump if carry clear (alias //JNAE//                |
 | 130 | $82  | [[#call|CALL]]   | CALL @label   | Call subroutine (push IP, jump)              |         | | 130 | $82  | [[#call|CALL]]   | CALL @label   | Call subroutine (push IP, jump)              |         |
-| 133 | $85  | RET      | RET           | Return from subroutine (pop IP)              |         | +| 133 | $85  | [[#RET]]      | RET           | Return from subroutine (pop IP)              |         | 
-| 134 | $86  | INT      | INT $10       | Software interrupt                                   | +| 134 | $86  | [[#INT]]      | INT $10       | Software interrupt                                   | 
-| 135 | $87  | RTI      | RTI           | Return from interrupt                        | *       | +| 135 | $87  | [[#RTI]]      | RTI           | Return from interrupt                        | *       | 
-| 182 | $B6  | SETF     | SETF $80      | Set bits in the flags register               | *       | +| 182 | $B6  | [[#SETF]]     | SETF $80      | Set bits in the flags register               | *       | 
-| 183 | $B7  | CLRF     | CLRF $80      | Clear bits in the flags register             | *       | +| 183 | $B7  | [[#CLRF]]     | CLRF $80      | Clear bits in the flags register             | *       | 
-| 184 | $B8  | TESTF    | TESTF $80     | Non-destructive AND against flags            | Z C     | +| 184 | $B8  | [[#TESTF]]    | TESTF $80     | Non-destructive AND against flags            | Z C     | 
-| 254 | $FE  | NOP      | NOP           | No operation                                         | +| 254 | $FE  | [[#NOP]]      | NOP           | No operation                                         | 
-| 255 | $FF  | HALT     | HALT          | Halt CPU (sets HALT flag)                    |         |+| 255 | $FF  | [[#HALT]]     | HALT          | Halt CPU (sets HALT flag)                    |         | 
 + 
 +Although this is intended as a RISC core, there are some extras here, primarily LD-8bit hot path, which is done to speed up execution of 8 bit loads by about 30%. Additionally, INC, DEC and CALL/RET are semi-RISC because you can ADD reg, #1 or PUSH ptr0 and JMP (then POP IP to return). INT and RTI are suspect here, as well as CMP_IMM (you can just load into a register and use register compare). But these instructions are so common that it is difficult to justify not including them. The core set is intended to be minimalist, but not obtusely so. 
 + 
 +POPF however, is a strong canidate for removal. It would really only be needed for a kind of protected mode, interrupt mode or kernal mode, and we dont use it currently. 
 + 
 +Finally, it may be interesting to fuse CMP and JZ. Imagine, any CMP and conditional jump could be a CJMP. ex. ''CJZ A, B, address'' -- if they're equal, then we jump. One instruction. We save a dispatch and a byte. 
 + 
 +Consider: 
 +* No CMP exists in isolation 
 +* No JZ exists without responding to a change in the Z flag. 
 +* CJZ A, A can test for zero after a load if we really need one. 
 + 
 +Further investigate: 
 +* Does the cost of flag calculation outweight dispatch for how often a CMP occurrs?
  
 === Tier 2: Extended (Quality of Life) === Tier 2: Extended (Quality of Life)
Line 164: Line 178:
  
 === Tier 4: Acceleration (LLVM / Forth / Hardware) === Tier 4: Acceleration (LLVM / Forth / Hardware)
-Instructions added to remove work from a specific hot path rather than to add +Instructions added to remove work from a specific hot path rather than to add expressiveness. Each one has a primary consumer noted below. 
-expressiveness. Each one has a primary consumer noted below.+ 
 +Canidates for inclusion: LEA, fused CMP-Bcc and CMP-Jcc, conditional move, LD_IDX16
  
 | #   | hex  | Mnemonic | Example          | Description                                  | Consumer | Flags | | #   | hex  | Mnemonic | Example          | Description                                  | Consumer | Flags |
Line 339: Line 354:
 <wrap #jc /> <wrap #jc />
 **''#105 $69 JC''**\\ **''#105 $69 JC''**\\
-Jump if carry set (alias JAE for unsigned >=). ''if (C) IP = @label''.+Jump if carry set (alias JAE for unsigned {{{>=)}}}. ''if (C) IP = @label''.
  
 <wrap #jnc /> <wrap #jnc />
Line 374: Line 389:
 <wrap #cmpc /> <wrap #cmpc />
 **''#142 $8E CMPC ELM, FLD, C''** (alias //CMPC3//)\\ **''#142 $8E CMPC ELM, FLD, C''** (alias //CMPC3//)\\
-Non-zero byte compare, useful for strings. Compares up to C characters; C returns +Non-zero byte compare, useful for strings. Compares up to C characters; C returns either the index of the first mismatch or the matched length. Sets ZERO on a full match; otherwise CARRY distinguishes the -1 / +1 ordering.
-either the index of the first mismatch or the matched length. Sets ZERO on a full +
-match; otherwise CARRY distinguishes the -1 / +1 ordering.+
  
-CMPC allows early termination when ''byte_a == 0'' -- the C-string "begins with" +CMPC allows early termination when ''byte_a == 0'' -- the C-string "begins with" semantics. If both strings reach a terminator at the same position with all prior bytes equal, the loop exits matched (Z=1, C=1). Only ''byte_a'' is tested because by that point ''byte_a == byte_b'' is already proven, so ''byte_a == 0'' implies ''byte_b == 0''. This lets CMPC do double duty: fixed-length compare and null-terminated strcmp in one instruction.
-semantics. If both strings reach a terminator at the same position with all prior +
-bytes equal, the loop exits matched (Z=1, C=1). Only ''byte_a'' is tested because by +
-that point ''byte_a == byte_b`` is already proven, so ''byte_a == 0'' implies +
-''byte_b == 0''. This lets CMPC do double duty: fixed-length compare and +
-null-terminated strcmp in one instruction.+
  
 <wrap #skpc /> <wrap #skpc />
Line 479: Line 487:
 <wrap #casetab /> <wrap #casetab />
 **''#202 $CA CASETAB base, selector, #limit''**\\ **''#202 $CA CASETAB base, selector, #limit''**\\
-Jump table held at a base address rather than inline. Indexes an address from the +Jump table held at a base address rather than inline. Indexes an address from the table at ''base'' by ''selector'', bounded by ''limit'', and dispatches to it.
-table at ''base'' by ''selector'', bounded by ''limit'', and dispatches to it. +
-//The precise indexing and out-of-bounds policy should be confirmed against the +
-current emulator handler: the older CASE3 (computed table at base) and CASEB +
-(scanned ''[selector][addr]'' table) were removed, and CASETAB is the surviving +
-table-at-base form.//+
  
 <wrap #cvtan /> <wrap #cvtan />
 **''#203 $CB CVTAN reg8''**\\ **''#203 $CB CVTAN reg8''**\\
-Convert ASCII to number. Maps '0'-'Z' to 0-35. Sets Overflow if the character is not +Convert ASCII to number. Maps '0'-'Z' to 0-35. Sets Overflow if the character is not a decimal digit (0-9) and Carry if it is not a hex digit (0-15). Also a fast digit test: ''MOV reg8, AL'' then ''CVTAN reg8'' lets you branch with JO/JNO (JV/JNV). Designed for zoned decimal, and works for zoned hex.
-a decimal digit (0-9) and Carry if it is not a hex digit (0-15). Also a fast digit +
-test: ''MOV reg8, AL'' then ''CVTAN reg8'' lets you branch with JO/JNO (JV/JNV). +
-Designed for zoned decimal, and works for zoned hex.+
  
 <wrap #cvtna /> <wrap #cvtna />
Line 499: Line 499:
  
 <wrap #idx /> <wrap #idx />
-**''#210 LD_IDXI / #211 LD_IDXR / #212 ST_IDXI / #213 ST_IDXR''**\\ +**''#210 LD_IDXI / #211 LD_IDXR / #212 ST_IDXI / #213 ST_IDXR''**\\ Indexed load/store: a 24-bit pointer register plus a displacement. The ''I'' forms take a signed byte immediate (-128..+127); the ''R'' forms take a register offset. These back the compiler's frame-slot and struct-field access (''[ptr + disp]''). The pointer base must be a 24-bit register; the effective address reads the base at its
-Indexed load/store: a 24-bit pointer register plus a displacement. The ''I'' forms +
-take a signed byte immediate (-128..+127); the ''R'' forms take a register offset. +
-These back the compiler's frame-slot and struct-field access (''[ptr + disp]''). The +
-pointer base must be a 24-bit register; the effective address reads the base at its+
 true width before applying the offset. true width before applying the offset.
  
Line 521: Line 517:
  
 <codify armasm> <codify armasm>
-    LDFLX $F000       ; loop start +    LDFLX $F000       ; 8 byte loop data start 
-    LDA #1 +    LDA #1            ; start at 
-    STA [FLX] +    STA [FLX]         ; write starting counter at first four bytes 
-    LDA #1000 +    LDA #1000         ; go until 1000 
-    STA [FLX+4]+    STA [FLX+4]       ; write finish (until) counter at second four bytes
 loop: loop:
-    LSTEPM+    LSTEPM            ; INC N1, if N1==N2 set Z=1
     JNZ @loop     JNZ @loop
 </codify> </codify>
  
-Unlike a DEC loop it counts upward and supports an arbitrary start. It is a kludge +Unlike a DEC loop it counts upward and supports an arbitrary start. The generalized form of this is [[#lstep|LSTEP]] which counts downwards instead. 
-for Forth and has been generalized by [[#lstep|LSTEP]]; once Forth uses LSTEP+ 
-LSTEPM is a candidate for removal.+Only used by Forth. It is recommended to use LSTEP instead; this instruction is a canidate for removal.
  
 <wrap #ttos /> <wrap #ttos />
sd/isa.1781597433.txt.gz · Last modified: by appledog

Donate Powered by PHP Valid HTML5 Valid CSS Driven by DokuWiki