diff options
| -rw-r--r-- | asm.peg | 8 | ||||
| -rw-r--r-- | main.c | 30 | ||||
| -rw-r--r-- | minias.h | 20 | ||||
| -rw-r--r-- | test/test.sh | 6 |
4 files changed, 57 insertions, 7 deletions
@@ -24,7 +24,11 @@ directive = | "balign" ws n:number { $$.balign = (Balign){.kind = ASM_DIR_BALIGN, .align = n.i64 }; } | "byte" ws n:number - { $$.byte = (Byte){.kind = ASM_DIR_BYTE, .b = (uint8_t)n.i64 }; } + { $$.dirbyte = (Byte){.kind = ASM_DIR_BYTE, .v = n.i64 }; } + | "int" ws n:number + { $$.dirint = (Int){.kind = ASM_DIR_INT, .v = n.i64 }; } + | "quad" ws n:number + { $$.dirquad = (Quad){.kind = ASM_DIR_QUAD, .v = n.i64 }; } | sd:section-directive { $$ = sd; } section-directive = @@ -52,6 +56,8 @@ instr = "nop" { $$.kind = ASM_NOP; } | "leave" { $$.kind = ASM_LEAVE; } | "ret" { $$.kind = ASM_RET; } + | "cltd" { $$.kind = ASM_CLTD; } + | "cqto" { $$.kind = ASM_CQTO; } | i:push { $$ = i; } | i:pop { $$ = i; } | i:call { $$ = i; } @@ -293,6 +293,20 @@ static void su32(uint32_t l) { secaddbytes(cursection, buf, sizeof(buf)); } +static void su64(uint32_t l) { + uint8_t buf[8] = { + l & 0xff, + (l & 0xff00) >> 8, + (l & 0xff00) >> 16, + (l & 0xff000000) >> 24, + (l & 0xff00000000) >> 32, + (l & 0xff0000000000) >> 40, + (l & 0xff000000000000) >> 48, + (l & 0xff00000000000000) >> 56, + }; + secaddbytes(cursection, buf, sizeof(buf)); +} + /* Convert an AsmKind to register bits in reg/rm style. */ static uint8_t regbits(AsmKind k) { return (k - (ASM_REG_BEGIN + 1)) % 16; } @@ -332,7 +346,7 @@ void assembleconstant(int64_t c, int nbytes) { su32((uint32_t)c); break; case 8: - fatal("TODO 8 byte"); + su64((uint64_t)c); break; default: unreachable(); @@ -651,7 +665,13 @@ static void assemble(void) { break; } case ASM_DIR_BYTE: - sb(v->byte.b); + sb((uint8_t)v->dirbyte.v); + break; + case ASM_DIR_INT: + su32((uint32_t)v->dirint.v); + break; + case ASM_DIR_QUAD: + su64((uint64_t)v->dirquad.v); break; case ASM_LABEL: sym = getsym(v->label.name); @@ -705,6 +725,12 @@ static void assemble(void) { case ASM_LEAVE: sb(0xc9); break; + case ASM_CLTD: + sb(0x99); + break; + case ASM_CQTO: + sb2(0x48, 0x99); + break; case ASM_RET: sb(0xc3); break; @@ -53,6 +53,8 @@ typedef enum { ASM_DIR_DATA, ASM_DIR_TEXT, ASM_DIR_BYTE, + ASM_DIR_INT, + ASM_DIR_QUAD, ASM_DIR_BALIGN, // Instructions ASM_NOP, @@ -60,6 +62,8 @@ typedef enum { ASM_PUSH, ASM_POP, ASM_CALL, + ASM_CLTD, + ASM_CQTO, ASM_JMP, ASM_LEAVE, ASM_ADD, @@ -181,11 +185,21 @@ typedef struct { typedef struct { AsmKind kind; - uint8_t b; + int64_t v; } Byte; typedef struct { AsmKind kind; + int64_t v; +} Int; + +typedef struct { + AsmKind kind; + int64_t v; +} Quad; + +typedef struct { + AsmKind kind; uint64_t align; } Balign; @@ -242,7 +256,9 @@ union Parsev { Instr instr; Call call; Jmp jmp; - Byte byte; + Byte dirbyte; + Int dirint; + Quad dirquad; Imm imm; String string; // Temporary values. diff --git a/test/test.sh b/test/test.sh index b3346e7..448a77c 100644 --- a/test/test.sh +++ b/test/test.sh @@ -30,6 +30,10 @@ t () { echo -n "." } +t "ret" +t "cltd" +t "cqto" + conditioncodes=" a ae b be c e z g ge l le na @@ -45,7 +49,6 @@ do t "set${cc} (%rax)" done - for op in sal sar shl shr do t "${op} \$3, %rax" @@ -95,7 +98,6 @@ t "popq (%r9)" t "popq %r9" t "popq %rax" - t "movb \$127, (%rsp)" t "movb \$127, (%rbp)" t "movb \$127, 2147483647(%rsp)" |
