x64: for loop
parent
5664cbd3d0
commit
7f5e3b36bc
|
@ -211,6 +211,18 @@ fn (mut g Gen) jne() int {
|
|||
return pos
|
||||
}
|
||||
|
||||
fn (mut g Gen) jge() int {
|
||||
g.write16(0x8d0f)
|
||||
pos := g.pos()
|
||||
g.write32(PLACEHOLDER)
|
||||
return pos
|
||||
}
|
||||
|
||||
fn (mut g Gen) jmp(addr int) {
|
||||
g.write8(0xe9)
|
||||
g.write32(addr) // 0xffffff
|
||||
}
|
||||
|
||||
fn abs(a i64) i64 {
|
||||
return if a < 0 {
|
||||
-a
|
||||
|
@ -237,12 +249,13 @@ fn (g &Gen) abs_to_rel_addr(addr i64) int {
|
|||
return int(abs(addr - g.buf.len)) - 1
|
||||
}
|
||||
|
||||
/*
|
||||
fn (mut g Gen) jmp(addr i64) {
|
||||
offset := 0xff - g.abs_to_rel_addr(addr)
|
||||
g.write8(0xe9)
|
||||
g.write8(offset)
|
||||
}
|
||||
|
||||
*/
|
||||
fn (mut g Gen) mov64(reg Register, val i64) {
|
||||
match reg {
|
||||
.rsi {
|
||||
|
@ -435,7 +448,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
|||
ast.FnDecl {
|
||||
g.fn_decl(it)
|
||||
}
|
||||
ast.ForStmt {}
|
||||
ast.ForStmt {
|
||||
g.for_stmt(it)
|
||||
}
|
||||
ast.Return {
|
||||
g.gen_exit()
|
||||
g.ret()
|
||||
|
@ -535,7 +550,9 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
|||
g.cmp_var(it.name, lit.val.int())
|
||||
jne_addr = g.jne()
|
||||
}
|
||||
else {}
|
||||
else {
|
||||
verror('unhandled infix.left')
|
||||
}
|
||||
}
|
||||
g.stmts(branch.stmts)
|
||||
// Now that we know where we need to jump if the condition is false, update the `jne` call.
|
||||
|
@ -545,6 +562,29 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
|||
g.write32_at(jne_addr, g.pos() - jne_addr - 4) // 4 is for "00 00 00 00"
|
||||
}
|
||||
|
||||
fn (mut g Gen) for_stmt(node ast.ForStmt) {
|
||||
infix_expr := node.cond as ast.InfixExpr
|
||||
// g.mov(.eax, 0x77777777)
|
||||
mut jump_addr := 0 // location of `jne *00 00 00 00*`
|
||||
start := g.pos()
|
||||
match infix_expr.left {
|
||||
ast.Ident {
|
||||
lit := infix_expr.right as ast.IntegerLiteral
|
||||
g.cmp_var(it.name, lit.val.int())
|
||||
jump_addr = g.jge()
|
||||
}
|
||||
else {
|
||||
verror('unhandled infix.left')
|
||||
}
|
||||
}
|
||||
g.stmts(node.stmts)
|
||||
// Go back to `cmp ...`
|
||||
// Diff between `jmp 00 00 00 00 X` and `cmp`
|
||||
g.jmp(0xffffffff - (g.pos() + 5 - start) + 1)
|
||||
// Update the jump addr to current pos
|
||||
g.write32_at(jump_addr, g.pos() - jump_addr - 4) // 4 is for "00 00 00 00"
|
||||
}
|
||||
|
||||
fn (mut g Gen) fn_decl(it ast.FnDecl) {
|
||||
is_main := it.name == 'main'
|
||||
println('saving addr $it.name $g.buf.len.hex()')
|
||||
|
|
|
@ -19,6 +19,15 @@ fn test() {
|
|||
}
|
||||
}
|
||||
|
||||
fn loop() {
|
||||
mut i := 0
|
||||
for i < 5 {
|
||||
println('hello')
|
||||
i++
|
||||
}
|
||||
}
|
||||
|
||||
fn main() {
|
||||
test()
|
||||
loop()
|
||||
}
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
a == 1
|
||||
b == 2
|
||||
now a == 2
|
||||
hello
|
||||
hello
|
||||
hello
|
||||
hello
|
||||
hello
|
||||
|
|
Loading…
Reference in New Issue