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