Coder Social home page Coder Social logo

zylin / zpugcc Goto Github PK

View Code? Open in Web Editor NEW
50.0 14.0 31.0 144.61 MB

Makefile 1.69% Perl 9.86% R 0.15% C 62.84% Objective-C 0.18% C++ 7.69% Shell 2.00% Bison 0.52% Groff 4.59% Rebol 0.02% Assembly 5.58% Scheme 0.39% JavaScript 0.25% Prolog 0.08% PHP 0.02% TeX 0.41% Component Pascal 0.01% D 1.51% DTrace 2.23% E 0.01%

zpugcc's Introduction

zpugcc

This repository contain the gcc, which is adapted for https://github.com/zylin/zpu CPU, the worlds smallest 32 bit CPU with GCC toolchain.

ZPU toolchain source code

The ZPU toolchain is too big to be hosted together with the HDL and the idea is that most HDL or normal users would not want to download and build their own toolchain.

ZPU build instructions to build unstable on linux (same for CygWin32)

git clone https://github.com/zylin/zpugcc.git
cd toolchain/toolchain
sh fixperm.sh
. env.sh
sh build.sh
tar -cjvf zpugcclinux_unstable.tar.bz2 install 

Build a different version

git log => shows log entries
git checkout 322875263beccb1d75936bd1dd9150c1647dc9c0 => checkout a version
Note that build.sh is only present in the later versions, but that it should work fine for those versions in git where it is absent. 

Cygwin build problems

If you are having problems building with Cygwin, try erasing the entire c:\cygwin folder and try again.

zpugcc's People

Contributors

alvieboy avatar bert-lange avatar oharboe avatar robinsonb5 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

zpugcc's Issues

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

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

Port a newer GCC?

GCC 3.x is quite old; perhaps a newer compiler should be retargeted for the ZPU

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

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:

static volatile int *TIMER;

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():
clock|=((long long )(TIMER[i]))<<(i*32);

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.

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

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 */

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

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

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

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo 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.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.