mirror of
https://github.com/vlang/v.git
synced 2025-09-13 17:36:52 -04:00
native: fix inc and improve support for i32 (#23753)
This commit is contained in:
parent
f2672b1f9f
commit
dbc96b22ec
@ -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]
|
||||
|
@ -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() {
|
||||
|
@ -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')
|
||||
}
|
||||
}
|
||||
|
||||
|
48
vlib/v/gen/native/tests/inc.vv
Normal file
48
vlib/v/gen/native/tests/inc.vv
Normal file
@ -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()
|
||||
}
|
18
vlib/v/gen/native/tests/inc.vv.out
Normal file
18
vlib/v/gen/native/tests/inc.vv.out
Normal file
@ -0,0 +1,18 @@
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
||||
1
|
||||
2
|
@ -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('')
|
||||
|
Loading…
x
Reference in New Issue
Block a user