1 /*	$Id: order.c,v 1.3 2008/10/04 08:43:17 ragge Exp $	*/
2 /*
3  * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 
30 # include "pass2.h"
31 
32 #include <string.h>
33 
34 int canaddr(NODE *);
35 
36 /* is it legal to make an OREG or NAME entry which has an
37  * offset of off, (from a register of r), if the
38  * resulting thing had type t */
39 int
notoff(TWORD t,int r,CONSZ off,char * cp)40 notoff(TWORD t, int r, CONSZ off, char *cp)
41 {
42 	return(0);  /* YES */
43 }
44 
45 static int
inctree(NODE * p)46 inctree(NODE *p)
47 {
48 	if (p->n_op == MINUS && p->n_left->n_op == ASSIGN &&
49 	    p->n_left->n_right->n_op == PLUS &&
50 	    treecmp(p->n_left->n_left, p->n_left->n_right->n_left) &&
51 	    p->n_right->n_op == ICON && p->n_right->n_lval == 1 &&
52 	    p->n_left->n_right->n_right->n_op == ICON &&
53 	    p->n_left->n_right->n_right->n_lval == 1) {
54 		/* post-increment by 1; (r0)+ */
55 		if (isreg(p->n_left->n_left)) /* Ignore if index not in reg */
56 			return 1;
57 	}
58 	return 0;
59 }
60 
61 /*
62  * Turn a UMUL-referenced node into OREG.
63  * Be careful about register classes, this is a place where classes change.
64  */
65 void
offstar(NODE * p,int shape)66 offstar(NODE *p, int shape)
67 {
68 	if (x2debug)
69 		printf("offstar(%p)\n", p);
70 
71 	if (isreg(p))
72 		return; /* Is already OREG */
73 
74 	if (p->n_op == UMUL)
75 		p = p->n_left; /* double indexed umul */
76 
77 	if (inctree(p)) /* Do post-inc conversion */
78 		return;
79 
80 	if( p->n_op == PLUS || p->n_op == MINUS ){
81 		if (p->n_right->n_op == ICON) {
82 			if (isreg(p->n_left) == 0)
83 				(void)geninsn(p->n_left, INAREG);
84 			/* Converted in ormake() */
85 			return;
86 		}
87 	}
88 	(void)geninsn(p, INAREG);
89 }
90 
91 /*
92  * Do the actual conversion of offstar-found OREGs into real OREGs.
93  */
94 void
myormake(NODE * p)95 myormake(NODE *p)
96 {
97 	NODE *q = p->n_left;
98 
99 	if (x2debug) {
100 		printf("myormake(%p)\n", p);
101 		fwalk(p, e2print, 0);
102 	}
103 	if (inctree(q)) {
104 		if (q->n_left->n_left->n_op == TEMP)
105 			return;
106 		p->n_op = OREG;
107 		p->n_lval = 0; /* Add support for index offset */
108 		p->n_rval = R2PACK(regno(q->n_left->n_left), 0, 1);
109 		tfree(q);
110 		return;
111 	}
112 	if (q->n_op != OREG)
113 		return;
114 	p->n_op = OREG;
115 	p->n_lval = q->n_lval;
116 	p->n_rval = R2PACK(q->n_rval, 0, 0);
117 	nfree(q);
118 }
119 
120 /*
121  * Shape matches for UMUL.  Cooperates with offstar().
122  */
123 int
shumul(NODE * p,int shape)124 shumul(NODE *p, int shape)
125 {
126 
127 	if (x2debug)
128 		printf("shumul(%p)\n", p);
129 
130 	if (p->n_op == NAME && (shape & STARNM))
131 		return SRDIR;
132 	if (shape & SOREG)
133 		return SROREG;	/* Calls offstar */
134 	return SRNOPE;
135 }
136 
137 /*
138  * Rewrite operations on binary operators (like +, -, etc...).
139  * Called as a result of table lookup.
140  */
141 int
setbin(NODE * p)142 setbin(NODE *p)
143 {
144 
145 	if (x2debug)
146 		printf("setbin(%p)\n", p);
147 	return 0;
148 
149 }
150 
151 /* setup for assignment operator */
152 int
setasg(NODE * p,int cookie)153 setasg(NODE *p, int cookie)
154 {
155 	if (x2debug)
156 		printf("setasg(%p)\n", p);
157 	return(0);
158 }
159 
160 /* setup for unary operator */
161 int
setuni(NODE * p,int cookie)162 setuni(NODE *p, int cookie)
163 {
164 	return(0);
165 }
166 
167 /*
168  * Special handling of some instruction register allocation.
169  */
170 struct rspecial *
nspecial(struct optab * q)171 nspecial(struct optab *q)
172 {
173 	switch (q->op) {
174 	case MUL:
175 		if (q->visit == INAREG) {
176 			static struct rspecial s[] = { { NLEFT, R1 }, { 0 } };
177 			return s;
178 		} else if (q->visit == INBREG) {
179 			static struct rspecial s[] = { { NRES, R01 }, { 0 } };
180 			return s;
181 		}
182 		break;
183 
184 	case DIV:
185 		if (q->visit == INAREG && q->ltype == TUNSIGNED) {
186 			static struct rspecial s[] = {
187 			   { NLEFT, R0 }, { NRIGHT, R1 }, { NRES, R0 }, { 0 } };
188 			return s;
189 		} else if (q->visit == INAREG) {
190 			static struct rspecial s[] = {
191 			    { NRES, R0 }, { 0 } };
192 			return s;
193 		} else if (q->visit == INBREG) {
194 			static struct rspecial s[] = { { NRES, R01 }, { 0 } };
195 			return s;
196 		}
197 		break;
198 
199 	case MOD:
200 		if (q->visit == INAREG && q->ltype == TUNSIGNED) {
201 			static struct rspecial s[] = {
202 			   { NLEFT, R0 }, { NRIGHT, R1 }, { NRES, R0 }, { 0 } };
203 			return s;
204 		} else if (q->visit == INBREG) {
205 			static struct rspecial s[] = { { NRES, R01 }, { 0 } };
206 			return s;
207 		}
208 		break;
209 
210 	case SCONV:
211 		if (q->lshape == SAREG) {
212 			static struct rspecial s[] = {
213 			    { NLEFT, R1 }, { NRES, R01 }, { 0 } };
214 			return s;
215 		}
216 		break;
217 	}
218 	comperr("nspecial entry %d", q - table);
219 	return 0; /* XXX gcc */
220 }
221 
222 /*
223  * Set evaluation order of a binary node if it differs from default.
224  */
225 int
setorder(NODE * p)226 setorder(NODE *p)
227 {
228 	return 0; /* nothing differs on x86 */
229 }
230 
231 /*
232  * set registers in calling conventions live.
233  */
234 int *
livecall(NODE * p)235 livecall(NODE *p)
236 {
237 	static int r[] = { -1 };
238 
239 	return r;
240 }
241 
242 /*
243  * Signal whether the instruction is acceptable for this target.
244  */
245 int
acceptable(struct optab * op)246 acceptable(struct optab *op)
247 {
248 	return 1;
249 }
250