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