__z88dk_fastcall problem

ZX80, ZX 81, ZX Spectrum, TS2068 and other clones
Post Reply
derekfountain
Member
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

__z88dk_fastcall problem

Post by derekfountain »

Are there any known problems with split builds and __z88dk_fastcall? I can't find anything, but I can't get it to work.

I tend to typedef my structures like this:

Code: Select all

typedef struct _slowdown_definition
{
/* Stuff */
} SLOWDOWN;
and I have a function which takes a pointer to one of these. The header file contains:

Code: Select all

void create_slowdown_pill( SLOWDOWN* slowdown );
and the code:

Code: Select all

void create_slowdown_pill( SLOWDOWN* slowdown )
{
   ...
This works fine. But if I make this fastcall:

Code: Select all

void create_slowdown_pill( SLOWDOWN* slowdown ) __z88dk_fastcall;
and:

Code: Select all

void create_slowdown_pill( SLOWDOWN* slowdown ) __z88dk_fastcall
{
then the program crashes. It's pretty obvious why from the lis file:

Code: Select all

751   004E              ;       ---------------------------------
752   004E              ; Function create_slowdown_pill
753   004E              ; ---------------------------------
754   004E              _create_slowdown_pill:
755   004E  DD E5               push    ix
756   0050  DD 21 00 00         ld      ix,0
757   0054  DD 39               add     ix,sp
758   0056  21 F3 FF            ld      hl, -13
759   0059  39                  add     hl, sp
760   005A  F9                  ld      sp, hl
The fastcall hasn't been respected at that end. But it is at the calling end:

Code: Select all

1007  0180  C5                  push    bc
1008  0181  D5                  push    de
1009  0182  EB                  ex      de,hl
1010  0183  CD 00 00            call    _create_slowdown_pill
1011  0186  D1                  pop     de
1012  0187  C1                  pop     bc
Unfortunately, despite my spending ages trying to isolate this into a test case, I can't make it do it in a smaller program. I sort of blamed the split build I use, but I don't have evidence that's actually involved. My project is a bit big to just shove in front of someone. :) I've tried other functions which use my typedef style with other structures and they do the same thing. But single integral types seem to work fine.

The command line my make uses is this:

Code: Select all

zcc +zx -vn -c -SO3 --max-allocs-per-node200000 -DNDEBUG --std-c99 --list -preserve -compiler sdcc -clib=sdcc_iy -pragma-include:zpragma.inc -o slowdown_pill.o slowdown_pill.c
and the same for the calling end. It also does it without the optimisation:

Code: Select all

zcc +zx -vn -c --std-c99 --list -preserve -compiler sdcc -clib=sdcc_iy -pragma-include:zpragma.inc -o slowdown_pill.o slowdown_pill.c
Any ideas? I'm using the nightly build from 12th Feb.
derekfountain
Member
Posts: 50
Joined: Mon Mar 26, 2018 1:49 pm

Post by derekfountain »

More experimentation and it seems it might be related to the source file. I copied that create function out to a C file of its own and added that to the build. Now it works:

Code: Select all

694   0000              ; Function create_slowdown_pill
695   0000              ; ---------------------------------
696   0000              _create_slowdown_pill:
697   0000  DD E5               push    ix
698   0002  DD 21 00 00         ld      ix,0
699   0006  DD 39               add     ix,sp
700   0008  F5                  push    af
701   0009  F5                  push    af
702   000A  4D                  ld      c, l
703   000B  44                  ld      b, h
I had to tweak the function slightly to make it compile, so it's not a perfect test. Maybe the source file size or complexity is relevant?
Post Reply