Fil-C on Nix

Filnix wiki

mbrock/filnix/nanofil

asm.pl

x86-64 assembly as terms, and their printer as GNU as (AT&T) text. The backends build a list of lines; this module is the only place that knows AT&T syntax.

Lines

LinePrints as
labelSS:
insOp, Suffix, OperandsOp, then Suffix unless it is none, then the operands in AT&T order (sources first)
a directivethe directive, below
DirectivePrints as
sectionSthe section S: text, data, rodata, bss, data_rel_ro or note_gnu_stack
p2alignN balignN.p2align N, .balign N
globlS weakS hiddenS.globl S, .weak S, .hidden S
typeS, T.type S, @T, T function or object
sizeS.size S, .-S
sizeS, N.size S, N
setS, E.set S, E
quadE.quad E
longN intN shortN.long N, .int N, .short N
byteNs.byte and the non-empty list Ns
zeroN.zero N
asciiChars.ascii and the characters, escaped
ascizAtom.asciz and the atom, as it is

Operands

Operands name concrete registers, so mixed widths such as movzbl %al, %eax need no width bookkeeping.

OperandPrints as
immE$E
regR%R, for example regeax, regcl, regr9d
memD, BD(%B), D omitted when 0
memD, B, ID(%B,%I), D omitted when 0
ripEE(%rip)
gotpcrelSS@GOTPCREL(%rip)
pltSS@PLT
symEE, a jump or call target
indO*O

An expression E is an integer, a symbol atom or E1+E2; a left operand that is itself a sum is parenthesized.

moduleasm
useslists
usesdcgs
usesformat
64lines[] ⟶
[]
65linesLine|Lines ⟶
lineLine
linesLines

The text of one line, committed to its first parse.

70lineLine ⟶
line_charsLine, Cs
→
true
else
thrownanofil_errorbad_asm_lineLine
seqCs
76line_charsLine, Cs ←
phraseline_textLine, Cs
line_text+Line//

the text of Line. directive//1 has no clause for label/1 or ins/3, so the cases are disjoint; line//1 commits to the first parse.

82line_textlabelS ⟶
":\n"
85line_textinsOp, Suffix, Operands ⟶
"\t"
suffixSuffix
operandsOperands
"\n"
91line_textDirective ⟶
"\t"
directiveDirective
"\n"

The cut is for the default case: a suffix is none or any other atom (a defaulty term shared with the backends).

98suffixnone ⟶
!
99suffixS ⟶
101operands[] ⟶
[]
102operandsO|Os ⟶
107more_operands[] ⟶
[]
108more_operandsO|Os ⟶
113operandimmE ⟶
"$"
114operandregR ⟶
115operandmemD, B ⟶
"(%"
")"
116operandmemD, B, I ⟶
"(%"
",%"
")"
117operandripE ⟶
"(%rip)"
118operandgotpcrelS ⟶
"@GOTPCREL(%rip)"
119operandpltS ⟶
"@PLT"
120operandsymE ⟶
121operandindO ⟶

A displacement of 0 is omitted; the cut is for the default case.

124disp0 ⟶
!
125dispD ⟶

A sum whose left operand is itself a sum parenthesizes it. The cut is for the default case, an integer or symbol (a defaulty term shared with the backends; literal//1 would throw on a sum).

130exprA + B ⟶
!
A = _ + _
→
"("
")"
else
"+"
137exprE ⟶
139directivesectionS ⟶
seqName
140directivep2alignN ⟶
".p2align "
141directivebalignN ⟶
".balign "
142directivegloblS ⟶
".globl "
143directiveweakS ⟶
".weak "
144directivehiddenS ⟶
".hidden "
145directivetypeS, T ⟶
".type "
", @"
146directivesizeS ⟶
".size "
", .-"
147directivesizeS, N ⟶
".size "
", "
148directivesetS, E ⟶
".set "
", "
149directivequadE ⟶
".quad "
150directivelongN ⟶
".long "
151directiveintN ⟶
".int "
152directiveshortN ⟶
".short "
153directivebyteN|Ns ⟶
154directivezeroN ⟶
".zero "
155directiveasciiCs ⟶
".ascii \""
"\""
156directiveascizA ⟶
".asciz \""
"\""
ascii_chars+Cs//

the bytes Cs, one per character, inside an .ascii string: printable ASCII as itself except quote and backslash, which are escaped, newline and tab as \n and \t, any other byte as three octal digits.

162ascii_chars[] ⟶
[]
163ascii_charsC|Cs ⟶
165ascii_char'"' ⟶
!
"\\\""
166ascii_char\ ⟶
!
"\\\\"
167ascii_char'\n' ⟶
!
"\\n"
168ascii_char'\t' ⟶
!
"\\t"
169ascii_charC ⟶
char_codeC, N
N ≥ 32
N ≤ 126
!
C
170ascii_charC ⟶
char_codeC, N
maplistoctal_charN, 6, 3, 0, Os
"\\"
seqOs
octal_char+N, +Shift, -O

O is the octal digit of N at bit Shift.

176octal_charN, Shift, O ←
D is N >> Shift /\ 7 + 0'0
char_codeO, D
178more_bytes[] ⟶
[]
179more_bytesN|Ns ⟶
section_name?Section, ?Name

Name is the directive text of Section.

section_name
185text".text"
186data".data"
187rodata".section .rodata"
188bss".bss"
189data_rel_ro".section .data.rel.ro,\"aw\",@progbits"
190note_gnu_stack".section .note.GNU-stack,\"\",@progbits"

The text of an atom or number.

193literalX ⟶
atomX
→
atom_charsX, Cs
else
number_charsX, Cs
seqCs