github.com/rohankumardubey/syslog-redirector-golang@v0.0.0-20140320174030-4859f03d829a/src/cmd/6c/sgen.c (about) 1 // Inferno utils/6c/sgen.c 2 // http://code.google.com/p/inferno-os/source/browse/utils/6c/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 #include "gc.h" 32 #include "../../pkg/runtime/funcdata.h" 33 34 Prog* 35 gtext(Sym *s, int32 stkoff) 36 { 37 vlong v; 38 39 v = ((uvlong)argsize() << 32) | (stkoff & 0xffffffff); 40 if((textflag & NOSPLIT) && stkoff >= 128) 41 yyerror("stack frame too large for NOSPLIT function"); 42 43 gpseudo(ATEXT, s, nodgconst(v, types[TVLONG])); 44 return p; 45 } 46 47 void 48 noretval(int n) 49 { 50 51 if(n & 1) { 52 gins(ANOP, Z, Z); 53 p->to.type = REGRET; 54 } 55 if(n & 2) { 56 gins(ANOP, Z, Z); 57 p->to.type = FREGRET; 58 } 59 } 60 61 /* welcome to commute */ 62 static void 63 commute(Node *n) 64 { 65 Node *l, *r; 66 67 l = n->left; 68 r = n->right; 69 if(r->complex > l->complex) { 70 n->left = r; 71 n->right = l; 72 } 73 } 74 75 void 76 indexshift(Node *n) 77 { 78 int g; 79 80 if(!typechlpv[n->type->etype]) 81 return; 82 simplifyshift(n); 83 if(n->op == OASHL && n->right->op == OCONST){ 84 g = vconst(n->right); 85 if(g >= 0 && g <= 3) 86 n->addable = 7; 87 } 88 } 89 90 /* 91 * calculate addressability as follows 92 * NAME ==> 10/11 name+value(SB/SP) 93 * REGISTER ==> 12 register 94 * CONST ==> 20 $value 95 * *(20) ==> 21 value 96 * &(10) ==> 13 $name+value(SB) 97 * &(11) ==> 1 $name+value(SP) 98 * (13) + (20) ==> 13 fold constants 99 * (1) + (20) ==> 1 fold constants 100 * *(13) ==> 10 back to name 101 * *(1) ==> 11 back to name 102 * 103 * (20) * (X) ==> 7 multiplier in indexing 104 * (X,7) + (13,1) ==> 8 adder in indexing (addresses) 105 * (8) ==> &9(OINDEX) index, almost addressable 106 * 107 * calculate complexity (number of registers) 108 */ 109 void 110 xcom(Node *n) 111 { 112 Node *l, *r; 113 int g; 114 115 if(n == Z) 116 return; 117 l = n->left; 118 r = n->right; 119 n->complex = 0; 120 n->addable = 0; 121 switch(n->op) { 122 case OCONST: 123 n->addable = 20; 124 break; 125 126 case ONAME: 127 if(flag_largemodel) 128 n->addable = 9; 129 else 130 n->addable = 10; 131 if(n->class == CPARAM || n->class == CAUTO) 132 n->addable = 11; 133 break; 134 135 case OEXREG: 136 n->addable = 0; 137 break; 138 139 case OREGISTER: 140 n->addable = 12; 141 break; 142 143 case OINDREG: 144 n->addable = 12; 145 break; 146 147 case OADDR: 148 xcom(l); 149 if(l->addable == 10) 150 n->addable = 13; 151 else 152 if(l->addable == 11) 153 n->addable = 1; 154 break; 155 156 case OADD: 157 xcom(l); 158 xcom(r); 159 if(n->type->etype != TIND) 160 break; 161 162 switch(r->addable) { 163 case 20: 164 switch(l->addable) { 165 case 1: 166 case 13: 167 commadd: 168 l->type = n->type; 169 *n = *l; 170 l = new(0, Z, Z); 171 *l = *(n->left); 172 l->xoffset += r->vconst; 173 n->left = l; 174 r = n->right; 175 goto brk; 176 } 177 break; 178 179 case 1: 180 case 13: 181 case 10: 182 case 11: 183 /* l is the base, r is the index */ 184 if(l->addable != 20) 185 n->addable = 8; 186 break; 187 } 188 switch(l->addable) { 189 case 20: 190 switch(r->addable) { 191 case 13: 192 case 1: 193 r = n->left; 194 l = n->right; 195 n->left = l; 196 n->right = r; 197 goto commadd; 198 } 199 break; 200 201 case 13: 202 case 1: 203 case 10: 204 case 11: 205 /* r is the base, l is the index */ 206 if(r->addable != 20) 207 n->addable = 8; 208 break; 209 } 210 if(n->addable == 8 && !side(n)) { 211 indx(n); 212 l = new1(OINDEX, idx.basetree, idx.regtree); 213 l->scale = idx.scale; 214 l->addable = 9; 215 l->complex = l->right->complex; 216 l->type = l->left->type; 217 n->op = OADDR; 218 n->left = l; 219 n->right = Z; 220 n->addable = 8; 221 break; 222 } 223 break; 224 225 case OINDEX: 226 xcom(l); 227 xcom(r); 228 n->addable = 9; 229 break; 230 231 case OIND: 232 xcom(l); 233 if(l->op == OADDR) { 234 l = l->left; 235 l->type = n->type; 236 *n = *l; 237 return; 238 } 239 switch(l->addable) { 240 case 20: 241 n->addable = 21; 242 break; 243 case 1: 244 n->addable = 11; 245 break; 246 case 13: 247 n->addable = 10; 248 break; 249 } 250 break; 251 252 case OASHL: 253 xcom(l); 254 xcom(r); 255 indexshift(n); 256 break; 257 258 case OMUL: 259 case OLMUL: 260 xcom(l); 261 xcom(r); 262 g = vlog(l); 263 if(g >= 0) { 264 n->left = r; 265 n->right = l; 266 l = r; 267 r = n->right; 268 } 269 g = vlog(r); 270 if(g >= 0) { 271 n->op = OASHL; 272 r->vconst = g; 273 r->type = types[TINT]; 274 indexshift(n); 275 break; 276 } 277 commute(n); 278 break; 279 280 case OASLDIV: 281 xcom(l); 282 xcom(r); 283 g = vlog(r); 284 if(g >= 0) { 285 n->op = OASLSHR; 286 r->vconst = g; 287 r->type = types[TINT]; 288 } 289 break; 290 291 case OLDIV: 292 xcom(l); 293 xcom(r); 294 g = vlog(r); 295 if(g >= 0) { 296 n->op = OLSHR; 297 r->vconst = g; 298 r->type = types[TINT]; 299 indexshift(n); 300 break; 301 } 302 break; 303 304 case OASLMOD: 305 xcom(l); 306 xcom(r); 307 g = vlog(r); 308 if(g >= 0) { 309 n->op = OASAND; 310 r->vconst--; 311 } 312 break; 313 314 case OLMOD: 315 xcom(l); 316 xcom(r); 317 g = vlog(r); 318 if(g >= 0) { 319 n->op = OAND; 320 r->vconst--; 321 } 322 break; 323 324 case OASMUL: 325 case OASLMUL: 326 xcom(l); 327 xcom(r); 328 g = vlog(r); 329 if(g >= 0) { 330 n->op = OASASHL; 331 r->vconst = g; 332 } 333 break; 334 335 case OLSHR: 336 case OASHR: 337 xcom(l); 338 xcom(r); 339 indexshift(n); 340 break; 341 342 default: 343 if(l != Z) 344 xcom(l); 345 if(r != Z) 346 xcom(r); 347 break; 348 } 349 brk: 350 if(n->addable >= 10) 351 return; 352 if(l != Z) 353 n->complex = l->complex; 354 if(r != Z) { 355 if(r->complex == n->complex) 356 n->complex = r->complex+1; 357 else 358 if(r->complex > n->complex) 359 n->complex = r->complex; 360 } 361 if(n->complex == 0) 362 n->complex++; 363 364 switch(n->op) { 365 366 case OFUNC: 367 n->complex = FNX; 368 break; 369 370 case OCAST: 371 if(l->type->etype == TUVLONG && typefd[n->type->etype]) 372 n->complex += 2; 373 break; 374 375 case OLMOD: 376 case OMOD: 377 case OLMUL: 378 case OLDIV: 379 case OMUL: 380 case ODIV: 381 case OASLMUL: 382 case OASLDIV: 383 case OASLMOD: 384 case OASMUL: 385 case OASDIV: 386 case OASMOD: 387 if(r->complex >= l->complex) { 388 n->complex = l->complex + 3; 389 if(r->complex > n->complex) 390 n->complex = r->complex; 391 } else { 392 n->complex = r->complex + 3; 393 if(l->complex > n->complex) 394 n->complex = l->complex; 395 } 396 break; 397 398 case OLSHR: 399 case OASHL: 400 case OASHR: 401 case OASLSHR: 402 case OASASHL: 403 case OASASHR: 404 if(r->complex >= l->complex) { 405 n->complex = l->complex + 2; 406 if(r->complex > n->complex) 407 n->complex = r->complex; 408 } else { 409 n->complex = r->complex + 2; 410 if(l->complex > n->complex) 411 n->complex = l->complex; 412 } 413 break; 414 415 case OADD: 416 case OXOR: 417 case OAND: 418 case OOR: 419 /* 420 * immediate operators, make const on right 421 */ 422 if(l->op == OCONST) { 423 n->left = r; 424 n->right = l; 425 } 426 break; 427 428 case OEQ: 429 case ONE: 430 case OLE: 431 case OLT: 432 case OGE: 433 case OGT: 434 case OHI: 435 case OHS: 436 case OLO: 437 case OLS: 438 /* 439 * compare operators, make const on left 440 */ 441 if(r->op == OCONST) { 442 n->left = r; 443 n->right = l; 444 n->op = invrel[relindex(n->op)]; 445 } 446 break; 447 } 448 } 449 450 void 451 indx(Node *n) 452 { 453 Node *l, *r; 454 455 if(debug['x']) 456 prtree(n, "indx"); 457 458 l = n->left; 459 r = n->right; 460 if(l->addable == 1 || l->addable == 13 || r->complex > l->complex) { 461 n->right = l; 462 n->left = r; 463 l = r; 464 r = n->right; 465 } 466 if(l->addable != 7) { 467 idx.regtree = l; 468 idx.scale = 1; 469 } else 470 if(l->right->addable == 20) { 471 idx.regtree = l->left; 472 idx.scale = 1 << l->right->vconst; 473 } else 474 if(l->left->addable == 20) { 475 idx.regtree = l->right; 476 idx.scale = 1 << l->left->vconst; 477 } else 478 diag(n, "bad index"); 479 480 idx.basetree = r; 481 if(debug['x']) { 482 print("scale = %d\n", idx.scale); 483 prtree(idx.regtree, "index"); 484 prtree(idx.basetree, "base"); 485 } 486 }