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

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
        !           214:    muliplier (for MULT). */
        !           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)
        !           383:     output_address (XEXP (x, 0));
        !           384:   else if (GET_CODE (x) == CONST_DOUBLE && GET_MODE (x) != DImode)
        !           385:     if (GET_MODE (x) == DFmode)
        !           386:       { 
        !           387:         union { double d; int i[2]; } u;
        !           388:        u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
        !           389:        PUT_IMMEDIATE_PREFIX(file);
        !           390:        fprintf (file, "0d%.20e", u.d); 
        !           391:       }
        !           392:     else
        !           393:       { 
        !           394:         union { double d; int i[2]; } u;
        !           395:        u.i[0] = CONST_DOUBLE_LOW (x); u.i[1] = CONST_DOUBLE_HIGH (x);
        !           396:        PUT_IMMEDIATE_PREFIX(file);
        !           397:        fprintf (file, "0f%.20e", u.d); 
        !           398:       }
        !           399:   else
        !           400:     {
        !           401:       PUT_IMMEDIATE_PREFIX(file);
        !           402:       output_addr_const (file, x);
        !           403:     }
        !           404: }
        !           405: 
        !           406: /* PRINT_OPERAND_ADDRESS is defined to call this function,
        !           407:    which is easier to debug than putting all the code in
        !           408:    a macro definition in ns32k.h .  */
        !           409: 
        !           410: /* Completely rewritten to get this to work with Gas for PC532 Mach.
        !           411:    This function didn't work and I just wasn't able (nor very willing) to
        !           412:    figure out how it worked.
        !           413:    90-11-25 Tatu Yl|nen <[email protected]> */
        !           414: 
        !           415: print_operand_address (file, addr)
        !           416:      register FILE *file;
        !           417:      register rtx addr;
        !           418: {
        !           419:   static char scales[] = { 'b', 'w', 'd', 0, 'q', };
        !           420:   rtx offset, base, indexexp, tmp;
        !           421:   int scale;
        !           422: 
        !           423:   if (GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_DEC)
        !           424:     {
        !           425:       fprintf (file, "tos");
        !           426:       return;
        !           427:     }
        !           428: 
        !           429:   offset = NULL;
        !           430:   base = NULL;
        !           431:   indexexp = NULL;
        !           432:   while (addr != NULL)
        !           433:     {
        !           434:       if (GET_CODE (addr) == PLUS)
        !           435:        {
        !           436:          if (GET_CODE (XEXP (addr, 0)) == PLUS)
        !           437:            {
        !           438:              tmp = XEXP (addr, 1);
        !           439:              addr = XEXP (addr, 0);
        !           440:            }
        !           441:          else
        !           442:            {
        !           443:              tmp = XEXP (addr,0);
        !           444:              addr = XEXP (addr,1);
        !           445:            }
        !           446:        }
        !           447:       else
        !           448:        {
        !           449:          tmp = addr;
        !           450:          addr = NULL;
        !           451:        }
        !           452:       switch (GET_CODE (tmp))
        !           453:        {
        !           454:        case PLUS:
        !           455:          abort ();
        !           456:        case MEM:
        !           457:          if (base)
        !           458:            {
        !           459:              indexexp = base;
        !           460:              base = tmp;
        !           461:            }
        !           462:          else
        !           463:            base = tmp;
        !           464:          break;
        !           465:        case REG:
        !           466:          if (REGNO (tmp) < 8)
        !           467:            if (base)
        !           468:              {
        !           469:                indexexp = tmp;
        !           470:              }
        !           471:            else
        !           472:              base = tmp;
        !           473:          else
        !           474:            if (base)
        !           475:              {
        !           476:                indexexp = base;
        !           477:                base = tmp;
        !           478:              }
        !           479:            else
        !           480:              base = tmp;
        !           481:          break;
        !           482:        case MULT:
        !           483:          indexexp = tmp;
        !           484:          break;
        !           485:        case CONST:
        !           486:        case CONST_INT:
        !           487:        case SYMBOL_REF:
        !           488:        case LABEL_REF:
        !           489:          if (offset)
        !           490:            offset = gen_rtx (PLUS, SImode, tmp, offset);
        !           491:          else
        !           492:            offset = tmp;
        !           493:          break;
        !           494:        default:
        !           495:          abort ();
        !           496:        }
        !           497:     }
        !           498:   if (! offset)
        !           499:     offset = const0_rtx;
        !           500:   /* now, offset, base and indexexp are set */
        !           501:   if (! base)
        !           502: #ifdef PC_RELATIVE
        !           503:     {
        !           504:       if (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF)
        !           505:        ;
        !           506:       else
        !           507: #endif
        !           508:        PUT_ABSOLUTE_PREFIX (file);
        !           509: #ifdef PC_RELATIVE
        !           510:     }
        !           511: #endif
        !           512: 
        !           513:   output_addr_const (file,offset);
        !           514:   if (base) /* base can be (REG ...) or (MEM ...) */
        !           515:     switch (GET_CODE (base))
        !           516:       {
        !           517:        /* now we must output base.  Possible alternatives are:
        !           518:           (rN)       (REG ...)
        !           519:           (sp) (REG ...)
        !           520:           (fp)       (REG ...)
        !           521:           (pc)       (REG ...)  used for SYMBOL_REF and LABEL_REF, output
        !           522:           (disp(fp)) (MEM ...)       just before possible [rX:y]
        !           523:           (disp(sp)) (MEM ...)
        !           524:           (disp(sb)) (MEM ...)
        !           525:           */
        !           526:       case REG:
        !           527:        fprintf (file, "(%s)", reg_names[REGNO (base)]);
        !           528:        break;
        !           529:       case MEM:
        !           530:        addr = XEXP(base,0);
        !           531:        base = NULL;
        !           532:        offset = NULL;
        !           533:        while (addr != NULL)
        !           534:          {
        !           535:            if (GET_CODE (addr) == PLUS)
        !           536:              {
        !           537:                if (GET_CODE (XEXP (addr, 0)) == PLUS)
        !           538:                  {
        !           539:                    tmp = XEXP (addr, 1);
        !           540:                    addr = XEXP (addr, 0);
        !           541:                  }
        !           542:                else
        !           543:                  {
        !           544:                    tmp = XEXP (addr, 0);
        !           545:                    addr = XEXP (addr, 1);
        !           546:                  }
        !           547:              }
        !           548:            else
        !           549:              {
        !           550:                tmp = addr;
        !           551:                addr = NULL;
        !           552:              }
        !           553:            switch (GET_CODE (tmp))
        !           554:              {
        !           555:              case REG:
        !           556:                base = tmp;
        !           557:                break;
        !           558:              case CONST:
        !           559:              case CONST_INT:
        !           560:              case SYMBOL_REF:
        !           561:              case LABEL_REF:
        !           562:                if (offset)
        !           563:                  offset = gen_rtx (PLUS, SImode, tmp, offset);
        !           564:                else
        !           565:                  offset = tmp;
        !           566:                break;
        !           567:              default:
        !           568:                abort ();
        !           569:              }
        !           570:          }
        !           571:        if (! offset)
        !           572:          offset = const0_rtx;
        !           573:        fprintf (file, "(");
        !           574:        output_addr_const (file, offset);
        !           575:        if (base)
        !           576:          fprintf (file, "(%s)", reg_names[REGNO (base)]);
        !           577:        else if (TARGET_SB)
        !           578:          fprintf (file, "(sb)");
        !           579:        else
        !           580:          abort ();
        !           581:        fprintf (file, ")");
        !           582:        break;
        !           583: 
        !           584:       default:
        !           585:        abort ();
        !           586:       }
        !           587: #ifdef PC_RELATIVE
        !           588:   else                         /* no base */
        !           589:     if (GET_CODE (offset) == LABEL_REF || GET_CODE (offset) == SYMBOL_REF)
        !           590:       fprintf (file, "(pc)");
        !           591: #endif
        !           592: #ifdef BASE_REG_NEEDED         /* this is defined if the assembler always
        !           593:                                   needs a base register */
        !           594:     else if (TARGET_SB)
        !           595:       fprintf (file, "(sb)");
        !           596:     else
        !           597:       abort ();
        !           598: #endif
        !           599:   /* now print index if we have one */
        !           600:   if (indexexp)
        !           601:     {
        !           602:       if (GET_CODE (indexexp) == MULT)
        !           603:        {
        !           604:          scale = INTVAL (XEXP (indexexp, 1)) >> 1;
        !           605:          indexexp = XEXP (indexexp, 0);
        !           606:        }
        !           607:       else
        !           608:        scale = 0;
        !           609:       if (GET_CODE (indexexp) != REG || REGNO (indexexp) >= 8)
        !           610:        abort ();
        !           611: 
        !           612:       fprintf (file, "[%s:%c]",
        !           613:               reg_names[REGNO (indexexp)],
        !           614:               scales[scale]);
        !           615:     }
        !           616: }
        !           617: 
        !           618: /* National 32032 shifting is so bad that we can get
        !           619:    better performance in many common cases by using other
        !           620:    techniques.  */
        !           621: char *
        !           622: output_shift_insn (operands)
        !           623:      rtx *operands;
        !           624: {
        !           625:   if (GET_CODE (operands[2]) == CONST_INT
        !           626:       && INTVAL (operands[2]) > 0
        !           627:       && INTVAL (operands[2]) <= 3)
        !           628:     if (GET_CODE (operands[0]) == REG)
        !           629:       {
        !           630:        if (GET_CODE (operands[1]) == REG)
        !           631:          {
        !           632:            if (REGNO (operands[0]) == REGNO (operands[1]))
        !           633:              {
        !           634:                if (operands[2] == const1_rtx)
        !           635:                  return "addd %0,%0";
        !           636:                else if (INTVAL (operands[2]) == 2)
        !           637:                  return "addd %0,%0\n\taddd %0,%0";
        !           638:              }
        !           639:            if (operands[2] == const1_rtx)
        !           640:              return "movd %1,%0\n\taddd %0,%0";
        !           641:            
        !           642:            operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
        !           643:            return "addr %a1,%0";
        !           644:          }
        !           645:        if (operands[2] == const1_rtx)
        !           646:          return "movd %1,%0\n\taddd %0,%0";
        !           647:       }
        !           648:     else if (GET_CODE (operands[1]) == REG)
        !           649:       {
        !           650:        operands[1] = gen_indexed_expr (const0_rtx, operands[1], operands[2]);
        !           651:        return "addr %a1,%0";
        !           652:       }
        !           653:     else if (INTVAL (operands[2]) == 1
        !           654:             && GET_CODE (operands[1]) == MEM
        !           655:             && rtx_equal_p (operands [0], operands[1]))
        !           656:       {
        !           657:        rtx temp = XEXP (operands[1], 0);
        !           658:        
        !           659:        if (GET_CODE (temp) == REG
        !           660:            || (GET_CODE (temp) == PLUS
        !           661:                && GET_CODE (XEXP (temp, 0)) == REG
        !           662:                && GET_CODE (XEXP (temp, 1)) == CONST_INT))
        !           663:          return "addd %0,%0";
        !           664:       }
        !           665:     else return "ashd %2,%0";
        !           666:   return "ashd %2,%0";
        !           667: }

unix.superglobalmegacorp.com

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