diff options
| -rw-r--r-- | asm.peg | 11 | ||||
| -rw-r--r-- | main.c | 13 | ||||
| -rw-r--r-- | minias.h | 1 | ||||
| -rw-r--r-- | test/test.sh | 48 |
4 files changed, 44 insertions, 29 deletions
@@ -4,7 +4,10 @@ line = | eol { yy->v.kind = ASM_BLANK; } | . { yy->v.kind = ASM_SYNTAX_ERROR; } -ws = [ \t]+ +ws = + [ \t]+ + | "/*" (! "*/" . )* "*/" # XXX multiline comments break our line numbers. + eol = ws? "\n" stmt = @@ -70,6 +73,7 @@ instr = | i:lea { $$ = i; } | i:mul { $$ = i; } | i:imul { $$ = i; } + | i:neg { $$ = i; } | i:movsx { $$ = i; } | i:movzx { $$ = i; } | i:mov { $$ = i; } @@ -161,6 +165,11 @@ mul = "mul" ( | args:r-opargs { args.instr.variant += 4 ; $$ = args; } ) { $$.instr.kind = ASM_MUL; } +neg = "neg" ( + args:m-opargs { $$ = args; } + | args:r-opargs { args.instr.variant += 4 ; $$ = args; } +) { $$.instr.kind = ASM_NEG; } + imul = "imul" ( ( 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR2(8, s, d); } @@ -573,7 +573,7 @@ static void assemblemovextend(Instr *mov, Opcode opcode) { assemblerrm(mov, opcode, opsz); } -static void assembledivmul(Instr *instr, uint8_t reg) { +static void assembledivmulneg(Instr *instr, uint8_t reg) { Opcode opcode; uint8_t rex, mod, rm, opsz; @@ -796,20 +796,20 @@ static void assemble(void) { break; } case ASM_DIV: - assembledivmul(&v->instr, 0x06); + assembledivmulneg(&v->instr, 0x06); break; case ASM_IDIV: - assembledivmul(&v->instr, 0x07); + assembledivmulneg(&v->instr, 0x07); break; case ASM_MUL: - assembledivmul(&v->instr, 0x04); + assembledivmulneg(&v->instr, 0x04); break; case ASM_IMUL: { Opcode opcode; uint8_t opsz; if (v->instr.variant < 8) { - assembledivmul(&v->instr, 0x05); + assembledivmulneg(&v->instr, 0x05); } else if (v->instr.variant < 14) { opcode = 0x01000faf; // 0f af variable length opcode. opsz = 1 << (1 + ((v->instr.variant - 8) % 3)); @@ -824,6 +824,9 @@ static void assemble(void) { } break; } + case ASM_NEG: + assembledivmulneg(&v->instr, 0x03); + break; case ASM_OR: { static uint8_t variant2op[24] = { 0x0c, 0x0d, 0x0d, 0x0d, 0x80, 0x81, 0x81, 0x81, @@ -77,6 +77,7 @@ typedef enum { ASM_MOV, ASM_MOVSX, ASM_MOVZX, + ASM_NEG, ASM_OR, ASM_SAL, ASM_SAR, diff --git a/test/test.sh b/test/test.sh index 37975e7..6091543 100644 --- a/test/test.sh +++ b/test/test.sh @@ -30,29 +30,6 @@ t () { echo -n "." } -for x in s z -do - t "mov${x}bw %al, %ax" - t "mov${x}bl %al, %eax" - t "mov${x}bq %al, %rax" - t "mov${x}wl %ax, %eax" - t "mov${x}wq %ax, %rax" - if test "$x" = s - then - t "mov${x}lq %eax, %rax" - fi - t "mov${x}bw (%rax), %ax" - t "mov${x}bl (%rax), %eax" - t "mov${x}bq (%rax), %rax" - t "mov${x}wl (%rax), %eax" - t "mov${x}wq (%rax), %rax" - if test "$x" = s - then - t "mov${x}lq (%rax), %rax" - fi -done - - t "ret" t "cltd" t "cqto" @@ -97,6 +74,9 @@ t "idivq (%rip)" t "mul %rax" t "mulq (%rax)" t "mulq (%rip)" +t "neg %rax" +t "negq (%rax)" +t "negq (%rip)" t "imul %rax" t "imulq (%rax)" @@ -126,6 +106,28 @@ t "movb \$127, (%rbp)" t "movb \$127, 2147483647(%rsp)" t "movb \$127, 2147483647(%rbp)" +for x in s z +do + t "mov${x}bw %al, %ax" + t "mov${x}bl %al, %eax" + t "mov${x}bq %al, %rax" + t "mov${x}wl %ax, %eax" + t "mov${x}wq %ax, %rax" + if test "$x" = s + then + t "mov${x}lq %eax, %rax" + fi + t "mov${x}bw (%rax), %ax" + t "mov${x}bl (%rax), %eax" + t "mov${x}bq (%rax), %rax" + t "mov${x}wl (%rax), %eax" + t "mov${x}wq (%rax), %rax" + if test "$x" = s + then + t "mov${x}lq (%rax), %rax" + fi +done + for r in a b do t "xchg %${r}l, %${r}l" |
