aboutsummaryrefslogtreecommitdiff
path: root/assembler/assemble.s
diff options
context:
space:
mode:
authorJacques Comeaux <jacquesrcomeaux@protonmail.com>2024-05-19 13:52:10 -0500
committerJacques Comeaux <jacquesrcomeaux@protonmail.com>2024-05-19 13:52:10 -0500
commitc96ba2b2678e4b92e7969c683d4cb3f1648af813 (patch)
tree38d8eef4cdc62a3ab508b4884a44657b22b9fbf7 /assembler/assemble.s
parenta63eba62ae9faffea51ba618b0d20f132c23c452 (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/assemble.s')
-rw-r--r--assembler/assemble.s147
1 files changed, 88 insertions, 59 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