diff options
| author | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2024-05-19 13:52:10 -0500 | 
|---|---|---|
| committer | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2024-05-19 13:52:10 -0500 | 
| commit | c96ba2b2678e4b92e7969c683d4cb3f1648af813 (patch) | |
| tree | 38d8eef4cdc62a3ab508b4884a44657b22b9fbf7 /assembler | |
| parent | a63eba62ae9faffea51ba618b0d20f132c23c452 (diff) | |
Rework assembler for simplified instruction set
- Remove commas and brackets from syntax
- Rename opcodes for unambiguous instruction encodings
- Redesign parse instruction encoding
- Implement opcode parser
- Add bit-width restriction to octal parser
Diffstat (limited to 'assembler')
| -rw-r--r-- | assembler/assemble.s | 147 | ||||
| -rw-r--r-- | assembler/get_char.s | 21 | ||||
| -rw-r--r-- | assembler/instructions | 233 | ||||
| -rw-r--r-- | assembler/notes | 35 | ||||
| -rw-r--r-- | assembler/octal.s | 72 | ||||
| -rw-r--r-- | assembler/opcode.s | 283 | ||||
| -rw-r--r-- | assembler/register.s | 59 | ||||
| -rw-r--r-- | assembler/string.s | 16 | 
8 files changed, 691 insertions, 175 deletions
| diff --git a/assembler/assemble.s b/assembler/assemble.s index bf31edf..ef3893d 100644 --- a/assembler/assemble.s +++ b/assembler/assemble.s @@ -1,71 +1,100 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.type assemble, %function +.global assemble + +// TODO: +// - implement opcode parser +// - test each instruction (do this later -- much easier) +// - test 4-bit reg instructions +// - test BEQ overlaps +// - decide on additional push or pops +  assemble: -  BL receive_op -  LDR R5, =0x20002000 // opcode table -  LDR R1, =0x20001000 // opcode buffer base addr -loop: -  LDR R0, [R5, 0]     // load the string addr -  BL string_compare -  BEQ match -  ADDS R5, 8          // next row of table -  LDR R0, =0x20002080 // opcode table end -  CMP R5, R0 -  BLO loop            // Keep going if lower than end -  B redo_line         // redo line if opcode was not found -match: -  LDR R6, [R5, 4]     // load the parse instructions +  // LDR R3, [SP, 20] +  MOVS R6, 0 +  LDR R7, =0x00C8E893 +  // LDR R7, =0xE0E3A588 +  MOVS R0, '  +  MOV R8, R0  main_loop: -  MOVS R0, 0xFF   // lsb mask -  ANDS R0, R6     // store in R0 -  MOVS R1, 0x80   // bit 7 mask -  TST R0, R1      // compare (AND) to R0 byte -  BNE handle_imm  // if IMM (== 1) -  LSRS R0, 4      // R0 hold 3 or 4 (or 0) -  BEQ handle_brackets // if BRACKETS (== 0) -handle_reg: -  BL register    // result is put in R4 -  MOVS R0, 0x0F  // lower nibble mask -  ANDS R0, R6    // store shift amount in R0 -  LSLS R4, R0    // shift the result by the shift amount -  ORRS R5, R4    // OR the register code into the word under construction +  LSRS R0, R7, 8    // just peek +  BNE skip          // if more stuff then skip +  MOVS R0, '\r +  MOV R8, R0        //set end char to carriage return +skip: +  // MOVS R0, 0xFF     // lsb mask +  // ANDS R0, R7       // store in R0 +  UXTB R0, R7       // store lsb in R0 +  LSRS R1, R0, 4    // upper nibble +  CMP R1, 0xC       // if 0xxxxxxx or 10xxxxxx +  BLO opcode +  CMP R1, 0xE       // if 110xyyyy +  BLO handle_imm +handle_reg:         // if 111xyyyy +  MOVS R1, (1<<4)   // bit 4 mask +  ANDS R0, R1       // get bit 4 +  ADDS R0, 3        // add 3 to it (now 3 or 4) +  BL register       // result is put in R4 +  MOVS R0, 0x0F     // lower nibble mask +  ANDS R0, R7       // store shift amount in R0 +  LSLS R4, R0       // shift the result by the shift amount +  ORRS R6, R4       // OR the register code into the word under construction    B done_stuff +opcode: +  MOVS R2, 9        // shift amount for 7-bit opcode +  MOVS R1, (1<<7)   // bit 7 mask +  TST R0, R1        // check bit 7 +  BEQ fin           // if zero done +  BICS R0, R1       // clear bit 7 +  MOVS R2, 11       // shift amount for 5-bit opcode high +  MOVS R1, (1<<5)   // bit 5 mask +  TST R0, R1        // check bit 5 +  BEQ fin           // if zero done +  BICS R0, R1       // clear bit 5 +  MOVS R2, 6        // shift amount for 5-bit opcode low +fin: +  LSLS R0, R2 +  ORRS R6, R0 +  B here  handle_imm:    MOVS R1, 0x0F  // lower nibble mask    ANDS R0, R1    // store immediate width in R0    BL octal       // result is put in R4 -  MOVS R0, 0x7F  // least significant 7 bits mask -  ANDS R0, R6    // store ls 7 bits in R0 -  LSRS R0, 4     // shift right to get shift amount +  LSLS R0, R7, 27 +  LSRS R0, 31 +  MOVS R2, 6 +  MULS R0, R2    // R0 has shift amount (0 or 6)    LSLS R4, R0    // shift the result by the shift amount +  ORRS R6, R4    // OR the immediate into the word under construction  done_stuff: -  LSRS R6, 0x8 // get next parse instruction -  BEQ done     // if it's zero there are no more things to parse -  MOVS R0, 0   // copy the end_char into R0 -  ORRS R0, R9 -  BL uart_send // echo the comma (or bracket) -10: -  BL get_char -  MOVS R1, '  // space char -  CMP R0, R1 -  BNE 10b // keep trying if not space -  BL uart_send // echo the space -  B main_loop -handle_brackets: -  BL get_char    // char in R0 -  MOVS R1, '[    // open bracket -  CMP R0, R1 -  BNE handle_brackets // keep trying if not bracket -  BL uart_send   // echo bracket -  MOVS R8, 1     // 1 means we are now in brackets -  LSRS R6, 0x8   // get next parse instruction -  BNE main_loop +  MOV R0, R8     // copy the end_char into R0 +  BL uart_send   // echo the space (or carriage return) +here: +  LSRS R7, 0x8   // get next parse instruction +  BNE main_loop  // if it's nonzero there are more things to parse  done: -  TST R8, R8 // R8 == whether we are in bracket or not -  BEQ no_brackets -  MOVS R0, ']  // echo bracket -  BL uart_send -no_bracket: -  MOVS R0, '\r  // send carriage return -  BL uart_send    MOVS R0, '\n  // send newline    BL uart_send -  B next_instr +  MOVS R0, R6 +  BL send_hex +  B assemble + +.type get_char, %function +.global get_char + +// R8: end_char +get_char: +  PUSH {LR} +  BL uart_recv +  CMP R0, 025 // ^U (NAK) +  BEQ redo_line +  // CMP R0, 004 // ^D (EOT) +  // BEQ done_for_real +  CMP R0, R8 +  POP {PC} +redo_line: +  POP {R0} +  B done diff --git a/assembler/get_char.s b/assembler/get_char.s deleted file mode 100644 index f1f43e7..0000000 --- a/assembler/get_char.s +++ /dev/null @@ -1,21 +0,0 @@ -// R9: end_char -get_char: -  PUSH {LR} -  BL uart_recv -  MOVS R1, 025 // ^U (NAK) -  CMP R0, R1 -  BEQ redo_line -  MOVS R1, 004 // ^D (EOT) -  CMP R0, R1 -  BEQ done_for_real -  CMP R0, R9 -  POP {PC} - -get_line: -  BL get_char -  ... -  B get_line - -redo_line: -  ... -  B get_line diff --git a/assembler/instructions b/assembler/instructions new file mode 100644 index 0000000..88ebd23 --- /dev/null +++ b/assembler/instructions @@ -0,0 +1,233 @@ +Clobber +R0: arg1, uart result +R1: arg2 +R2: +R3: shift_amount +------------- +Save +R4: octal result, register result +R5: second-level (octal or register) scratch +R6: word under construction +R7: parse instructions +R8: end_char +R8: +R9: +R10: +R11: +R12: + +Encoding + +start with all 0 + +0xxxxxxx // 7-bit field xxxxxxx at [15:9] (non zero) +100xxxxx // 5-bit field xxxxx at [15:11] +101xxxxx // 5-bit field xxxxx at [10:6] +1100yyyy // octal immediate with shift amount 0 and bit-width yyyy +1101yyyy // octal immediate with shift amount 6 and bit-width yyyy +1110yyyy // 3-bit reg with shift amount yyyy +1111yyyy // 4-bit reg with shift amount yyyy (excluding yyyy=1111=15) + +ADCS (register)     T1  01000 00101 Rm Rdn    E3 E0 A5 88 +ADDSI3 (immediate)  T1  0001110 imm3 Rn Rd    D3 E3 E0 0E +ADDSI8 (immediate)  T2  00110 Rdn imm8        00 C8 E3 86 +ADDSR (register)    T1  0001100 Rm Rn Rd      E6 E3 E0 0C +ADDRHI (register)   T2  010001001 Rm4 Rdn     F3 E0 B2 88     TODO (dn + 8) +ADDRLO (register)   T2  010001000 Rm4 Rdn     F3 E0 B0 88 +ADR                 T1  10100 Rd imm8         00 C8 E3 94 +ANDS (register)     T1  01000 00000 Rm Rdn    E3 E0 A0 88 +ASRSI (immediate)   T1  00010 imm5 Rm Rd      D5 E3 E0 82 +ASRSR (register)    T1  01000 00100 Rm Rdn    E3 E0 A4 88 +BEQ                 T1  11010 000 imm8        00 C8 A0 9A     TODO overlap +BNE                 T1  11010 001 imm8        00 C8 A4 9A +BHS                 T1  11010 010 imm8        00 C8 A8 9A +BLO                 T1  11010 011 imm8        00 C8 AC 9A +BMI                 T1  11010 100 imm8        00 C8 B0 9A +BPL                 T1  11010 101 imm8        00 C8 B4 9A +BVS                 T1  11010 110 imm8        00 C8 B8 9A +BVC                 T1  11010 111 imm8        00 C8 BC 9A +BHI                 T1  11011 000 imm8        00 C8 A0 9B +BLS                 T1  11011 001 imm8        00 C8 A4 9B +BGE                 T1  11011 010 imm8        00 C8 A8 9B +BLT                 T1  11011 011 imm8        00 C8 AC 9B +BGT                 T1  11011 100 imm8        00 C8 B0 9B +BLE                 T1  11011 101 imm8        00 C8 B4 9B +B                   T2  11100 imm11           00 00 CB 9C +BICS (register)     T1  01000 01110 Rm Rdn    E3 E0 AE 88 +BLHI                T1  11110 imm11           00 00 CB 9E +BLLO                T1  11111 imm11           00 00 CB 9F +BLX                 T1  01000 1111 Rm 000     00 E3 BE 88 +BX                  T1  01000 1110 Rm 000     00 E3 BC 88 +CMN (register)      T1  01000 01011 Rm Rn     E3 E0 AB 88 +CMPI (immediate)    T1  00101 Rn imm8         00 C8 E8 85 +CMPR (register)     T1  01000 01010 Rm Rn     E3 E0 AA 88 +CMPRHI (register)   T2  010001011 Rm4 Rd      F3 E0 B6 88      TODO (d + 8) +CMPRLO (register)   T2  010001010 Rm4 Rd      F3 E0 B4 88  +EORS (register)     T1  01000 00001 Rm Rdn    E3 E0 A1 88 +LDRI5 (immediate)   T1  01101 imm5 Rn Rt      D5 E3 E0 8D +LDRI8 (immediate)   T2  10011 Rt imm8         00 C8 E8 93 +LDRL (literal)      T1  01001 Rt imm8         00 C8 E8 89 +LDRR (register)     T1  0101100 Rm Rn Rt      E6 E3 E0 2C +LDRBI (immediate)   T1  01111 imm5 Rn Rt      D5 E3 E0 8F +LDRBR (register)    T1  0101110 Rm Rn Rt      E6 E3 E0 2E +LDRHI (immediate)   T1  10001 imm5 Rn Rt      D5 E3 E0 91 +LDRHR (register)    T1  0101101 Rm Rn Rt      E6 E3 E0 2D +LDRSB (register)    T1  0101011 Rm Rn Rt      E6 E3 E0 2B +LDRSH (register)    T1  0101111 Rm Rn Rt      E6 E3 E0 2F +LSLSI (immediate)   T1  00000 imm5 Rm Rd      D5 E3 E0 80 +LSLSR (register)    T1  01000 00010 Rm Rdn    E3 E0 A2 88 +LSRSI (immediate)   T1  00001 imm5 Rm Rd      D5 E3 E0 81 +LSRSR (register)    T1  01000 00011 Rm Rdn    E3 E0 A3 88 +MOVSI (immediate)   T1  00100 Rd imm8         00 C8 E8 84 +MOVRHI (register)   T1  010001101 Rm4 Rd      F3 E0 BA 88     TODO (d + 8) +MOVRLO (register)   T1  010001100 Rm4 Rd      F3 E0 B8 88 +MOVSR (register)    T2  00000 00000 Rm Rd     E3 E0 A0 80 +MULS                T1  01000 01101 Rn Rdm    E3 E0 AD 88 +MVNS (register)     T1  01000 01111 Rm Rd     E3 E0 AF 88 +ORRS (register)     T1  01000 01100 Rm Rdn    E3 E0 AC 88 +PUSHLR              T1  10110 10100 000000    00 00 B4 96     TODO nothing to do +POPPC               T1  10111 10100 000000    00 00 B4 97 +REV                 T1  10111 01000 Rm Rd     E3 E0 A8 97 +REV16               T1  10111 01001 Rm Rd     E3 E0 A9 97 +REVSH               T1  10111 01011 Rm Rd     E3 E0 AB 97 +RORS (register)     T1  01000 00111 Rm Rdn    E3 E0 A7 88 +NEG (immediate)     T1  01000 01001 Rn Rd     E3 E0 A9 88     TODO it's negate +SBCS (register)     T1  01000 00110 Rm Rdn    E3 E0 A6 88 +STRI5 (immediate)   T1  01100 imm5 Rn Rt      D5 E3 E0 8C +STRI8 (immediate)   T2  10010 Rt imm8         00 C8 E8 92 +STRR (register)     T1  0101000 Rm Rn Rt      E6 E3 E0 28 +STRBI (immediate)   T1  01110 imm5 Rn Rt      D5 E3 E0 8E +STRBR (register)    T1  0101010 Rm Rn Rt      E6 E3 E0 2A +STRHI (immediate)   T1  10000 imm5 Rn Rt      D5 E3 E0 90 +STRHR (register)    T1  0101001 Rm Rn Rt      E6 E3 E0 29 +SUBSI3 (immediate)  T1  0001111 imm3 Rn Rd    D3 E3 E0 0F +SUBSI8 (immediate)  T2  00111 Rdn imm8        00 C8 E8 87 +SUBSR (register)    T1  0001101 Rm Rn Rd      E6 E3 E0 0D +SVC                 T1  11011 111 imm8        00 C8 BC 9B +SXTB                T1  10110 01001 Rm Rd     E3 E0 A9 96 +SXTH                T1  10110 01000 Rm Rd     E3 E0 A8 96 +TST (register)      T1  01000 01000 Rm Rd     E3 E0 A8 88 +UXTB                T1  10110 01011 Rm Rd     E3 E0 AB 96 +UXTH                T1  10110 01010 Rm Rd     E3 E0 AA 96 + +A for ARITHMETIC  +B for BITWISE +C for COMPARE +D for DUPLICATE +J for JUMP +L for LOAD +P for PUSH or POP +R for ROTATE or REVERSE +S for STORE +T for TRANSLATE + +A for ARITHMETIC  +  +AAC     ADCS (register)     T1  01000 00101 Rm Rdn    E3 E0 A5 88 +AAI3    ADDSI3 (immediate)  T1  0001110 imm3 Rn Rd    D3 E3 E0 0E +AAI8    ADDSI8 (immediate)  T2  00110 Rdn imm8        00 C8 E3 86 +AARF    ADDSR (register)    T1  0001100 Rm Rn Rd      E6 E3 E0 0C +AARH    ADDRHI (register)   T2  010001001 Rm4 Rdn     F3 E0 B2 88 +AARL    ADDRLO (register)   T2  010001000 Rm4 Rdn     F3 E0 B0 88 +AAA     ADR                 T1  10100 Rd imm8         00 C8 E3 94 +ASC     SBCS (register)     T1  01000 00110 Rm Rdn    E3 E0 A6 88 +ASI3    SUBSI3 (immediate)  T1  0001111 imm3 Rn Rd    D3 E3 E0 0F +ASI8    SUBSI8 (immediate)  T2  00111 Rdn imm8        00 C8 E8 87 +ASR     SUBSR (register)    T1  0001101 Rm Rn Rd      E6 E3 E0 0D +AHI     SRSI (immediate)    T1  00010 imm5 Rm Rd      D5 E3 E0 82 +AHR     SRSR (register)     T1  01000 00100 Rm Rdn    E3 E0 A4 88 +AM      MULS                T1  01000 01101 Rn Rdm    E3 E0 AD 88 +AN      NEG (immediate)     T1  01000 01001 Rn Rd     E3 E0 A9 88 + +J for JUMP + +JE      BEQ                 T1  11010 000 imm8        00 C8 A0 9A +JN      BNE                 T1  11010 001 imm8        00 C8 A4 9A +JHS     BHS                 T1  11010 010 imm8        00 C8 A8 9A +JLO     BLO                 T1  11010 011 imm8        00 C8 AC 9A +JM      BMI                 T1  11010 100 imm8        00 C8 B0 9A +JP      BPL                 T1  11010 101 imm8        00 C8 B4 9A +JVS     BVS                 T1  11010 110 imm8        00 C8 B8 9A +JVC     BVC                 T1  11010 111 imm8        00 C8 BC 9A +JHI     BHI                 T1  11011 000 imm8        00 C8 A0 9B +JLS     BLS                 T1  11011 001 imm8        00 C8 A4 9B +JGE     BGE                 T1  11011 010 imm8        00 C8 A8 9B +JLT     BLT                 T1  11011 011 imm8        00 C8 AC 9B +JGT     BGT                 T1  11011 100 imm8        00 C8 B0 9B +JLE     BLE                 T1  11011 101 imm8        00 C8 B4 9B +JA      B                   T2  11100 imm11           00 00 CB 9C +JIH     BLHI                T1  11110 imm11           00 00 CB 9E +JIL     BLLO                T1  11111 imm11           00 00 CB 9F +JLR     BLX                 T1  01000 1111 Rm 000     00 E3 BE 88 +JR      BX                  T1  01000 1110 Rm 000     00 E3 BC 88 +JS      SVC                 T1  11011 111 imm8        00 C8 BC 9B + +C for COMPARE + +CN      CMN (register)      T1  01000 01011 Rm Rn     E3 E0 AB 88 +CI      CMPI (immediate)    T1  00101 Rn imm8         00 C8 E8 85 +CR3     CMPR (register)     T1  01000 01010 Rm Rn     E3 E0 AA 88 +CR4H    CMPRHI (register)   T2  010001011 Rm4 Rd      F3 E0 B6 88 +CR4L    CMPRLO (register)   T2  010001010 Rm4 Rd      F3 E0 B4 88  + +L for LOAD + +LI5     LDRI5 (immediate)   T1  01101 imm5 Rn Rt      D5 E3 E0 8D +LI8     LDRI8 (immediate)   T2  10011 Rt imm8         00 C8 E8 93 +LL      LDRL (literal)      T1  01001 Rt imm8         00 C8 E8 89 +LR      LDRR (register)     T1  0101100 Rm Rn Rt      E6 E3 E0 2C +LBI     LDRBI (immediate)   T1  01111 imm5 Rn Rt      D5 E3 E0 8F +LBR     LDRBR (register)    T1  0101110 Rm Rn Rt      E6 E3 E0 2E +LHI     LDRHI (immediate)   T1  10001 imm5 Rn Rt      D5 E3 E0 91 +LHR     LDRHR (register)    T1  0101101 Rm Rn Rt      E6 E3 E0 2D +LSB     LDRSB (register)    T1  0101011 Rm Rn Rt      E6 E3 E0 2B +LSH     LDRSH (register)    T1  0101111 Rm Rn Rt      E6 E3 E0 2F + +S for STORE + +SI5     STRI5 (immediate)   T1  01100 imm5 Rn Rt      D5 E3 E0 8C +SI8     STRI8 (immediate)   T2  10010 Rt imm8         00 C8 E8 92 +SR      STRR (register)     T1  0101000 Rm Rn Rt      E6 E3 E0 28 +SBI     STRBI (immediate)   T1  01110 imm5 Rn Rt      D5 E3 E0 8E +SBR     STRBR (register)    T1  0101010 Rm Rn Rt      E6 E3 E0 2A +SHI     STRHI (immediate)   T1  10000 imm5 Rn Rt      D5 E3 E0 90 +SHR     STRHR (register)    T1  0101001 Rm Rn Rt      E6 E3 E0 29 + +D for DUPLICATE + +DI      MOVSI (immediate)   T1  00100 Rd imm8         00 C8 E8 84 +DRH     MOVRHI (register)   T1  010001101 Rm4 Rd      F3 E0 BA 88 +DRL     MOVRLO (register)   T1  010001100 Rm4 Rd      F3 E0 B8 88 +DRF     MOVSR (register)    T2  00000 00000 Rm Rd     E3 E0 A0 80 +DSB     SXTB                T1  10110 01001 Rm Rd     E3 E0 A9 96 +DSH     SXTH                T1  10110 01000 Rm Rd     E3 E0 A8 96 +DUB     UXTB                T1  10110 01011 Rm Rd     E3 E0 AB 96 +DUH     UXTH                T1  10110 01010 Rm Rd     E3 E0 AA 96 + +B for BITWISE + +BC      BICS (register)     T1  01000 01110 Rm Rdn    E3 E0 AE 88 +BA      ANDS (register)     T1  01000 00000 Rm Rdn    E3 E0 A0 88 +BX      EORS (register)     T1  01000 00001 Rm Rdn    E3 E0 A1 88 +BO      ORRS (register)     T1  01000 01100 Rm Rdn    E3 E0 AC 88 +BI      MVNS (register)     T1  01000 01111 Rm Rd     E3 E0 AF 88 +BT      TST (register)      T1  01000 01000 Rm Rd     E3 E0 A8 88 + +T for TRANSLATE + +TLI     LSLSI (immediate)   T1  00000 imm5 Rm Rd      D5 E3 E0 80 +TLR     LSLSR (register)    T1  01000 00010 Rm Rdn    E3 E0 A2 88 +TRI     LSRSI (immediate)   T1  00001 imm5 Rm Rd      D5 E3 E0 81 +TRR     LSRSR (register)    T1  01000 00011 Rm Rdn    E3 E0 A3 88 + +R for ROTATE or REVERSE + +RR      RORS (register)     T1  01000 00111 Rm Rdn    E3 E0 A7 88 +RBW     REV                 T1  10111 01000 Rm Rd     E3 E0 A8 97 +RBH     REV16               T1  10111 01001 Rm Rd     E3 E0 A9 97 +RBS     REVSH               T1  10111 01011 Rm Rd     E3 E0 AB 97 + +P for PUSH or POP + +PL      PUSHLR              T1  10110 10100 000000    00 00 B4 96 +PP      POPPC               T1  10111 10100 000000    00 00 B4 97 diff --git a/assembler/notes b/assembler/notes deleted file mode 100644 index 6206eff..0000000 --- a/assembler/notes +++ /dev/null @@ -1,35 +0,0 @@ -Clobber -R0: arg1, uart result -R1: arg2 -R2: -R3: shift_amount -------------- -Save -R4: octal result, register result -R5: word under construction -R6: parse instructions -R8: -R9: end_char - -1yyyxxxx Imm         yyy = shift amount xxxx = bit-width -00000001 Brackets -0011yyyy Reg        yyyy = shift amount -0100yyyy Reg - -MOVS 0x 00 00 88 38 -ADDS 0x 00 00 88 38 -SUBS 0x 00 00 88 38 -CMP  0x 00 00 33 30 -ANDS 0x 00 00 33 30 -ORRS 0x 00 00 33 30 -TST  0x 00 00 33 30 -LSLS 0x 00 E5 33 30 -LSRS 0x 00 E5 33 30 -RORS 0x 00 00 33 30 -LDR  0x E5 33 01 30 -LDRB 0x 36 33 01 30 -STR  0x E5 33 01 30 -STRB 0x 36 33 01 30 -B<c> 0x 00 00 00 88 -B    0x 00 00 00 8B -BX   0x 00 00 00 43 diff --git a/assembler/octal.s b/assembler/octal.s index 7382ca4..18abebd 100644 --- a/assembler/octal.s +++ b/assembler/octal.s @@ -1,25 +1,75 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.type octal, %function +.global octal +  octal:    PUSH {LR} +  MOVS R5, R0 + +  // Handle bit-width = 0 +  BNE 30f  10:    BL get_char -  MOVS R1, '0 -  CMP R0, R1 +  CMP R0, '0    BNE 10b    BL uart_send    MOVS R4, 0  20:    BL get_char -  BEQ 30f -  MOVS R1, '0 -  CMP R0, R1 -  BLO 20b -  MOVS R1, '7 -  CMP R0, R1 -  BHI 20b +  BNE 20b +  POP {PC} +30: + +  // R4 will become '1 or '3 or '7 +  MOVS R0, 3 +  CMP R5, 3 +  BHS 40f +  MOVS R0, R5 +40: +  MOVS R4, 1 +  LSLS R4, R0 +  ADDS R4, ('0 - 1) + +  // Get first char +50: +  BL get_char +  CMP R0, '0 +  BLO 50b +  CMP R0, R4 +  BHI 50b +  BL uart_send +  SUBS R0, '0 +  MOVS R4, R0 + +  // Subtract 1, 2, or 3 from bit-width +  MOVS R1, 0 +60: +  ADDS R1, 1 +  LSRS R0, 1 +  BNE 60b +  SUBS R5, R1 + +  // Loop for remaining chars +70: +  CMP R5, 3 +  BLO 80f +  BL get_char +  BEQ 90f +  CMP R0, '0 +  BLO 70b +  CMP R0, '7 +  BHI 70b    BL uart_send    SUBS R0, '0    LSLS R4, 3    ADDS R4, R0 -  B 20b -30: +  SUBS R5, 3 +  B 70b +80: +  BL get_char +  BNE 80b +90:    POP {PC} diff --git a/assembler/opcode.s b/assembler/opcode.s new file mode 100644 index 0000000..f6e93c4 --- /dev/null +++ b/assembler/opcode.s @@ -0,0 +1,283 @@ +// choice encoding: + +// end of choices +//      3  2  1  0 +//   |------------- +// 0 | __ __ __ 00  +// 4 | __ __ __ __ + +// parse instruction +//      3  2  1  0 +//   |------------- +// 0 | __ __ 00 AA      // AA == ascii char (non-zero) +// 4 | XX XX XX XX      // XX XX XX XX == parse instruction + +// new choice offset +//      3  2  1  0 +//   |------------- +// 0 | __ __ YY AA      // AA == ascii char (YY == non zero) +// 4 | XX XX XX XX      // XX XX == new address + +.syntax unified +.cpu cortex-m0plus +.thumb + +.type opcode, %function +.global opcode + +// R4: start of choices, final result (parse instruction) +// R5: choice pointer +opcode: +  PUSH {LR} +  ADR R4, start     // start at the start +get_match: +  BL get_char +  MOV R5, R4        // reset choice pointer +  B first_time      // don't increment pointer on first time +next_choice: +  ADDS R5, 8        // increment choice pointer +first_time: +  LDRB R1, [R5]     // load char +  TST R1, R1        // test if char is zero +  BEQ get_match     // if run out of options, get a new char +  CMP R0, R1        // check if input matches char +  BNE next_choice   // if not match try next option +  BL uart_send      // echo char send if match +  LDR R4, [R5, 4]   // load parse instruction or offset +  LDRB R1, [R5, 1]  // load parse instruction vs offset byte +  TST R1, R1        // check if zero +  BNE get_match     // non-zero means it's an address +  POP {PC}          // zero means it's a parse instruction + +.align 4 + +start: +  .byte 'A, 0x01 ; .hword 0x0000 ; .word A +  // .byte 'B, 0x00 ; .hword 0x0000 ; .word 0xE3E0AE88 // BICS (register)     T1  01000 01110 Rm Rdn +  // .byte 'C, 0x00 ; .hword 0x0000 ; .word 0xE3E0AB88 // CMN (register)      T1  01000 01011 Rm Rn +  // .byte 'D, 0x00 ; .hword 0x0000 ; .word 0x00C8E884 // MOVSI (immediate)   T1  00100 Rd imm8 +  // .byte 'J, 0x00 ; .hword 0x0000 ; .word 0x00C8A09A // BEQ                 T1  11010 000 imm8 +  // .byte 'L, 0x00 ; .hword 0x0000 ; .word 0xD5E3E08D // LDRI5 (immediate)   T1  01101 imm5 Rn Rt +  // .byte 'P, 0x00 ; .hword 0x0000 ; .word 0x0000B496 // PUSHLR              T1  10110 10100 000000 +  // .byte 'R, 0x00 ; .hword 0x0000 ; .word 0xE3E0A788 // RORS (register)     T1  01000 00111 Rm Rdn +  // .byte 'S, 0x00 ; .hword 0x0000 ; .word 0xD5E3E08C // STRI5 (immediate)   T1  01100 imm5 Rn Rt +  // .byte 'T, 0x00 ; .hword 0x0000 ; .word 0xD5E3E080 // LSLSI (immediate)   T1  00000 imm5 Rm Rd +  .word 0x00000000, 0x00000000 + +A: +  .byte 'A, 0x01 ; .hword 0x0000 ; .word AA +  // .byte 'H, 0x01 ; .hword 0x0000 ; .word AH +  .byte 'M, 0x00 ; .hword 0x0000 ; .word 0xE3E0AD88 // MULS                T1  01000 01101 Rn Rdm +  .byte 'N, 0x00 ; .hword 0x0000 ; .word 0xE3E0A988 // NEG (immediate)     T1  01000 01001 Rn Rd +  // .byte 'S, 0x01 ; .hword 0x0000 ; .word AS +  .word 0x00000000, 0x00000000 + +AA: +  .byte 'A, 0x00 ; .hword 0x0000 ; .word 0x00C8E394 // ADR                 T1  10100 Rd imm8 +  .byte 'C, 0x00 ; .hword 0x0000 ; .word 0xE3E0A588 // ADCS (register)     T1  01000 00101 Rm Rdn +  .byte 'I, 0x01 ; .hword 0x0000 ; .word AAI +  .byte 'R, 0x01 ; .hword 0x0000 ; .word AAR +  .word 0x00000000, 0x00000000 + +AAI: +  .byte '3, 0x00 ; .hword 0x0000 ; .word 0xD3E3E00E // ADDSI3 (immediate)  T1  0001110 imm3 Rn Rd +  .byte '8, 0x00 ; .hword 0x0000 ; .word 0x00C8E386 // ADDSI8 (immediate)  T2  00110 Rdn imm8 +  .word 0x00000000, 0x00000000 + +AAR: +  .byte 'F, 0x00 ; .hword 0x0000 ; .word 0xE6E3E00C // ADDSR (register)    T1  0001100 Rm Rn Rd +  .byte 'H, 0x00 ; .hword 0x0000 ; .word 0xF3E0B288 // ADDRHI (register)   T2  010001001 Rm4 Rdn +  .byte 'L, 0x00 ; .hword 0x0000 ; .word 0xF3E0B088 // ADDRLO (register)   T2  010001000 Rm4 Rdn +  .word 0x00000000, 0x00000000 + +// ASC     SBCS (register)     T1  01000 00110 Rm Rdn    E3 E0 A6 88 +// ASI3    SUBSI3 (immediate)  T1  0001111 imm3 Rn Rd    D3 E3 E0 0F +// ASI8    SUBSI8 (immediate)  T2  00111 Rdn imm8        00 C8 E8 87 +// ASR     SUBSR (register)    T1  0001101 Rm Rn Rd      E6 E3 E0 0D + +// AHI     SRSI (immediate)    T1  00010 imm5 Rm Rd      D5 E3 E0 82 +// AHR     SRSR (register)     T1  01000 00100 Rm Rdn    E3 E0 A4 88 + +// Choice 2 +// AH +// --I +// --R + +// Choice 3 +// AS +// --C +// --I +// --R + +// Choice 6 +// B  +// -A +// -C +// -I +// -O +// -T +// -X + +// Choice 3 +// C +// -I +// -N +// -R + +// Choice 2 +// CR +// --3 +// --4 + +// Choice 2 +// CR4 +// ---H +// ---L + +// Choice 4 +// D +// -I +// -R +// -S +// -U + +// Choice 3 +// DR +// --F +// --H +// --L + +// Choice 2 +// DS +// --B +// --H + +// Choice 2 +// DU +// --B +// --H + +// Choice 12 +// J +// -A +// -E +// -G +// -H +// -I +// -L +// -M +// -N +// -P +// -R +// -S +// -V + +// Choice 2 +// JG +// --E +// --T + +// Choice 2 +// JH +// --I +// --S + +// Choice 2 +// JI +// --H +// --L + +// Choice 5 +// JL +// --E +// --O +// --R +// --S +// --T + +// Choice 2 +// JV +// --C +// --S + +// Choice 6 +// L +// -B +// -H +// -I +// -L +// -R +// -S + +// Choice 2 +// LB +// --I +// --R + +// Choice 2 +// LH +// --I +// --R + +// Choice 2 +// LI +// --5 +// --8 + +// Choice 2 +// LS +// --B +// --H + +// Choice 2 +// P +// -L +// -P + +// Choice 2 +// R +// -B +// -R + +// Choice 3 +// RB +// --H +// --S +// --W + +// Choice 4 +// S +// -B +// -H +// -I +// -R + +// Choice 2 +// SB +// --I +// --R + +// Choice 2 +// SH +// --I +// --R + +// Choice 2 +// SI +// --5 +// --8 + +// Choice 2 +// T +// -L +// -R + +// Choice 2 +// TL +// --I +// --R + +// Choice 2 +// TR +// --I +// --R diff --git a/assembler/register.s b/assembler/register.s index dd0e1ae..348d8cf 100644 --- a/assembler/register.s +++ b/assembler/register.s @@ -1,62 +1,55 @@ -register4: +.syntax unified +.cpu cortex-m0plus +.thumb + +.type register, %function +.global register + +register:    PUSH {LR} +  MOV R4, R0 +  LSLS R4, 1 +  ADDS R4, ('0 + 1)  10:    BL get_char    MOVS R1, 'R -  CMPS R0, R1 +  CMP R0, R1    BNE 10b +  BL uart_send  20:    BL get_char    MOVS R1, '0 -  CMPS R0, R1 +  CMP R0, R1    BLO 20b -  MOVS R1, '9 -  CMPS R0, R1 +  CMP R0, R4    BHI 20b +  BL uart_send    MOVS R1, '1 -  CMPS R0, R1 +  CMP R0, R1    BNE 30f +  MOVS R1, '7 +  CMP R4, R1 +  BEQ 30f  50:    BL get_char +  // CMP R0, '  // space is stop char    BEQ 60f    MOVS R1, '0 -  CMPS R0, R1 +  CMP R0, R1    BLO 50b    MOVS R1, '5 -  CMPS R0, R1 +  CMP R0, R1    BHI 50b +  BL uart_send    ADDS R0, 10  30:    SUBS R0, '0 -  MOVS R4, 0 -  ORRS R4, R0 +  MOV R4, R0  40:    BL get_char +  // CMP R0, '  // space is stop char    BNE 40b    POP {PC}  60:    MOVS R4, 1    POP {PC} - -register3: -  PUSH {LR} -10: -  BL get_char -  MOVS R1, 'R -  CMPS R0, R1 -  BNE 10b -20: -  BL get_char -  MOVS R1, '0 -  CMPS R0, R1 -  BLO 20b -  MOVS R1, '7 -  CMPS R0, R1 -  BHI 20b -30: -  SUBS R0, '0 -  MOVS R4, 0 -  ORRS R4, R0 -  BL get_char -  BNE 40b -  POP {PC} diff --git a/assembler/string.s b/assembler/string.s deleted file mode 100644 index 0ed7ca3..0000000 --- a/assembler/string.s +++ /dev/null @@ -1,16 +0,0 @@ -// R0 : string1 address -// R1 : string2 address -// Result in R0 -string_compare: -  MOVS R4, 0 -loop: -  LDRB R2, [R0, R4] -  LDRB R3, [R1, R4] -  CMP R2, R3 -  BNE done -  CMP R2, 0 -  BEQ done -  ADDS R4, 1 -  B loop -done: -  BX LR | 
