Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include	"l.h"
2
 
3
void
4
noops(void)
5
{
6
	Prog *p, *p1, *q, *q1;
7
	int o, curframe, curbecome, maxbecome;
8
 
9
	/*
10
	 * find leaf subroutines
11
	 * become sizes
12
	 * frame sizes
13
	 * strip NOPs
14
	 * expand RET
15
	 * expand BECOME pseudo
16
	 */
17
 
18
	if(debug['v'])
19
		Bprint(&bso, "%5.2f noops\n", cputime());
20
	Bflush(&bso);
21
 
22
	curframe = 0;
23
	curbecome = 0;
24
	maxbecome = 0;
25
	curtext = 0;
26
	q = P;
27
	for(p = firstp; p != P; p = p->link) {
28
 
29
		/* find out how much arg space is used in this TEXT */
30
		if(p->to.type == D_OREG && p->to.reg == REGSP)
31
			if(p->to.offset > curframe)
32
				curframe = p->to.offset;
33
 
34
		switch(p->as) {
35
		/* too hard, just leave alone */
36
		case ATEXT:
37
			if(curtext && curtext->from.sym) {
38
				curtext->from.sym->frame = curframe;
39
				curtext->from.sym->become = curbecome;
40
				if(curbecome > maxbecome)
41
					maxbecome = curbecome;
42
			}
43
			curframe = 0;
44
			curbecome = 0;
45
 
46
			q = p;
47
			p->mark |= LABEL|LEAF|SYNC;
48
			if(p->link)
49
				p->link->mark |= LABEL;
50
			curtext = p;
51
			break;
52
 
53
		case AORN:
54
			q = p;
55
			if(p->to.type == D_REG)
56
				if(p->to.reg == REGZERO)
57
					p->mark |= LABEL|SYNC;
58
			break;
59
 
60
		case AUNIMP:
61
		case ATAS:
62
		case ASWAP:
63
		case ATA:
64
		case ATCC:
65
		case ATCS:
66
		case ATE:
67
		case ATG:
68
		case ATGE:
69
		case ATGU:
70
		case ATL:
71
		case ATLE:
72
		case ATLEU:
73
		case ATN:
74
		case ATNE:
75
		case ATNEG:
76
		case ATPOS:
77
		case ATVC:
78
		case ATVS:
79
		case AWORD:
80
			q = p;
81
			p->mark |= LABEL|SYNC;
82
			continue;
83
 
84
		case AFABSD:
85
		case AFABSF:
86
		case AFABSX:
87
		case AFADDD:
88
		case AFADDF:
89
		case AFADDX:
90
		case AFDIVD:
91
		case AFDIVF:
92
		case AFDIVX:
93
		case AFMOVD:
94
		case AFMOVDF:
95
		case AFMOVDW:
96
		case AFMOVDX:
97
		case AFMOVF:
98
		case AFMOVFD:
99
		case AFMOVFW:
100
		case AFMOVFX:
101
		case AFMOVWD:
102
		case AFMOVWF:
103
		case AFMOVWX:
104
		case AFMOVX:
105
		case AFMOVXD:
106
		case AFMOVXF:
107
		case AFMOVXW:
108
		case AFMULD:
109
		case AFMULF:
110
		case AFMULX:
111
		case AFNEGD:
112
		case AFNEGF:
113
		case AFNEGX:
114
		case AFSQRTD:
115
		case AFSQRTF:
116
		case AFSQRTX:
117
		case AFSUBD:
118
		case AFSUBF:
119
		case AFSUBX:
120
			q = p;
121
			p->mark |= FLOAT;
122
			continue;
123
 
124
		case AMUL:
125
		case ADIV:
126
		case ADIVL:
127
		case AMOD:
128
		case AMODL:
129
			q = p;
130
			if(!debug['M']) {
131
				if(prog_mul == P)
132
					initmuldiv();
133
				if(curtext != P)
134
					curtext->mark &= ~LEAF;
135
			}
136
			continue;
137
 
138
		case AJMPL:
139
			if(curtext != P)
140
				curtext->mark &= ~LEAF;
141
 
142
		case AJMP:
143
 
144
		case ABA:
145
		case ABN:
146
		case ABE:
147
		case ABNE:
148
		case ABLE:
149
		case ABG:
150
		case ABL:
151
		case ABGE:
152
		case ABLEU:
153
		case ABGU:
154
		case ABCS:
155
		case ABCC:
156
		case ABNEG:
157
		case ABPOS:
158
		case ABVC:
159
		case ABVS:
160
 
161
		case AFBN:
162
		case AFBO:
163
		case AFBE:
164
		case AFBLG:
165
		case AFBG:
166
		case AFBLE:
167
		case AFBGE:
168
		case AFBL:
169
		case AFBNE:
170
		case AFBUE:
171
		case AFBA:
172
		case AFBU:
173
		case AFBUG:
174
		case AFBULE:
175
		case AFBUGE:
176
		case AFBUL:
177
			p->mark |= BRANCH;
178
			q = p;
179
			q1 = p->cond;
180
			if(q1 != P) {
181
				while(q1->as == ANOP) {
182
					q1 = q1->link;
183
					p->cond = q1;
184
				}
185
				if(!(q1->mark & LEAF))
186
					q1->mark |= LABEL;
187
			} else
188
				p->mark |= LABEL;
189
			q1 = p->link;
190
			if(q1 != P)
191
				q1->mark |= LABEL;
192
			continue;
193
 
194
		case AFCMPD:
195
		case AFCMPED:
196
		case AFCMPEF:
197
		case AFCMPEX:
198
		case AFCMPF:
199
		case AFCMPX:
200
			q = p;
201
			p->mark |= FCMP|FLOAT;
202
			continue;
203
 
204
		case ARETURN:
205
			/* special form of RETURN is BECOME */
206
			if(p->from.type == D_CONST)
207
				if(p->from.offset > curbecome)
208
					curbecome = p->from.offset;
209
 
210
			q = p;
211
			if(p->link != P)
212
				p->link->mark |= LABEL;
213
			continue;
214
 
215
		case ANOP:
216
			q1 = p->link;
217
			q->link = q1;		/* q is non-nop */
218
			q1->mark |= p->mark;
219
			continue;
220
 
221
		default:
222
			q = p;
223
			continue;
224
		}
225
	}
226
	if(curtext && curtext->from.sym) {
227
		curtext->from.sym->frame = curframe;
228
		curtext->from.sym->become = curbecome;
229
		if(curbecome > maxbecome)
230
			maxbecome = curbecome;
231
	}
232
 
233
	if(debug['b'])
234
		print("max become = %d\n", maxbecome);
235
	xdefine("ALEFbecome", STEXT, maxbecome);
236
 
237
	curtext = 0;
238
	for(p = firstp; p != P; p = p->link) {
239
		switch(p->as) {
240
		case ATEXT:
241
			curtext = p;
242
			break;
243
 
244
		case AJMPL:
245
			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
246
				o = maxbecome - curtext->from.sym->frame;
247
				if(o <= 0)
248
					break;
249
				/* calling a become or calling a variable */
250
				if(p->to.sym == S || p->to.sym->become) {
251
					curtext->to.offset += o;
252
					if(debug['b']) {
253
						curp = p;
254
						print("%D calling %D increase %d\n",
255
							&curtext->from, &p->to, o);
256
					}
257
				}
258
			}
259
			break;
260
		}
261
	}
