diff options
| author | Andrew Chambers <[email protected]> | 2021-10-09 12:14:13 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-09 12:14:13 +1300 |
| commit | 08716714c914e696ffbd1410fa7f16a0bc18ad1c (patch) | |
| tree | 6dba906e095e999bb2aefe36d64ff3141f705e33 | |
| parent | 8c0f425c60720ad364dea03722df2bba2b863405 (diff) | |
More instructions, refactor.
| -rw-r--r-- | asm.peg | 113 | ||||
| -rw-r--r-- | main.c | 166 | ||||
| -rw-r--r-- | minias.h | 20 | ||||
| -rw-r--r-- | test/test.sh | 11 |
4 files changed, 198 insertions, 112 deletions
@@ -35,80 +35,99 @@ instr = "nop" { $$.kind = ASM_NOP; } | "leave" { $$.kind = ASM_LEAVE; } | "ret" { $$.kind = ASM_RET; } + | i:push { $$ = i; } + | i:pop { $$ = i; } + | i:call { $$ = i; } | i:jmp { $$ = i; } - | i:xchg { $$ = i; } | i:add { $$ = i; } | i:and { $$ = i; } | i:lea { $$ = i; } | i:mov { $$ = i; } | i:or { $$ = i; } | i:sub { $$ = i; } + | i:xchg { $$ = i; } | i:xor { $$ = i; } +push = + "push" ( + 'q'? ws s:r64 { $$ = INSTR1(0, s); } + | 'q' ws s:m { $$ = INSTR1(1, s); } + ) { $$.instr2.kind = ASM_PUSH; } + +pop = + "pop" ( + 'q'? ws d:r64 { $$ = INSTR1(0, d); } + | 'q' ws d:m { $$ = INSTR1(1, d); } + ) { $$.instr2.kind = ASM_POP; } + +call = + "call" 'q'? ws t:ident + { $$.call = (Call){ .kind = ASM_CALL, .target=t.ident.name } ; } + jmp = "jmp" ws t:ident { $$.jmp = (Jmp){ .kind = ASM_JMP, .target=t.ident.name } ; } lea = "lea" ( - 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR(0, s, d); } - | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR(1, s, d); } - | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR(2, s, d); } - ) { $$.instr.kind = ASM_LEA; } + 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR2(0, s, d); } + | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR2(1, s, d); } + | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR2(2, s, d); } + ) { $$.instr2.kind = ASM_LEA; } imm-rm-opargs = - 'b' ws s:imm8 ws? ',' ws? d:m { $$ = INSTR(0, s, d); } - | 'w' ws s:imm16 ws? ',' ws? d:m { $$ = INSTR(1, s, d); } - | 'l' ws s:imm32 ws? ',' ws? d:m { $$ = INSTR(2, s, d); } - | 'q' ws s:imm32 ws? ',' ws? d:m { $$ = INSTR(3, s, d); } - | 'b'? ws s:imm8 ws? ',' ws? d:r8 { $$ = INSTR(4, s, d); } - | 'w'? ws s:imm16 ws? ',' ws? d:r16 { $$ = INSTR(5, s, d); } - | 'l'? ws s:imm32 ws? ',' ws? d:r32 { $$ = INSTR(6, s, d); } - | 'q'? ws s:imm32 ws? ',' ws? d:r64 { $$ = INSTR(7, s, d); } + 'b' ws s:imm8 ws? ',' ws? d:m { $$ = INSTR2(0, s, d); } + | 'w' ws s:imm16 ws? ',' ws? d:m { $$ = INSTR2(1, s, d); } + | 'l' ws s:imm32 ws? ',' ws? d:m { $$ = INSTR2(2, s, d); } + | 'q' ws s:imm32 ws? ',' ws? d:m { $$ = INSTR2(3, s, d); } + | 'b'? ws s:imm8 ws? ',' ws? d:r8 { $$ = INSTR2(4, s, d); } + | 'w'? ws s:imm16 ws? ',' ws? d:r16 { $$ = INSTR2(5, s, d); } + | 'l'? ws s:imm32 ws? ',' ws? d:r32 { $$ = INSTR2(6, s, d); } + | 'q'? ws s:imm32 ws? ',' ws? d:r64 { $$ = INSTR2(7, s, d); } r-rm-opargs = - 'b'? ws s:m ws? ',' ws? d:r8 { $$ = INSTR(0, s, d); } - | 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR(1, s, d); } - | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR(2, s, d); } - | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR(3, s, d); } - | 'b'? ws s:r8 ws? ',' ws? d:m { $$ = INSTR(4, s, d); } - | 'w'? ws s:r16 ws? ',' ws? d:m { $$ = INSTR(5, s, d); } - | 'l'? ws s:r32 ws? ',' ws? d:m { $$ = INSTR(6, s, d); } - | 'q'? ws s:r64 ws? ',' ws? d:m { $$ = INSTR(7, s, d); } - | 'b'? ws s:r8 ws? ',' ws? d:r8 { $$ = INSTR(8, s, d); } - | 'w'? ws s:r16 ws? ',' ws? d:r16 { $$ = INSTR(9, s, d); } - | 'l'? ws s:r32 ws? ',' ws? d:r32 { $$ = INSTR(10, s, d); } - | 'q'? ws s:r64 ws? ',' ws? d:r64 { $$ = INSTR(11, s, d); } + 'b'? ws s:m ws? ',' ws? d:r8 { $$ = INSTR2(0, s, d); } + | 'w'? ws s:m ws? ',' ws? d:r16 { $$ = INSTR2(1, s, d); } + | 'l'? ws s:m ws? ',' ws? d:r32 { $$ = INSTR2(2, s, d); } + | 'q'? ws s:m ws? ',' ws? d:r64 { $$ = INSTR2(3, s, d); } + | 'b'? ws s:r8 ws? ',' ws? d:m { $$ = INSTR2(4, s, d); } + | 'w'? ws s:r16 ws? ',' ws? d:m { $$ = INSTR2(5, s, d); } + | 'l'? ws s:r32 ws? ',' ws? d:m { $$ = INSTR2(6, s, d); } + | 'q'? ws s:r64 ws? ',' ws? d:m { $$ = INSTR2(7, s, d); } + | 'b'? ws s:r8 ws? ',' ws? d:r8 { $$ = INSTR2(8, s, d); } + | 'w'? ws s:r16 ws? ',' ws? d:r16 { $$ = INSTR2(9, s, d); } + | 'l'? ws s:r32 ws? ',' ws? d:r32 { $$ = INSTR2(10, s, d); } + | 'q'? ws s:r64 ws? ',' ws? d:r64 { $$ = INSTR2(11, s, d); } mov = "mov" ( args:imm-rm-opargs { $$ = args; } - | args:r-rm-opargs { args.instr.variant += 8; $$ = args; } -) { $$.instr.kind = ASM_MOV; } + | args:r-rm-opargs { args.instr2.variant += 8; $$ = args; } +) { $$.instr2.kind = ASM_MOV; } xchg = 'xchg' ( - 'w'? ws s:ax ws? ',' ws? d:r16 { $$ = INSTR(0, s, d); } - | 'w'? ws s:r16 ws? ',' ws? d:ax { $$ = INSTR(1, s, d); } - | 'l'? ws s:eax ws? ',' ws? d:r32 { $$ = INSTR(2, s, d); } - | 'l'? ws s:r32 ws? ',' ws? d:eax { $$ = INSTR(3, s, d); } - | 'q'? ws s:rax ws? ',' ws? d:r64 { $$ = INSTR(4, s, d); } - | 'q'? ws s:r64 ws? ',' ws? d:rax { $$ = INSTR(5, s, d); } - | args:r-rm-opargs { args.instr.variant += 6; $$ = args; } - ) { $$.instr.kind = ASM_XCHG; } - -add = "add" a:basic-op-args { a.instr.kind = ASM_ADD; $$ = a; } -and = "and" a:basic-op-args { a.instr.kind = ASM_AND; $$ = a; } -or = "or" a:basic-op-args { a.instr.kind = ASM_OR; $$ = a; } -sub = "sub" a:basic-op-args { a.instr.kind = ASM_SUB; $$ = a; } -xor = "xor" a:basic-op-args { a.instr.kind = ASM_XOR; $$ = a; } + 'w'? ws s:ax ws? ',' ws? d:r16 { $$ = INSTR2(0, s, d); } + | 'w'? ws s:r16 ws? ',' ws? d:ax { $$ = INSTR2(1, s, d); } + | 'l'? ws s:eax ws? ',' ws? d:r32 { $$ = INSTR2(2, s, d); } + | 'l'? ws s:r32 ws? ',' ws? d:eax { $$ = INSTR2(3, s, d); } + | 'q'? ws s:rax ws? ',' ws? d:r64 { $$ = INSTR2(4, s, d); } + | 'q'? ws s:r64 ws? ',' ws? d:rax { $$ = INSTR2(5, s, d); } + | args:r-rm-opargs { args.instr2.variant += 6; $$ = args; } + ) { $$.instr2.kind = ASM_XCHG; } + +add = "add" a:basic-op-args { a.instr2.kind = ASM_ADD; $$ = a; } +and = "and" a:basic-op-args { a.instr2.kind = ASM_AND; $$ = a; } +or = "or" a:basic-op-args { a.instr2.kind = ASM_OR; $$ = a; } +sub = "sub" a:basic-op-args { a.instr2.kind = ASM_SUB; $$ = a; } +xor = "xor" a:basic-op-args { a.instr2.kind = ASM_XOR; $$ = a; } basic-op-args = - 'b'? ws s:imm8 ws? ',' ws? d:al { $$ = INSTR(0, s, d); } - | 'w'? ws s:imm16 ws? ',' ws? d:ax { $$ = INSTR(1, s, d); } - | 'l'? ws s:imm32 ws? ',' ws? d:eax { $$ = INSTR(2, s, d); } - | 'q'? ws s:imm32 ws? ',' ws? d:rax { $$ = INSTR(3, s, d); } - | args:imm-rm-opargs { args.instr.variant += 4; $$ = args; } - | args:r-rm-opargs { args.instr.variant += 12; $$ = args; } + 'b'? ws s:imm8 ws? ',' ws? d:al { $$ = INSTR2(0, s, d); } + | 'w'? ws s:imm16 ws? ',' ws? d:ax { $$ = INSTR2(1, s, d); } + | 'l'? ws s:imm32 ws? ',' ws? d:eax { $$ = INSTR2(2, s, d); } + | 'q'? ws s:imm32 ws? ',' ws? d:rax { $$ = INSTR2(3, s, d); } + | args:imm-rm-opargs { args.instr2.variant += 4; $$ = args; } + | args:r-rm-opargs { args.instr2.variant += 12; $$ = args; } r64-or-rip = ( r:r64 @@ -129,21 +129,6 @@ Relocation *newreloc() { return &relocs[nrelocs++]; } -static Parsev *dupv(Parsev *p) { - Parsev *r = xmalloc(sizeof(Parsev)); - *r = *p; - return r; -} - -#define INSTR(V, S, D) \ - (Parsev) { \ - .instr = (Instr) { \ - .kind = 0, .variant = V, .src = dupv(&S), .dst = dupv(&D) \ - } \ - } -#define REG(K) \ - (Parsev) { .kind = K } - static String decodestring(char *s) { int i; char *end; @@ -185,6 +170,26 @@ static String decodestring(char *s) { return (String){.kind = ASM_STRING, .len = len, .data = data}; } +static Parsev *dupv(Parsev *p) { + Parsev *r = xmalloc(sizeof(Parsev)); + *r = *p; + return r; +} + +#define INSTR1(V, A) \ + (Parsev) { \ + .instr1 = (Instr1) { .kind = 0, .variant = V, .arg = dupv(&A), } \ + } + +#define INSTR2(V, S, D) \ + (Parsev) { \ + .instr2 = (Instr2) { \ + .kind = 0, .variant = V, .src = dupv(&S), .dst = dupv(&D) \ + } \ + } +#define REG(K) \ + (Parsev) { .kind = K } + #define YYSTYPE Parsev #define YY_CTX_LOCAL #define YY_CTX_MEMBERS Parsev v; @@ -278,9 +283,9 @@ static uint8_t sibbyte(uint8_t ss, uint8_t idx, uint8_t base) { } /* Assemble op +rw | op + rd. */ -static void assembleplusr(uint8_t opcode, AsmKind reg) { +static void assembleplusr(uint8_t opcode, uint8_t rexw, AsmKind reg) { uint8_t bits = regbits(reg); - uint8_t rex = rexbyte(isreg64(reg), 0, 0, bits & (1 << 3)); + uint8_t rex = rexbyte(rexw, 0, 0, bits & (1 << 3)); if (isreg16(reg)) sb(0x66); if (rex != rexbyte(0, 0, 0, 0)) @@ -355,7 +360,7 @@ static void assemblemem(Memarg *memarg, uint8_t rexw, uint8_t opcode, sb2(opcode, modregrm(0, reg, rm)); } } else { - /* XXX choose smaller size if not label .*/ + /* TODO choose smaller size if not label .*/ if ((rm & 7) == 4) { /* Matches '(%rsp/%esp...)'. */ sb3(opcode, modregrm(2, reg, 4), sibbyte(0, 4, 4)); } else if ((rm & 7) == 5) { /* Matches '(%rbp/%ebp...)'. */ @@ -368,7 +373,7 @@ static void assemblemem(Memarg *memarg, uint8_t rexw, uint8_t opcode, } /* Assemble op + imm -> r/m. */ -static void assembleimmrm(Instr *instr, uint8_t opcode, uint8_t immreg, +static void assembleimmrm(Instr2 *instr, uint8_t opcode, uint8_t immreg, uint8_t opsz) { Imm *imm; @@ -395,11 +400,20 @@ static void assembleimmrm(Instr *instr, uint8_t opcode, uint8_t immreg, } /* Assemble op + r <-> r/m. */ -static void assemblerrm(Instr *instr, uint8_t opcode, uint8_t opsz) { +static void assemblerrm(Instr2 *instr, uint8_t opcode, uint8_t opsz) { Memarg *memarg; AsmKind regarg; - if (instr->src->kind == ASM_MEMARG) { + if (instr->src->kind == ASM_MEMARG && instr->src->memarg.reg == ASM_RIP) { + memarg = &instr->src->memarg; + regarg = instr->dst->kind; + assembleriprel(memarg, isreg64(regarg), opcode, regbits(regarg), opsz); + } else if (instr->dst->kind == ASM_MEMARG && + instr->dst->memarg.reg == ASM_RIP) { + memarg = &instr->dst->memarg; + regarg = instr->src->kind; + assembleriprel(memarg, isreg64(regarg), opcode, regbits(regarg), opsz); + } else if (instr->src->kind == ASM_MEMARG) { memarg = &instr->src->memarg; regarg = instr->dst->kind; assemblemem(memarg, isreg64(regarg), opcode, regbits(regarg), opsz); @@ -423,7 +437,7 @@ static void assemblerrm(Instr *instr, uint8_t opcode, uint8_t opsz) { } /* Assemble a 'basic op' which is just a repeated op pattern we have named. */ -static void assemblebasicop(Instr *instr, uint8_t opcode, uint8_t immreg) { +static void assemblebasicop(Instr2 *instr, uint8_t opcode, uint8_t immreg) { Imm *imm; uint8_t opsz = 1 << (instr->variant % 4); if (instr->variant < 4) { @@ -441,21 +455,21 @@ static void assemblebasicop(Instr *instr, uint8_t opcode, uint8_t immreg) { } } -static void assemblexchg(Instr *xchg) { +static void assemblexchg(Instr2 *xchg) { static uint8_t variant2op[18] = {0x90, 0x90, 0x90, 0x90, 0x90, 0x90, 0x86, 0x87, 0x87, 0x87, 0x86, 0x87, 0x87, 0x87, 0x86, 0x87, 0x87, 0x87}; uint8_t opcode = variant2op[xchg->variant]; if (xchg->variant < 6) { - assembleplusr(opcode, - (xchg->variant % 2) ? xchg->src->kind : xchg->dst->kind); + AsmKind reg = (xchg->variant % 2) ? xchg->src->kind : xchg->dst->kind; + assembleplusr(opcode, isreg64(reg), reg); } else { uint8_t opsz = 1 << ((xchg->variant - 6) % 4); assemblerrm(xchg, opcode, opsz); } } -static void assemblemov(Instr *mov) { +static void assemblemov(Instr2 *mov) { Imm *imm; uint8_t opcode, rex, mod, rm; @@ -467,7 +481,7 @@ static void assemblemov(Instr *mov) { opcode = variant2op[mov->variant]; if (mov->variant >= 4 && mov->variant <= 6) { imm = &mov->src->imm; - assembleplusr(opcode, mov->dst->kind); + assembleplusr(opcode, isreg64(mov->dst->kind), mov->dst->kind); assemblevalue(imm->l, imm->c, imm->nbytes); } else if (mov->variant == 7 || mov->variant < 4) { uint8_t opsz = 1 << (mov->variant % 4); @@ -528,6 +542,48 @@ static void assemble(void) { lfatal("%s already defined", sym->name); sym->defined = 1; break; + case ASM_CALL: { + Symbol *sym; + Relocation *reloc; + + sb(0xe8); + sym = getsym(v->call.target); + reloc = newreloc(); + reloc->kind = 0; // XXX + reloc->section = cursection; + reloc->sym = sym; + reloc->offset = cursection->hdr.sh_size; + sl(0); + break; + } + case ASM_JMP: { + Symbol *sym; + Relocation *reloc; + + sb(0xe9); + sym = getsym(v->jmp.target); + reloc = newreloc(); + reloc->kind = 0; // XXX + reloc->section = cursection; + reloc->sym = sym; + reloc->offset = cursection->hdr.sh_size; + sl(-4); + break; + } + case ASM_PUSH: + if (v->instr1.arg->kind == ASM_MEMARG) { + assemblemem(&v->instr1.arg->memarg, 0, 0xff, 0x06, 8); + } else { + assembleplusr(0x50, 0, v->instr1.arg->kind); + } + break; + case ASM_POP: + if (v->instr1.arg->kind == ASM_MEMARG) { + assemblemem(&v->instr1.arg->memarg, 0, 0x8f, 0x00, 8); + } else { + assembleplusr(0x58, 0, v->instr1.arg->kind); + } + break; case ASM_NOP: sb(0x90); break; @@ -538,12 +594,12 @@ static void assemble(void) { sb(0xc3); break; case ASM_LEA: { - uint8_t opsz = 1 << (v->instr.variant + 1); - assemblerrm(&v->instr, 0x8d, opsz); + uint8_t opsz = 1 << (v->instr2.variant + 1); + assemblerrm(&v->instr2, 0x8d, opsz); break; } case ASM_MOV: - assemblemov(&v->instr); + assemblemov(&v->instr2); break; case ASM_ADD: { static uint8_t variant2op[24] = { @@ -551,7 +607,7 @@ static void assemble(void) { 0x80, 0x81, 0x81, 0x81, 0x02, 0x03, 0x03, 0x03, 0x00, 0x01, 0x01, 0x01, 0x00, 0x01, 0x01, 0x01, }; - assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x00); + assemblebasicop(&v->instr2, variant2op[v->instr2.variant], 0x00); break; } case ASM_AND: { @@ -560,7 +616,7 @@ static void assemble(void) { 0x80, 0x81, 0x81, 0x81, 0x22, 0x23, 0x23, 0x23, 0x20, 0x21, 0x21, 0x21, 0x20, 0x21, 0x21, 0x21, }; - assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x04); + assemblebasicop(&v->instr2, variant2op[v->instr2.variant], 0x04); break; } case ASM_OR: { @@ -569,7 +625,7 @@ static void assemble(void) { 0x80, 0x81, 0x81, 0x81, 0x0a, 0x0b, 0x0b, 0x0b, 0x08, 0x09, 0x09, 0x09, 0x08, 0x09, 0x09, 0x09, }; - assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x01); + assemblebasicop(&v->instr2, variant2op[v->instr2.variant], 0x01); break; } case ASM_SUB: { @@ -578,7 +634,7 @@ static void assemble(void) { 0x80, 0x81, 0x81, 0x81, 0x2a, 0x2b, 0x2b, 0x2b, 0x28, 0x29, 0x29, 0x29, 0x28, 0x29, 0x29, 0x29, }; - assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x05); + assemblebasicop(&v->instr2, variant2op[v->instr2.variant], 0x05); break; } case ASM_XOR: { @@ -587,25 +643,11 @@ static void assemble(void) { 0x80, 0x81, 0x81, 0x81, 0x32, 0x33, 0x33, 0x33, 0x30, 0x31, 0x31, 0x31, 0x30, 0x31, 0x31, 0x31, }; - assemblebasicop(&v->instr, variant2op[v->instr.variant], 0x06); + assemblebasicop(&v->instr2, variant2op[v->instr2.variant], 0x06); break; } case ASM_XCHG: { - assemblexchg(&v->instr); - break; - } - case ASM_JMP: { - Symbol *sym; - Relocation *reloc; - - sb(0xe9); - sym = getsym(v->jmp.target); - reloc = newreloc(); - reloc->kind = 0; // XXX - reloc->section = cursection; - reloc->sym = sym; - reloc->offset = cursection->hdr.sh_size; - sl(-4); + assemblexchg(&v->instr2); break; } default: @@ -618,15 +660,22 @@ static void addtosymtab(Symbol *sym) { Elf64_Sym elfsym; int stype; int sbind; - stype = (sym->section->hdr.sh_flags & SHF_EXECINSTR) ? STT_FUNC : STT_OBJECT; - sbind = sym->global ? STB_GLOBAL : STB_LOCAL; + + if (sym->defined) { + stype = + (sym->section->hdr.sh_flags & SHF_EXECINSTR) ? STT_FUNC : STT_OBJECT; + sbind = sym->global ? STB_GLOBAL : STB_LOCAL; + } else { + stype = 0; + sbind = 0; + } memset(&elfsym, 0, sizeof(elfsym)); elfsym.st_name = elfstr(strtab, sym->name); elfsym.st_size = sym->size; elfsym.st_value = sym->offset; elfsym.st_info = ELF32_ST_BIND(sbind) | ELF32_ST_TYPE(stype); - elfsym.st_shndx = sym->section->idx; + elfsym.st_shndx = sym->section ? sym->section->idx : SHN_UNDEF; secaddbytes(symtab, (uint8_t *)&elfsym, sizeof(Elf64_Sym)); } @@ -634,21 +683,12 @@ static void fillsymtab(void) { Symbol *sym; size_t i; - // Local symbols - for (i = 0; i < symbols->cap; i++) { - if (!symbols->keys[i].str) - continue; - sym = symbols->vals[i]; - if (sym->global || !sym->section) - continue; - addtosymtab(sym); - } // Global symbols for (i = 0; i < symbols->cap; i++) { if (!symbols->keys[i].str) continue; sym = symbols->vals[i]; - if (!sym->global || !sym->section) + if (!sym->global && sym->defined) continue; addtosymtab(sym); } @@ -57,6 +57,9 @@ typedef enum { // Instructions ASM_NOP, ASM_RET, + ASM_PUSH, + ASM_POP, + ASM_CALL, ASM_JMP, ASM_LEAVE, ASM_ADD, @@ -203,14 +206,25 @@ typedef String Asciiz; typedef struct { AsmKind kind; const char *target; +} Call; + +typedef struct { + AsmKind kind; + const char *target; } Jmp; typedef struct { AsmKind kind; uint8_t variant; + Parsev *arg; +} Instr1; + +typedef struct { + AsmKind kind; + uint8_t variant; Parsev *src; Parsev *dst; -} Instr; +} Instr2; union Parsev { AsmKind kind; @@ -220,7 +234,9 @@ union Parsev { Ascii ascii; Asciiz asciiz; Memarg memarg; - Instr instr; + Instr1 instr1; + Instr2 instr2; + Call call; Jmp jmp; Byte byte; Imm imm; diff --git a/test/test.sh b/test/test.sh index e8293a7..1a3f34a 100644 --- a/test/test.sh +++ b/test/test.sh @@ -30,6 +30,14 @@ t () { echo -n "." } +t "pushq (%r9)" +t "pushq %r9" +t "pushq %rax" +t "popq (%r9)" +t "popq %r9" +t "popq %rax" + + t "movb \$127, (%rsp)" t "movb \$127, (%rbp)" t "movb \$127, 2147483647(%rsp)" @@ -87,6 +95,8 @@ do t "${op}q \$2147483647, %r${r}x" # r rm variants + t "${op}b (%rip), %${r}l" + t "${op}b (%rax), %${r}l" t "${op}b (%rax), %${r}l" t "${op}w (%rax), %${r}x" t "${op}l (%rax), %e${r}x" @@ -94,6 +104,7 @@ do t "${op}q (%rbp), %r${r}x" t "${op}q (%r8), %r${r}x" t "${op}q (%r13), %r${r}x" + t "${op}b %${r}l, (%rip)" t "${op}b %${r}l, (%rax)" t "${op}w %${r}x, (%rax)" t "${op}l %e${r}x, (%rax)" |
