Annotation of gcc/config/convex/convex.c, revision 1.1.1.3

1.1       root        1: /* Subroutines for insn-output.c for Convex.
1.1.1.2   root        2:    Copyright (C) 1988, 1993, 1994 Free Software Foundation, Inc.
1.1       root        3: 
                      4: This file is part of GNU CC.
                      5: 
                      6: GNU CC is free software; you can redistribute it and/or modify
                      7: it under the terms of the GNU General Public License as published by
                      8: the Free Software Foundation; either version 1, or (at your option)
                      9: any later version.
                     10: 
                     11: GNU CC is distributed in the hope that it will be useful,
                     12: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     14: GNU General Public License for more details.
                     15: 
                     16: You should have received a copy of the GNU General Public License
                     17: along with GNU CC; see the file COPYING.  If not, write to
1.1.1.3 ! root       18: the Free Software Foundation, 59 Temple Place - Suite 330,
        !            19: Boston, MA 02111-1307, USA.  */
1.1       root       20: 
                     21: #include "config.h"
                     22: #include "tree.h"
                     23: #include "rtl.h"
                     24: #include "regs.h"
                     25: #include "hard-reg-set.h"
                     26: #include "real.h"
                     27: #include "insn-config.h"
                     28: #include "conditions.h"
                     29: #include "insn-flags.h"
                     30: #include "insn-attr.h"
                     31: #include "output.h"
                     32: #include "expr.h"
                     33: 
                     34: #undef NULL
                     35: #include <stdio.h>
                     36: 
                     37: /* Tables used in convex.h */
                     38: 
                     39: char regno_ok_for_index_p_base[1 + LAST_VIRTUAL_REGISTER + 1];
                     40: enum reg_class regno_reg_class[FIRST_PSEUDO_REGISTER];
                     41: enum reg_class reg_class_from_letter[256];
                     42: 
                     43: /* Target cpu index. */
                     44: 
                     45: int target_cpu;
                     46: 
                     47: /* Boolean to keep track of whether the current section is .text or not.
                     48:    Used by .align handler in convex.h. */
                     49: 
                     50: int current_section_is_text;
                     51: 
                     52: /* Communication between output_compare and output_condjump. */
                     53: 
                     54: static rtx cmp_operand0, cmp_operand1;
                     55: static char cmp_modech;
                     56: 
                     57: /* Forwards */
                     58: 
                     59: static rtx frame_argblock;
                     60: static int frame_argblock_size;
                     61: static rtx convert_arg_pushes ();
                     62: static void expand_movstr_call ();
                     63: 
                     64: /* Here from OVERRIDE_OPTIONS at startup.  Initialize constant tables. */
                     65: 
                     66: init_convex ()
                     67: {
                     68:   int regno;
                     69: 
                     70:   /* Set A and S reg classes. */
                     71:   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                     72:     if (A_REGNO_P (regno))
                     73:       {
                     74:        regno_ok_for_index_p[regno] = 1;
                     75:        regno_reg_class[regno] = INDEX_REGS;
                     76:       }
                     77:     else
                     78:       {
                     79:        regno_ok_for_index_p[regno] = 0;
                     80:        regno_reg_class[regno] = S_REGS;
                     81:       }
                     82: 
                     83:   /* Can't index off the stack pointer, register 0. */
                     84:   regno_ok_for_index_p[STACK_POINTER_REGNUM] = 0;
                     85:   regno_reg_class[STACK_POINTER_REGNUM] = SP_REGS;
                     86: 
                     87:   /* Can't index off aliases of the stack pointer.  */
                     88:   regno_ok_for_index_p[VIRTUAL_INCOMING_ARGS_REGNUM] = 1;
                     89:   regno_ok_for_index_p[VIRTUAL_STACK_VARS_REGNUM] = 1;
                     90:   regno_ok_for_index_p[VIRTUAL_STACK_DYNAMIC_REGNUM] = 0;
                     91:   regno_ok_for_index_p[VIRTUAL_OUTGOING_ARGS_REGNUM] = 0;
                     92: 
                     93:   /* Can't index off hard reg -1 == pseudos not assigned */
                     94:   regno_ok_for_index_p[-1] = 0;
                     95: 
                     96:   /* Set reg class letters */
                     97:   reg_class_from_letter['a'] = A_REGS;
                     98:   reg_class_from_letter['A'] = INDEX_REGS;
                     99:   reg_class_from_letter['d'] = S_REGS;
                    100: 
                    101:   /* Turn off floating point exception enables in the psw. */
                    102:   psw_disable_float ();
                    103: }
                    104: 
                    105: psw_disable_float ()
                    106: {
                    107: #if __convex__ && __GNUC__
                    108:   register int *p;
                    109:   asm ("mov fp,%0" : "=a" (p));
                    110:   while (p)
                    111:     {
                    112:       p[1] &= ~0x1000c400;
                    113:       p = (int *) p[2];
                    114:     }
                    115: #endif  
                    116: }
                    117: 
                    118: /* Here to output code for a compare insn.  Output nothing, just
                    119:    record the operands and their mode. */
                    120: 
                    121: char *
                    122: output_cmp (operand0, operand1, modech)
                    123:      rtx operand0, operand1;
                    124:      char modech;
                    125: {
                    126:   cmp_operand0 = operand0;
                    127:   cmp_operand1 = operand1;
                    128:   cmp_modech = modech;
                    129:   return "";
                    130: }
                    131: 
                    132: /* Output code for a conditional jump.  The preceding instruction
                    133:    is necessarily a compare.  Output two instructions, for example
                    134:        eq.w a1,a2
                    135:        jbra.t L5
                    136:    for
                    137:        (cmpsi a1 a2)
                    138:        (beq L5)
                    139:  */
                    140: 
                    141: char *
                    142: output_condjump (label, cond, jbr_sense)
                    143:      rtx label;
                    144:      char *cond;
                    145:      char jbr_sense;
                    146: {
                    147:   rtx operands[3];
                    148:   char cmp_op[4];
                    149:   char buf[80];
                    150:   char jbr_regch;
                    151: 
                    152:   strcpy (cmp_op, cond);
                    153: 
                    154:   /* [BL] mean the value is being compared against immediate 0.
                    155:      Use neg.x, which produces the same carry that eq.x #0 would if it
                    156:      existed.  In this case operands[1] is a scratch register, not a
                    157:      compare operand. */
                    158: 
                    159:   if (cmp_modech == 'B' || cmp_modech == 'L')
                    160:     {
                    161:       cmp_modech = cmp_modech - 'A' + 'a';
                    162:       strcpy (cmp_op, "neg");
                    163:     }
                    164: 
                    165:   /* [WH] mean the value being compared resulted from "add.[wh] #-1,rk"
                    166:      when rk was nonnegative -- we can omit equality compares against -1
                    167:      or inequality compares against 0. */
                    168: 
                    169:   else if (cmp_modech == 'W' || cmp_modech == 'H')
                    170:     {
                    171:       if (! strcmp (cmp_op, "eq") && cmp_operand1 == constm1_rtx)
                    172:        jbr_sense ^= 't' ^ 'f';
                    173:       else if (! strcmp (cmp_op, "lt") && cmp_operand1 == const0_rtx)
                    174:        ;
                    175:       else
                    176:        cmp_modech = cmp_modech - 'A' + 'a';
                    177:     }
                    178: 
                    179:   /* Constant must be first; swap operands if necessary.
                    180:      If lt, le, ltu, leu are swapped, change to le, lt, leu, ltu
                    181:      and reverse the sense of the jump. */
                    182: 
                    183:   if (! REG_P (cmp_operand1))
                    184:     {
                    185:       operands[0] = cmp_operand1;
                    186:       operands[1] = cmp_operand0;
                    187:       if (cmp_op[0] == 'l')
                    188:        {
                    189:          cmp_op[1] ^= 'e' ^ 't';
                    190:          jbr_sense ^= 't' ^ 'f';
                    191:        }
                    192:     }
                    193:   else
                    194:     {
                    195:       operands[0] = cmp_operand0;
                    196:       operands[1] = cmp_operand1;
                    197:     }
                    198: 
                    199:   operands[2] = label;
                    200: 
                    201:   if (S_REG_P (operands[1]))
                    202:     jbr_regch = 's';
                    203:   else if (A_REG_P (operands[1]))
                    204:     jbr_regch = 'a';
                    205:   else
                    206:     abort ();
                    207: 
                    208:   if (cmp_modech == 'W' || cmp_modech == 'H')
                    209:     sprintf (buf, "jbr%c.%c %%l2", jbr_regch, jbr_sense);
                    210:   else
                    211:     sprintf (buf, "%s.%c %%0,%%1\n\tjbr%c.%c %%l2",
                    212:             cmp_op, cmp_modech, jbr_regch, jbr_sense);
                    213:   output_asm_insn (buf, operands);
                    214:   return "";
                    215: }
                    216: 
                    217: /* Return 1 if OP is valid for cmpsf.
                    218:    In IEEE mode, +/- zero compares are not handled by 
                    219:      the immediate versions of eq.s and on some machines, lt.s, and le.s.  
                    220:    So disallow 0.0 as the immediate operand of xx.s compares in IEEE mode. */
                    221: 
                    222: int
                    223: nonmemory_cmpsf_operand (op, mode)
                    224:      rtx op;
                    225:      enum machine_mode mode;
                    226: {
                    227: #if _IEEE_FLOAT_
                    228:   if (op == CONST0_RTX (SFmode))
                    229:     return 0;
                    230: #endif
                    231: 
                    232:   return nonmemory_operand (op, mode);
                    233: }
                    234: 
                    235: /* Convex /bin/as does not like unary minus in some contexts.
                    236:    Simplify CONST addresses to remove it. */
                    237: 
                    238: rtx
                    239: simplify_for_convex (x)
                    240:      rtx x;
                    241: {
                    242:   switch (GET_CODE (x))
                    243:     {
                    244:     case MINUS:
                    245:       if (GET_CODE (XEXP (x, 1)) == CONST_INT
                    246:          && INTVAL (XEXP (x, 1)) < 0)
                    247:        {
                    248:          PUT_CODE (x, PLUS);
                    249:          XEXP (x, 1) = GEN_INT (- INTVAL (XEXP (x, 1)));
                    250:        }
                    251:       break;
                    252: 
                    253:     case CONST:
                    254:       return simplify_for_convex (XEXP (x, 0));
                    255:     }
                    256: 
                    257:   return x;
                    258: }
                    259: 
                    260: /* Routines to separate CONST_DOUBLEs into component parts. */
                    261: 
                    262: int
                    263: const_double_high_int (x)
                    264:      rtx x;
                    265: {
                    266:   if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
                    267:     return CONST_DOUBLE_LOW (x);
                    268:   else
                    269:     return CONST_DOUBLE_HIGH (x);
                    270: }
                    271: 
                    272: int
                    273: const_double_low_int (x)
                    274:      rtx x;
                    275: {
                    276:   if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
                    277:     return CONST_DOUBLE_HIGH (x);
                    278:   else
                    279:     return CONST_DOUBLE_LOW (x);
                    280: }
                    281: 
                    282: /* Inline block copy. */
                    283: 
                    284: void
                    285: expand_movstr (operands)
                    286:      rtx *operands;
                    287: {
                    288:   rtx dest = operands[0];
                    289:   rtx src = operands[1];
                    290:   int align = INTVAL (operands[3]);
                    291:   int nregs, maxsize;
                    292:   unsigned len;
                    293:   enum machine_mode mode;
                    294:   rtx reg, load, store, prev_store, prev_store_2;
                    295:   int size;
                    296: 
                    297:   /* Decide how many regs to use, depending on load latency, and what
                    298:      size pieces to move, depending on whether machine does unaligned
                    299:      loads and stores efficiently. */
                    300: 
                    301:   if (TARGET_C1)
                    302:     {
                    303:       /* ld.l latency is 4, no alignment problems. */
                    304:       nregs = 3, maxsize = 8;
                    305:     }
                    306:   else if (TARGET_C2)
                    307:     {
                    308:       /* loads are latency 2 if we avoid ld.l not at least word aligned. */
                    309:       if (align >= 4)
                    310:        nregs = 2, maxsize = 8;
                    311:       else
                    312:        nregs = 2, maxsize = 4;
                    313:     }
                    314:   else if (TARGET_C34)
                    315:     {
                    316:       /* latency is 4 if aligned, horrible if not. */
                    317:       nregs = 3, maxsize = align;
                    318:     }
                    319:   else if (TARGET_C38)
                    320:     {
                    321:       /* latency is 2 if at least word aligned, 3 or 4 if unaligned. */
                    322:       if (align >= 4)
                    323:        nregs = 2, maxsize = 8;
                    324:       else
                    325:        nregs = 3, maxsize = 8;
                    326:     }
                    327:   else
                    328:     abort ();
                    329: 
                    330:   /* Caller is not necessarily prepared for us to fail in this
                    331:      expansion.  So fall back by generating memcpy call here. */
                    332: 
                    333:   if (GET_CODE (operands[2]) != CONST_INT
                    334:       || (len = INTVAL (operands[2])) > (unsigned) 32 * maxsize)
                    335:     {
                    336:       expand_movstr_call (operands);
                    337:       return;
                    338:     }
                    339: 
                    340:   reg = 0;
                    341:   prev_store = prev_store_2 = 0;
                    342: 
                    343:   while (len > 0)
                    344:     {
                    345:       if (len >= 8 && maxsize >= 8)
                    346:        mode = DImode;
                    347:       else if (len >= 4 && maxsize >= 4)
                    348:        mode = SImode;
                    349:       else if (len >= 2 && maxsize >= 2)
                    350:        mode = HImode;
                    351:       else
                    352:        mode = QImode;
                    353: 
                    354:       /* If no temp pseudo to reuse, or not the right mode, make one */
                    355:       if (! reg || GET_MODE (reg) != mode)
                    356:        reg = gen_reg_rtx (mode);
                    357: 
                    358:       /* Get src and dest in the right mode */
                    359:       if (GET_MODE (src) != mode)
                    360:        src = change_address (src, mode, 0),
                    361:        dest = change_address (dest, mode, 0);
                    362: 
                    363:       /* Make load and store patterns for this piece */
                    364:       load = gen_rtx (SET, VOIDmode, reg, src);
                    365:       store = gen_rtx (SET, VOIDmode, dest, reg);
                    366: 
                    367:       /* Emit the load and the store from last time. 
                    368:         When we emit a store, we can reuse its temp reg. */
                    369:       emit_insn (load);
                    370:       if (prev_store)
                    371:        {
                    372:          reg = SET_SRC (prev_store);
                    373:          emit_insn (prev_store);
                    374:        }
                    375:       else
                    376:        reg = 0;
                    377: 
                    378:       /* Queue up the store, for next time or the time after that. */
                    379:       if (nregs == 2)
                    380:        prev_store = store;
                    381:       else
                    382:        prev_store = prev_store_2, prev_store_2 = store;
                    383: 
                    384:       /* Advance to next piece. */
                    385:       size = GET_MODE_SIZE (mode);
                    386:       src = adj_offsettable_operand (src, size);
                    387:       dest = adj_offsettable_operand (dest, size);
                    388:       len -= size;
                    389:     }
                    390: 
                    391:   /* Finally, emit the last stores. */
                    392:   if (prev_store)
                    393:     emit_insn (prev_store);
                    394:   if (prev_store_2)
                    395:     emit_insn (prev_store_2);
                    396: }
                    397: 
                    398: static void
                    399: expand_movstr_call (operands)
                    400:      rtx *operands;
                    401: {
                    402:   emit_library_call (gen_rtx (SYMBOL_REF, Pmode, "memcpy"), 0,
                    403:                     VOIDmode, 3,
                    404:                     XEXP (operands[0], 0), Pmode,
                    405:                     XEXP (operands[1], 0), Pmode,
                    406:                     operands[2], SImode);
                    407: }
                    408: 
                    409: #if _IEEE_FLOAT_
                    410: #define MAX_FLOAT 3.4028234663852886e+38
                    411: #define MIN_FLOAT 1.1754943508222875e-38
                    412: #else
                    413: #define MAX_FLOAT 1.7014117331926443e+38
                    414: #define MIN_FLOAT 2.9387358770557188e-39
                    415: #endif
                    416: 
