github.com/xushiwei/go@v0.0.0-20130601165731-2b9d83f45bc9/src/cmd/5c/sgen.c (about) 1 // Inferno utils/5c/sgen.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/5c/sgen.c 3 // 4 // Copyright © 1994-1999 Lucent Technologies Inc. All rights reserved. 5 // Portions Copyright © 1995-1997 C H Forsyth (forsyth@terzarima.net) 6 // Portions Copyright © 1997-1999 Vita Nuova Limited 7 // Portions Copyright © 2000-2007 Vita Nuova Holdings Limited (www.vitanuova.com) 8 // Portions Copyright © 2004,2006 Bruce Ellis 9 // Portions Copyright © 2005-2007 C H Forsyth (forsyth@terzarima.net) 10 // Revisions Copyright © 2000-2007 Lucent Technologies Inc. and others 11 // Portions Copyright © 2009 The Go Authors. All rights reserved. 12 // 13 // Permission is hereby granted, free of charge, to any person obtaining a copy 14 // of this software and associated documentation files (the "Software"), to deal 15 // in the Software without restriction, including without limitation the rights 16 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 17 // copies of the Software, and to permit persons to whom the Software is 18 // furnished to do so, subject to the following conditions: 19 // 20 // The above copyright notice and this permission notice shall be included in 21 // all copies or substantial portions of the Software. 22 // 23 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 24 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 25 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 26 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 27 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 28 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 29 // THE SOFTWARE. 30 31 32 #include "gc.h" 33 34 Prog* 35 gtext(Sym *s, int32 stkoff) 36 { 37 int32 a; 38 39 a = 0; 40 if(!(textflag & NOSPLIT)) 41 a = argsize(); 42 else if(stkoff >= 128) 43 yyerror("stack frame too large for NOSPLIT function"); 44 45 gpseudo(ATEXT, s, nodconst(stkoff)); 46 p->to.type = D_CONST2; 47 p->to.offset2 = a; 48 return p; 49 } 50 51 void 52 noretval(int n) 53 { 54 55 if(n & 1) { 56 gins(ANOP, Z, Z); 57 p->to.type = D_REG; 58 p->to.reg = REGRET; 59 } 60 if(n & 2) { 61 gins(ANOP, Z, Z); 62 p->to.type = D_FREG; 63 p->to.reg = FREGRET; 64 } 65 } 66 67 /* 68 * calculate addressability as follows 69 * CONST ==> 20 $value 70 * NAME ==> 10 name 71 * REGISTER ==> 11 register 72 * INDREG ==> 12 *[(reg)+offset] 73 * &10 ==> 2 $name 74 * ADD(2, 20) ==> 2 $name+offset 75 * ADD(3, 20) ==> 3 $(reg)+offset 76 * &12 ==> 3 $(reg)+offset 77 * *11 ==> 11 ?? 78 * *2 ==> 10 name 79 * *3 ==> 12 *(reg)+offset 80 * calculate complexity (number of registers) 81 */ 82 void 83 xcom(Node *n) 84 { 85 Node *l, *r; 86 int t; 87 88 if(n == Z) 89 return; 90 l = n->left; 91 r = n->right; 92 n->addable = 0; 93 n->complex = 0; 94 switch(n->op) { 95 case OCONST: 96 n->addable = 20; 97 return; 98 99 case OREGISTER: 100 n->addable = 11; 101 return; 102 103 case OINDREG: 104 n->addable = 12; 105 return; 106 107 case ONAME: 108 n->addable = 10; 109 return; 110 111 case OADDR: 112 xcom(l); 113 if(l->addable == 10) 114 n->addable = 2; 115 if(l->addable == 12) 116 n->addable = 3; 117 break; 118 119 case OIND: 120 xcom(l); 121 if(l->addable == 11) 122 n->addable = 12; 123 if(l->addable == 3) 124 n->addable = 12; 125 if(l->addable == 2) 126 n->addable = 10; 127 break; 128 129 case OADD: 130 xcom(l); 131 xcom(r); 132 if(l->addable == 20) { 133 if(r->addable == 2) 134 n->addable = 2; 135 if(r->addable == 3) 136 n->addable = 3; 137 } 138 if(r->addable == 20) { 139 if(l->addable == 2) 140 n->addable = 2; 141 if(l->addable == 3) 142 n->addable = 3; 143 } 144 break; 145 146 case OASLMUL: 147 case OASMUL: 148 xcom(l); 149 xcom(r); 150 t = vlog(r); 151 if(t >= 0) { 152 n->op = OASASHL; 153 r->vconst = t; 154 r->type = types[TINT]; 155 } 156 break; 157 158 case OMUL: 159 case OLMUL: 160 xcom(l); 161 xcom(r); 162 t = vlog(r); 163 if(t >= 0) { 164 n->op = OASHL; 165 r->vconst = t; 166 r->type = types[TINT]; 167 } 168 t = vlog(l); 169 if(t >= 0) { 170 n->op = OASHL; 171 n->left = r; 172 n->right = l; 173 r = l; 174 l = n->left; 175 r->vconst = t; 176 r->type = types[TINT]; 177 } 178 break; 179 180 case OASLDIV: 181 xcom(l); 182 xcom(r); 183 t = vlog(r); 184 if(t >= 0) { 185 n->op = OASLSHR; 186 r->vconst = t; 187 r->type = types[TINT]; 188 } 189 break; 190 191 case OLDIV: 192 xcom(l); 193 xcom(r); 194 t = vlog(r); 195 if(t >= 0) { 196 n->op = OLSHR; 197 r->vconst = t; 198 r->type = types[TINT]; 199 } 200 break; 201 202 case OASLMOD: 203 xcom(l); 204 xcom(r); 205 t = vlog(r); 206 if(t >= 0) { 207 n->op = OASAND; 208 r->vconst--; 209 } 210 break; 211 212 case OLMOD: 213 xcom(l); 214 xcom(r); 215 t = vlog(r); 216 if(t >= 0) { 217 n->op = OAND; 218 r->vconst--; 219 } 220 break; 221 222 default: 223 if(l != Z) 224 xcom(l); 225 if(r != Z) 226 xcom(r); 227 break; 228 } 229 if(n->addable >= 10) 230 return; 231 232 if(l != Z) 233 n->complex = l->complex; 234 if(r != Z) { 235 if(r->complex == n->complex) 236 n->complex = r->complex+1; 237 else 238 if(r->complex > n->complex) 239 n->complex = r->complex; 240 } 241 if(n->complex == 0) 242 n->complex++; 243 244 if(com64(n)) 245 return; 246 247 switch(n->op) { 248 case OFUNC: 249 n->complex = FNX; 250 break; 251 252 case OADD: 253 case OXOR: 254 case OAND: 255 case OOR: 256 case OEQ: 257 case ONE: 258 /* 259 * immediate operators, make const on right 260 */ 261 if(l->op == OCONST) { 262 n->left = r; 263 n->right = l; 264 } 265 break; 266 } 267 }