native: better raw output and more arm64 cleanup
							parent
							
								
									9a3869c521
								
							
						
					
					
						commit
						9b07278930
					
				|  | @ -223,7 +223,7 @@ fn (mut g Gen) call(addr int) { | |||
| 	// println('call addr=$addr.hex2() rel_addr=$rel.hex2() pos=$g.buf.len')
 | ||||
| 	g.write8(0xe8) | ||||
| 	g.write32(rel) | ||||
| 	// g.println('fn call')
 | ||||
| 	g.println('call $addr') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) syscall() { | ||||
|  | @ -589,6 +589,10 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) { | |||
| } | ||||
| 
 | ||||
| fn (mut g Gen) fn_decl(node ast.FnDecl) { | ||||
| 	if g.pref.arch == .arm64 { | ||||
| 		g.fn_decl_arm64(node) | ||||
| 		return | ||||
| 	} | ||||
| 	if g.pref.is_verbose { | ||||
| 		println(term.green('\n$node.name:')) | ||||
| 	} | ||||
|  |  | |||
|  | @ -1,11 +1,102 @@ | |||
| module native | ||||
| 
 | ||||
| pub struct Aarch64 { | ||||
| import v.ast | ||||
| 
 | ||||
| enum Arm64Register { | ||||
| 	x0 | ||||
| 	x1 | ||||
| 	x2 | ||||
| 	x3 | ||||
| 	x4 | ||||
| 	x5 | ||||
| 	x6 | ||||
| 	x7 | ||||
| 	x8 | ||||
| 	x9 | ||||
| 	x10 | ||||
| 	x11 | ||||
| 	x12 | ||||
| 	x13 | ||||
| 	x14 | ||||
| 	x15 | ||||
| 	x16 | ||||
| } | ||||
| 
 | ||||
| pub struct Arm64 { | ||||
| mut: | ||||
| 	// arm64 specific stuff for code generation
 | ||||
| 	g Gen | ||||
| } | ||||
| 
 | ||||
| pub fn (mut x Aarch64) allocate_var(name string, size int, initial_val int) { | ||||
| pub fn (mut x Arm64) allocate_var(name string, size int, initial_val int) { | ||||
| 	eprintln('TODO: allocating var on arm64 ($name) = $size = $initial_val') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) mov_arm(reg Arm64Register, val u64) { | ||||
| 	// m := u64(0xffff)
 | ||||
| 	// x := u64(val)
 | ||||
| 	// println('========')
 | ||||
| 	// println(x & ~m)
 | ||||
| 	// println(x & ~(m << 16))
 | ||||
| 	// g.write32(0x777777)
 | ||||
| 	r := int(reg) | ||||
| 	if r == 0 && val == 1 { | ||||
| 		g.write32(0xd2800020) | ||||
| 		g.println('mov x0, 1') | ||||
| 	} else if r == 0 { | ||||
| 		g.write32(0xd2800000) | ||||
| 		g.println('mov x0, 0') | ||||
| 	} else if r == 16 { | ||||
| 		g.write32(0xd2800030) | ||||
| 		g.println('mov x16, 1') | ||||
| 	} | ||||
| 	/* | ||||
| 	if 1 ^ (x & ~m) != 0 { | ||||
| 		// println('yep')
 | ||||
| 		g.write32(int(u64(0x52800000) | u64(r) | x << 5)) | ||||
| 		g.write32(0x88888888) | ||||
| 		g.write32(int(u64(0x52800000) | u64(r) | x >> 11)) | ||||
| 	} else if 1 ^ (x & ~(m << 16)) != 0 { | ||||
| 		// g.write32(int(u64(0x52800000) | u64(r) | x >> 11))
 | ||||
| 		// println('yep2')
 | ||||
| 		// g.write32(0x52a00000 | r | val >> 11)
 | ||||
| 	} | ||||
| 	*/ | ||||
| } | ||||
| 
 | ||||
| pub fn (mut g Gen) fn_decl_arm64(node ast.FnDecl) { | ||||
| 	// TODO
 | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) gen_arm64_helloworld() { | ||||
| 	// ADD THE CODE HERE THIS GOES INTO THE STMTS THING
 | ||||
| 	// g.write32(0x77777777)
 | ||||
| 	// assembly
 | ||||
| 	g.mov_arm(.x0, 1) | ||||
| 	g.adr() | ||||
| 	g.bl() | ||||
| 	g.mov_arm(.x0, 0) | ||||
| 	g.mov_arm(.x16, 1) | ||||
| 	g.svc() | ||||
| 	//
 | ||||
| 	g.write_string('Hello World!\n') | ||||
| 	g.write8(0) // padding?
 | ||||
| 	g.write8(0) | ||||
| 	g.write8(0) | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) adr() { | ||||
| 	g.write32(0x100000a0) | ||||
| 	g.println('adr x0, 0x14') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) bl() { | ||||
| 	// g.write32(0xa9400000)
 | ||||
| 	g.write32(0x94000000) | ||||
| 	g.println('bl 0') | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) svc() { | ||||
| 	g.write32(0xd4001001) | ||||
| 	g.println('svc') | ||||
| } | ||||
|  |  | |||
|  | @ -3,8 +3,6 @@ | |||
| // that can be found in the LICENSE file.
 | ||||
| module native | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| const ( | ||||
| 	mag0        = byte(0x7f) | ||||
| 	mag1        = `E` | ||||
|  | @ -72,11 +70,13 @@ pub fn (mut 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()') | ||||
| 	if g.pref.is_verbose { | ||||
| 		eprintln('code_start_pos = $g.buf.len.hex()') | ||||
| 	} | ||||
| 	g.code_start_pos = i64(g.buf.len) | ||||
| 	g.debug_pos = g.buf.len | ||||
| 	g.call(native.placeholder) // call main function, it's not guaranteed to be the first, we don't know its address yet
 | ||||
| 	g.println('call fn main') | ||||
| 	g.println('; call fn main') | ||||
| } | ||||
| 
 | ||||
| pub fn (mut g Gen) generate_elf_footer() { | ||||
|  | @ -103,12 +103,5 @@ pub fn (mut g Gen) generate_elf_footer() { | |||
| 	// +1 is for "e8"
 | ||||
| 	// -5 is for "e8 00 00 00 00"
 | ||||
| 	g.write32_at(g.code_start_pos + 1, int(g.main_fn_addr - g.code_start_pos) - 5) | ||||
| 	// Create the binary
 | ||||
| 	mut f := os.create(g.out_name) or { panic(err) } | ||||
| 	os.chmod(g.out_name, 0o775) // make it an executable
 | ||||
| 	unsafe { f.write_ptr(g.buf.data, g.buf.len) } | ||||
| 	f.close() | ||||
| 	if g.pref.is_verbose { | ||||
| 		println('\nnative elf binary has been successfully generated') | ||||
| 	} | ||||
| 	g.create_executable() | ||||
| } | ||||
|  |  | |||
|  | @ -3,6 +3,7 @@ | |||
| // that can be found in the LICENSE file.
 | ||||
| module native | ||||
| 
 | ||||
| import os | ||||
| import v.ast | ||||
| import v.util | ||||
| import v.token | ||||
|  | @ -49,7 +50,7 @@ enum Size { | |||
| 
 | ||||
| fn (g Gen) get_backend(pref &pref.Preferences) CodeGen { | ||||
| 	if pref.arch == .arm64 { | ||||
| 		return Aarch64{} | ||||
| 		return Arm64{} | ||||
| 	} | ||||
| 	return Amd64{} | ||||
| } | ||||
|  | @ -86,13 +87,28 @@ pub fn (mut g Gen) generate_header() { | |||
| 		.linux { | ||||
| 			g.generate_elf_header() | ||||
| 		} | ||||
| 		.raw {} | ||||
| 		.raw { | ||||
| 			if g.pref.arch == .arm64 { | ||||
| 				g.gen_arm64_helloworld() | ||||
| 			} | ||||
| 		} | ||||
| 		else { | ||||
| 			verror('Error: only `raw`, `linux` and `macos` are supported for -os in -native') | ||||
| 		} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (mut g Gen) create_executable() { | ||||
| 	// Create the binary // should be .o ?
 | ||||
| 	mut f := os.create(g.out_name) or { panic(err) } | ||||
| 	os.chmod(g.out_name, 0o775) // make it executable
 | ||||
| 	unsafe { f.write_ptr(g.buf.data, g.buf.len) } | ||||
| 	f.close() | ||||
| 	if g.pref.is_verbose { | ||||
| 		println('\narm64 mach-o binary has been successfully generated') | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
| pub fn (mut g Gen) generate_footer() { | ||||
| 	match g.pref.os { | ||||
| 		.macos { | ||||
|  | @ -101,9 +117,10 @@ pub fn (mut g Gen) generate_footer() { | |||
| 		.linux { | ||||
| 			g.generate_elf_footer() | ||||
| 		} | ||||
| 		else { | ||||
| 			g.generate_macho_footer() | ||||
| 		.raw { | ||||
| 			g.create_executable() | ||||
| 		} | ||||
| 		else {} | ||||
| 	} | ||||
| } | ||||
| 
 | ||||
|  | @ -221,7 +238,7 @@ pub fn (mut g Gen) register_function_address(name string) { | |||
| } | ||||
| 
 | ||||
| fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { | ||||
| 	eprintln('for-in statement is not yet implemented') | ||||
| 	verror('for-in statement is not yet implemented') | ||||
| 	/* | ||||
| 	if node.is_range { | ||||
| 		// `for x in 1..10 {`
 | ||||
|  |  | |||
|  | @ -3,8 +3,6 @@ | |||
| // that can be found in the LICENSE file.
 | ||||
| module native | ||||
| 
 | ||||
| import os | ||||
| 
 | ||||
| const ( | ||||
| 	s_attr_some_instructions = 0x00000400 | ||||
| 	s_attr_pure_instructions = 0x80000000 | ||||
|  | @ -99,33 +97,19 @@ pub fn (mut g Gen) generate_macho_header() { | |||
| 	for _ in 0 .. 12 { | ||||
| 		g.write32(0) | ||||
| 	} | ||||
| 	// ADD THE CODE HERE THIS GOES INTO THE STMTS THING
 | ||||
| 	// g.write32(0x77777777)
 | ||||
| 	// assembly
 | ||||
| 	g.mov_arm(.x0, 1) | ||||
| 	g.adr() | ||||
| 	g.bl() | ||||
| 	g.mov_arm(.x0, 0) | ||||
| 	g.mov_arm(.x16, 1) | ||||
| 	g.svc() | ||||
| 	//
 | ||||
| 	g.write_string('Hello World!\n') | ||||
| 	g.write8(0) // padding?
 | ||||
| 	g.write8(0) | ||||
| 	g.write8(0) | ||||
| 
 | ||||
| 	if g.pref.arch == .arm64 { | ||||
| 		g.gen_arm64_helloworld() | ||||
| 	} | ||||
| 
 | ||||
| } | ||||
| 
 | ||||
| pub fn (mut g Gen) generate_macho_footer() { | ||||
| 	g.write_relocs() | ||||
| 	g.sym_table() | ||||
| 	g.sym_string_table() | ||||
| 	g.write8(0) | ||||
| } | ||||
| 
 | ||||
| pub fn (mut g Gen) generate_macho_footer() { | ||||
| 	// Create the binary // should be .o ?
 | ||||
| 	mut f := os.create(g.out_name) or { panic(err) } | ||||
| 	os.chmod(g.out_name, 0o775) // make it executable
 | ||||
| 	unsafe { f.write_ptr(g.buf.data, g.buf.len) } | ||||
| 	f.close() | ||||
| 	// println('\narm64 mach-o binary has been successfully generated')
 | ||||
| 	g.create_executable() | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) sym_table_command() { | ||||
|  | @ -184,68 +168,6 @@ pub fn (mut g Gen) zeroes(n int) { | |||
| 	} | ||||
| } | ||||
| 
 | ||||
| enum Register2 { | ||||
| 	x0 | ||||
| 	x1 | ||||
| 	x2 | ||||
| 	x3 | ||||
| 	x4 | ||||
| 	x5 | ||||
| 	x6 | ||||
| 	x7 | ||||
| 	x8 | ||||
| 	x9 | ||||
| 	x10 | ||||
| 	x11 | ||||
| 	x12 | ||||
| 	x13 | ||||
| 	x14 | ||||
| 	x15 | ||||
| 	x16 | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) mov_arm(reg Register2, val u64) { | ||||
| 	// m := u64(0xffff)
 | ||||
| 	// x := u64(val)
 | ||||
| 	// println('========')
 | ||||
| 	// println(x & ~m)
 | ||||
| 	// println(x & ~(m << 16))
 | ||||
| 	// g.write32(0x777777)
 | ||||
| 	r := int(reg) | ||||
| 	if r == 0 && val == 1 { | ||||
| 		g.write32(0xd2800020) | ||||
| 	} else if r == 0 { | ||||
| 		g.write32(0xd2800000) | ||||
| 	} else if r == 16 { | ||||
| 		g.write32(0xd2800030) | ||||
| 	} | ||||
| 	/* | ||||
| 	if 1 ^ (x & ~m) != 0 { | ||||
| 		// println('yep')
 | ||||
| 		g.write32(int(u64(0x52800000) | u64(r) | x << 5)) | ||||
| 		g.write32(0x88888888) | ||||
| 		g.write32(int(u64(0x52800000) | u64(r) | x >> 11)) | ||||
| 	} else if 1 ^ (x & ~(m << 16)) != 0 { | ||||
| 		// g.write32(int(u64(0x52800000) | u64(r) | x >> 11))
 | ||||
| 		// println('yep2')
 | ||||
| 		// g.write32(0x52a00000 | r | val >> 11)
 | ||||
| 	} | ||||
| 	*/ | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) adr() { | ||||
| 	g.write32(0x100000a0) | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) bl() { | ||||
| 	// g.write32(0xa9400000)
 | ||||
| 	g.write32(0x94000000) | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) svc() { | ||||
| 	g.write32(0xd4001001) | ||||
| } | ||||
| 
 | ||||
| fn (mut g Gen) write_relocs() { | ||||
| 	g.write32(0x8) | ||||
| 	g.write32(0x2d000003) | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue