diff options
| author | Andrew Chambers <[email protected]> | 2021-10-07 01:53:34 +1300 |
|---|---|---|
| committer | Andrew Chambers <[email protected]> | 2021-10-07 01:53:34 +1300 |
| commit | f4a9a52d001a54ca1142110b70142a8ef8df53bc (patch) | |
| tree | 95226e04b60c43b1143b7d27d7fe6905ae0b3dd4 /asm.peg | |
| parent | 78aa469080b95f41fabc0f428bd4e5b1bbdaa04b (diff) | |
Work.
Diffstat (limited to 'asm.peg')
| -rw-r--r-- | asm.peg | 236 |
1 files changed, 168 insertions, 68 deletions
@@ -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" - |
