* common.opt (-Wattributes): New. Default true.
[official-gcc.git] / gcc / config / arc / arc.c
blob2161817ca95724dcf13b21f661a7574b76f32bbc
1 /* Subroutines used for code generation on the Argonaut ARC cpu.
2 Copyright (C) 1994, 1995, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004,
3 2005
4 Free Software Foundation, Inc.
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2, or (at your option)
11 any later version.
13 GCC is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING. If not, write to
20 the Free Software Foundation, 59 Temple Place - Suite 330,
21 Boston, MA 02111-1307, USA. */
23 /* ??? This is an old port, and is undoubtedly suffering from bit rot. */
25 #include "config.h"
26 #include "system.h"
27 #include "coretypes.h"
28 #include "tm.h"
29 #include "tree.h"
30 #include "rtl.h"
31 #include "regs.h"
32 #include "hard-reg-set.h"
33 #include "real.h"
34 #include "insn-config.h"
35 #include "conditions.h"
36 #include "output.h"
37 #include "insn-attr.h"
38 #include "flags.h"
39 #include "function.h"
40 #include "expr.h"
41 #include "recog.h"
42 #include "toplev.h"
43 #include "tm_p.h"
44 #include "target.h"
45 #include "target-def.h"
47 /* Which cpu we're compiling for. */
48 static const char *arc_cpu_string = "base";
49 int arc_cpu_type;
51 /* Name of mangle string to add to symbols to separate code compiled for each
52 cpu (or NULL). */
53 const char *arc_mangle_cpu;
55 /* Save the operands last given to a compare for use when we
56 generate a scc or bcc insn. */
57 rtx arc_compare_op0, arc_compare_op1;
59 /* Name of text, data, and rodata sections, as specified on command line.
60 Selected by -m{text,data,rodata} flags. */
61 static const char *arc_text_string = ARC_DEFAULT_TEXT_SECTION;
62 static const char *arc_data_string = ARC_DEFAULT_DATA_SECTION;
63 static const char *arc_rodata_string = ARC_DEFAULT_RODATA_SECTION;
65 /* Name of text, data, and rodata sections used in varasm.c. */
66 const char *arc_text_section;
67 const char *arc_data_section;
68 const char *arc_rodata_section;
70 /* Array of valid operand punctuation characters. */
71 char arc_punct_chars[256];
73 /* Variables used by arc_final_prescan_insn to implement conditional
74 execution. */
75 static int arc_ccfsm_state;
76 static int arc_ccfsm_current_cc;
77 static rtx arc_ccfsm_target_insn;
78 static int arc_ccfsm_target_label;
80 /* The maximum number of insns skipped which will be conditionalised if
81 possible. */
82 #define MAX_INSNS_SKIPPED 3
84 /* A nop is needed between a 4 byte insn that sets the condition codes and
85 a branch that uses them (the same isn't true for an 8 byte insn that sets
86 the condition codes). Set by arc_final_prescan_insn. Used by
87 arc_print_operand. */
88 static int last_insn_set_cc_p;
89 static int current_insn_set_cc_p;
90 static bool arc_handle_option (size_t, const char *, int);
91 static void record_cc_ref (rtx);
92 static void arc_init_reg_tables (void);
93 static int get_arc_condition_code (rtx);
94 const struct attribute_spec arc_attribute_table[];
95 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
96 static bool arc_assemble_integer (rtx, unsigned int, int);
97 static void arc_output_function_prologue (FILE *, HOST_WIDE_INT);
98 static void arc_output_function_epilogue (FILE *, HOST_WIDE_INT);
99 static void arc_file_start (void);
100 static void arc_internal_label (FILE *, const char *, unsigned long);
101 static void arc_setup_incoming_varargs (CUMULATIVE_ARGS *, enum machine_mode,
102 tree, int *, int);
103 static bool arc_rtx_costs (rtx, int, int, int *);
104 static int arc_address_cost (rtx);
105 static void arc_external_libcall (rtx);
106 static bool arc_return_in_memory (tree, tree);
107 static bool arc_pass_by_reference (CUMULATIVE_ARGS *, enum machine_mode,
108 tree, bool);
110 /* Initialize the GCC target structure. */
111 #undef TARGET_ASM_ALIGNED_HI_OP
112 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
113 #undef TARGET_ASM_ALIGNED_SI_OP
114 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
115 #undef TARGET_ASM_INTEGER
116 #define TARGET_ASM_INTEGER arc_assemble_integer
118 #undef TARGET_ASM_FUNCTION_PROLOGUE
119 #define TARGET_ASM_FUNCTION_PROLOGUE arc_output_function_prologue
120 #undef TARGET_ASM_FUNCTION_EPILOGUE
121 #define TARGET_ASM_FUNCTION_EPILOGUE arc_output_function_epilogue
122 #undef TARGET_ASM_FILE_START
123 #define TARGET_ASM_FILE_START arc_file_start
124 #undef TARGET_ATTRIBUTE_TABLE
125 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
126 #undef TARGET_ASM_INTERNAL_LABEL
127 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
128 #undef TARGET_ASM_EXTERNAL_LIBCALL
129 #define TARGET_ASM_EXTERNAL_LIBCALL arc_external_libcall
131 #undef TARGET_HANDLE_OPTION
132 #define TARGET_HANDLE_OPTION arc_handle_option
134 #undef TARGET_RTX_COSTS
135 #define TARGET_RTX_COSTS arc_rtx_costs
136 #undef TARGET_ADDRESS_COST
137 #define TARGET_ADDRESS_COST arc_address_cost
139 #undef TARGET_PROMOTE_FUNCTION_ARGS
140 #define TARGET_PROMOTE_FUNCTION_ARGS hook_bool_tree_true
141 #undef TARGET_PROMOTE_FUNCTION_RETURN
142 #define TARGET_PROMOTE_FUNCTION_RETURN hook_bool_tree_true
143 #undef TARGET_PROMOTE_PROTOTYPES
144 #define TARGET_PROMOTE_PROTOTYPES hook_bool_tree_true
146 #undef TARGET_RETURN_IN_MEMORY
147 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
148 #undef TARGET_PASS_BY_REFERENCE
149 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
150 #undef TARGET_CALLEE_COPIES
151 #define TARGET_CALLEE_COPIES hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true
153 #undef TARGET_SETUP_INCOMING_VARARGS
154 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
156 struct gcc_target targetm = TARGET_INITIALIZER;
158 /* Implement TARGET_HANDLE_OPTION. */
160 static bool
161 arc_handle_option (size_t code, const char *arg, int value ATTRIBUTE_UNUSED)
163 switch (code)
165 case OPT_mcpu_:
166 if (strcmp (arg, "base") == 0 || ARC_EXTENSION_CPU (arg))
168 arc_cpu_string = arg;
169 return true;
171 return false;
173 case OPT_mtext_:
174 arc_text_string = arg;
175 return true;
177 case OPT_mdata_:
178 arc_data_string = arg;
179 return true;
181 case OPT_mrodata_:
182 arc_rodata_string = arg;
183 return true;
185 default:
186 return true;
190 /* Called by OVERRIDE_OPTIONS to initialize various things. */
192 void
193 arc_init (void)
195 char *tmp;
197 /* Set the pseudo-ops for the various standard sections. */
198 arc_text_section = tmp = xmalloc (strlen (arc_text_string) + sizeof (ARC_SECTION_FORMAT) + 1);
199 sprintf (tmp, ARC_SECTION_FORMAT, arc_text_string);
200 arc_data_section = tmp = xmalloc (strlen (arc_data_string) + sizeof (ARC_SECTION_FORMAT) + 1);
201 sprintf (tmp, ARC_SECTION_FORMAT, arc_data_string);
202 arc_rodata_section = tmp = xmalloc (strlen (arc_rodata_string) + sizeof (ARC_SECTION_FORMAT) + 1);
203 sprintf (tmp, ARC_SECTION_FORMAT, arc_rodata_string);
205 arc_init_reg_tables ();
207 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
208 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
209 arc_punct_chars['#'] = 1;
210 arc_punct_chars['*'] = 1;
211 arc_punct_chars['?'] = 1;
212 arc_punct_chars['!'] = 1;
213 arc_punct_chars['~'] = 1;
216 /* The condition codes of the ARC, and the inverse function. */
217 static const char *const arc_condition_codes[] =
219 "al", 0, "eq", "ne", "p", "n", "c", "nc", "v", "nv",
220 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
223 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
225 /* Returns the index of the ARC condition code string in
226 `arc_condition_codes'. COMPARISON should be an rtx like
227 `(eq (...) (...))'. */
229 static int
230 get_arc_condition_code (rtx comparison)
232 switch (GET_CODE (comparison))
234 case EQ : return 2;
235 case NE : return 3;
236 case GT : return 10;
237 case LE : return 11;
238 case GE : return 12;
239 case LT : return 13;
240 case GTU : return 14;
241 case LEU : return 15;
242 case LTU : return 6;
243 case GEU : return 7;
244 default : gcc_unreachable ();
246 /*NOTREACHED*/
247 return (42);
250 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
251 return the mode to be used for the comparison. */
253 enum machine_mode
254 arc_select_cc_mode (enum rtx_code op,
255 rtx x ATTRIBUTE_UNUSED,
256 rtx y ATTRIBUTE_UNUSED)
258 switch (op)
260 case EQ :
261 case NE :
262 return CCZNmode;
263 default :
264 switch (GET_CODE (x))
266 case AND :
267 case IOR :
268 case XOR :
269 case SIGN_EXTEND :
270 case ZERO_EXTEND :
271 return CCZNmode;
272 case ASHIFT :
273 case ASHIFTRT :
274 case LSHIFTRT :
275 return CCZNCmode;
276 default:
277 break;
280 return CCmode;
283 /* Vectors to keep interesting information about registers where it can easily
284 be got. We use to use the actual mode value as the bit number, but there
285 is (or may be) more than 32 modes now. Instead we use two tables: one
286 indexed by hard register number, and one indexed by mode. */
288 /* The purpose of arc_mode_class is to shrink the range of modes so that
289 they all fit (as bit numbers) in a 32 bit word (again). Each real mode is
290 mapped into one arc_mode_class mode. */
292 enum arc_mode_class {
293 C_MODE,
294 S_MODE, D_MODE, T_MODE, O_MODE,
295 SF_MODE, DF_MODE, TF_MODE, OF_MODE
298 /* Modes for condition codes. */
299 #define C_MODES (1 << (int) C_MODE)
301 /* Modes for single-word and smaller quantities. */
302 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
304 /* Modes for double-word and smaller quantities. */
305 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
307 /* Modes for quad-word and smaller quantities. */
308 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
310 /* Value is 1 if register/mode pair is acceptable on arc. */
312 const unsigned int arc_hard_regno_mode_ok[] = {
313 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
314 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
315 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
316 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
318 /* ??? Leave these as S_MODES for now. */
319 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
320 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
321 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
322 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES
325 unsigned int arc_mode_class [NUM_MACHINE_MODES];
327 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
329 static void
330 arc_init_reg_tables (void)
332 int i;
334 for (i = 0; i < NUM_MACHINE_MODES; i++)
336 switch (GET_MODE_CLASS (i))
338 case MODE_INT:
339 case MODE_PARTIAL_INT:
340 case MODE_COMPLEX_INT:
341 if (GET_MODE_SIZE (i) <= 4)
342 arc_mode_class[i] = 1 << (int) S_MODE;
343 else if (GET_MODE_SIZE (i) == 8)
344 arc_mode_class[i] = 1 << (int) D_MODE;
345 else if (GET_MODE_SIZE (i) == 16)
346 arc_mode_class[i] = 1 << (int) T_MODE;
347 else if (GET_MODE_SIZE (i) == 32)
348 arc_mode_class[i] = 1 << (int) O_MODE;
349 else
350 arc_mode_class[i] = 0;
351 break;
352 case MODE_FLOAT:
353 case MODE_COMPLEX_FLOAT:
354 if (GET_MODE_SIZE (i) <= 4)
355 arc_mode_class[i] = 1 << (int) SF_MODE;
356 else if (GET_MODE_SIZE (i) == 8)
357 arc_mode_class[i] = 1 << (int) DF_MODE;
358 else if (GET_MODE_SIZE (i) == 16)
359 arc_mode_class[i] = 1 << (int) TF_MODE;
360 else if (GET_MODE_SIZE (i) == 32)
361 arc_mode_class[i] = 1 << (int) OF_MODE;
362 else
363 arc_mode_class[i] = 0;
364 break;
365 case MODE_CC:
366 arc_mode_class[i] = 1 << (int) C_MODE;
367 break;
368 default:
369 arc_mode_class[i] = 0;
370 break;
374 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
376 if (i < 60)
377 arc_regno_reg_class[i] = GENERAL_REGS;
378 else if (i == 60)
379 arc_regno_reg_class[i] = LPCOUNT_REG;
380 else if (i == 61)
381 arc_regno_reg_class[i] = NO_REGS /* CC_REG: must be NO_REGS */;
382 else
383 arc_regno_reg_class[i] = NO_REGS;
387 /* ARC specific attribute support.
389 The ARC has these attributes:
390 interrupt - for interrupt functions
393 const struct attribute_spec arc_attribute_table[] =
395 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler } */
396 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute },
397 { NULL, 0, 0, false, false, false, NULL }
400 /* Handle an "interrupt" attribute; arguments as in
401 struct attribute_spec.handler. */
402 static tree
403 arc_handle_interrupt_attribute (tree *node ATTRIBUTE_UNUSED,
404 tree name,
405 tree args,
406 int flags ATTRIBUTE_UNUSED,
407 bool *no_add_attrs)
409 tree value = TREE_VALUE (args);
411 if (TREE_CODE (value) != STRING_CST)
413 warning (OPT_Wattributes,
414 "argument of %qs attribute is not a string constant",
415 IDENTIFIER_POINTER (name));
416 *no_add_attrs = true;
418 else if (strcmp (TREE_STRING_POINTER (value), "ilink1")
419 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
421 warning (OPT_Wattributes,
422 "argument of %qs attribute is not \"ilink1\" or \"ilink2\"",
423 IDENTIFIER_POINTER (name));
424 *no_add_attrs = true;
427 return NULL_TREE;
431 /* Acceptable arguments to the call insn. */
434 call_address_operand (rtx op, enum machine_mode mode)
436 return (symbolic_operand (op, mode)
437 || (GET_CODE (op) == CONST_INT && LEGITIMATE_CONSTANT_P (op))
438 || (GET_CODE (op) == REG));
442 call_operand (rtx op, enum machine_mode mode)
444 if (GET_CODE (op) != MEM)
445 return 0;
446 op = XEXP (op, 0);
447 return call_address_operand (op, mode);
450 /* Returns 1 if OP is a symbol reference. */
453 symbolic_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
455 switch (GET_CODE (op))
457 case SYMBOL_REF:
458 case LABEL_REF:
459 case CONST :
460 return 1;
461 default:
462 return 0;
466 /* Return truth value of statement that OP is a symbolic memory
467 operand of mode MODE. */
470 symbolic_memory_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
472 if (GET_CODE (op) == SUBREG)
473 op = SUBREG_REG (op);
474 if (GET_CODE (op) != MEM)
475 return 0;
476 op = XEXP (op, 0);
477 return (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == CONST
478 || GET_CODE (op) == LABEL_REF);
481 /* Return true if OP is a short immediate (shimm) value. */
484 short_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
486 if (GET_CODE (op) != CONST_INT)
487 return 0;
488 return SMALL_INT (INTVAL (op));
491 /* Return true if OP will require a long immediate (limm) value.
492 This is currently only used when calculating length attributes. */
495 long_immediate_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
497 switch (GET_CODE (op))
499 case SYMBOL_REF :
500 case LABEL_REF :
501 case CONST :
502 return 1;
503 case CONST_INT :
504 return !SMALL_INT (INTVAL (op));
505 case CONST_DOUBLE :
506 /* These can happen because large unsigned 32 bit constants are
507 represented this way (the multiplication patterns can cause these
508 to be generated). They also occur for SFmode values. */
509 return 1;
510 default:
511 break;
513 return 0;
516 /* Return true if OP is a MEM that when used as a load or store address will
517 require an 8 byte insn.
518 Load and store instructions don't allow the same possibilities but they're
519 similar enough that this one function will do.
520 This is currently only used when calculating length attributes. */
523 long_immediate_loadstore_operand (rtx op,
524 enum machine_mode mode ATTRIBUTE_UNUSED)
526 if (GET_CODE (op) != MEM)
527 return 0;
529 op = XEXP (op, 0);
530 switch (GET_CODE (op))
532 case SYMBOL_REF :
533 case LABEL_REF :
534 case CONST :
535 return 1;
536 case CONST_INT :
537 /* This must be handled as "st c,[limm]". Ditto for load.
538 Technically, the assembler could translate some possibilities to
539 "st c,[limm/2 + limm/2]" if limm/2 will fit in a shimm, but we don't
540 assume that it does. */
541 return 1;
542 case CONST_DOUBLE :
543 /* These can happen because large unsigned 32 bit constants are
544 represented this way (the multiplication patterns can cause these
545 to be generated). They also occur for SFmode values. */
546 return 1;
547 case REG :
548 return 0;
549 case PLUS :
550 if (GET_CODE (XEXP (op, 1)) == CONST_INT
551 && !SMALL_INT (INTVAL (XEXP (op, 1))))
552 return 1;
553 return 0;
554 default:
555 break;
557 return 0;
560 /* Return true if OP is an acceptable argument for a single word
561 move source. */
564 move_src_operand (rtx op, enum machine_mode mode)
566 switch (GET_CODE (op))
568 case SYMBOL_REF :
569 case LABEL_REF :
570 case CONST :
571 return 1;
572 case CONST_INT :
573 return (LARGE_INT (INTVAL (op)));
574 case CONST_DOUBLE :
575 /* We can handle DImode integer constants in SImode if the value
576 (signed or unsigned) will fit in 32 bits. This is needed because
577 large unsigned 32 bit constants are represented as CONST_DOUBLEs. */
578 if (mode == SImode)
579 return arc_double_limm_p (op);
580 /* We can handle 32 bit floating point constants. */
581 if (mode == SFmode)
582 return GET_MODE (op) == SFmode;
583 return 0;
584 case REG :
585 return register_operand (op, mode);
586 case SUBREG :
587 /* (subreg (mem ...) ...) can occur here if the inner part was once a
588 pseudo-reg and is now a stack slot. */
589 if (GET_CODE (SUBREG_REG (op)) == MEM)
590 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
591 else
592 return register_operand (op, mode);
593 case MEM :
594 return address_operand (XEXP (op, 0), mode);
595 default :
596 return 0;
600 /* Return true if OP is an acceptable argument for a double word
601 move source. */
604 move_double_src_operand (rtx op, enum machine_mode mode)
606 switch (GET_CODE (op))
608 case REG :
609 return register_operand (op, mode);
610 case SUBREG :
611 /* (subreg (mem ...) ...) can occur here if the inner part was once a
612 pseudo-reg and is now a stack slot. */
613 if (GET_CODE (SUBREG_REG (op)) == MEM)
614 return move_double_src_operand (SUBREG_REG (op), mode);
615 else
616 return register_operand (op, mode);
617 case MEM :
618 /* Disallow auto inc/dec for now. */
619 if (GET_CODE (XEXP (op, 0)) == PRE_DEC
620 || GET_CODE (XEXP (op, 0)) == PRE_INC)
621 return 0;
622 return address_operand (XEXP (op, 0), mode);
623 case CONST_INT :
624 case CONST_DOUBLE :
625 return 1;
626 default :
627 return 0;
631 /* Return true if OP is an acceptable argument for a move destination. */
634 move_dest_operand (rtx op, enum machine_mode mode)
636 switch (GET_CODE (op))
638 case REG :
639 return register_operand (op, mode);
640 case SUBREG :
641 /* (subreg (mem ...) ...) can occur here if the inner part was once a
642 pseudo-reg and is now a stack slot. */
643 if (GET_CODE (SUBREG_REG (op)) == MEM)
644 return address_operand (XEXP (SUBREG_REG (op), 0), mode);
645 else
646 return register_operand (op, mode);
647 case MEM :
648 return address_operand (XEXP (op, 0), mode);
649 default :
650 return 0;
654 /* Return true if OP is valid load with update operand. */
657 load_update_operand (rtx op, enum machine_mode mode)
659 if (GET_CODE (op) != MEM
660 || GET_MODE (op) != mode)
661 return 0;
662 op = XEXP (op, 0);
663 if (GET_CODE (op) != PLUS
664 || GET_MODE (op) != Pmode
665 || !register_operand (XEXP (op, 0), Pmode)
666 || !nonmemory_operand (XEXP (op, 1), Pmode))
667 return 0;
668 return 1;
671 /* Return true if OP is valid store with update operand. */
674 store_update_operand (rtx op, enum machine_mode mode)
676 if (GET_CODE (op) != MEM
677 || GET_MODE (op) != mode)
678 return 0;
679 op = XEXP (op, 0);
680 if (GET_CODE (op) != PLUS
681 || GET_MODE (op) != Pmode
682 || !register_operand (XEXP (op, 0), Pmode)
683 || !(GET_CODE (XEXP (op, 1)) == CONST_INT
684 && SMALL_INT (INTVAL (XEXP (op, 1)))))
685 return 0;
686 return 1;
689 /* Return true if OP is a non-volatile non-immediate operand.
690 Volatile memory refs require a special "cache-bypass" instruction
691 and only the standard movXX patterns are set up to handle them. */
694 nonvol_nonimm_operand (rtx op, enum machine_mode mode)
696 if (GET_CODE (op) == MEM && MEM_VOLATILE_P (op))
697 return 0;
698 return nonimmediate_operand (op, mode);
701 /* Accept integer operands in the range -0x80000000..0x7fffffff. We have
702 to check the range carefully since this predicate is used in DImode
703 contexts. */
706 const_sint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
708 /* All allowed constants will fit a CONST_INT. */
709 return (GET_CODE (op) == CONST_INT
710 && (INTVAL (op) >= (-0x7fffffff - 1) && INTVAL (op) <= 0x7fffffff));
713 /* Accept integer operands in the range 0..0xffffffff. We have to check the
714 range carefully since this predicate is used in DImode contexts. Also, we
715 need some extra crud to make it work when hosted on 64-bit machines. */
718 const_uint32_operand (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
720 #if HOST_BITS_PER_WIDE_INT > 32
721 /* All allowed constants will fit a CONST_INT. */
722 return (GET_CODE (op) == CONST_INT
723 && (INTVAL (op) >= 0 && INTVAL (op) <= 0xffffffffL));
724 #else
725 return ((GET_CODE (op) == CONST_INT && INTVAL (op) >= 0)
726 || (GET_CODE (op) == CONST_DOUBLE && CONST_DOUBLE_HIGH (op) == 0));
727 #endif
730 /* Return 1 if OP is a comparison operator valid for the mode of CC.
731 This allows the use of MATCH_OPERATOR to recognize all the branch insns.
733 Some insns only set a few bits in the condition code. So only allow those
734 comparisons that use the bits that are valid. */
737 proper_comparison_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
739 enum rtx_code code;
740 if (!COMPARISON_P (op))
741 return 0;
743 code = GET_CODE (op);
744 if (GET_MODE (XEXP (op, 0)) == CCZNmode)
745 return (code == EQ || code == NE);
746 if (GET_MODE (XEXP (op, 0)) == CCZNCmode)
747 return (code == EQ || code == NE
748 || code == LTU || code == GEU || code == GTU || code == LEU);
749 return 1;
752 /* Misc. utilities. */
754 /* X and Y are two things to compare using CODE. Emit the compare insn and
755 return the rtx for the cc reg in the proper mode. */
758 gen_compare_reg (enum rtx_code code, rtx x, rtx y)
760 enum machine_mode mode = SELECT_CC_MODE (code, x, y);
761 rtx cc_reg;
763 cc_reg = gen_rtx_REG (mode, 61);
765 emit_insn (gen_rtx_SET (VOIDmode, cc_reg,
766 gen_rtx_COMPARE (mode, x, y)));
768 return cc_reg;
771 /* Return 1 if VALUE, a const_double, will fit in a limm (4 byte number).
772 We assume the value can be either signed or unsigned. */
775 arc_double_limm_p (rtx value)
777 HOST_WIDE_INT low, high;
779 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
781 low = CONST_DOUBLE_LOW (value);
782 high = CONST_DOUBLE_HIGH (value);
784 if (low & 0x80000000)
786 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
787 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
788 == - (unsigned HOST_WIDE_INT) 0x80000000)
789 && high == -1));
791 else
793 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
797 /* Do any needed setup for a variadic function. For the ARC, we must
798 create a register parameter block, and then copy any anonymous arguments
799 in registers to memory.
801 CUM has not been updated for the last named argument which has type TYPE
802 and mode MODE, and we rely on this fact.
804 We do things a little weird here. We're supposed to only allocate space
805 for the anonymous arguments. However we need to keep the stack eight byte
806 aligned. So we round the space up if necessary, and leave it to va_start
807 to compensate. */
809 static void
810 arc_setup_incoming_varargs (CUMULATIVE_ARGS *cum,
811 enum machine_mode mode,
812 tree type ATTRIBUTE_UNUSED,
813 int *pretend_size,
814 int no_rtl)
816 int first_anon_arg;
818 /* All BLKmode values are passed by reference. */
819 gcc_assert (mode != BLKmode);
821 first_anon_arg = *cum + ((GET_MODE_SIZE (mode) + UNITS_PER_WORD - 1)
822 / UNITS_PER_WORD);
824 if (first_anon_arg < MAX_ARC_PARM_REGS && !no_rtl)
826 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
827 int first_reg_offset = first_anon_arg;
828 /* Size in words to "pretend" allocate. */
829 int size = MAX_ARC_PARM_REGS - first_reg_offset;
830 /* Extra slop to keep stack eight byte aligned. */
831 int align_slop = size & 1;
832 rtx regblock;
834 regblock = gen_rtx_MEM (BLKmode,
835 plus_constant (arg_pointer_rtx,
836 FIRST_PARM_OFFSET (0)
837 + align_slop * UNITS_PER_WORD));
838 set_mem_alias_set (regblock, get_varargs_alias_set ());
839 set_mem_align (regblock, BITS_PER_WORD);
840 move_block_from_reg (first_reg_offset, regblock,
841 MAX_ARC_PARM_REGS - first_reg_offset);
843 *pretend_size = ((MAX_ARC_PARM_REGS - first_reg_offset + align_slop)
844 * UNITS_PER_WORD);
848 /* Cost functions. */
850 /* Compute a (partial) cost for rtx X. Return true if the complete
851 cost has been computed, and false if subexpressions should be
852 scanned. In either case, *TOTAL contains the cost result. */
854 static bool
855 arc_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, int *total)
857 switch (code)
859 /* Small integers are as cheap as registers. 4 byte values can
860 be fetched as immediate constants - let's give that the cost
861 of an extra insn. */
862 case CONST_INT:
863 if (SMALL_INT (INTVAL (x)))
865 *total = 0;
866 return true;
868 /* FALLTHRU */
870 case CONST:
871 case LABEL_REF:
872 case SYMBOL_REF:
873 *total = COSTS_N_INSNS (1);
874 return true;
876 case CONST_DOUBLE:
878 rtx high, low;
879 split_double (x, &high, &low);
880 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (high))
881 + !SMALL_INT (INTVAL (low)));
882 return true;
885 /* Encourage synth_mult to find a synthetic multiply when reasonable.
886 If we need more than 12 insns to do a multiply, then go out-of-line,
887 since the call overhead will be < 10% of the cost of the multiply. */
888 case ASHIFT:
889 case ASHIFTRT:
890 case LSHIFTRT:
891 if (TARGET_SHIFTER)
892 *total = COSTS_N_INSNS (1);
893 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
894 *total = COSTS_N_INSNS (16);
895 else
896 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
897 return false;
899 default:
900 return false;
905 /* Provide the costs of an addressing mode that contains ADDR.
906 If ADDR is not a valid address, its cost is irrelevant. */
908 static int
909 arc_address_cost (rtx addr)
911 switch (GET_CODE (addr))
913 case REG :
914 return 1;
916 case LABEL_REF :
917 case SYMBOL_REF :
918 case CONST :
919 return 2;
921 case PLUS :
923 register rtx plus0 = XEXP (addr, 0);
924 register rtx plus1 = XEXP (addr, 1);
926 if (GET_CODE (plus0) != REG)
927 break;
929 switch (GET_CODE (plus1))
931 case CONST_INT :
932 return SMALL_INT (plus1) ? 1 : 2;
933 case CONST :
934 case SYMBOL_REF :
935 case LABEL_REF :
936 return 2;
937 default:
938 break;
940 break;
942 default:
943 break;
946 return 4;
949 /* Function prologue/epilogue handlers. */
951 /* ARC stack frames look like:
953 Before call After call
954 +-----------------------+ +-----------------------+
955 | | | |
956 high | local variables, | | local variables, |
957 mem | reg save area, etc. | | reg save area, etc. |
958 | | | |
959 +-----------------------+ +-----------------------+
960 | | | |
961 | arguments on stack. | | arguments on stack. |
962 | | | |
963 SP+16->+-----------------------+FP+48->+-----------------------+
964 | 4 word save area for | | reg parm save area, |
965 | return addr, prev %fp | | only created for |
966 SP+0->+-----------------------+ | variable argument |
967 | functions |
968 FP+16->+-----------------------+
969 | 4 word save area for |
970 | return addr, prev %fp |
971 FP+0->+-----------------------+
972 | |
973 | local variables |
974 | |
975 +-----------------------+
976 | |
977 | register save area |
978 | |
979 +-----------------------+
980 | |
981 | alloca allocations |
982 | |
983 +-----------------------+
984 | |
985 | arguments on stack |
986 | |
987 SP+16->+-----------------------+
988 low | 4 word save area for |
989 memory | return addr, prev %fp |
990 SP+0->+-----------------------+
992 Notes:
993 1) The "reg parm save area" does not exist for non variable argument fns.
994 The "reg parm save area" can be eliminated completely if we created our
995 own va-arc.h, but that has tradeoffs as well (so it's not done). */
997 /* Structure to be filled in by arc_compute_frame_size with register
998 save masks, and offsets for the current function. */
999 struct arc_frame_info
1001 unsigned int total_size; /* # bytes that the entire frame takes up. */
1002 unsigned int extra_size; /* # bytes of extra stuff. */
1003 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
1004 unsigned int args_size; /* # bytes that outgoing arguments take up. */
1005 unsigned int reg_size; /* # bytes needed to store regs. */
1006 unsigned int var_size; /* # bytes that variables take up. */
1007 unsigned int reg_offset; /* Offset from new sp to store regs. */
1008 unsigned int gmask; /* Mask of saved gp registers. */
1009 int initialized; /* Nonzero if frame size already calculated. */
1012 /* Current frame information calculated by arc_compute_frame_size. */
1013 static struct arc_frame_info current_frame_info;
1015 /* Zero structure to initialize current_frame_info. */
1016 static struct arc_frame_info zero_frame_info;
1018 /* Type of function DECL.
1020 The result is cached. To reset the cache at the end of a function,
1021 call with DECL = NULL_TREE. */
1023 enum arc_function_type
1024 arc_compute_function_type (tree decl)
1026 tree a;
1027 /* Cached value. */
1028 static enum arc_function_type fn_type = ARC_FUNCTION_UNKNOWN;
1029 /* Last function we were called for. */
1030 static tree last_fn = NULL_TREE;
1032 /* Resetting the cached value? */
1033 if (decl == NULL_TREE)
1035 fn_type = ARC_FUNCTION_UNKNOWN;
1036 last_fn = NULL_TREE;
1037 return fn_type;
1040 if (decl == last_fn && fn_type != ARC_FUNCTION_UNKNOWN)
1041 return fn_type;
1043 /* Assume we have a normal function (not an interrupt handler). */
1044 fn_type = ARC_FUNCTION_NORMAL;
1046 /* Now see if this is an interrupt handler. */
1047 for (a = DECL_ATTRIBUTES (current_function_decl);
1049 a = TREE_CHAIN (a))
1051 tree name = TREE_PURPOSE (a), args = TREE_VALUE (a);
1053 if (name == get_identifier ("__interrupt__")
1054 && list_length (args) == 1
1055 && TREE_CODE (TREE_VALUE (args)) == STRING_CST)
1057 tree value = TREE_VALUE (args);
1059 if (!strcmp (TREE_STRING_POINTER (value), "ilink1"))
1060 fn_type = ARC_FUNCTION_ILINK1;
1061 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
1062 fn_type = ARC_FUNCTION_ILINK2;
1063 else
1064 gcc_unreachable ();
1065 break;
1069 last_fn = decl;
1070 return fn_type;
1073 #define ILINK1_REGNUM 29
1074 #define ILINK2_REGNUM 30
1075 #define RETURN_ADDR_REGNUM 31
1076 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
1077 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
1079 /* Tell prologue and epilogue if register REGNO should be saved / restored.
1080 The return address and frame pointer are treated separately.
1081 Don't consider them here. */
1082 #define MUST_SAVE_REGISTER(regno, interrupt_p) \
1083 ((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
1084 && (regs_ever_live[regno] && (!call_used_regs[regno] || interrupt_p)))
1086 #define MUST_SAVE_RETURN_ADDR (regs_ever_live[RETURN_ADDR_REGNUM])
1088 /* Return the bytes needed to compute the frame pointer from the current
1089 stack pointer.
1091 SIZE is the size needed for local variables. */
1093 unsigned int
1094 arc_compute_frame_size (int size /* # of var. bytes allocated. */)
1096 int regno;
1097 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
1098 unsigned int reg_size, reg_offset;
1099 unsigned int gmask;
1100 enum arc_function_type fn_type;
1101 int interrupt_p;
1103 var_size = size;
1104 args_size = current_function_outgoing_args_size;
1105 pretend_size = current_function_pretend_args_size;
1106 extra_size = FIRST_PARM_OFFSET (0);
1107 total_size = extra_size + pretend_size + args_size + var_size;
1108 reg_offset = FIRST_PARM_OFFSET(0) + current_function_outgoing_args_size;
1109 reg_size = 0;
1110 gmask = 0;
1112 /* See if this is an interrupt handler. Call used registers must be saved
1113 for them too. */
1114 fn_type = arc_compute_function_type (current_function_decl);
1115 interrupt_p = ARC_INTERRUPT_P (fn_type);
1117 /* Calculate space needed for registers.
1118 ??? We ignore the extension registers for now. */
1120 for (regno = 0; regno <= 31; regno++)
1122 if (MUST_SAVE_REGISTER (regno, interrupt_p))
1124 reg_size += UNITS_PER_WORD;
1125 gmask |= 1 << regno;
1129 total_size += reg_size;
1131 /* If the only space to allocate is the fp/blink save area this is an
1132 empty frame. However, if we'll be making a function call we need to
1133 allocate a stack frame for our callee's fp/blink save area. */
1134 if (total_size == extra_size
1135 && !MUST_SAVE_RETURN_ADDR)
1136 total_size = extra_size = 0;
1138 total_size = ARC_STACK_ALIGN (total_size);
1140 /* Save computed information. */
1141 current_frame_info.total_size = total_size;
1142 current_frame_info.extra_size = extra_size;
1143 current_frame_info.pretend_size = pretend_size;
1144 current_frame_info.var_size = var_size;
1145 current_frame_info.args_size = args_size;
1146 current_frame_info.reg_size = reg_size;
1147 current_frame_info.reg_offset = reg_offset;
1148 current_frame_info.gmask = gmask;
1149 current_frame_info.initialized = reload_completed;
1151 /* Ok, we're done. */
1152 return total_size;
1155 /* Common code to save/restore registers. */
1157 void
1158 arc_save_restore (FILE *file,
1159 const char *base_reg,
1160 unsigned int offset,
1161 unsigned int gmask,
1162 const char *op)
1164 int regno;
1166 if (gmask == 0)
1167 return;
1169 for (regno = 0; regno <= 31; regno++)
1171 if ((gmask & (1L << regno)) != 0)
1173 fprintf (file, "\t%s %s,[%s,%d]\n",
1174 op, reg_names[regno], base_reg, offset);
1175 offset += UNITS_PER_WORD;
1180 /* Target hook to assemble an integer object. The ARC version needs to
1181 emit a special directive for references to labels and function
1182 symbols. */
1184 static bool
1185 arc_assemble_integer (rtx x, unsigned int size, int aligned_p)
1187 if (size == UNITS_PER_WORD && aligned_p
1188 && ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
1189 || GET_CODE (x) == LABEL_REF))
1191 fputs ("\t.word\t%st(", asm_out_file);
1192 output_addr_const (asm_out_file, x);
1193 fputs (")\n", asm_out_file);
1194 return true;
1196 return default_assemble_integer (x, size, aligned_p);
1199 /* Set up the stack and frame pointer (if desired) for the function. */
1201 static void
1202 arc_output_function_prologue (FILE *file, HOST_WIDE_INT size)
1204 const char *sp_str = reg_names[STACK_POINTER_REGNUM];
1205 const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
1206 unsigned int gmask = current_frame_info.gmask;
1207 enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
1209 /* If this is an interrupt handler, set up our stack frame.
1210 ??? Optimize later. */
1211 if (ARC_INTERRUPT_P (fn_type))
1213 fprintf (file, "\t%s interrupt handler\n",
1214 ASM_COMMENT_START);
1215 fprintf (file, "\tsub %s,%s,16\n", sp_str, sp_str);
1218 /* This is only for the human reader. */
1219 fprintf (file, "\t%s BEGIN PROLOGUE %s vars= %d, regs= %d, args= %d, extra= %d\n",
1220 ASM_COMMENT_START, ASM_COMMENT_START,
1221 current_frame_info.var_size,
1222 current_frame_info.reg_size / 4,
1223 current_frame_info.args_size,
1224 current_frame_info.extra_size);
1226 size = ARC_STACK_ALIGN (size);
1227 size = (! current_frame_info.initialized
1228 ? arc_compute_frame_size (size)
1229 : current_frame_info.total_size);
1231 /* These cases shouldn't happen. Catch them now. */
1232 gcc_assert (size || !gmask);
1234 /* Allocate space for register arguments if this is a variadic function. */
1235 if (current_frame_info.pretend_size != 0)
1236 fprintf (file, "\tsub %s,%s,%d\n",
1237 sp_str, sp_str, current_frame_info.pretend_size);
1239 /* The home-grown ABI says link register is saved first. */
1240 if (MUST_SAVE_RETURN_ADDR)
1241 fprintf (file, "\tst %s,[%s,%d]\n",
1242 reg_names[RETURN_ADDR_REGNUM], sp_str, UNITS_PER_WORD);
1244 /* Set up the previous frame pointer next (if we need to). */
1245 if (frame_pointer_needed)
1247 fprintf (file, "\tst %s,[%s]\n", fp_str, sp_str);
1248 fprintf (file, "\tmov %s,%s\n", fp_str, sp_str);
1251 /* ??? We don't handle the case where the saved regs are more than 252
1252 bytes away from sp. This can be handled by decrementing sp once, saving
1253 the regs, and then decrementing it again. The epilogue doesn't have this
1254 problem as the `ld' insn takes reg+limm values (though it would be more
1255 efficient to avoid reg+limm). */
1257 /* Allocate the stack frame. */
1258 if (size - current_frame_info.pretend_size > 0)
1259 fprintf (file, "\tsub %s,%s," HOST_WIDE_INT_PRINT_DEC "\n",
1260 sp_str, sp_str, size - current_frame_info.pretend_size);
1262 /* Save any needed call-saved regs (and call-used if this is an
1263 interrupt handler). */
1264 arc_save_restore (file, sp_str, current_frame_info.reg_offset,
1265 /* The zeroing of these two bits is unnecessary,
1266 but leave this in for clarity. */
1267 gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
1268 "st");
1270 fprintf (file, "\t%s END PROLOGUE\n", ASM_COMMENT_START);
1273 /* Do any necessary cleanup after a function to restore stack, frame,
1274 and regs. */
1276 static void
1277 arc_output_function_epilogue (FILE *file, HOST_WIDE_INT size)
1279 rtx epilogue_delay = current_function_epilogue_delay_list;
1280 int noepilogue = FALSE;
1281 enum arc_function_type fn_type = arc_compute_function_type (current_function_decl);
1283 /* This is only for the human reader. */
1284 fprintf (file, "\t%s EPILOGUE\n", ASM_COMMENT_START);
1286 size = ARC_STACK_ALIGN (size);
1287 size = (!current_frame_info.initialized
1288 ? arc_compute_frame_size (size)
1289 : current_frame_info.total_size);
1291 if (size == 0 && epilogue_delay == 0)
1293 rtx insn = get_last_insn ();
1295 /* If the last insn was a BARRIER, we don't have to write any code
1296 because a jump (aka return) was put there. */
1297 if (GET_CODE (insn) == NOTE)
1298 insn = prev_nonnote_insn (insn);
1299 if (insn && GET_CODE (insn) == BARRIER)
1300 noepilogue = TRUE;
1303 if (!noepilogue)
1305 unsigned int pretend_size = current_frame_info.pretend_size;
1306 unsigned int frame_size = size - pretend_size;
1307 int restored, fp_restored_p;
1308 int can_trust_sp_p = !current_function_calls_alloca;
1309 const char *sp_str = reg_names[STACK_POINTER_REGNUM];
1310 const char *fp_str = reg_names[FRAME_POINTER_REGNUM];
1312 /* ??? There are lots of optimizations that can be done here.
1313 EG: Use fp to restore regs if it's closer.
1314 Maybe in time we'll do them all. For now, always restore regs from
1315 sp, but don't restore sp if we don't have to. */
1317 if (!can_trust_sp_p)
1319 gcc_assert (frame_pointer_needed);
1320 fprintf (file,"\tsub %s,%s,%d\t\t%s sp not trusted here\n",
1321 sp_str, fp_str, frame_size, ASM_COMMENT_START);
1324 /* Restore any saved registers. */
1325 arc_save_restore (file, sp_str, current_frame_info.reg_offset,
1326 /* The zeroing of these two bits is unnecessary,
1327 but leave this in for clarity. */
1328 current_frame_info.gmask & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK),
1329 "ld");
1331 if (MUST_SAVE_RETURN_ADDR)
1332 fprintf (file, "\tld %s,[%s,%d]\n",
1333 reg_names[RETURN_ADDR_REGNUM],
1334 frame_pointer_needed ? fp_str : sp_str,
1335 UNITS_PER_WORD + (frame_pointer_needed ? 0 : frame_size));
1337 /* Keep track of how much of the stack pointer we've restored.
1338 It makes the following a lot more readable. */
1339 restored = 0;
1340 fp_restored_p = 0;
1342 /* We try to emit the epilogue delay slot insn right after the load
1343 of the return address register so that it can execute with the
1344 stack intact. Secondly, loads are delayed. */
1345 /* ??? If stack intactness is important, always emit now. */
1346 if (MUST_SAVE_RETURN_ADDR && epilogue_delay != NULL_RTX)
1348 final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
1349 epilogue_delay = NULL_RTX;
1352 if (frame_pointer_needed)
1354 /* Try to restore the frame pointer in the delay slot. We can't,
1355 however, if any of these is true. */
1356 if (epilogue_delay != NULL_RTX
1357 || !SMALL_INT (frame_size)
1358 || pretend_size
1359 || ARC_INTERRUPT_P (fn_type))
1361 /* Note that we restore fp and sp here! */
1362 fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
1363 restored += frame_size;
1364 fp_restored_p = 1;
1367 else if (!SMALL_INT (size /* frame_size + pretend_size */)
1368 || ARC_INTERRUPT_P (fn_type))
1370 fprintf (file, "\tadd %s,%s,%d\n", sp_str, sp_str, frame_size);
1371 restored += frame_size;
1374 /* These must be done before the return insn because the delay slot
1375 does the final stack restore. */
1376 if (ARC_INTERRUPT_P (fn_type))
1378 if (epilogue_delay)
1380 final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
1384 /* Emit the return instruction. */
1386 static const int regs[4] = {
1387 0, RETURN_ADDR_REGNUM, ILINK1_REGNUM, ILINK2_REGNUM
1389 fprintf (file, "\tj.d %s\n", reg_names[regs[fn_type]]);
1392 /* If the only register saved is the return address, we need a
1393 nop, unless we have an instruction to put into it. Otherwise
1394 we don't since reloading multiple registers doesn't reference
1395 the register being loaded. */
1397 if (ARC_INTERRUPT_P (fn_type))
1398 fprintf (file, "\tadd %s,%s,16\n", sp_str, sp_str);
1399 else if (epilogue_delay != NULL_RTX)
1401 gcc_assert (!frame_pointer_needed || fp_restored_p);
1402 gcc_assert (restored >= size);
1403 final_scan_insn (XEXP (epilogue_delay, 0), file, 1, 1, NULL);
1405 else if (frame_pointer_needed && !fp_restored_p)
1407 gcc_assert (SMALL_INT (frame_size));
1408 /* Note that we restore fp and sp here! */
1409 fprintf (file, "\tld.a %s,[%s,%d]\n", fp_str, sp_str, frame_size);
1411 else if (restored < size)
1413 gcc_assert (SMALL_INT (size - restored));
1414 fprintf (file, "\tadd %s,%s," HOST_WIDE_INT_PRINT_DEC "\n",
1415 sp_str, sp_str, size - restored);
1417 else
1418 fprintf (file, "\tnop\n");
1421 /* Reset state info for each function. */
1422 current_frame_info = zero_frame_info;
1423 arc_compute_function_type (NULL_TREE);
1426 /* Define the number of delay slots needed for the function epilogue.
1428 Interrupt handlers can't have any epilogue delay slots (it's always needed
1429 for something else, I think). For normal functions, we have to worry about
1430 using call-saved regs as they'll be restored before the delay slot insn.
1431 Functions with non-empty frames already have enough choices for the epilogue
1432 delay slot so for now we only consider functions with empty frames. */
1435 arc_delay_slots_for_epilogue (void)
1437 if (arc_compute_function_type (current_function_decl) != ARC_FUNCTION_NORMAL)
1438 return 0;
1439 if (!current_frame_info.initialized)
1440 (void) arc_compute_frame_size (get_frame_size ());
1441 if (current_frame_info.total_size == 0)
1442 return 1;
1443 return 0;
1446 /* Return true if TRIAL is a valid insn for the epilogue delay slot.
1447 Any single length instruction which doesn't reference the stack or frame
1448 pointer or any call-saved register is OK. SLOT will always be 0. */
1451 arc_eligible_for_epilogue_delay (rtx trial, int slot)
1453 gcc_assert (!slot);
1455 if (get_attr_length (trial) == 1
1456 /* If registers where saved, presumably there's more than enough
1457 possibilities for the delay slot. The alternative is something
1458 more complicated (of course, if we expanded the epilogue as rtl
1459 this problem would go away). */
1460 /* ??? Note that this will always be true since only functions with
1461 empty frames have epilogue delay slots. See
1462 arc_delay_slots_for_epilogue. */
1463 && current_frame_info.gmask == 0
1464 && ! reg_mentioned_p (stack_pointer_rtx, PATTERN (trial))
1465 && ! reg_mentioned_p (frame_pointer_rtx, PATTERN (trial)))
1466 return 1;
1467 return 0;
1470 /* PIC */
1472 /* Emit special PIC prologues and epilogues. */
1474 void
1475 arc_finalize_pic (void)
1477 /* nothing to do */
1480 /* Return true if OP is a shift operator. */
1483 shift_operator (rtx op, enum machine_mode mode ATTRIBUTE_UNUSED)
1485 switch (GET_CODE (op))
1487 case ASHIFTRT:
1488 case LSHIFTRT:
1489 case ASHIFT:
1490 return 1;
1491 default:
1492 return 0;
1496 /* Output the assembler code for doing a shift.
1497 We go to a bit of trouble to generate efficient code as the ARC only has
1498 single bit shifts. This is taken from the h8300 port. We only have one
1499 mode of shifting and can't access individual bytes like the h8300 can, so
1500 this is greatly simplified (at the expense of not generating hyper-
1501 efficient code).
1503 This function is not used if the variable shift insns are present. */
1505 /* ??? We assume the output operand is the same as operand 1.
1506 This can be optimized (deleted) in the case of 1 bit shifts. */
1507 /* ??? We use the loop register here. We don't use it elsewhere (yet) and
1508 using it here will give us a chance to play with it. */
1510 const char *
1511 output_shift (rtx *operands)
1513 rtx shift = operands[3];
1514 enum machine_mode mode = GET_MODE (shift);
1515 enum rtx_code code = GET_CODE (shift);
1516 const char *shift_one;
1518 gcc_assert (mode == SImode);
1520 switch (code)
1522 case ASHIFT: shift_one = "asl %0,%0"; break;
1523 case ASHIFTRT: shift_one = "asr %0,%0"; break;
1524 case LSHIFTRT: shift_one = "lsr %0,%0"; break;
1525 default: gcc_unreachable ();
1528 if (GET_CODE (operands[2]) != CONST_INT)
1530 if (optimize)
1531 output_asm_insn ("mov lp_count,%2", operands);
1532 else
1533 output_asm_insn ("mov %4,%2", operands);
1534 goto shiftloop;
1536 else
1538 int n = INTVAL (operands[2]);
1540 /* If the count is negative, make it 0. */
1541 if (n < 0)
1542 n = 0;
1543 /* If the count is too big, truncate it.
1544 ANSI says shifts of GET_MODE_BITSIZE are undefined - we choose to
1545 do the intuitive thing. */
1546 else if (n > GET_MODE_BITSIZE (mode))
1547 n = GET_MODE_BITSIZE (mode);
1549 /* First see if we can do them inline. */
1550 if (n <= 8)
1552 while (--n >= 0)
1553 output_asm_insn (shift_one, operands);
1555 /* See if we can use a rotate/and. */
1556 else if (n == BITS_PER_WORD - 1)
1558 switch (code)
1560 case ASHIFT :
1561 output_asm_insn ("and %0,%0,1\n\tror %0,%0", operands);
1562 break;
1563 case ASHIFTRT :
1564 /* The ARC doesn't have a rol insn. Use something else. */
1565 output_asm_insn ("asl.f 0,%0\n\tsbc %0,0,0", operands);
1566 break;
1567 case LSHIFTRT :
1568 /* The ARC doesn't have a rol insn. Use something else. */
1569 output_asm_insn ("asl.f 0,%0\n\tadc %0,0,0", operands);
1570 break;
1571 default:
1572 break;
1575 /* Must loop. */
1576 else
1578 char buf[100];
1580 if (optimize)
1581 output_asm_insn ("mov lp_count,%c2", operands);
1582 else
1583 output_asm_insn ("mov %4,%c2", operands);
1584 shiftloop:
1585 if (optimize)
1587 if (flag_pic)
1588 sprintf (buf, "lr %%4,[status]\n\tadd %%4,%%4,6\t%s single insn loop start",
1589 ASM_COMMENT_START);
1590 else
1591 sprintf (buf, "mov %%4,%%%%st(1f)\t%s (single insn loop start) >> 2",
1592 ASM_COMMENT_START);
1593 output_asm_insn (buf, operands);
1594 output_asm_insn ("sr %4,[lp_start]", operands);
1595 output_asm_insn ("add %4,%4,1", operands);
1596 output_asm_insn ("sr %4,[lp_end]", operands);
1597 output_asm_insn ("nop\n\tnop", operands);
1598 if (flag_pic)
1599 fprintf (asm_out_file, "\t%s single insn loop\n",
1600 ASM_COMMENT_START);
1601 else
1602 fprintf (asm_out_file, "1:\t%s single insn loop\n",
1603 ASM_COMMENT_START);
1604 output_asm_insn (shift_one, operands);
1606 else
1608 fprintf (asm_out_file, "1:\t%s begin shift loop\n",
1609 ASM_COMMENT_START);
1610 output_asm_insn ("sub.f %4,%4,1", operands);
1611 output_asm_insn ("nop", operands);
1612 output_asm_insn ("bn.nd 2f", operands);
1613 output_asm_insn (shift_one, operands);
1614 output_asm_insn ("b.nd 1b", operands);
1615 fprintf (asm_out_file, "2:\t%s end shift loop\n",
1616 ASM_COMMENT_START);
1621 return "";
1624 /* Nested function support. */
1626 /* Emit RTL insns to initialize the variable parts of a trampoline.
1627 FNADDR is an RTX for the address of the function's pure code.
1628 CXT is an RTX for the static chain value for the function. */
1630 void
1631 arc_initialize_trampoline (rtx tramp ATTRIBUTE_UNUSED,
1632 rtx fnaddr ATTRIBUTE_UNUSED,
1633 rtx cxt ATTRIBUTE_UNUSED)
1637 /* Set the cpu type and print out other fancy things,
1638 at the top of the file. */
1640 static void
1641 arc_file_start (void)
1643 default_file_start ();
1644 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
1647 /* Print operand X (an rtx) in assembler syntax to file FILE.
1648 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
1649 For `%' followed by punctuation, CODE is the punctuation and X is null. */
1651 void
1652 arc_print_operand (FILE *file, rtx x, int code)
1654 switch (code)
1656 case '#' :
1657 /* Conditional branches. For now these are equivalent. */
1658 case '*' :
1659 /* Unconditional branches. Output the appropriate delay slot suffix. */
1660 if (!final_sequence || XVECLEN (final_sequence, 0) == 1)
1662 /* There's nothing in the delay slot. */
1663 fputs (".nd", file);
1665 else
1667 rtx jump = XVECEXP (final_sequence, 0, 0);
1668 rtx delay = XVECEXP (final_sequence, 0, 1);
1669 if (INSN_ANNULLED_BRANCH_P (jump))
1670 fputs (INSN_FROM_TARGET_P (delay) ? ".jd" : ".nd", file);
1671 else
1672 fputs (".d", file);
1674 return;
1675 case '?' : /* with leading "." */
1676 case '!' : /* without leading "." */
1677 /* This insn can be conditionally executed. See if the ccfsm machinery
1678 says it should be conditionalized. */
1679 if (arc_ccfsm_state == 3 || arc_ccfsm_state == 4)
1681 /* Is this insn in a delay slot? */
1682 if (final_sequence && XVECLEN (final_sequence, 0) == 2)
1684 rtx insn = XVECEXP (final_sequence, 0, 1);
1686 /* If the insn is annulled and is from the target path, we need
1687 to inverse the condition test. */
1688 if (INSN_ANNULLED_BRANCH_P (insn))
1690 if (INSN_FROM_TARGET_P (insn))
1691 fprintf (file, "%s%s",
1692 code == '?' ? "." : "",
1693 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc)]);
1694 else
1695 fprintf (file, "%s%s",
1696 code == '?' ? "." : "",
1697 arc_condition_codes[arc_ccfsm_current_cc]);
1699 else
1701 /* This insn is executed for either path, so don't
1702 conditionalize it at all. */
1703 ; /* nothing to do */
1706 else
1708 /* This insn isn't in a delay slot. */
1709 fprintf (file, "%s%s",
1710 code == '?' ? "." : "",
1711 arc_condition_codes[arc_ccfsm_current_cc]);
1714 return;
1715 case '~' :
1716 /* Output a nop if we're between a set of the condition codes,
1717 and a conditional branch. */
1718 if (last_insn_set_cc_p)
1719 fputs ("nop\n\t", file);
1720 return;
1721 case 'd' :
1722 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
1723 return;
1724 case 'D' :
1725 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
1726 (get_arc_condition_code (x))],
1727 file);
1728 return;
1729 case 'R' :
1730 /* Write second word of DImode or DFmode reference,
1731 register or memory. */
1732 if (GET_CODE (x) == REG)
1733 fputs (reg_names[REGNO (x)+1], file);
1734 else if (GET_CODE (x) == MEM)
1736 fputc ('[', file);
1737 /* Handle possible auto-increment. Since it is pre-increment and
1738 we have already done it, we can just use an offset of four. */
1739 /* ??? This is taken from rs6000.c I think. I don't think it is
1740 currently necessary, but keep it around. */
1741 if (GET_CODE (XEXP (x, 0)) == PRE_INC
1742 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1743 output_address (plus_constant (XEXP (XEXP (x, 0), 0), 4));
1744 else
1745 output_address (plus_constant (XEXP (x, 0), 4));
1746 fputc (']', file);
1748 else
1749 output_operand_lossage ("invalid operand to %%R code");
1750 return;
1751 case 'S' :
1752 if ((GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_FUNCTION_P (x))
1753 || GET_CODE (x) == LABEL_REF)
1755 fprintf (file, "%%st(");
1756 output_addr_const (file, x);
1757 fprintf (file, ")");
1758 return;
1760 break;
1761 case 'H' :
1762 case 'L' :
1763 if (GET_CODE (x) == REG)
1765 /* L = least significant word, H = most significant word */
1766 if ((TARGET_BIG_ENDIAN != 0) ^ (code == 'L'))
1767 fputs (reg_names[REGNO (x)], file);
1768 else
1769 fputs (reg_names[REGNO (x)+1], file);
1771 else if (GET_CODE (x) == CONST_INT
1772 || GET_CODE (x) == CONST_DOUBLE)
1774 rtx first, second;
1776 split_double (x, &first, &second);
1777 fprintf (file, "0x%08lx",
1778 (long)(code == 'L' ? INTVAL (first) : INTVAL (second)));
1780 else
1781 output_operand_lossage ("invalid operand to %%H/%%L code");
1782 return;
1783 case 'A' :
1785 char str[30];
1787 gcc_assert (GET_CODE (x) == CONST_DOUBLE
1788 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
1790 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
1791 fprintf (file, "%s", str);
1792 return;
1794 case 'U' :
1795 /* Output a load/store with update indicator if appropriate. */
1796 if (GET_CODE (x) == MEM)
1798 if (GET_CODE (XEXP (x, 0)) == PRE_INC
1799 || GET_CODE (XEXP (x, 0)) == PRE_DEC)
1800 fputs (".a", file);
1802 else
1803 output_operand_lossage ("invalid operand to %%U code");
1804 return;
1805 case 'V' :
1806 /* Output cache bypass indicator for a load/store insn. Volatile memory
1807 refs are defined to use the cache bypass mechanism. */
1808 if (GET_CODE (x) == MEM)
1810 if (MEM_VOLATILE_P (x))
1811 fputs (".di", file);
1813 else
1814 output_operand_lossage ("invalid operand to %%V code");
1815 return;
1816 case 0 :
1817 /* Do nothing special. */
1818 break;
1819 default :
1820 /* Unknown flag. */
1821 output_operand_lossage ("invalid operand output code");
1824 switch (GET_CODE (x))
1826 case REG :
1827 fputs (reg_names[REGNO (x)], file);
1828 break;
1829 case MEM :
1830 fputc ('[', file);
1831 if (GET_CODE (XEXP (x, 0)) == PRE_INC)
1832 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
1833 GET_MODE_SIZE (GET_MODE (x))));
1834 else if (GET_CODE (XEXP (x, 0)) == PRE_DEC)
1835 output_address (plus_constant (XEXP (XEXP (x, 0), 0),
1836 - GET_MODE_SIZE (GET_MODE (x))));
1837 else
1838 output_address (XEXP (x, 0));
1839 fputc (']', file);
1840 break;
1841 case CONST_DOUBLE :
1842 /* We handle SFmode constants here as output_addr_const doesn't. */
1843 if (GET_MODE (x) == SFmode)
1845 REAL_VALUE_TYPE d;
1846 long l;
1848 REAL_VALUE_FROM_CONST_DOUBLE (d, x);
1849 REAL_VALUE_TO_TARGET_SINGLE (d, l);
1850 fprintf (file, "0x%08lx", l);
1851 break;
1853 /* Fall through. Let output_addr_const deal with it. */
1854 default :
1855 output_addr_const (file, x);
1856 break;
1860 /* Print a memory address as an operand to reference that memory location. */
1862 void
1863 arc_print_operand_address (FILE *file, rtx addr)
1865 register rtx base, index = 0;
1866 int offset = 0;
1868 switch (GET_CODE (addr))
1870 case REG :
1871 fputs (reg_names[REGNO (addr)], file);
1872 break;
1873 case SYMBOL_REF :
1874 if (/*???*/ 0 && SYMBOL_REF_FUNCTION_P (addr))
1876 fprintf (file, "%%st(");
1877 output_addr_const (file, addr);
1878 fprintf (file, ")");
1880 else
1881 output_addr_const (file, addr);
1882 break;
1883 case PLUS :
1884 if (GET_CODE (XEXP (addr, 0)) == CONST_INT)
1885 offset = INTVAL (XEXP (addr, 0)), base = XEXP (addr, 1);
1886 else if (GET_CODE (XEXP (addr, 1)) == CONST_INT)
1887 offset = INTVAL (XEXP (addr, 1)), base = XEXP (addr, 0);
1888 else
1889 base = XEXP (addr, 0), index = XEXP (addr, 1);
1890 gcc_assert (GET_CODE (base) == REG);
1891 fputs (reg_names[REGNO (base)], file);
1892 if (index == 0)
1894 if (offset != 0)
1895 fprintf (file, ",%d", offset);
1897 else
1899 switch (GET_CODE (index))
1901 case REG:
1902 fprintf (file, ",%s", reg_names[REGNO (index)]);
1903 break;
1904 case SYMBOL_REF:
1905 fputc (',', file), output_addr_const (file, index);
1906 break;
1907 default:
1908 gcc_unreachable ();
1911 break;
1912 case PRE_INC :
1913 case PRE_DEC :
1914 /* We shouldn't get here as we've lost the mode of the memory object
1915 (which says how much to inc/dec by. */
1916 gcc_unreachable ();
1917 break;
1918 default :
1919 output_addr_const (file, addr);
1920 break;
1924 /* Update compare/branch separation marker. */
1926 static void
1927 record_cc_ref (rtx insn)
1929 last_insn_set_cc_p = current_insn_set_cc_p;
1931 switch (get_attr_cond (insn))
1933 case COND_SET :
1934 case COND_SET_ZN :
1935 case COND_SET_ZNC :
1936 if (get_attr_length (insn) == 1)
1937 current_insn_set_cc_p = 1;
1938 else
1939 current_insn_set_cc_p = 0;
1940 break;
1941 default :
1942 current_insn_set_cc_p = 0;
1943 break;
1947 /* Conditional execution support.
1949 This is based on the ARM port but for now is much simpler.
1951 A finite state machine takes care of noticing whether or not instructions
1952 can be conditionally executed, and thus decrease execution time and code
1953 size by deleting branch instructions. The fsm is controlled by
1954 final_prescan_insn, and controls the actions of PRINT_OPERAND. The patterns
1955 in the .md file for the branch insns also have a hand in this. */
1957 /* The state of the fsm controlling condition codes are:
1958 0: normal, do nothing special
1959 1: don't output this insn
1960 2: don't output this insn
1961 3: make insns conditional
1962 4: make insns conditional
1964 State transitions (state->state by whom, under what condition):
1965 0 -> 1 final_prescan_insn, if insn is conditional branch
1966 0 -> 2 final_prescan_insn, if the `target' is an unconditional branch
1967 1 -> 3 branch patterns, after having not output the conditional branch
1968 2 -> 4 branch patterns, after having not output the conditional branch
1969 3 -> 0 (*targetm.asm_out.internal_label), if the `target' label is reached
1970 (the target label has CODE_LABEL_NUMBER equal to
1971 arc_ccfsm_target_label).
1972 4 -> 0 final_prescan_insn, if `target' unconditional branch is reached
1974 If the jump clobbers the conditions then we use states 2 and 4.
1976 A similar thing can be done with conditional return insns.
1978 We also handle separating branches from sets of the condition code.
1979 This is done here because knowledge of the ccfsm state is required,
1980 we may not be outputting the branch. */
1982 void
1983 arc_final_prescan_insn (rtx insn,
1984 rtx *opvec ATTRIBUTE_UNUSED,
1985 int noperands ATTRIBUTE_UNUSED)
1987 /* BODY will hold the body of INSN. */
1988 register rtx body = PATTERN (insn);
1990 /* This will be 1 if trying to repeat the trick (i.e.: do the `else' part of
1991 an if/then/else), and things need to be reversed. */
1992 int reverse = 0;
1994 /* If we start with a return insn, we only succeed if we find another one. */
1995 int seeking_return = 0;
1997 /* START_INSN will hold the insn from where we start looking. This is the
1998 first insn after the following code_label if REVERSE is true. */
1999 rtx start_insn = insn;
2001 /* Update compare/branch separation marker. */
2002 record_cc_ref (insn);
2004 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
2005 We can't do this in macro FINAL_PRESCAN_INSN because its called from
2006 final_scan_insn which has `optimize' as a local. */
2007 if (optimize < 2 || TARGET_NO_COND_EXEC)
2008 return;
2010 /* If in state 4, check if the target branch is reached, in order to
2011 change back to state 0. */
2012 if (arc_ccfsm_state == 4)
2014 if (insn == arc_ccfsm_target_insn)
2016 arc_ccfsm_target_insn = NULL;
2017 arc_ccfsm_state = 0;
2019 return;
2022 /* If in state 3, it is possible to repeat the trick, if this insn is an
2023 unconditional branch to a label, and immediately following this branch
2024 is the previous target label which is only used once, and the label this
2025 branch jumps to is not too far off. Or in other words "we've done the
2026 `then' part, see if we can do the `else' part." */
2027 if (arc_ccfsm_state == 3)
2029 if (simplejump_p (insn))
2031 start_insn = next_nonnote_insn (start_insn);
2032 if (GET_CODE (start_insn) == BARRIER)
2034 /* ??? Isn't this always a barrier? */
2035 start_insn = next_nonnote_insn (start_insn);
2037 if (GET_CODE (start_insn) == CODE_LABEL
2038 && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
2039 && LABEL_NUSES (start_insn) == 1)
2040 reverse = TRUE;
2041 else
2042 return;
2044 else if (GET_CODE (body) == RETURN)
2046 start_insn = next_nonnote_insn (start_insn);
2047 if (GET_CODE (start_insn) == BARRIER)
2048 start_insn = next_nonnote_insn (start_insn);
2049 if (GET_CODE (start_insn) == CODE_LABEL
2050 && CODE_LABEL_NUMBER (start_insn) == arc_ccfsm_target_label
2051 && LABEL_NUSES (start_insn) == 1)
2053 reverse = TRUE;
2054 seeking_return = 1;
2056 else
2057 return;
2059 else
2060 return;
2063 if (GET_CODE (insn) != JUMP_INSN)
2064 return;
2066 /* This jump might be paralleled with a clobber of the condition codes,
2067 the jump should always come first. */
2068 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
2069 body = XVECEXP (body, 0, 0);
2071 if (reverse
2072 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
2073 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
2075 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
2076 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
2077 int then_not_else = TRUE;
2078 /* Nonzero if next insn must be the target label. */
2079 int next_must_be_target_label_p;
2080 rtx this_insn = start_insn, label = 0;
2082 /* Register the insn jumped to. */
2083 if (reverse)
2085 if (!seeking_return)
2086 label = XEXP (SET_SRC (body), 0);
2088 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
2089 label = XEXP (XEXP (SET_SRC (body), 1), 0);
2090 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
2092 label = XEXP (XEXP (SET_SRC (body), 2), 0);
2093 then_not_else = FALSE;
2095 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == RETURN)
2096 seeking_return = 1;
2097 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == RETURN)
2099 seeking_return = 1;
2100 then_not_else = FALSE;
2102 else
2103 gcc_unreachable ();
2105 /* See how many insns this branch skips, and what kind of insns. If all
2106 insns are okay, and the label or unconditional branch to the same
2107 label is not too far away, succeed. */
2108 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
2109 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
2110 insns_skipped++)
2112 rtx scanbody;
2114 this_insn = next_nonnote_insn (this_insn);
2115 if (!this_insn)
2116 break;
2118 if (next_must_be_target_label_p)
2120 if (GET_CODE (this_insn) == BARRIER)
2121 continue;
2122 if (GET_CODE (this_insn) == CODE_LABEL
2123 && this_insn == label)
2125 arc_ccfsm_state = 1;
2126 succeed = TRUE;
2128 else
2129 fail = TRUE;
2130 break;
2133 scanbody = PATTERN (this_insn);
2135 switch (GET_CODE (this_insn))
2137 case CODE_LABEL:
2138 /* Succeed if it is the target label, otherwise fail since
2139 control falls in from somewhere else. */
2140 if (this_insn == label)
2142 arc_ccfsm_state = 1;
2143 succeed = TRUE;
2145 else
2146 fail = TRUE;
2147 break;
2149 case BARRIER:
2150 /* Succeed if the following insn is the target label.
2151 Otherwise fail.
2152 If return insns are used then the last insn in a function
2153 will be a barrier. */
2154 next_must_be_target_label_p = TRUE;
2155 break;
2157 case CALL_INSN:
2158 /* Can handle a call insn if there are no insns after it.
2159 IE: The next "insn" is the target label. We don't have to
2160 worry about delay slots as such insns are SEQUENCE's inside
2161 INSN's. ??? It is possible to handle such insns though. */
2162 if (get_attr_cond (this_insn) == COND_CANUSE)
2163 next_must_be_target_label_p = TRUE;
2164 else
2165 fail = TRUE;
2166 break;
2168 case JUMP_INSN:
2169 /* If this is an unconditional branch to the same label, succeed.
2170 If it is to another label, do nothing. If it is conditional,
2171 fail. */
2172 /* ??? Probably, the test for the SET and the PC are unnecessary. */
2174 if (GET_CODE (scanbody) == SET
2175 && GET_CODE (SET_DEST (scanbody)) == PC)
2177 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
2178 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
2180 arc_ccfsm_state = 2;
2181 succeed = TRUE;
2183 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
2184 fail = TRUE;
2186 else if (GET_CODE (scanbody) == RETURN
2187 && seeking_return)
2189 arc_ccfsm_state = 2;
2190 succeed = TRUE;
2192 else if (GET_CODE (scanbody) == PARALLEL)
2194 if (get_attr_cond (this_insn) != COND_CANUSE)
2195 fail = TRUE;
2197 break;
2199 case INSN:
2200 /* We can only do this with insns that can use the condition
2201 codes (and don't set them). */
2202 if (GET_CODE (scanbody) == SET
2203 || GET_CODE (scanbody) == PARALLEL)
2205 if (get_attr_cond (this_insn) != COND_CANUSE)
2206 fail = TRUE;
2208 /* We can't handle other insns like sequences. */
2209 else
2210 fail = TRUE;
2211 break;
2213 default:
2214 break;
2218 if (succeed)
2220 if ((!seeking_return) && (arc_ccfsm_state == 1 || reverse))
2221 arc_ccfsm_target_label = CODE_LABEL_NUMBER (label);
2222 else
2224 gcc_assert (seeking_return || arc_ccfsm_state == 2);
2225 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
2227 this_insn = next_nonnote_insn (this_insn);
2228 gcc_assert (!this_insn
2229 || (GET_CODE (this_insn) != BARRIER
2230 && GET_CODE (this_insn) != CODE_LABEL));
2232 if (!this_insn)
2234 /* Oh dear! we ran off the end, give up. */
2235 extract_insn_cached (insn);
2236 arc_ccfsm_state = 0;
2237 arc_ccfsm_target_insn = NULL;
2238 return;
2240 arc_ccfsm_target_insn = this_insn;
2243 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
2244 what it was. */
2245 if (!reverse)
2246 arc_ccfsm_current_cc = get_arc_condition_code (XEXP (SET_SRC (body),
2247 0));
2249 if (reverse || then_not_else)
2250 arc_ccfsm_current_cc = ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current_cc);
2253 /* Restore recog_data. Getting the attributes of other insns can
2254 destroy this array, but final.c assumes that it remains intact
2255 across this call. */
2256 extract_insn_cached (insn);
2260 /* Record that we are currently outputting label NUM with prefix PREFIX.
2261 It it's the label we're looking for, reset the ccfsm machinery.
2263 Called from (*targetm.asm_out.internal_label). */
2265 void
2266 arc_ccfsm_at_label (const char *prefix, int num)
2268 if (arc_ccfsm_state == 3 && arc_ccfsm_target_label == num
2269 && !strcmp (prefix, "L"))
2271 arc_ccfsm_state = 0;
2272 arc_ccfsm_target_insn = NULL_RTX;
2276 /* See if the current insn, which is a conditional branch, is to be
2277 deleted. */
2280 arc_ccfsm_branch_deleted_p (void)
2282 if (arc_ccfsm_state == 1 || arc_ccfsm_state == 2)
2283 return 1;
2284 return 0;
2287 /* Record a branch isn't output because subsequent insns can be
2288 conditionalized. */
2290 void
2291 arc_ccfsm_record_branch_deleted (void)
2293 /* Indicate we're conditionalizing insns now. */
2294 arc_ccfsm_state += 2;
2296 /* If the next insn is a subroutine call, we still need a nop between the
2297 cc setter and user. We need to undo the effect of calling record_cc_ref
2298 for the just deleted branch. */
2299 current_insn_set_cc_p = last_insn_set_cc_p;
2302 void
2303 arc_va_start (tree valist, rtx nextarg)
2305 /* See arc_setup_incoming_varargs for reasons for this oddity. */
2306 if (current_function_args_info < 8
2307 && (current_function_args_info & 1))
2308 nextarg = plus_constant (nextarg, UNITS_PER_WORD);
2310 std_expand_builtin_va_start (valist, nextarg);
2313 /* This is how to output a definition of an internal numbered label where
2314 PREFIX is the class of label and NUM is the number within the class. */
2316 static void
2317 arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
2319 arc_ccfsm_at_label (prefix, labelno);
2320 default_internal_label (stream, prefix, labelno);
2323 /* Worker function for TARGET_ASM_EXTERNAL_LIBCALL. */
2325 static void
2326 arc_external_libcall (rtx fun ATTRIBUTE_UNUSED)
2328 #if 0
2329 /* On the ARC we want to have libgcc's for multiple cpus in one binary.
2330 We can't use `assemble_name' here as that will call ASM_OUTPUT_LABELREF
2331 and we'll get another suffix added on if -mmangle-cpu. */
2332 if (TARGET_MANGLE_CPU_LIBGCC)
2334 fprintf (FILE, "\t.rename\t_%s, _%s%s\n",
2335 XSTR (SYMREF, 0), XSTR (SYMREF, 0),
2336 arc_mangle_suffix);
2338 #endif
2341 /* Worker function for TARGET_RETURN_IN_MEMORY. */
2343 static bool
2344 arc_return_in_memory (tree type, tree fntype ATTRIBUTE_UNUSED)
2346 if (AGGREGATE_TYPE_P (type))
2347 return true;
2348 else
2350 HOST_WIDE_INT size = int_size_in_bytes (type);
2351 return (size == -1 || size > 8);
2355 /* For ARC, All aggregates and arguments greater than 8 bytes are
2356 passed by reference. */
2358 static bool
2359 arc_pass_by_reference (CUMULATIVE_ARGS *ca ATTRIBUTE_UNUSED,
2360 enum machine_mode mode, tree type,
2361 bool named ATTRIBUTE_UNUSED)
2363 unsigned HOST_WIDE_INT size;
2365 if (type)
2367 if (AGGREGATE_TYPE_P (type))
2368 return true;
2369 size = int_size_in_bytes (type);
2371 else
2372 size = GET_MODE_SIZE (mode);
2374 return size > 8;