mirror of
git://repo.or.cz/tinycc.git
synced 2026-06-19 11:24:19 +08:00
Riscv struct saving
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
Some checks are pending
build and test / test-x86_64-linux (push) Waiting to run
build and test / test-x86_64-osx (push) Waiting to run
build and test / test-aarch64-osx (push) Waiting to run
build and test / test-x86_64-win32 (push) Waiting to run
build and test / test-i386-win32 (push) Waiting to run
build and test / test-armv7-linux (push) Waiting to run
build and test / test-aarch64-linux (push) Waiting to run
build and test / test-riscv64-linux (push) Waiting to run
While adding some testcases for attribute cleanup I found a bug in the riscv code. It modifies the sv->c.i in load_symofs. If a structure contains more then one element only the first is stored correctly. This only happens on a large stack frame. Fixed by saving/restoring sv->c.i.
This commit is contained in:
parent
9670d10294
commit
7c23c48a93
@ -233,6 +233,7 @@ ST_FUNC void load(int r, SValue *sv)
|
||||
int v = fr & VT_VALMASK;
|
||||
int rr = is_ireg(r) ? ireg(r) : freg(r);
|
||||
int fc = sv->c.i;
|
||||
int save_fc = fc;
|
||||
int bt = sv->type.t & VT_BTYPE;
|
||||
int align, size;
|
||||
if (fr & VT_LVAL) {
|
||||
@ -370,6 +371,7 @@ ST_FUNC void load(int r, SValue *sv)
|
||||
EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
|
||||
} else
|
||||
tcc_error("unimp: load(non-const)");
|
||||
sv->c.i = save_fc;
|
||||
}
|
||||
|
||||
ST_FUNC void store(int r, SValue *sv)
|
||||
@ -377,6 +379,7 @@ ST_FUNC void store(int r, SValue *sv)
|
||||
int fr = sv->r & VT_VALMASK;
|
||||
int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;
|
||||
int fc = sv->c.i;
|
||||
int save_fc = fc;
|
||||
int bt = sv->type.t & VT_BTYPE;
|
||||
int align, size = type_size(&sv->type, &align);
|
||||
assert(!is_float(bt) || is_freg(r) || bt == VT_LDOUBLE);
|
||||
@ -413,6 +416,7 @@ ST_FUNC void store(int r, SValue *sv)
|
||||
ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...
|
||||
size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]
|
||||
ptrreg, rr, fc); // RR, fc(base)
|
||||
sv->c.i = save_fc;
|
||||
}
|
||||
|
||||
static void gcall_or_jmp(int docall)
|
||||
|
||||
@ -5,6 +5,8 @@ typedef struct { int a; int b; int c; int d; int e; int f; int g; int h; } tstl;
|
||||
typedef struct { int a; int b; int c; int d; } tsti;
|
||||
typedef struct { double a; double b; } tstd;
|
||||
typedef struct { long double a; } tstld;
|
||||
typedef struct { int a; double b; } tstm;
|
||||
typedef struct { float a; float b; float c; float d; } tstf;
|
||||
|
||||
void incr_glob_i(int *i)
|
||||
{
|
||||
@ -258,6 +260,44 @@ tstld test_cleanup5(void) {
|
||||
return n;
|
||||
}
|
||||
|
||||
void my_cleanup6(tstm *p) {
|
||||
printf("%d %g\n", p->a, p->b);
|
||||
p->a = 90;
|
||||
p->b = 91.0;
|
||||
}
|
||||
|
||||
tstm test_cleanup6(void) {
|
||||
tstm __attribute__((cleanup(my_cleanup6))) n;
|
||||
n.a = 42;
|
||||
n.b = 43.0;
|
||||
return n;
|
||||
}
|
||||
|
||||
void my_cleanup7(tstf *p) {
|
||||
printf("%f %f %f %f\n", p->a, p->b, p->c, p->d);
|
||||
p->a = 0x90; p->b = 0x91; p->c = 0x92; p->d = 0x93;
|
||||
}
|
||||
|
||||
tstf test_cleanup7(void) {
|
||||
tstf __attribute__((cleanup(my_cleanup7))) n;
|
||||
n.a = 42; n.b = 43; n.c = 44; n.d = 45;
|
||||
return n;
|
||||
}
|
||||
|
||||
void my_cleanup8(int **p) {
|
||||
**p = 0x90;
|
||||
}
|
||||
|
||||
int test_cleanup8(void) {
|
||||
int n = 42;
|
||||
int __attribute__((cleanup(my_cleanup8))) *p = &n;
|
||||
return n;
|
||||
}
|
||||
|
||||
static void my_cleanupe(int *p) {
|
||||
*p = 0x90;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
int i __attribute__ ((__cleanup__(check))) = 0, not_i;
|
||||
@ -267,6 +307,8 @@ int main()
|
||||
tsti ti;
|
||||
tstd td;
|
||||
tstld tld;
|
||||
tstm tm;
|
||||
tstf tf;
|
||||
|
||||
{
|
||||
__attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'o', o = 'a';
|
||||
@ -299,6 +341,14 @@ int main()
|
||||
printf("%g %g\n", td.a, td.b);
|
||||
tld = test_cleanup5();
|
||||
printf("%Lf\n", tld.a);
|
||||
tm = test_cleanup6();
|
||||
printf("%d %g\n", tm.a, tm.b);
|
||||
tf = test_cleanup7();
|
||||
printf("%f %f %f %f\n", tf.a, tf.b, tf.c, tf.d);
|
||||
printf("%d\n", test_cleanup8());
|
||||
printf("%d\n", ({
|
||||
int __attribute__ ((cleanup(my_cleanupe))) n = 42;
|
||||
n; }));
|
||||
return i;
|
||||
}
|
||||
|
||||
|
||||
@ -58,6 +58,12 @@ after break
|
||||
42 43
|
||||
42.000000
|
||||
42.000000
|
||||
42 43
|
||||
42 43
|
||||
42.000000 43.000000 44.000000 45.000000
|
||||
42.000000 43.000000 44.000000 45.000000
|
||||
42
|
||||
42
|
||||
---- 0
|
||||
---- 1
|
||||
str: plop
|
||||
|
||||
Loading…
Reference in New Issue
Block a user