1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2019 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 /* Check if an rtx fits in the store instruction format. Loads can
91 handle any constant. */
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) & (~0x03), \
95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
97 : -(-GET_MODE_SIZE (MODE) | (~0x03)) >> 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 /* Start enter/leave register range. */
175 #define ENTER_LEAVE_START_REG 13
177 /* End enter/leave register range. */
178 #define ENTER_LEAVE_END_REG 26
180 /* The maximum number of insns skipped which will be conditionalised if
182 /* When optimizing for speed:
183 Let p be the probability that the potentially skipped insns need to
184 be executed, pn the cost of a correctly predicted non-taken branch,
185 mt the cost of a mis/non-predicted taken branch,
186 mn mispredicted non-taken, pt correctly predicted taken ;
187 costs expressed in numbers of instructions like the ones considered
189 Unfortunately we don't have a measure of predictability - this
190 is linked to probability only in that in the no-eviction-scenario
191 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
192 value that can be assumed *if* the distribution is perfectly random.
193 A predictability of 1 is perfectly plausible not matter what p is,
194 because the decision could be dependent on an invocation parameter
196 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
197 For small p, we want MAX_INSNS_SKIPPED == pt
199 When optimizing for size:
200 We want to skip insn unless we could use 16 opcodes for the
201 non-conditionalized insn to balance the branch length or more.
202 Performance can be tie-breaker. */
203 /* If the potentially-skipped insns are likely to be executed, we'll
204 generally save one non-taken branch
206 this to be no less than the 1/p */
207 #define MAX_INSNS_SKIPPED 3
209 /* A nop is needed between a 4 byte insn that sets the condition codes and
210 a branch that uses them (the same isn't true for an 8 byte insn that sets
211 the condition codes). Set by arc_ccfsm_advance. Used by
212 arc_print_operand. */
214 static int get_arc_condition_code (rtx
);
216 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
217 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
218 static tree
arc_handle_jli_attribute (tree
*, tree
, tree
, int, bool *);
219 static tree
arc_handle_secure_attribute (tree
*, tree
, tree
, int, bool *);
220 static tree
arc_handle_uncached_attribute (tree
*, tree
, tree
, int, bool *);
221 static tree
arc_handle_aux_attribute (tree
*, tree
, tree
, int, bool *);
223 /* Initialized arc_attribute_table to NULL since arc doesnot have any
224 machine specific supported attributes. */
225 const struct attribute_spec arc_attribute_table
[] =
227 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
228 affects_type_identity, handler, exclude } */
229 { "interrupt", 1, 1, true, false, false, true,
230 arc_handle_interrupt_attribute
, NULL
},
231 /* Function calls made to this symbol must be done indirectly, because
232 it may lie outside of the 21/25 bit addressing range of a normal function
234 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
235 /* Whereas these functions are always known to reside within the 25 bit
236 addressing range of unconditionalized bl. */
237 { "medium_call", 0, 0, false, true, true, false, NULL
, NULL
},
238 /* And these functions are always known to reside within the 21 bit
239 addressing range of blcc. */
240 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
241 /* Function which are not having the prologue and epilogue generated
243 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute
,
245 /* Functions calls made using jli instruction. The pointer in JLI
246 table is found latter. */
247 { "jli_always", 0, 0, false, true, true, false, NULL
, NULL
},
248 /* Functions calls made using jli instruction. The pointer in JLI
249 table is given as input parameter. */
250 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute
,
252 /* Call a function using secure-mode. */
253 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute
,
255 /* Bypass caches using .di flag. */
256 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute
,
258 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute
, NULL
},
259 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
261 static int arc_comp_type_attributes (const_tree
, const_tree
);
262 static void arc_file_start (void);
263 static void arc_internal_label (FILE *, const char *, unsigned long);
264 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
266 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
267 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
269 static void arc_init_builtins (void);
270 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
272 static int branch_dest (rtx
);
274 static void arc_output_pic_addr_const (FILE *, rtx
, int);
275 static bool arc_function_ok_for_sibcall (tree
, tree
);
276 static rtx
arc_function_value (const_tree
, const_tree
, bool);
277 const char * output_shift (rtx
*);
278 static void arc_reorg (void);
279 static bool arc_in_small_data_p (const_tree
);
281 static void arc_init_reg_tables (void);
282 static bool arc_return_in_memory (const_tree
, const_tree
);
283 static bool arc_vector_mode_supported_p (machine_mode
);
285 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
287 static const char *arc_invalid_within_doloop (const rtx_insn
*);
289 static void output_short_suffix (FILE *file
);
291 static bool arc_frame_pointer_required (void);
293 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
295 enum by_pieces_operation op
,
298 /* Globally visible information about currently selected cpu. */
299 const arc_cpu_t
*arc_selected_cpu
;
301 /* Given a symbol RTX (const (symb <+ const_int>), returns its
305 get_symbol_alignment (rtx x
)
307 tree decl
= NULL_TREE
;
310 switch (GET_CODE (x
))
313 decl
= SYMBOL_REF_DECL (x
);
316 return get_symbol_alignment (XEXP (x
, 0));
318 gcc_assert (CONST_INT_P (XEXP (x
, 1)));
319 return get_symbol_alignment (XEXP (x
, 0));
325 align
= DECL_ALIGN (decl
);
326 align
= align
/ BITS_PER_UNIT
;
330 /* Return true if x is ok to be used as a small data address. */
333 legitimate_small_data_address_p (rtx x
)
335 switch (GET_CODE (x
))
338 return legitimate_small_data_address_p (XEXP (x
, 0));
340 return SYMBOL_REF_SMALL_P (x
);
343 bool p0
= (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
)
344 && SYMBOL_REF_SMALL_P (XEXP (x
, 0));
345 bool p1
= CONST_INT_P (XEXP (x
, 1))
346 && (INTVAL (XEXP (x
, 1)) <= g_switch_value
);
354 /* TRUE if op is an scaled address. */
356 legitimate_scaled_address_p (machine_mode mode
, rtx op
, bool strict
)
358 if (GET_CODE (op
) != PLUS
)
361 if (GET_CODE (XEXP (op
, 0)) != MULT
)
364 /* Check multiplication operands. */
365 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op
, 0), 0), strict
))
368 if (!CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
371 switch (GET_MODE_SIZE (mode
))
374 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 2)
382 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 4)
389 /* Check the base. */
390 if (RTX_OK_FOR_BASE_P (XEXP (op
, 1), (strict
)))
395 if (CONST_INT_P (XEXP (op
, 1)))
400 /* Scalled addresses for sdata is done other places. */
401 if (legitimate_small_data_address_p (op
))
404 if (CONSTANT_P (XEXP (op
, 1)))
410 /* Check for constructions like REG + OFFS, where OFFS can be a
411 register, an immediate or an long immediate. */
414 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
416 if (GET_CODE (x
) != PLUS
)
419 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
422 /* Check for: [Rx + small offset] or [Rx + Ry]. */
423 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
424 && GET_MODE_SIZE ((mode
)) <= 4)
425 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
428 /* Check for [Rx + symbol]. */
430 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
431 /* Avoid this type of address for double or larger modes. */
432 && (GET_MODE_SIZE (mode
) <= 4)
433 /* Avoid small data which ends in something like GP +
435 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))))
441 /* Implements target hook vector_mode_supported_p. */
444 arc_vector_mode_supported_p (machine_mode mode
)
449 return TARGET_PLUS_DMPY
;
452 return TARGET_PLUS_QMACW
;
455 return TARGET_SIMD_SET
;
462 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
465 arc_preferred_simd_mode (scalar_mode mode
)
470 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
479 /* Implements target hook
480 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
483 arc_autovectorize_vector_sizes (vector_sizes
*sizes
)
485 if (TARGET_PLUS_QMACW
)
487 sizes
->quick_push (8);
488 sizes
->quick_push (4);
493 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
495 arc_sched_issue_rate (void)
508 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
509 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
510 static rtx
arc_delegitimize_address (rtx
);
511 static bool arc_can_follow_jump (const rtx_insn
*follower
,
512 const rtx_insn
*followee
);
514 static rtx
frame_insn (rtx
);
515 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
517 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
519 /* initialize the GCC target structure. */
520 #undef TARGET_COMP_TYPE_ATTRIBUTES
521 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
522 #undef TARGET_ASM_FILE_START
523 #define TARGET_ASM_FILE_START arc_file_start
524 #undef TARGET_ATTRIBUTE_TABLE
525 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
526 #undef TARGET_ASM_INTERNAL_LABEL
527 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
528 #undef TARGET_RTX_COSTS
529 #define TARGET_RTX_COSTS arc_rtx_costs
530 #undef TARGET_ADDRESS_COST
531 #define TARGET_ADDRESS_COST arc_address_cost
533 #undef TARGET_ENCODE_SECTION_INFO
534 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
536 #undef TARGET_CANNOT_FORCE_CONST_MEM
537 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
539 #undef TARGET_INIT_BUILTINS
540 #define TARGET_INIT_BUILTINS arc_init_builtins
542 #undef TARGET_EXPAND_BUILTIN
543 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
545 #undef TARGET_BUILTIN_DECL
546 #define TARGET_BUILTIN_DECL arc_builtin_decl
548 #undef TARGET_ASM_OUTPUT_MI_THUNK
549 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
551 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
552 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
554 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
555 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
557 #undef TARGET_MACHINE_DEPENDENT_REORG
558 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
560 #undef TARGET_IN_SMALL_DATA_P
561 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
563 #undef TARGET_PROMOTE_FUNCTION_MODE
564 #define TARGET_PROMOTE_FUNCTION_MODE \
565 default_promote_function_mode_always_promote
567 #undef TARGET_PROMOTE_PROTOTYPES
568 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
570 #undef TARGET_RETURN_IN_MEMORY
571 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
572 #undef TARGET_PASS_BY_REFERENCE
573 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
575 #undef TARGET_SETUP_INCOMING_VARARGS
576 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
578 #undef TARGET_ARG_PARTIAL_BYTES
579 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
581 #undef TARGET_MUST_PASS_IN_STACK
582 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
584 #undef TARGET_FUNCTION_VALUE
585 #define TARGET_FUNCTION_VALUE arc_function_value
587 #undef TARGET_SCHED_ADJUST_PRIORITY
588 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
590 #undef TARGET_SCHED_ISSUE_RATE
591 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
593 #undef TARGET_VECTOR_MODE_SUPPORTED_P
594 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
596 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
597 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
599 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
600 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
602 #undef TARGET_CAN_USE_DOLOOP_P
603 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
605 #undef TARGET_INVALID_WITHIN_DOLOOP
606 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
608 #undef TARGET_PRESERVE_RELOAD_P
609 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
611 #undef TARGET_CAN_FOLLOW_JUMP
612 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
614 #undef TARGET_DELEGITIMIZE_ADDRESS
615 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
617 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
618 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
619 arc_use_by_pieces_infrastructure_p
621 /* Usually, we will be able to scale anchor offsets.
622 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
623 #undef TARGET_MIN_ANCHOR_OFFSET
624 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
625 #undef TARGET_MAX_ANCHOR_OFFSET
626 #define TARGET_MAX_ANCHOR_OFFSET (1020)
628 #undef TARGET_SECONDARY_RELOAD
629 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
631 #define TARGET_OPTION_OVERRIDE arc_override_options
633 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
635 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
637 #define TARGET_CAN_ELIMINATE arc_can_eliminate
639 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
641 #define TARGET_FUNCTION_ARG arc_function_arg
643 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
645 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
647 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
649 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
651 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
653 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
654 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
655 arc_no_speculation_in_delay_slots_p
658 #define TARGET_LRA_P arc_lra_p
659 #define TARGET_REGISTER_PRIORITY arc_register_priority
660 /* Stores with scaled offsets have different displacement ranges. */
661 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
662 #define TARGET_SPILL_CLASS arc_spill_class
664 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
665 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
667 #undef TARGET_WARN_FUNC_RETURN
668 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
670 #include "target-def.h"
672 #undef TARGET_ASM_ALIGNED_HI_OP
673 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
674 #undef TARGET_ASM_ALIGNED_SI_OP
675 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
678 #undef TARGET_HAVE_TLS
679 #define TARGET_HAVE_TLS HAVE_AS_TLS
682 #undef TARGET_DWARF_REGISTER_SPAN
683 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
685 #undef TARGET_HARD_REGNO_NREGS
686 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
687 #undef TARGET_HARD_REGNO_MODE_OK
688 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
690 #undef TARGET_MODES_TIEABLE_P
691 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
692 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
693 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value
695 /* Try to keep the (mov:DF _, reg) as early as possible so
696 that the d<add/sub/mul>h-lr insns appear together and can
697 use the peephole2 pattern. */
700 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
702 rtx set
= single_set (insn
);
704 && GET_MODE (SET_SRC(set
)) == DFmode
705 && GET_CODE (SET_SRC(set
)) == REG
)
707 /* Incrementing priority by 20 (empirically derived). */
708 return priority
+ 20;
714 /* For ARC base register + offset addressing, the validity of the
715 address is mode-dependent for most of the offset range, as the
716 offset can be scaled by the access size.
717 We don't expose these as mode-dependent addresses in the
718 mode_dependent_address_p target hook, because that would disable
719 lots of optimizations, and most uses of these addresses are for 32
720 or 64 bit accesses anyways, which are fine.
721 However, that leaves some addresses for 8 / 16 bit values not
722 properly reloaded by the generic code, which is why we have to
723 schedule secondary reloads for these. */
726 arc_secondary_reload (bool in_p
,
730 secondary_reload_info
*sri
)
732 enum rtx_code code
= GET_CODE (x
);
734 if (cl
== DOUBLE_REGS
)
737 /* If we have a subreg (reg), where reg is a pseudo (that will end in
738 a memory location), then we may need a scratch register to handle
739 the fp/sp+largeoffset address. */
747 int regno
= REGNO (x
);
748 if (regno
>= FIRST_PSEUDO_REGISTER
)
749 regno
= reg_renumber
[regno
];
754 /* It is a pseudo that ends in a stack location. This
755 procedure only works with the old reload step. */
756 if (reg_equiv_mem (REGNO (x
)) && !lra_in_progress
)
758 /* Get the equivalent address and check the range of the
760 rtx mem
= reg_equiv_mem (REGNO (x
));
761 addr
= find_replacement (&XEXP (mem
, 0));
766 gcc_assert (MEM_P (x
));
768 addr
= simplify_rtx (addr
);
770 if (addr
&& GET_CODE (addr
) == PLUS
771 && CONST_INT_P (XEXP (addr
, 1))
772 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
778 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
782 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
792 /* Convert reloads using offsets that are too large to use indirect
796 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
800 gcc_assert (GET_CODE (mem
) == MEM
);
801 addr
= XEXP (mem
, 0);
803 /* Large offset: use a move. FIXME: ld ops accepts limms as
804 offsets. Hence, the following move insn is not required. */
805 emit_move_insn (scratch
, addr
);
806 mem
= replace_equiv_address_nv (mem
, scratch
);
808 /* Now create the move. */
810 emit_insn (gen_rtx_SET (mem
, reg
));
812 emit_insn (gen_rtx_SET (reg
, mem
));
817 static unsigned arc_ifcvt (void);
821 const pass_data pass_data_arc_ifcvt
=
824 "arc_ifcvt", /* name */
825 OPTGROUP_NONE
, /* optinfo_flags */
826 TV_IFCVT2
, /* tv_id */
827 0, /* properties_required */
828 0, /* properties_provided */
829 0, /* properties_destroyed */
830 0, /* todo_flags_start */
831 TODO_df_finish
/* todo_flags_finish */
834 class pass_arc_ifcvt
: public rtl_opt_pass
837 pass_arc_ifcvt(gcc::context
*ctxt
)
838 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
841 /* opt_pass methods: */
842 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
843 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
849 make_pass_arc_ifcvt (gcc::context
*ctxt
)
851 return new pass_arc_ifcvt (ctxt
);
854 static unsigned arc_predicate_delay_insns (void);
858 const pass_data pass_data_arc_predicate_delay_insns
=
861 "arc_predicate_delay_insns", /* name */
862 OPTGROUP_NONE
, /* optinfo_flags */
863 TV_IFCVT2
, /* tv_id */
864 0, /* properties_required */
865 0, /* properties_provided */
866 0, /* properties_destroyed */
867 0, /* todo_flags_start */
868 TODO_df_finish
/* todo_flags_finish */
871 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
874 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
875 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
878 /* opt_pass methods: */
879 virtual unsigned int execute (function
*)
881 return arc_predicate_delay_insns ();
888 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
890 return new pass_arc_predicate_delay_insns (ctxt
);
893 /* Called by OVERRIDE_OPTIONS to initialize various things. */
900 /* I have the multiplier, then use it*/
901 if (TARGET_MPYW
|| TARGET_MULTI
)
902 arc_multcost
= COSTS_N_INSNS (1);
904 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
905 if (arc_multcost
< 0)
908 case ARC_TUNE_ARC700_4_2_STD
:
910 max throughput (1 multiply + 4 other insns) / 5 cycles. */
911 arc_multcost
= COSTS_N_INSNS (4);
912 if (TARGET_NOMPY_SET
)
913 arc_multcost
= COSTS_N_INSNS (30);
915 case ARC_TUNE_ARC700_4_2_XMAC
:
917 max throughput (1 multiply + 2 other insns) / 3 cycles. */
918 arc_multcost
= COSTS_N_INSNS (3);
919 if (TARGET_NOMPY_SET
)
920 arc_multcost
= COSTS_N_INSNS (30);
922 case ARC_TUNE_ARC600
:
923 if (TARGET_MUL64_SET
)
925 arc_multcost
= COSTS_N_INSNS (4);
930 arc_multcost
= COSTS_N_INSNS (30);
934 /* MPY instructions valid only for ARC700 or ARCv2. */
935 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
936 error ("-mno-mpy supported only for ARC700 or ARCv2");
938 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
939 error ("-mno-dpfp-lrsr supported only with -mdpfp");
941 /* FPX-1. No fast and compact together. */
942 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
943 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
944 error ("FPX fast and compact options cannot be specified together");
946 /* FPX-2. No fast-spfp for arc600 or arc601. */
947 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
948 error ("-mspfp_fast not available on ARC600 or ARC601");
950 /* FPX-4. No FPX extensions mixed with FPU extensions. */
951 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
952 && TARGET_HARD_FLOAT
)
953 error ("No FPX/FPU mixing allowed");
955 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
956 if (flag_pic
&& TARGET_ARC600_FAMILY
)
959 "PIC is not supported for %s. Generating non-PIC code only..",
964 arc_init_reg_tables ();
966 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
967 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
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;
974 arc_punct_chars
['+'] = 1;
975 arc_punct_chars
['_'] = 1;
977 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
979 /* There are two target-independent ifcvt passes, and arc_reorg may do
980 one or more arc_ifcvt calls. */
981 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
982 struct register_pass_info arc_ifcvt4_info
983 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
984 struct register_pass_info arc_ifcvt5_info
985 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
987 register_pass (&arc_ifcvt4_info
);
988 register_pass (&arc_ifcvt5_info
);
991 if (flag_delayed_branch
)
993 opt_pass
*pass_arc_predicate_delay_insns
994 = make_pass_arc_predicate_delay_insns (g
);
995 struct register_pass_info arc_predicate_delay_info
996 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
998 register_pass (&arc_predicate_delay_info
);
1002 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1003 register range is specified as two registers separated by a dash.
1004 It always starts with r0, and its upper limit is fp register.
1005 blink and lp_count registers are optional. */
1008 irq_range (const char *cstr
)
1010 int i
, first
, last
, blink
, lpcount
, xreg
;
1011 char *str
, *dash
, *comma
;
1014 str
= (char *) alloca (i
+ 1);
1015 memcpy (str
, cstr
, i
+ 1);
1019 dash
= strchr (str
, '-');
1022 warning (OPT_mirq_ctrl_saved_
, "missing dash");
1027 comma
= strchr (dash
+ 1, ',');
1031 first
= decode_reg_name (str
);
1034 warning (OPT_mirq_ctrl_saved_
, "first register must be R0");
1038 /* At this moment we do not have the register names initialized
1040 if (!strcmp (dash
+ 1, "ilink"))
1043 last
= decode_reg_name (dash
+ 1);
1047 warning (OPT_mirq_ctrl_saved_
, "unknown register name: %s", dash
+ 1);
1053 warning (OPT_mirq_ctrl_saved_
,
1054 "last register name %s must be an odd register", dash
+ 1);
1062 warning (OPT_mirq_ctrl_saved_
,
1063 "%s-%s is an empty range", str
, dash
+ 1);
1072 comma
= strchr (str
, ',');
1076 xreg
= decode_reg_name (str
);
1088 warning (OPT_mirq_ctrl_saved_
,
1089 "unknown register name: %s", str
);
1094 irq_ctrl_saved
.irq_save_last_reg
= last
;
1095 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
1096 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
1099 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1103 parse_mrgf_banked_regs_option (const char *arg
)
1109 val
= strtol (arg
, &end_ptr
, 10);
1110 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
1111 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
1113 error ("invalid number in -mrgf-banked-regs=%s "
1114 "valid values are 0, 4, 8, 16, or 32", arg
);
1117 rgf_banked_register_count
= (int) val
;
1120 /* Check ARC options, generate derived target attributes. */
1123 arc_override_options (void)
1126 cl_deferred_option
*opt
;
1127 vec
<cl_deferred_option
> *vopt
1128 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
1130 if (arc_cpu
== PROCESSOR_NONE
)
1131 arc_cpu
= TARGET_CPU_DEFAULT
;
1133 /* Set the default cpu options. */
1134 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
1136 /* Set the architectures. */
1137 switch (arc_selected_cpu
->arch_info
->arch_id
)
1140 arc_cpu_string
= "EM";
1143 arc_cpu_string
= "HS";
1146 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
1147 arc_cpu_string
= "NPS400";
1149 arc_cpu_string
= "ARC700";
1152 arc_cpu_string
= "ARC600";
1158 irq_ctrl_saved
.irq_save_last_reg
= -1;
1159 irq_ctrl_saved
.irq_save_blink
= false;
1160 irq_ctrl_saved
.irq_save_lpcount
= false;
1162 rgf_banked_register_count
= 0;
1164 /* Handle the deferred options. */
1166 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1168 switch (opt
->opt_index
)
1170 case OPT_mirq_ctrl_saved_
:
1172 irq_range (opt
->arg
);
1174 warning (OPT_mirq_ctrl_saved_
,
1175 "option -mirq-ctrl-saved valid only for ARC v2 processors");
1178 case OPT_mrgf_banked_regs_
:
1180 parse_mrgf_banked_regs_option (opt
->arg
);
1182 warning (OPT_mrgf_banked_regs_
,
1183 "option -mrgf-banked-regs valid only for ARC v2 processors");
1191 CLEAR_HARD_REG_SET (overrideregs
);
1192 if (common_deferred_options
)
1194 vec
<cl_deferred_option
> v
=
1195 *((vec
<cl_deferred_option
> *) common_deferred_options
);
1198 FOR_EACH_VEC_ELT (v
, i
, opt
)
1200 switch (opt
->opt_index
)
1203 case OPT_fcall_used_
:
1204 case OPT_fcall_saved_
:
1205 if ((reg
= decode_reg_name_and_count (opt
->arg
, &nregs
)) >= 0)
1206 for (j
= reg
; j
< reg
+ nregs
; j
++)
1207 SET_HARD_REG_BIT (overrideregs
, j
);
1215 /* Check options against architecture options. Throw an error if
1216 option is not allowed. Extra, check options against default
1217 architecture/cpu flags and throw an warning if we find a
1219 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1221 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1223 error ("Option %s=%s is not available for %s CPU.", \
1224 DOC0, DOC1, arc_selected_cpu->name); \
1225 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1226 && (VAR != DEFAULT_##VAR) \
1228 warning (0, "Option %s is ignored, the default value %s" \
1229 " is considered for %s CPU.", DOC0, DOC1, \
1230 arc_selected_cpu->name); \
1232 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1234 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1235 && (target_flags & MASK)) \
1236 error ("Option %s is not available for %s CPU", \
1237 DOC, arc_selected_cpu->name); \
1238 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1239 && (target_flags_explicit & MASK) \
1240 && (!(target_flags & MASK))) \
1241 warning (0, "Unset option %s is ignored, it is always" \
1242 " enabled for %s CPU.", DOC, \
1243 arc_selected_cpu->name); \
1246 #include "arc-options.def"
1251 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1252 specific flags are set in arc-common.c. The architecture forces
1253 the default hardware configurations in, regardless what command
1254 line options are saying. The CPU optional hw options can be
1255 turned on or off. */
1256 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1258 if ((arc_selected_cpu->flags & CODE) \
1259 && ((target_flags_explicit & MASK) == 0)) \
1260 target_flags |= MASK; \
1261 if (arc_selected_cpu->arch_info->dflags & CODE) \
1262 target_flags |= MASK; \
1264 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1266 if ((arc_selected_cpu->flags & CODE) \
1267 && (VAR == DEFAULT_##VAR)) \
1269 if (arc_selected_cpu->arch_info->dflags & CODE) \
1273 #include "arc-options.def"
1279 switch (arc_selected_cpu
->extra
)
1281 case HAS_LPCOUNT_16
:
1288 /* Set Tune option. */
1289 if (arc_tune
== ARC_TUNE_NONE
)
1290 arc_tune
= (enum arc_tune_attr
) arc_selected_cpu
->tune
;
1292 if (arc_size_opt_level
== 3)
1296 target_flags
|= MASK_NO_SDATA_SET
;
1298 if (flag_no_common
== 255)
1299 flag_no_common
= !TARGET_NO_SDATA_SET
;
1301 if (TARGET_MIXED_CODE
)
1304 /* Check for small data option */
1305 if (!global_options_set
.x_g_switch_value
&& !TARGET_NO_SDATA_SET
)
1306 g_switch_value
= TARGET_LL64
? 8 : 4;
1308 /* A7 has an issue with delay slots. */
1309 if (TARGET_ARC700
&& (arc_tune
!= ARC_TUNE_ARC7XX
))
1310 flag_delayed_branch
= 0;
1312 /* Millicode thunks doesn't work with long calls. */
1313 if (TARGET_LONG_CALLS_SET
)
1314 target_flags
&= ~MASK_MILLICODE_THUNK_SET
;
1316 /* These need to be done at start up. It's convenient to do them here. */
1320 /* The condition codes of the ARC, and the inverse function. */
1321 /* For short branches, the "c" / "nc" names are not defined in the ARC
1322 Programmers manual, so we have to use "lo" / "hs"" instead. */
1323 static const char *arc_condition_codes
[] =
1325 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1326 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1329 enum arc_cc_code_index
1331 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1332 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1333 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1334 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1337 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1339 /* Returns the index of the ARC condition code string in
1340 `arc_condition_codes'. COMPARISON should be an rtx like
1341 `(eq (...) (...))'. */
1344 get_arc_condition_code (rtx comparison
)
1346 switch (GET_MODE (XEXP (comparison
, 0)))
1349 case E_SImode
: /* For BRcc. */
1350 switch (GET_CODE (comparison
))
1352 case EQ
: return ARC_CC_EQ
;
1353 case NE
: return ARC_CC_NE
;
1354 case GT
: return ARC_CC_GT
;
1355 case LE
: return ARC_CC_LE
;
1356 case GE
: return ARC_CC_GE
;
1357 case LT
: return ARC_CC_LT
;
1358 case GTU
: return ARC_CC_HI
;
1359 case LEU
: return ARC_CC_LS
;
1360 case LTU
: return ARC_CC_LO
;
1361 case GEU
: return ARC_CC_HS
;
1362 default : gcc_unreachable ();
1365 switch (GET_CODE (comparison
))
1367 case EQ
: return ARC_CC_EQ
;
1368 case NE
: return ARC_CC_NE
;
1369 case GE
: return ARC_CC_P
;
1370 case LT
: return ARC_CC_N
;
1371 case GT
: return ARC_CC_PNZ
;
1372 default : gcc_unreachable ();
1375 switch (GET_CODE (comparison
))
1377 case EQ
: return ARC_CC_EQ
;
1378 case NE
: return ARC_CC_NE
;
1379 default : gcc_unreachable ();
1382 switch (GET_CODE (comparison
))
1384 case LTU
: return ARC_CC_C
;
1385 case GEU
: return ARC_CC_NC
;
1386 default : gcc_unreachable ();
1388 case E_CC_FP_GTmode
:
1389 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1390 switch (GET_CODE (comparison
))
1392 case GT
: return ARC_CC_N
;
1393 case UNLE
: return ARC_CC_P
;
1394 default : gcc_unreachable ();
1397 switch (GET_CODE (comparison
))
1399 case GT
: return ARC_CC_HI
;
1400 case UNLE
: return ARC_CC_LS
;
1401 default : gcc_unreachable ();
1403 case E_CC_FP_GEmode
:
1404 /* Same for FPX and non-FPX. */
1405 switch (GET_CODE (comparison
))
1407 case GE
: return ARC_CC_HS
;
1408 case UNLT
: return ARC_CC_LO
;
1409 default : gcc_unreachable ();
1411 case E_CC_FP_UNEQmode
:
1412 switch (GET_CODE (comparison
))
1414 case UNEQ
: return ARC_CC_EQ
;
1415 case LTGT
: return ARC_CC_NE
;
1416 default : gcc_unreachable ();
1418 case E_CC_FP_ORDmode
:
1419 switch (GET_CODE (comparison
))
1421 case UNORDERED
: return ARC_CC_C
;
1422 case ORDERED
: return ARC_CC_NC
;
1423 default : gcc_unreachable ();
1426 switch (GET_CODE (comparison
))
1428 case EQ
: return ARC_CC_EQ
;
1429 case NE
: return ARC_CC_NE
;
1430 case UNORDERED
: return ARC_CC_C
;
1431 case ORDERED
: return ARC_CC_NC
;
1432 case LTGT
: return ARC_CC_HI
;
1433 case UNEQ
: return ARC_CC_LS
;
1434 default : gcc_unreachable ();
1437 switch (GET_CODE (comparison
))
1439 case EQ
: return ARC_CC_EQ
;
1440 case NE
: return ARC_CC_NE
;
1441 case GT
: return ARC_CC_GT
;
1442 case GE
: return ARC_CC_GE
;
1443 case LT
: return ARC_CC_C
;
1444 case LE
: return ARC_CC_LS
;
1445 case UNORDERED
: return ARC_CC_V
;
1446 case ORDERED
: return ARC_CC_NV
;
1447 case UNGT
: return ARC_CC_HI
;
1448 case UNGE
: return ARC_CC_HS
;
1449 case UNLT
: return ARC_CC_LT
;
1450 case UNLE
: return ARC_CC_LE
;
1451 /* UNEQ and LTGT do not have representation. */
1452 case LTGT
: /* Fall through. */
1453 case UNEQ
: /* Fall through. */
1454 default : gcc_unreachable ();
1456 case E_CC_FPU_UNEQmode
:
1457 switch (GET_CODE (comparison
))
1459 case LTGT
: return ARC_CC_NE
;
1460 case UNEQ
: return ARC_CC_EQ
;
1461 default : gcc_unreachable ();
1463 default : gcc_unreachable ();
1469 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1472 arc_short_comparison_p (rtx comparison
, int offset
)
1474 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1475 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1476 switch (get_arc_condition_code (comparison
))
1478 case ARC_CC_EQ
: case ARC_CC_NE
:
1479 return offset
>= -512 && offset
<= 506;
1480 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1481 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1482 return offset
>= -64 && offset
<= 58;
1488 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1489 return the mode to be used for the comparison. */
1492 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1494 machine_mode mode
= GET_MODE (x
);
1497 /* For an operation that sets the condition codes as a side-effect, the
1498 C and V flags is not set as for cmp, so we can only use comparisons where
1499 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1501 /* ??? We could use "pnz" for greater than zero, however, we could then
1502 get into trouble because the comparison could not be reversed. */
1503 if (GET_MODE_CLASS (mode
) == MODE_INT
1505 && (op
== EQ
|| op
== NE
1506 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1509 /* add.f for if (a+b) */
1511 && GET_CODE (y
) == NEG
1512 && (op
== EQ
|| op
== NE
))
1515 /* Check if this is a test suitable for bxor.f . */
1516 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1517 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1521 /* Check if this is a test suitable for add / bmsk.f . */
1522 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1523 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1524 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1525 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1526 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1529 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1530 && GET_CODE (x
) == PLUS
1531 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1534 if (TARGET_ARGONAUT_SET
1535 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1538 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1540 case LT
: case UNGE
: case GT
: case UNLE
:
1541 return CC_FP_GTmode
;
1542 case LE
: case UNGT
: case GE
: case UNLT
:
1543 return CC_FP_GEmode
;
1544 default: gcc_unreachable ();
1546 else if (TARGET_HARD_FLOAT
1547 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1548 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1567 return CC_FPU_UNEQmode
;
1572 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1576 case EQ
: case NE
: return CC_Zmode
;
1578 case GT
: case UNLE
: return CC_FP_GTmode
;
1580 case GE
: case UNLT
: return CC_FP_GEmode
;
1581 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1582 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1583 default: gcc_unreachable ();
1589 /* Vectors to keep interesting information about registers where it can easily
1590 be got. We use to use the actual mode value as the bit number, but there
1591 is (or may be) more than 32 modes now. Instead we use two tables: one
1592 indexed by hard register number, and one indexed by mode. */
1594 /* The purpose of arc_mode_class is to shrink the range of modes so that
1595 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1596 mapped into one arc_mode_class mode. */
1598 enum arc_mode_class
{
1600 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1601 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1605 /* Modes for condition codes. */
1606 #define C_MODES (1 << (int) C_MODE)
1608 /* Modes for single-word and smaller quantities. */
1609 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1611 /* Modes for double-word and smaller quantities. */
1612 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1614 /* Mode for 8-byte DF values only. */
1615 #define DF_MODES (1 << DF_MODE)
1617 /* Modes for quad-word and smaller quantities. */
1618 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1620 /* Modes for 128-bit vectors. */
1621 #define V_MODES (1 << (int) V_MODE)
1623 /* Value is 1 if register/mode pair is acceptable on arc. */
1625 static unsigned int arc_hard_regno_modes
[] = {
1626 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1627 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1628 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1629 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1631 /* ??? Leave these as S_MODES for now. */
1632 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1633 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1634 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1635 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1637 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1638 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1639 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1640 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1642 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1643 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1644 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1645 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1647 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1648 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1651 static unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1653 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1656 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1661 /* Initialize the arc_mode_class array. */
1664 arc_init_reg_tables (void)
1668 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1670 machine_mode m
= (machine_mode
) i
;
1672 switch (GET_MODE_CLASS (m
))
1675 case MODE_PARTIAL_INT
:
1676 case MODE_COMPLEX_INT
:
1677 if (GET_MODE_SIZE (m
) <= 4)
1678 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1679 else if (GET_MODE_SIZE (m
) == 8)
1680 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1681 else if (GET_MODE_SIZE (m
) == 16)
1682 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1683 else if (GET_MODE_SIZE (m
) == 32)
1684 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1686 arc_mode_class
[i
] = 0;
1689 case MODE_COMPLEX_FLOAT
:
1690 if (GET_MODE_SIZE (m
) <= 4)
1691 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1692 else if (GET_MODE_SIZE (m
) == 8)
1693 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1694 else if (GET_MODE_SIZE (m
) == 16)
1695 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1696 else if (GET_MODE_SIZE (m
) == 32)
1697 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1699 arc_mode_class
[i
] = 0;
1701 case MODE_VECTOR_INT
:
1702 if (GET_MODE_SIZE (m
) == 4)
1703 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1704 else if (GET_MODE_SIZE (m
) == 8)
1705 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1707 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1711 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1712 we must explicitly check for them here. */
1713 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1714 || i
== (int) CC_Cmode
1715 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1716 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1717 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1719 arc_mode_class
[i
] = 0;
1725 /* Core registers 56..59 are used for multiply extension options.
1726 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1727 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1728 number depends on endianness.
1729 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1730 Because mlo / mhi form a 64 bit value, we use different gcc internal
1731 register numbers to make them form a register pair as the gcc internals
1732 know it. mmid gets number 57, if still available, and mlo / mhi get
1733 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1734 to map this back. */
1735 char rname56
[5] = "r56";
1736 char rname57
[5] = "r57";
1737 char rname58
[5] = "r58";
1738 char rname59
[5] = "r59";
1739 char rname29
[7] = "ilink1";
1740 char rname30
[7] = "ilink2";
1743 arc_conditional_register_usage (void)
1747 int fix_start
= 60, fix_end
= 55;
1751 /* For ARCv2 the core register set is changed. */
1752 strcpy (rname29
, "ilink");
1753 strcpy (rname30
, "r30");
1755 if (!TEST_HARD_REG_BIT (overrideregs
, R30_REG
))
1757 /* No user interference. Set the r30 to be used by the
1759 call_used_regs
[R30_REG
] = 1;
1760 fixed_regs
[R30_REG
] = 0;
1762 arc_regno_reg_class
[R30_REG
] = GENERAL_REGS
;
1766 if (TARGET_MUL64_SET
)
1768 fix_start
= R57_REG
;
1771 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1772 you are supposed to refer to it as mlo & mhi, e.g
1773 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1774 In an actual asm instruction, you are of course use mmed.
1775 The point of avoiding having a separate register for mmed is that
1776 this way, we don't have to carry clobbers of that reg around in every
1777 isntruction that modifies mlo and/or mhi. */
1778 strcpy (rname57
, "");
1779 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1780 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1783 /* The nature of arc_tp_regno is actually something more like a global
1784 register, however globalize_reg requires a declaration.
1785 We use EPILOGUE_USES to compensate so that sets from
1786 __builtin_set_frame_pointer are not deleted. */
1787 if (arc_tp_regno
!= -1)
1788 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1790 if (TARGET_MULMAC_32BY16_SET
)
1792 fix_start
= MUL32x16_REG
;
1793 fix_end
= fix_end
> R57_REG
? fix_end
: R57_REG
;
1794 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1795 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1797 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1799 if (!fixed_regs
[regno
])
1800 warning (0, "multiply option implies r%d is fixed", regno
);
1801 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1807 reg_alloc_order
[0] = 0;
1808 reg_alloc_order
[1] = 1;
1809 reg_alloc_order
[2] = 2;
1810 reg_alloc_order
[3] = 3;
1811 reg_alloc_order
[4] = 12;
1812 reg_alloc_order
[5] = 13;
1813 reg_alloc_order
[6] = 14;
1814 reg_alloc_order
[7] = 15;
1815 reg_alloc_order
[8] = 4;
1816 reg_alloc_order
[9] = 5;
1817 reg_alloc_order
[10] = 6;
1818 reg_alloc_order
[11] = 7;
1819 reg_alloc_order
[12] = 8;
1820 reg_alloc_order
[13] = 9;
1821 reg_alloc_order
[14] = 10;
1822 reg_alloc_order
[15] = 11;
1826 reg_alloc_order
[2] = 12;
1827 reg_alloc_order
[3] = 13;
1828 reg_alloc_order
[4] = 14;
1829 reg_alloc_order
[5] = 15;
1830 reg_alloc_order
[6] = 1;
1831 reg_alloc_order
[7] = 0;
1832 reg_alloc_order
[8] = 4;
1833 reg_alloc_order
[9] = 5;
1834 reg_alloc_order
[10] = 6;
1835 reg_alloc_order
[11] = 7;
1836 reg_alloc_order
[12] = 8;
1837 reg_alloc_order
[13] = 9;
1838 reg_alloc_order
[14] = 10;
1839 reg_alloc_order
[15] = 11;
1842 if (TARGET_SIMD_SET
)
1845 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1846 reg_alloc_order
[i
] = i
;
1847 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1848 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1849 reg_alloc_order
[i
] = i
;
1852 /* Reduced configuration: don't use r4-r9, r16-r25. */
1855 for (i
= R4_REG
; i
<= R9_REG
; i
++)
1856 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1857 for (i
= R16_REG
; i
<= R25_REG
; i
++)
1858 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1861 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1864 for (regno
= R1_REG
; regno
< R32_REG
; regno
+=2)
1865 arc_hard_regno_modes
[regno
] = S_MODES
;
1867 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1870 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1871 && ((i
<= R3_REG
) || ((i
>= R12_REG
) && (i
<= R15_REG
))))
1872 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1874 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1876 else if (i
< LP_COUNT
)
1877 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1879 arc_regno_reg_class
[i
] = NO_REGS
;
1881 /* Handle Special Registers. */
1882 arc_regno_reg_class
[CC_REG
] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1883 arc_regno_reg_class
[62] = GENERAL_REGS
;
1886 for (i
= R40_REG
; i
< R44_REG
; ++i
)
1888 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1889 if (!TARGET_ARGONAUT_SET
)
1890 CLEAR_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], i
);
1894 /* Disable all DOUBLE_REGISTER settings, if not generating DPFP
1896 arc_regno_reg_class
[R40_REG
] = ALL_REGS
;
1897 arc_regno_reg_class
[R41_REG
] = ALL_REGS
;
1898 arc_regno_reg_class
[R42_REG
] = ALL_REGS
;
1899 arc_regno_reg_class
[R43_REG
] = ALL_REGS
;
1901 fixed_regs
[R40_REG
] = 1;
1902 fixed_regs
[R41_REG
] = 1;
1903 fixed_regs
[R42_REG
] = 1;
1904 fixed_regs
[R43_REG
] = 1;
1906 arc_hard_regno_modes
[R40_REG
] = 0;
1907 arc_hard_regno_modes
[R42_REG
] = 0;
1910 if (TARGET_SIMD_SET
)
1912 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1913 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1915 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1916 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1918 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1919 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1920 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1921 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1923 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1924 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1925 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1929 arc_regno_reg_class
[PCL_REG
] = NO_REGS
;
1931 /*ARCV2 Accumulator. */
1933 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1934 || TARGET_PLUS_DMPY
)
1936 arc_regno_reg_class
[ACCL_REGNO
] = GENERAL_REGS
;
1937 arc_regno_reg_class
[ACCH_REGNO
] = GENERAL_REGS
;
1939 /* Allow the compiler to freely use them. */
1940 if (!TEST_HARD_REG_BIT (overrideregs
, ACCL_REGNO
))
1941 fixed_regs
[ACCL_REGNO
] = 0;
1942 if (!TEST_HARD_REG_BIT (overrideregs
, ACCH_REGNO
))
1943 fixed_regs
[ACCH_REGNO
] = 0;
1945 if (!fixed_regs
[ACCH_REGNO
] && !fixed_regs
[ACCL_REGNO
])
1946 arc_hard_regno_modes
[ACC_REG_FIRST
] = D_MODES
;
1950 /* Implement TARGET_HARD_REGNO_NREGS. */
1953 arc_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
1955 if (GET_MODE_SIZE (mode
) == 16
1956 && regno
>= ARC_FIRST_SIMD_VR_REG
1957 && regno
<= ARC_LAST_SIMD_VR_REG
)
1960 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
1963 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1966 arc_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
1968 return (arc_hard_regno_modes
[regno
] & arc_mode_class
[mode
]) != 0;
1971 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1974 arc_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
1976 return (GET_MODE_CLASS (mode1
) == MODE_INT
1977 && GET_MODE_CLASS (mode2
) == MODE_INT
1978 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
1979 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
);
1982 /* Handle an "interrupt" attribute; arguments as in
1983 struct attribute_spec.handler. */
1986 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
1991 tree value
= TREE_VALUE (args
);
1993 if (TREE_CODE (value
) != STRING_CST
)
1995 warning (OPT_Wattributes
,
1996 "argument of %qE attribute is not a string constant",
1998 *no_add_attrs
= true;
2001 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
2002 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2004 warning (OPT_Wattributes
,
2005 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2007 *no_add_attrs
= true;
2010 && strcmp (TREE_STRING_POINTER (value
), "ilink")
2011 && strcmp (TREE_STRING_POINTER (value
), "firq"))
2013 warning (OPT_Wattributes
,
2014 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2016 *no_add_attrs
= true;
2023 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
2024 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
2026 if (TREE_CODE (*node
) != FUNCTION_DECL
)
2028 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2030 *no_add_attrs
= true;
2036 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2039 arc_allocate_stack_slots_for_args (void)
2041 /* Naked functions should not allocate stack slots for arguments. */
2042 unsigned int fn_type
= arc_compute_function_type (cfun
);
2044 return !ARC_NAKED_P(fn_type
);
2047 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2050 arc_warn_func_return (tree decl
)
2052 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
2053 unsigned int fn_type
= arc_compute_function_type (func
);
2055 return !ARC_NAKED_P (fn_type
);
2058 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2059 and two if they are nearly compatible (which causes a warning to be
2063 arc_comp_type_attributes (const_tree type1
,
2066 int l1
, l2
, m1
, m2
, s1
, s2
;
2068 /* Check for mismatch of non-default calling convention. */
2069 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
2072 /* Check for mismatched call attributes. */
2073 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2074 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2075 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2076 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2077 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2078 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2080 /* Only bother to check if an attribute is defined. */
2081 if (l1
| l2
| m1
| m2
| s1
| s2
)
2083 /* If one type has an attribute, the other must have the same attribute. */
2084 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
2087 /* Disallow mixed attributes. */
2088 if (l1
+ m1
+ s1
> 1)
2096 /* Misc. utilities. */
2098 /* X and Y are two things to compare using CODE. Emit the compare insn and
2099 return the rtx for the cc reg in the proper mode. */
2102 gen_compare_reg (rtx comparison
, machine_mode omode
)
2104 enum rtx_code code
= GET_CODE (comparison
);
2105 rtx x
= XEXP (comparison
, 0);
2106 rtx y
= XEXP (comparison
, 1);
2108 machine_mode mode
, cmode
;
2111 cmode
= GET_MODE (x
);
2112 if (cmode
== VOIDmode
)
2113 cmode
= GET_MODE (y
);
2114 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
2115 if (cmode
== SImode
)
2117 if (!register_operand (x
, SImode
))
2119 if (register_operand (y
, SImode
))
2124 code
= swap_condition (code
);
2127 x
= copy_to_mode_reg (SImode
, x
);
2129 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
2130 y
= copy_to_mode_reg (SImode
, y
);
2134 x
= force_reg (cmode
, x
);
2135 y
= force_reg (cmode
, y
);
2137 mode
= SELECT_CC_MODE (code
, x
, y
);
2139 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
2141 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2142 cmpdfpx_raw, is not a correct comparison for floats:
2143 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2145 if (TARGET_ARGONAUT_SET
2146 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2150 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2151 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2153 case GT
: case UNLE
: case GE
: case UNLT
:
2154 code
= swap_condition (code
);
2162 if (cmode
== SFmode
)
2164 emit_insn (gen_cmpsfpx_raw (x
, y
));
2168 /* Accepts Dx regs directly by insns. */
2169 emit_insn (gen_cmpdfpx_raw (x
, y
));
2172 if (mode
!= CC_FPXmode
)
2173 emit_insn (gen_rtx_SET (cc_reg
,
2174 gen_rtx_COMPARE (mode
,
2175 gen_rtx_REG (CC_FPXmode
, 61),
2178 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2182 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2183 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2185 case LT
: case UNGE
: case LE
: case UNGT
:
2186 code
= swap_condition (code
);
2195 emit_insn (gen_cmp_quark (cc_reg
,
2196 gen_rtx_COMPARE (mode
, x
, y
)));
2198 else if (TARGET_HARD_FLOAT
2199 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2200 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2201 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2202 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2204 rtx op0
= gen_rtx_REG (cmode
, 0);
2205 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2210 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2211 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2213 case LT
: case UNGE
: case LE
: case UNGT
:
2214 code
= swap_condition (code
);
2220 if (currently_expanding_to_rtl
)
2228 emit_move_insn (op0
, x
);
2229 emit_move_insn (op1
, y
);
2233 gcc_assert (rtx_equal_p (op0
, x
));
2234 gcc_assert (rtx_equal_p (op1
, y
));
2241 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2244 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2245 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2248 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2249 We assume the value can be either signed or unsigned. */
2252 arc_double_limm_p (rtx value
)
2254 HOST_WIDE_INT low
, high
;
2256 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2261 low
= CONST_DOUBLE_LOW (value
);
2262 high
= CONST_DOUBLE_HIGH (value
);
2264 if (low
& 0x80000000)
2266 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2267 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2268 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2273 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2277 /* Do any needed setup for a variadic function. For the ARC, we must
2278 create a register parameter block, and then copy any anonymous arguments
2279 in registers to memory.
2281 CUM has not been updated for the last named argument which has type TYPE
2282 and mode MODE, and we rely on this fact. */
2285 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2286 machine_mode mode
, tree type
,
2287 int *pretend_size
, int no_rtl
)
2290 CUMULATIVE_ARGS next_cum
;
2292 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2294 next_cum
= *get_cumulative_args (args_so_far
);
2295 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2297 first_anon_arg
= next_cum
;
2299 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2301 /* First anonymous (unnamed) argument is in a reg. */
2303 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2304 int first_reg_offset
= first_anon_arg
;
2309 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2310 FIRST_PARM_OFFSET (0)));
2311 move_block_from_reg (first_reg_offset
, regblock
,
2312 MAX_ARC_PARM_REGS
- first_reg_offset
);
2316 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2320 /* Cost functions. */
2322 /* Provide the costs of an addressing mode that contains ADDR.
2323 If ADDR is not a valid address, its cost is irrelevant. */
2326 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2328 switch (GET_CODE (addr
))
2331 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2332 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2333 case PRE_MODIFY
: case POST_MODIFY
:
2339 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2341 /* Most likely needs a LIMM. */
2342 return COSTS_N_INSNS (1);
2346 register rtx plus0
= XEXP (addr
, 0);
2347 register rtx plus1
= XEXP (addr
, 1);
2349 if (GET_CODE (plus0
) != REG
2350 && (GET_CODE (plus0
) != MULT
2351 || !CONST_INT_P (XEXP (plus0
, 1))
2352 || (INTVAL (XEXP (plus0
, 1)) != 2
2353 && INTVAL (XEXP (plus0
, 1)) != 4)))
2356 switch (GET_CODE (plus1
))
2359 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2363 : (satisfies_constraint_Rcq (plus0
)
2364 && satisfies_constraint_O (plus1
))
2368 return (speed
< 1 ? 0
2369 : (satisfies_constraint_Rcq (plus0
)
2370 && satisfies_constraint_Rcq (plus1
))
2375 return COSTS_N_INSNS (1);
2388 /* Emit instruction X with the frame related bit set. */
2394 RTX_FRAME_RELATED_P (x
) = 1;
2398 /* Emit a frame insn to move SRC to DST. */
2401 frame_move (rtx dst
, rtx src
)
2403 rtx tmp
= gen_rtx_SET (dst
, src
);
2404 RTX_FRAME_RELATED_P (tmp
) = 1;
2405 return frame_insn (tmp
);
2408 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2409 auto increment address, or is zero. */
2412 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2414 rtx insn
= frame_move (dst
, src
);
2417 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2418 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2419 add_reg_note (insn
, REG_INC
, reg
);
2423 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2426 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2428 gcc_assert ((offset
& 0x3) == 0);
2431 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2434 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2437 frame_stack_add (HOST_WIDE_INT offset
)
2439 return frame_add (stack_pointer_rtx
, offset
);
2442 /* Traditionally, we push saved registers first in the prologue,
2443 then we allocate the rest of the frame - and reverse in the epilogue.
2444 This has still its merits for ease of debugging, or saving code size
2445 or even execution time if the stack frame is so large that some accesses
2446 can't be encoded anymore with offsets in the instruction code when using
2448 Also, it would be a good starting point if we got instructions to help
2449 with register save/restore.
2451 However, often stack frames are small, and the pushing / popping has
2453 - the stack modification prevents a lot of scheduling.
2454 - frame allocation / deallocation needs extra instructions.
2455 - unless we know that we compile ARC700 user code, we need to put
2456 a memory barrier after frame allocation / before deallocation to
2457 prevent interrupts clobbering our data in the frame.
2458 In particular, we don't have any such guarantees for library functions,
2459 which tend to, on the other hand, to have small frames.
2461 Thus, for small frames, we'd like to use a different scheme:
2462 - The frame is allocated in full with the first prologue instruction,
2463 and deallocated in full with the last epilogue instruction.
2464 Thus, the instructions in-betwen can be freely scheduled.
2465 - If the function has no outgoing arguments on the stack, we can allocate
2466 one register save slot at the top of the stack. This register can then
2467 be saved simultanously with frame allocation, and restored with
2469 This register can be picked depending on scheduling considerations,
2470 although same though should go into having some set of registers
2471 to be potentially lingering after a call, and others to be available
2472 immediately - i.e. in the absence of interprocedual optimization, we
2473 can use an ABI-like convention for register allocation to reduce
2474 stalls after function return. */
2475 /* Function prologue/epilogue handlers. */
2477 /* ARCompact stack frames look like:
2479 Before call After call
2480 high +-----------------------+ +-----------------------+
2481 mem | reg parm save area | | reg parm save area |
2482 | only created for | | only created for |
2483 | variable arg fns | | variable arg fns |
2484 AP +-----------------------+ +-----------------------+
2485 | return addr register | | return addr register |
2486 | (if required) | | (if required) |
2487 +-----------------------+ +-----------------------+
2489 | reg save area | | reg save area |
2491 +-----------------------+ +-----------------------+
2492 | frame pointer | | frame pointer |
2493 | (if required) | | (if required) |
2494 FP +-----------------------+ +-----------------------+
2496 | local/temp variables | | local/temp variables |
2498 +-----------------------+ +-----------------------+
2500 | arguments on stack | | arguments on stack |
2502 SP +-----------------------+ +-----------------------+
2503 | reg parm save area |
2504 | only created for |
2505 | variable arg fns |
2506 AP +-----------------------+
2507 | return addr register |
2509 +-----------------------+
2513 +-----------------------+
2516 FP +-----------------------+
2518 | local/temp variables |
2520 +-----------------------+
2522 | arguments on stack |
2524 mem SP +-----------------------+
2527 1) The "reg parm save area" does not exist for non variable argument fns.
2528 The "reg parm save area" can be eliminated completely if we created our
2529 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2531 /* Structure to be filled in by arc_compute_frame_size with register
2532 save masks, and offsets for the current function. */
2533 struct GTY (()) arc_frame_info
2535 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2536 unsigned int extra_size
; /* # bytes of extra stuff. */
2537 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2538 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2539 unsigned int reg_size
; /* # bytes needed to store regs. */
2540 unsigned int var_size
; /* # bytes that variables take up. */
2541 unsigned int gmask
; /* Mask of saved gp registers. */
2542 bool initialized
; /* FALSE if frame size already calculated. */
2543 short millicode_start_reg
;
2544 short millicode_end_reg
;
2545 bool save_return_addr
;
2548 /* Defining data structures for per-function information. */
2550 typedef struct GTY (()) machine_function
2552 unsigned int fn_type
;
2553 struct arc_frame_info frame_info
;
2554 /* To keep track of unalignment caused by short insns. */
2556 struct arc_ccfsm ccfsm_current
;
2557 /* Map from uid to ccfsm state during branch shortening. */
2558 rtx ccfsm_current_insn
;
2559 char arc_reorg_started
;
2560 char prescan_initialized
;
2563 /* Type of function DECL.
2565 The result is cached. To reset the cache at the end of a function,
2566 call with DECL = NULL_TREE. */
2569 arc_compute_function_type (struct function
*fun
)
2571 tree attr
, decl
= fun
->decl
;
2572 unsigned int fn_type
= fun
->machine
->fn_type
;
2574 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2577 /* Check if it is a naked function. */
2578 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2579 fn_type
|= ARC_FUNCTION_NAKED
;
2581 fn_type
|= ARC_FUNCTION_NORMAL
;
2583 /* Now see if this is an interrupt handler. */
2584 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2585 if (attr
!= NULL_TREE
)
2587 tree value
, args
= TREE_VALUE (attr
);
2589 gcc_assert (list_length (args
) == 1);
2590 value
= TREE_VALUE (args
);
2591 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2593 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2594 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2595 fn_type
|= ARC_FUNCTION_ILINK1
;
2596 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2597 fn_type
|= ARC_FUNCTION_ILINK2
;
2598 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2599 fn_type
|= ARC_FUNCTION_FIRQ
;
2604 return fun
->machine
->fn_type
= fn_type
;
2607 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2608 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2610 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2611 The return address and frame pointer are treated separately.
2612 Don't consider them here.
2613 Addition for pic: The gp register needs to be saved if the current
2614 function changes it to access gotoff variables.
2615 FIXME: This will not be needed if we used some arbitrary register
2619 arc_must_save_register (int regno
, struct function
*func
)
2621 unsigned int fn_type
= arc_compute_function_type (func
);
2622 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2623 && ARC_AUTO_IRQ_P (fn_type
));
2624 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2626 switch (rgf_banked_register_count
)
2629 firq_auto_save_p
&= (regno
< 4);
2632 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2635 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2636 || ((regno
> 25) && (regno
< 29))
2637 || ((regno
> 29) && (regno
< 32)));
2640 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2643 firq_auto_save_p
= false;
2647 if ((regno
) != RETURN_ADDR_REGNUM
2648 && (regno
) != FRAME_POINTER_REGNUM
2649 && df_regs_ever_live_p (regno
)
2650 && (!call_used_regs
[regno
]
2651 || ARC_INTERRUPT_P (fn_type
))
2652 /* Do not emit code for auto saved regs. */
2654 && !firq_auto_save_p
)
2660 /* Return true if the return address must be saved in the current function,
2661 otherwise return false. */
2664 arc_must_save_return_addr (struct function
*func
)
2666 if (func
->machine
->frame_info
.save_return_addr
)
2672 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2673 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2674 Register Allocator) pass, while we want to get the frame size
2675 correct earlier than the IRA pass.
2677 When a function uses eh_return we must ensure that the fp register
2678 is saved and then restored so that the unwinder can restore the
2679 correct value for the frame we are going to jump to.
2681 To do this we force all frames that call eh_return to require a
2682 frame pointer (see arc_frame_pointer_required), this
2683 will ensure that the previous frame pointer is stored on entry to
2684 the function, and will then be reloaded at function exit.
2686 As the frame pointer is handled as a special case in our prologue
2687 and epilogue code it must not be saved and restored using the
2688 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2689 believes that the function is not using a frame pointer and that
2690 the value in the fp register is the frame pointer, while the
2691 prologue and epilogue are busy saving and restoring the fp
2694 During compilation of a function the frame size is evaluated
2695 multiple times, it is not until the reload pass is complete the the
2696 frame size is considered fixed (it is at this point that space for
2697 all spills has been allocated). However the frame_pointer_needed
2698 variable is not set true until the register allocation pass, as a
2699 result in the early stages the frame size does not include space
2700 for the frame pointer to be spilled.
2702 The problem that this causes is that the rtl generated for
2703 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2704 the offset from the frame pointer at which the return address
2705 lives. However, in early passes GCC has not yet realised we need a
2706 frame pointer, and so has not included space for the frame pointer
2707 in the frame size, and so gets the offset of the return address
2708 wrong. This should not be an issue as in later passes GCC has
2709 realised that the frame pointer needs to be spilled, and has
2710 increased the frame size. However, the rtl for the
2711 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2712 offset, and the wrong smaller offset is used. */
2715 arc_frame_pointer_needed (void)
2717 return (frame_pointer_needed
|| crtl
->calls_eh_return
);
2720 /* Return non-zero if there are registers to be saved or loaded using
2721 millicode thunks. We can only use consecutive sequences starting
2722 with r13, and not going beyond r25.
2723 GMASK is a bitmask of registers to save. This function sets
2724 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2725 of registers to be saved / restored with a millicode call. */
2728 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2729 struct arc_frame_info
*frame
)
2733 int start_reg
= 13, end_reg
= 25;
2735 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2737 end_reg
= regno
- 1;
2738 /* There is no point in using millicode thunks if we don't save/restore
2739 at least three registers. For non-leaf functions we also have the
2741 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2743 frame
->millicode_start_reg
= 13;
2744 frame
->millicode_end_reg
= regno
- 1;
2750 /* Return the bytes needed to compute the frame pointer from the
2751 current stack pointer. */
2754 arc_compute_frame_size (void)
2757 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2758 unsigned int reg_size
;
2760 struct arc_frame_info
*frame_info
;
2762 unsigned int extra_plus_reg_size
;
2763 unsigned int extra_plus_reg_size_aligned
;
2765 /* The answer might already be known. */
2766 if (cfun
->machine
->frame_info
.initialized
)
2767 return cfun
->machine
->frame_info
.total_size
;
2769 frame_info
= &cfun
->machine
->frame_info
;
2770 size
= ARC_STACK_ALIGN (get_frame_size ());
2772 /* 1) Size of locals and temporaries. */
2775 /* 2) Size of outgoing arguments. */
2776 args_size
= crtl
->outgoing_args_size
;
2778 /* 3) Calculate space needed for saved registers.
2779 ??? We ignore the extension registers for now. */
2781 /* See if this is an interrupt handler. Call used registers must be saved
2787 for (regno
= 0; regno
<= 31; regno
++)
2789 if (arc_must_save_register (regno
, cfun
))
2791 reg_size
+= UNITS_PER_WORD
;
2792 gmask
|= 1L << regno
;
2796 /* In a frame that calls __builtin_eh_return two data registers are
2797 used to pass values back to the exception handler.
2799 Ensure that these registers are spilled to the stack so that the
2800 exception throw code can find them, and update the saved values.
2801 The handling code will then consume these reloaded values to
2802 handle the exception. */
2803 if (crtl
->calls_eh_return
)
2804 for (regno
= 0; EH_RETURN_DATA_REGNO (regno
) != INVALID_REGNUM
; regno
++)
2806 reg_size
+= UNITS_PER_WORD
;
2807 gmask
|= 1L << regno
;
2810 /* Check if we need to save the return address. */
2811 frame_info
->save_return_addr
= (!crtl
->is_leaf
2812 || df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2813 || crtl
->calls_eh_return
);
2815 /* Saving blink reg for millicode thunk calls. */
2816 if (TARGET_MILLICODE_THUNK_SET
2817 && !crtl
->calls_eh_return
)
2819 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2820 frame_info
->save_return_addr
= true;
2823 /* 4) Calculate extra size made up of the blink + fp size. */
2825 if (arc_must_save_return_addr (cfun
))
2827 if (arc_frame_pointer_needed ())
2830 /* 5) Space for variable arguments passed in registers */
2831 pretend_size
= crtl
->args
.pretend_args_size
;
2833 /* Ensure everything before the locals is aligned appropriately. */
2834 extra_plus_reg_size
= extra_size
+ reg_size
;
2835 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN (extra_plus_reg_size
);
2836 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2838 /* Compute total frame size. */
2839 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2841 /* It used to be the case that the alignment was forced at this
2842 point. However, that is dangerous, calculations based on
2843 total_size would be wrong. Given that this has never cropped up
2844 as an issue I've changed this to an assert for now. */
2845 gcc_assert (total_size
== ARC_STACK_ALIGN (total_size
));
2847 /* Save computed information. */
2848 frame_info
->total_size
= total_size
;
2849 frame_info
->extra_size
= extra_size
;
2850 frame_info
->pretend_size
= pretend_size
;
2851 frame_info
->var_size
= var_size
;
2852 frame_info
->args_size
= args_size
;
2853 frame_info
->reg_size
= reg_size
;
2854 frame_info
->gmask
= gmask
;
2855 frame_info
->initialized
= reload_completed
;
2857 /* Ok, we're done. */
2861 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2865 arc_dwarf_emit_irq_save_regs (void)
2867 rtx tmp
, par
, insn
, reg
;
2870 par
= gen_rtx_SEQUENCE (VOIDmode
,
2871 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2872 + irq_ctrl_saved
.irq_save_blink
2873 + irq_ctrl_saved
.irq_save_lpcount
2876 /* Build the stack adjustment note for unwind info. */
2878 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2879 + irq_ctrl_saved
.irq_save_blink
2880 + irq_ctrl_saved
.irq_save_lpcount
);
2881 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2882 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2883 RTX_FRAME_RELATED_P (tmp
) = 1;
2884 XVECEXP (par
, 0, j
++) = tmp
;
2886 offset
-= UNITS_PER_WORD
;
2888 /* 1st goes LP_COUNT. */
2889 if (irq_ctrl_saved
.irq_save_lpcount
)
2891 reg
= gen_rtx_REG (SImode
, 60);
2892 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2893 tmp
= gen_frame_mem (SImode
, tmp
);
2894 tmp
= gen_rtx_SET (tmp
, reg
);
2895 RTX_FRAME_RELATED_P (tmp
) = 1;
2896 XVECEXP (par
, 0, j
++) = tmp
;
2897 offset
-= UNITS_PER_WORD
;
2900 /* 2nd goes BLINK. */
2901 if (irq_ctrl_saved
.irq_save_blink
)
2903 reg
= gen_rtx_REG (SImode
, 31);
2904 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2905 tmp
= gen_frame_mem (SImode
, tmp
);
2906 tmp
= gen_rtx_SET (tmp
, reg
);
2907 RTX_FRAME_RELATED_P (tmp
) = 1;
2908 XVECEXP (par
, 0, j
++) = tmp
;
2909 offset
-= UNITS_PER_WORD
;
2912 /* Build the parallel of the remaining registers recorded as saved
2914 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
2916 reg
= gen_rtx_REG (SImode
, i
);
2917 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2918 tmp
= gen_frame_mem (SImode
, tmp
);
2919 tmp
= gen_rtx_SET (tmp
, reg
);
2920 RTX_FRAME_RELATED_P (tmp
) = 1;
2921 XVECEXP (par
, 0, j
++) = tmp
;
2922 offset
-= UNITS_PER_WORD
;
2925 /* Dummy insn used to anchor the dwarf info. */
2926 insn
= emit_insn (gen_stack_irq_dwarf());
2927 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
2928 RTX_FRAME_RELATED_P (insn
) = 1;
2931 /* Helper for prologue: emit frame store with pre_modify or pre_dec to
2932 save register REG on stack. An initial offset OFFSET can be passed
2936 frame_save_reg (rtx reg
, HOST_WIDE_INT offset
)
2942 rtx tmp
= plus_constant (Pmode
, stack_pointer_rtx
,
2943 offset
- GET_MODE_SIZE (GET_MODE (reg
)));
2944 addr
= gen_frame_mem (GET_MODE (reg
),
2945 gen_rtx_PRE_MODIFY (Pmode
,
2950 addr
= gen_frame_mem (GET_MODE (reg
), gen_rtx_PRE_DEC (Pmode
,
2951 stack_pointer_rtx
));
2952 frame_move_inc (addr
, reg
, stack_pointer_rtx
, 0);
2954 return GET_MODE_SIZE (GET_MODE (reg
)) - offset
;
2957 /* Helper for epilogue: emit frame load with post_modify or post_inc
2958 to restore register REG from stack. The initial offset is passed
2962 frame_restore_reg (rtx reg
, HOST_WIDE_INT offset
)
2968 rtx tmp
= plus_constant (Pmode
, stack_pointer_rtx
,
2969 offset
+ GET_MODE_SIZE (GET_MODE (reg
)));
2970 addr
= gen_frame_mem (GET_MODE (reg
),
2971 gen_rtx_POST_MODIFY (Pmode
,
2976 addr
= gen_frame_mem (GET_MODE (reg
), gen_rtx_POST_INC (Pmode
,
2977 stack_pointer_rtx
));
2978 insn
= frame_move_inc (reg
, addr
, stack_pointer_rtx
, 0);
2979 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2981 if (reg
== frame_pointer_rtx
)
2982 add_reg_note (insn
, REG_CFA_DEF_CFA
,
2983 plus_constant (Pmode
, stack_pointer_rtx
,
2984 GET_MODE_SIZE (GET_MODE (reg
)) + offset
));
2986 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
2987 gen_rtx_SET (stack_pointer_rtx
,
2988 plus_constant (Pmode
, stack_pointer_rtx
,
2989 GET_MODE_SIZE (GET_MODE (reg
))
2992 return GET_MODE_SIZE (GET_MODE (reg
)) + offset
;
2995 /* Check if we have a continous range to be save/restored with the
2996 help of enter/leave instructions. A vaild register range starts
2997 from $r13 and is up to (including) $r26. */
3000 arc_enter_leave_p (unsigned int gmask
)
3003 unsigned int rmask
= 0;
3008 for (regno
= ENTER_LEAVE_START_REG
;
3009 regno
<= ENTER_LEAVE_END_REG
&& (gmask
& (1L << regno
)); regno
++)
3010 rmask
|= 1L << regno
;
3018 /* ARC's prologue, save any needed call-saved regs (and call-used if
3019 this is an interrupt handler) for ARCompact ISA, using ST/STD
3023 arc_save_callee_saves (unsigned int gmask
,
3026 HOST_WIDE_INT offset
)
3029 int frame_allocated
= 0;
3031 /* The home-grown ABI says link register is saved first. */
3034 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3035 frame_allocated
+= frame_save_reg (reg
, offset
);
3039 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3041 for (int i
= 31; i
>= 0; i
--)
3043 machine_mode save_mode
= SImode
;
3046 && ((i
- 1) % 2 == 0)
3047 && ((gmask
& (1L << i
)) != 0)
3048 && ((gmask
& (1L << (i
- 1))) != 0))
3053 else if ((gmask
& (1L << i
)) == 0)
3056 reg
= gen_rtx_REG (save_mode
, i
);
3057 frame_allocated
+= frame_save_reg (reg
, offset
);
3061 /* Save frame pointer if needed. First save the FP on stack, if not
3062 autosaved. Unfortunately, I cannot add it to gmask and use the
3063 above loop to save fp because our ABI states fp goes aftert all
3064 registers are saved. */
3067 frame_allocated
+= frame_save_reg (frame_pointer_rtx
, offset
);
3071 /* Emit mov fp,sp. */
3072 if (arc_frame_pointer_needed ())
3073 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3075 return frame_allocated
;
3078 /* ARC's epilogue, restore any required call-saved regs (and call-used
3079 if it is for an interrupt handler) using LD/LDD instructions. */
3082 arc_restore_callee_saves (unsigned int gmask
,
3085 HOST_WIDE_INT offset
,
3086 HOST_WIDE_INT allocated
)
3089 int frame_deallocated
= 0;
3091 /* Emit mov fp,sp. */
3092 if (arc_frame_pointer_needed () && offset
)
3094 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3095 frame_deallocated
+= offset
;
3101 /* Any offset is taken care by previous if-statement. */
3102 gcc_assert (offset
== 0);
3103 frame_deallocated
+= frame_restore_reg (frame_pointer_rtx
, 0);
3108 /* No $fp involved, we need to do an add to set the $sp to the
3109 location of the first register. */
3110 frame_stack_add (offset
);
3111 frame_deallocated
+= offset
;
3115 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3117 for (int i
= 0; i
<= 31; i
++)
3119 machine_mode restore_mode
= SImode
;
3123 && ((gmask
& (1L << i
)) != 0)
3124 && ((gmask
& (1L << (i
+ 1))) != 0))
3125 restore_mode
= DImode
;
3126 else if ((gmask
& (1L << i
)) == 0)
3129 reg
= gen_rtx_REG (restore_mode
, i
);
3130 frame_deallocated
+= frame_restore_reg (reg
, 0);
3133 if (restore_mode
== DImode
)
3139 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3140 frame_deallocated
+= frame_restore_reg (reg
, allocated
3142 /* Consider as well the
3148 return frame_deallocated
;
3151 /* ARC prologue, save the registers using enter instruction. Leave
3152 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3156 arc_save_callee_enter (unsigned int gmask
,
3159 HOST_WIDE_INT offset
)
3161 int start_reg
= ENTER_LEAVE_START_REG
;
3162 int end_reg
= ENTER_LEAVE_END_REG
;
3163 int regno
, indx
, off
, nregs
;
3165 int frame_allocated
= 0;
3167 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
3170 end_reg
= regno
- 1;
3171 nregs
= end_reg
- start_reg
+ 1;
3172 nregs
+= save_blink
? 1 : 0;
3173 nregs
+= save_fp
? 1 : 0;
3176 frame_stack_add (offset
);
3178 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ (save_fp
? 1 : 0)
3182 reg
= gen_rtx_SET (stack_pointer_rtx
,
3183 plus_constant (Pmode
,
3185 nregs
* UNITS_PER_WORD
));
3186 RTX_FRAME_RELATED_P (reg
) = 1;
3187 XVECEXP (insn
, 0, indx
++) = reg
;
3188 off
= nregs
* UNITS_PER_WORD
;
3192 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3193 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3196 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3197 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3198 off
-= UNITS_PER_WORD
;
3202 for (regno
= start_reg
;
3204 regno
++, indx
++, off
-= UNITS_PER_WORD
)
3206 reg
= gen_rtx_REG (SImode
, regno
);
3207 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3210 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3211 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3212 gmask
= gmask
& ~(1L << regno
);
3217 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3220 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, frame_pointer_rtx
);
3221 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3222 off
-= UNITS_PER_WORD
;
3224 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (frame_pointer_rtx
,
3226 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3230 gcc_assert (off
== 0);
3231 insn
= frame_insn (insn
);
3233 add_reg_note (insn
, REG_INC
, stack_pointer_rtx
);
3235 frame_allocated
= nregs
* UNITS_PER_WORD
;
3237 /* offset is a negative number, make sure we add it. */
3238 return frame_allocated
- offset
;
3241 /* ARC epilogue, restore the registers using leave instruction. An
3242 initial offset is passed in OFFSET. Besides restoring an register
3243 range, leave can also restore $blink (RESTORE_BLINK), or $fp
3244 (RESTORE_FP), and can automatic return (RETURN_P). */
3247 arc_restore_callee_leave (unsigned int gmask
,
3251 HOST_WIDE_INT offset
)
3253 int start_reg
= ENTER_LEAVE_START_REG
;
3254 int end_reg
= ENTER_LEAVE_END_REG
;
3255 int regno
, indx
, off
, nregs
;
3257 int frame_allocated
= 0;
3259 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
3262 end_reg
= regno
- 1;
3263 nregs
= end_reg
- start_reg
+ 1;
3264 nregs
+= restore_blink
? 1 : 0;
3265 nregs
+= restore_fp
? 1 : 0;
3267 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ 1
3268 + (return_p
? 1 : 0)));
3272 XVECEXP (insn
, 0, indx
++) = ret_rtx
;
3276 /* I cannot emit set (sp, fp) here as cselib expects a single sp
3277 set and not two. Thus, use the offset, and change sp adjust
3279 frame_allocated
+= offset
;
3282 if (offset
&& !restore_fp
)
3284 /* This add is only emmited when we do not restore fp with leave
3286 frame_stack_add (offset
);
3287 frame_allocated
+= offset
;
3291 reg
= gen_rtx_SET (stack_pointer_rtx
,
3292 plus_constant (Pmode
,
3294 offset
+ nregs
* UNITS_PER_WORD
));
3295 RTX_FRAME_RELATED_P (reg
) = 1;
3296 XVECEXP (insn
, 0, indx
++) = reg
;
3297 off
= nregs
* UNITS_PER_WORD
;
3301 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3302 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3305 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3306 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3307 off
-= UNITS_PER_WORD
;
3310 for (regno
= start_reg
;
3312 regno
++, indx
++, off
-= UNITS_PER_WORD
)
3314 reg
= gen_rtx_REG (SImode
, regno
);
3315 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3318 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3319 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3320 gmask
= gmask
& ~(1L << regno
);
3325 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3328 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (frame_pointer_rtx
, mem
);
3329 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3330 off
-= UNITS_PER_WORD
;
3333 gcc_assert (off
== 0);
3336 insn
= emit_jump_insn (insn
);
3337 RTX_FRAME_RELATED_P (insn
) = 1;
3340 insn
= frame_insn (insn
);
3342 add_reg_note (insn
, REG_INC
, stack_pointer_rtx
);
3344 /* Dwarf related info. */
3347 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3348 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3349 plus_constant (Pmode
, stack_pointer_rtx
,
3350 offset
+ nregs
* UNITS_PER_WORD
));
3354 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3355 gen_rtx_SET (stack_pointer_rtx
,
3356 plus_constant (Pmode
, stack_pointer_rtx
,
3357 nregs
* UNITS_PER_WORD
)));
3360 add_reg_note (insn
, REG_CFA_RESTORE
,
3361 gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3362 for (regno
= start_reg
; regno
<= end_reg
; regno
++)
3363 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, regno
));
3365 frame_allocated
+= nregs
* UNITS_PER_WORD
;
3367 return frame_allocated
;
3370 /* Millicode thunks implementation:
3371 Generates calls to millicodes for registers starting from r13 to r25
3372 Present Limitations:
3373 - Only one range supported. The remaining regs will have the ordinary
3374 st and ld instructions for store and loads. Hence a gmask asking
3375 to store r13-14, r16-r25 will only generate calls to store and
3376 load r13 to r14 while store and load insns will be generated for
3377 r16 to r25 in the prologue and epilogue respectively.
3379 - Presently library only supports register ranges starting from r13.
3383 arc_save_callee_milli (unsigned int gmask
,
3386 HOST_WIDE_INT offset
,
3387 HOST_WIDE_INT reg_size
)
3391 int regno
, indx
, off
, nregs
;
3393 int frame_allocated
= 0;
3395 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
3398 end_reg
= regno
- 1;
3399 nregs
= end_reg
- start_reg
+ 1;
3400 gcc_assert (end_reg
> 14);
3403 /* Allocate space on stack for the registers, and take into account
3404 also the initial offset. The registers will be saved using
3405 offsets. N.B. OFFSET is a negative number. */
3408 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3409 frame_allocated
+= frame_save_reg (reg
, offset
);
3413 if (reg_size
|| offset
)
3415 frame_stack_add (offset
- reg_size
);
3416 frame_allocated
+= nregs
* UNITS_PER_WORD
- offset
;
3420 /* Start generate millicode call. */
3421 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ 1));
3424 /* This is a call, we clobber blink. */
3425 XVECEXP (insn
, 0, nregs
) =
3426 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3428 for (regno
= start_reg
, indx
= 0, off
= 0;
3430 regno
++, indx
++, off
+= UNITS_PER_WORD
)
3432 reg
= gen_rtx_REG (SImode
, regno
);
3433 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3436 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3437 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3438 gmask
= gmask
& ~(1L << regno
);
3440 insn
= frame_insn (insn
);
3442 /* Add DWARF info. */
3443 for (regno
= start_reg
, off
= 0;
3445 regno
++, off
+= UNITS_PER_WORD
)
3447 reg
= gen_rtx_REG (SImode
, regno
);
3448 mem
= gen_rtx_MEM (SImode
, plus_constant (Pmode
,
3449 stack_pointer_rtx
, off
));
3450 add_reg_note (insn
, REG_CFA_OFFSET
, gen_rtx_SET (mem
, reg
));
3454 /* In the case of millicode thunk, we need to restore the
3455 clobbered blink register. */
3456 if (arc_must_save_return_addr (cfun
))
3458 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
),
3460 plus_constant (Pmode
,
3465 /* Save remaining registers using st instructions. */
3466 for (regno
= 0; regno
<= 31; regno
++)
3468 if ((gmask
& (1L << regno
)) == 0)
3471 reg
= gen_rtx_REG (SImode
, regno
);
3472 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3475 frame_move_inc (mem
, reg
, stack_pointer_rtx
, 0);
3476 frame_allocated
+= UNITS_PER_WORD
;
3477 off
+= UNITS_PER_WORD
;
3480 /* Save frame pointer if needed. First save the FP on stack, if not
3481 autosaved. Unfortunately, I cannot add it to gmask and use the
3482 above loop to save fp because our ABI states fp goes aftert all
3483 registers are saved. */
3485 frame_allocated
+= frame_save_reg (frame_pointer_rtx
, offset
);
3487 /* Emit mov fp,sp. */
3488 if (arc_frame_pointer_needed ())
3489 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3491 return frame_allocated
;
3494 /* Like the previous function but restore. */
3497 arc_restore_callee_milli (unsigned int gmask
,
3501 HOST_WIDE_INT offset
)
3505 int regno
, indx
, off
, nregs
;
3507 int frame_allocated
= 0;
3509 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
3512 end_reg
= regno
- 1;
3513 nregs
= end_reg
- start_reg
+ 1;
3514 gcc_assert (end_reg
> 14);
3516 /* Emit mov fp,sp. */
3517 if (arc_frame_pointer_needed () && offset
)
3519 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3520 frame_allocated
= offset
;
3525 frame_allocated
+= frame_restore_reg (frame_pointer_rtx
, 0);
3529 /* No fp involved, hence, we need to adjust the sp via an
3531 frame_stack_add (offset
);
3532 frame_allocated
+= offset
;
3536 /* Start generate millicode call. */
3537 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc ((return_p
? 1 : 0)
3543 /* sibling call, the blink is restored with the help of the
3544 value held into r12. */
3545 reg
= gen_rtx_REG (Pmode
, 12);
3546 XVECEXP (insn
, 0, indx
++) = ret_rtx
;
3547 XVECEXP (insn
, 0, indx
++) =
3548 gen_rtx_SET (stack_pointer_rtx
,
3549 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, reg
));
3550 frame_allocated
+= UNITS_PER_WORD
;
3554 /* This is a call, we clobber blink. */
3555 XVECEXP (insn
, 0, nregs
) =
3556 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3559 for (regno
= start_reg
, off
= 0;
3561 regno
++, indx
++, off
+= UNITS_PER_WORD
)
3563 reg
= gen_rtx_REG (SImode
, regno
);
3564 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3567 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3568 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3569 gmask
= gmask
& ~(1L << regno
);
3572 /* Restore remaining registers using LD instructions. */
3573 for (regno
= 0; regno
<= 31; regno
++)
3575 if ((gmask
& (1L << regno
)) == 0)
3578 reg
= gen_rtx_REG (SImode
, regno
);
3579 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3582 rtx tmp
= frame_move_inc (reg
, mem
, stack_pointer_rtx
, 0);
3583 add_reg_note (tmp
, REG_CFA_RESTORE
, reg
);
3584 off
+= UNITS_PER_WORD
;
3587 /* Emit millicode call. */
3590 reg
= gen_rtx_REG (Pmode
, 12);
3591 frame_insn (gen_rtx_SET (reg
, GEN_INT (off
)));
3592 frame_allocated
+= off
;
3593 insn
= emit_jump_insn (insn
);
3594 RTX_FRAME_RELATED_P (insn
) = 1;
3597 insn
= frame_insn (insn
);
3599 /* Add DWARF info. */
3600 for (regno
= start_reg
; regno
<= end_reg
; regno
++)
3602 reg
= gen_rtx_REG (SImode
, regno
);
3603 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3607 if (restore_blink
&& !return_p
)
3609 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3610 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, stack_pointer_rtx
,
3612 insn
= frame_insn (gen_rtx_SET (reg
, mem
));
3613 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3616 return frame_allocated
;
3619 /* Set up the stack and frame pointer (if desired) for the function. */
3622 arc_expand_prologue (void)
3625 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
3626 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
3627 unsigned int frame_size_to_allocate
;
3628 int first_offset
= 0;
3629 unsigned int fn_type
= arc_compute_function_type (cfun
);
3630 bool save_blink
= false;
3631 bool save_fp
= false;
3633 /* Naked functions don't have prologue. */
3634 if (ARC_NAKED_P (fn_type
))
3636 if (flag_stack_usage_info
)
3637 current_function_static_stack_size
= 0;
3641 /* Compute total frame size. */
3642 size
= arc_compute_frame_size ();
3644 if (flag_stack_usage_info
)
3645 current_function_static_stack_size
= size
;
3647 /* Keep track of frame size to be allocated. */
3648 frame_size_to_allocate
= size
;
3650 /* These cases shouldn't happen. Catch them now. */
3651 gcc_assert (!(size
== 0 && gmask
));
3653 /* Allocate space for register arguments if this is a variadic function. */
3654 if (frame
->pretend_size
!= 0)
3655 first_offset
= -frame
->pretend_size
;
3657 /* IRQ using automatic save mechanism will save the register before
3659 if (ARC_AUTO_IRQ_P (fn_type
)
3660 && !ARC_FAST_INTERRUPT_P (fn_type
))
3662 frame_stack_add (first_offset
);
3664 arc_dwarf_emit_irq_save_regs ();
3667 save_blink
= arc_must_save_return_addr (cfun
)
3668 && !ARC_AUTOBLINK_IRQ_P (fn_type
);
3669 save_fp
= arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type
);
3671 /* Use enter/leave only for non-interrupt functions. */
3672 if (TARGET_CODE_DENSITY
3673 && TARGET_CODE_DENSITY_FRAME
3674 && !ARC_AUTOFP_IRQ_P (fn_type
)
3675 && !ARC_AUTOBLINK_IRQ_P (fn_type
)
3676 && !ARC_INTERRUPT_P (fn_type
)
3677 && arc_enter_leave_p (gmask
))
3678 frame_size_to_allocate
-= arc_save_callee_enter (gmask
, save_blink
,
3681 else if (frame
->millicode_end_reg
> 14)
3682 frame_size_to_allocate
-= arc_save_callee_milli (gmask
, save_blink
,
3687 frame_size_to_allocate
-= arc_save_callee_saves (gmask
, save_blink
, save_fp
,
3690 /* Allocate the stack frame. */
3691 if (frame_size_to_allocate
> 0)
3693 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3694 /* If the frame pointer is needed, emit a special barrier that
3695 will prevent the scheduler from moving stores to the frame
3696 before the stack adjustment. */
3697 if (arc_frame_pointer_needed ())
3698 emit_insn (gen_stack_tie (stack_pointer_rtx
, hard_frame_pointer_rtx
));
3702 /* Do any necessary cleanup after a function to restore stack, frame,
3706 arc_expand_epilogue (int sibcall_p
)
3709 unsigned int fn_type
= arc_compute_function_type (cfun
);
3710 unsigned int size_to_deallocate
;
3712 int can_trust_sp_p
= !cfun
->calls_alloca
;
3714 bool restore_fp
= arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type
);
3715 bool restore_blink
= arc_must_save_return_addr (cfun
)
3716 && !ARC_AUTOBLINK_IRQ_P (fn_type
);
3717 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
3718 bool return_p
= !sibcall_p
&& fn_type
== ARC_FUNCTION_NORMAL
3719 && !cfun
->machine
->frame_info
.pretend_size
;
3720 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
3723 /* Naked functions don't have epilogue. */
3724 if (ARC_NAKED_P (fn_type
))
3727 size
= arc_compute_frame_size ();
3728 size_to_deallocate
= size
;
3730 first_offset
= size
- (frame
->pretend_size
+ frame
->reg_size
3731 + frame
->extra_size
);
3733 if (!can_trust_sp_p
)
3734 gcc_assert (arc_frame_pointer_needed ());
3736 if (TARGET_CODE_DENSITY
3737 && TARGET_CODE_DENSITY_FRAME
3738 && !ARC_AUTOFP_IRQ_P (fn_type
)
3739 && !ARC_AUTOBLINK_IRQ_P (fn_type
)
3740 && !ARC_INTERRUPT_P (fn_type
)
3741 && arc_enter_leave_p (gmask
))
3743 /* Using leave instruction. */
3744 size_to_deallocate
-= arc_restore_callee_leave (gmask
, restore_blink
,
3750 gcc_assert (size_to_deallocate
== 0);
3754 else if (frame
->millicode_end_reg
> 14)
3756 /* Using millicode calls. */
3757 size_to_deallocate
-= arc_restore_callee_milli (gmask
, restore_blink
,
3763 gcc_assert (size_to_deallocate
== 0);
3768 size_to_deallocate
-= arc_restore_callee_saves (gmask
, restore_blink
,
3771 size_to_deallocate
);
3773 /* Keep track of how much of the stack pointer we've restored. It
3774 makes the following a lot more readable. */
3775 restored
= size
- size_to_deallocate
;
3777 if (size
> restored
)
3778 frame_stack_add (size
- restored
);
3780 /* For frames that use __builtin_eh_return, the register defined by
3781 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
3782 On eh_return paths however, the register is set to the value that
3783 should be added to the stack pointer in order to restore the
3784 correct stack pointer for the exception handling frame.
3786 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
3787 this onto the stack for eh_return frames. */
3788 if (crtl
->calls_eh_return
)
3789 emit_insn (gen_add2_insn (stack_pointer_rtx
,
3790 EH_RETURN_STACKADJ_RTX
));
3792 /* Emit the return instruction. */
3793 if (sibcall_p
== FALSE
)
3794 emit_jump_insn (gen_simple_return ());
3797 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable
3798 construct to match either enter or leave instruction. Which one
3799 which is selected by PUSH_P argument. */
3802 arc_check_multi (rtx op
, bool push_p
)
3804 HOST_WIDE_INT len
= XVECLEN (op
, 0);
3805 unsigned int regno
, i
, start
;
3806 unsigned int memp
= push_p
? 0 : 1;
3813 elt
= XVECEXP (op
, 0, 0);
3814 if (!push_p
&& GET_CODE (elt
) == RETURN
)
3817 for (i
= start
, regno
= ENTER_LEAVE_START_REG
; i
< len
; i
++, regno
++)
3819 rtx elt
= XVECEXP (op
, 0, i
);
3822 if (GET_CODE (elt
) != SET
)
3824 mem
= XEXP (elt
, memp
);
3825 reg
= XEXP (elt
, 1 - memp
);
3831 /* Check for blink. */
3832 if (REGNO (reg
) == RETURN_ADDR_REGNUM
3835 else if (REGNO (reg
) == FRAME_POINTER_REGNUM
)
3837 else if (REGNO (reg
) != regno
)
3840 addr
= XEXP (mem
, 0);
3841 if (GET_CODE (addr
) == PLUS
)
3843 if (!rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
3844 || !CONST_INT_P (XEXP (addr
, 1)))
3849 if (!rtx_equal_p (stack_pointer_rtx
, addr
))
3856 /* Return rtx for the location of the return address on the stack,
3857 suitable for use in __builtin_eh_return. The new return address
3858 will be written to this location in order to redirect the return to
3859 the exception handler. Our ABI says the blink is pushed first on
3860 stack followed by an unknown number of register saves, and finally
3861 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the
3862 stack is not finalized. */
3865 arc_eh_return_address_location (rtx source
)
3869 struct arc_frame_info
*afi
;
3871 arc_compute_frame_size ();
3872 afi
= &cfun
->machine
->frame_info
;
3874 gcc_assert (crtl
->calls_eh_return
);
3875 gcc_assert (afi
->save_return_addr
);
3876 gcc_assert (afi
->extra_size
>= 4);
3878 /* The '-4' removes the size of the return address, which is
3879 included in the 'extra_size' field. */
3880 offset
= afi
->reg_size
+ afi
->extra_size
- 4;
3881 mem
= gen_frame_mem (Pmode
,
3882 plus_constant (Pmode
, frame_pointer_rtx
, offset
));
3884 /* The following should not be needed, and is, really a hack. The
3885 issue being worked around here is that the DSE (Dead Store
3886 Elimination) pass will remove this write to the stack as it sees
3887 a single store and no corresponding read. The read however
3888 occurs in the epilogue code, which is not added into the function
3889 rtl until a later pass. So, at the time of DSE, the decision to
3890 remove this store seems perfectly sensible. Marking the memory
3891 address as volatile obviously has the effect of preventing DSE
3892 from removing the store. */
3893 MEM_VOLATILE_P (mem
) = true;
3894 emit_move_insn (mem
, source
);
3899 /* Helper to generate unspec constant. */
3902 arc_unspec_offset (rtx loc
, int unspec
)
3904 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3908 /* !TARGET_BARREL_SHIFTER support. */
3909 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3913 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3915 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3917 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3918 (op0
, op1
, op2
, shift
));
3922 /* Output the assembler code for doing a shift.
3923 We go to a bit of trouble to generate efficient code as the ARC601 only has
3924 single bit shifts. This is taken from the h8300 port. We only have one
3925 mode of shifting and can't access individual bytes like the h8300 can, so
3926 this is greatly simplified (at the expense of not generating hyper-
3929 This function is not used if the variable shift insns are present. */
3931 /* FIXME: This probably can be done using a define_split in arc.md.
3932 Alternately, generate rtx rather than output instructions. */
3935 output_shift (rtx
*operands
)
3937 /* static int loopend_lab;*/
3938 rtx shift
= operands
[3];
3939 machine_mode mode
= GET_MODE (shift
);
3940 enum rtx_code code
= GET_CODE (shift
);
3941 const char *shift_one
;
3943 gcc_assert (mode
== SImode
);
3947 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3948 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3949 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3950 default: gcc_unreachable ();
3953 if (GET_CODE (operands
[2]) != CONST_INT
)
3955 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3962 n
= INTVAL (operands
[2]);
3964 /* Only consider the lower 5 bits of the shift count. */
3967 /* First see if we can do them inline. */
3968 /* ??? We could get better scheduling & shorter code (using short insns)
3969 by using splitters. Alas, that'd be even more verbose. */
3970 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3971 && dest_reg_operand (operands
[4], SImode
))
3973 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3974 for (n
-=3 ; n
>= 3; n
-= 3)
3975 output_asm_insn ("add3 %0,%4,%0", operands
);
3977 output_asm_insn ("add2 %0,%4,%0", operands
);
3979 output_asm_insn ("add %0,%0,%0", operands
);
3985 output_asm_insn (shift_one
, operands
);
3986 operands
[1] = operands
[0];
3989 /* See if we can use a rotate/and. */
3990 else if (n
== BITS_PER_WORD
- 1)
3995 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3998 /* The ARC doesn't have a rol insn. Use something else. */
3999 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
4002 /* The ARC doesn't have a rol insn. Use something else. */
4003 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
4009 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
4014 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
4017 #if 1 /* Need some scheduling comparisons. */
4018 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
4019 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
4021 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
4022 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
4027 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
4028 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
4030 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
4031 "and %0,%0,1\n\trlc %0,%0", operands
);
4038 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
4039 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
4044 operands
[2] = GEN_INT (n
);
4045 output_asm_insn ("mov.f lp_count, %2", operands
);
4049 output_asm_insn ("lpnz\t2f", operands
);
4050 output_asm_insn (shift_one
, operands
);
4051 output_asm_insn ("nop", operands
);
4052 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
4061 /* Nested function support. */
4063 /* Output assembler code for a block containing the constant parts of
4064 a trampoline, leaving space for variable parts. A trampoline looks
4070 .word function's address
4071 .word static chain value
4076 arc_asm_trampoline_template (FILE *f
)
4078 asm_fprintf (f
, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG
);
4079 asm_fprintf (f
, "\tld\t%s,[pcl,12]\n", reg_names
[STATIC_CHAIN_REGNUM
]);
4080 asm_fprintf (f
, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG
);
4081 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
4082 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
4085 /* Emit RTL insns to initialize the variable parts of a trampoline.
4086 FNADDR is an RTX for the address of the function's pure code. CXT
4087 is an RTX for the static chain value for the function.
4089 The fastest trampoline to execute for trampolines within +-8KB of CTX
4093 j [limm] 0x20200f80 limm
4095 and that would also be faster to write to the stack by computing
4096 the offset from CTX to TRAMP at compile time. However, it would
4097 really be better to get rid of the high cost of cache invalidation
4098 when generating trampolines, which requires that the code part of
4099 trampolines stays constant, and additionally either making sure
4100 that no executable code but trampolines is on the stack, no icache
4101 entries linger for the area of the stack from when before the stack
4102 was allocated, and allocating trampolines in trampoline-only cache
4103 lines or allocate trampolines fram a special pool of pre-allocated
4107 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
4109 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
4111 emit_block_move (tramp
, assemble_trampoline_template (),
4112 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
4113 emit_move_insn (adjust_address (tramp
, SImode
, 8), fnaddr
);
4114 emit_move_insn (adjust_address (tramp
, SImode
, 12), cxt
);
4115 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__clear_cache"),
4116 LCT_NORMAL
, VOIDmode
, XEXP (tramp
, 0), Pmode
,
4117 plus_constant (Pmode
, XEXP (tramp
, 0), TRAMPOLINE_SIZE
),
4121 /* Add the given function declaration to emit code in JLI section. */
4124 arc_add_jli_section (rtx pat
)
4128 arc_jli_section
*sec
= arc_jli_sections
, *new_section
;
4129 tree decl
= SYMBOL_REF_DECL (pat
);
4136 /* For fixed locations do not generate the jli table entry. It
4137 should be provided by the user as an asm file. */
4138 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
4139 if (lookup_attribute ("jli_fixed", attrs
))
4143 name
= XSTR (pat
, 0);
4145 /* Don't insert the same symbol twice. */
4148 if(strcmp (name
, sec
->name
) == 0)
4153 /* New name, insert it. */
4154 new_section
= (arc_jli_section
*) xmalloc (sizeof (arc_jli_section
));
4155 gcc_assert (new_section
!= NULL
);
4156 new_section
->name
= name
;
4157 new_section
->next
= arc_jli_sections
;
4158 arc_jli_sections
= new_section
;
4161 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4162 reset when we output the scaled address. */
4163 static int output_scaled
= 0;
4165 /* Set when we force sdata output. */
4166 static int output_sdata
= 0;
4168 /* Print operand X (an rtx) in assembler syntax to file FILE.
4169 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4170 For `%' followed by punctuation, CODE is the punctuation and X is null. */
4171 /* In final.c:output_asm_insn:
4174 'c' : constant address if CONSTANT_ADDRESS_P
4180 'p': bit Position of lsb
4181 's': size of bit field
4182 '#': condbranch delay slot suffix
4183 '*': jump delay slot suffix
4184 '?' : nonjump-insn suffix for conditional execution or short instruction
4185 '!' : jump / call suffix for conditional execution or short instruction
4186 '`': fold constant inside unary o-perator, re-recognize, and emit.
4190 'S': JLI instruction
4191 'j': used by mov instruction to properly emit jli related labels.
4192 'B': Branch comparison operand - suppress sda reference
4193 'H': Most significant word
4194 'L': Least significant word
4195 'A': ASCII decimal representation of floating point value
4196 'U': Load/store update or scaling indicator
4197 'V': cache bypass indicator for volatile
4202 'o': original symbol - no @ prepending. */
4205 arc_print_operand (FILE *file
, rtx x
, int code
)
4210 if (GET_CODE (x
) == CONST_INT
)
4211 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
4213 output_operand_lossage ("invalid operand to %%Z code");
4218 if (GET_CODE (x
) == CONST_INT
)
4219 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
4221 output_operand_lossage ("invalid operand to %%z code");
4226 if (GET_CODE (x
) == CONST_INT
)
4227 fprintf (file
, "%ld", INTVAL (x
) );
4229 output_operand_lossage ("invalid operands to %%c code");
4234 if (GET_CODE (x
) == CONST_INT
)
4235 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
4237 output_operand_lossage ("invalid operand to %%M code");
4242 if (GET_CODE (x
) == CONST_INT
)
4243 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
4245 output_operand_lossage ("invalid operand to %%p code");
4249 if (GET_CODE (x
) == CONST_INT
)
4251 HOST_WIDE_INT i
= INTVAL (x
);
4252 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
4253 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
4256 output_operand_lossage ("invalid operand to %%s code");
4260 /* Conditional branches depending on condition codes.
4261 Note that this is only for branches that were known to depend on
4262 condition codes before delay slot scheduling;
4263 out-of-range brcc / bbit expansions should use '*'.
4264 This distinction is important because of the different
4265 allowable delay slot insns and the output of the delay suffix
4266 for TARGET_AT_DBR_COND_EXEC. */
4268 /* Unconditional branches / branches not depending on condition codes.
4269 This could also be a CALL_INSN.
4270 Output the appropriate delay slot suffix. */
4271 if (final_sequence
&& final_sequence
->len () != 1)
4273 rtx_insn
*jump
= final_sequence
->insn (0);
4274 rtx_insn
*delay
= final_sequence
->insn (1);
4276 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
4277 if (delay
->deleted ())
4279 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
4280 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
4281 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
4282 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
4289 case '?' : /* with leading "." */
4290 case '!' : /* without leading "." */
4291 /* This insn can be conditionally executed. See if the ccfsm machinery
4292 says it should be conditionalized.
4293 If it shouldn't, we'll check the compact attribute if this insn
4294 has a short variant, which may be used depending on code size and
4295 alignment considerations. */
4296 if (current_insn_predicate
)
4297 arc_ccfsm_current
.cc
4298 = get_arc_condition_code (current_insn_predicate
);
4299 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
4301 /* Is this insn in a delay slot sequence? */
4302 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
4303 || current_insn_predicate
4304 || CALL_P (final_sequence
->insn (0))
4305 || simplejump_p (final_sequence
->insn (0)))
4307 /* This insn isn't in a delay slot sequence, or conditionalized
4308 independently of its position in a delay slot. */
4309 fprintf (file
, "%s%s",
4310 code
== '?' ? "." : "",
4311 arc_condition_codes
[arc_ccfsm_current
.cc
]);
4312 /* If this is a jump, there are still short variants. However,
4313 only beq_s / bne_s have the same offset range as b_s,
4314 and the only short conditional returns are jeq_s and jne_s. */
4316 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
4317 || arc_ccfsm_current
.cc
== ARC_CC_NE
4318 || 0 /* FIXME: check if branch in 7 bit range. */))
4319 output_short_suffix (file
);
4321 else if (code
== '!') /* Jump with delay slot. */
4322 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
4323 else /* An Instruction in a delay slot of a jump or call. */
4325 rtx jump
= XVECEXP (final_sequence
, 0, 0);
4326 rtx insn
= XVECEXP (final_sequence
, 0, 1);
4328 /* If the insn is annulled and is from the target path, we need
4329 to inverse the condition test. */
4330 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
4332 if (INSN_FROM_TARGET_P (insn
))
4333 fprintf (file
, "%s%s",
4334 code
== '?' ? "." : "",
4335 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
4337 fprintf (file
, "%s%s",
4338 code
== '?' ? "." : "",
4339 arc_condition_codes
[arc_ccfsm_current
.cc
]);
4340 if (arc_ccfsm_current
.state
== 5)
4341 arc_ccfsm_current
.state
= 0;
4344 /* This insn is executed for either path, so don't
4345 conditionalize it at all. */
4346 output_short_suffix (file
);
4351 output_short_suffix (file
);
4354 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
4357 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
4360 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
4361 (get_arc_condition_code (x
))],
4365 /* Write second word of DImode or DFmode reference,
4366 register or memory. */
4367 if (GET_CODE (x
) == REG
)
4368 fputs (reg_names
[REGNO (x
)+1], file
);
4369 else if (GET_CODE (x
) == MEM
)
4373 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4374 PRE_MODIFY, we will have handled the first word already;
4375 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4376 first word will be done later. In either case, the access
4377 to the first word will do the modify, and we only have
4378 to add an offset of four here. */
4379 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
4380 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
4381 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
4382 || GET_CODE (XEXP (x
, 0)) == POST_INC
4383 || GET_CODE (XEXP (x
, 0)) == POST_DEC
4384 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
4385 output_address (VOIDmode
,
4386 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
4387 else if (output_scaled
)
4389 rtx addr
= XEXP (x
, 0);
4390 int size
= GET_MODE_SIZE (GET_MODE (x
));
4392 output_address (VOIDmode
,
4393 plus_constant (Pmode
, XEXP (addr
, 0),
4394 ((INTVAL (XEXP (addr
, 1)) + 4)
4395 >> (size
== 2 ? 1 : 2))));
4399 output_address (VOIDmode
,
4400 plus_constant (Pmode
, XEXP (x
, 0), 4));
4404 output_operand_lossage ("invalid operand to %%R code");
4408 if (GET_CODE (x
) == SYMBOL_REF
4409 && arc_is_jli_call_p (x
))
4411 if (SYMBOL_REF_DECL (x
))
4413 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4414 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4416 if (lookup_attribute ("jli_fixed", attrs
))
4418 /* No special treatment for jli_fixed functions. */
4421 fprintf (file
, "%ld\t; @",
4422 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4423 assemble_name (file
, XSTR (x
, 0));
4427 fprintf (file
, "@__jli.");
4428 assemble_name (file
, XSTR (x
, 0));
4430 arc_add_jli_section (x
);
4433 if (GET_CODE (x
) == SYMBOL_REF
4434 && arc_is_secure_call_p (x
))
4436 /* No special treatment for secure functions. */
4439 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4440 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4442 fprintf (file
, "%ld\t; @",
4443 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4444 assemble_name (file
, XSTR (x
, 0));
4448 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4451 output_addr_const (file
, x
);
4457 if (GET_CODE (x
) == REG
)
4459 /* L = least significant word, H = most significant word. */
4460 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
4461 fputs (reg_names
[REGNO (x
)], file
);
4463 fputs (reg_names
[REGNO (x
)+1], file
);
4465 else if (GET_CODE (x
) == CONST_INT
4466 || GET_CODE (x
) == CONST_DOUBLE
)
4468 rtx first
, second
, word
;
4470 split_double (x
, &first
, &second
);
4472 if((WORDS_BIG_ENDIAN
) == 0)
4473 word
= (code
== 'L' ? first
: second
);
4475 word
= (code
== 'L' ? second
: first
);
4477 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
4480 output_operand_lossage ("invalid operand to %%H/%%L code");
4486 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
4487 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
4489 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
4490 fprintf (file
, "%s", str
);
4494 /* Output a load/store with update indicator if appropriate. */
4495 if (GET_CODE (x
) == MEM
)
4497 rtx addr
= XEXP (x
, 0);
4498 switch (GET_CODE (addr
))
4500 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
4501 fputs (".a", file
); break;
4502 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
4503 fputs (".ab", file
); break;
4505 /* Are we using a scaled index? */
4506 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4507 fputs (".as", file
);
4508 /* Can we use a scaled offset? */
4509 else if (CONST_INT_P (XEXP (addr
, 1))
4510 && GET_MODE_SIZE (GET_MODE (x
)) > 1
4511 && (!(INTVAL (XEXP (addr
, 1))
4512 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
4513 /* Does it make a difference? */
4514 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
4515 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
4517 fputs (".as", file
);
4523 if (legitimate_small_data_address_p (addr
)
4524 && GET_MODE_SIZE (GET_MODE (x
)) > 1)
4526 int align
= get_symbol_alignment (addr
);
4528 switch (GET_MODE (x
))
4537 if (align
&& ((align
& mask
) == 0))
4538 fputs (".as", file
);
4544 gcc_assert (CONSTANT_P (addr
)); break;
4548 output_operand_lossage ("invalid operand to %%U code");
4551 /* Output cache bypass indicator for a load/store insn. Volatile memory
4552 refs are defined to use the cache bypass mechanism. */
4553 if (GET_CODE (x
) == MEM
)
4555 if ((MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
4556 || arc_is_uncached_mem_p (x
))
4557 fputs (".di", file
);
4560 output_operand_lossage ("invalid operand to %%V code");
4565 /* Do nothing special. */
4568 fputs (reg_names
[REGNO (x
)]+1, file
);
4571 /* This punctuation character is needed because label references are
4572 printed in the output template using %l. This is a front end
4573 character, and when we want to emit a '@' before it, we have to use
4579 /* Output an operator. */
4580 switch (GET_CODE (x
))
4582 case PLUS
: fputs ("add", file
); return;
4583 case SS_PLUS
: fputs ("adds", file
); return;
4584 case AND
: fputs ("and", file
); return;
4585 case IOR
: fputs ("or", file
); return;
4586 case XOR
: fputs ("xor", file
); return;
4587 case MINUS
: fputs ("sub", file
); return;
4588 case SS_MINUS
: fputs ("subs", file
); return;
4589 case ASHIFT
: fputs ("asl", file
); return;
4590 case ASHIFTRT
: fputs ("asr", file
); return;
4591 case LSHIFTRT
: fputs ("lsr", file
); return;
4592 case ROTATERT
: fputs ("ror", file
); return;
4593 case MULT
: fputs ("mpy", file
); return;
4594 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
4595 case NEG
: fputs ("neg", file
); return;
4596 case SS_NEG
: fputs ("negs", file
); return;
4597 case NOT
: fputs ("not", file
); return; /* Unconditional. */
4599 fputs ("ext", file
); /* bmsk allows predication. */
4601 case SIGN_EXTEND
: /* Unconditional. */
4602 fputs ("sex", file
);
4604 switch (GET_MODE (XEXP (x
, 0)))
4606 case E_QImode
: fputs ("b", file
); return;
4607 case E_HImode
: fputs ("w", file
); return;
4612 if (GET_MODE (x
) != HImode
)
4614 fputs ("sat16", file
);
4617 output_operand_lossage ("invalid operand to %%O code"); return;
4619 if (GET_CODE (x
) == SYMBOL_REF
)
4621 assemble_name (file
, XSTR (x
, 0));
4626 if (TARGET_ANNOTATE_ALIGN
)
4627 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
4643 output_operand_lossage ("invalid operand output code");
4646 switch (GET_CODE (x
))
4649 fputs (reg_names
[REGNO (x
)], file
);
4653 rtx addr
= XEXP (x
, 0);
4654 int size
= GET_MODE_SIZE (GET_MODE (x
));
4656 if (legitimate_small_data_address_p (addr
))
4661 switch (GET_CODE (addr
))
4663 case PRE_INC
: case POST_INC
:
4664 output_address (VOIDmode
,
4665 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
4666 case PRE_DEC
: case POST_DEC
:
4667 output_address (VOIDmode
,
4668 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
4670 case PRE_MODIFY
: case POST_MODIFY
:
4671 output_address (VOIDmode
, XEXP (addr
, 1)); break;
4675 output_address (VOIDmode
,
4676 plus_constant (Pmode
, XEXP (addr
, 0),
4677 (INTVAL (XEXP (addr
, 1))
4678 >> (size
== 2 ? 1 : 2))));
4682 output_address (VOIDmode
, addr
);
4685 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
4686 arc_output_pic_addr_const (file
, addr
, code
);
4688 output_address (VOIDmode
, addr
);
4695 /* We handle SFmode constants here as output_addr_const doesn't. */
4696 if (GET_MODE (x
) == SFmode
)
4700 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
4701 fprintf (file
, "0x%08lx", l
);
4705 /* Let output_addr_const deal with it. */
4708 || (GET_CODE (x
) == CONST
4709 && GET_CODE (XEXP (x
, 0)) == UNSPEC
4710 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
4711 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
4712 || (GET_CODE (x
) == CONST
4713 && GET_CODE (XEXP (x
, 0)) == PLUS
4714 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
4715 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
4716 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
4717 arc_output_pic_addr_const (file
, x
, code
);
4719 output_addr_const (file
, x
);
4724 /* Print a memory address as an operand to reference that memory location. */
4727 arc_print_operand_address (FILE *file
, rtx addr
)
4729 register rtx base
, index
= 0;
4731 switch (GET_CODE (addr
))
4734 fputs (reg_names
[REGNO (addr
)], file
);
4738 fputs ("gp,", file
);
4739 output_addr_const (file
, addr
);
4741 fputs ("@sda", file
);
4745 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4746 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
4747 else if (CONST_INT_P (XEXP (addr
, 0)))
4748 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
4750 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
4752 gcc_assert (OBJECT_P (base
));
4753 arc_print_operand_address (file
, base
);
4754 if (CONSTANT_P (base
) && CONST_INT_P (index
))
4758 gcc_assert (OBJECT_P (index
));
4759 arc_print_operand_address (file
, index
);
4763 rtx c
= XEXP (addr
, 0);
4765 if ((GET_CODE (c
) == UNSPEC
4766 && (XINT (c
, 1) == UNSPEC_TLS_OFF
4767 || XINT (c
, 1) == UNSPEC_TLS_IE
))
4768 || (GET_CODE (c
) == PLUS
4769 && GET_CODE (XEXP (c
, 0)) == UNSPEC
4770 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
4771 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4773 arc_output_pic_addr_const (file
, c
, 0);
4776 gcc_assert (GET_CODE (c
) == PLUS
);
4777 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4778 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4780 output_address (VOIDmode
, XEXP (addr
, 0));
4786 /* We shouldn't get here as we've lost the mode of the memory object
4787 (which says how much to inc/dec by. */
4792 arc_output_pic_addr_const (file
, addr
, 0);
4794 output_addr_const (file
, addr
);
4799 /* Conditional execution support.
4801 This is based on the ARM port but for now is much simpler.
4803 A finite state machine takes care of noticing whether or not instructions
4804 can be conditionally executed, and thus decrease execution time and code
4805 size by deleting branch instructions. The fsm is controlled by
4806 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4807 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4808 insns also have a hand in this. */
4809 /* The way we leave dealing with non-anulled or annull-false delay slot
4810 insns to the consumer is awkward. */
4812 /* The state of the fsm controlling condition codes are:
4813 0: normal, do nothing special
4814 1: don't output this insn
4815 2: don't output this insn
4816 3: make insns conditional
4817 4: make insns conditional
4818 5: make insn conditional (only for outputting anulled delay slot insns)
4820 special value for cfun->machine->uid_ccfsm_state:
4821 6: return with but one insn before it since function start / call
4823 State transitions (state->state by whom, under what condition):
4824 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4826 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4827 by zero or more non-jump insns and an unconditional branch with
4828 the same target label as the condbranch.
4829 1 -> 3 branch patterns, after having not output the conditional branch
4830 2 -> 4 branch patterns, after having not output the conditional branch
4831 0 -> 5 branch patterns, for anulled delay slot insn.
4832 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4833 (the target label has CODE_LABEL_NUMBER equal to
4834 arc_ccfsm_target_label).
4835 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4836 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4837 5 -> 0 when outputting the delay slot insn
4839 If the jump clobbers the conditions then we use states 2 and 4.
4841 A similar thing can be done with conditional return insns.
4843 We also handle separating branches from sets of the condition code.
4844 This is done here because knowledge of the ccfsm state is required,
4845 we may not be outputting the branch. */
4847 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4848 before letting final output INSN. */
4851 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4853 /* BODY will hold the body of INSN. */
4856 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4857 an if/then/else), and things need to be reversed. */
4860 /* If we start with a return insn, we only succeed if we find another one. */
4861 int seeking_return
= 0;
4863 /* START_INSN will hold the insn from where we start looking. This is the
4864 first insn after the following code_label if REVERSE is true. */
4865 rtx_insn
*start_insn
= insn
;
4867 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4868 since they don't rely on a cmp preceding the. */
4869 enum attr_type jump_insn_type
;
4871 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4872 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4873 final_scan_insn which has `optimize' as a local. */
4874 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4877 /* Ignore notes and labels. */
4880 body
= PATTERN (insn
);
4881 /* If in state 4, check if the target branch is reached, in order to
4882 change back to state 0. */
4883 if (state
->state
== 4)
4885 if (insn
== state
->target_insn
)
4887 state
->target_insn
= NULL
;
4893 /* If in state 3, it is possible to repeat the trick, if this insn is an
4894 unconditional branch to a label, and immediately following this branch
4895 is the previous target label which is only used once, and the label this
4896 branch jumps to is not too far off. Or in other words "we've done the
4897 `then' part, see if we can do the `else' part." */
4898 if (state
->state
== 3)
4900 if (simplejump_p (insn
))
4902 start_insn
= next_nonnote_insn (start_insn
);
4903 if (GET_CODE (start_insn
) == BARRIER
)
4905 /* ??? Isn't this always a barrier? */
4906 start_insn
= next_nonnote_insn (start_insn
);
4908 if (GET_CODE (start_insn
) == CODE_LABEL
4909 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4910 && LABEL_NUSES (start_insn
) == 1)
4915 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4917 start_insn
= next_nonnote_insn (start_insn
);
4918 if (GET_CODE (start_insn
) == BARRIER
)
4919 start_insn
= next_nonnote_insn (start_insn
);
4920 if (GET_CODE (start_insn
) == CODE_LABEL
4921 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4922 && LABEL_NUSES (start_insn
) == 1)
4934 if (GET_CODE (insn
) != JUMP_INSN
4935 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4936 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4939 /* We can't predicate BRCC or loop ends.
4940 Also, when generating PIC code, and considering a medium range call,
4941 we can't predicate the call. */
4942 jump_insn_type
= get_attr_type (insn
);
4943 if (jump_insn_type
== TYPE_BRCC
4944 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4945 || jump_insn_type
== TYPE_LOOP_END
4946 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4949 /* This jump might be paralleled with a clobber of the condition codes,
4950 the jump should always come first. */
4951 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4952 body
= XVECEXP (body
, 0, 0);
4955 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4956 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4958 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4959 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4960 int then_not_else
= TRUE
;
4961 /* Nonzero if next insn must be the target label. */
4962 int next_must_be_target_label_p
;
4963 rtx_insn
*this_insn
= start_insn
;
4966 /* Register the insn jumped to. */
4969 if (!seeking_return
)
4970 label
= XEXP (SET_SRC (body
), 0);
4972 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4973 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4974 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4976 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4977 then_not_else
= FALSE
;
4979 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4981 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4984 then_not_else
= FALSE
;
4989 /* If this is a non-annulled branch with a delay slot, there is
4990 no need to conditionalize the delay slot. */
4991 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn
)))) == SEQUENCE
)
4992 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4994 this_insn
= NEXT_INSN (this_insn
);
4996 /* See how many insns this branch skips, and what kind of insns. If all
4997 insns are okay, and the label or unconditional branch to the same
4998 label is not too far away, succeed. */
4999 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
5000 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
5005 this_insn
= next_nonnote_insn (this_insn
);
5009 if (next_must_be_target_label_p
)
5011 if (GET_CODE (this_insn
) == BARRIER
)
5013 if (GET_CODE (this_insn
) == CODE_LABEL
5014 && this_insn
== label
)
5024 switch (GET_CODE (this_insn
))
5027 /* Succeed if it is the target label, otherwise fail since
5028 control falls in from somewhere else. */
5029 if (this_insn
== label
)
5039 /* Succeed if the following insn is the target label.
5041 If return insns are used then the last insn in a function
5042 will be a barrier. */
5043 next_must_be_target_label_p
= TRUE
;
5047 /* Can handle a call insn if there are no insns after it.
5048 IE: The next "insn" is the target label. We don't have to
5049 worry about delay slots as such insns are SEQUENCE's inside
5050 INSN's. ??? It is possible to handle such insns though. */
5051 if (get_attr_cond (this_insn
) == COND_CANUSE
)
5052 next_must_be_target_label_p
= TRUE
;
5058 scanbody
= PATTERN (this_insn
);
5060 /* If this is an unconditional branch to the same label, succeed.
5061 If it is to another label, do nothing. If it is conditional,
5063 /* ??? Probably, the test for the SET and the PC are
5066 if (GET_CODE (scanbody
) == SET
5067 && GET_CODE (SET_DEST (scanbody
)) == PC
)
5069 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
5070 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
5075 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
5077 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
5080 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
5086 else if (GET_CODE (scanbody
) == PARALLEL
)
5088 if (get_attr_cond (this_insn
) != COND_CANUSE
)
5094 scanbody
= PATTERN (this_insn
);
5096 /* We can only do this with insns that can use the condition
5097 codes (and don't set them). */
5098 if (GET_CODE (scanbody
) == SET
5099 || GET_CODE (scanbody
) == PARALLEL
)
5101 if (get_attr_cond (this_insn
) != COND_CANUSE
)
5104 /* We can't handle other insns like sequences. */
5116 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
5117 state
->target_label
= CODE_LABEL_NUMBER (label
);
5118 else if (seeking_return
|| state
->state
== 2)
5120 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
5122 this_insn
= next_nonnote_insn (this_insn
);
5124 gcc_assert (!this_insn
||
5125 (GET_CODE (this_insn
) != BARRIER
5126 && GET_CODE (this_insn
) != CODE_LABEL
));
5130 /* Oh dear! we ran off the end, give up. */
5131 extract_insn_cached (insn
);
5133 state
->target_insn
= NULL
;
5136 state
->target_insn
= this_insn
;
5141 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
5145 state
->cond
= XEXP (SET_SRC (body
), 0);
5146 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
5149 if (reverse
|| then_not_else
)
5150 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
5153 /* Restore recog_operand. Getting the attributes of other insns can
5154 destroy this array, but final.c assumes that it remains intact
5155 across this call; since the insn has been recognized already we
5156 call insn_extract direct. */
5157 extract_insn_cached (insn
);
5161 /* Record that we are currently outputting label NUM with prefix PREFIX.
5162 It it's the label we're looking for, reset the ccfsm machinery.
5164 Called from ASM_OUTPUT_INTERNAL_LABEL. */
5167 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
5169 if (state
->state
== 3 && state
->target_label
== num
5170 && !strcmp (prefix
, "L"))
5173 state
->target_insn
= NULL
;
5177 /* We are considering a conditional branch with the condition COND.
5178 Check if we want to conditionalize a delay slot insn, and if so modify
5179 the ccfsm state accordingly.
5180 REVERSE says branch will branch when the condition is false. */
5182 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
5183 struct arc_ccfsm
*state
)
5185 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
5187 state
= &arc_ccfsm_current
;
5189 gcc_assert (state
->state
== 0);
5190 if (seq_insn
!= jump
)
5192 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
5194 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
5195 && INSN_ANNULLED_BRANCH_P (jump
)
5196 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
5199 state
->cc
= get_arc_condition_code (cond
);
5201 arc_ccfsm_current
.cc
5202 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
5203 rtx pat
= PATTERN (insn
);
5204 if (GET_CODE (pat
) == COND_EXEC
)
5205 gcc_assert ((INSN_FROM_TARGET_P (insn
)
5206 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
5207 == get_arc_condition_code (XEXP (pat
, 0)));
5214 /* Update *STATE as we would when we emit INSN. */
5217 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
5219 enum attr_type type
;
5222 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
5223 else if (JUMP_P (insn
)
5224 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
5225 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
5226 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
5227 || ((type
== TYPE_UNCOND_BRANCH
5228 || type
== TYPE_RETURN
)
5229 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
5231 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
5232 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
5235 rtx src
= SET_SRC (PATTERN (insn
));
5236 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
5240 else if (arc_ccfsm_current
.state
== 5)
5241 arc_ccfsm_current
.state
= 0;
5244 /* Return true if the current insn, which is a conditional branch, is to be
5248 arc_ccfsm_branch_deleted_p (void)
5250 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
5253 /* Record a branch isn't output because subsequent insns can be
5257 arc_ccfsm_record_branch_deleted (void)
5259 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
5262 /* During insn output, indicate if the current insn is predicated. */
5265 arc_ccfsm_cond_exec_p (void)
5267 return (cfun
->machine
->prescan_initialized
5268 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
5271 /* When deciding if an insn should be output short, we want to know something
5272 about the following insns:
5273 - if another insn follows which we know we can output as a short insn
5274 before an alignment-sensitive point, we can output this insn short:
5275 the decision about the eventual alignment can be postponed.
5276 - if a to-be-aligned label comes next, we should output this insn such
5277 as to get / preserve 4-byte alignment.
5278 - if a likely branch without delay slot insn, or a call with an immediately
5279 following short insn comes next, we should out output this insn such as to
5280 get / preserve 2 mod 4 unalignment.
5281 - do the same for a not completely unlikely branch with a short insn
5282 following before any other branch / label.
5283 - in order to decide if we are actually looking at a branch, we need to
5284 call arc_ccfsm_advance.
5285 - in order to decide if we are looking at a short insn, we should know
5286 if it is conditionalized. To a first order of approximation this is
5287 the case if the state from arc_ccfsm_advance from before this insn
5288 indicates the insn is conditionalized. However, a further refinement
5289 could be to not conditionalize an insn if the destination register(s)
5290 is/are dead in the non-executed case. */
5291 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5292 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5293 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5296 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
5298 enum attr_iscompact iscompact
;
5302 iscompact
= get_attr_iscompact (insn
);
5303 if (iscompact
== ISCOMPACT_FALSE
)
5307 return (get_attr_length (insn
) & 2) != 0;
5310 /* When outputting an instruction (alternative) that can potentially be short,
5311 output the short suffix if the insn is in fact short, and update
5312 cfun->machine->unalign accordingly. */
5315 output_short_suffix (FILE *file
)
5317 rtx_insn
*insn
= current_output_insn
;
5319 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
5321 fprintf (file
, "_s");
5322 cfun
->machine
->unalign
^= 2;
5324 /* Restore recog_operand. */
5325 extract_insn_cached (insn
);
5328 /* Implement FINAL_PRESCAN_INSN. */
5331 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
5332 int noperands ATTRIBUTE_UNUSED
)
5334 if (TARGET_DUMPISIZE
)
5335 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
5337 if (!cfun
->machine
->prescan_initialized
)
5339 /* Clear lingering state from branch shortening. */
5340 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
5341 cfun
->machine
->prescan_initialized
= 1;
5343 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
5346 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5347 Frame pointer elimination is automatically handled.
5349 All eliminations are permissible. If we need a frame
5350 pointer, we must eliminate ARG_POINTER_REGNUM into
5351 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5354 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
5356 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
5359 /* Define the offset between two registers, one to be eliminated, and
5360 the other its replacement, at the start of a routine. */
5363 arc_initial_elimination_offset (int from
, int to
)
5365 if (!cfun
->machine
->frame_info
.initialized
)
5366 arc_compute_frame_size ();
5368 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
5370 return (cfun
->machine
->frame_info
.extra_size
5371 + cfun
->machine
->frame_info
.reg_size
);
5374 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
5376 return (cfun
->machine
->frame_info
.total_size
5377 - cfun
->machine
->frame_info
.pretend_size
);
5380 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
5382 return (cfun
->machine
->frame_info
.total_size
5383 - (cfun
->machine
->frame_info
.pretend_size
5384 + cfun
->machine
->frame_info
.extra_size
5385 + cfun
->machine
->frame_info
.reg_size
));
5392 arc_frame_pointer_required (void)
5394 return cfun
->calls_alloca
|| crtl
->calls_eh_return
;
5398 /* Return the destination address of a branch. */
5401 branch_dest (rtx branch
)
5403 rtx pat
= PATTERN (branch
);
5404 rtx dest
= (GET_CODE (pat
) == PARALLEL
5405 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
5408 if (GET_CODE (dest
) == IF_THEN_ELSE
)
5409 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
5411 dest
= XEXP (dest
, 0);
5412 dest_uid
= INSN_UID (dest
);
5414 return INSN_ADDRESSES (dest_uid
);
5418 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5421 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
5423 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5424 This clears machine specific flags, so has to come first. */
5425 default_encode_section_info (decl
, rtl
, first
);
5427 /* Check if it is a function, and whether it has the
5428 [long/medium/short]_call attribute specified. */
5429 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5431 rtx symbol
= XEXP (rtl
, 0);
5432 int flags
= SYMBOL_REF_FLAGS (symbol
);
5434 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5435 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
5436 tree long_call_attr
= lookup_attribute ("long_call", attr
);
5437 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
5438 tree short_call_attr
= lookup_attribute ("short_call", attr
);
5440 if (long_call_attr
!= NULL_TREE
)
5441 flags
|= SYMBOL_FLAG_LONG_CALL
;
5442 else if (medium_call_attr
!= NULL_TREE
)
5443 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
5444 else if (short_call_attr
!= NULL_TREE
)
5445 flags
|= SYMBOL_FLAG_SHORT_CALL
;
5447 SYMBOL_REF_FLAGS (symbol
) = flags
;
5449 else if (TREE_CODE (decl
) == VAR_DECL
)
5451 rtx symbol
= XEXP (rtl
, 0);
5453 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5454 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
5456 tree sec_attr
= lookup_attribute ("section", attr
);
5459 const char *sec_name
5460 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
5461 if (strcmp (sec_name
, ".cmem") == 0
5462 || strcmp (sec_name
, ".cmem_shared") == 0
5463 || strcmp (sec_name
, ".cmem_private") == 0)
5464 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
5469 /* This is how to output a definition of an internal numbered label where
5470 PREFIX is the class of label and NUM is the number within the class. */
5472 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
5475 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
5476 default_internal_label (stream
, prefix
, labelno
);
5479 /* Set the cpu type and print out other fancy things,
5480 at the top of the file. */
5482 static void arc_file_start (void)
5484 default_file_start ();
5485 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
5487 /* Set some want to have build attributes. */
5488 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5490 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5491 TARGET_RF16
? 1 : 0);
5492 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5494 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5495 (arc_tp_regno
!= -1) ? 1 : 0);
5496 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5497 TARGET_NO_SDATA_SET
? 0 : 2);
5498 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5499 TARGET_OPTFPE
? 1 : 0);
5501 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5502 (arc_tune
< ARC_TUNE_CORE_3
) ? 2 :
5503 (arc_tune
== ARC_TUNE_CORE_3
? 3 : 4));
5506 /* Implement `TARGET_ASM_FILE_END'. */
5507 /* Outputs to the stdio stream FILE jli related text. */
5509 void arc_file_end (void)
5511 arc_jli_section
*sec
= arc_jli_sections
;
5515 fprintf (asm_out_file
, "\n");
5516 fprintf (asm_out_file
, "# JLI entry for function ");
5517 assemble_name (asm_out_file
, sec
->name
);
5518 fprintf (asm_out_file
, "\n\t.section .jlitab, \"axG\", @progbits, "
5520 assemble_name (asm_out_file
, sec
->name
);
5521 fprintf (asm_out_file
,", comdat\n");
5523 fprintf (asm_out_file
, "\t.align\t4\n");
5524 fprintf (asm_out_file
, "__jli.");
5525 assemble_name (asm_out_file
, sec
->name
);
5526 fprintf (asm_out_file
, ":\n\t.weak __jli.");
5527 assemble_name (asm_out_file
, sec
->name
);
5528 fprintf (asm_out_file
, "\n\tb\t@");
5529 assemble_name (asm_out_file
, sec
->name
);
5530 fprintf (asm_out_file
, "\n");
5533 file_end_indicate_exec_stack ();
5536 /* Cost functions. */
5538 /* Compute a (partial) cost for rtx X. Return true if the complete
5539 cost has been computed, and false if subexpressions should be
5540 scanned. In either case, *TOTAL contains the cost result. */
5543 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
5544 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
5546 int code
= GET_CODE (x
);
5550 /* Small integers are as cheap as registers. */
5553 bool nolimm
= false; /* Can we do without long immediate? */
5554 bool fast
= false; /* Is the result available immediately? */
5555 bool condexec
= false; /* Does this allow conditiobnal execution? */
5556 bool compact
= false; /* Is a 16 bit opcode available? */
5557 /* CONDEXEC also implies that we can have an unconditional
5558 3-address operation. */
5560 nolimm
= compact
= condexec
= false;
5561 if (UNSIGNED_INT6 (INTVAL (x
)))
5562 nolimm
= condexec
= compact
= true;
5565 if (SMALL_INT (INTVAL (x
)))
5566 nolimm
= fast
= true;
5569 case AND
: /* bclr, bmsk, ext[bw] */
5570 if (satisfies_constraint_Ccp (x
) /* bclr */
5571 || satisfies_constraint_C1p (x
) /* bmsk */)
5572 nolimm
= fast
= condexec
= compact
= true;
5574 case IOR
: /* bset */
5575 if (satisfies_constraint_C0p (x
)) /* bset */
5576 nolimm
= fast
= condexec
= compact
= true;
5579 if (satisfies_constraint_C0p (x
)) /* bxor */
5580 nolimm
= fast
= condexec
= true;
5583 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
5589 /* FIXME: Add target options to attach a small cost if
5590 condexec / compact is not true. */
5599 /* 4 byte values can be fetched as immediate constants -
5600 let's give that the cost of an extra insn. */
5604 *total
= COSTS_N_INSNS (1);
5613 *total
= COSTS_N_INSNS (1);
5616 split_double (x
, &first
, &second
);
5617 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
5618 + !SMALL_INT (INTVAL (second
)));
5622 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5623 If we need more than 12 insns to do a multiply, then go out-of-line,
5624 since the call overhead will be < 10% of the cost of the multiply. */
5628 if (TARGET_BARREL_SHIFTER
)
5630 /* If we want to shift a constant, we need a LIMM. */
5631 /* ??? when the optimizers want to know if a constant should be
5632 hoisted, they ask for the cost of the constant. OUTER_CODE is
5633 insufficient context for shifts since we don't know which operand
5634 we are looking at. */
5635 if (CONSTANT_P (XEXP (x
, 0)))
5637 *total
+= (COSTS_N_INSNS (2)
5638 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
5642 *total
= COSTS_N_INSNS (1);
5644 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5645 *total
= COSTS_N_INSNS (16);
5648 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
5649 /* ??? want_to_gcse_p can throw negative shift counts at us,
5650 and then panics when it gets a negative cost as result.
5651 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5660 *total
= COSTS_N_INSNS(30);
5662 *total
= COSTS_N_INSNS(1);
5666 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
5667 *total
= COSTS_N_INSNS (1);
5669 *total
= arc_multcost
;
5670 /* We do not want synth_mult sequences when optimizing
5672 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
5673 *total
= COSTS_N_INSNS (1);
5675 *total
= COSTS_N_INSNS (2);
5678 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
5679 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
5680 || (GET_CODE (XEXP (x
, 0)) == MULT
5681 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
5683 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
5684 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
5689 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
5690 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
5691 || (GET_CODE (XEXP (x
, 1)) == MULT
5692 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
5694 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
5695 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
5701 rtx op0
= XEXP (x
, 0);
5702 rtx op1
= XEXP (x
, 1);
5704 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
5705 && XEXP (op0
, 1) == const1_rtx
)
5707 /* btst / bbit0 / bbit1:
5708 Small integers and registers are free; everything else can
5709 be put in a register. */
5710 mode
= GET_MODE (XEXP (op0
, 0));
5711 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5712 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5715 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5716 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5719 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5723 if (GET_CODE (op1
) == NEG
)
5725 /* op0 might be constant, the inside of op1 is rather
5726 unlikely to be so. So swapping the operands might lower
5728 mode
= GET_MODE (op0
);
5729 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5730 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5735 if (outer_code
== IF_THEN_ELSE
5736 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5737 && XEXP (x
, 1) == const0_rtx
5738 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5740 /* btst / bbit0 / bbit1:
5741 Small integers and registers are free; everything else can
5742 be put in a register. */
5743 rtx op0
= XEXP (x
, 0);
5745 mode
= GET_MODE (XEXP (op0
, 0));
5746 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5747 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5751 /* scc_insn expands into two insns. */
5752 case GTU
: case GEU
: case LEU
:
5754 *total
+= COSTS_N_INSNS (1);
5756 case LTU
: /* might use adc. */
5758 *total
+= COSTS_N_INSNS (1) - 1;
5765 /* Return true if ADDR is a valid pic address.
5766 A valid pic address on arc should look like
5767 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5770 arc_legitimate_pic_addr_p (rtx addr
)
5772 if (GET_CODE (addr
) != CONST
)
5775 addr
= XEXP (addr
, 0);
5778 if (GET_CODE (addr
) == PLUS
)
5780 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5782 addr
= XEXP (addr
, 0);
5785 if (GET_CODE (addr
) != UNSPEC
5786 || XVECLEN (addr
, 0) != 1)
5789 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5790 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5791 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5792 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5793 && XINT (addr
, 1) != UNSPEC_TLS_GD
5794 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5797 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5798 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5806 /* Return true if OP contains a symbol reference. */
5809 symbolic_reference_mentioned_p (rtx op
)
5811 register const char *fmt
;
5814 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5817 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5818 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5824 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5825 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5829 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5836 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5837 If SKIP_LOCAL is true, skip symbols that bind locally.
5838 This is used further down in this file, and, without SKIP_LOCAL,
5839 in the addsi3 / subsi3 expanders when generating PIC code. */
5842 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5844 register const char *fmt
;
5847 if (GET_CODE(op
) == UNSPEC
)
5850 if (GET_CODE (op
) == SYMBOL_REF
)
5852 if (SYMBOL_REF_TLS_MODEL (op
))
5856 tree decl
= SYMBOL_REF_DECL (op
);
5857 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5860 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5861 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5867 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5868 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5873 else if (fmt
[i
] == 'e'
5874 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5882 /* The __tls_get_attr symbol. */
5883 static GTY(()) rtx arc_tls_symbol
;
5885 /* Emit a call to __tls_get_addr. TI is the argument to this function.
5886 RET is an RTX for the return value location. The entire insn sequence
5890 arc_call_tls_get_addr (rtx ti
)
5892 rtx arg
= gen_rtx_REG (Pmode
, R0_REG
);
5893 rtx ret
= gen_rtx_REG (Pmode
, R0_REG
);
5897 if (!arc_tls_symbol
)
5898 arc_tls_symbol
= init_one_libfunc ("__tls_get_addr");
5900 emit_move_insn (arg
, ti
);
5901 fn
= gen_rtx_MEM (SImode
, arc_tls_symbol
);
5902 insn
= emit_call_insn (gen_call_value (ret
, fn
, const0_rtx
));
5903 RTL_CONST_CALL_P (insn
) = 1;
5904 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), ret
);
5905 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), arg
);
5910 #define DTPOFF_ZERO_SYM ".tdata"
5912 /* Return a legitimized address for ADDR,
5913 which is a SYMBOL_REF with tls_model MODEL. */
5916 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5920 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5921 model
= TLS_MODEL_LOCAL_EXEC
;
5924 /* The TP pointer needs to be set. */
5925 gcc_assert (arc_tp_regno
!= -1);
5929 case TLS_MODEL_GLOBAL_DYNAMIC
:
5930 tmp
= gen_reg_rtx (Pmode
);
5931 emit_move_insn (tmp
, arc_unspec_offset (addr
, UNSPEC_TLS_GD
));
5932 return arc_call_tls_get_addr (tmp
);
5934 case TLS_MODEL_LOCAL_DYNAMIC
:
5937 const char *base_name
;
5939 decl
= SYMBOL_REF_DECL (addr
);
5940 base_name
= DTPOFF_ZERO_SYM
;
5941 if (decl
&& bss_initializer_p (decl
))
5942 base_name
= ".tbss";
5944 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5945 tmp
= gen_reg_rtx (Pmode
);
5946 emit_move_insn (tmp
, arc_unspec_offset (base
, UNSPEC_TLS_GD
));
5947 base
= arc_call_tls_get_addr (tmp
);
5948 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
),
5949 arc_unspec_offset (addr
, UNSPEC_TLS_OFF
));
5951 case TLS_MODEL_INITIAL_EXEC
:
5952 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5953 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5954 return gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
, arc_tp_regno
), addr
);
5956 case TLS_MODEL_LOCAL_EXEC
:
5957 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5958 return gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
, arc_tp_regno
), addr
);
5965 /* Legitimize a pic address reference in ORIG.
5966 The return value is the legitimated address.
5967 If OLDX is non-zero, it is the target to assign the address to first. */
5970 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5979 if (GET_CODE (addr
) == LABEL_REF
)
5981 else if (GET_CODE (addr
) == SYMBOL_REF
)
5983 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5985 return arc_legitimize_tls_address (addr
, model
);
5988 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5989 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5991 /* This symbol must be referenced via a load from the Global
5992 Offset Table (@GOTPC). */
5993 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5994 pat
= gen_const_mem (Pmode
, pat
);
5997 oldx
= gen_reg_rtx (Pmode
);
5999 emit_move_insn (oldx
, pat
);
6004 if (GET_CODE (addr
) == CONST
)
6006 addr
= XEXP (addr
, 0);
6007 if (GET_CODE (addr
) == UNSPEC
)
6009 /* Check that the unspec is one of the ones we generate? */
6012 /* fwprop is placing in the REG_EQUIV notes constant pic
6013 unspecs expressions. Then, loop may use these notes for
6014 optimizations resulting in complex patterns that are not
6015 supported by the current implementation. The following
6016 two if-cases are simplifying the complex patters to
6018 else if (GET_CODE (addr
) == MINUS
)
6020 rtx op0
= XEXP (addr
, 0);
6021 rtx op1
= XEXP (addr
, 1);
6023 gcc_assert (GET_CODE (op1
) == UNSPEC
);
6025 emit_move_insn (oldx
,
6026 gen_rtx_CONST (SImode
,
6027 arc_legitimize_pic_address (op1
,
6029 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
6033 else if (GET_CODE (addr
) != PLUS
)
6035 rtx tmp
= XEXP (addr
, 0);
6036 enum rtx_code code
= GET_CODE (addr
);
6038 /* It only works for UNARY operations. */
6039 gcc_assert (UNARY_P (addr
));
6040 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
6045 gen_rtx_CONST (SImode
,
6046 arc_legitimize_pic_address (tmp
,
6049 emit_insn (gen_rtx_SET (oldx
,
6050 gen_rtx_fmt_ee (code
, SImode
,
6051 oldx
, const0_rtx
)));
6057 gcc_assert (GET_CODE (addr
) == PLUS
);
6058 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
6063 if (GET_CODE (addr
) == PLUS
)
6065 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
6067 base
= arc_legitimize_pic_address (op0
, oldx
);
6068 pat
= arc_legitimize_pic_address (op1
,
6069 base
== oldx
? NULL_RTX
: oldx
);
6071 if (base
== op0
&& pat
== op1
)
6074 if (GET_CODE (pat
) == CONST_INT
)
6075 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
6078 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
6080 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
6081 pat
= XEXP (pat
, 1);
6083 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
6091 /* Output address constant X to FILE, taking PIC into account. */
6094 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
6099 switch (GET_CODE (x
))
6109 output_addr_const (file
, x
);
6111 /* Local functions do not get references through the PLT. */
6112 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
6113 fputs ("@plt", file
);
6117 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
6118 assemble_name (file
, buf
);
6122 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
6123 assemble_name (file
, buf
);
6127 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
6131 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6135 if (GET_MODE (x
) == VOIDmode
)
6137 /* We can use %d if the number is one word and positive. */
6138 if (CONST_DOUBLE_HIGH (x
))
6139 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
6140 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
6141 else if (CONST_DOUBLE_LOW (x
) < 0)
6142 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
6144 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
6147 /* We can't handle floating point constants;
6148 PRINT_OPERAND must handle them. */
6149 output_operand_lossage ("floating constant misused");
6153 /* FIXME: Not needed here. */
6154 /* Some assemblers need integer constants to appear last (eg masm). */
6155 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
6157 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6158 fprintf (file
, "+");
6159 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6161 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6163 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6164 if (INTVAL (XEXP (x
, 1)) >= 0)
6165 fprintf (file
, "+");
6166 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6173 /* Avoid outputting things like x-x or x+5-x,
6174 since some assemblers can't handle that. */
6175 x
= simplify_subtraction (x
);
6176 if (GET_CODE (x
) != MINUS
)
6179 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6180 fprintf (file
, "-");
6181 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
6182 && INTVAL (XEXP (x
, 1)) < 0)
6184 fprintf (file
, "(");
6185 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6186 fprintf (file
, ")");
6189 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6194 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6200 bool pcrel
; pcrel
= false;
6201 rtx base
; base
= NULL
;
6202 gcc_assert (XVECLEN (x
, 0) >= 1);
6203 switch (XINT (x
, 1))
6205 case ARC_UNSPEC_GOT
:
6206 suffix
= "@gotpc", pcrel
= true;
6208 case ARC_UNSPEC_GOTOFF
:
6211 case ARC_UNSPEC_GOTOFFPC
:
6212 suffix
= "@pcl", pcrel
= true;
6214 case ARC_UNSPEC_PLT
:
6218 suffix
= "@tlsgd", pcrel
= true;
6221 suffix
= "@tlsie", pcrel
= true;
6223 case UNSPEC_TLS_OFF
:
6224 if (XVECLEN (x
, 0) == 2)
6225 base
= XVECEXP (x
, 0, 1);
6226 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6227 || (!flag_pic
&& !base
))
6233 suffix
= "@invalid";
6234 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
6238 fputs ("pcl,", file
);
6239 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
6240 fputs (suffix
, file
);
6242 arc_output_pic_addr_const (file
, base
, code
);
6246 output_operand_lossage ("invalid expression as operand");
6250 #define SYMBOLIC_CONST(X) \
6251 (GET_CODE (X) == SYMBOL_REF \
6252 || GET_CODE (X) == LABEL_REF \
6253 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
6255 /* Emit insns to move operands[1] into operands[0]. */
6258 prepare_pic_move (rtx
*operands
, machine_mode
)
6260 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
6262 operands
[1] = force_reg (Pmode
, operands
[1]);
6265 rtx temp
= (reload_in_progress
? operands
[0]
6266 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
6267 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
6272 /* The function returning the number of words, at the beginning of an
6273 argument, must be put in registers. The returned value must be
6274 zero for arguments that are passed entirely in registers or that
6275 are entirely pushed on the stack.
6277 On some machines, certain arguments must be passed partially in
6278 registers and partially in memory. On these machines, typically
6279 the first N words of arguments are passed in registers, and the
6280 rest on the stack. If a multi-word argument (a `double' or a
6281 structure) crosses that boundary, its first few words must be
6282 passed in registers and the rest must be pushed. This function
6283 tells the compiler when this occurs, and how many of the words
6284 should go in registers.
6286 `FUNCTION_ARG' for these arguments should return the first register
6287 to be used by the caller for this argument; likewise
6288 `FUNCTION_INCOMING_ARG', for the called function.
6290 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6292 /* If REGNO is the least arg reg available then what is the total number of arg
6294 #define GPR_REST_ARG_REGS(REGNO) \
6295 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6297 /* Since arc parm regs are contiguous. */
6298 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6300 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6303 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
6304 tree type
, bool named ATTRIBUTE_UNUSED
)
6306 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6307 int bytes
= (mode
== BLKmode
6308 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
6309 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6313 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
6314 ret
= GPR_REST_ARG_REGS (arg_num
);
6316 /* ICEd at function.c:2361, and ret is copied to data->partial */
6317 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
6322 /* This function is used to control a function argument is passed in a
6323 register, and which register.
6325 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
6326 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
6327 all of the previous arguments so far passed in registers; MODE, the
6328 machine mode of the argument; TYPE, the data type of the argument
6329 as a tree node or 0 if that is not known (which happens for C
6330 support library functions); and NAMED, which is 1 for an ordinary
6331 argument and 0 for nameless arguments that correspond to `...' in
6332 the called function's prototype.
6334 The returned value should either be a `reg' RTX for the hard
6335 register in which to pass the argument, or zero to pass the
6336 argument on the stack.
6338 For machines like the Vax and 68000, where normally all arguments
6339 are pushed, zero suffices as a definition.
6341 The usual way to make the ANSI library `stdarg.h' work on a machine
6342 where some arguments are usually passed in registers, is to cause
6343 nameless arguments to be passed on the stack instead. This is done
6344 by making the function return 0 whenever NAMED is 0.
6346 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
6347 definition of this function to determine if this argument is of a
6348 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
6349 is not defined and the function returns non-zero for such an
6350 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
6351 defined, the argument will be computed in the stack and then loaded
6354 The function is used to implement macro FUNCTION_ARG. */
6355 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
6356 and the rest are pushed. */
6359 arc_function_arg (cumulative_args_t cum_v
,
6361 const_tree type ATTRIBUTE_UNUSED
,
6362 bool named ATTRIBUTE_UNUSED
)
6364 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6367 const char *debstr ATTRIBUTE_UNUSED
;
6369 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
6370 /* Return a marker for use in the call instruction. */
6371 if (mode
== VOIDmode
)
6376 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
6378 ret
= gen_rtx_REG (mode
, arg_num
);
6379 debstr
= reg_names
[arg_num
];
6389 /* The function to update the summarizer variable *CUM to advance past
6390 an argument in the argument list. The values MODE, TYPE and NAMED
6391 describe that argument. Once this is done, the variable *CUM is
6392 suitable for analyzing the *following* argument with
6393 `FUNCTION_ARG', etc.
6395 This function need not do anything if the argument in question was
6396 passed on the stack. The compiler knows how to track the amount of
6397 stack space used for arguments without any special help.
6399 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
6400 /* For the ARC: the cum set here is passed on to function_arg where we
6401 look at its value and say which reg to use. Strategy: advance the
6402 regnumber here till we run out of arg regs, then set *cum to last
6403 reg. In function_arg, since *cum > last arg reg we would return 0
6404 and thus the arg will end up on the stack. For straddling args of
6405 course function_arg_partial_nregs will come into play. */
6408 arc_function_arg_advance (cumulative_args_t cum_v
,
6411 bool named ATTRIBUTE_UNUSED
)
6413 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6414 int bytes
= (mode
== BLKmode
6415 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
6416 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6420 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
6421 for (i
= 0; i
< words
; i
++)
6422 *cum
= ARC_NEXT_ARG_REG (*cum
);
6426 /* Define how to find the value returned by a function.
6427 VALTYPE is the data type of the value (as a tree).
6428 If the precise function being called is known, FN_DECL_OR_TYPE is its
6429 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6432 arc_function_value (const_tree valtype
,
6433 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
6434 bool outgoing ATTRIBUTE_UNUSED
)
6436 machine_mode mode
= TYPE_MODE (valtype
);
6437 int unsignedp ATTRIBUTE_UNUSED
;
6439 unsignedp
= TYPE_UNSIGNED (valtype
);
6440 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
6441 PROMOTE_MODE (mode
, unsignedp
, valtype
);
6442 return gen_rtx_REG (mode
, 0);
6445 /* Returns the return address that is used by builtin_return_address. */
6448 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
6453 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6456 /* Determine if a given RTX is a valid constant. We already know this
6457 satisfies CONSTANT_P. */
6460 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
6462 switch (GET_CODE (x
))
6467 if (arc_legitimate_pic_addr_p (x
))
6470 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6473 if (SYMBOL_REF_TLS_MODEL (x
))
6485 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6490 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6491 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
6500 return TARGET_PLUS_DMPY
;
6503 return TARGET_PLUS_QMACW
;
6509 switch (XINT (x
, 1))
6512 case UNSPEC_TLS_OFF
:
6516 /* Any other unspec ending here are pic related, hence the above
6517 constant pic address checking returned false. */
6523 fatal_insn ("unrecognized supposed constant", x
);
6530 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
6532 if (RTX_OK_FOR_BASE_P (x
, strict
))
6534 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
6536 if (legitimate_scaled_address_p (mode
, x
, strict
))
6538 if (legitimate_small_data_address_p (x
))
6540 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
6543 /* When we compile for size avoid const (@sym + offset)
6545 if (!flag_pic
&& optimize_size
&& !reload_completed
6546 && (GET_CODE (x
) == CONST
)
6547 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
6548 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
6549 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
6550 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
6552 rtx addend
= XEXP (XEXP (x
, 0), 1);
6553 gcc_assert (CONST_INT_P (addend
));
6554 HOST_WIDE_INT offset
= INTVAL (addend
);
6556 /* Allow addresses having a large offset to pass. Anyhow they
6557 will end in a limm. */
6558 return !(offset
> -1024 && offset
< 1020);
6561 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
6563 return arc_legitimate_constant_p (mode
, x
);
6565 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
6566 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
6567 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
6569 /* We're restricted here by the `st' insn. */
6570 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
6571 && GET_CODE (XEXP ((x
), 1)) == PLUS
6572 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
6573 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
6574 TARGET_AUTO_MODIFY_REG
, strict
))
6579 /* Return true iff ADDR (a legitimate address expression)
6580 has an effect that depends on the machine mode it is used for. */
6583 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
6585 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6586 which is valid for loads and stores, or a limm offset, which is valid for
6587 loads. Scaled indices are scaled by the access mode. */
6588 if (GET_CODE (addr
) == PLUS
6589 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
6594 /* Determine if it's legal to put X into the constant pool. */
6597 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
6599 return !arc_legitimate_constant_p (mode
, x
);
6602 /* IDs for all the ARC builtins. */
6606 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6607 ARC_BUILTIN_ ## NAME,
6608 #include "builtins.def"
6614 struct GTY(()) arc_builtin_description
6616 enum insn_code icode
;
6621 static GTY(()) struct arc_builtin_description
6622 arc_bdesc
[ARC_BUILTIN_COUNT
] =
6624 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6625 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6626 #include "builtins.def"
6630 /* Transform UP into lowercase and write the result to LO.
6631 You must provide enough space for LO. Return LO. */
6634 arc_tolower (char *lo
, const char *up
)
6638 for (; *up
; up
++, lo
++)
6639 *lo
= TOLOWER (*up
);
6646 /* Implement `TARGET_BUILTIN_DECL'. */
6649 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6651 if (id
< ARC_BUILTIN_COUNT
)
6652 return arc_bdesc
[id
].fndecl
;
6654 return error_mark_node
;
6658 arc_init_builtins (void)
6660 tree V4HI_type_node
;
6661 tree V2SI_type_node
;
6662 tree V2HI_type_node
;
6664 /* Vector types based on HS SIMD elements. */
6665 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6666 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6667 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6669 tree pcvoid_type_node
6670 = build_pointer_type (build_qualified_type (void_type_node
,
6672 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6675 tree void_ftype_void
6676 = build_function_type_list (void_type_node
, NULL_TREE
);
6678 = build_function_type_list (integer_type_node
, integer_type_node
,
6680 tree int_ftype_pcvoid_int
6681 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6682 integer_type_node
, NULL_TREE
);
6683 tree void_ftype_usint_usint
6684 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6685 long_unsigned_type_node
, NULL_TREE
);
6686 tree int_ftype_int_int
6687 = build_function_type_list (integer_type_node
, integer_type_node
,
6688 integer_type_node
, NULL_TREE
);
6689 tree usint_ftype_usint
6690 = build_function_type_list (long_unsigned_type_node
,
6691 long_unsigned_type_node
, NULL_TREE
);
6692 tree void_ftype_usint
6693 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6696 = build_function_type_list (integer_type_node
, void_type_node
,
6699 = build_function_type_list (void_type_node
, integer_type_node
,
6701 tree int_ftype_short
6702 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6705 /* Old ARC SIMD types. */
6706 tree v8hi_ftype_v8hi_v8hi
6707 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6708 V8HI_type_node
, NULL_TREE
);
6709 tree v8hi_ftype_v8hi_int
6710 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6711 integer_type_node
, NULL_TREE
);
6712 tree v8hi_ftype_v8hi_int_int
6713 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6714 integer_type_node
, integer_type_node
,
6716 tree void_ftype_v8hi_int_int
6717 = build_function_type_list (void_type_node
, V8HI_type_node
,
6718 integer_type_node
, integer_type_node
,
6720 tree void_ftype_v8hi_int_int_int
6721 = build_function_type_list (void_type_node
, V8HI_type_node
,
6722 integer_type_node
, integer_type_node
,
6723 integer_type_node
, NULL_TREE
);
6724 tree v8hi_ftype_int_int
6725 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6726 integer_type_node
, NULL_TREE
);
6727 tree void_ftype_int_int
6728 = build_function_type_list (void_type_node
, integer_type_node
,
6729 integer_type_node
, NULL_TREE
);
6730 tree v8hi_ftype_v8hi
6731 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6733 /* ARCv2 SIMD types. */
6734 tree long_ftype_v4hi_v4hi
6735 = build_function_type_list (long_long_integer_type_node
,
6736 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6737 tree int_ftype_v2hi_v2hi
6738 = build_function_type_list (integer_type_node
,
6739 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6740 tree v2si_ftype_v2hi_v2hi
6741 = build_function_type_list (V2SI_type_node
,
6742 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6743 tree v2hi_ftype_v2hi_v2hi
6744 = build_function_type_list (V2HI_type_node
,
6745 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6746 tree v2si_ftype_v2si_v2si
6747 = build_function_type_list (V2SI_type_node
,
6748 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6749 tree v4hi_ftype_v4hi_v4hi
6750 = build_function_type_list (V4HI_type_node
,
6751 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6752 tree long_ftype_v2si_v2hi
6753 = build_function_type_list (long_long_integer_type_node
,
6754 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6756 /* Add the builtins. */
6757 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6759 int id = ARC_BUILTIN_ ## NAME; \
6760 const char *Name = "__builtin_arc_" #NAME; \
6761 char *name = (char*) alloca (1 + strlen (Name)); \
6763 gcc_assert (id < ARC_BUILTIN_COUNT); \
6765 arc_bdesc[id].fndecl \
6766 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6767 BUILT_IN_MD, NULL, NULL_TREE); \
6769 #include "builtins.def"
6773 /* Helper to expand __builtin_arc_aligned (void* val, int
6777 arc_expand_builtin_aligned (tree exp
)
6779 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6780 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6782 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6783 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6785 if (!CONST_INT_P (op1
))
6787 /* If we can't fold the alignment to a constant integer
6788 whilst optimizing, this is probably a user error. */
6790 warning (0, "__builtin_arc_aligned with non-constant alignment");
6794 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6795 /* Check alignTest is positive, and a power of two. */
6796 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6798 error ("invalid alignment value for __builtin_arc_aligned");
6802 if (CONST_INT_P (op0
))
6804 HOST_WIDE_INT pnt
= INTVAL (op0
);
6806 if ((pnt
& (alignTest
- 1)) == 0)
6811 unsigned align
= get_pointer_alignment (arg0
);
6812 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6814 if (align
&& align
>= numBits
)
6816 /* Another attempt to ascertain alignment. Check the type
6817 we are pointing to. */
6818 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6819 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6824 /* Default to false. */
6828 /* Helper arc_expand_builtin, generates a pattern for the given icode
6832 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6834 switch (insn_data
[icode
].n_generator_args
)
6837 return GEN_FCN (icode
) ();
6839 return GEN_FCN (icode
) (arg
[0]);
6841 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6843 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6845 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6847 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6853 /* Expand an expression EXP that calls a built-in function,
6854 with result going to TARGET if that's convenient
6855 (and in mode MODE if that's convenient).
6856 SUBTARGET may be used as the target for computing one of EXP's operands.
6857 IGNORE is nonzero if the value is to be ignored. */
6860 arc_expand_builtin (tree exp
,
6862 rtx subtarget ATTRIBUTE_UNUSED
,
6863 machine_mode mode ATTRIBUTE_UNUSED
,
6864 int ignore ATTRIBUTE_UNUSED
)
6866 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6867 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6868 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6869 int i
, j
, n_args
= call_expr_nargs (exp
);
6872 enum insn_code icode
= d
->icode
;
6873 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6890 if (id
>= ARC_BUILTIN_COUNT
)
6891 internal_error ("bad builtin fcode");
6893 /* 1st part: Expand special builtins. */
6896 case ARC_BUILTIN_NOP
:
6897 emit_insn (gen_nopv ());
6900 case ARC_BUILTIN_RTIE
:
6901 case ARC_BUILTIN_SYNC
:
6902 case ARC_BUILTIN_BRK
:
6903 case ARC_BUILTIN_SWI
:
6904 case ARC_BUILTIN_UNIMP_S
:
6905 gcc_assert (icode
!= 0);
6906 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6909 case ARC_BUILTIN_ALIGNED
:
6910 return arc_expand_builtin_aligned (exp
);
6912 case ARC_BUILTIN_CLRI
:
6913 target
= gen_reg_rtx (SImode
);
6914 emit_insn (gen_clri (target
, const1_rtx
));
6917 case ARC_BUILTIN_TRAP_S
:
6918 case ARC_BUILTIN_SLEEP
:
6919 arg0
= CALL_EXPR_ARG (exp
, 0);
6921 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6923 gcc_assert (icode
!= 0);
6924 emit_insn (GEN_FCN (icode
) (op0
));
6927 case ARC_BUILTIN_VDORUN
:
6928 case ARC_BUILTIN_VDIRUN
:
6929 arg0
= CALL_EXPR_ARG (exp
, 0);
6930 arg1
= CALL_EXPR_ARG (exp
, 1);
6931 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6932 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6934 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6936 mode0
= insn_data
[icode
].operand
[1].mode
;
6937 mode1
= insn_data
[icode
].operand
[2].mode
;
6939 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6940 op0
= copy_to_mode_reg (mode0
, op0
);
6942 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6943 op1
= copy_to_mode_reg (mode1
, op1
);
6945 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6952 case ARC_BUILTIN_VDIWR
:
6953 case ARC_BUILTIN_VDOWR
:
6954 arg0
= CALL_EXPR_ARG (exp
, 0);
6955 arg1
= CALL_EXPR_ARG (exp
, 1);
6956 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6957 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6959 if (!CONST_INT_P (op0
)
6960 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6961 error ("operand 1 should be an unsigned 3-bit immediate");
6963 mode1
= insn_data
[icode
].operand
[1].mode
;
6965 if (icode
== CODE_FOR_vdiwr_insn
)
6966 target
= gen_rtx_REG (SImode
,
6967 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6968 else if (icode
== CODE_FOR_vdowr_insn
)
6969 target
= gen_rtx_REG (SImode
,
6970 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6974 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6975 op1
= copy_to_mode_reg (mode1
, op1
);
6977 pat
= GEN_FCN (icode
) (target
, op1
);
6984 case ARC_BUILTIN_VASRW
:
6985 case ARC_BUILTIN_VSR8
:
6986 case ARC_BUILTIN_VSR8AW
:
6987 arg0
= CALL_EXPR_ARG (exp
, 0);
6988 arg1
= CALL_EXPR_ARG (exp
, 1);
6989 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6990 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6991 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6993 target
= gen_reg_rtx (V8HImode
);
6994 mode0
= insn_data
[icode
].operand
[1].mode
;
6995 mode1
= insn_data
[icode
].operand
[2].mode
;
6997 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6998 op0
= copy_to_mode_reg (mode0
, op0
);
7000 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
7001 || !(UNSIGNED_INT3 (INTVAL (op1
))))
7002 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7004 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
7011 case ARC_BUILTIN_VLD32WH
:
7012 case ARC_BUILTIN_VLD32WL
:
7013 case ARC_BUILTIN_VLD64
:
7014 case ARC_BUILTIN_VLD32
:
7017 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
7018 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
7019 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
7021 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7022 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7023 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7024 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7026 /* target <- src vreg. */
7027 emit_insn (gen_move_insn (target
, src_vreg
));
7029 /* target <- vec_concat: target, mem (Ib, u8). */
7030 mode0
= insn_data
[icode
].operand
[3].mode
;
7031 mode1
= insn_data
[icode
].operand
[1].mode
;
7033 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
7034 || !(UNSIGNED_INT3 (INTVAL (op0
))))
7035 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7037 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
7038 || !(UNSIGNED_INT8 (INTVAL (op1
))))
7039 error ("operand 2 should be an unsigned 8-bit value");
7041 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
7048 case ARC_BUILTIN_VLD64W
:
7049 case ARC_BUILTIN_VLD128
:
7050 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
7051 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
7053 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7054 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7055 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7057 /* target <- src vreg. */
7058 target
= gen_reg_rtx (V8HImode
);
7060 /* target <- vec_concat: target, mem (Ib, u8). */
7061 mode0
= insn_data
[icode
].operand
[1].mode
;
7062 mode1
= insn_data
[icode
].operand
[2].mode
;
7063 mode2
= insn_data
[icode
].operand
[3].mode
;
7065 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
7066 || !(UNSIGNED_INT3 (INTVAL (op1
))))
7067 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7069 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
7070 || !(UNSIGNED_INT8 (INTVAL (op2
))))
7071 error ("operand 2 should be an unsigned 8-bit value");
7073 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
7081 case ARC_BUILTIN_VST128
:
7082 case ARC_BUILTIN_VST64
:
7083 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
7084 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
7085 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
7087 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7088 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7089 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7090 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7092 mode0
= insn_data
[icode
].operand
[0].mode
;
7093 mode1
= insn_data
[icode
].operand
[1].mode
;
7094 mode2
= insn_data
[icode
].operand
[2].mode
;
7095 mode3
= insn_data
[icode
].operand
[3].mode
;
7097 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
7098 || !(UNSIGNED_INT3 (INTVAL (op1
))))
7099 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7101 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
7102 || !(UNSIGNED_INT8 (INTVAL (op2
))))
7103 error ("operand 3 should be an unsigned 8-bit value");
7105 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
7106 op3
= copy_to_mode_reg (mode3
, op3
);
7108 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
7115 case ARC_BUILTIN_VST16_N
:
7116 case ARC_BUILTIN_VST32_N
:
7117 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
7118 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
7119 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
7120 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
7122 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7123 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7124 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7125 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7126 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7128 mode0
= insn_data
[icode
].operand
[0].mode
;
7129 mode2
= insn_data
[icode
].operand
[2].mode
;
7130 mode3
= insn_data
[icode
].operand
[3].mode
;
7131 mode4
= insn_data
[icode
].operand
[4].mode
;
7133 /* Do some correctness checks for the operands. */
7134 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
7135 || !(UNSIGNED_INT8 (INTVAL (op0
))))
7136 error ("operand 4 should be an unsigned 8-bit value (0-255)");
7138 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
7139 || !(UNSIGNED_INT3 (INTVAL (op2
))))
7140 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
7142 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
7143 op3
= copy_to_mode_reg (mode3
, op3
);
7145 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
7146 || !(UNSIGNED_INT3 (INTVAL (op4
))))
7147 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
7148 else if (icode
== CODE_FOR_vst32_n_insn
7149 && ((INTVAL (op4
) % 2) != 0))
7150 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
7152 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
7163 /* 2nd part: Expand regular builtins. */
7165 internal_error ("bad builtin fcode");
7167 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
7172 if (target
== NULL_RTX
7173 || GET_MODE (target
) != tmode
7174 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
7176 target
= gen_reg_rtx (tmode
);
7181 gcc_assert (n_args
<= 4);
7182 for (i
= 0; i
< n_args
; i
++, j
++)
7184 tree arg
= CALL_EXPR_ARG (exp
, i
);
7185 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
7186 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
7187 machine_mode opmode
= GET_MODE (op
);
7188 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
7190 /* SIMD extension requires exact immediate operand match. */
7191 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
7192 && (id
< ARC_BUILTIN_SIMD_END
)
7196 if (!CONST_INT_P (op
))
7197 error ("builtin requires an immediate for operand %d", j
);
7201 if (!satisfies_constraint_L (op
))
7202 error ("operand %d should be a 6 bit unsigned immediate", j
);
7205 if (!satisfies_constraint_P (op
))
7206 error ("operand %d should be a 8 bit unsigned immediate", j
);
7209 if (!satisfies_constraint_K (op
))
7210 error ("operand %d should be a 3 bit unsigned immediate", j
);
7213 error ("unknown builtin immediate operand type for operand %d",
7218 if (CONST_INT_P (op
))
7221 if ((opmode
== SImode
) && (mode
== HImode
))
7224 op
= gen_lowpart (HImode
, op
);
7227 /* In case the insn wants input operands in modes different from
7228 the result, abort. */
7229 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
7231 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
7232 op
= copy_to_mode_reg (mode
, op
);
7237 pat
= apply_GEN_FCN (icode
, xop
);
7238 if (pat
== NULL_RTX
)
7249 /* Returns true if the operands[opno] is a valid compile-time constant to be
7250 used as register number in the code for builtins. Else it flags an error
7251 and returns false. */
7254 check_if_valid_regno_const (rtx
*operands
, int opno
)
7257 switch (GET_CODE (operands
[opno
]))
7264 error ("register number must be a compile-time constant. Try giving higher optimization levels");
7270 /* Return true if it is ok to make a tail-call to DECL. */
7273 arc_function_ok_for_sibcall (tree decl
,
7274 tree exp ATTRIBUTE_UNUSED
)
7276 tree attrs
= NULL_TREE
;
7278 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7279 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
7284 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
7286 if (lookup_attribute ("jli_always", attrs
))
7288 if (lookup_attribute ("jli_fixed", attrs
))
7290 if (lookup_attribute ("secure_call", attrs
))
7294 /* Everything else is ok. */
7298 /* Output code to add DELTA to the first argument, and then jump
7299 to FUNCTION. Used for C++ multiple inheritance. */
7302 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7303 HOST_WIDE_INT delta
,
7304 HOST_WIDE_INT vcall_offset
,
7307 int mi_delta
= delta
;
7308 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
7311 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
7315 mi_delta
= - mi_delta
;
7317 /* Add DELTA. When possible use a plain add, otherwise load it into
7318 a register first. */
7320 while (mi_delta
!= 0)
7322 if ((mi_delta
& (3 << shift
)) == 0)
7326 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
7327 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
7328 mi_delta
& (0xff << shift
));
7329 mi_delta
&= ~(0xff << shift
);
7334 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7335 if (vcall_offset
!= 0)
7337 /* ld r12,[this] --> temp = *this
7338 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7340 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7341 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7342 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
7343 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
7344 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
7345 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7346 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
7347 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
7348 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
7351 fnaddr
= XEXP (DECL_RTL (function
), 0);
7353 if (arc_is_longcall_p (fnaddr
))
7357 asm_fprintf (file
, "\tld\t%s, [pcl, @",
7358 ARC_TEMP_SCRATCH_REG
);
7359 assemble_name (file
, XSTR (fnaddr
, 0));
7360 fputs ("@gotpc]\n", file
);
7361 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
7365 fputs ("\tj\t@", file
);
7366 assemble_name (file
, XSTR (fnaddr
, 0));
7371 fputs ("\tb\t@", file
);
7372 assemble_name (file
, XSTR (fnaddr
, 0));
7374 fputs ("@plt\n", file
);
7379 /* Return true if a 32 bit "long_call" should be generated for
7380 this calling SYM_REF. We generate a long_call if the function:
7382 a. has an __attribute__((long call))
7383 or b. the -mlong-calls command line switch has been specified
7385 However we do not generate a long call if the function has an
7386 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7388 This function will be called by C fragments contained in the machine
7389 description file. */
7392 arc_is_longcall_p (rtx sym_ref
)
7394 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7397 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
7398 || (TARGET_LONG_CALLS_SET
7399 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7400 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7404 /* Likewise for short calls. */
7407 arc_is_shortcall_p (rtx sym_ref
)
7409 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7412 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7413 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
7414 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
7415 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7419 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7422 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7424 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
7428 HOST_WIDE_INT size
= int_size_in_bytes (type
);
7429 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
7434 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
7435 machine_mode mode ATTRIBUTE_UNUSED
,
7437 bool named ATTRIBUTE_UNUSED
)
7440 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
7441 || TREE_ADDRESSABLE (type
)));
7444 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7447 arc_can_use_doloop_p (const widest_int
&,
7448 const widest_int
&iterations_max
,
7449 unsigned int loop_depth
, bool entered_at_top
)
7451 /* Considering limitations in the hardware, only use doloop
7452 for innermost loops which must be entered from the top. */
7453 if (loop_depth
> 1 || !entered_at_top
)
7456 /* Check for lp_count width boundary. */
7457 if (arc_lpcwidth
!= 32
7458 && (wi::gtu_p (iterations_max
, ((1 << arc_lpcwidth
) - 1))
7459 || wi::eq_p (iterations_max
, 0)))
7464 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7465 return why doloop cannot be applied. */
7468 arc_invalid_within_doloop (const rtx_insn
*insn
)
7471 return "Function call in the loop.";
7473 /* FIXME! add here all the ZOL exceptions. */
7477 /* Return the next active insn, skiping the inline assembly code. */
7480 arc_active_insn (rtx_insn
*insn
)
7482 rtx_insn
*nxt
= next_active_insn (insn
);
7484 if (nxt
&& GET_CODE (PATTERN (nxt
)) == ASM_INPUT
)
7485 nxt
= next_active_insn (nxt
);
7489 /* Search for a sequence made out of two stores and a given number of
7490 loads, insert a nop if required. */
7493 check_store_cacheline_hazard (void)
7495 rtx_insn
*insn
, *succ0
, *insn1
;
7498 for (insn
= get_insns (); insn
; insn
= arc_active_insn (insn
))
7500 succ0
= arc_active_insn (insn
);
7505 if (!single_set (insn
) || !single_set (succ0
))
7508 if ((get_attr_type (insn
) != TYPE_STORE
)
7509 || (get_attr_type (succ0
) != TYPE_STORE
))
7512 /* Found at least two consecutive stores. Goto the end of the
7514 for (insn1
= succ0
; insn1
; insn1
= arc_active_insn (insn1
))
7515 if (!single_set (insn1
) || get_attr_type (insn1
) != TYPE_STORE
)
7518 /* Now, check the next two instructions for the following cases:
7519 1. next instruction is a LD => insert 2 nops between store
7521 2. next-next instruction is a LD => inset 1 nop after the store
7523 if (insn1
&& single_set (insn1
)
7524 && (get_attr_type (insn1
) == TYPE_LOAD
))
7527 emit_insn_before (gen_nopv (), insn1
);
7528 emit_insn_before (gen_nopv (), insn1
);
7532 if (insn1
&& (get_attr_type (insn1
) == TYPE_COMPARE
))
7534 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7535 reorg, so it is safe to reuse it for avoiding the
7536 current compare insn to be part of a BRcc
7538 add_reg_note (insn1
, REG_SAVE_NOTE
, GEN_INT (3));
7540 insn1
= arc_active_insn (insn1
);
7541 if (insn1
&& single_set (insn1
)
7542 && (get_attr_type (insn1
) == TYPE_LOAD
))
7545 emit_insn_before (gen_nopv (), insn1
);
7555 /* Return true if a load instruction (CONSUMER) uses the same address as a
7556 store instruction (PRODUCER). This function is used to avoid st/ld
7557 address hazard in ARC700 cores. */
7560 arc_store_addr_hazard_internal_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7562 rtx in_set
, out_set
;
7563 rtx out_addr
, in_addr
;
7571 /* Peel the producer and the consumer for the address. */
7572 out_set
= single_set (producer
);
7575 out_addr
= SET_DEST (out_set
);
7578 if (GET_CODE (out_addr
) == ZERO_EXTEND
7579 || GET_CODE (out_addr
) == SIGN_EXTEND
)
7580 out_addr
= XEXP (out_addr
, 0);
7582 if (!MEM_P (out_addr
))
7585 in_set
= single_set (consumer
);
7588 in_addr
= SET_SRC (in_set
);
7591 if (GET_CODE (in_addr
) == ZERO_EXTEND
7592 || GET_CODE (in_addr
) == SIGN_EXTEND
)
7593 in_addr
= XEXP (in_addr
, 0);
7595 if (!MEM_P (in_addr
))
7597 /* Get rid of the MEM and check if the addresses are
7599 in_addr
= XEXP (in_addr
, 0);
7600 out_addr
= XEXP (out_addr
, 0);
7602 return exp_equiv_p (in_addr
, out_addr
, 0, true);
7608 /* Return TRUE is we have an store address hazard. */
7611 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7613 if (TARGET_ARC700
&& (arc_tune
!= ARC_TUNE_ARC7XX
))
7615 return arc_store_addr_hazard_internal_p (producer
, consumer
);
7618 /* The same functionality as arc_hazard. It is called in machine
7619 reorg before any other optimization. Hence, the NOP size is taken
7620 into account when doing branch shortening. */
7623 workaround_arc_anomaly (void)
7625 rtx_insn
*insn
, *succ0
;
7628 /* For any architecture: call arc_hazard here. */
7629 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7631 succ0
= next_real_insn (insn
);
7632 if (arc_hazard (insn
, succ0
))
7634 emit_insn_before (gen_nopv (), succ0
);
7641 /* Old A7 are suffering of a cache hazard, and we need to insert two
7642 nops between any sequence of stores and a load. */
7643 if (arc_tune
!= ARC_TUNE_ARC7XX
)
7644 check_store_cacheline_hazard ();
7646 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7648 succ0
= next_real_insn (insn
);
7649 if (arc_store_addr_hazard_internal_p (insn
, succ0
))
7651 emit_insn_after (gen_nopv (), insn
);
7652 emit_insn_after (gen_nopv (), insn
);
7656 /* Avoid adding nops if the instruction between the ST and LD is
7658 succ1
= next_real_insn (succ0
);
7659 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
7660 && arc_store_addr_hazard_internal_p (insn
, succ1
))
7661 emit_insn_after (gen_nopv (), insn
);
7665 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7666 turns out not to be optimizable; we have to split the loop_end pattern into
7667 a subtract and a test. */
7670 hwloop_fail (hwloop_info loop
)
7673 rtx insn
= loop
->loop_end
;
7676 && (loop
->length
&& (loop
->length
<= ARC_MAX_LOOP_LENGTH
))
7677 && REG_P (loop
->iter_reg
))
7679 /* TARGET_V2 core3 has dbnz instructions. */
7680 test
= gen_dbnz (loop
->iter_reg
, loop
->start_label
);
7681 insn
= emit_jump_insn_before (test
, loop
->loop_end
);
7683 else if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
) == LP_COUNT
))
7685 /* We have the lp_count as loop iterator, try to use it. */
7686 emit_insn_before (gen_loop_fail (), loop
->loop_end
);
7687 test
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CC_ZNmode
, CC_REG
),
7689 test
= gen_rtx_IF_THEN_ELSE (VOIDmode
, test
,
7690 gen_rtx_LABEL_REF (Pmode
, loop
->start_label
),
7692 insn
= emit_jump_insn_before (gen_rtx_SET (pc_rtx
, test
),
7697 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
7701 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
7702 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
7708 JUMP_LABEL (insn
) = loop
->start_label
;
7709 LABEL_NUSES (loop
->start_label
)++;
7710 delete_insn (loop
->loop_end
);
7713 /* Return the next insn after INSN that is not a NOTE, but stop the
7714 search before we enter another basic block. This routine does not
7715 look inside SEQUENCEs. */
7718 next_nonnote_insn_bb (rtx_insn
*insn
)
7722 insn
= NEXT_INSN (insn
);
7723 if (insn
== 0 || !NOTE_P (insn
))
7725 if (NOTE_INSN_BASIC_BLOCK_P (insn
))
7732 /* Optimize LOOP. */
7735 hwloop_optimize (hwloop_info loop
)
7739 basic_block entry_bb
, bb
;
7741 rtx_insn
*insn
, *seq
, *entry_after
, *last_insn
, *end_label
;
7742 unsigned int length
;
7743 bool need_fix
= false;
7744 rtx lp_reg
= gen_rtx_REG (SImode
, LP_COUNT
);
7746 if (loop
->depth
> 1)
7749 fprintf (dump_file
, ";; loop %d is not innermost\n",
7754 if (!loop
->incoming_dest
)
7757 fprintf (dump_file
, ";; loop %d has more than one entry\n",
7762 if (loop
->incoming_dest
!= loop
->head
)
7765 fprintf (dump_file
, ";; loop %d is not entered from head\n",
7770 if (loop
->has_call
|| loop
->has_asm
)
7773 fprintf (dump_file
, ";; loop %d has invalid insn\n",
7778 /* Scan all the blocks to make sure they don't use iter_reg. */
7779 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
7782 fprintf (dump_file
, ";; loop %d uses iterator\n",
7787 /* Check if start_label appears before doloop_end. */
7789 for (insn
= loop
->start_label
;
7790 insn
&& insn
!= loop
->loop_end
;
7791 insn
= NEXT_INSN (insn
))
7793 length
+= NONDEBUG_INSN_P (insn
) ? get_attr_length (insn
) : 0;
7794 if (JUMP_TABLES_IN_TEXT_SECTION
7795 && JUMP_TABLE_DATA_P (insn
))
7798 fprintf (dump_file
, ";; loop %d has a jump table\n",
7807 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
7812 loop
->length
= length
;
7813 if (loop
->length
> ARC_MAX_LOOP_LENGTH
)
7816 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7819 else if (!loop
->length
)
7822 fprintf (dump_file
, ";; loop %d is empty\n", loop
->loop_no
);
7826 /* Check if we use a register or not. */
7827 if (!REG_P (loop
->iter_reg
))
7830 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7835 /* Check if we use a register or not. */
7836 if (!REG_P (loop
->iter_reg
))
7839 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7844 /* Check if loop register is lpcount. */
7845 if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
)) != LP_COUNT
)
7848 fprintf (dump_file
, ";; loop %d doesn't use lp_count as loop"
7851 /* This loop doesn't use the lp_count, check though if we can
7853 if (TEST_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
)
7854 /* In very unique cases we may have LP_COUNT alive. */
7855 || (loop
->incoming_src
7856 && REGNO_REG_SET_P (df_get_live_out (loop
->incoming_src
),
7860 fprintf (dump_file
, ";; loop %d, lp_count is alive", loop
->loop_no
);
7867 /* Check for control like instruction as the last instruction of a
7870 last_insn
= PREV_INSN (loop
->loop_end
);
7874 for (; last_insn
!= BB_HEAD (bb
);
7875 last_insn
= PREV_INSN (last_insn
))
7876 if (NONDEBUG_INSN_P (last_insn
))
7879 if (last_insn
!= BB_HEAD (bb
))
7882 if (single_pred_p (bb
)
7883 && single_pred_edge (bb
)->flags
& EDGE_FALLTHRU
7884 && single_pred (bb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
))
7886 bb
= single_pred (bb
);
7887 last_insn
= BB_END (bb
);
7900 fprintf (dump_file
, ";; loop %d has no last instruction\n",
7905 if ((TARGET_ARC600_FAMILY
|| TARGET_HS
)
7906 && INSN_P (last_insn
)
7907 && (JUMP_P (last_insn
) || CALL_P (last_insn
)
7908 || GET_CODE (PATTERN (last_insn
)) == SEQUENCE
7909 /* At this stage we can have (insn (clobber (mem:BLK
7910 (reg)))) instructions, ignore them. */
7911 || (GET_CODE (PATTERN (last_insn
)) != CLOBBER
7912 && (get_attr_type (last_insn
) == TYPE_BRCC
7913 || get_attr_type (last_insn
) == TYPE_BRCC_NO_DELAY_SLOT
))))
7915 if (loop
->length
+ 2 > ARC_MAX_LOOP_LENGTH
)
7918 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7922 fprintf (dump_file
, ";; loop %d has a control like last insn;"
7926 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7929 if (LABEL_P (last_insn
))
7932 fprintf (dump_file
, ";; loop %d has a label as last insn;"
7935 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7938 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7939 and we can use it to indicate the last ZOL instruction cannot be
7940 part of a delay slot. */
7941 add_reg_note (last_insn
, REG_SAVE_NOTE
, GEN_INT (2));
7943 loop
->last_insn
= last_insn
;
7945 /* Get the loop iteration register. */
7946 iter_reg
= loop
->iter_reg
;
7948 gcc_assert (REG_P (iter_reg
));
7952 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
7953 if (entry_edge
->flags
& EDGE_FALLTHRU
)
7956 if (entry_edge
== NULL
)
7959 fprintf (dump_file
, ";; loop %d has no fallthru edge jumping"
7964 /* The loop is good. */
7965 end_label
= gen_label_rtx ();
7966 loop
->end_label
= end_label
;
7968 /* Place the zero_cost_loop_start instruction before the loop. */
7969 entry_bb
= entry_edge
->src
;
7975 /* The loop uses a R-register, but the lp_count is free, thus
7977 emit_insn (gen_rtx_SET (lp_reg
, iter_reg
));
7978 SET_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
);
7982 fprintf (dump_file
, ";; fix loop %d to use lp_count\n",
7987 insn
= emit_insn (gen_arc_lp (loop
->start_label
,
7993 entry_after
= BB_END (entry_bb
);
7994 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
8001 emit_insn_before (seq
, BB_HEAD (loop
->head
));
8002 seq
= emit_label_before (gen_label_rtx (), seq
);
8003 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
8004 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
8006 if (!(e
->flags
& EDGE_FALLTHRU
))
8007 redirect_edge_and_branch_force (e
, new_bb
);
8009 redirect_edge_succ (e
, new_bb
);
8012 make_edge (new_bb
, loop
->head
, 0);
8017 while (DEBUG_INSN_P (entry_after
)
8018 || (NOTE_P (entry_after
)
8019 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
8020 /* Make sure we don't split a call and its corresponding
8021 CALL_ARG_LOCATION note. */
8022 && NOTE_KIND (entry_after
) != NOTE_INSN_CALL_ARG_LOCATION
))
8023 entry_after
= NEXT_INSN (entry_after
);
8025 entry_after
= next_nonnote_insn_bb (entry_after
);
8027 gcc_assert (entry_after
);
8028 emit_insn_before (seq
, entry_after
);
8031 /* Insert the loop end label before the last instruction of the
8033 emit_label_after (end_label
, loop
->last_insn
);
8034 /* Make sure we mark the begining and end label as used. */
8035 LABEL_NUSES (loop
->end_label
)++;
8036 LABEL_NUSES (loop
->start_label
)++;
8041 /* A callback for the hw-doloop pass. This function examines INSN; if
8042 it is a loop_end pattern we recognize, return the reg rtx for the
8043 loop counter. Otherwise, return NULL_RTX. */
8046 hwloop_pattern_reg (rtx_insn
*insn
)
8050 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
8053 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
8059 static struct hw_doloop_hooks arc_doloop_hooks
=
8066 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8067 and tries to rewrite the RTL of these loops so that proper Blackfin
8068 hardware loops are generated. */
8071 arc_reorg_loops (void)
8073 reorg_loops (true, &arc_doloop_hooks
);
8076 /* Scan all calls and add symbols to be emitted in the jli section if
8080 jli_call_scan (void)
8084 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8089 rtx pat
= PATTERN (insn
);
8090 if (GET_CODE (pat
) == COND_EXEC
)
8091 pat
= COND_EXEC_CODE (pat
);
8092 pat
= XVECEXP (pat
, 0, 0);
8093 if (GET_CODE (pat
) == SET
)
8094 pat
= SET_SRC (pat
);
8096 pat
= XEXP (XEXP (pat
, 0), 0);
8097 if (GET_CODE (pat
) == SYMBOL_REF
8098 && arc_is_jli_call_p (pat
))
8099 arc_add_jli_section (pat
);
8103 /* Add padding if necessary to avoid a mispredict. A return could
8104 happen immediately after the function start. A call/return and
8105 return/return must be 6 bytes apart to avoid mispredict. */
8113 if (!TARGET_PAD_RETURN
)
8116 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8118 rtx_insn
*prev0
= prev_active_insn (insn
);
8119 bool wantlong
= false;
8121 if (!INSN_P (insn
) || GET_CODE (PATTERN (insn
)) != SIMPLE_RETURN
)
8126 prev0
= emit_insn_before (gen_nopv (), insn
);
8127 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8128 so it is safe to reuse it for forcing a particular length
8129 for an instruction. */
8130 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
8131 emit_insn_before (gen_nopv (), insn
);
8134 offset
= get_attr_length (prev0
);
8136 if (get_attr_length (prev0
) == 2
8137 && get_attr_iscompact (prev0
) != ISCOMPACT_TRUE
)
8139 /* Force long version of the insn. */
8144 rtx_insn
*prev
= prev_active_insn (prev0
);
8146 offset
+= get_attr_length (prev
);
8148 prev
= prev_active_insn (prev
);
8150 offset
+= get_attr_length (prev
);
8155 prev
= emit_insn_before (gen_nopv (), insn
);
8156 add_reg_note (prev
, REG_SAVE_NOTE
, GEN_INT (1));
8159 emit_insn_before (gen_nopv (), insn
);
8166 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
8168 /* Emit a blockage to avoid delay slot scheduling. */
8169 emit_insn_before (gen_blockage (), insn
);
8173 static int arc_reorg_in_progress
= 0;
8175 /* ARC's machince specific reorg function. */
8186 cfun
->machine
->arc_reorg_started
= 1;
8187 arc_reorg_in_progress
= 1;
8189 compute_bb_for_insn ();
8193 /* Doloop optimization. */
8196 workaround_arc_anomaly ();
8200 /* FIXME: should anticipate ccfsm action, generate special patterns for
8201 to-be-deleted branches that have no delay slot and have at least the
8202 length of the size increase forced on other insns that are conditionalized.
8203 This can also have an insn_list inside that enumerates insns which are
8204 not actually conditionalized because the destinations are dead in the
8206 Could also tag branches that we want to be unaligned if they get no delay
8207 slot, or even ones that we don't want to do delay slot sheduling for
8208 because we can unalign them.
8210 However, there are cases when conditional execution is only possible after
8211 delay slot scheduling:
8213 - If a delay slot is filled with a nocond/set insn from above, the previous
8214 basic block can become elegible for conditional execution.
8215 - If a delay slot is filled with a nocond insn from the fall-through path,
8216 the branch with that delay slot can become eligble for conditional
8217 execution (however, with the same sort of data flow analysis that dbr
8218 does, we could have figured out before that we don't need to
8219 conditionalize this insn.)
8220 - If a delay slot insn is filled with an insn from the target, the
8221 target label gets its uses decremented (even deleted if falling to zero),
8222 thus possibly creating more condexec opportunities there.
8223 Therefore, we should still be prepared to apply condexec optimization on
8224 non-prepared branches if the size increase of conditionalized insns is no
8225 more than the size saved from eliminating the branch. An invocation option
8226 could also be used to reserve a bit of extra size for condbranches so that
8227 this'll work more often (could also test in arc_reorg if the block is
8228 'close enough' to be eligible for condexec to make this likely, and
8229 estimate required size increase). */
8230 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8231 if (TARGET_NO_BRCC_SET
)
8236 init_insn_lengths();
8239 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
8242 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
8243 df_finish_pass ((flags
& TODO_df_verify
) != 0);
8247 fprintf (dump_file
, ";; After if conversion:\n\n");
8248 print_rtl (dump_file
, get_insns ());
8252 /* Call shorten_branches to calculate the insn lengths. */
8253 shorten_branches (get_insns());
8254 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
8256 if (!INSN_ADDRESSES_SET_P())
8257 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
8259 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8262 enum attr_type insn_type
;
8264 /* If a non-jump insn (or a casesi jump table), continue. */
8265 if (GET_CODE (insn
) != JUMP_INSN
||
8266 GET_CODE (PATTERN (insn
)) == ADDR_VEC
8267 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
8270 /* If we already have a brcc, note if it is suitable for brcc_s.
8271 Be a bit generous with the brcc_s range so that we can take
8272 advantage of any code shortening from delay slot scheduling. */
8273 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
8275 rtx pat
= PATTERN (insn
);
8276 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
8277 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
8279 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
8280 if ((offset
>= -140 && offset
< 140)
8281 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
8282 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
8283 && equality_comparison_operator (op
, VOIDmode
))
8284 PUT_MODE (*ccp
, CC_Zmode
);
8285 else if (GET_MODE (*ccp
) == CC_Zmode
)
8286 PUT_MODE (*ccp
, CC_ZNmode
);
8289 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
8290 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
8293 /* OK. so we have a jump insn. */
8294 /* We need to check that it is a bcc. */
8295 /* Bcc => set (pc) (if_then_else ) */
8296 pattern
= PATTERN (insn
);
8297 if (GET_CODE (pattern
) != SET
8298 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
8299 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
8302 /* Now check if the jump is beyond the s9 range. */
8303 if (CROSSING_JUMP_P (insn
))
8305 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
8307 if(offset
> 253 || offset
< -254)
8310 pc_target
= SET_SRC (pattern
);
8312 /* Avoid FPU instructions. */
8313 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
8314 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
8317 /* Now go back and search for the set cc insn. */
8319 label
= XEXP (pc_target
, 1);
8323 rtx_insn
*scan
, *link_insn
= NULL
;
8325 for (scan
= PREV_INSN (insn
);
8326 scan
&& GET_CODE (scan
) != CODE_LABEL
;
8327 scan
= PREV_INSN (scan
))
8329 if (! INSN_P (scan
))
8331 pat
= PATTERN (scan
);
8332 if (GET_CODE (pat
) == SET
8333 && cc_register (SET_DEST (pat
), VOIDmode
))
8343 /* Check if this is a data dependency. */
8344 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
8347 /* Make sure we can use it for brcc insns. */
8348 if (find_reg_note (link_insn
, REG_SAVE_NOTE
, GEN_INT (3)))
8351 /* Ok this is the set cc. copy args here. */
8352 op
= XEXP (pc_target
, 0);
8354 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
8355 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
8356 if (GET_CODE (op0
) == ZERO_EXTRACT
8357 && XEXP (op0
, 1) == const1_rtx
8358 && (GET_CODE (op
) == EQ
8359 || GET_CODE (op
) == NE
))
8361 /* btst / b{eq,ne} -> bbit{0,1} */
8362 op0
= XEXP (cmp0
, 0);
8363 op1
= XEXP (cmp0
, 2);
8365 else if (!register_operand (op0
, VOIDmode
)
8366 || !general_operand (op1
, VOIDmode
))
8368 /* Be careful not to break what cmpsfpx_raw is
8369 trying to create for checking equality of
8370 single-precision floats. */
8371 else if (TARGET_SPFP
8372 && GET_MODE (op0
) == SFmode
8373 && GET_MODE (op1
) == SFmode
)
8376 /* None of the two cmp operands should be set between the
8377 cmp and the branch. */
8378 if (reg_set_between_p (op0
, link_insn
, insn
))
8381 if (reg_set_between_p (op1
, link_insn
, insn
))
8384 /* Since the MODE check does not work, check that this is
8385 CC reg's last set location before insn, and also no
8386 instruction between the cmp and branch uses the
8388 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
8389 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
8392 /* CC reg should be dead after insn. */
8393 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
8396 op
= gen_rtx_fmt_ee (GET_CODE (op
),
8397 GET_MODE (op
), cmp0
, cmp1
);
8398 /* If we create a LIMM where there was none before,
8399 we only benefit if we can avoid a scheduling bubble
8400 for the ARC600. Otherwise, we'd only forgo chances
8401 at short insn generation, and risk out-of-range
8403 if (!brcc_nolimm_operator (op
, VOIDmode
)
8404 && !long_immediate_operand (op1
, VOIDmode
)
8406 || next_active_insn (link_insn
) != insn
))
8409 /* Emit bbit / brcc (or brcc_s if possible).
8410 CC_Zmode indicates that brcc_s is possible. */
8413 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
8414 else if ((offset
>= -140 && offset
< 140)
8415 && rtx_equal_p (op1
, const0_rtx
)
8416 && compact_register_operand (op0
, VOIDmode
)
8417 && (GET_CODE (op
) == EQ
8418 || GET_CODE (op
) == NE
))
8419 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
8421 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
8424 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
8425 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
8426 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
8429 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
8430 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
8432 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
8433 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
8436 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8437 REG_NOTES (brcc_insn
) = note
;
8439 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
8442 remove_note (link_insn
, note
);
8443 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8444 REG_NOTES (brcc_insn
) = note
;
8446 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
8449 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8450 REG_NOTES (brcc_insn
) = note
;
8455 /* Delete the bcc insn. */
8456 set_insn_deleted (insn
);
8458 /* Delete the cmp insn. */
8459 set_insn_deleted (link_insn
);
8464 /* Clear out insn_addresses. */
8465 INSN_ADDRESSES_FREE ();
8469 if (INSN_ADDRESSES_SET_P())
8470 fatal_error (input_location
, "insn addresses not freed");
8472 arc_reorg_in_progress
= 0;
8475 /* Check if the operands are valid for BRcc.d generation
8476 Valid Brcc.d patterns are
8480 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
8481 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8482 does not have a delay slot
8484 Assumed precondition: Second operand is either a register or a u6 value. */
8487 valid_brcc_with_delay_p (rtx
*operands
)
8489 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
8491 return brcc_nolimm_operator (operands
[0], VOIDmode
);
8494 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8495 access DECL using %gp_rel(...)($gp). */
8498 arc_in_small_data_p (const_tree decl
)
8503 /* Only variables are going into small data area. */
8504 if (TREE_CODE (decl
) != VAR_DECL
)
8507 if (TARGET_NO_SDATA_SET
)
8510 /* Disable sdata references to weak variables. */
8511 if (DECL_WEAK (decl
))
8514 /* Don't put constants into the small data section: we want them to
8515 be in ROM rather than RAM. */
8516 if (TREE_READONLY (decl
))
8519 /* To ensure -mvolatile-cache works ld.di does not have a
8520 gp-relative variant. */
8521 if (!TARGET_VOLATILE_CACHE_SET
8522 && TREE_THIS_VOLATILE (decl
))
8525 /* Likewise for uncached data. */
8526 attr
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
8527 if (lookup_attribute ("uncached", attr
))
8530 /* and for aux regs. */
8531 attr
= DECL_ATTRIBUTES (decl
);
8532 if (lookup_attribute ("aux", attr
))
8535 if (DECL_SECTION_NAME (decl
) != 0)
8537 const char *name
= DECL_SECTION_NAME (decl
);
8538 if (strcmp (name
, ".sdata") == 0
8539 || strcmp (name
, ".sbss") == 0)
8542 /* If it's not public, there's no need to put it in the small data
8544 else if (TREE_PUBLIC (decl
))
8546 size
= int_size_in_bytes (TREE_TYPE (decl
));
8547 return (size
> 0 && size
<= g_switch_value
);
8552 /* Return true if OP is an acceptable memory operand for ARCompact
8553 16-bit gp-relative load instructions.
8555 /* volatile cache option still to be handled. */
8558 compact_sda_memory_operand (rtx op
, machine_mode mode
, bool short_p
)
8565 /* Eliminate non-memory operations. */
8566 if (GET_CODE (op
) != MEM
)
8569 if (mode
== VOIDmode
)
8570 mode
= GET_MODE (op
);
8572 size
= GET_MODE_SIZE (mode
);
8574 /* dword operations really put out 2 instructions, so eliminate them. */
8575 if (size
> UNITS_PER_WORD
)
8578 /* Decode the address now. */
8579 addr
= XEXP (op
, 0);
8581 if (!legitimate_small_data_address_p (addr
))
8584 if (!short_p
|| size
== 1)
8587 /* Now check for the alignment, the short loads using gp require the
8588 addresses to be aligned. */
8589 align
= get_symbol_alignment (addr
);
8600 if (align
&& ((align
& mask
) == 0))
8605 /* Return TRUE if PAT is accessing an aux-reg. */
8608 arc_is_aux_reg_p (rtx pat
)
8610 tree attrs
= NULL_TREE
;
8616 /* Get the memory attributes. */
8617 addr
= MEM_EXPR (pat
);
8621 /* Get the attributes. */
8622 if (TREE_CODE (addr
) == VAR_DECL
)
8623 attrs
= DECL_ATTRIBUTES (addr
);
8624 else if (TREE_CODE (addr
) == MEM_REF
)
8625 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
8629 if (lookup_attribute ("aux", attrs
))
8634 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8637 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
8638 unsigned HOST_WIDE_INT size
,
8639 unsigned HOST_WIDE_INT align
,
8640 unsigned HOST_WIDE_INT globalize_p
)
8642 int in_small_data
= arc_in_small_data_p (decl
);
8643 rtx mem
= decl
== NULL_TREE
? NULL_RTX
: DECL_RTL (decl
);
8645 /* Don't output aux-reg symbols. */
8646 if (mem
!= NULL_RTX
&& MEM_P (mem
)
8647 && SYMBOL_REF_P (XEXP (mem
, 0))
8648 && arc_is_aux_reg_p (mem
))
8652 switch_to_section (get_named_section (NULL
, ".sbss", 0));
8653 /* named_section (0,".sbss",0); */
8655 switch_to_section (bss_section
);
8658 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
8660 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
8661 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
8662 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
8663 ASM_OUTPUT_LABEL (stream
, name
);
8666 ASM_OUTPUT_SKIP (stream
, size
);
8670 arc_preserve_reload_p (rtx in
)
8672 return (GET_CODE (in
) == PLUS
8673 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
8674 && CONST_INT_P (XEXP (in
, 1))
8675 && !((INTVAL (XEXP (in
, 1)) & 511)));
8679 arc_register_move_cost (machine_mode
,
8680 enum reg_class from_class
, enum reg_class to_class
)
8682 /* Force an attempt to 'mov Dy,Dx' to spill. */
8683 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
8684 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
8690 /* Emit code for an addsi3 instruction with OPERANDS.
8691 COND_P indicates if this will use conditional execution.
8692 Return the length of the instruction.
8693 If OUTPUT_P is false, don't actually output the instruction, just return
8696 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
8700 int match
= operands_match_p (operands
[0], operands
[1]);
8701 int match2
= operands_match_p (operands
[0], operands
[2]);
8702 int intval
= (REG_P (operands
[2]) ? 1
8703 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
8704 int neg_intval
= -intval
;
8705 int short_0
= satisfies_constraint_Rcq (operands
[0]);
8706 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
8709 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8710 && REGNO (OP) != 30) \
8713 #define ADDSI_OUTPUT1(FORMAT) do {\
8715 output_asm_insn (FORMAT, operands);\
8718 #define ADDSI_OUTPUT(LIST) do {\
8721 ADDSI_OUTPUT1 (format);\
8725 /* First try to emit a 16 bit insn. */
8728 /* If we are actually about to output this insn, don't try a 16 bit
8729 variant if we already decided that we don't want that
8730 (I.e. we upsized this insn to align some following insn.)
8731 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8732 but add1 r0,sp,35 doesn't. */
8733 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
8735 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8738 && ((REG_H_P (operands
[2])
8739 && (match
|| satisfies_constraint_Rcq (operands
[2])))
8740 || (CONST_INT_P (operands
[2])
8741 && ((unsigned) intval
<= (match
? 127 : 7)))))
8742 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8744 /* Generate add_s b,b,h patterns. */
8745 if (short_0
&& match2
&& REG_H_P (operands
[1]))
8746 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8748 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8749 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
8750 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
8751 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8753 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
8754 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
8755 && match
&& !(neg_intval
& ~124)))
8756 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8758 /* Generate add_s h,h,s3 patterns. */
8759 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
8760 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
8761 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8763 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8764 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
8765 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
8766 && satisfies_constraint_Rcq (operands
[1])
8767 && satisfies_constraint_L (operands
[2]))
8768 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8771 /* Now try to emit a 32 bit insn without long immediate. */
8773 if (!match
&& match2
&& REG_P (operands
[1]))
8774 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8775 if (match
|| !cond_p
)
8777 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
8778 int range_factor
= neg_intval
& intval
;
8781 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
8782 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8784 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8785 same size, do, so - the insn latency is lower. */
8786 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8788 if ((intval
>= 0 && intval
<= limit
)
8789 || (intval
== -0x800 && limit
== 0x7ff))
8790 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8791 else if ((intval
< 0 && neg_intval
<= limit
)
8792 || (intval
== 0x800 && limit
== 0x7ff))
8793 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8794 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
8795 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
8796 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
8797 if (((intval
< 0 && intval
!= -0x4000)
8798 /* sub[123] is slower than add_s / sub, only use it if it
8799 avoids a long immediate. */
8800 && neg_intval
<= limit
<< shift
)
8801 || (intval
== 0x4000 && limit
== 0x7ff))
8802 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
8803 shift
, neg_intval
>> shift
));
8804 else if ((intval
>= 0 && intval
<= limit
<< shift
)
8805 || (intval
== -0x4000 && limit
== 0x7ff))
8806 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
8808 /* Try to emit a 16 bit opcode with long immediate. */
8810 if (short_p
&& match
)
8811 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8813 /* We have to use a 32 bit opcode, and with a long immediate. */
8815 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8818 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8819 Return the length of the instruction.
8820 If OUTPUT_P is false, don't actually output the instruction, just return
8823 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
8825 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
8826 const char *pat
= NULL
;
8828 /* Canonical rtl should not have a constant in the first operand position. */
8829 gcc_assert (!CONSTANT_P (operands
[1]));
8831 switch (commutative_op
)
8834 if (satisfies_constraint_C1p (operands
[2]))
8835 pat
= "bmsk%? %0,%1,%Z2";
8836 else if (satisfies_constraint_C2p (operands
[2]))
8838 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
8839 pat
= "bmskn%? %0,%1,%Z2";
8841 else if (satisfies_constraint_Ccp (operands
[2]))
8842 pat
= "bclr%? %0,%1,%M2";
8843 else if (satisfies_constraint_CnL (operands
[2]))
8844 pat
= "bic%? %0,%1,%n2-1";
8847 if (satisfies_constraint_C0p (operands
[2]))
8848 pat
= "bset%? %0,%1,%z2";
8851 if (satisfies_constraint_C0p (operands
[2]))
8852 pat
= "bxor%? %0,%1,%z2";
8855 return arc_output_addsi (operands
, true, output_p
);
8859 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
8860 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
8865 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8866 Emit code and return an potentially modified address such that offsets
8867 up to SIZE are can be added to yield a legitimate address.
8868 if REUSE is set, ADDR is a register that may be modified. */
8871 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
8874 rtx offs
= const0_rtx
;
8876 if (GET_CODE (base
) == PLUS
)
8878 offs
= XEXP (base
, 1);
8879 base
= XEXP (base
, 0);
8882 || (REGNO (base
) != STACK_POINTER_REGNUM
8883 && REGNO_PTR_FRAME_P (REGNO (base
)))
8884 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
8885 || !SMALL_INT (INTVAL (offs
) + size
))
8888 emit_insn (gen_add2_insn (addr
, offs
));
8890 addr
= copy_to_mode_reg (Pmode
, addr
);
8895 /* Like move_by_pieces, but take account of load latency, and actual
8896 offset ranges. Return true on success. */
8899 arc_expand_movmem (rtx
*operands
)
8901 rtx dst
= operands
[0];
8902 rtx src
= operands
[1];
8903 rtx dst_addr
, src_addr
;
8905 int align
= INTVAL (operands
[3]);
8912 if (!CONST_INT_P (operands
[2]))
8914 size
= INTVAL (operands
[2]);
8915 /* move_by_pieces_ninsns is static, so we can't use it. */
8919 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
8921 n_pieces
= (size
+ 2) / 4U + (size
& 1);
8923 else if (align
== 2)
8924 n_pieces
= (size
+ 1) / 2U;
8927 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
8929 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8931 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
8935 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
8936 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
8937 store
[0] = store
[1] = NULL_RTX
;
8938 tmpx
[0] = tmpx
[1] = NULL_RTX
;
8939 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
8944 while (piece
> size
)
8946 mode
= smallest_int_mode_for_size (piece
* BITS_PER_UNIT
);
8947 /* If we don't re-use temporaries, the scheduler gets carried away,
8948 and the register pressure gets unnecessarily high. */
8949 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
8952 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
8953 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
8954 src_addr
= force_offsettable (src_addr
, piece
, 1);
8956 emit_insn (store
[i
]);
8957 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
8958 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
8959 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
8960 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
8963 emit_insn (store
[i
]);
8965 emit_insn (store
[i
^1]);
8970 arc_get_aux_arg (rtx pat
, int *auxr
)
8972 tree attr
, addr
= MEM_EXPR (pat
);
8973 if (TREE_CODE (addr
) != VAR_DECL
)
8976 attr
= DECL_ATTRIBUTES (addr
);
8977 if (lookup_attribute ("aux", attr
))
8979 tree arg
= TREE_VALUE (attr
);
8982 *auxr
= TREE_INT_CST_LOW (TREE_VALUE (arg
));
8990 /* Prepare operands for move in MODE. Return true iff the move has
8994 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8996 /* First handle aux attribute. */
8998 && (MEM_P (operands
[0]) || MEM_P (operands
[1])))
9002 if (MEM_P (operands
[0]) && arc_is_aux_reg_p (operands
[0]))
9004 /* Save operation. */
9005 if (arc_get_aux_arg (operands
[0], &auxr
))
9007 tmp
= gen_reg_rtx (SImode
);
9008 emit_move_insn (tmp
, GEN_INT (auxr
));
9012 tmp
= XEXP (operands
[0], 0);
9015 operands
[1] = force_reg (SImode
, operands
[1]);
9016 emit_insn (gen_rtx_UNSPEC_VOLATILE
9017 (VOIDmode
, gen_rtvec (2, operands
[1], tmp
),
9021 if (MEM_P (operands
[1]) && arc_is_aux_reg_p (operands
[1]))
9023 if (arc_get_aux_arg (operands
[1], &auxr
))
9025 tmp
= gen_reg_rtx (SImode
);
9026 emit_move_insn (tmp
, GEN_INT (auxr
));
9030 tmp
= XEXP (operands
[1], 0);
9031 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
9033 /* Load operation. */
9034 gcc_assert (REG_P (operands
[0]));
9035 emit_insn (gen_rtx_SET (operands
[0],
9036 gen_rtx_UNSPEC_VOLATILE
9037 (SImode
, gen_rtvec (1, tmp
),
9043 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
9045 prepare_pic_move (operands
, SImode
);
9047 /* Disable any REG_EQUALs associated with the symref
9048 otherwise the optimization pass undoes the work done
9049 here and references the variable directly. */
9052 if (MEM_P (operands
[0])
9053 && !(reload_in_progress
|| reload_completed
))
9055 operands
[1] = force_reg (mode
, operands
[1]);
9056 if (!move_dest_operand (operands
[0], mode
))
9058 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
9059 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
9060 except that we can't use that function because it is static. */
9061 rtx pat
= change_address (operands
[0], mode
, addr
);
9062 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
9065 if (!cse_not_expected
)
9067 rtx pat
= XEXP (operands
[0], 0);
9069 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
9072 pat
= change_address (operands
[0], mode
, pat
);
9073 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
9079 if (MEM_P (operands
[1]) && !cse_not_expected
)
9081 rtx pat
= XEXP (operands
[1], 0);
9083 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
9086 pat
= change_address (operands
[1], mode
, pat
);
9087 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
9095 /* Output a library call to a function called FNAME that has been arranged
9096 to be local to any dso. */
9099 arc_output_libcall (const char *fname
)
9101 unsigned len
= strlen (fname
);
9102 static char buf
[64];
9104 gcc_assert (len
< sizeof buf
- 35);
9105 if (TARGET_LONG_CALLS_SET
9106 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
9109 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
9111 sprintf (buf
, "jl%%! @%s", fname
);
9114 sprintf (buf
, "bl%%!%%* @%s", fname
);
9118 /* Return the SImode highpart of the DImode value IN. */
9121 disi_highpart (rtx in
)
9123 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
9126 /* Return length adjustment for INSN.
9128 A write to a core reg greater or equal to 32 must not be immediately
9129 followed by a use. Anticipate the length requirement to insert a nop
9130 between PRED and SUCC to prevent a hazard. */
9133 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
9137 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
9138 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
9139 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
9140 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
9141 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
9142 || recog_memoized (pred
) == CODE_FOR_umul_600
9143 || recog_memoized (pred
) == CODE_FOR_mac_600
9144 || recog_memoized (pred
) == CODE_FOR_mul64_600
9145 || recog_memoized (pred
) == CODE_FOR_mac64_600
9146 || recog_memoized (pred
) == CODE_FOR_umul64_600
9147 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
9149 subrtx_iterator::array_type array
;
9150 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
9152 const_rtx x
= *iter
;
9153 switch (GET_CODE (x
))
9155 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9158 /* This is also fine for PRE/POST_MODIFY, because they
9162 rtx dest
= XEXP (x
, 0);
9163 /* Check if this sets a an extension register. N.B. we use 61 for the
9164 condition codes, which is definitely not an extension register. */
9165 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
9166 /* Check if the same register is used by the PAT. */
9167 && (refers_to_regno_p
9169 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
9170 PATTERN (succ
), 0)))
9176 /* Given a rtx, check if it is an assembly instruction or not. */
9179 arc_asm_insn_p (rtx x
)
9186 switch (GET_CODE (x
))
9193 return arc_asm_insn_p (SET_SRC (x
));
9197 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
9198 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
9211 A write to a core reg greater or equal to 32 must not be immediately
9212 followed by a use. Anticipate the length requirement to insert a nop
9213 between PRED and SUCC to prevent a hazard. */
9216 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
9218 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
9222 return arc600_corereg_hazard (pred
, succ
);
9227 /* Return length adjustment for INSN. */
9230 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
9234 /* We already handle sequences by ignoring the delay sequence flag. */
9235 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9238 /* Check for return with but one preceding insn since function
9240 if (TARGET_PAD_RETURN
9242 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
9243 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
9244 && get_attr_type (insn
) == TYPE_RETURN
)
9246 rtx_insn
*prev
= prev_active_insn (insn
);
9248 if (!prev
|| !(prev
= prev_active_insn (prev
))
9249 || ((NONJUMP_INSN_P (prev
)
9250 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9251 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9253 : CALL_ATTR (prev
, NON_SIBCALL
)))
9258 rtx_insn
*succ
= next_real_insn (insn
);
9260 /* One the ARC600, a write to an extension register must be separated
9262 if (succ
&& INSN_P (succ
))
9263 len
+= arc600_corereg_hazard (insn
, succ
);
9266 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9268 extract_constrain_insn_cached (insn
);
9273 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
9274 CC field of *STATEP. */
9277 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
9279 rtx cond
= statep
->cond
;
9280 int raw_cc
= get_arc_condition_code (cond
);
9282 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
9284 if (statep
->cc
== raw_cc
)
9285 return copy_rtx (cond
);
9287 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
9289 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9290 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9291 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9292 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9294 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9295 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
9298 /* Return version of PAT conditionalized with COND, which is part of INSN.
9299 ANNULLED indicates if INSN is an annulled delay-slot insn.
9300 Register further changes if necessary. */
9302 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
9304 /* For commutative operators, we generally prefer to have
9305 the first source match the destination. */
9306 if (GET_CODE (pat
) == SET
)
9308 rtx src
= SET_SRC (pat
);
9310 if (COMMUTATIVE_P (src
))
9312 rtx src0
= XEXP (src
, 0);
9313 rtx src1
= XEXP (src
, 1);
9314 rtx dst
= SET_DEST (pat
);
9316 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
9317 /* Leave add_n alone - the canonical form is to
9318 have the complex summand first. */
9320 pat
= gen_rtx_SET (dst
,
9321 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
9326 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
9327 what to do with COND_EXEC. */
9328 if (RTX_FRAME_RELATED_P (insn
))
9330 /* If this is the delay slot insn of an anulled branch,
9331 dwarf2out.c:scan_trace understands the anulling semantics
9332 without the COND_EXEC. */
9333 gcc_assert (annulled
);
9334 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
9336 validate_change (insn
, ®_NOTES (insn
), note
, 1);
9338 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
9342 /* Use the ccfsm machinery to do if conversion. */
9347 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
9349 memset (statep
, 0, sizeof *statep
);
9350 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
9352 arc_ccfsm_advance (insn
, statep
);
9354 switch (statep
->state
)
9360 /* Deleted branch. */
9361 arc_ccfsm_post_advance (insn
, statep
);
9362 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
9363 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
9364 if (GET_CODE (PATTERN (seq
)) == SEQUENCE
)
9366 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
9367 rtx pat
= PATTERN (slot
);
9368 if (INSN_ANNULLED_BRANCH_P (insn
))
9371 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
9372 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
9374 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
9376 PUT_CODE (slot
, NOTE
);
9377 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
9381 set_insn_deleted (insn
);
9387 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
9389 arc_ccfsm_post_advance (insn
, statep
);
9390 if (--LABEL_NUSES (insn
) == 0)
9396 if (!NONDEBUG_INSN_P (insn
))
9399 /* Conditionalized insn. */
9401 rtx_insn
*prev
, *pprev
;
9402 rtx
*patp
, pat
, cond
;
9403 bool annulled
; annulled
= false;
9405 /* If this is a delay slot insn in a non-annulled branch,
9406 don't conditionalize it. N.B., this should be fine for
9407 conditional return too. However, don't do this for
9408 unconditional branches, as these would be encountered when
9409 processing an 'else' part. */
9410 prev
= PREV_INSN (insn
);
9411 pprev
= PREV_INSN (prev
);
9412 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
9413 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
9415 if (!INSN_ANNULLED_BRANCH_P (prev
))
9420 patp
= &PATTERN (insn
);
9422 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
9423 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
9425 /* ??? don't conditionalize if all side effects are dead
9426 in the not-execute case. */
9428 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
9430 else if (simplejump_p (insn
))
9432 patp
= &SET_SRC (pat
);
9433 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
9435 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
9437 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
9438 pat
= gen_rtx_SET (pc_rtx
, pat
);
9442 validate_change (insn
, patp
, pat
, 1);
9443 if (!apply_change_group ())
9447 rtx_insn
*next
= next_nonnote_insn (insn
);
9448 if (GET_CODE (next
) == BARRIER
)
9450 if (statep
->state
== 3)
9457 arc_ccfsm_post_advance (insn
, statep
);
9462 /* Find annulled delay insns and convert them to use the appropriate predicate.
9463 This allows branch shortening to size up these insns properly. */
9466 arc_predicate_delay_insns (void)
9468 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9470 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
9473 if (!NONJUMP_INSN_P (insn
)
9474 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
9476 jump
= XVECEXP (pat
, 0, 0);
9477 dlay
= XVECEXP (pat
, 0, 1);
9478 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
9480 /* If the branch insn does the annulling, leave the delay insn alone. */
9481 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
9483 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9484 on the other path. */
9485 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
9486 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
9487 src
= SET_SRC (PATTERN (jump
));
9488 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
9489 cond
= XEXP (src
, 0);
9490 if (XEXP (src
, 2) == pc_rtx
)
9492 else if (XEXP (src
, 1) == pc_rtx
)
9496 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
9498 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9499 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9500 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9501 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9503 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9504 copy_rtx (XEXP (cond
, 0)),
9505 copy_rtx (XEXP (cond
, 1)));
9508 cond
= copy_rtx (cond
);
9509 patp
= &PATTERN (dlay
);
9511 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9512 validate_change (dlay
, patp
, pat
, 1);
9513 if (!apply_change_group ())
9519 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9520 (other than of a forward brcc), it creates a hazard when there is a read
9521 of the same register at the branch target. We can't know what is at the
9522 branch target of calls, and for branches, we don't really know before the
9523 end of delay slot scheduling, either. Not only can individual instruction
9524 be hoisted out into a delay slot, a basic block can also be emptied this
9525 way, and branch and/or fall through targets be redirected. Hence we don't
9526 want such writes in a delay slot. */
9528 /* Return nonzreo iff INSN writes to an extension core register. */
9531 arc_write_ext_corereg (rtx insn
)
9533 subrtx_iterator::array_type array
;
9534 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9536 const_rtx x
= *iter
;
9537 switch (GET_CODE (x
))
9539 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9542 /* This is also fine for PRE/POST_MODIFY, because they
9546 const_rtx dest
= XEXP (x
, 0);
9547 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9553 /* This is like the hook, but returns NULL when it can't / won't generate
9554 a legitimate address. */
9557 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9562 if (flag_pic
&& SYMBOLIC_CONST (x
))
9563 (x
) = arc_legitimize_pic_address (x
, 0);
9565 if (GET_CODE (addr
) == CONST
)
9566 addr
= XEXP (addr
, 0);
9567 if (GET_CODE (addr
) == PLUS
9568 && CONST_INT_P (XEXP (addr
, 1))
9569 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9570 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9571 || (REG_P (XEXP (addr
, 0))
9572 && (INTVAL (XEXP (addr
, 1)) & 252))))
9574 HOST_WIDE_INT offs
, upper
;
9575 int size
= GET_MODE_SIZE (mode
);
9577 offs
= INTVAL (XEXP (addr
, 1));
9578 upper
= (offs
+ 256 * size
) & ~511 * size
;
9579 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9580 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9581 if (GET_CODE (x
) == CONST
)
9582 inner
= gen_rtx_CONST (Pmode
, inner
);
9584 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9587 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9588 x
= force_reg (Pmode
, x
);
9589 if (memory_address_p ((machine_mode
) mode
, x
))
9595 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9597 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9599 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9601 return arc_legitimize_tls_address (orig_x
, model
);
9604 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9612 arc_delegitimize_address_0 (rtx op
)
9614 switch (GET_CODE (op
))
9617 return arc_delegitimize_address_0 (XEXP (op
, 0));
9620 switch (XINT (op
, 1))
9622 case ARC_UNSPEC_GOT
:
9623 case ARC_UNSPEC_GOTOFFPC
:
9624 return XVECEXP (op
, 0, 0);
9632 rtx t1
= arc_delegitimize_address_0 (XEXP (op
, 0));
9633 rtx t2
= XEXP (op
, 1);
9636 return gen_rtx_PLUS (GET_MODE (op
), t1
, t2
);
9647 arc_delegitimize_address (rtx orig_x
)
9654 x
= arc_delegitimize_address_0 (x
);
9659 x
= replace_equiv_address_nv (orig_x
, x
);
9663 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9664 differ from the hardware register number in order to allow the generic
9665 code to correctly split the concatenation of acc1 and acc2. */
9670 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9673 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9674 differ from the hardware register number in order to allow the generic
9675 code to correctly split the concatenation of acc1 and acc2. */
9680 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9683 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9684 differ from the hardware register number in order to allow the generic
9685 code to correctly split the concatenation of mhi and mlo. */
9690 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9693 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9694 differ from the hardware register number in order to allow the generic
9695 code to correctly split the concatenation of mhi and mlo. */
9700 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9703 /* FIXME: a parameter should be added, and code added to final.c,
9704 to reproduce this functionality in shorten_branches. */
9706 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9707 a previous instruction. */
9709 arc_unalign_branch_p (rtx branch
)
9713 if (!TARGET_UNALIGN_BRANCH
)
9715 /* Do not do this if we have a filled delay slot. */
9716 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9717 && !NEXT_INSN (branch
)->deleted ())
9719 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9721 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9722 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9726 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9727 are three reasons why we need to consider branches to be length 6:
9728 - annull-false delay slot insns are implemented using conditional execution,
9729 thus preventing short insn formation where used.
9730 - for ARC600: annul-true delay slot insns are implemented where possible
9731 using conditional execution, preventing short insn formation where used.
9732 - for ARC700: likely or somewhat likely taken branches are made long and
9733 unaligned if possible to avoid branch penalty. */
9736 arc_branch_size_unknown_p (void)
9738 return !optimize_size
&& arc_reorg_in_progress
;
9741 /* The usual; we set up our machine_function data. */
9743 static struct machine_function
*
9744 arc_init_machine_status (void)
9746 struct machine_function
*machine
;
9747 machine
= ggc_cleared_alloc
<machine_function
> ();
9748 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9753 /* Implements INIT_EXPANDERS. We just set up to call the above
9757 arc_init_expanders (void)
9759 init_machine_status
= arc_init_machine_status
;
9762 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9763 indicates a number of elements to ignore - that allows to have a
9764 sibcall pattern that starts with (return). LOAD_P is zero for store
9765 multiple (for prologues), and one for load multiples (for epilogues),
9766 and two for load multiples where no final clobber of blink is required.
9767 We also skip the first load / store element since this is supposed to
9768 be checked in the instruction pattern. */
9771 arc_check_millicode (rtx op
, int offset
, int load_p
)
9773 int len
= XVECLEN (op
, 0) - offset
;
9778 if (len
< 2 || len
> 13)
9784 rtx elt
= XVECEXP (op
, 0, --len
);
9786 if (GET_CODE (elt
) != CLOBBER
9787 || !REG_P (XEXP (elt
, 0))
9788 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9789 || len
< 3 || len
> 13)
9792 for (i
= 1; i
< len
; i
++)
9794 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9797 if (GET_CODE (elt
) != SET
)
9799 mem
= XEXP (elt
, load_p
);
9800 reg
= XEXP (elt
, 1-load_p
);
9801 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9803 addr
= XEXP (mem
, 0);
9804 if (GET_CODE (addr
) != PLUS
9805 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9806 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9812 /* Accessor functions for cfun->machine->unalign. */
9815 arc_get_unalign (void)
9817 return cfun
->machine
->unalign
;
9821 arc_clear_unalign (void)
9824 cfun
->machine
->unalign
= 0;
9828 arc_toggle_unalign (void)
9830 cfun
->machine
->unalign
^= 2;
9833 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9834 constant in operand 2, but which would require a LIMM because of
9836 operands 3 and 4 are new SET_SRCs for operands 0. */
9839 split_addsi (rtx
*operands
)
9841 int val
= INTVAL (operands
[2]);
9843 /* Try for two short insns first. Lengths being equal, we prefer
9844 expansions with shorter register lifetimes. */
9845 if (val
> 127 && val
<= 255
9846 && satisfies_constraint_Rcq (operands
[0]))
9848 operands
[3] = operands
[2];
9849 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9853 operands
[3] = operands
[1];
9854 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9858 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9859 constant in operand 1, but which would require a LIMM because of
9861 operands 3 and 4 are new SET_SRCs for operands 0. */
9864 split_subsi (rtx
*operands
)
9866 int val
= INTVAL (operands
[1]);
9868 /* Try for two short insns first. Lengths being equal, we prefer
9869 expansions with shorter register lifetimes. */
9870 if (satisfies_constraint_Rcq (operands
[0])
9871 && satisfies_constraint_Rcq (operands
[2]))
9873 if (val
>= -31 && val
<= 127)
9875 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9876 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9879 else if (val
>= 0 && val
< 255)
9881 operands
[3] = operands
[1];
9882 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9886 /* If the destination is not an ARCompact16 register, we might
9887 still have a chance to make a short insn if the source is;
9888 we need to start with a reg-reg move for this. */
9889 operands
[3] = operands
[2];
9890 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9893 /* Handle DOUBLE_REGS uses.
9894 Operand 0: destination register
9895 Operand 1: source register */
9898 arc_process_double_reg_moves (rtx
*operands
)
9900 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9901 enum usesDxState state
= none
;
9902 rtx dest
= operands
[0];
9903 rtx src
= operands
[1];
9905 if (refers_to_regno_p (40, 44, src
, 0))
9908 gcc_assert (REG_P (dest
));
9910 if (refers_to_regno_p (40, 44, dest
, 0))
9912 /* Via arc_register_move_cost, we should never see D,D moves. */
9913 gcc_assert (REG_P (src
));
9914 gcc_assert (state
== none
);
9923 /* Without the LR insn, we need to split this into a
9924 sequence of insns which will use the DEXCLx and DADDHxy
9925 insns to be able to read the Dx register in question. */
9926 if (TARGET_DPFP_DISABLE_LRSR
)
9928 /* gen *movdf_insn_nolrsr */
9929 rtx set
= gen_rtx_SET (dest
, src
);
9930 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9931 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9935 /* When we have 'mov D, r' or 'mov D, D' then get the target
9936 register pair for use with LR insn. */
9937 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9938 TARGET_BIG_ENDIAN
? 0 : 4);
9939 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9940 TARGET_BIG_ENDIAN
? 4 : 0);
9942 /* Produce the two LR insns to get the high and low parts. */
9943 emit_insn (gen_rtx_SET (destHigh
,
9944 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9946 VUNSPEC_ARC_LR_HIGH
)));
9947 emit_insn (gen_rtx_SET (destLow
,
9948 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9953 else if (state
== destDx
)
9955 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9956 LR insn get the target register pair. */
9957 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9958 TARGET_BIG_ENDIAN
? 0 : 4);
9959 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9960 TARGET_BIG_ENDIAN
? 4 : 0);
9962 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9970 /* operands 0..1 are the operands of a 64 bit move instruction.
9971 split it into two moves with operands 2/3 and 4/5. */
9974 arc_split_move (rtx
*operands
)
9976 machine_mode mode
= GET_MODE (operands
[0]);
9983 if (arc_process_double_reg_moves (operands
))
9988 && ((memory_operand (operands
[0], mode
)
9989 && (even_register_operand (operands
[1], mode
)
9990 || satisfies_constraint_Cm3 (operands
[1])))
9991 || (memory_operand (operands
[1], mode
)
9992 && even_register_operand (operands
[0], mode
))))
9994 emit_move_insn (operands
[0], operands
[1]);
9998 if (TARGET_PLUS_QMACW
9999 && GET_CODE (operands
[1]) == CONST_VECTOR
)
10001 HOST_WIDE_INT intval0
, intval1
;
10002 if (GET_MODE (operands
[1]) == V2SImode
)
10004 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
10005 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
10009 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
10010 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
10011 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
10012 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
10014 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
10015 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
10016 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
10017 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
10018 emit_move_insn (xop
[0], xop
[2]);
10019 emit_move_insn (xop
[3], xop
[1]);
10023 for (i
= 0; i
< 2; i
++)
10025 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
10027 rtx addr
= XEXP (operands
[i
], 0);
10029 enum rtx_code code
;
10031 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
10032 switch (GET_CODE (addr
))
10034 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
10035 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
10036 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
10040 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
10041 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
10042 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
10044 code
= POST_MODIFY
;
10048 gcc_unreachable ();
10050 r
= XEXP (addr
, 0);
10051 xop
[0+i
] = adjust_automodify_address_nv
10052 (operands
[i
], SImode
,
10053 gen_rtx_fmt_ee (code
, Pmode
, r
,
10054 gen_rtx_PLUS (Pmode
, r
, o
)),
10056 xop
[2+i
] = adjust_automodify_address_nv
10057 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
10061 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
10062 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
10065 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
10068 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
10071 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
10072 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
10076 /* Select between the instruction output templates s_tmpl (for short INSNs)
10077 and l_tmpl (for long INSNs). */
10080 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
10082 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
10084 extract_constrain_insn_cached (insn
);
10085 return is_short
? s_tmpl
: l_tmpl
;
10088 /* Searches X for any reference to REGNO, returning the rtx of the
10089 reference found if any. Otherwise, returns NULL_RTX. */
10092 arc_regno_use_in (unsigned int regno
, rtx x
)
10098 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
10101 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
10102 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
10106 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
10109 else if (fmt
[i
] == 'E')
10110 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
10111 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
10118 /* Return the integer value of the "type" attribute for INSN, or -1 if
10119 INSN can't have attributes. */
10122 arc_attr_type (rtx_insn
*insn
)
10124 if (NONJUMP_INSN_P (insn
)
10125 ? (GET_CODE (PATTERN (insn
)) == USE
10126 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
10128 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
10129 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
10132 return get_attr_type (insn
);
10135 /* Return true if insn sets the condition codes. */
10138 arc_sets_cc_p (rtx_insn
*insn
)
10140 if (NONJUMP_INSN_P (insn
))
10141 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
10142 insn
= seq
->insn (seq
->len () - 1);
10143 return arc_attr_type (insn
) == TYPE_COMPARE
;
10146 /* Return true if INSN is an instruction with a delay slot we may want
10150 arc_need_delay (rtx_insn
*insn
)
10154 if (!flag_delayed_branch
)
10156 /* The return at the end of a function needs a delay slot. */
10157 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
10158 && (!(next
= next_active_insn (insn
))
10159 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
10160 && arc_attr_type (next
) == TYPE_RETURN
))
10161 && (!TARGET_PAD_RETURN
10162 || (prev_active_insn (insn
)
10163 && prev_active_insn (prev_active_insn (insn
))
10164 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
10166 if (NONJUMP_INSN_P (insn
)
10167 ? (GET_CODE (PATTERN (insn
)) == USE
10168 || GET_CODE (PATTERN (insn
)) == CLOBBER
10169 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
10171 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
10172 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
10175 return num_delay_slots (insn
) != 0;
10178 /* Return true if the scheduling pass(es) has/have already run,
10179 i.e. where possible, we should try to mitigate high latencies
10180 by different instruction selection. */
10183 arc_scheduling_not_expected (void)
10185 return cfun
->machine
->arc_reorg_started
;
10188 /* Code has a minimum p2 alignment of 1, which we must restore after
10189 an ADDR_DIFF_VEC. */
10192 arc_label_align (rtx_insn
*label
)
10194 if (align_labels
.levels
[0].log
< 1)
10196 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
10197 if (INSN_P (next
) && recog_memoized (next
) >= 0)
10200 return align_labels
.levels
[0].log
;
10203 /* Return true if LABEL is in executable code. */
10206 arc_text_label (rtx_insn
*label
)
10210 /* ??? We use deleted labels like they were still there, see
10211 gcc.c-torture/compile/20000326-2.c . */
10212 gcc_assert (GET_CODE (label
) == CODE_LABEL
10213 || (GET_CODE (label
) == NOTE
10214 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
10215 next
= next_nonnote_insn (label
);
10217 return (!JUMP_TABLE_DATA_P (next
)
10218 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
10219 else if (!PREV_INSN (label
))
10220 /* ??? sometimes text labels get inserted very late, see
10221 gcc.dg/torture/stackalign/comp-goto-1.c */
10226 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
10227 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
10228 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
10229 to redirect two breqs. */
10232 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
10234 /* ??? get_attr_type is declared to take an rtx. */
10235 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
10238 if (CROSSING_JUMP_P (followee
))
10239 switch (get_attr_type (u
.r
))
10242 if (get_attr_length (u
.r
) != 2)
10244 /* Fall through. */
10246 case TYPE_BRCC_NO_DELAY_SLOT
:
10254 /* Return the register number of the register holding the return address
10255 for a function of type TYPE. */
10258 arc_return_address_register (unsigned int fn_type
)
10262 if (ARC_INTERRUPT_P (fn_type
))
10264 if ((fn_type
& (ARC_FUNCTION_ILINK1
| ARC_FUNCTION_FIRQ
)) != 0)
10265 regno
= ILINK1_REG
;
10266 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
10267 regno
= ILINK2_REG
;
10269 gcc_unreachable ();
10271 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
10272 regno
= RETURN_ADDR_REGNUM
;
10274 gcc_assert (regno
!= 0);
10278 /* Implement EPILOGUE_USES.
10279 Return true if REGNO should be added to the deemed uses of the epilogue.
10281 We have to make sure all the register restore instructions are
10282 known to be live in interrupt functions, plus the blink register if
10283 it is clobbered by the isr. */
10286 arc_epilogue_uses (int regno
)
10288 unsigned int fn_type
;
10290 if (regno
== arc_tp_regno
)
10293 fn_type
= arc_compute_function_type (cfun
);
10294 if (reload_completed
)
10296 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
10298 if (!fixed_regs
[regno
])
10300 return ((regno
== arc_return_address_register (fn_type
))
10301 || (regno
== RETURN_ADDR_REGNUM
));
10304 return regno
== RETURN_ADDR_REGNUM
;
10307 return regno
== arc_return_address_register (fn_type
);
10310 /* Helper for EH_USES macro. */
10313 arc_eh_uses (int regno
)
10315 if (regno
== arc_tp_regno
)
10320 /* Return true if we use LRA instead of reload pass. */
10325 return arc_lra_flag
;
10328 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10329 Rcq registers, because some insn are shorter with them. OTOH we already
10330 have separate alternatives for this purpose, and other insns don't
10331 mind, so maybe we should rather prefer the other registers?
10332 We need more data, and we can only get that if we allow people to
10333 try all options. */
10335 arc_register_priority (int r
)
10337 switch (arc_lra_priority_tag
)
10339 case ARC_LRA_PRIORITY_NONE
:
10341 case ARC_LRA_PRIORITY_NONCOMPACT
:
10342 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
10343 case ARC_LRA_PRIORITY_COMPACT
:
10344 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
10346 gcc_unreachable ();
10351 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
10353 return GENERAL_REGS
;
10357 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
10361 enum reload_type type
= (enum reload_type
) itype
;
10363 if (GET_CODE (x
) == PLUS
10364 && CONST_INT_P (XEXP (x
, 1))
10365 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
10366 || (REG_P (XEXP (x
, 0))
10367 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
10369 int scale
= GET_MODE_SIZE (mode
);
10371 rtx index_rtx
= XEXP (x
, 1);
10372 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
10373 rtx reg
, sum
, sum2
;
10377 if ((scale
-1) & offset
)
10379 shift
= scale
>> 1;
10381 = ((offset
+ (256 << shift
))
10382 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
10383 /* Sometimes the normal form does not suit DImode. We
10384 could avoid that by using smaller ranges, but that
10385 would give less optimized code when SImode is
10387 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
10392 regno
= REGNO (reg
);
10393 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
10395 if (reg_equiv_constant (regno
))
10397 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
10399 if (GET_CODE (sum2
) == PLUS
)
10400 sum2
= gen_rtx_CONST (Pmode
, sum2
);
10402 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
10403 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
10404 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
10409 /* We must re-recognize what we created before. */
10410 else if (GET_CODE (x
) == PLUS
10411 && GET_CODE (XEXP (x
, 0)) == PLUS
10412 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
10413 && REG_P (XEXP (XEXP (x
, 0), 0))
10414 && CONST_INT_P (XEXP (x
, 1)))
10416 /* Because this address is so complex, we know it must have
10417 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10418 it is already unshared, and needs no further unsharing. */
10419 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
10420 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
10426 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10429 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
10430 unsigned int align
,
10431 enum by_pieces_operation op
,
10434 /* Let the movmem expander handle small block moves. */
10435 if (op
== MOVE_BY_PIECES
)
10438 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
10441 /* Emit a (pre) memory barrier around an atomic sequence according to
10445 arc_pre_atomic_barrier (enum memmodel model
)
10447 if (need_atomic_barrier_p (model
, true))
10448 emit_insn (gen_memory_barrier ());
10451 /* Emit a (post) memory barrier around an atomic sequence according to
10455 arc_post_atomic_barrier (enum memmodel model
)
10457 if (need_atomic_barrier_p (model
, false))
10458 emit_insn (gen_memory_barrier ());
10461 /* Expand a compare and swap pattern. */
10464 emit_unlikely_jump (rtx insn
)
10466 rtx_insn
*jump
= emit_jump_insn (insn
);
10467 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10470 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10471 32-bit compare and swap on the word containing the byte or
10472 half-word. The difference between a weak and a strong CAS is that
10473 the weak version may simply fail. The strong version relies on two
10474 loops, one checks if the SCOND op is succsfully or not, the other
10475 checks if the 32 bit accessed location which contains the 8 or 16
10476 bit datum is not changed by other thread. The first loop is
10477 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10478 loops is implemented by this routine. */
10481 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10482 rtx oldval
, rtx newval
, rtx weak
,
10483 rtx mod_s
, rtx mod_f
)
10485 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10486 rtx addr
= gen_reg_rtx (Pmode
);
10487 rtx off
= gen_reg_rtx (SImode
);
10488 rtx oldv
= gen_reg_rtx (SImode
);
10489 rtx newv
= gen_reg_rtx (SImode
);
10490 rtx oldvalue
= gen_reg_rtx (SImode
);
10491 rtx newvalue
= gen_reg_rtx (SImode
);
10492 rtx res
= gen_reg_rtx (SImode
);
10493 rtx resv
= gen_reg_rtx (SImode
);
10494 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10496 bool is_weak
= (weak
!= const0_rtx
);
10498 /* Truncate the address. */
10499 emit_insn (gen_rtx_SET (addr
,
10500 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10502 /* Compute the datum offset. */
10503 emit_insn (gen_rtx_SET (off
,
10504 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10505 if (TARGET_BIG_ENDIAN
)
10506 emit_insn (gen_rtx_SET (off
,
10507 gen_rtx_MINUS (SImode
,
10508 (GET_MODE (mem
) == QImode
) ?
10509 GEN_INT (3) : GEN_INT (2), off
)));
10511 /* Normal read from truncated address. */
10512 memsi
= gen_rtx_MEM (SImode
, addr
);
10513 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10514 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10516 val
= copy_to_reg (memsi
);
10518 /* Convert the offset in bits. */
10519 emit_insn (gen_rtx_SET (off
,
10520 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10522 /* Get the proper mask. */
10523 if (GET_MODE (mem
) == QImode
)
10524 mask
= force_reg (SImode
, GEN_INT (0xff));
10526 mask
= force_reg (SImode
, GEN_INT (0xffff));
10528 emit_insn (gen_rtx_SET (mask
,
10529 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10531 /* Prepare the old and new values. */
10532 emit_insn (gen_rtx_SET (val
,
10533 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10536 oldval
= gen_lowpart (SImode
, oldval
);
10537 emit_insn (gen_rtx_SET (oldv
,
10538 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10540 newval
= gen_lowpart_common (SImode
, newval
);
10541 emit_insn (gen_rtx_SET (newv
,
10542 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10544 emit_insn (gen_rtx_SET (oldv
,
10545 gen_rtx_AND (SImode
, oldv
, mask
)));
10547 emit_insn (gen_rtx_SET (newv
,
10548 gen_rtx_AND (SImode
, newv
, mask
)));
10552 end_label
= gen_label_rtx ();
10553 loop_label
= gen_label_rtx ();
10554 emit_label (loop_label
);
10557 /* Make the old and new values. */
10558 emit_insn (gen_rtx_SET (oldvalue
,
10559 gen_rtx_IOR (SImode
, oldv
, val
)));
10561 emit_insn (gen_rtx_SET (newvalue
,
10562 gen_rtx_IOR (SImode
, newv
, val
)));
10564 /* Try an 32bit atomic compare and swap. It clobbers the CC
10566 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10567 weak
, mod_s
, mod_f
));
10569 /* Regardless of the weakness of the operation, a proper boolean
10570 result needs to be provided. */
10571 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10572 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10573 emit_insn (gen_rtx_SET (bool_result
, x
));
10577 /* Check the results: if the atomic op is successfully the goto
10579 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10580 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10581 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10582 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10583 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10585 /* Wait for the right moment when the accessed 32-bit location
10587 emit_insn (gen_rtx_SET (resv
,
10588 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10590 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10591 cc
= gen_rtx_REG (mode
, CC_REG
);
10592 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10594 /* Set the new value of the 32 bit location, proper masked. */
10595 emit_insn (gen_rtx_SET (val
, resv
));
10597 /* Try again if location is unstable. Fall through if only
10598 scond op failed. */
10599 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10600 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10601 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10602 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10604 emit_label (end_label
);
10607 /* End: proper return the result for the given mode. */
10608 emit_insn (gen_rtx_SET (res
,
10609 gen_rtx_AND (SImode
, res
, mask
)));
10611 emit_insn (gen_rtx_SET (res
,
10612 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10614 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10617 /* Helper function used by "atomic_compare_and_swap" expand
10621 arc_expand_compare_and_swap (rtx operands
[])
10623 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10626 bval
= operands
[0];
10627 rval
= operands
[1];
10629 oldval
= operands
[3];
10630 newval
= operands
[4];
10631 is_weak
= operands
[5];
10632 mod_s
= operands
[6];
10633 mod_f
= operands
[7];
10634 mode
= GET_MODE (mem
);
10636 if (reg_overlap_mentioned_p (rval
, oldval
))
10637 oldval
= copy_to_reg (oldval
);
10639 if (mode
== SImode
)
10641 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10642 is_weak
, mod_s
, mod_f
));
10643 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10644 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10645 emit_insn (gen_rtx_SET (bval
, x
));
10649 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10650 is_weak
, mod_s
, mod_f
);
10654 /* Helper function used by the "atomic_compare_and_swapsi_1"
10658 arc_split_compare_and_swap (rtx operands
[])
10660 rtx rval
, mem
, oldval
, newval
;
10662 enum memmodel mod_s
, mod_f
;
10664 rtx label1
, label2
, x
, cond
;
10666 rval
= operands
[0];
10668 oldval
= operands
[2];
10669 newval
= operands
[3];
10670 is_weak
= (operands
[4] != const0_rtx
);
10671 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10672 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10673 mode
= GET_MODE (mem
);
10675 /* ARC atomic ops work only with 32-bit aligned memories. */
10676 gcc_assert (mode
== SImode
);
10678 arc_pre_atomic_barrier (mod_s
);
10683 label1
= gen_label_rtx ();
10684 emit_label (label1
);
10686 label2
= gen_label_rtx ();
10688 /* Load exclusive. */
10689 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10691 /* Check if it is oldval. */
10692 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10693 cond
= gen_rtx_REG (mode
, CC_REG
);
10694 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10696 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10697 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10698 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10699 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10701 /* Exclusively store new item. Store clobbers CC reg. */
10702 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10706 /* Check the result of the store. */
10707 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10708 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10709 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10710 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10711 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10714 if (mod_f
!= MEMMODEL_RELAXED
)
10715 emit_label (label2
);
10717 arc_post_atomic_barrier (mod_s
);
10719 if (mod_f
== MEMMODEL_RELAXED
)
10720 emit_label (label2
);
10723 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10724 to perform. MEM is the memory on which to operate. VAL is the second
10725 operand of the binary operator. BEFORE and AFTER are optional locations to
10726 return the value of MEM either before of after the operation. MODEL_RTX
10727 is a CONST_INT containing the memory model to use. */
10730 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10731 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10733 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10734 machine_mode mode
= GET_MODE (mem
);
10735 rtx label
, x
, cond
;
10736 rtx before
= orig_before
, after
= orig_after
;
10738 /* ARC atomic ops work only with 32-bit aligned memories. */
10739 gcc_assert (mode
== SImode
);
10741 arc_pre_atomic_barrier (model
);
10743 label
= gen_label_rtx ();
10744 emit_label (label
);
10745 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10747 if (before
== NULL_RTX
)
10748 before
= gen_reg_rtx (mode
);
10750 if (after
== NULL_RTX
)
10751 after
= gen_reg_rtx (mode
);
10753 /* Load exclusive. */
10754 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10759 x
= gen_rtx_AND (mode
, before
, val
);
10760 emit_insn (gen_rtx_SET (after
, x
));
10761 x
= gen_rtx_NOT (mode
, after
);
10762 emit_insn (gen_rtx_SET (after
, x
));
10766 if (CONST_INT_P (val
))
10768 val
= GEN_INT (-INTVAL (val
));
10774 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10775 emit_insn (gen_rtx_SET (after
, x
));
10779 /* Exclusively store new item. Store clobbers CC reg. */
10780 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10782 /* Check the result of the store. */
10783 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10784 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10785 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10787 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10789 arc_post_atomic_barrier (model
);
10792 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10795 arc_no_speculation_in_delay_slots_p ()
10800 /* Return a parallel of registers to represent where to find the
10801 register pieces if required, otherwise NULL_RTX. */
10804 arc_dwarf_register_span (rtx rtl
)
10806 machine_mode mode
= GET_MODE (rtl
);
10810 if (GET_MODE_SIZE (mode
) != 8)
10813 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10814 regno
= REGNO (rtl
);
10815 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10816 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10821 /* Return true if OP is an acceptable memory operand for ARCompact
10822 16-bit load instructions of MODE.
10824 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10825 non scaled instructions.
10827 SCALED: TRUE if address can be scaled. */
10830 compact_memory_operand_p (rtx op
, machine_mode mode
,
10831 bool av2short
, bool scaled
)
10833 rtx addr
, plus0
, plus1
;
10836 /* Eliminate non-memory operations. */
10837 if (GET_CODE (op
) != MEM
)
10840 /* .di instructions have no 16-bit form. */
10841 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10844 /* likewise for uncached types. */
10845 if (arc_is_uncached_mem_p (op
))
10848 if (mode
== VOIDmode
)
10849 mode
= GET_MODE (op
);
10851 size
= GET_MODE_SIZE (mode
);
10853 /* dword operations really put out 2 instructions, so eliminate
10855 if (size
> UNITS_PER_WORD
)
10858 /* Decode the address now. */
10859 addr
= XEXP (op
, 0);
10860 switch (GET_CODE (addr
))
10863 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10864 || COMPACT_GP_REG_P (REGNO (addr
))
10865 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10867 plus0
= XEXP (addr
, 0);
10868 plus1
= XEXP (addr
, 1);
10870 if ((GET_CODE (plus0
) == REG
)
10871 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10872 || COMPACT_GP_REG_P (REGNO (plus0
)))
10873 && ((GET_CODE (plus1
) == REG
)
10874 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10875 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10880 if ((GET_CODE (plus0
) == REG
)
10881 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10882 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10883 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10884 && (GET_CODE (plus1
) == CONST_INT
))
10886 bool valid
= false;
10888 off
= INTVAL (plus1
);
10890 /* Negative offset is not supported in 16-bit load/store insns. */
10894 /* Only u5 immediates allowed in code density instructions. */
10902 /* This is an ldh_s.x instruction, check the u6
10904 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10908 /* Only u5 immediates allowed in 32bit access code
10909 density instructions. */
10910 if (REGNO (plus0
) <= 31)
10911 return ((off
< 32) && (off
% 4 == 0));
10918 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10929 /* The 6-bit constant get shifted to fit the real
10930 5-bits field. Check also for the alignment. */
10931 return ((off
< 64) && (off
% 2 == 0));
10933 return ((off
< 128) && (off
% 4 == 0));
10940 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10941 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10942 || SP_REG_P (REGNO (plus0
)))
10945 off
= INTVAL (plus1
);
10946 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10949 if ((GET_CODE (plus0
) == MULT
)
10950 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10951 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10952 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10953 && (GET_CODE (plus1
) == REG
)
10954 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10955 || COMPACT_GP_REG_P (REGNO (plus1
))))
10959 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10960 for 16-bit load instructions. */
10965 /* Return the frame pointer value to be backed up in the setjmp buffer. */
10968 arc_builtin_setjmp_frame_value (void)
10970 /* We always want to preserve whatever value is currently in the frame
10971 pointer register. For frames that are using the frame pointer the new
10972 value of the frame pointer register will have already been computed
10973 (as part of the prologue). For frames that are not using the frame
10974 pointer it is important that we backup whatever value is in the frame
10975 pointer register, as earlier (more outer) frames may have placed a
10976 value into the frame pointer register. It might be tempting to try
10977 and use `frame_pointer_rtx` here, however, this is not what we want.
10978 For frames that are using the frame pointer this will give the
10979 correct value. However, for frames that are not using the frame
10980 pointer this will still give the value that _would_ have been the
10981 frame pointer value for this frame (if the use of the frame pointer
10982 had not been removed). We really do want the raw frame pointer
10984 return gen_raw_REG (Pmode
, FRAME_POINTER_REGNUM
);
10987 /* Return nonzero if a jli call should be generated for a call from
10988 the current function to DECL. */
10991 arc_is_jli_call_p (rtx pat
)
10994 tree decl
= SYMBOL_REF_DECL (pat
);
10996 /* If it is not a well defined public function then return false. */
10997 if (!decl
|| !SYMBOL_REF_FUNCTION_P (pat
) || !TREE_PUBLIC (decl
))
11000 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
11001 if (lookup_attribute ("jli_always", attrs
))
11004 if (lookup_attribute ("jli_fixed", attrs
))
11007 return TARGET_JLI_ALWAYS
;
11010 /* Handle and "jli" attribute; arguments as in struct
11011 attribute_spec.handler. */
11014 arc_handle_jli_attribute (tree
*node ATTRIBUTE_UNUSED
,
11015 tree name
, tree args
, int,
11016 bool *no_add_attrs
)
11020 warning (OPT_Wattributes
,
11021 "%qE attribute only valid for ARCv2 architecture",
11023 *no_add_attrs
= true;
11026 if (args
== NULL_TREE
)
11028 warning (OPT_Wattributes
,
11029 "argument of %qE attribute is missing",
11031 *no_add_attrs
= true;
11035 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
11036 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
11037 tree arg
= TREE_VALUE (args
);
11038 if (TREE_CODE (arg
) != INTEGER_CST
)
11040 warning (0, "%qE attribute allows only an integer constant argument",
11042 *no_add_attrs
= true;
11044 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11049 /* Handle and "scure" attribute; arguments as in struct
11050 attribute_spec.handler. */
11053 arc_handle_secure_attribute (tree
*node ATTRIBUTE_UNUSED
,
11054 tree name
, tree args
, int,
11055 bool *no_add_attrs
)
11059 warning (OPT_Wattributes
,
11060 "%qE attribute only valid for ARC EM architecture",
11062 *no_add_attrs
= true;
11065 if (args
== NULL_TREE
)
11067 warning (OPT_Wattributes
,
11068 "argument of %qE attribute is missing",
11070 *no_add_attrs
= true;
11074 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
11075 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
11076 tree arg
= TREE_VALUE (args
);
11077 if (TREE_CODE (arg
) != INTEGER_CST
)
11079 warning (0, "%qE attribute allows only an integer constant argument",
11081 *no_add_attrs
= true;
11087 /* Return nonzero if the symbol is a secure function. */
11090 arc_is_secure_call_p (rtx pat
)
11093 tree decl
= SYMBOL_REF_DECL (pat
);
11098 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
11099 if (lookup_attribute ("secure_call", attrs
))
11105 /* Handle "uncached" qualifier. */
11108 arc_handle_uncached_attribute (tree
*node
,
11109 tree name
, tree args
,
11110 int flags ATTRIBUTE_UNUSED
,
11111 bool *no_add_attrs
)
11113 if (DECL_P (*node
) && TREE_CODE (*node
) != TYPE_DECL
)
11115 error ("%qE attribute only applies to types",
11117 *no_add_attrs
= true;
11121 warning (OPT_Wattributes
, "argument of %qE attribute ignored", name
);
11126 /* Return TRUE if PAT is a memory addressing an uncached data. */
11129 arc_is_uncached_mem_p (rtx pat
)
11131 tree attrs
= NULL_TREE
;
11137 /* Get the memory attributes. */
11138 addr
= MEM_EXPR (pat
);
11142 /* Get the attributes. */
11143 if (TREE_CODE (addr
) == MEM_REF
)
11145 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (addr
));
11146 if (lookup_attribute ("uncached", attrs
))
11149 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
11150 if (lookup_attribute ("uncached", attrs
))
11154 /* For COMPONENT_REF, use the FIELD_DECL from tree operand 1. */
11155 if (TREE_CODE (addr
) == COMPONENT_REF
)
11157 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 1)));
11158 if (lookup_attribute ("uncached", attrs
))
11164 /* Handle aux attribute. The auxiliary registers are addressed using
11165 special instructions lr and sr. The attribute 'aux' indicates if a
11166 variable refers to the aux-regs and what is the register number
11170 arc_handle_aux_attribute (tree
*node
,
11171 tree name
, tree args
, int,
11172 bool *no_add_attrs
)
11174 /* Isn't it better to use address spaces for the aux-regs? */
11175 if (DECL_P (*node
))
11177 if (TREE_CODE (*node
) != VAR_DECL
)
11179 error ("%qE attribute only applies to variables", name
);
11180 *no_add_attrs
= true;
11184 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
11185 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
11186 tree arg
= TREE_VALUE (args
);
11187 if (TREE_CODE (arg
) != INTEGER_CST
)
11189 warning (OPT_Wattributes
, "%qE attribute allows only an integer "
11190 "constant argument", name
);
11191 *no_add_attrs
= true;
11193 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11196 if (TREE_CODE (*node
) == VAR_DECL
)
11198 tree fntype
= TREE_TYPE (*node
);
11199 if (fntype
&& TREE_CODE (fntype
) == POINTER_TYPE
)
11201 tree attrs
= tree_cons (get_identifier ("aux"), NULL_TREE
,
11202 TYPE_ATTRIBUTES (fntype
));
11203 TYPE_ATTRIBUTES (fntype
) = attrs
;
11210 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
11211 anchors for small data: the GP register acts as an anchor in that
11212 case. We also don't want to use them for PC-relative accesses,
11213 where the PC acts as an anchor. Prohibit also TLS symbols to use
11217 arc_use_anchors_for_symbol_p (const_rtx symbol
)
11219 if (SYMBOL_REF_TLS_MODEL (symbol
))
11225 if (SYMBOL_REF_SMALL_P (symbol
))
11228 return default_use_anchors_for_symbol_p (symbol
);
11231 /* Return true if SUBST can't safely replace its equivalent during RA. */
11233 arc_cannot_substitute_mem_equiv_p (rtx
)
11235 /* If SUBST is mem[base+index], the address may not fit ISA,
11236 thus return true. */
11240 /* Checks whether the operands are valid for use in an LDD/STD
11241 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
11242 by the patterns. Assumes that the address in the base register RN
11243 is word aligned. Pattern guarantees that both memory accesses use
11244 the same base register, the offsets are constants within the range,
11245 and the gap between the offsets is 4. If reload complete then
11246 check that registers are legal. */
11249 operands_ok_ldd_std (rtx rt
, rtx rt2
, HOST_WIDE_INT offset
)
11251 unsigned int t
, t2
;
11253 if (!reload_completed
)
11256 if (!(SMALL_INT_RANGE (offset
, (GET_MODE_SIZE (DImode
) - 1) & (~0x03),
11257 (offset
& (GET_MODE_SIZE (DImode
) - 1) & 3
11258 ? 0 : -(-GET_MODE_SIZE (DImode
) | (~0x03)) >> 1))))
11264 if ((t2
== PCL_REG
)
11265 || (t
% 2 != 0) /* First destination register is not even. */
11272 /* Helper for gen_operands_ldd_std. Returns true iff the memory
11273 operand MEM's address contains an immediate offset from the base
11274 register and has no side effects, in which case it sets BASE and
11275 OFFSET accordingly. */
11278 mem_ok_for_ldd_std (rtx mem
, rtx
*base
, rtx
*offset
)
11282 gcc_assert (base
!= NULL
&& offset
!= NULL
);
11284 /* TODO: Handle more general memory operand patterns, such as
11285 PRE_DEC and PRE_INC. */
11287 if (side_effects_p (mem
))
11290 /* Can't deal with subregs. */
11291 if (GET_CODE (mem
) == SUBREG
)
11294 gcc_assert (MEM_P (mem
));
11296 *offset
= const0_rtx
;
11298 addr
= XEXP (mem
, 0);
11300 /* If addr isn't valid for DImode, then we can't handle it. */
11301 if (!arc_legitimate_address_p (DImode
, addr
,
11302 reload_in_progress
|| reload_completed
))
11310 else if (GET_CODE (addr
) == PLUS
|| GET_CODE (addr
) == MINUS
)
11312 *base
= XEXP (addr
, 0);
11313 *offset
= XEXP (addr
, 1);
11314 return (REG_P (*base
) && CONST_INT_P (*offset
));
11320 /* Called from peephole2 to replace two word-size accesses with a
11321 single LDD/STD instruction. Returns true iff we can generate a new
11322 instruction sequence. That is, both accesses use the same base
11323 register and the gap between constant offsets is 4. OPERANDS are
11324 the operands found by the peephole matcher; OPERANDS[0,1] are
11325 register operands, and OPERANDS[2,3] are the corresponding memory
11326 operands. LOAD indicates whether the access is load or store. */
11329 gen_operands_ldd_std (rtx
*operands
, bool load
, bool commute
)
11332 HOST_WIDE_INT offsets
[2], offset
;
11334 rtx cur_base
, cur_offset
, tmp
;
11335 rtx base
= NULL_RTX
;
11337 /* Check that the memory references are immediate offsets from the
11338 same base register. Extract the base register, the destination
11339 registers, and the corresponding memory offsets. */
11340 for (i
= 0; i
< nops
; i
++)
11342 if (!mem_ok_for_ldd_std (operands
[nops
+i
], &cur_base
, &cur_offset
))
11347 else if (REGNO (base
) != REGNO (cur_base
))
11350 offsets
[i
] = INTVAL (cur_offset
);
11351 if (GET_CODE (operands
[i
]) == SUBREG
)
11353 tmp
= SUBREG_REG (operands
[i
]);
11354 gcc_assert (GET_MODE (operands
[i
]) == GET_MODE (tmp
));
11359 /* Make sure there is no dependency between the individual loads. */
11360 if (load
&& REGNO (operands
[0]) == REGNO (base
))
11361 return false; /* RAW. */
11363 if (load
&& REGNO (operands
[0]) == REGNO (operands
[1]))
11364 return false; /* WAW. */
11366 /* Make sure the instructions are ordered with lower memory access first. */
11367 if (offsets
[0] > offsets
[1])
11369 gap
= offsets
[0] - offsets
[1];
11370 offset
= offsets
[1];
11372 /* Swap the instructions such that lower memory is accessed first. */
11373 std::swap (operands
[0], operands
[1]);
11374 std::swap (operands
[2], operands
[3]);
11378 gap
= offsets
[1] - offsets
[0];
11379 offset
= offsets
[0];
11382 /* Make sure accesses are to consecutive memory locations. */
11386 /* Make sure we generate legal instructions. */
11387 if (operands_ok_ldd_std (operands
[0], operands
[1], offset
))
11390 if (load
&& commute
)
11392 /* Try reordering registers. */
11393 std::swap (operands
[0], operands
[1]);
11394 if (operands_ok_ldd_std (operands
[0], operands
[1], offset
))
11401 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11402 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11404 #undef TARGET_CONSTANT_ALIGNMENT
11405 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11407 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11408 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11410 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11411 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11413 struct gcc_target targetm
= TARGET_INITIALIZER
;
11415 #include "gt-arc.h"