OSDN Git Service

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