From f642817f0dc761e51c3bd362f75b0068a8d4b0c8 Mon Sep 17 00:00:00 2001 From: Xavier Leroy Date: Fri, 28 Apr 2017 15:56:59 +0200 Subject: RISC-V port and assorted changes This commits adds code generation for the RISC-V architecture, both in 32- and 64-bit modes. The generated code was lightly tested using the simulator and cross-binutils from https://riscv.org/software-tools/ This port required the following additional changes: - Integers: More properties about shrx - SelectOp: now provides smart constructors for mulhs and mulhu - SelectDiv, 32-bit integer division and modulus: implement constant propagation, use the new smart constructors mulhs and mulhu. - Runtime library: if no asm implementation is provided, run the reference C implementation through CompCert. Since CompCert rejects the definitions of names of special functions such as __i64_shl, the reference implementation now uses "i64_" names, e.g. "i64_shl", and a renaming "i64_ -> __i64_" is performed over the generated assembly file, before assembling and building the runtime library. - test/: add SIMU make variable to run tests through a simulator - test/regression/alignas.c: make sure _Alignas and _Alignof are not #define'd by C headers commit da14495c01cf4f66a928c2feff5c53f09bde837f Author: Xavier Leroy Date: Thu Apr 13 17:36:10 2017 +0200 RISC-V port, continued Now working on Asmgen. commit 36f36eb3a5abfbb8805960443d087b6a83e86005 Author: Xavier Leroy Date: Wed Apr 12 17:26:39 2017 +0200 RISC-V port, first steps This port is based on Prashanth Mundkur's experimental RV32 port and brings it up to date with CompCert, and adds 64-bit support (RV64). Work in progress. --- test/Makefile | 2 +- test/c/Makefile | 2 +- test/c/aes.c | 3 ++- test/compression/Makefile | 4 ++-- test/raytracer/Makefile | 2 +- test/regression/Makefile | 6 +++--- test/regression/Results/builtins-riscV | 12 ++++++++++++ test/regression/Runtest | 2 +- test/regression/alignas.c | 7 +++++++ test/regression/builtins-riscV.c | 30 ++++++++++++++++++++++++++++++ test/regression/extasm.c | 2 +- test/regression/floats-basics.c | 3 ++- test/regression/floats.c | 3 ++- test/spass/Makefile | 2 +- 14 files changed, 66 insertions(+), 14 deletions(-) create mode 100644 test/regression/Results/builtins-riscV create mode 100644 test/regression/builtins-riscV.c (limited to 'test') diff --git a/test/Makefile b/test/Makefile index b469eec2..5e9e0555 100644 --- a/test/Makefile +++ b/test/Makefile @@ -4,7 +4,7 @@ all: for i in $(DIRS); do $(MAKE) -C $$i all; done test: - set -e; for i in $(DIRS); do $(MAKE) -C $$i test; done + set -e; for i in $(DIRS); do $(MAKE) SIMU='$(SIMU)' -C $$i test; done bench: for i in $(DIRS); do $(MAKE) -C $$i bench; done diff --git a/test/c/Makefile b/test/c/Makefile index 5979dfd4..94feb993 100644 --- a/test/c/Makefile +++ b/test/c/Makefile @@ -32,7 +32,7 @@ all_gcc: $(PROGS:%=%.gcc) test: @for i in $(PROGS); do \ - if ./$$i.compcert | cmp -s - Results/$$i; \ + if $(SIMU) ./$$i.compcert | cmp -s - Results/$$i; \ then echo "$$i: passed"; \ else echo "$$i: FAILED"; exit 2; \ fi; \ diff --git a/test/c/aes.c b/test/c/aes.c index 053324f3..5bd57cbc 100644 --- a/test/c/aes.c +++ b/test/c/aes.c @@ -38,7 +38,8 @@ typedef unsigned int u32; #if defined(__ppc__) || defined(__PPC__) || defined(__ARMEB__) #define ARCH_BIG_ENDIAN -#elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) +#elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) \ + || defined(__riscv) #undef ARCH_BIG_ENDIAN #else #error "unknown endianness" diff --git a/test/compression/Makefile b/test/compression/Makefile index 784f7e73..fa73f0e6 100644 --- a/test/compression/Makefile +++ b/test/compression/Makefile @@ -35,9 +35,9 @@ test: @echo "Test data: $(TESTFILE)" @for i in $(EXE); do \ echo "$$i: compression..."; \ - ./$$i -c -i $(TESTFILE) -o $(TESTCOMPR); \ + $(SIMU) ./$$i -c -i $(TESTFILE) -o $(TESTCOMPR); \ echo "$$i: decompression..."; \ - ./$$i -d -i $(TESTCOMPR) -o $(TESTEXPND); \ + $(SIMU) ./$$i -d -i $(TESTCOMPR) -o $(TESTEXPND); \ if cmp $(TESTFILE) $(TESTEXPND); \ then echo "$$i: passed"; \ else echo "$$i: FAILED"; exit 2; \ diff --git a/test/raytracer/Makefile b/test/raytracer/Makefile index dc007fd7..c481ff86 100644 --- a/test/raytracer/Makefile +++ b/test/raytracer/Makefile @@ -23,7 +23,7 @@ depend: gcc -MM *.c > .depend test: - ./render < kal.gml + $(SIMU) ./render < kal.gml @if cmp kal.ppm Results/kal.ppm; \ then echo "raytracer: passed"; \ else echo "raytracer: FAILED"; exit 2; \ diff --git a/test/regression/Makefile b/test/regression/Makefile index 5def966b..54745863 100644 --- a/test/regression/Makefile +++ b/test/regression/Makefile @@ -71,15 +71,15 @@ clean: test: @echo "----------- Compiled tests -------------" @for i in $(TESTS) $(TESTS_COMP); do \ - ./Runtest $$i ./$$i.compcert; \ + SIMU='$(SIMU)' ./Runtest $$i ./$$i.compcert; \ done @echo "----------- Interpreted tests -------------" @for i in $(TESTS); do \ - ./Runtest $$i $(CCOMP) -fall -interp -quiet $$i.c; \ + SIMU='' ./Runtest $$i $(CCOMP) -fall -interp -quiet $$i.c; \ done @for i in $(TESTS_DIFF); do \ if $(CCOMP) -fall -interp -quiet $$i.c > _cinterp.log; then \ - if ./$$i.compcert | cmp -s _cinterp.log -; \ + if $(SIMU) ./$$i.compcert | cmp -s _cinterp.log -; \ then echo "$$i: compiler and interpreter agree"; \ else echo "$$i: compiler and interpreter DISAGREE"; \ fi; \ diff --git a/test/regression/Results/builtins-riscV b/test/regression/Results/builtins-riscV new file mode 100644 index 00000000..1576b252 --- /dev/null +++ b/test/regression/Results/builtins-riscV @@ -0,0 +1,12 @@ +bswap16(1234) = 3412 +bswap32(12345678) = 78563412 +bswap64(123456789abcdef0) = f0debc9a78563412 +fmadd(3.141590, 2.718000, 1.414000) = 9.952842 +fmsub(3.141590, 2.718000, 1.414000) = 7.124842 +fnmadd(3.141590, 2.718000, 1.414000) = -9.952842 +fnmsub(3.141590, 2.718000, 1.414000) = -7.124842 +fabs(3.141590) = 3.141590 +fabs(-3.141590) = 3.141590 +fsqrt(3.141590) = 1.772453 +fmax(3.141590, 2.718000) = 3.141590 +fmin(3.141590, 2.718000) = 2.718000 diff --git a/test/regression/Runtest b/test/regression/Runtest index 9051b5b7..ad2a58f1 100755 --- a/test/regression/Runtest +++ b/test/regression/Runtest @@ -27,7 +27,7 @@ else fi # Administer the test -if $* > $out +if $SIMU $* > $out then if test -n "$ref"; then if cmp -s "$out" "$ref"; then diff --git a/test/regression/alignas.c b/test/regression/alignas.c index a6a2e690..b3754039 100644 --- a/test/regression/alignas.c +++ b/test/regression/alignas.c @@ -7,6 +7,13 @@ #define _Alignof(x) __alignof__(x) #endif +#ifdef _Alignas +#undef _Alignas +#endif +#ifdef _Alignof +#undef _Alignof +#endif + /* Base type */ int _Alignas(16) a; char filler1; diff --git a/test/regression/builtins-riscV.c b/test/regression/builtins-riscV.c new file mode 100644 index 00000000..a302a6c4 --- /dev/null +++ b/test/regression/builtins-riscV.c @@ -0,0 +1,30 @@ +/* Fun with builtins */ + +#include + +int main(int argc, char ** argv) +{ + unsigned int x = 0x12345678; + unsigned short s = 0x1234; + unsigned long long zz = 0x123456789ABCDEF0ULL; + double a = 3.14159; + double b = 2.718; + double c = 1.414; + + printf("bswap16(%x) = %x\n", s, __builtin_bswap16(s)); + printf("bswap32(%x) = %x\n", x, __builtin_bswap32(x)); + printf("bswap64(%llx) = %llx\n", zz, __builtin_bswap64(zz)); + printf("fmadd(%f, %f, %f) = %f\n", a, b, c, __builtin_fmadd(a, b, c)); + printf("fmsub(%f, %f, %f) = %f\n", a, b, c, __builtin_fmsub(a, b, c)); + printf("fnmadd(%f, %f, %f) = %f\n", a, b, c, __builtin_fnmadd(a, b, c)); + printf("fnmsub(%f, %f, %f) = %f\n", a, b, c, __builtin_fnmsub(a, b, c)); + printf("fabs(%f) = %f\n", a, __builtin_fabs(a)); + printf("fabs(%f) = %f\n", -a, __builtin_fabs(-a)); + printf("fsqrt(%f) = %f\n", a, __builtin_fsqrt(a)); + printf("fmax(%f, %f) = %f\n", a, b, __builtin_fmax(a, b)); + printf("fmin(%f, %f) = %f\n", a, b, __builtin_fmin(a, b)); + /* Make sure that ignoring the result of a builtin + doesn't cause an internal error */ + (void) __builtin_fsqrt(a); + return 0; +} diff --git a/test/regression/extasm.c b/test/regression/extasm.c index c0534047..a41c4202 100644 --- a/test/regression/extasm.c +++ b/test/regression/extasm.c @@ -18,7 +18,7 @@ int clobbers(int x, int z) return y + z; } -#if defined(__x86_64__) +#if defined(__x86_64__) || __riscv_xlen == 64 #define SIXTYFOUR #else #undef SIXTYFOUR diff --git a/test/regression/floats-basics.c b/test/regression/floats-basics.c index 5aa91d14..a7ba3623 100644 --- a/test/regression/floats-basics.c +++ b/test/regression/floats-basics.c @@ -6,7 +6,8 @@ #if defined(__ppc__) || defined(__PPC__) || defined(__ARMEB__) #define ARCH_BIG_ENDIAN -#elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) +#elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) \ + || defined(__riscv) #undef ARCH_BIG_ENDIAN #else #error "unknown endianness" diff --git a/test/regression/floats.c b/test/regression/floats.c index 68d60f65..84c4e062 100644 --- a/test/regression/floats.c +++ b/test/regression/floats.c @@ -5,7 +5,8 @@ #if defined(__ppc__) || defined(__PPC__) || defined(__ARMEB__) #define ARCH_BIG_ENDIAN -#elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) +#elif defined(__i386__) || defined(__x86_64__) || defined(__ARMEL__) \ + || defined(__riscv) #undef ARCH_BIG_ENDIAN #else #error "unknown endianness" diff --git a/test/spass/Makefile b/test/spass/Makefile index f6acc551..110359ad 100644 --- a/test/spass/Makefile +++ b/test/spass/Makefile @@ -22,7 +22,7 @@ clean: rm -f *.o *.s *.parsed.c *.light.c *.sdump test: - ./spass small_problem.dfg | grep 'Proof found' + $(SIMU) ./spass small_problem.dfg | grep 'Proof found' TIME=xtime -o /dev/null # Xavier's hack #TIME=time >/dev/null # Otherwise -- cgit