mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
native: move for_in_stmt to stmt.v (#18705)
This commit is contained in:
parent
578264c815
commit
b0323c79ad
@ -10,7 +10,7 @@ import v.token
|
|||||||
pub struct Amd64 {
|
pub struct Amd64 {
|
||||||
mut:
|
mut:
|
||||||
g &Gen = unsafe { nil }
|
g &Gen = unsafe { nil }
|
||||||
// arm64 specific stuff for code generation
|
// amd64 specific stuff for code generation
|
||||||
is_16bit_aligned bool
|
is_16bit_aligned bool
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -995,7 +995,8 @@ fn (mut c Amd64) ret() {
|
|||||||
c.g.println('ret')
|
c.g.println('ret')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) push(reg Amd64Register) {
|
fn (mut c Amd64) push(r Register) {
|
||||||
|
reg := r as Amd64Register
|
||||||
if int(reg) < int(Amd64Register.r8) {
|
if int(reg) < int(Amd64Register.r8) {
|
||||||
c.g.write8(0x50 + int(reg))
|
c.g.write8(0x50 + int(reg))
|
||||||
} else {
|
} else {
|
||||||
@ -1122,7 +1123,7 @@ fn (mut c Amd64) leave() {
|
|||||||
c.g.println('; label 0: return')
|
c.g.println('; label 0: return')
|
||||||
if c.g.defer_stmts.len != 0 {
|
if c.g.defer_stmts.len != 0 {
|
||||||
// save return value
|
// save return value
|
||||||
c.push(.rax)
|
c.push(Amd64Register.rax)
|
||||||
for defer_stmt in c.g.defer_stmts.reverse() {
|
for defer_stmt in c.g.defer_stmts.reverse() {
|
||||||
name := '_defer${defer_stmt.idx_in_fn}'
|
name := '_defer${defer_stmt.idx_in_fn}'
|
||||||
defer_var := c.g.get_var_offset(name)
|
defer_var := c.g.get_var_offset(name)
|
||||||
@ -1712,14 +1713,14 @@ pub fn (mut c Amd64) call_fn(node ast.CallExpr) {
|
|||||||
is_16bit_aligned := c.is_16bit_aligned != (stack_size % 2 == 1)
|
is_16bit_aligned := c.is_16bit_aligned != (stack_size % 2 == 1)
|
||||||
if !is_16bit_aligned {
|
if !is_16bit_aligned {
|
||||||
// dummy data
|
// dummy data
|
||||||
c.push(.rbp)
|
c.push(Amd64Register.rbp)
|
||||||
}
|
}
|
||||||
reg_args << ssereg_args
|
reg_args << ssereg_args
|
||||||
reg_args << stack_args
|
reg_args << stack_args
|
||||||
for i in reg_args.reverse() {
|
for i in reg_args.reverse() {
|
||||||
if i == 0 && is_struct_return {
|
if i == 0 && is_struct_return {
|
||||||
c.lea_var_to_reg(Amd64Register.rax, return_pos)
|
c.lea_var_to_reg(Amd64Register.rax, return_pos)
|
||||||
c.push(.rax)
|
c.push(Amd64Register.rax)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
c.g.expr(args[i].expr)
|
c.g.expr(args[i].expr)
|
||||||
@ -1754,17 +1755,17 @@ pub fn (mut c Amd64) call_fn(node ast.CallExpr) {
|
|||||||
} else {
|
} else {
|
||||||
match args_size[i] {
|
match args_size[i] {
|
||||||
1...8 {
|
1...8 {
|
||||||
c.push(.rax)
|
c.push(Amd64Register.rax)
|
||||||
}
|
}
|
||||||
9...16 {
|
9...16 {
|
||||||
c.push(.rdx)
|
c.push(Amd64Register.rdx)
|
||||||
c.push(.rax)
|
c.push(Amd64Register.rax)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.add(.rax, args_size[i] - ((args_size[i] + 7) % 8 + 1))
|
c.add(.rax, args_size[i] - ((args_size[i] + 7) % 8 + 1))
|
||||||
for _ in 0 .. (args_size[i] + 7) / 8 {
|
for _ in 0 .. (args_size[i] + 7) / 8 {
|
||||||
c.mov_deref(.rdx, .rax, ast.i64_type_idx)
|
c.mov_deref(.rdx, .rax, ast.i64_type_idx)
|
||||||
c.push(.rdx)
|
c.push(Amd64Register.rdx)
|
||||||
c.sub(.rax, 8)
|
c.sub(.rax, 8)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1854,51 +1855,6 @@ fn (mut c Amd64) call_builtin(name Builtin) i64 {
|
|||||||
return call_addr
|
return call_addr
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) for_in_stmt(node ast.ForInStmt) {
|
|
||||||
if node.is_range {
|
|
||||||
// for a in node.cond .. node.high {
|
|
||||||
i := c.allocate_var(node.val_var, 8, 0) // iterator variable
|
|
||||||
c.g.expr(node.cond)
|
|
||||||
c.mov_reg_to_var(LocalVar{i, ast.i64_type_idx, node.val_var}, Amd64Register.rax) // i = node.cond // initial value
|
|
||||||
start := c.g.pos() // label-begin:
|
|
||||||
start_label := c.g.labels.new_label()
|
|
||||||
c.mov_var_to_reg(Amd64Register.rbx, LocalVar{i, ast.i64_type_idx, node.val_var}) // rbx = iterator value
|
|
||||||
c.g.expr(node.high) // final value
|
|
||||||
c.cmp_reg(.rbx, .rax) // rbx = iterator, rax = max value
|
|
||||||
jump_addr := c.cjmp(.jge) // leave loop if i is beyond end
|
|
||||||
end_label := c.g.labels.new_label()
|
|
||||||
c.g.labels.patches << LabelPatch{
|
|
||||||
id: end_label
|
|
||||||
pos: jump_addr
|
|
||||||
}
|
|
||||||
c.g.println('; jump to label ${end_label}')
|
|
||||||
c.g.labels.branches << BranchLabel{
|
|
||||||
name: node.label
|
|
||||||
start: start_label
|
|
||||||
end: end_label
|
|
||||||
}
|
|
||||||
c.g.stmts(node.stmts)
|
|
||||||
c.g.labels.addrs[start_label] = c.g.pos()
|
|
||||||
c.g.println('; label ${start_label}')
|
|
||||||
c.inc_var(LocalVar{i, ast.i64_type_idx, node.val_var})
|
|
||||||
c.g.labels.branches.pop()
|
|
||||||
c.jmp_back(start)
|
|
||||||
c.g.labels.addrs[end_label] = c.g.pos()
|
|
||||||
c.g.println('; label ${end_label}')
|
|
||||||
/*
|
|
||||||
} 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 {
|
|
||||||
c.g.v_error('for-in statement is not yet implemented', node.pos)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn (mut c Amd64) gen_concat_expr(node ast.ConcatExpr) {
|
fn (mut c Amd64) gen_concat_expr(node ast.ConcatExpr) {
|
||||||
typ := node.return_type
|
typ := node.return_type
|
||||||
ts := c.g.table.sym(typ)
|
ts := c.g.table.sym(typ)
|
||||||
@ -3186,7 +3142,7 @@ fn (mut c Amd64) infloop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn (mut c Amd64) fn_decl(node ast.FnDecl) {
|
fn (mut c Amd64) fn_decl(node ast.FnDecl) {
|
||||||
c.push(.rbp)
|
c.push(Amd64Register.rbp)
|
||||||
c.mov_reg(Amd64Register.rbp, Amd64Register.rsp)
|
c.mov_reg(Amd64Register.rbp, Amd64Register.rsp)
|
||||||
local_alloc_pos := c.g.pos()
|
local_alloc_pos := c.g.pos()
|
||||||
c.sub(.rsp, 0)
|
c.sub(.rsp, 0)
|
||||||
@ -3616,7 +3572,7 @@ fn (mut c Amd64) convert_int_to_string(a Register, b Register) {
|
|||||||
loop_start := c.g.pos()
|
loop_start := c.g.pos()
|
||||||
c.g.println('; label ${loop_label}')
|
c.g.println('; label ${loop_label}')
|
||||||
|
|
||||||
c.push(.rax)
|
c.push(Amd64Register.rax)
|
||||||
|
|
||||||
c.mov(Amd64Register.rdx, 0)
|
c.mov(Amd64Register.rdx, 0)
|
||||||
c.mov(Amd64Register.rbx, 10)
|
c.mov(Amd64Register.rbx, 10)
|
||||||
@ -3719,7 +3675,7 @@ fn (mut c Amd64) gen_match_expr(expr ast.MatchExpr) {
|
|||||||
} else {
|
} else {
|
||||||
c.g.expr(expr.cond)
|
c.g.expr(expr.cond)
|
||||||
}
|
}
|
||||||
c.push(.rax)
|
c.push(Amd64Register.rax)
|
||||||
|
|
||||||
mut else_label := 0
|
mut else_label := 0
|
||||||
for i, branch in expr.branches {
|
for i, branch in expr.branches {
|
||||||
@ -3747,7 +3703,7 @@ fn (mut c Amd64) gen_match_expr(expr ast.MatchExpr) {
|
|||||||
id: branch_labels[i]
|
id: branch_labels[i]
|
||||||
pos: then_addr
|
pos: then_addr
|
||||||
}
|
}
|
||||||
c.push(.rdx)
|
c.push(Amd64Register.rdx)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
c.g.expr(cond)
|
c.g.expr(cond)
|
||||||
@ -3758,7 +3714,7 @@ fn (mut c Amd64) gen_match_expr(expr ast.MatchExpr) {
|
|||||||
id: branch_labels[i]
|
id: branch_labels[i]
|
||||||
pos: then_addr
|
pos: then_addr
|
||||||
}
|
}
|
||||||
c.push(.rdx)
|
c.push(Amd64Register.rdx)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4172,6 +4128,11 @@ fn (mut c Amd64) gen_cast_expr(expr ast.CastExpr) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Amd64) cmp_to_stack_top(reg Register) {
|
||||||
|
c.pop(.rbx)
|
||||||
|
c.cmp_reg(.rbx, reg as Amd64Register)
|
||||||
|
}
|
||||||
|
|
||||||
// Temporary!
|
// Temporary!
|
||||||
fn (mut c Amd64) adr(r Arm64Register, delta int) {
|
fn (mut c Amd64) adr(r Arm64Register, delta int) {
|
||||||
panic('`adr` instruction not supported with amd64')
|
panic('`adr` instruction not supported with amd64')
|
||||||
|
@ -522,3 +522,11 @@ fn (mut c Arm64) call_addr_at(addr int, at i64) i64 {
|
|||||||
fn (mut c Arm64) gen_concat_expr(expr ast.ConcatExpr) {
|
fn (mut c Arm64) gen_concat_expr(expr ast.ConcatExpr) {
|
||||||
panic('Arm64.gen_concat_expr() not implemented')
|
panic('Arm64.gen_concat_expr() not implemented')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut c Arm64) cmp_to_stack_top(reg Register) {
|
||||||
|
panic('Arm64.cmp_to_stack_top() not implemented')
|
||||||
|
}
|
||||||
|
|
||||||
|
fn (mut c Arm64) push(r Register) {
|
||||||
|
panic('Arm64.push() not implemented')
|
||||||
|
}
|
||||||
|
@ -78,6 +78,7 @@ mut:
|
|||||||
call_fn(node ast.CallExpr)
|
call_fn(node ast.CallExpr)
|
||||||
call(addr int) i64
|
call(addr int) i64
|
||||||
cjmp(op JumpOp) int
|
cjmp(op JumpOp) int
|
||||||
|
cmp_to_stack_top(r Register)
|
||||||
cmp_var_reg(var Var, reg Register, config VarConfig)
|
cmp_var_reg(var Var, reg Register, config VarConfig)
|
||||||
cmp_var(var Var, val int, config VarConfig)
|
cmp_var(var Var, val int, config VarConfig)
|
||||||
cmp_zero(reg Register)
|
cmp_zero(reg Register)
|
||||||
@ -86,7 +87,6 @@ mut:
|
|||||||
convert_rune_to_string(r Register, buffer int, var Var, config VarConfig)
|
convert_rune_to_string(r Register, buffer int, var Var, config VarConfig)
|
||||||
dec_var(var Var, config VarConfig)
|
dec_var(var Var, config VarConfig)
|
||||||
fn_decl(node ast.FnDecl)
|
fn_decl(node ast.FnDecl)
|
||||||
for_in_stmt(node ast.ForInStmt)
|
|
||||||
gen_asm_stmt(asm_node ast.AsmStmt)
|
gen_asm_stmt(asm_node ast.AsmStmt)
|
||||||
gen_assert(assert_node ast.AssertStmt)
|
gen_assert(assert_node ast.AssertStmt)
|
||||||
gen_cast_expr(expr ast.CastExpr)
|
gen_cast_expr(expr ast.CastExpr)
|
||||||
@ -118,6 +118,7 @@ mut:
|
|||||||
mov64(r Register, val i64)
|
mov64(r Register, val i64)
|
||||||
movabs(reg Register, val i64)
|
movabs(reg Register, val i64)
|
||||||
prefix_expr(node ast.PrefixExpr)
|
prefix_expr(node ast.PrefixExpr)
|
||||||
|
push(r Register)
|
||||||
ret()
|
ret()
|
||||||
return_stmt(node ast.Return)
|
return_stmt(node ast.Return)
|
||||||
reverse_string(r Register)
|
reverse_string(r Register)
|
||||||
|
@ -63,7 +63,7 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||||||
// if no statements, just dont make it
|
// if no statements, just dont make it
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
g.code_gen.for_in_stmt(node)
|
g.for_in_stmt(node)
|
||||||
}
|
}
|
||||||
ast.ForStmt {
|
ast.ForStmt {
|
||||||
g.for_stmt(node)
|
g.for_stmt(node)
|
||||||
@ -274,3 +274,52 @@ fn (mut g Gen) for_stmt(node ast.ForStmt) {
|
|||||||
g.println('; label ${end_label}')
|
g.println('; label ${end_label}')
|
||||||
g.println('jmp after for')
|
g.println('jmp after for')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn (mut g Gen) for_in_stmt(node ast.ForInStmt) { // Work on that
|
||||||
|
if node.is_range {
|
||||||
|
// for a in node.cond .. node.high {
|
||||||
|
i := g.code_gen.allocate_var(node.val_var, 8, 0) // iterator variable
|
||||||
|
g.expr(node.cond) // outputs the lower loop bound (initial value) to the main reg
|
||||||
|
main_reg := g.code_gen.main_reg()
|
||||||
|
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.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.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.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}')
|
||||||
|
/*
|
||||||
|
} 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user