OSDN Git Service

663f50b6e844d761564faf4c7caaee6cfb3d3d4c
[pf3gnuchains/gcc-fork.git] / gcc / config / arc / arc.c
1 /* Subroutines used for code generation on the Argonaut ARC cpu.
2    Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002
3    Free Software Foundation, Inc.
4
5 This file is part of GNU CC.
6
7 GNU CC is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 2, or (at your option)
10 any later version.
11
12 GNU CC is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GNU CC; see the file COPYING.  If not, write to
19 the Free Software Foundation, 59 Temple Place - Suite 330,
20 Boston, MA 02111-1307, USA.  */
21
22 /* ??? This is an old port, and is undoubtedly suffering from bit rot.  */
23
24 #include "config.h"
25 #include "system.h"
26 #include "tree.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 "flags.h"
36 #include "function.h"
37 #include "expr.h"
38 #include "recog.h"
39 #include "toplev.h"
40 #include "tm_p.h"
41 #include "target.h"
42 #include "target-def.h"
43
44 /* Which cpu we're compiling for (NULL(=base), ???).  */
45 const char *arc_cpu_string;
46 int arc_cpu_type;
47
48 /* Name of mangle string to add to symbols to separate code compiled for each
49    cpu (or NULL).  */
50 const char *arc_mangle_cpu;
51
52 /* Save the operands last given to a compare for use when we
53    generate a scc or bcc insn.  */
54 rtx arc_compare_op0, arc_compare_op1;
55
56 /* Name of text, data, and rodata sections, as specified on command line.
57    Selected by -m{text,data,rodata} flags.  */
58 const char *arc_text_string = ARC_DEFAULT_TEXT_SECTION;
59 const char *arc_data_string = ARC_DEFAULT_DATA_SECTION;
60 const char *arc_rodata_string = ARC_DEFAULT_RODATA_SECTION;
61
62 /* Name of text, data, and rodata sections used in varasm.c.  */
63 const char *arc_text_section;
64 const char *arc_data_section;
65 const char *arc_rodata_section;
66
67 /* Array of valid operand punctuation characters.  */
68 char arc_punct_chars[256];
69
70 /* Variables used by arc_final_prescan_insn to implement conditional
71    execution.  */
72 static int arc_ccfsm_state;
73 static int arc_ccfsm_current_cc;
74 static rtx arc_ccfsm_target_insn;
75 static int arc_ccfsm_target_label;
76
77 /* The maximum number of insns skipped which will be conditionalised if
78    possible.  */
79 #define MAX_INSNS_SKIPPED 3
80
81 /* A nop is needed between a 4 byte insn that sets the condition codes and
82    a branch that uses them (the same isn't true for an 8 byte insn that sets
83    the condition codes).  Set by arc_final_prescan_insn.  Used by
84    arc_print_operand.  */
85 static int last_insn_set_cc_p;
86 static int current_insn_set_cc_p;
87 static void record_cc_ref PARAMS ((rtx));
88 static void arc_init_reg_tables PARAMS ((void));
89 static int get_arc_condition_code PARAMS ((rtx));
90 const struct attribute_spec arc_attribute_table[];
91 static tree arc_handle_interrupt_attribute PARAMS ((tree *, tree, tree, int, bool *));
92 static bool arc_assemble_integer PARAMS ((rtx, unsigned int, int));
93 static void arc_output_function_prologue PARAMS ((FILE *, HOST_WIDE_INT));
94 static void arc_output_function_epilogue PARAMS ((FILE *, HOST_WIDE_INT));
95 \f
96 /* Initialize the GCC target structure.  */
97 #undef TARGET_ASM_ALIGNED_HI_OP
98 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
99 #undef TARGET_ASM_ALIGNED_SI_OP
100 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
101 #undef TARGET_ASM_INTEGER
102 #define TARGET_ASM_INTEGER arc_assemble_integer
103
104 #undef TARGET_ASM_FUNCTION_PROLOGUE
105 #define TARGET_ASM_FUNCTION_PROLOGUE arc_output_function_prologue
106 #undef TARGET_ASM_FUNCTION_EPILOGUE
107 #define TARGET_ASM_FUNCTION_EPILOGUE arc_output_function_epilogue
108 #undef TARGET_ATTRIBUTE_TABLE
109 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
110
111 struct gcc_target targetm = TARGET_INITIALIZER;
112 \f
113 /* Called by OVERRIDE_OPTIONS to initialize various things.  */
114
115 void
116 arc_init (void)
117 {
118   char *tmp;
119   
120   if (arc_cpu_string == 0
121       || !strcmp (arc_cpu_string, "base"))
122     {
123       /* Ensure we have a printable value for the .cpu pseudo-op.  */
124       arc_cpu_string = "base";
125       arc_cpu_type = 0;
126       arc_mangle_cpu = NULL;
127     }
128   else if (ARC_EXTENSION_CPU (arc_cpu_string))
129     ; /* nothing to do */
130   else
131     {
132       error ("bad value (%s) for -mcpu switch", arc_cpu_string);
133       arc_cpu_string = "base";
134       arc_cpu_type = 0;
135       arc_mangle_cpu = NULL;
136     }
137
138   /* Set the pseudo-ops for the various standard sections.  */
139   arc_text_section = tmp = xmalloc (strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
140   sprintf (tmp, ARC_SECTION_FORMAT, arc_text_string);
141   arc_data_section = tmp = xmalloc (strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1);
142   sprintf (tmp, ARC_SECTION_FORMAT, arc_data_string);
143   arc_rodata_section = tmp = xmalloc (strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1);
144   sprintf (tmp, ARC_SECTION_FORMAT, arc_rodata_string);
145
146   arc_init_reg_tables ();
147
148   /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P.  */
149   memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
150   arc_punct_chars['#'] = 1;
151   arc_punct_chars['*'] = 1;
152   arc_punct_chars['?'] = 1;
153   arc_punct_chars['!'] = 1;
154   arc_punct_chars['~'] = 1;
155 }
156 \f
157 /* The condition codes of the ARC, and the inverse function.  */
158 static const char *const arc_condition_codes[] =
159 {
160   "al", 0, "eq", "ne", "p", "n", "c", "nc", "v", "nv",
161   "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
162 };
163
164 #define ARC_INVERSE_CONDITION_CODE(X)  ((X) ^ 1)
165
166 /* Returns the index of the ARC condition code string in
167    `arc_condition_codes'.  COMPARISON should be an rtx like
168    `(eq (...) (...))'.  */
169
170 static int
171 get_arc_condition_code (comparison)
172      rtx comparison;
173 {
174   switch (GET_CODE (comparison))
175     {
176     case EQ : return 2;
177     case NE : return 3;
178     case GT : return 10;
179     case LE : return 11;
180     case GE : return 12;
181     case LT : return 13;
182     case GTU : return 14;
183     case LEU : return 15;
184     case LTU : return 6;
185     case GEU : return 7;
186     default : abort ();
187     }
188   /*NOTREACHED*/
189   return (42);
190 }
191
192 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
193    return the mode to be used for the comparison.  */
194
195 enum machine_mode
196 arc_select_cc_mode (op, x, y)
197      enum rtx_code op;
198      rtx x, y ATTRIBUTE_UNUSED;
199 {
200   switch (op)
201     {
202     case EQ :
203     case NE :
204       return CCZNmode;
205     default :
206       switch (GET_CODE (x))
207         {
208         case AND :
209         case IOR :
210         case XOR :
211         case SIGN_EXTEND :
212         case ZERO_EXTEND :
213           return CCZNmode;
214         case ASHIFT :
215         case ASHIFTRT :
216         case LSHIFTRT :
217           return CCZNCmode;
218         default:
219           break;
220         }
221     }
222   return CCmode;
223 }
224 \f
225 /* Vectors to keep interesting information about registers where it can easily
226    be got.  We use to use the actual mode value as the bit number, but there
227    is (or may be) more than 32 modes now.  Instead we use two tables: one
228    indexed by hard register number, and one indexed by mode.  */
229
230 /* The purpose of arc_mode_class is to shrink the range of modes so that
231    they all fit (as bit numbers) in a 32 bit word (again).  Each real mode is
232    mapped into one arc_mode_class mode.  */
233
234 enum arc_mode_class {
235   C_MODE,
236   S_MODE, D_MODE, T_MODE, O_MODE,
237   SF_MODE, DF_MODE, TF_MODE, OF_MODE
238 };
239
240 /* Modes for condition codes.  */
241 #define C_MODES (1 << (int) C_MODE)
242
243 /* Modes for single-word and smaller quantities.  */
244 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
245
246 /* Modes for double-word and smaller quantities.  */
247 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
248
249 /* Modes for quad-word and smaller quantities.  */
250 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
251
252 /* Value is 1 if register/mode pair is acceptable on arc.  */
253
254 const unsigned int arc_hard_regno_mode_ok[] = {
255   T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
256   T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
257   T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
258   D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
259
260   /* ??? Leave these as S_MODES for now.  */
261   S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
262   S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
263   S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
264   S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES
265 };
266
267 unsigned int arc_mode_class [NUM_MACHINE_MODES];
268
269 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
270
271 static void
272 arc_init_reg_tables ()
273 {
274   int i;
275
276   for (i = 0; i < NUM_MACHINE_MODES; i++)
277     {
278       switch (GET_MODE_CLASS (i))
279         {
280         case MODE_INT:
281         case MODE_PARTIAL_INT:
282         case MODE_COMPLEX_INT:
283           if (GET_MODE_SIZE (i) <= 4)
284             arc_mode_class[i] = 1 << (int) S_MODE;
285           else if (GET_MODE_SIZE (i) == 8)
286             arc_mode_class[i] = 1 << (int) D_MODE;
287           else if (GET_MODE_SIZE (i) == 16)
288             arc_mode_class[i] = 1 << (int) T_MODE;
289           else if (GET_MODE_SIZE (i) == 32)
290             arc_mode_class[i] = 1 << (int) O_MODE;
291           else 
292             arc_mode_class[i] = 0;
293           break;
294         case MODE_FLOAT:
295         case MODE_COMPLEX_FLOAT:
296           if (GET_MODE_SIZE (i) <= 4)
297             arc_mode_class[i] = 1 << (int) SF_MODE;
298           else if (GET_MODE_SIZE (i) == 8)
299             arc_mode_class[i] = 1 << (int) DF_MODE;
300           else if (GET_MODE_SIZE (i) == 16)
301             arc_mode_class[i] = 1 << (int) TF_MODE;
302           else if (GET_MODE_SIZE (i) == 32)
303             arc_mode_class[i] = 1 << (int) OF_MODE;
304           else 
305             arc_mode_class[i] = 0;
306           break;
307         case MODE_CC:
308         default:
309           /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
310              we must explicitly check for them here.  */
311           if (i == (int) CCmode || i == (int) CCZNmode || i == (int) CCZNCmode)
312             arc_mode_class[i] = 1 << (int) C_MODE;
313           else
314             arc_mode_class[i] = 0;
315           break;
316         }
317     }
318
319   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
320     {
321       if (i < 60)
322         arc_regno_reg_class[i] = GENERAL_REGS;
323       else if (i == 60)
324         arc_regno_reg_class[i] = LPCOUNT_REG;
325       else if (i == 61)
326         arc_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
327       else
328         arc_regno_reg_class[i] = NO_REGS;
329     }
330 }
331 \f
332 /* ARC specific attribute support.
333
334    The ARC has these attributes:
335    interrupt - for interrupt functions
336 */
337
338 const struct attribute_spec arc_attribute_table[] =
339 {
340   /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
341   { "interrupt", 1, 1, true,  false, false, arc_handle_interrupt_attribute },
342   { NULL,        0, 0, false, false, false, NULL }
343 };
344
345 /* Handle an "interrupt" attribute; arguments as in
346    struct attribute_spec.handler.  */
347 static tree
348 arc_handle_interrupt_attribute (node, name, args, flags, no_add_attrs)
349      tree *node ATTRIBUTE_UNUSED;
350      tree name;
351      tree args;
352      int flags ATTRIBUTE_UNUSED;
353      bool *no_add_attrs;
354 {
355   tree value = TREE_VALUE (args);
356
357   if (TREE_CODE (value) != STRING_CST)
358     {
359       warning ("argument of `%s' attribute is not a string constant",
360                IDENTIFIER_POINTER (name));
361       *no_add_attrs = true;
362     }
363   else if (strcmp (TREE_STRING_POINTER (value), "ilink1")
364            && strcmp (TREE_STRING_POINTER (value), "ilink2"))
365     {
366       warning ("argument of `%s' attribute is not \"ilink1\" or \"ilink2\"",
367                IDENTIFIER_POINTER (name));
368       *no_add_attrs = true;
369     }
370
371   return NULL_TREE;
372 }
373
374 \f
375 /* Acceptable arguments to the call insn.  */
376
377 int
378 call_address_operand (op, mode)
379      rtx op;
380      enum machine_mode mode;
381 {
382   return (symbolic_operand (op, mode)
383           || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
384           || (GET_CODE (op) == REG));
385 }
386
387 int
388 call_operand (op, mode)
389      rtx op;
390      enum machine_mode mode;
391 {
392   if (GET_CODE (op) != MEM)
393     return 0;
394   op = XEXP (op, 0);
395   return call_address_operand (op, mode);
396 }
397
398 /* Returns 1 if OP is a symbol reference.  */
399
400 int
401 symbolic_operand (op, mode)
402      rtx op;
403      enum machine_mode mode ATTRIBUTE_UNUSED;
404 {
405   switch (GET_CODE (op))
406     {
407     case SYMBOL_REF:
408     case LABEL_REF:
409     case CONST :
410       return 1;
411     default:
412       return 0;
413     }
414 }
415
416 /* Return truth value of statement that OP is a symbolic memory
417    operand of mode MODE.  */
418
419 int
420 symbolic_memory_operand (op, mode)
421      rtx op;
422      enum machine_mode mode ATTRIBUTE_UNUSED;
423 {
424   if (GET_CODE (op) == SUBREG)
425     op = SUBREG_REG (op);
426   if (GET_CODE (op) != MEM)
427     return 0;
428   op = XEXP (op, 0);
429   return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
430           || GET_CODE (op) == LABEL_REF);
431 }
432
433 /* Return true if OP is a short immediate (shimm) value.  */
434
435 int
436 short_immediate_operand (op, mode)
437      rtx op;
438      enum machine_mode mode ATTRIBUTE_UNUSED;
439 {
440   if (GET_CODE (op) != CONST_INT)
441     return 0;
442   return SMALL_INT (INTVAL (op));
443 }
444
445 /* Return true if OP will require a long immediate (limm) value.
446    This is currently only used when calculating length attributes.  */
447
448 int
449 long_immediate_operand (op, mode)
450      rtx op;
451      enum machine_mode mode ATTRIBUTE_UNUSED;
452 {
453   switch (GET_CODE (op))
454     {
455     case SYMBOL_REF :
456     case LABEL_REF :
457     case CONST :
458       return 1;
459     case CONST_INT :
460       return !SMALL_INT (INTVAL (op));
461     case CONST_DOUBLE :
462       /* These can happen because large unsigned 32 bit constants are
463          represented this way (the multiplication patterns can cause these
464          to be generated).  They also occur for SFmode values.  */
465       return 1;
466     default:
467       break;
468     }
469   return 0;
470 }
471
472 /* Return true if OP is a MEM that when used as a load or store address will
473    require an 8 byte insn.
474    Load and store instructions don't allow the same possibilities but they're
475    similar enough that this one function will do.
476    This is currently only used when calculating length attributes.  */
477
478 int
479 long_immediate_loadstore_operand (op, mode)
480      rtx op;
481      enum machine_mode mode ATTRIBUTE_UNUSED;
482 {
483   if (GET_CODE (op) != MEM)
484     return 0;
485
486   op = XEXP (op, 0);
487   switch (GET_CODE (op))
488     {
489     case SYMBOL_REF :
490     case LABEL_REF :
491     case CONST :
492       return 1;
493     case CONST_INT :
494       /* This must be handled as "st c,[limm]".  Ditto for load.
495          Technically, the assembler could translate some possibilities to
496          "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't
497          assume that it does.  */
498       return 1;
499     case CONST_DOUBLE :
500       /* These can happen because large unsigned 32 bit constants are
501          represented this way (the multiplication patterns can cause these
502          to be generated).  They also occur for SFmode values.  */
503       return 1;
504     case REG :
505       return 0;
506     case PLUS :
507       if (GET_CODE (XEXP (op, 1)) == CONST_INT
508           && !SMALL_INT (INTVAL (XEXP (op, 1))))
509         return 1;
510       return 0;
511     default:
512       break;
513     }
514   return 0;
515 }
516
517 /* Return true if OP is an acceptable argument for a single word
518    move source.  */
519
520 int
521 move_src_operand (op, mode)
522      rtx op;
523      enum machine_mode mode;
524 {
525   switch (GET_CODE (op))
526     {
527     case SYMBOL_REF :
528     case LABEL_REF :
529     case CONST :
530       return 1;
531     case CONST_INT :
532       return (LARGE_INT (INTVAL (op)));
533     case CONST_DOUBLE :
534       /* We can handle DImode integer constants in SImode if the value
535          (signed or unsigned) will fit in 32 bits.  This is needed because
536          large unsigned 32 bit constants are represented as CONST_DOUBLEs.  */
537       if (mode == SImode)
538         return arc_double_limm_p (op);
539       /* We can handle 32 bit floating point constants.  */
540       if (mode == SFmode)
541         return GET_MODE (op) == SFmode;
542       return 0;
543     case REG :
544       return register_operand (op, mode);
545     case SUBREG :
546       /* (subreg (mem ...) ...) can occur here if the inner part was once a
547          pseudo-reg and is now a stack slot.  */
548       if (GET_CODE (SUBREG_REG (op)) == MEM)
549         return address_operand (XEXP (SUBREG_REG (op), 0), mode);
550       else
551         return register_operand (op, mode);
552     case MEM :
553       return address_operand (XEXP (op, 0), mode);
554     default :
555       return 0;
556     }
557 }
558
559 /* Return true if OP is an acceptable argument for a double word
560    move source.  */
561
562 int
563 move_double_src_operand (op, mode)
564      rtx op;
565      enum machine_mode mode;
566 {
567   switch (GET_CODE (op))
568     {
569     case REG :
570       return register_operand (op, mode);
571     case SUBREG :
572       /* (subreg (mem ...) ...) can occur here if the inner part was once a
573          pseudo-reg and is now a stack slot.  */
574       if (GET_CODE (SUBREG_REG (op)) == MEM)
575         return move_double_src_operand (SUBREG_REG (op), mode);
576       else
577         return register_operand (op, mode);
578     case MEM :
579       /* Disallow auto inc/dec for now.  */
580       if (GET_CODE (XEXP (op, 0)) == PRE_DEC
581           || GET_CODE (XEXP (op, 0)) == PRE_INC)
582         return 0;
583       return address_operand (XEXP (op, 0), mode);
584     case CONST_INT :
585     case CONST_DOUBLE :
586       return 1;
587     default :
588       return 0;
589     }
590 }
591
592 /* Return true if OP is an acceptable argument for a move destination.  */
593
594 int
595 move_dest_operand (op, mode)
596      rtx op;
597      enum machine_mode mode;
598 {
599   switch (GET_CODE (op))
600     {
601     case REG :
602       return register_operand (op, mode);
603     case SUBREG :
604       /* (subreg (mem ...) ...) can occur here if the inner part was once a
605          pseudo-reg and is now a stack slot.  */
606       if (GET_CODE (SUBREG_REG (op)) == MEM)
607         return address_operand (XEXP (SUBREG_REG (op), 0), mode);
608       else
609         return register_operand (op, mode);
610     case MEM :
611       return address_operand (XEXP (op, 0), mode);
612     default :
613       return 0;
614     }
615 }
616
617 /* Return true if OP is valid load with update operand.  */
618
619 int
620 load_update_operand (op, mode)
621      rtx op;
622      enum machine_mode mode;
623 {
624   if (GET_CODE (op) != MEM
625       || GET_MODE (op) != mode)
626     return 0;
627   op = XEXP (op, 0);
628   if (GET_CODE (op) != PLUS
629       || GET_MODE (op) != Pmode
630       || !register_operand (XEXP (op, 0), Pmode)
631       || !nonmemory_operand (XEXP (op, 1), Pmode))
632     return 0;
633   return 1;
634 }
635
636 /* Return true if OP is valid store with update operand.  */
637
638 int
639 store_update_operand (op, mode)
640      rtx op;
641      enum machine_mode mode;
642 {
643   if (GET_CODE (op) != MEM
644       || GET_MODE (op) != mode)
645     return 0;
646   op = XEXP (op, 0);
647   if (GET_CODE (op) != PLUS
648       || GET_MODE (op) != Pmode
649       || !register_operand (XEXP (op, 0), Pmode)
650       || !(GET_CODE (XEXP (op, 1)) == CONST_INT
651            && SMALL_INT (INTVAL (XEXP (op, 1)))))
652     return 0;
653   return 1;
654 }
655
656 /* Return true if OP is a non-volatile non-immediate operand.
657    Volatile memory refs require a special "cache-bypass" instruction
658    and only the standard movXX patterns are set up to handle them.  */
659
660 int
661 nonvol_nonimm_operand (op, mode)
662      rtx op;
663      enum machine_mode mode;
664 {
665   if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
666     return 0;
667   return nonimmediate_operand (op, mode);
668 }
669
670 /* Accept integer operands in the range -0x80000000..0x7fffffff.  We have
671    to check the range carefully since this predicate is used in DImode
672    contexts.  */
673
674 int
675 const_sint32_operand (op, mode)
676      rtx op;
677      enum machine_mode mode ATTRIBUTE_UNUSED;
678 {
679   /* All allowed constants will fit a CONST_INT.  */
680   return (GET_CODE (op) == CONST_INT
681           && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
682 }
683
684 /* Accept integer operands in the range 0..0xffffffff.  We have to check the
685    range carefully since this predicate is used in DImode contexts.  Also, we
686    need some extra crud to make it work when hosted on 64-bit machines.  */
687
688 int
689 const_uint32_operand (op, mode)
690      rtx op;
691      enum machine_mode mode ATTRIBUTE_UNUSED;
692 {
693 #if HOST_BITS_PER_WIDE_INT > 32
694   /* All allowed constants will fit a CONST_INT.  */
695   return (GET_CODE (op) == CONST_INT
696           && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
697 #else
698   return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
699           || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
700 #endif
701 }
702
703 /* Return 1 if OP is a comparison operator valid for the mode of CC.
704    This allows the use of MATCH_OPERATOR to recognize all the branch insns.
705
706    Some insns only set a few bits in the condition code.  So only allow those
707    comparisons that use the bits that are valid.  */
708
709 int
710 proper_comparison_operator (op, mode)
711     rtx op;
712     enum machine_mode mode ATTRIBUTE_UNUSED;
713 {
714   enum rtx_code code = GET_CODE (op);
715
716   if (GET_RTX_CLASS (code) != '<')
717     return 0;
718
719   if (GET_MODE (XEXP (op, 0)) == CCZNmode)
720     return (code == EQ || code == NE);
721   if (GET_MODE (XEXP (op, 0)) == CCZNCmode)
722     return (code == EQ || code == NE
723             || code == LTU || code == GEU || code == GTU || code == LEU);
724   return 1;
725 }
726 \f
727 /* Misc. utilities.  */
728
729 /* X and Y are two things to compare using CODE.  Emit the compare insn and
730    return the rtx for the cc reg in the proper mode.  */
731
732 rtx
733 gen_compare_reg (code, x, y)
734      enum rtx_code code;
735      rtx x, y;
736 {
737   enum machine_mode mode = SELECT_CC_MODE (code, x, y);
738   rtx cc_reg;
739
740   cc_reg = gen_rtx_REG (mode, 61);
741
742   emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
743                           gen_rtx_COMPARE (mode, x, y)));
744
745   return cc_reg;
746 }
747
748 /* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
749    We assume the value can be either signed or unsigned.  */
750
751 int
752 arc_double_limm_p (value)
753      rtx value;
754 {
755   HOST_WIDE_INT low, high;
756
757   if (GET_CODE (value) != CONST_DOUBLE)
758     abort ();
759
760   low = CONST_DOUBLE_LOW (value);
761   high = CONST_DOUBLE_HIGH (value);
762
763   if (low & 0x80000000)
764     {
765       return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
766               || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
767                    == - (unsigned HOST_WIDE_INT) 0x80000000)
768                   && high == -1));
769     }
770   else
771     {
772       return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
773     }
774 }
775 \f
776 /* Do any needed setup for a variadic function.  For the ARC, we must
777    create a register parameter block, and then copy any anonymous arguments
778    in registers to memory.
779
780    CUM has not been updated for the last named argument which has type TYPE
781    and mode MODE, and we rely on this fact.
782
783    We do things a little weird here.  We're supposed to only allocate space
784    for the anonymous arguments.  However we need to keep the stack eight byte
785    aligned.  So we round the space up if necessary, and leave it to va_start
786    to compensate.  */
787
788 void
789 arc_setup_incoming_varargs (cum, mode, type, pretend_size, no_rtl)
790      CUMULATIVE_ARGS *cum;
791      enum machine_mode mode;
792      tree type ATTRIBUTE_UNUSED;
793      int *pretend_size;
794      int no_rtl;
795 {
796   int first_anon_arg;
797
798   /* All BLKmode values are passed by reference.  */
799   if (mode == BLKmode)
800     abort ();
801
802   /* We must treat `__builtin_va_alist' as an anonymous arg.  */
803   if (current_function_varargs)
804     first_anon_arg = *cum;
805   else
806     first_anon_arg = *cum + ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
807                              / UNITS_PER_WORD);
808
809   if (first_anon_arg < MAX_ARC_PARM_REGS && !no_rtl)
810     {
811       /* Note that first_reg_offset < MAX_ARC_PARM_REGS.  */
812       int first_reg_offset = first_anon_arg;
813       /* Size in words to "pretend" allocate.  */
814       int size = MAX_ARC_PARM_REGS - first_reg_offset;
815       /* Extra slop to keep stack eight byte aligned.  */
816       int align_slop = size & 1;
817       rtx regblock;
818
819       regblock = gen_rtx_MEM (BLKmode,
820                               plus_constant (arg_pointer_rtx,
821                                              FIRST_PARM_OFFSET (0)
822                                              + align_slop * UNITS_PER_WORD));
823       set_mem_alias_set (regblock, get_varargs_alias_set ());
824       set_mem_align (regblock, BITS_PER_WORD);
825       move_block_from_reg (first_reg_offset, regblock,
826                            MAX_ARC_PARM_REGS - first_reg_offset,
827                            ((MAX_ARC_PARM_REGS - first_reg_offset)
828                             * UNITS_PER_WORD));
829
830       *pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
831                        * UNITS_PER_WORD);
832     }
833 }
834 \f
835 /* Cost functions.  */
836
837 /* Provide the costs of an addressing mode that contains ADDR.
838    If ADDR is not a valid address, its cost is irrelevant.  */
839
840 int
841 arc_address_cost (addr)
842      rtx addr;
843 {
844   switch (GET_CODE (addr))
845     {
846     case REG :
847       /* This is handled in the macro that calls us.
848          It's here for documentation.  */
849       return 1;
850
851     case LABEL_REF :
852     case SYMBOL_REF :
853     case CONST :
854       return 2;
855
856     case PLUS :
857       {
858         register rtx plus0 = XEXP (addr, 0);
859         register rtx plus1 = XEXP (addr, 1);
860
861         if (GET_CODE (plus0) != REG)
862           break;
863
864         switch (GET_CODE (plus1))
865           {
866           case CONST_INT :
867             return SMALL_INT (plus1) ? 1 : 2;
868           case CONST :
869           case SYMBOL_REF :
870           case LABEL_REF :
871             return 2;
872           default:
873             break;
874           }
875         break;
876       }
877     default:
878       break;
879     }
880
881   return 4;
882 }
883 \f
884 /* Function prologue/epilogue handlers.  */
885
886 /* ARC stack frames look like:
887
888              Before call                       After call
889         +-----------------------+       +-----------------------+
890         |                       |       |                       |
891    high |  local variables,     |       |  local variables,     |
892    mem  |  reg save area, etc.  |       |  reg save area, etc.  |
893         |                       |       |                       |
894         +-----------------------+       +-----------------------+
895         |                       |       |                       |
896         |  arguments on stack.  |       |  arguments on stack.  |
897         |                       |       |                       |
898  SP+16->+-----------------------+FP+48->+-----------------------+
899         | 4 word save area for  |       |  reg parm save area,  |
900         | return addr, prev %fp |       |  only created for     |    
901   SP+0->+-----------------------+       |  variable argument    |    
902                                         |  functions            |    
903                                  FP+16->+-----------------------+    
904                                         | 4 word save area for  |    
905                                         | return addr, prev %fp |    
906                                   FP+0->+-----------------------+    
907                                         |                       |    
908                                         |  local variables      |    
909                                         |                       |    
910                                         +-----------------------+    
911                                         |                       |    
912                                         |  register save area   |    
913                                         |                       |    
914                                         +-----------------------+    
915                                         |                       |    
916                                         |  alloca allocations   |    
917                                         |                       |    
918                                         +-----------------------+    
919                                         |                       |    
920                                         |  arguments on stack   |    
921                                         |                       |    
922                                  SP+16->+-----------------------+
923    low                                  | 4 word save area for  |    
924    memory                               | return addr, prev %fp |    
925                                   SP+0->+-----------------------+    
926
927 Notes:
928 1) The "reg parm save area" does not exist for non variable argument fns.
929    The "reg parm save area" can be eliminated completely if we created our
930    own va-arc.h, but that has tradeoffs as well (so it's not done).  */
931
932 /* Structure to be filled in by arc_compute_frame_size with register
933    save masks, and offsets for the current function.  */
934 struct arc_frame_info
935 {
936   unsigned int total_size;      /* # bytes that the entire frame takes up.  */
937   unsigned int extra_size;      /* # bytes of extra stuff.  */
938   unsigned int pretend_size;    /* # bytes we push and pretend caller did.  */
939   unsigned int args_size;       /* # bytes that outgoing arguments take up.  */
940   unsigned int reg_size;        /* # bytes needed to store regs.  */
941   unsigned int var_size;        /* # bytes that variables take up.  */
942   unsigned int reg_offset;      /* Offset from new sp to store regs.  */
943   unsigned int gmask;           /* Mask of saved gp registers.  */
944   int          initialized;     /* Nonzero if frame size already calculated.  */
945 };
946
947 /* Current frame information calculated by arc_compute_frame_size.  */
948 static struct arc_frame_info current_frame_info;
949
950 /* Zero structure to initialize current_frame_info.  */
951 static struct arc_frame_info zero_frame_info;
952
953 /* Type of function DECL.
954
955    The result is cached.  To reset the cache at the end of a function,
956    call with DECL = NULL_TREE.  */
957
958 enum arc_function_type
959 arc_compute_function_type (decl)
960      tree decl;
961 {
962   tree a;
963   /* Cached value.  */
964   static enum arc_function_type fn_type = ARC_FUNCTION_UNKNOWN;
965   /* Last function we were called for.  */
966   static tree last_fn = NULL_TREE;
967
968   /* Resetting the cached value?  */
969   if (decl == NULL_TREE)
970     {
971       fn_type = ARC_FUNCTION_UNKNOWN;
972       last_fn = NULL_TREE;
973       return fn_type;
974     }
975
976   if (decl == last_fn && fn_type != ARC_FUNCTION_UNKNOWN)
977     return fn_type;
978
979   /* Assume we have a normal function (not an interrupt handler).  */
980   fn_type = ARC_FUNCTION_NORMAL;
981
982   /* Now see if this is an interrupt handler.  */
983   for (a = DECL_ATTRIBUTES (current_function_decl);
984        a;
985        a = TREE_CHAIN (a))
986     {
987       tree name = TREE_PURPOSE (a), args = TREE_VALUE (a);
988
989       if (name == get_identifier ("__interrupt__")
990           && list_length (args) == 1
991           && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
992         {
993           tree value = TREE_VALUE (args);
994
995           if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
996             fn_type = ARC_FUNCTION_ILINK1;
997           else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
998             fn_type = ARC_FUNCTION_ILINK2;
999           else
1000             abort ();
1001           break;
1002         }
1003     }
1004
1005   last_fn = decl;
1006   return fn_type;
1007 }
1008
1009 #define ILINK1_REGNUM 29
1010 #define ILINK2_REGNUM 30
1011 #define RETURN_ADDR_REGNUM 31
1012 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
1013 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
1014
1015 /* Tell prologue and epilogue if register REGNO should be saved / restored.
1016    The return address and frame pointer are treated separately.
1017    Don't consider them here.  */
1018 #define MUST_SAVE_REGISTER(regno, interrupt_p) \
1019 ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
1020  && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
1021
1022 #define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
1023
1024 /* Return the bytes needed to compute the frame pointer from the current
1025    stack pointer.
1026
1027    SIZE is the size needed for local variables.  */
1028
1029 unsigned int
1030 arc_compute_frame_size (size)
1031      int size;                  /* # of var. bytes allocated.  */
1032 {
1033   int regno;
1034   unsigned int total_size, var_size, args_size, pretend_size, extra_size;
1035   unsigned int reg_size, reg_offset;
1036   unsigned int gmask;
1037   enum arc_function_type fn_type;
1038   int interrupt_p;
1039
1040   var_size      = size;
1041   args_size     = current_function_outgoing_args_size;
1042   pretend_size  = current_function_pretend_args_size;
1043   extra_size    = FIRST_PARM_OFFSET (0);
1044   total_size    = extra_size + pretend_size + args_size + var_size;
1045   reg_offset    = FIRST_PARM_OFFSET(0) + current_function_outgoing_args_size;
1046   reg_size      = 0;
1047   gmask         = 0;
1048
1049   /* See if this is an interrupt handler.  Call used registers must be saved
1050      for them too.  */
1051   fn_type = arc_compute_function_type (current_function_decl);
1052   interrupt_p = ARC_INTERRUPT_P (fn_type);
1053
1054   /* Calculate space needed for registers.
1055      ??? We ignore the extension registers for now.  */
1056
1057   for (regno = 0; regno <= 31; regno++)
1058     {
1059       if (MUST_SAVE_REGISTER (regno, interrupt_p))
1060         {
1061           reg_size += UNITS_PER_WORD;
1062           gmask |= 1 << regno;
1063         }
1064     }
1065
1066   total_size += reg_size;
1067
1068   /* If the only space to allocate is the fp/blink save area this is an
1069      empty frame.  However, if we'll be making a function call we need to
1070      allocate a stack frame for our callee's fp/blink save area.  */
1071   if (total_size == extra_size
1072       && !MUST_SAVE_RETURN_ADDR)
1073     total_size = extra_size = 0;
1074
1075   total_size = ARC_STACK_ALIGN (total_size);
1076
1077   /* Save computed information.  */
1078   current_frame_info.total_size   = total_size;
1079   current_frame_info.extra_size   = extra_size;
1080   current_frame_info.pretend_size = pretend_size;
1081   current_frame_info.var_size     = var_size;
1082   current_frame_info.args_size    = args_size;
1083   current_frame_info.reg_size     = reg_size;
1084   current_frame_info.reg_offset   = reg_offset;
1085   current_frame_info.gmask        = gmask;
1086   current_frame_info.initialized  = reload_completed;
1087
1088   /* Ok, we're done.  */
1089   return total_size;
1090 }
1091 \f
1092 /* Common code to save/restore registers.  */
1093
1094 void
1095 arc_save_restore (file, base_reg, offset, gmask, op)
1096      FILE *file;
1097      const char *base_reg;
1098      unsigned int offset;
1099      unsigned int gmask;
1100      const char *op;
1101 {
1102   int regno;
1103
1104   if (gmask == 0)
1105     return;
1106
1107   for (regno = 0; regno <= 31; regno++)
1108     {
1109       if ((gmask & (1L << regno)) != 0)
1110         {
1111           fprintf (file, "\t%s %s,[%s,%d]\n",
1112                      op, reg_names[regno], base_reg, offset);
1113           offset += UNITS_PER_WORD;
1114         }
1115     }
1116 }
1117 \f
1118 /* Target hook to assemble an integer object.  The ARC version needs to
1119    emit a special directive for references to labels and function
1120    symbols.  */
1121
1122 static bool
1123 arc_assemble_integer (x, size, aligned_p)
1124      rtx x;
1125      unsigned int size;
1126      int aligned_p;
1127 {
1128   if (size == UNITS_PER_WORD && aligned_p
1129       && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
1130           || GET_CODE (x) == LABEL_REF))
1131     {
1132       fputs ("\t.word\t%st(", asm_out_file);
1133       output_addr_const (asm_out_file, x);
1134       fputs (")\n", asm_out_file);
1135       return true;
1136     }
1137   return default_assemble_integer (x, size, aligned_p);
1138 }
1139 \f
1140 /* Set up the stack and frame pointer (if desired) for the function.  */
1141
1142 static void
1143 arc_output_function_prologue (file, size)
1144      FILE *file;
1145      HOST_WIDE_INT size;
1146 {
1147   const char *sp_str = reg_names[STACK_POINTER_REGNUM];
1148   const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
1149   unsigned int gmask = current_frame_info.gmask;
1150   enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
1151
1152   /* If this is an interrupt handler, set up our stack frame.
1153      ??? Optimize later.  */
1154   if (ARC_INTERRUPT_P (fn_type))
1155     {
1156       fprintf (file, "\t%s interrupt handler\n",
1157                ASM_COMMENT_START);
1158       fprintf (file, "\tsub %s,%s,16\n", sp_str, sp_str);
1159     }
1160
1161   /* This is only for the human reader.  */
1162   fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
1163            ASM_COMMENT_START, ASM_COMMENT_START,
1164            current_frame_info.var_size,
1165            current_frame_info.reg_size / 4,
1166            current_frame_info.args_size,
1167            current_frame_info.extra_size);
1168
1169   size = ARC_STACK_ALIGN (size);
1170   size = (! current_frame_info.initialized
1171            ? arc_compute_frame_size (size)
1172            : current_frame_info.total_size);
1173
1174   /* These cases shouldn't happen.  Catch them now.  */
1175   if (size == 0 && gmask)
1176     abort ();
1177
1178   /* Allocate space for register arguments if this is a variadic function.  */
1179   if (current_frame_info.pretend_size != 0)
1180     fprintf (file, "\tsub %s,%s,%d\n",
1181              sp_str, sp_str, current_frame_info.pretend_size);
1182
1183   /* The home-grown ABI says link register is saved first.  */
1184   if (MUST_SAVE_RETURN_ADDR)
1185     fprintf (file, "\tst %s,[%s,%d]\n",
1186              reg_names[RETURN_ADDR_REGNUM], sp_str, UNITS_PER_WORD);
1187
1188   /* Set up the previous frame pointer next (if we need to).  */
1189   if (frame_pointer_needed)
1190     {
1191       fprintf (file, "\tst %s,[%s]\n", fp_str, sp_str);
1192       fprintf (file, "\tmov %s,%s\n", fp_str, sp_str);
1193     }
1194
1195   /* ??? We don't handle the case where the saved regs are more than 252
1196      bytes away from sp.  This can be handled by decrementing sp once, saving
1197      the regs, and then decrementing it again.  The epilogue doesn't have this
1198      problem as the `ld' insn takes reg+limm values (though it would be more
1199      efficient to avoid reg+limm).  */
1200
1201   /* Allocate the stack frame.  */
1202   if (size - current_frame_info.pretend_size > 0)
1203     fprintf (file, "\tsub %s,%s,%d\n",
1204              sp_str, sp_str, size - current_frame_info.pretend_size);
1205
1206   /* Save any needed call-saved regs (and call-used if this is an
1207      interrupt handler).  */
1208   arc_save_restore (file, sp_str, current_frame_info.reg_offset,
1209                     /* The zeroing of these two bits is unnecessary,
1210                        but leave this in for clarity.  */
1211                     gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
1212                     "st");
1213
1214   fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
1215 }
1216 \f
1217 /* Do any necessary cleanup after a function to restore stack, frame,
1218    and regs.  */
1219
1220 static void
1221 arc_output_function_epilogue (file, size)
1222      FILE *file;
1223      HOST_WIDE_INT size;
1224 {
1225   rtx epilogue_delay = current_function_epilogue_delay_list;
1226   int noepilogue = FALSE;
1227   enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
1228
1229   /* This is only for the human reader.  */
1230   fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
1231
1232   size = ARC_STACK_ALIGN (size);
1233   size = (!current_frame_info.initialized
1234            ? arc_compute_frame_size (size)
1235            : current_frame_info.total_size);
1236
1237   if (size == 0 && epilogue_delay == 0)
1238     {
1239       rtx insn = get_last_insn ();
1240
1241       /* If the last insn was a BARRIER, we don't have to write any code
1242          because a jump (aka return) was put there.  */
1243       if (GET_CODE (insn) == NOTE)
1244         insn = prev_nonnote_insn (insn);
1245       if (insn && GET_CODE (insn) == BARRIER)
1246         noepilogue = TRUE;
1247     }
1248
1249   if (!noepilogue)
1250     {
1251       unsigned int pretend_size = current_frame_info.pretend_size;
1252       unsigned int frame_size = size - pretend_size;
1253       int restored, fp_restored_p;
1254       int can_trust_sp_p = !current_function_calls_alloca;
1255       const char *sp_str = reg_names[STACK_POINTER_REGNUM];
1256       const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
1257
1258       /* ??? There are lots of optimizations that can be done here.
1259          EG: Use fp to restore regs if it's closer.
1260          Maybe in time we'll do them all.  For now, always restore regs from
1261          sp, but don't restore sp if we don't have to.  */
1262
1263       if (!can_trust_sp_p)
1264         {
1265           if (!frame_pointer_needed)
1266             abort ();
1267           fprintf (file,"\tsub %s,%s,%d\t\t%s sp not trusted here\n",
1268                    sp_str, fp_str, frame_size, ASM_COMMENT_START);
1269         }
1270
1271       /* Restore any saved registers.  */
1272       arc_save_restore (file, sp_str, current_frame_info.reg_offset,
1273                         /* The zeroing of these two bits is unnecessary,
1274                            but leave this in for clarity.  */
1275                         current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
1276                         "ld");
1277
1278       if (MUST_SAVE_RETURN_ADDR)
1279         fprintf (file, "\tld %s,[%s,%d]\n",
1280                  reg_names[RETURN_ADDR_REGNUM],
1281                  frame_pointer_needed ? fp_str : sp_str,
1282                  UNITS_PER_WORD + (frame_pointer_needed ? 0 : frame_size));
1283
1284       /* Keep track of how much of the stack pointer we've restored.
1285          It makes the following a lot more readable.  */
1286       restored = 0;
1287       fp_restored_p = 0;
1288
1289       /* We try to emit the epilogue delay slot insn right after the load
1290          of the return address register so that it can execute with the
1291          stack intact.  Secondly, loads are delayed.  */
1292       /* ??? If stack intactness is important, always emit now.  */
1293       if (MUST_SAVE_RETURN_ADDR && epilogue_delay != NULL_RTX)
1294         {
1295           final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
1296           epilogue_delay = NULL_RTX;
1297         }
1298
1299       if (frame_pointer_needed)
1300         {
1301           /* Try to restore the frame pointer in the delay slot.  We can't,
1302              however, if any of these is true.  */
1303           if (epilogue_delay != NULL_RTX
1304               || !SMALL_INT (frame_size)
1305               || pretend_size
1306               || ARC_INTERRUPT_P (fn_type))
1307             {
1308               /* Note that we restore fp and sp here!  */
1309               fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
1310               restored += frame_size;
1311               fp_restored_p = 1;
1312             }
1313         }
1314       else if (!SMALL_INT (size /* frame_size + pretend_size */)
1315                || ARC_INTERRUPT_P (fn_type))
1316         {
1317           fprintf (file, "\tadd %s,%s,%d\n", sp_str, sp_str, frame_size);
1318           restored += frame_size;
1319         }
1320
1321       /* These must be done before the return insn because the delay slot
1322          does the final stack restore.  */
1323       if (ARC_INTERRUPT_P (fn_type))
1324         {
1325           if (epilogue_delay)
1326             {
1327               final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
1328             }
1329         }
1330
1331       /* Emit the return instruction.  */
1332       {
1333         static const int regs[4] = {
1334           0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM
1335         };
1336         fprintf (file, "\tj.d %s\n", reg_names[regs[fn_type]]);
1337       }
1338
1339       /* If the only register saved is the return address, we need a
1340          nop, unless we have an instruction to put into it.  Otherwise
1341          we don't since reloading multiple registers doesn't reference
1342          the register being loaded.  */
1343
1344       if (ARC_INTERRUPT_P (fn_type))
1345         fprintf (file, "\tadd %s,%s,16\n", sp_str, sp_str);
1346       else if (epilogue_delay != NULL_RTX)
1347         {
1348           if (frame_pointer_needed && !fp_restored_p)
1349             abort ();
1350           if (restored < size)
1351             abort ();
1352           final_scan_insn (XEXP (epilogue_delay, 0), file, 1, -2, 1);
1353         }
1354       else if (frame_pointer_needed && !fp_restored_p)
1355         {
1356           if (!SMALL_INT (frame_size))
1357             abort ();
1358           /* Note that we restore fp and sp here!  */
1359           fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
1360         }
1361       else if (restored < size)
1362         {
1363           if (!SMALL_INT (size - restored))
1364             abort ();
1365           fprintf (file, "\tadd %s,%s,%d\n",
1366                    sp_str, sp_str, size - restored);
1367         }
1368       else
1369         fprintf (file, "\tnop\n");
1370     }
1371
1372   /* Reset state info for each function.  */
1373   current_frame_info = zero_frame_info;
1374   arc_compute_function_type (NULL_TREE);
1375 }
1376 \f
1377 /* Define the number of delay slots needed for the function epilogue.
1378
1379    Interrupt handlers can't have any epilogue delay slots (it's always needed
1380    for something else, I think).  For normal functions, we have to worry about
1381    using call-saved regs as they'll be restored before the delay slot insn.
1382    Functions with non-empty frames already have enough choices for the epilogue
1383    delay slot so for now we only consider functions with empty frames.  */
1384
1385 int
1386 arc_delay_slots_for_epilogue ()
1387 {
1388   if (arc_compute_function_type (current_function_decl) != ARC_FUNCTION_NORMAL)
1389     return 0;
1390   if (!current_frame_info.initialized)
1391     (void) arc_compute_frame_size (get_frame_size ());
1392   if (current_frame_info.total_size == 0)
1393     return 1;
1394   return 0;
1395 }
1396
1397 /* Return true if TRIAL is a valid insn for the epilogue delay slot.
1398    Any single length instruction which doesn't reference the stack or frame
1399    pointer or any call-saved register is OK.  SLOT will always be 0.  */
1400
1401 int
1402 arc_eligible_for_epilogue_delay (trial, slot)
1403      rtx trial;
1404      int slot;
1405 {
1406   if (slot != 0)
1407     abort ();
1408
1409   if (get_attr_length (trial) == 1
1410       /* If registers where saved, presumably there's more than enough
1411          possibilities for the delay slot.  The alternative is something
1412          more complicated (of course, if we expanded the epilogue as rtl
1413          this problem would go away).  */
1414       /* ??? Note that this will always be true since only functions with
1415          empty frames have epilogue delay slots.  See
1416          arc_delay_slots_for_epilogue.  */
1417       && current_frame_info.gmask == 0
1418       && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
1419       && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
1420     return 1;
1421   return 0;
1422 }
1423 \f
1424 /* PIC */
1425
1426 /* Emit special PIC prologues and epilogues.  */
1427
1428 void
1429 arc_finalize_pic ()
1430 {
1431   /* nothing to do */
1432 }
1433 \f
1434 /* Return true if OP is a shift operator.  */
1435
1436 int
1437 shift_operator (op, mode)
1438      rtx op;
1439      enum machine_mode mode ATTRIBUTE_UNUSED;
1440 {
1441   switch (GET_CODE (op))
1442     {
1443     case ASHIFTRT:
1444     case LSHIFTRT:
1445     case ASHIFT:
1446       return 1;
1447     default:
1448       return 0;
1449     }
1450 }
1451
1452 /* Output the assembler code for doing a shift.
1453    We go to a bit of trouble to generate efficient code as the ARC only has
1454    single bit shifts.  This is taken from the h8300 port.  We only have one
1455    mode of shifting and can't access individual bytes like the h8300 can, so
1456    this is greatly simplified (at the expense of not generating hyper-
1457    efficient code).
1458
1459    This function is not used if the variable shift insns are present.  */
1460
1461 /* ??? We assume the output operand is the same as operand 1.
1462    This can be optimized (deleted) in the case of 1 bit shifts.  */
1463 /* ??? We use the loop register here.  We don't use it elsewhere (yet) and
1464    using it here will give us a chance to play with it.  */
1465
1466 const char *
1467 output_shift (operands)
1468      rtx *operands;
1469 {
1470   rtx shift = operands[3];
1471   enum machine_mode mode = GET_MODE (shift);
1472   enum rtx_code code = GET_CODE (shift);
1473   const char *shift_one;
1474
1475   if (mode != SImode)
1476     abort ();
1477
1478   switch (code)
1479     {
1480     case ASHIFT:   shift_one = "asl %0,%0"; break;
1481     case ASHIFTRT: shift_one = "asr %0,%0"; break;
1482     case LSHIFTRT: shift_one = "lsr %0,%0"; break;
1483     default:       abort ();
1484     }
1485
1486   if (GET_CODE (operands[2]) != CONST_INT)
1487     {
1488       if (optimize)
1489         output_asm_insn ("mov lp_count,%2", operands);
1490       else
1491         output_asm_insn ("mov %4,%2", operands);
1492       goto shiftloop;
1493     }
1494   else
1495     {
1496       int n = INTVAL (operands[2]);
1497
1498       /* If the count is negative, make it 0.  */
1499       if (n < 0)
1500         n = 0;
1501       /* If the count is too big, truncate it.
1502          ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
1503          do the intuitive thing.  */
1504       else if (n > GET_MODE_BITSIZE (mode))
1505         n = GET_MODE_BITSIZE (mode);
1506
1507       /* First see if we can do them inline.  */
1508       if (n <= 8)
1509         {
1510           while (--n >= 0)
1511             output_asm_insn (shift_one, operands);
1512         }
1513       /* See if we can use a rotate/and.  */
1514       else if (n == BITS_PER_WORD - 1)
1515         {
1516           switch (code)
1517             {
1518             case ASHIFT :
1519               output_asm_insn ("and %0,%0,1\n\tror %0,%0", operands);
1520               break;
1521             case ASHIFTRT :
1522               /* The ARC doesn't have a rol insn.  Use something else.  */
1523               output_asm_insn ("asl.f 0,%0\n\tsbc %0,0,0", operands);
1524               break;
1525             case LSHIFTRT :
1526               /* The ARC doesn't have a rol insn.  Use something else.  */
1527               output_asm_insn ("asl.f 0,%0\n\tadc %0,0,0", operands);
1528               break;
1529             default:
1530               break;
1531             }
1532         }
1533       /* Must loop.  */
1534       else
1535         {
1536           char buf[100];
1537
1538           if (optimize)
1539             output_asm_insn ("mov lp_count,%c2", operands);
1540           else
1541             output_asm_insn ("mov %4,%c2", operands);
1542         shiftloop:
1543           if (optimize)
1544             {
1545               if (flag_pic)
1546                 sprintf (buf, "lr %%4,[status]\n\tadd %%4,%%4,6\t%s single insn loop start",
1547                          ASM_COMMENT_START);
1548               else
1549                 sprintf (buf, "mov %%4,%%%%st(1f)\t%s (single insn loop start) >> 2",
1550                          ASM_COMMENT_START);
1551               output_asm_insn (buf, operands);
1552               output_asm_insn ("sr %4,[lp_start]", operands);
1553               output_asm_insn ("add %4,%4,1", operands);
1554               output_asm_insn ("sr %4,[lp_end]", operands);
1555               output_asm_insn ("nop\n\tnop", operands);
1556               if (flag_pic)
1557                 asm_fprintf (asm_out_file, "\t%s single insn loop\n",
1558                              ASM_COMMENT_START);
1559               else
1560                 asm_fprintf (asm_out_file, "1:\t%s single insn loop\n",
1561                              ASM_COMMENT_START);
1562               output_asm_insn (shift_one, operands);
1563             }
1564           else 
1565             {
1566               asm_fprintf (asm_out_file, "1:\t%s begin shift loop\n",
1567                            ASM_COMMENT_START);
1568               output_asm_insn ("sub.f %4,%4,1", operands);
1569               output_asm_insn ("nop", operands);
1570               output_asm_insn ("bn.nd 2f", operands);
1571               output_asm_insn (shift_one, operands);
1572               output_asm_insn ("b.nd 1b", operands);
1573               asm_fprintf (asm_out_file, "2:\t%s end shift loop\n",
1574                            ASM_COMMENT_START);
1575             }
1576         }
1577     }
1578
1579   return "";
1580 }
1581 \f
1582 /* Nested function support.  */
1583
1584 /* Emit RTL insns to initialize the variable parts of a trampoline.
1585    FNADDR is an RTX for the address of the function's pure code.
1586    CXT is an RTX for the static chain value for the function.  */
1587
1588 void
1589 arc_initialize_trampoline (tramp, fnaddr, cxt)
1590      rtx tramp ATTRIBUTE_UNUSED, fnaddr ATTRIBUTE_UNUSED, cxt ATTRIBUTE_UNUSED;
1591 {
1592 }
1593 \f
1594 /* Set the cpu type and print out other fancy things,
1595    at the top of the file.  */
1596
1597 void
1598 arc_asm_file_start (file)
1599      FILE *file;
1600 {
1601   fprintf (file, "\t.cpu %s\n", arc_cpu_string);
1602 }
1603 \f
1604 /* Print operand X (an rtx) in assembler syntax to file FILE.
1605    CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
1606    For `%' followed by punctuation, CODE is the punctuation and X is null.  */
1607
1608 void
1609 arc_print_operand (file, x, code)
1610      FILE *file;
1611      rtx x;
1612      int code;
1613 {
1614   switch (code)
1615     {
1616     case '#' :
1617       /* Conditional branches.  For now these are equivalent.  */
1618     case '*' :
1619       /* Unconditional branches.  Output the appropriate delay slot suffix.  */
1620       if (!final_sequence || XVECLEN (final_sequence, 0) == 1)
1621         {
1622           /* There's nothing in the delay slot.  */
1623           fputs (".nd", file);
1624         }
1625       else
1626         {
1627           rtx jump = XVECEXP (final_sequence, 0, 0);
1628           rtx delay = XVECEXP (final_sequence, 0, 1);
1629           if (INSN_ANNULLED_BRANCH_P (jump))
1630             fputs (INSN_FROM_TARGET_P (delay) ? ".jd" : ".nd", file);
1631           else
1632             fputs (".d", file);
1633         }
1634       return;
1635     case '?' : /* with leading "." */
1636     case '!' : /* without leading "." */
1637       /* This insn can be conditionally executed.  See if the ccfsm machinery
1638          says it should be conditionalized.  */
1639       if (arc_ccfsm_state == 3 || arc_ccfsm_state == 4)
1640         {
1641           /* Is this insn in a delay slot?  */
1642           if (final_sequence && XVECLEN (final_sequence, 0) == 2)
1643             {
1644               rtx insn = XVECEXP (final_sequence, 0, 1);
1645
1646               /* If the insn is annulled and is from the target path, we need
1647                  to inverse the condition test.  */
1648               if (INSN_ANNULLED_BRANCH_P (insn))
1649                 {
1650                   if (INSN_FROM_TARGET_P (insn))
1651                     fprintf (file, "%s%s",
1652                              code == '?' ? "." : "",
1653                              arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc)]);
1654                   else
1655                     fprintf (file, "%s%s",
1656                              code == '?' ? "." : "",
1657                              arc_condition_codes[arc_ccfsm_current_cc]);
1658                 }
1659               else
1660                 {
1661                   /* This insn is executed for either path, so don't
1662                      conditionalize it at all.  */
1663                   ; /* nothing to do */
1664                 }
1665             }
1666           else
1667             {
1668               /* This insn isn't in a delay slot.  */
1669               fprintf (file, "%s%s",
1670                        code == '?' ? "." : "",
1671                        arc_condition_codes[arc_ccfsm_current_cc]);
1672             }
1673         }
1674       return;
1675     case '~' :
1676       /* Output a nop if we're between a set of the condition codes,
1677          and a conditional branch.  */
1678       if (last_insn_set_cc_p)
1679         fputs ("nop\n\t", file);
1680       return;
1681     case 'd' :
1682       fputs (arc_condition_codes[get_arc_condition_code (x)], file);
1683       return;
1684     case 'D' :
1685       fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
1686                                  (get_arc_condition_code (x))],
1687              file);
1688       return;
1689     case 'R' :
1690       /* Write second word of DImode or DFmode reference,
1691          register or memory.  */
1692       if (GET_CODE (x) == REG)
1693         fputs (reg_names[REGNO (x)+1], file);
1694       else if (GET_CODE (x) == MEM)
1695         {
1696           fputc ('[', file);
1697           /* Handle possible auto-increment.  Since it is pre-increment and
1698              we have already done it, we can just use an offset of four.  */
1699           /* ??? This is taken from rs6000.c I think.  I don't think it is
1700              currently necessary, but keep it around.  */
1701           if (GET_CODE (XEXP (x, 0)) == PRE_INC
1702               || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1703             output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
1704           else
1705             output_address (plus_constant (XEXP (x, 0), 4));
1706           fputc (']', file);
1707         }
1708       else
1709         output_operand_lossage ("invalid operand to %%R code");
1710       return;
1711     case 'S' :
1712       if ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FLAG (x))
1713           || GET_CODE (x) == LABEL_REF)
1714         {
1715           fprintf (file, "%%st(");
1716           output_addr_const (file, x);
1717           fprintf (file, ")");
1718           return;
1719         }
1720       break;
1721     case 'H' :
1722     case 'L' :
1723       if (GET_CODE (x) == REG)
1724         {
1725           /* L = least significant word, H = most significant word */
1726           if ((TARGET_BIG_ENDIAN != 0) ^ (code == 'L'))
1727             fputs (reg_names[REGNO (x)], file);
1728           else
1729             fputs (reg_names[REGNO (x)+1], file);
1730         }
1731       else if (GET_CODE (x) == CONST_INT
1732                || GET_CODE (x) == CONST_DOUBLE)
1733         {
1734           rtx first, second;
1735
1736           split_double (x, &first, &second);
1737           fprintf (file, "0x%08lx",
1738                    (long)(code == 'L' ? INTVAL (first) : INTVAL (second)));
1739         }
1740       else
1741         output_operand_lossage ("invalid operand to %%H/%%L code");
1742       return;
1743     case 'A' :
1744       {
1745         REAL_VALUE_TYPE d;
1746         char str[30];
1747
1748         if (GET_CODE (x) != CONST_DOUBLE
1749             || GET_MODE_CLASS (GET_MODE (x)) != MODE_FLOAT)
1750           abort ();
1751         REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1752         REAL_VALUE_TO_DECIMAL (d, "%.20e", str);
1753         fprintf (file, "%s", str);
1754         return;
1755       }
1756     case 'U' :
1757       /* Output a load/store with update indicator if appropriate.  */
1758       if (GET_CODE (x) == MEM)
1759         {
1760           if (GET_CODE (XEXP (x, 0)) == PRE_INC
1761               || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1762             fputs (".a", file);
1763         }
1764       else
1765         output_operand_lossage ("invalid operand to %%U code");
1766       return;
1767     case 'V' :
1768       /* Output cache bypass indicator for a load/store insn.  Volatile memory
1769          refs are defined to use the cache bypass mechanism.  */
1770       if (GET_CODE (x) == MEM)
1771         {
1772           if (MEM_VOLATILE_P (x))
1773             fputs (".di", file);
1774         }
1775       else
1776         output_operand_lossage ("invalid operand to %%V code");
1777       return;
1778     case 0 :
1779       /* Do nothing special.  */
1780       break;
1781     default :
1782       /* Unknown flag.  */
1783       output_operand_lossage ("invalid operand output code");
1784     }
1785
1786   switch (GET_CODE (x))
1787     {
1788     case REG :
1789       fputs (reg_names[REGNO (x)], file);
1790       break;
1791     case MEM :
1792       fputc ('[', file);
1793       if (GET_CODE (XEXP (x, 0)) == PRE_INC)
1794         output_address (plus_constant (XEXP (XEXP (x, 0), 0),
1795                                        GET_MODE_SIZE (GET_MODE (x))));
1796       else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
1797         output_address (plus_constant (XEXP (XEXP (x, 0), 0),
1798                                        - GET_MODE_SIZE (GET_MODE (x))));
1799       else
1800         output_address (XEXP (x, 0));
1801       fputc (']', file);
1802       break;
1803     case CONST_DOUBLE :
1804       /* We handle SFmode constants here as output_addr_const doesn't.  */
1805       if (GET_MODE (x) == SFmode)
1806         {
1807           REAL_VALUE_TYPE d;
1808           long l;
1809
1810           REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1811           REAL_VALUE_TO_TARGET_SINGLE (d, l);
1812           fprintf (file, "0x%08lx", l);
1813           break;
1814         }
1815       /* Fall through.  Let output_addr_const deal with it.  */
1816     default :
1817       output_addr_const (file, x);
1818       break;
1819     }
1820 }
1821
1822 /* Print a memory address as an operand to reference that memory location.  */
1823
1824 void
1825 arc_print_operand_address (file, addr)
1826      FILE *file;
1827      rtx addr;
1828 {
1829   register rtx base, index = 0;
1830   int offset = 0;
1831
1832   switch (GET_CODE (addr))
1833     {
1834     case REG :
1835       fputs (reg_names[REGNO (addr)], file);
1836       break;
1837     case SYMBOL_REF :
1838       if (/*???*/ 0 && SYMBOL_REF_FLAG (addr))
1839         {
1840           fprintf (file, "%%st(");
1841           output_addr_const (file, addr);
1842           fprintf (file, ")");
1843         }
1844       else
1845         output_addr_const (file, addr);
1846       break;
1847     case PLUS :
1848       if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1849         offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
1850       else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
1851         offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
1852       else
1853         base = XEXP (addr, 0), index = XEXP (addr, 1);
1854       if (GET_CODE (base) != REG)
1855         abort ();
1856       fputs (reg_names[REGNO (base)], file);
1857       if (index == 0)
1858         {
1859           if (offset != 0)
1860             fprintf (file, ",%d", offset);
1861         }
1862       else if (GET_CODE (index) == REG)
1863         fprintf (file, ",%s", reg_names[REGNO (index)]);
1864       else if (GET_CODE (index) == SYMBOL_REF)
1865         fputc (',', file), output_addr_const (file, index);
1866       else
1867         abort ();
1868       break;
1869     case PRE_INC :
1870     case PRE_DEC :
1871       /* We shouldn't get here as we've lost the mode of the memory object
1872          (which says how much to inc/dec by.  */
1873       abort ();
1874       break;
1875     default :
1876       output_addr_const (file, addr);
1877       break;
1878     }
1879 }
1880
1881 /* Update compare/branch separation marker.  */
1882
1883 static void
1884 record_cc_ref (insn)
1885      rtx insn;
1886 {
1887   last_insn_set_cc_p = current_insn_set_cc_p;
1888
1889   switch (get_attr_cond (insn))
1890     {
1891     case COND_SET :
1892     case COND_SET_ZN :
1893     case COND_SET_ZNC :
1894       if (get_attr_length (insn) == 1)
1895         current_insn_set_cc_p = 1;
1896       else
1897         current_insn_set_cc_p = 0;
1898       break;
1899     default :
1900       current_insn_set_cc_p = 0;
1901       break;
1902     }
1903 }
1904 \f
1905 /* Conditional execution support.
1906
1907    This is based on the ARM port but for now is much simpler.
1908
1909    A finite state machine takes care of noticing whether or not instructions
1910    can be conditionally executed, and thus decrease execution time and code
1911    size by deleting branch instructions.  The fsm is controlled by
1912    final_prescan_insn, and controls the actions of PRINT_OPERAND.  The patterns
1913    in the .md file for the branch insns also have a hand in this.  */
1914
1915 /* The state of the fsm controlling condition codes are:
1916    0: normal, do nothing special
1917    1: don't output this insn
1918    2: don't output this insn
1919    3: make insns conditional
1920    4: make insns conditional
1921
1922    State transitions (state->state by whom, under what condition):
1923    0 -> 1 final_prescan_insn, if insn is conditional branch
1924    0 -> 2 final_prescan_insn, if the `target' is an unconditional branch
1925    1 -> 3 branch patterns, after having not output the conditional branch
1926    2 -> 4 branch patterns, after having not output the conditional branch
1927    3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
1928           (the target label has CODE_LABEL_NUMBER equal to
1929           arc_ccfsm_target_label).
1930    4 -> 0 final_prescan_insn, if `target' unconditional branch is reached
1931
1932    If the jump clobbers the conditions then we use states 2 and 4.
1933
1934    A similar thing can be done with conditional return insns.
1935
1936    We also handle separating branches from sets of the condition code.
1937    This is done here because knowledge of the ccfsm state is required,
1938    we may not be outputting the branch.  */
1939
1940 void
1941 arc_final_prescan_insn (insn, opvec, noperands)
1942      rtx insn;
1943      rtx *opvec ATTRIBUTE_UNUSED;
1944      int noperands ATTRIBUTE_UNUSED;
1945 {
1946   /* BODY will hold the body of INSN.  */
1947   register rtx body = PATTERN (insn);
1948
1949   /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
1950      an if/then/else), and things need to be reversed.  */
1951   int reverse = 0;
1952
1953   /* If we start with a return insn, we only succeed if we find another one.  */
1954   int seeking_return = 0;
1955   
1956   /* START_INSN will hold the insn from where we start looking.  This is the
1957      first insn after the following code_label if REVERSE is true.  */
1958   rtx start_insn = insn;
1959
1960   /* Update compare/branch separation marker.  */
1961   record_cc_ref (insn);
1962
1963   /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
1964      We can't do this in macro FINAL_PRESCAN_INSN because its called from
1965      final_scan_insn which has `optimize' as a local.  */
1966   if (optimize < 2 || TARGET_NO_COND_EXEC)
1967     return;
1968
1969   /* If in state 4, check if the target branch is reached, in order to
1970      change back to state 0.  */
1971   if (arc_ccfsm_state == 4)
1972     {
1973       if (insn == arc_ccfsm_target_insn)
1974         {
1975           arc_ccfsm_target_insn = NULL;
1976           arc_ccfsm_state = 0;
1977         }
1978       return;
1979     }
1980
1981   /* If in state 3, it is possible to repeat the trick, if this insn is an
1982      unconditional branch to a label, and immediately following this branch
1983      is the previous target label which is only used once, and the label this
1984      branch jumps to is not too far off.  Or in other words "we've done the
1985      `then' part, see if we can do the `else' part."  */
1986   if (arc_ccfsm_state == 3)
1987     {
1988       if (simplejump_p (insn))
1989         {
1990           start_insn = next_nonnote_insn (start_insn);
1991           if (GET_CODE (start_insn) == BARRIER)
1992             {
1993               /* ??? Isn't this always a barrier?  */
1994               start_insn = next_nonnote_insn (start_insn);
1995             }
1996           if (GET_CODE (start_insn) == CODE_LABEL
1997               && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
1998               && LABEL_NUSES (start_insn) == 1)
1999             reverse = TRUE;
2000           else
2001             return;
2002         }
2003       else if (GET_CODE (body) == RETURN)
2004         {
2005           start_insn = next_nonnote_insn (start_insn);
2006           if (GET_CODE (start_insn) == BARRIER)
2007             start_insn = next_nonnote_insn (start_insn);
2008           if (GET_CODE (start_insn) == CODE_LABEL
2009               && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
2010               && LABEL_NUSES (start_insn) == 1)
2011             {
2012               reverse = TRUE;
2013               seeking_return = 1;
2014             }
2015           else
2016             return;
2017         }
2018       else
2019         return;
2020     }
2021
2022   if (GET_CODE (insn) != JUMP_INSN)
2023     return;
2024
2025   /* This jump might be paralleled with a clobber of the condition codes,
2026      the jump should always come first.  */
2027   if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
2028     body = XVECEXP (body, 0, 0);
2029
2030   if (reverse
2031       || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
2032           && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
2033     {
2034       int insns_skipped = 0, fail = FALSE, succeed = FALSE;
2035       /* Flag which part of the IF_THEN_ELSE is the LABEL_REF.  */
2036       int then_not_else = TRUE;
2037       /* Nonzero if next insn must be the target label.  */
2038       int next_must_be_target_label_p;
2039       rtx this_insn = start_insn, label = 0;
2040
2041       /* Register the insn jumped to.  */
2042       if (reverse)
2043         {
2044           if (!seeking_return)
2045             label = XEXP (SET_SRC (body), 0);
2046         }
2047       else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
2048         label = XEXP (XEXP (SET_SRC (body), 1), 0);
2049       else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
2050         {
2051           label = XEXP (XEXP (SET_SRC (body), 2), 0);
2052           then_not_else = FALSE;
2053         }
2054       else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
2055         seeking_return = 1;
2056       else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
2057         {
2058           seeking_return = 1;
2059           then_not_else = FALSE;
2060         }
2061       else
2062         abort ();
2063
2064       /* See how many insns this branch skips, and what kind of insns.  If all
2065          insns are okay, and the label or unconditional branch to the same
2066          label is not too far away, succeed.  */
2067       for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
2068            !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
2069            insns_skipped++)
2070         {
2071           rtx scanbody;
2072
2073           this_insn = next_nonnote_insn (this_insn);
2074           if (!this_insn)
2075             break;
2076
2077           if (next_must_be_target_label_p)
2078             {
2079               if (GET_CODE (this_insn) == BARRIER)
2080                 continue;
2081               if (GET_CODE (this_insn) == CODE_LABEL
2082                   && this_insn == label)
2083                 {
2084                   arc_ccfsm_state = 1;
2085                   succeed = TRUE;
2086                 }
2087               else
2088                 fail = TRUE;
2089               break;
2090             }
2091
2092           scanbody = PATTERN (this_insn);
2093
2094           switch (GET_CODE (this_insn))
2095             {
2096             case CODE_LABEL:
2097               /* Succeed if it is the target label, otherwise fail since
2098                  control falls in from somewhere else.  */
2099               if (this_insn == label)
2100                 {
2101                   arc_ccfsm_state = 1;
2102                   succeed = TRUE;
2103                 }
2104               else
2105                 fail = TRUE;
2106               break;
2107
2108             case BARRIER:
2109               /* Succeed if the following insn is the target label.
2110                  Otherwise fail.  
2111                  If return insns are used then the last insn in a function 
2112                  will be a barrier.  */
2113               next_must_be_target_label_p = TRUE;
2114               break;
2115
2116             case CALL_INSN:
2117               /* Can handle a call insn if there are no insns after it.
2118                  IE: The next "insn" is the target label.  We don't have to
2119                  worry about delay slots as such insns are SEQUENCE's inside
2120                  INSN's.  ??? It is possible to handle such insns though.  */
2121               if (get_attr_cond (this_insn) == COND_CANUSE)
2122                 next_must_be_target_label_p = TRUE;
2123               else
2124                 fail = TRUE;
2125               break;
2126
2127             case JUMP_INSN:
2128               /* If this is an unconditional branch to the same label, succeed.
2129                  If it is to another label, do nothing.  If it is conditional,
2130                  fail.  */
2131               /* ??? Probably, the test for the SET and the PC are unnecessary.  */
2132
2133               if (GET_CODE (scanbody) == SET
2134                   && GET_CODE (SET_DEST (scanbody)) == PC)
2135                 {
2136                   if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
2137                       && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
2138                     {
2139                       arc_ccfsm_state = 2;
2140                       succeed = TRUE;
2141                     }
2142                   else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
2143                     fail = TRUE;
2144                 }
2145               else if (GET_CODE (scanbody) == RETURN
2146                        && seeking_return)
2147                 {
2148                   arc_ccfsm_state = 2;
2149                   succeed = TRUE;
2150                 }
2151               else if (GET_CODE (scanbody) == PARALLEL)
2152                 {
2153                   if (get_attr_cond (this_insn) != COND_CANUSE)
2154                     fail = TRUE;
2155                 }
2156               break;
2157
2158             case INSN:
2159               /* We can only do this with insns that can use the condition
2160                  codes (and don't set them).  */
2161               if (GET_CODE (scanbody) == SET
2162                   || GET_CODE (scanbody) == PARALLEL)
2163                 {
2164                   if (get_attr_cond (this_insn) != COND_CANUSE)
2165                     fail = TRUE;
2166                 }
2167               /* We can't handle other insns like sequences.  */
2168               else
2169                 fail = TRUE;
2170               break;
2171
2172             default:
2173               break;
2174             }
2175         }
2176
2177       if (succeed)
2178         {
2179           if ((!seeking_return) && (arc_ccfsm_state == 1 || reverse))
2180             arc_ccfsm_target_label = CODE_LABEL_NUMBER (label);
2181           else if (seeking_return || arc_ccfsm_state == 2)
2182             {
2183               while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
2184                 {
2185                   this_insn = next_nonnote_insn (this_insn);
2186                   if (this_insn && (GET_CODE (this_insn) == BARRIER
2187                                     || GET_CODE (this_insn) == CODE_LABEL))
2188                     abort ();
2189                 }
2190               if (!this_insn)
2191                 {
2192                   /* Oh dear! we ran off the end, give up.  */
2193                   extract_insn_cached (insn);
2194                   arc_ccfsm_state = 0;
2195                   arc_ccfsm_target_insn = NULL;
2196                   return;
2197                 }
2198               arc_ccfsm_target_insn = this_insn;
2199             }
2200           else
2201             abort ();
2202
2203           /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
2204              what it was.  */
2205           if (!reverse)
2206             arc_ccfsm_current_cc = get_arc_condition_code (XEXP (SET_SRC (body),
2207                                                                  0));
2208
2209           if (reverse || then_not_else)
2210             arc_ccfsm_current_cc = ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc);
2211         }
2212
2213       /* Restore recog_data.  Getting the attributes of other insns can
2214          destroy this array, but final.c assumes that it remains intact
2215          across this call.  */
2216       extract_insn_cached (insn);
2217     }
2218 }
2219
2220 /* Record that we are currently outputting label NUM with prefix PREFIX.
2221    It it's the label we're looking for, reset the ccfsm machinery.
2222
2223    Called from ASM_OUTPUT_INTERNAL_LABEL.  */
2224
2225 void
2226 arc_ccfsm_at_label (prefix, num)
2227      const char *prefix;
2228      int num;
2229 {
2230   if (arc_ccfsm_state == 3 && arc_ccfsm_target_label == num
2231       && !strcmp (prefix, "L"))
2232     {
2233       arc_ccfsm_state = 0;
2234       arc_ccfsm_target_insn = NULL_RTX;
2235     }
2236 }
2237
2238 /* See if the current insn, which is a conditional branch, is to be
2239    deleted.  */
2240
2241 int
2242 arc_ccfsm_branch_deleted_p ()
2243 {
2244   if (arc_ccfsm_state == 1 || arc_ccfsm_state == 2)
2245     return 1;
2246   return 0;
2247 }
2248
2249 /* Record a branch isn't output because subsequent insns can be
2250    conditionalized.  */
2251
2252 void
2253 arc_ccfsm_record_branch_deleted ()
2254 {
2255   /* Indicate we're conditionalizing insns now.  */
2256   arc_ccfsm_state += 2;
2257
2258   /* If the next insn is a subroutine call, we still need a nop between the
2259      cc setter and user.  We need to undo the effect of calling record_cc_ref
2260      for the just deleted branch.  */
2261   current_insn_set_cc_p = last_insn_set_cc_p;
2262 }
2263 \f
2264 void
2265 arc_va_start (stdarg_p, valist, nextarg)
2266      int stdarg_p;
2267      tree valist;
2268      rtx nextarg;
2269 {
2270   /* See arc_setup_incoming_varargs for reasons for this oddity.  */
2271   if (current_function_args_info < 8
2272       && (current_function_args_info & 1))
2273     nextarg = plus_constant (nextarg, UNITS_PER_WORD);
2274
2275   std_expand_builtin_va_start (stdarg_p, valist, nextarg);
2276 }
2277
2278 rtx
2279 arc_va_arg (valist, type)
2280      tree valist, type;
2281 {
2282   rtx addr_rtx;
2283   tree addr, incr;
2284   tree type_ptr = build_pointer_type (type);
2285
2286   /* All aggregates are passed by reference.  All scalar types larger
2287      than 8 bytes are passed by reference.  */
2288
2289   if (AGGREGATE_TYPE_P (type) || int_size_in_bytes (type) > 8)
2290     {
2291       tree type_ptr_ptr = build_pointer_type (type_ptr);
2292
2293       addr = build (INDIRECT_REF, type_ptr,
2294                     build (NOP_EXPR, type_ptr_ptr, valist));
2295
2296       incr = build (PLUS_EXPR, TREE_TYPE (valist),
2297                     valist, build_int_2 (UNITS_PER_WORD, 0));
2298     }
2299   else
2300     {
2301       HOST_WIDE_INT align, rounded_size;
2302
2303       /* Compute the rounded size of the type.  */
2304       align = PARM_BOUNDARY / BITS_PER_UNIT;
2305       rounded_size = (((TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT
2306                         + align - 1) / align) * align);
2307
2308       /* Align 8 byte operands.  */
2309       addr = valist;
2310       if (TYPE_ALIGN (type) > BITS_PER_WORD)
2311         {
2312           /* AP = (TYPE *)(((int)AP + 7) & -8)  */
2313
2314           addr = build (NOP_EXPR, integer_type_node, valist);
2315           addr = fold (build (PLUS_EXPR, integer_type_node, addr,
2316                               build_int_2 (7, 0)));
2317           addr = fold (build (BIT_AND_EXPR, integer_type_node, addr,
2318                               build_int_2 (-8, 0)));
2319           addr = fold (build (NOP_EXPR, TREE_TYPE (valist), addr));
2320         }
2321
2322       /* The increment is always rounded_size past the aligned pointer.  */
2323       incr = fold (build (PLUS_EXPR, TREE_TYPE (addr), addr,
2324                           build_int_2 (rounded_size, 0)));
2325
2326       /* Adjust the pointer in big-endian mode.  */
2327       if (BYTES_BIG_ENDIAN)
2328         {
2329           HOST_WIDE_INT adj;
2330           adj = TREE_INT_CST_LOW (TYPE_SIZE (type)) / BITS_PER_UNIT;
2331           if (rounded_size > align)
2332             adj = rounded_size;
2333
2334           addr = fold (build (PLUS_EXPR, TREE_TYPE (addr), addr,
2335                               build_int_2 (rounded_size - adj, 0)));
2336         }
2337     }
2338
2339   /* Evaluate the data address.  */
2340   addr_rtx = expand_expr (addr, NULL_RTX, Pmode, EXPAND_NORMAL);
2341   addr_rtx = copy_to_reg (addr_rtx);
2342   
2343   /* Compute new value for AP.  */
2344   incr = build (MODIFY_EXPR, TREE_TYPE (valist), valist, incr);
2345   TREE_SIDE_EFFECTS (incr) = 1;
2346   expand_expr (incr, const0_rtx, VOIDmode, EXPAND_NORMAL);
2347
2348   return addr_rtx;
2349 }