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 GCC.
7 GCC 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 GCC 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 GCC; 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 void dsp16xx_file_start PARAMS ((void));
155 static bool dsp16xx_rtx_costs PARAMS ((rtx, int, int, int *));
156 static int dsp16xx_address_cost PARAMS ((rtx));
158 /* Initialize the GCC target structure. */
160 #undef TARGET_ASM_BYTE_OP
161 #define TARGET_ASM_BYTE_OP "\tint\t"
162 #undef TARGET_ASM_ALIGNED_HI_OP
163 #define TARGET_ASM_ALIGNED_HI_OP NULL
164 #undef TARGET_ASM_ALIGNED_SI_OP
165 #define TARGET_ASM_ALIGNED_SI_OP NULL
167 #undef TARGET_ASM_FUNCTION_PROLOGUE
168 #define TARGET_ASM_FUNCTION_PROLOGUE dsp16xx_output_function_prologue
169 #undef TARGET_ASM_FUNCTION_EPILOGUE
170 #define TARGET_ASM_FUNCTION_EPILOGUE dsp16xx_output_function_epilogue
172 #undef TARGET_ASM_FILE_START
173 #define TARGET_ASM_FILE_START dsp16xx_file_start
175 #undef TARGET_RTX_COSTS
176 #define TARGET_RTX_COSTS dsp16xx_rtx_costs
177 #undef TARGET_ADDRESS_COST
178 #define TARGET_ADDRESS_COST dsp16xx_address_cost
180 struct gcc_target targetm = TARGET_INITIALIZER;
183 hard_regno_mode_ok (regno, mode)
185 enum machine_mode mode;
192 /* We can't use the c0-c2 for QImode, since they are only
196 if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
201 /* We only allow a0, a1, y, and p to be allocated for 32-bit modes.
202 Additionally we allow the virtual ybase registers to be used for 32-bit
212 if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
213 || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
224 dsp16xx_reg_class_from_letter (c)
239 return ACCUM_HIGH_REGS;
269 return ACCUM_Y_OR_P_REGS;
275 return (TARGET_BMU ? BMU_REGS : NO_REGS);
278 return YBASE_VIRT_REGS;
290 return YBASE_ELIGIBLE_REGS;
293 return ACCUM_LOW_REGS;
296 return NON_YBASE_REGS;
302 return SLOW_MEM_LOAD_REGS;
309 /* Return the class number of the smallest class containing
313 regno_reg_class(regno)
319 return (int) A0L_REG;
321 return (int) A1L_REG;
324 return (int) A0H_REG;
326 return (int) A1H_REG;
341 case REG_R0: case REG_R1: case REG_R2: case REG_R3:
342 return (int) Y_ADDR_REGS;
347 return (int) GENERAL_REGS;
350 return (int) GENERAL_REGS;
353 return (int) GENERAL_REGS;
355 case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:
356 return (int) BMU_REGS;
358 case REG_C0: case REG_C1: case REG_C2:
359 return (int) GENERAL_REGS;
362 return (int) GENERAL_REGS;
365 return (int) GENERAL_REGS;
367 case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:
368 case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:
369 case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:
370 case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:
371 case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:
372 case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:
373 case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:
374 case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:
375 return (int) YBASE_VIRT_REGS;
378 return (int) NO_REGS;
382 /* A C expression for the maximum number of consecutive registers of class CLASS
383 needed to hold a value of mode MODE. */
386 class_max_nregs(class, mode)
387 enum reg_class class ATTRIBUTE_UNUSED;
388 enum machine_mode mode;
390 return (GET_MODE_SIZE(mode));
394 limit_reload_class (mode, class)
395 enum machine_mode mode ATTRIBUTE_UNUSED;
396 enum reg_class class;
402 dsp16xx_register_move_cost (from, to)
403 enum reg_class from, to;
405 if (from == A0H_REG || from == A0L_REG || from == A0_REG ||
406 from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||
407 from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)
409 if (to == Y_REG || to == P_REG)
415 if (to == A0H_REG || to == A0L_REG || to == A0_REG ||
416 to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||
417 to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)
422 if (from == YBASE_VIRT_REGS)
424 if (to == YBASE_VIRT_REGS)
427 if (to == X_REG || to == YH_REG || to == YL_REG ||
428 to == Y_REG || to == PL_REG || to == PH_REG ||
429 to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||
438 if (to == YBASE_VIRT_REGS)
440 if (from == X_REG || from == YH_REG || from == YL_REG ||
441 from == Y_REG || from == PL_REG || from == PH_REG ||
442 from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||
454 /* Given an rtx X being reloaded into a reg required to be
455 in class CLASS, return the class of reg to actually use.
456 In general this is just CLASS; but on some machines
457 in some cases it is preferable to use a more restrictive class.
458 Also, we must ensure that a PLUS is reloaded either
459 into an accumulator or an address register. */
462 preferred_reload_class (x, class)
464 enum reg_class class;
466 /* The ybase registers cannot have constants copied directly
473 case YBASE_VIRT_REGS:
474 return (!reload_in_progress ? NO_REGS : class);
476 case ACCUM_LOW_OR_YBASE_REGS:
477 return ACCUM_LOW_REGS;
479 case ACCUM_OR_YBASE_REGS:
482 case X_OR_YBASE_REGS:
485 case Y_OR_YBASE_REGS:
488 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
489 return YL_OR_PL_OR_ACCUM_LOW_REGS;
491 case P_OR_YBASE_REGS:
494 case ACCUM_Y_P_OR_YBASE_REGS:
495 return ACCUM_Y_OR_P_REGS;
497 case Y_ADDR_OR_YBASE_REGS:
500 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
501 return NON_HIGH_YBASE_ELIGIBLE_REGS;;
503 case YBASE_OR_YBASE_ELIGIBLE_REGS:
504 return YBASE_ELIGIBLE_REGS;
506 case NO_HIGH_ALL_REGS:
507 return NOHIGH_NON_YBASE_REGS;
510 return NON_YBASE_REGS;
517 /* If x is not an accumulator or a ybase register, restrict the class of registers
518 we can copy the register into. */
520 if (REG_P (x) && !IS_ACCUM_REG (REGNO (x)) && !IS_YBASE_REGISTER_WINDOW (REGNO (x)))
525 case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
526 case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS:
527 case A1_REG: case ACCUM_REGS:
531 return (!reload_in_progress ? NO_REGS : class);
533 case X_OR_ACCUM_LOW_REGS:
534 return ACCUM_LOW_REGS;
536 case X_OR_ACCUM_REGS:
540 return (!reload_in_progress ? NO_REGS : class);
542 case YH_OR_ACCUM_HIGH_REGS:
543 return ACCUM_HIGH_REGS;
547 return (!reload_in_progress ? NO_REGS : class);
549 case YL_OR_ACCUM_LOW_REGS:
550 return ACCUM_LOW_REGS;
553 case X_OR_Y_REGS: case Y_REG:
554 return (!reload_in_progress ? NO_REGS : class);
556 case ACCUM_OR_Y_REGS:
560 case X_OR_PH_REGS: case PL_REG:
561 return (!reload_in_progress ? NO_REGS : class);
563 case PL_OR_ACCUM_LOW_REGS:
564 return ACCUM_LOW_REGS;
567 return (!reload_in_progress ? NO_REGS : class);
569 case YL_OR_PL_OR_ACCUM_LOW_REGS:
570 return ACCUM_LOW_REGS;
573 return (!reload_in_progress ? NO_REGS : class);
575 case ACCUM_OR_P_REGS:
579 return (!reload_in_progress ? NO_REGS : class);
581 case ACCUM_LOW_OR_YL_OR_P_REGS:
582 return ACCUM_LOW_REGS;
585 return (!reload_in_progress ? NO_REGS : class);
587 case ACCUM_Y_OR_P_REGS:
590 case NO_FRAME_Y_ADDR_REGS:
592 return (!reload_in_progress ? NO_REGS : class);
594 case ACCUM_LOW_OR_Y_ADDR_REGS:
595 return ACCUM_LOW_REGS;
597 case ACCUM_OR_Y_ADDR_REGS:
600 case X_OR_Y_ADDR_REGS:
601 case Y_OR_Y_ADDR_REGS:
602 case P_OR_Y_ADDR_REGS:
603 return (!reload_in_progress ? NO_REGS : class);
605 case NON_HIGH_YBASE_ELIGIBLE_REGS:
606 return ACCUM_LOW_REGS;
608 case YBASE_ELIGIBLE_REGS:
612 case J_OR_DAU_16_BIT_REGS:
614 return (!reload_in_progress ? NO_REGS : class);
616 case YBASE_VIRT_REGS:
617 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
620 return (!reload_in_progress ? NO_REGS : class);
622 case ACCUM_LOW_OR_YBASE_REGS:
623 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
626 return ACCUM_LOW_REGS;
628 case ACCUM_OR_YBASE_REGS:
629 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
634 case X_OR_YBASE_REGS:
635 case Y_OR_YBASE_REGS:
636 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
637 return YBASE_VIRT_REGS;
639 return (!reload_in_progress ? NO_REGS : class);
641 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
642 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
643 return ACCUM_LOW_OR_YBASE_REGS;
645 return ACCUM_LOW_REGS;
647 case P_OR_YBASE_REGS:
648 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
649 return YBASE_VIRT_REGS;
651 return (!reload_in_progress ? NO_REGS : class);
653 case ACCUM_Y_P_OR_YBASE_REGS:
654 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
655 return ACCUM_OR_YBASE_REGS;
659 case Y_ADDR_OR_YBASE_REGS:
660 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
661 return YBASE_VIRT_REGS;
663 return (!reload_in_progress ? NO_REGS : class);
665 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
666 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
667 return ACCUM_LOW_OR_YBASE_REGS;
669 return ACCUM_LOW_REGS;
671 case YBASE_OR_YBASE_ELIGIBLE_REGS:
672 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
673 return ACCUM_OR_YBASE_REGS;
677 case NO_HIGH_ALL_REGS:
678 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
679 return ACCUM_LOW_OR_YBASE_REGS;
681 return ACCUM_LOW_REGS;
684 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
685 return ACCUM_OR_YBASE_REGS;
689 case NOHIGH_NON_ADDR_REGS:
690 return ACCUM_LOW_REGS;
693 case SLOW_MEM_LOAD_REGS:
696 case NOHIGH_NON_YBASE_REGS:
697 return ACCUM_LOW_REGS;
699 case NO_ACCUM_NON_YBASE_REGS:
700 return (!reload_in_progress ? NO_REGS : class);
710 /* If x (the input) is a ybase register, restrict the class of registers
711 we can copy the register into. */
713 if (REG_P (x) && !TARGET_RESERVE_YBASE
714 && IS_YBASE_REGISTER_WINDOW (REGNO(x)))
719 case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
720 case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS:
721 case A1_REG: case ACCUM_REGS: case X_REG:
722 case X_OR_ACCUM_LOW_REGS: case X_OR_ACCUM_REGS:
723 case YH_REG: case YH_OR_ACCUM_HIGH_REGS:
724 case X_OR_YH_REGS: case YL_REG:
725 case YL_OR_ACCUM_LOW_REGS: case X_OR_YL_REGS:
726 case X_OR_Y_REGS: case Y_REG:
727 case ACCUM_OR_Y_REGS: case PH_REG:
728 case X_OR_PH_REGS: case PL_REG:
729 case PL_OR_ACCUM_LOW_REGS: case X_OR_PL_REGS:
730 case YL_OR_PL_OR_ACCUM_LOW_REGS: case P_REG:
731 case ACCUM_OR_P_REGS: case YL_OR_P_REGS:
732 case ACCUM_LOW_OR_YL_OR_P_REGS: case Y_OR_P_REGS:
733 case ACCUM_Y_OR_P_REGS: case NO_FRAME_Y_ADDR_REGS:
734 case Y_ADDR_REGS: case ACCUM_LOW_OR_Y_ADDR_REGS:
735 case ACCUM_OR_Y_ADDR_REGS: case X_OR_Y_ADDR_REGS:
736 case Y_OR_Y_ADDR_REGS: case P_OR_Y_ADDR_REGS:
737 case NON_HIGH_YBASE_ELIGIBLE_REGS: case YBASE_ELIGIBLE_REGS:
742 return (!reload_in_progress ? NO_REGS : class);
744 case J_OR_DAU_16_BIT_REGS:
745 return ACCUM_HIGH_REGS;
748 case YBASE_VIRT_REGS:
749 return (!reload_in_progress ? NO_REGS : class);
751 case ACCUM_LOW_OR_YBASE_REGS:
752 return ACCUM_LOW_REGS;
754 case ACCUM_OR_YBASE_REGS:
757 case X_OR_YBASE_REGS:
760 case Y_OR_YBASE_REGS:
763 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
764 return YL_OR_PL_OR_ACCUM_LOW_REGS;
766 case P_OR_YBASE_REGS:
769 case ACCUM_Y_P_OR_YBASE_REGS:
770 return ACCUM_Y_OR_P_REGS;
772 case Y_ADDR_OR_YBASE_REGS:
775 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
776 return NON_HIGH_YBASE_ELIGIBLE_REGS;
778 case YBASE_OR_YBASE_ELIGIBLE_REGS:
779 return YBASE_ELIGIBLE_REGS;
781 case NO_HIGH_ALL_REGS:
782 return NON_HIGH_YBASE_ELIGIBLE_REGS;
785 return YBASE_ELIGIBLE_REGS;
787 case NOHIGH_NON_ADDR_REGS:
788 return ACCUM_LOW_OR_YL_OR_P_REGS;
791 return ACCUM_Y_OR_P_REGS;
793 case SLOW_MEM_LOAD_REGS:
794 return ACCUM_OR_Y_ADDR_REGS;
796 case NOHIGH_NON_YBASE_REGS:
797 return NON_HIGH_YBASE_ELIGIBLE_REGS;
799 case NO_ACCUM_NON_YBASE_REGS:
803 return YBASE_ELIGIBLE_REGS;
807 if (GET_CODE (x) == PLUS)
809 if (GET_MODE (x) == QImode
810 && REG_P (XEXP (x,0))
811 && (XEXP (x,0) == frame_pointer_rtx
812 || XEXP (x,0) == stack_pointer_rtx)
813 && (GET_CODE (XEXP (x,1)) == CONST_INT))
815 if (class == ACCUM_HIGH_REGS)
818 /* If the accumulators are not part of the class
819 being reloaded into, return NO_REGS. */
821 if (!reg_class_subset_p (ACCUM_REGS, class))
822 return (!reload_in_progress ? NO_REGS : class);
824 if (reg_class_subset_p (ACCUM_HIGH_REGS, class))
825 return ACCUM_HIGH_REGS;
827 /* We will use accumulator 'a1l' for reloading a
828 PLUS. We can only use one accumulator because
829 'reload_inqi' only allows one alternative to be
832 else if (class == ACCUM_LOW_REGS)
834 else if (class == A0L_REG)
840 if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
845 else if (GET_CODE (x) == MEM)
847 /* We can't copy from a memory location into a
849 if (reg_class_subset_p(YBASE_VIRT_REGS, class))
853 case YBASE_VIRT_REGS:
854 return (!reload_in_progress ? NO_REGS : class);
856 case ACCUM_LOW_OR_YBASE_REGS:
857 return ACCUM_LOW_REGS;
859 case ACCUM_OR_YBASE_REGS:
862 case X_OR_YBASE_REGS:
865 case Y_OR_YBASE_REGS:
868 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
869 return YL_OR_PL_OR_ACCUM_LOW_REGS;
871 case P_OR_YBASE_REGS:
874 case ACCUM_Y_P_OR_YBASE_REGS:
875 return ACCUM_Y_OR_P_REGS;
877 case Y_ADDR_OR_YBASE_REGS:
880 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
881 return NON_HIGH_YBASE_ELIGIBLE_REGS;
883 case YBASE_OR_YBASE_ELIGIBLE_REGS:
884 return YBASE_ELIGIBLE_REGS;
886 case NO_HIGH_ALL_REGS:
887 return NOHIGH_NON_YBASE_REGS;
890 return NON_YBASE_REGS;
903 /* Return the register class of a scratch register needed to copy IN into
904 or out of a register in CLASS in MODE. If it can be done directly,
905 NO_REGS is returned. */
908 secondary_reload_class (class, mode, in)
909 enum reg_class class;
910 enum machine_mode mode;
915 if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
916 regno = true_regnum (in);
918 /* If we are reloading a plus into a high accumulator register,
919 we need a scratch low accumulator, because the low half gets
922 if (class == ACCUM_HIGH_REGS
926 if (GET_CODE (in) == PLUS && mode == QImode)
927 return ACCUM_LOW_REGS;
930 if (class == ACCUM_HIGH_REGS
931 || class == ACCUM_LOW_REGS
937 if (GET_CODE (in) == PLUS && mode == QImode)
939 rtx addr0 = XEXP (in, 0);
940 rtx addr1 = XEXP (in, 1);
942 /* If we are reloading a plus (reg:QI) (reg:QI)
943 we need an additional register. */
944 if (REG_P (addr0) && REG_P (addr1))
949 /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
952 if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS ||
953 class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG ||
954 class == A1H_REG || class == A1_REG) ||
955 (regno >= REG_A0 && regno < REG_A1L + 1))
958 if (class == ACCUM_OR_YBASE_REGS && REG_P(in)
959 && IS_YBASE_ELIGIBLE_REG(regno))
964 /* We can copy the ybase registers into:
965 r0-r3, a0-a1, y, p, & x or the union of
968 if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
973 case (int) X_OR_ACCUM_LOW_REGS:
974 case (int) X_OR_ACCUM_REGS:
976 case (int) YH_OR_ACCUM_HIGH_REGS:
977 case (int) X_OR_YH_REGS:
979 case (int) YL_OR_ACCUM_LOW_REGS:
980 case (int) X_OR_Y_REGS:
981 case (int) X_OR_YL_REGS:
983 case (int) ACCUM_OR_Y_REGS:
985 case (int) X_OR_PH_REGS:
987 case (int) PL_OR_ACCUM_LOW_REGS:
988 case (int) X_OR_PL_REGS:
989 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
991 case (int) ACCUM_OR_P_REGS:
992 case (int) YL_OR_P_REGS:
993 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
994 case (int) Y_OR_P_REGS:
995 case (int) ACCUM_Y_OR_P_REGS:
996 case (int) Y_ADDR_REGS:
997 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
998 case (int) ACCUM_OR_Y_ADDR_REGS:
999 case (int) X_OR_Y_ADDR_REGS:
1000 case (int) Y_OR_Y_ADDR_REGS:
1001 case (int) P_OR_Y_ADDR_REGS:
1002 case (int) YBASE_ELIGIBLE_REGS:
1006 return ACCUM_HIGH_REGS;
1010 /* We can copy r0-r3, a0-a1, y, & p
1011 directly to the ybase registers. In addition
1012 we can use any of the ybase virtual registers
1013 as the secondary reload registers when copying
1014 between any of these registers. */
1016 if (!TARGET_RESERVE_YBASE && regno != -1)
1033 if (class == YBASE_VIRT_REGS)
1037 switch ((int) class)
1040 case (int) X_OR_ACCUM_LOW_REGS:
1041 case (int) X_OR_ACCUM_REGS:
1043 case (int) YH_OR_ACCUM_HIGH_REGS:
1044 case (int) X_OR_YH_REGS:
1046 case (int) YL_OR_ACCUM_LOW_REGS:
1047 case (int) X_OR_Y_REGS:
1048 case (int) X_OR_YL_REGS:
1050 case (int) ACCUM_OR_Y_REGS:
1052 case (int) X_OR_PH_REGS:
1054 case (int) PL_OR_ACCUM_LOW_REGS:
1055 case (int) X_OR_PL_REGS:
1056 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
1058 case (int) ACCUM_OR_P_REGS:
1059 case (int) YL_OR_P_REGS:
1060 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
1061 case (int) Y_OR_P_REGS:
1062 case (int) ACCUM_Y_OR_P_REGS:
1063 case (int) Y_ADDR_REGS:
1064 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
1065 case (int) ACCUM_OR_Y_ADDR_REGS:
1066 case (int) X_OR_Y_ADDR_REGS:
1067 case (int) Y_OR_Y_ADDR_REGS:
1068 case (int) P_OR_Y_ADDR_REGS:
1069 case (int) YBASE_ELIGIBLE_REGS:
1070 return YBASE_VIRT_REGS;
1079 /* Memory or constants can be moved from or to any register
1080 except the ybase virtual registers. */
1081 if (regno == -1 && GET_CODE(in) != PLUS)
1083 if (class == YBASE_VIRT_REGS)
1084 return NON_YBASE_REGS;
1089 if (GET_CODE (in) == PLUS && mode == QImode)
1091 rtx addr0 = XEXP (in, 0);
1092 rtx addr1 = XEXP (in, 1);
1094 /* If we are reloading a plus (reg:QI) (reg:QI)
1095 we need a low accumulator, not a high one. */
1096 if (REG_P (addr0) && REG_P (addr1))
1097 return ACCUM_LOW_REGS;
1105 /* Otherwise, we need a high accumulator(s). */
1106 return ACCUM_HIGH_REGS;
1110 symbolic_address_operand (op, mode)
1112 enum machine_mode mode ATTRIBUTE_UNUSED;
1114 return (symbolic_address_p (op));
1118 symbolic_address_p (op)
1121 switch (GET_CODE (op))
1129 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1130 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1131 && GET_CODE (XEXP (op, 1)) == CONST_INT
1132 && INTVAL (XEXP (op,1)) < 0x20);
1139 /* For a Y address space operand we allow only *rn, *rn++, *rn--.
1140 This routine only recognizes *rn, the '<>' constraints recognize
1141 (*rn++), and (*rn--). */
1144 Y_address_operand (op, mode)
1146 enum machine_mode mode;
1148 return (memory_address_p (mode, op) && !symbolic_address_p (op));
1152 sp_operand (op, mode)
1154 enum machine_mode mode ATTRIBUTE_UNUSED;
1156 return (GET_CODE (op) == PLUS
1157 && (XEXP (op, 0) == stack_pointer_rtx
1158 || XEXP (op, 0) == frame_pointer_rtx)
1159 && GET_CODE (XEXP (op,1)) == CONST_INT);
1163 sp_operand2 (op, mode)
1165 enum machine_mode mode ATTRIBUTE_UNUSED;
1167 if ((GET_CODE (op) == PLUS
1168 && (XEXP (op, 0) == stack_pointer_rtx
1169 || XEXP (op, 0) == frame_pointer_rtx)
1170 && (REG_P (XEXP (op,1))
1171 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
1173 else if ((GET_CODE (op) == PLUS
1174 && (XEXP (op, 1) == stack_pointer_rtx
1175 || XEXP (op, 1) == frame_pointer_rtx)
1176 && (REG_P (XEXP (op,0))
1177 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
1184 nonmemory_arith_operand (op, mode)
1186 enum machine_mode mode;
1188 return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
1192 arith_reg_operand (op, mode)
1194 enum machine_mode mode;
1196 return (register_operand (op, mode)
1197 && (GET_CODE (op) != REG
1198 || REGNO (op) >= FIRST_PSEUDO_REGISTER
1199 || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op)))
1200 && REGNO (op) != FRAME_POINTER_REGNUM)));
1204 call_address_operand (op, mode)
1206 enum machine_mode mode ATTRIBUTE_UNUSED;
1208 if (symbolic_address_p (op) || REG_P(op))
1217 dsp16xx_comparison_operator (op, mode)
1219 enum machine_mode mode;
1221 return ((mode == VOIDmode || GET_MODE (op) == mode)
1222 && GET_RTX_CLASS (GET_CODE (op)) == '<'
1223 && (GET_CODE(op) != GE && GET_CODE (op) != LT &&
1224 GET_CODE (op) != GEU && GET_CODE (op) != LTU));
1228 notice_update_cc(exp)
1231 if (GET_CODE (exp) == SET)
1233 /* Jumps do not alter the cc's. */
1235 if (SET_DEST (exp) == pc_rtx)
1238 /* Moving register or memory into a register:
1239 it doesn't alter the cc's, but it might invalidate
1240 the RTX's which we remember the cc's came from.
1241 (Note that moving a constant 0 or 1 MAY set the cc's). */
1242 if (REG_P (SET_DEST (exp))
1243 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
1245 if (cc_status.value1
1246 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1247 cc_status.value1 = 0;
1248 if (cc_status.value2
1249 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1250 cc_status.value2 = 0;
1253 /* Moving register into memory doesn't alter the cc's.
1254 It may invalidate the RTX's which we remember the cc's came from. */
1255 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
1257 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1258 cc_status.value1 = 0;
1259 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1260 cc_status.value2 = 0;
1263 /* Function calls clobber the cc's. */
1264 else if (GET_CODE (SET_SRC (exp)) == CALL)
1269 /* Tests and compares set the cc's in predictable ways. */
1270 else if (SET_DEST (exp) == cc0_rtx)
1273 cc_status.value1 = SET_SRC (exp);
1276 /* Certain instructions effect the condition codes. */
1277 else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT)
1278 switch (GET_CODE (SET_SRC (exp)))
1282 if (REG_P (SET_DEST (exp)))
1284 /* Address registers don't set the condition codes. */
1285 if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp))))
1300 cc_status.value1 = SET_SRC (exp);
1301 cc_status.value2 = SET_DEST (exp);
1312 else if (GET_CODE (exp) == PARALLEL
1313 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1315 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1318 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1321 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1334 dsp16xx_makes_calls ()
1338 for (insn = get_insns (); insn; insn = next_insn (insn))
1339 if (GET_CODE (insn) == CALL_INSN)
1346 compute_frame_size (size)
1355 /* This value is needed to compute reg_size. */
1356 current_frame_info.function_makes_calls = !leaf_function_p ();
1361 args_size = current_function_outgoing_args_size;
1362 reg_size = reg_save_size ();
1364 total_size = var_size + args_size + extra_size + reg_size;
1367 /* Save other computed information. */
1368 current_frame_info.total_size = total_size;
1369 current_frame_info.var_size = var_size;
1370 current_frame_info.args_size = args_size;
1371 current_frame_info.extra_size = extra_size;
1372 current_frame_info.reg_size = reg_size;
1373 current_frame_info.initialized = reload_completed;
1374 current_frame_info.reg_size = reg_size / UNITS_PER_WORD;
1378 unsigned long offset = args_size + var_size + reg_size;
1379 current_frame_info.sp_save_offset = offset;
1380 current_frame_info.fp_save_offset = offset - total_size;
1387 dsp16xx_call_saved_register (regno)
1391 if (regno == REG_PR && current_frame_info.function_makes_calls)
1394 return (regs_ever_live[regno] && !call_used_regs[regno] &&
1395 !IS_YBASE_REGISTER_WINDOW(regno));
1399 ybase_regs_ever_used ()
1404 for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
1405 if (regs_ever_live[regno])
1415 dsp16xx_output_function_prologue (file, size)
1421 fp = reg_names[FRAME_POINTER_REGNUM];
1422 sp = reg_names[STACK_POINTER_REGNUM];
1423 rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */
1424 a1h = reg_names[REG_A1];
1426 total_size = compute_frame_size (size);
1428 fprintf (file, "\t/* FUNCTION PROLOGUE: */\n");
1429 fprintf (file, "\t/* total=%ld, vars= %ld, regs= %d, args=%d, extra= %ld */\n",
1430 current_frame_info.total_size,
1431 current_frame_info.var_size,
1432 current_frame_info.reg_size,
1433 current_function_outgoing_args_size,
1434 current_frame_info.extra_size);
1436 fprintf (file, "\t/* fp save offset= %ld, sp save_offset= %ld */\n\n",
1437 current_frame_info.fp_save_offset,
1438 current_frame_info.sp_save_offset);
1439 /* Set up the 'ybase' register window. */
1441 if (ybase_regs_ever_used())
1443 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1444 if (TARGET_YBASE_HIGH)
1445 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1447 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1448 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1451 if (current_frame_info.var_size)
1453 if (current_frame_info.var_size == 1)
1454 fprintf (file, "\t*%s++\n", sp);
1457 if (SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0))
1458 fprintf (file, "\t%s=%ld\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]);
1460 fatal_error ("stack size > 32k");
1464 /* Save any registers this function uses, unless they are
1465 used in a call, in which case we don't need to. */
1467 for(regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno)
1468 if (dsp16xx_call_saved_register (regno))
1470 fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[regno]);
1473 /* For debugging purposes, we want the return address to be at a predictable
1475 if (current_frame_info.function_makes_calls)
1476 fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[RETURN_ADDRESS_REGNUM]);
1478 if (current_frame_info.args_size)
1480 if (current_frame_info.args_size == 1)
1481 fprintf (file, "\t*%s++\n", sp);
1483 error ("stack size > 32k");
1486 if (frame_pointer_needed)
1488 fprintf (file, "\t%s=%s\n", a1h, sp);
1489 fprintf (file, "\t%s=%s\n", fp, a1h); /* Establish new base frame */
1490 fprintf (file, "\t%s=%ld\n", reg_names[REG_J], -total_size);
1491 fprintf (file, "\t*%s++%s\n", fp, reg_names[REG_J]);
1494 fprintf (file, "\t/* END FUNCTION PROLOGUE: */\n\n");
1498 init_emulation_routines ()
1500 dsp16xx_addhf3_libcall = (rtx) 0;
1501 dsp16xx_subhf3_libcall = (rtx) 0;
1502 dsp16xx_mulhf3_libcall = (rtx) 0;
1503 dsp16xx_divhf3_libcall = (rtx) 0;
1504 dsp16xx_cmphf3_libcall = (rtx) 0;
1505 dsp16xx_fixhfhi2_libcall = (rtx) 0;
1506 dsp16xx_floathihf2_libcall = (rtx) 0;
1507 dsp16xx_neghf2_libcall = (rtx) 0;
1509 dsp16xx_mulhi3_libcall = (rtx) 0;
1510 dsp16xx_udivqi3_libcall = (rtx) 0;
1511 dsp16xx_udivhi3_libcall = (rtx) 0;
1512 dsp16xx_divqi3_libcall = (rtx) 0;
1513 dsp16xx_divhi3_libcall = (rtx) 0;
1514 dsp16xx_modqi3_libcall = (rtx) 0;
1515 dsp16xx_modhi3_libcall = (rtx) 0;
1516 dsp16xx_umodqi3_libcall = (rtx) 0;
1517 dsp16xx_umodhi3_libcall = (rtx) 0;
1518 dsp16xx_ashrhi3_libcall = (rtx) 0;
1519 dsp16xx_ashlhi3_libcall = (rtx) 0;
1520 dsp16xx_ucmphi2_libcall = (rtx) 0;
1521 dsp16xx_lshrhi3_libcall = (rtx) 0;
1525 dsp16xx_output_function_epilogue (file, size)
1527 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
1531 fp = reg_names[FRAME_POINTER_REGNUM];
1532 sp = reg_names[STACK_POINTER_REGNUM];
1533 rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */
1534 a1h = reg_names[REG_A1];
1536 fprintf (file, "\n\t/* FUNCTION EPILOGUE: */\n");
1538 if (current_frame_info.args_size)
1540 if (current_frame_info.args_size == 1)
1541 fprintf (file, "\t*%s--\n", sp);
1544 fprintf (file, "\t%s=%ld\n\t*%s++%s\n",
1545 reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]);
1549 if (ybase_regs_ever_used())
1551 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1552 if (TARGET_YBASE_HIGH)
1553 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1555 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1556 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1559 if (current_frame_info.function_makes_calls)
1560 fprintf (file, "\t%s=pop(*%s)\n", reg_names[RETURN_ADDRESS_REGNUM], sp);
1562 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
1563 if (dsp16xx_call_saved_register(regno))
1565 fprintf (file, "\t%s=pop(*%s)\n", reg_names[regno], sp);
1568 if (current_frame_info.var_size)
1570 if (current_frame_info.var_size == 1)
1571 fprintf (file, "\t*%s--\n", sp);
1574 fprintf (file, "\t%s=%ld\n\t*%s++%s\n",
1575 reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]);
1579 fprintf (file, "\treturn\n");
1580 /* Reset the frame info for the next function. */
1581 current_frame_info = zero_frame_info;
1582 init_emulation_routines ();
1585 /* Emit insns to move operands[1] into operands[0].
1587 Return 1 if we have written out everything that needs to be done to
1588 do the move. Otherwise, return 0 and the caller will emit the move
1592 emit_move_sequence (operands, mode)
1594 enum machine_mode mode;
1596 register rtx operand0 = operands[0];
1597 register rtx operand1 = operands[1];
1599 /* We can only store registers to memory. */
1601 if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
1602 operands[1] = force_reg (mode, operand1);
1608 double_reg_from_memory (operands)
1613 if (GET_CODE(XEXP(operands[1],0)) == POST_INC)
1615 output_asm_insn ("%u0=%1", operands);
1616 output_asm_insn ("%w0=%1", operands);
1618 else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC)
1620 xoperands[1] = XEXP (XEXP (operands[1], 0), 0);
1621 xoperands[0] = operands[0];
1623 /* We can't use j anymore since the compiler can allocate it. */
1624 /* output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */
1625 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands);
1627 else if (GET_CODE(XEXP(operands[1],0)) == PLUS)
1632 output_asm_insn ("%u0=%1", operands);
1635 /* In order to print out the least significant word we must
1636 use 'offset + 1'. */
1637 addr = XEXP (operands[1], 0);
1638 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1639 offset = INTVAL(XEXP(addr,0)) + 1;
1640 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1641 offset = INTVAL(XEXP(addr,1)) + 1;
1643 fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31);
1647 xoperands[1] = XEXP(operands[1],0);
1648 xoperands[0] = operands[0];
1650 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
1656 double_reg_to_memory (operands)
1661 if (GET_CODE(XEXP(operands[0],0)) == POST_INC)
1663 output_asm_insn ("%0=%u1", operands);
1664 output_asm_insn ("%0=%w1", operands);
1666 else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC)
1668 xoperands[0] = XEXP (XEXP (operands[0], 0), 0);
1669 xoperands[1] = operands[1];
1671 /* We can't use j anymore since the compiler can allocate it. */
1673 /* output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */
1674 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands);
1677 else if (GET_CODE(XEXP(operands[0],0)) == PLUS)
1682 output_asm_insn ("%0=%u1", operands);
1684 /* In order to print out the least significant word we must
1685 use 'offset + 1'. */
1686 addr = XEXP (operands[0], 0);
1687 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1688 offset = INTVAL(XEXP(addr,0)) + 1;
1689 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1690 offset = INTVAL(XEXP(addr,1)) + 1;
1692 fatal_error ("invalid addressing mode");
1694 fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
1698 xoperands[0] = XEXP(operands[0],0);
1699 xoperands[1] = operands[1];
1701 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
1708 if (chip_name == (char *) 0)
1709 chip_name = DEFAULT_CHIP_NAME;
1711 if (text_seg_name == (char *) 0)
1712 text_seg_name = DEFAULT_TEXT_SEG_NAME;
1714 if (data_seg_name == (char *) 0)
1715 data_seg_name = DEFAULT_DATA_SEG_NAME;
1717 if (bss_seg_name == (char *) 0)
1718 bss_seg_name = DEFAULT_BSS_SEG_NAME;
1720 if (const_seg_name == (char *) 0)
1721 const_seg_name = DEFAULT_CONST_SEG_NAME;
1723 save_chip_name = xstrdup (chip_name);
1725 rsect_text = concat (".rsect \"", text_seg_name, "\"", NULL);
1726 rsect_data = concat (".rsect \"", data_seg_name, "\"", NULL);
1727 rsect_bss = concat (".rsect \"", bss_seg_name, "\"", NULL);
1728 rsect_const = concat (".rsect \"", const_seg_name, "\"", NULL);
1732 next_cc_user_unsigned (insn)
1735 switch (next_cc_user_code (insn))
1748 next_cc_user_code (insn)
1751 /* If no insn could be found we assume that the jump has been
1752 deleted and the compare will be deleted later. */
1754 if (!(insn = next_cc0_user (insn)))
1755 return (enum rtx_code) 0;
1756 else if (GET_CODE (insn) == JUMP_INSN
1757 && GET_CODE (PATTERN (insn)) == SET
1758 && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
1759 return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
1760 else if (GET_CODE (insn) == INSN
1761 && GET_CODE (PATTERN (insn)) == SET
1762 && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode))
1763 return GET_CODE (SET_SRC (PATTERN (insn)));
1769 print_operand(file, op, letter)
1776 code = GET_CODE(op);
1781 code = reverse_condition (code);
1790 else if (code == NE)
1795 else if (code == GT || code == GTU)
1800 else if (code == LT || code == LTU)
1805 else if (code == GE || code == GEU)
1810 else if (code == LE || code == LEU)
1825 /* Print the low half of a 32-bit register pair. */
1827 fprintf (file, "%s", reg_names[REGNO (op) + 1]);
1828 else if (letter == 'u' || !letter)
1829 fprintf (file, "%s", reg_names[REGNO (op)]);
1830 else if (letter == 'b')
1831 fprintf (file, "%sh", reg_names[REGNO (op)]);
1832 else if (letter == 'm')
1833 fprintf (file, "%s", himode_reg_name[REGNO (op)]);
1835 output_operand_lossage ("bad register extension code");
1837 else if (code == MEM)
1838 output_address (XEXP(op,0));
1839 else if (code == CONST_INT)
1841 HOST_WIDE_INT val = INTVAL (op);
1844 fprintf (file, HOST_WIDE_INT_PRINT_HEX, val & 0xffff);
1845 else if (letter == 'h')
1846 fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
1847 else if (letter == 'U')
1848 fprintf (file, HOST_WIDE_INT_PRINT_HEX, (val >> 16) & 0xffff);
1850 output_addr_const(file, op);
1852 else if (code == CONST_DOUBLE && GET_MODE(op) != DImode)
1856 REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1857 REAL_VALUE_TO_TARGET_SINGLE (r, l);
1858 fprintf (file, "0x%lx", l);
1860 else if (code == CONST)
1862 rtx addr = XEXP (op, 0);
1864 if (GET_CODE (addr) != PLUS)
1866 output_addr_const(file, op);
1870 if ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
1871 || GET_CODE (XEXP (addr, 0)) == LABEL_REF)
1872 && (GET_CODE (XEXP (addr, 1)) == CONST_INT))
1874 int n = INTVAL (XEXP(addr, 1));
1875 output_addr_const (file, XEXP (addr, 0));
1878 fprintf (file, "+");
1880 n = (int) (short) n;
1881 fprintf (file, "%d", n);
1883 else if ((GET_CODE (XEXP (addr, 1)) == SYMBOL_REF
1884 || GET_CODE (XEXP (addr, 1)) == LABEL_REF)
1885 && (GET_CODE (XEXP (addr, 0)) == CONST_INT))
1887 int n = INTVAL (XEXP(addr, 0));
1888 output_addr_const (file, XEXP (addr, 1));
1891 fprintf (file, "+");
1893 n = (int) (short) n;
1894 fprintf (file, "%d", n);
1897 output_addr_const(file, op);
1900 output_addr_const (file, op);
1905 print_operand_address(file, addr)
1912 switch (GET_CODE (addr))
1915 fprintf (file, "*%s", reg_names[REGNO (addr)]);
1918 fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
1921 fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
1924 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1925 offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1);
1926 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1927 offset = INTVAL(XEXP(addr,1)), base = XEXP(addr,0);
1930 if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
1932 if (offset >= -31 && offset <= 0)
1933 offset = 31 + offset;
1935 fatal_error ("invalid offset in ybase addressing");
1938 fatal_error ("invalid register in ybase addressing");
1940 fprintf (file, "*(%d)", offset);
1944 if (FITS_5_BITS (addr))
1945 fprintf (file, "*(0x%x)", (int)(INTVAL (addr) & 0x20));
1947 output_addr_const (file, addr);
1952 output_dsp16xx_float_const (operands)
1955 rtx src = operands[1];
1960 REAL_VALUE_FROM_CONST_DOUBLE (d, src);
1961 REAL_VALUE_TO_TARGET_SINGLE (d, value);
1963 operands[1] = GEN_INT (value);
1964 output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands);
1970 int reg_save_size = 0;
1973 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1974 if (dsp16xx_call_saved_register (regno))
1976 reg_save_size += UNITS_PER_WORD;
1979 /* If the function makes calls we will save need to save the 'pr' register. */
1980 if (current_frame_info.function_makes_calls)
1983 return (reg_save_size);
1988 dsp16xx_starting_frame_offset()
1990 int reg_save_size = 0;
1993 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1994 if (dsp16xx_call_saved_register (regno))
1996 reg_save_size += UNITS_PER_WORD;
1999 return (reg_save_size);
2004 initial_frame_pointer_offset()
2008 offset = compute_frame_size (get_frame_size());
2010 #ifdef STACK_GROWS_DOWNWARD
2017 /* Generate the minimum number of 1600 core shift instructions
2018 to shift by 'shift_amount'. */
2022 emit_1600_core_shift (shift_op, operands, shift_amount, mode)
2023 enum rtx_code shift_op;
2026 enum machine_mode mode;
2030 int first_shift_emitted = 0;
2032 while (shift_amount != 0)
2034 if (shift_amount/16)
2036 quotient = shift_amount/16;
2037 shift_amount = shift_amount - (quotient * 16);
2038 for (i = 0; i < quotient; i++)
2039 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2040 gen_rtx (shift_op, mode,
2042 ? operands[0] : operands[1],
2044 first_shift_emitted = 1;
2046 else if (shift_amount/8)
2048 quotient = shift_amount/8;
2049 shift_amount = shift_amount - (quotient * 8);
2050 for (i = 0; i < quotient; i++)
2051 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2052 gen_rtx (shift_op, mode,
2054 ? operands[0] : operands[1],
2056 first_shift_emitted = 1;
2058 else if (shift_amount/4)
2060 quotient = shift_amount/4;
2061 shift_amount = shift_amount - (quotient * 4);
2062 for (i = 0; i < quotient; i++)
2063 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2064 gen_rtx (shift_op, mode,
2066 ? operands[0] : operands[1],
2068 first_shift_emitted = 1;
2070 else if (shift_amount/1)
2072 quotient = shift_amount/1;
2073 shift_amount = shift_amount - (quotient * 1);
2074 for (i = 0; i < quotient; i++)
2075 emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2076 gen_rtx (shift_op, mode,
2078 ? operands[0] : operands[1],
2080 first_shift_emitted = 1;
2086 emit_1600_core_shift (shift_op, operands, shift_amount)
2087 enum rtx_code shift_op;
2093 int first_shift_emitted = 0;
2094 const char * const *shift_asm_ptr;
2095 const char * const *shift_asm_ptr_first;
2097 if (shift_op == ASHIFT)
2099 shift_asm_ptr = ashift_left_asm;
2100 shift_asm_ptr_first = ashift_left_asm_first;
2102 else if (shift_op == ASHIFTRT)
2104 shift_asm_ptr = ashift_right_asm;
2105 shift_asm_ptr_first = ashift_right_asm_first;
2107 else if (shift_op == LSHIFTRT)
2109 shift_asm_ptr = lshift_right_asm;
2110 shift_asm_ptr_first = lshift_right_asm_first;
2113 fatal_error ("invalid shift operator in emit_1600_core_shift");
2115 while (shift_amount != 0)
2117 if (shift_amount/16)
2119 quotient = shift_amount/16;
2120 shift_amount = shift_amount - (quotient * 16);
2121 for (i = 0; i < quotient; i++)
2122 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_16]
2123 : shift_asm_ptr_first[SHIFT_INDEX_16]), operands);
2124 first_shift_emitted = 1;
2126 else if (shift_amount/8)
2128 quotient = shift_amount/8;
2129 shift_amount = shift_amount - (quotient * 8);
2130 for (i = 0; i < quotient; i++)
2131 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_8]
2132 : shift_asm_ptr_first[SHIFT_INDEX_8]), operands);
2133 first_shift_emitted = 1;
2135 else if (shift_amount/4)
2137 quotient = shift_amount/4;
2138 shift_amount = shift_amount - (quotient * 4);
2139 for (i = 0; i < quotient; i++)
2140 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_4]
2141 : shift_asm_ptr_first[SHIFT_INDEX_4]), operands);
2142 first_shift_emitted = 1;
2144 else if (shift_amount/1)
2146 quotient = shift_amount/1;
2147 shift_amount = shift_amount - (quotient * 1);
2148 for (i = 0; i < quotient; i++)
2149 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_1]
2150 : shift_asm_ptr_first[SHIFT_INDEX_1]), operands);
2151 first_shift_emitted = 1;
2158 num_1600_core_shifts (shift_amount)
2163 int first_shift_emitted = 0;
2166 while (shift_amount != 0)
2168 if (shift_amount/16)
2170 quotient = shift_amount/16;
2171 shift_amount = shift_amount - (quotient * 16);
2172 for (i = 0; i < quotient; i++)
2174 first_shift_emitted = 1;
2176 else if (shift_amount/8)
2178 quotient = shift_amount/8;
2179 shift_amount = shift_amount - (quotient * 8);
2180 for (i = 0; i < quotient; i++)
2183 first_shift_emitted = 1;
2185 else if (shift_amount/4)
2187 quotient = shift_amount/4;
2188 shift_amount = shift_amount - (quotient * 4);
2189 for (i = 0; i < quotient; i++)
2192 first_shift_emitted = 1;
2194 else if (shift_amount/1)
2196 quotient = shift_amount/1;
2197 shift_amount = shift_amount - (quotient * 1);
2198 for (i = 0; i < quotient; i++)
2201 first_shift_emitted = 1;
2208 asm_output_common(file, name, size, rounded)
2211 int size ATTRIBUTE_UNUSED;
2215 (*targetm.asm_out.globalize_label) (file, name);
2216 assemble_name (file, name);
2219 fprintf (file, "%d * int\n", rounded);
2221 fprintf (file, "int\n");
2225 asm_output_local(file, name, size, rounded)
2228 int size ATTRIBUTE_UNUSED;
2232 assemble_name (file, name);
2235 fprintf (file, "%d * int\n", rounded);
2237 fprintf (file, "int\n");
2241 dsp16xx_address_cost (addr)
2244 switch (GET_CODE (addr))
2254 rtx offset = const0_rtx;
2255 addr = eliminate_constant_term (addr, &offset);
2257 if (GET_CODE (addr) == LABEL_REF)
2260 if (GET_CODE (addr) != SYMBOL_REF)
2263 if (INTVAL (offset) == 0)
2268 case POST_INC: case POST_DEC:
2269 return (GET_MODE (addr) == QImode ? 1 : 2);
2271 case SYMBOL_REF: case LABEL_REF:
2276 register rtx plus0 = XEXP (addr, 0);
2277 register rtx plus1 = XEXP (addr, 1);
2279 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
2281 plus0 = XEXP (addr, 1);
2282 plus1 = XEXP (addr, 0);
2285 if (GET_CODE (plus0) != REG)
2288 switch (GET_CODE (plus1))
2299 return dsp16xx_address_cost (plus1) + 1;
2308 /* Determine whether a function argument is passed in a register, and
2311 The arguments are CUM, which summarizes all the previous
2312 arguments; MODE, the machine mode of the argument; TYPE,
2313 the data type of the argument as a tree node or 0 if that is not known
2314 (which happens for C support library functions); and NAMED,
2315 which is 1 for an ordinary argument and 0 for nameless arguments that
2316 correspond to `...' in the called function's prototype.
2318 The value of the expression should either be a `reg' RTX for the
2319 hard register in which to pass the argument, or zero to pass the
2320 argument on the stack.
2322 On the dsp1610 the first four words of args are normally in registers
2323 and the rest are pushed. If we a long or on float mode, the argument
2324 must begin on an even register boundary
2326 Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2327 For structures that are passed in memory, but could have been
2328 passed in registers, we first load the structure into the
2329 register, and then when the last argument is passed, we store
2330 the registers into the stack locations. This fixes some bugs
2331 where GCC did not expect to have register arguments, followed. */
2334 dsp16xx_function_arg (args_so_far, mode, type, named)
2335 CUMULATIVE_ARGS args_so_far;
2336 enum machine_mode mode;
2342 if ((args_so_far & 1) != 0
2343 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2346 if (type == void_type_node)
2347 return (struct rtx_def *) 0;
2349 if (named && args_so_far < 4 && !MUST_PASS_IN_STACK (mode,type))
2350 return gen_rtx_REG (mode, args_so_far + FIRST_REG_FOR_FUNCTION_ARG);
2352 return (struct rtx_def *) 0;
2355 return (struct rtx_def *) 0;
2358 /* Advance the argument to the next argument position. */
2361 dsp16xx_function_arg_advance (cum, mode, type, named)
2362 CUMULATIVE_ARGS *cum; /* current arg information */
2363 enum machine_mode mode; /* current arg mode */
2364 tree type; /* type of the argument or 0 if lib support */
2365 int named ATTRIBUTE_UNUSED;/* whether or not the argument was named */
2370 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2373 if (mode != BLKmode)
2374 *cum += GET_MODE_SIZE (mode);
2376 *cum += int_size_in_bytes (type);
2381 dsp16xx_file_start ()
2383 fprintf (asm_out_file, "#include <%s.h>\n", save_chip_name);
2390 enum machine_mode mode;
2392 mode = GET_MODE (x);
2395 emit_insn (gen_rtx_PARALLEL
2397 gen_rtvec (2, gen_rtx_SET (VOIDmode, cc0_rtx, x),
2398 gen_rtx_CLOBBER (VOIDmode,
2399 gen_rtx_SCRATCH (QImode)))));
2400 else if (mode == HImode)
2401 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, x));
2403 fatal_error ("invalid mode for gen_tst_reg");
2409 gen_compare_reg (code, x, y)
2413 enum machine_mode mode;
2415 mode = GET_MODE (x);
2416 /* For floating point compare insns, a call is generated so don't
2417 do anything here. */
2419 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2424 if (code == GTU || code == GEU
2425 || code == LTU || code == LEU)
2427 emit_insn (gen_rtx_PARALLEL
2430 gen_rtx_SET (VOIDmode, cc0_rtx,
2431 gen_rtx_COMPARE (mode, x, y)),
2432 gen_rtx_CLOBBER (VOIDmode,
2433 gen_rtx_SCRATCH (QImode)),
2434 gen_rtx_CLOBBER (VOIDmode,
2435 gen_rtx_SCRATCH (QImode)))));
2439 emit_insn (gen_rtx_PARALLEL
2441 gen_rtvec (3, gen_rtx_SET (VOIDmode, cc0_rtx,
2442 gen_rtx_COMPARE (mode, x, y)),
2443 gen_rtx_CLOBBER (VOIDmode,
2444 gen_rtx_SCRATCH (QImode)),
2445 gen_rtx_CLOBBER (VOIDmode,
2446 gen_rtx_SCRATCH (QImode)))));
2449 else if (mode == HImode)
2451 if (code == GTU || code == GEU
2452 || code == LTU || code == LEU)
2454 emit_insn (gen_rtx_PARALLEL
2457 gen_rtx_SET (VOIDmode, cc0_rtx,
2458 gen_rtx_COMPARE (VOIDmode, x, y)),
2459 gen_rtx_CLOBBER (VOIDmode,
2460 gen_rtx_SCRATCH (QImode)),
2461 gen_rtx_CLOBBER (VOIDmode,
2462 gen_rtx_SCRATCH (QImode)),
2463 gen_rtx_CLOBBER (VOIDmode,
2464 gen_rtx_SCRATCH (QImode)),
2465 gen_rtx_CLOBBER (VOIDmode,
2466 gen_rtx_SCRATCH (QImode)))));
2469 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx,
2470 gen_rtx_COMPARE (VOIDmode,
2471 force_reg (HImode, x),
2472 force_reg (HImode,y))));
2475 fatal_error ("invalid mode for integer comparison in gen_compare_reg");
2481 output_block_move (operands)
2484 int loop_count = INTVAL(operands[2]);
2487 fprintf (asm_out_file, "\tdo %d {\n", loop_count);
2488 xoperands[0] = operands[4];
2489 xoperands[1] = operands[1];
2490 output_asm_insn ("%0=*%1++", xoperands);
2492 xoperands[0] = operands[0];
2493 xoperands[1] = operands[4];
2494 output_asm_insn ("*%0++=%1", xoperands);
2496 fprintf (asm_out_file, "\t}\n");
2501 uns_comparison_operator (op, mode)
2503 enum machine_mode mode;
2505 if (mode == VOIDmode || GET_MODE (op) == mode)
2509 code = GET_CODE(op);
2511 if (code == LEU || code == LTU || code == GEU
2524 signed_comparison_operator (op, mode)
2526 enum machine_mode mode;
2528 if (mode == VOIDmode || GET_MODE (op) == mode)
2532 code = GET_CODE(op);
2534 if (!(code == LEU || code == LTU || code == GEU
2547 dsp16xx_rtx_costs (x, code, outer_code, total)
2550 int outer_code ATTRIBUTE_UNUSED;
2556 *total = (unsigned HOST_WIDE_INT) INTVAL (x) < 65536 ? 0 : 2;
2562 *total = COSTS_N_INSNS (1);
2566 *total = COSTS_N_INSNS (2);
2570 *total = COSTS_N_INSNS (GET_MODE (x) == QImode ? 2 : 4);
2575 *total = COSTS_N_INSNS (38);
2579 if (GET_MODE (x) == QImode)
2580 *total = COSTS_N_INSNS (2);
2582 *total = COSTS_N_INSNS (38);
2590 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2597 *total = COSTS_N_INSNS (38);
2603 *total = COSTS_N_INSNS (1);
2609 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2611 HOST_WIDE_INT number = INTVAL (XEXP (x, 1));
2612 if (number == 1 || number == 4 || number == 8
2614 *total = COSTS_N_INSNS (1);
2615 else if (TARGET_BMU)
2616 *total = COSTS_N_INSNS (2);
2618 *total = COSTS_N_INSNS (num_1600_core_shifts (number));
2625 *total = COSTS_N_INSNS (1);
2627 *total = COSTS_N_INSNS (15);