Annotation of gcc/config/vax.c, revision 1.1.1.4

1.1       root        1: /* Subroutines for insn-output.c for Vax.
                      2:    Copyright (C) 1987 Free Software Foundation, Inc.
                      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 2, 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
                     18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     19: 
                     20: #include <stdio.h>
                     21: #include "config.h"
                     22: #include "rtl.h"
                     23: #include "regs.h"
                     24: #include "hard-reg-set.h"
                     25: #include "real.h"
                     26: #include "insn-config.h"
                     27: #include "conditions.h"
                     28: #include "insn-flags.h"
                     29: #include "output.h"
                     30: #include "insn-attr.h"
                     31: 
                     32: 
1.1.1.2   root       33: /* This is like nonimmediate_operand with a restriction on the type of MEM.  */
1.1       root       34: 
                     35: void
                     36: split_quadword_operands (operands, low, n)
                     37:      rtx *operands, *low;
1.1.1.4 ! root       38:      int n;
1.1       root       39: {
                     40:   int i;
                     41:   /* Split operands.  */
                     42: 
                     43:   low[0] = low[1] = low[2] = 0;
                     44:   for (i = 0; i < 3; i++)
                     45:     {
                     46:       if (low[i])
                     47:        /* it's already been figured out */;
                     48:       else if (GET_CODE (operands[i]) == MEM
                     49:               && (GET_CODE (XEXP (operands[i], 0)) == POST_INC))
                     50:        {
                     51:          rtx addr = XEXP (operands[i], 0);
                     52:          operands[i] = low[i] = gen_rtx (MEM, SImode, addr);
                     53:          if (which_alternative == 0 && i == 0)
                     54:            {
                     55:              addr = XEXP (operands[i], 0);
                     56:              operands[i+1] = low[i+1] = gen_rtx (MEM, SImode, addr);
                     57:            }
                     58:        }
                     59:       else
                     60:        {
                     61:          low[i] = operand_subword (operands[i], 0, 0, DImode);
                     62:          operands[i] = operand_subword (operands[i], 1, 0, DImode);
                     63:        }
                     64:     }
                     65: }
                     66: 
                     67: print_operand_address (file, addr)
                     68:      FILE *file;
                     69:      register rtx addr;
                     70: {
                     71:   register rtx reg1, reg2, breg, ireg;
                     72:   rtx offset;
                     73: 
                     74:  retry:
                     75:   switch (GET_CODE (addr))
                     76:     {
                     77:     case MEM:
                     78:       fprintf (file, "*");
                     79:       addr = XEXP (addr, 0);
                     80:       goto retry;
                     81: 
                     82:     case REG:
                     83:       fprintf (file, "(%s)", reg_names[REGNO (addr)]);
                     84:       break;
                     85: 
                     86:     case PRE_DEC:
                     87:       fprintf (file, "-(%s)", reg_names[REGNO (XEXP (addr, 0))]);
                     88:       break;
                     89: 
                     90:     case POST_INC:
                     91:       fprintf (file, "(%s)+", reg_names[REGNO (XEXP (addr, 0))]);
                     92:       break;
                     93: 
                     94:     case PLUS:
                     95:       /* There can be either two or three things added here.  One must be a
                     96:         REG.  One can be either a REG or a MULT of a REG and an appropriate
                     97:         constant, and the third can only be a constant or a MEM.
                     98: 
                     99:         We get these two or three things and put the constant or MEM in
                    100:         OFFSET, the MULT or REG in IREG, and the REG in BREG.  If we have
                    101:         a register and can't tell yet if it is a base or index register,
                    102:         put it into REG1.  */
                    103: 
                    104:       reg1 = 0; ireg = 0; breg = 0; offset = 0;
                    105: 
                    106:       if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
                    107:          || GET_CODE (XEXP (addr, 0)) == MEM)
                    108:        {
                    109:          offset = XEXP (addr, 0);
                    110:          addr = XEXP (addr, 1);
                    111:        }
                    112:       else if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
                    113:               || GET_CODE (XEXP (addr, 1)) == MEM)
                    114:        {
                    115:          offset = XEXP (addr, 1);
                    116:          addr = XEXP (addr, 0);
                    117:        }
                    118:       else if (GET_CODE (XEXP (addr, 1)) == MULT)
                    119:        {
                    120:          ireg = XEXP (addr, 1);
                    121:          addr = XEXP (addr, 0);
                    122:        }
                    123:       else if (GET_CODE (XEXP (addr, 0)) == MULT)
                    124:        {
                    125:          ireg = XEXP (addr, 0);
                    126:          addr = XEXP (addr, 1);
                    127:        }
                    128:       else if (GET_CODE (XEXP (addr, 1)) == REG)
                    129:        {
                    130:          reg1 = XEXP (addr, 1);
                    131:          addr = XEXP (addr, 0);
                    132:        }
