(*zeroextract[qs]i_compare0_scratch): Use const_int_operand
[official-gcc.git] / gcc / config / dsp16xx / dsp16xx.c
blob90b316d5a1c0ac451355ff2c0c75a57107061546
1 /* Subroutines for assembler code output on the DSP1610.
2 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
3 Contributed by Michael Collison (collison@world.std.com).
5 This file is part of GNU CC.
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING. If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA. */
22 /* Some output-actions in dsp1600.md need these. */
23 #include <stdio.h>
24 #include "config.h"
25 #include "rtl.h"
26 #include "regs.h"
27 #include "hard-reg-set.h"
28 #include "real.h"
29 #include "insn-config.h"
30 #include "conditions.h"
31 #include "insn-flags.h"
32 #include "output.h"
33 #include "insn-attr.h"
34 #include "tree.h"
35 #include "expr.h"
36 #include "flags.h"
38 char *text_seg_name;
39 char *rsect_text;
40 char *data_seg_name;
41 char *rsect_data;
42 char *bss_seg_name;
43 char *rsect_bss;
44 char *const_seg_name;
45 char *rsect_const;
47 char *chip_name;
48 char *save_chip_name;
50 /* Save the operands of a compare. The 16xx has not lt or gt, so
51 in these cases we swap the operands and reverse the condition */
53 rtx dsp16xx_compare_op0;
54 rtx dsp16xx_compare_op1;
55 struct rtx_def *(*dsp16xx_compare_gen)();
57 static char *fp;
58 static char *sp;
59 static char *rr;
60 static char *a1h;
62 struct dsp16xx_frame_info current_frame_info;
63 struct dsp16xx_frame_info zero_frame_info;
65 rtx dsp16xx_addhf3_libcall = (rtx) 0;
66 rtx dsp16xx_subhf3_libcall = (rtx) 0;
67 rtx dsp16xx_mulhf3_libcall = (rtx) 0;
68 rtx dsp16xx_divhf3_libcall = (rtx) 0;
69 rtx dsp16xx_cmphf3_libcall = (rtx) 0;
70 rtx dsp16xx_fixhfhi2_libcall = (rtx) 0;
71 rtx dsp16xx_floathihf2_libcall = (rtx) 0;
72 rtx dsp16xx_neghf2_libcall = (rtx) 0;
74 rtx dsp16xx_mulhi3_libcall = (rtx) 0;
75 rtx dsp16xx_udivqi3_libcall = (rtx) 0;
76 rtx dsp16xx_udivhi3_libcall = (rtx) 0;
77 rtx dsp16xx_divqi3_libcall = (rtx) 0;
78 rtx dsp16xx_divhi3_libcall = (rtx) 0;
79 rtx dsp16xx_modqi3_libcall = (rtx) 0;
80 rtx dsp16xx_modhi3_libcall = (rtx) 0;
81 rtx dsp16xx_umodqi3_libcall = (rtx) 0;
82 rtx dsp16xx_umodhi3_libcall = (rtx) 0;
83 rtx dsp16xx_ashrhi3_libcall = (rtx) 0;
84 rtx dsp16xx_ashlhi3_libcall = (rtx) 0;
85 rtx dsp16xx_ucmphi2_libcall = (rtx) 0;
86 rtx dsp16xx_lshrhi3_libcall = (rtx) 0;
88 char *himode_reg_name[] = HIMODE_REGISTER_NAMES;
90 #define SHIFT_INDEX_1 0
91 #define SHIFT_INDEX_4 1
92 #define SHIFT_INDEX_8 2
93 #define SHIFT_INDEX_16 3
95 static char *ashift_right_asm[] =
97 "%0=%0>>1",
98 "%0=%0>>4",
99 "%0=%0>>8",
100 "%0=%0>>16"
103 static char *ashift_right_asm_first[] =
105 "%0=%1>>1",
106 "%0=%1>>4",
107 "%0=%1>>8",
108 "%0=%1>>16"
111 static char *ashift_left_asm[] =
113 "%0=%0<<1",
114 "%0=%0<<4",
115 "%0=%0<<8",
116 "%0=%0<<16"
119 static char *ashift_left_asm_first[] =
121 "%0=%1<<1",
122 "%0=%1<<4",
123 "%0=%1<<8",
124 "%0=%1<<16"
127 static char *lshift_right_asm[] =
129 "%0=%0>>1\n\t%0=%b0&0x7fff",
130 "%0=%0>>4\n\t%0=%b0&0x0fff",
131 "%0=%0>>8\n\t%0=%b0&0x00ff",
132 "%0=%0>>16\n\t%0=%b0&0x0000"
135 static char *lshift_right_asm_first[] =
137 "%0=%1>>1\n\t%0=%b0&0x7fff",
138 "%0=%1>>4\n\t%0=%b0&0x0fff",
139 "%0=%1>>8\n\t%0=%b0&0x00ff",
140 "%0=%1>>16\n\t%0=%b0&0x0000"
143 int
144 hard_regno_mode_ok (regno, mode)
145 int regno;
146 enum machine_mode mode;
148 switch ((int) mode)
150 case VOIDmode:
151 return 1;
154 We can't use the c0-c2 for QImode, since they are only
155 8 bits in length */
157 case QImode:
158 if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
159 return 1;
160 else
161 return 0;
163 /* We only allow a0, a1, y, and p to be allocated for 32-bit modes.
164 Additionally we allow the virtual ybase registers to be used for 32-bit
165 modes. */
167 case HFmode:
168 case SFmode:
169 case DFmode:
170 case XFmode:
171 case HImode:
172 case SImode:
173 case DImode:
174 if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
175 || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
176 return 1;
177 else
178 return 0;
180 default:
181 return 0;
185 enum reg_class
186 dsp16xx_reg_class_from_letter (c)
187 int c;
189 switch (c)
191 case 'A':
192 return ACCUM_REGS;
194 case 'h':
195 return ACCUM_HIGH_REGS;
197 case 'j':
198 return A0H_REG;
200 case 'k':
201 return A0L_REG;
203 case 'q':
204 return A1H_REG;
206 case 'u':
207 return A1L_REG;
209 case 'x':
210 return X_REG;
212 case 'y':
213 return YH_REG;
215 case 'z':
216 return YL_REG;
218 case 't':
219 return P_REG;
221 case 'Z':
222 return Y_OR_P_REGS;
224 case 'd':
225 return ACCUM_Y_OR_P_REGS;
227 case 'C':
228 return NO_FRAME_Y_ADDR_REGS;
230 case 'a':
231 return Y_ADDR_REGS;
233 case 'B':
234 return (TARGET_BMU ? BMU_REGS : NO_REGS);
236 case 'Y':
237 return YBASE_VIRT_REGS;
239 case 'v':
240 return PH_REG;
242 case 'w':
243 return PL_REG;
245 case 'W':
246 return J_REG;
248 case 'e':
249 return YBASE_ELIGIBLE_REGS;
251 case 'b':
252 return ACCUM_LOW_REGS;
254 case 'c':
255 return NON_YBASE_REGS;
257 case 'f':
258 return Y_REG;
260 case 'D':
261 return SLOW_MEM_LOAD_REGS;
263 default:
264 fatal ("Invalid register class letter %c", c);
265 return NO_REGS;
268 /* Return the class number of the smallest class containing
269 reg number REGNO. */
271 int
272 regno_reg_class(regno)
273 int regno;
275 switch (regno)
277 case REG_A0L:
278 return (int) A0L_REG;
279 case REG_A1L:
280 return (int) A1L_REG;
282 case REG_A0:
283 return (int) A0H_REG;
284 case REG_A1:
285 return (int) A1H_REG;
287 case REG_X:
288 return (int) X_REG;
290 case REG_Y:
291 return (int) YH_REG;
292 case REG_YL:
293 return (int) YL_REG;
295 case REG_PROD:
296 return (int) PH_REG;
297 case REG_PRODL:
298 return (int) PL_REG;
300 case REG_R0: case REG_R1: case REG_R2: case REG_R3:
301 return (int) Y_ADDR_REGS;
303 case REG_J:
304 return (int) J_REG;
305 case REG_K:
306 return (int) GENERAL_REGS;
308 case REG_YBASE:
309 return (int) GENERAL_REGS;
311 case REG_PT:
312 return (int) GENERAL_REGS;
314 case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:
315 return (int) BMU_REGS;
317 case REG_C0: case REG_C1: case REG_C2:
318 return (int) GENERAL_REGS;
320 case REG_PR:
321 return (int) GENERAL_REGS;
323 case REG_RB:
324 return (int) GENERAL_REGS;
326 case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:
327 case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:
328 case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:
329 case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:
330 case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:
331 case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:
332 case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:
333 case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:
334 return (int) YBASE_VIRT_REGS;
336 default:
337 return (int) NO_REGS;
341 /* A C expression for the maximum number of consecutive registers of class CLASS
342 needed to hold a value of mode MODE */
345 class_max_nregs(class, mode)
346 enum reg_class class;
347 enum machine_mode mode;
349 return (GET_MODE_SIZE(mode));
352 enum reg_class
353 limit_reload_class (mode, class)
354 enum machine_mode mode;
355 enum reg_class class;
357 switch ((int) class)
359 case NO_REGS:
360 case A0H_REG:
361 case A0L_REG:
362 case A0_REG:
363 case A1H_REG:
364 return class;
366 case ACCUM_HIGH_REGS:
367 fatal ("ACCUM_HIGH_REGS class in limit_reload_class");
369 case A1L_REG:
370 case ACCUM_LOW_REGS:
371 case A1_REG:
372 return class;
374 case ACCUM_REGS:
375 if (GET_MODE_SIZE(mode) == 1)
376 return ACCUM_LOW_REGS;
377 else
378 return class;
380 case X_REG:
381 case X_OR_ACCUM_LOW_REGS:
382 return class;
384 case X_OR_ACCUM_REGS:
385 if (GET_MODE_SIZE(mode) == 1)
386 return X_OR_ACCUM_LOW_REGS;
387 else
388 return class;
390 case YH_REG:
391 return class;
393 case YH_OR_ACCUM_HIGH_REGS:
394 fatal ("YH_OR_ACCUM_HIGH_REGS found in limit_reload_class");
396 case X_OR_YH_REGS:
397 return class;
399 case YL_REG:
400 /* Register 'yl' is invalid for QImode, so we should never
401 see it. */
403 fatal ("YL found in limit_reload_class");
405 case YL_OR_ACCUM_LOW_REGS:
406 case X_OR_YL_REGS:
407 return class;
409 case Y_REG:
410 if (GET_MODE_SIZE(mode) > 1)
411 return class;
412 else
413 return YH_REG;
415 case ACCUM_OR_Y_REGS:
416 if (GET_MODE_SIZE(mode) > 1)
417 return class;
418 else
419 return YL_OR_ACCUM_LOW_REGS;
421 case PH_REG:
422 case X_OR_PH_REGS:
423 case PL_REG:
424 case PL_OR_ACCUM_LOW_REGS:
425 case X_OR_PL_REGS:
426 return class;
428 case P_REG:
429 if (GET_MODE_SIZE(mode) > 1)
430 return class;
431 else
432 return PL_REG;
434 case ACCUM_OR_P_REGS:
435 if (GET_MODE_SIZE(mode) > 1)
436 return class;
437 else
438 return PL_OR_ACCUM_LOW_REGS;
440 case YL_OR_P_REGS:
441 case ACCUM_LOW_OR_YL_OR_P_REGS:
442 return class;
444 case Y_OR_P_REGS:
445 return class;
447 case ACCUM_Y_OR_P_REGS:
448 if (GET_MODE_SIZE(mode) > 1)
449 return class;
450 else
451 return ACCUM_LOW_OR_YL_OR_P_REGS;
453 case NO_FRAME_Y_ADDR_REGS:
454 case Y_ADDR_REGS:
455 case ACCUM_LOW_OR_Y_ADDR_REGS:
456 return class;
458 case ACCUM_OR_Y_ADDR_REGS:
459 if (GET_MODE_SIZE(mode) > 1)
460 return ACCUM_REGS;
461 else
462 return ACCUM_LOW_OR_Y_ADDR_REGS;
464 case X_OR_Y_ADDR_REGS:
465 return class;
467 case Y_OR_Y_ADDR_REGS:
468 case P_OR_Y_ADDR_REGS:
469 case NON_HIGH_YBASE_ELIGIBLE_REGS:
471 case J_REG:
472 return class;
474 case YBASE_ELIGIBLE_REGS:
475 if (GET_MODE_SIZE(mode) > 1)
476 return ACCUM_Y_P_OR_YBASE_REGS;
477 else
478 return NON_HIGH_YBASE_ELIGIBLE_REGS;
480 case J_OR_DAU_16_BIT_REGS:
481 if (GET_MODE_SIZE(mode) == 1)
482 return J_REG;
483 else
484 return class;
486 case BMU_REGS:
487 case NOHIGH_NON_ADDR_REGS:
488 return class;
490 case NON_ADDR_REGS:
491 if (GET_MODE_SIZE(mode) > 1)
492 return class;
493 else
494 return NOHIGH_NON_ADDR_REGS;
496 case NOHIGH_NON_YBASE_REGS:
497 return class;
499 case NON_YBASE_REGS:
500 if (GET_MODE_SIZE(mode) > 1)
501 return class;
502 else
503 return NOHIGH_NON_YBASE_REGS;
505 case YBASE_VIRT_REGS:
506 case ACCUM_LOW_OR_YBASE_REGS:
507 return class;
509 case ACCUM_OR_YBASE_REGS:
510 if (GET_MODE_SIZE(mode) > 1)
511 return class;
512 else
513 return ACCUM_LOW_OR_YBASE_REGS;
515 case X_OR_YBASE_REGS:
516 return class;
518 case Y_OR_YBASE_REGS:
519 case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
520 case P_OR_YBASE_REGS:
521 return class;
523 case ACCUM_Y_P_OR_YBASE_REGS:
524 return ACCUM_LOW_YL_PL_OR_YBASE_REGS;
526 case Y_ADDR_OR_YBASE_REGS:
527 case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
528 return class;
530 case YBASE_OR_YBASE_ELIGIBLE_REGS:
531 if (GET_MODE_SIZE(mode) > 1)
532 return class;
533 else
534 return YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS;
536 case NO_HIGH_ALL_REGS:
537 return class;
539 case ALL_REGS:
540 if (GET_MODE_SIZE(mode) > 1)
541 return class;
542 else
543 return NO_HIGH_ALL_REGS;
545 default:
546 return class;
551 dsp16xx_register_move_cost (from, to)
552 enum reg_class from, to;
554 #if 0
555 if (from == NO_REGS || to == NO_REGS || (from == to))
556 return 2;
557 #endif
559 if (from == A0H_REG || from == A0L_REG || from == A0_REG ||
560 from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||
561 from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)
563 if (to == Y_REG || to == P_REG)
564 return 4;
565 else
566 return 2;
569 if (to == A0H_REG || to == A0L_REG || to == A0_REG ||
570 to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||
571 to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)
573 return 2;
576 #if 0
577 if (from == YBASE_VIRT_REGS)
579 if (to == X_REG || to == YH_REG || to == YL_REG ||
580 to == Y_REG || to == PL_REG || to == PH_REG ||
581 to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||
582 to == Y_OR_P_REGS)
584 return 2;
586 else
587 return 4;
590 if (to == YBASE_VIRT_REGS)
592 if (from == X_REG || from == YH_REG || from == YL_REG ||
593 from == Y_REG || from == PL_REG || from == PH_REG ||
594 from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||
595 from == Y_OR_P_REGS)
597 return 2;
599 else
600 return 4;
602 #endif
603 return 4;
606 /* Given an rtx X being reloaded into a reg required to be
607 in class CLASS, return the class of reg to actually use.
608 In general this is just CLASS; but on some machines
609 in some cases it is preferable to use a more restrictive class.
610 Also, we must ensure that a PLUS is reloaded either
611 into an accumulator or an address register. */
613 enum reg_class
614 preferred_reload_class (x, class)
615 rtx x;
616 enum reg_class class;
618 /* The ybase registers cannot have constants copied directly
619 to them. */
621 if (CONSTANT_P (x))
623 if (class == ALL_REGS)
624 return NON_YBASE_REGS;
627 if (class == ALL_REGS && REG_P (x) && !TARGET_RESERVE_YBASE
628 && IS_YBASE_REGISTER_WINDOW (REGNO(x)))
629 return YBASE_ELIGIBLE_REGS;
631 if (GET_CODE (x) == PLUS)
633 if (GET_MODE (x) == QImode
634 && REG_P (XEXP (x,0))
635 && (XEXP (x,0) == frame_pointer_rtx
636 || XEXP (x,0) == stack_pointer_rtx)
637 && (GET_CODE (XEXP (x,1)) == CONST_INT))
639 if (class == ACCUM_HIGH_REGS)
640 return class;
642 if (reg_class_subset_p (ACCUM_HIGH_REGS, class))
643 return ACCUM_HIGH_REGS;
645 /* We will use accumulator 'a1l' for reloading a
646 PLUS. We can only use one accumulator because
647 'reload_inqi' only allows one alternative to be
648 used. */
650 else if (class == ACCUM_LOW_REGS)
651 return A1L_REG;
652 else if (class == A0L_REG)
653 return NO_REGS;
654 else
655 return class;
658 if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
659 return Y_ADDR_REGS;
660 else
661 return class;
663 else if (GET_CODE (x) == MEM)
665 if (class == ALL_REGS)
667 #if 0
668 if (GET_MODE(x) == HImode)
669 return NO_ACCUM_NON_YBASE_REGS;
670 else
671 #endif
672 return NON_YBASE_REGS;
674 else
675 return class;
677 else
678 return class;
681 /* Return the register class of a scratch register needed to copy IN into
682 or out of a register in CLASS in MODE. If it can be done directly,
683 NO_REGS is returned. */
685 enum reg_class
686 secondary_reload_class (class, mode, in)
687 enum reg_class class;
688 enum machine_mode mode;
689 rtx in;
691 int regno = -1;
693 if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
694 regno = true_regnum (in);
696 if (class == ACCUM_HIGH_REGS
697 || class == ACCUM_LOW_REGS
698 || class == A1L_REG
699 || class == A0L_REG
700 || class == A1H_REG
701 || class == A0H_REG)
703 if (GET_CODE (in) == PLUS && mode == QImode)
705 rtx addr0 = XEXP (in, 0);
706 rtx addr1 = XEXP (in, 1);
708 /* If we are reloading a plus (reg:QI) (reg:QI)
709 we need an additional register. */
710 if (REG_P (addr0) && REG_P (addr1))
711 return NO_REGS;
715 /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
716 into anything. */
718 if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS ||
719 class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG ||
720 class == A1H_REG || class == A1_REG) ||
721 (regno >= REG_A0 && regno < REG_A1L + 1))
722 return NO_REGS;
724 /* We can copy the ybase registers into:
725 r0-r3, a0-a1, y, p, & x or the union of
726 any of these. */
728 if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
730 switch ((int) class)
732 case (int) X_REG:
733 case (int) X_OR_ACCUM_LOW_REGS:
734 case (int) X_OR_ACCUM_REGS:
735 case (int) YH_REG:
736 case (int) YH_OR_ACCUM_HIGH_REGS:
737 case (int) X_OR_YH_REGS:
738 case (int) YL_REG:
739 case (int) YL_OR_ACCUM_LOW_REGS:
740 case (int) X_OR_Y_REGS:
741 case (int) X_OR_YL_REGS:
742 case (int) Y_REG:
743 case (int) ACCUM_OR_Y_REGS:
744 case (int) PH_REG:
745 case (int) X_OR_PH_REGS:
746 case (int) PL_REG:
747 case (int) PL_OR_ACCUM_LOW_REGS:
748 case (int) X_OR_PL_REGS:
749 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
750 case (int) P_REG:
751 case (int) ACCUM_OR_P_REGS:
752 case (int) YL_OR_P_REGS:
753 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
754 case (int) Y_OR_P_REGS:
755 case (int) ACCUM_Y_OR_P_REGS:
756 case (int) Y_ADDR_REGS:
757 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
758 case (int) ACCUM_OR_Y_ADDR_REGS:
759 case (int) X_OR_Y_ADDR_REGS:
760 case (int) Y_OR_Y_ADDR_REGS:
761 case (int) P_OR_Y_ADDR_REGS:
762 case (int) YBASE_ELIGIBLE_REGS:
763 return NO_REGS;
765 default:
766 return ACCUM_HIGH_REGS;
770 /* We can copy r0-r3, a0-a1, y, & p
771 directly to the ybase registers. In addition
772 we can use any of the ybase virtual registers
773 as the secondary reload registers when copying
774 between any of these registers. */
776 if (!TARGET_RESERVE_YBASE && regno != -1)
778 switch (regno)
780 case REG_A0:
781 case REG_A0L:
782 case REG_A1:
783 case REG_A1L:
784 case REG_X:
785 case REG_Y:
786 case REG_YL:
787 case REG_PROD:
788 case REG_PRODL:
789 case REG_R0:
790 case REG_R1:
791 case REG_R2:
792 case REG_R3:
793 if (class == YBASE_VIRT_REGS)
794 return NO_REGS;
795 else
797 switch ((int) class)
799 case (int) X_REG:
800 case (int) X_OR_ACCUM_LOW_REGS:
801 case (int) X_OR_ACCUM_REGS:
802 case (int) YH_REG:
803 case (int) YH_OR_ACCUM_HIGH_REGS:
804 case (int) X_OR_YH_REGS:
805 case (int) YL_REG:
806 case (int) YL_OR_ACCUM_LOW_REGS:
807 case (int) X_OR_Y_REGS:
808 case (int) X_OR_YL_REGS:
809 case (int) Y_REG:
810 case (int) ACCUM_OR_Y_REGS:
811 case (int) PH_REG:
812 case (int) X_OR_PH_REGS:
813 case (int) PL_REG:
814 case (int) PL_OR_ACCUM_LOW_REGS:
815 case (int) X_OR_PL_REGS:
816 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
817 case (int) P_REG:
818 case (int) ACCUM_OR_P_REGS:
819 case (int) YL_OR_P_REGS:
820 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
821 case (int) Y_OR_P_REGS:
822 case (int) ACCUM_Y_OR_P_REGS:
823 case (int) Y_ADDR_REGS:
824 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
825 case (int) ACCUM_OR_Y_ADDR_REGS:
826 case (int) X_OR_Y_ADDR_REGS:
827 case (int) Y_OR_Y_ADDR_REGS:
828 case (int) P_OR_Y_ADDR_REGS:
829 case (int) YBASE_ELIGIBLE_REGS:
830 return YBASE_VIRT_REGS;
832 default:
833 break;
839 /* Memory or constants can be moved from or to any register
840 except the ybase virtual registers */
841 if (regno == -1 && GET_CODE(in) != PLUS)
843 if (class == YBASE_VIRT_REGS)
844 return NON_YBASE_REGS;
845 else
846 return NO_REGS;
849 if (GET_CODE (in) == PLUS && mode == QImode)
851 rtx addr0 = XEXP (in, 0);
852 rtx addr1 = XEXP (in, 1);
854 /* If we are reloading a plus (reg:QI) (reg:QI)
855 we need a low accumulator, not a high one. */
856 if (REG_P (addr0) && REG_P (addr1))
857 return ACCUM_LOW_REGS;
860 #if 0
861 if (REG_P(in))
862 return ACCUM_REGS;
863 #endif
865 /* Otherwise, we need a high accumulator(s). */
866 return ACCUM_HIGH_REGS;
870 symbolic_address_operand (op, mode)
871 rtx op;
872 enum machine_mode mode;
874 return (symbolic_address_p (op));
878 int symbolic_address_p (op)
879 rtx op;
881 switch (GET_CODE (op))
883 case SYMBOL_REF:
884 case LABEL_REF:
885 return 1;
887 case CONST:
888 op = XEXP (op, 0);
889 return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
890 || GET_CODE (XEXP (op, 0)) == LABEL_REF)
891 && GET_CODE (XEXP (op, 1)) == CONST_INT
892 && INTVAL (XEXP (op,1)) < 0x20);
894 default:
895 return 0;
899 /* For a Y address space operand we allow only *rn, *rn++, *rn--.
900 This routine only recognizes *rn, the '<>' constraints recognize
901 *rn++, *rn-- */
904 Y_address_operand (op, mode)
905 rtx op;
906 enum machine_mode mode;
908 return (memory_address_p (mode, op) && !symbolic_address_p (op));
912 sp_operand (op, mode)
913 rtx op;
914 enum machine_mode mode;
916 return (GET_CODE (op) == PLUS
917 && (XEXP (op, 0) == stack_pointer_rtx
918 || XEXP (op, 0) == frame_pointer_rtx)
919 && GET_CODE (XEXP (op,1)) == CONST_INT);
923 sp_operand2 (op, mode)
924 rtx op;
925 enum machine_mode mode;
927 if ((GET_CODE (op) == PLUS
928 && (XEXP (op, 0) == stack_pointer_rtx
929 || XEXP (op, 0) == frame_pointer_rtx)
930 && (REG_P (XEXP (op,1))
931 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
932 return 1;
933 else if ((GET_CODE (op) == PLUS
934 && (XEXP (op, 1) == stack_pointer_rtx
935 || XEXP (op, 1) == frame_pointer_rtx)
936 && (REG_P (XEXP (op,0))
937 && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
938 return 1;
939 else
940 return 0;
944 nonmemory_arith_operand (op, mode)
945 rtx op;
946 enum machine_mode mode;
948 return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
952 arith_reg_operand (op, mode)
953 rtx op;
954 enum machine_mode mode;
956 return (register_operand (op, mode)
957 && (GET_CODE (op) != REG
958 || REGNO (op) >= FIRST_PSEUDO_REGISTER
959 || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op)))
960 && REGNO (op) != FRAME_POINTER_REGNUM)));
964 call_address_operand (op, mode)
965 rtx op;
966 enum machine_mode mode;
968 if (symbolic_address_p (op) || REG_P(op))
970 return 1;
973 return 0;
977 dsp16xx_comparison_operator (op, mode)
978 register rtx op;
979 enum machine_mode mode;
981 return ((mode == VOIDmode || GET_MODE (op) == mode)
982 && GET_RTX_CLASS (GET_CODE (op)) == '<'
983 && (GET_CODE(op) != GE && GET_CODE (op) != LT &&
984 GET_CODE (op) != GEU && GET_CODE (op) != LTU));
987 void
988 notice_update_cc(exp)
989 rtx exp;
991 if (GET_CODE (exp) == SET)
993 /* Jumps do not alter the cc's. */
995 if (SET_DEST (exp) == pc_rtx)
996 return;
998 /* Moving register or memory into a register:
999 it doesn't alter the cc's, but it might invalidate
1000 the RTX's which we remember the cc's came from.
1001 (Note that moving a constant 0 or 1 MAY set the cc's). */
1002 if (REG_P (SET_DEST (exp))
1003 && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
1005 if (cc_status.value1
1006 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1007 cc_status.value1 = 0;
1008 if (cc_status.value2
1009 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1010 cc_status.value2 = 0;
1011 return;
1013 /* Moving register into memory doesn't alter the cc's.
1014 It may invalidate the RTX's which we remember the cc's came from. */
1015 if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
1017 if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1018 cc_status.value1 = 0;
1019 if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1020 cc_status.value2 = 0;
1021 return;
1023 /* Function calls clobber the cc's. */
1024 else if (GET_CODE (SET_SRC (exp)) == CALL)
1026 CC_STATUS_INIT;
1027 return;
1029 /* Tests and compares set the cc's in predictable ways. */
1030 else if (SET_DEST (exp) == cc0_rtx)
1032 CC_STATUS_INIT;
1033 cc_status.value1 = SET_SRC (exp);
1034 return;
1036 /* Certain instructions effect the condition codes. */
1037 else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT)
1038 switch( GET_CODE (SET_SRC (exp)) )
1040 case PLUS:
1041 case MINUS:
1042 if (REG_P (SET_DEST (exp)))
1044 /* Address registers don't set the condition codes */
1045 if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp))))
1047 CC_STATUS_INIT;
1048 break;
1051 case ASHIFTRT:
1052 case LSHIFTRT:
1053 case ASHIFT:
1054 case AND:
1055 case IOR:
1056 case XOR:
1057 case MULT:
1058 case NEG:
1059 case NOT:
1060 cc_status.value1 = SET_SRC (exp);
1061 cc_status.value2 = SET_DEST (exp);
1062 break;
1064 default:
1065 CC_STATUS_INIT;
1067 else
1069 CC_STATUS_INIT;
1072 else if (GET_CODE (exp) == PARALLEL
1073 && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1075 if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1076 return;
1078 if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1080 CC_STATUS_INIT;
1081 cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1082 return;
1085 CC_STATUS_INIT;
1087 else
1089 CC_STATUS_INIT;
1094 dsp16xx_makes_calls ()
1096 rtx insn;
1098 for (insn = get_insns (); insn; insn = next_insn (insn))
1099 if (GET_CODE (insn) == CALL_INSN)
1100 return (1);
1102 return 0;
1105 long compute_frame_size (size)
1106 int size;
1108 long total_size;
1109 long var_size;
1110 long args_size;
1111 long extra_size;
1112 long reg_size;
1114 reg_size = 0;
1115 extra_size = 0;
1116 var_size = size;
1117 args_size = current_function_outgoing_args_size;
1118 reg_size = reg_save_size ();
1120 total_size = var_size + args_size + extra_size + reg_size;
1123 /* Save other computed information. */
1124 current_frame_info.total_size = total_size;
1125 current_frame_info.var_size = var_size;
1126 current_frame_info.args_size = args_size;
1127 current_frame_info.extra_size = extra_size;
1128 current_frame_info.reg_size = reg_size;
1129 current_frame_info.initialized = reload_completed;
1130 current_frame_info.reg_size = reg_size / UNITS_PER_WORD;
1131 current_frame_info.function_makes_calls = dsp16xx_makes_calls ();
1133 if (reg_size)
1135 unsigned long offset = args_size + var_size + reg_size;
1136 current_frame_info.sp_save_offset = offset;
1137 current_frame_info.fp_save_offset = offset - total_size;
1140 return total_size;
1144 dsp16xx_call_saved_register (regno)
1145 int regno;
1147 return (regs_ever_live[regno] && !call_used_regs[regno] &&
1148 !IS_YBASE_REGISTER_WINDOW(regno));
1153 ybase_regs_ever_used ()
1155 int regno;
1156 int live = 0;
1158 for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
1159 if (regs_ever_live[regno])
1161 live = 1;
1162 break;
1165 return live;
1168 void
1169 function_prologue (file, size)
1170 FILE *file;
1171 int size;
1173 int regno;
1174 long total_size;
1175 fp = reg_names[FRAME_POINTER_REGNUM];
1176 sp = reg_names[STACK_POINTER_REGNUM];
1177 rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */
1178 a1h = reg_names[REG_A1];
1180 total_size = compute_frame_size (size);
1182 fprintf( file, "\t/* FUNCTION PROLOGUE: */\n" );
1183 fprintf (file, "\t/* total=%d, vars= %d, regs= %d, args=%d, extra= %d */\n",
1184 current_frame_info.total_size,
1185 current_frame_info.var_size,
1186 current_frame_info.reg_size,
1187 current_function_outgoing_args_size,
1188 current_frame_info.extra_size);
1190 fprintf (file, "\t/* fp save offset= %d, sp save_offset= %d */\n\n",
1191 current_frame_info.fp_save_offset,
1192 current_frame_info.sp_save_offset);
1193 /* Set up the 'ybase' register window. */
1195 if (ybase_regs_ever_used())
1197 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1198 if (TARGET_YBASE_HIGH)
1199 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1200 else
1201 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1202 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1205 #if 0
1206 if (current_frame_info.function_makes_calls)
1207 fprintf( file, "\t*%s++=%s\n", sp, rr ); /* Push return address */
1208 #endif
1211 if (current_frame_info.var_size)
1213 if (current_frame_info.var_size == 1)
1214 fprintf (file, "\t*%s++\n", sp);
1215 else
1217 if(SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0))
1218 fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]);
1219 else
1220 fatal ("Stack size > 32k");
1224 /* Save any registers this function uses, unless they are
1225 * used in a call, in which case we don't need to
1228 for( regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno )
1229 if (dsp16xx_call_saved_register (regno))
1231 #if OLD_REGISTER_SAVE
1232 fprintf( file, "\t*%s++=%s\n", sp, reg_names[regno] );
1233 #else
1234 fprintf( file, "\tpush(*%s)=%s\n", sp, reg_names[regno] );
1235 #endif
1238 if (current_frame_info.args_size)
1240 if (current_frame_info.args_size == 1)
1241 fprintf (file, "\t*%s++\n", sp);
1242 else
1244 if(SMALL_INTVAL(current_frame_info.args_size) && ((current_frame_info.args_size & 0x8000) == 0))
1245 fprintf (file, "\t%s=%d\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.args_size, sp, reg_names[REG_J]);
1246 else
1247 fatal ("Stack size > 32k");
1251 if (frame_pointer_needed)
1253 fprintf( file, "\t%s=%s\n", a1h, sp );
1254 fprintf( file, "\t%s=%s\n", fp, a1h ); /* Establish new base frame */
1255 fprintf( file, "\t%s=%d\n", reg_names[REG_J], -total_size);
1256 fprintf( file, "\t*%s++%s\n", fp, reg_names[REG_J]);
1259 fprintf( file, "\t/* END FUNCTION PROLOGUE: */\n\n" );
1262 void
1263 init_emulation_routines ()
1265 dsp16xx_addhf3_libcall = (rtx) 0;
1266 dsp16xx_subhf3_libcall = (rtx) 0;
1267 dsp16xx_mulhf3_libcall = (rtx) 0;
1268 dsp16xx_divhf3_libcall = (rtx) 0;
1269 dsp16xx_cmphf3_libcall = (rtx) 0;
1270 dsp16xx_fixhfhi2_libcall = (rtx) 0;
1271 dsp16xx_floathihf2_libcall = (rtx) 0;
1272 dsp16xx_neghf2_libcall = (rtx) 0;
1274 dsp16xx_mulhi3_libcall = (rtx) 0;
1275 dsp16xx_udivqi3_libcall = (rtx) 0;
1276 dsp16xx_udivhi3_libcall = (rtx) 0;
1277 dsp16xx_divqi3_libcall = (rtx) 0;
1278 dsp16xx_divhi3_libcall = (rtx) 0;
1279 dsp16xx_modqi3_libcall = (rtx) 0;
1280 dsp16xx_modhi3_libcall = (rtx) 0;
1281 dsp16xx_umodqi3_libcall = (rtx) 0;
1282 dsp16xx_umodhi3_libcall = (rtx) 0;
1283 dsp16xx_ashrhi3_libcall = (rtx) 0;
1284 dsp16xx_ashlhi3_libcall = (rtx) 0;
1285 dsp16xx_ucmphi2_libcall = (rtx) 0;
1286 dsp16xx_lshrhi3_libcall = (rtx) 0;
1289 void
1290 function_epilogue (file, size)
1291 FILE *file;
1292 int size;
1294 int regno;
1295 int initial_stack_dec = 0;
1297 fp = reg_names[FRAME_POINTER_REGNUM];
1298 sp = reg_names[STACK_POINTER_REGNUM];
1299 rr = reg_names[RETURN_ADDRESS_REGNUM]; /* return address register */
1300 a1h = reg_names[REG_A1];
1302 fprintf( file, "\n\t/* FUNCTION EPILOGUE: */\n" );
1304 if (current_frame_info.args_size)
1306 if (current_frame_info.args_size == 1)
1307 fprintf (file, "\t*%s--\n", sp);
1308 else
1310 fprintf (file, "\t%s=%d\n\t*%s++%s\n",
1311 reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]);
1315 if (ybase_regs_ever_used())
1317 fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1318 if (TARGET_YBASE_HIGH)
1319 fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1320 else
1321 fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1322 fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1325 for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
1326 if (dsp16xx_call_saved_register(regno))
1328 #if OLD_REGISTER_SAVE
1329 if (!initial_stack_dec)
1331 initial_stack_dec = 1;
1332 fprintf (file, "\t*%s--\n", sp);
1334 #endif
1336 #if OLD_REGISTER_SAVE
1337 fprintf( file, "\t%s=*%s--\n", reg_names[regno], sp );
1338 #else
1339 fprintf( file, "\t%s=pop(*%s)\n", reg_names[regno], sp );
1340 #endif
1343 /* If we restored any registers we have to account for the
1344 initial pre-decrement. But only if we had any local variables
1345 or spills. */
1346 #if OLD_REGISTER_SAVE
1347 if (initial_stack_dec)
1348 fprintf (file, "\t*%s++\n", sp);
1349 #endif
1351 if (current_frame_info.var_size)
1353 if (current_frame_info.var_size == 1)
1354 fprintf (file, "\t*%s--\n", sp);
1355 else
1357 fprintf (file, "\t%s=%d\n\t*%s++%s\n",
1358 reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]);
1362 fprintf (file, "\treturn\n");
1363 /* Reset the frame info for the next function */
1364 current_frame_info = zero_frame_info;
1365 init_emulation_routines ();
1368 /* Emit insns to move operands[1] into operands[0].
1370 Return 1 if we have written out everything that needs to be done to
1371 do the move. Otherwise, return 0 and the caller will emit the move
1372 normally. */
1375 emit_move_sequence (operands, mode)
1376 rtx *operands;
1377 enum machine_mode mode;
1379 register rtx operand0 = operands[0];
1380 register rtx operand1 = operands[1];
1382 /* We can only store registers to memory. */
1384 if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
1385 operands[1] = force_reg (mode, operand1);
1387 return 0;
1390 void
1391 double_reg_from_memory (operands)
1392 rtx operands[];
1394 rtx xoperands[4];
1396 if (GET_CODE(XEXP(operands[1],0)) == POST_INC)
1398 output_asm_insn ("%u0=%1", operands);
1399 output_asm_insn ("%w0=%1", operands);
1401 else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC)
1403 xoperands[1] = XEXP (XEXP (operands[1], 0), 0);
1404 xoperands[0] = operands[0];
1406 /* We can't use j anymore since the compiler can allocate it. */
1407 /* output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */
1408 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands);
1410 else if (GET_CODE(XEXP(operands[1],0)) == PLUS)
1412 rtx addr;
1413 rtx base;
1414 int offset;
1416 output_asm_insn ("%u0=%1", operands);
1419 /* In order to print out the least significant word we must
1420 use 'offset + 1'. */
1421 addr = XEXP (operands[1], 0);
1422 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1423 offset = INTVAL(XEXP(addr,0)) + 1;
1424 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1425 offset = INTVAL(XEXP(addr,1)) + 1;
1427 fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31);
1429 else
1431 xoperands[1] = XEXP(operands[1],0);
1432 xoperands[0] = operands[0];
1434 output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
1439 void
1440 double_reg_to_memory (operands)
1441 rtx operands[];
1443 rtx xoperands[4];
1445 if (GET_CODE(XEXP(operands[0],0)) == POST_INC)
1447 output_asm_insn ("%0=%u1", operands);
1448 output_asm_insn ("%0=%w1", operands);
1450 else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC)
1452 xoperands[0] = XEXP (XEXP (operands[0], 0), 0);
1453 xoperands[1] = operands[1];
1455 /* We can't use j anymore since the compiler can allocate it. */
1457 /* output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */
1458 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands);
1461 else if (GET_CODE(XEXP(operands[0],0)) == PLUS)
1463 rtx addr;
1464 int offset;
1466 output_asm_insn ("%0=%u1", operands);
1468 /* In order to print out the least significant word we must
1469 use 'offset + 1'. */
1470 addr = XEXP (operands[0], 0);
1471 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1472 offset = INTVAL(XEXP(addr,0)) + 1;
1473 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1474 offset = INTVAL(XEXP(addr,1)) + 1;
1475 else
1476 fatal ("Invalid addressing mode");
1478 fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
1480 else
1482 xoperands[0] = XEXP(operands[0],0);
1483 xoperands[1] = operands[1];
1485 output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
1489 void
1490 override_options ()
1492 if (chip_name == (char *) 0)
1493 chip_name = DEFAULT_CHIP_NAME;
1495 if (text_seg_name == (char *) 0)
1496 text_seg_name = DEFAULT_TEXT_SEG_NAME;
1498 if (data_seg_name == (char *) 0)
1499 data_seg_name = DEFAULT_DATA_SEG_NAME;
1501 if (bss_seg_name == (char *) 0)
1502 bss_seg_name = DEFAULT_BSS_SEG_NAME;
1504 if (const_seg_name == (char *) 0)
1505 const_seg_name = DEFAULT_CONST_SEG_NAME;
1507 save_chip_name = (char *) xmalloc (strlen(chip_name) + 1);
1508 strcpy (save_chip_name, chip_name);
1510 rsect_text = (char *) xmalloc (strlen(".rsect ") +
1511 strlen(text_seg_name) + 3);
1512 rsect_data = (char *) xmalloc (strlen(".rsect ") +
1513 strlen(data_seg_name) + 3);
1514 rsect_bss = (char *) xmalloc (strlen(".rsect ") +
1515 strlen(bss_seg_name) + 3);
1516 rsect_const = (char *) xmalloc (strlen(".rsect ") +
1517 strlen(const_seg_name) + 3);
1519 sprintf (rsect_text, ".rsect \"%s\"", text_seg_name);
1520 sprintf (rsect_data, ".rsect \"%s\"", data_seg_name);
1521 sprintf (rsect_bss, ".rsect \"%s\"", bss_seg_name);
1522 sprintf (rsect_const, ".rsect \"%s\"", const_seg_name);
1524 if (optimize)
1526 if (TARGET_OPTIMIZE_SPEED)
1528 flag_unroll_loops = 1;
1529 flag_inline_functions = 1;
1534 enum rtx_code save_next_cc_user_code;
1536 enum rtx_code
1537 next_cc_user_code (insn)
1538 rtx insn;
1540 if ( !(insn = next_cc0_user (insn)))
1541 abort ();
1542 else if (GET_CODE (insn) == JUMP_INSN
1543 && GET_CODE (PATTERN (insn)) == SET
1544 && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
1545 return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
1546 else if (GET_CODE (insn) == INSN
1547 && GET_CODE (PATTERN (insn)) == SET
1548 && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode))
1549 return GET_CODE (SET_SRC (PATTERN (insn)));
1550 else
1551 abort ();
1554 void
1555 print_operand(file, op, letter)
1556 FILE *file;
1557 rtx op;
1558 int letter;
1560 enum rtx_code code;
1562 code = GET_CODE(op);
1564 switch (letter)
1566 case 'I':
1567 code = reverse_condition (code);
1568 /* Fallthrough */
1570 case 'C':
1571 if (code == EQ)
1573 fputs ("eq", file);
1574 return;
1576 else if (code == NE)
1578 fputs ("ne", file);
1579 return;
1581 else if (code == GT || code == GTU)
1583 fputs ("gt", file);
1584 return;
1586 else if (code == LT || code == LTU)
1588 fputs ("mi", file);
1589 return;
1591 else if (code == GE || code == GEU)
1593 fputs ("pl", file);
1594 return;
1596 else if (code == LE || code == LEU)
1598 fputs ("le", file);
1599 return;
1601 else
1602 abort ();
1603 break;
1605 default:
1606 break;
1609 if( code == REG )
1611 /* Print the low half of a 32-bit register pair */
1612 if (letter == 'w')
1613 fprintf( file, "%s", reg_names[REGNO(op)+1] );
1614 else if (letter == 'u' || !letter)
1615 fprintf( file, "%s", reg_names[REGNO(op)]);
1616 else if (letter == 'b')
1617 fprintf ( file, "%sh", reg_names[REGNO(op)]);
1618 else if (letter == 'm')
1619 fprintf (file, "%s", himode_reg_name[REGNO(op)]);
1620 else
1621 fatal("Bad register extension code");
1623 else if( code == MEM )
1624 output_address( XEXP(op,0) );
1625 else if( code == CONST_INT )
1627 if( letter == 'H' )
1628 fprintf( file, "0x%x", (INTVAL(op) & 0xffff) );
1629 else if (letter == 'h')
1630 fprintf( file, "%d", INTVAL (op) );
1631 else if( letter == 'U' )
1632 fprintf( file, "0x%x", ((INTVAL(op) & 0xffff0000) >> 16) & 0xffff );
1633 else
1634 output_addr_const( file, op );
1636 else if( code == CONST_DOUBLE && GET_MODE(op) != DImode )
1638 union { double d; int i[2]; } u;
1639 union { float f; int i; } u1;
1640 u.i[0] = CONST_DOUBLE_LOW (op);
1641 u.i[1] = CONST_DOUBLE_HIGH (op);
1642 u1.f = u.d;
1643 fprintf( file, "0x%x", u1.i );
1645 else output_addr_const( file, op);
1649 void
1650 print_operand_address(file, addr)
1651 FILE *file;
1652 rtx addr;
1654 rtx base;
1655 int offset;
1657 switch (GET_CODE (addr))
1659 case REG:
1660 fprintf (file, "*%s", reg_names[REGNO (addr)]);
1661 break;
1662 case POST_DEC:
1663 fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
1664 break;
1665 case POST_INC:
1666 fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
1667 break;
1668 case PLUS:
1669 if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1670 offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1);
1671 else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1672 offset = INTVAL(XEXP(addr,1)), base = XEXP(addr,0);
1673 if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
1675 if (offset >= -31 && offset <= 0)
1676 offset = 31 + offset;
1677 else
1678 fatal ("Invalid offset in ybase addressing");
1680 else
1681 fatal ("Invalid register in ybase addressing");
1683 fprintf (file, "*(%d)", offset);
1684 break;
1686 default:
1687 if( FITS_5_BITS( addr ) )
1688 fprintf( file, "*(0x%x)", (INTVAL(addr) & 0x20) );
1689 else
1690 output_addr_const(file, addr);
1694 void
1695 output_dsp16xx_float_const(operands)
1696 rtx *operands;
1698 rtx dst = operands[0];
1699 rtx src = operands[1];
1701 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
1702 REAL_VALUE_TYPE d;
1703 long value;
1705 REAL_VALUE_FROM_CONST_DOUBLE (d, src);
1706 REAL_VALUE_TO_TARGET_SINGLE (d, value);
1708 operands[1] = gen_rtx (CONST_INT, VOIDmode, value);
1709 output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands);
1710 #else
1711 fatal ("inline float constants not supported on this host");
1712 #endif
1716 reg_save_size ()
1718 int reg_save_size = 0;
1719 int regno;
1721 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1722 if (dsp16xx_call_saved_register (regno))
1724 reg_save_size += UNITS_PER_WORD;
1727 return (reg_save_size);
1731 dsp16xx_starting_frame_offset()
1733 int reg_save_size = 0;
1734 int regno;
1736 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1737 if (dsp16xx_call_saved_register (regno))
1739 reg_save_size += UNITS_PER_WORD;
1742 return (reg_save_size);
1746 initial_frame_pointer_offset()
1748 int frame_size;
1749 int regno;
1750 int offset = 0;
1752 offset = compute_frame_size (get_frame_size());
1754 #ifdef STACK_GROWS_DOWNWARD
1755 return (offset);
1756 #else
1757 return (-offset);
1758 #endif
1761 /* Generate the minimum number of 1600 core shift instructions
1762 to shift by 'shift_amount'. */
1764 #if 0
1765 void
1766 emit_1600_core_shift (shift_op, operands, shift_amount, mode)
1767 enum rtx_code shift_op;
1768 rtx *operands;
1769 int shift_amount;
1770 enum machine_mode mode;
1772 int quotient;
1773 int i;
1774 int first_shift_emitted = 0;
1776 while (shift_amount != 0)
1778 if (shift_amount/16)
1780 quotient = shift_amount/16;
1781 shift_amount = shift_amount - (quotient * 16);
1782 for (i = 0; i < quotient; i++)
1783 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1784 gen_rtx (shift_op, mode,
1785 first_shift_emitted ? operands[0] : operands[1],
1786 gen_rtx (CONST_INT, VOIDmode, 16))));
1787 first_shift_emitted = 1;
1789 else if (shift_amount/8)
1791 quotient = shift_amount/8;
1792 shift_amount = shift_amount - (quotient * 8);
1793 for (i = 0; i < quotient; i++)
1794 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1795 gen_rtx (shift_op, mode,
1796 first_shift_emitted ? operands[0] : operands[1],
1797 gen_rtx (CONST_INT, VOIDmode, 8))));
1798 first_shift_emitted = 1;
1800 else if (shift_amount/4)
1802 quotient = shift_amount/4;
1803 shift_amount = shift_amount - (quotient * 4);
1804 for (i = 0; i < quotient; i++)
1805 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1806 gen_rtx (shift_op, mode,
1807 first_shift_emitted ? operands[0] : operands[1],
1808 gen_rtx (CONST_INT, VOIDmode, 4))));
1809 first_shift_emitted = 1;
1811 else if (shift_amount/1)
1813 quotient = shift_amount/1;
1814 shift_amount = shift_amount - (quotient * 1);
1815 for (i = 0; i < quotient; i++)
1816 emit_insn (gen_rtx (SET, VOIDmode, operands[0],
1817 gen_rtx (shift_op, mode,
1818 first_shift_emitted ? operands[0] : operands[1],
1819 gen_rtx (CONST_INT, VOIDmode, 1))));
1820 first_shift_emitted = 1;
1824 #else
1825 void
1826 emit_1600_core_shift (shift_op, operands, shift_amount)
1827 enum rtx_code shift_op;
1828 rtx *operands;
1829 int shift_amount;
1831 int quotient;
1832 int i;
1833 int first_shift_emitted = 0;
1834 char **shift_asm_ptr;
1835 char **shift_asm_ptr_first;
1837 if (shift_op == ASHIFT)
1839 shift_asm_ptr = ashift_left_asm;
1840 shift_asm_ptr_first = ashift_left_asm_first;
1842 else if (shift_op == ASHIFTRT)
1844 shift_asm_ptr = ashift_right_asm;
1845 shift_asm_ptr_first = ashift_right_asm_first;
1847 else if (shift_op == LSHIFTRT)
1849 shift_asm_ptr = lshift_right_asm;
1850 shift_asm_ptr_first = lshift_right_asm_first;
1852 else
1853 fatal ("Invalid shift operator in emit_1600_core_shift");
1855 while (shift_amount != 0)
1857 if (shift_amount/16)
1859 quotient = shift_amount/16;
1860 shift_amount = shift_amount - (quotient * 16);
1861 for (i = 0; i < quotient; i++)
1862 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_16]
1863 : shift_asm_ptr_first[SHIFT_INDEX_16]), operands);
1864 first_shift_emitted = 1;
1866 else if (shift_amount/8)
1868 quotient = shift_amount/8;
1869 shift_amount = shift_amount - (quotient * 8);
1870 for (i = 0; i < quotient; i++)
1871 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_8]
1872 : shift_asm_ptr_first[SHIFT_INDEX_8]), operands);
1873 first_shift_emitted = 1;
1875 else if (shift_amount/4)
1877 quotient = shift_amount/4;
1878 shift_amount = shift_amount - (quotient * 4);
1879 for (i = 0; i < quotient; i++)
1880 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_4]
1881 : shift_asm_ptr_first[SHIFT_INDEX_4]), operands);
1882 first_shift_emitted = 1;
1884 else if (shift_amount/1)
1886 quotient = shift_amount/1;
1887 shift_amount = shift_amount - (quotient * 1);
1888 for (i = 0; i < quotient; i++)
1889 output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_1]
1890 : shift_asm_ptr_first[SHIFT_INDEX_1]), operands);
1891 first_shift_emitted = 1;
1895 #endif
1896 void
1897 asm_output_common(file, name, size, rounded)
1898 FILE *file;
1899 char *name;
1900 int size;
1901 int rounded;
1903 bss_section ();
1904 ASM_GLOBALIZE_LABEL (file, name);
1905 assemble_name (file, name);
1906 fputs (":", file);
1907 if (rounded > 1)
1908 fprintf (file, "%d * int\n", rounded);
1909 else
1910 fprintf (file, "int\n");
1913 void
1914 asm_output_local(file, name, size, rounded)
1915 FILE *file;
1916 char *name;
1917 int size;
1918 int rounded;
1920 bss_section ();
1921 assemble_name (file, name);
1922 fputs (":", file);
1923 if (rounded > 1)
1924 fprintf (file, "%d * int\n", rounded);
1925 else
1926 fprintf (file, "int\n");
1929 void
1930 asm_output_float (file, fp_const)
1931 FILE *file;
1932 double fp_const;
1934 #if HOST_FLOAT_FORMAT == TARGET_FLOAT_FORMAT
1935 REAL_VALUE_TYPE d = fp_const;
1936 long value;
1938 REAL_VALUE_TO_TARGET_SINGLE (d, value);
1939 fputs ("\tint ", file);
1940 #ifdef WORDS_BIG_ENDIAN
1941 fprintf (file, "0x%-4.4x, 0x%-4.4x", (value >> 16) & 0xffff, (value & 0xffff));
1942 #else
1943 fprintf (file, "0x%-4.4x, 0x%-4.4x", (value & 0xffff), (value >> 16) & 0xffff);
1944 #endif
1945 fputs ("\n", file);
1946 #else
1947 fatal ("inline float constants not supported on this host");
1948 #endif
1951 void
1952 asm_output_long (file, value)
1953 FILE *file;
1954 long value;
1956 fputs ("\tint ", file);
1957 #ifdef WORDS_BIG_ENDIAN
1958 fprintf (file, "0x%-4.4x, 0x%-4.4x", (value >> 16) & 0xffff, (value & 0xffff));
1959 #else
1960 fprintf (file, "0x%-4.4x, 0x%-4.4x", (value & 0xffff), (value >> 16) & 0xffff);
1961 #endif
1962 fputs ("\n", file);
1966 dsp16xx_address_cost (addr)
1967 rtx addr;
1969 switch (GET_CODE (addr))
1971 default:
1972 break;
1974 case REG:
1975 return 1;
1977 case CONST:
1979 rtx offset = const0_rtx;
1980 addr = eliminate_constant_term (addr, &offset);
1982 if (GET_CODE (addr) == LABEL_REF)
1983 return 2;
1985 if (GET_CODE (addr) != SYMBOL_REF)
1986 return 4;
1988 if (INTVAL (offset) == 0)
1989 return 2;
1991 /* fall through */
1993 case POST_INC: case POST_DEC:
1994 return (GET_MODE (addr) == QImode ? 1 : 2);
1996 case SYMBOL_REF: case LABEL_REF:
1997 return 2;
1999 case PLUS:
2001 register rtx plus0 = XEXP (addr, 0);
2002 register rtx plus1 = XEXP (addr, 1);
2004 if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
2006 plus0 = XEXP (addr, 1);
2007 plus1 = XEXP (addr, 0);
2010 if (GET_CODE (plus0) != REG)
2011 break;
2013 switch (GET_CODE (plus1))
2015 default:
2016 break;
2018 case CONST_INT:
2019 return 4;
2021 case CONST:
2022 case SYMBOL_REF:
2023 case LABEL_REF:
2024 return dsp16xx_address_cost (plus1) + 1;
2029 return 4;
2033 /* Determine whether a function argument is passed in a register, and
2034 which register.
2036 The arguments are CUM, which summarizes all the previous
2037 arguments; MODE, the machine mode of the argument; TYPE,
2038 the data type of the argument as a tree node or 0 if that is not known
2039 (which happens for C support library functions); and NAMED,
2040 which is 1 for an ordinary argument and 0 for nameless arguments that
2041 correspond to `...' in the called function's prototype.
2043 The value of the expression should either be a `reg' RTX for the
2044 hard register in which to pass the argument, or zero to pass the
2045 argument on the stack.
2047 On the dsp1610 the first four words of args are normally in registers
2048 and the rest are pushed. If we a long or on float mode, the argument
2049 must begin on a even register boundary
2051 Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2052 For structures that are passed in memory, but could have been
2053 passed in registers, we first load the structure into the
2054 register, and then when the last argument is passed, we store
2055 the registers into the stack locations. This fixes some bugs
2056 where GCC did not expect to have register arguments, followed */
2059 struct rtx_def *
2060 dsp16xx_function_arg (args_so_far, mode, type, named)
2061 CUMULATIVE_ARGS args_so_far;
2062 enum machine_mode mode;
2063 tree type;
2064 int named;
2066 if (TARGET_REGPARM)
2068 if ((args_so_far & 1) != 0
2069 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2070 args_so_far++;
2072 if (named && args_so_far < 4 && !MUST_PASS_IN_STACK (mode,type))
2073 return gen_rtx (REG, mode, args_so_far + FIRST_REG_FOR_FUNCTION_ARG);
2074 else
2075 return (struct rtx_def *) 0;
2077 else
2078 return (struct rtx_def *) 0;
2081 /* Advance the argument to the next argument position. */
2083 void
2084 dsp16xx_function_arg_advance (cum, mode, type, named)
2085 CUMULATIVE_ARGS *cum; /* current arg information */
2086 enum machine_mode mode; /* current arg mode */
2087 tree type; /* type of the argument or 0 if lib support */
2088 int named; /* whether or not the argument was named */
2090 if (TARGET_REGPARM)
2092 if ((*cum & 1) != 0
2093 && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2094 *cum += 1;
2096 if (mode != BLKmode)
2097 *cum += GET_MODE_SIZE (mode);
2098 else
2099 *cum += int_size_in_bytes (type);
2103 void
2104 dsp16xx_file_start ()
2106 fprintf (asm_out_file, "#include <%s.h>\n", save_chip_name);
2107 #if 0
2108 if (TARGET_BMU)
2109 fprintf (asm_out_file, "#include <1610.h>\n");
2110 #endif
2114 gen_tst_reg (x)
2115 rtx x;
2117 enum machine_mode mode;
2119 mode = GET_MODE (x);
2121 if (mode == QImode)
2123 emit_insn (gen_rtx (PARALLEL, VOIDmode,
2124 gen_rtvec (2,
2125 gen_rtx (SET, VOIDmode, cc0_rtx, x),
2126 gen_rtx (CLOBBER, VOIDmode,
2127 gen_rtx (SCRATCH, QImode, 0)))));
2129 else if (mode == HImode)
2130 emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx, x));
2131 else
2132 fatal ("Invalid mode for gen_tst_reg");
2134 return cc0_rtx;
2138 gen_compare_reg (code, x, y)
2139 enum rtx_code code;
2140 rtx x, y;
2142 enum machine_mode mode;
2144 mode = GET_MODE (x);
2145 /* For floating point compare insns, a call is generated so don't
2146 do anything here. */
2148 if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2149 return cc0_rtx;
2151 if (mode == QImode)
2153 if (code == GTU || code == GEU ||
2154 code == LTU || code == LEU)
2156 emit_insn (gen_rtx (PARALLEL, VOIDmode,
2157 gen_rtvec (3,
2158 gen_rtx (SET, VOIDmode, cc0_rtx,
2159 gen_rtx (COMPARE, mode, x, y)),
2160 gen_rtx (CLOBBER, VOIDmode,
2161 gen_rtx (SCRATCH, QImode, 0)),
2162 gen_rtx (CLOBBER, VOIDmode,
2163 gen_rtx (SCRATCH, QImode, 0)))));
2165 else
2167 emit_insn (gen_rtx (PARALLEL, VOIDmode,
2168 gen_rtvec (3,
2169 gen_rtx (SET, VOIDmode, cc0_rtx,
2170 gen_rtx (COMPARE, mode, x, y)),
2171 gen_rtx (CLOBBER, VOIDmode,
2172 gen_rtx (SCRATCH, QImode, 0)),
2173 gen_rtx (CLOBBER, VOIDmode,
2174 gen_rtx (SCRATCH, QImode, 0)))));
2177 else if (mode == HImode)
2179 if (code == GTU || code == GEU ||
2180 code == LTU || code == LEU)
2182 #if 1
2183 emit_insn (gen_rtx (PARALLEL, VOIDmode, gen_rtvec (5,
2184 gen_rtx (SET, VOIDmode, cc0_rtx, gen_rtx (COMPARE, VOIDmode, x, y)),
2185 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)),
2186 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)),
2187 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)),
2188 gen_rtx (CLOBBER, VOIDmode, gen_rtx (SCRATCH, QImode, 0)))));
2189 #else
2190 if (!dsp16xx_ucmphi2_libcall)
2191 dsp16xx_ucmphi2_libcall = gen_rtx (SYMBOL_REF, Pmode, UCMPHI2_LIBCALL);
2192 emit_library_call (dsp16xx_ucmphi2_libcall, 1, HImode, 2,
2193 x, HImode, y, HImode);
2194 emit_insn (gen_tsthi_1 (copy_to_reg(hard_libcall_value (HImode))));
2195 #endif
2197 else
2198 emit_insn (gen_rtx (SET, VOIDmode, cc0_rtx,
2199 gen_rtx (COMPARE, VOIDmode, force_reg(HImode, x),
2200 force_reg(HImode,y))));
2202 else
2203 fatal ("Invalid mode for integer comparison in gen_compare_reg");
2205 return cc0_rtx;
2208 char *
2209 output_block_move (operands)
2210 rtx operands[];
2212 int loop_count = INTVAL(operands[2]);
2213 rtx xoperands[4];
2215 fprintf (asm_out_file, "\tdo %d {\n", loop_count);
2216 xoperands[0] = operands[4];
2217 xoperands[1] = operands[1];
2218 output_asm_insn ("%0=*%1++", xoperands);
2220 xoperands[0] = operands[0];
2221 xoperands[1] = operands[4];
2222 output_asm_insn ("*%0++=%1", xoperands);
2224 fprintf (asm_out_file, "\t}\n");
2225 return "";