aboutsummaryrefslogtreecommitdiff
path: root/asm.peg
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-09 12:14:13 +1300
committerAndrew Chambers <[email protected]>2021-10-09 12:14:13 +1300
commit08716714c914e696ffbd1410fa7f16a0bc18ad1c (patch)
tree6dba906e095e999bb2aefe36d64ff3141f705e33 /asm.peg
parent8c0f425c60720ad364dea03722df2bba2b863405 (diff)
More instructions, refactor.
Diffstat (limited to 'asm.peg')
-rw-r--r--asm.peg113
1 files changed, 66 insertions, 47 deletions
diff --git a/asm.peg b/asm.peg
index 256603d..5d9db3b 100644
--- a/asm.peg
+++ b/asm.peg
@@ -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