const.c 18.1 KB
Newer Older
1 2 3 4 5 6 7
// Copyright 2009 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.

#include	"go.h"
#define	TUP(x,y)	(((x)<<16)|(y))

8 9 10 11 12 13 14 15
static Val toflt(Val);
static Val toint(Val);
static Val tostr(Val);
static void overflow(Val, Type*);
static Val copyval(Val);

/*
 * truncate float literal fv to 32-bit or 64-bit precision
16
 * according to type; return truncated value.
17
 */
18 19
Mpflt*
truncfltlit(Mpflt *oldv, Type *t)
20 21 22
{
	double d;
	float f;
23
	Mpflt *fv;
24 25

	if(t == T)
26 27 28 29
		return oldv;

	fv = mal(sizeof *fv);
	*fv = *oldv;
30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47

	// convert large precision literal floating
	// into limited precision (float64 or float32)
	// botch -- this assumes that compiler fp
	//    has same precision as runtime fp
	switch(t->etype) {
	case TFLOAT64:
		d = mpgetflt(fv);
		mpmovecflt(fv, d);
		break;

	case TFLOAT32:
		d = mpgetflt(fv);
		f = d;
		d = f;
		mpmovecflt(fv, d);
		break;
	}
48
	return fv;
49 50
}

51 52 53 54
/*
 * convert n, if literal, to type t.
 * implicit conversion.
 */
55
void
56
convlit(Node **np, Type *t)
57
{
Russ Cox's avatar
Russ Cox committed
58
	convlit1(np, t, 0);
59 60 61 62
}

/*
 * convert n, if literal, to type t.
63 64
 * return a new node if necessary
 * (if n is a named constant, can't edit n->type directly).
65 66
 */
void
67
convlit1(Node **np, Type *t, int explicit)
68
{
69
	int ct, et;
70
	Node *n, *nn;
71

72
	n = *np;
Russ Cox's avatar
Russ Cox committed
73
	if(n == N || t == T || n->type == T || isideal(t) || n->type == t)
74
		return;
75
	if(!explicit && !isideal(n->type))
Russ Cox's avatar
Russ Cox committed
76
		return;
77 78 79 80 81 82 83 84 85

//dump("convlit1", n);
	if(n->op == OLITERAL) {
		nn = nod(OXXX, N, N);
		*nn = *n;
		n = nn;
		*np = n;
	}
//dump("convlit2", n);
Ken Thompson's avatar
Ken Thompson committed
86

Ken Thompson's avatar
Ken Thompson committed
87 88
	switch(n->op) {
	default:
Russ Cox's avatar
Russ Cox committed
89 90 91 92 93
		if(n->type->etype == TIDEAL) {
			convlit(&n->left, t);
			convlit(&n->right, t);
			n->type = t;
		}
Ken Thompson's avatar
Ken Thompson committed
94 95
		return;
	case OLITERAL:
Russ Cox's avatar
Russ Cox committed
96 97 98
		// target is invalid type for a constant?  leave alone.
		if(!okforconst[t->etype] && n->type->etype != TNIL)
			return;
Ken Thompson's avatar
Ken Thompson committed
99 100 101
		break;
	case OLSH:
	case ORSH:
102
		convlit1(&n->left, t, explicit);
Russ Cox's avatar
Russ Cox committed
103 104 105 106 107 108
		t = n->left->type;
		if(t != T && !isint[t->etype]) {
			yyerror("invalid operation: %#N (shift of type %T)", n, t);
			t = T;
		}
		n->type = t;
Ken Thompson's avatar
Ken Thompson committed
109 110
		return;
	}
Russ Cox's avatar
Russ Cox committed
111

112
	// avoided repeated calculations, errors
113
	if(cvttype(n->type, t) == 1) {
114 115 116 117 118 119 120
		n->type = t;
		return;
	}

	ct = consttype(n);
	if(ct < 0)
		goto bad;
121

122
	et = t->etype;
123
	if(et == TINTER) {
124
		if(ct == CTNIL && n->type == types[TNIL]) {
125 126 127
			n->type = t;
			return;
		}
128
		defaultlit(np, T);
129 130 131 132
		return;
	}

	switch(ct) {
Ken Thompson's avatar
Ken Thompson committed
133
	default:
134
		goto bad;
Ken Thompson's avatar
Ken Thompson committed
135

136
	case CTNIL:
Ken Thompson's avatar
Ken Thompson committed
137 138
		switch(et) {
		default:
Russ Cox's avatar
Russ Cox committed
139 140
			yyerror("cannot use nil as %T", t);
			n->type = T;
141
			goto bad;
Ken Thompson's avatar
Ken Thompson committed
142

Ken Thompson's avatar
Ken Thompson committed
143 144 145 146
		case TSTRING:
			// let normal conversion code handle it
			return;

Russ Cox's avatar
Russ Cox committed
147 148 149 150 151
		case TARRAY:
			if(!isslice(t))
				goto bad;
			break;

Ken Thompson's avatar
Ken Thompson committed
152 153 154
		case TPTR32:
		case TPTR64:
		case TINTER:
Russ Cox's avatar
Russ Cox committed
155 156
		case TMAP:
		case TCHAN:
Russ Cox's avatar
Russ Cox committed
157
		case TFUNC:
Ken Thompson's avatar
Ken Thompson committed
158
			break;
Ken Thompson's avatar
Ken Thompson committed
159 160
		}
		break;
Ken Thompson's avatar
Ken Thompson committed
161

162 163 164 165 166
	case CTSTR:
	case CTBOOL:
		if(et != n->type->etype)
			goto bad;
		break;
167

168 169 170
	case CTINT:
	case CTFLT:
		ct = n->val.ctype;
171
		if(isint[et]) {
172 173 174 175 176 177 178 179 180 181 182
			if(ct == CTFLT)
				n->val = toint(n->val);
			else if(ct != CTINT)
				goto bad;
			overflow(n->val, t);
		} else if(isfloat[et]) {
			if(ct == CTINT)
				n->val = toflt(n->val);
			else if(ct != CTFLT)
				goto bad;
			overflow(n->val, t);
183
			n->val.u.fval = truncfltlit(n->val.u.fval, t);
184 185 186 187
		} else if(et == TSTRING && ct == CTINT && explicit)
			n->val = tostr(n->val);
		else
			goto bad;
188
	}
189
	n->type = t;
190 191
	return;

192
bad:
Russ Cox's avatar
Russ Cox committed
193 194 195 196
	if(!n->diag) {
		yyerror("cannot convert %#N to type %T", n, t);
		n->diag = 1;
	}
197
	if(isideal(n->type)) {
198 199 200
		defaultlit(&n, T);
		*np = n;
	}
201
	return;
202
}
203

