source: mainline/uspace/app/pcc/arch/arm/order.c@ a44424f

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since a44424f was a7de7182, checked in by Jiří Zárevúcky <zarevucky.jiri@…>, 14 years ago

Added pcc source tree (contents of pcc-1.0.0.tgz)

  • Property mode set to 100644
File size: 7.5 KB
Line 
1/* $Id: order.c,v 1.9 2008/09/27 07:35:22 ragge Exp $ */
2/*
3 * Copyright (c) 2007 Gregory McGarry (g.mcgarry@ieee.org).
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 * Machine-dependent code-generation strategy (pass 2).
32 */
33
34#include <assert.h>
35#include <string.h>
36
37#include "pass2.h"
38
39/*
40 * Check size of offset in OREG. Called by oregok() to see if an
41 * OREG can be generated.
42 */
43int
44notoff(TWORD ty, int r, CONSZ off, char *cp)
45{
46 if (cp && cp[0]) return 1;
47 if (DEUNSIGN(ty) == INT || ty == UCHAR)
48 return !(off < 4096 && off > -4096);
49 else
50 return !(off < 256 && off > -256);
51}
52
53/*
54 * Generate instructions for an OREG. Why is this routine MD?
55 * Called by swmatch().
56 */
57void
58offstar(NODE *p, int shape)
59{
60 NODE *r;
61
62 if (isreg(p))
63 return; /* Is already OREG */
64
65 r = p->n_right;
66 if( p->n_op == PLUS || p->n_op == MINUS ){
67 if( r->n_op == ICON ){
68 if (isreg(p->n_left) == 0)
69 (void)geninsn(p->n_left, INAREG);
70 /* Converted in ormake() */
71 return;
72 }
73 /* usually for arraying indexing: */
74 if (r->n_op == LS && r->n_right->n_op == ICON &&
75 r->n_right->n_lval == 2 && p->n_op == PLUS) {
76 if (isreg(p->n_left) == 0)
77 (void)geninsn(p->n_left, INAREG);
78 if (isreg(r->n_left) == 0)
79 (void)geninsn(r->n_left, INAREG);
80 return;
81 }
82 }
83 (void)geninsn(p, INAREG);
84}
85
86/*
87 * Unable to convert to OREG (notoff() returned failure). Output
88 * suitable instructions to replace OREG.
89 */
90void
91myormake(NODE *q)
92{
93 NODE *p, *r;
94
95 if (x2debug)
96 printf("myormake(%p)\n", q);
97
98 p = q->n_left;
99
100 /*
101 * This handles failed OREGs conversions, due to the offset
102 * being too large for an OREG.
103 */
104 if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_right->n_op == ICON) {
105 if (isreg(p->n_left) == 0)
106 (void)geninsn(p->n_left, INAREG);
107 if (isreg(p->n_right) == 0)
108 (void)geninsn(p->n_right, INAREG);
109 (void)geninsn(p, INAREG);
110 } else if (p->n_op == REG) {
111 q->n_op = OREG;
112 q->n_lval = p->n_lval;
113 q->n_rval = p->n_rval;
114 tfree(p);
115 } else if (p->n_op == PLUS && (r = p->n_right)->n_op == LS &&
116 r->n_right->n_op == ICON && r->n_right->n_lval == 2 &&
117 p->n_left->n_op == REG && r->n_left->n_op == REG) {
118 q->n_op = OREG;
119 q->n_lval = 0;
120 q->n_rval = R2PACK(p->n_left->n_rval, r->n_left->n_rval,
121 r->n_right->n_lval);
122 tfree(p);
123 }
124}
125
126/*
127 * Check to if the UMUL node can be converted into an OREG.
128 */
129int
130shumul(NODE *p, int shape)
131{
132 /* Turns currently anything into OREG */
133 if (shape & SOREG)
134 return SROREG;
135 return SRNOPE;
136}
137
138/*
139 * Rewrite operations on binary operators (like +, -, etc...).
140 * Called as a result of a failed table lookup.
141 *
142 * Return nonzero to retry table search on new tree, or zero to fail.
143 */
144int
145setbin(NODE *p)
146{
147 return 0;
148
149}
150
151/*
152 * Rewrite assignment operations.
153 * Called as a result of a failed table lookup.
154 *
155 * Return nonzero to retry table search on new tree, or zero to fail.
156 */
157int
158setasg(NODE *p, int cookie)
159{
160 return 0;
161}
162
163/*
164 * Rewrite UMUL operation.
165 * Called as a result of a failed table lookup.
166 *
167 * Return nonzero to retry table search on new tree, or zero to fail.
168 */
169int
170setuni(NODE *p, int cookie)
171{
172 return 0;
173}
174
175/*
176 * Special handling of some instruction register allocation.
177 *
178 * Called as a result of specifying NSPECIAL in the table.
179 */
180struct rspecial *
181nspecial(struct optab *q)
182{
183
184 switch (q->op) {
185
186#if !defined(ARM_HAS_FPA) && !defined(ARM_HAS_VFP)
187 case UMINUS:
188 case SCONV:
189 if (q->lshape == SBREG && q->rshape == SAREG) {
190 static struct rspecial s[] = {
191 { NLEFT, R0R1 },
192 { NRES, R0 },
193 { 0 }
194 };
195 return s;
196 } else if (q->lshape == SAREG && q->rshape == SBREG) {
197 static struct rspecial s[] = {
198 { NLEFT, R0 },
199 { NRES, R0R1 },
200 { 0 }
201 };
202 return s;
203 } else if (q->lshape == SAREG && q->rshape == SAREG) {
204 static struct rspecial s[] = {
205 { NLEFT, R0 },
206 { NRES, R0 },
207 { 0 }
208 };
209 return s;
210 } else if (q->lshape == SBREG && q->rshape == SBREG) {
211 static struct rspecial s[] = {
212 { NLEFT, R0R1 },
213 { NRES, R0R1 },
214 { 0 }
215 };
216 return s;
217 }
218
219 case OPLOG:
220 if (q->lshape == SBREG) {
221 static struct rspecial s[] = {
222 { NLEFT, R0R1 },
223 { NRIGHT, R2R3 },
224 { NRES, R0 },
225 { 0 }
226 };
227 return s;
228 } else if (q->lshape == SAREG) {
229 static struct rspecial s[] = {
230 { NLEFT, R0 },
231 { NRIGHT, R1 },
232 { NRES, R0 },
233 { 0 }
234 };
235 return s;
236 }
237 case PLUS:
238 case MINUS:
239 case MUL:
240#endif
241 case MOD:
242 case DIV:
243 if (q->lshape == SBREG) {
244 static struct rspecial s[] = {
245 { NLEFT, R0R1 },
246 { NRIGHT, R2R3 },
247 { NRES, R0R1 },
248 { 0 }
249 };
250 return s;
251 } else if (q->lshape == SAREG) {
252 static struct rspecial s[] = {
253 { NLEFT, R0 },
254 { NRIGHT, R1 },
255 { NRES, R0 },
256 { 0 }
257 };
258 return s;
259 }
260 case LS:
261 case RS:
262 if (q->lshape == SBREG) {
263 static struct rspecial s[] = {
264 { NLEFT, R0R1 },
265 { NRIGHT, R2 },
266 { NRES, R0R1 },
267 { 0 }
268 };
269 return s;
270 } else if (q->lshape == SAREG) {
271 static struct rspecial s[] = {
272 { NLEFT, R0 },
273 { NRIGHT, R1 },
274 { NRES, R0 },
275 { 0 }
276 };
277 return s;
278 }
279 case STASG:
280 {
281 static struct rspecial s[] = {
282 { NEVER, R0 },
283 { NRIGHT, R1 },
284 { NEVER, R2 },
285 { 0 } };
286 return s;
287 }
288 break;
289
290 default:
291 break;
292 }
293
294#ifdef PCC_DEBUG
295 comperr("nspecial entry %d [0x%x]: %s", q - table, q->op, q->cstring);
296#endif
297 return 0; /* XXX gcc */
298}
299
300/*
301 * Set evaluation order of a binary node ('+','-', '*', '/', etc) if it
302 * differs from default.
303 */
304int
305setorder(NODE *p)
306{
307 return 0;
308}
309
310/*
311 * Set registers "live" at function calls (like arguments in registers).
312 * This is for liveness analysis of registers.
313 */
314int *
315livecall(NODE *p)
316{
317 static int r[] = { R3, R2, R1, R0, -1 };
318 int num = 1;
319
320 if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
321 return &r[4-0];
322
323 for (p = p->n_right; p->n_op == CM; p = p->n_left)
324 num += szty(p->n_right->n_type);
325 num += szty(p->n_right->n_type);
326
327 num = (num > 4 ? 4 : num);
328
329 return &r[4 - num];
330}
331
332/*
333 * Signal whether the instruction is acceptable for this target.
334 */
335int
336acceptable(struct optab *op)
337{
338 return features(op->visit & 0xffff0000);
339}
Note: See TracBrowser for help on using the repository browser.