diff options
author | Xavier Leroy <xavier.leroy@inria.fr> | 2017-04-28 15:56:59 +0200 |
---|---|---|
committer | Xavier Leroy <xavier.leroy@inria.fr> | 2017-04-28 16:05:51 +0200 |
commit | f642817f0dc761e51c3bd362f75b0068a8d4b0c8 (patch) | |
tree | b5830bb772611d2271c4b7d26f162d5c200dd788 /runtime/c/i64_udivmod.c | |
parent | 2fbdb0c45f0913b9fd8e95606c525fc5bfb3bc6d (diff) | |
download | compcert-f642817f0dc761e51c3bd362f75b0068a8d4b0c8.tar.gz compcert-f642817f0dc761e51c3bd362f75b0068a8d4b0c8.zip |
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 <xavier.leroy@inria.fr>
Date: Thu Apr 13 17:36:10 2017 +0200
RISC-V port, continued
Now working on Asmgen.
commit 36f36eb3a5abfbb8805960443d087b6a83e86005
Author: Xavier Leroy <xavier.leroy@inria.fr>
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.
Diffstat (limited to 'runtime/c/i64_udivmod.c')
-rw-r--r-- | runtime/c/i64_udivmod.c | 22 |
1 files changed, 11 insertions, 11 deletions
diff --git a/runtime/c/i64_udivmod.c b/runtime/c/i64_udivmod.c index d8f5073a..03efbc9d 100644 --- a/runtime/c/i64_udivmod.c +++ b/runtime/c/i64_udivmod.c @@ -37,13 +37,13 @@ #include <stddef.h> #include "i64.h" -static unsigned __i64_udiv6432(unsigned u1, unsigned u0, +static unsigned i64_udiv6432(unsigned u1, unsigned u0, unsigned v, unsigned *r); -static int __i64_nlz(unsigned x); +static int i64_nlz(unsigned x); /* Unsigned division and remainder */ -unsigned long long __i64_udivmod(unsigned long long n, +unsigned long long i64_udivmod(unsigned long long n, unsigned long long d, unsigned long long * rp) { @@ -62,7 +62,7 @@ unsigned long long __i64_udivmod(unsigned long long n, unsigned dl = d; unsigned qh = nh / dl; unsigned rl; - unsigned ql = __i64_udiv6432(nh % dl, nl, dl, &rl); + unsigned ql = i64_udiv6432(nh % dl, nl, dl, &rl); *rp = (unsigned long long) rl; /* high word of remainder is 0 */ return ((unsigned long long) qh) << 32 | ql; } @@ -70,11 +70,11 @@ unsigned long long __i64_udivmod(unsigned long long n, /* General case 64 / 64 */ unsigned dl = d; /* Scale N and D down, giving N' and D' such that 2^31 <= D' < 2^32 */ - int s = 32 - __i64_nlz(dh); /* shift amount, between 1 and 32 */ - unsigned long long np = __i64_shr(n, s); - unsigned dp = (unsigned) __i64_shr(d, s); + int s = 32 - i64_nlz(dh); /* shift amount, between 1 and 32 */ + unsigned long long np = i64_shr(n, s); + unsigned dp = (unsigned) i64_shr(d, s); /* Divide N' by D' to get an approximate quotient Q */ - unsigned q = __i64_udiv6432(np >> 32, np, dp, NULL); + unsigned q = i64_udiv6432(np >> 32, np, dp, NULL); again: ; /* Tentative quotient Q is either correct or one too high */ /* Compute Q * D, checking for overflow */ @@ -99,7 +99,7 @@ unsigned long long __i64_udivmod(unsigned long long n, /* Unsigned division and remainder for 64 bits divided by 32 bits. */ /* This is algorithm "divlu" from _Hacker's Delight_, fig 9.3 */ -static unsigned __i64_udiv6432(unsigned u1, unsigned u0, +static unsigned i64_udiv6432(unsigned u1, unsigned u0, unsigned v, unsigned *r) { const unsigned b = 65536; // Number base (16 bits). @@ -114,7 +114,7 @@ static unsigned __i64_udiv6432(unsigned u1, unsigned u0, if (r != NULL) *r = 0xFFFFFFFFU; // set rem to an impossible value, return 0xFFFFFFFFU; // and return largest possible quotient. } - s = __i64_nlz(v); // 0 <= s <= 31. + s = i64_nlz(v); // 0 <= s <= 31. v = v << s; // Normalize divisor. vn1 = v >> 16; // Break divisor up into vn0 = v & 0xFFFF; // two 16-bit digits. @@ -145,7 +145,7 @@ again2: /* Number of leading zeroes */ -static int __i64_nlz(unsigned x) +static int i64_nlz(unsigned x) { if (x == 0) return 32; int n = 0; |