1.1.1.2   root      133:       else if (GET_CODE (XEXP (addr, 0)) == REG)
                    134:        {
                    135:          reg1 = XEXP (addr, 0);
                    136:          addr = XEXP (addr, 1);
                    137:        }
1.1       root      138:       else
                    139:        abort ();
                    140: 
                    141:       if (GET_CODE (addr) == REG)
                    142:        {
                    143:          if (reg1)
                    144:            ireg = addr;
                    145:          else
                    146:            reg1 = addr;
                    147:        }
                    148:       else if (GET_CODE (addr) == MULT)
                    149:        ireg = addr;
                    150:       else if (GET_CODE (addr) == PLUS)
                    151:        {
                    152:          if (CONSTANT_ADDRESS_P (XEXP (addr, 0))
                    153:              || GET_CODE (XEXP (addr, 0)) == MEM)
                    154:            {
                    155:              if (offset)
                    156:                {
                    157:                  if (GET_CODE (offset) == CONST_INT)
                    158:                    offset = plus_constant (XEXP (addr, 0), INTVAL (offset));
                    159:                  else if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
                    160:                    offset = plus_constant (offset, INTVAL (XEXP (addr, 0)));
                    161:                  else
                    162:                    abort ();
                    163:                }
                    164:              offset = XEXP (addr, 0);
                    165:            }
                    166:          else if (GET_CODE (XEXP (addr, 0)) == REG)
                    167:            {
                    168:              if (reg1)
                    169:                ireg = reg1, breg = XEXP (addr, 0), reg1 = 0;
                    170:              else
                    171:                reg1 = XEXP (addr, 0);
                    172:            }
                    173:          else if (GET_CODE (XEXP (addr, 0)) == MULT)
                    174:            {
                    175:              if (ireg)
                    176:                abort ();
                    177:              ireg = XEXP (addr, 0);
                    178:            }
                    179:          else
                    180:            abort ();
                    181: 
                    182:          if (CONSTANT_ADDRESS_P (XEXP (addr, 1))
                    183:              || GET_CODE (XEXP (addr, 1)) == MEM)
                    184:            {
                    185:              if (offset)
                    186:                {
                    187:                  if (GET_CODE (offset) == CONST_INT)
                    188:                    offset = plus_constant (XEXP (addr, 1), INTVAL (offset));
                    189:                  else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
                    190:                    offset = plus_constant (offset, INTVAL (XEXP (addr, 1)));
                    191:                  else
                    192:                    abort ();
                    193:                }
                    194:              offset = XEXP (addr, 1);
                    195:            }
                    196:          else if (GET_CODE (XEXP (addr, 1)) == REG)
                    197:            {
                    198:              if (reg1)
                    199:                ireg = reg1, breg = XEXP (addr, 1), reg1 = 0;
                    200:              else
                    201:                reg1 = XEXP (addr, 1);
                    202:            }
                    203:          else if (GET_CODE (XEXP (addr, 1)) == MULT)
                    204:            {
                    205:              if (ireg)
                    206:                abort ();
                    207:              ireg = XEXP (addr, 1);
                    208:            }
                    209:          else
                    210:            abort ();
                    211:        }
                    212:       else
                    213:        abort ();
                    214: 
                    215:       /* If REG1 is non-zero, figure out if it is a base or index register.  */
                    216:       if (reg1)
                    217:        {
                    218:          if (breg != 0 || (offset && GET_CODE (offset) == MEM))
                    219:            {
                    220:              if (ireg)
                    221:                abort ();
                    222:              ireg = reg1;
                    223:            }
                    224:          else
                    225:            breg = reg1;
                    226:        }
                    227: 
                    228:       if (offset != 0)
                    229:        output_address (offset);
                    230: 
                    231:       if (breg != 0)
                    232:        fprintf (file, "(%s)", reg_names[REGNO (breg)]);
                    233: 
                    234:       if (ireg != 0)
                    235:        {
                    236:          if (GET_CODE (ireg) == MULT)
                    237:            ireg = XEXP (ireg, 0);
                    238:          if (GET_CODE (ireg) != REG)
                    239:            abort ();
                    240:          fprintf (file, "[%s]", reg_names[REGNO (ireg)]);
                    241:        }
                    242:       break;
                    243: 
                    244:     default:
                    245:       output_addr_const (file, addr);
                    246:     }
                    247: }
                    248: 
                    249: char *
                    250: rev_cond_name (op)
                    251:      rtx op;
                    252: {
                    253:   switch (GET_CODE (op))
                    254:     {
                    255:     case EQ:
                    256:       return "neq";
                    257:     case NE:
                    258:       return "eql";
                    259:     case LT:
                    260:       return "geq";
                    261:     case LE:
                    262:       return "gtr";
                    263:     case GT:
                    264:       return "leq";
                    265:     case GE:
                    266:       return "lss";
                    267:     case LTU:
                    268:       return "gequ";
                    269:     case LEU:
                    270:       return "gtru";
                    271:     case GTU:
                    272:       return "lequ";
                    273:     case GEU:
                    274:       return "lssu";
                    275: 
                    276:     default:
                    277:       abort ();
                    278:     }
                    279: }
