From 2b867cd198633ef4bb4e994f2e54d061ea8b5e6d Mon Sep 17 00:00:00 2001 From: Ast-x64 Date: Wed, 22 Jun 2022 02:36:13 +0800 Subject: [PATCH] RISCV: Fix vararg implementation Fixing previous wrong implementation according to RISCV Calling Convention. Arguments larger than 2*XLEN bits are replaced by the address, and others with 2*XLEN-bit alignment should be aligned in register or stack. --- src/core/stdc/stdarg.d | 9 ++++++++- src/core/vararg.d | 10 +++++++++- 2 files changed, 17 insertions(+), 2 deletions(-) diff --git a/src/core/stdc/stdarg.d b/src/core/stdc/stdarg.d index 19a6fc0eec..646905eaff 100644 --- a/src/core/stdc/stdarg.d +++ b/src/core/stdc/stdarg.d @@ -269,7 +269,14 @@ T va_arg(T)(ref va_list ap) } else version (RISCV_Any) { - auto p = cast(T*) ap; + static if (T.sizeof > (size_t.sizeof << 1)) + auto p = *cast(T**) ap; + else + { + static if (T.alignof == (size_t.sizeof << 1)) + ap = ap.alignUp!(size_t.sizeof << 1); + auto p = cast(T*) ap; + } ap += T.sizeof.alignUp; return *p; } diff --git a/src/core/vararg.d b/src/core/vararg.d index 9ad572e4d8..2c3e9659fb 100644 --- a/src/core/vararg.d +++ b/src/core/vararg.d @@ -141,7 +141,15 @@ void va_arg()(ref va_list ap, TypeInfo ti, void* parmn) else version (RISCV_Any) { const tsize = ti.tsize; - auto p = cast(void*) ap; + void* p; + if (tsize > (size_t.sizeof << 1)) + p = *cast(void**) ap; + else + { + if (tsize == (size_t.sizeof << 1)) + ap = ap.alignUp!(size_t.sizeof << 1); + p = cast(void*) ap; + } ap += tsize.alignUp; parmn[0..tsize] = p[0..tsize]; }