1 /* $Id: order.c,v 1.8 2009/01/07 11:44:03 gmcgarry Exp $ */
3 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
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.
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.
44 notoff(TWORD t
, int r
, CONSZ off
, char *cp
)
47 if (off
>= 32767 || off
<= -32768)
48 printf("; notoff %lld TOO BIG!\n", off
);
50 if (cp
&& cp
[0]) return 1;
51 return (off
>= 32768 || off
<= -32769);
55 * Generate instructions for an OREG.
56 * Called by swmatch().
59 offstar(NODE
*p
, int shape
)
64 printf("offstar(%p)\n", p
);
67 return; /* Is already OREG */
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() */
78 (void)geninsn(p
, INAREG
);
82 * Unable to convert to OREG (notoff() returned failure). Output
83 * suitable instructions to replace OREG.
91 printf("myormake(%p)\n", q
);
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
) {
107 q
->n_lval
= p
->n_lval
;
108 q
->n_rval
= p
->n_rval
;
114 * Shape matches for UMUL. Cooperates with offstar().
117 shumul(NODE
*p
, int shape
)
121 printf("shumul(%p)\n", p
);
123 /* Turns currently anything into OREG on x86 */
130 * Rewrite operations on binary operators (like +, -, etc...).
131 * Called as a result of table lookup.
138 printf("setbin(%p)\n", p
);
143 /* setup for assignment operator */
145 setasg(NODE
*p
, int cookie
)
148 printf("setasg(%p)\n", p
);
152 /* setup for unary operator */
154 setuni(NODE
*p
, int cookie
)
160 * Special handling of some instruction register allocation.
163 nspecial(struct optab
*q
)
166 printf("nspecial: op=%d, visit=0x%x: %s", q
->op
, q
->visit
, q
->cstring
);
170 /* soft-float stuff */
173 if (q
->lshape
== SBREG
) {
174 static struct rspecial s
[] = {
181 } else if (q
->lshape
== SAREG
) {
182 static struct rspecial s
[] = {
191 cerror("nspecial LS/RS");
196 if (q
->lshape
== SBREG
&& q
->rshape
== SAREG
) {
197 static struct rspecial s
[] = {
203 } else if (q
->lshape
== SAREG
&& q
->rshape
== SBREG
) {
204 static struct rspecial s
[] = {
210 } else if (q
->lshape
== SAREG
&& q
->rshape
== SAREG
) {
211 static struct rspecial s
[] = {
217 } else if (q
->lshape
== SBREG
&& q
->rshape
== SBREG
) {
218 static struct rspecial s
[] = {
224 } else if (q
->lshape
== SCREG
&& q
->rshape
== SBREG
) {
225 static struct rspecial s
[] = {
227 { NEVER
, F0
}, /* stomped on */
232 } else if (q
->lshape
== SBREG
&& q
->rshape
== SCREG
) {
233 static struct rspecial s
[] = {
235 { NEVER
, F0
}, /* stomped on */
241 static struct rspecial s
[] = {
250 if (q
->lshape
== SBREG
) {
251 static struct rspecial s
[] = {
258 } else if (q
->lshape
== SAREG
) {
259 static struct rspecial s
[] = {
268 cerror("nspecial oplog");
276 if (q
->lshape
== SBREG
&&
277 (q
->ltype
& (TDOUBLE
|TLDOUBLE
|TLONGLONG
|TULONGLONG
))) {
278 static struct rspecial s
[] = {
285 } else if (q
->lshape
== SAREG
&& q
->ltype
& TFLOAT
) {
286 static struct rspecial s
[] = {
293 } else if (q
->lshape
== SAREG
) {
294 static struct rspecial s
[] = {
300 cerror("nspecial mul");
305 static struct rspecial s
[] = {
316 if (q
->visit
& SAREG
) {
317 static struct rspecial s
[] = {
326 if (q
->lshape
& SNAME
) {
327 static struct rspecial s
[] = {
331 } else if (q
->rshape
& SNAME
) {
332 static struct rspecial s
[] = {
336 } else if (q
->lshape
& SOREG
) {
337 static struct rspecial s
[] = {
341 } else if (q
->rshape
& SOREG
) {
342 static struct rspecial s
[] = {
354 static struct rspecial s
[] = {
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.
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.
384 static int r
[] = { R10
, R9
, R8
, R7
, R6
, R5
, R4
, R3
, R30
, R31
, -1 };
387 if (p
->n_op
!= CALL
&& p
->n_op
!= FORTCALL
&& p
->n_op
!= STCALL
)
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
);
400 * Signal whether the instruction is acceptable for this target.
403 acceptable(struct optab
*op
)
405 if ((op
->visit
& FEATURE_PIC
) != 0)
407 return features(op
->visit
& 0xffff0000);