204 205 206 207 208
static Val
copyval(Val v)
{
	Mpint *i;
	Mpflt *f;
209

210 211 212 213 214 215 216 217 218 219 220 221 222
	switch(v.ctype) {
	case CTINT:
		i = mal(sizeof(*i));
		mpmovefixfix(i, v.u.xval);
		v.u.xval = i;
		break;
	case CTFLT:
		f = mal(sizeof(*f));
		mpmovefltflt(f, v.u.fval);
		v.u.fval = f;
		break;
	}
	return v;
223 224
}

225 226
static Val
toflt(Val v)
Ken Thompson's avatar
Ken Thompson committed
227
{
228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
	Mpflt *f;

	if(v.ctype == CTINT) {
		f = mal(sizeof(*f));
		mpmovefixflt(f, v.u.xval);
		v.ctype = CTFLT;
		v.u.fval = f;
	}
	return v;
}

static Val
toint(Val v)
{
	Mpint *i;

	if(v.ctype == CTFLT) {
		i = mal(sizeof(*i));
		if(mpmovefltfix(i, v.u.fval) < 0)
			yyerror("constant %#F truncated to integer", v.u.fval);
		v.ctype = CTINT;
		v.u.xval = i;
	}
	return v;
}

static void
overflow(Val v, Type *t)
{
	// v has already been converted
	// to appropriate form for t.
	if(t == T || t->etype == TIDEAL)
		return;
	switch(v.ctype) {
	case CTINT:
Russ Cox's avatar
Russ Cox committed
263 264
		if(!isint[t->etype])
			fatal("overflow: %T integer constant", t);
265 266 267 268 269
		if(mpcmpfixfix(v.u.xval, minintval[t->etype]) < 0
		|| mpcmpfixfix(v.u.xval, maxintval[t->etype]) > 0)
			yyerror("constant %B overflows %T", v.u.xval, t);
		break;
	case CTFLT:
Russ Cox's avatar
Russ Cox committed
270 271
		if(!isfloat[t->etype])
			fatal("overflow: %T floating-point constant", t);
272 273
		if(mpcmpfltflt(v.u.fval, minfltval[t->etype]) <= 0
		|| mpcmpfltflt(v.u.fval, maxfltval[t->etype]) >= 0)
274 275 276 277 278 279 280 281 282 283
			yyerror("constant %#F overflows %T", v.u.fval, t);
		break;
	}
}

