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 (void);
152 static void dsp16xx_output_function_prologue (FILE *, HOST_WIDE_INT
);
153 static void dsp16xx_output_function_epilogue (FILE *, HOST_WIDE_INT
);
154 static void dsp16xx_file_start (void);
155 static bool dsp16xx_rtx_costs (rtx
, int, int, int *);
156 static int dsp16xx_address_cost (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
207 #if 0 /* ??? These modes do not appear in the machine description nor
208 are there library routines for them. */
215 if (regno
== REG_A0
|| regno
== REG_A1
|| regno
== REG_Y
|| regno
== REG_PROD
216 || (IS_YBASE_REGISTER_WINDOW(regno
) && ((regno
& 1) == 0)))
227 dsp16xx_reg_class_from_letter (c
)
242 return ACCUM_HIGH_REGS
;
272 return ACCUM_Y_OR_P_REGS
;
278 return (TARGET_BMU
? BMU_REGS
: NO_REGS
);
281 return YBASE_VIRT_REGS
;
293 return YBASE_ELIGIBLE_REGS
;
296 return ACCUM_LOW_REGS
;
299 return NON_YBASE_REGS
;
305 return SLOW_MEM_LOAD_REGS
;
312 /* Return the class number of the smallest class containing
316 regno_reg_class(regno
)
322 return (int) A0L_REG
;
324 return (int) A1L_REG
;
327 return (int) A0H_REG
;
329 return (int) A1H_REG
;
344 case REG_R0
: case REG_R1
: case REG_R2
: case REG_R3
:
345 return (int) Y_ADDR_REGS
;
350 return (int) GENERAL_REGS
;
353 return (int) GENERAL_REGS
;
356 return (int) GENERAL_REGS
;
358 case REG_AR0
: case REG_AR1
: case REG_AR2
: case REG_AR3
:
359 return (int) BMU_REGS
;
361 case REG_C0
: case REG_C1
: case REG_C2
:
362 return (int) GENERAL_REGS
;
365 return (int) GENERAL_REGS
;
368 return (int) GENERAL_REGS
;
370 case REG_YBASE0
: case REG_YBASE1
: case REG_YBASE2
: case REG_YBASE3
:
371 case REG_YBASE4
: case REG_YBASE5
: case REG_YBASE6
: case REG_YBASE7
:
372 case REG_YBASE8
: case REG_YBASE9
: case REG_YBASE10
: case REG_YBASE11
:
373 case REG_YBASE12
: case REG_YBASE13
: case REG_YBASE14
: case REG_YBASE15
:
374 case REG_YBASE16
: case REG_YBASE17
: case REG_YBASE18
: case REG_YBASE19
:
375 case REG_YBASE20
: case REG_YBASE21
: case REG_YBASE22
: case REG_YBASE23
:
376 case REG_YBASE24
: case REG_YBASE25
: case REG_YBASE26
: case REG_YBASE27
:
377 case REG_YBASE28
: case REG_YBASE29
: case REG_YBASE30
: case REG_YBASE31
:
378 return (int) YBASE_VIRT_REGS
;
381 return (int) NO_REGS
;
385 /* A C expression for the maximum number of consecutive registers of class CLASS
386 needed to hold a value of mode MODE. */
389 class_max_nregs(class, mode
)
390 enum reg_class
class ATTRIBUTE_UNUSED
;
391 enum machine_mode mode
;
393 return (GET_MODE_SIZE(mode
));
397 limit_reload_class (mode
, class)
398 enum machine_mode mode ATTRIBUTE_UNUSED
;
399 enum reg_class
class;
405 dsp16xx_register_move_cost (from
, to
)
406 enum reg_class from
, to
;
408 if (from
== A0H_REG
|| from
== A0L_REG
|| from
== A0_REG
||
409 from
== A1H_REG
|| from
== ACCUM_HIGH_REGS
|| from
== A1L_REG
||
410 from
== ACCUM_LOW_REGS
|| from
== A1_REG
|| from
== ACCUM_REGS
)
412 if (to
== Y_REG
|| to
== P_REG
)
418 if (to
== A0H_REG
|| to
== A0L_REG
|| to
== A0_REG
||
419 to
== A1H_REG
|| to
== ACCUM_HIGH_REGS
|| to
== A1L_REG
||
420 to
== ACCUM_LOW_REGS
|| to
== A1_REG
|| to
== ACCUM_REGS
)
425 if (from
== YBASE_VIRT_REGS
)
427 if (to
== YBASE_VIRT_REGS
)
430 if (to
== X_REG
|| to
== YH_REG
|| to
== YL_REG
||
431 to
== Y_REG
|| to
== PL_REG
|| to
== PH_REG
||
432 to
== P_REG
|| to
== Y_ADDR_REGS
|| to
== YBASE_ELIGIBLE_REGS
||
441 if (to
== YBASE_VIRT_REGS
)
443 if (from
== X_REG
|| from
== YH_REG
|| from
== YL_REG
||
444 from
== Y_REG
|| from
== PL_REG
|| from
== PH_REG
||
445 from
== P_REG
|| from
== Y_ADDR_REGS
|| from
== YBASE_ELIGIBLE_REGS
||
457 /* Given an rtx X being reloaded into a reg required to be
458 in class CLASS, return the class of reg to actually use.
459 In general this is just CLASS; but on some machines
460 in some cases it is preferable to use a more restrictive class.
461 Also, we must ensure that a PLUS is reloaded either
462 into an accumulator or an address register. */
465 preferred_reload_class (x
, class)
467 enum reg_class
class;
469 /* The ybase registers cannot have constants copied directly
476 case YBASE_VIRT_REGS
:
477 return (!reload_in_progress
? NO_REGS
: class);
479 case ACCUM_LOW_OR_YBASE_REGS
:
480 return ACCUM_LOW_REGS
;
482 case ACCUM_OR_YBASE_REGS
:
485 case X_OR_YBASE_REGS
:
488 case Y_OR_YBASE_REGS
:
491 case ACCUM_LOW_YL_PL_OR_YBASE_REGS
:
492 return YL_OR_PL_OR_ACCUM_LOW_REGS
;
494 case P_OR_YBASE_REGS
:
497 case ACCUM_Y_P_OR_YBASE_REGS
:
498 return ACCUM_Y_OR_P_REGS
;
500 case Y_ADDR_OR_YBASE_REGS
:
503 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS
:
504 return NON_HIGH_YBASE_ELIGIBLE_REGS
;;
506 case YBASE_OR_YBASE_ELIGIBLE_REGS
:
507 return YBASE_ELIGIBLE_REGS
;
509 case NO_HIGH_ALL_REGS
:
510 return NOHIGH_NON_YBASE_REGS
;
513 return NON_YBASE_REGS
;
520 /* If x is not an accumulator or a ybase register, restrict the class of registers
521 we can copy the register into. */
523 if (REG_P (x
) && !IS_ACCUM_REG (REGNO (x
)) && !IS_YBASE_REGISTER_WINDOW (REGNO (x
)))
528 case A0H_REG
: case A0L_REG
: case A0_REG
: case A1H_REG
:
529 case ACCUM_HIGH_REGS
: case A1L_REG
: case ACCUM_LOW_REGS
:
530 case A1_REG
: case ACCUM_REGS
:
534 return (!reload_in_progress
? NO_REGS
: class);
536 case X_OR_ACCUM_LOW_REGS
:
537 return ACCUM_LOW_REGS
;
539 case X_OR_ACCUM_REGS
:
543 return (!reload_in_progress
? NO_REGS
: class);
545 case YH_OR_ACCUM_HIGH_REGS
:
546 return ACCUM_HIGH_REGS
;
550 return (!reload_in_progress
? NO_REGS
: class);
552 case YL_OR_ACCUM_LOW_REGS
:
553 return ACCUM_LOW_REGS
;
556 case X_OR_Y_REGS
: case Y_REG
:
557 return (!reload_in_progress
? NO_REGS
: class);
559 case ACCUM_OR_Y_REGS
:
563 case X_OR_PH_REGS
: case PL_REG
:
564 return (!reload_in_progress
? NO_REGS
: class);
566 case PL_OR_ACCUM_LOW_REGS
:
567 return ACCUM_LOW_REGS
;
570 return (!reload_in_progress
? NO_REGS
: class);
572 case YL_OR_PL_OR_ACCUM_LOW_REGS
:
573 return ACCUM_LOW_REGS
;
576 return (!reload_in_progress
? NO_REGS
: class);
578 case ACCUM_OR_P_REGS
:
582 return (!reload_in_progress
? NO_REGS
: class);
584 case ACCUM_LOW_OR_YL_OR_P_REGS
:
585 return ACCUM_LOW_REGS
;
588 return (!reload_in_progress
? NO_REGS
: class);
590 case ACCUM_Y_OR_P_REGS
:
593 case NO_FRAME_Y_ADDR_REGS
:
595 return (!reload_in_progress
? NO_REGS
: class);
597 case ACCUM_LOW_OR_Y_ADDR_REGS
:
598 return ACCUM_LOW_REGS
;
600 case ACCUM_OR_Y_ADDR_REGS
:
603 case X_OR_Y_ADDR_REGS
:
604 case Y_OR_Y_ADDR_REGS
:
605 case P_OR_Y_ADDR_REGS
:
606 return (!reload_in_progress
? NO_REGS
: class);
608 case NON_HIGH_YBASE_ELIGIBLE_REGS
:
609 return ACCUM_LOW_REGS
;
611 case YBASE_ELIGIBLE_REGS
:
615 case J_OR_DAU_16_BIT_REGS
:
617 return (!reload_in_progress
? NO_REGS
: class);
619 case YBASE_VIRT_REGS
:
620 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
623 return (!reload_in_progress
? NO_REGS
: class);
625 case ACCUM_LOW_OR_YBASE_REGS
:
626 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
629 return ACCUM_LOW_REGS
;
631 case ACCUM_OR_YBASE_REGS
:
632 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
637 case X_OR_YBASE_REGS
:
638 case Y_OR_YBASE_REGS
:
639 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
640 return YBASE_VIRT_REGS
;
642 return (!reload_in_progress
? NO_REGS
: class);
644 case ACCUM_LOW_YL_PL_OR_YBASE_REGS
:
645 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
646 return ACCUM_LOW_OR_YBASE_REGS
;
648 return ACCUM_LOW_REGS
;
650 case P_OR_YBASE_REGS
:
651 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
652 return YBASE_VIRT_REGS
;
654 return (!reload_in_progress
? NO_REGS
: class);
656 case ACCUM_Y_P_OR_YBASE_REGS
:
657 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
658 return ACCUM_OR_YBASE_REGS
;
662 case Y_ADDR_OR_YBASE_REGS
:
663 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
664 return YBASE_VIRT_REGS
;
666 return (!reload_in_progress
? NO_REGS
: class);
668 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS
:
669 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
670 return ACCUM_LOW_OR_YBASE_REGS
;
672 return ACCUM_LOW_REGS
;
674 case YBASE_OR_YBASE_ELIGIBLE_REGS
:
675 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
676 return ACCUM_OR_YBASE_REGS
;
680 case NO_HIGH_ALL_REGS
:
681 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
682 return ACCUM_LOW_OR_YBASE_REGS
;
684 return ACCUM_LOW_REGS
;
687 if (IS_YBASE_ELIGIBLE_REG (REGNO (x
)))
688 return ACCUM_OR_YBASE_REGS
;
692 case NOHIGH_NON_ADDR_REGS
:
693 return ACCUM_LOW_REGS
;
696 case SLOW_MEM_LOAD_REGS
:
699 case NOHIGH_NON_YBASE_REGS
:
700 return ACCUM_LOW_REGS
;
702 case NO_ACCUM_NON_YBASE_REGS
:
703 return (!reload_in_progress
? NO_REGS
: class);
713 /* If x (the input) is a ybase register, restrict the class of registers
714 we can copy the register into. */
716 if (REG_P (x
) && !TARGET_RESERVE_YBASE
717 && IS_YBASE_REGISTER_WINDOW (REGNO(x
)))
722 case A0H_REG
: case A0L_REG
: case A0_REG
: case A1H_REG
:
723 case ACCUM_HIGH_REGS
: case A1L_REG
: case ACCUM_LOW_REGS
:
724 case A1_REG
: case ACCUM_REGS
: case X_REG
:
725 case X_OR_ACCUM_LOW_REGS
: case X_OR_ACCUM_REGS
:
726 case YH_REG
: case YH_OR_ACCUM_HIGH_REGS
:
727 case X_OR_YH_REGS
: case YL_REG
:
728 case YL_OR_ACCUM_LOW_REGS
: case X_OR_YL_REGS
:
729 case X_OR_Y_REGS
: case Y_REG
:
730 case ACCUM_OR_Y_REGS
: case PH_REG
:
731 case X_OR_PH_REGS
: case PL_REG
:
732 case PL_OR_ACCUM_LOW_REGS
: case X_OR_PL_REGS
:
733 case YL_OR_PL_OR_ACCUM_LOW_REGS
: case P_REG
:
734 case ACCUM_OR_P_REGS
: case YL_OR_P_REGS
:
735 case ACCUM_LOW_OR_YL_OR_P_REGS
: case Y_OR_P_REGS
:
736 case ACCUM_Y_OR_P_REGS
: case NO_FRAME_Y_ADDR_REGS
:
737 case Y_ADDR_REGS
: case ACCUM_LOW_OR_Y_ADDR_REGS
:
738 case ACCUM_OR_Y_ADDR_REGS
: case X_OR_Y_ADDR_REGS
:
739 case Y_OR_Y_ADDR_REGS
: case P_OR_Y_ADDR_REGS
:
740 case NON_HIGH_YBASE_ELIGIBLE_REGS
: case YBASE_ELIGIBLE_REGS
:
745 return (!reload_in_progress
? NO_REGS
: class);
747 case J_OR_DAU_16_BIT_REGS
:
748 return ACCUM_HIGH_REGS
;
751 case YBASE_VIRT_REGS
:
752 return (!reload_in_progress
? NO_REGS
: class);
754 case ACCUM_LOW_OR_YBASE_REGS
:
755 return ACCUM_LOW_REGS
;
757 case ACCUM_OR_YBASE_REGS
:
760 case X_OR_YBASE_REGS
:
763 case Y_OR_YBASE_REGS
:
766 case ACCUM_LOW_YL_PL_OR_YBASE_REGS
:
767 return YL_OR_PL_OR_ACCUM_LOW_REGS
;
769 case P_OR_YBASE_REGS
:
772 case ACCUM_Y_P_OR_YBASE_REGS
:
773 return ACCUM_Y_OR_P_REGS
;
775 case Y_ADDR_OR_YBASE_REGS
:
778 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS
:
779 return NON_HIGH_YBASE_ELIGIBLE_REGS
;
781 case YBASE_OR_YBASE_ELIGIBLE_REGS
:
782 return YBASE_ELIGIBLE_REGS
;
784 case NO_HIGH_ALL_REGS
:
785 return NON_HIGH_YBASE_ELIGIBLE_REGS
;
788 return YBASE_ELIGIBLE_REGS
;
790 case NOHIGH_NON_ADDR_REGS
:
791 return ACCUM_LOW_OR_YL_OR_P_REGS
;
794 return ACCUM_Y_OR_P_REGS
;
796 case SLOW_MEM_LOAD_REGS
:
797 return ACCUM_OR_Y_ADDR_REGS
;
799 case NOHIGH_NON_YBASE_REGS
:
800 return NON_HIGH_YBASE_ELIGIBLE_REGS
;
802 case NO_ACCUM_NON_YBASE_REGS
:
806 return YBASE_ELIGIBLE_REGS
;
810 if (GET_CODE (x
) == PLUS
)
812 if (GET_MODE (x
) == QImode
813 && REG_P (XEXP (x
,0))
814 && (XEXP (x
,0) == frame_pointer_rtx
815 || XEXP (x
,0) == stack_pointer_rtx
)
816 && (GET_CODE (XEXP (x
,1)) == CONST_INT
))
818 if (class == ACCUM_HIGH_REGS
)
821 /* If the accumulators are not part of the class
822 being reloaded into, return NO_REGS. */
824 if (!reg_class_subset_p (ACCUM_REGS
, class))
825 return (!reload_in_progress
? NO_REGS
: class);
827 if (reg_class_subset_p (ACCUM_HIGH_REGS
, class))
828 return ACCUM_HIGH_REGS
;
830 /* We will use accumulator 'a1l' for reloading a
831 PLUS. We can only use one accumulator because
832 'reload_inqi' only allows one alternative to be
835 else if (class == ACCUM_LOW_REGS
)
837 else if (class == A0L_REG
)
843 if (class == NON_YBASE_REGS
|| class == YBASE_ELIGIBLE_REGS
)
848 else if (GET_CODE (x
) == MEM
)
850 /* We can't copy from a memory location into a
852 if (reg_class_subset_p(YBASE_VIRT_REGS
, class))
856 case YBASE_VIRT_REGS
:
857 return (!reload_in_progress
? NO_REGS
: class);
859 case ACCUM_LOW_OR_YBASE_REGS
:
860 return ACCUM_LOW_REGS
;
862 case ACCUM_OR_YBASE_REGS
:
865 case X_OR_YBASE_REGS
:
868 case Y_OR_YBASE_REGS
:
871 case ACCUM_LOW_YL_PL_OR_YBASE_REGS
:
872 return YL_OR_PL_OR_ACCUM_LOW_REGS
;
874 case P_OR_YBASE_REGS
:
877 case ACCUM_Y_P_OR_YBASE_REGS
:
878 return ACCUM_Y_OR_P_REGS
;
880 case Y_ADDR_OR_YBASE_REGS
:
883 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS
:
884 return NON_HIGH_YBASE_ELIGIBLE_REGS
;
886 case YBASE_OR_YBASE_ELIGIBLE_REGS
:
887 return YBASE_ELIGIBLE_REGS
;
889 case NO_HIGH_ALL_REGS
:
890 return NOHIGH_NON_YBASE_REGS
;
893 return NON_YBASE_REGS
;
906 /* Return the register class of a scratch register needed to copy IN into
907 or out of a register in CLASS in MODE. If it can be done directly,
908 NO_REGS is returned. */
911 secondary_reload_class (class, mode
, in
)
912 enum reg_class
class;
913 enum machine_mode mode
;
918 if (GET_CODE (in
) == REG
|| GET_CODE (in
) == SUBREG
)
919 regno
= true_regnum (in
);
921 /* If we are reloading a plus into a high accumulator register,
922 we need a scratch low accumulator, because the low half gets
925 if (class == ACCUM_HIGH_REGS
929 if (GET_CODE (in
) == PLUS
&& mode
== QImode
)
930 return ACCUM_LOW_REGS
;
933 if (class == ACCUM_HIGH_REGS
934 || class == ACCUM_LOW_REGS
940 if (GET_CODE (in
) == PLUS
&& mode
== QImode
)
942 rtx addr0
= XEXP (in
, 0);
943 rtx addr1
= XEXP (in
, 1);
945 /* If we are reloading a plus (reg:QI) (reg:QI)
946 we need an additional register. */
947 if (REG_P (addr0
) && REG_P (addr1
))
952 /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
955 if ((class == ACCUM_REGS
|| class == ACCUM_HIGH_REGS
||
956 class == ACCUM_LOW_REGS
|| class == A0H_REG
|| class == A0L_REG
||
957 class == A1H_REG
|| class == A1_REG
) ||
958 (regno
>= REG_A0
&& regno
< REG_A1L
+ 1))
961 if (class == ACCUM_OR_YBASE_REGS
&& REG_P(in
)
962 && IS_YBASE_ELIGIBLE_REG(regno
))
967 /* We can copy the ybase registers into:
968 r0-r3, a0-a1, y, p, & x or the union of
971 if (!TARGET_RESERVE_YBASE
&& IS_YBASE_REGISTER_WINDOW(regno
))
976 case (int) X_OR_ACCUM_LOW_REGS
:
977 case (int) X_OR_ACCUM_REGS
:
979 case (int) YH_OR_ACCUM_HIGH_REGS
:
980 case (int) X_OR_YH_REGS
:
982 case (int) YL_OR_ACCUM_LOW_REGS
:
983 case (int) X_OR_Y_REGS
:
984 case (int) X_OR_YL_REGS
:
986 case (int) ACCUM_OR_Y_REGS
:
988 case (int) X_OR_PH_REGS
:
990 case (int) PL_OR_ACCUM_LOW_REGS
:
991 case (int) X_OR_PL_REGS
:
992 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS
:
994 case (int) ACCUM_OR_P_REGS
:
995 case (int) YL_OR_P_REGS
:
996 case (int) ACCUM_LOW_OR_YL_OR_P_REGS
:
997 case (int) Y_OR_P_REGS
:
998 case (int) ACCUM_Y_OR_P_REGS
:
999 case (int) Y_ADDR_REGS
:
1000 case (int) ACCUM_LOW_OR_Y_ADDR_REGS
:
1001 case (int) ACCUM_OR_Y_ADDR_REGS
:
1002 case (int) X_OR_Y_ADDR_REGS
:
1003 case (int) Y_OR_Y_ADDR_REGS
:
1004 case (int) P_OR_Y_ADDR_REGS
:
1005 case (int) YBASE_ELIGIBLE_REGS
:
1009 return ACCUM_HIGH_REGS
;
1013 /* We can copy r0-r3, a0-a1, y, & p
1014 directly to the ybase registers. In addition
1015 we can use any of the ybase virtual registers
1016 as the secondary reload registers when copying
1017 between any of these registers. */
1019 if (!TARGET_RESERVE_YBASE
&& regno
!= -1)
1036 if (class == YBASE_VIRT_REGS
)
1040 switch ((int) class)
1043 case (int) X_OR_ACCUM_LOW_REGS
:
1044 case (int) X_OR_ACCUM_REGS
:
1046 case (int) YH_OR_ACCUM_HIGH_REGS
:
1047 case (int) X_OR_YH_REGS
:
1049 case (int) YL_OR_ACCUM_LOW_REGS
:
1050 case (int) X_OR_Y_REGS
:
1051 case (int) X_OR_YL_REGS
:
1053 case (int) ACCUM_OR_Y_REGS
:
1055 case (int) X_OR_PH_REGS
:
1057 case (int) PL_OR_ACCUM_LOW_REGS
:
1058 case (int) X_OR_PL_REGS
:
1059 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS
:
1061 case (int) ACCUM_OR_P_REGS
:
1062 case (int) YL_OR_P_REGS
:
1063 case (int) ACCUM_LOW_OR_YL_OR_P_REGS
:
1064 case (int) Y_OR_P_REGS
:
1065 case (int) ACCUM_Y_OR_P_REGS
:
1066 case (int) Y_ADDR_REGS
:
1067 case (int) ACCUM_LOW_OR_Y_ADDR_REGS
:
1068 case (int) ACCUM_OR_Y_ADDR_REGS
:
1069 case (int) X_OR_Y_ADDR_REGS
:
1070 case (int) Y_OR_Y_ADDR_REGS
:
1071 case (int) P_OR_Y_ADDR_REGS
:
1072 case (int) YBASE_ELIGIBLE_REGS
:
1073 return YBASE_VIRT_REGS
;
1082 /* Memory or constants can be moved from or to any register
1083 except the ybase virtual registers. */
1084 if (regno
== -1 && GET_CODE(in
) != PLUS
)
1086 if (class == YBASE_VIRT_REGS
)
1087 return NON_YBASE_REGS
;
1092 if (GET_CODE (in
) == PLUS
&& mode
== QImode
)
1094 rtx addr0
= XEXP (in
, 0);
1095 rtx addr1
= XEXP (in
, 1);
1097 /* If we are reloading a plus (reg:QI) (reg:QI)
1098 we need a low accumulator, not a high one. */
1099 if (REG_P (addr0
) && REG_P (addr1
))
1100 return ACCUM_LOW_REGS
;
1108 /* Otherwise, we need a high accumulator(s). */
1109 return ACCUM_HIGH_REGS
;
1113 symbolic_address_operand (op
, mode
)
1115 enum machine_mode mode ATTRIBUTE_UNUSED
;
1117 return (symbolic_address_p (op
));
1121 symbolic_address_p (op
)
1124 switch (GET_CODE (op
))
1132 return ((GET_CODE (XEXP (op
, 0)) == SYMBOL_REF
1133 || GET_CODE (XEXP (op
, 0)) == LABEL_REF
)
1134 && GET_CODE (XEXP (op
, 1)) == CONST_INT
1135 && INTVAL (XEXP (op
,1)) < 0x20);
1142 /* For a Y address space operand we allow only *rn, *rn++, *rn--.
1143 This routine only recognizes *rn, the '<>' constraints recognize
1144 (*rn++), and (*rn--). */
1147 Y_address_operand (op
, mode
)
1149 enum machine_mode mode
;
1151 return (memory_address_p (mode
, op
) && !symbolic_address_p (op
));
1155 sp_operand (op
, mode
)
1157 enum machine_mode mode ATTRIBUTE_UNUSED
;
1159 return (GET_CODE (op
) == PLUS
1160 && (XEXP (op
, 0) == stack_pointer_rtx
1161 || XEXP (op
, 0) == frame_pointer_rtx
)
1162 && GET_CODE (XEXP (op
,1)) == CONST_INT
);
1166 sp_operand2 (op
, mode
)
1168 enum machine_mode mode ATTRIBUTE_UNUSED
;
1170 if ((GET_CODE (op
) == PLUS
1171 && (XEXP (op
, 0) == stack_pointer_rtx
1172 || XEXP (op
, 0) == frame_pointer_rtx
)
1173 && (REG_P (XEXP (op
,1))
1174 && IS_ADDRESS_REGISTER (REGNO (XEXP(op
, 1))))))
1176 else if ((GET_CODE (op
) == PLUS
1177 && (XEXP (op
, 1) == stack_pointer_rtx
1178 || XEXP (op
, 1) == frame_pointer_rtx
)
1179 && (REG_P (XEXP (op
,0))
1180 && IS_ADDRESS_REGISTER (REGNO (XEXP(op
, 1))))))
1187 nonmemory_arith_operand (op
, mode
)
1189 enum machine_mode mode
;
1191 return (immediate_operand (op
, mode
) || arith_reg_operand (op
, mode
));
1195 arith_reg_operand (op
, mode
)
1197 enum machine_mode mode
;
1199 return (register_operand (op
, mode
)
1200 && (GET_CODE (op
) != REG
1201 || REGNO (op
) >= FIRST_PSEUDO_REGISTER
1202 || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op
)))
1203 && REGNO (op
) != FRAME_POINTER_REGNUM
)));
1207 call_address_operand (op
, mode
)
1209 enum machine_mode mode ATTRIBUTE_UNUSED
;
1211 if (symbolic_address_p (op
) || REG_P(op
))
1220 dsp16xx_comparison_operator (op
, mode
)
1222 enum machine_mode mode
;
1224 return ((mode
== VOIDmode
|| GET_MODE (op
) == mode
)
1225 && GET_RTX_CLASS (GET_CODE (op
)) == '<'
1226 && (GET_CODE(op
) != GE
&& GET_CODE (op
) != LT
&&
1227 GET_CODE (op
) != GEU
&& GET_CODE (op
) != LTU
));
1231 notice_update_cc(exp
)
1234 if (GET_CODE (exp
) == SET
)
1236 /* Jumps do not alter the cc's. */
1238 if (SET_DEST (exp
) == pc_rtx
)
1241 /* Moving register or memory into a register:
1242 it doesn't alter the cc's, but it might invalidate
1243 the RTX's which we remember the cc's came from.
1244 (Note that moving a constant 0 or 1 MAY set the cc's). */
1245 if (REG_P (SET_DEST (exp
))
1246 && (REG_P (SET_SRC (exp
)) || GET_CODE (SET_SRC (exp
)) == MEM
))
1248 if (cc_status
.value1
1249 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value1
))
1250 cc_status
.value1
= 0;
1251 if (cc_status
.value2
1252 && reg_overlap_mentioned_p (SET_DEST (exp
), cc_status
.value2
))
1253 cc_status
.value2
= 0;
1256 /* Moving register into memory doesn't alter the cc's.
1257 It may invalidate the RTX's which we remember the cc's came from. */
1258 if (GET_CODE (SET_DEST (exp
)) == MEM
&& REG_P (SET_SRC (exp
)))
1260 if (cc_status
.value1
&& GET_CODE (cc_status
.value1
) == MEM
)
1261 cc_status
.value1
= 0;
1262 if (cc_status
.value2
&& GET_CODE (cc_status
.value2
) == MEM
)
1263 cc_status
.value2
= 0;
1266 /* Function calls clobber the cc's. */
1267 else if (GET_CODE (SET_SRC (exp
)) == CALL
)
1272 /* Tests and compares set the cc's in predictable ways. */
1273 else if (SET_DEST (exp
) == cc0_rtx
)
1276 cc_status
.value1
= SET_SRC (exp
);
1279 /* Certain instructions effect the condition codes. */
1280 else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp
))) == MODE_INT
)
1281 switch (GET_CODE (SET_SRC (exp
)))
1285 if (REG_P (SET_DEST (exp
)))
1287 /* Address registers don't set the condition codes. */
1288 if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp
))))
1303 cc_status
.value1
= SET_SRC (exp
);
1304 cc_status
.value2
= SET_DEST (exp
);
1315 else if (GET_CODE (exp
) == PARALLEL
1316 && GET_CODE (XVECEXP (exp
, 0, 0)) == SET
)
1318 if (SET_DEST (XVECEXP (exp
, 0, 0)) == pc_rtx
)
1321 if (SET_DEST (XVECEXP (exp
, 0, 0)) == cc0_rtx
)
1324 cc_status
.value1
= SET_SRC (XVECEXP (exp
, 0, 0));
1337 dsp16xx_makes_calls ()
1341 for (insn
= get_insns (); insn
; insn
= next_insn (insn
))
1342 if (GET_CODE (insn
) == CALL_INSN
)
1349 compute_frame_size (size
)
1358 /* This value is needed to compute reg_size. */
1359 current_frame_info
.function_makes_calls
= !leaf_function_p ();
1364 args_size
= current_function_outgoing_args_size
;
1365 reg_size
= reg_save_size ();
1367 total_size
= var_size
+ args_size
+ extra_size
+ reg_size
;
1370 /* Save other computed information. */
1371 current_frame_info
.total_size
= total_size
;
1372 current_frame_info
.var_size
= var_size
;
1373 current_frame_info
.args_size
= args_size
;
1374 current_frame_info
.extra_size
= extra_size
;
1375 current_frame_info
.reg_size
= reg_size
;
1376 current_frame_info
.initialized
= reload_completed
;
1377 current_frame_info
.reg_size
= reg_size
/ UNITS_PER_WORD
;
1381 unsigned long offset
= args_size
+ var_size
+ reg_size
;
1382 current_frame_info
.sp_save_offset
= offset
;
1383 current_frame_info
.fp_save_offset
= offset
- total_size
;
1390 dsp16xx_call_saved_register (regno
)
1394 if (regno
== REG_PR
&& current_frame_info
.function_makes_calls
)
1397 return (regs_ever_live
[regno
] && !call_used_regs
[regno
] &&
1398 !IS_YBASE_REGISTER_WINDOW(regno
));
1402 ybase_regs_ever_used ()
1407 for (regno
= REG_YBASE0
; regno
<= REG_YBASE31
; regno
++)
1408 if (regs_ever_live
[regno
])
1418 dsp16xx_output_function_prologue (file
, size
)
1424 fp
= reg_names
[FRAME_POINTER_REGNUM
];
1425 sp
= reg_names
[STACK_POINTER_REGNUM
];
1426 rr
= reg_names
[RETURN_ADDRESS_REGNUM
]; /* return address register */
1427 a1h
= reg_names
[REG_A1
];
1429 total_size
= compute_frame_size (size
);
1431 fprintf (file
, "\t/* FUNCTION PROLOGUE: */\n");
1432 fprintf (file
, "\t/* total=%ld, vars= %ld, regs= %d, args=%d, extra= %ld */\n",
1433 current_frame_info
.total_size
,
1434 current_frame_info
.var_size
,
1435 current_frame_info
.reg_size
,
1436 current_function_outgoing_args_size
,
1437 current_frame_info
.extra_size
);
1439 fprintf (file
, "\t/* fp save offset= %ld, sp save_offset= %ld */\n\n",
1440 current_frame_info
.fp_save_offset
,
1441 current_frame_info
.sp_save_offset
);
1442 /* Set up the 'ybase' register window. */
1444 if (ybase_regs_ever_used())
1446 fprintf (file
, "\t%s=%s\n", a1h
, reg_names
[REG_YBASE
]);
1447 if (TARGET_YBASE_HIGH
)
1448 fprintf (file
, "\t%s=%sh-32\n", reg_names
[REG_A1
], a1h
);
1450 fprintf (file
, "\t%s=%sh+32\n", reg_names
[REG_A1
], a1h
);
1451 fprintf (file
, "\t%s=%s\n", reg_names
[REG_YBASE
], a1h
);
1454 if (current_frame_info
.var_size
)
1456 if (current_frame_info
.var_size
== 1)
1457 fprintf (file
, "\t*%s++\n", sp
);
1460 if (SMALL_INTVAL(current_frame_info
.var_size
) && ((current_frame_info
.var_size
& 0x8000) == 0))
1461 fprintf (file
, "\t%s=%ld\n\t*%s++%s\n", reg_names
[REG_J
], current_frame_info
.var_size
, sp
, reg_names
[REG_J
]);
1463 fatal_error ("stack size > 32k");
1467 /* Save any registers this function uses, unless they are
1468 used in a call, in which case we don't need to. */
1470 for(regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; ++ regno
)
1471 if (dsp16xx_call_saved_register (regno
))
1473 fprintf (file
, "\tpush(*%s)=%s\n", sp
, reg_names
[regno
]);
1476 /* For debugging purposes, we want the return address to be at a predictable
1478 if (current_frame_info
.function_makes_calls
)
1479 fprintf (file
, "\tpush(*%s)=%s\n", sp
, reg_names
[RETURN_ADDRESS_REGNUM
]);
1481 if (current_frame_info
.args_size
)
1483 if (current_frame_info
.args_size
== 1)
1484 fprintf (file
, "\t*%s++\n", sp
);
1486 error ("stack size > 32k");
1489 if (frame_pointer_needed
)
1491 fprintf (file
, "\t%s=%s\n", a1h
, sp
);
1492 fprintf (file
, "\t%s=%s\n", fp
, a1h
); /* Establish new base frame */
1493 fprintf (file
, "\t%s=%ld\n", reg_names
[REG_J
], -total_size
);
1494 fprintf (file
, "\t*%s++%s\n", fp
, reg_names
[REG_J
]);
1497 fprintf (file
, "\t/* END FUNCTION PROLOGUE: */\n\n");
1501 init_emulation_routines ()
1503 dsp16xx_addhf3_libcall
= (rtx
) 0;
1504 dsp16xx_subhf3_libcall
= (rtx
) 0;
1505 dsp16xx_mulhf3_libcall
= (rtx
) 0;
1506 dsp16xx_divhf3_libcall
= (rtx
) 0;
1507 dsp16xx_cmphf3_libcall
= (rtx
) 0;
1508 dsp16xx_fixhfhi2_libcall
= (rtx
) 0;
1509 dsp16xx_floathihf2_libcall
= (rtx
) 0;
1510 dsp16xx_neghf2_libcall
= (rtx
) 0;
1512 dsp16xx_mulhi3_libcall
= (rtx
) 0;
1513 dsp16xx_udivqi3_libcall
= (rtx
) 0;
1514 dsp16xx_udivhi3_libcall
= (rtx
) 0;
1515 dsp16xx_divqi3_libcall
= (rtx
) 0;
1516 dsp16xx_divhi3_libcall
= (rtx
) 0;
1517 dsp16xx_modqi3_libcall
= (rtx
) 0;
1518 dsp16xx_modhi3_libcall
= (rtx
) 0;
1519 dsp16xx_umodqi3_libcall
= (rtx
) 0;
1520 dsp16xx_umodhi3_libcall
= (rtx
) 0;
1521 dsp16xx_ashrhi3_libcall
= (rtx
) 0;
1522 dsp16xx_ashlhi3_libcall
= (rtx
) 0;
1523 dsp16xx_ucmphi2_libcall
= (rtx
) 0;
1524 dsp16xx_lshrhi3_libcall
= (rtx
) 0;
1528 dsp16xx_output_function_epilogue (file
, size
)
1530 HOST_WIDE_INT size ATTRIBUTE_UNUSED
;
1534 fp
= reg_names
[FRAME_POINTER_REGNUM
];
1535 sp
= reg_names
[STACK_POINTER_REGNUM
];
1536 rr
= reg_names
[RETURN_ADDRESS_REGNUM
]; /* return address register */
1537 a1h
= reg_names
[REG_A1
];
1539 fprintf (file
, "\n\t/* FUNCTION EPILOGUE: */\n");
1541 if (current_frame_info
.args_size
)
1543 if (current_frame_info
.args_size
== 1)
1544 fprintf (file
, "\t*%s--\n", sp
);
1547 fprintf (file
, "\t%s=%ld\n\t*%s++%s\n",
1548 reg_names
[REG_J
], -current_frame_info
.args_size
, sp
, reg_names
[REG_J
]);
1552 if (ybase_regs_ever_used())
1554 fprintf (file
, "\t%s=%s\n", a1h
, reg_names
[REG_YBASE
]);
1555 if (TARGET_YBASE_HIGH
)
1556 fprintf (file
, "\t%s=%sh+32\n", reg_names
[REG_A1
], a1h
);
1558 fprintf (file
, "\t%s=%sh-32\n", reg_names
[REG_A1
], a1h
);
1559 fprintf (file
, "\t%s=%s\n", reg_names
[REG_YBASE
], a1h
);
1562 if (current_frame_info
.function_makes_calls
)
1563 fprintf (file
, "\t%s=pop(*%s)\n", reg_names
[RETURN_ADDRESS_REGNUM
], sp
);
1565 for (regno
= FIRST_PSEUDO_REGISTER
- 1; regno
>= 0; --regno
)
1566 if (dsp16xx_call_saved_register(regno
))
1568 fprintf (file
, "\t%s=pop(*%s)\n", reg_names
[regno
], sp
);
1571 if (current_frame_info
.var_size
)
1573 if (current_frame_info
.var_size
== 1)
1574 fprintf (file
, "\t*%s--\n", sp
);
1577 fprintf (file
, "\t%s=%ld\n\t*%s++%s\n",
1578 reg_names
[REG_J
], -current_frame_info
.var_size
, sp
, reg_names
[REG_J
]);
1582 fprintf (file
, "\treturn\n");
1583 /* Reset the frame info for the next function. */
1584 current_frame_info
= zero_frame_info
;
1585 init_emulation_routines ();
1588 /* Emit insns to move operands[1] into operands[0].
1590 Return 1 if we have written out everything that needs to be done to
1591 do the move. Otherwise, return 0 and the caller will emit the move
1595 emit_move_sequence (operands
, mode
)
1597 enum machine_mode mode
;
1599 register rtx operand0
= operands
[0];
1600 register rtx operand1
= operands
[1];
1602 /* We can only store registers to memory. */
1604 if (GET_CODE (operand0
) == MEM
&& GET_CODE (operand1
) != REG
)
1605 operands
[1] = force_reg (mode
, operand1
);
1611 double_reg_from_memory (operands
)
1616 if (GET_CODE(XEXP(operands
[1],0)) == POST_INC
)
1618 output_asm_insn ("%u0=%1", operands
);
1619 output_asm_insn ("%w0=%1", operands
);
1621 else if (GET_CODE(XEXP(operands
[1],0)) == POST_DEC
)
1623 xoperands
[1] = XEXP (XEXP (operands
[1], 0), 0);
1624 xoperands
[0] = operands
[0];
1626 /* We can't use j anymore since the compiler can allocate it. */
1627 /* output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */
1628 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands
);
1630 else if (GET_CODE(XEXP(operands
[1],0)) == PLUS
)
1635 output_asm_insn ("%u0=%1", operands
);
1638 /* In order to print out the least significant word we must
1639 use 'offset + 1'. */
1640 addr
= XEXP (operands
[1], 0);
1641 if (GET_CODE (XEXP(addr
,0)) == CONST_INT
)
1642 offset
= INTVAL(XEXP(addr
,0)) + 1;
1643 else if (GET_CODE (XEXP(addr
,1)) == CONST_INT
)
1644 offset
= INTVAL(XEXP(addr
,1)) + 1;
1646 fprintf (asm_out_file
, "\t%s=*(%d)\n", reg_names
[REGNO(operands
[0]) + 1], offset
+ 31);
1650 xoperands
[1] = XEXP(operands
[1],0);
1651 xoperands
[0] = operands
[0];
1653 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands
);
1659 double_reg_to_memory (operands
)
1664 if (GET_CODE(XEXP(operands
[0],0)) == POST_INC
)
1666 output_asm_insn ("%0=%u1", operands
);
1667 output_asm_insn ("%0=%w1", operands
);
1669 else if (GET_CODE(XEXP(operands
[0],0)) == POST_DEC
)
1671 xoperands
[0] = XEXP (XEXP (operands
[0], 0), 0);
1672 xoperands
[1] = operands
[1];
1674 /* We can't use j anymore since the compiler can allocate it. */
1676 /* output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */
1677 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands
);
1680 else if (GET_CODE(XEXP(operands
[0],0)) == PLUS
)
1685 output_asm_insn ("%0=%u1", operands
);
1687 /* In order to print out the least significant word we must
1688 use 'offset + 1'. */
1689 addr
= XEXP (operands
[0], 0);
1690 if (GET_CODE (XEXP(addr
,0)) == CONST_INT
)
1691 offset
= INTVAL(XEXP(addr
,0)) + 1;
1692 else if (GET_CODE (XEXP(addr
,1)) == CONST_INT
)
1693 offset
= INTVAL(XEXP(addr
,1)) + 1;
1695 fatal_error ("invalid addressing mode");
1697 fprintf (asm_out_file
, "\t*(%d)=%s\n", offset
+ 31, reg_names
[REGNO(operands
[1]) + 1]);
1701 xoperands
[0] = XEXP(operands
[0],0);
1702 xoperands
[1] = operands
[1];
1704 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands
);
1711 if (chip_name
== (char *) 0)
1712 chip_name
= DEFAULT_CHIP_NAME
;
1714 if (text_seg_name
== (char *) 0)
1715 text_seg_name
= DEFAULT_TEXT_SEG_NAME
;
1717 if (data_seg_name
== (char *) 0)
1718 data_seg_name
= DEFAULT_DATA_SEG_NAME
;
1720 if (bss_seg_name
== (char *) 0)
1721 bss_seg_name
= DEFAULT_BSS_SEG_NAME
;
1723 if (const_seg_name
== (char *) 0)
1724 const_seg_name
= DEFAULT_CONST_SEG_NAME
;
1726 save_chip_name
= xstrdup (chip_name
);
1728 rsect_text
= concat (".rsect \"", text_seg_name
, "\"", NULL
);
1729 rsect_data
= concat (".rsect \"", data_seg_name
, "\"", NULL
);
1730 rsect_bss
= concat (".rsect \"", bss_seg_name
, "\"", NULL
);
1731 rsect_const
= concat (".rsect \"", const_seg_name
, "\"", NULL
);
1735 next_cc_user_unsigned (insn
)
1738 switch (next_cc_user_code (insn
))
1751 next_cc_user_code (insn
)
1754 /* If no insn could be found we assume that the jump has been
1755 deleted and the compare will be deleted later. */
1757 if (!(insn
= next_cc0_user (insn
)))
1758 return (enum rtx_code
) 0;
1759 else if (GET_CODE (insn
) == JUMP_INSN
1760 && GET_CODE (PATTERN (insn
)) == SET
1761 && GET_CODE (SET_SRC (PATTERN (insn
))) == IF_THEN_ELSE
)
1762 return GET_CODE (XEXP (SET_SRC (PATTERN (insn
)), 0));
1763 else if (GET_CODE (insn
) == INSN
1764 && GET_CODE (PATTERN (insn
)) == SET
1765 && comparison_operator (SET_SRC (PATTERN (insn
)), VOIDmode
))
1766 return GET_CODE (SET_SRC (PATTERN (insn
)));
1772 print_operand(file
, op
, letter
)
1779 code
= GET_CODE(op
);
1784 code
= reverse_condition (code
);
1793 else if (code
== NE
)
1798 else if (code
== GT
|| code
== GTU
)
1803 else if (code
== LT
|| code
== LTU
)
1808 else if (code
== GE
|| code
== GEU
)
1813 else if (code
== LE
|| code
== LEU
)
1828 /* Print the low half of a 32-bit register pair. */
1830 fprintf (file
, "%s", reg_names
[REGNO (op
) + 1]);
1831 else if (letter
== 'u' || !letter
)
1832 fprintf (file
, "%s", reg_names
[REGNO (op
)]);
1833 else if (letter
== 'b')
1834 fprintf (file
, "%sh", reg_names
[REGNO (op
)]);
1835 else if (letter
== 'm')
1836 fprintf (file
, "%s", himode_reg_name
[REGNO (op
)]);
1838 output_operand_lossage ("bad register extension code");
1840 else if (code
== MEM
)
1841 output_address (XEXP(op
,0));
1842 else if (code
== CONST_INT
)
1844 HOST_WIDE_INT val
= INTVAL (op
);
1847 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, val
& 0xffff);
1848 else if (letter
== 'h')
1849 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, val
);
1850 else if (letter
== 'U')
1851 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, (val
>> 16) & 0xffff);
1853 output_addr_const(file
, op
);
1855 else if (code
== CONST_DOUBLE
&& GET_MODE(op
) != DImode
)
1859 REAL_VALUE_FROM_CONST_DOUBLE (r
, op
);
1860 REAL_VALUE_TO_TARGET_SINGLE (r
, l
);
1861 fprintf (file
, "0x%lx", l
);
1863 else if (code
== CONST
)
1865 rtx addr
= XEXP (op
, 0);
1867 if (GET_CODE (addr
) != PLUS
)
1869 output_addr_const(file
, op
);
1873 if ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
1874 || GET_CODE (XEXP (addr
, 0)) == LABEL_REF
)
1875 && (GET_CODE (XEXP (addr
, 1)) == CONST_INT
))
1877 int n
= INTVAL (XEXP(addr
, 1));
1878 output_addr_const (file
, XEXP (addr
, 0));
1881 fprintf (file
, "+");
1883 n
= (int) (short) n
;
1884 fprintf (file
, "%d", n
);
1886 else if ((GET_CODE (XEXP (addr
, 1)) == SYMBOL_REF
1887 || GET_CODE (XEXP (addr
, 1)) == LABEL_REF
)
1888 && (GET_CODE (XEXP (addr
, 0)) == CONST_INT
))
1890 int n
= INTVAL (XEXP(addr
, 0));
1891 output_addr_const (file
, XEXP (addr
, 1));
1894 fprintf (file
, "+");
1896 n
= (int) (short) n
;
1897 fprintf (file
, "%d", n
);
1900 output_addr_const(file
, op
);
1903 output_addr_const (file
, op
);
1908 print_operand_address(file
, addr
)
1915 switch (GET_CODE (addr
))
1918 fprintf (file
, "*%s", reg_names
[REGNO (addr
)]);
1921 fprintf (file
, "*%s--", reg_names
[REGNO (XEXP (addr
, 0))]);
1924 fprintf (file
, "*%s++", reg_names
[REGNO (XEXP (addr
, 0))]);
1927 if (GET_CODE (XEXP(addr
,0)) == CONST_INT
)
1928 offset
= INTVAL(XEXP(addr
,0)), base
= XEXP(addr
,1);
1929 else if (GET_CODE (XEXP(addr
,1)) == CONST_INT
)
1930 offset
= INTVAL(XEXP(addr
,1)), base
= XEXP(addr
,0);
1933 if (GET_CODE (base
) == REG
&& REGNO(base
) == STACK_POINTER_REGNUM
)
1935 if (offset
>= -31 && offset
<= 0)
1936 offset
= 31 + offset
;
1938 fatal_error ("invalid offset in ybase addressing");
1941 fatal_error ("invalid register in ybase addressing");
1943 fprintf (file
, "*(%d)", offset
);
1947 if (FITS_5_BITS (addr
))
1948 fprintf (file
, "*(0x%x)", (int)(INTVAL (addr
) & 0x20));
1950 output_addr_const (file
, addr
);
1955 output_dsp16xx_float_const (operands
)
1958 rtx src
= operands
[1];
1963 REAL_VALUE_FROM_CONST_DOUBLE (d
, src
);
1964 REAL_VALUE_TO_TARGET_SINGLE (d
, value
);
1966 operands
[1] = GEN_INT (value
);
1967 output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands
);
1973 int reg_save_size
= 0;
1976 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1977 if (dsp16xx_call_saved_register (regno
))
1979 reg_save_size
+= UNITS_PER_WORD
;
1982 /* If the function makes calls we will save need to save the 'pr' register. */
1983 if (current_frame_info
.function_makes_calls
)
1986 return (reg_save_size
);
1991 dsp16xx_starting_frame_offset()
1993 int reg_save_size
= 0;
1996 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1997 if (dsp16xx_call_saved_register (regno
))
1999 reg_save_size
+= UNITS_PER_WORD
;
2002 return (reg_save_size
);
2007 initial_frame_pointer_offset()
2011 offset
= compute_frame_size (get_frame_size());
2013 #ifdef STACK_GROWS_DOWNWARD
2020 /* Generate the minimum number of 1600 core shift instructions
2021 to shift by 'shift_amount'. */
2025 emit_1600_core_shift (shift_op
, operands
, shift_amount
, mode
)
2026 enum rtx_code shift_op
;
2029 enum machine_mode mode
;
2033 int first_shift_emitted
= 0;
2035 while (shift_amount
!= 0)
2037 if (shift_amount
/16)
2039 quotient
= shift_amount
/16;
2040 shift_amount
= shift_amount
- (quotient
* 16);
2041 for (i
= 0; i
< quotient
; i
++)
2042 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0],
2043 gen_rtx (shift_op
, mode
,
2045 ? operands
[0] : operands
[1],
2047 first_shift_emitted
= 1;
2049 else if (shift_amount
/8)
2051 quotient
= shift_amount
/8;
2052 shift_amount
= shift_amount
- (quotient
* 8);
2053 for (i
= 0; i
< quotient
; i
++)
2054 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0],
2055 gen_rtx (shift_op
, mode
,
2057 ? operands
[0] : operands
[1],
2059 first_shift_emitted
= 1;
2061 else if (shift_amount
/4)
2063 quotient
= shift_amount
/4;
2064 shift_amount
= shift_amount
- (quotient
* 4);
2065 for (i
= 0; i
< quotient
; i
++)
2066 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0],
2067 gen_rtx (shift_op
, mode
,
2069 ? operands
[0] : operands
[1],
2071 first_shift_emitted
= 1;
2073 else if (shift_amount
/1)
2075 quotient
= shift_amount
/1;
2076 shift_amount
= shift_amount
- (quotient
* 1);
2077 for (i
= 0; i
< quotient
; i
++)
2078 emit_insn (gen_rtx_SET (VOIDmode
, operands
[0],
2079 gen_rtx (shift_op
, mode
,
2081 ? operands
[0] : operands
[1],
2083 first_shift_emitted
= 1;
2089 emit_1600_core_shift (shift_op
, operands
, shift_amount
)
2090 enum rtx_code shift_op
;
2096 int first_shift_emitted
= 0;
2097 const char * const *shift_asm_ptr
;
2098 const char * const *shift_asm_ptr_first
;
2100 if (shift_op
== ASHIFT
)
2102 shift_asm_ptr
= ashift_left_asm
;
2103 shift_asm_ptr_first
= ashift_left_asm_first
;
2105 else if (shift_op
== ASHIFTRT
)
2107 shift_asm_ptr
= ashift_right_asm
;
2108 shift_asm_ptr_first
= ashift_right_asm_first
;
2110 else if (shift_op
== LSHIFTRT
)
2112 shift_asm_ptr
= lshift_right_asm
;
2113 shift_asm_ptr_first
= lshift_right_asm_first
;
2116 fatal_error ("invalid shift operator in emit_1600_core_shift");
2118 while (shift_amount
!= 0)
2120 if (shift_amount
/16)
2122 quotient
= shift_amount
/16;
2123 shift_amount
= shift_amount
- (quotient
* 16);
2124 for (i
= 0; i
< quotient
; i
++)
2125 output_asm_insn ((first_shift_emitted
? shift_asm_ptr
[SHIFT_INDEX_16
]
2126 : shift_asm_ptr_first
[SHIFT_INDEX_16
]), operands
);
2127 first_shift_emitted
= 1;
2129 else if (shift_amount
/8)
2131 quotient
= shift_amount
/8;
2132 shift_amount
= shift_amount
- (quotient
* 8);
2133 for (i
= 0; i
< quotient
; i
++)
2134 output_asm_insn ((first_shift_emitted
? shift_asm_ptr
[SHIFT_INDEX_8
]
2135 : shift_asm_ptr_first
[SHIFT_INDEX_8
]), operands
);
2136 first_shift_emitted
= 1;
2138 else if (shift_amount
/4)
2140 quotient
= shift_amount
/4;
2141 shift_amount
= shift_amount
- (quotient
* 4);
2142 for (i
= 0; i
< quotient
; i
++)
2143 output_asm_insn ((first_shift_emitted
? shift_asm_ptr
[SHIFT_INDEX_4
]
2144 : shift_asm_ptr_first
[SHIFT_INDEX_4
]), operands
);
2145 first_shift_emitted
= 1;
2147 else if (shift_amount
/1)
2149 quotient
= shift_amount
/1;
2150 shift_amount
= shift_amount
- (quotient
* 1);
2151 for (i
= 0; i
< quotient
; i
++)
2152 output_asm_insn ((first_shift_emitted
? shift_asm_ptr
[SHIFT_INDEX_1
]
2153 : shift_asm_ptr_first
[SHIFT_INDEX_1
]), operands
);
2154 first_shift_emitted
= 1;
2161 num_1600_core_shifts (shift_amount
)
2166 int first_shift_emitted
= 0;
2169 while (shift_amount
!= 0)
2171 if (shift_amount
/16)
2173 quotient
= shift_amount
/16;
2174 shift_amount
= shift_amount
- (quotient
* 16);
2175 for (i
= 0; i
< quotient
; i
++)
2177 first_shift_emitted
= 1;
2179 else if (shift_amount
/8)
2181 quotient
= shift_amount
/8;
2182 shift_amount
= shift_amount
- (quotient
* 8);
2183 for (i
= 0; i
< quotient
; i
++)
2186 first_shift_emitted
= 1;
2188 else if (shift_amount
/4)
2190 quotient
= shift_amount
/4;
2191 shift_amount
= shift_amount
- (quotient
* 4);
2192 for (i
= 0; i
< quotient
; i
++)
2195 first_shift_emitted
= 1;
2197 else if (shift_amount
/1)
2199 quotient
= shift_amount
/1;
2200 shift_amount
= shift_amount
- (quotient
* 1);
2201 for (i
= 0; i
< quotient
; i
++)
2204 first_shift_emitted
= 1;
2211 asm_output_common(file
, name
, size
, rounded
)
2214 int size ATTRIBUTE_UNUSED
;
2218 (*targetm
.asm_out
.globalize_label
) (file
, name
);
2219 assemble_name (file
, name
);
2222 fprintf (file
, "%d * int\n", rounded
);
2224 fprintf (file
, "int\n");
2228 asm_output_local(file
, name
, size
, rounded
)
2231 int size ATTRIBUTE_UNUSED
;
2235 assemble_name (file
, name
);
2238 fprintf (file
, "%d * int\n", rounded
);
2240 fprintf (file
, "int\n");
2244 dsp16xx_address_cost (addr
)
2247 switch (GET_CODE (addr
))
2257 rtx offset
= const0_rtx
;
2258 addr
= eliminate_constant_term (addr
, &offset
);
2260 if (GET_CODE (addr
) == LABEL_REF
)
2263 if (GET_CODE (addr
) != SYMBOL_REF
)
2266 if (INTVAL (offset
) == 0)
2271 case POST_INC
: case POST_DEC
:
2272 return (GET_MODE (addr
) == QImode
? 1 : 2);
2274 case SYMBOL_REF
: case LABEL_REF
:
2279 register rtx plus0
= XEXP (addr
, 0);
2280 register rtx plus1
= XEXP (addr
, 1);
2282 if (GET_CODE (plus0
) != REG
&& GET_CODE (plus1
) == REG
)
2284 plus0
= XEXP (addr
, 1);
2285 plus1
= XEXP (addr
, 0);
2288 if (GET_CODE (plus0
) != REG
)
2291 switch (GET_CODE (plus1
))
2302 return dsp16xx_address_cost (plus1
) + 1;
2311 /* Determine whether a function argument is passed in a register, and
2314 The arguments are CUM, which summarizes all the previous
2315 arguments; MODE, the machine mode of the argument; TYPE,
2316 the data type of the argument as a tree node or 0 if that is not known
2317 (which happens for C support library functions); and NAMED,
2318 which is 1 for an ordinary argument and 0 for nameless arguments that
2319 correspond to `...' in the called function's prototype.
2321 The value of the expression should either be a `reg' RTX for the
2322 hard register in which to pass the argument, or zero to pass the
2323 argument on the stack.
2325 On the dsp1610 the first four words of args are normally in registers
2326 and the rest are pushed. If we a long or on float mode, the argument
2327 must begin on an even register boundary
2329 Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2330 For structures that are passed in memory, but could have been
2331 passed in registers, we first load the structure into the
2332 register, and then when the last argument is passed, we store
2333 the registers into the stack locations. This fixes some bugs
2334 where GCC did not expect to have register arguments, followed. */
2337 dsp16xx_function_arg (args_so_far
, mode
, type
, named
)
2338 CUMULATIVE_ARGS args_so_far
;
2339 enum machine_mode mode
;
2345 if ((args_so_far
& 1) != 0
2346 && (mode
== HImode
|| GET_MODE_CLASS(mode
) == MODE_FLOAT
))
2349 if (type
== void_type_node
)
2350 return (struct rtx_def
*) 0;
2352 if (named
&& args_so_far
< 4 && !MUST_PASS_IN_STACK (mode
,type
))
2353 return gen_rtx_REG (mode
, args_so_far
+ FIRST_REG_FOR_FUNCTION_ARG
);
2355 return (struct rtx_def
*) 0;
2358 return (struct rtx_def
*) 0;
2361 /* Advance the argument to the next argument position. */
2364 dsp16xx_function_arg_advance (cum
, mode
, type
, named
)
2365 CUMULATIVE_ARGS
*cum
; /* current arg information */
2366 enum machine_mode mode
; /* current arg mode */
2367 tree type
; /* type of the argument or 0 if lib support */
2368 int named ATTRIBUTE_UNUSED
;/* whether or not the argument was named */
2373 && (mode
== HImode
|| GET_MODE_CLASS(mode
) == MODE_FLOAT
))
2376 if (mode
!= BLKmode
)
2377 *cum
+= GET_MODE_SIZE (mode
);
2379 *cum
+= int_size_in_bytes (type
);
2384 dsp16xx_file_start ()
2386 fprintf (asm_out_file
, "#include <%s.h>\n", save_chip_name
);
2393 enum machine_mode mode
;
2395 mode
= GET_MODE (x
);
2398 emit_insn (gen_rtx_PARALLEL
2400 gen_rtvec (2, gen_rtx_SET (VOIDmode
, cc0_rtx
, x
),
2401 gen_rtx_CLOBBER (VOIDmode
,
2402 gen_rtx_SCRATCH (QImode
)))));
2403 else if (mode
== HImode
)
2404 emit_insn (gen_rtx_SET (VOIDmode
, cc0_rtx
, x
));
2406 fatal_error ("invalid mode for gen_tst_reg");
2412 gen_compare_reg (code
, x
, y
)
2416 enum machine_mode mode
;
2418 mode
= GET_MODE (x
);
2419 /* For floating point compare insns, a call is generated so don't
2420 do anything here. */
2422 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
)
2427 if (code
== GTU
|| code
== GEU
2428 || code
== LTU
|| code
== LEU
)
2430 emit_insn (gen_rtx_PARALLEL
2433 gen_rtx_SET (VOIDmode
, cc0_rtx
,
2434 gen_rtx_COMPARE (mode
, x
, y
)),
2435 gen_rtx_CLOBBER (VOIDmode
,
2436 gen_rtx_SCRATCH (QImode
)),
2437 gen_rtx_CLOBBER (VOIDmode
,
2438 gen_rtx_SCRATCH (QImode
)))));
2442 emit_insn (gen_rtx_PARALLEL
2444 gen_rtvec (3, gen_rtx_SET (VOIDmode
, cc0_rtx
,
2445 gen_rtx_COMPARE (mode
, x
, y
)),
2446 gen_rtx_CLOBBER (VOIDmode
,
2447 gen_rtx_SCRATCH (QImode
)),
2448 gen_rtx_CLOBBER (VOIDmode
,
2449 gen_rtx_SCRATCH (QImode
)))));
2452 else if (mode
== HImode
)
2454 if (code
== GTU
|| code
== GEU
2455 || code
== LTU
|| code
== LEU
)
2457 emit_insn (gen_rtx_PARALLEL
2460 gen_rtx_SET (VOIDmode
, cc0_rtx
,
2461 gen_rtx_COMPARE (VOIDmode
, x
, y
)),
2462 gen_rtx_CLOBBER (VOIDmode
,
2463 gen_rtx_SCRATCH (QImode
)),
2464 gen_rtx_CLOBBER (VOIDmode
,
2465 gen_rtx_SCRATCH (QImode
)),
2466 gen_rtx_CLOBBER (VOIDmode
,
2467 gen_rtx_SCRATCH (QImode
)),
2468 gen_rtx_CLOBBER (VOIDmode
,
2469 gen_rtx_SCRATCH (QImode
)))));
2472 emit_insn (gen_rtx_SET (VOIDmode
, cc0_rtx
,
2473 gen_rtx_COMPARE (VOIDmode
,
2474 force_reg (HImode
, x
),
2475 force_reg (HImode
,y
))));
2478 fatal_error ("invalid mode for integer comparison in gen_compare_reg");
2484 output_block_move (operands
)
2487 int loop_count
= INTVAL(operands
[2]);
2490 fprintf (asm_out_file
, "\tdo %d {\n", loop_count
);
2491 xoperands
[0] = operands
[4];
2492 xoperands
[1] = operands
[1];
2493 output_asm_insn ("%0=*%1++", xoperands
);
2495 xoperands
[0] = operands
[0];
2496 xoperands
[1] = operands
[4];
2497 output_asm_insn ("*%0++=%1", xoperands
);
2499 fprintf (asm_out_file
, "\t}\n");
2504 uns_comparison_operator (op
, mode
)
2506 enum machine_mode mode
;
2508 if (mode
== VOIDmode
|| GET_MODE (op
) == mode
)
2512 code
= GET_CODE(op
);
2514 if (code
== LEU
|| code
== LTU
|| code
== GEU
2527 signed_comparison_operator (op
, mode
)
2529 enum machine_mode mode
;
2531 if (mode
== VOIDmode
|| GET_MODE (op
) == mode
)
2535 code
= GET_CODE(op
);
2537 if (!(code
== LEU
|| code
== LTU
|| code
== GEU
2550 dsp16xx_rtx_costs (x
, code
, outer_code
, total
)
2553 int outer_code ATTRIBUTE_UNUSED
;
2559 *total
= (unsigned HOST_WIDE_INT
) INTVAL (x
) < 65536 ? 0 : 2;
2565 *total
= COSTS_N_INSNS (1);
2569 *total
= COSTS_N_INSNS (2);
2573 *total
= COSTS_N_INSNS (GET_MODE (x
) == QImode
? 2 : 4);
2578 *total
= COSTS_N_INSNS (38);
2582 if (GET_MODE (x
) == QImode
)
2583 *total
= COSTS_N_INSNS (2);
2585 *total
= COSTS_N_INSNS (38);
2593 if (GET_MODE_CLASS (GET_MODE (x
)) == MODE_INT
)
2600 *total
= COSTS_N_INSNS (38);
2606 *total
= COSTS_N_INSNS (1);
2612 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
2614 HOST_WIDE_INT number
= INTVAL (XEXP (x
, 1));
2615 if (number
== 1 || number
== 4 || number
== 8
2617 *total
= COSTS_N_INSNS (1);
2618 else if (TARGET_BMU
)
2619 *total
= COSTS_N_INSNS (2);
2621 *total
= COSTS_N_INSNS (num_1600_core_shifts (number
));
2628 *total
= COSTS_N_INSNS (1);
2630 *total
= COSTS_N_INSNS (15);