mirror of
https://github.com/mirror/tinycc.git
synced 2026-08-22 11:23:27 +08:00
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) fixesa82aff3337fixesfd6d2180c5(slightly)
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user