OSDN Git Service

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