262
 
263
	curtext = P;
264
	for(p = firstp; p != P; p = p->link) {
265
		o = p->as;
266
		switch(o) {
267
		case ATEXT:
268
			curtext = p;
269
			autosize = p->to.offset + 4;
270
			if((p->mark & LEAF) && autosize <= 4)
271
				autosize = 0;
272
			else
273
				if(autosize & 4)
274
					autosize += 4;
275
			p->to.offset = autosize - 4;
276
 
277
			q = p;
278
			if(autosize) {
279
				q = prg();
280
				q->as = ASUB;
281
				q->line = p->line;
282
				q->from.type = D_CONST;
283
				q->from.offset = autosize;
284
				q->to.type = D_REG;
285
				q->to.reg = REGSP;
286
 
287
				q->link = p->link;
288
				p->link = q;
289
			} else
290
			if(!(curtext->mark & LEAF)) {
291
				if(debug['v'])
292
					Bprint(&bso, "save suppressed in: %s\n",
293
						curtext->from.sym->name);
294
				curtext->mark |= LEAF;
295
			}
296
 
297
			if(curtext->mark & LEAF) {
298
				if(curtext->from.sym)
299
					curtext->from.sym->type = SLEAF;
300
				break;
301
			}
302
 
303
			q1 = prg();
304
			q1->as = AMOVW;
305
			q1->line = p->line;
306
			q1->from.type = D_REG;
307
			q1->from.reg = REGLINK;
308
			q1->to.type = D_OREG;
309
			q1->from.offset = 0;
310
			q1->to.reg = REGSP;
311
 
312
			q1->link = q->link;
313
			q->link = q1;
314
			break;
315
 
316
		case AMUL:
317
		case ADIV:
318
		case ADIVL:
319
		case AMOD:
320
		case AMODL:
321
			if(debug['M'])
322
				break;
323
			if(p->from.type != D_REG)
324
				break;
325
			if(p->to.type != D_REG)
326
				break;
327
			q1 = p;
328
 
329
			/* MOV a,4(SP) */
330
			q = prg();
331
			q->link = p->link;
332
			p->link = q;
333
			p = q;
334
 
335
			p->as = AMOVW;
336
			p->line = q1->line;
337
			p->from.type = D_REG;
338
			p->from.reg = q1->from.reg;
339
			p->to.type = D_OREG;
340
			p->to.reg = REGSP;
341
			p->to.offset = 4;
342
 
343
			/* MOV b,REGTMP */
344
			q = prg();
345
			q->link = p->link;
346
			p->link = q;
347
			p = q;
348
 
349
			p->as = AMOVW;
350
			p->line = q1->line;
351
			p->from.type = D_REG;
352
			p->from.reg = q1->reg;
353
			if(q1->reg == NREG)
354
				p->from.reg = q1->to.reg;
355
			p->to.type = D_REG;
356
			p->to.reg = REGTMP;
357
			p->to.offset = 0;
358
 
359
			/* CALL appropriate */
360
			q = prg();
361
			q->link = p->link;
362
			p->link = q;
363
			p = q;
364
 
365
			p->as = AJMPL;
366
			p->line = q1->line;
367
			p->to.type = D_BRANCH;
368
			p->cond = p;
369
			p->mark |= BRANCH;
370
			switch(o) {
371
			case AMUL:
372
				p->cond = prog_mul;
373
				break;
374
			case ADIV:
375
				p->cond = prog_div;
376
				break;
377
			case ADIVL:
378
				p->cond = prog_divl;
379
				break;
380
			case AMOD:
381
				p->cond = prog_mod;
382
				break;
383
			case AMODL:
384
				p->cond = prog_modl;
385
				break;
386
			}
387
 
388
			/* MOV REGTMP, b */
389
			q = prg();
390
			q->link = p->link;
391
			p->link = q;
392
			p = q;
393
 
394
			p->as = AMOVW;
395
			p->line = q1->line;
396
			p->from.type = D_REG;
397
			p->from.reg = REGTMP;
398
			p->from.offset = 0;
399
			p->to.type = D_REG;
400
			p->to.reg = q1->to.reg;
401
 
402
			/* ADD $8,SP */
403
			q = prg();
404
			q->link = p->link;
405
			p->link = q;
406
			p = q;
407
 
408
			p->as = AADD;
409
			p->from.type = D_CONST;
410
			p->from.reg = NREG;
411
			p->from.offset = 8;
412
			p->reg = NREG;
413
			p->to.type = D_REG;
414
			p->to.reg = REGSP;
415
 
416
			/* SUB $8,SP */
417
			q1->as = ASUB;
418
			q1->from.type = D_CONST;
419
			q1->from.offset = 8;
420
			q1->from.reg = NREG;
421
			q1->reg = NREG;
422
			q1->to.type = D_REG;
423
			q1->to.reg = REGSP;
424
			break;
425
 
426
		case ARETURN:
427
			if(p->from.type == D_CONST)
428
				goto become;
429
			if(curtext->mark & LEAF) {
430
				if(!autosize) {
431
					p->as = AJMP;
432
					p->from = zprg.from;
433
					p->to.type = D_OREG;
434
					p->to.offset = 8;
435
					p->to.reg = REGLINK;
436
					p->mark |= BRANCH;
437
					break;
438
				}
439
 
440
				p->as = AADD;
441
				p->from.type = D_CONST;
442
				p->from.offset = autosize;
443
				p->to.type = D_REG;
444
				p->to.reg = REGSP;
445
 
446
				q = prg();
447
				q->as = AJMP;
448
				q->line = p->line;
449
				q->to.type = D_OREG;
450
				q->to.offset = 8;
451
				q->to.reg = REGLINK;
452
				q->mark |= BRANCH;
453
 
454
				q->link = p->link;
455
				p->link = q;
456
				break;
457
			}
458
 
459
			p->as = AMOVW;
460
			p->from.type = D_OREG;
461
			p->from.offset = 0;
462
			p->from.reg = REGSP;
463
			p->to.type = D_REG;
464
			p->to.reg = REGRET+1;
465
 
466
			q = p;
467
			if(autosize) {
468
				q = prg();
469
				q->as = AADD;
470
				q->line = p->line;
471
				q->from.type = D_CONST;
472
				q->from.offset = autosize;
473
				q->to.type = D_REG;
474
				q->to.reg = REGSP;
475
 
476
				q->link = p->link;
477
				p->link = q;
478
			}
479
 
480
			q1 = prg();
481
			q1->as = AJMP;
482
			q1->line = p->line;
483
			q1->to.type = D_OREG;
484
			q1->to.offset = 8;
485
			q1->to.reg = REGRET+1;
486
			q1->mark |= BRANCH;
487
 
488
			q1->link = q->link;
489
			q->link = q1;
490
			break;
491
 
492
		become:
493
			if(curtext->mark & LEAF) {
494
 
495
				q = prg();
496
				q->line = p->line;
497
				q->as = AJMP;
498
				q->from = zprg.from;
499
				q->to = p->to;
500
				q->cond = p->cond;
501
				q->link = p->link;
502
				q->mark |= BRANCH;
503
				p->link = q;
504
 
505
				p->as = AADD;
506
				p->from = zprg.from;
507
				p->from.type = D_CONST;
508
				p->from.offset = autosize;
509
				p->to = zprg.to;
510
				p->to.type = D_REG;
511
				p->to.reg = REGSP;
512
 
513
				break;
514
			}
515
			q = prg();
516
			q->line = p->line;
517
			q->as = AJMP;
518
			q->from = zprg.from;
519
			q->to = p->to;
520
			q->cond = p->cond;
521
			q->mark |= BRANCH;
522
			q->link = p->link;
523
			p->link = q;
524
 
525
			q = prg();
526
			q->line = p->line;
527
			q->as = AADD;
528
			q->from.type = D_CONST;
529
			q->from.offset = autosize;
530
			q->to.type = D_REG;
531
			q->to.reg = REGSP;
532
			q->link = p->link;
533
			p->link = q;
534
 
535
			p->as = AMOVW;
536
			p->from = zprg.from;
537
			p->from.type = D_OREG;
538
			p->from.offset = 0;
539
			p->from.reg = REGSP;
540
			p->to = zprg.to;
541
			p->to.type = D_REG;
542
			p->to.reg = REGLINK;
543
 
544
			break;
545
		}
546
	}
