Annotation of gcc/config/ns32k.c, revision 1.1.1.2

1.1       root        1: /* Subroutines for assembler code output on the NS32000.
                      2:    Copyright (C) 1988 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: /* Some output-actions in ns32k.md need these.  */
                     21: #include <stdio.h>
                     22: #include "config.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 "output.h"
                     31: #include "insn-attr.h"
                     32: 
                     33: #ifdef OSF_OS
                     34: int ns32k_num_files = 0;
                     35: #endif
                     36: 
                     37: void
                     38: trace (s, s1, s2)
                     39:      char *s, *s1, *s2;
                     40: {
                     41:     fprintf (stderr, s, s1, s2);
                     42: }
                     43: 
                     44: /* Value is 1 if hard register REGNO can hold a value of machine-mode MODE. */ 
                     45: 
                     46: int
                     47: hard_regno_mode_ok( regno, mode )
                     48: int regno;
                     49: int mode;
                     50: {
                     51:        switch( mode ) {
                     52:                case QImode:
                     53:                case HImode:
                     54:                case PSImode:
                     55:                case SImode:
                     56:                case PDImode:
                     57:                case VOIDmode:
                     58:                case BLKmode:
                     59:                        if( (regno < 8) || (regno == 16) || (regno == 17) ) {
                     60:                                return( 1 );
                     61:                        }
                     62:                        else {
                     63:                                return( 0 );
                     64:                        }
                     65: 
                     66:                case DImode:
                     67:                        if( (regno < 8) && ((regno & 1) == 0) ) {
                     68:                                return( 1 );
                     69:                        }
                     70:                        else {
                     71:                                return( 0 );
                     72:                        }
                     73: 
                     74: 
                     75:                case SFmode:
                     76:                case SCmode:
                     77:                        if( TARGET_32081 ) {
                     78:                                if( regno < 16 ) {
                     79:                                        return( 1 );
                     80:                                }
                     81:                                else {
                     82:                                        return( 0 );
                     83:                                }
                     84:                        }
                     85:                        else {
                     86:                                if( regno < 8 ) {
                     87:                                        return( 1 );
                     88:                                }
                     89:                                else {
                     90:                                        return( 0 );
                     91:                                }
                     92:                        }
                     93: 
                     94:                case DFmode:
                     95:                case DCmode:
                     96:                        if( (regno & 1) == 0 ) {
                     97:                                if( TARGET_32081 ) {
                     98:                                        if( regno < 16 ) {
                     99:                                                return( 1 );
                    100:                                        }
                    101:                                        else {
                    102:                                                return( 0 );
                    103:                                        }
                    104:                                }
                    105:                                else {
                    106:                                        if( regno < 8 ) {
                    107:                                                return( 1 );
                    108:                                        }
                    109:                                        else {
                    110:                                                return( 0 );
                    111:                                        }
                    112:                                }
                    113:                        }
                    114:                        else {
                    115:                                return( 0 );
                    116:                        }
                    117:  
                    118:                case XFmode:
                    119:                        abort( 0 );
                    120:                case CCmode:
                    121:                        abort( 0 );
                    122:                case TImode:
                    123:                        abort( 0 );
                    124:                case XCmode:    
                    125:                        abort( 0 );
                    126:                case TFmode:
                    127:                        abort( 0 );
                    128:                case TCmode:
                    129:                        abort( 0 );
                    130: 
                    131: 
                    132:                default:
                    133:                        fprintf( stderr, "cant match mode %d\n", mode );
                    134:                        abort( 0 );
                    135:        }
                    136:        abort(0);
                    137: }
                    138: 
                    139: /* ADDRESS_COST calls this.  This function is not optimal
                    140:    for the 32032 & 32332, but it probably is better than
                    141:    the default. */
                    142: 
                    143: int
                    144: calc_address_cost (operand)
                    145:      rtx operand;
                    146: {
                    147:   int i;
                    148:   int cost = 0;
                    149:   
                    150:   if (GET_CODE (operand) == MEM)
                    151:     cost += 3;
                    152:   if (GET_CODE (operand) == MULT)
                    153:     cost += 2;
                    154: #if 0
                    155:   if (GET_CODE (operand) == REG)
                    156:     cost += 1;                 /* not really, but the documentation
                    157:                                   says different amount of registers
                    158:                                   shouldn't return the same costs */
                    159: #endif
                    160:   switch (GET_CODE (operand))
                    161:     {
                    162:     case REG:
                    163:     case CONST:
                    164:     case CONST_INT:
                    165:     case CONST_DOUBLE:
                    166:     case SYMBOL_REF:
                    167:     case LABEL_REF:
                    168:     case POST_DEC:
                    169:     case PRE_DEC:
                    170:       break;
                    171:     case MULT:
                    172:     case MEM:
                    173:     case PLUS:
                    174:       for (i = 0; i < GET_RTX_LENGTH (GET_CODE (operand)); i++)
                    175:        {
                    176:          cost += calc_address_cost (XEXP (operand, i));
                    177:        }
                    178:     default:
                    179:       break;
                    180:     }
                    181:   return cost;
                    182: }
                    183: 
                    184: /* Return the register class of a scratch register needed to copy IN into
                    185:    or out of a register in CLASS in MODE.  If it can be done directly,
                    186:    NO_REGS is returned.  */
                    187: 
                    188: enum reg_class
                    189: secondary_reload_class (class, mode, in)
                    190:      enum reg_class class;
                    191:      enum machine_mode mode;
                    192:      rtx in;
                    193: {
                    194:   int regno = true_regnum (in);
                    195: 
                    196:   if (regno >= FIRST_PSEUDO_REGISTER)
                    197:     regno = -1;
                    198: 
                    199:   /* We can place anything into GENERAL_REGS and can put GENERAL_REGS
                    200:      into anything.  */
                    201:   if (class == GENERAL_REGS || (regno >= 0 && regno < 8))
                    202:     return NO_REGS;
                    203: 
                    204:   /* Constants, memory, and FP registers can go into FP registers */
                    205:   if ((regno == -1 || (regno >= 8 && regno < 16)) && (class == FLOAT_REGS))
                    206:     return NO_REGS;
                    207: 
                    208:   /* Otherwise, we need GENERAL_REGS. */
                    209:   return GENERAL_REGS;
                    210: }
                    211: /* Generate the rtx that comes from an address expression in the md file */
                    212: /* The expression to be build is BASE[INDEX:SCALE].  To recognize this,
                    213:    scale must be converted from an exponent (from ASHIFT) to a
1.1.1.2 ! root      214:    multiplier (for MULT). */
1.1       root      215: rtx
                    216: gen_indexed_expr (base, index, scale)
                    217:      rtx base, index, scale;
                    218: {
                    219:   rtx addr;
                    220: 
                    221:   /* This generates an illegal addressing mode, if BASE is
                    222:      fp or sp.  This is handled by PRINT_OPERAND_ADDRESS.  */
                    223:   if (GET_CODE (base) != REG && GET_CODE (base) != CONST_INT)
                    224:     base = gen_rtx (MEM, SImode, base);
                    225:   addr = gen_rtx (MULT, SImode, index,
                    226:                  gen_rtx (CONST_INT, VOIDmode, 1 << INTVAL (scale)));
                    227:   addr = gen_rtx (PLUS, SImode, base, addr);
                    228:   return addr;
                    229: }
                    230: 
                    231: /* Return 1 if OP is a valid operand of mode MODE.  This
                    232:    predicate rejects operands which do not have a mode
                    233:    (such as CONST_INT which are VOIDmode).  */
                    234: int
                    235: reg_or_mem_operand (op, mode)
                    236:      register rtx op;
                    237:      enum machine_mode mode;
                    238: {
                    239:   return (GET_MODE (op) == mode
                    240:          && (GET_CODE (op) == REG
                    241:              || GET_CODE (op) == SUBREG
                    242:              || GET_CODE (op) == MEM));
                    243: }
                    244: 
                    245: /* Return the best assembler insn template
                    246:    for moving operands[1] into operands[0] as a fullword.  */
                    247: 
                    248: static char *
                    249: singlemove_string (operands)
                    250:      rtx *operands;
                    251: {
                    252:   if (GET_CODE (operands[1]) == CONST_INT
                    253:       && INTVAL (operands[1]) <= 7
                    254:       && INTVAL (operands[1]) >= -8)
                    255:     return "movqd %1,%0";
                    256:   return "movd %1,%0";
                    257: }
                    258: 
                    259: char *
                    260: output_move_double (operands)
                    261:      rtx *operands;
                    262: {
                    263:   enum anon1 { REGOP, OFFSOP, POPOP, CNSTOP, RNDOP } optype0, optype1;
                    264:   rtx latehalf[2];
                    265: 
                    266:   /* First classify both operands.  */
                    267: 
                    268:   if (REG_P (operands[0]))
                    269:     optype0 = REGOP;
                    270:   else if (offsettable_memref_p (operands[0]))
                    271:     optype0 = OFFSOP;
                    272:   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
                    273:     optype0 = POPOP;
                    274:   else
                    275:     optype0 = RNDOP;
                    276: 
                    277:   if (REG_P (operands[1]))
                    278:     optype1 = REGOP;
                    279:   else if (CONSTANT_ADDRESS_P (operands[1])
                    280:           || GET_CODE (operands[1]) == CONST_DOUBLE)
                    281:     optype1 = CNSTOP;
                    282:   else if (offsettable_memref_p (operands[1]))
                    283:     optype1 = OFFSOP;
                    284:   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
                    285:     optype1 = POPOP;
                    286:   else
                    287:     optype1 = RNDOP;
                    288: 
                    289:   /* Check for the cases that the operand constraints are not
                    290:      supposed to allow to happen.  Abort if we get one,
                    291:      because generating code for these cases is painful.  */
                    292: 
                    293:   if (optype0 == RNDOP || optype1 == RNDOP)
                    294:     abort ();
                    295: 
                    296:   /* Ok, we can do one word at a time.
                    297:      Normally we do the low-numbered word first,
                    298:      but if either operand is autodecrementing then we
                    299:      do the high-numbered word first.
                    300: 
                    301:      In either case, set up in LATEHALF the operands to use
                    302:      for the high-numbered word and in some cases alter the
                    303:      operands in OPERANDS to be suitable for the low-numbered word.  */
                    304: 
                    305:   if (optype0 == REGOP)
                    306:     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
                    307:   else if (optype0 == OFFSOP)
                    308:     latehalf[0] = adj_offsettable_operand (operands[0], 4);
                    309:   else
                    310:     latehalf[0] = operands[0];
                    311: 
                    312:   if (optype1 == REGOP)
                    313:     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
                    314:   else if (optype1 == OFFSOP)
                    315:     latehalf[1] = adj_offsettable_operand (operands[1], 4);
                    316:   else if (optype1 == CNSTOP)
                    317:     {
                    318:       if (CONSTANT_ADDRESS_P (operands[1]))
                    319:        latehalf[1] = const0_rtx;
                    320:       else if (GET_CODE (operands[1]) == CONST_DOUBLE)
                    321:        split_double (operands[1], &operands[1], &latehalf[1]);
                    322:     }
                    323:   else
                    324:     latehalf[1] = operands[1];
                    325: 
                    326:   /* If one or both operands autodecrementing,
                    327:      do the two words, high-numbered first.  */
                    328: 
                    329:   if (optype0 == POPOP || optype1 == POPOP)
                    330:     {
                    331:       output_asm_insn (singlemove_string (latehalf), latehalf);
                    332:       return singlemove_string (operands);
                    333:     }
                    334: 
                    335:   /* Not autodecrementing.  Do the two words, low-numbered first.  */
                    336: 
                    337:   output_asm_insn (singlemove_string (operands), operands);
                    338: 
                    339:   operands[0] = latehalf[0];
                    340:   operands[1] = latehalf[1];
                    341:   return singlemove_string (operands);
                    342: }
                    343: 
                    344: int
                    345: check_reg (oper, reg)
                    346:      rtx oper;
                    347:      int reg;
                    348: {
                    349:   register int i;
                    350: 
                    351:   if (oper == 0)
                    352:     return 0;
                    353:   switch (GET_CODE(oper))
                    354:     {
                    355:     case REG:
                    356:       return (REGNO(oper) == reg) ? 1 : 0;
                    357:     case MEM:
                    358:       return check_reg(XEXP(oper, 0), reg);
                    359:     case PLUS:
                    360:     case MULT:
                    361:       return check_reg(XEXP(oper, 0), reg) || check_reg(XEXP(oper, 1), reg);
                    362:     }
                    363:   return 0;
                    364: }
                    365: 
                    366: /* PRINT_OPERAND is defined to call this function,
                    367:    which is easier to debug than putting all the code in
                    368:    a macro definition in ns32k.h.  */
                    369: 
                    370: void
                    371: print_operand (file, x, code)
                    372:      FILE *file;
                    373:      rtx x;
                    374:      char code;
                    375: {
                    376:   if (code == '$')
                    377:     PUT_IMMEDIATE_PREFIX(file);
                    378:   else if (code == '?')
                    379:     PUT_EXTERNAL_PREFIX(file);
                    380:   else if (GET_CODE (x) == REG)
                    381:     fprintf (file, "%s", reg_names[REGNO (x)]);
                    382:   else if (GET_CODE (x) == MEM)
1.1.1.2 ! root      383:     {
        !           384:       rtx tmp = XEXP (x, 0);
        !           385: #ifndef PC_RELATIVE
        !           386:       if (GET_CODE (tmp) == SYMBOL_REF || GET_CODE (tmp) == LABEL_REF)
        !           387:        {
        !           388:          char *out = XSTR (tmp, 0);
        !           389:          if (out[0] == '*')
        !           390:            fprintf (file, "@%s", &out[1]);
        !           391:          else
        !           392:            ASM_OUTPUT_LABELREF (file, out);
        !           393:        }
        !           394:       else
        !           395: #endif
        !           396:        output_address (XEXP (x, 0));
        !           397:     }
1.1       root      398:   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode)
1.1.1.2 ! root      399:     {
        !           400:       if (GET_MODE (x) == DFmode)
        !           401:        { 
        !           402:          union { double d; int i[2]; } u;
        !           403:          u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
        !           404:          PUT_IMMEDIATE_PREFIX(file);
        !           405: #ifdef SEQUENT_ASM
        !           406:          /* Sequent likes it's floating point constants as integers */
        !           407:          fprintf (file, "0Dx%08x%08x", u.i[1], u.i[0])l
        !           408: #else
        !           409: #ifdef ENCORE_ASM
        !           410:          fprintf (file, "0f%.20e", u.d); 
        !           411: #else
        !           412:          fprintf (file, "0d%.20e", u.d); 
        !           413: #endif
        !           414: #endif
        !           415:        }
        !           416:       else
        !           417:        { 
        !           418:          union { double d; int i[2]; } u;
        !           419:          u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
        !           420:          PUT_IMMEDIATE_PREFIX(file);
        !           421: #ifdef SEQUENT_ASM
        !           422:          {
        !           423:            union { float f; long l; } uu;
        !           424:            uu.f = u.d;
        !           425:            fprintf (file, "0Fx%08x", uu.l);
        !           426:          }
        !           427: #else
        !           428:          fprintf (file, "0f%.20e", u.d); 
        !           429: #endif
        !           430:        }
        !           431:     }
