mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
x64: fix off by one error in for loops
This commit is contained in:
parent
39bc38233a
commit
431568faad
@ -1,6 +1,6 @@
|
|||||||
fn test_fn() {
|
fn test_fn() {
|
||||||
println('test fn')
|
println('test fn')
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println('x64 test')
|
println('x64 test')
|
||||||
@ -8,7 +8,7 @@ fn main() {
|
|||||||
println('Hello world from V x64 machine code generator!')
|
println('Hello world from V x64 machine code generator!')
|
||||||
}
|
}
|
||||||
println('Hello again!')
|
println('Hello again!')
|
||||||
test_fn()
|
//test_fn()
|
||||||
println('dne')
|
println('done')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,7 +17,7 @@ mut:
|
|||||||
code_start_pos i64 // location of the start of the assembly instructions
|
code_start_pos i64 // location of the start of the assembly instructions
|
||||||
fn_addr map[string]i64
|
fn_addr map[string]i64
|
||||||
//string_addr map[string]i64
|
//string_addr map[string]i64
|
||||||
}
|
}
|
||||||
|
|
||||||
enum Register {
|
enum Register {
|
||||||
eax
|
eax
|
||||||
@ -35,31 +35,31 @@ enum Size {
|
|||||||
_16
|
_16
|
||||||
_32
|
_32
|
||||||
_64
|
_64
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn new_gen(out_name string) &Gen {
|
pub fn new_gen(out_name string) &Gen {
|
||||||
return &Gen{
|
return &Gen{
|
||||||
sect_header_name_pos : 0
|
sect_header_name_pos : 0
|
||||||
buf: []
|
buf: []
|
||||||
out_name: out_name
|
out_name: out_name
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (g &Gen) pos() i64 {
|
pub fn (g &Gen) pos() i64 {
|
||||||
return g.buf.len
|
return g.buf.len
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
fn (g mut Gen) write8(n int) {
|
fn (g mut Gen) write8(n int) {
|
||||||
// write 1 byte
|
// write 1 byte
|
||||||
g.buf << byte(n)
|
g.buf << byte(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write16(n int) {
|
fn (g mut Gen) write16(n int) {
|
||||||
// write 2 bytes
|
// write 2 bytes
|
||||||
g.buf << byte(n)
|
g.buf << byte(n)
|
||||||
g.buf << byte(n >> 8)
|
g.buf << byte(n >> 8)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write32(n int) {
|
fn (g mut Gen) write32(n int) {
|
||||||
// write 4 bytes
|
// write 4 bytes
|
||||||
@ -67,7 +67,7 @@ fn (g mut Gen) write32(n int) {
|
|||||||
g.buf << byte(n >> 8)
|
g.buf << byte(n >> 8)
|
||||||
g.buf << byte(n >> 16)
|
g.buf << byte(n >> 16)
|
||||||
g.buf << byte(n >> 24)
|
g.buf << byte(n >> 24)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write64(n i64) {
|
fn (g mut Gen) write64(n i64) {
|
||||||
// write 8 bytes
|
// write 8 bytes
|
||||||
@ -79,7 +79,7 @@ fn (g mut Gen) write64(n i64) {
|
|||||||
g.buf << byte(n >> 40)
|
g.buf << byte(n >> 40)
|
||||||
g.buf << byte(n >> 48)
|
g.buf << byte(n >> 48)
|
||||||
g.buf << byte(n >> 56)
|
g.buf << byte(n >> 56)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write64_at(n i64, at i64) {
|
fn (g mut Gen) write64_at(n i64, at i64) {
|
||||||
// write 8 bytes
|
// write 8 bytes
|
||||||
@ -91,12 +91,12 @@ fn (g mut Gen) write64_at(n i64, at i64) {
|
|||||||
g.buf[at+5] = byte(n >> 40)
|
g.buf[at+5] = byte(n >> 40)
|
||||||
g.buf[at+6] = byte(n >> 48)
|
g.buf[at+6] = byte(n >> 48)
|
||||||
g.buf[at+7] = byte(n >> 56)
|
g.buf[at+7] = byte(n >> 56)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) write_string(s string) {
|
fn (g mut Gen) write_string(s string) {
|
||||||
for c in s {
|
for c in s {
|
||||||
g.write8(int(c))
|
g.write8(int(c))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) inc(reg Register) {
|
fn (g mut Gen) inc(reg Register) {
|
||||||
@ -104,8 +104,8 @@ fn (g mut Gen) inc(reg Register) {
|
|||||||
match reg {
|
match reg {
|
||||||
.r12 { g.write8(0xc4) }
|
.r12 { g.write8(0xc4) }
|
||||||
else { panic('unhandled inc $reg') }
|
else { panic('unhandled inc $reg') }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn (g mut Gen) cmp(reg Register, size Size, val i64) {
|
fn (g mut Gen) cmp(reg Register, size Size, val i64) {
|
||||||
g.write8(0x49)
|
g.write8(0x49)
|
||||||
@ -114,12 +114,12 @@ fn (g mut Gen) cmp(reg Register, size Size, val i64) {
|
|||||||
._8 { g.write8(0x83) }
|
._8 { g.write8(0x83) }
|
||||||
._32 { g.write8(0x81) }
|
._32 { g.write8(0x81) }
|
||||||
else { panic('unhandled cmp') }
|
else { panic('unhandled cmp') }
|
||||||
}
|
}
|
||||||
// Third byte depends on the register being compared to
|
// Third byte depends on the register being compared to
|
||||||
match reg {
|
match reg {
|
||||||
.r12 { g.write8(0xfc) }
|
.r12 { g.write8(0xfc) }
|
||||||
else { panic('unhandled cmp') }
|
else { panic('unhandled cmp') }
|
||||||
}
|
}
|
||||||
g.write8(int(val))
|
g.write8(int(val))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -141,7 +141,7 @@ fn (g mut Gen) jl(addr i64) {
|
|||||||
|
|
||||||
fn (g &Gen) abs_to_rel_addr(addr i64) int {
|
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 (g mut Gen) jmp (addr i64) {
|
fn (g mut Gen) jmp (addr i64) {
|
||||||
offset := 0xff - g.abs_to_rel_addr(addr)
|
offset := 0xff - g.abs_to_rel_addr(addr)
|
||||||
@ -163,7 +163,7 @@ fn (g mut Gen) mov64(reg Register, val i64) {
|
|||||||
fn (g mut Gen) call(addr int) {
|
fn (g mut Gen) call(addr int) {
|
||||||
//rel := g.abs_to_rel_addr(addr)
|
//rel := g.abs_to_rel_addr(addr)
|
||||||
rel := 0xffffffff - int(abs(addr - g.buf.len))-1
|
rel := 0xffffffff - int(abs(addr - g.buf.len))-1
|
||||||
|
|
||||||
println('call addr=$addr rel_addr=$addr pos=$g.buf.len')
|
println('call addr=$addr rel_addr=$addr pos=$g.buf.len')
|
||||||
g.write8(0xe8)
|
g.write8(0xe8)
|
||||||
g.write32(addr)
|
g.write32(addr)
|
||||||
@ -189,7 +189,7 @@ pub fn (g mut Gen) gen_loop_start(from int) int {
|
|||||||
|
|
||||||
pub fn (g mut Gen) gen_loop_end(to int, label int) {
|
pub fn (g mut Gen) gen_loop_end(to int, label int) {
|
||||||
g.cmp(.r12, ._8, to)
|
g.cmp(.r12, ._8, to)
|
||||||
g.jle(label)
|
g.jl(label)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (g mut Gen) save_main_fn_addr() {
|
pub fn (g mut Gen) save_main_fn_addr() {
|
||||||
@ -206,7 +206,7 @@ pub fn (g mut Gen) gen_print(s string) {
|
|||||||
g.mov64(.rsi, 0) //segment_start + 0x9f) // str pos // PLACEHOLDER
|
g.mov64(.rsi, 0) //segment_start + 0x9f) // str pos // PLACEHOLDER
|
||||||
g.mov(.edx, s.len+1) // len
|
g.mov(.edx, s.len+1) // len
|
||||||
g.syscall()
|
g.syscall()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn (g mut Gen) gen_exit() {
|
pub fn (g mut Gen) gen_exit() {
|
||||||
// Return 0
|
// Return 0
|
||||||
@ -227,11 +227,11 @@ fn (g mut Gen) mov(reg Register, val int) {
|
|||||||
.r12 {
|
.r12 {
|
||||||
g.write8(0x41)
|
g.write8(0x41)
|
||||||
g.write8(0xbc) // r11 is 0xbb etc
|
g.write8(0xbc) // r11 is 0xbb etc
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
panic('unhandled mov $reg')
|
panic('unhandled mov $reg')
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
g.write32(val)
|
g.write32(val)
|
||||||
}
|
}
|
||||||
@ -245,7 +245,7 @@ pub fn (g mut Gen) register_function_address(name string) {
|
|||||||
pub fn (g mut Gen) call_fn(name string) {
|
pub fn (g mut Gen) call_fn(name string) {
|
||||||
if !name.contains('__') {
|
if !name.contains('__') {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
addr := g.fn_addr[name]
|
addr := g.fn_addr[name]
|
||||||
g.call(int(addr))
|
g.call(int(addr))
|
||||||
println('call $name $addr')
|
println('call $name $addr')
|
||||||
|
Loading…
Reference in New Issue
Block a user