tccgen: update "Fix invalid load generated by gfunc_return()"

tccgen.c:
- new function incr_offset(int) to increment a lvalue
- use it in gv/vstore to load/store from/to two-word types
- use it to advance the pointer to struct fields
- use it to load/store structs passed in registers
- structs: always assume that reg-classes of registers are 2^n
- adjust stack space when regsize > sizeof the_struct

x86_64-gen.c:
- return regsize=16 for VT_QLONG/QFLOAT

i386-gen.c:
- pass structs of size(8) as two VT_INT rather than one VT_LLONG
  (both should work now)

fixes a82aff3337
fixes fd6d2180c5 (slightly)
This commit is contained in:
grischka
2023-07-31 11:43:15 +02:00
parent 022fb4293b
commit c29420ab0d
5 changed files with 154 additions and 100 deletions

View File

@@ -1,49 +1,70 @@
#include<stdio.h>
#define DATA 0x1234567890abcdll, 0x5a5aa5a5f0f00f0fll
struct s1 {
unsigned char a:4, b:4;
} g1 = { 0x05, 0x0a };
struct s {
long long int a;
long long int b;
};
struct s2 {
unsigned char a, b;
} g2 = { 0x12, 0x34 };
struct {
struct s d;
} g = { { DATA } }, *gp = &g;
struct s4 {
unsigned short a, b;
} g4 = { 0x1245, 0x5678 };
struct s
foo1(void)
{
struct s d = { DATA };
struct s *p = &d;
long long int x = 0;
return *p;
struct s8 {
unsigned a, b;
} g8 = { 0x12345678, 0x9abcdef0 };
/* returned in 2 registers on riscv64 */
struct s16 {
unsigned long long a, b;
} g16 = { 0x123456789abcdef0ULL, 0xfedcba9876543210ULL };
/* Homogeneous float aggregate on ARM hard-float */
struct s_f4 {
double a, b, c, d;
} g_f4 = { 1,2,3,4 };
#define def(S) \
struct s##S f##S(int x) \
{ \
struct s##S l##S = g##S, *p##S = &l##S; \
if (x == 0) \
return g##S; \
else if (x == 1) \
return l##S; \
else \
return *p##S; \
}
struct s
foo2(void)
{
long long int unused = 0;
return gp->d;
}
def(1)
def(2)
def(4)
def(8)
def(16)
def(_f4)
struct s
foo3(void)
{
struct s d = { DATA };
long long int unused = 0;
return d;
}
#define chk(S,x) \
struct s##S l##S = f##S(x); \
printf("%02llx %02llx\n", \
(unsigned long long)l##S.a, \
(unsigned long long)l##S.b \
);
int
main(void)
int main()
{
struct s d;
d = foo1();
printf("%llx %llx\n", d.a, d.b);
d = foo2();
printf("%llx %llx\n", d.a, d.b);
d = foo3();
printf("%llx %llx\n", d.a, d.b);
return 0;
for (int x = 0;;) {
chk(1,x);
chk(2,x);
chk(4,x);
chk(8,x);
chk(16,x);
struct s_f4 l_f4 = f_f4(x);
printf("%.1f %.1f %.1f %.1f\n", l_f4.a, l_f4.b, l_f4.c, l_f4.d);
if (++x > 2)
break;
printf("\n");
}
return 0;
}

View File

@@ -1,3 +1,20 @@
1234567890abcd 5a5aa5a5f0f00f0f
1234567890abcd 5a5aa5a5f0f00f0f
1234567890abcd 5a5aa5a5f0f00f0f
05 0a
12 34
1245 5678
12345678 9abcdef0
123456789abcdef0 fedcba9876543210
1.0 2.0 3.0 4.0
05 0a
12 34
1245 5678
12345678 9abcdef0
123456789abcdef0 fedcba9876543210
1.0 2.0 3.0 4.0
05 0a
12 34
1245 5678
12345678 9abcdef0
123456789abcdef0 fedcba9876543210
1.0 2.0 3.0 4.0