Pristine Ack-5.5
[Ack-5.5.git] / mach / proto / ncg / nextem.c
1 #ifndef NORCSID
2 static char rcsid[] = "$Id: nextem.c,v 0.9 1994/06/24 13:27:43 ceriel Exp $";
3 #endif
4
5 #include <em_spec.h>
6 #include <em_flag.h>
7 #include "assert.h"
8 #include "param.h"
9 #include "tables.h"
10 #include "types.h"
11 #include <cgg_cg.h>
12 #include "data.h"
13 #include "result.h"
14 #include "extern.h"
15
16 /*
17  * (c) copyright 1987 by the Vrije Universiteit, Amsterdam, The Netherlands.
18  * See the copyright notice in the ACK home directory, in the file "Copyright".
19  *
20  * Author: Hans van Staveren
21  */
22
23 #ifndef NDEBUG
24 #include <stdio.h>
25 extern char em_mnem[][4];
26 #endif
27
28 byte *trypat(bp,len) register byte *bp; {
29         register patlen,i;
30         result_t result;
31
32         getint(patlen,bp);
33         if (len == 3) {
34                 if (patlen < 3)
35                         return(0);
36         } else {
37                 if (patlen != len)
38                         return(0);
39         }
40         for(i=0;i<patlen;i++)
41                 if (emp[i].em_instr != (*bp++&BMASK))
42                         return(0);
43         for (i=0;i<patlen;i++)
44                 if (emp[i].em_optyp==OPNO)
45                         dollar[i].e_typ=EV_UNDEF;
46                 else if ((dollar[i].e_typ=argtyp(emp[i].em_instr))==EV_INT)
47                         dollar[i].e_v.e_con=emp[i].em_u.em_ioper;
48                 else {
49                         dollar[i].e_v.e_addr.ea_str=emp[i].em_soper;
50                         dollar[i].e_v.e_addr.ea_off=0;
51                 }
52         getint(i,bp);
53         if (i!=0) {
54                 struct emline *svp = saveemp;
55
56                 saveemp = emp;
57                 compute(&enodes[i], &result);
58                 if (result.e_typ != EV_INT || result.e_v.e_con == 0) {
59                         saveemp = svp;
60                         return(0);
61                 }
62         }
63 #ifndef NDEBUG
64         if (Debug) {
65                 fprintf(stderr,"Matched:");
66                 for (i=0;i<patlen;i++) {
67 #ifdef USE_TES
68                         if (emp[i].em_instr == op_lab)
69                                 fprintf(stderr," lab");
70                         else
71 #endif
72                                 fprintf(stderr," %3.3s",em_mnem[emp[i].em_instr-sp_fmnem]);
73                         if (emp[i].em_soper)
74                                 fprintf(stderr," %s",emp[i].em_soper);
75                 }
76                 fprintf(stderr,"\n");
77         }
78 #endif
79         saveemp = emp;
80         emp += patlen;
81         return(bp);
82 }
83
84 extern char em_flag[];
85
86 argtyp(mn) {
87
88         switch(em_flag[mn-sp_fmnem]&EM_PAR) {
89         case PAR_W:
90         case PAR_S:
91         case PAR_Z:
92         case PAR_O:
93         case PAR_N:
94         case PAR_L:
95         case PAR_F:
96         case PAR_R:
97         case PAR_C:
98                 return(EV_INT);
99         default:
100                 return(EV_ADDR);
101         }
102 }
103
104 byte *nextem(toplevel) {
105         register i;
106         short hash[3];
107         register byte *bp;
108         byte *cp;
109         int index;
110         register struct emline *ep;
111
112         if (toplevel) {
113                 if (nemlines && emp>emlines) {
114                         nemlines -= emp-emlines;
115                         for (i=0,ep=emlines;i<nemlines;i++)
116                                 *ep++ = *emp++;
117                         emp=emlines;
118                 }
119                 fillemlines();
120         }
121         hash[0] = emp[0].em_instr;
122         hash[1] = (hash[0]<<4) ^ emp[1].em_instr;
123         hash[2] = (hash[1]<<4) ^ emp[2].em_instr;
124         for (i=2;i>=0;i--) {
125                 index = pathash[hash[i]&BMASK];
126                 while (index != 0) {
127                         bp = &pattern[index];
128                         if ( bp[PO_HASH] == (hash[i]>>8))
129                                 if ((cp=trypat(&bp[PO_MATCH],i+1)) != 0)
130                                         return(cp);
131                         index = (bp[PO_NEXT]&BMASK) | (bp[PO_NEXT+1]<<8);
132                 }
133         }
134         return(0);
135 }