547
 
548
	curtext = P;
549
	q = P;		/* p - 1 */
550
	q1 = firstp;	/* top of block */
551
	o = 0;		/* count of instructions */
552
	for(p = firstp; p != P; p = p1) {
553
		p1 = p->link;
554
		o++;
555
		if(p->mark & NOSCHED){
556
			if(q1 != p){
557
				sched(q1, q);
558
			}
559
			for(; p != P; p = p->link){
560
				if(!(p->mark & NOSCHED))
561
					break;
562
				q = p;
563
			}
564
			p1 = p;
565
			q1 = p;
566
			o = 0;
567
			continue;
568
		}
569
		if(p->mark & (LABEL|SYNC)) {
570
			if(q1 != p)
571
				sched(q1, q);
572
			q1 = p;
573
			o = 1;
574
		}
575
		if(p->mark & (BRANCH|SYNC)) {
576
			sched(q1, p);
577
			q1 = p1;
578
			o = 0;
579
		}
580
		if(o >= NSCHED) {
581
			sched(q1, p);
582
			q1 = p1;
583
			o = 0;
584
		}
585
		q = p;
586
	}
587
}
588
 
589
void
590
addnop(Prog *p)
591
{
592
	Prog *q;
593
 
594
	q = prg();
595
	q->as = AORN;
596
	q->line = p->line;
597
	q->from.type = D_REG;
598
	q->from.reg = REGZERO;
599
	q->to.type = D_REG;
600
	q->to.reg = REGZERO;
601
 
602
	q->link = p->link;
603
	p->link = q;
604
}
605
 
