1/* Id: order.c,v 1.22 2014/06/01 11:35:02 ragge Exp */ 2/* $NetBSD$ */ 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# include <strings.h> 33 34int canaddr(NODE *); 35 36/* 37 * should the assignment op p be stored, 38 * given that it lies as the right operand of o 39 * (or the left, if o==UNARY MUL) 40 */ 41/* 42void 43stoasg(NODE *p, int o) 44{ 45 if (x2debug) 46 printf("stoasg(%p, %o)\n", p, o); 47} 48*/ 49/* should we delay the INCR or DECR operation p */ 50int 51deltest(NODE *p) 52{ 53 return 0; 54} 55 56/* 57 * Check if p can be autoincremented. 58 * XXX - nothing can be autoincremented for now. 59 */ 60int 61autoincr(NODE *p) 62{ 63 return 0; 64} 65 66/* is it legal to make an OREG or NAME entry which has an 67 * offset of off, (from a register of r), if the 68 * resulting thing had type t */ 69int 70notoff(TWORD t, int r, CONSZ off, char *cp) 71{ 72 return(0); /* YES */ 73} 74 75/* 76 * Turn a UMUL-referenced node into OREG. 77 */ 78int 79offstar(NODE *p, int shape) 80{ 81 if (x2debug) 82 printf("offstar(%p)\n", p); 83 84 if( p->n_op == PLUS || p->n_op == MINUS ){ 85 if( p->n_right->n_op == ICON ){ 86 geninsn(p->n_left, INBREG); 87 p->n_su = -1; 88 return 1; 89 } 90 } 91 geninsn(p, INBREG); 92 return 0; 93} 94 95/* 96 * Shape matches for UMUL. Cooperates with offstar(). 97 */ 98int 99shumul(NODE *p, int shape) 100{ 101// NODE *l = p->n_left; 102 103#ifdef PCC_DEBUG 104 if (x2debug) { 105 printf("shumul(%p)\n", p); 106 fwalk(p, e2print, 0); 107 } 108#endif 109 /* XXX - fix */ 110 111 /* Can only generate OREG of BREGs (or FB) */ 112 if (p->n_op == REG && (isbreg(p->n_rval) || p->n_rval == FB)) 113 return SROREG; 114#if 0 115 if ((p->n_op == PLUS || p->n_op == MINUS) && 116 (l->n_op == REG && (isbreg(l->n_rval) || l->n_rval == FB)) && 117 p->n_right->n_op == ICON) 118 return SOREG; 119 return 0; 120#else 121 return SROREG; 122#endif 123} 124 125/* 126 * Rewrite increment/decrement operation. 127 */ 128int 129setincr(NODE *p) 130{ 131 if (x2debug) 132 printf("setincr(%p)\n", p); 133 134 return(0); 135} 136 137/* 138 * Rewrite operations on binary operators (like +, -, etc...). 139 * Called as a result of table lookup. 140 */ 141int 142setbin(NODE *p) 143{ 144 145 if (x2debug) 146 printf("setbin(%p)\n", p); 147 return 0; 148 149} 150 151/* setup for assignment operator */ 152int 153setasg(NODE *p, int cookie) 154{ 155 if (x2debug) 156 printf("setasg(%p)\n", p); 157 return(0); 158} 159 160/* setup for unary operator */ 161int 162setuni(NODE *p, int cookie) 163{ 164 return 0; 165} 166 167#if 0 168/* 169 * register allocation for instructions with special preferences. 170 */ 171regcode 172regalloc(NODE *p, struct optab *q, int wantreg) 173{ 174 regcode regc; 175 176 if (q->op == DIV || q->op == MOD) { 177 /* 178 * 16-bit div. 179 */ 180 if (regblk[R0] & 1 || regblk[R2] & 1) 181 comperr("regalloc: needed regs inuse, node %p", p); 182 if (p->n_su & DORIGHT) { 183 regc = alloregs(p->n_right, A0); 184 if (REGNUM(regc) != A0) { 185 p->n_right = movenode(p->n_right, A0); 186 if ((p->n_su & RMASK) == ROREG) { 187 p->n_su &= ~RMASK; 188 p->n_su |= RREG; 189 p->n_right->n_su &= ~LMASK; 190 p->n_right->n_su |= LOREG; 191 } 192 freeregs(regc); 193 regblk[A0] |= 1; 194 } 195 } 196 regc = alloregs(p->n_left, R0); 197 if (REGNUM(regc) != R0) { 198 p->n_left = movenode(p->n_left, R0); 199 freeregs(regc); 200 regblk[R0] |= 1; 201 } 202 if ((p->n_su & RMASK) && !(p->n_su & DORIGHT)) { 203 regc = alloregs(p->n_right, A0); 204 if (REGNUM(regc) != A0) { 205 p->n_right = movenode(p->n_right, A0); 206 if ((p->n_su & RMASK) == ROREG) { 207 p->n_su &= ~RMASK; 208 p->n_su |= RREG; 209 p->n_right->n_su &= ~LMASK; 210 p->n_right->n_su |= LOREG; 211 } 212 } 213 } 214 regblk[A0] &= ~1; 215 regblk[R0] &= ~1; 216 regblk[R2] &= ~1; 217 if (q->op == DIV) { 218 MKREGC(regc, R0, 1); 219 regblk[R0] |= 1; 220 } else { 221 MKREGC(regc, R2, 1); 222 regblk[R2] |= 1; 223 } 224 } else 225 comperr("regalloc"); 226 p->n_rall = REGNUM(regc); 227 return regc; 228} 229#endif 230 231/* 232 * Special handling of some instruction register allocation. 233 * - left is the register that left node wants. 234 * - right is the register that right node wants. 235 * - res is in which register the result will end up. 236 * - mask is registers that will be clobbered. 237 * 238 * XXX - Fix this function 239 */ 240struct rspecial * 241nspecial(struct optab *q) 242{ 243 switch (q->op) { 244 245 case DIV: 246 case MOD: 247 if(q->ltype & (TINT|TSHORT)){ 248 static struct rspecial s[] = { 249 { NRES, R0 }, { NRES, R2}, { 0 } }; 250 return s; 251 } 252 /* 253 else if(q->ltype & TCHAR) { 254 static struct rspecial s[] = { 255 { NRES, R0L }, { NRES, R0H}, { 0 } }; 256 return s; 257 }*/ 258 break; 259 260 case MUL: 261 /* 262 if(q->ltype & (TINT|TSHORT)){ 263 static struct rspecial s[] = { 264 { NRES, R0 }, { NRES, R2}, { 0 } }; 265 return s; 266 }*/ 267 comperr("multiplication not implemented"); 268 break; 269 270 default: 271 break; 272 } 273 comperr("nspecial entry %d", q - table); 274 return 0; /* XXX gcc */ 275} 276 277 278/* 279 * Splitup a function call and give away its arguments first. 280 * Calling convention used ("normal" in IAR syntax) is: 281 * - 1-byte parameters in R0L if possible, otherwise in R0H. 282 * - 2-byte pointers in A0. 283 * - 2-byte non-pointers in R0 if no byte-size arguments are found in 284 * in the first 6 bytes of parameters, otherwise R2 or at last A0. 285 * - 4-byte parameters in R2R0. 286 */ 287void 288gencall(NODE *p, NODE *prev) 289{ 290 NODE *n = 0; /* XXX gcc */ 291 static int storearg(NODE *); 292 int o = p->n_op; 293 int ty = optype(o); 294 295 if (ty == LTYPE) 296 return; 297 298 switch (o) { 299 case CALL: 300 /* swap arguments on some hardop-converted insns */ 301 /* Normal call, just push args and be done with it */ 302 p->n_op = UCALL; 303//printf("call\n"); 304 /* Check if left can be evaluated directly */ 305 if (p->n_left->n_op == UMUL) { 306 TWORD t = p->n_left->n_type; 307 int k = (freetemp(szty(t))); 308 NODE *n = mklnode(OREG, k, FB, t); 309 NODE *q = tcopy(n); 310 pass2_compile(ipnode(mkbinode(ASSIGN, n, p->n_left,t))); 311 p->n_left = q; 312 } 313 gencall(p->n_left, p); 314 p->n_rval = storearg(p->n_right); 315//printf("end call\n"); 316 break; 317 318 case UFORTCALL: 319 case FORTCALL: 320 comperr("FORTCALL"); 321 322 case USTCALL: 323 case STCALL: 324 /* 325 * Structure return. Look at the node above 326 * to decide about buffer address: 327 * - FUNARG, allocate space on stack, don't remove. 328 * - nothing, allocate space on stack and remove. 329 * - STASG, get the address of the left side as arg. 330 * - FORCE, this ends up in a return, get supplied addr. 331 * (this is not pretty, but what to do?) 332 */ 333 if (prev == NULL || prev->n_op == FUNARG) { 334 /* Create nodes to generate stack space */ 335 n = mkbinode(ASSIGN, mklnode(REG, 0, STKREG, INT), 336 mkbinode(MINUS, mklnode(REG, 0, STKREG, INT), 337 mklnode(ICON, p->n_stsize, 0, INT), INT), INT); 338//printf("stsize %d\n", p->n_stsize); 339 pass2_compile(ipnode(n)); 340 } else if (prev->n_op == STASG) { 341 n = prev->n_left; 342 if (n->n_op == UMUL) 343 n = nfree(n); 344 else if (n->n_op == NAME) { 345 n->n_op = ICON; /* Constant reference */ 346 n->n_type = INCREF(n->n_type); 347 } else 348 comperr("gencall stasg"); 349 } else if (prev->n_op == FORCE) { 350 ; /* do nothing here */ 351 } else { 352 comperr("gencall bad op %d", prev->n_op); 353 } 354 355 /* Deal with standard arguments */ 356 gencall(p->n_left, p); 357 if (o == STCALL) { 358 p->n_op = USTCALL; 359 p->n_rval = storearg(p->n_right); 360 } else 361 p->n_rval = 0; 362 /* push return struct address */ 363 if (prev == NULL || prev->n_op == FUNARG) { 364 n = mklnode(REG, 0, STKREG, INT); 365 if (p->n_rval) 366 n = mkbinode(PLUS, n, 367 mklnode(ICON, p->n_rval, 0, INT), INT); 368 pass2_compile(ipnode(mkunode(FUNARG, n, 0, INT))); 369 if (prev == NULL) 370 p->n_rval += p->n_stsize/4; 371 } else if (prev->n_op == FORCE) { 372 /* return value for this function */ 373 n = mklnode(OREG, 8, FPREG, INT); 374 pass2_compile(ipnode(mkunode(FUNARG, n, 0, INT))); 375 p->n_rval++; 376 } else { 377 pass2_compile(ipnode(mkunode(FUNARG, n, 0, INT))); 378 n = p; 379 *prev = *p; 380 nfree(n); 381 } 382//printf("end stcall\n"); 383 break; 384 385 default: 386 if (ty != UTYPE) 387 gencall(p->n_right, p); 388 gencall(p->n_left, p); 389 break; 390 } 391} 392 393/* 394 * Create separate node trees for function arguments. 395 * This is partly ticky, the strange calling convention 396 * may cause a bunch of code reorganization here. 397 */ 398static int 399storearg(NODE *p) 400{ 401 NODE *n, *q, **narry; 402 int nch, k, i, nn, rary[4]; 403 int r0l, r0h, r2, a0, stk, sz; 404 TWORD t; 405 int maxrargs = 0; 406 407 if (p->n_op == CM) 408 maxrargs = p->n_stalign; 409 410 /* count the arguments */ 411 for (i = 1, q = p; q->n_op == CM; q = q->n_left) 412 i++; 413 nn = i; 414 415 /* allocate array to store arguments */ 416 narry = tmpalloc(sizeof(NODE *)*nn); 417 418 /* enter nodes into array */ 419 for (q = p; q->n_op == CM; q = q->n_left) 420 narry[--i] = q->n_right; 421 narry[--i] = q; 422 423 /* free CM nodes */ 424 for (q = p; q->n_op == CM; ) { 425 n = q->n_left; 426 nfree(q); 427 q = n; 428 } 429 430 /* count char args */ 431 r0l = r0h = r2 = a0 = 0; 432 for (sz = nch = i = 0; i < nn && i < 6; i++) { 433 TWORD t = narry[i]->n_type; 434 if (sz >= 6) 435 break; 436 if (t == CHAR || t == UCHAR) { 437 nch++; 438 sz++; 439 } else if ((t >= SHORT && t <= UNSIGNED) || 440 t > BTMASK || t == FLOAT) { 441 sz += 2; 442 } else /* long, double */ 443 sz += 4; 444 445 } 446 447 /* 448 * Now the tricky part. The parameters that should be on stack 449 * must be found and pushed first, then the register parameters. 450 * For the latter, be sure that evaluating them do not use any 451 * registers where argument values already are inserted. 452 * XXX - function pointers? 453 * XXX foo(long a, char b) ??? 454 */ 455 for (stk = 0; stk < 4; stk++) { 456 TWORD t; 457 458 if (stk == nn) 459 break; 460 t = narry[stk]->n_type; 461 if (ISFTN(DECREF(t))) 462 t = LONG; 463 switch (t) { 464 case CHAR: case UCHAR: 465 if (r0l) { 466 if (r0h) 467 break; 468 rary[stk] = R2; /* char talk for 'R0H' */ 469 r0h = 1; 470 } else { 471 rary[stk] = R0; 472 r0l = 1; 473 } 474 continue; 475 476 case INT: case UNSIGNED: 477 if (r0l || nch) { 478 if (r2) { 479 if (a0) 480 break; 481 rary[stk] = A0; 482 a0 = 1; 483 } else { 484 rary[stk] = R2; 485 r2 = 1; 486 } 487 } else { 488 rary[stk] = R0; 489 r0l = r0h = 1; 490 } 491 continue; 492 493 case LONG: case ULONG: 494 if (r0l || r2) 495 break; 496 rary[stk] = R0; 497 r0l = r0h = r2 = 1; 498 continue; 499 500 default: 501 if (ISPTR(narry[stk]->n_type) && 502 !ISFTN(DECREF(narry[stk]->n_type))) { 503 if (a0) { 504 if (r0l || nch) { 505 if (r2) 506 break; 507 rary[stk] = R2; 508 r2 = 1; 509 } else { 510 rary[stk] = R0; 511 r0l = r0h = 1; 512 } 513 } else { 514 rary[stk] = A0; 515 a0 = 1; 516 } 517 continue; 518 } 519 break; 520 } 521 break; 522 } 523 524 /* 525 * The arguments that must be on stack are stk->nn args. 526 * Argument 0->stk-1 should be put in the rary[] register. 527 */ 528 for (sz = 0, i = nn-1; i >= stk; i--) { /* first stack args */ 529 NODE nod; 530 pass2_compile(ipnode(mkunode(FUNARG, 531 narry[i], 0, narry[i]->n_type))); 532 nod.n_type = narry[i]->n_type; 533 sz += tlen(&nod); 534 } 535 /* if param cannot be addressed directly, evaluate and put on stack */ 536 for (i = 0; i < stk; i++) { 537 538 if (canaddr(narry[i])) 539 continue; 540 t = narry[i]->n_type; 541 k = (freetemp(szty(t))); 542 n = mklnode(OREG, k, FB, t); 543 q = tcopy(n); 544 pass2_compile(ipnode(mkbinode(ASSIGN, n, narry[i], t))); 545 narry[i] = q; 546 } 547 /* move args to registers */ 548 for (i = 0; i < stk; i++) { 549 t = narry[i]->n_type; 550 pass2_compile(ipnode(mkbinode(ASSIGN, 551 mklnode(REG, 0, rary[i], t), narry[i], t))); 552 } 553 return sz; 554} 555 556/* 557 * Tell if a register can hold a specific datatype. 558 */ 559#if 0 560int 561mayuse(int reg, TWORD type) 562{ 563 return 1; /* Everything is OK */ 564} 565#endif 566 567#ifdef TAILCALL 568void 569mktailopt(struct interpass *ip1, struct interpass *ip2) 570{ 571 extern int earlylab; 572 extern char *cftname; 573 char *fn; 574 NODE *p; 575 576 p = ip1->ip_node->n_left->n_left; 577 if (p->n_op == ICON) { 578 fn = p->n_name; 579 /* calling ourselves */ 580 p = ip1->ip_node->n_left; 581 if (p->n_op == CALL) { 582 if (storearg(p->n_right)) 583 comperr("too many args: fix mktailopt"); 584 p->n_op = UCALL; 585 } 586 tfree(ip1->ip_node); 587 p = ip2->ip_node->n_left; 588 if (strcmp(fn, cftname)) { 589 /* Not us, must generate fake prologue */ 590 ip1->type = IP_ASM; 591 ip1->ip_asm = "\tmov.w FB,SP\n\tpop.w FB\n"; 592 pass2_compile(ip1); 593 p->n_lval = p->n_rval = 0; 594 p->n_name = fn; 595 } else 596 p->n_lval = earlylab; 597 } else { 598 pass2_compile(ip1); 599 } 600 pass2_compile(ip2); 601} 602#endif 603/* 604 * Set registers "live" at function calls (like arguments in registers). 605 * This is for liveness analysis of registers. 606 */ 607int * 608livecall(NODE *p) 609{ 610 static int r[1] = { -1 }; /* Terminate with -1 */ 611 612 return &r[0]; 613} 614 615/* 616 * Signal whether the instruction is acceptable for this target. 617 */ 618int 619acceptable(struct optab *op) 620{ 621 return 1; 622} 623