diff options
| author | 2025-12-02 14:27:14 +0100 | |
|---|---|---|
| committer | 2025-12-02 14:27:14 +0100 | |
| commit | 3c6e4dd54d5c144369b96d6673da7f23df4940da (patch) | |
| tree | 6f331c91187641c15aeef23f21e456fdc09561ec | |
| parent | c14321c4d35549d989d614437953b36b8c771cc2 (diff) | |
test/11-abi
| -rw-r--r-- | amd64/isel.c | 15 | ||||
| -rw-r--r-- | test/11-abi.c | 37 |
2 files changed, 46 insertions, 6 deletions
diff --git a/amd64/isel.c b/amd64/isel.c index 3611670..9634103 100644 --- a/amd64/isel.c +++ b/amd64/isel.c @@ -68,8 +68,8 @@ fixarg(union ref *r, struct instr *ins, struct block *blk, int *curi) /* add X, INT32MAX+1 -> sub X, INT32MIN */ ins->op = Oadd + (op == Oadd); *r = mkintcon(KI32, -2147483648); - } else if (kisflt(con->cls) && con->f == 0) { - /* copy of float zero -> regular zero, that emit() will turn into xor x,x */ + } else if (kisflt(con->cls) && con->i == 0) { + /* copy of positive float zero -> regular zero, that emit() will turn into xor x,x */ if (in_range(op, Ocopy, Omove) || op == Ophi) *r = ZEROREF; else @@ -176,10 +176,13 @@ selcall(struct function *fn, struct instr *ins, struct block *blk, int *curi) /* duplicate to reuse same TMP ref */ insertinstr(blk, (*curi)++, *ins); *ins = mkinstr(Ocopy, cls, mkref(RREG, call->abiret[0].reg)); - if (*curi + 1 < blk->ins.n) - if (instrtab[blk->ins.p[*curi + 1]].op == Ocall2r) { - ins = &instrtab[blk->ins.p[++*curi]]; - *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, call->abiret[1].reg)); + for (int i = 1; i <= 2; ++i) { + if (*curi + i >= blk->ins.n) break; + if (instrtab[blk->ins.p[*curi + i]].op == Ocall2r) { + ins = &instrtab[blk->ins.p[*curi += i]]; + *ins = mkinstr(Ocopy, ins->cls, mkref(RREG, call->abiret[1].reg)); + break; + } } } } diff --git a/test/11-abi.c b/test/11-abi.c new file mode 100644 index 0000000..895b3ba --- /dev/null +++ b/test/11-abi.c @@ -0,0 +1,37 @@ +/* EXPECT: +1 2 3 4 5 6 (nil) 9 abcdef +: 10, 20 +1.000000 2.000000 3.000000 {4.000000,5.000000} -0.000000(80000000h) 99.000000 +: -1.000000 +*/ + +#include <stdio.h> + +struct l { short s[10]; }; +struct x { long p; }; +struct ll { long a, b; }; + +struct ll f(int a, int b, struct l c, int d, int e, int f, void *g, struct x x, char *s) { + printf("%d %d %d %d ", a, b, c.s[0], d); + printf("%d %d %p %ld %s\n", e, f, g, x.p, s); + return (struct ll){10,20}; +} + +struct f2 { float f[2]; }; +union fi { float f; int i; }; + +struct hs { float x[10]; }; + +struct hs g(float a, float b, float c, struct f2 d, union fi e, double z) { + printf("%f %f %f {%f,%f} ", a, b, c, d.f[0], d.f[1]); + printf("%f(%xh) %f\n", e.f, e.i, z); + return (struct hs){-1.0f}; +} + +int main() { + struct ll a = f(1,2,(struct l){3},4,5,6, NULL, (struct x){9}, "abcdef"); + printf(": %ld, %ld\n", a.a, a.b); + struct hs h = g(1.0f, 2.0, 3.0f, (struct f2){4.0,5.0}, (union fi){-0.0f}, 99.f); + printf(": %f\n", h.x[0]); +} + |