diff --git a/vlib/builtin/int.v b/vlib/builtin/int.v index 83a9e12ee0..718f47de03 100644 --- a/vlib/builtin/int.v +++ b/vlib/builtin/int.v @@ -321,6 +321,10 @@ pub fn (nn int) hex() string { return u32(nn).hex() } +pub fn (n int) hex2() string { + return '0x' + n.hex() +} + pub fn (nn u64) hex() string { if nn == 0 { return '0' diff --git a/vlib/v/builder/cc.v b/vlib/v/builder/cc.v index 113ff0a80b..6a09accc6a 100644 --- a/vlib/v/builder/cc.v +++ b/vlib/v/builder/cc.v @@ -516,6 +516,7 @@ fn (mut c Builder) cc_linux_cross() { //'SYSROOT/lib/x86_64-linux-gnu/libcrypto.so' '-lcrypto' '-lssl' + '-lpthread' //'-dynamic-linker /usr/lib/x86_64-linux-gnu/libcrypto.so' //'SYSROOT/lib/x86_64-linux-gnu/libssl.a' '$sysroot/crtn.o' diff --git a/vlib/v/gen/x64/gen.v b/vlib/v/gen/x64/gen.v index 5414b17f24..ad239a3cbf 100644 --- a/vlib/v/gen/x64/gen.v +++ b/vlib/v/gen/x64/gen.v @@ -308,10 +308,11 @@ fn (mut g Gen) mov64(reg Register, val i64) { g.println('mov64 $reg, $val') } -fn (mut g Gen) mov_from_reg(var_offset int, reg Register) { - // 89 7d fc mov DWORD PTR [rbp-0x4],edi +fn (mut g Gen) mov_reg_to_rbp(var_offset int, reg Register) { + // 89 7d fc mov DWORD PTR [rbp-0x4],edi g.write8(0x89) match reg { + .eax, .rax { g.write8(0x45) } .edi, .rdi { g.write8(0x7d) } .rsi { g.write8(0x75) } .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') } } 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] g.write8(0x8b) match reg { + .eax, .rax { g.write8(0x45) } .edi, .rdi { g.write8(0x7d) } .rsi { g.write8(0x75) } .rdx { g.write8(0x55) } .rcx { g.write8(0x4d) } - else { verror('mov_rbp_offset $reg') } + else { verror('mov_var_to_reg $reg') } } 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) { @@ -342,7 +344,7 @@ fn (mut g Gen) call(addr int) { // +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') + // println('call addr=$addr.hex2() rel_addr=$rel.hex2() pos=$g.buf.len') g.write8(0xe8) g.write32(rel) // g.println('fn call') @@ -387,7 +389,7 @@ pub fn (mut g Gen) sub32(reg Register, val int) { g.write8(0x81) g.write8(0xe8 + reg) // TODO rax is different? 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) { @@ -395,7 +397,7 @@ pub fn (mut g Gen) sub8(reg Register, val int) { g.write8(0x83) g.write8(0xe8 + reg) // TODO rax is different? 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) { @@ -403,7 +405,7 @@ pub fn (mut g Gen) add(reg Register, val int) { g.write8(0x81) g.write8(0xe8 + reg) // TODO rax is different? 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) { @@ -412,7 +414,27 @@ pub fn (mut g Gen) add8(reg Register, val int) { // g.write8(0xe8 + reg) // TODO rax is different? g.write8(0xc4) 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() { @@ -542,10 +564,10 @@ pub fn (mut g Gen) call_fn(node ast.CallExpr) { } ast.Ident { // `foo(x)` => `mov edi,DWORD PTR [rbp-0x8]` - offset := g.get_var_offset(it.name) - println('i=$i fn name= $name offset=$offset') + var_offset := g.get_var_offset(it.name) + println('i=$i fn name= $name offset=$var_offset') 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 { verror('unhandled call_fn node: ' + typeof(expr)) @@ -608,6 +630,7 @@ fn (mut g Gen) expr(node ast.Expr) { // println('cgen expr()') match node { ast.ArrayInit {} + ast.BoolLiteral {} ast.CallExpr { if it.name in ['println', 'print', 'eprintln', 'eprint'] { expr := it.args[0].expr @@ -628,7 +651,6 @@ fn (mut g Gen) expr(node ast.Expr) { } ast.StringLiteral {} ast.StructInit {} - ast.BoolLiteral {} else { 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 g.write32(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) { @@ -684,6 +706,10 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { ast.InfixExpr { g.infix_expr(it) 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 { 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) { println('infix expr op=$node.op') - match node.op { - .plus {} + if node.left is ast.InfixExpr { + 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 {} } + 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) { @@ -751,7 +789,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { println(term.green('\n$node.name:')) g.stack_var_pos = 0 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 { g.save_main_fn_addr() } else { @@ -773,7 +811,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { g.allocate_var(name, 4, 0) // `mov DWORD PTR [rbp-0x4],edi` 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) diff --git a/vlib/v/gen/x64/tests/expressions.vv b/vlib/v/gen/x64/tests/expressions.vv new file mode 100644 index 0000000000..f82c347017 --- /dev/null +++ b/vlib/v/gen/x64/tests/expressions.vv @@ -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') +} diff --git a/vlib/v/gen/x64/tests/expressions.vv.out b/vlib/v/gen/x64/tests/expressions.vv.out new file mode 100644 index 0000000000..431a9330e6 --- /dev/null +++ b/vlib/v/gen/x64/tests/expressions.vv.out @@ -0,0 +1,8 @@ +start +test_add() +2 +3 +5 +1 +end + diff --git a/vlib/v/gen/x64/tests/simple_fn_calls.vv b/vlib/v/gen/x64/tests/simple_fn_calls.vv index 3f58472757..b5830e445c 100644 --- a/vlib/v/gen/x64/tests/simple_fn_calls.vv +++ b/vlib/v/gen/x64/tests/simple_fn_calls.vv @@ -6,34 +6,9 @@ fn print_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() { println('start') print_greeting() print_123() - test_add() println('end') } diff --git a/vlib/v/gen/x64/tests/simple_fn_calls.vv.out b/vlib/v/gen/x64/tests/simple_fn_calls.vv.out index 0b2689dd8d..761cb66834 100644 --- a/vlib/v/gen/x64/tests/simple_fn_calls.vv.out +++ b/vlib/v/gen/x64/tests/simple_fn_calls.vv.out @@ -1,8 +1,4 @@ start hello from x64 123 -test_add() -2 -3 -2 end