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
|
g.write64(0x1000) // p_align
|
||||||
// user code starts here at
|
// user code starts here at
|
||||||
// address: 00070 and a half
|
// address: 00070 and a half
|
||||||
|
println('code_start_pos = $g.buf.len.hex()')
|
||||||
g.code_start_pos = g.buf.len
|
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
|
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) {
|
fn (var g Gen) call(addr int) {
|
||||||
// rel := g.abs_to_rel_addr(addr)
|
// Need to calculate the difference between current position (position after the e8 call)
|
||||||
// rel := 0xffffffff - int(abs(addr - g.buf.len))-1
|
// and the function to call.
|
||||||
println('call addr=$addr rel_addr=$addr pos=$g.buf.len')
|
// +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.write8(0xe8)
|
||||||
g.write32(addr)
|
g.write32(rel)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (var g Gen) syscall() {
|
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) {
|
pub fn (var g Gen) call_fn(name string) {
|
||||||
|
println('call fn $name')
|
||||||
if !name.contains('__') {
|
if !name.contains('__') {
|
||||||
return
|
// return
|
||||||
}
|
}
|
||||||
addr := g.fn_addr[name]
|
addr := g.fn_addr[name]
|
||||||
|
if addr == 0 {
|
||||||
|
verror('fn addr of `$name` = 0')
|
||||||
|
}
|
||||||
g.call(int(addr))
|
g.call(int(addr))
|
||||||
println('call $name $addr')
|
println('call $name $addr')
|
||||||
}
|
}
|
||||||
|
@ -313,8 +320,11 @@ fn (var g Gen) stmt(node ast.Stmt) {
|
||||||
ast.ConstDecl {}
|
ast.ConstDecl {}
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
is_main := it.name == 'main'
|
is_main := it.name == 'main'
|
||||||
|
println('saving addr $it.name $g.buf.len.hex()')
|
||||||
if is_main {
|
if is_main {
|
||||||
g.save_main_fn_addr()
|
g.save_main_fn_addr()
|
||||||
|
} else {
|
||||||
|
g.register_function_address(it.name)
|
||||||
}
|
}
|
||||||
for arg in it.args {
|
for arg in it.args {
|
||||||
}
|
}
|
||||||
|
@ -324,11 +334,14 @@ fn (var g Gen) stmt(node ast.Stmt) {
|
||||||
if is_main {
|
if is_main {
|
||||||
println('end of main: gen exit')
|
println('end of main: gen exit')
|
||||||
g.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.AssignStmt {}
|
||||||
ast.ForStmt {}
|
ast.ForStmt {}
|
||||||
ast.StructDecl {}
|
ast.StructDecl {}
|
||||||
|
@ -360,17 +373,9 @@ fn (var g Gen) expr(node ast.Expr) {
|
||||||
if it.name in ['println', 'print', 'eprintln', 'eprint'] {
|
if it.name in ['println', 'print', 'eprintln', 'eprint'] {
|
||||||
expr := it.args[0].expr
|
expr := it.args[0].expr
|
||||||
g.gen_print_from_expr(expr, it.name in ['println', 'eprintln'])
|
g.gen_print_from_expr(expr, it.name in ['println', 'eprintln'])
|
||||||
|
return
|
||||||
}
|
}
|
||||||
/*
|
g.call_fn(it.name)
|
||||||
g.write('${it.name}(')
|
|
||||||
for i, expr in it.args {
|
|
||||||
g.expr(expr)
|
|
||||||
if i != it.args.len - 1 {
|
|
||||||
g.write(', ')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
g.write(')')
|
|
||||||
*/
|
|
||||||
}
|
}
|
||||||
ast.ArrayInit {}
|
ast.ArrayInit {}
|
||||||
ast.Ident {}
|
ast.Ident {}
|
||||||
|
|
|
@ -98,7 +98,6 @@ pub enum Kind {
|
||||||
key_goto
|
key_goto
|
||||||
key_if
|
key_if
|
||||||
key_import
|
key_import
|
||||||
key_import_const
|
|
||||||
key_in
|
key_in
|
||||||
key_interface
|
key_interface
|
||||||
key_is
|
key_is
|
||||||
|
@ -234,7 +233,6 @@ fn build_token_str() []string {
|
||||||
s[Kind.key_enum] = 'enum'
|
s[Kind.key_enum] = 'enum'
|
||||||
s[Kind.key_interface] = 'interface'
|
s[Kind.key_interface] = 'interface'
|
||||||
s[Kind.key_pub] = 'pub'
|
s[Kind.key_pub] = 'pub'
|
||||||
s[Kind.key_import_const] = 'import_const'
|
|
||||||
s[Kind.key_in] = 'in'
|
s[Kind.key_in] = 'in'
|
||||||
s[Kind.key_atomic] = 'atomic'
|
s[Kind.key_atomic] = 'atomic'
|
||||||
s[Kind.key_orelse] = 'or'
|
s[Kind.key_orelse] = 'or'
|
||||||
|
@ -267,7 +265,7 @@ pub fn is_key(key string) bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_decl(t Kind) 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 {
|
pub fn (t Kind) is_assign() bool {
|
||||||
|
|
Loading…
Reference in New Issue