Exemplo n.º 1
0
void
mpxorfixfix(Mpint *a, Mpint *b)
{
	int i;
	long x, *a1, *b1;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mporfixfix");
		mpmovecfix(a, 0);
		a->ovf = 1;
		return;
	}
	if(a->neg) {
		a->neg = 0;
		mpneg(a);
	}
	if(b->neg)
		mpneg(b);

	a1 = &a->a[0];
	b1 = &b->a[0];
	for(i=0; i<Mpprec; i++) {
		x = *a1 ^ *b1++;
		*a1++ = x;
	}

	if(b->neg)
		mpneg(b);
	if(x & Mpsign) {
		a->neg = 1;
		mpneg(a);
	}
}
Exemplo n.º 2
0
int
Bconv(Fmt *fp)
{
	char buf[500], *p;
	Mpint *xval, q, r, ten;
	int f;

	xval = va_arg(fp->args, Mpint*);
	mpmovefixfix(&q, xval);
	f = 0;
	if(mptestfix(&q) < 0) {
		f = 1;
		mpnegfix(&q);
	}
	mpmovecfix(&ten, 10);

	p = &buf[sizeof(buf)];
	*--p = 0;
	for(;;) {
		mpdivmodfixfix(&q, &r, &q, &ten);
		*--p = mpgetfix(&r) + '0';
		if(mptestfix(&q) <= 0)
			break;
	}
	if(f)
		*--p = '-';
	return fmtstrcpy(fp, p);
}
Exemplo n.º 3
0
int
mpcmpfixc(Mpint *b, vlong c)
{
	Mpint c1;

	mpmovecfix(&c1, c);
	return mpcmpfixfix(b, &c1);
}
Exemplo n.º 4
0
void
mpmulcfix(Mpint *a, vlong c)
{
	Mpint b;

	mpmovecfix(&b, c);
	mpmulfixfix(a, &b);
}
Exemplo n.º 5
0
Arquivo: mparith1.c Projeto: hfeeki/go
int
mpcmpfixc(Mpint *b, vlong c)
{
	Mpint a;

	mpmovecfix(&a, c);
	return mpcmpfixfix(&a, b);
}
Exemplo n.º 6
0
int
Bconv(Fmt *fp)
{
	char buf[500], *p;
	Mpint *xval, q, r, ten, sixteen;
	int f, digit;

	xval = va_arg(fp->args, Mpint*);
	mpmovefixfix(&q, xval);
	f = 0;
	if(mptestfix(&q) < 0) {
		f = 1;
		mpnegfix(&q);
	}

	p = &buf[sizeof(buf)];
	*--p = 0;
	if(fp->flags & FmtSharp) {
		// Hexadecimal
		mpmovecfix(&sixteen, 16);
		for(;;) {
			mpdivmodfixfix(&q, &r, &q, &sixteen);
			digit = mpgetfix(&r);
			if(digit < 10)
				*--p = digit + '0';
			else
				*--p = digit - 10 + 'A';
			if(mptestfix(&q) <= 0)
				break;
		}
		*--p = 'x';
		*--p = '0';
	} else {
		// Decimal
		mpmovecfix(&ten, 10);
		for(;;) {
			mpdivmodfixfix(&q, &r, &q, &ten);
			*--p = mpgetfix(&r) + '0';
			if(mptestfix(&q) <= 0)
				break;
		}
	}
	if(f)
		*--p = '-';
	return fmtstrcpy(fp, p);
}
Exemplo n.º 7
0
void
mpaddcfix(Mpint *a, vlong c)
{
	Mpint b;

	mpmovecfix(&b, c);
	mpaddfixfix(a, &b, 0);
}
Exemplo n.º 8
0
void
mpcomfix(Mpint *a)
{
	Mpint b;

	mpmovecfix(&b, 1);
	mpnegfix(a);
	mpsubfixfix(a, &b);
}
Exemplo n.º 9
0
void
mplshfixfix(Mpint *a, Mpint *b)
{
	vlong s;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mporfixfix");
		mpmovecfix(a, 0);
		a->ovf = 1;
		return;
	}
	s = mpgetfix(b);
	if(s < 0 || s >= Mpprec*Mpscale) {
		yyerror("stupid shift: %lld", s);
		mpmovecfix(a, 0);
		return;
	}

	mpshiftfix(a, s);
}
Exemplo n.º 10
0
void
mpdivmodfixfix(Mpint *q, Mpint *r, Mpint *n, Mpint *d)
{
	int i, ns, ds;

	ns = n->neg;
	ds = d->neg;
	n->neg = 0;
	d->neg = 0;

	mpmovefixfix(r, n);
	mpmovecfix(q, 0);

	// shift denominator until it
	// is larger than numerator
	for(i=0; i<Mpprec*Mpscale; i++) {
		if(mpcmp(d, r) > 0)
			break;
		mplsh(d);
	}

	// if it never happens
	// denominator is probably zero
	if(i >= Mpprec*Mpscale) {
		q->ovf = 1;
		r->ovf = 1;
		n->neg = ns;
		d->neg = ds;
		yyerror("set ovf in mpdivmodfixfix");
		return;
	}

	// shift denominator back creating
	// quotient a bit at a time
	// when done the remaining numerator
	// will be the remainder
	for(; i>0; i--) {
		mplsh(q);
		mprsh(d);
		if(mpcmp(d, r) <= 0) {
			mpaddcfix(q, 1);
			mpsubfixfix(r, d);
		}
	}

	n->neg = ns;
	d->neg = ds;
	r->neg = ns;
	q->neg = ns^ds;
}
Exemplo n.º 11
0
int
mptestfix(Mpint *a)
{
	Mpint b;
	int r;

	mpmovecfix(&b, 0);
	r = mpcmp(a, &b);
	if(a->neg) {
		if(r > 0)
			return -1;
		if(r < 0)
			return +1;
	}
	return r;
}
Exemplo n.º 12
0
void
mpmulfixfix(Mpint *a, Mpint *b)
{

	int i, j, na, nb;
	long *a1, x;
	Mpint s, q;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mpmulfixfix");
		a->ovf = 1;
		return;
	}

	// pick the smaller
	// to test for bits
	na = mplen(a);
	nb = mplen(b);
	if(na > nb) {
		mpmovefixfix(&s, a);
		a1 = &b->a[0];
		na = nb;
	} else {
		mpmovefixfix(&s, b);
		a1 = &a->a[0];
	}
	s.neg = 0;

	mpmovecfix(&q, 0);
	for(i=0; i<na; i++) {
		x = *a1++;
		for(j=0; j<Mpscale; j++) {
			if(x & 1)
				mpaddfixfix(&q, &s);
			mplsh(&s);
			x >>= 1;
		}
	}

	q.neg = a->neg ^ b->neg;
	mpmovefixfix(a, &q);
	if(a->ovf)
		yyerror("set ovf in mpmulfixfix");
}
Exemplo n.º 13
0
void
mpmulfract(Mpint *a, Mpint *b)
{

	int i, j;
	long *a1, x;
	Mpint s, q;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mpmulflt");
		a->ovf = 1;
		return;
	}

	mpmovefixfix(&s, b);
	a1 = &a->a[Mpprec];
	s.neg = 0;
	mpmovecfix(&q, 0);

	for(i=0; i<Mpprec; i++) {
		x = *--a1;
		if(x == 0) {
			mprshw(&s);
			continue;
		}
		for(j=0; j<Mpscale; j++) {
			x <<= 1;
			if(x & Mpbase)
				mpaddfixfix(&q, &s);
			mprsh(&s);
		}
	}

	q.neg = a->neg ^ b->neg;
	mpmovefixfix(a, &q);
	if(a->ovf)
		yyerror("set ovf in mpmulflt");
}
Exemplo n.º 14
0
//
// fixed point input
// required syntax is [+-][0[x]]d*
//
void
mpatofix(Mpint *a, char *as)
{
	int c, f;
	char *s, *s0;

	s = as;
	f = 0;
	mpmovecfix(a, 0);

	c = *s++;
	switch(c) {
	case '-':
		f = 1;

	case '+':
		c = *s++;
		if(c != '0')
			break;

	case '0':
		goto oct;
	}

	while(c) {
		if(c >= '0' && c <= '9') {
			mpmulcfix(a, 10);
			mpaddcfix(a, c-'0');
			c = *s++;
			continue;
		}
		goto bad;
	}
	goto out;

oct:
	c = *s++;
	if(c == 'x' || c == 'X')
		goto hex;
	while(c) {
		if(c >= '0' && c <= '7') {
			mpmulcfix(a, 8);
			mpaddcfix(a, c-'0');
			c = *s++;
			continue;
		}
		goto bad;
	}
	goto out;

hex:
	s0 = s;
	c = *s;
	while(c) {
		if((c >= '0' && c <= '9') || (c >= 'a' && c <= 'f') || (c >= 'A' && c <= 'F')) {
			s++;
			c = *s;
			continue;
		}
		goto bad;
	}
	mphextofix(a, s0, s-s0);
	if(a->ovf)
		goto bad;

out:
	if(f)
		mpnegfix(a);
	return;

bad:
	yyerror("constant too large: %s", as);
	mpmovecfix(a, 0);
}
Exemplo n.º 15
0
Arquivo: unsafe.c Projeto: 8l/go-learn
/*
 * look for
 *	unsafe.Sizeof
 *	unsafe.Offsetof
 * rewrite with a constant
 */
