Update cmd/dc.
This commit is contained in:
@@ -2,8 +2,39 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <signal.h>
|
#include <signal.h>
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
#include "dc.h"
|
#include "dc.h"
|
||||||
|
|
||||||
|
void init(int argc, char *argv[]);
|
||||||
|
void commnds(void);
|
||||||
|
int readc(void);
|
||||||
|
void unreadc(char c);
|
||||||
|
void pushp(struct blk *p);
|
||||||
|
void sdump(char *s1, struct blk *hptr);
|
||||||
|
void chsign(struct blk *p);
|
||||||
|
void more(struct blk *hptr);
|
||||||
|
int subt(void);
|
||||||
|
int eqk(void);
|
||||||
|
void binop(char c);
|
||||||
|
int dscale(void);
|
||||||
|
void release(struct blk *p);
|
||||||
|
int log2v(long n);
|
||||||
|
void print(struct blk *hptr);
|
||||||
|
void load(void);
|
||||||
|
void seekc(struct blk *hptr, int n);
|
||||||
|
void salterwd(struct wblk *hptr, struct blk *n);
|
||||||
|
void putwd(struct blk *p, struct blk *c);
|
||||||
|
int command(void);
|
||||||
|
int cond(char c);
|
||||||
|
void oneot(struct blk *p, int sc, char ch);
|
||||||
|
void tenot(struct blk *p, int sc);
|
||||||
|
void hexot(struct blk *p, int flg);
|
||||||
|
void bigot(struct blk *p, int flg);
|
||||||
|
void garbage(char *s);
|
||||||
|
void ospace(char *s);
|
||||||
|
void redef(struct blk *p);
|
||||||
|
|
||||||
|
int
|
||||||
main(argc,argv)
|
main(argc,argv)
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[];
|
char *argv[];
|
||||||
@@ -12,6 +43,7 @@ char *argv[];
|
|||||||
commnds();
|
commnds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
commnds()
|
commnds()
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
@@ -491,7 +523,7 @@ sempty:
|
|||||||
if (q!=NULL) release(q);
|
if (q!=NULL) release(q);
|
||||||
s = pop();
|
s = pop();
|
||||||
EMPTY;
|
EMPTY;
|
||||||
salterwd(p,s);
|
salterwd((struct wblk *) p, s);
|
||||||
sptr->val = p;
|
sptr->val = p;
|
||||||
continue;
|
continue;
|
||||||
case ';':
|
case ';':
|
||||||
@@ -703,6 +735,7 @@ ddone:
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
dscale()
|
dscale()
|
||||||
{
|
{
|
||||||
register struct blk *dd,*dr;
|
register struct blk *dd,*dr;
|
||||||
@@ -873,7 +906,8 @@ edone:
|
|||||||
return(r);
|
return(r);
|
||||||
}
|
}
|
||||||
|
|
||||||
void onintr(sig)
|
void
|
||||||
|
onintr(sig)
|
||||||
{
|
{
|
||||||
signal(SIGINT,onintr);
|
signal(SIGINT,onintr);
|
||||||
while(readptr != &readstk[0]){
|
while(readptr != &readstk[0]){
|
||||||
@@ -884,6 +918,7 @@ void onintr(sig)
|
|||||||
commnds();
|
commnds();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
init(argc,argv)
|
init(argc,argv)
|
||||||
int argc;
|
int argc;
|
||||||
char *argv[];
|
char *argv[];
|
||||||
@@ -943,6 +978,7 @@ char *argv[];
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
pushp(p)
|
pushp(p)
|
||||||
struct blk *p;
|
struct blk *p;
|
||||||
{
|
{
|
||||||
@@ -1098,6 +1134,7 @@ struct blk *p,*q;
|
|||||||
return(mr);
|
return(mr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
chsign(p)
|
chsign(p)
|
||||||
struct blk *p;
|
struct blk *p;
|
||||||
{
|
{
|
||||||
@@ -1133,6 +1170,7 @@ struct blk *p;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
readc()
|
readc()
|
||||||
{
|
{
|
||||||
loop:
|
loop:
|
||||||
@@ -1157,8 +1195,8 @@ loop:
|
|||||||
exit(0);
|
exit(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
unreadc(c)
|
void
|
||||||
char c;
|
unreadc(char c)
|
||||||
{
|
{
|
||||||
|
|
||||||
if((readptr != &readstk[0]) && (*readptr != 0)){
|
if((readptr != &readstk[0]) && (*readptr != 0)){
|
||||||
@@ -1168,8 +1206,8 @@ char c;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
binop(c)
|
void
|
||||||
char c;
|
binop(char c)
|
||||||
{
|
{
|
||||||
register struct blk *r;
|
register struct blk *r;
|
||||||
|
|
||||||
@@ -1191,6 +1229,7 @@ char c;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
print(hptr)
|
print(hptr)
|
||||||
struct blk *hptr;
|
struct blk *hptr;
|
||||||
{
|
{
|
||||||
@@ -1304,6 +1343,7 @@ struct blk *p;
|
|||||||
return(q);
|
return(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
tenot(p,sc)
|
tenot(p,sc)
|
||||||
struct blk *p;
|
struct blk *p;
|
||||||
{
|
{
|
||||||
@@ -1354,9 +1394,8 @@ struct blk *p;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
oneot(p,sc,ch)
|
void
|
||||||
struct blk *p;
|
oneot(struct blk *p, int sc, char ch)
|
||||||
char ch;
|
|
||||||
{
|
{
|
||||||
register struct blk *q;
|
register struct blk *q;
|
||||||
|
|
||||||
@@ -1374,6 +1413,7 @@ char ch;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
hexot(p,flg)
|
hexot(p,flg)
|
||||||
struct blk *p;
|
struct blk *p;
|
||||||
{
|
{
|
||||||
@@ -1394,6 +1434,7 @@ struct blk *p;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
bigot(p,flg)
|
bigot(p,flg)
|
||||||
struct blk *p;
|
struct blk *p;
|
||||||
{
|
{
|
||||||
@@ -1494,6 +1535,7 @@ struct blk *a1,*a2;
|
|||||||
return(p);
|
return(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
eqk()
|
eqk()
|
||||||
{
|
{
|
||||||
register struct blk *p,*q;
|
register struct blk *p,*q;
|
||||||
@@ -1577,6 +1619,7 @@ struct blk *p;
|
|||||||
return(q);
|
return(q);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
subt()
|
subt()
|
||||||
{
|
{
|
||||||
arg1=pop();
|
arg1=pop();
|
||||||
@@ -1590,6 +1633,7 @@ subt()
|
|||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
command()
|
command()
|
||||||
{
|
{
|
||||||
int c;
|
int c;
|
||||||
@@ -1622,8 +1666,8 @@ command()
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
cond(c)
|
int
|
||||||
char c;
|
cond(char c)
|
||||||
{
|
{
|
||||||
register struct blk *p;
|
register struct blk *p;
|
||||||
register char cc;
|
register char cc;
|
||||||
@@ -1664,6 +1708,7 @@ char c;
|
|||||||
return(1);
|
return(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
load()
|
load()
|
||||||
{
|
{
|
||||||
register int c;
|
register int c;
|
||||||
@@ -1699,6 +1744,7 @@ load()
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int
|
||||||
log2v(n)
|
log2v(n)
|
||||||
long n;
|
long n;
|
||||||
{
|
{
|
||||||
@@ -1793,17 +1839,20 @@ int size;
|
|||||||
return(hdr);
|
return(hdr);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
sdump(s1,hptr)
|
sdump(s1,hptr)
|
||||||
char *s1;
|
char *s1;
|
||||||
struct blk *hptr;
|
struct blk *hptr;
|
||||||
{
|
{
|
||||||
char *p;
|
char *p;
|
||||||
printf("%s %o rd %o wt %o beg %o last %o\n",s1,hptr,hptr->rd,hptr->wt,hptr->beg,hptr->last);
|
printf("%s %p rd %p wt %p beg %p last %p\n",
|
||||||
|
s1, hptr, hptr->rd, hptr->wt, hptr->beg, hptr->last);
|
||||||
p = hptr->beg;
|
p = hptr->beg;
|
||||||
while(p < hptr->wt)printf("%d ",*p++);
|
while(p < hptr->wt)printf("%d ",*p++);
|
||||||
printf("\n");
|
printf("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
seekc(hptr,n)
|
seekc(hptr,n)
|
||||||
struct blk *hptr;
|
struct blk *hptr;
|
||||||
{
|
{
|
||||||
@@ -1828,16 +1877,19 @@ struct blk *hptr;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
salterwd(hptr,n)
|
salterwd(hptr,n)
|
||||||
struct wblk *hptr;
|
struct wblk *hptr;
|
||||||
struct blk *n;
|
struct blk *n;
|
||||||
{
|
{
|
||||||
if(hptr->rdw == hptr->lastw)more(hptr);
|
if (hptr->rdw == hptr->lastw)
|
||||||
|
more((struct blk *) hptr);
|
||||||
*hptr->rdw++ = n;
|
*hptr->rdw++ = n;
|
||||||
if(hptr->rdw > hptr->wtw)hptr->wtw = hptr->rdw;
|
if (hptr->rdw > hptr->wtw)
|
||||||
return;
|
hptr->wtw = hptr->rdw;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
more(hptr)
|
more(hptr)
|
||||||
struct blk *hptr;
|
struct blk *hptr;
|
||||||
{
|
{
|
||||||
@@ -1860,6 +1912,7 @@ struct blk *hptr;
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
ospace(s)
|
ospace(s)
|
||||||
char *s;
|
char *s;
|
||||||
{
|
{
|
||||||
@@ -1870,6 +1923,7 @@ char *s;
|
|||||||
abort();
|
abort();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
garbage(s)
|
garbage(s)
|
||||||
char *s;
|
char *s;
|
||||||
{
|
{
|
||||||
@@ -1904,7 +1958,7 @@ char *s;
|
|||||||
if(q != 0){
|
if(q != 0){
|
||||||
if(((int)q->beg & 01) != 0){
|
if(((int)q->beg & 01) != 0){
|
||||||
printf("array %o elt %d odd\n",i-ARRAYST,ct);
|
printf("array %o elt %d odd\n",i-ARRAYST,ct);
|
||||||
printf("tmps %o p %o\n",tmps,p);
|
printf("tmps %p p %p\n", tmps, p);
|
||||||
sdump("elt",q);
|
sdump("elt",q);
|
||||||
}
|
}
|
||||||
redef(q);
|
redef(q);
|
||||||
@@ -1917,14 +1971,15 @@ printf("tmps %o p %o\n",tmps,p);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
redef(p)
|
redef(p)
|
||||||
struct blk *p;
|
struct blk *p;
|
||||||
{
|
{
|
||||||
register offset;
|
register int offset;
|
||||||
register char *newp;
|
register char *newp;
|
||||||
|
|
||||||
if ((int)p->beg&01) {
|
if ((int)p->beg&01) {
|
||||||
printf("odd ptr %o hdr %o\n",p->beg,p);
|
printf("odd ptr %p hdr %p\n",p->beg,p);
|
||||||
ospace("redef-bad");
|
ospace("redef-bad");
|
||||||
}
|
}
|
||||||
newp = realloc(p->beg, (unsigned)(p->last-p->beg));
|
newp = realloc(p->beg, (unsigned)(p->last-p->beg));
|
||||||
@@ -1936,6 +1991,7 @@ struct blk *p;
|
|||||||
p->last += offset;
|
p->last += offset;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
release(p)
|
release(p)
|
||||||
register struct blk *p;
|
register struct blk *p;
|
||||||
{
|
{
|
||||||
@@ -1958,6 +2014,7 @@ struct blk *p;
|
|||||||
return(*wp->rdw++);
|
return(*wp->rdw++);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
putwd(p, c)
|
putwd(p, c)
|
||||||
struct blk *p, *c;
|
struct blk *p, *c;
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -103,8 +103,7 @@ long all;
|
|||||||
long headmor;
|
long headmor;
|
||||||
long obase;
|
long obase;
|
||||||
int fw,fw1,ll;
|
int fw,fw1,ll;
|
||||||
int (*outdit)();
|
void (*outdit)(struct blk *p, int flg);
|
||||||
int bigot(),hexot();
|
|
||||||
int logo;
|
int logo;
|
||||||
int log10v;
|
int log10v;
|
||||||
int count;
|
int count;
|
||||||
|
|||||||
@@ -21,10 +21,11 @@ CFLAGS += ${DEFS}
|
|||||||
|
|
||||||
OBJS = adddf3.o \
|
OBJS = adddf3.o \
|
||||||
addsf3.o \
|
addsf3.o \
|
||||||
divdf3.o \
|
|
||||||
divsf3.o \
|
|
||||||
comparedf2.o \
|
comparedf2.o \
|
||||||
comparesf2.o \
|
comparesf2.o \
|
||||||
|
divdf3.o \
|
||||||
|
divdi3.o \
|
||||||
|
divsf3.o \
|
||||||
extendsfdf2.o \
|
extendsfdf2.o \
|
||||||
fixdfsi.o \
|
fixdfsi.o \
|
||||||
fixsfsi.o \
|
fixsfsi.o \
|
||||||
@@ -32,11 +33,15 @@ OBJS = adddf3.o \
|
|||||||
floatsisf.o \
|
floatsisf.o \
|
||||||
floatunsisf.o \
|
floatunsisf.o \
|
||||||
fp_mode.o \
|
fp_mode.o \
|
||||||
|
moddi3.o \
|
||||||
muldf3.o \
|
muldf3.o \
|
||||||
mulsf3.o \
|
mulsf3.o \
|
||||||
subdf3.o \
|
subdf3.o \
|
||||||
subsf3.o \
|
subsf3.o \
|
||||||
truncdfsf2.o
|
truncdfsf2.o \
|
||||||
|
udivdi3.o \
|
||||||
|
udivmoddi4.o \
|
||||||
|
umoddi3.o
|
||||||
|
|
||||||
runtime.a: ${OBJS}
|
runtime.a: ${OBJS}
|
||||||
@echo "buiding runtime.a"
|
@echo "buiding runtime.a"
|
||||||
|
|||||||
22
src/libc/runtime/divdi3.c
Normal file
22
src/libc/runtime/divdi3.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//===-- divdi3.c - Implement __divdi3 -------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements __divdi3 for the compiler_rt library.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "int_lib.h"
|
||||||
|
|
||||||
|
// Returns: a / b
|
||||||
|
|
||||||
|
#define fixint_t di_int
|
||||||
|
#define fixuint_t du_int
|
||||||
|
#define COMPUTE_UDIV(a, b) __udivmoddi4((a), (b), (du_int *)0)
|
||||||
|
#include "int_div_impl.inc"
|
||||||
|
|
||||||
|
COMPILER_RT_ABI di_int __divdi3(di_int a, di_int b) { return __divXi3(a, b); }
|
||||||
95
src/libc/runtime/int_div_impl.inc
Normal file
95
src/libc/runtime/int_div_impl.inc
Normal file
@@ -0,0 +1,95 @@
|
|||||||
|
//===-- int_div_impl.inc - Integer division ---------------------*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// Helpers used by __udivsi3, __umodsi3, __udivdi3, and __umodsi3.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#define clz(a) (sizeof(a) == sizeof(unsigned long long) ? __builtin_clzll(a) : clzsi(a))
|
||||||
|
|
||||||
|
// Adapted from Figure 3-40 of The PowerPC Compiler Writer's Guide
|
||||||
|
static __inline fixuint_t __udivXi3(fixuint_t n, fixuint_t d) {
|
||||||
|
const unsigned N = sizeof(fixuint_t) * CHAR_BIT;
|
||||||
|
// d == 0 cases are unspecified.
|
||||||
|
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
|
||||||
|
// 0 <= sr <= N - 1 or sr is very large.
|
||||||
|
if (sr > N - 1) // n < d
|
||||||
|
return 0;
|
||||||
|
if (sr == N - 1) // d == 1
|
||||||
|
return n;
|
||||||
|
++sr;
|
||||||
|
// 1 <= sr <= N - 1. Shifts do not trigger UB.
|
||||||
|
fixuint_t r = n >> sr;
|
||||||
|
n <<= N - sr;
|
||||||
|
fixuint_t carry = 0;
|
||||||
|
for (; sr > 0; --sr) {
|
||||||
|
r = (r << 1) | (n >> (N - 1));
|
||||||
|
n = (n << 1) | carry;
|
||||||
|
// Branch-less version of:
|
||||||
|
// carry = 0;
|
||||||
|
// if (r >= d) r -= d, carry = 1;
|
||||||
|
const fixint_t s = (fixint_t)(d - r - 1) >> (N - 1);
|
||||||
|
carry = s & 1;
|
||||||
|
r -= d & s;
|
||||||
|
}
|
||||||
|
n = (n << 1) | carry;
|
||||||
|
return n;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Mostly identical to __udivXi3 but the return values are different.
|
||||||
|
static __inline fixuint_t __umodXi3(fixuint_t n, fixuint_t d) {
|
||||||
|
const unsigned N = sizeof(fixuint_t) * CHAR_BIT;
|
||||||
|
// d == 0 cases are unspecified.
|
||||||
|
unsigned sr = (d ? clz(d) : N) - (n ? clz(n) : N);
|
||||||
|
// 0 <= sr <= N - 1 or sr is very large.
|
||||||
|
if (sr > N - 1) // n < d
|
||||||
|
return n;
|
||||||
|
if (sr == N - 1) // d == 1
|
||||||
|
return 0;
|
||||||
|
++sr;
|
||||||
|
// 1 <= sr <= N - 1. Shifts do not trigger UB.
|
||||||
|
fixuint_t r = n >> sr;
|
||||||
|
n <<= N - sr;
|
||||||
|
fixuint_t carry = 0;
|
||||||
|
for (; sr > 0; --sr) {
|
||||||
|
r = (r << 1) | (n >> (N - 1));
|
||||||
|
n = (n << 1) | carry;
|
||||||
|
// Branch-less version of:
|
||||||
|
// carry = 0;
|
||||||
|
// if (r >= d) r -= d, carry = 1;
|
||||||
|
const fixint_t s = (fixint_t)(d - r - 1) >> (N - 1);
|
||||||
|
carry = s & 1;
|
||||||
|
r -= d & s;
|
||||||
|
}
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef COMPUTE_UDIV
|
||||||
|
static __inline fixint_t __divXi3(fixint_t a, fixint_t b) {
|
||||||
|
const int N = (int)(sizeof(fixint_t) * CHAR_BIT) - 1;
|
||||||
|
fixint_t s_a = a >> N; // s_a = a < 0 ? -1 : 0
|
||||||
|
fixint_t s_b = b >> N; // s_b = b < 0 ? -1 : 0
|
||||||
|
fixuint_t a_u = (fixuint_t)(a ^ s_a) + (-s_a); // negate if s_a == -1
|
||||||
|
fixuint_t b_u = (fixuint_t)(b ^ s_b) + (-s_b); // negate if s_b == -1
|
||||||
|
s_a ^= s_b; // sign of quotient
|
||||||
|
return (COMPUTE_UDIV(a_u, b_u) ^ s_a) + (-s_a); // negate if s_a == -1
|
||||||
|
}
|
||||||
|
#endif // COMPUTE_UDIV
|
||||||
|
|
||||||
|
#ifdef ASSIGN_UMOD
|
||||||
|
static __inline fixint_t __modXi3(fixint_t a, fixint_t b) {
|
||||||
|
const int N = (int)(sizeof(fixint_t) * CHAR_BIT) - 1;
|
||||||
|
fixint_t s = b >> N; // s = b < 0 ? -1 : 0
|
||||||
|
fixuint_t b_u = (fixuint_t)(b ^ s) + (-s); // negate if s == -1
|
||||||
|
s = a >> N; // s = a < 0 ? -1 : 0
|
||||||
|
fixuint_t a_u = (fixuint_t)(a ^ s) + (-s); // negate if s == -1
|
||||||
|
fixuint_t res;
|
||||||
|
ASSIGN_UMOD(res, a_u, b_u);
|
||||||
|
return (res ^ s) + (-s); // negate if s == -1
|
||||||
|
}
|
||||||
|
#endif // ASSIGN_UMOD
|
||||||
22
src/libc/runtime/moddi3.c
Normal file
22
src/libc/runtime/moddi3.c
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
//===-- moddi3.c - Implement __moddi3 -------------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements __moddi3 for the compiler_rt library.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "int_lib.h"
|
||||||
|
|
||||||
|
// Returns: a % b
|
||||||
|
|
||||||
|
#define fixint_t di_int
|
||||||
|
#define fixuint_t du_int
|
||||||
|
#define ASSIGN_UMOD(res, a, b) __udivmoddi4((a), (b), &(res))
|
||||||
|
#include "int_div_impl.inc"
|
||||||
|
|
||||||
|
COMPILER_RT_ABI di_int __moddi3(di_int a, di_int b) { return __modXi3(a, b); }
|
||||||
23
src/libc/runtime/udivdi3.c
Normal file
23
src/libc/runtime/udivdi3.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//===-- udivdi3.c - Implement __udivdi3 -----------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements __udivdi3 for the compiler_rt library.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "int_lib.h"
|
||||||
|
|
||||||
|
typedef du_int fixuint_t;
|
||||||
|
typedef di_int fixint_t;
|
||||||
|
#include "int_div_impl.inc"
|
||||||
|
|
||||||
|
// Returns: a / b
|
||||||
|
|
||||||
|
COMPILER_RT_ABI du_int __udivdi3(du_int a, du_int b) {
|
||||||
|
return __udivXi3(a, b);
|
||||||
|
}
|
||||||
200
src/libc/runtime/udivmoddi4.c
Normal file
200
src/libc/runtime/udivmoddi4.c
Normal file
@@ -0,0 +1,200 @@
|
|||||||
|
//===-- udivmoddi4.c - Implement __udivmoddi4 -----------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements __udivmoddi4 for the compiler_rt library.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "int_lib.h"
|
||||||
|
|
||||||
|
// Effects: if rem != 0, *rem = a % b
|
||||||
|
// Returns: a / b
|
||||||
|
|
||||||
|
// Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
// MSVC throws a warning about mod 0 here, disable it for builds that
|
||||||
|
// warn-as-error
|
||||||
|
#pragma warning(push)
|
||||||
|
#pragma warning(disable : 4724)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem) {
|
||||||
|
const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT;
|
||||||
|
const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT;
|
||||||
|
udwords n;
|
||||||
|
n.all = a;
|
||||||
|
udwords d;
|
||||||
|
d.all = b;
|
||||||
|
udwords q;
|
||||||
|
udwords r;
|
||||||
|
unsigned sr;
|
||||||
|
// special cases, X is unknown, K != 0
|
||||||
|
if (n.s.high == 0) {
|
||||||
|
if (d.s.high == 0) {
|
||||||
|
// 0 X
|
||||||
|
// ---
|
||||||
|
// 0 X
|
||||||
|
if (rem)
|
||||||
|
*rem = n.s.low % d.s.low;
|
||||||
|
return n.s.low / d.s.low;
|
||||||
|
}
|
||||||
|
// 0 X
|
||||||
|
// ---
|
||||||
|
// K X
|
||||||
|
if (rem)
|
||||||
|
*rem = n.s.low;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
// n.s.high != 0
|
||||||
|
if (d.s.low == 0) {
|
||||||
|
if (d.s.high == 0) {
|
||||||
|
// K X
|
||||||
|
// ---
|
||||||
|
// 0 0
|
||||||
|
if (rem)
|
||||||
|
*rem = n.s.high % d.s.low;
|
||||||
|
return n.s.high / d.s.low;
|
||||||
|
}
|
||||||
|
// d.s.high != 0
|
||||||
|
if (n.s.low == 0) {
|
||||||
|
// K 0
|
||||||
|
// ---
|
||||||
|
// K 0
|
||||||
|
if (rem) {
|
||||||
|
r.s.high = n.s.high % d.s.high;
|
||||||
|
r.s.low = 0;
|
||||||
|
*rem = r.all;
|
||||||
|
}
|
||||||
|
return n.s.high / d.s.high;
|
||||||
|
}
|
||||||
|
// K K
|
||||||
|
// ---
|
||||||
|
// K 0
|
||||||
|
if ((d.s.high & (d.s.high - 1)) == 0) /* if d is a power of 2 */ {
|
||||||
|
if (rem) {
|
||||||
|
r.s.low = n.s.low;
|
||||||
|
r.s.high = n.s.high & (d.s.high - 1);
|
||||||
|
*rem = r.all;
|
||||||
|
}
|
||||||
|
return n.s.high >> __builtin_ctz(d.s.high);
|
||||||
|
}
|
||||||
|
// K K
|
||||||
|
// ---
|
||||||
|
// K 0
|
||||||
|
sr = clzsi(d.s.high) - clzsi(n.s.high);
|
||||||
|
// 0 <= sr <= n_uword_bits - 2 or sr large
|
||||||
|
if (sr > n_uword_bits - 2) {
|
||||||
|
if (rem)
|
||||||
|
*rem = n.all;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++sr;
|
||||||
|
// 1 <= sr <= n_uword_bits - 1
|
||||||
|
// q.all = n.all << (n_udword_bits - sr);
|
||||||
|
q.s.low = 0;
|
||||||
|
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||||
|
// r.all = n.all >> sr;
|
||||||
|
r.s.high = n.s.high >> sr;
|
||||||
|
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||||
|
} else /* d.s.low != 0 */ {
|
||||||
|
if (d.s.high == 0) {
|
||||||
|
// K X
|
||||||
|
// ---
|
||||||
|
// 0 K
|
||||||
|
if ((d.s.low & (d.s.low - 1)) == 0) /* if d is a power of 2 */ {
|
||||||
|
if (rem)
|
||||||
|
*rem = n.s.low & (d.s.low - 1);
|
||||||
|
if (d.s.low == 1)
|
||||||
|
return n.all;
|
||||||
|
sr = __builtin_ctz(d.s.low);
|
||||||
|
q.s.high = n.s.high >> sr;
|
||||||
|
q.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||||
|
return q.all;
|
||||||
|
}
|
||||||
|
// K X
|
||||||
|
// ---
|
||||||
|
// 0 K
|
||||||
|
sr = 1 + n_uword_bits + clzsi(d.s.low) - clzsi(n.s.high);
|
||||||
|
// 2 <= sr <= n_udword_bits - 1
|
||||||
|
// q.all = n.all << (n_udword_bits - sr);
|
||||||
|
// r.all = n.all >> sr;
|
||||||
|
if (sr == n_uword_bits) {
|
||||||
|
q.s.low = 0;
|
||||||
|
q.s.high = n.s.low;
|
||||||
|
r.s.high = 0;
|
||||||
|
r.s.low = n.s.high;
|
||||||
|
} else if (sr < n_uword_bits) /* 2 <= sr <= n_uword_bits - 1 */ {
|
||||||
|
q.s.low = 0;
|
||||||
|
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||||
|
r.s.high = n.s.high >> sr;
|
||||||
|
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||||
|
} else /* n_uword_bits + 1 <= sr <= n_udword_bits - 1 */ {
|
||||||
|
q.s.low = n.s.low << (n_udword_bits - sr);
|
||||||
|
q.s.high = (n.s.high << (n_udword_bits - sr)) |
|
||||||
|
(n.s.low >> (sr - n_uword_bits));
|
||||||
|
r.s.high = 0;
|
||||||
|
r.s.low = n.s.high >> (sr - n_uword_bits);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// K X
|
||||||
|
// ---
|
||||||
|
// K K
|
||||||
|
sr = clzsi(d.s.high) - clzsi(n.s.high);
|
||||||
|
// 0 <= sr <= n_uword_bits - 1 or sr large
|
||||||
|
if (sr > n_uword_bits - 1) {
|
||||||
|
if (rem)
|
||||||
|
*rem = n.all;
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
++sr;
|
||||||
|
// 1 <= sr <= n_uword_bits
|
||||||
|
// q.all = n.all << (n_udword_bits - sr);
|
||||||
|
q.s.low = 0;
|
||||||
|
if (sr == n_uword_bits) {
|
||||||
|
q.s.high = n.s.low;
|
||||||
|
r.s.high = 0;
|
||||||
|
r.s.low = n.s.high;
|
||||||
|
} else {
|
||||||
|
q.s.high = n.s.low << (n_uword_bits - sr);
|
||||||
|
r.s.high = n.s.high >> sr;
|
||||||
|
r.s.low = (n.s.high << (n_uword_bits - sr)) | (n.s.low >> sr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Not a special case
|
||||||
|
// q and r are initialized with:
|
||||||
|
// q.all = n.all << (n_udword_bits - sr);
|
||||||
|
// r.all = n.all >> sr;
|
||||||
|
// 1 <= sr <= n_udword_bits - 1
|
||||||
|
su_int carry = 0;
|
||||||
|
for (; sr > 0; --sr) {
|
||||||
|
// r:q = ((r:q) << 1) | carry
|
||||||
|
r.s.high = (r.s.high << 1) | (r.s.low >> (n_uword_bits - 1));
|
||||||
|
r.s.low = (r.s.low << 1) | (q.s.high >> (n_uword_bits - 1));
|
||||||
|
q.s.high = (q.s.high << 1) | (q.s.low >> (n_uword_bits - 1));
|
||||||
|
q.s.low = (q.s.low << 1) | carry;
|
||||||
|
// carry = 0;
|
||||||
|
// if (r.all >= d.all)
|
||||||
|
// {
|
||||||
|
// r.all -= d.all;
|
||||||
|
// carry = 1;
|
||||||
|
// }
|
||||||
|
const di_int s = (di_int)(d.all - r.all - 1) >> (n_udword_bits - 1);
|
||||||
|
carry = s & 1;
|
||||||
|
r.all -= d.all & s;
|
||||||
|
}
|
||||||
|
q.all = (q.all << 1) | carry;
|
||||||
|
if (rem)
|
||||||
|
*rem = r.all;
|
||||||
|
return q.all;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(_MSC_VER) && !defined(__clang__)
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
23
src/libc/runtime/umoddi3.c
Normal file
23
src/libc/runtime/umoddi3.c
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
//===-- umoddi3.c - Implement __umoddi3 -----------------------------------===//
|
||||||
|
//
|
||||||
|
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
|
||||||
|
// See https://llvm.org/LICENSE.txt for license information.
|
||||||
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This file implements __umoddi3 for the compiler_rt library.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "int_lib.h"
|
||||||
|
|
||||||
|
typedef du_int fixuint_t;
|
||||||
|
typedef di_int fixint_t;
|
||||||
|
#include "int_div_impl.inc"
|
||||||
|
|
||||||
|
// Returns: a % b
|
||||||
|
|
||||||
|
COMPILER_RT_ABI du_int __umoddi3(du_int a, du_int b) {
|
||||||
|
return __umodXi3(a, b);
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user