Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature_tlsv12/sys/src/cmd/cc/scon.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "cc.h"
2
 
3
static Node*
4
acast(Type *t, Node *n)
5
{
6
	if(n->type->etype != t->etype || n->op == OBIT) {
7
		n = new1(OCAST, n, Z);
8
		if(nocast(n->left->type, t))
9
			*n = *n->left;
10
		n->type = t;
11
	}
12
	return n;
13
}
14
 
15
 
16
void
17
evconst(Node *n)
18
{
19
	Node *l, *r;
20
	int et, isf;
21
	vlong v;
22
	double d;
23
 
24
	if(n == Z || n->type == T)
25
		return;
26
 
27
	et = n->type->etype;
28
	isf = typefd[et];
29
 
30
	l = n->left;
31
	r = n->right;
32
 
33
	d = 0;
34
	v = 0;
35
 
36
	switch(n->op) {
37
	default:
38
		return;
39
 
40
	case ONEG:
41
		if(isf)
42
			d = -l->fconst;
43
		else
44
			v = -l->vconst;
45
		break;
46
 
47
	case OCOM:
48
		v = ~l->vconst;
49
		break;
50
 
51
	case OCAST:
52
		if(et == TVOID)
53
			return;
54
		et = l->type->etype;
55
		if(isf) {
56
			if(typefd[et])
57
				d = l->fconst;
58
			else
59
				d = l->vconst;
60
		} else {
61
			if(typefd[et])
62
				v = l->fconst;
63
			else
64
				v = convvtox(l->vconst, n->type->etype);
65
		}
66
		break;
67
 
68
	case OCONST:
69
		break;
70
 
71
	case OADD:
72
		if(isf)
73
			d = l->fconst + r->fconst;
74
		else {
75
			v = l->vconst + r->vconst;
76
		}
77
		break;
78
 
79
	case OSUB:
80
		if(isf)
81
			d = l->fconst - r->fconst;
82
		else
83
			v = l->vconst - r->vconst;
84
		break;
85
 
86
	case OMUL:
87
		if(isf)
88
			d = l->fconst * r->fconst;
89
		else {
90
			v = l->vconst * r->vconst;
91
		}
92
		break;
93
 
94
	case OLMUL:
95
		v = (uvlong)l->vconst * (uvlong)r->vconst;
96
		break;
97
 
98
 
99
	case ODIV:
100
		if(vconst(r) == 0) {
101
			warn(n, "divide by zero");
102
			return;
103
		}
104
		if(isf)
105
			d = l->fconst / r->fconst;
106
		else
107
			v = l->vconst / r->vconst;
108
		break;
109
 
110
	case OLDIV:
111
		if(vconst(r) == 0) {
112
			warn(n, "divide by zero");
113
			return;
114
		}
115
		v = (uvlong)l->vconst / (uvlong)r->vconst;
116
		break;
117
 
118
	case OMOD:
119
		if(vconst(r) == 0) {
120
			warn(n, "modulo by zero");
121
			return;
122
		}
123
		v = l->vconst % r->vconst;
124
		break;
125
 
126
	case OLMOD:
127
		if(vconst(r) == 0) {
128
			warn(n, "modulo by zero");
129
			return;
130
		}
131
		v = (uvlong)l->vconst % (uvlong)r->vconst;
132
		break;
133
 
134
	case OAND:
135
		v = l->vconst & r->vconst;
136
		break;
137
 
138
	case OOR:
139
		v = l->vconst | r->vconst;
140
		break;
141
 
142
	case OXOR:
143
		v = l->vconst ^ r->vconst;
144
		break;
145
 
146
	case OLSHR:
147
		v = (uvlong)l->vconst >> r->vconst;
148
		break;
149
 
150
	case OASHR:
151
		v = l->vconst >> r->vconst;
152
		break;
153
 
154
	case OASHL:
155
		v = l->vconst << r->vconst;
156
		break;
157
 
158
	case OLO:
159
		v = (uvlong)l->vconst < (uvlong)r->vconst;
160
		break;
161
 
162
	case OLT:
163
		if(typefd[l->type->etype])
164
			v = l->fconst < r->fconst;
165
		else
166
			v = l->vconst < r->vconst;
167
		break;
168
 
169
	case OHI:
170
		v = (uvlong)l->vconst > (uvlong)r->vconst;
171
		break;
172
 
173
	case OGT:
174
		if(typefd[l->type->etype])
175
			v = l->fconst > r->fconst;
176
		else
177
			v = l->vconst > r->vconst;
178
		break;
179
 
180
	case OLS:
181
		v = (uvlong)l->vconst <= (uvlong)r->vconst;
182
		break;
183
 
184
	case OLE:
185
		if(typefd[l->type->etype])
186
			v = l->fconst <= r->fconst;
187
		else
188
			v = l->vconst <= r->vconst;
189
		break;
190
 
191
	case OHS:
192
		v = (uvlong)l->vconst >= (uvlong)r->vconst;
193
		break;
194
 
195
	case OGE:
196
		if(typefd[l->type->etype])
197
			v = l->fconst >= r->fconst;
198
		else
199
			v = l->vconst >= r->vconst;
200
		break;
201
 
202
	case OEQ:
203
		if(typefd[l->type->etype])
204
			v = l->fconst == r->fconst;
205
		else
206
			v = l->vconst == r->vconst;
207
		break;
208
 
209
	case ONE:
210
		if(typefd[l->type->etype])
211
			v = l->fconst != r->fconst;
212
		else
213
			v = l->vconst != r->vconst;
214
		break;
215
 
216
	case ONOT:
217
		if(typefd[l->type->etype])
218
			v = !l->fconst;
219
		else
220
			v = !l->vconst;
221
		break;
222
 
223
	case OANDAND:
224
		if(typefd[l->type->etype])
225
			v = l->fconst && r->fconst;
226
		else
227
			v = l->vconst && r->vconst;
228
		break;
229
 
230
	case OOROR:
231
		if(typefd[l->type->etype])
232
			v = l->fconst || r->fconst;
233
		else
234
			v = l->vconst || r->vconst;
235
		break;
236
	}
237
	if(isf) {
238
		n->fconst = d;
239
	} else {
240
		n->vconst = convvtox(v, n->type->etype);
241
	}
242
	n->oldop = n->op;
243
	n->op = OCONST;
244
}
245
 