static Val
tostr(Val v)
{
	Rune rune;
	int l;
284
	Strlit *s;
285 286 287 288 289 290 291 292 293 294 295

	switch(v.ctype) {
	case CTINT:
		if(mpcmpfixfix(v.u.xval, minintval[TINT]) < 0
		|| mpcmpfixfix(v.u.xval, maxintval[TINT]) > 0)
			yyerror("overflow in int -> string");
		rune = mpgetfix(v.u.xval);
		l = runelen(rune);
		s = mal(sizeof(*s)+l);
		s->len = l;
		runetochar((char*)s->s, &rune);
Russ Cox's avatar
Russ Cox committed
296
		memset(&v, 0, sizeof v);
297 298 299 300 301 302
		v.ctype = CTSTR;
		v.u.sval = s;
		break;

	case CTFLT:
		yyerror("no float -> string");
303

Russ Cox's avatar
Russ Cox committed
304 305 306 307 308
	case CTNIL:
		memset(&v, 0, sizeof v);
		v.ctype = CTSTR;
		v.u.sval = mal(sizeof *s);
		break;
309 310
	}
	return v;
Ken Thompson's avatar
Ken Thompson committed
311 312
}

313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329
int
consttype(Node *n)
{
	if(n == N || n->op != OLITERAL)
		return -1;
	return n->val.ctype;
}

int
isconst(Node *n, int ct)
{
	return consttype(n) == ct;
}

/*
 * if n is constant, rewrite as OLITERAL node.
 */
