aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-10 13:10:36 +1300
committerAndrew Chambers <[email protected]>2021-10-10 13:10:36 +1300
commit0c15252bb0ca5a1f2f38ad2bd33c025d79590716 (patch)
tree11fbc2a003a24c7280abca4576877d18b7db60b8
parenta1c13cabff6e80e6f3d025294b355a26300894e5 (diff)
Three address form of imul.
-rw-r--r--asm.peg19
-rw-r--r--main.c7
-rw-r--r--test/test.sh8
3 files changed, 26 insertions, 8 deletions
diff --git a/asm.peg b/asm.peg
index 08c5884..8076cce 100644
--- a/asm.peg
+++ b/asm.peg
@@ -110,12 +110,19 @@ mul = "mul" (
imul = "imul" (
(
- 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR2(8, s, d); }
- | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR2(9, s, d); }
- | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR2(10, s, d); }
- | 'w'? ws s:r16 ws? ',' ws? d:r16 { $$ = INSTR2(11, s, d); }
- | 'l'? ws s:r32 ws? ',' ws? d:r32 { $$ = INSTR2(12, s, d); }
- | 'q'? ws s:r64 ws? ',' ws? d:r64 { $$ = INSTR2(13, s, d); }
+ 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR2(8, s, d); }
+ | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR2(9, s, d); }
+ | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR2(10, s, d); }
+ | 'w'? ws s:r16 ws? ',' ws? d:r16 { $$ = INSTR2(11, s, d); }
+ | 'l'? ws s:r32 ws? ',' ws? d:r32 { $$ = INSTR2(12, s, d); }
+ | 'q'? ws s:r64 ws? ',' ws? d:r64 { $$ = INSTR2(13, s, d); }
+
+ | 'w'? ws i:imm16 ',' ws? s:m ws? ',' ws? d:r16 { $$ = INSTR3(14, s, d, i); }
+ | 'l'? ws i:imm32 ',' ws? s:m ws? ',' ws? d:r32 { $$ = INSTR3(15, s, d, i); }
+ | 'q'? ws i:imm32 ',' ws? s:m ws? ',' ws? d:r64 { $$ = INSTR3(16, s, d, i); }
+ | 'w'? ws i:imm16 ',' ws? s:r16 ws? ',' ws? d:r16 { $$ = INSTR3(17, s, d, i); }
+ | 'l'? ws i:imm32 ',' ws? s:r32 ws? ',' ws? d:r32 { $$ = INSTR3(18, s, d, i); }
+ | 'q'? ws i:imm32 ',' ws? s:r64 ws? ',' ws? d:r64 { $$ = INSTR3(19, s, d, i); }
)
| args:divmul-opargs { $$ = args; } # Must come last due to peg ordering.
) { $$.instr.kind = ASM_IMUL; }
diff --git a/main.c b/main.c
index a994b21..e422c42 100644
--- a/main.c
+++ b/main.c
@@ -740,7 +740,12 @@ static void assemble(void) {
opsz = 1 << (1 + ((v->instr.variant - 8) % 3));
assemblerrm(&v->instr, opcode, opsz);
} else {
- unreachable();
+ Imm *imm;
+ opcode = 0x69;
+ opsz = 1 << (1 + ((v->instr.variant - 14) % 3));
+ assemblerrm(&v->instr, opcode, opsz);
+ imm = &v->instr.arg3->imm;
+ assemblereloc(imm->l, imm->c, imm->nbytes, R_X86_64_32);
}
break;
}
diff --git a/test/test.sh b/test/test.sh
index 7251e76..f908e4a 100644
--- a/test/test.sh
+++ b/test/test.sh
@@ -48,7 +48,13 @@ t "imul %rax, %rax"
t "imulq (%rax), %rax"
t "imul %eax, %eax"
t "imull (%rax), %eax"
-t "imul %eax, %eax"
+
+t "imul \$2147483647, %rax, %rax"
+t "imul \$2147483647, (%rax), %rax"
+t "imul \$2147483647, %eax, %eax"
+t "imul \$2147483647, (%rax), %eax"
+t "imul \$32767, %ax, %ax"
+t "imul \$32767, (%rax), %ax"
t "pushq (%r9)"
t "pushq %r9"