Update cmd/dc.

This commit is contained in:
Serge
2022-05-27 01:23:51 -07:00
parent bd9f0208d2
commit a47779d9d6
9 changed files with 469 additions and 23 deletions

View File

@@ -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;
{ {

View File

@@ -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;

View File

@@ -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
View 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); }

View 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
View 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); }

View 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);
}

View 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

View 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);
}