330 331 332 333
void
evconst(Node *n)
{
	Node *nl, *nr;
334
	int32 len;
335
	Strlit *str;
336
	int wl, wr, lno, et;
Russ Cox's avatar
Russ Cox committed
337
	Val v, rv;
338
	Mpint b;
339

340 341
	// pick off just the opcodes that can be
	// constant evaluated.
Russ Cox's avatar
Russ Cox committed
342
	switch(n->op) {
343
	default:
Russ Cox's avatar
Russ Cox committed
344
		return;
345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370
	case OADD:
	case OADDSTR:
	case OAND:
	case OANDAND:
	case OANDNOT:
	case OARRAYBYTESTR:
	case OCOM:
	case ODIV:
	case OEQ:
	case OGE:
	case OGT:
	case OLE:
	case OLSH:
	case OLT:
	case OMINUS:
	case OMOD:
	case OMUL:
	case ONE:
	case ONOT:
	case OOR:
	case OOROR:
	case OPLUS:
	case ORSH:
	case OSUB:
	case OXOR:
		break;
Russ Cox's avatar
Russ Cox committed
371 372 373 374 375 376
	case OCONV:
		if(n->type == T)
			return;
		if(!okforconst[n->type->etype] && n->type->etype != TNIL)
			return;
		break;
Russ Cox's avatar
Russ Cox committed
377 378
	}

379
	nl = n->left;
380
	if(nl == N || nl->type == T)
381
		return;
382
	if(consttype(nl) < 0)
383
		return;
384 385 386
	wl = nl->type->etype;
	if(isint[wl] || isfloat[wl])
		wl = TIDEAL;
387 388 389 390

	nr = n->right;
	if(nr == N)
		goto unary;
391
	if(nr->type == T)
392
		return;
393 394 395 396 397 398 399 400 401
	if(consttype(nr) < 0)
		return;
	wr = nr->type->etype;
	if(isint[wr] || isfloat[wr])
		wr = TIDEAL;

	// check for compatible general types (numeric, string, etc)
	if(wl != wr)
		goto illegal;
402

403 404 405 406
	// check for compatible types.
	switch(n->op) {
	default:
		// ideal const mixes with anything but otherwise must match.
407 408 409 410 411 412 413 414
		if(nl->type->etype != TIDEAL) {
			defaultlit(&nr, nl->type);
			n->right = nr;
		}
		if(nr->type->etype != TIDEAL) {
			defaultlit(&nl, nr->type);
			n->left = nl;
		}
415 416
		if(nl->type->etype != nr->type->etype)
			goto illegal;
417
		break;
418

419 420 421 422
	case OLSH:
	case ORSH:
		// right must be unsigned.
		// left can be ideal.
423 424
		defaultlit(&nr, types[TUINT]);
		n->right = nr;
Russ Cox's avatar
Russ Cox committed
425 426
		if(nr->type && (issigned[nr->type->etype] || !isint[nr->type->etype]))
			goto illegal;
427
		break;
428 429
	}

430 431 432 433 434 435
	// copy numeric value to avoid modifying
	// n->left, in case someone still refers to it (e.g. iota).
	v = nl->val;
	if(wl == TIDEAL)
		v = copyval(v);

Russ Cox's avatar
Russ Cox committed
436 437
	rv = nr->val;

438 439 440 441 442 443
	// since wl == wr,
	// the only way v.ctype != nr->val.ctype
	// is when one is CTINT and the other CTFLT.
	// make both CTFLT.
	if(v.ctype != nr->val.ctype) {
		v = toflt(v);
Russ Cox's avatar
Russ Cox committed
444
		rv = toflt(rv);
Ken Thompson's avatar
Ken Thompson committed
445 446
	}

447 448
	// run op
	switch(TUP(n->op, v.ctype)) {
449
	default:
450
	illegal:
Russ Cox's avatar
Russ Cox committed
451 452 453 454 455
		if(!n->diag) {
			yyerror("illegal constant expression: %T %O %T",
				nl->type, n->op, nr->type);
			n->diag = 1;
		}
456 457
		return;

458
	case TUP(OADD, CTINT):
Russ Cox's avatar
Russ Cox committed
459
		mpaddfixfix(v.u.xval, rv.u.xval);
460
		break;
461
	case TUP(OSUB, CTINT):
Russ Cox's avatar
Russ Cox committed
462
		mpsubfixfix(v.u.xval, rv.u.xval);
463
		break;
464
	case TUP(OMUL, CTINT):
Russ Cox's avatar
Russ Cox committed
465
		mpmulfixfix(v.u.xval, rv.u.xval);
466
		break;
467
	case TUP(ODIV, CTINT):
Russ Cox's avatar
Russ Cox committed
468
		if(mpcmpfixc(rv.u.xval, 0) == 0) {
469 470 471 472
			yyerror("division by zero");
			mpmovecfix(v.u.xval, 1);
			break;
		}
Russ Cox's avatar
Russ Cox committed
473
		mpdivfixfix(v.u.xval, rv.u.xval);
474
		break;
475
	case TUP(OMOD, CTINT):
Russ Cox's avatar
Russ Cox committed
476
		if(mpcmpfixc(rv.u.xval, 0) == 0) {
477 478 479 480
			yyerror("division by zero");
			mpmovecfix(v.u.xval, 1);
			break;
		}
Russ Cox's avatar
Russ Cox committed
481
		mpmodfixfix(v.u.xval, rv.u.xval);
482
		break;
Ken Thompson's avatar
Ken Thompson committed
483

484
	case TUP(OLSH, CTINT):
Russ Cox's avatar
Russ Cox committed
485
		mplshfixfix(v.u.xval, rv.u.xval);
486
		break;
487
	case TUP(ORSH, CTINT):
Russ Cox's avatar
Russ Cox committed
488
		mprshfixfix(v.u.xval, rv.u.xval);
489
		break;
490
	case TUP(OOR, CTINT):
Russ Cox's avatar
Russ Cox committed
491
		mporfixfix(v.u.xval, rv.u.xval);
492
		break;
493
	case TUP(OAND, CTINT):
Russ Cox's avatar
Russ Cox committed
494
		mpandfixfix(v.u.xval, rv.u.xval);
495
		break;
496
	case TUP(OANDNOT, CTINT):
Russ Cox's avatar
Russ Cox committed
497
		mpandnotfixfix(v.u.xval, rv.u.xval);
498
		break;
499
	case TUP(OXOR, CTINT):
Russ Cox's avatar
Russ Cox committed
500
		mpxorfixfix(v.u.xval, rv.u.xval);
Ken Thompson's avatar
Ken Thompson committed
501
		break;
502
	case TUP(OADD, CTFLT):
Russ Cox's avatar
Russ Cox committed
503
		mpaddfltflt(v.u.fval, rv.u.fval);
504
		break;
505
	case TUP(OSUB, CTFLT):
Russ Cox's avatar
Russ Cox committed
506
		mpsubfltflt(v.u.fval, rv.u.fval);
507
		break;
508
	case TUP(OMUL, CTFLT):
Russ Cox's avatar
Russ Cox committed
509
		mpmulfltflt(v.u.fval, rv.u.fval);
510
		break;
511
	case TUP(ODIV, CTFLT):
Russ Cox's avatar
Russ Cox committed
512
		if(mpcmpfltc(rv.u.fval, 0) == 0) {
513 514 515 516
			yyerror("division by zero");
			mpmovecflt(v.u.fval, 1.0);
			break;
		}
Russ Cox's avatar
Russ Cox committed
517
		mpdivfltflt(v.u.fval, rv.u.fval);
518 519
		break;

520
	case TUP(OEQ, CTNIL):
Ken Thompson's avatar
Ken Thompson committed
521
		goto settrue;
522
	case TUP(ONE, CTNIL):
Ken Thompson's avatar
Ken Thompson committed
523 524
		goto setfalse;

525
	case TUP(OEQ, CTINT):
Russ Cox's avatar
Russ Cox committed
526
		if(mpcmpfixfix(v.u.xval, rv.u.xval) == 0)
527 528
			goto settrue;
		goto setfalse;
529
	case TUP(ONE, CTINT):
Russ Cox's avatar
Russ Cox committed
530
		if(mpcmpfixfix(v.u.xval, rv.u.xval) != 0)
531 532
			goto settrue;
		goto setfalse;
533
	case TUP(OLT, CTINT):
Russ Cox's avatar
Russ Cox committed
534
		if(mpcmpfixfix(v.u.xval, rv.u.xval) < 0)
535 536
			goto settrue;
		goto setfalse;
537
	case TUP(OLE, CTINT):
Russ Cox's avatar
Russ Cox committed
538
		if(mpcmpfixfix(v.u.xval, rv.u.xval) <= 0)
539 540
			goto settrue;
		goto setfalse;
541
	case TUP(OGE, CTINT):
Russ Cox's avatar
Russ Cox committed
542
		if(mpcmpfixfix(v.u.xval, rv.u.xval) >= 0)
543 544
			goto settrue;
		goto setfalse;
545
	case TUP(OGT, CTINT):
Russ Cox's avatar
Russ Cox committed
546
		if(mpcmpfixfix(v.u.xval, rv.u.xval) > 0)
547 548 549
			goto settrue;
		goto setfalse;

550
	case TUP(OEQ, CTFLT):
Russ Cox's avatar
Russ Cox committed
551
		if(mpcmpfltflt(v.u.fval, rv.u.fval) == 0)
552 553
			goto settrue;
		goto setfalse;
554
	case TUP(ONE, CTFLT):
Russ Cox's avatar
Russ Cox committed
555
		if(mpcmpfltflt(v.u.fval, rv.u.fval) != 0)
556 557
			goto settrue;
		goto setfalse;
558
	case TUP(OLT, CTFLT):
Russ Cox's avatar
Russ Cox committed
559
		if(mpcmpfltflt(v.u.fval, rv.u.fval) < 0)
560 561
			goto settrue;
		goto setfalse;
562
	case TUP(OLE, CTFLT):
Russ Cox's avatar
Russ Cox committed
563
		if(mpcmpfltflt(v.u.fval, rv.u.fval) <= 0)
564 565
			goto settrue;
		goto setfalse;
566
	case TUP(OGE, CTFLT):
Russ Cox's avatar
Russ Cox committed
567
		if(mpcmpfltflt(v.u.fval, rv.u.fval) >= 0)
568 569
			goto settrue;
		goto setfalse;
570
	case TUP(OGT, CTFLT):
Russ Cox's avatar
Russ Cox committed
571
		if(mpcmpfltflt(v.u.fval, rv.u.fval) > 0)
572 573 574
			goto settrue;
		goto setfalse;

575
	case TUP(OEQ, CTSTR):
576 577 578
		if(cmpslit(nl, nr) == 0)
			goto settrue;
		goto setfalse;
579
	case TUP(ONE, CTSTR):
580 581 582
		if(cmpslit(nl, nr) != 0)
			goto settrue;
		goto setfalse;
583
	case TUP(OLT, CTSTR):
584 585 586
		if(cmpslit(nl, nr) < 0)
			goto settrue;
		goto setfalse;
587
	case TUP(OLE, CTSTR):
588 589 590
		if(cmpslit(nl, nr) <= 0)
			goto settrue;
		goto setfalse;
591
	case TUP(OGE, CTSTR):
592 593 594
		if(cmpslit(nl, nr) >= 0l)
			goto settrue;
		goto setfalse;
595
	case TUP(OGT, CTSTR):
596 597 598
		if(cmpslit(nl, nr) > 0)
			goto settrue;
		goto setfalse;
Russ Cox's avatar
Russ Cox committed
599
	case TUP(OADDSTR, CTSTR):
Russ Cox's avatar
Russ Cox committed
600
		len = v.u.sval->len + rv.u.sval->len;
601 602
		str = mal(sizeof(*str) + len);
		str->len = len;
603
		memcpy(str->s, v.u.sval->s, v.u.sval->len);
Russ Cox's avatar
Russ Cox committed
604
		memcpy(str->s+v.u.sval->len, rv.u.sval->s, rv.u.sval->len);
605
		str->len = len;
606
		v.u.sval = str;
607 608
		break;

609
	case TUP(OOROR, CTBOOL):
Russ Cox's avatar
Russ Cox committed
610
		if(v.u.bval || rv.u.bval)
611 612
			goto settrue;
		goto setfalse;
613
	case TUP(OANDAND, CTBOOL):
Russ Cox's avatar
Russ Cox committed
614
		if(v.u.bval && rv.u.bval)
615 616 617
			goto settrue;
		goto setfalse;
	case TUP(OEQ, CTBOOL):
Russ Cox's avatar
Russ Cox committed
618
		if(v.u.bval == rv.u.bval)
619 620 621
			goto settrue;
		goto setfalse;
	case TUP(ONE, CTBOOL):
Russ Cox's avatar
Russ Cox committed
622
		if(v.u.bval != rv.u.bval)
623 624 625
			goto settrue;
		goto setfalse;
	}
Ken Thompson's avatar
Ken Thompson committed
626
	goto ret;
627 628

unary:
629 630 631 632 633
	// copy numeric value to avoid modifying
	// nl, in case someone still refers to it (e.g. iota).
	v = nl->val;
	if(wl == TIDEAL)
		v = copyval(v);
Ken Thompson's avatar
Ken Thompson committed
634

635
	switch(TUP(n->op, v.ctype)) {
636
	default:
Russ Cox's avatar
Russ Cox committed
637 638 639 640
		if(!n->diag) {
			yyerror("illegal constant expression %O %T", n->op, nl->type);
			n->diag = 1;
		}
641 642
		return;

Russ Cox's avatar
Russ Cox committed
643 644 645 646 647 648 649 650
	case TUP(OCONV, CTNIL):
	case TUP(OARRAYBYTESTR, CTNIL):
		if(n->type->etype == TSTRING) {
			v = tostr(v);
			nl->type = n->type;
			break;
		}
		// fall through
651 652 653 654 655 656
	case TUP(OCONV, CTINT):
	case TUP(OCONV, CTFLT):
	case TUP(OCONV, CTSTR):
		convlit1(&nl, n->type, 1);
		break;

657
	case TUP(OPLUS, CTINT):
658
		break;
659 660
	case TUP(OMINUS, CTINT):
		mpnegfix(v.u.xval);
661
		break;
662
	case TUP(OCOM, CTINT):
663 664 665 666 667 668 669 670
		et = Txxx;
		if(nl->type != T)
			et = nl->type->etype;

		// calculate the mask in b
		// result will be (a ^ mask)
		switch(et) {
		default:
Ken Thompson's avatar
Ken Thompson committed
671
			// signed guys change sign
672 673 674 675 676 677 678 679 680
			mpmovecfix(&b, -1);
			break;

		case TUINT8:
		case TUINT16:
		case TUINT32:
		case TUINT64:
		case TUINT:
		case TUINTPTR:
Ken Thompson's avatar
Ken Thompson committed
681
			// unsigned guys invert their bits
682 683 684 685
			mpmovefixfix(&b, maxintval[et]);
			break;
		}
		mpxorfixfix(v.u.xval, &b);
686 687
		break;

688
	case TUP(OPLUS, CTFLT):
689
		break;
690 691
	case TUP(OMINUS, CTFLT):
		mpnegflt(v.u.fval);
692 693
		break;

694 695
	case TUP(ONOT, CTBOOL):
		if(!v.u.bval)
696 697 698
			goto settrue;
		goto setfalse;
	}
Ken Thompson's avatar
Ken Thompson committed
699 700

ret:
701
	// rewrite n in place.
702
	*n = *nl;
703 704 705
	n->val = v;

	// check range.
706
	lno = setlineno(n);
707 708 709 710 711
	overflow(v, n->type);
	lineno = lno;

	// truncate precision for non-ideal float.
	if(v.ctype == CTFLT && n->type->etype != TIDEAL)
712
		n->val.u.fval = truncfltlit(v.u.fval, n->type);
713 714 715 716 717 718 719 720 721 722
	return;

settrue:
	*n = *nodbool(1);
	return;

setfalse:
	*n = *nodbool(0);
	return;
}
Ken Thompson's avatar
Ken Thompson committed
723

