From 80e6afd33522d4583f0753b85e4b75da0b79ebee Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Fri, 19 May 2017 14:20:04 +0300 Subject: [PATCH 1/4] Add two new trampoline test cases --- test/val/trampoline-params.c | 32 +++++++++++++++++++++++ test/val/trampoline-varargs.c | 48 +++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) create mode 100644 test/val/trampoline-params.c create mode 100644 test/val/trampoline-varargs.c diff --git a/test/val/trampoline-params.c b/test/val/trampoline-params.c new file mode 100644 index 000000000..890e43e5f --- /dev/null +++ b/test/val/trampoline-params.c @@ -0,0 +1,32 @@ +/* + !!DESCRIPTION!! wrapped-call pragma w/ many params + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + +#include + +static unsigned char flag; + +static void trampoline_set() { + asm("ldy tmp4"); + asm("sty %v", flag); + asm("jsr callptr4"); +} + +#pragma wrapped-call(push, trampoline_set, 4) +long adder(long in); +#pragma wrapped-call(pop) + +long adder(long in) { + + return in + 7; +} + +int main() { + + flag = 0; + + return adder(70436) == 70436 + 7 && flag == 4 ? 0 : 1; +} diff --git a/test/val/trampoline-varargs.c b/test/val/trampoline-varargs.c new file mode 100644 index 000000000..5d3377c68 --- /dev/null +++ b/test/val/trampoline-varargs.c @@ -0,0 +1,48 @@ +/* + !!DESCRIPTION!! wrapped-call pragma w/ varags + !!ORIGIN!! cc65 regression tests + !!LICENCE!! Public Domain + !!AUTHOR!! Lauri Kasanen +*/ + +#include + +static unsigned char flag; + +static void trampoline_set() { + // The Y register is used for variadics - save and restore + asm("sty tmp3"); + + asm("ldy tmp4"); + asm("sty %v", flag); + + asm("ldy tmp3"); + asm("jsr callptr4"); +} + +#pragma wrapped-call(push, trampoline_set, 4) +unsigned adder(unsigned char num, ...); +#pragma wrapped-call(pop) + +unsigned adder(unsigned char num, ...) { + + unsigned char i; + unsigned sum = 0; + va_list ap; + va_start(ap, num); + + for (i = 0; i < num; i++) { + sum += va_arg(ap, unsigned); + } + + va_end(ap); + + return sum; +} + +int main() { + + flag = 0; + + return adder(3, 0, 5, 500) == 505 && flag == 4 ? 0 : 1; +} From 901ac80026f3defad4c143d2336558384bd763ad Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Fri, 19 May 2017 15:20:36 +0300 Subject: [PATCH 2/4] Wrapper functions use all registers --- src/cc65/codeinfo.c | 4 ++++ src/cc65/funcdesc.h | 3 ++- src/cc65/pragma.c | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index de51781a6..06c66baf4 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -401,6 +401,10 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) */ if ((D->Flags & FD_VARIADIC) != 0) { *Use = REG_Y; + } else if (D->Flags & FD_CALL_WRAPPER) { + /* Wrappers may go to any functions, so mark them as using all + registers */ + *Use = REG_EAXY; } else if (D->ParamCount > 0 && (AutoCDecl ? IsQualFastcall (E->Type) : diff --git a/src/cc65/funcdesc.h b/src/cc65/funcdesc.h index 040f6e97c..a04ffb14a 100644 --- a/src/cc65/funcdesc.h +++ b/src/cc65/funcdesc.h @@ -52,9 +52,10 @@ #define FD_OLDSTYLE 0x0010U /* Old style (K&R) function */ #define FD_OLDSTYLE_INTRET 0x0020U /* K&R func has implicit int return */ #define FD_UNNAMED_PARAMS 0x0040U /* Function has unnamed params */ +#define FD_CALL_WRAPPER 0x0080U /* This function is used as a wrapper */ /* Bits that must be ignored when comparing funcs */ -#define FD_IGNORE (FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS) +#define FD_IGNORE (FD_OLDSTYLE | FD_OLDSTYLE_INTRET | FD_UNNAMED_PARAMS | FD_CALL_WRAPPER) diff --git a/src/cc65/pragma.c b/src/cc65/pragma.c index 8d5dfd8b1..3dfc62668 100644 --- a/src/cc65/pragma.c +++ b/src/cc65/pragma.c @@ -513,6 +513,7 @@ static void WrappedCallPragma (StrBuf* B) PushWrappedCall(Entry, Val); Entry->Flags |= SC_REF; + Entry->V.F.Func->Flags |= FD_CALL_WRAPPER; } else { From e8a735492de02f1ab7dc5f28a24dc1c5022c0d82 Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Fri, 19 May 2017 15:38:50 +0300 Subject: [PATCH 3/4] Correct comment style --- src/cc65/codeinfo.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/cc65/codeinfo.c b/src/cc65/codeinfo.c index 06c66baf4..e9d98f5b8 100644 --- a/src/cc65/codeinfo.c +++ b/src/cc65/codeinfo.c @@ -403,7 +403,8 @@ void GetFuncInfo (const char* Name, unsigned short* Use, unsigned short* Chg) *Use = REG_Y; } else if (D->Flags & FD_CALL_WRAPPER) { /* Wrappers may go to any functions, so mark them as using all - registers */ + ** registers. + */ *Use = REG_EAXY; } else if (D->ParamCount > 0 && (AutoCDecl ? From 05b73276c2ff1b6ea88735c1d78a9da8e1d8cabc Mon Sep 17 00:00:00 2001 From: Lauri Kasanen Date: Sat, 20 May 2017 09:53:30 +0300 Subject: [PATCH 4/4] Update test description --- test/val/trampoline-varargs.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/val/trampoline-varargs.c b/test/val/trampoline-varargs.c index 5d3377c68..d154a3da0 100644 --- a/test/val/trampoline-varargs.c +++ b/test/val/trampoline-varargs.c @@ -1,5 +1,5 @@ /* - !!DESCRIPTION!! wrapped-call pragma w/ varags + !!DESCRIPTION!! wrapped-call pragma w/ variadic function !!ORIGIN!! cc65 regression tests !!LICENCE!! Public Domain !!AUTHOR!! Lauri Kasanen