source: mainline/uspace/app/pcc/arch/powerpc/order.c@ 814717fa

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since 814717fa 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: 8.6 KB
Line 
1/* $Id: order.c,v 1.8 2009/01/07 11:44:03 gmcgarry 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#include <assert.h>
30
31# include "pass2.h"
32
33#include <string.h>
34
35int canaddr(NODE *);
36
37/*
38 * Check size of offset in OREG. Called by oregok() to see if an
39 * OREG can be generated.
40 *
41 * returns 0 if it can, 1 otherwise.
42 */
43int
44notoff(TWORD t, int r, CONSZ off, char *cp)
45{
46#if 0
47 if (off >= 32767 || off <= -32768)
48 printf("; notoff %lld TOO BIG!\n", off);
49#endif
50 if (cp && cp[0]) return 1;
51 return (off >= 32768 || off <= -32769);
52}
53
54/*
55 * Generate instructions for an OREG.
56 * Called by swmatch().
57 */
58void
59offstar(NODE *p, int shape)
60{
61 NODE *r;
62
63 if (x2debug)
64 printf("offstar(%p)\n", p);
65
66 if (isreg(p))
67 return; /* Is already OREG */
68
69 r = p->n_right;
70 if( p->n_op == PLUS || p->n_op == MINUS ){
71 if( r->n_op == ICON ){
72 if (isreg(p->n_left) == 0)
73 (void)geninsn(p->n_left, INAREG);
74 /* Converted in ormake() */
75 return;
76 }
77 }
78 (void)geninsn(p, INAREG);
79}
80
81/*
82 * Unable to convert to OREG (notoff() returned failure). Output
83 * suitable instructions to replace OREG.
84 */
85void
86myormake(NODE *q)
87{
88 NODE *p;
89
90 if (x2debug)
91 printf("myormake(%p)\n", q);
92
93 p = q->n_left;
94
95 /*
96 * This handles failed OREGs conversions, due to the offset
97 * being too large for an OREG.
98 */
99 if ((p->n_op == PLUS || p->n_op == MINUS) && p->n_right->n_op == ICON) {
100 if (isreg(p->n_left) == 0)
101 (void)geninsn(p->n_left, INAREG);
102 if (isreg(p->n_right) == 0)
103 (void)geninsn(p->n_right, INAREG);
104 (void)geninsn(p, INAREG);
105 } else if (p->n_op == REG) {
106 q->n_op = OREG;
107 q->n_lval = p->n_lval;
108 q->n_rval = p->n_rval;
109 tfree(p);
110 }
111}
112
113/*
114 * Shape matches for UMUL. Cooperates with offstar().
115 */
116int
117shumul(NODE *p, int shape)
118{
119
120 if (x2debug)
121 printf("shumul(%p)\n", p);
122
123 /* Turns currently anything into OREG on x86 */
124 if (shape & SOREG)
125 return SROREG;
126 return SRNOPE;
127}
128
129/*
130 * Rewrite operations on binary operators (like +, -, etc...).
131 * Called as a result of table lookup.
132 */
133int
134setbin(NODE *p)
135{
136
137 if (x2debug)
138 printf("setbin(%p)\n", p);
139 return 0;
140
141}
142
143/* setup for assignment operator */
144int
145setasg(NODE *p, int cookie)
146{
147 if (x2debug)
148 printf("setasg(%p)\n", p);
149 return(0);
150}
151
152/* setup for unary operator */
153int
154setuni(NODE *p, int cookie)
155{
156 return 0;
157}
158
159/*
160 * Special handling of some instruction register allocation.
161 */
162struct rspecial *
163nspecial(struct optab *q)
164{
165 if (x2debug)
166 printf("nspecial: op=%d, visit=0x%x: %s", q->op, q->visit, q->cstring);
167
168 switch (q->op) {
169
170 /* soft-float stuff */
171 case RS:
172 case LS:
173 if (q->lshape == SBREG) {
174 static struct rspecial s[] = {
175 { NLEFT, R3R4 },
176 { NRIGHT, R5 },
177 { NRES, R3R4 },
178 { 0 },
179 };
180 return s;
181 } else if (q->lshape == SAREG) {
182 static struct rspecial s[] = {
183 { NLEFT, R3 },
184 { NRIGHT, R4 },
185 { NRES, R3 },
186 { 0 },
187 };
188 return s;
189 }
190
191 cerror("nspecial LS/RS");
192 break;
193
194 case UMINUS:
195 case SCONV:
196 if (q->lshape == SBREG && q->rshape == SAREG) {
197 static struct rspecial s[] = {
198 { NLEFT, R3R4 },
199 { NRES, R3 },
200 { 0 }
201 };
202 return s;
203 } else if (q->lshape == SAREG && q->rshape == SBREG) {
204 static struct rspecial s[] = {
205 { NLEFT, R3 },
206 { NRES, R3R4 },
207 { 0 }
208 };
209 return s;
210 } else if (q->lshape == SAREG && q->rshape == SAREG) {
211 static struct rspecial s[] = {
212 { NLEFT, R3 },
213 { NRES, R3 },
214 { 0 }
215 };
216 return s;
217 } else if (q->lshape == SBREG && q->rshape == SBREG) {
218 static struct rspecial s[] = {
219 { NLEFT, R3R4 },
220 { NRES, R3R4 },
221 { 0 }
222 };
223 return s;
224 } else if (q->lshape == SCREG && q->rshape == SBREG) {
225 static struct rspecial s[] = {
226 { NLEFT, F1 },
227 { NEVER, F0 }, /* stomped on */
228 { NRES, R3R4 },
229 { 0 }
230 };
231 return s;
232 } else if (q->lshape == SBREG && q->rshape == SCREG) {
233 static struct rspecial s[] = {
234 { NLEFT, R3R4 },
235 { NEVER, F0 }, /* stomped on */
236 { NRES, F1 },
237 { 0 }
238 };
239 return s;
240 } else {
241 static struct rspecial s[] = {
242 { NOLEFT, R0 },
243 { 0 } };
244 return s;
245 }
246
247 break;
248
249 case OPLOG:
250 if (q->lshape == SBREG) {
251 static struct rspecial s[] = {
252 { NLEFT, R3R4 },
253 { NRIGHT, R5R6 },
254 { NRES, R3 },
255 { 0 }
256 };
257 return s;
258 } else if (q->lshape == SAREG) {
259 static struct rspecial s[] = {
260 { NLEFT, R3 },
261 { NRIGHT, R4 },
262 { NRES, R3 },
263 { 0 }
264 };
265 return s;
266 }
267
268 cerror("nspecial oplog");
269 break;
270
271 case PLUS:
272 case MINUS:
273 case MUL:
274 case DIV:
275 case MOD:
276 if (q->lshape == SBREG &&
277 (q->ltype & (TDOUBLE|TLDOUBLE|TLONGLONG|TULONGLONG))) {
278 static struct rspecial s[] = {
279 { NLEFT, R3R4 },
280 { NRIGHT, R5R6 },
281 { NRES, R3R4 },
282 { 0 }
283 };
284 return s;
285 } else if (q->lshape == SAREG && q->ltype & TFLOAT) {
286 static struct rspecial s[] = {
287 { NLEFT, R3 },
288 { NRIGHT, R4 },
289 { NRES, R3 },
290 { 0 }
291 };
292 return s;
293 } else if (q->lshape == SAREG) {
294 static struct rspecial s[] = {
295 { NOLEFT, R0 },
296 { 0 } };
297 return s;
298 }
299
300 cerror("nspecial mul");
301 break;
302
303 case STASG:
304 {
305 static struct rspecial s[] = {
306 { NEVER, R3 },
307 { NRIGHT, R4 },
308 { NEVER, R5 },
309 { 0 } };
310 return s;
311 }
312 break;
313
314 case OPLTYPE:
315 {
316 if (q->visit & SAREG) {
317 static struct rspecial s[] = {
318 { NEVER, R0 },
319 { 0 } };
320 return s;
321 }
322 }
323 break;
324
325 case ASSIGN:
326 if (q->lshape & SNAME) {
327 static struct rspecial s[] = {
328 { NEVER, R0 },
329 { 0 } };
330 return s;
331 } else if (q->rshape & SNAME) {
332 static struct rspecial s[] = {
333 { NOLEFT, R0 },
334 { 0 } };
335 return s;
336 } else if (q->lshape & SOREG) {
337 static struct rspecial s[] = {
338 { NOLEFT, R0 },
339 { 0 } };
340 return s;
341 } else if (q->rshape & SOREG) {
342 static struct rspecial s[] = {
343 { NORIGHT, R0 },
344 { 0 } };
345 return s;
346 }
347 /* fallthough */
348
349 case UMUL:
350 case AND:
351 case OR:
352 case ER:
353 {
354 static struct rspecial s[] = {
355 { NOLEFT, R0 },
356 { 0 } };
357 return s;
358 }
359
360 default:
361 break;
362 }
363
364 comperr("nspecial entry %d: %s", q - table, q->cstring);
365 return 0; /* XXX gcc */
366}
367
368/*
369 * Set evaluation order of a binary node if it differs from default.
370 */
371int
372setorder(NODE *p)
373{
374 return 0; /* nothing differs on x86 */
375}
376
377/*
378 * Set registers "live" at function calls (like arguments in registers).
379 * This is for liveness analysis of registers.
380 */
381int *
382livecall(NODE *p)
383{
384 static int r[] = { R10, R9, R8, R7, R6, R5, R4, R3, R30, R31, -1 };
385 int num = 1;
386
387 if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
388 return &r[8-0];
389
390 for (p = p->n_right; p->n_op == CM; p = p->n_left)
391 num += szty(p->n_right->n_type);
392 num += szty(p->n_right->n_type);
393
394 num = (num > 8 ? 8 : num);
395
396 return &r[8 - num];
397}
398
399/*
400 * Signal whether the instruction is acceptable for this target.
401 */
402int
403acceptable(struct optab *op)
404{
405 if ((op->visit & FEATURE_PIC) != 0)
406 return (kflag != 0);
407 return features(op->visit & 0xffff0000);
408}
Note: See TracBrowser for help on using the repository browser.