long long is not supported
long long is not supported
Eigenmath needs long long
This simple sample shows the problem (no problem with gcc):
#include <stdio.h>
int main(void)
{
long long a;
a= 10;
printf("%lld\n",a);
return 0;
}
zcc +zx -lndos toto.c
cp /home/joaopa/z88dk/lib/config//../..//lib/spec_crt0.opt /tmp/tmpXX7mfT1f.opt
cp /tmp/tmpXX7mfT1f.opt /tmp/tmpXX7mfT1f.asm
zcpp -I. -DZ80 -DSPECTRUM -D__SPECTRUM__ -D__SPECTRUM -DSCCZ80 -DSMALL_C -I/home/david/z88dk/lib/config//../..//include toto.c /tmp/tmpXXtHy3Df.i
sccz80 -asm=z80asm /tmp/tmpXXtHy3Df.i
sccz80:"toto.c" L:4 Warning:#17:Expected ';'
sccz80:"toto.c" L:4 Error:#42:Unknown symbol: a
sccz80:"toto.c" L:6 Error:#33:Must be lvalue
Compilation aborted
This simple sample shows the problem (no problem with gcc):
#include <stdio.h>
int main(void)
{
long long a;
a= 10;
printf("%lld\n",a);
return 0;
}
zcc +zx -lndos toto.c
cp /home/joaopa/z88dk/lib/config//../..//lib/spec_crt0.opt /tmp/tmpXX7mfT1f.opt
cp /tmp/tmpXX7mfT1f.opt /tmp/tmpXX7mfT1f.asm
zcpp -I. -DZ80 -DSPECTRUM -D__SPECTRUM__ -D__SPECTRUM -DSCCZ80 -DSMALL_C -I/home/david/z88dk/lib/config//../..//include toto.c /tmp/tmpXXtHy3Df.i
sccz80 -asm=z80asm /tmp/tmpXXtHy3Df.i
sccz80:"toto.c" L:4 Warning:#17:Expected ';'
sccz80:"toto.c" L:4 Error:#42:Unknown symbol: a
sccz80:"toto.c" L:6 Error:#33:Must be lvalue
Compilation aborted
Last edited by joaopa on Sun Feb 21, 2016 4:47 am, edited 1 time in total.
longlong is not supported in sccz80. It's a 64-bit integer. Can you get away with 32-bit?
If you really need 64-bit integers, you will have to use sdcc. 64-bit integers are rarely supported on 8-bit machines and as far as I know, only sdcc has some support for them among z80 compilers. If you do need it, we'll have to update the c lib with 64-bit math functions and add %lld to printf and scanf.
If you really need 64-bit integers, you will have to use sdcc. 64-bit integers are rarely supported on 8-bit machines and as far as I know, only sdcc has some support for them among z80 compilers. If you do need it, we'll have to update the c lib with 64-bit math functions and add %lld to printf and scanf.
If you can limit computation to 32 bits, that would help in speed and program size.joaopa wrote:After diving in the problem, the conclusion is that we need 64 bit-integers for Eigenmath. Otherwise, even a simple second degree can not be solved...
And all the computatin is limited to 2^32.
I will look at 64-bit ints this weekend.
It shouldn't take more than a day or two to add the first bit of longlong support to the library. The code that sdcc produces is very bloaty. 25 bytes to clear a longlong to zero. 72 bytes to add two longlongs together. Everything is inlined so I think once the longlong support is in, we should look at changing the compiler to produce subroutine calls to the library to carry out these operations. The library code is faster than the code sdcc is inlining and it would be a lot smaller. The same size issue arises with sdcc and longs but the code sdcc inlines for longs is usually faster after it has been processed by the aggressive peephole set.
The first bit of longlong support will be present in the May 7 build.
Only sdcc supports longlong and for the moment on the new c library has the functionality.
You can add, subtract, multiply, divide and shift 64-bit integers. The following functions have been added: ffsll(long long i) [string.h], _lldiv_(), _lldivu_(), llabs(), lltoa() and ulltoa() [stdlib.h].
What's missing currently: strtoll(), strtoull(), float<->longlong conversion, type definitions in headers (eg uint64_t, etc), printf & scanf converters for longlong.
An example program compiled for the zx target:
You'll note that lltoa() is used to generate a base 10 string from the longlong since there is no printf %lld yet. Because there is no scanf %lld yet, the 64-bit numbers are scanned in two 32-bit halves in hexadecimal.
I did come across a bug in sdcc which will hopefully be fixed soon:
https://sourceforge.net/p/sdcc/bugs/2501/
"in_pause(200);" is inserted into the code to eliminate the bug in this program.
If you're on windows, after the nightly build is installed, be sure to update your zsdcc executable in z88dk/bin from http://z88dk.cvs.sourceforge.net/viewvc ... _patch.zip . Everything else in the nightly will be up to date but the binary is less frequently updated. When sdcc fixes the aforementioned bug, I'll be updating that zip with a new build.
Only sdcc supports longlong and for the moment on the new c library has the functionality.
You can add, subtract, multiply, divide and shift 64-bit integers. The following functions have been added: ffsll(long long i) [string.h], _lldiv_(), _lldivu_(), llabs(), lltoa() and ulltoa() [stdlib.h].
What's missing currently: strtoll(), strtoull(), float<->longlong conversion, type definitions in headers (eg uint64_t, etc), printf & scanf converters for longlong.
An example program compiled for the zx target:
Code: Select all
// zcc +zx -vn -SO3 -startup=4 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 lg.c -o lg --list
#include <stdio.h>
#include <input.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
struct long_s
{
unsigned long ls32;
unsigned long ms32;
};
union u64_s
{
long long a;
struct long_s b;
};
union u64_s x, y, z;
double_t d;
char buffer_0[100];
char buffer_1[100];
char buffer_2[100];
lldiv_t ld;
void main(void)
{
in_wait_nokey();
while(1)
{
fflush(stdin);
printf("\n\n[#1] MS32 <space> LS32 in hex\n");
scanf("%lx%lx", &x.b.ms32, &x.b.ls32);
printf("\n[#2] MS32 <space> LS32 in hex\n");
scanf("%lx%lx", &y.b.ms32, &y.b.ls32);
lltoa(x.a, buffer_0, 10);
lltoa(y.a, buffer_1, 10);
z.a = x.a + y.a;
lltoa(z.a, buffer_2, 10);
printf("\n%s + %s = %s\n", buffer_0, buffer_1, buffer_2);
z.a = x.a - y.a;
lltoa(z.a, buffer_2, 10);
printf("%s - %s = %s\n", buffer_0, buffer_1, buffer_2);
z.a = x.a * y.a;
lltoa(z.a, buffer_2, 10);
printf("%s * %s = %s\n", buffer_0, buffer_1, buffer_2);
z.a = x.a / y.a;
lltoa(z.a, buffer_2, 10);
printf("%s / %s = %s\n", buffer_0, buffer_1, buffer_2);
z.a = x.a % y.a;
lltoa(z.a, buffer_2, 10);
printf("%s %% %s = %s\n", buffer_0, buffer_1, buffer_2);
z.a = x.a >> y.a;
lltoa(z.a, buffer_2, 10);
printf("%s >> %s = %s\n", buffer_0, buffer_1, buffer_2);
z.a = x.a << y.a;
lltoa(z.a, buffer_2, 10);
printf("%s << %s = %s\n", buffer_0, buffer_1, buffer_2);
printf("ffsll(%s) = %u\n", buffer_0, ffsll(x.a));
z.a = llabs(x.a);
in_pause(200);
lltoa(z.a, buffer_2, 10);
printf("llabs(%s) = %s\n", buffer_0, buffer_2);
_lldiv_(&ld, x.a, y.a);
lltoa(ld.quot, buffer_0, 10);
lltoa(ld.rem, buffer_1, 10);
printf("lldiv: quotient = %s, remainder = %s\n\n", buffer_0, buffer_1);
}
}
I did come across a bug in sdcc which will hopefully be fixed soon:
https://sourceforge.net/p/sdcc/bugs/2501/
"in_pause(200);" is inserted into the code to eliminate the bug in this program.
If you're on windows, after the nightly build is installed, be sure to update your zsdcc executable in z88dk/bin from http://z88dk.cvs.sourceforge.net/viewvc ... _patch.zip . Everything else in the nightly will be up to date but the binary is less frequently updated. When sdcc fixes the aforementioned bug, I'll be updating that zip with a new build.
64-bit long longs are now fully supported in the new c lib as of the May 11 night build.
http://www.z88dk.org/forum/viewtopic.ph ... 796#p13796
The 64-bit scan converters for printf and scanf are disabled by default so in order to use those you must reconfigure the library and rebuild. It's simple to do this so if you're not sure how, just ask.
example compile for zx:
zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test --list
translate to assembly language only (useful to find errors without having to build a binary):
zcc +zx -vn -a -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c
http://www.z88dk.org/forum/viewtopic.ph ... 796#p13796
The 64-bit scan converters for printf and scanf are disabled by default so in order to use those you must reconfigure the library and rebuild. It's simple to do this so if you're not sure how, just ask.
example compile for zx:
zcc +zx -vn -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test --list
translate to assembly language only (useful to find errors without having to build a binary):
zcc +zx -vn -a -SO3 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c
It is up to you but I think it's worthwhile to use now.
sdcc never generates incorrect code - what is happening is it bails out when there is a problem. And when that problem occurs, it's easy to spot where to insert a dummy "intrinsic_stub();" between the two offending statements to allow the compile to complete. The intrinsic_stub() function takes up no space in the output binary.
sdcc is looking to do a new release very soon so I'm not sure how long it will take to see a fix.
sdcc never generates incorrect code - what is happening is it bails out when there is a problem. And when that problem occurs, it's easy to spot where to insert a dummy "intrinsic_stub();" between the two offending statements to allow the compile to complete. The intrinsic_stub() function takes up no space in the output binary.
sdcc is looking to do a new release very soon so I'm not sure how long it will take to see a fix.
I wanted to give a try to the 64-bit long support. So I downloaded the latest nighty build (this one, all is fine). When I compiled your example above in this thread, the compilation fails with
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test.exe --list
sh: 1: zsdcpp: not found
What must I do to fix this problem?
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test.exe --list
sh: 1: zsdcpp: not found
What must I do to fix this problem?
The windows and mac packages include the sdcc binaries but for other platforms, the sdcc binaries have to be built separately.joaopa wrote:I wanted to give a try to the 64-bit long support. So I downloaded the latest nighty build (this one, all is fine). When I compiled your example above in this thread, the compilation fails with
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test.exe --list
sh: 1: zsdcpp: not found
What must I do to fix this problem?
Instructions are here:
http://www.z88dk.org/wiki/doku.php?id=temp:front#sdcc1
For programs containing 64-bit integers, using the --opt-code-size flag will significantly reduce code size, the compiler generated portion by about 50% in fact.
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_ix --reserve-regs-iy --max-allocs-per-node200000 test.c -o test --list --opt-code-size
The output filename "test" will be the root name used for all the output binaries generated by a compile. The output binary in this case will be "test_CODE.bin" which you can run by entering "CLEAR 32768", load the binary to 32768, then "RAND USR 32768".
The final test program I was using was this, which mixes floats in along with some long long printf and scanf conversions:
Code: Select all
// zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test --list --opt-code-size
#include <stdio.h>
#include <math.h>
#include <string.h>
#include <stdlib.h>
#include <stdint.h>
#include <errno.h>
#include <intrinsic.h>
#include <input.h>
double_t d;
char buffer_0[100];
char buffer_1[100];
char buffer_2[100];
lldiv_t ld;
long long x, z;
void main(void)
{
long long y;
intrinsic_di();
in_wait_nokey();
while(1)
{
fflush(stdin);
printf("\n[#1] ");
errno = 0;
scanf("%lli", &x);
if (errno) perror("scanf");
sprintf(buffer_0, "%lld", x);
fflush(stdin);
printf("[#2] ");
scanf("%s", buffer_1);
errno = 0;
y = strtoll(buffer_1, NULL, 0);
if (errno) perror("strtoll");
lltoa(y, buffer_1, 10);
z = x + y;
printf("\n%lld + %lld = %lld\n", x, y, z);
z = x - y;
lltoa(z, buffer_2, 10);
printf("%s - %s = %s\n", buffer_0, buffer_1, buffer_2);
z = x * y;
lltoa(z, buffer_2, 10);
printf("%s * %s = %s\n", buffer_0, buffer_1, buffer_2);
z = x / y;
lltoa(z, buffer_2, 10);
printf("%s / %s = %s\n", buffer_0, buffer_1, buffer_2);
z = x % y;
lltoa(z, buffer_2, 10);
printf("%s %% %s = %s\n", buffer_0, buffer_1, buffer_2);
z = x >> y;
lltoa(z, buffer_2, 10);
printf("%s >> %s = %lld\n",buffer_0, buffer_1, z);
z = x << y;
lltoa(z, buffer_2, 10);
printf("%s << %s = %s\n", buffer_0, buffer_1, buffer_2);
printf("ffsll(%s) = %u\n", buffer_0, ffsll(x));
z = llabs(x);
lltoa(z, buffer_2, 10);
printf("llabs(%s) = %s\n", buffer_0, buffer_2);
d = x;
printf("float(%lld) = %g\n", x, d);
z = d;
lltoa(z, buffer_0, 10);
printf("longlong(%g) = %s\n", d, buffer_0);
_lldiv_(&ld, x, y);
lltoa(ld.quot, buffer_0, 10);
lltoa(ld.rem, buffer_1, 10);
printf("lldiv: quotient = %s, remainder = %s\n", buffer_0, buffer_1);
}
}
The default zx library is built with float and long long printf / scanf converters disabled so before this program can be compiled, the zx library has to have those converters enabled and the library re-built.
You do this by editing the zx's clib configuration file: z88dk/libsrc/_DEVELOPMENT/target/zx/clib_cfg.asm
In that file there are a few binary words that define which % converters should be enabled for printf and scanf: __CLIB_OPT_PRINTF, __CLIB_OPT_PRINTF_2, __CLIB_OPT_SCANF, __CLIB_OPT_SCANF_2 . You can reduce code size by selecting which converters will be active but for this program, it's alright to activate them all by assigning $ffffffff to these constants. Comment out the old values and add a new line so that you can restore the defaults later.
After that file is saved, re-build the zx library by going to the z88dk/libsrc/_DEVELOPMENT directory and running "Winmake zx" (windows) or "make TARGET=zx" (other). It will take 5-10 mins to build the library.
Then you will be able to compile the program above.
For that last program I forgot to link the floating point library in the compile line:
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test -lm --list --opt-code-size
Once you are done playing with that, you may want to restore the clib configuration to its default (undo the changes to __CLIB_OPT_PRINTF, etc, and rebuild the libary). Otherwise eg, with printf's float converters enabled, compiles using printf will always need the float library linked and some float code will always make it into the final binary.
zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test -lm --list --opt-code-size
Once you are done playing with that, you may want to restore the clib configuration to its default (undo the changes to __CLIB_OPT_PRINTF, etc, and rebuild the libary). Otherwise eg, with printf's float converters enabled, compiles using printf will always need the float library linked and some float code will always make it into the final binary.
I compiled sdcc with the patch. But since the build fails I can not say if everything was done fine. With the test programm, I obtain
zsdcc -v
ZSDCC is a modification of SDCC for Z88DK
sdcc website:
https://sourceforge.net/projects/sdcc/
patch details:
http://z88dk.cvs.sourceforge.net/viewvc ... _patch.zip
modification date:
Jun 16 2016
sdcc -v:
3.6.0 #9615 (Linux)
mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8
published under GNU General Public License (GPL)
joaopa@Carlitz:~$ zsdcpp --version
zsdcpp (SDCC) 4.6.3 (GNU cpp adapted for SDCC)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
joaopa@Carlitz:~$ zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test -lm --list --opt-code-size
Error at file '/tmp/tmpXXqr0evT.opt' line 835: symbol '____sdcc_ll_copy_src_de_dst_hlsp' not defined
Error at file '/tmp/tmpXXqr0evT.opt' line 841: symbol '____sdcc_ll_push_hlix' not defined
Error at file '/tmp/tmpXXqr0evT.opt' line 842: symbol '_lltoa_callee' not defined
Error at file '/tmp/tmpXXqr0evT.opt' line 845: symbol '____sdcc_ll_copy_src_de_dst_hlsp' not defined
and tons of such messages
zsdcc -v
ZSDCC is a modification of SDCC for Z88DK
sdcc website:
https://sourceforge.net/projects/sdcc/
patch details:
http://z88dk.cvs.sourceforge.net/viewvc ... _patch.zip
modification date:
Jun 16 2016
sdcc -v:
3.6.0 #9615 (Linux)
mcs51/z80/z180/r2k/r3ka/gbz80/tlcs90/ds390/pic16/pic14/TININative/ds400/hc08/s08/stm8
published under GNU General Public License (GPL)
joaopa@Carlitz:~$ zsdcpp --version
zsdcpp (SDCC) 4.6.3 (GNU cpp adapted for SDCC)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
joaopa@Carlitz:~$ zcc +zx -vn -SO3 -startup=4 -clib=sdcc_iy --max-allocs-per-node200000 test.c -o test -lm --list --opt-code-size
Error at file '/tmp/tmpXXqr0evT.opt' line 835: symbol '____sdcc_ll_copy_src_de_dst_hlsp' not defined
Error at file '/tmp/tmpXXqr0evT.opt' line 841: symbol '____sdcc_ll_push_hlix' not defined
Error at file '/tmp/tmpXXqr0evT.opt' line 842: symbol '_lltoa_callee' not defined
Error at file '/tmp/tmpXXqr0evT.opt' line 845: symbol '____sdcc_ll_copy_src_de_dst_hlsp' not defined
and tons of such messages
I think the problem is the source tarball is including the new c lib's z80 libraries from cvs, which are not updated daily and in fact probably haven't been updated in months. So you probably have outdated z80 libraries which won't contain the 64-bit code. This is an oversight in the build instructions so I will update that if this turns out to be the case.joaopa wrote:However, when I try to compile the sudoku example, everything works. Problem with the 64-bit library?
Try to rebuild the new c lib's z80 libraries yourself****.
cd z88dk/libsrc/_DEVELOPMENT
make (windows is "Winmake all")
This will take 5-10 minutes to finish. After that's done the libraries in z88dk/libsrc/_DEVELOPMENT/lib should all be marked the current date.
**** Before you do that you may want to edit the zx spectrum's clib_cfg.asm file as mentioned in the post above to enable the long long and float converters for printf/scanf which are required by the test program I gave.
Long longs are only available through the new c library and the new c library only has three supported targets currently: cpm, zx, and embedded (which can be used for any z80 but it's necessarily generic).joaopa wrote:Thanks, that works for zx spectrum.
But my target is vg5000. What must I modify to printf long long? There is no file clib_cfg.asm in _Developpment for VG5000
So what needs to be done is to add a vg5000 target to the new c library and write simple device drivers attached to printf and scanf. There is a bit of a learning curve associated with doing this but if you enjoy that sort of challenge you can make a vg5000 target yourself and then submit it to us. Instructions for making a new target for the new c lib are here:
http://www.z88dk.org/wiki/doku.php?id=t ... g_a_target
Otherwise I can have a look and get one started.