(nightly) sccz80 crashes func ptr calls with double params

Bug reports (if you don't/won't have a Github account)
Post Reply
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

(nightly) sccz80 crashes func ptr calls with double params

Post by alvin »

As stated, sccz80 crashes when generating code to call through function pointers with double parameters.

Code: Select all

// zcc +zx -vn -a -clib=new crash.c

#include <math.h>

void *f;

main()
{
   f = cos;   
   (f)(0.0);
   
   // f = copysign;
   // (f)(1.0,-1.0);
}
User avatar
dom
Well known member
Posts: 1195
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I've run this test through valgrind and I'm not seeing anything bad showing up - have you fixed this one already?
User avatar
dom
Well known member
Posts: 1195
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

The code generated was incorrect, I've just fixed it.
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

It doesn't crash sccz80 anymore but there is a more serious difficulty with function pointers and returning floats.

I tested with this program:

Code: Select all

// zcc +zx -vn -clib=new test.c -o test -lm -create-app --list
// zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test -lm -create-app --list

#pragma output CLIB_OPT_PRINTF = 0x4000000

#include <stdio.h>
#include <math.h>

#ifdef __SDCC

float (*f)(float);

#else

void *f;

#endif

main()
{
   f = cos;
   printf("cos 0.0 = %f\n", (float)((f)(0.0)));
}
The sdcc compile produces the right answer but the sccz80 compile produces the wrong answer.

It comes down to the function pointer not being typeable. If you look at the generated code after the function pointer call:

Code: Select all

31    001A  CD 00 00            call        l_jphl
32    001D  C1                  pop        bc
33    001E  C1                  pop        bc
34    001F  C1                  pop        bc
35    0020  CD 00 00            call        float
36    0023  CD 00 00            call        dpush
37    0026  3E 04               ld        a,4
38    0028  CD 00 00            call        printf
you can see sccz80 assumes the result of a function pointer call is a long (in dehl), which works for everything except float return values.

So in printing the float value returned by the function pointer call, sccz80 is assuming the result of the call is in dehl and does a long->float conversion and prints that.
User avatar
dom
Well known member
Posts: 1195
Joined: Sun Jul 15, 2007 10:01 pm

Post by dom »

I think there's some bad information out there, function pointers in sccz80 can be typed, but they can't have arguments.

Code: Select all

double test(double d)
{
        printf("%f\n",d);
        return 3.0;
}

int main()
{
        double (*fn)() = test;
        double  d;
       
        d = fn(1.345);
        printf("%lf\n",d);
}
Works as expected with the output:

1.345000
3.000000
alvin
Well known member
Posts: 1872
Joined: Mon Jul 16, 2007 7:39 pm

Post by alvin »

I never realized function pointers could have a return type in sccz80. I should have guessed since this is K&R. I'll have to change some of the documentation I wrote.

This now works with both compilers.

Code: Select all

// zcc +zx -vn -clib=new test.c -o test -lm -create-app --list
// zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test -lm -create-app --list

#pragma output CLIB_OPT_PRINTF = 0x4000000

#include <stdio.h>
#include <math.h>

#ifdef __SDCC

float (*f)(float);

#else

float (*f)();

#endif

main()
{
   f = cos;
   printf("cos 0.0 = %f\n", (f)(0.0));
}
The K&R declaration doesn't work with sdcc, although that is on their to-do list.
Post Reply