aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-09 00:33:47 +1300
committerAndrew Chambers <[email protected]>2021-10-09 00:33:47 +1300
commitee80372abea5d9a2ff100f1ddb8be08470cc272d (patch)
tree4904b7d3deb3ae5289acaa4c4461a78d45caabf6
parenta8cc59047d02d5c5b352b10a630f73249dc24a5d (diff)
Refactor.
-rw-r--r--asm.peg37
-rw-r--r--main.c9
-rw-r--r--test/test.sh121
3 files changed, 81 insertions, 86 deletions
diff --git a/asm.peg b/asm.peg
index ad7812f..08fcd9e 100644
--- a/asm.peg
+++ b/asm.peg
@@ -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; }
diff --git a/main.c b/main.c
index cb6c685..9fc57f6 100644
--- a/main.c
+++ b/main.c
@@ -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"