Node*
unsafenmagic(Node *fn, NodeList *args)
{
	Node *r, *n;
	Sym *s;
	Type *t, *tr;
	long v;
	Val val;

	if(fn == N || fn->op != ONAME || (s = fn->sym) == S)
		goto no;
	if(strcmp(s->package, "unsafe") != 0)
		goto no;

	if(args == nil) {
		yyerror("missing argument for %S", s);
		goto no;
	}
	r = args->n;

	n = nod(OLITERAL, N, N);
	if(strcmp(s->name, "Sizeof") == 0) {
		typecheck(&r, Erv);
		tr = r->type;
		if(r->op == OLITERAL && r->val.ctype == CTSTR)
			tr = types[TSTRING];
		if(tr == T)
			goto no;
		v = tr->width;
		goto yes;
	}
	if(strcmp(s->name, "Offsetof") == 0) {
		if(r->op != ODOT && r->op != ODOTPTR)
			goto no;
		typecheck(&r, Erv);
		v = r->xoffset;
		goto yes;
	}
	if(strcmp(s->name, "Alignof") == 0) {
		typecheck(&r, Erv);
		tr = r->type;
		if(r->op == OLITERAL && r->val.ctype == CTSTR)
			tr = types[TSTRING];
		if(tr == T)
			goto no;

		// make struct { byte; T; }
		t = typ(TSTRUCT);
		t->type = typ(TFIELD);
		t->type->type = types[TUINT8];
		t->type->down = typ(TFIELD);
		t->type->down->type = tr;
		// compute struct widths
		dowidth(t);

		// the offset of T is its required alignment
		v = t->type->down->width;
		goto yes;
	}

no:
	return N;

yes:
	if(args->next != nil)
		yyerror("extra arguments for %S", s);
	// any side effects disappear; ignore init
	val.ctype = CTINT;
	val.u.xval = mal(sizeof(*n->val.u.xval));
	mpmovecfix(val.u.xval, v);
	n = nod(OLITERAL, N, N);
	n->val = val;
	n->type = types[TINT];
	return n;
}
Exemplo n.º 16
0
void
mpaddfixfix(Mpint *a, Mpint *b)
{
	int i, c;
	long x, *a1, *b1;

	if(a->ovf || b->ovf) {
		yyerror("ovf in mpaddxx");
		a->ovf = 1;
		return;
	}

	c = 0;
	a1 = &a->a[0];
	b1 = &b->a[0];
	if(a->neg != b->neg)
		goto sub;

	// perform a+b
	for(i=0; i<Mpprec; i++) {
		x = *a1 + *b1++ + c;
		c = 0;
		if(x >= Mpbase) {
			x -= Mpbase;
			c = 1;
		}
		*a1++ = x;
	}
	a->ovf = c;
	if(a->ovf)
		yyerror("set ovf in mpaddxx");

	return;

sub:
	// perform a-b
	switch(mpcmp(a, b)) {
	case 0:
		mpmovecfix(a, 0);
		break;

	case 1:
		for(i=0; i<Mpprec; i++) {
			x = *a1 - *b1++ - c;
			c = 0;
			if(x < 0) {
				x += Mpbase;
				c = 1;
			}
			*a1++ = x;
		}
		break;

	case -1:
		a->neg ^= 1;
		for(i=0; i<Mpprec; i++) {
			x = *b1++ - *a1 - c;
			c = 0;
			if(x < 0) {
				x += Mpbase;
				c = 1;
			}
			*a1++ = x;
		}
		break;
	}
}
Exemplo n.º 17
0
//
// fixed point input
// required syntax is [+-][0[x]]d*
//
void
mpatofix(Mpint *a, char *as)
{
	int c, f;
	char *s;

	s = as;
	f = 0;
	mpmovecfix(a, 0);

	c = *s++;
	switch(c) {
	case '-':
		f = 1;

	case '+':
		c = *s++;
		if(c != '0')
			break;

	case '0':
		goto oct;
	}

	while(c) {
		if(c >= '0' && c <= '9') {
			mpmulcfix(a, 10);
			mpaddcfix(a, c-'0');
			c = *s++;
			continue;
		}
		goto bad;
	}
	goto out;

oct:
	c = *s++;
	if(c == 'x' || c == 'X')
		goto hex;
	while(c) {
		if(c >= '0' && c <= '7') {
			mpmulcfix(a, 8);
			mpaddcfix(a, c-'0');
			c = *s++;
			continue;
		}
		goto bad;
	}
	goto out;

hex:
	c = *s++;
	while(c) {
		if(c >= '0' && c <= '9') {
			mpmulcfix(a, 16);
			mpaddcfix(a, c-'0');
			c = *s++;
			continue;
		}
		if(c >= 'a' && c <= 'f') {
			mpmulcfix(a, 16);
			mpaddcfix(a, c+10-'a');
			c = *s++;
			continue;
		}
		if(c >= 'A' && c <= 'F') {
			mpmulcfix(a, 16);
			mpaddcfix(a, c+10-'A');
			c = *s++;
			continue;
		}
		goto bad;
	}

out:
	if(f)
		mpnegfix(a);
	return;

bad:
	yyerror("set ovf in mpatov: %s", as);
	mpmovecfix(a, 0);
}
Exemplo n.º 18
0
/*
 * look for
 *	unsafe.Sizeof
 *	unsafe.Offsetof
 * rewrite with a constant
 */
