1 /* Id: local2.c,v 1.8 2009/07/29 12:34:19 ragge Exp */ 2 /* $NetBSD: local2.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 # include "pass2.h" 31 # include <ctype.h> 32 # include <string.h> 33 34 static int spcoff; 35 static int argsiz(NODE *p); 36 37 void 38 deflab(int label) 39 { 40 printf(LABFMT ":\n", label); 41 } 42 43 void 44 prologue(struct interpass_prolog *ipp) 45 { 46 int addto; 47 48 #ifdef LANG_F77 49 if (ipp->ipp_vis) 50 printf(" .globl %s\n", ipp->ipp_name); 51 printf("%s:\n", ipp->ipp_name); 52 #endif 53 printf("jsr r5,csv\n"); 54 addto = p2maxautooff; 55 if (addto >= AUTOINIT/SZCHAR) 56 addto -= AUTOINIT/SZCHAR; 57 if (addto & 1) 58 addto++; 59 if (addto == 2) 60 printf("tst -(sp)\n"); 61 else if (addto == 4) 62 printf("cmp -(sp),-(sp)\n"); 63 else if (addto > 4) 64 printf("sub $%o,sp\n", addto); 65 spcoff = 0; 66 } 67 68 void 69 eoftn(struct interpass_prolog *ipp) 70 { 71 if (spcoff) 72 comperr("spcoff == %d", spcoff); 73 if (ipp->ipp_ip.ip_lbl == 0) 74 return; /* no code needs to be generated */ 75 printf("jmp cret\n"); 76 } 77 78 /* 79 * add/sub/... 80 * 81 * Param given: 82 */ 83 void 84 hopcode(int f, int o) 85 { 86 char *str; 87 88 switch (o) { 89 case PLUS: 90 str = "add"; 91 break; 92 case MINUS: 93 str = "sub"; 94 break; 95 case AND: 96 str = "and"; 97 break; 98 case OR: 99 str = "or"; 100 break; 101 case ER: 102 str = "xor"; 103 break; 104 default: 105 comperr("hopcode2: %d", o); 106 str = 0; /* XXX gcc */ 107 } 108 printf("%s%c", str, f); 109 } 110 111 /* 112 * Return type size in bytes. Used by R2REGS, arg 2 to offset(). 113 */ 114 int 115 tlen(p) NODE *p; 116 { 117 switch(p->n_type) { 118 case CHAR: 119 case UCHAR: 120 return(1); 121 122 case SHORT: 123 case USHORT: 124 return(SZSHORT/SZCHAR); 125 126 case DOUBLE: 127 return(SZDOUBLE/SZCHAR); 128 129 case INT: 130 case UNSIGNED: 131 case LONG: 132 case ULONG: 133 return(SZINT/SZCHAR); 134 135 case LONGLONG: 136 case ULONGLONG: 137 return SZLONGLONG/SZCHAR; 138 139 default: 140 if (!ISPTR(p->n_type)) 141 comperr("tlen type %d not pointer"); 142 return SZPOINT(p->n_type)/SZCHAR; 143 } 144 } 145 146 /* 147 * Emit code to compare two long numbers. 148 */ 149 static void 150 twolcomp(NODE *p) 151 { 152 int o = p->n_op; 153 int s = getlab2(); 154 int e = p->n_label; 155 int cb1, cb2; 156 157 if (o >= ULE) 158 o -= (ULE-LE); 159 switch (o) { 160 case NE: 161 cb1 = 0; 162 cb2 = NE; 163 break; 164 case EQ: 165 cb1 = NE; 166 cb2 = 0; 167 break; 168 case LE: 169 case LT: 170 cb1 = GT; 171 cb2 = LT; 172 break; 173 case GE: 174 case GT: 175 cb1 = LT; 176 cb2 = GT; 177 break; 178 179 default: 180 cb1 = cb2 = 0; /* XXX gcc */ 181 } 182 if (p->n_op >= ULE) 183 cb1 += 2, cb2 += 2; 184 expand(p, 0, "cmp AR,AL\n"); 185 if (cb1) cbgen(cb1, s); 186 if (cb2) cbgen(cb2, e); 187 expand(p, 0, "cmp UR,UL\n"); 188 cbgen(p->n_op, e); 189 deflab(s); 190 } 191 192 193 /* 194 * Generate compare code for long instructions when right node is 0. 195 */ 196 static void 197 lcomp(NODE *p) 198 { 199 switch (p->n_op) { 200 case EQ: 201 expand(p, FORCC, "tst AL\n"); 202 printf("jne 1f\n"); 203 expand(p, FORCC, "tst UL\n"); 204 cbgen(EQ, p->n_label); 205 printf("1:\n"); 206 break; 207 case NE: 208 expand(p, FORCC, "tst AL\n"); 209 cbgen(NE, p->n_label); 210 expand(p, FORCC, "tst UL\n"); 211 cbgen(NE, p->n_label); 212 break; 213 case GE: 214 expand(p, FORCC, "tst AL\n"); 215 cbgen(GE, p->n_label); 216 break; 217 default: 218 comperr("lcomp %p", p); 219 } 220 } 221 222 void 223 zzzcode(NODE *p, int c) 224 { 225 switch (c) { 226 case 'A': /* print out - if not first arg */ 227 if (spcoff || (p->n_type == FLOAT || p->n_type == DOUBLE)) 228 printf("-"); 229 spcoff += argsiz(p); 230 break; 231 232 case 'B': /* arg is pointer to block */ 233 expand(p->n_left, FOREFF, "mov AL,ZA(sp)\n"); 234 expand(p->n_left, FOREFF, "sub CR,(sp)\n"); 235 break; 236 237 case 'C': /* subtract stack after call */ 238 spcoff -= p->n_qual; 239 if (spcoff == 0 && !(p->n_flags & NLOCAL1)) 240 p->n_qual -= 2; 241 if (p->n_qual == 2) 242 printf("tst (sp)+\n"); 243 else if (p->n_qual == 4) 244 printf("cmp (sp)+,(sp)+\n"); 245 else if (p->n_qual > 2) 246 printf("add $%o,sp\n", (int)p->n_qual); 247 break; 248 249 case 'D': /* long comparisions */ 250 lcomp(p); 251 break; 252 253 case 'E': /* long move */ 254 rmove(p->n_right->n_reg, p->n_left->n_reg, p->n_type); 255 break; 256 257 case 'F': /* long comparision */ 258 twolcomp(p); 259 break; 260 261 case 'G': /* printout a subnode for post-inc */ 262 adrput(stdout, p->n_left->n_left); 263 break; 264 265 case 'H': /* arg with post-inc */ 266 expand(p->n_left->n_left, FOREFF, "mov AL,ZA(sp)\n"); 267 expand(p->n_left->n_left, FOREFF, "inc AL\n"); 268 break; 269 270 case 'Q': /* struct assignment, no rv */ 271 printf("mov $%o,", p->n_stsize/2); 272 expand(p, INAREG, "A1\n"); 273 printf("1:\n"); 274 expand(p, INAREG, "mov (AR)+,(AL)+\n"); 275 expand(p, INAREG, "dec A1\n"); 276 printf("jne 1b\n"); 277 break; 278 279 case 'R': /* struct assignment with rv */ 280 printf("mov $%o,", p->n_stsize/2); 281 expand(p, INAREG, "A1\n"); 282 expand(p, INAREG, "mov AR,A2\n"); 283 printf("1:\n"); 284 expand(p, INAREG, "mov (A2)+,(AL)+\n"); 285 expand(p, INAREG, "dec A1\n"); 286 printf("jne 1b\n"); 287 break; 288 289 case '1': /* lower part of double regs */ 290 p = getlr(p, '1'); 291 printf("r%c", rnames[p->n_rval][1]); 292 break; 293 294 default: 295 comperr("zzzcode %c", c); 296 } 297 } 298 299 /*ARGSUSED*/ 300 int 301 rewfld(NODE *p) 302 { 303 return(1); 304 } 305 306 int canaddr(NODE *); 307 int 308 canaddr(NODE *p) 309 { 310 int o = p->n_op; 311 312 if (o==NAME || o==REG || o==ICON || o==OREG || 313 (o==UMUL && shumul(p->n_left, STARNM|SOREG))) 314 return(1); 315 return(0); 316 } 317 318 /* 319 * Does the bitfield shape match? 320 */ 321 int 322 flshape(NODE *p) 323 { 324 int o = p->n_op; 325 326 if (o == OREG || o == REG || o == NAME) 327 return SRDIR; /* Direct match */ 328 if (o == UMUL && shumul(p->n_left, SOREG)) 329 return SROREG; /* Convert into oreg */ 330 return SRREG; /* put it into a register */ 331 } 332 333 /* INTEMP shapes must not contain any temporary registers */ 334 /* XXX should this go away now? */ 335 int 336 shtemp(NODE *p) 337 { 338 return 0; 339 #if 0 340 int r; 341 342 if (p->n_op == STARG ) 343 p = p->n_left; 344 345 switch (p->n_op) { 346 case REG: 347 return (!istreg(p->n_rval)); 348 349 case OREG: 350 r = p->n_rval; 351 if (R2TEST(r)) { 352 if (istreg(R2UPK1(r))) 353 return(0); 354 r = R2UPK2(r); 355 } 356 return (!istreg(r)); 357 358 case UMUL: 359 p = p->n_left; 360 return (p->n_op != UMUL && shtemp(p)); 361 } 362 363 if (optype(p->n_op) != LTYPE) 364 return(0); 365 return(1); 366 #endif 367 } 368 369 static void 370 negcon(FILE *fp, int con) 371 { 372 if (con < 0) 373 fprintf(fp, "-"), con = -con; 374 fprintf(fp, "%o", con & 0177777); 375 } 376 377 void 378 adrcon(CONSZ val) 379 { 380 printf("$" CONFMT, val); 381 } 382 383 void 384 conput(FILE *fp, NODE *p) 385 { 386 int val = p->n_lval; 387 388 switch (p->n_op) { 389 case ICON: 390 printf("$"); 391 if (p->n_name[0] != '\0') { 392 fprintf(fp, "%s", p->n_name); 393 if (val) 394 fprintf(fp, "+%o", val & 0177777); 395 } else if (p->n_type == LONG || p->n_type == ULONG) 396 negcon(fp, val >> 16); 397 else 398 negcon(fp, val); 399 return; 400 401 default: 402 comperr("illegal conput, p %p", p); 403 } 404 } 405 406 /*ARGSUSED*/ 407 void 408 insput(NODE *p) 409 { 410 comperr("insput"); 411 } 412 413 /* 414 * Write out the upper address, like the upper register of a 2-register 415 * reference, or the next memory location. 416 */ 417 void 418 upput(NODE *p, int size) 419 { 420 size /= SZINT; 421 switch (p->n_op) { 422 case NAME: 423 case OREG: 424 p->n_lval += size; 425 adrput(stdout, p); 426 p->n_lval -= size; 427 break; 428 case REG: 429 printf("r%c", rnames[p->n_rval][2]); 430 break; 431 case ICON: 432 /* On PDP11 upper value is low 16 bits */ 433 printf("$"); 434 negcon(stdout, p->n_lval & 0177777); 435 break; 436 default: 437 comperr("upput bad op %d size %d", p->n_op, size); 438 } 439 } 440 441 /* 442 * output an address, with offsets, from p 443 */ 444 void 445 adrput(FILE *io, NODE *p) 446 { 447 int r; 448 449 if (p->n_op == FLD) 450 p = p->n_left; 451 452 switch (p->n_op) { 453 case NAME: 454 if (p->n_name[0] != '\0') { 455 fputs(p->n_name, io); 456 if (p->n_lval != 0) 457 fprintf(io, "+%o", (int)(p->n_lval&0177777)); 458 } else 459 negcon(io, p->n_lval); 460 return; 461 462 case OREG: 463 r = p->n_rval; 464 if (p->n_name[0]) 465 printf("%s%s", p->n_name, p->n_lval ? "+" : ""); 466 if (R2TEST(r) && R2UPK3(r) == 0) 467 printf("*"); 468 if (p->n_lval) 469 negcon(io, p->n_lval); 470 if (R2TEST(r)) { 471 fprintf(io, "(%s)", rnames[R2UPK1(r)]); 472 if (R2UPK3(r) == 1) 473 fprintf(io, "+"); 474 } else 475 fprintf(io, "(%s)", rnames[p->n_rval]); 476 return; 477 case ICON: 478 /* addressable value of the constant */ 479 conput(io, p); 480 return; 481 482 case REG: 483 switch (p->n_type) { 484 case LONG: 485 case ULONG: 486 fprintf(io, "r%c", rnames[p->n_rval][1]); 487 break; 488 default: 489 fprintf(io, "%s", rnames[p->n_rval]); 490 } 491 return; 492 493 case UMUL: 494 if (tshape(p, STARNM)) { 495 printf("*"); 496 adrput(io, p->n_left); 497 break; 498 } 499 /* FALLTHROUGH */ 500 default: 501 comperr("illegal address, op %d, node %p", p->n_op, p); 502 return; 503 504 } 505 } 506 507 static char * 508 ccbranches[] = { 509 "jeq", /* jumpe */ 510 "jne", /* jumpn */ 511 "jle", /* jumple */ 512 "jlt", /* jumpl */ 513 "jge", /* jumpge */ 514 "jgt", /* jumpg */ 515 "jlos", /* jumple (jlequ) */ 516 "jlo", /* jumpl (jlssu) */ 517 "jhis", /* jumpge (jgequ) */ 518 "jhi", /* jumpg (jgtru) */ 519 }; 520 521 522 /* printf conditional and unconditional branches */ 523 void 524 cbgen(int o, int lab) 525 { 526 if (o < EQ || o > UGT) 527 comperr("bad conditional branch: %s", opst[o]); 528 printf("%s " LABFMT "\n", ccbranches[o-EQ], lab); 529 } 530 531 #define IS1CON(p) ((p)->n_op == ICON && (p)->n_lval == 1) 532 533 /* 534 * Move postfix operators to the next statement, unless they are 535 * within a function call or a branch. 536 */ 537 static void 538 cvtree(NODE *p, struct interpass *ip2) 539 { 540 struct interpass *ip; 541 NODE *q; 542 543 if (callop(p->n_op) || p->n_op == CBRANCH) 544 return; 545 546 if ((p->n_op == PLUS || p->n_op == MINUS) && 547 IS1CON(p->n_right) && (q = p->n_left)->n_op == ASSIGN && 548 treecmp(q->n_left, q->n_right->n_left) && 549 IS1CON(q->n_right->n_right)) { 550 if ((p->n_op == PLUS && q->n_right->n_op == MINUS) || 551 (p->n_op == MINUS && q->n_right->n_op == PLUS)) { 552 nfree(p->n_right); 553 *p = *q->n_left; 554 if (optype(p->n_op) != LTYPE) 555 p->n_left = tcopy(p->n_left); 556 ip = ipnode(q); 557 DLIST_INSERT_AFTER(ip2, ip, qelem); 558 return; 559 } 560 } 561 if (optype(p->n_op) == BITYPE) 562 cvtree(p->n_right, ip2); 563 if (optype(p->n_op) != LTYPE) 564 cvtree(p->n_left, ip2); 565 } 566 567 /* 568 * Convert AND to BIC. 569 */ 570 static void 571 fixops(NODE *p, void *arg) 572 { 573 static int fltwritten; 574 575 if (!fltwritten && (p->n_type == FLOAT || p->n_type == DOUBLE)) { 576 printf(".globl fltused\n"); 577 fltwritten = 1; 578 } 579 switch (p->n_op) { 580 case AND: 581 if (p->n_right->n_op == ICON) { 582 p->n_right->n_lval = ((~p->n_right->n_lval) & 0177777); 583 } else if (p->n_right->n_op == COMPL) { 584 NODE *q = p->n_right->n_left; 585 nfree(p->n_right); 586 p->n_right = q; 587 } else 588 p->n_right = mkunode(COMPL, p->n_right, 0, p->n_type); 589 break; 590 case RS: 591 p->n_right = mkunode(UMINUS, p->n_right, 0, p->n_right->n_type); 592 p->n_op = LS; 593 break; 594 case EQ: 595 case NE: /* Hack not to clear bits if FORCC */ 596 if (p->n_left->n_op == AND) 597 fixops(p->n_left, 0); /* Convert an extra time */ 598 break; 599 } 600 } 601 602 void 603 myreader(struct interpass *ipole) 604 { 605 struct interpass *ip; 606 607 #ifdef PCC_DEBUG 608 if (x2debug) { 609 printf("myreader before\n"); 610 printip(ipole); 611 } 612 #endif 613 DLIST_FOREACH(ip, ipole, qelem) { 614 if (ip->type != IP_NODE) 615 continue; 616 walkf(ip->ip_node, fixops, 0); 617 canon(ip->ip_node); /* call it early */ 618 } 619 #ifdef PCC_DEBUG 620 if (x2debug) { 621 printf("myreader middle\n"); 622 printip(ipole); 623 } 624 #endif 625 DLIST_FOREACH(ip, ipole, qelem) { 626 if (ip->type == IP_NODE) 627 cvtree(ip->ip_node, ip); 628 } 629 #ifdef PCC_DEBUG 630 if (x2debug) { 631 printf("myreader after\n"); 632 printip(ipole); 633 } 634 #endif 635 } 636 637 /* 638 * Remove SCONVs where the left node is an OREG with a smaller type. 639 */ 640 static void 641 delsconv(NODE *p, void *arg) 642 { 643 #if 0 644 NODE *l; 645 646 if (p->n_op != SCONV || (l = p->n_left)->n_op != OREG) 647 return; 648 if (DEUNSIGN(p->n_type) == INT && DEUNSIGN(l->n_type) == LONG) { 649 p->n_op = OREG; 650 p->n_lval = l->n_lval; /* high word */ 651 p->n_rval = l->n_rval; 652 nfree(l); 653 } 654 #endif 655 /* Could do this for char etc. also */ 656 } 657 658 void 659 mycanon(NODE *p) 660 { 661 walkf(p, delsconv, 0); 662 } 663 664 void 665 myoptim(struct interpass *ip) 666 { 667 } 668 669 void 670 rmove(int s, int d, TWORD t) 671 { 672 if (t < LONG || t > BTMASK) { 673 printf("mov%s %s,%s\n", t < SHORT ? "b" : "", 674 rnames[s],rnames[d]); /* XXX char should be full reg? */ 675 } else if (t == LONG || t == ULONG) { 676 /* avoid trashing double regs */ 677 if (d > s) 678 printf("mov r%c,r%c\nmov r%c,r%c\n", 679 rnames[s][2],rnames[d][2], 680 rnames[s][1],rnames[d][1]); 681 else 682 printf("mov r%c,r%c\nmov r%c,r%c\n", 683 rnames[s][1],rnames[d][1], 684 rnames[s][2],rnames[d][2]); 685 } else if (t == FLOAT || t == DOUBLE) { 686 printf("movf %s,%s\n", rnames[s],rnames[d]); 687 } else 688 comperr("bad float rmove: %d %d %x", s, d, t); 689 690 } 691 692 /* 693 * For class c, find worst-case displacement of the number of 694 * registers in the array r[] indexed by class. 695 */ 696 int 697 COLORMAP(int c, int *r) 698 { 699 switch (c) { 700 case CLASSA: 701 return (r[CLASSB] * 2 + r[CLASSA]) < 5; 702 case CLASSB: 703 if (r[CLASSB] > 1) return 0; 704 if (r[CLASSB] == 1 && r[CLASSA] > 0) return 0; 705 if (r[CLASSA] > 2) return 0; 706 return 1; 707 case CLASSC: 708 return r[CLASSC] < 8; 709 } 710 return 0; 711 } 712 713 char *rnames[] = { 714 "r0", "r1", "r2", "r3", "r4", "r5", "sp", "pc", 715 "r01", "r12", "r23", "r34", "XXX", "XXX", "XXX", "XXX", 716 "fr0", "fr1", "fr2", "fr3", "fr4", "fr5", "XXX", "XXX", 717 }; 718 719 /* 720 * Return a class suitable for a specific type. 721 */ 722 int 723 gclass(TWORD t) 724 { 725 if (t < LONG || t > BTMASK) 726 return CLASSA; 727 if (t == LONG || t == ULONG) 728 return CLASSB; 729 if (t == FLOAT || t == DOUBLE || t == LDOUBLE) 730 return CLASSC; 731 comperr("gclass"); 732 return CLASSD; 733 } 734 735 static int 736 argsiz(NODE *p) 737 { 738 TWORD t = p->n_type; 739 740 if (t == LONG || t == ULONG || t == FLOAT) 741 return 4; 742 if (t == DOUBLE) 743 return 8; 744 if (t == STRTY || t == UNIONTY) 745 return p->n_stsize; 746 return 2; 747 } 748 749 /* 750 * Argument specialties. 751 */ 752 void 753 lastcall(NODE *p) 754 { 755 NODE *op = p; 756 int size = 0; 757 758 /* 759 * Calculate arg sizes. 760 * Mark first arg not to have - before it. 761 */ 762 p->n_qual = 0; 763 if (p->n_op != CALL && p->n_op != FORTCALL && p->n_op != STCALL) 764 return; 765 for (p = p->n_right; p->n_op == CM; p = p->n_left) { 766 p->n_right->n_qual = 0; 767 size += argsiz(p->n_right); 768 } 769 p->n_qual = 0; 770 size += argsiz(p); 771 p = op->n_right; 772 773 if (p->n_op == CM) 774 p = p->n_right; 775 if (p->n_type == FLOAT || p->n_type == DOUBLE || 776 p->n_type == STRTY || p->n_type == UNIONTY) 777 op->n_flags |= NLOCAL1; /* Does not use stack slot */ 778 else 779 op->n_flags &= ~NLOCAL1; 780 op->n_qual = size; /* XXX */ 781 } 782 783 static int 784 is1con(NODE *p) 785 { 786 if (p->n_op == ICON && p->n_lval == 1) 787 return 1; 788 return 0; 789 } 790 791 /* 792 * Special shapes. 793 */ 794 int 795 special(NODE *p, int shape) 796 { 797 CONSZ s; 798 799 switch (shape) { 800 case SANDSCON: 801 s = ~p->n_lval; 802 if (s < 65536 || s > -65537) 803 return SRDIR; 804 break; 805 case SINCB: /* Check if subject for post-inc */ 806 if (p->n_op == ASSIGN && p->n_right->n_op == PLUS && 807 treecmp(p->n_left, p->n_right->n_left) && 808 is1con(p->n_right->n_right)) 809 return SRDIR; 810 break; 811 case SARGSUB: 812 if (p->n_op == MINUS && p->n_right->n_op == ICON && 813 p->n_left->n_op == REG) 814 return SRDIR; 815 break; 816 case SARGINC: 817 if (p->n_op == MINUS && is1con(p->n_right)) 818 return special(p->n_left, SINCB); 819 break; 820 } 821 return SRNOPE; 822 } 823 824 /* 825 * Target-dependent command-line options. 826 */ 827 void 828 mflags(char *str) 829 { 830 } 831 832 /* 833 * Do something target-dependent for xasm arguments. 834 */ 835 int 836 myxasm(struct interpass *ip, NODE *p) 837 { 838 return 0; 839 } 840 841 int 842 fldexpand(NODE *p, int cookie, char **cp) 843 { 844 return 0; 845 } 846 847