Annotation of GNUtools/cc/config/gmicro/gmicro.c, revision 1.1.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.