1 /* Id: order.c,v 1.3 2008/10/04 08:43:17 ragge Exp */ 2 /* $NetBSD: order.c,v 1.1.1.2 2010/06/03 18:57:25 plunky Exp $ */ 3 /* 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 # include "pass2.h" 32 33 #include <string.h> 34 35 int canaddr(NODE *); 36 37 /* is it legal to make an OREG or NAME entry which has an 38 * offset of off, (from a register of r), if the 39 * resulting thing had type t */ 40 int 41 notoff(TWORD t, int r, CONSZ off, char *cp) 42 { 43 return(0); /* YES */ 44 } 45 46 static int 47 inctree(NODE *p) 48 { 49 if (p->n_op == MINUS && p->n_left->n_op == ASSIGN && 50 p->n_left->n_right->n_op == PLUS && 51 treecmp(p->n_left->n_left, p->n_left->n_right->n_left) && 52 p->n_right->n_op == ICON && p->n_right->n_lval == 1 && 53 p->n_left->n_right->n_right->n_op == ICON && 54 p->n_left->n_right->n_right->n_lval == 1) { 55 /* post-increment by 1; (r0)+ */ 56 if (isreg(p->n_left->n_left)) /* Ignore if index not in reg */ 57 return 1; 58 } 59 return 0; 60 } 61 62 /* 63 * Turn a UMUL-referenced node into OREG. 64 * Be careful about register classes, this is a place where classes change. 65 */ 66 void 67 offstar(NODE *p, int shape) 68 { 69 if (x2debug) 70 printf("offstar(%p)\n", p); 71 72 if (isreg(p)) 73 return; /* Is already OREG */ 74 75 if (p->n_op == UMUL) 76 p = p->n_left; /* double indexed umul */ 77 78 if (inctree(p)) /* Do post-inc conversion */ 79 return; 80 81 if( p->n_op == PLUS || p->n_op == MINUS ){ 82 if (p->n_right->n_op == ICON) { 83 if (isreg(p->n_left) == 0) 84 (void)geninsn(p->n_left, INAREG); 85 /* Converted in ormake() */ 86 return; 87 } 88 } 89 (void)geninsn(p, INAREG); 90 } 91 92 /* 93 * Do the actual conversion of offstar-found OREGs into real OREGs. 94 */ 95 void 96 myormake(NODE *p) 97 { 98 NODE *q = p->n_left; 99 100 if (x2debug) { 101 printf("myormake(%p)\n", p); 102 fwalk(p, e2print, 0); 103 } 104 if (inctree(q)) { 105 if (q->n_left->n_left->n_op == TEMP) 106 return; 107 p->n_op = OREG; 108 p->n_lval = 0; /* Add support for index offset */ 109 p->n_rval = R2PACK(regno(q->n_left->n_left), 0, 1); 110 tfree(q); 111 return; 112 } 113 if (q->n_op != OREG) 114 return; 115 p->n_op = OREG; 116 p->n_lval = q->n_lval; 117 p->n_rval = R2PACK(q->n_rval, 0, 0); 118 nfree(q); 119 } 120 121 /* 122 * Shape matches for UMUL. Cooperates with offstar(). 123 */ 124 int 125 shumul(NODE *p, int shape) 126 { 127 128 if (x2debug) 129 printf("shumul(%p)\n", p); 130 131 if (p->n_op == NAME && (shape & STARNM)) 132 return SRDIR; 133 if (shape & SOREG) 134 return SROREG; /* Calls offstar */ 135 return SRNOPE; 136 } 137 138 /* 139 * Rewrite operations on binary operators (like +, -, etc...). 140 * Called as a result of table lookup. 141 */ 142 int 143 setbin(NODE *p) 144 { 145 146 if (x2debug) 147 printf("setbin(%p)\n", p); 148 return 0; 149 150 } 151 152 /* setup for assignment operator */ 153 int 154 setasg(NODE *p, int cookie) 155 { 156 if (x2debug) 157 printf("setasg(%p)\n", p); 158 return(0); 159 } 160 161 /* setup for unary operator */ 162 int 163 setuni(NODE *p, int cookie) 164 { 165 return(0); 166 } 167 168 /* 169 * Special handling of some instruction register allocation. 170 */ 171 struct rspecial * 172 nspecial(struct optab *q) 173 { 174 switch (q->op) { 175 case MUL: 176 if (q->visit == INAREG) { 177 static struct rspecial s[] = { { NLEFT, R1 }, { 0 } }; 178 return s; 179 } else if (q->visit == INBREG) { 180 static struct rspecial s[] = { { NRES, R01 }, { 0 } }; 181 return s; 182 } 183 break; 184 185 case DIV: 186 if (q->visit == INAREG && q->ltype == TUNSIGNED) { 187 static struct rspecial s[] = { 188 { NLEFT, R0 }, { NRIGHT, R1 }, { NRES, R0 }, { 0 } }; 189 return s; 190 } else if (q->visit == INAREG) { 191 static struct rspecial s[] = { 192 { NRES, R0 }, { 0 } }; 193 return s; 194 } else if (q->visit == INBREG) { 195 static struct rspecial s[] = { { NRES, R01 }, { 0 } }; 196 return s; 197 } 198 break; 199 200 case MOD: 201 if (q->visit == INAREG && q->ltype == TUNSIGNED) { 202 static struct rspecial s[] = { 203 { NLEFT, R0 }, { NRIGHT, R1 }, { NRES, R0 }, { 0 } }; 204 return s; 205 } else if (q->visit == INBREG) { 206 static struct rspecial s[] = { { NRES, R01 }, { 0 } }; 207 return s; 208 } 209 break; 210 211 case SCONV: 212 if (q->lshape == SAREG) { 213 static struct rspecial s[] = { 214 { NLEFT, R1 }, { NRES, R01 }, { 0 } }; 215 return s; 216 } 217 break; 218 } 219 comperr("nspecial entry %d", q - table); 220 return 0; /* XXX gcc */ 221 } 222 223 /* 224 * Set evaluation order of a binary node if it differs from default. 225 */ 226 int 227 setorder(NODE *p) 228 { 229 return 0; /* nothing differs on x86 */ 230 } 231 232 /* 233 * set registers in calling conventions live. 234 */ 235 int * 236 livecall(NODE *p) 237 { 238 static int r[] = { -1 }; 239 240 return r; 241 } 242 243 /* 244 * Signal whether the instruction is acceptable for this target. 245 */ 246 int 247 acceptable(struct optab *op) 248 { 249 return 1; 250 } 251