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 <signal.h>
#include <unistd.h>
#include <sys/wait.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)
int argc;
char *argv[];
@@ -12,6 +43,7 @@ char *argv[];
commnds();
}
void
commnds()
{
register int c;
@@ -491,7 +523,7 @@ sempty:
if (q!=NULL) release(q);
s = pop();
EMPTY;
salterwd(p,s);
salterwd((struct wblk *) p, s);
sptr->val = p;
continue;
case ';':
@@ -703,6 +735,7 @@ ddone:
return(p);
}
int
dscale()
{
register struct blk *dd,*dr;
@@ -873,7 +906,8 @@ edone:
return(r);
}
void onintr(sig)
void
onintr(sig)
{
signal(SIGINT,onintr);
while(readptr != &readstk[0]){
@@ -884,6 +918,7 @@ void onintr(sig)
commnds();
}
void
init(argc,argv)
int argc;
char *argv[];
@@ -943,6 +978,7 @@ char *argv[];
return;
}
void
pushp(p)
struct blk *p;
{
@@ -1098,6 +1134,7 @@ struct blk *p,*q;
return(mr);
}
void
chsign(p)
struct blk *p;
{
@@ -1133,6 +1170,7 @@ struct blk *p;
return;
}
int
readc()
{
loop:
@@ -1157,8 +1195,8 @@ loop:
exit(0);
}
unreadc(c)
char c;
void
unreadc(char c)
{
if((readptr != &readstk[0]) && (*readptr != 0)){
@@ -1168,8 +1206,8 @@ char c;
return;
}
binop(c)
char c;
void
binop(char c)
{
register struct blk *r;
@@ -1191,6 +1229,7 @@ char c;
return;
}
void
print(hptr)
struct blk *hptr;
{
@@ -1304,6 +1343,7 @@ struct blk *p;
return(q);
}
void
tenot(p,sc)
struct blk *p;
{
@@ -1354,9 +1394,8 @@ struct blk *p;
return;
}
oneot(p,sc,ch)
struct blk *p;
char ch;
void
oneot(struct blk *p, int sc, char ch)
{
register struct blk *q;
@@ -1374,6 +1413,7 @@ char ch;
return;
}
void
hexot(p,flg)
struct blk *p;
{
@@ -1394,6 +1434,7 @@ struct blk *p;
return;
}
void
bigot(p,flg)
struct blk *p;
{
@@ -1494,6 +1535,7 @@ struct blk *a1,*a2;
return(p);
}
int
eqk()
{
register struct blk *p,*q;
@@ -1577,6 +1619,7 @@ struct blk *p;
return(q);
}
int
subt()
{
arg1=pop();
@@ -1590,6 +1633,7 @@ subt()
return(0);
}
int
command()
{
int c;
@@ -1622,8 +1666,8 @@ command()
}
}
cond(c)
char c;
int
cond(char c)
{
register struct blk *p;
register char cc;
@@ -1664,6 +1708,7 @@ char c;
return(1);
}
void
load()
{
register int c;
@@ -1699,6 +1744,7 @@ load()
return;
}
int
log2v(n)
long n;
{
@@ -1793,17 +1839,20 @@ int size;
return(hdr);
}
void
sdump(s1,hptr)
char *s1;
struct blk *hptr;
{
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;
while(p < hptr->wt)printf("%d ",*p++);
printf("\n");
}
void
seekc(hptr,n)
struct blk *hptr;
{
@@ -1828,16 +1877,19 @@ struct blk *hptr;
return;
}
void
salterwd(hptr,n)
struct wblk *hptr;
struct blk *n;
{
if(hptr->rdw == hptr->lastw)more(hptr);
if (hptr->rdw == hptr->lastw)
more((struct blk *) hptr);
*hptr->rdw++ = n;
if(hptr->rdw > hptr->wtw)hptr->wtw = hptr->rdw;
return;
if (hptr->rdw > hptr->wtw)
hptr->wtw = hptr->rdw;
}
void
more(hptr)
struct blk *hptr;
{
@@ -1860,6 +1912,7 @@ struct blk *hptr;
return;
}
void
ospace(s)
char *s;
{
@@ -1870,6 +1923,7 @@ char *s;
abort();
}
void
garbage(s)
char *s;
{
@@ -1904,7 +1958,7 @@ char *s;
if(q != 0){
if(((int)q->beg & 01) != 0){
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);
}
redef(q);
@@ -1917,14 +1971,15 @@ printf("tmps %o p %o\n",tmps,p);
}
}
void
redef(p)
struct blk *p;
{
register offset;
register int offset;
register char *newp;
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");
}
newp = realloc(p->beg, (unsigned)(p->last-p->beg));
@@ -1936,6 +1991,7 @@ struct blk *p;
p->last += offset;
}
void
release(p)
register struct blk *p;
{
@@ -1958,6 +2014,7 @@ struct blk *p;
return(*wp->rdw++);
}
void
putwd(p, c)
struct blk *p, *c;
{

View File

@@ -103,8 +103,7 @@ long all;
long headmor;
long obase;
int fw,fw1,ll;
int (*outdit)();
int bigot(),hexot();
void (*outdit)(struct blk *p, int flg);
int logo;
int log10v;
int count;

View File

@@ -21,10 +21,11 @@ CFLAGS += ${DEFS}
OBJS = adddf3.o \
addsf3.o \
divdf3.o \
divsf3.o \
comparedf2.o \
comparesf2.o \
divdf3.o \
divdi3.o \
divsf3.o \
extendsfdf2.o \
fixdfsi.o \
fixsfsi.o \
@@ -32,11 +33,15 @@ OBJS = adddf3.o \
floatsisf.o \
floatunsisf.o \
fp_mode.o \
moddi3.o \
muldf3.o \
mulsf3.o \
subdf3.o \
subsf3.o \
truncdfsf2.o
truncdfsf2.o \
udivdi3.o \
udivmoddi4.o \
umoddi3.o
runtime.a: ${OBJS}
@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);
}