diff options
| -rw-r--r-- | asm.peg | 9 | ||||
| -rw-r--r-- | default.do | 2 | ||||
| -rw-r--r-- | main.c | 31 | ||||
| -rw-r--r-- | minias.h | 3 | ||||
| -rw-r--r-- | test/test.sh | 7 |
5 files changed, 32 insertions, 20 deletions
@@ -50,6 +50,7 @@ lea = mod-rm-binop = "add" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_ADD; } | "and" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_AND;} + | "mov" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_MOV;} | "or" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_OR;} | "sub" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_SUB;} | "xor" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_XOR;} @@ -119,10 +120,10 @@ r32 = imm = -'$' i:ident - { $$.imm = (Imm){.kind = ASM_IMM, .l = i.ident.name, .c = 0 }; } - | '$' <'-'?[0-9]+> - { $$.imm = (Imm){.kind = ASM_IMM, .l = NULL, .c = strtoll(yytext, NULL, 10) }; } + '$' i:ident + { $$.imm = (Imm){.kind = ASM_IMM, .l = i.ident.name, .c = 0 }; } + | '$' <'-'?[0-9]+> + { $$.imm = (Imm){.kind = ASM_IMM, .l = NULL, .c = strtoll(yytext, NULL, 10) }; } ident = <[_a-zA-Z][_a-zA-Z0-9]*> @@ -24,7 +24,7 @@ case "$1" in clang-format -i main.c util.c >&2 ;; *) - echo "don't know how to build $1" 2>&1 + echo "don't know how to do $1" 2>&1 exit 1 ;; esac
\ No newline at end of file @@ -1,5 +1,6 @@ #include "minias.h" +static FILE *outf = NULL; static AsmLine *allasm = NULL; // Symbols in memory before @@ -257,10 +258,10 @@ static void assemble() { case ASM_RET: sb(0xc3); break; - case ASM_ADD: case ASM_AND: case ASM_LEA: + case ASM_MOV: case ASM_OR: case ASM_SUB: case ASM_XOR: { @@ -320,6 +321,8 @@ static void assemble() { opcode = 0x01; } else if (op->kind == ASM_AND) { opcode = 0x21; + } else if (op->kind == ASM_MOV) { + opcode = 0x89; } else if (op->kind == ASM_OR) { opcode = 0x09; } else if (op->kind == ASM_SUB) { @@ -331,17 +334,6 @@ static void assemble() { } reg = rbits(op->src->kind); - } else if (op->src->kind == ASM_IMM) { - - opcode = 0x81; - reg = 0x00; - - if (memarg) { - rm = rbits(memarg->reg); - } else { - rm = rbits(op->dst->kind); - } - } else if (op->src->kind == ASM_MEMARG) { if (op->kind == ASM_ADD) { @@ -350,6 +342,8 @@ static void assemble() { opcode = 0x23; } else if (op->kind == ASM_LEA) { opcode = 0x8d; + } else if (op->kind == ASM_MOV) { + opcode = 0x8b; } else if (op->kind == ASM_OR) { opcode = 0x0b; } else if (op->kind == ASM_SUB) { @@ -359,8 +353,17 @@ static void assemble() { } else { fatal("unreachable"); } - /* dst is reg */ reg = rbits(op->dst->kind); + } else if (op->src->kind == ASM_IMM) { + + opcode = 0x81; + reg = 0x00; + if (memarg) { + rm = rbits(memarg->reg); + } else { + rm = rbits(op->dst->kind); + } + } rex = REX(op->type == 'q', reg & (1 << 4), 0, rm & (1 << 4)); @@ -462,8 +465,6 @@ static void fillsymtab(void) { } } -FILE *outf = NULL; - static void out(uint8_t *buf, size_t n) { fwrite(buf, 1, n, outf); if (ferror(outf)) @@ -50,6 +50,7 @@ typedef enum { ASM_ADD, ASM_AND, ASM_LEA, + ASM_MOV, ASM_OR, ASM_SUB, ASM_XOR, @@ -142,6 +143,7 @@ typedef struct { typedef ModRMBinop Add; typedef ModRMBinop And; typedef ModRMBinop Lea; +typedef ModRMBinop Mov; typedef ModRMBinop Or; typedef ModRMBinop Sub; typedef ModRMBinop Xor; @@ -156,6 +158,7 @@ union Parsev { Add add; And and; Lea lea; + Mov mov; Or or; Xor xor; Sub sub; diff --git a/test/test.sh b/test/test.sh index b261afa..be5a91f 100644 --- a/test/test.sh +++ b/test/test.sh @@ -25,6 +25,13 @@ t () { echo -n "." } +# TODO Tidy and be more systematic, we could just loop +t "movq %rax, %rax" +t "movq (%rax), %rax" +t "movq %rax, (%rax)" +t "movl %eax, %eax" +t "movl (%rax), %eax" +t "movl %eax, (%rax)" t "leaq (%rax), %rax" t "leal (%rax), %eax" t "addq (%rax), %rax" |