1.1.1.3   root      280: 
                    281: int
                    282: vax_float_literal(c)
                    283:     register rtx c;
                    284: {
                    285:   register enum machine_mode mode;
                    286:   int i;
                    287:   union {double d; int i[2];} val;
                    288: 
                    289:   if (GET_CODE (c) != CONST_DOUBLE)
                    290:     return 0;
                    291: 
                    292:   mode = GET_MODE (c);
                    293: 
                    294:   if (c == const_tiny_rtx[(int) mode][0]
                    295:       || c == const_tiny_rtx[(int) mode][1]
                    296:       || c == const_tiny_rtx[(int) mode][2])
                    297:     return 1;
                    298: 
                    299: #if HOST_FLOAT_FORMAT == VAX_FLOAT_FORMAT
                    300: 
                    301:   val.i[0] = CONST_DOUBLE_LOW (c);
                    302:   val.i[1] = CONST_DOUBLE_HIGH (c);
                    303: 
                    304:   for (i = 0; i < 7; i ++)
                    305:     if (val.d == 1 << i || val.d == 1 / (1 << i))
                    306:       return 1;
                    307: #endif
                    308:   return 0;
                    309: }
                    310: 
                    311: 
                    312: /* Return the cost in cycles of a memory address, relative to register
                    313:    indirect.
                    314: 
                    315:    Each of the following adds the indicated number of cycles:
                    316: 
                    317:    1 - symbolic address
                    318:    1 - pre-decrement
                    319:    1 - indexing and/or offset(register)
                    320:    2 - indirect */
                    321: 
                    322: 
                    323: int vax_address_cost(addr)
                    324:     register rtx addr;
                    325: {
                    326:   int reg = 0, indexed = 0, indir = 0, offset = 0, predec = 0;
                    327:   rtx plus_op0 = 0, plus_op1 = 0;
                    328:  restart:
                    329:   switch (GET_CODE (addr))
                    330:     {
                    331:     case PRE_DEC:
                    332:       predec = 1;
                    333:     case REG:
                    334:     case SUBREG:
                    335:     case POST_INC:
                    336:       reg = 1;
                    337:       break;
                    338:     case MULT:
                    339:       indexed = 1;     /* 2 on VAX 2 */
                    340:       break;
                    341:     case CONST_INT:
                    342:       /* byte offsets cost nothing (on a VAX 2, they cost 1 cycle) */
                    343:       if (offset == 0)
                    344:        offset = (unsigned)(INTVAL(addr)+128) > 256;
                    345:       break;
                    346:     case CONST:
                    347:     case SYMBOL_REF:
                    348:       offset = 1;      /* 2 on VAX 2 */
                    349:       break;
                    350:     case LABEL_REF:    /* this is probably a byte offset from the pc */
                    351:       if (offset == 0)
                    352:        offset = 1;
                    353:       break;
                    354:     case PLUS:
                    355:       if (plus_op0)
                    356:        plus_op1 = XEXP (addr, 0);
                    357:       else
                    358:        plus_op0 = XEXP (addr, 0);
                    359:       addr = XEXP (addr, 1);
                    360:       goto restart;
                    361:     case MEM:
                    362:       indir = 2;       /* 3 on VAX 2 */
                    363:       addr = XEXP (addr, 0);
                    364:       goto restart;
                    365:     }
                    366: 
                    367:   /* Up to 3 things can be added in an address.  They are stored in
                    368:      plus_op0, plus_op1, and addr.  */
                    369: 
                    370:   if (plus_op0)
                    371:     {
                    372:       addr = plus_op0;
                    373:       plus_op0 = 0;
                    374:       goto restart;
                    375:     }
                    376:   if (plus_op1)
                    377:     {
                    378:       addr = plus_op1;
                    379:       plus_op1 = 0;
                    380:       goto restart;
                    381:     }
                    382:   /* Indexing and register+offset can both be used (except on a VAX 2)
                    383:      without increasing execution time over either one alone. */
                    384:   if (reg && indexed && offset)
                    385:     return reg + indir + offset + predec;
                    386:   return reg + indexed + indir + offset + predec;
                    387: }
                    388: 
                    389: 
                    390: /* Cost of an expression on a VAX.  This version has costs tuned for the
                    391:    CVAX chip (found in the VAX 3 series) with comments for variations on
                    392:    other models.  */
                    393: 
                    394: int
                    395: vax_rtx_cost (x)
                    396:     register rtx x;
                    397: {
                    398:   register enum rtx_code code = GET_CODE (x);
                    399:   enum machine_mode mode = GET_MODE (x);
                    400:   register int c;
                    401:   int i = 0;                           /* may be modified in switch */
                    402:   char *fmt = GET_RTX_FORMAT (code);   /* may be modified in switch */
                    403: 
                    404:   switch (code)
                    405:     {
                    406:     case POST_INC:
                    407:       return 2;
                    408:     case PRE_DEC:
                    409:       return 3;
                    410:     case MULT:
                    411:       switch (mode)
                    412:        {
                    413:        case DFmode:
                    414:          c = 16;               /* 4 on VAX 9000 */
                    415:          break;
                    416:        case SFmode:
                    417:          c = 9;                /* 4 on VAX 9000, 12 on VAX 2 */
                    418:          break;
                    419:        case DImode:
                    420:          c = 16;               /* 6 on VAX 9000, 28 on VAX 2 */
                    421:          break;
                    422:        case SImode:
                    423:        case HImode:
                    424:        case QImode:
                    425:          c = 10;               /* 3-4 on VAX 9000, 20-28 on VAX 2 */
                    426:          break;
                    427:        }
                    428:       break;
                    429:     case UDIV:
                    430:       c = 17;
                    431:       break;
                    432:     case DIV:
                    433:       if (mode == DImode)
                    434:        c = 30; /* highly variable */
                    435:       else if (mode == DFmode)
                    436:        /* divide takes 28 cycles if the result is not zero, 13 otherwise */
                    437:        c = 24;
                    438:       else
                    439:        c = 11;                 /* 25 on VAX 2 */
                    440:       break;
                    441:     case MOD:
                    442:       c = 23;
                    443:       break;
                    444:     case UMOD:
                    445:       c = 29;
                    446:       break;
                    447:     case FLOAT:
                    448:       c = 6 + (mode == DFmode) + (GET_MODE (XEXP (x, 0)) != SImode);
                    449:       /* 4 on VAX 9000 */
                    450:       break;
                    451:     case FIX:
                    452:       c = 7;                   /* 17 on VAX 2 */
                    453:       break;
                    454:     case LSHIFT:
                    455:     case ASHIFT:
                    456:     case LSHIFTRT:
                    457:     case ASHIFTRT:
                    458:       if (mode == DImode)
                    459:        c = 12;
                    460:       else
                    461:        c = 10;                 /* 6 on VAX 9000 */
                    462:       break;
                    463:     case ROTATE:
                    464:     case ROTATERT:
                    465:       c = 6;                   /* 5 on VAX 2, 4 on VAX 9000 */
                    466:       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
                    467:        fmt = "e";      /* all constant rotate counts are short */
                    468:       break;
                    469:     case PLUS:
                    470:       /* Check for small negative integer operand: subl2 can be used with
                    471:         a short positive constant instead.  */
                    472:       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
                    473:        if ((unsigned)(INTVAL (XEXP (x, 1)) + 63) < 127)
                    474:          fmt = "e";
                    475:     case MINUS:
                    476:       c = (mode == DFmode) ? 13 : 8;   /* 6/8 on VAX 9000, 16/15 on VAX 2 */
                    477:     case IOR:
                    478:     case XOR:
                    479:       c = 3;
                    480:       break;
                    481:     case AND:
                    482:       /* AND is special because the first operand is complemented. */
                    483:       c = 3;
                    484:       if (GET_CODE (XEXP (x, 0)) == CONST_INT)
                    485:        {
                    486:          if ((unsigned)~INTVAL (XEXP (x, 0)) > 63)
                    487:            c = 4;
                    488:          fmt = "e";
                    489:          i = 1;
                    490:        }
                    491:       break;
                    492:     case NEG:
                    493:       if (mode == DFmode)
                    494:        return 9;
                    495:       else if (mode == SFmode)
                    496:        return 6;
                    497:       else if (mode == DImode)
                    498:        return 4;
                    499:     case NOT:
                    500:       return 2;
                    501:     case ZERO_EXTRACT:
                    502:     case SIGN_EXTRACT:
                    503:       c = 15;
                    504:       break;
                    505:     case MEM:
                    506:       if (mode == DImode || mode == DFmode)
                    507:        c = 5;                          /* 7 on VAX 2 */
                    508:       else
                    509:        c = 3;                          /* 4 on VAX 2 */
                    510:       x = XEXP (x, 0);
                    511:       if (GET_CODE (x) == REG || GET_CODE (x) == POST_INC)
                    512:        return c;
                    513:       return c + vax_address_cost (x);
                    514:     default:
                    515:       c = 3;
                    516:       break;
                    517:     }
                    518: 
                    519: 
                    520:   /* Now look inside the expression.  Operands which are not registers or
                    521:      short constants add to the cost.
                    522: 
                    523:      FMT and I may have been adjusted in the switch above for instructions
                    524:      which require special handling */
                    525: 
                    526:   while (*fmt++ == 'e')
                    527:     {
                    528:       register rtx op = XEXP (x, i++);
                    529:       code = GET_CODE (op);
                    530: 
                    531:       /* A NOT is likely to be found as the first operand of an AND
                    532:         (in which case the relevant cost is of the operand inside
                    533:         the not) and not likely to be found anywhere else.  */
                    534:       if (code == NOT)
                    535:        op = XEXP (op, 0), code = GET_CODE (op);
                    536: 
                    537:       switch (code)
                    538:        {
                    539:        case CONST_INT:
                    540:          if ((unsigned)INTVAL (op) > 63 && GET_MODE (x) != QImode)
                    541:            c += 1;             /* 2 on VAX 2 */
                    542:          break;
                    543:        case CONST:
                    544:        case LABEL_REF:
                    545:        case SYMBOL_REF:
                    546:          c += 1;               /* 2 on VAX 2 */
                    547:          break;
                    548:        case CONST_DOUBLE:
                    549:          if (GET_MODE_CLASS (GET_MODE (op)) == MODE_FLOAT)
                    550:            {
                    551:              /* Registers are faster than floating point constants -- even
                    552:                 those constants which can be encoded in a single byte.  */
                    553:              if (vax_float_literal (op))
                    554:                c++;
                    555:              else
                    556:                c += (GET_MODE (x) == DFmode) ? 3 : 2;
                    557:            }
                    558:          else
                    559:            {
                    560:              if (CONST_DOUBLE_HIGH (op) != 0
                    561:                  || (unsigned)CONST_DOUBLE_LOW (op) > 63)
                    562:                c += 2;
                    563:            }
                    564:          break;
                    565:        case MEM:
                    566:          c += 1;               /* 2 on VAX 2 */
                    567:          if (GET_CODE (XEXP (op, 0)) != REG)
                    568:            c += vax_address_cost (XEXP (op, 0));
                    569:          break;
                    570:        case REG:
                    571:        case SUBREG:
                    572:          break;
                    573:        default:
                    574:          c += 1;
                    575:          break;
                    576:        }
                    577:     }
                    578:   return c;
                    579: }
