diff options
author | Michael Forney <mforney@mforney.org> | 2021-09-07 12:50:50 -0700 |
---|---|---|
committer | Michael Forney <mforney@mforney.org> | 2021-09-07 13:19:19 -0700 |
commit | 97c8fc5358bbecb6e2452425861e6cd5a5c93f91 (patch) | |
tree | 8bebb448e9c460072bf4e2aa52dce138d9ffcd1c | |
parent | 056c471bb7f85854e2af7a0166785d06820b251a (diff) |
expr: Fix varargs again and add more tests
-rw-r--r-- | expr.c | 12 | ||||
-rw-r--r-- | test/builtin-va-copy+x86_64.c | 9 | ||||
-rw-r--r-- | test/builtin-va-copy+x86_64.qbe | 44 | ||||
l---------[-rw-r--r--] | test/varargs+aarch64.c | 13 | ||||
-rw-r--r-- | test/varargs+aarch64.qbe | 39 | ||||
l---------[-rw-r--r--] | test/varargs+riscv64.c | 13 | ||||
-rw-r--r-- | test/varargs+riscv64.qbe | 41 | ||||
-rw-r--r-- | test/varargs+x86_64.c | 16 | ||||
-rw-r--r-- | test/varargs+x86_64.qbe | 41 | ||||
-rw-r--r-- | test/varargs-pass-valist+aarch64.c | 5 | ||||
-rw-r--r-- | test/varargs-pass-valist+aarch64.qbe | 9 | ||||
-rw-r--r-- | test/varargs-pass-valist+riscv64.c | 5 | ||||
-rw-r--r-- | test/varargs-pass-valist+riscv64.qbe | 9 | ||||
-rw-r--r-- | test/varargs-pass-valist+x86_64.c | 5 | ||||
-rw-r--r-- | test/varargs-pass-valist+x86_64.qbe | 8 |
15 files changed, 174 insertions, 95 deletions
@@ -645,7 +645,7 @@ builtinfunc(struct scope *s, enum builtinkind kind) e->base = assignexpr(s); if (!typesame(e->base->type, typeadjvalist)) error(&tok.loc, "va_arg argument must have type va_list"); - if (!e->base->decayed) + if (typeadjvalist == targ->typevalist) e->base = mkunaryexpr(TBAND, e->base); expect(TCOMMA, "after va_list"); e->type = typename(s, &e->qual); @@ -655,14 +655,14 @@ builtinfunc(struct scope *s, enum builtinkind kind) e->assign.l = assignexpr(s); if (!typesame(e->assign.l->type, typeadjvalist)) error(&tok.loc, "va_copy destination must have type va_list"); - if (e->assign.l->decayed) - e->assign.l = e->assign.l->base; + if (typeadjvalist != targ->typevalist) + e->assign.l = mkunaryexpr(TMUL, e->assign.l); expect(TCOMMA, "after target va_list"); e->assign.r = assignexpr(s); if (!typesame(e->assign.r->type, typeadjvalist)) error(&tok.loc, "va_copy source must have type va_list"); - if (e->assign.r->decayed) - e->assign.r = e->assign.r->base; + if (typeadjvalist != targ->typevalist) + e->assign.r = mkunaryexpr(TMUL, e->assign.r); break; case BUILTINVAEND: e = assignexpr(s); @@ -677,7 +677,7 @@ builtinfunc(struct scope *s, enum builtinkind kind) e->base = assignexpr(s); if (!typesame(e->base->type, typeadjvalist)) error(&tok.loc, "va_start argument must have type va_list"); - if (!e->base->decayed) + if (typeadjvalist == targ->typevalist) e->base = mkunaryexpr(TBAND, e->base); expect(TCOMMA, "after va_list"); param = assignexpr(s); diff --git a/test/builtin-va-copy+x86_64.c b/test/builtin-va-copy+x86_64.c index 7a69596..48577ed 100644 --- a/test/builtin-va-copy+x86_64.c +++ b/test/builtin-va-copy+x86_64.c @@ -1,4 +1,11 @@ -void f(void) { +void f1(void) { static __builtin_va_list a, b; __builtin_va_copy(a, b); } +void f2(__builtin_va_list b) { + static __builtin_va_list a; + __builtin_va_copy(a, b); +} +void f3(__builtin_va_list a, __builtin_va_list b) { + __builtin_va_copy(a, b); +} diff --git a/test/builtin-va-copy+x86_64.qbe b/test/builtin-va-copy+x86_64.qbe index 47e1d9e..de2fa5a 100644 --- a/test/builtin-va-copy+x86_64.qbe +++ b/test/builtin-va-copy+x86_64.qbe @@ -1,7 +1,7 @@ data $.La.2 = align 8 { z 24 } data $.Lb.3 = align 8 { z 24 } export -function $f() { +function $f1() { @start.1 @body.2 %.1 =l loadl $.Lb.3 @@ -16,3 +16,45 @@ function $f() { storel %.7, %.6 ret } +data $.La.5 = align 8 { z 24 } +export +function $f2(l %.1) { +@start.3 + %.2 =l alloc8 8 + storel %.1, %.2 +@body.4 + %.3 =l loadl %.2 + %.4 =l loadl %.3 + storel %.4, $.La.5 + %.5 =l add %.3, 8 + %.6 =l add $.La.5, 8 + %.7 =l loadl %.5 + storel %.7, %.6 + %.8 =l add %.5, 8 + %.9 =l add %.6, 8 + %.10 =l loadl %.8 + storel %.10, %.9 + ret +} +export +function $f3(l %.1, l %.3) { +@start.5 + %.2 =l alloc8 8 + storel %.1, %.2 + %.4 =l alloc8 8 + storel %.3, %.4 +@body.6 + %.5 =l loadl %.4 + %.6 =l loadl %.2 + %.7 =l loadl %.5 + storel %.7, %.6 + %.8 =l add %.5, 8 + %.9 =l add %.6, 8 + %.10 =l loadl %.8 + storel %.10, %.9 + %.11 =l add %.8, 8 + %.12 =l add %.9, 8 + %.13 =l loadl %.11 + storel %.13, %.12 + ret +} diff --git a/test/varargs+aarch64.c b/test/varargs+aarch64.c index 0b5a73d..c9c990c 100644..120000 --- a/test/varargs+aarch64.c +++ b/test/varargs+aarch64.c @@ -1,12 +1 @@ -void f(int n, ...) { - __builtin_va_list ap; - - __builtin_va_start(ap, n); - while (n) { - __builtin_va_arg(ap, int); - __builtin_va_arg(ap, float); - __builtin_va_arg(ap, char *); - --n; - } - __builtin_va_end(ap); -} +varargs+x86_64.c
\ No newline at end of file diff --git a/test/varargs+aarch64.qbe b/test/varargs+aarch64.qbe index 512a8c7..5b6e830 100644 --- a/test/varargs+aarch64.qbe +++ b/test/varargs+aarch64.qbe @@ -1,22 +1,47 @@ +type :va_list.1 = align 8 { 32 } export -function $f(w %.1, ...) { +function w $f1(w %.1, :va_list.1 %.3) { @start.1 %.2 =l alloc4 4 storew %.1, %.2 - %.3 =l alloc8 32 @body.2 + %.4 =w vaarg %.3 + ret %.4 +} +export +function w $f2(w %.1, ...) { +@start.3 + %.2 =l alloc4 4 + storew %.1, %.2 + %.3 =l alloc4 4 + %.4 =l alloc8 32 +@body.4 + vastart %.4 + %.5 =w loadw %.2 + %.6 =w call $f1(w %.5, :va_list.1 %.4) + storew %.6, %.3 + %.7 =w loadw %.3 + ret %.7 +} +export +function $f3(w %.1, ...) { +@start.5 + %.2 =l alloc4 4 + storew %.1, %.2 + %.3 =l alloc8 32 +@body.6 vastart %.3 -@while_cond.3 +@while_cond.7 %.4 =w loadw %.2 - jnz %.4, @while_body.4, @while_join.5 -@while_body.4 + jnz %.4, @while_body.8, @while_join.9 +@while_body.8 %.5 =w vaarg %.3 %.6 =s vaarg %.3 %.7 =l vaarg %.3 %.8 =w loadw %.2 %.9 =w sub %.8, 1 storew %.9, %.2 - jmp @while_cond.3 -@while_join.5 + jmp @while_cond.7 +@while_join.9 ret } diff --git a/test/varargs+riscv64.c b/test/varargs+riscv64.c index 0b5a73d..c9c990c 100644..120000 --- a/test/varargs+riscv64.c +++ b/test/varargs+riscv64.c @@ -1,12 +1 @@ -void f(int n, ...) { - __builtin_va_list ap; - - __builtin_va_start(ap, n); - while (n) { - __builtin_va_arg(ap, int); - __builtin_va_arg(ap, float); - __builtin_va_arg(ap, char *); - --n; - } - __builtin_va_end(ap); -} +varargs+x86_64.c
\ No newline at end of file diff --git a/test/varargs+riscv64.qbe b/test/varargs+riscv64.qbe index 7fcda8d..a918014 100644 --- a/test/varargs+riscv64.qbe +++ b/test/varargs+riscv64.qbe @@ -1,22 +1,49 @@ export -function $f(w %.1, ...) { +function w $f1(w %.1, l %.3) { @start.1 %.2 =l alloc4 4 storew %.1, %.2 - %.3 =l alloc8 8 + %.4 =l alloc8 8 + storel %.3, %.4 @body.2 + %.5 =w vaarg %.4 + ret %.5 +} +export +function w $f2(w %.1, ...) { +@start.3 + %.2 =l alloc4 4 + storew %.1, %.2 + %.3 =l alloc4 4 + %.4 =l alloc8 8 +@body.4 + vastart %.4 + %.5 =w loadw %.2 + %.6 =l loadl %.4 + %.7 =w call $f1(w %.5, l %.6) + storew %.7, %.3 + %.8 =w loadw %.3 + ret %.8 +} +export +function $f3(w %.1, ...) { +@start.5 + %.2 =l alloc4 4 + storew %.1, %.2 + %.3 =l alloc8 8 +@body.6 vastart %.3 -@while_cond.3 +@while_cond.7 %.4 =w loadw %.2 - jnz %.4, @while_body.4, @while_join.5 -@while_body.4 + jnz %.4, @while_body.8, @while_join.9 +@while_body.8 %.5 =w vaarg %.3 %.6 =s vaarg %.3 %.7 =l vaarg %.3 %.8 =w loadw %.2 %.9 =w sub %.8, 1 storew %.9, %.2 - jmp @while_cond.3 -@while_join.5 + jmp @while_cond.7 +@while_join.9 ret } diff --git a/test/varargs+x86_64.c b/test/varargs+x86_64.c index 0b5a73d..71bf1d3 100644 --- a/test/varargs+x86_64.c +++ b/test/varargs+x86_64.c @@ -1,4 +1,18 @@ -void f(int n, ...) { +int f1(int n, __builtin_va_list ap) { + return __builtin_va_arg(ap, int); +} + +int f2(int n, ...) { + int r; + __builtin_va_list ap; + + __builtin_va_start(ap, n); + r = f1(n, ap); + __builtin_va_end(ap); + return r; +} + +void f3(int n, ...) { __builtin_va_list ap; __builtin_va_start(ap, n); diff --git a/test/varargs+x86_64.qbe b/test/varargs+x86_64.qbe index 641afa1..46904b6 100644 --- a/test/varargs+x86_64.qbe +++ b/test/varargs+x86_64.qbe @@ -1,22 +1,49 @@ export -function $f(w %.1, ...) { +function w $f1(w %.1, l %.3) { @start.1 %.2 =l alloc4 4 storew %.1, %.2 - %.3 =l alloc8 24 + %.4 =l alloc8 8 + storel %.3, %.4 @body.2 + %.5 =l loadl %.4 + %.6 =w vaarg %.5 + ret %.6 +} +export +function w $f2(w %.1, ...) { +@start.3 + %.2 =l alloc4 4 + storew %.1, %.2 + %.3 =l alloc4 4 + %.4 =l alloc8 24 +@body.4 + vastart %.4 + %.5 =w loadw %.2 + %.6 =w call $f1(w %.5, l %.4) + storew %.6, %.3 + %.7 =w loadw %.3 + ret %.7 +} +export +function $f3(w %.1, ...) { +@start.5 + %.2 =l alloc4 4 + storew %.1, %.2 + %.3 =l alloc8 24 +@body.6 vastart %.3 -@while_cond.3 +@while_cond.7 %.4 =w loadw %.2 - jnz %.4, @while_body.4, @while_join.5 -@while_body.4 + jnz %.4, @while_body.8, @while_join.9 +@while_body.8 %.5 =w vaarg %.3 %.6 =s vaarg %.3 %.7 =l vaarg %.3 %.8 =w loadw %.2 %.9 =w sub %.8, 1 storew %.9, %.2 - jmp @while_cond.3 -@while_join.5 + jmp @while_cond.7 +@while_join.9 ret } diff --git a/test/varargs-pass-valist+aarch64.c b/test/varargs-pass-valist+aarch64.c deleted file mode 100644 index c1ede84..0000000 --- a/test/varargs-pass-valist+aarch64.c +++ /dev/null @@ -1,5 +0,0 @@ -void f(__builtin_va_list ap); -void g(void) { - static __builtin_va_list ap; - f(ap); -} diff --git a/test/varargs-pass-valist+aarch64.qbe b/test/varargs-pass-valist+aarch64.qbe deleted file mode 100644 index 67cef8a..0000000 --- a/test/varargs-pass-valist+aarch64.qbe +++ /dev/null @@ -1,9 +0,0 @@ -data $.Lap.2 = align 8 { z 32 } -type :va_list.1 = align 8 { 32 } -export -function $g() { -@start.1 -@body.2 - call $f(:va_list.1 $.Lap.2) - ret -} diff --git a/test/varargs-pass-valist+riscv64.c b/test/varargs-pass-valist+riscv64.c deleted file mode 100644 index c1ede84..0000000 --- a/test/varargs-pass-valist+riscv64.c +++ /dev/null @@ -1,5 +0,0 @@ -void f(__builtin_va_list ap); -void g(void) { - static __builtin_va_list ap; - f(ap); -} diff --git a/test/varargs-pass-valist+riscv64.qbe b/test/varargs-pass-valist+riscv64.qbe deleted file mode 100644 index 937f50a..0000000 --- a/test/varargs-pass-valist+riscv64.qbe +++ /dev/null @@ -1,9 +0,0 @@ -data $.Lap.2 = align 8 { z 8 } -export -function $g() { -@start.1 -@body.2 - %.1 =l loadl $.Lap.2 - call $f(l %.1) - ret -} diff --git a/test/varargs-pass-valist+x86_64.c b/test/varargs-pass-valist+x86_64.c deleted file mode 100644 index c1ede84..0000000 --- a/test/varargs-pass-valist+x86_64.c +++ /dev/null @@ -1,5 +0,0 @@ -void f(__builtin_va_list ap); -void g(void) { - static __builtin_va_list ap; - f(ap); -} diff --git a/test/varargs-pass-valist+x86_64.qbe b/test/varargs-pass-valist+x86_64.qbe deleted file mode 100644 index 50d9283..0000000 --- a/test/varargs-pass-valist+x86_64.qbe +++ /dev/null @@ -1,8 +0,0 @@ -data $.Lap.2 = align 8 { z 24 } -export -function $g() { -@start.1 -@body.2 - call $f(l $.Lap.2) - ret -} |