Annotation of GNUtools/cc/config/gmicro/gmicro.c, revision 1.1

1.1     ! root        1: /* Subroutines for insn-output.c for the Gmicro.
        !             2:    Ported by Masanobu Yuhara, Fujitsu Laboratories LTD.
        !             3:    ([email protected])
        !             4: 
        !             5:    Copyright (C) 1990, 1991 Free Software Foundation, Inc.
        !             6: 
        !             7: This file is part of GNU CC.
        !             8: 
        !             9: GNU CC is free software; you can redistribute it and/or modify
        !            10: it under the terms of the GNU General Public License as published by
        !            11: the Free Software Foundation; either version 2, or (at your option)
        !            12: any later version.
        !            13: 
        !            14: GNU CC is distributed in the hope that it will be useful,
        !            15: but WITHOUT ANY WARRANTY; without even the implied warranty of
        !            16: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
        !            17: GNU General Public License for more details.
        !            18: 
        !            19: Among other things, the copyright
        !            20: notice and this notice must be preserved on all copies.
        !            21: 
        !            22: You should have received a copy of the GNU General Public License
        !            23: along with GNU CC; see the file COPYING.  If not, write to
        !            24: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
        !            25: 
        !            26: 
        !            27: #include <stdio.h>
        !            28: #include "config.h"
        !            29: #include "rtl.h"
        !            30: #include "regs.h"
        !            31: #include "hard-reg-set.h"
        !            32: #include "real.h"
        !            33: #include "insn-config.h"
        !            34: #include "conditions.h"
        !            35: #include "insn-flags.h"
        !            36: #include "output.h"
        !            37: #include "insn-attr.h"
        !            38: 
        !            39: extern char *rtx_name[];
        !            40: 
        !            41: mypr (s, a1, a2, a3, a4, a5)
        !            42:      char *s;
        !            43:      int a1, a2, a3, a4, a5;
        !            44: {
        !            45:   fprintf (stderr, s, a1, a2, a3, a4, a5);
        !            46: }
        !            47: 
        !            48: myprcode (i)
        !            49:      int i;
        !            50: {
        !            51:   if (i < 0 || i > 90)
        !            52:     fprintf (stderr, "code = %d\n", i);
        !            53:   else
        !            54:     fprintf (stderr, "code = %s\n", rtx_name[i]);
        !            55: }
        !            56: 
        !            57: myabort (i)
        !            58:      int i;
        !            59: {
        !            60:   fprintf (stderr, "myabort");
        !            61:   myprcode (i);
        !            62: }
        !            63: 
        !            64: 
        !            65: /* This is how to output an ascii string.  */
        !            66: /* See ASM_OUTPUT_ASCII in gmicro.h.  */
        !            67: output_ascii (file, p, size)
        !            68:      FILE *file;
        !            69:      char *p;
        !            70:      int size;
        !            71: {
        !            72:   int i;
        !            73:   int in_quote = 0;
        !            74:   register int c;
        !            75: 
        !            76:   fprintf (file, "\t.sdata ");
        !            77: 
        !            78:   for (i = 0; i < size; i++) 
        !            79:     {
        !            80:       c = p[i];
        !            81:       if (c >= ' ' && c < 0x7f) 
        !            82:        {
        !            83:          if (!in_quote) 
        !            84:            {
        !            85:              putc ('"', file);
        !            86:              in_quote = 1;
        !            87:            }
        !            88:          putc (c, file);
        !            89:        }
        !            90:       else 
        !            91:        {
        !            92:          if (in_quote) 
        !            93:            {
        !            94:              putc ('"', file);
        !            95:              in_quote = 0;
        !            96:            }
        !            97:          fprintf (file, "<%d>", c);
        !            98:        }
        !            99:     }
        !           100:   if (in_quote)
        !           101:     putc ('"', file);
        !           102:   putc ('\n', file);
        !           103: }
        !           104: 
        !           105: 
        !           106: /* call this when GET_CODE (index) is MULT. */
        !           107: print_scaled_index (file, index)
        !           108:      FILE *file;
        !           109:      register rtx index;
        !           110: {
        !           111:   register rtx ireg;
        !           112:   int scale;
        !           113: 
        !           114:   if (GET_CODE (XEXP (index, 0)) == REG) 
        !           115:     {
        !           116:       ireg = XEXP (index, 0);
        !           117:       scale = INTVAL (XEXP (index, 1));
        !           118:     }
        !           119:   else 
        !           120:     {
        !           121:       ireg = XEXP (index, 1);
        !           122:       scale = INTVAL (XEXP (index, 0));
        !           123:     }
        !           124:   if (scale == 1)
        !           125:     fprintf (file, "%s", reg_names[REGNO (ireg)]);
        !           126:   else
        !           127:     fprintf (file, "%s*%d", reg_names[REGNO (ireg)], scale);
        !           128: }
        !           129:     
        !           130: 
        !           131: print_operand_address (file, addr)
        !           132:      FILE *file;
        !           133:      register rtx addr;
        !           134: {
        !           135:   register rtx xtmp0, xtmp1, breg, ixreg;
        !           136:   int scale;
        !           137:   int needcomma = 0;
        !           138:   rtx offset;
        !           139: 
        !           140:   fprintf (file, "@");
        !           141:  retry:
        !           142:   switch (GET_CODE (addr)) 
        !           143:     {
        !           144:     case MEM:
        !           145:       fprintf (file, "@");
        !           146:       addr = XEXP (addr, 0);
        !           147:       goto retry;
        !           148: 
        !           149:     case REG:
        !           150:       fprintf (file, "%s", reg_names[REGNO (addr)]);
        !           151:       break;
        !           152: 
        !           153:     case MULT:
        !           154:       print_scaled_index (file, addr);
        !           155:       break;
        !           156: 
        !           157:     case PRE_DEC:
        !           158:       fprintf (file, "-%s", reg_names[REGNO (XEXP (addr, 0))]);
        !           159:       break;
        !           160: 
        !           161:     case POST_INC:
        !           162:       fprintf (file, "%s+", reg_names[REGNO (XEXP (addr, 0))]);
        !           163:       break;
        !           164: 
        !           165:     case PLUS:
        !           166:       xtmp0 = XEXP (addr, 0);
        !           167:       xtmp1 = XEXP (addr, 1);
        !           168:       ixreg = 0;       breg = 0;
        !           169:       offset = 0;
        !           170:       if (CONSTANT_ADDRESS_P (xtmp0)) 
        !           171:        {
        !           172:          offset = xtmp0;
        !           173:          breg = xtmp1;
        !           174:        }
        !           175:       else if (CONSTANT_ADDRESS_P (xtmp1)) 
        !           176:        {
        !           177:          offset = xtmp1;
        !           178:          breg = xtmp0;
        !           179:        }
        !           180:       else 
        !           181:        {
        !           182:          goto NOT_DISP;
        !           183:        }
        !           184: 
        !           185:       if (REG_CODE_BASE_P (breg))
        !           186:        goto PRINT_MEM;
        !           187: 
        !           188:       if (GET_CODE (breg) == MULT) 
        !           189:        {
        !           190:          if (REG_CODE_INDEX_P (XEXP (breg, 0))) 
        !           191:            {
        !           192:              ixreg = XEXP (breg, 0);
        !           193:              scale = INTVAL (XEXP (breg, 1));
        !           194:              breg = 0;
        !           195:            }
        !           196:          else 
        !           197:            {
        !           198:              ixreg = XEXP (breg, 1);
        !           199:              scale = INTVAL (XEXP (breg, 0));
        !           200:              breg = 0;
        !           201:            }
        !           202:          goto PRINT_MEM;
        !           203:        }
        !           204: 
        !           205:       /* GET_CODE (breg) must be PLUS here. */
        !           206:       xtmp0 = XEXP (breg, 0);
        !           207:       xtmp1 = XEXP (breg, 1);
        !           208:       if (REG_CODE_BASE_P (xtmp0)) 
        !           209:        {
        !           210:          breg = xtmp0;
        !           211:          xtmp0 = xtmp1;
        !           212:        }
        !           213:       else 
        !           214:        {
        !           215:          breg = xtmp1;
        !           216:          /* xtmp0 = xtmp0; */
        !           217:        }
        !           218: 
        !           219:       if (GET_CODE (xtmp0) == MULT) 
        !           220:        {
        !           221:          if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 
        !           222:            {
        !           223:              ixreg = XEXP (xtmp0, 0);
        !           224:              scale = INTVAL (XEXP (xtmp0, 1));
        !           225:            }
        !           226:          else 
        !           227:            {
        !           228:              ixreg = XEXP (xtmp0, 1);
        !           229:              scale = INTVAL (XEXP (xtmp0, 0));
        !           230:            }
        !           231:        }
        !           232:       else 
        !           233:        {
        !           234:          ixreg = xtmp0;
        !           235:          scale = 1;
        !           236:        }
        !           237:       goto PRINT_MEM;
        !           238: 
        !           239:     NOT_DISP:
        !           240:       if (REG_CODE_BASE_P (xtmp0)) 
        !           241:        {
        !           242:          breg = xtmp0;
        !           243:          xtmp0 = xtmp1;
        !           244:        }
        !           245:       else if (REG_CODE_BASE_P (xtmp1)) 
        !           246:        {
        !           247:          breg = xtmp1;
        !           248:          /* xtmp0 = xtmp0; */
        !           249:        }
        !           250:       else
        !           251:        goto NOT_BASE;
        !           252:     
        !           253:       if (REG_CODE_INDEX_P (xtmp0)) 
        !           254:        {
        !           255:          ixreg = xtmp0;
        !           256:          scale = 1;
        !           257:          goto PRINT_MEM;
        !           258:        }
        !           259:       else if (CONSTANT_ADDRESS_P (xtmp0)) 
        !           260:        {
        !           261:          offset = xtmp0;
        !           262:          goto PRINT_MEM;
        !           263:        }
        !           264:       else if (GET_CODE (xtmp0) == MULT) 
        !           265:        {
        !           266:          if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 
        !           267:            {
        !           268:              ixreg = XEXP (xtmp0, 0);
        !           269:              scale = INTVAL (XEXP (xtmp0, 1));
        !           270:            }
        !           271:          else 
        !           272:            {
        !           273:              ixreg = XEXP (xtmp0, 1);
        !           274:              scale = INTVAL (XEXP (xtmp0, 0));
        !           275:            }
        !           276:          goto PRINT_MEM;
        !           277:        }
        !           278: 
        !           279:       /* GET_CODE (xtmp0) must be PLUS. */
        !           280:       xtmp1 = XEXP (xtmp0, 1);
        !           281:       xtmp0 = XEXP (xtmp0, 0);
        !           282: 
        !           283:       if (CONSTANT_ADDRESS_P (xtmp0)) 
        !           284:        {
        !           285:          offset = xtmp0;
        !           286:          xtmp0 = xtmp1;
        !           287:        }
        !           288:       else 
        !           289:        {
        !           290:          offset = xtmp1;
        !           291:          /* xtmp0 = xtmp0; */
        !           292:        }
        !           293: 
        !           294:       if (REG_CODE_INDEX_P (xtmp0)) 
        !           295:        {
        !           296:          ixreg = xtmp0;
        !           297:        }
        !           298:       else 
        !           299:        {                       /* GET_CODE (xtmp0) must be MULT. */
        !           300:          if (REG_CODE_INDEX_P (XEXP (xtmp0, 0))) 
        !           301:            {
        !           302:              ixreg = XEXP (xtmp0, 0);
        !           303:              scale = INTVAL (XEXP (xtmp0, 1));
        !           304:            }
        !           305:          else 
        !           306:            {
        !           307:              ixreg = XEXP (xtmp0, 1);
        !           308:              scale = INTVAL (XEXP (xtmp0, 0));
        !           309:            }
        !           310:        }
        !           311:       goto PRINT_MEM;
        !           312: 
        !           313:     NOT_BASE:
        !           314:       if (GET_CODE (xtmp0) == PLUS) 
        !           315:        {
        !           316:          ixreg = xtmp1;
        !           317:          /* xtmp0 = xtmp0; */
        !           318:        }
        !           319:       else 
        !           320:        {
        !           321:          ixreg = xtmp0;
        !           322:          xtmp0 = xtmp1;
        !           323:        }
        !           324: 
        !           325:       if (REG_CODE_INDEX_P (ixreg)) 
        !           326:        {
        !           327:          scale = 1;
        !           328:        }
        !           329:       else if (REG_CODE_INDEX_P (XEXP (ixreg, 0))) 
        !           330:        {
        !           331:          scale = INTVAL (XEXP (ixreg, 1));
        !           332:          ixreg = XEXP (ixreg, 0);
        !           333:        }
        !           334:       else 
        !           335:        {                       /* was else if with no condition. OK ??? */
        !           336:          scale = INTVAL (XEXP (ixreg, 0));
        !           337:          ixreg = XEXP (ixreg, 1);
        !           338:        }
        !           339: 
        !           340:       if (REG_CODE_BASE_P (XEXP (xtmp0, 0))) 
        !           341:        {
        !           342:          breg = XEXP (xtmp0, 0);
        !           343:          offset = XEXP (xtmp0, 1);
        !           344:        }
        !           345:       else 
        !           346:        {
        !           347:          breg = XEXP (xtmp0, 1);
        !           348:          offset = XEXP (xtmp0, 0);
        !           349:        }
        !           350: 
        !           351:     PRINT_MEM:
        !           352:       if (breg == 0 && ixreg == 0) 
        !           353:        {
        !           354:          output_address (offset);
        !           355:          break;
        !           356:        }
        !           357:       else if (ixreg == 0 && offset == 0) 
        !           358:        {
        !           359:          fprintf (file, "%s", reg_names[REGNO (breg)]);
        !           360:          break;
        !           361:        }
        !           362:       else 
        !           363:        {
        !           364:          fprintf (file, "(");
        !           365:          if (offset != 0) 
        !           366:            {
        !           367:              output_addr_const (file, offset);
        !           368:              needcomma = 1;
        !           369:            }
        !           370:          if (breg != 0) 
        !           371:            {
        !           372:              if (needcomma)
        !           373:                fprintf (file, ",");
        !           374:              fprintf (file, "%s", reg_names[REGNO (breg)]);
        !           375:              needcomma = 1;
        !           376:            }
        !           377:          if (ixreg != 0) 
        !           378:            {
        !           379:              if (needcomma)
        !           380:                fprintf (file, ",");
        !           381:              fprintf (file, "%s", reg_names[REGNO (ixreg)]);
        !           382:              if (scale != 1)
        !           383:                fprintf (file,"*%d", scale);
        !           384:            }
        !           385:          fprintf (file, ")");
        !           386: 
        !           387:          break;
        !           388:        }
        !           389: 
        !           390:     default:
        !           391:       output_addr_const (file, addr);
        !           392:     }
        !           393: }
        !           394: 
        !           395: 
        !           396: 
        !           397: /* Return a REG that occurs in ADDR with coefficient 1.
        !           398:    ADDR can be effectively incremented by incrementing REG.  */
        !           399: 
        !           400: static rtx
        !           401: find_addr_reg (addr)
        !           402:      rtx addr;
        !           403: {
        !           404:   while (GET_CODE (addr) == PLUS)
        !           405:     {
        !           406:       if (GET_CODE (XEXP (addr, 0)) == REG)
        !           407:        addr = XEXP (addr, 0);
        !           408:       else if (GET_CODE (XEXP (addr, 1)) == REG)
        !           409:        addr = XEXP (addr, 1);
        !           410:       else if (GET_CODE (XEXP (addr, 0)) == PLUS)
        !           411:        addr = XEXP (addr, 0);
        !           412:       else if (GET_CODE (XEXP (addr, 1)) == PLUS)
        !           413:        addr = XEXP (addr, 1);
        !           414:     }
        !           415:   if (GET_CODE (addr) == REG)
        !           416:     return addr;
        !           417:   return 0;
        !           418: }
        !           419: 
        !           420: 
        !           421:     /* Return the best assembler insn template
        !           422:     for moving operands[1] into operands[0] as a fullword.  */
        !           423: 
        !           424: static char *
        !           425: singlemove_string (operands)
        !           426:      rtx *operands;
        !           427: {
        !           428:   if (FPU_REG_P (operands[0]) || FPU_REG_P (operands[1])) 
        !           429:     {
        !           430:       if (GREG_P (operands[0]) || GREG_P (operands[1])) 
        !           431:        {
        !           432:          myabort (101);        /* Not Supported yet !! */
        !           433:        }
        !           434:       else 
        !           435:        {
        !           436:          return "fmov.s %1,%0";
        !           437:        }
        !           438:     }
        !           439:   return "mov.w %1,%0";
        !           440: }
        !           441: 
        !           442: 
        !           443: /* Output assembler code to perform a doubleword move insn
        !           444:    with operands OPERANDS.  */
        !           445: 
        !           446: char *
        !           447: output_move_double (operands)
        !           448:      rtx *operands;
        !           449: {
        !           450:   enum 
        !           451:     { REGOP, OFFSOP, MEMOP, PUSHOP, POPOP, CNSTOP, RNDOP }
        !           452:   optype0, optype1;
        !           453:   rtx latehalf[2];
        !           454:   rtx addreg0 = 0, addreg1 = 0;
        !           455: 
        !           456:   /* First classify both operands.  */
        !           457: 
        !           458:   if (REG_P (operands[0]))
        !           459:     optype0 = REGOP;
        !           460:   else if (offsettable_memref_p (operands[0]))
        !           461:     optype0 = OFFSOP;
        !           462:   else if (GET_CODE (XEXP (operands[0], 0)) == POST_INC)
        !           463:     optype0 = POPOP;
        !           464:   else if (GET_CODE (XEXP (operands[0], 0)) == PRE_DEC)
        !           465:     optype0 = PUSHOP;
        !           466:   else if (GET_CODE (operands[0]) == MEM)
        !           467:     optype0 = MEMOP;
        !           468:   else
        !           469:     optype0 = RNDOP;
        !           470: 
        !           471:   if (REG_P (operands[1]))
        !           472:     optype1 = REGOP;
        !           473:   else if (CONSTANT_P (operands[1]))
        !           474:     optype1 = CNSTOP;
        !           475:   else if (offsettable_memref_p (operands[1]))
        !           476:     optype1 = OFFSOP;
        !           477:   else if (GET_CODE (XEXP (operands[1], 0)) == POST_INC)
        !           478:     optype1 = POPOP;
        !           479:   else if (GET_CODE (XEXP (operands[1], 0)) == PRE_DEC)
        !           480:     optype1 = PUSHOP;
        !           481:   else if (GET_CODE (operands[1]) == MEM)
        !           482:     optype1 = MEMOP;
        !           483:   else
        !           484:     optype1 = RNDOP;
        !           485: 
        !           486:   /* Check for the cases that the operand constraints are not
        !           487:      supposed to allow to happen.  Abort if we get one,
        !           488:      because generating code for these cases is painful.  */
        !           489: 
        !           490:   if (optype0 == RNDOP || optype1 == RNDOP)
        !           491:     myabort (102);
        !           492: 
        !           493:   /* If one operand is decrementing and one is incrementing
        !           494:      decrement the former register explicitly
        !           495:      and change that operand into ordinary indexing.  */
        !           496: 
        !           497:   if (optype0 == PUSHOP && optype1 == POPOP)
        !           498:     {
        !           499:       operands[0] = XEXP (XEXP (operands[0], 0), 0);
        !           500:       output_asm_insn ("sub.w %#8,%0", operands);
        !           501:       operands[0] = gen_rtx (MEM, DImode, operands[0]);
        !           502:       optype0 = OFFSOP;
        !           503:     }
        !           504:   if (optype0 == POPOP && optype1 == PUSHOP)
        !           505:     {
        !           506:       operands[1] = XEXP (XEXP (operands[1], 0), 0);
        !           507:       output_asm_insn ("sub.w %#8,%1", operands);
        !           508:       operands[1] = gen_rtx (MEM, DImode, operands[1]);
        !           509:       optype1 = OFFSOP;
        !           510:     }
        !           511: 
        !           512:   /* If an operand is an unoffsettable memory ref, find a register
        !           513:      we can increment temporarily to make it refer to the second word.  */
        !           514: 
        !           515:   if (optype0 == MEMOP)
        !           516:     addreg0 = find_addr_reg (operands[0]);
        !           517: 
        !           518:   if (optype1 == MEMOP)
        !           519:     addreg1 = find_addr_reg (operands[1]);
        !           520: 
        !           521:   /* Ok, we can do one word at a time.
        !           522:      Normally we do the low-numbered word first,
        !           523:      but if either operand is autodecrementing then we
        !           524:      do the high-numbered word first.
        !           525:      
        !           526:      In either case, set up in LATEHALF the operands to use
        !           527:      for the high-numbered word and in some cases alter the
        !           528:      operands in OPERANDS to be suitable for the low-numbered word.  */
        !           529: 
        !           530:   if (optype0 == REGOP)
        !           531:     latehalf[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
        !           532:   else if (optype0 == OFFSOP)
        !           533:     latehalf[0] = adj_offsettable_operand (operands[0], 4);
        !           534:   else
        !           535:     latehalf[0] = operands[0];
        !           536: 
        !           537:   if (optype1 == REGOP)
        !           538:     latehalf[1] = gen_rtx (REG, SImode, REGNO (operands[1]) + 1);
        !           539:   else if (optype1 == OFFSOP)
        !           540:     latehalf[1] = adj_offsettable_operand (operands[1], 4);
        !           541:   else if (optype1 == CNSTOP)
        !           542:     {
        !           543:       if (GET_CODE (operands[1]) == CONST_DOUBLE)
        !           544:        split_double (operands[1], &operands[1], &latehalf[1]);
        !           545:       else if (CONSTANT_P (operands[1]))
        !           546:        latehalf[1] = const0_rtx;
        !           547:     }
        !           548:   else
        !           549:     latehalf[1] = operands[1];
        !           550: 
        !           551:   /* If insn is effectively movd N(sp),-(sp) then we will do the
        !           552:      high word first.  We should use the adjusted operand 1 (which is N+4(sp))
        !           553:      for the low word as well, to compensate for the first decrement of sp.  */
        !           554:   if (optype0 == PUSHOP
        !           555:       && REGNO (XEXP (XEXP (operands[0], 0), 0)) == STACK_POINTER_REGNUM
        !           556:       && reg_overlap_mentioned_p (stack_pointer_rtx, operands[1]))
        !           557:     operands[1] = latehalf[1];
        !           558: 
        !           559:   /* If one or both operands autodecrementing,
        !           560:      do the two words, high-numbered first.  */
        !           561: 
        !           562:   /* Likewise,  the first move would clobber the source of the second one,
        !           563:      do them in the other order.  This happens only for registers;
        !           564:      such overlap can't happen in memory unless the user explicitly
        !           565:      sets it up, and that is an undefined circumstance.  */
        !           566: 
        !           567:   if (optype0 == PUSHOP || optype1 == PUSHOP
        !           568:       || (optype0 == REGOP && optype1 == REGOP
        !           569:          && REGNO (operands[0]) == REGNO (latehalf[1])))
        !           570:     {
        !           571:       /* Make any unoffsettable addresses point at high-numbered word.  */
        !           572:       if (addreg0)
        !           573:        output_asm_insn ("add.w %#4,%0", &addreg0);
        !           574:       if (addreg1)
        !           575:        output_asm_insn ("add.w %#4,%0", &addreg1);
        !           576: 
        !           577:       /* Do that word.  */
        !           578:       output_asm_insn (singlemove_string (latehalf), latehalf);
        !           579: 
        !           580:       /* Undo the adds we just did.  */
        !           581:       if (addreg0)
        !           582:        output_asm_insn ("sub.w %#4,%0", &addreg0);
        !           583:       if (addreg1)
        !           584:        output_asm_insn ("sub.w %#4,%0", &addreg1);
        !           585: 
        !           586:       /* Do low-numbered word.  */
        !           587:       return singlemove_string (operands);
        !           588:     }
        !           589: 
        !           590:   /* Normal case: do the two words, low-numbered first.  */
        !           591: 
        !           592:   output_asm_insn (singlemove_string (operands), operands);
        !           593: 
        !           594:   /* Make any unoffsettable addresses point at high-numbered word.  */
        !           595:   if (addreg0)
        !           596:     output_asm_insn ("add.w %#4,%0", &addreg0);
        !           597:   if (addreg1)
        !           598:     output_asm_insn ("add.w %#4,%0", &addreg1);
        !           599: 
        !           600:   /* Do that word.  */
        !           601:   output_asm_insn (singlemove_string (latehalf), latehalf);
        !           602: 
        !           603:   /* Undo the adds we just did.  */
        !           604:   if (addreg0)
        !           605:     output_asm_insn ("sub.w %#4,%0", &addreg0);
        !           606:   if (addreg1)
        !           607:     output_asm_insn ("sub.w %#4,%0", &addreg1);
        !           608: 
        !           609:   return "";
        !           610: }
        !           611: 
        !           612: /* Move const_double to floating point register (DF) */
        !           613: char *
        !           614: output_move_const_double (operands)
        !           615:      rtx *operands;
        !           616: {
        !           617:   int code = standard_fpu_constant_p (operands[1]);
        !           618: 
        !           619:   if (FPU_REG_P (operands[0])) 
        !           620:     {
        !           621:       if (code != 0)
        !           622:        {
        !           623:          static char buf[40];
        !           624: 
        !           625:          sprintf (buf, "fmvr from%d,%%0.d", code);
        !           626:          return buf;
        !           627:        }
        !           628:       else 
        !           629:        {
        !           630:          return "fmov %1,%0.d";
        !           631:        }
        !           632:     }
        !           633:   else if (GREG_P (operands[0])) 
        !           634:     {
        !           635:       rtx xoperands[2];
        !           636:       xoperands[0] = gen_rtx (REG, SImode, REGNO (operands[0]) + 1);
        !           637:       xoperands[1] = gen_rtx (CONST_INT, VOIDmode,
        !           638:                              CONST_DOUBLE_HIGH (operands[1]));
        !           639:       output_asm_insn ("mov.w %1,%0", xoperands);
        !           640:       operands[1] = gen_rtx (CONST_INT, VOIDmode,
        !           641:                             CONST_DOUBLE_LOW (operands[1]));
        !           642:       return "mov.w %1,%0";
        !           643:     }
        !           644:   else 
        !           645:     {
        !           646:       return output_move_double (operands); /* ?????? */
        !           647:     }
        !           648: }
        !           649: 
        !           650: char *
        !           651: output_move_const_single (operands)
        !           652:      rtx *operands;
        !           653: {
        !           654:   int code = standard_fpu_constant_p (operands[1]);
        !           655:   static char buf[40];
        !           656: 
        !           657:   if (FPU_REG_P (operands[0])) 
        !           658:     {
        !           659:       if (code != 0)
        !           660:        {
        !           661:          sprintf (buf, "fmvr from%d,%%0.s", code);
        !           662:          return buf;
        !           663:        }
        !           664:       return "fmov.s %f1,%0";
        !           665:     }
        !           666:   else 
        !           667:     return "mov.w %f1,%0";
        !           668: }
        !           669: 
        !           670: 
        !           671: /* Return nonzero if X, a CONST_DOUBLE, has a value that we can get
        !           672:    from the "fmvr" instruction of the Gmicro FPU.
        !           673:    The value, anded with 0xff, gives the code to use in fmovecr
        !           674:    to get the desired constant.  */
        !           675: 
        !           676:   u.i[0] = CONST_DOUBLE_LOW (x);
        !           677:   u.i[1] = CONST_DOUBLE_HIGH (x);
        !           678:   d = u.d;
        !           679: 
        !           680:   if (d == 0.0)                        /* +0.0 */
        !           681:     return 0x0;
        !           682:   /* Note: there are various other constants available
        !           683:      but it is a nuisance to put in their values here.  */
        !           684:   if (d == 1.0)                        /* +1.0 */
        !           685:     return 0x1;
        !           686: 
        !           687:   /*
        !           688:    * Stuff that looks different if it's single or double
        !           689:    */
        !           690:   if (GET_MODE (x) == SFmode)
        !           691:     {
        !           692:       if (d == S_PI)
        !           693:        return 0x2;
        !           694:       if (d == (S_PI / 2.0))
        !           695:        return 0x3;
        !           696:       if (d == S_E)
        !           697:        return 0x4;
        !           698:       if (d == S_LOGEof2)
        !           699:        return 0x5;
        !           700:       if (d == S_LOGEof10)
        !           701:        return 0x6;
        !           702:       if (d == S_LOG10of2)
        !           703:        return 0x7;
        !           704:       if (d == S_LOG10ofE)
        !           705:        return 0x8;
        !           706:       if (d == S_LOG2ofE)
        !           707:        return 0x9;
        !           708:     }
        !           709:   else
        !           710:     {
        !           711:       if (d == D_PI)
        !           712:        return 0x2;
        !           713:       if (d == (D_PI / 2.0))
        !           714:        return 0x3;
        !           715:       if (d == D_E)
        !           716:        return 0x4;
        !           717:       if (d == D_LOGEof2)
        !           718:        return 0x5;
        !           719:       if (d == D_LOGEof10)
        !           720:        return 0x6;
        !           721:       if (d == D_LOG10of2)
        !           722:        return 0x7;
        !           723:       if (d == D_LOG10ofE)
        !           724:        return 0x8;
        !           725:       if (d == D_LOG2ofE)
        !           726:        return 0x9;
        !           727:     }
        !           728: 
        !           729:   return 0;
        !           730: }
        !           731: 
        !           732: #undef S_PI
        !           733: #undef D_PI
        !           734: #undef S_E
        !           735: #undef D_E
        !           736: #undef S_LOGEof2
        !           737: #undef D_LOGEof2
        !           738: #undef S_LOGEof10
        !           739: #undef D_LOGEof10
        !           740: #undef S_LOG10of2
        !           741: #undef D_LOG10of2
        !           742: #undef S_LOG10ofE
        !           743: #undef D_LOG10ofE
        !           744: #undef S_LOG2ofE
        !           745: #undef D_LOG2ofE
        !           746: 
        !           747: /* dest should be operand 0 */
        !           748: /* imm should be operand 1 */
        !           749: 
        !           750: extern char *sub_imm_word ();
        !           751: 
        !           752: char *
        !           753: add_imm_word (imm, dest, immp)
        !           754:      int imm;
        !           755:      rtx dest, *immp;
        !           756: {
        !           757:   int is_reg, short_ok;
        !           758: 
        !           759: 
        !           760:   if (imm < 0) 
        !           761:     {
        !           762:       *immp = gen_rtx (CONST_INT, VOIDmode, -imm);
        !           763:       return sub_imm_word (-imm, dest);
        !           764:     }
        !           765:     
        !           766:   if (imm == 0)
        !           767:     return "mov:l.w #0,%0";
        !           768:     
        !           769:   short_ok = short_format_ok (dest);
        !           770: 
        !           771:   if (short_ok && imm <= 8)
        !           772:     return "add:q %1,%0.w";
        !           773: 
        !           774:   if (imm < 128)
        !           775:     return "add:e %1,%0.w";
        !           776: 
        !           777:   is_reg = (GET_CODE (dest) == REG);
        !           778: 
        !           779:   if (is_reg)
        !           780:     return "add:l %1,%0.w";
        !           781:     
        !           782:   if (short_ok)
        !           783:     return "add:i %1,%0.w";
        !           784:     
        !           785:   return "add %1,%0.w";
        !           786: }
        !           787: 
        !           788: char *
        !           789: sub_imm_word (imm, dest, immp)
        !           790:      int imm;
        !           791:      rtx dest, *immp;
        !           792: {
        !           793:   int is_reg, short_ok;
        !           794: 
        !           795:   if (imm < 0 &&  imm != 0x80000000) 
        !           796:     {
        !           797:       *immp = gen_rtx (CONST_INT, VOIDmode, -imm);
        !           798:       return add_imm_word (-imm, dest);
        !           799:     }
        !           800:     
        !           801:   if (imm == 0)
        !           802:     return "mov:z.w #0,%0";
        !           803:     
        !           804:   short_ok = short_format_ok (dest);
        !           805: 
        !           806:   if (short_ok && imm <= 8)
        !           807:     return "sub:q %1,%0.w";
        !           808: 
        !           809:   if (imm < 128)
        !           810:     return "sub:e %1,%0.w";
        !           811: 
        !           812:   is_reg = (GET_CODE (dest) == REG);
        !           813: 
        !           814:   if (is_reg)
        !           815:     return "sub:l %1,%0.w";
        !           816:     
        !           817:   if (short_ok)
        !           818:     return "sub:i %1,%0.w";
        !           819:     
        !           820:   return "sub %1,%0.w";
        !           821: }
        !           822: 
        !           823: int
        !           824: short_format_ok (x)
        !           825:      rtx x;
        !           826: {
        !           827:   rtx x0, x1;
        !           828: 
        !           829:   if (GET_CODE (x) == REG)
        !           830:     return 1;
        !           831: 
        !           832:   if (GET_CODE (x) == MEM 
        !           833:       && GET_CODE (XEXP (x, 0)) == PLUS) 
        !           834:     {
        !           835:       x0 = XEXP (XEXP (x, 0), 0);
        !           836:       x1 = XEXP (XEXP (x, 0), 1);
        !           837:       return ((GET_CODE (x0) == REG
        !           838:               && CONSTANT_P (x1)
        !           839:               && ((unsigned) (INTVAL (x1) + 0x8000)  < 0x10000))
        !           840:              ||
        !           841:              (GET_CODE (x1) == REG
        !           842:               && CONSTANT_P (x0)
        !           843:               && ((unsigned) (INTVAL (x0) + 0x8000)  < 0x10000)));
        !           844:     }
        !           845: 
        !           846:   return 0;
        !           847: }
        !           848: 
        !           849: myoutput_sp_adjust (file, op, fsize)
        !           850:      FILE *file;
        !           851:      char *op;
        !           852:      int fsize;
        !           853: {
        !           854:   if (fsize == 0)
        !           855:     ;
        !           856:   else if (fsize < 8)
        !           857:     fprintf (file, "\t%s:q #%d,sp.w\n", op, fsize);
        !           858:   else if (fsize < 128)
        !           859:     fprintf (file, "\t%s:e #%d,sp.w\n", op, fsize);
        !           860:   else
        !           861:     fprintf (file, "\t%s:l #%d,sp.w\n", op, fsize);
        !           862: }
        !           863: 
        !           864: 
        !           865: char *
        !           866: mov_imm_word (imm, dest)
        !           867:      int imm;
        !           868:      rtx dest;
        !           869: {
        !           870:   int is_reg, short_ok;
        !           871: 
        !           872:   if (imm == 0)
        !           873:     return "mov:z.w #0,%0";
        !           874:     
        !           875:   short_ok = short_format_ok (dest);
        !           876: 
        !           877:   if (short_ok && imm > 0 && imm <= 8)
        !           878:     return "mov:q %1,%0.w";
        !           879: 
        !           880:   if (-128 <= imm && imm < 128)
        !           881:     return "mov:e %1,%0.w";
        !           882: 
        !           883:   is_reg = (GET_CODE (dest) == REG);
        !           884: 
        !           885:   if (is_reg)
        !           886:     return "mov:l %1,%0.w";
        !           887:     
        !           888:   if (short_ok)
        !           889:     return "mov:i %1,%0.w";
        !           890:     
        !           891:   return "mov %1,%0.w";
        !           892: }
        !           893: 
        !           894: char *
        !           895: cmp_imm_word (imm, dest)
        !           896:      int imm;
        !           897:      rtx dest;
        !           898: {
        !           899:   int is_reg, short_ok;
        !           900: 
        !           901:   if (imm == 0)
        !           902:     return "cmp:z.w #0,%0";
        !           903:     
        !           904:   short_ok = short_format_ok (dest);
        !           905: 
        !           906:   if (short_ok && imm >0 && imm <= 8)
        !           907:     return "cmp:q %1,%0.w";
        !           908: 
        !           909:   if (-128 <= imm && imm < 128)
        !           910:     return "cmp:e %1,%0.w";
        !           911: 
        !           912:   is_reg = (GET_CODE (dest) == REG);
        !           913: 
        !           914:   if (is_reg)
        !           915:     return "cmp:l %1,%0.w";
        !           916:     
        !           917:   if (short_ok)
        !           918:     return "cmp:i %1,%0.w";
        !           919:     
        !           920:   return "cmp %1,%0.w";
        !           921: }
        !           922: 
        !           923: char *
        !           924: push_imm_word (imm)
        !           925:      int imm;
        !           926: {
        !           927:   if (imm == 0)
        !           928:     return "mov:z.w #0,%-";
        !           929:     
        !           930:   if (imm > 0 && imm <= 8)
        !           931:     return "mov:q %1,%-.w";
        !           932: 
        !           933:   if (-128 <= imm && imm < 128)
        !           934:     return "mov:e %1,%-.w";
        !           935: 
        !           936:   return "mov:g %1,%-.w";
        !           937:     
        !           938:   /* In some cases, g-format may be better than I format.??
        !           939:      return "mov %1,%0.w";
        !           940:      */
        !           941: }
        !           942: 
        !           943: my_signed_comp (insn)
        !           944:      rtx insn;
        !           945: {
        !           946:   rtx my_insn;
        !           947: 
        !           948:   my_insn = NEXT_INSN (insn);
        !           949:   if (GET_CODE (my_insn) != JUMP_INSN) 
        !           950:     {
        !           951:       fprintf (stderr, "my_signed_comp: Not Jump_insn ");
        !           952:       myabort (GET_CODE (my_insn));
        !           953:     }
        !           954:   my_insn = PATTERN (my_insn);
        !           955:   if (GET_CODE (my_insn) != SET) 
        !           956:     {
        !           957:       fprintf (stderr, "my_signed_comp: Not Set ");
        !           958:       myabort (GET_CODE (my_insn));
        !           959:     }
        !           960:   my_insn = SET_SRC (my_insn);
        !           961:   if (GET_CODE (my_insn) != IF_THEN_ELSE) 
        !           962:     {
        !           963:       fprintf (stderr, "my_signed_comp: Not if_then_else ");
        !           964:       myabort (GET_CODE (my_insn));
        !           965:     }
        !           966:   switch (GET_CODE (XEXP (my_insn, 0)))
        !           967:     {
        !           968:     case NE:
        !           969:     case EQ:
        !           970:     case GE:
        !           971:     case GT:
        !           972:     case LE:
        !           973:     case LT:
        !           974:       return 1;
        !           975:     case GEU:
        !           976:     case GTU:
        !           977:     case LEU:
        !           978:     case LTU:
        !           979:       return 0;
        !           980:     }
        !           981:   fprintf (stderr, "my_signed_comp: Not cccc ");
        !           982:   myabort (GET_CODE (XEXP (my_insn, 0)));
        !           983: }

unix.superglobalmegacorp.com

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