246
void
247
acom(Node *n)
248
{
249
	Type *t;
250
	Node *l, *r;
251
	int i;
252
 
253
	switch(n->op)
254
	{
255
 
256
	case ONAME:
257
	case OCONST:
258
	case OSTRING:
259
	case OINDREG:
260
	case OREGISTER:
261
		return;
262
 
263
	case ONEG:
264
		l = n->left;
265
		if(addo(n) && addo(l))
266
			break;
267
		acom(l);
268
		return;
269
 
270
	case OADD:
271
	case OSUB:
272
	case OMUL:
273
		l = n->left;
274
		r = n->right;
275
		if(addo(n)) {
276
			if(addo(r))
277
				break;
278
			if(addo(l))
279
				break;
280
		}
281
		acom(l);
282
		acom(r);
283
		return;
284
 
285
	default:
286
		l = n->left;
287
		r = n->right;
288
		if(l != Z)
289
			acom(l);
290
		if(r != Z)
291
			acom(r);
292
		return;
293
	}
294
 
295
	/* bust terms out */
296
	t = n->type;
297
	term[0].mult = 0;
298
	term[0].node = Z;
299
	nterm = 1;
300
	acom1(1, n);
301
	if(debug['m'])
302
	for(i=0; i<nterm; i++) {
303
		print("%d %3lld ", i, term[i].mult);
304
		prtree1(term[i].node, 1, 0);
305
	}
306
	if(nterm < NTERM)
307
		acom2(n, t);
308
	n->type = t;
309
}
310
 