606
void
607
initmuldiv(void)
608
{
609
	Sym *s1, *s2, *s3, *s4, *s5;
610
	Prog *p;
611
 
612
	s1 = lookup("_mul", 0);
613
	s2 = lookup("_div", 0);
614
	s3 = lookup("_divl", 0);
615
	s4 = lookup("_mod", 0);
616
	s5 = lookup("_modl", 0);
617
	for(p = firstp; p != P; p = p->link)
618
		if(p->as == ATEXT) {
619
			if(p->from.sym == s1)
620
				prog_mul = p;
621
			if(p->from.sym == s2)
622
				prog_div = p;
623
			if(p->from.sym == s3)
624
				prog_divl = p;
625
			if(p->from.sym == s4)
626
				prog_mod = p;
627
			if(p->from.sym == s5)
628
				prog_modl = p;
629
		}
630
	if(prog_mul == P) {
631
		diag("undefined: %s", s1->name);
632
		prog_mul = curtext;
633
	}
634
	if(prog_div == P) {
635
		diag("undefined: %s", s2->name);
636
		prog_div = curtext;
637
	}
638
	if(prog_divl == P) {
639
		diag("undefined: %s", s3->name);
640
		prog_divl = curtext;
641
	}
642
	if(prog_mod == P) {
643
		diag("undefined: %s", s4->name);
644
		prog_mod = curtext;
645
	}
646
	if(prog_modl == P) {
647
		diag("undefined: %s", s5->name);
648
		prog_modl = curtext;
649
	}
650
}