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')
|
// println('call addr=$addr.hex2() rel_addr=$rel.hex2() pos=$g.buf.len')
|
||||||
g.write8(0xe8)
|
g.write8(0xe8)
|
||||||
g.write32(rel)
|
g.write32(rel)
|
||||||
// g.println('fn call')
|
g.println('call $addr')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) syscall() {
|
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) {
|
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 {
|
if g.pref.is_verbose {
|
||||||
println(term.green('\n$node.name:'))
|
println(term.green('\n$node.name:'))
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,11 +1,102 @@
|
||||||
module native
|
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:
|
mut:
|
||||||
// arm64 specific stuff for code generation
|
// arm64 specific stuff for code generation
|
||||||
g Gen
|
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')
|
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.
|
// that can be found in the LICENSE file.
|
||||||
module native
|
module native
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
mag0 = byte(0x7f)
|
mag0 = byte(0x7f)
|
||||||
mag1 = `E`
|
mag1 = `E`
|
||||||
|
@ -72,11 +70,13 @@ pub fn (mut 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()')
|
if g.pref.is_verbose {
|
||||||
|
eprintln('code_start_pos = $g.buf.len.hex()')
|
||||||
|
}
|
||||||
g.code_start_pos = i64(g.buf.len)
|
g.code_start_pos = i64(g.buf.len)
|
||||||
g.debug_pos = 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.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() {
|
pub fn (mut g Gen) generate_elf_footer() {
|
||||||
|
@ -103,12 +103,5 @@ pub fn (mut g Gen) generate_elf_footer() {
|
||||||
// +1 is for "e8"
|
// +1 is for "e8"
|
||||||
// -5 is for "e8 00 00 00 00"
|
// -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)
|
g.write32_at(g.code_start_pos + 1, int(g.main_fn_addr - g.code_start_pos) - 5)
|
||||||
// Create the binary
|
g.create_executable()
|
||||||
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')
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module native
|
module native
|
||||||
|
|
||||||
|
import os
|
||||||
import v.ast
|
import v.ast
|
||||||
import v.util
|
import v.util
|
||||||
import v.token
|
import v.token
|
||||||
|
@ -49,7 +50,7 @@ enum Size {
|
||||||
|
|
||||||
fn (g Gen) get_backend(pref &pref.Preferences) CodeGen {
|
fn (g Gen) get_backend(pref &pref.Preferences) CodeGen {
|
||||||
if pref.arch == .arm64 {
|
if pref.arch == .arm64 {
|
||||||
return Aarch64{}
|
return Arm64{}
|
||||||
}
|
}
|
||||||
return Amd64{}
|
return Amd64{}
|
||||||
}
|
}
|
||||||
|
@ -86,13 +87,28 @@ pub fn (mut g Gen) generate_header() {
|
||||||
.linux {
|
.linux {
|
||||||
g.generate_elf_header()
|
g.generate_elf_header()
|
||||||
}
|
}
|
||||||
.raw {}
|
.raw {
|
||||||
|
if g.pref.arch == .arm64 {
|
||||||
|
g.gen_arm64_helloworld()
|
||||||
|
}
|
||||||
|
}
|
||||||
else {
|
else {
|
||||||
verror('Error: only `raw`, `linux` and `macos` are supported for -os in -native')
|
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() {
|
pub fn (mut g Gen) generate_footer() {
|
||||||
match g.pref.os {
|
match g.pref.os {
|
||||||
.macos {
|
.macos {
|
||||||
|
@ -101,9 +117,10 @@ pub fn (mut g Gen) generate_footer() {
|
||||||
.linux {
|
.linux {
|
||||||
g.generate_elf_footer()
|
g.generate_elf_footer()
|
||||||
}
|
}
|
||||||
else {
|
.raw {
|
||||||
g.generate_macho_footer()
|
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) {
|
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 {
|
if node.is_range {
|
||||||
// `for x in 1..10 {`
|
// `for x in 1..10 {`
|
||||||
|
|
|
@ -3,8 +3,6 @@
|
||||||
// that can be found in the LICENSE file.
|
// that can be found in the LICENSE file.
|
||||||
module native
|
module native
|
||||||
|
|
||||||
import os
|
|
||||||
|
|
||||||
const (
|
const (
|
||||||
s_attr_some_instructions = 0x00000400
|
s_attr_some_instructions = 0x00000400
|
||||||
s_attr_pure_instructions = 0x80000000
|
s_attr_pure_instructions = 0x80000000
|
||||||
|
@ -99,33 +97,19 @@ pub fn (mut g Gen) generate_macho_header() {
|
||||||
for _ in 0 .. 12 {
|
for _ in 0 .. 12 {
|
||||||
g.write32(0)
|
g.write32(0)
|
||||||
}
|
}
|
||||||
// ADD THE CODE HERE THIS GOES INTO THE STMTS THING
|
|
||||||
// g.write32(0x77777777)
|
if g.pref.arch == .arm64 {
|
||||||
// assembly
|
g.gen_arm64_helloworld()
|
||||||
g.mov_arm(.x0, 1)
|
}
|
||||||
g.adr()
|
|
||||||
g.bl()
|
}
|
||||||
g.mov_arm(.x0, 0)
|
|
||||||
g.mov_arm(.x16, 1)
|
pub fn (mut g Gen) generate_macho_footer() {
|
||||||
g.svc()
|
|
||||||
//
|
|
||||||
g.write_string('Hello World!\n')
|
|
||||||
g.write8(0) // padding?
|
|
||||||
g.write8(0)
|
|
||||||
g.write8(0)
|
|
||||||
g.write_relocs()
|
g.write_relocs()
|
||||||
g.sym_table()
|
g.sym_table()
|
||||||
g.sym_string_table()
|
g.sym_string_table()
|
||||||
g.write8(0)
|
g.write8(0)
|
||||||
}
|
g.create_executable()
|
||||||
|
|
||||||
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')
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) sym_table_command() {
|
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() {
|
fn (mut g Gen) write_relocs() {
|
||||||
g.write32(0x8)
|
g.write32(0x8)
|
||||||
g.write32(0x2d000003)
|
g.write32(0x2d000003)
|
||||||
|
|
Loading…
Reference in New Issue