aboutsummaryrefslogtreecommitdiff
path: root/i386-gen.c
diff options
context:
space:
mode:
authorgrischka <grischka>2017-02-08 19:45:31 +0100
committergrischka <grischka>2017-02-08 19:45:31 +0100
commit68666eee2ade45ab73b07361367d0a38d350d663 (patch)
tree1cb0bdc6b04665e96ba563a137bea20bf909fdca /i386-gen.c
parentf077d16c20c524d7db8cb38a9193242eeade343d (diff)
downloadtinycc-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.c21
1 files changed, 11 insertions, 10 deletions
diff --git a/i386-gen.c b/i386-gen.c
index 7d9c3d0..759f33c 100644
--- a/i386-gen.c
+++ b/i386-gen.c
@@ -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