diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index d168dc86ca..a4a32c35ef 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -1,6 +1,5 @@ module native -import term import v.ast import v.token @@ -153,8 +152,6 @@ fn (mut g Gen) cjmp(op JumpOp) int { return int(pos) } -// Returns the position of the address to jump to (set later). - fn (mut g Gen) jmp(addr int) { g.write8(0xe9) g.write32(addr) // 0xffffff @@ -426,10 +423,6 @@ pub fn (mut g Gen) gen_loop_end(to int, label int) { g.jl(label) } -pub fn (mut g Gen) save_main_fn_addr() { - g.main_fn_addr = i64(g.buf.len) -} - pub fn (mut g Gen) allocate_string(s string, opsize int) int { g.strings << s str_pos := g.buf.len + opsize @@ -1373,39 +1366,13 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) { g.println('jmp after for') } -fn (mut g Gen) fn_decl(node ast.FnDecl) { - if g.pref.is_verbose { - println(term.green('\n$node.name:')) - } - // if g.is_method - if node.is_deprecated { - eprintln('fn_decl: $node.name is deprecated') - } - if node.is_builtin { - eprintln('fn_decl: $node.name is builtin') - } - g.stack_var_pos = 0 - is_main := node.name == 'main.main' - // println('saving addr $node.name $g.buf.len.hex2()') - if is_main { - g.save_main_fn_addr() - } else { - g.register_function_address(node.name) - } - if g.pref.arch == .arm64 { - g.fn_decl_arm64(node) - return - } - +fn (mut g Gen) fn_decl_amd64(node ast.FnDecl) { g.push(.rbp) g.mov_rbp_rsp() locals_count := node.scope.objects.len + node.params.len g.stackframe_size = (locals_count * 8) + 0x10 g.sub8(.rsp, g.stackframe_size) - if node.params.len > 0 { - // g.mov(.r12, 0x77777777) - } // Copy values from registers to local vars (calling convention) mut offset := 0 for i in 0 .. node.params.len { @@ -1418,6 +1385,7 @@ fn (mut g Gen) fn_decl(node ast.FnDecl) { } // g.stmts(node.stmts) + is_main := node.name == 'main.main' if is_main { // println('end of main: gen exit') zero := ast.IntegerLiteral{} @@ -1442,8 +1410,7 @@ pub fn (mut g Gen) allocate_array(name string, size int, items int) int { } pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) int { - // `a := 3` => - // `move DWORD [rbp-0x4],0x3` + // `a := 3` => `mov DWORD [rbp-0x4],0x3` match size { 1 { // BYTE @@ -1473,6 +1440,6 @@ pub fn (mut g Gen) allocate_var(name string, size int, initial_val int) 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-$n.hex2()],$initial_val (Allocate var `$name`)') + g.println('mov [rbp-$n.hex2()], $initial_val (Allocate var `$name`)') return g.stack_var_pos } diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 72ee00dfd1..7d153c4524 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -44,10 +44,9 @@ mut: errors []errors.Error warnings []errors.Warning syms []Symbol - // UNUSED relocs []Reloc - size_pos []int - nlines int - callpatches []CallPatch + size_pos []int + nlines int + callpatches []CallPatch } struct CallPatch { @@ -99,9 +98,11 @@ pub fn gen(files []&ast.File, table &ast.Table, out_name string, pref &pref.Pref g.code_gen.g = g g.generate_header() for file in files { + /* if file.warnings.len > 0 { eprintln('warning: ${file.warnings[0]}') } + */ if file.errors.len > 0 { g.n_error(file.errors[0].str()) } @@ -307,6 +308,9 @@ pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, name string) { } } ast.None {} + ast.EmptyExpr { + g.n_error('unhandled EmptyExpr') + } ast.PostfixExpr {} ast.PrefixExpr {} ast.SelectorExpr { @@ -323,6 +327,7 @@ g.expr dump(expr) g.v_error('struct.field selector not yet implemented for this backend', expr.pos) } + ast.NodeError {} /* ast.AnonFn {} ast.ArrayDecompose {} @@ -339,45 +344,72 @@ g.expr ast.ComptimeSelector {} ast.ConcatExpr {} ast.DumpExpr {} - ast.EmptyExpr {} ast.EnumVal {} - ast.FloatLiteral {} ast.GoExpr {} - ast.IfExpr {} ast.IfGuardExpr {} ast.IndexExpr {} ast.InfixExpr {} ast.IsRefType {} - ast.Likely {} - ast.LockExpr {} ast.MapInit {} ast.MatchExpr {} - ast.NodeError {} ast.OrExpr {} ast.ParExpr {} ast.RangeExpr {} ast.SelectExpr {} ast.SqlExpr {} - ast.StringInterLiteral {} - ast.StructInit {} ast.TypeNode {} ast.TypeOf {} - ast.UnsafeExpr {} */ + ast.LockExpr { + // passthru + eprintln('Warning: locks not implemented yet in the native backend') + g.expr(expr) + } + ast.Likely { + // passthru + g.expr(expr) + } + ast.UnsafeExpr { + // passthru + g.expr(expr) + } + ast.StringInterLiteral { + g.n_error('Interlaced string literals are not yet supported in the native backend.') // , expr.pos) + } else { dump(typeof(expr).name) dump(expr) // g.v_error('expected string as argument for print', expr.pos) g.n_error('expected string as argument for print') // , expr.pos) - // g.warning('expected string as argument for print') } } } +fn (mut g Gen) fn_decl(node ast.FnDecl) { + if g.pref.is_verbose { + println(term.green('\n$node.name:')) + } + if node.is_deprecated { + g.warning('fn_decl: $node.name is deprecated', node.pos) + } + if node.is_builtin { + g.warning('fn_decl: $node.name is builtin', node.pos) + } + g.stack_var_pos = 0 + g.register_function_address(node.name) + if g.pref.arch == .arm64 { + g.fn_decl_arm64(node) + } else { + g.fn_decl_amd64(node) + } +} + pub fn (mut g Gen) register_function_address(name string) { - addr := g.pos() - // eprintln('register function $name = $addr') - g.fn_addr[name] = addr + if name == 'main.main' { + g.main_fn_addr = i64(g.buf.len) + } else { + g.fn_addr[name] = g.pos() + } } fn (mut g Gen) println(comment string) { @@ -604,7 +636,7 @@ fn (mut g Gen) expr(node ast.Expr) { ast.StringLiteral {} ast.StructInit {} ast.GoExpr { - g.v_error('native backend doesnt support threads yet', node.pos) // token.Position{}) + g.v_error('native backend doesnt support threads yet', node.pos) } else { g.n_error('expr: unhandled node type: $node.type_name()')