home *** CD-ROM | disk | FTP | other *** search
/ Geek Gadgets 1 / ADE-1.bin / ade-dist / gcc-2.7.2.1-base.tgz / gcc-2.7.2.1-base.tar / fsf / gcc / config / dsp16xx / dsp16xx.c next >
C/C++ Source or Header  |  1995-06-15  |  53KB  |  2,227 lines

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