aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm.peg8
-rw-r--r--main.c42
-rw-r--r--minias.h1
-rw-r--r--test/test.sh120
4 files changed, 51 insertions, 120 deletions
diff --git a/asm.peg b/asm.peg
index f958b8c..fc904d5 100644
--- a/asm.peg
+++ b/asm.peg
@@ -31,7 +31,7 @@ directive =
| "byte" ws v:value
{ $$.dirbyte = (Byte){.kind = ASM_DIR_BYTE, .value = v.value }; }
| "short" ws v:value
- { $$.dirshort = (Short){.kind = ASM_DIR_BYTE, .value = v.value }; }
+ { $$.dirshort = (Short){.kind = ASM_DIR_SHORT, .value = v.value }; }
| "int" ws v:value
{ $$.dirint = (Int){.kind = ASM_DIR_INT, .value = v.value }; }
| "quad" ws v:value
@@ -115,6 +115,7 @@ instr =
# Floating point is less common, so check last.
| i:addss { $$ = i; }
| i:addsd { $$ = i; }
+ | i:divss { $$ = i; }
| i:divsd { $$ = i; }
| i:pxor { $$ = i; }
| i:xorpd { $$ = i; }
@@ -489,6 +490,11 @@ divsd = "divsd" (
| ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_DIVSD; }
+divss = "divss" (
+ ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+) { $$.instr.kind = ASM_DIVSS; }
+
movaps = "movaps" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
| ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
diff --git a/main.c b/main.c
index 652b21b..86721e8 100644
--- a/main.c
+++ b/main.c
@@ -319,21 +319,29 @@ static void assemblereloc(const char *l, int64_t c, int nbytes, int type) {
assembleconstant(c, nbytes);
}
+/* Rip relative addressing. */
+static void assembleriprel(const Memarg *memarg, Rex rex, VarBytes prefix,
+ VarBytes opcode, uint8_t reg, int32_t adjust) {
+ uint8_t rm;
+
+ rm = 0x05;
+ assemblemodregrm(rex, prefix, opcode, 0x00, reg, rm);
+ if (memarg->disp.l) {
+ assemblereloc(memarg->disp.l, memarg->disp.c - 4 + adjust, 4,
+ R_X86_64_PC32);
+ } else {
+ assembleconstant(memarg->disp.c, 4);
+ }
+}
+
/* Assemble a r <-> mem operation. */
static void assemblemem(const Memarg *memarg, Rex rex, VarBytes prefix,
VarBytes opcode, uint8_t reg) {
uint8_t mod, rm, scale, index, base;
- /* rip relative addressing. */
if (memarg->base == ASM_RIP) {
- rm = 0x05;
- assemblemodregrm(rex, prefix, opcode, 0x00, reg, rm);
- if (memarg->disp.l) {
- assemblereloc(memarg->disp.l, memarg->disp.c - 4, 4, R_X86_64_PC32);
- } else {
- assembleconstant(memarg->disp.c, 4);
- }
+ assembleriprel(memarg, rex, prefix, opcode, reg, 0);
return;
}
@@ -450,14 +458,7 @@ static void assembleimmrm(const Instr *instr, Rex rex, VarBytes prefix,
memarg = &instr->arg2->memarg;
if (memarg->base == ASM_RIP) {
- rm = 0x05;
- assemblemodregrm(rex, prefix, opcode, 0x00, immreg, rm);
- if (memarg->disp.l) {
- assemblereloc(memarg->disp.l, memarg->disp.c - 4 - imm->nbytes, 4,
- R_X86_64_PC32);
- } else {
- assembleconstant(memarg->disp.c, 4);
- }
+ assembleriprel(memarg, rex, prefix, opcode, immreg, -imm->nbytes);
} else {
assemblemem(memarg, rex, prefix, opcode, immreg);
}
@@ -1037,15 +1038,18 @@ static void assemble(void) {
case ASM_IDIV:
assembledivmulneg(&v->instr, 0x07);
break;
+ case ASM_DIVSD:
+ assemblerrm(&v->instr, 0xf2, 0x01000f5e, 1);
+ break;
+ case ASM_DIVSS:
+ assemblerrm(&v->instr, 0xf3, 0x01000f5e, 1);
+ break;
case ASM_MUL:
assembledivmulneg(&v->instr, 0x04);
break;
case ASM_MULSD:
assemblerrm(&v->instr, 0xf2, 0x01000f59, 1);
break;
- case ASM_DIVSD:
- assemblerrm(&v->instr, 0xf2, 0x01000f5e, 1);
- break;
case ASM_MULSS:
assemblerrm(&v->instr, 0xf3, 0x01000f59, 1);
break;
diff --git a/minias.h b/minias.h
index 9ddef20..020de41 100644
--- a/minias.h
+++ b/minias.h
@@ -81,6 +81,7 @@ typedef enum {
ASM_CVTTSD2SI,
ASM_CVTTSS2SI,
ASM_DIV,
+ ASM_DIVSS,
ASM_DIVSD,
ASM_IDIV,
ASM_LEA,
diff --git a/test/test.sh b/test/test.sh
index 256654e..7ee3855 100644
--- a/test/test.sh
+++ b/test/test.sh
@@ -57,6 +57,7 @@ t "movb %r11b, (%rsi, %r12, 1)"
t "cvttsd2si %xmm1, %rax"
t "cvttsd2si %xmm10, %rax"
+t "cvttsd2si %xmm10, %r9"
t "cvttsd2si %xmm1, %eax"
t "cvttsd2si %xmm10, %eax"
@@ -67,6 +68,7 @@ t "cvttss2si %xmm10, %eax"
t "cvtsi2sd %rax, %xmm1"
t "cvtsi2sd %rax, %xmm10"
+t "cvtsi2sd %r9, %xmm10"
t "cvtsi2sd (%rax), %xmm1"
t "cvtsi2sd (%rax), %xmm10"
t "cvtsi2sd %eax, %xmm1"
@@ -74,111 +76,29 @@ t "cvtsi2sd %eax, %xmm10"
t "cvtsi2ss %rax, %xmm1"
t "cvtsi2ss %rax, %xmm10"
+t "cvtsi2ss %r9, %xmm10"
t "cvtsi2ss (%rax), %xmm1"
t "cvtsi2ss (%rax), %xmm10"
t "cvtsi2ss %eax, %xmm1"
t "cvtsi2ss %eax, %xmm10"
-t "pxor %xmm0, %xmm1"
-t "pxor %xmm10, %xmm1"
-t "pxor (%rax), %xmm0"
-t "pxor (%rax), %xmm10"
-
-t "movaps %xmm0, %xmm1"
-t "movaps %xmm0, (%rax)"
-t "movaps (%rax), %xmm0"
-t "movaps %xmm0, %xmm1"
-t "movaps %xmm10, (%rax)"
-t "movaps (%rax), %xmm10"
-
-t "cvtss2sd %xmm0, %xmm1"
-t "cvtss2sd %xmm10, %xmm1"
-t "cvtss2sd (%rax), %xmm0"
-t "cvtss2sd (%rax), %xmm10"
-
-t "cvtsd2ss %xmm0, %xmm1"
-t "cvtsd2ss %xmm10, %xmm1"
-t "cvtsd2ss (%rax), %xmm0"
-t "cvtsd2ss (%rax), %xmm10"
-
-t "pxor %xmm0, %xmm1"
-t "pxor (%rax), %xmm1"
-
-t "xorps %xmm0, %xmm1"
-t "xorps %xmm10, %xmm1"
-t "xorps (%rax), %xmm0"
-t "xorps (%rax), %xmm10"
-
-t "xorpd %xmm0, %xmm1"
-t "xorpd %xmm10, %xmm1"
-t "xorpd (%rax), %xmm0"
-t "xorpd (%rax), %xmm10"
-
-t "movsd %xmm0, %xmm1"
-t "movsd %xmm0, (%rax)"
-t "movsd (%rax), %xmm0"
-t "movsd %xmm0, %xmm1"
-t "movsd %xmm10, (%rax)"
-t "movsd (%rax), %xmm10"
-
-t "movss %xmm0, %xmm1"
-t "movss %xmm0, (%rax)"
-t "movss (%rax), %xmm0"
-t "movss %xmm0, %xmm1"
-t "movss %xmm10, (%rax)"
-t "movss (%rax), %xmm10"
-
-t "addsd %xmm0, %xmm1"
-t "addsd (%rax), %xmm1"
-t "addsd %xmm10, %xmm1"
-t "addsd %xmm1, %xmm10"
-t "addsd %xmm10, %xmm11"
-t "addsd (%rax), %xmm11"
-t "addss %xmm0, %xmm1"
-t "addss (%rax), %xmm1"
-t "addss %xmm10, %xmm1"
-t "addss %xmm1, %xmm10"
-t "addss %xmm10, %xmm11"
-t "addss (%rax), %xmm11"
-
-t "subsd %xmm0, %xmm1"
-t "subsd (%rax), %xmm1"
-t "subsd %xmm10, %xmm1"
-t "subsd %xmm1, %xmm10"
-t "subsd %xmm10, %xmm11"
-t "subsd (%rax), %xmm11"
-t "subss %xmm0, %xmm1"
-t "subss (%rax), %xmm1"
-t "subss %xmm10, %xmm1"
-t "subss %xmm1, %xmm10"
-t "subss %xmm10, %xmm11"
-t "subss (%rax), %xmm11"
-
-t "mulsd %xmm0, %xmm1"
-t "mulsd (%rax), %xmm1"
-t "mulsd %xmm10, %xmm1"
-t "mulsd %xmm1, %xmm10"
-t "mulsd %xmm10, %xmm11"
-t "mulsd (%rax), %xmm11"
-t "mulss %xmm0, %xmm1"
-t "mulss (%rax), %xmm1"
-t "mulss %xmm10, %xmm1"
-t "mulss %xmm1, %xmm10"
-t "mulss %xmm10, %xmm11"
-t "mulss (%rax), %xmm11"
-
-t "ucomisd %xmm0, %xmm1"
-t "ucomisd (%rax), %xmm1"
-t "ucomisd %xmm10, %xmm1"
-t "ucomisd %xmm1, %xmm10"
-t "ucomisd %xmm10, %xmm11"
-t "ucomisd (%rax), %xmm11"
-t "ucomiss %xmm0, %xmm1"
-t "ucomiss (%rax), %xmm1"
-t "ucomiss %xmm10, %xmm1"
-t "ucomiss %xmm1, %xmm10"
-t "ucomiss %xmm10, %xmm11"
-t "ucomiss (%rax), %xmm11"
+
+xmmops="
+pxor movaps cvtss2sd xorps xorpd
+movss addsd addss subsd subss
+divss divsd mulss mulsd ucomiss
+ucomisd
+"
+for op in $xmmops
+do
+ t "${op} %xmm0, %xmm1"
+ t "${op} (%rax), %xmm1"
+ t "${op} %xmm10, %xmm1"
+ t "${op} %xmm1, %xmm10"
+ t "${op} %xmm10, %xmm11"
+ t "${op} (%rax), %xmm11"
+done
+
for r in a b
do