builder: add -lpthread; x64: a+b, a-b
parent
947e8922f2
commit
1d28d45c5c
|
@ -321,6 +321,10 @@ pub fn (nn int) hex() string {
|
||||||
return u32(nn).hex()
|
return u32(nn).hex()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn (n int) hex2() string {
|
||||||
|
return '0x' + n.hex()
|
||||||
|
}
|
||||||
|
|
||||||
pub fn (nn u64) hex() string {
|
pub fn (nn u64) hex() string {
|
||||||
if nn == 0 {
|
if nn == 0 {
|
||||||
return '0'
|
return '0'
|
||||||
|
|
|
@ -516,6 +516,7 @@ fn (mut c Builder) cc_linux_cross() {
|
||||||
//'SYSROOT/lib/x86_64-linux-gnu/libcrypto.so'
|
//'SYSROOT/lib/x86_64-linux-gnu/libcrypto.so'
|
||||||
'-lcrypto'
|
'-lcrypto'
|
||||||
'-lssl'
|
'-lssl'
|
||||||
|
'-lpthread'
|
||||||
//'-dynamic-linker /usr/lib/x86_64-linux-gnu/libcrypto.so'
|
//'-dynamic-linker /usr/lib/x86_64-linux-gnu/libcrypto.so'
|
||||||
//'SYSROOT/lib/x86_64-linux-gnu/libssl.a'
|
//'SYSROOT/lib/x86_64-linux-gnu/libssl.a'
|
||||||
'$sysroot/crtn.o'
|
'$sysroot/crtn.o'
|
||||||
|
|
|
@ -308,10 +308,11 @@ fn (mut g Gen) mov64(reg Register, val i64) {
|
||||||
g.println('mov64 $reg, $val')
|
g.println('mov64 $reg, $val')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) mov_from_reg(var_offset int, reg Register) {
|
fn (mut g Gen) mov_reg_to_rbp(var_offset int, reg Register) {
|
||||||
// 89 7d fc mov DWORD PTR [rbp-0x4],edi
|
// 89 7d fc mov DWORD PTR [rbp-0x4],edi
|
||||||
g.write8(0x89)
|
g.write8(0x89)
|
||||||
match reg {
|
match reg {
|
||||||
|
.eax, .rax { g.write8(0x45) }
|
||||||
.edi, .rdi { g.write8(0x7d) }
|
.edi, .rdi { g.write8(0x7d) }
|
||||||
.rsi { g.write8(0x75) }
|
.rsi { g.write8(0x75) }
|
||||||
.rdx { g.write8(0x55) }
|
.rdx { g.write8(0x55) }
|
||||||
|
@ -319,21 +320,22 @@ fn (mut g Gen) mov_from_reg(var_offset int, reg Register) {
|
||||||
else { verror('mov_from_reg $reg') }
|
else { verror('mov_from_reg $reg') }
|
||||||
}
|
}
|
||||||
g.write8(0xff - var_offset + 1)
|
g.write8(0xff - var_offset + 1)
|
||||||
g.println('mov DWORD PTR[rbp-$var_offset.hex()],$reg')
|
g.println('mov DWORD PTR[rbp-$var_offset.hex2()],$reg')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) mov_rbp_offset(reg Register, var_offset int) {
|
fn (mut g Gen) mov_var_to_reg(reg Register, var_offset int) {
|
||||||
// 8b 7d f8 mov edi,DWORD PTR [rbp-0x8]
|
// 8b 7d f8 mov edi,DWORD PTR [rbp-0x8]
|
||||||
g.write8(0x8b)
|
g.write8(0x8b)
|
||||||
match reg {
|
match reg {
|
||||||
|
.eax, .rax { g.write8(0x45) }
|
||||||
.edi, .rdi { g.write8(0x7d) }
|
.edi, .rdi { g.write8(0x7d) }
|
||||||
.rsi { g.write8(0x75) }
|
.rsi { g.write8(0x75) }
|
||||||
.rdx { g.write8(0x55) }
|
.rdx { g.write8(0x55) }
|
||||||
.rcx { g.write8(0x4d) }
|
.rcx { g.write8(0x4d) }
|
||||||
else { verror('mov_rbp_offset $reg') }
|
else { verror('mov_var_to_reg $reg') }
|
||||||
}
|
}
|
||||||
g.write8(0xff - var_offset + 1)
|
g.write8(0xff - var_offset + 1)
|
||||||
g.println('mov $reg,DWORD PTR[rbp-$var_offset]')
|
g.println('mov $reg,DWORD PTR[rbp-$var_offset.hex2()]')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) call(addr int) {
|
fn (mut g Gen) call(addr int) {
|
||||||
|
@ -342,7 +344,7 @@ fn (mut g Gen) call(addr int) {
|
||||||
// +5 is to get the posistion "e8 xx xx xx xx"
|
// +5 is to get the posistion "e8 xx xx xx xx"
|
||||||
// Not sure about the -1.
|
// Not sure about the -1.
|
||||||
rel := 0xffffffff - (g.buf.len + 5 - addr - 1)
|
rel := 0xffffffff - (g.buf.len + 5 - addr - 1)
|
||||||
// println('call addr=$addr.hex() rel_addr=$rel.hex() 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('fn call')
|
||||||
|
@ -387,7 +389,7 @@ pub fn (mut g Gen) sub32(reg Register, val int) {
|
||||||
g.write8(0x81)
|
g.write8(0x81)
|
||||||
g.write8(0xe8 + reg) // TODO rax is different?
|
g.write8(0xe8 + reg) // TODO rax is different?
|
||||||
g.write32(val)
|
g.write32(val)
|
||||||
g.println('sub32 $reg,0x$val.hex()')
|
g.println('sub32 $reg,$val.hex2()')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) sub8(reg Register, val int) {
|
pub fn (mut g Gen) sub8(reg Register, val int) {
|
||||||
|
@ -395,7 +397,7 @@ pub fn (mut g Gen) sub8(reg Register, val int) {
|
||||||
g.write8(0x83)
|
g.write8(0x83)
|
||||||
g.write8(0xe8 + reg) // TODO rax is different?
|
g.write8(0xe8 + reg) // TODO rax is different?
|
||||||
g.write8(val)
|
g.write8(val)
|
||||||
g.println('sub8 $reg,0x$val.hex()')
|
g.println('sub8 $reg,$val.hex2()')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) add(reg Register, val int) {
|
pub fn (mut g Gen) add(reg Register, val int) {
|
||||||
|
@ -403,7 +405,7 @@ pub fn (mut g Gen) add(reg Register, val int) {
|
||||||
g.write8(0x81)
|
g.write8(0x81)
|
||||||
g.write8(0xe8 + reg) // TODO rax is different?
|
g.write8(0xe8 + reg) // TODO rax is different?
|
||||||
g.write32(val)
|
g.write32(val)
|
||||||
g.println('add $reg,0x$val.hex()')
|
g.println('add $reg,$val.hex2()')
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (mut g Gen) add8(reg Register, val int) {
|
pub fn (mut g Gen) add8(reg Register, val int) {
|
||||||
|
@ -412,7 +414,27 @@ pub fn (mut g Gen) add8(reg Register, val int) {
|
||||||
// g.write8(0xe8 + reg) // TODO rax is different?
|
// g.write8(0xe8 + reg) // TODO rax is different?
|
||||||
g.write8(0xc4)
|
g.write8(0xc4)
|
||||||
g.write8(val)
|
g.write8(val)
|
||||||
g.println('add8 $reg,0x$val.hex()')
|
g.println('add8 $reg,$val.hex2()')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) add8_var(reg Register, var_offset int) {
|
||||||
|
g.write8(0x03)
|
||||||
|
match reg {
|
||||||
|
.eax, .rax { g.write8(0x45) }
|
||||||
|
else { verror('add8_var') }
|
||||||
|
}
|
||||||
|
g.write8(0xff - var_offset + 1)
|
||||||
|
g.println('add8 $reg,DWORD PTR[rbp-$var_offset.hex2()]')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) sub8_var(reg Register, var_offset int) {
|
||||||
|
g.write8(0x2b)
|
||||||
|
match reg {
|
||||||
|
.eax, .rax { g.write8(0x45) }
|
||||||
|
else { verror('sub8_var') }
|
||||||
|
}
|
||||||
|
g.write8(0xff - var_offset + 1)
|
||||||
|
g.println('sub8 $reg,DWORD PTR[rbp-$var_offset.hex2()]')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) leave() {
|
fn (mut g Gen) leave() {
|
||||||
|
@ -542,10 +564,10 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) {
|
||||||
}
|
}
|
||||||
ast.Ident {
|
ast.Ident {
|
||||||
// `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]`
|
// `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]`
|
||||||
offset := g.get_var_offset(it.name)
|
var_offset := g.get_var_offset(it.name)
|
||||||
println('i=$i fn name= $name offset=$offset')
|
println('i=$i fn name= $name offset=$var_offset')
|
||||||
println(int(fn_arg_registers[i]))
|
println(int(fn_arg_registers[i]))
|
||||||
g.mov_rbp_offset(fn_arg_registers[i], offset)
|
g.mov_var_to_reg(fn_arg_registers[i], var_offset)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
verror('unhandled call_fn node: ' + typeof(expr))
|
verror('unhandled call_fn node: ' + typeof(expr))
|
||||||
|
@ -608,6 +630,7 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
// println('cgen expr()')
|
// println('cgen expr()')
|
||||||
match node {
|
match node {
|
||||||
ast.ArrayInit {}
|
ast.ArrayInit {}
|
||||||
|
ast.BoolLiteral {}
|
||||||
ast.CallExpr {
|
ast.CallExpr {
|
||||||
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
|
||||||
|
@ -628,7 +651,6 @@ fn (mut g Gen) expr(node ast.Expr) {
|
||||||
}
|
}
|
||||||
ast.StringLiteral {}
|
ast.StringLiteral {}
|
||||||
ast.StructInit {}
|
ast.StructInit {}
|
||||||
ast.BoolLiteral {}
|
|
||||||
else {
|
else {
|
||||||
println(term.red('x64.expr(): unhandled node: ' + typeof(node)))
|
println(term.red('x64.expr(): unhandled node: ' + typeof(node)))
|
||||||
}
|
}
|
||||||
|
@ -667,7 +689,7 @@ fn (mut g Gen) allocate_var(name string, size, initial_val int) {
|
||||||
// Generate the value assigned to the variable
|
// Generate the value assigned to the variable
|
||||||
g.write32(initial_val)
|
g.write32(initial_val)
|
||||||
// println('allocate_var(size=$size, initial_val=$initial_val)')
|
// println('allocate_var(size=$size, initial_val=$initial_val)')
|
||||||
g.println('mov DWORD [rbp-0x$n],$initial_val (Allocate var `$name`)')
|
g.println('mov DWORD [rbp-$n.hex2()],$initial_val (Allocate var `$name`)')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
||||||
|
@ -684,6 +706,10 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
||||||
ast.InfixExpr {
|
ast.InfixExpr {
|
||||||
g.infix_expr(it)
|
g.infix_expr(it)
|
||||||
g.allocate_var(name, 4, 0)
|
g.allocate_var(name, 4, 0)
|
||||||
|
// `mov DWORD PTR [rbp-0x8],eax`
|
||||||
|
offset := g.get_var_offset(name)
|
||||||
|
println('ASS $name offset=$offset.hex2()')
|
||||||
|
g.mov_reg_to_rbp(offset, .eax)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
g.error_with_pos('assign_stmt unhandled expr: ' + typeof(right), right.position())
|
g.error_with_pos('assign_stmt unhandled expr: ' + typeof(right), right.position())
|
||||||
|
@ -695,10 +721,22 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) {
|
||||||
|
|
||||||
fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
fn (mut g Gen) infix_expr(node ast.InfixExpr) {
|
||||||
println('infix expr op=$node.op')
|
println('infix expr op=$node.op')
|
||||||
match node.op {
|
if node.left is ast.InfixExpr {
|
||||||
.plus {}
|
verror('only simple expressions are supported right now (not more than 2 operands)')
|
||||||
|
}
|
||||||
|
match node.left {
|
||||||
|
ast.Ident { g.mov_var_to_reg(.eax, g.get_var_offset(it.name)) }
|
||||||
else {}
|
else {}
|
||||||
}
|
}
|
||||||
|
if node.right is ast.Ident {
|
||||||
|
ident := node.right as ast.Ident
|
||||||
|
var_offset := g.get_var_offset(ident.name)
|
||||||
|
match node.op {
|
||||||
|
.plus { g.add8_var(.eax, var_offset) }
|
||||||
|
.minus { g.sub8_var(.eax, var_offset) }
|
||||||
|
else {}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut g Gen) if_expr(node ast.IfExpr) {
|
fn (mut g Gen) if_expr(node ast.IfExpr) {
|
||||||
|
@ -751,7 +789,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
||||||
println(term.green('\n$node.name:'))
|
println(term.green('\n$node.name:'))
|
||||||
g.stack_var_pos = 0
|
g.stack_var_pos = 0
|
||||||
is_main := node.name == 'main'
|
is_main := node.name == 'main'
|
||||||
// println('saving addr $node.name $g.buf.len.hex()')
|
// println('saving addr $node.name $g.buf.len.hex2()')
|
||||||
if is_main {
|
if is_main {
|
||||||
g.save_main_fn_addr()
|
g.save_main_fn_addr()
|
||||||
} else {
|
} else {
|
||||||
|
@ -773,7 +811,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) {
|
||||||
g.allocate_var(name, 4, 0)
|
g.allocate_var(name, 4, 0)
|
||||||
// `mov DWORD PTR [rbp-0x4],edi`
|
// `mov DWORD PTR [rbp-0x4],edi`
|
||||||
offset += 4
|
offset += 4
|
||||||
g.mov_from_reg(offset, fn_arg_registers[i])
|
g.mov_reg_to_rbp(offset, fn_arg_registers[i])
|
||||||
}
|
}
|
||||||
//
|
//
|
||||||
g.stmts(node.stmts)
|
g.stmts(node.stmts)
|
||||||
|
|
|
@ -0,0 +1,30 @@
|
||||||
|
fn print_number(n int) {
|
||||||
|
if n == 0 { println('0') }
|
||||||
|
if n == 1 { println('1') }
|
||||||
|
if n == 2 { println('2') }
|
||||||
|
if n == 3 { println('3') }
|
||||||
|
if n == 4 { println('4') }
|
||||||
|
if n == 5 { println('5') }
|
||||||
|
if n == 6 { println('6') }
|
||||||
|
if n == 7 { println('7') }
|
||||||
|
if n == 8 { println('8') }
|
||||||
|
if n == 9 { println('9') }
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_add() {
|
||||||
|
println('test_add()')
|
||||||
|
x := 2
|
||||||
|
y := 3
|
||||||
|
z := x + y
|
||||||
|
q := y - x
|
||||||
|
print_number(x)
|
||||||
|
print_number(y)
|
||||||
|
print_number(z)
|
||||||
|
print_number(q)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
println('start')
|
||||||
|
test_add()
|
||||||
|
println('end')
|
||||||
|
}
|
|
@ -0,0 +1,8 @@
|
||||||
|
start
|
||||||
|
test_add()
|
||||||
|
2
|
||||||
|
3
|
||||||
|
5
|
||||||
|
1
|
||||||
|
end
|
||||||
|
|
|
@ -6,34 +6,9 @@ fn print_123() {
|
||||||
println('123')
|
println('123')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn print_number(n int) {
|
|
||||||
if n == 1 { println('1') }
|
|
||||||
if n == 2 { println('2') }
|
|
||||||
if n == 3 { println('3') }
|
|
||||||
if n == 4 { println('4') }
|
|
||||||
if n == 5 { println('5') }
|
|
||||||
if n == 6 { println('6') }
|
|
||||||
if n == 7 { println('7') }
|
|
||||||
if n == 8 { println('8') }
|
|
||||||
if n == 9 { println('9') }
|
|
||||||
}
|
|
||||||
|
|
||||||
fn test_add() {
|
|
||||||
println('test_add()')
|
|
||||||
x := 2
|
|
||||||
y := 3
|
|
||||||
//z := x + y
|
|
||||||
print_number(x)
|
|
||||||
print_number(y)
|
|
||||||
//print_number(z)
|
|
||||||
print_number(x)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('start')
|
println('start')
|
||||||
print_greeting()
|
print_greeting()
|
||||||
print_123()
|
print_123()
|
||||||
test_add()
|
|
||||||
println('end')
|
println('end')
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,4 @@
|
||||||
start
|
start
|
||||||
hello from x64
|
hello from x64
|
||||||
123
|
123
|
||||||
test_add()
|
|
||||||
2
|
|
||||||
3
|
|
||||||
2
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue