Skip to content

Commit dbc96b2

Browse files
authored
native: fix inc and improve support for i32 (#23753)
1 parent f2672b1 commit dbc96b2

File tree

6 files changed

+115
-17
lines changed

6 files changed

+115
-17
lines changed

vlib/v/gen/native/amd64.v

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -400,26 +400,51 @@ fn (mut c Amd64) inc_var(var Var, config VarConfig) {
400400
c.inc_var(var_object as GlobalVar, config)
401401
}
402402
Register {
403+
c.g.n_error('Register incrementation is not supported yet')
403404
// TODO
404405
// g.inc()
405406
}
406407
}
407408
}
408409
LocalVar {
409-
// TODO: size
410-
c.g.write8(0x81) // 83 for 1 byte
410+
typ := c.g.unwrap(var.typ)
411+
mut size_str := 'UNKNOWN'
411412
offset := var.offset - config.offset
412413
is_far_var := offset > 0x80 || offset < -0x7f
414+
match typ {
415+
ast.i64_type_idx, ast.u64_type_idx, ast.isize_type_idx, ast.usize_type_idx,
416+
ast.int_literal_type_idx {
417+
c.g.write16(0xFF48)
418+
size_str = 'QWORD'
419+
}
420+
ast.i32_type_idx, ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
421+
c.g.write8(0xFF)
422+
size_str = 'DWORD'
423+
}
424+
ast.i16_type_idx, ast.u16_type_idx {
425+
c.g.write8(0xFF)
426+
size_str = 'WORD'
427+
}
428+
ast.i8_type_idx, ast.u8_type_idx, ast.char_type_idx {
429+
c.g.write8(0xFE)
430+
size_str = 'BYTE'
431+
}
432+
else {
433+
ts := c.g.table.sym(typ.idx_type())
434+
c.g.n_error('unsupported type for inc_var ${ts.info}')
435+
}
436+
}
437+
413438
c.g.write8(if is_far_var { i32(0x85) } else { i32(0x45) })
414439
if is_far_var {
415440
c.g.write32(i32((0xffffffff - i64(offset) + 1) % 0x100000000))
416441
} else {
417442
c.g.write8((0xff - offset + 1) % 0x100)
418443
}
419-
c.g.write32(1)
420-
c.g.println('inc_var `${var.name}`')
444+
c.g.println('inc_var ${size_str} `${var.name}`')
421445
}
422446
GlobalVar {
447+
c.g.n_error('Global variables incrementation is not supported yet')
423448
// TODO
424449
}
425450
}
@@ -643,7 +668,7 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
643668
c.g.write16(0x8948 + if is_extended_register { i32(4) } else { i32(0) })
644669
size_str = 'QWORD'
645670
}
646-
ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
671+
ast.i32_type_idx, ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
647672
if is_extended_register {
648673
c.g.write8(0x44)
649674
}
@@ -694,7 +719,7 @@ fn (mut c Amd64) mov_reg_to_var(var Var, r Register, config VarConfig) {
694719
} else {
695720
c.g.write8((0xff - offset + 1) % 0x100)
696721
}
697-
c.g.println('mov ${size_str} PTR [rbp-${int(offset).hex2()}],${reg}')
722+
c.g.println('mov ${size_str} PTR [rbp-${int(offset).hex2()}],${reg} ; `${var.name}`')
698723
}
699724
GlobalVar {
700725
// TODO
@@ -746,7 +771,7 @@ fn (mut c Amd64) mov_int_to_var(var Var, integer i32, config VarConfig) {
746771
c.g.write16(u16(integer))
747772
c.g.println('mov WORD PTR[rbp-${int(offset).hex2()}], ${integer}')
748773
}
749-
ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
774+
ast.i32_type_idx, ast.int_type_idx, ast.u32_type_idx, ast.rune_type_idx {
750775
c.g.write8(0xc7)
751776
c.g.write8(if is_far_var { i32(0x85) } else { i32(0x45) })
752777
if is_far_var {
@@ -832,7 +857,6 @@ fn (mut c Amd64) mov_var_to_reg(reg Register, var Var, config VarConfig) {
832857
typ := if config.typ == 0 { var.typ } else { config.typ }
833858
size := c.g.get_type_size(typ)
834859
is_signed := !typ.is_any_kind_of_pointer() && typ.is_signed()
835-
836860
instruction, size_str := match true {
837861
size == 4 && is_signed {
838862
// movsxd rax, DWORD PTR [rbp-0x8]

vlib/v/gen/native/gen.v

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -710,7 +710,8 @@ fn (mut g Gen) get_type_size(raw_type ast.Type) i32 {
710710
ast.u8_type_idx { 1 }
711711
ast.i16_type_idx { 2 }
712712
ast.u16_type_idx { 2 }
713-
ast.int_type_idx { 4 }
713+
ast.int_type_idx { 4 } // TODO: change when V will have changed
714+
ast.i32_type_idx { 4 }
714715
ast.u32_type_idx { 4 }
715716
ast.i64_type_idx { 8 }
716717
ast.u64_type_idx { 8 }
@@ -722,7 +723,7 @@ fn (mut g Gen) get_type_size(raw_type ast.Type) i32 {
722723
ast.float_literal_type_idx { 8 }
723724
ast.char_type_idx { 1 }
724725
ast.rune_type_idx { 4 }
725-
else { 8 }
726+
else { g.n_error('unknown type size ${typ}') }
726727
}
727728
}
728729
if typ.is_bool() {

vlib/v/gen/native/stmt.c.v

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -243,50 +243,56 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
243243

244244
fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { // Work on that
245245
if node.is_range {
246+
g.println('; for ${node.val_var} in range {')
246247
// for a in node.cond .. node.high {
247248
i := g.code_gen.allocate_var(node.val_var, 8, 0) // iterator variable
249+
g.println('; evaluate node.cond for lower bound:')
248250
g.expr(node.cond) // outputs the lower loop bound (initial value) to the main reg
249251
main_reg := g.code_gen.main_reg()
252+
g.println('; move the result to i')
250253
g.code_gen.mov_reg_to_var(LocalVar{i, ast.i64_type_idx, node.val_var}, main_reg) // i = node.cond // initial value
251254

252255
start := g.pos() // label-begin:
253256
start_label := g.labels.new_label()
257+
258+
g.println('; check iterator against upper loop bound')
254259
g.code_gen.mov_var_to_reg(main_reg, LocalVar{i, ast.i64_type_idx, node.val_var})
255260
g.code_gen.push(main_reg) // put the iterator on the stack
256261
g.expr(node.high) // final value (upper bound) to the main reg
257262
g.code_gen.cmp_to_stack_top(main_reg)
258263
jump_addr := g.code_gen.cjmp(.jge) // leave loop i >= upper bound
259-
260264
end_label := g.labels.new_label()
261265
g.labels.patches << LabelPatch{
262266
id: end_label
263267
pos: jump_addr
264268
}
265-
g.println('; jump to label ${end_label}')
269+
g.println('; jump to label ${end_label} (end_label)')
266270
g.labels.branches << BranchLabel{
267271
name: node.label
268272
start: start_label
269273
end: end_label
270274
}
275+
271276
g.stmts(node.stmts) // writes the actual body of the loop
272277
g.labels.addrs[start_label] = g.pos()
273-
g.println('; label ${start_label}')
278+
g.println('; label ${start_label} (start_label)')
274279
g.code_gen.inc_var(LocalVar{i, ast.i64_type_idx, node.val_var})
275280
g.labels.branches.pop()
276281
g.code_gen.jmp_back(start) // loops
277282
g.labels.addrs[end_label] = g.pos()
278-
g.println('; label ${end_label}')
283+
g.println('; label ${end_label} (end_label)')
284+
g.println('; for ${node.val_var} in range }')
279285
/*
280-
} else if node.kind == .array {
286+
} else if node.kind == .array {
281287
} else if node.kind == .array_fixed {
282288
} else if node.kind == .map {
283289
} else if node.kind == .string {
284290
} else if node.kind == .struct {
285291
} else if it.kind in [.array, .string] || it.cond_type.has_flag(.variadic) {
286292
} else if it.kind == .map {
287-
*/
293+
*/
288294
} else {
289-
g.v_error('for-in statement is not yet implemented', node.pos)
295+
g.n_error('for-in ${node.kind} statement is not yet implemented')
290296
}
291297
}
292298

vlib/v/gen/native/tests/inc.vv

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
fn signed_inc_test() {
2+
mut a := i64(1)
3+
println(a)
4+
a++
5+
println(a)
6+
mut b := i32(1)
7+
println(b)
8+
b++
9+
println(b)
10+
mut c := i16(1)
11+
println(c)
12+
c++
13+
println(c)
14+
mut d := i8(1)
15+
println(d)
16+
d++
17+
println(d)
18+
mut e := int(1)
19+
println(e)
20+
e++
21+
println(e)
22+
23+
// TODO: negative inc test (when negative ints will be supported)
24+
}
25+
26+
fn unsigned_inc_test() {
27+
mut f := u64(1)
28+
println(f)
29+
f++
30+
println(f)
31+
mut g := u32(1)
32+
println(g)
33+
g++
34+
println(g)
35+
mut h := u16(1)
36+
println(h)
37+
h++
38+
println(h)
39+
mut i := u8(1)
40+
println(i)
41+
i++
42+
println(i)
43+
}
44+
45+
fn main() {
46+
signed_inc_test()
47+
unsigned_inc_test()
48+
}

vlib/v/gen/native/tests/inc.vv.out

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
1
2+
2
3+
1
4+
2
5+
1
6+
2
7+
1
8+
2
9+
1
10+
2
11+
1
12+
2
13+
1
14+
2
15+
1
16+
2
17+
1
18+
2

vlib/v/gen/native/tests/native_test.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -80,6 +80,7 @@ fn test_native() {
8080
eprintln('------------------------------------------------')
8181
eprintln('> tmperrfile: ${tmperrfile}, exists: ${os.exists(tmperrfile)}, content:')
8282
errstr := os.read_file(tmperrfile) or { '' }
83+
eprintln('------------------------------------------------')
8384
eprintln(errstr)
8485
eprintln('------------------------------------------------')
8586
eprintln('')

0 commit comments

Comments
 (0)