1.1       root      432:   else
                    433:     {
                    434:       PUT_IMMEDIATE_PREFIX(file);
                    435:       output_addr_const (file, x);
                    436:     }
                    437: }
                    438: 
                    439: /* PRINT_OPERAND_ADDRESS is defined to call this function,
                    440:    which is easier to debug than putting all the code in
                    441:    a macro definition in ns32k.h .  */
                    442: 
                    443: /* Completely rewritten to get this to work with Gas for PC532 Mach.
                    444:    This function didn't work and I just wasn't able (nor very willing) to
                    445:    figure out how it worked.
                    446:    90-11-25 Tatu Yl|nen <[email protected]> */
                    447: 
                    448: print_operand_address (file, addr)
                    449:      register FILE *file;
                    450:      register rtx addr;
                    451: {
                    452:   static char scales[] = { 'b', 'w', 'd', 0, 'q', };
                    453:   rtx offset, base, indexexp, tmp;
                    454:   int scale;
                    455: 
                    456:   if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC)
                    457:     {
                    458:       fprintf (file, "tos");
                    459:       return;
                    460:     }
                    461: 
                    462:   offset = NULL;
                    463:   base = NULL;
                    464:   indexexp = NULL;
                    465:   while (addr != NULL)
                    466:     {
                    467:       if (GET_CODE (addr) == PLUS)
                    468:        {
                    469:          if (GET_CODE (XEXP (addr, 0)) == PLUS)
                    470:            {
                    471:              tmp = XEXP (addr, 1);
                    472:              addr = XEXP (addr, 0);
                    473:            }
                    474:          else
                    475:            {
                    476:              tmp = XEXP (addr,0);
                    477:              addr = XEXP (addr,1);
                    478:            }
                    479:        }
                    480:       else
                    481:        {
                    482:          tmp = addr;
                    483:          addr = NULL;
                    484:        }
                    485:       switch (GET_CODE (tmp))
                    486:        {
                    487:        case PLUS:
                    488:          abort ();
                    489:        case MEM:
                    490:          if (base)
                    491:            {
                    492:              indexexp = base;
                    493:              base = tmp;
                    494:            }
                    495:          else
                    496:            base = tmp;
                    497:          break;
                    498:        case REG:
                    499:          if (REGNO (tmp) < 8)
                    500:            if (base)
                    501:              {
                    502:                indexexp = tmp;
                    503:              }
                    504:            else
                    505:              base = tmp;
                    506:          else
                    507:            if (base)
                    508:              {
                    509:                indexexp = base;
                    510:                base = tmp;
                    511:              }
                    512:            else
                    513:              base = tmp;
                    514:          break;
                    515:        case MULT:
                    516:          indexexp = tmp;
                    517:          break;
                    518:        case CONST:
                    519:        case CONST_INT:
                    520:        case SYMBOL_REF:
                    521:        case LABEL_REF:
                    522:          if (offset)
                    523:            offset = gen_rtx (PLUS, SImode, tmp, offset);
                    524:          else
                    525:            offset = tmp;
                    526:          break;
                    527:        default:
                    528:          abort ();
                    529:        }
                    530:     }
                    531:   if (! offset)
                    532:     offset = const0_rtx;
                    533:   /* now, offset, base and indexexp are set */
                    534:   if (! base)
                    535:     {
1.1.1.2 ! root      536: #if defined (PC_RELATIVE) || defined (NO_ABSOLUTE_PREFIX_IF_SYMBOLIC)
        !           537:       if (! (GET_CODE (offset) == LABEL_REF
        !           538:             || GET_CODE (offset) == SYMBOL_REF))
1.1       root      539: #endif
                    540:        PUT_ABSOLUTE_PREFIX (file);
                    541:     }
                    542: 