724 725 726 727 728 729 730 731 732 733 734
Node*
nodlit(Val v)
{
	Node *n;

	n = nod(OLITERAL, N, N);
	n->val = v;
	switch(v.ctype) {
	default:
		fatal("nodlit ctype %d", v.ctype);
	case CTSTR:
Russ Cox's avatar
Russ Cox committed
735
		n->type = idealstring;
736 737
		break;
	case CTBOOL:
Russ Cox's avatar
Russ Cox committed
738
		n->type = idealbool;
739 740 741 742 743 744 745 746
		break;
	case CTINT:
	case CTFLT:
		n->type = types[TIDEAL];
		break;
	case CTNIL:
		n->type = types[TNIL];
		break;
Ken Thompson's avatar
Ken Thompson committed
747
	}
748
	return n;
749 750
}

751
// TODO(rsc): combine with convlit
752
void
753
defaultlit(Node **np, Type *t)
754
{
755
	int lno;
756
	Node *n, *nn;
757

758
	n = *np;
759
	if(n == N || !isideal(n->type))
760
		return;
761 762 763

	switch(n->op) {
	case OLITERAL:
764 765 766 767
		nn = nod(OXXX, N, N);
		*nn = *n;
		n = nn;
		*np = n;
768 769 770
		break;
	case OLSH:
	case ORSH:
771
		defaultlit(&n->left, t);
Russ Cox's avatar
Russ Cox committed
772 773 774 775 776 777
		t = n->left->type;
		if(t != T && !isint[t->etype]) {
			yyerror("invalid operation: %#N (shift of type %T)", n, t);
			t = T;
		}
		n->type = t;
778
		return;
Russ Cox's avatar
Russ Cox committed
779
	default:
780 781 782 783
		if(n->left == N) {
			dump("defaultlit", n);
			fatal("defaultlit");
		}
Russ Cox's avatar
Russ Cox committed
784 785
		defaultlit(&n->left, t);
		defaultlit(&n->right, t);
Russ Cox's avatar
Russ Cox committed
786 787 788 789
		if(n->type == idealbool || n->type == idealstring)
			n->type = types[n->type->etype];
		else
			n->type = n->left->type;
Russ Cox's avatar
Russ Cox committed
790
		return;
791
	}
792

793
	lno = setlineno(n);
794 795
	switch(n->val.ctype) {
	default:
796 797 798 799 800 801 802 803 804 805
		if(t != T) {
			convlit(np, t);
			break;
		}
		if(n->val.ctype == CTNIL) {
			lineno = lno;
			yyerror("use of untyped nil");
			n->type = T;
			break;
		}
806 807 808 809
		if(n->val.ctype == CTSTR) {
			n->type = types[TSTRING];
			break;
		}
810
		yyerror("defaultlit: unknown literal: %#N", n);
811
		break;
Russ Cox's avatar
Russ Cox committed
812 813 814
	case CTBOOL:
		n->type = types[TBOOL];
		break;
815
	case CTINT:
Ken Thompson's avatar
Ken Thompson committed
816
		n->type = types[TINT];
817 818 819 820 821 822 823 824 825
		if(t != T) {
			if(isint[t->etype])
				n->type = t;
			else if(isfloat[t->etype]) {
				n->type = t;
				n->val = toflt(n->val);
			}
		}
		overflow(n->val, n->type);
826 827
		break;
	case CTFLT:
Ken Thompson's avatar
Ken Thompson committed
828
		n->type = types[TFLOAT];
829 830 831 832 833 834 835 836 837
		if(t != T) {
			if(isfloat[t->etype])
				n->type = t;
			else if(isint[t->etype]) {
				n->type = t;
				n->val = toint(n->val);
			}
		}
		overflow(n->val, n->type);
838 839
		break;
	}
840 841 842 843 844 845 846 847 848
	lineno = lno;
}

