OSDN Git Service

2003-01-29 Joel Sherrill <joel@OARcorp.com>
[pf3gnuchains/gcc-fork.git] / gcc / config / dsp16xx / dsp16xx.c
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).
4
5 This file is part of GNU CC.
6
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.
11
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.
16
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.  */
21
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"
45
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;
54
55 const char *chip_name;
56 const char *save_chip_name;
57
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.  */
60
61 rtx dsp16xx_compare_op0;
62 rtx dsp16xx_compare_op1;
63 bool dsp16xx_compare_gen;
64
65 static const char *fp;
66 static const char *sp;
67 static const char *rr;
68 static const char *a1h;
69
70 struct dsp16xx_frame_info current_frame_info;
71 struct dsp16xx_frame_info zero_frame_info;
72
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;
81
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;
95
96 static const char *const himode_reg_name[] = HIMODE_REGISTER_NAMES;
97
98 #define SHIFT_INDEX_1   0
99 #define SHIFT_INDEX_4   1
100 #define SHIFT_INDEX_8   2
101 #define SHIFT_INDEX_16  3
102
103 static const char *const ashift_right_asm[] = 
104 {
105   "%0=%0>>1",
106   "%0=%0>>4",
107   "%0=%0>>8",
108   "%0=%0>>16"
109 };
110
111 static const char *const ashift_right_asm_first[] = 
112 {
113   "%0=%1>>1",
114   "%0=%1>>4",
115   "%0=%1>>8",
116   "%0=%1>>16"
117 };
118
119 static const char *const ashift_left_asm[] = 
120 {
121   "%0=%0<<1",
122   "%0=%0<<4",
123   "%0=%0<<8",
124   "%0=%0<<16"
125 };
126
127 static const char *const ashift_left_asm_first[] = 
128 {
129   "%0=%1<<1",
130   "%0=%1<<4",
131   "%0=%1<<8",
132   "%0=%1<<16"
133 };
134
135 static const char *const lshift_right_asm[] = 
136 {
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"
141 };
142
143 static const char *const lshift_right_asm_first[] = 
144 {
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"
149 };
150
151 static int reg_save_size PARAMS ((void));
152 static void dsp16xx_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
153 static void dsp16xx_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
154 static bool dsp16xx_rtx_costs PARAMS ((rtx, int, int, int *));
155 static int dsp16xx_address_cost PARAMS ((rtx));
156 \f
157 /* Initialize the GCC target structure.  */
158
159 #undef TARGET_ASM_BYTE_OP
160 #define TARGET_ASM_BYTE_OP "\tint\t"
161 #undef TARGET_ASM_ALIGNED_HI_OP
162 #define TARGET_ASM_ALIGNED_HI_OP NULL
163 #undef TARGET_ASM_ALIGNED_SI_OP
164 #define TARGET_ASM_ALIGNED_SI_OP NULL
165
166 #undef TARGET_ASM_FUNCTION_PROLOGUE
167 #define TARGET_ASM_FUNCTION_PROLOGUE dsp16xx_output_function_prologue
168 #undef TARGET_ASM_FUNCTION_EPILOGUE
169 #define TARGET_ASM_FUNCTION_EPILOGUE dsp16xx_output_function_epilogue
170
171 #undef TARGET_RTX_COSTS
172 #define TARGET_RTX_COSTS dsp16xx_rtx_costs
173 #undef TARGET_ADDRESS_COST
174 #define TARGET_ADDRESS_COST dsp16xx_address_cost
175
176 struct gcc_target targetm = TARGET_INITIALIZER;
177
178 int 
179 hard_regno_mode_ok (regno, mode)
180      int regno;
181      enum machine_mode mode;
182 {
183   switch ((int) mode)
184     {
185     case VOIDmode:
186       return 1;
187       
188       /* We can't use the c0-c2 for QImode, since they are only
189          8 bits in length.  */
190
191     case QImode:
192       if (regno != REG_C0 && regno != REG_C1 && regno != REG_C2)
193         return 1;
194       else
195         return 0;
196       
197       /* We only allow a0, a1, y, and p to be allocated for 32-bit modes.
198          Additionally we allow the virtual ybase registers to be used for 32-bit
199          modes.  */
200       
201     case HFmode:
202     case SFmode:
203     case DFmode:
204     case XFmode:
205     case HImode:
206     case SImode:
207     case DImode:
208       if (regno == REG_A0 || regno == REG_A1 || regno == REG_Y || regno == REG_PROD
209           || (IS_YBASE_REGISTER_WINDOW(regno) && ((regno & 1) == 0)))
210         return 1;
211       else
212         return 0;
213       
214     default:
215       return 0;
216     }
217 }
218
219 enum reg_class
220 dsp16xx_reg_class_from_letter (c)
221      int c;
222 {
223   switch (c)
224     {
225     case 'A':
226       return ACCUM_REGS;
227
228     case 'l':
229       return A0_REG;
230
231     case 'C':
232       return A1_REG;
233       
234     case 'h':
235       return ACCUM_HIGH_REGS;
236       
237     case 'j':
238       return A0H_REG;
239       
240     case 'k':
241       return A0L_REG;
242       
243     case 'q':
244       return A1H_REG;
245       
246     case 'u':
247       return A1L_REG;
248       
249     case 'x':
250       return X_REG;
251
252     case 'y':
253       return YH_REG;
254
255     case 'z':
256       return YL_REG;
257
258     case 't':
259       return P_REG;
260
261     case 'Z':
262       return Y_OR_P_REGS;
263
264     case 'd':
265       return ACCUM_Y_OR_P_REGS;
266
267     case 'a':
268       return Y_ADDR_REGS;
269
270     case 'B':
271       return (TARGET_BMU ? BMU_REGS : NO_REGS);
272
273     case 'Y':
274       return YBASE_VIRT_REGS;
275
276     case 'v':
277       return PH_REG;
278
279     case 'w':
280       return PL_REG;
281
282     case 'W':
283       return J_REG;
284
285     case 'e':
286       return YBASE_ELIGIBLE_REGS;
287
288     case 'b':
289       return ACCUM_LOW_REGS;
290
291     case 'c':
292       return NON_YBASE_REGS;
293
294     case 'f':
295       return Y_REG;
296
297     case 'D':
298       return SLOW_MEM_LOAD_REGS;
299
300     default:
301       return NO_REGS;
302     }
303 }
304
305 /* Return the class number of the smallest class containing
306    reg number REGNO.  */
307
308 int 
309 regno_reg_class(regno)
310      int regno;
311 {
312   switch (regno)
313     {
314     case REG_A0L:
315       return (int) A0L_REG;
316     case REG_A1L:
317       return (int) A1L_REG;
318       
319     case REG_A0:
320       return (int) A0H_REG;
321     case REG_A1:
322       return (int) A1H_REG;
323       
324     case REG_X:
325       return (int) X_REG;
326       
327     case REG_Y:
328       return (int) YH_REG;
329     case REG_YL:
330       return (int) YL_REG;
331       
332     case REG_PROD:
333       return (int) PH_REG;
334     case REG_PRODL:
335       return (int) PL_REG;
336       
337     case REG_R0: case REG_R1: case REG_R2: case REG_R3:
338       return (int) Y_ADDR_REGS;
339       
340     case REG_J:
341       return (int) J_REG;
342     case REG_K:
343       return (int) GENERAL_REGS;
344       
345     case REG_YBASE:
346       return (int) GENERAL_REGS;
347       
348     case REG_PT:
349       return (int) GENERAL_REGS;
350       
351     case REG_AR0: case REG_AR1: case REG_AR2: case REG_AR3:
352       return (int) BMU_REGS;
353       
354     case REG_C0: case REG_C1: case REG_C2:
355       return (int) GENERAL_REGS;
356       
357     case REG_PR:
358       return (int) GENERAL_REGS;
359       
360     case REG_RB:
361       return (int) GENERAL_REGS;
362       
363     case REG_YBASE0: case REG_YBASE1: case REG_YBASE2: case REG_YBASE3:
364     case REG_YBASE4: case REG_YBASE5: case REG_YBASE6: case REG_YBASE7:
365     case REG_YBASE8: case REG_YBASE9: case REG_YBASE10: case REG_YBASE11:
366     case REG_YBASE12: case REG_YBASE13: case REG_YBASE14: case REG_YBASE15:
367     case REG_YBASE16: case REG_YBASE17: case REG_YBASE18: case REG_YBASE19:
368     case REG_YBASE20: case REG_YBASE21: case REG_YBASE22: case REG_YBASE23:
369     case REG_YBASE24: case REG_YBASE25: case REG_YBASE26: case REG_YBASE27:
370     case REG_YBASE28: case REG_YBASE29: case REG_YBASE30: case REG_YBASE31:
371       return (int) YBASE_VIRT_REGS;
372       
373     default:
374       return (int) NO_REGS;
375     }
376 }
377
378 /* A C expression for the maximum number of consecutive registers of class CLASS
379    needed to hold a value of mode MODE.  */
380
381 int
382 class_max_nregs(class, mode)
383      enum reg_class class ATTRIBUTE_UNUSED;
384      enum machine_mode mode;
385 {
386     return (GET_MODE_SIZE(mode));
387 }
388
389 enum reg_class
390 limit_reload_class (mode, class)
391      enum machine_mode mode ATTRIBUTE_UNUSED;
392      enum reg_class class;
393 {
394   return class;
395 }
396
397 int
398 dsp16xx_register_move_cost (from, to)
399      enum reg_class from, to;
400 {
401   if (from == A0H_REG || from == A0L_REG || from == A0_REG ||
402       from == A1H_REG || from == ACCUM_HIGH_REGS || from == A1L_REG ||
403       from == ACCUM_LOW_REGS || from == A1_REG || from == ACCUM_REGS)
404     {
405       if (to == Y_REG || to == P_REG)
406         return 4;
407       else
408         return 2;
409     }
410
411   if (to == A0H_REG || to == A0L_REG || to == A0_REG ||
412       to == A1H_REG || to == ACCUM_HIGH_REGS || to == A1L_REG ||
413       to == ACCUM_LOW_REGS || to == A1_REG || to == ACCUM_REGS)
414     {
415       return 2;
416     }
417
418   if (from == YBASE_VIRT_REGS)
419     {
420       if (to == YBASE_VIRT_REGS)
421         return 16;
422
423       if (to == X_REG || to == YH_REG || to == YL_REG ||
424           to == Y_REG || to == PL_REG || to == PH_REG ||
425           to == P_REG || to == Y_ADDR_REGS || to == YBASE_ELIGIBLE_REGS ||
426           to == Y_OR_P_REGS)
427         {
428           return 8;
429         }
430       else
431         return 10;
432     }
433
434   if (to == YBASE_VIRT_REGS)
435     {
436       if (from == X_REG || from == YH_REG || from == YL_REG ||
437           from == Y_REG || from == PL_REG || from == PH_REG ||
438           from == P_REG || from == Y_ADDR_REGS || from == YBASE_ELIGIBLE_REGS ||
439           from == Y_OR_P_REGS)
440         {
441           return 8;
442         }
443       else
444         return 10;
445     }
446
447   return 8;
448 }
449
450 /* Given an rtx X being reloaded into a reg required to be
451    in class CLASS, return the class of reg to actually use.
452    In general this is just CLASS; but on some machines
453    in some cases it is preferable to use a more restrictive class.
454    Also, we must ensure that a PLUS is reloaded either
455    into an accumulator or an address register.  */
456
457 enum reg_class
458 preferred_reload_class (x, class)
459      rtx x;
460      enum reg_class class;
461 {
462   /* The ybase registers cannot have constants copied directly
463      to them.  */
464
465   if (CONSTANT_P (x))
466     {
467       switch ((int) class)
468         {
469         case YBASE_VIRT_REGS:
470           return (!reload_in_progress ? NO_REGS : class);
471
472         case ACCUM_LOW_OR_YBASE_REGS:
473           return ACCUM_LOW_REGS;
474
475         case ACCUM_OR_YBASE_REGS:
476           return ACCUM_REGS;
477
478         case X_OR_YBASE_REGS:
479           return X_REG;
480
481         case Y_OR_YBASE_REGS:
482           return Y_REG;
483
484         case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
485           return YL_OR_PL_OR_ACCUM_LOW_REGS;
486
487         case P_OR_YBASE_REGS:
488           return P_REG;
489
490         case ACCUM_Y_P_OR_YBASE_REGS:
491           return ACCUM_Y_OR_P_REGS;
492
493         case Y_ADDR_OR_YBASE_REGS:
494           return Y_ADDR_REGS;
495
496         case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
497           return NON_HIGH_YBASE_ELIGIBLE_REGS;;
498           
499         case YBASE_OR_YBASE_ELIGIBLE_REGS:
500           return YBASE_ELIGIBLE_REGS;
501
502         case NO_HIGH_ALL_REGS:
503           return NOHIGH_NON_YBASE_REGS;
504
505         case ALL_REGS:
506           return NON_YBASE_REGS;
507
508         default:
509           return class;
510         }
511     }
512
513   /* If x is not an accumulator or a ybase register, restrict the class of registers
514      we can copy the register into.  */
515
516   if (REG_P (x) && !IS_ACCUM_REG (REGNO (x)) && !IS_YBASE_REGISTER_WINDOW (REGNO (x)))
517     {
518       switch ((int) class)
519         {
520         case NO_REGS:
521         case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
522         case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS: 
523         case A1_REG: case ACCUM_REGS:
524           return class;
525
526         case X_REG: 
527           return (!reload_in_progress ? NO_REGS : class);
528
529         case X_OR_ACCUM_LOW_REGS: 
530           return ACCUM_LOW_REGS;
531
532         case X_OR_ACCUM_REGS:
533           return ACCUM_REGS;
534
535         case YH_REG:
536           return (!reload_in_progress ? NO_REGS : class);
537
538         case YH_OR_ACCUM_HIGH_REGS:
539           return ACCUM_HIGH_REGS;
540
541         case X_OR_YH_REGS: 
542         case YL_REG:
543           return (!reload_in_progress ? NO_REGS : class);
544
545         case YL_OR_ACCUM_LOW_REGS: 
546           return ACCUM_LOW_REGS;
547
548         case X_OR_YL_REGS:
549         case X_OR_Y_REGS: case Y_REG:
550           return (!reload_in_progress ? NO_REGS : class);
551
552         case ACCUM_OR_Y_REGS: 
553           return ACCUM_REGS;
554
555         case PH_REG:
556         case X_OR_PH_REGS: case PL_REG: 
557           return (!reload_in_progress ? NO_REGS : class);
558
559         case PL_OR_ACCUM_LOW_REGS:
560           return ACCUM_LOW_REGS;
561
562         case X_OR_PL_REGS:
563           return (!reload_in_progress ? NO_REGS : class);
564
565         case YL_OR_PL_OR_ACCUM_LOW_REGS: 
566           return ACCUM_LOW_REGS;
567
568         case P_REG:
569           return (!reload_in_progress ? NO_REGS : class);
570
571         case ACCUM_OR_P_REGS: 
572           return ACCUM_REGS;
573
574         case YL_OR_P_REGS:
575           return (!reload_in_progress ? NO_REGS : class);
576
577         case ACCUM_LOW_OR_YL_OR_P_REGS: 
578           return ACCUM_LOW_REGS;
579
580         case Y_OR_P_REGS:
581           return (!reload_in_progress ? NO_REGS : class);
582
583         case ACCUM_Y_OR_P_REGS: 
584           return ACCUM_REGS;
585
586         case NO_FRAME_Y_ADDR_REGS:
587         case Y_ADDR_REGS:
588           return (!reload_in_progress ? NO_REGS : class);
589
590         case ACCUM_LOW_OR_Y_ADDR_REGS:
591           return ACCUM_LOW_REGS;
592
593         case ACCUM_OR_Y_ADDR_REGS: 
594           return ACCUM_REGS;
595
596         case X_OR_Y_ADDR_REGS:
597         case Y_OR_Y_ADDR_REGS: 
598         case P_OR_Y_ADDR_REGS:
599           return (!reload_in_progress ? NO_REGS : class);
600
601         case NON_HIGH_YBASE_ELIGIBLE_REGS: 
602           return ACCUM_LOW_REGS;
603
604         case YBASE_ELIGIBLE_REGS:
605           return ACCUM_REGS;
606
607         case J_REG:
608         case J_OR_DAU_16_BIT_REGS:
609         case BMU_REGS: 
610           return (!reload_in_progress ? NO_REGS : class);
611
612         case YBASE_VIRT_REGS:
613           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
614             return class;
615           else
616             return (!reload_in_progress ? NO_REGS : class);
617
618         case ACCUM_LOW_OR_YBASE_REGS:
619           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
620             return class;
621           else
622             return ACCUM_LOW_REGS;
623
624         case ACCUM_OR_YBASE_REGS:
625           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
626             return class;
627           else
628             return ACCUM_REGS;
629
630         case X_OR_YBASE_REGS:
631         case Y_OR_YBASE_REGS:
632           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
633             return YBASE_VIRT_REGS;
634           else
635             return (!reload_in_progress ? NO_REGS : class);
636
637         case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
638           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
639             return ACCUM_LOW_OR_YBASE_REGS;
640           else
641             return ACCUM_LOW_REGS;
642
643         case P_OR_YBASE_REGS:
644           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
645             return YBASE_VIRT_REGS;
646           else
647             return (!reload_in_progress ? NO_REGS : class);
648
649         case ACCUM_Y_P_OR_YBASE_REGS:
650           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
651             return ACCUM_OR_YBASE_REGS;
652           else
653             return ACCUM_REGS;
654
655         case Y_ADDR_OR_YBASE_REGS:
656           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
657             return YBASE_VIRT_REGS;
658           else
659             return (!reload_in_progress ? NO_REGS : class);
660
661         case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
662           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
663             return ACCUM_LOW_OR_YBASE_REGS;
664           else
665             return ACCUM_LOW_REGS;
666
667         case YBASE_OR_YBASE_ELIGIBLE_REGS:
668           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
669             return ACCUM_OR_YBASE_REGS;
670           else
671             return ACCUM_REGS;
672
673         case NO_HIGH_ALL_REGS:
674           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
675             return ACCUM_LOW_OR_YBASE_REGS;
676           else
677             return ACCUM_LOW_REGS;
678
679         case ALL_REGS: 
680           if (IS_YBASE_ELIGIBLE_REG (REGNO (x)))
681             return ACCUM_OR_YBASE_REGS;
682           else
683             return ACCUM_REGS;
684
685         case NOHIGH_NON_ADDR_REGS:
686             return ACCUM_LOW_REGS;
687
688         case NON_ADDR_REGS:
689         case SLOW_MEM_LOAD_REGS:
690             return ACCUM_REGS;
691
692         case NOHIGH_NON_YBASE_REGS:
693             return ACCUM_LOW_REGS;
694
695         case NO_ACCUM_NON_YBASE_REGS:
696           return (!reload_in_progress ? NO_REGS : class);
697
698         case NON_YBASE_REGS:
699             return ACCUM_REGS;
700
701         default:
702           return class;
703         }
704     }
705
706   /* If x (the input) is a ybase register, restrict the class of registers
707      we can copy the register into.  */
708
709   if (REG_P (x) && !TARGET_RESERVE_YBASE
710       && IS_YBASE_REGISTER_WINDOW (REGNO(x)))
711     {
712       switch ((int) class)
713         {
714         case NO_REGS:
715         case A0H_REG: case A0L_REG: case A0_REG: case A1H_REG:
716         case ACCUM_HIGH_REGS: case A1L_REG: case ACCUM_LOW_REGS: 
717         case A1_REG: case ACCUM_REGS: case X_REG: 
718         case X_OR_ACCUM_LOW_REGS: case X_OR_ACCUM_REGS:
719         case YH_REG: case YH_OR_ACCUM_HIGH_REGS:
720         case X_OR_YH_REGS: case YL_REG:
721         case YL_OR_ACCUM_LOW_REGS: case X_OR_YL_REGS:
722         case X_OR_Y_REGS: case Y_REG:
723         case ACCUM_OR_Y_REGS: case PH_REG:
724         case X_OR_PH_REGS: case PL_REG: 
725         case PL_OR_ACCUM_LOW_REGS: case X_OR_PL_REGS:
726         case YL_OR_PL_OR_ACCUM_LOW_REGS: case P_REG:
727         case ACCUM_OR_P_REGS: case YL_OR_P_REGS:
728         case ACCUM_LOW_OR_YL_OR_P_REGS: case Y_OR_P_REGS:
729         case ACCUM_Y_OR_P_REGS: case NO_FRAME_Y_ADDR_REGS:
730         case Y_ADDR_REGS: case ACCUM_LOW_OR_Y_ADDR_REGS:
731         case ACCUM_OR_Y_ADDR_REGS: case X_OR_Y_ADDR_REGS:
732         case Y_OR_Y_ADDR_REGS: case P_OR_Y_ADDR_REGS:
733         case NON_HIGH_YBASE_ELIGIBLE_REGS: case YBASE_ELIGIBLE_REGS:
734         default:
735           return class;
736
737         case J_REG:
738           return (!reload_in_progress ? NO_REGS : class);
739
740         case J_OR_DAU_16_BIT_REGS:
741           return ACCUM_HIGH_REGS;
742
743         case BMU_REGS: 
744         case YBASE_VIRT_REGS:
745           return (!reload_in_progress ? NO_REGS : class);
746
747         case ACCUM_LOW_OR_YBASE_REGS:
748           return ACCUM_LOW_REGS;
749
750         case ACCUM_OR_YBASE_REGS:
751           return ACCUM_REGS;
752
753         case X_OR_YBASE_REGS:
754           return X_REG;
755
756         case Y_OR_YBASE_REGS:
757           return Y_REG;
758
759         case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
760           return YL_OR_PL_OR_ACCUM_LOW_REGS; 
761
762         case P_OR_YBASE_REGS:
763           return P_REG;
764
765         case ACCUM_Y_P_OR_YBASE_REGS:
766           return ACCUM_Y_OR_P_REGS;
767
768         case Y_ADDR_OR_YBASE_REGS:
769           return Y_ADDR_REGS;
770
771         case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
772           return NON_HIGH_YBASE_ELIGIBLE_REGS;
773
774         case YBASE_OR_YBASE_ELIGIBLE_REGS:
775           return YBASE_ELIGIBLE_REGS;
776
777         case NO_HIGH_ALL_REGS:
778           return NON_HIGH_YBASE_ELIGIBLE_REGS;
779
780         case ALL_REGS: 
781           return YBASE_ELIGIBLE_REGS;
782
783         case NOHIGH_NON_ADDR_REGS:
784           return ACCUM_LOW_OR_YL_OR_P_REGS;
785
786         case NON_ADDR_REGS:
787           return ACCUM_Y_OR_P_REGS;
788
789         case SLOW_MEM_LOAD_REGS:
790           return ACCUM_OR_Y_ADDR_REGS;
791
792         case NOHIGH_NON_YBASE_REGS:
793           return NON_HIGH_YBASE_ELIGIBLE_REGS;
794
795         case NO_ACCUM_NON_YBASE_REGS:
796           return Y_ADDR_REGS;
797
798         case NON_YBASE_REGS:
799           return YBASE_ELIGIBLE_REGS;
800         }
801     }
802
803   if (GET_CODE (x) == PLUS)
804     {
805       if (GET_MODE (x) == QImode
806           && REG_P (XEXP (x,0))
807           && (XEXP (x,0) == frame_pointer_rtx
808               || XEXP (x,0) == stack_pointer_rtx)
809           && (GET_CODE (XEXP (x,1)) == CONST_INT))
810         {
811           if (class == ACCUM_HIGH_REGS)
812             return class;
813
814           /* If the accumulators are not part of the class
815              being reloaded into, return NO_REGS.  */
816 #if 0
817           if (!reg_class_subset_p (ACCUM_REGS, class))
818             return (!reload_in_progress ? NO_REGS : class);
819 #endif
820           if (reg_class_subset_p (ACCUM_HIGH_REGS, class))
821             return ACCUM_HIGH_REGS;
822
823           /* We will use accumulator 'a1l' for reloading a
824              PLUS.  We can only use one accumulator because
825              'reload_inqi' only allows one alternative to be
826              used.  */
827
828           else if (class == ACCUM_LOW_REGS)
829             return A1L_REG;
830           else if (class == A0L_REG)
831             return NO_REGS;
832           else
833             return class;
834         }
835
836       if (class == NON_YBASE_REGS || class == YBASE_ELIGIBLE_REGS)
837         return Y_ADDR_REGS;
838       else
839         return class;
840     }
841   else if (GET_CODE (x) == MEM)
842     {
843       /* We can't copy from a memory location into a
844          ybase register.  */
845       if (reg_class_subset_p(YBASE_VIRT_REGS, class))
846         {
847           switch ((int) class)
848             {
849             case YBASE_VIRT_REGS:
850               return (!reload_in_progress ? NO_REGS : class);
851
852             case ACCUM_LOW_OR_YBASE_REGS:
853               return ACCUM_LOW_REGS;
854
855             case ACCUM_OR_YBASE_REGS:
856               return ACCUM_REGS;
857
858             case X_OR_YBASE_REGS:
859               return X_REG;
860
861             case Y_OR_YBASE_REGS:
862               return Y_REG;
863
864             case ACCUM_LOW_YL_PL_OR_YBASE_REGS:
865               return YL_OR_PL_OR_ACCUM_LOW_REGS;
866
867             case P_OR_YBASE_REGS:
868               return P_REG;
869
870             case ACCUM_Y_P_OR_YBASE_REGS:
871               return ACCUM_Y_OR_P_REGS;
872
873             case Y_ADDR_OR_YBASE_REGS:
874               return Y_ADDR_REGS;
875
876             case YBASE_OR_NOHIGH_YBASE_ELIGIBLE_REGS:
877               return NON_HIGH_YBASE_ELIGIBLE_REGS;
878           
879             case YBASE_OR_YBASE_ELIGIBLE_REGS:
880               return YBASE_ELIGIBLE_REGS;
881
882             case NO_HIGH_ALL_REGS:
883               return NOHIGH_NON_YBASE_REGS;
884
885             case ALL_REGS:
886               return NON_YBASE_REGS;
887
888             default:
889               return class;
890             }
891         }
892       else
893         return class;
894     }
895   else
896     return class;
897 }
898         
899 /* Return the register class of a scratch register needed to copy IN into
900    or out of a register in CLASS in MODE.  If it can be done directly,
901    NO_REGS is returned.  */
902
903 enum reg_class
904 secondary_reload_class (class, mode, in)
905      enum reg_class class;
906      enum machine_mode mode;
907      rtx in;
908 {
909   int regno = -1;
910
911   if (GET_CODE (in) == REG || GET_CODE (in) == SUBREG)
912     regno = true_regnum (in);
913
914   /* If we are reloading a plus into a high accumulator register,
915      we need a scratch low accumulator, because the low half gets
916      clobbered.  */
917
918   if (class == ACCUM_HIGH_REGS 
919       || class == A1H_REG
920       || class == A0H_REG)
921     {
922       if (GET_CODE (in) == PLUS && mode == QImode)
923         return ACCUM_LOW_REGS;
924     }
925
926   if (class == ACCUM_HIGH_REGS 
927       || class == ACCUM_LOW_REGS
928       || class == A1L_REG
929       || class == A0L_REG
930       || class == A1H_REG
931       || class == A0H_REG)
932     {
933       if (GET_CODE (in) == PLUS && mode == QImode)
934         {
935           rtx addr0 = XEXP (in, 0);
936           rtx addr1 = XEXP (in, 1);
937           
938           /* If we are reloading a plus (reg:QI) (reg:QI)
939              we need an additional register.  */ 
940           if (REG_P (addr0) && REG_P (addr1))
941             return NO_REGS;
942         }
943     }
944
945   /* We can place anything into ACCUM_REGS and can put ACCUM_REGS
946      into anything.  */
947
948   if ((class == ACCUM_REGS || class == ACCUM_HIGH_REGS ||
949        class == ACCUM_LOW_REGS || class == A0H_REG || class == A0L_REG ||
950        class == A1H_REG || class == A1_REG) || 
951       (regno >= REG_A0 && regno < REG_A1L + 1))
952     return NO_REGS;
953
954   if (class == ACCUM_OR_YBASE_REGS && REG_P(in)
955       && IS_YBASE_ELIGIBLE_REG(regno))
956     {
957       return NO_REGS;
958     }
959
960   /* We can copy the ybase registers into:
961      r0-r3, a0-a1, y, p, & x or the union of
962      any of these.  */
963
964   if (!TARGET_RESERVE_YBASE && IS_YBASE_REGISTER_WINDOW(regno))
965     {
966       switch ((int) class)
967         {
968         case (int) X_REG:
969         case (int) X_OR_ACCUM_LOW_REGS:
970         case (int) X_OR_ACCUM_REGS:
971         case (int) YH_REG:
972         case (int) YH_OR_ACCUM_HIGH_REGS:
973         case (int) X_OR_YH_REGS:
974         case (int) YL_REG:
975         case (int) YL_OR_ACCUM_LOW_REGS:
976         case (int) X_OR_Y_REGS:
977         case (int) X_OR_YL_REGS:
978         case (int) Y_REG:
979         case (int) ACCUM_OR_Y_REGS:
980         case (int) PH_REG:
981         case (int) X_OR_PH_REGS:
982         case (int) PL_REG:
983         case (int) PL_OR_ACCUM_LOW_REGS:
984         case (int) X_OR_PL_REGS:
985         case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
986         case (int) P_REG:
987         case (int) ACCUM_OR_P_REGS:
988         case (int) YL_OR_P_REGS:
989         case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
990         case (int) Y_OR_P_REGS:
991         case (int) ACCUM_Y_OR_P_REGS:
992         case (int) Y_ADDR_REGS:
993         case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
994         case (int) ACCUM_OR_Y_ADDR_REGS:
995         case (int) X_OR_Y_ADDR_REGS:
996         case (int) Y_OR_Y_ADDR_REGS:
997         case (int) P_OR_Y_ADDR_REGS:
998         case (int) YBASE_ELIGIBLE_REGS:
999           return NO_REGS;
1000
1001         default:
1002           return ACCUM_HIGH_REGS;
1003         }
1004     }
1005
1006   /* We can copy r0-r3, a0-a1, y, & p
1007      directly to the ybase registers. In addition
1008      we can use any of the ybase virtual registers
1009      as the secondary reload registers when copying
1010      between any of these registers.  */
1011
1012   if (!TARGET_RESERVE_YBASE && regno != -1)
1013     {
1014       switch (regno)
1015         {
1016         case REG_A0:
1017         case REG_A0L:
1018         case REG_A1:
1019         case REG_A1L:
1020         case REG_X:
1021         case REG_Y:
1022         case REG_YL:
1023         case REG_PROD:
1024         case REG_PRODL:
1025         case REG_R0:
1026         case REG_R1:
1027         case REG_R2:
1028         case REG_R3:
1029           if (class == YBASE_VIRT_REGS)
1030             return NO_REGS;
1031           else
1032             {
1033               switch ((int) class)
1034                 {
1035                 case (int) X_REG:
1036                 case (int) X_OR_ACCUM_LOW_REGS:
1037                 case (int) X_OR_ACCUM_REGS:
1038                 case (int) YH_REG:
1039                 case (int) YH_OR_ACCUM_HIGH_REGS:
1040                 case (int) X_OR_YH_REGS:
1041                 case (int) YL_REG:
1042                 case (int) YL_OR_ACCUM_LOW_REGS:
1043                 case (int) X_OR_Y_REGS:
1044                 case (int) X_OR_YL_REGS:
1045                 case (int) Y_REG:
1046                 case (int) ACCUM_OR_Y_REGS:
1047                 case (int) PH_REG:
1048                 case (int) X_OR_PH_REGS:
1049                 case (int) PL_REG:
1050                 case (int) PL_OR_ACCUM_LOW_REGS:
1051                 case (int) X_OR_PL_REGS:
1052                 case (int) YL_OR_PL_OR_ACCUM_LOW_REGS:
1053                 case (int) P_REG:
1054                 case (int) ACCUM_OR_P_REGS:
1055                 case (int) YL_OR_P_REGS:
1056                 case (int) ACCUM_LOW_OR_YL_OR_P_REGS:
1057                 case (int) Y_OR_P_REGS:
1058                 case (int) ACCUM_Y_OR_P_REGS:
1059                 case (int) Y_ADDR_REGS:
1060                 case (int) ACCUM_LOW_OR_Y_ADDR_REGS:
1061                 case (int) ACCUM_OR_Y_ADDR_REGS:
1062                 case (int) X_OR_Y_ADDR_REGS:
1063                 case (int) Y_OR_Y_ADDR_REGS:
1064                 case (int) P_OR_Y_ADDR_REGS:
1065                 case (int) YBASE_ELIGIBLE_REGS:
1066                   return YBASE_VIRT_REGS;
1067
1068                 default:
1069                   break;
1070                 }
1071             }
1072         }
1073     }
1074
1075   /* Memory or constants can be moved from or to any register
1076      except the ybase virtual registers.  */
1077   if (regno == -1 && GET_CODE(in) != PLUS)
1078     {
1079       if (class == YBASE_VIRT_REGS)
1080         return NON_YBASE_REGS;
1081       else
1082         return NO_REGS;
1083     }
1084
1085   if (GET_CODE (in) == PLUS && mode == QImode)
1086     {
1087       rtx addr0 = XEXP (in, 0);
1088       rtx addr1 = XEXP (in, 1);
1089
1090       /* If we are reloading a plus (reg:QI) (reg:QI)
1091          we need a low accumulator, not a high one.  */
1092       if (REG_P (addr0) && REG_P (addr1))
1093         return ACCUM_LOW_REGS;
1094     }
1095
1096 #if 0
1097   if (REG_P(in))
1098     return ACCUM_REGS;
1099 #endif
1100
1101   /* Otherwise, we need a high accumulator(s).  */
1102   return ACCUM_HIGH_REGS;
1103 }
1104
1105 int
1106 symbolic_address_operand (op, mode)
1107      rtx op;
1108      enum machine_mode mode ATTRIBUTE_UNUSED;
1109 {
1110   return (symbolic_address_p (op));
1111 }
1112
1113 int
1114 symbolic_address_p (op)
1115      rtx op;
1116 {
1117   switch (GET_CODE (op))
1118     {
1119     case SYMBOL_REF:
1120     case LABEL_REF:
1121       return 1;
1122
1123     case CONST:
1124       op = XEXP (op, 0);
1125       return ((GET_CODE (XEXP (op, 0)) == SYMBOL_REF
1126                || GET_CODE (XEXP (op, 0)) == LABEL_REF)
1127               && GET_CODE (XEXP (op, 1)) == CONST_INT
1128               && INTVAL (XEXP (op,1)) < 0x20);
1129
1130     default:
1131       return 0;
1132     }
1133 }
1134
1135 /* For a Y address space operand we allow only *rn, *rn++, *rn--.
1136    This routine only recognizes *rn, the '<>' constraints recognize
1137    (*rn++), and (*rn--).  */
1138
1139 int
1140 Y_address_operand (op, mode)
1141      rtx op;
1142      enum machine_mode mode;
1143 {
1144   return (memory_address_p (mode, op) && !symbolic_address_p (op));
1145 }            
1146
1147 int
1148 sp_operand (op, mode)
1149      rtx op;
1150      enum machine_mode mode ATTRIBUTE_UNUSED;
1151 {
1152     return (GET_CODE (op) == PLUS
1153             && (XEXP (op, 0) == stack_pointer_rtx
1154                 || XEXP (op, 0) == frame_pointer_rtx)
1155             && GET_CODE (XEXP (op,1)) == CONST_INT);
1156 }
1157
1158 int
1159 sp_operand2 (op, mode)
1160      rtx op;
1161      enum machine_mode mode ATTRIBUTE_UNUSED;
1162 {
1163   if ((GET_CODE (op) == PLUS 
1164        && (XEXP (op, 0) == stack_pointer_rtx
1165            || XEXP (op, 0) == frame_pointer_rtx)
1166        && (REG_P (XEXP (op,1))
1167            && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
1168     return 1;
1169   else if ((GET_CODE (op) == PLUS
1170        && (XEXP (op, 1) == stack_pointer_rtx
1171            || XEXP (op, 1) == frame_pointer_rtx)
1172        && (REG_P (XEXP (op,0))
1173            && IS_ADDRESS_REGISTER (REGNO (XEXP(op, 1))))))
1174     return 1;
1175   else
1176     return 0;
1177 }
1178
1179 int
1180 nonmemory_arith_operand (op, mode)
1181      rtx op;
1182      enum machine_mode mode;
1183 {
1184   return (immediate_operand (op, mode) || arith_reg_operand (op, mode));
1185 }
1186
1187 int
1188 arith_reg_operand (op, mode)
1189      rtx op;
1190      enum machine_mode mode;
1191 {
1192   return (register_operand (op, mode)
1193           && (GET_CODE (op) != REG
1194               || REGNO (op) >= FIRST_PSEUDO_REGISTER
1195               || (!(IS_YBASE_REGISTER_WINDOW (REGNO (op)))
1196                   && REGNO (op) != FRAME_POINTER_REGNUM)));
1197 }
1198
1199 int
1200 call_address_operand (op, mode)
1201      rtx op;
1202      enum machine_mode mode ATTRIBUTE_UNUSED;
1203 {
1204     if (symbolic_address_p (op) || REG_P(op))
1205     {
1206         return 1;
1207     }
1208
1209     return 0;
1210 }
1211
1212 int
1213 dsp16xx_comparison_operator (op, mode)
1214     register rtx op;
1215     enum machine_mode mode;
1216 {
1217   return ((mode == VOIDmode || GET_MODE (op) == mode)
1218           && GET_RTX_CLASS (GET_CODE (op)) == '<'
1219           && (GET_CODE(op) != GE && GET_CODE (op) != LT &&
1220               GET_CODE (op) != GEU && GET_CODE (op) != LTU));
1221 }
1222
1223 void
1224 notice_update_cc(exp)
1225      rtx exp;
1226 {
1227     if (GET_CODE (exp) == SET)
1228     {
1229         /* Jumps do not alter the cc's.  */
1230
1231         if (SET_DEST (exp) == pc_rtx)
1232             return;
1233
1234         /* Moving register or memory into a register:
1235            it doesn't alter the cc's, but it might invalidate
1236            the RTX's which we remember the cc's came from.
1237            (Note that moving a constant 0 or 1 MAY set the cc's).  */
1238         if (REG_P (SET_DEST (exp))
1239             && (REG_P (SET_SRC (exp)) || GET_CODE (SET_SRC (exp)) == MEM))
1240         {
1241             if (cc_status.value1
1242                 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value1))
1243                 cc_status.value1 = 0;
1244             if (cc_status.value2
1245                 && reg_overlap_mentioned_p (SET_DEST (exp), cc_status.value2))
1246                 cc_status.value2 = 0;
1247             return;
1248         }
1249         /* Moving register into memory doesn't alter the cc's.
1250            It may invalidate the RTX's which we remember the cc's came from.  */
1251         if (GET_CODE (SET_DEST (exp)) == MEM && REG_P (SET_SRC (exp)))
1252         {
1253             if (cc_status.value1 && GET_CODE (cc_status.value1) == MEM)
1254                 cc_status.value1 = 0;
1255             if (cc_status.value2 && GET_CODE (cc_status.value2) == MEM)
1256                 cc_status.value2 = 0;
1257             return;
1258         }
1259         /* Function calls clobber the cc's.  */
1260         else if (GET_CODE (SET_SRC (exp)) == CALL)
1261         {
1262             CC_STATUS_INIT;
1263             return;
1264         }
1265         /* Tests and compares set the cc's in predictable ways.  */
1266         else if (SET_DEST (exp) == cc0_rtx)
1267         {
1268             CC_STATUS_INIT;
1269             cc_status.value1 = SET_SRC (exp);
1270             return;
1271         }
1272         /* Certain instructions effect the condition codes.  */
1273         else if (GET_MODE_CLASS (GET_MODE (SET_SRC (exp))) == MODE_INT)
1274             switch (GET_CODE (SET_SRC (exp)))
1275             {
1276             case PLUS: 
1277             case MINUS:
1278               if (REG_P (SET_DEST (exp)))
1279                 {
1280                   /* Address registers don't set the condition codes.  */
1281                   if (IS_ADDRESS_REGISTER (REGNO (SET_DEST (exp))))
1282                     {
1283                       CC_STATUS_INIT;
1284                       break;
1285                     }
1286                 }
1287             case ASHIFTRT: 
1288             case LSHIFTRT:
1289             case ASHIFT: 
1290             case AND: 
1291             case IOR: 
1292             case XOR:
1293             case MULT:
1294             case NEG:
1295             case NOT:
1296               cc_status.value1 = SET_SRC (exp);
1297               cc_status.value2 = SET_DEST (exp);
1298               break;
1299               
1300             default:
1301               CC_STATUS_INIT;
1302             }
1303         else
1304         {
1305             CC_STATUS_INIT;
1306         }
1307     }
1308     else if (GET_CODE (exp) == PARALLEL
1309              && GET_CODE (XVECEXP (exp, 0, 0)) == SET)
1310     {
1311         if (SET_DEST (XVECEXP (exp, 0, 0)) == pc_rtx)
1312             return;
1313
1314         if (SET_DEST (XVECEXP (exp, 0, 0)) == cc0_rtx)
1315         {
1316             CC_STATUS_INIT;
1317             cc_status.value1 = SET_SRC (XVECEXP (exp, 0, 0));
1318             return;
1319         }
1320
1321         CC_STATUS_INIT;
1322     }
1323     else
1324     {
1325         CC_STATUS_INIT;
1326     }
1327 }
1328
1329 int
1330 dsp16xx_makes_calls ()
1331 {
1332   rtx insn;
1333
1334   for (insn = get_insns (); insn; insn = next_insn (insn))
1335     if (GET_CODE (insn) == CALL_INSN)
1336       return (1);
1337
1338   return 0;
1339 }
1340
1341 long
1342 compute_frame_size (size)
1343      int size;
1344 {
1345   long total_size;
1346   long var_size;
1347   long args_size;
1348   long extra_size;
1349   long reg_size;
1350
1351   /* This value is needed to compute reg_size.  */
1352   current_frame_info.function_makes_calls = !leaf_function_p ();
1353
1354   reg_size = 0;
1355   extra_size = 0;
1356   var_size = size;
1357   args_size = current_function_outgoing_args_size;
1358   reg_size = reg_save_size ();  
1359
1360   total_size = var_size + args_size + extra_size + reg_size;
1361
1362
1363   /* Save other computed information.  */
1364   current_frame_info.total_size  = total_size;
1365   current_frame_info.var_size    = var_size;
1366   current_frame_info.args_size   = args_size;
1367   current_frame_info.extra_size  = extra_size;
1368   current_frame_info.reg_size    = reg_size;
1369   current_frame_info.initialized = reload_completed;
1370   current_frame_info.reg_size    = reg_size / UNITS_PER_WORD;
1371
1372   if (reg_size)
1373     {
1374       unsigned long offset = args_size + var_size + reg_size;
1375       current_frame_info.sp_save_offset = offset;
1376       current_frame_info.fp_save_offset = offset - total_size;
1377     }
1378
1379   return total_size;
1380 }
1381
1382 int
1383 dsp16xx_call_saved_register (regno)
1384      int regno;
1385 {
1386 #if 0
1387   if (regno == REG_PR && current_frame_info.function_makes_calls)
1388     return 1;
1389 #endif
1390   return (regs_ever_live[regno] && !call_used_regs[regno] &&
1391           !IS_YBASE_REGISTER_WINDOW(regno));
1392 }
1393
1394 int
1395 ybase_regs_ever_used ()
1396 {
1397   int regno;
1398   int live = 0;
1399
1400   for (regno = REG_YBASE0; regno <= REG_YBASE31; regno++)
1401     if (regs_ever_live[regno])
1402       {
1403         live = 1;
1404         break;
1405       }
1406
1407   return live;
1408 }
1409
1410 static void 
1411 dsp16xx_output_function_prologue (file, size)
1412      FILE *file;
1413      HOST_WIDE_INT size;
1414 {
1415   int regno;
1416   long total_size;
1417   fp = reg_names[FRAME_POINTER_REGNUM];
1418   sp = reg_names[STACK_POINTER_REGNUM];
1419   rr = reg_names[RETURN_ADDRESS_REGNUM];   /* return address register */
1420   a1h = reg_names[REG_A1];
1421   
1422   total_size = compute_frame_size (size);
1423   
1424   fprintf (file, "\t/* FUNCTION PROLOGUE: */\n");
1425   fprintf (file, "\t/* total=%ld, vars= %ld, regs= %d, args=%d, extra= %ld */\n",
1426            current_frame_info.total_size,
1427            current_frame_info.var_size,
1428            current_frame_info.reg_size,
1429            current_function_outgoing_args_size,
1430            current_frame_info.extra_size);
1431   
1432   fprintf (file, "\t/* fp save offset= %ld, sp save_offset= %ld */\n\n",
1433            current_frame_info.fp_save_offset,
1434            current_frame_info.sp_save_offset);
1435   /* Set up the 'ybase' register window.  */
1436   
1437   if (ybase_regs_ever_used())
1438     {
1439       fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1440       if (TARGET_YBASE_HIGH)
1441         fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1442       else
1443         fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1444       fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1445     }
1446   
1447   if (current_frame_info.var_size)
1448     {
1449       if (current_frame_info.var_size == 1)
1450         fprintf (file, "\t*%s++\n", sp);
1451       else
1452         {
1453           if (SMALL_INTVAL(current_frame_info.var_size) && ((current_frame_info.var_size & 0x8000) == 0))
1454             fprintf (file, "\t%s=%ld\n\t*%s++%s\n", reg_names[REG_J], current_frame_info.var_size, sp, reg_names[REG_J]);
1455           else
1456             fatal_error ("stack size > 32k");
1457         }
1458     }
1459   
1460   /* Save any registers this function uses, unless they are
1461      used in a call, in which case we don't need to.  */
1462   
1463   for(regno = 0; regno < FIRST_PSEUDO_REGISTER; ++ regno)
1464     if (dsp16xx_call_saved_register (regno)) 
1465       {
1466         fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[regno]);
1467       }
1468
1469   /* For debugging purposes, we want the return address to be at a predictable
1470      location.  */
1471   if (current_frame_info.function_makes_calls)
1472     fprintf (file, "\tpush(*%s)=%s\n", sp, reg_names[RETURN_ADDRESS_REGNUM]);
1473
1474   if (current_frame_info.args_size)
1475     {
1476       if (current_frame_info.args_size == 1)
1477         fprintf (file, "\t*%s++\n", sp);
1478       else
1479         error ("stack size > 32k");
1480     }
1481    
1482   if (frame_pointer_needed)
1483     {
1484       fprintf (file, "\t%s=%s\n", a1h, sp);
1485       fprintf (file, "\t%s=%s\n", fp, a1h);  /* Establish new base frame */
1486       fprintf (file, "\t%s=%ld\n", reg_names[REG_J], -total_size);
1487       fprintf (file, "\t*%s++%s\n", fp, reg_names[REG_J]);
1488     }
1489   
1490   fprintf (file, "\t/* END FUNCTION PROLOGUE: */\n\n");
1491 }
1492
1493 void
1494 init_emulation_routines ()
1495 {
1496  dsp16xx_addhf3_libcall = (rtx) 0;
1497  dsp16xx_subhf3_libcall = (rtx) 0;
1498  dsp16xx_mulhf3_libcall = (rtx) 0;
1499  dsp16xx_divhf3_libcall = (rtx) 0;
1500  dsp16xx_cmphf3_libcall = (rtx) 0;
1501  dsp16xx_fixhfhi2_libcall = (rtx) 0;
1502  dsp16xx_floathihf2_libcall = (rtx) 0;
1503  dsp16xx_neghf2_libcall = (rtx) 0;
1504
1505  dsp16xx_mulhi3_libcall = (rtx) 0;
1506  dsp16xx_udivqi3_libcall = (rtx) 0;
1507  dsp16xx_udivhi3_libcall = (rtx) 0;
1508  dsp16xx_divqi3_libcall = (rtx) 0;
1509  dsp16xx_divhi3_libcall = (rtx) 0;
1510  dsp16xx_modqi3_libcall = (rtx) 0;
1511  dsp16xx_modhi3_libcall = (rtx) 0;
1512  dsp16xx_umodqi3_libcall = (rtx) 0;
1513  dsp16xx_umodhi3_libcall = (rtx) 0;
1514  dsp16xx_ashrhi3_libcall = (rtx) 0;
1515  dsp16xx_ashlhi3_libcall = (rtx) 0;
1516  dsp16xx_ucmphi2_libcall = (rtx) 0;
1517  dsp16xx_lshrhi3_libcall = (rtx) 0;
1518
1519 }
1520 static void
1521 dsp16xx_output_function_epilogue (file, size)
1522      FILE *file;
1523      HOST_WIDE_INT size ATTRIBUTE_UNUSED;
1524 {
1525   int regno;
1526   
1527   fp = reg_names[FRAME_POINTER_REGNUM];
1528   sp = reg_names[STACK_POINTER_REGNUM];
1529   rr = reg_names[RETURN_ADDRESS_REGNUM];   /* return address register */
1530   a1h = reg_names[REG_A1];
1531   
1532   fprintf (file, "\n\t/* FUNCTION EPILOGUE: */\n");
1533   
1534   if (current_frame_info.args_size)
1535     {
1536       if (current_frame_info.args_size == 1)
1537         fprintf (file, "\t*%s--\n", sp);
1538       else
1539         {
1540           fprintf (file, "\t%s=%ld\n\t*%s++%s\n", 
1541                    reg_names[REG_J], -current_frame_info.args_size, sp, reg_names[REG_J]);
1542         }
1543     }
1544   
1545   if (ybase_regs_ever_used())
1546     {
1547       fprintf (file, "\t%s=%s\n", a1h, reg_names[REG_YBASE]);
1548       if (TARGET_YBASE_HIGH)
1549         fprintf (file, "\t%s=%sh+32\n", reg_names[REG_A1], a1h);
1550       else
1551         fprintf (file, "\t%s=%sh-32\n", reg_names[REG_A1], a1h);
1552       fprintf (file, "\t%s=%s\n", reg_names[REG_YBASE], a1h);
1553     }
1554
1555   if (current_frame_info.function_makes_calls)
1556     fprintf (file, "\t%s=pop(*%s)\n", reg_names[RETURN_ADDRESS_REGNUM], sp);
1557   
1558   for (regno = FIRST_PSEUDO_REGISTER - 1; regno >= 0; --regno)
1559     if (dsp16xx_call_saved_register(regno))
1560       {
1561         fprintf (file, "\t%s=pop(*%s)\n", reg_names[regno], sp);
1562       }
1563   
1564   if (current_frame_info.var_size)
1565     {
1566       if (current_frame_info.var_size == 1)
1567         fprintf (file, "\t*%s--\n", sp);
1568       else
1569         {
1570           fprintf (file, "\t%s=%ld\n\t*%s++%s\n", 
1571                    reg_names[REG_J], -current_frame_info.var_size, sp, reg_names[REG_J]);
1572         }
1573     }
1574   
1575   fprintf (file, "\treturn\n");
1576   /* Reset the frame info for the next function.  */
1577   current_frame_info = zero_frame_info;
1578   init_emulation_routines ();
1579 }
1580
1581 /* Emit insns to move operands[1] into operands[0].
1582
1583    Return 1 if we have written out everything that needs to be done to
1584    do the move.  Otherwise, return 0 and the caller will emit the move
1585    normally.  */
1586
1587 int
1588 emit_move_sequence (operands, mode)
1589      rtx *operands;
1590      enum machine_mode mode;
1591 {
1592   register rtx operand0 = operands[0];
1593   register rtx operand1 = operands[1];
1594
1595   /* We can only store registers to memory.  */
1596
1597   if (GET_CODE (operand0) == MEM && GET_CODE (operand1) != REG)
1598     operands[1] = force_reg (mode, operand1);
1599
1600   return 0;
1601 }
1602
1603 void
1604 double_reg_from_memory (operands)
1605      rtx operands[];
1606 {
1607     rtx xoperands[4];
1608
1609     if (GET_CODE(XEXP(operands[1],0)) == POST_INC)
1610     {
1611         output_asm_insn ("%u0=%1", operands);
1612         output_asm_insn ("%w0=%1", operands);
1613     }
1614     else if (GET_CODE(XEXP(operands[1],0)) == POST_DEC)
1615     {
1616         xoperands[1] = XEXP (XEXP (operands[1], 0), 0);
1617         xoperands[0] = operands[0];
1618         
1619         /* We can't use j anymore since the compiler can allocate it.  */
1620 /*      output_asm_insn ("j=-3\n\t%u0=*%1++\n\t%w0=*%1++j", xoperands); */
1621         output_asm_insn ("%u0=*%1++\n\t%w0=*%1--\n\t*%1--\n\t*%1--", xoperands);
1622     }
1623     else if (GET_CODE(XEXP(operands[1],0)) == PLUS)
1624     {
1625       rtx addr;
1626       int offset = 0;
1627
1628       output_asm_insn ("%u0=%1", operands);
1629
1630
1631       /* In order to print out the least significant word we must
1632          use 'offset + 1'.  */
1633       addr = XEXP (operands[1], 0);
1634       if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1635         offset = INTVAL(XEXP(addr,0)) + 1;
1636       else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1637         offset = INTVAL(XEXP(addr,1)) + 1;
1638
1639       fprintf (asm_out_file, "\t%s=*(%d)\n", reg_names[REGNO(operands[0]) + 1], offset + 31);
1640     }
1641     else
1642     {
1643         xoperands[1] = XEXP(operands[1],0);
1644         xoperands[0] = operands[0];
1645
1646         output_asm_insn ("%u0=*%1++\n\t%w0=*%1--", xoperands);
1647     }
1648 }
1649
1650
1651 void
1652 double_reg_to_memory (operands)
1653      rtx operands[];
1654 {
1655     rtx xoperands[4];
1656
1657     if (GET_CODE(XEXP(operands[0],0)) == POST_INC)
1658     {
1659         output_asm_insn ("%0=%u1", operands);
1660         output_asm_insn ("%0=%w1", operands);
1661     }
1662     else if (GET_CODE(XEXP(operands[0],0)) == POST_DEC)
1663     {
1664         xoperands[0] = XEXP (XEXP (operands[0], 0), 0);
1665         xoperands[1] = operands[1];
1666         
1667         /* We can't use j anymore since the compiler can allocate it.  */
1668
1669 /*      output_asm_insn ("j=-3\n\t*%0++=%u1\n\t*%0++j=%w1", xoperands); */
1670         output_asm_insn ("*%0++=%u1\n\t*%0--=%w1\n\t*%0--\n\t*%0--", xoperands);
1671
1672     }
1673     else if (GET_CODE(XEXP(operands[0],0)) == PLUS)
1674     {
1675       rtx addr;
1676       int offset = 0;
1677
1678       output_asm_insn ("%0=%u1", operands);
1679
1680       /* In order to print out the least significant word we must
1681          use 'offset + 1'.  */
1682       addr = XEXP (operands[0], 0);
1683       if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1684         offset = INTVAL(XEXP(addr,0)) + 1;
1685       else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1686         offset = INTVAL(XEXP(addr,1)) + 1;
1687       else
1688         fatal_error ("invalid addressing mode");
1689
1690       fprintf (asm_out_file, "\t*(%d)=%s\n", offset + 31, reg_names[REGNO(operands[1]) + 1]);
1691     }
1692     else
1693     {
1694         xoperands[0] = XEXP(operands[0],0);
1695         xoperands[1] = operands[1];
1696
1697         output_asm_insn ("*%0++=%u1\n\t*%0--=%w1", xoperands);
1698     }
1699 }
1700
1701 void
1702 override_options ()
1703 {
1704   if (chip_name == (char *) 0)
1705     chip_name = DEFAULT_CHIP_NAME;
1706
1707   if (text_seg_name == (char *) 0)
1708     text_seg_name = DEFAULT_TEXT_SEG_NAME;
1709   
1710   if (data_seg_name == (char *) 0)
1711     data_seg_name = DEFAULT_DATA_SEG_NAME;
1712   
1713   if (bss_seg_name == (char *) 0)
1714     bss_seg_name = DEFAULT_BSS_SEG_NAME;
1715   
1716   if (const_seg_name == (char *) 0)
1717     const_seg_name = DEFAULT_CONST_SEG_NAME;
1718   
1719   save_chip_name = xstrdup (chip_name);
1720
1721   rsect_text = concat (".rsect \"", text_seg_name, "\"", NULL);
1722   rsect_data = concat (".rsect \"", data_seg_name, "\"", NULL);
1723   rsect_bss = concat (".rsect \"", bss_seg_name, "\"", NULL);
1724   rsect_const = concat (".rsect \"", const_seg_name, "\"", NULL);
1725 }
1726
1727 int
1728 next_cc_user_unsigned (insn)
1729      rtx insn;
1730 {
1731   switch (next_cc_user_code (insn))
1732     {
1733     case GTU:
1734     case GEU:
1735     case LTU:
1736     case LEU:
1737       return 1;
1738     default:
1739       return 0;
1740     }
1741 }
1742
1743 enum rtx_code
1744 next_cc_user_code (insn)
1745      rtx insn;
1746 {
1747   /* If no insn could be found we assume that the jump has been
1748      deleted and the compare will be deleted later.  */
1749
1750   if (!(insn = next_cc0_user (insn)))
1751     return (enum rtx_code) 0;
1752   else if (GET_CODE (insn) == JUMP_INSN
1753            && GET_CODE (PATTERN (insn)) == SET
1754            && GET_CODE (SET_SRC (PATTERN (insn))) == IF_THEN_ELSE)
1755     return GET_CODE (XEXP (SET_SRC (PATTERN (insn)), 0));
1756   else if (GET_CODE (insn) == INSN
1757            && GET_CODE (PATTERN (insn)) == SET
1758            && comparison_operator (SET_SRC (PATTERN (insn)), VOIDmode))
1759     return GET_CODE (SET_SRC (PATTERN (insn)));
1760   else
1761     abort ();
1762 }
1763
1764 void
1765 print_operand(file, op, letter)
1766      FILE *file;
1767      rtx op;
1768      int letter;
1769 {
1770     enum rtx_code code;
1771
1772     code = GET_CODE(op);
1773
1774     switch (letter)
1775     {
1776        case 'I':
1777           code = reverse_condition (code);
1778           /* Fallthrough */
1779
1780        case 'C':
1781           if (code == EQ) 
1782           { 
1783               fputs ("eq", file); 
1784               return; 
1785           }
1786           else if (code == NE)  
1787           { 
1788               fputs ("ne", file); 
1789               return; 
1790           }
1791           else if (code == GT || code == GTU)  
1792           { 
1793               fputs ("gt", file); 
1794               return; 
1795           }
1796           else if (code == LT || code == LTU)  
1797           { 
1798               fputs ("mi", file); 
1799               return; 
1800           }
1801           else if (code == GE || code == GEU)  
1802           {
1803               fputs ("pl", file); 
1804               return; 
1805           }
1806           else if (code == LE || code == LEU)  
1807           { 
1808               fputs ("le", file); 
1809               return; 
1810           }
1811           else 
1812               abort ();
1813           break;
1814
1815        default:
1816           break;  
1817     }
1818
1819     if (code == REG)
1820     {
1821         /* Print the low half of a 32-bit register pair.  */
1822         if (letter == 'w')
1823            fprintf (file, "%s", reg_names[REGNO (op) + 1]);
1824         else if (letter == 'u' || !letter)
1825            fprintf (file, "%s", reg_names[REGNO (op)]);
1826         else if (letter == 'b')
1827             fprintf (file, "%sh", reg_names[REGNO (op)]);
1828         else if (letter == 'm')
1829           fprintf (file, "%s", himode_reg_name[REGNO (op)]);
1830         else
1831           output_operand_lossage ("bad register extension code");
1832     }
1833     else if (code == MEM)
1834       output_address (XEXP(op,0));
1835     else if (code == CONST_INT)
1836       { 
1837         HOST_WIDE_INT val = INTVAL (op);
1838
1839         if (letter == 'H')
1840           fprintf (file, HOST_WIDE_INT_PRINT_HEX, val & 0xffff);
1841         else if (letter == 'h')
1842           fprintf (file, HOST_WIDE_INT_PRINT_DEC, val);
1843         else if (letter == 'U')
1844           fprintf (file, HOST_WIDE_INT_PRINT_HEX, (val >> 16) & 0xffff);
1845         else
1846            output_addr_const(file, op);
1847       }
1848     else if (code == CONST_DOUBLE && GET_MODE(op) != DImode)
1849       {
1850         long l;
1851         REAL_VALUE_TYPE r;
1852         REAL_VALUE_FROM_CONST_DOUBLE (r, op);
1853         REAL_VALUE_TO_TARGET_SINGLE (r, l);
1854         fprintf (file, "0x%lx", l);
1855       }
1856     else if (code == CONST)
1857       {
1858         rtx addr = XEXP (op, 0);
1859         
1860         if (GET_CODE (addr) != PLUS)
1861           {
1862             output_addr_const(file, op);
1863             return;
1864           }
1865         
1866         if ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
1867              || GET_CODE (XEXP (addr, 0)) == LABEL_REF)
1868             && (GET_CODE (XEXP (addr, 1)) == CONST_INT))
1869           {
1870             int n = INTVAL (XEXP(addr, 1));
1871             output_addr_const (file, XEXP (addr, 0));
1872             
1873             if (n >= 0)
1874               fprintf (file, "+");
1875             
1876             n = (int) (short) n;
1877             fprintf (file, "%d", n);
1878           }
1879         else if ((GET_CODE (XEXP (addr, 1)) == SYMBOL_REF
1880                   || GET_CODE (XEXP (addr, 1)) == LABEL_REF)
1881                  && (GET_CODE (XEXP (addr, 0)) == CONST_INT))
1882           {
1883             int n = INTVAL (XEXP(addr, 0));
1884             output_addr_const (file, XEXP (addr, 1));
1885             
1886             if (n >= 0)
1887               fprintf (file, "+");
1888             
1889             n = (int) (short) n;
1890             fprintf (file, "%d", n);
1891           }
1892         else
1893           output_addr_const(file, op);
1894       }
1895     else
1896       output_addr_const (file, op);
1897 }
1898
1899
1900 void
1901 print_operand_address(file, addr)
1902      FILE *file;
1903      rtx addr;
1904 {
1905   rtx base;
1906   int offset = 0;;
1907   
1908   switch (GET_CODE (addr))
1909     {
1910     case REG:
1911       fprintf (file, "*%s", reg_names[REGNO (addr)]);
1912       break;
1913     case POST_DEC:
1914       fprintf (file, "*%s--", reg_names[REGNO (XEXP (addr, 0))]);
1915       break;
1916     case POST_INC:
1917       fprintf (file, "*%s++", reg_names[REGNO (XEXP (addr, 0))]);
1918       break;
1919     case PLUS:
1920       if (GET_CODE (XEXP(addr,0)) == CONST_INT)
1921         offset = INTVAL(XEXP(addr,0)), base = XEXP(addr,1);
1922       else if (GET_CODE (XEXP(addr,1)) == CONST_INT)
1923         offset = INTVAL(XEXP(addr,1)), base = XEXP(addr,0);
1924       else
1925         abort();
1926       if (GET_CODE (base) == REG && REGNO(base) == STACK_POINTER_REGNUM)
1927         {
1928           if (offset >= -31 && offset <= 0)
1929             offset = 31 + offset;
1930           else
1931             fatal_error ("invalid offset in ybase addressing");
1932         }
1933       else
1934         fatal_error ("invalid register in ybase addressing");
1935       
1936       fprintf (file, "*(%d)", offset);
1937       break;
1938       
1939     default:
1940       if (FITS_5_BITS (addr))
1941         fprintf (file, "*(0x%x)", (INTVAL (addr) & 0x20));
1942       else
1943         output_addr_const (file, addr);
1944     }
1945 }
1946
1947 void
1948 output_dsp16xx_float_const (operands)
1949      rtx *operands;
1950 {
1951   rtx src = operands[1];
1952   
1953   REAL_VALUE_TYPE d;
1954   long value;
1955   
1956   REAL_VALUE_FROM_CONST_DOUBLE (d, src);
1957   REAL_VALUE_TO_TARGET_SINGLE (d, value);
1958   
1959   operands[1] = GEN_INT (value);
1960   output_asm_insn ("%u0=%U1\n\t%w0=%H1", operands);
1961 }
1962
1963 static int
1964 reg_save_size ()
1965 {
1966   int reg_save_size = 0;
1967   int regno;
1968
1969   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1970     if (dsp16xx_call_saved_register (regno))
1971       {
1972         reg_save_size += UNITS_PER_WORD;
1973       }
1974
1975   /* If the function makes calls we will save need to save the 'pr' register.  */
1976   if (current_frame_info.function_makes_calls)
1977     reg_save_size += 1;
1978
1979   return (reg_save_size);
1980 }
1981
1982 #if 0
1983 int
1984 dsp16xx_starting_frame_offset()
1985 {
1986   int reg_save_size = 0;
1987  int regno;
1988  
1989   for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1990     if (dsp16xx_call_saved_register (regno))
1991       {
1992         reg_save_size += UNITS_PER_WORD;
1993       }
1994
1995   return (reg_save_size);
1996 }
1997 #endif
1998
1999 int
2000 initial_frame_pointer_offset()
2001 {
2002   int offset = 0;
2003   
2004   offset = compute_frame_size (get_frame_size());
2005
2006 #ifdef STACK_GROWS_DOWNWARD
2007   return (offset);
2008 #else
2009   return (-offset);
2010 #endif
2011 }
2012
2013 /* Generate the minimum number of 1600 core shift instructions
2014    to shift by 'shift_amount'.  */
2015
2016 #if 0
2017 void
2018 emit_1600_core_shift (shift_op, operands, shift_amount, mode)
2019      enum rtx_code shift_op;
2020      rtx *operands;
2021      int shift_amount;
2022      enum machine_mode mode;
2023 {
2024   int quotient;
2025   int i;
2026   int first_shift_emitted = 0;
2027   
2028   while (shift_amount != 0)
2029     {
2030       if (shift_amount/16)
2031         {
2032           quotient = shift_amount/16;
2033           shift_amount = shift_amount - (quotient * 16);
2034           for (i = 0; i < quotient; i++)
2035             emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2036                                     gen_rtx (shift_op, mode, 
2037                                              first_shift_emitted
2038                                              ? operands[0] : operands[1],
2039                                              GEN_INT (16))));
2040           first_shift_emitted = 1;
2041         }
2042       else if (shift_amount/8)
2043         {
2044           quotient = shift_amount/8;
2045           shift_amount = shift_amount - (quotient * 8);
2046           for (i = 0; i < quotient; i++)
2047             emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2048                                     gen_rtx (shift_op, mode, 
2049                                              first_shift_emitted
2050                                              ? operands[0] : operands[1],
2051                                              GEN_INT (8))));
2052           first_shift_emitted = 1;
2053         }
2054       else if (shift_amount/4)
2055         {
2056           quotient = shift_amount/4;
2057           shift_amount = shift_amount - (quotient * 4);
2058           for (i = 0; i < quotient; i++)
2059             emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2060                                     gen_rtx (shift_op, mode, 
2061                                              first_shift_emitted
2062                                              ? operands[0] : operands[1],
2063                                              GEN_INT (4))));
2064           first_shift_emitted = 1;
2065         }
2066       else if (shift_amount/1)
2067         {
2068           quotient = shift_amount/1;
2069           shift_amount = shift_amount - (quotient * 1);
2070           for (i = 0; i < quotient; i++)
2071             emit_insn (gen_rtx_SET (VOIDmode, operands[0],
2072                                     gen_rtx (shift_op, mode, 
2073                                              first_shift_emitted
2074                                              ? operands[0] : operands[1],
2075                                              GEN_INT (1))));
2076           first_shift_emitted = 1;
2077         }
2078     }
2079 }
2080 #else
2081 void
2082 emit_1600_core_shift (shift_op, operands, shift_amount)
2083      enum rtx_code shift_op;
2084      rtx *operands;
2085      int shift_amount;
2086 {
2087   int quotient;
2088   int i;
2089   int first_shift_emitted = 0;
2090   const char * const *shift_asm_ptr;
2091   const char * const *shift_asm_ptr_first;
2092
2093   if (shift_op == ASHIFT)
2094     {
2095       shift_asm_ptr = ashift_left_asm;
2096       shift_asm_ptr_first = ashift_left_asm_first;
2097     }
2098   else if (shift_op == ASHIFTRT)
2099     {
2100       shift_asm_ptr = ashift_right_asm;
2101       shift_asm_ptr_first = ashift_right_asm_first;
2102     }
2103   else if (shift_op == LSHIFTRT)
2104     {
2105       shift_asm_ptr = lshift_right_asm;
2106       shift_asm_ptr_first = lshift_right_asm_first;
2107     }
2108   else
2109     fatal_error ("invalid shift operator in emit_1600_core_shift");
2110
2111   while (shift_amount != 0)
2112     {
2113       if (shift_amount/16)
2114         {
2115           quotient = shift_amount/16;
2116           shift_amount = shift_amount - (quotient * 16);
2117           for (i = 0; i < quotient; i++)
2118             output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_16]
2119                               : shift_asm_ptr_first[SHIFT_INDEX_16]), operands);
2120           first_shift_emitted = 1;
2121         }
2122       else if (shift_amount/8)
2123         {
2124           quotient = shift_amount/8;
2125           shift_amount = shift_amount - (quotient * 8);
2126           for (i = 0; i < quotient; i++)
2127             output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_8]
2128                               : shift_asm_ptr_first[SHIFT_INDEX_8]), operands);
2129           first_shift_emitted = 1;
2130         }
2131       else if (shift_amount/4)
2132         {
2133           quotient = shift_amount/4;
2134           shift_amount = shift_amount - (quotient * 4);
2135           for (i = 0; i < quotient; i++)
2136             output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_4]
2137                               : shift_asm_ptr_first[SHIFT_INDEX_4]), operands);
2138           first_shift_emitted = 1;
2139         }
2140       else if (shift_amount/1)
2141         {
2142           quotient = shift_amount/1;
2143           shift_amount = shift_amount - (quotient * 1);
2144           for (i = 0; i < quotient; i++)
2145             output_asm_insn ((first_shift_emitted ? shift_asm_ptr[SHIFT_INDEX_1]
2146                               : shift_asm_ptr_first[SHIFT_INDEX_1]), operands);
2147           first_shift_emitted = 1;
2148         }
2149     }
2150 }
2151 #endif
2152
2153 int
2154 num_1600_core_shifts (shift_amount)
2155 int shift_amount;
2156 {
2157   int quotient;
2158   int i;
2159   int first_shift_emitted = 0;
2160   int num_shifts = 0;
2161
2162   while (shift_amount != 0)
2163     {
2164       if (shift_amount/16)
2165         {
2166           quotient = shift_amount/16;
2167           shift_amount = shift_amount - (quotient * 16);
2168           for (i = 0; i < quotient; i++)
2169             num_shifts++;
2170           first_shift_emitted = 1;
2171         }
2172       else if (shift_amount/8)
2173         {
2174           quotient = shift_amount/8;
2175           shift_amount = shift_amount - (quotient * 8);
2176           for (i = 0; i < quotient; i++)
2177             num_shifts++;
2178
2179           first_shift_emitted = 1;
2180         }
2181       else if (shift_amount/4)
2182         {
2183           quotient = shift_amount/4;
2184           shift_amount = shift_amount - (quotient * 4);
2185           for (i = 0; i < quotient; i++)
2186             num_shifts++;
2187
2188           first_shift_emitted = 1;
2189         }
2190       else if (shift_amount/1)
2191         {
2192           quotient = shift_amount/1;
2193           shift_amount = shift_amount - (quotient * 1);
2194           for (i = 0; i < quotient; i++)
2195             num_shifts++;
2196
2197           first_shift_emitted = 1;
2198         }
2199     }
2200   return num_shifts;
2201 }
2202
2203 void
2204 asm_output_common(file, name, size, rounded)
2205      FILE *file;
2206      const char *name;
2207      int size ATTRIBUTE_UNUSED;
2208      int rounded;
2209 {
2210     bss_section ();
2211     (*targetm.asm_out.globalize_label) (file, name);
2212     assemble_name (file, name);
2213     fputs (":", file);
2214     if (rounded > 1)
2215         fprintf (file, "%d * int\n", rounded);
2216     else
2217         fprintf (file, "int\n");
2218 }
2219
2220 void
2221 asm_output_local(file, name, size, rounded)
2222      FILE *file;
2223      const char *name;
2224      int size ATTRIBUTE_UNUSED;
2225      int rounded;
2226 {
2227     bss_section ();
2228     assemble_name (file, name);
2229     fputs (":", file);
2230     if (rounded > 1)
2231         fprintf (file, "%d * int\n", rounded);
2232     else
2233         fprintf (file, "int\n");
2234 }
2235
2236 static int
2237 dsp16xx_address_cost (addr)
2238      rtx addr;
2239 {
2240     switch (GET_CODE (addr))
2241     {
2242           default:
2243              break;
2244
2245           case REG:
2246              return 1;
2247
2248           case CONST:
2249              {
2250                 rtx offset = const0_rtx;
2251                 addr = eliminate_constant_term (addr, &offset);
2252
2253                 if (GET_CODE (addr) == LABEL_REF)
2254                     return 2;
2255
2256                 if (GET_CODE (addr) != SYMBOL_REF)
2257                     return 4;
2258
2259                 if (INTVAL (offset) == 0)
2260                     return 2;
2261              }
2262              /* fall through */
2263
2264           case POST_INC: case POST_DEC:
2265              return (GET_MODE (addr) == QImode ? 1 : 2);
2266
2267           case SYMBOL_REF: case LABEL_REF:
2268              return 2;
2269
2270           case PLUS:
2271           {
2272              register rtx plus0 = XEXP (addr, 0);
2273              register rtx plus1 = XEXP (addr, 1);
2274              
2275              if (GET_CODE (plus0) != REG && GET_CODE (plus1) == REG)
2276              {
2277                  plus0 = XEXP (addr, 1);
2278                  plus1 = XEXP (addr, 0);
2279              }
2280              
2281              if (GET_CODE (plus0) != REG)
2282                  break;
2283              
2284              switch (GET_CODE (plus1))
2285              {
2286                    default:
2287                       break;
2288                  
2289                    case CONST_INT:
2290                       return 4;
2291
2292                    case CONST:
2293                    case SYMBOL_REF:
2294                    case LABEL_REF:
2295                       return dsp16xx_address_cost (plus1) + 1;
2296              }
2297           }
2298      }
2299              
2300      return 4;
2301 }
2302
2303 \f
2304 /* Determine whether a function argument is passed in a register, and
2305    which register.
2306
2307    The arguments are CUM, which summarizes all the previous
2308    arguments; MODE, the machine mode of the argument; TYPE,
2309    the data type of the argument as a tree node or 0 if that is not known
2310    (which happens for C support library functions); and NAMED,
2311    which is 1 for an ordinary argument and 0 for nameless arguments that
2312    correspond to `...' in the called function's prototype.
2313
2314    The value of the expression should either be a `reg' RTX for the
2315    hard register in which to pass the argument, or zero to pass the
2316    argument on the stack.
2317
2318    On the dsp1610 the first four words of args are normally in registers
2319    and the rest are pushed. If we a long or on float mode, the argument
2320    must begin on an even register boundary
2321
2322    Note that FUNCTION_ARG and FUNCTION_INCOMING_ARG were different.
2323    For structures that are passed in memory, but could have been
2324    passed in registers, we first load the structure into the
2325    register, and then when the last argument is passed, we store
2326    the registers into the stack locations.  This fixes some bugs
2327    where GCC did not expect to have register arguments, followed.  */
2328
2329 struct rtx_def *
2330 dsp16xx_function_arg (args_so_far, mode, type, named)
2331      CUMULATIVE_ARGS args_so_far;
2332      enum machine_mode mode;
2333      tree type;
2334      int named;
2335 {
2336   if (TARGET_REGPARM)
2337     {
2338       if ((args_so_far & 1) != 0
2339           && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2340         args_so_far++;
2341
2342       if (type == void_type_node)
2343         return (struct rtx_def *) 0;
2344
2345       if (named && args_so_far < 4 && !MUST_PASS_IN_STACK (mode,type))
2346         return gen_rtx_REG (mode, args_so_far + FIRST_REG_FOR_FUNCTION_ARG);
2347       else
2348         return (struct rtx_def *) 0;
2349     }
2350   else
2351     return (struct rtx_def *) 0;
2352 }
2353
2354 /* Advance the argument to the next argument position.  */
2355
2356 void
2357 dsp16xx_function_arg_advance (cum, mode, type, named)
2358      CUMULATIVE_ARGS *cum;      /* current arg information */
2359      enum machine_mode mode;    /* current arg mode */
2360      tree type;                 /* type of the argument or 0 if lib support */
2361      int named ATTRIBUTE_UNUSED;/* whether or not the argument was named */
2362 {
2363   if (TARGET_REGPARM)
2364     {
2365       if ((*cum & 1) != 0
2366           && (mode == HImode || GET_MODE_CLASS(mode) == MODE_FLOAT))
2367         *cum += 1;
2368
2369       if (mode != BLKmode)
2370         *cum += GET_MODE_SIZE (mode);
2371       else
2372         *cum += int_size_in_bytes (type);
2373     }
2374 }
2375
2376 void
2377 coff_dsp16xx_file_start (file)
2378      FILE *file;
2379 {
2380   fprintf (file, "#include <%s.h>\n", save_chip_name);
2381 }
2382
2383 void
2384 luxworks_dsp16xx_file_start (file)
2385      FILE *file;
2386 {
2387   char *temp_filename;
2388   int len, err_code;
2389
2390
2391   fprintf (file, "\t.debug ");
2392   err_code = (TARGET_DEBUG) ? fprintf (file, "yes, ") : fprintf (file, "no, ");
2393   err_code = (TARGET_SAVE_TEMPS) ? fprintf (file, "asm, ") : fprintf (file, "temp, ");
2394   len = strlen (main_input_filename);
2395   temp_filename = (char *) xmalloc (len + 2);
2396   strcpy (temp_filename, main_input_filename);
2397 #ifdef __CYGWIN32__
2398     p = temp_filename;
2399     while (*p != '\0') {
2400     if (*p == '\\')
2401         *p = '/';
2402          p++;
2403          }
2404 #endif
2405     fprintf (file, "\"%s\"\n", temp_filename);
2406
2407   fprintf (file, "#include <%s.h>\n", save_chip_name);
2408
2409    /*
2410     * Add dummy sections, so that they always exist in the 
2411     * object code. These have been created so that the number and
2412     * type of sections remain consistent with and without -g option. Note
2413     * that the .data, .text, .const and .bss are always created when -g
2414     * is provided as an option.  */
2415    fprintf (file, "\t.rsect \".text\" , nodelete\n");
2416    fprintf (file, "\t.rsect \".data\" , nodelete\n");
2417    fprintf (file, "\t.rsect \".const\" , nodelete\n");
2418    fprintf (file, "\t.rsect \".bss\" , nodelete\n");
2419 }
2420
2421 rtx
2422 gen_tst_reg (x)
2423      rtx x;
2424 {
2425   enum machine_mode mode;
2426
2427   mode = GET_MODE (x);
2428
2429   if (mode == QImode)
2430     emit_insn (gen_rtx_PARALLEL
2431                (VOIDmode,
2432                 gen_rtvec (2, gen_rtx_SET (VOIDmode, cc0_rtx, x),
2433                            gen_rtx_CLOBBER (VOIDmode,
2434                                             gen_rtx_SCRATCH (QImode)))));
2435   else if (mode == HImode)
2436     emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx, x));
2437   else
2438     fatal_error ("invalid mode for gen_tst_reg");
2439
2440   return cc0_rtx;
2441 }
2442
2443 rtx
2444 gen_compare_reg (code, x, y)
2445      enum rtx_code code;
2446      rtx x, y;
2447 {
2448   enum machine_mode mode;
2449
2450   mode = GET_MODE (x);
2451   /* For floating point compare insns, a call is generated so don't
2452      do anything here.  */
2453
2454   if (GET_MODE_CLASS (mode) == MODE_FLOAT)
2455     return cc0_rtx;
2456
2457   if (mode == QImode)
2458     {
2459       if (code == GTU || code == GEU
2460           || code == LTU || code == LEU)
2461         {
2462           emit_insn (gen_rtx_PARALLEL
2463                      (VOIDmode,
2464                       gen_rtvec (3,
2465                                  gen_rtx_SET (VOIDmode, cc0_rtx,
2466                                               gen_rtx_COMPARE (mode, x, y)),
2467                                  gen_rtx_CLOBBER (VOIDmode,
2468                                                   gen_rtx_SCRATCH (QImode)),
2469                                  gen_rtx_CLOBBER (VOIDmode,
2470                                                   gen_rtx_SCRATCH (QImode)))));
2471         }
2472       else
2473         {
2474           emit_insn (gen_rtx_PARALLEL
2475                      (VOIDmode,
2476                       gen_rtvec (3, gen_rtx_SET (VOIDmode, cc0_rtx,
2477                                                  gen_rtx_COMPARE (mode, x, y)),
2478                                  gen_rtx_CLOBBER (VOIDmode,
2479                                                   gen_rtx_SCRATCH (QImode)),
2480                                  gen_rtx_CLOBBER (VOIDmode,
2481                                                   gen_rtx_SCRATCH (QImode)))));
2482         }
2483     }
2484   else if (mode == HImode)
2485     {
2486       if (code == GTU || code == GEU
2487           || code == LTU || code == LEU)
2488         {
2489           emit_insn (gen_rtx_PARALLEL 
2490                      (VOIDmode, 
2491                       gen_rtvec (5,
2492                                  gen_rtx_SET (VOIDmode, cc0_rtx, 
2493                                               gen_rtx_COMPARE (VOIDmode, x, y)),
2494                                  gen_rtx_CLOBBER (VOIDmode, 
2495                                                   gen_rtx_SCRATCH (QImode)),
2496                                  gen_rtx_CLOBBER (VOIDmode, 
2497                                                   gen_rtx_SCRATCH (QImode)),
2498                                  gen_rtx_CLOBBER (VOIDmode, 
2499                                                   gen_rtx_SCRATCH (QImode)),
2500                                  gen_rtx_CLOBBER (VOIDmode, 
2501                                                   gen_rtx_SCRATCH (QImode)))));
2502         }
2503       else
2504         emit_insn (gen_rtx_SET (VOIDmode, cc0_rtx,
2505                                 gen_rtx_COMPARE (VOIDmode,
2506                                                  force_reg (HImode, x), 
2507                                                  force_reg (HImode,y))));
2508     }
2509   else
2510     fatal_error ("invalid mode for integer comparison in gen_compare_reg");
2511
2512   return cc0_rtx;
2513 }
2514
2515 const char *
2516 output_block_move (operands)
2517      rtx operands[];
2518 {
2519   int loop_count = INTVAL(operands[2]);
2520   rtx xoperands[4];
2521
2522   fprintf (asm_out_file, "\tdo %d {\n", loop_count);
2523   xoperands[0] = operands[4];
2524   xoperands[1] = operands[1];
2525   output_asm_insn ("%0=*%1++", xoperands);
2526
2527   xoperands[0] = operands[0];
2528   xoperands[1] = operands[4];
2529   output_asm_insn ("*%0++=%1", xoperands);
2530
2531   fprintf (asm_out_file, "\t}\n");
2532   return "";
2533 }
2534
2535 int
2536 uns_comparison_operator (op, mode)
2537      rtx op;
2538      enum machine_mode mode;
2539 {
2540   if (mode == VOIDmode || GET_MODE (op) == mode)
2541     {
2542       enum rtx_code code;
2543       
2544       code = GET_CODE(op);
2545
2546       if (code == LEU || code == LTU || code == GEU
2547           || code == GTU)
2548         {
2549           return 1;
2550         }
2551       else
2552         return 0;
2553     }
2554
2555   return 0;
2556 }
2557
2558 int
2559 signed_comparison_operator (op, mode)
2560      rtx op;
2561      enum machine_mode mode;
2562 {
2563   if (mode == VOIDmode || GET_MODE (op) == mode)
2564     {
2565       enum rtx_code code;
2566       
2567       code = GET_CODE(op);
2568
2569       if (!(code == LEU || code == LTU || code == GEU
2570           || code == GTU))
2571         {
2572           return 1;
2573         }
2574       else
2575         return 0;
2576     }
2577
2578   return 0;
2579 }
2580 \f
2581 static bool
2582 dsp16xx_rtx_costs (x, code, outer_code, total)
2583      rtx x;
2584      int code;
2585      int outer_code ATTRIBUTE_UNUSED;
2586      int *total;
2587 {
2588   switch (code)
2589     {
2590     case CONST_INT:
2591       *total = (unsigned HOST_WIDE_INT) INTVAL (x) < 65536 ? 0 : 2;
2592       return true;
2593
2594     case LABEL_REF:
2595     case SYMBOL_REF:
2596     case CONST:
2597       *total = COSTS_N_INSNS (1);
2598       return true;
2599
2600     case CONST_DOUBLE:
2601       *total = COSTS_N_INSNS (2);
2602       return true;
2603
2604     case MEM:
2605       *total = COSTS_N_INSNS (GET_MODE (x) == QImode ? 2 : 4);
2606       return true;
2607
2608     case DIV:
2609     case MOD:
2610       *total = COSTS_N_INSNS (38);
2611       return true;
2612
2613     case MULT:
2614       if (GET_MODE (x) == QImode)
2615         *total = COSTS_N_INSNS (2);
2616       else
2617         *total = COSTS_N_INSNS (38);
2618       return true;
2619
2620     case PLUS:
2621     case MINUS:
2622     case AND:
2623     case IOR:
2624     case XOR:
2625       if (GET_MODE_CLASS (GET_MODE (x)) == MODE_INT)
2626         {
2627           *total = 1;
2628           return false;
2629         }
2630       else
2631         {
2632           *total = COSTS_N_INSNS (38);
2633           return true;
2634         }
2635
2636     case NEG:
2637     case NOT:
2638       *total = COSTS_N_INSNS (1);
2639       return true;
2640
2641     case ASHIFT:
2642     case ASHIFTRT:
2643     case LSHIFTRT:
2644       if (GET_CODE (XEXP (x, 1)) == CONST_INT)
2645         {
2646           HOST_WIDE_INT number = INTVAL (XEXP (x, 1));
2647           if (number == 1 || number == 4 || number == 8
2648               || number == 16)
2649             *total = COSTS_N_INSNS (1);
2650           else if (TARGET_BMU)
2651             *total = COSTS_N_INSNS (2);
2652           else
2653             *total = COSTS_N_INSNS (num_1600_core_shifts (number));
2654           return true;
2655         }
2656       break;
2657     }
2658
2659   if (TARGET_BMU)
2660     *total = COSTS_N_INSNS (1);
2661   else
2662     *total = COSTS_N_INSNS (15);
2663   return true;
2664 }