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, mov, aoffset, 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 ANOR:
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 ALWAR:
61
		case ASTWCCC:
62
		case AECIWX:
63
		case AECOWX:
64
		case AEIEIO:
65
		case AICBI:
66
		case AISYNC:
67
		case ATLBIE:
68
		case ADCBF:
69
		case ADCBI:
70
		case ADCBST:
71
		case ADCBT:
72
		case ADCBTST:
73
		case ADCBZ:
74
		case ASYNC:
75
		case ATW:
76
		case AWORD:
77
		case ARFI:
78
		case ARFCI:
79
			q = p;
80
			p->mark |= LABEL|SYNC;
81
			continue;
82
 
83
		case AMOVW:
84
			q = p;
85
			switch(p->from.type) {
86
			case D_MSR:
87
			case D_SREG:
88
			case D_SPR:
89
			case D_FPSCR:
90
			case D_CREG:
91
			case D_DCR:
92
				p->mark |= LABEL|SYNC;
93
			}
94
			switch(p->to.type) {
95
			case D_MSR:
96
			case D_SREG:
97
			case D_SPR:
98
			case D_FPSCR:
99
			case D_CREG:
100
			case D_DCR:
101
				p->mark |= LABEL|SYNC;
102
			}
103
			continue;
104
 
105
		case AFABS:
106
		case AFABSCC:
107
		case AFADD:
108
		case AFADDCC:
109
		case AFCTIW:
110
		case AFCTIWCC:
111
		case AFCTIWZ:
112
		case AFCTIWZCC:
113
		case AFDIV:
114
		case AFDIVCC:
115
		case AFMADD:
116
		case AFMADDCC:
117
		case AFMOVD:
118
		case AFMOVDU:
119
		/* case AFMOVDS: */
120
		case AFMOVS:
121
		case AFMOVSU:
122
		/* case AFMOVSD: */
123
		case AFMSUB:
124
		case AFMSUBCC:
125
		case AFMUL:
126
		case AFMULCC:
127
		case AFNABS:
128
		case AFNABSCC:
129
		case AFNEG:
130
		case AFNEGCC:
131
		case AFNMADD:
132
		case AFNMADDCC:
133
		case AFNMSUB:
134
		case AFNMSUBCC:
135
		case AFRSP:
136
		case AFRSPCC:
137
		case AFSUB:
138
		case AFSUBCC:
139
			q = p;
140
			p->mark |= FLOAT;
141
			continue;
142
 
143
		case ABL:
144
		case ABCL:
145
			if(curtext != P)
146
				curtext->mark &= ~LEAF;
147
 
148
		case ABC:
149
		case ABEQ:
150
		case ABGE:
151
		case ABGT:
152
		case ABLE:
153
		case ABLT:
154
		case ABNE:
155
		case ABR:
156
		case ABVC:
157
		case ABVS:
158
 
159
			p->mark |= BRANCH;
160
			q = p;
161
			q1 = p->cond;
162
			if(q1 != P) {
163
				while(q1->as == ANOP) {
164
					q1 = q1->link;
165
					p->cond = q1;
166
				}
167
				if(!(q1->mark & LEAF))
168
					q1->mark |= LABEL;
169
			} else
170
				p->mark |= LABEL;
171
			q1 = p->link;
172
			if(q1 != P)
173
				q1->mark |= LABEL;
174
			continue;
175
 
176
		case AFCMPO:
177
		case AFCMPU:
178
			q = p;
179
			p->mark |= FCMP|FLOAT;
180
			continue;
181
 
182
		case ARETURN:
183
			/* special form of RETURN is BECOME */
184
			if(p->from.type == D_CONST)
185
				if(p->from.offset > curbecome)
186
					curbecome = p->from.offset;
187
 
188
			q = p;
189
			if(p->link != P)
190
				p->link->mark |= LABEL;
191
			continue;
192
 
193
		case ANOP:
194
			q1 = p->link;
195
			q->link = q1;		/* q is non-nop */
196
			q1->mark |= p->mark;
197
			continue;
198
 
199
		default:
200
			q = p;
201
			continue;
202
		}
203
	}
204
	if(curtext && curtext->from.sym) {
205
		curtext->from.sym->frame = curframe;
206
		curtext->from.sym->become = curbecome;
207
		if(curbecome > maxbecome)
208
			maxbecome = curbecome;
209
	}
210
 
211
	if(debug['b'])
212
		print("max become = %d\n", maxbecome);