1.1.1.4 ! root      580: 
        !           581: #ifdef VMS
        !           582: /* Additional support code for VMS. */
        !           583: 
        !           584: #ifdef QSORT_WORKAROUND
        !           585:   /*
        !           586:        Do not use VAXCRTL's qsort() due to a severe bug:  once you've
        !           587:        sorted something which has a size that's an exact multiple of 4
        !           588:        and is longword aligned, you cannot safely sort anything which
        !           589:        is either not a multiple of 4 in size or not longword aligned.
        !           590:        A static "move-by-longword" optimization flag inside qsort() is
        !           591:        never reset.  This is known of affect VMS V4.6 through VMS V5.5-1.
        !           592: 
        !           593:        In this work-around an insertion sort is used for simplicity.
        !           594:        The qsort code from glibc should probably be used instead.
        !           595:    */
        !           596: void
        !           597: not_qsort (array, count, size, compare)
        !           598:      void *array;
        !           599:      unsigned count, size;
        !           600:      int (*compare)();
        !           601: {
        !           602: 
        !           603:   if (size == sizeof (short))
        !           604:     {
        !           605:       register int i;
        !           606:       register short *next, *prev;
        !           607:       short tmp, *base = array;
        !           608: 
        !           609:       for (next = base, i = count - 1; i > 0; i--)
        !           610:        {
        !           611:          prev = next++;
        !           612:          if ((*compare)(next, prev) < 0)
        !           613:            {
        !           614:              tmp = *next;
        !           615:              do  *(prev + 1) = *prev;
        !           616:                while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
        !           617:              *(prev + 1) = tmp;
        !           618:            }
        !           619:        }
        !           620:     }
        !           621:   else if (size == sizeof (long))
        !           622:     {
        !           623:       register int i;
        !           624:       register long *next, *prev;
        !           625:       long tmp, *base = array;
        !           626: 
        !           627:       for (next = base, i = count - 1; i > 0; i--)
        !           628:        {
        !           629:          prev = next++;
        !           630:          if ((*compare)(next, prev) < 0)
        !           631:            {
        !           632:              tmp = *next;
        !           633:              do  *(prev + 1) = *prev;
        !           634:                while (--prev >= base ? (*compare)(&tmp, prev) < 0 : 0);
        !           635:              *(prev + 1) = tmp;
        !           636:            }
        !           637:        }
        !           638:     }
        !           639:   else  /* arbitrary size */
        !           640:     {
        !           641: #ifdef USE_C_ALLOCA
        !           642:       extern void *alloca ();
        !           643: #endif
        !           644:       register int i;
        !           645:       register char *next, *prev, *tmp = alloca (size), *base = array;
        !           646: 
        !           647:       for (next = base, i = count - 1; i > 0; i--)
        !           648:        {   /* count-1 forward iterations */
        !           649:          prev = next,  next += size;           /* increment front pointer */
        !           650:          if ((*compare)(next, prev) < 0)
        !           651:            {   /* found element out of order; move others up then re-insert */
        !           652:              memcpy (tmp, next, size);         /* save smaller element */
        !           653:              do { memcpy (prev + size, prev, size); /* move larger elem. up */
        !           654:                   prev -= size;                /* decrement back pointer */
        !           655:                 } while (prev >= base ? (*compare)(tmp, prev) < 0 : 0);
        !           656:              memcpy (prev + size, tmp, size);  /* restore small element */
        !           657:            }
        !           658:        }
        !           659: #ifdef USE_C_ALLOCA
        !           660:       alloca (0);
        !           661: #endif
        !           662:     }
        !           663: 
        !           664:   return;
        !           665: }
        !           666: #endif /* QSORT_WORKAROUND */
        !           667: 
        !           668: #endif /* VMS */

unix.superglobalmegacorp.com

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