1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2017 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
33 #include "coretypes.h"
42 #include "stringpool.h"
47 #include "diagnostic.h"
48 #include "fold-const.h"
50 #include "stor-layout.h"
53 #include "insn-attr.h"
57 #include "langhooks.h"
58 #include "tm-constrs.h"
59 #include "reload.h" /* For operands_match_p */
61 #include "tree-pass.h"
68 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
69 static char arc_cpu_name
[10] = "";
70 static const char *arc_cpu_string
= arc_cpu_name
;
72 /* ??? Loads can handle any constant, stores can only handle small ones. */
73 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
74 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
75 (GET_CODE (X) == CONST_INT \
76 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
77 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
79 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
81 #define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
82 (GET_CODE (X) == PLUS \
83 && GET_CODE (XEXP (X, 0)) == MULT \
84 && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
85 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
86 && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
87 || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
88 && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
89 || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
91 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
92 (GET_CODE (X) == PLUS \
93 && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
94 && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
95 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
96 || (GET_CODE (XEXP ((X), 1)) == CONST \
97 && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
98 && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
99 && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
100 && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
102 /* Array of valid operand punctuation characters. */
103 char arc_punct_chars
[256];
105 /* State used by arc_ccfsm_advance to implement conditional execution. */
106 struct GTY (()) arc_ccfsm
111 rtx_insn
*target_insn
;
115 /* Status of the IRQ_CTRL_AUX register. */
116 typedef struct irq_ctrl_saved_t
118 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
119 short irq_save_last_reg
;
120 /* True if BLINK is automatically saved. */
122 /* True if LPCOUNT is automatically saved. */
123 bool irq_save_lpcount
;
125 static irq_ctrl_saved_t irq_ctrl_saved
;
127 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
128 ((ARC_INTERRUPT_P (FNTYPE) \
129 && irq_ctrl_saved.irq_save_blink) \
130 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
131 && rgf_banked_register_count > 8))
133 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
134 ((ARC_INTERRUPT_P (FNTYPE) \
135 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
136 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
137 && rgf_banked_register_count > 8))
139 #define ARC_AUTO_IRQ_P(FNTYPE) \
140 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
141 && (irq_ctrl_saved.irq_save_blink \
142 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
144 /* Number of registers in second bank for FIRQ support. */
145 static int rgf_banked_register_count
;
147 #define arc_ccfsm_current cfun->machine->ccfsm_current
149 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
150 ((STATE)->state == 1 || (STATE)->state == 2)
152 /* Indicate we're conditionalizing insns now. */
153 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
154 ((STATE)->state += 2)
156 #define ARC_CCFSM_COND_EXEC_P(STATE) \
157 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
158 || current_insn_predicate)
160 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
161 #define CCFSM_ISCOMPACT(INSN,STATE) \
162 (ARC_CCFSM_COND_EXEC_P (STATE) \
163 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
164 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
165 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
167 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
168 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
169 ((ARC_CCFSM_COND_EXEC_P (STATE) \
171 && INSN_ANNULLED_BRANCH_P (JUMP) \
172 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
173 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
174 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
175 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
177 /* The maximum number of insns skipped which will be conditionalised if
179 /* When optimizing for speed:
180 Let p be the probability that the potentially skipped insns need to
181 be executed, pn the cost of a correctly predicted non-taken branch,
182 mt the cost of a mis/non-predicted taken branch,
183 mn mispredicted non-taken, pt correctly predicted taken ;
184 costs expressed in numbers of instructions like the ones considered
186 Unfortunately we don't have a measure of predictability - this
187 is linked to probability only in that in the no-eviction-scenario
188 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
189 value that can be assumed *if* the distribution is perfectly random.
190 A predictability of 1 is perfectly plausible not matter what p is,
191 because the decision could be dependent on an invocation parameter
193 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
194 For small p, we want MAX_INSNS_SKIPPED == pt
196 When optimizing for size:
197 We want to skip insn unless we could use 16 opcodes for the
198 non-conditionalized insn to balance the branch length or more.
199 Performance can be tie-breaker. */
200 /* If the potentially-skipped insns are likely to be executed, we'll
201 generally save one non-taken branch
203 this to be no less than the 1/p */
204 #define MAX_INSNS_SKIPPED 3
206 /* A nop is needed between a 4 byte insn that sets the condition codes and
207 a branch that uses them (the same isn't true for an 8 byte insn that sets
208 the condition codes). Set by arc_ccfsm_advance. Used by
209 arc_print_operand. */
211 static int get_arc_condition_code (rtx
);
213 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
215 /* Initialized arc_attribute_table to NULL since arc doesnot have any
216 machine specific supported attributes. */
217 const struct attribute_spec arc_attribute_table
[] =
219 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
220 affects_type_identity } */
221 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute
, true },
222 /* Function calls made to this symbol must be done indirectly, because
223 it may lie outside of the 21/25 bit addressing range of a normal function
225 { "long_call", 0, 0, false, true, true, NULL
, false },
226 /* Whereas these functions are always known to reside within the 25 bit
227 addressing range of unconditionalized bl. */
228 { "medium_call", 0, 0, false, true, true, NULL
, false },
229 /* And these functions are always known to reside within the 21 bit
230 addressing range of blcc. */
231 { "short_call", 0, 0, false, true, true, NULL
, false },
232 { NULL
, 0, 0, false, false, false, NULL
, false }
234 static int arc_comp_type_attributes (const_tree
, const_tree
);
235 static void arc_file_start (void);
236 static void arc_internal_label (FILE *, const char *, unsigned long);
237 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
239 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
240 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
242 static void arc_init_builtins (void);
243 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
245 static int branch_dest (rtx
);
247 static void arc_output_pic_addr_const (FILE *, rtx
, int);
248 bool arc_legitimate_pic_operand_p (rtx
);
249 static bool arc_function_ok_for_sibcall (tree
, tree
);
250 static rtx
arc_function_value (const_tree
, const_tree
, bool);
251 const char * output_shift (rtx
*);
252 static void arc_reorg (void);
253 static bool arc_in_small_data_p (const_tree
);
255 static void arc_init_reg_tables (void);
256 static bool arc_return_in_memory (const_tree
, const_tree
);
257 static bool arc_vector_mode_supported_p (machine_mode
);
259 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
261 static const char *arc_invalid_within_doloop (const rtx_insn
*);
263 static void output_short_suffix (FILE *file
);
265 static bool arc_frame_pointer_required (void);
267 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
269 enum by_pieces_operation op
,
272 /* Globally visible information about currently selected cpu. */
273 const arc_cpu_t
*arc_selected_cpu
;
275 /* Check for constructions like REG + OFFS, where OFFS can be a
276 register, an immediate or an long immediate. */
279 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
281 if (GET_CODE (x
) != PLUS
)
284 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
287 /* Check for: [Rx + small offset] or [Rx + Ry]. */
288 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
289 && GET_MODE_SIZE ((mode
)) <= 4)
290 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
293 /* Check for [Rx + symbol]. */
295 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
296 /* Avoid this type of address for double or larger modes. */
297 && (GET_MODE_SIZE (mode
) <= 4)
298 /* Avoid small data which ends in something like GP +
300 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))
301 || TARGET_NO_SDATA_SET
))
307 /* Implements target hook vector_mode_supported_p. */
310 arc_vector_mode_supported_p (machine_mode mode
)
315 return TARGET_PLUS_DMPY
;
318 return TARGET_PLUS_QMACW
;
321 return TARGET_SIMD_SET
;
328 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
331 arc_preferred_simd_mode (machine_mode mode
)
336 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
345 /* Implements target hook
346 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
349 arc_autovectorize_vector_sizes (void)
351 return TARGET_PLUS_QMACW
? (8 | 4) : 0;
354 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
355 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
356 static rtx
arc_delegitimize_address (rtx
);
357 static bool arc_can_follow_jump (const rtx_insn
*follower
,
358 const rtx_insn
*followee
);
360 static rtx
frame_insn (rtx
);
361 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
363 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
365 static void arc_finalize_pic (void);
367 /* initialize the GCC target structure. */
368 #undef TARGET_COMP_TYPE_ATTRIBUTES
369 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
370 #undef TARGET_ASM_FILE_START
371 #define TARGET_ASM_FILE_START arc_file_start
372 #undef TARGET_ATTRIBUTE_TABLE
373 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
374 #undef TARGET_ASM_INTERNAL_LABEL
375 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
376 #undef TARGET_RTX_COSTS
377 #define TARGET_RTX_COSTS arc_rtx_costs
378 #undef TARGET_ADDRESS_COST
379 #define TARGET_ADDRESS_COST arc_address_cost
381 #undef TARGET_ENCODE_SECTION_INFO
382 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
384 #undef TARGET_CANNOT_FORCE_CONST_MEM
385 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
387 #undef TARGET_INIT_BUILTINS
388 #define TARGET_INIT_BUILTINS arc_init_builtins
390 #undef TARGET_EXPAND_BUILTIN
391 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
393 #undef TARGET_BUILTIN_DECL
394 #define TARGET_BUILTIN_DECL arc_builtin_decl
396 #undef TARGET_ASM_OUTPUT_MI_THUNK
397 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
399 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
400 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
402 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
403 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
405 #undef TARGET_MACHINE_DEPENDENT_REORG
406 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
408 #undef TARGET_IN_SMALL_DATA_P
409 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
411 #undef TARGET_PROMOTE_FUNCTION_MODE
412 #define TARGET_PROMOTE_FUNCTION_MODE \
413 default_promote_function_mode_always_promote
415 #undef TARGET_PROMOTE_PROTOTYPES
416 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
418 #undef TARGET_RETURN_IN_MEMORY
419 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
420 #undef TARGET_PASS_BY_REFERENCE
421 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
423 #undef TARGET_SETUP_INCOMING_VARARGS
424 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
426 #undef TARGET_ARG_PARTIAL_BYTES
427 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
429 #undef TARGET_MUST_PASS_IN_STACK
430 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
432 #undef TARGET_FUNCTION_VALUE
433 #define TARGET_FUNCTION_VALUE arc_function_value
435 #undef TARGET_SCHED_ADJUST_PRIORITY
436 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
438 #undef TARGET_VECTOR_MODE_SUPPORTED_P
439 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
441 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
442 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
444 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
445 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
447 #undef TARGET_CAN_USE_DOLOOP_P
448 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
450 #undef TARGET_INVALID_WITHIN_DOLOOP
451 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
453 #undef TARGET_PRESERVE_RELOAD_P
454 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
456 #undef TARGET_CAN_FOLLOW_JUMP
457 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
459 #undef TARGET_DELEGITIMIZE_ADDRESS
460 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
462 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
463 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
464 arc_use_by_pieces_infrastructure_p
466 /* Usually, we will be able to scale anchor offsets.
467 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
468 #undef TARGET_MIN_ANCHOR_OFFSET
469 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
470 #undef TARGET_MAX_ANCHOR_OFFSET
471 #define TARGET_MAX_ANCHOR_OFFSET (1020)
473 #undef TARGET_SECONDARY_RELOAD
474 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
476 #define TARGET_OPTION_OVERRIDE arc_override_options
478 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
480 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
482 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
484 #define TARGET_CAN_ELIMINATE arc_can_eliminate
486 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
488 #define TARGET_FUNCTION_ARG arc_function_arg
490 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
492 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
494 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
496 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
498 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
500 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
502 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
504 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
505 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
506 arc_no_speculation_in_delay_slots_p
509 #define TARGET_LRA_P arc_lra_p
510 #define TARGET_REGISTER_PRIORITY arc_register_priority
511 /* Stores with scaled offsets have different displacement ranges. */
512 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
513 #define TARGET_SPILL_CLASS arc_spill_class
515 #include "target-def.h"
517 #undef TARGET_ASM_ALIGNED_HI_OP
518 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
519 #undef TARGET_ASM_ALIGNED_SI_OP
520 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
523 #undef TARGET_HAVE_TLS
524 #define TARGET_HAVE_TLS HAVE_AS_TLS
527 #undef TARGET_DWARF_REGISTER_SPAN
528 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
530 /* Try to keep the (mov:DF _, reg) as early as possible so
531 that the d<add/sub/mul>h-lr insns appear together and can
532 use the peephole2 pattern. */
535 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
537 rtx set
= single_set (insn
);
539 && GET_MODE (SET_SRC(set
)) == DFmode
540 && GET_CODE (SET_SRC(set
)) == REG
)
542 /* Incrementing priority by 20 (empirically derived). */
543 return priority
+ 20;
549 /* For ARC base register + offset addressing, the validity of the
550 address is mode-dependent for most of the offset range, as the
551 offset can be scaled by the access size.
552 We don't expose these as mode-dependent addresses in the
553 mode_dependent_address_p target hook, because that would disable
554 lots of optimizations, and most uses of these addresses are for 32
555 or 64 bit accesses anyways, which are fine.
556 However, that leaves some addresses for 8 / 16 bit values not
557 properly reloaded by the generic code, which is why we have to
558 schedule secondary reloads for these. */
561 arc_secondary_reload (bool in_p
,
565 secondary_reload_info
*sri
)
567 enum rtx_code code
= GET_CODE (x
);
569 if (cl
== DOUBLE_REGS
)
572 /* The loop counter register can be stored, but not loaded directly. */
573 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
574 && in_p
&& MEM_P (x
))
577 /* If we have a subreg (reg), where reg is a pseudo (that will end in
578 a memory location), then we may need a scratch register to handle
579 the fp/sp+largeoffset address. */
587 int regno
= REGNO (x
);
588 if (regno
>= FIRST_PSEUDO_REGISTER
)
589 regno
= reg_renumber
[regno
];
594 /* It is a pseudo that ends in a stack location. */
595 if (reg_equiv_mem (REGNO (x
)))
597 /* Get the equivalent address and check the range of the
599 rtx mem
= reg_equiv_mem (REGNO (x
));
600 addr
= find_replacement (&XEXP (mem
, 0));
605 gcc_assert (MEM_P (x
));
607 addr
= simplify_rtx (addr
);
609 if (addr
&& GET_CODE (addr
) == PLUS
610 && CONST_INT_P (XEXP (addr
, 1))
611 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
617 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
621 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
631 /* Convert reloads using offsets that are too large to use indirect
635 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
639 gcc_assert (GET_CODE (mem
) == MEM
);
640 addr
= XEXP (mem
, 0);
642 /* Large offset: use a move. FIXME: ld ops accepts limms as
643 offsets. Hence, the following move insn is not required. */
644 emit_move_insn (scratch
, addr
);
645 mem
= replace_equiv_address_nv (mem
, scratch
);
647 /* Now create the move. */
649 emit_insn (gen_rtx_SET (mem
, reg
));
651 emit_insn (gen_rtx_SET (reg
, mem
));
656 static unsigned arc_ifcvt (void);
660 const pass_data pass_data_arc_ifcvt
=
663 "arc_ifcvt", /* name */
664 OPTGROUP_NONE
, /* optinfo_flags */
665 TV_IFCVT2
, /* tv_id */
666 0, /* properties_required */
667 0, /* properties_provided */
668 0, /* properties_destroyed */
669 0, /* todo_flags_start */
670 TODO_df_finish
/* todo_flags_finish */
673 class pass_arc_ifcvt
: public rtl_opt_pass
676 pass_arc_ifcvt(gcc::context
*ctxt
)
677 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
680 /* opt_pass methods: */
681 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
682 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
688 make_pass_arc_ifcvt (gcc::context
*ctxt
)
690 return new pass_arc_ifcvt (ctxt
);
693 static unsigned arc_predicate_delay_insns (void);
697 const pass_data pass_data_arc_predicate_delay_insns
=
700 "arc_predicate_delay_insns", /* name */
701 OPTGROUP_NONE
, /* optinfo_flags */
702 TV_IFCVT2
, /* tv_id */
703 0, /* properties_required */
704 0, /* properties_provided */
705 0, /* properties_destroyed */
706 0, /* todo_flags_start */
707 TODO_df_finish
/* todo_flags_finish */
710 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
713 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
714 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
717 /* opt_pass methods: */
718 virtual unsigned int execute (function
*)
720 return arc_predicate_delay_insns ();
727 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
729 return new pass_arc_predicate_delay_insns (ctxt
);
732 /* Called by OVERRIDE_OPTIONS to initialize various things. */
739 /* I have the multiplier, then use it*/
740 if (TARGET_MPYW
|| TARGET_MULTI
)
741 arc_multcost
= COSTS_N_INSNS (1);
743 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
744 if (arc_multcost
< 0)
747 case TUNE_ARC700_4_2_STD
:
749 max throughput (1 multiply + 4 other insns) / 5 cycles. */
750 arc_multcost
= COSTS_N_INSNS (4);
751 if (TARGET_NOMPY_SET
)
752 arc_multcost
= COSTS_N_INSNS (30);
754 case TUNE_ARC700_4_2_XMAC
:
756 max throughput (1 multiply + 2 other insns) / 3 cycles. */
757 arc_multcost
= COSTS_N_INSNS (3);
758 if (TARGET_NOMPY_SET
)
759 arc_multcost
= COSTS_N_INSNS (30);
762 if (TARGET_MUL64_SET
)
764 arc_multcost
= COSTS_N_INSNS (4);
769 arc_multcost
= COSTS_N_INSNS (30);
773 /* MPY instructions valid only for ARC700 or ARCv2. */
774 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
775 error ("-mno-mpy supported only for ARC700 or ARCv2");
777 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
778 error ("-mno-dpfp-lrsr supported only with -mdpfp");
780 /* FPX-1. No fast and compact together. */
781 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
782 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
783 error ("FPX fast and compact options cannot be specified together");
785 /* FPX-2. No fast-spfp for arc600 or arc601. */
786 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
787 error ("-mspfp_fast not available on ARC600 or ARC601");
789 /* FPX-4. No FPX extensions mixed with FPU extensions. */
790 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
791 && TARGET_HARD_FLOAT
)
792 error ("No FPX/FPU mixing allowed");
794 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
795 if (flag_pic
&& TARGET_ARC600_FAMILY
)
798 "PIC is not supported for %s. Generating non-PIC code only..",
803 arc_init_reg_tables ();
805 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
806 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
807 arc_punct_chars
['#'] = 1;
808 arc_punct_chars
['*'] = 1;
809 arc_punct_chars
['?'] = 1;
810 arc_punct_chars
['!'] = 1;
811 arc_punct_chars
['^'] = 1;
812 arc_punct_chars
['&'] = 1;
813 arc_punct_chars
['+'] = 1;
814 arc_punct_chars
['_'] = 1;
816 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
818 /* There are two target-independent ifcvt passes, and arc_reorg may do
819 one or more arc_ifcvt calls. */
820 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
821 struct register_pass_info arc_ifcvt4_info
822 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
823 struct register_pass_info arc_ifcvt5_info
824 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
826 register_pass (&arc_ifcvt4_info
);
827 register_pass (&arc_ifcvt5_info
);
830 if (flag_delayed_branch
)
832 opt_pass
*pass_arc_predicate_delay_insns
833 = make_pass_arc_predicate_delay_insns (g
);
834 struct register_pass_info arc_predicate_delay_info
835 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
837 register_pass (&arc_predicate_delay_info
);
841 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
842 register range is specified as two registers separated by a dash.
843 It always starts with r0, and its upper limit is fp register.
844 blink and lp_count registers are optional. */
847 irq_range (const char *cstr
)
849 int i
, first
, last
, blink
, lpcount
, xreg
;
850 char *str
, *dash
, *comma
;
853 str
= (char *) alloca (i
+ 1);
854 memcpy (str
, cstr
, i
+ 1);
858 dash
= strchr (str
, '-');
861 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
866 comma
= strchr (dash
+ 1, ',');
870 first
= decode_reg_name (str
);
873 warning (0, "first register must be R0");
877 /* At this moment we do not have the register names initialized
879 if (!strcmp (dash
+ 1, "ilink"))
882 last
= decode_reg_name (dash
+ 1);
886 warning (0, "unknown register name: %s", dash
+ 1);
892 warning (0, "last register name %s must be an odd register", dash
+ 1);
900 warning (0, "%s-%s is an empty range", str
, dash
+ 1);
909 comma
= strchr (str
, ',');
913 xreg
= decode_reg_name (str
);
925 warning (0, "unknown register name: %s", str
);
930 irq_ctrl_saved
.irq_save_last_reg
= last
;
931 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
932 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
935 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
939 parse_mrgf_banked_regs_option (const char *arg
)
945 val
= strtol (arg
, &end_ptr
, 10);
946 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
947 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
949 error ("invalid number in -mrgf-banked-regs=%s "
950 "valid values are 0, 4, 8, 16, or 32", arg
);
953 rgf_banked_register_count
= (int) val
;
956 /* Check ARC options, generate derived target attributes. */
959 arc_override_options (void)
962 cl_deferred_option
*opt
;
963 vec
<cl_deferred_option
> *vopt
964 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
966 if (arc_cpu
== PROCESSOR_NONE
)
967 arc_cpu
= TARGET_CPU_DEFAULT
;
969 /* Set the default cpu options. */
970 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
972 /* Set the architectures. */
973 switch (arc_selected_cpu
->arch_info
->arch_id
)
976 arc_cpu_string
= "EM";
979 arc_cpu_string
= "HS";
982 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
983 arc_cpu_string
= "NPS400";
985 arc_cpu_string
= "ARC700";
988 arc_cpu_string
= "ARC600";
994 irq_ctrl_saved
.irq_save_last_reg
= -1;
995 irq_ctrl_saved
.irq_save_blink
= false;
996 irq_ctrl_saved
.irq_save_lpcount
= false;
998 rgf_banked_register_count
= 0;
1000 /* Handle the deferred options. */
1002 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1004 switch (opt
->opt_index
)
1006 case OPT_mirq_ctrl_saved_
:
1008 irq_range (opt
->arg
);
1010 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1013 case OPT_mrgf_banked_regs_
:
1015 parse_mrgf_banked_regs_option (opt
->arg
);
1017 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1025 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1026 specific flags are set in arc-common.c. The architecture forces
1027 the default hardware configurations in, regardless what command
1028 line options are saying. The CPU optional hw options can be
1029 turned on or off. */
1030 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1032 if ((arc_selected_cpu->flags & CODE) \
1033 && ((target_flags_explicit & MASK) == 0)) \
1034 target_flags |= MASK; \
1035 if (arc_selected_cpu->arch_info->dflags & CODE) \
1036 target_flags |= MASK; \
1038 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1040 if ((arc_selected_cpu->flags & CODE) \
1041 && (VAR == DEFAULT_##VAR)) \
1043 if (arc_selected_cpu->arch_info->dflags & CODE) \
1047 #include "arc-options.def"
1052 /* Check options against architecture options. Throw an error if
1053 option is not allowed. */
1054 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1057 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1059 error ("%s is not available for %s architecture", \
1060 DOC, arc_selected_cpu->arch_info->name); \
1063 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1065 if ((target_flags & MASK) \
1066 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1067 error ("%s is not available for %s architecture", \
1068 DOC, arc_selected_cpu->arch_info->name); \
1071 #include "arc-options.def"
1076 /* Set Tune option. */
1077 if (arc_tune
== TUNE_NONE
)
1078 arc_tune
= (enum attr_tune
) arc_selected_cpu
->tune
;
1080 if (arc_size_opt_level
== 3)
1083 /* Compact casesi is not a valid option for ARCv2 family. */
1086 if (TARGET_COMPACT_CASESI
)
1088 warning (0, "compact-casesi is not applicable to ARCv2");
1089 TARGET_COMPACT_CASESI
= 0;
1092 else if (optimize_size
== 1
1093 && !global_options_set
.x_TARGET_COMPACT_CASESI
)
1094 TARGET_COMPACT_CASESI
= 1;
1097 target_flags
|= MASK_NO_SDATA_SET
;
1099 if (flag_no_common
== 255)
1100 flag_no_common
= !TARGET_NO_SDATA_SET
;
1102 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1103 if (TARGET_MIXED_CODE
)
1105 if (!TARGET_Q_CLASS
)
1106 TARGET_COMPACT_CASESI
= 0;
1107 if (TARGET_COMPACT_CASESI
)
1108 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
1110 /* These need to be done at start up. It's convenient to do them here. */
1114 /* The condition codes of the ARC, and the inverse function. */
1115 /* For short branches, the "c" / "nc" names are not defined in the ARC
1116 Programmers manual, so we have to use "lo" / "hs"" instead. */
1117 static const char *arc_condition_codes
[] =
1119 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1120 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1123 enum arc_cc_code_index
1125 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1126 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1127 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1128 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1131 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1133 /* Returns the index of the ARC condition code string in
1134 `arc_condition_codes'. COMPARISON should be an rtx like
1135 `(eq (...) (...))'. */
1138 get_arc_condition_code (rtx comparison
)
1140 switch (GET_MODE (XEXP (comparison
, 0)))
1143 case SImode
: /* For BRcc. */
1144 switch (GET_CODE (comparison
))
1146 case EQ
: return ARC_CC_EQ
;
1147 case NE
: return ARC_CC_NE
;
1148 case GT
: return ARC_CC_GT
;
1149 case LE
: return ARC_CC_LE
;
1150 case GE
: return ARC_CC_GE
;
1151 case LT
: return ARC_CC_LT
;
1152 case GTU
: return ARC_CC_HI
;
1153 case LEU
: return ARC_CC_LS
;
1154 case LTU
: return ARC_CC_LO
;
1155 case GEU
: return ARC_CC_HS
;
1156 default : gcc_unreachable ();
1159 switch (GET_CODE (comparison
))
1161 case EQ
: return ARC_CC_EQ
;
1162 case NE
: return ARC_CC_NE
;
1163 case GE
: return ARC_CC_P
;
1164 case LT
: return ARC_CC_N
;
1165 case GT
: return ARC_CC_PNZ
;
1166 default : gcc_unreachable ();
1169 switch (GET_CODE (comparison
))
1171 case EQ
: return ARC_CC_EQ
;
1172 case NE
: return ARC_CC_NE
;
1173 default : gcc_unreachable ();
1176 switch (GET_CODE (comparison
))
1178 case LTU
: return ARC_CC_C
;
1179 case GEU
: return ARC_CC_NC
;
1180 default : gcc_unreachable ();
1183 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1184 switch (GET_CODE (comparison
))
1186 case GT
: return ARC_CC_N
;
1187 case UNLE
: return ARC_CC_P
;
1188 default : gcc_unreachable ();
1191 switch (GET_CODE (comparison
))
1193 case GT
: return ARC_CC_HI
;
1194 case UNLE
: return ARC_CC_LS
;
1195 default : gcc_unreachable ();
1198 /* Same for FPX and non-FPX. */
1199 switch (GET_CODE (comparison
))
1201 case GE
: return ARC_CC_HS
;
1202 case UNLT
: return ARC_CC_LO
;
1203 default : gcc_unreachable ();
1205 case CC_FP_UNEQmode
:
1206 switch (GET_CODE (comparison
))
1208 case UNEQ
: return ARC_CC_EQ
;
1209 case LTGT
: return ARC_CC_NE
;
1210 default : gcc_unreachable ();
1213 switch (GET_CODE (comparison
))
1215 case UNORDERED
: return ARC_CC_C
;
1216 case ORDERED
: return ARC_CC_NC
;
1217 default : gcc_unreachable ();
1220 switch (GET_CODE (comparison
))
1222 case EQ
: return ARC_CC_EQ
;
1223 case NE
: return ARC_CC_NE
;
1224 case UNORDERED
: return ARC_CC_C
;
1225 case ORDERED
: return ARC_CC_NC
;
1226 case LTGT
: return ARC_CC_HI
;
1227 case UNEQ
: return ARC_CC_LS
;
1228 default : gcc_unreachable ();
1231 switch (GET_CODE (comparison
))
1233 case EQ
: return ARC_CC_EQ
;
1234 case NE
: return ARC_CC_NE
;
1235 case GT
: return ARC_CC_GT
;
1236 case GE
: return ARC_CC_GE
;
1237 case LT
: return ARC_CC_C
;
1238 case LE
: return ARC_CC_LS
;
1239 case UNORDERED
: return ARC_CC_V
;
1240 case ORDERED
: return ARC_CC_NV
;
1241 case UNGT
: return ARC_CC_HI
;
1242 case UNGE
: return ARC_CC_HS
;
1243 case UNLT
: return ARC_CC_LT
;
1244 case UNLE
: return ARC_CC_LE
;
1245 /* UNEQ and LTGT do not have representation. */
1246 case LTGT
: /* Fall through. */
1247 case UNEQ
: /* Fall through. */
1248 default : gcc_unreachable ();
1250 case CC_FPU_UNEQmode
:
1251 switch (GET_CODE (comparison
))
1253 case LTGT
: return ARC_CC_NE
;
1254 case UNEQ
: return ARC_CC_EQ
;
1255 default : gcc_unreachable ();
1257 default : gcc_unreachable ();
1263 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1266 arc_short_comparison_p (rtx comparison
, int offset
)
1268 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1269 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1270 switch (get_arc_condition_code (comparison
))
1272 case ARC_CC_EQ
: case ARC_CC_NE
:
1273 return offset
>= -512 && offset
<= 506;
1274 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1275 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1276 return offset
>= -64 && offset
<= 58;
1282 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1283 return the mode to be used for the comparison. */
1286 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1288 machine_mode mode
= GET_MODE (x
);
1291 /* For an operation that sets the condition codes as a side-effect, the
1292 C and V flags is not set as for cmp, so we can only use comparisons where
1293 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1295 /* ??? We could use "pnz" for greater than zero, however, we could then
1296 get into trouble because the comparison could not be reversed. */
1297 if (GET_MODE_CLASS (mode
) == MODE_INT
1299 && (op
== EQ
|| op
== NE
1300 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1303 /* add.f for if (a+b) */
1305 && GET_CODE (y
) == NEG
1306 && (op
== EQ
|| op
== NE
))
1309 /* Check if this is a test suitable for bxor.f . */
1310 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1311 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1315 /* Check if this is a test suitable for add / bmsk.f . */
1316 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1317 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1318 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1319 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1320 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1323 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1324 && GET_CODE (x
) == PLUS
1325 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1328 if (TARGET_ARGONAUT_SET
1329 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1332 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1334 case LT
: case UNGE
: case GT
: case UNLE
:
1335 return CC_FP_GTmode
;
1336 case LE
: case UNGT
: case GE
: case UNLT
:
1337 return CC_FP_GEmode
;
1338 default: gcc_unreachable ();
1340 else if (TARGET_HARD_FLOAT
1341 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1342 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1361 return CC_FPU_UNEQmode
;
1366 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1370 case EQ
: case NE
: return CC_Zmode
;
1372 case GT
: case UNLE
: return CC_FP_GTmode
;
1374 case GE
: case UNLT
: return CC_FP_GEmode
;
1375 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1376 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1377 default: gcc_unreachable ();
1383 /* Vectors to keep interesting information about registers where it can easily
1384 be got. We use to use the actual mode value as the bit number, but there
1385 is (or may be) more than 32 modes now. Instead we use two tables: one
1386 indexed by hard register number, and one indexed by mode. */
1388 /* The purpose of arc_mode_class is to shrink the range of modes so that
1389 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1390 mapped into one arc_mode_class mode. */
1392 enum arc_mode_class
{
1394 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1395 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1399 /* Modes for condition codes. */
1400 #define C_MODES (1 << (int) C_MODE)
1402 /* Modes for single-word and smaller quantities. */
1403 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1405 /* Modes for double-word and smaller quantities. */
1406 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1408 /* Mode for 8-byte DF values only. */
1409 #define DF_MODES (1 << DF_MODE)
1411 /* Modes for quad-word and smaller quantities. */
1412 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1414 /* Modes for 128-bit vectors. */
1415 #define V_MODES (1 << (int) V_MODE)
1417 /* Value is 1 if register/mode pair is acceptable on arc. */
1419 unsigned int arc_hard_regno_mode_ok
[] = {
1420 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1421 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1422 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1423 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1425 /* ??? Leave these as S_MODES for now. */
1426 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1427 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1428 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1429 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1431 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1432 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1433 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1434 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1436 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1437 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1438 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1439 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1441 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1442 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1445 unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1447 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1450 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1452 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1453 return GENERAL_REGS
;
1457 /* Initialize the arc_mode_class array. */
1460 arc_init_reg_tables (void)
1464 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1466 machine_mode m
= (machine_mode
) i
;
1468 switch (GET_MODE_CLASS (m
))
1471 case MODE_PARTIAL_INT
:
1472 case MODE_COMPLEX_INT
:
1473 if (GET_MODE_SIZE (m
) <= 4)
1474 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1475 else if (GET_MODE_SIZE (m
) == 8)
1476 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1477 else if (GET_MODE_SIZE (m
) == 16)
1478 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1479 else if (GET_MODE_SIZE (m
) == 32)
1480 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1482 arc_mode_class
[i
] = 0;
1485 case MODE_COMPLEX_FLOAT
:
1486 if (GET_MODE_SIZE (m
) <= 4)
1487 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1488 else if (GET_MODE_SIZE (m
) == 8)
1489 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1490 else if (GET_MODE_SIZE (m
) == 16)
1491 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1492 else if (GET_MODE_SIZE (m
) == 32)
1493 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1495 arc_mode_class
[i
] = 0;
1497 case MODE_VECTOR_INT
:
1498 if (GET_MODE_SIZE (m
) == 4)
1499 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1500 else if (GET_MODE_SIZE (m
) == 8)
1501 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1503 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1507 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1508 we must explicitly check for them here. */
1509 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1510 || i
== (int) CC_Cmode
1511 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1512 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1513 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1515 arc_mode_class
[i
] = 0;
1521 /* Core registers 56..59 are used for multiply extension options.
1522 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1523 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1524 number depends on endianness.
1525 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1526 Because mlo / mhi form a 64 bit value, we use different gcc internal
1527 register numbers to make them form a register pair as the gcc internals
1528 know it. mmid gets number 57, if still available, and mlo / mhi get
1529 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1530 to map this back. */
1531 char rname56
[5] = "r56";
1532 char rname57
[5] = "r57";
1533 char rname58
[5] = "r58";
1534 char rname59
[5] = "r59";
1535 char rname29
[7] = "ilink1";
1536 char rname30
[7] = "ilink2";
1539 arc_conditional_register_usage (void)
1543 int fix_start
= 60, fix_end
= 55;
1547 /* For ARCv2 the core register set is changed. */
1548 strcpy (rname29
, "ilink");
1549 strcpy (rname30
, "r30");
1550 call_used_regs
[30] = 1;
1553 arc_regno_reg_class
[30] = WRITABLE_CORE_REGS
;
1554 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], 30);
1555 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], 30);
1556 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], 30);
1557 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], 30);
1560 if (TARGET_MUL64_SET
)
1565 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1566 you are supposed to refer to it as mlo & mhi, e.g
1567 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1568 In an actual asm instruction, you are of course use mmed.
1569 The point of avoiding having a separate register for mmed is that
1570 this way, we don't have to carry clobbers of that reg around in every
1571 isntruction that modifies mlo and/or mhi. */
1572 strcpy (rname57
, "");
1573 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1574 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1577 /* The nature of arc_tp_regno is actually something more like a global
1578 register, however globalize_reg requires a declaration.
1579 We use EPILOGUE_USES to compensate so that sets from
1580 __builtin_set_frame_pointer are not deleted. */
1581 if (arc_tp_regno
!= -1)
1582 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1584 if (TARGET_MULMAC_32BY16_SET
)
1587 fix_end
= fix_end
> 57 ? fix_end
: 57;
1588 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1589 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1591 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1593 if (!fixed_regs
[regno
])
1594 warning (0, "multiply option implies r%d is fixed", regno
);
1595 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1601 reg_alloc_order
[0] = 0;
1602 reg_alloc_order
[1] = 1;
1603 reg_alloc_order
[2] = 2;
1604 reg_alloc_order
[3] = 3;
1605 reg_alloc_order
[4] = 12;
1606 reg_alloc_order
[5] = 13;
1607 reg_alloc_order
[6] = 14;
1608 reg_alloc_order
[7] = 15;
1609 reg_alloc_order
[8] = 4;
1610 reg_alloc_order
[9] = 5;
1611 reg_alloc_order
[10] = 6;
1612 reg_alloc_order
[11] = 7;
1613 reg_alloc_order
[12] = 8;
1614 reg_alloc_order
[13] = 9;
1615 reg_alloc_order
[14] = 10;
1616 reg_alloc_order
[15] = 11;
1620 reg_alloc_order
[2] = 12;
1621 reg_alloc_order
[3] = 13;
1622 reg_alloc_order
[4] = 14;
1623 reg_alloc_order
[5] = 15;
1624 reg_alloc_order
[6] = 1;
1625 reg_alloc_order
[7] = 0;
1626 reg_alloc_order
[8] = 4;
1627 reg_alloc_order
[9] = 5;
1628 reg_alloc_order
[10] = 6;
1629 reg_alloc_order
[11] = 7;
1630 reg_alloc_order
[12] = 8;
1631 reg_alloc_order
[13] = 9;
1632 reg_alloc_order
[14] = 10;
1633 reg_alloc_order
[15] = 11;
1636 if (TARGET_SIMD_SET
)
1639 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1640 reg_alloc_order
[i
] = i
;
1641 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1642 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1643 reg_alloc_order
[i
] = i
;
1645 /* For ARC600, lp_count may not be read in an instruction
1646 following immediately after another one setting it to a new value.
1647 There was some discussion on how to enforce scheduling constraints for
1648 processors with missing interlocks on the gcc mailing list:
1649 http://gcc.gnu.org/ml/gcc/2008-05/msg00021.html .
1650 However, we can't actually use this approach, because for ARC the
1651 delay slot scheduling pass is active, which runs after
1652 machine_dependent_reorg. */
1654 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1655 else if (!TARGET_LP_WR_INTERLOCK
)
1656 fixed_regs
[LP_COUNT
] = 1;
1657 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1658 if (!call_used_regs
[regno
])
1659 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1660 for (regno
= 32; regno
< 60; regno
++)
1661 if (!fixed_regs
[regno
])
1662 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1663 if (!TARGET_ARC600_FAMILY
)
1665 for (regno
= 32; regno
<= 60; regno
++)
1666 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1668 /* If they have used -ffixed-lp_count, make sure it takes
1670 if (fixed_regs
[LP_COUNT
])
1672 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1673 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1674 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1676 /* Instead of taking out SF_MODE like below, forbid it outright. */
1677 arc_hard_regno_mode_ok
[60] = 0;
1680 arc_hard_regno_mode_ok
[60] = 1 << (int) S_MODE
;
1683 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1687 for (regno
= 1; regno
< 32; regno
+=2)
1689 arc_hard_regno_mode_ok
[regno
] = S_MODES
;
1693 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1697 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1698 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1699 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1701 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1704 arc_regno_reg_class
[i
]
1706 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1707 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1708 : (((!TARGET_ARC600_FAMILY
)
1709 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1710 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1712 arc_regno_reg_class
[i
] = NO_REGS
;
1715 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1716 has not been activated. */
1717 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1718 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1719 if (!TARGET_Q_CLASS
)
1720 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1722 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1724 /* Handle Special Registers. */
1725 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1727 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1728 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1729 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1730 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1731 arc_regno_reg_class
[62] = GENERAL_REGS
;
1735 for (i
= 40; i
< 44; ++i
)
1737 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1739 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1740 no attempt is made to use such a register as a destination
1741 operand in *movdf_insn. */
1742 if (!TARGET_ARGONAUT_SET
)
1744 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1745 interpreted to mean they can use D1 or D2 in their insn. */
1746 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1747 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1748 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1749 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1755 /* Disable all DOUBLE_REGISTER settings,
1756 if not generating DPFP code. */
1757 arc_regno_reg_class
[40] = ALL_REGS
;
1758 arc_regno_reg_class
[41] = ALL_REGS
;
1759 arc_regno_reg_class
[42] = ALL_REGS
;
1760 arc_regno_reg_class
[43] = ALL_REGS
;
1767 arc_hard_regno_mode_ok
[40] = 0;
1768 arc_hard_regno_mode_ok
[42] = 0;
1770 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1773 if (TARGET_SIMD_SET
)
1775 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1776 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1778 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1779 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1781 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1782 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1783 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1784 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1786 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1787 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1788 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1792 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
1794 /*ARCV2 Accumulator. */
1796 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1797 || TARGET_PLUS_DMPY
)
1799 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
1800 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
1801 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
1802 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
1803 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
1804 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
1805 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCL_REGNO
);
1806 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCH_REGNO
);
1807 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCL_REGNO
);
1808 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCH_REGNO
);
1810 /* Allow the compiler to freely use them. */
1811 fixed_regs
[ACCL_REGNO
] = 0;
1812 fixed_regs
[ACCH_REGNO
] = 0;
1814 arc_hard_regno_mode_ok
[ACC_REG_FIRST
] = D_MODES
;
1818 /* Handle an "interrupt" attribute; arguments as in
1819 struct attribute_spec.handler. */
1822 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
1827 tree value
= TREE_VALUE (args
);
1829 if (TREE_CODE (value
) != STRING_CST
)
1831 warning (OPT_Wattributes
,
1832 "argument of %qE attribute is not a string constant",
1834 *no_add_attrs
= true;
1837 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
1838 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
1840 warning (OPT_Wattributes
,
1841 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1843 *no_add_attrs
= true;
1846 && strcmp (TREE_STRING_POINTER (value
), "ilink")
1847 && strcmp (TREE_STRING_POINTER (value
), "firq"))
1849 warning (OPT_Wattributes
,
1850 "argument of %qE attribute is not \"ilink\" or \"firq\"",
1852 *no_add_attrs
= true;
1858 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1859 and two if they are nearly compatible (which causes a warning to be
1863 arc_comp_type_attributes (const_tree type1
,
1866 int l1
, l2
, m1
, m2
, s1
, s2
;
1868 /* Check for mismatch of non-default calling convention. */
1869 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
1872 /* Check for mismatched call attributes. */
1873 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1874 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1875 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1876 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1877 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1878 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1880 /* Only bother to check if an attribute is defined. */
1881 if (l1
| l2
| m1
| m2
| s1
| s2
)
1883 /* If one type has an attribute, the other must have the same attribute. */
1884 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
1887 /* Disallow mixed attributes. */
1888 if (l1
+ m1
+ s1
> 1)
1896 /* Set the default attributes for TYPE. */
1899 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED
)
1904 /* Misc. utilities. */
1906 /* X and Y are two things to compare using CODE. Emit the compare insn and
1907 return the rtx for the cc reg in the proper mode. */
1910 gen_compare_reg (rtx comparison
, machine_mode omode
)
1912 enum rtx_code code
= GET_CODE (comparison
);
1913 rtx x
= XEXP (comparison
, 0);
1914 rtx y
= XEXP (comparison
, 1);
1916 machine_mode mode
, cmode
;
1919 cmode
= GET_MODE (x
);
1920 if (cmode
== VOIDmode
)
1921 cmode
= GET_MODE (y
);
1922 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
1923 if (cmode
== SImode
)
1925 if (!register_operand (x
, SImode
))
1927 if (register_operand (y
, SImode
))
1932 code
= swap_condition (code
);
1935 x
= copy_to_mode_reg (SImode
, x
);
1937 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
1938 y
= copy_to_mode_reg (SImode
, y
);
1942 x
= force_reg (cmode
, x
);
1943 y
= force_reg (cmode
, y
);
1945 mode
= SELECT_CC_MODE (code
, x
, y
);
1947 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
1949 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
1950 cmpdfpx_raw, is not a correct comparison for floats:
1951 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1953 if (TARGET_ARGONAUT_SET
1954 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
1958 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
1959 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1961 case GT
: case UNLE
: case GE
: case UNLT
:
1962 code
= swap_condition (code
);
1970 if (cmode
== SFmode
)
1972 emit_insn (gen_cmpsfpx_raw (x
, y
));
1976 /* Accepts Dx regs directly by insns. */
1977 emit_insn (gen_cmpdfpx_raw (x
, y
));
1980 if (mode
!= CC_FPXmode
)
1981 emit_insn (gen_rtx_SET (cc_reg
,
1982 gen_rtx_COMPARE (mode
,
1983 gen_rtx_REG (CC_FPXmode
, 61),
1986 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
1990 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
1991 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1993 case LT
: case UNGE
: case LE
: case UNGT
:
1994 code
= swap_condition (code
);
2003 emit_insn (gen_cmp_quark (cc_reg
,
2004 gen_rtx_COMPARE (mode
, x
, y
)));
2006 else if (TARGET_HARD_FLOAT
2007 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2008 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2009 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2010 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2012 rtx op0
= gen_rtx_REG (cmode
, 0);
2013 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2018 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2019 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2021 case LT
: case UNGE
: case LE
: case UNGT
:
2022 code
= swap_condition (code
);
2028 if (currently_expanding_to_rtl
)
2036 emit_move_insn (op0
, x
);
2037 emit_move_insn (op1
, y
);
2041 gcc_assert (rtx_equal_p (op0
, x
));
2042 gcc_assert (rtx_equal_p (op1
, y
));
2049 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2052 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2053 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2056 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2057 We assume the value can be either signed or unsigned. */
2060 arc_double_limm_p (rtx value
)
2062 HOST_WIDE_INT low
, high
;
2064 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2069 low
= CONST_DOUBLE_LOW (value
);
2070 high
= CONST_DOUBLE_HIGH (value
);
2072 if (low
& 0x80000000)
2074 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2075 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2076 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2081 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2085 /* Do any needed setup for a variadic function. For the ARC, we must
2086 create a register parameter block, and then copy any anonymous arguments
2087 in registers to memory.
2089 CUM has not been updated for the last named argument which has type TYPE
2090 and mode MODE, and we rely on this fact. */
2093 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2094 machine_mode mode
, tree type
,
2095 int *pretend_size
, int no_rtl
)
2098 CUMULATIVE_ARGS next_cum
;
2100 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2102 next_cum
= *get_cumulative_args (args_so_far
);
2103 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2105 first_anon_arg
= next_cum
;
2107 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2109 /* First anonymous (unnamed) argument is in a reg. */
2111 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2112 int first_reg_offset
= first_anon_arg
;
2117 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2118 FIRST_PARM_OFFSET (0)));
2119 move_block_from_reg (first_reg_offset
, regblock
,
2120 MAX_ARC_PARM_REGS
- first_reg_offset
);
2124 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2128 /* Cost functions. */
2130 /* Provide the costs of an addressing mode that contains ADDR.
2131 If ADDR is not a valid address, its cost is irrelevant. */
2134 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2136 switch (GET_CODE (addr
))
2139 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2140 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2141 case PRE_MODIFY
: case POST_MODIFY
:
2147 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2149 /* Most likely needs a LIMM. */
2150 return COSTS_N_INSNS (1);
2154 register rtx plus0
= XEXP (addr
, 0);
2155 register rtx plus1
= XEXP (addr
, 1);
2157 if (GET_CODE (plus0
) != REG
2158 && (GET_CODE (plus0
) != MULT
2159 || !CONST_INT_P (XEXP (plus0
, 1))
2160 || (INTVAL (XEXP (plus0
, 1)) != 2
2161 && INTVAL (XEXP (plus0
, 1)) != 4)))
2164 switch (GET_CODE (plus1
))
2167 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2171 : (satisfies_constraint_Rcq (plus0
)
2172 && satisfies_constraint_O (plus1
))
2176 return (speed
< 1 ? 0
2177 : (satisfies_constraint_Rcq (plus0
)
2178 && satisfies_constraint_Rcq (plus1
))
2183 return COSTS_N_INSNS (1);
2196 /* Emit instruction X with the frame related bit set. */
2202 RTX_FRAME_RELATED_P (x
) = 1;
2206 /* Emit a frame insn to move SRC to DST. */
2209 frame_move (rtx dst
, rtx src
)
2211 rtx tmp
= gen_rtx_SET (dst
, src
);
2212 RTX_FRAME_RELATED_P (tmp
) = 1;
2213 return frame_insn (tmp
);
2216 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2217 auto increment address, or is zero. */
2220 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2222 rtx insn
= frame_move (dst
, src
);
2225 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2226 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2227 add_reg_note (insn
, REG_INC
, reg
);
2231 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2234 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2236 gcc_assert ((offset
& 0x3) == 0);
2239 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2242 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2245 frame_stack_add (HOST_WIDE_INT offset
)
2247 return frame_add (stack_pointer_rtx
, offset
);
2250 /* Traditionally, we push saved registers first in the prologue,
2251 then we allocate the rest of the frame - and reverse in the epilogue.
2252 This has still its merits for ease of debugging, or saving code size
2253 or even execution time if the stack frame is so large that some accesses
2254 can't be encoded anymore with offsets in the instruction code when using
2256 Also, it would be a good starting point if we got instructions to help
2257 with register save/restore.
2259 However, often stack frames are small, and the pushing / popping has
2261 - the stack modification prevents a lot of scheduling.
2262 - frame allocation / deallocation needs extra instructions.
2263 - unless we know that we compile ARC700 user code, we need to put
2264 a memory barrier after frame allocation / before deallocation to
2265 prevent interrupts clobbering our data in the frame.
2266 In particular, we don't have any such guarantees for library functions,
2267 which tend to, on the other hand, to have small frames.
2269 Thus, for small frames, we'd like to use a different scheme:
2270 - The frame is allocated in full with the first prologue instruction,
2271 and deallocated in full with the last epilogue instruction.
2272 Thus, the instructions in-betwen can be freely scheduled.
2273 - If the function has no outgoing arguments on the stack, we can allocate
2274 one register save slot at the top of the stack. This register can then
2275 be saved simultanously with frame allocation, and restored with
2277 This register can be picked depending on scheduling considerations,
2278 although same though should go into having some set of registers
2279 to be potentially lingering after a call, and others to be available
2280 immediately - i.e. in the absence of interprocedual optimization, we
2281 can use an ABI-like convention for register allocation to reduce
2282 stalls after function return. */
2283 /* Function prologue/epilogue handlers. */
2285 /* ARCompact stack frames look like:
2287 Before call After call
2288 high +-----------------------+ +-----------------------+
2289 mem | reg parm save area | | reg parm save area |
2290 | only created for | | only created for |
2291 | variable arg fns | | variable arg fns |
2292 AP +-----------------------+ +-----------------------+
2293 | return addr register | | return addr register |
2294 | (if required) | | (if required) |
2295 +-----------------------+ +-----------------------+
2297 | reg save area | | reg save area |
2299 +-----------------------+ +-----------------------+
2300 | frame pointer | | frame pointer |
2301 | (if required) | | (if required) |
2302 FP +-----------------------+ +-----------------------+
2304 | local/temp variables | | local/temp variables |
2306 +-----------------------+ +-----------------------+
2308 | arguments on stack | | arguments on stack |
2310 SP +-----------------------+ +-----------------------+
2311 | reg parm save area |
2312 | only created for |
2313 | variable arg fns |
2314 AP +-----------------------+
2315 | return addr register |
2317 +-----------------------+
2321 +-----------------------+
2324 FP +-----------------------+
2326 | local/temp variables |
2328 +-----------------------+
2330 | arguments on stack |
2332 mem SP +-----------------------+
2335 1) The "reg parm save area" does not exist for non variable argument fns.
2336 The "reg parm save area" can be eliminated completely if we created our
2337 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2339 /* Structure to be filled in by arc_compute_frame_size with register
2340 save masks, and offsets for the current function. */
2341 struct GTY (()) arc_frame_info
2343 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2344 unsigned int extra_size
; /* # bytes of extra stuff. */
2345 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2346 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2347 unsigned int reg_size
; /* # bytes needed to store regs. */
2348 unsigned int var_size
; /* # bytes that variables take up. */
2349 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2350 unsigned int gmask
; /* Mask of saved gp registers. */
2351 int initialized
; /* Nonzero if frame size already calculated. */
2352 short millicode_start_reg
;
2353 short millicode_end_reg
;
2354 bool save_return_addr
;
2357 /* Defining data structures for per-function information. */
2359 typedef struct GTY (()) machine_function
2361 enum arc_function_type fn_type
;
2362 struct arc_frame_info frame_info
;
2363 /* To keep track of unalignment caused by short insns. */
2365 int force_short_suffix
; /* Used when disgorging return delay slot insns. */
2366 const char *size_reason
;
2367 struct arc_ccfsm ccfsm_current
;
2368 /* Map from uid to ccfsm state during branch shortening. */
2369 rtx ccfsm_current_insn
;
2370 char arc_reorg_started
;
2371 char prescan_initialized
;
2374 /* Type of function DECL.
2376 The result is cached. To reset the cache at the end of a function,
2377 call with DECL = NULL_TREE. */
2379 enum arc_function_type
2380 arc_compute_function_type (struct function
*fun
)
2382 tree decl
= fun
->decl
;
2384 enum arc_function_type fn_type
= fun
->machine
->fn_type
;
2386 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2389 /* Assume we have a normal function (not an interrupt handler). */
2390 fn_type
= ARC_FUNCTION_NORMAL
;
2392 /* Now see if this is an interrupt handler. */
2393 for (a
= DECL_ATTRIBUTES (decl
);
2397 tree name
= TREE_PURPOSE (a
), args
= TREE_VALUE (a
);
2399 if (name
== get_identifier ("interrupt")
2400 && list_length (args
) == 1
2401 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
)
2403 tree value
= TREE_VALUE (args
);
2405 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2406 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2407 fn_type
= ARC_FUNCTION_ILINK1
;
2408 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2409 fn_type
= ARC_FUNCTION_ILINK2
;
2410 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2411 fn_type
= ARC_FUNCTION_FIRQ
;
2418 return fun
->machine
->fn_type
= fn_type
;
2421 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2422 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2424 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2425 The return address and frame pointer are treated separately.
2426 Don't consider them here.
2427 Addition for pic: The gp register needs to be saved if the current
2428 function changes it to access gotoff variables.
2429 FIXME: This will not be needed if we used some arbitrary register
2434 arc_must_save_register (int regno
, struct function
*func
)
2436 enum arc_function_type fn_type
= arc_compute_function_type (func
);
2437 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2438 && ARC_AUTO_IRQ_P (fn_type
));
2439 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2441 switch (rgf_banked_register_count
)
2444 firq_auto_save_p
&= (regno
< 4);
2447 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2450 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2451 || ((regno
> 25) && (regno
< 29))
2452 || ((regno
> 29) && (regno
< 32)));
2455 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2458 firq_auto_save_p
= false;
2462 if ((regno
) != RETURN_ADDR_REGNUM
2463 && (regno
) != FRAME_POINTER_REGNUM
2464 && df_regs_ever_live_p (regno
)
2465 && (!call_used_regs
[regno
]
2466 || ARC_INTERRUPT_P (fn_type
))
2467 /* Do not emit code for auto saved regs. */
2469 && !firq_auto_save_p
)
2472 if (flag_pic
&& crtl
->uses_pic_offset_table
2473 && regno
== PIC_OFFSET_TABLE_REGNUM
)
2479 /* Return true if the return address must be saved in the current function,
2480 otherwise return false. */
2483 arc_must_save_return_addr (struct function
*func
)
2485 if (func
->machine
->frame_info
.save_return_addr
)
2491 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2492 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2493 Register Allocator) pass, while we want to get the frame size
2494 correct earlier than the IRA pass. */
2496 arc_frame_pointer_needed (void)
2498 return (frame_pointer_needed
);
2502 /* Return non-zero if there are registers to be saved or loaded using
2503 millicode thunks. We can only use consecutive sequences starting
2504 with r13, and not going beyond r25.
2505 GMASK is a bitmask of registers to save. This function sets
2506 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2507 of registers to be saved / restored with a millicode call. */
2510 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2511 struct arc_frame_info
*frame
)
2515 int start_reg
= 13, end_reg
= 25;
2517 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2519 end_reg
= regno
- 1;
2520 /* There is no point in using millicode thunks if we don't save/restore
2521 at least three registers. For non-leaf functions we also have the
2523 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2525 frame
->millicode_start_reg
= 13;
2526 frame
->millicode_end_reg
= regno
- 1;
2532 /* Return the bytes needed to compute the frame pointer from the current
2535 SIZE is the size needed for local variables. */
2538 arc_compute_frame_size (int size
) /* size = # of var. bytes allocated. */
2541 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2542 unsigned int reg_size
, reg_offset
;
2544 struct arc_frame_info
*frame_info
= &cfun
->machine
->frame_info
;
2546 size
= ARC_STACK_ALIGN (size
);
2548 /* 1) Size of locals and temporaries */
2551 /* 2) Size of outgoing arguments */
2552 args_size
= crtl
->outgoing_args_size
;
2554 /* 3) Calculate space needed for saved registers.
2555 ??? We ignore the extension registers for now. */
2557 /* See if this is an interrupt handler. Call used registers must be saved
2563 for (regno
= 0; regno
<= 31; regno
++)
2565 if (arc_must_save_register (regno
, cfun
))
2567 reg_size
+= UNITS_PER_WORD
;
2568 gmask
|= 1L << regno
;
2572 /* 4) Space for back trace data structure.
2573 <return addr reg size> (if required) + <fp size> (if required). */
2574 frame_info
->save_return_addr
2575 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
));
2576 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2577 if (optimize_size
&& !TARGET_NO_MILLICODE_THUNK_SET
)
2579 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2580 frame_info
->save_return_addr
= true;
2584 if (arc_must_save_return_addr (cfun
))
2586 if (arc_frame_pointer_needed ())
2589 /* 5) Space for variable arguments passed in registers */
2590 pretend_size
= crtl
->args
.pretend_args_size
;
2592 /* Ensure everything before the locals is aligned appropriately. */
2594 unsigned int extra_plus_reg_size
;
2595 unsigned int extra_plus_reg_size_aligned
;
2597 extra_plus_reg_size
= extra_size
+ reg_size
;
2598 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2599 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2602 /* Compute total frame size. */
2603 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2605 total_size
= ARC_STACK_ALIGN (total_size
);
2607 /* Compute offset of register save area from stack pointer:
2608 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2610 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2611 + (arc_frame_pointer_needed () ? 4 : 0));
2613 /* Save computed information. */
2614 frame_info
->total_size
= total_size
;
2615 frame_info
->extra_size
= extra_size
;
2616 frame_info
->pretend_size
= pretend_size
;
2617 frame_info
->var_size
= var_size
;
2618 frame_info
->args_size
= args_size
;
2619 frame_info
->reg_size
= reg_size
;
2620 frame_info
->reg_offset
= reg_offset
;
2621 frame_info
->gmask
= gmask
;
2622 frame_info
->initialized
= reload_completed
;
2624 /* Ok, we're done. */
2628 /* Common code to save/restore registers. */
2629 /* BASE_REG is the base register to use for addressing and to adjust.
2630 GMASK is a bitmask of general purpose registers to save/restore.
2631 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2632 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2633 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2637 arc_save_restore (rtx base_reg
,
2638 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2640 unsigned int offset
= 0;
2642 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2643 rtx sibthunk_insn
= NULL_RTX
;
2647 /* Millicode thunks implementation:
2648 Generates calls to millicodes for registers starting from r13 to r25
2649 Present Limitations:
2650 - Only one range supported. The remaining regs will have the ordinary
2651 st and ld instructions for store and loads. Hence a gmask asking
2652 to store r13-14, r16-r25 will only generate calls to store and
2653 load r13 to r14 while store and load insns will be generated for
2654 r16 to r25 in the prologue and epilogue respectively.
2656 - Presently library only supports register ranges starting from r13.
2658 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2660 int start_call
= frame
->millicode_start_reg
;
2661 int end_call
= frame
->millicode_end_reg
;
2662 int n_regs
= end_call
- start_call
+ 1;
2663 int i
= 0, r
, off
= 0;
2665 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2669 /* "reg_size" won't be more than 127 . */
2670 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
2671 frame_add (base_reg
, *first_offset
);
2674 insn
= gen_rtx_PARALLEL
2675 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
2676 if (epilogue_p
== 2)
2679 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
2680 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
2682 rtx reg
= gen_rtx_REG (SImode
, r
);
2684 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
2687 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
2689 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
2690 gmask
= gmask
& ~(1L << r
);
2692 if (epilogue_p
== 2)
2693 sibthunk_insn
= insn
;
2696 insn
= frame_insn (insn
);
2698 for (r
= start_call
; r
<= end_call
; r
++)
2700 rtx reg
= gen_rtx_REG (SImode
, r
);
2701 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2707 for (regno
= 0; regno
<= 31; regno
++)
2709 machine_mode mode
= SImode
;
2714 && ((gmask
& (1L << regno
)) != 0)
2715 && ((gmask
& (1L << (regno
+1))) != 0))
2720 else if ((gmask
& (1L << regno
)) != 0)
2728 rtx reg
= gen_rtx_REG (mode
, regno
);
2730 int cfa_adjust
= *first_offset
;
2734 gcc_assert (!offset
);
2735 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
2736 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
2741 gcc_assert (SMALL_INT (offset
));
2742 addr
= plus_constant (Pmode
, base_reg
, offset
);
2744 mem
= gen_frame_mem (mode
, addr
);
2748 frame_move_inc (reg
, mem
, base_reg
, addr
);
2749 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2752 enum reg_note note
= REG_CFA_ADJUST_CFA
;
2753 add_reg_note (insn
, note
,
2754 gen_rtx_SET (stack_pointer_rtx
,
2755 plus_constant (Pmode
,
2761 frame_move_inc (mem
, reg
, base_reg
, addr
);
2762 offset
+= UNITS_PER_WORD
;
2765 offset
+= UNITS_PER_WORD
;
2773 int start_call
= frame
->millicode_start_reg
;
2774 int end_call
= frame
->millicode_end_reg
;
2777 rtx r12
= gen_rtx_REG (Pmode
, 12);
2779 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
2780 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
2781 XVECEXP (sibthunk_insn
, 0, 1)
2782 = gen_rtx_SET (stack_pointer_rtx
,
2783 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
2784 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
2785 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
2787 /* Would be nice if we could do this earlier, when the PARALLEL
2788 is populated, but these need to be attached after the
2790 for (r
= start_call
; r
<= end_call
; r
++)
2792 rtx reg
= gen_rtx_REG (SImode
, r
);
2793 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
2796 } /* arc_save_restore */
2798 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2802 arc_dwarf_emit_irq_save_regs (void)
2804 rtx tmp
, par
, insn
, reg
;
2807 par
= gen_rtx_SEQUENCE (VOIDmode
,
2808 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2809 + irq_ctrl_saved
.irq_save_blink
2810 + irq_ctrl_saved
.irq_save_lpcount
2813 /* Build the stack adjustment note for unwind info. */
2815 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2816 + irq_ctrl_saved
.irq_save_blink
2817 + irq_ctrl_saved
.irq_save_lpcount
);
2818 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2819 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2820 RTX_FRAME_RELATED_P (tmp
) = 1;
2821 XVECEXP (par
, 0, j
++) = tmp
;
2823 offset
-= UNITS_PER_WORD
;
2825 /* 1st goes LP_COUNT. */
2826 if (irq_ctrl_saved
.irq_save_lpcount
)
2828 reg
= gen_rtx_REG (SImode
, 60);
2829 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2830 tmp
= gen_frame_mem (SImode
, tmp
);
2831 tmp
= gen_rtx_SET (tmp
, reg
);
2832 RTX_FRAME_RELATED_P (tmp
) = 1;
2833 XVECEXP (par
, 0, j
++) = tmp
;
2834 offset
-= UNITS_PER_WORD
;
2837 /* 2nd goes BLINK. */
2838 if (irq_ctrl_saved
.irq_save_blink
)
2840 reg
= gen_rtx_REG (SImode
, 31);
2841 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2842 tmp
= gen_frame_mem (SImode
, tmp
);
2843 tmp
= gen_rtx_SET (tmp
, reg
);
2844 RTX_FRAME_RELATED_P (tmp
) = 1;
2845 XVECEXP (par
, 0, j
++) = tmp
;
2846 offset
-= UNITS_PER_WORD
;
2849 /* Build the parallel of the remaining registers recorded as saved
2851 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
2853 reg
= gen_rtx_REG (SImode
, i
);
2854 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2855 tmp
= gen_frame_mem (SImode
, tmp
);
2856 tmp
= gen_rtx_SET (tmp
, reg
);
2857 RTX_FRAME_RELATED_P (tmp
) = 1;
2858 XVECEXP (par
, 0, j
++) = tmp
;
2859 offset
-= UNITS_PER_WORD
;
2862 /* Dummy insn used to anchor the dwarf info. */
2863 insn
= emit_insn (gen_stack_irq_dwarf());
2864 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
2865 RTX_FRAME_RELATED_P (insn
) = 1;
2868 /* Set up the stack and frame pointer (if desired) for the function. */
2871 arc_expand_prologue (void)
2873 int size
= get_frame_size ();
2874 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
2875 /* unsigned int frame_pointer_offset;*/
2876 unsigned int frame_size_to_allocate
;
2877 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2878 Change the stack layout so that we rather store a high register with the
2879 PRE_MODIFY, thus enabling more short insn generation.) */
2880 int first_offset
= 0;
2881 enum arc_function_type fn_type
= arc_compute_function_type (cfun
);
2883 size
= ARC_STACK_ALIGN (size
);
2885 /* Compute/get total frame size. */
2886 size
= (!cfun
->machine
->frame_info
.initialized
2887 ? arc_compute_frame_size (size
)
2888 : cfun
->machine
->frame_info
.total_size
);
2890 if (flag_stack_usage_info
)
2891 current_function_static_stack_size
= size
;
2893 /* Keep track of frame size to be allocated. */
2894 frame_size_to_allocate
= size
;
2896 /* These cases shouldn't happen. Catch them now. */
2897 gcc_assert (!(size
== 0 && gmask
));
2899 /* Allocate space for register arguments if this is a variadic function. */
2900 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
2902 /* Ensure pretend_size is maximum of 8 * word_size. */
2903 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
2905 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
2906 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
2909 /* IRQ using automatic save mechanism will save the register before
2911 if (ARC_AUTO_IRQ_P (fn_type
)
2912 && !ARC_FAST_INTERRUPT_P (fn_type
))
2914 arc_dwarf_emit_irq_save_regs ();
2917 /* The home-grown ABI says link register is saved first. */
2918 if (arc_must_save_return_addr (cfun
)
2919 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
2921 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
2922 rtx mem
= gen_frame_mem (Pmode
,
2923 gen_rtx_PRE_DEC (Pmode
,
2924 stack_pointer_rtx
));
2926 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
2927 frame_size_to_allocate
-= UNITS_PER_WORD
;
2930 /* Save any needed call-saved regs (and call-used if this is an
2931 interrupt handler) for ARCompact ISA. */
2932 if (cfun
->machine
->frame_info
.reg_size
)
2934 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
2935 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
2936 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
2937 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
2940 /* Save frame pointer if needed. First save the FP on stack, if not
2942 if (arc_frame_pointer_needed ()
2943 && !ARC_AUTOFP_IRQ_P (fn_type
))
2945 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
2946 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
2947 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
2950 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
2951 frame_size_to_allocate
-= UNITS_PER_WORD
;
2955 /* Emit mov fp,sp. */
2956 if (arc_frame_pointer_needed ())
2958 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
2961 /* ??? We don't handle the case where the saved regs are more than 252
2962 bytes away from sp. This can be handled by decrementing sp once, saving
2963 the regs, and then decrementing it again. The epilogue doesn't have this
2964 problem as the `ld' insn takes reg+limm values (though it would be more
2965 efficient to avoid reg+limm). */
2967 frame_size_to_allocate
-= first_offset
;
2968 /* Allocate the stack frame. */
2969 if (frame_size_to_allocate
> 0)
2971 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
2972 /* If the frame pointer is needed, emit a special barrier that
2973 will prevent the scheduler from moving stores to the frame
2974 before the stack adjustment. */
2975 if (arc_frame_pointer_needed ())
2976 emit_insn (gen_stack_tie (stack_pointer_rtx
,
2977 hard_frame_pointer_rtx
));
2980 /* Setup the gp register, if needed. */
2981 if (crtl
->uses_pic_offset_table
)
2982 arc_finalize_pic ();
2985 /* Do any necessary cleanup after a function to restore stack, frame,
2989 arc_expand_epilogue (int sibcall_p
)
2991 int size
= get_frame_size ();
2992 enum arc_function_type fn_type
= arc_compute_function_type (cfun
);
2994 size
= ARC_STACK_ALIGN (size
);
2995 size
= (!cfun
->machine
->frame_info
.initialized
2996 ? arc_compute_frame_size (size
)
2997 : cfun
->machine
->frame_info
.total_size
);
2999 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
3000 unsigned int frame_size
;
3001 unsigned int size_to_deallocate
;
3003 int can_trust_sp_p
= !cfun
->calls_alloca
;
3004 int first_offset
= 0;
3005 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
3008 size_to_deallocate
= size
;
3010 frame_size
= size
- (pretend_size
+
3011 cfun
->machine
->frame_info
.reg_size
+
3012 cfun
->machine
->frame_info
.extra_size
);
3014 /* ??? There are lots of optimizations that can be done here.
3015 EG: Use fp to restore regs if it's closer.
3016 Maybe in time we'll do them all. For now, always restore regs from
3017 sp, but don't restore sp if we don't have to. */
3019 if (!can_trust_sp_p
)
3020 gcc_assert (arc_frame_pointer_needed ());
3022 /* Restore stack pointer to the beginning of saved register area for
3026 if (arc_frame_pointer_needed ())
3027 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3029 first_offset
= frame_size
;
3030 size_to_deallocate
-= frame_size
;
3032 else if (!can_trust_sp_p
)
3033 frame_stack_add (-frame_size
);
3036 /* Restore any saved registers. */
3037 if (arc_frame_pointer_needed ()
3038 && !ARC_AUTOFP_IRQ_P (fn_type
))
3040 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
3042 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
3043 stack_pointer_rtx
, 0);
3044 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3045 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3046 plus_constant (SImode
, stack_pointer_rtx
,
3048 size_to_deallocate
-= UNITS_PER_WORD
;
3051 /* Load blink after the calls to thunk calls in case of optimize size. */
3054 int sibthunk_p
= (!sibcall_p
3055 && fn_type
== ARC_FUNCTION_NORMAL
3056 && !cfun
->machine
->frame_info
.pretend_size
);
3058 gcc_assert (!(cfun
->machine
->frame_info
.gmask
3059 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
3060 arc_save_restore (stack_pointer_rtx
,
3061 cfun
->machine
->frame_info
.gmask
,
3062 1 + sibthunk_p
, &first_offset
);
3066 /* If we are to restore registers, and first_offset would require
3067 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3068 fast add to the stack pointer, do this now. */
3069 if ((!SMALL_INT (first_offset
)
3070 && cfun
->machine
->frame_info
.gmask
3071 && ((TARGET_ARC700
&& !optimize_size
)
3072 ? first_offset
<= 0x800
3073 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
3074 /* Also do this if we have both gprs and return
3075 address to restore, and they both would need a LIMM. */
3076 || (arc_must_save_return_addr (cfun
)
3077 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
3078 && cfun
->machine
->frame_info
.gmask
))
3080 frame_stack_add (first_offset
);
3083 if (arc_must_save_return_addr (cfun
)
3084 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3086 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3087 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
3088 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
3089 HOST_WIDE_INT cfa_adjust
= 0;
3091 /* If the load of blink would need a LIMM, but we can add
3092 the offset quickly to sp, do the latter. */
3093 if (!SMALL_INT (ra_offs
>> 2)
3094 && !cfun
->machine
->frame_info
.gmask
3095 && ((TARGET_ARC700
&& !optimize_size
)
3097 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
3099 size_to_deallocate
-= ra_offs
- first_offset
;
3101 frame_stack_add (ra_offs
);
3103 addr
= stack_pointer_rtx
;
3105 /* See if we can combine the load of the return address with the
3106 final stack adjustment.
3107 We need a separate load if there are still registers to
3108 restore. We also want a separate load if the combined insn
3109 would need a limm, but a separate load doesn't. */
3111 && !cfun
->machine
->frame_info
.gmask
3112 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
3114 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
3115 cfa_adjust
= ra_offs
;
3117 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
3119 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
3121 addr
= gen_rtx_POST_INC (Pmode
, addr
);
3122 cfa_adjust
= GET_MODE_SIZE (Pmode
);
3123 size_to_deallocate
= 0;
3126 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
3127 stack_pointer_rtx
, addr
);
3130 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3132 add_reg_note (insn
, note
,
3133 gen_rtx_SET (stack_pointer_rtx
,
3134 plus_constant (SImode
, stack_pointer_rtx
,
3137 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
3142 if (cfun
->machine
->frame_info
.reg_size
)
3143 arc_save_restore (stack_pointer_rtx
,
3144 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3145 cfun
->machine
->frame_info
.gmask
3146 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
3149 /* The rest of this function does the following:
3150 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3153 /* Keep track of how much of the stack pointer we've restored.
3154 It makes the following a lot more readable. */
3155 size_to_deallocate
+= first_offset
;
3156 restored
= size
- size_to_deallocate
;
3158 if (size
> restored
)
3159 frame_stack_add (size
- restored
);
3161 /* Emit the return instruction. */
3162 if (sibcall_p
== FALSE
)
3163 emit_jump_insn (gen_simple_return ());
3166 /* Return the offset relative to the stack pointer where the return address
3167 is stored, or -1 if it is not stored. */
3170 arc_return_slot_offset ()
3172 struct arc_frame_info
*afi
= &cfun
->machine
->frame_info
;
3174 return (afi
->save_return_addr
3175 ? afi
->total_size
- afi
->pretend_size
- afi
->extra_size
: -1);
3180 /* Helper to generate unspec constant. */
3183 arc_unspec_offset (rtx loc
, int unspec
)
3185 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3189 /* Emit special PIC prologues and epilogues. */
3190 /* If the function has any GOTOFF relocations, then the GOTBASE
3191 register has to be setup in the prologue
3192 The instruction needed at the function start for setting up the
3195 ----------------------------------------------------------
3196 The rtl to be emitted for this should be:
3199 (const (unspec (symref _DYNAMIC) 3)))
3200 ---------------------------------------------------------- */
3203 arc_finalize_pic (void)
3206 rtx baseptr_rtx
= gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
);
3208 if (crtl
->uses_pic_offset_table
== 0)
3211 gcc_assert (flag_pic
!= 0);
3213 pat
= gen_rtx_SYMBOL_REF (Pmode
, "_DYNAMIC");
3214 pat
= arc_unspec_offset (pat
, ARC_UNSPEC_GOT
);
3215 pat
= gen_rtx_SET (baseptr_rtx
, pat
);
3220 /* !TARGET_BARREL_SHIFTER support. */
3221 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3225 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3227 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3229 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3230 (op0
, op1
, op2
, shift
));
3234 /* Output the assembler code for doing a shift.
3235 We go to a bit of trouble to generate efficient code as the ARC601 only has
3236 single bit shifts. This is taken from the h8300 port. We only have one
3237 mode of shifting and can't access individual bytes like the h8300 can, so
3238 this is greatly simplified (at the expense of not generating hyper-
3241 This function is not used if the variable shift insns are present. */
3243 /* FIXME: This probably can be done using a define_split in arc.md.
3244 Alternately, generate rtx rather than output instructions. */
3247 output_shift (rtx
*operands
)
3249 /* static int loopend_lab;*/
3250 rtx shift
= operands
[3];
3251 machine_mode mode
= GET_MODE (shift
);
3252 enum rtx_code code
= GET_CODE (shift
);
3253 const char *shift_one
;
3255 gcc_assert (mode
== SImode
);
3259 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3260 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3261 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3262 default: gcc_unreachable ();
3265 if (GET_CODE (operands
[2]) != CONST_INT
)
3267 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3274 n
= INTVAL (operands
[2]);
3276 /* Only consider the lower 5 bits of the shift count. */
3279 /* First see if we can do them inline. */
3280 /* ??? We could get better scheduling & shorter code (using short insns)
3281 by using splitters. Alas, that'd be even more verbose. */
3282 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3283 && dest_reg_operand (operands
[4], SImode
))
3285 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3286 for (n
-=3 ; n
>= 3; n
-= 3)
3287 output_asm_insn ("add3 %0,%4,%0", operands
);
3289 output_asm_insn ("add2 %0,%4,%0", operands
);
3291 output_asm_insn ("add %0,%0,%0", operands
);
3297 output_asm_insn (shift_one
, operands
);
3298 operands
[1] = operands
[0];
3301 /* See if we can use a rotate/and. */
3302 else if (n
== BITS_PER_WORD
- 1)
3307 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3310 /* The ARC doesn't have a rol insn. Use something else. */
3311 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
3314 /* The ARC doesn't have a rol insn. Use something else. */
3315 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
3321 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
3326 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
3329 #if 1 /* Need some scheduling comparisons. */
3330 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3331 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3333 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3334 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
3339 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3340 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3342 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3343 "and %0,%0,1\n\trlc %0,%0", operands
);
3350 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
3351 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3356 operands
[2] = GEN_INT (n
);
3357 output_asm_insn ("mov.f lp_count, %2", operands
);
3361 output_asm_insn ("lpnz\t2f", operands
);
3362 output_asm_insn (shift_one
, operands
);
3363 output_asm_insn ("nop", operands
);
3364 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
3373 /* Nested function support. */
3375 /* Directly store VALUE into memory object BLOCK at OFFSET. */
3378 emit_store_direct (rtx block
, int offset
, int value
)
3380 emit_insn (gen_store_direct (adjust_address (block
, SImode
, offset
),
3382 gen_int_mode (value
, SImode
))));
3385 /* Emit RTL insns to initialize the variable parts of a trampoline.
3386 FNADDR is an RTX for the address of the function's pure code.
3387 CXT is an RTX for the static chain value for the function. */
3388 /* With potentially multiple shared objects loaded, and multiple stacks
3389 present for multiple thereds where trampolines might reside, a simple
3390 range check will likely not suffice for the profiler to tell if a callee
3391 is a trampoline. We a speedier check by making the trampoline start at
3392 an address that is not 4-byte aligned.
3393 A trampoline looks like this:
3397 ld_s r12,[pcl,12] 0xd403
3398 ld r11,[pcl,12] 0x170c 700b
3402 The fastest trampoline to execute for trampolines within +-8KB of CTX
3405 j [limm] 0x20200f80 limm
3406 and that would also be faster to write to the stack by computing the offset
3407 from CTX to TRAMP at compile time. However, it would really be better to
3408 get rid of the high cost of cache invalidation when generating trampolines,
3409 which requires that the code part of trampolines stays constant, and
3411 - making sure that no executable code but trampolines is on the stack,
3412 no icache entries linger for the area of the stack from when before the
3413 stack was allocated, and allocating trampolines in trampoline-only
3416 - allocate trampolines fram a special pool of pre-allocated trampolines. */
3419 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
3421 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3423 emit_store_direct (tramp
, 0, TARGET_BIG_ENDIAN
? 0x78e0d403 : 0xd40378e0);
3424 emit_store_direct (tramp
, 4, TARGET_BIG_ENDIAN
? 0x170c700b : 0x700b170c);
3425 emit_store_direct (tramp
, 8, TARGET_BIG_ENDIAN
? 0x7c0078e0 : 0x78e07c00);
3426 emit_move_insn (adjust_address (tramp
, SImode
, 12), fnaddr
);
3427 emit_move_insn (adjust_address (tramp
, SImode
, 16), cxt
);
3428 emit_insn (gen_flush_icache (adjust_address (tramp
, SImode
, 0)));
3431 /* Allow the profiler to easily distinguish trampolines from normal
3435 arc_trampoline_adjust_address (rtx addr
)
3437 return plus_constant (Pmode
, addr
, 2);
3440 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3441 reset when we output the scaled address. */
3442 static int output_scaled
= 0;
3444 /* Print operand X (an rtx) in assembler syntax to file FILE.
3445 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3446 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3447 /* In final.c:output_asm_insn:
3450 'c' : constant address if CONSTANT_ADDRESS_P
3456 'p': bit Position of lsb
3457 's': size of bit field
3458 '#': condbranch delay slot suffix
3459 '*': jump delay slot suffix
3460 '?' : nonjump-insn suffix for conditional execution or short instruction
3461 '!' : jump / call suffix for conditional execution or short instruction
3462 '`': fold constant inside unary o-perator, re-recognize, and emit.
3467 'B': Branch comparison operand - suppress sda reference
3468 'H': Most significant word
3469 'L': Least significant word
3470 'A': ASCII decimal representation of floating point value
3471 'U': Load/store update or scaling indicator
3472 'V': cache bypass indicator for volatile
3477 'o': original symbol - no @ prepending. */
3480 arc_print_operand (FILE *file
, rtx x
, int code
)
3485 if (GET_CODE (x
) == CONST_INT
)
3486 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3488 output_operand_lossage ("invalid operand to %%Z code");
3493 if (GET_CODE (x
) == CONST_INT
)
3494 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3496 output_operand_lossage ("invalid operand to %%z code");
3501 if (GET_CODE (x
) == CONST_INT
)
3502 fprintf (file
, "%d", INTVAL (x
) );
3504 output_operand_lossage ("invalid operands to %%c code");
3509 if (GET_CODE (x
) == CONST_INT
)
3510 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3512 output_operand_lossage ("invalid operand to %%M code");
3517 if (GET_CODE (x
) == CONST_INT
)
3518 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3520 output_operand_lossage ("invalid operand to %%p code");
3524 if (GET_CODE (x
) == CONST_INT
)
3526 HOST_WIDE_INT i
= INTVAL (x
);
3527 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3528 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3531 output_operand_lossage ("invalid operand to %%s code");
3535 /* Conditional branches depending on condition codes.
3536 Note that this is only for branches that were known to depend on
3537 condition codes before delay slot scheduling;
3538 out-of-range brcc / bbit expansions should use '*'.
3539 This distinction is important because of the different
3540 allowable delay slot insns and the output of the delay suffix
3541 for TARGET_AT_DBR_COND_EXEC. */
3543 /* Unconditional branches / branches not depending on condition codes.
3544 This could also be a CALL_INSN.
3545 Output the appropriate delay slot suffix. */
3546 if (final_sequence
&& final_sequence
->len () != 1)
3548 rtx_insn
*jump
= final_sequence
->insn (0);
3549 rtx_insn
*delay
= final_sequence
->insn (1);
3551 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3552 if (delay
->deleted ())
3554 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3555 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3556 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3557 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3564 case '?' : /* with leading "." */
3565 case '!' : /* without leading "." */
3566 /* This insn can be conditionally executed. See if the ccfsm machinery
3567 says it should be conditionalized.
3568 If it shouldn't, we'll check the compact attribute if this insn
3569 has a short variant, which may be used depending on code size and
3570 alignment considerations. */
3571 if (current_insn_predicate
)
3572 arc_ccfsm_current
.cc
3573 = get_arc_condition_code (current_insn_predicate
);
3574 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3576 /* Is this insn in a delay slot sequence? */
3577 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3578 || current_insn_predicate
3579 || CALL_P (final_sequence
->insn (0))
3580 || simplejump_p (final_sequence
->insn (0)))
3582 /* This insn isn't in a delay slot sequence, or conditionalized
3583 independently of its position in a delay slot. */
3584 fprintf (file
, "%s%s",
3585 code
== '?' ? "." : "",
3586 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3587 /* If this is a jump, there are still short variants. However,
3588 only beq_s / bne_s have the same offset range as b_s,
3589 and the only short conditional returns are jeq_s and jne_s. */
3591 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3592 || arc_ccfsm_current
.cc
== ARC_CC_NE
3593 || 0 /* FIXME: check if branch in 7 bit range. */))
3594 output_short_suffix (file
);
3596 else if (code
== '!') /* Jump with delay slot. */
3597 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
3598 else /* An Instruction in a delay slot of a jump or call. */
3600 rtx jump
= XVECEXP (final_sequence
, 0, 0);
3601 rtx insn
= XVECEXP (final_sequence
, 0, 1);
3603 /* If the insn is annulled and is from the target path, we need
3604 to inverse the condition test. */
3605 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3607 if (INSN_FROM_TARGET_P (insn
))
3608 fprintf (file
, "%s%s",
3609 code
== '?' ? "." : "",
3610 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
3612 fprintf (file
, "%s%s",
3613 code
== '?' ? "." : "",
3614 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3615 if (arc_ccfsm_current
.state
== 5)
3616 arc_ccfsm_current
.state
= 0;
3619 /* This insn is executed for either path, so don't
3620 conditionalize it at all. */
3621 output_short_suffix (file
);
3626 output_short_suffix (file
);
3629 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3632 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
3635 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
3636 (get_arc_condition_code (x
))],
3640 /* Write second word of DImode or DFmode reference,
3641 register or memory. */
3642 if (GET_CODE (x
) == REG
)
3643 fputs (reg_names
[REGNO (x
)+1], file
);
3644 else if (GET_CODE (x
) == MEM
)
3648 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3649 PRE_MODIFY, we will have handled the first word already;
3650 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3651 first word will be done later. In either case, the access
3652 to the first word will do the modify, and we only have
3653 to add an offset of four here. */
3654 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
3655 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
3656 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
3657 || GET_CODE (XEXP (x
, 0)) == POST_INC
3658 || GET_CODE (XEXP (x
, 0)) == POST_DEC
3659 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
3660 output_address (VOIDmode
,
3661 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
3662 else if (output_scaled
)
3664 rtx addr
= XEXP (x
, 0);
3665 int size
= GET_MODE_SIZE (GET_MODE (x
));
3667 output_address (VOIDmode
,
3668 plus_constant (Pmode
, XEXP (addr
, 0),
3669 ((INTVAL (XEXP (addr
, 1)) + 4)
3670 >> (size
== 2 ? 1 : 2))));
3674 output_address (VOIDmode
,
3675 plus_constant (Pmode
, XEXP (x
, 0), 4));
3679 output_operand_lossage ("invalid operand to %%R code");
3682 /* FIXME: remove %S option. */
3684 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3687 output_addr_const (file
, x
);
3693 if (GET_CODE (x
) == REG
)
3695 /* L = least significant word, H = most significant word. */
3696 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
3697 fputs (reg_names
[REGNO (x
)], file
);
3699 fputs (reg_names
[REGNO (x
)+1], file
);
3701 else if (GET_CODE (x
) == CONST_INT
3702 || GET_CODE (x
) == CONST_DOUBLE
)
3704 rtx first
, second
, word
;
3706 split_double (x
, &first
, &second
);
3708 if((WORDS_BIG_ENDIAN
) == 0)
3709 word
= (code
== 'L' ? first
: second
);
3711 word
= (code
== 'L' ? second
: first
);
3713 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
3716 output_operand_lossage ("invalid operand to %%H/%%L code");
3722 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
3723 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
3725 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
3726 fprintf (file
, "%s", str
);
3730 /* Output a load/store with update indicator if appropriate. */
3731 if (GET_CODE (x
) == MEM
)
3733 rtx addr
= XEXP (x
, 0);
3734 switch (GET_CODE (addr
))
3736 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
3737 fputs (".a", file
); break;
3738 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
3739 fputs (".ab", file
); break;
3741 /* Are we using a scaled index? */
3742 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3743 fputs (".as", file
);
3744 /* Can we use a scaled offset? */
3745 else if (CONST_INT_P (XEXP (addr
, 1))
3746 && GET_MODE_SIZE (GET_MODE (x
)) > 1
3747 && (!(INTVAL (XEXP (addr
, 1))
3748 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
3749 /* Does it make a difference? */
3750 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
3751 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
3753 fputs (".as", file
);
3760 gcc_assert (CONSTANT_P (addr
)); break;
3764 output_operand_lossage ("invalid operand to %%U code");
3767 /* Output cache bypass indicator for a load/store insn. Volatile memory
3768 refs are defined to use the cache bypass mechanism. */
3769 if (GET_CODE (x
) == MEM
)
3771 if (MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
3772 fputs (".di", file
);
3775 output_operand_lossage ("invalid operand to %%V code");
3780 /* Do nothing special. */
3783 fputs (reg_names
[REGNO (x
)]+1, file
);
3786 /* This punctuation character is needed because label references are
3787 printed in the output template using %l. This is a front end
3788 character, and when we want to emit a '@' before it, we have to use
3794 /* Output an operator. */
3795 switch (GET_CODE (x
))
3797 case PLUS
: fputs ("add", file
); return;
3798 case SS_PLUS
: fputs ("adds", file
); return;
3799 case AND
: fputs ("and", file
); return;
3800 case IOR
: fputs ("or", file
); return;
3801 case XOR
: fputs ("xor", file
); return;
3802 case MINUS
: fputs ("sub", file
); return;
3803 case SS_MINUS
: fputs ("subs", file
); return;
3804 case ASHIFT
: fputs ("asl", file
); return;
3805 case ASHIFTRT
: fputs ("asr", file
); return;
3806 case LSHIFTRT
: fputs ("lsr", file
); return;
3807 case ROTATERT
: fputs ("ror", file
); return;
3808 case MULT
: fputs ("mpy", file
); return;
3809 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
3810 case NEG
: fputs ("neg", file
); return;
3811 case SS_NEG
: fputs ("negs", file
); return;
3812 case NOT
: fputs ("not", file
); return; /* Unconditional. */
3814 fputs ("ext", file
); /* bmsk allows predication. */
3816 case SIGN_EXTEND
: /* Unconditional. */
3817 fputs ("sex", file
);
3819 switch (GET_MODE (XEXP (x
, 0)))
3821 case QImode
: fputs ("b", file
); return;
3822 case HImode
: fputs ("w", file
); return;
3827 if (GET_MODE (x
) != HImode
)
3829 fputs ("sat16", file
);
3832 output_operand_lossage ("invalid operand to %%O code"); return;
3834 if (GET_CODE (x
) == SYMBOL_REF
)
3836 assemble_name (file
, XSTR (x
, 0));
3841 if (TARGET_ANNOTATE_ALIGN
&& cfun
->machine
->size_reason
)
3842 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
3858 output_operand_lossage ("invalid operand output code");
3861 switch (GET_CODE (x
))
3864 fputs (reg_names
[REGNO (x
)], file
);
3868 rtx addr
= XEXP (x
, 0);
3869 int size
= GET_MODE_SIZE (GET_MODE (x
));
3873 switch (GET_CODE (addr
))
3875 case PRE_INC
: case POST_INC
:
3876 output_address (VOIDmode
,
3877 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
3878 case PRE_DEC
: case POST_DEC
:
3879 output_address (VOIDmode
,
3880 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
3882 case PRE_MODIFY
: case POST_MODIFY
:
3883 output_address (VOIDmode
, XEXP (addr
, 1)); break;
3887 output_address (VOIDmode
,
3888 plus_constant (Pmode
, XEXP (addr
, 0),
3889 (INTVAL (XEXP (addr
, 1))
3890 >> (size
== 2 ? 1 : 2))));
3894 output_address (VOIDmode
, addr
);
3897 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
3898 arc_output_pic_addr_const (file
, addr
, code
);
3900 output_address (VOIDmode
, addr
);
3907 /* We handle SFmode constants here as output_addr_const doesn't. */
3908 if (GET_MODE (x
) == SFmode
)
3912 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
3913 fprintf (file
, "0x%08lx", l
);
3917 /* Let output_addr_const deal with it. */
3920 || (GET_CODE (x
) == CONST
3921 && GET_CODE (XEXP (x
, 0)) == UNSPEC
3922 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
3923 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
3924 || (GET_CODE (x
) == CONST
3925 && GET_CODE (XEXP (x
, 0)) == PLUS
3926 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
3927 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
3928 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
3929 arc_output_pic_addr_const (file
, x
, code
);
3932 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3933 with asm_output_symbol_ref */
3934 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
)
3937 output_addr_const (file
, XEXP (x
, 0));
3938 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (XEXP (x
, 0)))
3939 fprintf (file
, "@sda");
3941 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
3942 || INTVAL (XEXP (x
, 1)) >= 0)
3943 fprintf (file
, "+");
3944 output_addr_const (file
, XEXP (x
, 1));
3947 output_addr_const (file
, x
);
3949 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
3950 fprintf (file
, "@sda");
3955 /* Print a memory address as an operand to reference that memory location. */
3958 arc_print_operand_address (FILE *file
, rtx addr
)
3960 register rtx base
, index
= 0;
3962 switch (GET_CODE (addr
))
3965 fputs (reg_names
[REGNO (addr
)], file
);
3968 output_addr_const (file
, addr
);
3969 if (SYMBOL_REF_SMALL_P (addr
))
3970 fprintf (file
, "@sda");
3973 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3974 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
3975 else if (CONST_INT_P (XEXP (addr
, 0)))
3976 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
3978 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
3980 gcc_assert (OBJECT_P (base
));
3981 arc_print_operand_address (file
, base
);
3982 if (CONSTANT_P (base
) && CONST_INT_P (index
))
3986 gcc_assert (OBJECT_P (index
));
3987 arc_print_operand_address (file
, index
);
3991 rtx c
= XEXP (addr
, 0);
3993 if ((GET_CODE (c
) == UNSPEC
3994 && (XINT (c
, 1) == UNSPEC_TLS_OFF
3995 || XINT (c
, 1) == UNSPEC_TLS_IE
))
3996 || (GET_CODE (c
) == PLUS
3997 && GET_CODE (XEXP (c
, 0)) == UNSPEC
3998 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
3999 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4001 arc_output_pic_addr_const (file
, c
, 0);
4004 gcc_assert (GET_CODE (c
) == PLUS
);
4005 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4006 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4008 output_address (VOIDmode
, XEXP (addr
, 0));
4014 /* We shouldn't get here as we've lost the mode of the memory object
4015 (which says how much to inc/dec by. */
4020 arc_output_pic_addr_const (file
, addr
, 0);
4022 output_addr_const (file
, addr
);
4027 /* Conditional execution support.
4029 This is based on the ARM port but for now is much simpler.
4031 A finite state machine takes care of noticing whether or not instructions
4032 can be conditionally executed, and thus decrease execution time and code
4033 size by deleting branch instructions. The fsm is controlled by
4034 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4035 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4036 insns also have a hand in this. */
4037 /* The way we leave dealing with non-anulled or annull-false delay slot
4038 insns to the consumer is awkward. */
4040 /* The state of the fsm controlling condition codes are:
4041 0: normal, do nothing special
4042 1: don't output this insn
4043 2: don't output this insn
4044 3: make insns conditional
4045 4: make insns conditional
4046 5: make insn conditional (only for outputting anulled delay slot insns)
4048 special value for cfun->machine->uid_ccfsm_state:
4049 6: return with but one insn before it since function start / call
4051 State transitions (state->state by whom, under what condition):
4052 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4054 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4055 by zero or more non-jump insns and an unconditional branch with
4056 the same target label as the condbranch.
4057 1 -> 3 branch patterns, after having not output the conditional branch
4058 2 -> 4 branch patterns, after having not output the conditional branch
4059 0 -> 5 branch patterns, for anulled delay slot insn.
4060 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4061 (the target label has CODE_LABEL_NUMBER equal to
4062 arc_ccfsm_target_label).
4063 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4064 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4065 5 -> 0 when outputting the delay slot insn
4067 If the jump clobbers the conditions then we use states 2 and 4.
4069 A similar thing can be done with conditional return insns.
4071 We also handle separating branches from sets of the condition code.
4072 This is done here because knowledge of the ccfsm state is required,
4073 we may not be outputting the branch. */
4075 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4076 before letting final output INSN. */
4079 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4081 /* BODY will hold the body of INSN. */
4084 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4085 an if/then/else), and things need to be reversed. */
4088 /* If we start with a return insn, we only succeed if we find another one. */
4089 int seeking_return
= 0;
4091 /* START_INSN will hold the insn from where we start looking. This is the
4092 first insn after the following code_label if REVERSE is true. */
4093 rtx_insn
*start_insn
= insn
;
4095 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4096 since they don't rely on a cmp preceding the. */
4097 enum attr_type jump_insn_type
;
4099 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4100 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4101 final_scan_insn which has `optimize' as a local. */
4102 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4105 /* Ignore notes and labels. */
4108 body
= PATTERN (insn
);
4109 /* If in state 4, check if the target branch is reached, in order to
4110 change back to state 0. */
4111 if (state
->state
== 4)
4113 if (insn
== state
->target_insn
)
4115 state
->target_insn
= NULL
;
4121 /* If in state 3, it is possible to repeat the trick, if this insn is an
4122 unconditional branch to a label, and immediately following this branch
4123 is the previous target label which is only used once, and the label this
4124 branch jumps to is not too far off. Or in other words "we've done the
4125 `then' part, see if we can do the `else' part." */
4126 if (state
->state
== 3)
4128 if (simplejump_p (insn
))
4130 start_insn
= next_nonnote_insn (start_insn
);
4131 if (GET_CODE (start_insn
) == BARRIER
)
4133 /* ??? Isn't this always a barrier? */
4134 start_insn
= next_nonnote_insn (start_insn
);
4136 if (GET_CODE (start_insn
) == CODE_LABEL
4137 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4138 && LABEL_NUSES (start_insn
) == 1)
4143 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4145 start_insn
= next_nonnote_insn (start_insn
);
4146 if (GET_CODE (start_insn
) == BARRIER
)
4147 start_insn
= next_nonnote_insn (start_insn
);
4148 if (GET_CODE (start_insn
) == CODE_LABEL
4149 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4150 && LABEL_NUSES (start_insn
) == 1)
4162 if (GET_CODE (insn
) != JUMP_INSN
4163 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4164 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4167 /* We can't predicate BRCC or loop ends.
4168 Also, when generating PIC code, and considering a medium range call,
4169 we can't predicate the call. */
4170 jump_insn_type
= get_attr_type (insn
);
4171 if (jump_insn_type
== TYPE_BRCC
4172 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4173 || jump_insn_type
== TYPE_LOOP_END
4174 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4177 /* This jump might be paralleled with a clobber of the condition codes,
4178 the jump should always come first. */
4179 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4180 body
= XVECEXP (body
, 0, 0);
4183 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4184 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4186 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4187 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4188 int then_not_else
= TRUE
;
4189 /* Nonzero if next insn must be the target label. */
4190 int next_must_be_target_label_p
;
4191 rtx_insn
*this_insn
= start_insn
;
4194 /* Register the insn jumped to. */
4197 if (!seeking_return
)
4198 label
= XEXP (SET_SRC (body
), 0);
4200 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4201 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4202 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4204 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4205 then_not_else
= FALSE
;
4207 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4209 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4212 then_not_else
= FALSE
;
4217 /* If this is a non-annulled branch with a delay slot, there is
4218 no need to conditionalize the delay slot. */
4219 if (NEXT_INSN (PREV_INSN (insn
)) != insn
4220 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4222 this_insn
= NEXT_INSN (this_insn
);
4223 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn
)))
4224 == NEXT_INSN (this_insn
));
4226 /* See how many insns this branch skips, and what kind of insns. If all
4227 insns are okay, and the label or unconditional branch to the same
4228 label is not too far away, succeed. */
4229 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
4230 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
4235 this_insn
= next_nonnote_insn (this_insn
);
4239 if (next_must_be_target_label_p
)
4241 if (GET_CODE (this_insn
) == BARRIER
)
4243 if (GET_CODE (this_insn
) == CODE_LABEL
4244 && this_insn
== label
)
4254 switch (GET_CODE (this_insn
))
4257 /* Succeed if it is the target label, otherwise fail since
4258 control falls in from somewhere else. */
4259 if (this_insn
== label
)
4269 /* Succeed if the following insn is the target label.
4271 If return insns are used then the last insn in a function
4272 will be a barrier. */
4273 next_must_be_target_label_p
= TRUE
;
4277 /* Can handle a call insn if there are no insns after it.
4278 IE: The next "insn" is the target label. We don't have to
4279 worry about delay slots as such insns are SEQUENCE's inside
4280 INSN's. ??? It is possible to handle such insns though. */
4281 if (get_attr_cond (this_insn
) == COND_CANUSE
)
4282 next_must_be_target_label_p
= TRUE
;
4288 scanbody
= PATTERN (this_insn
);
4290 /* If this is an unconditional branch to the same label, succeed.
4291 If it is to another label, do nothing. If it is conditional,
4293 /* ??? Probably, the test for the SET and the PC are
4296 if (GET_CODE (scanbody
) == SET
4297 && GET_CODE (SET_DEST (scanbody
)) == PC
)
4299 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
4300 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
4305 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
4307 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
4310 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
4316 else if (GET_CODE (scanbody
) == PARALLEL
)
4318 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4324 scanbody
= PATTERN (this_insn
);
4326 /* We can only do this with insns that can use the condition
4327 codes (and don't set them). */
4328 if (GET_CODE (scanbody
) == SET
4329 || GET_CODE (scanbody
) == PARALLEL
)
4331 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4334 /* We can't handle other insns like sequences. */
4346 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
4347 state
->target_label
= CODE_LABEL_NUMBER (label
);
4348 else if (seeking_return
|| state
->state
== 2)
4350 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
4352 this_insn
= next_nonnote_insn (this_insn
);
4354 gcc_assert (!this_insn
||
4355 (GET_CODE (this_insn
) != BARRIER
4356 && GET_CODE (this_insn
) != CODE_LABEL
));
4360 /* Oh dear! we ran off the end, give up. */
4361 extract_insn_cached (insn
);
4363 state
->target_insn
= NULL
;
4366 state
->target_insn
= this_insn
;
4371 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4375 state
->cond
= XEXP (SET_SRC (body
), 0);
4376 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4379 if (reverse
|| then_not_else
)
4380 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4383 /* Restore recog_operand. Getting the attributes of other insns can
4384 destroy this array, but final.c assumes that it remains intact
4385 across this call; since the insn has been recognized already we
4386 call insn_extract direct. */
4387 extract_insn_cached (insn
);
4391 /* Record that we are currently outputting label NUM with prefix PREFIX.
4392 It it's the label we're looking for, reset the ccfsm machinery.
4394 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4397 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4399 if (state
->state
== 3 && state
->target_label
== num
4400 && !strcmp (prefix
, "L"))
4403 state
->target_insn
= NULL
;
4407 /* We are considering a conditional branch with the condition COND.
4408 Check if we want to conditionalize a delay slot insn, and if so modify
4409 the ccfsm state accordingly.
4410 REVERSE says branch will branch when the condition is false. */
4412 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4413 struct arc_ccfsm
*state
)
4415 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4417 state
= &arc_ccfsm_current
;
4419 gcc_assert (state
->state
== 0);
4420 if (seq_insn
!= jump
)
4422 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4424 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4425 && INSN_ANNULLED_BRANCH_P (jump
)
4426 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4429 state
->cc
= get_arc_condition_code (cond
);
4431 arc_ccfsm_current
.cc
4432 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4433 rtx pat
= PATTERN (insn
);
4434 if (GET_CODE (pat
) == COND_EXEC
)
4435 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4436 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4437 == get_arc_condition_code (XEXP (pat
, 0)));
4444 /* Update *STATE as we would when we emit INSN. */
4447 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4449 enum attr_type type
;
4452 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4453 else if (JUMP_P (insn
)
4454 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4455 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4456 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4457 || ((type
== TYPE_UNCOND_BRANCH
4458 || type
== TYPE_RETURN
)
4459 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4461 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4462 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4465 rtx src
= SET_SRC (PATTERN (insn
));
4466 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4470 else if (arc_ccfsm_current
.state
== 5)
4471 arc_ccfsm_current
.state
= 0;
4474 /* Return true if the current insn, which is a conditional branch, is to be
4478 arc_ccfsm_branch_deleted_p (void)
4480 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4483 /* Record a branch isn't output because subsequent insns can be
4487 arc_ccfsm_record_branch_deleted (void)
4489 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4492 /* During insn output, indicate if the current insn is predicated. */
4495 arc_ccfsm_cond_exec_p (void)
4497 return (cfun
->machine
->prescan_initialized
4498 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4501 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4502 and look inside SEQUENCEs. */
4505 arc_next_active_insn (rtx_insn
*insn
, struct arc_ccfsm
*statep
)
4512 arc_ccfsm_post_advance (insn
, statep
);
4513 insn
= NEXT_INSN (insn
);
4514 if (!insn
|| BARRIER_P (insn
))
4517 arc_ccfsm_advance (insn
, statep
);
4519 while (NOTE_P (insn
)
4520 || (cfun
->machine
->arc_reorg_started
4521 && LABEL_P (insn
) && !label_to_alignment (insn
))
4522 || (NONJUMP_INSN_P (insn
)
4523 && (GET_CODE (PATTERN (insn
)) == USE
4524 || GET_CODE (PATTERN (insn
)) == CLOBBER
)));
4525 if (!LABEL_P (insn
))
4527 gcc_assert (INSN_P (insn
));
4528 pat
= PATTERN (insn
);
4529 if (GET_CODE (pat
) == ADDR_VEC
|| GET_CODE (pat
) == ADDR_DIFF_VEC
)
4531 if (GET_CODE (pat
) == SEQUENCE
)
4532 return as_a
<rtx_insn
*> (XVECEXP (pat
, 0, 0));
4537 /* When deciding if an insn should be output short, we want to know something
4538 about the following insns:
4539 - if another insn follows which we know we can output as a short insn
4540 before an alignment-sensitive point, we can output this insn short:
4541 the decision about the eventual alignment can be postponed.
4542 - if a to-be-aligned label comes next, we should output this insn such
4543 as to get / preserve 4-byte alignment.
4544 - if a likely branch without delay slot insn, or a call with an immediately
4545 following short insn comes next, we should out output this insn such as to
4546 get / preserve 2 mod 4 unalignment.
4547 - do the same for a not completely unlikely branch with a short insn
4548 following before any other branch / label.
4549 - in order to decide if we are actually looking at a branch, we need to
4550 call arc_ccfsm_advance.
4551 - in order to decide if we are looking at a short insn, we should know
4552 if it is conditionalized. To a first order of approximation this is
4553 the case if the state from arc_ccfsm_advance from before this insn
4554 indicates the insn is conditionalized. However, a further refinement
4555 could be to not conditionalize an insn if the destination register(s)
4556 is/are dead in the non-executed case. */
4557 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4558 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4559 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4562 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4564 enum attr_iscompact iscompact
;
4565 struct machine_function
*machine
;
4569 iscompact
= get_attr_iscompact (insn
);
4570 if (iscompact
== ISCOMPACT_FALSE
)
4573 machine
= cfun
->machine
;
4575 if (machine
->force_short_suffix
>= 0)
4576 return machine
->force_short_suffix
;
4578 return (get_attr_length (insn
) & 2) != 0;
4581 /* When outputting an instruction (alternative) that can potentially be short,
4582 output the short suffix if the insn is in fact short, and update
4583 cfun->machine->unalign accordingly. */
4586 output_short_suffix (FILE *file
)
4588 rtx_insn
*insn
= current_output_insn
;
4590 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
4592 fprintf (file
, "_s");
4593 cfun
->machine
->unalign
^= 2;
4595 /* Restore recog_operand. */
4596 extract_insn_cached (insn
);
4599 /* Implement FINAL_PRESCAN_INSN. */
4602 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
4603 int noperands ATTRIBUTE_UNUSED
)
4605 if (TARGET_DUMPISIZE
)
4606 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
4608 /* Output a nop if necessary to prevent a hazard.
4609 Don't do this for delay slots: inserting a nop would
4610 alter semantics, and the only time we would find a hazard is for a
4611 call function result - and in that case, the hazard is spurious to
4613 if (PREV_INSN (insn
)
4614 && PREV_INSN (NEXT_INSN (insn
)) == insn
4615 && arc_hazard (prev_real_insn (insn
), insn
))
4617 current_output_insn
=
4618 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn
)));
4619 final_scan_insn (current_output_insn
, asm_out_file
, optimize
, 1, NULL
);
4620 current_output_insn
= insn
;
4622 /* Restore extraction data which might have been clobbered by arc_hazard. */
4623 extract_constrain_insn_cached (insn
);
4625 if (!cfun
->machine
->prescan_initialized
)
4627 /* Clear lingering state from branch shortening. */
4628 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
4629 cfun
->machine
->prescan_initialized
= 1;
4631 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
4633 cfun
->machine
->size_reason
= 0;
4636 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4637 Frame pointer elimination is automatically handled.
4639 All eliminations are permissible. If we need a frame
4640 pointer, we must eliminate ARG_POINTER_REGNUM into
4641 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4644 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4646 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
4649 /* Define the offset between two registers, one to be eliminated, and
4650 the other its replacement, at the start of a routine. */
4653 arc_initial_elimination_offset (int from
, int to
)
4655 if (! cfun
->machine
->frame_info
.initialized
)
4656 arc_compute_frame_size (get_frame_size ());
4658 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
4660 return (cfun
->machine
->frame_info
.extra_size
4661 + cfun
->machine
->frame_info
.reg_size
);
4664 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
4666 return (cfun
->machine
->frame_info
.total_size
4667 - cfun
->machine
->frame_info
.pretend_size
);
4670 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
4672 return (cfun
->machine
->frame_info
.total_size
4673 - (cfun
->machine
->frame_info
.pretend_size
4674 + cfun
->machine
->frame_info
.extra_size
4675 + cfun
->machine
->frame_info
.reg_size
));
4682 arc_frame_pointer_required (void)
4684 return cfun
->calls_alloca
;
4688 /* Return the destination address of a branch. */
4691 branch_dest (rtx branch
)
4693 rtx pat
= PATTERN (branch
);
4694 rtx dest
= (GET_CODE (pat
) == PARALLEL
4695 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
4698 if (GET_CODE (dest
) == IF_THEN_ELSE
)
4699 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
4701 dest
= XEXP (dest
, 0);
4702 dest_uid
= INSN_UID (dest
);
4704 return INSN_ADDRESSES (dest_uid
);
4708 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4711 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
4713 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4714 This clears machine specific flags, so has to come first. */
4715 default_encode_section_info (decl
, rtl
, first
);
4717 /* Check if it is a function, and whether it has the
4718 [long/medium/short]_call attribute specified. */
4719 if (TREE_CODE (decl
) == FUNCTION_DECL
)
4721 rtx symbol
= XEXP (rtl
, 0);
4722 int flags
= SYMBOL_REF_FLAGS (symbol
);
4724 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4725 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
4726 tree long_call_attr
= lookup_attribute ("long_call", attr
);
4727 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
4728 tree short_call_attr
= lookup_attribute ("short_call", attr
);
4730 if (long_call_attr
!= NULL_TREE
)
4731 flags
|= SYMBOL_FLAG_LONG_CALL
;
4732 else if (medium_call_attr
!= NULL_TREE
)
4733 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
4734 else if (short_call_attr
!= NULL_TREE
)
4735 flags
|= SYMBOL_FLAG_SHORT_CALL
;
4737 SYMBOL_REF_FLAGS (symbol
) = flags
;
4739 else if (TREE_CODE (decl
) == VAR_DECL
)
4741 rtx symbol
= XEXP (rtl
, 0);
4743 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4744 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
4746 tree sec_attr
= lookup_attribute ("section", attr
);
4749 const char *sec_name
4750 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
4751 if (strcmp (sec_name
, ".cmem") == 0
4752 || strcmp (sec_name
, ".cmem_shared") == 0
4753 || strcmp (sec_name
, ".cmem_private") == 0)
4754 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
4759 /* This is how to output a definition of an internal numbered label where
4760 PREFIX is the class of label and NUM is the number within the class. */
4762 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
4765 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
4766 default_internal_label (stream
, prefix
, labelno
);
4769 /* Set the cpu type and print out other fancy things,
4770 at the top of the file. */
4772 static void arc_file_start (void)
4774 default_file_start ();
4775 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
4778 /* Cost functions. */
4780 /* Compute a (partial) cost for rtx X. Return true if the complete
4781 cost has been computed, and false if subexpressions should be
4782 scanned. In either case, *TOTAL contains the cost result. */
4785 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4786 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4788 int code
= GET_CODE (x
);
4792 /* Small integers are as cheap as registers. */
4795 bool nolimm
= false; /* Can we do without long immediate? */
4796 bool fast
= false; /* Is the result available immediately? */
4797 bool condexec
= false; /* Does this allow conditiobnal execution? */
4798 bool compact
= false; /* Is a 16 bit opcode available? */
4799 /* CONDEXEC also implies that we can have an unconditional
4800 3-address operation. */
4802 nolimm
= compact
= condexec
= false;
4803 if (UNSIGNED_INT6 (INTVAL (x
)))
4804 nolimm
= condexec
= compact
= true;
4807 if (SMALL_INT (INTVAL (x
)))
4808 nolimm
= fast
= true;
4811 case AND
: /* bclr, bmsk, ext[bw] */
4812 if (satisfies_constraint_Ccp (x
) /* bclr */
4813 || satisfies_constraint_C1p (x
) /* bmsk */)
4814 nolimm
= fast
= condexec
= compact
= true;
4816 case IOR
: /* bset */
4817 if (satisfies_constraint_C0p (x
)) /* bset */
4818 nolimm
= fast
= condexec
= compact
= true;
4821 if (satisfies_constraint_C0p (x
)) /* bxor */
4822 nolimm
= fast
= condexec
= true;
4825 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
4831 /* FIXME: Add target options to attach a small cost if
4832 condexec / compact is not true. */
4841 /* 4 byte values can be fetched as immediate constants -
4842 let's give that the cost of an extra insn. */
4846 *total
= COSTS_N_INSNS (1);
4855 *total
= COSTS_N_INSNS (1);
4858 split_double (x
, &first
, &second
);
4859 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
4860 + !SMALL_INT (INTVAL (second
)));
4864 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4865 If we need more than 12 insns to do a multiply, then go out-of-line,
4866 since the call overhead will be < 10% of the cost of the multiply. */
4870 if (TARGET_BARREL_SHIFTER
)
4872 /* If we want to shift a constant, we need a LIMM. */
4873 /* ??? when the optimizers want to know if a constant should be
4874 hoisted, they ask for the cost of the constant. OUTER_CODE is
4875 insufficient context for shifts since we don't know which operand
4876 we are looking at. */
4877 if (CONSTANT_P (XEXP (x
, 0)))
4879 *total
+= (COSTS_N_INSNS (2)
4880 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
4884 *total
= COSTS_N_INSNS (1);
4886 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
4887 *total
= COSTS_N_INSNS (16);
4890 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
4891 /* ??? want_to_gcse_p can throw negative shift counts at us,
4892 and then panics when it gets a negative cost as result.
4893 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4902 *total
= COSTS_N_INSNS(30);
4904 *total
= COSTS_N_INSNS(1);
4908 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
4909 *total
= COSTS_N_INSNS (1);
4911 *total
= arc_multcost
;
4912 /* We do not want synth_mult sequences when optimizing
4914 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
4915 *total
= COSTS_N_INSNS (1);
4917 *total
= COSTS_N_INSNS (2);
4920 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
4921 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
4922 || (GET_CODE (XEXP (x
, 0)) == MULT
4923 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
4925 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
4926 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
4931 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
4932 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
4933 || (GET_CODE (XEXP (x
, 1)) == MULT
4934 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
4936 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
4937 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
4943 rtx op0
= XEXP (x
, 0);
4944 rtx op1
= XEXP (x
, 1);
4946 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
4947 && XEXP (op0
, 1) == const1_rtx
)
4949 /* btst / bbit0 / bbit1:
4950 Small integers and registers are free; everything else can
4951 be put in a register. */
4952 mode
= GET_MODE (XEXP (op0
, 0));
4953 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
4954 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
4957 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
4958 && satisfies_constraint_C1p (XEXP (op0
, 1)))
4961 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
4965 if (GET_CODE (op1
) == NEG
)
4967 /* op0 might be constant, the inside of op1 is rather
4968 unlikely to be so. So swapping the operands might lower
4970 mode
= GET_MODE (op0
);
4971 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
4972 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
4977 if (outer_code
== IF_THEN_ELSE
4978 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
4979 && XEXP (x
, 1) == const0_rtx
4980 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
4982 /* btst / bbit0 / bbit1:
4983 Small integers and registers are free; everything else can
4984 be put in a register. */
4985 rtx op0
= XEXP (x
, 0);
4987 mode
= GET_MODE (XEXP (op0
, 0));
4988 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
4989 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
4993 /* scc_insn expands into two insns. */
4994 case GTU
: case GEU
: case LEU
:
4996 *total
+= COSTS_N_INSNS (1);
4998 case LTU
: /* might use adc. */
5000 *total
+= COSTS_N_INSNS (1) - 1;
5007 /* Helper used by arc_legitimate_pc_offset_p. */
5010 arc_needs_pcl_p (rtx x
)
5012 register const char *fmt
;
5015 if ((GET_CODE (x
) == UNSPEC
)
5016 && (XVECLEN (x
, 0) == 1)
5017 && (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
))
5018 switch (XINT (x
, 1))
5020 case ARC_UNSPEC_GOT
:
5021 case ARC_UNSPEC_GOTOFFPC
:
5029 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5030 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5034 if (arc_needs_pcl_p (XEXP (x
, i
)))
5037 else if (fmt
[i
] == 'E')
5038 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
5039 if (arc_needs_pcl_p (XVECEXP (x
, i
, j
)))
5046 /* Return true if ADDR is an address that needs to be expressed as an
5047 explicit sum of pcl + offset. */
5050 arc_legitimate_pc_offset_p (rtx addr
)
5052 if (GET_CODE (addr
) != CONST
)
5055 return arc_needs_pcl_p (addr
);
5058 /* Return true if ADDR is a valid pic address.
5059 A valid pic address on arc should look like
5060 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5063 arc_legitimate_pic_addr_p (rtx addr
)
5065 if (GET_CODE (addr
) == LABEL_REF
)
5067 if (GET_CODE (addr
) != CONST
)
5070 addr
= XEXP (addr
, 0);
5073 if (GET_CODE (addr
) == PLUS
)
5075 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5077 addr
= XEXP (addr
, 0);
5080 if (GET_CODE (addr
) != UNSPEC
5081 || XVECLEN (addr
, 0) != 1)
5084 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5085 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5086 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5087 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5088 && XINT (addr
, 1) != UNSPEC_TLS_GD
5089 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5092 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5093 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5101 /* Return true if OP contains a symbol reference. */
5104 symbolic_reference_mentioned_p (rtx op
)
5106 register const char *fmt
;
5109 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5112 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5113 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5119 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5120 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5124 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5131 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5132 If SKIP_LOCAL is true, skip symbols that bind locally.
5133 This is used further down in this file, and, without SKIP_LOCAL,
5134 in the addsi3 / subsi3 expanders when generating PIC code. */
5137 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5139 register const char *fmt
;
5142 if (GET_CODE(op
) == UNSPEC
)
5145 if (GET_CODE (op
) == SYMBOL_REF
)
5147 if (SYMBOL_REF_TLS_MODEL (op
))
5151 tree decl
= SYMBOL_REF_DECL (op
);
5152 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5155 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5156 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5162 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5163 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5168 else if (fmt
[i
] == 'e'
5169 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5177 /* Get the thread pointer. */
5182 /* If arc_tp_regno has been set, we can use that hard register
5183 directly as a base register. */
5184 if (arc_tp_regno
!= -1)
5185 return gen_rtx_REG (Pmode
, arc_tp_regno
);
5187 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5188 conflicts with function arguments / results. */
5189 rtx reg
= gen_reg_rtx (Pmode
);
5190 emit_insn (gen_tls_load_tp_soft ());
5191 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
5195 /* Helper to be used by TLS Global dynamic model. */
5198 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
5200 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
5201 rtx call_fusage
= NULL_RTX
;
5205 rtx x
= arc_unspec_offset (sym
, reloc
);
5206 emit_move_insn (r0
, x
);
5207 use_reg (&call_fusage
, r0
);
5209 gcc_assert (reloc
== UNSPEC_TLS_GD
);
5210 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
5211 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5212 way that the application should care. */
5213 RTL_PURE_CALL_P (call_insn
) = 1;
5214 add_function_usage_to (call_insn
, call_fusage
);
5216 rtx_insn
*insns
= get_insns ();
5219 rtx dest
= gen_reg_rtx (Pmode
);
5220 emit_libcall_block (insns
, dest
, r0
, eqv
);
5224 #define DTPOFF_ZERO_SYM ".tdata"
5226 /* Return a legitimized address for ADDR,
5227 which is a SYMBOL_REF with tls_model MODEL. */
5230 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5232 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5233 model
= TLS_MODEL_LOCAL_EXEC
;
5237 case TLS_MODEL_LOCAL_DYNAMIC
:
5240 const char *base_name
;
5243 decl
= SYMBOL_REF_DECL (addr
);
5244 base_name
= DTPOFF_ZERO_SYM
;
5245 if (decl
&& bss_initializer_p (decl
))
5246 base_name
= ".tbss";
5248 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5249 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
5253 v
= gen_rtvec (1, addr
);
5256 v
= gen_rtvec (2, addr
, base
);
5257 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
5258 addr
= gen_rtx_CONST (Pmode
, addr
);
5259 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
5260 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
5262 case TLS_MODEL_GLOBAL_DYNAMIC
:
5263 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
5265 case TLS_MODEL_INITIAL_EXEC
:
5266 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5267 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5268 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5270 case TLS_MODEL_LOCAL_EXEC
:
5272 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5273 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5279 /* Legitimize a pic address reference in ORIG.
5280 The return value is the legitimated address.
5281 If OLDX is non-zero, it is the target to assign the address to first. */
5284 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5293 if (GET_CODE (addr
) == LABEL_REF
)
5295 else if (GET_CODE (addr
) == SYMBOL_REF
)
5297 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5299 return arc_legitimize_tls_address (addr
, model
);
5302 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5303 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5305 /* This symbol must be referenced via a load from the Global
5306 Offset Table (@GOTPC). */
5307 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5308 pat
= gen_const_mem (Pmode
, pat
);
5311 oldx
= gen_reg_rtx (Pmode
);
5313 emit_move_insn (oldx
, pat
);
5318 if (GET_CODE (addr
) == CONST
)
5320 addr
= XEXP (addr
, 0);
5321 if (GET_CODE (addr
) == UNSPEC
)
5323 /* Check that the unspec is one of the ones we generate? */
5326 /* fwprop is placing in the REG_EQUIV notes constant pic
5327 unspecs expressions. Then, loop may use these notes for
5328 optimizations resulting in complex patterns that are not
5329 supported by the current implementation. The following
5330 two if-cases are simplifying the complex patters to
5332 else if (GET_CODE (addr
) == MINUS
)
5334 rtx op0
= XEXP (addr
, 0);
5335 rtx op1
= XEXP (addr
, 1);
5337 gcc_assert (GET_CODE (op1
) == UNSPEC
);
5339 emit_move_insn (oldx
,
5340 gen_rtx_CONST (SImode
,
5341 arc_legitimize_pic_address (op1
,
5343 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
5347 else if (GET_CODE (addr
) != PLUS
)
5349 rtx tmp
= XEXP (addr
, 0);
5350 enum rtx_code code
= GET_CODE (addr
);
5352 /* It only works for UNARY operations. */
5353 gcc_assert (UNARY_P (addr
));
5354 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
5359 gen_rtx_CONST (SImode
,
5360 arc_legitimize_pic_address (tmp
,
5363 emit_insn (gen_rtx_SET (oldx
,
5364 gen_rtx_fmt_ee (code
, SImode
,
5365 oldx
, const0_rtx
)));
5371 gcc_assert (GET_CODE (addr
) == PLUS
);
5372 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
5377 if (GET_CODE (addr
) == PLUS
)
5379 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
5381 base
= arc_legitimize_pic_address (op0
, oldx
);
5382 pat
= arc_legitimize_pic_address (op1
,
5383 base
== oldx
? NULL_RTX
: oldx
);
5385 if (base
== op0
&& pat
== op1
)
5388 if (GET_CODE (pat
) == CONST_INT
)
5389 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
5392 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
5394 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
5395 pat
= XEXP (pat
, 1);
5397 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
5405 /* Output address constant X to FILE, taking PIC into account. */
5408 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5413 switch (GET_CODE (x
))
5423 output_addr_const (file
, x
);
5425 /* Local functions do not get references through the PLT. */
5426 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5427 fputs ("@plt", file
);
5431 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5432 assemble_name (file
, buf
);
5436 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5437 assemble_name (file
, buf
);
5441 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5445 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5449 if (GET_MODE (x
) == VOIDmode
)
5451 /* We can use %d if the number is one word and positive. */
5452 if (CONST_DOUBLE_HIGH (x
))
5453 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5454 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5455 else if (CONST_DOUBLE_LOW (x
) < 0)
5456 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5458 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5461 /* We can't handle floating point constants;
5462 PRINT_OPERAND must handle them. */
5463 output_operand_lossage ("floating constant misused");
5467 /* FIXME: Not needed here. */
5468 /* Some assemblers need integer constants to appear last (eg masm). */
5469 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5471 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5472 fprintf (file
, "+");
5473 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5475 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5477 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5478 if (INTVAL (XEXP (x
, 1)) >= 0)
5479 fprintf (file
, "+");
5480 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5487 /* Avoid outputting things like x-x or x+5-x,
5488 since some assemblers can't handle that. */
5489 x
= simplify_subtraction (x
);
5490 if (GET_CODE (x
) != MINUS
)
5493 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5494 fprintf (file
, "-");
5495 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5496 && INTVAL (XEXP (x
, 1)) < 0)
5498 fprintf (file
, "(");
5499 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5500 fprintf (file
, ")");
5503 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5508 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5514 bool pcrel
; pcrel
= false;
5515 rtx base
; base
= NULL
;
5516 gcc_assert (XVECLEN (x
, 0) >= 1);
5517 switch (XINT (x
, 1))
5519 case ARC_UNSPEC_GOT
:
5520 suffix
= "@gotpc", pcrel
= true;
5522 case ARC_UNSPEC_GOTOFF
:
5525 case ARC_UNSPEC_GOTOFFPC
:
5526 suffix
= "@pcl", pcrel
= true;
5528 case ARC_UNSPEC_PLT
:
5532 suffix
= "@tlsgd", pcrel
= true;
5535 suffix
= "@tlsie", pcrel
= true;
5537 case UNSPEC_TLS_OFF
:
5538 if (XVECLEN (x
, 0) == 2)
5539 base
= XVECEXP (x
, 0, 1);
5540 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5541 || (!flag_pic
&& !base
))
5547 suffix
= "@invalid";
5548 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5552 fputs ("pcl,", file
);
5553 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5554 fputs (suffix
, file
);
5556 arc_output_pic_addr_const (file
, base
, code
);
5560 output_operand_lossage ("invalid expression as operand");
5564 #define SYMBOLIC_CONST(X) \
5565 (GET_CODE (X) == SYMBOL_REF \
5566 || GET_CODE (X) == LABEL_REF \
5567 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5569 /* Emit insns to move operands[1] into operands[0]. */
5572 prepare_pic_move (rtx
*operands
, machine_mode
)
5574 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5576 operands
[1] = force_reg (Pmode
, operands
[1]);
5579 rtx temp
= (reload_in_progress
? operands
[0]
5580 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5581 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5586 /* The function returning the number of words, at the beginning of an
5587 argument, must be put in registers. The returned value must be
5588 zero for arguments that are passed entirely in registers or that
5589 are entirely pushed on the stack.
5591 On some machines, certain arguments must be passed partially in
5592 registers and partially in memory. On these machines, typically
5593 the first N words of arguments are passed in registers, and the
5594 rest on the stack. If a multi-word argument (a `double' or a
5595 structure) crosses that boundary, its first few words must be
5596 passed in registers and the rest must be pushed. This function
5597 tells the compiler when this occurs, and how many of the words
5598 should go in registers.
5600 `FUNCTION_ARG' for these arguments should return the first register
5601 to be used by the caller for this argument; likewise
5602 `FUNCTION_INCOMING_ARG', for the called function.
5604 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5606 /* If REGNO is the least arg reg available then what is the total number of arg
5608 #define GPR_REST_ARG_REGS(REGNO) \
5609 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5611 /* Since arc parm regs are contiguous. */
5612 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5614 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5617 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
5618 tree type
, bool named ATTRIBUTE_UNUSED
)
5620 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5621 int bytes
= (mode
== BLKmode
5622 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5623 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5627 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5628 ret
= GPR_REST_ARG_REGS (arg_num
);
5630 /* ICEd at function.c:2361, and ret is copied to data->partial */
5631 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
5636 /* This function is used to control a function argument is passed in a
5637 register, and which register.
5639 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5640 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5641 all of the previous arguments so far passed in registers; MODE, the
5642 machine mode of the argument; TYPE, the data type of the argument
5643 as a tree node or 0 if that is not known (which happens for C
5644 support library functions); and NAMED, which is 1 for an ordinary
5645 argument and 0 for nameless arguments that correspond to `...' in
5646 the called function's prototype.
5648 The returned value should either be a `reg' RTX for the hard
5649 register in which to pass the argument, or zero to pass the
5650 argument on the stack.
5652 For machines like the Vax and 68000, where normally all arguments
5653 are pushed, zero suffices as a definition.
5655 The usual way to make the ANSI library `stdarg.h' work on a machine
5656 where some arguments are usually passed in registers, is to cause
5657 nameless arguments to be passed on the stack instead. This is done
5658 by making the function return 0 whenever NAMED is 0.
5660 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5661 definition of this function to determine if this argument is of a
5662 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5663 is not defined and the function returns non-zero for such an
5664 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5665 defined, the argument will be computed in the stack and then loaded
5668 The function is used to implement macro FUNCTION_ARG. */
5669 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5670 and the rest are pushed. */
5673 arc_function_arg (cumulative_args_t cum_v
,
5675 const_tree type ATTRIBUTE_UNUSED
,
5676 bool named ATTRIBUTE_UNUSED
)
5678 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5681 const char *debstr ATTRIBUTE_UNUSED
;
5683 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5684 /* Return a marker for use in the call instruction. */
5685 if (mode
== VOIDmode
)
5690 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
5692 ret
= gen_rtx_REG (mode
, arg_num
);
5693 debstr
= reg_names
[arg_num
];
5703 /* The function to update the summarizer variable *CUM to advance past
5704 an argument in the argument list. The values MODE, TYPE and NAMED
5705 describe that argument. Once this is done, the variable *CUM is
5706 suitable for analyzing the *following* argument with
5707 `FUNCTION_ARG', etc.
5709 This function need not do anything if the argument in question was
5710 passed on the stack. The compiler knows how to track the amount of
5711 stack space used for arguments without any special help.
5713 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5714 /* For the ARC: the cum set here is passed on to function_arg where we
5715 look at its value and say which reg to use. Strategy: advance the
5716 regnumber here till we run out of arg regs, then set *cum to last
5717 reg. In function_arg, since *cum > last arg reg we would return 0
5718 and thus the arg will end up on the stack. For straddling args of
5719 course function_arg_partial_nregs will come into play. */
5722 arc_function_arg_advance (cumulative_args_t cum_v
,
5725 bool named ATTRIBUTE_UNUSED
)
5727 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5728 int bytes
= (mode
== BLKmode
5729 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5730 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5734 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
5735 for (i
= 0; i
< words
; i
++)
5736 *cum
= ARC_NEXT_ARG_REG (*cum
);
5740 /* Define how to find the value returned by a function.
5741 VALTYPE is the data type of the value (as a tree).
5742 If the precise function being called is known, FN_DECL_OR_TYPE is its
5743 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5746 arc_function_value (const_tree valtype
,
5747 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
5748 bool outgoing ATTRIBUTE_UNUSED
)
5750 machine_mode mode
= TYPE_MODE (valtype
);
5751 int unsignedp ATTRIBUTE_UNUSED
;
5753 unsignedp
= TYPE_UNSIGNED (valtype
);
5754 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
5755 PROMOTE_MODE (mode
, unsignedp
, valtype
);
5756 return gen_rtx_REG (mode
, 0);
5759 /* Returns the return address that is used by builtin_return_address. */
5762 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
5767 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
5770 /* Nonzero if the constant value X is a legitimate general operand
5771 when generating PIC code. It is given that flag_pic is on and
5772 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
5775 arc_legitimate_pic_operand_p (rtx x
)
5777 return !arc_raw_symbolic_reference_mentioned_p (x
, true);
5780 /* Determine if a given RTX is a valid constant. We already know this
5781 satisfies CONSTANT_P. */
5784 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
5786 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
))
5789 if (!flag_pic
&& mode
!= Pmode
)
5792 switch (GET_CODE (x
))
5797 if (GET_CODE (x
) == PLUS
)
5800 ? GET_CODE (XEXP (x
, 1)) != CONST_INT
5801 : !arc_legitimate_constant_p (mode
, XEXP (x
, 1)))
5806 /* Only some unspecs are valid as "constants". */
5807 if (GET_CODE (x
) == UNSPEC
)
5808 switch (XINT (x
, 1))
5810 case ARC_UNSPEC_PLT
:
5811 case ARC_UNSPEC_GOTOFF
:
5812 case ARC_UNSPEC_GOTOFFPC
:
5813 case ARC_UNSPEC_GOT
:
5816 case UNSPEC_TLS_OFF
:
5823 /* We must have drilled down to a symbol. */
5824 if (arc_raw_symbolic_reference_mentioned_p (x
, false))
5831 if (SYMBOL_REF_TLS_MODEL (x
))
5843 /* Otherwise we handle everything else in the move patterns. */
5848 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
5850 if (RTX_OK_FOR_BASE_P (x
, strict
))
5852 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
5854 if (LEGITIMATE_SCALED_ADDRESS_P (mode
, x
, strict
))
5856 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x
))
5858 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
5861 /* When we compile for size avoid const (@sym + offset)
5863 if (!flag_pic
&& optimize_size
&& !reload_completed
5864 && (GET_CODE (x
) == CONST
)
5865 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
5866 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
5867 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
5868 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
5870 rtx addend
= XEXP (XEXP (x
, 0), 1);
5871 gcc_assert (CONST_INT_P (addend
));
5872 HOST_WIDE_INT offset
= INTVAL (addend
);
5874 /* Allow addresses having a large offset to pass. Anyhow they
5875 will end in a limm. */
5876 return !(offset
> -1024 && offset
< 1020);
5879 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
5881 if (flag_pic
? arc_legitimate_pic_addr_p (x
)
5882 : arc_legitimate_constant_p (Pmode
, x
))
5885 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
5886 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
5887 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5889 /* We're restricted here by the `st' insn. */
5890 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
5891 && GET_CODE (XEXP ((x
), 1)) == PLUS
5892 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
5893 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
5894 TARGET_AUTO_MODIFY_REG
, strict
))
5899 /* Return true iff ADDR (a legitimate address expression)
5900 has an effect that depends on the machine mode it is used for. */
5903 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
5905 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5906 which is valid for loads and stores, or a limm offset, which is valid for
5907 loads. Scaled indices are scaled by the access mode. */
5908 if (GET_CODE (addr
) == PLUS
5909 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
5914 /* Determine if it's legal to put X into the constant pool. */
5917 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
5919 return !arc_legitimate_constant_p (mode
, x
);
5922 /* IDs for all the ARC builtins. */
5926 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5927 ARC_BUILTIN_ ## NAME,
5928 #include "builtins.def"
5934 struct GTY(()) arc_builtin_description
5936 enum insn_code icode
;
5941 static GTY(()) struct arc_builtin_description
5942 arc_bdesc
[ARC_BUILTIN_COUNT
] =
5944 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5945 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
5946 #include "builtins.def"
5950 /* Transform UP into lowercase and write the result to LO.
5951 You must provide enough space for LO. Return LO. */
5954 arc_tolower (char *lo
, const char *up
)
5958 for (; *up
; up
++, lo
++)
5959 *lo
= TOLOWER (*up
);
5966 /* Implement `TARGET_BUILTIN_DECL'. */
5969 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
5971 if (id
< ARC_BUILTIN_COUNT
)
5972 return arc_bdesc
[id
].fndecl
;
5974 return error_mark_node
;
5978 arc_init_builtins (void)
5980 tree V4HI_type_node
;
5981 tree V2SI_type_node
;
5982 tree V2HI_type_node
;
5984 /* Vector types based on HS SIMD elements. */
5985 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
5986 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
5987 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
5989 tree pcvoid_type_node
5990 = build_pointer_type (build_qualified_type (void_type_node
,
5992 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
5995 tree void_ftype_void
5996 = build_function_type_list (void_type_node
, NULL_TREE
);
5998 = build_function_type_list (integer_type_node
, integer_type_node
,
6000 tree int_ftype_pcvoid_int
6001 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6002 integer_type_node
, NULL_TREE
);
6003 tree void_ftype_usint_usint
6004 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6005 long_unsigned_type_node
, NULL_TREE
);
6006 tree int_ftype_int_int
6007 = build_function_type_list (integer_type_node
, integer_type_node
,
6008 integer_type_node
, NULL_TREE
);
6009 tree usint_ftype_usint
6010 = build_function_type_list (long_unsigned_type_node
,
6011 long_unsigned_type_node
, NULL_TREE
);
6012 tree void_ftype_usint
6013 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6016 = build_function_type_list (integer_type_node
, void_type_node
,
6019 = build_function_type_list (void_type_node
, integer_type_node
,
6021 tree int_ftype_short
6022 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6025 /* Old ARC SIMD types. */
6026 tree v8hi_ftype_v8hi_v8hi
6027 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6028 V8HI_type_node
, NULL_TREE
);
6029 tree v8hi_ftype_v8hi_int
6030 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6031 integer_type_node
, NULL_TREE
);
6032 tree v8hi_ftype_v8hi_int_int
6033 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6034 integer_type_node
, integer_type_node
,
6036 tree void_ftype_v8hi_int_int
6037 = build_function_type_list (void_type_node
, V8HI_type_node
,
6038 integer_type_node
, integer_type_node
,
6040 tree void_ftype_v8hi_int_int_int
6041 = build_function_type_list (void_type_node
, V8HI_type_node
,
6042 integer_type_node
, integer_type_node
,
6043 integer_type_node
, NULL_TREE
);
6044 tree v8hi_ftype_int_int
6045 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6046 integer_type_node
, NULL_TREE
);
6047 tree void_ftype_int_int
6048 = build_function_type_list (void_type_node
, integer_type_node
,
6049 integer_type_node
, NULL_TREE
);
6050 tree v8hi_ftype_v8hi
6051 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6053 /* ARCv2 SIMD types. */
6054 tree long_ftype_v4hi_v4hi
6055 = build_function_type_list (long_long_integer_type_node
,
6056 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6057 tree int_ftype_v2hi_v2hi
6058 = build_function_type_list (integer_type_node
,
6059 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6060 tree v2si_ftype_v2hi_v2hi
6061 = build_function_type_list (V2SI_type_node
,
6062 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6063 tree v2hi_ftype_v2hi_v2hi
6064 = build_function_type_list (V2HI_type_node
,
6065 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6066 tree v2si_ftype_v2si_v2si
6067 = build_function_type_list (V2SI_type_node
,
6068 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6069 tree v4hi_ftype_v4hi_v4hi
6070 = build_function_type_list (V4HI_type_node
,
6071 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6072 tree long_ftype_v2si_v2hi
6073 = build_function_type_list (long_long_integer_type_node
,
6074 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6076 /* Add the builtins. */
6077 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6079 int id = ARC_BUILTIN_ ## NAME; \
6080 const char *Name = "__builtin_arc_" #NAME; \
6081 char *name = (char*) alloca (1 + strlen (Name)); \
6083 gcc_assert (id < ARC_BUILTIN_COUNT); \
6085 arc_bdesc[id].fndecl \
6086 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6087 BUILT_IN_MD, NULL, NULL_TREE); \
6089 #include "builtins.def"
6093 /* Helper to expand __builtin_arc_aligned (void* val, int
6097 arc_expand_builtin_aligned (tree exp
)
6099 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6100 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6102 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6103 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6105 if (!CONST_INT_P (op1
))
6107 /* If we can't fold the alignment to a constant integer
6108 whilst optimizing, this is probably a user error. */
6110 warning (0, "__builtin_arc_aligned with non-constant alignment");
6114 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6115 /* Check alignTest is positive, and a power of two. */
6116 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6118 error ("invalid alignment value for __builtin_arc_aligned");
6122 if (CONST_INT_P (op0
))
6124 HOST_WIDE_INT pnt
= INTVAL (op0
);
6126 if ((pnt
& (alignTest
- 1)) == 0)
6131 unsigned align
= get_pointer_alignment (arg0
);
6132 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6134 if (align
&& align
>= numBits
)
6136 /* Another attempt to ascertain alignment. Check the type
6137 we are pointing to. */
6138 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6139 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6144 /* Default to false. */
6148 /* Helper arc_expand_builtin, generates a pattern for the given icode
6152 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6154 switch (insn_data
[icode
].n_generator_args
)
6157 return GEN_FCN (icode
) ();
6159 return GEN_FCN (icode
) (arg
[0]);
6161 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6163 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6165 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6167 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6173 /* Expand an expression EXP that calls a built-in function,
6174 with result going to TARGET if that's convenient
6175 (and in mode MODE if that's convenient).
6176 SUBTARGET may be used as the target for computing one of EXP's operands.
6177 IGNORE is nonzero if the value is to be ignored. */
6180 arc_expand_builtin (tree exp
,
6182 rtx subtarget ATTRIBUTE_UNUSED
,
6183 machine_mode mode ATTRIBUTE_UNUSED
,
6184 int ignore ATTRIBUTE_UNUSED
)
6186 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6187 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6188 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6189 int i
, j
, n_args
= call_expr_nargs (exp
);
6192 enum insn_code icode
= d
->icode
;
6193 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6210 if (id
>= ARC_BUILTIN_COUNT
)
6211 internal_error ("bad builtin fcode");
6213 /* 1st part: Expand special builtins. */
6216 case ARC_BUILTIN_NOP
:
6217 emit_insn (gen_nopv ());
6220 case ARC_BUILTIN_RTIE
:
6221 case ARC_BUILTIN_SYNC
:
6222 case ARC_BUILTIN_BRK
:
6223 case ARC_BUILTIN_SWI
:
6224 case ARC_BUILTIN_UNIMP_S
:
6225 gcc_assert (icode
!= 0);
6226 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6229 case ARC_BUILTIN_ALIGNED
:
6230 return arc_expand_builtin_aligned (exp
);
6232 case ARC_BUILTIN_CLRI
:
6233 target
= gen_reg_rtx (SImode
);
6234 emit_insn (gen_clri (target
, const1_rtx
));
6237 case ARC_BUILTIN_TRAP_S
:
6238 case ARC_BUILTIN_SLEEP
:
6239 arg0
= CALL_EXPR_ARG (exp
, 0);
6241 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6243 if (!CONST_INT_P (op0
) || !satisfies_constraint_L (op0
))
6245 error ("builtin operand should be an unsigned 6-bit value");
6248 gcc_assert (icode
!= 0);
6249 emit_insn (GEN_FCN (icode
) (op0
));
6252 case ARC_BUILTIN_VDORUN
:
6253 case ARC_BUILTIN_VDIRUN
:
6254 arg0
= CALL_EXPR_ARG (exp
, 0);
6255 arg1
= CALL_EXPR_ARG (exp
, 1);
6256 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6257 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6259 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6261 mode0
= insn_data
[icode
].operand
[1].mode
;
6262 mode1
= insn_data
[icode
].operand
[2].mode
;
6264 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6265 op0
= copy_to_mode_reg (mode0
, op0
);
6267 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6268 op1
= copy_to_mode_reg (mode1
, op1
);
6270 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6277 case ARC_BUILTIN_VDIWR
:
6278 case ARC_BUILTIN_VDOWR
:
6279 arg0
= CALL_EXPR_ARG (exp
, 0);
6280 arg1
= CALL_EXPR_ARG (exp
, 1);
6281 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6282 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6284 if (!CONST_INT_P (op0
)
6285 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6286 error ("operand 1 should be an unsigned 3-bit immediate");
6288 mode1
= insn_data
[icode
].operand
[1].mode
;
6290 if (icode
== CODE_FOR_vdiwr_insn
)
6291 target
= gen_rtx_REG (SImode
,
6292 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6293 else if (icode
== CODE_FOR_vdowr_insn
)
6294 target
= gen_rtx_REG (SImode
,
6295 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6299 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6300 op1
= copy_to_mode_reg (mode1
, op1
);
6302 pat
= GEN_FCN (icode
) (target
, op1
);
6309 case ARC_BUILTIN_VASRW
:
6310 case ARC_BUILTIN_VSR8
:
6311 case ARC_BUILTIN_VSR8AW
:
6312 arg0
= CALL_EXPR_ARG (exp
, 0);
6313 arg1
= CALL_EXPR_ARG (exp
, 1);
6314 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6315 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6316 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6318 target
= gen_reg_rtx (V8HImode
);
6319 mode0
= insn_data
[icode
].operand
[1].mode
;
6320 mode1
= insn_data
[icode
].operand
[2].mode
;
6322 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6323 op0
= copy_to_mode_reg (mode0
, op0
);
6325 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6326 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6327 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6329 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6336 case ARC_BUILTIN_VLD32WH
:
6337 case ARC_BUILTIN_VLD32WL
:
6338 case ARC_BUILTIN_VLD64
:
6339 case ARC_BUILTIN_VLD32
:
6342 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6343 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6344 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6346 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6347 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6348 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6349 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6351 /* target <- src vreg. */
6352 emit_insn (gen_move_insn (target
, src_vreg
));
6354 /* target <- vec_concat: target, mem (Ib, u8). */
6355 mode0
= insn_data
[icode
].operand
[3].mode
;
6356 mode1
= insn_data
[icode
].operand
[1].mode
;
6358 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6359 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6360 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6362 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6363 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6364 error ("operand 2 should be an unsigned 8-bit value");
6366 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6373 case ARC_BUILTIN_VLD64W
:
6374 case ARC_BUILTIN_VLD128
:
6375 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6376 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6378 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6379 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6380 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6382 /* target <- src vreg. */
6383 target
= gen_reg_rtx (V8HImode
);
6385 /* target <- vec_concat: target, mem (Ib, u8). */
6386 mode0
= insn_data
[icode
].operand
[1].mode
;
6387 mode1
= insn_data
[icode
].operand
[2].mode
;
6388 mode2
= insn_data
[icode
].operand
[3].mode
;
6390 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6391 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6392 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6394 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6395 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6396 error ("operand 2 should be an unsigned 8-bit value");
6398 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6406 case ARC_BUILTIN_VST128
:
6407 case ARC_BUILTIN_VST64
:
6408 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6409 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6410 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6412 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6413 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6414 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6415 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6417 mode0
= insn_data
[icode
].operand
[0].mode
;
6418 mode1
= insn_data
[icode
].operand
[1].mode
;
6419 mode2
= insn_data
[icode
].operand
[2].mode
;
6420 mode3
= insn_data
[icode
].operand
[3].mode
;
6422 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6423 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6424 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6426 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6427 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6428 error ("operand 3 should be an unsigned 8-bit value");
6430 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6431 op3
= copy_to_mode_reg (mode3
, op3
);
6433 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6440 case ARC_BUILTIN_VST16_N
:
6441 case ARC_BUILTIN_VST32_N
:
6442 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6443 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6444 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6445 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6447 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6448 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6449 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6450 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6451 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6453 mode0
= insn_data
[icode
].operand
[0].mode
;
6454 mode2
= insn_data
[icode
].operand
[2].mode
;
6455 mode3
= insn_data
[icode
].operand
[3].mode
;
6456 mode4
= insn_data
[icode
].operand
[4].mode
;
6458 /* Do some correctness checks for the operands. */
6459 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6460 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6461 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6463 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6464 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6465 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6467 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6468 op3
= copy_to_mode_reg (mode3
, op3
);
6470 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6471 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6472 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6473 else if (icode
== CODE_FOR_vst32_n_insn
6474 && ((INTVAL (op4
) % 2) != 0))
6475 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6477 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6488 /* 2nd part: Expand regular builtins. */
6490 internal_error ("bad builtin fcode");
6492 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6497 if (target
== NULL_RTX
6498 || GET_MODE (target
) != tmode
6499 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6501 target
= gen_reg_rtx (tmode
);
6506 gcc_assert (n_args
<= 4);
6507 for (i
= 0; i
< n_args
; i
++, j
++)
6509 tree arg
= CALL_EXPR_ARG (exp
, i
);
6510 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6511 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6512 machine_mode opmode
= GET_MODE (op
);
6513 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6515 /* SIMD extension requires exact immediate operand match. */
6516 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6517 && (id
< ARC_BUILTIN_SIMD_END
)
6521 if (!CONST_INT_P (op
))
6522 error ("builtin requires an immediate for operand %d", j
);
6526 if (!satisfies_constraint_L (op
))
6527 error ("operand %d should be a 6 bit unsigned immediate", j
);
6530 if (!satisfies_constraint_P (op
))
6531 error ("operand %d should be a 8 bit unsigned immediate", j
);
6534 if (!satisfies_constraint_K (op
))
6535 error ("operand %d should be a 3 bit unsigned immediate", j
);
6538 error ("unknown builtin immediate operand type for operand %d",
6543 if (CONST_INT_P (op
))
6546 if ((opmode
== SImode
) && (mode
== HImode
))
6549 op
= gen_lowpart (HImode
, op
);
6552 /* In case the insn wants input operands in modes different from
6553 the result, abort. */
6554 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6556 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6557 op
= copy_to_mode_reg (mode
, op
);
6562 pat
= apply_GEN_FCN (icode
, xop
);
6563 if (pat
== NULL_RTX
)
6574 /* Returns true if the operands[opno] is a valid compile-time constant to be
6575 used as register number in the code for builtins. Else it flags an error
6576 and returns false. */
6579 check_if_valid_regno_const (rtx
*operands
, int opno
)
6582 switch (GET_CODE (operands
[opno
]))
6589 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6595 /* Check that after all the constant folding, whether the operand to
6596 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6599 check_if_valid_sleep_operand (rtx
*operands
, int opno
)
6601 switch (GET_CODE (operands
[opno
]))
6605 if( UNSIGNED_INT6 (INTVAL (operands
[opno
])))
6609 fatal_error (input_location
,
6610 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6616 /* Return true if it is ok to make a tail-call to DECL. */
6619 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
6620 tree exp ATTRIBUTE_UNUSED
)
6622 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6623 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6626 /* Everything else is ok. */
6630 /* Output code to add DELTA to the first argument, and then jump
6631 to FUNCTION. Used for C++ multiple inheritance. */
6634 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
6635 HOST_WIDE_INT delta
,
6636 HOST_WIDE_INT vcall_offset
,
6639 int mi_delta
= delta
;
6640 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
6643 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
6647 mi_delta
= - mi_delta
;
6649 /* Add DELTA. When possible use a plain add, otherwise load it into
6650 a register first. */
6652 while (mi_delta
!= 0)
6654 if ((mi_delta
& (3 << shift
)) == 0)
6658 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
6659 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
6660 mi_delta
& (0xff << shift
));
6661 mi_delta
&= ~(0xff << shift
);
6666 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6667 if (vcall_offset
!= 0)
6669 /* ld r12,[this] --> temp = *this
6670 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6672 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6673 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6674 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
6675 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
6676 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
6677 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6678 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
6679 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
6680 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
6683 fnaddr
= XEXP (DECL_RTL (function
), 0);
6685 if (arc_is_longcall_p (fnaddr
))
6689 asm_fprintf (file
, "\tld\t%s, [pcl, @",
6690 ARC_TEMP_SCRATCH_REG
);
6691 assemble_name (file
, XSTR (fnaddr
, 0));
6692 fputs ("@gotpc]\n", file
);
6693 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
6697 fputs ("\tj\t@", file
);
6698 assemble_name (file
, XSTR (fnaddr
, 0));
6703 fputs ("\tb\t@", file
);
6704 assemble_name (file
, XSTR (fnaddr
, 0));
6706 fputs ("@plt\n", file
);
6711 /* Return true if a 32 bit "long_call" should be generated for
6712 this calling SYM_REF. We generate a long_call if the function:
6714 a. has an __attribute__((long call))
6715 or b. the -mlong-calls command line switch has been specified
6717 However we do not generate a long call if the function has an
6718 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6720 This function will be called by C fragments contained in the machine
6721 description file. */
6724 arc_is_longcall_p (rtx sym_ref
)
6726 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6729 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
6730 || (TARGET_LONG_CALLS_SET
6731 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6732 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6736 /* Likewise for short calls. */
6739 arc_is_shortcall_p (rtx sym_ref
)
6741 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6744 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6745 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
6746 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
6747 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6751 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6754 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
6756 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
6760 HOST_WIDE_INT size
= int_size_in_bytes (type
);
6761 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
6766 /* This was in rtlanal.c, and can go in there when we decide we want
6767 to submit the change for inclusion in the GCC tree. */
6768 /* Like note_stores, but allow the callback to have side effects on the rtl
6769 (like the note_stores of yore):
6770 Call FUN on each register or MEM that is stored into or clobbered by X.
6771 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6772 ignored by note_stores, but passed to FUN.
6773 FUN may alter parts of the RTL.
6775 FUN receives three arguments:
6776 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6777 2. the SET or CLOBBER rtx that does the store,
6778 3. the pointer DATA provided to note_stores.
6780 If the item being stored in or clobbered is a SUBREG of a hard register,
6781 the SUBREG will be passed. */
6783 /* For now. */ static
6785 walk_stores (rtx x
, void (*fun
) (rtx
, rtx
, void *), void *data
)
6789 if (GET_CODE (x
) == COND_EXEC
)
6790 x
= COND_EXEC_CODE (x
);
6792 if (GET_CODE (x
) == SET
|| GET_CODE (x
) == CLOBBER
)
6794 rtx dest
= SET_DEST (x
);
6796 while ((GET_CODE (dest
) == SUBREG
6797 && (!REG_P (SUBREG_REG (dest
))
6798 || REGNO (SUBREG_REG (dest
)) >= FIRST_PSEUDO_REGISTER
))
6799 || GET_CODE (dest
) == ZERO_EXTRACT
6800 || GET_CODE (dest
) == STRICT_LOW_PART
)
6801 dest
= XEXP (dest
, 0);
6803 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6804 each of whose first operand is a register. */
6805 if (GET_CODE (dest
) == PARALLEL
)
6807 for (i
= XVECLEN (dest
, 0) - 1; i
>= 0; i
--)
6808 if (XEXP (XVECEXP (dest
, 0, i
), 0) != 0)
6809 (*fun
) (XEXP (XVECEXP (dest
, 0, i
), 0), x
, data
);
6812 (*fun
) (dest
, x
, data
);
6815 else if (GET_CODE (x
) == PARALLEL
)
6816 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
6817 walk_stores (XVECEXP (x
, 0, i
), fun
, data
);
6821 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
6822 machine_mode mode ATTRIBUTE_UNUSED
,
6824 bool named ATTRIBUTE_UNUSED
)
6827 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
6828 || TREE_ADDRESSABLE (type
)));
6831 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6834 arc_can_use_doloop_p (const widest_int
&iterations
, const widest_int
&,
6835 unsigned int loop_depth
, bool entered_at_top
)
6839 /* Setting up the loop with two sr instructions costs 6 cycles. */
6842 && wi::gtu_p (iterations
, 0)
6843 && wi::leu_p (iterations
, flag_pic
? 6 : 3))
6848 /* NULL if INSN insn is valid within a low-overhead loop.
6849 Otherwise return why doloop cannot be applied. */
6852 arc_invalid_within_doloop (const rtx_insn
*insn
)
6855 return "Function call in the loop.";
6859 /* Return true if a load instruction (CONSUMER) uses the same address as a
6860 store instruction (PRODUCER). This function is used to avoid st/ld
6861 address hazard in ARC700 cores. */
6863 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
6865 rtx in_set
, out_set
;
6866 rtx out_addr
, in_addr
;
6874 /* Peel the producer and the consumer for the address. */
6875 out_set
= single_set (producer
);
6878 out_addr
= SET_DEST (out_set
);
6881 if (GET_CODE (out_addr
) == ZERO_EXTEND
6882 || GET_CODE (out_addr
) == SIGN_EXTEND
)
6883 out_addr
= XEXP (out_addr
, 0);
6885 if (!MEM_P (out_addr
))
6888 in_set
= single_set (consumer
);
6891 in_addr
= SET_SRC (in_set
);
6894 if (GET_CODE (in_addr
) == ZERO_EXTEND
6895 || GET_CODE (in_addr
) == SIGN_EXTEND
)
6896 in_addr
= XEXP (in_addr
, 0);
6898 if (!MEM_P (in_addr
))
6900 /* Get rid of the MEM and check if the addresses are
6902 in_addr
= XEXP (in_addr
, 0);
6903 out_addr
= XEXP (out_addr
, 0);
6905 return exp_equiv_p (in_addr
, out_addr
, 0, true);
6911 /* The same functionality as arc_hazard. It is called in machine
6912 reorg before any other optimization. Hence, the NOP size is taken
6913 into account when doing branch shortening. */
6916 workaround_arc_anomaly (void)
6918 rtx_insn
*insn
, *succ0
;
6920 /* For any architecture: call arc_hazard here. */
6921 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6923 succ0
= next_real_insn (insn
);
6924 if (arc_hazard (insn
, succ0
))
6926 emit_insn_before (gen_nopv (), succ0
);
6934 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6936 succ0
= next_real_insn (insn
);
6937 if (arc_store_addr_hazard_p (insn
, succ0
))
6939 emit_insn_after (gen_nopv (), insn
);
6940 emit_insn_after (gen_nopv (), insn
);
6944 /* Avoid adding nops if the instruction between the ST and LD is
6946 succ1
= next_real_insn (succ0
);
6947 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
6948 && arc_store_addr_hazard_p (insn
, succ1
))
6949 emit_insn_after (gen_nopv (), insn
);
6954 static int arc_reorg_in_progress
= 0;
6956 /* ARC's machince specific reorg function. */
6967 workaround_arc_anomaly ();
6969 cfun
->machine
->arc_reorg_started
= 1;
6970 arc_reorg_in_progress
= 1;
6972 /* Link up loop ends with their loop start. */
6974 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6975 if (GET_CODE (insn
) == JUMP_INSN
6976 && recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
6979 = as_a
<rtx_insn
*> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 1), 0));
6980 rtx num
= GEN_INT (CODE_LABEL_NUMBER (top_label
));
6981 rtx_insn
*lp
, *prev
= prev_nonnote_insn (top_label
);
6982 rtx_insn
*lp_simple
= NULL
;
6983 rtx_insn
*next
= NULL
;
6984 rtx op0
= XEXP (XVECEXP (PATTERN (insn
), 0, 1), 0);
6988 (lp
&& NONJUMP_INSN_P (lp
)
6989 && recog_memoized (lp
) != CODE_FOR_doloop_begin_i
);
6990 lp
= prev_nonnote_insn (lp
))
6992 if (!lp
|| !NONJUMP_INSN_P (lp
)
6993 || dead_or_set_regno_p (lp
, LP_COUNT
))
6995 HOST_WIDE_INT loop_end_id
6996 = INTVAL (XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0));
6998 for (prev
= next
= insn
, lp
= NULL
; prev
|| next
;)
7002 if (NONJUMP_INSN_P (prev
)
7003 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
7004 && (INTVAL (XEXP (XVECEXP (PATTERN (prev
), 0, 5), 0))
7010 else if (LABEL_P (prev
))
7012 prev
= prev_nonnote_insn (prev
);
7016 if (NONJUMP_INSN_P (next
)
7017 && recog_memoized (next
) == CODE_FOR_doloop_begin_i
7018 && (INTVAL (XEXP (XVECEXP (PATTERN (next
), 0, 5), 0))
7024 next
= next_nonnote_insn (next
);
7031 if (lp
&& !dead_or_set_regno_p (lp
, LP_COUNT
))
7033 rtx begin_cnt
= XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0);
7034 if (INTVAL (XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0)))
7035 /* The loop end insn has been duplicated. That can happen
7036 when there is a conditional block at the very end of
7039 /* If Register allocation failed to allocate to the right
7040 register, There is no point into teaching reload to
7041 fix this up with reloads, as that would cost more
7042 than using an ordinary core register with the
7043 doloop_fallback pattern. */
7044 if ((true_regnum (op0
) != LP_COUNT
|| !REG_P (begin_cnt
))
7045 /* Likewise, if the loop setup is evidently inside the loop,
7047 || (!lp_simple
&& lp
!= next
&& !seen_label
))
7052 /* It is common that the optimizers copy the loop count from
7053 another register, and doloop_begin_i is stuck with the
7054 source of the move. Making doloop_begin_i only accept "l"
7055 is nonsentical, as this then makes reload evict the pseudo
7056 used for the loop end. The underlying cause is that the
7057 optimizers don't understand that the register allocation for
7058 doloop_begin_i should be treated as part of the loop.
7059 Try to work around this problem by verifying the previous
7061 if (true_regnum (begin_cnt
) != LP_COUNT
)
7066 for (mov
= prev_nonnote_insn (lp
); mov
;
7067 mov
= prev_nonnote_insn (mov
))
7069 if (!NONJUMP_INSN_P (mov
))
7071 else if ((set
= single_set (mov
))
7072 && rtx_equal_p (SET_SRC (set
), begin_cnt
)
7073 && rtx_equal_p (SET_DEST (set
), op0
))
7078 XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0) = op0
;
7079 note
= find_regno_note (lp
, REG_DEAD
, REGNO (begin_cnt
));
7081 remove_note (lp
, note
);
7089 XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0) = num
;
7090 XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0) = num
;
7092 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const2_rtx
;
7093 else if (!lp_simple
)
7094 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const1_rtx
;
7095 else if (prev
!= lp
)
7098 add_insn_after (lp
, prev
, NULL
);
7102 XEXP (XVECEXP (PATTERN (lp
), 0, 7), 0)
7103 = gen_rtx_LABEL_REF (Pmode
, top_label
);
7104 add_reg_note (lp
, REG_LABEL_OPERAND
, top_label
);
7105 LABEL_NUSES (top_label
)++;
7107 /* We can avoid tedious loop start / end setting for empty loops
7108 be merely setting the loop count to its final value. */
7109 if (next_active_insn (top_label
) == insn
)
7112 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp
), 0, 3), 0),
7115 rtx_insn
*lc_set_insn
= emit_insn_before (lc_set
, insn
);
7120 /* If the loop is non-empty with zero length, we can't make it
7121 a zero-overhead loop. That can happen for empty asms. */
7126 for (scan
= top_label
;
7127 (scan
&& scan
!= insn
7128 && (!NONJUMP_INSN_P (scan
) || !get_attr_length (scan
)));
7129 scan
= NEXT_INSN (scan
));
7139 /* Sometimes the loop optimizer makes a complete hash of the
7140 loop. If it were only that the loop is not entered at the
7141 top, we could fix this up by setting LP_START with SR .
7142 However, if we can't find the loop begin were it should be,
7143 chances are that it does not even dominate the loop, but is
7144 inside the loop instead. Using SR there would kill
7146 We use the doloop_fallback pattern here, which executes
7147 in two cycles on the ARC700 when predicted correctly. */
7151 rtx op3
= XEXP (XVECEXP (PATTERN (insn
), 0, 5), 0);
7153 emit_insn_before (gen_move_insn (op3
, op0
), insn
);
7155 = gen_doloop_fallback_m (op3
, JUMP_LABEL (insn
), op0
);
7158 XVEC (PATTERN (insn
), 0)
7159 = gen_rtvec (2, XVECEXP (PATTERN (insn
), 0, 0),
7160 XVECEXP (PATTERN (insn
), 0, 1));
7161 INSN_CODE (insn
) = -1;
7166 /* FIXME: should anticipate ccfsm action, generate special patterns for
7167 to-be-deleted branches that have no delay slot and have at least the
7168 length of the size increase forced on other insns that are conditionalized.
7169 This can also have an insn_list inside that enumerates insns which are
7170 not actually conditionalized because the destinations are dead in the
7172 Could also tag branches that we want to be unaligned if they get no delay
7173 slot, or even ones that we don't want to do delay slot sheduling for
7174 because we can unalign them.
7176 However, there are cases when conditional execution is only possible after
7177 delay slot scheduling:
7179 - If a delay slot is filled with a nocond/set insn from above, the previous
7180 basic block can become elegible for conditional execution.
7181 - If a delay slot is filled with a nocond insn from the fall-through path,
7182 the branch with that delay slot can become eligble for conditional
7183 execution (however, with the same sort of data flow analysis that dbr
7184 does, we could have figured out before that we don't need to
7185 conditionalize this insn.)
7186 - If a delay slot insn is filled with an insn from the target, the
7187 target label gets its uses decremented (even deleted if falling to zero),
7188 thus possibly creating more condexec opportunities there.
7189 Therefore, we should still be prepared to apply condexec optimization on
7190 non-prepared branches if the size increase of conditionalized insns is no
7191 more than the size saved from eliminating the branch. An invocation option
7192 could also be used to reserve a bit of extra size for condbranches so that
7193 this'll work more often (could also test in arc_reorg if the block is
7194 'close enough' to be eligible for condexec to make this likely, and
7195 estimate required size increase). */
7196 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7197 if (TARGET_NO_BRCC_SET
)
7202 init_insn_lengths();
7205 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
7208 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
7209 df_finish_pass ((flags
& TODO_df_verify
) != 0);
7212 /* Call shorten_branches to calculate the insn lengths. */
7213 shorten_branches (get_insns());
7214 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
7216 if (!INSN_ADDRESSES_SET_P())
7217 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
7219 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7222 enum attr_type insn_type
;
7224 /* If a non-jump insn (or a casesi jump table), continue. */
7225 if (GET_CODE (insn
) != JUMP_INSN
||
7226 GET_CODE (PATTERN (insn
)) == ADDR_VEC
7227 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
7230 /* If we already have a brcc, note if it is suitable for brcc_s.
7231 Be a bit generous with the brcc_s range so that we can take
7232 advantage of any code shortening from delay slot scheduling. */
7233 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
7235 rtx pat
= PATTERN (insn
);
7236 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
7237 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
7239 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7240 if ((offset
>= -140 && offset
< 140)
7241 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
7242 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
7243 && equality_comparison_operator (op
, VOIDmode
))
7244 PUT_MODE (*ccp
, CC_Zmode
);
7245 else if (GET_MODE (*ccp
) == CC_Zmode
)
7246 PUT_MODE (*ccp
, CC_ZNmode
);
7249 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
7250 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
7253 /* OK. so we have a jump insn. */
7254 /* We need to check that it is a bcc. */
7255 /* Bcc => set (pc) (if_then_else ) */
7256 pattern
= PATTERN (insn
);
7257 if (GET_CODE (pattern
) != SET
7258 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
7259 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
7262 /* Now check if the jump is beyond the s9 range. */
7263 if (CROSSING_JUMP_P (insn
))
7265 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7267 if(offset
> 253 || offset
< -254)
7270 pc_target
= SET_SRC (pattern
);
7272 /* Avoid FPU instructions. */
7273 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
7274 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
7277 /* Now go back and search for the set cc insn. */
7279 label
= XEXP (pc_target
, 1);
7283 rtx_insn
*scan
, *link_insn
= NULL
;
7285 for (scan
= PREV_INSN (insn
);
7286 scan
&& GET_CODE (scan
) != CODE_LABEL
;
7287 scan
= PREV_INSN (scan
))
7289 if (! INSN_P (scan
))
7291 pat
= PATTERN (scan
);
7292 if (GET_CODE (pat
) == SET
7293 && cc_register (SET_DEST (pat
), VOIDmode
))
7302 /* Check if this is a data dependency. */
7304 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
7307 /* Ok this is the set cc. copy args here. */
7308 op
= XEXP (pc_target
, 0);
7310 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
7311 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
7312 if (GET_CODE (op0
) == ZERO_EXTRACT
7313 && XEXP (op0
, 1) == const1_rtx
7314 && (GET_CODE (op
) == EQ
7315 || GET_CODE (op
) == NE
))
7317 /* btst / b{eq,ne} -> bbit{0,1} */
7318 op0
= XEXP (cmp0
, 0);
7319 op1
= XEXP (cmp0
, 2);
7321 else if (!register_operand (op0
, VOIDmode
)
7322 || !general_operand (op1
, VOIDmode
))
7324 /* Be careful not to break what cmpsfpx_raw is
7325 trying to create for checking equality of
7326 single-precision floats. */
7327 else if (TARGET_SPFP
7328 && GET_MODE (op0
) == SFmode
7329 && GET_MODE (op1
) == SFmode
)
7332 /* None of the two cmp operands should be set between the
7333 cmp and the branch. */
7334 if (reg_set_between_p (op0
, link_insn
, insn
))
7337 if (reg_set_between_p (op1
, link_insn
, insn
))
7340 /* Since the MODE check does not work, check that this is
7341 CC reg's last set location before insn, and also no
7342 instruction between the cmp and branch uses the
7344 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
7345 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
7348 /* CC reg should be dead after insn. */
7349 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
7352 op
= gen_rtx_fmt_ee (GET_CODE (op
),
7353 GET_MODE (op
), cmp0
, cmp1
);
7354 /* If we create a LIMM where there was none before,
7355 we only benefit if we can avoid a scheduling bubble
7356 for the ARC600. Otherwise, we'd only forgo chances
7357 at short insn generation, and risk out-of-range
7359 if (!brcc_nolimm_operator (op
, VOIDmode
)
7360 && !long_immediate_operand (op1
, VOIDmode
)
7362 || next_active_insn (link_insn
) != insn
))
7365 /* Emit bbit / brcc (or brcc_s if possible).
7366 CC_Zmode indicates that brcc_s is possible. */
7369 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
7370 else if ((offset
>= -140 && offset
< 140)
7371 && rtx_equal_p (op1
, const0_rtx
)
7372 && compact_register_operand (op0
, VOIDmode
)
7373 && (GET_CODE (op
) == EQ
7374 || GET_CODE (op
) == NE
))
7375 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
7377 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
7380 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
7381 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
7382 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
7385 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
7386 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
7388 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
7389 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
7392 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7393 REG_NOTES (brcc_insn
) = note
;
7395 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
7398 remove_note (link_insn
, note
);
7399 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7400 REG_NOTES (brcc_insn
) = note
;
7402 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
7405 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7406 REG_NOTES (brcc_insn
) = note
;
7411 /* Delete the bcc insn. */
7412 set_insn_deleted (insn
);
7414 /* Delete the cmp insn. */
7415 set_insn_deleted (link_insn
);
7420 /* Clear out insn_addresses. */
7421 INSN_ADDRESSES_FREE ();
7425 if (INSN_ADDRESSES_SET_P())
7426 fatal_error (input_location
, "insn addresses not freed");
7428 arc_reorg_in_progress
= 0;
7431 /* Check if the operands are valid for BRcc.d generation
7432 Valid Brcc.d patterns are
7436 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7437 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7438 does not have a delay slot
7440 Assumed precondition: Second operand is either a register or a u6 value. */
7443 valid_brcc_with_delay_p (rtx
*operands
)
7445 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
7447 return brcc_nolimm_operator (operands
[0], VOIDmode
);
7450 /* ??? Hack. This should no really be here. See PR32143. */
7452 arc_decl_anon_ns_mem_p (const_tree decl
)
7456 if (decl
== NULL_TREE
|| decl
== error_mark_node
)
7458 if (TREE_CODE (decl
) == NAMESPACE_DECL
7459 && DECL_NAME (decl
) == NULL_TREE
)
7461 /* Classes and namespaces inside anonymous namespaces have
7462 TREE_PUBLIC == 0, so we can shortcut the search. */
7463 else if (TYPE_P (decl
))
7464 return (TREE_PUBLIC (TYPE_NAME (decl
)) == 0);
7465 else if (TREE_CODE (decl
) == NAMESPACE_DECL
)
7466 return (TREE_PUBLIC (decl
) == 0);
7468 decl
= DECL_CONTEXT (decl
);
7472 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7473 access DECL using %gp_rel(...)($gp). */
7476 arc_in_small_data_p (const_tree decl
)
7480 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
7484 /* We don't yet generate small-data references for -mabicalls. See related
7485 -G handling in override_options. */
7486 if (TARGET_NO_SDATA_SET
)
7489 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
7493 /* Reject anything that isn't in a known small-data section. */
7494 name
= DECL_SECTION_NAME (decl
);
7495 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
7498 /* If a symbol is defined externally, the assembler will use the
7499 usual -G rules when deciding how to implement macros. */
7500 if (!DECL_EXTERNAL (decl
))
7503 /* Only global variables go into sdata section for now. */
7506 /* Don't put constants into the small data section: we want them
7507 to be in ROM rather than RAM. */
7508 if (TREE_CODE (decl
) != VAR_DECL
)
7511 if (TREE_READONLY (decl
)
7512 && !TREE_SIDE_EFFECTS (decl
)
7513 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
7516 /* TREE_PUBLIC might change after the first call, because of the patch
7518 if (default_binds_local_p_1 (decl
, 1)
7519 || arc_decl_anon_ns_mem_p (decl
))
7522 /* To ensure -mvolatile-cache works
7523 ld.di does not have a gp-relative variant. */
7524 if (TREE_THIS_VOLATILE (decl
))
7528 /* Disable sdata references to weak variables. */
7529 if (DECL_WEAK (decl
))
7532 size
= int_size_in_bytes (TREE_TYPE (decl
));
7534 /* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7537 /* Allow only <=4B long data types into sdata. */
7538 return (size
> 0 && size
<= 4);
7541 /* Return true if X is a small data address that can be rewritten
7545 arc_rewrite_small_data_p (const_rtx x
)
7547 if (GET_CODE (x
) == CONST
)
7550 if (GET_CODE (x
) == PLUS
)
7552 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
7556 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
7558 gcc_assert (SYMBOL_REF_TLS_MODEL (x
) == 0);
7564 /* If possible, rewrite OP so that it refers to small data using
7565 explicit relocations. */
7568 arc_rewrite_small_data (rtx op
)
7570 op
= copy_insn (op
);
7571 subrtx_ptr_iterator::array_type array
;
7572 FOR_EACH_SUBRTX_PTR (iter
, array
, &op
, ALL
)
7575 if (arc_rewrite_small_data_p (*loc
))
7577 gcc_assert (SDATA_BASE_REGNUM
== PIC_OFFSET_TABLE_REGNUM
);
7578 *loc
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, *loc
);
7581 if (GET_CODE (op
) == MEM
&& &XEXP (op
, 0) == loc
)
7583 else if (GET_CODE (op
) == MEM
7584 && GET_CODE (XEXP (op
, 0)) == PLUS
7585 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == MULT
)
7586 *loc
= force_reg (Pmode
, *loc
);
7590 iter
.skip_subrtxes ();
7592 else if (GET_CODE (*loc
) == PLUS
7593 && rtx_equal_p (XEXP (*loc
, 0), pic_offset_table_rtx
))
7594 iter
.skip_subrtxes ();
7599 /* Return true if OP refers to small data symbols directly, not through
7603 small_data_pattern (rtx op
, machine_mode
)
7605 if (GET_CODE (op
) == SEQUENCE
)
7607 subrtx_iterator::array_type array
;
7608 FOR_EACH_SUBRTX (iter
, array
, op
, ALL
)
7610 const_rtx x
= *iter
;
7611 if (GET_CODE (x
) == PLUS
7612 && rtx_equal_p (XEXP (x
, 0), pic_offset_table_rtx
))
7613 iter
.skip_subrtxes ();
7614 else if (arc_rewrite_small_data_p (x
))
7620 /* Return true if OP is an acceptable memory operand for ARCompact
7621 16-bit gp-relative load instructions.
7622 op shd look like : [r26, symref@sda]
7623 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7625 /* volatile cache option still to be handled. */
7628 compact_sda_memory_operand (rtx op
, machine_mode mode
)
7633 /* Eliminate non-memory operations. */
7634 if (GET_CODE (op
) != MEM
)
7637 if (mode
== VOIDmode
)
7638 mode
= GET_MODE (op
);
7640 size
= GET_MODE_SIZE (mode
);
7642 /* dword operations really put out 2 instructions, so eliminate them. */
7643 if (size
> UNITS_PER_WORD
)
7646 /* Decode the address now. */
7647 addr
= XEXP (op
, 0);
7649 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
);
7652 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7655 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
7656 unsigned HOST_WIDE_INT size
,
7657 unsigned HOST_WIDE_INT align
,
7658 unsigned HOST_WIDE_INT globalize_p
)
7660 int in_small_data
= arc_in_small_data_p (decl
);
7663 switch_to_section (get_named_section (NULL
, ".sbss", 0));
7664 /* named_section (0,".sbss",0); */
7666 switch_to_section (bss_section
);
7669 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
7671 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
7672 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
7673 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
7674 ASM_OUTPUT_LABEL (stream
, name
);
7677 ASM_OUTPUT_SKIP (stream
, size
);
7681 arc_preserve_reload_p (rtx in
)
7683 return (GET_CODE (in
) == PLUS
7684 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
7685 && CONST_INT_P (XEXP (in
, 1))
7686 && !((INTVAL (XEXP (in
, 1)) & 511)));
7690 arc_register_move_cost (machine_mode
,
7691 enum reg_class from_class
, enum reg_class to_class
)
7693 /* The ARC600 has no bypass for extension registers, hence a nop might be
7694 needed to be inserted after a write so that reads are safe. */
7697 if (to_class
== MPY_WRITABLE_CORE_REGS
)
7699 /* Instructions modifying LP_COUNT need 4 additional cycles before
7700 the register will actually contain the value. */
7701 else if (to_class
== LPCOUNT_REG
)
7703 else if (to_class
== WRITABLE_CORE_REGS
)
7707 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7709 && (from_class
== LPCOUNT_REG
|| from_class
== ALL_CORE_REGS
7710 || from_class
== WRITABLE_CORE_REGS
))
7713 /* Force an attempt to 'mov Dy,Dx' to spill. */
7714 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
7715 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
7721 /* Emit code for an addsi3 instruction with OPERANDS.
7722 COND_P indicates if this will use conditional execution.
7723 Return the length of the instruction.
7724 If OUTPUT_P is false, don't actually output the instruction, just return
7727 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
7731 int match
= operands_match_p (operands
[0], operands
[1]);
7732 int match2
= operands_match_p (operands
[0], operands
[2]);
7733 int intval
= (REG_P (operands
[2]) ? 1
7734 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
7735 int neg_intval
= -intval
;
7736 int short_0
= satisfies_constraint_Rcq (operands
[0]);
7737 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
7740 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
7741 && REGNO (OP) != 30) \
7744 #define ADDSI_OUTPUT1(FORMAT) do {\
7746 output_asm_insn (FORMAT, operands);\
7749 #define ADDSI_OUTPUT(LIST) do {\
7752 ADDSI_OUTPUT1 (format);\
7756 /* First try to emit a 16 bit insn. */
7759 /* If we are actually about to output this insn, don't try a 16 bit
7760 variant if we already decided that we don't want that
7761 (I.e. we upsized this insn to align some following insn.)
7762 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7763 but add1 r0,sp,35 doesn't. */
7764 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
7766 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
7769 && ((REG_H_P (operands
[2])
7770 && (match
|| satisfies_constraint_Rcq (operands
[2])))
7771 || (CONST_INT_P (operands
[2])
7772 && ((unsigned) intval
<= (match
? 127 : 7)))))
7773 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
7775 /* Generate add_s b,b,h patterns. */
7776 if (short_0
&& match2
&& REG_H_P (operands
[1]))
7777 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
7779 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
7780 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
7781 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
7782 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
7784 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
7785 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
7786 && match
&& !(neg_intval
& ~124)))
7787 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
7789 /* Generate add_s h,h,s3 patterns. */
7790 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
7791 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
7792 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
7794 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
7795 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
7796 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
7797 && satisfies_constraint_Rcq (operands
[1])
7798 && satisfies_constraint_L (operands
[2]))
7799 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
7802 /* Now try to emit a 32 bit insn without long immediate. */
7804 if (!match
&& match2
&& REG_P (operands
[1]))
7805 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7806 if (match
|| !cond_p
)
7808 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
7809 int range_factor
= neg_intval
& intval
;
7812 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
7813 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7815 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7816 same size, do, so - the insn latency is lower. */
7817 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7819 if ((intval
>= 0 && intval
<= limit
)
7820 || (intval
== -0x800 && limit
== 0x7ff))
7821 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7822 else if ((intval
< 0 && neg_intval
<= limit
)
7823 || (intval
== 0x800 && limit
== 0x7ff))
7824 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7825 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
7826 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
7827 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
7828 if (((intval
< 0 && intval
!= -0x4000)
7829 /* sub[123] is slower than add_s / sub, only use it if it
7830 avoids a long immediate. */
7831 && neg_intval
<= limit
<< shift
)
7832 || (intval
== 0x4000 && limit
== 0x7ff))
7833 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
7834 shift
, neg_intval
>> shift
));
7835 else if ((intval
>= 0 && intval
<= limit
<< shift
)
7836 || (intval
== -0x4000 && limit
== 0x7ff))
7837 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
7839 /* Try to emit a 16 bit opcode with long immediate. */
7841 if (short_p
&& match
)
7842 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7844 /* We have to use a 32 bit opcode, and with a long immediate. */
7846 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7849 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
7850 Return the length of the instruction.
7851 If OUTPUT_P is false, don't actually output the instruction, just return
7854 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
7856 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
7857 const char *pat
= NULL
;
7859 /* Canonical rtl should not have a constant in the first operand position. */
7860 gcc_assert (!CONSTANT_P (operands
[1]));
7862 switch (commutative_op
)
7865 if (satisfies_constraint_C1p (operands
[2]))
7866 pat
= "bmsk%? %0,%1,%Z2";
7867 else if (satisfies_constraint_C2p (operands
[2]))
7869 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
7870 pat
= "bmskn%? %0,%1,%Z2";
7872 else if (satisfies_constraint_Ccp (operands
[2]))
7873 pat
= "bclr%? %0,%1,%M2";
7874 else if (satisfies_constraint_CnL (operands
[2]))
7875 pat
= "bic%? %0,%1,%n2-1";
7878 if (satisfies_constraint_C0p (operands
[2]))
7879 pat
= "bset%? %0,%1,%z2";
7882 if (satisfies_constraint_C0p (operands
[2]))
7883 pat
= "bxor%? %0,%1,%z2";
7886 return arc_output_addsi (operands
, true, output_p
);
7890 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
7891 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
7896 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7897 Emit code and return an potentially modified address such that offsets
7898 up to SIZE are can be added to yield a legitimate address.
7899 if REUSE is set, ADDR is a register that may be modified. */
7902 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
7905 rtx offs
= const0_rtx
;
7907 if (GET_CODE (base
) == PLUS
)
7909 offs
= XEXP (base
, 1);
7910 base
= XEXP (base
, 0);
7913 || (REGNO (base
) != STACK_POINTER_REGNUM
7914 && REGNO_PTR_FRAME_P (REGNO (base
)))
7915 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
7916 || !SMALL_INT (INTVAL (offs
) + size
))
7919 emit_insn (gen_add2_insn (addr
, offs
));
7921 addr
= copy_to_mode_reg (Pmode
, addr
);
7926 /* Like move_by_pieces, but take account of load latency, and actual
7927 offset ranges. Return true on success. */
7930 arc_expand_movmem (rtx
*operands
)
7932 rtx dst
= operands
[0];
7933 rtx src
= operands
[1];
7934 rtx dst_addr
, src_addr
;
7936 int align
= INTVAL (operands
[3]);
7943 if (!CONST_INT_P (operands
[2]))
7945 size
= INTVAL (operands
[2]);
7946 /* move_by_pieces_ninsns is static, so we can't use it. */
7950 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
7952 n_pieces
= (size
+ 2) / 4U + (size
& 1);
7954 else if (align
== 2)
7955 n_pieces
= (size
+ 1) / 2U;
7958 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
7960 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7962 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
7966 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
7967 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
7968 store
[0] = store
[1] = NULL_RTX
;
7969 tmpx
[0] = tmpx
[1] = NULL_RTX
;
7970 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
7975 while (piece
> size
)
7977 mode
= smallest_mode_for_size (piece
* BITS_PER_UNIT
, MODE_INT
);
7978 /* If we don't re-use temporaries, the scheduler gets carried away,
7979 and the register pressure gets unnecessarily high. */
7980 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
7983 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
7984 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
7985 src_addr
= force_offsettable (src_addr
, piece
, 1);
7987 emit_insn (store
[i
]);
7988 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
7989 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
7990 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
7991 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
7994 emit_insn (store
[i
]);
7996 emit_insn (store
[i
^1]);
8000 /* Prepare operands for move in MODE. Return true iff the move has
8004 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8006 /* We used to do this only for MODE_INT Modes, but addresses to floating
8007 point variables may well be in the small data section. */
8008 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[0], Pmode
))
8009 operands
[0] = arc_rewrite_small_data (operands
[0]);
8011 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
8013 prepare_pic_move (operands
, SImode
);
8015 /* Disable any REG_EQUALs associated with the symref
8016 otherwise the optimization pass undoes the work done
8017 here and references the variable directly. */
8020 if (GET_CODE (operands
[0]) != MEM
8021 && !TARGET_NO_SDATA_SET
8022 && small_data_pattern (operands
[1], Pmode
))
8024 /* This is to take care of address calculations involving sdata
8026 operands
[1] = arc_rewrite_small_data (operands
[1]);
8028 emit_insn (gen_rtx_SET (operands
[0],operands
[1]));
8029 /* ??? This note is useless, since it only restates the set itself.
8030 We should rather use the original SYMBOL_REF. However, there is
8031 the problem that we are lying to the compiler about these
8032 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8033 so that we can tell it apart from an actual symbol. */
8034 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8036 /* Take care of the REG_EQUAL note that will be attached to mark the
8037 output reg equal to the initial symbol_ref after this code is
8039 emit_move_insn (operands
[0], operands
[0]);
8043 if (MEM_P (operands
[0])
8044 && !(reload_in_progress
|| reload_completed
))
8046 operands
[1] = force_reg (mode
, operands
[1]);
8047 if (!move_dest_operand (operands
[0], mode
))
8049 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
8050 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8051 except that we can't use that function because it is static. */
8052 rtx pat
= change_address (operands
[0], mode
, addr
);
8053 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8056 if (!cse_not_expected
)
8058 rtx pat
= XEXP (operands
[0], 0);
8060 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8063 pat
= change_address (operands
[0], mode
, pat
);
8064 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8070 if (MEM_P (operands
[1]) && !cse_not_expected
)
8072 rtx pat
= XEXP (operands
[1], 0);
8074 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8077 pat
= change_address (operands
[1], mode
, pat
);
8078 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
8086 /* Prepare OPERANDS for an extension using CODE to OMODE.
8087 Return true iff the move has been emitted. */
8090 prepare_extend_operands (rtx
*operands
, enum rtx_code code
,
8093 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[1], Pmode
))
8095 /* This is to take care of address calculations involving sdata
8098 = gen_rtx_fmt_e (code
, omode
, arc_rewrite_small_data (operands
[1]));
8099 emit_insn (gen_rtx_SET (operands
[0], operands
[1]));
8100 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8102 /* Take care of the REG_EQUAL note that will be attached to mark the
8103 output reg equal to the initial extension after this code is
8105 emit_move_insn (operands
[0], operands
[0]);
8111 /* Output a library call to a function called FNAME that has been arranged
8112 to be local to any dso. */
8115 arc_output_libcall (const char *fname
)
8117 unsigned len
= strlen (fname
);
8118 static char buf
[64];
8120 gcc_assert (len
< sizeof buf
- 35);
8121 if (TARGET_LONG_CALLS_SET
8122 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
8125 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
8127 sprintf (buf
, "jl%%! @%s", fname
);
8130 sprintf (buf
, "bl%%!%%* @%s", fname
);
8134 /* Return the SImode highpart of the DImode value IN. */
8137 disi_highpart (rtx in
)
8139 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
8142 /* Return length adjustment for INSN.
8144 A write to a core reg greater or equal to 32 must not be immediately
8145 followed by a use. Anticipate the length requirement to insert a nop
8146 between PRED and SUCC to prevent a hazard. */
8149 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8153 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
8154 in front of SUCC anyway, so there will be separation between PRED and
8156 if (recog_memoized (succ
) == CODE_FOR_doloop_end_i
8157 && LABEL_P (prev_nonnote_insn (succ
)))
8159 if (recog_memoized (succ
) == CODE_FOR_doloop_begin_i
)
8161 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8162 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
8163 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
8164 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
8165 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
8166 || recog_memoized (pred
) == CODE_FOR_umul_600
8167 || recog_memoized (pred
) == CODE_FOR_mac_600
8168 || recog_memoized (pred
) == CODE_FOR_mul64_600
8169 || recog_memoized (pred
) == CODE_FOR_mac64_600
8170 || recog_memoized (pred
) == CODE_FOR_umul64_600
8171 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
8173 subrtx_iterator::array_type array
;
8174 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
8176 const_rtx x
= *iter
;
8177 switch (GET_CODE (x
))
8179 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8182 /* This is also fine for PRE/POST_MODIFY, because they
8186 rtx dest
= XEXP (x
, 0);
8187 /* Check if this sets a an extension register. N.B. we use 61 for the
8188 condition codes, which is definitely not an extension register. */
8189 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
8190 /* Check if the same register is used by the PAT. */
8191 && (refers_to_regno_p
8193 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
8194 PATTERN (succ
), 0)))
8200 /* Given a rtx, check if it is an assembly instruction or not. */
8203 arc_asm_insn_p (rtx x
)
8210 switch (GET_CODE (x
))
8217 return arc_asm_insn_p (SET_SRC (x
));
8221 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8222 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
8234 /* We might have a CALL to a non-returning function before a loop end.
8235 ??? Although the manual says that's OK (the target is outside the
8236 loop, and the loop counter unused there), the assembler barfs on
8237 this for ARC600, so we must insert a nop before such a call too.
8238 For ARC700, and ARCv2 is not allowed to have the last ZOL
8239 instruction a jump to a location where lp_count is modified. */
8242 arc_loop_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8244 rtx_insn
*jump
= NULL
;
8245 rtx label_rtx
= NULL_RTX
;
8246 rtx_insn
*label
= NULL
;
8247 basic_block succ_bb
;
8249 if (recog_memoized (succ
) != CODE_FOR_doloop_end_i
)
8252 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
8253 (i.e., jump/call) as the last instruction of a ZOL. */
8254 if (TARGET_ARC600
|| TARGET_HS
)
8255 if (JUMP_P (pred
) || CALL_P (pred
)
8256 || arc_asm_insn_p (PATTERN (pred
))
8257 || GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8260 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
8261 instruction a jump to a location where lp_count is modified. */
8263 /* Phase 2a: Dig for the jump instruction. */
8266 else if (GET_CODE (PATTERN (pred
)) == SEQUENCE
8267 && JUMP_P (XVECEXP (PATTERN (pred
), 0, 0)))
8268 jump
= as_a
<rtx_insn
*> (XVECEXP (PATTERN (pred
), 0, 0));
8272 /* Phase 2b: Make sure is not a millicode jump. */
8273 if ((GET_CODE (PATTERN (jump
)) == PARALLEL
)
8274 && (XVECEXP (PATTERN (jump
), 0, 0) == ret_rtx
))
8277 label_rtx
= JUMP_LABEL (jump
);
8281 /* Phase 2c: Make sure is not a return. */
8282 if (ANY_RETURN_P (label_rtx
))
8285 /* Pahse 2d: Go to the target of the jump and check for aliveness of
8286 LP_COUNT register. */
8287 label
= safe_as_a
<rtx_insn
*> (label_rtx
);
8288 succ_bb
= BLOCK_FOR_INSN (label
);
8291 gcc_assert (NEXT_INSN (label
));
8292 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label
)))
8293 succ_bb
= NOTE_BASIC_BLOCK (NEXT_INSN (label
));
8295 succ_bb
= BLOCK_FOR_INSN (NEXT_INSN (label
));
8298 if (succ_bb
&& REGNO_REG_SET_P (df_get_live_out (succ_bb
), LP_COUNT
))
8305 A write to a core reg greater or equal to 32 must not be immediately
8306 followed by a use. Anticipate the length requirement to insert a nop
8307 between PRED and SUCC to prevent a hazard. */
8310 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8312 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
8315 if (arc_loop_hazard (pred
, succ
))
8319 return arc600_corereg_hazard (pred
, succ
);
8324 /* Return length adjustment for INSN. */
8327 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
8331 /* We already handle sequences by ignoring the delay sequence flag. */
8332 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8335 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
8336 the ZOL mechanism only triggers when advancing to the end address,
8337 so if there's a label at the end of a ZOL, we need to insert a nop.
8338 The ARC600 ZOL also has extra restrictions on jumps at the end of a
8340 if (recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
8342 rtx_insn
*prev
= prev_nonnote_insn (insn
);
8344 return ((LABEL_P (prev
)
8347 || CALL_P (prev
) /* Could be a noreturn call. */
8348 || (NONJUMP_INSN_P (prev
)
8349 && GET_CODE (PATTERN (prev
)) == SEQUENCE
))))
8353 /* Check for return with but one preceding insn since function
8355 if (TARGET_PAD_RETURN
8357 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
8358 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
8359 && get_attr_type (insn
) == TYPE_RETURN
)
8361 rtx_insn
*prev
= prev_active_insn (insn
);
8363 if (!prev
|| !(prev
= prev_active_insn (prev
))
8364 || ((NONJUMP_INSN_P (prev
)
8365 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8366 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8368 : CALL_ATTR (prev
, NON_SIBCALL
)))
8373 rtx_insn
*succ
= next_real_insn (insn
);
8375 /* One the ARC600, a write to an extension register must be separated
8377 if (succ
&& INSN_P (succ
))
8378 len
+= arc600_corereg_hazard (insn
, succ
);
8381 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8383 extract_constrain_insn_cached (insn
);
8388 /* Values for length_sensitive. */
8392 ARC_LS_25
, // 25 bit offset, B
8393 ARC_LS_21
, // 21 bit offset, Bcc
8394 ARC_LS_U13
,// 13 bit unsigned offset, LP
8395 ARC_LS_10
, // 10 bit offset, B_s, Beq_s, Bne_s
8396 ARC_LS_9
, // 9 bit offset, BRcc
8397 ARC_LS_8
, // 8 bit offset, BRcc_s
8398 ARC_LS_U7
, // 7 bit unsigned offset, LPcc
8399 ARC_LS_7
// 7 bit offset, Bcc_s
8402 /* While the infrastructure patch is waiting for review, duplicate the
8403 struct definitions, to allow this file to compile. */
8408 /* Cost as a branch / call target or call return address. */
8410 int fallthrough_cost
;
8413 /* 0 for not length sensitive, 1 for largest offset range,
8414 * 2 for next smaller etc. */
8415 unsigned length_sensitive
: 8;
8417 } insn_length_variant_t
;
8419 typedef struct insn_length_parameters_s
8424 int (*get_variants
) (rtx_insn
*, int, bool, bool, insn_length_variant_t
*);
8425 } insn_length_parameters_t
;
8428 arc_insn_length_parameters (insn_length_parameters_t
*ilp
) ATTRIBUTE_UNUSED
;
8432 arc_get_insn_variants (rtx_insn
*insn
, int len
, bool, bool target_p
,
8433 insn_length_variant_t
*ilv
)
8435 if (!NONDEBUG_INSN_P (insn
))
8437 enum attr_type type
;
8438 /* shorten_branches doesn't take optimize_size into account yet for the
8439 get_variants mechanism, so turn this off for now. */
8442 if (rtx_sequence
*pat
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
8444 /* The interaction of a short delay slot insn with a short branch is
8445 too weird for shorten_branches to piece together, so describe the
8448 if (TARGET_UPSIZE_DBR
8449 && get_attr_length (pat
->insn (1)) <= 2
8450 && (((type
= get_attr_type (inner
= pat
->insn (0)))
8451 == TYPE_UNCOND_BRANCH
)
8452 || type
== TYPE_BRANCH
)
8453 && get_attr_delay_slot_filled (inner
) == DELAY_SLOT_FILLED_YES
)
8456 = arc_get_insn_variants (inner
, get_attr_length (inner
), true,
8458 /* The short variant gets split into a higher-cost aligned
8459 and a lower cost unaligned variant. */
8460 gcc_assert (n_variants
);
8461 gcc_assert (ilv
[1].length_sensitive
== ARC_LS_7
8462 || ilv
[1].length_sensitive
== ARC_LS_10
);
8463 gcc_assert (ilv
[1].align_set
== 3);
8465 ilv
[0].align_set
= 1;
8466 ilv
[0].branch_cost
+= 1;
8467 ilv
[1].align_set
= 2;
8469 for (int i
= 0; i
< n_variants
; i
++)
8471 /* In case an instruction with aligned size is wanted, and
8472 the short variants are unavailable / too expensive, add
8473 versions of long branch + long delay slot. */
8474 for (int i
= 2, end
= n_variants
; i
< end
; i
++, n_variants
++)
8476 ilv
[n_variants
] = ilv
[i
];
8477 ilv
[n_variants
].length
+= 2;
8483 insn_length_variant_t
*first_ilv
= ilv
;
8484 type
= get_attr_type (insn
);
8486 = (get_attr_delay_slot_filled (insn
) == DELAY_SLOT_FILLED_YES
);
8487 int branch_align_cost
= delay_filled
? 0 : 1;
8488 int branch_unalign_cost
= delay_filled
? 0 : TARGET_UNALIGN_BRANCH
? 0 : 1;
8489 /* If the previous instruction is an sfunc call, this insn is always
8490 a target, even though the middle-end is unaware of this. */
8491 bool force_target
= false;
8492 rtx_insn
*prev
= prev_active_insn (insn
);
8493 if (prev
&& arc_next_active_insn (prev
, 0) == insn
8494 && ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8495 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8497 : (CALL_ATTR (prev
, NON_SIBCALL
)
8498 && NEXT_INSN (PREV_INSN (prev
)) == prev
)))
8499 force_target
= true;
8504 /* Short BRCC only comes in no-delay-slot version, and without limm */
8509 ilv
->branch_cost
= 1;
8510 ilv
->enabled
= (len
== 2);
8511 ilv
->length_sensitive
= ARC_LS_8
;
8515 case TYPE_BRCC_NO_DELAY_SLOT
:
8516 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8517 (delay slot) scheduling purposes, but they are longer. */
8518 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8519 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 1)) == SET
)
8521 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8522 ilv
->length
= ((type
== TYPE_BRCC
) ? 4 : 8);
8524 ilv
->branch_cost
= branch_align_cost
;
8525 ilv
->enabled
= (len
<= ilv
->length
);
8526 ilv
->length_sensitive
= ARC_LS_9
;
8527 if ((target_p
|| force_target
)
8528 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8534 ilv
->target_cost
= 1;
8535 ilv
->branch_cost
= branch_unalign_cost
;
8540 op
= XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 0);
8543 if (GET_CODE (op0
) == ZERO_EXTRACT
8544 && satisfies_constraint_L (XEXP (op0
, 2)))
8545 op0
= XEXP (op0
, 0);
8546 if (satisfies_constraint_Rcq (op0
))
8548 ilv
->length
= ((type
== TYPE_BRCC
) ? 6 : 10);
8550 ilv
->branch_cost
= 1 + branch_align_cost
;
8551 ilv
->fallthrough_cost
= 1;
8552 ilv
->enabled
= true;
8553 ilv
->length_sensitive
= ARC_LS_21
;
8554 if (!delay_filled
&& TARGET_UNALIGN_BRANCH
)
8560 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8564 ilv
->length
= ((type
== TYPE_BRCC
) ? 8 : 12);
8566 ilv
->branch_cost
= 1 + branch_align_cost
;
8567 ilv
->fallthrough_cost
= 1;
8568 ilv
->enabled
= true;
8569 ilv
->length_sensitive
= ARC_LS_21
;
8570 if ((target_p
|| force_target
)
8571 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8577 ilv
->target_cost
= 1;
8578 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8586 case TYPE_CALL_NO_DELAY_SLOT
:
8591 ilv
->length_sensitive
8592 = GET_CODE (PATTERN (insn
)) == COND_EXEC
? ARC_LS_21
: ARC_LS_25
;
8595 ilv
->fallthrough_cost
= branch_align_cost
;
8596 ilv
->enabled
= true;
8597 if ((target_p
|| force_target
)
8598 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8604 ilv
->target_cost
= 1;
8605 ilv
->fallthrough_cost
= branch_unalign_cost
;
8609 case TYPE_UNCOND_BRANCH
:
8610 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8611 but that makes no difference at the moment. */
8612 ilv
->length_sensitive
= ARC_LS_7
;
8613 ilv
[1].length_sensitive
= ARC_LS_25
;
8616 ilv
->length_sensitive
= ARC_LS_10
;
8617 ilv
[1].length_sensitive
= ARC_LS_21
;
8621 ilv
->branch_cost
= branch_align_cost
;
8622 ilv
->enabled
= (len
== ilv
->length
);
8626 ilv
->branch_cost
= branch_align_cost
;
8627 ilv
->enabled
= true;
8628 if ((target_p
|| force_target
)
8629 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8635 ilv
->target_cost
= 1;
8636 ilv
->branch_cost
= branch_unalign_cost
;
8643 /* For every short insn, there is generally also a long insn.
8644 trap_s is an exception. */
8645 if ((len
& 2) == 0 || recog_memoized (insn
) == CODE_FOR_trap_s
)
8652 ilv
->length
= len
+ 2;
8654 if (target_p
|| force_target
)
8660 ilv
->target_cost
= 1;
8664 /* If the previous instruction is an sfunc call, this insn is always
8665 a target, even though the middle-end is unaware of this.
8666 Therefore, if we have a call predecessor, transfer the target cost
8667 to the fallthrough and branch costs. */
8670 for (insn_length_variant_t
*p
= first_ilv
; p
< ilv
; p
++)
8672 p
->fallthrough_cost
+= p
->target_cost
;
8673 p
->branch_cost
+= p
->target_cost
;
8678 return ilv
- first_ilv
;
8682 arc_insn_length_parameters (insn_length_parameters_t
*ilp
)
8684 ilp
->align_unit_log
= 1;
8685 ilp
->align_base_log
= 1;
8686 ilp
->max_variants
= 7;
8687 ilp
->get_variants
= arc_get_insn_variants
;
8690 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8691 CC field of *STATEP. */
8694 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8696 rtx cond
= statep
->cond
;
8697 int raw_cc
= get_arc_condition_code (cond
);
8699 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8701 if (statep
->cc
== raw_cc
)
8702 return copy_rtx (cond
);
8704 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8706 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8707 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8708 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8709 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8711 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8712 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8715 /* Return version of PAT conditionalized with COND, which is part of INSN.
8716 ANNULLED indicates if INSN is an annulled delay-slot insn.
8717 Register further changes if necessary. */
8719 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8721 /* For commutative operators, we generally prefer to have
8722 the first source match the destination. */
8723 if (GET_CODE (pat
) == SET
)
8725 rtx src
= SET_SRC (pat
);
8727 if (COMMUTATIVE_P (src
))
8729 rtx src0
= XEXP (src
, 0);
8730 rtx src1
= XEXP (src
, 1);
8731 rtx dst
= SET_DEST (pat
);
8733 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8734 /* Leave add_n alone - the canonical form is to
8735 have the complex summand first. */
8737 pat
= gen_rtx_SET (dst
,
8738 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8743 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8744 what to do with COND_EXEC. */
8745 if (RTX_FRAME_RELATED_P (insn
))
8747 /* If this is the delay slot insn of an anulled branch,
8748 dwarf2out.c:scan_trace understands the anulling semantics
8749 without the COND_EXEC. */
8750 gcc_assert (annulled
);
8751 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8753 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8755 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8759 /* Use the ccfsm machinery to do if conversion. */
8764 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8765 basic_block merge_bb
= 0;
8767 memset (statep
, 0, sizeof *statep
);
8768 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8770 arc_ccfsm_advance (insn
, statep
);
8772 switch (statep
->state
)
8780 /* Deleted branch. */
8781 gcc_assert (!merge_bb
);
8782 merge_bb
= BLOCK_FOR_INSN (insn
);
8784 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn
))));
8785 arc_ccfsm_post_advance (insn
, statep
);
8786 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8787 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8790 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8791 rtx pat
= PATTERN (slot
);
8792 if (INSN_ANNULLED_BRANCH_P (insn
))
8795 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8796 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8798 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8800 PUT_CODE (slot
, NOTE
);
8801 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
8802 if (merge_bb
&& succ_bb
)
8803 merge_blocks (merge_bb
, succ_bb
);
8805 else if (merge_bb
&& succ_bb
)
8807 set_insn_deleted (insn
);
8808 merge_blocks (merge_bb
, succ_bb
);
8812 PUT_CODE (insn
, NOTE
);
8813 NOTE_KIND (insn
) = NOTE_INSN_DELETED
;
8819 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
8821 arc_ccfsm_post_advance (insn
, statep
);
8822 basic_block succ_bb
= BLOCK_FOR_INSN (insn
);
8823 if (merge_bb
&& succ_bb
)
8824 merge_blocks (merge_bb
, succ_bb
);
8825 else if (--LABEL_NUSES (insn
) == 0)
8827 const char *name
= LABEL_NAME (insn
);
8828 PUT_CODE (insn
, NOTE
);
8829 NOTE_KIND (insn
) = NOTE_INSN_DELETED_LABEL
;
8830 NOTE_DELETED_LABEL_NAME (insn
) = name
;
8837 if (!NONDEBUG_INSN_P (insn
))
8840 /* Conditionalized insn. */
8842 rtx_insn
*prev
, *pprev
;
8843 rtx
*patp
, pat
, cond
;
8844 bool annulled
; annulled
= false;
8846 /* If this is a delay slot insn in a non-annulled branch,
8847 don't conditionalize it. N.B., this should be fine for
8848 conditional return too. However, don't do this for
8849 unconditional branches, as these would be encountered when
8850 processing an 'else' part. */
8851 prev
= PREV_INSN (insn
);
8852 pprev
= PREV_INSN (prev
);
8853 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
8854 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
8856 if (!INSN_ANNULLED_BRANCH_P (prev
))
8861 patp
= &PATTERN (insn
);
8863 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
8864 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
8866 /* ??? don't conditionalize if all side effects are dead
8867 in the not-execute case. */
8869 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
8871 else if (simplejump_p (insn
))
8873 patp
= &SET_SRC (pat
);
8874 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
8876 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
8878 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
8879 pat
= gen_rtx_SET (pc_rtx
, pat
);
8883 validate_change (insn
, patp
, pat
, 1);
8884 if (!apply_change_group ())
8888 rtx_insn
*next
= next_nonnote_insn (insn
);
8889 if (GET_CODE (next
) == BARRIER
)
8891 if (statep
->state
== 3)
8898 arc_ccfsm_post_advance (insn
, statep
);
8903 /* Find annulled delay insns and convert them to use the appropriate predicate.
8904 This allows branch shortening to size up these insns properly. */
8907 arc_predicate_delay_insns (void)
8909 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8911 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
8914 if (!NONJUMP_INSN_P (insn
)
8915 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
8917 jump
= XVECEXP (pat
, 0, 0);
8918 dlay
= XVECEXP (pat
, 0, 1);
8919 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
8921 /* If the branch insn does the annulling, leave the delay insn alone. */
8922 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
8924 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8925 on the other path. */
8926 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
8927 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
8928 src
= SET_SRC (PATTERN (jump
));
8929 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
8930 cond
= XEXP (src
, 0);
8931 if (XEXP (src
, 2) == pc_rtx
)
8933 else if (XEXP (src
, 1) == pc_rtx
)
8937 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
8939 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8940 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8941 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8942 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8944 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8945 copy_rtx (XEXP (cond
, 0)),
8946 copy_rtx (XEXP (cond
, 1)));
8949 cond
= copy_rtx (cond
);
8950 patp
= &PATTERN (dlay
);
8952 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
8953 validate_change (dlay
, patp
, pat
, 1);
8954 if (!apply_change_group ())
8960 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
8961 (other than of a forward brcc), it creates a hazard when there is a read
8962 of the same register at the branch target. We can't know what is at the
8963 branch target of calls, and for branches, we don't really know before the
8964 end of delay slot scheduling, either. Not only can individual instruction
8965 be hoisted out into a delay slot, a basic block can also be emptied this
8966 way, and branch and/or fall through targets be redirected. Hence we don't
8967 want such writes in a delay slot. */
8969 /* Return nonzreo iff INSN writes to an extension core register. */
8972 arc_write_ext_corereg (rtx insn
)
8974 subrtx_iterator::array_type array
;
8975 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
8977 const_rtx x
= *iter
;
8978 switch (GET_CODE (x
))
8980 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8983 /* This is also fine for PRE/POST_MODIFY, because they
8987 const_rtx dest
= XEXP (x
, 0);
8988 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
8994 /* This is like the hook, but returns NULL when it can't / won't generate
8995 a legitimate address. */
8998 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9003 if (flag_pic
&& SYMBOLIC_CONST (x
))
9004 (x
) = arc_legitimize_pic_address (x
, 0);
9006 if (GET_CODE (addr
) == CONST
)
9007 addr
= XEXP (addr
, 0);
9008 if (GET_CODE (addr
) == PLUS
9009 && CONST_INT_P (XEXP (addr
, 1))
9010 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9011 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9012 || (REG_P (XEXP (addr
, 0))
9013 && (INTVAL (XEXP (addr
, 1)) & 252))))
9015 HOST_WIDE_INT offs
, upper
;
9016 int size
= GET_MODE_SIZE (mode
);
9018 offs
= INTVAL (XEXP (addr
, 1));
9019 upper
= (offs
+ 256 * size
) & ~511 * size
;
9020 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9021 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9022 if (GET_CODE (x
) == CONST
)
9023 inner
= gen_rtx_CONST (Pmode
, inner
);
9025 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9028 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9029 x
= force_reg (Pmode
, x
);
9030 if (memory_address_p ((machine_mode
) mode
, x
))
9036 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9038 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9040 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9042 return arc_legitimize_tls_address (orig_x
, model
);
9045 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9053 arc_delegitimize_address_0 (rtx x
)
9057 if (GET_CODE (x
) == CONST
&& GET_CODE (u
= XEXP (x
, 0)) == UNSPEC
)
9059 if (XINT (u
, 1) == ARC_UNSPEC_GOT
9060 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
)
9061 return XVECEXP (u
, 0, 0);
9063 else if (GET_CODE (x
) == CONST
&& GET_CODE (p
= XEXP (x
, 0)) == PLUS
9064 && GET_CODE (u
= XEXP (p
, 0)) == UNSPEC
9065 && (XINT (u
, 1) == ARC_UNSPEC_GOT
9066 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
))
9067 return gen_rtx_CONST
9069 gen_rtx_PLUS (GET_MODE (p
), XVECEXP (u
, 0, 0), XEXP (p
, 1)));
9070 else if (GET_CODE (x
) == PLUS
9071 && ((REG_P (gp
= XEXP (x
, 0))
9072 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9073 || (GET_CODE (gp
) == CONST
9074 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9075 && XINT (u
, 1) == ARC_UNSPEC_GOT
9076 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9077 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9078 && GET_CODE (XEXP (x
, 1)) == CONST
9079 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9080 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9081 return XVECEXP (u
, 0, 0);
9082 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 0)) == PLUS
9083 && ((REG_P (gp
= XEXP (XEXP (x
, 0), 1))
9084 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9085 || (GET_CODE (gp
) == CONST
9086 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9087 && XINT (u
, 1) == ARC_UNSPEC_GOT
9088 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9089 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9090 && GET_CODE (XEXP (x
, 1)) == CONST
9091 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9092 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9093 return gen_rtx_PLUS (GET_MODE (x
), XEXP (XEXP (x
, 0), 0),
9095 else if (GET_CODE (x
) == PLUS
9096 && (u
= arc_delegitimize_address_0 (XEXP (x
, 1))))
9097 return gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0), u
);
9102 arc_delegitimize_address (rtx x
)
9104 rtx orig_x
= x
= delegitimize_mem_from_attrs (x
);
9105 if (GET_CODE (x
) == MEM
)
9107 x
= arc_delegitimize_address_0 (x
);
9111 x
= replace_equiv_address_nv (orig_x
, x
);
9117 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9118 differ from the hardware register number in order to allow the generic
9119 code to correctly split the concatenation of acc1 and acc2. */
9124 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9127 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9128 differ from the hardware register number in order to allow the generic
9129 code to correctly split the concatenation of acc1 and acc2. */
9134 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9137 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9138 differ from the hardware register number in order to allow the generic
9139 code to correctly split the concatenation of mhi and mlo. */
9144 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9147 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9148 differ from the hardware register number in order to allow the generic
9149 code to correctly split the concatenation of mhi and mlo. */
9154 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9157 /* FIXME: a parameter should be added, and code added to final.c,
9158 to reproduce this functionality in shorten_branches. */
9160 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9161 a previous instruction. */
9163 arc_unalign_branch_p (rtx branch
)
9167 if (!TARGET_UNALIGN_BRANCH
)
9169 /* Do not do this if we have a filled delay slot. */
9170 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9171 && !NEXT_INSN (branch
)->deleted ())
9173 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9175 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9176 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9180 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9181 are three reasons why we need to consider branches to be length 6:
9182 - annull-false delay slot insns are implemented using conditional execution,
9183 thus preventing short insn formation where used.
9184 - for ARC600: annul-true delay slot insns are implemented where possible
9185 using conditional execution, preventing short insn formation where used.
9186 - for ARC700: likely or somewhat likely taken branches are made long and
9187 unaligned if possible to avoid branch penalty. */
9190 arc_branch_size_unknown_p (void)
9192 return !optimize_size
&& arc_reorg_in_progress
;
9195 /* We are about to output a return insn. Add padding if necessary to avoid
9196 a mispredict. A return could happen immediately after the function
9197 start, but after a call we know that there will be at least a blink
9201 arc_pad_return (void)
9203 rtx_insn
*insn
= current_output_insn
;
9204 rtx_insn
*prev
= prev_active_insn (insn
);
9209 fputs ("\tnop_s\n", asm_out_file
);
9210 cfun
->machine
->unalign
^= 2;
9213 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9214 because after a call, we'd have to restore blink first. */
9215 else if (GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9219 want_long
= (get_attr_length (prev
) == 2);
9220 prev
= prev_active_insn (prev
);
9223 || ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9224 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9226 : CALL_ATTR (prev
, NON_SIBCALL
)))
9229 cfun
->machine
->size_reason
9230 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9231 else if (TARGET_UNALIGN_BRANCH
&& cfun
->machine
->unalign
)
9233 cfun
->machine
->size_reason
9234 = "Long unaligned jump avoids non-delay slot penalty";
9237 /* Disgorge delay insn, if there is any, and it may be moved. */
9239 /* ??? Annulled would be OK if we can and do conditionalize
9240 the delay slot insn accordingly. */
9241 && !INSN_ANNULLED_BRANCH_P (insn
)
9242 && (get_attr_cond (insn
) != COND_USE
9243 || !reg_set_p (gen_rtx_REG (CCmode
, CC_REG
),
9244 XVECEXP (final_sequence
, 0, 1))))
9246 prev
= as_a
<rtx_insn
*> (XVECEXP (final_sequence
, 0, 1));
9247 gcc_assert (!prev_real_insn (insn
)
9248 || !arc_hazard (prev_real_insn (insn
), prev
));
9249 cfun
->machine
->force_short_suffix
= !want_long
;
9250 rtx save_pred
= current_insn_predicate
;
9251 final_scan_insn (prev
, asm_out_file
, optimize
, 1, NULL
);
9252 cfun
->machine
->force_short_suffix
= -1;
9253 prev
->set_deleted ();
9254 current_output_insn
= insn
;
9255 current_insn_predicate
= save_pred
;
9258 fputs ("\tnop\n", asm_out_file
);
9261 fputs ("\tnop_s\n", asm_out_file
);
9262 cfun
->machine
->unalign
^= 2;
9268 /* The usual; we set up our machine_function data. */
9270 static struct machine_function
*
9271 arc_init_machine_status (void)
9273 struct machine_function
*machine
;
9274 machine
= ggc_cleared_alloc
<machine_function
> ();
9275 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9276 machine
->force_short_suffix
= -1;
9281 /* Implements INIT_EXPANDERS. We just set up to call the above
9285 arc_init_expanders (void)
9287 init_machine_status
= arc_init_machine_status
;
9290 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9291 indicates a number of elements to ignore - that allows to have a
9292 sibcall pattern that starts with (return). LOAD_P is zero for store
9293 multiple (for prologues), and one for load multiples (for epilogues),
9294 and two for load multiples where no final clobber of blink is required.
9295 We also skip the first load / store element since this is supposed to
9296 be checked in the instruction pattern. */
9299 arc_check_millicode (rtx op
, int offset
, int load_p
)
9301 int len
= XVECLEN (op
, 0) - offset
;
9306 if (len
< 2 || len
> 13)
9312 rtx elt
= XVECEXP (op
, 0, --len
);
9314 if (GET_CODE (elt
) != CLOBBER
9315 || !REG_P (XEXP (elt
, 0))
9316 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9317 || len
< 3 || len
> 13)
9320 for (i
= 1; i
< len
; i
++)
9322 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9325 if (GET_CODE (elt
) != SET
)
9327 mem
= XEXP (elt
, load_p
);
9328 reg
= XEXP (elt
, 1-load_p
);
9329 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9331 addr
= XEXP (mem
, 0);
9332 if (GET_CODE (addr
) != PLUS
9333 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9334 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9340 /* Accessor functions for cfun->machine->unalign. */
9343 arc_get_unalign (void)
9345 return cfun
->machine
->unalign
;
9349 arc_clear_unalign (void)
9352 cfun
->machine
->unalign
= 0;
9356 arc_toggle_unalign (void)
9358 cfun
->machine
->unalign
^= 2;
9361 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9362 constant in operand 2, but which would require a LIMM because of
9364 operands 3 and 4 are new SET_SRCs for operands 0. */
9367 split_addsi (rtx
*operands
)
9369 int val
= INTVAL (operands
[2]);
9371 /* Try for two short insns first. Lengths being equal, we prefer
9372 expansions with shorter register lifetimes. */
9373 if (val
> 127 && val
<= 255
9374 && satisfies_constraint_Rcq (operands
[0]))
9376 operands
[3] = operands
[2];
9377 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9381 operands
[3] = operands
[1];
9382 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9386 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9387 constant in operand 1, but which would require a LIMM because of
9389 operands 3 and 4 are new SET_SRCs for operands 0. */
9392 split_subsi (rtx
*operands
)
9394 int val
= INTVAL (operands
[1]);
9396 /* Try for two short insns first. Lengths being equal, we prefer
9397 expansions with shorter register lifetimes. */
9398 if (satisfies_constraint_Rcq (operands
[0])
9399 && satisfies_constraint_Rcq (operands
[2]))
9401 if (val
>= -31 && val
<= 127)
9403 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9404 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9407 else if (val
>= 0 && val
< 255)
9409 operands
[3] = operands
[1];
9410 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9414 /* If the destination is not an ARCompact16 register, we might
9415 still have a chance to make a short insn if the source is;
9416 we need to start with a reg-reg move for this. */
9417 operands
[3] = operands
[2];
9418 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9421 /* Handle DOUBLE_REGS uses.
9422 Operand 0: destination register
9423 Operand 1: source register */
9426 arc_process_double_reg_moves (rtx
*operands
)
9428 rtx dest
= operands
[0];
9429 rtx src
= operands
[1];
9431 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9432 enum usesDxState state
= none
;
9434 if (refers_to_regno_p (40, 44, src
, 0))
9436 if (refers_to_regno_p (40, 44, dest
, 0))
9438 /* Via arc_register_move_cost, we should never see D,D moves. */
9439 gcc_assert (state
== none
);
9448 /* Without the LR insn, we need to split this into a
9449 sequence of insns which will use the DEXCLx and DADDHxy
9450 insns to be able to read the Dx register in question. */
9451 if (TARGET_DPFP_DISABLE_LRSR
)
9453 /* gen *movdf_insn_nolrsr */
9454 rtx set
= gen_rtx_SET (dest
, src
);
9455 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9456 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9460 /* When we have 'mov D, r' or 'mov D, D' then get the target
9461 register pair for use with LR insn. */
9462 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9463 TARGET_BIG_ENDIAN
? 0 : 4);
9464 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9465 TARGET_BIG_ENDIAN
? 4 : 0);
9467 /* Produce the two LR insns to get the high and low parts. */
9468 emit_insn (gen_rtx_SET (destHigh
,
9469 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9471 VUNSPEC_ARC_LR_HIGH
)));
9472 emit_insn (gen_rtx_SET (destLow
,
9473 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9478 else if (state
== destDx
)
9480 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9481 LR insn get the target register pair. */
9482 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9483 TARGET_BIG_ENDIAN
? 0 : 4);
9484 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9485 TARGET_BIG_ENDIAN
? 4 : 0);
9487 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9495 /* operands 0..1 are the operands of a 64 bit move instruction.
9496 split it into two moves with operands 2/3 and 4/5. */
9499 arc_split_move (rtx
*operands
)
9501 machine_mode mode
= GET_MODE (operands
[0]);
9508 if (arc_process_double_reg_moves (operands
))
9513 && ((memory_operand (operands
[0], mode
)
9514 && even_register_operand (operands
[1], mode
))
9515 || (memory_operand (operands
[1], mode
)
9516 && even_register_operand (operands
[0], mode
))))
9518 emit_move_insn (operands
[0], operands
[1]);
9522 if (TARGET_PLUS_QMACW
9523 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9525 HOST_WIDE_INT intval0
, intval1
;
9526 if (GET_MODE (operands
[1]) == V2SImode
)
9528 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9529 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9533 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9534 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9535 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9536 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9538 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9539 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9540 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9541 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9542 emit_move_insn (xop
[0], xop
[2]);
9543 emit_move_insn (xop
[3], xop
[1]);
9547 for (i
= 0; i
< 2; i
++)
9549 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9551 rtx addr
= XEXP (operands
[i
], 0);
9555 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9556 switch (GET_CODE (addr
))
9558 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9559 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9560 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9564 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9565 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9566 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9575 xop
[0+i
] = adjust_automodify_address_nv
9576 (operands
[i
], SImode
,
9577 gen_rtx_fmt_ee (code
, Pmode
, r
,
9578 gen_rtx_PLUS (Pmode
, r
, o
)),
9580 xop
[2+i
] = adjust_automodify_address_nv
9581 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9585 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9586 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9589 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9592 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9595 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9596 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9600 /* Select between the instruction output templates s_tmpl (for short INSNs)
9601 and l_tmpl (for long INSNs). */
9604 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9606 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9608 extract_constrain_insn_cached (insn
);
9609 return is_short
? s_tmpl
: l_tmpl
;
9612 /* Searches X for any reference to REGNO, returning the rtx of the
9613 reference found if any. Otherwise, returns NULL_RTX. */
9616 arc_regno_use_in (unsigned int regno
, rtx x
)
9622 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9625 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9626 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9630 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9633 else if (fmt
[i
] == 'E')
9634 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9635 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9642 /* Return the integer value of the "type" attribute for INSN, or -1 if
9643 INSN can't have attributes. */
9646 arc_attr_type (rtx_insn
*insn
)
9648 if (NONJUMP_INSN_P (insn
)
9649 ? (GET_CODE (PATTERN (insn
)) == USE
9650 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9652 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9653 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9656 return get_attr_type (insn
);
9659 /* Return true if insn sets the condition codes. */
9662 arc_sets_cc_p (rtx_insn
*insn
)
9664 if (NONJUMP_INSN_P (insn
))
9665 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9666 insn
= seq
->insn (seq
->len () - 1);
9667 return arc_attr_type (insn
) == TYPE_COMPARE
;
9670 /* Return true if INSN is an instruction with a delay slot we may want
9674 arc_need_delay (rtx_insn
*insn
)
9678 if (!flag_delayed_branch
)
9680 /* The return at the end of a function needs a delay slot. */
9681 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9682 && (!(next
= next_active_insn (insn
))
9683 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9684 && arc_attr_type (next
) == TYPE_RETURN
))
9685 && (!TARGET_PAD_RETURN
9686 || (prev_active_insn (insn
)
9687 && prev_active_insn (prev_active_insn (insn
))
9688 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9690 if (NONJUMP_INSN_P (insn
)
9691 ? (GET_CODE (PATTERN (insn
)) == USE
9692 || GET_CODE (PATTERN (insn
)) == CLOBBER
9693 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9695 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9696 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9699 return num_delay_slots (insn
) != 0;
9702 /* Return true if the scheduling pass(es) has/have already run,
9703 i.e. where possible, we should try to mitigate high latencies
9704 by different instruction selection. */
9707 arc_scheduling_not_expected (void)
9709 return cfun
->machine
->arc_reorg_started
;
9712 /* Oddly enough, sometimes we get a zero overhead loop that branch
9713 shortening doesn't think is a loop - observed with compile/pr24883.c
9714 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9715 alignment visible for branch shortening (we actually align the loop
9716 insn before it, but that is equivalent since the loop insn is 4 byte
9720 arc_label_align (rtx_insn
*label
)
9722 int loop_align
= LOOP_ALIGN (LABEL
);
9724 if (loop_align
> align_labels_log
)
9726 rtx_insn
*prev
= prev_nonnote_insn (label
);
9728 if (prev
&& NONJUMP_INSN_P (prev
)
9729 && GET_CODE (PATTERN (prev
)) == PARALLEL
9730 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
)
9733 /* Code has a minimum p2 alignment of 1, which we must restore after an
9735 if (align_labels_log
< 1)
9737 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9738 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9741 return align_labels_log
;
9744 /* Return true if LABEL is in executable code. */
9747 arc_text_label (rtx_insn
*label
)
9751 /* ??? We use deleted labels like they were still there, see
9752 gcc.c-torture/compile/20000326-2.c . */
9753 gcc_assert (GET_CODE (label
) == CODE_LABEL
9754 || (GET_CODE (label
) == NOTE
9755 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9756 next
= next_nonnote_insn (label
);
9758 return (!JUMP_TABLE_DATA_P (next
)
9759 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9760 else if (!PREV_INSN (label
))
9761 /* ??? sometimes text labels get inserted very late, see
9762 gcc.dg/torture/stackalign/comp-goto-1.c */
9767 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9768 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9769 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9770 to redirect two breqs. */
9773 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9775 /* ??? get_attr_type is declared to take an rtx. */
9776 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9779 if (CROSSING_JUMP_P (followee
))
9780 switch (get_attr_type (u
.r
))
9783 case TYPE_BRCC_NO_DELAY_SLOT
:
9791 int arc_return_address_regs
[5] =
9792 {0, RETURN_ADDR_REGNUM
, ILINK1_REGNUM
, ILINK2_REGNUM
, ILINK1_REGNUM
};
9794 /* Implement EPILOGUE__USES.
9795 Return true if REGNO should be added to the deemed uses of the epilogue.
9797 We use the return address
9798 arc_return_address_regs[arc_compute_function_type (cfun)]. But
9799 also, we have to make sure all the register restore instructions
9800 are known to be live in interrupt functions, plus the blink
9801 register if it is clobbered by the isr. */
9804 arc_epilogue_uses (int regno
)
9806 if (regno
== arc_tp_regno
)
9808 if (reload_completed
)
9810 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9812 if (!fixed_regs
[regno
])
9814 return ((regno
== arc_return_address_regs
[cfun
->machine
->fn_type
])
9815 || (regno
== RETURN_ADDR_REGNUM
));
9818 return regno
== RETURN_ADDR_REGNUM
;
9821 return regno
== arc_return_address_regs
[arc_compute_function_type (cfun
)];
9824 /* Helper for EH_USES macro. */
9827 arc_eh_uses (int regno
)
9829 if (regno
== arc_tp_regno
)
9834 #ifndef TARGET_NO_LRA
9835 #define TARGET_NO_LRA !TARGET_LRA
9841 return !TARGET_NO_LRA
;
9844 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9845 Rcq registers, because some insn are shorter with them. OTOH we already
9846 have separate alternatives for this purpose, and other insns don't
9847 mind, so maybe we should rather prefer the other registers?
9848 We need more data, and we can only get that if we allow people to
9851 arc_register_priority (int r
)
9853 switch (arc_lra_priority_tag
)
9855 case ARC_LRA_PRIORITY_NONE
:
9857 case ARC_LRA_PRIORITY_NONCOMPACT
:
9858 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
9859 case ARC_LRA_PRIORITY_COMPACT
:
9860 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
9867 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
9869 return GENERAL_REGS
;
9873 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
9877 enum reload_type type
= (enum reload_type
) itype
;
9879 if (GET_CODE (x
) == PLUS
9880 && CONST_INT_P (XEXP (x
, 1))
9881 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
9882 || (REG_P (XEXP (x
, 0))
9883 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
9885 int scale
= GET_MODE_SIZE (mode
);
9887 rtx index_rtx
= XEXP (x
, 1);
9888 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
9893 if ((scale
-1) & offset
)
9897 = ((offset
+ (256 << shift
))
9898 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
9899 /* Sometimes the normal form does not suit DImode. We
9900 could avoid that by using smaller ranges, but that
9901 would give less optimized code when SImode is
9903 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
9908 regno
= REGNO (reg
);
9909 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
9911 if (reg_equiv_constant (regno
))
9913 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
9915 if (GET_CODE (sum2
) == PLUS
)
9916 sum2
= gen_rtx_CONST (Pmode
, sum2
);
9918 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
9919 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
9920 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
9925 /* We must re-recognize what we created before. */
9926 else if (GET_CODE (x
) == PLUS
9927 && GET_CODE (XEXP (x
, 0)) == PLUS
9928 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
9929 && REG_P (XEXP (XEXP (x
, 0), 0))
9930 && CONST_INT_P (XEXP (x
, 1)))
9932 /* Because this address is so complex, we know it must have
9933 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9934 it is already unshared, and needs no further unsharing. */
9935 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
9936 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
9942 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9945 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
9947 enum by_pieces_operation op
,
9950 /* Let the movmem expander handle small block moves. */
9951 if (op
== MOVE_BY_PIECES
)
9954 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
9957 /* Emit a (pre) memory barrier around an atomic sequence according to
9961 arc_pre_atomic_barrier (enum memmodel model
)
9963 if (need_atomic_barrier_p (model
, true))
9964 emit_insn (gen_memory_barrier ());
9967 /* Emit a (post) memory barrier around an atomic sequence according to
9971 arc_post_atomic_barrier (enum memmodel model
)
9973 if (need_atomic_barrier_p (model
, false))
9974 emit_insn (gen_memory_barrier ());
9977 /* Expand a compare and swap pattern. */
9980 emit_unlikely_jump (rtx insn
)
9982 int very_unlikely
= REG_BR_PROB_BASE
/ 100 - 1;
9984 rtx_insn
*jump
= emit_jump_insn (insn
);
9985 add_int_reg_note (jump
, REG_BR_PROB
, very_unlikely
);
9988 /* Expand code to perform a 8 or 16-bit compare and swap by doing
9989 32-bit compare and swap on the word containing the byte or
9990 half-word. The difference between a weak and a strong CAS is that
9991 the weak version may simply fail. The strong version relies on two
9992 loops, one checks if the SCOND op is succsfully or not, the other
9993 checks if the 32 bit accessed location which contains the 8 or 16
9994 bit datum is not changed by other thread. The first loop is
9995 implemented by the atomic_compare_and_swapsi_1 pattern. The second
9996 loops is implemented by this routine. */
9999 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10000 rtx oldval
, rtx newval
, rtx weak
,
10001 rtx mod_s
, rtx mod_f
)
10003 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10004 rtx addr
= gen_reg_rtx (Pmode
);
10005 rtx off
= gen_reg_rtx (SImode
);
10006 rtx oldv
= gen_reg_rtx (SImode
);
10007 rtx newv
= gen_reg_rtx (SImode
);
10008 rtx oldvalue
= gen_reg_rtx (SImode
);
10009 rtx newvalue
= gen_reg_rtx (SImode
);
10010 rtx res
= gen_reg_rtx (SImode
);
10011 rtx resv
= gen_reg_rtx (SImode
);
10012 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10014 bool is_weak
= (weak
!= const0_rtx
);
10016 /* Truncate the address. */
10017 emit_insn (gen_rtx_SET (addr
,
10018 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10020 /* Compute the datum offset. */
10021 emit_insn (gen_rtx_SET (off
,
10022 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10023 if (TARGET_BIG_ENDIAN
)
10024 emit_insn (gen_rtx_SET (off
,
10025 gen_rtx_MINUS (SImode
,
10026 (GET_MODE (mem
) == QImode
) ?
10027 GEN_INT (3) : GEN_INT (2), off
)));
10029 /* Normal read from truncated address. */
10030 memsi
= gen_rtx_MEM (SImode
, addr
);
10031 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10032 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10034 val
= copy_to_reg (memsi
);
10036 /* Convert the offset in bits. */
10037 emit_insn (gen_rtx_SET (off
,
10038 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10040 /* Get the proper mask. */
10041 if (GET_MODE (mem
) == QImode
)
10042 mask
= force_reg (SImode
, GEN_INT (0xff));
10044 mask
= force_reg (SImode
, GEN_INT (0xffff));
10046 emit_insn (gen_rtx_SET (mask
,
10047 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10049 /* Prepare the old and new values. */
10050 emit_insn (gen_rtx_SET (val
,
10051 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10054 oldval
= gen_lowpart (SImode
, oldval
);
10055 emit_insn (gen_rtx_SET (oldv
,
10056 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10058 newval
= gen_lowpart_common (SImode
, newval
);
10059 emit_insn (gen_rtx_SET (newv
,
10060 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10062 emit_insn (gen_rtx_SET (oldv
,
10063 gen_rtx_AND (SImode
, oldv
, mask
)));
10065 emit_insn (gen_rtx_SET (newv
,
10066 gen_rtx_AND (SImode
, newv
, mask
)));
10070 end_label
= gen_label_rtx ();
10071 loop_label
= gen_label_rtx ();
10072 emit_label (loop_label
);
10075 /* Make the old and new values. */
10076 emit_insn (gen_rtx_SET (oldvalue
,
10077 gen_rtx_IOR (SImode
, oldv
, val
)));
10079 emit_insn (gen_rtx_SET (newvalue
,
10080 gen_rtx_IOR (SImode
, newv
, val
)));
10082 /* Try an 32bit atomic compare and swap. It clobbers the CC
10084 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10085 weak
, mod_s
, mod_f
));
10087 /* Regardless of the weakness of the operation, a proper boolean
10088 result needs to be provided. */
10089 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10090 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10091 emit_insn (gen_rtx_SET (bool_result
, x
));
10095 /* Check the results: if the atomic op is successfully the goto
10097 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10098 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10099 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10100 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10101 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10103 /* Wait for the right moment when the accessed 32-bit location
10105 emit_insn (gen_rtx_SET (resv
,
10106 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10108 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10109 cc
= gen_rtx_REG (mode
, CC_REG
);
10110 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10112 /* Set the new value of the 32 bit location, proper masked. */
10113 emit_insn (gen_rtx_SET (val
, resv
));
10115 /* Try again if location is unstable. Fall through if only
10116 scond op failed. */
10117 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10118 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10119 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10120 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10122 emit_label (end_label
);
10125 /* End: proper return the result for the given mode. */
10126 emit_insn (gen_rtx_SET (res
,
10127 gen_rtx_AND (SImode
, res
, mask
)));
10129 emit_insn (gen_rtx_SET (res
,
10130 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10132 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10135 /* Helper function used by "atomic_compare_and_swap" expand
10139 arc_expand_compare_and_swap (rtx operands
[])
10141 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10144 bval
= operands
[0];
10145 rval
= operands
[1];
10147 oldval
= operands
[3];
10148 newval
= operands
[4];
10149 is_weak
= operands
[5];
10150 mod_s
= operands
[6];
10151 mod_f
= operands
[7];
10152 mode
= GET_MODE (mem
);
10154 if (reg_overlap_mentioned_p (rval
, oldval
))
10155 oldval
= copy_to_reg (oldval
);
10157 if (mode
== SImode
)
10159 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10160 is_weak
, mod_s
, mod_f
));
10161 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10162 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10163 emit_insn (gen_rtx_SET (bval
, x
));
10167 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10168 is_weak
, mod_s
, mod_f
);
10172 /* Helper function used by the "atomic_compare_and_swapsi_1"
10176 arc_split_compare_and_swap (rtx operands
[])
10178 rtx rval
, mem
, oldval
, newval
;
10180 enum memmodel mod_s
, mod_f
;
10182 rtx label1
, label2
, x
, cond
;
10184 rval
= operands
[0];
10186 oldval
= operands
[2];
10187 newval
= operands
[3];
10188 is_weak
= (operands
[4] != const0_rtx
);
10189 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10190 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10191 mode
= GET_MODE (mem
);
10193 /* ARC atomic ops work only with 32-bit aligned memories. */
10194 gcc_assert (mode
== SImode
);
10196 arc_pre_atomic_barrier (mod_s
);
10201 label1
= gen_label_rtx ();
10202 emit_label (label1
);
10204 label2
= gen_label_rtx ();
10206 /* Load exclusive. */
10207 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10209 /* Check if it is oldval. */
10210 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10211 cond
= gen_rtx_REG (mode
, CC_REG
);
10212 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10214 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10215 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10216 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10217 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10219 /* Exclusively store new item. Store clobbers CC reg. */
10220 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10224 /* Check the result of the store. */
10225 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10226 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10227 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10228 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10229 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10232 if (mod_f
!= MEMMODEL_RELAXED
)
10233 emit_label (label2
);
10235 arc_post_atomic_barrier (mod_s
);
10237 if (mod_f
== MEMMODEL_RELAXED
)
10238 emit_label (label2
);
10241 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10242 to perform. MEM is the memory on which to operate. VAL is the second
10243 operand of the binary operator. BEFORE and AFTER are optional locations to
10244 return the value of MEM either before of after the operation. MODEL_RTX
10245 is a CONST_INT containing the memory model to use. */
10248 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10249 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10251 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10252 machine_mode mode
= GET_MODE (mem
);
10253 rtx label
, x
, cond
;
10254 rtx before
= orig_before
, after
= orig_after
;
10256 /* ARC atomic ops work only with 32-bit aligned memories. */
10257 gcc_assert (mode
== SImode
);
10259 arc_pre_atomic_barrier (model
);
10261 label
= gen_label_rtx ();
10262 emit_label (label
);
10263 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10265 if (before
== NULL_RTX
)
10266 before
= gen_reg_rtx (mode
);
10268 if (after
== NULL_RTX
)
10269 after
= gen_reg_rtx (mode
);
10271 /* Load exclusive. */
10272 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10277 x
= gen_rtx_AND (mode
, before
, val
);
10278 emit_insn (gen_rtx_SET (after
, x
));
10279 x
= gen_rtx_NOT (mode
, after
);
10280 emit_insn (gen_rtx_SET (after
, x
));
10284 if (CONST_INT_P (val
))
10286 val
= GEN_INT (-INTVAL (val
));
10292 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10293 emit_insn (gen_rtx_SET (after
, x
));
10297 /* Exclusively store new item. Store clobbers CC reg. */
10298 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10300 /* Check the result of the store. */
10301 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10302 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10303 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10305 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10307 arc_post_atomic_barrier (model
);
10310 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10313 arc_no_speculation_in_delay_slots_p ()
10318 /* Return a parallel of registers to represent where to find the
10319 register pieces if required, otherwise NULL_RTX. */
10322 arc_dwarf_register_span (rtx rtl
)
10324 machine_mode mode
= GET_MODE (rtl
);
10328 if (GET_MODE_SIZE (mode
) != 8)
10331 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10332 regno
= REGNO (rtl
);
10333 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10334 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10339 /* Return true if OP is an acceptable memory operand for ARCompact
10340 16-bit load instructions of MODE.
10342 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10343 non scaled instructions.
10345 SCALED: TRUE if address can be scaled. */
10348 compact_memory_operand_p (rtx op
, machine_mode mode
,
10349 bool av2short
, bool scaled
)
10351 rtx addr
, plus0
, plus1
;
10354 /* Eliminate non-memory operations. */
10355 if (GET_CODE (op
) != MEM
)
10358 /* .di instructions have no 16-bit form. */
10359 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10362 if (mode
== VOIDmode
)
10363 mode
= GET_MODE (op
);
10365 size
= GET_MODE_SIZE (mode
);
10367 /* dword operations really put out 2 instructions, so eliminate
10369 if (size
> UNITS_PER_WORD
)
10372 /* Decode the address now. */
10373 addr
= XEXP (op
, 0);
10374 switch (GET_CODE (addr
))
10377 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10378 || COMPACT_GP_REG_P (REGNO (addr
))
10379 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10381 plus0
= XEXP (addr
, 0);
10382 plus1
= XEXP (addr
, 1);
10384 if ((GET_CODE (plus0
) == REG
)
10385 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10386 || COMPACT_GP_REG_P (REGNO (plus0
)))
10387 && ((GET_CODE (plus1
) == REG
)
10388 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10389 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10394 if ((GET_CODE (plus0
) == REG
)
10395 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10396 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10397 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10398 && (GET_CODE (plus1
) == CONST_INT
))
10400 bool valid
= false;
10402 off
= INTVAL (plus1
);
10404 /* Negative offset is not supported in 16-bit load/store insns. */
10408 /* Only u5 immediates allowed in code density instructions. */
10416 /* This is an ldh_s.x instruction, check the u6
10418 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10422 /* Only u5 immediates allowed in 32bit access code
10423 density instructions. */
10424 if (REGNO (plus0
) <= 31)
10425 return ((off
< 32) && (off
% 4 == 0));
10432 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10443 /* The 6-bit constant get shifted to fit the real
10444 5-bits field. Check also for the alignment. */
10445 return ((off
< 64) && (off
% 2 == 0));
10447 return ((off
< 128) && (off
% 4 == 0));
10454 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10455 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10456 || SP_REG_P (REGNO (plus0
)))
10459 off
= INTVAL (plus1
);
10460 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10463 if ((GET_CODE (plus0
) == MULT
)
10464 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10465 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10466 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10467 && (GET_CODE (plus1
) == REG
)
10468 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10469 || COMPACT_GP_REG_P (REGNO (plus1
))))
10473 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10474 for 16-bit load instructions. */
10479 struct gcc_target targetm
= TARGET_INITIALIZER
;
10481 #include "gt-arc.h"