1 /* $Id: order.c,v 1.9 2008/09/27 07:35:22 ragge Exp $ */
3 * Copyright (c) 2007 Gregory McGarry (g.mcgarry@ieee.org).
4 * Copyright (c) 2003 Anders Magnusson (ragge@ludd.luth.se).
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
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
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.
31 * Machine-dependent code-generation strategy (pass 2).
40 * Check size of offset in OREG. Called by oregok() to see if an
41 * OREG can be generated.
44 notoff(TWORD ty
, int r
, CONSZ off
, char *cp
)
46 if (cp
&& cp
[0]) return 1;
47 if (DEUNSIGN(ty
) == INT
|| ty
== UCHAR
)
48 return !(off
< 4096 && off
> -4096);
50 return !(off
< 256 && off
> -256);
54 * Generate instructions for an OREG. Why is this routine MD?
55 * Called by swmatch().
58 offstar(NODE
*p
, int shape
)
63 return; /* Is already OREG */
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() */
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
);
83 (void)geninsn(p
, INAREG
);
87 * Unable to convert to OREG (notoff() returned failure). Output
88 * suitable instructions to replace OREG.
96 printf("myormake(%p)\n", q
);
101 * This handles failed OREGs conversions, due to the offset
102 * being too large for an OREG.
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
) {
112 q
->n_lval
= p
->n_lval
;
113 q
->n_rval
= p
->n_rval
;
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
) {
120 q
->n_rval
= R2PACK(p
->n_left
->n_rval
, r
->n_left
->n_rval
,
127 * Check to if the UMUL node can be converted into an OREG.
130 shumul(NODE
*p
, int shape
)
132 /* Turns currently anything into OREG */
139 * Rewrite operations on binary operators (like +, -, etc...).
140 * Called as a result of a failed table lookup.
142 * Return nonzero to retry table search on new tree, or zero to fail.
152 * Rewrite assignment operations.
153 * Called as a result of a failed table lookup.
155 * Return nonzero to retry table search on new tree, or zero to fail.
158 setasg(NODE
*p
, int cookie
)
164 * Rewrite UMUL operation.
165 * Called as a result of a failed table lookup.
167 * Return nonzero to retry table search on new tree, or zero to fail.
170 setuni(NODE
*p
, int cookie
)
176 * Special handling of some instruction register allocation.
178 * Called as a result of specifying NSPECIAL in the table.
181 nspecial(struct optab
*q
)
186 #if !defined(ARM_HAS_FPA) && !defined(ARM_HAS_VFP)
189 if (q
->lshape
== SBREG
&& q
->rshape
== SAREG
) {
190 static struct rspecial s
[] = {
196 } else if (q
->lshape
== SAREG
&& q
->rshape
== SBREG
) {
197 static struct rspecial s
[] = {
203 } else if (q
->lshape
== SAREG
&& q
->rshape
== SAREG
) {
204 static struct rspecial s
[] = {
210 } else if (q
->lshape
== SBREG
&& q
->rshape
== SBREG
) {
211 static struct rspecial s
[] = {
220 if (q
->lshape
== SBREG
) {
221 static struct rspecial s
[] = {
228 } else if (q
->lshape
== SAREG
) {
229 static struct rspecial s
[] = {
243 if (q
->lshape
== SBREG
) {
244 static struct rspecial s
[] = {
251 } else if (q
->lshape
== SAREG
) {
252 static struct rspecial s
[] = {
262 if (q
->lshape
== SBREG
) {
263 static struct rspecial s
[] = {
270 } else if (q
->lshape
== SAREG
) {
271 static struct rspecial s
[] = {
281 static struct rspecial s
[] = {
295 comperr("nspecial entry %d [0x%x]: %s", q
- table
, q
->op
, q
->cstring
);
297 return 0; /* XXX gcc */
301 * Set evaluation order of a binary node ('+','-', '*', '/', etc) if it
302 * differs from default.
311 * Set registers "live" at function calls (like arguments in registers).
312 * This is for liveness analysis of registers.
317 static int r
[] = { R3
, R2
, R1
, R0
, -1 };
320 if (p
->n_op
!= CALL
&& p
->n_op
!= FORTCALL
&& p
->n_op
!= STCALL
)
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
);
327 num
= (num
> 4 ? 4 : num
);
333 * Signal whether the instruction is acceptable for this target.
336 acceptable(struct optab
*op
)
338 return features(op
->visit
& 0xffff0000);