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

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

unix.superglobalmegacorp.com

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