From 3f1e232c9b408ca98e3373951a4d7f31bf4a9507 Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 8 Mar 2022 18:52:30 +0100 Subject: [PATCH] native: support comparing two idents and avoid printing idents (#13686) --- vlib/v/gen/native/amd64.v | 28 +++++++++++++++++++++++--- vlib/v/gen/native/gen.v | 7 ++++++- vlib/v/gen/native/tests/compare.vv | 8 ++++++++ vlib/v/gen/native/tests/compare.vv.out | 1 + 4 files changed, 40 insertions(+), 4 deletions(-) create mode 100644 vlib/v/gen/native/tests/compare.vv create mode 100644 vlib/v/gen/native/tests/compare.vv.out diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index 7d6ae8277f..85e0dbc62c 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -135,6 +135,15 @@ fn (mut g Gen) cmp_reg(reg Register, reg2 Register) { g.println('cmp $reg, $reg2') } +fn (mut g Gen) cmp_var_reg(var_name string, reg Register) { + g.write8(0x48) // 83 for 1 byte? + g.write8(0x39) + g.write8(0x45) + offset := g.get_var_offset(var_name) + g.write8(0xff - offset + 1) + g.println('cmp var `$var_name`, $reg') +} + fn (mut g Gen) cmp_var(var_name string, val int) { g.write8(0x81) // 83 for 1 byte? g.write8(0x7d) @@ -1007,7 +1016,7 @@ fn (mut g Gen) assign_stmt(node ast.AssignStmt) { g.mov_reg_to_var(offset, .rax) } ast.InfixExpr { - eprintln('assign') + // eprintln('assign') // dump(node.left[i]) offset := g.get_var_offset('i') // node.left[i]) g.mov_reg_to_var(offset, native.fn_arg_registers[i]) @@ -1407,6 +1416,7 @@ fn (mut g Gen) condition(infix_expr ast.InfixExpr, neg bool) int { // 3 < 4 a0 := infix_expr.left.val.int() // a0 := (infix_expr.left as ast.IntegerLiteral).val.int() + // XXX this will not compile a1 := (infix_expr.right as ast.IntegerLiteral).val.int() // TODO. compute at compile time g.mov(.eax, a0) @@ -1507,8 +1517,20 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) { start := g.pos() match mut infix_expr.left { ast.Ident { - lit := infix_expr.right as ast.IntegerLiteral - g.cmp_var(infix_expr.left.name, lit.val.int()) + match infix_expr.right { + ast.Ident { + var_offset := g.get_var_offset(infix_expr.right.name) + g.mov_var_to_reg(.rax, var_offset) + g.cmp_var_reg(infix_expr.left.name, .rax) + } + ast.IntegerLiteral { + lit := infix_expr.right as ast.IntegerLiteral + g.cmp_var(infix_expr.left.name, lit.val.int()) + } + else { + g.n_error('unhandled expression type') + } + } match infix_expr.left.tok_kind { .lt { jump_addr = g.cjmp(.jge) diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 1f4f7b65e7..a7fd1e5dbb 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -300,8 +300,13 @@ pub fn (mut g Gen) gen_print_from_expr(expr ast.Expr, name string) { g.gen_print_reg(.rax, 3, fd) } ast.Ident { - g.expr(expr) + g.n_error('Printing idents is not yet supported in the native backend') + /* + vo := g.get_var_offset(expr.name) + g.mov_var_to_reg(.rax, vo) + //g.expr(expr) g.gen_print_reg(.rax, 3, fd) + */ } ast.IntegerLiteral { g.learel(.rax, g.allocate_string('$expr.val\n', 3, .rel32)) diff --git a/vlib/v/gen/native/tests/compare.vv b/vlib/v/gen/native/tests/compare.vv new file mode 100644 index 0000000000..5f777ab84c --- /dev/null +++ b/vlib/v/gen/native/tests/compare.vv @@ -0,0 +1,8 @@ +fn main() { + a := 123 + b := 456 + for a < b { + println('a < b') + exit(0) + } +} diff --git a/vlib/v/gen/native/tests/compare.vv.out b/vlib/v/gen/native/tests/compare.vv.out new file mode 100644 index 0000000000..ec87be7535 --- /dev/null +++ b/vlib/v/gen/native/tests/compare.vv.out @@ -0,0 +1 @@ +a < b