aboutsummaryrefslogtreecommitdiff
path: root/asm.peg
diff options
context:
space:
mode:
authorAndrew Chambers <[email protected]>2021-10-17 18:08:14 +1300
committerAndrew Chambers <[email protected]>2021-10-17 18:08:14 +1300
commit8464df80ace17b3decc59c4752bf1f4de9dccae8 (patch)
treedb62cd75918c2f466313d1171fb8573975baa3d4 /asm.peg
parentfccfcc2043e56306935dff29e66c414fd6c0a6d0 (diff)
parentbcaa994f61c57ca5c5446a4ead7015dd1ead95db (diff)
Merge branch 'master' of github.com:andrewchambers/minias
Diffstat (limited to 'asm.peg')
-rw-r--r--asm.peg190
1 files changed, 93 insertions, 97 deletions
diff --git a/asm.peg b/asm.peg
index fc904d5..88f5324 100644
--- a/asm.peg
+++ b/asm.peg
@@ -5,13 +5,10 @@ line =
| . { yy->v.kind = ASM_SYNTAX_ERROR; }
ws = ([ \t]+ | comment)+
-
comment = "/*" ( ! "\n" ! "*/" . )* "*/" # No support for multiline comments for now as they break our line numbers.
-
eolcomment = '#' (! "\n" .)+
eol = ws? eolcomment? "\n"
-
stmt =
'.' d:directive eol {$$ = d;}
| i:instr eol { $$ = i; }
@@ -66,25 +63,50 @@ label =
{ $$.label = (Label){.kind = ASM_LABEL, .name = i.charptr}; }
instr =
- # Ordered by relative frequency for performance.
-
- # Movs are very common, so they come first.
+ # Ordered by instruction frequency for performance.
+ # e.g. movs are very common, so they come first.
+ # The & operator means check without consuming input.
(& 'm'
(
- i:mov { $$ = i; }
- | i:movsx { $$ = i; }
- | i:movzx { $$ = i; }
- | i:mul { $$ = i; }
- # Less common, but we have already checked for 'm'
- | i:movaps { $$ = i; }
- | i:movq { $$ = i; }
- | i:movsd { $$ = i; }
- | i:movss { $$ = i; }
- | i:mulsd { $$ = i; }
- | i:mulss { $$ = i; }))
- | i:add { $$ = i; }
- | i:and { $$ = i; }
- | i:cmp { $$ = i; }
+ i:mov { $$ = i; }
+ | i:movsx { $$ = i; }
+ | i:movzx { $$ = i; }
+ | i:mul { $$ = i; }
+ | i:movaps { $$ = i; }
+ | i:movq { $$ = i; }
+ | i:movsd { $$ = i; }
+ | i:movss { $$ = i; }
+ | i:mulsd { $$ = i; }
+ | i:mulss { $$ = i; }))
+ | (& 'a'
+ (
+ i:add { $$ = i; }
+ | i:and { $$ = i; }
+ | i:addss { $$ = i; }
+ | i:addsd { $$ = i; } ))
+ | (& 'c'
+ (
+ i:cmp { $$ = i; }
+ | i:call { $$ = i; }
+ | i:cvtsi2sd { $$ = i; }
+ | i:cvtsi2ss { $$ = i; }
+ | i:cvtss2sd { $$ = i; }
+ | i:cvtsd2ss { $$ = i; }
+ | i:cvttsd2si { $$ = i; }
+ | i:cvttss2si { $$ = i; }
+ | i:cltd { $$ = i; }
+ | i:cqto { $$ = i; }))
+ | (& 's'
+ (
+ i:set { $$ = i; }
+ | i:sub { $$ = i; }
+ | i:sal { $$ = i; }
+ | i:sar { $$ = i; }
+ | i:shl { $$ = i; }
+ | i:shr { $$ = i; }
+ | i:subsd { $$ = i; }
+ | i:subss { $$ = i; }))
+ | i:or { $$ = i; }
| i:leave { $$ = i; }
| i:ret { $$ = i; }
| i:push { $$ = i; }
@@ -95,44 +117,18 @@ instr =
| i:lea { $$ = i; }
| i:imul { $$ = i; }
| i:neg { $$ = i; }
- | i:or { $$ = i; }
- | (& 's'
- (
- i:set { $$ = i; }
- | i:sub { $$ = i; }
- | i:sal { $$ = i; }
- | i:sar { $$ = i; }
- | i:shl { $$ = i; }
- | i:shr { $$ = i; }))
| i:test { $$ = i; }
| i:xchg { $$ = i; }
| i:xor { $$ = i; }
- | i:call { $$ = i; }
- # Misc
- | i:cltd { $$ = i; }
- | i:cqto { $$ = i; }
- | i:nop { $$ = i; }
# Floating point is less common, so check last.
- | i:addss { $$ = i; }
- | i:addsd { $$ = i; }
| i:divss { $$ = i; }
| i:divsd { $$ = i; }
| i:pxor { $$ = i; }
| i:xorpd { $$ = i; }
| i:xorps { $$ = i; }
- | i:subsd { $$ = i; }
- | i:subss { $$ = i; }
| i:ucomisd { $$ = i; }
| i:ucomiss { $$ = i; }
- | (& 'c'
- (
- i:cvtsi2sd { $$ = i; }
- | i:cvtsi2ss { $$ = i; }
- | i:cvtss2sd { $$ = i; }
- | i:cvtsd2ss { $$ = i; }
- | i:cvttsd2si { $$ = i; }
- | i:cvttss2si { $$ = i; }))
-
+ | i:nop { $$ = i; }
cltd = "cltd" { $$ = (Parsev){ .kind=ASM_CLTD }; }
cqto = "cqto" { $$ = (Parsev){ .kind=ASM_CQTO }; }
@@ -140,17 +136,15 @@ leave = "leave" { $$ = (Parsev){ .kind=ASM_LEAVE }; }
nop = "nop" { $$ = (Parsev){ .kind=ASM_NOP }; }
ret = "ret" { $$ = (Parsev){ .kind=ASM_RET }; }
-push =
- "push" (
- 'q'? ws s:r64 { $$ = INSTR1(0, s); }
- | 'q' ws s:mem { $$ = INSTR1(1, s); }
- ) { $$.instr.kind = ASM_PUSH; }
+push = "push" (
+ 'q'? ws s:r64 { $$ = INSTR1(0, s); }
+ | 'q' ws s:mem { $$ = INSTR1(1, s); }
+) { $$.instr.kind = ASM_PUSH; }
-pop =
- "pop" (
- 'q'? ws d:r64 { $$ = INSTR1(0, d); }
- | 'q' ws d:mem { $$ = INSTR1(1, d); }
- ) { $$.instr.kind = ASM_POP; }
+pop = "pop" (
+ 'q'? ws d:r64 { $$ = INSTR1(0, d); }
+ | 'q' ws d:mem { $$ = INSTR1(1, d); }
+) { $$.instr.kind = ASM_POP; }
call = "call" 'q'? ws (
'*' t:mem
@@ -175,20 +169,22 @@ condition-code =
| "pe" { $$.i64 = 3; }
| "p" { $$.i64 = 4; }
| "o" { $$.i64 = 5; }
- | "nz" { $$.i64 = 6; }
- | "ns" { $$.i64 = 7; }
- | "np" { $$.i64 = 8; }
- | "no" { $$.i64 = 9; }
- | "nle" { $$.i64 = 10; }
- | "nl" { $$.i64 = 11; }
- | "nge" { $$.i64 = 12; }
- | "ng" { $$.i64 = 13; }
- | "ne" { $$.i64 = 14; }
- | "nc" { $$.i64 = 15; }
- | "nbe" { $$.i64 = 16; }
- | "nb" { $$.i64 = 17; }
- | "nae" { $$.i64 = 18; }
- | "na" { $$.i64 = 19; }
+ | ("n"
+ (
+ "z" { $$.i64 = 6; }
+ | "s" { $$.i64 = 7; }
+ | "p" { $$.i64 = 8; }
+ | "o" { $$.i64 = 9; }
+ | "le" { $$.i64 = 10; }
+ | "l" { $$.i64 = 11; }
+ | "ge" { $$.i64 = 12; }
+ | "g" { $$.i64 = 13; }
+ | "e" { $$.i64 = 14; }
+ | "c" { $$.i64 = 15; }
+ | "be" { $$.i64 = 16; }
+ | "b" { $$.i64 = 17; }
+ | "ae" { $$.i64 = 18; }
+ | "a" { $$.i64 = 19; }))
| "le" { $$.i64 = 20; }
| "l" { $$.i64 = 21; }
| "ge" { $$.i64 = 22; }
@@ -429,22 +425,22 @@ test = "test" (
addsd = "addsd" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_ADDSD; }
addss = "addss" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_ADDSS; }
subsd = "subsd" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_SUBSD; }
subss = "subss" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_SUBSS; }
cvtsi2sd = "cvtsi2sd" (
@@ -463,12 +459,12 @@ cvtsi2ss = "cvtsi2ss" (
cvtss2sd = "cvtss2sd" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_CVTSS2SD; }
cvtsd2ss = "cvtsd2ss" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_CVTSD2SS; }
cvttss2si = "cvttss2si" (
@@ -492,7 +488,7 @@ divsd = "divsd" (
divss = "divss" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_DIVSS; }
movaps = "movaps" (
@@ -503,12 +499,12 @@ movaps = "movaps" (
mulsd = "mulsd" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_MULSD; }
mulss = "mulss" (
ws s:xmm ws? ',' ws? d:xmm { $$ = INSTR2(0, s, d); }
- | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
+ | ws s:mem ws? ',' ws? d:xmm { $$ = INSTR2(1, s, d); }
) { $$.instr.kind = ASM_MULSS; }
movss = "movss" (
@@ -667,24 +663,24 @@ r64 = "%r" (
| "15" ![lwb] { $$ = REG(R15); }
)
-xmm = "%x" (
+xmm = "%xmm" (
# Reverse order due to peg ordering.
- "mm15" { $$ = REG(XMM15); }
- | "mm14" { $$ = REG(XMM14); }
- | "mm13" { $$ = REG(XMM13); }
- | "mm12" { $$ = REG(XMM12); }
- | "mm11" { $$ = REG(XMM11); }
- | "mm10" { $$ = REG(XMM10); }
- | "mm9" { $$ = REG(XMM7); }
- | "mm8" { $$ = REG(XMM7); }
- | "mm7" { $$ = REG(XMM7); }
- | "mm6" { $$ = REG(XMM6); }
- | "mm5" { $$ = REG(XMM5); }
- | "mm4" { $$ = REG(XMM4); }
- | "mm3" { $$ = REG(XMM3); }
- | "mm2" { $$ = REG(XMM2); }
- | "mm1" { $$ = REG(XMM1); }
- | "mm0" { $$ = REG(XMM0); }
+ "15" { $$ = REG(XMM15); }
+ | "14" { $$ = REG(XMM14); }
+ | "13" { $$ = REG(XMM13); }
+ | "12" { $$ = REG(XMM12); }
+ | "11" { $$ = REG(XMM11); }
+ | "10" { $$ = REG(XMM10); }
+ | "9" { $$ = REG(XMM7); }
+ | "8" { $$ = REG(XMM7); }
+ | "7" { $$ = REG(XMM7); }
+ | "6" { $$ = REG(XMM6); }
+ | "5" { $$ = REG(XMM5); }
+ | "4" { $$ = REG(XMM4); }
+ | "3" { $$ = REG(XMM3); }
+ | "2" { $$ = REG(XMM2); }
+ | "1" { $$ = REG(XMM1); }
+ | "0" { $$ = REG(XMM0); }
)
# We disallow newlines in our strings, it is simpler for lineno tracking.