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"
48 #include "diagnostic.h"
49 #include "fold-const.h"
51 #include "stor-layout.h"
54 #include "insn-attr.h"
58 #include "langhooks.h"
59 #include "tm-constrs.h"
60 #include "reload.h" /* For operands_match_p */
62 #include "tree-pass.h"
69 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
70 static char arc_cpu_name
[10] = "";
71 static const char *arc_cpu_string
= arc_cpu_name
;
73 /* ??? Loads can handle any constant, stores can only handle small ones. */
74 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
75 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
76 (GET_CODE (X) == CONST_INT \
77 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
78 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
80 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
82 #define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
83 (GET_CODE (X) == PLUS \
84 && GET_CODE (XEXP (X, 0)) == MULT \
85 && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
86 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
87 && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
88 || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
89 && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
90 || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
92 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
93 (GET_CODE (X) == PLUS \
94 && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
95 && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
96 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
97 || (GET_CODE (XEXP ((X), 1)) == CONST \
98 && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
99 && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
100 && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
101 && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
103 /* Array of valid operand punctuation characters. */
104 char arc_punct_chars
[256];
106 /* State used by arc_ccfsm_advance to implement conditional execution. */
107 struct GTY (()) arc_ccfsm
112 rtx_insn
*target_insn
;
116 /* Status of the IRQ_CTRL_AUX register. */
117 typedef struct irq_ctrl_saved_t
119 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
120 short irq_save_last_reg
;
121 /* True if BLINK is automatically saved. */
123 /* True if LPCOUNT is automatically saved. */
124 bool irq_save_lpcount
;
126 static irq_ctrl_saved_t irq_ctrl_saved
;
128 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
129 ((ARC_INTERRUPT_P (FNTYPE) \
130 && irq_ctrl_saved.irq_save_blink) \
131 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
132 && rgf_banked_register_count > 8))
134 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
135 ((ARC_INTERRUPT_P (FNTYPE) \
136 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
137 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
138 && rgf_banked_register_count > 8))
140 #define ARC_AUTO_IRQ_P(FNTYPE) \
141 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
142 && (irq_ctrl_saved.irq_save_blink \
143 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
145 /* Number of registers in second bank for FIRQ support. */
146 static int rgf_banked_register_count
;
148 #define arc_ccfsm_current cfun->machine->ccfsm_current
150 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
151 ((STATE)->state == 1 || (STATE)->state == 2)
153 /* Indicate we're conditionalizing insns now. */
154 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
155 ((STATE)->state += 2)
157 #define ARC_CCFSM_COND_EXEC_P(STATE) \
158 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
159 || current_insn_predicate)
161 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
162 #define CCFSM_ISCOMPACT(INSN,STATE) \
163 (ARC_CCFSM_COND_EXEC_P (STATE) \
164 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
165 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
166 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
168 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
169 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
170 ((ARC_CCFSM_COND_EXEC_P (STATE) \
172 && INSN_ANNULLED_BRANCH_P (JUMP) \
173 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
174 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
175 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
176 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
178 /* The maximum number of insns skipped which will be conditionalised if
180 /* When optimizing for speed:
181 Let p be the probability that the potentially skipped insns need to
182 be executed, pn the cost of a correctly predicted non-taken branch,
183 mt the cost of a mis/non-predicted taken branch,
184 mn mispredicted non-taken, pt correctly predicted taken ;
185 costs expressed in numbers of instructions like the ones considered
187 Unfortunately we don't have a measure of predictability - this
188 is linked to probability only in that in the no-eviction-scenario
189 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
190 value that can be assumed *if* the distribution is perfectly random.
191 A predictability of 1 is perfectly plausible not matter what p is,
192 because the decision could be dependent on an invocation parameter
194 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
195 For small p, we want MAX_INSNS_SKIPPED == pt
197 When optimizing for size:
198 We want to skip insn unless we could use 16 opcodes for the
199 non-conditionalized insn to balance the branch length or more.
200 Performance can be tie-breaker. */
201 /* If the potentially-skipped insns are likely to be executed, we'll
202 generally save one non-taken branch
204 this to be no less than the 1/p */
205 #define MAX_INSNS_SKIPPED 3
207 /* A nop is needed between a 4 byte insn that sets the condition codes and
208 a branch that uses them (the same isn't true for an 8 byte insn that sets
209 the condition codes). Set by arc_ccfsm_advance. Used by
210 arc_print_operand. */
212 static int get_arc_condition_code (rtx
);
214 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
215 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
217 /* Initialized arc_attribute_table to NULL since arc doesnot have any
218 machine specific supported attributes. */
219 const struct attribute_spec arc_attribute_table
[] =
221 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
222 affects_type_identity } */
223 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute
, true },
224 /* Function calls made to this symbol must be done indirectly, because
225 it may lie outside of the 21/25 bit addressing range of a normal function
227 { "long_call", 0, 0, false, true, true, NULL
, false },
228 /* Whereas these functions are always known to reside within the 25 bit
229 addressing range of unconditionalized bl. */
230 { "medium_call", 0, 0, false, true, true, NULL
, false },
231 /* And these functions are always known to reside within the 21 bit
232 addressing range of blcc. */
233 { "short_call", 0, 0, false, true, true, NULL
, false },
234 /* Function which are not having the prologue and epilogue generated
236 { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute
, false },
237 { NULL
, 0, 0, false, false, false, NULL
, false }
239 static int arc_comp_type_attributes (const_tree
, const_tree
);
240 static void arc_file_start (void);
241 static void arc_internal_label (FILE *, const char *, unsigned long);
242 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
244 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
245 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
247 static void arc_init_builtins (void);
248 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
250 static int branch_dest (rtx
);
252 static void arc_output_pic_addr_const (FILE *, rtx
, int);
253 static bool arc_function_ok_for_sibcall (tree
, tree
);
254 static rtx
arc_function_value (const_tree
, const_tree
, bool);
255 const char * output_shift (rtx
*);
256 static void arc_reorg (void);
257 static bool arc_in_small_data_p (const_tree
);
259 static void arc_init_reg_tables (void);
260 static bool arc_return_in_memory (const_tree
, const_tree
);
261 static bool arc_vector_mode_supported_p (machine_mode
);
263 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
265 static const char *arc_invalid_within_doloop (const rtx_insn
*);
267 static void output_short_suffix (FILE *file
);
269 static bool arc_frame_pointer_required (void);
271 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
273 enum by_pieces_operation op
,
276 /* Globally visible information about currently selected cpu. */
277 const arc_cpu_t
*arc_selected_cpu
;
279 /* Check for constructions like REG + OFFS, where OFFS can be a
280 register, an immediate or an long immediate. */
283 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
285 if (GET_CODE (x
) != PLUS
)
288 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
291 /* Check for: [Rx + small offset] or [Rx + Ry]. */
292 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
293 && GET_MODE_SIZE ((mode
)) <= 4)
294 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
297 /* Check for [Rx + symbol]. */
299 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
300 /* Avoid this type of address for double or larger modes. */
301 && (GET_MODE_SIZE (mode
) <= 4)
302 /* Avoid small data which ends in something like GP +
304 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))
305 || TARGET_NO_SDATA_SET
))
311 /* Implements target hook vector_mode_supported_p. */
314 arc_vector_mode_supported_p (machine_mode mode
)
319 return TARGET_PLUS_DMPY
;
322 return TARGET_PLUS_QMACW
;
325 return TARGET_SIMD_SET
;
332 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
335 arc_preferred_simd_mode (machine_mode mode
)
340 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
349 /* Implements target hook
350 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
353 arc_autovectorize_vector_sizes (void)
355 return TARGET_PLUS_QMACW
? (8 | 4) : 0;
358 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
359 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
360 static rtx
arc_delegitimize_address (rtx
);
361 static bool arc_can_follow_jump (const rtx_insn
*follower
,
362 const rtx_insn
*followee
);
364 static rtx
frame_insn (rtx
);
365 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
367 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
369 static void arc_finalize_pic (void);
371 /* initialize the GCC target structure. */
372 #undef TARGET_COMP_TYPE_ATTRIBUTES
373 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
374 #undef TARGET_ASM_FILE_START
375 #define TARGET_ASM_FILE_START arc_file_start
376 #undef TARGET_ATTRIBUTE_TABLE
377 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
378 #undef TARGET_ASM_INTERNAL_LABEL
379 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
380 #undef TARGET_RTX_COSTS
381 #define TARGET_RTX_COSTS arc_rtx_costs
382 #undef TARGET_ADDRESS_COST
383 #define TARGET_ADDRESS_COST arc_address_cost
385 #undef TARGET_ENCODE_SECTION_INFO
386 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
388 #undef TARGET_CANNOT_FORCE_CONST_MEM
389 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
391 #undef TARGET_INIT_BUILTINS
392 #define TARGET_INIT_BUILTINS arc_init_builtins
394 #undef TARGET_EXPAND_BUILTIN
395 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
397 #undef TARGET_BUILTIN_DECL
398 #define TARGET_BUILTIN_DECL arc_builtin_decl
400 #undef TARGET_ASM_OUTPUT_MI_THUNK
401 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
403 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
404 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
406 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
407 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
409 #undef TARGET_MACHINE_DEPENDENT_REORG
410 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
412 #undef TARGET_IN_SMALL_DATA_P
413 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
415 #undef TARGET_PROMOTE_FUNCTION_MODE
416 #define TARGET_PROMOTE_FUNCTION_MODE \
417 default_promote_function_mode_always_promote
419 #undef TARGET_PROMOTE_PROTOTYPES
420 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
422 #undef TARGET_RETURN_IN_MEMORY
423 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
424 #undef TARGET_PASS_BY_REFERENCE
425 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
427 #undef TARGET_SETUP_INCOMING_VARARGS
428 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
430 #undef TARGET_ARG_PARTIAL_BYTES
431 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
433 #undef TARGET_MUST_PASS_IN_STACK
434 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
436 #undef TARGET_FUNCTION_VALUE
437 #define TARGET_FUNCTION_VALUE arc_function_value
439 #undef TARGET_SCHED_ADJUST_PRIORITY
440 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
442 #undef TARGET_VECTOR_MODE_SUPPORTED_P
443 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
445 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
446 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
448 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
449 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
451 #undef TARGET_CAN_USE_DOLOOP_P
452 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
454 #undef TARGET_INVALID_WITHIN_DOLOOP
455 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
457 #undef TARGET_PRESERVE_RELOAD_P
458 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
460 #undef TARGET_CAN_FOLLOW_JUMP
461 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
463 #undef TARGET_DELEGITIMIZE_ADDRESS
464 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
466 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
467 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
468 arc_use_by_pieces_infrastructure_p
470 /* Usually, we will be able to scale anchor offsets.
471 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
472 #undef TARGET_MIN_ANCHOR_OFFSET
473 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
474 #undef TARGET_MAX_ANCHOR_OFFSET
475 #define TARGET_MAX_ANCHOR_OFFSET (1020)
477 #undef TARGET_SECONDARY_RELOAD
478 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
480 #define TARGET_OPTION_OVERRIDE arc_override_options
482 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
484 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
486 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
488 #define TARGET_CAN_ELIMINATE arc_can_eliminate
490 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
492 #define TARGET_FUNCTION_ARG arc_function_arg
494 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
496 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
498 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
500 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
502 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
504 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
506 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
508 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
509 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
510 arc_no_speculation_in_delay_slots_p
513 #define TARGET_LRA_P arc_lra_p
514 #define TARGET_REGISTER_PRIORITY arc_register_priority
515 /* Stores with scaled offsets have different displacement ranges. */
516 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
517 #define TARGET_SPILL_CLASS arc_spill_class
519 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
520 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
522 #undef TARGET_WARN_FUNC_RETURN
523 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
525 #include "target-def.h"
527 #undef TARGET_ASM_ALIGNED_HI_OP
528 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
529 #undef TARGET_ASM_ALIGNED_SI_OP
530 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
533 #undef TARGET_HAVE_TLS
534 #define TARGET_HAVE_TLS HAVE_AS_TLS
537 #undef TARGET_DWARF_REGISTER_SPAN
538 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
540 /* Try to keep the (mov:DF _, reg) as early as possible so
541 that the d<add/sub/mul>h-lr insns appear together and can
542 use the peephole2 pattern. */
545 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
547 rtx set
= single_set (insn
);
549 && GET_MODE (SET_SRC(set
)) == DFmode
550 && GET_CODE (SET_SRC(set
)) == REG
)
552 /* Incrementing priority by 20 (empirically derived). */
553 return priority
+ 20;
559 /* For ARC base register + offset addressing, the validity of the
560 address is mode-dependent for most of the offset range, as the
561 offset can be scaled by the access size.
562 We don't expose these as mode-dependent addresses in the
563 mode_dependent_address_p target hook, because that would disable
564 lots of optimizations, and most uses of these addresses are for 32
565 or 64 bit accesses anyways, which are fine.
566 However, that leaves some addresses for 8 / 16 bit values not
567 properly reloaded by the generic code, which is why we have to
568 schedule secondary reloads for these. */
571 arc_secondary_reload (bool in_p
,
575 secondary_reload_info
*sri
)
577 enum rtx_code code
= GET_CODE (x
);
579 if (cl
== DOUBLE_REGS
)
582 /* The loop counter register can be stored, but not loaded directly. */
583 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
584 && in_p
&& MEM_P (x
))
587 /* If we have a subreg (reg), where reg is a pseudo (that will end in
588 a memory location), then we may need a scratch register to handle
589 the fp/sp+largeoffset address. */
597 int regno
= REGNO (x
);
598 if (regno
>= FIRST_PSEUDO_REGISTER
)
599 regno
= reg_renumber
[regno
];
604 /* It is a pseudo that ends in a stack location. */
605 if (reg_equiv_mem (REGNO (x
)))
607 /* Get the equivalent address and check the range of the
609 rtx mem
= reg_equiv_mem (REGNO (x
));
610 addr
= find_replacement (&XEXP (mem
, 0));
615 gcc_assert (MEM_P (x
));
617 addr
= simplify_rtx (addr
);
619 if (addr
&& GET_CODE (addr
) == PLUS
620 && CONST_INT_P (XEXP (addr
, 1))
621 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
627 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
631 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
641 /* Convert reloads using offsets that are too large to use indirect
645 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
649 gcc_assert (GET_CODE (mem
) == MEM
);
650 addr
= XEXP (mem
, 0);
652 /* Large offset: use a move. FIXME: ld ops accepts limms as
653 offsets. Hence, the following move insn is not required. */
654 emit_move_insn (scratch
, addr
);
655 mem
= replace_equiv_address_nv (mem
, scratch
);
657 /* Now create the move. */
659 emit_insn (gen_rtx_SET (mem
, reg
));
661 emit_insn (gen_rtx_SET (reg
, mem
));
666 static unsigned arc_ifcvt (void);
670 const pass_data pass_data_arc_ifcvt
=
673 "arc_ifcvt", /* name */
674 OPTGROUP_NONE
, /* optinfo_flags */
675 TV_IFCVT2
, /* tv_id */
676 0, /* properties_required */
677 0, /* properties_provided */
678 0, /* properties_destroyed */
679 0, /* todo_flags_start */
680 TODO_df_finish
/* todo_flags_finish */
683 class pass_arc_ifcvt
: public rtl_opt_pass
686 pass_arc_ifcvt(gcc::context
*ctxt
)
687 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
690 /* opt_pass methods: */
691 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
692 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
698 make_pass_arc_ifcvt (gcc::context
*ctxt
)
700 return new pass_arc_ifcvt (ctxt
);
703 static unsigned arc_predicate_delay_insns (void);
707 const pass_data pass_data_arc_predicate_delay_insns
=
710 "arc_predicate_delay_insns", /* name */
711 OPTGROUP_NONE
, /* optinfo_flags */
712 TV_IFCVT2
, /* tv_id */
713 0, /* properties_required */
714 0, /* properties_provided */
715 0, /* properties_destroyed */
716 0, /* todo_flags_start */
717 TODO_df_finish
/* todo_flags_finish */
720 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
723 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
724 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
727 /* opt_pass methods: */
728 virtual unsigned int execute (function
*)
730 return arc_predicate_delay_insns ();
737 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
739 return new pass_arc_predicate_delay_insns (ctxt
);
742 /* Called by OVERRIDE_OPTIONS to initialize various things. */
749 /* I have the multiplier, then use it*/
750 if (TARGET_MPYW
|| TARGET_MULTI
)
751 arc_multcost
= COSTS_N_INSNS (1);
753 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
754 if (arc_multcost
< 0)
757 case TUNE_ARC700_4_2_STD
:
759 max throughput (1 multiply + 4 other insns) / 5 cycles. */
760 arc_multcost
= COSTS_N_INSNS (4);
761 if (TARGET_NOMPY_SET
)
762 arc_multcost
= COSTS_N_INSNS (30);
764 case TUNE_ARC700_4_2_XMAC
:
766 max throughput (1 multiply + 2 other insns) / 3 cycles. */
767 arc_multcost
= COSTS_N_INSNS (3);
768 if (TARGET_NOMPY_SET
)
769 arc_multcost
= COSTS_N_INSNS (30);
772 if (TARGET_MUL64_SET
)
774 arc_multcost
= COSTS_N_INSNS (4);
779 arc_multcost
= COSTS_N_INSNS (30);
783 /* MPY instructions valid only for ARC700 or ARCv2. */
784 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
785 error ("-mno-mpy supported only for ARC700 or ARCv2");
787 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
788 error ("-mno-dpfp-lrsr supported only with -mdpfp");
790 /* FPX-1. No fast and compact together. */
791 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
792 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
793 error ("FPX fast and compact options cannot be specified together");
795 /* FPX-2. No fast-spfp for arc600 or arc601. */
796 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
797 error ("-mspfp_fast not available on ARC600 or ARC601");
799 /* FPX-4. No FPX extensions mixed with FPU extensions. */
800 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
801 && TARGET_HARD_FLOAT
)
802 error ("No FPX/FPU mixing allowed");
804 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
805 if (flag_pic
&& TARGET_ARC600_FAMILY
)
808 "PIC is not supported for %s. Generating non-PIC code only..",
813 arc_init_reg_tables ();
815 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
816 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
817 arc_punct_chars
['#'] = 1;
818 arc_punct_chars
['*'] = 1;
819 arc_punct_chars
['?'] = 1;
820 arc_punct_chars
['!'] = 1;
821 arc_punct_chars
['^'] = 1;
822 arc_punct_chars
['&'] = 1;
823 arc_punct_chars
['+'] = 1;
824 arc_punct_chars
['_'] = 1;
826 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
828 /* There are two target-independent ifcvt passes, and arc_reorg may do
829 one or more arc_ifcvt calls. */
830 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
831 struct register_pass_info arc_ifcvt4_info
832 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
833 struct register_pass_info arc_ifcvt5_info
834 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
836 register_pass (&arc_ifcvt4_info
);
837 register_pass (&arc_ifcvt5_info
);
840 if (flag_delayed_branch
)
842 opt_pass
*pass_arc_predicate_delay_insns
843 = make_pass_arc_predicate_delay_insns (g
);
844 struct register_pass_info arc_predicate_delay_info
845 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
847 register_pass (&arc_predicate_delay_info
);
851 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
852 register range is specified as two registers separated by a dash.
853 It always starts with r0, and its upper limit is fp register.
854 blink and lp_count registers are optional. */
857 irq_range (const char *cstr
)
859 int i
, first
, last
, blink
, lpcount
, xreg
;
860 char *str
, *dash
, *comma
;
863 str
= (char *) alloca (i
+ 1);
864 memcpy (str
, cstr
, i
+ 1);
868 dash
= strchr (str
, '-');
871 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
876 comma
= strchr (dash
+ 1, ',');
880 first
= decode_reg_name (str
);
883 warning (0, "first register must be R0");
887 /* At this moment we do not have the register names initialized
889 if (!strcmp (dash
+ 1, "ilink"))
892 last
= decode_reg_name (dash
+ 1);
896 warning (0, "unknown register name: %s", dash
+ 1);
902 warning (0, "last register name %s must be an odd register", dash
+ 1);
910 warning (0, "%s-%s is an empty range", str
, dash
+ 1);
919 comma
= strchr (str
, ',');
923 xreg
= decode_reg_name (str
);
935 warning (0, "unknown register name: %s", str
);
940 irq_ctrl_saved
.irq_save_last_reg
= last
;
941 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
942 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
945 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
949 parse_mrgf_banked_regs_option (const char *arg
)
955 val
= strtol (arg
, &end_ptr
, 10);
956 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
957 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
959 error ("invalid number in -mrgf-banked-regs=%s "
960 "valid values are 0, 4, 8, 16, or 32", arg
);
963 rgf_banked_register_count
= (int) val
;
966 /* Check ARC options, generate derived target attributes. */
969 arc_override_options (void)
972 cl_deferred_option
*opt
;
973 vec
<cl_deferred_option
> *vopt
974 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
976 if (arc_cpu
== PROCESSOR_NONE
)
977 arc_cpu
= TARGET_CPU_DEFAULT
;
979 /* Set the default cpu options. */
980 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
982 /* Set the architectures. */
983 switch (arc_selected_cpu
->arch_info
->arch_id
)
986 arc_cpu_string
= "EM";
989 arc_cpu_string
= "HS";
992 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
993 arc_cpu_string
= "NPS400";
995 arc_cpu_string
= "ARC700";
998 arc_cpu_string
= "ARC600";
1004 irq_ctrl_saved
.irq_save_last_reg
= -1;
1005 irq_ctrl_saved
.irq_save_blink
= false;
1006 irq_ctrl_saved
.irq_save_lpcount
= false;
1008 rgf_banked_register_count
= 0;
1010 /* Handle the deferred options. */
1012 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1014 switch (opt
->opt_index
)
1016 case OPT_mirq_ctrl_saved_
:
1018 irq_range (opt
->arg
);
1020 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1023 case OPT_mrgf_banked_regs_
:
1025 parse_mrgf_banked_regs_option (opt
->arg
);
1027 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1035 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1036 specific flags are set in arc-common.c. The architecture forces
1037 the default hardware configurations in, regardless what command
1038 line options are saying. The CPU optional hw options can be
1039 turned on or off. */
1040 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1042 if ((arc_selected_cpu->flags & CODE) \
1043 && ((target_flags_explicit & MASK) == 0)) \
1044 target_flags |= MASK; \
1045 if (arc_selected_cpu->arch_info->dflags & CODE) \
1046 target_flags |= MASK; \
1048 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1050 if ((arc_selected_cpu->flags & CODE) \
1051 && (VAR == DEFAULT_##VAR)) \
1053 if (arc_selected_cpu->arch_info->dflags & CODE) \
1057 #include "arc-options.def"
1062 /* Check options against architecture options. Throw an error if
1063 option is not allowed. */
1064 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1067 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1069 error ("%s is not available for %s architecture", \
1070 DOC, arc_selected_cpu->arch_info->name); \
1073 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1075 if ((target_flags & MASK) \
1076 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1077 error ("%s is not available for %s architecture", \
1078 DOC, arc_selected_cpu->arch_info->name); \
1081 #include "arc-options.def"
1086 /* Set Tune option. */
1087 if (arc_tune
== TUNE_NONE
)
1088 arc_tune
= (enum attr_tune
) arc_selected_cpu
->tune
;
1090 if (arc_size_opt_level
== 3)
1093 /* Compact casesi is not a valid option for ARCv2 family. */
1096 if (TARGET_COMPACT_CASESI
)
1098 warning (0, "compact-casesi is not applicable to ARCv2");
1099 TARGET_COMPACT_CASESI
= 0;
1102 else if (optimize_size
== 1
1103 && !global_options_set
.x_TARGET_COMPACT_CASESI
)
1104 TARGET_COMPACT_CASESI
= 1;
1107 target_flags
|= MASK_NO_SDATA_SET
;
1109 if (flag_no_common
== 255)
1110 flag_no_common
= !TARGET_NO_SDATA_SET
;
1112 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1113 if (TARGET_MIXED_CODE
)
1115 if (!TARGET_Q_CLASS
)
1116 TARGET_COMPACT_CASESI
= 0;
1117 if (TARGET_COMPACT_CASESI
)
1118 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
1120 /* These need to be done at start up. It's convenient to do them here. */
1124 /* The condition codes of the ARC, and the inverse function. */
1125 /* For short branches, the "c" / "nc" names are not defined in the ARC
1126 Programmers manual, so we have to use "lo" / "hs"" instead. */
1127 static const char *arc_condition_codes
[] =
1129 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1130 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1133 enum arc_cc_code_index
1135 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1136 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1137 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1138 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1141 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1143 /* Returns the index of the ARC condition code string in
1144 `arc_condition_codes'. COMPARISON should be an rtx like
1145 `(eq (...) (...))'. */
1148 get_arc_condition_code (rtx comparison
)
1150 switch (GET_MODE (XEXP (comparison
, 0)))
1153 case E_SImode
: /* For BRcc. */
1154 switch (GET_CODE (comparison
))
1156 case EQ
: return ARC_CC_EQ
;
1157 case NE
: return ARC_CC_NE
;
1158 case GT
: return ARC_CC_GT
;
1159 case LE
: return ARC_CC_LE
;
1160 case GE
: return ARC_CC_GE
;
1161 case LT
: return ARC_CC_LT
;
1162 case GTU
: return ARC_CC_HI
;
1163 case LEU
: return ARC_CC_LS
;
1164 case LTU
: return ARC_CC_LO
;
1165 case GEU
: return ARC_CC_HS
;
1166 default : gcc_unreachable ();
1169 switch (GET_CODE (comparison
))
1171 case EQ
: return ARC_CC_EQ
;
1172 case NE
: return ARC_CC_NE
;
1173 case GE
: return ARC_CC_P
;
1174 case LT
: return ARC_CC_N
;
1175 case GT
: return ARC_CC_PNZ
;
1176 default : gcc_unreachable ();
1179 switch (GET_CODE (comparison
))
1181 case EQ
: return ARC_CC_EQ
;
1182 case NE
: return ARC_CC_NE
;
1183 default : gcc_unreachable ();
1186 switch (GET_CODE (comparison
))
1188 case LTU
: return ARC_CC_C
;
1189 case GEU
: return ARC_CC_NC
;
1190 default : gcc_unreachable ();
1192 case E_CC_FP_GTmode
:
1193 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1194 switch (GET_CODE (comparison
))
1196 case GT
: return ARC_CC_N
;
1197 case UNLE
: return ARC_CC_P
;
1198 default : gcc_unreachable ();
1201 switch (GET_CODE (comparison
))
1203 case GT
: return ARC_CC_HI
;
1204 case UNLE
: return ARC_CC_LS
;
1205 default : gcc_unreachable ();
1207 case E_CC_FP_GEmode
:
1208 /* Same for FPX and non-FPX. */
1209 switch (GET_CODE (comparison
))
1211 case GE
: return ARC_CC_HS
;
1212 case UNLT
: return ARC_CC_LO
;
1213 default : gcc_unreachable ();
1215 case E_CC_FP_UNEQmode
:
1216 switch (GET_CODE (comparison
))
1218 case UNEQ
: return ARC_CC_EQ
;
1219 case LTGT
: return ARC_CC_NE
;
1220 default : gcc_unreachable ();
1222 case E_CC_FP_ORDmode
:
1223 switch (GET_CODE (comparison
))
1225 case UNORDERED
: return ARC_CC_C
;
1226 case ORDERED
: return ARC_CC_NC
;
1227 default : gcc_unreachable ();
1230 switch (GET_CODE (comparison
))
1232 case EQ
: return ARC_CC_EQ
;
1233 case NE
: return ARC_CC_NE
;
1234 case UNORDERED
: return ARC_CC_C
;
1235 case ORDERED
: return ARC_CC_NC
;
1236 case LTGT
: return ARC_CC_HI
;
1237 case UNEQ
: return ARC_CC_LS
;
1238 default : gcc_unreachable ();
1241 switch (GET_CODE (comparison
))
1243 case EQ
: return ARC_CC_EQ
;
1244 case NE
: return ARC_CC_NE
;
1245 case GT
: return ARC_CC_GT
;
1246 case GE
: return ARC_CC_GE
;
1247 case LT
: return ARC_CC_C
;
1248 case LE
: return ARC_CC_LS
;
1249 case UNORDERED
: return ARC_CC_V
;
1250 case ORDERED
: return ARC_CC_NV
;
1251 case UNGT
: return ARC_CC_HI
;
1252 case UNGE
: return ARC_CC_HS
;
1253 case UNLT
: return ARC_CC_LT
;
1254 case UNLE
: return ARC_CC_LE
;
1255 /* UNEQ and LTGT do not have representation. */
1256 case LTGT
: /* Fall through. */
1257 case UNEQ
: /* Fall through. */
1258 default : gcc_unreachable ();
1260 case E_CC_FPU_UNEQmode
:
1261 switch (GET_CODE (comparison
))
1263 case LTGT
: return ARC_CC_NE
;
1264 case UNEQ
: return ARC_CC_EQ
;
1265 default : gcc_unreachable ();
1267 default : gcc_unreachable ();
1273 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1276 arc_short_comparison_p (rtx comparison
, int offset
)
1278 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1279 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1280 switch (get_arc_condition_code (comparison
))
1282 case ARC_CC_EQ
: case ARC_CC_NE
:
1283 return offset
>= -512 && offset
<= 506;
1284 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1285 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1286 return offset
>= -64 && offset
<= 58;
1292 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1293 return the mode to be used for the comparison. */
1296 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1298 machine_mode mode
= GET_MODE (x
);
1301 /* For an operation that sets the condition codes as a side-effect, the
1302 C and V flags is not set as for cmp, so we can only use comparisons where
1303 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1305 /* ??? We could use "pnz" for greater than zero, however, we could then
1306 get into trouble because the comparison could not be reversed. */
1307 if (GET_MODE_CLASS (mode
) == MODE_INT
1309 && (op
== EQ
|| op
== NE
1310 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1313 /* add.f for if (a+b) */
1315 && GET_CODE (y
) == NEG
1316 && (op
== EQ
|| op
== NE
))
1319 /* Check if this is a test suitable for bxor.f . */
1320 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1321 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1325 /* Check if this is a test suitable for add / bmsk.f . */
1326 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1327 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1328 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1329 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1330 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1333 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1334 && GET_CODE (x
) == PLUS
1335 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1338 if (TARGET_ARGONAUT_SET
1339 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1342 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1344 case LT
: case UNGE
: case GT
: case UNLE
:
1345 return CC_FP_GTmode
;
1346 case LE
: case UNGT
: case GE
: case UNLT
:
1347 return CC_FP_GEmode
;
1348 default: gcc_unreachable ();
1350 else if (TARGET_HARD_FLOAT
1351 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1352 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1371 return CC_FPU_UNEQmode
;
1376 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1380 case EQ
: case NE
: return CC_Zmode
;
1382 case GT
: case UNLE
: return CC_FP_GTmode
;
1384 case GE
: case UNLT
: return CC_FP_GEmode
;
1385 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1386 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1387 default: gcc_unreachable ();
1393 /* Vectors to keep interesting information about registers where it can easily
1394 be got. We use to use the actual mode value as the bit number, but there
1395 is (or may be) more than 32 modes now. Instead we use two tables: one
1396 indexed by hard register number, and one indexed by mode. */
1398 /* The purpose of arc_mode_class is to shrink the range of modes so that
1399 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1400 mapped into one arc_mode_class mode. */
1402 enum arc_mode_class
{
1404 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1405 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1409 /* Modes for condition codes. */
1410 #define C_MODES (1 << (int) C_MODE)
1412 /* Modes for single-word and smaller quantities. */
1413 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1415 /* Modes for double-word and smaller quantities. */
1416 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1418 /* Mode for 8-byte DF values only. */
1419 #define DF_MODES (1 << DF_MODE)
1421 /* Modes for quad-word and smaller quantities. */
1422 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1424 /* Modes for 128-bit vectors. */
1425 #define V_MODES (1 << (int) V_MODE)
1427 /* Value is 1 if register/mode pair is acceptable on arc. */
1429 unsigned int arc_hard_regno_mode_ok
[] = {
1430 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1431 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1432 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1433 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1435 /* ??? Leave these as S_MODES for now. */
1436 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1437 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1438 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1439 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1441 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1442 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1443 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1444 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1446 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1447 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1448 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1449 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1451 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1452 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1455 unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1457 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1460 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1462 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1463 return GENERAL_REGS
;
1467 /* Initialize the arc_mode_class array. */
1470 arc_init_reg_tables (void)
1474 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1476 machine_mode m
= (machine_mode
) i
;
1478 switch (GET_MODE_CLASS (m
))
1481 case MODE_PARTIAL_INT
:
1482 case MODE_COMPLEX_INT
:
1483 if (GET_MODE_SIZE (m
) <= 4)
1484 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1485 else if (GET_MODE_SIZE (m
) == 8)
1486 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1487 else if (GET_MODE_SIZE (m
) == 16)
1488 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1489 else if (GET_MODE_SIZE (m
) == 32)
1490 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1492 arc_mode_class
[i
] = 0;
1495 case MODE_COMPLEX_FLOAT
:
1496 if (GET_MODE_SIZE (m
) <= 4)
1497 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1498 else if (GET_MODE_SIZE (m
) == 8)
1499 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1500 else if (GET_MODE_SIZE (m
) == 16)
1501 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1502 else if (GET_MODE_SIZE (m
) == 32)
1503 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1505 arc_mode_class
[i
] = 0;
1507 case MODE_VECTOR_INT
:
1508 if (GET_MODE_SIZE (m
) == 4)
1509 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1510 else if (GET_MODE_SIZE (m
) == 8)
1511 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1513 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1517 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1518 we must explicitly check for them here. */
1519 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1520 || i
== (int) CC_Cmode
1521 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1522 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1523 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1525 arc_mode_class
[i
] = 0;
1531 /* Core registers 56..59 are used for multiply extension options.
1532 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1533 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1534 number depends on endianness.
1535 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1536 Because mlo / mhi form a 64 bit value, we use different gcc internal
1537 register numbers to make them form a register pair as the gcc internals
1538 know it. mmid gets number 57, if still available, and mlo / mhi get
1539 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1540 to map this back. */
1541 char rname56
[5] = "r56";
1542 char rname57
[5] = "r57";
1543 char rname58
[5] = "r58";
1544 char rname59
[5] = "r59";
1545 char rname29
[7] = "ilink1";
1546 char rname30
[7] = "ilink2";
1549 arc_conditional_register_usage (void)
1553 int fix_start
= 60, fix_end
= 55;
1557 /* For ARCv2 the core register set is changed. */
1558 strcpy (rname29
, "ilink");
1559 strcpy (rname30
, "r30");
1560 call_used_regs
[30] = 1;
1563 arc_regno_reg_class
[30] = WRITABLE_CORE_REGS
;
1564 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], 30);
1565 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], 30);
1566 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], 30);
1567 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], 30);
1570 if (TARGET_MUL64_SET
)
1575 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1576 you are supposed to refer to it as mlo & mhi, e.g
1577 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1578 In an actual asm instruction, you are of course use mmed.
1579 The point of avoiding having a separate register for mmed is that
1580 this way, we don't have to carry clobbers of that reg around in every
1581 isntruction that modifies mlo and/or mhi. */
1582 strcpy (rname57
, "");
1583 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1584 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1587 /* The nature of arc_tp_regno is actually something more like a global
1588 register, however globalize_reg requires a declaration.
1589 We use EPILOGUE_USES to compensate so that sets from
1590 __builtin_set_frame_pointer are not deleted. */
1591 if (arc_tp_regno
!= -1)
1592 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1594 if (TARGET_MULMAC_32BY16_SET
)
1597 fix_end
= fix_end
> 57 ? fix_end
: 57;
1598 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1599 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1601 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1603 if (!fixed_regs
[regno
])
1604 warning (0, "multiply option implies r%d is fixed", regno
);
1605 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1611 reg_alloc_order
[0] = 0;
1612 reg_alloc_order
[1] = 1;
1613 reg_alloc_order
[2] = 2;
1614 reg_alloc_order
[3] = 3;
1615 reg_alloc_order
[4] = 12;
1616 reg_alloc_order
[5] = 13;
1617 reg_alloc_order
[6] = 14;
1618 reg_alloc_order
[7] = 15;
1619 reg_alloc_order
[8] = 4;
1620 reg_alloc_order
[9] = 5;
1621 reg_alloc_order
[10] = 6;
1622 reg_alloc_order
[11] = 7;
1623 reg_alloc_order
[12] = 8;
1624 reg_alloc_order
[13] = 9;
1625 reg_alloc_order
[14] = 10;
1626 reg_alloc_order
[15] = 11;
1630 reg_alloc_order
[2] = 12;
1631 reg_alloc_order
[3] = 13;
1632 reg_alloc_order
[4] = 14;
1633 reg_alloc_order
[5] = 15;
1634 reg_alloc_order
[6] = 1;
1635 reg_alloc_order
[7] = 0;
1636 reg_alloc_order
[8] = 4;
1637 reg_alloc_order
[9] = 5;
1638 reg_alloc_order
[10] = 6;
1639 reg_alloc_order
[11] = 7;
1640 reg_alloc_order
[12] = 8;
1641 reg_alloc_order
[13] = 9;
1642 reg_alloc_order
[14] = 10;
1643 reg_alloc_order
[15] = 11;
1646 if (TARGET_SIMD_SET
)
1649 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1650 reg_alloc_order
[i
] = i
;
1651 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1652 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1653 reg_alloc_order
[i
] = i
;
1655 /* For ARC600, lp_count may not be read in an instruction
1656 following immediately after another one setting it to a new value.
1657 There was some discussion on how to enforce scheduling constraints for
1658 processors with missing interlocks on the gcc mailing list:
1659 http://gcc.gnu.org/ml/gcc/2008-05/msg00021.html .
1660 However, we can't actually use this approach, because for ARC the
1661 delay slot scheduling pass is active, which runs after
1662 machine_dependent_reorg. */
1664 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1665 else if (!TARGET_LP_WR_INTERLOCK
)
1666 fixed_regs
[LP_COUNT
] = 1;
1667 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1668 if (!call_used_regs
[regno
])
1669 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1670 for (regno
= 32; regno
< 60; regno
++)
1671 if (!fixed_regs
[regno
])
1672 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1673 if (!TARGET_ARC600_FAMILY
)
1675 for (regno
= 32; regno
<= 60; regno
++)
1676 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1678 /* If they have used -ffixed-lp_count, make sure it takes
1680 if (fixed_regs
[LP_COUNT
])
1682 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1683 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1684 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1686 /* Instead of taking out SF_MODE like below, forbid it outright. */
1687 arc_hard_regno_mode_ok
[60] = 0;
1690 arc_hard_regno_mode_ok
[60] = 1 << (int) S_MODE
;
1693 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1697 for (regno
= 1; regno
< 32; regno
+=2)
1699 arc_hard_regno_mode_ok
[regno
] = S_MODES
;
1703 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1707 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1708 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1709 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1711 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1714 arc_regno_reg_class
[i
]
1716 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1717 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1718 : (((!TARGET_ARC600_FAMILY
)
1719 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1720 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1722 arc_regno_reg_class
[i
] = NO_REGS
;
1725 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1726 has not been activated. */
1727 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1728 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1729 if (!TARGET_Q_CLASS
)
1730 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1732 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1734 /* Handle Special Registers. */
1735 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1737 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1738 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1739 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1740 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1741 arc_regno_reg_class
[62] = GENERAL_REGS
;
1745 for (i
= 40; i
< 44; ++i
)
1747 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1749 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1750 no attempt is made to use such a register as a destination
1751 operand in *movdf_insn. */
1752 if (!TARGET_ARGONAUT_SET
)
1754 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1755 interpreted to mean they can use D1 or D2 in their insn. */
1756 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1757 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1758 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1759 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1765 /* Disable all DOUBLE_REGISTER settings,
1766 if not generating DPFP code. */
1767 arc_regno_reg_class
[40] = ALL_REGS
;
1768 arc_regno_reg_class
[41] = ALL_REGS
;
1769 arc_regno_reg_class
[42] = ALL_REGS
;
1770 arc_regno_reg_class
[43] = ALL_REGS
;
1777 arc_hard_regno_mode_ok
[40] = 0;
1778 arc_hard_regno_mode_ok
[42] = 0;
1780 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1783 if (TARGET_SIMD_SET
)
1785 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1786 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1788 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1789 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1791 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1792 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1793 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1794 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1796 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1797 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1798 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1802 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
1804 /*ARCV2 Accumulator. */
1806 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1807 || TARGET_PLUS_DMPY
)
1809 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
1810 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
1811 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
1812 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
1813 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
1814 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
1815 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCL_REGNO
);
1816 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCH_REGNO
);
1817 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCL_REGNO
);
1818 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCH_REGNO
);
1820 /* Allow the compiler to freely use them. */
1821 fixed_regs
[ACCL_REGNO
] = 0;
1822 fixed_regs
[ACCH_REGNO
] = 0;
1824 arc_hard_regno_mode_ok
[ACC_REG_FIRST
] = D_MODES
;
1828 /* Handle an "interrupt" attribute; arguments as in
1829 struct attribute_spec.handler. */
1832 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
1837 tree value
= TREE_VALUE (args
);
1839 if (TREE_CODE (value
) != STRING_CST
)
1841 warning (OPT_Wattributes
,
1842 "argument of %qE attribute is not a string constant",
1844 *no_add_attrs
= true;
1847 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
1848 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
1850 warning (OPT_Wattributes
,
1851 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1853 *no_add_attrs
= true;
1856 && strcmp (TREE_STRING_POINTER (value
), "ilink")
1857 && strcmp (TREE_STRING_POINTER (value
), "firq"))
1859 warning (OPT_Wattributes
,
1860 "argument of %qE attribute is not \"ilink\" or \"firq\"",
1862 *no_add_attrs
= true;
1869 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
1870 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
1872 if (TREE_CODE (*node
) != FUNCTION_DECL
)
1874 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
1876 *no_add_attrs
= true;
1882 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
1885 arc_allocate_stack_slots_for_args (void)
1887 /* Naked functions should not allocate stack slots for arguments. */
1888 unsigned int fn_type
= arc_compute_function_type (cfun
);
1890 return !ARC_NAKED_P(fn_type
);
1893 /* Implement `TARGET_WARN_FUNC_RETURN'. */
1896 arc_warn_func_return (tree decl
)
1898 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
1899 unsigned int fn_type
= arc_compute_function_type (func
);
1901 return !ARC_NAKED_P (fn_type
);
1904 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1905 and two if they are nearly compatible (which causes a warning to be
1909 arc_comp_type_attributes (const_tree type1
,
1912 int l1
, l2
, m1
, m2
, s1
, s2
;
1914 /* Check for mismatch of non-default calling convention. */
1915 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
1918 /* Check for mismatched call attributes. */
1919 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1920 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1921 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1922 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1923 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1924 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1926 /* Only bother to check if an attribute is defined. */
1927 if (l1
| l2
| m1
| m2
| s1
| s2
)
1929 /* If one type has an attribute, the other must have the same attribute. */
1930 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
1933 /* Disallow mixed attributes. */
1934 if (l1
+ m1
+ s1
> 1)
1942 /* Set the default attributes for TYPE. */
1945 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED
)
1950 /* Misc. utilities. */
1952 /* X and Y are two things to compare using CODE. Emit the compare insn and
1953 return the rtx for the cc reg in the proper mode. */
1956 gen_compare_reg (rtx comparison
, machine_mode omode
)
1958 enum rtx_code code
= GET_CODE (comparison
);
1959 rtx x
= XEXP (comparison
, 0);
1960 rtx y
= XEXP (comparison
, 1);
1962 machine_mode mode
, cmode
;
1965 cmode
= GET_MODE (x
);
1966 if (cmode
== VOIDmode
)
1967 cmode
= GET_MODE (y
);
1968 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
1969 if (cmode
== SImode
)
1971 if (!register_operand (x
, SImode
))
1973 if (register_operand (y
, SImode
))
1978 code
= swap_condition (code
);
1981 x
= copy_to_mode_reg (SImode
, x
);
1983 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
1984 y
= copy_to_mode_reg (SImode
, y
);
1988 x
= force_reg (cmode
, x
);
1989 y
= force_reg (cmode
, y
);
1991 mode
= SELECT_CC_MODE (code
, x
, y
);
1993 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
1995 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
1996 cmpdfpx_raw, is not a correct comparison for floats:
1997 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1999 if (TARGET_ARGONAUT_SET
2000 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2004 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2005 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2007 case GT
: case UNLE
: case GE
: case UNLT
:
2008 code
= swap_condition (code
);
2016 if (cmode
== SFmode
)
2018 emit_insn (gen_cmpsfpx_raw (x
, y
));
2022 /* Accepts Dx regs directly by insns. */
2023 emit_insn (gen_cmpdfpx_raw (x
, y
));
2026 if (mode
!= CC_FPXmode
)
2027 emit_insn (gen_rtx_SET (cc_reg
,
2028 gen_rtx_COMPARE (mode
,
2029 gen_rtx_REG (CC_FPXmode
, 61),
2032 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2036 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2037 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2039 case LT
: case UNGE
: case LE
: case UNGT
:
2040 code
= swap_condition (code
);
2049 emit_insn (gen_cmp_quark (cc_reg
,
2050 gen_rtx_COMPARE (mode
, x
, y
)));
2052 else if (TARGET_HARD_FLOAT
2053 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2054 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2055 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2056 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2058 rtx op0
= gen_rtx_REG (cmode
, 0);
2059 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2064 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2065 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2067 case LT
: case UNGE
: case LE
: case UNGT
:
2068 code
= swap_condition (code
);
2074 if (currently_expanding_to_rtl
)
2082 emit_move_insn (op0
, x
);
2083 emit_move_insn (op1
, y
);
2087 gcc_assert (rtx_equal_p (op0
, x
));
2088 gcc_assert (rtx_equal_p (op1
, y
));
2095 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2098 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2099 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2102 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2103 We assume the value can be either signed or unsigned. */
2106 arc_double_limm_p (rtx value
)
2108 HOST_WIDE_INT low
, high
;
2110 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2115 low
= CONST_DOUBLE_LOW (value
);
2116 high
= CONST_DOUBLE_HIGH (value
);
2118 if (low
& 0x80000000)
2120 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2121 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2122 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2127 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2131 /* Do any needed setup for a variadic function. For the ARC, we must
2132 create a register parameter block, and then copy any anonymous arguments
2133 in registers to memory.
2135 CUM has not been updated for the last named argument which has type TYPE
2136 and mode MODE, and we rely on this fact. */
2139 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2140 machine_mode mode
, tree type
,
2141 int *pretend_size
, int no_rtl
)
2144 CUMULATIVE_ARGS next_cum
;
2146 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2148 next_cum
= *get_cumulative_args (args_so_far
);
2149 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2151 first_anon_arg
= next_cum
;
2153 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2155 /* First anonymous (unnamed) argument is in a reg. */
2157 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2158 int first_reg_offset
= first_anon_arg
;
2163 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2164 FIRST_PARM_OFFSET (0)));
2165 move_block_from_reg (first_reg_offset
, regblock
,
2166 MAX_ARC_PARM_REGS
- first_reg_offset
);
2170 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2174 /* Cost functions. */
2176 /* Provide the costs of an addressing mode that contains ADDR.
2177 If ADDR is not a valid address, its cost is irrelevant. */
2180 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2182 switch (GET_CODE (addr
))
2185 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2186 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2187 case PRE_MODIFY
: case POST_MODIFY
:
2193 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2195 /* Most likely needs a LIMM. */
2196 return COSTS_N_INSNS (1);
2200 register rtx plus0
= XEXP (addr
, 0);
2201 register rtx plus1
= XEXP (addr
, 1);
2203 if (GET_CODE (plus0
) != REG
2204 && (GET_CODE (plus0
) != MULT
2205 || !CONST_INT_P (XEXP (plus0
, 1))
2206 || (INTVAL (XEXP (plus0
, 1)) != 2
2207 && INTVAL (XEXP (plus0
, 1)) != 4)))
2210 switch (GET_CODE (plus1
))
2213 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2217 : (satisfies_constraint_Rcq (plus0
)
2218 && satisfies_constraint_O (plus1
))
2222 return (speed
< 1 ? 0
2223 : (satisfies_constraint_Rcq (plus0
)
2224 && satisfies_constraint_Rcq (plus1
))
2229 return COSTS_N_INSNS (1);
2242 /* Emit instruction X with the frame related bit set. */
2248 RTX_FRAME_RELATED_P (x
) = 1;
2252 /* Emit a frame insn to move SRC to DST. */
2255 frame_move (rtx dst
, rtx src
)
2257 rtx tmp
= gen_rtx_SET (dst
, src
);
2258 RTX_FRAME_RELATED_P (tmp
) = 1;
2259 return frame_insn (tmp
);
2262 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2263 auto increment address, or is zero. */
2266 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2268 rtx insn
= frame_move (dst
, src
);
2271 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2272 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2273 add_reg_note (insn
, REG_INC
, reg
);
2277 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2280 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2282 gcc_assert ((offset
& 0x3) == 0);
2285 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2288 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2291 frame_stack_add (HOST_WIDE_INT offset
)
2293 return frame_add (stack_pointer_rtx
, offset
);
2296 /* Traditionally, we push saved registers first in the prologue,
2297 then we allocate the rest of the frame - and reverse in the epilogue.
2298 This has still its merits for ease of debugging, or saving code size
2299 or even execution time if the stack frame is so large that some accesses
2300 can't be encoded anymore with offsets in the instruction code when using
2302 Also, it would be a good starting point if we got instructions to help
2303 with register save/restore.
2305 However, often stack frames are small, and the pushing / popping has
2307 - the stack modification prevents a lot of scheduling.
2308 - frame allocation / deallocation needs extra instructions.
2309 - unless we know that we compile ARC700 user code, we need to put
2310 a memory barrier after frame allocation / before deallocation to
2311 prevent interrupts clobbering our data in the frame.
2312 In particular, we don't have any such guarantees for library functions,
2313 which tend to, on the other hand, to have small frames.
2315 Thus, for small frames, we'd like to use a different scheme:
2316 - The frame is allocated in full with the first prologue instruction,
2317 and deallocated in full with the last epilogue instruction.
2318 Thus, the instructions in-betwen can be freely scheduled.
2319 - If the function has no outgoing arguments on the stack, we can allocate
2320 one register save slot at the top of the stack. This register can then
2321 be saved simultanously with frame allocation, and restored with
2323 This register can be picked depending on scheduling considerations,
2324 although same though should go into having some set of registers
2325 to be potentially lingering after a call, and others to be available
2326 immediately - i.e. in the absence of interprocedual optimization, we
2327 can use an ABI-like convention for register allocation to reduce
2328 stalls after function return. */
2329 /* Function prologue/epilogue handlers. */
2331 /* ARCompact stack frames look like:
2333 Before call After call
2334 high +-----------------------+ +-----------------------+
2335 mem | reg parm save area | | reg parm save area |
2336 | only created for | | only created for |
2337 | variable arg fns | | variable arg fns |
2338 AP +-----------------------+ +-----------------------+
2339 | return addr register | | return addr register |
2340 | (if required) | | (if required) |
2341 +-----------------------+ +-----------------------+
2343 | reg save area | | reg save area |
2345 +-----------------------+ +-----------------------+
2346 | frame pointer | | frame pointer |
2347 | (if required) | | (if required) |
2348 FP +-----------------------+ +-----------------------+
2350 | local/temp variables | | local/temp variables |
2352 +-----------------------+ +-----------------------+
2354 | arguments on stack | | arguments on stack |
2356 SP +-----------------------+ +-----------------------+
2357 | reg parm save area |
2358 | only created for |
2359 | variable arg fns |
2360 AP +-----------------------+
2361 | return addr register |
2363 +-----------------------+
2367 +-----------------------+
2370 FP +-----------------------+
2372 | local/temp variables |
2374 +-----------------------+
2376 | arguments on stack |
2378 mem SP +-----------------------+
2381 1) The "reg parm save area" does not exist for non variable argument fns.
2382 The "reg parm save area" can be eliminated completely if we created our
2383 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2385 /* Structure to be filled in by arc_compute_frame_size with register
2386 save masks, and offsets for the current function. */
2387 struct GTY (()) arc_frame_info
2389 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2390 unsigned int extra_size
; /* # bytes of extra stuff. */
2391 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2392 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2393 unsigned int reg_size
; /* # bytes needed to store regs. */
2394 unsigned int var_size
; /* # bytes that variables take up. */
2395 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2396 unsigned int gmask
; /* Mask of saved gp registers. */
2397 int initialized
; /* Nonzero if frame size already calculated. */
2398 short millicode_start_reg
;
2399 short millicode_end_reg
;
2400 bool save_return_addr
;
2403 /* Defining data structures for per-function information. */
2405 typedef struct GTY (()) machine_function
2407 unsigned int fn_type
;
2408 struct arc_frame_info frame_info
;
2409 /* To keep track of unalignment caused by short insns. */
2411 int force_short_suffix
; /* Used when disgorging return delay slot insns. */
2412 const char *size_reason
;
2413 struct arc_ccfsm ccfsm_current
;
2414 /* Map from uid to ccfsm state during branch shortening. */
2415 rtx ccfsm_current_insn
;
2416 char arc_reorg_started
;
2417 char prescan_initialized
;
2420 /* Type of function DECL.
2422 The result is cached. To reset the cache at the end of a function,
2423 call with DECL = NULL_TREE. */
2426 arc_compute_function_type (struct function
*fun
)
2428 tree attr
, decl
= fun
->decl
;
2429 unsigned int fn_type
= fun
->machine
->fn_type
;
2431 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2434 /* Check if it is a naked function. */
2435 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2436 fn_type
|= ARC_FUNCTION_NAKED
;
2438 fn_type
|= ARC_FUNCTION_NORMAL
;
2440 /* Now see if this is an interrupt handler. */
2441 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2442 if (attr
!= NULL_TREE
)
2444 tree value
, args
= TREE_VALUE (attr
);
2446 gcc_assert (list_length (args
) == 1);
2447 value
= TREE_VALUE (args
);
2448 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2450 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2451 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2452 fn_type
|= ARC_FUNCTION_ILINK1
;
2453 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2454 fn_type
|= ARC_FUNCTION_ILINK2
;
2455 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2456 fn_type
|= ARC_FUNCTION_FIRQ
;
2461 return fun
->machine
->fn_type
= fn_type
;
2464 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2465 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2467 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2468 The return address and frame pointer are treated separately.
2469 Don't consider them here.
2470 Addition for pic: The gp register needs to be saved if the current
2471 function changes it to access gotoff variables.
2472 FIXME: This will not be needed if we used some arbitrary register
2477 arc_must_save_register (int regno
, struct function
*func
)
2479 unsigned int fn_type
= arc_compute_function_type (func
);
2480 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2481 && ARC_AUTO_IRQ_P (fn_type
));
2482 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2484 switch (rgf_banked_register_count
)
2487 firq_auto_save_p
&= (regno
< 4);
2490 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2493 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2494 || ((regno
> 25) && (regno
< 29))
2495 || ((regno
> 29) && (regno
< 32)));
2498 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2501 firq_auto_save_p
= false;
2505 if ((regno
) != RETURN_ADDR_REGNUM
2506 && (regno
) != FRAME_POINTER_REGNUM
2507 && df_regs_ever_live_p (regno
)
2508 && (!call_used_regs
[regno
]
2509 || ARC_INTERRUPT_P (fn_type
))
2510 /* Do not emit code for auto saved regs. */
2512 && !firq_auto_save_p
)
2515 if (flag_pic
&& crtl
->uses_pic_offset_table
2516 && regno
== PIC_OFFSET_TABLE_REGNUM
)
2522 /* Return true if the return address must be saved in the current function,
2523 otherwise return false. */
2526 arc_must_save_return_addr (struct function
*func
)
2528 if (func
->machine
->frame_info
.save_return_addr
)
2534 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2535 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2536 Register Allocator) pass, while we want to get the frame size
2537 correct earlier than the IRA pass. */
2539 arc_frame_pointer_needed (void)
2541 return (frame_pointer_needed
);
2545 /* Return non-zero if there are registers to be saved or loaded using
2546 millicode thunks. We can only use consecutive sequences starting
2547 with r13, and not going beyond r25.
2548 GMASK is a bitmask of registers to save. This function sets
2549 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2550 of registers to be saved / restored with a millicode call. */
2553 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2554 struct arc_frame_info
*frame
)
2558 int start_reg
= 13, end_reg
= 25;
2560 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2562 end_reg
= regno
- 1;
2563 /* There is no point in using millicode thunks if we don't save/restore
2564 at least three registers. For non-leaf functions we also have the
2566 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2568 frame
->millicode_start_reg
= 13;
2569 frame
->millicode_end_reg
= regno
- 1;
2575 /* Return the bytes needed to compute the frame pointer from the current
2578 SIZE is the size needed for local variables. */
2581 arc_compute_frame_size (int size
) /* size = # of var. bytes allocated. */
2584 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2585 unsigned int reg_size
, reg_offset
;
2587 struct arc_frame_info
*frame_info
= &cfun
->machine
->frame_info
;
2589 size
= ARC_STACK_ALIGN (size
);
2591 /* 1) Size of locals and temporaries */
2594 /* 2) Size of outgoing arguments */
2595 args_size
= crtl
->outgoing_args_size
;
2597 /* 3) Calculate space needed for saved registers.
2598 ??? We ignore the extension registers for now. */
2600 /* See if this is an interrupt handler. Call used registers must be saved
2606 for (regno
= 0; regno
<= 31; regno
++)
2608 if (arc_must_save_register (regno
, cfun
))
2610 reg_size
+= UNITS_PER_WORD
;
2611 gmask
|= 1L << regno
;
2615 /* 4) Space for back trace data structure.
2616 <return addr reg size> (if required) + <fp size> (if required). */
2617 frame_info
->save_return_addr
2618 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
));
2619 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2620 if (optimize_size
&& !TARGET_NO_MILLICODE_THUNK_SET
)
2622 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2623 frame_info
->save_return_addr
= true;
2627 if (arc_must_save_return_addr (cfun
))
2629 if (arc_frame_pointer_needed ())
2632 /* 5) Space for variable arguments passed in registers */
2633 pretend_size
= crtl
->args
.pretend_args_size
;
2635 /* Ensure everything before the locals is aligned appropriately. */
2637 unsigned int extra_plus_reg_size
;
2638 unsigned int extra_plus_reg_size_aligned
;
2640 extra_plus_reg_size
= extra_size
+ reg_size
;
2641 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2642 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2645 /* Compute total frame size. */
2646 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2648 total_size
= ARC_STACK_ALIGN (total_size
);
2650 /* Compute offset of register save area from stack pointer:
2651 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2653 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2654 + (arc_frame_pointer_needed () ? 4 : 0));
2656 /* Save computed information. */
2657 frame_info
->total_size
= total_size
;
2658 frame_info
->extra_size
= extra_size
;
2659 frame_info
->pretend_size
= pretend_size
;
2660 frame_info
->var_size
= var_size
;
2661 frame_info
->args_size
= args_size
;
2662 frame_info
->reg_size
= reg_size
;
2663 frame_info
->reg_offset
= reg_offset
;
2664 frame_info
->gmask
= gmask
;
2665 frame_info
->initialized
= reload_completed
;
2667 /* Ok, we're done. */
2671 /* Common code to save/restore registers. */
2672 /* BASE_REG is the base register to use for addressing and to adjust.
2673 GMASK is a bitmask of general purpose registers to save/restore.
2674 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2675 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2676 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2680 arc_save_restore (rtx base_reg
,
2681 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2683 unsigned int offset
= 0;
2685 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2686 rtx sibthunk_insn
= NULL_RTX
;
2690 /* Millicode thunks implementation:
2691 Generates calls to millicodes for registers starting from r13 to r25
2692 Present Limitations:
2693 - Only one range supported. The remaining regs will have the ordinary
2694 st and ld instructions for store and loads. Hence a gmask asking
2695 to store r13-14, r16-r25 will only generate calls to store and
2696 load r13 to r14 while store and load insns will be generated for
2697 r16 to r25 in the prologue and epilogue respectively.
2699 - Presently library only supports register ranges starting from r13.
2701 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2703 int start_call
= frame
->millicode_start_reg
;
2704 int end_call
= frame
->millicode_end_reg
;
2705 int n_regs
= end_call
- start_call
+ 1;
2706 int i
= 0, r
, off
= 0;
2708 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2712 /* "reg_size" won't be more than 127 . */
2713 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
2714 frame_add (base_reg
, *first_offset
);
2717 insn
= gen_rtx_PARALLEL
2718 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
2719 if (epilogue_p
== 2)
2722 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
2723 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
2725 rtx reg
= gen_rtx_REG (SImode
, r
);
2727 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
2730 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
2732 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
2733 gmask
= gmask
& ~(1L << r
);
2735 if (epilogue_p
== 2)
2736 sibthunk_insn
= insn
;
2739 insn
= frame_insn (insn
);
2741 for (r
= start_call
; r
<= end_call
; r
++)
2743 rtx reg
= gen_rtx_REG (SImode
, r
);
2744 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2750 for (regno
= 0; regno
<= 31; regno
++)
2752 machine_mode mode
= SImode
;
2757 && ((gmask
& (1L << regno
)) != 0)
2758 && ((gmask
& (1L << (regno
+1))) != 0))
2763 else if ((gmask
& (1L << regno
)) != 0)
2771 rtx reg
= gen_rtx_REG (mode
, regno
);
2773 int cfa_adjust
= *first_offset
;
2777 gcc_assert (!offset
);
2778 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
2779 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
2784 gcc_assert (SMALL_INT (offset
));
2785 addr
= plus_constant (Pmode
, base_reg
, offset
);
2787 mem
= gen_frame_mem (mode
, addr
);
2791 frame_move_inc (reg
, mem
, base_reg
, addr
);
2792 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2795 enum reg_note note
= REG_CFA_ADJUST_CFA
;
2796 add_reg_note (insn
, note
,
2797 gen_rtx_SET (stack_pointer_rtx
,
2798 plus_constant (Pmode
,
2804 frame_move_inc (mem
, reg
, base_reg
, addr
);
2805 offset
+= UNITS_PER_WORD
;
2808 offset
+= UNITS_PER_WORD
;
2816 int start_call
= frame
->millicode_start_reg
;
2817 int end_call
= frame
->millicode_end_reg
;
2820 rtx r12
= gen_rtx_REG (Pmode
, 12);
2822 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
2823 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
2824 XVECEXP (sibthunk_insn
, 0, 1)
2825 = gen_rtx_SET (stack_pointer_rtx
,
2826 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
2827 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
2828 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
2830 /* Would be nice if we could do this earlier, when the PARALLEL
2831 is populated, but these need to be attached after the
2833 for (r
= start_call
; r
<= end_call
; r
++)
2835 rtx reg
= gen_rtx_REG (SImode
, r
);
2836 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
2839 } /* arc_save_restore */
2841 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2845 arc_dwarf_emit_irq_save_regs (void)
2847 rtx tmp
, par
, insn
, reg
;
2850 par
= gen_rtx_SEQUENCE (VOIDmode
,
2851 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2852 + irq_ctrl_saved
.irq_save_blink
2853 + irq_ctrl_saved
.irq_save_lpcount
2856 /* Build the stack adjustment note for unwind info. */
2858 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2859 + irq_ctrl_saved
.irq_save_blink
2860 + irq_ctrl_saved
.irq_save_lpcount
);
2861 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2862 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2863 RTX_FRAME_RELATED_P (tmp
) = 1;
2864 XVECEXP (par
, 0, j
++) = tmp
;
2866 offset
-= UNITS_PER_WORD
;
2868 /* 1st goes LP_COUNT. */
2869 if (irq_ctrl_saved
.irq_save_lpcount
)
2871 reg
= gen_rtx_REG (SImode
, 60);
2872 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2873 tmp
= gen_frame_mem (SImode
, tmp
);
2874 tmp
= gen_rtx_SET (tmp
, reg
);
2875 RTX_FRAME_RELATED_P (tmp
) = 1;
2876 XVECEXP (par
, 0, j
++) = tmp
;
2877 offset
-= UNITS_PER_WORD
;
2880 /* 2nd goes BLINK. */
2881 if (irq_ctrl_saved
.irq_save_blink
)
2883 reg
= gen_rtx_REG (SImode
, 31);
2884 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2885 tmp
= gen_frame_mem (SImode
, tmp
);
2886 tmp
= gen_rtx_SET (tmp
, reg
);
2887 RTX_FRAME_RELATED_P (tmp
) = 1;
2888 XVECEXP (par
, 0, j
++) = tmp
;
2889 offset
-= UNITS_PER_WORD
;
2892 /* Build the parallel of the remaining registers recorded as saved
2894 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
2896 reg
= gen_rtx_REG (SImode
, i
);
2897 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2898 tmp
= gen_frame_mem (SImode
, tmp
);
2899 tmp
= gen_rtx_SET (tmp
, reg
);
2900 RTX_FRAME_RELATED_P (tmp
) = 1;
2901 XVECEXP (par
, 0, j
++) = tmp
;
2902 offset
-= UNITS_PER_WORD
;
2905 /* Dummy insn used to anchor the dwarf info. */
2906 insn
= emit_insn (gen_stack_irq_dwarf());
2907 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
2908 RTX_FRAME_RELATED_P (insn
) = 1;
2911 /* Set up the stack and frame pointer (if desired) for the function. */
2914 arc_expand_prologue (void)
2916 int size
= get_frame_size ();
2917 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
2918 /* unsigned int frame_pointer_offset;*/
2919 unsigned int frame_size_to_allocate
;
2920 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2921 Change the stack layout so that we rather store a high register with the
2922 PRE_MODIFY, thus enabling more short insn generation.) */
2923 int first_offset
= 0;
2924 unsigned int fn_type
= arc_compute_function_type (cfun
);
2926 /* Naked functions don't have prologue. */
2927 if (ARC_NAKED_P (fn_type
))
2930 size
= ARC_STACK_ALIGN (size
);
2932 /* Compute/get total frame size. */
2933 size
= (!cfun
->machine
->frame_info
.initialized
2934 ? arc_compute_frame_size (size
)
2935 : cfun
->machine
->frame_info
.total_size
);
2937 if (flag_stack_usage_info
)
2938 current_function_static_stack_size
= size
;
2940 /* Keep track of frame size to be allocated. */
2941 frame_size_to_allocate
= size
;
2943 /* These cases shouldn't happen. Catch them now. */
2944 gcc_assert (!(size
== 0 && gmask
));
2946 /* Allocate space for register arguments if this is a variadic function. */
2947 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
2949 /* Ensure pretend_size is maximum of 8 * word_size. */
2950 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
2952 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
2953 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
2956 /* IRQ using automatic save mechanism will save the register before
2958 if (ARC_AUTO_IRQ_P (fn_type
)
2959 && !ARC_FAST_INTERRUPT_P (fn_type
))
2961 arc_dwarf_emit_irq_save_regs ();
2964 /* The home-grown ABI says link register is saved first. */
2965 if (arc_must_save_return_addr (cfun
)
2966 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
2968 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
2969 rtx mem
= gen_frame_mem (Pmode
,
2970 gen_rtx_PRE_DEC (Pmode
,
2971 stack_pointer_rtx
));
2973 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
2974 frame_size_to_allocate
-= UNITS_PER_WORD
;
2977 /* Save any needed call-saved regs (and call-used if this is an
2978 interrupt handler) for ARCompact ISA. */
2979 if (cfun
->machine
->frame_info
.reg_size
)
2981 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
2982 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
2983 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
2984 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
2987 /* Save frame pointer if needed. First save the FP on stack, if not
2989 if (arc_frame_pointer_needed ()
2990 && !ARC_AUTOFP_IRQ_P (fn_type
))
2992 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
2993 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
2994 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
2997 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
2998 frame_size_to_allocate
-= UNITS_PER_WORD
;
3002 /* Emit mov fp,sp. */
3003 if (arc_frame_pointer_needed ())
3005 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3008 /* ??? We don't handle the case where the saved regs are more than 252
3009 bytes away from sp. This can be handled by decrementing sp once, saving
3010 the regs, and then decrementing it again. The epilogue doesn't have this
3011 problem as the `ld' insn takes reg+limm values (though it would be more
3012 efficient to avoid reg+limm). */
3014 frame_size_to_allocate
-= first_offset
;
3015 /* Allocate the stack frame. */
3016 if (frame_size_to_allocate
> 0)
3018 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3019 /* If the frame pointer is needed, emit a special barrier that
3020 will prevent the scheduler from moving stores to the frame
3021 before the stack adjustment. */
3022 if (arc_frame_pointer_needed ())
3023 emit_insn (gen_stack_tie (stack_pointer_rtx
,
3024 hard_frame_pointer_rtx
));
3027 /* Setup the gp register, if needed. */
3028 if (crtl
->uses_pic_offset_table
)
3029 arc_finalize_pic ();
3032 /* Do any necessary cleanup after a function to restore stack, frame,
3036 arc_expand_epilogue (int sibcall_p
)
3038 int size
= get_frame_size ();
3039 unsigned int fn_type
= arc_compute_function_type (cfun
);
3041 size
= ARC_STACK_ALIGN (size
);
3042 size
= (!cfun
->machine
->frame_info
.initialized
3043 ? arc_compute_frame_size (size
)
3044 : cfun
->machine
->frame_info
.total_size
);
3046 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
3047 unsigned int frame_size
;
3048 unsigned int size_to_deallocate
;
3050 int can_trust_sp_p
= !cfun
->calls_alloca
;
3051 int first_offset
= 0;
3052 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
3055 /* Naked functions don't have epilogue. */
3056 if (ARC_NAKED_P (fn_type
))
3059 size_to_deallocate
= size
;
3061 frame_size
= size
- (pretend_size
+
3062 cfun
->machine
->frame_info
.reg_size
+
3063 cfun
->machine
->frame_info
.extra_size
);
3065 /* ??? There are lots of optimizations that can be done here.
3066 EG: Use fp to restore regs if it's closer.
3067 Maybe in time we'll do them all. For now, always restore regs from
3068 sp, but don't restore sp if we don't have to. */
3070 if (!can_trust_sp_p
)
3071 gcc_assert (arc_frame_pointer_needed ());
3073 /* Restore stack pointer to the beginning of saved register area for
3077 if (arc_frame_pointer_needed ())
3078 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3080 first_offset
= frame_size
;
3081 size_to_deallocate
-= frame_size
;
3083 else if (!can_trust_sp_p
)
3084 frame_stack_add (-frame_size
);
3087 /* Restore any saved registers. */
3088 if (arc_frame_pointer_needed ()
3089 && !ARC_AUTOFP_IRQ_P (fn_type
))
3091 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
3093 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
3094 stack_pointer_rtx
, 0);
3095 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3096 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3097 plus_constant (SImode
, stack_pointer_rtx
,
3099 size_to_deallocate
-= UNITS_PER_WORD
;
3102 /* Load blink after the calls to thunk calls in case of optimize size. */
3105 int sibthunk_p
= (!sibcall_p
3106 && fn_type
== ARC_FUNCTION_NORMAL
3107 && !cfun
->machine
->frame_info
.pretend_size
);
3109 gcc_assert (!(cfun
->machine
->frame_info
.gmask
3110 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
3111 arc_save_restore (stack_pointer_rtx
,
3112 cfun
->machine
->frame_info
.gmask
,
3113 1 + sibthunk_p
, &first_offset
);
3117 /* If we are to restore registers, and first_offset would require
3118 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3119 fast add to the stack pointer, do this now. */
3120 if ((!SMALL_INT (first_offset
)
3121 && cfun
->machine
->frame_info
.gmask
3122 && ((TARGET_ARC700
&& !optimize_size
)
3123 ? first_offset
<= 0x800
3124 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
3125 /* Also do this if we have both gprs and return
3126 address to restore, and they both would need a LIMM. */
3127 || (arc_must_save_return_addr (cfun
)
3128 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
3129 && cfun
->machine
->frame_info
.gmask
))
3131 frame_stack_add (first_offset
);
3134 if (arc_must_save_return_addr (cfun
)
3135 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3137 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3138 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
3139 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
3140 HOST_WIDE_INT cfa_adjust
= 0;
3142 /* If the load of blink would need a LIMM, but we can add
3143 the offset quickly to sp, do the latter. */
3144 if (!SMALL_INT (ra_offs
>> 2)
3145 && !cfun
->machine
->frame_info
.gmask
3146 && ((TARGET_ARC700
&& !optimize_size
)
3148 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
3150 size_to_deallocate
-= ra_offs
- first_offset
;
3152 frame_stack_add (ra_offs
);
3154 addr
= stack_pointer_rtx
;
3156 /* See if we can combine the load of the return address with the
3157 final stack adjustment.
3158 We need a separate load if there are still registers to
3159 restore. We also want a separate load if the combined insn
3160 would need a limm, but a separate load doesn't. */
3162 && !cfun
->machine
->frame_info
.gmask
3163 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
3165 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
3166 cfa_adjust
= ra_offs
;
3168 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
3170 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
3172 addr
= gen_rtx_POST_INC (Pmode
, addr
);
3173 cfa_adjust
= GET_MODE_SIZE (Pmode
);
3174 size_to_deallocate
= 0;
3177 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
3178 stack_pointer_rtx
, addr
);
3181 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3183 add_reg_note (insn
, note
,
3184 gen_rtx_SET (stack_pointer_rtx
,
3185 plus_constant (SImode
, stack_pointer_rtx
,
3188 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
3193 if (cfun
->machine
->frame_info
.reg_size
)
3194 arc_save_restore (stack_pointer_rtx
,
3195 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3196 cfun
->machine
->frame_info
.gmask
3197 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
3200 /* The rest of this function does the following:
3201 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3204 /* Keep track of how much of the stack pointer we've restored.
3205 It makes the following a lot more readable. */
3206 size_to_deallocate
+= first_offset
;
3207 restored
= size
- size_to_deallocate
;
3209 if (size
> restored
)
3210 frame_stack_add (size
- restored
);
3212 /* Emit the return instruction. */
3213 if (sibcall_p
== FALSE
)
3214 emit_jump_insn (gen_simple_return ());
3217 /* Return the offset relative to the stack pointer where the return address
3218 is stored, or -1 if it is not stored. */
3221 arc_return_slot_offset ()
3223 struct arc_frame_info
*afi
= &cfun
->machine
->frame_info
;
3225 return (afi
->save_return_addr
3226 ? afi
->total_size
- afi
->pretend_size
- afi
->extra_size
: -1);
3231 /* Helper to generate unspec constant. */
3234 arc_unspec_offset (rtx loc
, int unspec
)
3236 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3240 /* Emit special PIC prologues and epilogues. */
3241 /* If the function has any GOTOFF relocations, then the GOTBASE
3242 register has to be setup in the prologue
3243 The instruction needed at the function start for setting up the
3246 ----------------------------------------------------------
3247 The rtl to be emitted for this should be:
3250 (const (unspec (symref _DYNAMIC) 3)))
3251 ---------------------------------------------------------- */
3254 arc_finalize_pic (void)
3257 rtx baseptr_rtx
= gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
);
3259 if (crtl
->uses_pic_offset_table
== 0)
3262 gcc_assert (flag_pic
!= 0);
3264 pat
= gen_rtx_SYMBOL_REF (Pmode
, "_DYNAMIC");
3265 pat
= arc_unspec_offset (pat
, ARC_UNSPEC_GOT
);
3266 pat
= gen_rtx_SET (baseptr_rtx
, pat
);
3271 /* !TARGET_BARREL_SHIFTER support. */
3272 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3276 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3278 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3280 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3281 (op0
, op1
, op2
, shift
));
3285 /* Output the assembler code for doing a shift.
3286 We go to a bit of trouble to generate efficient code as the ARC601 only has
3287 single bit shifts. This is taken from the h8300 port. We only have one
3288 mode of shifting and can't access individual bytes like the h8300 can, so
3289 this is greatly simplified (at the expense of not generating hyper-
3292 This function is not used if the variable shift insns are present. */
3294 /* FIXME: This probably can be done using a define_split in arc.md.
3295 Alternately, generate rtx rather than output instructions. */
3298 output_shift (rtx
*operands
)
3300 /* static int loopend_lab;*/
3301 rtx shift
= operands
[3];
3302 machine_mode mode
= GET_MODE (shift
);
3303 enum rtx_code code
= GET_CODE (shift
);
3304 const char *shift_one
;
3306 gcc_assert (mode
== SImode
);
3310 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3311 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3312 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3313 default: gcc_unreachable ();
3316 if (GET_CODE (operands
[2]) != CONST_INT
)
3318 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3325 n
= INTVAL (operands
[2]);
3327 /* Only consider the lower 5 bits of the shift count. */
3330 /* First see if we can do them inline. */
3331 /* ??? We could get better scheduling & shorter code (using short insns)
3332 by using splitters. Alas, that'd be even more verbose. */
3333 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3334 && dest_reg_operand (operands
[4], SImode
))
3336 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3337 for (n
-=3 ; n
>= 3; n
-= 3)
3338 output_asm_insn ("add3 %0,%4,%0", operands
);
3340 output_asm_insn ("add2 %0,%4,%0", operands
);
3342 output_asm_insn ("add %0,%0,%0", operands
);
3348 output_asm_insn (shift_one
, operands
);
3349 operands
[1] = operands
[0];
3352 /* See if we can use a rotate/and. */
3353 else if (n
== BITS_PER_WORD
- 1)
3358 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3361 /* The ARC doesn't have a rol insn. Use something else. */
3362 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
3365 /* The ARC doesn't have a rol insn. Use something else. */
3366 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
3372 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
3377 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
3380 #if 1 /* Need some scheduling comparisons. */
3381 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3382 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3384 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3385 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
3390 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3391 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3393 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3394 "and %0,%0,1\n\trlc %0,%0", operands
);
3401 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
3402 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3407 operands
[2] = GEN_INT (n
);
3408 output_asm_insn ("mov.f lp_count, %2", operands
);
3412 output_asm_insn ("lpnz\t2f", operands
);
3413 output_asm_insn (shift_one
, operands
);
3414 output_asm_insn ("nop", operands
);
3415 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
3424 /* Nested function support. */
3426 /* Directly store VALUE into memory object BLOCK at OFFSET. */
3429 emit_store_direct (rtx block
, int offset
, int value
)
3431 emit_insn (gen_store_direct (adjust_address (block
, SImode
, offset
),
3433 gen_int_mode (value
, SImode
))));
3436 /* Emit RTL insns to initialize the variable parts of a trampoline.
3437 FNADDR is an RTX for the address of the function's pure code.
3438 CXT is an RTX for the static chain value for the function. */
3439 /* With potentially multiple shared objects loaded, and multiple stacks
3440 present for multiple thereds where trampolines might reside, a simple
3441 range check will likely not suffice for the profiler to tell if a callee
3442 is a trampoline. We a speedier check by making the trampoline start at
3443 an address that is not 4-byte aligned.
3444 A trampoline looks like this:
3448 ld_s r12,[pcl,12] 0xd403
3449 ld r11,[pcl,12] 0x170c 700b
3453 The fastest trampoline to execute for trampolines within +-8KB of CTX
3456 j [limm] 0x20200f80 limm
3457 and that would also be faster to write to the stack by computing the offset
3458 from CTX to TRAMP at compile time. However, it would really be better to
3459 get rid of the high cost of cache invalidation when generating trampolines,
3460 which requires that the code part of trampolines stays constant, and
3462 - making sure that no executable code but trampolines is on the stack,
3463 no icache entries linger for the area of the stack from when before the
3464 stack was allocated, and allocating trampolines in trampoline-only
3467 - allocate trampolines fram a special pool of pre-allocated trampolines. */
3470 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
3472 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3474 emit_store_direct (tramp
, 0, TARGET_BIG_ENDIAN
? 0x78e0d403 : 0xd40378e0);
3475 emit_store_direct (tramp
, 4, TARGET_BIG_ENDIAN
? 0x170c700b : 0x700b170c);
3476 emit_store_direct (tramp
, 8, TARGET_BIG_ENDIAN
? 0x7c0078e0 : 0x78e07c00);
3477 emit_move_insn (adjust_address (tramp
, SImode
, 12), fnaddr
);
3478 emit_move_insn (adjust_address (tramp
, SImode
, 16), cxt
);
3479 emit_insn (gen_flush_icache (adjust_address (tramp
, SImode
, 0)));
3482 /* Allow the profiler to easily distinguish trampolines from normal
3486 arc_trampoline_adjust_address (rtx addr
)
3488 return plus_constant (Pmode
, addr
, 2);
3491 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3492 reset when we output the scaled address. */
3493 static int output_scaled
= 0;
3495 /* Print operand X (an rtx) in assembler syntax to file FILE.
3496 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3497 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3498 /* In final.c:output_asm_insn:
3501 'c' : constant address if CONSTANT_ADDRESS_P
3507 'p': bit Position of lsb
3508 's': size of bit field
3509 '#': condbranch delay slot suffix
3510 '*': jump delay slot suffix
3511 '?' : nonjump-insn suffix for conditional execution or short instruction
3512 '!' : jump / call suffix for conditional execution or short instruction
3513 '`': fold constant inside unary o-perator, re-recognize, and emit.
3518 'B': Branch comparison operand - suppress sda reference
3519 'H': Most significant word
3520 'L': Least significant word
3521 'A': ASCII decimal representation of floating point value
3522 'U': Load/store update or scaling indicator
3523 'V': cache bypass indicator for volatile
3528 'o': original symbol - no @ prepending. */
3531 arc_print_operand (FILE *file
, rtx x
, int code
)
3536 if (GET_CODE (x
) == CONST_INT
)
3537 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3539 output_operand_lossage ("invalid operand to %%Z code");
3544 if (GET_CODE (x
) == CONST_INT
)
3545 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3547 output_operand_lossage ("invalid operand to %%z code");
3552 if (GET_CODE (x
) == CONST_INT
)
3553 fprintf (file
, "%d", INTVAL (x
) );
3555 output_operand_lossage ("invalid operands to %%c code");
3560 if (GET_CODE (x
) == CONST_INT
)
3561 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3563 output_operand_lossage ("invalid operand to %%M code");
3568 if (GET_CODE (x
) == CONST_INT
)
3569 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3571 output_operand_lossage ("invalid operand to %%p code");
3575 if (GET_CODE (x
) == CONST_INT
)
3577 HOST_WIDE_INT i
= INTVAL (x
);
3578 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3579 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3582 output_operand_lossage ("invalid operand to %%s code");
3586 /* Conditional branches depending on condition codes.
3587 Note that this is only for branches that were known to depend on
3588 condition codes before delay slot scheduling;
3589 out-of-range brcc / bbit expansions should use '*'.
3590 This distinction is important because of the different
3591 allowable delay slot insns and the output of the delay suffix
3592 for TARGET_AT_DBR_COND_EXEC. */
3594 /* Unconditional branches / branches not depending on condition codes.
3595 This could also be a CALL_INSN.
3596 Output the appropriate delay slot suffix. */
3597 if (final_sequence
&& final_sequence
->len () != 1)
3599 rtx_insn
*jump
= final_sequence
->insn (0);
3600 rtx_insn
*delay
= final_sequence
->insn (1);
3602 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3603 if (delay
->deleted ())
3605 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3606 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3607 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3608 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3615 case '?' : /* with leading "." */
3616 case '!' : /* without leading "." */
3617 /* This insn can be conditionally executed. See if the ccfsm machinery
3618 says it should be conditionalized.
3619 If it shouldn't, we'll check the compact attribute if this insn
3620 has a short variant, which may be used depending on code size and
3621 alignment considerations. */
3622 if (current_insn_predicate
)
3623 arc_ccfsm_current
.cc
3624 = get_arc_condition_code (current_insn_predicate
);
3625 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3627 /* Is this insn in a delay slot sequence? */
3628 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3629 || current_insn_predicate
3630 || CALL_P (final_sequence
->insn (0))
3631 || simplejump_p (final_sequence
->insn (0)))
3633 /* This insn isn't in a delay slot sequence, or conditionalized
3634 independently of its position in a delay slot. */
3635 fprintf (file
, "%s%s",
3636 code
== '?' ? "." : "",
3637 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3638 /* If this is a jump, there are still short variants. However,
3639 only beq_s / bne_s have the same offset range as b_s,
3640 and the only short conditional returns are jeq_s and jne_s. */
3642 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3643 || arc_ccfsm_current
.cc
== ARC_CC_NE
3644 || 0 /* FIXME: check if branch in 7 bit range. */))
3645 output_short_suffix (file
);
3647 else if (code
== '!') /* Jump with delay slot. */
3648 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
3649 else /* An Instruction in a delay slot of a jump or call. */
3651 rtx jump
= XVECEXP (final_sequence
, 0, 0);
3652 rtx insn
= XVECEXP (final_sequence
, 0, 1);
3654 /* If the insn is annulled and is from the target path, we need
3655 to inverse the condition test. */
3656 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3658 if (INSN_FROM_TARGET_P (insn
))
3659 fprintf (file
, "%s%s",
3660 code
== '?' ? "." : "",
3661 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
3663 fprintf (file
, "%s%s",
3664 code
== '?' ? "." : "",
3665 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3666 if (arc_ccfsm_current
.state
== 5)
3667 arc_ccfsm_current
.state
= 0;
3670 /* This insn is executed for either path, so don't
3671 conditionalize it at all. */
3672 output_short_suffix (file
);
3677 output_short_suffix (file
);
3680 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3683 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
3686 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
3687 (get_arc_condition_code (x
))],
3691 /* Write second word of DImode or DFmode reference,
3692 register or memory. */
3693 if (GET_CODE (x
) == REG
)
3694 fputs (reg_names
[REGNO (x
)+1], file
);
3695 else if (GET_CODE (x
) == MEM
)
3699 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3700 PRE_MODIFY, we will have handled the first word already;
3701 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3702 first word will be done later. In either case, the access
3703 to the first word will do the modify, and we only have
3704 to add an offset of four here. */
3705 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
3706 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
3707 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
3708 || GET_CODE (XEXP (x
, 0)) == POST_INC
3709 || GET_CODE (XEXP (x
, 0)) == POST_DEC
3710 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
3711 output_address (VOIDmode
,
3712 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
3713 else if (output_scaled
)
3715 rtx addr
= XEXP (x
, 0);
3716 int size
= GET_MODE_SIZE (GET_MODE (x
));
3718 output_address (VOIDmode
,
3719 plus_constant (Pmode
, XEXP (addr
, 0),
3720 ((INTVAL (XEXP (addr
, 1)) + 4)
3721 >> (size
== 2 ? 1 : 2))));
3725 output_address (VOIDmode
,
3726 plus_constant (Pmode
, XEXP (x
, 0), 4));
3730 output_operand_lossage ("invalid operand to %%R code");
3733 /* FIXME: remove %S option. */
3735 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3738 output_addr_const (file
, x
);
3744 if (GET_CODE (x
) == REG
)
3746 /* L = least significant word, H = most significant word. */
3747 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
3748 fputs (reg_names
[REGNO (x
)], file
);
3750 fputs (reg_names
[REGNO (x
)+1], file
);
3752 else if (GET_CODE (x
) == CONST_INT
3753 || GET_CODE (x
) == CONST_DOUBLE
)
3755 rtx first
, second
, word
;
3757 split_double (x
, &first
, &second
);
3759 if((WORDS_BIG_ENDIAN
) == 0)
3760 word
= (code
== 'L' ? first
: second
);
3762 word
= (code
== 'L' ? second
: first
);
3764 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
3767 output_operand_lossage ("invalid operand to %%H/%%L code");
3773 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
3774 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
3776 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
3777 fprintf (file
, "%s", str
);
3781 /* Output a load/store with update indicator if appropriate. */
3782 if (GET_CODE (x
) == MEM
)
3784 rtx addr
= XEXP (x
, 0);
3785 switch (GET_CODE (addr
))
3787 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
3788 fputs (".a", file
); break;
3789 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
3790 fputs (".ab", file
); break;
3792 /* Are we using a scaled index? */
3793 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3794 fputs (".as", file
);
3795 /* Can we use a scaled offset? */
3796 else if (CONST_INT_P (XEXP (addr
, 1))
3797 && GET_MODE_SIZE (GET_MODE (x
)) > 1
3798 && (!(INTVAL (XEXP (addr
, 1))
3799 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
3800 /* Does it make a difference? */
3801 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
3802 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
3804 fputs (".as", file
);
3811 gcc_assert (CONSTANT_P (addr
)); break;
3815 output_operand_lossage ("invalid operand to %%U code");
3818 /* Output cache bypass indicator for a load/store insn. Volatile memory
3819 refs are defined to use the cache bypass mechanism. */
3820 if (GET_CODE (x
) == MEM
)
3822 if (MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
3823 fputs (".di", file
);
3826 output_operand_lossage ("invalid operand to %%V code");
3831 /* Do nothing special. */
3834 fputs (reg_names
[REGNO (x
)]+1, file
);
3837 /* This punctuation character is needed because label references are
3838 printed in the output template using %l. This is a front end
3839 character, and when we want to emit a '@' before it, we have to use
3845 /* Output an operator. */
3846 switch (GET_CODE (x
))
3848 case PLUS
: fputs ("add", file
); return;
3849 case SS_PLUS
: fputs ("adds", file
); return;
3850 case AND
: fputs ("and", file
); return;
3851 case IOR
: fputs ("or", file
); return;
3852 case XOR
: fputs ("xor", file
); return;
3853 case MINUS
: fputs ("sub", file
); return;
3854 case SS_MINUS
: fputs ("subs", file
); return;
3855 case ASHIFT
: fputs ("asl", file
); return;
3856 case ASHIFTRT
: fputs ("asr", file
); return;
3857 case LSHIFTRT
: fputs ("lsr", file
); return;
3858 case ROTATERT
: fputs ("ror", file
); return;
3859 case MULT
: fputs ("mpy", file
); return;
3860 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
3861 case NEG
: fputs ("neg", file
); return;
3862 case SS_NEG
: fputs ("negs", file
); return;
3863 case NOT
: fputs ("not", file
); return; /* Unconditional. */
3865 fputs ("ext", file
); /* bmsk allows predication. */
3867 case SIGN_EXTEND
: /* Unconditional. */
3868 fputs ("sex", file
);
3870 switch (GET_MODE (XEXP (x
, 0)))
3872 case E_QImode
: fputs ("b", file
); return;
3873 case E_HImode
: fputs ("w", file
); return;
3878 if (GET_MODE (x
) != HImode
)
3880 fputs ("sat16", file
);
3883 output_operand_lossage ("invalid operand to %%O code"); return;
3885 if (GET_CODE (x
) == SYMBOL_REF
)
3887 assemble_name (file
, XSTR (x
, 0));
3892 if (TARGET_ANNOTATE_ALIGN
&& cfun
->machine
->size_reason
)
3893 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
3909 output_operand_lossage ("invalid operand output code");
3912 switch (GET_CODE (x
))
3915 fputs (reg_names
[REGNO (x
)], file
);
3919 rtx addr
= XEXP (x
, 0);
3920 int size
= GET_MODE_SIZE (GET_MODE (x
));
3924 switch (GET_CODE (addr
))
3926 case PRE_INC
: case POST_INC
:
3927 output_address (VOIDmode
,
3928 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
3929 case PRE_DEC
: case POST_DEC
:
3930 output_address (VOIDmode
,
3931 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
3933 case PRE_MODIFY
: case POST_MODIFY
:
3934 output_address (VOIDmode
, XEXP (addr
, 1)); break;
3938 output_address (VOIDmode
,
3939 plus_constant (Pmode
, XEXP (addr
, 0),
3940 (INTVAL (XEXP (addr
, 1))
3941 >> (size
== 2 ? 1 : 2))));
3945 output_address (VOIDmode
, addr
);
3948 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
3949 arc_output_pic_addr_const (file
, addr
, code
);
3951 output_address (VOIDmode
, addr
);
3958 /* We handle SFmode constants here as output_addr_const doesn't. */
3959 if (GET_MODE (x
) == SFmode
)
3963 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
3964 fprintf (file
, "0x%08lx", l
);
3968 /* Let output_addr_const deal with it. */
3971 || (GET_CODE (x
) == CONST
3972 && GET_CODE (XEXP (x
, 0)) == UNSPEC
3973 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
3974 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
3975 || (GET_CODE (x
) == CONST
3976 && GET_CODE (XEXP (x
, 0)) == PLUS
3977 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
3978 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
3979 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
3980 arc_output_pic_addr_const (file
, x
, code
);
3983 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3984 with asm_output_symbol_ref */
3985 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
)
3988 output_addr_const (file
, XEXP (x
, 0));
3989 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (XEXP (x
, 0)))
3990 fprintf (file
, "@sda");
3992 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
3993 || INTVAL (XEXP (x
, 1)) >= 0)
3994 fprintf (file
, "+");
3995 output_addr_const (file
, XEXP (x
, 1));
3998 output_addr_const (file
, x
);
4000 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
4001 fprintf (file
, "@sda");
4006 /* Print a memory address as an operand to reference that memory location. */
4009 arc_print_operand_address (FILE *file
, rtx addr
)
4011 register rtx base
, index
= 0;
4013 switch (GET_CODE (addr
))
4016 fputs (reg_names
[REGNO (addr
)], file
);
4019 output_addr_const (file
, addr
);
4020 if (SYMBOL_REF_SMALL_P (addr
))
4021 fprintf (file
, "@sda");
4024 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4025 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
4026 else if (CONST_INT_P (XEXP (addr
, 0)))
4027 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
4029 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
4031 gcc_assert (OBJECT_P (base
));
4032 arc_print_operand_address (file
, base
);
4033 if (CONSTANT_P (base
) && CONST_INT_P (index
))
4037 gcc_assert (OBJECT_P (index
));
4038 arc_print_operand_address (file
, index
);
4042 rtx c
= XEXP (addr
, 0);
4044 if ((GET_CODE (c
) == UNSPEC
4045 && (XINT (c
, 1) == UNSPEC_TLS_OFF
4046 || XINT (c
, 1) == UNSPEC_TLS_IE
))
4047 || (GET_CODE (c
) == PLUS
4048 && GET_CODE (XEXP (c
, 0)) == UNSPEC
4049 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
4050 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4052 arc_output_pic_addr_const (file
, c
, 0);
4055 gcc_assert (GET_CODE (c
) == PLUS
);
4056 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4057 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4059 output_address (VOIDmode
, XEXP (addr
, 0));
4065 /* We shouldn't get here as we've lost the mode of the memory object
4066 (which says how much to inc/dec by. */
4071 arc_output_pic_addr_const (file
, addr
, 0);
4073 output_addr_const (file
, addr
);
4078 /* Conditional execution support.
4080 This is based on the ARM port but for now is much simpler.
4082 A finite state machine takes care of noticing whether or not instructions
4083 can be conditionally executed, and thus decrease execution time and code
4084 size by deleting branch instructions. The fsm is controlled by
4085 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4086 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4087 insns also have a hand in this. */
4088 /* The way we leave dealing with non-anulled or annull-false delay slot
4089 insns to the consumer is awkward. */
4091 /* The state of the fsm controlling condition codes are:
4092 0: normal, do nothing special
4093 1: don't output this insn
4094 2: don't output this insn
4095 3: make insns conditional
4096 4: make insns conditional
4097 5: make insn conditional (only for outputting anulled delay slot insns)
4099 special value for cfun->machine->uid_ccfsm_state:
4100 6: return with but one insn before it since function start / call
4102 State transitions (state->state by whom, under what condition):
4103 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4105 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4106 by zero or more non-jump insns and an unconditional branch with
4107 the same target label as the condbranch.
4108 1 -> 3 branch patterns, after having not output the conditional branch
4109 2 -> 4 branch patterns, after having not output the conditional branch
4110 0 -> 5 branch patterns, for anulled delay slot insn.
4111 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4112 (the target label has CODE_LABEL_NUMBER equal to
4113 arc_ccfsm_target_label).
4114 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4115 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4116 5 -> 0 when outputting the delay slot insn
4118 If the jump clobbers the conditions then we use states 2 and 4.
4120 A similar thing can be done with conditional return insns.
4122 We also handle separating branches from sets of the condition code.
4123 This is done here because knowledge of the ccfsm state is required,
4124 we may not be outputting the branch. */
4126 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4127 before letting final output INSN. */
4130 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4132 /* BODY will hold the body of INSN. */
4135 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4136 an if/then/else), and things need to be reversed. */
4139 /* If we start with a return insn, we only succeed if we find another one. */
4140 int seeking_return
= 0;
4142 /* START_INSN will hold the insn from where we start looking. This is the
4143 first insn after the following code_label if REVERSE is true. */
4144 rtx_insn
*start_insn
= insn
;
4146 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4147 since they don't rely on a cmp preceding the. */
4148 enum attr_type jump_insn_type
;
4150 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4151 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4152 final_scan_insn which has `optimize' as a local. */
4153 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4156 /* Ignore notes and labels. */
4159 body
= PATTERN (insn
);
4160 /* If in state 4, check if the target branch is reached, in order to
4161 change back to state 0. */
4162 if (state
->state
== 4)
4164 if (insn
== state
->target_insn
)
4166 state
->target_insn
= NULL
;
4172 /* If in state 3, it is possible to repeat the trick, if this insn is an
4173 unconditional branch to a label, and immediately following this branch
4174 is the previous target label which is only used once, and the label this
4175 branch jumps to is not too far off. Or in other words "we've done the
4176 `then' part, see if we can do the `else' part." */
4177 if (state
->state
== 3)
4179 if (simplejump_p (insn
))
4181 start_insn
= next_nonnote_insn (start_insn
);
4182 if (GET_CODE (start_insn
) == BARRIER
)
4184 /* ??? Isn't this always a barrier? */
4185 start_insn
= next_nonnote_insn (start_insn
);
4187 if (GET_CODE (start_insn
) == CODE_LABEL
4188 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4189 && LABEL_NUSES (start_insn
) == 1)
4194 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4196 start_insn
= next_nonnote_insn (start_insn
);
4197 if (GET_CODE (start_insn
) == BARRIER
)
4198 start_insn
= next_nonnote_insn (start_insn
);
4199 if (GET_CODE (start_insn
) == CODE_LABEL
4200 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4201 && LABEL_NUSES (start_insn
) == 1)
4213 if (GET_CODE (insn
) != JUMP_INSN
4214 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4215 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4218 /* We can't predicate BRCC or loop ends.
4219 Also, when generating PIC code, and considering a medium range call,
4220 we can't predicate the call. */
4221 jump_insn_type
= get_attr_type (insn
);
4222 if (jump_insn_type
== TYPE_BRCC
4223 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4224 || jump_insn_type
== TYPE_LOOP_END
4225 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4228 /* This jump might be paralleled with a clobber of the condition codes,
4229 the jump should always come first. */
4230 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4231 body
= XVECEXP (body
, 0, 0);
4234 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4235 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4237 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4238 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4239 int then_not_else
= TRUE
;
4240 /* Nonzero if next insn must be the target label. */
4241 int next_must_be_target_label_p
;
4242 rtx_insn
*this_insn
= start_insn
;
4245 /* Register the insn jumped to. */
4248 if (!seeking_return
)
4249 label
= XEXP (SET_SRC (body
), 0);
4251 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4252 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4253 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4255 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4256 then_not_else
= FALSE
;
4258 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4260 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4263 then_not_else
= FALSE
;
4268 /* If this is a non-annulled branch with a delay slot, there is
4269 no need to conditionalize the delay slot. */
4270 if (NEXT_INSN (PREV_INSN (insn
)) != insn
4271 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4273 this_insn
= NEXT_INSN (this_insn
);
4274 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn
)))
4275 == NEXT_INSN (this_insn
));
4277 /* See how many insns this branch skips, and what kind of insns. If all
4278 insns are okay, and the label or unconditional branch to the same
4279 label is not too far away, succeed. */
4280 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
4281 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
4286 this_insn
= next_nonnote_insn (this_insn
);
4290 if (next_must_be_target_label_p
)
4292 if (GET_CODE (this_insn
) == BARRIER
)
4294 if (GET_CODE (this_insn
) == CODE_LABEL
4295 && this_insn
== label
)
4305 switch (GET_CODE (this_insn
))
4308 /* Succeed if it is the target label, otherwise fail since
4309 control falls in from somewhere else. */
4310 if (this_insn
== label
)
4320 /* Succeed if the following insn is the target label.
4322 If return insns are used then the last insn in a function
4323 will be a barrier. */
4324 next_must_be_target_label_p
= TRUE
;
4328 /* Can handle a call insn if there are no insns after it.
4329 IE: The next "insn" is the target label. We don't have to
4330 worry about delay slots as such insns are SEQUENCE's inside
4331 INSN's. ??? It is possible to handle such insns though. */
4332 if (get_attr_cond (this_insn
) == COND_CANUSE
)
4333 next_must_be_target_label_p
= TRUE
;
4339 scanbody
= PATTERN (this_insn
);
4341 /* If this is an unconditional branch to the same label, succeed.
4342 If it is to another label, do nothing. If it is conditional,
4344 /* ??? Probably, the test for the SET and the PC are
4347 if (GET_CODE (scanbody
) == SET
4348 && GET_CODE (SET_DEST (scanbody
)) == PC
)
4350 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
4351 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
4356 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
4358 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
4361 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
4367 else if (GET_CODE (scanbody
) == PARALLEL
)
4369 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4375 scanbody
= PATTERN (this_insn
);
4377 /* We can only do this with insns that can use the condition
4378 codes (and don't set them). */
4379 if (GET_CODE (scanbody
) == SET
4380 || GET_CODE (scanbody
) == PARALLEL
)
4382 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4385 /* We can't handle other insns like sequences. */
4397 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
4398 state
->target_label
= CODE_LABEL_NUMBER (label
);
4399 else if (seeking_return
|| state
->state
== 2)
4401 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
4403 this_insn
= next_nonnote_insn (this_insn
);
4405 gcc_assert (!this_insn
||
4406 (GET_CODE (this_insn
) != BARRIER
4407 && GET_CODE (this_insn
) != CODE_LABEL
));
4411 /* Oh dear! we ran off the end, give up. */
4412 extract_insn_cached (insn
);
4414 state
->target_insn
= NULL
;
4417 state
->target_insn
= this_insn
;
4422 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4426 state
->cond
= XEXP (SET_SRC (body
), 0);
4427 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4430 if (reverse
|| then_not_else
)
4431 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4434 /* Restore recog_operand. Getting the attributes of other insns can
4435 destroy this array, but final.c assumes that it remains intact
4436 across this call; since the insn has been recognized already we
4437 call insn_extract direct. */
4438 extract_insn_cached (insn
);
4442 /* Record that we are currently outputting label NUM with prefix PREFIX.
4443 It it's the label we're looking for, reset the ccfsm machinery.
4445 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4448 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4450 if (state
->state
== 3 && state
->target_label
== num
4451 && !strcmp (prefix
, "L"))
4454 state
->target_insn
= NULL
;
4458 /* We are considering a conditional branch with the condition COND.
4459 Check if we want to conditionalize a delay slot insn, and if so modify
4460 the ccfsm state accordingly.
4461 REVERSE says branch will branch when the condition is false. */
4463 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4464 struct arc_ccfsm
*state
)
4466 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4468 state
= &arc_ccfsm_current
;
4470 gcc_assert (state
->state
== 0);
4471 if (seq_insn
!= jump
)
4473 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4475 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4476 && INSN_ANNULLED_BRANCH_P (jump
)
4477 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4480 state
->cc
= get_arc_condition_code (cond
);
4482 arc_ccfsm_current
.cc
4483 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4484 rtx pat
= PATTERN (insn
);
4485 if (GET_CODE (pat
) == COND_EXEC
)
4486 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4487 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4488 == get_arc_condition_code (XEXP (pat
, 0)));
4495 /* Update *STATE as we would when we emit INSN. */
4498 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4500 enum attr_type type
;
4503 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4504 else if (JUMP_P (insn
)
4505 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4506 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4507 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4508 || ((type
== TYPE_UNCOND_BRANCH
4509 || type
== TYPE_RETURN
)
4510 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4512 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4513 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4516 rtx src
= SET_SRC (PATTERN (insn
));
4517 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4521 else if (arc_ccfsm_current
.state
== 5)
4522 arc_ccfsm_current
.state
= 0;
4525 /* Return true if the current insn, which is a conditional branch, is to be
4529 arc_ccfsm_branch_deleted_p (void)
4531 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4534 /* Record a branch isn't output because subsequent insns can be
4538 arc_ccfsm_record_branch_deleted (void)
4540 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4543 /* During insn output, indicate if the current insn is predicated. */
4546 arc_ccfsm_cond_exec_p (void)
4548 return (cfun
->machine
->prescan_initialized
4549 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4552 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4553 and look inside SEQUENCEs. */
4556 arc_next_active_insn (rtx_insn
*insn
, struct arc_ccfsm
*statep
)
4563 arc_ccfsm_post_advance (insn
, statep
);
4564 insn
= NEXT_INSN (insn
);
4565 if (!insn
|| BARRIER_P (insn
))
4568 arc_ccfsm_advance (insn
, statep
);
4570 while (NOTE_P (insn
)
4571 || (cfun
->machine
->arc_reorg_started
4572 && LABEL_P (insn
) && !label_to_alignment (insn
))
4573 || (NONJUMP_INSN_P (insn
)
4574 && (GET_CODE (PATTERN (insn
)) == USE
4575 || GET_CODE (PATTERN (insn
)) == CLOBBER
)));
4576 if (!LABEL_P (insn
))
4578 gcc_assert (INSN_P (insn
));
4579 pat
= PATTERN (insn
);
4580 if (GET_CODE (pat
) == ADDR_VEC
|| GET_CODE (pat
) == ADDR_DIFF_VEC
)
4582 if (GET_CODE (pat
) == SEQUENCE
)
4583 return as_a
<rtx_insn
*> (XVECEXP (pat
, 0, 0));
4588 /* When deciding if an insn should be output short, we want to know something
4589 about the following insns:
4590 - if another insn follows which we know we can output as a short insn
4591 before an alignment-sensitive point, we can output this insn short:
4592 the decision about the eventual alignment can be postponed.
4593 - if a to-be-aligned label comes next, we should output this insn such
4594 as to get / preserve 4-byte alignment.
4595 - if a likely branch without delay slot insn, or a call with an immediately
4596 following short insn comes next, we should out output this insn such as to
4597 get / preserve 2 mod 4 unalignment.
4598 - do the same for a not completely unlikely branch with a short insn
4599 following before any other branch / label.
4600 - in order to decide if we are actually looking at a branch, we need to
4601 call arc_ccfsm_advance.
4602 - in order to decide if we are looking at a short insn, we should know
4603 if it is conditionalized. To a first order of approximation this is
4604 the case if the state from arc_ccfsm_advance from before this insn
4605 indicates the insn is conditionalized. However, a further refinement
4606 could be to not conditionalize an insn if the destination register(s)
4607 is/are dead in the non-executed case. */
4608 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4609 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4610 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4613 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4615 enum attr_iscompact iscompact
;
4616 struct machine_function
*machine
;
4620 iscompact
= get_attr_iscompact (insn
);
4621 if (iscompact
== ISCOMPACT_FALSE
)
4624 machine
= cfun
->machine
;
4626 if (machine
->force_short_suffix
>= 0)
4627 return machine
->force_short_suffix
;
4629 return (get_attr_length (insn
) & 2) != 0;
4632 /* When outputting an instruction (alternative) that can potentially be short,
4633 output the short suffix if the insn is in fact short, and update
4634 cfun->machine->unalign accordingly. */
4637 output_short_suffix (FILE *file
)
4639 rtx_insn
*insn
= current_output_insn
;
4641 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
4643 fprintf (file
, "_s");
4644 cfun
->machine
->unalign
^= 2;
4646 /* Restore recog_operand. */
4647 extract_insn_cached (insn
);
4650 /* Implement FINAL_PRESCAN_INSN. */
4653 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
4654 int noperands ATTRIBUTE_UNUSED
)
4656 if (TARGET_DUMPISIZE
)
4657 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
4659 /* Output a nop if necessary to prevent a hazard.
4660 Don't do this for delay slots: inserting a nop would
4661 alter semantics, and the only time we would find a hazard is for a
4662 call function result - and in that case, the hazard is spurious to
4664 if (PREV_INSN (insn
)
4665 && PREV_INSN (NEXT_INSN (insn
)) == insn
4666 && arc_hazard (prev_real_insn (insn
), insn
))
4668 current_output_insn
=
4669 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn
)));
4670 final_scan_insn (current_output_insn
, asm_out_file
, optimize
, 1, NULL
);
4671 current_output_insn
= insn
;
4673 /* Restore extraction data which might have been clobbered by arc_hazard. */
4674 extract_constrain_insn_cached (insn
);
4676 if (!cfun
->machine
->prescan_initialized
)
4678 /* Clear lingering state from branch shortening. */
4679 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
4680 cfun
->machine
->prescan_initialized
= 1;
4682 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
4684 cfun
->machine
->size_reason
= 0;
4687 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4688 Frame pointer elimination is automatically handled.
4690 All eliminations are permissible. If we need a frame
4691 pointer, we must eliminate ARG_POINTER_REGNUM into
4692 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4695 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4697 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
4700 /* Define the offset between two registers, one to be eliminated, and
4701 the other its replacement, at the start of a routine. */
4704 arc_initial_elimination_offset (int from
, int to
)
4706 if (! cfun
->machine
->frame_info
.initialized
)
4707 arc_compute_frame_size (get_frame_size ());
4709 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
4711 return (cfun
->machine
->frame_info
.extra_size
4712 + cfun
->machine
->frame_info
.reg_size
);
4715 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
4717 return (cfun
->machine
->frame_info
.total_size
4718 - cfun
->machine
->frame_info
.pretend_size
);
4721 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
4723 return (cfun
->machine
->frame_info
.total_size
4724 - (cfun
->machine
->frame_info
.pretend_size
4725 + cfun
->machine
->frame_info
.extra_size
4726 + cfun
->machine
->frame_info
.reg_size
));
4733 arc_frame_pointer_required (void)
4735 return cfun
->calls_alloca
;
4739 /* Return the destination address of a branch. */
4742 branch_dest (rtx branch
)
4744 rtx pat
= PATTERN (branch
);
4745 rtx dest
= (GET_CODE (pat
) == PARALLEL
4746 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
4749 if (GET_CODE (dest
) == IF_THEN_ELSE
)
4750 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
4752 dest
= XEXP (dest
, 0);
4753 dest_uid
= INSN_UID (dest
);
4755 return INSN_ADDRESSES (dest_uid
);
4759 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4762 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
4764 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4765 This clears machine specific flags, so has to come first. */
4766 default_encode_section_info (decl
, rtl
, first
);
4768 /* Check if it is a function, and whether it has the
4769 [long/medium/short]_call attribute specified. */
4770 if (TREE_CODE (decl
) == FUNCTION_DECL
)
4772 rtx symbol
= XEXP (rtl
, 0);
4773 int flags
= SYMBOL_REF_FLAGS (symbol
);
4775 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4776 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
4777 tree long_call_attr
= lookup_attribute ("long_call", attr
);
4778 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
4779 tree short_call_attr
= lookup_attribute ("short_call", attr
);
4781 if (long_call_attr
!= NULL_TREE
)
4782 flags
|= SYMBOL_FLAG_LONG_CALL
;
4783 else if (medium_call_attr
!= NULL_TREE
)
4784 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
4785 else if (short_call_attr
!= NULL_TREE
)
4786 flags
|= SYMBOL_FLAG_SHORT_CALL
;
4788 SYMBOL_REF_FLAGS (symbol
) = flags
;
4790 else if (TREE_CODE (decl
) == VAR_DECL
)
4792 rtx symbol
= XEXP (rtl
, 0);
4794 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4795 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
4797 tree sec_attr
= lookup_attribute ("section", attr
);
4800 const char *sec_name
4801 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
4802 if (strcmp (sec_name
, ".cmem") == 0
4803 || strcmp (sec_name
, ".cmem_shared") == 0
4804 || strcmp (sec_name
, ".cmem_private") == 0)
4805 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
4810 /* This is how to output a definition of an internal numbered label where
4811 PREFIX is the class of label and NUM is the number within the class. */
4813 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
4816 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
4817 default_internal_label (stream
, prefix
, labelno
);
4820 /* Set the cpu type and print out other fancy things,
4821 at the top of the file. */
4823 static void arc_file_start (void)
4825 default_file_start ();
4826 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
4829 /* Cost functions. */
4831 /* Compute a (partial) cost for rtx X. Return true if the complete
4832 cost has been computed, and false if subexpressions should be
4833 scanned. In either case, *TOTAL contains the cost result. */
4836 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4837 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4839 int code
= GET_CODE (x
);
4843 /* Small integers are as cheap as registers. */
4846 bool nolimm
= false; /* Can we do without long immediate? */
4847 bool fast
= false; /* Is the result available immediately? */
4848 bool condexec
= false; /* Does this allow conditiobnal execution? */
4849 bool compact
= false; /* Is a 16 bit opcode available? */
4850 /* CONDEXEC also implies that we can have an unconditional
4851 3-address operation. */
4853 nolimm
= compact
= condexec
= false;
4854 if (UNSIGNED_INT6 (INTVAL (x
)))
4855 nolimm
= condexec
= compact
= true;
4858 if (SMALL_INT (INTVAL (x
)))
4859 nolimm
= fast
= true;
4862 case AND
: /* bclr, bmsk, ext[bw] */
4863 if (satisfies_constraint_Ccp (x
) /* bclr */
4864 || satisfies_constraint_C1p (x
) /* bmsk */)
4865 nolimm
= fast
= condexec
= compact
= true;
4867 case IOR
: /* bset */
4868 if (satisfies_constraint_C0p (x
)) /* bset */
4869 nolimm
= fast
= condexec
= compact
= true;
4872 if (satisfies_constraint_C0p (x
)) /* bxor */
4873 nolimm
= fast
= condexec
= true;
4876 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
4882 /* FIXME: Add target options to attach a small cost if
4883 condexec / compact is not true. */
4892 /* 4 byte values can be fetched as immediate constants -
4893 let's give that the cost of an extra insn. */
4897 *total
= COSTS_N_INSNS (1);
4906 *total
= COSTS_N_INSNS (1);
4909 split_double (x
, &first
, &second
);
4910 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
4911 + !SMALL_INT (INTVAL (second
)));
4915 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4916 If we need more than 12 insns to do a multiply, then go out-of-line,
4917 since the call overhead will be < 10% of the cost of the multiply. */
4921 if (TARGET_BARREL_SHIFTER
)
4923 /* If we want to shift a constant, we need a LIMM. */
4924 /* ??? when the optimizers want to know if a constant should be
4925 hoisted, they ask for the cost of the constant. OUTER_CODE is
4926 insufficient context for shifts since we don't know which operand
4927 we are looking at. */
4928 if (CONSTANT_P (XEXP (x
, 0)))
4930 *total
+= (COSTS_N_INSNS (2)
4931 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
4935 *total
= COSTS_N_INSNS (1);
4937 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
4938 *total
= COSTS_N_INSNS (16);
4941 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
4942 /* ??? want_to_gcse_p can throw negative shift counts at us,
4943 and then panics when it gets a negative cost as result.
4944 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4953 *total
= COSTS_N_INSNS(30);
4955 *total
= COSTS_N_INSNS(1);
4959 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
4960 *total
= COSTS_N_INSNS (1);
4962 *total
= arc_multcost
;
4963 /* We do not want synth_mult sequences when optimizing
4965 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
4966 *total
= COSTS_N_INSNS (1);
4968 *total
= COSTS_N_INSNS (2);
4971 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
4972 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
4973 || (GET_CODE (XEXP (x
, 0)) == MULT
4974 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
4976 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
4977 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
4982 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
4983 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
4984 || (GET_CODE (XEXP (x
, 1)) == MULT
4985 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
4987 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
4988 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
4994 rtx op0
= XEXP (x
, 0);
4995 rtx op1
= XEXP (x
, 1);
4997 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
4998 && XEXP (op0
, 1) == const1_rtx
)
5000 /* btst / bbit0 / bbit1:
5001 Small integers and registers are free; everything else can
5002 be put in a register. */
5003 mode
= GET_MODE (XEXP (op0
, 0));
5004 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5005 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5008 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5009 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5012 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5016 if (GET_CODE (op1
) == NEG
)
5018 /* op0 might be constant, the inside of op1 is rather
5019 unlikely to be so. So swapping the operands might lower
5021 mode
= GET_MODE (op0
);
5022 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5023 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5028 if (outer_code
== IF_THEN_ELSE
5029 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5030 && XEXP (x
, 1) == const0_rtx
5031 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5033 /* btst / bbit0 / bbit1:
5034 Small integers and registers are free; everything else can
5035 be put in a register. */
5036 rtx op0
= XEXP (x
, 0);
5038 mode
= GET_MODE (XEXP (op0
, 0));
5039 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5040 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5044 /* scc_insn expands into two insns. */
5045 case GTU
: case GEU
: case LEU
:
5047 *total
+= COSTS_N_INSNS (1);
5049 case LTU
: /* might use adc. */
5051 *total
+= COSTS_N_INSNS (1) - 1;
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
) != CONST
)
5068 addr
= XEXP (addr
, 0);
5071 if (GET_CODE (addr
) == PLUS
)
5073 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5075 addr
= XEXP (addr
, 0);
5078 if (GET_CODE (addr
) != UNSPEC
5079 || XVECLEN (addr
, 0) != 1)
5082 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5083 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5084 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5085 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5086 && XINT (addr
, 1) != UNSPEC_TLS_GD
5087 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5090 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5091 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5099 /* Return true if OP contains a symbol reference. */
5102 symbolic_reference_mentioned_p (rtx op
)
5104 register const char *fmt
;
5107 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5110 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5111 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5117 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5118 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5122 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5129 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5130 If SKIP_LOCAL is true, skip symbols that bind locally.
5131 This is used further down in this file, and, without SKIP_LOCAL,
5132 in the addsi3 / subsi3 expanders when generating PIC code. */
5135 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5137 register const char *fmt
;
5140 if (GET_CODE(op
) == UNSPEC
)
5143 if (GET_CODE (op
) == SYMBOL_REF
)
5145 if (SYMBOL_REF_TLS_MODEL (op
))
5149 tree decl
= SYMBOL_REF_DECL (op
);
5150 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5153 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5154 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5160 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5161 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5166 else if (fmt
[i
] == 'e'
5167 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5175 /* Get the thread pointer. */
5180 /* If arc_tp_regno has been set, we can use that hard register
5181 directly as a base register. */
5182 if (arc_tp_regno
!= -1)
5183 return gen_rtx_REG (Pmode
, arc_tp_regno
);
5185 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5186 conflicts with function arguments / results. */
5187 rtx reg
= gen_reg_rtx (Pmode
);
5188 emit_insn (gen_tls_load_tp_soft ());
5189 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
5193 /* Helper to be used by TLS Global dynamic model. */
5196 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
5198 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
5199 rtx call_fusage
= NULL_RTX
;
5203 rtx x
= arc_unspec_offset (sym
, reloc
);
5204 emit_move_insn (r0
, x
);
5205 use_reg (&call_fusage
, r0
);
5207 gcc_assert (reloc
== UNSPEC_TLS_GD
);
5208 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
5209 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5210 way that the application should care. */
5211 RTL_PURE_CALL_P (call_insn
) = 1;
5212 add_function_usage_to (call_insn
, call_fusage
);
5214 rtx_insn
*insns
= get_insns ();
5217 rtx dest
= gen_reg_rtx (Pmode
);
5218 emit_libcall_block (insns
, dest
, r0
, eqv
);
5222 #define DTPOFF_ZERO_SYM ".tdata"
5224 /* Return a legitimized address for ADDR,
5225 which is a SYMBOL_REF with tls_model MODEL. */
5228 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5230 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5231 model
= TLS_MODEL_LOCAL_EXEC
;
5235 case TLS_MODEL_LOCAL_DYNAMIC
:
5238 const char *base_name
;
5241 decl
= SYMBOL_REF_DECL (addr
);
5242 base_name
= DTPOFF_ZERO_SYM
;
5243 if (decl
&& bss_initializer_p (decl
))
5244 base_name
= ".tbss";
5246 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5247 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
5251 v
= gen_rtvec (1, addr
);
5254 v
= gen_rtvec (2, addr
, base
);
5255 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
5256 addr
= gen_rtx_CONST (Pmode
, addr
);
5257 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
5258 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
5260 case TLS_MODEL_GLOBAL_DYNAMIC
:
5261 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
5263 case TLS_MODEL_INITIAL_EXEC
:
5264 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5265 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5266 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5268 case TLS_MODEL_LOCAL_EXEC
:
5270 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5271 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5277 /* Legitimize a pic address reference in ORIG.
5278 The return value is the legitimated address.
5279 If OLDX is non-zero, it is the target to assign the address to first. */
5282 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5291 if (GET_CODE (addr
) == LABEL_REF
)
5293 else if (GET_CODE (addr
) == SYMBOL_REF
)
5295 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5297 return arc_legitimize_tls_address (addr
, model
);
5300 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5301 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5303 /* This symbol must be referenced via a load from the Global
5304 Offset Table (@GOTPC). */
5305 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5306 pat
= gen_const_mem (Pmode
, pat
);
5309 oldx
= gen_reg_rtx (Pmode
);
5311 emit_move_insn (oldx
, pat
);
5316 if (GET_CODE (addr
) == CONST
)
5318 addr
= XEXP (addr
, 0);
5319 if (GET_CODE (addr
) == UNSPEC
)
5321 /* Check that the unspec is one of the ones we generate? */
5324 /* fwprop is placing in the REG_EQUIV notes constant pic
5325 unspecs expressions. Then, loop may use these notes for
5326 optimizations resulting in complex patterns that are not
5327 supported by the current implementation. The following
5328 two if-cases are simplifying the complex patters to
5330 else if (GET_CODE (addr
) == MINUS
)
5332 rtx op0
= XEXP (addr
, 0);
5333 rtx op1
= XEXP (addr
, 1);
5335 gcc_assert (GET_CODE (op1
) == UNSPEC
);
5337 emit_move_insn (oldx
,
5338 gen_rtx_CONST (SImode
,
5339 arc_legitimize_pic_address (op1
,
5341 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
5345 else if (GET_CODE (addr
) != PLUS
)
5347 rtx tmp
= XEXP (addr
, 0);
5348 enum rtx_code code
= GET_CODE (addr
);
5350 /* It only works for UNARY operations. */
5351 gcc_assert (UNARY_P (addr
));
5352 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
5357 gen_rtx_CONST (SImode
,
5358 arc_legitimize_pic_address (tmp
,
5361 emit_insn (gen_rtx_SET (oldx
,
5362 gen_rtx_fmt_ee (code
, SImode
,
5363 oldx
, const0_rtx
)));
5369 gcc_assert (GET_CODE (addr
) == PLUS
);
5370 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
5375 if (GET_CODE (addr
) == PLUS
)
5377 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
5379 base
= arc_legitimize_pic_address (op0
, oldx
);
5380 pat
= arc_legitimize_pic_address (op1
,
5381 base
== oldx
? NULL_RTX
: oldx
);
5383 if (base
== op0
&& pat
== op1
)
5386 if (GET_CODE (pat
) == CONST_INT
)
5387 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
5390 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
5392 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
5393 pat
= XEXP (pat
, 1);
5395 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
5403 /* Output address constant X to FILE, taking PIC into account. */
5406 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5411 switch (GET_CODE (x
))
5421 output_addr_const (file
, x
);
5423 /* Local functions do not get references through the PLT. */
5424 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5425 fputs ("@plt", file
);
5429 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5430 assemble_name (file
, buf
);
5434 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5435 assemble_name (file
, buf
);
5439 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5443 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5447 if (GET_MODE (x
) == VOIDmode
)
5449 /* We can use %d if the number is one word and positive. */
5450 if (CONST_DOUBLE_HIGH (x
))
5451 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5452 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5453 else if (CONST_DOUBLE_LOW (x
) < 0)
5454 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5456 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5459 /* We can't handle floating point constants;
5460 PRINT_OPERAND must handle them. */
5461 output_operand_lossage ("floating constant misused");
5465 /* FIXME: Not needed here. */
5466 /* Some assemblers need integer constants to appear last (eg masm). */
5467 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5469 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5470 fprintf (file
, "+");
5471 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5473 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5475 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5476 if (INTVAL (XEXP (x
, 1)) >= 0)
5477 fprintf (file
, "+");
5478 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5485 /* Avoid outputting things like x-x or x+5-x,
5486 since some assemblers can't handle that. */
5487 x
= simplify_subtraction (x
);
5488 if (GET_CODE (x
) != MINUS
)
5491 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5492 fprintf (file
, "-");
5493 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5494 && INTVAL (XEXP (x
, 1)) < 0)
5496 fprintf (file
, "(");
5497 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5498 fprintf (file
, ")");
5501 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5506 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5512 bool pcrel
; pcrel
= false;
5513 rtx base
; base
= NULL
;
5514 gcc_assert (XVECLEN (x
, 0) >= 1);
5515 switch (XINT (x
, 1))
5517 case ARC_UNSPEC_GOT
:
5518 suffix
= "@gotpc", pcrel
= true;
5520 case ARC_UNSPEC_GOTOFF
:
5523 case ARC_UNSPEC_GOTOFFPC
:
5524 suffix
= "@pcl", pcrel
= true;
5526 case ARC_UNSPEC_PLT
:
5530 suffix
= "@tlsgd", pcrel
= true;
5533 suffix
= "@tlsie", pcrel
= true;
5535 case UNSPEC_TLS_OFF
:
5536 if (XVECLEN (x
, 0) == 2)
5537 base
= XVECEXP (x
, 0, 1);
5538 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5539 || (!flag_pic
&& !base
))
5545 suffix
= "@invalid";
5546 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5550 fputs ("pcl,", file
);
5551 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5552 fputs (suffix
, file
);
5554 arc_output_pic_addr_const (file
, base
, code
);
5558 output_operand_lossage ("invalid expression as operand");
5562 #define SYMBOLIC_CONST(X) \
5563 (GET_CODE (X) == SYMBOL_REF \
5564 || GET_CODE (X) == LABEL_REF \
5565 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5567 /* Emit insns to move operands[1] into operands[0]. */
5570 prepare_pic_move (rtx
*operands
, machine_mode
)
5572 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5574 operands
[1] = force_reg (Pmode
, operands
[1]);
5577 rtx temp
= (reload_in_progress
? operands
[0]
5578 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5579 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5584 /* The function returning the number of words, at the beginning of an
5585 argument, must be put in registers. The returned value must be
5586 zero for arguments that are passed entirely in registers or that
5587 are entirely pushed on the stack.
5589 On some machines, certain arguments must be passed partially in
5590 registers and partially in memory. On these machines, typically
5591 the first N words of arguments are passed in registers, and the
5592 rest on the stack. If a multi-word argument (a `double' or a
5593 structure) crosses that boundary, its first few words must be
5594 passed in registers and the rest must be pushed. This function
5595 tells the compiler when this occurs, and how many of the words
5596 should go in registers.
5598 `FUNCTION_ARG' for these arguments should return the first register
5599 to be used by the caller for this argument; likewise
5600 `FUNCTION_INCOMING_ARG', for the called function.
5602 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5604 /* If REGNO is the least arg reg available then what is the total number of arg
5606 #define GPR_REST_ARG_REGS(REGNO) \
5607 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5609 /* Since arc parm regs are contiguous. */
5610 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5612 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5615 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
5616 tree type
, bool named ATTRIBUTE_UNUSED
)
5618 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5619 int bytes
= (mode
== BLKmode
5620 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5621 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5625 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5626 ret
= GPR_REST_ARG_REGS (arg_num
);
5628 /* ICEd at function.c:2361, and ret is copied to data->partial */
5629 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
5634 /* This function is used to control a function argument is passed in a
5635 register, and which register.
5637 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5638 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5639 all of the previous arguments so far passed in registers; MODE, the
5640 machine mode of the argument; TYPE, the data type of the argument
5641 as a tree node or 0 if that is not known (which happens for C
5642 support library functions); and NAMED, which is 1 for an ordinary
5643 argument and 0 for nameless arguments that correspond to `...' in
5644 the called function's prototype.
5646 The returned value should either be a `reg' RTX for the hard
5647 register in which to pass the argument, or zero to pass the
5648 argument on the stack.
5650 For machines like the Vax and 68000, where normally all arguments
5651 are pushed, zero suffices as a definition.
5653 The usual way to make the ANSI library `stdarg.h' work on a machine
5654 where some arguments are usually passed in registers, is to cause
5655 nameless arguments to be passed on the stack instead. This is done
5656 by making the function return 0 whenever NAMED is 0.
5658 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5659 definition of this function to determine if this argument is of a
5660 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5661 is not defined and the function returns non-zero for such an
5662 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5663 defined, the argument will be computed in the stack and then loaded
5666 The function is used to implement macro FUNCTION_ARG. */
5667 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5668 and the rest are pushed. */
5671 arc_function_arg (cumulative_args_t cum_v
,
5673 const_tree type ATTRIBUTE_UNUSED
,
5674 bool named ATTRIBUTE_UNUSED
)
5676 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5679 const char *debstr ATTRIBUTE_UNUSED
;
5681 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5682 /* Return a marker for use in the call instruction. */
5683 if (mode
== VOIDmode
)
5688 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
5690 ret
= gen_rtx_REG (mode
, arg_num
);
5691 debstr
= reg_names
[arg_num
];
5701 /* The function to update the summarizer variable *CUM to advance past
5702 an argument in the argument list. The values MODE, TYPE and NAMED
5703 describe that argument. Once this is done, the variable *CUM is
5704 suitable for analyzing the *following* argument with
5705 `FUNCTION_ARG', etc.
5707 This function need not do anything if the argument in question was
5708 passed on the stack. The compiler knows how to track the amount of
5709 stack space used for arguments without any special help.
5711 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5712 /* For the ARC: the cum set here is passed on to function_arg where we
5713 look at its value and say which reg to use. Strategy: advance the
5714 regnumber here till we run out of arg regs, then set *cum to last
5715 reg. In function_arg, since *cum > last arg reg we would return 0
5716 and thus the arg will end up on the stack. For straddling args of
5717 course function_arg_partial_nregs will come into play. */
5720 arc_function_arg_advance (cumulative_args_t cum_v
,
5723 bool named ATTRIBUTE_UNUSED
)
5725 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5726 int bytes
= (mode
== BLKmode
5727 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5728 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5732 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
5733 for (i
= 0; i
< words
; i
++)
5734 *cum
= ARC_NEXT_ARG_REG (*cum
);
5738 /* Define how to find the value returned by a function.
5739 VALTYPE is the data type of the value (as a tree).
5740 If the precise function being called is known, FN_DECL_OR_TYPE is its
5741 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5744 arc_function_value (const_tree valtype
,
5745 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
5746 bool outgoing ATTRIBUTE_UNUSED
)
5748 machine_mode mode
= TYPE_MODE (valtype
);
5749 int unsignedp ATTRIBUTE_UNUSED
;
5751 unsignedp
= TYPE_UNSIGNED (valtype
);
5752 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
5753 PROMOTE_MODE (mode
, unsignedp
, valtype
);
5754 return gen_rtx_REG (mode
, 0);
5757 /* Returns the return address that is used by builtin_return_address. */
5760 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
5765 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
5768 /* Determine if a given RTX is a valid constant. We already know this
5769 satisfies CONSTANT_P. */
5772 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
5774 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
))
5777 if (!flag_pic
&& mode
!= Pmode
)
5780 switch (GET_CODE (x
))
5785 if (arc_legitimate_pic_addr_p (x
))
5788 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
5791 if (SYMBOL_REF_TLS_MODEL (x
))
5803 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
5808 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
5809 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
5818 return TARGET_PLUS_DMPY
;
5821 return TARGET_PLUS_QMACW
;
5827 switch (XINT (x
, 1))
5830 case UNSPEC_TLS_OFF
:
5834 /* Any other unspec ending here are pic related, hence the above
5835 constant pic address checking returned false. */
5841 fatal_insn ("unrecognized supposed constant", x
);
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 return arc_legitimate_constant_p (mode
, x
);
5883 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
5884 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
5885 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5887 /* We're restricted here by the `st' insn. */
5888 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
5889 && GET_CODE (XEXP ((x
), 1)) == PLUS
5890 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
5891 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
5892 TARGET_AUTO_MODIFY_REG
, strict
))
5897 /* Return true iff ADDR (a legitimate address expression)
5898 has an effect that depends on the machine mode it is used for. */
5901 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
5903 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5904 which is valid for loads and stores, or a limm offset, which is valid for
5905 loads. Scaled indices are scaled by the access mode. */
5906 if (GET_CODE (addr
) == PLUS
5907 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
5912 /* Determine if it's legal to put X into the constant pool. */
5915 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
5917 return !arc_legitimate_constant_p (mode
, x
);
5920 /* IDs for all the ARC builtins. */
5924 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5925 ARC_BUILTIN_ ## NAME,
5926 #include "builtins.def"
5932 struct GTY(()) arc_builtin_description
5934 enum insn_code icode
;
5939 static GTY(()) struct arc_builtin_description
5940 arc_bdesc
[ARC_BUILTIN_COUNT
] =
5942 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5943 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
5944 #include "builtins.def"
5948 /* Transform UP into lowercase and write the result to LO.
5949 You must provide enough space for LO. Return LO. */
5952 arc_tolower (char *lo
, const char *up
)
5956 for (; *up
; up
++, lo
++)
5957 *lo
= TOLOWER (*up
);
5964 /* Implement `TARGET_BUILTIN_DECL'. */
5967 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
5969 if (id
< ARC_BUILTIN_COUNT
)
5970 return arc_bdesc
[id
].fndecl
;
5972 return error_mark_node
;
5976 arc_init_builtins (void)
5978 tree V4HI_type_node
;
5979 tree V2SI_type_node
;
5980 tree V2HI_type_node
;
5982 /* Vector types based on HS SIMD elements. */
5983 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
5984 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
5985 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
5987 tree pcvoid_type_node
5988 = build_pointer_type (build_qualified_type (void_type_node
,
5990 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
5993 tree void_ftype_void
5994 = build_function_type_list (void_type_node
, NULL_TREE
);
5996 = build_function_type_list (integer_type_node
, integer_type_node
,
5998 tree int_ftype_pcvoid_int
5999 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6000 integer_type_node
, NULL_TREE
);
6001 tree void_ftype_usint_usint
6002 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6003 long_unsigned_type_node
, NULL_TREE
);
6004 tree int_ftype_int_int
6005 = build_function_type_list (integer_type_node
, integer_type_node
,
6006 integer_type_node
, NULL_TREE
);
6007 tree usint_ftype_usint
6008 = build_function_type_list (long_unsigned_type_node
,
6009 long_unsigned_type_node
, NULL_TREE
);
6010 tree void_ftype_usint
6011 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6014 = build_function_type_list (integer_type_node
, void_type_node
,
6017 = build_function_type_list (void_type_node
, integer_type_node
,
6019 tree int_ftype_short
6020 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6023 /* Old ARC SIMD types. */
6024 tree v8hi_ftype_v8hi_v8hi
6025 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6026 V8HI_type_node
, NULL_TREE
);
6027 tree v8hi_ftype_v8hi_int
6028 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6029 integer_type_node
, NULL_TREE
);
6030 tree v8hi_ftype_v8hi_int_int
6031 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6032 integer_type_node
, integer_type_node
,
6034 tree void_ftype_v8hi_int_int
6035 = build_function_type_list (void_type_node
, V8HI_type_node
,
6036 integer_type_node
, integer_type_node
,
6038 tree void_ftype_v8hi_int_int_int
6039 = build_function_type_list (void_type_node
, V8HI_type_node
,
6040 integer_type_node
, integer_type_node
,
6041 integer_type_node
, NULL_TREE
);
6042 tree v8hi_ftype_int_int
6043 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6044 integer_type_node
, NULL_TREE
);
6045 tree void_ftype_int_int
6046 = build_function_type_list (void_type_node
, integer_type_node
,
6047 integer_type_node
, NULL_TREE
);
6048 tree v8hi_ftype_v8hi
6049 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6051 /* ARCv2 SIMD types. */
6052 tree long_ftype_v4hi_v4hi
6053 = build_function_type_list (long_long_integer_type_node
,
6054 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6055 tree int_ftype_v2hi_v2hi
6056 = build_function_type_list (integer_type_node
,
6057 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6058 tree v2si_ftype_v2hi_v2hi
6059 = build_function_type_list (V2SI_type_node
,
6060 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6061 tree v2hi_ftype_v2hi_v2hi
6062 = build_function_type_list (V2HI_type_node
,
6063 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6064 tree v2si_ftype_v2si_v2si
6065 = build_function_type_list (V2SI_type_node
,
6066 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6067 tree v4hi_ftype_v4hi_v4hi
6068 = build_function_type_list (V4HI_type_node
,
6069 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6070 tree long_ftype_v2si_v2hi
6071 = build_function_type_list (long_long_integer_type_node
,
6072 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6074 /* Add the builtins. */
6075 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6077 int id = ARC_BUILTIN_ ## NAME; \
6078 const char *Name = "__builtin_arc_" #NAME; \
6079 char *name = (char*) alloca (1 + strlen (Name)); \
6081 gcc_assert (id < ARC_BUILTIN_COUNT); \
6083 arc_bdesc[id].fndecl \
6084 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6085 BUILT_IN_MD, NULL, NULL_TREE); \
6087 #include "builtins.def"
6091 /* Helper to expand __builtin_arc_aligned (void* val, int
6095 arc_expand_builtin_aligned (tree exp
)
6097 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6098 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6100 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6101 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6103 if (!CONST_INT_P (op1
))
6105 /* If we can't fold the alignment to a constant integer
6106 whilst optimizing, this is probably a user error. */
6108 warning (0, "__builtin_arc_aligned with non-constant alignment");
6112 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6113 /* Check alignTest is positive, and a power of two. */
6114 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6116 error ("invalid alignment value for __builtin_arc_aligned");
6120 if (CONST_INT_P (op0
))
6122 HOST_WIDE_INT pnt
= INTVAL (op0
);
6124 if ((pnt
& (alignTest
- 1)) == 0)
6129 unsigned align
= get_pointer_alignment (arg0
);
6130 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6132 if (align
&& align
>= numBits
)
6134 /* Another attempt to ascertain alignment. Check the type
6135 we are pointing to. */
6136 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6137 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6142 /* Default to false. */
6146 /* Helper arc_expand_builtin, generates a pattern for the given icode
6150 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6152 switch (insn_data
[icode
].n_generator_args
)
6155 return GEN_FCN (icode
) ();
6157 return GEN_FCN (icode
) (arg
[0]);
6159 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6161 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6163 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6165 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6171 /* Expand an expression EXP that calls a built-in function,
6172 with result going to TARGET if that's convenient
6173 (and in mode MODE if that's convenient).
6174 SUBTARGET may be used as the target for computing one of EXP's operands.
6175 IGNORE is nonzero if the value is to be ignored. */
6178 arc_expand_builtin (tree exp
,
6180 rtx subtarget ATTRIBUTE_UNUSED
,
6181 machine_mode mode ATTRIBUTE_UNUSED
,
6182 int ignore ATTRIBUTE_UNUSED
)
6184 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6185 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6186 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6187 int i
, j
, n_args
= call_expr_nargs (exp
);
6190 enum insn_code icode
= d
->icode
;
6191 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6208 if (id
>= ARC_BUILTIN_COUNT
)
6209 internal_error ("bad builtin fcode");
6211 /* 1st part: Expand special builtins. */
6214 case ARC_BUILTIN_NOP
:
6215 emit_insn (gen_nopv ());
6218 case ARC_BUILTIN_RTIE
:
6219 case ARC_BUILTIN_SYNC
:
6220 case ARC_BUILTIN_BRK
:
6221 case ARC_BUILTIN_SWI
:
6222 case ARC_BUILTIN_UNIMP_S
:
6223 gcc_assert (icode
!= 0);
6224 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6227 case ARC_BUILTIN_ALIGNED
:
6228 return arc_expand_builtin_aligned (exp
);
6230 case ARC_BUILTIN_CLRI
:
6231 target
= gen_reg_rtx (SImode
);
6232 emit_insn (gen_clri (target
, const1_rtx
));
6235 case ARC_BUILTIN_TRAP_S
:
6236 case ARC_BUILTIN_SLEEP
:
6237 arg0
= CALL_EXPR_ARG (exp
, 0);
6239 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6241 if (!CONST_INT_P (op0
) || !satisfies_constraint_L (op0
))
6243 error ("builtin operand should be an unsigned 6-bit value");
6246 gcc_assert (icode
!= 0);
6247 emit_insn (GEN_FCN (icode
) (op0
));
6250 case ARC_BUILTIN_VDORUN
:
6251 case ARC_BUILTIN_VDIRUN
:
6252 arg0
= CALL_EXPR_ARG (exp
, 0);
6253 arg1
= CALL_EXPR_ARG (exp
, 1);
6254 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6255 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6257 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6259 mode0
= insn_data
[icode
].operand
[1].mode
;
6260 mode1
= insn_data
[icode
].operand
[2].mode
;
6262 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6263 op0
= copy_to_mode_reg (mode0
, op0
);
6265 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6266 op1
= copy_to_mode_reg (mode1
, op1
);
6268 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6275 case ARC_BUILTIN_VDIWR
:
6276 case ARC_BUILTIN_VDOWR
:
6277 arg0
= CALL_EXPR_ARG (exp
, 0);
6278 arg1
= CALL_EXPR_ARG (exp
, 1);
6279 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6280 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6282 if (!CONST_INT_P (op0
)
6283 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6284 error ("operand 1 should be an unsigned 3-bit immediate");
6286 mode1
= insn_data
[icode
].operand
[1].mode
;
6288 if (icode
== CODE_FOR_vdiwr_insn
)
6289 target
= gen_rtx_REG (SImode
,
6290 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6291 else if (icode
== CODE_FOR_vdowr_insn
)
6292 target
= gen_rtx_REG (SImode
,
6293 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6297 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6298 op1
= copy_to_mode_reg (mode1
, op1
);
6300 pat
= GEN_FCN (icode
) (target
, op1
);
6307 case ARC_BUILTIN_VASRW
:
6308 case ARC_BUILTIN_VSR8
:
6309 case ARC_BUILTIN_VSR8AW
:
6310 arg0
= CALL_EXPR_ARG (exp
, 0);
6311 arg1
= CALL_EXPR_ARG (exp
, 1);
6312 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6313 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6314 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6316 target
= gen_reg_rtx (V8HImode
);
6317 mode0
= insn_data
[icode
].operand
[1].mode
;
6318 mode1
= insn_data
[icode
].operand
[2].mode
;
6320 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6321 op0
= copy_to_mode_reg (mode0
, op0
);
6323 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6324 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6325 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6327 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6334 case ARC_BUILTIN_VLD32WH
:
6335 case ARC_BUILTIN_VLD32WL
:
6336 case ARC_BUILTIN_VLD64
:
6337 case ARC_BUILTIN_VLD32
:
6340 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6341 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6342 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6344 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6345 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6346 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6347 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6349 /* target <- src vreg. */
6350 emit_insn (gen_move_insn (target
, src_vreg
));
6352 /* target <- vec_concat: target, mem (Ib, u8). */
6353 mode0
= insn_data
[icode
].operand
[3].mode
;
6354 mode1
= insn_data
[icode
].operand
[1].mode
;
6356 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6357 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6358 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6360 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6361 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6362 error ("operand 2 should be an unsigned 8-bit value");
6364 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6371 case ARC_BUILTIN_VLD64W
:
6372 case ARC_BUILTIN_VLD128
:
6373 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6374 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6376 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6377 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6378 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6380 /* target <- src vreg. */
6381 target
= gen_reg_rtx (V8HImode
);
6383 /* target <- vec_concat: target, mem (Ib, u8). */
6384 mode0
= insn_data
[icode
].operand
[1].mode
;
6385 mode1
= insn_data
[icode
].operand
[2].mode
;
6386 mode2
= insn_data
[icode
].operand
[3].mode
;
6388 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6389 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6390 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6392 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6393 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6394 error ("operand 2 should be an unsigned 8-bit value");
6396 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6404 case ARC_BUILTIN_VST128
:
6405 case ARC_BUILTIN_VST64
:
6406 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6407 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6408 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6410 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6411 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6412 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6413 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6415 mode0
= insn_data
[icode
].operand
[0].mode
;
6416 mode1
= insn_data
[icode
].operand
[1].mode
;
6417 mode2
= insn_data
[icode
].operand
[2].mode
;
6418 mode3
= insn_data
[icode
].operand
[3].mode
;
6420 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6421 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6422 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6424 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6425 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6426 error ("operand 3 should be an unsigned 8-bit value");
6428 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6429 op3
= copy_to_mode_reg (mode3
, op3
);
6431 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6438 case ARC_BUILTIN_VST16_N
:
6439 case ARC_BUILTIN_VST32_N
:
6440 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6441 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6442 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6443 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6445 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6446 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6447 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6448 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6449 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6451 mode0
= insn_data
[icode
].operand
[0].mode
;
6452 mode2
= insn_data
[icode
].operand
[2].mode
;
6453 mode3
= insn_data
[icode
].operand
[3].mode
;
6454 mode4
= insn_data
[icode
].operand
[4].mode
;
6456 /* Do some correctness checks for the operands. */
6457 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6458 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6459 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6461 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6462 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6463 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6465 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6466 op3
= copy_to_mode_reg (mode3
, op3
);
6468 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6469 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6470 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6471 else if (icode
== CODE_FOR_vst32_n_insn
6472 && ((INTVAL (op4
) % 2) != 0))
6473 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6475 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6486 /* 2nd part: Expand regular builtins. */
6488 internal_error ("bad builtin fcode");
6490 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6495 if (target
== NULL_RTX
6496 || GET_MODE (target
) != tmode
6497 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6499 target
= gen_reg_rtx (tmode
);
6504 gcc_assert (n_args
<= 4);
6505 for (i
= 0; i
< n_args
; i
++, j
++)
6507 tree arg
= CALL_EXPR_ARG (exp
, i
);
6508 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6509 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6510 machine_mode opmode
= GET_MODE (op
);
6511 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6513 /* SIMD extension requires exact immediate operand match. */
6514 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6515 && (id
< ARC_BUILTIN_SIMD_END
)
6519 if (!CONST_INT_P (op
))
6520 error ("builtin requires an immediate for operand %d", j
);
6524 if (!satisfies_constraint_L (op
))
6525 error ("operand %d should be a 6 bit unsigned immediate", j
);
6528 if (!satisfies_constraint_P (op
))
6529 error ("operand %d should be a 8 bit unsigned immediate", j
);
6532 if (!satisfies_constraint_K (op
))
6533 error ("operand %d should be a 3 bit unsigned immediate", j
);
6536 error ("unknown builtin immediate operand type for operand %d",
6541 if (CONST_INT_P (op
))
6544 if ((opmode
== SImode
) && (mode
== HImode
))
6547 op
= gen_lowpart (HImode
, op
);
6550 /* In case the insn wants input operands in modes different from
6551 the result, abort. */
6552 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6554 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6555 op
= copy_to_mode_reg (mode
, op
);
6560 pat
= apply_GEN_FCN (icode
, xop
);
6561 if (pat
== NULL_RTX
)
6572 /* Returns true if the operands[opno] is a valid compile-time constant to be
6573 used as register number in the code for builtins. Else it flags an error
6574 and returns false. */
6577 check_if_valid_regno_const (rtx
*operands
, int opno
)
6580 switch (GET_CODE (operands
[opno
]))
6587 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6593 /* Check that after all the constant folding, whether the operand to
6594 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6597 check_if_valid_sleep_operand (rtx
*operands
, int opno
)
6599 switch (GET_CODE (operands
[opno
]))
6603 if( UNSIGNED_INT6 (INTVAL (operands
[opno
])))
6607 fatal_error (input_location
,
6608 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6614 /* Return true if it is ok to make a tail-call to DECL. */
6617 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
6618 tree exp ATTRIBUTE_UNUSED
)
6620 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6621 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6624 /* Everything else is ok. */
6628 /* Output code to add DELTA to the first argument, and then jump
6629 to FUNCTION. Used for C++ multiple inheritance. */
6632 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
6633 HOST_WIDE_INT delta
,
6634 HOST_WIDE_INT vcall_offset
,
6637 int mi_delta
= delta
;
6638 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
6641 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
6645 mi_delta
= - mi_delta
;
6647 /* Add DELTA. When possible use a plain add, otherwise load it into
6648 a register first. */
6650 while (mi_delta
!= 0)
6652 if ((mi_delta
& (3 << shift
)) == 0)
6656 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
6657 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
6658 mi_delta
& (0xff << shift
));
6659 mi_delta
&= ~(0xff << shift
);
6664 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6665 if (vcall_offset
!= 0)
6667 /* ld r12,[this] --> temp = *this
6668 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6670 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6671 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6672 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
6673 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
6674 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
6675 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6676 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
6677 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
6678 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
6681 fnaddr
= XEXP (DECL_RTL (function
), 0);
6683 if (arc_is_longcall_p (fnaddr
))
6687 asm_fprintf (file
, "\tld\t%s, [pcl, @",
6688 ARC_TEMP_SCRATCH_REG
);
6689 assemble_name (file
, XSTR (fnaddr
, 0));
6690 fputs ("@gotpc]\n", file
);
6691 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
6695 fputs ("\tj\t@", file
);
6696 assemble_name (file
, XSTR (fnaddr
, 0));
6701 fputs ("\tb\t@", file
);
6702 assemble_name (file
, XSTR (fnaddr
, 0));
6704 fputs ("@plt\n", file
);
6709 /* Return true if a 32 bit "long_call" should be generated for
6710 this calling SYM_REF. We generate a long_call if the function:
6712 a. has an __attribute__((long call))
6713 or b. the -mlong-calls command line switch has been specified
6715 However we do not generate a long call if the function has an
6716 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6718 This function will be called by C fragments contained in the machine
6719 description file. */
6722 arc_is_longcall_p (rtx sym_ref
)
6724 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6727 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
6728 || (TARGET_LONG_CALLS_SET
6729 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6730 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6734 /* Likewise for short calls. */
6737 arc_is_shortcall_p (rtx sym_ref
)
6739 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6742 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6743 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
6744 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
6745 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6749 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6752 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
6754 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
6758 HOST_WIDE_INT size
= int_size_in_bytes (type
);
6759 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
6764 /* This was in rtlanal.c, and can go in there when we decide we want
6765 to submit the change for inclusion in the GCC tree. */
6766 /* Like note_stores, but allow the callback to have side effects on the rtl
6767 (like the note_stores of yore):
6768 Call FUN on each register or MEM that is stored into or clobbered by X.
6769 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6770 ignored by note_stores, but passed to FUN.
6771 FUN may alter parts of the RTL.
6773 FUN receives three arguments:
6774 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6775 2. the SET or CLOBBER rtx that does the store,
6776 3. the pointer DATA provided to note_stores.
6778 If the item being stored in or clobbered is a SUBREG of a hard register,
6779 the SUBREG will be passed. */
6781 /* For now. */ static
6783 walk_stores (rtx x
, void (*fun
) (rtx
, rtx
, void *), void *data
)
6787 if (GET_CODE (x
) == COND_EXEC
)
6788 x
= COND_EXEC_CODE (x
);
6790 if (GET_CODE (x
) == SET
|| GET_CODE (x
) == CLOBBER
)
6792 rtx dest
= SET_DEST (x
);
6794 while ((GET_CODE (dest
) == SUBREG
6795 && (!REG_P (SUBREG_REG (dest
))
6796 || REGNO (SUBREG_REG (dest
)) >= FIRST_PSEUDO_REGISTER
))
6797 || GET_CODE (dest
) == ZERO_EXTRACT
6798 || GET_CODE (dest
) == STRICT_LOW_PART
)
6799 dest
= XEXP (dest
, 0);
6801 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6802 each of whose first operand is a register. */
6803 if (GET_CODE (dest
) == PARALLEL
)
6805 for (i
= XVECLEN (dest
, 0) - 1; i
>= 0; i
--)
6806 if (XEXP (XVECEXP (dest
, 0, i
), 0) != 0)
6807 (*fun
) (XEXP (XVECEXP (dest
, 0, i
), 0), x
, data
);
6810 (*fun
) (dest
, x
, data
);
6813 else if (GET_CODE (x
) == PARALLEL
)
6814 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
6815 walk_stores (XVECEXP (x
, 0, i
), fun
, data
);
6819 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
6820 machine_mode mode ATTRIBUTE_UNUSED
,
6822 bool named ATTRIBUTE_UNUSED
)
6825 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
6826 || TREE_ADDRESSABLE (type
)));
6829 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6832 arc_can_use_doloop_p (const widest_int
&iterations
, const widest_int
&,
6833 unsigned int loop_depth
, bool entered_at_top
)
6837 /* Setting up the loop with two sr instructions costs 6 cycles. */
6840 && wi::gtu_p (iterations
, 0)
6841 && wi::leu_p (iterations
, flag_pic
? 6 : 3))
6846 /* NULL if INSN insn is valid within a low-overhead loop.
6847 Otherwise return why doloop cannot be applied. */
6850 arc_invalid_within_doloop (const rtx_insn
*insn
)
6853 return "Function call in the loop.";
6857 /* Return true if a load instruction (CONSUMER) uses the same address as a
6858 store instruction (PRODUCER). This function is used to avoid st/ld
6859 address hazard in ARC700 cores. */
6861 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
6863 rtx in_set
, out_set
;
6864 rtx out_addr
, in_addr
;
6872 /* Peel the producer and the consumer for the address. */
6873 out_set
= single_set (producer
);
6876 out_addr
= SET_DEST (out_set
);
6879 if (GET_CODE (out_addr
) == ZERO_EXTEND
6880 || GET_CODE (out_addr
) == SIGN_EXTEND
)
6881 out_addr
= XEXP (out_addr
, 0);
6883 if (!MEM_P (out_addr
))
6886 in_set
= single_set (consumer
);
6889 in_addr
= SET_SRC (in_set
);
6892 if (GET_CODE (in_addr
) == ZERO_EXTEND
6893 || GET_CODE (in_addr
) == SIGN_EXTEND
)
6894 in_addr
= XEXP (in_addr
, 0);
6896 if (!MEM_P (in_addr
))
6898 /* Get rid of the MEM and check if the addresses are
6900 in_addr
= XEXP (in_addr
, 0);
6901 out_addr
= XEXP (out_addr
, 0);
6903 return exp_equiv_p (in_addr
, out_addr
, 0, true);
6909 /* The same functionality as arc_hazard. It is called in machine
6910 reorg before any other optimization. Hence, the NOP size is taken
6911 into account when doing branch shortening. */
6914 workaround_arc_anomaly (void)
6916 rtx_insn
*insn
, *succ0
;
6918 /* For any architecture: call arc_hazard here. */
6919 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6921 succ0
= next_real_insn (insn
);
6922 if (arc_hazard (insn
, succ0
))
6924 emit_insn_before (gen_nopv (), succ0
);
6932 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6934 succ0
= next_real_insn (insn
);
6935 if (arc_store_addr_hazard_p (insn
, succ0
))
6937 emit_insn_after (gen_nopv (), insn
);
6938 emit_insn_after (gen_nopv (), insn
);
6942 /* Avoid adding nops if the instruction between the ST and LD is
6944 succ1
= next_real_insn (succ0
);
6945 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
6946 && arc_store_addr_hazard_p (insn
, succ1
))
6947 emit_insn_after (gen_nopv (), insn
);
6952 static int arc_reorg_in_progress
= 0;
6954 /* ARC's machince specific reorg function. */
6965 workaround_arc_anomaly ();
6967 cfun
->machine
->arc_reorg_started
= 1;
6968 arc_reorg_in_progress
= 1;
6970 /* Link up loop ends with their loop start. */
6972 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6973 if (GET_CODE (insn
) == JUMP_INSN
6974 && recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
6977 = as_a
<rtx_insn
*> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 1), 0));
6978 rtx num
= GEN_INT (CODE_LABEL_NUMBER (top_label
));
6979 rtx_insn
*lp
, *prev
= prev_nonnote_insn (top_label
);
6980 rtx_insn
*lp_simple
= NULL
;
6981 rtx_insn
*next
= NULL
;
6982 rtx op0
= XEXP (XVECEXP (PATTERN (insn
), 0, 1), 0);
6986 (lp
&& NONJUMP_INSN_P (lp
)
6987 && recog_memoized (lp
) != CODE_FOR_doloop_begin_i
);
6988 lp
= prev_nonnote_insn (lp
))
6990 if (!lp
|| !NONJUMP_INSN_P (lp
)
6991 || dead_or_set_regno_p (lp
, LP_COUNT
))
6993 HOST_WIDE_INT loop_end_id
6994 = INTVAL (XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0));
6996 for (prev
= next
= insn
, lp
= NULL
; prev
|| next
;)
7000 if (NONJUMP_INSN_P (prev
)
7001 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
7002 && (INTVAL (XEXP (XVECEXP (PATTERN (prev
), 0, 5), 0))
7008 else if (LABEL_P (prev
))
7010 prev
= prev_nonnote_insn (prev
);
7014 if (NONJUMP_INSN_P (next
)
7015 && recog_memoized (next
) == CODE_FOR_doloop_begin_i
7016 && (INTVAL (XEXP (XVECEXP (PATTERN (next
), 0, 5), 0))
7022 next
= next_nonnote_insn (next
);
7029 if (lp
&& !dead_or_set_regno_p (lp
, LP_COUNT
))
7031 rtx begin_cnt
= XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0);
7032 if (INTVAL (XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0)))
7033 /* The loop end insn has been duplicated. That can happen
7034 when there is a conditional block at the very end of
7037 /* If Register allocation failed to allocate to the right
7038 register, There is no point into teaching reload to
7039 fix this up with reloads, as that would cost more
7040 than using an ordinary core register with the
7041 doloop_fallback pattern. */
7042 if ((true_regnum (op0
) != LP_COUNT
|| !REG_P (begin_cnt
))
7043 /* Likewise, if the loop setup is evidently inside the loop,
7045 || (!lp_simple
&& lp
!= next
&& !seen_label
))
7050 /* It is common that the optimizers copy the loop count from
7051 another register, and doloop_begin_i is stuck with the
7052 source of the move. Making doloop_begin_i only accept "l"
7053 is nonsentical, as this then makes reload evict the pseudo
7054 used for the loop end. The underlying cause is that the
7055 optimizers don't understand that the register allocation for
7056 doloop_begin_i should be treated as part of the loop.
7057 Try to work around this problem by verifying the previous
7059 if (true_regnum (begin_cnt
) != LP_COUNT
)
7064 for (mov
= prev_nonnote_insn (lp
); mov
;
7065 mov
= prev_nonnote_insn (mov
))
7067 if (!NONJUMP_INSN_P (mov
))
7069 else if ((set
= single_set (mov
))
7070 && rtx_equal_p (SET_SRC (set
), begin_cnt
)
7071 && rtx_equal_p (SET_DEST (set
), op0
))
7076 XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0) = op0
;
7077 note
= find_regno_note (lp
, REG_DEAD
, REGNO (begin_cnt
));
7079 remove_note (lp
, note
);
7087 XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0) = num
;
7088 XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0) = num
;
7090 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const2_rtx
;
7091 else if (!lp_simple
)
7092 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const1_rtx
;
7093 else if (prev
!= lp
)
7096 add_insn_after (lp
, prev
, NULL
);
7100 XEXP (XVECEXP (PATTERN (lp
), 0, 7), 0)
7101 = gen_rtx_LABEL_REF (Pmode
, top_label
);
7102 add_reg_note (lp
, REG_LABEL_OPERAND
, top_label
);
7103 LABEL_NUSES (top_label
)++;
7105 /* We can avoid tedious loop start / end setting for empty loops
7106 be merely setting the loop count to its final value. */
7107 if (next_active_insn (top_label
) == insn
)
7110 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp
), 0, 3), 0),
7113 rtx_insn
*lc_set_insn
= emit_insn_before (lc_set
, insn
);
7118 /* If the loop is non-empty with zero length, we can't make it
7119 a zero-overhead loop. That can happen for empty asms. */
7124 for (scan
= top_label
;
7125 (scan
&& scan
!= insn
7126 && (!NONJUMP_INSN_P (scan
) || !get_attr_length (scan
)));
7127 scan
= NEXT_INSN (scan
));
7137 /* Sometimes the loop optimizer makes a complete hash of the
7138 loop. If it were only that the loop is not entered at the
7139 top, we could fix this up by setting LP_START with SR .
7140 However, if we can't find the loop begin were it should be,
7141 chances are that it does not even dominate the loop, but is
7142 inside the loop instead. Using SR there would kill
7144 We use the doloop_fallback pattern here, which executes
7145 in two cycles on the ARC700 when predicted correctly. */
7149 rtx op3
= XEXP (XVECEXP (PATTERN (insn
), 0, 5), 0);
7151 emit_insn_before (gen_move_insn (op3
, op0
), insn
);
7153 = gen_doloop_fallback_m (op3
, JUMP_LABEL (insn
), op0
);
7156 XVEC (PATTERN (insn
), 0)
7157 = gen_rtvec (2, XVECEXP (PATTERN (insn
), 0, 0),
7158 XVECEXP (PATTERN (insn
), 0, 1));
7159 INSN_CODE (insn
) = -1;
7164 /* FIXME: should anticipate ccfsm action, generate special patterns for
7165 to-be-deleted branches that have no delay slot and have at least the
7166 length of the size increase forced on other insns that are conditionalized.
7167 This can also have an insn_list inside that enumerates insns which are
7168 not actually conditionalized because the destinations are dead in the
7170 Could also tag branches that we want to be unaligned if they get no delay
7171 slot, or even ones that we don't want to do delay slot sheduling for
7172 because we can unalign them.
7174 However, there are cases when conditional execution is only possible after
7175 delay slot scheduling:
7177 - If a delay slot is filled with a nocond/set insn from above, the previous
7178 basic block can become elegible for conditional execution.
7179 - If a delay slot is filled with a nocond insn from the fall-through path,
7180 the branch with that delay slot can become eligble for conditional
7181 execution (however, with the same sort of data flow analysis that dbr
7182 does, we could have figured out before that we don't need to
7183 conditionalize this insn.)
7184 - If a delay slot insn is filled with an insn from the target, the
7185 target label gets its uses decremented (even deleted if falling to zero),
7186 thus possibly creating more condexec opportunities there.
7187 Therefore, we should still be prepared to apply condexec optimization on
7188 non-prepared branches if the size increase of conditionalized insns is no
7189 more than the size saved from eliminating the branch. An invocation option
7190 could also be used to reserve a bit of extra size for condbranches so that
7191 this'll work more often (could also test in arc_reorg if the block is
7192 'close enough' to be eligible for condexec to make this likely, and
7193 estimate required size increase). */
7194 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7195 if (TARGET_NO_BRCC_SET
)
7200 init_insn_lengths();
7203 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
7206 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
7207 df_finish_pass ((flags
& TODO_df_verify
) != 0);
7210 /* Call shorten_branches to calculate the insn lengths. */
7211 shorten_branches (get_insns());
7212 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
7214 if (!INSN_ADDRESSES_SET_P())
7215 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
7217 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7220 enum attr_type insn_type
;
7222 /* If a non-jump insn (or a casesi jump table), continue. */
7223 if (GET_CODE (insn
) != JUMP_INSN
||
7224 GET_CODE (PATTERN (insn
)) == ADDR_VEC
7225 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
7228 /* If we already have a brcc, note if it is suitable for brcc_s.
7229 Be a bit generous with the brcc_s range so that we can take
7230 advantage of any code shortening from delay slot scheduling. */
7231 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
7233 rtx pat
= PATTERN (insn
);
7234 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
7235 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
7237 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7238 if ((offset
>= -140 && offset
< 140)
7239 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
7240 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
7241 && equality_comparison_operator (op
, VOIDmode
))
7242 PUT_MODE (*ccp
, CC_Zmode
);
7243 else if (GET_MODE (*ccp
) == CC_Zmode
)
7244 PUT_MODE (*ccp
, CC_ZNmode
);
7247 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
7248 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
7251 /* OK. so we have a jump insn. */
7252 /* We need to check that it is a bcc. */
7253 /* Bcc => set (pc) (if_then_else ) */
7254 pattern
= PATTERN (insn
);
7255 if (GET_CODE (pattern
) != SET
7256 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
7257 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
7260 /* Now check if the jump is beyond the s9 range. */
7261 if (CROSSING_JUMP_P (insn
))
7263 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7265 if(offset
> 253 || offset
< -254)
7268 pc_target
= SET_SRC (pattern
);
7270 /* Avoid FPU instructions. */
7271 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
7272 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
7275 /* Now go back and search for the set cc insn. */
7277 label
= XEXP (pc_target
, 1);
7281 rtx_insn
*scan
, *link_insn
= NULL
;
7283 for (scan
= PREV_INSN (insn
);
7284 scan
&& GET_CODE (scan
) != CODE_LABEL
;
7285 scan
= PREV_INSN (scan
))
7287 if (! INSN_P (scan
))
7289 pat
= PATTERN (scan
);
7290 if (GET_CODE (pat
) == SET
7291 && cc_register (SET_DEST (pat
), VOIDmode
))
7300 /* Check if this is a data dependency. */
7302 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
7305 /* Ok this is the set cc. copy args here. */
7306 op
= XEXP (pc_target
, 0);
7308 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
7309 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
7310 if (GET_CODE (op0
) == ZERO_EXTRACT
7311 && XEXP (op0
, 1) == const1_rtx
7312 && (GET_CODE (op
) == EQ
7313 || GET_CODE (op
) == NE
))
7315 /* btst / b{eq,ne} -> bbit{0,1} */
7316 op0
= XEXP (cmp0
, 0);
7317 op1
= XEXP (cmp0
, 2);
7319 else if (!register_operand (op0
, VOIDmode
)
7320 || !general_operand (op1
, VOIDmode
))
7322 /* Be careful not to break what cmpsfpx_raw is
7323 trying to create for checking equality of
7324 single-precision floats. */
7325 else if (TARGET_SPFP
7326 && GET_MODE (op0
) == SFmode
7327 && GET_MODE (op1
) == SFmode
)
7330 /* None of the two cmp operands should be set between the
7331 cmp and the branch. */
7332 if (reg_set_between_p (op0
, link_insn
, insn
))
7335 if (reg_set_between_p (op1
, link_insn
, insn
))
7338 /* Since the MODE check does not work, check that this is
7339 CC reg's last set location before insn, and also no
7340 instruction between the cmp and branch uses the
7342 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
7343 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
7346 /* CC reg should be dead after insn. */
7347 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
7350 op
= gen_rtx_fmt_ee (GET_CODE (op
),
7351 GET_MODE (op
), cmp0
, cmp1
);
7352 /* If we create a LIMM where there was none before,
7353 we only benefit if we can avoid a scheduling bubble
7354 for the ARC600. Otherwise, we'd only forgo chances
7355 at short insn generation, and risk out-of-range
7357 if (!brcc_nolimm_operator (op
, VOIDmode
)
7358 && !long_immediate_operand (op1
, VOIDmode
)
7360 || next_active_insn (link_insn
) != insn
))
7363 /* Emit bbit / brcc (or brcc_s if possible).
7364 CC_Zmode indicates that brcc_s is possible. */
7367 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
7368 else if ((offset
>= -140 && offset
< 140)
7369 && rtx_equal_p (op1
, const0_rtx
)
7370 && compact_register_operand (op0
, VOIDmode
)
7371 && (GET_CODE (op
) == EQ
7372 || GET_CODE (op
) == NE
))
7373 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
7375 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
7378 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
7379 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
7380 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
7383 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
7384 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
7386 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
7387 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
7390 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7391 REG_NOTES (brcc_insn
) = note
;
7393 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
7396 remove_note (link_insn
, note
);
7397 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7398 REG_NOTES (brcc_insn
) = note
;
7400 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
7403 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7404 REG_NOTES (brcc_insn
) = note
;
7409 /* Delete the bcc insn. */
7410 set_insn_deleted (insn
);
7412 /* Delete the cmp insn. */
7413 set_insn_deleted (link_insn
);
7418 /* Clear out insn_addresses. */
7419 INSN_ADDRESSES_FREE ();
7423 if (INSN_ADDRESSES_SET_P())
7424 fatal_error (input_location
, "insn addresses not freed");
7426 arc_reorg_in_progress
= 0;
7429 /* Check if the operands are valid for BRcc.d generation
7430 Valid Brcc.d patterns are
7434 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7435 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7436 does not have a delay slot
7438 Assumed precondition: Second operand is either a register or a u6 value. */
7441 valid_brcc_with_delay_p (rtx
*operands
)
7443 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
7445 return brcc_nolimm_operator (operands
[0], VOIDmode
);
7448 /* ??? Hack. This should no really be here. See PR32143. */
7450 arc_decl_anon_ns_mem_p (const_tree decl
)
7454 if (decl
== NULL_TREE
|| decl
== error_mark_node
)
7456 if (TREE_CODE (decl
) == NAMESPACE_DECL
7457 && DECL_NAME (decl
) == NULL_TREE
)
7459 /* Classes and namespaces inside anonymous namespaces have
7460 TREE_PUBLIC == 0, so we can shortcut the search. */
7461 else if (TYPE_P (decl
))
7462 return (TREE_PUBLIC (TYPE_NAME (decl
)) == 0);
7463 else if (TREE_CODE (decl
) == NAMESPACE_DECL
)
7464 return (TREE_PUBLIC (decl
) == 0);
7466 decl
= DECL_CONTEXT (decl
);
7470 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7471 access DECL using %gp_rel(...)($gp). */
7474 arc_in_small_data_p (const_tree decl
)
7478 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
7482 /* We don't yet generate small-data references for -mabicalls. See related
7483 -G handling in override_options. */
7484 if (TARGET_NO_SDATA_SET
)
7487 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
7491 /* Reject anything that isn't in a known small-data section. */
7492 name
= DECL_SECTION_NAME (decl
);
7493 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
7496 /* If a symbol is defined externally, the assembler will use the
7497 usual -G rules when deciding how to implement macros. */
7498 if (!DECL_EXTERNAL (decl
))
7501 /* Only global variables go into sdata section for now. */
7504 /* Don't put constants into the small data section: we want them
7505 to be in ROM rather than RAM. */
7506 if (TREE_CODE (decl
) != VAR_DECL
)
7509 if (TREE_READONLY (decl
)
7510 && !TREE_SIDE_EFFECTS (decl
)
7511 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
7514 /* TREE_PUBLIC might change after the first call, because of the patch
7516 if (default_binds_local_p_1 (decl
, 1)
7517 || arc_decl_anon_ns_mem_p (decl
))
7520 /* To ensure -mvolatile-cache works
7521 ld.di does not have a gp-relative variant. */
7522 if (TREE_THIS_VOLATILE (decl
))
7526 /* Disable sdata references to weak variables. */
7527 if (DECL_WEAK (decl
))
7530 size
= int_size_in_bytes (TREE_TYPE (decl
));
7532 /* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7535 /* Allow only <=4B long data types into sdata. */
7536 return (size
> 0 && size
<= 4);
7539 /* Return true if X is a small data address that can be rewritten
7543 arc_rewrite_small_data_p (const_rtx x
)
7545 if (GET_CODE (x
) == CONST
)
7548 if (GET_CODE (x
) == PLUS
)
7550 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
7554 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
7556 gcc_assert (SYMBOL_REF_TLS_MODEL (x
) == 0);
7562 /* If possible, rewrite OP so that it refers to small data using
7563 explicit relocations. */
7566 arc_rewrite_small_data (rtx op
)
7568 op
= copy_insn (op
);
7569 subrtx_ptr_iterator::array_type array
;
7570 FOR_EACH_SUBRTX_PTR (iter
, array
, &op
, ALL
)
7573 if (arc_rewrite_small_data_p (*loc
))
7575 gcc_assert (SDATA_BASE_REGNUM
== PIC_OFFSET_TABLE_REGNUM
);
7576 *loc
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, *loc
);
7579 if (GET_CODE (op
) == MEM
&& &XEXP (op
, 0) == loc
)
7581 else if (GET_CODE (op
) == MEM
7582 && GET_CODE (XEXP (op
, 0)) == PLUS
7583 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == MULT
)
7584 *loc
= force_reg (Pmode
, *loc
);
7588 iter
.skip_subrtxes ();
7590 else if (GET_CODE (*loc
) == PLUS
7591 && rtx_equal_p (XEXP (*loc
, 0), pic_offset_table_rtx
))
7592 iter
.skip_subrtxes ();
7597 /* Return true if OP refers to small data symbols directly, not through
7601 small_data_pattern (rtx op
, machine_mode
)
7603 if (GET_CODE (op
) == SEQUENCE
)
7605 subrtx_iterator::array_type array
;
7606 FOR_EACH_SUBRTX (iter
, array
, op
, ALL
)
7608 const_rtx x
= *iter
;
7609 if (GET_CODE (x
) == PLUS
7610 && rtx_equal_p (XEXP (x
, 0), pic_offset_table_rtx
))
7611 iter
.skip_subrtxes ();
7612 else if (arc_rewrite_small_data_p (x
))
7618 /* Return true if OP is an acceptable memory operand for ARCompact
7619 16-bit gp-relative load instructions.
7620 op shd look like : [r26, symref@sda]
7621 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7623 /* volatile cache option still to be handled. */
7626 compact_sda_memory_operand (rtx op
, machine_mode mode
)
7631 /* Eliminate non-memory operations. */
7632 if (GET_CODE (op
) != MEM
)
7635 if (mode
== VOIDmode
)
7636 mode
= GET_MODE (op
);
7638 size
= GET_MODE_SIZE (mode
);
7640 /* dword operations really put out 2 instructions, so eliminate them. */
7641 if (size
> UNITS_PER_WORD
)
7644 /* Decode the address now. */
7645 addr
= XEXP (op
, 0);
7647 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
);
7650 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7653 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
7654 unsigned HOST_WIDE_INT size
,
7655 unsigned HOST_WIDE_INT align
,
7656 unsigned HOST_WIDE_INT globalize_p
)
7658 int in_small_data
= arc_in_small_data_p (decl
);
7661 switch_to_section (get_named_section (NULL
, ".sbss", 0));
7662 /* named_section (0,".sbss",0); */
7664 switch_to_section (bss_section
);
7667 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
7669 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
7670 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
7671 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
7672 ASM_OUTPUT_LABEL (stream
, name
);
7675 ASM_OUTPUT_SKIP (stream
, size
);
7679 arc_preserve_reload_p (rtx in
)
7681 return (GET_CODE (in
) == PLUS
7682 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
7683 && CONST_INT_P (XEXP (in
, 1))
7684 && !((INTVAL (XEXP (in
, 1)) & 511)));
7688 arc_register_move_cost (machine_mode
,
7689 enum reg_class from_class
, enum reg_class to_class
)
7691 /* The ARC600 has no bypass for extension registers, hence a nop might be
7692 needed to be inserted after a write so that reads are safe. */
7695 if (to_class
== MPY_WRITABLE_CORE_REGS
)
7697 /* Instructions modifying LP_COUNT need 4 additional cycles before
7698 the register will actually contain the value. */
7699 else if (to_class
== LPCOUNT_REG
)
7701 else if (to_class
== WRITABLE_CORE_REGS
)
7705 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7707 && (from_class
== LPCOUNT_REG
|| from_class
== ALL_CORE_REGS
7708 || from_class
== WRITABLE_CORE_REGS
))
7711 /* Force an attempt to 'mov Dy,Dx' to spill. */
7712 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
7713 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
7719 /* Emit code for an addsi3 instruction with OPERANDS.
7720 COND_P indicates if this will use conditional execution.
7721 Return the length of the instruction.
7722 If OUTPUT_P is false, don't actually output the instruction, just return
7725 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
7729 int match
= operands_match_p (operands
[0], operands
[1]);
7730 int match2
= operands_match_p (operands
[0], operands
[2]);
7731 int intval
= (REG_P (operands
[2]) ? 1
7732 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
7733 int neg_intval
= -intval
;
7734 int short_0
= satisfies_constraint_Rcq (operands
[0]);
7735 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
7738 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
7739 && REGNO (OP) != 30) \
7742 #define ADDSI_OUTPUT1(FORMAT) do {\
7744 output_asm_insn (FORMAT, operands);\
7747 #define ADDSI_OUTPUT(LIST) do {\
7750 ADDSI_OUTPUT1 (format);\
7754 /* First try to emit a 16 bit insn. */
7757 /* If we are actually about to output this insn, don't try a 16 bit
7758 variant if we already decided that we don't want that
7759 (I.e. we upsized this insn to align some following insn.)
7760 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7761 but add1 r0,sp,35 doesn't. */
7762 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
7764 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
7767 && ((REG_H_P (operands
[2])
7768 && (match
|| satisfies_constraint_Rcq (operands
[2])))
7769 || (CONST_INT_P (operands
[2])
7770 && ((unsigned) intval
<= (match
? 127 : 7)))))
7771 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
7773 /* Generate add_s b,b,h patterns. */
7774 if (short_0
&& match2
&& REG_H_P (operands
[1]))
7775 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
7777 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
7778 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
7779 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
7780 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
7782 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
7783 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
7784 && match
&& !(neg_intval
& ~124)))
7785 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
7787 /* Generate add_s h,h,s3 patterns. */
7788 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
7789 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
7790 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
7792 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
7793 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
7794 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
7795 && satisfies_constraint_Rcq (operands
[1])
7796 && satisfies_constraint_L (operands
[2]))
7797 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
7800 /* Now try to emit a 32 bit insn without long immediate. */
7802 if (!match
&& match2
&& REG_P (operands
[1]))
7803 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7804 if (match
|| !cond_p
)
7806 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
7807 int range_factor
= neg_intval
& intval
;
7810 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
7811 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7813 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7814 same size, do, so - the insn latency is lower. */
7815 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7817 if ((intval
>= 0 && intval
<= limit
)
7818 || (intval
== -0x800 && limit
== 0x7ff))
7819 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7820 else if ((intval
< 0 && neg_intval
<= limit
)
7821 || (intval
== 0x800 && limit
== 0x7ff))
7822 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7823 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
7824 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
7825 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
7826 if (((intval
< 0 && intval
!= -0x4000)
7827 /* sub[123] is slower than add_s / sub, only use it if it
7828 avoids a long immediate. */
7829 && neg_intval
<= limit
<< shift
)
7830 || (intval
== 0x4000 && limit
== 0x7ff))
7831 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
7832 shift
, neg_intval
>> shift
));
7833 else if ((intval
>= 0 && intval
<= limit
<< shift
)
7834 || (intval
== -0x4000 && limit
== 0x7ff))
7835 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
7837 /* Try to emit a 16 bit opcode with long immediate. */
7839 if (short_p
&& match
)
7840 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7842 /* We have to use a 32 bit opcode, and with a long immediate. */
7844 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7847 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
7848 Return the length of the instruction.
7849 If OUTPUT_P is false, don't actually output the instruction, just return
7852 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
7854 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
7855 const char *pat
= NULL
;
7857 /* Canonical rtl should not have a constant in the first operand position. */
7858 gcc_assert (!CONSTANT_P (operands
[1]));
7860 switch (commutative_op
)
7863 if (satisfies_constraint_C1p (operands
[2]))
7864 pat
= "bmsk%? %0,%1,%Z2";
7865 else if (satisfies_constraint_C2p (operands
[2]))
7867 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
7868 pat
= "bmskn%? %0,%1,%Z2";
7870 else if (satisfies_constraint_Ccp (operands
[2]))
7871 pat
= "bclr%? %0,%1,%M2";
7872 else if (satisfies_constraint_CnL (operands
[2]))
7873 pat
= "bic%? %0,%1,%n2-1";
7876 if (satisfies_constraint_C0p (operands
[2]))
7877 pat
= "bset%? %0,%1,%z2";
7880 if (satisfies_constraint_C0p (operands
[2]))
7881 pat
= "bxor%? %0,%1,%z2";
7884 return arc_output_addsi (operands
, true, output_p
);
7888 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
7889 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
7894 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7895 Emit code and return an potentially modified address such that offsets
7896 up to SIZE are can be added to yield a legitimate address.
7897 if REUSE is set, ADDR is a register that may be modified. */
7900 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
7903 rtx offs
= const0_rtx
;
7905 if (GET_CODE (base
) == PLUS
)
7907 offs
= XEXP (base
, 1);
7908 base
= XEXP (base
, 0);
7911 || (REGNO (base
) != STACK_POINTER_REGNUM
7912 && REGNO_PTR_FRAME_P (REGNO (base
)))
7913 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
7914 || !SMALL_INT (INTVAL (offs
) + size
))
7917 emit_insn (gen_add2_insn (addr
, offs
));
7919 addr
= copy_to_mode_reg (Pmode
, addr
);
7924 /* Like move_by_pieces, but take account of load latency, and actual
7925 offset ranges. Return true on success. */
7928 arc_expand_movmem (rtx
*operands
)
7930 rtx dst
= operands
[0];
7931 rtx src
= operands
[1];
7932 rtx dst_addr
, src_addr
;
7934 int align
= INTVAL (operands
[3]);
7941 if (!CONST_INT_P (operands
[2]))
7943 size
= INTVAL (operands
[2]);
7944 /* move_by_pieces_ninsns is static, so we can't use it. */
7948 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
7950 n_pieces
= (size
+ 2) / 4U + (size
& 1);
7952 else if (align
== 2)
7953 n_pieces
= (size
+ 1) / 2U;
7956 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
7958 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7960 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
7964 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
7965 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
7966 store
[0] = store
[1] = NULL_RTX
;
7967 tmpx
[0] = tmpx
[1] = NULL_RTX
;
7968 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
7973 while (piece
> size
)
7975 mode
= smallest_mode_for_size (piece
* BITS_PER_UNIT
, MODE_INT
);
7976 /* If we don't re-use temporaries, the scheduler gets carried away,
7977 and the register pressure gets unnecessarily high. */
7978 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
7981 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
7982 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
7983 src_addr
= force_offsettable (src_addr
, piece
, 1);
7985 emit_insn (store
[i
]);
7986 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
7987 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
7988 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
7989 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
7992 emit_insn (store
[i
]);
7994 emit_insn (store
[i
^1]);
7998 /* Prepare operands for move in MODE. Return true iff the move has
8002 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8004 /* We used to do this only for MODE_INT Modes, but addresses to floating
8005 point variables may well be in the small data section. */
8006 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[0], Pmode
))
8007 operands
[0] = arc_rewrite_small_data (operands
[0]);
8009 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
8011 prepare_pic_move (operands
, SImode
);
8013 /* Disable any REG_EQUALs associated with the symref
8014 otherwise the optimization pass undoes the work done
8015 here and references the variable directly. */
8018 if (GET_CODE (operands
[0]) != MEM
8019 && !TARGET_NO_SDATA_SET
8020 && small_data_pattern (operands
[1], Pmode
))
8022 /* This is to take care of address calculations involving sdata
8024 operands
[1] = arc_rewrite_small_data (operands
[1]);
8026 emit_insn (gen_rtx_SET (operands
[0],operands
[1]));
8027 /* ??? This note is useless, since it only restates the set itself.
8028 We should rather use the original SYMBOL_REF. However, there is
8029 the problem that we are lying to the compiler about these
8030 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8031 so that we can tell it apart from an actual symbol. */
8032 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8034 /* Take care of the REG_EQUAL note that will be attached to mark the
8035 output reg equal to the initial symbol_ref after this code is
8037 emit_move_insn (operands
[0], operands
[0]);
8041 if (MEM_P (operands
[0])
8042 && !(reload_in_progress
|| reload_completed
))
8044 operands
[1] = force_reg (mode
, operands
[1]);
8045 if (!move_dest_operand (operands
[0], mode
))
8047 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
8048 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8049 except that we can't use that function because it is static. */
8050 rtx pat
= change_address (operands
[0], mode
, addr
);
8051 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8054 if (!cse_not_expected
)
8056 rtx pat
= XEXP (operands
[0], 0);
8058 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8061 pat
= change_address (operands
[0], mode
, pat
);
8062 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8068 if (MEM_P (operands
[1]) && !cse_not_expected
)
8070 rtx pat
= XEXP (operands
[1], 0);
8072 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8075 pat
= change_address (operands
[1], mode
, pat
);
8076 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
8084 /* Prepare OPERANDS for an extension using CODE to OMODE.
8085 Return true iff the move has been emitted. */
8088 prepare_extend_operands (rtx
*operands
, enum rtx_code code
,
8091 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[1], Pmode
))
8093 /* This is to take care of address calculations involving sdata
8096 = gen_rtx_fmt_e (code
, omode
, arc_rewrite_small_data (operands
[1]));
8097 emit_insn (gen_rtx_SET (operands
[0], operands
[1]));
8098 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8100 /* Take care of the REG_EQUAL note that will be attached to mark the
8101 output reg equal to the initial extension after this code is
8103 emit_move_insn (operands
[0], operands
[0]);
8109 /* Output a library call to a function called FNAME that has been arranged
8110 to be local to any dso. */
8113 arc_output_libcall (const char *fname
)
8115 unsigned len
= strlen (fname
);
8116 static char buf
[64];
8118 gcc_assert (len
< sizeof buf
- 35);
8119 if (TARGET_LONG_CALLS_SET
8120 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
8123 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
8125 sprintf (buf
, "jl%%! @%s", fname
);
8128 sprintf (buf
, "bl%%!%%* @%s", fname
);
8132 /* Return the SImode highpart of the DImode value IN. */
8135 disi_highpart (rtx in
)
8137 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
8140 /* Return length adjustment for INSN.
8142 A write to a core reg greater or equal to 32 must not be immediately
8143 followed by a use. Anticipate the length requirement to insert a nop
8144 between PRED and SUCC to prevent a hazard. */
8147 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8151 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
8152 in front of SUCC anyway, so there will be separation between PRED and
8154 if (recog_memoized (succ
) == CODE_FOR_doloop_end_i
8155 && LABEL_P (prev_nonnote_insn (succ
)))
8157 if (recog_memoized (succ
) == CODE_FOR_doloop_begin_i
)
8159 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8160 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
8161 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
8162 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
8163 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
8164 || recog_memoized (pred
) == CODE_FOR_umul_600
8165 || recog_memoized (pred
) == CODE_FOR_mac_600
8166 || recog_memoized (pred
) == CODE_FOR_mul64_600
8167 || recog_memoized (pred
) == CODE_FOR_mac64_600
8168 || recog_memoized (pred
) == CODE_FOR_umul64_600
8169 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
8171 subrtx_iterator::array_type array
;
8172 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
8174 const_rtx x
= *iter
;
8175 switch (GET_CODE (x
))
8177 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8180 /* This is also fine for PRE/POST_MODIFY, because they
8184 rtx dest
= XEXP (x
, 0);
8185 /* Check if this sets a an extension register. N.B. we use 61 for the
8186 condition codes, which is definitely not an extension register. */
8187 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
8188 /* Check if the same register is used by the PAT. */
8189 && (refers_to_regno_p
8191 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
8192 PATTERN (succ
), 0)))
8198 /* Given a rtx, check if it is an assembly instruction or not. */
8201 arc_asm_insn_p (rtx x
)
8208 switch (GET_CODE (x
))
8215 return arc_asm_insn_p (SET_SRC (x
));
8219 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8220 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
8232 /* We might have a CALL to a non-returning function before a loop end.
8233 ??? Although the manual says that's OK (the target is outside the
8234 loop, and the loop counter unused there), the assembler barfs on
8235 this for ARC600, so we must insert a nop before such a call too.
8236 For ARC700, and ARCv2 is not allowed to have the last ZOL
8237 instruction a jump to a location where lp_count is modified. */
8240 arc_loop_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8242 rtx_insn
*jump
= NULL
;
8243 rtx label_rtx
= NULL_RTX
;
8244 rtx_insn
*label
= NULL
;
8245 basic_block succ_bb
;
8247 if (recog_memoized (succ
) != CODE_FOR_doloop_end_i
)
8250 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
8251 (i.e., jump/call) as the last instruction of a ZOL. */
8252 if (TARGET_ARC600
|| TARGET_HS
)
8253 if (JUMP_P (pred
) || CALL_P (pred
)
8254 || arc_asm_insn_p (PATTERN (pred
))
8255 || GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8258 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
8259 instruction a jump to a location where lp_count is modified. */
8261 /* Phase 2a: Dig for the jump instruction. */
8264 else if (GET_CODE (PATTERN (pred
)) == SEQUENCE
8265 && JUMP_P (XVECEXP (PATTERN (pred
), 0, 0)))
8266 jump
= as_a
<rtx_insn
*> (XVECEXP (PATTERN (pred
), 0, 0));
8270 /* Phase 2b: Make sure is not a millicode jump. */
8271 if ((GET_CODE (PATTERN (jump
)) == PARALLEL
)
8272 && (XVECEXP (PATTERN (jump
), 0, 0) == ret_rtx
))
8275 label_rtx
= JUMP_LABEL (jump
);
8279 /* Phase 2c: Make sure is not a return. */
8280 if (ANY_RETURN_P (label_rtx
))
8283 /* Pahse 2d: Go to the target of the jump and check for aliveness of
8284 LP_COUNT register. */
8285 label
= safe_as_a
<rtx_insn
*> (label_rtx
);
8286 succ_bb
= BLOCK_FOR_INSN (label
);
8289 gcc_assert (NEXT_INSN (label
));
8290 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label
)))
8291 succ_bb
= NOTE_BASIC_BLOCK (NEXT_INSN (label
));
8293 succ_bb
= BLOCK_FOR_INSN (NEXT_INSN (label
));
8296 if (succ_bb
&& REGNO_REG_SET_P (df_get_live_out (succ_bb
), LP_COUNT
))
8303 A write to a core reg greater or equal to 32 must not be immediately
8304 followed by a use. Anticipate the length requirement to insert a nop
8305 between PRED and SUCC to prevent a hazard. */
8308 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8310 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
8313 if (arc_loop_hazard (pred
, succ
))
8317 return arc600_corereg_hazard (pred
, succ
);
8322 /* Return length adjustment for INSN. */
8325 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
8329 /* We already handle sequences by ignoring the delay sequence flag. */
8330 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8333 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
8334 the ZOL mechanism only triggers when advancing to the end address,
8335 so if there's a label at the end of a ZOL, we need to insert a nop.
8336 The ARC600 ZOL also has extra restrictions on jumps at the end of a
8338 if (recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
8340 rtx_insn
*prev
= prev_nonnote_insn (insn
);
8342 return ((LABEL_P (prev
)
8345 || CALL_P (prev
) /* Could be a noreturn call. */
8346 || (NONJUMP_INSN_P (prev
)
8347 && GET_CODE (PATTERN (prev
)) == SEQUENCE
))))
8351 /* Check for return with but one preceding insn since function
8353 if (TARGET_PAD_RETURN
8355 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
8356 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
8357 && get_attr_type (insn
) == TYPE_RETURN
)
8359 rtx_insn
*prev
= prev_active_insn (insn
);
8361 if (!prev
|| !(prev
= prev_active_insn (prev
))
8362 || ((NONJUMP_INSN_P (prev
)
8363 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8364 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8366 : CALL_ATTR (prev
, NON_SIBCALL
)))
8371 rtx_insn
*succ
= next_real_insn (insn
);
8373 /* One the ARC600, a write to an extension register must be separated
8375 if (succ
&& INSN_P (succ
))
8376 len
+= arc600_corereg_hazard (insn
, succ
);
8379 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8381 extract_constrain_insn_cached (insn
);
8386 /* Values for length_sensitive. */
8390 ARC_LS_25
, // 25 bit offset, B
8391 ARC_LS_21
, // 21 bit offset, Bcc
8392 ARC_LS_U13
,// 13 bit unsigned offset, LP
8393 ARC_LS_10
, // 10 bit offset, B_s, Beq_s, Bne_s
8394 ARC_LS_9
, // 9 bit offset, BRcc
8395 ARC_LS_8
, // 8 bit offset, BRcc_s
8396 ARC_LS_U7
, // 7 bit unsigned offset, LPcc
8397 ARC_LS_7
// 7 bit offset, Bcc_s
8400 /* While the infrastructure patch is waiting for review, duplicate the
8401 struct definitions, to allow this file to compile. */
8406 /* Cost as a branch / call target or call return address. */
8408 int fallthrough_cost
;
8411 /* 0 for not length sensitive, 1 for largest offset range,
8412 * 2 for next smaller etc. */
8413 unsigned length_sensitive
: 8;
8415 } insn_length_variant_t
;
8417 typedef struct insn_length_parameters_s
8422 int (*get_variants
) (rtx_insn
*, int, bool, bool, insn_length_variant_t
*);
8423 } insn_length_parameters_t
;
8426 arc_insn_length_parameters (insn_length_parameters_t
*ilp
) ATTRIBUTE_UNUSED
;
8430 arc_get_insn_variants (rtx_insn
*insn
, int len
, bool, bool target_p
,
8431 insn_length_variant_t
*ilv
)
8433 if (!NONDEBUG_INSN_P (insn
))
8435 enum attr_type type
;
8436 /* shorten_branches doesn't take optimize_size into account yet for the
8437 get_variants mechanism, so turn this off for now. */
8440 if (rtx_sequence
*pat
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
8442 /* The interaction of a short delay slot insn with a short branch is
8443 too weird for shorten_branches to piece together, so describe the
8446 if (TARGET_UPSIZE_DBR
8447 && get_attr_length (pat
->insn (1)) <= 2
8448 && (((type
= get_attr_type (inner
= pat
->insn (0)))
8449 == TYPE_UNCOND_BRANCH
)
8450 || type
== TYPE_BRANCH
)
8451 && get_attr_delay_slot_filled (inner
) == DELAY_SLOT_FILLED_YES
)
8454 = arc_get_insn_variants (inner
, get_attr_length (inner
), true,
8456 /* The short variant gets split into a higher-cost aligned
8457 and a lower cost unaligned variant. */
8458 gcc_assert (n_variants
);
8459 gcc_assert (ilv
[1].length_sensitive
== ARC_LS_7
8460 || ilv
[1].length_sensitive
== ARC_LS_10
);
8461 gcc_assert (ilv
[1].align_set
== 3);
8463 ilv
[0].align_set
= 1;
8464 ilv
[0].branch_cost
+= 1;
8465 ilv
[1].align_set
= 2;
8467 for (int i
= 0; i
< n_variants
; i
++)
8469 /* In case an instruction with aligned size is wanted, and
8470 the short variants are unavailable / too expensive, add
8471 versions of long branch + long delay slot. */
8472 for (int i
= 2, end
= n_variants
; i
< end
; i
++, n_variants
++)
8474 ilv
[n_variants
] = ilv
[i
];
8475 ilv
[n_variants
].length
+= 2;
8481 insn_length_variant_t
*first_ilv
= ilv
;
8482 type
= get_attr_type (insn
);
8484 = (get_attr_delay_slot_filled (insn
) == DELAY_SLOT_FILLED_YES
);
8485 int branch_align_cost
= delay_filled
? 0 : 1;
8486 int branch_unalign_cost
= delay_filled
? 0 : TARGET_UNALIGN_BRANCH
? 0 : 1;
8487 /* If the previous instruction is an sfunc call, this insn is always
8488 a target, even though the middle-end is unaware of this. */
8489 bool force_target
= false;
8490 rtx_insn
*prev
= prev_active_insn (insn
);
8491 if (prev
&& arc_next_active_insn (prev
, 0) == insn
8492 && ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8493 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8495 : (CALL_ATTR (prev
, NON_SIBCALL
)
8496 && NEXT_INSN (PREV_INSN (prev
)) == prev
)))
8497 force_target
= true;
8502 /* Short BRCC only comes in no-delay-slot version, and without limm */
8507 ilv
->branch_cost
= 1;
8508 ilv
->enabled
= (len
== 2);
8509 ilv
->length_sensitive
= ARC_LS_8
;
8513 case TYPE_BRCC_NO_DELAY_SLOT
:
8514 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8515 (delay slot) scheduling purposes, but they are longer. */
8516 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8517 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 1)) == SET
)
8519 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8520 ilv
->length
= ((type
== TYPE_BRCC
) ? 4 : 8);
8522 ilv
->branch_cost
= branch_align_cost
;
8523 ilv
->enabled
= (len
<= ilv
->length
);
8524 ilv
->length_sensitive
= ARC_LS_9
;
8525 if ((target_p
|| force_target
)
8526 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8532 ilv
->target_cost
= 1;
8533 ilv
->branch_cost
= branch_unalign_cost
;
8538 op
= XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 0);
8541 if (GET_CODE (op0
) == ZERO_EXTRACT
8542 && satisfies_constraint_L (XEXP (op0
, 2)))
8543 op0
= XEXP (op0
, 0);
8544 if (satisfies_constraint_Rcq (op0
))
8546 ilv
->length
= ((type
== TYPE_BRCC
) ? 6 : 10);
8548 ilv
->branch_cost
= 1 + branch_align_cost
;
8549 ilv
->fallthrough_cost
= 1;
8550 ilv
->enabled
= true;
8551 ilv
->length_sensitive
= ARC_LS_21
;
8552 if (!delay_filled
&& TARGET_UNALIGN_BRANCH
)
8558 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8562 ilv
->length
= ((type
== TYPE_BRCC
) ? 8 : 12);
8564 ilv
->branch_cost
= 1 + branch_align_cost
;
8565 ilv
->fallthrough_cost
= 1;
8566 ilv
->enabled
= true;
8567 ilv
->length_sensitive
= ARC_LS_21
;
8568 if ((target_p
|| force_target
)
8569 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8575 ilv
->target_cost
= 1;
8576 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8584 case TYPE_CALL_NO_DELAY_SLOT
:
8589 ilv
->length_sensitive
8590 = GET_CODE (PATTERN (insn
)) == COND_EXEC
? ARC_LS_21
: ARC_LS_25
;
8593 ilv
->fallthrough_cost
= branch_align_cost
;
8594 ilv
->enabled
= true;
8595 if ((target_p
|| force_target
)
8596 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8602 ilv
->target_cost
= 1;
8603 ilv
->fallthrough_cost
= branch_unalign_cost
;
8607 case TYPE_UNCOND_BRANCH
:
8608 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8609 but that makes no difference at the moment. */
8610 ilv
->length_sensitive
= ARC_LS_7
;
8611 ilv
[1].length_sensitive
= ARC_LS_25
;
8614 ilv
->length_sensitive
= ARC_LS_10
;
8615 ilv
[1].length_sensitive
= ARC_LS_21
;
8619 ilv
->branch_cost
= branch_align_cost
;
8620 ilv
->enabled
= (len
== ilv
->length
);
8624 ilv
->branch_cost
= branch_align_cost
;
8625 ilv
->enabled
= true;
8626 if ((target_p
|| force_target
)
8627 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8633 ilv
->target_cost
= 1;
8634 ilv
->branch_cost
= branch_unalign_cost
;
8641 /* For every short insn, there is generally also a long insn.
8642 trap_s is an exception. */
8643 if ((len
& 2) == 0 || recog_memoized (insn
) == CODE_FOR_trap_s
)
8650 ilv
->length
= len
+ 2;
8652 if (target_p
|| force_target
)
8658 ilv
->target_cost
= 1;
8662 /* If the previous instruction is an sfunc call, this insn is always
8663 a target, even though the middle-end is unaware of this.
8664 Therefore, if we have a call predecessor, transfer the target cost
8665 to the fallthrough and branch costs. */
8668 for (insn_length_variant_t
*p
= first_ilv
; p
< ilv
; p
++)
8670 p
->fallthrough_cost
+= p
->target_cost
;
8671 p
->branch_cost
+= p
->target_cost
;
8676 return ilv
- first_ilv
;
8680 arc_insn_length_parameters (insn_length_parameters_t
*ilp
)
8682 ilp
->align_unit_log
= 1;
8683 ilp
->align_base_log
= 1;
8684 ilp
->max_variants
= 7;
8685 ilp
->get_variants
= arc_get_insn_variants
;
8688 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8689 CC field of *STATEP. */
8692 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8694 rtx cond
= statep
->cond
;
8695 int raw_cc
= get_arc_condition_code (cond
);
8697 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8699 if (statep
->cc
== raw_cc
)
8700 return copy_rtx (cond
);
8702 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8704 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8705 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8706 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8707 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8709 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8710 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8713 /* Return version of PAT conditionalized with COND, which is part of INSN.
8714 ANNULLED indicates if INSN is an annulled delay-slot insn.
8715 Register further changes if necessary. */
8717 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8719 /* For commutative operators, we generally prefer to have
8720 the first source match the destination. */
8721 if (GET_CODE (pat
) == SET
)
8723 rtx src
= SET_SRC (pat
);
8725 if (COMMUTATIVE_P (src
))
8727 rtx src0
= XEXP (src
, 0);
8728 rtx src1
= XEXP (src
, 1);
8729 rtx dst
= SET_DEST (pat
);
8731 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8732 /* Leave add_n alone - the canonical form is to
8733 have the complex summand first. */
8735 pat
= gen_rtx_SET (dst
,
8736 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8741 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8742 what to do with COND_EXEC. */
8743 if (RTX_FRAME_RELATED_P (insn
))
8745 /* If this is the delay slot insn of an anulled branch,
8746 dwarf2out.c:scan_trace understands the anulling semantics
8747 without the COND_EXEC. */
8748 gcc_assert (annulled
);
8749 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8751 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8753 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8757 /* Use the ccfsm machinery to do if conversion. */
8762 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8763 basic_block merge_bb
= 0;
8765 memset (statep
, 0, sizeof *statep
);
8766 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8768 arc_ccfsm_advance (insn
, statep
);
8770 switch (statep
->state
)
8778 /* Deleted branch. */
8779 gcc_assert (!merge_bb
);
8780 merge_bb
= BLOCK_FOR_INSN (insn
);
8782 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn
))));
8783 arc_ccfsm_post_advance (insn
, statep
);
8784 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8785 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8788 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8789 rtx pat
= PATTERN (slot
);
8790 if (INSN_ANNULLED_BRANCH_P (insn
))
8793 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8794 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8796 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8798 PUT_CODE (slot
, NOTE
);
8799 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
8800 if (merge_bb
&& succ_bb
)
8801 merge_blocks (merge_bb
, succ_bb
);
8803 else if (merge_bb
&& succ_bb
)
8805 set_insn_deleted (insn
);
8806 merge_blocks (merge_bb
, succ_bb
);
8810 PUT_CODE (insn
, NOTE
);
8811 NOTE_KIND (insn
) = NOTE_INSN_DELETED
;
8817 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
8819 arc_ccfsm_post_advance (insn
, statep
);
8820 basic_block succ_bb
= BLOCK_FOR_INSN (insn
);
8821 if (merge_bb
&& succ_bb
)
8822 merge_blocks (merge_bb
, succ_bb
);
8823 else if (--LABEL_NUSES (insn
) == 0)
8825 const char *name
= LABEL_NAME (insn
);
8826 PUT_CODE (insn
, NOTE
);
8827 NOTE_KIND (insn
) = NOTE_INSN_DELETED_LABEL
;
8828 NOTE_DELETED_LABEL_NAME (insn
) = name
;
8835 if (!NONDEBUG_INSN_P (insn
))
8838 /* Conditionalized insn. */
8840 rtx_insn
*prev
, *pprev
;
8841 rtx
*patp
, pat
, cond
;
8842 bool annulled
; annulled
= false;
8844 /* If this is a delay slot insn in a non-annulled branch,
8845 don't conditionalize it. N.B., this should be fine for
8846 conditional return too. However, don't do this for
8847 unconditional branches, as these would be encountered when
8848 processing an 'else' part. */
8849 prev
= PREV_INSN (insn
);
8850 pprev
= PREV_INSN (prev
);
8851 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
8852 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
8854 if (!INSN_ANNULLED_BRANCH_P (prev
))
8859 patp
= &PATTERN (insn
);
8861 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
8862 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
8864 /* ??? don't conditionalize if all side effects are dead
8865 in the not-execute case. */
8867 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
8869 else if (simplejump_p (insn
))
8871 patp
= &SET_SRC (pat
);
8872 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
8874 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
8876 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
8877 pat
= gen_rtx_SET (pc_rtx
, pat
);
8881 validate_change (insn
, patp
, pat
, 1);
8882 if (!apply_change_group ())
8886 rtx_insn
*next
= next_nonnote_insn (insn
);
8887 if (GET_CODE (next
) == BARRIER
)
8889 if (statep
->state
== 3)
8896 arc_ccfsm_post_advance (insn
, statep
);
8901 /* Find annulled delay insns and convert them to use the appropriate predicate.
8902 This allows branch shortening to size up these insns properly. */
8905 arc_predicate_delay_insns (void)
8907 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8909 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
8912 if (!NONJUMP_INSN_P (insn
)
8913 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
8915 jump
= XVECEXP (pat
, 0, 0);
8916 dlay
= XVECEXP (pat
, 0, 1);
8917 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
8919 /* If the branch insn does the annulling, leave the delay insn alone. */
8920 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
8922 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8923 on the other path. */
8924 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
8925 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
8926 src
= SET_SRC (PATTERN (jump
));
8927 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
8928 cond
= XEXP (src
, 0);
8929 if (XEXP (src
, 2) == pc_rtx
)
8931 else if (XEXP (src
, 1) == pc_rtx
)
8935 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
8937 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8938 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8939 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8940 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8942 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8943 copy_rtx (XEXP (cond
, 0)),
8944 copy_rtx (XEXP (cond
, 1)));
8947 cond
= copy_rtx (cond
);
8948 patp
= &PATTERN (dlay
);
8950 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
8951 validate_change (dlay
, patp
, pat
, 1);
8952 if (!apply_change_group ())
8958 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
8959 (other than of a forward brcc), it creates a hazard when there is a read
8960 of the same register at the branch target. We can't know what is at the
8961 branch target of calls, and for branches, we don't really know before the
8962 end of delay slot scheduling, either. Not only can individual instruction
8963 be hoisted out into a delay slot, a basic block can also be emptied this
8964 way, and branch and/or fall through targets be redirected. Hence we don't
8965 want such writes in a delay slot. */
8967 /* Return nonzreo iff INSN writes to an extension core register. */
8970 arc_write_ext_corereg (rtx insn
)
8972 subrtx_iterator::array_type array
;
8973 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
8975 const_rtx x
= *iter
;
8976 switch (GET_CODE (x
))
8978 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8981 /* This is also fine for PRE/POST_MODIFY, because they
8985 const_rtx dest
= XEXP (x
, 0);
8986 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
8992 /* This is like the hook, but returns NULL when it can't / won't generate
8993 a legitimate address. */
8996 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9001 if (flag_pic
&& SYMBOLIC_CONST (x
))
9002 (x
) = arc_legitimize_pic_address (x
, 0);
9004 if (GET_CODE (addr
) == CONST
)
9005 addr
= XEXP (addr
, 0);
9006 if (GET_CODE (addr
) == PLUS
9007 && CONST_INT_P (XEXP (addr
, 1))
9008 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9009 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9010 || (REG_P (XEXP (addr
, 0))
9011 && (INTVAL (XEXP (addr
, 1)) & 252))))
9013 HOST_WIDE_INT offs
, upper
;
9014 int size
= GET_MODE_SIZE (mode
);
9016 offs
= INTVAL (XEXP (addr
, 1));
9017 upper
= (offs
+ 256 * size
) & ~511 * size
;
9018 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9019 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9020 if (GET_CODE (x
) == CONST
)
9021 inner
= gen_rtx_CONST (Pmode
, inner
);
9023 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9026 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9027 x
= force_reg (Pmode
, x
);
9028 if (memory_address_p ((machine_mode
) mode
, x
))
9034 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9036 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9038 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9040 return arc_legitimize_tls_address (orig_x
, model
);
9043 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9051 arc_delegitimize_address_0 (rtx x
)
9055 if (GET_CODE (x
) == CONST
&& GET_CODE (u
= XEXP (x
, 0)) == UNSPEC
)
9057 if (XINT (u
, 1) == ARC_UNSPEC_GOT
9058 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
)
9059 return XVECEXP (u
, 0, 0);
9061 else if (GET_CODE (x
) == CONST
&& GET_CODE (p
= XEXP (x
, 0)) == PLUS
9062 && GET_CODE (u
= XEXP (p
, 0)) == UNSPEC
9063 && (XINT (u
, 1) == ARC_UNSPEC_GOT
9064 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
))
9065 return gen_rtx_CONST
9067 gen_rtx_PLUS (GET_MODE (p
), XVECEXP (u
, 0, 0), XEXP (p
, 1)));
9068 else if (GET_CODE (x
) == PLUS
9069 && ((REG_P (gp
= XEXP (x
, 0))
9070 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9071 || (GET_CODE (gp
) == CONST
9072 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9073 && XINT (u
, 1) == ARC_UNSPEC_GOT
9074 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9075 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9076 && GET_CODE (XEXP (x
, 1)) == CONST
9077 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9078 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9079 return XVECEXP (u
, 0, 0);
9080 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 0)) == PLUS
9081 && ((REG_P (gp
= XEXP (XEXP (x
, 0), 1))
9082 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9083 || (GET_CODE (gp
) == CONST
9084 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9085 && XINT (u
, 1) == ARC_UNSPEC_GOT
9086 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9087 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9088 && GET_CODE (XEXP (x
, 1)) == CONST
9089 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9090 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9091 return gen_rtx_PLUS (GET_MODE (x
), XEXP (XEXP (x
, 0), 0),
9093 else if (GET_CODE (x
) == PLUS
9094 && (u
= arc_delegitimize_address_0 (XEXP (x
, 1))))
9095 return gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0), u
);
9100 arc_delegitimize_address (rtx x
)
9102 rtx orig_x
= x
= delegitimize_mem_from_attrs (x
);
9103 if (GET_CODE (x
) == MEM
)
9105 x
= arc_delegitimize_address_0 (x
);
9109 x
= replace_equiv_address_nv (orig_x
, x
);
9115 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9116 differ from the hardware register number in order to allow the generic
9117 code to correctly split the concatenation of acc1 and acc2. */
9122 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9125 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9126 differ from the hardware register number in order to allow the generic
9127 code to correctly split the concatenation of acc1 and acc2. */
9132 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9135 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9136 differ from the hardware register number in order to allow the generic
9137 code to correctly split the concatenation of mhi and mlo. */
9142 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9145 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9146 differ from the hardware register number in order to allow the generic
9147 code to correctly split the concatenation of mhi and mlo. */
9152 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9155 /* FIXME: a parameter should be added, and code added to final.c,
9156 to reproduce this functionality in shorten_branches. */
9158 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9159 a previous instruction. */
9161 arc_unalign_branch_p (rtx branch
)
9165 if (!TARGET_UNALIGN_BRANCH
)
9167 /* Do not do this if we have a filled delay slot. */
9168 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9169 && !NEXT_INSN (branch
)->deleted ())
9171 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9173 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9174 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9178 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9179 are three reasons why we need to consider branches to be length 6:
9180 - annull-false delay slot insns are implemented using conditional execution,
9181 thus preventing short insn formation where used.
9182 - for ARC600: annul-true delay slot insns are implemented where possible
9183 using conditional execution, preventing short insn formation where used.
9184 - for ARC700: likely or somewhat likely taken branches are made long and
9185 unaligned if possible to avoid branch penalty. */
9188 arc_branch_size_unknown_p (void)
9190 return !optimize_size
&& arc_reorg_in_progress
;
9193 /* We are about to output a return insn. Add padding if necessary to avoid
9194 a mispredict. A return could happen immediately after the function
9195 start, but after a call we know that there will be at least a blink
9199 arc_pad_return (void)
9201 rtx_insn
*insn
= current_output_insn
;
9202 rtx_insn
*prev
= prev_active_insn (insn
);
9207 fputs ("\tnop_s\n", asm_out_file
);
9208 cfun
->machine
->unalign
^= 2;
9211 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9212 because after a call, we'd have to restore blink first. */
9213 else if (GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9217 want_long
= (get_attr_length (prev
) == 2);
9218 prev
= prev_active_insn (prev
);
9221 || ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9222 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9224 : CALL_ATTR (prev
, NON_SIBCALL
)))
9227 cfun
->machine
->size_reason
9228 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9229 else if (TARGET_UNALIGN_BRANCH
&& cfun
->machine
->unalign
)
9231 cfun
->machine
->size_reason
9232 = "Long unaligned jump avoids non-delay slot penalty";
9235 /* Disgorge delay insn, if there is any, and it may be moved. */
9237 /* ??? Annulled would be OK if we can and do conditionalize
9238 the delay slot insn accordingly. */
9239 && !INSN_ANNULLED_BRANCH_P (insn
)
9240 && (get_attr_cond (insn
) != COND_USE
9241 || !reg_set_p (gen_rtx_REG (CCmode
, CC_REG
),
9242 XVECEXP (final_sequence
, 0, 1))))
9244 prev
= as_a
<rtx_insn
*> (XVECEXP (final_sequence
, 0, 1));
9245 gcc_assert (!prev_real_insn (insn
)
9246 || !arc_hazard (prev_real_insn (insn
), prev
));
9247 cfun
->machine
->force_short_suffix
= !want_long
;
9248 rtx save_pred
= current_insn_predicate
;
9249 final_scan_insn (prev
, asm_out_file
, optimize
, 1, NULL
);
9250 cfun
->machine
->force_short_suffix
= -1;
9251 prev
->set_deleted ();
9252 current_output_insn
= insn
;
9253 current_insn_predicate
= save_pred
;
9256 fputs ("\tnop\n", asm_out_file
);
9259 fputs ("\tnop_s\n", asm_out_file
);
9260 cfun
->machine
->unalign
^= 2;
9266 /* The usual; we set up our machine_function data. */
9268 static struct machine_function
*
9269 arc_init_machine_status (void)
9271 struct machine_function
*machine
;
9272 machine
= ggc_cleared_alloc
<machine_function
> ();
9273 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9274 machine
->force_short_suffix
= -1;
9279 /* Implements INIT_EXPANDERS. We just set up to call the above
9283 arc_init_expanders (void)
9285 init_machine_status
= arc_init_machine_status
;
9288 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9289 indicates a number of elements to ignore - that allows to have a
9290 sibcall pattern that starts with (return). LOAD_P is zero for store
9291 multiple (for prologues), and one for load multiples (for epilogues),
9292 and two for load multiples where no final clobber of blink is required.
9293 We also skip the first load / store element since this is supposed to
9294 be checked in the instruction pattern. */
9297 arc_check_millicode (rtx op
, int offset
, int load_p
)
9299 int len
= XVECLEN (op
, 0) - offset
;
9304 if (len
< 2 || len
> 13)
9310 rtx elt
= XVECEXP (op
, 0, --len
);
9312 if (GET_CODE (elt
) != CLOBBER
9313 || !REG_P (XEXP (elt
, 0))
9314 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9315 || len
< 3 || len
> 13)
9318 for (i
= 1; i
< len
; i
++)
9320 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9323 if (GET_CODE (elt
) != SET
)
9325 mem
= XEXP (elt
, load_p
);
9326 reg
= XEXP (elt
, 1-load_p
);
9327 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9329 addr
= XEXP (mem
, 0);
9330 if (GET_CODE (addr
) != PLUS
9331 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9332 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9338 /* Accessor functions for cfun->machine->unalign. */
9341 arc_get_unalign (void)
9343 return cfun
->machine
->unalign
;
9347 arc_clear_unalign (void)
9350 cfun
->machine
->unalign
= 0;
9354 arc_toggle_unalign (void)
9356 cfun
->machine
->unalign
^= 2;
9359 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9360 constant in operand 2, but which would require a LIMM because of
9362 operands 3 and 4 are new SET_SRCs for operands 0. */
9365 split_addsi (rtx
*operands
)
9367 int val
= INTVAL (operands
[2]);
9369 /* Try for two short insns first. Lengths being equal, we prefer
9370 expansions with shorter register lifetimes. */
9371 if (val
> 127 && val
<= 255
9372 && satisfies_constraint_Rcq (operands
[0]))
9374 operands
[3] = operands
[2];
9375 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9379 operands
[3] = operands
[1];
9380 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9384 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9385 constant in operand 1, but which would require a LIMM because of
9387 operands 3 and 4 are new SET_SRCs for operands 0. */
9390 split_subsi (rtx
*operands
)
9392 int val
= INTVAL (operands
[1]);
9394 /* Try for two short insns first. Lengths being equal, we prefer
9395 expansions with shorter register lifetimes. */
9396 if (satisfies_constraint_Rcq (operands
[0])
9397 && satisfies_constraint_Rcq (operands
[2]))
9399 if (val
>= -31 && val
<= 127)
9401 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9402 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9405 else if (val
>= 0 && val
< 255)
9407 operands
[3] = operands
[1];
9408 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9412 /* If the destination is not an ARCompact16 register, we might
9413 still have a chance to make a short insn if the source is;
9414 we need to start with a reg-reg move for this. */
9415 operands
[3] = operands
[2];
9416 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9419 /* Handle DOUBLE_REGS uses.
9420 Operand 0: destination register
9421 Operand 1: source register */
9424 arc_process_double_reg_moves (rtx
*operands
)
9426 rtx dest
= operands
[0];
9427 rtx src
= operands
[1];
9429 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9430 enum usesDxState state
= none
;
9432 if (refers_to_regno_p (40, 44, src
, 0))
9434 if (refers_to_regno_p (40, 44, dest
, 0))
9436 /* Via arc_register_move_cost, we should never see D,D moves. */
9437 gcc_assert (state
== none
);
9446 /* Without the LR insn, we need to split this into a
9447 sequence of insns which will use the DEXCLx and DADDHxy
9448 insns to be able to read the Dx register in question. */
9449 if (TARGET_DPFP_DISABLE_LRSR
)
9451 /* gen *movdf_insn_nolrsr */
9452 rtx set
= gen_rtx_SET (dest
, src
);
9453 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9454 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9458 /* When we have 'mov D, r' or 'mov D, D' then get the target
9459 register pair for use with LR insn. */
9460 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9461 TARGET_BIG_ENDIAN
? 0 : 4);
9462 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9463 TARGET_BIG_ENDIAN
? 4 : 0);
9465 /* Produce the two LR insns to get the high and low parts. */
9466 emit_insn (gen_rtx_SET (destHigh
,
9467 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9469 VUNSPEC_ARC_LR_HIGH
)));
9470 emit_insn (gen_rtx_SET (destLow
,
9471 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9476 else if (state
== destDx
)
9478 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9479 LR insn get the target register pair. */
9480 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9481 TARGET_BIG_ENDIAN
? 0 : 4);
9482 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9483 TARGET_BIG_ENDIAN
? 4 : 0);
9485 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9493 /* operands 0..1 are the operands of a 64 bit move instruction.
9494 split it into two moves with operands 2/3 and 4/5. */
9497 arc_split_move (rtx
*operands
)
9499 machine_mode mode
= GET_MODE (operands
[0]);
9506 if (arc_process_double_reg_moves (operands
))
9511 && ((memory_operand (operands
[0], mode
)
9512 && even_register_operand (operands
[1], mode
))
9513 || (memory_operand (operands
[1], mode
)
9514 && even_register_operand (operands
[0], mode
))))
9516 emit_move_insn (operands
[0], operands
[1]);
9520 if (TARGET_PLUS_QMACW
9521 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9523 HOST_WIDE_INT intval0
, intval1
;
9524 if (GET_MODE (operands
[1]) == V2SImode
)
9526 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9527 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9531 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9532 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9533 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9534 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9536 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9537 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9538 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9539 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9540 emit_move_insn (xop
[0], xop
[2]);
9541 emit_move_insn (xop
[3], xop
[1]);
9545 for (i
= 0; i
< 2; i
++)
9547 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9549 rtx addr
= XEXP (operands
[i
], 0);
9553 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9554 switch (GET_CODE (addr
))
9556 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9557 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9558 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9562 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9563 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9564 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9573 xop
[0+i
] = adjust_automodify_address_nv
9574 (operands
[i
], SImode
,
9575 gen_rtx_fmt_ee (code
, Pmode
, r
,
9576 gen_rtx_PLUS (Pmode
, r
, o
)),
9578 xop
[2+i
] = adjust_automodify_address_nv
9579 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9583 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9584 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9587 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9590 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9593 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9594 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9598 /* Select between the instruction output templates s_tmpl (for short INSNs)
9599 and l_tmpl (for long INSNs). */
9602 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9604 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9606 extract_constrain_insn_cached (insn
);
9607 return is_short
? s_tmpl
: l_tmpl
;
9610 /* Searches X for any reference to REGNO, returning the rtx of the
9611 reference found if any. Otherwise, returns NULL_RTX. */
9614 arc_regno_use_in (unsigned int regno
, rtx x
)
9620 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9623 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9624 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9628 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9631 else if (fmt
[i
] == 'E')
9632 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9633 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9640 /* Return the integer value of the "type" attribute for INSN, or -1 if
9641 INSN can't have attributes. */
9644 arc_attr_type (rtx_insn
*insn
)
9646 if (NONJUMP_INSN_P (insn
)
9647 ? (GET_CODE (PATTERN (insn
)) == USE
9648 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9650 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9651 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9654 return get_attr_type (insn
);
9657 /* Return true if insn sets the condition codes. */
9660 arc_sets_cc_p (rtx_insn
*insn
)
9662 if (NONJUMP_INSN_P (insn
))
9663 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9664 insn
= seq
->insn (seq
->len () - 1);
9665 return arc_attr_type (insn
) == TYPE_COMPARE
;
9668 /* Return true if INSN is an instruction with a delay slot we may want
9672 arc_need_delay (rtx_insn
*insn
)
9676 if (!flag_delayed_branch
)
9678 /* The return at the end of a function needs a delay slot. */
9679 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9680 && (!(next
= next_active_insn (insn
))
9681 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9682 && arc_attr_type (next
) == TYPE_RETURN
))
9683 && (!TARGET_PAD_RETURN
9684 || (prev_active_insn (insn
)
9685 && prev_active_insn (prev_active_insn (insn
))
9686 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9688 if (NONJUMP_INSN_P (insn
)
9689 ? (GET_CODE (PATTERN (insn
)) == USE
9690 || GET_CODE (PATTERN (insn
)) == CLOBBER
9691 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9693 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9694 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9697 return num_delay_slots (insn
) != 0;
9700 /* Return true if the scheduling pass(es) has/have already run,
9701 i.e. where possible, we should try to mitigate high latencies
9702 by different instruction selection. */
9705 arc_scheduling_not_expected (void)
9707 return cfun
->machine
->arc_reorg_started
;
9710 /* Oddly enough, sometimes we get a zero overhead loop that branch
9711 shortening doesn't think is a loop - observed with compile/pr24883.c
9712 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9713 alignment visible for branch shortening (we actually align the loop
9714 insn before it, but that is equivalent since the loop insn is 4 byte
9718 arc_label_align (rtx_insn
*label
)
9720 int loop_align
= LOOP_ALIGN (LABEL
);
9722 if (loop_align
> align_labels_log
)
9724 rtx_insn
*prev
= prev_nonnote_insn (label
);
9726 if (prev
&& NONJUMP_INSN_P (prev
)
9727 && GET_CODE (PATTERN (prev
)) == PARALLEL
9728 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
)
9731 /* Code has a minimum p2 alignment of 1, which we must restore after an
9733 if (align_labels_log
< 1)
9735 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9736 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9739 return align_labels_log
;
9742 /* Return true if LABEL is in executable code. */
9745 arc_text_label (rtx_insn
*label
)
9749 /* ??? We use deleted labels like they were still there, see
9750 gcc.c-torture/compile/20000326-2.c . */
9751 gcc_assert (GET_CODE (label
) == CODE_LABEL
9752 || (GET_CODE (label
) == NOTE
9753 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9754 next
= next_nonnote_insn (label
);
9756 return (!JUMP_TABLE_DATA_P (next
)
9757 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9758 else if (!PREV_INSN (label
))
9759 /* ??? sometimes text labels get inserted very late, see
9760 gcc.dg/torture/stackalign/comp-goto-1.c */
9765 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9766 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9767 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9768 to redirect two breqs. */
9771 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9773 /* ??? get_attr_type is declared to take an rtx. */
9774 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9777 if (CROSSING_JUMP_P (followee
))
9778 switch (get_attr_type (u
.r
))
9781 case TYPE_BRCC_NO_DELAY_SLOT
:
9789 /* Return the register number of the register holding the return address
9790 for a function of type TYPE. */
9793 arc_return_address_register (unsigned int fn_type
)
9797 if (ARC_INTERRUPT_P (fn_type
))
9799 if (((fn_type
& ARC_FUNCTION_ILINK1
) | ARC_FUNCTION_FIRQ
) != 0)
9800 regno
= ILINK1_REGNUM
;
9801 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
9802 regno
= ILINK2_REGNUM
;
9806 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
9807 regno
= RETURN_ADDR_REGNUM
;
9809 gcc_assert (regno
!= 0);
9813 /* Implement EPILOGUE_USES.
9814 Return true if REGNO should be added to the deemed uses of the epilogue.
9816 We have to make sure all the register restore instructions are
9817 known to be live in interrupt functions, plus the blink register if
9818 it is clobbered by the isr. */
9821 arc_epilogue_uses (int regno
)
9823 unsigned int fn_type
;
9825 if (regno
== arc_tp_regno
)
9828 fn_type
= arc_compute_function_type (cfun
);
9829 if (reload_completed
)
9831 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9833 if (!fixed_regs
[regno
])
9835 return ((regno
== arc_return_address_register (fn_type
))
9836 || (regno
== RETURN_ADDR_REGNUM
));
9839 return regno
== RETURN_ADDR_REGNUM
;
9842 return regno
== arc_return_address_register (fn_type
);
9845 /* Helper for EH_USES macro. */
9848 arc_eh_uses (int regno
)
9850 if (regno
== arc_tp_regno
)
9855 #ifndef TARGET_NO_LRA
9856 #define TARGET_NO_LRA !TARGET_LRA
9862 return !TARGET_NO_LRA
;
9865 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9866 Rcq registers, because some insn are shorter with them. OTOH we already
9867 have separate alternatives for this purpose, and other insns don't
9868 mind, so maybe we should rather prefer the other registers?
9869 We need more data, and we can only get that if we allow people to
9872 arc_register_priority (int r
)
9874 switch (arc_lra_priority_tag
)
9876 case ARC_LRA_PRIORITY_NONE
:
9878 case ARC_LRA_PRIORITY_NONCOMPACT
:
9879 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
9880 case ARC_LRA_PRIORITY_COMPACT
:
9881 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
9888 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
9890 return GENERAL_REGS
;
9894 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
9898 enum reload_type type
= (enum reload_type
) itype
;
9900 if (GET_CODE (x
) == PLUS
9901 && CONST_INT_P (XEXP (x
, 1))
9902 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
9903 || (REG_P (XEXP (x
, 0))
9904 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
9906 int scale
= GET_MODE_SIZE (mode
);
9908 rtx index_rtx
= XEXP (x
, 1);
9909 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
9914 if ((scale
-1) & offset
)
9918 = ((offset
+ (256 << shift
))
9919 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
9920 /* Sometimes the normal form does not suit DImode. We
9921 could avoid that by using smaller ranges, but that
9922 would give less optimized code when SImode is
9924 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
9929 regno
= REGNO (reg
);
9930 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
9932 if (reg_equiv_constant (regno
))
9934 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
9936 if (GET_CODE (sum2
) == PLUS
)
9937 sum2
= gen_rtx_CONST (Pmode
, sum2
);
9939 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
9940 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
9941 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
9946 /* We must re-recognize what we created before. */
9947 else if (GET_CODE (x
) == PLUS
9948 && GET_CODE (XEXP (x
, 0)) == PLUS
9949 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
9950 && REG_P (XEXP (XEXP (x
, 0), 0))
9951 && CONST_INT_P (XEXP (x
, 1)))
9953 /* Because this address is so complex, we know it must have
9954 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9955 it is already unshared, and needs no further unsharing. */
9956 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
9957 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
9963 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9966 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
9968 enum by_pieces_operation op
,
9971 /* Let the movmem expander handle small block moves. */
9972 if (op
== MOVE_BY_PIECES
)
9975 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
9978 /* Emit a (pre) memory barrier around an atomic sequence according to
9982 arc_pre_atomic_barrier (enum memmodel model
)
9984 if (need_atomic_barrier_p (model
, true))
9985 emit_insn (gen_memory_barrier ());
9988 /* Emit a (post) memory barrier around an atomic sequence according to
9992 arc_post_atomic_barrier (enum memmodel model
)
9994 if (need_atomic_barrier_p (model
, false))
9995 emit_insn (gen_memory_barrier ());
9998 /* Expand a compare and swap pattern. */
10001 emit_unlikely_jump (rtx insn
)
10003 rtx_insn
*jump
= emit_jump_insn (insn
);
10004 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10007 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10008 32-bit compare and swap on the word containing the byte or
10009 half-word. The difference between a weak and a strong CAS is that
10010 the weak version may simply fail. The strong version relies on two
10011 loops, one checks if the SCOND op is succsfully or not, the other
10012 checks if the 32 bit accessed location which contains the 8 or 16
10013 bit datum is not changed by other thread. The first loop is
10014 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10015 loops is implemented by this routine. */
10018 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10019 rtx oldval
, rtx newval
, rtx weak
,
10020 rtx mod_s
, rtx mod_f
)
10022 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10023 rtx addr
= gen_reg_rtx (Pmode
);
10024 rtx off
= gen_reg_rtx (SImode
);
10025 rtx oldv
= gen_reg_rtx (SImode
);
10026 rtx newv
= gen_reg_rtx (SImode
);
10027 rtx oldvalue
= gen_reg_rtx (SImode
);
10028 rtx newvalue
= gen_reg_rtx (SImode
);
10029 rtx res
= gen_reg_rtx (SImode
);
10030 rtx resv
= gen_reg_rtx (SImode
);
10031 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10033 bool is_weak
= (weak
!= const0_rtx
);
10035 /* Truncate the address. */
10036 emit_insn (gen_rtx_SET (addr
,
10037 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10039 /* Compute the datum offset. */
10040 emit_insn (gen_rtx_SET (off
,
10041 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10042 if (TARGET_BIG_ENDIAN
)
10043 emit_insn (gen_rtx_SET (off
,
10044 gen_rtx_MINUS (SImode
,
10045 (GET_MODE (mem
) == QImode
) ?
10046 GEN_INT (3) : GEN_INT (2), off
)));
10048 /* Normal read from truncated address. */
10049 memsi
= gen_rtx_MEM (SImode
, addr
);
10050 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10051 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10053 val
= copy_to_reg (memsi
);
10055 /* Convert the offset in bits. */
10056 emit_insn (gen_rtx_SET (off
,
10057 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10059 /* Get the proper mask. */
10060 if (GET_MODE (mem
) == QImode
)
10061 mask
= force_reg (SImode
, GEN_INT (0xff));
10063 mask
= force_reg (SImode
, GEN_INT (0xffff));
10065 emit_insn (gen_rtx_SET (mask
,
10066 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10068 /* Prepare the old and new values. */
10069 emit_insn (gen_rtx_SET (val
,
10070 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10073 oldval
= gen_lowpart (SImode
, oldval
);
10074 emit_insn (gen_rtx_SET (oldv
,
10075 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10077 newval
= gen_lowpart_common (SImode
, newval
);
10078 emit_insn (gen_rtx_SET (newv
,
10079 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10081 emit_insn (gen_rtx_SET (oldv
,
10082 gen_rtx_AND (SImode
, oldv
, mask
)));
10084 emit_insn (gen_rtx_SET (newv
,
10085 gen_rtx_AND (SImode
, newv
, mask
)));
10089 end_label
= gen_label_rtx ();
10090 loop_label
= gen_label_rtx ();
10091 emit_label (loop_label
);
10094 /* Make the old and new values. */
10095 emit_insn (gen_rtx_SET (oldvalue
,
10096 gen_rtx_IOR (SImode
, oldv
, val
)));
10098 emit_insn (gen_rtx_SET (newvalue
,
10099 gen_rtx_IOR (SImode
, newv
, val
)));
10101 /* Try an 32bit atomic compare and swap. It clobbers the CC
10103 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10104 weak
, mod_s
, mod_f
));
10106 /* Regardless of the weakness of the operation, a proper boolean
10107 result needs to be provided. */
10108 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10109 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10110 emit_insn (gen_rtx_SET (bool_result
, x
));
10114 /* Check the results: if the atomic op is successfully the goto
10116 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10117 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10118 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10119 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10120 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10122 /* Wait for the right moment when the accessed 32-bit location
10124 emit_insn (gen_rtx_SET (resv
,
10125 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10127 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10128 cc
= gen_rtx_REG (mode
, CC_REG
);
10129 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10131 /* Set the new value of the 32 bit location, proper masked. */
10132 emit_insn (gen_rtx_SET (val
, resv
));
10134 /* Try again if location is unstable. Fall through if only
10135 scond op failed. */
10136 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10137 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10138 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10139 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10141 emit_label (end_label
);
10144 /* End: proper return the result for the given mode. */
10145 emit_insn (gen_rtx_SET (res
,
10146 gen_rtx_AND (SImode
, res
, mask
)));
10148 emit_insn (gen_rtx_SET (res
,
10149 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10151 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10154 /* Helper function used by "atomic_compare_and_swap" expand
10158 arc_expand_compare_and_swap (rtx operands
[])
10160 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10163 bval
= operands
[0];
10164 rval
= operands
[1];
10166 oldval
= operands
[3];
10167 newval
= operands
[4];
10168 is_weak
= operands
[5];
10169 mod_s
= operands
[6];
10170 mod_f
= operands
[7];
10171 mode
= GET_MODE (mem
);
10173 if (reg_overlap_mentioned_p (rval
, oldval
))
10174 oldval
= copy_to_reg (oldval
);
10176 if (mode
== SImode
)
10178 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10179 is_weak
, mod_s
, mod_f
));
10180 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10181 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10182 emit_insn (gen_rtx_SET (bval
, x
));
10186 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10187 is_weak
, mod_s
, mod_f
);
10191 /* Helper function used by the "atomic_compare_and_swapsi_1"
10195 arc_split_compare_and_swap (rtx operands
[])
10197 rtx rval
, mem
, oldval
, newval
;
10199 enum memmodel mod_s
, mod_f
;
10201 rtx label1
, label2
, x
, cond
;
10203 rval
= operands
[0];
10205 oldval
= operands
[2];
10206 newval
= operands
[3];
10207 is_weak
= (operands
[4] != const0_rtx
);
10208 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10209 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10210 mode
= GET_MODE (mem
);
10212 /* ARC atomic ops work only with 32-bit aligned memories. */
10213 gcc_assert (mode
== SImode
);
10215 arc_pre_atomic_barrier (mod_s
);
10220 label1
= gen_label_rtx ();
10221 emit_label (label1
);
10223 label2
= gen_label_rtx ();
10225 /* Load exclusive. */
10226 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10228 /* Check if it is oldval. */
10229 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10230 cond
= gen_rtx_REG (mode
, CC_REG
);
10231 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10233 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10234 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10235 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10236 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10238 /* Exclusively store new item. Store clobbers CC reg. */
10239 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10243 /* Check the result of the store. */
10244 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10245 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10246 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10247 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10248 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10251 if (mod_f
!= MEMMODEL_RELAXED
)
10252 emit_label (label2
);
10254 arc_post_atomic_barrier (mod_s
);
10256 if (mod_f
== MEMMODEL_RELAXED
)
10257 emit_label (label2
);
10260 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10261 to perform. MEM is the memory on which to operate. VAL is the second
10262 operand of the binary operator. BEFORE and AFTER are optional locations to
10263 return the value of MEM either before of after the operation. MODEL_RTX
10264 is a CONST_INT containing the memory model to use. */
10267 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10268 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10270 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10271 machine_mode mode
= GET_MODE (mem
);
10272 rtx label
, x
, cond
;
10273 rtx before
= orig_before
, after
= orig_after
;
10275 /* ARC atomic ops work only with 32-bit aligned memories. */
10276 gcc_assert (mode
== SImode
);
10278 arc_pre_atomic_barrier (model
);
10280 label
= gen_label_rtx ();
10281 emit_label (label
);
10282 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10284 if (before
== NULL_RTX
)
10285 before
= gen_reg_rtx (mode
);
10287 if (after
== NULL_RTX
)
10288 after
= gen_reg_rtx (mode
);
10290 /* Load exclusive. */
10291 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10296 x
= gen_rtx_AND (mode
, before
, val
);
10297 emit_insn (gen_rtx_SET (after
, x
));
10298 x
= gen_rtx_NOT (mode
, after
);
10299 emit_insn (gen_rtx_SET (after
, x
));
10303 if (CONST_INT_P (val
))
10305 val
= GEN_INT (-INTVAL (val
));
10311 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10312 emit_insn (gen_rtx_SET (after
, x
));
10316 /* Exclusively store new item. Store clobbers CC reg. */
10317 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10319 /* Check the result of the store. */
10320 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10321 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10322 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10324 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10326 arc_post_atomic_barrier (model
);
10329 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10332 arc_no_speculation_in_delay_slots_p ()
10337 /* Return a parallel of registers to represent where to find the
10338 register pieces if required, otherwise NULL_RTX. */
10341 arc_dwarf_register_span (rtx rtl
)
10343 machine_mode mode
= GET_MODE (rtl
);
10347 if (GET_MODE_SIZE (mode
) != 8)
10350 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10351 regno
= REGNO (rtl
);
10352 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10353 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10358 /* Return true if OP is an acceptable memory operand for ARCompact
10359 16-bit load instructions of MODE.
10361 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10362 non scaled instructions.
10364 SCALED: TRUE if address can be scaled. */
10367 compact_memory_operand_p (rtx op
, machine_mode mode
,
10368 bool av2short
, bool scaled
)
10370 rtx addr
, plus0
, plus1
;
10373 /* Eliminate non-memory operations. */
10374 if (GET_CODE (op
) != MEM
)
10377 /* .di instructions have no 16-bit form. */
10378 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10381 if (mode
== VOIDmode
)
10382 mode
= GET_MODE (op
);
10384 size
= GET_MODE_SIZE (mode
);
10386 /* dword operations really put out 2 instructions, so eliminate
10388 if (size
> UNITS_PER_WORD
)
10391 /* Decode the address now. */
10392 addr
= XEXP (op
, 0);
10393 switch (GET_CODE (addr
))
10396 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10397 || COMPACT_GP_REG_P (REGNO (addr
))
10398 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10400 plus0
= XEXP (addr
, 0);
10401 plus1
= XEXP (addr
, 1);
10403 if ((GET_CODE (plus0
) == REG
)
10404 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10405 || COMPACT_GP_REG_P (REGNO (plus0
)))
10406 && ((GET_CODE (plus1
) == REG
)
10407 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10408 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10413 if ((GET_CODE (plus0
) == REG
)
10414 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10415 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10416 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10417 && (GET_CODE (plus1
) == CONST_INT
))
10419 bool valid
= false;
10421 off
= INTVAL (plus1
);
10423 /* Negative offset is not supported in 16-bit load/store insns. */
10427 /* Only u5 immediates allowed in code density instructions. */
10435 /* This is an ldh_s.x instruction, check the u6
10437 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10441 /* Only u5 immediates allowed in 32bit access code
10442 density instructions. */
10443 if (REGNO (plus0
) <= 31)
10444 return ((off
< 32) && (off
% 4 == 0));
10451 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10462 /* The 6-bit constant get shifted to fit the real
10463 5-bits field. Check also for the alignment. */
10464 return ((off
< 64) && (off
% 2 == 0));
10466 return ((off
< 128) && (off
% 4 == 0));
10473 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10474 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10475 || SP_REG_P (REGNO (plus0
)))
10478 off
= INTVAL (plus1
);
10479 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10482 if ((GET_CODE (plus0
) == MULT
)
10483 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10484 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10485 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10486 && (GET_CODE (plus1
) == REG
)
10487 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10488 || COMPACT_GP_REG_P (REGNO (plus1
))))
10492 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10493 for 16-bit load instructions. */
10498 struct gcc_target targetm
= TARGET_INITIALIZER
;
10500 #include "gt-arc.h"