1.1.1.2 ! root      543:   output_addr_const (file, offset);
1.1       root      544:   if (base) /* base can be (REG ...) or (MEM ...) */
                    545:     switch (GET_CODE (base))
                    546:       {
                    547:        /* now we must output base.  Possible alternatives are:
                    548:           (rN)       (REG ...)
                    549:           (sp) (REG ...)
                    550:           (fp)       (REG ...)
                    551:           (pc)       (REG ...)  used for SYMBOL_REF and LABEL_REF, output
                    552:           (disp(fp)) (MEM ...)       just before possible [rX:y]
                    553:           (disp(sp)) (MEM ...)
                    554:           (disp(sb)) (MEM ...)
                    555:           */
                    556:       case REG:
                    557:        fprintf (file, "(%s)", reg_names[REGNO (base)]);
                    558:        break;
                    559:       case MEM:
                    560:        addr = XEXP(base,0);
                    561:        base = NULL;
                    562:        offset = NULL;
                    563:        while (addr != NULL)
                    564:          {
                    565:            if (GET_CODE (addr) == PLUS)
                    566:              {
                    567:                if (GET_CODE (XEXP (addr, 0)) == PLUS)
                    568:                  {
                    569:                    tmp = XEXP (addr, 1);
                    570:                    addr = XEXP (addr, 0);
                    571:                  }
                    572:                else
                    573:                  {
                    574:                    tmp = XEXP (addr, 0);
                    575:                    addr = XEXP (addr, 1);
                    576:                  }
                    577:              }
                    578:            else
                    579:              {
                    580:                tmp = addr;
                    581:                addr = NULL;
                    582:              }
                    583:            switch (GET_CODE (tmp))
                    584:              {
                    585:              case REG:
                    586:                base = tmp;
                    587:                break;
                    588:              case CONST:
                    589:              case CONST_INT:
                    590:              case SYMBOL_REF:
                    591:              case LABEL_REF:
                    592:                if (offset)
                    593:                  offset = gen_rtx (PLUS, SImode, tmp, offset);
                    594:                else
                    595:                  offset = tmp;
                    596:                break;
                    597:              default:
                    598:                abort ();
                    599:              }
                    600:          }
                    601:        if (! offset)
                    602:          offset = const0_rtx;
                    603:        fprintf (file, "(");
                    604:        output_addr_const (file, offset);
                    605:        if (base)
                    606:          fprintf (file, "(%s)", reg_names[REGNO (base)]);
1.1.1.2 ! root      607: #ifdef BASE_REG_NEEDED
1.1       root      608:        else if (TARGET_SB)
                    609:          fprintf (file, "(sb)");
                    610:        else
                    611:          abort ();
1.1.1.2 ! root      612: #endif
1.1       root      613:        fprintf (file, ")");
                    614:        break;
                    615: 
                    616:       default:
                    617:        abort ();
                    618:       }
                    619: #ifdef PC_RELATIVE
                    620:   else                         /* no base */
                    621:     if (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF)
                    622:       fprintf (file, "(pc)");
                    623: #endif
                    624: #ifdef BASE_REG_NEEDED         /* this is defined if the assembler always
                    625:                                   needs a base register */
                    626:     else if (TARGET_SB)
                    627:       fprintf (file, "(sb)");
                    628:     else
                    629:       abort ();
                    630: #endif
                    631:   /* now print index if we have one */
                    632:   if (indexexp)
                    633:     {
                    634:       if (GET_CODE (indexexp) == MULT)
                    635:        {
                    636:          scale = INTVAL (XEXP (indexexp, 1)) >> 1;
                    637:          indexexp = XEXP (indexexp, 0);
                    638:        }
                    639:       else
                    640:        scale = 0;
                    641:       if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8)
                    642:        abort ();
                    643: 
                    644:       fprintf (file, "[%s:%c]",
                    645:               reg_names[REGNO (indexexp)],
                    646:               scales[scale]);
                    647:     }
                    648: }
                    649: 
                    650: /* National 32032 shifting is so bad that we can get
                    651:    better performance in many common cases by using other
                    652:    techniques.  */
                    653: char *
                    654: output_shift_insn (operands)
                    655:      rtx *operands;
                    656: {
                    657:   if (GET_CODE (operands[2]) == CONST_INT
                    658:       && INTVAL (operands[2]) > 0
                    659:       && INTVAL (operands[2]) <= 3)
                    660:     if (GET_CODE (operands[0]) == REG)
                    661:       {
                    662:        if (GET_CODE (operands[1]) == REG)
                    663:          {
                    664:            if (REGNO (operands[0]) == REGNO (operands[1]))
                    665:              {
                    666:                if (operands[2] == const1_rtx)
                    667:                  return "addd %0,%0";
                    668:                else if (INTVAL (operands[2]) == 2)
                    669:                  return "addd %0,%0\n\taddd %0,%0";
                    670:              }
                    671:            if (operands[2] == const1_rtx)
                    672:              return "movd %1,%0\n\taddd %0,%0";
                    673:            
                    674:            operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
                    675:            return "addr %a1,%0";
                    676:          }
                    677:        if (operands[2] == const1_rtx)
                    678:          return "movd %1,%0\n\taddd %0,%0";
                    679:       }
                    680:     else if (GET_CODE (operands[1]) == REG)
                    681:       {
                    682:        operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
                    683:        return "addr %a1,%0";
                    684:       }
                    685:     else if (INTVAL (operands[2]) == 1
                    686:             && GET_CODE (operands[1]) == MEM
                    687:             && rtx_equal_p (operands [0], operands[1]))
                    688:       {
                    689:        rtx temp = XEXP (operands[1], 0);
                    690:        
                    691:        if (GET_CODE (temp) == REG
                    692:            || (GET_CODE (temp) == PLUS
                    693:                && GET_CODE (XEXP (temp, 0)) == REG
                    694:                && GET_CODE (XEXP (temp, 1)) == CONST_INT))
                    695:          return "addd %0,%0";
                    696:       }
                    697:     else return "ashd %2,%0";
                    698:   return "ashd %2,%0";
                    699: }

unix.superglobalmegacorp.com

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