aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--asm.peg11
-rw-r--r--main.c13
-rw-r--r--minias.h1
-rw-r--r--test/test.sh48
4 files changed, 44 insertions, 29 deletions
diff --git a/asm.peg b/asm.peg
index e8cd805..1392fdd 100644
--- a/asm.peg
+++ b/asm.peg
@@ -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); }
diff --git a/main.c b/main.c
index 9746059..d472e08 100644
--- a/main.c
+++ b/main.c
@@ -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,
diff --git a/minias.h b/minias.h
index 83eea1a..02b2b77 100644
--- a/minias.h
+++ b/minias.h
@@ -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"