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