213
	xdefine("ALEFbecome", STEXT, maxbecome);
214
 
215
	curtext = 0;
216
	for(p = firstp; p != P; p = p->link) {
217
		switch(p->as) {
218
		case ATEXT:
219
			curtext = p;
220
			break;
221
 
222
		case ABL:	/* ABCL? */
223
			if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
224
				o = maxbecome - curtext->from.sym->frame;
225
				if(o <= 0)
226
					break;
227
				/* calling a become or calling a variable */
228
				if(p->to.sym == S || p->to.sym->become) {
229
					curtext->to.offset += o;
230
					if(debug['b']) {
231
						curp = p;
232
						print("%D calling %D increase %d\n",
233
							&curtext->from, &p->to, o);
234
					}
235
				}
236
			}
237
			break;
238
		}
239
	}
240
 
241
	curtext = P;
242
	for(p = firstp; p != P; p = p->link) {
243
		o = p->as;
244
		switch(o) {
245
		case ATEXT:
246
			mov = AMOVW;
247
			aoffset = 0;
248
			curtext = p;
249
			autosize = p->to.offset + 4;
250
			if((p->mark & LEAF) && autosize <= 4)
251
				autosize = 0;
252
			else
253
				if(autosize & 4)
254
					autosize += 4;
255
			p->to.offset = autosize - 4;
256
 
257
			q = p;
258
			if(autosize) {
259
				/* use MOVWU to adjust R1 when saving R31, if autosize is small */
260
				if(!(curtext->mark & LEAF) && autosize >= -BIG && autosize <= BIG) {
261
					mov = AMOVWU;
262
					aoffset = -autosize;
263
				} else {
264
					q = prg();
265
					q->as = AADD;
266
					q->line = p->line;
267
					q->from.type = D_CONST;
268
					q->from.offset = -autosize;
269
					q->to.type = D_REG;
270
					q->to.reg = REGSP;
271
 
272
					q->link = p->link;
273
					p->link = q;
274
				}
275
			} else
276
			if(!(curtext->mark & LEAF)) {
277
				if(debug['v'])
278
					Bprint(&bso, "save suppressed in: %s\n",
279
						curtext->from.sym->name);
280
				curtext->mark |= LEAF;
281
			}
282
 
283
			if(curtext->mark & LEAF) {
284
				if(curtext->from.sym)
285
					curtext->from.sym->type = SLEAF;
286
				break;
287
			}
288
 
289
			q1 = prg();
290
			q1->as = mov;
291
			q1->line = p->line;
292
			q1->from.type = D_REG;
293
			q1->from.reg = REGTMP;
294
			q1->to.type = D_OREG;
295
			q1->to.offset = aoffset;
296
			q1->to.reg = REGSP;
297
 
298
			q1->link = q->link;
299
			q->link = q1;
300
 
301
			q1 = prg();
302
			q1->as = AMOVW;
303
			q1->line = p->line;
304
			q1->from.type = D_SPR;
305
			q1->from.offset = D_LR;
306
			q1->to.type = D_REG;
307
			q1->to.reg = REGTMP;
308
 
309
			q1->link = q->link;
310
			q->link = q1;
311
			break;
312
 
313
		case ARETURN:
314
			if(p->from.type == D_CONST)
315
				goto become;
316
			if(curtext->mark & LEAF) {
317
				if(!autosize) {
318
					p->as = ABR;
319
					p->from = zprg.from;
320
					p->to.type = D_SPR;
321
					p->to.offset = D_LR;
322
					p->mark |= BRANCH;
323
					break;
324
				}
325
 
326
				p->as = AADD;
327
				p->from.type = D_CONST;
328
				p->from.offset = autosize;
329
				p->to.type = D_REG;
330
				p->to.reg = REGSP;
331
 
332
				q = prg();
333
				q->as = ABR;
334
				q->line = p->line;
335
				q->to.type = D_SPR;
336
				q->to.offset = D_LR;
337
				q->mark |= BRANCH;
338
 
339
				q->link = p->link;
340
				p->link = q;
341
				break;
342
			}
343
 
344
			p->as = AMOVW;
345
			p->from.type = D_OREG;
346
			p->from.offset = 0;
347
			p->from.reg = REGSP;
348
			p->to.type = D_REG;
349
			p->to.reg = REGTMP;
350
 
351
			q = prg();
352
			q->as = AMOVW;
353
			q->line = p->line;
354
			q->from.type = D_REG;
355
			q->from.reg = REGTMP;
356
			q->to.type = D_SPR;
357
			q->to.offset = D_LR;
358
 
359
			q->link = p->link;
360
			p->link = q;
361
			p = q;
362
 
363
			if(autosize) {
364
				q = prg();
365
				q->as = AADD;
366
				q->line = p->line;
367
				q->from.type = D_CONST;
368
				q->from.offset = autosize;
369
				q->to.type = D_REG;
370
				q->to.reg = REGSP;
371
 
372
				q->link = p->link;
373
				p->link = q;
374
			}
375
 
376
			q1 = prg();
377
			q1->as = ABR;
378
			q1->line = p->line;
379
			q1->to.type = D_SPR;
380
			q1->to.offset = D_LR;
381
			q1->mark |= BRANCH;
382
 
383
			q1->link = q->link;
384
			q->link = q1;
385
			break;
386
 
387
		become:
388
			if(curtext->mark & LEAF) {
389
 
390
				q = prg();
391
				q->line = p->line;
392
				q->as = ABR;
393
				q->from = zprg.from;
394
				q->to = p->to;
395
				q->cond = p->cond;
396
				q->link = p->link;
397
				q->mark |= BRANCH;
398
				p->link = q;
399
 
400
				p->as = AADD;
401
				p->from = zprg.from;
402
				p->from.type = D_CONST;
403
				p->from.offset = autosize;
404
				p->to = zprg.to;
405
				p->to.type = D_REG;
406
				p->to.reg = REGSP;
407
 
408
				break;
409
			}
410
			q = prg();
411
			q->line = p->line;
412
			q->as = ABR;
413
			q->from = zprg.from;
414
			q->to = p->to;
415
			q->cond = p->cond;
416
			q->mark |= BRANCH;
417
			q->link = p->link;
418
			p->link = q;
419
 
420
			q = prg();
421
			q->line = p->line;
422
			q->as = AADD;
423
			q->from.type = D_CONST;
424
			q->from.offset = autosize;
425
			q->to.type = D_REG;
426
			q->to.reg = REGSP;
427
			q->link = p->link;
428
			p->link = q;
429
 
430
			q = prg();
431
			q->line = p->line;
432
			q->as = AMOVW;
433
			q->line = p->line;
434
			q->from.type = D_REG;
435
			q->from.reg = REGTMP;
436
			q->to.type = D_SPR;
437
			q->to.offset = D_LR;
438
			q->link = p->link;
439
			p->link = q;
440
 
441
			p->as = AMOVW;
442
			p->from = zprg.from;
443
			p->from.type = D_OREG;
444
			p->from.offset = 0;
445
			p->from.reg = REGSP;
446
			p->to = zprg.to;
447
			p->to.type = D_REG;
448
			p->to.reg = REGTMP;
449
 
450
			break;
451
		}
452
	}
