1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2018 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
31 #define IN_TARGET_CODE 1
35 #include "coretypes.h"
44 #include "stringpool.h"
50 #include "diagnostic.h"
51 #include "fold-const.h"
53 #include "stor-layout.h"
56 #include "insn-attr.h"
60 #include "langhooks.h"
61 #include "tm-constrs.h"
62 #include "reload.h" /* For operands_match_p */
64 #include "tree-pass.h"
70 #include "hw-doloop.h"
72 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
73 static char arc_cpu_name
[10] = "";
74 static const char *arc_cpu_string
= arc_cpu_name
;
76 typedef struct GTY (()) _arc_jli_section
79 struct _arc_jli_section
*next
;
82 static arc_jli_section
*arc_jli_sections
= NULL
;
84 /* Track which regs are set fixed/call saved/call used from commnad line. */
85 HARD_REG_SET overrideregs
;
87 /* Maximum size of a loop. */
88 #define ARC_MAX_LOOP_LENGTH 4095
90 /* ??? Loads can handle any constant, stores can only handle small ones. */
91 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
92 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
93 (GET_CODE (X) == CONST_INT \
94 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
97 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
99 #define LEGITIMATE_SMALL_DATA_OFFSET_P(X) \
100 (GET_CODE (X) == CONST \
101 && GET_CODE (XEXP ((X), 0)) == PLUS \
102 && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \
103 && SYMBOL_REF_SMALL_P (XEXP (XEXP ((X), 0), 0)) \
104 && GET_CODE (XEXP(XEXP ((X), 0), 1)) == CONST_INT \
105 && INTVAL (XEXP (XEXP ((X), 0), 1)) <= g_switch_value)
107 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
108 (GET_CODE (X) == PLUS \
109 && REG_P (XEXP ((X), 0)) \
110 && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM \
111 && ((GET_CODE (XEXP ((X), 1)) == SYMBOL_REF \
112 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
113 || LEGITIMATE_SMALL_DATA_OFFSET_P (XEXP ((X), 1))))
115 /* Array of valid operand punctuation characters. */
116 char arc_punct_chars
[256];
118 /* State used by arc_ccfsm_advance to implement conditional execution. */
119 struct GTY (()) arc_ccfsm
124 rtx_insn
*target_insn
;
128 /* Status of the IRQ_CTRL_AUX register. */
129 typedef struct irq_ctrl_saved_t
131 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
132 short irq_save_last_reg
;
133 /* True if BLINK is automatically saved. */
135 /* True if LPCOUNT is automatically saved. */
136 bool irq_save_lpcount
;
138 static irq_ctrl_saved_t irq_ctrl_saved
;
140 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
141 ((ARC_INTERRUPT_P (FNTYPE) \
142 && irq_ctrl_saved.irq_save_blink) \
143 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
144 && rgf_banked_register_count > 8))
146 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
147 ((ARC_INTERRUPT_P (FNTYPE) \
148 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
149 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
150 && rgf_banked_register_count > 8))
152 #define ARC_AUTO_IRQ_P(FNTYPE) \
153 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
154 && (irq_ctrl_saved.irq_save_blink \
155 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
157 /* Number of registers in second bank for FIRQ support. */
158 static int rgf_banked_register_count
;
160 #define arc_ccfsm_current cfun->machine->ccfsm_current
162 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
163 ((STATE)->state == 1 || (STATE)->state == 2)
165 /* Indicate we're conditionalizing insns now. */
166 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
167 ((STATE)->state += 2)
169 #define ARC_CCFSM_COND_EXEC_P(STATE) \
170 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
171 || current_insn_predicate)
173 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
174 #define CCFSM_ISCOMPACT(INSN,STATE) \
175 (ARC_CCFSM_COND_EXEC_P (STATE) \
176 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
177 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
178 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
180 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
181 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
182 ((ARC_CCFSM_COND_EXEC_P (STATE) \
184 && INSN_ANNULLED_BRANCH_P (JUMP) \
185 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
186 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
187 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
188 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
190 /* The maximum number of insns skipped which will be conditionalised if
192 /* When optimizing for speed:
193 Let p be the probability that the potentially skipped insns need to
194 be executed, pn the cost of a correctly predicted non-taken branch,
195 mt the cost of a mis/non-predicted taken branch,
196 mn mispredicted non-taken, pt correctly predicted taken ;
197 costs expressed in numbers of instructions like the ones considered
199 Unfortunately we don't have a measure of predictability - this
200 is linked to probability only in that in the no-eviction-scenario
201 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
202 value that can be assumed *if* the distribution is perfectly random.
203 A predictability of 1 is perfectly plausible not matter what p is,
204 because the decision could be dependent on an invocation parameter
206 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
207 For small p, we want MAX_INSNS_SKIPPED == pt
209 When optimizing for size:
210 We want to skip insn unless we could use 16 opcodes for the
211 non-conditionalized insn to balance the branch length or more.
212 Performance can be tie-breaker. */
213 /* If the potentially-skipped insns are likely to be executed, we'll
214 generally save one non-taken branch
216 this to be no less than the 1/p */
217 #define MAX_INSNS_SKIPPED 3
219 /* A nop is needed between a 4 byte insn that sets the condition codes and
220 a branch that uses them (the same isn't true for an 8 byte insn that sets
221 the condition codes). Set by arc_ccfsm_advance. Used by
222 arc_print_operand. */
224 static int get_arc_condition_code (rtx
);
226 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
227 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
228 static tree
arc_handle_jli_attribute (tree
*, tree
, tree
, int, bool *);
229 static tree
arc_handle_secure_attribute (tree
*, tree
, tree
, int, bool *);
230 static tree
arc_handle_uncached_attribute (tree
*, tree
, tree
, int, bool *);
231 static tree
arc_handle_aux_attribute (tree
*, tree
, tree
, int, bool *);
233 /* Initialized arc_attribute_table to NULL since arc doesnot have any
234 machine specific supported attributes. */
235 const struct attribute_spec arc_attribute_table
[] =
237 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
238 affects_type_identity, handler, exclude } */
239 { "interrupt", 1, 1, true, false, false, true,
240 arc_handle_interrupt_attribute
, NULL
},
241 /* Function calls made to this symbol must be done indirectly, because
242 it may lie outside of the 21/25 bit addressing range of a normal function
244 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
245 /* Whereas these functions are always known to reside within the 25 bit
246 addressing range of unconditionalized bl. */
247 { "medium_call", 0, 0, false, true, true, false, NULL
, NULL
},
248 /* And these functions are always known to reside within the 21 bit
249 addressing range of blcc. */
250 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
251 /* Function which are not having the prologue and epilogue generated
253 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute
,
255 /* Functions calls made using jli instruction. The pointer in JLI
256 table is found latter. */
257 { "jli_always", 0, 0, false, true, true, false, NULL
, NULL
},
258 /* Functions calls made using jli instruction. The pointer in JLI
259 table is given as input parameter. */
260 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute
,
262 /* Call a function using secure-mode. */
263 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute
,
265 /* Bypass caches using .di flag. */
266 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute
,
268 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute
, NULL
},
269 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
271 static int arc_comp_type_attributes (const_tree
, const_tree
);
272 static void arc_file_start (void);
273 static void arc_internal_label (FILE *, const char *, unsigned long);
274 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
276 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
277 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
279 static void arc_init_builtins (void);
280 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
282 static int branch_dest (rtx
);
284 static void arc_output_pic_addr_const (FILE *, rtx
, int);
285 static bool arc_function_ok_for_sibcall (tree
, tree
);
286 static rtx
arc_function_value (const_tree
, const_tree
, bool);
287 const char * output_shift (rtx
*);
288 static void arc_reorg (void);
289 static bool arc_in_small_data_p (const_tree
);
291 static void arc_init_reg_tables (void);
292 static bool arc_return_in_memory (const_tree
, const_tree
);
293 static bool arc_vector_mode_supported_p (machine_mode
);
295 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
297 static const char *arc_invalid_within_doloop (const rtx_insn
*);
299 static void output_short_suffix (FILE *file
);
301 static bool arc_frame_pointer_required (void);
303 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
305 enum by_pieces_operation op
,
308 /* Globally visible information about currently selected cpu. */
309 const arc_cpu_t
*arc_selected_cpu
;
312 legitimate_scaled_address_p (machine_mode mode
, rtx op
, bool strict
)
314 if (GET_CODE (op
) != PLUS
)
317 if (GET_CODE (XEXP (op
, 0)) != MULT
)
320 /* Check multiplication operands. */
321 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op
, 0), 0), strict
))
324 if (!CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
327 switch (GET_MODE_SIZE (mode
))
330 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 2)
338 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 4)
345 /* Check the base. */
346 if (RTX_OK_FOR_BASE_P (XEXP (op
, 1), (strict
)))
351 if (CONST_INT_P (XEXP (op
, 1)))
355 if (CONSTANT_P (XEXP (op
, 1)))
357 /* Scalled addresses for sdata is done other places. */
358 if (GET_CODE (XEXP (op
, 1)) == SYMBOL_REF
359 && SYMBOL_REF_SMALL_P (XEXP (op
, 1)))
367 /* Check for constructions like REG + OFFS, where OFFS can be a
368 register, an immediate or an long immediate. */
371 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
373 if (GET_CODE (x
) != PLUS
)
376 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
379 /* Check for: [Rx + small offset] or [Rx + Ry]. */
380 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
381 && GET_MODE_SIZE ((mode
)) <= 4)
382 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
385 /* Check for [Rx + symbol]. */
387 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
388 /* Avoid this type of address for double or larger modes. */
389 && (GET_MODE_SIZE (mode
) <= 4)
390 /* Avoid small data which ends in something like GP +
392 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))))
398 /* Implements target hook vector_mode_supported_p. */
401 arc_vector_mode_supported_p (machine_mode mode
)
406 return TARGET_PLUS_DMPY
;
409 return TARGET_PLUS_QMACW
;
412 return TARGET_SIMD_SET
;
419 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
422 arc_preferred_simd_mode (scalar_mode mode
)
427 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
436 /* Implements target hook
437 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
440 arc_autovectorize_vector_sizes (vector_sizes
*sizes
)
442 if (TARGET_PLUS_QMACW
)
444 sizes
->quick_push (8);
445 sizes
->quick_push (4);
449 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
450 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
451 static rtx
arc_delegitimize_address (rtx
);
452 static bool arc_can_follow_jump (const rtx_insn
*follower
,
453 const rtx_insn
*followee
);
455 static rtx
frame_insn (rtx
);
456 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
458 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
460 /* initialize the GCC target structure. */
461 #undef TARGET_COMP_TYPE_ATTRIBUTES
462 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
463 #undef TARGET_ASM_FILE_START
464 #define TARGET_ASM_FILE_START arc_file_start
465 #undef TARGET_ATTRIBUTE_TABLE
466 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
467 #undef TARGET_ASM_INTERNAL_LABEL
468 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
469 #undef TARGET_RTX_COSTS
470 #define TARGET_RTX_COSTS arc_rtx_costs
471 #undef TARGET_ADDRESS_COST
472 #define TARGET_ADDRESS_COST arc_address_cost
474 #undef TARGET_ENCODE_SECTION_INFO
475 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
477 #undef TARGET_CANNOT_FORCE_CONST_MEM
478 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
480 #undef TARGET_INIT_BUILTINS
481 #define TARGET_INIT_BUILTINS arc_init_builtins
483 #undef TARGET_EXPAND_BUILTIN
484 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
486 #undef TARGET_BUILTIN_DECL
487 #define TARGET_BUILTIN_DECL arc_builtin_decl
489 #undef TARGET_ASM_OUTPUT_MI_THUNK
490 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
492 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
493 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
495 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
496 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
498 #undef TARGET_MACHINE_DEPENDENT_REORG
499 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
501 #undef TARGET_IN_SMALL_DATA_P
502 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
504 #undef TARGET_PROMOTE_FUNCTION_MODE
505 #define TARGET_PROMOTE_FUNCTION_MODE \
506 default_promote_function_mode_always_promote
508 #undef TARGET_PROMOTE_PROTOTYPES
509 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
511 #undef TARGET_RETURN_IN_MEMORY
512 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
513 #undef TARGET_PASS_BY_REFERENCE
514 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
516 #undef TARGET_SETUP_INCOMING_VARARGS
517 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
519 #undef TARGET_ARG_PARTIAL_BYTES
520 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
522 #undef TARGET_MUST_PASS_IN_STACK
523 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
525 #undef TARGET_FUNCTION_VALUE
526 #define TARGET_FUNCTION_VALUE arc_function_value
528 #undef TARGET_SCHED_ADJUST_PRIORITY
529 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
531 #undef TARGET_VECTOR_MODE_SUPPORTED_P
532 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
534 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
535 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
537 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
538 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
540 #undef TARGET_CAN_USE_DOLOOP_P
541 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
543 #undef TARGET_INVALID_WITHIN_DOLOOP
544 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
546 #undef TARGET_PRESERVE_RELOAD_P
547 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
549 #undef TARGET_CAN_FOLLOW_JUMP
550 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
552 #undef TARGET_DELEGITIMIZE_ADDRESS
553 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
555 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
556 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
557 arc_use_by_pieces_infrastructure_p
559 /* Usually, we will be able to scale anchor offsets.
560 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
561 #undef TARGET_MIN_ANCHOR_OFFSET
562 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
563 #undef TARGET_MAX_ANCHOR_OFFSET
564 #define TARGET_MAX_ANCHOR_OFFSET (1020)
566 #undef TARGET_SECONDARY_RELOAD
567 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
569 #define TARGET_OPTION_OVERRIDE arc_override_options
571 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
573 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
575 #define TARGET_CAN_ELIMINATE arc_can_eliminate
577 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
579 #define TARGET_FUNCTION_ARG arc_function_arg
581 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
583 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
585 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
587 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
589 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
591 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
592 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
593 arc_no_speculation_in_delay_slots_p
596 #define TARGET_LRA_P arc_lra_p
597 #define TARGET_REGISTER_PRIORITY arc_register_priority
598 /* Stores with scaled offsets have different displacement ranges. */
599 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
600 #define TARGET_SPILL_CLASS arc_spill_class
602 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
603 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
605 #undef TARGET_WARN_FUNC_RETURN
606 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
608 #include "target-def.h"
610 #undef TARGET_ASM_ALIGNED_HI_OP
611 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
612 #undef TARGET_ASM_ALIGNED_SI_OP
613 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
616 #undef TARGET_HAVE_TLS
617 #define TARGET_HAVE_TLS HAVE_AS_TLS
620 #undef TARGET_DWARF_REGISTER_SPAN
621 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
623 #undef TARGET_HARD_REGNO_NREGS
624 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
625 #undef TARGET_HARD_REGNO_MODE_OK
626 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
628 #undef TARGET_MODES_TIEABLE_P
629 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
630 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
631 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value
633 /* Try to keep the (mov:DF _, reg) as early as possible so
634 that the d<add/sub/mul>h-lr insns appear together and can
635 use the peephole2 pattern. */
638 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
640 rtx set
= single_set (insn
);
642 && GET_MODE (SET_SRC(set
)) == DFmode
643 && GET_CODE (SET_SRC(set
)) == REG
)
645 /* Incrementing priority by 20 (empirically derived). */
646 return priority
+ 20;
652 /* For ARC base register + offset addressing, the validity of the
653 address is mode-dependent for most of the offset range, as the
654 offset can be scaled by the access size.
655 We don't expose these as mode-dependent addresses in the
656 mode_dependent_address_p target hook, because that would disable
657 lots of optimizations, and most uses of these addresses are for 32
658 or 64 bit accesses anyways, which are fine.
659 However, that leaves some addresses for 8 / 16 bit values not
660 properly reloaded by the generic code, which is why we have to
661 schedule secondary reloads for these. */
664 arc_secondary_reload (bool in_p
,
668 secondary_reload_info
*sri
)
670 enum rtx_code code
= GET_CODE (x
);
672 if (cl
== DOUBLE_REGS
)
675 /* The loop counter register can be stored, but not loaded directly. */
676 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
677 && in_p
&& MEM_P (x
))
680 /* If we have a subreg (reg), where reg is a pseudo (that will end in
681 a memory location), then we may need a scratch register to handle
682 the fp/sp+largeoffset address. */
690 int regno
= REGNO (x
);
691 if (regno
>= FIRST_PSEUDO_REGISTER
)
692 regno
= reg_renumber
[regno
];
697 /* It is a pseudo that ends in a stack location. */
698 if (reg_equiv_mem (REGNO (x
)))
700 /* Get the equivalent address and check the range of the
702 rtx mem
= reg_equiv_mem (REGNO (x
));
703 addr
= find_replacement (&XEXP (mem
, 0));
708 gcc_assert (MEM_P (x
));
710 addr
= simplify_rtx (addr
);
712 if (addr
&& GET_CODE (addr
) == PLUS
713 && CONST_INT_P (XEXP (addr
, 1))
714 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
720 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
724 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
734 /* Convert reloads using offsets that are too large to use indirect
738 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
742 gcc_assert (GET_CODE (mem
) == MEM
);
743 addr
= XEXP (mem
, 0);
745 /* Large offset: use a move. FIXME: ld ops accepts limms as
746 offsets. Hence, the following move insn is not required. */
747 emit_move_insn (scratch
, addr
);
748 mem
= replace_equiv_address_nv (mem
, scratch
);
750 /* Now create the move. */
752 emit_insn (gen_rtx_SET (mem
, reg
));
754 emit_insn (gen_rtx_SET (reg
, mem
));
759 static unsigned arc_ifcvt (void);
763 const pass_data pass_data_arc_ifcvt
=
766 "arc_ifcvt", /* name */
767 OPTGROUP_NONE
, /* optinfo_flags */
768 TV_IFCVT2
, /* tv_id */
769 0, /* properties_required */
770 0, /* properties_provided */
771 0, /* properties_destroyed */
772 0, /* todo_flags_start */
773 TODO_df_finish
/* todo_flags_finish */
776 class pass_arc_ifcvt
: public rtl_opt_pass
779 pass_arc_ifcvt(gcc::context
*ctxt
)
780 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
783 /* opt_pass methods: */
784 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
785 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
791 make_pass_arc_ifcvt (gcc::context
*ctxt
)
793 return new pass_arc_ifcvt (ctxt
);
796 static unsigned arc_predicate_delay_insns (void);
800 const pass_data pass_data_arc_predicate_delay_insns
=
803 "arc_predicate_delay_insns", /* name */
804 OPTGROUP_NONE
, /* optinfo_flags */
805 TV_IFCVT2
, /* tv_id */
806 0, /* properties_required */
807 0, /* properties_provided */
808 0, /* properties_destroyed */
809 0, /* todo_flags_start */
810 TODO_df_finish
/* todo_flags_finish */
813 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
816 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
817 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
820 /* opt_pass methods: */
821 virtual unsigned int execute (function
*)
823 return arc_predicate_delay_insns ();
830 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
832 return new pass_arc_predicate_delay_insns (ctxt
);
835 /* Called by OVERRIDE_OPTIONS to initialize various things. */
842 /* I have the multiplier, then use it*/
843 if (TARGET_MPYW
|| TARGET_MULTI
)
844 arc_multcost
= COSTS_N_INSNS (1);
846 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
847 if (arc_multcost
< 0)
850 case ARC_TUNE_ARC700_4_2_STD
:
852 max throughput (1 multiply + 4 other insns) / 5 cycles. */
853 arc_multcost
= COSTS_N_INSNS (4);
854 if (TARGET_NOMPY_SET
)
855 arc_multcost
= COSTS_N_INSNS (30);
857 case ARC_TUNE_ARC700_4_2_XMAC
:
859 max throughput (1 multiply + 2 other insns) / 3 cycles. */
860 arc_multcost
= COSTS_N_INSNS (3);
861 if (TARGET_NOMPY_SET
)
862 arc_multcost
= COSTS_N_INSNS (30);
864 case ARC_TUNE_ARC600
:
865 if (TARGET_MUL64_SET
)
867 arc_multcost
= COSTS_N_INSNS (4);
872 arc_multcost
= COSTS_N_INSNS (30);
876 /* MPY instructions valid only for ARC700 or ARCv2. */
877 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
878 error ("-mno-mpy supported only for ARC700 or ARCv2");
880 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
881 error ("-mno-dpfp-lrsr supported only with -mdpfp");
883 /* FPX-1. No fast and compact together. */
884 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
885 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
886 error ("FPX fast and compact options cannot be specified together");
888 /* FPX-2. No fast-spfp for arc600 or arc601. */
889 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
890 error ("-mspfp_fast not available on ARC600 or ARC601");
892 /* FPX-4. No FPX extensions mixed with FPU extensions. */
893 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
894 && TARGET_HARD_FLOAT
)
895 error ("No FPX/FPU mixing allowed");
897 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
898 if (flag_pic
&& TARGET_ARC600_FAMILY
)
901 "PIC is not supported for %s. Generating non-PIC code only..",
906 arc_init_reg_tables ();
908 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
909 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
910 arc_punct_chars
['#'] = 1;
911 arc_punct_chars
['*'] = 1;
912 arc_punct_chars
['?'] = 1;
913 arc_punct_chars
['!'] = 1;
914 arc_punct_chars
['^'] = 1;
915 arc_punct_chars
['&'] = 1;
916 arc_punct_chars
['+'] = 1;
917 arc_punct_chars
['_'] = 1;
919 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
921 /* There are two target-independent ifcvt passes, and arc_reorg may do
922 one or more arc_ifcvt calls. */
923 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
924 struct register_pass_info arc_ifcvt4_info
925 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
926 struct register_pass_info arc_ifcvt5_info
927 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
929 register_pass (&arc_ifcvt4_info
);
930 register_pass (&arc_ifcvt5_info
);
933 if (flag_delayed_branch
)
935 opt_pass
*pass_arc_predicate_delay_insns
936 = make_pass_arc_predicate_delay_insns (g
);
937 struct register_pass_info arc_predicate_delay_info
938 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
940 register_pass (&arc_predicate_delay_info
);
944 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
945 register range is specified as two registers separated by a dash.
946 It always starts with r0, and its upper limit is fp register.
947 blink and lp_count registers are optional. */
950 irq_range (const char *cstr
)
952 int i
, first
, last
, blink
, lpcount
, xreg
;
953 char *str
, *dash
, *comma
;
956 str
= (char *) alloca (i
+ 1);
957 memcpy (str
, cstr
, i
+ 1);
961 dash
= strchr (str
, '-');
964 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
969 comma
= strchr (dash
+ 1, ',');
973 first
= decode_reg_name (str
);
976 warning (0, "first register must be R0");
980 /* At this moment we do not have the register names initialized
982 if (!strcmp (dash
+ 1, "ilink"))
985 last
= decode_reg_name (dash
+ 1);
989 warning (0, "unknown register name: %s", dash
+ 1);
995 warning (0, "last register name %s must be an odd register", dash
+ 1);
1003 warning (0, "%s-%s is an empty range", str
, dash
+ 1);
1012 comma
= strchr (str
, ',');
1016 xreg
= decode_reg_name (str
);
1028 warning (0, "unknown register name: %s", str
);
1033 irq_ctrl_saved
.irq_save_last_reg
= last
;
1034 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
1035 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
1038 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1042 parse_mrgf_banked_regs_option (const char *arg
)
1048 val
= strtol (arg
, &end_ptr
, 10);
1049 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
1050 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
1052 error ("invalid number in -mrgf-banked-regs=%s "
1053 "valid values are 0, 4, 8, 16, or 32", arg
);
1056 rgf_banked_register_count
= (int) val
;
1059 /* Check ARC options, generate derived target attributes. */
1062 arc_override_options (void)
1065 cl_deferred_option
*opt
;
1066 vec
<cl_deferred_option
> *vopt
1067 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
1069 if (arc_cpu
== PROCESSOR_NONE
)
1070 arc_cpu
= TARGET_CPU_DEFAULT
;
1072 /* Set the default cpu options. */
1073 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
1075 /* Set the architectures. */
1076 switch (arc_selected_cpu
->arch_info
->arch_id
)
1079 arc_cpu_string
= "EM";
1082 arc_cpu_string
= "HS";
1085 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
1086 arc_cpu_string
= "NPS400";
1088 arc_cpu_string
= "ARC700";
1091 arc_cpu_string
= "ARC600";
1097 irq_ctrl_saved
.irq_save_last_reg
= -1;
1098 irq_ctrl_saved
.irq_save_blink
= false;
1099 irq_ctrl_saved
.irq_save_lpcount
= false;
1101 rgf_banked_register_count
= 0;
1103 /* Handle the deferred options. */
1105 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1107 switch (opt
->opt_index
)
1109 case OPT_mirq_ctrl_saved_
:
1111 irq_range (opt
->arg
);
1113 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1116 case OPT_mrgf_banked_regs_
:
1118 parse_mrgf_banked_regs_option (opt
->arg
);
1120 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1128 CLEAR_HARD_REG_SET (overrideregs
);
1129 if (common_deferred_options
)
1131 vec
<cl_deferred_option
> v
=
1132 *((vec
<cl_deferred_option
> *) common_deferred_options
);
1135 FOR_EACH_VEC_ELT (v
, i
, opt
)
1137 switch (opt
->opt_index
)
1140 case OPT_fcall_used_
:
1141 case OPT_fcall_saved_
:
1142 if ((reg
= decode_reg_name_and_count (opt
->arg
, &nregs
)) >= 0)
1143 for (j
= reg
; j
< reg
+ nregs
; j
++)
1144 SET_HARD_REG_BIT (overrideregs
, j
);
1152 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1153 specific flags are set in arc-common.c. The architecture forces
1154 the default hardware configurations in, regardless what command
1155 line options are saying. The CPU optional hw options can be
1156 turned on or off. */
1157 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1159 if ((arc_selected_cpu->flags & CODE) \
1160 && ((target_flags_explicit & MASK) == 0)) \
1161 target_flags |= MASK; \
1162 if (arc_selected_cpu->arch_info->dflags & CODE) \
1163 target_flags |= MASK; \
1165 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1167 if ((arc_selected_cpu->flags & CODE) \
1168 && (VAR == DEFAULT_##VAR)) \
1170 if (arc_selected_cpu->arch_info->dflags & CODE) \
1174 #include "arc-options.def"
1179 /* Check options against architecture options. Throw an error if
1180 option is not allowed. */
1181 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1184 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1186 error ("%s is not available for %s architecture", \
1187 DOC, arc_selected_cpu->arch_info->name); \
1190 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1192 if ((target_flags & MASK) \
1193 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1194 error ("%s is not available for %s architecture", \
1195 DOC, arc_selected_cpu->arch_info->name); \
1198 #include "arc-options.def"
1203 /* Set Tune option. */
1204 if (arc_tune
== ARC_TUNE_NONE
)
1205 arc_tune
= (enum arc_tune_attr
) arc_selected_cpu
->tune
;
1207 if (arc_size_opt_level
== 3)
1210 /* Compact casesi is not a valid option for ARCv2 family. */
1213 if (TARGET_COMPACT_CASESI
)
1215 warning (0, "compact-casesi is not applicable to ARCv2");
1216 TARGET_COMPACT_CASESI
= 0;
1219 else if (optimize_size
== 1
1220 && !global_options_set
.x_TARGET_COMPACT_CASESI
)
1221 TARGET_COMPACT_CASESI
= 1;
1224 target_flags
|= MASK_NO_SDATA_SET
;
1226 if (flag_no_common
== 255)
1227 flag_no_common
= !TARGET_NO_SDATA_SET
;
1229 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1230 if (TARGET_MIXED_CODE
)
1232 if (!TARGET_Q_CLASS
)
1233 TARGET_COMPACT_CASESI
= 0;
1234 if (TARGET_COMPACT_CASESI
)
1235 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
1237 /* Check for small data option */
1238 if (!global_options_set
.x_g_switch_value
&& !TARGET_NO_SDATA_SET
)
1239 g_switch_value
= TARGET_LL64
? 8 : 4;
1241 /* These need to be done at start up. It's convenient to do them here. */
1245 /* The condition codes of the ARC, and the inverse function. */
1246 /* For short branches, the "c" / "nc" names are not defined in the ARC
1247 Programmers manual, so we have to use "lo" / "hs"" instead. */
1248 static const char *arc_condition_codes
[] =
1250 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1251 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1254 enum arc_cc_code_index
1256 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1257 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1258 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1259 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1262 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1264 /* Returns the index of the ARC condition code string in
1265 `arc_condition_codes'. COMPARISON should be an rtx like
1266 `(eq (...) (...))'. */
1269 get_arc_condition_code (rtx comparison
)
1271 switch (GET_MODE (XEXP (comparison
, 0)))
1274 case E_SImode
: /* For BRcc. */
1275 switch (GET_CODE (comparison
))
1277 case EQ
: return ARC_CC_EQ
;
1278 case NE
: return ARC_CC_NE
;
1279 case GT
: return ARC_CC_GT
;
1280 case LE
: return ARC_CC_LE
;
1281 case GE
: return ARC_CC_GE
;
1282 case LT
: return ARC_CC_LT
;
1283 case GTU
: return ARC_CC_HI
;
1284 case LEU
: return ARC_CC_LS
;
1285 case LTU
: return ARC_CC_LO
;
1286 case GEU
: return ARC_CC_HS
;
1287 default : gcc_unreachable ();
1290 switch (GET_CODE (comparison
))
1292 case EQ
: return ARC_CC_EQ
;
1293 case NE
: return ARC_CC_NE
;
1294 case GE
: return ARC_CC_P
;
1295 case LT
: return ARC_CC_N
;
1296 case GT
: return ARC_CC_PNZ
;
1297 default : gcc_unreachable ();
1300 switch (GET_CODE (comparison
))
1302 case EQ
: return ARC_CC_EQ
;
1303 case NE
: return ARC_CC_NE
;
1304 default : gcc_unreachable ();
1307 switch (GET_CODE (comparison
))
1309 case LTU
: return ARC_CC_C
;
1310 case GEU
: return ARC_CC_NC
;
1311 default : gcc_unreachable ();
1313 case E_CC_FP_GTmode
:
1314 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1315 switch (GET_CODE (comparison
))
1317 case GT
: return ARC_CC_N
;
1318 case UNLE
: return ARC_CC_P
;
1319 default : gcc_unreachable ();
1322 switch (GET_CODE (comparison
))
1324 case GT
: return ARC_CC_HI
;
1325 case UNLE
: return ARC_CC_LS
;
1326 default : gcc_unreachable ();
1328 case E_CC_FP_GEmode
:
1329 /* Same for FPX and non-FPX. */
1330 switch (GET_CODE (comparison
))
1332 case GE
: return ARC_CC_HS
;
1333 case UNLT
: return ARC_CC_LO
;
1334 default : gcc_unreachable ();
1336 case E_CC_FP_UNEQmode
:
1337 switch (GET_CODE (comparison
))
1339 case UNEQ
: return ARC_CC_EQ
;
1340 case LTGT
: return ARC_CC_NE
;
1341 default : gcc_unreachable ();
1343 case E_CC_FP_ORDmode
:
1344 switch (GET_CODE (comparison
))
1346 case UNORDERED
: return ARC_CC_C
;
1347 case ORDERED
: return ARC_CC_NC
;
1348 default : gcc_unreachable ();
1351 switch (GET_CODE (comparison
))
1353 case EQ
: return ARC_CC_EQ
;
1354 case NE
: return ARC_CC_NE
;
1355 case UNORDERED
: return ARC_CC_C
;
1356 case ORDERED
: return ARC_CC_NC
;
1357 case LTGT
: return ARC_CC_HI
;
1358 case UNEQ
: return ARC_CC_LS
;
1359 default : gcc_unreachable ();
1362 switch (GET_CODE (comparison
))
1364 case EQ
: return ARC_CC_EQ
;
1365 case NE
: return ARC_CC_NE
;
1366 case GT
: return ARC_CC_GT
;
1367 case GE
: return ARC_CC_GE
;
1368 case LT
: return ARC_CC_C
;
1369 case LE
: return ARC_CC_LS
;
1370 case UNORDERED
: return ARC_CC_V
;
1371 case ORDERED
: return ARC_CC_NV
;
1372 case UNGT
: return ARC_CC_HI
;
1373 case UNGE
: return ARC_CC_HS
;
1374 case UNLT
: return ARC_CC_LT
;
1375 case UNLE
: return ARC_CC_LE
;
1376 /* UNEQ and LTGT do not have representation. */
1377 case LTGT
: /* Fall through. */
1378 case UNEQ
: /* Fall through. */
1379 default : gcc_unreachable ();
1381 case E_CC_FPU_UNEQmode
:
1382 switch (GET_CODE (comparison
))
1384 case LTGT
: return ARC_CC_NE
;
1385 case UNEQ
: return ARC_CC_EQ
;
1386 default : gcc_unreachable ();
1388 default : gcc_unreachable ();
1394 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1397 arc_short_comparison_p (rtx comparison
, int offset
)
1399 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1400 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1401 switch (get_arc_condition_code (comparison
))
1403 case ARC_CC_EQ
: case ARC_CC_NE
:
1404 return offset
>= -512 && offset
<= 506;
1405 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1406 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1407 return offset
>= -64 && offset
<= 58;
1413 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1414 return the mode to be used for the comparison. */
1417 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1419 machine_mode mode
= GET_MODE (x
);
1422 /* For an operation that sets the condition codes as a side-effect, the
1423 C and V flags is not set as for cmp, so we can only use comparisons where
1424 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1426 /* ??? We could use "pnz" for greater than zero, however, we could then
1427 get into trouble because the comparison could not be reversed. */
1428 if (GET_MODE_CLASS (mode
) == MODE_INT
1430 && (op
== EQ
|| op
== NE
1431 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1434 /* add.f for if (a+b) */
1436 && GET_CODE (y
) == NEG
1437 && (op
== EQ
|| op
== NE
))
1440 /* Check if this is a test suitable for bxor.f . */
1441 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1442 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1446 /* Check if this is a test suitable for add / bmsk.f . */
1447 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1448 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1449 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1450 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1451 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1454 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1455 && GET_CODE (x
) == PLUS
1456 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1459 if (TARGET_ARGONAUT_SET
1460 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1463 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1465 case LT
: case UNGE
: case GT
: case UNLE
:
1466 return CC_FP_GTmode
;
1467 case LE
: case UNGT
: case GE
: case UNLT
:
1468 return CC_FP_GEmode
;
1469 default: gcc_unreachable ();
1471 else if (TARGET_HARD_FLOAT
1472 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1473 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1492 return CC_FPU_UNEQmode
;
1497 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1501 case EQ
: case NE
: return CC_Zmode
;
1503 case GT
: case UNLE
: return CC_FP_GTmode
;
1505 case GE
: case UNLT
: return CC_FP_GEmode
;
1506 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1507 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1508 default: gcc_unreachable ();
1514 /* Vectors to keep interesting information about registers where it can easily
1515 be got. We use to use the actual mode value as the bit number, but there
1516 is (or may be) more than 32 modes now. Instead we use two tables: one
1517 indexed by hard register number, and one indexed by mode. */
1519 /* The purpose of arc_mode_class is to shrink the range of modes so that
1520 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1521 mapped into one arc_mode_class mode. */
1523 enum arc_mode_class
{
1525 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1526 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1530 /* Modes for condition codes. */
1531 #define C_MODES (1 << (int) C_MODE)
1533 /* Modes for single-word and smaller quantities. */
1534 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1536 /* Modes for double-word and smaller quantities. */
1537 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1539 /* Mode for 8-byte DF values only. */
1540 #define DF_MODES (1 << DF_MODE)
1542 /* Modes for quad-word and smaller quantities. */
1543 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1545 /* Modes for 128-bit vectors. */
1546 #define V_MODES (1 << (int) V_MODE)
1548 /* Value is 1 if register/mode pair is acceptable on arc. */
1550 static unsigned int arc_hard_regno_modes
[] = {
1551 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1552 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1553 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1554 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1556 /* ??? Leave these as S_MODES for now. */
1557 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1558 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1559 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1560 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1562 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1563 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1564 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1565 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1567 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1568 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1569 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1570 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1572 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1573 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1576 static unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1578 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1581 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1583 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1584 return GENERAL_REGS
;
1588 /* Initialize the arc_mode_class array. */
1591 arc_init_reg_tables (void)
1595 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1597 machine_mode m
= (machine_mode
) i
;
1599 switch (GET_MODE_CLASS (m
))
1602 case MODE_PARTIAL_INT
:
1603 case MODE_COMPLEX_INT
:
1604 if (GET_MODE_SIZE (m
) <= 4)
1605 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1606 else if (GET_MODE_SIZE (m
) == 8)
1607 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1608 else if (GET_MODE_SIZE (m
) == 16)
1609 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1610 else if (GET_MODE_SIZE (m
) == 32)
1611 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1613 arc_mode_class
[i
] = 0;
1616 case MODE_COMPLEX_FLOAT
:
1617 if (GET_MODE_SIZE (m
) <= 4)
1618 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1619 else if (GET_MODE_SIZE (m
) == 8)
1620 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1621 else if (GET_MODE_SIZE (m
) == 16)
1622 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1623 else if (GET_MODE_SIZE (m
) == 32)
1624 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1626 arc_mode_class
[i
] = 0;
1628 case MODE_VECTOR_INT
:
1629 if (GET_MODE_SIZE (m
) == 4)
1630 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1631 else if (GET_MODE_SIZE (m
) == 8)
1632 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1634 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1638 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1639 we must explicitly check for them here. */
1640 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1641 || i
== (int) CC_Cmode
1642 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1643 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1644 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1646 arc_mode_class
[i
] = 0;
1652 /* Core registers 56..59 are used for multiply extension options.
1653 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1654 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1655 number depends on endianness.
1656 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1657 Because mlo / mhi form a 64 bit value, we use different gcc internal
1658 register numbers to make them form a register pair as the gcc internals
1659 know it. mmid gets number 57, if still available, and mlo / mhi get
1660 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1661 to map this back. */
1662 char rname56
[5] = "r56";
1663 char rname57
[5] = "r57";
1664 char rname58
[5] = "r58";
1665 char rname59
[5] = "r59";
1666 char rname29
[7] = "ilink1";
1667 char rname30
[7] = "ilink2";
1670 arc_conditional_register_usage (void)
1674 int fix_start
= 60, fix_end
= 55;
1678 /* For ARCv2 the core register set is changed. */
1679 strcpy (rname29
, "ilink");
1680 strcpy (rname30
, "r30");
1682 if (!TEST_HARD_REG_BIT (overrideregs
, 30))
1684 /* No user interference. Set the r30 to be used by the
1686 call_used_regs
[30] = 1;
1689 arc_regno_reg_class
[30] = WRITABLE_CORE_REGS
;
1690 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], 30);
1691 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], 30);
1692 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], 30);
1693 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], 30);
1697 if (TARGET_MUL64_SET
)
1702 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1703 you are supposed to refer to it as mlo & mhi, e.g
1704 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1705 In an actual asm instruction, you are of course use mmed.
1706 The point of avoiding having a separate register for mmed is that
1707 this way, we don't have to carry clobbers of that reg around in every
1708 isntruction that modifies mlo and/or mhi. */
1709 strcpy (rname57
, "");
1710 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1711 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1714 /* The nature of arc_tp_regno is actually something more like a global
1715 register, however globalize_reg requires a declaration.
1716 We use EPILOGUE_USES to compensate so that sets from
1717 __builtin_set_frame_pointer are not deleted. */
1718 if (arc_tp_regno
!= -1)
1719 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1721 if (TARGET_MULMAC_32BY16_SET
)
1724 fix_end
= fix_end
> 57 ? fix_end
: 57;
1725 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1726 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1728 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1730 if (!fixed_regs
[regno
])
1731 warning (0, "multiply option implies r%d is fixed", regno
);
1732 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1738 reg_alloc_order
[0] = 0;
1739 reg_alloc_order
[1] = 1;
1740 reg_alloc_order
[2] = 2;
1741 reg_alloc_order
[3] = 3;
1742 reg_alloc_order
[4] = 12;
1743 reg_alloc_order
[5] = 13;
1744 reg_alloc_order
[6] = 14;
1745 reg_alloc_order
[7] = 15;
1746 reg_alloc_order
[8] = 4;
1747 reg_alloc_order
[9] = 5;
1748 reg_alloc_order
[10] = 6;
1749 reg_alloc_order
[11] = 7;
1750 reg_alloc_order
[12] = 8;
1751 reg_alloc_order
[13] = 9;
1752 reg_alloc_order
[14] = 10;
1753 reg_alloc_order
[15] = 11;
1757 reg_alloc_order
[2] = 12;
1758 reg_alloc_order
[3] = 13;
1759 reg_alloc_order
[4] = 14;
1760 reg_alloc_order
[5] = 15;
1761 reg_alloc_order
[6] = 1;
1762 reg_alloc_order
[7] = 0;
1763 reg_alloc_order
[8] = 4;
1764 reg_alloc_order
[9] = 5;
1765 reg_alloc_order
[10] = 6;
1766 reg_alloc_order
[11] = 7;
1767 reg_alloc_order
[12] = 8;
1768 reg_alloc_order
[13] = 9;
1769 reg_alloc_order
[14] = 10;
1770 reg_alloc_order
[15] = 11;
1773 if (TARGET_SIMD_SET
)
1776 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1777 reg_alloc_order
[i
] = i
;
1778 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1779 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1780 reg_alloc_order
[i
] = i
;
1783 /* Reduced configuration: don't use r4-r9, r16-r25. */
1786 for (i
= 4; i
<= 9; i
++)
1788 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1790 for (i
= 16; i
<= 25; i
++)
1792 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1796 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1797 if (!call_used_regs
[regno
])
1798 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1799 for (regno
= 32; regno
< 60; regno
++)
1800 if (!fixed_regs
[regno
])
1801 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1802 if (!TARGET_ARC600_FAMILY
)
1804 for (regno
= 32; regno
<= 60; regno
++)
1805 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1807 /* If they have used -ffixed-lp_count, make sure it takes
1809 if (fixed_regs
[LP_COUNT
])
1811 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1812 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1813 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1815 /* Instead of taking out SF_MODE like below, forbid it outright. */
1816 arc_hard_regno_modes
[60] = 0;
1819 arc_hard_regno_modes
[60] = 1 << (int) S_MODE
;
1822 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1826 for (regno
= 1; regno
< 32; regno
+=2)
1828 arc_hard_regno_modes
[regno
] = S_MODES
;
1832 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1836 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1837 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1838 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1840 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1843 arc_regno_reg_class
[i
]
1845 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1846 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1847 : (((!TARGET_ARC600_FAMILY
)
1848 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1849 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1851 arc_regno_reg_class
[i
] = NO_REGS
;
1854 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1855 has not been activated. */
1856 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1857 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1858 if (!TARGET_Q_CLASS
)
1859 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1861 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1863 /* Handle Special Registers. */
1864 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1866 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1867 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1868 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1869 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1870 arc_regno_reg_class
[62] = GENERAL_REGS
;
1874 for (i
= 40; i
< 44; ++i
)
1876 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1878 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1879 no attempt is made to use such a register as a destination
1880 operand in *movdf_insn. */
1881 if (!TARGET_ARGONAUT_SET
)
1883 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1884 interpreted to mean they can use D1 or D2 in their insn. */
1885 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1886 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1887 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1888 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1894 /* Disable all DOUBLE_REGISTER settings,
1895 if not generating DPFP code. */
1896 arc_regno_reg_class
[40] = ALL_REGS
;
1897 arc_regno_reg_class
[41] = ALL_REGS
;
1898 arc_regno_reg_class
[42] = ALL_REGS
;
1899 arc_regno_reg_class
[43] = ALL_REGS
;
1906 arc_hard_regno_modes
[40] = 0;
1907 arc_hard_regno_modes
[42] = 0;
1909 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1912 if (TARGET_SIMD_SET
)
1914 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1915 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1917 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1918 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1920 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1921 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1922 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1923 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1925 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1926 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1927 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1931 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
1933 /*ARCV2 Accumulator. */
1935 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1936 || TARGET_PLUS_DMPY
)
1938 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
1939 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
1940 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
1941 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
1942 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
1943 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
1944 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCL_REGNO
);
1945 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCH_REGNO
);
1946 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCL_REGNO
);
1947 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCH_REGNO
);
1949 /* Allow the compiler to freely use them. */
1950 if (!TEST_HARD_REG_BIT (overrideregs
, ACCL_REGNO
))
1951 fixed_regs
[ACCL_REGNO
] = 0;
1952 if (!TEST_HARD_REG_BIT (overrideregs
, ACCH_REGNO
))
1953 fixed_regs
[ACCH_REGNO
] = 0;
1955 if (!fixed_regs
[ACCH_REGNO
] && !fixed_regs
[ACCL_REGNO
])
1956 arc_hard_regno_modes
[ACC_REG_FIRST
] = D_MODES
;
1960 /* Implement TARGET_HARD_REGNO_NREGS. */
1963 arc_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
1965 if (GET_MODE_SIZE (mode
) == 16
1966 && regno
>= ARC_FIRST_SIMD_VR_REG
1967 && regno
<= ARC_LAST_SIMD_VR_REG
)
1970 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
1973 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1976 arc_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
1978 return (arc_hard_regno_modes
[regno
] & arc_mode_class
[mode
]) != 0;
1981 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1984 arc_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
1986 return (GET_MODE_CLASS (mode1
) == MODE_INT
1987 && GET_MODE_CLASS (mode2
) == MODE_INT
1988 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
1989 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
);
1992 /* Handle an "interrupt" attribute; arguments as in
1993 struct attribute_spec.handler. */
1996 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
2001 tree value
= TREE_VALUE (args
);
2003 if (TREE_CODE (value
) != STRING_CST
)
2005 warning (OPT_Wattributes
,
2006 "argument of %qE attribute is not a string constant",
2008 *no_add_attrs
= true;
2011 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
2012 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2014 warning (OPT_Wattributes
,
2015 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2017 *no_add_attrs
= true;
2020 && strcmp (TREE_STRING_POINTER (value
), "ilink")
2021 && strcmp (TREE_STRING_POINTER (value
), "firq"))
2023 warning (OPT_Wattributes
,
2024 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2026 *no_add_attrs
= true;
2033 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
2034 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
2036 if (TREE_CODE (*node
) != FUNCTION_DECL
)
2038 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2040 *no_add_attrs
= true;
2046 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2049 arc_allocate_stack_slots_for_args (void)
2051 /* Naked functions should not allocate stack slots for arguments. */
2052 unsigned int fn_type
= arc_compute_function_type (cfun
);
2054 return !ARC_NAKED_P(fn_type
);
2057 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2060 arc_warn_func_return (tree decl
)
2062 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
2063 unsigned int fn_type
= arc_compute_function_type (func
);
2065 return !ARC_NAKED_P (fn_type
);
2068 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2069 and two if they are nearly compatible (which causes a warning to be
2073 arc_comp_type_attributes (const_tree type1
,
2076 int l1
, l2
, m1
, m2
, s1
, s2
;
2078 /* Check for mismatch of non-default calling convention. */
2079 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
2082 /* Check for mismatched call attributes. */
2083 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2084 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2085 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2086 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2087 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2088 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2090 /* Only bother to check if an attribute is defined. */
2091 if (l1
| l2
| m1
| m2
| s1
| s2
)
2093 /* If one type has an attribute, the other must have the same attribute. */
2094 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
2097 /* Disallow mixed attributes. */
2098 if (l1
+ m1
+ s1
> 1)
2106 /* Misc. utilities. */
2108 /* X and Y are two things to compare using CODE. Emit the compare insn and
2109 return the rtx for the cc reg in the proper mode. */
2112 gen_compare_reg (rtx comparison
, machine_mode omode
)
2114 enum rtx_code code
= GET_CODE (comparison
);
2115 rtx x
= XEXP (comparison
, 0);
2116 rtx y
= XEXP (comparison
, 1);
2118 machine_mode mode
, cmode
;
2121 cmode
= GET_MODE (x
);
2122 if (cmode
== VOIDmode
)
2123 cmode
= GET_MODE (y
);
2124 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
2125 if (cmode
== SImode
)
2127 if (!register_operand (x
, SImode
))
2129 if (register_operand (y
, SImode
))
2134 code
= swap_condition (code
);
2137 x
= copy_to_mode_reg (SImode
, x
);
2139 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
2140 y
= copy_to_mode_reg (SImode
, y
);
2144 x
= force_reg (cmode
, x
);
2145 y
= force_reg (cmode
, y
);
2147 mode
= SELECT_CC_MODE (code
, x
, y
);
2149 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
2151 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2152 cmpdfpx_raw, is not a correct comparison for floats:
2153 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2155 if (TARGET_ARGONAUT_SET
2156 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2160 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2161 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2163 case GT
: case UNLE
: case GE
: case UNLT
:
2164 code
= swap_condition (code
);
2172 if (cmode
== SFmode
)
2174 emit_insn (gen_cmpsfpx_raw (x
, y
));
2178 /* Accepts Dx regs directly by insns. */
2179 emit_insn (gen_cmpdfpx_raw (x
, y
));
2182 if (mode
!= CC_FPXmode
)
2183 emit_insn (gen_rtx_SET (cc_reg
,
2184 gen_rtx_COMPARE (mode
,
2185 gen_rtx_REG (CC_FPXmode
, 61),
2188 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2192 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2193 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2195 case LT
: case UNGE
: case LE
: case UNGT
:
2196 code
= swap_condition (code
);
2205 emit_insn (gen_cmp_quark (cc_reg
,
2206 gen_rtx_COMPARE (mode
, x
, y
)));
2208 else if (TARGET_HARD_FLOAT
2209 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2210 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2211 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2212 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2214 rtx op0
= gen_rtx_REG (cmode
, 0);
2215 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2220 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2221 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2223 case LT
: case UNGE
: case LE
: case UNGT
:
2224 code
= swap_condition (code
);
2230 if (currently_expanding_to_rtl
)
2238 emit_move_insn (op0
, x
);
2239 emit_move_insn (op1
, y
);
2243 gcc_assert (rtx_equal_p (op0
, x
));
2244 gcc_assert (rtx_equal_p (op1
, y
));
2251 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2254 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2255 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2258 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2259 We assume the value can be either signed or unsigned. */
2262 arc_double_limm_p (rtx value
)
2264 HOST_WIDE_INT low
, high
;
2266 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2271 low
= CONST_DOUBLE_LOW (value
);
2272 high
= CONST_DOUBLE_HIGH (value
);
2274 if (low
& 0x80000000)
2276 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2277 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2278 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2283 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2287 /* Do any needed setup for a variadic function. For the ARC, we must
2288 create a register parameter block, and then copy any anonymous arguments
2289 in registers to memory.
2291 CUM has not been updated for the last named argument which has type TYPE
2292 and mode MODE, and we rely on this fact. */
2295 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2296 machine_mode mode
, tree type
,
2297 int *pretend_size
, int no_rtl
)
2300 CUMULATIVE_ARGS next_cum
;
2302 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2304 next_cum
= *get_cumulative_args (args_so_far
);
2305 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2307 first_anon_arg
= next_cum
;
2309 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2311 /* First anonymous (unnamed) argument is in a reg. */
2313 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2314 int first_reg_offset
= first_anon_arg
;
2319 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2320 FIRST_PARM_OFFSET (0)));
2321 move_block_from_reg (first_reg_offset
, regblock
,
2322 MAX_ARC_PARM_REGS
- first_reg_offset
);
2326 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2330 /* Cost functions. */
2332 /* Provide the costs of an addressing mode that contains ADDR.
2333 If ADDR is not a valid address, its cost is irrelevant. */
2336 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2338 switch (GET_CODE (addr
))
2341 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2342 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2343 case PRE_MODIFY
: case POST_MODIFY
:
2349 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2351 /* Most likely needs a LIMM. */
2352 return COSTS_N_INSNS (1);
2356 register rtx plus0
= XEXP (addr
, 0);
2357 register rtx plus1
= XEXP (addr
, 1);
2359 if (GET_CODE (plus0
) != REG
2360 && (GET_CODE (plus0
) != MULT
2361 || !CONST_INT_P (XEXP (plus0
, 1))
2362 || (INTVAL (XEXP (plus0
, 1)) != 2
2363 && INTVAL (XEXP (plus0
, 1)) != 4)))
2366 switch (GET_CODE (plus1
))
2369 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2373 : (satisfies_constraint_Rcq (plus0
)
2374 && satisfies_constraint_O (plus1
))
2378 return (speed
< 1 ? 0
2379 : (satisfies_constraint_Rcq (plus0
)
2380 && satisfies_constraint_Rcq (plus1
))
2385 return COSTS_N_INSNS (1);
2398 /* Emit instruction X with the frame related bit set. */
2404 RTX_FRAME_RELATED_P (x
) = 1;
2408 /* Emit a frame insn to move SRC to DST. */
2411 frame_move (rtx dst
, rtx src
)
2413 rtx tmp
= gen_rtx_SET (dst
, src
);
2414 RTX_FRAME_RELATED_P (tmp
) = 1;
2415 return frame_insn (tmp
);
2418 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2419 auto increment address, or is zero. */
2422 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2424 rtx insn
= frame_move (dst
, src
);
2427 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2428 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2429 add_reg_note (insn
, REG_INC
, reg
);
2433 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2436 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2438 gcc_assert ((offset
& 0x3) == 0);
2441 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2444 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2447 frame_stack_add (HOST_WIDE_INT offset
)
2449 return frame_add (stack_pointer_rtx
, offset
);
2452 /* Traditionally, we push saved registers first in the prologue,
2453 then we allocate the rest of the frame - and reverse in the epilogue.
2454 This has still its merits for ease of debugging, or saving code size
2455 or even execution time if the stack frame is so large that some accesses
2456 can't be encoded anymore with offsets in the instruction code when using
2458 Also, it would be a good starting point if we got instructions to help
2459 with register save/restore.
2461 However, often stack frames are small, and the pushing / popping has
2463 - the stack modification prevents a lot of scheduling.
2464 - frame allocation / deallocation needs extra instructions.
2465 - unless we know that we compile ARC700 user code, we need to put
2466 a memory barrier after frame allocation / before deallocation to
2467 prevent interrupts clobbering our data in the frame.
2468 In particular, we don't have any such guarantees for library functions,
2469 which tend to, on the other hand, to have small frames.
2471 Thus, for small frames, we'd like to use a different scheme:
2472 - The frame is allocated in full with the first prologue instruction,
2473 and deallocated in full with the last epilogue instruction.
2474 Thus, the instructions in-betwen can be freely scheduled.
2475 - If the function has no outgoing arguments on the stack, we can allocate
2476 one register save slot at the top of the stack. This register can then
2477 be saved simultanously with frame allocation, and restored with
2479 This register can be picked depending on scheduling considerations,
2480 although same though should go into having some set of registers
2481 to be potentially lingering after a call, and others to be available
2482 immediately - i.e. in the absence of interprocedual optimization, we
2483 can use an ABI-like convention for register allocation to reduce
2484 stalls after function return. */
2485 /* Function prologue/epilogue handlers. */
2487 /* ARCompact stack frames look like:
2489 Before call After call
2490 high +-----------------------+ +-----------------------+
2491 mem | reg parm save area | | reg parm save area |
2492 | only created for | | only created for |
2493 | variable arg fns | | variable arg fns |
2494 AP +-----------------------+ +-----------------------+
2495 | return addr register | | return addr register |
2496 | (if required) | | (if required) |
2497 +-----------------------+ +-----------------------+
2499 | reg save area | | reg save area |
2501 +-----------------------+ +-----------------------+
2502 | frame pointer | | frame pointer |
2503 | (if required) | | (if required) |
2504 FP +-----------------------+ +-----------------------+
2506 | local/temp variables | | local/temp variables |
2508 +-----------------------+ +-----------------------+
2510 | arguments on stack | | arguments on stack |
2512 SP +-----------------------+ +-----------------------+
2513 | reg parm save area |
2514 | only created for |
2515 | variable arg fns |
2516 AP +-----------------------+
2517 | return addr register |
2519 +-----------------------+
2523 +-----------------------+
2526 FP +-----------------------+
2528 | local/temp variables |
2530 +-----------------------+
2532 | arguments on stack |
2534 mem SP +-----------------------+
2537 1) The "reg parm save area" does not exist for non variable argument fns.
2538 The "reg parm save area" can be eliminated completely if we created our
2539 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2541 /* Structure to be filled in by arc_compute_frame_size with register
2542 save masks, and offsets for the current function. */
2543 struct GTY (()) arc_frame_info
2545 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2546 unsigned int extra_size
; /* # bytes of extra stuff. */
2547 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2548 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2549 unsigned int reg_size
; /* # bytes needed to store regs. */
2550 unsigned int var_size
; /* # bytes that variables take up. */
2551 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2552 unsigned int gmask
; /* Mask of saved gp registers. */
2553 int initialized
; /* Nonzero if frame size already calculated. */
2554 short millicode_start_reg
;
2555 short millicode_end_reg
;
2556 bool save_return_addr
;
2559 /* Defining data structures for per-function information. */
2561 typedef struct GTY (()) machine_function
2563 unsigned int fn_type
;
2564 struct arc_frame_info frame_info
;
2565 /* To keep track of unalignment caused by short insns. */
2567 int force_short_suffix
; /* Used when disgorging return delay slot insns. */
2568 const char *size_reason
;
2569 struct arc_ccfsm ccfsm_current
;
2570 /* Map from uid to ccfsm state during branch shortening. */
2571 rtx ccfsm_current_insn
;
2572 char arc_reorg_started
;
2573 char prescan_initialized
;
2576 /* Type of function DECL.
2578 The result is cached. To reset the cache at the end of a function,
2579 call with DECL = NULL_TREE. */
2582 arc_compute_function_type (struct function
*fun
)
2584 tree attr
, decl
= fun
->decl
;
2585 unsigned int fn_type
= fun
->machine
->fn_type
;
2587 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2590 /* Check if it is a naked function. */
2591 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2592 fn_type
|= ARC_FUNCTION_NAKED
;
2594 fn_type
|= ARC_FUNCTION_NORMAL
;
2596 /* Now see if this is an interrupt handler. */
2597 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2598 if (attr
!= NULL_TREE
)
2600 tree value
, args
= TREE_VALUE (attr
);
2602 gcc_assert (list_length (args
) == 1);
2603 value
= TREE_VALUE (args
);
2604 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2606 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2607 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2608 fn_type
|= ARC_FUNCTION_ILINK1
;
2609 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2610 fn_type
|= ARC_FUNCTION_ILINK2
;
2611 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2612 fn_type
|= ARC_FUNCTION_FIRQ
;
2617 return fun
->machine
->fn_type
= fn_type
;
2620 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2621 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2623 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2624 The return address and frame pointer are treated separately.
2625 Don't consider them here.
2626 Addition for pic: The gp register needs to be saved if the current
2627 function changes it to access gotoff variables.
2628 FIXME: This will not be needed if we used some arbitrary register
2632 arc_must_save_register (int regno
, struct function
*func
)
2634 unsigned int fn_type
= arc_compute_function_type (func
);
2635 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2636 && ARC_AUTO_IRQ_P (fn_type
));
2637 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2639 switch (rgf_banked_register_count
)
2642 firq_auto_save_p
&= (regno
< 4);
2645 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2648 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2649 || ((regno
> 25) && (regno
< 29))
2650 || ((regno
> 29) && (regno
< 32)));
2653 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2656 firq_auto_save_p
= false;
2660 if ((regno
) != RETURN_ADDR_REGNUM
2661 && (regno
) != FRAME_POINTER_REGNUM
2662 && df_regs_ever_live_p (regno
)
2663 && (!call_used_regs
[regno
]
2664 || ARC_INTERRUPT_P (fn_type
))
2665 /* Do not emit code for auto saved regs. */
2667 && !firq_auto_save_p
)
2673 /* Return true if the return address must be saved in the current function,
2674 otherwise return false. */
2677 arc_must_save_return_addr (struct function
*func
)
2679 if (func
->machine
->frame_info
.save_return_addr
)
2685 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2686 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2687 Register Allocator) pass, while we want to get the frame size
2688 correct earlier than the IRA pass.
2690 When a function uses eh_return we must ensure that the fp register
2691 is saved and then restored so that the unwinder can restore the
2692 correct value for the frame we are going to jump to.
2694 To do this we force all frames that call eh_return to require a
2695 frame pointer (see arc_frame_pointer_required), this
2696 will ensure that the previous frame pointer is stored on entry to
2697 the function, and will then be reloaded at function exit.
2699 As the frame pointer is handled as a special case in our prologue
2700 and epilogue code it must not be saved and restored using the
2701 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2702 believes that the function is not using a frame pointer and that
2703 the value in the fp register is the frame pointer, while the
2704 prologue and epilogue are busy saving and restoring the fp
2707 During compilation of a function the frame size is evaluated
2708 multiple times, it is not until the reload pass is complete the the
2709 frame size is considered fixed (it is at this point that space for
2710 all spills has been allocated). However the frame_pointer_needed
2711 variable is not set true until the register allocation pass, as a
2712 result in the early stages the frame size does not include space
2713 for the frame pointer to be spilled.
2715 The problem that this causes is that the rtl generated for
2716 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2717 the offset from the frame pointer at which the return address
2718 lives. However, in early passes GCC has not yet realised we need a
2719 frame pointer, and so has not included space for the frame pointer
2720 in the frame size, and so gets the offset of the return address
2721 wrong. This should not be an issue as in later passes GCC has
2722 realised that the frame pointer needs to be spilled, and has
2723 increased the frame size. However, the rtl for the
2724 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2725 offset, and the wrong smaller offset is used. */
2728 arc_frame_pointer_needed (void)
2730 return (frame_pointer_needed
|| crtl
->calls_eh_return
);
2733 /* Return non-zero if there are registers to be saved or loaded using
2734 millicode thunks. We can only use consecutive sequences starting
2735 with r13, and not going beyond r25.
2736 GMASK is a bitmask of registers to save. This function sets
2737 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2738 of registers to be saved / restored with a millicode call. */
2741 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2742 struct arc_frame_info
*frame
)
2746 int start_reg
= 13, end_reg
= 25;
2748 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2750 end_reg
= regno
- 1;
2751 /* There is no point in using millicode thunks if we don't save/restore
2752 at least three registers. For non-leaf functions we also have the
2754 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2756 frame
->millicode_start_reg
= 13;
2757 frame
->millicode_end_reg
= regno
- 1;
2763 /* Return the bytes needed to compute the frame pointer from the
2764 current stack pointer. */
2767 arc_compute_frame_size (void)
2770 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2771 unsigned int reg_size
, reg_offset
;
2773 struct arc_frame_info
*frame_info
;
2776 /* The answer might already be known. */
2777 if (cfun
->machine
->frame_info
.initialized
)
2778 return cfun
->machine
->frame_info
.total_size
;
2780 frame_info
= &cfun
->machine
->frame_info
;
2781 size
= ARC_STACK_ALIGN (get_frame_size ());
2783 /* 1) Size of locals and temporaries. */
2786 /* 2) Size of outgoing arguments. */
2787 args_size
= crtl
->outgoing_args_size
;
2789 /* 3) Calculate space needed for saved registers.
2790 ??? We ignore the extension registers for now. */
2792 /* See if this is an interrupt handler. Call used registers must be saved
2798 for (regno
= 0; regno
<= 31; regno
++)
2800 if (arc_must_save_register (regno
, cfun
))
2802 reg_size
+= UNITS_PER_WORD
;
2803 gmask
|= 1L << regno
;
2807 /* In a frame that calls __builtin_eh_return two data registers are
2808 used to pass values back to the exception handler.
2810 Ensure that these registers are spilled to the stack so that the
2811 exception throw code can find them, and update the saved values.
2812 The handling code will then consume these reloaded values to
2813 handle the exception. */
2814 if (crtl
->calls_eh_return
)
2815 for (regno
= 0; EH_RETURN_DATA_REGNO (regno
) != INVALID_REGNUM
; regno
++)
2817 reg_size
+= UNITS_PER_WORD
;
2818 gmask
|= 1 << regno
;
2821 /* 4) Space for back trace data structure.
2822 <return addr reg size> (if required) + <fp size> (if required). */
2823 frame_info
->save_return_addr
2824 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2825 || crtl
->calls_eh_return
);
2826 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2828 && !TARGET_NO_MILLICODE_THUNK_SET
2829 && !crtl
->calls_eh_return
)
2831 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2832 frame_info
->save_return_addr
= true;
2836 if (arc_must_save_return_addr (cfun
))
2838 if (arc_frame_pointer_needed ())
2841 /* 5) Space for variable arguments passed in registers */
2842 pretend_size
= crtl
->args
.pretend_args_size
;
2844 /* Ensure everything before the locals is aligned appropriately. */
2846 unsigned int extra_plus_reg_size
;
2847 unsigned int extra_plus_reg_size_aligned
;
2849 extra_plus_reg_size
= extra_size
+ reg_size
;
2850 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2851 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2854 /* Compute total frame size. */
2855 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2857 /* It used to be the case that the alignment was forced at this
2858 point. However, that is dangerous, calculations based on
2859 total_size would be wrong. Given that this has never cropped up
2860 as an issue I've changed this to an assert for now. */
2861 gcc_assert (total_size
== ARC_STACK_ALIGN (total_size
));
2863 /* Compute offset of register save area from stack pointer:
2864 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2866 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2867 + (arc_frame_pointer_needed () ? 4 : 0));
2869 /* Save computed information. */
2870 frame_info
->total_size
= total_size
;
2871 frame_info
->extra_size
= extra_size
;
2872 frame_info
->pretend_size
= pretend_size
;
2873 frame_info
->var_size
= var_size
;
2874 frame_info
->args_size
= args_size
;
2875 frame_info
->reg_size
= reg_size
;
2876 frame_info
->reg_offset
= reg_offset
;
2877 frame_info
->gmask
= gmask
;
2878 frame_info
->initialized
= reload_completed
;
2880 /* Ok, we're done. */
2884 /* Common code to save/restore registers. */
2885 /* BASE_REG is the base register to use for addressing and to adjust.
2886 GMASK is a bitmask of general purpose registers to save/restore.
2887 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2888 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2889 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2893 arc_save_restore (rtx base_reg
,
2894 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2896 unsigned int offset
= 0;
2898 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2899 rtx sibthunk_insn
= NULL_RTX
;
2903 /* Millicode thunks implementation:
2904 Generates calls to millicodes for registers starting from r13 to r25
2905 Present Limitations:
2906 - Only one range supported. The remaining regs will have the ordinary
2907 st and ld instructions for store and loads. Hence a gmask asking
2908 to store r13-14, r16-r25 will only generate calls to store and
2909 load r13 to r14 while store and load insns will be generated for
2910 r16 to r25 in the prologue and epilogue respectively.
2912 - Presently library only supports register ranges starting from r13.
2914 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2916 int start_call
= frame
->millicode_start_reg
;
2917 int end_call
= frame
->millicode_end_reg
;
2918 int n_regs
= end_call
- start_call
+ 1;
2919 int i
= 0, r
, off
= 0;
2921 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2925 /* "reg_size" won't be more than 127 . */
2926 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
2927 frame_add (base_reg
, *first_offset
);
2930 insn
= gen_rtx_PARALLEL
2931 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
2932 if (epilogue_p
== 2)
2935 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
2936 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
2938 rtx reg
= gen_rtx_REG (SImode
, r
);
2940 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
2943 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
2945 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
2946 gmask
= gmask
& ~(1L << r
);
2948 if (epilogue_p
== 2)
2949 sibthunk_insn
= insn
;
2952 insn
= frame_insn (insn
);
2953 for (r
= start_call
, off
= 0;
2955 r
++, off
+= UNITS_PER_WORD
)
2957 rtx reg
= gen_rtx_REG (SImode
, r
);
2959 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2962 rtx mem
= gen_rtx_MEM (SImode
, plus_constant (Pmode
,
2966 add_reg_note (insn
, REG_CFA_OFFSET
,
2967 gen_rtx_SET (mem
, reg
));
2974 for (regno
= 0; regno
<= 31; regno
++)
2976 machine_mode mode
= SImode
;
2981 && ((gmask
& (1L << regno
)) != 0)
2982 && ((gmask
& (1L << (regno
+1))) != 0))
2987 else if ((gmask
& (1L << regno
)) != 0)
2995 rtx reg
= gen_rtx_REG (mode
, regno
);
2997 int cfa_adjust
= *first_offset
;
3001 gcc_assert (!offset
);
3002 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
3003 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
3008 gcc_assert (SMALL_INT (offset
));
3009 addr
= plus_constant (Pmode
, base_reg
, offset
);
3011 mem
= gen_frame_mem (mode
, addr
);
3015 frame_move_inc (reg
, mem
, base_reg
, addr
);
3016 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3019 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3020 add_reg_note (insn
, note
,
3021 gen_rtx_SET (stack_pointer_rtx
,
3022 plus_constant (Pmode
,
3028 frame_move_inc (mem
, reg
, base_reg
, addr
);
3029 offset
+= UNITS_PER_WORD
;
3032 offset
+= UNITS_PER_WORD
;
3040 int start_call
= frame
->millicode_start_reg
;
3041 int end_call
= frame
->millicode_end_reg
;
3044 rtx r12
= gen_rtx_REG (Pmode
, 12);
3046 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
3047 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
3048 XVECEXP (sibthunk_insn
, 0, 1)
3049 = gen_rtx_SET (stack_pointer_rtx
,
3050 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
3051 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
3052 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
3054 /* Would be nice if we could do this earlier, when the PARALLEL
3055 is populated, but these need to be attached after the
3057 for (r
= start_call
; r
<= end_call
; r
++)
3059 rtx reg
= gen_rtx_REG (SImode
, r
);
3060 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
3063 } /* arc_save_restore */
3065 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
3069 arc_dwarf_emit_irq_save_regs (void)
3071 rtx tmp
, par
, insn
, reg
;
3074 par
= gen_rtx_SEQUENCE (VOIDmode
,
3075 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
3076 + irq_ctrl_saved
.irq_save_blink
3077 + irq_ctrl_saved
.irq_save_lpcount
3080 /* Build the stack adjustment note for unwind info. */
3082 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
3083 + irq_ctrl_saved
.irq_save_blink
3084 + irq_ctrl_saved
.irq_save_lpcount
);
3085 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
3086 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
3087 RTX_FRAME_RELATED_P (tmp
) = 1;
3088 XVECEXP (par
, 0, j
++) = tmp
;
3090 offset
-= UNITS_PER_WORD
;
3092 /* 1st goes LP_COUNT. */
3093 if (irq_ctrl_saved
.irq_save_lpcount
)
3095 reg
= gen_rtx_REG (SImode
, 60);
3096 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3097 tmp
= gen_frame_mem (SImode
, tmp
);
3098 tmp
= gen_rtx_SET (tmp
, reg
);
3099 RTX_FRAME_RELATED_P (tmp
) = 1;
3100 XVECEXP (par
, 0, j
++) = tmp
;
3101 offset
-= UNITS_PER_WORD
;
3104 /* 2nd goes BLINK. */
3105 if (irq_ctrl_saved
.irq_save_blink
)
3107 reg
= gen_rtx_REG (SImode
, 31);
3108 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3109 tmp
= gen_frame_mem (SImode
, tmp
);
3110 tmp
= gen_rtx_SET (tmp
, reg
);
3111 RTX_FRAME_RELATED_P (tmp
) = 1;
3112 XVECEXP (par
, 0, j
++) = tmp
;
3113 offset
-= UNITS_PER_WORD
;
3116 /* Build the parallel of the remaining registers recorded as saved
3118 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
3120 reg
= gen_rtx_REG (SImode
, i
);
3121 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3122 tmp
= gen_frame_mem (SImode
, tmp
);
3123 tmp
= gen_rtx_SET (tmp
, reg
);
3124 RTX_FRAME_RELATED_P (tmp
) = 1;
3125 XVECEXP (par
, 0, j
++) = tmp
;
3126 offset
-= UNITS_PER_WORD
;
3129 /* Dummy insn used to anchor the dwarf info. */
3130 insn
= emit_insn (gen_stack_irq_dwarf());
3131 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
3132 RTX_FRAME_RELATED_P (insn
) = 1;
3135 /* Set up the stack and frame pointer (if desired) for the function. */
3138 arc_expand_prologue (void)
3141 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
3142 /* unsigned int frame_pointer_offset;*/
3143 unsigned int frame_size_to_allocate
;
3144 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
3145 Change the stack layout so that we rather store a high register with the
3146 PRE_MODIFY, thus enabling more short insn generation.) */
3147 int first_offset
= 0;
3148 unsigned int fn_type
= arc_compute_function_type (cfun
);
3150 /* Naked functions don't have prologue. */
3151 if (ARC_NAKED_P (fn_type
))
3153 if (flag_stack_usage_info
)
3154 current_function_static_stack_size
= 0;
3158 /* Compute total frame size. */
3159 size
= arc_compute_frame_size ();
3161 if (flag_stack_usage_info
)
3162 current_function_static_stack_size
= size
;
3164 /* Keep track of frame size to be allocated. */
3165 frame_size_to_allocate
= size
;
3167 /* These cases shouldn't happen. Catch them now. */
3168 gcc_assert (!(size
== 0 && gmask
));
3170 /* Allocate space for register arguments if this is a variadic function. */
3171 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
3173 /* Ensure pretend_size is maximum of 8 * word_size. */
3174 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
3176 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
3177 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
3180 /* IRQ using automatic save mechanism will save the register before
3182 if (ARC_AUTO_IRQ_P (fn_type
)
3183 && !ARC_FAST_INTERRUPT_P (fn_type
))
3185 arc_dwarf_emit_irq_save_regs ();
3188 /* The home-grown ABI says link register is saved first. */
3189 if (arc_must_save_return_addr (cfun
)
3190 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3192 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
3193 rtx mem
= gen_frame_mem (Pmode
,
3194 gen_rtx_PRE_DEC (Pmode
,
3195 stack_pointer_rtx
));
3197 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
3198 frame_size_to_allocate
-= UNITS_PER_WORD
;
3201 /* Save any needed call-saved regs (and call-used if this is an
3202 interrupt handler) for ARCompact ISA. */
3203 if (cfun
->machine
->frame_info
.reg_size
)
3205 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
3206 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3207 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
3208 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
3211 /* In the case of millicode thunk, we need to restore the clobbered
3213 if (cfun
->machine
->frame_info
.millicode_end_reg
> 0
3214 && arc_must_save_return_addr (cfun
))
3216 HOST_WIDE_INT tmp
= cfun
->machine
->frame_info
.reg_size
;
3217 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
),
3219 plus_constant (Pmode
,
3224 /* Save frame pointer if needed. First save the FP on stack, if not
3226 if (arc_frame_pointer_needed ()
3227 && !ARC_AUTOFP_IRQ_P (fn_type
))
3229 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
3230 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
3231 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
3234 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
3235 frame_size_to_allocate
-= UNITS_PER_WORD
;
3239 /* Emit mov fp,sp. */
3240 if (arc_frame_pointer_needed ())
3242 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3245 /* ??? We don't handle the case where the saved regs are more than 252
3246 bytes away from sp. This can be handled by decrementing sp once, saving
3247 the regs, and then decrementing it again. The epilogue doesn't have this
3248 problem as the `ld' insn takes reg+limm values (though it would be more
3249 efficient to avoid reg+limm). */
3251 frame_size_to_allocate
-= first_offset
;
3252 /* Allocate the stack frame. */
3253 if (frame_size_to_allocate
> 0)
3255 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3256 /* If the frame pointer is needed, emit a special barrier that
3257 will prevent the scheduler from moving stores to the frame
3258 before the stack adjustment. */
3259 if (arc_frame_pointer_needed ())
3260 emit_insn (gen_stack_tie (stack_pointer_rtx
,
3261 hard_frame_pointer_rtx
));
3265 /* Do any necessary cleanup after a function to restore stack, frame,
3269 arc_expand_epilogue (int sibcall_p
)
3272 unsigned int fn_type
= arc_compute_function_type (cfun
);
3274 size
= arc_compute_frame_size ();
3276 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
3277 unsigned int frame_size
;
3278 unsigned int size_to_deallocate
;
3280 int can_trust_sp_p
= !cfun
->calls_alloca
;
3281 int first_offset
= 0;
3282 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
3285 /* Naked functions don't have epilogue. */
3286 if (ARC_NAKED_P (fn_type
))
3289 size_to_deallocate
= size
;
3291 frame_size
= size
- (pretend_size
+
3292 cfun
->machine
->frame_info
.reg_size
+
3293 cfun
->machine
->frame_info
.extra_size
);
3295 /* ??? There are lots of optimizations that can be done here.
3296 EG: Use fp to restore regs if it's closer.
3297 Maybe in time we'll do them all. For now, always restore regs from
3298 sp, but don't restore sp if we don't have to. */
3300 if (!can_trust_sp_p
)
3301 gcc_assert (arc_frame_pointer_needed ());
3303 /* Restore stack pointer to the beginning of saved register area for
3307 if (arc_frame_pointer_needed ())
3308 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3310 first_offset
= frame_size
;
3311 size_to_deallocate
-= frame_size
;
3313 else if (!can_trust_sp_p
)
3314 frame_stack_add (-frame_size
);
3317 /* Restore any saved registers. */
3318 if (arc_frame_pointer_needed ()
3319 && !ARC_AUTOFP_IRQ_P (fn_type
))
3321 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
3323 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
3324 stack_pointer_rtx
, 0);
3325 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3326 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3327 plus_constant (SImode
, stack_pointer_rtx
,
3329 size_to_deallocate
-= UNITS_PER_WORD
;
3332 /* Load blink after the calls to thunk calls in case of optimize size. */
3335 int sibthunk_p
= (!sibcall_p
3336 && fn_type
== ARC_FUNCTION_NORMAL
3337 && !cfun
->machine
->frame_info
.pretend_size
);
3339 gcc_assert (!(cfun
->machine
->frame_info
.gmask
3340 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
3341 arc_save_restore (stack_pointer_rtx
,
3342 cfun
->machine
->frame_info
.gmask
,
3343 1 + sibthunk_p
, &first_offset
);
3347 /* If we are to restore registers, and first_offset would require
3348 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3349 fast add to the stack pointer, do this now. */
3350 if ((!SMALL_INT (first_offset
)
3351 && cfun
->machine
->frame_info
.gmask
3352 && ((TARGET_ARC700
&& !optimize_size
)
3353 ? first_offset
<= 0x800
3354 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
3355 /* Also do this if we have both gprs and return
3356 address to restore, and they both would need a LIMM. */
3357 || (arc_must_save_return_addr (cfun
)
3358 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
3359 && cfun
->machine
->frame_info
.gmask
))
3361 frame_stack_add (first_offset
);
3364 if (arc_must_save_return_addr (cfun
)
3365 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3367 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3368 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
3369 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
3370 HOST_WIDE_INT cfa_adjust
= 0;
3372 /* If the load of blink would need a LIMM, but we can add
3373 the offset quickly to sp, do the latter. */
3374 if (!SMALL_INT (ra_offs
>> 2)
3375 && !cfun
->machine
->frame_info
.gmask
3376 && ((TARGET_ARC700
&& !optimize_size
)
3378 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
3380 size_to_deallocate
-= ra_offs
- first_offset
;
3382 frame_stack_add (ra_offs
);
3384 addr
= stack_pointer_rtx
;
3386 /* See if we can combine the load of the return address with the
3387 final stack adjustment.
3388 We need a separate load if there are still registers to
3389 restore. We also want a separate load if the combined insn
3390 would need a limm, but a separate load doesn't. */
3392 && !cfun
->machine
->frame_info
.gmask
3393 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
3395 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
3396 cfa_adjust
= ra_offs
;
3398 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
3400 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
3402 addr
= gen_rtx_POST_INC (Pmode
, addr
);
3403 cfa_adjust
= GET_MODE_SIZE (Pmode
);
3404 size_to_deallocate
= 0;
3407 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
3408 stack_pointer_rtx
, addr
);
3411 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3413 add_reg_note (insn
, note
,
3414 gen_rtx_SET (stack_pointer_rtx
,
3415 plus_constant (SImode
, stack_pointer_rtx
,
3418 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
3423 if (cfun
->machine
->frame_info
.reg_size
)
3424 arc_save_restore (stack_pointer_rtx
,
3425 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3426 cfun
->machine
->frame_info
.gmask
3427 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
3430 /* The rest of this function does the following:
3431 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3434 /* Keep track of how much of the stack pointer we've restored.
3435 It makes the following a lot more readable. */
3436 size_to_deallocate
+= first_offset
;
3437 restored
= size
- size_to_deallocate
;
3439 if (size
> restored
)
3440 frame_stack_add (size
- restored
);
3442 /* For frames that use __builtin_eh_return, the register defined by
3443 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
3444 On eh_return paths however, the register is set to the value that
3445 should be added to the stack pointer in order to restore the
3446 correct stack pointer for the exception handling frame.
3448 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
3449 this onto the stack for eh_return frames. */
3450 if (crtl
->calls_eh_return
)
3451 emit_insn (gen_add2_insn (stack_pointer_rtx
,
3452 EH_RETURN_STACKADJ_RTX
));
3454 /* Emit the return instruction. */
3455 if (sibcall_p
== FALSE
)
3456 emit_jump_insn (gen_simple_return ());
3459 /* Return rtx for the location of the return address on the stack,
3460 suitable for use in __builtin_eh_return. The new return address
3461 will be written to this location in order to redirect the return to
3462 the exception handler. */
3465 arc_eh_return_address_location (void)
3469 struct arc_frame_info
*afi
;
3471 arc_compute_frame_size ();
3472 afi
= &cfun
->machine
->frame_info
;
3474 gcc_assert (crtl
->calls_eh_return
);
3475 gcc_assert (afi
->save_return_addr
);
3476 gcc_assert (afi
->extra_size
>= 4);
3478 /* The '-4' removes the size of the return address, which is
3479 included in the 'extra_size' field. */
3480 offset
= afi
->reg_size
+ afi
->extra_size
- 4;
3481 mem
= gen_frame_mem (Pmode
,
3482 plus_constant (Pmode
, frame_pointer_rtx
, offset
));
3484 /* The following should not be needed, and is, really a hack. The
3485 issue being worked around here is that the DSE (Dead Store
3486 Elimination) pass will remove this write to the stack as it sees
3487 a single store and no corresponding read. The read however
3488 occurs in the epilogue code, which is not added into the function
3489 rtl until a later pass. So, at the time of DSE, the decision to
3490 remove this store seems perfectly sensible. Marking the memory
3491 address as volatile obviously has the effect of preventing DSE
3492 from removing the store. */
3493 MEM_VOLATILE_P (mem
) = 1;
3499 /* Helper to generate unspec constant. */
3502 arc_unspec_offset (rtx loc
, int unspec
)
3504 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3508 /* !TARGET_BARREL_SHIFTER support. */
3509 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3513 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3515 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3517 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3518 (op0
, op1
, op2
, shift
));
3522 /* Output the assembler code for doing a shift.
3523 We go to a bit of trouble to generate efficient code as the ARC601 only has
3524 single bit shifts. This is taken from the h8300 port. We only have one
3525 mode of shifting and can't access individual bytes like the h8300 can, so
3526 this is greatly simplified (at the expense of not generating hyper-
3529 This function is not used if the variable shift insns are present. */
3531 /* FIXME: This probably can be done using a define_split in arc.md.
3532 Alternately, generate rtx rather than output instructions. */
3535 output_shift (rtx
*operands
)
3537 /* static int loopend_lab;*/
3538 rtx shift
= operands
[3];
3539 machine_mode mode
= GET_MODE (shift
);
3540 enum rtx_code code
= GET_CODE (shift
);
3541 const char *shift_one
;
3543 gcc_assert (mode
== SImode
);
3547 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3548 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3549 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3550 default: gcc_unreachable ();
3553 if (GET_CODE (operands
[2]) != CONST_INT
)
3555 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3562 n
= INTVAL (operands
[2]);
3564 /* Only consider the lower 5 bits of the shift count. */
3567 /* First see if we can do them inline. */
3568 /* ??? We could get better scheduling & shorter code (using short insns)
3569 by using splitters. Alas, that'd be even more verbose. */
3570 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3571 && dest_reg_operand (operands
[4], SImode
))
3573 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3574 for (n
-=3 ; n
>= 3; n
-= 3)
3575 output_asm_insn ("add3 %0,%4,%0", operands
);
3577 output_asm_insn ("add2 %0,%4,%0", operands
);
3579 output_asm_insn ("add %0,%0,%0", operands
);
3585 output_asm_insn (shift_one
, operands
);
3586 operands
[1] = operands
[0];
3589 /* See if we can use a rotate/and. */
3590 else if (n
== BITS_PER_WORD
- 1)
3595 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3598 /* The ARC doesn't have a rol insn. Use something else. */
3599 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
3602 /* The ARC doesn't have a rol insn. Use something else. */
3603 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
3609 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
3614 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
3617 #if 1 /* Need some scheduling comparisons. */
3618 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3619 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3621 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3622 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
3627 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3628 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3630 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3631 "and %0,%0,1\n\trlc %0,%0", operands
);
3638 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
3639 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3644 operands
[2] = GEN_INT (n
);
3645 output_asm_insn ("mov.f lp_count, %2", operands
);
3649 output_asm_insn ("lpnz\t2f", operands
);
3650 output_asm_insn (shift_one
, operands
);
3651 output_asm_insn ("nop", operands
);
3652 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
3661 /* Nested function support. */
3663 /* Output assembler code for a block containing the constant parts of
3664 a trampoline, leaving space for variable parts. A trampoline looks
3670 .word function's address
3671 .word static chain value
3676 arc_asm_trampoline_template (FILE *f
)
3678 asm_fprintf (f
, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG
);
3679 asm_fprintf (f
, "\tld\t%s,[pcl,12]\n", reg_names
[STATIC_CHAIN_REGNUM
]);
3680 asm_fprintf (f
, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG
);
3681 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
3682 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
3685 /* Emit RTL insns to initialize the variable parts of a trampoline.
3686 FNADDR is an RTX for the address of the function's pure code. CXT
3687 is an RTX for the static chain value for the function.
3689 The fastest trampoline to execute for trampolines within +-8KB of CTX
3693 j [limm] 0x20200f80 limm
3695 and that would also be faster to write to the stack by computing
3696 the offset from CTX to TRAMP at compile time. However, it would
3697 really be better to get rid of the high cost of cache invalidation
3698 when generating trampolines, which requires that the code part of
3699 trampolines stays constant, and additionally either making sure
3700 that no executable code but trampolines is on the stack, no icache
3701 entries linger for the area of the stack from when before the stack
3702 was allocated, and allocating trampolines in trampoline-only cache
3703 lines or allocate trampolines fram a special pool of pre-allocated
3707 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
3709 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3711 emit_block_move (tramp
, assemble_trampoline_template (),
3712 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
3713 emit_move_insn (adjust_address (tramp
, SImode
, 8), fnaddr
);
3714 emit_move_insn (adjust_address (tramp
, SImode
, 12), cxt
);
3715 emit_library_call (gen_rtx_SYMBOL_REF (Pmode
, "__clear_cache"),
3716 LCT_NORMAL
, VOIDmode
, XEXP (tramp
, 0), Pmode
,
3717 plus_constant (Pmode
, XEXP (tramp
, 0), TRAMPOLINE_SIZE
),
3721 /* Add the given function declaration to emit code in JLI section. */
3724 arc_add_jli_section (rtx pat
)
3728 arc_jli_section
*sec
= arc_jli_sections
, *new_section
;
3729 tree decl
= SYMBOL_REF_DECL (pat
);
3736 /* For fixed locations do not generate the jli table entry. It
3737 should be provided by the user as an asm file. */
3738 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
3739 if (lookup_attribute ("jli_fixed", attrs
))
3743 name
= XSTR (pat
, 0);
3745 /* Don't insert the same symbol twice. */
3748 if(strcmp (name
, sec
->name
) == 0)
3753 /* New name, insert it. */
3754 new_section
= (arc_jli_section
*) xmalloc (sizeof (arc_jli_section
));
3755 gcc_assert (new_section
!= NULL
);
3756 new_section
->name
= name
;
3757 new_section
->next
= arc_jli_sections
;
3758 arc_jli_sections
= new_section
;
3761 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3762 reset when we output the scaled address. */
3763 static int output_scaled
= 0;
3765 /* Print operand X (an rtx) in assembler syntax to file FILE.
3766 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3767 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3768 /* In final.c:output_asm_insn:
3771 'c' : constant address if CONSTANT_ADDRESS_P
3777 'p': bit Position of lsb
3778 's': size of bit field
3779 '#': condbranch delay slot suffix
3780 '*': jump delay slot suffix
3781 '?' : nonjump-insn suffix for conditional execution or short instruction
3782 '!' : jump / call suffix for conditional execution or short instruction
3783 '`': fold constant inside unary o-perator, re-recognize, and emit.
3787 'S': JLI instruction
3788 'j': used by mov instruction to properly emit jli related labels.
3789 'B': Branch comparison operand - suppress sda reference
3790 'H': Most significant word
3791 'L': Least significant word
3792 'A': ASCII decimal representation of floating point value
3793 'U': Load/store update or scaling indicator
3794 'V': cache bypass indicator for volatile
3799 'o': original symbol - no @ prepending. */
3802 arc_print_operand (FILE *file
, rtx x
, int code
)
3807 if (GET_CODE (x
) == CONST_INT
)
3808 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3810 output_operand_lossage ("invalid operand to %%Z code");
3815 if (GET_CODE (x
) == CONST_INT
)
3816 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3818 output_operand_lossage ("invalid operand to %%z code");
3823 if (GET_CODE (x
) == CONST_INT
)
3824 fprintf (file
, "%ld", INTVAL (x
) );
3826 output_operand_lossage ("invalid operands to %%c code");
3831 if (GET_CODE (x
) == CONST_INT
)
3832 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3834 output_operand_lossage ("invalid operand to %%M code");
3839 if (GET_CODE (x
) == CONST_INT
)
3840 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3842 output_operand_lossage ("invalid operand to %%p code");
3846 if (GET_CODE (x
) == CONST_INT
)
3848 HOST_WIDE_INT i
= INTVAL (x
);
3849 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3850 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3853 output_operand_lossage ("invalid operand to %%s code");
3857 /* Conditional branches depending on condition codes.
3858 Note that this is only for branches that were known to depend on
3859 condition codes before delay slot scheduling;
3860 out-of-range brcc / bbit expansions should use '*'.
3861 This distinction is important because of the different
3862 allowable delay slot insns and the output of the delay suffix
3863 for TARGET_AT_DBR_COND_EXEC. */
3865 /* Unconditional branches / branches not depending on condition codes.
3866 This could also be a CALL_INSN.
3867 Output the appropriate delay slot suffix. */
3868 if (final_sequence
&& final_sequence
->len () != 1)
3870 rtx_insn
*jump
= final_sequence
->insn (0);
3871 rtx_insn
*delay
= final_sequence
->insn (1);
3873 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3874 if (delay
->deleted ())
3876 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3877 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3878 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3879 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3886 case '?' : /* with leading "." */
3887 case '!' : /* without leading "." */
3888 /* This insn can be conditionally executed. See if the ccfsm machinery
3889 says it should be conditionalized.
3890 If it shouldn't, we'll check the compact attribute if this insn
3891 has a short variant, which may be used depending on code size and
3892 alignment considerations. */
3893 if (current_insn_predicate
)
3894 arc_ccfsm_current
.cc
3895 = get_arc_condition_code (current_insn_predicate
);
3896 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3898 /* Is this insn in a delay slot sequence? */
3899 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3900 || current_insn_predicate
3901 || CALL_P (final_sequence
->insn (0))
3902 || simplejump_p (final_sequence
->insn (0)))
3904 /* This insn isn't in a delay slot sequence, or conditionalized
3905 independently of its position in a delay slot. */
3906 fprintf (file
, "%s%s",
3907 code
== '?' ? "." : "",
3908 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3909 /* If this is a jump, there are still short variants. However,
3910 only beq_s / bne_s have the same offset range as b_s,
3911 and the only short conditional returns are jeq_s and jne_s. */
3913 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3914 || arc_ccfsm_current
.cc
== ARC_CC_NE
3915 || 0 /* FIXME: check if branch in 7 bit range. */))
3916 output_short_suffix (file
);
3918 else if (code
== '!') /* Jump with delay slot. */
3919 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
3920 else /* An Instruction in a delay slot of a jump or call. */
3922 rtx jump
= XVECEXP (final_sequence
, 0, 0);
3923 rtx insn
= XVECEXP (final_sequence
, 0, 1);
3925 /* If the insn is annulled and is from the target path, we need
3926 to inverse the condition test. */
3927 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3929 if (INSN_FROM_TARGET_P (insn
))
3930 fprintf (file
, "%s%s",
3931 code
== '?' ? "." : "",
3932 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
3934 fprintf (file
, "%s%s",
3935 code
== '?' ? "." : "",
3936 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3937 if (arc_ccfsm_current
.state
== 5)
3938 arc_ccfsm_current
.state
= 0;
3941 /* This insn is executed for either path, so don't
3942 conditionalize it at all. */
3943 output_short_suffix (file
);
3948 output_short_suffix (file
);
3951 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3954 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
3957 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
3958 (get_arc_condition_code (x
))],
3962 /* Write second word of DImode or DFmode reference,
3963 register or memory. */
3964 if (GET_CODE (x
) == REG
)
3965 fputs (reg_names
[REGNO (x
)+1], file
);
3966 else if (GET_CODE (x
) == MEM
)
3970 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3971 PRE_MODIFY, we will have handled the first word already;
3972 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3973 first word will be done later. In either case, the access
3974 to the first word will do the modify, and we only have
3975 to add an offset of four here. */
3976 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
3977 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
3978 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
3979 || GET_CODE (XEXP (x
, 0)) == POST_INC
3980 || GET_CODE (XEXP (x
, 0)) == POST_DEC
3981 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
3982 output_address (VOIDmode
,
3983 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
3984 else if (output_scaled
)
3986 rtx addr
= XEXP (x
, 0);
3987 int size
= GET_MODE_SIZE (GET_MODE (x
));
3989 output_address (VOIDmode
,
3990 plus_constant (Pmode
, XEXP (addr
, 0),
3991 ((INTVAL (XEXP (addr
, 1)) + 4)
3992 >> (size
== 2 ? 1 : 2))));
3996 output_address (VOIDmode
,
3997 plus_constant (Pmode
, XEXP (x
, 0), 4));
4001 output_operand_lossage ("invalid operand to %%R code");
4005 if (GET_CODE (x
) == SYMBOL_REF
4006 && arc_is_jli_call_p (x
))
4008 if (SYMBOL_REF_DECL (x
))
4010 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4011 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4013 if (lookup_attribute ("jli_fixed", attrs
))
4015 /* No special treatment for jli_fixed functions. */
4018 fprintf (file
, "%ld\t; @",
4019 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4020 assemble_name (file
, XSTR (x
, 0));
4024 fprintf (file
, "@__jli.");
4025 assemble_name (file
, XSTR (x
, 0));
4027 arc_add_jli_section (x
);
4030 if (GET_CODE (x
) == SYMBOL_REF
4031 && arc_is_secure_call_p (x
))
4033 /* No special treatment for secure functions. */
4036 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4037 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4039 fprintf (file
, "%ld\t; @",
4040 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4041 assemble_name (file
, XSTR (x
, 0));
4045 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4048 output_addr_const (file
, x
);
4054 if (GET_CODE (x
) == REG
)
4056 /* L = least significant word, H = most significant word. */
4057 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
4058 fputs (reg_names
[REGNO (x
)], file
);
4060 fputs (reg_names
[REGNO (x
)+1], file
);
4062 else if (GET_CODE (x
) == CONST_INT
4063 || GET_CODE (x
) == CONST_DOUBLE
)
4065 rtx first
, second
, word
;
4067 split_double (x
, &first
, &second
);
4069 if((WORDS_BIG_ENDIAN
) == 0)
4070 word
= (code
== 'L' ? first
: second
);
4072 word
= (code
== 'L' ? second
: first
);
4074 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
4077 output_operand_lossage ("invalid operand to %%H/%%L code");
4083 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
4084 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
4086 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
4087 fprintf (file
, "%s", str
);
4091 /* Output a load/store with update indicator if appropriate. */
4092 if (GET_CODE (x
) == MEM
)
4094 rtx addr
= XEXP (x
, 0);
4095 switch (GET_CODE (addr
))
4097 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
4098 fputs (".a", file
); break;
4099 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
4100 fputs (".ab", file
); break;
4102 /* Are we using a scaled index? */
4103 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4104 fputs (".as", file
);
4105 /* Can we use a scaled offset? */
4106 else if (CONST_INT_P (XEXP (addr
, 1))
4107 && GET_MODE_SIZE (GET_MODE (x
)) > 1
4108 && (!(INTVAL (XEXP (addr
, 1))
4109 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
4110 /* Does it make a difference? */
4111 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
4112 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
4114 fputs (".as", file
);
4117 else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
)
4118 && GET_MODE_SIZE (GET_MODE (x
)) > 1)
4120 tree decl
= NULL_TREE
;
4122 if (GET_CODE (XEXP (addr
, 1)) == SYMBOL_REF
)
4123 decl
= SYMBOL_REF_DECL (XEXP (addr
, 1));
4124 else if (GET_CODE (XEXP (XEXP (XEXP (addr
, 1), 0), 0))
4126 decl
= SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr
, 1), 0), 0));
4128 align
= DECL_ALIGN (decl
);
4129 align
= align
/ BITS_PER_UNIT
;
4130 if ((GET_MODE_SIZE (GET_MODE (x
)) == 2)
4131 && align
&& ((align
& 1) == 0))
4132 fputs (".as", file
);
4133 if ((GET_MODE_SIZE (GET_MODE (x
)) >= 4)
4134 && align
&& ((align
& 3) == 0))
4135 fputs (".as", file
);
4141 gcc_assert (CONSTANT_P (addr
)); break;
4145 output_operand_lossage ("invalid operand to %%U code");
4148 /* Output cache bypass indicator for a load/store insn. Volatile memory
4149 refs are defined to use the cache bypass mechanism. */
4150 if (GET_CODE (x
) == MEM
)
4152 if ((MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
4153 || arc_is_uncached_mem_p (x
))
4154 fputs (".di", file
);
4157 output_operand_lossage ("invalid operand to %%V code");
4162 /* Do nothing special. */
4165 fputs (reg_names
[REGNO (x
)]+1, file
);
4168 /* This punctuation character is needed because label references are
4169 printed in the output template using %l. This is a front end
4170 character, and when we want to emit a '@' before it, we have to use
4176 /* Output an operator. */
4177 switch (GET_CODE (x
))
4179 case PLUS
: fputs ("add", file
); return;
4180 case SS_PLUS
: fputs ("adds", file
); return;
4181 case AND
: fputs ("and", file
); return;
4182 case IOR
: fputs ("or", file
); return;
4183 case XOR
: fputs ("xor", file
); return;
4184 case MINUS
: fputs ("sub", file
); return;
4185 case SS_MINUS
: fputs ("subs", file
); return;
4186 case ASHIFT
: fputs ("asl", file
); return;
4187 case ASHIFTRT
: fputs ("asr", file
); return;
4188 case LSHIFTRT
: fputs ("lsr", file
); return;
4189 case ROTATERT
: fputs ("ror", file
); return;
4190 case MULT
: fputs ("mpy", file
); return;
4191 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
4192 case NEG
: fputs ("neg", file
); return;
4193 case SS_NEG
: fputs ("negs", file
); return;
4194 case NOT
: fputs ("not", file
); return; /* Unconditional. */
4196 fputs ("ext", file
); /* bmsk allows predication. */
4198 case SIGN_EXTEND
: /* Unconditional. */
4199 fputs ("sex", file
);
4201 switch (GET_MODE (XEXP (x
, 0)))
4203 case E_QImode
: fputs ("b", file
); return;
4204 case E_HImode
: fputs ("w", file
); return;
4209 if (GET_MODE (x
) != HImode
)
4211 fputs ("sat16", file
);
4214 output_operand_lossage ("invalid operand to %%O code"); return;
4216 if (GET_CODE (x
) == SYMBOL_REF
)
4218 assemble_name (file
, XSTR (x
, 0));
4223 if (TARGET_ANNOTATE_ALIGN
&& cfun
->machine
->size_reason
)
4224 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
4240 output_operand_lossage ("invalid operand output code");
4243 switch (GET_CODE (x
))
4246 fputs (reg_names
[REGNO (x
)], file
);
4250 rtx addr
= XEXP (x
, 0);
4251 int size
= GET_MODE_SIZE (GET_MODE (x
));
4255 switch (GET_CODE (addr
))
4257 case PRE_INC
: case POST_INC
:
4258 output_address (VOIDmode
,
4259 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
4260 case PRE_DEC
: case POST_DEC
:
4261 output_address (VOIDmode
,
4262 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
4264 case PRE_MODIFY
: case POST_MODIFY
:
4265 output_address (VOIDmode
, XEXP (addr
, 1)); break;
4269 output_address (VOIDmode
,
4270 plus_constant (Pmode
, XEXP (addr
, 0),
4271 (INTVAL (XEXP (addr
, 1))
4272 >> (size
== 2 ? 1 : 2))));
4276 output_address (VOIDmode
, addr
);
4279 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
4280 arc_output_pic_addr_const (file
, addr
, code
);
4282 output_address (VOIDmode
, addr
);
4289 /* We handle SFmode constants here as output_addr_const doesn't. */
4290 if (GET_MODE (x
) == SFmode
)
4294 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
4295 fprintf (file
, "0x%08lx", l
);
4299 /* Let output_addr_const deal with it. */
4302 || (GET_CODE (x
) == CONST
4303 && GET_CODE (XEXP (x
, 0)) == UNSPEC
4304 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
4305 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
4306 || (GET_CODE (x
) == CONST
4307 && GET_CODE (XEXP (x
, 0)) == PLUS
4308 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
4309 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
4310 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
4311 arc_output_pic_addr_const (file
, x
, code
);
4314 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
4315 with asm_output_symbol_ref */
4316 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
)
4319 output_addr_const (file
, XEXP (x
, 0));
4320 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (XEXP (x
, 0)))
4321 fprintf (file
, "@sda");
4323 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
4324 || INTVAL (XEXP (x
, 1)) >= 0)
4325 fprintf (file
, "+");
4326 output_addr_const (file
, XEXP (x
, 1));
4329 output_addr_const (file
, x
);
4331 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
4332 fprintf (file
, "@sda");
4337 /* Print a memory address as an operand to reference that memory location. */
4340 arc_print_operand_address (FILE *file
, rtx addr
)
4342 register rtx base
, index
= 0;
4344 switch (GET_CODE (addr
))
4347 fputs (reg_names
[REGNO (addr
)], file
);
4350 output_addr_const (file
, addr
);
4351 if (SYMBOL_REF_SMALL_P (addr
))
4352 fprintf (file
, "@sda");
4355 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4356 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
4357 else if (CONST_INT_P (XEXP (addr
, 0)))
4358 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
4360 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
4362 gcc_assert (OBJECT_P (base
));
4363 arc_print_operand_address (file
, base
);
4364 if (CONSTANT_P (base
) && CONST_INT_P (index
))
4368 gcc_assert (OBJECT_P (index
));
4369 arc_print_operand_address (file
, index
);
4373 rtx c
= XEXP (addr
, 0);
4375 if ((GET_CODE (c
) == UNSPEC
4376 && (XINT (c
, 1) == UNSPEC_TLS_OFF
4377 || XINT (c
, 1) == UNSPEC_TLS_IE
))
4378 || (GET_CODE (c
) == PLUS
4379 && GET_CODE (XEXP (c
, 0)) == UNSPEC
4380 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
4381 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4383 arc_output_pic_addr_const (file
, c
, 0);
4386 gcc_assert (GET_CODE (c
) == PLUS
);
4387 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4388 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4390 output_address (VOIDmode
, XEXP (addr
, 0));
4396 /* We shouldn't get here as we've lost the mode of the memory object
4397 (which says how much to inc/dec by. */
4402 arc_output_pic_addr_const (file
, addr
, 0);
4404 output_addr_const (file
, addr
);
4409 /* Conditional execution support.
4411 This is based on the ARM port but for now is much simpler.
4413 A finite state machine takes care of noticing whether or not instructions
4414 can be conditionally executed, and thus decrease execution time and code
4415 size by deleting branch instructions. The fsm is controlled by
4416 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4417 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4418 insns also have a hand in this. */
4419 /* The way we leave dealing with non-anulled or annull-false delay slot
4420 insns to the consumer is awkward. */
4422 /* The state of the fsm controlling condition codes are:
4423 0: normal, do nothing special
4424 1: don't output this insn
4425 2: don't output this insn
4426 3: make insns conditional
4427 4: make insns conditional
4428 5: make insn conditional (only for outputting anulled delay slot insns)
4430 special value for cfun->machine->uid_ccfsm_state:
4431 6: return with but one insn before it since function start / call
4433 State transitions (state->state by whom, under what condition):
4434 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4436 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4437 by zero or more non-jump insns and an unconditional branch with
4438 the same target label as the condbranch.
4439 1 -> 3 branch patterns, after having not output the conditional branch
4440 2 -> 4 branch patterns, after having not output the conditional branch
4441 0 -> 5 branch patterns, for anulled delay slot insn.
4442 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4443 (the target label has CODE_LABEL_NUMBER equal to
4444 arc_ccfsm_target_label).
4445 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4446 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4447 5 -> 0 when outputting the delay slot insn
4449 If the jump clobbers the conditions then we use states 2 and 4.
4451 A similar thing can be done with conditional return insns.
4453 We also handle separating branches from sets of the condition code.
4454 This is done here because knowledge of the ccfsm state is required,
4455 we may not be outputting the branch. */
4457 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4458 before letting final output INSN. */
4461 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4463 /* BODY will hold the body of INSN. */
4466 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4467 an if/then/else), and things need to be reversed. */
4470 /* If we start with a return insn, we only succeed if we find another one. */
4471 int seeking_return
= 0;
4473 /* START_INSN will hold the insn from where we start looking. This is the
4474 first insn after the following code_label if REVERSE is true. */
4475 rtx_insn
*start_insn
= insn
;
4477 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4478 since they don't rely on a cmp preceding the. */
4479 enum attr_type jump_insn_type
;
4481 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4482 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4483 final_scan_insn which has `optimize' as a local. */
4484 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4487 /* Ignore notes and labels. */
4490 body
= PATTERN (insn
);
4491 /* If in state 4, check if the target branch is reached, in order to
4492 change back to state 0. */
4493 if (state
->state
== 4)
4495 if (insn
== state
->target_insn
)
4497 state
->target_insn
= NULL
;
4503 /* If in state 3, it is possible to repeat the trick, if this insn is an
4504 unconditional branch to a label, and immediately following this branch
4505 is the previous target label which is only used once, and the label this
4506 branch jumps to is not too far off. Or in other words "we've done the
4507 `then' part, see if we can do the `else' part." */
4508 if (state
->state
== 3)
4510 if (simplejump_p (insn
))
4512 start_insn
= next_nonnote_insn (start_insn
);
4513 if (GET_CODE (start_insn
) == BARRIER
)
4515 /* ??? Isn't this always a barrier? */
4516 start_insn
= next_nonnote_insn (start_insn
);
4518 if (GET_CODE (start_insn
) == CODE_LABEL
4519 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4520 && LABEL_NUSES (start_insn
) == 1)
4525 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4527 start_insn
= next_nonnote_insn (start_insn
);
4528 if (GET_CODE (start_insn
) == BARRIER
)
4529 start_insn
= next_nonnote_insn (start_insn
);
4530 if (GET_CODE (start_insn
) == CODE_LABEL
4531 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4532 && LABEL_NUSES (start_insn
) == 1)
4544 if (GET_CODE (insn
) != JUMP_INSN
4545 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4546 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4549 /* We can't predicate BRCC or loop ends.
4550 Also, when generating PIC code, and considering a medium range call,
4551 we can't predicate the call. */
4552 jump_insn_type
= get_attr_type (insn
);
4553 if (jump_insn_type
== TYPE_BRCC
4554 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4555 || jump_insn_type
== TYPE_LOOP_END
4556 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4559 /* This jump might be paralleled with a clobber of the condition codes,
4560 the jump should always come first. */
4561 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4562 body
= XVECEXP (body
, 0, 0);
4565 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4566 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4568 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4569 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4570 int then_not_else
= TRUE
;
4571 /* Nonzero if next insn must be the target label. */
4572 int next_must_be_target_label_p
;
4573 rtx_insn
*this_insn
= start_insn
;
4576 /* Register the insn jumped to. */
4579 if (!seeking_return
)
4580 label
= XEXP (SET_SRC (body
), 0);
4582 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4583 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4584 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4586 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4587 then_not_else
= FALSE
;
4589 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4591 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4594 then_not_else
= FALSE
;
4599 /* If this is a non-annulled branch with a delay slot, there is
4600 no need to conditionalize the delay slot. */
4601 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn
)))) == SEQUENCE
)
4602 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4604 this_insn
= NEXT_INSN (this_insn
);
4606 /* See how many insns this branch skips, and what kind of insns. If all
4607 insns are okay, and the label or unconditional branch to the same
4608 label is not too far away, succeed. */
4609 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
4610 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
4615 this_insn
= next_nonnote_insn (this_insn
);
4619 if (next_must_be_target_label_p
)
4621 if (GET_CODE (this_insn
) == BARRIER
)
4623 if (GET_CODE (this_insn
) == CODE_LABEL
4624 && this_insn
== label
)
4634 switch (GET_CODE (this_insn
))
4637 /* Succeed if it is the target label, otherwise fail since
4638 control falls in from somewhere else. */
4639 if (this_insn
== label
)
4649 /* Succeed if the following insn is the target label.
4651 If return insns are used then the last insn in a function
4652 will be a barrier. */
4653 next_must_be_target_label_p
= TRUE
;
4657 /* Can handle a call insn if there are no insns after it.
4658 IE: The next "insn" is the target label. We don't have to
4659 worry about delay slots as such insns are SEQUENCE's inside
4660 INSN's. ??? It is possible to handle such insns though. */
4661 if (get_attr_cond (this_insn
) == COND_CANUSE
)
4662 next_must_be_target_label_p
= TRUE
;
4668 scanbody
= PATTERN (this_insn
);
4670 /* If this is an unconditional branch to the same label, succeed.
4671 If it is to another label, do nothing. If it is conditional,
4673 /* ??? Probably, the test for the SET and the PC are
4676 if (GET_CODE (scanbody
) == SET
4677 && GET_CODE (SET_DEST (scanbody
)) == PC
)
4679 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
4680 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
4685 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
4687 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
4690 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
4696 else if (GET_CODE (scanbody
) == PARALLEL
)
4698 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4704 scanbody
= PATTERN (this_insn
);
4706 /* We can only do this with insns that can use the condition
4707 codes (and don't set them). */
4708 if (GET_CODE (scanbody
) == SET
4709 || GET_CODE (scanbody
) == PARALLEL
)
4711 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4714 /* We can't handle other insns like sequences. */
4726 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
4727 state
->target_label
= CODE_LABEL_NUMBER (label
);
4728 else if (seeking_return
|| state
->state
== 2)
4730 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
4732 this_insn
= next_nonnote_insn (this_insn
);
4734 gcc_assert (!this_insn
||
4735 (GET_CODE (this_insn
) != BARRIER
4736 && GET_CODE (this_insn
) != CODE_LABEL
));
4740 /* Oh dear! we ran off the end, give up. */
4741 extract_insn_cached (insn
);
4743 state
->target_insn
= NULL
;
4746 state
->target_insn
= this_insn
;
4751 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4755 state
->cond
= XEXP (SET_SRC (body
), 0);
4756 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4759 if (reverse
|| then_not_else
)
4760 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4763 /* Restore recog_operand. Getting the attributes of other insns can
4764 destroy this array, but final.c assumes that it remains intact
4765 across this call; since the insn has been recognized already we
4766 call insn_extract direct. */
4767 extract_insn_cached (insn
);
4771 /* Record that we are currently outputting label NUM with prefix PREFIX.
4772 It it's the label we're looking for, reset the ccfsm machinery.
4774 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4777 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4779 if (state
->state
== 3 && state
->target_label
== num
4780 && !strcmp (prefix
, "L"))
4783 state
->target_insn
= NULL
;
4787 /* We are considering a conditional branch with the condition COND.
4788 Check if we want to conditionalize a delay slot insn, and if so modify
4789 the ccfsm state accordingly.
4790 REVERSE says branch will branch when the condition is false. */
4792 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4793 struct arc_ccfsm
*state
)
4795 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4797 state
= &arc_ccfsm_current
;
4799 gcc_assert (state
->state
== 0);
4800 if (seq_insn
!= jump
)
4802 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4804 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4805 && INSN_ANNULLED_BRANCH_P (jump
)
4806 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4809 state
->cc
= get_arc_condition_code (cond
);
4811 arc_ccfsm_current
.cc
4812 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4813 rtx pat
= PATTERN (insn
);
4814 if (GET_CODE (pat
) == COND_EXEC
)
4815 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4816 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4817 == get_arc_condition_code (XEXP (pat
, 0)));
4824 /* Update *STATE as we would when we emit INSN. */
4827 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4829 enum attr_type type
;
4832 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4833 else if (JUMP_P (insn
)
4834 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4835 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4836 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4837 || ((type
== TYPE_UNCOND_BRANCH
4838 || type
== TYPE_RETURN
)
4839 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4841 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4842 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4845 rtx src
= SET_SRC (PATTERN (insn
));
4846 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4850 else if (arc_ccfsm_current
.state
== 5)
4851 arc_ccfsm_current
.state
= 0;
4854 /* Return true if the current insn, which is a conditional branch, is to be
4858 arc_ccfsm_branch_deleted_p (void)
4860 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4863 /* Record a branch isn't output because subsequent insns can be
4867 arc_ccfsm_record_branch_deleted (void)
4869 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4872 /* During insn output, indicate if the current insn is predicated. */
4875 arc_ccfsm_cond_exec_p (void)
4877 return (cfun
->machine
->prescan_initialized
4878 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4881 /* When deciding if an insn should be output short, we want to know something
4882 about the following insns:
4883 - if another insn follows which we know we can output as a short insn
4884 before an alignment-sensitive point, we can output this insn short:
4885 the decision about the eventual alignment can be postponed.
4886 - if a to-be-aligned label comes next, we should output this insn such
4887 as to get / preserve 4-byte alignment.
4888 - if a likely branch without delay slot insn, or a call with an immediately
4889 following short insn comes next, we should out output this insn such as to
4890 get / preserve 2 mod 4 unalignment.
4891 - do the same for a not completely unlikely branch with a short insn
4892 following before any other branch / label.
4893 - in order to decide if we are actually looking at a branch, we need to
4894 call arc_ccfsm_advance.
4895 - in order to decide if we are looking at a short insn, we should know
4896 if it is conditionalized. To a first order of approximation this is
4897 the case if the state from arc_ccfsm_advance from before this insn
4898 indicates the insn is conditionalized. However, a further refinement
4899 could be to not conditionalize an insn if the destination register(s)
4900 is/are dead in the non-executed case. */
4901 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4902 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4903 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4906 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4908 enum attr_iscompact iscompact
;
4909 struct machine_function
*machine
;
4913 iscompact
= get_attr_iscompact (insn
);
4914 if (iscompact
== ISCOMPACT_FALSE
)
4917 machine
= cfun
->machine
;
4919 if (machine
->force_short_suffix
>= 0)
4920 return machine
->force_short_suffix
;
4922 return (get_attr_length (insn
) & 2) != 0;
4925 /* When outputting an instruction (alternative) that can potentially be short,
4926 output the short suffix if the insn is in fact short, and update
4927 cfun->machine->unalign accordingly. */
4930 output_short_suffix (FILE *file
)
4932 rtx_insn
*insn
= current_output_insn
;
4934 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
4936 fprintf (file
, "_s");
4937 cfun
->machine
->unalign
^= 2;
4939 /* Restore recog_operand. */
4940 extract_insn_cached (insn
);
4943 /* Implement FINAL_PRESCAN_INSN. */
4946 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
4947 int noperands ATTRIBUTE_UNUSED
)
4949 if (TARGET_DUMPISIZE
)
4950 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
4952 if (!cfun
->machine
->prescan_initialized
)
4954 /* Clear lingering state from branch shortening. */
4955 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
4956 cfun
->machine
->prescan_initialized
= 1;
4958 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
4960 cfun
->machine
->size_reason
= 0;
4963 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4964 Frame pointer elimination is automatically handled.
4966 All eliminations are permissible. If we need a frame
4967 pointer, we must eliminate ARG_POINTER_REGNUM into
4968 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4971 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4973 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
4976 /* Define the offset between two registers, one to be eliminated, and
4977 the other its replacement, at the start of a routine. */
4980 arc_initial_elimination_offset (int from
, int to
)
4982 if (!cfun
->machine
->frame_info
.initialized
)
4983 arc_compute_frame_size ();
4985 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
4987 return (cfun
->machine
->frame_info
.extra_size
4988 + cfun
->machine
->frame_info
.reg_size
);
4991 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
4993 return (cfun
->machine
->frame_info
.total_size
4994 - cfun
->machine
->frame_info
.pretend_size
);
4997 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
4999 return (cfun
->machine
->frame_info
.total_size
5000 - (cfun
->machine
->frame_info
.pretend_size
5001 + cfun
->machine
->frame_info
.extra_size
5002 + cfun
->machine
->frame_info
.reg_size
));
5009 arc_frame_pointer_required (void)
5011 return cfun
->calls_alloca
|| crtl
->calls_eh_return
;
5015 /* Return the destination address of a branch. */
5018 branch_dest (rtx branch
)
5020 rtx pat
= PATTERN (branch
);
5021 rtx dest
= (GET_CODE (pat
) == PARALLEL
5022 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
5025 if (GET_CODE (dest
) == IF_THEN_ELSE
)
5026 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
5028 dest
= XEXP (dest
, 0);
5029 dest_uid
= INSN_UID (dest
);
5031 return INSN_ADDRESSES (dest_uid
);
5035 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5038 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
5040 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5041 This clears machine specific flags, so has to come first. */
5042 default_encode_section_info (decl
, rtl
, first
);
5044 /* Check if it is a function, and whether it has the
5045 [long/medium/short]_call attribute specified. */
5046 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5048 rtx symbol
= XEXP (rtl
, 0);
5049 int flags
= SYMBOL_REF_FLAGS (symbol
);
5051 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5052 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
5053 tree long_call_attr
= lookup_attribute ("long_call", attr
);
5054 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
5055 tree short_call_attr
= lookup_attribute ("short_call", attr
);
5057 if (long_call_attr
!= NULL_TREE
)
5058 flags
|= SYMBOL_FLAG_LONG_CALL
;
5059 else if (medium_call_attr
!= NULL_TREE
)
5060 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
5061 else if (short_call_attr
!= NULL_TREE
)
5062 flags
|= SYMBOL_FLAG_SHORT_CALL
;
5064 SYMBOL_REF_FLAGS (symbol
) = flags
;
5066 else if (TREE_CODE (decl
) == VAR_DECL
)
5068 rtx symbol
= XEXP (rtl
, 0);
5070 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5071 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
5073 tree sec_attr
= lookup_attribute ("section", attr
);
5076 const char *sec_name
5077 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
5078 if (strcmp (sec_name
, ".cmem") == 0
5079 || strcmp (sec_name
, ".cmem_shared") == 0
5080 || strcmp (sec_name
, ".cmem_private") == 0)
5081 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
5086 /* This is how to output a definition of an internal numbered label where
5087 PREFIX is the class of label and NUM is the number within the class. */
5089 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
5092 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
5093 default_internal_label (stream
, prefix
, labelno
);
5096 /* Set the cpu type and print out other fancy things,
5097 at the top of the file. */
5099 static void arc_file_start (void)
5101 default_file_start ();
5102 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
5104 /* Set some want to have build attributes. */
5105 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5107 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5108 TARGET_RF16
? 1 : 0);
5109 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5111 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5112 (arc_tp_regno
!= -1) ? 1 : 0);
5113 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5114 TARGET_NO_SDATA_SET
? 0 : 2);
5115 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5116 TARGET_OPTFPE
? 1 : 0);
5118 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5119 arc_tune
== ARC_TUNE_CORE_3
? 3 : 2);
5122 /* Implement `TARGET_ASM_FILE_END'. */
5123 /* Outputs to the stdio stream FILE jli related text. */
5125 void arc_file_end (void)
5127 arc_jli_section
*sec
= arc_jli_sections
;
5131 fprintf (asm_out_file
, "\n");
5132 fprintf (asm_out_file
, "# JLI entry for function ");
5133 assemble_name (asm_out_file
, sec
->name
);
5134 fprintf (asm_out_file
, "\n\t.section .jlitab, \"axG\", @progbits, "
5136 assemble_name (asm_out_file
, sec
->name
);
5137 fprintf (asm_out_file
,", comdat\n");
5139 fprintf (asm_out_file
, "\t.align\t4\n");
5140 fprintf (asm_out_file
, "__jli.");
5141 assemble_name (asm_out_file
, sec
->name
);
5142 fprintf (asm_out_file
, ":\n\t.weak __jli.");
5143 assemble_name (asm_out_file
, sec
->name
);
5144 fprintf (asm_out_file
, "\n\tb\t@");
5145 assemble_name (asm_out_file
, sec
->name
);
5146 fprintf (asm_out_file
, "\n");
5149 file_end_indicate_exec_stack ();
5152 /* Cost functions. */
5154 /* Compute a (partial) cost for rtx X. Return true if the complete
5155 cost has been computed, and false if subexpressions should be
5156 scanned. In either case, *TOTAL contains the cost result. */
5159 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
5160 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
5162 int code
= GET_CODE (x
);
5166 /* Small integers are as cheap as registers. */
5169 bool nolimm
= false; /* Can we do without long immediate? */
5170 bool fast
= false; /* Is the result available immediately? */
5171 bool condexec
= false; /* Does this allow conditiobnal execution? */
5172 bool compact
= false; /* Is a 16 bit opcode available? */
5173 /* CONDEXEC also implies that we can have an unconditional
5174 3-address operation. */
5176 nolimm
= compact
= condexec
= false;
5177 if (UNSIGNED_INT6 (INTVAL (x
)))
5178 nolimm
= condexec
= compact
= true;
5181 if (SMALL_INT (INTVAL (x
)))
5182 nolimm
= fast
= true;
5185 case AND
: /* bclr, bmsk, ext[bw] */
5186 if (satisfies_constraint_Ccp (x
) /* bclr */
5187 || satisfies_constraint_C1p (x
) /* bmsk */)
5188 nolimm
= fast
= condexec
= compact
= true;
5190 case IOR
: /* bset */
5191 if (satisfies_constraint_C0p (x
)) /* bset */
5192 nolimm
= fast
= condexec
= compact
= true;
5195 if (satisfies_constraint_C0p (x
)) /* bxor */
5196 nolimm
= fast
= condexec
= true;
5199 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
5205 /* FIXME: Add target options to attach a small cost if
5206 condexec / compact is not true. */
5215 /* 4 byte values can be fetched as immediate constants -
5216 let's give that the cost of an extra insn. */
5220 *total
= COSTS_N_INSNS (1);
5229 *total
= COSTS_N_INSNS (1);
5232 split_double (x
, &first
, &second
);
5233 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
5234 + !SMALL_INT (INTVAL (second
)));
5238 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5239 If we need more than 12 insns to do a multiply, then go out-of-line,
5240 since the call overhead will be < 10% of the cost of the multiply. */
5244 if (TARGET_BARREL_SHIFTER
)
5246 /* If we want to shift a constant, we need a LIMM. */
5247 /* ??? when the optimizers want to know if a constant should be
5248 hoisted, they ask for the cost of the constant. OUTER_CODE is
5249 insufficient context for shifts since we don't know which operand
5250 we are looking at. */
5251 if (CONSTANT_P (XEXP (x
, 0)))
5253 *total
+= (COSTS_N_INSNS (2)
5254 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
5258 *total
= COSTS_N_INSNS (1);
5260 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5261 *total
= COSTS_N_INSNS (16);
5264 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
5265 /* ??? want_to_gcse_p can throw negative shift counts at us,
5266 and then panics when it gets a negative cost as result.
5267 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5276 *total
= COSTS_N_INSNS(30);
5278 *total
= COSTS_N_INSNS(1);
5282 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
5283 *total
= COSTS_N_INSNS (1);
5285 *total
= arc_multcost
;
5286 /* We do not want synth_mult sequences when optimizing
5288 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
5289 *total
= COSTS_N_INSNS (1);
5291 *total
= COSTS_N_INSNS (2);
5294 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
5295 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
5296 || (GET_CODE (XEXP (x
, 0)) == MULT
5297 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
5299 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
5300 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
5305 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
5306 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
5307 || (GET_CODE (XEXP (x
, 1)) == MULT
5308 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
5310 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
5311 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
5317 rtx op0
= XEXP (x
, 0);
5318 rtx op1
= XEXP (x
, 1);
5320 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
5321 && XEXP (op0
, 1) == const1_rtx
)
5323 /* btst / bbit0 / bbit1:
5324 Small integers and registers are free; everything else can
5325 be put in a register. */
5326 mode
= GET_MODE (XEXP (op0
, 0));
5327 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5328 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5331 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5332 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5335 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5339 if (GET_CODE (op1
) == NEG
)
5341 /* op0 might be constant, the inside of op1 is rather
5342 unlikely to be so. So swapping the operands might lower
5344 mode
= GET_MODE (op0
);
5345 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5346 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5351 if (outer_code
== IF_THEN_ELSE
5352 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5353 && XEXP (x
, 1) == const0_rtx
5354 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5356 /* btst / bbit0 / bbit1:
5357 Small integers and registers are free; everything else can
5358 be put in a register. */
5359 rtx op0
= XEXP (x
, 0);
5361 mode
= GET_MODE (XEXP (op0
, 0));
5362 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5363 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5367 /* scc_insn expands into two insns. */
5368 case GTU
: case GEU
: case LEU
:
5370 *total
+= COSTS_N_INSNS (1);
5372 case LTU
: /* might use adc. */
5374 *total
+= COSTS_N_INSNS (1) - 1;
5381 /* Return true if ADDR is a valid pic address.
5382 A valid pic address on arc should look like
5383 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5386 arc_legitimate_pic_addr_p (rtx addr
)
5388 if (GET_CODE (addr
) != CONST
)
5391 addr
= XEXP (addr
, 0);
5394 if (GET_CODE (addr
) == PLUS
)
5396 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5398 addr
= XEXP (addr
, 0);
5401 if (GET_CODE (addr
) != UNSPEC
5402 || XVECLEN (addr
, 0) != 1)
5405 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5406 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5407 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5408 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5409 && XINT (addr
, 1) != UNSPEC_TLS_GD
5410 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5413 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5414 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5422 /* Return true if OP contains a symbol reference. */
5425 symbolic_reference_mentioned_p (rtx op
)
5427 register const char *fmt
;
5430 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5433 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5434 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5440 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5441 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5445 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5452 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5453 If SKIP_LOCAL is true, skip symbols that bind locally.
5454 This is used further down in this file, and, without SKIP_LOCAL,
5455 in the addsi3 / subsi3 expanders when generating PIC code. */
5458 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5460 register const char *fmt
;
5463 if (GET_CODE(op
) == UNSPEC
)
5466 if (GET_CODE (op
) == SYMBOL_REF
)
5468 if (SYMBOL_REF_TLS_MODEL (op
))
5472 tree decl
= SYMBOL_REF_DECL (op
);
5473 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5476 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5477 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5483 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5484 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5489 else if (fmt
[i
] == 'e'
5490 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5498 /* Get the thread pointer. */
5503 /* If arc_tp_regno has been set, we can use that hard register
5504 directly as a base register. */
5505 if (arc_tp_regno
!= -1)
5506 return gen_rtx_REG (Pmode
, arc_tp_regno
);
5508 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5509 conflicts with function arguments / results. */
5510 rtx reg
= gen_reg_rtx (Pmode
);
5511 emit_insn (gen_tls_load_tp_soft ());
5512 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
5516 /* Helper to be used by TLS Global dynamic model. */
5519 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
5521 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
5522 rtx call_fusage
= NULL_RTX
;
5526 rtx x
= arc_unspec_offset (sym
, reloc
);
5527 emit_move_insn (r0
, x
);
5528 use_reg (&call_fusage
, r0
);
5530 gcc_assert (reloc
== UNSPEC_TLS_GD
);
5531 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
5532 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5533 way that the application should care. */
5534 RTL_PURE_CALL_P (call_insn
) = 1;
5535 add_function_usage_to (call_insn
, call_fusage
);
5537 rtx_insn
*insns
= get_insns ();
5540 rtx dest
= gen_reg_rtx (Pmode
);
5541 emit_libcall_block (insns
, dest
, r0
, eqv
);
5545 #define DTPOFF_ZERO_SYM ".tdata"
5547 /* Return a legitimized address for ADDR,
5548 which is a SYMBOL_REF with tls_model MODEL. */
5551 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5553 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5554 model
= TLS_MODEL_LOCAL_EXEC
;
5558 case TLS_MODEL_LOCAL_DYNAMIC
:
5561 const char *base_name
;
5564 decl
= SYMBOL_REF_DECL (addr
);
5565 base_name
= DTPOFF_ZERO_SYM
;
5566 if (decl
&& bss_initializer_p (decl
))
5567 base_name
= ".tbss";
5569 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5570 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
5574 v
= gen_rtvec (1, addr
);
5577 v
= gen_rtvec (2, addr
, base
);
5578 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
5579 addr
= gen_rtx_CONST (Pmode
, addr
);
5580 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
5581 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
5583 case TLS_MODEL_GLOBAL_DYNAMIC
:
5584 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
5586 case TLS_MODEL_INITIAL_EXEC
:
5587 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5588 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5589 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5591 case TLS_MODEL_LOCAL_EXEC
:
5593 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5594 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5600 /* Legitimize a pic address reference in ORIG.
5601 The return value is the legitimated address.
5602 If OLDX is non-zero, it is the target to assign the address to first. */
5605 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5614 if (GET_CODE (addr
) == LABEL_REF
)
5616 else if (GET_CODE (addr
) == SYMBOL_REF
)
5618 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5620 return arc_legitimize_tls_address (addr
, model
);
5623 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5624 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5626 /* This symbol must be referenced via a load from the Global
5627 Offset Table (@GOTPC). */
5628 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5629 pat
= gen_const_mem (Pmode
, pat
);
5632 oldx
= gen_reg_rtx (Pmode
);
5634 emit_move_insn (oldx
, pat
);
5639 if (GET_CODE (addr
) == CONST
)
5641 addr
= XEXP (addr
, 0);
5642 if (GET_CODE (addr
) == UNSPEC
)
5644 /* Check that the unspec is one of the ones we generate? */
5647 /* fwprop is placing in the REG_EQUIV notes constant pic
5648 unspecs expressions. Then, loop may use these notes for
5649 optimizations resulting in complex patterns that are not
5650 supported by the current implementation. The following
5651 two if-cases are simplifying the complex patters to
5653 else if (GET_CODE (addr
) == MINUS
)
5655 rtx op0
= XEXP (addr
, 0);
5656 rtx op1
= XEXP (addr
, 1);
5658 gcc_assert (GET_CODE (op1
) == UNSPEC
);
5660 emit_move_insn (oldx
,
5661 gen_rtx_CONST (SImode
,
5662 arc_legitimize_pic_address (op1
,
5664 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
5668 else if (GET_CODE (addr
) != PLUS
)
5670 rtx tmp
= XEXP (addr
, 0);
5671 enum rtx_code code
= GET_CODE (addr
);
5673 /* It only works for UNARY operations. */
5674 gcc_assert (UNARY_P (addr
));
5675 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
5680 gen_rtx_CONST (SImode
,
5681 arc_legitimize_pic_address (tmp
,
5684 emit_insn (gen_rtx_SET (oldx
,
5685 gen_rtx_fmt_ee (code
, SImode
,
5686 oldx
, const0_rtx
)));
5692 gcc_assert (GET_CODE (addr
) == PLUS
);
5693 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
5698 if (GET_CODE (addr
) == PLUS
)
5700 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
5702 base
= arc_legitimize_pic_address (op0
, oldx
);
5703 pat
= arc_legitimize_pic_address (op1
,
5704 base
== oldx
? NULL_RTX
: oldx
);
5706 if (base
== op0
&& pat
== op1
)
5709 if (GET_CODE (pat
) == CONST_INT
)
5710 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
5713 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
5715 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
5716 pat
= XEXP (pat
, 1);
5718 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
5726 /* Output address constant X to FILE, taking PIC into account. */
5729 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5734 switch (GET_CODE (x
))
5744 output_addr_const (file
, x
);
5746 /* Local functions do not get references through the PLT. */
5747 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5748 fputs ("@plt", file
);
5752 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5753 assemble_name (file
, buf
);
5757 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5758 assemble_name (file
, buf
);
5762 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5766 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5770 if (GET_MODE (x
) == VOIDmode
)
5772 /* We can use %d if the number is one word and positive. */
5773 if (CONST_DOUBLE_HIGH (x
))
5774 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5775 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5776 else if (CONST_DOUBLE_LOW (x
) < 0)
5777 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5779 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5782 /* We can't handle floating point constants;
5783 PRINT_OPERAND must handle them. */
5784 output_operand_lossage ("floating constant misused");
5788 /* FIXME: Not needed here. */
5789 /* Some assemblers need integer constants to appear last (eg masm). */
5790 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5792 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5793 fprintf (file
, "+");
5794 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5796 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5798 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5799 if (INTVAL (XEXP (x
, 1)) >= 0)
5800 fprintf (file
, "+");
5801 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5808 /* Avoid outputting things like x-x or x+5-x,
5809 since some assemblers can't handle that. */
5810 x
= simplify_subtraction (x
);
5811 if (GET_CODE (x
) != MINUS
)
5814 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5815 fprintf (file
, "-");
5816 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5817 && INTVAL (XEXP (x
, 1)) < 0)
5819 fprintf (file
, "(");
5820 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5821 fprintf (file
, ")");
5824 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5829 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5835 bool pcrel
; pcrel
= false;
5836 rtx base
; base
= NULL
;
5837 gcc_assert (XVECLEN (x
, 0) >= 1);
5838 switch (XINT (x
, 1))
5840 case ARC_UNSPEC_GOT
:
5841 suffix
= "@gotpc", pcrel
= true;
5843 case ARC_UNSPEC_GOTOFF
:
5846 case ARC_UNSPEC_GOTOFFPC
:
5847 suffix
= "@pcl", pcrel
= true;
5849 case ARC_UNSPEC_PLT
:
5853 suffix
= "@tlsgd", pcrel
= true;
5856 suffix
= "@tlsie", pcrel
= true;
5858 case UNSPEC_TLS_OFF
:
5859 if (XVECLEN (x
, 0) == 2)
5860 base
= XVECEXP (x
, 0, 1);
5861 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5862 || (!flag_pic
&& !base
))
5868 suffix
= "@invalid";
5869 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5873 fputs ("pcl,", file
);
5874 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5875 fputs (suffix
, file
);
5877 arc_output_pic_addr_const (file
, base
, code
);
5881 output_operand_lossage ("invalid expression as operand");
5885 #define SYMBOLIC_CONST(X) \
5886 (GET_CODE (X) == SYMBOL_REF \
5887 || GET_CODE (X) == LABEL_REF \
5888 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5890 /* Emit insns to move operands[1] into operands[0]. */
5893 prepare_pic_move (rtx
*operands
, machine_mode
)
5895 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5897 operands
[1] = force_reg (Pmode
, operands
[1]);
5900 rtx temp
= (reload_in_progress
? operands
[0]
5901 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5902 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5907 /* The function returning the number of words, at the beginning of an
5908 argument, must be put in registers. The returned value must be
5909 zero for arguments that are passed entirely in registers or that
5910 are entirely pushed on the stack.
5912 On some machines, certain arguments must be passed partially in
5913 registers and partially in memory. On these machines, typically
5914 the first N words of arguments are passed in registers, and the
5915 rest on the stack. If a multi-word argument (a `double' or a
5916 structure) crosses that boundary, its first few words must be
5917 passed in registers and the rest must be pushed. This function
5918 tells the compiler when this occurs, and how many of the words
5919 should go in registers.
5921 `FUNCTION_ARG' for these arguments should return the first register
5922 to be used by the caller for this argument; likewise
5923 `FUNCTION_INCOMING_ARG', for the called function.
5925 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5927 /* If REGNO is the least arg reg available then what is the total number of arg
5929 #define GPR_REST_ARG_REGS(REGNO) \
5930 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5932 /* Since arc parm regs are contiguous. */
5933 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5935 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5938 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
5939 tree type
, bool named ATTRIBUTE_UNUSED
)
5941 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5942 int bytes
= (mode
== BLKmode
5943 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5944 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5948 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5949 ret
= GPR_REST_ARG_REGS (arg_num
);
5951 /* ICEd at function.c:2361, and ret is copied to data->partial */
5952 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
5957 /* This function is used to control a function argument is passed in a
5958 register, and which register.
5960 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5961 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5962 all of the previous arguments so far passed in registers; MODE, the
5963 machine mode of the argument; TYPE, the data type of the argument
5964 as a tree node or 0 if that is not known (which happens for C
5965 support library functions); and NAMED, which is 1 for an ordinary
5966 argument and 0 for nameless arguments that correspond to `...' in
5967 the called function's prototype.
5969 The returned value should either be a `reg' RTX for the hard
5970 register in which to pass the argument, or zero to pass the
5971 argument on the stack.
5973 For machines like the Vax and 68000, where normally all arguments
5974 are pushed, zero suffices as a definition.
5976 The usual way to make the ANSI library `stdarg.h' work on a machine
5977 where some arguments are usually passed in registers, is to cause
5978 nameless arguments to be passed on the stack instead. This is done
5979 by making the function return 0 whenever NAMED is 0.
5981 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5982 definition of this function to determine if this argument is of a
5983 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5984 is not defined and the function returns non-zero for such an
5985 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5986 defined, the argument will be computed in the stack and then loaded
5989 The function is used to implement macro FUNCTION_ARG. */
5990 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5991 and the rest are pushed. */
5994 arc_function_arg (cumulative_args_t cum_v
,
5996 const_tree type ATTRIBUTE_UNUSED
,
5997 bool named ATTRIBUTE_UNUSED
)
5999 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6002 const char *debstr ATTRIBUTE_UNUSED
;
6004 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
6005 /* Return a marker for use in the call instruction. */
6006 if (mode
== VOIDmode
)
6011 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
6013 ret
= gen_rtx_REG (mode
, arg_num
);
6014 debstr
= reg_names
[arg_num
];
6024 /* The function to update the summarizer variable *CUM to advance past
6025 an argument in the argument list. The values MODE, TYPE and NAMED
6026 describe that argument. Once this is done, the variable *CUM is
6027 suitable for analyzing the *following* argument with
6028 `FUNCTION_ARG', etc.
6030 This function need not do anything if the argument in question was
6031 passed on the stack. The compiler knows how to track the amount of
6032 stack space used for arguments without any special help.
6034 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
6035 /* For the ARC: the cum set here is passed on to function_arg where we
6036 look at its value and say which reg to use. Strategy: advance the
6037 regnumber here till we run out of arg regs, then set *cum to last
6038 reg. In function_arg, since *cum > last arg reg we would return 0
6039 and thus the arg will end up on the stack. For straddling args of
6040 course function_arg_partial_nregs will come into play. */
6043 arc_function_arg_advance (cumulative_args_t cum_v
,
6046 bool named ATTRIBUTE_UNUSED
)
6048 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6049 int bytes
= (mode
== BLKmode
6050 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
6051 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6055 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
6056 for (i
= 0; i
< words
; i
++)
6057 *cum
= ARC_NEXT_ARG_REG (*cum
);
6061 /* Define how to find the value returned by a function.
6062 VALTYPE is the data type of the value (as a tree).
6063 If the precise function being called is known, FN_DECL_OR_TYPE is its
6064 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6067 arc_function_value (const_tree valtype
,
6068 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
6069 bool outgoing ATTRIBUTE_UNUSED
)
6071 machine_mode mode
= TYPE_MODE (valtype
);
6072 int unsignedp ATTRIBUTE_UNUSED
;
6074 unsignedp
= TYPE_UNSIGNED (valtype
);
6075 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
6076 PROMOTE_MODE (mode
, unsignedp
, valtype
);
6077 return gen_rtx_REG (mode
, 0);
6080 /* Returns the return address that is used by builtin_return_address. */
6083 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
6088 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6091 /* Determine if a given RTX is a valid constant. We already know this
6092 satisfies CONSTANT_P. */
6095 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
6097 switch (GET_CODE (x
))
6102 if (arc_legitimate_pic_addr_p (x
))
6105 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6108 if (SYMBOL_REF_TLS_MODEL (x
))
6120 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6125 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6126 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
6135 return TARGET_PLUS_DMPY
;
6138 return TARGET_PLUS_QMACW
;
6144 switch (XINT (x
, 1))
6147 case UNSPEC_TLS_OFF
:
6151 /* Any other unspec ending here are pic related, hence the above
6152 constant pic address checking returned false. */
6158 fatal_insn ("unrecognized supposed constant", x
);
6165 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
6167 if (RTX_OK_FOR_BASE_P (x
, strict
))
6169 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
6171 if (legitimate_scaled_address_p (mode
, x
, strict
))
6173 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x
))
6175 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
6178 /* When we compile for size avoid const (@sym + offset)
6180 if (!flag_pic
&& optimize_size
&& !reload_completed
6181 && (GET_CODE (x
) == CONST
)
6182 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
6183 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
6184 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
6185 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
6187 rtx addend
= XEXP (XEXP (x
, 0), 1);
6188 gcc_assert (CONST_INT_P (addend
));
6189 HOST_WIDE_INT offset
= INTVAL (addend
);
6191 /* Allow addresses having a large offset to pass. Anyhow they
6192 will end in a limm. */
6193 return !(offset
> -1024 && offset
< 1020);
6196 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
6198 return arc_legitimate_constant_p (mode
, x
);
6200 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
6201 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
6202 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
6204 /* We're restricted here by the `st' insn. */
6205 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
6206 && GET_CODE (XEXP ((x
), 1)) == PLUS
6207 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
6208 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
6209 TARGET_AUTO_MODIFY_REG
, strict
))
6214 /* Return true iff ADDR (a legitimate address expression)
6215 has an effect that depends on the machine mode it is used for. */
6218 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
6220 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6221 which is valid for loads and stores, or a limm offset, which is valid for
6222 loads. Scaled indices are scaled by the access mode. */
6223 if (GET_CODE (addr
) == PLUS
6224 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
6229 /* Determine if it's legal to put X into the constant pool. */
6232 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
6234 return !arc_legitimate_constant_p (mode
, x
);
6237 /* IDs for all the ARC builtins. */
6241 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6242 ARC_BUILTIN_ ## NAME,
6243 #include "builtins.def"
6249 struct GTY(()) arc_builtin_description
6251 enum insn_code icode
;
6256 static GTY(()) struct arc_builtin_description
6257 arc_bdesc
[ARC_BUILTIN_COUNT
] =
6259 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6260 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6261 #include "builtins.def"
6265 /* Transform UP into lowercase and write the result to LO.
6266 You must provide enough space for LO. Return LO. */
6269 arc_tolower (char *lo
, const char *up
)
6273 for (; *up
; up
++, lo
++)
6274 *lo
= TOLOWER (*up
);
6281 /* Implement `TARGET_BUILTIN_DECL'. */
6284 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6286 if (id
< ARC_BUILTIN_COUNT
)
6287 return arc_bdesc
[id
].fndecl
;
6289 return error_mark_node
;
6293 arc_init_builtins (void)
6295 tree V4HI_type_node
;
6296 tree V2SI_type_node
;
6297 tree V2HI_type_node
;
6299 /* Vector types based on HS SIMD elements. */
6300 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6301 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6302 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6304 tree pcvoid_type_node
6305 = build_pointer_type (build_qualified_type (void_type_node
,
6307 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6310 tree void_ftype_void
6311 = build_function_type_list (void_type_node
, NULL_TREE
);
6313 = build_function_type_list (integer_type_node
, integer_type_node
,
6315 tree int_ftype_pcvoid_int
6316 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6317 integer_type_node
, NULL_TREE
);
6318 tree void_ftype_usint_usint
6319 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6320 long_unsigned_type_node
, NULL_TREE
);
6321 tree int_ftype_int_int
6322 = build_function_type_list (integer_type_node
, integer_type_node
,
6323 integer_type_node
, NULL_TREE
);
6324 tree usint_ftype_usint
6325 = build_function_type_list (long_unsigned_type_node
,
6326 long_unsigned_type_node
, NULL_TREE
);
6327 tree void_ftype_usint
6328 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6331 = build_function_type_list (integer_type_node
, void_type_node
,
6334 = build_function_type_list (void_type_node
, integer_type_node
,
6336 tree int_ftype_short
6337 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6340 /* Old ARC SIMD types. */
6341 tree v8hi_ftype_v8hi_v8hi
6342 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6343 V8HI_type_node
, NULL_TREE
);
6344 tree v8hi_ftype_v8hi_int
6345 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6346 integer_type_node
, NULL_TREE
);
6347 tree v8hi_ftype_v8hi_int_int
6348 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6349 integer_type_node
, integer_type_node
,
6351 tree void_ftype_v8hi_int_int
6352 = build_function_type_list (void_type_node
, V8HI_type_node
,
6353 integer_type_node
, integer_type_node
,
6355 tree void_ftype_v8hi_int_int_int
6356 = build_function_type_list (void_type_node
, V8HI_type_node
,
6357 integer_type_node
, integer_type_node
,
6358 integer_type_node
, NULL_TREE
);
6359 tree v8hi_ftype_int_int
6360 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6361 integer_type_node
, NULL_TREE
);
6362 tree void_ftype_int_int
6363 = build_function_type_list (void_type_node
, integer_type_node
,
6364 integer_type_node
, NULL_TREE
);
6365 tree v8hi_ftype_v8hi
6366 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6368 /* ARCv2 SIMD types. */
6369 tree long_ftype_v4hi_v4hi
6370 = build_function_type_list (long_long_integer_type_node
,
6371 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6372 tree int_ftype_v2hi_v2hi
6373 = build_function_type_list (integer_type_node
,
6374 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6375 tree v2si_ftype_v2hi_v2hi
6376 = build_function_type_list (V2SI_type_node
,
6377 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6378 tree v2hi_ftype_v2hi_v2hi
6379 = build_function_type_list (V2HI_type_node
,
6380 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6381 tree v2si_ftype_v2si_v2si
6382 = build_function_type_list (V2SI_type_node
,
6383 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6384 tree v4hi_ftype_v4hi_v4hi
6385 = build_function_type_list (V4HI_type_node
,
6386 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6387 tree long_ftype_v2si_v2hi
6388 = build_function_type_list (long_long_integer_type_node
,
6389 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6391 /* Add the builtins. */
6392 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6394 int id = ARC_BUILTIN_ ## NAME; \
6395 const char *Name = "__builtin_arc_" #NAME; \
6396 char *name = (char*) alloca (1 + strlen (Name)); \
6398 gcc_assert (id < ARC_BUILTIN_COUNT); \
6400 arc_bdesc[id].fndecl \
6401 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6402 BUILT_IN_MD, NULL, NULL_TREE); \
6404 #include "builtins.def"
6408 /* Helper to expand __builtin_arc_aligned (void* val, int
6412 arc_expand_builtin_aligned (tree exp
)
6414 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6415 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6417 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6418 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6420 if (!CONST_INT_P (op1
))
6422 /* If we can't fold the alignment to a constant integer
6423 whilst optimizing, this is probably a user error. */
6425 warning (0, "__builtin_arc_aligned with non-constant alignment");
6429 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6430 /* Check alignTest is positive, and a power of two. */
6431 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6433 error ("invalid alignment value for __builtin_arc_aligned");
6437 if (CONST_INT_P (op0
))
6439 HOST_WIDE_INT pnt
= INTVAL (op0
);
6441 if ((pnt
& (alignTest
- 1)) == 0)
6446 unsigned align
= get_pointer_alignment (arg0
);
6447 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6449 if (align
&& align
>= numBits
)
6451 /* Another attempt to ascertain alignment. Check the type
6452 we are pointing to. */
6453 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6454 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6459 /* Default to false. */
6463 /* Helper arc_expand_builtin, generates a pattern for the given icode
6467 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6469 switch (insn_data
[icode
].n_generator_args
)
6472 return GEN_FCN (icode
) ();
6474 return GEN_FCN (icode
) (arg
[0]);
6476 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6478 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6480 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6482 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6488 /* Expand an expression EXP that calls a built-in function,
6489 with result going to TARGET if that's convenient
6490 (and in mode MODE if that's convenient).
6491 SUBTARGET may be used as the target for computing one of EXP's operands.
6492 IGNORE is nonzero if the value is to be ignored. */
6495 arc_expand_builtin (tree exp
,
6497 rtx subtarget ATTRIBUTE_UNUSED
,
6498 machine_mode mode ATTRIBUTE_UNUSED
,
6499 int ignore ATTRIBUTE_UNUSED
)
6501 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6502 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6503 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6504 int i
, j
, n_args
= call_expr_nargs (exp
);
6507 enum insn_code icode
= d
->icode
;
6508 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6525 if (id
>= ARC_BUILTIN_COUNT
)
6526 internal_error ("bad builtin fcode");
6528 /* 1st part: Expand special builtins. */
6531 case ARC_BUILTIN_NOP
:
6532 emit_insn (gen_nopv ());
6535 case ARC_BUILTIN_RTIE
:
6536 case ARC_BUILTIN_SYNC
:
6537 case ARC_BUILTIN_BRK
:
6538 case ARC_BUILTIN_SWI
:
6539 case ARC_BUILTIN_UNIMP_S
:
6540 gcc_assert (icode
!= 0);
6541 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6544 case ARC_BUILTIN_ALIGNED
:
6545 return arc_expand_builtin_aligned (exp
);
6547 case ARC_BUILTIN_CLRI
:
6548 target
= gen_reg_rtx (SImode
);
6549 emit_insn (gen_clri (target
, const1_rtx
));
6552 case ARC_BUILTIN_TRAP_S
:
6553 case ARC_BUILTIN_SLEEP
:
6554 arg0
= CALL_EXPR_ARG (exp
, 0);
6556 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6558 if (!CONST_INT_P (op0
) || !satisfies_constraint_L (op0
))
6560 error ("builtin operand should be an unsigned 6-bit value");
6563 gcc_assert (icode
!= 0);
6564 emit_insn (GEN_FCN (icode
) (op0
));
6567 case ARC_BUILTIN_VDORUN
:
6568 case ARC_BUILTIN_VDIRUN
:
6569 arg0
= CALL_EXPR_ARG (exp
, 0);
6570 arg1
= CALL_EXPR_ARG (exp
, 1);
6571 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6572 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6574 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6576 mode0
= insn_data
[icode
].operand
[1].mode
;
6577 mode1
= insn_data
[icode
].operand
[2].mode
;
6579 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6580 op0
= copy_to_mode_reg (mode0
, op0
);
6582 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6583 op1
= copy_to_mode_reg (mode1
, op1
);
6585 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6592 case ARC_BUILTIN_VDIWR
:
6593 case ARC_BUILTIN_VDOWR
:
6594 arg0
= CALL_EXPR_ARG (exp
, 0);
6595 arg1
= CALL_EXPR_ARG (exp
, 1);
6596 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6597 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6599 if (!CONST_INT_P (op0
)
6600 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6601 error ("operand 1 should be an unsigned 3-bit immediate");
6603 mode1
= insn_data
[icode
].operand
[1].mode
;
6605 if (icode
== CODE_FOR_vdiwr_insn
)
6606 target
= gen_rtx_REG (SImode
,
6607 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6608 else if (icode
== CODE_FOR_vdowr_insn
)
6609 target
= gen_rtx_REG (SImode
,
6610 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6614 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6615 op1
= copy_to_mode_reg (mode1
, op1
);
6617 pat
= GEN_FCN (icode
) (target
, op1
);
6624 case ARC_BUILTIN_VASRW
:
6625 case ARC_BUILTIN_VSR8
:
6626 case ARC_BUILTIN_VSR8AW
:
6627 arg0
= CALL_EXPR_ARG (exp
, 0);
6628 arg1
= CALL_EXPR_ARG (exp
, 1);
6629 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6630 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6631 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6633 target
= gen_reg_rtx (V8HImode
);
6634 mode0
= insn_data
[icode
].operand
[1].mode
;
6635 mode1
= insn_data
[icode
].operand
[2].mode
;
6637 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6638 op0
= copy_to_mode_reg (mode0
, op0
);
6640 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6641 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6642 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6644 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6651 case ARC_BUILTIN_VLD32WH
:
6652 case ARC_BUILTIN_VLD32WL
:
6653 case ARC_BUILTIN_VLD64
:
6654 case ARC_BUILTIN_VLD32
:
6657 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6658 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6659 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6661 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6662 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6663 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6664 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6666 /* target <- src vreg. */
6667 emit_insn (gen_move_insn (target
, src_vreg
));
6669 /* target <- vec_concat: target, mem (Ib, u8). */
6670 mode0
= insn_data
[icode
].operand
[3].mode
;
6671 mode1
= insn_data
[icode
].operand
[1].mode
;
6673 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6674 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6675 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6677 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6678 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6679 error ("operand 2 should be an unsigned 8-bit value");
6681 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6688 case ARC_BUILTIN_VLD64W
:
6689 case ARC_BUILTIN_VLD128
:
6690 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6691 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6693 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6694 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6695 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6697 /* target <- src vreg. */
6698 target
= gen_reg_rtx (V8HImode
);
6700 /* target <- vec_concat: target, mem (Ib, u8). */
6701 mode0
= insn_data
[icode
].operand
[1].mode
;
6702 mode1
= insn_data
[icode
].operand
[2].mode
;
6703 mode2
= insn_data
[icode
].operand
[3].mode
;
6705 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6706 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6707 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6709 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6710 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6711 error ("operand 2 should be an unsigned 8-bit value");
6713 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6721 case ARC_BUILTIN_VST128
:
6722 case ARC_BUILTIN_VST64
:
6723 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6724 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6725 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6727 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6728 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6729 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6730 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6732 mode0
= insn_data
[icode
].operand
[0].mode
;
6733 mode1
= insn_data
[icode
].operand
[1].mode
;
6734 mode2
= insn_data
[icode
].operand
[2].mode
;
6735 mode3
= insn_data
[icode
].operand
[3].mode
;
6737 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6738 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6739 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6741 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6742 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6743 error ("operand 3 should be an unsigned 8-bit value");
6745 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6746 op3
= copy_to_mode_reg (mode3
, op3
);
6748 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6755 case ARC_BUILTIN_VST16_N
:
6756 case ARC_BUILTIN_VST32_N
:
6757 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6758 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6759 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6760 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6762 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6763 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6764 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6765 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6766 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6768 mode0
= insn_data
[icode
].operand
[0].mode
;
6769 mode2
= insn_data
[icode
].operand
[2].mode
;
6770 mode3
= insn_data
[icode
].operand
[3].mode
;
6771 mode4
= insn_data
[icode
].operand
[4].mode
;
6773 /* Do some correctness checks for the operands. */
6774 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6775 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6776 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6778 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6779 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6780 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6782 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6783 op3
= copy_to_mode_reg (mode3
, op3
);
6785 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6786 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6787 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6788 else if (icode
== CODE_FOR_vst32_n_insn
6789 && ((INTVAL (op4
) % 2) != 0))
6790 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6792 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6803 /* 2nd part: Expand regular builtins. */
6805 internal_error ("bad builtin fcode");
6807 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6812 if (target
== NULL_RTX
6813 || GET_MODE (target
) != tmode
6814 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6816 target
= gen_reg_rtx (tmode
);
6821 gcc_assert (n_args
<= 4);
6822 for (i
= 0; i
< n_args
; i
++, j
++)
6824 tree arg
= CALL_EXPR_ARG (exp
, i
);
6825 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6826 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6827 machine_mode opmode
= GET_MODE (op
);
6828 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6830 /* SIMD extension requires exact immediate operand match. */
6831 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6832 && (id
< ARC_BUILTIN_SIMD_END
)
6836 if (!CONST_INT_P (op
))
6837 error ("builtin requires an immediate for operand %d", j
);
6841 if (!satisfies_constraint_L (op
))
6842 error ("operand %d should be a 6 bit unsigned immediate", j
);
6845 if (!satisfies_constraint_P (op
))
6846 error ("operand %d should be a 8 bit unsigned immediate", j
);
6849 if (!satisfies_constraint_K (op
))
6850 error ("operand %d should be a 3 bit unsigned immediate", j
);
6853 error ("unknown builtin immediate operand type for operand %d",
6858 if (CONST_INT_P (op
))
6861 if ((opmode
== SImode
) && (mode
== HImode
))
6864 op
= gen_lowpart (HImode
, op
);
6867 /* In case the insn wants input operands in modes different from
6868 the result, abort. */
6869 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6871 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6872 op
= copy_to_mode_reg (mode
, op
);
6877 pat
= apply_GEN_FCN (icode
, xop
);
6878 if (pat
== NULL_RTX
)
6889 /* Returns true if the operands[opno] is a valid compile-time constant to be
6890 used as register number in the code for builtins. Else it flags an error
6891 and returns false. */
6894 check_if_valid_regno_const (rtx
*operands
, int opno
)
6897 switch (GET_CODE (operands
[opno
]))
6904 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6910 /* Check that after all the constant folding, whether the operand to
6911 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6914 check_if_valid_sleep_operand (rtx
*operands
, int opno
)
6916 switch (GET_CODE (operands
[opno
]))
6920 if( UNSIGNED_INT6 (INTVAL (operands
[opno
])))
6924 fatal_error (input_location
,
6925 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6931 /* Return true if it is ok to make a tail-call to DECL. */
6934 arc_function_ok_for_sibcall (tree decl
,
6935 tree exp ATTRIBUTE_UNUSED
)
6937 tree attrs
= NULL_TREE
;
6939 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6940 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6945 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
6947 if (lookup_attribute ("jli_always", attrs
))
6949 if (lookup_attribute ("jli_fixed", attrs
))
6951 if (lookup_attribute ("secure_call", attrs
))
6955 /* Everything else is ok. */
6959 /* Output code to add DELTA to the first argument, and then jump
6960 to FUNCTION. Used for C++ multiple inheritance. */
6963 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
6964 HOST_WIDE_INT delta
,
6965 HOST_WIDE_INT vcall_offset
,
6968 int mi_delta
= delta
;
6969 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
6972 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
6976 mi_delta
= - mi_delta
;
6978 /* Add DELTA. When possible use a plain add, otherwise load it into
6979 a register first. */
6981 while (mi_delta
!= 0)
6983 if ((mi_delta
& (3 << shift
)) == 0)
6987 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
6988 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
6989 mi_delta
& (0xff << shift
));
6990 mi_delta
&= ~(0xff << shift
);
6995 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6996 if (vcall_offset
!= 0)
6998 /* ld r12,[this] --> temp = *this
6999 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7001 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7002 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7003 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
7004 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
7005 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
7006 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7007 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
7008 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
7009 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
7012 fnaddr
= XEXP (DECL_RTL (function
), 0);
7014 if (arc_is_longcall_p (fnaddr
))
7018 asm_fprintf (file
, "\tld\t%s, [pcl, @",
7019 ARC_TEMP_SCRATCH_REG
);
7020 assemble_name (file
, XSTR (fnaddr
, 0));
7021 fputs ("@gotpc]\n", file
);
7022 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
7026 fputs ("\tj\t@", file
);
7027 assemble_name (file
, XSTR (fnaddr
, 0));
7032 fputs ("\tb\t@", file
);
7033 assemble_name (file
, XSTR (fnaddr
, 0));
7035 fputs ("@plt\n", file
);
7040 /* Return true if a 32 bit "long_call" should be generated for
7041 this calling SYM_REF. We generate a long_call if the function:
7043 a. has an __attribute__((long call))
7044 or b. the -mlong-calls command line switch has been specified
7046 However we do not generate a long call if the function has an
7047 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7049 This function will be called by C fragments contained in the machine
7050 description file. */
7053 arc_is_longcall_p (rtx sym_ref
)
7055 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7058 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
7059 || (TARGET_LONG_CALLS_SET
7060 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7061 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7065 /* Likewise for short calls. */
7068 arc_is_shortcall_p (rtx sym_ref
)
7070 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7073 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7074 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
7075 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
7076 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7080 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7083 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7085 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
7089 HOST_WIDE_INT size
= int_size_in_bytes (type
);
7090 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
7095 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
7096 machine_mode mode ATTRIBUTE_UNUSED
,
7098 bool named ATTRIBUTE_UNUSED
)
7101 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
7102 || TREE_ADDRESSABLE (type
)));
7105 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7108 arc_can_use_doloop_p (const widest_int
&,
7109 const widest_int
&iterations_max
,
7110 unsigned int loop_depth
, bool entered_at_top
)
7112 /* Considering limitations in the hardware, only use doloop
7113 for innermost loops which must be entered from the top. */
7114 if (loop_depth
> 1 || !entered_at_top
)
7117 /* Check for lp_count width boundary. */
7118 if (arc_lpcwidth
!= 32
7119 && (wi::gtu_p (iterations_max
, ((1 << arc_lpcwidth
) - 1))
7120 || wi::eq_p (iterations_max
, 0)))
7125 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7126 return why doloop cannot be applied. */
7129 arc_invalid_within_doloop (const rtx_insn
*insn
)
7132 return "Function call in the loop.";
7134 /* FIXME! add here all the ZOL exceptions. */
7138 /* Return true if a load instruction (CONSUMER) uses the same address as a
7139 store instruction (PRODUCER). This function is used to avoid st/ld
7140 address hazard in ARC700 cores. */
7142 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7144 rtx in_set
, out_set
;
7145 rtx out_addr
, in_addr
;
7153 /* Peel the producer and the consumer for the address. */
7154 out_set
= single_set (producer
);
7157 out_addr
= SET_DEST (out_set
);
7160 if (GET_CODE (out_addr
) == ZERO_EXTEND
7161 || GET_CODE (out_addr
) == SIGN_EXTEND
)
7162 out_addr
= XEXP (out_addr
, 0);
7164 if (!MEM_P (out_addr
))
7167 in_set
= single_set (consumer
);
7170 in_addr
= SET_SRC (in_set
);
7173 if (GET_CODE (in_addr
) == ZERO_EXTEND
7174 || GET_CODE (in_addr
) == SIGN_EXTEND
)
7175 in_addr
= XEXP (in_addr
, 0);
7177 if (!MEM_P (in_addr
))
7179 /* Get rid of the MEM and check if the addresses are
7181 in_addr
= XEXP (in_addr
, 0);
7182 out_addr
= XEXP (out_addr
, 0);
7184 return exp_equiv_p (in_addr
, out_addr
, 0, true);
7190 /* The same functionality as arc_hazard. It is called in machine
7191 reorg before any other optimization. Hence, the NOP size is taken
7192 into account when doing branch shortening. */
7195 workaround_arc_anomaly (void)
7197 rtx_insn
*insn
, *succ0
;
7199 /* For any architecture: call arc_hazard here. */
7200 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7202 succ0
= next_real_insn (insn
);
7203 if (arc_hazard (insn
, succ0
))
7205 emit_insn_before (gen_nopv (), succ0
);
7213 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7215 succ0
= next_real_insn (insn
);
7216 if (arc_store_addr_hazard_p (insn
, succ0
))
7218 emit_insn_after (gen_nopv (), insn
);
7219 emit_insn_after (gen_nopv (), insn
);
7223 /* Avoid adding nops if the instruction between the ST and LD is
7225 succ1
= next_real_insn (succ0
);
7226 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
7227 && arc_store_addr_hazard_p (insn
, succ1
))
7228 emit_insn_after (gen_nopv (), insn
);
7233 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7234 turns out not to be optimizable; we have to split the loop_end pattern into
7235 a subtract and a test. */
7238 hwloop_fail (hwloop_info loop
)
7241 rtx insn
= loop
->loop_end
;
7244 && (loop
->length
&& (loop
->length
<= ARC_MAX_LOOP_LENGTH
))
7245 && REG_P (loop
->iter_reg
))
7247 /* TARGET_V2 core3 has dbnz instructions. */
7248 test
= gen_dbnz (loop
->iter_reg
, loop
->start_label
);
7249 insn
= emit_jump_insn_before (test
, loop
->loop_end
);
7251 else if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
) == LP_COUNT
))
7253 /* We have the lp_count as loop iterator, try to use it. */
7254 emit_insn_before (gen_loop_fail (), loop
->loop_end
);
7255 test
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CC_ZNmode
, CC_REG
),
7257 test
= gen_rtx_IF_THEN_ELSE (VOIDmode
, test
,
7258 gen_rtx_LABEL_REF (Pmode
, loop
->start_label
),
7260 insn
= emit_jump_insn_before (gen_rtx_SET (pc_rtx
, test
),
7265 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
7269 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
7270 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
7276 JUMP_LABEL (insn
) = loop
->start_label
;
7277 LABEL_NUSES (loop
->start_label
)++;
7278 delete_insn (loop
->loop_end
);
7281 /* Optimize LOOP. */
7284 hwloop_optimize (hwloop_info loop
)
7288 basic_block entry_bb
, bb
;
7289 rtx iter_reg
, end_label
;
7290 rtx_insn
*insn
, *seq
, *entry_after
, *last_insn
;
7291 unsigned int length
;
7292 bool need_fix
= false;
7293 rtx lp_reg
= gen_rtx_REG (SImode
, LP_COUNT
);
7295 if (loop
->depth
> 1)
7298 fprintf (dump_file
, ";; loop %d is not innermost\n",
7303 if (!loop
->incoming_dest
)
7306 fprintf (dump_file
, ";; loop %d has more than one entry\n",
7311 if (loop
->incoming_dest
!= loop
->head
)
7314 fprintf (dump_file
, ";; loop %d is not entered from head\n",
7319 if (loop
->has_call
|| loop
->has_asm
)
7322 fprintf (dump_file
, ";; loop %d has invalid insn\n",
7327 /* Scan all the blocks to make sure they don't use iter_reg. */
7328 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
7331 fprintf (dump_file
, ";; loop %d uses iterator\n",
7336 /* Check if start_label appears before doloop_end. */
7338 for (insn
= loop
->start_label
;
7339 insn
&& insn
!= loop
->loop_end
;
7340 insn
= NEXT_INSN (insn
))
7341 length
+= NONDEBUG_INSN_P (insn
) ? get_attr_length (insn
) : 0;
7346 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
7351 loop
->length
= length
;
7352 if (loop
->length
> ARC_MAX_LOOP_LENGTH
)
7355 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7358 else if (!loop
->length
)
7361 fprintf (dump_file
, ";; loop %d is empty\n", loop
->loop_no
);
7365 /* Check if we use a register or not. */
7366 if (!REG_P (loop
->iter_reg
))
7369 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7374 /* Check if loop register is lpcount. */
7375 if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
)) != LP_COUNT
)
7378 fprintf (dump_file
, ";; loop %d doesn't use lp_count as loop"
7381 /* This loop doesn't use the lp_count, check though if we can
7383 if (TEST_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
)
7384 /* In very unique cases we may have LP_COUNT alive. */
7385 || (loop
->incoming_src
7386 && REGNO_REG_SET_P (df_get_live_out (loop
->incoming_src
),
7393 /* Check for control like instruction as the last instruction of a
7396 last_insn
= PREV_INSN (loop
->loop_end
);
7400 for (; last_insn
!= BB_HEAD (bb
);
7401 last_insn
= PREV_INSN (last_insn
))
7402 if (NONDEBUG_INSN_P (last_insn
))
7405 if (last_insn
!= BB_HEAD (bb
))
7408 if (single_pred_p (bb
)
7409 && single_pred_edge (bb
)->flags
& EDGE_FALLTHRU
7410 && single_pred (bb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
))
7412 bb
= single_pred (bb
);
7413 last_insn
= BB_END (bb
);
7426 fprintf (dump_file
, ";; loop %d has no last instruction\n",
7431 if ((TARGET_ARC600_FAMILY
|| TARGET_HS
)
7432 && INSN_P (last_insn
)
7433 && (JUMP_P (last_insn
) || CALL_P (last_insn
)
7434 || GET_CODE (PATTERN (last_insn
)) == SEQUENCE
7435 /* At this stage we can have (insn (clobber (mem:BLK
7436 (reg)))) instructions, ignore them. */
7437 || (GET_CODE (PATTERN (last_insn
)) != CLOBBER
7438 && (get_attr_type (last_insn
) == TYPE_BRCC
7439 || get_attr_type (last_insn
) == TYPE_BRCC_NO_DELAY_SLOT
))))
7441 if (loop
->length
+ 2 > ARC_MAX_LOOP_LENGTH
)
7444 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7448 fprintf (dump_file
, ";; loop %d has a control like last insn;"
7452 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7455 if (LABEL_P (last_insn
))
7458 fprintf (dump_file
, ";; loop %d has a label as last insn;"
7461 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7464 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7465 and we can use it to indicate the last ZOL instruction cannot be
7466 part of a delay slot. */
7467 add_reg_note (last_insn
, REG_SAVE_NOTE
, GEN_INT (2));
7469 loop
->last_insn
= last_insn
;
7471 /* Get the loop iteration register. */
7472 iter_reg
= loop
->iter_reg
;
7474 gcc_assert (REG_P (iter_reg
));
7478 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
7479 if (entry_edge
->flags
& EDGE_FALLTHRU
)
7482 if (entry_edge
== NULL
)
7485 fprintf (dump_file
, ";; loop %d has no fallthru edge jumping"
7490 /* The loop is good. */
7491 end_label
= gen_label_rtx ();
7492 loop
->end_label
= end_label
;
7494 /* Place the zero_cost_loop_start instruction before the loop. */
7495 entry_bb
= entry_edge
->src
;
7501 /* The loop uses a R-register, but the lp_count is free, thus
7503 emit_insn (gen_movsi (lp_reg
, iter_reg
));
7504 SET_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
);
7508 fprintf (dump_file
, ";; fix loop %d to use lp_count\n",
7513 insn
= emit_insn (gen_arc_lp (iter_reg
,
7520 entry_after
= BB_END (entry_bb
);
7521 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
7528 emit_insn_before (seq
, BB_HEAD (loop
->head
));
7529 seq
= emit_label_before (gen_label_rtx (), seq
);
7530 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
7531 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
7533 if (!(e
->flags
& EDGE_FALLTHRU
))
7534 redirect_edge_and_branch_force (e
, new_bb
);
7536 redirect_edge_succ (e
, new_bb
);
7539 make_edge (new_bb
, loop
->head
, 0);
7544 while (DEBUG_INSN_P (entry_after
)
7545 || (NOTE_P (entry_after
)
7546 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
))
7547 entry_after
= NEXT_INSN (entry_after
);
7549 entry_after
= next_nonnote_nondebug_insn_bb (entry_after
);
7551 gcc_assert (entry_after
);
7552 emit_insn_before (seq
, entry_after
);
7555 delete_insn (loop
->loop_end
);
7556 /* Insert the loop end label before the last instruction of the
7558 emit_label_after (end_label
, loop
->last_insn
);
7559 /* Make sure we mark the begining and end label as used. */
7560 LABEL_NUSES (loop
->end_label
)++;
7561 LABEL_NUSES (loop
->start_label
)++;
7566 /* A callback for the hw-doloop pass. This function examines INSN; if
7567 it is a loop_end pattern we recognize, return the reg rtx for the
7568 loop counter. Otherwise, return NULL_RTX. */
7571 hwloop_pattern_reg (rtx_insn
*insn
)
7575 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
7578 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
7584 static struct hw_doloop_hooks arc_doloop_hooks
=
7591 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
7592 and tries to rewrite the RTL of these loops so that proper Blackfin
7593 hardware loops are generated. */
7596 arc_reorg_loops (void)
7598 reorg_loops (true, &arc_doloop_hooks
);
7601 /* Scan all calls and add symbols to be emitted in the jli section if
7605 jli_call_scan (void)
7609 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7614 rtx pat
= PATTERN (insn
);
7615 if (GET_CODE (pat
) == COND_EXEC
)
7616 pat
= COND_EXEC_CODE (pat
);
7617 pat
= XVECEXP (pat
, 0, 0);
7618 if (GET_CODE (pat
) == SET
)
7619 pat
= SET_SRC (pat
);
7621 pat
= XEXP (XEXP (pat
, 0), 0);
7622 if (GET_CODE (pat
) == SYMBOL_REF
7623 && arc_is_jli_call_p (pat
))
7624 arc_add_jli_section (pat
);
7628 static int arc_reorg_in_progress
= 0;
7630 /* ARC's machince specific reorg function. */
7641 cfun
->machine
->arc_reorg_started
= 1;
7642 arc_reorg_in_progress
= 1;
7644 compute_bb_for_insn ();
7648 /* Doloop optimization. */
7651 workaround_arc_anomaly ();
7654 /* FIXME: should anticipate ccfsm action, generate special patterns for
7655 to-be-deleted branches that have no delay slot and have at least the
7656 length of the size increase forced on other insns that are conditionalized.
7657 This can also have an insn_list inside that enumerates insns which are
7658 not actually conditionalized because the destinations are dead in the
7660 Could also tag branches that we want to be unaligned if they get no delay
7661 slot, or even ones that we don't want to do delay slot sheduling for
7662 because we can unalign them.
7664 However, there are cases when conditional execution is only possible after
7665 delay slot scheduling:
7667 - If a delay slot is filled with a nocond/set insn from above, the previous
7668 basic block can become elegible for conditional execution.
7669 - If a delay slot is filled with a nocond insn from the fall-through path,
7670 the branch with that delay slot can become eligble for conditional
7671 execution (however, with the same sort of data flow analysis that dbr
7672 does, we could have figured out before that we don't need to
7673 conditionalize this insn.)
7674 - If a delay slot insn is filled with an insn from the target, the
7675 target label gets its uses decremented (even deleted if falling to zero),
7676 thus possibly creating more condexec opportunities there.
7677 Therefore, we should still be prepared to apply condexec optimization on
7678 non-prepared branches if the size increase of conditionalized insns is no
7679 more than the size saved from eliminating the branch. An invocation option
7680 could also be used to reserve a bit of extra size for condbranches so that
7681 this'll work more often (could also test in arc_reorg if the block is
7682 'close enough' to be eligible for condexec to make this likely, and
7683 estimate required size increase). */
7684 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7685 if (TARGET_NO_BRCC_SET
)
7690 init_insn_lengths();
7693 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
7696 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
7697 df_finish_pass ((flags
& TODO_df_verify
) != 0);
7701 fprintf (dump_file
, ";; After if conversion:\n\n");
7702 print_rtl (dump_file
, get_insns ());
7706 /* Call shorten_branches to calculate the insn lengths. */
7707 shorten_branches (get_insns());
7708 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
7710 if (!INSN_ADDRESSES_SET_P())
7711 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
7713 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7716 enum attr_type insn_type
;
7718 /* If a non-jump insn (or a casesi jump table), continue. */
7719 if (GET_CODE (insn
) != JUMP_INSN
||
7720 GET_CODE (PATTERN (insn
)) == ADDR_VEC
7721 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
7724 /* If we already have a brcc, note if it is suitable for brcc_s.
7725 Be a bit generous with the brcc_s range so that we can take
7726 advantage of any code shortening from delay slot scheduling. */
7727 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
7729 rtx pat
= PATTERN (insn
);
7730 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
7731 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
7733 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7734 if ((offset
>= -140 && offset
< 140)
7735 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
7736 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
7737 && equality_comparison_operator (op
, VOIDmode
))
7738 PUT_MODE (*ccp
, CC_Zmode
);
7739 else if (GET_MODE (*ccp
) == CC_Zmode
)
7740 PUT_MODE (*ccp
, CC_ZNmode
);
7743 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
7744 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
7747 /* OK. so we have a jump insn. */
7748 /* We need to check that it is a bcc. */
7749 /* Bcc => set (pc) (if_then_else ) */
7750 pattern
= PATTERN (insn
);
7751 if (GET_CODE (pattern
) != SET
7752 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
7753 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
7756 /* Now check if the jump is beyond the s9 range. */
7757 if (CROSSING_JUMP_P (insn
))
7759 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7761 if(offset
> 253 || offset
< -254)
7764 pc_target
= SET_SRC (pattern
);
7766 /* Avoid FPU instructions. */
7767 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
7768 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
7771 /* Now go back and search for the set cc insn. */
7773 label
= XEXP (pc_target
, 1);
7777 rtx_insn
*scan
, *link_insn
= NULL
;
7779 for (scan
= PREV_INSN (insn
);
7780 scan
&& GET_CODE (scan
) != CODE_LABEL
;
7781 scan
= PREV_INSN (scan
))
7783 if (! INSN_P (scan
))
7785 pat
= PATTERN (scan
);
7786 if (GET_CODE (pat
) == SET
7787 && cc_register (SET_DEST (pat
), VOIDmode
))
7796 /* Check if this is a data dependency. */
7798 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
7801 /* Ok this is the set cc. copy args here. */
7802 op
= XEXP (pc_target
, 0);
7804 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
7805 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
7806 if (GET_CODE (op0
) == ZERO_EXTRACT
7807 && XEXP (op0
, 1) == const1_rtx
7808 && (GET_CODE (op
) == EQ
7809 || GET_CODE (op
) == NE
))
7811 /* btst / b{eq,ne} -> bbit{0,1} */
7812 op0
= XEXP (cmp0
, 0);
7813 op1
= XEXP (cmp0
, 2);
7815 else if (!register_operand (op0
, VOIDmode
)
7816 || !general_operand (op1
, VOIDmode
))
7818 /* Be careful not to break what cmpsfpx_raw is
7819 trying to create for checking equality of
7820 single-precision floats. */
7821 else if (TARGET_SPFP
7822 && GET_MODE (op0
) == SFmode
7823 && GET_MODE (op1
) == SFmode
)
7826 /* None of the two cmp operands should be set between the
7827 cmp and the branch. */
7828 if (reg_set_between_p (op0
, link_insn
, insn
))
7831 if (reg_set_between_p (op1
, link_insn
, insn
))
7834 /* Since the MODE check does not work, check that this is
7835 CC reg's last set location before insn, and also no
7836 instruction between the cmp and branch uses the
7838 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
7839 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
7842 /* CC reg should be dead after insn. */
7843 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
7846 op
= gen_rtx_fmt_ee (GET_CODE (op
),
7847 GET_MODE (op
), cmp0
, cmp1
);
7848 /* If we create a LIMM where there was none before,
7849 we only benefit if we can avoid a scheduling bubble
7850 for the ARC600. Otherwise, we'd only forgo chances
7851 at short insn generation, and risk out-of-range
7853 if (!brcc_nolimm_operator (op
, VOIDmode
)
7854 && !long_immediate_operand (op1
, VOIDmode
)
7856 || next_active_insn (link_insn
) != insn
))
7859 /* Emit bbit / brcc (or brcc_s if possible).
7860 CC_Zmode indicates that brcc_s is possible. */
7863 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
7864 else if ((offset
>= -140 && offset
< 140)
7865 && rtx_equal_p (op1
, const0_rtx
)
7866 && compact_register_operand (op0
, VOIDmode
)
7867 && (GET_CODE (op
) == EQ
7868 || GET_CODE (op
) == NE
))
7869 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
7871 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
7874 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
7875 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
7876 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
7879 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
7880 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
7882 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
7883 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
7886 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7887 REG_NOTES (brcc_insn
) = note
;
7889 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
7892 remove_note (link_insn
, note
);
7893 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7894 REG_NOTES (brcc_insn
) = note
;
7896 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
7899 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7900 REG_NOTES (brcc_insn
) = note
;
7905 /* Delete the bcc insn. */
7906 set_insn_deleted (insn
);
7908 /* Delete the cmp insn. */
7909 set_insn_deleted (link_insn
);
7914 /* Clear out insn_addresses. */
7915 INSN_ADDRESSES_FREE ();
7919 if (INSN_ADDRESSES_SET_P())
7920 fatal_error (input_location
, "insn addresses not freed");
7922 arc_reorg_in_progress
= 0;
7925 /* Check if the operands are valid for BRcc.d generation
7926 Valid Brcc.d patterns are
7930 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7931 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7932 does not have a delay slot
7934 Assumed precondition: Second operand is either a register or a u6 value. */
7937 valid_brcc_with_delay_p (rtx
*operands
)
7939 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
7941 return brcc_nolimm_operator (operands
[0], VOIDmode
);
7944 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7945 access DECL using %gp_rel(...)($gp). */
7948 arc_in_small_data_p (const_tree decl
)
7953 /* Only variables are going into small data area. */
7954 if (TREE_CODE (decl
) != VAR_DECL
)
7957 if (TARGET_NO_SDATA_SET
)
7960 /* Disable sdata references to weak variables. */
7961 if (DECL_WEAK (decl
))
7964 /* Don't put constants into the small data section: we want them to
7965 be in ROM rather than RAM. */
7966 if (TREE_READONLY (decl
))
7969 /* To ensure -mvolatile-cache works ld.di does not have a
7970 gp-relative variant. */
7971 if (!TARGET_VOLATILE_CACHE_SET
7972 && TREE_THIS_VOLATILE (decl
))
7975 /* Likewise for uncached data. */
7976 attr
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
7977 if (lookup_attribute ("uncached", attr
))
7980 /* and for aux regs. */
7981 attr
= DECL_ATTRIBUTES (decl
);
7982 if (lookup_attribute ("aux", attr
))
7985 if (DECL_SECTION_NAME (decl
) != 0)
7987 const char *name
= DECL_SECTION_NAME (decl
);
7988 if (strcmp (name
, ".sdata") == 0
7989 || strcmp (name
, ".sbss") == 0)
7992 /* If it's not public, there's no need to put it in the small data
7994 else if (TREE_PUBLIC (decl
))
7996 size
= int_size_in_bytes (TREE_TYPE (decl
));
7997 return (size
> 0 && size
<= g_switch_value
);
8002 /* Return true if X is a small data address that can be rewritten
8006 arc_rewrite_small_data_p (const_rtx x
)
8008 if (GET_CODE (x
) == CONST
)
8011 if (GET_CODE (x
) == PLUS
)
8013 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
8017 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
8019 gcc_assert (SYMBOL_REF_TLS_MODEL (x
) == 0);
8025 /* If possible, rewrite OP so that it refers to small data using
8026 explicit relocations. */
8029 arc_rewrite_small_data_1 (rtx op
)
8031 rtx rgp
= gen_rtx_REG (Pmode
, SDATA_BASE_REGNUM
);
8032 op
= copy_insn (op
);
8033 subrtx_ptr_iterator::array_type array
;
8034 FOR_EACH_SUBRTX_PTR (iter
, array
, &op
, ALL
)
8037 if (arc_rewrite_small_data_p (*loc
))
8039 *loc
= gen_rtx_PLUS (Pmode
, rgp
, *loc
);
8040 iter
.skip_subrtxes ();
8042 else if (GET_CODE (*loc
) == PLUS
8043 && rtx_equal_p (XEXP (*loc
, 0), rgp
))
8044 iter
.skip_subrtxes ();
8050 arc_rewrite_small_data (rtx op
)
8052 op
= arc_rewrite_small_data_1 (op
);
8054 /* Check if we fit small data constraints. */
8056 && !LEGITIMATE_SMALL_DATA_ADDRESS_P (XEXP (op
, 0)))
8058 rtx addr
= XEXP (op
, 0);
8059 rtx tmp
= gen_reg_rtx (Pmode
);
8060 emit_move_insn (tmp
, addr
);
8061 op
= replace_equiv_address_nv (op
, tmp
);
8066 /* Return true if OP refers to small data symbols directly, not through
8070 small_data_pattern (rtx op
, machine_mode
)
8072 if (GET_CODE (op
) == SEQUENCE
)
8075 rtx rgp
= gen_rtx_REG (Pmode
, SDATA_BASE_REGNUM
);
8076 subrtx_iterator::array_type array
;
8077 FOR_EACH_SUBRTX (iter
, array
, op
, ALL
)
8079 const_rtx x
= *iter
;
8080 if (GET_CODE (x
) == PLUS
8081 && rtx_equal_p (XEXP (x
, 0), rgp
))
8082 iter
.skip_subrtxes ();
8083 else if (arc_rewrite_small_data_p (x
))
8089 /* Return true if OP is an acceptable memory operand for ARCompact
8090 16-bit gp-relative load instructions.
8091 op shd look like : [r26, symref@sda]
8092 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
8094 /* volatile cache option still to be handled. */
8097 compact_sda_memory_operand (rtx op
, machine_mode mode
, bool short_p
)
8101 tree decl
= NULL_TREE
;
8105 /* Eliminate non-memory operations. */
8106 if (GET_CODE (op
) != MEM
)
8109 if (mode
== VOIDmode
)
8110 mode
= GET_MODE (op
);
8112 size
= GET_MODE_SIZE (mode
);
8114 /* dword operations really put out 2 instructions, so eliminate them. */
8115 if (size
> UNITS_PER_WORD
)
8118 /* Decode the address now. */
8119 addr
= XEXP (op
, 0);
8121 if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
))
8124 if (!short_p
|| size
== 1)
8127 /* Now check for the alignment, the short loads using gp require the
8128 addresses to be aligned. */
8129 if (GET_CODE (XEXP (addr
, 1)) == SYMBOL_REF
)
8130 decl
= SYMBOL_REF_DECL (XEXP (addr
, 1));
8131 else if (GET_CODE (XEXP (XEXP (XEXP (addr
, 1), 0), 0)) == SYMBOL_REF
)
8132 decl
= SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr
, 1), 0), 0));
8134 align
= DECL_ALIGN (decl
);
8135 align
= align
/ BITS_PER_UNIT
;
8147 if (align
&& ((align
& mask
) == 0))
8152 /* Return TRUE if PAT is accessing an aux-reg. */
8155 arc_is_aux_reg_p (rtx pat
)
8157 tree attrs
= NULL_TREE
;
8163 /* Get the memory attributes. */
8164 addr
= MEM_EXPR (pat
);
8168 /* Get the attributes. */
8169 if (TREE_CODE (addr
) == VAR_DECL
)
8170 attrs
= DECL_ATTRIBUTES (addr
);
8171 else if (TREE_CODE (addr
) == MEM_REF
)
8172 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
8176 if (lookup_attribute ("aux", attrs
))
8181 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8184 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
8185 unsigned HOST_WIDE_INT size
,
8186 unsigned HOST_WIDE_INT align
,
8187 unsigned HOST_WIDE_INT globalize_p
)
8189 int in_small_data
= arc_in_small_data_p (decl
);
8190 rtx mem
= decl
== NULL_TREE
? NULL_RTX
: DECL_RTL (decl
);
8192 /* Don't output aux-reg symbols. */
8193 if (mem
!= NULL_RTX
&& MEM_P (mem
)
8194 && SYMBOL_REF_P (XEXP (mem
, 0))
8195 && arc_is_aux_reg_p (mem
))
8199 switch_to_section (get_named_section (NULL
, ".sbss", 0));
8200 /* named_section (0,".sbss",0); */
8202 switch_to_section (bss_section
);
8205 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
8207 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
8208 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
8209 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
8210 ASM_OUTPUT_LABEL (stream
, name
);
8213 ASM_OUTPUT_SKIP (stream
, size
);
8217 arc_preserve_reload_p (rtx in
)
8219 return (GET_CODE (in
) == PLUS
8220 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
8221 && CONST_INT_P (XEXP (in
, 1))
8222 && !((INTVAL (XEXP (in
, 1)) & 511)));
8226 arc_register_move_cost (machine_mode
,
8227 enum reg_class from_class
, enum reg_class to_class
)
8229 /* The ARC600 has no bypass for extension registers, hence a nop might be
8230 needed to be inserted after a write so that reads are safe. */
8233 if (to_class
== MPY_WRITABLE_CORE_REGS
)
8235 /* Instructions modifying LP_COUNT need 4 additional cycles before
8236 the register will actually contain the value. */
8237 else if (to_class
== LPCOUNT_REG
)
8239 else if (to_class
== WRITABLE_CORE_REGS
)
8243 /* Using lp_count as scratch reg is a VERY bad idea. */
8244 if (from_class
== LPCOUNT_REG
)
8246 if (to_class
== LPCOUNT_REG
)
8249 /* Force an attempt to 'mov Dy,Dx' to spill. */
8250 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
8251 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
8257 /* Emit code for an addsi3 instruction with OPERANDS.
8258 COND_P indicates if this will use conditional execution.
8259 Return the length of the instruction.
8260 If OUTPUT_P is false, don't actually output the instruction, just return
8263 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
8267 int match
= operands_match_p (operands
[0], operands
[1]);
8268 int match2
= operands_match_p (operands
[0], operands
[2]);
8269 int intval
= (REG_P (operands
[2]) ? 1
8270 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
8271 int neg_intval
= -intval
;
8272 int short_0
= satisfies_constraint_Rcq (operands
[0]);
8273 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
8276 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8277 && REGNO (OP) != 30) \
8280 #define ADDSI_OUTPUT1(FORMAT) do {\
8282 output_asm_insn (FORMAT, operands);\
8285 #define ADDSI_OUTPUT(LIST) do {\
8288 ADDSI_OUTPUT1 (format);\
8292 /* First try to emit a 16 bit insn. */
8295 /* If we are actually about to output this insn, don't try a 16 bit
8296 variant if we already decided that we don't want that
8297 (I.e. we upsized this insn to align some following insn.)
8298 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8299 but add1 r0,sp,35 doesn't. */
8300 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
8302 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8305 && ((REG_H_P (operands
[2])
8306 && (match
|| satisfies_constraint_Rcq (operands
[2])))
8307 || (CONST_INT_P (operands
[2])
8308 && ((unsigned) intval
<= (match
? 127 : 7)))))
8309 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8311 /* Generate add_s b,b,h patterns. */
8312 if (short_0
&& match2
&& REG_H_P (operands
[1]))
8313 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8315 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8316 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
8317 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
8318 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8320 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
8321 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
8322 && match
&& !(neg_intval
& ~124)))
8323 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8325 /* Generate add_s h,h,s3 patterns. */
8326 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
8327 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
8328 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8330 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8331 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
8332 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
8333 && satisfies_constraint_Rcq (operands
[1])
8334 && satisfies_constraint_L (operands
[2]))
8335 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8338 /* Now try to emit a 32 bit insn without long immediate. */
8340 if (!match
&& match2
&& REG_P (operands
[1]))
8341 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8342 if (match
|| !cond_p
)
8344 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
8345 int range_factor
= neg_intval
& intval
;
8348 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
8349 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8351 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8352 same size, do, so - the insn latency is lower. */
8353 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8355 if ((intval
>= 0 && intval
<= limit
)
8356 || (intval
== -0x800 && limit
== 0x7ff))
8357 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8358 else if ((intval
< 0 && neg_intval
<= limit
)
8359 || (intval
== 0x800 && limit
== 0x7ff))
8360 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8361 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
8362 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
8363 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
8364 if (((intval
< 0 && intval
!= -0x4000)
8365 /* sub[123] is slower than add_s / sub, only use it if it
8366 avoids a long immediate. */
8367 && neg_intval
<= limit
<< shift
)
8368 || (intval
== 0x4000 && limit
== 0x7ff))
8369 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
8370 shift
, neg_intval
>> shift
));
8371 else if ((intval
>= 0 && intval
<= limit
<< shift
)
8372 || (intval
== -0x4000 && limit
== 0x7ff))
8373 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
8375 /* Try to emit a 16 bit opcode with long immediate. */
8377 if (short_p
&& match
)
8378 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8380 /* We have to use a 32 bit opcode, and with a long immediate. */
8382 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8385 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8386 Return the length of the instruction.
8387 If OUTPUT_P is false, don't actually output the instruction, just return
8390 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
8392 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
8393 const char *pat
= NULL
;
8395 /* Canonical rtl should not have a constant in the first operand position. */
8396 gcc_assert (!CONSTANT_P (operands
[1]));
8398 switch (commutative_op
)
8401 if (satisfies_constraint_C1p (operands
[2]))
8402 pat
= "bmsk%? %0,%1,%Z2";
8403 else if (satisfies_constraint_C2p (operands
[2]))
8405 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
8406 pat
= "bmskn%? %0,%1,%Z2";
8408 else if (satisfies_constraint_Ccp (operands
[2]))
8409 pat
= "bclr%? %0,%1,%M2";
8410 else if (satisfies_constraint_CnL (operands
[2]))
8411 pat
= "bic%? %0,%1,%n2-1";
8414 if (satisfies_constraint_C0p (operands
[2]))
8415 pat
= "bset%? %0,%1,%z2";
8418 if (satisfies_constraint_C0p (operands
[2]))
8419 pat
= "bxor%? %0,%1,%z2";
8422 return arc_output_addsi (operands
, true, output_p
);
8426 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
8427 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
8432 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8433 Emit code and return an potentially modified address such that offsets
8434 up to SIZE are can be added to yield a legitimate address.
8435 if REUSE is set, ADDR is a register that may be modified. */
8438 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
8441 rtx offs
= const0_rtx
;
8443 if (GET_CODE (base
) == PLUS
)
8445 offs
= XEXP (base
, 1);
8446 base
= XEXP (base
, 0);
8449 || (REGNO (base
) != STACK_POINTER_REGNUM
8450 && REGNO_PTR_FRAME_P (REGNO (base
)))
8451 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
8452 || !SMALL_INT (INTVAL (offs
) + size
))
8455 emit_insn (gen_add2_insn (addr
, offs
));
8457 addr
= copy_to_mode_reg (Pmode
, addr
);
8462 /* Like move_by_pieces, but take account of load latency, and actual
8463 offset ranges. Return true on success. */
8466 arc_expand_movmem (rtx
*operands
)
8468 rtx dst
= operands
[0];
8469 rtx src
= operands
[1];
8470 rtx dst_addr
, src_addr
;
8472 int align
= INTVAL (operands
[3]);
8479 if (!CONST_INT_P (operands
[2]))
8481 size
= INTVAL (operands
[2]);
8482 /* move_by_pieces_ninsns is static, so we can't use it. */
8486 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
8488 n_pieces
= (size
+ 2) / 4U + (size
& 1);
8490 else if (align
== 2)
8491 n_pieces
= (size
+ 1) / 2U;
8494 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
8496 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8498 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
8502 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
8503 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
8504 store
[0] = store
[1] = NULL_RTX
;
8505 tmpx
[0] = tmpx
[1] = NULL_RTX
;
8506 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
8511 while (piece
> size
)
8513 mode
= smallest_int_mode_for_size (piece
* BITS_PER_UNIT
);
8514 /* If we don't re-use temporaries, the scheduler gets carried away,
8515 and the register pressure gets unnecessarily high. */
8516 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
8519 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
8520 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
8521 src_addr
= force_offsettable (src_addr
, piece
, 1);
8523 emit_insn (store
[i
]);
8524 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
8525 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
8526 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
8527 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
8530 emit_insn (store
[i
]);
8532 emit_insn (store
[i
^1]);
8537 arc_get_aux_arg (rtx pat
, int *auxr
)
8539 tree attr
, addr
= MEM_EXPR (pat
);
8540 if (TREE_CODE (addr
) != VAR_DECL
)
8543 attr
= DECL_ATTRIBUTES (addr
);
8544 if (lookup_attribute ("aux", attr
))
8546 tree arg
= TREE_VALUE (attr
);
8549 *auxr
= TREE_INT_CST_LOW (TREE_VALUE (arg
));
8557 /* Prepare operands for move in MODE. Return true iff the move has
8561 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8563 /* First handle aux attribute. */
8565 && (MEM_P (operands
[0]) || MEM_P (operands
[1])))
8569 if (MEM_P (operands
[0]) && arc_is_aux_reg_p (operands
[0]))
8571 /* Save operation. */
8572 if (arc_get_aux_arg (operands
[0], &auxr
))
8574 tmp
= gen_reg_rtx (SImode
);
8575 emit_move_insn (tmp
, GEN_INT (auxr
));
8579 tmp
= XEXP (operands
[0], 0);
8582 operands
[1] = force_reg (SImode
, operands
[1]);
8583 emit_insn (gen_rtx_UNSPEC_VOLATILE
8584 (VOIDmode
, gen_rtvec (2, operands
[1], tmp
),
8588 if (MEM_P (operands
[1]) && arc_is_aux_reg_p (operands
[1]))
8590 if (arc_get_aux_arg (operands
[1], &auxr
))
8592 tmp
= gen_reg_rtx (SImode
);
8593 emit_move_insn (tmp
, GEN_INT (auxr
));
8597 tmp
= XEXP (operands
[1], 0);
8598 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
8600 /* Load operation. */
8601 gcc_assert (REG_P (operands
[0]));
8602 emit_insn (gen_rtx_SET (operands
[0],
8603 gen_rtx_UNSPEC_VOLATILE
8604 (SImode
, gen_rtvec (1, tmp
),
8610 /* We used to do this only for MODE_INT Modes, but addresses to floating
8611 point variables may well be in the small data section. */
8612 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[0], Pmode
))
8613 operands
[0] = arc_rewrite_small_data (operands
[0]);
8615 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
8617 prepare_pic_move (operands
, SImode
);
8619 /* Disable any REG_EQUALs associated with the symref
8620 otherwise the optimization pass undoes the work done
8621 here and references the variable directly. */
8624 if (GET_CODE (operands
[0]) != MEM
8625 && !TARGET_NO_SDATA_SET
8626 && small_data_pattern (operands
[1], Pmode
))
8628 /* This is to take care of address calculations involving sdata
8630 operands
[1] = arc_rewrite_small_data (operands
[1]);
8632 emit_insn (gen_rtx_SET (operands
[0],operands
[1]));
8633 /* ??? This note is useless, since it only restates the set itself.
8634 We should rather use the original SYMBOL_REF. However, there is
8635 the problem that we are lying to the compiler about these
8636 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8637 so that we can tell it apart from an actual symbol. */
8638 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8640 /* Take care of the REG_EQUAL note that will be attached to mark the
8641 output reg equal to the initial symbol_ref after this code is
8643 emit_move_insn (operands
[0], operands
[0]);
8647 if (MEM_P (operands
[0])
8648 && !(reload_in_progress
|| reload_completed
))
8650 operands
[1] = force_reg (mode
, operands
[1]);
8651 if (!move_dest_operand (operands
[0], mode
))
8653 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
8654 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8655 except that we can't use that function because it is static. */
8656 rtx pat
= change_address (operands
[0], mode
, addr
);
8657 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8660 if (!cse_not_expected
)
8662 rtx pat
= XEXP (operands
[0], 0);
8664 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8667 pat
= change_address (operands
[0], mode
, pat
);
8668 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8674 if (MEM_P (operands
[1]) && !cse_not_expected
)
8676 rtx pat
= XEXP (operands
[1], 0);
8678 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8681 pat
= change_address (operands
[1], mode
, pat
);
8682 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
8690 /* Prepare OPERANDS for an extension using CODE to OMODE.
8691 Return true iff the move has been emitted. */
8694 prepare_extend_operands (rtx
*operands
, enum rtx_code code
,
8697 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[1], Pmode
))
8699 /* This is to take care of address calculations involving sdata
8702 = gen_rtx_fmt_e (code
, omode
, arc_rewrite_small_data (operands
[1]));
8703 emit_insn (gen_rtx_SET (operands
[0], operands
[1]));
8704 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8706 /* Take care of the REG_EQUAL note that will be attached to mark the
8707 output reg equal to the initial extension after this code is
8709 emit_move_insn (operands
[0], operands
[0]);
8715 /* Output a library call to a function called FNAME that has been arranged
8716 to be local to any dso. */
8719 arc_output_libcall (const char *fname
)
8721 unsigned len
= strlen (fname
);
8722 static char buf
[64];
8724 gcc_assert (len
< sizeof buf
- 35);
8725 if (TARGET_LONG_CALLS_SET
8726 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
8729 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
8731 sprintf (buf
, "jl%%! @%s", fname
);
8734 sprintf (buf
, "bl%%!%%* @%s", fname
);
8738 /* Return the SImode highpart of the DImode value IN. */
8741 disi_highpart (rtx in
)
8743 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
8746 /* Return length adjustment for INSN.
8748 A write to a core reg greater or equal to 32 must not be immediately
8749 followed by a use. Anticipate the length requirement to insert a nop
8750 between PRED and SUCC to prevent a hazard. */
8753 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8757 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8758 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
8759 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
8760 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
8761 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
8762 || recog_memoized (pred
) == CODE_FOR_umul_600
8763 || recog_memoized (pred
) == CODE_FOR_mac_600
8764 || recog_memoized (pred
) == CODE_FOR_mul64_600
8765 || recog_memoized (pred
) == CODE_FOR_mac64_600
8766 || recog_memoized (pred
) == CODE_FOR_umul64_600
8767 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
8769 subrtx_iterator::array_type array
;
8770 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
8772 const_rtx x
= *iter
;
8773 switch (GET_CODE (x
))
8775 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8778 /* This is also fine for PRE/POST_MODIFY, because they
8782 rtx dest
= XEXP (x
, 0);
8783 /* Check if this sets a an extension register. N.B. we use 61 for the
8784 condition codes, which is definitely not an extension register. */
8785 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
8786 /* Check if the same register is used by the PAT. */
8787 && (refers_to_regno_p
8789 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
8790 PATTERN (succ
), 0)))
8796 /* Given a rtx, check if it is an assembly instruction or not. */
8799 arc_asm_insn_p (rtx x
)
8806 switch (GET_CODE (x
))
8813 return arc_asm_insn_p (SET_SRC (x
));
8817 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8818 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
8831 A write to a core reg greater or equal to 32 must not be immediately
8832 followed by a use. Anticipate the length requirement to insert a nop
8833 between PRED and SUCC to prevent a hazard. */
8836 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8838 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
8842 return arc600_corereg_hazard (pred
, succ
);
8847 /* Return length adjustment for INSN. */
8850 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
8854 /* We already handle sequences by ignoring the delay sequence flag. */
8855 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8858 /* Check for return with but one preceding insn since function
8860 if (TARGET_PAD_RETURN
8862 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
8863 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
8864 && get_attr_type (insn
) == TYPE_RETURN
)
8866 rtx_insn
*prev
= prev_active_insn (insn
);
8868 if (!prev
|| !(prev
= prev_active_insn (prev
))
8869 || ((NONJUMP_INSN_P (prev
)
8870 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8871 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8873 : CALL_ATTR (prev
, NON_SIBCALL
)))
8878 rtx_insn
*succ
= next_real_insn (insn
);
8880 /* One the ARC600, a write to an extension register must be separated
8882 if (succ
&& INSN_P (succ
))
8883 len
+= arc600_corereg_hazard (insn
, succ
);
8886 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8888 extract_constrain_insn_cached (insn
);
8893 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8894 CC field of *STATEP. */
8897 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8899 rtx cond
= statep
->cond
;
8900 int raw_cc
= get_arc_condition_code (cond
);
8902 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8904 if (statep
->cc
== raw_cc
)
8905 return copy_rtx (cond
);
8907 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8909 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8910 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8911 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8912 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8914 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8915 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8918 /* Return version of PAT conditionalized with COND, which is part of INSN.
8919 ANNULLED indicates if INSN is an annulled delay-slot insn.
8920 Register further changes if necessary. */
8922 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8924 /* For commutative operators, we generally prefer to have
8925 the first source match the destination. */
8926 if (GET_CODE (pat
) == SET
)
8928 rtx src
= SET_SRC (pat
);
8930 if (COMMUTATIVE_P (src
))
8932 rtx src0
= XEXP (src
, 0);
8933 rtx src1
= XEXP (src
, 1);
8934 rtx dst
= SET_DEST (pat
);
8936 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8937 /* Leave add_n alone - the canonical form is to
8938 have the complex summand first. */
8940 pat
= gen_rtx_SET (dst
,
8941 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8946 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8947 what to do with COND_EXEC. */
8948 if (RTX_FRAME_RELATED_P (insn
))
8950 /* If this is the delay slot insn of an anulled branch,
8951 dwarf2out.c:scan_trace understands the anulling semantics
8952 without the COND_EXEC. */
8953 gcc_assert (annulled
);
8954 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8956 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8958 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8962 /* Use the ccfsm machinery to do if conversion. */
8967 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8969 memset (statep
, 0, sizeof *statep
);
8970 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8972 arc_ccfsm_advance (insn
, statep
);
8974 switch (statep
->state
)
8980 /* Deleted branch. */
8981 arc_ccfsm_post_advance (insn
, statep
);
8982 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8983 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8984 if (GET_CODE (PATTERN (seq
)) == SEQUENCE
)
8986 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8987 rtx pat
= PATTERN (slot
);
8988 if (INSN_ANNULLED_BRANCH_P (insn
))
8991 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8992 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8994 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8996 PUT_CODE (slot
, NOTE
);
8997 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
9001 set_insn_deleted (insn
);
9007 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
9009 arc_ccfsm_post_advance (insn
, statep
);
9010 if (--LABEL_NUSES (insn
) == 0)
9016 if (!NONDEBUG_INSN_P (insn
))
9019 /* Conditionalized insn. */
9021 rtx_insn
*prev
, *pprev
;
9022 rtx
*patp
, pat
, cond
;
9023 bool annulled
; annulled
= false;
9025 /* If this is a delay slot insn in a non-annulled branch,
9026 don't conditionalize it. N.B., this should be fine for
9027 conditional return too. However, don't do this for
9028 unconditional branches, as these would be encountered when
9029 processing an 'else' part. */
9030 prev
= PREV_INSN (insn
);
9031 pprev
= PREV_INSN (prev
);
9032 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
9033 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
9035 if (!INSN_ANNULLED_BRANCH_P (prev
))
9040 patp
= &PATTERN (insn
);
9042 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
9043 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
9045 /* ??? don't conditionalize if all side effects are dead
9046 in the not-execute case. */
9048 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
9050 else if (simplejump_p (insn
))
9052 patp
= &SET_SRC (pat
);
9053 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
9055 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
9057 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
9058 pat
= gen_rtx_SET (pc_rtx
, pat
);
9062 validate_change (insn
, patp
, pat
, 1);
9063 if (!apply_change_group ())
9067 rtx_insn
*next
= next_nonnote_insn (insn
);
9068 if (GET_CODE (next
) == BARRIER
)
9070 if (statep
->state
== 3)
9077 arc_ccfsm_post_advance (insn
, statep
);
9082 /* Find annulled delay insns and convert them to use the appropriate predicate.
9083 This allows branch shortening to size up these insns properly. */
9086 arc_predicate_delay_insns (void)
9088 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9090 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
9093 if (!NONJUMP_INSN_P (insn
)
9094 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
9096 jump
= XVECEXP (pat
, 0, 0);
9097 dlay
= XVECEXP (pat
, 0, 1);
9098 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
9100 /* If the branch insn does the annulling, leave the delay insn alone. */
9101 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
9103 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9104 on the other path. */
9105 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
9106 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
9107 src
= SET_SRC (PATTERN (jump
));
9108 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
9109 cond
= XEXP (src
, 0);
9110 if (XEXP (src
, 2) == pc_rtx
)
9112 else if (XEXP (src
, 1) == pc_rtx
)
9116 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
9118 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9119 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9120 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9121 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9123 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9124 copy_rtx (XEXP (cond
, 0)),
9125 copy_rtx (XEXP (cond
, 1)));
9128 cond
= copy_rtx (cond
);
9129 patp
= &PATTERN (dlay
);
9131 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9132 validate_change (dlay
, patp
, pat
, 1);
9133 if (!apply_change_group ())
9139 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9140 (other than of a forward brcc), it creates a hazard when there is a read
9141 of the same register at the branch target. We can't know what is at the
9142 branch target of calls, and for branches, we don't really know before the
9143 end of delay slot scheduling, either. Not only can individual instruction
9144 be hoisted out into a delay slot, a basic block can also be emptied this
9145 way, and branch and/or fall through targets be redirected. Hence we don't
9146 want such writes in a delay slot. */
9148 /* Return nonzreo iff INSN writes to an extension core register. */
9151 arc_write_ext_corereg (rtx insn
)
9153 subrtx_iterator::array_type array
;
9154 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9156 const_rtx x
= *iter
;
9157 switch (GET_CODE (x
))
9159 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9162 /* This is also fine for PRE/POST_MODIFY, because they
9166 const_rtx dest
= XEXP (x
, 0);
9167 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9173 /* This is like the hook, but returns NULL when it can't / won't generate
9174 a legitimate address. */
9177 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9182 if (flag_pic
&& SYMBOLIC_CONST (x
))
9183 (x
) = arc_legitimize_pic_address (x
, 0);
9185 if (GET_CODE (addr
) == CONST
)
9186 addr
= XEXP (addr
, 0);
9187 if (GET_CODE (addr
) == PLUS
9188 && CONST_INT_P (XEXP (addr
, 1))
9189 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9190 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9191 || (REG_P (XEXP (addr
, 0))
9192 && (INTVAL (XEXP (addr
, 1)) & 252))))
9194 HOST_WIDE_INT offs
, upper
;
9195 int size
= GET_MODE_SIZE (mode
);
9197 offs
= INTVAL (XEXP (addr
, 1));
9198 upper
= (offs
+ 256 * size
) & ~511 * size
;
9199 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9200 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9201 if (GET_CODE (x
) == CONST
)
9202 inner
= gen_rtx_CONST (Pmode
, inner
);
9204 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9207 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9208 x
= force_reg (Pmode
, x
);
9209 if (memory_address_p ((machine_mode
) mode
, x
))
9215 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9217 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9219 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9221 return arc_legitimize_tls_address (orig_x
, model
);
9224 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9232 arc_delegitimize_address_0 (rtx op
)
9234 switch (GET_CODE (op
))
9237 return arc_delegitimize_address_0 (XEXP (op
, 0));
9240 switch (XINT (op
, 1))
9242 case ARC_UNSPEC_GOT
:
9243 case ARC_UNSPEC_GOTOFFPC
:
9244 return XVECEXP (op
, 0, 0);
9252 rtx t1
= arc_delegitimize_address_0 (XEXP (op
, 0));
9253 rtx t2
= XEXP (op
, 1);
9256 return gen_rtx_PLUS (GET_MODE (op
), t1
, t2
);
9267 arc_delegitimize_address (rtx orig_x
)
9274 x
= arc_delegitimize_address_0 (x
);
9279 x
= replace_equiv_address_nv (orig_x
, x
);
9283 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9284 differ from the hardware register number in order to allow the generic
9285 code to correctly split the concatenation of acc1 and acc2. */
9290 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9293 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9294 differ from the hardware register number in order to allow the generic
9295 code to correctly split the concatenation of acc1 and acc2. */
9300 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9303 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9304 differ from the hardware register number in order to allow the generic
9305 code to correctly split the concatenation of mhi and mlo. */
9310 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9313 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9314 differ from the hardware register number in order to allow the generic
9315 code to correctly split the concatenation of mhi and mlo. */
9320 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9323 /* FIXME: a parameter should be added, and code added to final.c,
9324 to reproduce this functionality in shorten_branches. */
9326 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9327 a previous instruction. */
9329 arc_unalign_branch_p (rtx branch
)
9333 if (!TARGET_UNALIGN_BRANCH
)
9335 /* Do not do this if we have a filled delay slot. */
9336 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9337 && !NEXT_INSN (branch
)->deleted ())
9339 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9341 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9342 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9346 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9347 are three reasons why we need to consider branches to be length 6:
9348 - annull-false delay slot insns are implemented using conditional execution,
9349 thus preventing short insn formation where used.
9350 - for ARC600: annul-true delay slot insns are implemented where possible
9351 using conditional execution, preventing short insn formation where used.
9352 - for ARC700: likely or somewhat likely taken branches are made long and
9353 unaligned if possible to avoid branch penalty. */
9356 arc_branch_size_unknown_p (void)
9358 return !optimize_size
&& arc_reorg_in_progress
;
9361 /* We are about to output a return insn. Add padding if necessary to avoid
9362 a mispredict. A return could happen immediately after the function
9363 start, but after a call we know that there will be at least a blink
9367 arc_pad_return (void)
9369 rtx_insn
*insn
= current_output_insn
;
9370 rtx_insn
*prev
= prev_active_insn (insn
);
9375 fputs ("\tnop_s\n", asm_out_file
);
9376 cfun
->machine
->unalign
^= 2;
9379 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9380 because after a call, we'd have to restore blink first. */
9381 else if (GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9385 want_long
= (get_attr_length (prev
) == 2);
9386 prev
= prev_active_insn (prev
);
9389 || ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9390 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9392 : CALL_ATTR (prev
, NON_SIBCALL
)))
9395 cfun
->machine
->size_reason
9396 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9397 else if (TARGET_UNALIGN_BRANCH
&& cfun
->machine
->unalign
)
9399 cfun
->machine
->size_reason
9400 = "Long unaligned jump avoids non-delay slot penalty";
9403 /* Disgorge delay insn, if there is any, and it may be moved. */
9405 /* ??? Annulled would be OK if we can and do conditionalize
9406 the delay slot insn accordingly. */
9407 && !INSN_ANNULLED_BRANCH_P (insn
)
9408 && (get_attr_cond (insn
) != COND_USE
9409 || !reg_set_p (gen_rtx_REG (CCmode
, CC_REG
),
9410 XVECEXP (final_sequence
, 0, 1))))
9412 prev
= as_a
<rtx_insn
*> (XVECEXP (final_sequence
, 0, 1));
9413 gcc_assert (!prev_real_insn (insn
)
9414 || !arc_hazard (prev_real_insn (insn
), prev
));
9415 cfun
->machine
->force_short_suffix
= !want_long
;
9416 rtx save_pred
= current_insn_predicate
;
9417 final_scan_insn (prev
, asm_out_file
, optimize
, 1, NULL
);
9418 cfun
->machine
->force_short_suffix
= -1;
9419 prev
->set_deleted ();
9420 current_output_insn
= insn
;
9421 current_insn_predicate
= save_pred
;
9424 fputs ("\tnop\n", asm_out_file
);
9427 fputs ("\tnop_s\n", asm_out_file
);
9428 cfun
->machine
->unalign
^= 2;
9434 /* The usual; we set up our machine_function data. */
9436 static struct machine_function
*
9437 arc_init_machine_status (void)
9439 struct machine_function
*machine
;
9440 machine
= ggc_cleared_alloc
<machine_function
> ();
9441 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9442 machine
->force_short_suffix
= -1;
9447 /* Implements INIT_EXPANDERS. We just set up to call the above
9451 arc_init_expanders (void)
9453 init_machine_status
= arc_init_machine_status
;
9456 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9457 indicates a number of elements to ignore - that allows to have a
9458 sibcall pattern that starts with (return). LOAD_P is zero for store
9459 multiple (for prologues), and one for load multiples (for epilogues),
9460 and two for load multiples where no final clobber of blink is required.
9461 We also skip the first load / store element since this is supposed to
9462 be checked in the instruction pattern. */
9465 arc_check_millicode (rtx op
, int offset
, int load_p
)
9467 int len
= XVECLEN (op
, 0) - offset
;
9472 if (len
< 2 || len
> 13)
9478 rtx elt
= XVECEXP (op
, 0, --len
);
9480 if (GET_CODE (elt
) != CLOBBER
9481 || !REG_P (XEXP (elt
, 0))
9482 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9483 || len
< 3 || len
> 13)
9486 for (i
= 1; i
< len
; i
++)
9488 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9491 if (GET_CODE (elt
) != SET
)
9493 mem
= XEXP (elt
, load_p
);
9494 reg
= XEXP (elt
, 1-load_p
);
9495 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9497 addr
= XEXP (mem
, 0);
9498 if (GET_CODE (addr
) != PLUS
9499 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9500 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9506 /* Accessor functions for cfun->machine->unalign. */
9509 arc_get_unalign (void)
9511 return cfun
->machine
->unalign
;
9515 arc_clear_unalign (void)
9518 cfun
->machine
->unalign
= 0;
9522 arc_toggle_unalign (void)
9524 cfun
->machine
->unalign
^= 2;
9527 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9528 constant in operand 2, but which would require a LIMM because of
9530 operands 3 and 4 are new SET_SRCs for operands 0. */
9533 split_addsi (rtx
*operands
)
9535 int val
= INTVAL (operands
[2]);
9537 /* Try for two short insns first. Lengths being equal, we prefer
9538 expansions with shorter register lifetimes. */
9539 if (val
> 127 && val
<= 255
9540 && satisfies_constraint_Rcq (operands
[0]))
9542 operands
[3] = operands
[2];
9543 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9547 operands
[3] = operands
[1];
9548 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9552 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9553 constant in operand 1, but which would require a LIMM because of
9555 operands 3 and 4 are new SET_SRCs for operands 0. */
9558 split_subsi (rtx
*operands
)
9560 int val
= INTVAL (operands
[1]);
9562 /* Try for two short insns first. Lengths being equal, we prefer
9563 expansions with shorter register lifetimes. */
9564 if (satisfies_constraint_Rcq (operands
[0])
9565 && satisfies_constraint_Rcq (operands
[2]))
9567 if (val
>= -31 && val
<= 127)
9569 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9570 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9573 else if (val
>= 0 && val
< 255)
9575 operands
[3] = operands
[1];
9576 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9580 /* If the destination is not an ARCompact16 register, we might
9581 still have a chance to make a short insn if the source is;
9582 we need to start with a reg-reg move for this. */
9583 operands
[3] = operands
[2];
9584 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9587 /* Handle DOUBLE_REGS uses.
9588 Operand 0: destination register
9589 Operand 1: source register */
9592 arc_process_double_reg_moves (rtx
*operands
)
9594 rtx dest
= operands
[0];
9595 rtx src
= operands
[1];
9597 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9598 enum usesDxState state
= none
;
9600 if (refers_to_regno_p (40, 44, src
, 0))
9602 if (refers_to_regno_p (40, 44, dest
, 0))
9604 /* Via arc_register_move_cost, we should never see D,D moves. */
9605 gcc_assert (state
== none
);
9614 /* Without the LR insn, we need to split this into a
9615 sequence of insns which will use the DEXCLx and DADDHxy
9616 insns to be able to read the Dx register in question. */
9617 if (TARGET_DPFP_DISABLE_LRSR
)
9619 /* gen *movdf_insn_nolrsr */
9620 rtx set
= gen_rtx_SET (dest
, src
);
9621 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9622 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9626 /* When we have 'mov D, r' or 'mov D, D' then get the target
9627 register pair for use with LR insn. */
9628 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9629 TARGET_BIG_ENDIAN
? 0 : 4);
9630 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9631 TARGET_BIG_ENDIAN
? 4 : 0);
9633 /* Produce the two LR insns to get the high and low parts. */
9634 emit_insn (gen_rtx_SET (destHigh
,
9635 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9637 VUNSPEC_ARC_LR_HIGH
)));
9638 emit_insn (gen_rtx_SET (destLow
,
9639 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9644 else if (state
== destDx
)
9646 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9647 LR insn get the target register pair. */
9648 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9649 TARGET_BIG_ENDIAN
? 0 : 4);
9650 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9651 TARGET_BIG_ENDIAN
? 4 : 0);
9653 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9661 /* operands 0..1 are the operands of a 64 bit move instruction.
9662 split it into two moves with operands 2/3 and 4/5. */
9665 arc_split_move (rtx
*operands
)
9667 machine_mode mode
= GET_MODE (operands
[0]);
9674 if (arc_process_double_reg_moves (operands
))
9679 && ((memory_operand (operands
[0], mode
)
9680 && even_register_operand (operands
[1], mode
))
9681 || (memory_operand (operands
[1], mode
)
9682 && even_register_operand (operands
[0], mode
))))
9684 emit_move_insn (operands
[0], operands
[1]);
9688 if (TARGET_PLUS_QMACW
9689 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9691 HOST_WIDE_INT intval0
, intval1
;
9692 if (GET_MODE (operands
[1]) == V2SImode
)
9694 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9695 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9699 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9700 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9701 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9702 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9704 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9705 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9706 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9707 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9708 emit_move_insn (xop
[0], xop
[2]);
9709 emit_move_insn (xop
[3], xop
[1]);
9713 for (i
= 0; i
< 2; i
++)
9715 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9717 rtx addr
= XEXP (operands
[i
], 0);
9721 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9722 switch (GET_CODE (addr
))
9724 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9725 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9726 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9730 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9731 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9732 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9741 xop
[0+i
] = adjust_automodify_address_nv
9742 (operands
[i
], SImode
,
9743 gen_rtx_fmt_ee (code
, Pmode
, r
,
9744 gen_rtx_PLUS (Pmode
, r
, o
)),
9746 xop
[2+i
] = adjust_automodify_address_nv
9747 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9751 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9752 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9755 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9758 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9761 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9762 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9766 /* Select between the instruction output templates s_tmpl (for short INSNs)
9767 and l_tmpl (for long INSNs). */
9770 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9772 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9774 extract_constrain_insn_cached (insn
);
9775 return is_short
? s_tmpl
: l_tmpl
;
9778 /* Searches X for any reference to REGNO, returning the rtx of the
9779 reference found if any. Otherwise, returns NULL_RTX. */
9782 arc_regno_use_in (unsigned int regno
, rtx x
)
9788 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9791 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9792 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9796 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9799 else if (fmt
[i
] == 'E')
9800 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9801 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9808 /* Return the integer value of the "type" attribute for INSN, or -1 if
9809 INSN can't have attributes. */
9812 arc_attr_type (rtx_insn
*insn
)
9814 if (NONJUMP_INSN_P (insn
)
9815 ? (GET_CODE (PATTERN (insn
)) == USE
9816 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9818 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9819 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9822 return get_attr_type (insn
);
9825 /* Return true if insn sets the condition codes. */
9828 arc_sets_cc_p (rtx_insn
*insn
)
9830 if (NONJUMP_INSN_P (insn
))
9831 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9832 insn
= seq
->insn (seq
->len () - 1);
9833 return arc_attr_type (insn
) == TYPE_COMPARE
;
9836 /* Return true if INSN is an instruction with a delay slot we may want
9840 arc_need_delay (rtx_insn
*insn
)
9844 if (!flag_delayed_branch
)
9846 /* The return at the end of a function needs a delay slot. */
9847 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9848 && (!(next
= next_active_insn (insn
))
9849 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9850 && arc_attr_type (next
) == TYPE_RETURN
))
9851 && (!TARGET_PAD_RETURN
9852 || (prev_active_insn (insn
)
9853 && prev_active_insn (prev_active_insn (insn
))
9854 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9856 if (NONJUMP_INSN_P (insn
)
9857 ? (GET_CODE (PATTERN (insn
)) == USE
9858 || GET_CODE (PATTERN (insn
)) == CLOBBER
9859 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9861 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9862 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9865 return num_delay_slots (insn
) != 0;
9868 /* Return true if the scheduling pass(es) has/have already run,
9869 i.e. where possible, we should try to mitigate high latencies
9870 by different instruction selection. */
9873 arc_scheduling_not_expected (void)
9875 return cfun
->machine
->arc_reorg_started
;
9879 arc_label_align (rtx_insn
*label
)
9881 /* Code has a minimum p2 alignment of 1, which we must restore after an
9883 if (align_labels_log
< 1)
9885 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9886 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9889 return align_labels_log
;
9892 /* Return true if LABEL is in executable code. */
9895 arc_text_label (rtx_insn
*label
)
9899 /* ??? We use deleted labels like they were still there, see
9900 gcc.c-torture/compile/20000326-2.c . */
9901 gcc_assert (GET_CODE (label
) == CODE_LABEL
9902 || (GET_CODE (label
) == NOTE
9903 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9904 next
= next_nonnote_insn (label
);
9906 return (!JUMP_TABLE_DATA_P (next
)
9907 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9908 else if (!PREV_INSN (label
))
9909 /* ??? sometimes text labels get inserted very late, see
9910 gcc.dg/torture/stackalign/comp-goto-1.c */
9915 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9916 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9917 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9918 to redirect two breqs. */
9921 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9923 /* ??? get_attr_type is declared to take an rtx. */
9924 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9927 if (CROSSING_JUMP_P (followee
))
9928 switch (get_attr_type (u
.r
))
9931 if (get_attr_length (u
.r
) != 2)
9935 case TYPE_BRCC_NO_DELAY_SLOT
:
9943 /* Return the register number of the register holding the return address
9944 for a function of type TYPE. */
9947 arc_return_address_register (unsigned int fn_type
)
9951 if (ARC_INTERRUPT_P (fn_type
))
9953 if (((fn_type
& ARC_FUNCTION_ILINK1
) | ARC_FUNCTION_FIRQ
) != 0)
9954 regno
= ILINK1_REGNUM
;
9955 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
9956 regno
= ILINK2_REGNUM
;
9960 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
9961 regno
= RETURN_ADDR_REGNUM
;
9963 gcc_assert (regno
!= 0);
9967 /* Implement EPILOGUE_USES.
9968 Return true if REGNO should be added to the deemed uses of the epilogue.
9970 We have to make sure all the register restore instructions are
9971 known to be live in interrupt functions, plus the blink register if
9972 it is clobbered by the isr. */
9975 arc_epilogue_uses (int regno
)
9977 unsigned int fn_type
;
9979 if (regno
== arc_tp_regno
)
9982 fn_type
= arc_compute_function_type (cfun
);
9983 if (reload_completed
)
9985 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9987 if (!fixed_regs
[regno
])
9989 return ((regno
== arc_return_address_register (fn_type
))
9990 || (regno
== RETURN_ADDR_REGNUM
));
9993 return regno
== RETURN_ADDR_REGNUM
;
9996 return regno
== arc_return_address_register (fn_type
);
9999 /* Helper for EH_USES macro. */
10002 arc_eh_uses (int regno
)
10004 if (regno
== arc_tp_regno
)
10009 #ifndef TARGET_NO_LRA
10010 #define TARGET_NO_LRA !TARGET_LRA
10016 return !TARGET_NO_LRA
;
10019 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10020 Rcq registers, because some insn are shorter with them. OTOH we already
10021 have separate alternatives for this purpose, and other insns don't
10022 mind, so maybe we should rather prefer the other registers?
10023 We need more data, and we can only get that if we allow people to
10024 try all options. */
10026 arc_register_priority (int r
)
10028 switch (arc_lra_priority_tag
)
10030 case ARC_LRA_PRIORITY_NONE
:
10032 case ARC_LRA_PRIORITY_NONCOMPACT
:
10033 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
10034 case ARC_LRA_PRIORITY_COMPACT
:
10035 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
10037 gcc_unreachable ();
10042 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
10044 return GENERAL_REGS
;
10048 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
10052 enum reload_type type
= (enum reload_type
) itype
;
10054 if (GET_CODE (x
) == PLUS
10055 && CONST_INT_P (XEXP (x
, 1))
10056 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
10057 || (REG_P (XEXP (x
, 0))
10058 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
10060 int scale
= GET_MODE_SIZE (mode
);
10062 rtx index_rtx
= XEXP (x
, 1);
10063 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
10064 rtx reg
, sum
, sum2
;
10068 if ((scale
-1) & offset
)
10070 shift
= scale
>> 1;
10072 = ((offset
+ (256 << shift
))
10073 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
10074 /* Sometimes the normal form does not suit DImode. We
10075 could avoid that by using smaller ranges, but that
10076 would give less optimized code when SImode is
10078 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
10083 regno
= REGNO (reg
);
10084 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
10086 if (reg_equiv_constant (regno
))
10088 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
10090 if (GET_CODE (sum2
) == PLUS
)
10091 sum2
= gen_rtx_CONST (Pmode
, sum2
);
10093 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
10094 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
10095 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
10100 /* We must re-recognize what we created before. */
10101 else if (GET_CODE (x
) == PLUS
10102 && GET_CODE (XEXP (x
, 0)) == PLUS
10103 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
10104 && REG_P (XEXP (XEXP (x
, 0), 0))
10105 && CONST_INT_P (XEXP (x
, 1)))
10107 /* Because this address is so complex, we know it must have
10108 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10109 it is already unshared, and needs no further unsharing. */
10110 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
10111 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
10117 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10120 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
10121 unsigned int align
,
10122 enum by_pieces_operation op
,
10125 /* Let the movmem expander handle small block moves. */
10126 if (op
== MOVE_BY_PIECES
)
10129 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
10132 /* Emit a (pre) memory barrier around an atomic sequence according to
10136 arc_pre_atomic_barrier (enum memmodel model
)
10138 if (need_atomic_barrier_p (model
, true))
10139 emit_insn (gen_memory_barrier ());
10142 /* Emit a (post) memory barrier around an atomic sequence according to
10146 arc_post_atomic_barrier (enum memmodel model
)
10148 if (need_atomic_barrier_p (model
, false))
10149 emit_insn (gen_memory_barrier ());
10152 /* Expand a compare and swap pattern. */
10155 emit_unlikely_jump (rtx insn
)
10157 rtx_insn
*jump
= emit_jump_insn (insn
);
10158 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10161 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10162 32-bit compare and swap on the word containing the byte or
10163 half-word. The difference between a weak and a strong CAS is that
10164 the weak version may simply fail. The strong version relies on two
10165 loops, one checks if the SCOND op is succsfully or not, the other
10166 checks if the 32 bit accessed location which contains the 8 or 16
10167 bit datum is not changed by other thread. The first loop is
10168 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10169 loops is implemented by this routine. */
10172 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10173 rtx oldval
, rtx newval
, rtx weak
,
10174 rtx mod_s
, rtx mod_f
)
10176 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10177 rtx addr
= gen_reg_rtx (Pmode
);
10178 rtx off
= gen_reg_rtx (SImode
);
10179 rtx oldv
= gen_reg_rtx (SImode
);
10180 rtx newv
= gen_reg_rtx (SImode
);
10181 rtx oldvalue
= gen_reg_rtx (SImode
);
10182 rtx newvalue
= gen_reg_rtx (SImode
);
10183 rtx res
= gen_reg_rtx (SImode
);
10184 rtx resv
= gen_reg_rtx (SImode
);
10185 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10187 bool is_weak
= (weak
!= const0_rtx
);
10189 /* Truncate the address. */
10190 emit_insn (gen_rtx_SET (addr
,
10191 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10193 /* Compute the datum offset. */
10194 emit_insn (gen_rtx_SET (off
,
10195 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10196 if (TARGET_BIG_ENDIAN
)
10197 emit_insn (gen_rtx_SET (off
,
10198 gen_rtx_MINUS (SImode
,
10199 (GET_MODE (mem
) == QImode
) ?
10200 GEN_INT (3) : GEN_INT (2), off
)));
10202 /* Normal read from truncated address. */
10203 memsi
= gen_rtx_MEM (SImode
, addr
);
10204 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10205 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10207 val
= copy_to_reg (memsi
);
10209 /* Convert the offset in bits. */
10210 emit_insn (gen_rtx_SET (off
,
10211 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10213 /* Get the proper mask. */
10214 if (GET_MODE (mem
) == QImode
)
10215 mask
= force_reg (SImode
, GEN_INT (0xff));
10217 mask
= force_reg (SImode
, GEN_INT (0xffff));
10219 emit_insn (gen_rtx_SET (mask
,
10220 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10222 /* Prepare the old and new values. */
10223 emit_insn (gen_rtx_SET (val
,
10224 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10227 oldval
= gen_lowpart (SImode
, oldval
);
10228 emit_insn (gen_rtx_SET (oldv
,
10229 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10231 newval
= gen_lowpart_common (SImode
, newval
);
10232 emit_insn (gen_rtx_SET (newv
,
10233 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10235 emit_insn (gen_rtx_SET (oldv
,
10236 gen_rtx_AND (SImode
, oldv
, mask
)));
10238 emit_insn (gen_rtx_SET (newv
,
10239 gen_rtx_AND (SImode
, newv
, mask
)));
10243 end_label
= gen_label_rtx ();
10244 loop_label
= gen_label_rtx ();
10245 emit_label (loop_label
);
10248 /* Make the old and new values. */
10249 emit_insn (gen_rtx_SET (oldvalue
,
10250 gen_rtx_IOR (SImode
, oldv
, val
)));
10252 emit_insn (gen_rtx_SET (newvalue
,
10253 gen_rtx_IOR (SImode
, newv
, val
)));
10255 /* Try an 32bit atomic compare and swap. It clobbers the CC
10257 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10258 weak
, mod_s
, mod_f
));
10260 /* Regardless of the weakness of the operation, a proper boolean
10261 result needs to be provided. */
10262 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10263 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10264 emit_insn (gen_rtx_SET (bool_result
, x
));
10268 /* Check the results: if the atomic op is successfully the goto
10270 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10271 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10272 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10273 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10274 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10276 /* Wait for the right moment when the accessed 32-bit location
10278 emit_insn (gen_rtx_SET (resv
,
10279 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10281 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10282 cc
= gen_rtx_REG (mode
, CC_REG
);
10283 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10285 /* Set the new value of the 32 bit location, proper masked. */
10286 emit_insn (gen_rtx_SET (val
, resv
));
10288 /* Try again if location is unstable. Fall through if only
10289 scond op failed. */
10290 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10291 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10292 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10293 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10295 emit_label (end_label
);
10298 /* End: proper return the result for the given mode. */
10299 emit_insn (gen_rtx_SET (res
,
10300 gen_rtx_AND (SImode
, res
, mask
)));
10302 emit_insn (gen_rtx_SET (res
,
10303 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10305 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10308 /* Helper function used by "atomic_compare_and_swap" expand
10312 arc_expand_compare_and_swap (rtx operands
[])
10314 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10317 bval
= operands
[0];
10318 rval
= operands
[1];
10320 oldval
= operands
[3];
10321 newval
= operands
[4];
10322 is_weak
= operands
[5];
10323 mod_s
= operands
[6];
10324 mod_f
= operands
[7];
10325 mode
= GET_MODE (mem
);
10327 if (reg_overlap_mentioned_p (rval
, oldval
))
10328 oldval
= copy_to_reg (oldval
);
10330 if (mode
== SImode
)
10332 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10333 is_weak
, mod_s
, mod_f
));
10334 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10335 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10336 emit_insn (gen_rtx_SET (bval
, x
));
10340 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10341 is_weak
, mod_s
, mod_f
);
10345 /* Helper function used by the "atomic_compare_and_swapsi_1"
10349 arc_split_compare_and_swap (rtx operands
[])
10351 rtx rval
, mem
, oldval
, newval
;
10353 enum memmodel mod_s
, mod_f
;
10355 rtx label1
, label2
, x
, cond
;
10357 rval
= operands
[0];
10359 oldval
= operands
[2];
10360 newval
= operands
[3];
10361 is_weak
= (operands
[4] != const0_rtx
);
10362 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10363 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10364 mode
= GET_MODE (mem
);
10366 /* ARC atomic ops work only with 32-bit aligned memories. */
10367 gcc_assert (mode
== SImode
);
10369 arc_pre_atomic_barrier (mod_s
);
10374 label1
= gen_label_rtx ();
10375 emit_label (label1
);
10377 label2
= gen_label_rtx ();
10379 /* Load exclusive. */
10380 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10382 /* Check if it is oldval. */
10383 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10384 cond
= gen_rtx_REG (mode
, CC_REG
);
10385 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10387 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10388 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10389 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10390 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10392 /* Exclusively store new item. Store clobbers CC reg. */
10393 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10397 /* Check the result of the store. */
10398 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10399 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10400 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10401 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10402 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10405 if (mod_f
!= MEMMODEL_RELAXED
)
10406 emit_label (label2
);
10408 arc_post_atomic_barrier (mod_s
);
10410 if (mod_f
== MEMMODEL_RELAXED
)
10411 emit_label (label2
);
10414 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10415 to perform. MEM is the memory on which to operate. VAL is the second
10416 operand of the binary operator. BEFORE and AFTER are optional locations to
10417 return the value of MEM either before of after the operation. MODEL_RTX
10418 is a CONST_INT containing the memory model to use. */
10421 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10422 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10424 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10425 machine_mode mode
= GET_MODE (mem
);
10426 rtx label
, x
, cond
;
10427 rtx before
= orig_before
, after
= orig_after
;
10429 /* ARC atomic ops work only with 32-bit aligned memories. */
10430 gcc_assert (mode
== SImode
);
10432 arc_pre_atomic_barrier (model
);
10434 label
= gen_label_rtx ();
10435 emit_label (label
);
10436 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10438 if (before
== NULL_RTX
)
10439 before
= gen_reg_rtx (mode
);
10441 if (after
== NULL_RTX
)
10442 after
= gen_reg_rtx (mode
);
10444 /* Load exclusive. */
10445 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10450 x
= gen_rtx_AND (mode
, before
, val
);
10451 emit_insn (gen_rtx_SET (after
, x
));
10452 x
= gen_rtx_NOT (mode
, after
);
10453 emit_insn (gen_rtx_SET (after
, x
));
10457 if (CONST_INT_P (val
))
10459 val
= GEN_INT (-INTVAL (val
));
10465 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10466 emit_insn (gen_rtx_SET (after
, x
));
10470 /* Exclusively store new item. Store clobbers CC reg. */
10471 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10473 /* Check the result of the store. */
10474 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10475 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10476 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10478 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10480 arc_post_atomic_barrier (model
);
10483 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10486 arc_no_speculation_in_delay_slots_p ()
10491 /* Return a parallel of registers to represent where to find the
10492 register pieces if required, otherwise NULL_RTX. */
10495 arc_dwarf_register_span (rtx rtl
)
10497 machine_mode mode
= GET_MODE (rtl
);
10501 if (GET_MODE_SIZE (mode
) != 8)
10504 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10505 regno
= REGNO (rtl
);
10506 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10507 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10512 /* Return true if OP is an acceptable memory operand for ARCompact
10513 16-bit load instructions of MODE.
10515 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10516 non scaled instructions.
10518 SCALED: TRUE if address can be scaled. */
10521 compact_memory_operand_p (rtx op
, machine_mode mode
,
10522 bool av2short
, bool scaled
)
10524 rtx addr
, plus0
, plus1
;
10527 /* Eliminate non-memory operations. */
10528 if (GET_CODE (op
) != MEM
)
10531 /* .di instructions have no 16-bit form. */
10532 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10535 if (mode
== VOIDmode
)
10536 mode
= GET_MODE (op
);
10538 size
= GET_MODE_SIZE (mode
);
10540 /* dword operations really put out 2 instructions, so eliminate
10542 if (size
> UNITS_PER_WORD
)
10545 /* Decode the address now. */
10546 addr
= XEXP (op
, 0);
10547 switch (GET_CODE (addr
))
10550 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10551 || COMPACT_GP_REG_P (REGNO (addr
))
10552 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10554 plus0
= XEXP (addr
, 0);
10555 plus1
= XEXP (addr
, 1);
10557 if ((GET_CODE (plus0
) == REG
)
10558 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10559 || COMPACT_GP_REG_P (REGNO (plus0
)))
10560 && ((GET_CODE (plus1
) == REG
)
10561 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10562 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10567 if ((GET_CODE (plus0
) == REG
)
10568 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10569 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10570 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10571 && (GET_CODE (plus1
) == CONST_INT
))
10573 bool valid
= false;
10575 off
= INTVAL (plus1
);
10577 /* Negative offset is not supported in 16-bit load/store insns. */
10581 /* Only u5 immediates allowed in code density instructions. */
10589 /* This is an ldh_s.x instruction, check the u6
10591 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10595 /* Only u5 immediates allowed in 32bit access code
10596 density instructions. */
10597 if (REGNO (plus0
) <= 31)
10598 return ((off
< 32) && (off
% 4 == 0));
10605 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10616 /* The 6-bit constant get shifted to fit the real
10617 5-bits field. Check also for the alignment. */
10618 return ((off
< 64) && (off
% 2 == 0));
10620 return ((off
< 128) && (off
% 4 == 0));
10627 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10628 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10629 || SP_REG_P (REGNO (plus0
)))
10632 off
= INTVAL (plus1
);
10633 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10636 if ((GET_CODE (plus0
) == MULT
)
10637 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10638 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10639 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10640 && (GET_CODE (plus1
) == REG
)
10641 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10642 || COMPACT_GP_REG_P (REGNO (plus1
))))
10646 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10647 for 16-bit load instructions. */
10652 /* Return the frame pointer value to be backed up in the setjmp buffer. */
10655 arc_builtin_setjmp_frame_value (void)
10657 /* We always want to preserve whatever value is currently in the frame
10658 pointer register. For frames that are using the frame pointer the new
10659 value of the frame pointer register will have already been computed
10660 (as part of the prologue). For frames that are not using the frame
10661 pointer it is important that we backup whatever value is in the frame
10662 pointer register, as earlier (more outer) frames may have placed a
10663 value into the frame pointer register. It might be tempting to try
10664 and use `frame_pointer_rtx` here, however, this is not what we want.
10665 For frames that are using the frame pointer this will give the
10666 correct value. However, for frames that are not using the frame
10667 pointer this will still give the value that _would_ have been the
10668 frame pointer value for this frame (if the use of the frame pointer
10669 had not been removed). We really do want the raw frame pointer
10671 return gen_raw_REG (Pmode
, FRAME_POINTER_REGNUM
);
10674 /* Return nonzero if a jli call should be generated for a call from
10675 the current function to DECL. */
10678 arc_is_jli_call_p (rtx pat
)
10681 tree decl
= SYMBOL_REF_DECL (pat
);
10683 /* If it is not a well defined public function then return false. */
10684 if (!decl
|| !SYMBOL_REF_FUNCTION_P (pat
) || !TREE_PUBLIC (decl
))
10687 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
10688 if (lookup_attribute ("jli_always", attrs
))
10691 if (lookup_attribute ("jli_fixed", attrs
))
10694 return TARGET_JLI_ALWAYS
;
10697 /* Handle and "jli" attribute; arguments as in struct
10698 attribute_spec.handler. */
10701 arc_handle_jli_attribute (tree
*node ATTRIBUTE_UNUSED
,
10702 tree name
, tree args
, int,
10703 bool *no_add_attrs
)
10707 warning (OPT_Wattributes
,
10708 "%qE attribute only valid for ARCv2 architecture",
10710 *no_add_attrs
= true;
10713 if (args
== NULL_TREE
)
10715 warning (OPT_Wattributes
,
10716 "argument of %qE attribute is missing",
10718 *no_add_attrs
= true;
10722 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10723 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10724 tree arg
= TREE_VALUE (args
);
10725 if (TREE_CODE (arg
) != INTEGER_CST
)
10727 warning (0, "%qE attribute allows only an integer constant argument",
10729 *no_add_attrs
= true;
10731 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10736 /* Handle and "scure" attribute; arguments as in struct
10737 attribute_spec.handler. */
10740 arc_handle_secure_attribute (tree
*node ATTRIBUTE_UNUSED
,
10741 tree name
, tree args
, int,
10742 bool *no_add_attrs
)
10746 warning (OPT_Wattributes
,
10747 "%qE attribute only valid for ARC EM architecture",
10749 *no_add_attrs
= true;
10752 if (args
== NULL_TREE
)
10754 warning (OPT_Wattributes
,
10755 "argument of %qE attribute is missing",
10757 *no_add_attrs
= true;
10761 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10762 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10763 tree arg
= TREE_VALUE (args
);
10764 if (TREE_CODE (arg
) != INTEGER_CST
)
10766 warning (0, "%qE attribute allows only an integer constant argument",
10768 *no_add_attrs
= true;
10774 /* Return nonzero if the symbol is a secure function. */
10777 arc_is_secure_call_p (rtx pat
)
10780 tree decl
= SYMBOL_REF_DECL (pat
);
10785 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
10786 if (lookup_attribute ("secure_call", attrs
))
10792 /* Handle "uncached" qualifier. */
10795 arc_handle_uncached_attribute (tree
*node
,
10796 tree name
, tree args
,
10797 int flags ATTRIBUTE_UNUSED
,
10798 bool *no_add_attrs
)
10800 if (DECL_P (*node
) && TREE_CODE (*node
) != TYPE_DECL
)
10802 error ("%qE attribute only applies to types",
10804 *no_add_attrs
= true;
10808 warning (OPT_Wattributes
, "argument of %qE attribute ignored", name
);
10813 /* Return TRUE if PAT is a memory addressing an uncached data. */
10816 arc_is_uncached_mem_p (rtx pat
)
10820 struct mem_attrs
*refattrs
;
10825 /* Get the memory attributes. */
10826 refattrs
= MEM_ATTRS (pat
);
10828 || !refattrs
->expr
)
10831 /* Get the type declaration. */
10832 ttype
= TREE_TYPE (refattrs
->expr
);
10836 /* Get the type attributes. */
10837 attrs
= TYPE_ATTRIBUTES (ttype
);
10838 if (lookup_attribute ("uncached", attrs
))
10843 /* Handle aux attribute. The auxiliary registers are addressed using
10844 special instructions lr and sr. The attribute 'aux' indicates if a
10845 variable refers to the aux-regs and what is the register number
10849 arc_handle_aux_attribute (tree
*node
,
10850 tree name
, tree args
, int,
10851 bool *no_add_attrs
)
10853 /* Isn't it better to use address spaces for the aux-regs? */
10854 if (DECL_P (*node
))
10856 if (TREE_CODE (*node
) != VAR_DECL
)
10858 error ("%qE attribute only applies to variables", name
);
10859 *no_add_attrs
= true;
10863 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10864 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10865 tree arg
= TREE_VALUE (args
);
10866 if (TREE_CODE (arg
) != INTEGER_CST
)
10868 warning (0, "%qE attribute allows only an integer "
10869 "constant argument", name
);
10870 *no_add_attrs
= true;
10872 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10875 if (TREE_CODE (*node
) == VAR_DECL
)
10877 tree fntype
= TREE_TYPE (*node
);
10878 if (fntype
&& TREE_CODE (fntype
) == POINTER_TYPE
)
10880 tree attrs
= tree_cons (get_identifier ("aux"), NULL_TREE
,
10881 TYPE_ATTRIBUTES (fntype
));
10882 TYPE_ATTRIBUTES (fntype
) = attrs
;
10889 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10890 anchors for small data: the GP register acts as an anchor in that
10891 case. We also don't want to use them for PC-relative accesses,
10892 where the PC acts as an anchor. Prohibit also TLS symbols to use
10896 arc_use_anchors_for_symbol_p (const_rtx symbol
)
10898 if (SYMBOL_REF_TLS_MODEL (symbol
))
10904 if (SYMBOL_REF_SMALL_P (symbol
))
10907 return default_use_anchors_for_symbol_p (symbol
);
10910 /* Return true if SUBST can't safely replace its equivalent during RA. */
10912 arc_cannot_substitute_mem_equiv_p (rtx
)
10914 /* If SUBST is mem[base+index], the address may not fit ISA,
10915 thus return true. */
10919 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
10920 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
10922 #undef TARGET_CONSTANT_ALIGNMENT
10923 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
10925 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
10926 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
10928 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10929 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
10931 struct gcc_target targetm
= TARGET_INITIALIZER
;
10933 #include "gt-arc.h"