diff options
| author | Andrew Chambers <[email protected]> | 2021-10-09 00:33:47 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-09 00:33:47 +1300 |
| commit | ee80372abea5d9a2ff100f1ddb8be08470cc272d (patch) | |
| tree | 4904b7d3deb3ae5289acaa4c4461a78d45caabf6 | |
| parent | a8cc59047d02d5c5b352b10a630f73249dc24a5d (diff) | |
Refactor.
| -rw-r--r-- | asm.peg | 37 | ||||
| -rw-r--r-- | main.c | 9 | ||||
| -rw-r--r-- | test/test.sh | 121 |
3 files changed, 81 insertions, 86 deletions
@@ -56,7 +56,20 @@ lea = | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR(2, s, d); } ) { $$.instr.kind = ASM_LEA; } -#XXX Some of these rules can probably be collapsed (or expanded for simplicity?). + +r-rm-opargs = + 'b'? ws s:m ws? ',' ws? d:r8 { $$ = INSTR(0, s, d); } + | 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR(1, s, d); } + | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR(2, s, d); } + | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR(3, s, d); } + | 'b'? ws s:r8 ws? ',' ws? d:m { $$ = INSTR(4, s, d); } + | 'w'? ws s:r16 ws? ',' ws? d:m { $$ = INSTR(5, s, d); } + | 'l'? ws s:r32 ws? ',' ws? d:m { $$ = INSTR(6, s, d); } + | 'q'? ws s:r64 ws? ',' ws? d:m { $$ = INSTR(7, s, d); } + | 'b'? ws s:r8 ws? ',' ws? d:r8 { $$ = INSTR(8, s, d); } + | 'w'? ws s:r16 ws? ',' ws? d:r16 { $$ = INSTR(9, s, d); } + | 'l'? ws s:r32 ws? ',' ws? d:r32 { $$ = INSTR(10, s, d); } + | 'q'? ws s:r64 ws? ',' ws? d:r64 { $$ = INSTR(11, s, d); } mov = "mov" ( 'b'? ws s:imm8 ws? ',' ws? d:r8 { $$ = INSTR(0, s, d); } @@ -67,18 +80,7 @@ mov = "mov" ( | 'w' ws s:imm16 ws? ',' ws? d:m { $$ = INSTR(5, s, d); } | 'l' ws s:imm32 ws? ',' ws? d:m { $$ = INSTR(6, s, d); } | 'q' ws s:imm32 ws? ',' ws? d:m { $$ = INSTR(7, s, d); } - | 'b'? ws s:m ws? ',' ws? d:r8 { $$ = INSTR(8, s, d); } - | 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR(9, s, d); } - | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR(10, s, d); } - | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR(11, s, d); } - | 'b'? ws s:r8 ws? ',' ws? d:m { $$ = INSTR(12, s, d); } - | 'w'? ws s:r16 ws? ',' ws? d:m { $$ = INSTR(13, s, d); } - | 'l'? ws s:r32 ws? ',' ws? d:m { $$ = INSTR(14, s, d); } - | 'q'? ws s:r64 ws? ',' ws? d:m { $$ = INSTR(15, s, d); } - | 'b'? ws s:r8 ws? ',' ws? d:r8 { $$ = INSTR(16, s, d); } - | 'w'? ws s:r16 ws? ',' ws? d:r16 { $$ = INSTR(17, s, d); } - | 'l'? ws s:r32 ws? ',' ws? d:r32 { $$ = INSTR(18, s, d); } - | 'q'? ws s:r64 ws? ',' ws? d:r64 { $$ = INSTR(19, s, d); } + | args:r-rm-opargs { args.instr.variant += 8; $$ = args; } ) { $$.instr.kind = ASM_MOV; } xchg = @@ -89,14 +91,7 @@ xchg = | 'l'? ws s:r32 ws? ',' ws? d:eax { $$ = INSTR(3, s, d); } | 'q'? ws s:rax ws? ',' ws? d:r64 { $$ = INSTR(4, s, d); } | 'q'? ws s:r64 ws? ',' ws? d:rax { $$ = INSTR(5, s, d); } - | 'b'? ws s:r-m8 ws? ',' ws? d:r8 { $$ = INSTR(6, s, d); } - | 'b'? ws s:r8 ws? ',' ws? d:r-m8 { $$ = INSTR(7, s, d); } - | 'w'? ws s:r16 ws? ',' ws? d:r-m16 { $$ = INSTR(8, s, d); } - | 'w'? ws s:r-m16 ws? ',' ws? d:r16 { $$ = INSTR(9, s, d); } - | 'l'? ws s:r32 ws? ',' ws? d:r-m32 { $$ = INSTR(10, s, d); } - | 'l'? ws s:r-m32 ws? ',' ws? d:r32 { $$ = INSTR(11, s, d); } - | 'q'? ws s:r64 ws? ',' ws? d:r-m64 { $$ = INSTR(12, s, d); } - | 'q'? ws s:r-m64 ws? ',' ws? d:r64 { $$ = INSTR(13, s, d); } + | args:r-rm-opargs { args.instr.variant += 6; $$ = args; } ) { $$.instr.kind = ASM_XCHG; } add = "add" a:basic-op-args { a.instr.kind = ASM_ADD; $$ = a; } @@ -439,15 +439,16 @@ static void assemblebasicop(Instr *instr, uint8_t opcode, uint8_t immreg) { } static void assemblexchg(Instr *xchg) { - static uint8_t variant2op[14] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x86, - 0x86, 0x87, 0x87, 0x87, 0x87, 0x87, 0x87}; + static uint8_t variant2op[18] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, + 0x86, 0x87, 0x87, 0x87, 0x86, 0x87, + 0x87, 0x87, 0x86, 0x87, 0x87, 0x87}; uint8_t opcode = variant2op[xchg->variant]; - if (xchg->variant <= 5) { + if (xchg->variant < 6) { assembleplusr(opcode, (xchg->variant % 2) ? xchg->src->kind : xchg->dst->kind); } else { /* Uses a pattern in the variant table. */ - uint8_t opsz = 1 << (((xchg->variant - 6) / 2) % 4); + uint8_t opsz = 1 << ((xchg->variant - 6) % 4); assemblerrm(xchg, opcode, opsz); } } diff --git a/test/test.sh b/test/test.sh index ec9db55..3fb4cc5 100644 --- a/test/test.sh +++ b/test/test.sh @@ -30,6 +30,34 @@ t () { echo -n "." } +for r in a b +do + t "xchg %${r}l, %${r}l" + t "xchg %${r}x, %${r}x" + t "xchg %${r}x, %bx" + t "xchg %bx, %${r}x" + # t "xchg %e${r}x, %e${r}x" # clang disagrees + t "xchg %e${r}x, %ebx" + t "xchg %ebx, %e${r}x" + t "xchg %r${r}x, %rbx" + t "xchg %rbx, %r${r}x" + t "xchg %r${r}x, (%r${r}x)" + t "xchg %e${r}x, (%r${r}x)" + t "xchg %${r}x, (%r${r}x)" + t "xchg %${r}l, (%r${r}x)" + t "xchg (%r${r}x), %r${r}x" + t "xchg (%r${r}x), %e${r}x" + t "xchg (%r${r}x), %${r}x" + t "xchg (%r${r}x), %${r}l" +done + + +for r in a b + do + t "leaq (%r${r}x), %r${r}x" + t "leal (%r${r}x), %e${r}x" + t "leaw (%r${r}x), %${r}x" +done for op in mov add and or sub xor do @@ -39,69 +67,40 @@ do t "${op}l \$2147483647, (%rip)" t "${op}q \$2147483647, (%rip)" - # Special case a register variants. - t "${op}b \$127, %al" - t "${op}w \$32767, %ax" - t "${op}l \$2147483647, %eax" - t "${op}q \$2147483647, %rax" + t "${op}q %r9, %r9" - # immediate variants. - t "${op}b \$127, (%rbx)" - t "${op}w \$32767, (%rbx)" - t "${op}l \$2147483647, (%rbx)" - t "${op}q \$2147483647, (%rbx)" - t "${op}b \$127, %bl" - t "${op}w \$32767, %bx" - t "${op}l \$2147483647, %ebx" - t "${op}q \$2147483647, %rbx" + for r in a b + do + # immediate variants. + t "${op}b \$127, (%r${r}x)" + t "${op}w \$32767, (%r${r}x)" + t "${op}l \$2147483647, (%r${r}x)" + t "${op}q \$2147483647, (%r${r}x)" + t "${op}b \$127, %${r}l" + t "${op}w \$32767, %${r}x" + t "${op}l \$2147483647, %e${r}x" + t "${op}q \$2147483647, %r${r}x" - # r rm variants - t "${op}b (%rax), %al" - t "${op}w (%rax), %ax" - t "${op}l (%rax), %eax" - t "${op}q (%rax), %rax" - t "${op}q (%rbp), %rax" - t "${op}q (%r8), %rax" - t "${op}q (%r13), %rax" - t "${op}b %al, (%rax)" - t "${op}w %ax, (%rax)" - t "${op}l %eax, (%rax)" - t "${op}q %rax, (%rax)" - t "${op}q %rax, (%rbp)" - t "${op}q %rax, (%r8)" - t "${op}q %rax, (%r13)" - t "${op}b %al, %al" - t "${op}w %ax, %ax" - t "${op}l %eax, %eax" - t "${op}q %rax, %rax" - t "${op}q %r9, %r9" + # r rm variants + t "${op}b (%rax), %${r}l" + t "${op}w (%rax), %${r}x" + t "${op}l (%rax), %e${r}x" + t "${op}q (%rax), %r${r}x" + t "${op}q (%rbp), %r${r}x" + t "${op}q (%r8), %r${r}x" + t "${op}q (%r13), %r${r}x" + t "${op}b %${r}l, (%rax)" + t "${op}w %${r}x, (%rax)" + t "${op}l %e${r}x, (%rax)" + t "${op}q %r${r}x, (%rax)" + t "${op}q %r${r}x, (%rbp)" + t "${op}q %r${r}x, (%r8)" + t "${op}q %r${r}x, (%r13)" + t "${op}b %${r}l, %al" + t "${op}w %${r}x, %ax" + t "${op}l %e${r}x, %eax" + t "${op}q %r${r}x, %rax" + done done -t "xchg %al, %al" -t "xchg %ax, %ax" -t "xchg %ax, %r9w" -t "xchg %r9w, %ax" -t "xchg %ax, %bx" -t "xchg %bx, %ax" -#t "xchg %eax, %eax" # clang disagrees -t "xchg %eax, %r9d" -t "xchg %r9d, %eax" -t "xchg %eax, %ebx" -t "xchg %ebx, %eax" -t "xchg %rax, %r9" -t "xchg %r9, %rax" -t "xchg %rax, %rbx" -t "xchg %rbx, %rax" -t "xchg %rax, (%rax)" -t "xchg %eax, (%rax)" -t "xchg %ax, (%rax)" -t "xchg %al, (%rax)" -t "xchg (%rax), %rax" -t "xchg (%rax), %eax" -t "xchg (%rax), %ax" -t "xchg (%rax), %al" - -t "leaq (%rax), %rax" -t "leal (%rax), %eax" -t "leaw (%rax), %ax" |
