Annotation of gcc/config/dsp16xx/dsp16xx.c, revision 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.