311
int
312
acomcmp1(const void *a1, const void *a2)
313
{
314
	vlong c1, c2;
315
	Term *t1, *t2;
316
 
317
	t1 = (Term*)a1;
318
	t2 = (Term*)a2;
319
	c1 = t1->mult;
320
	if(c1 < 0)
321
		c1 = -c1;
322
	c2 = t2->mult;
323
	if(c2 < 0)
324
		c2 = -c2;
325
	if(c1 > c2)
326
		return 1;
327
	if(c1 < c2)
328
		return -1;
329
	c1 = 1;
330
	if(t1->mult < 0)
331
		c1 = 0;
332
	c2 = 1;
333
	if(t2->mult < 0)
334
		c2 = 0;
335
	if(c2 -= c1)
336
		return c2;
337
	if(t2 > t1)
338
		return 1;
339
	return -1;
340
}
341
 
342
int
343
acomcmp2(const void *a1, const void *a2)
344
{
345
	vlong c1, c2;
346
	Term *t1, *t2;
347
 
348
	t1 = (Term*)a1;
349
	t2 = (Term*)a2;
350
	c1 = t1->mult;
351
	c2 = t2->mult;
352
	if(c1 > c2)
353
		return 1;
354
	if(c1 < c2)
355
		return -1;
356
	if(t2 > t1)
357
		return 1;
358
	return -1;
359
}
360
 
361
void
362
acom2(Node *n, Type *t)
363
{
364
	Node *l, *r;
365
	Term trm[NTERM];
366
	int et, nt, i, j;
367
	vlong c1, c2;
368
 
369
	/*
370
	 * copy into automatic
371
	 */
372
	c2 = 0;
373
	nt = nterm;
374
	for(i=0; i<nt; i++)
375
		trm[i] = term[i];
376
	/*
377
	 * recur on subtrees
378
	 */
379
	j = 0;
380
	for(i=1; i<nt; i++) {
381
		c1 = trm[i].mult;
382
		if(c1 == 0)
383
			continue;
384
		l = trm[i].node;
385
		if(l != Z) {
386
			j = 1;
387
			acom(l);
388
		}
389
	}
390
	c1 = trm[0].mult;
391
	if(j == 0) {
392
		n->oldop = n->op;
393
		n->op = OCONST;
394
		n->vconst = c1;
395
		return;
396
	}
397
	et = t->etype;
398
 
399
	/*
400
	 * prepare constant term,
401
	 * combine it with an addressing term
402
	 */
403
	if(c1 != 0) {
404
		l = new1(OCONST, Z, Z);
405
		l->type = t;
406
		l->vconst = c1;
407
		trm[0].mult = 1;
408
		for(i=1; i<nt; i++) {
409
			if(trm[i].mult != 1)
410
				continue;
411
			r = trm[i].node;
412
			if(r->op != OADDR)
413
				continue;
414
			r->type = t;
415
			l = new1(OADD, r, l);
416
			l->type = t;
417
			trm[i].mult = 0;
418
			break;
419
		}
420
		trm[0].node = l;
421
	}
422
	/*
423
	 * look for factorable terms
424
	 * c1*i + c1*c2*j -> c1*(i + c2*j)
425
	 */
426
	qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp1);
427
	for(i=nt-1; i>=0; i--) {
428
		c1 = trm[i].mult;
429
		if(c1 < 0)
430
			c1 = -c1;
431
		if(c1 <= 1)
432
			continue;
433
		for(j=i+1; j<nt; j++) {
434
			c2 = trm[j].mult;
435
			if(c2 < 0)
436
				c2 = -c2;
437
			if(c2 <= 1)
438
				continue;
439
			if(c2 % c1)
440
				continue;
441
			r = trm[j].node;
442
			if(r->type->etype != et)
443
				r = acast(t, r);
444
			c2 = trm[j].mult/trm[i].mult;
445
			if(c2 != 1 && c2 != -1) {
446
				r = new1(OMUL, r, new(OCONST, Z, Z));
447
				r->type = t;
448
				r->right->type = t;
449
				r->right->vconst = c2;
450
			}
451
			l = trm[i].node;
452
			if(l->type->etype != et)
453
				l = acast(t, l);
454
			r = new1(OADD, l, r);
455
			r->type = t;
456
			if(c2 == -1)
457
				r->op = OSUB;
458
			trm[i].node = r;
459
			trm[j].mult = 0;
460
		}
461
	}
