aboutsummaryrefslogtreecommitdiff
path: root/asm.peg
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-07 01:53:34 +1300
committerAndrew Chambers <[email protected]>2021-10-07 01:53:34 +1300
commitf4a9a52d001a54ca1142110b70142a8ef8df53bc (patch)
tree95226e04b60c43b1143b7d27d7fe6905ae0b3dd4 /asm.peg
parent78aa469080b95f41fabc0f428bd4e5b1bbdaa04b (diff)
Work.
Diffstat (limited to 'asm.peg')
-rw-r--r--asm.peg236
1 files changed, 168 insertions, 68 deletions
diff --git a/asm.peg b/asm.peg
index f163271..1a834cc 100644
--- a/asm.peg
+++ b/asm.peg
@@ -1,8 +1,11 @@
-line =
- ws? s:stmt (eol | !. ) { yy->v = s; }
- | eol { yy->v.kind = ASM_BLANK; }
- | . { yy->v.kind = ASM_SYNTAX_ERROR; }
+line =
+ ws? s:stmt eol { yy->v = s; }
+ | eol { yy->v.kind = ASM_BLANK; }
+ | . { yy->v.kind = ASM_SYNTAX_ERROR; }
+
+ws = [ \t]+
+eol = ws? "\n"
stmt =
d:directive {$$ = d;}
@@ -10,7 +13,7 @@ stmt =
| l:label { $$ = l; }
directive =
- ".glob" "o"? "l" ws i:ident
+ ".glob" 'o'? 'l' ws i:ident
{ $$.globl = (Globl){.kind = ASM_DIR_GLOBL, .name = i.ident.name }; }
| ".data"
{ $$.kind = ASM_DIR_DATA; }
@@ -31,93 +34,195 @@ instr =
| "ret" { $$.kind = ASM_RET; }
| i:jmp { $$ = i; }
| i:lea { $$ = i; }
+ | i:movzx { $$ = i; }
| i:mod-rm-binop { $$ = i; }
jmp = "jmp" ws i:ident
{ $$.jmp = (Jmp){.kind = ASM_JMP, .target = i.ident.name}; }
+movzx =
+ "movzx"
+ (
+ (
+ 'b' ws s:m ws? ',' ws? d:r16
+ | 'b' ws s:m ws? ',' ws? d:r32
+ | 'b' ws s:m ws? ',' ws? d:r64
+ | 'b'? ws s:r8 ws? ',' ws? d:r16
+ | 'b'? ws s:r8 ws? ',' ws? d:r32
+ | 'b'? ws s:r8 ws? ',' ws? d:r64
+ ) { $$.movzx.type = 'b'; }
+ |
+ (
+ 'w' ws s:m ws? ',' ws? d:r32
+ | 'w' ws s:m ws? ',' ws? d:r64
+ | 'w'? ws s:r16 ws? ',' ws? d:r32
+ | 'w'? ws s:r16 ws? ',' ws? d:r64
+ ) { $$.movzx.type = 'w'; }
+ ) { $$.movzx.kind = ASM_MOVZX;
+ $$.movzx.src = dupv(&s);
+ $$.movzx.dst = dupv(&d); }
+
lea =
"lea"
(
- "q"? ws s:m ws? ',' ws? d:r64
- { $$.lea.type = 'q'; }
- | "l"? ws s:m ws? ',' ws? d:r32
- { $$.lea.type = 'l'; }
+ 'w'? ws s:m ws? ',' ws? d:r16
+ { $$.lea.type = 'w'; }
+ | 'l'? ws s:m ws? ',' ws? d:r32
+ { $$.lea.type = 'l'; }
+ | 'q'? ws s:m ws? ',' ws? d:r64
+ { $$.lea.type = 'q'; }
+
) { $$.lea.kind = ASM_LEA;
$$.lea.src = dupv(&s);
$$.lea.dst = dupv(&d); }
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;}
+ "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; }
+ | "xchg" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_XCHG; }
+ | "xor" a:mod-rm-binop-args { $$ = a; $$.kind = ASM_XOR; }
+
mod-rm-binop-args =
(
- "q" ws s:r-m64 ws? ',' ws? d:r64
- | "q" ws s:r64 ws? ',' ws? d:r-m64
- | "q" ws s:imm ws? ',' ws? d:r-m64
+ 'b' ws s:r-m8 ws? ',' ws? d:r8
+ | 'b' ws s:r8 ws? ',' ws? d:r-m8
+ | 'b' ws s:imm ws? ',' ws? d:r-m8
+ | ws s:r8 ws? ',' ws? d:r8
+ | ws s:m ws? ',' ws? d:r8
+ | ws s:imm ws? ',' ws? d:r8
+ )
+ { $$.modrmbinop = (ModRMBinop){ .type = 'b', .src = dupv(&s), .dst = dupv(&d) }; }
+ |
+ (
+ 'w' ws s:r-m16 ws? ',' ws? d:r16
+ | 'w' ws s:r16 ws? ',' ws? d:r-m16
+ | 'w' ws s:imm ws? ',' ws? d:r-m16
+ | ws s:r16 ws? ',' ws? d:r16
+ | ws s:m ws? ',' ws? d:r16
+ | ws s:imm ws? ',' ws? d:r16
+ )
+ { $$.modrmbinop = (ModRMBinop){ .type = 'w', .src = dupv(&s), .dst = dupv(&d) }; }
+ |
+ (
+ 'l' ws s:r-m32 ws? ',' ws? d:r32
+ | 'l' ws s:r32 ws? ',' ws? d:r-m32
+ | 'l' ws s:imm ws? ',' ws? d:r-m32
+ | ws s:r32 ws? ',' ws? d:r32
+ | ws s:m ws? ',' ws? d:r32
+ | ws s:imm ws? ',' ws? d:r32
+ )
+ { $$.modrmbinop = (ModRMBinop){ .type = 'l', .src = dupv(&s), .dst = dupv(&d) }; }
+ |
+ (
+ 'q' ws s:r-m64 ws? ',' ws? d:r64
+ | 'q' ws s:r64 ws? ',' ws? d:r-m64
+ | 'q' ws s:imm ws? ',' ws? d:r-m64
| ws s:r64 ws? ',' ws? d:r64
| ws s:m ws? ',' ws? d:r64
| ws s:imm ws? ',' ws? d:r64
- ) { $$.modrmbinop = (ModRMBinop){ .type = 'q', .src = dupv(&s), .dst = dupv(&d) } }
- | (
- "l" ws s:r-m32 ws? ',' ws? d:r32
- | "l" ws s:r32 ws? ',' ws? d:r-m32
- | "l" ws s:imm ws? ',' ws? d:r-m32
- | ws s:r32 ws? ',' ws? d:r32
- | ws s:m ws? ',' ws? d:r32
- | ws s:imm ws? ',' ws? d:r32
- )
- { $$.modrmbinop = (ModRMBinop){ .type = 'l', .src = dupv(&s), .dst = dupv(&d) } }
+ ) { $$.modrmbinop = (ModRMBinop){ .type = 'q', .src = dupv(&s), .dst = dupv(&d) }; }
-r-m64 =
- r:r64 { $$ = r; }
- | m:m { $$ = m; }
+
+r-m8 =
+ r:r8 { $$ = r; }
+ | m:m { $$ = m; }
+
+r-m16 =
+ r:r16 { $$ = r; }
+ | m:m { $$ = m; }
r-m32 =
r:r32 { $$ = r; }
| m:m { $$ = m; }
+r-m64 =
+ r:r64 { $$ = r; }
+ | m:m { $$ = m; }
+
m =
'(' ws? r:r64 ws? ')'
- { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = 0, .l = NULL, .reg = r.kind } }
+ { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = 0, .l = NULL, .reg = r.kind }; }
| <'-'?[0-9]+> ws? '(' ws? r:r64 ws? ')'
- { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = strtoll(yytext, NULL, 10), .l = NULL, .reg = r.kind } }
+ { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = strtoll(yytext, NULL, 10), .l = NULL, .reg = r.kind }; }
| i:ident ws? '(' ws? r:r64 ws? ')'
- { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = 0, .l = i.ident.name, .reg = r.kind } }
-
-r64 =
- "%rax" { $$.kind = ASM_RAX }
- | "%rcx" { $$.kind = ASM_RCX }
- | "%rdx" { $$.kind = ASM_RDX }
- | "%rbx" { $$.kind = ASM_RBX }
- | "%rsp" { $$.kind = ASM_RSP }
- | "%rbp" { $$.kind = ASM_RBP }
- | "%rsi" { $$.kind = ASM_RSI }
- | "%rdi" { $$.kind = ASM_RDI }
- | "%r8" { $$.kind = ASM_R8 }
- | "%r9" { $$.kind = ASM_R9 }
- | "%r10" { $$.kind = ASM_R10 }
- | "%r11" { $$.kind = ASM_R11 }
- | "%r12" { $$.kind = ASM_R12 }
- | "%r13" { $$.kind = ASM_R13 }
- | "%r14" { $$.kind = ASM_R14 }
- | "%r15" { $$.kind = ASM_R15 }
-
-r32 =
- "%eax" { $$.kind = ASM_EAX }
- | "%ecx" { $$.kind = ASM_ECX }
- | "%edx" { $$.kind = ASM_EDX }
- | "%ebx" { $$.kind = ASM_EBX }
- | "%esp" { $$.kind = ASM_ESP }
- | "%ebp" { $$.kind = ASM_EBP }
- | "%esi" { $$.kind = ASM_ESI }
- | "%edi" { $$.kind = ASM_EDI }
-
+ { $$.memarg = (Memarg){ .kind = ASM_MEMARG, .c = 0, .l = i.ident.name, .reg = r.kind }; }
+
+r8 =
+ "%al" { $$.kind = ASM_AL; }
+ | "%cl" { $$.kind = ASM_CL; }
+ | "%dl" { $$.kind = ASM_DL; }
+ | "%bl" { $$.kind = ASM_BL; }
+ | "%spl" { $$.kind = ASM_SPL; }
+ | "%bpl" { $$.kind = ASM_BPL; }
+ | "%sil" { $$.kind = ASM_SIL; }
+ | "%dil" { $$.kind = ASM_DIL; }
+ | "%r8b" { $$.kind = ASM_R8B; }
+ | "%r9b" { $$.kind = ASM_R9B; }
+ | "%r10b" { $$.kind = ASM_R10B; }
+ | "%r11b" { $$.kind = ASM_R11B; }
+ | "%r12b" { $$.kind = ASM_R12B; }
+ | "%r13b" { $$.kind = ASM_R13B; }
+ | "%r14b" { $$.kind = ASM_R14B; }
+ | "%r15b" { $$.kind = ASM_R15B; }
+
+r16 =
+ "%ax" { $$.kind = ASM_AX; }
+ | "%cx" { $$.kind = ASM_CX; }
+ | "%dx" { $$.kind = ASM_DX; }
+ | "%bx" { $$.kind = ASM_BX; }
+ | "%sp" { $$.kind = ASM_SP; }
+ | "%bp" { $$.kind = ASM_BP; }
+ | "%si" { $$.kind = ASM_SI; }
+ | "%di" { $$.kind = ASM_DI; }
+ | "%r8w" { $$.kind = ASM_R8W; }
+ | "%r9w" { $$.kind = ASM_R9W; }
+ | "%r10w" { $$.kind = ASM_R10W; }
+ | "%r11w" { $$.kind = ASM_R11W; }
+ | "%r12w" { $$.kind = ASM_R12W; }
+ | "%r13w" { $$.kind = ASM_R13W; }
+ | "%r14w" { $$.kind = ASM_R14W; }
+ | "%r15w" { $$.kind = ASM_R15W; }
+
+r32 =
+ "%eax" { $$.kind = ASM_EAX; }
+ | "%ecx" { $$.kind = ASM_ECX; }
+ | "%edx" { $$.kind = ASM_EDX; }
+ | "%ebx" { $$.kind = ASM_EBX; }
+ | "%esp" { $$.kind = ASM_ESP; }
+ | "%ebp" { $$.kind = ASM_EBP; }
+ | "%esi" { $$.kind = ASM_ESI; }
+ | "%edi" { $$.kind = ASM_EDI; }
+ | "%r8d" { $$.kind = ASM_R8D; }
+ | "%r9d" { $$.kind = ASM_R9D; }
+ | "%r10d" { $$.kind = ASM_R10D; }
+ | "%r11d" { $$.kind = ASM_R11D; }
+ | "%r12d" { $$.kind = ASM_R12D; }
+ | "%r13d" { $$.kind = ASM_R13D; }
+ | "%r14d" { $$.kind = ASM_R14D; }
+ | "%r15d" { $$.kind = ASM_R15D; }
+
+r64 = (
+ "%rax" { $$.kind = ASM_RAX; }
+ | "%rcx" { $$.kind = ASM_RCX; }
+ | "%rdx" { $$.kind = ASM_RDX; }
+ | "%rbx" { $$.kind = ASM_RBX; }
+ | "%rsp" { $$.kind = ASM_RSP; }
+ | "%rbp" { $$.kind = ASM_RBP; }
+ | "%rsi" { $$.kind = ASM_RSI; }
+ | "%rdi" { $$.kind = ASM_RDI; }
+ | "%r8" ![lwb] { $$.kind = ASM_R8; }
+ | "%r9" ![lwb] { $$.kind = ASM_R9; }
+ | "%r10" ![lwb] { $$.kind = ASM_R10; }
+ | "%r11" ![lwb] { $$.kind = ASM_R11; }
+ | "%r12" ![lwb] { $$.kind = ASM_R12; }
+ | "%r13" ![lwb] { $$.kind = ASM_R13; }
+ | "%r14" ![lwb] { $$.kind = ASM_R14; }
+ | "%r15" ![lwb] { $$.kind = ASM_R15; }
+)
imm =
'$' i:ident
@@ -132,8 +237,3 @@ ident =
number =
<'-'?[0-9]+>
{ $$.number = (Number){ .kind = ASM_NUMBER, .v = strtoll(yytext, NULL, 10) }; }
-
-ws = [ \t]+
-
-eol = ws? "\n"
-