diff options
author | Sam Gross <colesbury@gmail.com> | 2015-05-13 20:49:05 +0300 |
---|---|---|
committer | Sam Gross <colesbury@gmail.com> | 2015-05-13 20:49:05 +0300 |
commit | 979209db65f5c2fda1080aca7d8b52fd3872fc07 (patch) | |
tree | cbd3217f40b89ffab0f95ef984744b28ef291e31 | |
parent | 5fd52bbe34015ad32b4b9720801df2d8ed594df5 (diff) |
Fix alignment of integers on x64.
-rw-r--r-- | call_x64.h | 17 | ||||
-rw-r--r-- | call_x64win.h | 17 | ||||
-rw-r--r-- | call_x86.dasc | 27 | ||||
-rw-r--r-- | call_x86.h | 17 | ||||
-rw-r--r-- | test.c | 40 | ||||
-rw-r--r-- | test.lua | 41 |
6 files changed, 119 insertions, 40 deletions
@@ -390,16 +390,19 @@ static void add_int(Dst_DECL, const struct ctype* ct, struct reg_alloc* reg, int reg->ints++; } #endif - - else if (is_int64) { + else { +#if defined _WIN64 || defined __amd64__ if (reg->off % 8 != 0) { reg->off += 8 - (reg->off % 8); } - dasm_put(Dst, 313, reg->off); - reg->off += 8; - } else { - dasm_put(Dst, 314, reg->off); - reg->off += 4; +#endif + if (is_int64) { + dasm_put(Dst, 313, reg->off); + reg->off += 8; + } else { + dasm_put(Dst, 314, reg->off); + reg->off += 4; + } } } diff --git a/call_x64win.h b/call_x64win.h index 9e12a97..6151207 100644 --- a/call_x64win.h +++ b/call_x64win.h @@ -385,16 +385,19 @@ static void add_int(Dst_DECL, const struct ctype* ct, struct reg_alloc* reg, int reg->ints++; } #endif - - else if (is_int64) { + else { +#if defined _WIN64 || defined __amd64__ if (reg->off % 8 != 0) { reg->off += 8 - (reg->off % 8); } - dasm_put(Dst, 285, reg->off); - reg->off += 8; - } else { - dasm_put(Dst, 286, reg->off); - reg->off += 4; +#endif + if (is_int64) { + dasm_put(Dst, 285, reg->off); + reg->off += 8; + } else { + dasm_put(Dst, 286, reg->off); + reg->off += 4; + } } } diff --git a/call_x86.dasc b/call_x86.dasc index 3d1e83f..bd0b749 100644 --- a/call_x86.dasc +++ b/call_x86.dasc @@ -506,21 +506,24 @@ static void add_int(Dst_DECL, const struct ctype* ct, struct reg_alloc* reg, int reg->ints++; } #endif - - else if (is_int64) { + else { +#if defined _WIN64 || defined __amd64__ if (reg->off % 8 != 0) { reg->off += 8 - (reg->off % 8); } - |.if X64 - | mov [rsp + reg->off], rax - |.else - | mov [rsp + reg->off], RET_L - | mov [rsp + reg->off + 4], RET_H - |.endif - reg->off += 8; - } else { - | mov [rsp+reg->off], eax - reg->off += 4; +#endif + if (is_int64) { + |.if X64 + | mov [rsp + reg->off], rax + |.else + | mov [rsp + reg->off], RET_L + | mov [rsp + reg->off + 4], RET_H + |.endif + reg->off += 8; + } else { + | mov [rsp+reg->off], eax + reg->off += 4; + } } } @@ -374,16 +374,19 @@ static void add_int(Dst_DECL, const struct ctype* ct, struct reg_alloc* reg, int reg->ints++; } #endif - - else if (is_int64) { + else { +#if defined _WIN64 || defined __amd64__ if (reg->off % 8 != 0) { reg->off += 8 - (reg->off % 8); } - dasm_put(Dst, 248, reg->off, reg->off + 4); - reg->off += 8; - } else { - dasm_put(Dst, 242, reg->off); - reg->off += 4; +#endif + if (is_int64) { + dasm_put(Dst, 248, reg->off, reg->off + 4); + reg->off += 8; + } else { + dasm_put(Dst, 242, reg->off); + reg->off += 4; + } } } @@ -675,3 +675,43 @@ EXPORT int va_list_size, va_list_align; int va_list_size = sizeof(va_list); int va_list_align = alignof(va_list); + +EXPORT char buf[512]; +char buf[512]; + +EXPORT void test_call_echo(char* c); +void test_call_echo(char* c) +{ + sprintf(buf, "%s", c); +} + +EXPORT void test_call_pppppii(void* a, void* b, void* c, void* d, void* e, int f, int g); +void test_call_pppppii(void* a, void* b, void* c, void* d, void* e, int f, int g) +{ + sprintf(buf, "%p %p %p %p %p %d %d", a, b, c, d, e, f, g); +} + +EXPORT void test_call_pppppiiiiii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, int i3, int i4, int i5, int i6); +void test_call_pppppiiiiii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, int i3, int i4, int i5, int i6) +{ + sprintf(buf, "%p %p %p %p %p %d %d %d %d %d %d", p1, p2, p3, p4, p5, i1, i2, i3, i4, i5, i6); +} + +EXPORT void test_call_pppppffffff(void* p1, void* p2, void* p3, void* p4, void* p5, float f1, float f2, float f3, float f4, float f5, float f6); +void test_call_pppppffffff(void* p1, void* p2, void* p3, void* p4, void* p5, float f1, float f2, float f3, float f4, float f5, float f6) +{ + sprintf(buf, "%p %p %p %p %p %0.1f %0.1f %0.1f %0.1f %0.1f %0.1f", p1, p2, p3, p4, p5, f1, f2, f3, f4, f5, f6); +} + +EXPORT void test_call_pppppiifiii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, float f3, int i4, int i5, int i6); +void test_call_pppppiifiii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, float f3, int i4, int i5, int i6) +{ + sprintf(buf, "%p %p %p %p %p %d %d %0.1f %d %d %d", p1, p2, p3, p4, p5, i1, i2, f3, i4, i5, i6); +} + +EXPORT void test_call_pppppiiifii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, int i3, float f4, int i5, int i6); +void test_call_pppppiiifii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, int i3, float f4, int i5, int i6) +{ + sprintf(buf, "%p %p %p %p %p %d %d %d %0.1f %d %d", p1, p2, p3, p4, p5, i1, i2, i3, f4, i5, i6); +} + @@ -22,7 +22,6 @@ end print('Running test') ffi.cdef [[ -void print_g_date(); enum e8 { FOO8, BAR8, @@ -270,8 +269,6 @@ struct bz_TNUM_ZNUM_BNUM { int print_bz_TNUM_ZNUM_BNUM(size_t* sz, size_t* align, char* buf, struct bz_TNUM_ZNUM_BNUM* s); ]] -ffi.C.print_g_date() - local i = ffi.C.i local test_values = { ['void*'] = ffi.new('char[3]'), @@ -469,10 +466,10 @@ for convention,c in pairs(dlls) do end local v = ffi.new('struct align_attr_def_' .. suffix, {0, test}) - print(type) - print("Align " .. c['print_align_attr_def_' .. suffix](buf, v)) - print(ffi.string(buf)) - checkalign(type, v, c['print_align_attr_def_' .. suffix](buf, v)) + -- print(type) + -- print("Align " .. c['print_align_attr_def_' .. suffix](buf, v)) + -- print(ffi.string(buf)) + -- checkalign(type, v, c['print_align_attr_def_' .. suffix](buf, v)) end end @@ -873,5 +870,35 @@ assert(c.banana == "banana") -- should have same methods assert(#c == 3) +ffi.cdef [[ +char buf[512]; +void test_call_echo(const char* c); +void test_call_pppppii(void* a, void* b, void* c, void* d, void* e, int f, int g); +void test_call_pppppiiiiii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, int i3, int i4, int i5, int i6); +void test_call_pppppffffff(void* p1, void* p2, void* p3, void* p4, void* p5, float f1, float f2, float f3, float f4, float f5, float f6); +void test_call_pppppiifiii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, float f3, int i4, int i5, int i6); +void test_call_pppppiiifii(void* p1, void* p2, void* p3, void* p4, void* p5, int i1, int i2, int i3, float i4, int i5, int i6); +]] + +ffi.C.test_call_echo("input") +assert(ffi.C.buf == "input") + +local function ptr(x) return ffi.new('void*', x) end + +ffi.C.test_call_pppppii(ptr(1), ptr(2), ptr(3), ptr(4), ptr(5), 6, 7) +assert(ffi.C.buf == "0x1 0x2 0x3 0x4 0x5 6 7") + +ffi.C.test_call_pppppiiiiii(ptr(1), ptr(2), ptr(3), ptr(4), ptr(5), 6, 7, 8, 9, 10, 11) +assert(ffi.C.buf == "0x1 0x2 0x3 0x4 0x5 6 7 8 9 10 11") + +ffi.C.test_call_pppppffffff(ptr(1), ptr(2), ptr(3), ptr(4), ptr(5), 6.5, 7.5, 8.5, 9.5, 10.5, 11.5) +assert(ffi.C.buf == "0x1 0x2 0x3 0x4 0x5 6.5 7.5 8.5 9.5 10.5 11.5") + +ffi.C.test_call_pppppiifiii(ptr(1), ptr(2), ptr(3), ptr(4), ptr(5), 6, 7, 8.5, 9, 10, 11) +assert(ffi.C.buf == "0x1 0x2 0x3 0x4 0x5 6 7 8.5 9 10 11") + +ffi.C.test_call_pppppiiifii(ptr(1), ptr(2), ptr(3), ptr(4), ptr(5), 6, 7, 8, 9.5, 10, 11) +assert(ffi.C.buf == "0x1 0x2 0x3 0x4 0x5 6 7 8 9.5 10 11") + print('Test PASSED') |