native: handle ident and integer args in exit and add arm64
parent
a31a1eb9cb
commit
5be41ebc80
|
@ -361,10 +361,40 @@ pub fn (mut g Gen) gen_print(s string) {
|
|||
g.syscall()
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) gen_exit() {
|
||||
// Return 0
|
||||
g.mov(.edi, 0) // ret value
|
||||
g.mov(.eax, 60)
|
||||
fn (mut g Gen) nsyscall_exit() int {
|
||||
match g.pref.os {
|
||||
.linux {
|
||||
return 60
|
||||
}
|
||||
.macos {
|
||||
return 0x2000001
|
||||
}
|
||||
else {
|
||||
verror('unsupported exit syscall for this platform')
|
||||
}
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) gen_amd64_exit(expr ast.Expr) {
|
||||
// ret value
|
||||
match expr {
|
||||
ast.CallExpr {
|
||||
right := expr.return_type
|
||||
verror('native exit builtin: Unsupported call $right')
|
||||
}
|
||||
ast.Ident {
|
||||
var_offset := g.get_var_offset(expr.name)
|
||||
g.mov_var_to_reg(.edi, var_offset)
|
||||
}
|
||||
ast.IntegerLiteral {
|
||||
g.mov(.edi, expr.val.int())
|
||||
}
|
||||
else {
|
||||
verror('native builtin exit expects a numeric argument')
|
||||
}
|
||||
}
|
||||
g.mov(.eax, g.nsyscall_exit())
|
||||
g.syscall()
|
||||
}
|
||||
|
||||
|
@ -626,7 +656,8 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
|||
g.stmts(node.stmts)
|
||||
if is_main {
|
||||
// println('end of main: gen exit')
|
||||
g.gen_exit()
|
||||
zero := ast.IntegerLiteral{}
|
||||
g.gen_exit(zero)
|
||||
// return
|
||||
}
|
||||
if !is_main {
|
||||
|
|
|
@ -100,3 +100,16 @@ fn (mut g Gen) svc() {
|
|||
g.write32(0xd4001001)
|
||||
g.println('svc')
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) gen_arm64_exit(expr ast.Expr) {
|
||||
match expr {
|
||||
ast.IntegerLiteral {
|
||||
g.mov_arm(.x16, expr.val.u64())
|
||||
}
|
||||
else {
|
||||
verror('native builtin exit expects a numeric argument')
|
||||
}
|
||||
}
|
||||
g.mov_arm(.x0, 0)
|
||||
g.svc()
|
||||
}
|
||||
|
|
|
@ -259,6 +259,20 @@ fn (mut g Gen) for_in_stmt(node ast.ForInStmt) {
|
|||
*/
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) gen_exit(node ast.Expr) {
|
||||
match g.pref.arch {
|
||||
.amd64 {
|
||||
g.gen_amd64_exit(node)
|
||||
}
|
||||
.arm64 {
|
||||
g.gen_arm64_exit(node)
|
||||
}
|
||||
else {
|
||||
verror('native exit not implemented for this architecture $g.pref.arch')
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn (mut g Gen) stmt(node ast.Stmt) {
|
||||
match node {
|
||||
ast.AssignStmt {
|
||||
|
@ -294,7 +308,8 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
}
|
||||
ast.Module {}
|
||||
ast.Return {
|
||||
g.gen_exit()
|
||||
zero := ast.IntegerLiteral{}
|
||||
g.gen_exit(zero)
|
||||
g.ret()
|
||||
}
|
||||
ast.StructDecl {}
|
||||
|
@ -311,6 +326,11 @@ fn (mut g Gen) expr(node ast.Expr) {
|
|||
ast.ArrayInit {}
|
||||
ast.BoolLiteral {}
|
||||
ast.CallExpr {
|
||||
if node.name == 'exit' {
|
||||
expr := node.args[0].expr
|
||||
g.gen_exit(expr)
|
||||
return
|
||||
}
|
||||
if node.name in ['println', 'print', 'eprintln', 'eprint'] {
|
||||
expr := node.args[0].expr
|
||||
g.gen_print_from_expr(expr, node.name in ['println', 'eprintln'])
|
||||
|
|
|
@ -101,7 +101,6 @@ pub fn (mut g Gen) generate_macho_header() {
|
|||
if g.pref.arch == .arm64 {
|
||||
g.gen_arm64_helloworld()
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
pub fn (mut g Gen) generate_macho_footer() {
|
||||
|
|
Loading…
Reference in New Issue