zpugcc's People
Forkers
robinsonb5 csoren matrixsmaster datenschlumpf longhairedhacker hftrader lujialiang luluxiaowu rbarzic handsome3163 avlixa mark-r-stevens yin-pei riktw 8bitgeek amamory-ursa chuckb kargeor hackfin limingnefu-dotcom mrlxx jeff-ciesielski zongwuwang esovm 00mjk jvalenzu-ni freewing-jp enkihubtoyzpugcc's Issues
long long _readCycles() returning incorrect values when ZPU is running for a (very) long time
Hello, I am developing a ZPU simulator on a very old machine (don't ask why), and came across a strange issue.
When the ZPU is running for a (very) long time, _readCycles() returns unexpected negative values. They are unexpected because they should appear much later on since the timer is 64bits. After investigation, it appears that the returned value have a specific pattern. They looks like this in binary: 0b11...11xy...zt
more precisely, exactly 33 bits set to 1, followed by 30 random 0/1 bits. Actually the upper part of the 64bit value is all trashed with ones.
I have checked the (emulated) timer and the upper 32 bits are correctly read as a positive integer. What seem to happen is that each time the lower "int" of the timer is negative, the high "int" gets replaced with 0xff...ff (i.e. -1), resulting in a negative "long long" (64 bit value) where one expect a mix of 0/1 bits in there.
After checking the source code for _readCycles(), I think I have spotted the root cause for this.
Look at the declaration of TIMER[] in crt_io.c:
As you can see, it is declared as a signed
int
value. This mean that whenever TIMER[0] has its 31th bit (sign bit) set, the following code in _readCycles():will cast the negative int, into a negative long long. At this point
clock
now has all its upper bits sets to 1, masking the bits for the next "or" with TIMER[1]. This results in a returned value having this specific pattern: 0xFFFFFFFF<some negative 32bit value>.
The fix is fairly easy: one should declare TIMER as "unsigned int" to prevent the propagation of the sign bit of TIMER[0] during the cast: static volatile unsigned int *TIMER;
I have tested this simple change and I dont get these unexpected negative "cycles counts" anymore. Problem seem to be fixed (at least for me). I also decided to share this to you as I think you might be interested to have a feedback on this old project.
PS: By the way, one can also declare unsigned long long_readCycles()
to have everything correctly set to unsigned, but this isn't as important as the upper bits being trashed as soon as the ZPU starts its 2^31 cycle.
Example of adding UDIV/UMOD
I ran into issue similar to the one described in #8, unsigned division is very slow because it's not using DIV instruction. For me the easiest solution was to implement two new instructions: UDIV
and UMOD
. Here's a patch that enables them in zpugcc. By default they are disabled for compatibility. They can be enabled with -mumod
-mudiv
switches.
From 52bd35da458199cabdc308508d28946b9f4d8e87 Mon Sep 17 00:00:00 2001
From: svofski <[email protected]>
Date: Wed, 2 Dec 2020 22:41:57 +0300
Subject: [PATCH] support optional udiv and umod instructions
Opcodes 32 udiv, 33 umod. They are not standard and disabled by default.
Enable them with -mudiv -mumod.
---
toolchain/binutils/include/opcode/zpu.h | 2 ++
toolchain/binutils/opcodes/zpu-opc.c | 2 ++
toolchain/gcc/gcc/config/zpu/zpu.c | 16 ++++++++++++++++
toolchain/gcc/gcc/config/zpu/zpu.h | 11 +++++++++--
4 files changed, 29 insertions(+), 2 deletions(-)
diff --git a/toolchain/binutils/include/opcode/zpu.h b/toolchain/binutils/include/opcode/zpu.h
index ae740f3d..777421c2 100755
--- a/toolchain/binutils/include/opcode/zpu.h
+++ b/toolchain/binutils/include/opcode/zpu.h
@@ -80,6 +80,8 @@ enum ZPU_OPCODE
ZPU_pushspadd=61,
ZPU_halfmult=62,
ZPU_callpcrel=63,
+ ZPU_udiv=32,
+ ZPU_umod=33,
ZPU_impcrel=0, /* not an opcode, translates to IM instructions */
diff --git a/toolchain/binutils/opcodes/zpu-opc.c b/toolchain/binutils/opcodes/zpu-opc.c
index cf784838..97dcfa40 100755
--- a/toolchain/binutils/opcodes/zpu-opc.c
+++ b/toolchain/binutils/opcodes/zpu-opc.c
@@ -58,6 +58,8 @@ const struct zpu_opcode zpu_opcodes[]={
{ZPU_swap, "swap", ADDR_IMPLIED},
{ZPU_div, "div", ADDR_IMPLIED},
{ZPU_mod, "mod", ADDR_IMPLIED},
+ {ZPU_udiv, "udiv", ADDR_IMPLIED},
+ {ZPU_umod, "umod", ADDR_IMPLIED},
{ZPU_eqbranch, "eqbranch", ADDR_IMPLIED},
{ZPU_neqbranch, "neqbranch", ADDR_IMPLIED},
diff --git a/toolchain/gcc/gcc/config/zpu/zpu.c b/toolchain/gcc/gcc/config/zpu/zpu.c
index df6c787e..1fe8bbbb 100755
--- a/toolchain/gcc/gcc/config/zpu/zpu.c
+++ b/toolchain/gcc/gcc/config/zpu/zpu.c
@@ -551,6 +551,10 @@ int zpu_binary_operator (rtx op ATTRIBUTE_UNUSED, enum machine_mode mode ATTRIB
return TARGET_DIV;
case MOD:
return TARGET_MOD;
+ case UDIV:
+ return TARGET_UDIV;
+ case UMOD:
+ return TARGET_UMOD;
default:
break;
@@ -1692,12 +1696,24 @@ static void push_operand_value(rtx *operand)
push_operand_value(&XEXP (*operand, 0));
zpu_asm("div", operand);
stackOffset+=4;
+ } else if (GET_CODE(operand[0]) == UDIV)
+ {
+ push_operand_value(&XEXP (*operand, 1));
+ push_operand_value(&XEXP (*operand, 0));
+ zpu_asm("udiv", operand);
+ stackOffset+=4;
} else if (GET_CODE(operand[0])==MOD)
{
push_operand_value(&XEXP (*operand, 1));
push_operand_value(&XEXP (*operand, 0));
zpu_asm("mod", operand);
stackOffset+=4;
+ } else if (GET_CODE(operand[0])==UMOD)
+ {
+ push_operand_value(&XEXP (*operand, 1));
+ push_operand_value(&XEXP (*operand, 0));
+ zpu_asm("umod", operand);
+ stackOffset+=4;
} else if (GET_CODE(operand[0])==ZERO_EXTEND)
{
push_operand_value(&XEXP (*operand, 0));
diff --git a/toolchain/gcc/gcc/config/zpu/zpu.h b/toolchain/gcc/gcc/config/zpu/zpu.h
index 46483a08..7e7d5b95 100755
--- a/toolchain/gcc/gcc/config/zpu/zpu.h
+++ b/toolchain/gcc/gcc/config/zpu/zpu.h
@@ -92,11 +92,13 @@ extern int target_flags;
#define ZPU_BITSBIG (1<<24)
#define ZPU_MEMREG (1<<25)
+#define ZPU_UDIV (1<<26)
+#define ZPU_UMOD (1<<27)
-#define TARGET_SWITCHES_DEFAULT (0x7fffffff&~ZPU_BITSBIG)
+#define TARGET_SWITCHES_DEFAULT (0x7fffffff&~(ZPU_BITSBIG|ZPU_UDIV|ZPU_UMOD))
@@ -123,7 +125,8 @@ extern int target_flags;
#define TARGET_BYTESBIG ((target_flags & ZPU_BYTESBIG)!=0)
#define TARGET_BITSBIG ((target_flags & ZPU_BITSBIG)!=0)
#define TARGET_MEMREG ((target_flags & ZPU_MEMREG)!=0)
-
+#define TARGET_UDIV ((target_flags & ZPU_UDIV)!=0)
+#define TARGET_UMOD ((target_flags & ZPU_UMOD)!=0)
#define TARGET_SWITCHES \
{ \
@@ -133,6 +136,10 @@ extern int target_flags;
{ "no-div", -ZPU_DIV, "DIV instruction" },\
{ "mod", ZPU_MOD, "MOD instruction" },\
{ "no-mod", -ZPU_MOD, "MOD instruction" },\
+ { "udiv", ZPU_UDIV, "UDIV instruction" },\
+ { "no-udiv", -ZPU_UDIV, "UDIV instruction" },\
+ { "umod", ZPU_UMOD, "UMOD instruction" },\
+ { "no-umod", -ZPU_UMOD, "UMOD instruction" },\
{ "neg", ZPU_NEG, "NEG instruction" },\
{ "no-neg", -ZPU_NEG, "NEG instruction" },\
{ "loadsp", ZPU_LOADSP, "LOADSP instruction" },\
--
2.25.1
Compile Issue
I try to compile the gcc toolchain on linux and get following error:
There is some issue within the created command for compilation. Can you support me plz.
make[3]: Verzeichnis „/home/kw/Work/zpugcc/toolchain/build/ld“ wird betreten
/bin/sh ../../binutils/ld/../ylwrap "" ../../binutils/ld/ldgram.y y.tab.c ldgram.c y.tab.h ldgram.h -- -d
../../binutils/ld/../ylwrap: 86: ../../binutils/ld/../ylwrap: -d: not found
Makefile:407: die Regel für Ziel „ldgram.c“ scheiterte
make[3]: *** [ldgram.c] Fehler 1
make[3]: Verzeichnis „/home/kw/Work/zpugcc/toolchain/build/ld“ wird verlassen
Makefile:574: die Regel für Ziel „all-recursive“ scheiterte
make[2]: *** [all-recursive] Fehler 1
make[2]: Verzeichnis „/home/kw/Work/zpugcc/toolchain/build/ld“ wird verlassen
Makefile:745: die Regel für Ziel „all-recursive-am“ scheiterte
make[1]: *** [all-recursive-am] Fehler 2
make[1]: Verzeichnis „/home/kw/Work/zpugcc/toolchain/build/ld“ wird verlassen
Makefile:19975: die Regel für Ziel „all-ld“ scheiterte
make: *** [all-ld] Fehler 2
Optional opcode flags not working
At least the -mmult and -mdiv flags have no effect; the generated assembly continues to call into the emulated division routines and the mul opcode is nowhere to be found in the output.
Test code:
int main() {
unsigned int counter = 0;
counter++;
*debug_port = counter / 3;
}
Compiler flags:
zpu-elf-gcc -O0 -S -mmult -mdiv main.c
Generated assembly:
impcrel (__udivsi3)
Expected output:
div
ELI5
I am a little confused by this compiler and the ZPU.
I thought the C language targeted register machines.
And yet here it works with a stack machine.
I also do not understand why the gcc version used is so old, while there appears to be a thriving ecosystem around the ZPU. I would expect someone to have done the upgrade. Is there a reason the version has not been updated?
Is there a reason why this would or would not work with the LLVM compiler?
Is there a different C compiler which might be a better choice?
Somewhere there is some magic going on here, I am trying to figure out what is the key thing that makes this all work, and what are its limits.
Maybe I am not the only one who is curious.
Thank You.
Chris
Path to change to in build instructions in wrong.
The instruction to do this:
cd toolchain/toolchain
Should be this:
cd zpugcc/toolchain
Update homepage to mention correct cygwin version
Currently http://opensource.zylin.com/zpudownload.html only mentions Cygwin as a supported platform, where it should say "Cygwin for x86 (32-bit installation)", as the binary release of zpu-gcc does not work with "Cygwin for x86_64 (64-bit installation)".
binutils fails to build on OSX 11.0 -- missing malloc/free/etc
Needs to export ac_cv_header_stdc=yes
before configure to properly import stdlib.h.
Fails to build with GCC 5.4
I didn't make an note of the exact error but something like:
cfns.gperf:101:1: error: 'gnu_inline' attribute present on 'libc_name_p'
cfns.gperf:26:14: error: but not here
After googling I found that GCC 5 has a problem building older versions of GCC. I found a fix at https://gcc.gnu.org/ml/gcc-patches/2015-08/msg00375.html
I'll include the diff from that thread. I didn't run the diff but applied it by hand. The complilation completed after I made the changes.
Cheers
Alan
diff --git a/gcc/cp/cfns.gperf b/gcc/cp/cfns.gperf
index 68acd3d..953262f 100644
--- a/gcc/cp/cfns.gperf
+++ b/gcc/cp/cfns.gperf
@@ -22,6 +22,9 @@ __inline
static unsigned int hash (const char *, unsigned int);
#ifdef __GNUC__
__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
const char * libc_name_p (const char *, unsigned int);
%}
diff --git a/gcc/cp/cfns.h b/gcc/cp/cfns.h
index 1c6665d..6d00c0e 100644
--- a/gcc/cp/cfns.h
+++ b/gcc/cp/cfns.h
@@ -53,6 +53,9 @@ __inline
static unsigned int hash (const char *, unsigned int);
#ifdef __GNUC__
__inline
+#ifdef __GNUC_STDC_INLINE__
+__attribute__ ((__gnu_inline__))
+#endif
#endif
const char * libc_name_p (const char *, unsigned int);
/* maximum key range = 391, duplicates = 0 */
Port a newer GCC?
GCC 3.x is quite old; perhaps a newer compiler should be retargeted for the ZPU
build.sh fails
We run the following code:
git clone https://github.com/zylin/zpugcc.git
cd zpugcc/toolchain
sh fixperm.sh
. env.sh
sh build.sh
and we receive this error after a while:
...
checking whether NLS is requested... yes
checking whether included gettext is requested... no
checking for libintl.h... yes
checking for gettext in libc... yes
checking for msgfmt... no
checking for msgfmt... (cached) no
checking for gmsgfmt... no
checking for xgettext... :
checking for catalogs to be installed... fr sv tr es da de id pt_BR ro nl
checking for a BSD compatible install... /usr/bin/install -c
checking for string.h... (cached) yes
checking for strings.h... yes
checking for stdlib.h... yes
updating cache ./config.cache
creating ./config.status
creating Makefile
creating po/Makefile.in
creating config.h
make[1]: Entering directory '/home/main/zpugcc/toolchain/build/opcodes'
make all-recursive
make[2]: Entering directory '/home/main/zpugcc/toolchain/build/opcodes'
Making all in po
make[3]: Entering directory '/home/main/zpugcc/toolchain/build/opcodes/po'
file=../../../binutils/opcodes/po/`echo de | sed 's,.*/,,'`.gmo \
&& rm -f $file && PATH=../src:$PATH no -o $file ../../../binutils/opcodes/po/de.po
/bin/sh: 2: no: not found
make[3]: *** [Makefile:221: de.gmo] Error 127
make[3]: Leaving directory '/home/main/zpugcc/toolchain/build/opcodes/po'
make[2]: *** [Makefile:352: all-recursive] Error 1
make[2]: Leaving directory '/home/main/zpugcc/toolchain/build/opcodes'
make[1]: *** [Makefile:498: all-recursive-am] Error 2
make[1]: Leaving directory '/home/main/zpugcc/toolchain/build/opcodes'
make: *** [Makefile:18267: all-opcodes] Error 2
Bison and Flex dependency
It's not clear that flex and bison need to be installed on the system, or the build will fail.
Compile issue
I try to compile the gcc toolchain on ubuntu 16.04 and get following error.Can you support me plz.
configure: warning: ../zpugcc/toolchain/build/../install: invalid host type
creating cache ./config.cache
checking host system type... Invalid configuration ../zpugcc/toolchain/build/../install': machine ../zpugcc/toolchain/build/../install' not recognized
checking target system type... zpu-unknown-none
checking build system type... Invalid configuration ../zpugcc/toolchain/build/../install': machine ../zpugcc/toolchain/build/../install' not recognized
checking for a BSD compatible install... /usr/bin/install -c
../binutils/configure: 841: test: /home/../..: unexpected operator
../binutils/configure: 26: test: /home/../..: unexpected operator
checking for ../zpugcc/toolchain/build/../install-ar... no
checking for ar... ar
checking for ../zpugcc/toolchain/build/../install-as... no
checking for as... as
checking for ../zpugcc/toolchain/build/../install-dlltool... no
checking for dlltool... dlltool
checking for ../zpugcc/toolchain/build/../install-ld... no
checking for ld... ld
checking for ../zpugcc/toolchain/build/../install-nm... no
checking for nm... nm
checking for ../zpugcc/toolchain/build/../install-ranlib... no
checking for ranlib... ranlib
checking for ../zpugcc/toolchain/build/../install-windres... no
checking for windres... windres
checking for ../zpugcc/toolchain/build/../install-objcopy... no
checking for objcopy... objcopy
checking for ../zpugcc/toolchain/build/../install-objdump... no
checking for objdump... objdump
checking for zpu-elf-ar... no
../binutils/configure: 3540: test: =: unexpected operator
checking for zpu-elf-as... no
../binutils/configure: 3612: test: =: unexpected operator
checking for zpu-elf-dlltool... no
../binutils/configure: 3684: test: =: unexpected operator
checking for zpu-elf-ld... no
../binutils/configure: 3756: test: =: unexpected operator
checking for zpu-elf-nm... no
../binutils/configure: 3828: test: =: unexpected operator
checking for zpu-elf-ranlib... no
../binutils/configure: 3900: test: =: unexpected operator
checking for zpu-elf-windres... no
../binutils/configure: 3972: test: =: unexpected operator
checking whether to enable maintainer-specific portions of Makefiles... no
updating cache ./config.cache
creating ./config.status
creating Makefile
Configuring in libiberty
/bin/sh: 0: Can't open /home/../..
Makefile:20071: fallo en las instrucciones para el objetivo 'configure-libiberty'
make: *** [configure-libiberty] Error 1
Upload binaries to github
These download pages http://opensource.zylin.com/zpudownload.html should be migrated to github.
github has a release system to allow big binaries to be downloaded.
Build fails if PATH contains paths with spaces in them. As in the WSL on Win10.
When running Debian Buster under the Windows Subsystem for Linux on Win 10 the PATH will contain directory names with spaces in them. Which causes the build.sh to fail.
The fix is to add some double quotes to the configure commands. As per this patch:
diff --git a/toolchain/build.sh b/toolchain/build.sh
index 332e4065..6a232acb 100644
--- a/toolchain/build.sh
+++ b/toolchain/build.sh
@@ -4,12 +4,13 @@ rm -rf build
mkdir build
cd build
export CFLAGS=-D_FORTIFY_SOURCE=0
-../binutils/configure --target=zpu-elf --prefix=`pwd`/../install
+../binutils/configure --target=zpu-elf --prefix="`pwd`/../install"
make
make install
cd ..
-export PATH=`pwd`/install/bin:$PATH
+export PATH="`pwd`/install/bin:$PATH"
+
rm -rf gccbuild
mkdir gccbuild
cd gccbuild
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.