Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / cg / move.c
1 #ifndef NORCSID
2 static char rcsid[] = "$Id: move.c,v 2.5 1994/06/24 13:23:53 ceriel Exp $";
3 #endif
4
5 #include "assert.h"
6 #include "param.h"
7 #include "tables.h"
8 #include "types.h"
9 #include <cg_pattern.h>
10 #include "data.h"
11 #include "result.h"
12 #include "extern.h"
13
14 /*
15  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
16  * See the copyright notice in the ACK home directory, in the file "Copyright".
17  *
18  * Author: Hans van Staveren
19  */
20
21 unsigned costcalc();
22
23 move(tp1,tp2,ply,toplevel,maxcost) token_p tp1,tp2; unsigned maxcost; {
24         register move_p mp;
25         register unsigned t;
26         register struct reginfo *rp;
27         tkdef_p tdp;
28         int i;
29         unsigned codegen();
30
31         if (eqtoken(tp1,tp2))
32                 return(0);
33         if (tp2->t_token == -1) {
34                 if (tp1->t_token == -1) {
35                         if (eqtoken(&machregs[tp1->t_att[0].ar].r_contents,
36                                     &machregs[tp2->t_att[0].ar].r_contents) &&
37                               machregs[tp1->t_att[0].ar].r_contents.t_token!=0)
38                                 return(0);
39                         if (tp1->t_att[0].ar!=1) { /* COCO reg; tmp kludge */
40                                 erasereg(tp2->t_att[0].ar);
41                                 machregs[tp2->t_att[0].ar].r_contents =
42                                   machregs[tp1->t_att[0].ar].r_contents ;
43                         } else
44                                 machregs[tp1->t_att[0].ar].r_contents =
45                                   machregs[tp2->t_att[0].ar].r_contents ;
46                 } else {
47                         if (eqtoken(&machregs[tp2->t_att[0].ar].r_contents,tp1))
48                                 return(0);
49                         erasereg(tp2->t_att[0].ar);
50                         machregs[tp2->t_att[0].ar].r_contents = *tp1;
51                 }
52                 for (rp=machregs;rp<machregs+NREGS;rp++) {
53                         if (rp->r_contents.t_token == 0)
54                                 continue;
55                         assert(rp->r_contents.t_token > 0);
56                         tdp = &tokens[rp->r_contents.t_token];
57                         for (i=0;i<TOKENSIZE;i++)
58                                 if (tdp->t_type[i] == EV_REG &&
59                                     clash(rp->r_contents.t_att[i].ar,tp2->t_att[0].ar)) {
60                                         erasereg((int)(rp-machregs));
61                                         break;
62                                 }
63                 }
64         } else if (tp1->t_token == -1) {
65                 if (eqtoken(tp2,&machregs[tp1->t_att[0].ar].r_contents))
66                         return(0);
67                 machregs[tp1->t_att[0].ar].r_contents = *tp2;
68         }
69         /*
70          * If we arrive here the move must really be executed
71          */
72         for (mp=moves;mp<moves+NMOVES;mp++) {
73                 if (!match(tp1,&machsets[mp->m_set1],mp->m_expr1))
74                         continue;
75                 if (match(tp2,&machsets[mp->m_set2],mp->m_expr2))
76                         break;
77                 /*
78                  * Correct move rule is found
79                  */
80         }
81         assert(mp<moves+NMOVES);
82         /*
83          * To get correct interpretation of things like %[1]
84          * in move code we stack tp2 and tp1. This little trick
85          * saves a lot of testing in other places.
86          */
87
88         if (mp->m_cindex!=0) {
89                 fakestack[stackheight] = *tp2;
90                 fakestack[stackheight+1] = *tp1;
91                 stackheight += 2;
92                 t = codegen(&coderules[mp->m_cindex],ply,toplevel,maxcost,0);
93                 if (t <= maxcost)
94                         t += costcalc(mp->m_cost);
95                 stackheight -= 2;
96         } else {
97                 t = 0;
98         }
99         return(t);
100 }