x64: fn calls; return;

pull/4532/head^2
Alexander Medvednikov 2020-04-20 22:21:29 +02:00
parent b1459ade69
commit 871c29ea5d
3 changed files with 25 additions and 21 deletions

View File

@ -66,6 +66,7 @@ pub fn (var g Gen) generate_elf_header() {
g.write64(0x1000) // p_align
// user code starts here at
// address: 00070 and a half
println('code_start_pos = $g.buf.len.hex()')
g.code_start_pos = g.buf.len
g.call(PLACEHOLDER) // call main function, it's not guaranteed to be the first, we don't know its address yet
}

View File

@ -194,11 +194,14 @@ fn (var g Gen) mov64(reg Register, val i64) {
}
fn (var g Gen) call(addr int) {
// rel := g.abs_to_rel_addr(addr)
// rel := 0xffffffff - int(abs(addr - g.buf.len))-1
println('call addr=$addr rel_addr=$addr pos=$g.buf.len')
// Need to calculate the difference between current position (position after the e8 call)
// and the function to call.
// +5 is to get the posistion "e8 xx xx xx xx"
// Not sure about the -1.
rel := 0xffffffff - (g.buf.len + 5 - addr - 1)
println('call addr=$addr.hex() rel_addr=$rel.hex() pos=$g.buf.len')
g.write8(0xe8)
g.write32(addr)
g.write32(rel)
}
fn (var g Gen) syscall() {
@ -300,10 +303,14 @@ pub fn (g &Gen) writeln(s string) {
}
pub fn (var g Gen) call_fn(name string) {
println('call fn $name')
if !name.contains('__') {
return
// return
}
addr := g.fn_addr[name]
if addr == 0 {
verror('fn addr of `$name` = 0')
}
g.call(int(addr))
println('call $name $addr')
}
@ -313,8 +320,11 @@ fn (var g Gen) stmt(node ast.Stmt) {
ast.ConstDecl {}
ast.FnDecl {
is_main := it.name == 'main'
println('saving addr $it.name $g.buf.len.hex()')
if is_main {
g.save_main_fn_addr()
} else {
g.register_function_address(it.name)
}
for arg in it.args {
}
@ -324,11 +334,14 @@ fn (var g Gen) stmt(node ast.Stmt) {
if is_main {
println('end of main: gen exit')
g.gen_exit()
// g.write32(0x88888888)
// return
}
// g.ret()
g.ret()
}
ast.Return {
g.gen_exit()
g.ret()
}
ast.Return {}
ast.AssignStmt {}
ast.ForStmt {}
ast.StructDecl {}
@ -360,17 +373,9 @@ fn (var g Gen) expr(node ast.Expr) {
if it.name in ['println', 'print', 'eprintln', 'eprint'] {
expr := it.args[0].expr
g.gen_print_from_expr(expr, it.name in ['println', 'eprintln'])
return
}
/*
g.write('${it.name}(')
for i, expr in it.args {
g.expr(expr)
if i != it.args.len - 1 {
g.write(', ')
}
}
g.write(')')
*/
g.call_fn(it.name)
}
ast.ArrayInit {}
ast.Ident {}

View File

@ -98,7 +98,6 @@ pub enum Kind {
key_goto
key_if
key_import
key_import_const
key_in
key_interface
key_is
@ -234,7 +233,6 @@ fn build_token_str() []string {
s[Kind.key_enum] = 'enum'
s[Kind.key_interface] = 'interface'
s[Kind.key_pub] = 'pub'
s[Kind.key_import_const] = 'import_const'
s[Kind.key_in] = 'in'
s[Kind.key_atomic] = 'atomic'
s[Kind.key_orelse] = 'or'
@ -267,7 +265,7 @@ pub fn is_key(key string) bool {
}
pub fn is_decl(t Kind) bool {
return t in [.key_enum, .key_interface, .key_fn, .key_struct, .key_type, .key_const, .key_import_const, .key_pub, .eof]
return t in [.key_enum, .key_interface, .key_fn, .key_struct, .key_type, .key_const, .key_pub, .eof]
}
pub fn (t Kind) is_assign() bool {