1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2018 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/>. */
31 #define IN_TARGET_CODE 1
35 #include "coretypes.h"
44 #include "stringpool.h"
50 #include "diagnostic.h"
51 #include "fold-const.h"
53 #include "stor-layout.h"
56 #include "insn-attr.h"
60 #include "langhooks.h"
61 #include "tm-constrs.h"
62 #include "reload.h" /* For operands_match_p */
64 #include "tree-pass.h"
70 #include "hw-doloop.h"
72 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
73 static char arc_cpu_name
[10] = "";
74 static const char *arc_cpu_string
= arc_cpu_name
;
76 typedef struct GTY (()) _arc_jli_section
79 struct _arc_jli_section
*next
;
82 static arc_jli_section
*arc_jli_sections
= NULL
;
84 /* Track which regs are set fixed/call saved/call used from commnad line. */
85 HARD_REG_SET overrideregs
;
87 /* Maximum size of a loop. */
88 #define ARC_MAX_LOOP_LENGTH 4095
90 /* ??? Loads can handle any constant, stores can only handle small ones. */
91 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
92 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
93 (GET_CODE (X) == CONST_INT \
94 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
97 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
99 /* Array of valid operand punctuation characters. */
100 char arc_punct_chars
[256];
102 /* State used by arc_ccfsm_advance to implement conditional execution. */
103 struct GTY (()) arc_ccfsm
108 rtx_insn
*target_insn
;
112 /* Status of the IRQ_CTRL_AUX register. */
113 typedef struct irq_ctrl_saved_t
115 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
116 short irq_save_last_reg
;
117 /* True if BLINK is automatically saved. */
119 /* True if LPCOUNT is automatically saved. */
120 bool irq_save_lpcount
;
122 static irq_ctrl_saved_t irq_ctrl_saved
;
124 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
125 ((ARC_INTERRUPT_P (FNTYPE) \
126 && irq_ctrl_saved.irq_save_blink) \
127 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
128 && rgf_banked_register_count > 8))
130 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
131 ((ARC_INTERRUPT_P (FNTYPE) \
132 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
133 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
134 && rgf_banked_register_count > 8))
136 #define ARC_AUTO_IRQ_P(FNTYPE) \
137 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
138 && (irq_ctrl_saved.irq_save_blink \
139 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
141 /* Number of registers in second bank for FIRQ support. */
142 static int rgf_banked_register_count
;
144 #define arc_ccfsm_current cfun->machine->ccfsm_current
146 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
147 ((STATE)->state == 1 || (STATE)->state == 2)
149 /* Indicate we're conditionalizing insns now. */
150 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
151 ((STATE)->state += 2)
153 #define ARC_CCFSM_COND_EXEC_P(STATE) \
154 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
155 || current_insn_predicate)
157 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
158 #define CCFSM_ISCOMPACT(INSN,STATE) \
159 (ARC_CCFSM_COND_EXEC_P (STATE) \
160 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
161 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
162 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
164 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
165 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
166 ((ARC_CCFSM_COND_EXEC_P (STATE) \
168 && INSN_ANNULLED_BRANCH_P (JUMP) \
169 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
170 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
171 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
172 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
174 /* The maximum number of insns skipped which will be conditionalised if
176 /* When optimizing for speed:
177 Let p be the probability that the potentially skipped insns need to
178 be executed, pn the cost of a correctly predicted non-taken branch,
179 mt the cost of a mis/non-predicted taken branch,
180 mn mispredicted non-taken, pt correctly predicted taken ;
181 costs expressed in numbers of instructions like the ones considered
183 Unfortunately we don't have a measure of predictability - this
184 is linked to probability only in that in the no-eviction-scenario
185 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
186 value that can be assumed *if* the distribution is perfectly random.
187 A predictability of 1 is perfectly plausible not matter what p is,
188 because the decision could be dependent on an invocation parameter
190 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
191 For small p, we want MAX_INSNS_SKIPPED == pt
193 When optimizing for size:
194 We want to skip insn unless we could use 16 opcodes for the
195 non-conditionalized insn to balance the branch length or more.
196 Performance can be tie-breaker. */
197 /* If the potentially-skipped insns are likely to be executed, we'll
198 generally save one non-taken branch
200 this to be no less than the 1/p */
201 #define MAX_INSNS_SKIPPED 3
203 /* A nop is needed between a 4 byte insn that sets the condition codes and
204 a branch that uses them (the same isn't true for an 8 byte insn that sets
205 the condition codes). Set by arc_ccfsm_advance. Used by
206 arc_print_operand. */
208 static int get_arc_condition_code (rtx
);
210 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
211 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
212 static tree
arc_handle_jli_attribute (tree
*, tree
, tree
, int, bool *);
213 static tree
arc_handle_secure_attribute (tree
*, tree
, tree
, int, bool *);
214 static tree
arc_handle_uncached_attribute (tree
*, tree
, tree
, int, bool *);
215 static tree
arc_handle_aux_attribute (tree
*, tree
, tree
, int, bool *);
217 /* Initialized arc_attribute_table to NULL since arc doesnot have any
218 machine specific supported attributes. */
219 const struct attribute_spec arc_attribute_table
[] =
221 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
222 affects_type_identity, handler, exclude } */
223 { "interrupt", 1, 1, true, false, false, true,
224 arc_handle_interrupt_attribute
, NULL
},
225 /* Function calls made to this symbol must be done indirectly, because
226 it may lie outside of the 21/25 bit addressing range of a normal function
228 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
229 /* Whereas these functions are always known to reside within the 25 bit
230 addressing range of unconditionalized bl. */
231 { "medium_call", 0, 0, false, true, true, false, NULL
, NULL
},
232 /* And these functions are always known to reside within the 21 bit
233 addressing range of blcc. */
234 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
235 /* Function which are not having the prologue and epilogue generated
237 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute
,
239 /* Functions calls made using jli instruction. The pointer in JLI
240 table is found latter. */
241 { "jli_always", 0, 0, false, true, true, false, NULL
, NULL
},
242 /* Functions calls made using jli instruction. The pointer in JLI
243 table is given as input parameter. */
244 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute
,
246 /* Call a function using secure-mode. */
247 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute
,
249 /* Bypass caches using .di flag. */
250 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute
,
252 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute
, NULL
},
253 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
255 static int arc_comp_type_attributes (const_tree
, const_tree
);
256 static void arc_file_start (void);
257 static void arc_internal_label (FILE *, const char *, unsigned long);
258 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
260 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
261 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
263 static void arc_init_builtins (void);
264 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
266 static int branch_dest (rtx
);
268 static void arc_output_pic_addr_const (FILE *, rtx
, int);
269 static bool arc_function_ok_for_sibcall (tree
, tree
);
270 static rtx
arc_function_value (const_tree
, const_tree
, bool);
271 const char * output_shift (rtx
*);
272 static void arc_reorg (void);
273 static bool arc_in_small_data_p (const_tree
);
275 static void arc_init_reg_tables (void);
276 static bool arc_return_in_memory (const_tree
, const_tree
);
277 static bool arc_vector_mode_supported_p (machine_mode
);
279 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
281 static const char *arc_invalid_within_doloop (const rtx_insn
*);
283 static void output_short_suffix (FILE *file
);
285 static bool arc_frame_pointer_required (void);
287 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
289 enum by_pieces_operation op
,
292 /* Globally visible information about currently selected cpu. */
293 const arc_cpu_t
*arc_selected_cpu
;
295 /* Given a symbol RTX (const (symb <+ const_int>), returns its
299 get_symbol_alignment (rtx x
)
301 tree decl
= NULL_TREE
;
304 switch (GET_CODE (x
))
307 decl
= SYMBOL_REF_DECL (x
);
310 return get_symbol_alignment (XEXP (x
, 0));
312 gcc_assert (CONST_INT_P (XEXP (x
, 1)));
313 return get_symbol_alignment (XEXP (x
, 0));
319 align
= DECL_ALIGN (decl
);
320 align
= align
/ BITS_PER_UNIT
;
324 /* Return true if x is ok to be used as a small data address. */
327 legitimate_small_data_address_p (rtx x
)
329 switch (GET_CODE (x
))
332 return legitimate_small_data_address_p (XEXP (x
, 0));
334 return SYMBOL_REF_SMALL_P (x
);
337 bool p0
= (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
)
338 && SYMBOL_REF_SMALL_P (XEXP (x
, 0));
339 bool p1
= CONST_INT_P (XEXP (x
, 1))
340 && (INTVAL (XEXP (x
, 1)) <= g_switch_value
);
348 /* TRUE if op is an scaled address. */
350 legitimate_scaled_address_p (machine_mode mode
, rtx op
, bool strict
)
352 if (GET_CODE (op
) != PLUS
)
355 if (GET_CODE (XEXP (op
, 0)) != MULT
)
358 /* Check multiplication operands. */
359 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op
, 0), 0), strict
))
362 if (!CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
365 switch (GET_MODE_SIZE (mode
))
368 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 2)
376 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 4)
383 /* Check the base. */
384 if (RTX_OK_FOR_BASE_P (XEXP (op
, 1), (strict
)))
389 if (CONST_INT_P (XEXP (op
, 1)))
394 /* Scalled addresses for sdata is done other places. */
395 if (legitimate_small_data_address_p (op
))
398 if (CONSTANT_P (XEXP (op
, 1)))
404 /* Check for constructions like REG + OFFS, where OFFS can be a
405 register, an immediate or an long immediate. */
408 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
410 if (GET_CODE (x
) != PLUS
)
413 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
416 /* Check for: [Rx + small offset] or [Rx + Ry]. */
417 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
418 && GET_MODE_SIZE ((mode
)) <= 4)
419 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
422 /* Check for [Rx + symbol]. */
424 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
425 /* Avoid this type of address for double or larger modes. */
426 && (GET_MODE_SIZE (mode
) <= 4)
427 /* Avoid small data which ends in something like GP +
429 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))))
435 /* Implements target hook vector_mode_supported_p. */
438 arc_vector_mode_supported_p (machine_mode mode
)
443 return TARGET_PLUS_DMPY
;
446 return TARGET_PLUS_QMACW
;
449 return TARGET_SIMD_SET
;
456 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
459 arc_preferred_simd_mode (scalar_mode mode
)
464 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
473 /* Implements target hook
474 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
477 arc_autovectorize_vector_sizes (vector_sizes
*sizes
)
479 if (TARGET_PLUS_QMACW
)
481 sizes
->quick_push (8);
482 sizes
->quick_push (4);
487 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
489 arc_sched_issue_rate (void)
502 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
503 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
504 static rtx
arc_delegitimize_address (rtx
);
505 static bool arc_can_follow_jump (const rtx_insn
*follower
,
506 const rtx_insn
*followee
);
508 static rtx
frame_insn (rtx
);
509 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
511 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
513 /* initialize the GCC target structure. */
514 #undef TARGET_COMP_TYPE_ATTRIBUTES
515 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
516 #undef TARGET_ASM_FILE_START
517 #define TARGET_ASM_FILE_START arc_file_start
518 #undef TARGET_ATTRIBUTE_TABLE
519 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
520 #undef TARGET_ASM_INTERNAL_LABEL
521 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
522 #undef TARGET_RTX_COSTS
523 #define TARGET_RTX_COSTS arc_rtx_costs
524 #undef TARGET_ADDRESS_COST
525 #define TARGET_ADDRESS_COST arc_address_cost
527 #undef TARGET_ENCODE_SECTION_INFO
528 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
530 #undef TARGET_CANNOT_FORCE_CONST_MEM
531 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
533 #undef TARGET_INIT_BUILTINS
534 #define TARGET_INIT_BUILTINS arc_init_builtins
536 #undef TARGET_EXPAND_BUILTIN
537 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
539 #undef TARGET_BUILTIN_DECL
540 #define TARGET_BUILTIN_DECL arc_builtin_decl
542 #undef TARGET_ASM_OUTPUT_MI_THUNK
543 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
545 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
546 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
548 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
549 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
551 #undef TARGET_MACHINE_DEPENDENT_REORG
552 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
554 #undef TARGET_IN_SMALL_DATA_P
555 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
557 #undef TARGET_PROMOTE_FUNCTION_MODE
558 #define TARGET_PROMOTE_FUNCTION_MODE \
559 default_promote_function_mode_always_promote
561 #undef TARGET_PROMOTE_PROTOTYPES
562 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
564 #undef TARGET_RETURN_IN_MEMORY
565 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
566 #undef TARGET_PASS_BY_REFERENCE
567 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
569 #undef TARGET_SETUP_INCOMING_VARARGS
570 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
572 #undef TARGET_ARG_PARTIAL_BYTES
573 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
575 #undef TARGET_MUST_PASS_IN_STACK
576 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
578 #undef TARGET_FUNCTION_VALUE
579 #define TARGET_FUNCTION_VALUE arc_function_value
581 #undef TARGET_SCHED_ADJUST_PRIORITY
582 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
584 #undef TARGET_SCHED_ISSUE_RATE
585 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
587 #undef TARGET_VECTOR_MODE_SUPPORTED_P
588 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
590 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
591 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
593 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
594 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
596 #undef TARGET_CAN_USE_DOLOOP_P
597 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
599 #undef TARGET_INVALID_WITHIN_DOLOOP
600 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
602 #undef TARGET_PRESERVE_RELOAD_P
603 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
605 #undef TARGET_CAN_FOLLOW_JUMP
606 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
608 #undef TARGET_DELEGITIMIZE_ADDRESS
609 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
611 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
612 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
613 arc_use_by_pieces_infrastructure_p
615 /* Usually, we will be able to scale anchor offsets.
616 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
617 #undef TARGET_MIN_ANCHOR_OFFSET
618 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
619 #undef TARGET_MAX_ANCHOR_OFFSET
620 #define TARGET_MAX_ANCHOR_OFFSET (1020)
622 #undef TARGET_SECONDARY_RELOAD
623 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
625 #define TARGET_OPTION_OVERRIDE arc_override_options
627 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
629 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
631 #define TARGET_CAN_ELIMINATE arc_can_eliminate
633 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
635 #define TARGET_FUNCTION_ARG arc_function_arg
637 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
639 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
641 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
643 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
645 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
647 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
648 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
649 arc_no_speculation_in_delay_slots_p
652 #define TARGET_LRA_P arc_lra_p
653 #define TARGET_REGISTER_PRIORITY arc_register_priority
654 /* Stores with scaled offsets have different displacement ranges. */
655 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
656 #define TARGET_SPILL_CLASS arc_spill_class
658 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
659 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
661 #undef TARGET_WARN_FUNC_RETURN
662 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
664 #include "target-def.h"
666 #undef TARGET_ASM_ALIGNED_HI_OP
667 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
668 #undef TARGET_ASM_ALIGNED_SI_OP
669 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
672 #undef TARGET_HAVE_TLS
673 #define TARGET_HAVE_TLS HAVE_AS_TLS
676 #undef TARGET_DWARF_REGISTER_SPAN
677 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
679 #undef TARGET_HARD_REGNO_NREGS
680 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
681 #undef TARGET_HARD_REGNO_MODE_OK
682 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
684 #undef TARGET_MODES_TIEABLE_P
685 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
686 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
687 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value
689 /* Try to keep the (mov:DF _, reg) as early as possible so
690 that the d<add/sub/mul>h-lr insns appear together and can
691 use the peephole2 pattern. */
694 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
696 rtx set
= single_set (insn
);
698 && GET_MODE (SET_SRC(set
)) == DFmode
699 && GET_CODE (SET_SRC(set
)) == REG
)
701 /* Incrementing priority by 20 (empirically derived). */
702 return priority
+ 20;
708 /* For ARC base register + offset addressing, the validity of the
709 address is mode-dependent for most of the offset range, as the
710 offset can be scaled by the access size.
711 We don't expose these as mode-dependent addresses in the
712 mode_dependent_address_p target hook, because that would disable
713 lots of optimizations, and most uses of these addresses are for 32
714 or 64 bit accesses anyways, which are fine.
715 However, that leaves some addresses for 8 / 16 bit values not
716 properly reloaded by the generic code, which is why we have to
717 schedule secondary reloads for these. */
720 arc_secondary_reload (bool in_p
,
724 secondary_reload_info
*sri
)
726 enum rtx_code code
= GET_CODE (x
);
728 if (cl
== DOUBLE_REGS
)
731 /* The loop counter register can be stored, but not loaded directly. */
732 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
733 && in_p
&& MEM_P (x
))
736 /* If we have a subreg (reg), where reg is a pseudo (that will end in
737 a memory location), then we may need a scratch register to handle
738 the fp/sp+largeoffset address. */
746 int regno
= REGNO (x
);
747 if (regno
>= FIRST_PSEUDO_REGISTER
)
748 regno
= reg_renumber
[regno
];
753 /* It is a pseudo that ends in a stack location. */
754 if (reg_equiv_mem (REGNO (x
)))
756 /* Get the equivalent address and check the range of the
758 rtx mem
= reg_equiv_mem (REGNO (x
));
759 addr
= find_replacement (&XEXP (mem
, 0));
764 gcc_assert (MEM_P (x
));
766 addr
= simplify_rtx (addr
);
768 if (addr
&& GET_CODE (addr
) == PLUS
769 && CONST_INT_P (XEXP (addr
, 1))
770 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
776 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
780 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
790 /* Convert reloads using offsets that are too large to use indirect
794 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
798 gcc_assert (GET_CODE (mem
) == MEM
);
799 addr
= XEXP (mem
, 0);
801 /* Large offset: use a move. FIXME: ld ops accepts limms as
802 offsets. Hence, the following move insn is not required. */
803 emit_move_insn (scratch
, addr
);
804 mem
= replace_equiv_address_nv (mem
, scratch
);
806 /* Now create the move. */
808 emit_insn (gen_rtx_SET (mem
, reg
));
810 emit_insn (gen_rtx_SET (reg
, mem
));
815 static unsigned arc_ifcvt (void);
819 const pass_data pass_data_arc_ifcvt
=
822 "arc_ifcvt", /* name */
823 OPTGROUP_NONE
, /* optinfo_flags */
824 TV_IFCVT2
, /* tv_id */
825 0, /* properties_required */
826 0, /* properties_provided */
827 0, /* properties_destroyed */
828 0, /* todo_flags_start */
829 TODO_df_finish
/* todo_flags_finish */
832 class pass_arc_ifcvt
: public rtl_opt_pass
835 pass_arc_ifcvt(gcc::context
*ctxt
)
836 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
839 /* opt_pass methods: */
840 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
841 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
847 make_pass_arc_ifcvt (gcc::context
*ctxt
)
849 return new pass_arc_ifcvt (ctxt
);
852 static unsigned arc_predicate_delay_insns (void);
856 const pass_data pass_data_arc_predicate_delay_insns
=
859 "arc_predicate_delay_insns", /* name */
860 OPTGROUP_NONE
, /* optinfo_flags */
861 TV_IFCVT2
, /* tv_id */
862 0, /* properties_required */
863 0, /* properties_provided */
864 0, /* properties_destroyed */
865 0, /* todo_flags_start */
866 TODO_df_finish
/* todo_flags_finish */
869 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
872 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
873 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
876 /* opt_pass methods: */
877 virtual unsigned int execute (function
*)
879 return arc_predicate_delay_insns ();
886 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
888 return new pass_arc_predicate_delay_insns (ctxt
);
891 /* Called by OVERRIDE_OPTIONS to initialize various things. */
898 /* I have the multiplier, then use it*/
899 if (TARGET_MPYW
|| TARGET_MULTI
)
900 arc_multcost
= COSTS_N_INSNS (1);
902 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
903 if (arc_multcost
< 0)
906 case ARC_TUNE_ARC700_4_2_STD
:
908 max throughput (1 multiply + 4 other insns) / 5 cycles. */
909 arc_multcost
= COSTS_N_INSNS (4);
910 if (TARGET_NOMPY_SET
)
911 arc_multcost
= COSTS_N_INSNS (30);
913 case ARC_TUNE_ARC700_4_2_XMAC
:
915 max throughput (1 multiply + 2 other insns) / 3 cycles. */
916 arc_multcost
= COSTS_N_INSNS (3);
917 if (TARGET_NOMPY_SET
)
918 arc_multcost
= COSTS_N_INSNS (30);
920 case ARC_TUNE_ARC600
:
921 if (TARGET_MUL64_SET
)
923 arc_multcost
= COSTS_N_INSNS (4);
928 arc_multcost
= COSTS_N_INSNS (30);
932 /* MPY instructions valid only for ARC700 or ARCv2. */
933 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
934 error ("-mno-mpy supported only for ARC700 or ARCv2");
936 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
937 error ("-mno-dpfp-lrsr supported only with -mdpfp");
939 /* FPX-1. No fast and compact together. */
940 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
941 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
942 error ("FPX fast and compact options cannot be specified together");
944 /* FPX-2. No fast-spfp for arc600 or arc601. */
945 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
946 error ("-mspfp_fast not available on ARC600 or ARC601");
948 /* FPX-4. No FPX extensions mixed with FPU extensions. */
949 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
950 && TARGET_HARD_FLOAT
)
951 error ("No FPX/FPU mixing allowed");
953 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
954 if (flag_pic
&& TARGET_ARC600_FAMILY
)
957 "PIC is not supported for %s. Generating non-PIC code only..",
962 arc_init_reg_tables ();
964 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
965 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
966 arc_punct_chars
['#'] = 1;
967 arc_punct_chars
['*'] = 1;
968 arc_punct_chars
['?'] = 1;
969 arc_punct_chars
['!'] = 1;
970 arc_punct_chars
['^'] = 1;
971 arc_punct_chars
['&'] = 1;
972 arc_punct_chars
['+'] = 1;
973 arc_punct_chars
['_'] = 1;
975 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
977 /* There are two target-independent ifcvt passes, and arc_reorg may do
978 one or more arc_ifcvt calls. */
979 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
980 struct register_pass_info arc_ifcvt4_info
981 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
982 struct register_pass_info arc_ifcvt5_info
983 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
985 register_pass (&arc_ifcvt4_info
);
986 register_pass (&arc_ifcvt5_info
);
989 if (flag_delayed_branch
)
991 opt_pass
*pass_arc_predicate_delay_insns
992 = make_pass_arc_predicate_delay_insns (g
);
993 struct register_pass_info arc_predicate_delay_info
994 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
996 register_pass (&arc_predicate_delay_info
);
1000 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1001 register range is specified as two registers separated by a dash.
1002 It always starts with r0, and its upper limit is fp register.
1003 blink and lp_count registers are optional. */
1006 irq_range (const char *cstr
)
1008 int i
, first
, last
, blink
, lpcount
, xreg
;
1009 char *str
, *dash
, *comma
;
1012 str
= (char *) alloca (i
+ 1);
1013 memcpy (str
, cstr
, i
+ 1);
1017 dash
= strchr (str
, '-');
1020 warning (OPT_mirq_ctrl_saved_
, "missing dash");
1025 comma
= strchr (dash
+ 1, ',');
1029 first
= decode_reg_name (str
);
1032 warning (OPT_mirq_ctrl_saved_
, "first register must be R0");
1036 /* At this moment we do not have the register names initialized
1038 if (!strcmp (dash
+ 1, "ilink"))
1041 last
= decode_reg_name (dash
+ 1);
1045 warning (OPT_mirq_ctrl_saved_
, "unknown register name: %s", dash
+ 1);
1051 warning (OPT_mirq_ctrl_saved_
,
1052 "last register name %s must be an odd register", dash
+ 1);
1060 warning (OPT_mirq_ctrl_saved_
,
1061 "%s-%s is an empty range", str
, dash
+ 1);
1070 comma
= strchr (str
, ',');
1074 xreg
= decode_reg_name (str
);
1086 warning (OPT_mirq_ctrl_saved_
,
1087 "unknown register name: %s", str
);
1092 irq_ctrl_saved
.irq_save_last_reg
= last
;
1093 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
1094 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
1097 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1101 parse_mrgf_banked_regs_option (const char *arg
)
1107 val
= strtol (arg
, &end_ptr
, 10);
1108 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
1109 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
1111 error ("invalid number in -mrgf-banked-regs=%s "
1112 "valid values are 0, 4, 8, 16, or 32", arg
);
1115 rgf_banked_register_count
= (int) val
;
1118 /* Check ARC options, generate derived target attributes. */
1121 arc_override_options (void)
1124 cl_deferred_option
*opt
;
1125 vec
<cl_deferred_option
> *vopt
1126 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
1128 if (arc_cpu
== PROCESSOR_NONE
)
1129 arc_cpu
= TARGET_CPU_DEFAULT
;
1131 /* Set the default cpu options. */
1132 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
1134 /* Set the architectures. */
1135 switch (arc_selected_cpu
->arch_info
->arch_id
)
1138 arc_cpu_string
= "EM";
1141 arc_cpu_string
= "HS";
1144 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
1145 arc_cpu_string
= "NPS400";
1147 arc_cpu_string
= "ARC700";
1150 arc_cpu_string
= "ARC600";
1156 irq_ctrl_saved
.irq_save_last_reg
= -1;
1157 irq_ctrl_saved
.irq_save_blink
= false;
1158 irq_ctrl_saved
.irq_save_lpcount
= false;
1160 rgf_banked_register_count
= 0;
1162 /* Handle the deferred options. */
1164 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1166 switch (opt
->opt_index
)
1168 case OPT_mirq_ctrl_saved_
:
1170 irq_range (opt
->arg
);
1172 warning (OPT_mirq_ctrl_saved_
,
1173 "option -mirq-ctrl-saved valid only for ARC v2 processors");
1176 case OPT_mrgf_banked_regs_
:
1178 parse_mrgf_banked_regs_option (opt
->arg
);
1180 warning (OPT_mrgf_banked_regs_
,
1181 "option -mrgf-banked-regs valid only for ARC v2 processors");
1189 CLEAR_HARD_REG_SET (overrideregs
);
1190 if (common_deferred_options
)
1192 vec
<cl_deferred_option
> v
=
1193 *((vec
<cl_deferred_option
> *) common_deferred_options
);
1196 FOR_EACH_VEC_ELT (v
, i
, opt
)
1198 switch (opt
->opt_index
)
1201 case OPT_fcall_used_
:
1202 case OPT_fcall_saved_
:
1203 if ((reg
= decode_reg_name_and_count (opt
->arg
, &nregs
)) >= 0)
1204 for (j
= reg
; j
< reg
+ nregs
; j
++)
1205 SET_HARD_REG_BIT (overrideregs
, j
);
1213 /* Check options against architecture options. Throw an error if
1214 option is not allowed. Extra, check options against default
1215 architecture/cpu flags and throw an warning if we find a
1217 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1219 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1221 error ("Option %s=%s is not available for %s CPU.", \
1222 DOC0, DOC1, arc_selected_cpu->name); \
1223 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1224 && (VAR != DEFAULT_##VAR) \
1226 warning (0, "Option %s is ignored, the default value %s" \
1227 " is considered for %s CPU.", DOC0, DOC1, \
1228 arc_selected_cpu->name); \
1230 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1232 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1233 && (target_flags & MASK)) \
1234 error ("Option %s is not available for %s CPU", \
1235 DOC, arc_selected_cpu->name); \
1236 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1237 && (target_flags_explicit & MASK) \
1238 && (!(target_flags & MASK))) \
1239 warning (0, "Unset option %s is ignored, it is always" \
1240 " enabled for %s CPU.", DOC, \
1241 arc_selected_cpu->name); \
1244 #include "arc-options.def"
1249 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1250 specific flags are set in arc-common.c. The architecture forces
1251 the default hardware configurations in, regardless what command
1252 line options are saying. The CPU optional hw options can be
1253 turned on or off. */
1254 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1256 if ((arc_selected_cpu->flags & CODE) \
1257 && ((target_flags_explicit & MASK) == 0)) \
1258 target_flags |= MASK; \
1259 if (arc_selected_cpu->arch_info->dflags & CODE) \
1260 target_flags |= MASK; \
1262 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1264 if ((arc_selected_cpu->flags & CODE) \
1265 && (VAR == DEFAULT_##VAR)) \
1267 if (arc_selected_cpu->arch_info->dflags & CODE) \
1271 #include "arc-options.def"
1277 switch (arc_selected_cpu
->extra
)
1279 case HAS_LPCOUNT_16
:
1286 /* Set Tune option. */
1287 if (arc_tune
== ARC_TUNE_NONE
)
1288 arc_tune
= (enum arc_tune_attr
) arc_selected_cpu
->tune
;
1290 if (arc_size_opt_level
== 3)
1293 /* Compact casesi is not a valid option for ARCv2 family. */
1296 if (TARGET_COMPACT_CASESI
)
1298 warning (OPT_mcompact_casesi
,
1299 "compact-casesi is not applicable to ARCv2");
1300 TARGET_COMPACT_CASESI
= 0;
1303 else if (optimize_size
== 1
1304 && !global_options_set
.x_TARGET_COMPACT_CASESI
)
1305 TARGET_COMPACT_CASESI
= 1;
1308 target_flags
|= MASK_NO_SDATA_SET
;
1310 if (flag_no_common
== 255)
1311 flag_no_common
= !TARGET_NO_SDATA_SET
;
1313 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1314 if (TARGET_MIXED_CODE
)
1316 if (!TARGET_Q_CLASS
)
1317 TARGET_COMPACT_CASESI
= 0;
1318 if (TARGET_COMPACT_CASESI
)
1319 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
1321 /* Check for small data option */
1322 if (!global_options_set
.x_g_switch_value
&& !TARGET_NO_SDATA_SET
)
1323 g_switch_value
= TARGET_LL64
? 8 : 4;
1325 /* These need to be done at start up. It's convenient to do them here. */
1329 /* The condition codes of the ARC, and the inverse function. */
1330 /* For short branches, the "c" / "nc" names are not defined in the ARC
1331 Programmers manual, so we have to use "lo" / "hs"" instead. */
1332 static const char *arc_condition_codes
[] =
1334 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1335 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1338 enum arc_cc_code_index
1340 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1341 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1342 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1343 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1346 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1348 /* Returns the index of the ARC condition code string in
1349 `arc_condition_codes'. COMPARISON should be an rtx like
1350 `(eq (...) (...))'. */
1353 get_arc_condition_code (rtx comparison
)
1355 switch (GET_MODE (XEXP (comparison
, 0)))
1358 case E_SImode
: /* For BRcc. */
1359 switch (GET_CODE (comparison
))
1361 case EQ
: return ARC_CC_EQ
;
1362 case NE
: return ARC_CC_NE
;
1363 case GT
: return ARC_CC_GT
;
1364 case LE
: return ARC_CC_LE
;
1365 case GE
: return ARC_CC_GE
;
1366 case LT
: return ARC_CC_LT
;
1367 case GTU
: return ARC_CC_HI
;
1368 case LEU
: return ARC_CC_LS
;
1369 case LTU
: return ARC_CC_LO
;
1370 case GEU
: return ARC_CC_HS
;
1371 default : gcc_unreachable ();
1374 switch (GET_CODE (comparison
))
1376 case EQ
: return ARC_CC_EQ
;
1377 case NE
: return ARC_CC_NE
;
1378 case GE
: return ARC_CC_P
;
1379 case LT
: return ARC_CC_N
;
1380 case GT
: return ARC_CC_PNZ
;
1381 default : gcc_unreachable ();
1384 switch (GET_CODE (comparison
))
1386 case EQ
: return ARC_CC_EQ
;
1387 case NE
: return ARC_CC_NE
;
1388 default : gcc_unreachable ();
1391 switch (GET_CODE (comparison
))
1393 case LTU
: return ARC_CC_C
;
1394 case GEU
: return ARC_CC_NC
;
1395 default : gcc_unreachable ();
1397 case E_CC_FP_GTmode
:
1398 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1399 switch (GET_CODE (comparison
))
1401 case GT
: return ARC_CC_N
;
1402 case UNLE
: return ARC_CC_P
;
1403 default : gcc_unreachable ();
1406 switch (GET_CODE (comparison
))
1408 case GT
: return ARC_CC_HI
;
1409 case UNLE
: return ARC_CC_LS
;
1410 default : gcc_unreachable ();
1412 case E_CC_FP_GEmode
:
1413 /* Same for FPX and non-FPX. */
1414 switch (GET_CODE (comparison
))
1416 case GE
: return ARC_CC_HS
;
1417 case UNLT
: return ARC_CC_LO
;
1418 default : gcc_unreachable ();
1420 case E_CC_FP_UNEQmode
:
1421 switch (GET_CODE (comparison
))
1423 case UNEQ
: return ARC_CC_EQ
;
1424 case LTGT
: return ARC_CC_NE
;
1425 default : gcc_unreachable ();
1427 case E_CC_FP_ORDmode
:
1428 switch (GET_CODE (comparison
))
1430 case UNORDERED
: return ARC_CC_C
;
1431 case ORDERED
: return ARC_CC_NC
;
1432 default : gcc_unreachable ();
1435 switch (GET_CODE (comparison
))
1437 case EQ
: return ARC_CC_EQ
;
1438 case NE
: return ARC_CC_NE
;
1439 case UNORDERED
: return ARC_CC_C
;
1440 case ORDERED
: return ARC_CC_NC
;
1441 case LTGT
: return ARC_CC_HI
;
1442 case UNEQ
: return ARC_CC_LS
;
1443 default : gcc_unreachable ();
1446 switch (GET_CODE (comparison
))
1448 case EQ
: return ARC_CC_EQ
;
1449 case NE
: return ARC_CC_NE
;
1450 case GT
: return ARC_CC_GT
;
1451 case GE
: return ARC_CC_GE
;
1452 case LT
: return ARC_CC_C
;
1453 case LE
: return ARC_CC_LS
;
1454 case UNORDERED
: return ARC_CC_V
;
1455 case ORDERED
: return ARC_CC_NV
;
1456 case UNGT
: return ARC_CC_HI
;
1457 case UNGE
: return ARC_CC_HS
;
1458 case UNLT
: return ARC_CC_LT
;
1459 case UNLE
: return ARC_CC_LE
;
1460 /* UNEQ and LTGT do not have representation. */
1461 case LTGT
: /* Fall through. */
1462 case UNEQ
: /* Fall through. */
1463 default : gcc_unreachable ();
1465 case E_CC_FPU_UNEQmode
:
1466 switch (GET_CODE (comparison
))
1468 case LTGT
: return ARC_CC_NE
;
1469 case UNEQ
: return ARC_CC_EQ
;
1470 default : gcc_unreachable ();
1472 default : gcc_unreachable ();
1478 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1481 arc_short_comparison_p (rtx comparison
, int offset
)
1483 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1484 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1485 switch (get_arc_condition_code (comparison
))
1487 case ARC_CC_EQ
: case ARC_CC_NE
:
1488 return offset
>= -512 && offset
<= 506;
1489 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1490 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1491 return offset
>= -64 && offset
<= 58;
1497 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1498 return the mode to be used for the comparison. */
1501 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1503 machine_mode mode
= GET_MODE (x
);
1506 /* For an operation that sets the condition codes as a side-effect, the
1507 C and V flags is not set as for cmp, so we can only use comparisons where
1508 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1510 /* ??? We could use "pnz" for greater than zero, however, we could then
1511 get into trouble because the comparison could not be reversed. */
1512 if (GET_MODE_CLASS (mode
) == MODE_INT
1514 && (op
== EQ
|| op
== NE
1515 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1518 /* add.f for if (a+b) */
1520 && GET_CODE (y
) == NEG
1521 && (op
== EQ
|| op
== NE
))
1524 /* Check if this is a test suitable for bxor.f . */
1525 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1526 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1530 /* Check if this is a test suitable for add / bmsk.f . */
1531 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1532 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1533 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1534 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1535 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1538 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1539 && GET_CODE (x
) == PLUS
1540 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1543 if (TARGET_ARGONAUT_SET
1544 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1547 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1549 case LT
: case UNGE
: case GT
: case UNLE
:
1550 return CC_FP_GTmode
;
1551 case LE
: case UNGT
: case GE
: case UNLT
:
1552 return CC_FP_GEmode
;
1553 default: gcc_unreachable ();
1555 else if (TARGET_HARD_FLOAT
1556 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1557 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1576 return CC_FPU_UNEQmode
;
1581 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1585 case EQ
: case NE
: return CC_Zmode
;
1587 case GT
: case UNLE
: return CC_FP_GTmode
;
1589 case GE
: case UNLT
: return CC_FP_GEmode
;
1590 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1591 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1592 default: gcc_unreachable ();
1598 /* Vectors to keep interesting information about registers where it can easily
1599 be got. We use to use the actual mode value as the bit number, but there
1600 is (or may be) more than 32 modes now. Instead we use two tables: one
1601 indexed by hard register number, and one indexed by mode. */
1603 /* The purpose of arc_mode_class is to shrink the range of modes so that
1604 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1605 mapped into one arc_mode_class mode. */
1607 enum arc_mode_class
{
1609 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1610 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1614 /* Modes for condition codes. */
1615 #define C_MODES (1 << (int) C_MODE)
1617 /* Modes for single-word and smaller quantities. */
1618 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1620 /* Modes for double-word and smaller quantities. */
1621 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1623 /* Mode for 8-byte DF values only. */
1624 #define DF_MODES (1 << DF_MODE)
1626 /* Modes for quad-word and smaller quantities. */
1627 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1629 /* Modes for 128-bit vectors. */
1630 #define V_MODES (1 << (int) V_MODE)
1632 /* Value is 1 if register/mode pair is acceptable on arc. */
1634 static unsigned int arc_hard_regno_modes
[] = {
1635 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1636 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1637 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1638 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1640 /* ??? Leave these as S_MODES for now. */
1641 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1642 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1643 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1644 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1646 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1647 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1648 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1649 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1651 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1652 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1653 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1654 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1656 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1657 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1660 static unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1662 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1665 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1667 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1668 return GENERAL_REGS
;
1672 /* Initialize the arc_mode_class array. */
1675 arc_init_reg_tables (void)
1679 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1681 machine_mode m
= (machine_mode
) i
;
1683 switch (GET_MODE_CLASS (m
))
1686 case MODE_PARTIAL_INT
:
1687 case MODE_COMPLEX_INT
:
1688 if (GET_MODE_SIZE (m
) <= 4)
1689 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1690 else if (GET_MODE_SIZE (m
) == 8)
1691 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1692 else if (GET_MODE_SIZE (m
) == 16)
1693 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1694 else if (GET_MODE_SIZE (m
) == 32)
1695 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1697 arc_mode_class
[i
] = 0;
1700 case MODE_COMPLEX_FLOAT
:
1701 if (GET_MODE_SIZE (m
) <= 4)
1702 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1703 else if (GET_MODE_SIZE (m
) == 8)
1704 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1705 else if (GET_MODE_SIZE (m
) == 16)
1706 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1707 else if (GET_MODE_SIZE (m
) == 32)
1708 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1710 arc_mode_class
[i
] = 0;
1712 case MODE_VECTOR_INT
:
1713 if (GET_MODE_SIZE (m
) == 4)
1714 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1715 else if (GET_MODE_SIZE (m
) == 8)
1716 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1718 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1722 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1723 we must explicitly check for them here. */
1724 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1725 || i
== (int) CC_Cmode
1726 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1727 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1728 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1730 arc_mode_class
[i
] = 0;
1736 /* Core registers 56..59 are used for multiply extension options.
1737 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1738 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1739 number depends on endianness.
1740 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1741 Because mlo / mhi form a 64 bit value, we use different gcc internal
1742 register numbers to make them form a register pair as the gcc internals
1743 know it. mmid gets number 57, if still available, and mlo / mhi get
1744 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1745 to map this back. */
1746 char rname56
[5] = "r56";
1747 char rname57
[5] = "r57";
1748 char rname58
[5] = "r58";
1749 char rname59
[5] = "r59";
1750 char rname29
[7] = "ilink1";
1751 char rname30
[7] = "ilink2";
1754 arc_conditional_register_usage (void)
1758 int fix_start
= 60, fix_end
= 55;
1762 /* For ARCv2 the core register set is changed. */
1763 strcpy (rname29
, "ilink");
1764 strcpy (rname30
, "r30");
1766 if (!TEST_HARD_REG_BIT (overrideregs
, 30))
1768 /* No user interference. Set the r30 to be used by the
1770 call_used_regs
[30] = 1;
1773 arc_regno_reg_class
[30] = WRITABLE_CORE_REGS
;
1774 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], 30);
1775 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], 30);
1776 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], 30);
1777 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], 30);
1781 if (TARGET_MUL64_SET
)
1786 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1787 you are supposed to refer to it as mlo & mhi, e.g
1788 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1789 In an actual asm instruction, you are of course use mmed.
1790 The point of avoiding having a separate register for mmed is that
1791 this way, we don't have to carry clobbers of that reg around in every
1792 isntruction that modifies mlo and/or mhi. */
1793 strcpy (rname57
, "");
1794 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1795 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1798 /* The nature of arc_tp_regno is actually something more like a global
1799 register, however globalize_reg requires a declaration.
1800 We use EPILOGUE_USES to compensate so that sets from
1801 __builtin_set_frame_pointer are not deleted. */
1802 if (arc_tp_regno
!= -1)
1803 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1805 if (TARGET_MULMAC_32BY16_SET
)
1808 fix_end
= fix_end
> 57 ? fix_end
: 57;
1809 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1810 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1812 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1814 if (!fixed_regs
[regno
])
1815 warning (0, "multiply option implies r%d is fixed", regno
);
1816 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1822 reg_alloc_order
[0] = 0;
1823 reg_alloc_order
[1] = 1;
1824 reg_alloc_order
[2] = 2;
1825 reg_alloc_order
[3] = 3;
1826 reg_alloc_order
[4] = 12;
1827 reg_alloc_order
[5] = 13;
1828 reg_alloc_order
[6] = 14;
1829 reg_alloc_order
[7] = 15;
1830 reg_alloc_order
[8] = 4;
1831 reg_alloc_order
[9] = 5;
1832 reg_alloc_order
[10] = 6;
1833 reg_alloc_order
[11] = 7;
1834 reg_alloc_order
[12] = 8;
1835 reg_alloc_order
[13] = 9;
1836 reg_alloc_order
[14] = 10;
1837 reg_alloc_order
[15] = 11;
1841 reg_alloc_order
[2] = 12;
1842 reg_alloc_order
[3] = 13;
1843 reg_alloc_order
[4] = 14;
1844 reg_alloc_order
[5] = 15;
1845 reg_alloc_order
[6] = 1;
1846 reg_alloc_order
[7] = 0;
1847 reg_alloc_order
[8] = 4;
1848 reg_alloc_order
[9] = 5;
1849 reg_alloc_order
[10] = 6;
1850 reg_alloc_order
[11] = 7;
1851 reg_alloc_order
[12] = 8;
1852 reg_alloc_order
[13] = 9;
1853 reg_alloc_order
[14] = 10;
1854 reg_alloc_order
[15] = 11;
1857 if (TARGET_SIMD_SET
)
1860 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1861 reg_alloc_order
[i
] = i
;
1862 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1863 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1864 reg_alloc_order
[i
] = i
;
1867 /* Reduced configuration: don't use r4-r9, r16-r25. */
1870 for (i
= 4; i
<= 9; i
++)
1872 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1874 for (i
= 16; i
<= 25; i
++)
1876 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1880 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1881 if (!call_used_regs
[regno
])
1882 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1883 for (regno
= 32; regno
< 60; regno
++)
1884 if (!fixed_regs
[regno
])
1885 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1886 if (!TARGET_ARC600_FAMILY
)
1888 for (regno
= 32; regno
<= 60; regno
++)
1889 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1891 /* If they have used -ffixed-lp_count, make sure it takes
1893 if (fixed_regs
[LP_COUNT
])
1895 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1896 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1897 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1899 /* Instead of taking out SF_MODE like below, forbid it outright. */
1900 arc_hard_regno_modes
[60] = 0;
1903 arc_hard_regno_modes
[60] = 1 << (int) S_MODE
;
1906 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1910 for (regno
= 1; regno
< 32; regno
+=2)
1912 arc_hard_regno_modes
[regno
] = S_MODES
;
1916 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1920 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1921 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1922 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1924 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1927 arc_regno_reg_class
[i
]
1929 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1930 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1931 : (((!TARGET_ARC600_FAMILY
)
1932 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1933 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1935 arc_regno_reg_class
[i
] = NO_REGS
;
1938 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1939 has not been activated. */
1940 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1941 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1942 if (!TARGET_Q_CLASS
)
1943 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1945 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1947 /* Handle Special Registers. */
1948 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1950 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1951 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1952 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1953 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1954 arc_regno_reg_class
[62] = GENERAL_REGS
;
1958 for (i
= 40; i
< 44; ++i
)
1960 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1962 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1963 no attempt is made to use such a register as a destination
1964 operand in *movdf_insn. */
1965 if (!TARGET_ARGONAUT_SET
)
1967 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1968 interpreted to mean they can use D1 or D2 in their insn. */
1969 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1970 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1971 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1972 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1978 /* Disable all DOUBLE_REGISTER settings,
1979 if not generating DPFP code. */
1980 arc_regno_reg_class
[40] = ALL_REGS
;
1981 arc_regno_reg_class
[41] = ALL_REGS
;
1982 arc_regno_reg_class
[42] = ALL_REGS
;
1983 arc_regno_reg_class
[43] = ALL_REGS
;
1990 arc_hard_regno_modes
[40] = 0;
1991 arc_hard_regno_modes
[42] = 0;
1993 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1996 if (TARGET_SIMD_SET
)
1998 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1999 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
2001 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
2002 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
2004 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
2005 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
2006 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
2007 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
2009 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
2010 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
2011 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
2015 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
2017 /*ARCV2 Accumulator. */
2019 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
2020 || TARGET_PLUS_DMPY
)
2022 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
2023 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
2024 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
2025 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
2026 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
2027 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
2028 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCL_REGNO
);
2029 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCH_REGNO
);
2030 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCL_REGNO
);
2031 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCH_REGNO
);
2033 /* Allow the compiler to freely use them. */
2034 if (!TEST_HARD_REG_BIT (overrideregs
, ACCL_REGNO
))
2035 fixed_regs
[ACCL_REGNO
] = 0;
2036 if (!TEST_HARD_REG_BIT (overrideregs
, ACCH_REGNO
))
2037 fixed_regs
[ACCH_REGNO
] = 0;
2039 if (!fixed_regs
[ACCH_REGNO
] && !fixed_regs
[ACCL_REGNO
])
2040 arc_hard_regno_modes
[ACC_REG_FIRST
] = D_MODES
;
2044 /* Implement TARGET_HARD_REGNO_NREGS. */
2047 arc_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
2049 if (GET_MODE_SIZE (mode
) == 16
2050 && regno
>= ARC_FIRST_SIMD_VR_REG
2051 && regno
<= ARC_LAST_SIMD_VR_REG
)
2054 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
2057 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2060 arc_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
2062 return (arc_hard_regno_modes
[regno
] & arc_mode_class
[mode
]) != 0;
2065 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
2068 arc_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
2070 return (GET_MODE_CLASS (mode1
) == MODE_INT
2071 && GET_MODE_CLASS (mode2
) == MODE_INT
2072 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
2073 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
);
2076 /* Handle an "interrupt" attribute; arguments as in
2077 struct attribute_spec.handler. */
2080 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
2085 tree value
= TREE_VALUE (args
);
2087 if (TREE_CODE (value
) != STRING_CST
)
2089 warning (OPT_Wattributes
,
2090 "argument of %qE attribute is not a string constant",
2092 *no_add_attrs
= true;
2095 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
2096 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2098 warning (OPT_Wattributes
,
2099 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2101 *no_add_attrs
= true;
2104 && strcmp (TREE_STRING_POINTER (value
), "ilink")
2105 && strcmp (TREE_STRING_POINTER (value
), "firq"))
2107 warning (OPT_Wattributes
,
2108 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2110 *no_add_attrs
= true;
2117 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
2118 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
2120 if (TREE_CODE (*node
) != FUNCTION_DECL
)
2122 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2124 *no_add_attrs
= true;
2130 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2133 arc_allocate_stack_slots_for_args (void)
2135 /* Naked functions should not allocate stack slots for arguments. */
2136 unsigned int fn_type
= arc_compute_function_type (cfun
);
2138 return !ARC_NAKED_P(fn_type
);
2141 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2144 arc_warn_func_return (tree decl
)
2146 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
2147 unsigned int fn_type
= arc_compute_function_type (func
);
2149 return !ARC_NAKED_P (fn_type
);
2152 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2153 and two if they are nearly compatible (which causes a warning to be
2157 arc_comp_type_attributes (const_tree type1
,
2160 int l1
, l2
, m1
, m2
, s1
, s2
;
2162 /* Check for mismatch of non-default calling convention. */
2163 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
2166 /* Check for mismatched call attributes. */
2167 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2168 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2169 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2170 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2171 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2172 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2174 /* Only bother to check if an attribute is defined. */
2175 if (l1
| l2
| m1
| m2
| s1
| s2
)
2177 /* If one type has an attribute, the other must have the same attribute. */
2178 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
2181 /* Disallow mixed attributes. */
2182 if (l1
+ m1
+ s1
> 1)
2190 /* Misc. utilities. */
2192 /* X and Y are two things to compare using CODE. Emit the compare insn and
2193 return the rtx for the cc reg in the proper mode. */
2196 gen_compare_reg (rtx comparison
, machine_mode omode
)
2198 enum rtx_code code
= GET_CODE (comparison
);
2199 rtx x
= XEXP (comparison
, 0);
2200 rtx y
= XEXP (comparison
, 1);
2202 machine_mode mode
, cmode
;
2205 cmode
= GET_MODE (x
);
2206 if (cmode
== VOIDmode
)
2207 cmode
= GET_MODE (y
);
2208 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
2209 if (cmode
== SImode
)
2211 if (!register_operand (x
, SImode
))
2213 if (register_operand (y
, SImode
))
2218 code
= swap_condition (code
);
2221 x
= copy_to_mode_reg (SImode
, x
);
2223 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
2224 y
= copy_to_mode_reg (SImode
, y
);
2228 x
= force_reg (cmode
, x
);
2229 y
= force_reg (cmode
, y
);
2231 mode
= SELECT_CC_MODE (code
, x
, y
);
2233 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
2235 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2236 cmpdfpx_raw, is not a correct comparison for floats:
2237 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2239 if (TARGET_ARGONAUT_SET
2240 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2244 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2245 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2247 case GT
: case UNLE
: case GE
: case UNLT
:
2248 code
= swap_condition (code
);
2256 if (cmode
== SFmode
)
2258 emit_insn (gen_cmpsfpx_raw (x
, y
));
2262 /* Accepts Dx regs directly by insns. */
2263 emit_insn (gen_cmpdfpx_raw (x
, y
));
2266 if (mode
!= CC_FPXmode
)
2267 emit_insn (gen_rtx_SET (cc_reg
,
2268 gen_rtx_COMPARE (mode
,
2269 gen_rtx_REG (CC_FPXmode
, 61),
2272 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2276 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2277 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2279 case LT
: case UNGE
: case LE
: case UNGT
:
2280 code
= swap_condition (code
);
2289 emit_insn (gen_cmp_quark (cc_reg
,
2290 gen_rtx_COMPARE (mode
, x
, y
)));
2292 else if (TARGET_HARD_FLOAT
2293 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2294 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2295 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2296 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2298 rtx op0
= gen_rtx_REG (cmode
, 0);
2299 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2304 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2305 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2307 case LT
: case UNGE
: case LE
: case UNGT
:
2308 code
= swap_condition (code
);
2314 if (currently_expanding_to_rtl
)
2322 emit_move_insn (op0
, x
);
2323 emit_move_insn (op1
, y
);
2327 gcc_assert (rtx_equal_p (op0
, x
));
2328 gcc_assert (rtx_equal_p (op1
, y
));
2335 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2338 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2339 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2342 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2343 We assume the value can be either signed or unsigned. */
2346 arc_double_limm_p (rtx value
)
2348 HOST_WIDE_INT low
, high
;
2350 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2355 low
= CONST_DOUBLE_LOW (value
);
2356 high
= CONST_DOUBLE_HIGH (value
);
2358 if (low
& 0x80000000)
2360 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2361 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2362 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2367 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2371 /* Do any needed setup for a variadic function. For the ARC, we must
2372 create a register parameter block, and then copy any anonymous arguments
2373 in registers to memory.
2375 CUM has not been updated for the last named argument which has type TYPE
2376 and mode MODE, and we rely on this fact. */
2379 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2380 machine_mode mode
, tree type
,
2381 int *pretend_size
, int no_rtl
)
2384 CUMULATIVE_ARGS next_cum
;
2386 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2388 next_cum
= *get_cumulative_args (args_so_far
);
2389 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2391 first_anon_arg
= next_cum
;
2393 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2395 /* First anonymous (unnamed) argument is in a reg. */
2397 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2398 int first_reg_offset
= first_anon_arg
;
2403 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2404 FIRST_PARM_OFFSET (0)));
2405 move_block_from_reg (first_reg_offset
, regblock
,
2406 MAX_ARC_PARM_REGS
- first_reg_offset
);
2410 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2414 /* Cost functions. */
2416 /* Provide the costs of an addressing mode that contains ADDR.
2417 If ADDR is not a valid address, its cost is irrelevant. */
2420 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2422 switch (GET_CODE (addr
))
2425 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2426 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2427 case PRE_MODIFY
: case POST_MODIFY
:
2433 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2435 /* Most likely needs a LIMM. */
2436 return COSTS_N_INSNS (1);
2440 register rtx plus0
= XEXP (addr
, 0);
2441 register rtx plus1
= XEXP (addr
, 1);
2443 if (GET_CODE (plus0
) != REG
2444 && (GET_CODE (plus0
) != MULT
2445 || !CONST_INT_P (XEXP (plus0
, 1))
2446 || (INTVAL (XEXP (plus0
, 1)) != 2
2447 && INTVAL (XEXP (plus0
, 1)) != 4)))
2450 switch (GET_CODE (plus1
))
2453 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2457 : (satisfies_constraint_Rcq (plus0
)
2458 && satisfies_constraint_O (plus1
))
2462 return (speed
< 1 ? 0
2463 : (satisfies_constraint_Rcq (plus0
)
2464 && satisfies_constraint_Rcq (plus1
))
2469 return COSTS_N_INSNS (1);
2482 /* Emit instruction X with the frame related bit set. */
2488 RTX_FRAME_RELATED_P (x
) = 1;
2492 /* Emit a frame insn to move SRC to DST. */
2495 frame_move (rtx dst
, rtx src
)
2497 rtx tmp
= gen_rtx_SET (dst
, src
);
2498 RTX_FRAME_RELATED_P (tmp
) = 1;
2499 return frame_insn (tmp
);
2502 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2503 auto increment address, or is zero. */
2506 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2508 rtx insn
= frame_move (dst
, src
);
2511 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2512 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2513 add_reg_note (insn
, REG_INC
, reg
);
2517 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2520 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2522 gcc_assert ((offset
& 0x3) == 0);
2525 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2528 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2531 frame_stack_add (HOST_WIDE_INT offset
)
2533 return frame_add (stack_pointer_rtx
, offset
);
2536 /* Traditionally, we push saved registers first in the prologue,
2537 then we allocate the rest of the frame - and reverse in the epilogue.
2538 This has still its merits for ease of debugging, or saving code size
2539 or even execution time if the stack frame is so large that some accesses
2540 can't be encoded anymore with offsets in the instruction code when using
2542 Also, it would be a good starting point if we got instructions to help
2543 with register save/restore.
2545 However, often stack frames are small, and the pushing / popping has
2547 - the stack modification prevents a lot of scheduling.
2548 - frame allocation / deallocation needs extra instructions.
2549 - unless we know that we compile ARC700 user code, we need to put
2550 a memory barrier after frame allocation / before deallocation to
2551 prevent interrupts clobbering our data in the frame.
2552 In particular, we don't have any such guarantees for library functions,
2553 which tend to, on the other hand, to have small frames.
2555 Thus, for small frames, we'd like to use a different scheme:
2556 - The frame is allocated in full with the first prologue instruction,
2557 and deallocated in full with the last epilogue instruction.
2558 Thus, the instructions in-betwen can be freely scheduled.
2559 - If the function has no outgoing arguments on the stack, we can allocate
2560 one register save slot at the top of the stack. This register can then
2561 be saved simultanously with frame allocation, and restored with
2563 This register can be picked depending on scheduling considerations,
2564 although same though should go into having some set of registers
2565 to be potentially lingering after a call, and others to be available
2566 immediately - i.e. in the absence of interprocedual optimization, we
2567 can use an ABI-like convention for register allocation to reduce
2568 stalls after function return. */
2569 /* Function prologue/epilogue handlers. */
2571 /* ARCompact stack frames look like:
2573 Before call After call
2574 high +-----------------------+ +-----------------------+
2575 mem | reg parm save area | | reg parm save area |
2576 | only created for | | only created for |
2577 | variable arg fns | | variable arg fns |
2578 AP +-----------------------+ +-----------------------+
2579 | return addr register | | return addr register |
2580 | (if required) | | (if required) |
2581 +-----------------------+ +-----------------------+
2583 | reg save area | | reg save area |
2585 +-----------------------+ +-----------------------+
2586 | frame pointer | | frame pointer |
2587 | (if required) | | (if required) |
2588 FP +-----------------------+ +-----------------------+
2590 | local/temp variables | | local/temp variables |
2592 +-----------------------+ +-----------------------+
2594 | arguments on stack | | arguments on stack |
2596 SP +-----------------------+ +-----------------------+
2597 | reg parm save area |
2598 | only created for |
2599 | variable arg fns |
2600 AP +-----------------------+
2601 | return addr register |
2603 +-----------------------+
2607 +-----------------------+
2610 FP +-----------------------+
2612 | local/temp variables |
2614 +-----------------------+
2616 | arguments on stack |
2618 mem SP +-----------------------+
2621 1) The "reg parm save area" does not exist for non variable argument fns.
2622 The "reg parm save area" can be eliminated completely if we created our
2623 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2625 /* Structure to be filled in by arc_compute_frame_size with register
2626 save masks, and offsets for the current function. */
2627 struct GTY (()) arc_frame_info
2629 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2630 unsigned int extra_size
; /* # bytes of extra stuff. */
2631 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2632 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2633 unsigned int reg_size
; /* # bytes needed to store regs. */
2634 unsigned int var_size
; /* # bytes that variables take up. */
2635 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2636 unsigned int gmask
; /* Mask of saved gp registers. */
2637 int initialized
; /* Nonzero if frame size already calculated. */
2638 short millicode_start_reg
;
2639 short millicode_end_reg
;
2640 bool save_return_addr
;
2643 /* Defining data structures for per-function information. */
2645 typedef struct GTY (()) machine_function
2647 unsigned int fn_type
;
2648 struct arc_frame_info frame_info
;
2649 /* To keep track of unalignment caused by short insns. */
2651 struct arc_ccfsm ccfsm_current
;
2652 /* Map from uid to ccfsm state during branch shortening. */
2653 rtx ccfsm_current_insn
;
2654 char arc_reorg_started
;
2655 char prescan_initialized
;
2658 /* Type of function DECL.
2660 The result is cached. To reset the cache at the end of a function,
2661 call with DECL = NULL_TREE. */
2664 arc_compute_function_type (struct function
*fun
)
2666 tree attr
, decl
= fun
->decl
;
2667 unsigned int fn_type
= fun
->machine
->fn_type
;
2669 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2672 /* Check if it is a naked function. */
2673 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2674 fn_type
|= ARC_FUNCTION_NAKED
;
2676 fn_type
|= ARC_FUNCTION_NORMAL
;
2678 /* Now see if this is an interrupt handler. */
2679 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2680 if (attr
!= NULL_TREE
)
2682 tree value
, args
= TREE_VALUE (attr
);
2684 gcc_assert (list_length (args
) == 1);
2685 value
= TREE_VALUE (args
);
2686 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2688 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2689 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2690 fn_type
|= ARC_FUNCTION_ILINK1
;
2691 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2692 fn_type
|= ARC_FUNCTION_ILINK2
;
2693 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2694 fn_type
|= ARC_FUNCTION_FIRQ
;
2699 return fun
->machine
->fn_type
= fn_type
;
2702 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2703 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2705 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2706 The return address and frame pointer are treated separately.
2707 Don't consider them here.
2708 Addition for pic: The gp register needs to be saved if the current
2709 function changes it to access gotoff variables.
2710 FIXME: This will not be needed if we used some arbitrary register
2714 arc_must_save_register (int regno
, struct function
*func
)
2716 unsigned int fn_type
= arc_compute_function_type (func
);
2717 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2718 && ARC_AUTO_IRQ_P (fn_type
));
2719 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2721 switch (rgf_banked_register_count
)
2724 firq_auto_save_p
&= (regno
< 4);
2727 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2730 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2731 || ((regno
> 25) && (regno
< 29))
2732 || ((regno
> 29) && (regno
< 32)));
2735 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2738 firq_auto_save_p
= false;
2742 if ((regno
) != RETURN_ADDR_REGNUM
2743 && (regno
) != FRAME_POINTER_REGNUM
2744 && df_regs_ever_live_p (regno
)
2745 && (!call_used_regs
[regno
]
2746 || ARC_INTERRUPT_P (fn_type
))
2747 /* Do not emit code for auto saved regs. */
2749 && !firq_auto_save_p
)
2755 /* Return true if the return address must be saved in the current function,
2756 otherwise return false. */
2759 arc_must_save_return_addr (struct function
*func
)
2761 if (func
->machine
->frame_info
.save_return_addr
)
2767 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2768 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2769 Register Allocator) pass, while we want to get the frame size
2770 correct earlier than the IRA pass.
2772 When a function uses eh_return we must ensure that the fp register
2773 is saved and then restored so that the unwinder can restore the
2774 correct value for the frame we are going to jump to.
2776 To do this we force all frames that call eh_return to require a
2777 frame pointer (see arc_frame_pointer_required), this
2778 will ensure that the previous frame pointer is stored on entry to
2779 the function, and will then be reloaded at function exit.
2781 As the frame pointer is handled as a special case in our prologue
2782 and epilogue code it must not be saved and restored using the
2783 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2784 believes that the function is not using a frame pointer and that
2785 the value in the fp register is the frame pointer, while the
2786 prologue and epilogue are busy saving and restoring the fp
2789 During compilation of a function the frame size is evaluated
2790 multiple times, it is not until the reload pass is complete the the
2791 frame size is considered fixed (it is at this point that space for
2792 all spills has been allocated). However the frame_pointer_needed
2793 variable is not set true until the register allocation pass, as a
2794 result in the early stages the frame size does not include space
2795 for the frame pointer to be spilled.
2797 The problem that this causes is that the rtl generated for
2798 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2799 the offset from the frame pointer at which the return address
2800 lives. However, in early passes GCC has not yet realised we need a
2801 frame pointer, and so has not included space for the frame pointer
2802 in the frame size, and so gets the offset of the return address
2803 wrong. This should not be an issue as in later passes GCC has
2804 realised that the frame pointer needs to be spilled, and has
2805 increased the frame size. However, the rtl for the
2806 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2807 offset, and the wrong smaller offset is used. */
2810 arc_frame_pointer_needed (void)
2812 return (frame_pointer_needed
|| crtl
->calls_eh_return
);
2815 /* Return non-zero if there are registers to be saved or loaded using
2816 millicode thunks. We can only use consecutive sequences starting
2817 with r13, and not going beyond r25.
2818 GMASK is a bitmask of registers to save. This function sets
2819 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2820 of registers to be saved / restored with a millicode call. */
2823 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2824 struct arc_frame_info
*frame
)
2828 int start_reg
= 13, end_reg
= 25;
2830 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2832 end_reg
= regno
- 1;
2833 /* There is no point in using millicode thunks if we don't save/restore
2834 at least three registers. For non-leaf functions we also have the
2836 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2838 frame
->millicode_start_reg
= 13;
2839 frame
->millicode_end_reg
= regno
- 1;
2845 /* Return the bytes needed to compute the frame pointer from the
2846 current stack pointer. */
2849 arc_compute_frame_size (void)
2852 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2853 unsigned int reg_size
, reg_offset
;
2855 struct arc_frame_info
*frame_info
;
2858 /* The answer might already be known. */
2859 if (cfun
->machine
->frame_info
.initialized
)
2860 return cfun
->machine
->frame_info
.total_size
;
2862 frame_info
= &cfun
->machine
->frame_info
;
2863 size
= ARC_STACK_ALIGN (get_frame_size ());
2865 /* 1) Size of locals and temporaries. */
2868 /* 2) Size of outgoing arguments. */
2869 args_size
= crtl
->outgoing_args_size
;
2871 /* 3) Calculate space needed for saved registers.
2872 ??? We ignore the extension registers for now. */
2874 /* See if this is an interrupt handler. Call used registers must be saved
2880 for (regno
= 0; regno
<= 31; regno
++)
2882 if (arc_must_save_register (regno
, cfun
))
2884 reg_size
+= UNITS_PER_WORD
;
2885 gmask
|= 1L << regno
;
2889 /* In a frame that calls __builtin_eh_return two data registers are
2890 used to pass values back to the exception handler.
2892 Ensure that these registers are spilled to the stack so that the
2893 exception throw code can find them, and update the saved values.
2894 The handling code will then consume these reloaded values to
2895 handle the exception. */
2896 if (crtl
->calls_eh_return
)
2897 for (regno
= 0; EH_RETURN_DATA_REGNO (regno
) != INVALID_REGNUM
; regno
++)
2899 reg_size
+= UNITS_PER_WORD
;
2900 gmask
|= 1 << regno
;
2903 /* 4) Space for back trace data structure.
2904 <return addr reg size> (if required) + <fp size> (if required). */
2905 frame_info
->save_return_addr
2906 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2907 || crtl
->calls_eh_return
);
2908 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2910 && !TARGET_NO_MILLICODE_THUNK_SET
2911 && !crtl
->calls_eh_return
)
2913 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2914 frame_info
->save_return_addr
= true;
2918 if (arc_must_save_return_addr (cfun
))
2920 if (arc_frame_pointer_needed ())
2923 /* 5) Space for variable arguments passed in registers */
2924 pretend_size
= crtl
->args
.pretend_args_size
;
2926 /* Ensure everything before the locals is aligned appropriately. */
2928 unsigned int extra_plus_reg_size
;
2929 unsigned int extra_plus_reg_size_aligned
;
2931 extra_plus_reg_size
= extra_size
+ reg_size
;
2932 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2933 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2936 /* Compute total frame size. */
2937 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2939 /* It used to be the case that the alignment was forced at this
2940 point. However, that is dangerous, calculations based on
2941 total_size would be wrong. Given that this has never cropped up
2942 as an issue I've changed this to an assert for now. */
2943 gcc_assert (total_size
== ARC_STACK_ALIGN (total_size
));
2945 /* Compute offset of register save area from stack pointer:
2946 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2948 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2949 + (arc_frame_pointer_needed () ? 4 : 0));
2951 /* Save computed information. */
2952 frame_info
->total_size
= total_size
;
2953 frame_info
->extra_size
= extra_size
;
2954 frame_info
->pretend_size
= pretend_size
;
2955 frame_info
->var_size
= var_size
;
2956 frame_info
->args_size
= args_size
;
2957 frame_info
->reg_size
= reg_size
;
2958 frame_info
->reg_offset
= reg_offset
;
2959 frame_info
->gmask
= gmask
;
2960 frame_info
->initialized
= reload_completed
;
2962 /* Ok, we're done. */
2966 /* Common code to save/restore registers. */
2967 /* BASE_REG is the base register to use for addressing and to adjust.
2968 GMASK is a bitmask of general purpose registers to save/restore.
2969 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2970 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2971 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2975 arc_save_restore (rtx base_reg
,
2976 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2978 unsigned int offset
= 0;
2980 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2981 rtx sibthunk_insn
= NULL_RTX
;
2985 /* Millicode thunks implementation:
2986 Generates calls to millicodes for registers starting from r13 to r25
2987 Present Limitations:
2988 - Only one range supported. The remaining regs will have the ordinary
2989 st and ld instructions for store and loads. Hence a gmask asking
2990 to store r13-14, r16-r25 will only generate calls to store and
2991 load r13 to r14 while store and load insns will be generated for
2992 r16 to r25 in the prologue and epilogue respectively.
2994 - Presently library only supports register ranges starting from r13.
2996 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2998 int start_call
= frame
->millicode_start_reg
;
2999 int end_call
= frame
->millicode_end_reg
;
3000 int n_regs
= end_call
- start_call
+ 1;
3001 int i
= 0, r
, off
= 0;
3003 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3007 /* "reg_size" won't be more than 127 . */
3008 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
3009 frame_add (base_reg
, *first_offset
);
3012 insn
= gen_rtx_PARALLEL
3013 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
3014 if (epilogue_p
== 2)
3017 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
3018 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
3020 rtx reg
= gen_rtx_REG (SImode
, r
);
3022 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
3025 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
3027 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
3028 gmask
= gmask
& ~(1L << r
);
3030 if (epilogue_p
== 2)
3031 sibthunk_insn
= insn
;
3034 insn
= frame_insn (insn
);
3035 for (r
= start_call
, off
= 0;
3037 r
++, off
+= UNITS_PER_WORD
)
3039 rtx reg
= gen_rtx_REG (SImode
, r
);
3041 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3044 rtx mem
= gen_rtx_MEM (SImode
, plus_constant (Pmode
,
3048 add_reg_note (insn
, REG_CFA_OFFSET
,
3049 gen_rtx_SET (mem
, reg
));
3056 for (regno
= 0; regno
<= 31; regno
++)
3058 machine_mode mode
= SImode
;
3063 && ((gmask
& (1L << regno
)) != 0)
3064 && ((gmask
& (1L << (regno
+1))) != 0))
3069 else if ((gmask
& (1L << regno
)) != 0)
3077 rtx reg
= gen_rtx_REG (mode
, regno
);
3079 int cfa_adjust
= *first_offset
;
3083 gcc_assert (!offset
);
3084 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
3085 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
3090 gcc_assert (SMALL_INT (offset
));
3091 addr
= plus_constant (Pmode
, base_reg
, offset
);
3093 mem
= gen_frame_mem (mode
, addr
);
3097 frame_move_inc (reg
, mem
, base_reg
, addr
);
3098 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3101 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3102 add_reg_note (insn
, note
,
3103 gen_rtx_SET (stack_pointer_rtx
,
3104 plus_constant (Pmode
,
3110 frame_move_inc (mem
, reg
, base_reg
, addr
);
3111 offset
+= UNITS_PER_WORD
;
3114 offset
+= UNITS_PER_WORD
;
3122 int start_call
= frame
->millicode_start_reg
;
3123 int end_call
= frame
->millicode_end_reg
;
3126 rtx r12
= gen_rtx_REG (Pmode
, 12);
3128 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
3129 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
3130 XVECEXP (sibthunk_insn
, 0, 1)
3131 = gen_rtx_SET (stack_pointer_rtx
,
3132 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
3133 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
3134 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
3136 /* Would be nice if we could do this earlier, when the PARALLEL
3137 is populated, but these need to be attached after the
3139 for (r
= start_call
; r
<= end_call
; r
++)
3141 rtx reg
= gen_rtx_REG (SImode
, r
);
3142 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
3145 } /* arc_save_restore */
3147 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
3151 arc_dwarf_emit_irq_save_regs (void)
3153 rtx tmp
, par
, insn
, reg
;
3156 par
= gen_rtx_SEQUENCE (VOIDmode
,
3157 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
3158 + irq_ctrl_saved
.irq_save_blink
3159 + irq_ctrl_saved
.irq_save_lpcount
3162 /* Build the stack adjustment note for unwind info. */
3164 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
3165 + irq_ctrl_saved
.irq_save_blink
3166 + irq_ctrl_saved
.irq_save_lpcount
);
3167 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
3168 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
3169 RTX_FRAME_RELATED_P (tmp
) = 1;
3170 XVECEXP (par
, 0, j
++) = tmp
;
3172 offset
-= UNITS_PER_WORD
;
3174 /* 1st goes LP_COUNT. */
3175 if (irq_ctrl_saved
.irq_save_lpcount
)
3177 reg
= gen_rtx_REG (SImode
, 60);
3178 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3179 tmp
= gen_frame_mem (SImode
, tmp
);
3180 tmp
= gen_rtx_SET (tmp
, reg
);
3181 RTX_FRAME_RELATED_P (tmp
) = 1;
3182 XVECEXP (par
, 0, j
++) = tmp
;
3183 offset
-= UNITS_PER_WORD
;
3186 /* 2nd goes BLINK. */
3187 if (irq_ctrl_saved
.irq_save_blink
)
3189 reg
= gen_rtx_REG (SImode
, 31);
3190 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3191 tmp
= gen_frame_mem (SImode
, tmp
);
3192 tmp
= gen_rtx_SET (tmp
, reg
);
3193 RTX_FRAME_RELATED_P (tmp
) = 1;
3194 XVECEXP (par
, 0, j
++) = tmp
;
3195 offset
-= UNITS_PER_WORD
;
3198 /* Build the parallel of the remaining registers recorded as saved
3200 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
3202 reg
= gen_rtx_REG (SImode
, i
);
3203 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3204 tmp
= gen_frame_mem (SImode
, tmp
);
3205 tmp
= gen_rtx_SET (tmp
, reg
);
3206 RTX_FRAME_RELATED_P (tmp
) = 1;
3207 XVECEXP (par
, 0, j
++) = tmp
;
3208 offset
-= UNITS_PER_WORD
;
3211 /* Dummy insn used to anchor the dwarf info. */
3212 insn
= emit_insn (gen_stack_irq_dwarf());
3213 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
3214 RTX_FRAME_RELATED_P (insn
) = 1;
3217 /* Set up the stack and frame pointer (if desired) for the function. */
3220 arc_expand_prologue (void)
3223 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
3224 /* unsigned int frame_pointer_offset;*/
3225 unsigned int frame_size_to_allocate
;
3226 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
3227 Change the stack layout so that we rather store a high register with the
3228 PRE_MODIFY, thus enabling more short insn generation.) */
3229 int first_offset
= 0;
3230 unsigned int fn_type
= arc_compute_function_type (cfun
);
3232 /* Naked functions don't have prologue. */
3233 if (ARC_NAKED_P (fn_type
))
3235 if (flag_stack_usage_info
)
3236 current_function_static_stack_size
= 0;
3240 /* Compute total frame size. */
3241 size
= arc_compute_frame_size ();
3243 if (flag_stack_usage_info
)
3244 current_function_static_stack_size
= size
;
3246 /* Keep track of frame size to be allocated. */
3247 frame_size_to_allocate
= size
;
3249 /* These cases shouldn't happen. Catch them now. */
3250 gcc_assert (!(size
== 0 && gmask
));
3252 /* Allocate space for register arguments if this is a variadic function. */
3253 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
3255 /* Ensure pretend_size is maximum of 8 * word_size. */
3256 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
3258 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
3259 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
3262 /* IRQ using automatic save mechanism will save the register before
3264 if (ARC_AUTO_IRQ_P (fn_type
)
3265 && !ARC_FAST_INTERRUPT_P (fn_type
))
3267 arc_dwarf_emit_irq_save_regs ();
3270 /* The home-grown ABI says link register is saved first. */
3271 if (arc_must_save_return_addr (cfun
)
3272 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3274 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
3275 rtx mem
= gen_frame_mem (Pmode
,
3276 gen_rtx_PRE_DEC (Pmode
,
3277 stack_pointer_rtx
));
3279 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
3280 frame_size_to_allocate
-= UNITS_PER_WORD
;
3283 /* Save any needed call-saved regs (and call-used if this is an
3284 interrupt handler) for ARCompact ISA. */
3285 if (cfun
->machine
->frame_info
.reg_size
)
3287 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
3288 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3289 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
3290 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
3293 /* In the case of millicode thunk, we need to restore the clobbered
3295 if (cfun
->machine
->frame_info
.millicode_end_reg
> 0
3296 && arc_must_save_return_addr (cfun
))
3298 HOST_WIDE_INT tmp
= cfun
->machine
->frame_info
.reg_size
;
3299 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
),
3301 plus_constant (Pmode
,
3306 /* Save frame pointer if needed. First save the FP on stack, if not
3308 if (arc_frame_pointer_needed ()
3309 && !ARC_AUTOFP_IRQ_P (fn_type
))
3311 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3312 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
3313 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
3316 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
3317 frame_size_to_allocate
-= UNITS_PER_WORD
;
3321 /* Emit mov fp,sp. */
3322 if (arc_frame_pointer_needed ())
3324 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3327 /* ??? We don't handle the case where the saved regs are more than 252
3328 bytes away from sp. This can be handled by decrementing sp once, saving
3329 the regs, and then decrementing it again. The epilogue doesn't have this
3330 problem as the `ld' insn takes reg+limm values (though it would be more
3331 efficient to avoid reg+limm). */
3333 frame_size_to_allocate
-= first_offset
;
3334 /* Allocate the stack frame. */
3335 if (frame_size_to_allocate
> 0)
3337 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3338 /* If the frame pointer is needed, emit a special barrier that
3339 will prevent the scheduler from moving stores to the frame
3340 before the stack adjustment. */
3341 if (arc_frame_pointer_needed ())
3342 emit_insn (gen_stack_tie (stack_pointer_rtx
,
3343 hard_frame_pointer_rtx
));
3347 /* Do any necessary cleanup after a function to restore stack, frame,
3351 arc_expand_epilogue (int sibcall_p
)
3354 unsigned int fn_type
= arc_compute_function_type (cfun
);
3356 size
= arc_compute_frame_size ();
3358 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
3359 unsigned int frame_size
;
3360 unsigned int size_to_deallocate
;
3362 int can_trust_sp_p
= !cfun
->calls_alloca
;
3363 int first_offset
= 0;
3364 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
3367 /* Naked functions don't have epilogue. */
3368 if (ARC_NAKED_P (fn_type
))
3371 size_to_deallocate
= size
;
3373 frame_size
= size
- (pretend_size
+
3374 cfun
->machine
->frame_info
.reg_size
+
3375 cfun
->machine
->frame_info
.extra_size
);
3377 /* ??? There are lots of optimizations that can be done here.
3378 EG: Use fp to restore regs if it's closer.
3379 Maybe in time we'll do them all. For now, always restore regs from
3380 sp, but don't restore sp if we don't have to. */
3382 if (!can_trust_sp_p
)
3383 gcc_assert (arc_frame_pointer_needed ());
3385 /* Restore stack pointer to the beginning of saved register area for
3389 if (arc_frame_pointer_needed ())
3390 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3392 first_offset
= frame_size
;
3393 size_to_deallocate
-= frame_size
;
3395 else if (!can_trust_sp_p
)
3396 frame_stack_add (-frame_size
);
3399 /* Restore any saved registers. */
3400 if (arc_frame_pointer_needed ()
3401 && !ARC_AUTOFP_IRQ_P (fn_type
))
3403 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
3405 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
3406 stack_pointer_rtx
, 0);
3407 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3408 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3409 plus_constant (SImode
, stack_pointer_rtx
,
3411 size_to_deallocate
-= UNITS_PER_WORD
;
3414 /* Load blink after the calls to thunk calls in case of optimize size. */
3417 int sibthunk_p
= (!sibcall_p
3418 && fn_type
== ARC_FUNCTION_NORMAL
3419 && !cfun
->machine
->frame_info
.pretend_size
);
3421 gcc_assert (!(cfun
->machine
->frame_info
.gmask
3422 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
3423 arc_save_restore (stack_pointer_rtx
,
3424 cfun
->machine
->frame_info
.gmask
,
3425 1 + sibthunk_p
, &first_offset
);
3429 /* If we are to restore registers, and first_offset would require
3430 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3431 fast add to the stack pointer, do this now. */
3432 if ((!SMALL_INT (first_offset
)
3433 && cfun
->machine
->frame_info
.gmask
3434 && ((TARGET_ARC700
&& !optimize_size
)
3435 ? first_offset
<= 0x800
3436 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
3437 /* Also do this if we have both gprs and return
3438 address to restore, and they both would need a LIMM. */
3439 || (arc_must_save_return_addr (cfun
)
3440 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
3441 && cfun
->machine
->frame_info
.gmask
))
3443 frame_stack_add (first_offset
);
3446 if (arc_must_save_return_addr (cfun
)
3447 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3449 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3450 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
3451 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
3452 HOST_WIDE_INT cfa_adjust
= 0;
3454 /* If the load of blink would need a LIMM, but we can add
3455 the offset quickly to sp, do the latter. */
3456 if (!SMALL_INT (ra_offs
>> 2)
3457 && !cfun
->machine
->frame_info
.gmask
3458 && ((TARGET_ARC700
&& !optimize_size
)
3460 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
3462 size_to_deallocate
-= ra_offs
- first_offset
;
3464 frame_stack_add (ra_offs
);
3466 addr
= stack_pointer_rtx
;
3468 /* See if we can combine the load of the return address with the
3469 final stack adjustment.
3470 We need a separate load if there are still registers to
3471 restore. We also want a separate load if the combined insn
3472 would need a limm, but a separate load doesn't. */
3474 && !cfun
->machine
->frame_info
.gmask
3475 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
3477 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
3478 cfa_adjust
= ra_offs
;
3480 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
3482 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
3484 addr
= gen_rtx_POST_INC (Pmode
, addr
);
3485 cfa_adjust
= GET_MODE_SIZE (Pmode
);
3486 size_to_deallocate
= 0;
3489 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
3490 stack_pointer_rtx
, addr
);
3493 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3495 add_reg_note (insn
, note
,
3496 gen_rtx_SET (stack_pointer_rtx
,
3497 plus_constant (SImode
, stack_pointer_rtx
,
3500 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
3505 if (cfun
->machine
->frame_info
.reg_size
)
3506 arc_save_restore (stack_pointer_rtx
,
3507 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3508 cfun
->machine
->frame_info
.gmask
3509 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
3512 /* The rest of this function does the following:
3513 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3516 /* Keep track of how much of the stack pointer we've restored.
3517 It makes the following a lot more readable. */
3518 size_to_deallocate
+= first_offset
;
3519 restored
= size
- size_to_deallocate
;
3521 if (size
> restored
)
3522 frame_stack_add (size
- restored
);
3524 /* For frames that use __builtin_eh_return, the register defined by
3525 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
3526 On eh_return paths however, the register is set to the value that
3527 should be added to the stack pointer in order to restore the
3528 correct stack pointer for the exception handling frame.
3530 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
3531 this onto the stack for eh_return frames. */
3532 if (crtl
->calls_eh_return
)
3533 emit_insn (gen_add2_insn (stack_pointer_rtx
,
3534 EH_RETURN_STACKADJ_RTX
));
3536 /* Emit the return instruction. */
3537 if (sibcall_p
== FALSE
)
3538 emit_jump_insn (gen_simple_return ());
3541 /* Return rtx for the location of the return address on the stack,
3542 suitable for use in __builtin_eh_return. The new return address
3543 will be written to this location in order to redirect the return to
3544 the exception handler. */
3547 arc_eh_return_address_location (void)
3551 struct arc_frame_info
*afi
;
3553 arc_compute_frame_size ();
3554 afi
= &cfun
->machine
->frame_info
;
3556 gcc_assert (crtl
->calls_eh_return
);
3557 gcc_assert (afi
->save_return_addr
);
3558 gcc_assert (afi
->extra_size
>= 4);
3560 /* The '-4' removes the size of the return address, which is
3561 included in the 'extra_size' field. */
3562 offset
= afi
->reg_size
+ afi
->extra_size
- 4;
3563 mem
= gen_frame_mem (Pmode
,
3564 plus_constant (Pmode
, frame_pointer_rtx
, offset
));
3566 /* The following should not be needed, and is, really a hack. The
3567 issue being worked around here is that the DSE (Dead Store
3568 Elimination) pass will remove this write to the stack as it sees
3569 a single store and no corresponding read. The read however
3570 occurs in the epilogue code, which is not added into the function
3571 rtl until a later pass. So, at the time of DSE, the decision to
3572 remove this store seems perfectly sensible. Marking the memory
3573 address as volatile obviously has the effect of preventing DSE
3574 from removing the store. */
3575 MEM_VOLATILE_P (mem
) = 1;
3581 /* Helper to generate unspec constant. */
3584 arc_unspec_offset (rtx loc
, int unspec
)
3586 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3590 /* !TARGET_BARREL_SHIFTER support. */
3591 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3595 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3597 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3599 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3600 (op0
, op1
, op2
, shift
));
3604 /* Output the assembler code for doing a shift.
3605 We go to a bit of trouble to generate efficient code as the ARC601 only has
3606 single bit shifts. This is taken from the h8300 port. We only have one
3607 mode of shifting and can't access individual bytes like the h8300 can, so
3608 this is greatly simplified (at the expense of not generating hyper-
3611 This function is not used if the variable shift insns are present. */
3613 /* FIXME: This probably can be done using a define_split in arc.md.
3614 Alternately, generate rtx rather than output instructions. */
3617 output_shift (rtx
*operands
)
3619 /* static int loopend_lab;*/
3620 rtx shift
= operands
[3];
3621 machine_mode mode
= GET_MODE (shift
);
3622 enum rtx_code code
= GET_CODE (shift
);
3623 const char *shift_one
;
3625 gcc_assert (mode
== SImode
);
3629 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3630 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3631 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3632 default: gcc_unreachable ();
3635 if (GET_CODE (operands
[2]) != CONST_INT
)
3637 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3644 n
= INTVAL (operands
[2]);
3646 /* Only consider the lower 5 bits of the shift count. */
3649 /* First see if we can do them inline. */
3650 /* ??? We could get better scheduling & shorter code (using short insns)
3651 by using splitters. Alas, that'd be even more verbose. */
3652 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3653 && dest_reg_operand (operands
[4], SImode
))
3655 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3656 for (n
-=3 ; n
>= 3; n
-= 3)
3657 output_asm_insn ("add3 %0,%4,%0", operands
);
3659 output_asm_insn ("add2 %0,%4,%0", operands
);
3661 output_asm_insn ("add %0,%0,%0", operands
);
3667 output_asm_insn (shift_one
, operands
);
3668 operands
[1] = operands
[0];
3671 /* See if we can use a rotate/and. */
3672 else if (n
== BITS_PER_WORD
- 1)
3677 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3680 /* The ARC doesn't have a rol insn. Use something else. */
3681 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
3684 /* The ARC doesn't have a rol insn. Use something else. */
3685 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
3691 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
3696 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
3699 #if 1 /* Need some scheduling comparisons. */
3700 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3701 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3703 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3704 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
3709 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3710 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3712 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3713 "and %0,%0,1\n\trlc %0,%0", operands
);
3720 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
3721 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3726 operands
[2] = GEN_INT (n
);
3727 output_asm_insn ("mov.f lp_count, %2", operands
);
3731 output_asm_insn ("lpnz\t2f", operands
);
3732 output_asm_insn (shift_one
, operands
);
3733 output_asm_insn ("nop", operands
);
3734 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
3743 /* Nested function support. */
3745 /* Output assembler code for a block containing the constant parts of
3746 a trampoline, leaving space for variable parts. A trampoline looks
3752 .word function's address
3753 .word static chain value
3758 arc_asm_trampoline_template (FILE *f
)
3760 asm_fprintf (f
, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG
);
3761 asm_fprintf (f
, "\tld\t%s,[pcl,12]\n", reg_names
[STATIC_CHAIN_REGNUM
]);
3762 asm_fprintf (f
, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG
);
3763 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
3764 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
3767 /* Emit RTL insns to initialize the variable parts of a trampoline.
3768 FNADDR is an RTX for the address of the function's pure code. CXT
3769 is an RTX for the static chain value for the function.
3771 The fastest trampoline to execute for trampolines within +-8KB of CTX
3775 j [limm] 0x20200f80 limm
3777 and that would also be faster to write to the stack by computing
3778 the offset from CTX to TRAMP at compile time. However, it would
3779 really be better to get rid of the high cost of cache invalidation
3780 when generating trampolines, which requires that the code part of
3781 trampolines stays constant, and additionally either making sure
3782 that no executable code but trampolines is on the stack, no icache
3783 entries linger for the area of the stack from when before the stack
3784 was allocated, and allocating trampolines in trampoline-only cache
3785 lines or allocate trampolines fram a special pool of pre-allocated
3789 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
3791 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3793 emit_block_move (tramp
, assemble_trampoline_template (),
3794 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
3795 emit_move_insn (adjust_address (tramp
, SImode
, 8), fnaddr
);
3796 emit_move_insn (adjust_address (tramp
, SImode
, 12), cxt
);
3797 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__clear_cache"),
3798 LCT_NORMAL
, VOIDmode
, XEXP (tramp
, 0), Pmode
,
3799 plus_constant (Pmode
, XEXP (tramp
, 0), TRAMPOLINE_SIZE
),
3803 /* Add the given function declaration to emit code in JLI section. */
3806 arc_add_jli_section (rtx pat
)
3810 arc_jli_section
*sec
= arc_jli_sections
, *new_section
;
3811 tree decl
= SYMBOL_REF_DECL (pat
);
3818 /* For fixed locations do not generate the jli table entry. It
3819 should be provided by the user as an asm file. */
3820 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
3821 if (lookup_attribute ("jli_fixed", attrs
))
3825 name
= XSTR (pat
, 0);
3827 /* Don't insert the same symbol twice. */
3830 if(strcmp (name
, sec
->name
) == 0)
3835 /* New name, insert it. */
3836 new_section
= (arc_jli_section
*) xmalloc (sizeof (arc_jli_section
));
3837 gcc_assert (new_section
!= NULL
);
3838 new_section
->name
= name
;
3839 new_section
->next
= arc_jli_sections
;
3840 arc_jli_sections
= new_section
;
3843 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3844 reset when we output the scaled address. */
3845 static int output_scaled
= 0;
3847 /* Set when we force sdata output. */
3848 static int output_sdata
= 0;
3850 /* Print operand X (an rtx) in assembler syntax to file FILE.
3851 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3852 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3853 /* In final.c:output_asm_insn:
3856 'c' : constant address if CONSTANT_ADDRESS_P
3862 'p': bit Position of lsb
3863 's': size of bit field
3864 '#': condbranch delay slot suffix
3865 '*': jump delay slot suffix
3866 '?' : nonjump-insn suffix for conditional execution or short instruction
3867 '!' : jump / call suffix for conditional execution or short instruction
3868 '`': fold constant inside unary o-perator, re-recognize, and emit.
3872 'S': JLI instruction
3873 'j': used by mov instruction to properly emit jli related labels.
3874 'B': Branch comparison operand - suppress sda reference
3875 'H': Most significant word
3876 'L': Least significant word
3877 'A': ASCII decimal representation of floating point value
3878 'U': Load/store update or scaling indicator
3879 'V': cache bypass indicator for volatile
3884 'o': original symbol - no @ prepending. */
3887 arc_print_operand (FILE *file
, rtx x
, int code
)
3892 if (GET_CODE (x
) == CONST_INT
)
3893 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3895 output_operand_lossage ("invalid operand to %%Z code");
3900 if (GET_CODE (x
) == CONST_INT
)
3901 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3903 output_operand_lossage ("invalid operand to %%z code");
3908 if (GET_CODE (x
) == CONST_INT
)
3909 fprintf (file
, "%ld", INTVAL (x
) );
3911 output_operand_lossage ("invalid operands to %%c code");
3916 if (GET_CODE (x
) == CONST_INT
)
3917 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3919 output_operand_lossage ("invalid operand to %%M code");
3924 if (GET_CODE (x
) == CONST_INT
)
3925 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3927 output_operand_lossage ("invalid operand to %%p code");
3931 if (GET_CODE (x
) == CONST_INT
)
3933 HOST_WIDE_INT i
= INTVAL (x
);
3934 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3935 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3938 output_operand_lossage ("invalid operand to %%s code");
3942 /* Conditional branches depending on condition codes.
3943 Note that this is only for branches that were known to depend on
3944 condition codes before delay slot scheduling;
3945 out-of-range brcc / bbit expansions should use '*'.
3946 This distinction is important because of the different
3947 allowable delay slot insns and the output of the delay suffix
3948 for TARGET_AT_DBR_COND_EXEC. */
3950 /* Unconditional branches / branches not depending on condition codes.
3951 This could also be a CALL_INSN.
3952 Output the appropriate delay slot suffix. */
3953 if (final_sequence
&& final_sequence
->len () != 1)
3955 rtx_insn
*jump
= final_sequence
->insn (0);
3956 rtx_insn
*delay
= final_sequence
->insn (1);
3958 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3959 if (delay
->deleted ())
3961 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3962 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3963 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3964 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3971 case '?' : /* with leading "." */
3972 case '!' : /* without leading "." */
3973 /* This insn can be conditionally executed. See if the ccfsm machinery
3974 says it should be conditionalized.
3975 If it shouldn't, we'll check the compact attribute if this insn
3976 has a short variant, which may be used depending on code size and
3977 alignment considerations. */
3978 if (current_insn_predicate
)
3979 arc_ccfsm_current
.cc
3980 = get_arc_condition_code (current_insn_predicate
);
3981 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3983 /* Is this insn in a delay slot sequence? */
3984 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3985 || current_insn_predicate
3986 || CALL_P (final_sequence
->insn (0))
3987 || simplejump_p (final_sequence
->insn (0)))
3989 /* This insn isn't in a delay slot sequence, or conditionalized
3990 independently of its position in a delay slot. */
3991 fprintf (file
, "%s%s",
3992 code
== '?' ? "." : "",
3993 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3994 /* If this is a jump, there are still short variants. However,
3995 only beq_s / bne_s have the same offset range as b_s,
3996 and the only short conditional returns are jeq_s and jne_s. */
3998 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3999 || arc_ccfsm_current
.cc
== ARC_CC_NE
4000 || 0 /* FIXME: check if branch in 7 bit range. */))
4001 output_short_suffix (file
);
4003 else if (code
== '!') /* Jump with delay slot. */
4004 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
4005 else /* An Instruction in a delay slot of a jump or call. */
4007 rtx jump
= XVECEXP (final_sequence
, 0, 0);
4008 rtx insn
= XVECEXP (final_sequence
, 0, 1);
4010 /* If the insn is annulled and is from the target path, we need
4011 to inverse the condition test. */
4012 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
4014 if (INSN_FROM_TARGET_P (insn
))
4015 fprintf (file
, "%s%s",
4016 code
== '?' ? "." : "",
4017 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
4019 fprintf (file
, "%s%s",
4020 code
== '?' ? "." : "",
4021 arc_condition_codes
[arc_ccfsm_current
.cc
]);
4022 if (arc_ccfsm_current
.state
== 5)
4023 arc_ccfsm_current
.state
= 0;
4026 /* This insn is executed for either path, so don't
4027 conditionalize it at all. */
4028 output_short_suffix (file
);
4033 output_short_suffix (file
);
4036 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
4039 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
4042 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
4043 (get_arc_condition_code (x
))],
4047 /* Write second word of DImode or DFmode reference,
4048 register or memory. */
4049 if (GET_CODE (x
) == REG
)
4050 fputs (reg_names
[REGNO (x
)+1], file
);
4051 else if (GET_CODE (x
) == MEM
)
4055 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4056 PRE_MODIFY, we will have handled the first word already;
4057 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4058 first word will be done later. In either case, the access
4059 to the first word will do the modify, and we only have
4060 to add an offset of four here. */
4061 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
4062 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
4063 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
4064 || GET_CODE (XEXP (x
, 0)) == POST_INC
4065 || GET_CODE (XEXP (x
, 0)) == POST_DEC
4066 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
4067 output_address (VOIDmode
,
4068 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
4069 else if (output_scaled
)
4071 rtx addr
= XEXP (x
, 0);
4072 int size
= GET_MODE_SIZE (GET_MODE (x
));
4074 output_address (VOIDmode
,
4075 plus_constant (Pmode
, XEXP (addr
, 0),
4076 ((INTVAL (XEXP (addr
, 1)) + 4)
4077 >> (size
== 2 ? 1 : 2))));
4081 output_address (VOIDmode
,
4082 plus_constant (Pmode
, XEXP (x
, 0), 4));
4086 output_operand_lossage ("invalid operand to %%R code");
4090 if (GET_CODE (x
) == SYMBOL_REF
4091 && arc_is_jli_call_p (x
))
4093 if (SYMBOL_REF_DECL (x
))
4095 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4096 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4098 if (lookup_attribute ("jli_fixed", attrs
))
4100 /* No special treatment for jli_fixed functions. */
4103 fprintf (file
, "%ld\t; @",
4104 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4105 assemble_name (file
, XSTR (x
, 0));
4109 fprintf (file
, "@__jli.");
4110 assemble_name (file
, XSTR (x
, 0));
4112 arc_add_jli_section (x
);
4115 if (GET_CODE (x
) == SYMBOL_REF
4116 && arc_is_secure_call_p (x
))
4118 /* No special treatment for secure functions. */
4121 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4122 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4124 fprintf (file
, "%ld\t; @",
4125 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4126 assemble_name (file
, XSTR (x
, 0));
4130 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4133 output_addr_const (file
, x
);
4139 if (GET_CODE (x
) == REG
)
4141 /* L = least significant word, H = most significant word. */
4142 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
4143 fputs (reg_names
[REGNO (x
)], file
);
4145 fputs (reg_names
[REGNO (x
)+1], file
);
4147 else if (GET_CODE (x
) == CONST_INT
4148 || GET_CODE (x
) == CONST_DOUBLE
)
4150 rtx first
, second
, word
;
4152 split_double (x
, &first
, &second
);
4154 if((WORDS_BIG_ENDIAN
) == 0)
4155 word
= (code
== 'L' ? first
: second
);
4157 word
= (code
== 'L' ? second
: first
);
4159 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
4162 output_operand_lossage ("invalid operand to %%H/%%L code");
4168 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
4169 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
4171 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
4172 fprintf (file
, "%s", str
);
4176 /* Output a load/store with update indicator if appropriate. */
4177 if (GET_CODE (x
) == MEM
)
4179 rtx addr
= XEXP (x
, 0);
4180 switch (GET_CODE (addr
))
4182 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
4183 fputs (".a", file
); break;
4184 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
4185 fputs (".ab", file
); break;
4187 /* Are we using a scaled index? */
4188 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4189 fputs (".as", file
);
4190 /* Can we use a scaled offset? */
4191 else if (CONST_INT_P (XEXP (addr
, 1))
4192 && GET_MODE_SIZE (GET_MODE (x
)) > 1
4193 && (!(INTVAL (XEXP (addr
, 1))
4194 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
4195 /* Does it make a difference? */
4196 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
4197 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
4199 fputs (".as", file
);
4205 if (legitimate_small_data_address_p (addr
)
4206 && GET_MODE_SIZE (GET_MODE (x
)) > 1)
4208 int align
= get_symbol_alignment (addr
);
4210 switch (GET_MODE (x
))
4219 if (align
&& ((align
& mask
) == 0))
4220 fputs (".as", file
);
4226 gcc_assert (CONSTANT_P (addr
)); break;
4230 output_operand_lossage ("invalid operand to %%U code");
4233 /* Output cache bypass indicator for a load/store insn. Volatile memory
4234 refs are defined to use the cache bypass mechanism. */
4235 if (GET_CODE (x
) == MEM
)
4237 if ((MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
4238 || arc_is_uncached_mem_p (x
))
4239 fputs (".di", file
);
4242 output_operand_lossage ("invalid operand to %%V code");
4247 /* Do nothing special. */
4250 fputs (reg_names
[REGNO (x
)]+1, file
);
4253 /* This punctuation character is needed because label references are
4254 printed in the output template using %l. This is a front end
4255 character, and when we want to emit a '@' before it, we have to use
4261 /* Output an operator. */
4262 switch (GET_CODE (x
))
4264 case PLUS
: fputs ("add", file
); return;
4265 case SS_PLUS
: fputs ("adds", file
); return;
4266 case AND
: fputs ("and", file
); return;
4267 case IOR
: fputs ("or", file
); return;
4268 case XOR
: fputs ("xor", file
); return;
4269 case MINUS
: fputs ("sub", file
); return;
4270 case SS_MINUS
: fputs ("subs", file
); return;
4271 case ASHIFT
: fputs ("asl", file
); return;
4272 case ASHIFTRT
: fputs ("asr", file
); return;
4273 case LSHIFTRT
: fputs ("lsr", file
); return;
4274 case ROTATERT
: fputs ("ror", file
); return;
4275 case MULT
: fputs ("mpy", file
); return;
4276 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
4277 case NEG
: fputs ("neg", file
); return;
4278 case SS_NEG
: fputs ("negs", file
); return;
4279 case NOT
: fputs ("not", file
); return; /* Unconditional. */
4281 fputs ("ext", file
); /* bmsk allows predication. */
4283 case SIGN_EXTEND
: /* Unconditional. */
4284 fputs ("sex", file
);
4286 switch (GET_MODE (XEXP (x
, 0)))
4288 case E_QImode
: fputs ("b", file
); return;
4289 case E_HImode
: fputs ("w", file
); return;
4294 if (GET_MODE (x
) != HImode
)
4296 fputs ("sat16", file
);
4299 output_operand_lossage ("invalid operand to %%O code"); return;
4301 if (GET_CODE (x
) == SYMBOL_REF
)
4303 assemble_name (file
, XSTR (x
, 0));
4308 if (TARGET_ANNOTATE_ALIGN
)
4309 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
4325 output_operand_lossage ("invalid operand output code");
4328 switch (GET_CODE (x
))
4331 fputs (reg_names
[REGNO (x
)], file
);
4335 rtx addr
= XEXP (x
, 0);
4336 int size
= GET_MODE_SIZE (GET_MODE (x
));
4338 if (legitimate_small_data_address_p (addr
))
4343 switch (GET_CODE (addr
))
4345 case PRE_INC
: case POST_INC
:
4346 output_address (VOIDmode
,
4347 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
4348 case PRE_DEC
: case POST_DEC
:
4349 output_address (VOIDmode
,
4350 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
4352 case PRE_MODIFY
: case POST_MODIFY
:
4353 output_address (VOIDmode
, XEXP (addr
, 1)); break;
4357 output_address (VOIDmode
,
4358 plus_constant (Pmode
, XEXP (addr
, 0),
4359 (INTVAL (XEXP (addr
, 1))
4360 >> (size
== 2 ? 1 : 2))));
4364 output_address (VOIDmode
, addr
);
4367 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
4368 arc_output_pic_addr_const (file
, addr
, code
);
4370 output_address (VOIDmode
, addr
);
4377 /* We handle SFmode constants here as output_addr_const doesn't. */
4378 if (GET_MODE (x
) == SFmode
)
4382 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
4383 fprintf (file
, "0x%08lx", l
);
4387 /* Let output_addr_const deal with it. */
4390 || (GET_CODE (x
) == CONST
4391 && GET_CODE (XEXP (x
, 0)) == UNSPEC
4392 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
4393 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
4394 || (GET_CODE (x
) == CONST
4395 && GET_CODE (XEXP (x
, 0)) == PLUS
4396 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
4397 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
4398 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
4399 arc_output_pic_addr_const (file
, x
, code
);
4401 output_addr_const (file
, x
);
4406 /* Print a memory address as an operand to reference that memory location. */
4409 arc_print_operand_address (FILE *file
, rtx addr
)
4411 register rtx base
, index
= 0;
4413 switch (GET_CODE (addr
))
4416 fputs (reg_names
[REGNO (addr
)], file
);
4420 fputs ("gp,", file
);
4421 output_addr_const (file
, addr
);
4423 fputs ("@sda", file
);
4427 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4428 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
4429 else if (CONST_INT_P (XEXP (addr
, 0)))
4430 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
4432 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
4434 gcc_assert (OBJECT_P (base
));
4435 arc_print_operand_address (file
, base
);
4436 if (CONSTANT_P (base
) && CONST_INT_P (index
))
4440 gcc_assert (OBJECT_P (index
));
4441 arc_print_operand_address (file
, index
);
4445 rtx c
= XEXP (addr
, 0);
4447 if ((GET_CODE (c
) == UNSPEC
4448 && (XINT (c
, 1) == UNSPEC_TLS_OFF
4449 || XINT (c
, 1) == UNSPEC_TLS_IE
))
4450 || (GET_CODE (c
) == PLUS
4451 && GET_CODE (XEXP (c
, 0)) == UNSPEC
4452 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
4453 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4455 arc_output_pic_addr_const (file
, c
, 0);
4458 gcc_assert (GET_CODE (c
) == PLUS
);
4459 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4460 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4462 output_address (VOIDmode
, XEXP (addr
, 0));
4468 /* We shouldn't get here as we've lost the mode of the memory object
4469 (which says how much to inc/dec by. */
4474 arc_output_pic_addr_const (file
, addr
, 0);
4476 output_addr_const (file
, addr
);
4481 /* Conditional execution support.
4483 This is based on the ARM port but for now is much simpler.
4485 A finite state machine takes care of noticing whether or not instructions
4486 can be conditionally executed, and thus decrease execution time and code
4487 size by deleting branch instructions. The fsm is controlled by
4488 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4489 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4490 insns also have a hand in this. */
4491 /* The way we leave dealing with non-anulled or annull-false delay slot
4492 insns to the consumer is awkward. */
4494 /* The state of the fsm controlling condition codes are:
4495 0: normal, do nothing special
4496 1: don't output this insn
4497 2: don't output this insn
4498 3: make insns conditional
4499 4: make insns conditional
4500 5: make insn conditional (only for outputting anulled delay slot insns)
4502 special value for cfun->machine->uid_ccfsm_state:
4503 6: return with but one insn before it since function start / call
4505 State transitions (state->state by whom, under what condition):
4506 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4508 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4509 by zero or more non-jump insns and an unconditional branch with
4510 the same target label as the condbranch.
4511 1 -> 3 branch patterns, after having not output the conditional branch
4512 2 -> 4 branch patterns, after having not output the conditional branch
4513 0 -> 5 branch patterns, for anulled delay slot insn.
4514 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4515 (the target label has CODE_LABEL_NUMBER equal to
4516 arc_ccfsm_target_label).
4517 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4518 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4519 5 -> 0 when outputting the delay slot insn
4521 If the jump clobbers the conditions then we use states 2 and 4.
4523 A similar thing can be done with conditional return insns.
4525 We also handle separating branches from sets of the condition code.
4526 This is done here because knowledge of the ccfsm state is required,
4527 we may not be outputting the branch. */
4529 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4530 before letting final output INSN. */
4533 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4535 /* BODY will hold the body of INSN. */
4538 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4539 an if/then/else), and things need to be reversed. */
4542 /* If we start with a return insn, we only succeed if we find another one. */
4543 int seeking_return
= 0;
4545 /* START_INSN will hold the insn from where we start looking. This is the
4546 first insn after the following code_label if REVERSE is true. */
4547 rtx_insn
*start_insn
= insn
;
4549 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4550 since they don't rely on a cmp preceding the. */
4551 enum attr_type jump_insn_type
;
4553 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4554 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4555 final_scan_insn which has `optimize' as a local. */
4556 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4559 /* Ignore notes and labels. */
4562 body
= PATTERN (insn
);
4563 /* If in state 4, check if the target branch is reached, in order to
4564 change back to state 0. */
4565 if (state
->state
== 4)
4567 if (insn
== state
->target_insn
)
4569 state
->target_insn
= NULL
;
4575 /* If in state 3, it is possible to repeat the trick, if this insn is an
4576 unconditional branch to a label, and immediately following this branch
4577 is the previous target label which is only used once, and the label this
4578 branch jumps to is not too far off. Or in other words "we've done the
4579 `then' part, see if we can do the `else' part." */
4580 if (state
->state
== 3)
4582 if (simplejump_p (insn
))
4584 start_insn
= next_nonnote_insn (start_insn
);
4585 if (GET_CODE (start_insn
) == BARRIER
)
4587 /* ??? Isn't this always a barrier? */
4588 start_insn
= next_nonnote_insn (start_insn
);
4590 if (GET_CODE (start_insn
) == CODE_LABEL
4591 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4592 && LABEL_NUSES (start_insn
) == 1)
4597 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4599 start_insn
= next_nonnote_insn (start_insn
);
4600 if (GET_CODE (start_insn
) == BARRIER
)
4601 start_insn
= next_nonnote_insn (start_insn
);
4602 if (GET_CODE (start_insn
) == CODE_LABEL
4603 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4604 && LABEL_NUSES (start_insn
) == 1)
4616 if (GET_CODE (insn
) != JUMP_INSN
4617 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4618 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4621 /* We can't predicate BRCC or loop ends.
4622 Also, when generating PIC code, and considering a medium range call,
4623 we can't predicate the call. */
4624 jump_insn_type
= get_attr_type (insn
);
4625 if (jump_insn_type
== TYPE_BRCC
4626 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4627 || jump_insn_type
== TYPE_LOOP_END
4628 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4631 /* This jump might be paralleled with a clobber of the condition codes,
4632 the jump should always come first. */
4633 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4634 body
= XVECEXP (body
, 0, 0);
4637 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4638 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4640 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4641 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4642 int then_not_else
= TRUE
;
4643 /* Nonzero if next insn must be the target label. */
4644 int next_must_be_target_label_p
;
4645 rtx_insn
*this_insn
= start_insn
;
4648 /* Register the insn jumped to. */
4651 if (!seeking_return
)
4652 label
= XEXP (SET_SRC (body
), 0);
4654 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4655 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4656 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4658 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4659 then_not_else
= FALSE
;
4661 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4663 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4666 then_not_else
= FALSE
;
4671 /* If this is a non-annulled branch with a delay slot, there is
4672 no need to conditionalize the delay slot. */
4673 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn
)))) == SEQUENCE
)
4674 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4676 this_insn
= NEXT_INSN (this_insn
);
4678 /* See how many insns this branch skips, and what kind of insns. If all
4679 insns are okay, and the label or unconditional branch to the same
4680 label is not too far away, succeed. */
4681 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
4682 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
4687 this_insn
= next_nonnote_insn (this_insn
);
4691 if (next_must_be_target_label_p
)
4693 if (GET_CODE (this_insn
) == BARRIER
)
4695 if (GET_CODE (this_insn
) == CODE_LABEL
4696 && this_insn
== label
)
4706 switch (GET_CODE (this_insn
))
4709 /* Succeed if it is the target label, otherwise fail since
4710 control falls in from somewhere else. */
4711 if (this_insn
== label
)
4721 /* Succeed if the following insn is the target label.
4723 If return insns are used then the last insn in a function
4724 will be a barrier. */
4725 next_must_be_target_label_p
= TRUE
;
4729 /* Can handle a call insn if there are no insns after it.
4730 IE: The next "insn" is the target label. We don't have to
4731 worry about delay slots as such insns are SEQUENCE's inside
4732 INSN's. ??? It is possible to handle such insns though. */
4733 if (get_attr_cond (this_insn
) == COND_CANUSE
)
4734 next_must_be_target_label_p
= TRUE
;
4740 scanbody
= PATTERN (this_insn
);
4742 /* If this is an unconditional branch to the same label, succeed.
4743 If it is to another label, do nothing. If it is conditional,
4745 /* ??? Probably, the test for the SET and the PC are
4748 if (GET_CODE (scanbody
) == SET
4749 && GET_CODE (SET_DEST (scanbody
)) == PC
)
4751 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
4752 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
4757 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
4759 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
4762 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
4768 else if (GET_CODE (scanbody
) == PARALLEL
)
4770 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4776 scanbody
= PATTERN (this_insn
);
4778 /* We can only do this with insns that can use the condition
4779 codes (and don't set them). */
4780 if (GET_CODE (scanbody
) == SET
4781 || GET_CODE (scanbody
) == PARALLEL
)
4783 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4786 /* We can't handle other insns like sequences. */
4798 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
4799 state
->target_label
= CODE_LABEL_NUMBER (label
);
4800 else if (seeking_return
|| state
->state
== 2)
4802 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
4804 this_insn
= next_nonnote_insn (this_insn
);
4806 gcc_assert (!this_insn
||
4807 (GET_CODE (this_insn
) != BARRIER
4808 && GET_CODE (this_insn
) != CODE_LABEL
));
4812 /* Oh dear! we ran off the end, give up. */
4813 extract_insn_cached (insn
);
4815 state
->target_insn
= NULL
;
4818 state
->target_insn
= this_insn
;
4823 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4827 state
->cond
= XEXP (SET_SRC (body
), 0);
4828 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4831 if (reverse
|| then_not_else
)
4832 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4835 /* Restore recog_operand. Getting the attributes of other insns can
4836 destroy this array, but final.c assumes that it remains intact
4837 across this call; since the insn has been recognized already we
4838 call insn_extract direct. */
4839 extract_insn_cached (insn
);
4843 /* Record that we are currently outputting label NUM with prefix PREFIX.
4844 It it's the label we're looking for, reset the ccfsm machinery.
4846 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4849 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4851 if (state
->state
== 3 && state
->target_label
== num
4852 && !strcmp (prefix
, "L"))
4855 state
->target_insn
= NULL
;
4859 /* We are considering a conditional branch with the condition COND.
4860 Check if we want to conditionalize a delay slot insn, and if so modify
4861 the ccfsm state accordingly.
4862 REVERSE says branch will branch when the condition is false. */
4864 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4865 struct arc_ccfsm
*state
)
4867 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4869 state
= &arc_ccfsm_current
;
4871 gcc_assert (state
->state
== 0);
4872 if (seq_insn
!= jump
)
4874 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4876 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4877 && INSN_ANNULLED_BRANCH_P (jump
)
4878 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4881 state
->cc
= get_arc_condition_code (cond
);
4883 arc_ccfsm_current
.cc
4884 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4885 rtx pat
= PATTERN (insn
);
4886 if (GET_CODE (pat
) == COND_EXEC
)
4887 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4888 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4889 == get_arc_condition_code (XEXP (pat
, 0)));
4896 /* Update *STATE as we would when we emit INSN. */
4899 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4901 enum attr_type type
;
4904 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4905 else if (JUMP_P (insn
)
4906 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4907 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4908 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4909 || ((type
== TYPE_UNCOND_BRANCH
4910 || type
== TYPE_RETURN
)
4911 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4913 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4914 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4917 rtx src
= SET_SRC (PATTERN (insn
));
4918 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4922 else if (arc_ccfsm_current
.state
== 5)
4923 arc_ccfsm_current
.state
= 0;
4926 /* Return true if the current insn, which is a conditional branch, is to be
4930 arc_ccfsm_branch_deleted_p (void)
4932 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4935 /* Record a branch isn't output because subsequent insns can be
4939 arc_ccfsm_record_branch_deleted (void)
4941 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4944 /* During insn output, indicate if the current insn is predicated. */
4947 arc_ccfsm_cond_exec_p (void)
4949 return (cfun
->machine
->prescan_initialized
4950 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4953 /* When deciding if an insn should be output short, we want to know something
4954 about the following insns:
4955 - if another insn follows which we know we can output as a short insn
4956 before an alignment-sensitive point, we can output this insn short:
4957 the decision about the eventual alignment can be postponed.
4958 - if a to-be-aligned label comes next, we should output this insn such
4959 as to get / preserve 4-byte alignment.
4960 - if a likely branch without delay slot insn, or a call with an immediately
4961 following short insn comes next, we should out output this insn such as to
4962 get / preserve 2 mod 4 unalignment.
4963 - do the same for a not completely unlikely branch with a short insn
4964 following before any other branch / label.
4965 - in order to decide if we are actually looking at a branch, we need to
4966 call arc_ccfsm_advance.
4967 - in order to decide if we are looking at a short insn, we should know
4968 if it is conditionalized. To a first order of approximation this is
4969 the case if the state from arc_ccfsm_advance from before this insn
4970 indicates the insn is conditionalized. However, a further refinement
4971 could be to not conditionalize an insn if the destination register(s)
4972 is/are dead in the non-executed case. */
4973 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4974 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4975 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4978 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4980 enum attr_iscompact iscompact
;
4984 iscompact
= get_attr_iscompact (insn
);
4985 if (iscompact
== ISCOMPACT_FALSE
)
4989 return (get_attr_length (insn
) & 2) != 0;
4992 /* When outputting an instruction (alternative) that can potentially be short,
4993 output the short suffix if the insn is in fact short, and update
4994 cfun->machine->unalign accordingly. */
4997 output_short_suffix (FILE *file
)
4999 rtx_insn
*insn
= current_output_insn
;
5001 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
5003 fprintf (file
, "_s");
5004 cfun
->machine
->unalign
^= 2;
5006 /* Restore recog_operand. */
5007 extract_insn_cached (insn
);
5010 /* Implement FINAL_PRESCAN_INSN. */
5013 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
5014 int noperands ATTRIBUTE_UNUSED
)
5016 if (TARGET_DUMPISIZE
)
5017 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
5019 if (!cfun
->machine
->prescan_initialized
)
5021 /* Clear lingering state from branch shortening. */
5022 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
5023 cfun
->machine
->prescan_initialized
= 1;
5025 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
5028 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5029 Frame pointer elimination is automatically handled.
5031 All eliminations are permissible. If we need a frame
5032 pointer, we must eliminate ARG_POINTER_REGNUM into
5033 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5036 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
5038 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
5041 /* Define the offset between two registers, one to be eliminated, and
5042 the other its replacement, at the start of a routine. */
5045 arc_initial_elimination_offset (int from
, int to
)
5047 if (!cfun
->machine
->frame_info
.initialized
)
5048 arc_compute_frame_size ();
5050 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
5052 return (cfun
->machine
->frame_info
.extra_size
5053 + cfun
->machine
->frame_info
.reg_size
);
5056 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
5058 return (cfun
->machine
->frame_info
.total_size
5059 - cfun
->machine
->frame_info
.pretend_size
);
5062 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
5064 return (cfun
->machine
->frame_info
.total_size
5065 - (cfun
->machine
->frame_info
.pretend_size
5066 + cfun
->machine
->frame_info
.extra_size
5067 + cfun
->machine
->frame_info
.reg_size
));
5074 arc_frame_pointer_required (void)
5076 return cfun
->calls_alloca
|| crtl
->calls_eh_return
;
5080 /* Return the destination address of a branch. */
5083 branch_dest (rtx branch
)
5085 rtx pat
= PATTERN (branch
);
5086 rtx dest
= (GET_CODE (pat
) == PARALLEL
5087 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
5090 if (GET_CODE (dest
) == IF_THEN_ELSE
)
5091 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
5093 dest
= XEXP (dest
, 0);
5094 dest_uid
= INSN_UID (dest
);
5096 return INSN_ADDRESSES (dest_uid
);
5100 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5103 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
5105 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5106 This clears machine specific flags, so has to come first. */
5107 default_encode_section_info (decl
, rtl
, first
);
5109 /* Check if it is a function, and whether it has the
5110 [long/medium/short]_call attribute specified. */
5111 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5113 rtx symbol
= XEXP (rtl
, 0);
5114 int flags
= SYMBOL_REF_FLAGS (symbol
);
5116 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5117 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
5118 tree long_call_attr
= lookup_attribute ("long_call", attr
);
5119 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
5120 tree short_call_attr
= lookup_attribute ("short_call", attr
);
5122 if (long_call_attr
!= NULL_TREE
)
5123 flags
|= SYMBOL_FLAG_LONG_CALL
;
5124 else if (medium_call_attr
!= NULL_TREE
)
5125 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
5126 else if (short_call_attr
!= NULL_TREE
)
5127 flags
|= SYMBOL_FLAG_SHORT_CALL
;
5129 SYMBOL_REF_FLAGS (symbol
) = flags
;
5131 else if (TREE_CODE (decl
) == VAR_DECL
)
5133 rtx symbol
= XEXP (rtl
, 0);
5135 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5136 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
5138 tree sec_attr
= lookup_attribute ("section", attr
);
5141 const char *sec_name
5142 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
5143 if (strcmp (sec_name
, ".cmem") == 0
5144 || strcmp (sec_name
, ".cmem_shared") == 0
5145 || strcmp (sec_name
, ".cmem_private") == 0)
5146 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
5151 /* This is how to output a definition of an internal numbered label where
5152 PREFIX is the class of label and NUM is the number within the class. */
5154 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
5157 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
5158 default_internal_label (stream
, prefix
, labelno
);
5161 /* Set the cpu type and print out other fancy things,
5162 at the top of the file. */
5164 static void arc_file_start (void)
5166 default_file_start ();
5167 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
5169 /* Set some want to have build attributes. */
5170 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5172 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5173 TARGET_RF16
? 1 : 0);
5174 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5176 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5177 (arc_tp_regno
!= -1) ? 1 : 0);
5178 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5179 TARGET_NO_SDATA_SET
? 0 : 2);
5180 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5181 TARGET_OPTFPE
? 1 : 0);
5183 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5184 arc_tune
== ARC_TUNE_CORE_3
? 3 : 2);
5187 /* Implement `TARGET_ASM_FILE_END'. */
5188 /* Outputs to the stdio stream FILE jli related text. */
5190 void arc_file_end (void)
5192 arc_jli_section
*sec
= arc_jli_sections
;
5196 fprintf (asm_out_file
, "\n");
5197 fprintf (asm_out_file
, "# JLI entry for function ");
5198 assemble_name (asm_out_file
, sec
->name
);
5199 fprintf (asm_out_file
, "\n\t.section .jlitab, \"axG\", @progbits, "
5201 assemble_name (asm_out_file
, sec
->name
);
5202 fprintf (asm_out_file
,", comdat\n");
5204 fprintf (asm_out_file
, "\t.align\t4\n");
5205 fprintf (asm_out_file
, "__jli.");
5206 assemble_name (asm_out_file
, sec
->name
);
5207 fprintf (asm_out_file
, ":\n\t.weak __jli.");
5208 assemble_name (asm_out_file
, sec
->name
);
5209 fprintf (asm_out_file
, "\n\tb\t@");
5210 assemble_name (asm_out_file
, sec
->name
);
5211 fprintf (asm_out_file
, "\n");
5214 file_end_indicate_exec_stack ();
5217 /* Cost functions. */
5219 /* Compute a (partial) cost for rtx X. Return true if the complete
5220 cost has been computed, and false if subexpressions should be
5221 scanned. In either case, *TOTAL contains the cost result. */
5224 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
5225 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
5227 int code
= GET_CODE (x
);
5231 /* Small integers are as cheap as registers. */
5234 bool nolimm
= false; /* Can we do without long immediate? */
5235 bool fast
= false; /* Is the result available immediately? */
5236 bool condexec
= false; /* Does this allow conditiobnal execution? */
5237 bool compact
= false; /* Is a 16 bit opcode available? */
5238 /* CONDEXEC also implies that we can have an unconditional
5239 3-address operation. */
5241 nolimm
= compact
= condexec
= false;
5242 if (UNSIGNED_INT6 (INTVAL (x
)))
5243 nolimm
= condexec
= compact
= true;
5246 if (SMALL_INT (INTVAL (x
)))
5247 nolimm
= fast
= true;
5250 case AND
: /* bclr, bmsk, ext[bw] */
5251 if (satisfies_constraint_Ccp (x
) /* bclr */
5252 || satisfies_constraint_C1p (x
) /* bmsk */)
5253 nolimm
= fast
= condexec
= compact
= true;
5255 case IOR
: /* bset */
5256 if (satisfies_constraint_C0p (x
)) /* bset */
5257 nolimm
= fast
= condexec
= compact
= true;
5260 if (satisfies_constraint_C0p (x
)) /* bxor */
5261 nolimm
= fast
= condexec
= true;
5264 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
5270 /* FIXME: Add target options to attach a small cost if
5271 condexec / compact is not true. */
5280 /* 4 byte values can be fetched as immediate constants -
5281 let's give that the cost of an extra insn. */
5285 *total
= COSTS_N_INSNS (1);
5294 *total
= COSTS_N_INSNS (1);
5297 split_double (x
, &first
, &second
);
5298 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
5299 + !SMALL_INT (INTVAL (second
)));
5303 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5304 If we need more than 12 insns to do a multiply, then go out-of-line,
5305 since the call overhead will be < 10% of the cost of the multiply. */
5309 if (TARGET_BARREL_SHIFTER
)
5311 /* If we want to shift a constant, we need a LIMM. */
5312 /* ??? when the optimizers want to know if a constant should be
5313 hoisted, they ask for the cost of the constant. OUTER_CODE is
5314 insufficient context for shifts since we don't know which operand
5315 we are looking at. */
5316 if (CONSTANT_P (XEXP (x
, 0)))
5318 *total
+= (COSTS_N_INSNS (2)
5319 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
5323 *total
= COSTS_N_INSNS (1);
5325 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5326 *total
= COSTS_N_INSNS (16);
5329 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
5330 /* ??? want_to_gcse_p can throw negative shift counts at us,
5331 and then panics when it gets a negative cost as result.
5332 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5341 *total
= COSTS_N_INSNS(30);
5343 *total
= COSTS_N_INSNS(1);
5347 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
5348 *total
= COSTS_N_INSNS (1);
5350 *total
= arc_multcost
;
5351 /* We do not want synth_mult sequences when optimizing
5353 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
5354 *total
= COSTS_N_INSNS (1);
5356 *total
= COSTS_N_INSNS (2);
5359 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
5360 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
5361 || (GET_CODE (XEXP (x
, 0)) == MULT
5362 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
5364 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
5365 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
5370 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
5371 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
5372 || (GET_CODE (XEXP (x
, 1)) == MULT
5373 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
5375 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
5376 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
5382 rtx op0
= XEXP (x
, 0);
5383 rtx op1
= XEXP (x
, 1);
5385 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
5386 && XEXP (op0
, 1) == const1_rtx
)
5388 /* btst / bbit0 / bbit1:
5389 Small integers and registers are free; everything else can
5390 be put in a register. */
5391 mode
= GET_MODE (XEXP (op0
, 0));
5392 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5393 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5396 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5397 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5400 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5404 if (GET_CODE (op1
) == NEG
)
5406 /* op0 might be constant, the inside of op1 is rather
5407 unlikely to be so. So swapping the operands might lower
5409 mode
= GET_MODE (op0
);
5410 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5411 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5416 if (outer_code
== IF_THEN_ELSE
5417 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5418 && XEXP (x
, 1) == const0_rtx
5419 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5421 /* btst / bbit0 / bbit1:
5422 Small integers and registers are free; everything else can
5423 be put in a register. */
5424 rtx op0
= XEXP (x
, 0);
5426 mode
= GET_MODE (XEXP (op0
, 0));
5427 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5428 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5432 /* scc_insn expands into two insns. */
5433 case GTU
: case GEU
: case LEU
:
5435 *total
+= COSTS_N_INSNS (1);
5437 case LTU
: /* might use adc. */
5439 *total
+= COSTS_N_INSNS (1) - 1;
5446 /* Return true if ADDR is a valid pic address.
5447 A valid pic address on arc should look like
5448 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5451 arc_legitimate_pic_addr_p (rtx addr
)
5453 if (GET_CODE (addr
) != CONST
)
5456 addr
= XEXP (addr
, 0);
5459 if (GET_CODE (addr
) == PLUS
)
5461 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5463 addr
= XEXP (addr
, 0);
5466 if (GET_CODE (addr
) != UNSPEC
5467 || XVECLEN (addr
, 0) != 1)
5470 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5471 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5472 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5473 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5474 && XINT (addr
, 1) != UNSPEC_TLS_GD
5475 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5478 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5479 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5487 /* Return true if OP contains a symbol reference. */
5490 symbolic_reference_mentioned_p (rtx op
)
5492 register const char *fmt
;
5495 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5498 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5499 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5505 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5506 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5510 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5517 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5518 If SKIP_LOCAL is true, skip symbols that bind locally.
5519 This is used further down in this file, and, without SKIP_LOCAL,
5520 in the addsi3 / subsi3 expanders when generating PIC code. */
5523 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5525 register const char *fmt
;
5528 if (GET_CODE(op
) == UNSPEC
)
5531 if (GET_CODE (op
) == SYMBOL_REF
)
5533 if (SYMBOL_REF_TLS_MODEL (op
))
5537 tree decl
= SYMBOL_REF_DECL (op
);
5538 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5541 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5542 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5548 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5549 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5554 else if (fmt
[i
] == 'e'
5555 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5563 /* Get the thread pointer. */
5568 /* If arc_tp_regno has been set, we can use that hard register
5569 directly as a base register. */
5570 if (arc_tp_regno
!= -1)
5571 return gen_rtx_REG (Pmode
, arc_tp_regno
);
5573 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5574 conflicts with function arguments / results. */
5575 rtx reg
= gen_reg_rtx (Pmode
);
5576 emit_insn (gen_tls_load_tp_soft ());
5577 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
5581 /* Helper to be used by TLS Global dynamic model. */
5584 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
5586 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
5587 rtx call_fusage
= NULL_RTX
;
5591 rtx x
= arc_unspec_offset (sym
, reloc
);
5592 emit_move_insn (r0
, x
);
5593 use_reg (&call_fusage
, r0
);
5595 gcc_assert (reloc
== UNSPEC_TLS_GD
);
5596 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
5597 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5598 way that the application should care. */
5599 RTL_PURE_CALL_P (call_insn
) = 1;
5600 add_function_usage_to (call_insn
, call_fusage
);
5602 rtx_insn
*insns
= get_insns ();
5605 rtx dest
= gen_reg_rtx (Pmode
);
5606 emit_libcall_block (insns
, dest
, r0
, eqv
);
5610 #define DTPOFF_ZERO_SYM ".tdata"
5612 /* Return a legitimized address for ADDR,
5613 which is a SYMBOL_REF with tls_model MODEL. */
5616 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5618 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5619 model
= TLS_MODEL_LOCAL_EXEC
;
5623 case TLS_MODEL_LOCAL_DYNAMIC
:
5626 const char *base_name
;
5629 decl
= SYMBOL_REF_DECL (addr
);
5630 base_name
= DTPOFF_ZERO_SYM
;
5631 if (decl
&& bss_initializer_p (decl
))
5632 base_name
= ".tbss";
5634 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5635 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
5639 v
= gen_rtvec (1, addr
);
5642 v
= gen_rtvec (2, addr
, base
);
5643 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
5644 addr
= gen_rtx_CONST (Pmode
, addr
);
5645 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
5646 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
5648 case TLS_MODEL_GLOBAL_DYNAMIC
:
5649 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
5651 case TLS_MODEL_INITIAL_EXEC
:
5652 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5653 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5654 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5656 case TLS_MODEL_LOCAL_EXEC
:
5658 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5659 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5665 /* Legitimize a pic address reference in ORIG.
5666 The return value is the legitimated address.
5667 If OLDX is non-zero, it is the target to assign the address to first. */
5670 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5679 if (GET_CODE (addr
) == LABEL_REF
)
5681 else if (GET_CODE (addr
) == SYMBOL_REF
)
5683 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5685 return arc_legitimize_tls_address (addr
, model
);
5688 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5689 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5691 /* This symbol must be referenced via a load from the Global
5692 Offset Table (@GOTPC). */
5693 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5694 pat
= gen_const_mem (Pmode
, pat
);
5697 oldx
= gen_reg_rtx (Pmode
);
5699 emit_move_insn (oldx
, pat
);
5704 if (GET_CODE (addr
) == CONST
)
5706 addr
= XEXP (addr
, 0);
5707 if (GET_CODE (addr
) == UNSPEC
)
5709 /* Check that the unspec is one of the ones we generate? */
5712 /* fwprop is placing in the REG_EQUIV notes constant pic
5713 unspecs expressions. Then, loop may use these notes for
5714 optimizations resulting in complex patterns that are not
5715 supported by the current implementation. The following
5716 two if-cases are simplifying the complex patters to
5718 else if (GET_CODE (addr
) == MINUS
)
5720 rtx op0
= XEXP (addr
, 0);
5721 rtx op1
= XEXP (addr
, 1);
5723 gcc_assert (GET_CODE (op1
) == UNSPEC
);
5725 emit_move_insn (oldx
,
5726 gen_rtx_CONST (SImode
,
5727 arc_legitimize_pic_address (op1
,
5729 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
5733 else if (GET_CODE (addr
) != PLUS
)
5735 rtx tmp
= XEXP (addr
, 0);
5736 enum rtx_code code
= GET_CODE (addr
);
5738 /* It only works for UNARY operations. */
5739 gcc_assert (UNARY_P (addr
));
5740 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
5745 gen_rtx_CONST (SImode
,
5746 arc_legitimize_pic_address (tmp
,
5749 emit_insn (gen_rtx_SET (oldx
,
5750 gen_rtx_fmt_ee (code
, SImode
,
5751 oldx
, const0_rtx
)));
5757 gcc_assert (GET_CODE (addr
) == PLUS
);
5758 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
5763 if (GET_CODE (addr
) == PLUS
)
5765 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
5767 base
= arc_legitimize_pic_address (op0
, oldx
);
5768 pat
= arc_legitimize_pic_address (op1
,
5769 base
== oldx
? NULL_RTX
: oldx
);
5771 if (base
== op0
&& pat
== op1
)
5774 if (GET_CODE (pat
) == CONST_INT
)
5775 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
5778 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
5780 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
5781 pat
= XEXP (pat
, 1);
5783 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
5791 /* Output address constant X to FILE, taking PIC into account. */
5794 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5799 switch (GET_CODE (x
))
5809 output_addr_const (file
, x
);
5811 /* Local functions do not get references through the PLT. */
5812 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5813 fputs ("@plt", file
);
5817 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5818 assemble_name (file
, buf
);
5822 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5823 assemble_name (file
, buf
);
5827 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5831 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5835 if (GET_MODE (x
) == VOIDmode
)
5837 /* We can use %d if the number is one word and positive. */
5838 if (CONST_DOUBLE_HIGH (x
))
5839 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5840 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5841 else if (CONST_DOUBLE_LOW (x
) < 0)
5842 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5844 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5847 /* We can't handle floating point constants;
5848 PRINT_OPERAND must handle them. */
5849 output_operand_lossage ("floating constant misused");
5853 /* FIXME: Not needed here. */
5854 /* Some assemblers need integer constants to appear last (eg masm). */
5855 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5857 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5858 fprintf (file
, "+");
5859 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5861 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5863 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5864 if (INTVAL (XEXP (x
, 1)) >= 0)
5865 fprintf (file
, "+");
5866 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5873 /* Avoid outputting things like x-x or x+5-x,
5874 since some assemblers can't handle that. */
5875 x
= simplify_subtraction (x
);
5876 if (GET_CODE (x
) != MINUS
)
5879 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5880 fprintf (file
, "-");
5881 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5882 && INTVAL (XEXP (x
, 1)) < 0)
5884 fprintf (file
, "(");
5885 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5886 fprintf (file
, ")");
5889 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5894 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5900 bool pcrel
; pcrel
= false;
5901 rtx base
; base
= NULL
;
5902 gcc_assert (XVECLEN (x
, 0) >= 1);
5903 switch (XINT (x
, 1))
5905 case ARC_UNSPEC_GOT
:
5906 suffix
= "@gotpc", pcrel
= true;
5908 case ARC_UNSPEC_GOTOFF
:
5911 case ARC_UNSPEC_GOTOFFPC
:
5912 suffix
= "@pcl", pcrel
= true;
5914 case ARC_UNSPEC_PLT
:
5918 suffix
= "@tlsgd", pcrel
= true;
5921 suffix
= "@tlsie", pcrel
= true;
5923 case UNSPEC_TLS_OFF
:
5924 if (XVECLEN (x
, 0) == 2)
5925 base
= XVECEXP (x
, 0, 1);
5926 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5927 || (!flag_pic
&& !base
))
5933 suffix
= "@invalid";
5934 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5938 fputs ("pcl,", file
);
5939 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5940 fputs (suffix
, file
);
5942 arc_output_pic_addr_const (file
, base
, code
);
5946 output_operand_lossage ("invalid expression as operand");
5950 #define SYMBOLIC_CONST(X) \
5951 (GET_CODE (X) == SYMBOL_REF \
5952 || GET_CODE (X) == LABEL_REF \
5953 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5955 /* Emit insns to move operands[1] into operands[0]. */
5958 prepare_pic_move (rtx
*operands
, machine_mode
)
5960 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5962 operands
[1] = force_reg (Pmode
, operands
[1]);
5965 rtx temp
= (reload_in_progress
? operands
[0]
5966 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5967 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5972 /* The function returning the number of words, at the beginning of an
5973 argument, must be put in registers. The returned value must be
5974 zero for arguments that are passed entirely in registers or that
5975 are entirely pushed on the stack.
5977 On some machines, certain arguments must be passed partially in
5978 registers and partially in memory. On these machines, typically
5979 the first N words of arguments are passed in registers, and the
5980 rest on the stack. If a multi-word argument (a `double' or a
5981 structure) crosses that boundary, its first few words must be
5982 passed in registers and the rest must be pushed. This function
5983 tells the compiler when this occurs, and how many of the words
5984 should go in registers.
5986 `FUNCTION_ARG' for these arguments should return the first register
5987 to be used by the caller for this argument; likewise
5988 `FUNCTION_INCOMING_ARG', for the called function.
5990 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5992 /* If REGNO is the least arg reg available then what is the total number of arg
5994 #define GPR_REST_ARG_REGS(REGNO) \
5995 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5997 /* Since arc parm regs are contiguous. */
5998 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6000 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6003 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
6004 tree type
, bool named ATTRIBUTE_UNUSED
)
6006 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6007 int bytes
= (mode
== BLKmode
6008 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
6009 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6013 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
6014 ret
= GPR_REST_ARG_REGS (arg_num
);
6016 /* ICEd at function.c:2361, and ret is copied to data->partial */
6017 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
6022 /* This function is used to control a function argument is passed in a
6023 register, and which register.
6025 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
6026 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
6027 all of the previous arguments so far passed in registers; MODE, the
6028 machine mode of the argument; TYPE, the data type of the argument
6029 as a tree node or 0 if that is not known (which happens for C
6030 support library functions); and NAMED, which is 1 for an ordinary
6031 argument and 0 for nameless arguments that correspond to `...' in
6032 the called function's prototype.
6034 The returned value should either be a `reg' RTX for the hard
6035 register in which to pass the argument, or zero to pass the
6036 argument on the stack.
6038 For machines like the Vax and 68000, where normally all arguments
6039 are pushed, zero suffices as a definition.
6041 The usual way to make the ANSI library `stdarg.h' work on a machine
6042 where some arguments are usually passed in registers, is to cause
6043 nameless arguments to be passed on the stack instead. This is done
6044 by making the function return 0 whenever NAMED is 0.
6046 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
6047 definition of this function to determine if this argument is of a
6048 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
6049 is not defined and the function returns non-zero for such an
6050 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
6051 defined, the argument will be computed in the stack and then loaded
6054 The function is used to implement macro FUNCTION_ARG. */
6055 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
6056 and the rest are pushed. */
6059 arc_function_arg (cumulative_args_t cum_v
,
6061 const_tree type ATTRIBUTE_UNUSED
,
6062 bool named ATTRIBUTE_UNUSED
)
6064 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6067 const char *debstr ATTRIBUTE_UNUSED
;
6069 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
6070 /* Return a marker for use in the call instruction. */
6071 if (mode
== VOIDmode
)
6076 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
6078 ret
= gen_rtx_REG (mode
, arg_num
);
6079 debstr
= reg_names
[arg_num
];
6089 /* The function to update the summarizer variable *CUM to advance past
6090 an argument in the argument list. The values MODE, TYPE and NAMED
6091 describe that argument. Once this is done, the variable *CUM is
6092 suitable for analyzing the *following* argument with
6093 `FUNCTION_ARG', etc.
6095 This function need not do anything if the argument in question was
6096 passed on the stack. The compiler knows how to track the amount of
6097 stack space used for arguments without any special help.
6099 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
6100 /* For the ARC: the cum set here is passed on to function_arg where we
6101 look at its value and say which reg to use. Strategy: advance the
6102 regnumber here till we run out of arg regs, then set *cum to last
6103 reg. In function_arg, since *cum > last arg reg we would return 0
6104 and thus the arg will end up on the stack. For straddling args of
6105 course function_arg_partial_nregs will come into play. */
6108 arc_function_arg_advance (cumulative_args_t cum_v
,
6111 bool named ATTRIBUTE_UNUSED
)
6113 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6114 int bytes
= (mode
== BLKmode
6115 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
6116 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6120 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
6121 for (i
= 0; i
< words
; i
++)
6122 *cum
= ARC_NEXT_ARG_REG (*cum
);
6126 /* Define how to find the value returned by a function.
6127 VALTYPE is the data type of the value (as a tree).
6128 If the precise function being called is known, FN_DECL_OR_TYPE is its
6129 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6132 arc_function_value (const_tree valtype
,
6133 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
6134 bool outgoing ATTRIBUTE_UNUSED
)
6136 machine_mode mode
= TYPE_MODE (valtype
);
6137 int unsignedp ATTRIBUTE_UNUSED
;
6139 unsignedp
= TYPE_UNSIGNED (valtype
);
6140 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
6141 PROMOTE_MODE (mode
, unsignedp
, valtype
);
6142 return gen_rtx_REG (mode
, 0);
6145 /* Returns the return address that is used by builtin_return_address. */
6148 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
6153 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6156 /* Determine if a given RTX is a valid constant. We already know this
6157 satisfies CONSTANT_P. */
6160 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
6162 switch (GET_CODE (x
))
6167 if (arc_legitimate_pic_addr_p (x
))
6170 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6173 if (SYMBOL_REF_TLS_MODEL (x
))
6185 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6190 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6191 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
6200 return TARGET_PLUS_DMPY
;
6203 return TARGET_PLUS_QMACW
;
6209 switch (XINT (x
, 1))
6212 case UNSPEC_TLS_OFF
:
6216 /* Any other unspec ending here are pic related, hence the above
6217 constant pic address checking returned false. */
6223 fatal_insn ("unrecognized supposed constant", x
);
6230 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
6232 if (RTX_OK_FOR_BASE_P (x
, strict
))
6234 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
6236 if (legitimate_scaled_address_p (mode
, x
, strict
))
6238 if (legitimate_small_data_address_p (x
))
6240 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
6243 /* When we compile for size avoid const (@sym + offset)
6245 if (!flag_pic
&& optimize_size
&& !reload_completed
6246 && (GET_CODE (x
) == CONST
)
6247 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
6248 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
6249 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
6250 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
6252 rtx addend
= XEXP (XEXP (x
, 0), 1);
6253 gcc_assert (CONST_INT_P (addend
));
6254 HOST_WIDE_INT offset
= INTVAL (addend
);
6256 /* Allow addresses having a large offset to pass. Anyhow they
6257 will end in a limm. */
6258 return !(offset
> -1024 && offset
< 1020);
6261 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
6263 return arc_legitimate_constant_p (mode
, x
);
6265 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
6266 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
6267 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
6269 /* We're restricted here by the `st' insn. */
6270 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
6271 && GET_CODE (XEXP ((x
), 1)) == PLUS
6272 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
6273 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
6274 TARGET_AUTO_MODIFY_REG
, strict
))
6279 /* Return true iff ADDR (a legitimate address expression)
6280 has an effect that depends on the machine mode it is used for. */
6283 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
6285 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6286 which is valid for loads and stores, or a limm offset, which is valid for
6287 loads. Scaled indices are scaled by the access mode. */
6288 if (GET_CODE (addr
) == PLUS
6289 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
6294 /* Determine if it's legal to put X into the constant pool. */
6297 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
6299 return !arc_legitimate_constant_p (mode
, x
);
6302 /* IDs for all the ARC builtins. */
6306 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6307 ARC_BUILTIN_ ## NAME,
6308 #include "builtins.def"
6314 struct GTY(()) arc_builtin_description
6316 enum insn_code icode
;
6321 static GTY(()) struct arc_builtin_description
6322 arc_bdesc
[ARC_BUILTIN_COUNT
] =
6324 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6325 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6326 #include "builtins.def"
6330 /* Transform UP into lowercase and write the result to LO.
6331 You must provide enough space for LO. Return LO. */
6334 arc_tolower (char *lo
, const char *up
)
6338 for (; *up
; up
++, lo
++)
6339 *lo
= TOLOWER (*up
);
6346 /* Implement `TARGET_BUILTIN_DECL'. */
6349 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6351 if (id
< ARC_BUILTIN_COUNT
)
6352 return arc_bdesc
[id
].fndecl
;
6354 return error_mark_node
;
6358 arc_init_builtins (void)
6360 tree V4HI_type_node
;
6361 tree V2SI_type_node
;
6362 tree V2HI_type_node
;
6364 /* Vector types based on HS SIMD elements. */
6365 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6366 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6367 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6369 tree pcvoid_type_node
6370 = build_pointer_type (build_qualified_type (void_type_node
,
6372 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6375 tree void_ftype_void
6376 = build_function_type_list (void_type_node
, NULL_TREE
);
6378 = build_function_type_list (integer_type_node
, integer_type_node
,
6380 tree int_ftype_pcvoid_int
6381 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6382 integer_type_node
, NULL_TREE
);
6383 tree void_ftype_usint_usint
6384 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6385 long_unsigned_type_node
, NULL_TREE
);
6386 tree int_ftype_int_int
6387 = build_function_type_list (integer_type_node
, integer_type_node
,
6388 integer_type_node
, NULL_TREE
);
6389 tree usint_ftype_usint
6390 = build_function_type_list (long_unsigned_type_node
,
6391 long_unsigned_type_node
, NULL_TREE
);
6392 tree void_ftype_usint
6393 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6396 = build_function_type_list (integer_type_node
, void_type_node
,
6399 = build_function_type_list (void_type_node
, integer_type_node
,
6401 tree int_ftype_short
6402 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6405 /* Old ARC SIMD types. */
6406 tree v8hi_ftype_v8hi_v8hi
6407 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6408 V8HI_type_node
, NULL_TREE
);
6409 tree v8hi_ftype_v8hi_int
6410 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6411 integer_type_node
, NULL_TREE
);
6412 tree v8hi_ftype_v8hi_int_int
6413 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6414 integer_type_node
, integer_type_node
,
6416 tree void_ftype_v8hi_int_int
6417 = build_function_type_list (void_type_node
, V8HI_type_node
,
6418 integer_type_node
, integer_type_node
,
6420 tree void_ftype_v8hi_int_int_int
6421 = build_function_type_list (void_type_node
, V8HI_type_node
,
6422 integer_type_node
, integer_type_node
,
6423 integer_type_node
, NULL_TREE
);
6424 tree v8hi_ftype_int_int
6425 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6426 integer_type_node
, NULL_TREE
);
6427 tree void_ftype_int_int
6428 = build_function_type_list (void_type_node
, integer_type_node
,
6429 integer_type_node
, NULL_TREE
);
6430 tree v8hi_ftype_v8hi
6431 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6433 /* ARCv2 SIMD types. */
6434 tree long_ftype_v4hi_v4hi
6435 = build_function_type_list (long_long_integer_type_node
,
6436 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6437 tree int_ftype_v2hi_v2hi
6438 = build_function_type_list (integer_type_node
,
6439 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6440 tree v2si_ftype_v2hi_v2hi
6441 = build_function_type_list (V2SI_type_node
,
6442 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6443 tree v2hi_ftype_v2hi_v2hi
6444 = build_function_type_list (V2HI_type_node
,
6445 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6446 tree v2si_ftype_v2si_v2si
6447 = build_function_type_list (V2SI_type_node
,
6448 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6449 tree v4hi_ftype_v4hi_v4hi
6450 = build_function_type_list (V4HI_type_node
,
6451 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6452 tree long_ftype_v2si_v2hi
6453 = build_function_type_list (long_long_integer_type_node
,
6454 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6456 /* Add the builtins. */
6457 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6459 int id = ARC_BUILTIN_ ## NAME; \
6460 const char *Name = "__builtin_arc_" #NAME; \
6461 char *name = (char*) alloca (1 + strlen (Name)); \
6463 gcc_assert (id < ARC_BUILTIN_COUNT); \
6465 arc_bdesc[id].fndecl \
6466 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6467 BUILT_IN_MD, NULL, NULL_TREE); \
6469 #include "builtins.def"
6473 /* Helper to expand __builtin_arc_aligned (void* val, int
6477 arc_expand_builtin_aligned (tree exp
)
6479 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6480 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6482 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6483 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6485 if (!CONST_INT_P (op1
))
6487 /* If we can't fold the alignment to a constant integer
6488 whilst optimizing, this is probably a user error. */
6490 warning (0, "__builtin_arc_aligned with non-constant alignment");
6494 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6495 /* Check alignTest is positive, and a power of two. */
6496 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6498 error ("invalid alignment value for __builtin_arc_aligned");
6502 if (CONST_INT_P (op0
))
6504 HOST_WIDE_INT pnt
= INTVAL (op0
);
6506 if ((pnt
& (alignTest
- 1)) == 0)
6511 unsigned align
= get_pointer_alignment (arg0
);
6512 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6514 if (align
&& align
>= numBits
)
6516 /* Another attempt to ascertain alignment. Check the type
6517 we are pointing to. */
6518 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6519 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6524 /* Default to false. */
6528 /* Helper arc_expand_builtin, generates a pattern for the given icode
6532 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6534 switch (insn_data
[icode
].n_generator_args
)
6537 return GEN_FCN (icode
) ();
6539 return GEN_FCN (icode
) (arg
[0]);
6541 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6543 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6545 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6547 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6553 /* Expand an expression EXP that calls a built-in function,
6554 with result going to TARGET if that's convenient
6555 (and in mode MODE if that's convenient).
6556 SUBTARGET may be used as the target for computing one of EXP's operands.
6557 IGNORE is nonzero if the value is to be ignored. */
6560 arc_expand_builtin (tree exp
,
6562 rtx subtarget ATTRIBUTE_UNUSED
,
6563 machine_mode mode ATTRIBUTE_UNUSED
,
6564 int ignore ATTRIBUTE_UNUSED
)
6566 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6567 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6568 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6569 int i
, j
, n_args
= call_expr_nargs (exp
);
6572 enum insn_code icode
= d
->icode
;
6573 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6590 if (id
>= ARC_BUILTIN_COUNT
)
6591 internal_error ("bad builtin fcode");
6593 /* 1st part: Expand special builtins. */
6596 case ARC_BUILTIN_NOP
:
6597 emit_insn (gen_nopv ());
6600 case ARC_BUILTIN_RTIE
:
6601 case ARC_BUILTIN_SYNC
:
6602 case ARC_BUILTIN_BRK
:
6603 case ARC_BUILTIN_SWI
:
6604 case ARC_BUILTIN_UNIMP_S
:
6605 gcc_assert (icode
!= 0);
6606 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6609 case ARC_BUILTIN_ALIGNED
:
6610 return arc_expand_builtin_aligned (exp
);
6612 case ARC_BUILTIN_CLRI
:
6613 target
= gen_reg_rtx (SImode
);
6614 emit_insn (gen_clri (target
, const1_rtx
));
6617 case ARC_BUILTIN_TRAP_S
:
6618 case ARC_BUILTIN_SLEEP
:
6619 arg0
= CALL_EXPR_ARG (exp
, 0);
6621 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6623 gcc_assert (icode
!= 0);
6624 emit_insn (GEN_FCN (icode
) (op0
));
6627 case ARC_BUILTIN_VDORUN
:
6628 case ARC_BUILTIN_VDIRUN
:
6629 arg0
= CALL_EXPR_ARG (exp
, 0);
6630 arg1
= CALL_EXPR_ARG (exp
, 1);
6631 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6632 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6634 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6636 mode0
= insn_data
[icode
].operand
[1].mode
;
6637 mode1
= insn_data
[icode
].operand
[2].mode
;
6639 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6640 op0
= copy_to_mode_reg (mode0
, op0
);
6642 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6643 op1
= copy_to_mode_reg (mode1
, op1
);
6645 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6652 case ARC_BUILTIN_VDIWR
:
6653 case ARC_BUILTIN_VDOWR
:
6654 arg0
= CALL_EXPR_ARG (exp
, 0);
6655 arg1
= CALL_EXPR_ARG (exp
, 1);
6656 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6657 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6659 if (!CONST_INT_P (op0
)
6660 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6661 error ("operand 1 should be an unsigned 3-bit immediate");
6663 mode1
= insn_data
[icode
].operand
[1].mode
;
6665 if (icode
== CODE_FOR_vdiwr_insn
)
6666 target
= gen_rtx_REG (SImode
,
6667 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6668 else if (icode
== CODE_FOR_vdowr_insn
)
6669 target
= gen_rtx_REG (SImode
,
6670 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6674 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6675 op1
= copy_to_mode_reg (mode1
, op1
);
6677 pat
= GEN_FCN (icode
) (target
, op1
);
6684 case ARC_BUILTIN_VASRW
:
6685 case ARC_BUILTIN_VSR8
:
6686 case ARC_BUILTIN_VSR8AW
:
6687 arg0
= CALL_EXPR_ARG (exp
, 0);
6688 arg1
= CALL_EXPR_ARG (exp
, 1);
6689 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6690 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6691 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6693 target
= gen_reg_rtx (V8HImode
);
6694 mode0
= insn_data
[icode
].operand
[1].mode
;
6695 mode1
= insn_data
[icode
].operand
[2].mode
;
6697 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6698 op0
= copy_to_mode_reg (mode0
, op0
);
6700 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6701 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6702 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6704 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6711 case ARC_BUILTIN_VLD32WH
:
6712 case ARC_BUILTIN_VLD32WL
:
6713 case ARC_BUILTIN_VLD64
:
6714 case ARC_BUILTIN_VLD32
:
6717 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6718 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6719 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6721 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6722 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6723 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6724 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6726 /* target <- src vreg. */
6727 emit_insn (gen_move_insn (target
, src_vreg
));
6729 /* target <- vec_concat: target, mem (Ib, u8). */
6730 mode0
= insn_data
[icode
].operand
[3].mode
;
6731 mode1
= insn_data
[icode
].operand
[1].mode
;
6733 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6734 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6735 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6737 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6738 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6739 error ("operand 2 should be an unsigned 8-bit value");
6741 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6748 case ARC_BUILTIN_VLD64W
:
6749 case ARC_BUILTIN_VLD128
:
6750 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6751 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6753 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6754 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6755 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6757 /* target <- src vreg. */
6758 target
= gen_reg_rtx (V8HImode
);
6760 /* target <- vec_concat: target, mem (Ib, u8). */
6761 mode0
= insn_data
[icode
].operand
[1].mode
;
6762 mode1
= insn_data
[icode
].operand
[2].mode
;
6763 mode2
= insn_data
[icode
].operand
[3].mode
;
6765 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6766 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6767 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6769 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6770 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6771 error ("operand 2 should be an unsigned 8-bit value");
6773 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6781 case ARC_BUILTIN_VST128
:
6782 case ARC_BUILTIN_VST64
:
6783 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6784 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6785 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6787 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6788 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6789 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6790 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6792 mode0
= insn_data
[icode
].operand
[0].mode
;
6793 mode1
= insn_data
[icode
].operand
[1].mode
;
6794 mode2
= insn_data
[icode
].operand
[2].mode
;
6795 mode3
= insn_data
[icode
].operand
[3].mode
;
6797 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6798 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6799 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6801 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6802 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6803 error ("operand 3 should be an unsigned 8-bit value");
6805 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6806 op3
= copy_to_mode_reg (mode3
, op3
);
6808 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6815 case ARC_BUILTIN_VST16_N
:
6816 case ARC_BUILTIN_VST32_N
:
6817 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6818 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6819 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6820 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6822 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6823 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6824 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6825 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6826 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6828 mode0
= insn_data
[icode
].operand
[0].mode
;
6829 mode2
= insn_data
[icode
].operand
[2].mode
;
6830 mode3
= insn_data
[icode
].operand
[3].mode
;
6831 mode4
= insn_data
[icode
].operand
[4].mode
;
6833 /* Do some correctness checks for the operands. */
6834 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6835 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6836 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6838 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6839 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6840 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6842 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6843 op3
= copy_to_mode_reg (mode3
, op3
);
6845 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6846 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6847 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6848 else if (icode
== CODE_FOR_vst32_n_insn
6849 && ((INTVAL (op4
) % 2) != 0))
6850 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6852 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6863 /* 2nd part: Expand regular builtins. */
6865 internal_error ("bad builtin fcode");
6867 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6872 if (target
== NULL_RTX
6873 || GET_MODE (target
) != tmode
6874 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6876 target
= gen_reg_rtx (tmode
);
6881 gcc_assert (n_args
<= 4);
6882 for (i
= 0; i
< n_args
; i
++, j
++)
6884 tree arg
= CALL_EXPR_ARG (exp
, i
);
6885 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6886 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6887 machine_mode opmode
= GET_MODE (op
);
6888 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6890 /* SIMD extension requires exact immediate operand match. */
6891 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6892 && (id
< ARC_BUILTIN_SIMD_END
)
6896 if (!CONST_INT_P (op
))
6897 error ("builtin requires an immediate for operand %d", j
);
6901 if (!satisfies_constraint_L (op
))
6902 error ("operand %d should be a 6 bit unsigned immediate", j
);
6905 if (!satisfies_constraint_P (op
))
6906 error ("operand %d should be a 8 bit unsigned immediate", j
);
6909 if (!satisfies_constraint_K (op
))
6910 error ("operand %d should be a 3 bit unsigned immediate", j
);
6913 error ("unknown builtin immediate operand type for operand %d",
6918 if (CONST_INT_P (op
))
6921 if ((opmode
== SImode
) && (mode
== HImode
))
6924 op
= gen_lowpart (HImode
, op
);
6927 /* In case the insn wants input operands in modes different from
6928 the result, abort. */
6929 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6931 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6932 op
= copy_to_mode_reg (mode
, op
);
6937 pat
= apply_GEN_FCN (icode
, xop
);
6938 if (pat
== NULL_RTX
)
6949 /* Returns true if the operands[opno] is a valid compile-time constant to be
6950 used as register number in the code for builtins. Else it flags an error
6951 and returns false. */
6954 check_if_valid_regno_const (rtx
*operands
, int opno
)
6957 switch (GET_CODE (operands
[opno
]))
6964 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6970 /* Return true if it is ok to make a tail-call to DECL. */
6973 arc_function_ok_for_sibcall (tree decl
,
6974 tree exp ATTRIBUTE_UNUSED
)
6976 tree attrs
= NULL_TREE
;
6978 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6979 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6984 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
6986 if (lookup_attribute ("jli_always", attrs
))
6988 if (lookup_attribute ("jli_fixed", attrs
))
6990 if (lookup_attribute ("secure_call", attrs
))
6994 /* Everything else is ok. */
6998 /* Output code to add DELTA to the first argument, and then jump
6999 to FUNCTION. Used for C++ multiple inheritance. */
7002 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7003 HOST_WIDE_INT delta
,
7004 HOST_WIDE_INT vcall_offset
,
7007 int mi_delta
= delta
;
7008 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
7011 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
7015 mi_delta
= - mi_delta
;
7017 /* Add DELTA. When possible use a plain add, otherwise load it into
7018 a register first. */
7020 while (mi_delta
!= 0)
7022 if ((mi_delta
& (3 << shift
)) == 0)
7026 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
7027 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
7028 mi_delta
& (0xff << shift
));
7029 mi_delta
&= ~(0xff << shift
);
7034 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7035 if (vcall_offset
!= 0)
7037 /* ld r12,[this] --> temp = *this
7038 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7040 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7041 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7042 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
7043 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
7044 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
7045 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7046 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
7047 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
7048 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
7051 fnaddr
= XEXP (DECL_RTL (function
), 0);
7053 if (arc_is_longcall_p (fnaddr
))
7057 asm_fprintf (file
, "\tld\t%s, [pcl, @",
7058 ARC_TEMP_SCRATCH_REG
);
7059 assemble_name (file
, XSTR (fnaddr
, 0));
7060 fputs ("@gotpc]\n", file
);
7061 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
7065 fputs ("\tj\t@", file
);
7066 assemble_name (file
, XSTR (fnaddr
, 0));
7071 fputs ("\tb\t@", file
);
7072 assemble_name (file
, XSTR (fnaddr
, 0));
7074 fputs ("@plt\n", file
);
7079 /* Return true if a 32 bit "long_call" should be generated for
7080 this calling SYM_REF. We generate a long_call if the function:
7082 a. has an __attribute__((long call))
7083 or b. the -mlong-calls command line switch has been specified
7085 However we do not generate a long call if the function has an
7086 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7088 This function will be called by C fragments contained in the machine
7089 description file. */
7092 arc_is_longcall_p (rtx sym_ref
)
7094 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7097 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
7098 || (TARGET_LONG_CALLS_SET
7099 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7100 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7104 /* Likewise for short calls. */
7107 arc_is_shortcall_p (rtx sym_ref
)
7109 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7112 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7113 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
7114 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
7115 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7119 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7122 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7124 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
7128 HOST_WIDE_INT size
= int_size_in_bytes (type
);
7129 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
7134 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
7135 machine_mode mode ATTRIBUTE_UNUSED
,
7137 bool named ATTRIBUTE_UNUSED
)
7140 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
7141 || TREE_ADDRESSABLE (type
)));
7144 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7147 arc_can_use_doloop_p (const widest_int
&,
7148 const widest_int
&iterations_max
,
7149 unsigned int loop_depth
, bool entered_at_top
)
7151 /* Considering limitations in the hardware, only use doloop
7152 for innermost loops which must be entered from the top. */
7153 if (loop_depth
> 1 || !entered_at_top
)
7156 /* Check for lp_count width boundary. */
7157 if (arc_lpcwidth
!= 32
7158 && (wi::gtu_p (iterations_max
, ((1 << arc_lpcwidth
) - 1))
7159 || wi::eq_p (iterations_max
, 0)))
7164 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7165 return why doloop cannot be applied. */
7168 arc_invalid_within_doloop (const rtx_insn
*insn
)
7171 return "Function call in the loop.";
7173 /* FIXME! add here all the ZOL exceptions. */
7177 /* Return true if a load instruction (CONSUMER) uses the same address as a
7178 store instruction (PRODUCER). This function is used to avoid st/ld
7179 address hazard in ARC700 cores. */
7181 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7183 rtx in_set
, out_set
;
7184 rtx out_addr
, in_addr
;
7192 /* Peel the producer and the consumer for the address. */
7193 out_set
= single_set (producer
);
7196 out_addr
= SET_DEST (out_set
);
7199 if (GET_CODE (out_addr
) == ZERO_EXTEND
7200 || GET_CODE (out_addr
) == SIGN_EXTEND
)
7201 out_addr
= XEXP (out_addr
, 0);
7203 if (!MEM_P (out_addr
))
7206 in_set
= single_set (consumer
);
7209 in_addr
= SET_SRC (in_set
);
7212 if (GET_CODE (in_addr
) == ZERO_EXTEND
7213 || GET_CODE (in_addr
) == SIGN_EXTEND
)
7214 in_addr
= XEXP (in_addr
, 0);
7216 if (!MEM_P (in_addr
))
7218 /* Get rid of the MEM and check if the addresses are
7220 in_addr
= XEXP (in_addr
, 0);
7221 out_addr
= XEXP (out_addr
, 0);
7223 return exp_equiv_p (in_addr
, out_addr
, 0, true);
7229 /* The same functionality as arc_hazard. It is called in machine
7230 reorg before any other optimization. Hence, the NOP size is taken
7231 into account when doing branch shortening. */
7234 workaround_arc_anomaly (void)
7236 rtx_insn
*insn
, *succ0
;
7238 /* For any architecture: call arc_hazard here. */
7239 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7241 succ0
= next_real_insn (insn
);
7242 if (arc_hazard (insn
, succ0
))
7244 emit_insn_before (gen_nopv (), succ0
);
7252 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7254 succ0
= next_real_insn (insn
);
7255 if (arc_store_addr_hazard_p (insn
, succ0
))
7257 emit_insn_after (gen_nopv (), insn
);
7258 emit_insn_after (gen_nopv (), insn
);
7262 /* Avoid adding nops if the instruction between the ST and LD is
7264 succ1
= next_real_insn (succ0
);
7265 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
7266 && arc_store_addr_hazard_p (insn
, succ1
))
7267 emit_insn_after (gen_nopv (), insn
);
7272 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7273 turns out not to be optimizable; we have to split the loop_end pattern into
7274 a subtract and a test. */
7277 hwloop_fail (hwloop_info loop
)
7280 rtx insn
= loop
->loop_end
;
7283 && (loop
->length
&& (loop
->length
<= ARC_MAX_LOOP_LENGTH
))
7284 && REG_P (loop
->iter_reg
))
7286 /* TARGET_V2 core3 has dbnz instructions. */
7287 test
= gen_dbnz (loop
->iter_reg
, loop
->start_label
);
7288 insn
= emit_jump_insn_before (test
, loop
->loop_end
);
7290 else if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
) == LP_COUNT
))
7292 /* We have the lp_count as loop iterator, try to use it. */
7293 emit_insn_before (gen_loop_fail (), loop
->loop_end
);
7294 test
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CC_ZNmode
, CC_REG
),
7296 test
= gen_rtx_IF_THEN_ELSE (VOIDmode
, test
,
7297 gen_rtx_LABEL_REF (Pmode
, loop
->start_label
),
7299 insn
= emit_jump_insn_before (gen_rtx_SET (pc_rtx
, test
),
7304 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
7308 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
7309 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
7315 JUMP_LABEL (insn
) = loop
->start_label
;
7316 LABEL_NUSES (loop
->start_label
)++;
7317 delete_insn (loop
->loop_end
);
7320 /* Optimize LOOP. */
7323 hwloop_optimize (hwloop_info loop
)
7327 basic_block entry_bb
, bb
;
7329 rtx_insn
*insn
, *seq
, *entry_after
, *last_insn
, *end_label
;
7330 unsigned int length
;
7331 bool need_fix
= false;
7332 rtx lp_reg
= gen_rtx_REG (SImode
, LP_COUNT
);
7334 if (loop
->depth
> 1)
7337 fprintf (dump_file
, ";; loop %d is not innermost\n",
7342 if (!loop
->incoming_dest
)
7345 fprintf (dump_file
, ";; loop %d has more than one entry\n",
7350 if (loop
->incoming_dest
!= loop
->head
)
7353 fprintf (dump_file
, ";; loop %d is not entered from head\n",
7358 if (loop
->has_call
|| loop
->has_asm
)
7361 fprintf (dump_file
, ";; loop %d has invalid insn\n",
7366 /* Scan all the blocks to make sure they don't use iter_reg. */
7367 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
7370 fprintf (dump_file
, ";; loop %d uses iterator\n",
7375 /* Check if start_label appears before doloop_end. */
7377 for (insn
= loop
->start_label
;
7378 insn
&& insn
!= loop
->loop_end
;
7379 insn
= NEXT_INSN (insn
))
7380 length
+= NONDEBUG_INSN_P (insn
) ? get_attr_length (insn
) : 0;
7385 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
7390 loop
->length
= length
;
7391 if (loop
->length
> ARC_MAX_LOOP_LENGTH
)
7394 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7397 else if (!loop
->length
)
7400 fprintf (dump_file
, ";; loop %d is empty\n", loop
->loop_no
);
7404 /* Check if we use a register or not. */
7405 if (!REG_P (loop
->iter_reg
))
7408 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7413 /* Check if loop register is lpcount. */
7414 if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
)) != LP_COUNT
)
7417 fprintf (dump_file
, ";; loop %d doesn't use lp_count as loop"
7420 /* This loop doesn't use the lp_count, check though if we can
7422 if (TEST_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
)
7423 /* In very unique cases we may have LP_COUNT alive. */
7424 || (loop
->incoming_src
7425 && REGNO_REG_SET_P (df_get_live_out (loop
->incoming_src
),
7432 /* Check for control like instruction as the last instruction of a
7435 last_insn
= PREV_INSN (loop
->loop_end
);
7439 for (; last_insn
!= BB_HEAD (bb
);
7440 last_insn
= PREV_INSN (last_insn
))
7441 if (NONDEBUG_INSN_P (last_insn
))
7444 if (last_insn
!= BB_HEAD (bb
))
7447 if (single_pred_p (bb
)
7448 && single_pred_edge (bb
)->flags
& EDGE_FALLTHRU
7449 && single_pred (bb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
))
7451 bb
= single_pred (bb
);
7452 last_insn
= BB_END (bb
);
7465 fprintf (dump_file
, ";; loop %d has no last instruction\n",
7470 if ((TARGET_ARC600_FAMILY
|| TARGET_HS
)
7471 && INSN_P (last_insn
)
7472 && (JUMP_P (last_insn
) || CALL_P (last_insn
)
7473 || GET_CODE (PATTERN (last_insn
)) == SEQUENCE
7474 /* At this stage we can have (insn (clobber (mem:BLK
7475 (reg)))) instructions, ignore them. */
7476 || (GET_CODE (PATTERN (last_insn
)) != CLOBBER
7477 && (get_attr_type (last_insn
) == TYPE_BRCC
7478 || get_attr_type (last_insn
) == TYPE_BRCC_NO_DELAY_SLOT
))))
7480 if (loop
->length
+ 2 > ARC_MAX_LOOP_LENGTH
)
7483 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7487 fprintf (dump_file
, ";; loop %d has a control like last insn;"
7491 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7494 if (LABEL_P (last_insn
))
7497 fprintf (dump_file
, ";; loop %d has a label as last insn;"
7500 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7503 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7504 and we can use it to indicate the last ZOL instruction cannot be
7505 part of a delay slot. */
7506 add_reg_note (last_insn
, REG_SAVE_NOTE
, GEN_INT (2));
7508 loop
->last_insn
= last_insn
;
7510 /* Get the loop iteration register. */
7511 iter_reg
= loop
->iter_reg
;
7513 gcc_assert (REG_P (iter_reg
));
7517 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
7518 if (entry_edge
->flags
& EDGE_FALLTHRU
)
7521 if (entry_edge
== NULL
)
7524 fprintf (dump_file
, ";; loop %d has no fallthru edge jumping"
7529 /* The loop is good. */
7530 end_label
= gen_label_rtx ();
7531 loop
->end_label
= end_label
;
7533 /* Place the zero_cost_loop_start instruction before the loop. */
7534 entry_bb
= entry_edge
->src
;
7540 /* The loop uses a R-register, but the lp_count is free, thus
7542 emit_insn (gen_movsi (lp_reg
, iter_reg
));
7543 SET_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
);
7547 fprintf (dump_file
, ";; fix loop %d to use lp_count\n",
7552 insn
= emit_insn (gen_arc_lp (iter_reg
,
7559 entry_after
= BB_END (entry_bb
);
7560 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
7567 emit_insn_before (seq
, BB_HEAD (loop
->head
));
7568 seq
= emit_label_before (gen_label_rtx (), seq
);
7569 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
7570 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
7572 if (!(e
->flags
& EDGE_FALLTHRU
))
7573 redirect_edge_and_branch_force (e
, new_bb
);
7575 redirect_edge_succ (e
, new_bb
);
7578 make_edge (new_bb
, loop
->head
, 0);
7583 while (DEBUG_INSN_P (entry_after
)
7584 || (NOTE_P (entry_after
)
7585 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
))
7586 entry_after
= NEXT_INSN (entry_after
);
7588 entry_after
= next_nonnote_nondebug_insn_bb (entry_after
);
7590 gcc_assert (entry_after
);
7591 emit_insn_before (seq
, entry_after
);
7594 delete_insn (loop
->loop_end
);
7595 /* Insert the loop end label before the last instruction of the
7597 emit_label_after (end_label
, loop
->last_insn
);
7598 /* Make sure we mark the begining and end label as used. */
7599 LABEL_NUSES (loop
->end_label
)++;
7600 LABEL_NUSES (loop
->start_label
)++;
7605 /* A callback for the hw-doloop pass. This function examines INSN; if
7606 it is a loop_end pattern we recognize, return the reg rtx for the
7607 loop counter. Otherwise, return NULL_RTX. */
7610 hwloop_pattern_reg (rtx_insn
*insn
)
7614 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
7617 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
7623 static struct hw_doloop_hooks arc_doloop_hooks
=
7630 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
7631 and tries to rewrite the RTL of these loops so that proper Blackfin
7632 hardware loops are generated. */
7635 arc_reorg_loops (void)
7637 reorg_loops (true, &arc_doloop_hooks
);
7640 /* Scan all calls and add symbols to be emitted in the jli section if
7644 jli_call_scan (void)
7648 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7653 rtx pat
= PATTERN (insn
);
7654 if (GET_CODE (pat
) == COND_EXEC
)
7655 pat
= COND_EXEC_CODE (pat
);
7656 pat
= XVECEXP (pat
, 0, 0);
7657 if (GET_CODE (pat
) == SET
)
7658 pat
= SET_SRC (pat
);
7660 pat
= XEXP (XEXP (pat
, 0), 0);
7661 if (GET_CODE (pat
) == SYMBOL_REF
7662 && arc_is_jli_call_p (pat
))
7663 arc_add_jli_section (pat
);
7667 /* Add padding if necessary to avoid a mispredict. A return could
7668 happen immediately after the function start. A call/return and
7669 return/return must be 6 bytes apart to avoid mispredict. */
7677 if (!TARGET_PAD_RETURN
)
7680 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7682 rtx_insn
*prev0
= prev_active_insn (insn
);
7683 bool wantlong
= false;
7685 if (!INSN_P (insn
) || GET_CODE (PATTERN (insn
)) != SIMPLE_RETURN
)
7690 prev0
= emit_insn_before (gen_nopv (), insn
);
7691 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
7692 so it is safe to reuse it for forcing a particular length
7693 for an instruction. */
7694 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
7695 emit_insn_before (gen_nopv (), insn
);
7698 offset
= get_attr_length (prev0
);
7700 if (get_attr_length (prev0
) == 2
7701 && get_attr_iscompact (prev0
) != ISCOMPACT_TRUE
)
7703 /* Force long version of the insn. */
7708 rtx_insn
*prev
= prev_active_insn (prev0
);
7710 offset
+= get_attr_length (prev
);
7712 prev
= prev_active_insn (prev
);
7714 offset
+= get_attr_length (prev
);
7719 prev
= emit_insn_before (gen_nopv (), insn
);
7720 add_reg_note (prev
, REG_SAVE_NOTE
, GEN_INT (1));
7723 emit_insn_before (gen_nopv (), insn
);
7730 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
7732 /* Emit a blockage to avoid delay slot scheduling. */
7733 emit_insn_before (gen_blockage (), insn
);
7737 static int arc_reorg_in_progress
= 0;
7739 /* ARC's machince specific reorg function. */
7750 cfun
->machine
->arc_reorg_started
= 1;
7751 arc_reorg_in_progress
= 1;
7753 compute_bb_for_insn ();
7757 /* Doloop optimization. */
7760 workaround_arc_anomaly ();
7764 /* FIXME: should anticipate ccfsm action, generate special patterns for
7765 to-be-deleted branches that have no delay slot and have at least the
7766 length of the size increase forced on other insns that are conditionalized.
7767 This can also have an insn_list inside that enumerates insns which are
7768 not actually conditionalized because the destinations are dead in the
7770 Could also tag branches that we want to be unaligned if they get no delay
7771 slot, or even ones that we don't want to do delay slot sheduling for
7772 because we can unalign them.
7774 However, there are cases when conditional execution is only possible after
7775 delay slot scheduling:
7777 - If a delay slot is filled with a nocond/set insn from above, the previous
7778 basic block can become elegible for conditional execution.
7779 - If a delay slot is filled with a nocond insn from the fall-through path,
7780 the branch with that delay slot can become eligble for conditional
7781 execution (however, with the same sort of data flow analysis that dbr
7782 does, we could have figured out before that we don't need to
7783 conditionalize this insn.)
7784 - If a delay slot insn is filled with an insn from the target, the
7785 target label gets its uses decremented (even deleted if falling to zero),
7786 thus possibly creating more condexec opportunities there.
7787 Therefore, we should still be prepared to apply condexec optimization on
7788 non-prepared branches if the size increase of conditionalized insns is no
7789 more than the size saved from eliminating the branch. An invocation option
7790 could also be used to reserve a bit of extra size for condbranches so that
7791 this'll work more often (could also test in arc_reorg if the block is
7792 'close enough' to be eligible for condexec to make this likely, and
7793 estimate required size increase). */
7794 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7795 if (TARGET_NO_BRCC_SET
)
7800 init_insn_lengths();
7803 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
7806 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
7807 df_finish_pass ((flags
& TODO_df_verify
) != 0);
7811 fprintf (dump_file
, ";; After if conversion:\n\n");
7812 print_rtl (dump_file
, get_insns ());
7816 /* Call shorten_branches to calculate the insn lengths. */
7817 shorten_branches (get_insns());
7818 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
7820 if (!INSN_ADDRESSES_SET_P())
7821 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
7823 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7826 enum attr_type insn_type
;
7828 /* If a non-jump insn (or a casesi jump table), continue. */
7829 if (GET_CODE (insn
) != JUMP_INSN
||
7830 GET_CODE (PATTERN (insn
)) == ADDR_VEC
7831 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
7834 /* If we already have a brcc, note if it is suitable for brcc_s.
7835 Be a bit generous with the brcc_s range so that we can take
7836 advantage of any code shortening from delay slot scheduling. */
7837 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
7839 rtx pat
= PATTERN (insn
);
7840 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
7841 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
7843 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7844 if ((offset
>= -140 && offset
< 140)
7845 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
7846 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
7847 && equality_comparison_operator (op
, VOIDmode
))
7848 PUT_MODE (*ccp
, CC_Zmode
);
7849 else if (GET_MODE (*ccp
) == CC_Zmode
)
7850 PUT_MODE (*ccp
, CC_ZNmode
);
7853 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
7854 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
7857 /* OK. so we have a jump insn. */
7858 /* We need to check that it is a bcc. */
7859 /* Bcc => set (pc) (if_then_else ) */
7860 pattern
= PATTERN (insn
);
7861 if (GET_CODE (pattern
) != SET
7862 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
7863 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
7866 /* Now check if the jump is beyond the s9 range. */
7867 if (CROSSING_JUMP_P (insn
))
7869 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7871 if(offset
> 253 || offset
< -254)
7874 pc_target
= SET_SRC (pattern
);
7876 /* Avoid FPU instructions. */
7877 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
7878 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
7881 /* Now go back and search for the set cc insn. */
7883 label
= XEXP (pc_target
, 1);
7887 rtx_insn
*scan
, *link_insn
= NULL
;
7889 for (scan
= PREV_INSN (insn
);
7890 scan
&& GET_CODE (scan
) != CODE_LABEL
;
7891 scan
= PREV_INSN (scan
))
7893 if (! INSN_P (scan
))
7895 pat
= PATTERN (scan
);
7896 if (GET_CODE (pat
) == SET
7897 && cc_register (SET_DEST (pat
), VOIDmode
))
7906 /* Check if this is a data dependency. */
7908 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
7911 /* Ok this is the set cc. copy args here. */
7912 op
= XEXP (pc_target
, 0);
7914 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
7915 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
7916 if (GET_CODE (op0
) == ZERO_EXTRACT
7917 && XEXP (op0
, 1) == const1_rtx
7918 && (GET_CODE (op
) == EQ
7919 || GET_CODE (op
) == NE
))
7921 /* btst / b{eq,ne} -> bbit{0,1} */
7922 op0
= XEXP (cmp0
, 0);
7923 op1
= XEXP (cmp0
, 2);
7925 else if (!register_operand (op0
, VOIDmode
)
7926 || !general_operand (op1
, VOIDmode
))
7928 /* Be careful not to break what cmpsfpx_raw is
7929 trying to create for checking equality of
7930 single-precision floats. */
7931 else if (TARGET_SPFP
7932 && GET_MODE (op0
) == SFmode
7933 && GET_MODE (op1
) == SFmode
)
7936 /* None of the two cmp operands should be set between the
7937 cmp and the branch. */
7938 if (reg_set_between_p (op0
, link_insn
, insn
))
7941 if (reg_set_between_p (op1
, link_insn
, insn
))
7944 /* Since the MODE check does not work, check that this is
7945 CC reg's last set location before insn, and also no
7946 instruction between the cmp and branch uses the
7948 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
7949 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
7952 /* CC reg should be dead after insn. */
7953 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
7956 op
= gen_rtx_fmt_ee (GET_CODE (op
),
7957 GET_MODE (op
), cmp0
, cmp1
);
7958 /* If we create a LIMM where there was none before,
7959 we only benefit if we can avoid a scheduling bubble
7960 for the ARC600. Otherwise, we'd only forgo chances
7961 at short insn generation, and risk out-of-range
7963 if (!brcc_nolimm_operator (op
, VOIDmode
)
7964 && !long_immediate_operand (op1
, VOIDmode
)
7966 || next_active_insn (link_insn
) != insn
))
7969 /* Emit bbit / brcc (or brcc_s if possible).
7970 CC_Zmode indicates that brcc_s is possible. */
7973 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
7974 else if ((offset
>= -140 && offset
< 140)
7975 && rtx_equal_p (op1
, const0_rtx
)
7976 && compact_register_operand (op0
, VOIDmode
)
7977 && (GET_CODE (op
) == EQ
7978 || GET_CODE (op
) == NE
))
7979 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
7981 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
7984 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
7985 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
7986 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
7989 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
7990 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
7992 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
7993 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
7996 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7997 REG_NOTES (brcc_insn
) = note
;
7999 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
8002 remove_note (link_insn
, note
);
8003 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8004 REG_NOTES (brcc_insn
) = note
;
8006 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
8009 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8010 REG_NOTES (brcc_insn
) = note
;
8015 /* Delete the bcc insn. */
8016 set_insn_deleted (insn
);
8018 /* Delete the cmp insn. */
8019 set_insn_deleted (link_insn
);
8024 /* Clear out insn_addresses. */
8025 INSN_ADDRESSES_FREE ();
8029 if (INSN_ADDRESSES_SET_P())
8030 fatal_error (input_location
, "insn addresses not freed");
8032 arc_reorg_in_progress
= 0;
8035 /* Check if the operands are valid for BRcc.d generation
8036 Valid Brcc.d patterns are
8040 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
8041 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8042 does not have a delay slot
8044 Assumed precondition: Second operand is either a register or a u6 value. */
8047 valid_brcc_with_delay_p (rtx
*operands
)
8049 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
8051 return brcc_nolimm_operator (operands
[0], VOIDmode
);
8054 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8055 access DECL using %gp_rel(...)($gp). */
8058 arc_in_small_data_p (const_tree decl
)
8063 /* Only variables are going into small data area. */
8064 if (TREE_CODE (decl
) != VAR_DECL
)
8067 if (TARGET_NO_SDATA_SET
)
8070 /* Disable sdata references to weak variables. */
8071 if (DECL_WEAK (decl
))
8074 /* Don't put constants into the small data section: we want them to
8075 be in ROM rather than RAM. */
8076 if (TREE_READONLY (decl
))
8079 /* To ensure -mvolatile-cache works ld.di does not have a
8080 gp-relative variant. */
8081 if (!TARGET_VOLATILE_CACHE_SET
8082 && TREE_THIS_VOLATILE (decl
))
8085 /* Likewise for uncached data. */
8086 attr
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
8087 if (lookup_attribute ("uncached", attr
))
8090 /* and for aux regs. */
8091 attr
= DECL_ATTRIBUTES (decl
);
8092 if (lookup_attribute ("aux", attr
))
8095 if (DECL_SECTION_NAME (decl
) != 0)
8097 const char *name
= DECL_SECTION_NAME (decl
);
8098 if (strcmp (name
, ".sdata") == 0
8099 || strcmp (name
, ".sbss") == 0)
8102 /* If it's not public, there's no need to put it in the small data
8104 else if (TREE_PUBLIC (decl
))
8106 size
= int_size_in_bytes (TREE_TYPE (decl
));
8107 return (size
> 0 && size
<= g_switch_value
);
8112 /* Return true if OP is an acceptable memory operand for ARCompact
8113 16-bit gp-relative load instructions.
8115 /* volatile cache option still to be handled. */
8118 compact_sda_memory_operand (rtx op
, machine_mode mode
, bool short_p
)
8125 /* Eliminate non-memory operations. */
8126 if (GET_CODE (op
) != MEM
)
8129 if (mode
== VOIDmode
)
8130 mode
= GET_MODE (op
);
8132 size
= GET_MODE_SIZE (mode
);
8134 /* dword operations really put out 2 instructions, so eliminate them. */
8135 if (size
> UNITS_PER_WORD
)
8138 /* Decode the address now. */
8139 addr
= XEXP (op
, 0);
8141 if (!legitimate_small_data_address_p (addr
))
8144 if (!short_p
|| size
== 1)
8147 /* Now check for the alignment, the short loads using gp require the
8148 addresses to be aligned. */
8149 align
= get_symbol_alignment (addr
);
8160 if (align
&& ((align
& mask
) == 0))
8165 /* Return TRUE if PAT is accessing an aux-reg. */
8168 arc_is_aux_reg_p (rtx pat
)
8170 tree attrs
= NULL_TREE
;
8176 /* Get the memory attributes. */
8177 addr
= MEM_EXPR (pat
);
8181 /* Get the attributes. */
8182 if (TREE_CODE (addr
) == VAR_DECL
)
8183 attrs
= DECL_ATTRIBUTES (addr
);
8184 else if (TREE_CODE (addr
) == MEM_REF
)
8185 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
8189 if (lookup_attribute ("aux", attrs
))
8194 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8197 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
8198 unsigned HOST_WIDE_INT size
,
8199 unsigned HOST_WIDE_INT align
,
8200 unsigned HOST_WIDE_INT globalize_p
)
8202 int in_small_data
= arc_in_small_data_p (decl
);
8203 rtx mem
= decl
== NULL_TREE
? NULL_RTX
: DECL_RTL (decl
);
8205 /* Don't output aux-reg symbols. */
8206 if (mem
!= NULL_RTX
&& MEM_P (mem
)
8207 && SYMBOL_REF_P (XEXP (mem
, 0))
8208 && arc_is_aux_reg_p (mem
))
8212 switch_to_section (get_named_section (NULL
, ".sbss", 0));
8213 /* named_section (0,".sbss",0); */
8215 switch_to_section (bss_section
);
8218 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
8220 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
8221 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
8222 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
8223 ASM_OUTPUT_LABEL (stream
, name
);
8226 ASM_OUTPUT_SKIP (stream
, size
);
8230 arc_preserve_reload_p (rtx in
)
8232 return (GET_CODE (in
) == PLUS
8233 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
8234 && CONST_INT_P (XEXP (in
, 1))
8235 && !((INTVAL (XEXP (in
, 1)) & 511)));
8239 arc_register_move_cost (machine_mode
,
8240 enum reg_class from_class
, enum reg_class to_class
)
8242 /* The ARC600 has no bypass for extension registers, hence a nop might be
8243 needed to be inserted after a write so that reads are safe. */
8246 if (to_class
== MPY_WRITABLE_CORE_REGS
)
8248 /* Instructions modifying LP_COUNT need 4 additional cycles before
8249 the register will actually contain the value. */
8250 else if (to_class
== LPCOUNT_REG
)
8252 else if (to_class
== WRITABLE_CORE_REGS
)
8256 /* Using lp_count as scratch reg is a VERY bad idea. */
8257 if (from_class
== LPCOUNT_REG
)
8259 if (to_class
== LPCOUNT_REG
)
8262 /* Force an attempt to 'mov Dy,Dx' to spill. */
8263 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
8264 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
8270 /* Emit code for an addsi3 instruction with OPERANDS.
8271 COND_P indicates if this will use conditional execution.
8272 Return the length of the instruction.
8273 If OUTPUT_P is false, don't actually output the instruction, just return
8276 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
8280 int match
= operands_match_p (operands
[0], operands
[1]);
8281 int match2
= operands_match_p (operands
[0], operands
[2]);
8282 int intval
= (REG_P (operands
[2]) ? 1
8283 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
8284 int neg_intval
= -intval
;
8285 int short_0
= satisfies_constraint_Rcq (operands
[0]);
8286 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
8289 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8290 && REGNO (OP) != 30) \
8293 #define ADDSI_OUTPUT1(FORMAT) do {\
8295 output_asm_insn (FORMAT, operands);\
8298 #define ADDSI_OUTPUT(LIST) do {\
8301 ADDSI_OUTPUT1 (format);\
8305 /* First try to emit a 16 bit insn. */
8308 /* If we are actually about to output this insn, don't try a 16 bit
8309 variant if we already decided that we don't want that
8310 (I.e. we upsized this insn to align some following insn.)
8311 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8312 but add1 r0,sp,35 doesn't. */
8313 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
8315 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8318 && ((REG_H_P (operands
[2])
8319 && (match
|| satisfies_constraint_Rcq (operands
[2])))
8320 || (CONST_INT_P (operands
[2])
8321 && ((unsigned) intval
<= (match
? 127 : 7)))))
8322 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8324 /* Generate add_s b,b,h patterns. */
8325 if (short_0
&& match2
&& REG_H_P (operands
[1]))
8326 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8328 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8329 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
8330 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
8331 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8333 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
8334 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
8335 && match
&& !(neg_intval
& ~124)))
8336 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8338 /* Generate add_s h,h,s3 patterns. */
8339 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
8340 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
8341 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8343 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8344 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
8345 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
8346 && satisfies_constraint_Rcq (operands
[1])
8347 && satisfies_constraint_L (operands
[2]))
8348 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8351 /* Now try to emit a 32 bit insn without long immediate. */
8353 if (!match
&& match2
&& REG_P (operands
[1]))
8354 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8355 if (match
|| !cond_p
)
8357 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
8358 int range_factor
= neg_intval
& intval
;
8361 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
8362 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8364 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8365 same size, do, so - the insn latency is lower. */
8366 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8368 if ((intval
>= 0 && intval
<= limit
)
8369 || (intval
== -0x800 && limit
== 0x7ff))
8370 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8371 else if ((intval
< 0 && neg_intval
<= limit
)
8372 || (intval
== 0x800 && limit
== 0x7ff))
8373 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8374 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
8375 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
8376 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
8377 if (((intval
< 0 && intval
!= -0x4000)
8378 /* sub[123] is slower than add_s / sub, only use it if it
8379 avoids a long immediate. */
8380 && neg_intval
<= limit
<< shift
)
8381 || (intval
== 0x4000 && limit
== 0x7ff))
8382 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
8383 shift
, neg_intval
>> shift
));
8384 else if ((intval
>= 0 && intval
<= limit
<< shift
)
8385 || (intval
== -0x4000 && limit
== 0x7ff))
8386 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
8388 /* Try to emit a 16 bit opcode with long immediate. */
8390 if (short_p
&& match
)
8391 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8393 /* We have to use a 32 bit opcode, and with a long immediate. */
8395 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8398 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8399 Return the length of the instruction.
8400 If OUTPUT_P is false, don't actually output the instruction, just return
8403 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
8405 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
8406 const char *pat
= NULL
;
8408 /* Canonical rtl should not have a constant in the first operand position. */
8409 gcc_assert (!CONSTANT_P (operands
[1]));
8411 switch (commutative_op
)
8414 if (satisfies_constraint_C1p (operands
[2]))
8415 pat
= "bmsk%? %0,%1,%Z2";
8416 else if (satisfies_constraint_C2p (operands
[2]))
8418 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
8419 pat
= "bmskn%? %0,%1,%Z2";
8421 else if (satisfies_constraint_Ccp (operands
[2]))
8422 pat
= "bclr%? %0,%1,%M2";
8423 else if (satisfies_constraint_CnL (operands
[2]))
8424 pat
= "bic%? %0,%1,%n2-1";
8427 if (satisfies_constraint_C0p (operands
[2]))
8428 pat
= "bset%? %0,%1,%z2";
8431 if (satisfies_constraint_C0p (operands
[2]))
8432 pat
= "bxor%? %0,%1,%z2";
8435 return arc_output_addsi (operands
, true, output_p
);
8439 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
8440 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
8445 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8446 Emit code and return an potentially modified address such that offsets
8447 up to SIZE are can be added to yield a legitimate address.
8448 if REUSE is set, ADDR is a register that may be modified. */
8451 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
8454 rtx offs
= const0_rtx
;
8456 if (GET_CODE (base
) == PLUS
)
8458 offs
= XEXP (base
, 1);
8459 base
= XEXP (base
, 0);
8462 || (REGNO (base
) != STACK_POINTER_REGNUM
8463 && REGNO_PTR_FRAME_P (REGNO (base
)))
8464 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
8465 || !SMALL_INT (INTVAL (offs
) + size
))
8468 emit_insn (gen_add2_insn (addr
, offs
));
8470 addr
= copy_to_mode_reg (Pmode
, addr
);
8475 /* Like move_by_pieces, but take account of load latency, and actual
8476 offset ranges. Return true on success. */
8479 arc_expand_movmem (rtx
*operands
)
8481 rtx dst
= operands
[0];
8482 rtx src
= operands
[1];
8483 rtx dst_addr
, src_addr
;
8485 int align
= INTVAL (operands
[3]);
8492 if (!CONST_INT_P (operands
[2]))
8494 size
= INTVAL (operands
[2]);
8495 /* move_by_pieces_ninsns is static, so we can't use it. */
8499 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
8501 n_pieces
= (size
+ 2) / 4U + (size
& 1);
8503 else if (align
== 2)
8504 n_pieces
= (size
+ 1) / 2U;
8507 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
8509 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8511 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
8515 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
8516 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
8517 store
[0] = store
[1] = NULL_RTX
;
8518 tmpx
[0] = tmpx
[1] = NULL_RTX
;
8519 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
8524 while (piece
> size
)
8526 mode
= smallest_int_mode_for_size (piece
* BITS_PER_UNIT
);
8527 /* If we don't re-use temporaries, the scheduler gets carried away,
8528 and the register pressure gets unnecessarily high. */
8529 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
8532 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
8533 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
8534 src_addr
= force_offsettable (src_addr
, piece
, 1);
8536 emit_insn (store
[i
]);
8537 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
8538 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
8539 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
8540 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
8543 emit_insn (store
[i
]);
8545 emit_insn (store
[i
^1]);
8550 arc_get_aux_arg (rtx pat
, int *auxr
)
8552 tree attr
, addr
= MEM_EXPR (pat
);
8553 if (TREE_CODE (addr
) != VAR_DECL
)
8556 attr
= DECL_ATTRIBUTES (addr
);
8557 if (lookup_attribute ("aux", attr
))
8559 tree arg
= TREE_VALUE (attr
);
8562 *auxr
= TREE_INT_CST_LOW (TREE_VALUE (arg
));
8570 /* Prepare operands for move in MODE. Return true iff the move has
8574 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8576 /* First handle aux attribute. */
8578 && (MEM_P (operands
[0]) || MEM_P (operands
[1])))
8582 if (MEM_P (operands
[0]) && arc_is_aux_reg_p (operands
[0]))
8584 /* Save operation. */
8585 if (arc_get_aux_arg (operands
[0], &auxr
))
8587 tmp
= gen_reg_rtx (SImode
);
8588 emit_move_insn (tmp
, GEN_INT (auxr
));
8592 tmp
= XEXP (operands
[0], 0);
8595 operands
[1] = force_reg (SImode
, operands
[1]);
8596 emit_insn (gen_rtx_UNSPEC_VOLATILE
8597 (VOIDmode
, gen_rtvec (2, operands
[1], tmp
),
8601 if (MEM_P (operands
[1]) && arc_is_aux_reg_p (operands
[1]))
8603 if (arc_get_aux_arg (operands
[1], &auxr
))
8605 tmp
= gen_reg_rtx (SImode
);
8606 emit_move_insn (tmp
, GEN_INT (auxr
));
8610 tmp
= XEXP (operands
[1], 0);
8611 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
8613 /* Load operation. */
8614 gcc_assert (REG_P (operands
[0]));
8615 emit_insn (gen_rtx_SET (operands
[0],
8616 gen_rtx_UNSPEC_VOLATILE
8617 (SImode
, gen_rtvec (1, tmp
),
8623 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
8625 prepare_pic_move (operands
, SImode
);
8627 /* Disable any REG_EQUALs associated with the symref
8628 otherwise the optimization pass undoes the work done
8629 here and references the variable directly. */
8632 if (MEM_P (operands
[0])
8633 && !(reload_in_progress
|| reload_completed
))
8635 operands
[1] = force_reg (mode
, operands
[1]);
8636 if (!move_dest_operand (operands
[0], mode
))
8638 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
8639 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8640 except that we can't use that function because it is static. */
8641 rtx pat
= change_address (operands
[0], mode
, addr
);
8642 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8645 if (!cse_not_expected
)
8647 rtx pat
= XEXP (operands
[0], 0);
8649 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8652 pat
= change_address (operands
[0], mode
, pat
);
8653 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8659 if (MEM_P (operands
[1]) && !cse_not_expected
)
8661 rtx pat
= XEXP (operands
[1], 0);
8663 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8666 pat
= change_address (operands
[1], mode
, pat
);
8667 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
8675 /* Output a library call to a function called FNAME that has been arranged
8676 to be local to any dso. */
8679 arc_output_libcall (const char *fname
)
8681 unsigned len
= strlen (fname
);
8682 static char buf
[64];
8684 gcc_assert (len
< sizeof buf
- 35);
8685 if (TARGET_LONG_CALLS_SET
8686 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
8689 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
8691 sprintf (buf
, "jl%%! @%s", fname
);
8694 sprintf (buf
, "bl%%!%%* @%s", fname
);
8698 /* Return the SImode highpart of the DImode value IN. */
8701 disi_highpart (rtx in
)
8703 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
8706 /* Return length adjustment for INSN.
8708 A write to a core reg greater or equal to 32 must not be immediately
8709 followed by a use. Anticipate the length requirement to insert a nop
8710 between PRED and SUCC to prevent a hazard. */
8713 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8717 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8718 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
8719 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
8720 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
8721 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
8722 || recog_memoized (pred
) == CODE_FOR_umul_600
8723 || recog_memoized (pred
) == CODE_FOR_mac_600
8724 || recog_memoized (pred
) == CODE_FOR_mul64_600
8725 || recog_memoized (pred
) == CODE_FOR_mac64_600
8726 || recog_memoized (pred
) == CODE_FOR_umul64_600
8727 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
8729 subrtx_iterator::array_type array
;
8730 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
8732 const_rtx x
= *iter
;
8733 switch (GET_CODE (x
))
8735 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8738 /* This is also fine for PRE/POST_MODIFY, because they
8742 rtx dest
= XEXP (x
, 0);
8743 /* Check if this sets a an extension register. N.B. we use 61 for the
8744 condition codes, which is definitely not an extension register. */
8745 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
8746 /* Check if the same register is used by the PAT. */
8747 && (refers_to_regno_p
8749 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
8750 PATTERN (succ
), 0)))
8756 /* Given a rtx, check if it is an assembly instruction or not. */
8759 arc_asm_insn_p (rtx x
)
8766 switch (GET_CODE (x
))
8773 return arc_asm_insn_p (SET_SRC (x
));
8777 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8778 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
8791 A write to a core reg greater or equal to 32 must not be immediately
8792 followed by a use. Anticipate the length requirement to insert a nop
8793 between PRED and SUCC to prevent a hazard. */
8796 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8798 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
8802 return arc600_corereg_hazard (pred
, succ
);
8807 /* Return length adjustment for INSN. */
8810 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
8814 /* We already handle sequences by ignoring the delay sequence flag. */
8815 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8818 /* Check for return with but one preceding insn since function
8820 if (TARGET_PAD_RETURN
8822 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
8823 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
8824 && get_attr_type (insn
) == TYPE_RETURN
)
8826 rtx_insn
*prev
= prev_active_insn (insn
);
8828 if (!prev
|| !(prev
= prev_active_insn (prev
))
8829 || ((NONJUMP_INSN_P (prev
)
8830 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8831 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8833 : CALL_ATTR (prev
, NON_SIBCALL
)))
8838 rtx_insn
*succ
= next_real_insn (insn
);
8840 /* One the ARC600, a write to an extension register must be separated
8842 if (succ
&& INSN_P (succ
))
8843 len
+= arc600_corereg_hazard (insn
, succ
);
8846 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8848 extract_constrain_insn_cached (insn
);
8853 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8854 CC field of *STATEP. */
8857 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8859 rtx cond
= statep
->cond
;
8860 int raw_cc
= get_arc_condition_code (cond
);
8862 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8864 if (statep
->cc
== raw_cc
)
8865 return copy_rtx (cond
);
8867 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8869 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8870 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8871 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8872 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8874 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8875 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8878 /* Return version of PAT conditionalized with COND, which is part of INSN.
8879 ANNULLED indicates if INSN is an annulled delay-slot insn.
8880 Register further changes if necessary. */
8882 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8884 /* For commutative operators, we generally prefer to have
8885 the first source match the destination. */
8886 if (GET_CODE (pat
) == SET
)
8888 rtx src
= SET_SRC (pat
);
8890 if (COMMUTATIVE_P (src
))
8892 rtx src0
= XEXP (src
, 0);
8893 rtx src1
= XEXP (src
, 1);
8894 rtx dst
= SET_DEST (pat
);
8896 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8897 /* Leave add_n alone - the canonical form is to
8898 have the complex summand first. */
8900 pat
= gen_rtx_SET (dst
,
8901 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8906 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8907 what to do with COND_EXEC. */
8908 if (RTX_FRAME_RELATED_P (insn
))
8910 /* If this is the delay slot insn of an anulled branch,
8911 dwarf2out.c:scan_trace understands the anulling semantics
8912 without the COND_EXEC. */
8913 gcc_assert (annulled
);
8914 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8916 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8918 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8922 /* Use the ccfsm machinery to do if conversion. */
8927 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8929 memset (statep
, 0, sizeof *statep
);
8930 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8932 arc_ccfsm_advance (insn
, statep
);
8934 switch (statep
->state
)
8940 /* Deleted branch. */
8941 arc_ccfsm_post_advance (insn
, statep
);
8942 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8943 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8944 if (GET_CODE (PATTERN (seq
)) == SEQUENCE
)
8946 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8947 rtx pat
= PATTERN (slot
);
8948 if (INSN_ANNULLED_BRANCH_P (insn
))
8951 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8952 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8954 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8956 PUT_CODE (slot
, NOTE
);
8957 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
8961 set_insn_deleted (insn
);
8967 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
8969 arc_ccfsm_post_advance (insn
, statep
);
8970 if (--LABEL_NUSES (insn
) == 0)
8976 if (!NONDEBUG_INSN_P (insn
))
8979 /* Conditionalized insn. */
8981 rtx_insn
*prev
, *pprev
;
8982 rtx
*patp
, pat
, cond
;
8983 bool annulled
; annulled
= false;
8985 /* If this is a delay slot insn in a non-annulled branch,
8986 don't conditionalize it. N.B., this should be fine for
8987 conditional return too. However, don't do this for
8988 unconditional branches, as these would be encountered when
8989 processing an 'else' part. */
8990 prev
= PREV_INSN (insn
);
8991 pprev
= PREV_INSN (prev
);
8992 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
8993 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
8995 if (!INSN_ANNULLED_BRANCH_P (prev
))
9000 patp
= &PATTERN (insn
);
9002 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
9003 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
9005 /* ??? don't conditionalize if all side effects are dead
9006 in the not-execute case. */
9008 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
9010 else if (simplejump_p (insn
))
9012 patp
= &SET_SRC (pat
);
9013 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
9015 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
9017 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
9018 pat
= gen_rtx_SET (pc_rtx
, pat
);
9022 validate_change (insn
, patp
, pat
, 1);
9023 if (!apply_change_group ())
9027 rtx_insn
*next
= next_nonnote_insn (insn
);
9028 if (GET_CODE (next
) == BARRIER
)
9030 if (statep
->state
== 3)
9037 arc_ccfsm_post_advance (insn
, statep
);
9042 /* Find annulled delay insns and convert them to use the appropriate predicate.
9043 This allows branch shortening to size up these insns properly. */
9046 arc_predicate_delay_insns (void)
9048 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9050 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
9053 if (!NONJUMP_INSN_P (insn
)
9054 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
9056 jump
= XVECEXP (pat
, 0, 0);
9057 dlay
= XVECEXP (pat
, 0, 1);
9058 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
9060 /* If the branch insn does the annulling, leave the delay insn alone. */
9061 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
9063 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9064 on the other path. */
9065 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
9066 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
9067 src
= SET_SRC (PATTERN (jump
));
9068 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
9069 cond
= XEXP (src
, 0);
9070 if (XEXP (src
, 2) == pc_rtx
)
9072 else if (XEXP (src
, 1) == pc_rtx
)
9076 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
9078 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9079 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9080 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9081 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9083 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9084 copy_rtx (XEXP (cond
, 0)),
9085 copy_rtx (XEXP (cond
, 1)));
9088 cond
= copy_rtx (cond
);
9089 patp
= &PATTERN (dlay
);
9091 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9092 validate_change (dlay
, patp
, pat
, 1);
9093 if (!apply_change_group ())
9099 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9100 (other than of a forward brcc), it creates a hazard when there is a read
9101 of the same register at the branch target. We can't know what is at the
9102 branch target of calls, and for branches, we don't really know before the
9103 end of delay slot scheduling, either. Not only can individual instruction
9104 be hoisted out into a delay slot, a basic block can also be emptied this
9105 way, and branch and/or fall through targets be redirected. Hence we don't
9106 want such writes in a delay slot. */
9108 /* Return nonzreo iff INSN writes to an extension core register. */
9111 arc_write_ext_corereg (rtx insn
)
9113 subrtx_iterator::array_type array
;
9114 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9116 const_rtx x
= *iter
;
9117 switch (GET_CODE (x
))
9119 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9122 /* This is also fine for PRE/POST_MODIFY, because they
9126 const_rtx dest
= XEXP (x
, 0);
9127 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9133 /* This is like the hook, but returns NULL when it can't / won't generate
9134 a legitimate address. */
9137 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9142 if (flag_pic
&& SYMBOLIC_CONST (x
))
9143 (x
) = arc_legitimize_pic_address (x
, 0);
9145 if (GET_CODE (addr
) == CONST
)
9146 addr
= XEXP (addr
, 0);
9147 if (GET_CODE (addr
) == PLUS
9148 && CONST_INT_P (XEXP (addr
, 1))
9149 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9150 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9151 || (REG_P (XEXP (addr
, 0))
9152 && (INTVAL (XEXP (addr
, 1)) & 252))))
9154 HOST_WIDE_INT offs
, upper
;
9155 int size
= GET_MODE_SIZE (mode
);
9157 offs
= INTVAL (XEXP (addr
, 1));
9158 upper
= (offs
+ 256 * size
) & ~511 * size
;
9159 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9160 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9161 if (GET_CODE (x
) == CONST
)
9162 inner
= gen_rtx_CONST (Pmode
, inner
);
9164 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9167 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9168 x
= force_reg (Pmode
, x
);
9169 if (memory_address_p ((machine_mode
) mode
, x
))
9175 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9177 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9179 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9181 return arc_legitimize_tls_address (orig_x
, model
);
9184 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9192 arc_delegitimize_address_0 (rtx op
)
9194 switch (GET_CODE (op
))
9197 return arc_delegitimize_address_0 (XEXP (op
, 0));
9200 switch (XINT (op
, 1))
9202 case ARC_UNSPEC_GOT
:
9203 case ARC_UNSPEC_GOTOFFPC
:
9204 return XVECEXP (op
, 0, 0);
9212 rtx t1
= arc_delegitimize_address_0 (XEXP (op
, 0));
9213 rtx t2
= XEXP (op
, 1);
9216 return gen_rtx_PLUS (GET_MODE (op
), t1
, t2
);
9227 arc_delegitimize_address (rtx orig_x
)
9234 x
= arc_delegitimize_address_0 (x
);
9239 x
= replace_equiv_address_nv (orig_x
, x
);
9243 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9244 differ from the hardware register number in order to allow the generic
9245 code to correctly split the concatenation of acc1 and acc2. */
9250 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9253 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9254 differ from the hardware register number in order to allow the generic
9255 code to correctly split the concatenation of acc1 and acc2. */
9260 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9263 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9264 differ from the hardware register number in order to allow the generic
9265 code to correctly split the concatenation of mhi and mlo. */
9270 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9273 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9274 differ from the hardware register number in order to allow the generic
9275 code to correctly split the concatenation of mhi and mlo. */
9280 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9283 /* FIXME: a parameter should be added, and code added to final.c,
9284 to reproduce this functionality in shorten_branches. */
9286 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9287 a previous instruction. */
9289 arc_unalign_branch_p (rtx branch
)
9293 if (!TARGET_UNALIGN_BRANCH
)
9295 /* Do not do this if we have a filled delay slot. */
9296 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9297 && !NEXT_INSN (branch
)->deleted ())
9299 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9301 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9302 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9306 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9307 are three reasons why we need to consider branches to be length 6:
9308 - annull-false delay slot insns are implemented using conditional execution,
9309 thus preventing short insn formation where used.
9310 - for ARC600: annul-true delay slot insns are implemented where possible
9311 using conditional execution, preventing short insn formation where used.
9312 - for ARC700: likely or somewhat likely taken branches are made long and
9313 unaligned if possible to avoid branch penalty. */
9316 arc_branch_size_unknown_p (void)
9318 return !optimize_size
&& arc_reorg_in_progress
;
9321 /* The usual; we set up our machine_function data. */
9323 static struct machine_function
*
9324 arc_init_machine_status (void)
9326 struct machine_function
*machine
;
9327 machine
= ggc_cleared_alloc
<machine_function
> ();
9328 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9333 /* Implements INIT_EXPANDERS. We just set up to call the above
9337 arc_init_expanders (void)
9339 init_machine_status
= arc_init_machine_status
;
9342 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9343 indicates a number of elements to ignore - that allows to have a
9344 sibcall pattern that starts with (return). LOAD_P is zero for store
9345 multiple (for prologues), and one for load multiples (for epilogues),
9346 and two for load multiples where no final clobber of blink is required.
9347 We also skip the first load / store element since this is supposed to
9348 be checked in the instruction pattern. */
9351 arc_check_millicode (rtx op
, int offset
, int load_p
)
9353 int len
= XVECLEN (op
, 0) - offset
;
9358 if (len
< 2 || len
> 13)
9364 rtx elt
= XVECEXP (op
, 0, --len
);
9366 if (GET_CODE (elt
) != CLOBBER
9367 || !REG_P (XEXP (elt
, 0))
9368 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9369 || len
< 3 || len
> 13)
9372 for (i
= 1; i
< len
; i
++)
9374 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9377 if (GET_CODE (elt
) != SET
)
9379 mem
= XEXP (elt
, load_p
);
9380 reg
= XEXP (elt
, 1-load_p
);
9381 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9383 addr
= XEXP (mem
, 0);
9384 if (GET_CODE (addr
) != PLUS
9385 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9386 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9392 /* Accessor functions for cfun->machine->unalign. */
9395 arc_get_unalign (void)
9397 return cfun
->machine
->unalign
;
9401 arc_clear_unalign (void)
9404 cfun
->machine
->unalign
= 0;
9408 arc_toggle_unalign (void)
9410 cfun
->machine
->unalign
^= 2;
9413 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9414 constant in operand 2, but which would require a LIMM because of
9416 operands 3 and 4 are new SET_SRCs for operands 0. */
9419 split_addsi (rtx
*operands
)
9421 int val
= INTVAL (operands
[2]);
9423 /* Try for two short insns first. Lengths being equal, we prefer
9424 expansions with shorter register lifetimes. */
9425 if (val
> 127 && val
<= 255
9426 && satisfies_constraint_Rcq (operands
[0]))
9428 operands
[3] = operands
[2];
9429 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9433 operands
[3] = operands
[1];
9434 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9438 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9439 constant in operand 1, but which would require a LIMM because of
9441 operands 3 and 4 are new SET_SRCs for operands 0. */
9444 split_subsi (rtx
*operands
)
9446 int val
= INTVAL (operands
[1]);
9448 /* Try for two short insns first. Lengths being equal, we prefer
9449 expansions with shorter register lifetimes. */
9450 if (satisfies_constraint_Rcq (operands
[0])
9451 && satisfies_constraint_Rcq (operands
[2]))
9453 if (val
>= -31 && val
<= 127)
9455 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9456 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9459 else if (val
>= 0 && val
< 255)
9461 operands
[3] = operands
[1];
9462 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9466 /* If the destination is not an ARCompact16 register, we might
9467 still have a chance to make a short insn if the source is;
9468 we need to start with a reg-reg move for this. */
9469 operands
[3] = operands
[2];
9470 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9473 /* Handle DOUBLE_REGS uses.
9474 Operand 0: destination register
9475 Operand 1: source register */
9478 arc_process_double_reg_moves (rtx
*operands
)
9480 rtx dest
= operands
[0];
9481 rtx src
= operands
[1];
9483 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9484 enum usesDxState state
= none
;
9486 if (refers_to_regno_p (40, 44, src
, 0))
9488 if (refers_to_regno_p (40, 44, dest
, 0))
9490 /* Via arc_register_move_cost, we should never see D,D moves. */
9491 gcc_assert (state
== none
);
9500 /* Without the LR insn, we need to split this into a
9501 sequence of insns which will use the DEXCLx and DADDHxy
9502 insns to be able to read the Dx register in question. */
9503 if (TARGET_DPFP_DISABLE_LRSR
)
9505 /* gen *movdf_insn_nolrsr */
9506 rtx set
= gen_rtx_SET (dest
, src
);
9507 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9508 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9512 /* When we have 'mov D, r' or 'mov D, D' then get the target
9513 register pair for use with LR insn. */
9514 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9515 TARGET_BIG_ENDIAN
? 0 : 4);
9516 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9517 TARGET_BIG_ENDIAN
? 4 : 0);
9519 /* Produce the two LR insns to get the high and low parts. */
9520 emit_insn (gen_rtx_SET (destHigh
,
9521 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9523 VUNSPEC_ARC_LR_HIGH
)));
9524 emit_insn (gen_rtx_SET (destLow
,
9525 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9530 else if (state
== destDx
)
9532 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9533 LR insn get the target register pair. */
9534 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9535 TARGET_BIG_ENDIAN
? 0 : 4);
9536 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9537 TARGET_BIG_ENDIAN
? 4 : 0);
9539 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9547 /* operands 0..1 are the operands of a 64 bit move instruction.
9548 split it into two moves with operands 2/3 and 4/5. */
9551 arc_split_move (rtx
*operands
)
9553 machine_mode mode
= GET_MODE (operands
[0]);
9560 if (arc_process_double_reg_moves (operands
))
9565 && ((memory_operand (operands
[0], mode
)
9566 && (even_register_operand (operands
[1], mode
)
9567 || satisfies_constraint_Cm3 (operands
[1])))
9568 || (memory_operand (operands
[1], mode
)
9569 && even_register_operand (operands
[0], mode
))))
9571 emit_move_insn (operands
[0], operands
[1]);
9575 if (TARGET_PLUS_QMACW
9576 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9578 HOST_WIDE_INT intval0
, intval1
;
9579 if (GET_MODE (operands
[1]) == V2SImode
)
9581 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9582 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9586 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9587 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9588 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9589 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9591 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9592 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9593 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9594 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9595 emit_move_insn (xop
[0], xop
[2]);
9596 emit_move_insn (xop
[3], xop
[1]);
9600 for (i
= 0; i
< 2; i
++)
9602 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9604 rtx addr
= XEXP (operands
[i
], 0);
9608 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9609 switch (GET_CODE (addr
))
9611 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9612 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9613 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9617 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9618 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9619 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9628 xop
[0+i
] = adjust_automodify_address_nv
9629 (operands
[i
], SImode
,
9630 gen_rtx_fmt_ee (code
, Pmode
, r
,
9631 gen_rtx_PLUS (Pmode
, r
, o
)),
9633 xop
[2+i
] = adjust_automodify_address_nv
9634 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9638 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9639 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9642 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9645 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9648 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9649 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9653 /* Select between the instruction output templates s_tmpl (for short INSNs)
9654 and l_tmpl (for long INSNs). */
9657 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9659 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9661 extract_constrain_insn_cached (insn
);
9662 return is_short
? s_tmpl
: l_tmpl
;
9665 /* Searches X for any reference to REGNO, returning the rtx of the
9666 reference found if any. Otherwise, returns NULL_RTX. */
9669 arc_regno_use_in (unsigned int regno
, rtx x
)
9675 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9678 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9679 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9683 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9686 else if (fmt
[i
] == 'E')
9687 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9688 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9695 /* Return the integer value of the "type" attribute for INSN, or -1 if
9696 INSN can't have attributes. */
9699 arc_attr_type (rtx_insn
*insn
)
9701 if (NONJUMP_INSN_P (insn
)
9702 ? (GET_CODE (PATTERN (insn
)) == USE
9703 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9705 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9706 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9709 return get_attr_type (insn
);
9712 /* Return true if insn sets the condition codes. */
9715 arc_sets_cc_p (rtx_insn
*insn
)
9717 if (NONJUMP_INSN_P (insn
))
9718 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9719 insn
= seq
->insn (seq
->len () - 1);
9720 return arc_attr_type (insn
) == TYPE_COMPARE
;
9723 /* Return true if INSN is an instruction with a delay slot we may want
9727 arc_need_delay (rtx_insn
*insn
)
9731 if (!flag_delayed_branch
)
9733 /* The return at the end of a function needs a delay slot. */
9734 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9735 && (!(next
= next_active_insn (insn
))
9736 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9737 && arc_attr_type (next
) == TYPE_RETURN
))
9738 && (!TARGET_PAD_RETURN
9739 || (prev_active_insn (insn
)
9740 && prev_active_insn (prev_active_insn (insn
))
9741 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9743 if (NONJUMP_INSN_P (insn
)
9744 ? (GET_CODE (PATTERN (insn
)) == USE
9745 || GET_CODE (PATTERN (insn
)) == CLOBBER
9746 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9748 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9749 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9752 return num_delay_slots (insn
) != 0;
9755 /* Return true if the scheduling pass(es) has/have already run,
9756 i.e. where possible, we should try to mitigate high latencies
9757 by different instruction selection. */
9760 arc_scheduling_not_expected (void)
9762 return cfun
->machine
->arc_reorg_started
;
9765 /* Code has a minimum p2 alignment of 1, which we must restore after
9766 an ADDR_DIFF_VEC. */
9769 arc_label_align (rtx_insn
*label
)
9771 if (align_labels
.levels
[0].log
< 1)
9773 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9774 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9777 return align_labels
.levels
[0].log
;
9780 /* Return true if LABEL is in executable code. */
9783 arc_text_label (rtx_insn
*label
)
9787 /* ??? We use deleted labels like they were still there, see
9788 gcc.c-torture/compile/20000326-2.c . */
9789 gcc_assert (GET_CODE (label
) == CODE_LABEL
9790 || (GET_CODE (label
) == NOTE
9791 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9792 next
= next_nonnote_insn (label
);
9794 return (!JUMP_TABLE_DATA_P (next
)
9795 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9796 else if (!PREV_INSN (label
))
9797 /* ??? sometimes text labels get inserted very late, see
9798 gcc.dg/torture/stackalign/comp-goto-1.c */
9803 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9804 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9805 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9806 to redirect two breqs. */
9809 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9811 /* ??? get_attr_type is declared to take an rtx. */
9812 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9815 if (CROSSING_JUMP_P (followee
))
9816 switch (get_attr_type (u
.r
))
9819 if (get_attr_length (u
.r
) != 2)
9823 case TYPE_BRCC_NO_DELAY_SLOT
:
9831 /* Return the register number of the register holding the return address
9832 for a function of type TYPE. */
9835 arc_return_address_register (unsigned int fn_type
)
9839 if (ARC_INTERRUPT_P (fn_type
))
9841 if ((fn_type
& (ARC_FUNCTION_ILINK1
| ARC_FUNCTION_FIRQ
)) != 0)
9842 regno
= ILINK1_REGNUM
;
9843 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
9844 regno
= ILINK2_REGNUM
;
9848 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
9849 regno
= RETURN_ADDR_REGNUM
;
9851 gcc_assert (regno
!= 0);
9855 /* Implement EPILOGUE_USES.
9856 Return true if REGNO should be added to the deemed uses of the epilogue.
9858 We have to make sure all the register restore instructions are
9859 known to be live in interrupt functions, plus the blink register if
9860 it is clobbered by the isr. */
9863 arc_epilogue_uses (int regno
)
9865 unsigned int fn_type
;
9867 if (regno
== arc_tp_regno
)
9870 fn_type
= arc_compute_function_type (cfun
);
9871 if (reload_completed
)
9873 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9875 if (!fixed_regs
[regno
])
9877 return ((regno
== arc_return_address_register (fn_type
))
9878 || (regno
== RETURN_ADDR_REGNUM
));
9881 return regno
== RETURN_ADDR_REGNUM
;
9884 return regno
== arc_return_address_register (fn_type
);
9887 /* Helper for EH_USES macro. */
9890 arc_eh_uses (int regno
)
9892 if (regno
== arc_tp_regno
)
9897 #ifndef TARGET_NO_LRA
9898 #define TARGET_NO_LRA !TARGET_LRA
9904 return !TARGET_NO_LRA
;
9907 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9908 Rcq registers, because some insn are shorter with them. OTOH we already
9909 have separate alternatives for this purpose, and other insns don't
9910 mind, so maybe we should rather prefer the other registers?
9911 We need more data, and we can only get that if we allow people to
9914 arc_register_priority (int r
)
9916 switch (arc_lra_priority_tag
)
9918 case ARC_LRA_PRIORITY_NONE
:
9920 case ARC_LRA_PRIORITY_NONCOMPACT
:
9921 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
9922 case ARC_LRA_PRIORITY_COMPACT
:
9923 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
9930 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
9932 return GENERAL_REGS
;
9936 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
9940 enum reload_type type
= (enum reload_type
) itype
;
9942 if (GET_CODE (x
) == PLUS
9943 && CONST_INT_P (XEXP (x
, 1))
9944 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
9945 || (REG_P (XEXP (x
, 0))
9946 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
9948 int scale
= GET_MODE_SIZE (mode
);
9950 rtx index_rtx
= XEXP (x
, 1);
9951 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
9956 if ((scale
-1) & offset
)
9960 = ((offset
+ (256 << shift
))
9961 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
9962 /* Sometimes the normal form does not suit DImode. We
9963 could avoid that by using smaller ranges, but that
9964 would give less optimized code when SImode is
9966 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
9971 regno
= REGNO (reg
);
9972 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
9974 if (reg_equiv_constant (regno
))
9976 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
9978 if (GET_CODE (sum2
) == PLUS
)
9979 sum2
= gen_rtx_CONST (Pmode
, sum2
);
9981 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
9982 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
9983 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
9988 /* We must re-recognize what we created before. */
9989 else if (GET_CODE (x
) == PLUS
9990 && GET_CODE (XEXP (x
, 0)) == PLUS
9991 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
9992 && REG_P (XEXP (XEXP (x
, 0), 0))
9993 && CONST_INT_P (XEXP (x
, 1)))
9995 /* Because this address is so complex, we know it must have
9996 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9997 it is already unshared, and needs no further unsharing. */
9998 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
9999 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
10005 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10008 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
10009 unsigned int align
,
10010 enum by_pieces_operation op
,
10013 /* Let the movmem expander handle small block moves. */
10014 if (op
== MOVE_BY_PIECES
)
10017 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
10020 /* Emit a (pre) memory barrier around an atomic sequence according to
10024 arc_pre_atomic_barrier (enum memmodel model
)
10026 if (need_atomic_barrier_p (model
, true))
10027 emit_insn (gen_memory_barrier ());
10030 /* Emit a (post) memory barrier around an atomic sequence according to
10034 arc_post_atomic_barrier (enum memmodel model
)
10036 if (need_atomic_barrier_p (model
, false))
10037 emit_insn (gen_memory_barrier ());
10040 /* Expand a compare and swap pattern. */
10043 emit_unlikely_jump (rtx insn
)
10045 rtx_insn
*jump
= emit_jump_insn (insn
);
10046 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10049 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10050 32-bit compare and swap on the word containing the byte or
10051 half-word. The difference between a weak and a strong CAS is that
10052 the weak version may simply fail. The strong version relies on two
10053 loops, one checks if the SCOND op is succsfully or not, the other
10054 checks if the 32 bit accessed location which contains the 8 or 16
10055 bit datum is not changed by other thread. The first loop is
10056 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10057 loops is implemented by this routine. */
10060 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10061 rtx oldval
, rtx newval
, rtx weak
,
10062 rtx mod_s
, rtx mod_f
)
10064 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10065 rtx addr
= gen_reg_rtx (Pmode
);
10066 rtx off
= gen_reg_rtx (SImode
);
10067 rtx oldv
= gen_reg_rtx (SImode
);
10068 rtx newv
= gen_reg_rtx (SImode
);
10069 rtx oldvalue
= gen_reg_rtx (SImode
);
10070 rtx newvalue
= gen_reg_rtx (SImode
);
10071 rtx res
= gen_reg_rtx (SImode
);
10072 rtx resv
= gen_reg_rtx (SImode
);
10073 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10075 bool is_weak
= (weak
!= const0_rtx
);
10077 /* Truncate the address. */
10078 emit_insn (gen_rtx_SET (addr
,
10079 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10081 /* Compute the datum offset. */
10082 emit_insn (gen_rtx_SET (off
,
10083 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10084 if (TARGET_BIG_ENDIAN
)
10085 emit_insn (gen_rtx_SET (off
,
10086 gen_rtx_MINUS (SImode
,
10087 (GET_MODE (mem
) == QImode
) ?
10088 GEN_INT (3) : GEN_INT (2), off
)));
10090 /* Normal read from truncated address. */
10091 memsi
= gen_rtx_MEM (SImode
, addr
);
10092 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10093 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10095 val
= copy_to_reg (memsi
);
10097 /* Convert the offset in bits. */
10098 emit_insn (gen_rtx_SET (off
,
10099 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10101 /* Get the proper mask. */
10102 if (GET_MODE (mem
) == QImode
)
10103 mask
= force_reg (SImode
, GEN_INT (0xff));
10105 mask
= force_reg (SImode
, GEN_INT (0xffff));
10107 emit_insn (gen_rtx_SET (mask
,
10108 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10110 /* Prepare the old and new values. */
10111 emit_insn (gen_rtx_SET (val
,
10112 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10115 oldval
= gen_lowpart (SImode
, oldval
);
10116 emit_insn (gen_rtx_SET (oldv
,
10117 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10119 newval
= gen_lowpart_common (SImode
, newval
);
10120 emit_insn (gen_rtx_SET (newv
,
10121 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10123 emit_insn (gen_rtx_SET (oldv
,
10124 gen_rtx_AND (SImode
, oldv
, mask
)));
10126 emit_insn (gen_rtx_SET (newv
,
10127 gen_rtx_AND (SImode
, newv
, mask
)));
10131 end_label
= gen_label_rtx ();
10132 loop_label
= gen_label_rtx ();
10133 emit_label (loop_label
);
10136 /* Make the old and new values. */
10137 emit_insn (gen_rtx_SET (oldvalue
,
10138 gen_rtx_IOR (SImode
, oldv
, val
)));
10140 emit_insn (gen_rtx_SET (newvalue
,
10141 gen_rtx_IOR (SImode
, newv
, val
)));
10143 /* Try an 32bit atomic compare and swap. It clobbers the CC
10145 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10146 weak
, mod_s
, mod_f
));
10148 /* Regardless of the weakness of the operation, a proper boolean
10149 result needs to be provided. */
10150 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10151 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10152 emit_insn (gen_rtx_SET (bool_result
, x
));
10156 /* Check the results: if the atomic op is successfully the goto
10158 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10159 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10160 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10161 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10162 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10164 /* Wait for the right moment when the accessed 32-bit location
10166 emit_insn (gen_rtx_SET (resv
,
10167 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10169 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10170 cc
= gen_rtx_REG (mode
, CC_REG
);
10171 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10173 /* Set the new value of the 32 bit location, proper masked. */
10174 emit_insn (gen_rtx_SET (val
, resv
));
10176 /* Try again if location is unstable. Fall through if only
10177 scond op failed. */
10178 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10179 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10180 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10181 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10183 emit_label (end_label
);
10186 /* End: proper return the result for the given mode. */
10187 emit_insn (gen_rtx_SET (res
,
10188 gen_rtx_AND (SImode
, res
, mask
)));
10190 emit_insn (gen_rtx_SET (res
,
10191 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10193 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10196 /* Helper function used by "atomic_compare_and_swap" expand
10200 arc_expand_compare_and_swap (rtx operands
[])
10202 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10205 bval
= operands
[0];
10206 rval
= operands
[1];
10208 oldval
= operands
[3];
10209 newval
= operands
[4];
10210 is_weak
= operands
[5];
10211 mod_s
= operands
[6];
10212 mod_f
= operands
[7];
10213 mode
= GET_MODE (mem
);
10215 if (reg_overlap_mentioned_p (rval
, oldval
))
10216 oldval
= copy_to_reg (oldval
);
10218 if (mode
== SImode
)
10220 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10221 is_weak
, mod_s
, mod_f
));
10222 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10223 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10224 emit_insn (gen_rtx_SET (bval
, x
));
10228 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10229 is_weak
, mod_s
, mod_f
);
10233 /* Helper function used by the "atomic_compare_and_swapsi_1"
10237 arc_split_compare_and_swap (rtx operands
[])
10239 rtx rval
, mem
, oldval
, newval
;
10241 enum memmodel mod_s
, mod_f
;
10243 rtx label1
, label2
, x
, cond
;
10245 rval
= operands
[0];
10247 oldval
= operands
[2];
10248 newval
= operands
[3];
10249 is_weak
= (operands
[4] != const0_rtx
);
10250 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10251 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10252 mode
= GET_MODE (mem
);
10254 /* ARC atomic ops work only with 32-bit aligned memories. */
10255 gcc_assert (mode
== SImode
);
10257 arc_pre_atomic_barrier (mod_s
);
10262 label1
= gen_label_rtx ();
10263 emit_label (label1
);
10265 label2
= gen_label_rtx ();
10267 /* Load exclusive. */
10268 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10270 /* Check if it is oldval. */
10271 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10272 cond
= gen_rtx_REG (mode
, CC_REG
);
10273 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10275 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10276 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10277 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10278 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10280 /* Exclusively store new item. Store clobbers CC reg. */
10281 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10285 /* Check the result of the store. */
10286 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10287 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10288 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10289 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10290 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10293 if (mod_f
!= MEMMODEL_RELAXED
)
10294 emit_label (label2
);
10296 arc_post_atomic_barrier (mod_s
);
10298 if (mod_f
== MEMMODEL_RELAXED
)
10299 emit_label (label2
);
10302 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10303 to perform. MEM is the memory on which to operate. VAL is the second
10304 operand of the binary operator. BEFORE and AFTER are optional locations to
10305 return the value of MEM either before of after the operation. MODEL_RTX
10306 is a CONST_INT containing the memory model to use. */
10309 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10310 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10312 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10313 machine_mode mode
= GET_MODE (mem
);
10314 rtx label
, x
, cond
;
10315 rtx before
= orig_before
, after
= orig_after
;
10317 /* ARC atomic ops work only with 32-bit aligned memories. */
10318 gcc_assert (mode
== SImode
);
10320 arc_pre_atomic_barrier (model
);
10322 label
= gen_label_rtx ();
10323 emit_label (label
);
10324 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10326 if (before
== NULL_RTX
)
10327 before
= gen_reg_rtx (mode
);
10329 if (after
== NULL_RTX
)
10330 after
= gen_reg_rtx (mode
);
10332 /* Load exclusive. */
10333 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10338 x
= gen_rtx_AND (mode
, before
, val
);
10339 emit_insn (gen_rtx_SET (after
, x
));
10340 x
= gen_rtx_NOT (mode
, after
);
10341 emit_insn (gen_rtx_SET (after
, x
));
10345 if (CONST_INT_P (val
))
10347 val
= GEN_INT (-INTVAL (val
));
10353 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10354 emit_insn (gen_rtx_SET (after
, x
));
10358 /* Exclusively store new item. Store clobbers CC reg. */
10359 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10361 /* Check the result of the store. */
10362 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10363 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10364 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10366 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10368 arc_post_atomic_barrier (model
);
10371 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10374 arc_no_speculation_in_delay_slots_p ()
10379 /* Return a parallel of registers to represent where to find the
10380 register pieces if required, otherwise NULL_RTX. */
10383 arc_dwarf_register_span (rtx rtl
)
10385 machine_mode mode
= GET_MODE (rtl
);
10389 if (GET_MODE_SIZE (mode
) != 8)
10392 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10393 regno
= REGNO (rtl
);
10394 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10395 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10400 /* Return true if OP is an acceptable memory operand for ARCompact
10401 16-bit load instructions of MODE.
10403 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10404 non scaled instructions.
10406 SCALED: TRUE if address can be scaled. */
10409 compact_memory_operand_p (rtx op
, machine_mode mode
,
10410 bool av2short
, bool scaled
)
10412 rtx addr
, plus0
, plus1
;
10415 /* Eliminate non-memory operations. */
10416 if (GET_CODE (op
) != MEM
)
10419 /* .di instructions have no 16-bit form. */
10420 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10423 /* likewise for uncached types. */
10424 if (arc_is_uncached_mem_p (op
))
10427 if (mode
== VOIDmode
)
10428 mode
= GET_MODE (op
);
10430 size
= GET_MODE_SIZE (mode
);
10432 /* dword operations really put out 2 instructions, so eliminate
10434 if (size
> UNITS_PER_WORD
)
10437 /* Decode the address now. */
10438 addr
= XEXP (op
, 0);
10439 switch (GET_CODE (addr
))
10442 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10443 || COMPACT_GP_REG_P (REGNO (addr
))
10444 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10446 plus0
= XEXP (addr
, 0);
10447 plus1
= XEXP (addr
, 1);
10449 if ((GET_CODE (plus0
) == REG
)
10450 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10451 || COMPACT_GP_REG_P (REGNO (plus0
)))
10452 && ((GET_CODE (plus1
) == REG
)
10453 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10454 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10459 if ((GET_CODE (plus0
) == REG
)
10460 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10461 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10462 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10463 && (GET_CODE (plus1
) == CONST_INT
))
10465 bool valid
= false;
10467 off
= INTVAL (plus1
);
10469 /* Negative offset is not supported in 16-bit load/store insns. */
10473 /* Only u5 immediates allowed in code density instructions. */
10481 /* This is an ldh_s.x instruction, check the u6
10483 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10487 /* Only u5 immediates allowed in 32bit access code
10488 density instructions. */
10489 if (REGNO (plus0
) <= 31)
10490 return ((off
< 32) && (off
% 4 == 0));
10497 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10508 /* The 6-bit constant get shifted to fit the real
10509 5-bits field. Check also for the alignment. */
10510 return ((off
< 64) && (off
% 2 == 0));
10512 return ((off
< 128) && (off
% 4 == 0));
10519 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10520 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10521 || SP_REG_P (REGNO (plus0
)))
10524 off
= INTVAL (plus1
);
10525 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10528 if ((GET_CODE (plus0
) == MULT
)
10529 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10530 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10531 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10532 && (GET_CODE (plus1
) == REG
)
10533 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10534 || COMPACT_GP_REG_P (REGNO (plus1
))))
10538 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10539 for 16-bit load instructions. */
10544 /* Return the frame pointer value to be backed up in the setjmp buffer. */
10547 arc_builtin_setjmp_frame_value (void)
10549 /* We always want to preserve whatever value is currently in the frame
10550 pointer register. For frames that are using the frame pointer the new
10551 value of the frame pointer register will have already been computed
10552 (as part of the prologue). For frames that are not using the frame
10553 pointer it is important that we backup whatever value is in the frame
10554 pointer register, as earlier (more outer) frames may have placed a
10555 value into the frame pointer register. It might be tempting to try
10556 and use `frame_pointer_rtx` here, however, this is not what we want.
10557 For frames that are using the frame pointer this will give the
10558 correct value. However, for frames that are not using the frame
10559 pointer this will still give the value that _would_ have been the
10560 frame pointer value for this frame (if the use of the frame pointer
10561 had not been removed). We really do want the raw frame pointer
10563 return gen_raw_REG (Pmode
, FRAME_POINTER_REGNUM
);
10566 /* Return nonzero if a jli call should be generated for a call from
10567 the current function to DECL. */
10570 arc_is_jli_call_p (rtx pat
)
10573 tree decl
= SYMBOL_REF_DECL (pat
);
10575 /* If it is not a well defined public function then return false. */
10576 if (!decl
|| !SYMBOL_REF_FUNCTION_P (pat
) || !TREE_PUBLIC (decl
))
10579 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
10580 if (lookup_attribute ("jli_always", attrs
))
10583 if (lookup_attribute ("jli_fixed", attrs
))
10586 return TARGET_JLI_ALWAYS
;
10589 /* Handle and "jli" attribute; arguments as in struct
10590 attribute_spec.handler. */
10593 arc_handle_jli_attribute (tree
*node ATTRIBUTE_UNUSED
,
10594 tree name
, tree args
, int,
10595 bool *no_add_attrs
)
10599 warning (OPT_Wattributes
,
10600 "%qE attribute only valid for ARCv2 architecture",
10602 *no_add_attrs
= true;
10605 if (args
== NULL_TREE
)
10607 warning (OPT_Wattributes
,
10608 "argument of %qE attribute is missing",
10610 *no_add_attrs
= true;
10614 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10615 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10616 tree arg
= TREE_VALUE (args
);
10617 if (TREE_CODE (arg
) != INTEGER_CST
)
10619 warning (0, "%qE attribute allows only an integer constant argument",
10621 *no_add_attrs
= true;
10623 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10628 /* Handle and "scure" attribute; arguments as in struct
10629 attribute_spec.handler. */
10632 arc_handle_secure_attribute (tree
*node ATTRIBUTE_UNUSED
,
10633 tree name
, tree args
, int,
10634 bool *no_add_attrs
)
10638 warning (OPT_Wattributes
,
10639 "%qE attribute only valid for ARC EM architecture",
10641 *no_add_attrs
= true;
10644 if (args
== NULL_TREE
)
10646 warning (OPT_Wattributes
,
10647 "argument of %qE attribute is missing",
10649 *no_add_attrs
= true;
10653 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10654 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10655 tree arg
= TREE_VALUE (args
);
10656 if (TREE_CODE (arg
) != INTEGER_CST
)
10658 warning (0, "%qE attribute allows only an integer constant argument",
10660 *no_add_attrs
= true;
10666 /* Return nonzero if the symbol is a secure function. */
10669 arc_is_secure_call_p (rtx pat
)
10672 tree decl
= SYMBOL_REF_DECL (pat
);
10677 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
10678 if (lookup_attribute ("secure_call", attrs
))
10684 /* Handle "uncached" qualifier. */
10687 arc_handle_uncached_attribute (tree
*node
,
10688 tree name
, tree args
,
10689 int flags ATTRIBUTE_UNUSED
,
10690 bool *no_add_attrs
)
10692 if (DECL_P (*node
) && TREE_CODE (*node
) != TYPE_DECL
)
10694 error ("%qE attribute only applies to types",
10696 *no_add_attrs
= true;
10700 warning (OPT_Wattributes
, "argument of %qE attribute ignored", name
);
10705 /* Return TRUE if PAT is a memory addressing an uncached data. */
10708 arc_is_uncached_mem_p (rtx pat
)
10710 tree attrs
= NULL_TREE
;
10716 /* Get the memory attributes. */
10717 addr
= MEM_EXPR (pat
);
10721 /* Get the attributes. */
10722 if (TREE_CODE (addr
) == MEM_REF
)
10724 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (addr
));
10725 if (lookup_attribute ("uncached", attrs
))
10728 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
10729 if (lookup_attribute ("uncached", attrs
))
10733 /* For COMPONENT_REF, use the FIELD_DECL from tree operand 1. */
10734 if (TREE_CODE (addr
) == COMPONENT_REF
)
10736 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 1)));
10737 if (lookup_attribute ("uncached", attrs
))
10743 /* Handle aux attribute. The auxiliary registers are addressed using
10744 special instructions lr and sr. The attribute 'aux' indicates if a
10745 variable refers to the aux-regs and what is the register number
10749 arc_handle_aux_attribute (tree
*node
,
10750 tree name
, tree args
, int,
10751 bool *no_add_attrs
)
10753 /* Isn't it better to use address spaces for the aux-regs? */
10754 if (DECL_P (*node
))
10756 if (TREE_CODE (*node
) != VAR_DECL
)
10758 error ("%qE attribute only applies to variables", name
);
10759 *no_add_attrs
= true;
10763 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10764 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10765 tree arg
= TREE_VALUE (args
);
10766 if (TREE_CODE (arg
) != INTEGER_CST
)
10768 warning (OPT_Wattributes
, "%qE attribute allows only an integer "
10769 "constant argument", name
);
10770 *no_add_attrs
= true;
10772 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10775 if (TREE_CODE (*node
) == VAR_DECL
)
10777 tree fntype
= TREE_TYPE (*node
);
10778 if (fntype
&& TREE_CODE (fntype
) == POINTER_TYPE
)
10780 tree attrs
= tree_cons (get_identifier ("aux"), NULL_TREE
,
10781 TYPE_ATTRIBUTES (fntype
));
10782 TYPE_ATTRIBUTES (fntype
) = attrs
;
10789 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10790 anchors for small data: the GP register acts as an anchor in that
10791 case. We also don't want to use them for PC-relative accesses,
10792 where the PC acts as an anchor. Prohibit also TLS symbols to use
10796 arc_use_anchors_for_symbol_p (const_rtx symbol
)
10798 if (SYMBOL_REF_TLS_MODEL (symbol
))
10804 if (SYMBOL_REF_SMALL_P (symbol
))
10807 return default_use_anchors_for_symbol_p (symbol
);
10810 /* Return true if SUBST can't safely replace its equivalent during RA. */
10812 arc_cannot_substitute_mem_equiv_p (rtx
)
10814 /* If SUBST is mem[base+index], the address may not fit ISA,
10815 thus return true. */
10819 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
10820 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
10822 #undef TARGET_CONSTANT_ALIGNMENT
10823 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
10825 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
10826 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
10828 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10829 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
10831 struct gcc_target targetm
= TARGET_INITIALIZER
;
10833 #include "gt-arc.h"