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