x64: fn calls; return;
parent
b1459ade69
commit
871c29ea5d
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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 {}
|
||||
|
|
|
@ -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 {
|
||||
|
|
Loading…
Reference in New Issue