/*
 * defaultlit on both nodes simultaneously;
 * if they're both ideal going in they better
 * get the same type going out.
 */
void
Russ Cox's avatar
Russ Cox committed
849
defaultlit2(Node **lp, Node **rp, int force)
850
{
851 852 853 854
	Node *l, *r;

	l = *lp;
	r = *rp;
855 856
	if(l->type == T || r->type == T)
		return;
Russ Cox's avatar
Russ Cox committed
857
	if(!isideal(l->type)) {
858
		convlit(rp, l->type);
859 860
		return;
	}
Russ Cox's avatar
Russ Cox committed
861
	if(!isideal(r->type)) {
862
		convlit(lp, r->type);
863 864
		return;
	}
Russ Cox's avatar
Russ Cox committed
865 866
	if(!force)
		return;
867
	if(isconst(l, CTFLT) || isconst(r, CTFLT)) {
868 869
		convlit(lp, types[TFLOAT]);
		convlit(rp, types[TFLOAT]);
870 871
		return;
	}
872 873
	convlit(lp, types[TINT]);
	convlit(rp, types[TINT]);
874 875 876 877 878
}

int
cmpslit(Node *l, Node *r)
{
879
	int32 l1, l2, i, m;
880 881
	char *s1, *s2;

Ken Thompson's avatar
Ken Thompson committed
882 883 884 885
	l1 = l->val.u.sval->len;
	l2 = r->val.u.sval->len;
	s1 = l->val.u.sval->s;
	s2 = r->val.u.sval->s;
886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903

	m = l1;
	if(l2 < m)
		m = l2;

	for(i=0; i<m; i++) {
		if(s1[i] == s2[i])
			continue;
		if(s1[i] > s2[i])
			return +1;
		return -1;
	}
	if(l1 == l2)
		return 0;
	if(l1 > l2)
		return +1;
	return -1;
}
Ken Thompson's avatar
Ken Thompson committed
904 905 906 907

