aboutsummaryrefslogtreecommitdiff
path: root/asm.peg
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-05 18:10:36 +1300
committerAndrew Chambers <[email protected]>2021-10-05 18:10:36 +1300
commit5c0af4055474834542e2813f36f4dd9a16479e53 (patch)
tree0132bfdfd56bc995b83f2a6f1791dd4f4b8bc2c1 /asm.peg
parentdda3e77e5b3c01c52fc38a29cd81d49c52abb26c (diff)
Port lexer to leg.
Diffstat (limited to 'asm.peg')
-rw-r--r--asm.peg80
1 files changed, 80 insertions, 0 deletions
diff --git a/asm.peg b/asm.peg
new file mode 100644
index 0000000..946f6e6
--- /dev/null
+++ b/asm.peg
@@ -0,0 +1,80 @@
+
+line = s:stmt (eol | !. ) { yy->v = s; }
+ | eol { yy->v.kind = ASM_BLANK; }
+ | . { yy->v.kind = ASM_SYNTAX_ERROR; }
+
+stmt = d:directive {$$ = d;}
+ | i:instr { $$ = i; }
+ | l:label { $$ = l; }
+
+directive = ".glob" "o"? "l" ws i:ident
+ { $$.globl = (Globl){.kind = ASM_DIR_GLOBL, .name = i.ident.name }; }
+ | ".data" { $$.kind = ASM_DIR_DATA; }
+ | ".text" { $$.kind = ASM_DIR_TEXT; }
+ | ".balign" ws n:number
+ { $$.balign = (Balign){.kind = ASM_DIR_BALIGN, .align = n.number.v }; }
+ | ".byte" ws n:number
+ { $$.byte = (Byte){.kind = ASM_DIR_BYTE, .b = (uint8_t)n.number.v }; }
+
+label = i:ident ':'
+ { $$.label = (Label){.kind = ASM_LABEL, .name = i.ident.name}; }
+
+instr = "nop"{ $$.kind = ASM_NOP; }
+ | "leave" { $$.kind = ASM_LEAVE; }
+ | "ret" { $$.kind = ASM_RET; }
+ | i:jmp { $$ = i; }
+ | i:add { $$ = i; }
+
+jmp = "jmp" ws i:ident
+ { $$.jmp = (Jmp){.kind = ASM_JMP, .target = i.ident.name}; }
+
+add = "addq" ws s:r-m64 ws? ',' ws? d:r64
+ { $$.add = (Add){ .kind = ASM_ADD, .type = 'q', .src = dupv(&s), .dst = dupv(&d) } }
+ | "addq" ws s:r64 ws? ',' ws? d:r-m64
+ { $$.add = (Add){ .kind = ASM_ADD, .type = 'q', .src = dupv(&s), .dst = dupv(&d) } }
+ | "addq" ws s:imm ws? ',' ws? d:r-m64
+ { $$.add = (Add){ .kind = ASM_ADD, .type = 'q', .src = dupv(&s), .dst = dupv(&d) } }
+
+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 } }
+ | <'-'?[0-9]+> ws? '(' ws? r:r64 ws? ')'
+ { $$.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 }
+
+
+imm = '$' i:ident
+ { $$.imm = (Imm){.kind = ASM_IMM, .l = i.ident.name, .c = 0 }; }
+ | '$' <'-'?[0-9]+>
+ { $$.imm = (Imm){.kind = ASM_IMM, .l = NULL, .c = strtoll(yytext, NULL, 10) }; }
+
+ident = <[_a-zA-Z][_a-zA-Z0-9]*>
+ { $$.ident = (Ident){ .kind = ASM_IDENT, .name = xstrdup(yytext) }; }
+
+number = <'-'?[0-9]+>
+ { $$.number = (Number){ .kind = ASM_NUMBER, .v = strtoll(yytext, NULL, 10) }; }
+
+ws = [ \t]+
+
+eol = ws? "\n"
+