summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--twasm/README.md21
-rw-r--r--twasm/asm/main.asm151
2 files changed, 101 insertions, 71 deletions
diff --git a/twasm/README.md b/twasm/README.md
index 2edc4ee..7295afd 100644
--- a/twasm/README.md
+++ b/twasm/README.md
@@ -267,8 +267,8 @@ entries are as follows:
+----------+----------+----------+---------+
| 31 24 | 23 16 | 15 0 |
+----------+----------+--------------------+
-| reserved | opcode | token ID |
-| | dst=r/m | |
+| opcode+r | opcode | token ID |
+| dst=r | dst=r/m | |
+----------+----------+--------------------+
16 bytes
@@ -300,24 +300,25 @@ entries are as follows:
+-----------------+
| flags byte |
+----------+------+
-| 95 89 | 88 |
+| 95 89 | 88 |
+----------+------+
| reserved | 8bit |
+----------+------+
1 byte
-+----------------------------------------------------+
-| flagsX byte |
-+----------+-----------+-------------+---------------+
-| 7 5 | 4 | 3 | 2 0 |
-+----------+-----------+-------------+---------------+
-| reserved | no ModR/M | 0x0F prefix | operator flag |
-+----------+-----------+-------------+---------------+
++--------------------------------------------------------------+
+| flagsX byte |
++----------+---------+-----------+-------------+---------------+
+| 7 6 | 5 | 4 | 3 | 2 0 |
++----------+---------+-----------+-------------+---------------+
+| reserved | +r flag | no ModR/M | 0x0F prefix | operator flag |
++----------+---------+-----------+-------------+---------------+
; flags key:
8bit ; tte has opcodes for r/m8 and r8 instead of r/m and r respectively
; flagsX key:
++r flag ; there is a +r variation of this opcode
no ModR/M ; there is no ModR/M byte for this opcode
0x0F prefix ; there is a 0x0F prefix for this opcode
operator flag ; contents of `reg` if applicable
diff --git a/twasm/asm/main.asm b/twasm/asm/main.asm
index a0b267e..0e060dc 100644
--- a/twasm/asm/main.asm
+++ b/twasm/asm/main.asm
@@ -63,7 +63,7 @@ start:
pop rdi ; rdi = number of tokens in token table
call assemble
- mov rsi, msg_welcome
+ mov rsi, msg_welcome_1
call OUTPUT_ADDR
jmp halt
@@ -123,6 +123,8 @@ assemble:
call print.debug
pop rsi
+ mov esi, [.buffer_pointer]
+ sub esi, .buffer
mov esi, [.next_output_byte]
sub esi, OUTPUT_ADDR ; esi = relative address of label to start of program
and edi, 0x0FFF ; edi = index to add address hash to
@@ -210,7 +212,8 @@ assemble:
call .get_next_tte
mov rcx, rdi ; cx = operand tte
pop rdi
- push rcx ; pushes until after write_prefix_continue
+ push rcx ; pushes until after write_prefix_continue or before
+ ; plusr_continue
; di = tte of operator
mov sil, 0 ; dst=r/m
@@ -225,9 +228,40 @@ assemble:
.operator_1_get_opcode_label:
mov sil, 4 ; dst=rel
.operator_1_get_opcode_continue:
+ push rdi
+ push rbx
call get_opcode
; al = opcode
; dl = op flag
+ pop rbx ; flags
+ pop rdi ; di
+
+ push rdx
+ and dl, 0x20
+ cmp dl, 0x20
+ pop rdx
+ jne .operator_1_plusr_continue
+
+ mov sil, 1 ; dst=r
+ ; TODO only do this if we've confirmed the next token's a register xD
+ call .clear_write_buffer
+ call get_opcode
+ ; al = opcode
+ ; dl = op flag
+ pop rdi ; di = next tte. from early in .operator_1
+ push rax
+ ; di = tte
+ call get_tte_typed_metadata
+ ; al = register typed metadata
+ mov ecx, eax ; cl = register typed metadata
+ shr ecx, 2
+ and ecx, 111b ; cl = reg value
+ pop rax ; al = opcode
+ add eax, ecx ; opcode + r
+ call .write_byte
+
+ jmp .loop_next_token
+ .operator_1_plusr_continue:
push rdx
and dl, 1000b
cmp dl, 1000b
@@ -240,8 +274,7 @@ assemble:
.operator_1_write_prefix_continue
call .write_byte
pop rdx ; dl = op flag
-
- pop rdi ; di = next tte
+ pop rdi ; di = next tte. from early in .operator_1
push rdi
and di, 0xFF00
@@ -318,7 +351,9 @@ assemble:
call print.debug
pop rsi
- mov esi, [.next_output_byte]
+ mov esi, [.buffer_pointer]
+ sub esi, .buffer
+ add esi, [.next_output_byte]
sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start
; of program
mov eax, 0x04 ; al = first 4 bits: # bytes reserved
@@ -596,7 +631,9 @@ assemble:
jmp .operator_2_register_label_32
.operator_2_register_label_8:
- mov esi, [.next_output_byte]
+ mov esi, [.buffer_pointer]
+ sub esi, .buffer
+ add esi, [.next_output_byte]
sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start
mov eax, 0x11 ; al = first 4 bits: # bits reserved
; 5th bit: abs flag
@@ -606,7 +643,9 @@ assemble:
call .write_byte
jmp .loop_next_token
.operator_2_register_label_16:
- mov esi, [.next_output_byte]
+ mov esi, [.buffer_pointer]
+ sub esi, .buffer
+ add esi, [.next_output_byte]
sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start
mov eax, 0x12 ; al = first 4 bits: # bits reserved
; 5th bit: abs flag
@@ -617,7 +656,9 @@ assemble:
call .write_byte
jmp .loop_next_token
.operator_2_register_label_32:
- mov esi, [.next_output_byte]
+ mov esi, [.buffer_pointer]
+ sub esi, .buffer
+ add esi, [.next_output_byte]
sub esi, OUTPUT_ADDR ; esi = relative address of label reference to start
mov eax, 0x14 ; al = first 4 bits: # bits reserved
; 5th bit: abs flag
@@ -990,19 +1031,8 @@ assemble:
.tokens_processed dd 0
.tokens_total dd 0
- ; al = byte to write
- .output_byte:
- push rdx
- mov edx, [.next_output_byte] ; get output byte's address
- mov [edx], al ; write byte to that address
- inc edx ; increment address
- mov [.next_output_byte], edx ; put output byte's address
- pop rdx
- ret
- .next_output_byte dd OUTPUT_ADDR ; next empty byte in output
- ; TODO get rid of this sketchy bit of state
-
; al = byte to push
+ ; buffered push
.push_byte:
push rcx
mov ecx, [.buffer_pointer]
@@ -1027,6 +1057,7 @@ assemble:
ret
; al = byte to write
+ ; buffered write
.write_byte:
push rdx
mov edx, [.buffer_pointer]
@@ -1036,6 +1067,16 @@ assemble:
pop rdx
ret
+ .clear_write_buffer:
+ push rax
+ xor eax, eax
+ mov [.buffer], rax
+ mov [.buffer + 8], rax
+ mov eax, .buffer
+ mov [.buffer_pointer], eax
+ pop rax
+ ret
+
.flush_write_buffer:
push rcx
push rax
@@ -1054,10 +1095,23 @@ assemble:
pop rax
pop rcx
ret
- .buffer dq 0, 0 ; octo word of space for max of 8 bytes per write
+ .buffer dq 0, 0 ; octo word of space for max of 16 bytes per write
.buffer_end:
.buffer_pointer dd .buffer ; points to current byte in buffer
+ ; al = byte to write
+ ; unbuffered output; prefer `.write_byte`
+ .output_byte:
+ push rdx
+ mov edx, [.next_output_byte] ; get output byte's address
+ mov [edx], al ; write byte to that address
+ inc edx ; increment address
+ mov [.next_output_byte], edx ; put output byte's address
+ pop rdx
+ ret
+ .next_output_byte dd OUTPUT_ADDR ; next empty byte in output
+
+
.msg_unexpected_token db "unexpected token, aborting", 0x0A, 0x00
.msg_unsupported_memory_access db "unsupported memory access, aborting", 0x0A, 0x00
.msg_size_mismatch db "size mismatch, aborting", 0x0A, 0x00
@@ -1097,9 +1151,6 @@ resolve_awaiting_labels:
cmp rdi, 0
je .break
- mov rsi, .msg
- call print.warn
-
push rax
; rdi = raxth hash in awaiting label table
call add_label_hash
@@ -1111,8 +1162,6 @@ resolve_awaiting_labels:
mov esi, [AWAITING_LABEL_TABLE_ADDR + rax + 8] ; esi = address of reference
sub edi, esi ; edi = offset
- ; TODO fix this off-by-one error
- dec edi
; also sub length of reference TODO handle non-4-length refs
sub edi, 4
@@ -1132,7 +1181,7 @@ resolve_awaiting_labels:
pop rdx
jne .break
- mov [OUTPUT_ADDR + 1 + rsi], edi
+ mov [OUTPUT_ADDR + rsi], edi
shr rax, 4
inc rax
@@ -1140,7 +1189,6 @@ resolve_awaiting_labels:
.break:
mov rsp, rbp
ret
- .msg db "resolve_awaiting_labels", 0x0A, 0x00
; ------------------------------------------------------------------------------
; get_tte_type
@@ -1319,13 +1367,13 @@ get_ModRM:
; returned:
; al = opcode; the rest of rax is zeroed.
; dl = flagsX
-; +----------------------------------------------------+
-; | flagsX byte |
-; +----------+-----------+-------------+---------------+
-; | 7 5 | 4 | 3 | 2 0 |
-; +----------+-----------+-------------+---------------+
-; | reserved | no ModR/M | 0x0F prefix | operator flag |
-; +----------+-----------+-------------+---------------+
+; +--------------------------------------------------------------+
+; | flagsX byte |
+; +----------+---------+-----------+-------------+---------------+
+; | 7 6 | 5 | 4 | 3 | 2 0 |
+; +----------+---------+-----------+-------------+---------------+
+; | reserved | +r flag | no ModR/M | 0x0F prefix | operator flag |
+; +----------+---------+-----------+-------------+---------------+
;
; ------------------------------------------------------------------------------
@@ -2217,25 +2265,6 @@ print:
.warn_msg db 0x1B, "[1;35m", "[WARN]: ", 0x1B, "[0m", 0x00
; ------------------------------------------------------------------------------
-; print_least_4_bits
-;
-; description:
-; prints the least significant 4 bits of rax for debugging reasons
-; ------------------------------------------------------------------------------
-
-print_least_4_bits:
- push rax
- push rsi
- add eax, 0x30
- mov [.byte], al
- mov rsi, .byte
- call print.warn
- pop rsi
- pop rax
- ret
- .byte db 0x00, 0x0A, 0x00
-
-; ------------------------------------------------------------------------------
; halt
;
; description:
@@ -3186,30 +3215,30 @@ opcodes:
dw 0x0000
; push
- ; TODO add support for the +r variation
dw 0x005F
db 0xFF ; r/m
- db 0x00
+ db 0x50 ; +r
db 0x68 ; imm16/32
db 0x6A ; imm8
dw 0x0000
- db 0x06 ; 6: r/m
+ db 0x26 ; 26: +r flag, r/m
db 0x00
dw 0x0000
dd 0x00000000
; pop
- ; TODO add support for the +r variation
dw 0x0060
db 0x8F ; r/m
- db 0x00
+ db 0x58 ; +r
dd 0x00000000
- dd 0x00000000
+ db 0x20 ; 20: +r flag, r/m
+ db 0x00
+ dw 0x0000
dd 0x00000000
@@ -3229,6 +3258,7 @@ opcodes:
.by_id_end:
msg_welcome db 0x1B, "[35m", "Welcome to Twasm", 0x1B, "[0m", 0x0A, 0x00
+msg_welcome_1 db 0x1B, "[35m", "Welcome to Twasm (from the next level)", 0x1B, "[0m", 0x0A, 0x00
msg_halt db "halted.", 0x0A, 0x00
whitespace_2 db " ", 0x0D
@@ -3236,7 +3266,6 @@ whitespace_2 db " ", 0x0D
; test program
align 128
program:
- db "ret", 0x0A
db "print:", 0x0A
db " push rdx", 0x0A
db " push rax", 0x0A