1 /* Subroutines for assembler code output on the DSP1610.
2 Copyright (C) 1994, 1995, 1997, 1998, 2001 Free Software Foundation, Inc.
3 Contributed by Michael Collison (collison@isisinc.net).
5 This file is part of GNU CC.
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)
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.
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. */
22 /* Some output-actions in dsp1600.md need these. */
25 #include "coretypes.h"
29 #include "hard-reg-set.h"
31 #include "insn-config.h"
32 #include "conditions.h"
34 #include "insn-attr.h"
44 #include "target-def.h"
46 const char *text_seg_name;
47 const char *rsect_text;
48 const char *data_seg_name;
49 const char *rsect_data;
50 const char *bss_seg_name;
51 const char *rsect_bss;
52 const char *const_seg_name;
53 const char *rsect_const;
55 const char *chip_name;
56 const char *save_chip_name;
58 /* Save the operands of a compare. The 16xx has not lt or gt, so
59 in these cases we swap the operands and reverse the condition. */
61 rtx dsp16xx_compare_op0;
62 rtx dsp16xx_compare_op1;
63 bool dsp16xx_compare_gen;
65 static const char *fp;
66 static const char *sp;
67 static const char *rr;
68 static const char *a1h;
70 struct dsp16xx_frame_info current_frame_info;
71 struct dsp16xx_frame_info zero_frame_info;
73 rtx dsp16xx_addhf3_libcall = (rtx) 0;
74 rtx dsp16xx_subhf3_libcall = (rtx) 0;
75 rtx dsp16xx_mulhf3_libcall = (rtx) 0;
76 rtx dsp16xx_divhf3_libcall = (rtx) 0;
77 rtx dsp16xx_cmphf3_libcall = (rtx) 0;
78 rtx dsp16xx_fixhfhi2_libcall = (rtx) 0;
79 rtx dsp16xx_floathihf2_libcall = (rtx) 0;
80 rtx dsp16xx_neghf2_libcall = (rtx) 0;
82 rtx dsp16xx_mulhi3_libcall = (rtx) 0;
83 rtx dsp16xx_udivqi3_libcall = (rtx) 0;
84 rtx dsp16xx_udivhi3_libcall = (rtx) 0;
85 rtx dsp16xx_divqi3_libcall = (rtx) 0;
86 rtx dsp16xx_divhi3_libcall = (rtx) 0;
87 rtx dsp16xx_modqi3_libcall = (rtx) 0;
88 rtx dsp16xx_modhi3_libcall = (rtx) 0;
89 rtx dsp16xx_umodqi3_libcall = (rtx) 0;
90 rtx dsp16xx_umodhi3_libcall = (rtx) 0;
91 rtx dsp16xx_ashrhi3_libcall = (rtx) 0;
92 rtx dsp16xx_ashlhi3_libcall = (rtx) 0;
93 rtx dsp16xx_ucmphi2_libcall = (rtx) 0;
94 rtx dsp16xx_lshrhi3_libcall = (rtx) 0;
96 static const char *const himode_reg_name[] = HIMODE_REGISTER_NAMES;
98 #define SHIFT_INDEX_1 0
99 #define SHIFT_INDEX_4 1
100 #define SHIFT_INDEX_8 2
101 #define SHIFT_INDEX_16 3
103 static const char *const ashift_right_asm[] =
111 static const char *const ashift_right_asm_first[] =
119 static const char *const ashift_left_asm[] =
127 static const char *const ashift_left_asm_first[] =
135 static const char *const lshift_right_asm[] =
137 "%0=%0>>1\n\t%0=%b0&0x7fff",
138 "%0=%0>>4\n\t%0=%b0&0x0fff",
139 "%0=%0>>8\n\t%0=%b0&0x00ff",
140 "%0=%0>>16\n\t%0=%b0&0x0000"
143 static const char *const lshift_right_asm_first[] =
145 "%0=%1>>1\n\t%0=%b0&0x7fff",
146 "%0=%1>>4\n\t%0=%b0&0x0fff",
147 "%0=%1>>8\n\t%0=%b0&0x00ff",
148 "%0=%1>>16\n\t%0=%b0&0x0000"
151 static int reg_save_size PARAMS ((void));
152 static void dsp16xx_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
153 static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
154 static bool dsp16xx_rtx_costs PARAMS ((rtx, int, int, int *));
155 static int dsp16xx_address_cost PARAMS ((rtx));
157 /* Initialize the GCC target structure. */
159 #undef TARGET_ASM_BYTE_OP
160 #define TARGET_ASM_BYTE_OP "\tint\t"
161 #undef TARGET_ASM_ALIGNED_HI_OP
162 #define TARGET_ASM_ALIGNED_HI_OP NULL
163 #undef TARGET_ASM_ALIGNED_SI_OP
164 #define TARGET_ASM_ALIGNED_SI_OP NULL
166 #undef TARGET_ASM_FUNCTION_PROLOGUE
167 #define TARGET_ASM_FUNCTION_PROLOGUE dsp16xx_output_function_prologue
168 #undef TARGET_ASM_FUNCTION_EPILOGUE
169 #define TARGET_ASM_FUNCTION_EPILOGUE dsp16xx_output_function_epilogue
171 #undef TARGET_RTX_COSTS
172 #define TARGET_RTX_COSTS dsp16xx_rtx_costs
173 #undef TARGET_ADDRESS_COST
174 #define TARGET_ADDRESS_COST dsp16xx_address_cost
176 struct gcc_target targetm = TARGET_INITIALIZER;
179 hard_regno_mode_ok (regno, mode)
181 enum machine_mode mode;
188 /* We can't use the c0-c2 for QImode, since they are only
192 if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
197 /* We only allow a0, a1, y, and p to be allocated for 32-bit modes.
198 Additionally we allow the virtual ybase registers to be used for 32-bit
208 if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
209 || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
220 dsp16xx_reg_class_from_letter (c)
235 return ACCUM_HIGH_REGS;
265 return ACCUM_Y_OR_P_REGS;
271 return (TARGET_BMU ? BMU_REGS : NO_REGS);
274 return YBASE_VIRT_REGS;
286 return YBASE_ELIGIBLE_REGS;
289 return ACCUM_LOW_REGS;
292 return NON_YBASE_REGS;
298 return SLOW_MEM_LOAD_REGS;
305 /* Return the class number of the smallest class containing
309 regno_reg_class(regno)
315 return (int) A0L_REG;
317 return (int) A1L_REG;
320 return (int) A0H_REG;
322 return (int) A1H_REG;
337 case REG_R0: case REG_R1: case REG_R2: case REG_R3:
338 return (int) Y_ADDR_REGS;
343 return (int) GENERAL_REGS;
346 return (int) GENERAL_REGS;
349 return (int) GENERAL_REGS;
351 case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:
352 return (int) BMU_REGS;
354 case REG_C0: case REG_C1: case REG_C2:
355 return (int) GENERAL_REGS;
358 return (int) GENERAL_REGS;
361 return (int) GENERAL_REGS;
363 case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:
364 case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:
365 case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:
366 case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:
367 case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:
368 case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:
369 case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:
370 case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:
371 return (int) YBASE_VIRT_REGS;
374 return (int) NO_REGS;
378 /* A C expression for the maximum number of consecutive registers of class CLASS
379 needed to hold a value of mode MODE. */
382 class_max_nregs(class, mode)
383 enum reg_class class ATTRIBUTE_UNUSED;
384 enum machine_mode mode;
386 return (GET_MODE_SIZE(mode));
390 limit_reload_class (mode, class)
391 enum machine_mode mode ATTRIBUTE_UNUSED;
392 enum reg_class class;
398 dsp16xx_register_move_cost (from, to)
399 enum reg_class from, to;
401 if (from == A0H_REG || from == A0L_REG || from == A0_REG ||
402 from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||
403 from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)
405 if (to == Y_REG || to == P_REG)
411 if (to == A0H_REG || to == A0L_REG || to == A0_REG ||
412 to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||
413 to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)
418 if (from == YBASE_VIRT_REGS)
420 if (to == YBASE_VIRT_REGS)
423 if (to == X_REG || to == YH_REG || to == YL_REG ||
424 to == Y_REG || to == PL_REG || to == PH_REG ||
425 to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||
434 if (to == YBASE_VIRT_REGS)
436 if (from == X_REG || from == YH_REG || from == YL_REG ||
437 from == Y_REG || from == PL_REG || from == PH_REG ||
438 from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||
450 /* Given an rtx X being reloaded into a reg required to be
451 in class CLASS, return the class of reg to actually use.
452 In general this is just CLASS; but on some machines
453 in some cases it is preferable to use a more restrictive class.
454 Also, we must ensure that a PLUS is reloaded either
455 into an accumulator or an address register. */
458 preferred_reload_class (x, class)
460 enum reg_class class;
462 /* The ybase registers cannot have constants copied directly
469 case YBASE_VIRT_REGS:
470 return (!reload_in_progress ? NO_REGS : class);
472 case ACCUM_LOW_OR_YBASE_REGS:
473 return ACCUM_LOW_REGS;
475 case ACCUM_OR_YBASE_REGS:
478 case X_OR_YBASE_REGS:
481 case Y_OR_YBASE_REGS:
484 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
485 return YL_OR_PL_OR_ACCUM_LOW_REGS;
487 case P_OR_YBASE_REGS:
490 case ACCUM_Y_P_OR_YBASE_REGS:
491 return ACCUM_Y_OR_P_REGS;
493 case Y_ADDR_OR_YBASE_REGS:
496 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
497 return NON_HIGH_YBASE_ELIGIBLE_REGS;;
499 case YBASE_OR_YBASE_ELIGIBLE_REGS:
500 return YBASE_ELIGIBLE_REGS;
502 case NO_HIGH_ALL_REGS:
503 return NOHIGH_NON_YBASE_REGS;
506 return NON_YBASE_REGS;
513 /* If x is not an accumulator or a ybase register, restrict the class of registers
514 we can copy the register into. */
516 if (REG_P (x) && !IS_ACCUM_REG (REGNO (x)) && !IS_YBASE_REGISTER_WINDOW (REGNO (x)))
521 case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
522 case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS:
523 case A1_REG: case ACCUM_REGS:
527 return (!reload_in_progress ? NO_REGS : class);
529 case X_OR_ACCUM_LOW_REGS:
530 return ACCUM_LOW_REGS;
532 case X_OR_ACCUM_REGS:
536 return (!reload_in_progress ? NO_REGS : class);
538 case YH_OR_ACCUM_HIGH_REGS:
539 return ACCUM_HIGH_REGS;
543 return (!reload_in_progress ? NO_REGS : class);
545 case YL_OR_ACCUM_LOW_REGS:
546 return ACCUM_LOW_REGS;
549 case X_OR_Y_REGS: case Y_REG:
550 return (!reload_in_progress ? NO_REGS : class);
552 case ACCUM_OR_Y_REGS:
556 case X_OR_PH_REGS: case PL_REG:
557 return (!reload_in_progress ? NO_REGS : class);
559 case PL_OR_ACCUM_LOW_REGS:
560 return ACCUM_LOW_REGS;
563 return (!reload_in_progress ? NO_REGS : class);
565 case YL_OR_PL_OR_ACCUM_LOW_REGS:
566 return ACCUM_LOW_REGS;
569 return (!reload_in_progress ? NO_REGS : class);
571 case ACCUM_OR_P_REGS:
575 return (!reload_in_progress ? NO_REGS : class);
577 case ACCUM_LOW_OR_YL_OR_P_REGS:
578 return ACCUM_LOW_REGS;
581 return (!reload_in_progress ? NO_REGS : class);
583 case ACCUM_Y_OR_P_REGS:
586 case NO_FRAME_Y_ADDR_REGS:
588 return (!reload_in_progress ? NO_REGS : class);
590 case ACCUM_LOW_OR_Y_ADDR_REGS:
591 return ACCUM_LOW_REGS;
593 case ACCUM_OR_Y_ADDR_REGS:
596 case X_OR_Y_ADDR_REGS:
597 case Y_OR_Y_ADDR_REGS:
598 case P_OR_Y_ADDR_REGS:
599 return (!reload_in_progress ? NO_REGS : class);
601 case NON_HIGH_YBASE_ELIGIBLE_REGS:
602 return ACCUM_LOW_REGS;
604 case YBASE_ELIGIBLE_REGS:
608 case J_OR_DAU_16_BIT_REGS:
610 return (!reload_in_progress ? NO_REGS : class);
612 case YBASE_VIRT_REGS:
613 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
616 return (!reload_in_progress ? NO_REGS : class);
618 case ACCUM_LOW_OR_YBASE_REGS:
619 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
622 return ACCUM_LOW_REGS;
624 case ACCUM_OR_YBASE_REGS:
625 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
630 case X_OR_YBASE_REGS:
631 case Y_OR_YBASE_REGS:
632 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
633 return YBASE_VIRT_REGS;
635 return (!reload_in_progress ? NO_REGS : class);
637 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
638 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
639 return ACCUM_LOW_OR_YBASE_REGS;
641 return ACCUM_LOW_REGS;
643 case P_OR_YBASE_REGS:
644 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
645 return YBASE_VIRT_REGS;
647 return (!reload_in_progress ? NO_REGS : class);
649 case ACCUM_Y_P_OR_YBASE_REGS:
650 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
651 return ACCUM_OR_YBASE_REGS;
655 case Y_ADDR_OR_YBASE_REGS:
656 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
657 return YBASE_VIRT_REGS;
659 return (!reload_in_progress ? NO_REGS : class);
661 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
662 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
663 return ACCUM_LOW_OR_YBASE_REGS;
665 return ACCUM_LOW_REGS;
667 case YBASE_OR_YBASE_ELIGIBLE_REGS:
668 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
669 return ACCUM_OR_YBASE_REGS;
673 case NO_HIGH_ALL_REGS:
674 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
675 return ACCUM_LOW_OR_YBASE_REGS;
677 return ACCUM_LOW_REGS;
680 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
681 return ACCUM_OR_YBASE_REGS;
685 case NOHIGH_NON_ADDR_REGS:
686 return ACCUM_LOW_REGS;
689 case SLOW_MEM_LOAD_REGS:
692 case NOHIGH_NON_YBASE_REGS:
693 return ACCUM_LOW_REGS;
695 case NO_ACCUM_NON_YBASE_REGS:
696 return (!reload_in_progress ? NO_REGS : class);
706 /* If x (the input) is a ybase register, restrict the class of registers
707 we can copy the register into. */
709 if (REG_P (x) && !TARGET_RESERVE_YBASE
710 && IS_YBASE_REGISTER_WINDOW (REGNO(x)))
715 case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
716 case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS:
717 case A1_REG: case ACCUM_REGS: case X_REG:
718 case X_OR_ACCUM_LOW_REGS: case X_OR_ACCUM_REGS:
719 case YH_REG: case YH_OR_ACCUM_HIGH_REGS:
720 case X_OR_YH_REGS: case YL_REG:
721 case YL_OR_ACCUM_LOW_REGS: case X_OR_YL_REGS:
722 case X_OR_Y_REGS: case Y_REG:
723 case ACCUM_OR_Y_REGS: case PH_REG:
724 case X_OR_PH_REGS: case PL_REG:
725 case PL_OR_ACCUM_LOW_REGS: case X_OR_PL_REGS:
726 case YL_OR_PL_OR_ACCUM_LOW_REGS: case P_REG:
727 case ACCUM_OR_P_REGS: case YL_OR_P_REGS:
728 case ACCUM_LOW_OR_YL_OR_P_REGS: case Y_OR_P_REGS:
729 case ACCUM_Y_OR_P_REGS: case NO_FRAME_Y_ADDR_REGS:
730 case Y_ADDR_REGS: case ACCUM_LOW_OR_Y_ADDR_REGS:
731 case ACCUM_OR_Y_ADDR_REGS: case X_OR_Y_ADDR_REGS:
732 case Y_OR_Y_ADDR_REGS: case P_OR_Y_ADDR_REGS:
733 case NON_HIGH_YBASE_ELIGIBLE_REGS: case YBASE_ELIGIBLE_REGS:
738 return (!reload_in_progress ? NO_REGS : class);
740 case J_OR_DAU_16_BIT_REGS:
741 return ACCUM_HIGH_REGS;
744 case YBASE_VIRT_REGS:
745 return (!reload_in_progress ? NO_REGS : class);
747 case ACCUM_LOW_OR_YBASE_REGS:
748 return ACCUM_LOW_REGS;
750 case ACCUM_OR_YBASE_REGS:
753 case X_OR_YBASE_REGS:
756 case Y_OR_YBASE_REGS:
759 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
760 return YL_OR_PL_OR_ACCUM_LOW_REGS;
762 case P_OR_YBASE_REGS:
765 case ACCUM_Y_P_OR_YBASE_REGS:
766 return ACCUM_Y_OR_P_REGS;
768 case Y_ADDR_OR_YBASE_REGS:
771 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
772 return NON_HIGH_YBASE_ELIGIBLE_REGS;
774 case YBASE_OR_YBASE_ELIGIBLE_REGS:
775 return YBASE_ELIGIBLE_REGS;
777 case NO_HIGH_ALL_REGS:
778 return NON_HIGH_YBASE_ELIGIBLE_REGS;
781 return YBASE_ELIGIBLE_REGS;
783 case NOHIGH_NON_ADDR_REGS:
784 return ACCUM_LOW_OR_YL_OR_P_REGS;
787 return ACCUM_Y_OR_P_REGS;
789 case SLOW_MEM_LOAD_REGS:
790 return ACCUM_OR_Y_ADDR_REGS;
792 case NOHIGH_NON_YBASE_REGS:
793 return NON_HIGH_YBASE_ELIGIBLE_REGS;
795 case NO_ACCUM_NON_YBASE_REGS:
799 return YBASE_ELIGIBLE_REGS;
803 if (GET_CODE (x) == PLUS)
805 if (GET_MODE (x) == QImode
806 && REG_P (XEXP (x,0))
807 && (XEXP (x,0) == frame_pointer_rtx
808 || XEXP (x,0) == stack_pointer_rtx)
809 && (GET_CODE (XEXP (x,1)) == CONST_INT))
811 if (class == ACCUM_HIGH_REGS)
814 /* If the accumulators are not part of the class
815 being reloaded into, return NO_REGS. */
817 if (!reg_class_subset_p (ACCUM_REGS, class))
818 return (!reload_in_progress ? NO_REGS : class);
820 if (reg_class_subset_p (ACCUM_HIGH_REGS, class))
821 return ACCUM_HIGH_REGS;
823 /* We will use accumulator 'a1l' for reloading a
824 PLUS. We can only use one accumulator because
825 'reload_inqi' only allows one alternative to be
828 else if (class == ACCUM_LOW_REGS)
830 else if (class == A0L_REG)
836 if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
841 else if (GET_CODE (x) == MEM)
843 /* We can't copy from a memory location into a
845 if (reg_class_subset_p(YBASE_VIRT_REGS, class))
849 case YBASE_VIRT_REGS:
850 return (!reload_in_progress ? NO_REGS : class);
852 case ACCUM_LOW_OR_YBASE_REGS:
853 return ACCUM_LOW_REGS;
855 case ACCUM_OR_YBASE_REGS:
858 case X_OR_YBASE_REGS:
861 case Y_OR_YBASE_REGS:
864 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
865 return YL_OR_PL_OR_ACCUM_LOW_REGS;
867 case P_OR_YBASE_REGS:
870 case ACCUM_Y_P_OR_YBASE_REGS:
871 return ACCUM_Y_OR_P_REGS;
873 case Y_ADDR_OR_YBASE_REGS:
876 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
877 return NON_HIGH_YBASE_ELIGIBLE_REGS;
879 case YBASE_OR_YBASE_ELIGIBLE_REGS:
880 return YBASE_ELIGIBLE_REGS;
882 case NO_HIGH_ALL_REGS:
883 return NOHIGH_NON_YBASE_REGS;
886 return NON_YBASE_REGS;
899 /* Return the register class of a scratch register needed to copy IN into
900 or out of a register in CLASS in MODE. If it can be done directly,
901 NO_REGS is returned. */
904 secondary_reload_class (class, mode, in)
905 enum reg_class class;
906 enum machine_mode mode;
911 if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
912 regno = true_regnum (in);
914 /* If we are reloading a plus into a high accumulator register,
915 we need a scratch low accumulator, because the low half gets
918 if (class == ACCUM_HIGH_REGS
922 if (GET_CODE (in) == PLUS && mode == QImode)
923 return ACCUM_LOW_REGS;
926 if (class == ACCUM_HIGH_REGS
927 || class == ACCUM_LOW_REGS
933 if (GET_CODE (in) == PLUS && mode == QImode)
935 rtx addr0 = XEXP (in, 0);
936 rtx addr1 = XEXP (in, 1);
938 /* If we are reloading a plus (reg:QI) (reg:QI)
939 we need an additional register. */
940 if (REG_P (addr0) && REG_P (addr1))
945 /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
948 if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS ||
949 class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG ||
950 class == A1H_REG || class == A1_REG) ||
951 (regno >= REG_A0 && regno < REG_A1L + 1))
954 if (class == ACCUM_OR_YBASE_REGS && REG_P(in)
955 && IS_YBASE_ELIGIBLE_REG(regno))
960 /* We can copy the ybase registers into:
961 r0-r3, a0-a1, y, p, & x or the union of
964 if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
969 case (int) X_OR_ACCUM_LOW_REGS:
970 case (int) X_OR_ACCUM_REGS:
972 case (int) YH_OR_ACCUM_HIGH_REGS:
973 case (int) X_OR_YH_REGS:
975 case (int) YL_OR_ACCUM_LOW_REGS:
976 case (int) X_OR_Y_REGS:
977 case (int) X_OR_YL_REGS:
979 case (int) ACCUM_OR_Y_REGS:
981 case (int) X_OR_PH_REGS:
983 case (int) PL_OR_ACCUM_LOW_REGS:
984 case (int) X_OR_PL_REGS:
985 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
987 case (int) ACCUM_OR_P_REGS:
988 case (int) YL_OR_P_REGS:
989 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
990 case (int) Y_OR_P_REGS:
991 case (int) ACCUM_Y_OR_P_REGS:
992 case (int) Y_ADDR_REGS:
993 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
994 case (int) ACCUM_OR_Y_ADDR_REGS:
995 case (int) X_OR_Y_ADDR_REGS:
996 case (int) Y_OR_Y_ADDR_REGS:
997 case (int) P_OR_Y_ADDR_REGS:
998 case (int) YBASE_ELIGIBLE_REGS:
1002 return ACCUM_HIGH_REGS;
1006 /* We can copy r0-r3, a0-a1, y, & p
1007 directly to the ybase registers. In addition
1008 we can use any of the ybase virtual registers
1009 as the secondary reload registers when copying
1010 between any of these registers. */
1012 if (!TARGET_RESERVE_YBASE && regno != -1)
1029 if (class == YBASE_VIRT_REGS)
1033 switch ((int) class)
1036 case (int) X_OR_ACCUM_LOW_REGS:
1037 case (int) X_OR_ACCUM_REGS:
1039 case (int) YH_OR_ACCUM_HIGH_REGS:
1040 case (int) X_OR_YH_REGS:
1042 case (int) YL_OR_ACCUM_LOW_REGS:
1043 case (int) X_OR_Y_REGS:
1044 case (int) X_OR_YL_REGS:
1046 case (int) ACCUM_OR_Y_REGS:
1048 case (int) X_OR_PH_REGS:
1050 case (int) PL_OR_ACCUM_LOW_REGS:
1051 case (int) X_OR_PL_REGS:
1052 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
1054 case (int) ACCUM_OR_P_REGS:
1055 case (int) YL_OR_P_REGS:
1056 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
1057 case (int) Y_OR_P_REGS:
1058 case (int) ACCUM_Y_OR_P_REGS:
1059 case (int) Y_ADDR_REGS:
1060 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
1061 case (int) ACCUM_OR_Y_ADDR_REGS:
1062 case (int) X_OR_Y_ADDR_REGS:
1063 case (int) Y_OR_Y_ADDR_REGS:
1064 case (int) P_OR_Y_ADDR_REGS:
1065 case (int) YBASE_ELIGIBLE_REGS:
1066 return YBASE_VIRT_REGS;
1075 /* Memory or constants can be moved from or to any register
1076 except the ybase virtual registers. */
1077 if (regno == -1 && GET_CODE(in) != PLUS)
1079 if (class == YBASE_VIRT_REGS)
1080 return NON_YBASE_REGS;
1085 if (GET_CODE (in) == PLUS && mode == QImode)
1087 rtx addr0 = XEXP (in, 0);
1088 rtx addr1 = XEXP (in, 1);
1090 /* If we are reloading a plus (reg:QI) (reg:QI)
1091 we need a low accumulator, not a high one. */
1092 if (REG_P (addr0) && REG_P (addr1))
1093 return ACCUM_LOW_REGS;
1101 /* Otherwise, we need a high accumulator(s). */
1102 return ACCUM_HIGH_REGS;
1106 symbolic_address_operand (op, mode)
1108 enum machine_mode mode ATTRIBUTE_UNUSED;
1110 return (symbolic_address_p (op));
1114 symbolic_address_p (op)
1117 switch (GET_CODE (op))
1125 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1126 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1127 && GET_CODE (XEXP (op, 1)) == CONST_INT
1128 && INTVAL (XEXP (op,1)) < 0x20);
1135 /* For a Y address space operand we allow only *rn, *rn++, *rn--.
1136 This routine only recognizes *rn, the '<>' constraints recognize
1137 (*rn++), and (*rn--). */
1140 Y_address_operand (op, mode)
1142 enum machine_mode mode;
1144 return (memory_address_p (mode, op) && !symbolic_address_p (op));
1148 sp_operand (op, mode)
1150 enum machine_mode mode ATTRIBUTE_UNUSED;
1152 return (GET_CODE (op) == PLUS
1153 && (XEXP (op, 0) == stack_pointer_rtx
1154 || XEXP (op, 0) == frame_pointer_rtx)
1155 && GET_CODE (XEXP (op,1)) == CONST_INT);
1159 sp_operand2 (op, mode)
1161 enum machine_mode mode ATTRIBUTE_UNUSED;
1163 if ((GET_CODE (op) == PLUS
1164 && (XEXP (op, 0) == stack_pointer_rtx
1165 || XEXP (op, 0) == frame_pointer_rtx)
1166 && (REG_P (XEXP (op,1))
1167 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
1169 else if ((GET_CODE (op) == PLUS
1170 && (XEXP (op, 1) == stack_pointer_rtx
1171 || XEXP (op, 1) == frame_pointer_rtx)
1172 && (REG_P (XEXP (op,0))
1173 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
1180 nonmemory_arith_operand (op, mode)
1182 enum machine_mode mode;
1184 return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
1188 arith_reg_operand (op, mode)
1190 enum machine_mode mode;
1192 return (register_operand (op, mode)
1193 && (GET_CODE (op) != REG
1194 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1195 || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op)))
1196 && REGNO (op) != FRAME_POINTER_REGNUM)));
1200 call_address_operand (op, mode)
1202 enum machine_mode mode ATTRIBUTE_UNUSED;
1204 if (symbolic_address_p (op) || REG_P(op))
1213 dsp16xx_comparison_operator (op, mode)
1215 enum machine_mode mode;
1217 return ((mode == VOIDmode || GET_MODE (op) == mode)
1218 && GET_RTX_CLASS (GET_CODE (op)) == '<'
1219 && (GET_CODE(op) != GE && GET_CODE (op) != LT &&
1220 GET_CODE (op) != GEU && GET_CODE (op) != LTU));
1224 notice_update_cc(exp)
1227 if (GET_CODE (exp) == SET)
1229 /* Jumps do not alter the cc's. */
1231 if (SET_DEST (exp) == pc_rtx)
1234 /* Moving register or memory into a register:
1235 it doesn't alter the cc's, but it might invalidate
1236 the RTX's which we remember the cc's came from.
1237 (Note that moving a constant 0 or 1 MAY set the cc's). */
1238 if (REG_P (SET_DEST (exp))
1239 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
1241 if (cc_status.value1
1242 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1243 cc_status.value1 = 0;
1244 if (cc_status.value2
1245 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1246 cc_status.value2 = 0;
1249 /* Moving register into memory doesn't alter the cc's.
1250 It may invalidate the RTX's which we remember the cc's came from. */
1251 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
1253 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1254 cc_status.value1 = 0;
1255 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1256 cc_status.value2 = 0;
1259 /* Function calls clobber the cc's. */
1260 else if (GET_CODE (SET_SRC (exp)) == CALL)
1265 /* Tests and compares set the cc's in predictable ways. */
1266 else if (SET_DEST (exp) == cc0_rtx)
1269 cc_status.value1 = SET_SRC (exp);
1272 /* Certain instructions effect the condition codes. */
1273 else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT)
1274 switch (GET_CODE (SET_SRC (exp)))
1278 if (REG_P (SET_DEST (exp)))
1280 /* Address registers don't set the condition codes. */
1281 if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp))))
1296 cc_status.value1 = SET_SRC (exp);
1297 cc_status.value2 = SET_DEST (exp);
1308 else if (GET_CODE (exp) == PARALLEL
1309 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1311 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1314 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1317 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1330 dsp16xx_makes_calls ()
1334 for (insn = get_insns (); insn; insn = next_insn (insn))
1335 if (GET_CODE (insn) == CALL_INSN)
1342 compute_frame_size (size)
1351 /* This value is needed to compute reg_size. */
1352 current_frame_info.function_makes_calls = !leaf_function_p ();
1357 args_size = current_function_outgoing_args_size;
1358 reg_size = reg_save_size ();
1360 total_size = var_size + args_size + extra_size + reg_size;
1363 /* Save other computed information. */
1364 current_frame_info.total_size = total_size;
1365 current_frame_info.var_size = var_size;
1366 current_frame_info.args_size = args_size;
1367 current_frame_info.extra_size = extra_size;
1368 current_frame_info.reg_size = reg_size;
1369 current_frame_info.initialized = reload_completed;
1370 current_frame_info.reg_size = reg_size / UNITS_PER_WORD;
1374 unsigned long offset = args_size + var_size + reg_size;
1375 current_frame_info.sp_save_offset = offset;
1376 current_frame_info.fp_save_offset = offset - total_size;
1383 dsp16xx_call_saved_register (regno)
1387 if (regno == REG_PR && current_frame_info.function_makes_calls)
1390 return (regs_ever_live[regno] && !call_used_regs[regno] &&
1391 !IS_YBASE_REGISTER_WINDOW(regno));
1395 ybase_regs_ever_used ()
1400 for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
1401 if (regs_ever_live[regno])
1411 dsp16xx_output_function_prologue (file, size)
1417 fp = reg_names[FRAME_POINTER_REGNUM];
1418 sp = reg_names[STACK_POINTER_REGNUM];
1419 rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */
1420 a1h = reg_names[REG_A1];
1422 total_size = compute_frame_size (size);
1424 fprintf (file, "\t/* FUNCTION PROLOGUE: */\n");
1425 fprintf (file, "\t/* total=%ld, vars= %ld, regs= %d, args=%d, extra= %ld */\n",
1426 current_frame_info.total_size,
1427 current_frame_info.var_size,
1428 current_frame_info.reg_size,
1429 current_function_outgoing_args_size,
1430 current_frame_info.extra_size);
1432 fprintf (file, "\t/* fp save offset= %ld, sp save_offset= %ld */\n\n",
1433 current_frame_info.fp_save_offset,
1434 current_frame_info.sp_save_offset);
1435 /* Set up the 'ybase' register window. */
1437 if (ybase_regs_ever_used())
1439 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1440 if (TARGET_YBASE_HIGH)
1441 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1443 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1444 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1447 if (current_frame_info.var_size)
1449 if (current_frame_info.var_size == 1)
1450 fprintf (file, "\t*%s++\n", sp);
1453 if (SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0))
1454 fprintf (file, "\t%s=%ld\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]);
1456 fatal_error ("stack size > 32k");
1460 /* Save any registers this function uses, unless they are
1461 used in a call, in which case we don't need to. */
1463 for(regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno)
1464 if (dsp16xx_call_saved_register (regno))
1466 fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[regno]);
1469 /* For debugging purposes, we want the return address to be at a predictable
1471 if (current_frame_info.function_makes_calls)
1472 fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[RETURN_ADDRESS_REGNUM]);
1474 if (current_frame_info.args_size)
1476 if (current_frame_info.args_size == 1)
1477 fprintf (file, "\t*%s++\n", sp);
1479 error ("stack size > 32k");
1482 if (frame_pointer_needed)
1484 fprintf (file, "\t%s=%s\n", a1h, sp);
1485 fprintf (file, "\t%s=%s\n", fp, a1h); /* Establish new base frame */
1486 fprintf (file, "\t%s=%ld\n", reg_names[REG_J], -total_size);
1487 fprintf (file, "\t*%s++%s\n", fp, reg_names[REG_J]);
1490 fprintf (file, "\t/* END FUNCTION PROLOGUE: */\n\n");
1494 init_emulation_routines ()
1496 dsp16xx_addhf3_libcall = (rtx) 0;
1497 dsp16xx_subhf3_libcall = (rtx) 0;
1498 dsp16xx_mulhf3_libcall = (rtx) 0;
1499 dsp16xx_divhf3_libcall = (rtx) 0;
1500 dsp16xx_cmphf3_libcall = (rtx) 0;
1501 dsp16xx_fixhfhi2_libcall = (rtx) 0;
1502 dsp16xx_floathihf2_libcall = (rtx) 0;
1503 dsp16xx_neghf2_libcall = (rtx) 0;
1505 dsp16xx_mulhi3_libcall = (rtx) 0;
1506 dsp16xx_udivqi3_libcall = (rtx) 0;
1507 dsp16xx_udivhi3_libcall = (rtx) 0;
1508 dsp16xx_divqi3_libcall = (rtx) 0;
1509 dsp16xx_divhi3_libcall = (rtx) 0;
1510 dsp16xx_modqi3_libcall = (rtx) 0;
1511 dsp16xx_modhi3_libcall = (rtx) 0;
1512 dsp16xx_umodqi3_libcall = (rtx) 0;
1513 dsp16xx_umodhi3_libcall = (rtx) 0;
1514 dsp16xx_ashrhi3_libcall = (rtx) 0;
1515 dsp16xx_ashlhi3_libcall = (rtx) 0;
1516 dsp16xx_ucmphi2_libcall = (rtx) 0;
1517 dsp16xx_lshrhi3_libcall = (rtx) 0;
1521 dsp16xx_output_function_epilogue (file, size)
1523 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
1527 fp = reg_names[FRAME_POINTER_REGNUM];
1528 sp = reg_names[STACK_POINTER_REGNUM];
1529 rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */
1530 a1h = reg_names[REG_A1];
1532 fprintf (file, "\n\t/* FUNCTION EPILOGUE: */\n");
1534 if (current_frame_info.args_size)
1536 if (current_frame_info.args_size == 1)
1537 fprintf (file, "\t*%s--\n", sp);
1540 fprintf (file, "\t%s=%ld\n\t*%s++%s\n",
1541 reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]);
1545 if (ybase_regs_ever_used())
1547 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1548 if (TARGET_YBASE_HIGH)
1549 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1551 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1552 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1555 if (current_frame_info.function_makes_calls)
1556 fprintf (file, "\t%s=pop(*%s)\n", reg_names[RETURN_ADDRESS_REGNUM], sp);
1558 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
1559 if (dsp16xx_call_saved_register(regno))
1561 fprintf (file, "\t%s=pop(*%s)\n", reg_names[regno], sp);
1564 if (current_frame_info.var_size)
1566 if (current_frame_info.var_size == 1)
1567 fprintf (file, "\t*%s--\n", sp);
1570 fprintf (file, "\t%s=%ld\n\t*%s++%s\n",
1571 reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]);
1575 fprintf (file, "\treturn\n");
1576 /* Reset the frame info for the next function. */
1577 current_frame_info = zero_frame_info;
1578 init_emulation_routines ();
1581 /* Emit insns to move operands[1] into operands[0].
1583 Return 1 if we have written out everything that needs to be done to
1584 do the move. Otherwise, return 0 and the caller will emit the move
1588 emit_move_sequence (operands, mode)
1590 enum machine_mode mode;
1592 register rtx operand0 = operands[0];
1593 register rtx operand1 = operands[1];
1595 /* We can only store registers to memory. */
1597 if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
1598 operands[1] = force_reg (mode, operand1);
1604 double_reg_from_memory (operands)
1609 if (GET_CODE(XEXP(operands[1],0)) == POST_INC)
1611 output_asm_insn ("%u0=%1", operands);
1612 output_asm_insn ("%w0=%1", operands);
1614 else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC)
1616 xoperands[1] = XEXP (XEXP (operands[1], 0), 0);
1617 xoperands[0] = operands[0];
1619 /* We can't use j anymore since the compiler can allocate it. */
1620 /* output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */
1621 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands);
1623 else if (GET_CODE(XEXP(operands[1],0)) == PLUS)
1628 output_asm_insn ("%u0=%1", operands);
1631 /* In order to print out the least significant word we must
1632 use 'offset + 1'. */
1633 addr = XEXP (operands[1], 0);
1634 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1635 offset = INTVAL(XEXP(addr,0)) + 1;
1636 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1637 offset = INTVAL(XEXP(addr,1)) + 1;
1639 fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31);
1643 xoperands[1] = XEXP(operands[1],0);
1644 xoperands[0] = operands[0];
1646 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
1652 double_reg_to_memory (operands)
1657 if (GET_CODE(XEXP(operands[0],0)) == POST_INC)
1659 output_asm_insn ("%0=%u1", operands);
1660 output_asm_insn ("%0=%w1", operands);
1662 else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC)
1664 xoperands[0] = XEXP (XEXP (operands[0], 0), 0);
1665 xoperands[1] = operands[1];
1667 /* We can't use j anymore since the compiler can allocate it. */
1669 /* output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */
1670 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands);
1673 else if (GET_CODE(XEXP(operands[0],0)) == PLUS)
1678 output_asm_insn ("%0=%u1", operands);
1680 /* In order to print out the least significant word we must
1681 use 'offset + 1'. */
1682 addr = XEXP (operands[0], 0);
1683 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1684 offset = INTVAL(XEXP(addr,0)) + 1;
1685 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1686 offset = INTVAL(XEXP(addr,1)) + 1;
1688 fatal_error ("invalid addressing mode");
1690 fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
1694 xoperands[0] = XEXP(operands[0],0);
1695 xoperands[1] = operands[1];
1697 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
1704 if (chip_name == (char *) 0)
1705 chip_name = DEFAULT_CHIP_NAME;
1707 if (text_seg_name == (char *) 0)
1708 text_seg_name = DEFAULT_TEXT_SEG_NAME;
1710 if (data_seg_name == (char *) 0)
1711 data_seg_name = DEFAULT_DATA_SEG_NAME;
1713 if (bss_seg_name == (char *) 0)
1714 bss_seg_name = DEFAULT_BSS_SEG_NAME;
1716 if (const_seg_name == (char *) 0)
1717 const_seg_name = DEFAULT_CONST_SEG_NAME;
1719 save_chip_name = xstrdup (chip_name);
1721 rsect_text = concat (".rsect \"", text_seg_name, "\"", NULL);
1722 rsect_data = concat (".rsect \"", data_seg_name, "\"", NULL);
1723 rsect_bss = concat (".rsect \"", bss_seg_name, "\"", NULL);
1724 rsect_const = concat (".rsect \"", const_seg_name, "\"", NULL);
1728 next_cc_user_unsigned (insn)
1731 switch (next_cc_user_code (insn))
1744 next_cc_user_code (insn)
1747 /* If no insn could be found we assume that the jump has been
1748 deleted and the compare will be deleted later. */
1750 if (!(insn = next_cc0_user (insn)))
1751 return (enum rtx_code) 0;
1752 else if (GET_CODE (insn) == JUMP_INSN
1753 && GET_CODE (PATTERN (insn)) == SET
1754 && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
1755 return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
1756 else if (GET_CODE (insn) == INSN
1757 && GET_CODE (PATTERN (insn)) == SET
1758 && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode))
1759 return GET_CODE (SET_SRC (PATTERN (insn)));
1765 print_operand(file, op, letter)
1772 code = GET_CODE(op);
1777 code = reverse_condition (code);
1786 else if (code == NE)
1791 else if (code == GT || code == GTU)
1796 else if (code == LT || code == LTU)
1801 else if (code == GE || code == GEU)
1806 else if (code == LE || code == LEU)
1821 /* Print the low half of a 32-bit register pair. */
1823 fprintf (file, "%s", reg_names[REGNO (op) + 1]);
1824 else if (letter == 'u' || !letter)
1825 fprintf (file, "%s", reg_names[REGNO (op)]);
1826 else if (letter == 'b')
1827 fprintf (file, "%sh", reg_names[REGNO (op)]);
1828 else if (letter == 'm')
1829 fprintf (file, "%s", himode_reg_name[REGNO (op)]);
1831 output_operand_lossage ("bad register extension code");
1833 else if (code == MEM)
1834 output_address (XEXP(op,0));
1835 else if (code == CONST_INT)
1837 HOST_WIDE_INT val = INTVAL (op);
1840 fprintf (file, HOST_WIDE_INT_PRINT_HEX, val & 0xffff);
1841 else if (letter == 'h')
1842 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
1843 else if (letter == 'U')
1844 fprintf (file, HOST_WIDE_INT_PRINT_HEX, (val >> 16) & 0xffff);
1846 output_addr_const(file, op);
1848 else if (code == CONST_DOUBLE && GET_MODE(op) != DImode)
1852 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1853 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1854 fprintf (file, "0x%lx", l);
1856 else if (code == CONST)
1858 rtx addr = XEXP (op, 0);
1860 if (GET_CODE (addr) != PLUS)
1862 output_addr_const(file, op);
1866 if ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
1867 || GET_CODE (XEXP (addr, 0)) == LABEL_REF)
1868 && (GET_CODE (XEXP (addr, 1)) == CONST_INT))
1870 int n = INTVAL (XEXP(addr, 1));
1871 output_addr_const (file, XEXP (addr, 0));
1874 fprintf (file, "+");
1876 n = (int) (short) n;
1877 fprintf (file, "%d", n);
1879 else if ((GET_CODE (XEXP (addr, 1)) == SYMBOL_REF
1880 || GET_CODE (XEXP (addr, 1)) == LABEL_REF)
1881 && (GET_CODE (XEXP (addr, 0)) == CONST_INT))
1883 int n = INTVAL (XEXP(addr, 0));
1884 output_addr_const (file, XEXP (addr, 1));
1887 fprintf (file, "+");
1889 n = (int) (short) n;
1890 fprintf (file, "%d", n);
1893 output_addr_const(file, op);
1896 output_addr_const (file, op);
1901 print_operand_address(file, addr)
1908 switch (GET_CODE (addr))
1911 fprintf (file, "*%s", reg_names[REGNO (addr)]);
1914 fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
1917 fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
1920 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1921 offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1);
1922 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1923 offset = INTVAL(XEXP(addr,1)), base = XEXP(addr,0);
1926 if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
1928 if (offset >= -31 && offset <= 0)
1929 offset = 31 + offset;
1931 fatal_error ("invalid offset in ybase addressing");
1934 fatal_error ("invalid register in ybase addressing");
1936 fprintf (file, "*(%d)", offset);
1940 if (FITS_5_BITS (addr))
1941 fprintf (file, "*(0x%x)", (INTVAL (addr) & 0x20));
1943 output_addr_const (file, addr);
1948 output_dsp16xx_float_const (operands)
1951 rtx src = operands[1];
1956 REAL_VALUE_FROM_CONST_DOUBLE (d, src);
1957 REAL_VALUE_TO_TARGET_SINGLE (d, value);
1959 operands[1] = GEN_INT (value);
1960 output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands);
1966 int reg_save_size = 0;
1969 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1970 if (dsp16xx_call_saved_register (regno))
1972 reg_save_size += UNITS_PER_WORD;
1975 /* If the function makes calls we will save need to save the 'pr' register. */
1976 if (current_frame_info.function_makes_calls)
1979 return (reg_save_size);
1984 dsp16xx_starting_frame_offset()
1986 int reg_save_size = 0;
1989 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1990 if (dsp16xx_call_saved_register (regno))
1992 reg_save_size += UNITS_PER_WORD;
1995 return (reg_save_size);
2000 initial_frame_pointer_offset()
2004 offset = compute_frame_size (get_frame_size());
2006 #ifdef STACK_GROWS_DOWNWARD
2013 /* Generate the minimum number of 1600 core shift instructions
2014 to shift by 'shift_amount'. */
2018 emit_1600_core_shift (shift_op, operands, shift_amount, mode)
2019 enum rtx_code shift_op;
2022 enum machine_mode mode;
2026 int first_shift_emitted = 0;
2028 while (shift_amount != 0)
2030 if (shift_amount/16)
2032 quotient = shift_amount/16;
2033 shift_amount = shift_amount - (quotient * 16);
2034 for (i = 0; i < quotient; i++)
2035 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2036 gen_rtx (shift_op, mode,
2038 ? operands[0] : operands[1],
2040 first_shift_emitted = 1;
2042 else if (shift_amount/8)
2044 quotient = shift_amount/8;
2045 shift_amount = shift_amount - (quotient * 8);
2046 for (i = 0; i < quotient; i++)
2047 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2048 gen_rtx (shift_op, mode,
2050 ? operands[0] : operands[1],
2052 first_shift_emitted = 1;
2054 else if (shift_amount/4)
2056 quotient = shift_amount/4;
2057 shift_amount = shift_amount - (quotient * 4);
2058 for (i = 0; i < quotient; i++)
2059 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2060 gen_rtx (shift_op, mode,
2062 ? operands[0] : operands[1],
2064 first_shift_emitted = 1;
2066 else if (shift_amount/1)
2068 quotient = shift_amount/1;
2069 shift_amount = shift_amount - (quotient * 1);
2070 for (i = 0; i < quotient; i++)
2071 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2072 gen_rtx (shift_op, mode,
2074 ? operands[0] : operands[1],
2076 first_shift_emitted = 1;
2082 emit_1600_core_shift (shift_op, operands, shift_amount)
2083 enum rtx_code shift_op;
2089 int first_shift_emitted = 0;
2090 const char * const *shift_asm_ptr;
2091 const char * const *shift_asm_ptr_first;
2093 if (shift_op == ASHIFT)
2095 shift_asm_ptr = ashift_left_asm;
2096 shift_asm_ptr_first = ashift_left_asm_first;
2098 else if (shift_op == ASHIFTRT)
2100 shift_asm_ptr = ashift_right_asm;
2101 shift_asm_ptr_first = ashift_right_asm_first;
2103 else if (shift_op == LSHIFTRT)
2105 shift_asm_ptr = lshift_right_asm;
2106 shift_asm_ptr_first = lshift_right_asm_first;
2109 fatal_error ("invalid shift operator in emit_1600_core_shift");
2111 while (shift_amount != 0)
2113 if (shift_amount/16)
2115 quotient = shift_amount/16;
2116 shift_amount = shift_amount - (quotient * 16);
2117 for (i = 0; i < quotient; i++)
2118 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_16]
2119 : shift_asm_ptr_first[SHIFT_INDEX_16]), operands);
2120 first_shift_emitted = 1;
2122 else if (shift_amount/8)
2124 quotient = shift_amount/8;
2125 shift_amount = shift_amount - (quotient * 8);
2126 for (i = 0; i < quotient; i++)
2127 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_8]
2128 : shift_asm_ptr_first[SHIFT_INDEX_8]), operands);
2129 first_shift_emitted = 1;
2131 else if (shift_amount/4)
2133 quotient = shift_amount/4;
2134 shift_amount = shift_amount - (quotient * 4);
2135 for (i = 0; i < quotient; i++)
2136 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_4]
2137 : shift_asm_ptr_first[SHIFT_INDEX_4]), operands);
2138 first_shift_emitted = 1;
2140 else if (shift_amount/1)
2142 quotient = shift_amount/1;
2143 shift_amount = shift_amount - (quotient * 1);
2144 for (i = 0; i < quotient; i++)
2145 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_1]
2146 : shift_asm_ptr_first[SHIFT_INDEX_1]), operands);
2147 first_shift_emitted = 1;
2154 num_1600_core_shifts (shift_amount)
2159 int first_shift_emitted = 0;
2162 while (shift_amount != 0)
2164 if (shift_amount/16)
2166 quotient = shift_amount/16;
2167 shift_amount = shift_amount - (quotient * 16);
2168 for (i = 0; i < quotient; i++)
2170 first_shift_emitted = 1;
2172 else if (shift_amount/8)
2174 quotient = shift_amount/8;
2175 shift_amount = shift_amount - (quotient * 8);
2176 for (i = 0; i < quotient; i++)
2179 first_shift_emitted = 1;
2181 else if (shift_amount/4)
2183 quotient = shift_amount/4;
2184 shift_amount = shift_amount - (quotient * 4);
2185 for (i = 0; i < quotient; i++)
2188 first_shift_emitted = 1;
2190 else if (shift_amount/1)
2192 quotient = shift_amount/1;
2193 shift_amount = shift_amount - (quotient * 1);
2194 for (i = 0; i < quotient; i++)
2197 first_shift_emitted = 1;
2204 asm_output_common(file, name, size, rounded)
2207 int size ATTRIBUTE_UNUSED;
2211 (*targetm.asm_out.globalize_label) (file, name);
2212 assemble_name (file, name);
2215 fprintf (file, "%d * int\n", rounded);
2217 fprintf (file, "int\n");
2221 asm_output_local(file, name, size, rounded)
2224 int size ATTRIBUTE_UNUSED;
2228 assemble_name (file, name);
2231 fprintf (file, "%d * int\n", rounded);
2233 fprintf (file, "int\n");
2237 dsp16xx_address_cost (addr)
2240 switch (GET_CODE (addr))
2250 rtx offset = const0_rtx;
2251 addr = eliminate_constant_term (addr, &offset);
2253 if (GET_CODE (addr) == LABEL_REF)
2256 if (GET_CODE (addr) != SYMBOL_REF)
2259 if (INTVAL (offset) == 0)
2264 case POST_INC: case POST_DEC:
2265 return (GET_MODE (addr) == QImode ? 1 : 2);
2267 case SYMBOL_REF: case LABEL_REF:
2272 register rtx plus0 = XEXP (addr, 0);
2273 register rtx plus1 = XEXP (addr, 1);
2275 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
2277 plus0 = XEXP (addr, 1);
2278 plus1 = XEXP (addr, 0);
2281 if (GET_CODE (plus0) != REG)
2284 switch (GET_CODE (plus1))
2295 return dsp16xx_address_cost (plus1) + 1;
2304 /* Determine whether a function argument is passed in a register, and
2307 The arguments are CUM, which summarizes all the previous
2308 arguments; MODE, the machine mode of the argument; TYPE,
2309 the data type of the argument as a tree node or 0 if that is not known
2310 (which happens for C support library functions); and NAMED,
2311 which is 1 for an ordinary argument and 0 for nameless arguments that
2312 correspond to `...' in the called function's prototype.
2314 The value of the expression should either be a `reg' RTX for the
2315 hard register in which to pass the argument, or zero to pass the
2316 argument on the stack.
2318 On the dsp1610 the first four words of args are normally in registers
2319 and the rest are pushed. If we a long or on float mode, the argument
2320 must begin on an even register boundary
2322 Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2323 For structures that are passed in memory, but could have been
2324 passed in registers, we first load the structure into the
2325 register, and then when the last argument is passed, we store
2326 the registers into the stack locations. This fixes some bugs
2327 where GCC did not expect to have register arguments, followed. */
2330 dsp16xx_function_arg (args_so_far, mode, type, named)
2331 CUMULATIVE_ARGS args_so_far;
2332 enum machine_mode mode;
2338 if ((args_so_far & 1) != 0
2339 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2342 if (type == void_type_node)
2343 return (struct rtx_def *) 0;
2345 if (named && args_so_far < 4 && !MUST_PASS_IN_STACK (mode,type))
2346 return gen_rtx_REG (mode, args_so_far + FIRST_REG_FOR_FUNCTION_ARG);
2348 return (struct rtx_def *) 0;
2351 return (struct rtx_def *) 0;
2354 /* Advance the argument to the next argument position. */
2357 dsp16xx_function_arg_advance (cum, mode, type, named)
2358 CUMULATIVE_ARGS *cum; /* current arg information */
2359 enum machine_mode mode; /* current arg mode */
2360 tree type; /* type of the argument or 0 if lib support */
2361 int named ATTRIBUTE_UNUSED;/* whether or not the argument was named */
2366 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2369 if (mode != BLKmode)
2370 *cum += GET_MODE_SIZE (mode);
2372 *cum += int_size_in_bytes (type);
2377 coff_dsp16xx_file_start (file)
2380 fprintf (file, "#include <%s.h>\n", save_chip_name);
2384 luxworks_dsp16xx_file_start (file)
2387 char *temp_filename;
2391 fprintf (file, "\t.debug ");
2392 err_code = (TARGET_DEBUG) ? fprintf (file, "yes, ") : fprintf (file, "no, ");
2393 err_code = (TARGET_SAVE_TEMPS) ? fprintf (file, "asm, ") : fprintf (file, "temp, ");
2394 len = strlen (main_input_filename);
2395 temp_filename = (char *) xmalloc (len + 2);
2396 strcpy (temp_filename, main_input_filename);
2399 while (*p != '\0') {
2405 fprintf (file, "\"%s\"\n", temp_filename);
2407 fprintf (file, "#include <%s.h>\n", save_chip_name);
2410 * Add dummy sections, so that they always exist in the
2411 * object code. These have been created so that the number and
2412 * type of sections remain consistent with and without -g option. Note
2413 * that the .data, .text, .const and .bss are always created when -g
2414 * is provided as an option. */
2415 fprintf (file, "\t.rsect \".text\" , nodelete\n");
2416 fprintf (file, "\t.rsect \".data\" , nodelete\n");
2417 fprintf (file, "\t.rsect \".const\" , nodelete\n");
2418 fprintf (file, "\t.rsect \".bss\" , nodelete\n");
2425 enum machine_mode mode;
2427 mode = GET_MODE (x);
2430 emit_insn (gen_rtx_PARALLEL
2432 gen_rtvec (2, gen_rtx_SET (VOIDmode, cc0_rtx, x),
2433 gen_rtx_CLOBBER (VOIDmode,
2434 gen_rtx_SCRATCH (QImode)))));
2435 else if (mode == HImode)
2436 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, x));
2438 fatal_error ("invalid mode for gen_tst_reg");
2444 gen_compare_reg (code, x, y)
2448 enum machine_mode mode;
2450 mode = GET_MODE (x);
2451 /* For floating point compare insns, a call is generated so don't
2452 do anything here. */
2454 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2459 if (code == GTU || code == GEU
2460 || code == LTU || code == LEU)
2462 emit_insn (gen_rtx_PARALLEL
2465 gen_rtx_SET (VOIDmode, cc0_rtx,
2466 gen_rtx_COMPARE (mode, x, y)),
2467 gen_rtx_CLOBBER (VOIDmode,
2468 gen_rtx_SCRATCH (QImode)),
2469 gen_rtx_CLOBBER (VOIDmode,
2470 gen_rtx_SCRATCH (QImode)))));
2474 emit_insn (gen_rtx_PARALLEL
2476 gen_rtvec (3, gen_rtx_SET (VOIDmode, cc0_rtx,
2477 gen_rtx_COMPARE (mode, x, y)),
2478 gen_rtx_CLOBBER (VOIDmode,
2479 gen_rtx_SCRATCH (QImode)),
2480 gen_rtx_CLOBBER (VOIDmode,
2481 gen_rtx_SCRATCH (QImode)))));
2484 else if (mode == HImode)
2486 if (code == GTU || code == GEU
2487 || code == LTU || code == LEU)
2489 emit_insn (gen_rtx_PARALLEL
2492 gen_rtx_SET (VOIDmode, cc0_rtx,
2493 gen_rtx_COMPARE (VOIDmode, x, y)),
2494 gen_rtx_CLOBBER (VOIDmode,
2495 gen_rtx_SCRATCH (QImode)),
2496 gen_rtx_CLOBBER (VOIDmode,
2497 gen_rtx_SCRATCH (QImode)),
2498 gen_rtx_CLOBBER (VOIDmode,
2499 gen_rtx_SCRATCH (QImode)),
2500 gen_rtx_CLOBBER (VOIDmode,
2501 gen_rtx_SCRATCH (QImode)))));
2504 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx,
2505 gen_rtx_COMPARE (VOIDmode,
2506 force_reg (HImode, x),
2507 force_reg (HImode,y))));
2510 fatal_error ("invalid mode for integer comparison in gen_compare_reg");
2516 output_block_move (operands)
2519 int loop_count = INTVAL(operands[2]);
2522 fprintf (asm_out_file, "\tdo %d {\n", loop_count);
2523 xoperands[0] = operands[4];
2524 xoperands[1] = operands[1];
2525 output_asm_insn ("%0=*%1++", xoperands);
2527 xoperands[0] = operands[0];
2528 xoperands[1] = operands[4];
2529 output_asm_insn ("*%0++=%1", xoperands);
2531 fprintf (asm_out_file, "\t}\n");
2536 uns_comparison_operator (op, mode)
2538 enum machine_mode mode;
2540 if (mode == VOIDmode || GET_MODE (op) == mode)
2544 code = GET_CODE(op);
2546 if (code == LEU || code == LTU || code == GEU
2559 signed_comparison_operator (op, mode)
2561 enum machine_mode mode;
2563 if (mode == VOIDmode || GET_MODE (op) == mode)
2567 code = GET_CODE(op);
2569 if (!(code == LEU || code == LTU || code == GEU
2582 dsp16xx_rtx_costs (x, code, outer_code, total)
2585 int outer_code ATTRIBUTE_UNUSED;
2591 *total = (unsigned HOST_WIDE_INT) INTVAL (x) < 65536 ? 0 : 2;
2597 *total = COSTS_N_INSNS (1);
2601 *total = COSTS_N_INSNS (2);
2605 *total = COSTS_N_INSNS (GET_MODE (x) == QImode ? 2 : 4);
2610 *total = COSTS_N_INSNS (38);
2614 if (GET_MODE (x) == QImode)
2615 *total = COSTS_N_INSNS (2);
2617 *total = COSTS_N_INSNS (38);
2625 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2632 *total = COSTS_N_INSNS (38);
2638 *total = COSTS_N_INSNS (1);
2644 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2646 HOST_WIDE_INT number = INTVAL (XEXP (x, 1));
2647 if (number == 1 || number == 4 || number == 8
2649 *total = COSTS_N_INSNS (1);
2650 else if (TARGET_BMU)
2651 *total = COSTS_N_INSNS (2);
2653 *total = COSTS_N_INSNS (num_1600_core_shifts (number));
2660 *total = COSTS_N_INSNS (1);
2662 *total = COSTS_N_INSNS (15);