453
 
454
	if(debug['Q'] == 0)
455
		return;
456
 
457
	curtext = P;
458
	q = P;		/* p - 1 */
459
	q1 = firstp;	/* top of block */
460
	o = 0;		/* count of instructions */
461
	for(p = firstp; p != P; p = p1) {
462
		p1 = p->link;
463
		o++;
464
		if(p->mark & NOSCHED){
465
			if(q1 != p){
466
				sched(q1, q);
467
			}
468
			for(; p != P; p = p->link){
469
				if(!(p->mark & NOSCHED))
470
					break;
471
				q = p;
472
			}
473
			p1 = p;
474
			q1 = p;
475
			o = 0;
476
			continue;
477
		}
478
		if(p->mark & (LABEL|SYNC)) {
479
			if(q1 != p)
480
				sched(q1, q);
481
			q1 = p;
482
			o = 1;
483
		}
484
		if(p->mark & (BRANCH|SYNC)) {
485
			sched(q1, p);
486
			q1 = p1;
487
			o = 0;
488
		}
489
		if(o >= NSCHED) {
490
			sched(q1, p);
491
			q1 = p1;
492
			o = 0;
493
		}
494
		q = p;
495
	}
496
}
497
 
498
void
499
addnop(Prog *p)
500
{
501
	Prog *q;
502
 
503
	q = prg();
504
	q->as = ANOR;
505
	q->line = p->line;
506
	q->from.type = D_REG;
507
	q->from.reg = REGZERO;
508
	q->to.type = D_REG;
509
	q->to.reg = REGZERO;
510
 
511
	q->link = p->link;
512
	p->link = q;
513
}