diff --git a/vlib/v/gen/native/amd64.v b/vlib/v/gen/native/amd64.v index 89f7dbce96..fd611d541a 100644 --- a/vlib/v/gen/native/amd64.v +++ b/vlib/v/gen/native/amd64.v @@ -400,26 +400,51 @@ fn (mut c Amd64) inc_var(var Var, config VarConfig) { c.inc_var(var_object as GlobalVar, config) } Register { + c.g.n_error('Register incrementation is not supported yet') // TODO // g.inc() } } } LocalVar { - // TODO: size - c.g.write8(0x81) // 83 for 1 byte + typ := c.g.unwrap(var.typ) + mut size_str := 'UNKNOWN' offset := var.offset - config.offset is_far_var := offset > 0x80 || offset < -0x7f + match typ { + ast.i64_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx, + ast.int_literal_type_idx { + c.g.write16(0xFF48) + size_str = 'QWORD' + } + ast.i32_type_idx, ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx { + c.g.write8(0xFF) + size_str = 'DWORD' + } + ast.i16_type_idx, ast.u16_type_idx { + c.g.write8(0xFF) + size_str = 'WORD' + } + ast.i8_type_idx, ast.u8_type_idx, ast.char_type_idx { + c.g.write8(0xFE) + size_str = 'BYTE' + } + else { + ts := c.g.table.sym(typ.idx_type()) + c.g.n_error('unsupported type for inc_var ${ts.info}') + } + } + c.g.write8(if is_far_var { i32(0x85) } else { i32(0x45) }) if is_far_var { c.g.write32(i32((0xffffffff - i64(offset) + 1) % 0x100000000)) } else { c.g.write8((0xff - offset + 1) % 0x100) } - c.g.write32(1) - c.g.println('inc_var `${var.name}`') + c.g.println('inc_var ${size_str} `${var.name}`') } GlobalVar { + c.g.n_error('Global variables incrementation is not supported yet') // TODO } } @@ -643,7 +668,7 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) { c.g.write16(0x8948 + if is_extended_register { i32(4) } else { i32(0) }) size_str = 'QWORD' } - ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx { + ast.i32_type_idx, ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx { if is_extended_register { c.g.write8(0x44) } @@ -694,7 +719,7 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) { } else { c.g.write8((0xff - offset + 1) % 0x100) } - c.g.println('mov ${size_str} PTR [rbp-${int(offset).hex2()}],${reg}') + c.g.println('mov ${size_str} PTR [rbp-${int(offset).hex2()}],${reg} ; `${var.name}`') } GlobalVar { // TODO @@ -746,7 +771,7 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer i32, config VarConfig) { c.g.write16(u16(integer)) c.g.println('mov WORD PTR[rbp-${int(offset).hex2()}], ${integer}') } - ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx { + ast.i32_type_idx, ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx { c.g.write8(0xc7) c.g.write8(if is_far_var { i32(0x85) } else { i32(0x45) }) if is_far_var { @@ -832,7 +857,6 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) { typ := if config.typ == 0 { var.typ } else { config.typ } size := c.g.get_type_size(typ) is_signed := !typ.is_any_kind_of_pointer() && typ.is_signed() - instruction, size_str := match true { size == 4 && is_signed { // movsxd rax, DWORD PTR [rbp-0x8] diff --git a/vlib/v/gen/native/gen.v b/vlib/v/gen/native/gen.v index 24a488881b..c2fb0c8b8a 100644 --- a/vlib/v/gen/native/gen.v +++ b/vlib/v/gen/native/gen.v @@ -710,7 +710,8 @@ fn (mut g Gen) get_type_size(raw_type ast.Type) i32 { ast.u8_type_idx { 1 } ast.i16_type_idx { 2 } ast.u16_type_idx { 2 } - ast.int_type_idx { 4 } + ast.int_type_idx { 4 } // TODO: change when V will have changed + ast.i32_type_idx { 4 } ast.u32_type_idx { 4 } ast.i64_type_idx { 8 } ast.u64_type_idx { 8 } @@ -722,7 +723,7 @@ fn (mut g Gen) get_type_size(raw_type ast.Type) i32 { ast.float_literal_type_idx { 8 } ast.char_type_idx { 1 } ast.rune_type_idx { 4 } - else { 8 } + else { g.n_error('unknown type size ${typ}') } } } if typ.is_bool() { diff --git a/vlib/v/gen/native/stmt.c.v b/vlib/v/gen/native/stmt.c.v index 2a03a75497..aa6674492f 100644 --- a/vlib/v/gen/native/stmt.c.v +++ b/vlib/v/gen/native/stmt.c.v @@ -243,50 +243,56 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) { fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { // Work on that if node.is_range { + g.println('; for ${node.val_var} in range {') // for a in node.cond .. node.high { i := g.code_gen.allocate_var(node.val_var, 8, 0) // iterator variable + g.println('; evaluate node.cond for lower bound:') g.expr(node.cond) // outputs the lower loop bound (initial value) to the main reg main_reg := g.code_gen.main_reg() + g.println('; move the result to i') g.code_gen.mov_reg_to_var(LocalVar{i, ast.i64_type_idx, node.val_var}, main_reg) // i = node.cond // initial value start := g.pos() // label-begin: start_label := g.labels.new_label() + + g.println('; check iterator against upper loop bound') g.code_gen.mov_var_to_reg(main_reg, LocalVar{i, ast.i64_type_idx, node.val_var}) g.code_gen.push(main_reg) // put the iterator on the stack g.expr(node.high) // final value (upper bound) to the main reg g.code_gen.cmp_to_stack_top(main_reg) jump_addr := g.code_gen.cjmp(.jge) // leave loop i >= upper bound - end_label := g.labels.new_label() g.labels.patches << LabelPatch{ id: end_label pos: jump_addr } - g.println('; jump to label ${end_label}') + g.println('; jump to label ${end_label} (end_label)') g.labels.branches << BranchLabel{ name: node.label start: start_label end: end_label } + g.stmts(node.stmts) // writes the actual body of the loop g.labels.addrs[start_label] = g.pos() - g.println('; label ${start_label}') + g.println('; label ${start_label} (start_label)') g.code_gen.inc_var(LocalVar{i, ast.i64_type_idx, node.val_var}) g.labels.branches.pop() g.code_gen.jmp_back(start) // loops g.labels.addrs[end_label] = g.pos() - g.println('; label ${end_label}') + g.println('; label ${end_label} (end_label)') + g.println('; for ${node.val_var} in range }') /* - } else if node.kind == .array { + } else if node.kind == .array { } else if node.kind == .array_fixed { } else if node.kind == .map { } else if node.kind == .string { } else if node.kind == .struct { } else if it.kind in [.array, .string] || it.cond_type.has_flag(.variadic) { } else if it.kind == .map { - */ + */ } else { - g.v_error('for-in statement is not yet implemented', node.pos) + g.n_error('for-in ${node.kind} statement is not yet implemented') } } diff --git a/vlib/v/gen/native/tests/inc.vv b/vlib/v/gen/native/tests/inc.vv new file mode 100644 index 0000000000..4147936d4a --- /dev/null +++ b/vlib/v/gen/native/tests/inc.vv @@ -0,0 +1,48 @@ +fn signed_inc_test() { + mut a := i64(1) + println(a) + a++ + println(a) + mut b := i32(1) + println(b) + b++ + println(b) + mut c := i16(1) + println(c) + c++ + println(c) + mut d := i8(1) + println(d) + d++ + println(d) + mut e := int(1) + println(e) + e++ + println(e) + + // TODO: negative inc test (when negative ints will be supported) +} + +fn unsigned_inc_test() { + mut f := u64(1) + println(f) + f++ + println(f) + mut g := u32(1) + println(g) + g++ + println(g) + mut h := u16(1) + println(h) + h++ + println(h) + mut i := u8(1) + println(i) + i++ + println(i) +} + +fn main() { + signed_inc_test() + unsigned_inc_test() +} diff --git a/vlib/v/gen/native/tests/inc.vv.out b/vlib/v/gen/native/tests/inc.vv.out new file mode 100644 index 0000000000..06bce09492 --- /dev/null +++ b/vlib/v/gen/native/tests/inc.vv.out @@ -0,0 +1,18 @@ +1 +2 +1 +2 +1 +2 +1 +2 +1 +2 +1 +2 +1 +2 +1 +2 +1 +2 diff --git a/vlib/v/gen/native/tests/native_test.v b/vlib/v/gen/native/tests/native_test.v index eead96eb3e..92129a8c22 100644 --- a/vlib/v/gen/native/tests/native_test.v +++ b/vlib/v/gen/native/tests/native_test.v @@ -80,6 +80,7 @@ fn test_native() { eprintln('------------------------------------------------') eprintln('> tmperrfile: ${tmperrfile}, exists: ${os.exists(tmperrfile)}, content:') errstr := os.read_file(tmperrfile) or { '' } + eprintln('------------------------------------------------') eprintln(errstr) eprintln('------------------------------------------------') eprintln('')