* add p cc
[mascara-docs.git] / compilers / pcc / pcc-1.0.0 / arch / powerpc / order.c
blob61782cdf6ffa5ad2ab28247b885d8fad8e92f812
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.
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
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.
29 #include <assert.h>
31 # include "pass2.h"
33 #include <string.h>
35 int canaddr(NODE *);
38 * Check size of offset in OREG. Called by oregok() to see if an
39 * OREG can be generated.
41 * returns 0 if it can, 1 otherwise.
43 int
44 notoff(TWORD t, int r, CONSZ off, char *cp)
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);
55 * Generate instructions for an OREG.
56 * Called by swmatch().
58 void
59 offstar(NODE *p, int shape)
61 NODE *r;
63 if (x2debug)
64 printf("offstar(%p)\n", p);
66 if (isreg(p))
67 return; /* Is already OREG */
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;
78 (void)geninsn(p, INAREG);
82 * Unable to convert to OREG (notoff() returned failure). Output
83 * suitable instructions to replace OREG.
85 void
86 myormake(NODE *q)
88 NODE *p;
90 if (x2debug)
91 printf("myormake(%p)\n", q);
93 p = q->n_left;
96 * This handles failed OREGs conversions, due to the offset
97 * being too large for an OREG.
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);
114 * Shape matches for UMUL. Cooperates with offstar().
117 shumul(NODE *p, int shape)
120 if (x2debug)
121 printf("shumul(%p)\n", p);
123 /* Turns currently anything into OREG on x86 */
124 if (shape & SOREG)
125 return SROREG;
126 return SRNOPE;
130 * Rewrite operations on binary operators (like +, -, etc...).
131 * Called as a result of table lookup.
134 setbin(NODE *p)
137 if (x2debug)
138 printf("setbin(%p)\n", p);
139 return 0;
143 /* setup for assignment operator */
145 setasg(NODE *p, int cookie)
147 if (x2debug)
148 printf("setasg(%p)\n", p);
149 return(0);
152 /* setup for unary operator */
154 setuni(NODE *p, int cookie)
156 return 0;
160 * Special handling of some instruction register allocation.
162 struct rspecial *
163 nspecial(struct optab *q)
165 if (x2debug)
166 printf("nspecial: op=%d, visit=0x%x: %s", q->op, q->visit, q->cstring);
168 switch (q->op) {
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 },
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 },
188 return s;
191 cerror("nspecial LS/RS");
192 break;
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 }
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 }
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 }
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 }
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 }
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 }
239 return s;
240 } else {
241 static struct rspecial s[] = {
242 { NOLEFT, R0 },
243 { 0 } };
244 return s;
247 break;
249 case OPLOG:
250 if (q->lshape == SBREG) {
251 static struct rspecial s[] = {
252 { NLEFT, R3R4 },
253 { NRIGHT, R5R6 },
254 { NRES, R3 },
255 { 0 }
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 }
265 return s;
268 cerror("nspecial oplog");
269 break;
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 }
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 }
292 return s;
293 } else if (q->lshape == SAREG) {
294 static struct rspecial s[] = {
295 { NOLEFT, R0 },
296 { 0 } };
297 return s;
300 cerror("nspecial mul");
301 break;
303 case STASG:
305 static struct rspecial s[] = {
306 { NEVER, R3 },
307 { NRIGHT, R4 },
308 { NEVER, R5 },
309 { 0 } };
310 return s;
312 break;
314 case OPLTYPE:
316 if (q->visit & SAREG) {
317 static struct rspecial s[] = {
318 { NEVER, R0 },
319 { 0 } };
320 return s;
323 break;
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;
347 /* fallthough */
349 case UMUL:
350 case AND:
351 case OR:
352 case ER:
354 static struct rspecial s[] = {
355 { NOLEFT, R0 },
356 { 0 } };
357 return s;
360 default:
361 break;
364 comperr("nspecial entry %d: %s", q - table, q->cstring);
365 return 0; /* XXX gcc */
369 * Set evaluation order of a binary node if it differs from default.
372 setorder(NODE *p)
374 return 0; /* nothing differs on x86 */
378 * Set registers "live" at function calls (like arguments in registers).
379 * This is for liveness analysis of registers.
381 int *
382 livecall(NODE *p)
384 static int r[] = { R10, R9, R8, R7, R6, R5, R4, R3, R30, R31, -1 };
385 int num = 1;
387 if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL)
388 return &r[8-0];
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);
394 num = (num > 8 ? 8 : num);
396 return &r[8 - num];
400 * Signal whether the instruction is acceptable for this target.
403 acceptable(struct optab *op)
405 if ((op->visit & FEATURE_PIC) != 0)
406 return (kflag != 0);
407 return features(op->visit & 0xffff0000);