diff options
| author | grischka <grischka> | 2017-02-08 19:45:31 +0100 |
|---|---|---|
| committer | grischka <grischka> | 2017-02-08 19:45:31 +0100 |
| commit | 68666eee2ade45ab73b07361367d0a38d350d663 (patch) | |
| tree | 1cb0bdc6b04665e96ba563a137bea20bf909fdca /i386-gen.c | |
| parent | f077d16c20c524d7db8cb38a9193242eeade343d (diff) | |
| download | tinycc-68666eee2ade45ab73b07361367d0a38d350d663.tar.gz tinycc-68666eee2ade45ab73b07361367d0a38d350d663.tar.bz2 | |
tccgen: factor out gfunc_return
Also:
- on windows i386 and x86-64, structures of size <= 8 are
NOT returned in registers if size is not one of 1,2,4,8.
- cleanup: put all tv-push/pop/swap/rot into one place
Diffstat (limited to 'i386-gen.c')
| -rw-r--r-- | i386-gen.c | 21 |
1 files changed, 11 insertions, 10 deletions
@@ -396,21 +396,21 @@ ST_FUNC int gfunc_sret(CType *vt, int variadic, CType *ret, int *ret_align, int { #ifdef TCC_TARGET_PE int size, align; - *ret_align = 1; // Never have to re-align return values for x86 *regsize = 4; size = type_size(vt, &align); - if (size > 8) { + if (size > 8 || (size & (size - 1))) return 0; - } else if (size > 4) { - ret->ref = NULL; + if (size == 8) ret->t = VT_LLONG; - return 1; - } else { - ret->ref = NULL; + else if (size == 4) ret->t = VT_INT; - return 1; - } + else if (size == 2) + ret->t = VT_SHORT; + else + ret->t = VT_BYTE; + ret->ref = NULL; + return 1; #else *ret_align = 1; // Never have to re-align return values for x86 return 0; @@ -547,7 +547,8 @@ ST_FUNC void gfunc_prolog(CType *func_type) func_var = (sym->c == FUNC_ELLIPSIS); #ifdef TCC_TARGET_PE size = type_size(&func_vt,&align); - if (((func_vt.t & VT_BTYPE) == VT_STRUCT) && (size > 8)) { + if (((func_vt.t & VT_BTYPE) == VT_STRUCT) + && (size > 8 || (size & (size - 1)))) { #else if ((func_vt.t & VT_BTYPE) == VT_STRUCT) { #endif |
