2003-12-26 Guilhem Lavaux <guilhem@kaffe.org>
[official-gcc.git] / gcc / config / dsp16xx / dsp16xx.c
blob14d9c5e088e21515d56ee000fcf17e1d2407c8ee
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)
10 any later version.
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. */
23 #include "config.h"
24 #include "system.h"
25 #include "coretypes.h"
26 #include "tm.h"
27 #include "rtl.h"
28 #include "regs.h"
29 #include "hard-reg-set.h"
30 #include "real.h"
31 #include "insn-config.h"
32 #include "conditions.h"
33 #include "output.h"
34 #include "insn-attr.h"
35 #include "tree.h"
36 #include "expr.h"
37 #include "function.h"
38 #include "flags.h"
39 #include "ggc.h"
40 #include "toplev.h"
41 #include "recog.h"
42 #include "tm_p.h"
43 #include "target.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[] =
105 "%0=%0>>1",
106 "%0=%0>>4",
107 "%0=%0>>8",
108 "%0=%0>>16"
111 static const char *const ashift_right_asm_first[] =
113 "%0=%1>>1",
114 "%0=%1>>4",
115 "%0=%1>>8",
116 "%0=%1>>16"
119 static const char *const ashift_left_asm[] =
121 "%0=%0<<1",
122 "%0=%0<<4",
123 "%0=%0<<8",
124 "%0=%0<<16"
127 static const char *const ashift_left_asm_first[] =
129 "%0=%1<<1",
130 "%0=%1<<4",
131 "%0=%1<<8",
132 "%0=%1<<16"
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;
182 int
183 hard_regno_mode_ok (regno, mode)
184 int regno;
185 enum machine_mode mode;
187 switch ((int) mode)
189 case VOIDmode:
190 return 1;
192 /* We can't use the c0-c2 for QImode, since they are only
193 8 bits in length. */
195 case QImode:
196 if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
197 return 1;
198 else
199 return 0;
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
203 modes. */
205 case HFmode:
206 case HImode:
207 #if 0 /* ??? These modes do not appear in the machine description nor
208 are there library routines for them. */
209 case SFmode:
210 case DFmode:
211 case XFmode:
212 case SImode:
213 case DImode:
214 #endif
215 if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
216 || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
217 return 1;
218 else
219 return 0;
221 default:
222 return 0;
226 enum reg_class
227 dsp16xx_reg_class_from_letter (c)
228 int c;
230 switch (c)
232 case 'A':
233 return ACCUM_REGS;
235 case 'l':
236 return A0_REG;
238 case 'C':
239 return A1_REG;
241 case 'h':
242 return ACCUM_HIGH_REGS;
244 case 'j':
245 return A0H_REG;
247 case 'k':
248 return A0L_REG;
250 case 'q':
251 return A1H_REG;
253 case 'u':
254 return A1L_REG;
256 case 'x':
257 return X_REG;
259 case 'y':
260 return YH_REG;
262 case 'z':
263 return YL_REG;
265 case 't':
266 return P_REG;
268 case 'Z':
269 return Y_OR_P_REGS;
271 case 'd':
272 return ACCUM_Y_OR_P_REGS;
274 case 'a':
275 return Y_ADDR_REGS;
277 case 'B':
278 return (TARGET_BMU ? BMU_REGS : NO_REGS);
280 case 'Y':
281 return YBASE_VIRT_REGS;
283 case 'v':
284 return PH_REG;
286 case 'w':
287 return PL_REG;
289 case 'W':
290 return J_REG;
292 case 'e':
293 return YBASE_ELIGIBLE_REGS;
295 case 'b':
296 return ACCUM_LOW_REGS;
298 case 'c':
299 return NON_YBASE_REGS;
301 case 'f':
302 return Y_REG;
304 case 'D':
305 return SLOW_MEM_LOAD_REGS;
307 default:
308 return NO_REGS;
312 /* Return the class number of the smallest class containing
313 reg number REGNO. */
315 int
316 regno_reg_class(regno)
317 int regno;
319 switch (regno)
321 case REG_A0L:
322 return (int) A0L_REG;
323 case REG_A1L:
324 return (int) A1L_REG;
326 case REG_A0:
327 return (int) A0H_REG;
328 case REG_A1:
329 return (int) A1H_REG;
331 case REG_X:
332 return (int) X_REG;
334 case REG_Y:
335 return (int) YH_REG;
336 case REG_YL:
337 return (int) YL_REG;
339 case REG_PROD:
340 return (int) PH_REG;
341 case REG_PRODL:
342 return (int) PL_REG;
344 case REG_R0: case REG_R1: case REG_R2: case REG_R3:
345 return (int) Y_ADDR_REGS;
347 case REG_J:
348 return (int) J_REG;
349 case REG_K:
350 return (int) GENERAL_REGS;
352 case REG_YBASE:
353 return (int) GENERAL_REGS;
355 case REG_PT:
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;
364 case REG_PR:
365 return (int) GENERAL_REGS;
367 case REG_RB:
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;
380 default:
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));
396 enum reg_class
397 limit_reload_class (mode, class)
398 enum machine_mode mode ATTRIBUTE_UNUSED;
399 enum reg_class class;
401 return 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)
413 return 4;
414 else
415 return 2;
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)
422 return 2;
425 if (from == YBASE_VIRT_REGS)
427 if (to == YBASE_VIRT_REGS)
428 return 16;
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 ||
433 to == Y_OR_P_REGS)
435 return 8;
437 else
438 return 10;
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 ||
446 from == Y_OR_P_REGS)
448 return 8;
450 else
451 return 10;
454 return 8;
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. */
464 enum reg_class
465 preferred_reload_class (x, class)
466 rtx x;
467 enum reg_class class;
469 /* The ybase registers cannot have constants copied directly
470 to them. */
472 if (CONSTANT_P (x))
474 switch ((int) class)
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:
483 return ACCUM_REGS;
485 case X_OR_YBASE_REGS:
486 return X_REG;
488 case Y_OR_YBASE_REGS:
489 return Y_REG;
491 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
492 return YL_OR_PL_OR_ACCUM_LOW_REGS;
494 case P_OR_YBASE_REGS:
495 return P_REG;
497 case ACCUM_Y_P_OR_YBASE_REGS:
498 return ACCUM_Y_OR_P_REGS;
500 case Y_ADDR_OR_YBASE_REGS:
501 return Y_ADDR_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;
512 case ALL_REGS:
513 return NON_YBASE_REGS;
515 default:
516 return class;
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)))
525 switch ((int) class)
527 case NO_REGS:
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:
531 return class;
533 case X_REG:
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:
540 return ACCUM_REGS;
542 case YH_REG:
543 return (!reload_in_progress ? NO_REGS : class);
545 case YH_OR_ACCUM_HIGH_REGS:
546 return ACCUM_HIGH_REGS;
548 case X_OR_YH_REGS:
549 case YL_REG:
550 return (!reload_in_progress ? NO_REGS : class);
552 case YL_OR_ACCUM_LOW_REGS:
553 return ACCUM_LOW_REGS;
555 case X_OR_YL_REGS:
556 case X_OR_Y_REGS: case Y_REG:
557 return (!reload_in_progress ? NO_REGS : class);
559 case ACCUM_OR_Y_REGS:
560 return ACCUM_REGS;
562 case PH_REG:
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;
569 case X_OR_PL_REGS:
570 return (!reload_in_progress ? NO_REGS : class);
572 case YL_OR_PL_OR_ACCUM_LOW_REGS:
573 return ACCUM_LOW_REGS;
575 case P_REG:
576 return (!reload_in_progress ? NO_REGS : class);
578 case ACCUM_OR_P_REGS:
579 return ACCUM_REGS;
581 case YL_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;
587 case Y_OR_P_REGS:
588 return (!reload_in_progress ? NO_REGS : class);
590 case ACCUM_Y_OR_P_REGS:
591 return ACCUM_REGS;
593 case NO_FRAME_Y_ADDR_REGS:
594 case 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:
601 return ACCUM_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:
612 return ACCUM_REGS;
614 case J_REG:
615 case J_OR_DAU_16_BIT_REGS:
616 case BMU_REGS:
617 return (!reload_in_progress ? NO_REGS : class);
619 case YBASE_VIRT_REGS:
620 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
621 return class;
622 else
623 return (!reload_in_progress ? NO_REGS : class);
625 case ACCUM_LOW_OR_YBASE_REGS:
626 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
627 return class;
628 else
629 return ACCUM_LOW_REGS;
631 case ACCUM_OR_YBASE_REGS:
632 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
633 return class;
634 else
635 return ACCUM_REGS;
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;
641 else
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;
647 else
648 return ACCUM_LOW_REGS;
650 case P_OR_YBASE_REGS:
651 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
652 return YBASE_VIRT_REGS;
653 else
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;
659 else
660 return ACCUM_REGS;
662 case Y_ADDR_OR_YBASE_REGS:
663 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
664 return YBASE_VIRT_REGS;
665 else
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;
671 else
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;
677 else
678 return ACCUM_REGS;
680 case NO_HIGH_ALL_REGS:
681 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
682 return ACCUM_LOW_OR_YBASE_REGS;
683 else
684 return ACCUM_LOW_REGS;
686 case ALL_REGS:
687 if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
688 return ACCUM_OR_YBASE_REGS;
689 else
690 return ACCUM_REGS;
692 case NOHIGH_NON_ADDR_REGS:
693 return ACCUM_LOW_REGS;
695 case NON_ADDR_REGS:
696 case SLOW_MEM_LOAD_REGS:
697 return ACCUM_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);
705 case NON_YBASE_REGS:
706 return ACCUM_REGS;
708 default:
709 return 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)))
719 switch ((int) class)
721 case NO_REGS:
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:
741 default:
742 return class;
744 case J_REG:
745 return (!reload_in_progress ? NO_REGS : class);
747 case J_OR_DAU_16_BIT_REGS:
748 return ACCUM_HIGH_REGS;
750 case BMU_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:
758 return ACCUM_REGS;
760 case X_OR_YBASE_REGS:
761 return X_REG;
763 case Y_OR_YBASE_REGS:
764 return Y_REG;
766 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
767 return YL_OR_PL_OR_ACCUM_LOW_REGS;
769 case P_OR_YBASE_REGS:
770 return P_REG;
772 case ACCUM_Y_P_OR_YBASE_REGS:
773 return ACCUM_Y_OR_P_REGS;
775 case Y_ADDR_OR_YBASE_REGS:
776 return Y_ADDR_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;
787 case ALL_REGS:
788 return YBASE_ELIGIBLE_REGS;
790 case NOHIGH_NON_ADDR_REGS:
791 return ACCUM_LOW_OR_YL_OR_P_REGS;
793 case NON_ADDR_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:
803 return Y_ADDR_REGS;
805 case 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)
819 return class;
821 /* If the accumulators are not part of the class
822 being reloaded into, return NO_REGS. */
823 #if 0
824 if (!reg_class_subset_p (ACCUM_REGS, class))
825 return (!reload_in_progress ? NO_REGS : class);
826 #endif
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
833 used. */
835 else if (class == ACCUM_LOW_REGS)
836 return A1L_REG;
837 else if (class == A0L_REG)
838 return NO_REGS;
839 else
840 return class;
843 if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
844 return Y_ADDR_REGS;
845 else
846 return class;
848 else if (GET_CODE (x) == MEM)
850 /* We can't copy from a memory location into a
851 ybase register. */
852 if (reg_class_subset_p(YBASE_VIRT_REGS, class))
854 switch ((int) 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:
863 return ACCUM_REGS;
865 case X_OR_YBASE_REGS:
866 return X_REG;
868 case Y_OR_YBASE_REGS:
869 return Y_REG;
871 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
872 return YL_OR_PL_OR_ACCUM_LOW_REGS;
874 case P_OR_YBASE_REGS:
875 return P_REG;
877 case ACCUM_Y_P_OR_YBASE_REGS:
878 return ACCUM_Y_OR_P_REGS;
880 case Y_ADDR_OR_YBASE_REGS:
881 return Y_ADDR_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;
892 case ALL_REGS:
893 return NON_YBASE_REGS;
895 default:
896 return class;
899 else
900 return class;
902 else
903 return class;
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. */
910 enum reg_class
911 secondary_reload_class (class, mode, in)
912 enum reg_class class;
913 enum machine_mode mode;
914 rtx in;
916 int regno = -1;
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
923 clobbered. */
925 if (class == ACCUM_HIGH_REGS
926 || class == A1H_REG
927 || class == A0H_REG)
929 if (GET_CODE (in) == PLUS && mode == QImode)
930 return ACCUM_LOW_REGS;
933 if (class == ACCUM_HIGH_REGS
934 || class == ACCUM_LOW_REGS
935 || class == A1L_REG
936 || class == A0L_REG
937 || class == A1H_REG
938 || class == A0H_REG)
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))
948 return NO_REGS;
952 /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
953 into anything. */
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))
959 return NO_REGS;
961 if (class == ACCUM_OR_YBASE_REGS && REG_P(in)
962 && IS_YBASE_ELIGIBLE_REG(regno))
964 return NO_REGS;
967 /* We can copy the ybase registers into:
968 r0-r3, a0-a1, y, p, & x or the union of
969 any of these. */
971 if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
973 switch ((int) class)
975 case (int) X_REG:
976 case (int) X_OR_ACCUM_LOW_REGS:
977 case (int) X_OR_ACCUM_REGS:
978 case (int) YH_REG:
979 case (int) YH_OR_ACCUM_HIGH_REGS:
980 case (int) X_OR_YH_REGS:
981 case (int) YL_REG:
982 case (int) YL_OR_ACCUM_LOW_REGS:
983 case (int) X_OR_Y_REGS:
984 case (int) X_OR_YL_REGS:
985 case (int) Y_REG:
986 case (int) ACCUM_OR_Y_REGS:
987 case (int) PH_REG:
988 case (int) X_OR_PH_REGS:
989 case (int) PL_REG:
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:
993 case (int) P_REG:
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:
1006 return NO_REGS;
1008 default:
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)
1021 switch (regno)
1023 case REG_A0:
1024 case REG_A0L:
1025 case REG_A1:
1026 case REG_A1L:
1027 case REG_X:
1028 case REG_Y:
1029 case REG_YL:
1030 case REG_PROD:
1031 case REG_PRODL:
1032 case REG_R0:
1033 case REG_R1:
1034 case REG_R2:
1035 case REG_R3:
1036 if (class == YBASE_VIRT_REGS)
1037 return NO_REGS;
1038 else
1040 switch ((int) class)
1042 case (int) X_REG:
1043 case (int) X_OR_ACCUM_LOW_REGS:
1044 case (int) X_OR_ACCUM_REGS:
1045 case (int) YH_REG:
1046 case (int) YH_OR_ACCUM_HIGH_REGS:
1047 case (int) X_OR_YH_REGS:
1048 case (int) YL_REG:
1049 case (int) YL_OR_ACCUM_LOW_REGS:
1050 case (int) X_OR_Y_REGS:
1051 case (int) X_OR_YL_REGS:
1052 case (int) Y_REG:
1053 case (int) ACCUM_OR_Y_REGS:
1054 case (int) PH_REG:
1055 case (int) X_OR_PH_REGS:
1056 case (int) PL_REG:
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:
1060 case (int) P_REG:
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;
1075 default:
1076 break;
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;
1088 else
1089 return NO_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;
1103 #if 0
1104 if (REG_P(in))
1105 return ACCUM_REGS;
1106 #endif
1108 /* Otherwise, we need a high accumulator(s). */
1109 return ACCUM_HIGH_REGS;
1113 symbolic_address_operand (op, mode)
1114 rtx op;
1115 enum machine_mode mode ATTRIBUTE_UNUSED;
1117 return (symbolic_address_p (op));
1121 symbolic_address_p (op)
1122 rtx op;
1124 switch (GET_CODE (op))
1126 case SYMBOL_REF:
1127 case LABEL_REF:
1128 return 1;
1130 case CONST:
1131 op = XEXP (op, 0);
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);
1137 default:
1138 return 0;
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)
1148 rtx op;
1149 enum machine_mode mode;
1151 return (memory_address_p (mode, op) && !symbolic_address_p (op));
1155 sp_operand (op, mode)
1156 rtx op;
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)
1167 rtx op;
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))))))
1175 return 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))))))
1181 return 1;
1182 else
1183 return 0;
1187 nonmemory_arith_operand (op, mode)
1188 rtx op;
1189 enum machine_mode mode;
1191 return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
1195 arith_reg_operand (op, mode)
1196 rtx op;
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)
1208 rtx op;
1209 enum machine_mode mode ATTRIBUTE_UNUSED;
1211 if (symbolic_address_p (op) || REG_P(op))
1213 return 1;
1216 return 0;
1220 dsp16xx_comparison_operator (op, mode)
1221 register rtx op;
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));
1230 void
1231 notice_update_cc(exp)
1232 rtx exp;
1234 if (GET_CODE (exp) == SET)
1236 /* Jumps do not alter the cc's. */
1238 if (SET_DEST (exp) == pc_rtx)
1239 return;
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;
1254 return;
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;
1264 return;
1266 /* Function calls clobber the cc's. */
1267 else if (GET_CODE (SET_SRC (exp)) == CALL)
1269 CC_STATUS_INIT;
1270 return;
1272 /* Tests and compares set the cc's in predictable ways. */
1273 else if (SET_DEST (exp) == cc0_rtx)
1275 CC_STATUS_INIT;
1276 cc_status.value1 = SET_SRC (exp);
1277 return;
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)))
1283 case PLUS:
1284 case MINUS:
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))))
1290 CC_STATUS_INIT;
1291 break;
1294 case ASHIFTRT:
1295 case LSHIFTRT:
1296 case ASHIFT:
1297 case AND:
1298 case IOR:
1299 case XOR:
1300 case MULT:
1301 case NEG:
1302 case NOT:
1303 cc_status.value1 = SET_SRC (exp);
1304 cc_status.value2 = SET_DEST (exp);
1305 break;
1307 default:
1308 CC_STATUS_INIT;
1310 else
1312 CC_STATUS_INIT;
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)
1319 return;
1321 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1323 CC_STATUS_INIT;
1324 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1325 return;
1328 CC_STATUS_INIT;
1330 else
1332 CC_STATUS_INIT;
1337 dsp16xx_makes_calls ()
1339 rtx insn;
1341 for (insn = get_insns (); insn; insn = next_insn (insn))
1342 if (GET_CODE (insn) == CALL_INSN)
1343 return (1);
1345 return 0;
1348 long
1349 compute_frame_size (size)
1350 int size;
1352 long total_size;
1353 long var_size;
1354 long args_size;
1355 long extra_size;
1356 long reg_size;
1358 /* This value is needed to compute reg_size. */
1359 current_frame_info.function_makes_calls = !leaf_function_p ();
1361 reg_size = 0;
1362 extra_size = 0;
1363 var_size = size;
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;
1379 if (reg_size)
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;
1386 return total_size;
1390 dsp16xx_call_saved_register (regno)
1391 int regno;
1393 #if 0
1394 if (regno == REG_PR && current_frame_info.function_makes_calls)
1395 return 1;
1396 #endif
1397 return (regs_ever_live[regno] && !call_used_regs[regno] &&
1398 !IS_YBASE_REGISTER_WINDOW(regno));
1402 ybase_regs_ever_used ()
1404 int regno;
1405 int live = 0;
1407 for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
1408 if (regs_ever_live[regno])
1410 live = 1;
1411 break;
1414 return live;
1417 static void
1418 dsp16xx_output_function_prologue (file, size)
1419 FILE *file;
1420 HOST_WIDE_INT size;
1422 int regno;
1423 long total_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);
1449 else
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);
1458 else
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]);
1462 else
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
1477 location. */
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);
1485 else
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");
1500 void
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;
1527 static void
1528 dsp16xx_output_function_epilogue (file, size)
1529 FILE *file;
1530 HOST_WIDE_INT size ATTRIBUTE_UNUSED;
1532 int regno;
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);
1545 else
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);
1557 else
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);
1575 else
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
1592 normally. */
1595 emit_move_sequence (operands, mode)
1596 rtx *operands;
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);
1607 return 0;
1610 void
1611 double_reg_from_memory (operands)
1612 rtx operands[];
1614 rtx xoperands[4];
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)
1632 rtx addr;
1633 int offset = 0;
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);
1648 else
1650 xoperands[1] = XEXP(operands[1],0);
1651 xoperands[0] = operands[0];
1653 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
1658 void
1659 double_reg_to_memory (operands)
1660 rtx operands[];
1662 rtx xoperands[4];
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)
1682 rtx addr;
1683 int offset = 0;
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;
1694 else
1695 fatal_error ("invalid addressing mode");
1697 fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
1699 else
1701 xoperands[0] = XEXP(operands[0],0);
1702 xoperands[1] = operands[1];
1704 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
1708 void
1709 override_options ()
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)
1736 rtx insn;
1738 switch (next_cc_user_code (insn))
1740 case GTU:
1741 case GEU:
1742 case LTU:
1743 case LEU:
1744 return 1;
1745 default:
1746 return 0;
1750 enum rtx_code
1751 next_cc_user_code (insn)
1752 rtx 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)));
1767 else
1768 abort ();
1771 void
1772 print_operand(file, op, letter)
1773 FILE *file;
1774 rtx op;
1775 int letter;
1777 enum rtx_code code;
1779 code = GET_CODE(op);
1781 switch (letter)
1783 case 'I':
1784 code = reverse_condition (code);
1785 /* Fallthrough */
1787 case 'C':
1788 if (code == EQ)
1790 fputs ("eq", file);
1791 return;
1793 else if (code == NE)
1795 fputs ("ne", file);
1796 return;
1798 else if (code == GT || code == GTU)
1800 fputs ("gt", file);
1801 return;
1803 else if (code == LT || code == LTU)
1805 fputs ("mi", file);
1806 return;
1808 else if (code == GE || code == GEU)
1810 fputs ("pl", file);
1811 return;
1813 else if (code == LE || code == LEU)
1815 fputs ("le", file);
1816 return;
1818 else
1819 abort ();
1820 break;
1822 default:
1823 break;
1826 if (code == REG)
1828 /* Print the low half of a 32-bit register pair. */
1829 if (letter == 'w')
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)]);
1837 else
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);
1846 if (letter == 'H')
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);
1852 else
1853 output_addr_const(file, op);
1855 else if (code == CONST_DOUBLE && GET_MODE(op) != DImode)
1857 long l;
1858 REAL_VALUE_TYPE r;
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);
1870 return;
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));
1880 if (n >= 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));
1893 if (n >= 0)
1894 fprintf (file, "+");
1896 n = (int) (short) n;
1897 fprintf (file, "%d", n);
1899 else
1900 output_addr_const(file, op);
1902 else
1903 output_addr_const (file, op);
1907 void
1908 print_operand_address(file, addr)
1909 FILE *file;
1910 rtx addr;
1912 rtx base;
1913 int offset = 0;;
1915 switch (GET_CODE (addr))
1917 case REG:
1918 fprintf (file, "*%s", reg_names[REGNO (addr)]);
1919 break;
1920 case POST_DEC:
1921 fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
1922 break;
1923 case POST_INC:
1924 fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
1925 break;
1926 case PLUS:
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);
1931 else
1932 abort();
1933 if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
1935 if (offset >= -31 && offset <= 0)
1936 offset = 31 + offset;
1937 else
1938 fatal_error ("invalid offset in ybase addressing");
1940 else
1941 fatal_error ("invalid register in ybase addressing");
1943 fprintf (file, "*(%d)", offset);
1944 break;
1946 default:
1947 if (FITS_5_BITS (addr))
1948 fprintf (file, "*(0x%x)", (int)(INTVAL (addr) & 0x20));
1949 else
1950 output_addr_const (file, addr);
1954 void
1955 output_dsp16xx_float_const (operands)
1956 rtx *operands;
1958 rtx src = operands[1];
1960 REAL_VALUE_TYPE d;
1961 long value;
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);
1970 static int
1971 reg_save_size ()
1973 int reg_save_size = 0;
1974 int regno;
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)
1984 reg_save_size += 1;
1986 return (reg_save_size);
1989 #if 0
1991 dsp16xx_starting_frame_offset()
1993 int reg_save_size = 0;
1994 int regno;
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);
2004 #endif
2007 initial_frame_pointer_offset()
2009 int offset = 0;
2011 offset = compute_frame_size (get_frame_size());
2013 #ifdef STACK_GROWS_DOWNWARD
2014 return (offset);
2015 #else
2016 return (-offset);
2017 #endif
2020 /* Generate the minimum number of 1600 core shift instructions
2021 to shift by 'shift_amount'. */
2023 #if 0
2024 void
2025 emit_1600_core_shift (shift_op, operands, shift_amount, mode)
2026 enum rtx_code shift_op;
2027 rtx *operands;
2028 int shift_amount;
2029 enum machine_mode mode;
2031 int quotient;
2032 int i;
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,
2044 first_shift_emitted
2045 ? operands[0] : operands[1],
2046 GEN_INT (16))));
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,
2056 first_shift_emitted
2057 ? operands[0] : operands[1],
2058 GEN_INT (8))));
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,
2068 first_shift_emitted
2069 ? operands[0] : operands[1],
2070 GEN_INT (4))));
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,
2080 first_shift_emitted
2081 ? operands[0] : operands[1],
2082 GEN_INT (1))));
2083 first_shift_emitted = 1;
2087 #else
2088 void
2089 emit_1600_core_shift (shift_op, operands, shift_amount)
2090 enum rtx_code shift_op;
2091 rtx *operands;
2092 int shift_amount;
2094 int quotient;
2095 int i;
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;
2115 else
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;
2158 #endif
2161 num_1600_core_shifts (shift_amount)
2162 int shift_amount;
2164 int quotient;
2165 int i;
2166 int first_shift_emitted = 0;
2167 int num_shifts = 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++)
2176 num_shifts++;
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++)
2184 num_shifts++;
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++)
2193 num_shifts++;
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++)
2202 num_shifts++;
2204 first_shift_emitted = 1;
2207 return num_shifts;
2210 void
2211 asm_output_common(file, name, size, rounded)
2212 FILE *file;
2213 const char *name;
2214 int size ATTRIBUTE_UNUSED;
2215 int rounded;
2217 bss_section ();
2218 (*targetm.asm_out.globalize_label) (file, name);
2219 assemble_name (file, name);
2220 fputs (":", file);
2221 if (rounded > 1)
2222 fprintf (file, "%d * int\n", rounded);
2223 else
2224 fprintf (file, "int\n");
2227 void
2228 asm_output_local(file, name, size, rounded)
2229 FILE *file;
2230 const char *name;
2231 int size ATTRIBUTE_UNUSED;
2232 int rounded;
2234 bss_section ();
2235 assemble_name (file, name);
2236 fputs (":", file);
2237 if (rounded > 1)
2238 fprintf (file, "%d * int\n", rounded);
2239 else
2240 fprintf (file, "int\n");
2243 static int
2244 dsp16xx_address_cost (addr)
2245 rtx addr;
2247 switch (GET_CODE (addr))
2249 default:
2250 break;
2252 case REG:
2253 return 1;
2255 case CONST:
2257 rtx offset = const0_rtx;
2258 addr = eliminate_constant_term (addr, &offset);
2260 if (GET_CODE (addr) == LABEL_REF)
2261 return 2;
2263 if (GET_CODE (addr) != SYMBOL_REF)
2264 return 4;
2266 if (INTVAL (offset) == 0)
2267 return 2;
2269 /* fall through */
2271 case POST_INC: case POST_DEC:
2272 return (GET_MODE (addr) == QImode ? 1 : 2);
2274 case SYMBOL_REF: case LABEL_REF:
2275 return 2;
2277 case PLUS:
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)
2289 break;
2291 switch (GET_CODE (plus1))
2293 default:
2294 break;
2296 case CONST_INT:
2297 return 4;
2299 case CONST:
2300 case SYMBOL_REF:
2301 case LABEL_REF:
2302 return dsp16xx_address_cost (plus1) + 1;
2307 return 4;
2311 /* Determine whether a function argument is passed in a register, and
2312 which register.
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. */
2336 struct rtx_def *
2337 dsp16xx_function_arg (args_so_far, mode, type, named)
2338 CUMULATIVE_ARGS args_so_far;
2339 enum machine_mode mode;
2340 tree type;
2341 int named;
2343 if (TARGET_REGPARM)
2345 if ((args_so_far & 1) != 0
2346 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2347 args_so_far++;
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);
2354 else
2355 return (struct rtx_def *) 0;
2357 else
2358 return (struct rtx_def *) 0;
2361 /* Advance the argument to the next argument position. */
2363 void
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 */
2370 if (TARGET_REGPARM)
2372 if ((*cum & 1) != 0
2373 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2374 *cum += 1;
2376 if (mode != BLKmode)
2377 *cum += GET_MODE_SIZE (mode);
2378 else
2379 *cum += int_size_in_bytes (type);
2383 static void
2384 dsp16xx_file_start ()
2386 fprintf (asm_out_file, "#include <%s.h>\n", save_chip_name);
2390 gen_tst_reg (x)
2391 rtx x;
2393 enum machine_mode mode;
2395 mode = GET_MODE (x);
2397 if (mode == QImode)
2398 emit_insn (gen_rtx_PARALLEL
2399 (VOIDmode,
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));
2405 else
2406 fatal_error ("invalid mode for gen_tst_reg");
2408 return cc0_rtx;
2412 gen_compare_reg (code, x, y)
2413 enum rtx_code code;
2414 rtx 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)
2423 return cc0_rtx;
2425 if (mode == QImode)
2427 if (code == GTU || code == GEU
2428 || code == LTU || code == LEU)
2430 emit_insn (gen_rtx_PARALLEL
2431 (VOIDmode,
2432 gen_rtvec (3,
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)))));
2440 else
2442 emit_insn (gen_rtx_PARALLEL
2443 (VOIDmode,
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
2458 (VOIDmode,
2459 gen_rtvec (5,
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)))));
2471 else
2472 emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx,
2473 gen_rtx_COMPARE (VOIDmode,
2474 force_reg (HImode, x),
2475 force_reg (HImode,y))));
2477 else
2478 fatal_error ("invalid mode for integer comparison in gen_compare_reg");
2480 return cc0_rtx;
2483 const char *
2484 output_block_move (operands)
2485 rtx operands[];
2487 int loop_count = INTVAL(operands[2]);
2488 rtx xoperands[4];
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");
2500 return "";
2504 uns_comparison_operator (op, mode)
2505 rtx op;
2506 enum machine_mode mode;
2508 if (mode == VOIDmode || GET_MODE (op) == mode)
2510 enum rtx_code code;
2512 code = GET_CODE(op);
2514 if (code == LEU || code == LTU || code == GEU
2515 || code == GTU)
2517 return 1;
2519 else
2520 return 0;
2523 return 0;
2527 signed_comparison_operator (op, mode)
2528 rtx op;
2529 enum machine_mode mode;
2531 if (mode == VOIDmode || GET_MODE (op) == mode)
2533 enum rtx_code code;
2535 code = GET_CODE(op);
2537 if (!(code == LEU || code == LTU || code == GEU
2538 || code == GTU))
2540 return 1;
2542 else
2543 return 0;
2546 return 0;
2549 static bool
2550 dsp16xx_rtx_costs (x, code, outer_code, total)
2551 rtx x;
2552 int code;
2553 int outer_code ATTRIBUTE_UNUSED;
2554 int *total;
2556 switch (code)
2558 case CONST_INT:
2559 *total = (unsigned HOST_WIDE_INT) INTVAL (x) < 65536 ? 0 : 2;
2560 return true;
2562 case LABEL_REF:
2563 case SYMBOL_REF:
2564 case CONST:
2565 *total = COSTS_N_INSNS (1);
2566 return true;
2568 case CONST_DOUBLE:
2569 *total = COSTS_N_INSNS (2);
2570 return true;
2572 case MEM:
2573 *total = COSTS_N_INSNS (GET_MODE (x) == QImode ? 2 : 4);
2574 return true;
2576 case DIV:
2577 case MOD:
2578 *total = COSTS_N_INSNS (38);
2579 return true;
2581 case MULT:
2582 if (GET_MODE (x) == QImode)
2583 *total = COSTS_N_INSNS (2);
2584 else
2585 *total = COSTS_N_INSNS (38);
2586 return true;
2588 case PLUS:
2589 case MINUS:
2590 case AND:
2591 case IOR:
2592 case XOR:
2593 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2595 *total = 1;
2596 return false;
2598 else
2600 *total = COSTS_N_INSNS (38);
2601 return true;
2604 case NEG:
2605 case NOT:
2606 *total = COSTS_N_INSNS (1);
2607 return true;
2609 case ASHIFT:
2610 case ASHIFTRT:
2611 case LSHIFTRT:
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
2616 || number == 16)
2617 *total = COSTS_N_INSNS (1);
2618 else if (TARGET_BMU)
2619 *total = COSTS_N_INSNS (2);
2620 else
2621 *total = COSTS_N_INSNS (num_1600_core_shifts (number));
2622 return true;
2624 break;
2627 if (TARGET_BMU)
2628 *total = COSTS_N_INSNS (1);
2629 else
2630 *total = COSTS_N_INSNS (15);
2631 return true;