int
smallintconst(Node *n)
{
Russ Cox's avatar
Russ Cox committed
908
	if(n->op == OLITERAL && n->type != T)
Ken Thompson's avatar
Ken Thompson committed
909 910 911 912 913 914 915 916 917 918 919 920 921
	switch(simtype[n->type->etype]) {
	case TINT8:
	case TUINT8:
	case TINT16:
	case TUINT16:
	case TINT32:
	case TUINT32:
	case TBOOL:
	case TPTR32:
		return 1;
	}
	return 0;
}
Ken Thompson's avatar
Ken Thompson committed
922 923 924 925

long
nonnegconst(Node *n)
{
Russ Cox's avatar
Russ Cox committed
926
	if(n->op == OLITERAL && n->type != T)
Ken Thompson's avatar
Ken Thompson committed
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944
	switch(simtype[n->type->etype]) {
	case TINT8:
	case TUINT8:
	case TINT16:
	case TUINT16:
	case TINT32:
	case TUINT32:
	case TINT64:
	case TUINT64:
	case TIDEAL:
		// check negative and 2^31
		if(mpcmpfixfix(n->val.u.xval, minintval[TUINT32]) < 0
		|| mpcmpfixfix(n->val.u.xval, maxintval[TINT32]) > 0)
			break;
		return mpgetfix(n->val.u.xval);
	}
	return -1;
}
Russ Cox's avatar
Russ Cox committed
945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000

