History

Riscv struct saving

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.

herman ten brugge committed 1 year ago

Commit 7c23c481 parent 9670d103 files · +60 −0Browse files

Unified · Split

3 files
  1. riscv64-gen.c +4 −0
  2. tests/tests2/101_cleanup.c +50 −0
  3. tests/tests2/101_cleanup.expect +6 −0
riscv64-gen.c+4−0
@@ -233,6 +233,7 @@ ST_FUNC void load(int r, SValue *sv) · 232 unmodified lines
233 int v = fr & VT_VALMASK;233 int v = fr & VT_VALMASK;
234 int rr = is_ireg(r) ? ireg(r) : freg(r);234 int rr = is_ireg(r) ? ireg(r) : freg(r);
235 int fc = sv->c.i;235 int fc = sv->c.i;
236 int save_fc = fc;
236 int bt = sv->type.t & VT_BTYPE;237 int bt = sv->type.t & VT_BTYPE;
237 int align, size;238 int align, size;
238 if (fr & VT_LVAL) {239 if (fr & VT_LVAL) {
@@ -370,6 +371,7 @@ ST_FUNC void load(int r, SValue *sv) · 131 unmodified lines
370 EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t371 EI(0x13, 0, rr, 0, t ^ 1); // addi RR, x0, !t
371 } else372 } else
372 tcc_error("unimp: load(non-const)");373 tcc_error("unimp: load(non-const)");
374 sv->c.i = save_fc;
373}375}
374 376
375ST_FUNC void store(int r, SValue *sv)377ST_FUNC void store(int r, SValue *sv)
@@ -377,6 +379,7 @@ ST_FUNC void store(int r, SValue *sv) · 1 unmodified line
377 int fr = sv->r & VT_VALMASK;379 int fr = sv->r & VT_VALMASK;
378 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;380 int rr = is_ireg(r) ? ireg(r) : freg(r), ptrreg;
379 int fc = sv->c.i;381 int fc = sv->c.i;
382 int save_fc = fc;
380 int bt = sv->type.t & VT_BTYPE;383 int bt = sv->type.t & VT_BTYPE;
381 int align, size = type_size(&sv->type, &align);384 int align, size = type_size(&sv->type, &align);
382 assert(!is_float(bt) || is_freg(r) || bt == VT_LDOUBLE);385 assert(!is_float(bt) || is_freg(r) || bt == VT_LDOUBLE);
@@ -413,6 +416,7 @@ ST_FUNC void store(int r, SValue *sv) · 30 unmodified lines
413 ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...416 ES(is_freg(r) ? 0x27 : 0x23, // fs... | s...
414 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]417 size == 1 ? 0 : size == 2 ? 1 : size == 4 ? 2 : 3, // ... [wd] | [bhwd]
415 ptrreg, rr, fc); // RR, fc(base)418 ptrreg, rr, fc); // RR, fc(base)
419 sv->c.i = save_fc;
416}420}
417 421
418static void gcall_or_jmp(int docall)422static void gcall_or_jmp(int docall)
tests/tests2/101_cleanup.c+50−0
@@ -5,6 +5,8 @@ typedef struct { int a; int b; int c; int d; int e; int f; int g; int h; } tstl; · 4 unmodified lines
5typedef struct { int a; int b; int c; int d; } tsti;5typedef struct { int a; int b; int c; int d; } tsti;
6typedef struct { double a; double b; } tstd;6typedef struct { double a; double b; } tstd;
7typedef struct { long double a; } tstld;7typedef struct { long double a; } tstld;
8typedef struct { int a; double b; } tstm;
9typedef struct { float a; float b; float c; float d; } tstf;
8 10
9void incr_glob_i(int *i)11void incr_glob_i(int *i)
10{12{
@@ -258,6 +260,44 @@ tstld test_cleanup5(void) { · 247 unmodified lines
258 return n;260 return n;
259}261}
260 262
263void my_cleanup6(tstm *p) {
264 printf("%d %g\n", p->a, p->b);
265 p->a = 90;
266 p->b = 91.0;
267}
268
269tstm test_cleanup6(void) {
270 tstm __attribute__((cleanup(my_cleanup6))) n;
271 n.a = 42;
272 n.b = 43.0;
273 return n;
274}
275
276void my_cleanup7(tstf *p) {
277 printf("%f %f %f %f\n", p->a, p->b, p->c, p->d);
278 p->a = 0x90; p->b = 0x91; p->c = 0x92; p->d = 0x93;
279}
280
281tstf test_cleanup7(void) {
282 tstf __attribute__((cleanup(my_cleanup7))) n;
283 n.a = 42; n.b = 43; n.c = 44; n.d = 45;
284 return n;
285}
286
287void my_cleanup8(int **p) {
288 **p = 0x90;
289}
290
291int test_cleanup8(void) {
292 int n = 42;
293 int __attribute__((cleanup(my_cleanup8))) *p = &n;
294 return n;
295}
296
297static void my_cleanupe(int *p) {
298 *p = 0x90;
299}
300
261int main()301int main()
262{302{
263 int i __attribute__ ((__cleanup__(check))) = 0, not_i;303 int i __attribute__ ((__cleanup__(check))) = 0, not_i;
@@ -267,6 +307,8 @@ int main() · 3 unmodified lines
267 tsti ti;307 tsti ti;
268 tstd td;308 tstd td;
269 tstld tld;309 tstld tld;
310 tstm tm;
311 tstf tf;
270 312
271 {313 {
272 __attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'o', o = 'a';314 __attribute__ ((__cleanup__(check_oh_i))) char oh_i = 'o', o = 'a';
@@ -299,6 +341,14 @@ int main() · 26 unmodified lines
299 printf("%g %g\n", td.a, td.b);341 printf("%g %g\n", td.a, td.b);
300 tld = test_cleanup5();342 tld = test_cleanup5();
301 printf("%Lf\n", tld.a);343 printf("%Lf\n", tld.a);
344 tm = test_cleanup6();
345 printf("%d %g\n", tm.a, tm.b);
346 tf = test_cleanup7();
347 printf("%f %f %f %f\n", tf.a, tf.b, tf.c, tf.d);
348 printf("%d\n", test_cleanup8());
349 printf("%d\n", ({
350 int __attribute__ ((cleanup(my_cleanupe))) n = 42;
351 n; }));
302 return i;352 return i;
303}353}
304 354
tests/tests2/101_cleanup.expect+6−0
@@ -58,6 +58,12 @@ after break · 57 unmodified lines
5842 435842 43
5942.0000005942.000000
6042.0000006042.000000
6142 43
6242 43
6342.000000 43.000000 44.000000 45.000000
6442.000000 43.000000 44.000000 45.000000
6542
6642
61---- 067---- 0
62---- 168---- 1
63str: plop69str: plop

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t