Annotation of gcc/config/dsp16xx/dsp16xx.c, revision 1.1.1.1

1.1       root        1: /* Subroutines for assembler code output on the DSP1610.
                      2:    Copyright (C) 1994 Free Software Foundation, Inc.
                      3:    Contributed by Michael Collison ([email protected]).
                      4: 
                      5: This file is part of GNU CC.
                      6: 
                      7: GNU CC is free software; you can redistribute it and/or modify
                      8: it under the terms of the GNU General Public License as published by
                      9: the Free Software Foundation; either version 2, or (at your option)
                     10: any later version.
                     11: 
                     12: GNU CC is distributed in the hope that it will be useful,
                     13: but WITHOUT ANY WARRANTY; without even the implied warranty of
                     14: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
                     15: GNU General Public License for more details.
                     16: 
                     17: You should have received a copy of the GNU General Public License
                     18: along with GNU CC; see the file COPYING.  If not, write to
                     19: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.  */
                     20: 
                     21: /* Some output-actions in dsp1600.md need these.  */
                     22: #include <stdio.h>
                     23: #include "config.h"
                     24: #include "rtl.h"
                     25: #include "regs.h"
                     26: #include "hard-reg-set.h"
                     27: #include "real.h"
                     28: #include "insn-config.h"
                     29: #include "conditions.h"
                     30: #include "insn-flags.h"
                     31: #include "output.h"
                     32: #include "insn-attr.h"
                     33: #include "tree.h"
                     34: #include "expr.h"
                     35: #include "flags.h"
                     36: 
                     37: char *text_seg_name;
                     38: char *rsect_text;
                     39: char *data_seg_name;
                     40: char *rsect_data;
                     41: char *bss_seg_name;
                     42: char *rsect_bss;
                     43: char *const_seg_name;
                     44: char *rsect_const;
                     45: 
                     46: char *chip_name;
                     47: char *save_chip_name;
                     48: 
                     49: /* Save the operands of a compare. The 16xx has not lt or gt, so
                     50:    in these cases we swap the operands and reverse the condition */
                     51: 
                     52: rtx dsp16xx_compare_op0;
                     53: rtx dsp16xx_compare_op1;
                     54: struct rtx_def *(*dsp16xx_compare_gen)();
                     55: 
                     56: static char *fp;
                     57: static char *sp;
                     58: static char *rr;
                     59: static char *a1h;
                     60: 
                     61: struct dsp16xx_frame_info current_frame_info;
                     62: struct dsp16xx_frame_info zero_frame_info;
                     63: 
                     64: rtx dsp16xx_addhf3_libcall = (rtx) 0;
                     65: rtx dsp16xx_subhf3_libcall = (rtx) 0;
                     66: rtx dsp16xx_mulhf3_libcall = (rtx) 0;
                     67: rtx dsp16xx_divhf3_libcall = (rtx) 0;
                     68: rtx dsp16xx_cmphf3_libcall = (rtx) 0;
                     69: rtx dsp16xx_fixhfhi2_libcall = (rtx) 0;
                     70: rtx dsp16xx_floathihf2_libcall = (rtx) 0;
                     71: rtx dsp16xx_neghf2_libcall = (rtx) 0;
                     72: 
                     73: rtx dsp16xx_mulhi3_libcall = (rtx) 0;
                     74: rtx dsp16xx_udivqi3_libcall = (rtx) 0;
                     75: rtx dsp16xx_udivhi3_libcall = (rtx) 0;
                     76: rtx dsp16xx_divqi3_libcall = (rtx) 0;
                     77: rtx dsp16xx_divhi3_libcall = (rtx) 0;
                     78: rtx dsp16xx_modqi3_libcall = (rtx) 0;
                     79: rtx dsp16xx_modhi3_libcall = (rtx) 0;
                     80: rtx dsp16xx_umodqi3_libcall = (rtx) 0;
                     81: rtx dsp16xx_umodhi3_libcall = (rtx) 0;
                     82: rtx dsp16xx_ashrhi3_libcall = (rtx) 0;
                     83: rtx dsp16xx_ashlhi3_libcall = (rtx) 0;
                     84: rtx dsp16xx_ucmphi2_libcall = (rtx) 0;
                     85: rtx dsp16xx_lshrhi3_libcall = (rtx) 0;
                     86: 
                     87: char *himode_reg_name[] = HIMODE_REGISTER_NAMES;
                     88: 
                     89: #define SHIFT_INDEX_1   0
                     90: #define SHIFT_INDEX_4   1
                     91: #define SHIFT_INDEX_8   2
                     92: #define SHIFT_INDEX_16  3
                     93: 
                     94: static char *ashift_right_asm[] = 
                     95: {
                     96:   "%0=%0>>1",
                     97:   "%0=%0>>4",
                     98:   "%0=%0>>8",
                     99:   "%0=%0>>16"
                    100: };
                    101: 
                    102: static char *ashift_right_asm_first[] = 
                    103: {
                    104:   "%0=%1>>1",
                    105:   "%0=%1>>4",
                    106:   "%0=%1>>8",
                    107:   "%0=%1>>16"
                    108: };
                    109: 
                    110: static char *ashift_left_asm[] = 
                    111: {
                    112:   "%0=%0<<1",
                    113:   "%0=%0<<4",
                    114:   "%0=%0<<8",
                    115:   "%0=%0<<16"
                    116: };
                    117: 
                    118: static char *ashift_left_asm_first[] = 
                    119: {
                    120:   "%0=%1<<1",
                    121:   "%0=%1<<4",
                    122:   "%0=%1<<8",
                    123:   "%0=%1<<16"
                    124: };
                    125: 
                    126: static char *lshift_right_asm[] = 
                    127: {
                    128:   "%0=%0>>1\n\t%0=%b0&0x7fff",
                    129:   "%0=%0>>4\n\t%0=%b0&0x0fff",
                    130:   "%0=%0>>8\n\t%0=%b0&0x00ff",
                    131:   "%0=%0>>16\n\t%0=%b0&0x0000"
                    132: };
                    133: 
                    134: static char *lshift_right_asm_first[] = 
                    135: {
                    136:   "%0=%1>>1\n\t%0=%b0&0x7fff",
                    137:   "%0=%1>>4\n\t%0=%b0&0x0fff",
                    138:   "%0=%1>>8\n\t%0=%b0&0x00ff",
                    139:   "%0=%1>>16\n\t%0=%b0&0x0000"
                    140: };
                    141: 
                    142: int 
                    143: hard_regno_mode_ok (regno, mode)
                    144: int regno;
                    145: enum machine_mode mode;
                    146: {
                    147:   switch ((int) mode)
                    148:     {
                    149:     case VOIDmode:
                    150:       return 1;
                    151:       
                    152:       /* 
                    153:        We can't use the c0-c2 for QImode, since they are only
                    154:        8 bits in length */
                    155: 
                    156:     case QImode:
                    157:       if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
                    158:        return 1;
                    159:       else
                    160:        return 0;
                    161:       
                    162:       /* We only allow a0, a1, y, and p to be allocated for 32-bit modes.
                    163:          Additionally we allow the virtual ybase registers to be used for 32-bit
                    164:         modes. */
                    165:       
                    166:     case HFmode:
                    167:     case SFmode:
                    168:     case DFmode:
                    169:     case XFmode:
                    170:     case HImode:
                    171:     case SImode:
                    172:     case DImode:
                    173:       if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
                    174:          || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
                    175:        return 1;
                    176:       else
                    177:        return 0;
                    178:       
                    179:     default:
                    180:       return 0;
                    181:     }
                    182: }
                    183: 
                    184: enum reg_class
                    185: dsp16xx_reg_class_from_letter (c)
                    186: int c;
                    187: {
                    188:   switch (c)
                    189:     {
                    190:     case 'A':
                    191:       return ACCUM_REGS;
                    192:       
                    193:     case 'h':
                    194:       return ACCUM_HIGH_REGS;
                    195:       
                    196:     case 'j':
                    197:       return A0H_REG;
                    198:       
                    199:     case 'k':
                    200:       return A0L_REG;
                    201:       
                    202:     case 'q':
                    203:       return A1H_REG;
                    204:       
                    205:     case 'u':
                    206:       return A1L_REG;
                    207:       
                    208:     case 'x':
                    209:       return X_REG;
                    210: 
                    211:     case 'y':
                    212:       return YH_REG;
                    213: 
                    214:     case 'z':
                    215:       return YL_REG;
                    216: 
                    217:     case 't':
                    218:       return P_REG;
                    219: 
                    220:     case 'Z':
                    221:       return Y_OR_P_REGS;
                    222: 
                    223:     case 'd':
                    224:       return ACCUM_Y_OR_P_REGS;
                    225: 
                    226:     case 'C':
                    227:       return NO_FRAME_Y_ADDR_REGS;
                    228: 
                    229:     case 'a':
                    230:       return Y_ADDR_REGS;
                    231: 
                    232:     case 'B':
                    233:       return (TARGET_BMU ? BMU_REGS : NO_REGS);
                    234: 
                    235:     case 'Y':
                    236:       return YBASE_VIRT_REGS;
                    237: 
                    238:     case 'v':
                    239:       return PH_REG;
                    240: 
                    241:     case 'w':
                    242:       return PL_REG;
                    243: 
                    244:     case 'W':
                    245:       return J_REG;
                    246: 
                    247:     case 'e':
                    248:       return YBASE_ELIGIBLE_REGS;
                    249: 
                    250:     case 'b':
                    251:       return ACCUM_LOW_REGS;
                    252: 
                    253:     case 'c':
                    254:       return NON_YBASE_REGS;
                    255: 
                    256:     case 'f':
                    257:       return Y_REG;
                    258: 
                    259:     case 'D':
                    260:       return SLOW_MEM_LOAD_REGS;
                    261: 
                    262:     default:
                    263:       fatal ("Illegal register class letter %c", c);
                    264:       return NO_REGS;
                    265:     }
                    266: }
                    267: /* Return the class number of the smallest class containing
                    268:    reg number REGNO. */
                    269: 
                    270: int 
                    271: regno_reg_class(regno)
                    272: int regno;
                    273: {
                    274:   switch (regno)
                    275:     {
                    276:     case REG_A0L:
                    277:       return (int) A0L_REG;
                    278:     case REG_A1L:
                    279:       return (int) A1L_REG;
                    280:       
                    281:     case REG_A0:
                    282:       return (int) A0H_REG;
                    283:     case REG_A1:
                    284:       return (int) A1H_REG;
                    285:       
                    286:     case REG_X:
                    287:       return (int) X_REG;
                    288:       
                    289:     case REG_Y:
                    290:       return (int) YH_REG;
                    291:     case REG_YL:
                    292:       return (int) YL_REG;
                    293:       
                    294:     case REG_PROD:
                    295:       return (int) PH_REG;
                    296:     case REG_PRODL:
                    297:       return (int) PL_REG;
                    298:       
                    299:     case REG_R0: case REG_R1: case REG_R2: case REG_R3:
                    300:       return (int) Y_ADDR_REGS;
                    301:       
                    302:     case REG_J:
                    303:       return (int) J_REG;
                    304:     case REG_K:
                    305:       return (int) GENERAL_REGS;
                    306:       
                    307:     case REG_YBASE:
                    308:       return (int) GENERAL_REGS;
                    309:       
                    310:     case REG_PT:
                    311:       return (int) GENERAL_REGS;
                    312:       
                    313:     case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:
                    314:       return (int) BMU_REGS;
                    315:       
                    316:     case REG_C0: case REG_C1: case REG_C2:
                    317:       return (int) GENERAL_REGS;
                    318:       
                    319:     case REG_PR:
                    320:       return (int) GENERAL_REGS;
                    321:       
                    322:     case REG_RB:
                    323:       return (int) GENERAL_REGS;
                    324:       
                    325:     case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:
                    326:     case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:
                    327:     case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:
                    328:     case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:
                    329:     case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:
                    330:     case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:
                    331:     case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:
                    332:     case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:
                    333:       return (int) YBASE_VIRT_REGS;
                    334:       
                    335:     default:
                    336:       return (int) NO_REGS;
                    337:     }
                    338: }
                    339: 
                    340: /* A C expression for the maximum number of consecutive registers of class CLASS
                    341:    needed to hold a value of mode MODE */
                    342: 
                    343: int
                    344: class_max_nregs(class, mode)
                    345: enum reg_class class;
                    346: enum machine_mode mode;
                    347: {
                    348:     return (GET_MODE_SIZE(mode));
                    349: }
                    350: 
                    351: enum reg_class
                    352: limit_reload_class (mode, class)
                    353: enum machine_mode mode;
                    354: enum reg_class class;
                    355: {
                    356:   switch ((int) class)
                    357:     {
                    358:     case NO_REGS:
                    359:     case A0H_REG:
                    360:     case A0L_REG:
                    361:     case A0_REG:
                    362:     case A1H_REG:
                    363:       return class;
                    364: 
                    365:     case ACCUM_HIGH_REGS:
                    366:       fatal ("ACCUM_HIGH_REGS class in limit_reload_class");
                    367: 
                    368:     case A1L_REG:
                    369:     case ACCUM_LOW_REGS:
                    370:     case A1_REG:
                    371:       return class;
                    372: 
                    373:     case ACCUM_REGS:
                    374:       if (GET_MODE_SIZE(mode) == 1)
                    375:        return ACCUM_LOW_REGS;
                    376:       else
                    377:        return class;
                    378: 
                    379:     case X_REG:
                    380:     case X_OR_ACCUM_LOW_REGS:
                    381:       return class;
                    382: 
                    383:     case X_OR_ACCUM_REGS:
                    384:       if (GET_MODE_SIZE(mode) == 1)
                    385:        return X_OR_ACCUM_LOW_REGS;
                    386:       else
                    387:        return class;
                    388: 
                    389:     case YH_REG:
                    390:       return class;
                    391: 
                    392:     case YH_OR_ACCUM_HIGH_REGS:
                    393:       fatal ("YH_OR_ACCUM_HIGH_REGS found in limit_reload_class");
                    394: 
                    395:     case X_OR_YH_REGS:
                    396:       return class;
                    397: 
                    398:     case YL_REG:
                    399:       /* Register 'yl' is illegal for QImode, so we should never
                    400:         see it. */
                    401: 
                    402:       fatal ("YL found in limit_reload_class");
                    403: 
                    404:     case YL_OR_ACCUM_LOW_REGS:
                    405:     case X_OR_YL_REGS:
                    406:       return class;
                    407: 
                    408:     case Y_REG:
                    409:       if (GET_MODE_SIZE(mode) > 1)
                    410:        return class;
                    411:       else
                    412:        return YH_REG;
                    413: 
                    414:     case ACCUM_OR_Y_REGS:
                    415:       if (GET_MODE_SIZE(mode) > 1)
                    416:        return class;
                    417:       else
                    418:        return YL_OR_ACCUM_LOW_REGS;
                    419: 
                    420:     case PH_REG:
                    421:     case X_OR_PH_REGS:
                    422:     case PL_REG:
                    423:     case PL_OR_ACCUM_LOW_REGS:
                    424:     case X_OR_PL_REGS:
                    425:       return class;
                    426: 
                    427:     case P_REG:
                    428:       if (GET_MODE_SIZE(mode) > 1)
                    429:        return class;
                    430:       else
                    431:        return PL_REG;
                    432: 
                    433:     case ACCUM_OR_P_REGS:
                    434:       if (GET_MODE_SIZE(mode) > 1)
                    435:        return class;
                    436:       else
                    437:        return PL_OR_ACCUM_LOW_REGS;
                    438: 
                    439:     case YL_OR_P_REGS:
                    440:     case ACCUM_LOW_OR_YL_OR_P_REGS:
                    441:       return class;
                    442: 
                    443:     case Y_OR_P_REGS:
                    444:       return class;
                    445: 
                    446:     case ACCUM_Y_OR_P_REGS:
                    447:       if (GET_MODE_SIZE(mode) > 1)
                    448:        return class;
                    449:       else
                    450:        return ACCUM_LOW_OR_YL_OR_P_REGS;
                    451: 
                    452:     case NO_FRAME_Y_ADDR_REGS:
                    453:     case Y_ADDR_REGS: 
                    454:     case ACCUM_LOW_OR_Y_ADDR_REGS:
                    455:       return class;
                    456: 
                    457:     case ACCUM_OR_Y_ADDR_REGS:
                    458:       if (GET_MODE_SIZE(mode) > 1)
                    459:        return ACCUM_REGS;
                    460:       else
                    461:        return ACCUM_LOW_OR_Y_ADDR_REGS;
                    462: 
                    463:     case X_OR_Y_ADDR_REGS:
                    464:       return class;
                    465: 
                    466:     case Y_OR_Y_ADDR_REGS:
                    467:     case P_OR_Y_ADDR_REGS:
                    468:     case NON_HIGH_YBASE_ELIGIBLE_REGS:
                    469: 
                    470:     case J_REG:
                    471:       return class;
                    472: 
                    473:     case YBASE_ELIGIBLE_REGS:
                    474:       if (GET_MODE_SIZE(mode) > 1)
                    475:        return ACCUM_Y_P_OR_YBASE_REGS;
                    476:       else
                    477:        return NON_HIGH_YBASE_ELIGIBLE_REGS;
                    478: 
                    479:     case J_OR_DAU_16_BIT_REGS:
                    480:       if (GET_MODE_SIZE(mode) == 1)
                    481:        return J_REG;
                    482:       else
                    483:        return class;
                    484: 
                    485:     case BMU_REGS:
                    486:     case NOHIGH_NON_ADDR_REGS:
                    487:       return class;
                    488: 
                    489:     case NON_ADDR_REGS:
                    490:       if (GET_MODE_SIZE(mode) > 1)
                    491:        return class;
                    492:       else
                    493:        return NOHIGH_NON_ADDR_REGS;
                    494: 
                    495:     case NOHIGH_NON_YBASE_REGS:
                    496:       return class;
                    497: 
                    498:     case NON_YBASE_REGS:
                    499:       if (GET_MODE_SIZE(mode) > 1)
                    500:        return class;
                    501:       else
                    502:        return NOHIGH_NON_YBASE_REGS;
                    503: 
                    504:     case YBASE_VIRT_REGS:
                    505:     case ACCUM_LOW_OR_YBASE_REGS:
                    506:       return class;
                    507:       
                    508:     case ACCUM_OR_YBASE_REGS:
                    509:       if (GET_MODE_SIZE(mode) > 1)
                    510:        return class;
                    511:       else
                    512:        return ACCUM_LOW_OR_YBASE_REGS;
                    513: 
                    514:     case X_OR_YBASE_REGS:
                    515:       return class;
                    516: 
                    517:     case Y_OR_YBASE_REGS:
                    518:     case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
                    519:     case P_OR_YBASE_REGS:
                    520:       return class;
                    521: 
                    522:     case ACCUM_Y_P_OR_YBASE_REGS:
                    523:       return ACCUM_LOW_YL_PL_OR_YBASE_REGS;
                    524: 
                    525:     case Y_ADDR_OR_YBASE_REGS:
                    526:     case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
                    527:       return class;
                    528: 
                    529:     case YBASE_OR_YBASE_ELIGIBLE_REGS:
                    530:       if (GET_MODE_SIZE(mode) > 1)
                    531:        return class;
                    532:       else
                    533:        return YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS;
                    534: 
                    535:     case NO_HIGH_ALL_REGS:
                    536:       return class;
                    537: 
                    538:     case ALL_REGS:
                    539:       if (GET_MODE_SIZE(mode) > 1)
                    540:        return class;
                    541:       else
                    542:        return NO_HIGH_ALL_REGS;
                    543: 
                    544:     default:
                    545:       return class;
                    546:     }
                    547: }
                    548: 
                    549: int
                    550: dsp16xx_register_move_cost (from, to)
                    551: enum reg_class from, to;
                    552: {
                    553: #if 0
                    554:   if (from == NO_REGS || to == NO_REGS || (from == to))
                    555:     return 2;
                    556: #endif
                    557: 
                    558:   if (from == A0H_REG || from == A0L_REG || from == A0_REG ||
                    559:       from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||
                    560:       from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)
                    561:     {
                    562:       if (to == Y_REG || to == P_REG)
                    563:        return 4;
                    564:       else
                    565:        return 2;
                    566:     }
                    567: 
                    568:   if (to == A0H_REG || to == A0L_REG || to == A0_REG ||
                    569:       to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||
                    570:       to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)
                    571:     {
                    572:       return 2;
                    573:     }
                    574: 
                    575: #if 0
                    576:   if (from == YBASE_VIRT_REGS)
                    577:     {
                    578:       if (to == X_REG || to == YH_REG || to == YL_REG ||
                    579:          to == Y_REG || to == PL_REG || to == PH_REG ||
                    580:          to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||
                    581:          to == Y_OR_P_REGS)
                    582:        {
                    583:          return 2;
                    584:        }
                    585:       else
                    586:        return 4;
                    587:     }
                    588: 
                    589:   if (to == YBASE_VIRT_REGS)
                    590:     {
                    591:       if (from == X_REG || from == YH_REG || from == YL_REG ||
                    592:          from == Y_REG || from == PL_REG || from == PH_REG ||
                    593:          from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||
                    594:          from == Y_OR_P_REGS)
                    595:        {
                    596:          return 2;
                    597:        }
                    598:       else
                    599:        return 4;
                    600:     }
                    601: #endif
                    602:   return 4;
                    603: }
                    604: 
                    605: /* Given an rtx X being reloaded into a reg required to be
                    606:    in class CLASS, return the class of reg to actually use.
                    607:    In general this is just CLASS; but on some machines
                    608:    in some cases it is preferable to use a more restrictive class.
                    609:    Also, we must ensure that a PLUS is reloaded either
                    610:    into an accumulator or an address register.  */
                    611: 
                    612: enum reg_class
                    613: preferred_reload_class (x, class)
                    614:      rtx x;
                    615:      enum reg_class class;
                    616: {
                    617:   /* The ybase registers cannot have constants copied directly
                    618:      to them. */
                    619: 
                    620:   if (CONSTANT_P (x))
                    621:     {
                    622:       if (class == ALL_REGS)
                    623:        return NON_YBASE_REGS;
                    624:     }
                    625: 
                    626:   if (class == ALL_REGS && REG_P (x) && !TARGET_RESERVE_YBASE
                    627:       && IS_YBASE_REGISTER_WINDOW (REGNO(x)))
                    628:     return YBASE_ELIGIBLE_REGS;
                    629: 
                    630:   if (GET_CODE (x) == PLUS)
                    631:     {
                    632:       if (GET_MODE (x) == QImode
                    633:          && REG_P (XEXP (x,0))
                    634:          && (XEXP (x,0) == frame_pointer_rtx
                    635:              || XEXP (x,0) == stack_pointer_rtx)
                    636:          && (GET_CODE (XEXP (x,1)) == CONST_INT))
                    637:        {
                    638:          if (class == ACCUM_HIGH_REGS)
                    639:            return class;
                    640: 
                    641:          if (reg_class_subset_p (ACCUM_HIGH_REGS, class))
                    642:            return ACCUM_HIGH_REGS;
                    643: 
                    644:          /* We will use accumulator 'a1l' for reloading a
                    645:             PLUS. We can only use one accumulator because
                    646:             'reload_inqi' only allows one alternative to be
                    647:             used. */
                    648: 
                    649:          else if (class == ACCUM_LOW_REGS)
                    650:            return A1L_REG;
                    651:          else if (class == A0L_REG)
                    652:            return NO_REGS;
                    653:          else
                    654:            return class;
                    655:        }
                    656: 
                    657:       if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
                    658:        return Y_ADDR_REGS;
                    659:       else
                    660:        return class;
                    661:     }
                    662:   else if (GET_CODE (x) == MEM)
                    663:     {
                    664:       if (class == ALL_REGS)
                    665:        {
                    666: #if 0
                    667:          if (GET_MODE(x) == HImode)
                    668:            return NO_ACCUM_NON_YBASE_REGS;
                    669:          else
                    670: #endif
                    671:            return NON_YBASE_REGS;
                    672:        }
                    673:       else
                    674:        return class;
                    675:     }
                    676:   else
                    677:     return class;
                    678: }
                    679:        
                    680: /* Return the register class of a scratch register needed to copy IN into
                    681:    or out of a register in CLASS in MODE.  If it can be done directly,
                    682:    NO_REGS is returned.  */
                    683: 
                    684: enum reg_class
                    685: secondary_reload_class (class, mode, in)
                    686:      enum reg_class class;
                    687:      enum machine_mode mode;
                    688:      rtx in;
                    689: {
                    690:   int regno = -1;
                    691: 
                    692:   if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
                    693:     regno = true_regnum (in);
                    694: 
                    695:   if (class == ACCUM_HIGH_REGS 
                    696:       || class == ACCUM_LOW_REGS
                    697:       || class == A1L_REG
                    698:       || class == A0L_REG
                    699:       || class == A1H_REG
                    700:       || class == A0H_REG)
                    701:     {
                    702:       if (GET_CODE (in) == PLUS && mode == QImode)
                    703:        {
                    704:          rtx addr0 = XEXP (in, 0);
                    705:          rtx addr1 = XEXP (in, 1);
                    706:          
                    707:          /* If we are reloading a plus (reg:QI) (reg:QI)
                    708:             we need an additional register. */ 
                    709:          if (REG_P (addr0) && REG_P (addr1))
                    710:            return NO_REGS;
                    711:        }
                    712:     }
                    713: 
                    714:   /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
                    715:      into anything.  */
                    716: 
                    717:   if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS ||
                    718:        class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG ||
                    719:        class == A1H_REG || class == A1_REG) || 
                    720:       (regno >= REG_A0 && regno < REG_A1L + 1))
                    721:     return NO_REGS;
                    722: 
                    723:   /* We can copy the ybase registers into:
                    724:      r0-r3, a0-a1, y, p, & x or the union of
                    725:      any of these. */
                    726: 
                    727:   if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
                    728:     {
                    729:       switch ((int) class)
                    730:        {
                    731:        case (int) X_REG:
                    732:        case (int) X_OR_ACCUM_LOW_REGS:
                    733:        case (int) X_OR_ACCUM_REGS:
                    734:        case (int) YH_REG:
                    735:        case (int) YH_OR_ACCUM_HIGH_REGS:
                    736:        case (int) X_OR_YH_REGS:
                    737:        case (int) YL_REG:
                    738:        case (int) YL_OR_ACCUM_LOW_REGS:
                    739:        case (int) X_OR_Y_REGS:
                    740:        case (int) X_OR_YL_REGS:
                    741:        case (int) Y_REG:
                    742:        case (int) ACCUM_OR_Y_REGS:
                    743:        case (int) PH_REG:
                    744:        case (int) X_OR_PH_REGS:
                    745:        case (int) PL_REG:
                    746:        case (int) PL_OR_ACCUM_LOW_REGS:
                    747:        case (int) X_OR_PL_REGS:
                    748:        case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
                    749:        case (int) P_REG:
                    750:        case (int) ACCUM_OR_P_REGS:
                    751:        case (int) YL_OR_P_REGS:
                    752:        case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
                    753:        case (int) Y_OR_P_REGS:
                    754:        case (int) ACCUM_Y_OR_P_REGS:
                    755:        case (int) Y_ADDR_REGS:
                    756:        case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
                    757:        case (int) ACCUM_OR_Y_ADDR_REGS:
                    758:        case (int) X_OR_Y_ADDR_REGS:
                    759:        case (int) Y_OR_Y_ADDR_REGS:
                    760:        case (int) P_OR_Y_ADDR_REGS:
                    761:        case (int) YBASE_ELIGIBLE_REGS:
                    762:          return NO_REGS;
                    763: 
                    764:        default:
                    765:          return ACCUM_HIGH_REGS;
                    766:        }
                    767:     }
                    768: 
                    769:   /* We can copy r0-r3, a0-a1, y, & p
                    770:      directly to the ybase registers. In addition
                    771:      we can use any of the ybase virtual registers
                    772:      as the secondary reload registers when copying
                    773:      between any of these registers. */
                    774: 
                    775:   if (!TARGET_RESERVE_YBASE && regno != -1)
                    776:     {
                    777:       switch (regno)
                    778:        {
                    779:        case REG_A0:
                    780:        case REG_A0L:
                    781:        case REG_A1:
                    782:        case REG_A1L:
                    783:        case REG_X:
                    784:        case REG_Y:
                    785:        case REG_YL:
                    786:        case REG_PROD:
                    787:        case REG_PRODL:
                    788:        case REG_R0:
                    789:        case REG_R1:
                    790:        case REG_R2:
                    791:        case REG_R3:
                    792:          if (class == YBASE_VIRT_REGS)
                    793:            return NO_REGS;
                    794:          else
                    795:            {
                    796:              switch ((int) class)
                    797:                {
                    798:                case (int) X_REG:
                    799:                case (int) X_OR_ACCUM_LOW_REGS:
                    800:                case (int) X_OR_ACCUM_REGS:
                    801:                case (int) YH_REG:
                    802:                case (int) YH_OR_ACCUM_HIGH_REGS:
                    803:                case (int) X_OR_YH_REGS:
                    804:                case (int) YL_REG:
                    805:                case (int) YL_OR_ACCUM_LOW_REGS:
                    806:                case (int) X_OR_Y_REGS:
                    807:                case (int) X_OR_YL_REGS:
                    808:                case (int) Y_REG:
                    809:                case (int) ACCUM_OR_Y_REGS:
                    810:                case (int) PH_REG:
                    811:                case (int) X_OR_PH_REGS:
                    812:                case (int) PL_REG:
                    813:                case (int) PL_OR_ACCUM_LOW_REGS:
                    814:                case (int) X_OR_PL_REGS:
                    815:                case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
                    816:                case (int) P_REG:
                    817:                case (int) ACCUM_OR_P_REGS:
                    818:                case (int) YL_OR_P_REGS:
                    819:                case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
                    820:                case (int) Y_OR_P_REGS:
                    821:                case (int) ACCUM_Y_OR_P_REGS:
                    822:                case (int) Y_ADDR_REGS:
                    823:                case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
                    824:                case (int) ACCUM_OR_Y_ADDR_REGS:
                    825:                case (int) X_OR_Y_ADDR_REGS:
                    826:                case (int) Y_OR_Y_ADDR_REGS:
                    827:                case (int) P_OR_Y_ADDR_REGS:
                    828:                case (int) YBASE_ELIGIBLE_REGS:
                    829:                  return YBASE_VIRT_REGS;
                    830: 
                    831:                default:
                    832:                  break;
                    833:                }
                    834:            }
                    835:        }
                    836:     }
                    837: 
                    838:   /* Memory or constants can be moved from or to any register
                    839:      except the ybase virtual registers */
                    840:   if (regno == -1 && GET_CODE(in) != PLUS)
                    841:     {
                    842:       if (class == YBASE_VIRT_REGS)
                    843:        return NON_YBASE_REGS;
                    844:       else
                    845:         return NO_REGS;
                    846:     }
                    847: 
                    848:   if (GET_CODE (in) == PLUS && mode == QImode)
                    849:     {
                    850:       rtx addr0 = XEXP (in, 0);
                    851:       rtx addr1 = XEXP (in, 1);
                    852: 
                    853:       /* If we are reloading a plus (reg:QI) (reg:QI)
                    854:         we need a low accumulator, not a high one. */
                    855:       if (REG_P (addr0) && REG_P (addr1))
                    856:        return ACCUM_LOW_REGS;
                    857:     }
                    858: 
                    859: #if 0
                    860:   if (REG_P(in))
                    861:     return ACCUM_REGS;
                    862: #endif
                    863: 
                    864:   /* Otherwise, we need a high accumulator(s).  */
                    865:   return ACCUM_HIGH_REGS;
                    866: }
                    867: 
                    868: int
                    869: symbolic_address_operand (op, mode)
                    870: rtx op;
                    871: enum machine_mode mode;
                    872: {
                    873:     return (symbolic_address_p (op));
                    874: 
                    875: }
                    876: 
                    877: int symbolic_address_p (op)
                    878: rtx op;
                    879: {
                    880:   switch (GET_CODE (op))
                    881:     {
                    882:     case SYMBOL_REF:
                    883:     case LABEL_REF:
                    884:       return 1;
                    885: 
                    886:     case CONST:
                    887:       op = XEXP (op, 0);
                    888:       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
                    889:               || GET_CODE (XEXP (op, 0)) == LABEL_REF)
                    890:              && GET_CODE (XEXP (op, 1)) == CONST_INT
                    891:               && INTVAL (XEXP (op,1)) < 0x20);
                    892: 
                    893:     default:
                    894:       return 0;
                    895:     }
                    896: }
                    897: 
                    898: /* For a Y address space operand we allow only *rn, *rn++, *rn--.
                    899:    This routine only recognizes *rn, the '<>' constraints recognize
                    900:    *rn++, *rn-- */
                    901: 
                    902: int
                    903: Y_address_operand (op, mode)
                    904: rtx op;
                    905: enum machine_mode mode;
                    906: {
                    907:    return (memory_address_p (mode, op) && !symbolic_address_p (op));
                    908: }           
                    909: 
                    910: int
                    911: sp_operand (op, mode)
                    912: rtx op;
                    913: enum machine_mode mode;
                    914: {
                    915:     return (GET_CODE (op) == PLUS
                    916:            && (XEXP (op, 0) == stack_pointer_rtx
                    917:                || XEXP (op, 0) == frame_pointer_rtx)
                    918:            && GET_CODE (XEXP (op,1)) == CONST_INT);
                    919: }
                    920: 
                    921: int
                    922: sp_operand2 (op, mode)
                    923: rtx op;
                    924: enum machine_mode mode;
                    925: {
                    926:   if ((GET_CODE (op) == PLUS 
                    927:        && (XEXP (op, 0) == stack_pointer_rtx
                    928:           || XEXP (op, 0) == frame_pointer_rtx)
                    929:        && (REG_P (XEXP (op,1))
                    930:           && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
                    931:     return 1;
                    932:   else if ((GET_CODE (op) == PLUS
                    933:        && (XEXP (op, 1) == stack_pointer_rtx
                    934:           || XEXP (op, 1) == frame_pointer_rtx)
                    935:        && (REG_P (XEXP (op,0))
                    936:           && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
                    937:     return 1;
                    938:   else
                    939:     return 0;
                    940: }
                    941: 
                    942: int
                    943: nonmemory_arith_operand (op, mode)
                    944: rtx op;
                    945: enum machine_mode mode;
                    946: {
                    947:   return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
                    948: }
                    949: 
                    950: int
                    951: arith_reg_operand (op, mode)
                    952: rtx op;
                    953: enum machine_mode mode;
                    954: {
                    955:   return (register_operand (op, mode)
                    956:          && (GET_CODE (op) != REG
                    957:              || REGNO (op) >= FIRST_PSEUDO_REGISTER
                    958:              || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op)))
                    959:                  && REGNO (op) != FRAME_POINTER_REGNUM)));
                    960: }
                    961: 
                    962: int
                    963: call_address_operand (op, mode)
                    964: rtx op;
                    965: enum machine_mode mode;
                    966: {
                    967:     if (symbolic_address_p (op) || REG_P(op))
                    968:     {
                    969:        return 1;
                    970:     }
                    971: 
                    972:     return 0;
                    973: }
                    974: 
                    975: int
                    976: dsp16xx_comparison_operator (op, mode)
                    977:     register rtx op;
                    978:     enum machine_mode mode;
                    979: {
                    980:   return ((mode == VOIDmode || GET_MODE (op) == mode)
                    981:          && GET_RTX_CLASS (GET_CODE (op)) == '<'
                    982:          && (GET_CODE(op) != GE && GET_CODE (op) != LT &&
                    983:              GET_CODE (op) != GEU && GET_CODE (op) != LTU));
                    984: }
                    985: 
                    986: void
                    987: notice_update_cc(exp)
                    988: rtx exp;
                    989: {
                    990:     if (GET_CODE (exp) == SET)
                    991:     {
                    992:        /* Jumps do not alter the cc's.  */
                    993: 
                    994:        if (SET_DEST (exp) == pc_rtx)
                    995:            return;
                    996: 
                    997:        /* Moving register or memory into a register:
                    998:           it doesn't alter the cc's, but it might invalidate
                    999:           the RTX's which we remember the cc's came from.
                   1000:           (Note that moving a constant 0 or 1 MAY set the cc's).  */
                   1001:        if (REG_P (SET_DEST (exp))
                   1002:            && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
                   1003:        {
                   1004:            if (cc_status.value1
                   1005:                && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
                   1006:                cc_status.value1 = 0;
                   1007:            if (cc_status.value2
                   1008:                && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
                   1009:                cc_status.value2 = 0;
                   1010:            return;
                   1011:        }
                   1012:        /* Moving register into memory doesn't alter the cc's.
                   1013:           It may invalidate the RTX's which we remember the cc's came from.  */
                   1014:        if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
                   1015:        {
                   1016:            if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
                   1017:                cc_status.value1 = 0;
                   1018:            if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
                   1019:                cc_status.value2 = 0;
                   1020:            return;
                   1021:        }
                   1022:        /* Function calls clobber the cc's.  */
                   1023:        else if (GET_CODE (SET_SRC (exp)) == CALL)
                   1024:        {
                   1025:            CC_STATUS_INIT;
                   1026:            return;
                   1027:        }
                   1028:        /* Tests and compares set the cc's in predictable ways.  */
                   1029:        else if (SET_DEST (exp) == cc0_rtx)
                   1030:        {
                   1031:            CC_STATUS_INIT;
                   1032:            cc_status.value1 = SET_SRC (exp);
                   1033:            return;
                   1034:        }
                   1035:        /* Certain instructions effect the condition codes. */
                   1036:        else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT)
                   1037:            switch( GET_CODE (SET_SRC (exp)) )
                   1038:            {
                   1039:            case PLUS: 
                   1040:            case MINUS:
                   1041:              if (REG_P (SET_DEST (exp)))
                   1042:                {
                   1043:                  /* Address registers don't set the condition codes */
                   1044:                  if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp))))
                   1045:                    {
                   1046:                      CC_STATUS_INIT;
                   1047:                      break;
                   1048:                    }
                   1049:                }
                   1050:            case ASHIFTRT: 
                   1051:            case LSHIFTRT:
                   1052:            case ASHIFT: 
                   1053:            case AND: 
                   1054:            case IOR: 
                   1055:            case XOR:
                   1056:            case MULT:
                   1057:            case NEG:
                   1058:            case NOT:
                   1059:              cc_status.value1 = SET_SRC (exp);
                   1060:              cc_status.value2 = SET_DEST (exp);
                   1061:              break;
                   1062:              
                   1063:            default:
                   1064:              CC_STATUS_INIT;
                   1065:            }
                   1066:        else
                   1067:        {
                   1068:            CC_STATUS_INIT;
                   1069:        }
                   1070:     }
                   1071:     else if (GET_CODE (exp) == PARALLEL
                   1072:             && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
                   1073:     {
                   1074:        if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
                   1075:            return;
                   1076: 
                   1077:        if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
                   1078:        {
                   1079:            CC_STATUS_INIT;
                   1080:            cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
                   1081:            return;
                   1082:        }
                   1083: 
                   1084:        CC_STATUS_INIT;
                   1085:     }
                   1086:     else
                   1087:     {
                   1088:        CC_STATUS_INIT;
                   1089:     }
                   1090: }
                   1091: 
                   1092: int
                   1093: dsp16xx_makes_calls ()
                   1094: {
                   1095:   rtx insn;
                   1096: 
                   1097:   for (insn = get_insns (); insn; insn = next_insn (insn))
                   1098:     if (GET_CODE (insn) == CALL_INSN)
                   1099:       return (1);
                   1100: 
                   1101:   return 0;
                   1102: }
                   1103: 
                   1104: long compute_frame_size (size)
                   1105: int size;
                   1106: {
                   1107:   long total_size;
                   1108:   long var_size;
                   1109:   long args_size;
                   1110:   long extra_size;
                   1111:   long reg_size;
                   1112: 
                   1113:   reg_size = 0;
                   1114:   extra_size = 0;
                   1115:   var_size = size;
                   1116:   args_size = current_function_outgoing_args_size;
                   1117:   reg_size = reg_save_size ();  
                   1118: 
                   1119:   total_size = var_size + args_size + extra_size + reg_size;
                   1120: 
                   1121: 
                   1122:   /* Save other computed information.  */
                   1123:   current_frame_info.total_size  = total_size;
                   1124:   current_frame_info.var_size    = var_size;
                   1125:   current_frame_info.args_size   = args_size;
                   1126:   current_frame_info.extra_size  = extra_size;
                   1127:   current_frame_info.reg_size    = reg_size;
                   1128:   current_frame_info.initialized = reload_completed;
                   1129:   current_frame_info.reg_size   = reg_size / UNITS_PER_WORD;
                   1130:   current_frame_info.function_makes_calls = dsp16xx_makes_calls ();
                   1131: 
                   1132:   if (reg_size)
                   1133:     {
                   1134:       unsigned long offset = args_size + var_size + reg_size;
                   1135:       current_frame_info.sp_save_offset = offset;
                   1136:       current_frame_info.fp_save_offset = offset - total_size;
                   1137:     }
                   1138: 
                   1139:   return total_size;
                   1140: }
                   1141: 
                   1142: int
                   1143: dsp16xx_call_saved_register (regno)
                   1144: int regno;
                   1145: {
                   1146:   return (regs_ever_live[regno] && !call_used_regs[regno] &&
                   1147:          !IS_YBASE_REGISTER_WINDOW(regno));
                   1148: 
                   1149: }
                   1150: 
                   1151: int
                   1152: ybase_regs_ever_used ()
                   1153: {
                   1154:   int regno;
                   1155:   int live = 0;
                   1156: 
                   1157:   for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
                   1158:     if (regs_ever_live[regno])
                   1159:       {
                   1160:        live = 1;
                   1161:        break;
                   1162:       }
                   1163: 
                   1164:   return live;
                   1165: }
                   1166: 
                   1167: void 
                   1168: function_prologue (file, size)
                   1169: FILE *file;
                   1170: int  size;
                   1171: {
                   1172:   int regno;
                   1173:   long total_size;
                   1174:   fp = reg_names[FRAME_POINTER_REGNUM];
                   1175:   sp = reg_names[STACK_POINTER_REGNUM];
                   1176:   rr = reg_names[RETURN_ADDRESS_REGNUM];   /* return address register */
                   1177:   a1h = reg_names[REG_A1];
                   1178:   
                   1179:   total_size = compute_frame_size (size);
                   1180:   
                   1181:   fprintf( file, "\t/* FUNCTION PROLOGUE: */\n" );
                   1182:   fprintf (file, "\t/* total=%d, vars= %d, regs= %d, args=%d, extra= %d */\n",
                   1183:           current_frame_info.total_size,
                   1184:           current_frame_info.var_size,
                   1185:           current_frame_info.reg_size,
                   1186:           current_function_outgoing_args_size,
                   1187:           current_frame_info.extra_size);
                   1188:   
                   1189:   fprintf (file, "\t/* fp save offset= %d, sp save_offset= %d */\n\n",
                   1190:           current_frame_info.fp_save_offset,
                   1191:           current_frame_info.sp_save_offset);
                   1192:   /* Set up the 'ybase' register window. */
                   1193:   
                   1194:   if (ybase_regs_ever_used())
                   1195:     {
                   1196:       fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
                   1197:       if (TARGET_YBASE_HIGH)
                   1198:        fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
                   1199:       else
                   1200:        fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
                   1201:       fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
                   1202:     }
                   1203:   
                   1204: #if 0
                   1205:   if (current_frame_info.function_makes_calls)
                   1206:     fprintf( file, "\t*%s++=%s\n", sp, rr );   /* Push return address */
                   1207: #endif
                   1208:   
                   1209:   
                   1210:   if (current_frame_info.var_size)
                   1211:     {
                   1212:       if (current_frame_info.var_size == 1)
                   1213:        fprintf (file, "\t*%s++\n", sp);
                   1214:       else
                   1215:         {
                   1216:          if(SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0))
                   1217:            fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]);
                   1218:          else
                   1219:            fatal ("Stack size > 32k");
                   1220:        }
                   1221:     }
                   1222:   
                   1223:   /* Save any registers this function uses, unless they are
                   1224:    * used in a call, in which case we don't need to
                   1225:    */
                   1226:   
                   1227:   for( regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno )
                   1228:     if (dsp16xx_call_saved_register (regno)) 
                   1229:       {
                   1230: #if OLD_REGISTER_SAVE
                   1231:        fprintf( file, "\t*%s++=%s\n", sp, reg_names[regno] );
                   1232: #else
                   1233:        fprintf( file, "\tpush(*%s)=%s\n", sp, reg_names[regno] );
                   1234: #endif
                   1235:       }
                   1236:   
                   1237:   if (current_frame_info.args_size)
                   1238:     {
                   1239:       if (current_frame_info.args_size == 1)
                   1240:        fprintf (file, "\t*%s++\n", sp);
                   1241:       else
                   1242:         {
                   1243:          if(SMALL_INTVAL(current_frame_info.args_size) && ((current_frame_info.args_size & 0x8000) == 0))
                   1244:            fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.args_size, sp, reg_names[REG_J]);
                   1245:          else
                   1246:            fatal ("Stack size > 32k");
                   1247:        }
                   1248:     }
                   1249:   
                   1250:   if (frame_pointer_needed)
                   1251:     {
                   1252:       fprintf( file, "\t%s=%s\n", a1h, sp );
                   1253:       fprintf( file, "\t%s=%s\n", fp, a1h );  /* Establish new base frame */
                   1254:       fprintf( file, "\t%s=%d\n", reg_names[REG_J], -total_size);
                   1255:       fprintf( file, "\t*%s++%s\n", fp, reg_names[REG_J]);
                   1256:     }
                   1257:   
                   1258:   fprintf( file, "\t/* END FUNCTION PROLOGUE: */\n\n" );
                   1259: }
                   1260: 
                   1261: void
                   1262: init_emulation_routines ()
                   1263: {
                   1264:  dsp16xx_addhf3_libcall = (rtx) 0;
                   1265:  dsp16xx_subhf3_libcall = (rtx) 0;
                   1266:  dsp16xx_mulhf3_libcall = (rtx) 0;
                   1267:  dsp16xx_divhf3_libcall = (rtx) 0;
                   1268:  dsp16xx_cmphf3_libcall = (rtx) 0;
                   1269:  dsp16xx_fixhfhi2_libcall = (rtx) 0;
                   1270:  dsp16xx_floathihf2_libcall = (rtx) 0;
                   1271:  dsp16xx_neghf2_libcall = (rtx) 0;
                   1272: 
                   1273:  dsp16xx_mulhi3_libcall = (rtx) 0;
                   1274:  dsp16xx_udivqi3_libcall = (rtx) 0;
                   1275:  dsp16xx_udivhi3_libcall = (rtx) 0;
                   1276:  dsp16xx_divqi3_libcall = (rtx) 0;
                   1277:  dsp16xx_divhi3_libcall = (rtx) 0;
                   1278:  dsp16xx_modqi3_libcall = (rtx) 0;
                   1279:  dsp16xx_modhi3_libcall = (rtx) 0;
                   1280:  dsp16xx_umodqi3_libcall = (rtx) 0;
                   1281:  dsp16xx_umodhi3_libcall = (rtx) 0;
                   1282:  dsp16xx_ashrhi3_libcall = (rtx) 0;
                   1283:  dsp16xx_ashlhi3_libcall = (rtx) 0;
                   1284:  dsp16xx_ucmphi2_libcall = (rtx) 0;
                   1285:  dsp16xx_lshrhi3_libcall = (rtx) 0;
                   1286: 
                   1287: }
                   1288: void
                   1289: function_epilogue (file, size)
                   1290: FILE *file;
                   1291: int   size;
                   1292: {
                   1293:   int regno;
                   1294:   int initial_stack_dec = 0;
                   1295:   
                   1296:   fp = reg_names[FRAME_POINTER_REGNUM];
                   1297:   sp = reg_names[STACK_POINTER_REGNUM];
                   1298:   rr = reg_names[RETURN_ADDRESS_REGNUM];   /* return address register */
                   1299:   a1h = reg_names[REG_A1];
                   1300:   
                   1301:   fprintf( file, "\n\t/* FUNCTION EPILOGUE: */\n" );
                   1302:   
                   1303:   if (current_frame_info.args_size)
                   1304:     {
                   1305:       if (current_frame_info.args_size == 1)
                   1306:        fprintf (file, "\t*%s--\n", sp);
                   1307:       else
                   1308:        {
                   1309:          fprintf (file, "\t%s=%d\n\t*%s++%s\n", 
                   1310:                   reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]);
                   1311:        }
                   1312:     }
                   1313:   
                   1314:   if (ybase_regs_ever_used())
                   1315:     {
                   1316:       fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
                   1317:       if (TARGET_YBASE_HIGH)
                   1318:        fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
                   1319:       else
                   1320:        fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
                   1321:       fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
                   1322:     }
                   1323:   
                   1324:   for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
                   1325:     if (dsp16xx_call_saved_register(regno))
                   1326:       {
                   1327: #if OLD_REGISTER_SAVE
                   1328:        if (!initial_stack_dec)
                   1329:          {
                   1330:            initial_stack_dec = 1;
                   1331:            fprintf (file, "\t*%s--\n", sp);
                   1332:          }
                   1333: #endif
                   1334: 
                   1335: #if OLD_REGISTER_SAVE
                   1336:        fprintf( file, "\t%s=*%s--\n", reg_names[regno], sp );
                   1337: #else
                   1338:        fprintf( file, "\t%s=pop(*%s)\n", reg_names[regno], sp );
                   1339: #endif
                   1340:       }
                   1341:   
                   1342:   /* If we restored any registers we have to account for the
                   1343:      initial pre-decrement. But only if we had any local variables
                   1344:      or spills. */
                   1345: #if OLD_REGISTER_SAVE  
                   1346:   if (initial_stack_dec) 
                   1347:     fprintf (file, "\t*%s++\n", sp);
                   1348: #endif
                   1349:   
                   1350:   if (current_frame_info.var_size)
                   1351:     {
                   1352:       if (current_frame_info.var_size == 1)
                   1353:        fprintf (file, "\t*%s--\n", sp);
                   1354:       else
                   1355:        {
                   1356:          fprintf (file, "\t%s=%d\n\t*%s++%s\n", 
                   1357:                   reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]);
                   1358:        }
                   1359:     }
                   1360:   
                   1361:   fprintf (file, "\treturn\n");
                   1362:   /* Reset the frame info for the next function */
                   1363:   current_frame_info = zero_frame_info;
                   1364:   init_emulation_routines ();
                   1365: }
                   1366: 
                   1367: /* Emit insns to move operands[1] into operands[0].
                   1368: 
                   1369:    Return 1 if we have written out everything that needs to be done to
                   1370:    do the move.  Otherwise, return 0 and the caller will emit the move
                   1371:    normally.  */
                   1372: 
                   1373: int
                   1374: emit_move_sequence (operands, mode)
                   1375:      rtx *operands;
                   1376:      enum machine_mode mode;
                   1377: {
                   1378:   register rtx operand0 = operands[0];
                   1379:   register rtx operand1 = operands[1];
                   1380: 
                   1381:   /* We can only store registers to memory.  */
                   1382: 
                   1383:   if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
                   1384:     operands[1] = force_reg (mode, operand1);
                   1385: 
                   1386:   return 0;
                   1387: }
                   1388: 
                   1389: void
                   1390: double_reg_from_memory (operands)
                   1391: rtx operands[];
                   1392: {
                   1393:     rtx xoperands[4];
                   1394: 
                   1395:     if (GET_CODE(XEXP(operands[1],0)) == POST_INC)
                   1396:     {
                   1397:        output_asm_insn ("%u0=%1", operands);
                   1398:        output_asm_insn ("%w0=%1", operands);
                   1399:     }
                   1400:     else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC)
                   1401:     {
                   1402:        xoperands[1] = XEXP (XEXP (operands[1], 0), 0);
                   1403:        xoperands[0] = operands[0];
                   1404:        
                   1405:        /* We can't use j anymore since the compiler can allocate it. */
                   1406: /*     output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */
                   1407:        output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands);
                   1408:     }
                   1409:     else if (GET_CODE(XEXP(operands[1],0)) == PLUS)
                   1410:     {
                   1411:       rtx addr;
                   1412:       rtx base;
                   1413:       int offset;
                   1414: 
                   1415:       output_asm_insn ("%u0=%1", operands);
                   1416: 
                   1417: 
                   1418:       /* In order to print out the least significant word we must
                   1419:         use 'offset + 1'.  */
                   1420:       addr = XEXP (operands[1], 0);
                   1421:       if (GET_CODE (XEXP(addr,0)) == CONST_INT)
                   1422:        offset = INTVAL(XEXP(addr,0)) + 1;
                   1423:       else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
                   1424:        offset = INTVAL(XEXP(addr,1)) + 1;
                   1425: 
                   1426:       fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31);
                   1427:     }
                   1428:     else
                   1429:     {
                   1430:        xoperands[1] = XEXP(operands[1],0);
                   1431:        xoperands[0] = operands[0];
                   1432: 
                   1433:        output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
                   1434:     }
                   1435: }
                   1436: 
                   1437: 
                   1438: void
                   1439: double_reg_to_memory (operands)
                   1440: rtx operands[];
                   1441: {
                   1442:     rtx xoperands[4];
                   1443: 
                   1444:     if (GET_CODE(XEXP(operands[0],0)) == POST_INC)
                   1445:     {
                   1446:        output_asm_insn ("%0=%u1", operands);
                   1447:        output_asm_insn ("%0=%w1", operands);
                   1448:     }
                   1449:     else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC)
                   1450:     {
                   1451:        xoperands[0] = XEXP (XEXP (operands[0], 0), 0);
                   1452:        xoperands[1] = operands[1];
                   1453:        
                   1454:        /* We can't use j anymore since the compiler can allocate it. */
                   1455: 
                   1456: /*     output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */
                   1457:        output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands);
                   1458: 
                   1459:     }
                   1460:     else if (GET_CODE(XEXP(operands[0],0)) == PLUS)
                   1461:     {
                   1462:       rtx addr;
                   1463:       int offset;
                   1464: 
                   1465:       output_asm_insn ("%0=%u1", operands);
                   1466: 
                   1467:       /* In order to print out the least significant word we must
                   1468:         use 'offset + 1'.  */
                   1469:       addr = XEXP (operands[0], 0);
                   1470:       if (GET_CODE (XEXP(addr,0)) == CONST_INT)
                   1471:        offset = INTVAL(XEXP(addr,0)) + 1;
                   1472:       else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
                   1473:        offset = INTVAL(XEXP(addr,1)) + 1;
                   1474:       else
                   1475:        fatal ("Illegal addressing mode");
                   1476: 
                   1477:       fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
                   1478:     }
                   1479:     else
                   1480:     {
                   1481:        xoperands[0] = XEXP(operands[0],0);
                   1482:        xoperands[1] = operands[1];
                   1483: 
                   1484:        output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
                   1485:     }
                   1486: }
                   1487: 
                   1488: void
                   1489: override_options ()
                   1490: {
                   1491:   if (chip_name == (char *) 0)
                   1492:     chip_name = DEFAULT_CHIP_NAME;
                   1493: 
                   1494:   if (text_seg_name == (char *) 0)
                   1495:     text_seg_name = DEFAULT_TEXT_SEG_NAME;
                   1496:   
                   1497:   if (data_seg_name == (char *) 0)
                   1498:     data_seg_name = DEFAULT_DATA_SEG_NAME;
                   1499:   
                   1500:   if (bss_seg_name == (char *) 0)
                   1501:     bss_seg_name = DEFAULT_BSS_SEG_NAME;
                   1502:   
                   1503:   if (const_seg_name == (char *) 0)
                   1504:     const_seg_name = DEFAULT_CONST_SEG_NAME;
                   1505:   
                   1506:   save_chip_name = (char *) xmalloc (strlen(chip_name) + 1);
                   1507:   strcpy (save_chip_name, chip_name);
                   1508: 
                   1509:   rsect_text = (char *) xmalloc (strlen(".rsect ") + 
                   1510:                                 strlen(text_seg_name) + 3);
                   1511:   rsect_data = (char *) xmalloc (strlen(".rsect ") + 
                   1512:                                 strlen(data_seg_name) + 3);
                   1513:   rsect_bss = (char *) xmalloc (strlen(".rsect ") + 
                   1514:                                strlen(bss_seg_name) + 3);
                   1515:   rsect_const = (char *) xmalloc (strlen(".rsect ") + 
                   1516:                                  strlen(const_seg_name) + 3);
                   1517:   
                   1518:   sprintf (rsect_text, ".rsect \"%s\"", text_seg_name);
                   1519:   sprintf (rsect_data, ".rsect \"%s\"", data_seg_name);
                   1520:   sprintf (rsect_bss,  ".rsect \"%s\"", bss_seg_name);
                   1521:   sprintf (rsect_const, ".rsect \"%s\"", const_seg_name);
                   1522:   
                   1523:   if (optimize)
                   1524:     {
                   1525:       if (TARGET_OPTIMIZE_SPEED)
                   1526:        {
                   1527:          flag_unroll_loops = 1;
                   1528:          flag_inline_functions = 1;
                   1529:        }
                   1530:     }
                   1531: }
                   1532: 
                   1533: enum rtx_code save_next_cc_user_code;
                   1534: 
                   1535: enum rtx_code
                   1536: next_cc_user_code (insn)
                   1537: rtx insn;
                   1538: {
                   1539:   if ( !(insn = next_cc0_user (insn)))
                   1540:     abort ();
                   1541:   else if (GET_CODE (insn) == JUMP_INSN
                   1542:           && GET_CODE (PATTERN (insn)) == SET
                   1543:           && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
                   1544:     return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
                   1545:   else if (GET_CODE (insn) == INSN
                   1546:           && GET_CODE (PATTERN (insn)) == SET
                   1547:           && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode))
                   1548:     return GET_CODE (SET_SRC (PATTERN (insn)));
                   1549:   else
                   1550:     abort ();
                   1551: }
                   1552: 
                   1553: void
                   1554: print_operand(file, op, letter)
                   1555: FILE *file;
                   1556: rtx op;
                   1557: int letter;
                   1558: {
                   1559:     enum rtx_code code;
                   1560: 
                   1561:     code = GET_CODE(op);
                   1562: 
                   1563:     switch (letter)
                   1564:     {
                   1565:        case 'I':
                   1566:          code = reverse_condition (code);
                   1567:          /* Fallthrough */
                   1568: 
                   1569:        case 'C':
                   1570:           if (code == EQ) 
                   1571:           { 
                   1572:              fputs ("eq", file); 
                   1573:              return; 
                   1574:          }
                   1575:           else if (code == NE)  
                   1576:          { 
                   1577:              fputs ("ne", file); 
                   1578:              return; 
                   1579:          }
                   1580:           else if (code == GT || code == GTU)  
                   1581:          { 
                   1582:              fputs ("gt", file); 
                   1583:              return; 
                   1584:          }
                   1585:           else if (code == LT || code == LTU)  
                   1586:          { 
                   1587:              fputs ("mi", file); 
                   1588:              return; 
                   1589:          }
                   1590:           else if (code == GE || code == GEU)  
                   1591:          {
                   1592:              fputs ("pl", file); 
                   1593:              return; 
                   1594:          }
                   1595:           else if (code == LE || code == LEU)  
                   1596:          { 
                   1597:              fputs ("le", file); 
                   1598:              return; 
                   1599:          }
                   1600:           else 
                   1601:              abort ();
                   1602:          break;
                   1603: 
                   1604:        default:
                   1605:           break;  
                   1606:     }
                   1607: 
                   1608:     if( code == REG )
                   1609:     {
                   1610:        /* Print the low half of a 32-bit register pair */
                   1611:         if (letter == 'w')
                   1612:            fprintf( file, "%s", reg_names[REGNO(op)+1] );
                   1613:         else if (letter == 'u' || !letter)
                   1614:            fprintf( file, "%s", reg_names[REGNO(op)]);
                   1615:        else if (letter == 'b')
                   1616:            fprintf ( file, "%sh", reg_names[REGNO(op)]);
                   1617:        else if (letter == 'm')
                   1618:          fprintf (file, "%s", himode_reg_name[REGNO(op)]);
                   1619:         else
                   1620:            fatal("Bad register extension code");
                   1621:     }
                   1622:     else if( code == MEM )
                   1623:         output_address( XEXP(op,0) );
                   1624:     else if( code == CONST_INT )
                   1625:     { 
                   1626:         if( letter == 'H' )
                   1627:             fprintf( file, "0x%x", (INTVAL(op) & 0xffff) );
                   1628:        else if (letter == 'h')
                   1629:             fprintf( file, "%d", INTVAL (op) );
                   1630:         else if( letter == 'U' )
                   1631:             fprintf( file, "0x%x", ((INTVAL(op) & 0xffff0000) >> 16) & 0xffff );
                   1632:         else
                   1633:            output_addr_const( file, op );
                   1634:     }
                   1635:     else if( code == CONST_DOUBLE && GET_MODE(op) != DImode )
                   1636:     {
                   1637:          union { double d; int i[2]; } u;
                   1638:          union { float f; int i; } u1;
                   1639:          u.i[0] = CONST_DOUBLE_LOW (op);
                   1640:          u.i[1] = CONST_DOUBLE_HIGH (op);
                   1641:          u1.f = u.d;
                   1642:           fprintf( file, "0x%x", u1.i );
                   1643:     }
                   1644:     else output_addr_const( file, op);
                   1645: }
                   1646: 
                   1647: 
                   1648: void
                   1649: print_operand_address(file, addr)
                   1650: FILE *file;
                   1651: rtx addr;
                   1652: {
                   1653:   rtx base;
                   1654:   int offset;
                   1655:   
                   1656:   switch (GET_CODE (addr))
                   1657:     {
                   1658:     case REG:
                   1659:       fprintf (file, "*%s", reg_names[REGNO (addr)]);
                   1660:       break;
                   1661:     case POST_DEC:
                   1662:       fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
                   1663:       break;
                   1664:     case POST_INC:
                   1665:       fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
                   1666:       break;
                   1667:     case PLUS:
                   1668:       if (GET_CODE (XEXP(addr,0)) == CONST_INT)
                   1669:        offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1);
                   1670:       else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
                   1671:        offset = INTVAL(XEXP(addr,1)), base = XEXP(addr,0);
                   1672:       if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
                   1673:        {
                   1674:          if (offset >= -31 && offset <= 0)
                   1675:            offset = 31 + offset;
                   1676:          else
                   1677:            fatal ("Illegal offset in ybase addressing");
                   1678:        }
                   1679:       else
                   1680:        fatal ("Illegal register in ybase addresing");
                   1681:       
                   1682:       fprintf (file, "*(%d)", offset);
                   1683:       break;
                   1684:       
                   1685:     default:
                   1686:       if( FITS_5_BITS( addr ) )
                   1687:        fprintf( file, "*(0x%x)", (INTVAL(addr) & 0x20) );
                   1688:       else
                   1689:        output_addr_const(file, addr);
                   1690:     }
                   1691: }
                   1692: 
                   1693: void
                   1694: output_dsp16xx_float_const(operands)
                   1695: rtx *operands;
                   1696: {
                   1697:   rtx dst = operands[0];
                   1698:   rtx src = operands[1];
                   1699:   
                   1700: #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
                   1701:   REAL_VALUE_TYPE d;
                   1702:   long value;
                   1703:   
                   1704:   REAL_VALUE_FROM_CONST_DOUBLE (d, src);
                   1705:   REAL_VALUE_TO_TARGET_SINGLE (d, value);
                   1706:   
                   1707:   operands[1] = gen_rtx (CONST_INT, VOIDmode, value);
                   1708:   output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands);
                   1709: #else
                   1710:   fatal ("inline float constants not supported on this host");
                   1711: #endif
                   1712: }
                   1713: 
                   1714: int
                   1715: reg_save_size ()
                   1716: {
                   1717:   int reg_save_size = 0;
                   1718:  int regno;
                   1719:  
                   1720:   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                   1721:     if (dsp16xx_call_saved_register (regno))
                   1722:       {
                   1723:        reg_save_size += UNITS_PER_WORD;
                   1724:       }
                   1725: 
                   1726:   return (reg_save_size);
                   1727: }
                   1728: 
                   1729: int
                   1730: dsp16xx_starting_frame_offset()
                   1731: {
                   1732:   int reg_save_size = 0;
                   1733:  int regno;
                   1734:  
                   1735:   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
                   1736:     if (dsp16xx_call_saved_register (regno))
                   1737:       {
                   1738:        reg_save_size += UNITS_PER_WORD;
                   1739:       }
                   1740: 
                   1741:   return (reg_save_size);
                   1742: }
                   1743: 
                   1744: int
                   1745: initial_frame_pointer_offset()
                   1746: {
                   1747:   int frame_size;
                   1748:   int regno;
                   1749:   int offset = 0;
                   1750:   
                   1751:   offset = compute_frame_size (get_frame_size());
                   1752: 
                   1753: #ifdef STACK_GROWS_DOWNWARD
                   1754:   return (offset);
                   1755: #else
                   1756:   return (-offset);
                   1757: #endif
                   1758: }
                   1759: 
                   1760: /* Generate the minimum number of 1600 core shift instructions
                   1761:    to shift by 'shift_amount'. */
                   1762: 
                   1763: #if 0
                   1764: void
                   1765: emit_1600_core_shift (shift_op, operands, shift_amount, mode)
                   1766: enum rtx_code shift_op;
                   1767: rtx *operands;
                   1768: int shift_amount;
                   1769: enum machine_mode mode;
                   1770: {
                   1771:   int quotient;
                   1772:   int i;
                   1773:   int first_shift_emitted = 0;
                   1774:   
                   1775:   while (shift_amount != 0)
                   1776:     {
                   1777:       if (shift_amount/16)
                   1778:        {
                   1779:          quotient = shift_amount/16;
                   1780:          shift_amount = shift_amount - (quotient * 16);
                   1781:          for (i = 0; i < quotient; i++)
                   1782:            emit_insn (gen_rtx (SET, VOIDmode, operands[0],
                   1783:                                gen_rtx (shift_op, mode, 
                   1784:                                         first_shift_emitted ? operands[0] : operands[1],
                   1785:                                         gen_rtx (CONST_INT, VOIDmode, 16))));
                   1786:          first_shift_emitted = 1;
                   1787:        }
                   1788:       else if (shift_amount/8)
                   1789:        {
                   1790:          quotient = shift_amount/8;
                   1791:          shift_amount = shift_amount - (quotient * 8);
                   1792:          for (i = 0; i < quotient; i++)
                   1793:            emit_insn (gen_rtx (SET, VOIDmode, operands[0],
                   1794:                                gen_rtx (shift_op, mode, 
                   1795:                                         first_shift_emitted ? operands[0] : operands[1],
                   1796:                                         gen_rtx (CONST_INT, VOIDmode, 8))));
                   1797:          first_shift_emitted = 1;
                   1798:        }
                   1799:       else if (shift_amount/4)
                   1800:        {
                   1801:          quotient = shift_amount/4;
                   1802:          shift_amount = shift_amount - (quotient * 4);
                   1803:          for (i = 0; i < quotient; i++)
                   1804:            emit_insn (gen_rtx (SET, VOIDmode, operands[0],
                   1805:                                gen_rtx (shift_op, mode, 
                   1806:                                         first_shift_emitted ? operands[0] : operands[1],
                   1807:                                         gen_rtx (CONST_INT, VOIDmode, 4))));
                   1808:          first_shift_emitted = 1;
                   1809:        }
                   1810:       else if (shift_amount/1)
                   1811:        {
                   1812:          quotient = shift_amount/1;
                   1813:          shift_amount = shift_amount - (quotient * 1);
                   1814:          for (i = 0; i < quotient; i++)
                   1815:            emit_insn (gen_rtx (SET, VOIDmode, operands[0],
                   1816:                                gen_rtx (shift_op, mode, 
                   1817:                                         first_shift_emitted ? operands[0] : operands[1],
                   1818:                                         gen_rtx (CONST_INT, VOIDmode, 1))));
                   1819:          first_shift_emitted = 1;
                   1820:        }
                   1821:     }
                   1822: }
                   1823: #else
                   1824: void
                   1825: emit_1600_core_shift (shift_op, operands, shift_amount)
                   1826: enum rtx_code shift_op;
                   1827: rtx *operands;
                   1828: int shift_amount;
                   1829: {
                   1830:   int quotient;
                   1831:   int i;
                   1832:   int first_shift_emitted = 0;
                   1833:   char **shift_asm_ptr;
                   1834:   char **shift_asm_ptr_first;
                   1835: 
                   1836:   if (shift_op == ASHIFT)
                   1837:     {
                   1838:       shift_asm_ptr = ashift_left_asm;
                   1839:       shift_asm_ptr_first = ashift_left_asm_first;
                   1840:     }
                   1841:   else if (shift_op == ASHIFTRT)
                   1842:     {
                   1843:       shift_asm_ptr = ashift_right_asm;
                   1844:       shift_asm_ptr_first = ashift_right_asm_first;
                   1845:     }
                   1846:   else if (shift_op == LSHIFTRT)
                   1847:     {
                   1848:       shift_asm_ptr = lshift_right_asm;
                   1849:       shift_asm_ptr_first = lshift_right_asm_first;
                   1850:     }
                   1851:   else
                   1852:     fatal ("Illegal shift operator in emit_1600_core_shift");
                   1853: 
                   1854:   while (shift_amount != 0)
                   1855:     {
                   1856:       if (shift_amount/16)
                   1857:        {
                   1858:          quotient = shift_amount/16;
                   1859:          shift_amount = shift_amount - (quotient * 16);
                   1860:          for (i = 0; i < quotient; i++)
                   1861:            output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_16]
                   1862:                              : shift_asm_ptr_first[SHIFT_INDEX_16]), operands);
                   1863:          first_shift_emitted = 1;
                   1864:        }
                   1865:       else if (shift_amount/8)
                   1866:        {
                   1867:          quotient = shift_amount/8;
                   1868:          shift_amount = shift_amount - (quotient * 8);
                   1869:          for (i = 0; i < quotient; i++)
                   1870:            output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_8]
                   1871:                              : shift_asm_ptr_first[SHIFT_INDEX_8]), operands);
                   1872:          first_shift_emitted = 1;
                   1873:        }
                   1874:       else if (shift_amount/4)
                   1875:        {
                   1876:          quotient = shift_amount/4;
                   1877:          shift_amount = shift_amount - (quotient * 4);
                   1878:          for (i = 0; i < quotient; i++)
                   1879:            output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_4]
                   1880:                              : shift_asm_ptr_first[SHIFT_INDEX_4]), operands);
                   1881:          first_shift_emitted = 1;
                   1882:        }
                   1883:       else if (shift_amount/1)
                   1884:        {
                   1885:          quotient = shift_amount/1;
                   1886:          shift_amount = shift_amount - (quotient * 1);
                   1887:          for (i = 0; i < quotient; i++)
                   1888:            output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_1]
                   1889:                              : shift_asm_ptr_first[SHIFT_INDEX_1]), operands);
                   1890:          first_shift_emitted = 1;
                   1891:        }
                   1892:     }
                   1893: }
                   1894: #endif
                   1895: void
                   1896:   asm_output_common(file, name, size, rounded)
                   1897: FILE *file;
                   1898: char *name;
                   1899: int size;
                   1900: int rounded;
                   1901: {
                   1902:     bss_section ();
                   1903:     ASM_GLOBALIZE_LABEL (file, name);
                   1904:     assemble_name (file, name);
                   1905:     fputs (":", file);
                   1906:     if (rounded > 1)
                   1907:        fprintf (file, "%d * int\n", rounded);
                   1908:     else
                   1909:        fprintf (file, "int\n");
                   1910: }
                   1911: 
                   1912: void
                   1913: asm_output_local(file, name, size, rounded)
                   1914: FILE *file;
                   1915: char *name;
                   1916: int size;
                   1917: int rounded;
                   1918: {
                   1919:     bss_section ();
                   1920:     assemble_name (file, name);
                   1921:     fputs (":", file);
                   1922:     if (rounded > 1)
                   1923:        fprintf (file, "%d * int\n", rounded);
                   1924:     else
                   1925:        fprintf (file, "int\n");
                   1926: }
                   1927: 
                   1928: void
                   1929: asm_output_float (file, fp_const)
                   1930: FILE *file;
                   1931: double fp_const;
                   1932: {
                   1933: #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
                   1934:       REAL_VALUE_TYPE d = fp_const;
                   1935:       long value;
                   1936: 
                   1937:       REAL_VALUE_TO_TARGET_SINGLE (d, value);
                   1938:       fputs ("\tint ", file);
                   1939: #ifdef WORDS_BIG_ENDIAN
                   1940:       fprintf (file, "0x%-4.4x, 0x%-4.4x", (value >> 16) & 0xffff, (value & 0xffff));
                   1941: #else
                   1942:       fprintf (file, "0x%-4.4x, 0x%-4.4x", (value & 0xffff), (value >> 16) & 0xffff);
                   1943: #endif
                   1944:       fputs ("\n", file);
                   1945: #else
                   1946:       fatal ("inline float constants not supported on this host");
                   1947: #endif
                   1948: }
                   1949: 
                   1950: void
                   1951: asm_output_long (file, value)
                   1952: FILE *file;
                   1953: long value;
                   1954: {
                   1955:       fputs ("\tint ", file);
                   1956: #ifdef WORDS_BIG_ENDIAN
                   1957:       fprintf (file, "0x%-4.4x, 0x%-4.4x", (value >> 16) & 0xffff, (value & 0xffff));
                   1958: #else
                   1959:       fprintf (file, "0x%-4.4x, 0x%-4.4x", (value & 0xffff), (value >> 16) & 0xffff);
                   1960: #endif
                   1961:       fputs ("\n", file);
                   1962: }
                   1963: 
                   1964: int
                   1965: dsp16xx_address_cost (addr)
                   1966: rtx addr;
                   1967: {
                   1968:     switch (GET_CODE (addr))
                   1969:     {
                   1970:          default:
                   1971:             break;
                   1972: 
                   1973:          case REG:
                   1974:             return 1;
                   1975: 
                   1976:          case CONST:
                   1977:             {
                   1978:                rtx offset = const0_rtx;
                   1979:                addr = eliminate_constant_term (addr, &offset);
                   1980: 
                   1981:                if (GET_CODE (addr) == LABEL_REF)
                   1982:                    return 2;
                   1983: 
                   1984:                if (GET_CODE (addr) != SYMBOL_REF)
                   1985:                    return 4;
                   1986: 
                   1987:                if (INTVAL (offset) == 0)
                   1988:                    return 2;
                   1989:              }
                   1990:             /* fall through */
                   1991: 
                   1992:          case POST_INC: case POST_DEC:
                   1993:             return (GET_MODE (addr) == QImode ? 1 : 2);
                   1994: 
                   1995:          case SYMBOL_REF: case LABEL_REF:
                   1996:             return 2;
                   1997: 
                   1998:          case PLUS:
                   1999:          {
                   2000:             register rtx plus0 = XEXP (addr, 0);
                   2001:             register rtx plus1 = XEXP (addr, 1);
                   2002:             
                   2003:             if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
                   2004:             {
                   2005:                 plus0 = XEXP (addr, 1);
                   2006:                 plus1 = XEXP (addr, 0);
                   2007:             }
                   2008:             
                   2009:             if (GET_CODE (plus0) != REG)
                   2010:                 break;
                   2011:             
                   2012:             switch (GET_CODE (plus1))
                   2013:             {
                   2014:                   default:
                   2015:                      break;
                   2016:                 
                   2017:                   case CONST_INT:
                   2018:                      return 4;
                   2019: 
                   2020:                   case CONST:
                   2021:                   case SYMBOL_REF:
                   2022:                   case LABEL_REF:
                   2023:                      return dsp16xx_address_cost (plus1) + 1;
                   2024:             }
                   2025:          }
                   2026:      }
                   2027:             
                   2028:      return 4;
                   2029: }
                   2030: 
                   2031: 
                   2032: /* Determine whether a function argument is passed in a register, and
                   2033:    which register.
                   2034: 
                   2035:    The arguments are CUM, which summarizes all the previous
                   2036:    arguments; MODE, the machine mode of the argument; TYPE,
                   2037:    the data type of the argument as a tree node or 0 if that is not known
                   2038:    (which happens for C support library functions); and NAMED,
                   2039:    which is 1 for an ordinary argument and 0 for nameless arguments that
                   2040:    correspond to `...' in the called function's prototype.
                   2041: 
                   2042:    The value of the expression should either be a `reg' RTX for the
                   2043:    hard register in which to pass the argument, or zero to pass the
                   2044:    argument on the stack.
                   2045: 
                   2046:    On the dsp1610 the first four words of args are normally in registers
                   2047:    and the rest are pushed. If we a long or on float mode, the argument
                   2048:    must begin on a even register boundary
                   2049: 
                   2050:    Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
                   2051:    For structures that are passed in memory, but could have been
                   2052:    passed in registers, we first load the structure into the
                   2053:    register, and then when the last argument is passed, we store
                   2054:    the registers into the stack locations.  This fixes some bugs
                   2055:    where GCC did not expect to have register arguments, followed */
                   2056: 
                   2057: 
                   2058: struct rtx_def *
                   2059: dsp16xx_function_arg (args_so_far, mode, type, named)
                   2060:      CUMULATIVE_ARGS args_so_far;
                   2061:      enum machine_mode mode;
                   2062:      tree type;
                   2063:      int named;
                   2064: {
                   2065:   if (TARGET_REGPARM)
                   2066:     {
                   2067:       if ((args_so_far & 1) != 0
                   2068:          && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
                   2069:        args_so_far++;
                   2070: 
                   2071:       if (named && args_so_far < 4 && !MUST_PASS_IN_STACK (mode,type))
                   2072:        return gen_rtx (REG, mode, args_so_far + FIRST_REG_FOR_FUNCTION_ARG);
                   2073:       else
                   2074:        return (struct rtx_def *) 0;
                   2075:     }
                   2076:   else
                   2077:     return (struct rtx_def *) 0;
                   2078: }
                   2079: 
                   2080: /* Advance the argument to the next argument position.  */
                   2081: 
                   2082: void
                   2083: dsp16xx_function_arg_advance (cum, mode, type, named)
                   2084:      CUMULATIVE_ARGS *cum;     /* current arg information */
                   2085:      enum machine_mode mode;   /* current arg mode */
                   2086:      tree type;                        /* type of the argument or 0 if lib support */
                   2087:      int named;                        /* whether or not the argument was named */
                   2088: {
                   2089:   if (TARGET_REGPARM)
                   2090:     {
                   2091:       if ((*cum & 1) != 0
                   2092:          && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
                   2093:        *cum += 1;
                   2094: 
                   2095:       if (mode != BLKmode)
                   2096:        *cum += GET_MODE_SIZE (mode);
                   2097:       else
                   2098:        *cum += int_size_in_bytes (type);
                   2099:     }
                   2100: }
                   2101: 
                   2102: void
                   2103: dsp16xx_file_start ()
                   2104: {
                   2105:   fprintf (asm_out_file, "#include <%s.h>\n", save_chip_name);
                   2106: #if 0
                   2107:        if (TARGET_BMU)
                   2108:                fprintf (asm_out_file, "#include <1610.h>\n");
                   2109: #endif
                   2110: }
                   2111: 
                   2112: rtx
                   2113: gen_tst_reg (x)
                   2114:      rtx x;
                   2115: {
                   2116:   enum machine_mode mode;
                   2117: 
                   2118:   mode = GET_MODE (x);
                   2119: 
                   2120:   if (mode == QImode)
                   2121:     {
                   2122:          emit_insn (gen_rtx (PARALLEL, VOIDmode,
                   2123:                        gen_rtvec (2,
                   2124:                                   gen_rtx (SET, VOIDmode, cc0_rtx, x),
                   2125:                                   gen_rtx (CLOBBER, VOIDmode,
                   2126:                                            gen_rtx (SCRATCH, QImode, 0)))));
                   2127:        }
                   2128:   else if (mode == HImode)
                   2129:     emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, x));
                   2130:   else
                   2131:     fatal ("Illegal mode for gen_tst_reg");
                   2132: 
                   2133:   return cc0_rtx;
                   2134: }
                   2135: 
                   2136: rtx
                   2137: gen_compare_reg (code, x, y)
                   2138:      enum rtx_code code;
                   2139:      rtx x, y;
                   2140: {
                   2141:   enum machine_mode mode;
                   2142: 
                   2143:   mode = GET_MODE (x);
                   2144:   /* For floating point compare insns, a call is generated so don't
                   2145:      do anything here. */
                   2146: 
                   2147:   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
                   2148:     return cc0_rtx;
                   2149: 
                   2150:   if (mode == QImode)
                   2151:     {
                   2152:       if (code == GTU || code == GEU ||
                   2153:          code == LTU || code == LEU)
                   2154:        {
                   2155:          emit_insn (gen_rtx (PARALLEL, VOIDmode,
                   2156:                        gen_rtvec (3,
                   2157:                                   gen_rtx (SET, VOIDmode, cc0_rtx,
                   2158:                                            gen_rtx (COMPARE, mode, x, y)),
                   2159:                                   gen_rtx (CLOBBER, VOIDmode,
                   2160:                                            gen_rtx (SCRATCH, QImode, 0)),
                   2161:                                   gen_rtx (CLOBBER, VOIDmode,
                   2162:                                            gen_rtx (SCRATCH, QImode, 0)))));
                   2163:        }
                   2164:       else
                   2165:        {
                   2166:          emit_insn (gen_rtx (PARALLEL, VOIDmode,
                   2167:                        gen_rtvec (3,
                   2168:                                   gen_rtx (SET, VOIDmode, cc0_rtx,
                   2169:                                            gen_rtx (COMPARE, mode, x, y)),
                   2170:                                   gen_rtx (CLOBBER, VOIDmode,
                   2171:                                            gen_rtx (SCRATCH, QImode, 0)),
                   2172:                                   gen_rtx (CLOBBER, VOIDmode,
                   2173:                                            gen_rtx (SCRATCH, QImode, 0)))));
                   2174:        }
                   2175:     }
                   2176:   else if (mode == HImode)
                   2177:     {
                   2178:       if (code == GTU || code == GEU ||
                   2179:          code == LTU || code == LEU)
                   2180:        {
                   2181: #if 1
                   2182:          emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
                   2183:                             gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, x, y)),
                   2184:                             gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)),
                   2185:                             gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)),
                   2186:                             gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)),
                   2187:                             gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)))));
                   2188: #else
                   2189:          if (!dsp16xx_ucmphi2_libcall)
                   2190:            dsp16xx_ucmphi2_libcall = gen_rtx (SYMBOL_REF, Pmode, UCMPHI2_LIBCALL);
                   2191:          emit_library_call (dsp16xx_ucmphi2_libcall, 1, HImode, 2,
                   2192:                             x, HImode, y, HImode);
                   2193:          emit_insn (gen_tsthi_1 (copy_to_reg(hard_libcall_value (HImode))));
                   2194: #endif
                   2195:        }
                   2196:       else
                   2197:        emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
                   2198:                            gen_rtx (COMPARE, VOIDmode, force_reg(HImode, x), 
                   2199:                                     force_reg(HImode,y))));
                   2200:     }
                   2201:   else
                   2202:     fatal ("Illegal mode for integer comparison in gen_compare_reg");
                   2203: 
                   2204:   return cc0_rtx;
                   2205: }
                   2206: 
                   2207: char *
                   2208: output_block_move (operands)
                   2209:      rtx operands[];
                   2210: {
                   2211:   int loop_count = INTVAL(operands[2]);
                   2212:   rtx xoperands[4];
                   2213: 
                   2214:   fprintf (asm_out_file, "\tdo %d {\n", loop_count);
                   2215:   xoperands[0] = operands[4];
                   2216:   xoperands[1] = operands[1];
                   2217:   output_asm_insn ("%0=*%1++", xoperands);
                   2218: 
                   2219:   xoperands[0] = operands[0];
                   2220:   xoperands[1] = operands[4];
                   2221:   output_asm_insn ("*%0++=%1", xoperands);
                   2222: 
                   2223:   fprintf (asm_out_file, "\t}\n");
                   2224:   return "";
                   2225: }

unix.superglobalmegacorp.com

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