/*
 * convert x to type et and back to int64
 * for sign extension and truncation.
 */
int64
iconv(int64 x, int et)
{
	switch(et) {
	case TINT8:
		x = (int8)x;
		break;
	case TUINT8:
		x = (uint8)x;
		break;
	case TINT16:
		x = (int16)x;
		break;
	case TUINT16:
		x = (uint64)x;
		break;
	case TINT32:
		x = (int32)x;
		break;
	case TUINT32:
		x = (uint32)x;
		break;
	case TINT64:
	case TUINT64:
		break;
	}
	return x;
}

/*
 * convert constant val to type t; leave in con.
 * for back end.
 */
void
convconst(Node *con, Type *t, Val *val)
{
	int64 i;
	int tt;

	tt = simsimtype(t);

	// copy the constant for conversion
	nodconst(con, types[TINT8], 0);
	con->type = t;
	con->val = *val;

	if(isint[tt]) {
		con->val.ctype = CTINT;
		con->val.u.xval = mal(sizeof *con->val.u.xval);
		switch(val->ctype) {
		default:
Russ Cox's avatar
Russ Cox committed
1001
			fatal("convconst ctype=%d %lT", val->ctype, t);
Russ Cox's avatar
Russ Cox committed
1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036
		case CTINT:
			i = mpgetfix(val->u.xval);
			break;
		case CTBOOL:
			i = val->u.bval;
			break;
		case CTNIL:
			i = 0;
			break;
		}
		i = iconv(i, tt);
		mpmovecfix(con->val.u.xval, i);
		return;
	}

	if(isfloat[tt]) {
		if(con->val.ctype == CTINT) {
			con->val.ctype = CTFLT;
			con->val.u.fval = mal(sizeof *con->val.u.fval);
			mpmovefixflt(con->val.u.fval, val->u.xval);
		}
		if(con->val.ctype != CTFLT)
			fatal("convconst ctype=%d %T", con->val.ctype, t);
		if(!isfloat[tt]) {
			// easy to handle, but can it happen?
			fatal("convconst CTINT %T", t);
		}
		if(tt == TFLOAT32)
			con->val.u.fval = truncfltlit(con->val.u.fval, t);
		return;
	}

	fatal("convconst %lT constant", t);

}