x64: for loop
parent
5664cbd3d0
commit
7f5e3b36bc
|
@ -211,6 +211,18 @@ fn (mut g Gen) jne() int {
|
||||||
return pos
|
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 {
|
fn abs(a i64) i64 {
|
||||||
return if a < 0 {
|
return if a < 0 {
|
||||||
-a
|
-a
|
||||||
|
@ -237,12 +249,13 @@ fn (g &Gen) abs_to_rel_addr(addr i64) int {
|
||||||
return int(abs(addr - g.buf.len)) - 1
|
return int(abs(addr - g.buf.len)) - 1
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
fn (mut g Gen) jmp(addr i64) {
|
fn (mut g Gen) jmp(addr i64) {
|
||||||
offset := 0xff - g.abs_to_rel_addr(addr)
|
offset := 0xff - g.abs_to_rel_addr(addr)
|
||||||
g.write8(0xe9)
|
g.write8(0xe9)
|
||||||
g.write8(offset)
|
g.write8(offset)
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
fn (mut g Gen) mov64(reg Register, val i64) {
|
fn (mut g Gen) mov64(reg Register, val i64) {
|
||||||
match reg {
|
match reg {
|
||||||
.rsi {
|
.rsi {
|
||||||
|
@ -435,7 +448,9 @@ fn (mut g Gen) stmt(node ast.Stmt) {
|
||||||
ast.FnDecl {
|
ast.FnDecl {
|
||||||
g.fn_decl(it)
|
g.fn_decl(it)
|
||||||
}
|
}
|
||||||
ast.ForStmt {}
|
ast.ForStmt {
|
||||||
|
g.for_stmt(it)
|
||||||
|
}
|
||||||
ast.Return {
|
ast.Return {
|
||||||
g.gen_exit()
|
g.gen_exit()
|
||||||
g.ret()
|
g.ret()
|
||||||
|
@ -535,7 +550,9 @@ fn (mut g Gen) if_expr(node ast.IfExpr) {
|
||||||
g.cmp_var(it.name, lit.val.int())
|
g.cmp_var(it.name, lit.val.int())
|
||||||
jne_addr = g.jne()
|
jne_addr = g.jne()
|
||||||
}
|
}
|
||||||
else {}
|
else {
|
||||||
|
verror('unhandled infix.left')
|
||||||
|
}
|
||||||
}
|
}
|
||||||
g.stmts(branch.stmts)
|
g.stmts(branch.stmts)
|
||||||
// Now that we know where we need to jump if the condition is false, update the `jne` call.
|
// 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"
|
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) {
|
fn (mut g Gen) fn_decl(it ast.FnDecl) {
|
||||||
is_main := it.name == 'main'
|
is_main := it.name == 'main'
|
||||||
println('saving addr $it.name $g.buf.len.hex()')
|
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() {
|
fn main() {
|
||||||
test()
|
test()
|
||||||
|
loop()
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,3 +1,8 @@
|
||||||
a == 1
|
a == 1
|
||||||
b == 2
|
b == 2
|
||||||
now a == 2
|
now a == 2
|
||||||
|
hello
|
||||||
|
hello
|
||||||
|
hello
|
||||||
|
hello
|
||||||
|
hello
|
||||||
|
|
Loading…
Reference in New Issue