diff options
| -rw-r--r-- | asm.peg | 8 | ||||
| -rw-r--r-- | main.c | 42 | ||||
| -rw-r--r-- | minias.h | 1 | ||||
| -rw-r--r-- | test/test.sh | 120 |
4 files changed, 51 insertions, 120 deletions
@@ -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); } @@ -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; @@ -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 |
