diff options
author | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2024-08-23 19:46:17 -0500 |
---|---|---|
committer | Jacques Comeaux <jacquesrcomeaux@protonmail.com> | 2024-08-23 19:46:17 -0500 |
commit | 80d8f3ae48255f786bd4d52a1819ea0c339f6946 (patch) | |
tree | 70126a16181caf459cfcf79fce983655a7a704e5 | |
parent | b08def431c09449b5ad2ff4379fb403b2e1bf67b (diff) |
Add register parser and binary search for opcodes
-rw-r--r-- | newasm/Makefile | 8 | ||||
-rw-r--r-- | newasm/input.s | 1 | ||||
-rw-r--r-- | newasm/main.s | 23 | ||||
-rw-r--r-- | newasm/optable.s | 57 | ||||
-rw-r--r-- | newasm/parsers/decimal.s | 39 | ||||
-rw-r--r-- | newasm/parsers/label.s (renamed from newasm/label.s) | 8 | ||||
-rw-r--r-- | newasm/parsers/opcode.s (renamed from newasm/opcode.s) | 8 | ||||
-rw-r--r-- | newasm/parsers/register.s | 46 | ||||
-rw-r--r-- | newasm/parsers/symbol.s (renamed from newasm/symbol.s) | 8 | ||||
-rw-r--r-- | newasm/parsers/whitespace.s (renamed from newasm/whitespace.s) | 8 | ||||
-rw-r--r-- | newasm/statement.s | 17 | ||||
-rw-r--r-- | newasm/string.s | 6 |
12 files changed, 196 insertions, 33 deletions
diff --git a/newasm/Makefile b/newasm/Makefile index 7b31eb4..fd057fe 100644 --- a/newasm/Makefile +++ b/newasm/Makefile @@ -11,7 +11,13 @@ parse.bin: parse.elf arm-none-eabi-objcopy -O binary parse.elf parse.bin objects = main.o uart.o data.o string.o input.o \ - statement.o whitespace.o label.o symbol.o opcode.o + statement.o optable.o \ + parsers/whitespace.o \ + parsers/label.o \ + parsers/symbol.o \ + parsers/opcode.o \ + parsers/register.o \ + parsers/decimal.o parse.elf: pico_bin.ld $(objects) arm-none-eabi-ld -T pico_bin.ld -o parse.elf $(objects) diff --git a/newasm/input.s b/newasm/input.s index f3db1e9..7644a81 100644 --- a/newasm/input.s +++ b/newasm/input.s @@ -8,6 +8,7 @@ getline: PUSH {R4, R5, LR} // save registers MOVS R4, R0 // copy buffer start address + MOVS R5, 0 // beginning offset next: BL uart_recv // get a char CMP R0, 0x03 // end of text (^C) BEQ cancel // don't submit, start on next line diff --git a/newasm/main.s b/newasm/main.s index 57a1b98..a27fec9 100644 --- a/newasm/main.s +++ b/newasm/main.s @@ -5,33 +5,34 @@ .type main, %function .global main, strbuf -main: LDR R4, =0x20002000 +main: LDR R5, =0x20002000 BL uart_recv loop: BL prompt LDR R0, inpbuf BL getline LDR R0, inpbuf BL putstrln - LDR R1, inpbuf + LDR R4, inpbuf LDR R2, strbuf MOVS R0, 0 STRB R0, [R2] BL statement BNE bad + good: ADR R0, success PUSH {R1} BL putstrln - POP {R0} - BL putstrln - LDR R0, strbuf + MOVS R0, R4 BL putstrln + POP {R0} + BL send_hex + LDR R0, =crlf + BL putstr B loop + bad: ADR R0, fail - PUSH {R1} - BL putstrln - POP {R0} BL putstrln - LDR R0, strbuf + MOVS R0, R4 BL putstrln B loop never: BL uart_recv @@ -39,11 +40,11 @@ never: BL uart_recv BX R0 prompt: PUSH {LR} - MOVS R0, R4 + MOVS R0, R5 BL send_hex MOVS R0, ' BL uart_send - LDR R0, [R4] + LDR R0, [R5] BL send_hex MOVS R0, ' BL uart_send diff --git a/newasm/optable.s b/newasm/optable.s new file mode 100644 index 0000000..a063f02 --- /dev/null +++ b/newasm/optable.s @@ -0,0 +1,57 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.type lookup, %function +.global lookup + +// 1 unexpected char +// 2 unexpected end of input + +// input: +// R0 input string (unboxed) + +// output: +// R0 return code +// R1 instruction template +// R2 instruction type +// R3 special code + +lookup: PUSH {R4, R5, R6} + ADR R4, op_table// op table base address + MOVS R5, 0 // begin pointer + MOVS R6, 7 // end pointer +loop: CMP R5, R6 // if begin == end then range = 0 + BEQ error + ADDS R2, R5, R6 // get sum + LSRS R2, 1 // divide by two +no_jiggle:LSLS R3, R2, 3 // times 8 (index to offset) + LDR R1, [R4, R3]// read opcode from optable + CMP R0, R1 // compare opcode to input + BLO lower // if lower + BHI higher // if higher +found: LSLS R2, 3 // times 8 (index to offset) + ADDS R4, R2 // select row + MOVS R0, 0 // success return code + LDRH R1, [R4, 4] // get machine code template + LDRB R2, [R4, 6] // get instruction type + LDRB R3, [R4, 7] // get special code + POP {R4, R5, R6} + BX LR // result in R2 +lower: MOVS R6, R2 // update end pointer + B loop +higher: ADDS R5, R2, 1 // update begin pointer + B loop +error: MOVS R0, 1 // return code 1 (not found) + POP {R4, R5, R6} + BX LR + + .align 8 +op_table: + .ascii "ADD3"; .hword 0x1C00; .byte 0x01, 0x03 // instr type 1, special code 3 (imm width) + .ascii "ADD8"; .hword 0x3000; .byte 0x02, 0x08 // instr type 2, special code 8 (imm width) + .ascii "ASPI"; .hword 0xB000; .byte 0x04, 0x07 // instr type 4, special code 7 + .ascii "ASRI"; .hword 0x1000; .byte 0x01, 0x05 // instr type 1, special code 5 (imm width) + .ascii "ADCS"; .hword 0x4140; .byte 0x00, 0x00 // instr type 0, special code 0 + .ascii "ADDS"; .hword 0x1400; .byte 0x03, 0x00 // instr type 3, special code 0 + .ascii "BKPT"; .hword 0xBE00; .byte 0x04, 0x08 // instr type 4, special code 8 diff --git a/newasm/parsers/decimal.s b/newasm/parsers/decimal.s new file mode 100644 index 0000000..a1516d2 --- /dev/null +++ b/newasm/parsers/decimal.s @@ -0,0 +1,39 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.type decimal, %function +.global decimal + +// 1 not a digit + +// R4 input stream +// R2 output value + +decimal: LDRB R0, [R4] // get a char + CMP R0, '0 // check if zero + BNE notzero + ADDS R4, 1 // consume the char + MOVS R2, 0 // return value of zero +success: MOVS R0, #0 // return code zero (success) + BX LR +notzero: CMP R0, '1 // if not [1-9] then error + BLO bad + CMP R0, '9 + BHI bad + ADDS R4, 1 // consume the first digit + SUBS R0, '0 // calculate the value + MOVS R2, R0 // store it in R2 +loop: LDRB R0, [R4] // get another char + CMP R0, '0 // if not [0-9] then done + BLO success + CMP R0, '9 + BHI success + ADDS R4, 1 // consume the additional digit + SUBS R0, '0 // calculate the value + MOVS R3, 10 // base 10 + MULS R2, R3 // shift result by one decimal place + ADDS R2, R0 // accumulate into R2 + B loop // keep getting digits +bad: MOVS R0, #1 // return code 1 (not a digit) + BX LR diff --git a/newasm/label.s b/newasm/parsers/label.s index af2f641..4770e6c 100644 --- a/newasm/label.s +++ b/newasm/parsers/label.s @@ -8,11 +8,11 @@ // 1 unexpected begin char // 2 doesn't end with colon -// R1 input buffer +// R4 input buffer // R2 output buffer label: PUSH {LR} - LDRB R0, [R1] // get a char + LDRB R0, [R4] // get a char CMP R0, 0x61 // a BLO 1f CMP R0, 0x7A // z @@ -20,11 +20,11 @@ label: PUSH {LR} 1: MOVS R0, #1 // return code 1 (expected lowercase) POP {PC} 2: BL symbol - LDRB R0, [R1] // get a char + LDRB R0, [R4] // get a char CMP R0, ': // colon BEQ 3f MOVS R0, #2 // return code 2 (expected colon) POP {PC} -3: ADDS R1, 1 // consume the colon +3: ADDS R4, 1 // consume the colon MOVS R0, #0 // return code 0 (success) POP {PC} diff --git a/newasm/opcode.s b/newasm/parsers/opcode.s index 71a5201..8ec327d 100644 --- a/newasm/opcode.s +++ b/newasm/parsers/opcode.s @@ -7,21 +7,21 @@ // 1 unexpected first char -// R1 input buffer +// R4 input buffer // R2 output buffer opcode: PUSH {LR} - LDRB R0, [R1] // get a char + LDRB R0, [R4] // get a char CMP R0, 0x41 // A BLO 1f CMP R0, 0x5A // Z BLS 2f 1: MOVS R0, #1 // unexpected char POP {PC} -2: ADDS R1, 1 // consume the character +2: ADDS R4, 1 // consume the character STRB R0, [R2] // store in temp buffer ADDS R2, 1 // advance temp buffer pointer - LDRB R0, [R1] // get another character + LDRB R0, [R4] // get another character BL goodchar // check if valid symbol char BEQ 2b // if so keep getting chars MOVS R0, #0 // return code success diff --git a/newasm/parsers/register.s b/newasm/parsers/register.s new file mode 100644 index 0000000..48ebf7a --- /dev/null +++ b/newasm/parsers/register.s @@ -0,0 +1,46 @@ +.syntax unified +.cpu cortex-m0plus +.thumb + +.type register, %function +.global register + +// 1 unexpected char +// 2 invalid general-purpose register number + +// R4 input buffer +// R2 output buffer + +register: PUSH {LR} + LDRB R0, [R4] +r_test: CMP R0, 'R + BNE special + ADDS R4, 1 // consume R + BL decimal // consume a decimal number (result in R2) + BEQ validate + POP {PC} // error code already in R0 +validate: CMP R2, #12 // general purpose registers 0-12 + BLS success + MOVS R0, #2 // invalid register number error code + POP {PC} +special: LDRH R0, [R4] // get two bytes from input stream + ADR R2, table // get address of table + MOVS R3, 0 // set table offset to 0 +loop: LDRH R1, [R2, R3] // get two bytes from table at current offset + CMP R0, R1 // compare input to table row + BEQ done // if equal then done + ADDS R3, 2 // increment table offset + CMP R3, 6 // compare offset to table size + BLO loop // loop until end of table + MOVS R0, #1 // return code 1 (unexpected char) + POP {PC} +done: ADDS R4, 2 // consume two chars + LSRS R3, 1 // divide table offset by two to row + ADDS R3, 13 // add 13 to get register number + MOVS R2, R3 +success: MOVS R0, #0 // return code 0 (success) + POP {PC} + +table: .ascii "SP" + .ascii "LR" + .ascii "PC" diff --git a/newasm/symbol.s b/newasm/parsers/symbol.s index 0677f6a..f57d493 100644 --- a/newasm/symbol.s +++ b/newasm/parsers/symbol.s @@ -7,19 +7,19 @@ // 1 unexpected begin char -// R1 input buffer +// R4 input buffer // R2 output buffer symbol: PUSH {LR} - LDRB R0, [R1] // get a char + LDRB R0, [R4] // get a char BL goodchar // check if valid symbol char BEQ loop MOVS R0, #1 // unexpected begin char POP {PC} -loop: ADDS R1, 1 // consume the character +loop: ADDS R4, 1 // consume the character STRB R0, [R2] // store in temp buffer ADDS R2, 1 // advance temp buffer pointer - LDRB R0, [R1] // get another character + LDRB R0, [R4] // get another character BL goodchar // check if valid symbol char BEQ loop // if so keep getting chars MOVS R0, #0 // return code success diff --git a/newasm/whitespace.s b/newasm/parsers/whitespace.s index f4d8d9f..708cab3 100644 --- a/newasm/whitespace.s +++ b/newasm/parsers/whitespace.s @@ -7,14 +7,16 @@ // 1 unexpected char +// R4 input buffer + whitespace: - LDRB R0, [R1] // get a char + LDRB R0, [R4] // get a char CMP R0, ' // space BEQ 1f MOVS R0, #1 // return code 1 (unexpected char) BX LR -1: ADDS R1, 1 // consume the character - LDRB R0, [R1] // get another character +1: ADDS R4, 1 // consume the character + LDRB R0, [R4] // get another character CMP R0, ' // check if space BEQ 1b // if so keep getting chars MOVS R0, #0 // return code 0 (success) diff --git a/newasm/statement.s b/newasm/statement.s index 83f8d8d..4a199a6 100644 --- a/newasm/statement.s +++ b/newasm/statement.s @@ -7,24 +7,31 @@ // 1 reported an error -// R1 input buffer +// R4 input buffer // R2 output buffer statement:PUSH {LR} BL whitespace + PUSH {R2} BL label + POP {R2} CMP R0, #2 // check for error code 2 (no colon) BNE 1f ADR R0, no_colon B err_exit 1: BL whitespace + PUSH {R2} BL opcode + POP {R2} BEQ 2f ADR R0, no_opcode B err_exit -2: MOVS R0, #0 - POP {PC} - +2: LDR R0, [R2] + BL lookup + BEQ 3f + ADR R0, not_found + B err_exit +3: POP {PC} // success code already in R0 err_exit: BL putstrln MOVS R0, #1 // return code 1 (there was an error) POP {PC} @@ -33,3 +40,5 @@ err_exit: BL putstrln no_colon: .asciz "Error: Expected colon at end of label" .align 4 no_opcode: .asciz "Error: Expected an opcode" + .align 4 +not_found: .asciz "Error: Opcode not found" diff --git a/newasm/string.s b/newasm/string.s index c77958b..d897a98 100644 --- a/newasm/string.s +++ b/newasm/string.s @@ -28,7 +28,8 @@ putstrln: BL putstr POP {PC} -cmpstr: MOVS R4, 0 +cmpstr: PUSH {R4} + MOVS R4, 0 1: LDRB R2, [R0, R4] LDRB R3, [R1, R4] CMP R2, R3 @@ -37,4 +38,5 @@ cmpstr: MOVS R4, 0 BEQ 2f ADDS R4, 1 B 1b -2: BX LR +2: POP {R4} + BX LR |