1.1.1.2   root      417: int
                    418: check_float_value (mode, dp, overflow)
1.1       root      419:      enum machine_mode mode;
                    420:      REAL_VALUE_TYPE *dp;
1.1.1.2   root      421:      int overflow;
1.1       root      422: {
                    423:   REAL_VALUE_TYPE d = *dp;
                    424: 
1.1.1.2   root      425:   if (overflow)
                    426:     {
                    427:       *dp = MAX_FLOAT;
                    428:       return 1;
                    429:     }
                    430: 
1.1       root      431:   if (mode == SFmode)
                    432:     {
                    433:       if (d > MAX_FLOAT)
                    434:        {
                    435:          *dp = MAX_FLOAT;
1.1.1.2   root      436:          return 1;
1.1       root      437:        }
                    438:       else if (d < -MAX_FLOAT)
                    439:        {
                    440:          *dp = -MAX_FLOAT;
1.1.1.2   root      441:          return 1;
1.1       root      442:        }       
                    443:       else if ((d > 0 && d < MIN_FLOAT) || (d < 0 && d > -MIN_FLOAT))
                    444:        {
                    445:          *dp = 0.0;
1.1.1.2   root      446:          return 1;
1.1       root      447:        }
                    448:     }
1.1.1.2   root      449: 
                    450:   return 0;
1.1       root      451: }
                    452: 
                    453: /* Output the label at the start of a function.
                    454:    Precede it with the number of formal args so debuggers will have
                    455:    some idea of how many args to print. */
                    456: 
                    457: void
                    458: asm_declare_function_name (file, name, decl)
                    459:     FILE *file;
                    460:     char *name;
                    461:     tree decl;
                    462: {
                    463:   tree parms;
                    464:   int nargs = list_length (DECL_ARGUMENTS (decl));
                    465: 
                    466:   char *p, c;
                    467:   extern char *version_string;
                    468:   static char vers[4];
                    469:   int i;
                    470:   
                    471:   p = version_string;
                    472:   for (i = 0; i < 3; ) {
                    473:     c = *p;
                    474:     if (c - '0' < (unsigned) 10)
                    475:       vers[i++] = c;
                    476:     if (c == 0 || c == ' ')
                    477:       vers[i++] = '0';
                    478:     else
                    479:       p++;
                    480:   }
                    481:   fprintf (file, "\tds.b \"g%s\"\n", vers);
                    482: 
                    483:   if (nargs < 100)
                    484:     fprintf (file, "\tds.b \"+%02d\\0\"\n", nargs);
                    485:   else
                    486:     fprintf (file, "\tds.b \"+00\\0\"\n");
                    487: 
                    488:   ASM_OUTPUT_LABEL (file, name);
                    489: }
                    490: 
                    491: /* Print an instruction operand X on file FILE.
                    492:    CODE is the code from the %-spec that requested printing this operand;
                    493:    if `%z3' was used to print operand 3, then CODE is 'z'. */
                    494: /* Convex codes:
                    495:     %u prints a CONST_DOUBLE's high word
                    496:     %v prints a CONST_DOUBLE's low word
                    497:     %z prints a CONST_INT shift count as a multiply operand -- viz. 1 << n.
                    498:  */
                    499: 
                    500: print_operand (file, x, code)
                    501:      FILE *file;
                    502:      rtx x;
                    503:      char code;
                    504: {
                    505:   long u[2];
                    506:   REAL_VALUE_TYPE d;
                    507: 
                    508:   switch (GET_CODE (x))
                    509:     {
                    510:     case REG:
                    511:       fprintf (file, "%s", reg_names[REGNO (x)]);
                    512:       break;
                    513: 
                    514:     case MEM:
                    515:       output_address (XEXP (x, 0));
                    516:       break;
                    517: 
                    518:     case CONST_DOUBLE:
                    519:       REAL_VALUE_FROM_CONST_DOUBLE (d, x);
                    520:       switch (GET_MODE (x)) {
                    521:       case DFmode:
                    522: #if 0 /* doesn't work, produces dfloats */
                    523:        REAL_VALUE_TO_TARGET_DOUBLE (d, u); 
                    524: #else
                    525:        {
                    526:          union { double d; int i[2]; } t;
                    527:          t.d = d;
                    528:          u[0] = t.i[0];
                    529:          u[1] = t.i[1];
                    530:        }
                    531: #endif
                    532:        if (code == 'u')
                    533:          fprintf (file, "#%#x", u[0]);
                    534:        else if (code == 'v')
                    535:          fprintf (file, "#%#x", u[1]);
                    536:        else
                    537:          outfloat (file, d, "%.17e", "#", "");
                    538:        break;
                    539:       case SFmode:
                    540:        outfloat (file, d, "%.9e", "#", "");
                    541:        break;
                    542:       default:
                    543:        if (code == 'u')
                    544:          fprintf (file, "#%d", CONST_DOUBLE_HIGH (x));
                    545:        else
                    546:          fprintf (file, "#%d", CONST_DOUBLE_LOW (x));
                    547:       }
                    548:       break;
                    549: 
                    550:     default:
                    551:       if (code == 'z')
                    552:        {
                    553:          if (GET_CODE (x) != CONST_INT)
                    554:            abort ();
                    555:          fprintf (file, "#%d", 1 << INTVAL (x));
                    556:        }
                    557:       else
                    558:        {
                    559:          putc ('#', file);
                    560:          output_addr_const (file, x);
                    561:        }
                    562:     }
                    563: }
                    564: 
                    565: /* Print a memory operand whose address is X, on file FILE. */
                    566: 
                    567: print_operand_address (file, addr)
                    568:      FILE *file;
                    569:      rtx addr;
                    570: {
                    571:   rtx index = 0;
                    572:   rtx offset = 0;
                    573: 
                    574:   if (GET_CODE (addr) == MEM)
                    575:     {
                    576:       fprintf (file, "@");
                    577:       addr = XEXP (addr, 0);
                    578:     }
                    579: 
                    580:   switch (GET_CODE (addr))
                    581:     {
                    582:     case REG:
                    583:       index = addr;
                    584:       break;
                    585: 
                    586:     case PLUS:
                    587:       index = XEXP (addr, 0);
                    588:       if (REG_P (index))
                    589:        offset = XEXP (addr, 1);
                    590:       else
                    591:        {
                    592:          offset = XEXP (addr, 0);
                    593:          index = XEXP (addr, 1);
                    594:          if (! REG_P (index))
                    595:            abort ();
                    596:         }
                    597:       break;
                    598: 
                    599:     default:
                    600:       offset = addr;
                    601:       break;
                    602:     }
                    603: 
                    604:   if (offset)
                    605:     output_addr_const (file, offset);
                    606: 
                    607:   if (index)
                    608:     fprintf (file, "(%s)", reg_names[REGNO (index)]);
                    609: }
                    610: 
                    611: /* Output a float to FILE, value VALUE, format FMT, preceded by PFX
                    612:    and followed by SFX. */
                    613: 
                    614: outfloat (file, value, fmt, pfx, sfx)
                    615:      FILE *file;
                    616:      REAL_VALUE_TYPE value;
                    617:      char *fmt, *pfx, *sfx;
                    618: {
                    619:   char buf[64];
                    620:   fputs (pfx, file);
                    621:   REAL_VALUE_TO_DECIMAL (value, fmt, buf);
                    622:   fputs (buf, file);
                    623:   fputs (sfx, file);
                    624: }
                    625: 
                    626: /* Here during RTL generation of return.  If we are at the final return
                    627:    in a function, go through the function and replace pushes with stores
                    628:    into a frame arg block.  This is similar to what ACCUMULATE_OUTGOING_ARGS
                    629:    does, but we must index off the frame pointer, not the stack pointer,
                    630:    and the calling sequence does not require the arg block to be at the
                    631:    top of the stack.  */
                    632: 
                    633: replace_arg_pushes ()
                    634: {
                    635:   /* Doesn't work yet. */
                    636: }
                    637: 
                    638: /* Output the insns needed to do a call.  operands[] are
                    639:      0 - MEM, the place to call
                    640:      1 - CONST_INT, the number of bytes in the arg list
                    641:      2 - CONST_INT, the number of arguments
                    642:      3 - CONST_INT, the number of bytes to pop
                    643:      4 - address of the arg list.  
                    644:  */
                    645: 
                    646: char *
                    647: output_call (insn, operands)
                    648:      rtx insn, *operands;
                    649: {
                    650:   if (operands[4] == stack_pointer_rtx)
                    651:     output_asm_insn ("mov sp,ap", operands);
                    652:   else
                    653:     abort ();
                    654: 
                    655:   if (TARGET_ARGCOUNT)
                    656:     output_asm_insn ("pshea %a2", operands);
                    657: 
                    658:   output_asm_insn ("calls %0", operands);
                    659: 
                    660:   output_asm_insn ("ld.w 12(fp),ap", operands);
                    661: 
                    662:   if (operands[4] == stack_pointer_rtx && operands[3] != const0_rtx)
                    663:     output_asm_insn ("add.w %3,sp", operands);
                    664: 
                    665:   return "";
                    666: }
                    667: 
                    668: 
                    669: /* Here after reloading, before the second scheduling pass. */
                    670: 
                    671: emit_ap_optimizations ()
                    672: {
                    673:   /* Removed for now. */
                    674: }
                    675: 

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.