feat: generate assembly from main
This commit is contained in:
parent
1ce36dd8da
commit
7f2870e340
@ -64,157 +64,8 @@ def frontend(
|
|||||||
}
|
}
|
||||||
|
|
||||||
val s = "enter an integer to echo"
|
val s = "enter an integer to echo"
|
||||||
def backend(typedProg: microWacc.Program): List[asm.AsmLine] | String =
|
def backend(typedProg: microWacc.Program): List[asm.AsmLine] =
|
||||||
typedProg match {
|
asmGenerator.generateAsm(typedProg)
|
||||||
case microWacc.Program(
|
|
||||||
Nil,
|
|
||||||
microWacc.Call(microWacc.Builtin.Exit, microWacc.IntLiter(v) :: Nil) :: Nil
|
|
||||||
) =>
|
|
||||||
s""".intel_syntax noprefix
|
|
||||||
.globl main
|
|
||||||
main:
|
|
||||||
mov edi, ${v}
|
|
||||||
call exit@plt
|
|
||||||
"""
|
|
||||||
case microWacc.Program(
|
|
||||||
Nil,
|
|
||||||
microWacc.Assign(microWacc.Ident("x", _), microWacc.IntLiter(1)) ::
|
|
||||||
microWacc.Call(microWacc.Builtin.Println, _) ::
|
|
||||||
microWacc.Assign(
|
|
||||||
microWacc.Ident("x", _),
|
|
||||||
microWacc.Call(microWacc.Builtin.ReadInt, Nil)
|
|
||||||
) ::
|
|
||||||
microWacc.Call(microWacc.Builtin.Println, microWacc.Ident("x", _) :: Nil) :: Nil
|
|
||||||
) =>
|
|
||||||
""".intel_syntax noprefix
|
|
||||||
.globl main
|
|
||||||
.section .rodata
|
|
||||||
# length of .L.str0
|
|
||||||
.int 24
|
|
||||||
.L.str0:
|
|
||||||
.asciz "enter an integer to echo"
|
|
||||||
.text
|
|
||||||
main:
|
|
||||||
push rbp
|
|
||||||
# push {rbx, r12}
|
|
||||||
sub rsp, 16
|
|
||||||
mov qword ptr [rsp], rbx
|
|
||||||
mov qword ptr [rsp + 8], r12
|
|
||||||
mov rbp, rsp
|
|
||||||
mov r12d, 1
|
|
||||||
lea rdi, [rip + .L.str0]
|
|
||||||
# statement primitives do not return results (but will clobber r0/rax)
|
|
||||||
call _prints
|
|
||||||
call _println
|
|
||||||
# load the current value in the destination of the read so it supports defaults
|
|
||||||
mov edi, r12d
|
|
||||||
call _readi
|
|
||||||
mov r12d, eax
|
|
||||||
mov edi, eax
|
|
||||||
# statement primitives do not return results (but will clobber r0/rax)
|
|
||||||
call _printi
|
|
||||||
call _println
|
|
||||||
mov rax, 0
|
|
||||||
# pop/peek {rbx, r12}
|
|
||||||
mov rbx, qword ptr [rsp]
|
|
||||||
mov r12, qword ptr [rsp + 8]
|
|
||||||
add rsp, 16
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.section .rodata
|
|
||||||
# length of .L._printi_str0
|
|
||||||
.int 2
|
|
||||||
.L._printi_str0:
|
|
||||||
.asciz "%d"
|
|
||||||
.text
|
|
||||||
_printi:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
|
||||||
and rsp, -16
|
|
||||||
mov esi, edi
|
|
||||||
lea rdi, [rip + .L._printi_str0]
|
|
||||||
# on x86, al represents the number of SIMD registers used as variadic arguments
|
|
||||||
mov al, 0
|
|
||||||
call printf@plt
|
|
||||||
mov rdi, 0
|
|
||||||
call fflush@plt
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.section .rodata
|
|
||||||
# length of .L._prints_str0
|
|
||||||
.int 4
|
|
||||||
.L._prints_str0:
|
|
||||||
.asciz "%.*s"
|
|
||||||
.text
|
|
||||||
_prints:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
|
||||||
and rsp, -16
|
|
||||||
mov rdx, rdi
|
|
||||||
mov esi, dword ptr [rdi - 4]
|
|
||||||
lea rdi, [rip + .L._prints_str0]
|
|
||||||
# on x86, al represents the number of SIMD registers used as variadic arguments
|
|
||||||
mov al, 0
|
|
||||||
call printf@plt
|
|
||||||
mov rdi, 0
|
|
||||||
call fflush@plt
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.section .rodata
|
|
||||||
# length of .L._println_str0
|
|
||||||
.int 0
|
|
||||||
.L._println_str0:
|
|
||||||
.asciz ""
|
|
||||||
.text
|
|
||||||
_println:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
|
||||||
and rsp, -16
|
|
||||||
lea rdi, [rip + .L._println_str0]
|
|
||||||
call puts@plt
|
|
||||||
mov rdi, 0
|
|
||||||
call fflush@plt
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
|
|
||||||
.section .rodata
|
|
||||||
# length of .L._readi_str0
|
|
||||||
.int 2
|
|
||||||
.L._readi_str0:
|
|
||||||
.asciz "%d"
|
|
||||||
.text
|
|
||||||
_readi:
|
|
||||||
push rbp
|
|
||||||
mov rbp, rsp
|
|
||||||
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
|
||||||
and rsp, -16
|
|
||||||
# RDI contains the "original" value of the destination of the read
|
|
||||||
# allocate space on the stack to store the read: preserve alignment!
|
|
||||||
# the passed default argument should be stored in case of EOF
|
|
||||||
sub rsp, 16
|
|
||||||
mov dword ptr [rsp], edi
|
|
||||||
lea rsi, qword ptr [rsp]
|
|
||||||
lea rdi, [rip + .L._readi_str0]
|
|
||||||
# on x86, al represents the number of SIMD registers used as variadic arguments
|
|
||||||
mov al, 0
|
|
||||||
call scanf@plt
|
|
||||||
mov eax, dword ptr [rsp]
|
|
||||||
add rsp, 16
|
|
||||||
mov rsp, rbp
|
|
||||||
pop rbp
|
|
||||||
ret
|
|
||||||
"""
|
|
||||||
case _ => List()
|
|
||||||
}
|
|
||||||
|
|
||||||
def compile(filename: String, outFile: Option[File] = None)(using
|
def compile(filename: String, outFile: Option[File] = None)(using
|
||||||
stdout: PrintStream = Console.out
|
stdout: PrintStream = Console.out
|
||||||
@ -222,13 +73,8 @@ def compile(filename: String, outFile: Option[File] = None)(using
|
|||||||
frontend(os.read(os.Path(filename))) match {
|
frontend(os.read(os.Path(filename))) match {
|
||||||
case Left(typedProg) =>
|
case Left(typedProg) =>
|
||||||
val asmFile = outFile.getOrElse(File(filename.stripSuffix(".wacc") + ".s"))
|
val asmFile = outFile.getOrElse(File(filename.stripSuffix(".wacc") + ".s"))
|
||||||
backend(typedProg) match {
|
val asm = backend(typedProg)
|
||||||
case s: String =>
|
writer.writeTo(asm, PrintStream(asmFile))
|
||||||
os.write.over(os.Path(asmFile.getAbsolutePath), s)
|
|
||||||
case ops: List[asm.AsmLine] => {
|
|
||||||
writer.writeTo(ops, PrintStream(asmFile))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
0
|
0
|
||||||
case Right(exitCode) => exitCode
|
case Right(exitCode) => exitCode
|
||||||
}
|
}
|
||||||
|
@ -81,13 +81,14 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
|
|||||||
// disable formatting to avoid binPack
|
// disable formatting to avoid binPack
|
||||||
"^.*wacc-examples/valid/advanced.*$",
|
"^.*wacc-examples/valid/advanced.*$",
|
||||||
"^.*wacc-examples/valid/array.*$",
|
"^.*wacc-examples/valid/array.*$",
|
||||||
|
"^.*wacc-examples/valid/basic/exit.*$",
|
||||||
"^.*wacc-examples/valid/basic/skip.*$",
|
"^.*wacc-examples/valid/basic/skip.*$",
|
||||||
"^.*wacc-examples/valid/expressions.*$",
|
"^.*wacc-examples/valid/expressions.*$",
|
||||||
"^.*wacc-examples/valid/function/nested_functions.*$",
|
"^.*wacc-examples/valid/function/nested_functions.*$",
|
||||||
"^.*wacc-examples/valid/function/simple_functions.*$",
|
"^.*wacc-examples/valid/function/simple_functions.*$",
|
||||||
"^.*wacc-examples/valid/if.*$",
|
"^.*wacc-examples/valid/if.*$",
|
||||||
"^.*wacc-examples/valid/IO/print.*$",
|
"^.*wacc-examples/valid/IO/print.*$",
|
||||||
"^.*wacc-examples/valid/IO/read(?!echoInt\\.wacc).*$",
|
"^.*wacc-examples/valid/IO/read.*$",
|
||||||
"^.*wacc-examples/valid/IO/IOLoop.wacc.*$",
|
"^.*wacc-examples/valid/IO/IOLoop.wacc.*$",
|
||||||
"^.*wacc-examples/valid/IO/IOSequence.wacc.*$",
|
"^.*wacc-examples/valid/IO/IOSequence.wacc.*$",
|
||||||
"^.*wacc-examples/valid/pairs.*$",
|
"^.*wacc-examples/valid/pairs.*$",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user