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"
68 #include "hw-doloop.h"
70 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
71 static char arc_cpu_name
[10] = "";
72 static const char *arc_cpu_string
= arc_cpu_name
;
74 /* Maximum size of a loop. */
75 #define ARC_MAX_LOOP_LENGTH 4095
77 /* ??? Loads can handle any constant, stores can only handle small ones. */
78 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
79 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
80 (GET_CODE (X) == CONST_INT \
81 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
82 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
84 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
86 #define LEGITIMATE_SMALL_DATA_OFFSET_P(X) \
87 (GET_CODE (X) == CONST \
88 && GET_CODE (XEXP ((X), 0)) == PLUS \
89 && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \
90 && SYMBOL_REF_SMALL_P (XEXP (XEXP ((X), 0), 0)) \
91 && GET_CODE (XEXP(XEXP ((X), 0), 1)) == CONST_INT \
92 && INTVAL (XEXP (XEXP ((X), 0), 1)) <= g_switch_value)
94 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
95 (GET_CODE (X) == PLUS \
96 && REG_P (XEXP ((X), 0)) \
97 && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM \
98 && ((GET_CODE (XEXP ((X), 1)) == SYMBOL_REF \
99 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
100 || LEGITIMATE_SMALL_DATA_OFFSET_P (XEXP ((X), 1))))
102 /* Array of valid operand punctuation characters. */
103 char arc_punct_chars
[256];
105 /* State used by arc_ccfsm_advance to implement conditional execution. */
106 struct GTY (()) arc_ccfsm
111 rtx_insn
*target_insn
;
115 /* Status of the IRQ_CTRL_AUX register. */
116 typedef struct irq_ctrl_saved_t
118 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
119 short irq_save_last_reg
;
120 /* True if BLINK is automatically saved. */
122 /* True if LPCOUNT is automatically saved. */
123 bool irq_save_lpcount
;
125 static irq_ctrl_saved_t irq_ctrl_saved
;
127 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
128 ((ARC_INTERRUPT_P (FNTYPE) \
129 && irq_ctrl_saved.irq_save_blink) \
130 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
131 && rgf_banked_register_count > 8))
133 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
134 ((ARC_INTERRUPT_P (FNTYPE) \
135 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
136 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
137 && rgf_banked_register_count > 8))
139 #define ARC_AUTO_IRQ_P(FNTYPE) \
140 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
141 && (irq_ctrl_saved.irq_save_blink \
142 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
144 /* Number of registers in second bank for FIRQ support. */
145 static int rgf_banked_register_count
;
147 #define arc_ccfsm_current cfun->machine->ccfsm_current
149 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
150 ((STATE)->state == 1 || (STATE)->state == 2)
152 /* Indicate we're conditionalizing insns now. */
153 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
154 ((STATE)->state += 2)
156 #define ARC_CCFSM_COND_EXEC_P(STATE) \
157 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
158 || current_insn_predicate)
160 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
161 #define CCFSM_ISCOMPACT(INSN,STATE) \
162 (ARC_CCFSM_COND_EXEC_P (STATE) \
163 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
164 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
165 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
167 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
168 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
169 ((ARC_CCFSM_COND_EXEC_P (STATE) \
171 && INSN_ANNULLED_BRANCH_P (JUMP) \
172 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
173 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
174 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
175 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
177 /* The maximum number of insns skipped which will be conditionalised if
179 /* When optimizing for speed:
180 Let p be the probability that the potentially skipped insns need to
181 be executed, pn the cost of a correctly predicted non-taken branch,
182 mt the cost of a mis/non-predicted taken branch,
183 mn mispredicted non-taken, pt correctly predicted taken ;
184 costs expressed in numbers of instructions like the ones considered
186 Unfortunately we don't have a measure of predictability - this
187 is linked to probability only in that in the no-eviction-scenario
188 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
189 value that can be assumed *if* the distribution is perfectly random.
190 A predictability of 1 is perfectly plausible not matter what p is,
191 because the decision could be dependent on an invocation parameter
193 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
194 For small p, we want MAX_INSNS_SKIPPED == pt
196 When optimizing for size:
197 We want to skip insn unless we could use 16 opcodes for the
198 non-conditionalized insn to balance the branch length or more.
199 Performance can be tie-breaker. */
200 /* If the potentially-skipped insns are likely to be executed, we'll
201 generally save one non-taken branch
203 this to be no less than the 1/p */
204 #define MAX_INSNS_SKIPPED 3
206 /* A nop is needed between a 4 byte insn that sets the condition codes and
207 a branch that uses them (the same isn't true for an 8 byte insn that sets
208 the condition codes). Set by arc_ccfsm_advance. Used by
209 arc_print_operand. */
211 static int get_arc_condition_code (rtx
);
213 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
214 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
216 /* Initialized arc_attribute_table to NULL since arc doesnot have any
217 machine specific supported attributes. */
218 const struct attribute_spec arc_attribute_table
[] =
220 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
221 affects_type_identity } */
222 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute
, true },
223 /* Function calls made to this symbol must be done indirectly, because
224 it may lie outside of the 21/25 bit addressing range of a normal function
226 { "long_call", 0, 0, false, true, true, NULL
, false },
227 /* Whereas these functions are always known to reside within the 25 bit
228 addressing range of unconditionalized bl. */
229 { "medium_call", 0, 0, false, true, true, NULL
, false },
230 /* And these functions are always known to reside within the 21 bit
231 addressing range of blcc. */
232 { "short_call", 0, 0, false, true, true, NULL
, false },
233 /* Function which are not having the prologue and epilogue generated
235 { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute
, false },
236 { NULL
, 0, 0, false, false, false, NULL
, false }
238 static int arc_comp_type_attributes (const_tree
, const_tree
);
239 static void arc_file_start (void);
240 static void arc_internal_label (FILE *, const char *, unsigned long);
241 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
243 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
244 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
246 static void arc_init_builtins (void);
247 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
249 static int branch_dest (rtx
);
251 static void arc_output_pic_addr_const (FILE *, rtx
, int);
252 static bool arc_function_ok_for_sibcall (tree
, tree
);
253 static rtx
arc_function_value (const_tree
, const_tree
, bool);
254 const char * output_shift (rtx
*);
255 static void arc_reorg (void);
256 static bool arc_in_small_data_p (const_tree
);
258 static void arc_init_reg_tables (void);
259 static bool arc_return_in_memory (const_tree
, const_tree
);
260 static bool arc_vector_mode_supported_p (machine_mode
);
262 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
264 static const char *arc_invalid_within_doloop (const rtx_insn
*);
266 static void output_short_suffix (FILE *file
);
268 static bool arc_frame_pointer_required (void);
270 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
272 enum by_pieces_operation op
,
275 /* Globally visible information about currently selected cpu. */
276 const arc_cpu_t
*arc_selected_cpu
;
279 legitimate_scaled_address_p (machine_mode mode
, rtx op
, bool strict
)
281 if (GET_CODE (op
) != PLUS
)
284 if (GET_CODE (XEXP (op
, 0)) != MULT
)
287 /* Check multiplication operands. */
288 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op
, 0), 0), strict
))
291 if (!CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
294 switch (GET_MODE_SIZE (mode
))
297 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 2)
305 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 4)
311 /* Check the base. */
312 if (RTX_OK_FOR_BASE_P (XEXP (op
, 1), (strict
)))
317 if (CONST_INT_P (XEXP (op
, 1)))
321 if (CONSTANT_P (XEXP (op
, 1)))
323 /* Scalled addresses for sdata is done other places. */
324 if (GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
325 && SYMBOL_REF_SMALL_P (XEXP (op
, 1)))
333 /* Check for constructions like REG + OFFS, where OFFS can be a
334 register, an immediate or an long immediate. */
337 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
339 if (GET_CODE (x
) != PLUS
)
342 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
345 /* Check for: [Rx + small offset] or [Rx + Ry]. */
346 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
347 && GET_MODE_SIZE ((mode
)) <= 4)
348 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
351 /* Check for [Rx + symbol]. */
353 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
354 /* Avoid this type of address for double or larger modes. */
355 && (GET_MODE_SIZE (mode
) <= 4)
356 /* Avoid small data which ends in something like GP +
358 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))))
364 /* Implements target hook vector_mode_supported_p. */
367 arc_vector_mode_supported_p (machine_mode mode
)
372 return TARGET_PLUS_DMPY
;
375 return TARGET_PLUS_QMACW
;
378 return TARGET_SIMD_SET
;
385 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
388 arc_preferred_simd_mode (scalar_mode mode
)
393 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
402 /* Implements target hook
403 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
406 arc_autovectorize_vector_sizes (void)
408 return TARGET_PLUS_QMACW
? (8 | 4) : 0;
411 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
412 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
413 static rtx
arc_delegitimize_address (rtx
);
414 static bool arc_can_follow_jump (const rtx_insn
*follower
,
415 const rtx_insn
*followee
);
417 static rtx
frame_insn (rtx
);
418 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
420 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
422 static void arc_finalize_pic (void);
424 /* initialize the GCC target structure. */
425 #undef TARGET_COMP_TYPE_ATTRIBUTES
426 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
427 #undef TARGET_ASM_FILE_START
428 #define TARGET_ASM_FILE_START arc_file_start
429 #undef TARGET_ATTRIBUTE_TABLE
430 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
431 #undef TARGET_ASM_INTERNAL_LABEL
432 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
433 #undef TARGET_RTX_COSTS
434 #define TARGET_RTX_COSTS arc_rtx_costs
435 #undef TARGET_ADDRESS_COST
436 #define TARGET_ADDRESS_COST arc_address_cost
438 #undef TARGET_ENCODE_SECTION_INFO
439 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
441 #undef TARGET_CANNOT_FORCE_CONST_MEM
442 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
444 #undef TARGET_INIT_BUILTINS
445 #define TARGET_INIT_BUILTINS arc_init_builtins
447 #undef TARGET_EXPAND_BUILTIN
448 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
450 #undef TARGET_BUILTIN_DECL
451 #define TARGET_BUILTIN_DECL arc_builtin_decl
453 #undef TARGET_ASM_OUTPUT_MI_THUNK
454 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
456 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
457 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
459 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
460 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
462 #undef TARGET_MACHINE_DEPENDENT_REORG
463 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
465 #undef TARGET_IN_SMALL_DATA_P
466 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
468 #undef TARGET_PROMOTE_FUNCTION_MODE
469 #define TARGET_PROMOTE_FUNCTION_MODE \
470 default_promote_function_mode_always_promote
472 #undef TARGET_PROMOTE_PROTOTYPES
473 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
475 #undef TARGET_RETURN_IN_MEMORY
476 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
477 #undef TARGET_PASS_BY_REFERENCE
478 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
480 #undef TARGET_SETUP_INCOMING_VARARGS
481 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
483 #undef TARGET_ARG_PARTIAL_BYTES
484 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
486 #undef TARGET_MUST_PASS_IN_STACK
487 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
489 #undef TARGET_FUNCTION_VALUE
490 #define TARGET_FUNCTION_VALUE arc_function_value
492 #undef TARGET_SCHED_ADJUST_PRIORITY
493 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
495 #undef TARGET_VECTOR_MODE_SUPPORTED_P
496 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
498 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
499 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
501 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
502 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
504 #undef TARGET_CAN_USE_DOLOOP_P
505 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
507 #undef TARGET_INVALID_WITHIN_DOLOOP
508 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
510 #undef TARGET_PRESERVE_RELOAD_P
511 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
513 #undef TARGET_CAN_FOLLOW_JUMP
514 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
516 #undef TARGET_DELEGITIMIZE_ADDRESS
517 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
519 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
520 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
521 arc_use_by_pieces_infrastructure_p
523 /* Usually, we will be able to scale anchor offsets.
524 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
525 #undef TARGET_MIN_ANCHOR_OFFSET
526 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
527 #undef TARGET_MAX_ANCHOR_OFFSET
528 #define TARGET_MAX_ANCHOR_OFFSET (1020)
530 #undef TARGET_SECONDARY_RELOAD
531 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
533 #define TARGET_OPTION_OVERRIDE arc_override_options
535 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
537 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
539 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
541 #define TARGET_CAN_ELIMINATE arc_can_eliminate
543 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
545 #define TARGET_FUNCTION_ARG arc_function_arg
547 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
549 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
551 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
553 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
555 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
557 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
559 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
561 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
562 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
563 arc_no_speculation_in_delay_slots_p
566 #define TARGET_LRA_P arc_lra_p
567 #define TARGET_REGISTER_PRIORITY arc_register_priority
568 /* Stores with scaled offsets have different displacement ranges. */
569 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
570 #define TARGET_SPILL_CLASS arc_spill_class
572 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
573 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
575 #undef TARGET_WARN_FUNC_RETURN
576 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
578 #include "target-def.h"
580 #undef TARGET_ASM_ALIGNED_HI_OP
581 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
582 #undef TARGET_ASM_ALIGNED_SI_OP
583 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
586 #undef TARGET_HAVE_TLS
587 #define TARGET_HAVE_TLS HAVE_AS_TLS
590 #undef TARGET_DWARF_REGISTER_SPAN
591 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
593 #undef TARGET_HARD_REGNO_NREGS
594 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
595 #undef TARGET_HARD_REGNO_MODE_OK
596 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
598 #undef TARGET_MODES_TIEABLE_P
599 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
601 /* Try to keep the (mov:DF _, reg) as early as possible so
602 that the d<add/sub/mul>h-lr insns appear together and can
603 use the peephole2 pattern. */
606 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
608 rtx set
= single_set (insn
);
610 && GET_MODE (SET_SRC(set
)) == DFmode
611 && GET_CODE (SET_SRC(set
)) == REG
)
613 /* Incrementing priority by 20 (empirically derived). */
614 return priority
+ 20;
620 /* For ARC base register + offset addressing, the validity of the
621 address is mode-dependent for most of the offset range, as the
622 offset can be scaled by the access size.
623 We don't expose these as mode-dependent addresses in the
624 mode_dependent_address_p target hook, because that would disable
625 lots of optimizations, and most uses of these addresses are for 32
626 or 64 bit accesses anyways, which are fine.
627 However, that leaves some addresses for 8 / 16 bit values not
628 properly reloaded by the generic code, which is why we have to
629 schedule secondary reloads for these. */
632 arc_secondary_reload (bool in_p
,
636 secondary_reload_info
*sri
)
638 enum rtx_code code
= GET_CODE (x
);
640 if (cl
== DOUBLE_REGS
)
643 /* The loop counter register can be stored, but not loaded directly. */
644 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
645 && in_p
&& MEM_P (x
))
648 /* If we have a subreg (reg), where reg is a pseudo (that will end in
649 a memory location), then we may need a scratch register to handle
650 the fp/sp+largeoffset address. */
658 int regno
= REGNO (x
);
659 if (regno
>= FIRST_PSEUDO_REGISTER
)
660 regno
= reg_renumber
[regno
];
665 /* It is a pseudo that ends in a stack location. */
666 if (reg_equiv_mem (REGNO (x
)))
668 /* Get the equivalent address and check the range of the
670 rtx mem
= reg_equiv_mem (REGNO (x
));
671 addr
= find_replacement (&XEXP (mem
, 0));
676 gcc_assert (MEM_P (x
));
678 addr
= simplify_rtx (addr
);
680 if (addr
&& GET_CODE (addr
) == PLUS
681 && CONST_INT_P (XEXP (addr
, 1))
682 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
688 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
692 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
702 /* Convert reloads using offsets that are too large to use indirect
706 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
710 gcc_assert (GET_CODE (mem
) == MEM
);
711 addr
= XEXP (mem
, 0);
713 /* Large offset: use a move. FIXME: ld ops accepts limms as
714 offsets. Hence, the following move insn is not required. */
715 emit_move_insn (scratch
, addr
);
716 mem
= replace_equiv_address_nv (mem
, scratch
);
718 /* Now create the move. */
720 emit_insn (gen_rtx_SET (mem
, reg
));
722 emit_insn (gen_rtx_SET (reg
, mem
));
727 static unsigned arc_ifcvt (void);
731 const pass_data pass_data_arc_ifcvt
=
734 "arc_ifcvt", /* name */
735 OPTGROUP_NONE
, /* optinfo_flags */
736 TV_IFCVT2
, /* tv_id */
737 0, /* properties_required */
738 0, /* properties_provided */
739 0, /* properties_destroyed */
740 0, /* todo_flags_start */
741 TODO_df_finish
/* todo_flags_finish */
744 class pass_arc_ifcvt
: public rtl_opt_pass
747 pass_arc_ifcvt(gcc::context
*ctxt
)
748 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
751 /* opt_pass methods: */
752 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
753 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
759 make_pass_arc_ifcvt (gcc::context
*ctxt
)
761 return new pass_arc_ifcvt (ctxt
);
764 static unsigned arc_predicate_delay_insns (void);
768 const pass_data pass_data_arc_predicate_delay_insns
=
771 "arc_predicate_delay_insns", /* name */
772 OPTGROUP_NONE
, /* optinfo_flags */
773 TV_IFCVT2
, /* tv_id */
774 0, /* properties_required */
775 0, /* properties_provided */
776 0, /* properties_destroyed */
777 0, /* todo_flags_start */
778 TODO_df_finish
/* todo_flags_finish */
781 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
784 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
785 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
788 /* opt_pass methods: */
789 virtual unsigned int execute (function
*)
791 return arc_predicate_delay_insns ();
798 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
800 return new pass_arc_predicate_delay_insns (ctxt
);
803 /* Called by OVERRIDE_OPTIONS to initialize various things. */
810 /* I have the multiplier, then use it*/
811 if (TARGET_MPYW
|| TARGET_MULTI
)
812 arc_multcost
= COSTS_N_INSNS (1);
814 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
815 if (arc_multcost
< 0)
818 case TUNE_ARC700_4_2_STD
:
820 max throughput (1 multiply + 4 other insns) / 5 cycles. */
821 arc_multcost
= COSTS_N_INSNS (4);
822 if (TARGET_NOMPY_SET
)
823 arc_multcost
= COSTS_N_INSNS (30);
825 case TUNE_ARC700_4_2_XMAC
:
827 max throughput (1 multiply + 2 other insns) / 3 cycles. */
828 arc_multcost
= COSTS_N_INSNS (3);
829 if (TARGET_NOMPY_SET
)
830 arc_multcost
= COSTS_N_INSNS (30);
833 if (TARGET_MUL64_SET
)
835 arc_multcost
= COSTS_N_INSNS (4);
840 arc_multcost
= COSTS_N_INSNS (30);
844 /* MPY instructions valid only for ARC700 or ARCv2. */
845 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
846 error ("-mno-mpy supported only for ARC700 or ARCv2");
848 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
849 error ("-mno-dpfp-lrsr supported only with -mdpfp");
851 /* FPX-1. No fast and compact together. */
852 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
853 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
854 error ("FPX fast and compact options cannot be specified together");
856 /* FPX-2. No fast-spfp for arc600 or arc601. */
857 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
858 error ("-mspfp_fast not available on ARC600 or ARC601");
860 /* FPX-4. No FPX extensions mixed with FPU extensions. */
861 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
862 && TARGET_HARD_FLOAT
)
863 error ("No FPX/FPU mixing allowed");
865 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
866 if (flag_pic
&& TARGET_ARC600_FAMILY
)
869 "PIC is not supported for %s. Generating non-PIC code only..",
874 arc_init_reg_tables ();
876 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
877 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
878 arc_punct_chars
['#'] = 1;
879 arc_punct_chars
['*'] = 1;
880 arc_punct_chars
['?'] = 1;
881 arc_punct_chars
['!'] = 1;
882 arc_punct_chars
['^'] = 1;
883 arc_punct_chars
['&'] = 1;
884 arc_punct_chars
['+'] = 1;
885 arc_punct_chars
['_'] = 1;
887 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
889 /* There are two target-independent ifcvt passes, and arc_reorg may do
890 one or more arc_ifcvt calls. */
891 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
892 struct register_pass_info arc_ifcvt4_info
893 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
894 struct register_pass_info arc_ifcvt5_info
895 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
897 register_pass (&arc_ifcvt4_info
);
898 register_pass (&arc_ifcvt5_info
);
901 if (flag_delayed_branch
)
903 opt_pass
*pass_arc_predicate_delay_insns
904 = make_pass_arc_predicate_delay_insns (g
);
905 struct register_pass_info arc_predicate_delay_info
906 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
908 register_pass (&arc_predicate_delay_info
);
912 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
913 register range is specified as two registers separated by a dash.
914 It always starts with r0, and its upper limit is fp register.
915 blink and lp_count registers are optional. */
918 irq_range (const char *cstr
)
920 int i
, first
, last
, blink
, lpcount
, xreg
;
921 char *str
, *dash
, *comma
;
924 str
= (char *) alloca (i
+ 1);
925 memcpy (str
, cstr
, i
+ 1);
929 dash
= strchr (str
, '-');
932 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
937 comma
= strchr (dash
+ 1, ',');
941 first
= decode_reg_name (str
);
944 warning (0, "first register must be R0");
948 /* At this moment we do not have the register names initialized
950 if (!strcmp (dash
+ 1, "ilink"))
953 last
= decode_reg_name (dash
+ 1);
957 warning (0, "unknown register name: %s", dash
+ 1);
963 warning (0, "last register name %s must be an odd register", dash
+ 1);
971 warning (0, "%s-%s is an empty range", str
, dash
+ 1);
980 comma
= strchr (str
, ',');
984 xreg
= decode_reg_name (str
);
996 warning (0, "unknown register name: %s", str
);
1001 irq_ctrl_saved
.irq_save_last_reg
= last
;
1002 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
1003 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
1006 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1010 parse_mrgf_banked_regs_option (const char *arg
)
1016 val
= strtol (arg
, &end_ptr
, 10);
1017 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
1018 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
1020 error ("invalid number in -mrgf-banked-regs=%s "
1021 "valid values are 0, 4, 8, 16, or 32", arg
);
1024 rgf_banked_register_count
= (int) val
;
1027 /* Check ARC options, generate derived target attributes. */
1030 arc_override_options (void)
1033 cl_deferred_option
*opt
;
1034 vec
<cl_deferred_option
> *vopt
1035 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
1037 if (arc_cpu
== PROCESSOR_NONE
)
1038 arc_cpu
= TARGET_CPU_DEFAULT
;
1040 /* Set the default cpu options. */
1041 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
1043 /* Set the architectures. */
1044 switch (arc_selected_cpu
->arch_info
->arch_id
)
1047 arc_cpu_string
= "EM";
1050 arc_cpu_string
= "HS";
1053 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
1054 arc_cpu_string
= "NPS400";
1056 arc_cpu_string
= "ARC700";
1059 arc_cpu_string
= "ARC600";
1065 irq_ctrl_saved
.irq_save_last_reg
= -1;
1066 irq_ctrl_saved
.irq_save_blink
= false;
1067 irq_ctrl_saved
.irq_save_lpcount
= false;
1069 rgf_banked_register_count
= 0;
1071 /* Handle the deferred options. */
1073 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1075 switch (opt
->opt_index
)
1077 case OPT_mirq_ctrl_saved_
:
1079 irq_range (opt
->arg
);
1081 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1084 case OPT_mrgf_banked_regs_
:
1086 parse_mrgf_banked_regs_option (opt
->arg
);
1088 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1096 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1097 specific flags are set in arc-common.c. The architecture forces
1098 the default hardware configurations in, regardless what command
1099 line options are saying. The CPU optional hw options can be
1100 turned on or off. */
1101 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1103 if ((arc_selected_cpu->flags & CODE) \
1104 && ((target_flags_explicit & MASK) == 0)) \
1105 target_flags |= MASK; \
1106 if (arc_selected_cpu->arch_info->dflags & CODE) \
1107 target_flags |= MASK; \
1109 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1111 if ((arc_selected_cpu->flags & CODE) \
1112 && (VAR == DEFAULT_##VAR)) \
1114 if (arc_selected_cpu->arch_info->dflags & CODE) \
1118 #include "arc-options.def"
1123 /* Check options against architecture options. Throw an error if
1124 option is not allowed. */
1125 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1128 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1130 error ("%s is not available for %s architecture", \
1131 DOC, arc_selected_cpu->arch_info->name); \
1134 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1136 if ((target_flags & MASK) \
1137 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1138 error ("%s is not available for %s architecture", \
1139 DOC, arc_selected_cpu->arch_info->name); \
1142 #include "arc-options.def"
1147 /* Set Tune option. */
1148 if (arc_tune
== TUNE_NONE
)
1149 arc_tune
= (enum attr_tune
) arc_selected_cpu
->tune
;
1151 if (arc_size_opt_level
== 3)
1154 /* Compact casesi is not a valid option for ARCv2 family. */
1157 if (TARGET_COMPACT_CASESI
)
1159 warning (0, "compact-casesi is not applicable to ARCv2");
1160 TARGET_COMPACT_CASESI
= 0;
1163 else if (optimize_size
== 1
1164 && !global_options_set
.x_TARGET_COMPACT_CASESI
)
1165 TARGET_COMPACT_CASESI
= 1;
1168 target_flags
|= MASK_NO_SDATA_SET
;
1170 if (flag_no_common
== 255)
1171 flag_no_common
= !TARGET_NO_SDATA_SET
;
1173 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1174 if (TARGET_MIXED_CODE
)
1176 if (!TARGET_Q_CLASS
)
1177 TARGET_COMPACT_CASESI
= 0;
1178 if (TARGET_COMPACT_CASESI
)
1179 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
1181 /* Check for small data option */
1182 if (!global_options_set
.x_g_switch_value
&& !TARGET_NO_SDATA_SET
)
1183 g_switch_value
= TARGET_LL64
? 8 : 4;
1185 /* These need to be done at start up. It's convenient to do them here. */
1189 /* The condition codes of the ARC, and the inverse function. */
1190 /* For short branches, the "c" / "nc" names are not defined in the ARC
1191 Programmers manual, so we have to use "lo" / "hs"" instead. */
1192 static const char *arc_condition_codes
[] =
1194 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1195 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1198 enum arc_cc_code_index
1200 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1201 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1202 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1203 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1206 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1208 /* Returns the index of the ARC condition code string in
1209 `arc_condition_codes'. COMPARISON should be an rtx like
1210 `(eq (...) (...))'. */
1213 get_arc_condition_code (rtx comparison
)
1215 switch (GET_MODE (XEXP (comparison
, 0)))
1218 case E_SImode
: /* For BRcc. */
1219 switch (GET_CODE (comparison
))
1221 case EQ
: return ARC_CC_EQ
;
1222 case NE
: return ARC_CC_NE
;
1223 case GT
: return ARC_CC_GT
;
1224 case LE
: return ARC_CC_LE
;
1225 case GE
: return ARC_CC_GE
;
1226 case LT
: return ARC_CC_LT
;
1227 case GTU
: return ARC_CC_HI
;
1228 case LEU
: return ARC_CC_LS
;
1229 case LTU
: return ARC_CC_LO
;
1230 case GEU
: return ARC_CC_HS
;
1231 default : gcc_unreachable ();
1234 switch (GET_CODE (comparison
))
1236 case EQ
: return ARC_CC_EQ
;
1237 case NE
: return ARC_CC_NE
;
1238 case GE
: return ARC_CC_P
;
1239 case LT
: return ARC_CC_N
;
1240 case GT
: return ARC_CC_PNZ
;
1241 default : gcc_unreachable ();
1244 switch (GET_CODE (comparison
))
1246 case EQ
: return ARC_CC_EQ
;
1247 case NE
: return ARC_CC_NE
;
1248 default : gcc_unreachable ();
1251 switch (GET_CODE (comparison
))
1253 case LTU
: return ARC_CC_C
;
1254 case GEU
: return ARC_CC_NC
;
1255 default : gcc_unreachable ();
1257 case E_CC_FP_GTmode
:
1258 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1259 switch (GET_CODE (comparison
))
1261 case GT
: return ARC_CC_N
;
1262 case UNLE
: return ARC_CC_P
;
1263 default : gcc_unreachable ();
1266 switch (GET_CODE (comparison
))
1268 case GT
: return ARC_CC_HI
;
1269 case UNLE
: return ARC_CC_LS
;
1270 default : gcc_unreachable ();
1272 case E_CC_FP_GEmode
:
1273 /* Same for FPX and non-FPX. */
1274 switch (GET_CODE (comparison
))
1276 case GE
: return ARC_CC_HS
;
1277 case UNLT
: return ARC_CC_LO
;
1278 default : gcc_unreachable ();
1280 case E_CC_FP_UNEQmode
:
1281 switch (GET_CODE (comparison
))
1283 case UNEQ
: return ARC_CC_EQ
;
1284 case LTGT
: return ARC_CC_NE
;
1285 default : gcc_unreachable ();
1287 case E_CC_FP_ORDmode
:
1288 switch (GET_CODE (comparison
))
1290 case UNORDERED
: return ARC_CC_C
;
1291 case ORDERED
: return ARC_CC_NC
;
1292 default : gcc_unreachable ();
1295 switch (GET_CODE (comparison
))
1297 case EQ
: return ARC_CC_EQ
;
1298 case NE
: return ARC_CC_NE
;
1299 case UNORDERED
: return ARC_CC_C
;
1300 case ORDERED
: return ARC_CC_NC
;
1301 case LTGT
: return ARC_CC_HI
;
1302 case UNEQ
: return ARC_CC_LS
;
1303 default : gcc_unreachable ();
1306 switch (GET_CODE (comparison
))
1308 case EQ
: return ARC_CC_EQ
;
1309 case NE
: return ARC_CC_NE
;
1310 case GT
: return ARC_CC_GT
;
1311 case GE
: return ARC_CC_GE
;
1312 case LT
: return ARC_CC_C
;
1313 case LE
: return ARC_CC_LS
;
1314 case UNORDERED
: return ARC_CC_V
;
1315 case ORDERED
: return ARC_CC_NV
;
1316 case UNGT
: return ARC_CC_HI
;
1317 case UNGE
: return ARC_CC_HS
;
1318 case UNLT
: return ARC_CC_LT
;
1319 case UNLE
: return ARC_CC_LE
;
1320 /* UNEQ and LTGT do not have representation. */
1321 case LTGT
: /* Fall through. */
1322 case UNEQ
: /* Fall through. */
1323 default : gcc_unreachable ();
1325 case E_CC_FPU_UNEQmode
:
1326 switch (GET_CODE (comparison
))
1328 case LTGT
: return ARC_CC_NE
;
1329 case UNEQ
: return ARC_CC_EQ
;
1330 default : gcc_unreachable ();
1332 default : gcc_unreachable ();
1338 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1341 arc_short_comparison_p (rtx comparison
, int offset
)
1343 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1344 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1345 switch (get_arc_condition_code (comparison
))
1347 case ARC_CC_EQ
: case ARC_CC_NE
:
1348 return offset
>= -512 && offset
<= 506;
1349 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1350 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1351 return offset
>= -64 && offset
<= 58;
1357 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1358 return the mode to be used for the comparison. */
1361 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1363 machine_mode mode
= GET_MODE (x
);
1366 /* For an operation that sets the condition codes as a side-effect, the
1367 C and V flags is not set as for cmp, so we can only use comparisons where
1368 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1370 /* ??? We could use "pnz" for greater than zero, however, we could then
1371 get into trouble because the comparison could not be reversed. */
1372 if (GET_MODE_CLASS (mode
) == MODE_INT
1374 && (op
== EQ
|| op
== NE
1375 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1378 /* add.f for if (a+b) */
1380 && GET_CODE (y
) == NEG
1381 && (op
== EQ
|| op
== NE
))
1384 /* Check if this is a test suitable for bxor.f . */
1385 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1386 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1390 /* Check if this is a test suitable for add / bmsk.f . */
1391 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1392 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1393 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1394 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1395 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1398 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1399 && GET_CODE (x
) == PLUS
1400 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1403 if (TARGET_ARGONAUT_SET
1404 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1407 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1409 case LT
: case UNGE
: case GT
: case UNLE
:
1410 return CC_FP_GTmode
;
1411 case LE
: case UNGT
: case GE
: case UNLT
:
1412 return CC_FP_GEmode
;
1413 default: gcc_unreachable ();
1415 else if (TARGET_HARD_FLOAT
1416 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1417 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1436 return CC_FPU_UNEQmode
;
1441 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1445 case EQ
: case NE
: return CC_Zmode
;
1447 case GT
: case UNLE
: return CC_FP_GTmode
;
1449 case GE
: case UNLT
: return CC_FP_GEmode
;
1450 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1451 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1452 default: gcc_unreachable ();
1458 /* Vectors to keep interesting information about registers where it can easily
1459 be got. We use to use the actual mode value as the bit number, but there
1460 is (or may be) more than 32 modes now. Instead we use two tables: one
1461 indexed by hard register number, and one indexed by mode. */
1463 /* The purpose of arc_mode_class is to shrink the range of modes so that
1464 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1465 mapped into one arc_mode_class mode. */
1467 enum arc_mode_class
{
1469 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1470 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1474 /* Modes for condition codes. */
1475 #define C_MODES (1 << (int) C_MODE)
1477 /* Modes for single-word and smaller quantities. */
1478 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1480 /* Modes for double-word and smaller quantities. */
1481 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1483 /* Mode for 8-byte DF values only. */
1484 #define DF_MODES (1 << DF_MODE)
1486 /* Modes for quad-word and smaller quantities. */
1487 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1489 /* Modes for 128-bit vectors. */
1490 #define V_MODES (1 << (int) V_MODE)
1492 /* Value is 1 if register/mode pair is acceptable on arc. */
1494 static unsigned int arc_hard_regno_modes
[] = {
1495 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1496 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1497 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1498 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1500 /* ??? Leave these as S_MODES for now. */
1501 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1502 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1503 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1504 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1506 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1507 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1508 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1509 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1511 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1512 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1513 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1514 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1516 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1517 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1520 static unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1522 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1525 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1527 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1528 return GENERAL_REGS
;
1532 /* Initialize the arc_mode_class array. */
1535 arc_init_reg_tables (void)
1539 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1541 machine_mode m
= (machine_mode
) i
;
1543 switch (GET_MODE_CLASS (m
))
1546 case MODE_PARTIAL_INT
:
1547 case MODE_COMPLEX_INT
:
1548 if (GET_MODE_SIZE (m
) <= 4)
1549 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1550 else if (GET_MODE_SIZE (m
) == 8)
1551 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1552 else if (GET_MODE_SIZE (m
) == 16)
1553 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1554 else if (GET_MODE_SIZE (m
) == 32)
1555 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1557 arc_mode_class
[i
] = 0;
1560 case MODE_COMPLEX_FLOAT
:
1561 if (GET_MODE_SIZE (m
) <= 4)
1562 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1563 else if (GET_MODE_SIZE (m
) == 8)
1564 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1565 else if (GET_MODE_SIZE (m
) == 16)
1566 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1567 else if (GET_MODE_SIZE (m
) == 32)
1568 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1570 arc_mode_class
[i
] = 0;
1572 case MODE_VECTOR_INT
:
1573 if (GET_MODE_SIZE (m
) == 4)
1574 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1575 else if (GET_MODE_SIZE (m
) == 8)
1576 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1578 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1582 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1583 we must explicitly check for them here. */
1584 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1585 || i
== (int) CC_Cmode
1586 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1587 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1588 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1590 arc_mode_class
[i
] = 0;
1596 /* Core registers 56..59 are used for multiply extension options.
1597 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1598 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1599 number depends on endianness.
1600 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1601 Because mlo / mhi form a 64 bit value, we use different gcc internal
1602 register numbers to make them form a register pair as the gcc internals
1603 know it. mmid gets number 57, if still available, and mlo / mhi get
1604 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1605 to map this back. */
1606 char rname56
[5] = "r56";
1607 char rname57
[5] = "r57";
1608 char rname58
[5] = "r58";
1609 char rname59
[5] = "r59";
1610 char rname29
[7] = "ilink1";
1611 char rname30
[7] = "ilink2";
1614 arc_conditional_register_usage (void)
1618 int fix_start
= 60, fix_end
= 55;
1622 /* For ARCv2 the core register set is changed. */
1623 strcpy (rname29
, "ilink");
1624 strcpy (rname30
, "r30");
1625 call_used_regs
[30] = 1;
1628 arc_regno_reg_class
[30] = WRITABLE_CORE_REGS
;
1629 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], 30);
1630 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], 30);
1631 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], 30);
1632 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], 30);
1635 if (TARGET_MUL64_SET
)
1640 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1641 you are supposed to refer to it as mlo & mhi, e.g
1642 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1643 In an actual asm instruction, you are of course use mmed.
1644 The point of avoiding having a separate register for mmed is that
1645 this way, we don't have to carry clobbers of that reg around in every
1646 isntruction that modifies mlo and/or mhi. */
1647 strcpy (rname57
, "");
1648 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1649 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1652 /* The nature of arc_tp_regno is actually something more like a global
1653 register, however globalize_reg requires a declaration.
1654 We use EPILOGUE_USES to compensate so that sets from
1655 __builtin_set_frame_pointer are not deleted. */
1656 if (arc_tp_regno
!= -1)
1657 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1659 if (TARGET_MULMAC_32BY16_SET
)
1662 fix_end
= fix_end
> 57 ? fix_end
: 57;
1663 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1664 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1666 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1668 if (!fixed_regs
[regno
])
1669 warning (0, "multiply option implies r%d is fixed", regno
);
1670 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1676 reg_alloc_order
[0] = 0;
1677 reg_alloc_order
[1] = 1;
1678 reg_alloc_order
[2] = 2;
1679 reg_alloc_order
[3] = 3;
1680 reg_alloc_order
[4] = 12;
1681 reg_alloc_order
[5] = 13;
1682 reg_alloc_order
[6] = 14;
1683 reg_alloc_order
[7] = 15;
1684 reg_alloc_order
[8] = 4;
1685 reg_alloc_order
[9] = 5;
1686 reg_alloc_order
[10] = 6;
1687 reg_alloc_order
[11] = 7;
1688 reg_alloc_order
[12] = 8;
1689 reg_alloc_order
[13] = 9;
1690 reg_alloc_order
[14] = 10;
1691 reg_alloc_order
[15] = 11;
1695 reg_alloc_order
[2] = 12;
1696 reg_alloc_order
[3] = 13;
1697 reg_alloc_order
[4] = 14;
1698 reg_alloc_order
[5] = 15;
1699 reg_alloc_order
[6] = 1;
1700 reg_alloc_order
[7] = 0;
1701 reg_alloc_order
[8] = 4;
1702 reg_alloc_order
[9] = 5;
1703 reg_alloc_order
[10] = 6;
1704 reg_alloc_order
[11] = 7;
1705 reg_alloc_order
[12] = 8;
1706 reg_alloc_order
[13] = 9;
1707 reg_alloc_order
[14] = 10;
1708 reg_alloc_order
[15] = 11;
1711 if (TARGET_SIMD_SET
)
1714 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1715 reg_alloc_order
[i
] = i
;
1716 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1717 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1718 reg_alloc_order
[i
] = i
;
1721 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1722 if (!call_used_regs
[regno
])
1723 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1724 for (regno
= 32; regno
< 60; regno
++)
1725 if (!fixed_regs
[regno
])
1726 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1727 if (!TARGET_ARC600_FAMILY
)
1729 for (regno
= 32; regno
<= 60; regno
++)
1730 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1732 /* If they have used -ffixed-lp_count, make sure it takes
1734 if (fixed_regs
[LP_COUNT
])
1736 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1737 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1738 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1740 /* Instead of taking out SF_MODE like below, forbid it outright. */
1741 arc_hard_regno_modes
[60] = 0;
1744 arc_hard_regno_modes
[60] = 1 << (int) S_MODE
;
1747 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1751 for (regno
= 1; regno
< 32; regno
+=2)
1753 arc_hard_regno_modes
[regno
] = S_MODES
;
1757 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1761 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1762 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1763 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1765 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1768 arc_regno_reg_class
[i
]
1770 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1771 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1772 : (((!TARGET_ARC600_FAMILY
)
1773 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1774 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1776 arc_regno_reg_class
[i
] = NO_REGS
;
1779 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1780 has not been activated. */
1781 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1782 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1783 if (!TARGET_Q_CLASS
)
1784 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1786 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1788 /* Handle Special Registers. */
1789 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1791 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1792 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1793 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1794 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1795 arc_regno_reg_class
[62] = GENERAL_REGS
;
1799 for (i
= 40; i
< 44; ++i
)
1801 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1803 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1804 no attempt is made to use such a register as a destination
1805 operand in *movdf_insn. */
1806 if (!TARGET_ARGONAUT_SET
)
1808 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1809 interpreted to mean they can use D1 or D2 in their insn. */
1810 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1811 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1812 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1813 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1819 /* Disable all DOUBLE_REGISTER settings,
1820 if not generating DPFP code. */
1821 arc_regno_reg_class
[40] = ALL_REGS
;
1822 arc_regno_reg_class
[41] = ALL_REGS
;
1823 arc_regno_reg_class
[42] = ALL_REGS
;
1824 arc_regno_reg_class
[43] = ALL_REGS
;
1831 arc_hard_regno_modes
[40] = 0;
1832 arc_hard_regno_modes
[42] = 0;
1834 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1837 if (TARGET_SIMD_SET
)
1839 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1840 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1842 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1843 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1845 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1846 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1847 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1848 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1850 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1851 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1852 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1856 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
1858 /*ARCV2 Accumulator. */
1860 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1861 || TARGET_PLUS_DMPY
)
1863 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
1864 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
1865 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
1866 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
1867 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
1868 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
1869 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCL_REGNO
);
1870 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCH_REGNO
);
1871 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCL_REGNO
);
1872 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCH_REGNO
);
1874 /* Allow the compiler to freely use them. */
1875 fixed_regs
[ACCL_REGNO
] = 0;
1876 fixed_regs
[ACCH_REGNO
] = 0;
1878 arc_hard_regno_modes
[ACC_REG_FIRST
] = D_MODES
;
1882 /* Implement TARGET_HARD_REGNO_NREGS. */
1885 arc_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
1887 if (GET_MODE_SIZE (mode
) == 16
1888 && regno
>= ARC_FIRST_SIMD_VR_REG
1889 && regno
<= ARC_LAST_SIMD_VR_REG
)
1892 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
1895 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1898 arc_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
1900 return (arc_hard_regno_modes
[regno
] & arc_mode_class
[mode
]) != 0;
1903 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1906 arc_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
1908 return (GET_MODE_CLASS (mode1
) == MODE_INT
1909 && GET_MODE_CLASS (mode2
) == MODE_INT
1910 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
1911 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
);
1914 /* Handle an "interrupt" attribute; arguments as in
1915 struct attribute_spec.handler. */
1918 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
1923 tree value
= TREE_VALUE (args
);
1925 if (TREE_CODE (value
) != STRING_CST
)
1927 warning (OPT_Wattributes
,
1928 "argument of %qE attribute is not a string constant",
1930 *no_add_attrs
= true;
1933 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
1934 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
1936 warning (OPT_Wattributes
,
1937 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1939 *no_add_attrs
= true;
1942 && strcmp (TREE_STRING_POINTER (value
), "ilink")
1943 && strcmp (TREE_STRING_POINTER (value
), "firq"))
1945 warning (OPT_Wattributes
,
1946 "argument of %qE attribute is not \"ilink\" or \"firq\"",
1948 *no_add_attrs
= true;
1955 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
1956 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
1958 if (TREE_CODE (*node
) != FUNCTION_DECL
)
1960 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
1962 *no_add_attrs
= true;
1968 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
1971 arc_allocate_stack_slots_for_args (void)
1973 /* Naked functions should not allocate stack slots for arguments. */
1974 unsigned int fn_type
= arc_compute_function_type (cfun
);
1976 return !ARC_NAKED_P(fn_type
);
1979 /* Implement `TARGET_WARN_FUNC_RETURN'. */
1982 arc_warn_func_return (tree decl
)
1984 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
1985 unsigned int fn_type
= arc_compute_function_type (func
);
1987 return !ARC_NAKED_P (fn_type
);
1990 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1991 and two if they are nearly compatible (which causes a warning to be
1995 arc_comp_type_attributes (const_tree type1
,
1998 int l1
, l2
, m1
, m2
, s1
, s2
;
2000 /* Check for mismatch of non-default calling convention. */
2001 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
2004 /* Check for mismatched call attributes. */
2005 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2006 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2007 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2008 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2009 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2010 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2012 /* Only bother to check if an attribute is defined. */
2013 if (l1
| l2
| m1
| m2
| s1
| s2
)
2015 /* If one type has an attribute, the other must have the same attribute. */
2016 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
2019 /* Disallow mixed attributes. */
2020 if (l1
+ m1
+ s1
> 1)
2028 /* Set the default attributes for TYPE. */
2031 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED
)
2036 /* Misc. utilities. */
2038 /* X and Y are two things to compare using CODE. Emit the compare insn and
2039 return the rtx for the cc reg in the proper mode. */
2042 gen_compare_reg (rtx comparison
, machine_mode omode
)
2044 enum rtx_code code
= GET_CODE (comparison
);
2045 rtx x
= XEXP (comparison
, 0);
2046 rtx y
= XEXP (comparison
, 1);
2048 machine_mode mode
, cmode
;
2051 cmode
= GET_MODE (x
);
2052 if (cmode
== VOIDmode
)
2053 cmode
= GET_MODE (y
);
2054 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
2055 if (cmode
== SImode
)
2057 if (!register_operand (x
, SImode
))
2059 if (register_operand (y
, SImode
))
2064 code
= swap_condition (code
);
2067 x
= copy_to_mode_reg (SImode
, x
);
2069 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
2070 y
= copy_to_mode_reg (SImode
, y
);
2074 x
= force_reg (cmode
, x
);
2075 y
= force_reg (cmode
, y
);
2077 mode
= SELECT_CC_MODE (code
, x
, y
);
2079 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
2081 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2082 cmpdfpx_raw, is not a correct comparison for floats:
2083 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2085 if (TARGET_ARGONAUT_SET
2086 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2090 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2091 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2093 case GT
: case UNLE
: case GE
: case UNLT
:
2094 code
= swap_condition (code
);
2102 if (cmode
== SFmode
)
2104 emit_insn (gen_cmpsfpx_raw (x
, y
));
2108 /* Accepts Dx regs directly by insns. */
2109 emit_insn (gen_cmpdfpx_raw (x
, y
));
2112 if (mode
!= CC_FPXmode
)
2113 emit_insn (gen_rtx_SET (cc_reg
,
2114 gen_rtx_COMPARE (mode
,
2115 gen_rtx_REG (CC_FPXmode
, 61),
2118 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2122 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2123 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2125 case LT
: case UNGE
: case LE
: case UNGT
:
2126 code
= swap_condition (code
);
2135 emit_insn (gen_cmp_quark (cc_reg
,
2136 gen_rtx_COMPARE (mode
, x
, y
)));
2138 else if (TARGET_HARD_FLOAT
2139 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2140 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2141 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2142 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2144 rtx op0
= gen_rtx_REG (cmode
, 0);
2145 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2150 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2151 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2153 case LT
: case UNGE
: case LE
: case UNGT
:
2154 code
= swap_condition (code
);
2160 if (currently_expanding_to_rtl
)
2168 emit_move_insn (op0
, x
);
2169 emit_move_insn (op1
, y
);
2173 gcc_assert (rtx_equal_p (op0
, x
));
2174 gcc_assert (rtx_equal_p (op1
, y
));
2181 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2184 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2185 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2188 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2189 We assume the value can be either signed or unsigned. */
2192 arc_double_limm_p (rtx value
)
2194 HOST_WIDE_INT low
, high
;
2196 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2201 low
= CONST_DOUBLE_LOW (value
);
2202 high
= CONST_DOUBLE_HIGH (value
);
2204 if (low
& 0x80000000)
2206 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2207 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2208 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2213 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2217 /* Do any needed setup for a variadic function. For the ARC, we must
2218 create a register parameter block, and then copy any anonymous arguments
2219 in registers to memory.
2221 CUM has not been updated for the last named argument which has type TYPE
2222 and mode MODE, and we rely on this fact. */
2225 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2226 machine_mode mode
, tree type
,
2227 int *pretend_size
, int no_rtl
)
2230 CUMULATIVE_ARGS next_cum
;
2232 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2234 next_cum
= *get_cumulative_args (args_so_far
);
2235 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2237 first_anon_arg
= next_cum
;
2239 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2241 /* First anonymous (unnamed) argument is in a reg. */
2243 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2244 int first_reg_offset
= first_anon_arg
;
2249 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2250 FIRST_PARM_OFFSET (0)));
2251 move_block_from_reg (first_reg_offset
, regblock
,
2252 MAX_ARC_PARM_REGS
- first_reg_offset
);
2256 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2260 /* Cost functions. */
2262 /* Provide the costs of an addressing mode that contains ADDR.
2263 If ADDR is not a valid address, its cost is irrelevant. */
2266 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2268 switch (GET_CODE (addr
))
2271 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2272 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2273 case PRE_MODIFY
: case POST_MODIFY
:
2279 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2281 /* Most likely needs a LIMM. */
2282 return COSTS_N_INSNS (1);
2286 register rtx plus0
= XEXP (addr
, 0);
2287 register rtx plus1
= XEXP (addr
, 1);
2289 if (GET_CODE (plus0
) != REG
2290 && (GET_CODE (plus0
) != MULT
2291 || !CONST_INT_P (XEXP (plus0
, 1))
2292 || (INTVAL (XEXP (plus0
, 1)) != 2
2293 && INTVAL (XEXP (plus0
, 1)) != 4)))
2296 switch (GET_CODE (plus1
))
2299 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2303 : (satisfies_constraint_Rcq (plus0
)
2304 && satisfies_constraint_O (plus1
))
2308 return (speed
< 1 ? 0
2309 : (satisfies_constraint_Rcq (plus0
)
2310 && satisfies_constraint_Rcq (plus1
))
2315 return COSTS_N_INSNS (1);
2328 /* Emit instruction X with the frame related bit set. */
2334 RTX_FRAME_RELATED_P (x
) = 1;
2338 /* Emit a frame insn to move SRC to DST. */
2341 frame_move (rtx dst
, rtx src
)
2343 rtx tmp
= gen_rtx_SET (dst
, src
);
2344 RTX_FRAME_RELATED_P (tmp
) = 1;
2345 return frame_insn (tmp
);
2348 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2349 auto increment address, or is zero. */
2352 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2354 rtx insn
= frame_move (dst
, src
);
2357 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2358 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2359 add_reg_note (insn
, REG_INC
, reg
);
2363 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2366 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2368 gcc_assert ((offset
& 0x3) == 0);
2371 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2374 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2377 frame_stack_add (HOST_WIDE_INT offset
)
2379 return frame_add (stack_pointer_rtx
, offset
);
2382 /* Traditionally, we push saved registers first in the prologue,
2383 then we allocate the rest of the frame - and reverse in the epilogue.
2384 This has still its merits for ease of debugging, or saving code size
2385 or even execution time if the stack frame is so large that some accesses
2386 can't be encoded anymore with offsets in the instruction code when using
2388 Also, it would be a good starting point if we got instructions to help
2389 with register save/restore.
2391 However, often stack frames are small, and the pushing / popping has
2393 - the stack modification prevents a lot of scheduling.
2394 - frame allocation / deallocation needs extra instructions.
2395 - unless we know that we compile ARC700 user code, we need to put
2396 a memory barrier after frame allocation / before deallocation to
2397 prevent interrupts clobbering our data in the frame.
2398 In particular, we don't have any such guarantees for library functions,
2399 which tend to, on the other hand, to have small frames.
2401 Thus, for small frames, we'd like to use a different scheme:
2402 - The frame is allocated in full with the first prologue instruction,
2403 and deallocated in full with the last epilogue instruction.
2404 Thus, the instructions in-betwen can be freely scheduled.
2405 - If the function has no outgoing arguments on the stack, we can allocate
2406 one register save slot at the top of the stack. This register can then
2407 be saved simultanously with frame allocation, and restored with
2409 This register can be picked depending on scheduling considerations,
2410 although same though should go into having some set of registers
2411 to be potentially lingering after a call, and others to be available
2412 immediately - i.e. in the absence of interprocedual optimization, we
2413 can use an ABI-like convention for register allocation to reduce
2414 stalls after function return. */
2415 /* Function prologue/epilogue handlers. */
2417 /* ARCompact stack frames look like:
2419 Before call After call
2420 high +-----------------------+ +-----------------------+
2421 mem | reg parm save area | | reg parm save area |
2422 | only created for | | only created for |
2423 | variable arg fns | | variable arg fns |
2424 AP +-----------------------+ +-----------------------+
2425 | return addr register | | return addr register |
2426 | (if required) | | (if required) |
2427 +-----------------------+ +-----------------------+
2429 | reg save area | | reg save area |
2431 +-----------------------+ +-----------------------+
2432 | frame pointer | | frame pointer |
2433 | (if required) | | (if required) |
2434 FP +-----------------------+ +-----------------------+
2436 | local/temp variables | | local/temp variables |
2438 +-----------------------+ +-----------------------+
2440 | arguments on stack | | arguments on stack |
2442 SP +-----------------------+ +-----------------------+
2443 | reg parm save area |
2444 | only created for |
2445 | variable arg fns |
2446 AP +-----------------------+
2447 | return addr register |
2449 +-----------------------+
2453 +-----------------------+
2456 FP +-----------------------+
2458 | local/temp variables |
2460 +-----------------------+
2462 | arguments on stack |
2464 mem SP +-----------------------+
2467 1) The "reg parm save area" does not exist for non variable argument fns.
2468 The "reg parm save area" can be eliminated completely if we created our
2469 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2471 /* Structure to be filled in by arc_compute_frame_size with register
2472 save masks, and offsets for the current function. */
2473 struct GTY (()) arc_frame_info
2475 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2476 unsigned int extra_size
; /* # bytes of extra stuff. */
2477 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2478 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2479 unsigned int reg_size
; /* # bytes needed to store regs. */
2480 unsigned int var_size
; /* # bytes that variables take up. */
2481 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2482 unsigned int gmask
; /* Mask of saved gp registers. */
2483 int initialized
; /* Nonzero if frame size already calculated. */
2484 short millicode_start_reg
;
2485 short millicode_end_reg
;
2486 bool save_return_addr
;
2489 /* Defining data structures for per-function information. */
2491 typedef struct GTY (()) machine_function
2493 unsigned int fn_type
;
2494 struct arc_frame_info frame_info
;
2495 /* To keep track of unalignment caused by short insns. */
2497 int force_short_suffix
; /* Used when disgorging return delay slot insns. */
2498 const char *size_reason
;
2499 struct arc_ccfsm ccfsm_current
;
2500 /* Map from uid to ccfsm state during branch shortening. */
2501 rtx ccfsm_current_insn
;
2502 char arc_reorg_started
;
2503 char prescan_initialized
;
2506 /* Type of function DECL.
2508 The result is cached. To reset the cache at the end of a function,
2509 call with DECL = NULL_TREE. */
2512 arc_compute_function_type (struct function
*fun
)
2514 tree attr
, decl
= fun
->decl
;
2515 unsigned int fn_type
= fun
->machine
->fn_type
;
2517 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2520 /* Check if it is a naked function. */
2521 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2522 fn_type
|= ARC_FUNCTION_NAKED
;
2524 fn_type
|= ARC_FUNCTION_NORMAL
;
2526 /* Now see if this is an interrupt handler. */
2527 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2528 if (attr
!= NULL_TREE
)
2530 tree value
, args
= TREE_VALUE (attr
);
2532 gcc_assert (list_length (args
) == 1);
2533 value
= TREE_VALUE (args
);
2534 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2536 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2537 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2538 fn_type
|= ARC_FUNCTION_ILINK1
;
2539 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2540 fn_type
|= ARC_FUNCTION_ILINK2
;
2541 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2542 fn_type
|= ARC_FUNCTION_FIRQ
;
2547 return fun
->machine
->fn_type
= fn_type
;
2550 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2551 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2553 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2554 The return address and frame pointer are treated separately.
2555 Don't consider them here.
2556 Addition for pic: The gp register needs to be saved if the current
2557 function changes it to access gotoff variables.
2558 FIXME: This will not be needed if we used some arbitrary register
2563 arc_must_save_register (int regno
, struct function
*func
)
2565 unsigned int fn_type
= arc_compute_function_type (func
);
2566 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2567 && ARC_AUTO_IRQ_P (fn_type
));
2568 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2570 switch (rgf_banked_register_count
)
2573 firq_auto_save_p
&= (regno
< 4);
2576 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2579 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2580 || ((regno
> 25) && (regno
< 29))
2581 || ((regno
> 29) && (regno
< 32)));
2584 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2587 firq_auto_save_p
= false;
2591 if ((regno
) != RETURN_ADDR_REGNUM
2592 && (regno
) != FRAME_POINTER_REGNUM
2593 && df_regs_ever_live_p (regno
)
2594 && (!call_used_regs
[regno
]
2595 || ARC_INTERRUPT_P (fn_type
))
2596 /* Do not emit code for auto saved regs. */
2598 && !firq_auto_save_p
)
2601 if (flag_pic
&& crtl
->uses_pic_offset_table
2602 && regno
== PIC_OFFSET_TABLE_REGNUM
)
2608 /* Return true if the return address must be saved in the current function,
2609 otherwise return false. */
2612 arc_must_save_return_addr (struct function
*func
)
2614 if (func
->machine
->frame_info
.save_return_addr
)
2620 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2621 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2622 Register Allocator) pass, while we want to get the frame size
2623 correct earlier than the IRA pass. */
2625 arc_frame_pointer_needed (void)
2627 return (frame_pointer_needed
);
2631 /* Return non-zero if there are registers to be saved or loaded using
2632 millicode thunks. We can only use consecutive sequences starting
2633 with r13, and not going beyond r25.
2634 GMASK is a bitmask of registers to save. This function sets
2635 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2636 of registers to be saved / restored with a millicode call. */
2639 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2640 struct arc_frame_info
*frame
)
2644 int start_reg
= 13, end_reg
= 25;
2646 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2648 end_reg
= regno
- 1;
2649 /* There is no point in using millicode thunks if we don't save/restore
2650 at least three registers. For non-leaf functions we also have the
2652 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2654 frame
->millicode_start_reg
= 13;
2655 frame
->millicode_end_reg
= regno
- 1;
2661 /* Return the bytes needed to compute the frame pointer from the current
2664 SIZE is the size needed for local variables. */
2667 arc_compute_frame_size (int size
) /* size = # of var. bytes allocated. */
2670 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2671 unsigned int reg_size
, reg_offset
;
2673 struct arc_frame_info
*frame_info
= &cfun
->machine
->frame_info
;
2675 size
= ARC_STACK_ALIGN (size
);
2677 /* 1) Size of locals and temporaries */
2680 /* 2) Size of outgoing arguments */
2681 args_size
= crtl
->outgoing_args_size
;
2683 /* 3) Calculate space needed for saved registers.
2684 ??? We ignore the extension registers for now. */
2686 /* See if this is an interrupt handler. Call used registers must be saved
2692 for (regno
= 0; regno
<= 31; regno
++)
2694 if (arc_must_save_register (regno
, cfun
))
2696 reg_size
+= UNITS_PER_WORD
;
2697 gmask
|= 1L << regno
;
2701 /* 4) Space for back trace data structure.
2702 <return addr reg size> (if required) + <fp size> (if required). */
2703 frame_info
->save_return_addr
2704 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
));
2705 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2706 if (optimize_size
&& !TARGET_NO_MILLICODE_THUNK_SET
)
2708 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2709 frame_info
->save_return_addr
= true;
2713 if (arc_must_save_return_addr (cfun
))
2715 if (arc_frame_pointer_needed ())
2718 /* 5) Space for variable arguments passed in registers */
2719 pretend_size
= crtl
->args
.pretend_args_size
;
2721 /* Ensure everything before the locals is aligned appropriately. */
2723 unsigned int extra_plus_reg_size
;
2724 unsigned int extra_plus_reg_size_aligned
;
2726 extra_plus_reg_size
= extra_size
+ reg_size
;
2727 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2728 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2731 /* Compute total frame size. */
2732 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2734 total_size
= ARC_STACK_ALIGN (total_size
);
2736 /* Compute offset of register save area from stack pointer:
2737 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2739 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2740 + (arc_frame_pointer_needed () ? 4 : 0));
2742 /* Save computed information. */
2743 frame_info
->total_size
= total_size
;
2744 frame_info
->extra_size
= extra_size
;
2745 frame_info
->pretend_size
= pretend_size
;
2746 frame_info
->var_size
= var_size
;
2747 frame_info
->args_size
= args_size
;
2748 frame_info
->reg_size
= reg_size
;
2749 frame_info
->reg_offset
= reg_offset
;
2750 frame_info
->gmask
= gmask
;
2751 frame_info
->initialized
= reload_completed
;
2753 /* Ok, we're done. */
2757 /* Common code to save/restore registers. */
2758 /* BASE_REG is the base register to use for addressing and to adjust.
2759 GMASK is a bitmask of general purpose registers to save/restore.
2760 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2761 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2762 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2766 arc_save_restore (rtx base_reg
,
2767 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2769 unsigned int offset
= 0;
2771 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2772 rtx sibthunk_insn
= NULL_RTX
;
2776 /* Millicode thunks implementation:
2777 Generates calls to millicodes for registers starting from r13 to r25
2778 Present Limitations:
2779 - Only one range supported. The remaining regs will have the ordinary
2780 st and ld instructions for store and loads. Hence a gmask asking
2781 to store r13-14, r16-r25 will only generate calls to store and
2782 load r13 to r14 while store and load insns will be generated for
2783 r16 to r25 in the prologue and epilogue respectively.
2785 - Presently library only supports register ranges starting from r13.
2787 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2789 int start_call
= frame
->millicode_start_reg
;
2790 int end_call
= frame
->millicode_end_reg
;
2791 int n_regs
= end_call
- start_call
+ 1;
2792 int i
= 0, r
, off
= 0;
2794 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2798 /* "reg_size" won't be more than 127 . */
2799 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
2800 frame_add (base_reg
, *first_offset
);
2803 insn
= gen_rtx_PARALLEL
2804 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
2805 if (epilogue_p
== 2)
2808 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
2809 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
2811 rtx reg
= gen_rtx_REG (SImode
, r
);
2813 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
2816 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
2818 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
2819 gmask
= gmask
& ~(1L << r
);
2821 if (epilogue_p
== 2)
2822 sibthunk_insn
= insn
;
2825 insn
= frame_insn (insn
);
2827 for (r
= start_call
; r
<= end_call
; r
++)
2829 rtx reg
= gen_rtx_REG (SImode
, r
);
2830 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2836 for (regno
= 0; regno
<= 31; regno
++)
2838 machine_mode mode
= SImode
;
2843 && ((gmask
& (1L << regno
)) != 0)
2844 && ((gmask
& (1L << (regno
+1))) != 0))
2849 else if ((gmask
& (1L << regno
)) != 0)
2857 rtx reg
= gen_rtx_REG (mode
, regno
);
2859 int cfa_adjust
= *first_offset
;
2863 gcc_assert (!offset
);
2864 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
2865 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
2870 gcc_assert (SMALL_INT (offset
));
2871 addr
= plus_constant (Pmode
, base_reg
, offset
);
2873 mem
= gen_frame_mem (mode
, addr
);
2877 frame_move_inc (reg
, mem
, base_reg
, addr
);
2878 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2881 enum reg_note note
= REG_CFA_ADJUST_CFA
;
2882 add_reg_note (insn
, note
,
2883 gen_rtx_SET (stack_pointer_rtx
,
2884 plus_constant (Pmode
,
2890 frame_move_inc (mem
, reg
, base_reg
, addr
);
2891 offset
+= UNITS_PER_WORD
;
2894 offset
+= UNITS_PER_WORD
;
2902 int start_call
= frame
->millicode_start_reg
;
2903 int end_call
= frame
->millicode_end_reg
;
2906 rtx r12
= gen_rtx_REG (Pmode
, 12);
2908 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
2909 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
2910 XVECEXP (sibthunk_insn
, 0, 1)
2911 = gen_rtx_SET (stack_pointer_rtx
,
2912 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
2913 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
2914 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
2916 /* Would be nice if we could do this earlier, when the PARALLEL
2917 is populated, but these need to be attached after the
2919 for (r
= start_call
; r
<= end_call
; r
++)
2921 rtx reg
= gen_rtx_REG (SImode
, r
);
2922 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
2925 } /* arc_save_restore */
2927 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2931 arc_dwarf_emit_irq_save_regs (void)
2933 rtx tmp
, par
, insn
, reg
;
2936 par
= gen_rtx_SEQUENCE (VOIDmode
,
2937 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2938 + irq_ctrl_saved
.irq_save_blink
2939 + irq_ctrl_saved
.irq_save_lpcount
2942 /* Build the stack adjustment note for unwind info. */
2944 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2945 + irq_ctrl_saved
.irq_save_blink
2946 + irq_ctrl_saved
.irq_save_lpcount
);
2947 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2948 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2949 RTX_FRAME_RELATED_P (tmp
) = 1;
2950 XVECEXP (par
, 0, j
++) = tmp
;
2952 offset
-= UNITS_PER_WORD
;
2954 /* 1st goes LP_COUNT. */
2955 if (irq_ctrl_saved
.irq_save_lpcount
)
2957 reg
= gen_rtx_REG (SImode
, 60);
2958 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2959 tmp
= gen_frame_mem (SImode
, tmp
);
2960 tmp
= gen_rtx_SET (tmp
, reg
);
2961 RTX_FRAME_RELATED_P (tmp
) = 1;
2962 XVECEXP (par
, 0, j
++) = tmp
;
2963 offset
-= UNITS_PER_WORD
;
2966 /* 2nd goes BLINK. */
2967 if (irq_ctrl_saved
.irq_save_blink
)
2969 reg
= gen_rtx_REG (SImode
, 31);
2970 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2971 tmp
= gen_frame_mem (SImode
, tmp
);
2972 tmp
= gen_rtx_SET (tmp
, reg
);
2973 RTX_FRAME_RELATED_P (tmp
) = 1;
2974 XVECEXP (par
, 0, j
++) = tmp
;
2975 offset
-= UNITS_PER_WORD
;
2978 /* Build the parallel of the remaining registers recorded as saved
2980 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
2982 reg
= gen_rtx_REG (SImode
, i
);
2983 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2984 tmp
= gen_frame_mem (SImode
, tmp
);
2985 tmp
= gen_rtx_SET (tmp
, reg
);
2986 RTX_FRAME_RELATED_P (tmp
) = 1;
2987 XVECEXP (par
, 0, j
++) = tmp
;
2988 offset
-= UNITS_PER_WORD
;
2991 /* Dummy insn used to anchor the dwarf info. */
2992 insn
= emit_insn (gen_stack_irq_dwarf());
2993 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
2994 RTX_FRAME_RELATED_P (insn
) = 1;
2997 /* Set up the stack and frame pointer (if desired) for the function. */
3000 arc_expand_prologue (void)
3002 int size
= get_frame_size ();
3003 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
3004 /* unsigned int frame_pointer_offset;*/
3005 unsigned int frame_size_to_allocate
;
3006 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
3007 Change the stack layout so that we rather store a high register with the
3008 PRE_MODIFY, thus enabling more short insn generation.) */
3009 int first_offset
= 0;
3010 unsigned int fn_type
= arc_compute_function_type (cfun
);
3012 /* Naked functions don't have prologue. */
3013 if (ARC_NAKED_P (fn_type
))
3016 size
= ARC_STACK_ALIGN (size
);
3018 /* Compute/get total frame size. */
3019 size
= (!cfun
->machine
->frame_info
.initialized
3020 ? arc_compute_frame_size (size
)
3021 : cfun
->machine
->frame_info
.total_size
);
3023 if (flag_stack_usage_info
)
3024 current_function_static_stack_size
= size
;
3026 /* Keep track of frame size to be allocated. */
3027 frame_size_to_allocate
= size
;
3029 /* These cases shouldn't happen. Catch them now. */
3030 gcc_assert (!(size
== 0 && gmask
));
3032 /* Allocate space for register arguments if this is a variadic function. */
3033 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
3035 /* Ensure pretend_size is maximum of 8 * word_size. */
3036 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
3038 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
3039 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
3042 /* IRQ using automatic save mechanism will save the register before
3044 if (ARC_AUTO_IRQ_P (fn_type
)
3045 && !ARC_FAST_INTERRUPT_P (fn_type
))
3047 arc_dwarf_emit_irq_save_regs ();
3050 /* The home-grown ABI says link register is saved first. */
3051 if (arc_must_save_return_addr (cfun
)
3052 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3054 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
3055 rtx mem
= gen_frame_mem (Pmode
,
3056 gen_rtx_PRE_DEC (Pmode
,
3057 stack_pointer_rtx
));
3059 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
3060 frame_size_to_allocate
-= UNITS_PER_WORD
;
3063 /* Save any needed call-saved regs (and call-used if this is an
3064 interrupt handler) for ARCompact ISA. */
3065 if (cfun
->machine
->frame_info
.reg_size
)
3067 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
3068 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3069 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
3070 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
3073 /* Save frame pointer if needed. First save the FP on stack, if not
3075 if (arc_frame_pointer_needed ()
3076 && !ARC_AUTOFP_IRQ_P (fn_type
))
3078 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3079 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
3080 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
3083 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
3084 frame_size_to_allocate
-= UNITS_PER_WORD
;
3088 /* Emit mov fp,sp. */
3089 if (arc_frame_pointer_needed ())
3091 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3094 /* ??? We don't handle the case where the saved regs are more than 252
3095 bytes away from sp. This can be handled by decrementing sp once, saving
3096 the regs, and then decrementing it again. The epilogue doesn't have this
3097 problem as the `ld' insn takes reg+limm values (though it would be more
3098 efficient to avoid reg+limm). */
3100 frame_size_to_allocate
-= first_offset
;
3101 /* Allocate the stack frame. */
3102 if (frame_size_to_allocate
> 0)
3104 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3105 /* If the frame pointer is needed, emit a special barrier that
3106 will prevent the scheduler from moving stores to the frame
3107 before the stack adjustment. */
3108 if (arc_frame_pointer_needed ())
3109 emit_insn (gen_stack_tie (stack_pointer_rtx
,
3110 hard_frame_pointer_rtx
));
3113 /* Setup the gp register, if needed. */
3114 if (crtl
->uses_pic_offset_table
)
3115 arc_finalize_pic ();
3118 /* Do any necessary cleanup after a function to restore stack, frame,
3122 arc_expand_epilogue (int sibcall_p
)
3124 int size
= get_frame_size ();
3125 unsigned int fn_type
= arc_compute_function_type (cfun
);
3127 size
= ARC_STACK_ALIGN (size
);
3128 size
= (!cfun
->machine
->frame_info
.initialized
3129 ? arc_compute_frame_size (size
)
3130 : cfun
->machine
->frame_info
.total_size
);
3132 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
3133 unsigned int frame_size
;
3134 unsigned int size_to_deallocate
;
3136 int can_trust_sp_p
= !cfun
->calls_alloca
;
3137 int first_offset
= 0;
3138 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
3141 /* Naked functions don't have epilogue. */
3142 if (ARC_NAKED_P (fn_type
))
3145 size_to_deallocate
= size
;
3147 frame_size
= size
- (pretend_size
+
3148 cfun
->machine
->frame_info
.reg_size
+
3149 cfun
->machine
->frame_info
.extra_size
);
3151 /* ??? There are lots of optimizations that can be done here.
3152 EG: Use fp to restore regs if it's closer.
3153 Maybe in time we'll do them all. For now, always restore regs from
3154 sp, but don't restore sp if we don't have to. */
3156 if (!can_trust_sp_p
)
3157 gcc_assert (arc_frame_pointer_needed ());
3159 /* Restore stack pointer to the beginning of saved register area for
3163 if (arc_frame_pointer_needed ())
3164 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3166 first_offset
= frame_size
;
3167 size_to_deallocate
-= frame_size
;
3169 else if (!can_trust_sp_p
)
3170 frame_stack_add (-frame_size
);
3173 /* Restore any saved registers. */
3174 if (arc_frame_pointer_needed ()
3175 && !ARC_AUTOFP_IRQ_P (fn_type
))
3177 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
3179 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
3180 stack_pointer_rtx
, 0);
3181 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3182 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3183 plus_constant (SImode
, stack_pointer_rtx
,
3185 size_to_deallocate
-= UNITS_PER_WORD
;
3188 /* Load blink after the calls to thunk calls in case of optimize size. */
3191 int sibthunk_p
= (!sibcall_p
3192 && fn_type
== ARC_FUNCTION_NORMAL
3193 && !cfun
->machine
->frame_info
.pretend_size
);
3195 gcc_assert (!(cfun
->machine
->frame_info
.gmask
3196 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
3197 arc_save_restore (stack_pointer_rtx
,
3198 cfun
->machine
->frame_info
.gmask
,
3199 1 + sibthunk_p
, &first_offset
);
3203 /* If we are to restore registers, and first_offset would require
3204 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3205 fast add to the stack pointer, do this now. */
3206 if ((!SMALL_INT (first_offset
)
3207 && cfun
->machine
->frame_info
.gmask
3208 && ((TARGET_ARC700
&& !optimize_size
)
3209 ? first_offset
<= 0x800
3210 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
3211 /* Also do this if we have both gprs and return
3212 address to restore, and they both would need a LIMM. */
3213 || (arc_must_save_return_addr (cfun
)
3214 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
3215 && cfun
->machine
->frame_info
.gmask
))
3217 frame_stack_add (first_offset
);
3220 if (arc_must_save_return_addr (cfun
)
3221 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3223 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3224 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
3225 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
3226 HOST_WIDE_INT cfa_adjust
= 0;
3228 /* If the load of blink would need a LIMM, but we can add
3229 the offset quickly to sp, do the latter. */
3230 if (!SMALL_INT (ra_offs
>> 2)
3231 && !cfun
->machine
->frame_info
.gmask
3232 && ((TARGET_ARC700
&& !optimize_size
)
3234 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
3236 size_to_deallocate
-= ra_offs
- first_offset
;
3238 frame_stack_add (ra_offs
);
3240 addr
= stack_pointer_rtx
;
3242 /* See if we can combine the load of the return address with the
3243 final stack adjustment.
3244 We need a separate load if there are still registers to
3245 restore. We also want a separate load if the combined insn
3246 would need a limm, but a separate load doesn't. */
3248 && !cfun
->machine
->frame_info
.gmask
3249 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
3251 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
3252 cfa_adjust
= ra_offs
;
3254 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
3256 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
3258 addr
= gen_rtx_POST_INC (Pmode
, addr
);
3259 cfa_adjust
= GET_MODE_SIZE (Pmode
);
3260 size_to_deallocate
= 0;
3263 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
3264 stack_pointer_rtx
, addr
);
3267 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3269 add_reg_note (insn
, note
,
3270 gen_rtx_SET (stack_pointer_rtx
,
3271 plus_constant (SImode
, stack_pointer_rtx
,
3274 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
3279 if (cfun
->machine
->frame_info
.reg_size
)
3280 arc_save_restore (stack_pointer_rtx
,
3281 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3282 cfun
->machine
->frame_info
.gmask
3283 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
3286 /* The rest of this function does the following:
3287 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3290 /* Keep track of how much of the stack pointer we've restored.
3291 It makes the following a lot more readable. */
3292 size_to_deallocate
+= first_offset
;
3293 restored
= size
- size_to_deallocate
;
3295 if (size
> restored
)
3296 frame_stack_add (size
- restored
);
3298 /* Emit the return instruction. */
3299 if (sibcall_p
== FALSE
)
3300 emit_jump_insn (gen_simple_return ());
3303 /* Return the offset relative to the stack pointer where the return address
3304 is stored, or -1 if it is not stored. */
3307 arc_return_slot_offset ()
3309 struct arc_frame_info
*afi
= &cfun
->machine
->frame_info
;
3311 return (afi
->save_return_addr
3312 ? afi
->total_size
- afi
->pretend_size
- afi
->extra_size
: -1);
3317 /* Helper to generate unspec constant. */
3320 arc_unspec_offset (rtx loc
, int unspec
)
3322 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3326 /* Emit special PIC prologues and epilogues. */
3327 /* If the function has any GOTOFF relocations, then the GOTBASE
3328 register has to be setup in the prologue
3329 The instruction needed at the function start for setting up the
3332 ----------------------------------------------------------
3333 The rtl to be emitted for this should be:
3336 (const (unspec (symref _DYNAMIC) 3)))
3337 ---------------------------------------------------------- */
3340 arc_finalize_pic (void)
3343 rtx baseptr_rtx
= gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
);
3345 if (crtl
->uses_pic_offset_table
== 0)
3348 gcc_assert (flag_pic
!= 0);
3350 pat
= gen_rtx_SYMBOL_REF (Pmode
, "_DYNAMIC");
3351 pat
= arc_unspec_offset (pat
, ARC_UNSPEC_GOT
);
3352 pat
= gen_rtx_SET (baseptr_rtx
, pat
);
3357 /* !TARGET_BARREL_SHIFTER support. */
3358 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3362 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3364 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3366 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3367 (op0
, op1
, op2
, shift
));
3371 /* Output the assembler code for doing a shift.
3372 We go to a bit of trouble to generate efficient code as the ARC601 only has
3373 single bit shifts. This is taken from the h8300 port. We only have one
3374 mode of shifting and can't access individual bytes like the h8300 can, so
3375 this is greatly simplified (at the expense of not generating hyper-
3378 This function is not used if the variable shift insns are present. */
3380 /* FIXME: This probably can be done using a define_split in arc.md.
3381 Alternately, generate rtx rather than output instructions. */
3384 output_shift (rtx
*operands
)
3386 /* static int loopend_lab;*/
3387 rtx shift
= operands
[3];
3388 machine_mode mode
= GET_MODE (shift
);
3389 enum rtx_code code
= GET_CODE (shift
);
3390 const char *shift_one
;
3392 gcc_assert (mode
== SImode
);
3396 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3397 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3398 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3399 default: gcc_unreachable ();
3402 if (GET_CODE (operands
[2]) != CONST_INT
)
3404 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3411 n
= INTVAL (operands
[2]);
3413 /* Only consider the lower 5 bits of the shift count. */
3416 /* First see if we can do them inline. */
3417 /* ??? We could get better scheduling & shorter code (using short insns)
3418 by using splitters. Alas, that'd be even more verbose. */
3419 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3420 && dest_reg_operand (operands
[4], SImode
))
3422 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3423 for (n
-=3 ; n
>= 3; n
-= 3)
3424 output_asm_insn ("add3 %0,%4,%0", operands
);
3426 output_asm_insn ("add2 %0,%4,%0", operands
);
3428 output_asm_insn ("add %0,%0,%0", operands
);
3434 output_asm_insn (shift_one
, operands
);
3435 operands
[1] = operands
[0];
3438 /* See if we can use a rotate/and. */
3439 else if (n
== BITS_PER_WORD
- 1)
3444 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3447 /* The ARC doesn't have a rol insn. Use something else. */
3448 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
3451 /* The ARC doesn't have a rol insn. Use something else. */
3452 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
3458 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
3463 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
3466 #if 1 /* Need some scheduling comparisons. */
3467 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3468 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3470 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3471 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
3476 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3477 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3479 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3480 "and %0,%0,1\n\trlc %0,%0", operands
);
3487 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
3488 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3493 operands
[2] = GEN_INT (n
);
3494 output_asm_insn ("mov.f lp_count, %2", operands
);
3498 output_asm_insn ("lpnz\t2f", operands
);
3499 output_asm_insn (shift_one
, operands
);
3500 output_asm_insn ("nop", operands
);
3501 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
3510 /* Nested function support. */
3512 /* Directly store VALUE into memory object BLOCK at OFFSET. */
3515 emit_store_direct (rtx block
, int offset
, int value
)
3517 emit_insn (gen_store_direct (adjust_address (block
, SImode
, offset
),
3519 gen_int_mode (value
, SImode
))));
3522 /* Emit RTL insns to initialize the variable parts of a trampoline.
3523 FNADDR is an RTX for the address of the function's pure code.
3524 CXT is an RTX for the static chain value for the function. */
3525 /* With potentially multiple shared objects loaded, and multiple stacks
3526 present for multiple thereds where trampolines might reside, a simple
3527 range check will likely not suffice for the profiler to tell if a callee
3528 is a trampoline. We a speedier check by making the trampoline start at
3529 an address that is not 4-byte aligned.
3530 A trampoline looks like this:
3534 ld_s r12,[pcl,12] 0xd403
3535 ld r11,[pcl,12] 0x170c 700b
3539 The fastest trampoline to execute for trampolines within +-8KB of CTX
3542 j [limm] 0x20200f80 limm
3543 and that would also be faster to write to the stack by computing the offset
3544 from CTX to TRAMP at compile time. However, it would really be better to
3545 get rid of the high cost of cache invalidation when generating trampolines,
3546 which requires that the code part of trampolines stays constant, and
3548 - making sure that no executable code but trampolines is on the stack,
3549 no icache entries linger for the area of the stack from when before the
3550 stack was allocated, and allocating trampolines in trampoline-only
3553 - allocate trampolines fram a special pool of pre-allocated trampolines. */
3556 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
3558 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3560 emit_store_direct (tramp
, 0, TARGET_BIG_ENDIAN
? 0x78e0d403 : 0xd40378e0);
3561 emit_store_direct (tramp
, 4, TARGET_BIG_ENDIAN
? 0x170c700b : 0x700b170c);
3562 emit_store_direct (tramp
, 8, TARGET_BIG_ENDIAN
? 0x7c0078e0 : 0x78e07c00);
3563 emit_move_insn (adjust_address (tramp
, SImode
, 12), fnaddr
);
3564 emit_move_insn (adjust_address (tramp
, SImode
, 16), cxt
);
3565 emit_insn (gen_flush_icache (adjust_address (tramp
, SImode
, 0)));
3568 /* Allow the profiler to easily distinguish trampolines from normal
3572 arc_trampoline_adjust_address (rtx addr
)
3574 return plus_constant (Pmode
, addr
, 2);
3577 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3578 reset when we output the scaled address. */
3579 static int output_scaled
= 0;
3581 /* Print operand X (an rtx) in assembler syntax to file FILE.
3582 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3583 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3584 /* In final.c:output_asm_insn:
3587 'c' : constant address if CONSTANT_ADDRESS_P
3593 'p': bit Position of lsb
3594 's': size of bit field
3595 '#': condbranch delay slot suffix
3596 '*': jump delay slot suffix
3597 '?' : nonjump-insn suffix for conditional execution or short instruction
3598 '!' : jump / call suffix for conditional execution or short instruction
3599 '`': fold constant inside unary o-perator, re-recognize, and emit.
3604 'B': Branch comparison operand - suppress sda reference
3605 'H': Most significant word
3606 'L': Least significant word
3607 'A': ASCII decimal representation of floating point value
3608 'U': Load/store update or scaling indicator
3609 'V': cache bypass indicator for volatile
3614 'o': original symbol - no @ prepending. */
3617 arc_print_operand (FILE *file
, rtx x
, int code
)
3622 if (GET_CODE (x
) == CONST_INT
)
3623 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3625 output_operand_lossage ("invalid operand to %%Z code");
3630 if (GET_CODE (x
) == CONST_INT
)
3631 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3633 output_operand_lossage ("invalid operand to %%z code");
3638 if (GET_CODE (x
) == CONST_INT
)
3639 fprintf (file
, "%d", INTVAL (x
) );
3641 output_operand_lossage ("invalid operands to %%c code");
3646 if (GET_CODE (x
) == CONST_INT
)
3647 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3649 output_operand_lossage ("invalid operand to %%M code");
3654 if (GET_CODE (x
) == CONST_INT
)
3655 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3657 output_operand_lossage ("invalid operand to %%p code");
3661 if (GET_CODE (x
) == CONST_INT
)
3663 HOST_WIDE_INT i
= INTVAL (x
);
3664 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3665 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3668 output_operand_lossage ("invalid operand to %%s code");
3672 /* Conditional branches depending on condition codes.
3673 Note that this is only for branches that were known to depend on
3674 condition codes before delay slot scheduling;
3675 out-of-range brcc / bbit expansions should use '*'.
3676 This distinction is important because of the different
3677 allowable delay slot insns and the output of the delay suffix
3678 for TARGET_AT_DBR_COND_EXEC. */
3680 /* Unconditional branches / branches not depending on condition codes.
3681 This could also be a CALL_INSN.
3682 Output the appropriate delay slot suffix. */
3683 if (final_sequence
&& final_sequence
->len () != 1)
3685 rtx_insn
*jump
= final_sequence
->insn (0);
3686 rtx_insn
*delay
= final_sequence
->insn (1);
3688 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3689 if (delay
->deleted ())
3691 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3692 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3693 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3694 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3701 case '?' : /* with leading "." */
3702 case '!' : /* without leading "." */
3703 /* This insn can be conditionally executed. See if the ccfsm machinery
3704 says it should be conditionalized.
3705 If it shouldn't, we'll check the compact attribute if this insn
3706 has a short variant, which may be used depending on code size and
3707 alignment considerations. */
3708 if (current_insn_predicate
)
3709 arc_ccfsm_current
.cc
3710 = get_arc_condition_code (current_insn_predicate
);
3711 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3713 /* Is this insn in a delay slot sequence? */
3714 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3715 || current_insn_predicate
3716 || CALL_P (final_sequence
->insn (0))
3717 || simplejump_p (final_sequence
->insn (0)))
3719 /* This insn isn't in a delay slot sequence, or conditionalized
3720 independently of its position in a delay slot. */
3721 fprintf (file
, "%s%s",
3722 code
== '?' ? "." : "",
3723 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3724 /* If this is a jump, there are still short variants. However,
3725 only beq_s / bne_s have the same offset range as b_s,
3726 and the only short conditional returns are jeq_s and jne_s. */
3728 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3729 || arc_ccfsm_current
.cc
== ARC_CC_NE
3730 || 0 /* FIXME: check if branch in 7 bit range. */))
3731 output_short_suffix (file
);
3733 else if (code
== '!') /* Jump with delay slot. */
3734 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
3735 else /* An Instruction in a delay slot of a jump or call. */
3737 rtx jump
= XVECEXP (final_sequence
, 0, 0);
3738 rtx insn
= XVECEXP (final_sequence
, 0, 1);
3740 /* If the insn is annulled and is from the target path, we need
3741 to inverse the condition test. */
3742 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3744 if (INSN_FROM_TARGET_P (insn
))
3745 fprintf (file
, "%s%s",
3746 code
== '?' ? "." : "",
3747 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
3749 fprintf (file
, "%s%s",
3750 code
== '?' ? "." : "",
3751 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3752 if (arc_ccfsm_current
.state
== 5)
3753 arc_ccfsm_current
.state
= 0;
3756 /* This insn is executed for either path, so don't
3757 conditionalize it at all. */
3758 output_short_suffix (file
);
3763 output_short_suffix (file
);
3766 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3769 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
3772 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
3773 (get_arc_condition_code (x
))],
3777 /* Write second word of DImode or DFmode reference,
3778 register or memory. */
3779 if (GET_CODE (x
) == REG
)
3780 fputs (reg_names
[REGNO (x
)+1], file
);
3781 else if (GET_CODE (x
) == MEM
)
3785 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3786 PRE_MODIFY, we will have handled the first word already;
3787 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3788 first word will be done later. In either case, the access
3789 to the first word will do the modify, and we only have
3790 to add an offset of four here. */
3791 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
3792 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
3793 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
3794 || GET_CODE (XEXP (x
, 0)) == POST_INC
3795 || GET_CODE (XEXP (x
, 0)) == POST_DEC
3796 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
3797 output_address (VOIDmode
,
3798 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
3799 else if (output_scaled
)
3801 rtx addr
= XEXP (x
, 0);
3802 int size
= GET_MODE_SIZE (GET_MODE (x
));
3804 output_address (VOIDmode
,
3805 plus_constant (Pmode
, XEXP (addr
, 0),
3806 ((INTVAL (XEXP (addr
, 1)) + 4)
3807 >> (size
== 2 ? 1 : 2))));
3811 output_address (VOIDmode
,
3812 plus_constant (Pmode
, XEXP (x
, 0), 4));
3816 output_operand_lossage ("invalid operand to %%R code");
3819 /* FIXME: remove %S option. */
3821 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3824 output_addr_const (file
, x
);
3830 if (GET_CODE (x
) == REG
)
3832 /* L = least significant word, H = most significant word. */
3833 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
3834 fputs (reg_names
[REGNO (x
)], file
);
3836 fputs (reg_names
[REGNO (x
)+1], file
);
3838 else if (GET_CODE (x
) == CONST_INT
3839 || GET_CODE (x
) == CONST_DOUBLE
)
3841 rtx first
, second
, word
;
3843 split_double (x
, &first
, &second
);
3845 if((WORDS_BIG_ENDIAN
) == 0)
3846 word
= (code
== 'L' ? first
: second
);
3848 word
= (code
== 'L' ? second
: first
);
3850 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
3853 output_operand_lossage ("invalid operand to %%H/%%L code");
3859 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
3860 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
3862 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
3863 fprintf (file
, "%s", str
);
3867 /* Output a load/store with update indicator if appropriate. */
3868 if (GET_CODE (x
) == MEM
)
3870 rtx addr
= XEXP (x
, 0);
3871 switch (GET_CODE (addr
))
3873 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
3874 fputs (".a", file
); break;
3875 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
3876 fputs (".ab", file
); break;
3878 /* Are we using a scaled index? */
3879 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3880 fputs (".as", file
);
3881 /* Can we use a scaled offset? */
3882 else if (CONST_INT_P (XEXP (addr
, 1))
3883 && GET_MODE_SIZE (GET_MODE (x
)) > 1
3884 && (!(INTVAL (XEXP (addr
, 1))
3885 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
3886 /* Does it make a difference? */
3887 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
3888 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
3890 fputs (".as", file
);
3893 else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
)
3894 && GET_MODE_SIZE (GET_MODE (x
)) > 1)
3896 tree decl
= NULL_TREE
;
3898 if (GET_CODE (XEXP (addr
, 1)) == SYMBOL_REF
)
3899 decl
= SYMBOL_REF_DECL (XEXP (addr
, 1));
3900 else if (GET_CODE (XEXP (XEXP (XEXP (addr
, 1), 0), 0))
3902 decl
= SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr
, 1), 0), 0));
3904 align
= DECL_ALIGN (decl
);
3905 align
= align
/ BITS_PER_UNIT
;
3906 if ((GET_MODE_SIZE (GET_MODE (x
)) == 2)
3907 && align
&& ((align
& 1) == 0))
3908 fputs (".as", file
);
3909 if ((GET_MODE_SIZE (GET_MODE (x
)) >= 4)
3910 && align
&& ((align
& 3) == 0))
3911 fputs (".as", file
);
3917 gcc_assert (CONSTANT_P (addr
)); break;
3921 output_operand_lossage ("invalid operand to %%U code");
3924 /* Output cache bypass indicator for a load/store insn. Volatile memory
3925 refs are defined to use the cache bypass mechanism. */
3926 if (GET_CODE (x
) == MEM
)
3928 if (MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
3929 fputs (".di", file
);
3932 output_operand_lossage ("invalid operand to %%V code");
3937 /* Do nothing special. */
3940 fputs (reg_names
[REGNO (x
)]+1, file
);
3943 /* This punctuation character is needed because label references are
3944 printed in the output template using %l. This is a front end
3945 character, and when we want to emit a '@' before it, we have to use
3951 /* Output an operator. */
3952 switch (GET_CODE (x
))
3954 case PLUS
: fputs ("add", file
); return;
3955 case SS_PLUS
: fputs ("adds", file
); return;
3956 case AND
: fputs ("and", file
); return;
3957 case IOR
: fputs ("or", file
); return;
3958 case XOR
: fputs ("xor", file
); return;
3959 case MINUS
: fputs ("sub", file
); return;
3960 case SS_MINUS
: fputs ("subs", file
); return;
3961 case ASHIFT
: fputs ("asl", file
); return;
3962 case ASHIFTRT
: fputs ("asr", file
); return;
3963 case LSHIFTRT
: fputs ("lsr", file
); return;
3964 case ROTATERT
: fputs ("ror", file
); return;
3965 case MULT
: fputs ("mpy", file
); return;
3966 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
3967 case NEG
: fputs ("neg", file
); return;
3968 case SS_NEG
: fputs ("negs", file
); return;
3969 case NOT
: fputs ("not", file
); return; /* Unconditional. */
3971 fputs ("ext", file
); /* bmsk allows predication. */
3973 case SIGN_EXTEND
: /* Unconditional. */
3974 fputs ("sex", file
);
3976 switch (GET_MODE (XEXP (x
, 0)))
3978 case E_QImode
: fputs ("b", file
); return;
3979 case E_HImode
: fputs ("w", file
); return;
3984 if (GET_MODE (x
) != HImode
)
3986 fputs ("sat16", file
);
3989 output_operand_lossage ("invalid operand to %%O code"); return;
3991 if (GET_CODE (x
) == SYMBOL_REF
)
3993 assemble_name (file
, XSTR (x
, 0));
3998 if (TARGET_ANNOTATE_ALIGN
&& cfun
->machine
->size_reason
)
3999 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
4015 output_operand_lossage ("invalid operand output code");
4018 switch (GET_CODE (x
))
4021 fputs (reg_names
[REGNO (x
)], file
);
4025 rtx addr
= XEXP (x
, 0);
4026 int size
= GET_MODE_SIZE (GET_MODE (x
));
4030 switch (GET_CODE (addr
))
4032 case PRE_INC
: case POST_INC
:
4033 output_address (VOIDmode
,
4034 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
4035 case PRE_DEC
: case POST_DEC
:
4036 output_address (VOIDmode
,
4037 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
4039 case PRE_MODIFY
: case POST_MODIFY
:
4040 output_address (VOIDmode
, XEXP (addr
, 1)); break;
4044 output_address (VOIDmode
,
4045 plus_constant (Pmode
, XEXP (addr
, 0),
4046 (INTVAL (XEXP (addr
, 1))
4047 >> (size
== 2 ? 1 : 2))));
4051 output_address (VOIDmode
, addr
);
4054 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
4055 arc_output_pic_addr_const (file
, addr
, code
);
4057 output_address (VOIDmode
, addr
);
4064 /* We handle SFmode constants here as output_addr_const doesn't. */
4065 if (GET_MODE (x
) == SFmode
)
4069 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
4070 fprintf (file
, "0x%08lx", l
);
4074 /* Let output_addr_const deal with it. */
4077 || (GET_CODE (x
) == CONST
4078 && GET_CODE (XEXP (x
, 0)) == UNSPEC
4079 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
4080 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
4081 || (GET_CODE (x
) == CONST
4082 && GET_CODE (XEXP (x
, 0)) == PLUS
4083 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
4084 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
4085 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
4086 arc_output_pic_addr_const (file
, x
, code
);
4089 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
4090 with asm_output_symbol_ref */
4091 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
)
4094 output_addr_const (file
, XEXP (x
, 0));
4095 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (XEXP (x
, 0)))
4096 fprintf (file
, "@sda");
4098 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
4099 || INTVAL (XEXP (x
, 1)) >= 0)
4100 fprintf (file
, "+");
4101 output_addr_const (file
, XEXP (x
, 1));
4104 output_addr_const (file
, x
);
4106 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
4107 fprintf (file
, "@sda");
4112 /* Print a memory address as an operand to reference that memory location. */
4115 arc_print_operand_address (FILE *file
, rtx addr
)
4117 register rtx base
, index
= 0;
4119 switch (GET_CODE (addr
))
4122 fputs (reg_names
[REGNO (addr
)], file
);
4125 output_addr_const (file
, addr
);
4126 if (SYMBOL_REF_SMALL_P (addr
))
4127 fprintf (file
, "@sda");
4130 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4131 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
4132 else if (CONST_INT_P (XEXP (addr
, 0)))
4133 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
4135 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
4137 gcc_assert (OBJECT_P (base
));
4138 arc_print_operand_address (file
, base
);
4139 if (CONSTANT_P (base
) && CONST_INT_P (index
))
4143 gcc_assert (OBJECT_P (index
));
4144 arc_print_operand_address (file
, index
);
4148 rtx c
= XEXP (addr
, 0);
4150 if ((GET_CODE (c
) == UNSPEC
4151 && (XINT (c
, 1) == UNSPEC_TLS_OFF
4152 || XINT (c
, 1) == UNSPEC_TLS_IE
))
4153 || (GET_CODE (c
) == PLUS
4154 && GET_CODE (XEXP (c
, 0)) == UNSPEC
4155 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
4156 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4158 arc_output_pic_addr_const (file
, c
, 0);
4161 gcc_assert (GET_CODE (c
) == PLUS
);
4162 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4163 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4165 output_address (VOIDmode
, XEXP (addr
, 0));
4171 /* We shouldn't get here as we've lost the mode of the memory object
4172 (which says how much to inc/dec by. */
4177 arc_output_pic_addr_const (file
, addr
, 0);
4179 output_addr_const (file
, addr
);
4184 /* Conditional execution support.
4186 This is based on the ARM port but for now is much simpler.
4188 A finite state machine takes care of noticing whether or not instructions
4189 can be conditionally executed, and thus decrease execution time and code
4190 size by deleting branch instructions. The fsm is controlled by
4191 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4192 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4193 insns also have a hand in this. */
4194 /* The way we leave dealing with non-anulled or annull-false delay slot
4195 insns to the consumer is awkward. */
4197 /* The state of the fsm controlling condition codes are:
4198 0: normal, do nothing special
4199 1: don't output this insn
4200 2: don't output this insn
4201 3: make insns conditional
4202 4: make insns conditional
4203 5: make insn conditional (only for outputting anulled delay slot insns)
4205 special value for cfun->machine->uid_ccfsm_state:
4206 6: return with but one insn before it since function start / call
4208 State transitions (state->state by whom, under what condition):
4209 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4211 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4212 by zero or more non-jump insns and an unconditional branch with
4213 the same target label as the condbranch.
4214 1 -> 3 branch patterns, after having not output the conditional branch
4215 2 -> 4 branch patterns, after having not output the conditional branch
4216 0 -> 5 branch patterns, for anulled delay slot insn.
4217 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4218 (the target label has CODE_LABEL_NUMBER equal to
4219 arc_ccfsm_target_label).
4220 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4221 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4222 5 -> 0 when outputting the delay slot insn
4224 If the jump clobbers the conditions then we use states 2 and 4.
4226 A similar thing can be done with conditional return insns.
4228 We also handle separating branches from sets of the condition code.
4229 This is done here because knowledge of the ccfsm state is required,
4230 we may not be outputting the branch. */
4232 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4233 before letting final output INSN. */
4236 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4238 /* BODY will hold the body of INSN. */
4241 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4242 an if/then/else), and things need to be reversed. */
4245 /* If we start with a return insn, we only succeed if we find another one. */
4246 int seeking_return
= 0;
4248 /* START_INSN will hold the insn from where we start looking. This is the
4249 first insn after the following code_label if REVERSE is true. */
4250 rtx_insn
*start_insn
= insn
;
4252 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4253 since they don't rely on a cmp preceding the. */
4254 enum attr_type jump_insn_type
;
4256 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4257 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4258 final_scan_insn which has `optimize' as a local. */
4259 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4262 /* Ignore notes and labels. */
4265 body
= PATTERN (insn
);
4266 /* If in state 4, check if the target branch is reached, in order to
4267 change back to state 0. */
4268 if (state
->state
== 4)
4270 if (insn
== state
->target_insn
)
4272 state
->target_insn
= NULL
;
4278 /* If in state 3, it is possible to repeat the trick, if this insn is an
4279 unconditional branch to a label, and immediately following this branch
4280 is the previous target label which is only used once, and the label this
4281 branch jumps to is not too far off. Or in other words "we've done the
4282 `then' part, see if we can do the `else' part." */
4283 if (state
->state
== 3)
4285 if (simplejump_p (insn
))
4287 start_insn
= next_nonnote_insn (start_insn
);
4288 if (GET_CODE (start_insn
) == BARRIER
)
4290 /* ??? Isn't this always a barrier? */
4291 start_insn
= next_nonnote_insn (start_insn
);
4293 if (GET_CODE (start_insn
) == CODE_LABEL
4294 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4295 && LABEL_NUSES (start_insn
) == 1)
4300 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4302 start_insn
= next_nonnote_insn (start_insn
);
4303 if (GET_CODE (start_insn
) == BARRIER
)
4304 start_insn
= next_nonnote_insn (start_insn
);
4305 if (GET_CODE (start_insn
) == CODE_LABEL
4306 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4307 && LABEL_NUSES (start_insn
) == 1)
4319 if (GET_CODE (insn
) != JUMP_INSN
4320 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4321 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4324 /* We can't predicate BRCC or loop ends.
4325 Also, when generating PIC code, and considering a medium range call,
4326 we can't predicate the call. */
4327 jump_insn_type
= get_attr_type (insn
);
4328 if (jump_insn_type
== TYPE_BRCC
4329 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4330 || jump_insn_type
== TYPE_LOOP_END
4331 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4334 /* This jump might be paralleled with a clobber of the condition codes,
4335 the jump should always come first. */
4336 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4337 body
= XVECEXP (body
, 0, 0);
4340 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4341 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4343 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4344 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4345 int then_not_else
= TRUE
;
4346 /* Nonzero if next insn must be the target label. */
4347 int next_must_be_target_label_p
;
4348 rtx_insn
*this_insn
= start_insn
;
4351 /* Register the insn jumped to. */
4354 if (!seeking_return
)
4355 label
= XEXP (SET_SRC (body
), 0);
4357 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4358 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4359 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4361 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4362 then_not_else
= FALSE
;
4364 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4366 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4369 then_not_else
= FALSE
;
4374 /* If this is a non-annulled branch with a delay slot, there is
4375 no need to conditionalize the delay slot. */
4376 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn
)))) == SEQUENCE
)
4377 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4379 this_insn
= NEXT_INSN (this_insn
);
4381 /* See how many insns this branch skips, and what kind of insns. If all
4382 insns are okay, and the label or unconditional branch to the same
4383 label is not too far away, succeed. */
4384 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
4385 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
4390 this_insn
= next_nonnote_insn (this_insn
);
4394 if (next_must_be_target_label_p
)
4396 if (GET_CODE (this_insn
) == BARRIER
)
4398 if (GET_CODE (this_insn
) == CODE_LABEL
4399 && this_insn
== label
)
4409 switch (GET_CODE (this_insn
))
4412 /* Succeed if it is the target label, otherwise fail since
4413 control falls in from somewhere else. */
4414 if (this_insn
== label
)
4424 /* Succeed if the following insn is the target label.
4426 If return insns are used then the last insn in a function
4427 will be a barrier. */
4428 next_must_be_target_label_p
= TRUE
;
4432 /* Can handle a call insn if there are no insns after it.
4433 IE: The next "insn" is the target label. We don't have to
4434 worry about delay slots as such insns are SEQUENCE's inside
4435 INSN's. ??? It is possible to handle such insns though. */
4436 if (get_attr_cond (this_insn
) == COND_CANUSE
)
4437 next_must_be_target_label_p
= TRUE
;
4443 scanbody
= PATTERN (this_insn
);
4445 /* If this is an unconditional branch to the same label, succeed.
4446 If it is to another label, do nothing. If it is conditional,
4448 /* ??? Probably, the test for the SET and the PC are
4451 if (GET_CODE (scanbody
) == SET
4452 && GET_CODE (SET_DEST (scanbody
)) == PC
)
4454 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
4455 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
4460 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
4462 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
4465 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
4471 else if (GET_CODE (scanbody
) == PARALLEL
)
4473 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4479 scanbody
= PATTERN (this_insn
);
4481 /* We can only do this with insns that can use the condition
4482 codes (and don't set them). */
4483 if (GET_CODE (scanbody
) == SET
4484 || GET_CODE (scanbody
) == PARALLEL
)
4486 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4489 /* We can't handle other insns like sequences. */
4501 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
4502 state
->target_label
= CODE_LABEL_NUMBER (label
);
4503 else if (seeking_return
|| state
->state
== 2)
4505 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
4507 this_insn
= next_nonnote_insn (this_insn
);
4509 gcc_assert (!this_insn
||
4510 (GET_CODE (this_insn
) != BARRIER
4511 && GET_CODE (this_insn
) != CODE_LABEL
));
4515 /* Oh dear! we ran off the end, give up. */
4516 extract_insn_cached (insn
);
4518 state
->target_insn
= NULL
;
4521 state
->target_insn
= this_insn
;
4526 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4530 state
->cond
= XEXP (SET_SRC (body
), 0);
4531 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4534 if (reverse
|| then_not_else
)
4535 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4538 /* Restore recog_operand. Getting the attributes of other insns can
4539 destroy this array, but final.c assumes that it remains intact
4540 across this call; since the insn has been recognized already we
4541 call insn_extract direct. */
4542 extract_insn_cached (insn
);
4546 /* Record that we are currently outputting label NUM with prefix PREFIX.
4547 It it's the label we're looking for, reset the ccfsm machinery.
4549 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4552 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4554 if (state
->state
== 3 && state
->target_label
== num
4555 && !strcmp (prefix
, "L"))
4558 state
->target_insn
= NULL
;
4562 /* We are considering a conditional branch with the condition COND.
4563 Check if we want to conditionalize a delay slot insn, and if so modify
4564 the ccfsm state accordingly.
4565 REVERSE says branch will branch when the condition is false. */
4567 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4568 struct arc_ccfsm
*state
)
4570 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4572 state
= &arc_ccfsm_current
;
4574 gcc_assert (state
->state
== 0);
4575 if (seq_insn
!= jump
)
4577 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4579 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4580 && INSN_ANNULLED_BRANCH_P (jump
)
4581 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4584 state
->cc
= get_arc_condition_code (cond
);
4586 arc_ccfsm_current
.cc
4587 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4588 rtx pat
= PATTERN (insn
);
4589 if (GET_CODE (pat
) == COND_EXEC
)
4590 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4591 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4592 == get_arc_condition_code (XEXP (pat
, 0)));
4599 /* Update *STATE as we would when we emit INSN. */
4602 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4604 enum attr_type type
;
4607 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4608 else if (JUMP_P (insn
)
4609 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4610 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4611 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4612 || ((type
== TYPE_UNCOND_BRANCH
4613 || type
== TYPE_RETURN
)
4614 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4616 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4617 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4620 rtx src
= SET_SRC (PATTERN (insn
));
4621 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4625 else if (arc_ccfsm_current
.state
== 5)
4626 arc_ccfsm_current
.state
= 0;
4629 /* Return true if the current insn, which is a conditional branch, is to be
4633 arc_ccfsm_branch_deleted_p (void)
4635 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4638 /* Record a branch isn't output because subsequent insns can be
4642 arc_ccfsm_record_branch_deleted (void)
4644 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4647 /* During insn output, indicate if the current insn is predicated. */
4650 arc_ccfsm_cond_exec_p (void)
4652 return (cfun
->machine
->prescan_initialized
4653 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4656 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4657 and look inside SEQUENCEs. */
4660 arc_next_active_insn (rtx_insn
*insn
, struct arc_ccfsm
*statep
)
4667 arc_ccfsm_post_advance (insn
, statep
);
4668 insn
= NEXT_INSN (insn
);
4669 if (!insn
|| BARRIER_P (insn
))
4672 arc_ccfsm_advance (insn
, statep
);
4674 while (NOTE_P (insn
)
4675 || (cfun
->machine
->arc_reorg_started
4676 && LABEL_P (insn
) && !label_to_alignment (insn
))
4677 || (NONJUMP_INSN_P (insn
)
4678 && (GET_CODE (PATTERN (insn
)) == USE
4679 || GET_CODE (PATTERN (insn
)) == CLOBBER
)));
4680 if (!LABEL_P (insn
))
4682 gcc_assert (INSN_P (insn
));
4683 pat
= PATTERN (insn
);
4684 if (GET_CODE (pat
) == ADDR_VEC
|| GET_CODE (pat
) == ADDR_DIFF_VEC
)
4686 if (GET_CODE (pat
) == SEQUENCE
)
4687 return as_a
<rtx_insn
*> (XVECEXP (pat
, 0, 0));
4692 /* When deciding if an insn should be output short, we want to know something
4693 about the following insns:
4694 - if another insn follows which we know we can output as a short insn
4695 before an alignment-sensitive point, we can output this insn short:
4696 the decision about the eventual alignment can be postponed.
4697 - if a to-be-aligned label comes next, we should output this insn such
4698 as to get / preserve 4-byte alignment.
4699 - if a likely branch without delay slot insn, or a call with an immediately
4700 following short insn comes next, we should out output this insn such as to
4701 get / preserve 2 mod 4 unalignment.
4702 - do the same for a not completely unlikely branch with a short insn
4703 following before any other branch / label.
4704 - in order to decide if we are actually looking at a branch, we need to
4705 call arc_ccfsm_advance.
4706 - in order to decide if we are looking at a short insn, we should know
4707 if it is conditionalized. To a first order of approximation this is
4708 the case if the state from arc_ccfsm_advance from before this insn
4709 indicates the insn is conditionalized. However, a further refinement
4710 could be to not conditionalize an insn if the destination register(s)
4711 is/are dead in the non-executed case. */
4712 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4713 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4714 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4717 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4719 enum attr_iscompact iscompact
;
4720 struct machine_function
*machine
;
4724 iscompact
= get_attr_iscompact (insn
);
4725 if (iscompact
== ISCOMPACT_FALSE
)
4728 machine
= cfun
->machine
;
4730 if (machine
->force_short_suffix
>= 0)
4731 return machine
->force_short_suffix
;
4733 return (get_attr_length (insn
) & 2) != 0;
4736 /* When outputting an instruction (alternative) that can potentially be short,
4737 output the short suffix if the insn is in fact short, and update
4738 cfun->machine->unalign accordingly. */
4741 output_short_suffix (FILE *file
)
4743 rtx_insn
*insn
= current_output_insn
;
4745 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
4747 fprintf (file
, "_s");
4748 cfun
->machine
->unalign
^= 2;
4750 /* Restore recog_operand. */
4751 extract_insn_cached (insn
);
4754 /* Implement FINAL_PRESCAN_INSN. */
4757 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
4758 int noperands ATTRIBUTE_UNUSED
)
4760 if (TARGET_DUMPISIZE
)
4761 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
4763 /* Output a nop if necessary to prevent a hazard.
4764 Don't do this for delay slots: inserting a nop would
4765 alter semantics, and the only time we would find a hazard is for a
4766 call function result - and in that case, the hazard is spurious to
4768 if (PREV_INSN (insn
)
4769 && PREV_INSN (NEXT_INSN (insn
)) == insn
4770 && arc_hazard (prev_real_insn (insn
), insn
))
4772 current_output_insn
=
4773 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn
)));
4774 final_scan_insn (current_output_insn
, asm_out_file
, optimize
, 1, NULL
);
4775 current_output_insn
= insn
;
4777 /* Restore extraction data which might have been clobbered by arc_hazard. */
4778 extract_constrain_insn_cached (insn
);
4780 if (!cfun
->machine
->prescan_initialized
)
4782 /* Clear lingering state from branch shortening. */
4783 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
4784 cfun
->machine
->prescan_initialized
= 1;
4786 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
4788 cfun
->machine
->size_reason
= 0;
4791 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4792 Frame pointer elimination is automatically handled.
4794 All eliminations are permissible. If we need a frame
4795 pointer, we must eliminate ARG_POINTER_REGNUM into
4796 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4799 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4801 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
4804 /* Define the offset between two registers, one to be eliminated, and
4805 the other its replacement, at the start of a routine. */
4808 arc_initial_elimination_offset (int from
, int to
)
4810 if (! cfun
->machine
->frame_info
.initialized
)
4811 arc_compute_frame_size (get_frame_size ());
4813 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
4815 return (cfun
->machine
->frame_info
.extra_size
4816 + cfun
->machine
->frame_info
.reg_size
);
4819 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
4821 return (cfun
->machine
->frame_info
.total_size
4822 - cfun
->machine
->frame_info
.pretend_size
);
4825 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
4827 return (cfun
->machine
->frame_info
.total_size
4828 - (cfun
->machine
->frame_info
.pretend_size
4829 + cfun
->machine
->frame_info
.extra_size
4830 + cfun
->machine
->frame_info
.reg_size
));
4837 arc_frame_pointer_required (void)
4839 return cfun
->calls_alloca
;
4843 /* Return the destination address of a branch. */
4846 branch_dest (rtx branch
)
4848 rtx pat
= PATTERN (branch
);
4849 rtx dest
= (GET_CODE (pat
) == PARALLEL
4850 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
4853 if (GET_CODE (dest
) == IF_THEN_ELSE
)
4854 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
4856 dest
= XEXP (dest
, 0);
4857 dest_uid
= INSN_UID (dest
);
4859 return INSN_ADDRESSES (dest_uid
);
4863 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4866 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
4868 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4869 This clears machine specific flags, so has to come first. */
4870 default_encode_section_info (decl
, rtl
, first
);
4872 /* Check if it is a function, and whether it has the
4873 [long/medium/short]_call attribute specified. */
4874 if (TREE_CODE (decl
) == FUNCTION_DECL
)
4876 rtx symbol
= XEXP (rtl
, 0);
4877 int flags
= SYMBOL_REF_FLAGS (symbol
);
4879 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4880 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
4881 tree long_call_attr
= lookup_attribute ("long_call", attr
);
4882 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
4883 tree short_call_attr
= lookup_attribute ("short_call", attr
);
4885 if (long_call_attr
!= NULL_TREE
)
4886 flags
|= SYMBOL_FLAG_LONG_CALL
;
4887 else if (medium_call_attr
!= NULL_TREE
)
4888 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
4889 else if (short_call_attr
!= NULL_TREE
)
4890 flags
|= SYMBOL_FLAG_SHORT_CALL
;
4892 SYMBOL_REF_FLAGS (symbol
) = flags
;
4894 else if (TREE_CODE (decl
) == VAR_DECL
)
4896 rtx symbol
= XEXP (rtl
, 0);
4898 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4899 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
4901 tree sec_attr
= lookup_attribute ("section", attr
);
4904 const char *sec_name
4905 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
4906 if (strcmp (sec_name
, ".cmem") == 0
4907 || strcmp (sec_name
, ".cmem_shared") == 0
4908 || strcmp (sec_name
, ".cmem_private") == 0)
4909 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
4914 /* This is how to output a definition of an internal numbered label where
4915 PREFIX is the class of label and NUM is the number within the class. */
4917 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
4920 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
4921 default_internal_label (stream
, prefix
, labelno
);
4924 /* Set the cpu type and print out other fancy things,
4925 at the top of the file. */
4927 static void arc_file_start (void)
4929 default_file_start ();
4930 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
4933 /* Cost functions. */
4935 /* Compute a (partial) cost for rtx X. Return true if the complete
4936 cost has been computed, and false if subexpressions should be
4937 scanned. In either case, *TOTAL contains the cost result. */
4940 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4941 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4943 int code
= GET_CODE (x
);
4947 /* Small integers are as cheap as registers. */
4950 bool nolimm
= false; /* Can we do without long immediate? */
4951 bool fast
= false; /* Is the result available immediately? */
4952 bool condexec
= false; /* Does this allow conditiobnal execution? */
4953 bool compact
= false; /* Is a 16 bit opcode available? */
4954 /* CONDEXEC also implies that we can have an unconditional
4955 3-address operation. */
4957 nolimm
= compact
= condexec
= false;
4958 if (UNSIGNED_INT6 (INTVAL (x
)))
4959 nolimm
= condexec
= compact
= true;
4962 if (SMALL_INT (INTVAL (x
)))
4963 nolimm
= fast
= true;
4966 case AND
: /* bclr, bmsk, ext[bw] */
4967 if (satisfies_constraint_Ccp (x
) /* bclr */
4968 || satisfies_constraint_C1p (x
) /* bmsk */)
4969 nolimm
= fast
= condexec
= compact
= true;
4971 case IOR
: /* bset */
4972 if (satisfies_constraint_C0p (x
)) /* bset */
4973 nolimm
= fast
= condexec
= compact
= true;
4976 if (satisfies_constraint_C0p (x
)) /* bxor */
4977 nolimm
= fast
= condexec
= true;
4980 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
4986 /* FIXME: Add target options to attach a small cost if
4987 condexec / compact is not true. */
4996 /* 4 byte values can be fetched as immediate constants -
4997 let's give that the cost of an extra insn. */
5001 *total
= COSTS_N_INSNS (1);
5010 *total
= COSTS_N_INSNS (1);
5013 split_double (x
, &first
, &second
);
5014 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
5015 + !SMALL_INT (INTVAL (second
)));
5019 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5020 If we need more than 12 insns to do a multiply, then go out-of-line,
5021 since the call overhead will be < 10% of the cost of the multiply. */
5025 if (TARGET_BARREL_SHIFTER
)
5027 /* If we want to shift a constant, we need a LIMM. */
5028 /* ??? when the optimizers want to know if a constant should be
5029 hoisted, they ask for the cost of the constant. OUTER_CODE is
5030 insufficient context for shifts since we don't know which operand
5031 we are looking at. */
5032 if (CONSTANT_P (XEXP (x
, 0)))
5034 *total
+= (COSTS_N_INSNS (2)
5035 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
5039 *total
= COSTS_N_INSNS (1);
5041 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5042 *total
= COSTS_N_INSNS (16);
5045 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
5046 /* ??? want_to_gcse_p can throw negative shift counts at us,
5047 and then panics when it gets a negative cost as result.
5048 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5057 *total
= COSTS_N_INSNS(30);
5059 *total
= COSTS_N_INSNS(1);
5063 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
5064 *total
= COSTS_N_INSNS (1);
5066 *total
= arc_multcost
;
5067 /* We do not want synth_mult sequences when optimizing
5069 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
5070 *total
= COSTS_N_INSNS (1);
5072 *total
= COSTS_N_INSNS (2);
5075 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
5076 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
5077 || (GET_CODE (XEXP (x
, 0)) == MULT
5078 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
5080 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
5081 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
5086 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
5087 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
5088 || (GET_CODE (XEXP (x
, 1)) == MULT
5089 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
5091 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
5092 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
5098 rtx op0
= XEXP (x
, 0);
5099 rtx op1
= XEXP (x
, 1);
5101 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
5102 && XEXP (op0
, 1) == const1_rtx
)
5104 /* btst / bbit0 / bbit1:
5105 Small integers and registers are free; everything else can
5106 be put in a register. */
5107 mode
= GET_MODE (XEXP (op0
, 0));
5108 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5109 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5112 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5113 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5116 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5120 if (GET_CODE (op1
) == NEG
)
5122 /* op0 might be constant, the inside of op1 is rather
5123 unlikely to be so. So swapping the operands might lower
5125 mode
= GET_MODE (op0
);
5126 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5127 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5132 if (outer_code
== IF_THEN_ELSE
5133 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5134 && XEXP (x
, 1) == const0_rtx
5135 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5137 /* btst / bbit0 / bbit1:
5138 Small integers and registers are free; everything else can
5139 be put in a register. */
5140 rtx op0
= XEXP (x
, 0);
5142 mode
= GET_MODE (XEXP (op0
, 0));
5143 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5144 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5148 /* scc_insn expands into two insns. */
5149 case GTU
: case GEU
: case LEU
:
5151 *total
+= COSTS_N_INSNS (1);
5153 case LTU
: /* might use adc. */
5155 *total
+= COSTS_N_INSNS (1) - 1;
5162 /* Return true if ADDR is a valid pic address.
5163 A valid pic address on arc should look like
5164 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5167 arc_legitimate_pic_addr_p (rtx addr
)
5169 if (GET_CODE (addr
) != CONST
)
5172 addr
= XEXP (addr
, 0);
5175 if (GET_CODE (addr
) == PLUS
)
5177 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5179 addr
= XEXP (addr
, 0);
5182 if (GET_CODE (addr
) != UNSPEC
5183 || XVECLEN (addr
, 0) != 1)
5186 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5187 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5188 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5189 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5190 && XINT (addr
, 1) != UNSPEC_TLS_GD
5191 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5194 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5195 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5203 /* Return true if OP contains a symbol reference. */
5206 symbolic_reference_mentioned_p (rtx op
)
5208 register const char *fmt
;
5211 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5214 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5215 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5221 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5222 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5226 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5233 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5234 If SKIP_LOCAL is true, skip symbols that bind locally.
5235 This is used further down in this file, and, without SKIP_LOCAL,
5236 in the addsi3 / subsi3 expanders when generating PIC code. */
5239 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5241 register const char *fmt
;
5244 if (GET_CODE(op
) == UNSPEC
)
5247 if (GET_CODE (op
) == SYMBOL_REF
)
5249 if (SYMBOL_REF_TLS_MODEL (op
))
5253 tree decl
= SYMBOL_REF_DECL (op
);
5254 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5257 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5258 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5264 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5265 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5270 else if (fmt
[i
] == 'e'
5271 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5279 /* Get the thread pointer. */
5284 /* If arc_tp_regno has been set, we can use that hard register
5285 directly as a base register. */
5286 if (arc_tp_regno
!= -1)
5287 return gen_rtx_REG (Pmode
, arc_tp_regno
);
5289 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5290 conflicts with function arguments / results. */
5291 rtx reg
= gen_reg_rtx (Pmode
);
5292 emit_insn (gen_tls_load_tp_soft ());
5293 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
5297 /* Helper to be used by TLS Global dynamic model. */
5300 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
5302 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
5303 rtx call_fusage
= NULL_RTX
;
5307 rtx x
= arc_unspec_offset (sym
, reloc
);
5308 emit_move_insn (r0
, x
);
5309 use_reg (&call_fusage
, r0
);
5311 gcc_assert (reloc
== UNSPEC_TLS_GD
);
5312 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
5313 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5314 way that the application should care. */
5315 RTL_PURE_CALL_P (call_insn
) = 1;
5316 add_function_usage_to (call_insn
, call_fusage
);
5318 rtx_insn
*insns
= get_insns ();
5321 rtx dest
= gen_reg_rtx (Pmode
);
5322 emit_libcall_block (insns
, dest
, r0
, eqv
);
5326 #define DTPOFF_ZERO_SYM ".tdata"
5328 /* Return a legitimized address for ADDR,
5329 which is a SYMBOL_REF with tls_model MODEL. */
5332 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5334 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5335 model
= TLS_MODEL_LOCAL_EXEC
;
5339 case TLS_MODEL_LOCAL_DYNAMIC
:
5342 const char *base_name
;
5345 decl
= SYMBOL_REF_DECL (addr
);
5346 base_name
= DTPOFF_ZERO_SYM
;
5347 if (decl
&& bss_initializer_p (decl
))
5348 base_name
= ".tbss";
5350 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5351 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
5355 v
= gen_rtvec (1, addr
);
5358 v
= gen_rtvec (2, addr
, base
);
5359 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
5360 addr
= gen_rtx_CONST (Pmode
, addr
);
5361 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
5362 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
5364 case TLS_MODEL_GLOBAL_DYNAMIC
:
5365 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
5367 case TLS_MODEL_INITIAL_EXEC
:
5368 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5369 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5370 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5372 case TLS_MODEL_LOCAL_EXEC
:
5374 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5375 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5381 /* Legitimize a pic address reference in ORIG.
5382 The return value is the legitimated address.
5383 If OLDX is non-zero, it is the target to assign the address to first. */
5386 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5395 if (GET_CODE (addr
) == LABEL_REF
)
5397 else if (GET_CODE (addr
) == SYMBOL_REF
)
5399 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5401 return arc_legitimize_tls_address (addr
, model
);
5404 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5405 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5407 /* This symbol must be referenced via a load from the Global
5408 Offset Table (@GOTPC). */
5409 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5410 pat
= gen_const_mem (Pmode
, pat
);
5413 oldx
= gen_reg_rtx (Pmode
);
5415 emit_move_insn (oldx
, pat
);
5420 if (GET_CODE (addr
) == CONST
)
5422 addr
= XEXP (addr
, 0);
5423 if (GET_CODE (addr
) == UNSPEC
)
5425 /* Check that the unspec is one of the ones we generate? */
5428 /* fwprop is placing in the REG_EQUIV notes constant pic
5429 unspecs expressions. Then, loop may use these notes for
5430 optimizations resulting in complex patterns that are not
5431 supported by the current implementation. The following
5432 two if-cases are simplifying the complex patters to
5434 else if (GET_CODE (addr
) == MINUS
)
5436 rtx op0
= XEXP (addr
, 0);
5437 rtx op1
= XEXP (addr
, 1);
5439 gcc_assert (GET_CODE (op1
) == UNSPEC
);
5441 emit_move_insn (oldx
,
5442 gen_rtx_CONST (SImode
,
5443 arc_legitimize_pic_address (op1
,
5445 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
5449 else if (GET_CODE (addr
) != PLUS
)
5451 rtx tmp
= XEXP (addr
, 0);
5452 enum rtx_code code
= GET_CODE (addr
);
5454 /* It only works for UNARY operations. */
5455 gcc_assert (UNARY_P (addr
));
5456 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
5461 gen_rtx_CONST (SImode
,
5462 arc_legitimize_pic_address (tmp
,
5465 emit_insn (gen_rtx_SET (oldx
,
5466 gen_rtx_fmt_ee (code
, SImode
,
5467 oldx
, const0_rtx
)));
5473 gcc_assert (GET_CODE (addr
) == PLUS
);
5474 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
5479 if (GET_CODE (addr
) == PLUS
)
5481 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
5483 base
= arc_legitimize_pic_address (op0
, oldx
);
5484 pat
= arc_legitimize_pic_address (op1
,
5485 base
== oldx
? NULL_RTX
: oldx
);
5487 if (base
== op0
&& pat
== op1
)
5490 if (GET_CODE (pat
) == CONST_INT
)
5491 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
5494 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
5496 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
5497 pat
= XEXP (pat
, 1);
5499 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
5507 /* Output address constant X to FILE, taking PIC into account. */
5510 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5515 switch (GET_CODE (x
))
5525 output_addr_const (file
, x
);
5527 /* Local functions do not get references through the PLT. */
5528 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5529 fputs ("@plt", file
);
5533 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5534 assemble_name (file
, buf
);
5538 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5539 assemble_name (file
, buf
);
5543 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5547 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5551 if (GET_MODE (x
) == VOIDmode
)
5553 /* We can use %d if the number is one word and positive. */
5554 if (CONST_DOUBLE_HIGH (x
))
5555 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5556 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5557 else if (CONST_DOUBLE_LOW (x
) < 0)
5558 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5560 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5563 /* We can't handle floating point constants;
5564 PRINT_OPERAND must handle them. */
5565 output_operand_lossage ("floating constant misused");
5569 /* FIXME: Not needed here. */
5570 /* Some assemblers need integer constants to appear last (eg masm). */
5571 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5573 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5574 fprintf (file
, "+");
5575 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5577 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5579 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5580 if (INTVAL (XEXP (x
, 1)) >= 0)
5581 fprintf (file
, "+");
5582 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5589 /* Avoid outputting things like x-x or x+5-x,
5590 since some assemblers can't handle that. */
5591 x
= simplify_subtraction (x
);
5592 if (GET_CODE (x
) != MINUS
)
5595 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5596 fprintf (file
, "-");
5597 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5598 && INTVAL (XEXP (x
, 1)) < 0)
5600 fprintf (file
, "(");
5601 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5602 fprintf (file
, ")");
5605 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5610 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5616 bool pcrel
; pcrel
= false;
5617 rtx base
; base
= NULL
;
5618 gcc_assert (XVECLEN (x
, 0) >= 1);
5619 switch (XINT (x
, 1))
5621 case ARC_UNSPEC_GOT
:
5622 suffix
= "@gotpc", pcrel
= true;
5624 case ARC_UNSPEC_GOTOFF
:
5627 case ARC_UNSPEC_GOTOFFPC
:
5628 suffix
= "@pcl", pcrel
= true;
5630 case ARC_UNSPEC_PLT
:
5634 suffix
= "@tlsgd", pcrel
= true;
5637 suffix
= "@tlsie", pcrel
= true;
5639 case UNSPEC_TLS_OFF
:
5640 if (XVECLEN (x
, 0) == 2)
5641 base
= XVECEXP (x
, 0, 1);
5642 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5643 || (!flag_pic
&& !base
))
5649 suffix
= "@invalid";
5650 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5654 fputs ("pcl,", file
);
5655 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5656 fputs (suffix
, file
);
5658 arc_output_pic_addr_const (file
, base
, code
);
5662 output_operand_lossage ("invalid expression as operand");
5666 #define SYMBOLIC_CONST(X) \
5667 (GET_CODE (X) == SYMBOL_REF \
5668 || GET_CODE (X) == LABEL_REF \
5669 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5671 /* Emit insns to move operands[1] into operands[0]. */
5674 prepare_pic_move (rtx
*operands
, machine_mode
)
5676 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5678 operands
[1] = force_reg (Pmode
, operands
[1]);
5681 rtx temp
= (reload_in_progress
? operands
[0]
5682 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5683 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5688 /* The function returning the number of words, at the beginning of an
5689 argument, must be put in registers. The returned value must be
5690 zero for arguments that are passed entirely in registers or that
5691 are entirely pushed on the stack.
5693 On some machines, certain arguments must be passed partially in
5694 registers and partially in memory. On these machines, typically
5695 the first N words of arguments are passed in registers, and the
5696 rest on the stack. If a multi-word argument (a `double' or a
5697 structure) crosses that boundary, its first few words must be
5698 passed in registers and the rest must be pushed. This function
5699 tells the compiler when this occurs, and how many of the words
5700 should go in registers.
5702 `FUNCTION_ARG' for these arguments should return the first register
5703 to be used by the caller for this argument; likewise
5704 `FUNCTION_INCOMING_ARG', for the called function.
5706 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5708 /* If REGNO is the least arg reg available then what is the total number of arg
5710 #define GPR_REST_ARG_REGS(REGNO) \
5711 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5713 /* Since arc parm regs are contiguous. */
5714 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5716 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5719 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
5720 tree type
, bool named ATTRIBUTE_UNUSED
)
5722 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5723 int bytes
= (mode
== BLKmode
5724 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5725 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5729 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5730 ret
= GPR_REST_ARG_REGS (arg_num
);
5732 /* ICEd at function.c:2361, and ret is copied to data->partial */
5733 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
5738 /* This function is used to control a function argument is passed in a
5739 register, and which register.
5741 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5742 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5743 all of the previous arguments so far passed in registers; MODE, the
5744 machine mode of the argument; TYPE, the data type of the argument
5745 as a tree node or 0 if that is not known (which happens for C
5746 support library functions); and NAMED, which is 1 for an ordinary
5747 argument and 0 for nameless arguments that correspond to `...' in
5748 the called function's prototype.
5750 The returned value should either be a `reg' RTX for the hard
5751 register in which to pass the argument, or zero to pass the
5752 argument on the stack.
5754 For machines like the Vax and 68000, where normally all arguments
5755 are pushed, zero suffices as a definition.
5757 The usual way to make the ANSI library `stdarg.h' work on a machine
5758 where some arguments are usually passed in registers, is to cause
5759 nameless arguments to be passed on the stack instead. This is done
5760 by making the function return 0 whenever NAMED is 0.
5762 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5763 definition of this function to determine if this argument is of a
5764 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5765 is not defined and the function returns non-zero for such an
5766 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5767 defined, the argument will be computed in the stack and then loaded
5770 The function is used to implement macro FUNCTION_ARG. */
5771 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5772 and the rest are pushed. */
5775 arc_function_arg (cumulative_args_t cum_v
,
5777 const_tree type ATTRIBUTE_UNUSED
,
5778 bool named ATTRIBUTE_UNUSED
)
5780 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5783 const char *debstr ATTRIBUTE_UNUSED
;
5785 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5786 /* Return a marker for use in the call instruction. */
5787 if (mode
== VOIDmode
)
5792 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
5794 ret
= gen_rtx_REG (mode
, arg_num
);
5795 debstr
= reg_names
[arg_num
];
5805 /* The function to update the summarizer variable *CUM to advance past
5806 an argument in the argument list. The values MODE, TYPE and NAMED
5807 describe that argument. Once this is done, the variable *CUM is
5808 suitable for analyzing the *following* argument with
5809 `FUNCTION_ARG', etc.
5811 This function need not do anything if the argument in question was
5812 passed on the stack. The compiler knows how to track the amount of
5813 stack space used for arguments without any special help.
5815 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5816 /* For the ARC: the cum set here is passed on to function_arg where we
5817 look at its value and say which reg to use. Strategy: advance the
5818 regnumber here till we run out of arg regs, then set *cum to last
5819 reg. In function_arg, since *cum > last arg reg we would return 0
5820 and thus the arg will end up on the stack. For straddling args of
5821 course function_arg_partial_nregs will come into play. */
5824 arc_function_arg_advance (cumulative_args_t cum_v
,
5827 bool named ATTRIBUTE_UNUSED
)
5829 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5830 int bytes
= (mode
== BLKmode
5831 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5832 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5836 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
5837 for (i
= 0; i
< words
; i
++)
5838 *cum
= ARC_NEXT_ARG_REG (*cum
);
5842 /* Define how to find the value returned by a function.
5843 VALTYPE is the data type of the value (as a tree).
5844 If the precise function being called is known, FN_DECL_OR_TYPE is its
5845 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5848 arc_function_value (const_tree valtype
,
5849 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
5850 bool outgoing ATTRIBUTE_UNUSED
)
5852 machine_mode mode
= TYPE_MODE (valtype
);
5853 int unsignedp ATTRIBUTE_UNUSED
;
5855 unsignedp
= TYPE_UNSIGNED (valtype
);
5856 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
5857 PROMOTE_MODE (mode
, unsignedp
, valtype
);
5858 return gen_rtx_REG (mode
, 0);
5861 /* Returns the return address that is used by builtin_return_address. */
5864 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
5869 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
5872 /* Determine if a given RTX is a valid constant. We already know this
5873 satisfies CONSTANT_P. */
5876 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
5878 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
))
5881 if (!flag_pic
&& mode
!= Pmode
)
5884 switch (GET_CODE (x
))
5889 if (arc_legitimate_pic_addr_p (x
))
5892 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
5895 if (SYMBOL_REF_TLS_MODEL (x
))
5907 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
5912 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
5913 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
5922 return TARGET_PLUS_DMPY
;
5925 return TARGET_PLUS_QMACW
;
5931 switch (XINT (x
, 1))
5934 case UNSPEC_TLS_OFF
:
5938 /* Any other unspec ending here are pic related, hence the above
5939 constant pic address checking returned false. */
5945 fatal_insn ("unrecognized supposed constant", x
);
5952 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
5954 if (RTX_OK_FOR_BASE_P (x
, strict
))
5956 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
5958 if (legitimate_scaled_address_p (mode
, x
, strict
))
5960 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x
))
5962 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
5965 /* When we compile for size avoid const (@sym + offset)
5967 if (!flag_pic
&& optimize_size
&& !reload_completed
5968 && (GET_CODE (x
) == CONST
)
5969 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
5970 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
5971 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
5972 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
5974 rtx addend
= XEXP (XEXP (x
, 0), 1);
5975 gcc_assert (CONST_INT_P (addend
));
5976 HOST_WIDE_INT offset
= INTVAL (addend
);
5978 /* Allow addresses having a large offset to pass. Anyhow they
5979 will end in a limm. */
5980 return !(offset
> -1024 && offset
< 1020);
5983 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
5985 return arc_legitimate_constant_p (mode
, x
);
5987 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
5988 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
5989 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5991 /* We're restricted here by the `st' insn. */
5992 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
5993 && GET_CODE (XEXP ((x
), 1)) == PLUS
5994 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
5995 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
5996 TARGET_AUTO_MODIFY_REG
, strict
))
6001 /* Return true iff ADDR (a legitimate address expression)
6002 has an effect that depends on the machine mode it is used for. */
6005 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
6007 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6008 which is valid for loads and stores, or a limm offset, which is valid for
6009 loads. Scaled indices are scaled by the access mode. */
6010 if (GET_CODE (addr
) == PLUS
6011 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
6016 /* Determine if it's legal to put X into the constant pool. */
6019 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
6021 return !arc_legitimate_constant_p (mode
, x
);
6024 /* IDs for all the ARC builtins. */
6028 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6029 ARC_BUILTIN_ ## NAME,
6030 #include "builtins.def"
6036 struct GTY(()) arc_builtin_description
6038 enum insn_code icode
;
6043 static GTY(()) struct arc_builtin_description
6044 arc_bdesc
[ARC_BUILTIN_COUNT
] =
6046 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6047 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6048 #include "builtins.def"
6052 /* Transform UP into lowercase and write the result to LO.
6053 You must provide enough space for LO. Return LO. */
6056 arc_tolower (char *lo
, const char *up
)
6060 for (; *up
; up
++, lo
++)
6061 *lo
= TOLOWER (*up
);
6068 /* Implement `TARGET_BUILTIN_DECL'. */
6071 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6073 if (id
< ARC_BUILTIN_COUNT
)
6074 return arc_bdesc
[id
].fndecl
;
6076 return error_mark_node
;
6080 arc_init_builtins (void)
6082 tree V4HI_type_node
;
6083 tree V2SI_type_node
;
6084 tree V2HI_type_node
;
6086 /* Vector types based on HS SIMD elements. */
6087 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6088 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6089 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6091 tree pcvoid_type_node
6092 = build_pointer_type (build_qualified_type (void_type_node
,
6094 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6097 tree void_ftype_void
6098 = build_function_type_list (void_type_node
, NULL_TREE
);
6100 = build_function_type_list (integer_type_node
, integer_type_node
,
6102 tree int_ftype_pcvoid_int
6103 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6104 integer_type_node
, NULL_TREE
);
6105 tree void_ftype_usint_usint
6106 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6107 long_unsigned_type_node
, NULL_TREE
);
6108 tree int_ftype_int_int
6109 = build_function_type_list (integer_type_node
, integer_type_node
,
6110 integer_type_node
, NULL_TREE
);
6111 tree usint_ftype_usint
6112 = build_function_type_list (long_unsigned_type_node
,
6113 long_unsigned_type_node
, NULL_TREE
);
6114 tree void_ftype_usint
6115 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6118 = build_function_type_list (integer_type_node
, void_type_node
,
6121 = build_function_type_list (void_type_node
, integer_type_node
,
6123 tree int_ftype_short
6124 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6127 /* Old ARC SIMD types. */
6128 tree v8hi_ftype_v8hi_v8hi
6129 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6130 V8HI_type_node
, NULL_TREE
);
6131 tree v8hi_ftype_v8hi_int
6132 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6133 integer_type_node
, NULL_TREE
);
6134 tree v8hi_ftype_v8hi_int_int
6135 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6136 integer_type_node
, integer_type_node
,
6138 tree void_ftype_v8hi_int_int
6139 = build_function_type_list (void_type_node
, V8HI_type_node
,
6140 integer_type_node
, integer_type_node
,
6142 tree void_ftype_v8hi_int_int_int
6143 = build_function_type_list (void_type_node
, V8HI_type_node
,
6144 integer_type_node
, integer_type_node
,
6145 integer_type_node
, NULL_TREE
);
6146 tree v8hi_ftype_int_int
6147 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6148 integer_type_node
, NULL_TREE
);
6149 tree void_ftype_int_int
6150 = build_function_type_list (void_type_node
, integer_type_node
,
6151 integer_type_node
, NULL_TREE
);
6152 tree v8hi_ftype_v8hi
6153 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6155 /* ARCv2 SIMD types. */
6156 tree long_ftype_v4hi_v4hi
6157 = build_function_type_list (long_long_integer_type_node
,
6158 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6159 tree int_ftype_v2hi_v2hi
6160 = build_function_type_list (integer_type_node
,
6161 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6162 tree v2si_ftype_v2hi_v2hi
6163 = build_function_type_list (V2SI_type_node
,
6164 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6165 tree v2hi_ftype_v2hi_v2hi
6166 = build_function_type_list (V2HI_type_node
,
6167 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6168 tree v2si_ftype_v2si_v2si
6169 = build_function_type_list (V2SI_type_node
,
6170 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6171 tree v4hi_ftype_v4hi_v4hi
6172 = build_function_type_list (V4HI_type_node
,
6173 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6174 tree long_ftype_v2si_v2hi
6175 = build_function_type_list (long_long_integer_type_node
,
6176 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6178 /* Add the builtins. */
6179 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6181 int id = ARC_BUILTIN_ ## NAME; \
6182 const char *Name = "__builtin_arc_" #NAME; \
6183 char *name = (char*) alloca (1 + strlen (Name)); \
6185 gcc_assert (id < ARC_BUILTIN_COUNT); \
6187 arc_bdesc[id].fndecl \
6188 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6189 BUILT_IN_MD, NULL, NULL_TREE); \
6191 #include "builtins.def"
6195 /* Helper to expand __builtin_arc_aligned (void* val, int
6199 arc_expand_builtin_aligned (tree exp
)
6201 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6202 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6204 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6205 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6207 if (!CONST_INT_P (op1
))
6209 /* If we can't fold the alignment to a constant integer
6210 whilst optimizing, this is probably a user error. */
6212 warning (0, "__builtin_arc_aligned with non-constant alignment");
6216 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6217 /* Check alignTest is positive, and a power of two. */
6218 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6220 error ("invalid alignment value for __builtin_arc_aligned");
6224 if (CONST_INT_P (op0
))
6226 HOST_WIDE_INT pnt
= INTVAL (op0
);
6228 if ((pnt
& (alignTest
- 1)) == 0)
6233 unsigned align
= get_pointer_alignment (arg0
);
6234 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6236 if (align
&& align
>= numBits
)
6238 /* Another attempt to ascertain alignment. Check the type
6239 we are pointing to. */
6240 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6241 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6246 /* Default to false. */
6250 /* Helper arc_expand_builtin, generates a pattern for the given icode
6254 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6256 switch (insn_data
[icode
].n_generator_args
)
6259 return GEN_FCN (icode
) ();
6261 return GEN_FCN (icode
) (arg
[0]);
6263 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6265 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6267 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6269 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6275 /* Expand an expression EXP that calls a built-in function,
6276 with result going to TARGET if that's convenient
6277 (and in mode MODE if that's convenient).
6278 SUBTARGET may be used as the target for computing one of EXP's operands.
6279 IGNORE is nonzero if the value is to be ignored. */
6282 arc_expand_builtin (tree exp
,
6284 rtx subtarget ATTRIBUTE_UNUSED
,
6285 machine_mode mode ATTRIBUTE_UNUSED
,
6286 int ignore ATTRIBUTE_UNUSED
)
6288 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6289 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6290 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6291 int i
, j
, n_args
= call_expr_nargs (exp
);
6294 enum insn_code icode
= d
->icode
;
6295 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6312 if (id
>= ARC_BUILTIN_COUNT
)
6313 internal_error ("bad builtin fcode");
6315 /* 1st part: Expand special builtins. */
6318 case ARC_BUILTIN_NOP
:
6319 emit_insn (gen_nopv ());
6322 case ARC_BUILTIN_RTIE
:
6323 case ARC_BUILTIN_SYNC
:
6324 case ARC_BUILTIN_BRK
:
6325 case ARC_BUILTIN_SWI
:
6326 case ARC_BUILTIN_UNIMP_S
:
6327 gcc_assert (icode
!= 0);
6328 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6331 case ARC_BUILTIN_ALIGNED
:
6332 return arc_expand_builtin_aligned (exp
);
6334 case ARC_BUILTIN_CLRI
:
6335 target
= gen_reg_rtx (SImode
);
6336 emit_insn (gen_clri (target
, const1_rtx
));
6339 case ARC_BUILTIN_TRAP_S
:
6340 case ARC_BUILTIN_SLEEP
:
6341 arg0
= CALL_EXPR_ARG (exp
, 0);
6343 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6345 if (!CONST_INT_P (op0
) || !satisfies_constraint_L (op0
))
6347 error ("builtin operand should be an unsigned 6-bit value");
6350 gcc_assert (icode
!= 0);
6351 emit_insn (GEN_FCN (icode
) (op0
));
6354 case ARC_BUILTIN_VDORUN
:
6355 case ARC_BUILTIN_VDIRUN
:
6356 arg0
= CALL_EXPR_ARG (exp
, 0);
6357 arg1
= CALL_EXPR_ARG (exp
, 1);
6358 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6359 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6361 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6363 mode0
= insn_data
[icode
].operand
[1].mode
;
6364 mode1
= insn_data
[icode
].operand
[2].mode
;
6366 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6367 op0
= copy_to_mode_reg (mode0
, op0
);
6369 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6370 op1
= copy_to_mode_reg (mode1
, op1
);
6372 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6379 case ARC_BUILTIN_VDIWR
:
6380 case ARC_BUILTIN_VDOWR
:
6381 arg0
= CALL_EXPR_ARG (exp
, 0);
6382 arg1
= CALL_EXPR_ARG (exp
, 1);
6383 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6384 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6386 if (!CONST_INT_P (op0
)
6387 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6388 error ("operand 1 should be an unsigned 3-bit immediate");
6390 mode1
= insn_data
[icode
].operand
[1].mode
;
6392 if (icode
== CODE_FOR_vdiwr_insn
)
6393 target
= gen_rtx_REG (SImode
,
6394 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6395 else if (icode
== CODE_FOR_vdowr_insn
)
6396 target
= gen_rtx_REG (SImode
,
6397 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6401 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6402 op1
= copy_to_mode_reg (mode1
, op1
);
6404 pat
= GEN_FCN (icode
) (target
, op1
);
6411 case ARC_BUILTIN_VASRW
:
6412 case ARC_BUILTIN_VSR8
:
6413 case ARC_BUILTIN_VSR8AW
:
6414 arg0
= CALL_EXPR_ARG (exp
, 0);
6415 arg1
= CALL_EXPR_ARG (exp
, 1);
6416 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6417 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6418 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6420 target
= gen_reg_rtx (V8HImode
);
6421 mode0
= insn_data
[icode
].operand
[1].mode
;
6422 mode1
= insn_data
[icode
].operand
[2].mode
;
6424 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6425 op0
= copy_to_mode_reg (mode0
, op0
);
6427 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6428 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6429 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6431 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6438 case ARC_BUILTIN_VLD32WH
:
6439 case ARC_BUILTIN_VLD32WL
:
6440 case ARC_BUILTIN_VLD64
:
6441 case ARC_BUILTIN_VLD32
:
6444 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6445 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6446 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6448 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6449 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6450 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6451 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6453 /* target <- src vreg. */
6454 emit_insn (gen_move_insn (target
, src_vreg
));
6456 /* target <- vec_concat: target, mem (Ib, u8). */
6457 mode0
= insn_data
[icode
].operand
[3].mode
;
6458 mode1
= insn_data
[icode
].operand
[1].mode
;
6460 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6461 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6462 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6464 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6465 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6466 error ("operand 2 should be an unsigned 8-bit value");
6468 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6475 case ARC_BUILTIN_VLD64W
:
6476 case ARC_BUILTIN_VLD128
:
6477 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6478 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6480 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6481 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6482 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6484 /* target <- src vreg. */
6485 target
= gen_reg_rtx (V8HImode
);
6487 /* target <- vec_concat: target, mem (Ib, u8). */
6488 mode0
= insn_data
[icode
].operand
[1].mode
;
6489 mode1
= insn_data
[icode
].operand
[2].mode
;
6490 mode2
= insn_data
[icode
].operand
[3].mode
;
6492 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6493 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6494 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6496 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6497 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6498 error ("operand 2 should be an unsigned 8-bit value");
6500 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6508 case ARC_BUILTIN_VST128
:
6509 case ARC_BUILTIN_VST64
:
6510 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6511 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6512 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6514 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6515 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6516 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6517 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6519 mode0
= insn_data
[icode
].operand
[0].mode
;
6520 mode1
= insn_data
[icode
].operand
[1].mode
;
6521 mode2
= insn_data
[icode
].operand
[2].mode
;
6522 mode3
= insn_data
[icode
].operand
[3].mode
;
6524 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6525 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6526 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6528 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6529 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6530 error ("operand 3 should be an unsigned 8-bit value");
6532 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6533 op3
= copy_to_mode_reg (mode3
, op3
);
6535 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6542 case ARC_BUILTIN_VST16_N
:
6543 case ARC_BUILTIN_VST32_N
:
6544 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6545 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6546 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6547 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6549 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6550 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6551 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6552 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6553 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6555 mode0
= insn_data
[icode
].operand
[0].mode
;
6556 mode2
= insn_data
[icode
].operand
[2].mode
;
6557 mode3
= insn_data
[icode
].operand
[3].mode
;
6558 mode4
= insn_data
[icode
].operand
[4].mode
;
6560 /* Do some correctness checks for the operands. */
6561 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6562 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6563 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6565 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6566 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6567 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6569 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6570 op3
= copy_to_mode_reg (mode3
, op3
);
6572 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6573 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6574 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6575 else if (icode
== CODE_FOR_vst32_n_insn
6576 && ((INTVAL (op4
) % 2) != 0))
6577 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6579 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6590 /* 2nd part: Expand regular builtins. */
6592 internal_error ("bad builtin fcode");
6594 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6599 if (target
== NULL_RTX
6600 || GET_MODE (target
) != tmode
6601 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6603 target
= gen_reg_rtx (tmode
);
6608 gcc_assert (n_args
<= 4);
6609 for (i
= 0; i
< n_args
; i
++, j
++)
6611 tree arg
= CALL_EXPR_ARG (exp
, i
);
6612 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6613 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6614 machine_mode opmode
= GET_MODE (op
);
6615 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6617 /* SIMD extension requires exact immediate operand match. */
6618 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6619 && (id
< ARC_BUILTIN_SIMD_END
)
6623 if (!CONST_INT_P (op
))
6624 error ("builtin requires an immediate for operand %d", j
);
6628 if (!satisfies_constraint_L (op
))
6629 error ("operand %d should be a 6 bit unsigned immediate", j
);
6632 if (!satisfies_constraint_P (op
))
6633 error ("operand %d should be a 8 bit unsigned immediate", j
);
6636 if (!satisfies_constraint_K (op
))
6637 error ("operand %d should be a 3 bit unsigned immediate", j
);
6640 error ("unknown builtin immediate operand type for operand %d",
6645 if (CONST_INT_P (op
))
6648 if ((opmode
== SImode
) && (mode
== HImode
))
6651 op
= gen_lowpart (HImode
, op
);
6654 /* In case the insn wants input operands in modes different from
6655 the result, abort. */
6656 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6658 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6659 op
= copy_to_mode_reg (mode
, op
);
6664 pat
= apply_GEN_FCN (icode
, xop
);
6665 if (pat
== NULL_RTX
)
6676 /* Returns true if the operands[opno] is a valid compile-time constant to be
6677 used as register number in the code for builtins. Else it flags an error
6678 and returns false. */
6681 check_if_valid_regno_const (rtx
*operands
, int opno
)
6684 switch (GET_CODE (operands
[opno
]))
6691 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6697 /* Check that after all the constant folding, whether the operand to
6698 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6701 check_if_valid_sleep_operand (rtx
*operands
, int opno
)
6703 switch (GET_CODE (operands
[opno
]))
6707 if( UNSIGNED_INT6 (INTVAL (operands
[opno
])))
6711 fatal_error (input_location
,
6712 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6718 /* Return true if it is ok to make a tail-call to DECL. */
6721 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
6722 tree exp ATTRIBUTE_UNUSED
)
6724 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6725 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6728 /* Everything else is ok. */
6732 /* Output code to add DELTA to the first argument, and then jump
6733 to FUNCTION. Used for C++ multiple inheritance. */
6736 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
6737 HOST_WIDE_INT delta
,
6738 HOST_WIDE_INT vcall_offset
,
6741 int mi_delta
= delta
;
6742 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
6745 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
6749 mi_delta
= - mi_delta
;
6751 /* Add DELTA. When possible use a plain add, otherwise load it into
6752 a register first. */
6754 while (mi_delta
!= 0)
6756 if ((mi_delta
& (3 << shift
)) == 0)
6760 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
6761 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
6762 mi_delta
& (0xff << shift
));
6763 mi_delta
&= ~(0xff << shift
);
6768 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6769 if (vcall_offset
!= 0)
6771 /* ld r12,[this] --> temp = *this
6772 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6774 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6775 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6776 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
6777 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
6778 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
6779 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6780 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
6781 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
6782 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
6785 fnaddr
= XEXP (DECL_RTL (function
), 0);
6787 if (arc_is_longcall_p (fnaddr
))
6791 asm_fprintf (file
, "\tld\t%s, [pcl, @",
6792 ARC_TEMP_SCRATCH_REG
);
6793 assemble_name (file
, XSTR (fnaddr
, 0));
6794 fputs ("@gotpc]\n", file
);
6795 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
6799 fputs ("\tj\t@", file
);
6800 assemble_name (file
, XSTR (fnaddr
, 0));
6805 fputs ("\tb\t@", file
);
6806 assemble_name (file
, XSTR (fnaddr
, 0));
6808 fputs ("@plt\n", file
);
6813 /* Return true if a 32 bit "long_call" should be generated for
6814 this calling SYM_REF. We generate a long_call if the function:
6816 a. has an __attribute__((long call))
6817 or b. the -mlong-calls command line switch has been specified
6819 However we do not generate a long call if the function has an
6820 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6822 This function will be called by C fragments contained in the machine
6823 description file. */
6826 arc_is_longcall_p (rtx sym_ref
)
6828 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6831 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
6832 || (TARGET_LONG_CALLS_SET
6833 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6834 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6838 /* Likewise for short calls. */
6841 arc_is_shortcall_p (rtx sym_ref
)
6843 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6846 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6847 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
6848 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
6849 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6853 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6856 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
6858 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
6862 HOST_WIDE_INT size
= int_size_in_bytes (type
);
6863 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
6868 /* This was in rtlanal.c, and can go in there when we decide we want
6869 to submit the change for inclusion in the GCC tree. */
6870 /* Like note_stores, but allow the callback to have side effects on the rtl
6871 (like the note_stores of yore):
6872 Call FUN on each register or MEM that is stored into or clobbered by X.
6873 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6874 ignored by note_stores, but passed to FUN.
6875 FUN may alter parts of the RTL.
6877 FUN receives three arguments:
6878 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6879 2. the SET or CLOBBER rtx that does the store,
6880 3. the pointer DATA provided to note_stores.
6882 If the item being stored in or clobbered is a SUBREG of a hard register,
6883 the SUBREG will be passed. */
6885 /* For now. */ static
6887 walk_stores (rtx x
, void (*fun
) (rtx
, rtx
, void *), void *data
)
6891 if (GET_CODE (x
) == COND_EXEC
)
6892 x
= COND_EXEC_CODE (x
);
6894 if (GET_CODE (x
) == SET
|| GET_CODE (x
) == CLOBBER
)
6896 rtx dest
= SET_DEST (x
);
6898 while ((GET_CODE (dest
) == SUBREG
6899 && (!REG_P (SUBREG_REG (dest
))
6900 || REGNO (SUBREG_REG (dest
)) >= FIRST_PSEUDO_REGISTER
))
6901 || GET_CODE (dest
) == ZERO_EXTRACT
6902 || GET_CODE (dest
) == STRICT_LOW_PART
)
6903 dest
= XEXP (dest
, 0);
6905 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6906 each of whose first operand is a register. */
6907 if (GET_CODE (dest
) == PARALLEL
)
6909 for (i
= XVECLEN (dest
, 0) - 1; i
>= 0; i
--)
6910 if (XEXP (XVECEXP (dest
, 0, i
), 0) != 0)
6911 (*fun
) (XEXP (XVECEXP (dest
, 0, i
), 0), x
, data
);
6914 (*fun
) (dest
, x
, data
);
6917 else if (GET_CODE (x
) == PARALLEL
)
6918 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
6919 walk_stores (XVECEXP (x
, 0, i
), fun
, data
);
6923 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
6924 machine_mode mode ATTRIBUTE_UNUSED
,
6926 bool named ATTRIBUTE_UNUSED
)
6929 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
6930 || TREE_ADDRESSABLE (type
)));
6933 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6936 arc_can_use_doloop_p (const widest_int
&,
6937 const widest_int
&iterations_max
,
6938 unsigned int loop_depth
, bool entered_at_top
)
6940 /* Considering limitations in the hardware, only use doloop
6941 for innermost loops which must be entered from the top. */
6942 if (loop_depth
> 1 || !entered_at_top
)
6945 /* Check for lp_count width boundary. */
6946 if (arc_lpcwidth
!= 32
6947 && (wi::gtu_p (iterations_max
, ((1 << arc_lpcwidth
) - 1))
6948 || wi::eq_p (iterations_max
, 0)))
6953 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
6954 return why doloop cannot be applied. */
6957 arc_invalid_within_doloop (const rtx_insn
*insn
)
6960 return "Function call in the loop.";
6962 /* FIXME! add here all the ZOL exceptions. */
6966 /* Return true if a load instruction (CONSUMER) uses the same address as a
6967 store instruction (PRODUCER). This function is used to avoid st/ld
6968 address hazard in ARC700 cores. */
6970 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
6972 rtx in_set
, out_set
;
6973 rtx out_addr
, in_addr
;
6981 /* Peel the producer and the consumer for the address. */
6982 out_set
= single_set (producer
);
6985 out_addr
= SET_DEST (out_set
);
6988 if (GET_CODE (out_addr
) == ZERO_EXTEND
6989 || GET_CODE (out_addr
) == SIGN_EXTEND
)
6990 out_addr
= XEXP (out_addr
, 0);
6992 if (!MEM_P (out_addr
))
6995 in_set
= single_set (consumer
);
6998 in_addr
= SET_SRC (in_set
);
7001 if (GET_CODE (in_addr
) == ZERO_EXTEND
7002 || GET_CODE (in_addr
) == SIGN_EXTEND
)
7003 in_addr
= XEXP (in_addr
, 0);
7005 if (!MEM_P (in_addr
))
7007 /* Get rid of the MEM and check if the addresses are
7009 in_addr
= XEXP (in_addr
, 0);
7010 out_addr
= XEXP (out_addr
, 0);
7012 return exp_equiv_p (in_addr
, out_addr
, 0, true);
7018 /* The same functionality as arc_hazard. It is called in machine
7019 reorg before any other optimization. Hence, the NOP size is taken
7020 into account when doing branch shortening. */
7023 workaround_arc_anomaly (void)
7025 rtx_insn
*insn
, *succ0
;
7027 /* For any architecture: call arc_hazard here. */
7028 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7030 succ0
= next_real_insn (insn
);
7031 if (arc_hazard (insn
, succ0
))
7033 emit_insn_before (gen_nopv (), succ0
);
7041 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7043 succ0
= next_real_insn (insn
);
7044 if (arc_store_addr_hazard_p (insn
, succ0
))
7046 emit_insn_after (gen_nopv (), insn
);
7047 emit_insn_after (gen_nopv (), insn
);
7051 /* Avoid adding nops if the instruction between the ST and LD is
7053 succ1
= next_real_insn (succ0
);
7054 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
7055 && arc_store_addr_hazard_p (insn
, succ1
))
7056 emit_insn_after (gen_nopv (), insn
);
7061 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7062 turns out not to be optimizable; we have to split the loop_end pattern into
7063 a subtract and a test. */
7066 hwloop_fail (hwloop_info loop
)
7069 rtx insn
= loop
->loop_end
;
7072 && (loop
->length
&& (loop
->length
<= ARC_MAX_LOOP_LENGTH
))
7073 && REG_P (loop
->iter_reg
))
7075 /* TARGET_V2 has dbnz instructions. */
7076 test
= gen_dbnz (loop
->iter_reg
, loop
->start_label
);
7077 insn
= emit_jump_insn_before (test
, loop
->loop_end
);
7079 else if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
) == LP_COUNT
))
7081 /* We have the lp_count as loop iterator, try to use it. */
7082 emit_insn_before (gen_loop_fail (), loop
->loop_end
);
7083 test
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CC_ZNmode
, CC_REG
),
7085 test
= gen_rtx_IF_THEN_ELSE (VOIDmode
, test
,
7086 gen_rtx_LABEL_REF (Pmode
, loop
->start_label
),
7088 insn
= emit_jump_insn_before (gen_rtx_SET (pc_rtx
, test
),
7093 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
7097 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
7098 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
7104 JUMP_LABEL (insn
) = loop
->start_label
;
7105 LABEL_NUSES (loop
->start_label
)++;
7106 delete_insn (loop
->loop_end
);
7109 /* Optimize LOOP. */
7112 hwloop_optimize (hwloop_info loop
)
7116 basic_block entry_bb
, bb
;
7117 rtx iter_reg
, end_label
;
7118 rtx_insn
*insn
, *seq
, *entry_after
, *last_insn
;
7119 unsigned int length
;
7120 bool need_fix
= false;
7121 rtx lp_reg
= gen_rtx_REG (SImode
, LP_COUNT
);
7123 if (loop
->depth
> 1)
7126 fprintf (dump_file
, ";; loop %d is not innermost\n",
7131 if (!loop
->incoming_dest
)
7134 fprintf (dump_file
, ";; loop %d has more than one entry\n",
7139 if (loop
->incoming_dest
!= loop
->head
)
7142 fprintf (dump_file
, ";; loop %d is not entered from head\n",
7147 if (loop
->has_call
|| loop
->has_asm
)
7150 fprintf (dump_file
, ";; loop %d has invalid insn\n",
7155 /* Scan all the blocks to make sure they don't use iter_reg. */
7156 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
7159 fprintf (dump_file
, ";; loop %d uses iterator\n",
7164 /* Check if start_label appears before doloop_end. */
7166 for (insn
= loop
->start_label
;
7167 insn
&& insn
!= loop
->loop_end
;
7168 insn
= NEXT_INSN (insn
))
7169 length
+= NONDEBUG_INSN_P (insn
) ? get_attr_length (insn
) : 0;
7174 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
7179 loop
->length
= length
;
7180 if (loop
->length
> ARC_MAX_LOOP_LENGTH
)
7183 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7187 /* Check if we use a register or not. */
7188 if (!REG_P (loop
->iter_reg
))
7191 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7196 /* Check if loop register is lpcount. */
7197 if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
)) != LP_COUNT
)
7200 fprintf (dump_file
, ";; loop %d doesn't use lp_count as loop"
7203 /* This loop doesn't use the lp_count, check though if we can
7205 if (TEST_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
)
7206 /* In very unique cases we may have LP_COUNT alive. */
7207 || (loop
->incoming_src
7208 && REGNO_REG_SET_P (df_get_live_out (loop
->incoming_src
),
7215 /* Check for control like instruction as the last instruction of a
7218 last_insn
= PREV_INSN (loop
->loop_end
);
7222 for (; last_insn
!= BB_HEAD (bb
);
7223 last_insn
= PREV_INSN (last_insn
))
7224 if (NONDEBUG_INSN_P (last_insn
))
7227 if (last_insn
!= BB_HEAD (bb
))
7230 if (single_pred_p (bb
)
7231 && single_pred_edge (bb
)->flags
& EDGE_FALLTHRU
7232 && single_pred (bb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
))
7234 bb
= single_pred (bb
);
7235 last_insn
= BB_END (bb
);
7248 fprintf (dump_file
, ";; loop %d has no last instruction\n",
7253 if ((TARGET_ARC600_FAMILY
|| TARGET_HS
)
7254 && INSN_P (last_insn
)
7255 && (JUMP_P (last_insn
) || CALL_P (last_insn
)
7256 || GET_CODE (PATTERN (last_insn
)) == SEQUENCE
7257 || get_attr_type (last_insn
) == TYPE_BRCC
7258 || get_attr_type (last_insn
) == TYPE_BRCC_NO_DELAY_SLOT
))
7260 if (loop
->length
+ 2 > ARC_MAX_LOOP_LENGTH
)
7263 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7267 fprintf (dump_file
, ";; loop %d has a control like last insn;"
7271 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7274 if (LABEL_P (last_insn
))
7277 fprintf (dump_file
, ";; loop %d has a label as last insn;"
7280 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7282 loop
->last_insn
= last_insn
;
7284 /* Get the loop iteration register. */
7285 iter_reg
= loop
->iter_reg
;
7287 gcc_assert (REG_P (iter_reg
));
7291 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
7292 if (entry_edge
->flags
& EDGE_FALLTHRU
)
7295 if (entry_edge
== NULL
)
7298 fprintf (dump_file
, ";; loop %d has no fallthru edge jumping"
7303 /* The loop is good. */
7304 end_label
= gen_label_rtx ();
7305 loop
->end_label
= end_label
;
7307 /* Place the zero_cost_loop_start instruction before the loop. */
7308 entry_bb
= entry_edge
->src
;
7314 /* The loop uses a R-register, but the lp_count is free, thus
7316 emit_insn (gen_movsi (lp_reg
, iter_reg
));
7317 SET_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
);
7321 fprintf (dump_file
, ";; fix loop %d to use lp_count\n",
7326 insn
= emit_insn (gen_arc_lp (iter_reg
,
7333 entry_after
= BB_END (entry_bb
);
7334 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
7341 emit_insn_before (seq
, BB_HEAD (loop
->head
));
7342 seq
= emit_label_before (gen_label_rtx (), seq
);
7343 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
7344 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
7346 if (!(e
->flags
& EDGE_FALLTHRU
))
7347 redirect_edge_and_branch_force (e
, new_bb
);
7349 redirect_edge_succ (e
, new_bb
);
7352 make_edge (new_bb
, loop
->head
, 0);
7357 while (DEBUG_INSN_P (entry_after
)
7358 || (NOTE_P (entry_after
)
7359 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
7360 /* Make sure we don't split a call and its corresponding
7361 CALL_ARG_LOCATION note. */
7362 && NOTE_KIND (entry_after
) != NOTE_INSN_CALL_ARG_LOCATION
))
7363 entry_after
= NEXT_INSN (entry_after
);
7365 entry_after
= next_nonnote_insn_bb (entry_after
);
7367 gcc_assert (entry_after
);
7368 emit_insn_before (seq
, entry_after
);
7371 delete_insn (loop
->loop_end
);
7372 /* Insert the loop end label before the last instruction of the
7374 emit_label_after (end_label
, loop
->last_insn
);
7379 /* A callback for the hw-doloop pass. This function examines INSN; if
7380 it is a loop_end pattern we recognize, return the reg rtx for the
7381 loop counter. Otherwise, return NULL_RTX. */
7384 hwloop_pattern_reg (rtx_insn
*insn
)
7388 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
7391 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
7397 static struct hw_doloop_hooks arc_doloop_hooks
=
7404 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
7405 and tries to rewrite the RTL of these loops so that proper Blackfin
7406 hardware loops are generated. */
7409 arc_reorg_loops (void)
7411 reorg_loops (true, &arc_doloop_hooks
);
7414 static int arc_reorg_in_progress
= 0;
7416 /* ARC's machince specific reorg function. */
7427 cfun
->machine
->arc_reorg_started
= 1;
7428 arc_reorg_in_progress
= 1;
7430 compute_bb_for_insn ();
7434 /* Doloop optimization. */
7437 workaround_arc_anomaly ();
7439 /* FIXME: should anticipate ccfsm action, generate special patterns for
7440 to-be-deleted branches that have no delay slot and have at least the
7441 length of the size increase forced on other insns that are conditionalized.
7442 This can also have an insn_list inside that enumerates insns which are
7443 not actually conditionalized because the destinations are dead in the
7445 Could also tag branches that we want to be unaligned if they get no delay
7446 slot, or even ones that we don't want to do delay slot sheduling for
7447 because we can unalign them.
7449 However, there are cases when conditional execution is only possible after
7450 delay slot scheduling:
7452 - If a delay slot is filled with a nocond/set insn from above, the previous
7453 basic block can become elegible for conditional execution.
7454 - If a delay slot is filled with a nocond insn from the fall-through path,
7455 the branch with that delay slot can become eligble for conditional
7456 execution (however, with the same sort of data flow analysis that dbr
7457 does, we could have figured out before that we don't need to
7458 conditionalize this insn.)
7459 - If a delay slot insn is filled with an insn from the target, the
7460 target label gets its uses decremented (even deleted if falling to zero),
7461 thus possibly creating more condexec opportunities there.
7462 Therefore, we should still be prepared to apply condexec optimization on
7463 non-prepared branches if the size increase of conditionalized insns is no
7464 more than the size saved from eliminating the branch. An invocation option
7465 could also be used to reserve a bit of extra size for condbranches so that
7466 this'll work more often (could also test in arc_reorg if the block is
7467 'close enough' to be eligible for condexec to make this likely, and
7468 estimate required size increase). */
7469 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7470 if (TARGET_NO_BRCC_SET
)
7475 init_insn_lengths();
7478 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
7481 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
7482 df_finish_pass ((flags
& TODO_df_verify
) != 0);
7486 fprintf (dump_file
, ";; After if conversion:\n\n");
7487 print_rtl (dump_file
, get_insns ());
7491 /* Call shorten_branches to calculate the insn lengths. */
7492 shorten_branches (get_insns());
7493 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
7495 if (!INSN_ADDRESSES_SET_P())
7496 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
7498 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7501 enum attr_type insn_type
;
7503 /* If a non-jump insn (or a casesi jump table), continue. */
7504 if (GET_CODE (insn
) != JUMP_INSN
||
7505 GET_CODE (PATTERN (insn
)) == ADDR_VEC
7506 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
7509 /* If we already have a brcc, note if it is suitable for brcc_s.
7510 Be a bit generous with the brcc_s range so that we can take
7511 advantage of any code shortening from delay slot scheduling. */
7512 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
7514 rtx pat
= PATTERN (insn
);
7515 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
7516 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
7518 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7519 if ((offset
>= -140 && offset
< 140)
7520 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
7521 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
7522 && equality_comparison_operator (op
, VOIDmode
))
7523 PUT_MODE (*ccp
, CC_Zmode
);
7524 else if (GET_MODE (*ccp
) == CC_Zmode
)
7525 PUT_MODE (*ccp
, CC_ZNmode
);
7528 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
7529 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
7532 /* OK. so we have a jump insn. */
7533 /* We need to check that it is a bcc. */
7534 /* Bcc => set (pc) (if_then_else ) */
7535 pattern
= PATTERN (insn
);
7536 if (GET_CODE (pattern
) != SET
7537 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
7538 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
7541 /* Now check if the jump is beyond the s9 range. */
7542 if (CROSSING_JUMP_P (insn
))
7544 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7546 if(offset
> 253 || offset
< -254)
7549 pc_target
= SET_SRC (pattern
);
7551 /* Avoid FPU instructions. */
7552 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
7553 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
7556 /* Now go back and search for the set cc insn. */
7558 label
= XEXP (pc_target
, 1);
7562 rtx_insn
*scan
, *link_insn
= NULL
;
7564 for (scan
= PREV_INSN (insn
);
7565 scan
&& GET_CODE (scan
) != CODE_LABEL
;
7566 scan
= PREV_INSN (scan
))
7568 if (! INSN_P (scan
))
7570 pat
= PATTERN (scan
);
7571 if (GET_CODE (pat
) == SET
7572 && cc_register (SET_DEST (pat
), VOIDmode
))
7581 /* Check if this is a data dependency. */
7583 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
7586 /* Ok this is the set cc. copy args here. */
7587 op
= XEXP (pc_target
, 0);
7589 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
7590 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
7591 if (GET_CODE (op0
) == ZERO_EXTRACT
7592 && XEXP (op0
, 1) == const1_rtx
7593 && (GET_CODE (op
) == EQ
7594 || GET_CODE (op
) == NE
))
7596 /* btst / b{eq,ne} -> bbit{0,1} */
7597 op0
= XEXP (cmp0
, 0);
7598 op1
= XEXP (cmp0
, 2);
7600 else if (!register_operand (op0
, VOIDmode
)
7601 || !general_operand (op1
, VOIDmode
))
7603 /* Be careful not to break what cmpsfpx_raw is
7604 trying to create for checking equality of
7605 single-precision floats. */
7606 else if (TARGET_SPFP
7607 && GET_MODE (op0
) == SFmode
7608 && GET_MODE (op1
) == SFmode
)
7611 /* None of the two cmp operands should be set between the
7612 cmp and the branch. */
7613 if (reg_set_between_p (op0
, link_insn
, insn
))
7616 if (reg_set_between_p (op1
, link_insn
, insn
))
7619 /* Since the MODE check does not work, check that this is
7620 CC reg's last set location before insn, and also no
7621 instruction between the cmp and branch uses the
7623 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
7624 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
7627 /* CC reg should be dead after insn. */
7628 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
7631 op
= gen_rtx_fmt_ee (GET_CODE (op
),
7632 GET_MODE (op
), cmp0
, cmp1
);
7633 /* If we create a LIMM where there was none before,
7634 we only benefit if we can avoid a scheduling bubble
7635 for the ARC600. Otherwise, we'd only forgo chances
7636 at short insn generation, and risk out-of-range
7638 if (!brcc_nolimm_operator (op
, VOIDmode
)
7639 && !long_immediate_operand (op1
, VOIDmode
)
7641 || next_active_insn (link_insn
) != insn
))
7644 /* Emit bbit / brcc (or brcc_s if possible).
7645 CC_Zmode indicates that brcc_s is possible. */
7648 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
7649 else if ((offset
>= -140 && offset
< 140)
7650 && rtx_equal_p (op1
, const0_rtx
)
7651 && compact_register_operand (op0
, VOIDmode
)
7652 && (GET_CODE (op
) == EQ
7653 || GET_CODE (op
) == NE
))
7654 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
7656 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
7659 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
7660 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
7661 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
7664 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
7665 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
7667 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
7668 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
7671 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7672 REG_NOTES (brcc_insn
) = note
;
7674 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
7677 remove_note (link_insn
, note
);
7678 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7679 REG_NOTES (brcc_insn
) = note
;
7681 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
7684 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7685 REG_NOTES (brcc_insn
) = note
;
7690 /* Delete the bcc insn. */
7691 set_insn_deleted (insn
);
7693 /* Delete the cmp insn. */
7694 set_insn_deleted (link_insn
);
7699 /* Clear out insn_addresses. */
7700 INSN_ADDRESSES_FREE ();
7704 if (INSN_ADDRESSES_SET_P())
7705 fatal_error (input_location
, "insn addresses not freed");
7707 arc_reorg_in_progress
= 0;
7710 /* Check if the operands are valid for BRcc.d generation
7711 Valid Brcc.d patterns are
7715 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7716 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7717 does not have a delay slot
7719 Assumed precondition: Second operand is either a register or a u6 value. */
7722 valid_brcc_with_delay_p (rtx
*operands
)
7724 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
7726 return brcc_nolimm_operator (operands
[0], VOIDmode
);
7729 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7730 access DECL using %gp_rel(...)($gp). */
7733 arc_in_small_data_p (const_tree decl
)
7737 /* Only variables are going into small data area. */
7738 if (TREE_CODE (decl
) != VAR_DECL
)
7741 if (TARGET_NO_SDATA_SET
)
7744 /* Disable sdata references to weak variables. */
7745 if (DECL_WEAK (decl
))
7748 /* Don't put constants into the small data section: we want them to
7749 be in ROM rather than RAM. */
7750 if (TREE_READONLY (decl
))
7753 /* To ensure -mvolatile-cache works ld.di does not have a
7754 gp-relative variant. */
7755 if (!TARGET_VOLATILE_CACHE_SET
7756 && TREE_THIS_VOLATILE (decl
))
7759 if (DECL_SECTION_NAME (decl
) != 0)
7761 const char *name
= DECL_SECTION_NAME (decl
);
7762 if (strcmp (name
, ".sdata") == 0
7763 || strcmp (name
, ".sbss") == 0)
7766 /* If it's not public, there's no need to put it in the small data
7768 else if (TREE_PUBLIC (decl
))
7770 size
= int_size_in_bytes (TREE_TYPE (decl
));
7771 return (size
> 0 && size
<= g_switch_value
);
7776 /* Return true if X is a small data address that can be rewritten
7780 arc_rewrite_small_data_p (const_rtx x
)
7782 if (GET_CODE (x
) == CONST
)
7785 if (GET_CODE (x
) == PLUS
)
7787 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
7791 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
7793 gcc_assert (SYMBOL_REF_TLS_MODEL (x
) == 0);
7799 /* If possible, rewrite OP so that it refers to small data using
7800 explicit relocations. */
7803 arc_rewrite_small_data_1 (rtx op
)
7805 rtx rgp
= gen_rtx_REG (Pmode
, SDATA_BASE_REGNUM
);
7806 op
= copy_insn (op
);
7807 subrtx_ptr_iterator::array_type array
;
7808 FOR_EACH_SUBRTX_PTR (iter
, array
, &op
, ALL
)
7811 if (arc_rewrite_small_data_p (*loc
))
7813 *loc
= gen_rtx_PLUS (Pmode
, rgp
, *loc
);
7814 iter
.skip_subrtxes ();
7816 else if (GET_CODE (*loc
) == PLUS
7817 && rtx_equal_p (XEXP (*loc
, 0), rgp
))
7818 iter
.skip_subrtxes ();
7824 arc_rewrite_small_data (rtx op
)
7826 op
= arc_rewrite_small_data_1 (op
);
7828 /* Check if we fit small data constraints. */
7830 && !LEGITIMATE_SMALL_DATA_ADDRESS_P (XEXP (op
, 0)))
7832 rtx addr
= XEXP (op
, 0);
7833 rtx tmp
= gen_reg_rtx (Pmode
);
7834 emit_move_insn (tmp
, addr
);
7835 op
= replace_equiv_address_nv (op
, tmp
);
7840 /* Return true if OP refers to small data symbols directly, not through
7844 small_data_pattern (rtx op
, machine_mode
)
7846 if (GET_CODE (op
) == SEQUENCE
)
7849 rtx rgp
= gen_rtx_REG (Pmode
, SDATA_BASE_REGNUM
);
7850 subrtx_iterator::array_type array
;
7851 FOR_EACH_SUBRTX (iter
, array
, op
, ALL
)
7853 const_rtx x
= *iter
;
7854 if (GET_CODE (x
) == PLUS
7855 && rtx_equal_p (XEXP (x
, 0), rgp
))
7856 iter
.skip_subrtxes ();
7857 else if (arc_rewrite_small_data_p (x
))
7863 /* Return true if OP is an acceptable memory operand for ARCompact
7864 16-bit gp-relative load instructions.
7865 op shd look like : [r26, symref@sda]
7866 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7868 /* volatile cache option still to be handled. */
7871 compact_sda_memory_operand (rtx op
, machine_mode mode
, bool short_p
)
7875 tree decl
= NULL_TREE
;
7879 /* Eliminate non-memory operations. */
7880 if (GET_CODE (op
) != MEM
)
7883 if (mode
== VOIDmode
)
7884 mode
= GET_MODE (op
);
7886 size
= GET_MODE_SIZE (mode
);
7888 /* dword operations really put out 2 instructions, so eliminate them. */
7889 if (size
> UNITS_PER_WORD
)
7892 /* Decode the address now. */
7893 addr
= XEXP (op
, 0);
7895 if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
))
7898 if (!short_p
|| size
== 1)
7901 /* Now check for the alignment, the short loads using gp require the
7902 addresses to be aligned. */
7903 if (GET_CODE (XEXP (addr
, 1)) == SYMBOL_REF
)
7904 decl
= SYMBOL_REF_DECL (XEXP (addr
, 1));
7905 else if (GET_CODE (XEXP (XEXP (XEXP (addr
, 1), 0), 0)) == SYMBOL_REF
)
7906 decl
= SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr
, 1), 0), 0));
7908 align
= DECL_ALIGN (decl
);
7909 align
= align
/ BITS_PER_UNIT
;
7921 if (align
&& ((align
& mask
) == 0))
7926 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7929 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
7930 unsigned HOST_WIDE_INT size
,
7931 unsigned HOST_WIDE_INT align
,
7932 unsigned HOST_WIDE_INT globalize_p
)
7934 int in_small_data
= arc_in_small_data_p (decl
);
7937 switch_to_section (get_named_section (NULL
, ".sbss", 0));
7938 /* named_section (0,".sbss",0); */
7940 switch_to_section (bss_section
);
7943 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
7945 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
7946 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
7947 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
7948 ASM_OUTPUT_LABEL (stream
, name
);
7951 ASM_OUTPUT_SKIP (stream
, size
);
7955 arc_preserve_reload_p (rtx in
)
7957 return (GET_CODE (in
) == PLUS
7958 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
7959 && CONST_INT_P (XEXP (in
, 1))
7960 && !((INTVAL (XEXP (in
, 1)) & 511)));
7964 arc_register_move_cost (machine_mode
,
7965 enum reg_class from_class
, enum reg_class to_class
)
7967 /* The ARC600 has no bypass for extension registers, hence a nop might be
7968 needed to be inserted after a write so that reads are safe. */
7971 if (to_class
== MPY_WRITABLE_CORE_REGS
)
7973 /* Instructions modifying LP_COUNT need 4 additional cycles before
7974 the register will actually contain the value. */
7975 else if (to_class
== LPCOUNT_REG
)
7977 else if (to_class
== WRITABLE_CORE_REGS
)
7981 /* Using lp_count as scratch reg is a VERY bad idea. */
7982 if (from_class
== LPCOUNT_REG
)
7984 if (to_class
== LPCOUNT_REG
)
7987 /* Force an attempt to 'mov Dy,Dx' to spill. */
7988 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
7989 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
7995 /* Emit code for an addsi3 instruction with OPERANDS.
7996 COND_P indicates if this will use conditional execution.
7997 Return the length of the instruction.
7998 If OUTPUT_P is false, don't actually output the instruction, just return
8001 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
8005 int match
= operands_match_p (operands
[0], operands
[1]);
8006 int match2
= operands_match_p (operands
[0], operands
[2]);
8007 int intval
= (REG_P (operands
[2]) ? 1
8008 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
8009 int neg_intval
= -intval
;
8010 int short_0
= satisfies_constraint_Rcq (operands
[0]);
8011 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
8014 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8015 && REGNO (OP) != 30) \
8018 #define ADDSI_OUTPUT1(FORMAT) do {\
8020 output_asm_insn (FORMAT, operands);\
8023 #define ADDSI_OUTPUT(LIST) do {\
8026 ADDSI_OUTPUT1 (format);\
8030 /* First try to emit a 16 bit insn. */
8033 /* If we are actually about to output this insn, don't try a 16 bit
8034 variant if we already decided that we don't want that
8035 (I.e. we upsized this insn to align some following insn.)
8036 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8037 but add1 r0,sp,35 doesn't. */
8038 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
8040 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8043 && ((REG_H_P (operands
[2])
8044 && (match
|| satisfies_constraint_Rcq (operands
[2])))
8045 || (CONST_INT_P (operands
[2])
8046 && ((unsigned) intval
<= (match
? 127 : 7)))))
8047 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8049 /* Generate add_s b,b,h patterns. */
8050 if (short_0
&& match2
&& REG_H_P (operands
[1]))
8051 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8053 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8054 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
8055 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
8056 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8058 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
8059 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
8060 && match
&& !(neg_intval
& ~124)))
8061 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8063 /* Generate add_s h,h,s3 patterns. */
8064 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
8065 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
8066 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8068 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8069 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
8070 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
8071 && satisfies_constraint_Rcq (operands
[1])
8072 && satisfies_constraint_L (operands
[2]))
8073 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8076 /* Now try to emit a 32 bit insn without long immediate. */
8078 if (!match
&& match2
&& REG_P (operands
[1]))
8079 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8080 if (match
|| !cond_p
)
8082 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
8083 int range_factor
= neg_intval
& intval
;
8086 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
8087 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8089 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8090 same size, do, so - the insn latency is lower. */
8091 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8093 if ((intval
>= 0 && intval
<= limit
)
8094 || (intval
== -0x800 && limit
== 0x7ff))
8095 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8096 else if ((intval
< 0 && neg_intval
<= limit
)
8097 || (intval
== 0x800 && limit
== 0x7ff))
8098 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8099 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
8100 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
8101 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
8102 if (((intval
< 0 && intval
!= -0x4000)
8103 /* sub[123] is slower than add_s / sub, only use it if it
8104 avoids a long immediate. */
8105 && neg_intval
<= limit
<< shift
)
8106 || (intval
== 0x4000 && limit
== 0x7ff))
8107 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
8108 shift
, neg_intval
>> shift
));
8109 else if ((intval
>= 0 && intval
<= limit
<< shift
)
8110 || (intval
== -0x4000 && limit
== 0x7ff))
8111 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
8113 /* Try to emit a 16 bit opcode with long immediate. */
8115 if (short_p
&& match
)
8116 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
8118 /* We have to use a 32 bit opcode, and with a long immediate. */
8120 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
8123 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8124 Return the length of the instruction.
8125 If OUTPUT_P is false, don't actually output the instruction, just return
8128 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
8130 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
8131 const char *pat
= NULL
;
8133 /* Canonical rtl should not have a constant in the first operand position. */
8134 gcc_assert (!CONSTANT_P (operands
[1]));
8136 switch (commutative_op
)
8139 if (satisfies_constraint_C1p (operands
[2]))
8140 pat
= "bmsk%? %0,%1,%Z2";
8141 else if (satisfies_constraint_C2p (operands
[2]))
8143 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
8144 pat
= "bmskn%? %0,%1,%Z2";
8146 else if (satisfies_constraint_Ccp (operands
[2]))
8147 pat
= "bclr%? %0,%1,%M2";
8148 else if (satisfies_constraint_CnL (operands
[2]))
8149 pat
= "bic%? %0,%1,%n2-1";
8152 if (satisfies_constraint_C0p (operands
[2]))
8153 pat
= "bset%? %0,%1,%z2";
8156 if (satisfies_constraint_C0p (operands
[2]))
8157 pat
= "bxor%? %0,%1,%z2";
8160 return arc_output_addsi (operands
, true, output_p
);
8164 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
8165 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
8170 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8171 Emit code and return an potentially modified address such that offsets
8172 up to SIZE are can be added to yield a legitimate address.
8173 if REUSE is set, ADDR is a register that may be modified. */
8176 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
8179 rtx offs
= const0_rtx
;
8181 if (GET_CODE (base
) == PLUS
)
8183 offs
= XEXP (base
, 1);
8184 base
= XEXP (base
, 0);
8187 || (REGNO (base
) != STACK_POINTER_REGNUM
8188 && REGNO_PTR_FRAME_P (REGNO (base
)))
8189 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
8190 || !SMALL_INT (INTVAL (offs
) + size
))
8193 emit_insn (gen_add2_insn (addr
, offs
));
8195 addr
= copy_to_mode_reg (Pmode
, addr
);
8200 /* Like move_by_pieces, but take account of load latency, and actual
8201 offset ranges. Return true on success. */
8204 arc_expand_movmem (rtx
*operands
)
8206 rtx dst
= operands
[0];
8207 rtx src
= operands
[1];
8208 rtx dst_addr
, src_addr
;
8210 int align
= INTVAL (operands
[3]);
8217 if (!CONST_INT_P (operands
[2]))
8219 size
= INTVAL (operands
[2]);
8220 /* move_by_pieces_ninsns is static, so we can't use it. */
8224 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
8226 n_pieces
= (size
+ 2) / 4U + (size
& 1);
8228 else if (align
== 2)
8229 n_pieces
= (size
+ 1) / 2U;
8232 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
8234 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8236 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
8240 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
8241 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
8242 store
[0] = store
[1] = NULL_RTX
;
8243 tmpx
[0] = tmpx
[1] = NULL_RTX
;
8244 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
8249 while (piece
> size
)
8251 mode
= smallest_int_mode_for_size (piece
* BITS_PER_UNIT
);
8252 /* If we don't re-use temporaries, the scheduler gets carried away,
8253 and the register pressure gets unnecessarily high. */
8254 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
8257 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
8258 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
8259 src_addr
= force_offsettable (src_addr
, piece
, 1);
8261 emit_insn (store
[i
]);
8262 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
8263 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
8264 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
8265 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
8268 emit_insn (store
[i
]);
8270 emit_insn (store
[i
^1]);
8274 /* Prepare operands for move in MODE. Return true iff the move has
8278 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8280 /* We used to do this only for MODE_INT Modes, but addresses to floating
8281 point variables may well be in the small data section. */
8282 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[0], Pmode
))
8283 operands
[0] = arc_rewrite_small_data (operands
[0]);
8285 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
8287 prepare_pic_move (operands
, SImode
);
8289 /* Disable any REG_EQUALs associated with the symref
8290 otherwise the optimization pass undoes the work done
8291 here and references the variable directly. */
8294 if (GET_CODE (operands
[0]) != MEM
8295 && !TARGET_NO_SDATA_SET
8296 && small_data_pattern (operands
[1], Pmode
))
8298 /* This is to take care of address calculations involving sdata
8300 operands
[1] = arc_rewrite_small_data (operands
[1]);
8302 emit_insn (gen_rtx_SET (operands
[0],operands
[1]));
8303 /* ??? This note is useless, since it only restates the set itself.
8304 We should rather use the original SYMBOL_REF. However, there is
8305 the problem that we are lying to the compiler about these
8306 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8307 so that we can tell it apart from an actual symbol. */
8308 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8310 /* Take care of the REG_EQUAL note that will be attached to mark the
8311 output reg equal to the initial symbol_ref after this code is
8313 emit_move_insn (operands
[0], operands
[0]);
8317 if (MEM_P (operands
[0])
8318 && !(reload_in_progress
|| reload_completed
))
8320 operands
[1] = force_reg (mode
, operands
[1]);
8321 if (!move_dest_operand (operands
[0], mode
))
8323 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
8324 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8325 except that we can't use that function because it is static. */
8326 rtx pat
= change_address (operands
[0], mode
, addr
);
8327 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8330 if (!cse_not_expected
)
8332 rtx pat
= XEXP (operands
[0], 0);
8334 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8337 pat
= change_address (operands
[0], mode
, pat
);
8338 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8344 if (MEM_P (operands
[1]) && !cse_not_expected
)
8346 rtx pat
= XEXP (operands
[1], 0);
8348 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8351 pat
= change_address (operands
[1], mode
, pat
);
8352 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
8360 /* Prepare OPERANDS for an extension using CODE to OMODE.
8361 Return true iff the move has been emitted. */
8364 prepare_extend_operands (rtx
*operands
, enum rtx_code code
,
8367 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[1], Pmode
))
8369 /* This is to take care of address calculations involving sdata
8372 = gen_rtx_fmt_e (code
, omode
, arc_rewrite_small_data (operands
[1]));
8373 emit_insn (gen_rtx_SET (operands
[0], operands
[1]));
8374 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8376 /* Take care of the REG_EQUAL note that will be attached to mark the
8377 output reg equal to the initial extension after this code is
8379 emit_move_insn (operands
[0], operands
[0]);
8385 /* Output a library call to a function called FNAME that has been arranged
8386 to be local to any dso. */
8389 arc_output_libcall (const char *fname
)
8391 unsigned len
= strlen (fname
);
8392 static char buf
[64];
8394 gcc_assert (len
< sizeof buf
- 35);
8395 if (TARGET_LONG_CALLS_SET
8396 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
8399 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
8401 sprintf (buf
, "jl%%! @%s", fname
);
8404 sprintf (buf
, "bl%%!%%* @%s", fname
);
8408 /* Return the SImode highpart of the DImode value IN. */
8411 disi_highpart (rtx in
)
8413 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
8416 /* Return length adjustment for INSN.
8418 A write to a core reg greater or equal to 32 must not be immediately
8419 followed by a use. Anticipate the length requirement to insert a nop
8420 between PRED and SUCC to prevent a hazard. */
8423 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8427 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8428 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
8429 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
8430 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
8431 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
8432 || recog_memoized (pred
) == CODE_FOR_umul_600
8433 || recog_memoized (pred
) == CODE_FOR_mac_600
8434 || recog_memoized (pred
) == CODE_FOR_mul64_600
8435 || recog_memoized (pred
) == CODE_FOR_mac64_600
8436 || recog_memoized (pred
) == CODE_FOR_umul64_600
8437 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
8439 subrtx_iterator::array_type array
;
8440 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
8442 const_rtx x
= *iter
;
8443 switch (GET_CODE (x
))
8445 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8448 /* This is also fine for PRE/POST_MODIFY, because they
8452 rtx dest
= XEXP (x
, 0);
8453 /* Check if this sets a an extension register. N.B. we use 61 for the
8454 condition codes, which is definitely not an extension register. */
8455 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
8456 /* Check if the same register is used by the PAT. */
8457 && (refers_to_regno_p
8459 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
8460 PATTERN (succ
), 0)))
8466 /* Given a rtx, check if it is an assembly instruction or not. */
8469 arc_asm_insn_p (rtx x
)
8476 switch (GET_CODE (x
))
8483 return arc_asm_insn_p (SET_SRC (x
));
8487 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8488 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
8501 A write to a core reg greater or equal to 32 must not be immediately
8502 followed by a use. Anticipate the length requirement to insert a nop
8503 between PRED and SUCC to prevent a hazard. */
8506 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8508 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
8512 return arc600_corereg_hazard (pred
, succ
);
8517 /* Return length adjustment for INSN. */
8520 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
8524 /* We already handle sequences by ignoring the delay sequence flag. */
8525 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8528 /* Check for return with but one preceding insn since function
8530 if (TARGET_PAD_RETURN
8532 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
8533 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
8534 && get_attr_type (insn
) == TYPE_RETURN
)
8536 rtx_insn
*prev
= prev_active_insn (insn
);
8538 if (!prev
|| !(prev
= prev_active_insn (prev
))
8539 || ((NONJUMP_INSN_P (prev
)
8540 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8541 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8543 : CALL_ATTR (prev
, NON_SIBCALL
)))
8548 rtx_insn
*succ
= next_real_insn (insn
);
8550 /* One the ARC600, a write to an extension register must be separated
8552 if (succ
&& INSN_P (succ
))
8553 len
+= arc600_corereg_hazard (insn
, succ
);
8556 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8558 extract_constrain_insn_cached (insn
);
8563 /* Values for length_sensitive. */
8567 ARC_LS_25
, // 25 bit offset, B
8568 ARC_LS_21
, // 21 bit offset, Bcc
8569 ARC_LS_U13
,// 13 bit unsigned offset, LP
8570 ARC_LS_10
, // 10 bit offset, B_s, Beq_s, Bne_s
8571 ARC_LS_9
, // 9 bit offset, BRcc
8572 ARC_LS_8
, // 8 bit offset, BRcc_s
8573 ARC_LS_U7
, // 7 bit unsigned offset, LPcc
8574 ARC_LS_7
// 7 bit offset, Bcc_s
8577 /* While the infrastructure patch is waiting for review, duplicate the
8578 struct definitions, to allow this file to compile. */
8583 /* Cost as a branch / call target or call return address. */
8585 int fallthrough_cost
;
8588 /* 0 for not length sensitive, 1 for largest offset range,
8589 * 2 for next smaller etc. */
8590 unsigned length_sensitive
: 8;
8592 } insn_length_variant_t
;
8594 typedef struct insn_length_parameters_s
8599 int (*get_variants
) (rtx_insn
*, int, bool, bool, insn_length_variant_t
*);
8600 } insn_length_parameters_t
;
8603 arc_insn_length_parameters (insn_length_parameters_t
*ilp
) ATTRIBUTE_UNUSED
;
8607 arc_get_insn_variants (rtx_insn
*insn
, int len
, bool, bool target_p
,
8608 insn_length_variant_t
*ilv
)
8610 if (!NONDEBUG_INSN_P (insn
))
8612 enum attr_type type
;
8613 /* shorten_branches doesn't take optimize_size into account yet for the
8614 get_variants mechanism, so turn this off for now. */
8617 if (rtx_sequence
*pat
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
8619 /* The interaction of a short delay slot insn with a short branch is
8620 too weird for shorten_branches to piece together, so describe the
8623 if (TARGET_UPSIZE_DBR
8624 && get_attr_length (pat
->insn (1)) <= 2
8625 && (((type
= get_attr_type (inner
= pat
->insn (0)))
8626 == TYPE_UNCOND_BRANCH
)
8627 || type
== TYPE_BRANCH
)
8628 && get_attr_delay_slot_filled (inner
) == DELAY_SLOT_FILLED_YES
)
8631 = arc_get_insn_variants (inner
, get_attr_length (inner
), true,
8633 /* The short variant gets split into a higher-cost aligned
8634 and a lower cost unaligned variant. */
8635 gcc_assert (n_variants
);
8636 gcc_assert (ilv
[1].length_sensitive
== ARC_LS_7
8637 || ilv
[1].length_sensitive
== ARC_LS_10
);
8638 gcc_assert (ilv
[1].align_set
== 3);
8640 ilv
[0].align_set
= 1;
8641 ilv
[0].branch_cost
+= 1;
8642 ilv
[1].align_set
= 2;
8644 for (int i
= 0; i
< n_variants
; i
++)
8646 /* In case an instruction with aligned size is wanted, and
8647 the short variants are unavailable / too expensive, add
8648 versions of long branch + long delay slot. */
8649 for (int i
= 2, end
= n_variants
; i
< end
; i
++, n_variants
++)
8651 ilv
[n_variants
] = ilv
[i
];
8652 ilv
[n_variants
].length
+= 2;
8658 insn_length_variant_t
*first_ilv
= ilv
;
8659 type
= get_attr_type (insn
);
8661 = (get_attr_delay_slot_filled (insn
) == DELAY_SLOT_FILLED_YES
);
8662 int branch_align_cost
= delay_filled
? 0 : 1;
8663 int branch_unalign_cost
= delay_filled
? 0 : TARGET_UNALIGN_BRANCH
? 0 : 1;
8664 /* If the previous instruction is an sfunc call, this insn is always
8665 a target, even though the middle-end is unaware of this. */
8666 bool force_target
= false;
8667 rtx_insn
*prev
= prev_active_insn (insn
);
8668 if (prev
&& arc_next_active_insn (prev
, 0) == insn
8669 && ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8670 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8672 : (CALL_ATTR (prev
, NON_SIBCALL
)
8673 && NEXT_INSN (PREV_INSN (prev
)) == prev
)))
8674 force_target
= true;
8679 /* Short BRCC only comes in no-delay-slot version, and without limm */
8684 ilv
->branch_cost
= 1;
8685 ilv
->enabled
= (len
== 2);
8686 ilv
->length_sensitive
= ARC_LS_8
;
8690 case TYPE_BRCC_NO_DELAY_SLOT
:
8691 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8692 (delay slot) scheduling purposes, but they are longer. */
8693 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8694 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 1)) == SET
)
8696 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8697 ilv
->length
= ((type
== TYPE_BRCC
) ? 4 : 8);
8699 ilv
->branch_cost
= branch_align_cost
;
8700 ilv
->enabled
= (len
<= ilv
->length
);
8701 ilv
->length_sensitive
= ARC_LS_9
;
8702 if ((target_p
|| force_target
)
8703 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8709 ilv
->target_cost
= 1;
8710 ilv
->branch_cost
= branch_unalign_cost
;
8715 op
= XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 0);
8718 if (GET_CODE (op0
) == ZERO_EXTRACT
8719 && satisfies_constraint_L (XEXP (op0
, 2)))
8720 op0
= XEXP (op0
, 0);
8721 if (satisfies_constraint_Rcq (op0
))
8723 ilv
->length
= ((type
== TYPE_BRCC
) ? 6 : 10);
8725 ilv
->branch_cost
= 1 + branch_align_cost
;
8726 ilv
->fallthrough_cost
= 1;
8727 ilv
->enabled
= true;
8728 ilv
->length_sensitive
= ARC_LS_21
;
8729 if (!delay_filled
&& TARGET_UNALIGN_BRANCH
)
8735 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8739 ilv
->length
= ((type
== TYPE_BRCC
) ? 8 : 12);
8741 ilv
->branch_cost
= 1 + branch_align_cost
;
8742 ilv
->fallthrough_cost
= 1;
8743 ilv
->enabled
= true;
8744 ilv
->length_sensitive
= ARC_LS_21
;
8745 if ((target_p
|| force_target
)
8746 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8752 ilv
->target_cost
= 1;
8753 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8761 case TYPE_CALL_NO_DELAY_SLOT
:
8766 ilv
->length_sensitive
8767 = GET_CODE (PATTERN (insn
)) == COND_EXEC
? ARC_LS_21
: ARC_LS_25
;
8770 ilv
->fallthrough_cost
= branch_align_cost
;
8771 ilv
->enabled
= true;
8772 if ((target_p
|| force_target
)
8773 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8779 ilv
->target_cost
= 1;
8780 ilv
->fallthrough_cost
= branch_unalign_cost
;
8784 case TYPE_UNCOND_BRANCH
:
8785 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8786 but that makes no difference at the moment. */
8787 ilv
->length_sensitive
= ARC_LS_7
;
8788 ilv
[1].length_sensitive
= ARC_LS_25
;
8791 ilv
->length_sensitive
= ARC_LS_10
;
8792 ilv
[1].length_sensitive
= ARC_LS_21
;
8796 ilv
->branch_cost
= branch_align_cost
;
8797 ilv
->enabled
= (len
== ilv
->length
);
8801 ilv
->branch_cost
= branch_align_cost
;
8802 ilv
->enabled
= true;
8803 if ((target_p
|| force_target
)
8804 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8810 ilv
->target_cost
= 1;
8811 ilv
->branch_cost
= branch_unalign_cost
;
8818 /* For every short insn, there is generally also a long insn.
8819 trap_s is an exception. */
8820 if ((len
& 2) == 0 || recog_memoized (insn
) == CODE_FOR_trap_s
)
8827 ilv
->length
= len
+ 2;
8829 if (target_p
|| force_target
)
8835 ilv
->target_cost
= 1;
8839 /* If the previous instruction is an sfunc call, this insn is always
8840 a target, even though the middle-end is unaware of this.
8841 Therefore, if we have a call predecessor, transfer the target cost
8842 to the fallthrough and branch costs. */
8845 for (insn_length_variant_t
*p
= first_ilv
; p
< ilv
; p
++)
8847 p
->fallthrough_cost
+= p
->target_cost
;
8848 p
->branch_cost
+= p
->target_cost
;
8853 return ilv
- first_ilv
;
8857 arc_insn_length_parameters (insn_length_parameters_t
*ilp
)
8859 ilp
->align_unit_log
= 1;
8860 ilp
->align_base_log
= 1;
8861 ilp
->max_variants
= 7;
8862 ilp
->get_variants
= arc_get_insn_variants
;
8865 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8866 CC field of *STATEP. */
8869 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8871 rtx cond
= statep
->cond
;
8872 int raw_cc
= get_arc_condition_code (cond
);
8874 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8876 if (statep
->cc
== raw_cc
)
8877 return copy_rtx (cond
);
8879 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8881 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8882 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8883 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8884 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8886 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8887 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8890 /* Return version of PAT conditionalized with COND, which is part of INSN.
8891 ANNULLED indicates if INSN is an annulled delay-slot insn.
8892 Register further changes if necessary. */
8894 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8896 /* For commutative operators, we generally prefer to have
8897 the first source match the destination. */
8898 if (GET_CODE (pat
) == SET
)
8900 rtx src
= SET_SRC (pat
);
8902 if (COMMUTATIVE_P (src
))
8904 rtx src0
= XEXP (src
, 0);
8905 rtx src1
= XEXP (src
, 1);
8906 rtx dst
= SET_DEST (pat
);
8908 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8909 /* Leave add_n alone - the canonical form is to
8910 have the complex summand first. */
8912 pat
= gen_rtx_SET (dst
,
8913 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8918 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8919 what to do with COND_EXEC. */
8920 if (RTX_FRAME_RELATED_P (insn
))
8922 /* If this is the delay slot insn of an anulled branch,
8923 dwarf2out.c:scan_trace understands the anulling semantics
8924 without the COND_EXEC. */
8925 gcc_assert (annulled
);
8926 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8928 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8930 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8934 /* Use the ccfsm machinery to do if conversion. */
8939 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8941 memset (statep
, 0, sizeof *statep
);
8942 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8944 arc_ccfsm_advance (insn
, statep
);
8946 switch (statep
->state
)
8952 /* Deleted branch. */
8953 arc_ccfsm_post_advance (insn
, statep
);
8954 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8955 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8956 if (GET_CODE (PATTERN (seq
)) == SEQUENCE
)
8958 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8959 rtx pat
= PATTERN (slot
);
8960 if (INSN_ANNULLED_BRANCH_P (insn
))
8963 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8964 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8966 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8968 PUT_CODE (slot
, NOTE
);
8969 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
8973 set_insn_deleted (insn
);
8979 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
8981 arc_ccfsm_post_advance (insn
, statep
);
8982 if (--LABEL_NUSES (insn
) == 0)
8988 if (!NONDEBUG_INSN_P (insn
))
8991 /* Conditionalized insn. */
8993 rtx_insn
*prev
, *pprev
;
8994 rtx
*patp
, pat
, cond
;
8995 bool annulled
; annulled
= false;
8997 /* If this is a delay slot insn in a non-annulled branch,
8998 don't conditionalize it. N.B., this should be fine for
8999 conditional return too. However, don't do this for
9000 unconditional branches, as these would be encountered when
9001 processing an 'else' part. */
9002 prev
= PREV_INSN (insn
);
9003 pprev
= PREV_INSN (prev
);
9004 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
9005 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
9007 if (!INSN_ANNULLED_BRANCH_P (prev
))
9012 patp
= &PATTERN (insn
);
9014 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
9015 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
9017 /* ??? don't conditionalize if all side effects are dead
9018 in the not-execute case. */
9020 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
9022 else if (simplejump_p (insn
))
9024 patp
= &SET_SRC (pat
);
9025 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
9027 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
9029 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
9030 pat
= gen_rtx_SET (pc_rtx
, pat
);
9034 validate_change (insn
, patp
, pat
, 1);
9035 if (!apply_change_group ())
9039 rtx_insn
*next
= next_nonnote_insn (insn
);
9040 if (GET_CODE (next
) == BARRIER
)
9042 if (statep
->state
== 3)
9049 arc_ccfsm_post_advance (insn
, statep
);
9054 /* Find annulled delay insns and convert them to use the appropriate predicate.
9055 This allows branch shortening to size up these insns properly. */
9058 arc_predicate_delay_insns (void)
9060 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9062 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
9065 if (!NONJUMP_INSN_P (insn
)
9066 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
9068 jump
= XVECEXP (pat
, 0, 0);
9069 dlay
= XVECEXP (pat
, 0, 1);
9070 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
9072 /* If the branch insn does the annulling, leave the delay insn alone. */
9073 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
9075 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9076 on the other path. */
9077 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
9078 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
9079 src
= SET_SRC (PATTERN (jump
));
9080 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
9081 cond
= XEXP (src
, 0);
9082 if (XEXP (src
, 2) == pc_rtx
)
9084 else if (XEXP (src
, 1) == pc_rtx
)
9088 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
9090 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9091 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9092 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9093 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9095 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9096 copy_rtx (XEXP (cond
, 0)),
9097 copy_rtx (XEXP (cond
, 1)));
9100 cond
= copy_rtx (cond
);
9101 patp
= &PATTERN (dlay
);
9103 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9104 validate_change (dlay
, patp
, pat
, 1);
9105 if (!apply_change_group ())
9111 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9112 (other than of a forward brcc), it creates a hazard when there is a read
9113 of the same register at the branch target. We can't know what is at the
9114 branch target of calls, and for branches, we don't really know before the
9115 end of delay slot scheduling, either. Not only can individual instruction
9116 be hoisted out into a delay slot, a basic block can also be emptied this
9117 way, and branch and/or fall through targets be redirected. Hence we don't
9118 want such writes in a delay slot. */
9120 /* Return nonzreo iff INSN writes to an extension core register. */
9123 arc_write_ext_corereg (rtx insn
)
9125 subrtx_iterator::array_type array
;
9126 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9128 const_rtx x
= *iter
;
9129 switch (GET_CODE (x
))
9131 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9134 /* This is also fine for PRE/POST_MODIFY, because they
9138 const_rtx dest
= XEXP (x
, 0);
9139 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9145 /* This is like the hook, but returns NULL when it can't / won't generate
9146 a legitimate address. */
9149 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9154 if (flag_pic
&& SYMBOLIC_CONST (x
))
9155 (x
) = arc_legitimize_pic_address (x
, 0);
9157 if (GET_CODE (addr
) == CONST
)
9158 addr
= XEXP (addr
, 0);
9159 if (GET_CODE (addr
) == PLUS
9160 && CONST_INT_P (XEXP (addr
, 1))
9161 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9162 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9163 || (REG_P (XEXP (addr
, 0))
9164 && (INTVAL (XEXP (addr
, 1)) & 252))))
9166 HOST_WIDE_INT offs
, upper
;
9167 int size
= GET_MODE_SIZE (mode
);
9169 offs
= INTVAL (XEXP (addr
, 1));
9170 upper
= (offs
+ 256 * size
) & ~511 * size
;
9171 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9172 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9173 if (GET_CODE (x
) == CONST
)
9174 inner
= gen_rtx_CONST (Pmode
, inner
);
9176 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9179 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9180 x
= force_reg (Pmode
, x
);
9181 if (memory_address_p ((machine_mode
) mode
, x
))
9187 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9189 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9191 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9193 return arc_legitimize_tls_address (orig_x
, model
);
9196 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9204 arc_delegitimize_address_0 (rtx x
)
9208 if (GET_CODE (x
) == CONST
&& GET_CODE (u
= XEXP (x
, 0)) == UNSPEC
)
9210 if (XINT (u
, 1) == ARC_UNSPEC_GOT
9211 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
)
9212 return XVECEXP (u
, 0, 0);
9214 else if (GET_CODE (x
) == CONST
&& GET_CODE (p
= XEXP (x
, 0)) == PLUS
9215 && GET_CODE (u
= XEXP (p
, 0)) == UNSPEC
9216 && (XINT (u
, 1) == ARC_UNSPEC_GOT
9217 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
))
9218 return gen_rtx_CONST
9220 gen_rtx_PLUS (GET_MODE (p
), XVECEXP (u
, 0, 0), XEXP (p
, 1)));
9221 else if (GET_CODE (x
) == PLUS
9222 && ((REG_P (gp
= XEXP (x
, 0))
9223 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9224 || (GET_CODE (gp
) == CONST
9225 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9226 && XINT (u
, 1) == ARC_UNSPEC_GOT
9227 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9228 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9229 && GET_CODE (XEXP (x
, 1)) == CONST
9230 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9231 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9232 return XVECEXP (u
, 0, 0);
9233 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 0)) == PLUS
9234 && ((REG_P (gp
= XEXP (XEXP (x
, 0), 1))
9235 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9236 || (GET_CODE (gp
) == CONST
9237 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9238 && XINT (u
, 1) == ARC_UNSPEC_GOT
9239 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9240 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9241 && GET_CODE (XEXP (x
, 1)) == CONST
9242 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9243 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9244 return gen_rtx_PLUS (GET_MODE (x
), XEXP (XEXP (x
, 0), 0),
9246 else if (GET_CODE (x
) == PLUS
9247 && (u
= arc_delegitimize_address_0 (XEXP (x
, 1))))
9248 return gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0), u
);
9253 arc_delegitimize_address (rtx x
)
9255 rtx orig_x
= x
= delegitimize_mem_from_attrs (x
);
9256 if (GET_CODE (x
) == MEM
)
9258 x
= arc_delegitimize_address_0 (x
);
9262 x
= replace_equiv_address_nv (orig_x
, x
);
9268 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9269 differ from the hardware register number in order to allow the generic
9270 code to correctly split the concatenation of acc1 and acc2. */
9275 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9278 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9279 differ from the hardware register number in order to allow the generic
9280 code to correctly split the concatenation of acc1 and acc2. */
9285 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9288 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9289 differ from the hardware register number in order to allow the generic
9290 code to correctly split the concatenation of mhi and mlo. */
9295 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9298 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9299 differ from the hardware register number in order to allow the generic
9300 code to correctly split the concatenation of mhi and mlo. */
9305 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9308 /* FIXME: a parameter should be added, and code added to final.c,
9309 to reproduce this functionality in shorten_branches. */
9311 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9312 a previous instruction. */
9314 arc_unalign_branch_p (rtx branch
)
9318 if (!TARGET_UNALIGN_BRANCH
)
9320 /* Do not do this if we have a filled delay slot. */
9321 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9322 && !NEXT_INSN (branch
)->deleted ())
9324 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9326 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9327 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9331 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9332 are three reasons why we need to consider branches to be length 6:
9333 - annull-false delay slot insns are implemented using conditional execution,
9334 thus preventing short insn formation where used.
9335 - for ARC600: annul-true delay slot insns are implemented where possible
9336 using conditional execution, preventing short insn formation where used.
9337 - for ARC700: likely or somewhat likely taken branches are made long and
9338 unaligned if possible to avoid branch penalty. */
9341 arc_branch_size_unknown_p (void)
9343 return !optimize_size
&& arc_reorg_in_progress
;
9346 /* We are about to output a return insn. Add padding if necessary to avoid
9347 a mispredict. A return could happen immediately after the function
9348 start, but after a call we know that there will be at least a blink
9352 arc_pad_return (void)
9354 rtx_insn
*insn
= current_output_insn
;
9355 rtx_insn
*prev
= prev_active_insn (insn
);
9360 fputs ("\tnop_s\n", asm_out_file
);
9361 cfun
->machine
->unalign
^= 2;
9364 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9365 because after a call, we'd have to restore blink first. */
9366 else if (GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9370 want_long
= (get_attr_length (prev
) == 2);
9371 prev
= prev_active_insn (prev
);
9374 || ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9375 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9377 : CALL_ATTR (prev
, NON_SIBCALL
)))
9380 cfun
->machine
->size_reason
9381 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9382 else if (TARGET_UNALIGN_BRANCH
&& cfun
->machine
->unalign
)
9384 cfun
->machine
->size_reason
9385 = "Long unaligned jump avoids non-delay slot penalty";
9388 /* Disgorge delay insn, if there is any, and it may be moved. */
9390 /* ??? Annulled would be OK if we can and do conditionalize
9391 the delay slot insn accordingly. */
9392 && !INSN_ANNULLED_BRANCH_P (insn
)
9393 && (get_attr_cond (insn
) != COND_USE
9394 || !reg_set_p (gen_rtx_REG (CCmode
, CC_REG
),
9395 XVECEXP (final_sequence
, 0, 1))))
9397 prev
= as_a
<rtx_insn
*> (XVECEXP (final_sequence
, 0, 1));
9398 gcc_assert (!prev_real_insn (insn
)
9399 || !arc_hazard (prev_real_insn (insn
), prev
));
9400 cfun
->machine
->force_short_suffix
= !want_long
;
9401 rtx save_pred
= current_insn_predicate
;
9402 final_scan_insn (prev
, asm_out_file
, optimize
, 1, NULL
);
9403 cfun
->machine
->force_short_suffix
= -1;
9404 prev
->set_deleted ();
9405 current_output_insn
= insn
;
9406 current_insn_predicate
= save_pred
;
9409 fputs ("\tnop\n", asm_out_file
);
9412 fputs ("\tnop_s\n", asm_out_file
);
9413 cfun
->machine
->unalign
^= 2;
9419 /* The usual; we set up our machine_function data. */
9421 static struct machine_function
*
9422 arc_init_machine_status (void)
9424 struct machine_function
*machine
;
9425 machine
= ggc_cleared_alloc
<machine_function
> ();
9426 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9427 machine
->force_short_suffix
= -1;
9432 /* Implements INIT_EXPANDERS. We just set up to call the above
9436 arc_init_expanders (void)
9438 init_machine_status
= arc_init_machine_status
;
9441 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9442 indicates a number of elements to ignore - that allows to have a
9443 sibcall pattern that starts with (return). LOAD_P is zero for store
9444 multiple (for prologues), and one for load multiples (for epilogues),
9445 and two for load multiples where no final clobber of blink is required.
9446 We also skip the first load / store element since this is supposed to
9447 be checked in the instruction pattern. */
9450 arc_check_millicode (rtx op
, int offset
, int load_p
)
9452 int len
= XVECLEN (op
, 0) - offset
;
9457 if (len
< 2 || len
> 13)
9463 rtx elt
= XVECEXP (op
, 0, --len
);
9465 if (GET_CODE (elt
) != CLOBBER
9466 || !REG_P (XEXP (elt
, 0))
9467 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9468 || len
< 3 || len
> 13)
9471 for (i
= 1; i
< len
; i
++)
9473 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9476 if (GET_CODE (elt
) != SET
)
9478 mem
= XEXP (elt
, load_p
);
9479 reg
= XEXP (elt
, 1-load_p
);
9480 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9482 addr
= XEXP (mem
, 0);
9483 if (GET_CODE (addr
) != PLUS
9484 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9485 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9491 /* Accessor functions for cfun->machine->unalign. */
9494 arc_get_unalign (void)
9496 return cfun
->machine
->unalign
;
9500 arc_clear_unalign (void)
9503 cfun
->machine
->unalign
= 0;
9507 arc_toggle_unalign (void)
9509 cfun
->machine
->unalign
^= 2;
9512 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9513 constant in operand 2, but which would require a LIMM because of
9515 operands 3 and 4 are new SET_SRCs for operands 0. */
9518 split_addsi (rtx
*operands
)
9520 int val
= INTVAL (operands
[2]);
9522 /* Try for two short insns first. Lengths being equal, we prefer
9523 expansions with shorter register lifetimes. */
9524 if (val
> 127 && val
<= 255
9525 && satisfies_constraint_Rcq (operands
[0]))
9527 operands
[3] = operands
[2];
9528 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9532 operands
[3] = operands
[1];
9533 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9537 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9538 constant in operand 1, but which would require a LIMM because of
9540 operands 3 and 4 are new SET_SRCs for operands 0. */
9543 split_subsi (rtx
*operands
)
9545 int val
= INTVAL (operands
[1]);
9547 /* Try for two short insns first. Lengths being equal, we prefer
9548 expansions with shorter register lifetimes. */
9549 if (satisfies_constraint_Rcq (operands
[0])
9550 && satisfies_constraint_Rcq (operands
[2]))
9552 if (val
>= -31 && val
<= 127)
9554 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9555 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9558 else if (val
>= 0 && val
< 255)
9560 operands
[3] = operands
[1];
9561 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9565 /* If the destination is not an ARCompact16 register, we might
9566 still have a chance to make a short insn if the source is;
9567 we need to start with a reg-reg move for this. */
9568 operands
[3] = operands
[2];
9569 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9572 /* Handle DOUBLE_REGS uses.
9573 Operand 0: destination register
9574 Operand 1: source register */
9577 arc_process_double_reg_moves (rtx
*operands
)
9579 rtx dest
= operands
[0];
9580 rtx src
= operands
[1];
9582 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9583 enum usesDxState state
= none
;
9585 if (refers_to_regno_p (40, 44, src
, 0))
9587 if (refers_to_regno_p (40, 44, dest
, 0))
9589 /* Via arc_register_move_cost, we should never see D,D moves. */
9590 gcc_assert (state
== none
);
9599 /* Without the LR insn, we need to split this into a
9600 sequence of insns which will use the DEXCLx and DADDHxy
9601 insns to be able to read the Dx register in question. */
9602 if (TARGET_DPFP_DISABLE_LRSR
)
9604 /* gen *movdf_insn_nolrsr */
9605 rtx set
= gen_rtx_SET (dest
, src
);
9606 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9607 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9611 /* When we have 'mov D, r' or 'mov D, D' then get the target
9612 register pair for use with LR insn. */
9613 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9614 TARGET_BIG_ENDIAN
? 0 : 4);
9615 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9616 TARGET_BIG_ENDIAN
? 4 : 0);
9618 /* Produce the two LR insns to get the high and low parts. */
9619 emit_insn (gen_rtx_SET (destHigh
,
9620 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9622 VUNSPEC_ARC_LR_HIGH
)));
9623 emit_insn (gen_rtx_SET (destLow
,
9624 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9629 else if (state
== destDx
)
9631 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9632 LR insn get the target register pair. */
9633 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9634 TARGET_BIG_ENDIAN
? 0 : 4);
9635 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9636 TARGET_BIG_ENDIAN
? 4 : 0);
9638 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9646 /* operands 0..1 are the operands of a 64 bit move instruction.
9647 split it into two moves with operands 2/3 and 4/5. */
9650 arc_split_move (rtx
*operands
)
9652 machine_mode mode
= GET_MODE (operands
[0]);
9659 if (arc_process_double_reg_moves (operands
))
9664 && ((memory_operand (operands
[0], mode
)
9665 && even_register_operand (operands
[1], mode
))
9666 || (memory_operand (operands
[1], mode
)
9667 && even_register_operand (operands
[0], mode
))))
9669 emit_move_insn (operands
[0], operands
[1]);
9673 if (TARGET_PLUS_QMACW
9674 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9676 HOST_WIDE_INT intval0
, intval1
;
9677 if (GET_MODE (operands
[1]) == V2SImode
)
9679 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9680 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9684 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9685 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9686 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9687 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9689 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9690 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9691 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9692 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9693 emit_move_insn (xop
[0], xop
[2]);
9694 emit_move_insn (xop
[3], xop
[1]);
9698 for (i
= 0; i
< 2; i
++)
9700 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9702 rtx addr
= XEXP (operands
[i
], 0);
9706 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9707 switch (GET_CODE (addr
))
9709 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9710 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9711 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9715 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9716 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9717 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9726 xop
[0+i
] = adjust_automodify_address_nv
9727 (operands
[i
], SImode
,
9728 gen_rtx_fmt_ee (code
, Pmode
, r
,
9729 gen_rtx_PLUS (Pmode
, r
, o
)),
9731 xop
[2+i
] = adjust_automodify_address_nv
9732 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9736 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9737 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9740 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9743 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9746 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9747 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9751 /* Select between the instruction output templates s_tmpl (for short INSNs)
9752 and l_tmpl (for long INSNs). */
9755 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9757 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9759 extract_constrain_insn_cached (insn
);
9760 return is_short
? s_tmpl
: l_tmpl
;
9763 /* Searches X for any reference to REGNO, returning the rtx of the
9764 reference found if any. Otherwise, returns NULL_RTX. */
9767 arc_regno_use_in (unsigned int regno
, rtx x
)
9773 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9776 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9777 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9781 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9784 else if (fmt
[i
] == 'E')
9785 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9786 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9793 /* Return the integer value of the "type" attribute for INSN, or -1 if
9794 INSN can't have attributes. */
9797 arc_attr_type (rtx_insn
*insn
)
9799 if (NONJUMP_INSN_P (insn
)
9800 ? (GET_CODE (PATTERN (insn
)) == USE
9801 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9803 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9804 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9807 return get_attr_type (insn
);
9810 /* Return true if insn sets the condition codes. */
9813 arc_sets_cc_p (rtx_insn
*insn
)
9815 if (NONJUMP_INSN_P (insn
))
9816 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9817 insn
= seq
->insn (seq
->len () - 1);
9818 return arc_attr_type (insn
) == TYPE_COMPARE
;
9821 /* Return true if INSN is an instruction with a delay slot we may want
9825 arc_need_delay (rtx_insn
*insn
)
9829 if (!flag_delayed_branch
)
9831 /* The return at the end of a function needs a delay slot. */
9832 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9833 && (!(next
= next_active_insn (insn
))
9834 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9835 && arc_attr_type (next
) == TYPE_RETURN
))
9836 && (!TARGET_PAD_RETURN
9837 || (prev_active_insn (insn
)
9838 && prev_active_insn (prev_active_insn (insn
))
9839 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9841 if (NONJUMP_INSN_P (insn
)
9842 ? (GET_CODE (PATTERN (insn
)) == USE
9843 || GET_CODE (PATTERN (insn
)) == CLOBBER
9844 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9846 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9847 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9850 return num_delay_slots (insn
) != 0;
9853 /* Return true if the scheduling pass(es) has/have already run,
9854 i.e. where possible, we should try to mitigate high latencies
9855 by different instruction selection. */
9858 arc_scheduling_not_expected (void)
9860 return cfun
->machine
->arc_reorg_started
;
9864 arc_label_align (rtx_insn
*label
)
9866 /* Code has a minimum p2 alignment of 1, which we must restore after an
9868 if (align_labels_log
< 1)
9870 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9871 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9874 return align_labels_log
;
9877 /* Return true if LABEL is in executable code. */
9880 arc_text_label (rtx_insn
*label
)
9884 /* ??? We use deleted labels like they were still there, see
9885 gcc.c-torture/compile/20000326-2.c . */
9886 gcc_assert (GET_CODE (label
) == CODE_LABEL
9887 || (GET_CODE (label
) == NOTE
9888 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9889 next
= next_nonnote_insn (label
);
9891 return (!JUMP_TABLE_DATA_P (next
)
9892 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9893 else if (!PREV_INSN (label
))
9894 /* ??? sometimes text labels get inserted very late, see
9895 gcc.dg/torture/stackalign/comp-goto-1.c */
9900 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9901 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9902 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9903 to redirect two breqs. */
9906 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9908 /* ??? get_attr_type is declared to take an rtx. */
9909 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9912 if (CROSSING_JUMP_P (followee
))
9913 switch (get_attr_type (u
.r
))
9916 if (get_attr_length (u
.r
) != 2)
9919 case TYPE_BRCC_NO_DELAY_SLOT
:
9927 /* Return the register number of the register holding the return address
9928 for a function of type TYPE. */
9931 arc_return_address_register (unsigned int fn_type
)
9935 if (ARC_INTERRUPT_P (fn_type
))
9937 if (((fn_type
& ARC_FUNCTION_ILINK1
) | ARC_FUNCTION_FIRQ
) != 0)
9938 regno
= ILINK1_REGNUM
;
9939 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
9940 regno
= ILINK2_REGNUM
;
9944 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
9945 regno
= RETURN_ADDR_REGNUM
;
9947 gcc_assert (regno
!= 0);
9951 /* Implement EPILOGUE_USES.
9952 Return true if REGNO should be added to the deemed uses of the epilogue.
9954 We have to make sure all the register restore instructions are
9955 known to be live in interrupt functions, plus the blink register if
9956 it is clobbered by the isr. */
9959 arc_epilogue_uses (int regno
)
9961 unsigned int fn_type
;
9963 if (regno
== arc_tp_regno
)
9966 fn_type
= arc_compute_function_type (cfun
);
9967 if (reload_completed
)
9969 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9971 if (!fixed_regs
[regno
])
9973 return ((regno
== arc_return_address_register (fn_type
))
9974 || (regno
== RETURN_ADDR_REGNUM
));
9977 return regno
== RETURN_ADDR_REGNUM
;
9980 return regno
== arc_return_address_register (fn_type
);
9983 /* Helper for EH_USES macro. */
9986 arc_eh_uses (int regno
)
9988 if (regno
== arc_tp_regno
)
9993 #ifndef TARGET_NO_LRA
9994 #define TARGET_NO_LRA !TARGET_LRA
10000 return !TARGET_NO_LRA
;
10003 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10004 Rcq registers, because some insn are shorter with them. OTOH we already
10005 have separate alternatives for this purpose, and other insns don't
10006 mind, so maybe we should rather prefer the other registers?
10007 We need more data, and we can only get that if we allow people to
10008 try all options. */
10010 arc_register_priority (int r
)
10012 switch (arc_lra_priority_tag
)
10014 case ARC_LRA_PRIORITY_NONE
:
10016 case ARC_LRA_PRIORITY_NONCOMPACT
:
10017 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
10018 case ARC_LRA_PRIORITY_COMPACT
:
10019 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
10021 gcc_unreachable ();
10026 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
10028 return GENERAL_REGS
;
10032 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
10036 enum reload_type type
= (enum reload_type
) itype
;
10038 if (GET_CODE (x
) == PLUS
10039 && CONST_INT_P (XEXP (x
, 1))
10040 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
10041 || (REG_P (XEXP (x
, 0))
10042 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
10044 int scale
= GET_MODE_SIZE (mode
);
10046 rtx index_rtx
= XEXP (x
, 1);
10047 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
10048 rtx reg
, sum
, sum2
;
10052 if ((scale
-1) & offset
)
10054 shift
= scale
>> 1;
10056 = ((offset
+ (256 << shift
))
10057 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
10058 /* Sometimes the normal form does not suit DImode. We
10059 could avoid that by using smaller ranges, but that
10060 would give less optimized code when SImode is
10062 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
10067 regno
= REGNO (reg
);
10068 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
10070 if (reg_equiv_constant (regno
))
10072 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
10074 if (GET_CODE (sum2
) == PLUS
)
10075 sum2
= gen_rtx_CONST (Pmode
, sum2
);
10077 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
10078 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
10079 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
10084 /* We must re-recognize what we created before. */
10085 else if (GET_CODE (x
) == PLUS
10086 && GET_CODE (XEXP (x
, 0)) == PLUS
10087 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
10088 && REG_P (XEXP (XEXP (x
, 0), 0))
10089 && CONST_INT_P (XEXP (x
, 1)))
10091 /* Because this address is so complex, we know it must have
10092 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10093 it is already unshared, and needs no further unsharing. */
10094 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
10095 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
10101 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10104 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
10105 unsigned int align
,
10106 enum by_pieces_operation op
,
10109 /* Let the movmem expander handle small block moves. */
10110 if (op
== MOVE_BY_PIECES
)
10113 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
10116 /* Emit a (pre) memory barrier around an atomic sequence according to
10120 arc_pre_atomic_barrier (enum memmodel model
)
10122 if (need_atomic_barrier_p (model
, true))
10123 emit_insn (gen_memory_barrier ());
10126 /* Emit a (post) memory barrier around an atomic sequence according to
10130 arc_post_atomic_barrier (enum memmodel model
)
10132 if (need_atomic_barrier_p (model
, false))
10133 emit_insn (gen_memory_barrier ());
10136 /* Expand a compare and swap pattern. */
10139 emit_unlikely_jump (rtx insn
)
10141 rtx_insn
*jump
= emit_jump_insn (insn
);
10142 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10145 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10146 32-bit compare and swap on the word containing the byte or
10147 half-word. The difference between a weak and a strong CAS is that
10148 the weak version may simply fail. The strong version relies on two
10149 loops, one checks if the SCOND op is succsfully or not, the other
10150 checks if the 32 bit accessed location which contains the 8 or 16
10151 bit datum is not changed by other thread. The first loop is
10152 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10153 loops is implemented by this routine. */
10156 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10157 rtx oldval
, rtx newval
, rtx weak
,
10158 rtx mod_s
, rtx mod_f
)
10160 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10161 rtx addr
= gen_reg_rtx (Pmode
);
10162 rtx off
= gen_reg_rtx (SImode
);
10163 rtx oldv
= gen_reg_rtx (SImode
);
10164 rtx newv
= gen_reg_rtx (SImode
);
10165 rtx oldvalue
= gen_reg_rtx (SImode
);
10166 rtx newvalue
= gen_reg_rtx (SImode
);
10167 rtx res
= gen_reg_rtx (SImode
);
10168 rtx resv
= gen_reg_rtx (SImode
);
10169 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10171 bool is_weak
= (weak
!= const0_rtx
);
10173 /* Truncate the address. */
10174 emit_insn (gen_rtx_SET (addr
,
10175 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10177 /* Compute the datum offset. */
10178 emit_insn (gen_rtx_SET (off
,
10179 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10180 if (TARGET_BIG_ENDIAN
)
10181 emit_insn (gen_rtx_SET (off
,
10182 gen_rtx_MINUS (SImode
,
10183 (GET_MODE (mem
) == QImode
) ?
10184 GEN_INT (3) : GEN_INT (2), off
)));
10186 /* Normal read from truncated address. */
10187 memsi
= gen_rtx_MEM (SImode
, addr
);
10188 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10189 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10191 val
= copy_to_reg (memsi
);
10193 /* Convert the offset in bits. */
10194 emit_insn (gen_rtx_SET (off
,
10195 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10197 /* Get the proper mask. */
10198 if (GET_MODE (mem
) == QImode
)
10199 mask
= force_reg (SImode
, GEN_INT (0xff));
10201 mask
= force_reg (SImode
, GEN_INT (0xffff));
10203 emit_insn (gen_rtx_SET (mask
,
10204 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10206 /* Prepare the old and new values. */
10207 emit_insn (gen_rtx_SET (val
,
10208 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10211 oldval
= gen_lowpart (SImode
, oldval
);
10212 emit_insn (gen_rtx_SET (oldv
,
10213 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10215 newval
= gen_lowpart_common (SImode
, newval
);
10216 emit_insn (gen_rtx_SET (newv
,
10217 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10219 emit_insn (gen_rtx_SET (oldv
,
10220 gen_rtx_AND (SImode
, oldv
, mask
)));
10222 emit_insn (gen_rtx_SET (newv
,
10223 gen_rtx_AND (SImode
, newv
, mask
)));
10227 end_label
= gen_label_rtx ();
10228 loop_label
= gen_label_rtx ();
10229 emit_label (loop_label
);
10232 /* Make the old and new values. */
10233 emit_insn (gen_rtx_SET (oldvalue
,
10234 gen_rtx_IOR (SImode
, oldv
, val
)));
10236 emit_insn (gen_rtx_SET (newvalue
,
10237 gen_rtx_IOR (SImode
, newv
, val
)));
10239 /* Try an 32bit atomic compare and swap. It clobbers the CC
10241 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10242 weak
, mod_s
, mod_f
));
10244 /* Regardless of the weakness of the operation, a proper boolean
10245 result needs to be provided. */
10246 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10247 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10248 emit_insn (gen_rtx_SET (bool_result
, x
));
10252 /* Check the results: if the atomic op is successfully the goto
10254 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10255 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10256 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10257 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10258 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10260 /* Wait for the right moment when the accessed 32-bit location
10262 emit_insn (gen_rtx_SET (resv
,
10263 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10265 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10266 cc
= gen_rtx_REG (mode
, CC_REG
);
10267 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10269 /* Set the new value of the 32 bit location, proper masked. */
10270 emit_insn (gen_rtx_SET (val
, resv
));
10272 /* Try again if location is unstable. Fall through if only
10273 scond op failed. */
10274 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10275 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10276 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10277 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10279 emit_label (end_label
);
10282 /* End: proper return the result for the given mode. */
10283 emit_insn (gen_rtx_SET (res
,
10284 gen_rtx_AND (SImode
, res
, mask
)));
10286 emit_insn (gen_rtx_SET (res
,
10287 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10289 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10292 /* Helper function used by "atomic_compare_and_swap" expand
10296 arc_expand_compare_and_swap (rtx operands
[])
10298 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10301 bval
= operands
[0];
10302 rval
= operands
[1];
10304 oldval
= operands
[3];
10305 newval
= operands
[4];
10306 is_weak
= operands
[5];
10307 mod_s
= operands
[6];
10308 mod_f
= operands
[7];
10309 mode
= GET_MODE (mem
);
10311 if (reg_overlap_mentioned_p (rval
, oldval
))
10312 oldval
= copy_to_reg (oldval
);
10314 if (mode
== SImode
)
10316 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10317 is_weak
, mod_s
, mod_f
));
10318 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10319 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10320 emit_insn (gen_rtx_SET (bval
, x
));
10324 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10325 is_weak
, mod_s
, mod_f
);
10329 /* Helper function used by the "atomic_compare_and_swapsi_1"
10333 arc_split_compare_and_swap (rtx operands
[])
10335 rtx rval
, mem
, oldval
, newval
;
10337 enum memmodel mod_s
, mod_f
;
10339 rtx label1
, label2
, x
, cond
;
10341 rval
= operands
[0];
10343 oldval
= operands
[2];
10344 newval
= operands
[3];
10345 is_weak
= (operands
[4] != const0_rtx
);
10346 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10347 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10348 mode
= GET_MODE (mem
);
10350 /* ARC atomic ops work only with 32-bit aligned memories. */
10351 gcc_assert (mode
== SImode
);
10353 arc_pre_atomic_barrier (mod_s
);
10358 label1
= gen_label_rtx ();
10359 emit_label (label1
);
10361 label2
= gen_label_rtx ();
10363 /* Load exclusive. */
10364 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10366 /* Check if it is oldval. */
10367 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10368 cond
= gen_rtx_REG (mode
, CC_REG
);
10369 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10371 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10372 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10373 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10374 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10376 /* Exclusively store new item. Store clobbers CC reg. */
10377 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10381 /* Check the result of the store. */
10382 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10383 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10384 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10385 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10386 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10389 if (mod_f
!= MEMMODEL_RELAXED
)
10390 emit_label (label2
);
10392 arc_post_atomic_barrier (mod_s
);
10394 if (mod_f
== MEMMODEL_RELAXED
)
10395 emit_label (label2
);
10398 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10399 to perform. MEM is the memory on which to operate. VAL is the second
10400 operand of the binary operator. BEFORE and AFTER are optional locations to
10401 return the value of MEM either before of after the operation. MODEL_RTX
10402 is a CONST_INT containing the memory model to use. */
10405 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10406 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10408 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10409 machine_mode mode
= GET_MODE (mem
);
10410 rtx label
, x
, cond
;
10411 rtx before
= orig_before
, after
= orig_after
;
10413 /* ARC atomic ops work only with 32-bit aligned memories. */
10414 gcc_assert (mode
== SImode
);
10416 arc_pre_atomic_barrier (model
);
10418 label
= gen_label_rtx ();
10419 emit_label (label
);
10420 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10422 if (before
== NULL_RTX
)
10423 before
= gen_reg_rtx (mode
);
10425 if (after
== NULL_RTX
)
10426 after
= gen_reg_rtx (mode
);
10428 /* Load exclusive. */
10429 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10434 x
= gen_rtx_AND (mode
, before
, val
);
10435 emit_insn (gen_rtx_SET (after
, x
));
10436 x
= gen_rtx_NOT (mode
, after
);
10437 emit_insn (gen_rtx_SET (after
, x
));
10441 if (CONST_INT_P (val
))
10443 val
= GEN_INT (-INTVAL (val
));
10449 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10450 emit_insn (gen_rtx_SET (after
, x
));
10454 /* Exclusively store new item. Store clobbers CC reg. */
10455 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10457 /* Check the result of the store. */
10458 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10459 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10460 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10462 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10464 arc_post_atomic_barrier (model
);
10467 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10470 arc_no_speculation_in_delay_slots_p ()
10475 /* Return a parallel of registers to represent where to find the
10476 register pieces if required, otherwise NULL_RTX. */
10479 arc_dwarf_register_span (rtx rtl
)
10481 machine_mode mode
= GET_MODE (rtl
);
10485 if (GET_MODE_SIZE (mode
) != 8)
10488 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10489 regno
= REGNO (rtl
);
10490 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10491 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10496 /* Return true if OP is an acceptable memory operand for ARCompact
10497 16-bit load instructions of MODE.
10499 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10500 non scaled instructions.
10502 SCALED: TRUE if address can be scaled. */
10505 compact_memory_operand_p (rtx op
, machine_mode mode
,
10506 bool av2short
, bool scaled
)
10508 rtx addr
, plus0
, plus1
;
10511 /* Eliminate non-memory operations. */
10512 if (GET_CODE (op
) != MEM
)
10515 /* .di instructions have no 16-bit form. */
10516 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10519 if (mode
== VOIDmode
)
10520 mode
= GET_MODE (op
);
10522 size
= GET_MODE_SIZE (mode
);
10524 /* dword operations really put out 2 instructions, so eliminate
10526 if (size
> UNITS_PER_WORD
)
10529 /* Decode the address now. */
10530 addr
= XEXP (op
, 0);
10531 switch (GET_CODE (addr
))
10534 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10535 || COMPACT_GP_REG_P (REGNO (addr
))
10536 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10538 plus0
= XEXP (addr
, 0);
10539 plus1
= XEXP (addr
, 1);
10541 if ((GET_CODE (plus0
) == REG
)
10542 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10543 || COMPACT_GP_REG_P (REGNO (plus0
)))
10544 && ((GET_CODE (plus1
) == REG
)
10545 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10546 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10551 if ((GET_CODE (plus0
) == REG
)
10552 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10553 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10554 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10555 && (GET_CODE (plus1
) == CONST_INT
))
10557 bool valid
= false;
10559 off
= INTVAL (plus1
);
10561 /* Negative offset is not supported in 16-bit load/store insns. */
10565 /* Only u5 immediates allowed in code density instructions. */
10573 /* This is an ldh_s.x instruction, check the u6
10575 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10579 /* Only u5 immediates allowed in 32bit access code
10580 density instructions. */
10581 if (REGNO (plus0
) <= 31)
10582 return ((off
< 32) && (off
% 4 == 0));
10589 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10600 /* The 6-bit constant get shifted to fit the real
10601 5-bits field. Check also for the alignment. */
10602 return ((off
< 64) && (off
% 2 == 0));
10604 return ((off
< 128) && (off
% 4 == 0));
10611 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10612 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10613 || SP_REG_P (REGNO (plus0
)))
10616 off
= INTVAL (plus1
);
10617 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10620 if ((GET_CODE (plus0
) == MULT
)
10621 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10622 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10623 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10624 && (GET_CODE (plus1
) == REG
)
10625 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10626 || COMPACT_GP_REG_P (REGNO (plus1
))))
10630 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10631 for 16-bit load instructions. */
10636 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10637 anchors for small data: the GP register acts as an anchor in that
10638 case. We also don't want to use them for PC-relative accesses,
10639 where the PC acts as an anchor. Prohibit also TLS symbols to use
10643 arc_use_anchors_for_symbol_p (const_rtx symbol
)
10645 if (SYMBOL_REF_TLS_MODEL (symbol
))
10651 if (SYMBOL_REF_SMALL_P (symbol
))
10654 return default_use_anchors_for_symbol_p (symbol
);
10657 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
10658 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
10660 struct gcc_target targetm
= TARGET_INITIALIZER
;
10662 #include "gt-arc.h"