Node*
unsafenmagic(Node *nn)
{
	Node *r, *n;
	Sym *s;
	Type *t, *tr;
	long v;
	Val val;
	Node *fn;
	NodeList *args;
	
	fn = nn->left;
	args = nn->list;

	if(safemode || fn == N || fn->op != ONAME || (s = fn->sym) == S)
		goto no;
	if(s->pkg != unsafepkg)
		goto no;

	if(args == nil) {
		yyerror("missing argument for %S", s);
		goto no;
	}
	r = args->n;

	if(strcmp(s->name, "Sizeof") == 0) {
		typecheck(&r, Erv);
		defaultlit(&r, T);
		tr = r->type;
		if(tr == T)
			goto bad;
		dowidth(tr);
		v = tr->width;
		goto yes;
	}
	if(strcmp(s->name, "Offsetof") == 0) {
		typecheck(&r, Erv);
		if(r->op != ODOT && r->op != ODOTPTR)
			goto bad;
		typecheck(&r, Erv);
		v = r->xoffset;
		goto yes;
	}
	if(strcmp(s->name, "Alignof") == 0) {
		typecheck(&r, Erv);
		defaultlit(&r, T);
		tr = r->type;
		if(tr == T)
			goto bad;

		// make struct { byte; T; }
		t = typ(TSTRUCT);
		t->type = typ(TFIELD);
		t->type->type = types[TUINT8];
		t->type->down = typ(TFIELD);
		t->type->down->type = tr;
		// compute struct widths
		dowidth(t);

		// the offset of T is its required alignment
		v = t->type->down->width;
		goto yes;
	}

no:
	return N;

bad:
	yyerror("invalid expression %#N", nn);
	v = 0;
	goto ret;
	
yes:
	if(args->next != nil)
		yyerror("extra arguments for %S", s);
ret:
	// any side effects disappear; ignore init
	val.ctype = CTINT;
	val.u.xval = mal(sizeof(*n->val.u.xval));
	mpmovecfix(val.u.xval, v);
	n = nod(OLITERAL, N, N);
	n->val = val;
	n->type = types[TINT];
	return n;
}