462
	if(debug['m']) {
463
		print("\n");
464
		for(i=0; i<nt; i++) {
465
			print("%d %3lld ", i, trm[i].mult);
466
			prtree1(trm[i].node, 1, 0);
467
		}
468
	}
469
 
470
	/*
471
	 * put it all back together
472
	 */
473
	qsort(trm+1, nt-1, sizeof(trm[0]), acomcmp2);
474
	l = Z;
475
	for(i=nt-1; i>=0; i--) {
476
		c1 = trm[i].mult;
477
		if(c1 == 0)
478
			continue;
479
		r = trm[i].node;
480
		if(r->type->etype != et || r->op == OBIT)
481
			r = acast(t, r);
482
		if(c1 != 1 && c1 != -1) {
483
			r = new1(OMUL, r, new(OCONST, Z, Z));
484
			r->type = t;
485
			r->right->type = t;
486
			if(c1 < 0) {
487
				r->right->vconst = -c1;
488
				c1 = -1;
489
			} else {
490
				r->right->vconst = c1;
491
				c1 = 1;
492
			}
493
		}
494
		if(l == Z) {
495
			l = r;
496
			c2 = c1;
497
			continue;
498
		}
499
		if(c1 < 0)
500
			if(c2 < 0)
501
				l = new1(OADD, l, r);
502
			else
503
				l = new1(OSUB, l, r);
504
		else
505
			if(c2 < 0) {
506
				l = new1(OSUB, r, l);
507
				c2 = 1;
508
			} else
509
				l = new1(OADD, l, r);
510
		l->type = t;
511
	}
512
	if(c2 < 0) {
513
		r = new1(OCONST, 0, 0);
514
		r->vconst = 0;
515
		r->type = t;
516
		l = new1(OSUB, r, l);
517
		l->type = t;
518
	}
519
	*n = *l;
520
}
521
 
522
void
523
acom1(vlong v, Node *n)
524
{
525
	Node *l, *r;
526
 
527
	if(v == 0 || nterm >= NTERM)
528
		return;
529
	if(!addo(n)) {
530
		if(n->op == OCONST)
531
		if(!typefd[n->type->etype]) {
532
			term[0].mult += v*n->vconst;
533
			return;
534
		}
535
		term[nterm].mult = v;
536
		term[nterm].node = n;
537
		nterm++;
538
		return;
539
	}
540
	switch(n->op) {
541
 
542
	case OCAST:
543
		acom1(v, n->left);
544
		break;
545
 
546
	case ONEG:
547
		acom1(-v, n->left);
548
		break;
549
 
550
	case OADD:
551
		acom1(v, n->left);
552
		acom1(v, n->right);
553
		break;
554
 
555
	case OSUB:
556
		acom1(v, n->left);
557
		acom1(-v, n->right);
558
		break;
559
 
560
	case OMUL:
561
		l = n->left;
562
		r = n->right;
563
		if(l->op == OCONST)
564
		if(!typefd[n->type->etype]) {
565
			acom1(v*l->vconst, r);
566
			break;
567
		}
568
		if(r->op == OCONST)
569
		if(!typefd[n->type->etype]) {
570
			acom1(v*r->vconst, l);
571
			break;
572
		}
573
		break;
574
 
575
	default:
576
		diag(n, "not addo");
577
	}
578
}
579
 
580
int
581
addo(Node *n)
582
{
583
 
584
	if(n != Z)
585
	if(!typefd[n->type->etype])
586
	if(!typev[n->type->etype] || ewidth[TVLONG] == ewidth[TIND])
587
	switch(n->op) {
588
 
589
	case OCAST:
590
		if(nilcast(n->left->type, n->type))
591
			return 1;
592
		break;
593
 
594
	case ONEG:
595
	case OADD:
596
	case OSUB:
597
		return 1;
598
 
599
	case OMUL:
600
		if(n->left->op == OCONST)
601
			return 1;
602
		if(n->right->op == OCONST)
603
			return 1;
604
	}
605
	return 0;
606
}