]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/5l/noop.c
upas/fs: remove useless loop in rf822()
[plan9front.git] / sys / src / cmd / 5l / noop.c
1 #include        "l.h"
2
3 static  Sym*    sym_div;
4 static  Sym*    sym_divu;
5 static  Sym*    sym_mod;
6 static  Sym*    sym_modu;
7
8 void
9 noops(void)
10 {
11         Prog *p, *q, *q1;
12         int o, curframe, curbecome, maxbecome;
13
14         /*
15          * find leaf subroutines
16          * become sizes
17          * frame sizes
18          * strip NOPs
19          * expand RET
20          * expand BECOME pseudo
21          */
22
23         if(debug['v'])
24                 Bprint(&bso, "%5.2f noops\n", cputime());
25         Bflush(&bso);
26
27         curframe = 0;
28         curbecome = 0;
29         maxbecome = 0;
30         curtext = 0;
31
32         q = P;
33         for(p = firstp; p != P; p = p->link) {
34
35                 /* find out how much arg space is used in this TEXT */
36                 if(p->to.type == D_OREG && p->to.reg == REGSP)
37                         if(p->to.offset > curframe)
38                                 curframe = p->to.offset;
39
40                 switch(p->as) {
41                 case ATEXT:
42                         if(curtext && curtext->from.sym) {
43                                 curtext->from.sym->frame = curframe;
44                                 curtext->from.sym->become = curbecome;
45                                 if(curbecome > maxbecome)
46                                         maxbecome = curbecome;
47                         }
48                         curframe = 0;
49                         curbecome = 0;
50
51                         p->mark |= LEAF;
52                         curtext = p;
53                         break;
54
55                 case ARET:
56                         /* special form of RET is BECOME */
57                         if(p->from.type == D_CONST)
58                                 if(p->from.offset > curbecome)
59                                         curbecome = p->from.offset;
60                         break;
61
62                 case ADIV:
63                 case ADIVU:
64                 case AMOD:
65                 case AMODU:
66                         q = p;
67                         if(prog_div == P)
68                                 initdiv();
69                         if(curtext != P)
70                                 curtext->mark &= ~LEAF;
71                         continue;
72
73                 case ANOP:
74                         q1 = p->link;
75                         q->link = q1;           /* q is non-nop */
76                         q1->mark |= p->mark;
77                         continue;
78
79                 case ABL:
80                         if(curtext != P)
81                                 curtext->mark &= ~LEAF;
82
83                 case ABCASE:
84                 case AB:
85
86                 case ABEQ:
87                 case ABNE:
88                 case ABCS:
89                 case ABHS:
90                 case ABCC:
91                 case ABLO:
92                 case ABMI:
93                 case ABPL:
94                 case ABVS:
95                 case ABVC:
96                 case ABHI:
97                 case ABLS:
98                 case ABGE:
99                 case ABLT:
100                 case ABGT:
101                 case ABLE:
102
103                         q1 = p->cond;
104                         if(q1 != P) {
105                                 while(q1->as == ANOP) {
106                                         q1 = q1->link;
107                                         p->cond = q1;
108                                 }
109                         }
110                         break;
111                 }
112                 q = p;
113         }
114
115         if(curtext && curtext->from.sym) {
116                 curtext->from.sym->frame = curframe;
117                 curtext->from.sym->become = curbecome;
118                 if(curbecome > maxbecome)
119                         maxbecome = curbecome;
120         }
121
122         if(debug['b'])
123                 print("max become = %d\n", maxbecome);
124         xdefine("ALEFbecome", STEXT, maxbecome);
125
126         curtext = 0;
127         for(p = firstp; p != P; p = p->link) {
128                 switch(p->as) {
129                 case ATEXT:
130                         curtext = p;
131                         break;
132                 case ABL:
133                         if(curtext != P && curtext->from.sym != S && curtext->to.offset >= 0) {
134                                 o = maxbecome - curtext->from.sym->frame;
135                                 if(o <= 0)
136                                         break;
137                                 /* calling a become or calling a variable */
138                                 if(p->to.sym == S || p->to.sym->become) {
139                                         curtext->to.offset += o;
140                                         if(debug['b']) {
141                                                 curp = p;
142                                                 print("%D calling %D increase %d\n",
143                                                         &curtext->from, &p->to, o);
144                                         }
145                                 }
146                         }
147                         break;
148                 }
149         }
150
151         for(p = firstp; p != P; p = p->link) {
152                 o = p->as;
153                 switch(o) {
154                 case ATEXT:
155                         curtext = p;
156                         autosize = p->to.offset + 4;
157                         if(autosize <= 4)
158                         if(curtext->mark & LEAF) {
159                                 p->to.offset = -4;
160                                 autosize = 0;
161                         }
162
163                         if(!autosize && !(curtext->mark & LEAF)) {
164                                 if(debug['v'])
165                                         Bprint(&bso, "save suppressed in: %s\n",
166                                                 curtext->from.sym->name);
167                                 Bflush(&bso);
168                                 curtext->mark |= LEAF;
169                         }
170
171                         if(curtext->mark & LEAF) {
172                                 if(curtext->from.sym)
173                                         curtext->from.sym->type = SLEAF;
174 #ifdef optimise_time
175                                 if(autosize) {
176                                         q = prg();
177                                         q->as = ASUB;
178                                         q->line = p->line;
179                                         q->from.type = D_CONST;
180                                         q->from.offset = autosize;
181                                         q->to.type = D_REG;
182                                         q->to.reg = REGSP;
183
184                                         q->link = p->link;
185                                         p->link = q;
186                                 }
187                                 break;
188 #else
189                                 if(!autosize)
190                                         break;
191 #endif
192                         }
193
194                         q1 = prg();
195                         q1->as = AMOVW;
196                         q1->scond |= C_WBIT;
197                         q1->line = p->line;
198                         q1->from.type = D_REG;
199                         q1->from.reg = REGLINK;
200                         q1->to.type = D_OREG;
201                         q1->to.offset = -autosize;
202                         q1->to.reg = REGSP;
203
204                         q1->link = p->link;
205                         p->link = q1;
206                         break;
207
208                 case ARET:
209                         nocache(p);
210                         if(p->from.type == D_CONST)
211                                 goto become;
212                         if(curtext->mark & LEAF) {
213                                 if(!autosize) {
214                                         p->as = AB;
215                                         p->from = zprg.from;
216                                         p->to.type = D_OREG;
217                                         p->to.offset = 0;
218                                         p->to.reg = REGLINK;
219                                         break;
220                                 }
221
222 #ifdef optimise_time
223                                 p->as = AADD;
224                                 p->from.type = D_CONST;
225                                 p->from.offset = autosize;
226                                 p->to.type = D_REG;
227                                 p->to.reg = REGSP;
228
229                                 q = prg();
230                                 q->as = AB;
231                                 q->scond = p->scond;
232                                 q->line = p->line;
233                                 q->to.type = D_OREG;
234                                 q->to.offset = 0;
235                                 q->to.reg = REGLINK;
236
237                                 q->link = p->link;
238                                 p->link = q;
239
240                                 break;
241 #endif
242                         }
243                         p->as = AMOVW;
244                         p->scond |= C_PBIT;
245                         p->from.type = D_OREG;
246                         p->from.offset = autosize;
247                         p->from.reg = REGSP;
248                         p->to.type = D_REG;
249                         p->to.reg = REGPC;
250                         break;
251
252                 become:
253                         if(curtext->mark & LEAF) {
254
255                                 if(!autosize) {
256                                         p->as = AB;
257                                         p->from = zprg.from;
258                                         break;
259                                 }
260
261 #ifdef optimise_time
262                                 q = prg();
263                                 q->scond = p->scond;
264                                 q->line = p->line;
265                                 q->as = AB;
266                                 q->from = zprg.from;
267                                 q->to = p->to;
268                                 q->cond = p->cond;
269                                 q->link = p->link;
270                                 p->link = q;
271
272                                 p->as = AADD;
273                                 p->from = zprg.from;
274                                 p->from.type = D_CONST;
275                                 p->from.offset = autosize;
276                                 p->to = zprg.to;
277                                 p->to.type = D_REG;
278                                 p->to.reg = REGSP;
279
280                                 break;
281 #endif
282                         }
283                         q = prg();
284                         q->scond = p->scond;
285                         q->line = p->line;
286                         q->as = AB;
287                         q->from = zprg.from;
288                         q->to = p->to;
289                         q->cond = p->cond;
290                         q->link = p->link;
291                         p->link = q;
292
293                         p->as = AMOVW;
294                         p->scond |= C_PBIT;
295                         p->from = zprg.from;
296                         p->from.type = D_OREG;
297                         p->from.offset = autosize;
298                         p->from.reg = REGSP;
299                         p->to = zprg.to;
300                         p->to.type = D_REG;
301                         p->to.reg = REGLINK;
302
303                         break;
304
305                 /*
306                  * 5c code generation for unsigned -> double made the
307                  * unfortunate assumption that single and double floating
308                  * point registers are aliased - true for emulated 7500
309                  * but not for vfp.  Now corrected, but this test is
310                  * insurance against old 5c compiled code in libraries.
311                  */
312                 case AMOVWD:
313                         if((q = p->link) != P && q->as == ACMP)
314                         if((q = q->link) != P && q->as == AMOVF)
315                         if((q1 = q->link) != P && q1->as == AADDF)
316                         if(q1->to.type == D_FREG && q1->to.reg == p->to.reg) {
317                                 q1->as = AADDD;
318                                 q1 = prg();
319                                 q1->scond = q->scond;
320                                 q1->line = q->line;
321                                 q1->as = AMOVFD;
322                                 q1->from = q->to;
323                                 q1->to = q1->from;
324                                 q1->link = q->link;
325                                 q->link = q1;
326                         }
327                         break;
328
329                 case ADIV:
330                 case ADIVU:
331                 case AMOD:
332                 case AMODU:
333                         if(debug['M'])
334                                 break;
335                         if(p->from.type != D_REG)
336                                 break;
337                         if(p->to.type != D_REG)
338                                 break;
339                         q1 = p;
340
341                         /* MOV a,4(SP) */
342                         q = prg();
343                         q->link = p->link;
344                         p->link = q;
345                         p = q;
346
347                         p->as = AMOVW;
348                         p->line = q1->line;
349                         p->from.type = D_REG;
350                         p->from.reg = q1->from.reg;
351                         p->to.type = D_OREG;
352                         p->to.reg = REGSP;
353                         p->to.offset = 4;
354
355                         /* MOV b,REGTMP */
356                         q = prg();
357                         q->link = p->link;
358                         p->link = q;
359                         p = q;
360
361                         p->as = AMOVW;
362                         p->line = q1->line;
363                         p->from.type = D_REG;
364                         p->from.reg = q1->reg;
365                         if(q1->reg == NREG)
366                                 p->from.reg = q1->to.reg;
367                         p->to.type = D_REG;
368                         p->to.reg = REGTMP;
369                         p->to.offset = 0;
370
371                         /* CALL appropriate */
372                         q = prg();
373                         q->link = p->link;
374                         p->link = q;
375                         p = q;
376
377                         p->as = ABL;
378                         p->line = q1->line;
379                         p->to.type = D_BRANCH;
380                         p->cond = p;
381                         switch(o) {
382                         case ADIV:
383                                 p->cond = prog_div;
384                                 p->to.sym = sym_div;
385                                 break;
386                         case ADIVU:
387                                 p->cond = prog_divu;
388                                 p->to.sym = sym_divu;
389                                 break;
390                         case AMOD:
391                                 p->cond = prog_mod;
392                                 p->to.sym = sym_mod;
393                                 break;
394                         case AMODU:
395                                 p->cond = prog_modu;
396                                 p->to.sym = sym_modu;
397                                 break;
398                         }
399
400                         /* MOV REGTMP, b */
401                         q = prg();
402                         q->link = p->link;
403                         p->link = q;
404                         p = q;
405
406                         p->as = AMOVW;
407                         p->line = q1->line;
408                         p->from.type = D_REG;
409                         p->from.reg = REGTMP;
410                         p->from.offset = 0;
411                         p->to.type = D_REG;
412                         p->to.reg = q1->to.reg;
413
414                         /* ADD $8,SP */
415                         q = prg();
416                         q->link = p->link;
417                         p->link = q;
418                         p = q;
419
420                         p->as = AADD;
421                         p->from.type = D_CONST;
422                         p->from.reg = NREG;
423                         p->from.offset = 8;
424                         p->reg = NREG;
425                         p->to.type = D_REG;
426                         p->to.reg = REGSP;
427
428                         /* SUB $8,SP */
429                         q1->as = ASUB;
430                         q1->from.type = D_CONST;
431                         q1->from.offset = 8;
432                         q1->from.reg = NREG;
433                         q1->reg = NREG;
434                         q1->to.type = D_REG;
435                         q1->to.reg = REGSP;
436                         break;
437                 }
438         }
439 }
440
441 static void
442 sigdiv(char *n)
443 {
444         Sym *s;
445
446         s = lookup(n, 0);
447         if(s->type == STEXT){
448                 if(s->sig == 0)
449                         s->sig = SIGNINTERN;
450         }
451         else if(s->type == 0 || s->type == SXREF)
452                 s->type = SUNDEF;
453 }
454
455 void
456 divsig(void)
457 {
458         sigdiv("_div");
459         sigdiv("_divu");
460         sigdiv("_mod");
461         sigdiv("_modu");
462 }
463
464 static void
465 sdiv(Sym *s)
466 {
467         if(s->type == 0 || s->type == SXREF){
468                 /* undefsym(s); */
469                 s->type = SXREF;
470                 if(s->sig == 0)
471                         s->sig = SIGNINTERN;
472                 s->subtype = SIMPORT;
473         }
474         else if(s->type != STEXT)
475                 diag("undefined: %s", s->name);
476 }
477
478 void
479 initdiv(void)
480 {
481         Sym *s2, *s3, *s4, *s5;
482         Prog *p;
483
484         if(prog_div != P)
485                 return;
486         sym_div = s2 = lookup("_div", 0);
487         sym_divu = s3 = lookup("_divu", 0);
488         sym_mod = s4 = lookup("_mod", 0);
489         sym_modu = s5 = lookup("_modu", 0);
490         if(dlm) {
491                 sdiv(s2); if(s2->type == SXREF) prog_div = UP;
492                 sdiv(s3); if(s3->type == SXREF) prog_divu = UP;
493                 sdiv(s4); if(s4->type == SXREF) prog_mod = UP;
494                 sdiv(s5); if(s5->type == SXREF) prog_modu = UP;
495         }
496         for(p = firstp; p != P; p = p->link)
497                 if(p->as == ATEXT) {
498                         if(p->from.sym == s2)
499                                 prog_div = p;
500                         if(p->from.sym == s3)
501                                 prog_divu = p;
502                         if(p->from.sym == s4)
503                                 prog_mod = p;
504                         if(p->from.sym == s5)
505                                 prog_modu = p;
506                 }
507         if(prog_div == P) {
508                 diag("undefined: %s", s2->name);
509                 prog_div = curtext;
510         }
511         if(prog_divu == P) {
512                 diag("undefined: %s", s3->name);
513                 prog_divu = curtext;
514         }
515         if(prog_mod == P) {
516                 diag("undefined: %s", s4->name);
517                 prog_mod = curtext;
518         }
519         if(prog_modu == P) {
520                 diag("undefined: %s", s5->name);
521                 prog_modu = curtext;
522         }
523 }
524
525 void
526 nocache(Prog *p)
527 {
528         p->optab = 0;
529         p->from.class = 0;
530         p->to.class = 0;
531 }