1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2017 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
33 #include "coretypes.h"
42 #include "stringpool.h"
47 #include "diagnostic.h"
48 #include "fold-const.h"
50 #include "stor-layout.h"
53 #include "insn-attr.h"
57 #include "langhooks.h"
58 #include "tm-constrs.h"
59 #include "reload.h" /* For operands_match_p */
61 #include "tree-pass.h"
68 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
69 static char arc_cpu_name
[10] = "";
70 static const char *arc_cpu_string
= arc_cpu_name
;
72 /* ??? Loads can handle any constant, stores can only handle small ones. */
73 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
74 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
75 (GET_CODE (X) == CONST_INT \
76 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
77 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
79 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
81 #define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
82 (GET_CODE (X) == PLUS \
83 && GET_CODE (XEXP (X, 0)) == MULT \
84 && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
85 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
86 && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
87 || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
88 && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
89 || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
91 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
92 (GET_CODE (X) == PLUS \
93 && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
94 && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
95 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
96 || (GET_CODE (XEXP ((X), 1)) == CONST \
97 && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
98 && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
99 && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
100 && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
102 /* Array of valid operand punctuation characters. */
103 char arc_punct_chars
[256];
105 /* State used by arc_ccfsm_advance to implement conditional execution. */
106 struct GTY (()) arc_ccfsm
111 rtx_insn
*target_insn
;
115 /* Status of the IRQ_CTRL_AUX register. */
116 typedef struct irq_ctrl_saved_t
118 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
119 short irq_save_last_reg
;
120 /* True if BLINK is automatically saved. */
122 /* True if LPCOUNT is automatically saved. */
123 bool irq_save_lpcount
;
125 static irq_ctrl_saved_t irq_ctrl_saved
;
127 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
128 ((ARC_INTERRUPT_P (FNTYPE) \
129 && irq_ctrl_saved.irq_save_blink) \
130 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
131 && rgf_banked_register_count > 8))
133 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
134 ((ARC_INTERRUPT_P (FNTYPE) \
135 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
136 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
137 && rgf_banked_register_count > 8))
139 #define ARC_AUTO_IRQ_P(FNTYPE) \
140 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
141 && (irq_ctrl_saved.irq_save_blink \
142 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
144 /* Number of registers in second bank for FIRQ support. */
145 static int rgf_banked_register_count
;
147 #define arc_ccfsm_current cfun->machine->ccfsm_current
149 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
150 ((STATE)->state == 1 || (STATE)->state == 2)
152 /* Indicate we're conditionalizing insns now. */
153 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
154 ((STATE)->state += 2)
156 #define ARC_CCFSM_COND_EXEC_P(STATE) \
157 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
158 || current_insn_predicate)
160 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
161 #define CCFSM_ISCOMPACT(INSN,STATE) \
162 (ARC_CCFSM_COND_EXEC_P (STATE) \
163 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
164 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
165 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
167 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
168 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
169 ((ARC_CCFSM_COND_EXEC_P (STATE) \
171 && INSN_ANNULLED_BRANCH_P (JUMP) \
172 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
173 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
174 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
175 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
177 /* The maximum number of insns skipped which will be conditionalised if
179 /* When optimizing for speed:
180 Let p be the probability that the potentially skipped insns need to
181 be executed, pn the cost of a correctly predicted non-taken branch,
182 mt the cost of a mis/non-predicted taken branch,
183 mn mispredicted non-taken, pt correctly predicted taken ;
184 costs expressed in numbers of instructions like the ones considered
186 Unfortunately we don't have a measure of predictability - this
187 is linked to probability only in that in the no-eviction-scenario
188 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
189 value that can be assumed *if* the distribution is perfectly random.
190 A predictability of 1 is perfectly plausible not matter what p is,
191 because the decision could be dependent on an invocation parameter
193 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
194 For small p, we want MAX_INSNS_SKIPPED == pt
196 When optimizing for size:
197 We want to skip insn unless we could use 16 opcodes for the
198 non-conditionalized insn to balance the branch length or more.
199 Performance can be tie-breaker. */
200 /* If the potentially-skipped insns are likely to be executed, we'll
201 generally save one non-taken branch
203 this to be no less than the 1/p */
204 #define MAX_INSNS_SKIPPED 3
206 /* A nop is needed between a 4 byte insn that sets the condition codes and
207 a branch that uses them (the same isn't true for an 8 byte insn that sets
208 the condition codes). Set by arc_ccfsm_advance. Used by
209 arc_print_operand. */
211 static int get_arc_condition_code (rtx
);
213 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
214 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
216 /* Initialized arc_attribute_table to NULL since arc doesnot have any
217 machine specific supported attributes. */
218 const struct attribute_spec arc_attribute_table
[] =
220 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
221 affects_type_identity } */
222 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute
, true },
223 /* Function calls made to this symbol must be done indirectly, because
224 it may lie outside of the 21/25 bit addressing range of a normal function
226 { "long_call", 0, 0, false, true, true, NULL
, false },
227 /* Whereas these functions are always known to reside within the 25 bit
228 addressing range of unconditionalized bl. */
229 { "medium_call", 0, 0, false, true, true, NULL
, false },
230 /* And these functions are always known to reside within the 21 bit
231 addressing range of blcc. */
232 { "short_call", 0, 0, false, true, true, NULL
, false },
233 /* Function which are not having the prologue and epilogue generated
235 { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute
, false },
236 { NULL
, 0, 0, false, false, false, NULL
, false }
238 static int arc_comp_type_attributes (const_tree
, const_tree
);
239 static void arc_file_start (void);
240 static void arc_internal_label (FILE *, const char *, unsigned long);
241 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
243 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
244 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
246 static void arc_init_builtins (void);
247 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
249 static int branch_dest (rtx
);
251 static void arc_output_pic_addr_const (FILE *, rtx
, int);
252 bool arc_legitimate_pic_operand_p (rtx
);
253 static bool arc_function_ok_for_sibcall (tree
, tree
);
254 static rtx
arc_function_value (const_tree
, const_tree
, bool);
255 const char * output_shift (rtx
*);
256 static void arc_reorg (void);
257 static bool arc_in_small_data_p (const_tree
);
259 static void arc_init_reg_tables (void);
260 static bool arc_return_in_memory (const_tree
, const_tree
);
261 static bool arc_vector_mode_supported_p (machine_mode
);
263 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
265 static const char *arc_invalid_within_doloop (const rtx_insn
*);
267 static void output_short_suffix (FILE *file
);
269 static bool arc_frame_pointer_required (void);
271 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
273 enum by_pieces_operation op
,
276 /* Globally visible information about currently selected cpu. */
277 const arc_cpu_t
*arc_selected_cpu
;
279 /* Check for constructions like REG + OFFS, where OFFS can be a
280 register, an immediate or an long immediate. */
283 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
285 if (GET_CODE (x
) != PLUS
)
288 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
291 /* Check for: [Rx + small offset] or [Rx + Ry]. */
292 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
293 && GET_MODE_SIZE ((mode
)) <= 4)
294 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
297 /* Check for [Rx + symbol]. */
299 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
300 /* Avoid this type of address for double or larger modes. */
301 && (GET_MODE_SIZE (mode
) <= 4)
302 /* Avoid small data which ends in something like GP +
304 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))
305 || TARGET_NO_SDATA_SET
))
311 /* Implements target hook vector_mode_supported_p. */
314 arc_vector_mode_supported_p (machine_mode mode
)
319 return TARGET_PLUS_DMPY
;
322 return TARGET_PLUS_QMACW
;
325 return TARGET_SIMD_SET
;
332 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
335 arc_preferred_simd_mode (machine_mode mode
)
340 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
349 /* Implements target hook
350 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
353 arc_autovectorize_vector_sizes (void)
355 return TARGET_PLUS_QMACW
? (8 | 4) : 0;
358 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
359 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
360 static rtx
arc_delegitimize_address (rtx
);
361 static bool arc_can_follow_jump (const rtx_insn
*follower
,
362 const rtx_insn
*followee
);
364 static rtx
frame_insn (rtx
);
365 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
367 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
369 static void arc_finalize_pic (void);
371 /* initialize the GCC target structure. */
372 #undef TARGET_COMP_TYPE_ATTRIBUTES
373 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
374 #undef TARGET_ASM_FILE_START
375 #define TARGET_ASM_FILE_START arc_file_start
376 #undef TARGET_ATTRIBUTE_TABLE
377 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
378 #undef TARGET_ASM_INTERNAL_LABEL
379 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
380 #undef TARGET_RTX_COSTS
381 #define TARGET_RTX_COSTS arc_rtx_costs
382 #undef TARGET_ADDRESS_COST
383 #define TARGET_ADDRESS_COST arc_address_cost
385 #undef TARGET_ENCODE_SECTION_INFO
386 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
388 #undef TARGET_CANNOT_FORCE_CONST_MEM
389 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
391 #undef TARGET_INIT_BUILTINS
392 #define TARGET_INIT_BUILTINS arc_init_builtins
394 #undef TARGET_EXPAND_BUILTIN
395 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
397 #undef TARGET_BUILTIN_DECL
398 #define TARGET_BUILTIN_DECL arc_builtin_decl
400 #undef TARGET_ASM_OUTPUT_MI_THUNK
401 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
403 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
404 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
406 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
407 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
409 #undef TARGET_MACHINE_DEPENDENT_REORG
410 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
412 #undef TARGET_IN_SMALL_DATA_P
413 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
415 #undef TARGET_PROMOTE_FUNCTION_MODE
416 #define TARGET_PROMOTE_FUNCTION_MODE \
417 default_promote_function_mode_always_promote
419 #undef TARGET_PROMOTE_PROTOTYPES
420 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
422 #undef TARGET_RETURN_IN_MEMORY
423 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
424 #undef TARGET_PASS_BY_REFERENCE
425 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
427 #undef TARGET_SETUP_INCOMING_VARARGS
428 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
430 #undef TARGET_ARG_PARTIAL_BYTES
431 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
433 #undef TARGET_MUST_PASS_IN_STACK
434 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
436 #undef TARGET_FUNCTION_VALUE
437 #define TARGET_FUNCTION_VALUE arc_function_value
439 #undef TARGET_SCHED_ADJUST_PRIORITY
440 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
442 #undef TARGET_VECTOR_MODE_SUPPORTED_P
443 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
445 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
446 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
448 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
449 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
451 #undef TARGET_CAN_USE_DOLOOP_P
452 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
454 #undef TARGET_INVALID_WITHIN_DOLOOP
455 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
457 #undef TARGET_PRESERVE_RELOAD_P
458 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
460 #undef TARGET_CAN_FOLLOW_JUMP
461 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
463 #undef TARGET_DELEGITIMIZE_ADDRESS
464 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
466 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
467 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
468 arc_use_by_pieces_infrastructure_p
470 /* Usually, we will be able to scale anchor offsets.
471 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
472 #undef TARGET_MIN_ANCHOR_OFFSET
473 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
474 #undef TARGET_MAX_ANCHOR_OFFSET
475 #define TARGET_MAX_ANCHOR_OFFSET (1020)
477 #undef TARGET_SECONDARY_RELOAD
478 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
480 #define TARGET_OPTION_OVERRIDE arc_override_options
482 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
484 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
486 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
488 #define TARGET_CAN_ELIMINATE arc_can_eliminate
490 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
492 #define TARGET_FUNCTION_ARG arc_function_arg
494 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
496 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
498 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
500 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
502 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
504 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
506 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
508 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
509 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
510 arc_no_speculation_in_delay_slots_p
513 #define TARGET_LRA_P arc_lra_p
514 #define TARGET_REGISTER_PRIORITY arc_register_priority
515 /* Stores with scaled offsets have different displacement ranges. */
516 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
517 #define TARGET_SPILL_CLASS arc_spill_class
519 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
520 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
522 #undef TARGET_WARN_FUNC_RETURN
523 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
525 #include "target-def.h"
527 #undef TARGET_ASM_ALIGNED_HI_OP
528 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
529 #undef TARGET_ASM_ALIGNED_SI_OP
530 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
533 #undef TARGET_HAVE_TLS
534 #define TARGET_HAVE_TLS HAVE_AS_TLS
537 #undef TARGET_DWARF_REGISTER_SPAN
538 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
540 /* Try to keep the (mov:DF _, reg) as early as possible so
541 that the d<add/sub/mul>h-lr insns appear together and can
542 use the peephole2 pattern. */
545 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
547 rtx set
= single_set (insn
);
549 && GET_MODE (SET_SRC(set
)) == DFmode
550 && GET_CODE (SET_SRC(set
)) == REG
)
552 /* Incrementing priority by 20 (empirically derived). */
553 return priority
+ 20;
559 /* For ARC base register + offset addressing, the validity of the
560 address is mode-dependent for most of the offset range, as the
561 offset can be scaled by the access size.
562 We don't expose these as mode-dependent addresses in the
563 mode_dependent_address_p target hook, because that would disable
564 lots of optimizations, and most uses of these addresses are for 32
565 or 64 bit accesses anyways, which are fine.
566 However, that leaves some addresses for 8 / 16 bit values not
567 properly reloaded by the generic code, which is why we have to
568 schedule secondary reloads for these. */
571 arc_secondary_reload (bool in_p
,
575 secondary_reload_info
*sri
)
577 enum rtx_code code
= GET_CODE (x
);
579 if (cl
== DOUBLE_REGS
)
582 /* The loop counter register can be stored, but not loaded directly. */
583 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
584 && in_p
&& MEM_P (x
))
587 /* If we have a subreg (reg), where reg is a pseudo (that will end in
588 a memory location), then we may need a scratch register to handle
589 the fp/sp+largeoffset address. */
597 int regno
= REGNO (x
);
598 if (regno
>= FIRST_PSEUDO_REGISTER
)
599 regno
= reg_renumber
[regno
];
604 /* It is a pseudo that ends in a stack location. */
605 if (reg_equiv_mem (REGNO (x
)))
607 /* Get the equivalent address and check the range of the
609 rtx mem
= reg_equiv_mem (REGNO (x
));
610 addr
= find_replacement (&XEXP (mem
, 0));
615 gcc_assert (MEM_P (x
));
617 addr
= simplify_rtx (addr
);
619 if (addr
&& GET_CODE (addr
) == PLUS
620 && CONST_INT_P (XEXP (addr
, 1))
621 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
627 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
631 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
641 /* Convert reloads using offsets that are too large to use indirect
645 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
649 gcc_assert (GET_CODE (mem
) == MEM
);
650 addr
= XEXP (mem
, 0);
652 /* Large offset: use a move. FIXME: ld ops accepts limms as
653 offsets. Hence, the following move insn is not required. */
654 emit_move_insn (scratch
, addr
);
655 mem
= replace_equiv_address_nv (mem
, scratch
);
657 /* Now create the move. */
659 emit_insn (gen_rtx_SET (mem
, reg
));
661 emit_insn (gen_rtx_SET (reg
, mem
));
666 static unsigned arc_ifcvt (void);
670 const pass_data pass_data_arc_ifcvt
=
673 "arc_ifcvt", /* name */
674 OPTGROUP_NONE
, /* optinfo_flags */
675 TV_IFCVT2
, /* tv_id */
676 0, /* properties_required */
677 0, /* properties_provided */
678 0, /* properties_destroyed */
679 0, /* todo_flags_start */
680 TODO_df_finish
/* todo_flags_finish */
683 class pass_arc_ifcvt
: public rtl_opt_pass
686 pass_arc_ifcvt(gcc::context
*ctxt
)
687 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
690 /* opt_pass methods: */
691 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
692 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
698 make_pass_arc_ifcvt (gcc::context
*ctxt
)
700 return new pass_arc_ifcvt (ctxt
);
703 static unsigned arc_predicate_delay_insns (void);
707 const pass_data pass_data_arc_predicate_delay_insns
=
710 "arc_predicate_delay_insns", /* name */
711 OPTGROUP_NONE
, /* optinfo_flags */
712 TV_IFCVT2
, /* tv_id */
713 0, /* properties_required */
714 0, /* properties_provided */
715 0, /* properties_destroyed */
716 0, /* todo_flags_start */
717 TODO_df_finish
/* todo_flags_finish */
720 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
723 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
724 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
727 /* opt_pass methods: */
728 virtual unsigned int execute (function
*)
730 return arc_predicate_delay_insns ();
737 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
739 return new pass_arc_predicate_delay_insns (ctxt
);
742 /* Called by OVERRIDE_OPTIONS to initialize various things. */
749 /* I have the multiplier, then use it*/
750 if (TARGET_MPYW
|| TARGET_MULTI
)
751 arc_multcost
= COSTS_N_INSNS (1);
753 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
754 if (arc_multcost
< 0)
757 case TUNE_ARC700_4_2_STD
:
759 max throughput (1 multiply + 4 other insns) / 5 cycles. */
760 arc_multcost
= COSTS_N_INSNS (4);
761 if (TARGET_NOMPY_SET
)
762 arc_multcost
= COSTS_N_INSNS (30);
764 case TUNE_ARC700_4_2_XMAC
:
766 max throughput (1 multiply + 2 other insns) / 3 cycles. */
767 arc_multcost
= COSTS_N_INSNS (3);
768 if (TARGET_NOMPY_SET
)
769 arc_multcost
= COSTS_N_INSNS (30);
772 if (TARGET_MUL64_SET
)
774 arc_multcost
= COSTS_N_INSNS (4);
779 arc_multcost
= COSTS_N_INSNS (30);
783 /* MPY instructions valid only for ARC700 or ARCv2. */
784 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
785 error ("-mno-mpy supported only for ARC700 or ARCv2");
787 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
788 error ("-mno-dpfp-lrsr supported only with -mdpfp");
790 /* FPX-1. No fast and compact together. */
791 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
792 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
793 error ("FPX fast and compact options cannot be specified together");
795 /* FPX-2. No fast-spfp for arc600 or arc601. */
796 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
797 error ("-mspfp_fast not available on ARC600 or ARC601");
799 /* FPX-4. No FPX extensions mixed with FPU extensions. */
800 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
801 && TARGET_HARD_FLOAT
)
802 error ("No FPX/FPU mixing allowed");
804 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
805 if (flag_pic
&& TARGET_ARC600_FAMILY
)
808 "PIC is not supported for %s. Generating non-PIC code only..",
813 arc_init_reg_tables ();
815 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
816 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
817 arc_punct_chars
['#'] = 1;
818 arc_punct_chars
['*'] = 1;
819 arc_punct_chars
['?'] = 1;
820 arc_punct_chars
['!'] = 1;
821 arc_punct_chars
['^'] = 1;
822 arc_punct_chars
['&'] = 1;
823 arc_punct_chars
['+'] = 1;
824 arc_punct_chars
['_'] = 1;
826 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
828 /* There are two target-independent ifcvt passes, and arc_reorg may do
829 one or more arc_ifcvt calls. */
830 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
831 struct register_pass_info arc_ifcvt4_info
832 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
833 struct register_pass_info arc_ifcvt5_info
834 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
836 register_pass (&arc_ifcvt4_info
);
837 register_pass (&arc_ifcvt5_info
);
840 if (flag_delayed_branch
)
842 opt_pass
*pass_arc_predicate_delay_insns
843 = make_pass_arc_predicate_delay_insns (g
);
844 struct register_pass_info arc_predicate_delay_info
845 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
847 register_pass (&arc_predicate_delay_info
);
851 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
852 register range is specified as two registers separated by a dash.
853 It always starts with r0, and its upper limit is fp register.
854 blink and lp_count registers are optional. */
857 irq_range (const char *cstr
)
859 int i
, first
, last
, blink
, lpcount
, xreg
;
860 char *str
, *dash
, *comma
;
863 str
= (char *) alloca (i
+ 1);
864 memcpy (str
, cstr
, i
+ 1);
868 dash
= strchr (str
, '-');
871 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
876 comma
= strchr (dash
+ 1, ',');
880 first
= decode_reg_name (str
);
883 warning (0, "first register must be R0");
887 /* At this moment we do not have the register names initialized
889 if (!strcmp (dash
+ 1, "ilink"))
892 last
= decode_reg_name (dash
+ 1);
896 warning (0, "unknown register name: %s", dash
+ 1);
902 warning (0, "last register name %s must be an odd register", dash
+ 1);
910 warning (0, "%s-%s is an empty range", str
, dash
+ 1);
919 comma
= strchr (str
, ',');
923 xreg
= decode_reg_name (str
);
935 warning (0, "unknown register name: %s", str
);
940 irq_ctrl_saved
.irq_save_last_reg
= last
;
941 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
942 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
945 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
949 parse_mrgf_banked_regs_option (const char *arg
)
955 val
= strtol (arg
, &end_ptr
, 10);
956 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
957 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
959 error ("invalid number in -mrgf-banked-regs=%s "
960 "valid values are 0, 4, 8, 16, or 32", arg
);
963 rgf_banked_register_count
= (int) val
;
966 /* Check ARC options, generate derived target attributes. */
969 arc_override_options (void)
972 cl_deferred_option
*opt
;
973 vec
<cl_deferred_option
> *vopt
974 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
976 if (arc_cpu
== PROCESSOR_NONE
)
977 arc_cpu
= TARGET_CPU_DEFAULT
;
979 /* Set the default cpu options. */
980 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
982 /* Set the architectures. */
983 switch (arc_selected_cpu
->arch_info
->arch_id
)
986 arc_cpu_string
= "EM";
989 arc_cpu_string
= "HS";
992 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
993 arc_cpu_string
= "NPS400";
995 arc_cpu_string
= "ARC700";
998 arc_cpu_string
= "ARC600";
1004 irq_ctrl_saved
.irq_save_last_reg
= -1;
1005 irq_ctrl_saved
.irq_save_blink
= false;
1006 irq_ctrl_saved
.irq_save_lpcount
= false;
1008 rgf_banked_register_count
= 0;
1010 /* Handle the deferred options. */
1012 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1014 switch (opt
->opt_index
)
1016 case OPT_mirq_ctrl_saved_
:
1018 irq_range (opt
->arg
);
1020 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1023 case OPT_mrgf_banked_regs_
:
1025 parse_mrgf_banked_regs_option (opt
->arg
);
1027 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1035 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1036 specific flags are set in arc-common.c. The architecture forces
1037 the default hardware configurations in, regardless what command
1038 line options are saying. The CPU optional hw options can be
1039 turned on or off. */
1040 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1042 if ((arc_selected_cpu->flags & CODE) \
1043 && ((target_flags_explicit & MASK) == 0)) \
1044 target_flags |= MASK; \
1045 if (arc_selected_cpu->arch_info->dflags & CODE) \
1046 target_flags |= MASK; \
1048 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1050 if ((arc_selected_cpu->flags & CODE) \
1051 && (VAR == DEFAULT_##VAR)) \
1053 if (arc_selected_cpu->arch_info->dflags & CODE) \
1057 #include "arc-options.def"
1062 /* Check options against architecture options. Throw an error if
1063 option is not allowed. */
1064 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1067 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1069 error ("%s is not available for %s architecture", \
1070 DOC, arc_selected_cpu->arch_info->name); \
1073 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1075 if ((target_flags & MASK) \
1076 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1077 error ("%s is not available for %s architecture", \
1078 DOC, arc_selected_cpu->arch_info->name); \
1081 #include "arc-options.def"
1086 /* Set Tune option. */
1087 if (arc_tune
== TUNE_NONE
)
1088 arc_tune
= (enum attr_tune
) arc_selected_cpu
->tune
;
1090 if (arc_size_opt_level
== 3)
1093 /* Compact casesi is not a valid option for ARCv2 family. */
1096 if (TARGET_COMPACT_CASESI
)
1098 warning (0, "compact-casesi is not applicable to ARCv2");
1099 TARGET_COMPACT_CASESI
= 0;
1102 else if (optimize_size
== 1
1103 && !global_options_set
.x_TARGET_COMPACT_CASESI
)
1104 TARGET_COMPACT_CASESI
= 1;
1107 target_flags
|= MASK_NO_SDATA_SET
;
1109 if (flag_no_common
== 255)
1110 flag_no_common
= !TARGET_NO_SDATA_SET
;
1112 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1113 if (TARGET_MIXED_CODE
)
1115 if (!TARGET_Q_CLASS
)
1116 TARGET_COMPACT_CASESI
= 0;
1117 if (TARGET_COMPACT_CASESI
)
1118 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
1120 /* These need to be done at start up. It's convenient to do them here. */
1124 /* The condition codes of the ARC, and the inverse function. */
1125 /* For short branches, the "c" / "nc" names are not defined in the ARC
1126 Programmers manual, so we have to use "lo" / "hs"" instead. */
1127 static const char *arc_condition_codes
[] =
1129 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1130 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1133 enum arc_cc_code_index
1135 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1136 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1137 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1138 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1141 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1143 /* Returns the index of the ARC condition code string in
1144 `arc_condition_codes'. COMPARISON should be an rtx like
1145 `(eq (...) (...))'. */
1148 get_arc_condition_code (rtx comparison
)
1150 switch (GET_MODE (XEXP (comparison
, 0)))
1153 case SImode
: /* For BRcc. */
1154 switch (GET_CODE (comparison
))
1156 case EQ
: return ARC_CC_EQ
;
1157 case NE
: return ARC_CC_NE
;
1158 case GT
: return ARC_CC_GT
;
1159 case LE
: return ARC_CC_LE
;
1160 case GE
: return ARC_CC_GE
;
1161 case LT
: return ARC_CC_LT
;
1162 case GTU
: return ARC_CC_HI
;
1163 case LEU
: return ARC_CC_LS
;
1164 case LTU
: return ARC_CC_LO
;
1165 case GEU
: return ARC_CC_HS
;
1166 default : gcc_unreachable ();
1169 switch (GET_CODE (comparison
))
1171 case EQ
: return ARC_CC_EQ
;
1172 case NE
: return ARC_CC_NE
;
1173 case GE
: return ARC_CC_P
;
1174 case LT
: return ARC_CC_N
;
1175 case GT
: return ARC_CC_PNZ
;
1176 default : gcc_unreachable ();
1179 switch (GET_CODE (comparison
))
1181 case EQ
: return ARC_CC_EQ
;
1182 case NE
: return ARC_CC_NE
;
1183 default : gcc_unreachable ();
1186 switch (GET_CODE (comparison
))
1188 case LTU
: return ARC_CC_C
;
1189 case GEU
: return ARC_CC_NC
;
1190 default : gcc_unreachable ();
1193 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1194 switch (GET_CODE (comparison
))
1196 case GT
: return ARC_CC_N
;
1197 case UNLE
: return ARC_CC_P
;
1198 default : gcc_unreachable ();
1201 switch (GET_CODE (comparison
))
1203 case GT
: return ARC_CC_HI
;
1204 case UNLE
: return ARC_CC_LS
;
1205 default : gcc_unreachable ();
1208 /* Same for FPX and non-FPX. */
1209 switch (GET_CODE (comparison
))
1211 case GE
: return ARC_CC_HS
;
1212 case UNLT
: return ARC_CC_LO
;
1213 default : gcc_unreachable ();
1215 case CC_FP_UNEQmode
:
1216 switch (GET_CODE (comparison
))
1218 case UNEQ
: return ARC_CC_EQ
;
1219 case LTGT
: return ARC_CC_NE
;
1220 default : gcc_unreachable ();
1223 switch (GET_CODE (comparison
))
1225 case UNORDERED
: return ARC_CC_C
;
1226 case ORDERED
: return ARC_CC_NC
;
1227 default : gcc_unreachable ();
1230 switch (GET_CODE (comparison
))
1232 case EQ
: return ARC_CC_EQ
;
1233 case NE
: return ARC_CC_NE
;
1234 case UNORDERED
: return ARC_CC_C
;
1235 case ORDERED
: return ARC_CC_NC
;
1236 case LTGT
: return ARC_CC_HI
;
1237 case UNEQ
: return ARC_CC_LS
;
1238 default : gcc_unreachable ();
1241 switch (GET_CODE (comparison
))
1243 case EQ
: return ARC_CC_EQ
;
1244 case NE
: return ARC_CC_NE
;
1245 case GT
: return ARC_CC_GT
;
1246 case GE
: return ARC_CC_GE
;
1247 case LT
: return ARC_CC_C
;
1248 case LE
: return ARC_CC_LS
;
1249 case UNORDERED
: return ARC_CC_V
;
1250 case ORDERED
: return ARC_CC_NV
;
1251 case UNGT
: return ARC_CC_HI
;
1252 case UNGE
: return ARC_CC_HS
;
1253 case UNLT
: return ARC_CC_LT
;
1254 case UNLE
: return ARC_CC_LE
;
1255 /* UNEQ and LTGT do not have representation. */
1256 case LTGT
: /* Fall through. */
1257 case UNEQ
: /* Fall through. */
1258 default : gcc_unreachable ();
1260 case CC_FPU_UNEQmode
:
1261 switch (GET_CODE (comparison
))
1263 case LTGT
: return ARC_CC_NE
;
1264 case UNEQ
: return ARC_CC_EQ
;
1265 default : gcc_unreachable ();
1267 default : gcc_unreachable ();
1273 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1276 arc_short_comparison_p (rtx comparison
, int offset
)
1278 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1279 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1280 switch (get_arc_condition_code (comparison
))
1282 case ARC_CC_EQ
: case ARC_CC_NE
:
1283 return offset
>= -512 && offset
<= 506;
1284 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1285 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1286 return offset
>= -64 && offset
<= 58;
1292 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1293 return the mode to be used for the comparison. */
1296 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1298 machine_mode mode
= GET_MODE (x
);
1301 /* For an operation that sets the condition codes as a side-effect, the
1302 C and V flags is not set as for cmp, so we can only use comparisons where
1303 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1305 /* ??? We could use "pnz" for greater than zero, however, we could then
1306 get into trouble because the comparison could not be reversed. */
1307 if (GET_MODE_CLASS (mode
) == MODE_INT
1309 && (op
== EQ
|| op
== NE
1310 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1313 /* add.f for if (a+b) */
1315 && GET_CODE (y
) == NEG
1316 && (op
== EQ
|| op
== NE
))
1319 /* Check if this is a test suitable for bxor.f . */
1320 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1321 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1325 /* Check if this is a test suitable for add / bmsk.f . */
1326 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1327 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1328 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1329 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1330 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1333 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1334 && GET_CODE (x
) == PLUS
1335 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1338 if (TARGET_ARGONAUT_SET
1339 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1342 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1344 case LT
: case UNGE
: case GT
: case UNLE
:
1345 return CC_FP_GTmode
;
1346 case LE
: case UNGT
: case GE
: case UNLT
:
1347 return CC_FP_GEmode
;
1348 default: gcc_unreachable ();
1350 else if (TARGET_HARD_FLOAT
1351 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1352 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1371 return CC_FPU_UNEQmode
;
1376 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1380 case EQ
: case NE
: return CC_Zmode
;
1382 case GT
: case UNLE
: return CC_FP_GTmode
;
1384 case GE
: case UNLT
: return CC_FP_GEmode
;
1385 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1386 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1387 default: gcc_unreachable ();
1393 /* Vectors to keep interesting information about registers where it can easily
1394 be got. We use to use the actual mode value as the bit number, but there
1395 is (or may be) more than 32 modes now. Instead we use two tables: one
1396 indexed by hard register number, and one indexed by mode. */
1398 /* The purpose of arc_mode_class is to shrink the range of modes so that
1399 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1400 mapped into one arc_mode_class mode. */
1402 enum arc_mode_class
{
1404 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1405 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1409 /* Modes for condition codes. */
1410 #define C_MODES (1 << (int) C_MODE)
1412 /* Modes for single-word and smaller quantities. */
1413 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1415 /* Modes for double-word and smaller quantities. */
1416 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1418 /* Mode for 8-byte DF values only. */
1419 #define DF_MODES (1 << DF_MODE)
1421 /* Modes for quad-word and smaller quantities. */
1422 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1424 /* Modes for 128-bit vectors. */
1425 #define V_MODES (1 << (int) V_MODE)
1427 /* Value is 1 if register/mode pair is acceptable on arc. */
1429 unsigned int arc_hard_regno_mode_ok
[] = {
1430 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1431 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1432 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1433 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1435 /* ??? Leave these as S_MODES for now. */
1436 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1437 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1438 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1439 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1441 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1442 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1443 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1444 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1446 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1447 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1448 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1449 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1451 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1452 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1455 unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1457 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1460 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1462 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1463 return GENERAL_REGS
;
1467 /* Initialize the arc_mode_class array. */
1470 arc_init_reg_tables (void)
1474 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1476 machine_mode m
= (machine_mode
) i
;
1478 switch (GET_MODE_CLASS (m
))
1481 case MODE_PARTIAL_INT
:
1482 case MODE_COMPLEX_INT
:
1483 if (GET_MODE_SIZE (m
) <= 4)
1484 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1485 else if (GET_MODE_SIZE (m
) == 8)
1486 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1487 else if (GET_MODE_SIZE (m
) == 16)
1488 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1489 else if (GET_MODE_SIZE (m
) == 32)
1490 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1492 arc_mode_class
[i
] = 0;
1495 case MODE_COMPLEX_FLOAT
:
1496 if (GET_MODE_SIZE (m
) <= 4)
1497 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1498 else if (GET_MODE_SIZE (m
) == 8)
1499 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1500 else if (GET_MODE_SIZE (m
) == 16)
1501 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1502 else if (GET_MODE_SIZE (m
) == 32)
1503 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1505 arc_mode_class
[i
] = 0;
1507 case MODE_VECTOR_INT
:
1508 if (GET_MODE_SIZE (m
) == 4)
1509 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1510 else if (GET_MODE_SIZE (m
) == 8)
1511 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1513 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1517 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1518 we must explicitly check for them here. */
1519 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1520 || i
== (int) CC_Cmode
1521 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1522 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1523 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1525 arc_mode_class
[i
] = 0;
1531 /* Core registers 56..59 are used for multiply extension options.
1532 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1533 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1534 number depends on endianness.
1535 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1536 Because mlo / mhi form a 64 bit value, we use different gcc internal
1537 register numbers to make them form a register pair as the gcc internals
1538 know it. mmid gets number 57, if still available, and mlo / mhi get
1539 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1540 to map this back. */
1541 char rname56
[5] = "r56";
1542 char rname57
[5] = "r57";
1543 char rname58
[5] = "r58";
1544 char rname59
[5] = "r59";
1545 char rname29
[7] = "ilink1";
1546 char rname30
[7] = "ilink2";
1549 arc_conditional_register_usage (void)
1553 int fix_start
= 60, fix_end
= 55;
1557 /* For ARCv2 the core register set is changed. */
1558 strcpy (rname29
, "ilink");
1559 strcpy (rname30
, "r30");
1560 call_used_regs
[30] = 1;
1563 arc_regno_reg_class
[30] = WRITABLE_CORE_REGS
;
1564 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], 30);
1565 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], 30);
1566 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], 30);
1567 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], 30);
1570 if (TARGET_MUL64_SET
)
1575 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1576 you are supposed to refer to it as mlo & mhi, e.g
1577 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1578 In an actual asm instruction, you are of course use mmed.
1579 The point of avoiding having a separate register for mmed is that
1580 this way, we don't have to carry clobbers of that reg around in every
1581 isntruction that modifies mlo and/or mhi. */
1582 strcpy (rname57
, "");
1583 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1584 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1587 /* The nature of arc_tp_regno is actually something more like a global
1588 register, however globalize_reg requires a declaration.
1589 We use EPILOGUE_USES to compensate so that sets from
1590 __builtin_set_frame_pointer are not deleted. */
1591 if (arc_tp_regno
!= -1)
1592 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1594 if (TARGET_MULMAC_32BY16_SET
)
1597 fix_end
= fix_end
> 57 ? fix_end
: 57;
1598 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1599 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1601 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1603 if (!fixed_regs
[regno
])
1604 warning (0, "multiply option implies r%d is fixed", regno
);
1605 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1611 reg_alloc_order
[0] = 0;
1612 reg_alloc_order
[1] = 1;
1613 reg_alloc_order
[2] = 2;
1614 reg_alloc_order
[3] = 3;
1615 reg_alloc_order
[4] = 12;
1616 reg_alloc_order
[5] = 13;
1617 reg_alloc_order
[6] = 14;
1618 reg_alloc_order
[7] = 15;
1619 reg_alloc_order
[8] = 4;
1620 reg_alloc_order
[9] = 5;
1621 reg_alloc_order
[10] = 6;
1622 reg_alloc_order
[11] = 7;
1623 reg_alloc_order
[12] = 8;
1624 reg_alloc_order
[13] = 9;
1625 reg_alloc_order
[14] = 10;
1626 reg_alloc_order
[15] = 11;
1630 reg_alloc_order
[2] = 12;
1631 reg_alloc_order
[3] = 13;
1632 reg_alloc_order
[4] = 14;
1633 reg_alloc_order
[5] = 15;
1634 reg_alloc_order
[6] = 1;
1635 reg_alloc_order
[7] = 0;
1636 reg_alloc_order
[8] = 4;
1637 reg_alloc_order
[9] = 5;
1638 reg_alloc_order
[10] = 6;
1639 reg_alloc_order
[11] = 7;
1640 reg_alloc_order
[12] = 8;
1641 reg_alloc_order
[13] = 9;
1642 reg_alloc_order
[14] = 10;
1643 reg_alloc_order
[15] = 11;
1646 if (TARGET_SIMD_SET
)
1649 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1650 reg_alloc_order
[i
] = i
;
1651 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1652 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1653 reg_alloc_order
[i
] = i
;
1655 /* For ARC600, lp_count may not be read in an instruction
1656 following immediately after another one setting it to a new value.
1657 There was some discussion on how to enforce scheduling constraints for
1658 processors with missing interlocks on the gcc mailing list:
1659 http://gcc.gnu.org/ml/gcc/2008-05/msg00021.html .
1660 However, we can't actually use this approach, because for ARC the
1661 delay slot scheduling pass is active, which runs after
1662 machine_dependent_reorg. */
1664 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1665 else if (!TARGET_LP_WR_INTERLOCK
)
1666 fixed_regs
[LP_COUNT
] = 1;
1667 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1668 if (!call_used_regs
[regno
])
1669 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1670 for (regno
= 32; regno
< 60; regno
++)
1671 if (!fixed_regs
[regno
])
1672 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1673 if (!TARGET_ARC600_FAMILY
)
1675 for (regno
= 32; regno
<= 60; regno
++)
1676 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1678 /* If they have used -ffixed-lp_count, make sure it takes
1680 if (fixed_regs
[LP_COUNT
])
1682 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1683 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1684 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1686 /* Instead of taking out SF_MODE like below, forbid it outright. */
1687 arc_hard_regno_mode_ok
[60] = 0;
1690 arc_hard_regno_mode_ok
[60] = 1 << (int) S_MODE
;
1693 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1697 for (regno
= 1; regno
< 32; regno
+=2)
1699 arc_hard_regno_mode_ok
[regno
] = S_MODES
;
1703 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1707 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1708 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1709 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1711 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1714 arc_regno_reg_class
[i
]
1716 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1717 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1718 : (((!TARGET_ARC600_FAMILY
)
1719 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1720 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1722 arc_regno_reg_class
[i
] = NO_REGS
;
1725 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1726 has not been activated. */
1727 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1728 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1729 if (!TARGET_Q_CLASS
)
1730 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1732 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1734 /* Handle Special Registers. */
1735 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1737 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1738 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1739 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1740 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1741 arc_regno_reg_class
[62] = GENERAL_REGS
;
1745 for (i
= 40; i
< 44; ++i
)
1747 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1749 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1750 no attempt is made to use such a register as a destination
1751 operand in *movdf_insn. */
1752 if (!TARGET_ARGONAUT_SET
)
1754 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1755 interpreted to mean they can use D1 or D2 in their insn. */
1756 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1757 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1758 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1759 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1765 /* Disable all DOUBLE_REGISTER settings,
1766 if not generating DPFP code. */
1767 arc_regno_reg_class
[40] = ALL_REGS
;
1768 arc_regno_reg_class
[41] = ALL_REGS
;
1769 arc_regno_reg_class
[42] = ALL_REGS
;
1770 arc_regno_reg_class
[43] = ALL_REGS
;
1777 arc_hard_regno_mode_ok
[40] = 0;
1778 arc_hard_regno_mode_ok
[42] = 0;
1780 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1783 if (TARGET_SIMD_SET
)
1785 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1786 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1788 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1789 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1791 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1792 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1793 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1794 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1796 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1797 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1798 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1802 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
1804 /*ARCV2 Accumulator. */
1806 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1807 || TARGET_PLUS_DMPY
)
1809 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
1810 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
1811 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
1812 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
1813 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
1814 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
1815 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCL_REGNO
);
1816 SET_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], ACCH_REGNO
);
1817 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCL_REGNO
);
1818 SET_HARD_REG_BIT (reg_class_contents
[MPY_WRITABLE_CORE_REGS
], ACCH_REGNO
);
1820 /* Allow the compiler to freely use them. */
1821 fixed_regs
[ACCL_REGNO
] = 0;
1822 fixed_regs
[ACCH_REGNO
] = 0;
1824 arc_hard_regno_mode_ok
[ACC_REG_FIRST
] = D_MODES
;
1828 /* Handle an "interrupt" attribute; arguments as in
1829 struct attribute_spec.handler. */
1832 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
1837 tree value
= TREE_VALUE (args
);
1839 if (TREE_CODE (value
) != STRING_CST
)
1841 warning (OPT_Wattributes
,
1842 "argument of %qE attribute is not a string constant",
1844 *no_add_attrs
= true;
1847 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
1848 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
1850 warning (OPT_Wattributes
,
1851 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1853 *no_add_attrs
= true;
1856 && strcmp (TREE_STRING_POINTER (value
), "ilink")
1857 && strcmp (TREE_STRING_POINTER (value
), "firq"))
1859 warning (OPT_Wattributes
,
1860 "argument of %qE attribute is not \"ilink\" or \"firq\"",
1862 *no_add_attrs
= true;
1869 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
1870 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
1872 if (TREE_CODE (*node
) != FUNCTION_DECL
)
1874 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
1876 *no_add_attrs
= true;
1882 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
1885 arc_allocate_stack_slots_for_args (void)
1887 /* Naked functions should not allocate stack slots for arguments. */
1888 unsigned int fn_type
= arc_compute_function_type (cfun
);
1890 return !ARC_NAKED_P(fn_type
);
1893 /* Implement `TARGET_WARN_FUNC_RETURN'. */
1896 arc_warn_func_return (tree decl
)
1898 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
1899 unsigned int fn_type
= arc_compute_function_type (func
);
1901 return !ARC_NAKED_P (fn_type
);
1904 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1905 and two if they are nearly compatible (which causes a warning to be
1909 arc_comp_type_attributes (const_tree type1
,
1912 int l1
, l2
, m1
, m2
, s1
, s2
;
1914 /* Check for mismatch of non-default calling convention. */
1915 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
1918 /* Check for mismatched call attributes. */
1919 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1920 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1921 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1922 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1923 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1924 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1926 /* Only bother to check if an attribute is defined. */
1927 if (l1
| l2
| m1
| m2
| s1
| s2
)
1929 /* If one type has an attribute, the other must have the same attribute. */
1930 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
1933 /* Disallow mixed attributes. */
1934 if (l1
+ m1
+ s1
> 1)
1942 /* Set the default attributes for TYPE. */
1945 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED
)
1950 /* Misc. utilities. */
1952 /* X and Y are two things to compare using CODE. Emit the compare insn and
1953 return the rtx for the cc reg in the proper mode. */
1956 gen_compare_reg (rtx comparison
, machine_mode omode
)
1958 enum rtx_code code
= GET_CODE (comparison
);
1959 rtx x
= XEXP (comparison
, 0);
1960 rtx y
= XEXP (comparison
, 1);
1962 machine_mode mode
, cmode
;
1965 cmode
= GET_MODE (x
);
1966 if (cmode
== VOIDmode
)
1967 cmode
= GET_MODE (y
);
1968 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
1969 if (cmode
== SImode
)
1971 if (!register_operand (x
, SImode
))
1973 if (register_operand (y
, SImode
))
1978 code
= swap_condition (code
);
1981 x
= copy_to_mode_reg (SImode
, x
);
1983 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
1984 y
= copy_to_mode_reg (SImode
, y
);
1988 x
= force_reg (cmode
, x
);
1989 y
= force_reg (cmode
, y
);
1991 mode
= SELECT_CC_MODE (code
, x
, y
);
1993 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
1995 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
1996 cmpdfpx_raw, is not a correct comparison for floats:
1997 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1999 if (TARGET_ARGONAUT_SET
2000 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2004 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2005 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2007 case GT
: case UNLE
: case GE
: case UNLT
:
2008 code
= swap_condition (code
);
2016 if (cmode
== SFmode
)
2018 emit_insn (gen_cmpsfpx_raw (x
, y
));
2022 /* Accepts Dx regs directly by insns. */
2023 emit_insn (gen_cmpdfpx_raw (x
, y
));
2026 if (mode
!= CC_FPXmode
)
2027 emit_insn (gen_rtx_SET (cc_reg
,
2028 gen_rtx_COMPARE (mode
,
2029 gen_rtx_REG (CC_FPXmode
, 61),
2032 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2036 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2037 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2039 case LT
: case UNGE
: case LE
: case UNGT
:
2040 code
= swap_condition (code
);
2049 emit_insn (gen_cmp_quark (cc_reg
,
2050 gen_rtx_COMPARE (mode
, x
, y
)));
2052 else if (TARGET_HARD_FLOAT
2053 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2054 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2055 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2056 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2058 rtx op0
= gen_rtx_REG (cmode
, 0);
2059 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2064 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2065 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2067 case LT
: case UNGE
: case LE
: case UNGT
:
2068 code
= swap_condition (code
);
2074 if (currently_expanding_to_rtl
)
2082 emit_move_insn (op0
, x
);
2083 emit_move_insn (op1
, y
);
2087 gcc_assert (rtx_equal_p (op0
, x
));
2088 gcc_assert (rtx_equal_p (op1
, y
));
2095 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2098 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2099 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2102 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2103 We assume the value can be either signed or unsigned. */
2106 arc_double_limm_p (rtx value
)
2108 HOST_WIDE_INT low
, high
;
2110 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2115 low
= CONST_DOUBLE_LOW (value
);
2116 high
= CONST_DOUBLE_HIGH (value
);
2118 if (low
& 0x80000000)
2120 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2121 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2122 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2127 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2131 /* Do any needed setup for a variadic function. For the ARC, we must
2132 create a register parameter block, and then copy any anonymous arguments
2133 in registers to memory.
2135 CUM has not been updated for the last named argument which has type TYPE
2136 and mode MODE, and we rely on this fact. */
2139 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2140 machine_mode mode
, tree type
,
2141 int *pretend_size
, int no_rtl
)
2144 CUMULATIVE_ARGS next_cum
;
2146 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2148 next_cum
= *get_cumulative_args (args_so_far
);
2149 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
2151 first_anon_arg
= next_cum
;
2153 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2155 /* First anonymous (unnamed) argument is in a reg. */
2157 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2158 int first_reg_offset
= first_anon_arg
;
2163 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2164 FIRST_PARM_OFFSET (0)));
2165 move_block_from_reg (first_reg_offset
, regblock
,
2166 MAX_ARC_PARM_REGS
- first_reg_offset
);
2170 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2174 /* Cost functions. */
2176 /* Provide the costs of an addressing mode that contains ADDR.
2177 If ADDR is not a valid address, its cost is irrelevant. */
2180 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2182 switch (GET_CODE (addr
))
2185 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2186 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2187 case PRE_MODIFY
: case POST_MODIFY
:
2193 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2195 /* Most likely needs a LIMM. */
2196 return COSTS_N_INSNS (1);
2200 register rtx plus0
= XEXP (addr
, 0);
2201 register rtx plus1
= XEXP (addr
, 1);
2203 if (GET_CODE (plus0
) != REG
2204 && (GET_CODE (plus0
) != MULT
2205 || !CONST_INT_P (XEXP (plus0
, 1))
2206 || (INTVAL (XEXP (plus0
, 1)) != 2
2207 && INTVAL (XEXP (plus0
, 1)) != 4)))
2210 switch (GET_CODE (plus1
))
2213 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2217 : (satisfies_constraint_Rcq (plus0
)
2218 && satisfies_constraint_O (plus1
))
2222 return (speed
< 1 ? 0
2223 : (satisfies_constraint_Rcq (plus0
)
2224 && satisfies_constraint_Rcq (plus1
))
2229 return COSTS_N_INSNS (1);
2242 /* Emit instruction X with the frame related bit set. */
2248 RTX_FRAME_RELATED_P (x
) = 1;
2252 /* Emit a frame insn to move SRC to DST. */
2255 frame_move (rtx dst
, rtx src
)
2257 rtx tmp
= gen_rtx_SET (dst
, src
);
2258 RTX_FRAME_RELATED_P (tmp
) = 1;
2259 return frame_insn (tmp
);
2262 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2263 auto increment address, or is zero. */
2266 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2268 rtx insn
= frame_move (dst
, src
);
2271 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2272 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2273 add_reg_note (insn
, REG_INC
, reg
);
2277 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2280 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2282 gcc_assert ((offset
& 0x3) == 0);
2285 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2288 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2291 frame_stack_add (HOST_WIDE_INT offset
)
2293 return frame_add (stack_pointer_rtx
, offset
);
2296 /* Traditionally, we push saved registers first in the prologue,
2297 then we allocate the rest of the frame - and reverse in the epilogue.
2298 This has still its merits for ease of debugging, or saving code size
2299 or even execution time if the stack frame is so large that some accesses
2300 can't be encoded anymore with offsets in the instruction code when using
2302 Also, it would be a good starting point if we got instructions to help
2303 with register save/restore.
2305 However, often stack frames are small, and the pushing / popping has
2307 - the stack modification prevents a lot of scheduling.
2308 - frame allocation / deallocation needs extra instructions.
2309 - unless we know that we compile ARC700 user code, we need to put
2310 a memory barrier after frame allocation / before deallocation to
2311 prevent interrupts clobbering our data in the frame.
2312 In particular, we don't have any such guarantees for library functions,
2313 which tend to, on the other hand, to have small frames.
2315 Thus, for small frames, we'd like to use a different scheme:
2316 - The frame is allocated in full with the first prologue instruction,
2317 and deallocated in full with the last epilogue instruction.
2318 Thus, the instructions in-betwen can be freely scheduled.
2319 - If the function has no outgoing arguments on the stack, we can allocate
2320 one register save slot at the top of the stack. This register can then
2321 be saved simultanously with frame allocation, and restored with
2323 This register can be picked depending on scheduling considerations,
2324 although same though should go into having some set of registers
2325 to be potentially lingering after a call, and others to be available
2326 immediately - i.e. in the absence of interprocedual optimization, we
2327 can use an ABI-like convention for register allocation to reduce
2328 stalls after function return. */
2329 /* Function prologue/epilogue handlers. */
2331 /* ARCompact stack frames look like:
2333 Before call After call
2334 high +-----------------------+ +-----------------------+
2335 mem | reg parm save area | | reg parm save area |
2336 | only created for | | only created for |
2337 | variable arg fns | | variable arg fns |
2338 AP +-----------------------+ +-----------------------+
2339 | return addr register | | return addr register |
2340 | (if required) | | (if required) |
2341 +-----------------------+ +-----------------------+
2343 | reg save area | | reg save area |
2345 +-----------------------+ +-----------------------+
2346 | frame pointer | | frame pointer |
2347 | (if required) | | (if required) |
2348 FP +-----------------------+ +-----------------------+
2350 | local/temp variables | | local/temp variables |
2352 +-----------------------+ +-----------------------+
2354 | arguments on stack | | arguments on stack |
2356 SP +-----------------------+ +-----------------------+
2357 | reg parm save area |
2358 | only created for |
2359 | variable arg fns |
2360 AP +-----------------------+
2361 | return addr register |
2363 +-----------------------+
2367 +-----------------------+
2370 FP +-----------------------+
2372 | local/temp variables |
2374 +-----------------------+
2376 | arguments on stack |
2378 mem SP +-----------------------+
2381 1) The "reg parm save area" does not exist for non variable argument fns.
2382 The "reg parm save area" can be eliminated completely if we created our
2383 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2385 /* Structure to be filled in by arc_compute_frame_size with register
2386 save masks, and offsets for the current function. */
2387 struct GTY (()) arc_frame_info
2389 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2390 unsigned int extra_size
; /* # bytes of extra stuff. */
2391 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2392 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2393 unsigned int reg_size
; /* # bytes needed to store regs. */
2394 unsigned int var_size
; /* # bytes that variables take up. */
2395 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2396 unsigned int gmask
; /* Mask of saved gp registers. */
2397 int initialized
; /* Nonzero if frame size already calculated. */
2398 short millicode_start_reg
;
2399 short millicode_end_reg
;
2400 bool save_return_addr
;
2403 /* Defining data structures for per-function information. */
2405 typedef struct GTY (()) machine_function
2407 unsigned int fn_type
;
2408 struct arc_frame_info frame_info
;
2409 /* To keep track of unalignment caused by short insns. */
2411 int force_short_suffix
; /* Used when disgorging return delay slot insns. */
2412 const char *size_reason
;
2413 struct arc_ccfsm ccfsm_current
;
2414 /* Map from uid to ccfsm state during branch shortening. */
2415 rtx ccfsm_current_insn
;
2416 char arc_reorg_started
;
2417 char prescan_initialized
;
2420 /* Type of function DECL.
2422 The result is cached. To reset the cache at the end of a function,
2423 call with DECL = NULL_TREE. */
2426 arc_compute_function_type (struct function
*fun
)
2428 tree attr
, decl
= fun
->decl
;
2429 unsigned int fn_type
= fun
->machine
->fn_type
;
2431 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2434 /* Check if it is a naked function. */
2435 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2436 fn_type
|= ARC_FUNCTION_NAKED
;
2438 fn_type
|= ARC_FUNCTION_NORMAL
;
2440 /* Now see if this is an interrupt handler. */
2441 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2442 if (attr
!= NULL_TREE
)
2444 tree value
, args
= TREE_VALUE (attr
);
2446 gcc_assert (list_length (args
) == 1);
2447 value
= TREE_VALUE (args
);
2448 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2450 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2451 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2452 fn_type
|= ARC_FUNCTION_ILINK1
;
2453 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2454 fn_type
|= ARC_FUNCTION_ILINK2
;
2455 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2456 fn_type
|= ARC_FUNCTION_FIRQ
;
2461 return fun
->machine
->fn_type
= fn_type
;
2464 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2465 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2467 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2468 The return address and frame pointer are treated separately.
2469 Don't consider them here.
2470 Addition for pic: The gp register needs to be saved if the current
2471 function changes it to access gotoff variables.
2472 FIXME: This will not be needed if we used some arbitrary register
2477 arc_must_save_register (int regno
, struct function
*func
)
2479 unsigned int fn_type
= arc_compute_function_type (func
);
2480 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2481 && ARC_AUTO_IRQ_P (fn_type
));
2482 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2484 switch (rgf_banked_register_count
)
2487 firq_auto_save_p
&= (regno
< 4);
2490 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2493 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2494 || ((regno
> 25) && (regno
< 29))
2495 || ((regno
> 29) && (regno
< 32)));
2498 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2501 firq_auto_save_p
= false;
2505 if ((regno
) != RETURN_ADDR_REGNUM
2506 && (regno
) != FRAME_POINTER_REGNUM
2507 && df_regs_ever_live_p (regno
)
2508 && (!call_used_regs
[regno
]
2509 || ARC_INTERRUPT_P (fn_type
))
2510 /* Do not emit code for auto saved regs. */
2512 && !firq_auto_save_p
)
2515 if (flag_pic
&& crtl
->uses_pic_offset_table
2516 && regno
== PIC_OFFSET_TABLE_REGNUM
)
2522 /* Return true if the return address must be saved in the current function,
2523 otherwise return false. */
2526 arc_must_save_return_addr (struct function
*func
)
2528 if (func
->machine
->frame_info
.save_return_addr
)
2534 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2535 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2536 Register Allocator) pass, while we want to get the frame size
2537 correct earlier than the IRA pass. */
2539 arc_frame_pointer_needed (void)
2541 return (frame_pointer_needed
);
2545 /* Return non-zero if there are registers to be saved or loaded using
2546 millicode thunks. We can only use consecutive sequences starting
2547 with r13, and not going beyond r25.
2548 GMASK is a bitmask of registers to save. This function sets
2549 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2550 of registers to be saved / restored with a millicode call. */
2553 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2554 struct arc_frame_info
*frame
)
2558 int start_reg
= 13, end_reg
= 25;
2560 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2562 end_reg
= regno
- 1;
2563 /* There is no point in using millicode thunks if we don't save/restore
2564 at least three registers. For non-leaf functions we also have the
2566 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2568 frame
->millicode_start_reg
= 13;
2569 frame
->millicode_end_reg
= regno
- 1;
2575 /* Return the bytes needed to compute the frame pointer from the current
2578 SIZE is the size needed for local variables. */
2581 arc_compute_frame_size (int size
) /* size = # of var. bytes allocated. */
2584 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2585 unsigned int reg_size
, reg_offset
;
2587 struct arc_frame_info
*frame_info
= &cfun
->machine
->frame_info
;
2589 size
= ARC_STACK_ALIGN (size
);
2591 /* 1) Size of locals and temporaries */
2594 /* 2) Size of outgoing arguments */
2595 args_size
= crtl
->outgoing_args_size
;
2597 /* 3) Calculate space needed for saved registers.
2598 ??? We ignore the extension registers for now. */
2600 /* See if this is an interrupt handler. Call used registers must be saved
2606 for (regno
= 0; regno
<= 31; regno
++)
2608 if (arc_must_save_register (regno
, cfun
))
2610 reg_size
+= UNITS_PER_WORD
;
2611 gmask
|= 1L << regno
;
2615 /* 4) Space for back trace data structure.
2616 <return addr reg size> (if required) + <fp size> (if required). */
2617 frame_info
->save_return_addr
2618 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
));
2619 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2620 if (optimize_size
&& !TARGET_NO_MILLICODE_THUNK_SET
)
2622 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2623 frame_info
->save_return_addr
= true;
2627 if (arc_must_save_return_addr (cfun
))
2629 if (arc_frame_pointer_needed ())
2632 /* 5) Space for variable arguments passed in registers */
2633 pretend_size
= crtl
->args
.pretend_args_size
;
2635 /* Ensure everything before the locals is aligned appropriately. */
2637 unsigned int extra_plus_reg_size
;
2638 unsigned int extra_plus_reg_size_aligned
;
2640 extra_plus_reg_size
= extra_size
+ reg_size
;
2641 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2642 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2645 /* Compute total frame size. */
2646 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2648 total_size
= ARC_STACK_ALIGN (total_size
);
2650 /* Compute offset of register save area from stack pointer:
2651 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2653 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2654 + (arc_frame_pointer_needed () ? 4 : 0));
2656 /* Save computed information. */
2657 frame_info
->total_size
= total_size
;
2658 frame_info
->extra_size
= extra_size
;
2659 frame_info
->pretend_size
= pretend_size
;
2660 frame_info
->var_size
= var_size
;
2661 frame_info
->args_size
= args_size
;
2662 frame_info
->reg_size
= reg_size
;
2663 frame_info
->reg_offset
= reg_offset
;
2664 frame_info
->gmask
= gmask
;
2665 frame_info
->initialized
= reload_completed
;
2667 /* Ok, we're done. */
2671 /* Common code to save/restore registers. */
2672 /* BASE_REG is the base register to use for addressing and to adjust.
2673 GMASK is a bitmask of general purpose registers to save/restore.
2674 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2675 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2676 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2680 arc_save_restore (rtx base_reg
,
2681 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2683 unsigned int offset
= 0;
2685 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2686 rtx sibthunk_insn
= NULL_RTX
;
2690 /* Millicode thunks implementation:
2691 Generates calls to millicodes for registers starting from r13 to r25
2692 Present Limitations:
2693 - Only one range supported. The remaining regs will have the ordinary
2694 st and ld instructions for store and loads. Hence a gmask asking
2695 to store r13-14, r16-r25 will only generate calls to store and
2696 load r13 to r14 while store and load insns will be generated for
2697 r16 to r25 in the prologue and epilogue respectively.
2699 - Presently library only supports register ranges starting from r13.
2701 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2703 int start_call
= frame
->millicode_start_reg
;
2704 int end_call
= frame
->millicode_end_reg
;
2705 int n_regs
= end_call
- start_call
+ 1;
2706 int i
= 0, r
, off
= 0;
2708 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2712 /* "reg_size" won't be more than 127 . */
2713 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
2714 frame_add (base_reg
, *first_offset
);
2717 insn
= gen_rtx_PARALLEL
2718 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
2719 if (epilogue_p
== 2)
2722 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
2723 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
2725 rtx reg
= gen_rtx_REG (SImode
, r
);
2727 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
2730 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
2732 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
2733 gmask
= gmask
& ~(1L << r
);
2735 if (epilogue_p
== 2)
2736 sibthunk_insn
= insn
;
2739 insn
= frame_insn (insn
);
2741 for (r
= start_call
; r
<= end_call
; r
++)
2743 rtx reg
= gen_rtx_REG (SImode
, r
);
2744 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2750 for (regno
= 0; regno
<= 31; regno
++)
2752 machine_mode mode
= SImode
;
2757 && ((gmask
& (1L << regno
)) != 0)
2758 && ((gmask
& (1L << (regno
+1))) != 0))
2763 else if ((gmask
& (1L << regno
)) != 0)
2771 rtx reg
= gen_rtx_REG (mode
, regno
);
2773 int cfa_adjust
= *first_offset
;
2777 gcc_assert (!offset
);
2778 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
2779 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
2784 gcc_assert (SMALL_INT (offset
));
2785 addr
= plus_constant (Pmode
, base_reg
, offset
);
2787 mem
= gen_frame_mem (mode
, addr
);
2791 frame_move_inc (reg
, mem
, base_reg
, addr
);
2792 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2795 enum reg_note note
= REG_CFA_ADJUST_CFA
;
2796 add_reg_note (insn
, note
,
2797 gen_rtx_SET (stack_pointer_rtx
,
2798 plus_constant (Pmode
,
2804 frame_move_inc (mem
, reg
, base_reg
, addr
);
2805 offset
+= UNITS_PER_WORD
;
2808 offset
+= UNITS_PER_WORD
;
2816 int start_call
= frame
->millicode_start_reg
;
2817 int end_call
= frame
->millicode_end_reg
;
2820 rtx r12
= gen_rtx_REG (Pmode
, 12);
2822 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
2823 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
2824 XVECEXP (sibthunk_insn
, 0, 1)
2825 = gen_rtx_SET (stack_pointer_rtx
,
2826 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
2827 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
2828 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
2830 /* Would be nice if we could do this earlier, when the PARALLEL
2831 is populated, but these need to be attached after the
2833 for (r
= start_call
; r
<= end_call
; r
++)
2835 rtx reg
= gen_rtx_REG (SImode
, r
);
2836 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
2839 } /* arc_save_restore */
2841 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2845 arc_dwarf_emit_irq_save_regs (void)
2847 rtx tmp
, par
, insn
, reg
;
2850 par
= gen_rtx_SEQUENCE (VOIDmode
,
2851 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2852 + irq_ctrl_saved
.irq_save_blink
2853 + irq_ctrl_saved
.irq_save_lpcount
2856 /* Build the stack adjustment note for unwind info. */
2858 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2859 + irq_ctrl_saved
.irq_save_blink
2860 + irq_ctrl_saved
.irq_save_lpcount
);
2861 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2862 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2863 RTX_FRAME_RELATED_P (tmp
) = 1;
2864 XVECEXP (par
, 0, j
++) = tmp
;
2866 offset
-= UNITS_PER_WORD
;
2868 /* 1st goes LP_COUNT. */
2869 if (irq_ctrl_saved
.irq_save_lpcount
)
2871 reg
= gen_rtx_REG (SImode
, 60);
2872 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2873 tmp
= gen_frame_mem (SImode
, tmp
);
2874 tmp
= gen_rtx_SET (tmp
, reg
);
2875 RTX_FRAME_RELATED_P (tmp
) = 1;
2876 XVECEXP (par
, 0, j
++) = tmp
;
2877 offset
-= UNITS_PER_WORD
;
2880 /* 2nd goes BLINK. */
2881 if (irq_ctrl_saved
.irq_save_blink
)
2883 reg
= gen_rtx_REG (SImode
, 31);
2884 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2885 tmp
= gen_frame_mem (SImode
, tmp
);
2886 tmp
= gen_rtx_SET (tmp
, reg
);
2887 RTX_FRAME_RELATED_P (tmp
) = 1;
2888 XVECEXP (par
, 0, j
++) = tmp
;
2889 offset
-= UNITS_PER_WORD
;
2892 /* Build the parallel of the remaining registers recorded as saved
2894 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
2896 reg
= gen_rtx_REG (SImode
, i
);
2897 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2898 tmp
= gen_frame_mem (SImode
, tmp
);
2899 tmp
= gen_rtx_SET (tmp
, reg
);
2900 RTX_FRAME_RELATED_P (tmp
) = 1;
2901 XVECEXP (par
, 0, j
++) = tmp
;
2902 offset
-= UNITS_PER_WORD
;
2905 /* Dummy insn used to anchor the dwarf info. */
2906 insn
= emit_insn (gen_stack_irq_dwarf());
2907 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
2908 RTX_FRAME_RELATED_P (insn
) = 1;
2911 /* Set up the stack and frame pointer (if desired) for the function. */
2914 arc_expand_prologue (void)
2916 int size
= get_frame_size ();
2917 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
2918 /* unsigned int frame_pointer_offset;*/
2919 unsigned int frame_size_to_allocate
;
2920 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2921 Change the stack layout so that we rather store a high register with the
2922 PRE_MODIFY, thus enabling more short insn generation.) */
2923 int first_offset
= 0;
2924 unsigned int fn_type
= arc_compute_function_type (cfun
);
2926 /* Naked functions don't have prologue. */
2927 if (ARC_NAKED_P (fn_type
))
2930 size
= ARC_STACK_ALIGN (size
);
2932 /* Compute/get total frame size. */
2933 size
= (!cfun
->machine
->frame_info
.initialized
2934 ? arc_compute_frame_size (size
)
2935 : cfun
->machine
->frame_info
.total_size
);
2937 if (flag_stack_usage_info
)
2938 current_function_static_stack_size
= size
;
2940 /* Keep track of frame size to be allocated. */
2941 frame_size_to_allocate
= size
;
2943 /* These cases shouldn't happen. Catch them now. */
2944 gcc_assert (!(size
== 0 && gmask
));
2946 /* Allocate space for register arguments if this is a variadic function. */
2947 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
2949 /* Ensure pretend_size is maximum of 8 * word_size. */
2950 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
2952 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
2953 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
2956 /* IRQ using automatic save mechanism will save the register before
2958 if (ARC_AUTO_IRQ_P (fn_type
)
2959 && !ARC_FAST_INTERRUPT_P (fn_type
))
2961 arc_dwarf_emit_irq_save_regs ();
2964 /* The home-grown ABI says link register is saved first. */
2965 if (arc_must_save_return_addr (cfun
)
2966 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
2968 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
2969 rtx mem
= gen_frame_mem (Pmode
,
2970 gen_rtx_PRE_DEC (Pmode
,
2971 stack_pointer_rtx
));
2973 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
2974 frame_size_to_allocate
-= UNITS_PER_WORD
;
2977 /* Save any needed call-saved regs (and call-used if this is an
2978 interrupt handler) for ARCompact ISA. */
2979 if (cfun
->machine
->frame_info
.reg_size
)
2981 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
2982 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
2983 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
2984 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
2987 /* Save frame pointer if needed. First save the FP on stack, if not
2989 if (arc_frame_pointer_needed ()
2990 && !ARC_AUTOFP_IRQ_P (fn_type
))
2992 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
2993 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
2994 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
2997 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
2998 frame_size_to_allocate
-= UNITS_PER_WORD
;
3002 /* Emit mov fp,sp. */
3003 if (arc_frame_pointer_needed ())
3005 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
3008 /* ??? We don't handle the case where the saved regs are more than 252
3009 bytes away from sp. This can be handled by decrementing sp once, saving
3010 the regs, and then decrementing it again. The epilogue doesn't have this
3011 problem as the `ld' insn takes reg+limm values (though it would be more
3012 efficient to avoid reg+limm). */
3014 frame_size_to_allocate
-= first_offset
;
3015 /* Allocate the stack frame. */
3016 if (frame_size_to_allocate
> 0)
3018 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3019 /* If the frame pointer is needed, emit a special barrier that
3020 will prevent the scheduler from moving stores to the frame
3021 before the stack adjustment. */
3022 if (arc_frame_pointer_needed ())
3023 emit_insn (gen_stack_tie (stack_pointer_rtx
,
3024 hard_frame_pointer_rtx
));
3027 /* Setup the gp register, if needed. */
3028 if (crtl
->uses_pic_offset_table
)
3029 arc_finalize_pic ();
3032 /* Do any necessary cleanup after a function to restore stack, frame,
3036 arc_expand_epilogue (int sibcall_p
)
3038 int size
= get_frame_size ();
3039 unsigned int fn_type
= arc_compute_function_type (cfun
);
3041 size
= ARC_STACK_ALIGN (size
);
3042 size
= (!cfun
->machine
->frame_info
.initialized
3043 ? arc_compute_frame_size (size
)
3044 : cfun
->machine
->frame_info
.total_size
);
3046 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
3047 unsigned int frame_size
;
3048 unsigned int size_to_deallocate
;
3050 int can_trust_sp_p
= !cfun
->calls_alloca
;
3051 int first_offset
= 0;
3052 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
3055 /* Naked functions don't have epilogue. */
3056 if (ARC_NAKED_P (fn_type
))
3059 size_to_deallocate
= size
;
3061 frame_size
= size
- (pretend_size
+
3062 cfun
->machine
->frame_info
.reg_size
+
3063 cfun
->machine
->frame_info
.extra_size
);
3065 /* ??? There are lots of optimizations that can be done here.
3066 EG: Use fp to restore regs if it's closer.
3067 Maybe in time we'll do them all. For now, always restore regs from
3068 sp, but don't restore sp if we don't have to. */
3070 if (!can_trust_sp_p
)
3071 gcc_assert (arc_frame_pointer_needed ());
3073 /* Restore stack pointer to the beginning of saved register area for
3077 if (arc_frame_pointer_needed ())
3078 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
3080 first_offset
= frame_size
;
3081 size_to_deallocate
-= frame_size
;
3083 else if (!can_trust_sp_p
)
3084 frame_stack_add (-frame_size
);
3087 /* Restore any saved registers. */
3088 if (arc_frame_pointer_needed ()
3089 && !ARC_AUTOFP_IRQ_P (fn_type
))
3091 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
3093 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
3094 stack_pointer_rtx
, 0);
3095 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
3096 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3097 plus_constant (SImode
, stack_pointer_rtx
,
3099 size_to_deallocate
-= UNITS_PER_WORD
;
3102 /* Load blink after the calls to thunk calls in case of optimize size. */
3105 int sibthunk_p
= (!sibcall_p
3106 && fn_type
== ARC_FUNCTION_NORMAL
3107 && !cfun
->machine
->frame_info
.pretend_size
);
3109 gcc_assert (!(cfun
->machine
->frame_info
.gmask
3110 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
3111 arc_save_restore (stack_pointer_rtx
,
3112 cfun
->machine
->frame_info
.gmask
,
3113 1 + sibthunk_p
, &first_offset
);
3117 /* If we are to restore registers, and first_offset would require
3118 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3119 fast add to the stack pointer, do this now. */
3120 if ((!SMALL_INT (first_offset
)
3121 && cfun
->machine
->frame_info
.gmask
3122 && ((TARGET_ARC700
&& !optimize_size
)
3123 ? first_offset
<= 0x800
3124 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
3125 /* Also do this if we have both gprs and return
3126 address to restore, and they both would need a LIMM. */
3127 || (arc_must_save_return_addr (cfun
)
3128 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
3129 && cfun
->machine
->frame_info
.gmask
))
3131 frame_stack_add (first_offset
);
3134 if (arc_must_save_return_addr (cfun
)
3135 && !ARC_AUTOBLINK_IRQ_P (fn_type
))
3137 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3138 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
3139 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
3140 HOST_WIDE_INT cfa_adjust
= 0;
3142 /* If the load of blink would need a LIMM, but we can add
3143 the offset quickly to sp, do the latter. */
3144 if (!SMALL_INT (ra_offs
>> 2)
3145 && !cfun
->machine
->frame_info
.gmask
3146 && ((TARGET_ARC700
&& !optimize_size
)
3148 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
3150 size_to_deallocate
-= ra_offs
- first_offset
;
3152 frame_stack_add (ra_offs
);
3154 addr
= stack_pointer_rtx
;
3156 /* See if we can combine the load of the return address with the
3157 final stack adjustment.
3158 We need a separate load if there are still registers to
3159 restore. We also want a separate load if the combined insn
3160 would need a limm, but a separate load doesn't. */
3162 && !cfun
->machine
->frame_info
.gmask
3163 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
3165 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
3166 cfa_adjust
= ra_offs
;
3168 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
3170 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
3172 addr
= gen_rtx_POST_INC (Pmode
, addr
);
3173 cfa_adjust
= GET_MODE_SIZE (Pmode
);
3174 size_to_deallocate
= 0;
3177 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
3178 stack_pointer_rtx
, addr
);
3181 enum reg_note note
= REG_CFA_ADJUST_CFA
;
3183 add_reg_note (insn
, note
,
3184 gen_rtx_SET (stack_pointer_rtx
,
3185 plus_constant (SImode
, stack_pointer_rtx
,
3188 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
3193 if (cfun
->machine
->frame_info
.reg_size
)
3194 arc_save_restore (stack_pointer_rtx
,
3195 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3196 cfun
->machine
->frame_info
.gmask
3197 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
3200 /* The rest of this function does the following:
3201 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3204 /* Keep track of how much of the stack pointer we've restored.
3205 It makes the following a lot more readable. */
3206 size_to_deallocate
+= first_offset
;
3207 restored
= size
- size_to_deallocate
;
3209 if (size
> restored
)
3210 frame_stack_add (size
- restored
);
3212 /* Emit the return instruction. */
3213 if (sibcall_p
== FALSE
)
3214 emit_jump_insn (gen_simple_return ());
3217 /* Return the offset relative to the stack pointer where the return address
3218 is stored, or -1 if it is not stored. */
3221 arc_return_slot_offset ()
3223 struct arc_frame_info
*afi
= &cfun
->machine
->frame_info
;
3225 return (afi
->save_return_addr
3226 ? afi
->total_size
- afi
->pretend_size
- afi
->extra_size
: -1);
3231 /* Helper to generate unspec constant. */
3234 arc_unspec_offset (rtx loc
, int unspec
)
3236 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
3240 /* Emit special PIC prologues and epilogues. */
3241 /* If the function has any GOTOFF relocations, then the GOTBASE
3242 register has to be setup in the prologue
3243 The instruction needed at the function start for setting up the
3246 ----------------------------------------------------------
3247 The rtl to be emitted for this should be:
3250 (const (unspec (symref _DYNAMIC) 3)))
3251 ---------------------------------------------------------- */
3254 arc_finalize_pic (void)
3257 rtx baseptr_rtx
= gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
);
3259 if (crtl
->uses_pic_offset_table
== 0)
3262 gcc_assert (flag_pic
!= 0);
3264 pat
= gen_rtx_SYMBOL_REF (Pmode
, "_DYNAMIC");
3265 pat
= arc_unspec_offset (pat
, ARC_UNSPEC_GOT
);
3266 pat
= gen_rtx_SET (baseptr_rtx
, pat
);
3271 /* !TARGET_BARREL_SHIFTER support. */
3272 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3276 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
3278 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
3280 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
3281 (op0
, op1
, op2
, shift
));
3285 /* Output the assembler code for doing a shift.
3286 We go to a bit of trouble to generate efficient code as the ARC601 only has
3287 single bit shifts. This is taken from the h8300 port. We only have one
3288 mode of shifting and can't access individual bytes like the h8300 can, so
3289 this is greatly simplified (at the expense of not generating hyper-
3292 This function is not used if the variable shift insns are present. */
3294 /* FIXME: This probably can be done using a define_split in arc.md.
3295 Alternately, generate rtx rather than output instructions. */
3298 output_shift (rtx
*operands
)
3300 /* static int loopend_lab;*/
3301 rtx shift
= operands
[3];
3302 machine_mode mode
= GET_MODE (shift
);
3303 enum rtx_code code
= GET_CODE (shift
);
3304 const char *shift_one
;
3306 gcc_assert (mode
== SImode
);
3310 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
3311 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
3312 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
3313 default: gcc_unreachable ();
3316 if (GET_CODE (operands
[2]) != CONST_INT
)
3318 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
3325 n
= INTVAL (operands
[2]);
3327 /* Only consider the lower 5 bits of the shift count. */
3330 /* First see if we can do them inline. */
3331 /* ??? We could get better scheduling & shorter code (using short insns)
3332 by using splitters. Alas, that'd be even more verbose. */
3333 if (code
== ASHIFT
&& n
<= 9 && n
> 2
3334 && dest_reg_operand (operands
[4], SImode
))
3336 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
3337 for (n
-=3 ; n
>= 3; n
-= 3)
3338 output_asm_insn ("add3 %0,%4,%0", operands
);
3340 output_asm_insn ("add2 %0,%4,%0", operands
);
3342 output_asm_insn ("add %0,%0,%0", operands
);
3348 output_asm_insn (shift_one
, operands
);
3349 operands
[1] = operands
[0];
3352 /* See if we can use a rotate/and. */
3353 else if (n
== BITS_PER_WORD
- 1)
3358 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
3361 /* The ARC doesn't have a rol insn. Use something else. */
3362 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
3365 /* The ARC doesn't have a rol insn. Use something else. */
3366 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
3372 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
3377 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
3380 #if 1 /* Need some scheduling comparisons. */
3381 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3382 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3384 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3385 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
3390 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3391 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
3393 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3394 "and %0,%0,1\n\trlc %0,%0", operands
);
3401 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
3402 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3407 operands
[2] = GEN_INT (n
);
3408 output_asm_insn ("mov.f lp_count, %2", operands
);
3412 output_asm_insn ("lpnz\t2f", operands
);
3413 output_asm_insn (shift_one
, operands
);
3414 output_asm_insn ("nop", operands
);
3415 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
3424 /* Nested function support. */
3426 /* Directly store VALUE into memory object BLOCK at OFFSET. */
3429 emit_store_direct (rtx block
, int offset
, int value
)
3431 emit_insn (gen_store_direct (adjust_address (block
, SImode
, offset
),
3433 gen_int_mode (value
, SImode
))));
3436 /* Emit RTL insns to initialize the variable parts of a trampoline.
3437 FNADDR is an RTX for the address of the function's pure code.
3438 CXT is an RTX for the static chain value for the function. */
3439 /* With potentially multiple shared objects loaded, and multiple stacks
3440 present for multiple thereds where trampolines might reside, a simple
3441 range check will likely not suffice for the profiler to tell if a callee
3442 is a trampoline. We a speedier check by making the trampoline start at
3443 an address that is not 4-byte aligned.
3444 A trampoline looks like this:
3448 ld_s r12,[pcl,12] 0xd403
3449 ld r11,[pcl,12] 0x170c 700b
3453 The fastest trampoline to execute for trampolines within +-8KB of CTX
3456 j [limm] 0x20200f80 limm
3457 and that would also be faster to write to the stack by computing the offset
3458 from CTX to TRAMP at compile time. However, it would really be better to
3459 get rid of the high cost of cache invalidation when generating trampolines,
3460 which requires that the code part of trampolines stays constant, and
3462 - making sure that no executable code but trampolines is on the stack,
3463 no icache entries linger for the area of the stack from when before the
3464 stack was allocated, and allocating trampolines in trampoline-only
3467 - allocate trampolines fram a special pool of pre-allocated trampolines. */
3470 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
3472 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
3474 emit_store_direct (tramp
, 0, TARGET_BIG_ENDIAN
? 0x78e0d403 : 0xd40378e0);
3475 emit_store_direct (tramp
, 4, TARGET_BIG_ENDIAN
? 0x170c700b : 0x700b170c);
3476 emit_store_direct (tramp
, 8, TARGET_BIG_ENDIAN
? 0x7c0078e0 : 0x78e07c00);
3477 emit_move_insn (adjust_address (tramp
, SImode
, 12), fnaddr
);
3478 emit_move_insn (adjust_address (tramp
, SImode
, 16), cxt
);
3479 emit_insn (gen_flush_icache (adjust_address (tramp
, SImode
, 0)));
3482 /* Allow the profiler to easily distinguish trampolines from normal
3486 arc_trampoline_adjust_address (rtx addr
)
3488 return plus_constant (Pmode
, addr
, 2);
3491 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3492 reset when we output the scaled address. */
3493 static int output_scaled
= 0;
3495 /* Print operand X (an rtx) in assembler syntax to file FILE.
3496 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3497 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3498 /* In final.c:output_asm_insn:
3501 'c' : constant address if CONSTANT_ADDRESS_P
3507 'p': bit Position of lsb
3508 's': size of bit field
3509 '#': condbranch delay slot suffix
3510 '*': jump delay slot suffix
3511 '?' : nonjump-insn suffix for conditional execution or short instruction
3512 '!' : jump / call suffix for conditional execution or short instruction
3513 '`': fold constant inside unary o-perator, re-recognize, and emit.
3518 'B': Branch comparison operand - suppress sda reference
3519 'H': Most significant word
3520 'L': Least significant word
3521 'A': ASCII decimal representation of floating point value
3522 'U': Load/store update or scaling indicator
3523 'V': cache bypass indicator for volatile
3528 'o': original symbol - no @ prepending. */
3531 arc_print_operand (FILE *file
, rtx x
, int code
)
3536 if (GET_CODE (x
) == CONST_INT
)
3537 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3539 output_operand_lossage ("invalid operand to %%Z code");
3544 if (GET_CODE (x
) == CONST_INT
)
3545 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3547 output_operand_lossage ("invalid operand to %%z code");
3552 if (GET_CODE (x
) == CONST_INT
)
3553 fprintf (file
, "%d", INTVAL (x
) );
3555 output_operand_lossage ("invalid operands to %%c code");
3560 if (GET_CODE (x
) == CONST_INT
)
3561 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3563 output_operand_lossage ("invalid operand to %%M code");
3568 if (GET_CODE (x
) == CONST_INT
)
3569 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3571 output_operand_lossage ("invalid operand to %%p code");
3575 if (GET_CODE (x
) == CONST_INT
)
3577 HOST_WIDE_INT i
= INTVAL (x
);
3578 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3579 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3582 output_operand_lossage ("invalid operand to %%s code");
3586 /* Conditional branches depending on condition codes.
3587 Note that this is only for branches that were known to depend on
3588 condition codes before delay slot scheduling;
3589 out-of-range brcc / bbit expansions should use '*'.
3590 This distinction is important because of the different
3591 allowable delay slot insns and the output of the delay suffix
3592 for TARGET_AT_DBR_COND_EXEC. */
3594 /* Unconditional branches / branches not depending on condition codes.
3595 This could also be a CALL_INSN.
3596 Output the appropriate delay slot suffix. */
3597 if (final_sequence
&& final_sequence
->len () != 1)
3599 rtx_insn
*jump
= final_sequence
->insn (0);
3600 rtx_insn
*delay
= final_sequence
->insn (1);
3602 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3603 if (delay
->deleted ())
3605 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3606 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3607 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3608 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3615 case '?' : /* with leading "." */
3616 case '!' : /* without leading "." */
3617 /* This insn can be conditionally executed. See if the ccfsm machinery
3618 says it should be conditionalized.
3619 If it shouldn't, we'll check the compact attribute if this insn
3620 has a short variant, which may be used depending on code size and
3621 alignment considerations. */
3622 if (current_insn_predicate
)
3623 arc_ccfsm_current
.cc
3624 = get_arc_condition_code (current_insn_predicate
);
3625 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3627 /* Is this insn in a delay slot sequence? */
3628 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3629 || current_insn_predicate
3630 || CALL_P (final_sequence
->insn (0))
3631 || simplejump_p (final_sequence
->insn (0)))
3633 /* This insn isn't in a delay slot sequence, or conditionalized
3634 independently of its position in a delay slot. */
3635 fprintf (file
, "%s%s",
3636 code
== '?' ? "." : "",
3637 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3638 /* If this is a jump, there are still short variants. However,
3639 only beq_s / bne_s have the same offset range as b_s,
3640 and the only short conditional returns are jeq_s and jne_s. */
3642 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3643 || arc_ccfsm_current
.cc
== ARC_CC_NE
3644 || 0 /* FIXME: check if branch in 7 bit range. */))
3645 output_short_suffix (file
);
3647 else if (code
== '!') /* Jump with delay slot. */
3648 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
3649 else /* An Instruction in a delay slot of a jump or call. */
3651 rtx jump
= XVECEXP (final_sequence
, 0, 0);
3652 rtx insn
= XVECEXP (final_sequence
, 0, 1);
3654 /* If the insn is annulled and is from the target path, we need
3655 to inverse the condition test. */
3656 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3658 if (INSN_FROM_TARGET_P (insn
))
3659 fprintf (file
, "%s%s",
3660 code
== '?' ? "." : "",
3661 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
3663 fprintf (file
, "%s%s",
3664 code
== '?' ? "." : "",
3665 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3666 if (arc_ccfsm_current
.state
== 5)
3667 arc_ccfsm_current
.state
= 0;
3670 /* This insn is executed for either path, so don't
3671 conditionalize it at all. */
3672 output_short_suffix (file
);
3677 output_short_suffix (file
);
3680 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3683 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
3686 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
3687 (get_arc_condition_code (x
))],
3691 /* Write second word of DImode or DFmode reference,
3692 register or memory. */
3693 if (GET_CODE (x
) == REG
)
3694 fputs (reg_names
[REGNO (x
)+1], file
);
3695 else if (GET_CODE (x
) == MEM
)
3699 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3700 PRE_MODIFY, we will have handled the first word already;
3701 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3702 first word will be done later. In either case, the access
3703 to the first word will do the modify, and we only have
3704 to add an offset of four here. */
3705 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
3706 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
3707 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
3708 || GET_CODE (XEXP (x
, 0)) == POST_INC
3709 || GET_CODE (XEXP (x
, 0)) == POST_DEC
3710 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
3711 output_address (VOIDmode
,
3712 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
3713 else if (output_scaled
)
3715 rtx addr
= XEXP (x
, 0);
3716 int size
= GET_MODE_SIZE (GET_MODE (x
));
3718 output_address (VOIDmode
,
3719 plus_constant (Pmode
, XEXP (addr
, 0),
3720 ((INTVAL (XEXP (addr
, 1)) + 4)
3721 >> (size
== 2 ? 1 : 2))));
3725 output_address (VOIDmode
,
3726 plus_constant (Pmode
, XEXP (x
, 0), 4));
3730 output_operand_lossage ("invalid operand to %%R code");
3733 /* FIXME: remove %S option. */
3735 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3738 output_addr_const (file
, x
);
3744 if (GET_CODE (x
) == REG
)
3746 /* L = least significant word, H = most significant word. */
3747 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
3748 fputs (reg_names
[REGNO (x
)], file
);
3750 fputs (reg_names
[REGNO (x
)+1], file
);
3752 else if (GET_CODE (x
) == CONST_INT
3753 || GET_CODE (x
) == CONST_DOUBLE
)
3755 rtx first
, second
, word
;
3757 split_double (x
, &first
, &second
);
3759 if((WORDS_BIG_ENDIAN
) == 0)
3760 word
= (code
== 'L' ? first
: second
);
3762 word
= (code
== 'L' ? second
: first
);
3764 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
3767 output_operand_lossage ("invalid operand to %%H/%%L code");
3773 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
3774 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
3776 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
3777 fprintf (file
, "%s", str
);
3781 /* Output a load/store with update indicator if appropriate. */
3782 if (GET_CODE (x
) == MEM
)
3784 rtx addr
= XEXP (x
, 0);
3785 switch (GET_CODE (addr
))
3787 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
3788 fputs (".a", file
); break;
3789 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
3790 fputs (".ab", file
); break;
3792 /* Are we using a scaled index? */
3793 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3794 fputs (".as", file
);
3795 /* Can we use a scaled offset? */
3796 else if (CONST_INT_P (XEXP (addr
, 1))
3797 && GET_MODE_SIZE (GET_MODE (x
)) > 1
3798 && (!(INTVAL (XEXP (addr
, 1))
3799 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
3800 /* Does it make a difference? */
3801 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
3802 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
3804 fputs (".as", file
);
3811 gcc_assert (CONSTANT_P (addr
)); break;
3815 output_operand_lossage ("invalid operand to %%U code");
3818 /* Output cache bypass indicator for a load/store insn. Volatile memory
3819 refs are defined to use the cache bypass mechanism. */
3820 if (GET_CODE (x
) == MEM
)
3822 if (MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
3823 fputs (".di", file
);
3826 output_operand_lossage ("invalid operand to %%V code");
3831 /* Do nothing special. */
3834 fputs (reg_names
[REGNO (x
)]+1, file
);
3837 /* This punctuation character is needed because label references are
3838 printed in the output template using %l. This is a front end
3839 character, and when we want to emit a '@' before it, we have to use
3845 /* Output an operator. */
3846 switch (GET_CODE (x
))
3848 case PLUS
: fputs ("add", file
); return;
3849 case SS_PLUS
: fputs ("adds", file
); return;
3850 case AND
: fputs ("and", file
); return;
3851 case IOR
: fputs ("or", file
); return;
3852 case XOR
: fputs ("xor", file
); return;
3853 case MINUS
: fputs ("sub", file
); return;
3854 case SS_MINUS
: fputs ("subs", file
); return;
3855 case ASHIFT
: fputs ("asl", file
); return;
3856 case ASHIFTRT
: fputs ("asr", file
); return;
3857 case LSHIFTRT
: fputs ("lsr", file
); return;
3858 case ROTATERT
: fputs ("ror", file
); return;
3859 case MULT
: fputs ("mpy", file
); return;
3860 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
3861 case NEG
: fputs ("neg", file
); return;
3862 case SS_NEG
: fputs ("negs", file
); return;
3863 case NOT
: fputs ("not", file
); return; /* Unconditional. */
3865 fputs ("ext", file
); /* bmsk allows predication. */
3867 case SIGN_EXTEND
: /* Unconditional. */
3868 fputs ("sex", file
);
3870 switch (GET_MODE (XEXP (x
, 0)))
3872 case QImode
: fputs ("b", file
); return;
3873 case HImode
: fputs ("w", file
); return;
3878 if (GET_MODE (x
) != HImode
)
3880 fputs ("sat16", file
);
3883 output_operand_lossage ("invalid operand to %%O code"); return;
3885 if (GET_CODE (x
) == SYMBOL_REF
)
3887 assemble_name (file
, XSTR (x
, 0));
3892 if (TARGET_ANNOTATE_ALIGN
&& cfun
->machine
->size_reason
)
3893 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
3909 output_operand_lossage ("invalid operand output code");
3912 switch (GET_CODE (x
))
3915 fputs (reg_names
[REGNO (x
)], file
);
3919 rtx addr
= XEXP (x
, 0);
3920 int size
= GET_MODE_SIZE (GET_MODE (x
));
3924 switch (GET_CODE (addr
))
3926 case PRE_INC
: case POST_INC
:
3927 output_address (VOIDmode
,
3928 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
3929 case PRE_DEC
: case POST_DEC
:
3930 output_address (VOIDmode
,
3931 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
3933 case PRE_MODIFY
: case POST_MODIFY
:
3934 output_address (VOIDmode
, XEXP (addr
, 1)); break;
3938 output_address (VOIDmode
,
3939 plus_constant (Pmode
, XEXP (addr
, 0),
3940 (INTVAL (XEXP (addr
, 1))
3941 >> (size
== 2 ? 1 : 2))));
3945 output_address (VOIDmode
, addr
);
3948 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
3949 arc_output_pic_addr_const (file
, addr
, code
);
3951 output_address (VOIDmode
, addr
);
3958 /* We handle SFmode constants here as output_addr_const doesn't. */
3959 if (GET_MODE (x
) == SFmode
)
3963 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
3964 fprintf (file
, "0x%08lx", l
);
3968 /* Let output_addr_const deal with it. */
3971 || (GET_CODE (x
) == CONST
3972 && GET_CODE (XEXP (x
, 0)) == UNSPEC
3973 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
3974 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
3975 || (GET_CODE (x
) == CONST
3976 && GET_CODE (XEXP (x
, 0)) == PLUS
3977 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
3978 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
3979 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
3980 arc_output_pic_addr_const (file
, x
, code
);
3983 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3984 with asm_output_symbol_ref */
3985 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
)
3988 output_addr_const (file
, XEXP (x
, 0));
3989 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (XEXP (x
, 0)))
3990 fprintf (file
, "@sda");
3992 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
3993 || INTVAL (XEXP (x
, 1)) >= 0)
3994 fprintf (file
, "+");
3995 output_addr_const (file
, XEXP (x
, 1));
3998 output_addr_const (file
, x
);
4000 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
4001 fprintf (file
, "@sda");
4006 /* Print a memory address as an operand to reference that memory location. */
4009 arc_print_operand_address (FILE *file
, rtx addr
)
4011 register rtx base
, index
= 0;
4013 switch (GET_CODE (addr
))
4016 fputs (reg_names
[REGNO (addr
)], file
);
4019 output_addr_const (file
, addr
);
4020 if (SYMBOL_REF_SMALL_P (addr
))
4021 fprintf (file
, "@sda");
4024 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4025 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
4026 else if (CONST_INT_P (XEXP (addr
, 0)))
4027 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
4029 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
4031 gcc_assert (OBJECT_P (base
));
4032 arc_print_operand_address (file
, base
);
4033 if (CONSTANT_P (base
) && CONST_INT_P (index
))
4037 gcc_assert (OBJECT_P (index
));
4038 arc_print_operand_address (file
, index
);
4042 rtx c
= XEXP (addr
, 0);
4044 if ((GET_CODE (c
) == UNSPEC
4045 && (XINT (c
, 1) == UNSPEC_TLS_OFF
4046 || XINT (c
, 1) == UNSPEC_TLS_IE
))
4047 || (GET_CODE (c
) == PLUS
4048 && GET_CODE (XEXP (c
, 0)) == UNSPEC
4049 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
4050 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
4052 arc_output_pic_addr_const (file
, c
, 0);
4055 gcc_assert (GET_CODE (c
) == PLUS
);
4056 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
4057 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
4059 output_address (VOIDmode
, XEXP (addr
, 0));
4065 /* We shouldn't get here as we've lost the mode of the memory object
4066 (which says how much to inc/dec by. */
4071 arc_output_pic_addr_const (file
, addr
, 0);
4073 output_addr_const (file
, addr
);
4078 /* Conditional execution support.
4080 This is based on the ARM port but for now is much simpler.
4082 A finite state machine takes care of noticing whether or not instructions
4083 can be conditionally executed, and thus decrease execution time and code
4084 size by deleting branch instructions. The fsm is controlled by
4085 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4086 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4087 insns also have a hand in this. */
4088 /* The way we leave dealing with non-anulled or annull-false delay slot
4089 insns to the consumer is awkward. */
4091 /* The state of the fsm controlling condition codes are:
4092 0: normal, do nothing special
4093 1: don't output this insn
4094 2: don't output this insn
4095 3: make insns conditional
4096 4: make insns conditional
4097 5: make insn conditional (only for outputting anulled delay slot insns)
4099 special value for cfun->machine->uid_ccfsm_state:
4100 6: return with but one insn before it since function start / call
4102 State transitions (state->state by whom, under what condition):
4103 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4105 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4106 by zero or more non-jump insns and an unconditional branch with
4107 the same target label as the condbranch.
4108 1 -> 3 branch patterns, after having not output the conditional branch
4109 2 -> 4 branch patterns, after having not output the conditional branch
4110 0 -> 5 branch patterns, for anulled delay slot insn.
4111 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4112 (the target label has CODE_LABEL_NUMBER equal to
4113 arc_ccfsm_target_label).
4114 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4115 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4116 5 -> 0 when outputting the delay slot insn
4118 If the jump clobbers the conditions then we use states 2 and 4.
4120 A similar thing can be done with conditional return insns.
4122 We also handle separating branches from sets of the condition code.
4123 This is done here because knowledge of the ccfsm state is required,
4124 we may not be outputting the branch. */
4126 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4127 before letting final output INSN. */
4130 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4132 /* BODY will hold the body of INSN. */
4135 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4136 an if/then/else), and things need to be reversed. */
4139 /* If we start with a return insn, we only succeed if we find another one. */
4140 int seeking_return
= 0;
4142 /* START_INSN will hold the insn from where we start looking. This is the
4143 first insn after the following code_label if REVERSE is true. */
4144 rtx_insn
*start_insn
= insn
;
4146 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4147 since they don't rely on a cmp preceding the. */
4148 enum attr_type jump_insn_type
;
4150 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4151 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4152 final_scan_insn which has `optimize' as a local. */
4153 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
4156 /* Ignore notes and labels. */
4159 body
= PATTERN (insn
);
4160 /* If in state 4, check if the target branch is reached, in order to
4161 change back to state 0. */
4162 if (state
->state
== 4)
4164 if (insn
== state
->target_insn
)
4166 state
->target_insn
= NULL
;
4172 /* If in state 3, it is possible to repeat the trick, if this insn is an
4173 unconditional branch to a label, and immediately following this branch
4174 is the previous target label which is only used once, and the label this
4175 branch jumps to is not too far off. Or in other words "we've done the
4176 `then' part, see if we can do the `else' part." */
4177 if (state
->state
== 3)
4179 if (simplejump_p (insn
))
4181 start_insn
= next_nonnote_insn (start_insn
);
4182 if (GET_CODE (start_insn
) == BARRIER
)
4184 /* ??? Isn't this always a barrier? */
4185 start_insn
= next_nonnote_insn (start_insn
);
4187 if (GET_CODE (start_insn
) == CODE_LABEL
4188 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4189 && LABEL_NUSES (start_insn
) == 1)
4194 else if (GET_CODE (body
) == SIMPLE_RETURN
)
4196 start_insn
= next_nonnote_insn (start_insn
);
4197 if (GET_CODE (start_insn
) == BARRIER
)
4198 start_insn
= next_nonnote_insn (start_insn
);
4199 if (GET_CODE (start_insn
) == CODE_LABEL
4200 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
4201 && LABEL_NUSES (start_insn
) == 1)
4213 if (GET_CODE (insn
) != JUMP_INSN
4214 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
4215 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
4218 /* We can't predicate BRCC or loop ends.
4219 Also, when generating PIC code, and considering a medium range call,
4220 we can't predicate the call. */
4221 jump_insn_type
= get_attr_type (insn
);
4222 if (jump_insn_type
== TYPE_BRCC
4223 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
4224 || jump_insn_type
== TYPE_LOOP_END
4225 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
4228 /* This jump might be paralleled with a clobber of the condition codes,
4229 the jump should always come first. */
4230 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
4231 body
= XVECEXP (body
, 0, 0);
4234 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
4235 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
4237 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
4238 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4239 int then_not_else
= TRUE
;
4240 /* Nonzero if next insn must be the target label. */
4241 int next_must_be_target_label_p
;
4242 rtx_insn
*this_insn
= start_insn
;
4245 /* Register the insn jumped to. */
4248 if (!seeking_return
)
4249 label
= XEXP (SET_SRC (body
), 0);
4251 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
4252 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
4253 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
4255 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
4256 then_not_else
= FALSE
;
4258 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
4260 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
4263 then_not_else
= FALSE
;
4268 /* If this is a non-annulled branch with a delay slot, there is
4269 no need to conditionalize the delay slot. */
4270 if (NEXT_INSN (PREV_INSN (insn
)) != insn
4271 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
4273 this_insn
= NEXT_INSN (this_insn
);
4274 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn
)))
4275 == NEXT_INSN (this_insn
));
4277 /* See how many insns this branch skips, and what kind of insns. If all
4278 insns are okay, and the label or unconditional branch to the same
4279 label is not too far away, succeed. */
4280 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
4281 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
4286 this_insn
= next_nonnote_insn (this_insn
);
4290 if (next_must_be_target_label_p
)
4292 if (GET_CODE (this_insn
) == BARRIER
)
4294 if (GET_CODE (this_insn
) == CODE_LABEL
4295 && this_insn
== label
)
4305 switch (GET_CODE (this_insn
))
4308 /* Succeed if it is the target label, otherwise fail since
4309 control falls in from somewhere else. */
4310 if (this_insn
== label
)
4320 /* Succeed if the following insn is the target label.
4322 If return insns are used then the last insn in a function
4323 will be a barrier. */
4324 next_must_be_target_label_p
= TRUE
;
4328 /* Can handle a call insn if there are no insns after it.
4329 IE: The next "insn" is the target label. We don't have to
4330 worry about delay slots as such insns are SEQUENCE's inside
4331 INSN's. ??? It is possible to handle such insns though. */
4332 if (get_attr_cond (this_insn
) == COND_CANUSE
)
4333 next_must_be_target_label_p
= TRUE
;
4339 scanbody
= PATTERN (this_insn
);
4341 /* If this is an unconditional branch to the same label, succeed.
4342 If it is to another label, do nothing. If it is conditional,
4344 /* ??? Probably, the test for the SET and the PC are
4347 if (GET_CODE (scanbody
) == SET
4348 && GET_CODE (SET_DEST (scanbody
)) == PC
)
4350 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
4351 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
4356 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
4358 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
4361 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
4367 else if (GET_CODE (scanbody
) == PARALLEL
)
4369 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4375 scanbody
= PATTERN (this_insn
);
4377 /* We can only do this with insns that can use the condition
4378 codes (and don't set them). */
4379 if (GET_CODE (scanbody
) == SET
4380 || GET_CODE (scanbody
) == PARALLEL
)
4382 if (get_attr_cond (this_insn
) != COND_CANUSE
)
4385 /* We can't handle other insns like sequences. */
4397 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
4398 state
->target_label
= CODE_LABEL_NUMBER (label
);
4399 else if (seeking_return
|| state
->state
== 2)
4401 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
4403 this_insn
= next_nonnote_insn (this_insn
);
4405 gcc_assert (!this_insn
||
4406 (GET_CODE (this_insn
) != BARRIER
4407 && GET_CODE (this_insn
) != CODE_LABEL
));
4411 /* Oh dear! we ran off the end, give up. */
4412 extract_insn_cached (insn
);
4414 state
->target_insn
= NULL
;
4417 state
->target_insn
= this_insn
;
4422 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4426 state
->cond
= XEXP (SET_SRC (body
), 0);
4427 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4430 if (reverse
|| then_not_else
)
4431 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4434 /* Restore recog_operand. Getting the attributes of other insns can
4435 destroy this array, but final.c assumes that it remains intact
4436 across this call; since the insn has been recognized already we
4437 call insn_extract direct. */
4438 extract_insn_cached (insn
);
4442 /* Record that we are currently outputting label NUM with prefix PREFIX.
4443 It it's the label we're looking for, reset the ccfsm machinery.
4445 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4448 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4450 if (state
->state
== 3 && state
->target_label
== num
4451 && !strcmp (prefix
, "L"))
4454 state
->target_insn
= NULL
;
4458 /* We are considering a conditional branch with the condition COND.
4459 Check if we want to conditionalize a delay slot insn, and if so modify
4460 the ccfsm state accordingly.
4461 REVERSE says branch will branch when the condition is false. */
4463 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4464 struct arc_ccfsm
*state
)
4466 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4468 state
= &arc_ccfsm_current
;
4470 gcc_assert (state
->state
== 0);
4471 if (seq_insn
!= jump
)
4473 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4475 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4476 && INSN_ANNULLED_BRANCH_P (jump
)
4477 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4480 state
->cc
= get_arc_condition_code (cond
);
4482 arc_ccfsm_current
.cc
4483 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4484 rtx pat
= PATTERN (insn
);
4485 if (GET_CODE (pat
) == COND_EXEC
)
4486 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4487 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4488 == get_arc_condition_code (XEXP (pat
, 0)));
4495 /* Update *STATE as we would when we emit INSN. */
4498 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4500 enum attr_type type
;
4503 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4504 else if (JUMP_P (insn
)
4505 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4506 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4507 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4508 || ((type
== TYPE_UNCOND_BRANCH
4509 || type
== TYPE_RETURN
)
4510 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4512 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4513 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4516 rtx src
= SET_SRC (PATTERN (insn
));
4517 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4521 else if (arc_ccfsm_current
.state
== 5)
4522 arc_ccfsm_current
.state
= 0;
4525 /* Return true if the current insn, which is a conditional branch, is to be
4529 arc_ccfsm_branch_deleted_p (void)
4531 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4534 /* Record a branch isn't output because subsequent insns can be
4538 arc_ccfsm_record_branch_deleted (void)
4540 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4543 /* During insn output, indicate if the current insn is predicated. */
4546 arc_ccfsm_cond_exec_p (void)
4548 return (cfun
->machine
->prescan_initialized
4549 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4552 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4553 and look inside SEQUENCEs. */
4556 arc_next_active_insn (rtx_insn
*insn
, struct arc_ccfsm
*statep
)
4563 arc_ccfsm_post_advance (insn
, statep
);
4564 insn
= NEXT_INSN (insn
);
4565 if (!insn
|| BARRIER_P (insn
))
4568 arc_ccfsm_advance (insn
, statep
);
4570 while (NOTE_P (insn
)
4571 || (cfun
->machine
->arc_reorg_started
4572 && LABEL_P (insn
) && !label_to_alignment (insn
))
4573 || (NONJUMP_INSN_P (insn
)
4574 && (GET_CODE (PATTERN (insn
)) == USE
4575 || GET_CODE (PATTERN (insn
)) == CLOBBER
)));
4576 if (!LABEL_P (insn
))
4578 gcc_assert (INSN_P (insn
));
4579 pat
= PATTERN (insn
);
4580 if (GET_CODE (pat
) == ADDR_VEC
|| GET_CODE (pat
) == ADDR_DIFF_VEC
)
4582 if (GET_CODE (pat
) == SEQUENCE
)
4583 return as_a
<rtx_insn
*> (XVECEXP (pat
, 0, 0));
4588 /* When deciding if an insn should be output short, we want to know something
4589 about the following insns:
4590 - if another insn follows which we know we can output as a short insn
4591 before an alignment-sensitive point, we can output this insn short:
4592 the decision about the eventual alignment can be postponed.
4593 - if a to-be-aligned label comes next, we should output this insn such
4594 as to get / preserve 4-byte alignment.
4595 - if a likely branch without delay slot insn, or a call with an immediately
4596 following short insn comes next, we should out output this insn such as to
4597 get / preserve 2 mod 4 unalignment.
4598 - do the same for a not completely unlikely branch with a short insn
4599 following before any other branch / label.
4600 - in order to decide if we are actually looking at a branch, we need to
4601 call arc_ccfsm_advance.
4602 - in order to decide if we are looking at a short insn, we should know
4603 if it is conditionalized. To a first order of approximation this is
4604 the case if the state from arc_ccfsm_advance from before this insn
4605 indicates the insn is conditionalized. However, a further refinement
4606 could be to not conditionalize an insn if the destination register(s)
4607 is/are dead in the non-executed case. */
4608 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4609 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4610 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4613 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4615 enum attr_iscompact iscompact
;
4616 struct machine_function
*machine
;
4620 iscompact
= get_attr_iscompact (insn
);
4621 if (iscompact
== ISCOMPACT_FALSE
)
4624 machine
= cfun
->machine
;
4626 if (machine
->force_short_suffix
>= 0)
4627 return machine
->force_short_suffix
;
4629 return (get_attr_length (insn
) & 2) != 0;
4632 /* When outputting an instruction (alternative) that can potentially be short,
4633 output the short suffix if the insn is in fact short, and update
4634 cfun->machine->unalign accordingly. */
4637 output_short_suffix (FILE *file
)
4639 rtx_insn
*insn
= current_output_insn
;
4641 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
4643 fprintf (file
, "_s");
4644 cfun
->machine
->unalign
^= 2;
4646 /* Restore recog_operand. */
4647 extract_insn_cached (insn
);
4650 /* Implement FINAL_PRESCAN_INSN. */
4653 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
4654 int noperands ATTRIBUTE_UNUSED
)
4656 if (TARGET_DUMPISIZE
)
4657 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
4659 /* Output a nop if necessary to prevent a hazard.
4660 Don't do this for delay slots: inserting a nop would
4661 alter semantics, and the only time we would find a hazard is for a
4662 call function result - and in that case, the hazard is spurious to
4664 if (PREV_INSN (insn
)
4665 && PREV_INSN (NEXT_INSN (insn
)) == insn
4666 && arc_hazard (prev_real_insn (insn
), insn
))
4668 current_output_insn
=
4669 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn
)));
4670 final_scan_insn (current_output_insn
, asm_out_file
, optimize
, 1, NULL
);
4671 current_output_insn
= insn
;
4673 /* Restore extraction data which might have been clobbered by arc_hazard. */
4674 extract_constrain_insn_cached (insn
);
4676 if (!cfun
->machine
->prescan_initialized
)
4678 /* Clear lingering state from branch shortening. */
4679 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
4680 cfun
->machine
->prescan_initialized
= 1;
4682 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
4684 cfun
->machine
->size_reason
= 0;
4687 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4688 Frame pointer elimination is automatically handled.
4690 All eliminations are permissible. If we need a frame
4691 pointer, we must eliminate ARG_POINTER_REGNUM into
4692 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4695 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4697 return ((to
== FRAME_POINTER_REGNUM
) || !arc_frame_pointer_needed ());
4700 /* Define the offset between two registers, one to be eliminated, and
4701 the other its replacement, at the start of a routine. */
4704 arc_initial_elimination_offset (int from
, int to
)
4706 if (! cfun
->machine
->frame_info
.initialized
)
4707 arc_compute_frame_size (get_frame_size ());
4709 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
4711 return (cfun
->machine
->frame_info
.extra_size
4712 + cfun
->machine
->frame_info
.reg_size
);
4715 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
4717 return (cfun
->machine
->frame_info
.total_size
4718 - cfun
->machine
->frame_info
.pretend_size
);
4721 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
4723 return (cfun
->machine
->frame_info
.total_size
4724 - (cfun
->machine
->frame_info
.pretend_size
4725 + cfun
->machine
->frame_info
.extra_size
4726 + cfun
->machine
->frame_info
.reg_size
));
4733 arc_frame_pointer_required (void)
4735 return cfun
->calls_alloca
;
4739 /* Return the destination address of a branch. */
4742 branch_dest (rtx branch
)
4744 rtx pat
= PATTERN (branch
);
4745 rtx dest
= (GET_CODE (pat
) == PARALLEL
4746 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
4749 if (GET_CODE (dest
) == IF_THEN_ELSE
)
4750 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
4752 dest
= XEXP (dest
, 0);
4753 dest_uid
= INSN_UID (dest
);
4755 return INSN_ADDRESSES (dest_uid
);
4759 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4762 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
4764 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4765 This clears machine specific flags, so has to come first. */
4766 default_encode_section_info (decl
, rtl
, first
);
4768 /* Check if it is a function, and whether it has the
4769 [long/medium/short]_call attribute specified. */
4770 if (TREE_CODE (decl
) == FUNCTION_DECL
)
4772 rtx symbol
= XEXP (rtl
, 0);
4773 int flags
= SYMBOL_REF_FLAGS (symbol
);
4775 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4776 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
4777 tree long_call_attr
= lookup_attribute ("long_call", attr
);
4778 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
4779 tree short_call_attr
= lookup_attribute ("short_call", attr
);
4781 if (long_call_attr
!= NULL_TREE
)
4782 flags
|= SYMBOL_FLAG_LONG_CALL
;
4783 else if (medium_call_attr
!= NULL_TREE
)
4784 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
4785 else if (short_call_attr
!= NULL_TREE
)
4786 flags
|= SYMBOL_FLAG_SHORT_CALL
;
4788 SYMBOL_REF_FLAGS (symbol
) = flags
;
4790 else if (TREE_CODE (decl
) == VAR_DECL
)
4792 rtx symbol
= XEXP (rtl
, 0);
4794 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4795 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
4797 tree sec_attr
= lookup_attribute ("section", attr
);
4800 const char *sec_name
4801 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
4802 if (strcmp (sec_name
, ".cmem") == 0
4803 || strcmp (sec_name
, ".cmem_shared") == 0
4804 || strcmp (sec_name
, ".cmem_private") == 0)
4805 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
4810 /* This is how to output a definition of an internal numbered label where
4811 PREFIX is the class of label and NUM is the number within the class. */
4813 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
4816 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
4817 default_internal_label (stream
, prefix
, labelno
);
4820 /* Set the cpu type and print out other fancy things,
4821 at the top of the file. */
4823 static void arc_file_start (void)
4825 default_file_start ();
4826 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
4829 /* Cost functions. */
4831 /* Compute a (partial) cost for rtx X. Return true if the complete
4832 cost has been computed, and false if subexpressions should be
4833 scanned. In either case, *TOTAL contains the cost result. */
4836 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4837 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4839 int code
= GET_CODE (x
);
4843 /* Small integers are as cheap as registers. */
4846 bool nolimm
= false; /* Can we do without long immediate? */
4847 bool fast
= false; /* Is the result available immediately? */
4848 bool condexec
= false; /* Does this allow conditiobnal execution? */
4849 bool compact
= false; /* Is a 16 bit opcode available? */
4850 /* CONDEXEC also implies that we can have an unconditional
4851 3-address operation. */
4853 nolimm
= compact
= condexec
= false;
4854 if (UNSIGNED_INT6 (INTVAL (x
)))
4855 nolimm
= condexec
= compact
= true;
4858 if (SMALL_INT (INTVAL (x
)))
4859 nolimm
= fast
= true;
4862 case AND
: /* bclr, bmsk, ext[bw] */
4863 if (satisfies_constraint_Ccp (x
) /* bclr */
4864 || satisfies_constraint_C1p (x
) /* bmsk */)
4865 nolimm
= fast
= condexec
= compact
= true;
4867 case IOR
: /* bset */
4868 if (satisfies_constraint_C0p (x
)) /* bset */
4869 nolimm
= fast
= condexec
= compact
= true;
4872 if (satisfies_constraint_C0p (x
)) /* bxor */
4873 nolimm
= fast
= condexec
= true;
4876 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
4882 /* FIXME: Add target options to attach a small cost if
4883 condexec / compact is not true. */
4892 /* 4 byte values can be fetched as immediate constants -
4893 let's give that the cost of an extra insn. */
4897 *total
= COSTS_N_INSNS (1);
4906 *total
= COSTS_N_INSNS (1);
4909 split_double (x
, &first
, &second
);
4910 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
4911 + !SMALL_INT (INTVAL (second
)));
4915 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4916 If we need more than 12 insns to do a multiply, then go out-of-line,
4917 since the call overhead will be < 10% of the cost of the multiply. */
4921 if (TARGET_BARREL_SHIFTER
)
4923 /* If we want to shift a constant, we need a LIMM. */
4924 /* ??? when the optimizers want to know if a constant should be
4925 hoisted, they ask for the cost of the constant. OUTER_CODE is
4926 insufficient context for shifts since we don't know which operand
4927 we are looking at. */
4928 if (CONSTANT_P (XEXP (x
, 0)))
4930 *total
+= (COSTS_N_INSNS (2)
4931 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
4935 *total
= COSTS_N_INSNS (1);
4937 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
4938 *total
= COSTS_N_INSNS (16);
4941 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
4942 /* ??? want_to_gcse_p can throw negative shift counts at us,
4943 and then panics when it gets a negative cost as result.
4944 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4953 *total
= COSTS_N_INSNS(30);
4955 *total
= COSTS_N_INSNS(1);
4959 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
4960 *total
= COSTS_N_INSNS (1);
4962 *total
= arc_multcost
;
4963 /* We do not want synth_mult sequences when optimizing
4965 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
4966 *total
= COSTS_N_INSNS (1);
4968 *total
= COSTS_N_INSNS (2);
4971 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
4972 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
4973 || (GET_CODE (XEXP (x
, 0)) == MULT
4974 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
4976 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
4977 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
4982 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
4983 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
4984 || (GET_CODE (XEXP (x
, 1)) == MULT
4985 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
4987 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
4988 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
4994 rtx op0
= XEXP (x
, 0);
4995 rtx op1
= XEXP (x
, 1);
4997 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
4998 && XEXP (op0
, 1) == const1_rtx
)
5000 /* btst / bbit0 / bbit1:
5001 Small integers and registers are free; everything else can
5002 be put in a register. */
5003 mode
= GET_MODE (XEXP (op0
, 0));
5004 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5005 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5008 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5009 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5012 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5016 if (GET_CODE (op1
) == NEG
)
5018 /* op0 might be constant, the inside of op1 is rather
5019 unlikely to be so. So swapping the operands might lower
5021 mode
= GET_MODE (op0
);
5022 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5023 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5028 if (outer_code
== IF_THEN_ELSE
5029 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5030 && XEXP (x
, 1) == const0_rtx
5031 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5033 /* btst / bbit0 / bbit1:
5034 Small integers and registers are free; everything else can
5035 be put in a register. */
5036 rtx op0
= XEXP (x
, 0);
5038 mode
= GET_MODE (XEXP (op0
, 0));
5039 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5040 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5044 /* scc_insn expands into two insns. */
5045 case GTU
: case GEU
: case LEU
:
5047 *total
+= COSTS_N_INSNS (1);
5049 case LTU
: /* might use adc. */
5051 *total
+= COSTS_N_INSNS (1) - 1;
5058 /* Helper used by arc_legitimate_pc_offset_p. */
5061 arc_needs_pcl_p (rtx x
)
5063 register const char *fmt
;
5066 if ((GET_CODE (x
) == UNSPEC
)
5067 && (XVECLEN (x
, 0) == 1)
5068 && (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
))
5069 switch (XINT (x
, 1))
5071 case ARC_UNSPEC_GOT
:
5072 case ARC_UNSPEC_GOTOFFPC
:
5080 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
5081 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
5085 if (arc_needs_pcl_p (XEXP (x
, i
)))
5088 else if (fmt
[i
] == 'E')
5089 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
5090 if (arc_needs_pcl_p (XVECEXP (x
, i
, j
)))
5097 /* Return true if ADDR is an address that needs to be expressed as an
5098 explicit sum of pcl + offset. */
5101 arc_legitimate_pc_offset_p (rtx addr
)
5103 if (GET_CODE (addr
) != CONST
)
5106 return arc_needs_pcl_p (addr
);
5109 /* Return true if ADDR is a valid pic address.
5110 A valid pic address on arc should look like
5111 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5114 arc_legitimate_pic_addr_p (rtx addr
)
5116 if (GET_CODE (addr
) == LABEL_REF
)
5118 if (GET_CODE (addr
) != CONST
)
5121 addr
= XEXP (addr
, 0);
5124 if (GET_CODE (addr
) == PLUS
)
5126 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5128 addr
= XEXP (addr
, 0);
5131 if (GET_CODE (addr
) != UNSPEC
5132 || XVECLEN (addr
, 0) != 1)
5135 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5136 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5137 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5138 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5139 && XINT (addr
, 1) != UNSPEC_TLS_GD
5140 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5143 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5144 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5152 /* Return true if OP contains a symbol reference. */
5155 symbolic_reference_mentioned_p (rtx op
)
5157 register const char *fmt
;
5160 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5163 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5164 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5170 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5171 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5175 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5182 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5183 If SKIP_LOCAL is true, skip symbols that bind locally.
5184 This is used further down in this file, and, without SKIP_LOCAL,
5185 in the addsi3 / subsi3 expanders when generating PIC code. */
5188 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5190 register const char *fmt
;
5193 if (GET_CODE(op
) == UNSPEC
)
5196 if (GET_CODE (op
) == SYMBOL_REF
)
5198 if (SYMBOL_REF_TLS_MODEL (op
))
5202 tree decl
= SYMBOL_REF_DECL (op
);
5203 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5206 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5207 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5213 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5214 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5219 else if (fmt
[i
] == 'e'
5220 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5228 /* Get the thread pointer. */
5233 /* If arc_tp_regno has been set, we can use that hard register
5234 directly as a base register. */
5235 if (arc_tp_regno
!= -1)
5236 return gen_rtx_REG (Pmode
, arc_tp_regno
);
5238 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5239 conflicts with function arguments / results. */
5240 rtx reg
= gen_reg_rtx (Pmode
);
5241 emit_insn (gen_tls_load_tp_soft ());
5242 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
5246 /* Helper to be used by TLS Global dynamic model. */
5249 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
5251 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
5252 rtx call_fusage
= NULL_RTX
;
5256 rtx x
= arc_unspec_offset (sym
, reloc
);
5257 emit_move_insn (r0
, x
);
5258 use_reg (&call_fusage
, r0
);
5260 gcc_assert (reloc
== UNSPEC_TLS_GD
);
5261 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
5262 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5263 way that the application should care. */
5264 RTL_PURE_CALL_P (call_insn
) = 1;
5265 add_function_usage_to (call_insn
, call_fusage
);
5267 rtx_insn
*insns
= get_insns ();
5270 rtx dest
= gen_reg_rtx (Pmode
);
5271 emit_libcall_block (insns
, dest
, r0
, eqv
);
5275 #define DTPOFF_ZERO_SYM ".tdata"
5277 /* Return a legitimized address for ADDR,
5278 which is a SYMBOL_REF with tls_model MODEL. */
5281 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5283 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
5284 model
= TLS_MODEL_LOCAL_EXEC
;
5288 case TLS_MODEL_LOCAL_DYNAMIC
:
5291 const char *base_name
;
5294 decl
= SYMBOL_REF_DECL (addr
);
5295 base_name
= DTPOFF_ZERO_SYM
;
5296 if (decl
&& bss_initializer_p (decl
))
5297 base_name
= ".tbss";
5299 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
5300 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
5304 v
= gen_rtvec (1, addr
);
5307 v
= gen_rtvec (2, addr
, base
);
5308 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
5309 addr
= gen_rtx_CONST (Pmode
, addr
);
5310 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
5311 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
5313 case TLS_MODEL_GLOBAL_DYNAMIC
:
5314 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
5316 case TLS_MODEL_INITIAL_EXEC
:
5317 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5318 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5319 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5321 case TLS_MODEL_LOCAL_EXEC
:
5323 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5324 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
5330 /* Legitimize a pic address reference in ORIG.
5331 The return value is the legitimated address.
5332 If OLDX is non-zero, it is the target to assign the address to first. */
5335 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
5344 if (GET_CODE (addr
) == LABEL_REF
)
5346 else if (GET_CODE (addr
) == SYMBOL_REF
)
5348 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
5350 return arc_legitimize_tls_address (addr
, model
);
5353 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
5354 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5356 /* This symbol must be referenced via a load from the Global
5357 Offset Table (@GOTPC). */
5358 pat
= arc_unspec_offset (addr
, ARC_UNSPEC_GOT
);
5359 pat
= gen_const_mem (Pmode
, pat
);
5362 oldx
= gen_reg_rtx (Pmode
);
5364 emit_move_insn (oldx
, pat
);
5369 if (GET_CODE (addr
) == CONST
)
5371 addr
= XEXP (addr
, 0);
5372 if (GET_CODE (addr
) == UNSPEC
)
5374 /* Check that the unspec is one of the ones we generate? */
5377 /* fwprop is placing in the REG_EQUIV notes constant pic
5378 unspecs expressions. Then, loop may use these notes for
5379 optimizations resulting in complex patterns that are not
5380 supported by the current implementation. The following
5381 two if-cases are simplifying the complex patters to
5383 else if (GET_CODE (addr
) == MINUS
)
5385 rtx op0
= XEXP (addr
, 0);
5386 rtx op1
= XEXP (addr
, 1);
5388 gcc_assert (GET_CODE (op1
) == UNSPEC
);
5390 emit_move_insn (oldx
,
5391 gen_rtx_CONST (SImode
,
5392 arc_legitimize_pic_address (op1
,
5394 emit_insn (gen_rtx_SET (oldx
, gen_rtx_MINUS (SImode
, op0
, oldx
)));
5398 else if (GET_CODE (addr
) != PLUS
)
5400 rtx tmp
= XEXP (addr
, 0);
5401 enum rtx_code code
= GET_CODE (addr
);
5403 /* It only works for UNARY operations. */
5404 gcc_assert (UNARY_P (addr
));
5405 gcc_assert (GET_CODE (tmp
) == UNSPEC
);
5410 gen_rtx_CONST (SImode
,
5411 arc_legitimize_pic_address (tmp
,
5414 emit_insn (gen_rtx_SET (oldx
,
5415 gen_rtx_fmt_ee (code
, SImode
,
5416 oldx
, const0_rtx
)));
5422 gcc_assert (GET_CODE (addr
) == PLUS
);
5423 if (GET_CODE (XEXP (addr
, 0)) == UNSPEC
)
5428 if (GET_CODE (addr
) == PLUS
)
5430 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
5432 base
= arc_legitimize_pic_address (op0
, oldx
);
5433 pat
= arc_legitimize_pic_address (op1
,
5434 base
== oldx
? NULL_RTX
: oldx
);
5436 if (base
== op0
&& pat
== op1
)
5439 if (GET_CODE (pat
) == CONST_INT
)
5440 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
5443 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
5445 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
5446 pat
= XEXP (pat
, 1);
5448 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
5456 /* Output address constant X to FILE, taking PIC into account. */
5459 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5464 switch (GET_CODE (x
))
5474 output_addr_const (file
, x
);
5476 /* Local functions do not get references through the PLT. */
5477 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5478 fputs ("@plt", file
);
5482 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5483 assemble_name (file
, buf
);
5487 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5488 assemble_name (file
, buf
);
5492 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5496 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5500 if (GET_MODE (x
) == VOIDmode
)
5502 /* We can use %d if the number is one word and positive. */
5503 if (CONST_DOUBLE_HIGH (x
))
5504 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5505 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5506 else if (CONST_DOUBLE_LOW (x
) < 0)
5507 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5509 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5512 /* We can't handle floating point constants;
5513 PRINT_OPERAND must handle them. */
5514 output_operand_lossage ("floating constant misused");
5518 /* FIXME: Not needed here. */
5519 /* Some assemblers need integer constants to appear last (eg masm). */
5520 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5522 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5523 fprintf (file
, "+");
5524 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5526 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5528 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5529 if (INTVAL (XEXP (x
, 1)) >= 0)
5530 fprintf (file
, "+");
5531 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5538 /* Avoid outputting things like x-x or x+5-x,
5539 since some assemblers can't handle that. */
5540 x
= simplify_subtraction (x
);
5541 if (GET_CODE (x
) != MINUS
)
5544 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5545 fprintf (file
, "-");
5546 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5547 && INTVAL (XEXP (x
, 1)) < 0)
5549 fprintf (file
, "(");
5550 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5551 fprintf (file
, ")");
5554 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5559 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5565 bool pcrel
; pcrel
= false;
5566 rtx base
; base
= NULL
;
5567 gcc_assert (XVECLEN (x
, 0) >= 1);
5568 switch (XINT (x
, 1))
5570 case ARC_UNSPEC_GOT
:
5571 suffix
= "@gotpc", pcrel
= true;
5573 case ARC_UNSPEC_GOTOFF
:
5576 case ARC_UNSPEC_GOTOFFPC
:
5577 suffix
= "@pcl", pcrel
= true;
5579 case ARC_UNSPEC_PLT
:
5583 suffix
= "@tlsgd", pcrel
= true;
5586 suffix
= "@tlsie", pcrel
= true;
5588 case UNSPEC_TLS_OFF
:
5589 if (XVECLEN (x
, 0) == 2)
5590 base
= XVECEXP (x
, 0, 1);
5591 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5592 || (!flag_pic
&& !base
))
5598 suffix
= "@invalid";
5599 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5603 fputs ("pcl,", file
);
5604 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5605 fputs (suffix
, file
);
5607 arc_output_pic_addr_const (file
, base
, code
);
5611 output_operand_lossage ("invalid expression as operand");
5615 #define SYMBOLIC_CONST(X) \
5616 (GET_CODE (X) == SYMBOL_REF \
5617 || GET_CODE (X) == LABEL_REF \
5618 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5620 /* Emit insns to move operands[1] into operands[0]. */
5623 prepare_pic_move (rtx
*operands
, machine_mode
)
5625 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5627 operands
[1] = force_reg (Pmode
, operands
[1]);
5630 rtx temp
= (reload_in_progress
? operands
[0]
5631 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5632 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5637 /* The function returning the number of words, at the beginning of an
5638 argument, must be put in registers. The returned value must be
5639 zero for arguments that are passed entirely in registers or that
5640 are entirely pushed on the stack.
5642 On some machines, certain arguments must be passed partially in
5643 registers and partially in memory. On these machines, typically
5644 the first N words of arguments are passed in registers, and the
5645 rest on the stack. If a multi-word argument (a `double' or a
5646 structure) crosses that boundary, its first few words must be
5647 passed in registers and the rest must be pushed. This function
5648 tells the compiler when this occurs, and how many of the words
5649 should go in registers.
5651 `FUNCTION_ARG' for these arguments should return the first register
5652 to be used by the caller for this argument; likewise
5653 `FUNCTION_INCOMING_ARG', for the called function.
5655 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5657 /* If REGNO is the least arg reg available then what is the total number of arg
5659 #define GPR_REST_ARG_REGS(REGNO) \
5660 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5662 /* Since arc parm regs are contiguous. */
5663 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5665 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5668 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
5669 tree type
, bool named ATTRIBUTE_UNUSED
)
5671 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5672 int bytes
= (mode
== BLKmode
5673 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5674 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5678 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5679 ret
= GPR_REST_ARG_REGS (arg_num
);
5681 /* ICEd at function.c:2361, and ret is copied to data->partial */
5682 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
5687 /* This function is used to control a function argument is passed in a
5688 register, and which register.
5690 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5691 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5692 all of the previous arguments so far passed in registers; MODE, the
5693 machine mode of the argument; TYPE, the data type of the argument
5694 as a tree node or 0 if that is not known (which happens for C
5695 support library functions); and NAMED, which is 1 for an ordinary
5696 argument and 0 for nameless arguments that correspond to `...' in
5697 the called function's prototype.
5699 The returned value should either be a `reg' RTX for the hard
5700 register in which to pass the argument, or zero to pass the
5701 argument on the stack.
5703 For machines like the Vax and 68000, where normally all arguments
5704 are pushed, zero suffices as a definition.
5706 The usual way to make the ANSI library `stdarg.h' work on a machine
5707 where some arguments are usually passed in registers, is to cause
5708 nameless arguments to be passed on the stack instead. This is done
5709 by making the function return 0 whenever NAMED is 0.
5711 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5712 definition of this function to determine if this argument is of a
5713 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5714 is not defined and the function returns non-zero for such an
5715 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5716 defined, the argument will be computed in the stack and then loaded
5719 The function is used to implement macro FUNCTION_ARG. */
5720 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5721 and the rest are pushed. */
5724 arc_function_arg (cumulative_args_t cum_v
,
5726 const_tree type ATTRIBUTE_UNUSED
,
5727 bool named ATTRIBUTE_UNUSED
)
5729 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5732 const char *debstr ATTRIBUTE_UNUSED
;
5734 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5735 /* Return a marker for use in the call instruction. */
5736 if (mode
== VOIDmode
)
5741 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
5743 ret
= gen_rtx_REG (mode
, arg_num
);
5744 debstr
= reg_names
[arg_num
];
5754 /* The function to update the summarizer variable *CUM to advance past
5755 an argument in the argument list. The values MODE, TYPE and NAMED
5756 describe that argument. Once this is done, the variable *CUM is
5757 suitable for analyzing the *following* argument with
5758 `FUNCTION_ARG', etc.
5760 This function need not do anything if the argument in question was
5761 passed on the stack. The compiler knows how to track the amount of
5762 stack space used for arguments without any special help.
5764 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5765 /* For the ARC: the cum set here is passed on to function_arg where we
5766 look at its value and say which reg to use. Strategy: advance the
5767 regnumber here till we run out of arg regs, then set *cum to last
5768 reg. In function_arg, since *cum > last arg reg we would return 0
5769 and thus the arg will end up on the stack. For straddling args of
5770 course function_arg_partial_nregs will come into play. */
5773 arc_function_arg_advance (cumulative_args_t cum_v
,
5776 bool named ATTRIBUTE_UNUSED
)
5778 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5779 int bytes
= (mode
== BLKmode
5780 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5781 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5785 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
5786 for (i
= 0; i
< words
; i
++)
5787 *cum
= ARC_NEXT_ARG_REG (*cum
);
5791 /* Define how to find the value returned by a function.
5792 VALTYPE is the data type of the value (as a tree).
5793 If the precise function being called is known, FN_DECL_OR_TYPE is its
5794 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5797 arc_function_value (const_tree valtype
,
5798 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
5799 bool outgoing ATTRIBUTE_UNUSED
)
5801 machine_mode mode
= TYPE_MODE (valtype
);
5802 int unsignedp ATTRIBUTE_UNUSED
;
5804 unsignedp
= TYPE_UNSIGNED (valtype
);
5805 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
5806 PROMOTE_MODE (mode
, unsignedp
, valtype
);
5807 return gen_rtx_REG (mode
, 0);
5810 /* Returns the return address that is used by builtin_return_address. */
5813 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
5818 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
5821 /* Nonzero if the constant value X is a legitimate general operand
5822 when generating PIC code. It is given that flag_pic is on and
5823 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
5826 arc_legitimate_pic_operand_p (rtx x
)
5828 return !arc_raw_symbolic_reference_mentioned_p (x
, true);
5831 /* Determine if a given RTX is a valid constant. We already know this
5832 satisfies CONSTANT_P. */
5835 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
5837 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
))
5840 if (!flag_pic
&& mode
!= Pmode
)
5843 switch (GET_CODE (x
))
5848 if (GET_CODE (x
) == PLUS
)
5851 ? GET_CODE (XEXP (x
, 1)) != CONST_INT
5852 : !arc_legitimate_constant_p (mode
, XEXP (x
, 1)))
5857 /* Only some unspecs are valid as "constants". */
5858 if (GET_CODE (x
) == UNSPEC
)
5859 switch (XINT (x
, 1))
5861 case ARC_UNSPEC_PLT
:
5862 case ARC_UNSPEC_GOTOFF
:
5863 case ARC_UNSPEC_GOTOFFPC
:
5864 case ARC_UNSPEC_GOT
:
5867 case UNSPEC_TLS_OFF
:
5874 /* We must have drilled down to a symbol. */
5875 if (arc_raw_symbolic_reference_mentioned_p (x
, false))
5882 if (SYMBOL_REF_TLS_MODEL (x
))
5894 /* Otherwise we handle everything else in the move patterns. */
5899 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
5901 if (RTX_OK_FOR_BASE_P (x
, strict
))
5903 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
5905 if (LEGITIMATE_SCALED_ADDRESS_P (mode
, x
, strict
))
5907 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x
))
5909 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
5912 /* When we compile for size avoid const (@sym + offset)
5914 if (!flag_pic
&& optimize_size
&& !reload_completed
5915 && (GET_CODE (x
) == CONST
)
5916 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
5917 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
5918 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
5919 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
5921 rtx addend
= XEXP (XEXP (x
, 0), 1);
5922 gcc_assert (CONST_INT_P (addend
));
5923 HOST_WIDE_INT offset
= INTVAL (addend
);
5925 /* Allow addresses having a large offset to pass. Anyhow they
5926 will end in a limm. */
5927 return !(offset
> -1024 && offset
< 1020);
5930 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
5932 if (flag_pic
? arc_legitimate_pic_addr_p (x
)
5933 : arc_legitimate_constant_p (Pmode
, x
))
5936 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
5937 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
5938 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5940 /* We're restricted here by the `st' insn. */
5941 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
5942 && GET_CODE (XEXP ((x
), 1)) == PLUS
5943 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
5944 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
5945 TARGET_AUTO_MODIFY_REG
, strict
))
5950 /* Return true iff ADDR (a legitimate address expression)
5951 has an effect that depends on the machine mode it is used for. */
5954 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
5956 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5957 which is valid for loads and stores, or a limm offset, which is valid for
5958 loads. Scaled indices are scaled by the access mode. */
5959 if (GET_CODE (addr
) == PLUS
5960 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
5965 /* Determine if it's legal to put X into the constant pool. */
5968 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
5970 return !arc_legitimate_constant_p (mode
, x
);
5973 /* IDs for all the ARC builtins. */
5977 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5978 ARC_BUILTIN_ ## NAME,
5979 #include "builtins.def"
5985 struct GTY(()) arc_builtin_description
5987 enum insn_code icode
;
5992 static GTY(()) struct arc_builtin_description
5993 arc_bdesc
[ARC_BUILTIN_COUNT
] =
5995 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5996 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
5997 #include "builtins.def"
6001 /* Transform UP into lowercase and write the result to LO.
6002 You must provide enough space for LO. Return LO. */
6005 arc_tolower (char *lo
, const char *up
)
6009 for (; *up
; up
++, lo
++)
6010 *lo
= TOLOWER (*up
);
6017 /* Implement `TARGET_BUILTIN_DECL'. */
6020 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6022 if (id
< ARC_BUILTIN_COUNT
)
6023 return arc_bdesc
[id
].fndecl
;
6025 return error_mark_node
;
6029 arc_init_builtins (void)
6031 tree V4HI_type_node
;
6032 tree V2SI_type_node
;
6033 tree V2HI_type_node
;
6035 /* Vector types based on HS SIMD elements. */
6036 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6037 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6038 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6040 tree pcvoid_type_node
6041 = build_pointer_type (build_qualified_type (void_type_node
,
6043 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6046 tree void_ftype_void
6047 = build_function_type_list (void_type_node
, NULL_TREE
);
6049 = build_function_type_list (integer_type_node
, integer_type_node
,
6051 tree int_ftype_pcvoid_int
6052 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6053 integer_type_node
, NULL_TREE
);
6054 tree void_ftype_usint_usint
6055 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6056 long_unsigned_type_node
, NULL_TREE
);
6057 tree int_ftype_int_int
6058 = build_function_type_list (integer_type_node
, integer_type_node
,
6059 integer_type_node
, NULL_TREE
);
6060 tree usint_ftype_usint
6061 = build_function_type_list (long_unsigned_type_node
,
6062 long_unsigned_type_node
, NULL_TREE
);
6063 tree void_ftype_usint
6064 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6067 = build_function_type_list (integer_type_node
, void_type_node
,
6070 = build_function_type_list (void_type_node
, integer_type_node
,
6072 tree int_ftype_short
6073 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6076 /* Old ARC SIMD types. */
6077 tree v8hi_ftype_v8hi_v8hi
6078 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6079 V8HI_type_node
, NULL_TREE
);
6080 tree v8hi_ftype_v8hi_int
6081 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6082 integer_type_node
, NULL_TREE
);
6083 tree v8hi_ftype_v8hi_int_int
6084 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6085 integer_type_node
, integer_type_node
,
6087 tree void_ftype_v8hi_int_int
6088 = build_function_type_list (void_type_node
, V8HI_type_node
,
6089 integer_type_node
, integer_type_node
,
6091 tree void_ftype_v8hi_int_int_int
6092 = build_function_type_list (void_type_node
, V8HI_type_node
,
6093 integer_type_node
, integer_type_node
,
6094 integer_type_node
, NULL_TREE
);
6095 tree v8hi_ftype_int_int
6096 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6097 integer_type_node
, NULL_TREE
);
6098 tree void_ftype_int_int
6099 = build_function_type_list (void_type_node
, integer_type_node
,
6100 integer_type_node
, NULL_TREE
);
6101 tree v8hi_ftype_v8hi
6102 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6104 /* ARCv2 SIMD types. */
6105 tree long_ftype_v4hi_v4hi
6106 = build_function_type_list (long_long_integer_type_node
,
6107 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6108 tree int_ftype_v2hi_v2hi
6109 = build_function_type_list (integer_type_node
,
6110 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6111 tree v2si_ftype_v2hi_v2hi
6112 = build_function_type_list (V2SI_type_node
,
6113 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6114 tree v2hi_ftype_v2hi_v2hi
6115 = build_function_type_list (V2HI_type_node
,
6116 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6117 tree v2si_ftype_v2si_v2si
6118 = build_function_type_list (V2SI_type_node
,
6119 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6120 tree v4hi_ftype_v4hi_v4hi
6121 = build_function_type_list (V4HI_type_node
,
6122 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6123 tree long_ftype_v2si_v2hi
6124 = build_function_type_list (long_long_integer_type_node
,
6125 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6127 /* Add the builtins. */
6128 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6130 int id = ARC_BUILTIN_ ## NAME; \
6131 const char *Name = "__builtin_arc_" #NAME; \
6132 char *name = (char*) alloca (1 + strlen (Name)); \
6134 gcc_assert (id < ARC_BUILTIN_COUNT); \
6136 arc_bdesc[id].fndecl \
6137 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6138 BUILT_IN_MD, NULL, NULL_TREE); \
6140 #include "builtins.def"
6144 /* Helper to expand __builtin_arc_aligned (void* val, int
6148 arc_expand_builtin_aligned (tree exp
)
6150 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6151 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6153 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6154 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6156 if (!CONST_INT_P (op1
))
6158 /* If we can't fold the alignment to a constant integer
6159 whilst optimizing, this is probably a user error. */
6161 warning (0, "__builtin_arc_aligned with non-constant alignment");
6165 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6166 /* Check alignTest is positive, and a power of two. */
6167 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6169 error ("invalid alignment value for __builtin_arc_aligned");
6173 if (CONST_INT_P (op0
))
6175 HOST_WIDE_INT pnt
= INTVAL (op0
);
6177 if ((pnt
& (alignTest
- 1)) == 0)
6182 unsigned align
= get_pointer_alignment (arg0
);
6183 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6185 if (align
&& align
>= numBits
)
6187 /* Another attempt to ascertain alignment. Check the type
6188 we are pointing to. */
6189 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6190 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6195 /* Default to false. */
6199 /* Helper arc_expand_builtin, generates a pattern for the given icode
6203 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6205 switch (insn_data
[icode
].n_generator_args
)
6208 return GEN_FCN (icode
) ();
6210 return GEN_FCN (icode
) (arg
[0]);
6212 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6214 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6216 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6218 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6224 /* Expand an expression EXP that calls a built-in function,
6225 with result going to TARGET if that's convenient
6226 (and in mode MODE if that's convenient).
6227 SUBTARGET may be used as the target for computing one of EXP's operands.
6228 IGNORE is nonzero if the value is to be ignored. */
6231 arc_expand_builtin (tree exp
,
6233 rtx subtarget ATTRIBUTE_UNUSED
,
6234 machine_mode mode ATTRIBUTE_UNUSED
,
6235 int ignore ATTRIBUTE_UNUSED
)
6237 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6238 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
6239 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6240 int i
, j
, n_args
= call_expr_nargs (exp
);
6243 enum insn_code icode
= d
->icode
;
6244 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6261 if (id
>= ARC_BUILTIN_COUNT
)
6262 internal_error ("bad builtin fcode");
6264 /* 1st part: Expand special builtins. */
6267 case ARC_BUILTIN_NOP
:
6268 emit_insn (gen_nopv ());
6271 case ARC_BUILTIN_RTIE
:
6272 case ARC_BUILTIN_SYNC
:
6273 case ARC_BUILTIN_BRK
:
6274 case ARC_BUILTIN_SWI
:
6275 case ARC_BUILTIN_UNIMP_S
:
6276 gcc_assert (icode
!= 0);
6277 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6280 case ARC_BUILTIN_ALIGNED
:
6281 return arc_expand_builtin_aligned (exp
);
6283 case ARC_BUILTIN_CLRI
:
6284 target
= gen_reg_rtx (SImode
);
6285 emit_insn (gen_clri (target
, const1_rtx
));
6288 case ARC_BUILTIN_TRAP_S
:
6289 case ARC_BUILTIN_SLEEP
:
6290 arg0
= CALL_EXPR_ARG (exp
, 0);
6292 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6294 if (!CONST_INT_P (op0
) || !satisfies_constraint_L (op0
))
6296 error ("builtin operand should be an unsigned 6-bit value");
6299 gcc_assert (icode
!= 0);
6300 emit_insn (GEN_FCN (icode
) (op0
));
6303 case ARC_BUILTIN_VDORUN
:
6304 case ARC_BUILTIN_VDIRUN
:
6305 arg0
= CALL_EXPR_ARG (exp
, 0);
6306 arg1
= CALL_EXPR_ARG (exp
, 1);
6307 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6308 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6310 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6312 mode0
= insn_data
[icode
].operand
[1].mode
;
6313 mode1
= insn_data
[icode
].operand
[2].mode
;
6315 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6316 op0
= copy_to_mode_reg (mode0
, op0
);
6318 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6319 op1
= copy_to_mode_reg (mode1
, op1
);
6321 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6328 case ARC_BUILTIN_VDIWR
:
6329 case ARC_BUILTIN_VDOWR
:
6330 arg0
= CALL_EXPR_ARG (exp
, 0);
6331 arg1
= CALL_EXPR_ARG (exp
, 1);
6332 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6333 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6335 if (!CONST_INT_P (op0
)
6336 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6337 error ("operand 1 should be an unsigned 3-bit immediate");
6339 mode1
= insn_data
[icode
].operand
[1].mode
;
6341 if (icode
== CODE_FOR_vdiwr_insn
)
6342 target
= gen_rtx_REG (SImode
,
6343 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6344 else if (icode
== CODE_FOR_vdowr_insn
)
6345 target
= gen_rtx_REG (SImode
,
6346 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6350 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6351 op1
= copy_to_mode_reg (mode1
, op1
);
6353 pat
= GEN_FCN (icode
) (target
, op1
);
6360 case ARC_BUILTIN_VASRW
:
6361 case ARC_BUILTIN_VSR8
:
6362 case ARC_BUILTIN_VSR8AW
:
6363 arg0
= CALL_EXPR_ARG (exp
, 0);
6364 arg1
= CALL_EXPR_ARG (exp
, 1);
6365 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6366 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6367 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6369 target
= gen_reg_rtx (V8HImode
);
6370 mode0
= insn_data
[icode
].operand
[1].mode
;
6371 mode1
= insn_data
[icode
].operand
[2].mode
;
6373 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6374 op0
= copy_to_mode_reg (mode0
, op0
);
6376 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6377 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6378 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6380 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6387 case ARC_BUILTIN_VLD32WH
:
6388 case ARC_BUILTIN_VLD32WL
:
6389 case ARC_BUILTIN_VLD64
:
6390 case ARC_BUILTIN_VLD32
:
6393 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6394 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6395 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6397 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6398 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6399 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6400 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6402 /* target <- src vreg. */
6403 emit_insn (gen_move_insn (target
, src_vreg
));
6405 /* target <- vec_concat: target, mem (Ib, u8). */
6406 mode0
= insn_data
[icode
].operand
[3].mode
;
6407 mode1
= insn_data
[icode
].operand
[1].mode
;
6409 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6410 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6411 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6413 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6414 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6415 error ("operand 2 should be an unsigned 8-bit value");
6417 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6424 case ARC_BUILTIN_VLD64W
:
6425 case ARC_BUILTIN_VLD128
:
6426 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6427 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6429 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6430 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6431 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6433 /* target <- src vreg. */
6434 target
= gen_reg_rtx (V8HImode
);
6436 /* target <- vec_concat: target, mem (Ib, u8). */
6437 mode0
= insn_data
[icode
].operand
[1].mode
;
6438 mode1
= insn_data
[icode
].operand
[2].mode
;
6439 mode2
= insn_data
[icode
].operand
[3].mode
;
6441 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6442 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6443 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6445 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6446 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6447 error ("operand 2 should be an unsigned 8-bit value");
6449 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6457 case ARC_BUILTIN_VST128
:
6458 case ARC_BUILTIN_VST64
:
6459 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6460 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6461 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6463 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6464 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6465 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6466 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6468 mode0
= insn_data
[icode
].operand
[0].mode
;
6469 mode1
= insn_data
[icode
].operand
[1].mode
;
6470 mode2
= insn_data
[icode
].operand
[2].mode
;
6471 mode3
= insn_data
[icode
].operand
[3].mode
;
6473 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6474 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6475 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6477 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6478 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6479 error ("operand 3 should be an unsigned 8-bit value");
6481 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6482 op3
= copy_to_mode_reg (mode3
, op3
);
6484 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6491 case ARC_BUILTIN_VST16_N
:
6492 case ARC_BUILTIN_VST32_N
:
6493 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6494 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6495 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6496 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6498 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6499 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6500 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6501 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6502 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6504 mode0
= insn_data
[icode
].operand
[0].mode
;
6505 mode2
= insn_data
[icode
].operand
[2].mode
;
6506 mode3
= insn_data
[icode
].operand
[3].mode
;
6507 mode4
= insn_data
[icode
].operand
[4].mode
;
6509 /* Do some correctness checks for the operands. */
6510 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6511 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6512 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6514 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6515 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6516 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6518 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6519 op3
= copy_to_mode_reg (mode3
, op3
);
6521 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6522 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6523 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6524 else if (icode
== CODE_FOR_vst32_n_insn
6525 && ((INTVAL (op4
) % 2) != 0))
6526 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6528 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6539 /* 2nd part: Expand regular builtins. */
6541 internal_error ("bad builtin fcode");
6543 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6548 if (target
== NULL_RTX
6549 || GET_MODE (target
) != tmode
6550 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6552 target
= gen_reg_rtx (tmode
);
6557 gcc_assert (n_args
<= 4);
6558 for (i
= 0; i
< n_args
; i
++, j
++)
6560 tree arg
= CALL_EXPR_ARG (exp
, i
);
6561 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6562 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6563 machine_mode opmode
= GET_MODE (op
);
6564 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6566 /* SIMD extension requires exact immediate operand match. */
6567 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6568 && (id
< ARC_BUILTIN_SIMD_END
)
6572 if (!CONST_INT_P (op
))
6573 error ("builtin requires an immediate for operand %d", j
);
6577 if (!satisfies_constraint_L (op
))
6578 error ("operand %d should be a 6 bit unsigned immediate", j
);
6581 if (!satisfies_constraint_P (op
))
6582 error ("operand %d should be a 8 bit unsigned immediate", j
);
6585 if (!satisfies_constraint_K (op
))
6586 error ("operand %d should be a 3 bit unsigned immediate", j
);
6589 error ("unknown builtin immediate operand type for operand %d",
6594 if (CONST_INT_P (op
))
6597 if ((opmode
== SImode
) && (mode
== HImode
))
6600 op
= gen_lowpart (HImode
, op
);
6603 /* In case the insn wants input operands in modes different from
6604 the result, abort. */
6605 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6607 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6608 op
= copy_to_mode_reg (mode
, op
);
6613 pat
= apply_GEN_FCN (icode
, xop
);
6614 if (pat
== NULL_RTX
)
6625 /* Returns true if the operands[opno] is a valid compile-time constant to be
6626 used as register number in the code for builtins. Else it flags an error
6627 and returns false. */
6630 check_if_valid_regno_const (rtx
*operands
, int opno
)
6633 switch (GET_CODE (operands
[opno
]))
6640 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6646 /* Check that after all the constant folding, whether the operand to
6647 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6650 check_if_valid_sleep_operand (rtx
*operands
, int opno
)
6652 switch (GET_CODE (operands
[opno
]))
6656 if( UNSIGNED_INT6 (INTVAL (operands
[opno
])))
6660 fatal_error (input_location
,
6661 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6667 /* Return true if it is ok to make a tail-call to DECL. */
6670 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
6671 tree exp ATTRIBUTE_UNUSED
)
6673 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6674 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6677 /* Everything else is ok. */
6681 /* Output code to add DELTA to the first argument, and then jump
6682 to FUNCTION. Used for C++ multiple inheritance. */
6685 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
6686 HOST_WIDE_INT delta
,
6687 HOST_WIDE_INT vcall_offset
,
6690 int mi_delta
= delta
;
6691 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
6694 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
6698 mi_delta
= - mi_delta
;
6700 /* Add DELTA. When possible use a plain add, otherwise load it into
6701 a register first. */
6703 while (mi_delta
!= 0)
6705 if ((mi_delta
& (3 << shift
)) == 0)
6709 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
6710 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
6711 mi_delta
& (0xff << shift
));
6712 mi_delta
&= ~(0xff << shift
);
6717 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6718 if (vcall_offset
!= 0)
6720 /* ld r12,[this] --> temp = *this
6721 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6723 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6724 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6725 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
6726 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
6727 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
6728 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6729 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
6730 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
6731 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
6734 fnaddr
= XEXP (DECL_RTL (function
), 0);
6736 if (arc_is_longcall_p (fnaddr
))
6740 asm_fprintf (file
, "\tld\t%s, [pcl, @",
6741 ARC_TEMP_SCRATCH_REG
);
6742 assemble_name (file
, XSTR (fnaddr
, 0));
6743 fputs ("@gotpc]\n", file
);
6744 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
6748 fputs ("\tj\t@", file
);
6749 assemble_name (file
, XSTR (fnaddr
, 0));
6754 fputs ("\tb\t@", file
);
6755 assemble_name (file
, XSTR (fnaddr
, 0));
6757 fputs ("@plt\n", file
);
6762 /* Return true if a 32 bit "long_call" should be generated for
6763 this calling SYM_REF. We generate a long_call if the function:
6765 a. has an __attribute__((long call))
6766 or b. the -mlong-calls command line switch has been specified
6768 However we do not generate a long call if the function has an
6769 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6771 This function will be called by C fragments contained in the machine
6772 description file. */
6775 arc_is_longcall_p (rtx sym_ref
)
6777 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6780 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
6781 || (TARGET_LONG_CALLS_SET
6782 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6783 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6787 /* Likewise for short calls. */
6790 arc_is_shortcall_p (rtx sym_ref
)
6792 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6795 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6796 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
6797 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
6798 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6802 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6805 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
6807 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
6811 HOST_WIDE_INT size
= int_size_in_bytes (type
);
6812 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
6817 /* This was in rtlanal.c, and can go in there when we decide we want
6818 to submit the change for inclusion in the GCC tree. */
6819 /* Like note_stores, but allow the callback to have side effects on the rtl
6820 (like the note_stores of yore):
6821 Call FUN on each register or MEM that is stored into or clobbered by X.
6822 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6823 ignored by note_stores, but passed to FUN.
6824 FUN may alter parts of the RTL.
6826 FUN receives three arguments:
6827 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6828 2. the SET or CLOBBER rtx that does the store,
6829 3. the pointer DATA provided to note_stores.
6831 If the item being stored in or clobbered is a SUBREG of a hard register,
6832 the SUBREG will be passed. */
6834 /* For now. */ static
6836 walk_stores (rtx x
, void (*fun
) (rtx
, rtx
, void *), void *data
)
6840 if (GET_CODE (x
) == COND_EXEC
)
6841 x
= COND_EXEC_CODE (x
);
6843 if (GET_CODE (x
) == SET
|| GET_CODE (x
) == CLOBBER
)
6845 rtx dest
= SET_DEST (x
);
6847 while ((GET_CODE (dest
) == SUBREG
6848 && (!REG_P (SUBREG_REG (dest
))
6849 || REGNO (SUBREG_REG (dest
)) >= FIRST_PSEUDO_REGISTER
))
6850 || GET_CODE (dest
) == ZERO_EXTRACT
6851 || GET_CODE (dest
) == STRICT_LOW_PART
)
6852 dest
= XEXP (dest
, 0);
6854 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6855 each of whose first operand is a register. */
6856 if (GET_CODE (dest
) == PARALLEL
)
6858 for (i
= XVECLEN (dest
, 0) - 1; i
>= 0; i
--)
6859 if (XEXP (XVECEXP (dest
, 0, i
), 0) != 0)
6860 (*fun
) (XEXP (XVECEXP (dest
, 0, i
), 0), x
, data
);
6863 (*fun
) (dest
, x
, data
);
6866 else if (GET_CODE (x
) == PARALLEL
)
6867 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
6868 walk_stores (XVECEXP (x
, 0, i
), fun
, data
);
6872 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
6873 machine_mode mode ATTRIBUTE_UNUSED
,
6875 bool named ATTRIBUTE_UNUSED
)
6878 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
6879 || TREE_ADDRESSABLE (type
)));
6882 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6885 arc_can_use_doloop_p (const widest_int
&iterations
, const widest_int
&,
6886 unsigned int loop_depth
, bool entered_at_top
)
6890 /* Setting up the loop with two sr instructions costs 6 cycles. */
6893 && wi::gtu_p (iterations
, 0)
6894 && wi::leu_p (iterations
, flag_pic
? 6 : 3))
6899 /* NULL if INSN insn is valid within a low-overhead loop.
6900 Otherwise return why doloop cannot be applied. */
6903 arc_invalid_within_doloop (const rtx_insn
*insn
)
6906 return "Function call in the loop.";
6910 /* Return true if a load instruction (CONSUMER) uses the same address as a
6911 store instruction (PRODUCER). This function is used to avoid st/ld
6912 address hazard in ARC700 cores. */
6914 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
6916 rtx in_set
, out_set
;
6917 rtx out_addr
, in_addr
;
6925 /* Peel the producer and the consumer for the address. */
6926 out_set
= single_set (producer
);
6929 out_addr
= SET_DEST (out_set
);
6932 if (GET_CODE (out_addr
) == ZERO_EXTEND
6933 || GET_CODE (out_addr
) == SIGN_EXTEND
)
6934 out_addr
= XEXP (out_addr
, 0);
6936 if (!MEM_P (out_addr
))
6939 in_set
= single_set (consumer
);
6942 in_addr
= SET_SRC (in_set
);
6945 if (GET_CODE (in_addr
) == ZERO_EXTEND
6946 || GET_CODE (in_addr
) == SIGN_EXTEND
)
6947 in_addr
= XEXP (in_addr
, 0);
6949 if (!MEM_P (in_addr
))
6951 /* Get rid of the MEM and check if the addresses are
6953 in_addr
= XEXP (in_addr
, 0);
6954 out_addr
= XEXP (out_addr
, 0);
6956 return exp_equiv_p (in_addr
, out_addr
, 0, true);
6962 /* The same functionality as arc_hazard. It is called in machine
6963 reorg before any other optimization. Hence, the NOP size is taken
6964 into account when doing branch shortening. */
6967 workaround_arc_anomaly (void)
6969 rtx_insn
*insn
, *succ0
;
6971 /* For any architecture: call arc_hazard here. */
6972 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6974 succ0
= next_real_insn (insn
);
6975 if (arc_hazard (insn
, succ0
))
6977 emit_insn_before (gen_nopv (), succ0
);
6985 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6987 succ0
= next_real_insn (insn
);
6988 if (arc_store_addr_hazard_p (insn
, succ0
))
6990 emit_insn_after (gen_nopv (), insn
);
6991 emit_insn_after (gen_nopv (), insn
);
6995 /* Avoid adding nops if the instruction between the ST and LD is
6997 succ1
= next_real_insn (succ0
);
6998 if (succ0
&& !JUMP_P (succ0
) && !CALL_P (succ0
)
6999 && arc_store_addr_hazard_p (insn
, succ1
))
7000 emit_insn_after (gen_nopv (), insn
);
7005 static int arc_reorg_in_progress
= 0;
7007 /* ARC's machince specific reorg function. */
7018 workaround_arc_anomaly ();
7020 cfun
->machine
->arc_reorg_started
= 1;
7021 arc_reorg_in_progress
= 1;
7023 /* Link up loop ends with their loop start. */
7025 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7026 if (GET_CODE (insn
) == JUMP_INSN
7027 && recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
7030 = as_a
<rtx_insn
*> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 1), 0));
7031 rtx num
= GEN_INT (CODE_LABEL_NUMBER (top_label
));
7032 rtx_insn
*lp
, *prev
= prev_nonnote_insn (top_label
);
7033 rtx_insn
*lp_simple
= NULL
;
7034 rtx_insn
*next
= NULL
;
7035 rtx op0
= XEXP (XVECEXP (PATTERN (insn
), 0, 1), 0);
7039 (lp
&& NONJUMP_INSN_P (lp
)
7040 && recog_memoized (lp
) != CODE_FOR_doloop_begin_i
);
7041 lp
= prev_nonnote_insn (lp
))
7043 if (!lp
|| !NONJUMP_INSN_P (lp
)
7044 || dead_or_set_regno_p (lp
, LP_COUNT
))
7046 HOST_WIDE_INT loop_end_id
7047 = INTVAL (XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0));
7049 for (prev
= next
= insn
, lp
= NULL
; prev
|| next
;)
7053 if (NONJUMP_INSN_P (prev
)
7054 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
7055 && (INTVAL (XEXP (XVECEXP (PATTERN (prev
), 0, 5), 0))
7061 else if (LABEL_P (prev
))
7063 prev
= prev_nonnote_insn (prev
);
7067 if (NONJUMP_INSN_P (next
)
7068 && recog_memoized (next
) == CODE_FOR_doloop_begin_i
7069 && (INTVAL (XEXP (XVECEXP (PATTERN (next
), 0, 5), 0))
7075 next
= next_nonnote_insn (next
);
7082 if (lp
&& !dead_or_set_regno_p (lp
, LP_COUNT
))
7084 rtx begin_cnt
= XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0);
7085 if (INTVAL (XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0)))
7086 /* The loop end insn has been duplicated. That can happen
7087 when there is a conditional block at the very end of
7090 /* If Register allocation failed to allocate to the right
7091 register, There is no point into teaching reload to
7092 fix this up with reloads, as that would cost more
7093 than using an ordinary core register with the
7094 doloop_fallback pattern. */
7095 if ((true_regnum (op0
) != LP_COUNT
|| !REG_P (begin_cnt
))
7096 /* Likewise, if the loop setup is evidently inside the loop,
7098 || (!lp_simple
&& lp
!= next
&& !seen_label
))
7103 /* It is common that the optimizers copy the loop count from
7104 another register, and doloop_begin_i is stuck with the
7105 source of the move. Making doloop_begin_i only accept "l"
7106 is nonsentical, as this then makes reload evict the pseudo
7107 used for the loop end. The underlying cause is that the
7108 optimizers don't understand that the register allocation for
7109 doloop_begin_i should be treated as part of the loop.
7110 Try to work around this problem by verifying the previous
7112 if (true_regnum (begin_cnt
) != LP_COUNT
)
7117 for (mov
= prev_nonnote_insn (lp
); mov
;
7118 mov
= prev_nonnote_insn (mov
))
7120 if (!NONJUMP_INSN_P (mov
))
7122 else if ((set
= single_set (mov
))
7123 && rtx_equal_p (SET_SRC (set
), begin_cnt
)
7124 && rtx_equal_p (SET_DEST (set
), op0
))
7129 XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0) = op0
;
7130 note
= find_regno_note (lp
, REG_DEAD
, REGNO (begin_cnt
));
7132 remove_note (lp
, note
);
7140 XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0) = num
;
7141 XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0) = num
;
7143 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const2_rtx
;
7144 else if (!lp_simple
)
7145 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const1_rtx
;
7146 else if (prev
!= lp
)
7149 add_insn_after (lp
, prev
, NULL
);
7153 XEXP (XVECEXP (PATTERN (lp
), 0, 7), 0)
7154 = gen_rtx_LABEL_REF (Pmode
, top_label
);
7155 add_reg_note (lp
, REG_LABEL_OPERAND
, top_label
);
7156 LABEL_NUSES (top_label
)++;
7158 /* We can avoid tedious loop start / end setting for empty loops
7159 be merely setting the loop count to its final value. */
7160 if (next_active_insn (top_label
) == insn
)
7163 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp
), 0, 3), 0),
7166 rtx_insn
*lc_set_insn
= emit_insn_before (lc_set
, insn
);
7171 /* If the loop is non-empty with zero length, we can't make it
7172 a zero-overhead loop. That can happen for empty asms. */
7177 for (scan
= top_label
;
7178 (scan
&& scan
!= insn
7179 && (!NONJUMP_INSN_P (scan
) || !get_attr_length (scan
)));
7180 scan
= NEXT_INSN (scan
));
7190 /* Sometimes the loop optimizer makes a complete hash of the
7191 loop. If it were only that the loop is not entered at the
7192 top, we could fix this up by setting LP_START with SR .
7193 However, if we can't find the loop begin were it should be,
7194 chances are that it does not even dominate the loop, but is
7195 inside the loop instead. Using SR there would kill
7197 We use the doloop_fallback pattern here, which executes
7198 in two cycles on the ARC700 when predicted correctly. */
7202 rtx op3
= XEXP (XVECEXP (PATTERN (insn
), 0, 5), 0);
7204 emit_insn_before (gen_move_insn (op3
, op0
), insn
);
7206 = gen_doloop_fallback_m (op3
, JUMP_LABEL (insn
), op0
);
7209 XVEC (PATTERN (insn
), 0)
7210 = gen_rtvec (2, XVECEXP (PATTERN (insn
), 0, 0),
7211 XVECEXP (PATTERN (insn
), 0, 1));
7212 INSN_CODE (insn
) = -1;
7217 /* FIXME: should anticipate ccfsm action, generate special patterns for
7218 to-be-deleted branches that have no delay slot and have at least the
7219 length of the size increase forced on other insns that are conditionalized.
7220 This can also have an insn_list inside that enumerates insns which are
7221 not actually conditionalized because the destinations are dead in the
7223 Could also tag branches that we want to be unaligned if they get no delay
7224 slot, or even ones that we don't want to do delay slot sheduling for
7225 because we can unalign them.
7227 However, there are cases when conditional execution is only possible after
7228 delay slot scheduling:
7230 - If a delay slot is filled with a nocond/set insn from above, the previous
7231 basic block can become elegible for conditional execution.
7232 - If a delay slot is filled with a nocond insn from the fall-through path,
7233 the branch with that delay slot can become eligble for conditional
7234 execution (however, with the same sort of data flow analysis that dbr
7235 does, we could have figured out before that we don't need to
7236 conditionalize this insn.)
7237 - If a delay slot insn is filled with an insn from the target, the
7238 target label gets its uses decremented (even deleted if falling to zero),
7239 thus possibly creating more condexec opportunities there.
7240 Therefore, we should still be prepared to apply condexec optimization on
7241 non-prepared branches if the size increase of conditionalized insns is no
7242 more than the size saved from eliminating the branch. An invocation option
7243 could also be used to reserve a bit of extra size for condbranches so that
7244 this'll work more often (could also test in arc_reorg if the block is
7245 'close enough' to be eligible for condexec to make this likely, and
7246 estimate required size increase). */
7247 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7248 if (TARGET_NO_BRCC_SET
)
7253 init_insn_lengths();
7256 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
7259 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
7260 df_finish_pass ((flags
& TODO_df_verify
) != 0);
7263 /* Call shorten_branches to calculate the insn lengths. */
7264 shorten_branches (get_insns());
7265 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
7267 if (!INSN_ADDRESSES_SET_P())
7268 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
7270 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7273 enum attr_type insn_type
;
7275 /* If a non-jump insn (or a casesi jump table), continue. */
7276 if (GET_CODE (insn
) != JUMP_INSN
||
7277 GET_CODE (PATTERN (insn
)) == ADDR_VEC
7278 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
7281 /* If we already have a brcc, note if it is suitable for brcc_s.
7282 Be a bit generous with the brcc_s range so that we can take
7283 advantage of any code shortening from delay slot scheduling. */
7284 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
7286 rtx pat
= PATTERN (insn
);
7287 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
7288 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
7290 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7291 if ((offset
>= -140 && offset
< 140)
7292 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
7293 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
7294 && equality_comparison_operator (op
, VOIDmode
))
7295 PUT_MODE (*ccp
, CC_Zmode
);
7296 else if (GET_MODE (*ccp
) == CC_Zmode
)
7297 PUT_MODE (*ccp
, CC_ZNmode
);
7300 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
7301 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
7304 /* OK. so we have a jump insn. */
7305 /* We need to check that it is a bcc. */
7306 /* Bcc => set (pc) (if_then_else ) */
7307 pattern
= PATTERN (insn
);
7308 if (GET_CODE (pattern
) != SET
7309 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
7310 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
7313 /* Now check if the jump is beyond the s9 range. */
7314 if (CROSSING_JUMP_P (insn
))
7316 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
7318 if(offset
> 253 || offset
< -254)
7321 pc_target
= SET_SRC (pattern
);
7323 /* Avoid FPU instructions. */
7324 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
7325 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
7328 /* Now go back and search for the set cc insn. */
7330 label
= XEXP (pc_target
, 1);
7334 rtx_insn
*scan
, *link_insn
= NULL
;
7336 for (scan
= PREV_INSN (insn
);
7337 scan
&& GET_CODE (scan
) != CODE_LABEL
;
7338 scan
= PREV_INSN (scan
))
7340 if (! INSN_P (scan
))
7342 pat
= PATTERN (scan
);
7343 if (GET_CODE (pat
) == SET
7344 && cc_register (SET_DEST (pat
), VOIDmode
))
7353 /* Check if this is a data dependency. */
7355 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
7358 /* Ok this is the set cc. copy args here. */
7359 op
= XEXP (pc_target
, 0);
7361 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
7362 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
7363 if (GET_CODE (op0
) == ZERO_EXTRACT
7364 && XEXP (op0
, 1) == const1_rtx
7365 && (GET_CODE (op
) == EQ
7366 || GET_CODE (op
) == NE
))
7368 /* btst / b{eq,ne} -> bbit{0,1} */
7369 op0
= XEXP (cmp0
, 0);
7370 op1
= XEXP (cmp0
, 2);
7372 else if (!register_operand (op0
, VOIDmode
)
7373 || !general_operand (op1
, VOIDmode
))
7375 /* Be careful not to break what cmpsfpx_raw is
7376 trying to create for checking equality of
7377 single-precision floats. */
7378 else if (TARGET_SPFP
7379 && GET_MODE (op0
) == SFmode
7380 && GET_MODE (op1
) == SFmode
)
7383 /* None of the two cmp operands should be set between the
7384 cmp and the branch. */
7385 if (reg_set_between_p (op0
, link_insn
, insn
))
7388 if (reg_set_between_p (op1
, link_insn
, insn
))
7391 /* Since the MODE check does not work, check that this is
7392 CC reg's last set location before insn, and also no
7393 instruction between the cmp and branch uses the
7395 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
7396 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
7399 /* CC reg should be dead after insn. */
7400 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
7403 op
= gen_rtx_fmt_ee (GET_CODE (op
),
7404 GET_MODE (op
), cmp0
, cmp1
);
7405 /* If we create a LIMM where there was none before,
7406 we only benefit if we can avoid a scheduling bubble
7407 for the ARC600. Otherwise, we'd only forgo chances
7408 at short insn generation, and risk out-of-range
7410 if (!brcc_nolimm_operator (op
, VOIDmode
)
7411 && !long_immediate_operand (op1
, VOIDmode
)
7413 || next_active_insn (link_insn
) != insn
))
7416 /* Emit bbit / brcc (or brcc_s if possible).
7417 CC_Zmode indicates that brcc_s is possible. */
7420 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
7421 else if ((offset
>= -140 && offset
< 140)
7422 && rtx_equal_p (op1
, const0_rtx
)
7423 && compact_register_operand (op0
, VOIDmode
)
7424 && (GET_CODE (op
) == EQ
7425 || GET_CODE (op
) == NE
))
7426 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
7428 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
7431 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
7432 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
7433 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
7436 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
7437 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
7439 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
7440 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
7443 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7444 REG_NOTES (brcc_insn
) = note
;
7446 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
7449 remove_note (link_insn
, note
);
7450 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7451 REG_NOTES (brcc_insn
) = note
;
7453 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
7456 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
7457 REG_NOTES (brcc_insn
) = note
;
7462 /* Delete the bcc insn. */
7463 set_insn_deleted (insn
);
7465 /* Delete the cmp insn. */
7466 set_insn_deleted (link_insn
);
7471 /* Clear out insn_addresses. */
7472 INSN_ADDRESSES_FREE ();
7476 if (INSN_ADDRESSES_SET_P())
7477 fatal_error (input_location
, "insn addresses not freed");
7479 arc_reorg_in_progress
= 0;
7482 /* Check if the operands are valid for BRcc.d generation
7483 Valid Brcc.d patterns are
7487 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7488 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7489 does not have a delay slot
7491 Assumed precondition: Second operand is either a register or a u6 value. */
7494 valid_brcc_with_delay_p (rtx
*operands
)
7496 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
7498 return brcc_nolimm_operator (operands
[0], VOIDmode
);
7501 /* ??? Hack. This should no really be here. See PR32143. */
7503 arc_decl_anon_ns_mem_p (const_tree decl
)
7507 if (decl
== NULL_TREE
|| decl
== error_mark_node
)
7509 if (TREE_CODE (decl
) == NAMESPACE_DECL
7510 && DECL_NAME (decl
) == NULL_TREE
)
7512 /* Classes and namespaces inside anonymous namespaces have
7513 TREE_PUBLIC == 0, so we can shortcut the search. */
7514 else if (TYPE_P (decl
))
7515 return (TREE_PUBLIC (TYPE_NAME (decl
)) == 0);
7516 else if (TREE_CODE (decl
) == NAMESPACE_DECL
)
7517 return (TREE_PUBLIC (decl
) == 0);
7519 decl
= DECL_CONTEXT (decl
);
7523 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7524 access DECL using %gp_rel(...)($gp). */
7527 arc_in_small_data_p (const_tree decl
)
7531 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
7535 /* We don't yet generate small-data references for -mabicalls. See related
7536 -G handling in override_options. */
7537 if (TARGET_NO_SDATA_SET
)
7540 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
7544 /* Reject anything that isn't in a known small-data section. */
7545 name
= DECL_SECTION_NAME (decl
);
7546 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
7549 /* If a symbol is defined externally, the assembler will use the
7550 usual -G rules when deciding how to implement macros. */
7551 if (!DECL_EXTERNAL (decl
))
7554 /* Only global variables go into sdata section for now. */
7557 /* Don't put constants into the small data section: we want them
7558 to be in ROM rather than RAM. */
7559 if (TREE_CODE (decl
) != VAR_DECL
)
7562 if (TREE_READONLY (decl
)
7563 && !TREE_SIDE_EFFECTS (decl
)
7564 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
7567 /* TREE_PUBLIC might change after the first call, because of the patch
7569 if (default_binds_local_p_1 (decl
, 1)
7570 || arc_decl_anon_ns_mem_p (decl
))
7573 /* To ensure -mvolatile-cache works
7574 ld.di does not have a gp-relative variant. */
7575 if (TREE_THIS_VOLATILE (decl
))
7579 /* Disable sdata references to weak variables. */
7580 if (DECL_WEAK (decl
))
7583 size
= int_size_in_bytes (TREE_TYPE (decl
));
7585 /* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7588 /* Allow only <=4B long data types into sdata. */
7589 return (size
> 0 && size
<= 4);
7592 /* Return true if X is a small data address that can be rewritten
7596 arc_rewrite_small_data_p (const_rtx x
)
7598 if (GET_CODE (x
) == CONST
)
7601 if (GET_CODE (x
) == PLUS
)
7603 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
7607 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
7609 gcc_assert (SYMBOL_REF_TLS_MODEL (x
) == 0);
7615 /* If possible, rewrite OP so that it refers to small data using
7616 explicit relocations. */
7619 arc_rewrite_small_data (rtx op
)
7621 op
= copy_insn (op
);
7622 subrtx_ptr_iterator::array_type array
;
7623 FOR_EACH_SUBRTX_PTR (iter
, array
, &op
, ALL
)
7626 if (arc_rewrite_small_data_p (*loc
))
7628 gcc_assert (SDATA_BASE_REGNUM
== PIC_OFFSET_TABLE_REGNUM
);
7629 *loc
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, *loc
);
7632 if (GET_CODE (op
) == MEM
&& &XEXP (op
, 0) == loc
)
7634 else if (GET_CODE (op
) == MEM
7635 && GET_CODE (XEXP (op
, 0)) == PLUS
7636 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == MULT
)
7637 *loc
= force_reg (Pmode
, *loc
);
7641 iter
.skip_subrtxes ();
7643 else if (GET_CODE (*loc
) == PLUS
7644 && rtx_equal_p (XEXP (*loc
, 0), pic_offset_table_rtx
))
7645 iter
.skip_subrtxes ();
7650 /* Return true if OP refers to small data symbols directly, not through
7654 small_data_pattern (rtx op
, machine_mode
)
7656 if (GET_CODE (op
) == SEQUENCE
)
7658 subrtx_iterator::array_type array
;
7659 FOR_EACH_SUBRTX (iter
, array
, op
, ALL
)
7661 const_rtx x
= *iter
;
7662 if (GET_CODE (x
) == PLUS
7663 && rtx_equal_p (XEXP (x
, 0), pic_offset_table_rtx
))
7664 iter
.skip_subrtxes ();
7665 else if (arc_rewrite_small_data_p (x
))
7671 /* Return true if OP is an acceptable memory operand for ARCompact
7672 16-bit gp-relative load instructions.
7673 op shd look like : [r26, symref@sda]
7674 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7676 /* volatile cache option still to be handled. */
7679 compact_sda_memory_operand (rtx op
, machine_mode mode
)
7684 /* Eliminate non-memory operations. */
7685 if (GET_CODE (op
) != MEM
)
7688 if (mode
== VOIDmode
)
7689 mode
= GET_MODE (op
);
7691 size
= GET_MODE_SIZE (mode
);
7693 /* dword operations really put out 2 instructions, so eliminate them. */
7694 if (size
> UNITS_PER_WORD
)
7697 /* Decode the address now. */
7698 addr
= XEXP (op
, 0);
7700 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
);
7703 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7706 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
7707 unsigned HOST_WIDE_INT size
,
7708 unsigned HOST_WIDE_INT align
,
7709 unsigned HOST_WIDE_INT globalize_p
)
7711 int in_small_data
= arc_in_small_data_p (decl
);
7714 switch_to_section (get_named_section (NULL
, ".sbss", 0));
7715 /* named_section (0,".sbss",0); */
7717 switch_to_section (bss_section
);
7720 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
7722 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
7723 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
7724 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
7725 ASM_OUTPUT_LABEL (stream
, name
);
7728 ASM_OUTPUT_SKIP (stream
, size
);
7732 arc_preserve_reload_p (rtx in
)
7734 return (GET_CODE (in
) == PLUS
7735 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
7736 && CONST_INT_P (XEXP (in
, 1))
7737 && !((INTVAL (XEXP (in
, 1)) & 511)));
7741 arc_register_move_cost (machine_mode
,
7742 enum reg_class from_class
, enum reg_class to_class
)
7744 /* The ARC600 has no bypass for extension registers, hence a nop might be
7745 needed to be inserted after a write so that reads are safe. */
7748 if (to_class
== MPY_WRITABLE_CORE_REGS
)
7750 /* Instructions modifying LP_COUNT need 4 additional cycles before
7751 the register will actually contain the value. */
7752 else if (to_class
== LPCOUNT_REG
)
7754 else if (to_class
== WRITABLE_CORE_REGS
)
7758 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7760 && (from_class
== LPCOUNT_REG
|| from_class
== ALL_CORE_REGS
7761 || from_class
== WRITABLE_CORE_REGS
))
7764 /* Force an attempt to 'mov Dy,Dx' to spill. */
7765 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
7766 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
7772 /* Emit code for an addsi3 instruction with OPERANDS.
7773 COND_P indicates if this will use conditional execution.
7774 Return the length of the instruction.
7775 If OUTPUT_P is false, don't actually output the instruction, just return
7778 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
7782 int match
= operands_match_p (operands
[0], operands
[1]);
7783 int match2
= operands_match_p (operands
[0], operands
[2]);
7784 int intval
= (REG_P (operands
[2]) ? 1
7785 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
7786 int neg_intval
= -intval
;
7787 int short_0
= satisfies_constraint_Rcq (operands
[0]);
7788 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
7791 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
7792 && REGNO (OP) != 30) \
7795 #define ADDSI_OUTPUT1(FORMAT) do {\
7797 output_asm_insn (FORMAT, operands);\
7800 #define ADDSI_OUTPUT(LIST) do {\
7803 ADDSI_OUTPUT1 (format);\
7807 /* First try to emit a 16 bit insn. */
7810 /* If we are actually about to output this insn, don't try a 16 bit
7811 variant if we already decided that we don't want that
7812 (I.e. we upsized this insn to align some following insn.)
7813 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7814 but add1 r0,sp,35 doesn't. */
7815 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
7817 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
7820 && ((REG_H_P (operands
[2])
7821 && (match
|| satisfies_constraint_Rcq (operands
[2])))
7822 || (CONST_INT_P (operands
[2])
7823 && ((unsigned) intval
<= (match
? 127 : 7)))))
7824 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
7826 /* Generate add_s b,b,h patterns. */
7827 if (short_0
&& match2
&& REG_H_P (operands
[1]))
7828 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
7830 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
7831 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
7832 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
7833 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
7835 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
7836 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
7837 && match
&& !(neg_intval
& ~124)))
7838 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
7840 /* Generate add_s h,h,s3 patterns. */
7841 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
7842 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
7843 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
7845 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
7846 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
7847 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
7848 && satisfies_constraint_Rcq (operands
[1])
7849 && satisfies_constraint_L (operands
[2]))
7850 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
7853 /* Now try to emit a 32 bit insn without long immediate. */
7855 if (!match
&& match2
&& REG_P (operands
[1]))
7856 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7857 if (match
|| !cond_p
)
7859 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
7860 int range_factor
= neg_intval
& intval
;
7863 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
7864 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7866 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7867 same size, do, so - the insn latency is lower. */
7868 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7870 if ((intval
>= 0 && intval
<= limit
)
7871 || (intval
== -0x800 && limit
== 0x7ff))
7872 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7873 else if ((intval
< 0 && neg_intval
<= limit
)
7874 || (intval
== 0x800 && limit
== 0x7ff))
7875 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7876 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
7877 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
7878 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
7879 if (((intval
< 0 && intval
!= -0x4000)
7880 /* sub[123] is slower than add_s / sub, only use it if it
7881 avoids a long immediate. */
7882 && neg_intval
<= limit
<< shift
)
7883 || (intval
== 0x4000 && limit
== 0x7ff))
7884 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
7885 shift
, neg_intval
>> shift
));
7886 else if ((intval
>= 0 && intval
<= limit
<< shift
)
7887 || (intval
== -0x4000 && limit
== 0x7ff))
7888 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
7890 /* Try to emit a 16 bit opcode with long immediate. */
7892 if (short_p
&& match
)
7893 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7895 /* We have to use a 32 bit opcode, and with a long immediate. */
7897 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7900 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
7901 Return the length of the instruction.
7902 If OUTPUT_P is false, don't actually output the instruction, just return
7905 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
7907 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
7908 const char *pat
= NULL
;
7910 /* Canonical rtl should not have a constant in the first operand position. */
7911 gcc_assert (!CONSTANT_P (operands
[1]));
7913 switch (commutative_op
)
7916 if (satisfies_constraint_C1p (operands
[2]))
7917 pat
= "bmsk%? %0,%1,%Z2";
7918 else if (satisfies_constraint_C2p (operands
[2]))
7920 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
7921 pat
= "bmskn%? %0,%1,%Z2";
7923 else if (satisfies_constraint_Ccp (operands
[2]))
7924 pat
= "bclr%? %0,%1,%M2";
7925 else if (satisfies_constraint_CnL (operands
[2]))
7926 pat
= "bic%? %0,%1,%n2-1";
7929 if (satisfies_constraint_C0p (operands
[2]))
7930 pat
= "bset%? %0,%1,%z2";
7933 if (satisfies_constraint_C0p (operands
[2]))
7934 pat
= "bxor%? %0,%1,%z2";
7937 return arc_output_addsi (operands
, true, output_p
);
7941 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
7942 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
7947 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7948 Emit code and return an potentially modified address such that offsets
7949 up to SIZE are can be added to yield a legitimate address.
7950 if REUSE is set, ADDR is a register that may be modified. */
7953 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
7956 rtx offs
= const0_rtx
;
7958 if (GET_CODE (base
) == PLUS
)
7960 offs
= XEXP (base
, 1);
7961 base
= XEXP (base
, 0);
7964 || (REGNO (base
) != STACK_POINTER_REGNUM
7965 && REGNO_PTR_FRAME_P (REGNO (base
)))
7966 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
7967 || !SMALL_INT (INTVAL (offs
) + size
))
7970 emit_insn (gen_add2_insn (addr
, offs
));
7972 addr
= copy_to_mode_reg (Pmode
, addr
);
7977 /* Like move_by_pieces, but take account of load latency, and actual
7978 offset ranges. Return true on success. */
7981 arc_expand_movmem (rtx
*operands
)
7983 rtx dst
= operands
[0];
7984 rtx src
= operands
[1];
7985 rtx dst_addr
, src_addr
;
7987 int align
= INTVAL (operands
[3]);
7994 if (!CONST_INT_P (operands
[2]))
7996 size
= INTVAL (operands
[2]);
7997 /* move_by_pieces_ninsns is static, so we can't use it. */
8001 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
8003 n_pieces
= (size
+ 2) / 4U + (size
& 1);
8005 else if (align
== 2)
8006 n_pieces
= (size
+ 1) / 2U;
8009 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
8011 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8013 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
8017 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
8018 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
8019 store
[0] = store
[1] = NULL_RTX
;
8020 tmpx
[0] = tmpx
[1] = NULL_RTX
;
8021 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
8026 while (piece
> size
)
8028 mode
= smallest_mode_for_size (piece
* BITS_PER_UNIT
, MODE_INT
);
8029 /* If we don't re-use temporaries, the scheduler gets carried away,
8030 and the register pressure gets unnecessarily high. */
8031 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
8034 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
8035 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
8036 src_addr
= force_offsettable (src_addr
, piece
, 1);
8038 emit_insn (store
[i
]);
8039 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
8040 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
8041 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
8042 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
8045 emit_insn (store
[i
]);
8047 emit_insn (store
[i
^1]);
8051 /* Prepare operands for move in MODE. Return true iff the move has
8055 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8057 /* We used to do this only for MODE_INT Modes, but addresses to floating
8058 point variables may well be in the small data section. */
8059 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[0], Pmode
))
8060 operands
[0] = arc_rewrite_small_data (operands
[0]);
8062 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
8064 prepare_pic_move (operands
, SImode
);
8066 /* Disable any REG_EQUALs associated with the symref
8067 otherwise the optimization pass undoes the work done
8068 here and references the variable directly. */
8071 if (GET_CODE (operands
[0]) != MEM
8072 && !TARGET_NO_SDATA_SET
8073 && small_data_pattern (operands
[1], Pmode
))
8075 /* This is to take care of address calculations involving sdata
8077 operands
[1] = arc_rewrite_small_data (operands
[1]);
8079 emit_insn (gen_rtx_SET (operands
[0],operands
[1]));
8080 /* ??? This note is useless, since it only restates the set itself.
8081 We should rather use the original SYMBOL_REF. However, there is
8082 the problem that we are lying to the compiler about these
8083 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8084 so that we can tell it apart from an actual symbol. */
8085 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8087 /* Take care of the REG_EQUAL note that will be attached to mark the
8088 output reg equal to the initial symbol_ref after this code is
8090 emit_move_insn (operands
[0], operands
[0]);
8094 if (MEM_P (operands
[0])
8095 && !(reload_in_progress
|| reload_completed
))
8097 operands
[1] = force_reg (mode
, operands
[1]);
8098 if (!move_dest_operand (operands
[0], mode
))
8100 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
8101 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8102 except that we can't use that function because it is static. */
8103 rtx pat
= change_address (operands
[0], mode
, addr
);
8104 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8107 if (!cse_not_expected
)
8109 rtx pat
= XEXP (operands
[0], 0);
8111 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8114 pat
= change_address (operands
[0], mode
, pat
);
8115 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
8121 if (MEM_P (operands
[1]) && !cse_not_expected
)
8123 rtx pat
= XEXP (operands
[1], 0);
8125 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
8128 pat
= change_address (operands
[1], mode
, pat
);
8129 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
8137 /* Prepare OPERANDS for an extension using CODE to OMODE.
8138 Return true iff the move has been emitted. */
8141 prepare_extend_operands (rtx
*operands
, enum rtx_code code
,
8144 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[1], Pmode
))
8146 /* This is to take care of address calculations involving sdata
8149 = gen_rtx_fmt_e (code
, omode
, arc_rewrite_small_data (operands
[1]));
8150 emit_insn (gen_rtx_SET (operands
[0], operands
[1]));
8151 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
8153 /* Take care of the REG_EQUAL note that will be attached to mark the
8154 output reg equal to the initial extension after this code is
8156 emit_move_insn (operands
[0], operands
[0]);
8162 /* Output a library call to a function called FNAME that has been arranged
8163 to be local to any dso. */
8166 arc_output_libcall (const char *fname
)
8168 unsigned len
= strlen (fname
);
8169 static char buf
[64];
8171 gcc_assert (len
< sizeof buf
- 35);
8172 if (TARGET_LONG_CALLS_SET
8173 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
8176 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
8178 sprintf (buf
, "jl%%! @%s", fname
);
8181 sprintf (buf
, "bl%%!%%* @%s", fname
);
8185 /* Return the SImode highpart of the DImode value IN. */
8188 disi_highpart (rtx in
)
8190 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
8193 /* Return length adjustment for INSN.
8195 A write to a core reg greater or equal to 32 must not be immediately
8196 followed by a use. Anticipate the length requirement to insert a nop
8197 between PRED and SUCC to prevent a hazard. */
8200 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8204 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
8205 in front of SUCC anyway, so there will be separation between PRED and
8207 if (recog_memoized (succ
) == CODE_FOR_doloop_end_i
8208 && LABEL_P (prev_nonnote_insn (succ
)))
8210 if (recog_memoized (succ
) == CODE_FOR_doloop_begin_i
)
8212 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8213 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
8214 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
8215 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
8216 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
8217 || recog_memoized (pred
) == CODE_FOR_umul_600
8218 || recog_memoized (pred
) == CODE_FOR_mac_600
8219 || recog_memoized (pred
) == CODE_FOR_mul64_600
8220 || recog_memoized (pred
) == CODE_FOR_mac64_600
8221 || recog_memoized (pred
) == CODE_FOR_umul64_600
8222 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
8224 subrtx_iterator::array_type array
;
8225 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
8227 const_rtx x
= *iter
;
8228 switch (GET_CODE (x
))
8230 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8233 /* This is also fine for PRE/POST_MODIFY, because they
8237 rtx dest
= XEXP (x
, 0);
8238 /* Check if this sets a an extension register. N.B. we use 61 for the
8239 condition codes, which is definitely not an extension register. */
8240 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
8241 /* Check if the same register is used by the PAT. */
8242 && (refers_to_regno_p
8244 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
8245 PATTERN (succ
), 0)))
8251 /* Given a rtx, check if it is an assembly instruction or not. */
8254 arc_asm_insn_p (rtx x
)
8261 switch (GET_CODE (x
))
8268 return arc_asm_insn_p (SET_SRC (x
));
8272 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
8273 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
8285 /* We might have a CALL to a non-returning function before a loop end.
8286 ??? Although the manual says that's OK (the target is outside the
8287 loop, and the loop counter unused there), the assembler barfs on
8288 this for ARC600, so we must insert a nop before such a call too.
8289 For ARC700, and ARCv2 is not allowed to have the last ZOL
8290 instruction a jump to a location where lp_count is modified. */
8293 arc_loop_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8295 rtx_insn
*jump
= NULL
;
8296 rtx label_rtx
= NULL_RTX
;
8297 rtx_insn
*label
= NULL
;
8298 basic_block succ_bb
;
8300 if (recog_memoized (succ
) != CODE_FOR_doloop_end_i
)
8303 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
8304 (i.e., jump/call) as the last instruction of a ZOL. */
8305 if (TARGET_ARC600
|| TARGET_HS
)
8306 if (JUMP_P (pred
) || CALL_P (pred
)
8307 || arc_asm_insn_p (PATTERN (pred
))
8308 || GET_CODE (PATTERN (pred
)) == SEQUENCE
)
8311 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
8312 instruction a jump to a location where lp_count is modified. */
8314 /* Phase 2a: Dig for the jump instruction. */
8317 else if (GET_CODE (PATTERN (pred
)) == SEQUENCE
8318 && JUMP_P (XVECEXP (PATTERN (pred
), 0, 0)))
8319 jump
= as_a
<rtx_insn
*> (XVECEXP (PATTERN (pred
), 0, 0));
8323 /* Phase 2b: Make sure is not a millicode jump. */
8324 if ((GET_CODE (PATTERN (jump
)) == PARALLEL
)
8325 && (XVECEXP (PATTERN (jump
), 0, 0) == ret_rtx
))
8328 label_rtx
= JUMP_LABEL (jump
);
8332 /* Phase 2c: Make sure is not a return. */
8333 if (ANY_RETURN_P (label_rtx
))
8336 /* Pahse 2d: Go to the target of the jump and check for aliveness of
8337 LP_COUNT register. */
8338 label
= safe_as_a
<rtx_insn
*> (label_rtx
);
8339 succ_bb
= BLOCK_FOR_INSN (label
);
8342 gcc_assert (NEXT_INSN (label
));
8343 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label
)))
8344 succ_bb
= NOTE_BASIC_BLOCK (NEXT_INSN (label
));
8346 succ_bb
= BLOCK_FOR_INSN (NEXT_INSN (label
));
8349 if (succ_bb
&& REGNO_REG_SET_P (df_get_live_out (succ_bb
), LP_COUNT
))
8356 A write to a core reg greater or equal to 32 must not be immediately
8357 followed by a use. Anticipate the length requirement to insert a nop
8358 between PRED and SUCC to prevent a hazard. */
8361 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
8363 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
8366 if (arc_loop_hazard (pred
, succ
))
8370 return arc600_corereg_hazard (pred
, succ
);
8375 /* Return length adjustment for INSN. */
8378 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
8382 /* We already handle sequences by ignoring the delay sequence flag. */
8383 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
8386 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
8387 the ZOL mechanism only triggers when advancing to the end address,
8388 so if there's a label at the end of a ZOL, we need to insert a nop.
8389 The ARC600 ZOL also has extra restrictions on jumps at the end of a
8391 if (recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
8393 rtx_insn
*prev
= prev_nonnote_insn (insn
);
8395 return ((LABEL_P (prev
)
8398 || CALL_P (prev
) /* Could be a noreturn call. */
8399 || (NONJUMP_INSN_P (prev
)
8400 && GET_CODE (PATTERN (prev
)) == SEQUENCE
))))
8404 /* Check for return with but one preceding insn since function
8406 if (TARGET_PAD_RETURN
8408 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
8409 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
8410 && get_attr_type (insn
) == TYPE_RETURN
)
8412 rtx_insn
*prev
= prev_active_insn (insn
);
8414 if (!prev
|| !(prev
= prev_active_insn (prev
))
8415 || ((NONJUMP_INSN_P (prev
)
8416 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8417 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8419 : CALL_ATTR (prev
, NON_SIBCALL
)))
8424 rtx_insn
*succ
= next_real_insn (insn
);
8426 /* One the ARC600, a write to an extension register must be separated
8428 if (succ
&& INSN_P (succ
))
8429 len
+= arc600_corereg_hazard (insn
, succ
);
8432 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8434 extract_constrain_insn_cached (insn
);
8439 /* Values for length_sensitive. */
8443 ARC_LS_25
, // 25 bit offset, B
8444 ARC_LS_21
, // 21 bit offset, Bcc
8445 ARC_LS_U13
,// 13 bit unsigned offset, LP
8446 ARC_LS_10
, // 10 bit offset, B_s, Beq_s, Bne_s
8447 ARC_LS_9
, // 9 bit offset, BRcc
8448 ARC_LS_8
, // 8 bit offset, BRcc_s
8449 ARC_LS_U7
, // 7 bit unsigned offset, LPcc
8450 ARC_LS_7
// 7 bit offset, Bcc_s
8453 /* While the infrastructure patch is waiting for review, duplicate the
8454 struct definitions, to allow this file to compile. */
8459 /* Cost as a branch / call target or call return address. */
8461 int fallthrough_cost
;
8464 /* 0 for not length sensitive, 1 for largest offset range,
8465 * 2 for next smaller etc. */
8466 unsigned length_sensitive
: 8;
8468 } insn_length_variant_t
;
8470 typedef struct insn_length_parameters_s
8475 int (*get_variants
) (rtx_insn
*, int, bool, bool, insn_length_variant_t
*);
8476 } insn_length_parameters_t
;
8479 arc_insn_length_parameters (insn_length_parameters_t
*ilp
) ATTRIBUTE_UNUSED
;
8483 arc_get_insn_variants (rtx_insn
*insn
, int len
, bool, bool target_p
,
8484 insn_length_variant_t
*ilv
)
8486 if (!NONDEBUG_INSN_P (insn
))
8488 enum attr_type type
;
8489 /* shorten_branches doesn't take optimize_size into account yet for the
8490 get_variants mechanism, so turn this off for now. */
8493 if (rtx_sequence
*pat
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
8495 /* The interaction of a short delay slot insn with a short branch is
8496 too weird for shorten_branches to piece together, so describe the
8499 if (TARGET_UPSIZE_DBR
8500 && get_attr_length (pat
->insn (1)) <= 2
8501 && (((type
= get_attr_type (inner
= pat
->insn (0)))
8502 == TYPE_UNCOND_BRANCH
)
8503 || type
== TYPE_BRANCH
)
8504 && get_attr_delay_slot_filled (inner
) == DELAY_SLOT_FILLED_YES
)
8507 = arc_get_insn_variants (inner
, get_attr_length (inner
), true,
8509 /* The short variant gets split into a higher-cost aligned
8510 and a lower cost unaligned variant. */
8511 gcc_assert (n_variants
);
8512 gcc_assert (ilv
[1].length_sensitive
== ARC_LS_7
8513 || ilv
[1].length_sensitive
== ARC_LS_10
);
8514 gcc_assert (ilv
[1].align_set
== 3);
8516 ilv
[0].align_set
= 1;
8517 ilv
[0].branch_cost
+= 1;
8518 ilv
[1].align_set
= 2;
8520 for (int i
= 0; i
< n_variants
; i
++)
8522 /* In case an instruction with aligned size is wanted, and
8523 the short variants are unavailable / too expensive, add
8524 versions of long branch + long delay slot. */
8525 for (int i
= 2, end
= n_variants
; i
< end
; i
++, n_variants
++)
8527 ilv
[n_variants
] = ilv
[i
];
8528 ilv
[n_variants
].length
+= 2;
8534 insn_length_variant_t
*first_ilv
= ilv
;
8535 type
= get_attr_type (insn
);
8537 = (get_attr_delay_slot_filled (insn
) == DELAY_SLOT_FILLED_YES
);
8538 int branch_align_cost
= delay_filled
? 0 : 1;
8539 int branch_unalign_cost
= delay_filled
? 0 : TARGET_UNALIGN_BRANCH
? 0 : 1;
8540 /* If the previous instruction is an sfunc call, this insn is always
8541 a target, even though the middle-end is unaware of this. */
8542 bool force_target
= false;
8543 rtx_insn
*prev
= prev_active_insn (insn
);
8544 if (prev
&& arc_next_active_insn (prev
, 0) == insn
8545 && ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8546 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8548 : (CALL_ATTR (prev
, NON_SIBCALL
)
8549 && NEXT_INSN (PREV_INSN (prev
)) == prev
)))
8550 force_target
= true;
8555 /* Short BRCC only comes in no-delay-slot version, and without limm */
8560 ilv
->branch_cost
= 1;
8561 ilv
->enabled
= (len
== 2);
8562 ilv
->length_sensitive
= ARC_LS_8
;
8566 case TYPE_BRCC_NO_DELAY_SLOT
:
8567 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8568 (delay slot) scheduling purposes, but they are longer. */
8569 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8570 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 1)) == SET
)
8572 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8573 ilv
->length
= ((type
== TYPE_BRCC
) ? 4 : 8);
8575 ilv
->branch_cost
= branch_align_cost
;
8576 ilv
->enabled
= (len
<= ilv
->length
);
8577 ilv
->length_sensitive
= ARC_LS_9
;
8578 if ((target_p
|| force_target
)
8579 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8585 ilv
->target_cost
= 1;
8586 ilv
->branch_cost
= branch_unalign_cost
;
8591 op
= XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 0);
8594 if (GET_CODE (op0
) == ZERO_EXTRACT
8595 && satisfies_constraint_L (XEXP (op0
, 2)))
8596 op0
= XEXP (op0
, 0);
8597 if (satisfies_constraint_Rcq (op0
))
8599 ilv
->length
= ((type
== TYPE_BRCC
) ? 6 : 10);
8601 ilv
->branch_cost
= 1 + branch_align_cost
;
8602 ilv
->fallthrough_cost
= 1;
8603 ilv
->enabled
= true;
8604 ilv
->length_sensitive
= ARC_LS_21
;
8605 if (!delay_filled
&& TARGET_UNALIGN_BRANCH
)
8611 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8615 ilv
->length
= ((type
== TYPE_BRCC
) ? 8 : 12);
8617 ilv
->branch_cost
= 1 + branch_align_cost
;
8618 ilv
->fallthrough_cost
= 1;
8619 ilv
->enabled
= true;
8620 ilv
->length_sensitive
= ARC_LS_21
;
8621 if ((target_p
|| force_target
)
8622 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8628 ilv
->target_cost
= 1;
8629 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8637 case TYPE_CALL_NO_DELAY_SLOT
:
8642 ilv
->length_sensitive
8643 = GET_CODE (PATTERN (insn
)) == COND_EXEC
? ARC_LS_21
: ARC_LS_25
;
8646 ilv
->fallthrough_cost
= branch_align_cost
;
8647 ilv
->enabled
= true;
8648 if ((target_p
|| force_target
)
8649 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8655 ilv
->target_cost
= 1;
8656 ilv
->fallthrough_cost
= branch_unalign_cost
;
8660 case TYPE_UNCOND_BRANCH
:
8661 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8662 but that makes no difference at the moment. */
8663 ilv
->length_sensitive
= ARC_LS_7
;
8664 ilv
[1].length_sensitive
= ARC_LS_25
;
8667 ilv
->length_sensitive
= ARC_LS_10
;
8668 ilv
[1].length_sensitive
= ARC_LS_21
;
8672 ilv
->branch_cost
= branch_align_cost
;
8673 ilv
->enabled
= (len
== ilv
->length
);
8677 ilv
->branch_cost
= branch_align_cost
;
8678 ilv
->enabled
= true;
8679 if ((target_p
|| force_target
)
8680 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8686 ilv
->target_cost
= 1;
8687 ilv
->branch_cost
= branch_unalign_cost
;
8694 /* For every short insn, there is generally also a long insn.
8695 trap_s is an exception. */
8696 if ((len
& 2) == 0 || recog_memoized (insn
) == CODE_FOR_trap_s
)
8703 ilv
->length
= len
+ 2;
8705 if (target_p
|| force_target
)
8711 ilv
->target_cost
= 1;
8715 /* If the previous instruction is an sfunc call, this insn is always
8716 a target, even though the middle-end is unaware of this.
8717 Therefore, if we have a call predecessor, transfer the target cost
8718 to the fallthrough and branch costs. */
8721 for (insn_length_variant_t
*p
= first_ilv
; p
< ilv
; p
++)
8723 p
->fallthrough_cost
+= p
->target_cost
;
8724 p
->branch_cost
+= p
->target_cost
;
8729 return ilv
- first_ilv
;
8733 arc_insn_length_parameters (insn_length_parameters_t
*ilp
)
8735 ilp
->align_unit_log
= 1;
8736 ilp
->align_base_log
= 1;
8737 ilp
->max_variants
= 7;
8738 ilp
->get_variants
= arc_get_insn_variants
;
8741 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8742 CC field of *STATEP. */
8745 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8747 rtx cond
= statep
->cond
;
8748 int raw_cc
= get_arc_condition_code (cond
);
8750 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8752 if (statep
->cc
== raw_cc
)
8753 return copy_rtx (cond
);
8755 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8757 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8758 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8759 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8760 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8762 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8763 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8766 /* Return version of PAT conditionalized with COND, which is part of INSN.
8767 ANNULLED indicates if INSN is an annulled delay-slot insn.
8768 Register further changes if necessary. */
8770 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8772 /* For commutative operators, we generally prefer to have
8773 the first source match the destination. */
8774 if (GET_CODE (pat
) == SET
)
8776 rtx src
= SET_SRC (pat
);
8778 if (COMMUTATIVE_P (src
))
8780 rtx src0
= XEXP (src
, 0);
8781 rtx src1
= XEXP (src
, 1);
8782 rtx dst
= SET_DEST (pat
);
8784 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8785 /* Leave add_n alone - the canonical form is to
8786 have the complex summand first. */
8788 pat
= gen_rtx_SET (dst
,
8789 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8794 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8795 what to do with COND_EXEC. */
8796 if (RTX_FRAME_RELATED_P (insn
))
8798 /* If this is the delay slot insn of an anulled branch,
8799 dwarf2out.c:scan_trace understands the anulling semantics
8800 without the COND_EXEC. */
8801 gcc_assert (annulled
);
8802 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8804 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8806 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8810 /* Use the ccfsm machinery to do if conversion. */
8815 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8816 basic_block merge_bb
= 0;
8818 memset (statep
, 0, sizeof *statep
);
8819 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8821 arc_ccfsm_advance (insn
, statep
);
8823 switch (statep
->state
)
8831 /* Deleted branch. */
8832 gcc_assert (!merge_bb
);
8833 merge_bb
= BLOCK_FOR_INSN (insn
);
8835 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn
))));
8836 arc_ccfsm_post_advance (insn
, statep
);
8837 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8838 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8841 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8842 rtx pat
= PATTERN (slot
);
8843 if (INSN_ANNULLED_BRANCH_P (insn
))
8846 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8847 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8849 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8851 PUT_CODE (slot
, NOTE
);
8852 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
8853 if (merge_bb
&& succ_bb
)
8854 merge_blocks (merge_bb
, succ_bb
);
8856 else if (merge_bb
&& succ_bb
)
8858 set_insn_deleted (insn
);
8859 merge_blocks (merge_bb
, succ_bb
);
8863 PUT_CODE (insn
, NOTE
);
8864 NOTE_KIND (insn
) = NOTE_INSN_DELETED
;
8870 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
8872 arc_ccfsm_post_advance (insn
, statep
);
8873 basic_block succ_bb
= BLOCK_FOR_INSN (insn
);
8874 if (merge_bb
&& succ_bb
)
8875 merge_blocks (merge_bb
, succ_bb
);
8876 else if (--LABEL_NUSES (insn
) == 0)
8878 const char *name
= LABEL_NAME (insn
);
8879 PUT_CODE (insn
, NOTE
);
8880 NOTE_KIND (insn
) = NOTE_INSN_DELETED_LABEL
;
8881 NOTE_DELETED_LABEL_NAME (insn
) = name
;
8888 if (!NONDEBUG_INSN_P (insn
))
8891 /* Conditionalized insn. */
8893 rtx_insn
*prev
, *pprev
;
8894 rtx
*patp
, pat
, cond
;
8895 bool annulled
; annulled
= false;
8897 /* If this is a delay slot insn in a non-annulled branch,
8898 don't conditionalize it. N.B., this should be fine for
8899 conditional return too. However, don't do this for
8900 unconditional branches, as these would be encountered when
8901 processing an 'else' part. */
8902 prev
= PREV_INSN (insn
);
8903 pprev
= PREV_INSN (prev
);
8904 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
8905 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
8907 if (!INSN_ANNULLED_BRANCH_P (prev
))
8912 patp
= &PATTERN (insn
);
8914 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
8915 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
8917 /* ??? don't conditionalize if all side effects are dead
8918 in the not-execute case. */
8920 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
8922 else if (simplejump_p (insn
))
8924 patp
= &SET_SRC (pat
);
8925 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
8927 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
8929 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
8930 pat
= gen_rtx_SET (pc_rtx
, pat
);
8934 validate_change (insn
, patp
, pat
, 1);
8935 if (!apply_change_group ())
8939 rtx_insn
*next
= next_nonnote_insn (insn
);
8940 if (GET_CODE (next
) == BARRIER
)
8942 if (statep
->state
== 3)
8949 arc_ccfsm_post_advance (insn
, statep
);
8954 /* Find annulled delay insns and convert them to use the appropriate predicate.
8955 This allows branch shortening to size up these insns properly. */
8958 arc_predicate_delay_insns (void)
8960 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8962 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
8965 if (!NONJUMP_INSN_P (insn
)
8966 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
8968 jump
= XVECEXP (pat
, 0, 0);
8969 dlay
= XVECEXP (pat
, 0, 1);
8970 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
8972 /* If the branch insn does the annulling, leave the delay insn alone. */
8973 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
8975 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8976 on the other path. */
8977 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
8978 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
8979 src
= SET_SRC (PATTERN (jump
));
8980 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
8981 cond
= XEXP (src
, 0);
8982 if (XEXP (src
, 2) == pc_rtx
)
8984 else if (XEXP (src
, 1) == pc_rtx
)
8988 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
8990 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8991 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8992 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8993 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8995 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8996 copy_rtx (XEXP (cond
, 0)),
8997 copy_rtx (XEXP (cond
, 1)));
9000 cond
= copy_rtx (cond
);
9001 patp
= &PATTERN (dlay
);
9003 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9004 validate_change (dlay
, patp
, pat
, 1);
9005 if (!apply_change_group ())
9011 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9012 (other than of a forward brcc), it creates a hazard when there is a read
9013 of the same register at the branch target. We can't know what is at the
9014 branch target of calls, and for branches, we don't really know before the
9015 end of delay slot scheduling, either. Not only can individual instruction
9016 be hoisted out into a delay slot, a basic block can also be emptied this
9017 way, and branch and/or fall through targets be redirected. Hence we don't
9018 want such writes in a delay slot. */
9020 /* Return nonzreo iff INSN writes to an extension core register. */
9023 arc_write_ext_corereg (rtx insn
)
9025 subrtx_iterator::array_type array
;
9026 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9028 const_rtx x
= *iter
;
9029 switch (GET_CODE (x
))
9031 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9034 /* This is also fine for PRE/POST_MODIFY, because they
9038 const_rtx dest
= XEXP (x
, 0);
9039 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9045 /* This is like the hook, but returns NULL when it can't / won't generate
9046 a legitimate address. */
9049 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9054 if (flag_pic
&& SYMBOLIC_CONST (x
))
9055 (x
) = arc_legitimize_pic_address (x
, 0);
9057 if (GET_CODE (addr
) == CONST
)
9058 addr
= XEXP (addr
, 0);
9059 if (GET_CODE (addr
) == PLUS
9060 && CONST_INT_P (XEXP (addr
, 1))
9061 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9062 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9063 || (REG_P (XEXP (addr
, 0))
9064 && (INTVAL (XEXP (addr
, 1)) & 252))))
9066 HOST_WIDE_INT offs
, upper
;
9067 int size
= GET_MODE_SIZE (mode
);
9069 offs
= INTVAL (XEXP (addr
, 1));
9070 upper
= (offs
+ 256 * size
) & ~511 * size
;
9071 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9072 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9073 if (GET_CODE (x
) == CONST
)
9074 inner
= gen_rtx_CONST (Pmode
, inner
);
9076 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9079 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9080 x
= force_reg (Pmode
, x
);
9081 if (memory_address_p ((machine_mode
) mode
, x
))
9087 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9089 if (GET_CODE (orig_x
) == SYMBOL_REF
)
9091 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
9093 return arc_legitimize_tls_address (orig_x
, model
);
9096 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9104 arc_delegitimize_address_0 (rtx x
)
9108 if (GET_CODE (x
) == CONST
&& GET_CODE (u
= XEXP (x
, 0)) == UNSPEC
)
9110 if (XINT (u
, 1) == ARC_UNSPEC_GOT
9111 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
)
9112 return XVECEXP (u
, 0, 0);
9114 else if (GET_CODE (x
) == CONST
&& GET_CODE (p
= XEXP (x
, 0)) == PLUS
9115 && GET_CODE (u
= XEXP (p
, 0)) == UNSPEC
9116 && (XINT (u
, 1) == ARC_UNSPEC_GOT
9117 || XINT (u
, 1) == ARC_UNSPEC_GOTOFFPC
))
9118 return gen_rtx_CONST
9120 gen_rtx_PLUS (GET_MODE (p
), XVECEXP (u
, 0, 0), XEXP (p
, 1)));
9121 else if (GET_CODE (x
) == PLUS
9122 && ((REG_P (gp
= XEXP (x
, 0))
9123 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9124 || (GET_CODE (gp
) == CONST
9125 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9126 && XINT (u
, 1) == ARC_UNSPEC_GOT
9127 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9128 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9129 && GET_CODE (XEXP (x
, 1)) == CONST
9130 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9131 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9132 return XVECEXP (u
, 0, 0);
9133 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 0)) == PLUS
9134 && ((REG_P (gp
= XEXP (XEXP (x
, 0), 1))
9135 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
9136 || (GET_CODE (gp
) == CONST
9137 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
9138 && XINT (u
, 1) == ARC_UNSPEC_GOT
9139 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
9140 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
9141 && GET_CODE (XEXP (x
, 1)) == CONST
9142 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
9143 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
9144 return gen_rtx_PLUS (GET_MODE (x
), XEXP (XEXP (x
, 0), 0),
9146 else if (GET_CODE (x
) == PLUS
9147 && (u
= arc_delegitimize_address_0 (XEXP (x
, 1))))
9148 return gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0), u
);
9153 arc_delegitimize_address (rtx x
)
9155 rtx orig_x
= x
= delegitimize_mem_from_attrs (x
);
9156 if (GET_CODE (x
) == MEM
)
9158 x
= arc_delegitimize_address_0 (x
);
9162 x
= replace_equiv_address_nv (orig_x
, x
);
9168 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9169 differ from the hardware register number in order to allow the generic
9170 code to correctly split the concatenation of acc1 and acc2. */
9175 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9178 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9179 differ from the hardware register number in order to allow the generic
9180 code to correctly split the concatenation of acc1 and acc2. */
9185 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9188 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9189 differ from the hardware register number in order to allow the generic
9190 code to correctly split the concatenation of mhi and mlo. */
9195 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
9198 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9199 differ from the hardware register number in order to allow the generic
9200 code to correctly split the concatenation of mhi and mlo. */
9205 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
9208 /* FIXME: a parameter should be added, and code added to final.c,
9209 to reproduce this functionality in shorten_branches. */
9211 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9212 a previous instruction. */
9214 arc_unalign_branch_p (rtx branch
)
9218 if (!TARGET_UNALIGN_BRANCH
)
9220 /* Do not do this if we have a filled delay slot. */
9221 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9222 && !NEXT_INSN (branch
)->deleted ())
9224 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9226 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9227 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9231 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9232 are three reasons why we need to consider branches to be length 6:
9233 - annull-false delay slot insns are implemented using conditional execution,
9234 thus preventing short insn formation where used.
9235 - for ARC600: annul-true delay slot insns are implemented where possible
9236 using conditional execution, preventing short insn formation where used.
9237 - for ARC700: likely or somewhat likely taken branches are made long and
9238 unaligned if possible to avoid branch penalty. */
9241 arc_branch_size_unknown_p (void)
9243 return !optimize_size
&& arc_reorg_in_progress
;
9246 /* We are about to output a return insn. Add padding if necessary to avoid
9247 a mispredict. A return could happen immediately after the function
9248 start, but after a call we know that there will be at least a blink
9252 arc_pad_return (void)
9254 rtx_insn
*insn
= current_output_insn
;
9255 rtx_insn
*prev
= prev_active_insn (insn
);
9260 fputs ("\tnop_s\n", asm_out_file
);
9261 cfun
->machine
->unalign
^= 2;
9264 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9265 because after a call, we'd have to restore blink first. */
9266 else if (GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9270 want_long
= (get_attr_length (prev
) == 2);
9271 prev
= prev_active_insn (prev
);
9274 || ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9275 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9277 : CALL_ATTR (prev
, NON_SIBCALL
)))
9280 cfun
->machine
->size_reason
9281 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9282 else if (TARGET_UNALIGN_BRANCH
&& cfun
->machine
->unalign
)
9284 cfun
->machine
->size_reason
9285 = "Long unaligned jump avoids non-delay slot penalty";
9288 /* Disgorge delay insn, if there is any, and it may be moved. */
9290 /* ??? Annulled would be OK if we can and do conditionalize
9291 the delay slot insn accordingly. */
9292 && !INSN_ANNULLED_BRANCH_P (insn
)
9293 && (get_attr_cond (insn
) != COND_USE
9294 || !reg_set_p (gen_rtx_REG (CCmode
, CC_REG
),
9295 XVECEXP (final_sequence
, 0, 1))))
9297 prev
= as_a
<rtx_insn
*> (XVECEXP (final_sequence
, 0, 1));
9298 gcc_assert (!prev_real_insn (insn
)
9299 || !arc_hazard (prev_real_insn (insn
), prev
));
9300 cfun
->machine
->force_short_suffix
= !want_long
;
9301 rtx save_pred
= current_insn_predicate
;
9302 final_scan_insn (prev
, asm_out_file
, optimize
, 1, NULL
);
9303 cfun
->machine
->force_short_suffix
= -1;
9304 prev
->set_deleted ();
9305 current_output_insn
= insn
;
9306 current_insn_predicate
= save_pred
;
9309 fputs ("\tnop\n", asm_out_file
);
9312 fputs ("\tnop_s\n", asm_out_file
);
9313 cfun
->machine
->unalign
^= 2;
9319 /* The usual; we set up our machine_function data. */
9321 static struct machine_function
*
9322 arc_init_machine_status (void)
9324 struct machine_function
*machine
;
9325 machine
= ggc_cleared_alloc
<machine_function
> ();
9326 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9327 machine
->force_short_suffix
= -1;
9332 /* Implements INIT_EXPANDERS. We just set up to call the above
9336 arc_init_expanders (void)
9338 init_machine_status
= arc_init_machine_status
;
9341 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9342 indicates a number of elements to ignore - that allows to have a
9343 sibcall pattern that starts with (return). LOAD_P is zero for store
9344 multiple (for prologues), and one for load multiples (for epilogues),
9345 and two for load multiples where no final clobber of blink is required.
9346 We also skip the first load / store element since this is supposed to
9347 be checked in the instruction pattern. */
9350 arc_check_millicode (rtx op
, int offset
, int load_p
)
9352 int len
= XVECLEN (op
, 0) - offset
;
9357 if (len
< 2 || len
> 13)
9363 rtx elt
= XVECEXP (op
, 0, --len
);
9365 if (GET_CODE (elt
) != CLOBBER
9366 || !REG_P (XEXP (elt
, 0))
9367 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9368 || len
< 3 || len
> 13)
9371 for (i
= 1; i
< len
; i
++)
9373 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9376 if (GET_CODE (elt
) != SET
)
9378 mem
= XEXP (elt
, load_p
);
9379 reg
= XEXP (elt
, 1-load_p
);
9380 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9382 addr
= XEXP (mem
, 0);
9383 if (GET_CODE (addr
) != PLUS
9384 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9385 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9391 /* Accessor functions for cfun->machine->unalign. */
9394 arc_get_unalign (void)
9396 return cfun
->machine
->unalign
;
9400 arc_clear_unalign (void)
9403 cfun
->machine
->unalign
= 0;
9407 arc_toggle_unalign (void)
9409 cfun
->machine
->unalign
^= 2;
9412 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9413 constant in operand 2, but which would require a LIMM because of
9415 operands 3 and 4 are new SET_SRCs for operands 0. */
9418 split_addsi (rtx
*operands
)
9420 int val
= INTVAL (operands
[2]);
9422 /* Try for two short insns first. Lengths being equal, we prefer
9423 expansions with shorter register lifetimes. */
9424 if (val
> 127 && val
<= 255
9425 && satisfies_constraint_Rcq (operands
[0]))
9427 operands
[3] = operands
[2];
9428 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9432 operands
[3] = operands
[1];
9433 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
9437 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9438 constant in operand 1, but which would require a LIMM because of
9440 operands 3 and 4 are new SET_SRCs for operands 0. */
9443 split_subsi (rtx
*operands
)
9445 int val
= INTVAL (operands
[1]);
9447 /* Try for two short insns first. Lengths being equal, we prefer
9448 expansions with shorter register lifetimes. */
9449 if (satisfies_constraint_Rcq (operands
[0])
9450 && satisfies_constraint_Rcq (operands
[2]))
9452 if (val
>= -31 && val
<= 127)
9454 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9455 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9458 else if (val
>= 0 && val
< 255)
9460 operands
[3] = operands
[1];
9461 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9465 /* If the destination is not an ARCompact16 register, we might
9466 still have a chance to make a short insn if the source is;
9467 we need to start with a reg-reg move for this. */
9468 operands
[3] = operands
[2];
9469 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9472 /* Handle DOUBLE_REGS uses.
9473 Operand 0: destination register
9474 Operand 1: source register */
9477 arc_process_double_reg_moves (rtx
*operands
)
9479 rtx dest
= operands
[0];
9480 rtx src
= operands
[1];
9482 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9483 enum usesDxState state
= none
;
9485 if (refers_to_regno_p (40, 44, src
, 0))
9487 if (refers_to_regno_p (40, 44, dest
, 0))
9489 /* Via arc_register_move_cost, we should never see D,D moves. */
9490 gcc_assert (state
== none
);
9499 /* Without the LR insn, we need to split this into a
9500 sequence of insns which will use the DEXCLx and DADDHxy
9501 insns to be able to read the Dx register in question. */
9502 if (TARGET_DPFP_DISABLE_LRSR
)
9504 /* gen *movdf_insn_nolrsr */
9505 rtx set
= gen_rtx_SET (dest
, src
);
9506 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9507 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9511 /* When we have 'mov D, r' or 'mov D, D' then get the target
9512 register pair for use with LR insn. */
9513 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9514 TARGET_BIG_ENDIAN
? 0 : 4);
9515 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9516 TARGET_BIG_ENDIAN
? 4 : 0);
9518 /* Produce the two LR insns to get the high and low parts. */
9519 emit_insn (gen_rtx_SET (destHigh
,
9520 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9522 VUNSPEC_ARC_LR_HIGH
)));
9523 emit_insn (gen_rtx_SET (destLow
,
9524 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9529 else if (state
== destDx
)
9531 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9532 LR insn get the target register pair. */
9533 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9534 TARGET_BIG_ENDIAN
? 0 : 4);
9535 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9536 TARGET_BIG_ENDIAN
? 4 : 0);
9538 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9546 /* operands 0..1 are the operands of a 64 bit move instruction.
9547 split it into two moves with operands 2/3 and 4/5. */
9550 arc_split_move (rtx
*operands
)
9552 machine_mode mode
= GET_MODE (operands
[0]);
9559 if (arc_process_double_reg_moves (operands
))
9564 && ((memory_operand (operands
[0], mode
)
9565 && even_register_operand (operands
[1], mode
))
9566 || (memory_operand (operands
[1], mode
)
9567 && even_register_operand (operands
[0], mode
))))
9569 emit_move_insn (operands
[0], operands
[1]);
9573 if (TARGET_PLUS_QMACW
9574 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9576 HOST_WIDE_INT intval0
, intval1
;
9577 if (GET_MODE (operands
[1]) == V2SImode
)
9579 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9580 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9584 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9585 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9586 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9587 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9589 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9590 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9591 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9592 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9593 emit_move_insn (xop
[0], xop
[2]);
9594 emit_move_insn (xop
[3], xop
[1]);
9598 for (i
= 0; i
< 2; i
++)
9600 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9602 rtx addr
= XEXP (operands
[i
], 0);
9606 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9607 switch (GET_CODE (addr
))
9609 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9610 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9611 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9615 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9616 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9617 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9626 xop
[0+i
] = adjust_automodify_address_nv
9627 (operands
[i
], SImode
,
9628 gen_rtx_fmt_ee (code
, Pmode
, r
,
9629 gen_rtx_PLUS (Pmode
, r
, o
)),
9631 xop
[2+i
] = adjust_automodify_address_nv
9632 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9636 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9637 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9640 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9643 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9646 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9647 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9651 /* Select between the instruction output templates s_tmpl (for short INSNs)
9652 and l_tmpl (for long INSNs). */
9655 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9657 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9659 extract_constrain_insn_cached (insn
);
9660 return is_short
? s_tmpl
: l_tmpl
;
9663 /* Searches X for any reference to REGNO, returning the rtx of the
9664 reference found if any. Otherwise, returns NULL_RTX. */
9667 arc_regno_use_in (unsigned int regno
, rtx x
)
9673 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9676 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9677 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9681 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9684 else if (fmt
[i
] == 'E')
9685 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9686 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9693 /* Return the integer value of the "type" attribute for INSN, or -1 if
9694 INSN can't have attributes. */
9697 arc_attr_type (rtx_insn
*insn
)
9699 if (NONJUMP_INSN_P (insn
)
9700 ? (GET_CODE (PATTERN (insn
)) == USE
9701 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9703 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9704 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9707 return get_attr_type (insn
);
9710 /* Return true if insn sets the condition codes. */
9713 arc_sets_cc_p (rtx_insn
*insn
)
9715 if (NONJUMP_INSN_P (insn
))
9716 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9717 insn
= seq
->insn (seq
->len () - 1);
9718 return arc_attr_type (insn
) == TYPE_COMPARE
;
9721 /* Return true if INSN is an instruction with a delay slot we may want
9725 arc_need_delay (rtx_insn
*insn
)
9729 if (!flag_delayed_branch
)
9731 /* The return at the end of a function needs a delay slot. */
9732 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9733 && (!(next
= next_active_insn (insn
))
9734 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9735 && arc_attr_type (next
) == TYPE_RETURN
))
9736 && (!TARGET_PAD_RETURN
9737 || (prev_active_insn (insn
)
9738 && prev_active_insn (prev_active_insn (insn
))
9739 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9741 if (NONJUMP_INSN_P (insn
)
9742 ? (GET_CODE (PATTERN (insn
)) == USE
9743 || GET_CODE (PATTERN (insn
)) == CLOBBER
9744 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9746 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9747 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9750 return num_delay_slots (insn
) != 0;
9753 /* Return true if the scheduling pass(es) has/have already run,
9754 i.e. where possible, we should try to mitigate high latencies
9755 by different instruction selection. */
9758 arc_scheduling_not_expected (void)
9760 return cfun
->machine
->arc_reorg_started
;
9763 /* Oddly enough, sometimes we get a zero overhead loop that branch
9764 shortening doesn't think is a loop - observed with compile/pr24883.c
9765 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9766 alignment visible for branch shortening (we actually align the loop
9767 insn before it, but that is equivalent since the loop insn is 4 byte
9771 arc_label_align (rtx_insn
*label
)
9773 int loop_align
= LOOP_ALIGN (LABEL
);
9775 if (loop_align
> align_labels_log
)
9777 rtx_insn
*prev
= prev_nonnote_insn (label
);
9779 if (prev
&& NONJUMP_INSN_P (prev
)
9780 && GET_CODE (PATTERN (prev
)) == PARALLEL
9781 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
)
9784 /* Code has a minimum p2 alignment of 1, which we must restore after an
9786 if (align_labels_log
< 1)
9788 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9789 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9792 return align_labels_log
;
9795 /* Return true if LABEL is in executable code. */
9798 arc_text_label (rtx_insn
*label
)
9802 /* ??? We use deleted labels like they were still there, see
9803 gcc.c-torture/compile/20000326-2.c . */
9804 gcc_assert (GET_CODE (label
) == CODE_LABEL
9805 || (GET_CODE (label
) == NOTE
9806 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9807 next
= next_nonnote_insn (label
);
9809 return (!JUMP_TABLE_DATA_P (next
)
9810 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9811 else if (!PREV_INSN (label
))
9812 /* ??? sometimes text labels get inserted very late, see
9813 gcc.dg/torture/stackalign/comp-goto-1.c */
9818 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9819 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9820 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9821 to redirect two breqs. */
9824 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9826 /* ??? get_attr_type is declared to take an rtx. */
9827 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9830 if (CROSSING_JUMP_P (followee
))
9831 switch (get_attr_type (u
.r
))
9834 case TYPE_BRCC_NO_DELAY_SLOT
:
9842 /* Return the register number of the register holding the return address
9843 for a function of type TYPE. */
9846 arc_return_address_register (unsigned int fn_type
)
9850 if (ARC_INTERRUPT_P (fn_type
))
9852 if (((fn_type
& ARC_FUNCTION_ILINK1
) | ARC_FUNCTION_FIRQ
) != 0)
9853 regno
= ILINK1_REGNUM
;
9854 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
9855 regno
= ILINK2_REGNUM
;
9859 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
9860 regno
= RETURN_ADDR_REGNUM
;
9862 gcc_assert (regno
!= 0);
9866 /* Implement EPILOGUE_USES.
9867 Return true if REGNO should be added to the deemed uses of the epilogue.
9869 We have to make sure all the register restore instructions are
9870 known to be live in interrupt functions, plus the blink register if
9871 it is clobbered by the isr. */
9874 arc_epilogue_uses (int regno
)
9876 unsigned int fn_type
;
9878 if (regno
== arc_tp_regno
)
9881 fn_type
= arc_compute_function_type (cfun
);
9882 if (reload_completed
)
9884 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9886 if (!fixed_regs
[regno
])
9888 return ((regno
== arc_return_address_register (fn_type
))
9889 || (regno
== RETURN_ADDR_REGNUM
));
9892 return regno
== RETURN_ADDR_REGNUM
;
9895 return regno
== arc_return_address_register (fn_type
);
9898 /* Helper for EH_USES macro. */
9901 arc_eh_uses (int regno
)
9903 if (regno
== arc_tp_regno
)
9908 #ifndef TARGET_NO_LRA
9909 #define TARGET_NO_LRA !TARGET_LRA
9915 return !TARGET_NO_LRA
;
9918 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9919 Rcq registers, because some insn are shorter with them. OTOH we already
9920 have separate alternatives for this purpose, and other insns don't
9921 mind, so maybe we should rather prefer the other registers?
9922 We need more data, and we can only get that if we allow people to
9925 arc_register_priority (int r
)
9927 switch (arc_lra_priority_tag
)
9929 case ARC_LRA_PRIORITY_NONE
:
9931 case ARC_LRA_PRIORITY_NONCOMPACT
:
9932 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
9933 case ARC_LRA_PRIORITY_COMPACT
:
9934 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
9941 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
9943 return GENERAL_REGS
;
9947 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
9951 enum reload_type type
= (enum reload_type
) itype
;
9953 if (GET_CODE (x
) == PLUS
9954 && CONST_INT_P (XEXP (x
, 1))
9955 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
9956 || (REG_P (XEXP (x
, 0))
9957 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
9959 int scale
= GET_MODE_SIZE (mode
);
9961 rtx index_rtx
= XEXP (x
, 1);
9962 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
9967 if ((scale
-1) & offset
)
9971 = ((offset
+ (256 << shift
))
9972 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
9973 /* Sometimes the normal form does not suit DImode. We
9974 could avoid that by using smaller ranges, but that
9975 would give less optimized code when SImode is
9977 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
9982 regno
= REGNO (reg
);
9983 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
9985 if (reg_equiv_constant (regno
))
9987 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
9989 if (GET_CODE (sum2
) == PLUS
)
9990 sum2
= gen_rtx_CONST (Pmode
, sum2
);
9992 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
9993 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
9994 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
9999 /* We must re-recognize what we created before. */
10000 else if (GET_CODE (x
) == PLUS
10001 && GET_CODE (XEXP (x
, 0)) == PLUS
10002 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
10003 && REG_P (XEXP (XEXP (x
, 0), 0))
10004 && CONST_INT_P (XEXP (x
, 1)))
10006 /* Because this address is so complex, we know it must have
10007 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10008 it is already unshared, and needs no further unsharing. */
10009 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
10010 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
10016 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10019 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
10020 unsigned int align
,
10021 enum by_pieces_operation op
,
10024 /* Let the movmem expander handle small block moves. */
10025 if (op
== MOVE_BY_PIECES
)
10028 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
10031 /* Emit a (pre) memory barrier around an atomic sequence according to
10035 arc_pre_atomic_barrier (enum memmodel model
)
10037 if (need_atomic_barrier_p (model
, true))
10038 emit_insn (gen_memory_barrier ());
10041 /* Emit a (post) memory barrier around an atomic sequence according to
10045 arc_post_atomic_barrier (enum memmodel model
)
10047 if (need_atomic_barrier_p (model
, false))
10048 emit_insn (gen_memory_barrier ());
10051 /* Expand a compare and swap pattern. */
10054 emit_unlikely_jump (rtx insn
)
10056 rtx_insn
*jump
= emit_jump_insn (insn
);
10057 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10060 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10061 32-bit compare and swap on the word containing the byte or
10062 half-word. The difference between a weak and a strong CAS is that
10063 the weak version may simply fail. The strong version relies on two
10064 loops, one checks if the SCOND op is succsfully or not, the other
10065 checks if the 32 bit accessed location which contains the 8 or 16
10066 bit datum is not changed by other thread. The first loop is
10067 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10068 loops is implemented by this routine. */
10071 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10072 rtx oldval
, rtx newval
, rtx weak
,
10073 rtx mod_s
, rtx mod_f
)
10075 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10076 rtx addr
= gen_reg_rtx (Pmode
);
10077 rtx off
= gen_reg_rtx (SImode
);
10078 rtx oldv
= gen_reg_rtx (SImode
);
10079 rtx newv
= gen_reg_rtx (SImode
);
10080 rtx oldvalue
= gen_reg_rtx (SImode
);
10081 rtx newvalue
= gen_reg_rtx (SImode
);
10082 rtx res
= gen_reg_rtx (SImode
);
10083 rtx resv
= gen_reg_rtx (SImode
);
10084 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10086 bool is_weak
= (weak
!= const0_rtx
);
10088 /* Truncate the address. */
10089 emit_insn (gen_rtx_SET (addr
,
10090 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10092 /* Compute the datum offset. */
10093 emit_insn (gen_rtx_SET (off
,
10094 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10095 if (TARGET_BIG_ENDIAN
)
10096 emit_insn (gen_rtx_SET (off
,
10097 gen_rtx_MINUS (SImode
,
10098 (GET_MODE (mem
) == QImode
) ?
10099 GEN_INT (3) : GEN_INT (2), off
)));
10101 /* Normal read from truncated address. */
10102 memsi
= gen_rtx_MEM (SImode
, addr
);
10103 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10104 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10106 val
= copy_to_reg (memsi
);
10108 /* Convert the offset in bits. */
10109 emit_insn (gen_rtx_SET (off
,
10110 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10112 /* Get the proper mask. */
10113 if (GET_MODE (mem
) == QImode
)
10114 mask
= force_reg (SImode
, GEN_INT (0xff));
10116 mask
= force_reg (SImode
, GEN_INT (0xffff));
10118 emit_insn (gen_rtx_SET (mask
,
10119 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10121 /* Prepare the old and new values. */
10122 emit_insn (gen_rtx_SET (val
,
10123 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10126 oldval
= gen_lowpart (SImode
, oldval
);
10127 emit_insn (gen_rtx_SET (oldv
,
10128 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10130 newval
= gen_lowpart_common (SImode
, newval
);
10131 emit_insn (gen_rtx_SET (newv
,
10132 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10134 emit_insn (gen_rtx_SET (oldv
,
10135 gen_rtx_AND (SImode
, oldv
, mask
)));
10137 emit_insn (gen_rtx_SET (newv
,
10138 gen_rtx_AND (SImode
, newv
, mask
)));
10142 end_label
= gen_label_rtx ();
10143 loop_label
= gen_label_rtx ();
10144 emit_label (loop_label
);
10147 /* Make the old and new values. */
10148 emit_insn (gen_rtx_SET (oldvalue
,
10149 gen_rtx_IOR (SImode
, oldv
, val
)));
10151 emit_insn (gen_rtx_SET (newvalue
,
10152 gen_rtx_IOR (SImode
, newv
, val
)));
10154 /* Try an 32bit atomic compare and swap. It clobbers the CC
10156 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10157 weak
, mod_s
, mod_f
));
10159 /* Regardless of the weakness of the operation, a proper boolean
10160 result needs to be provided. */
10161 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10162 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10163 emit_insn (gen_rtx_SET (bool_result
, x
));
10167 /* Check the results: if the atomic op is successfully the goto
10169 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10170 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10171 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10172 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10173 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10175 /* Wait for the right moment when the accessed 32-bit location
10177 emit_insn (gen_rtx_SET (resv
,
10178 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10180 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10181 cc
= gen_rtx_REG (mode
, CC_REG
);
10182 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10184 /* Set the new value of the 32 bit location, proper masked. */
10185 emit_insn (gen_rtx_SET (val
, resv
));
10187 /* Try again if location is unstable. Fall through if only
10188 scond op failed. */
10189 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10190 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10191 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10192 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10194 emit_label (end_label
);
10197 /* End: proper return the result for the given mode. */
10198 emit_insn (gen_rtx_SET (res
,
10199 gen_rtx_AND (SImode
, res
, mask
)));
10201 emit_insn (gen_rtx_SET (res
,
10202 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10204 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10207 /* Helper function used by "atomic_compare_and_swap" expand
10211 arc_expand_compare_and_swap (rtx operands
[])
10213 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10216 bval
= operands
[0];
10217 rval
= operands
[1];
10219 oldval
= operands
[3];
10220 newval
= operands
[4];
10221 is_weak
= operands
[5];
10222 mod_s
= operands
[6];
10223 mod_f
= operands
[7];
10224 mode
= GET_MODE (mem
);
10226 if (reg_overlap_mentioned_p (rval
, oldval
))
10227 oldval
= copy_to_reg (oldval
);
10229 if (mode
== SImode
)
10231 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10232 is_weak
, mod_s
, mod_f
));
10233 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10234 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10235 emit_insn (gen_rtx_SET (bval
, x
));
10239 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10240 is_weak
, mod_s
, mod_f
);
10244 /* Helper function used by the "atomic_compare_and_swapsi_1"
10248 arc_split_compare_and_swap (rtx operands
[])
10250 rtx rval
, mem
, oldval
, newval
;
10252 enum memmodel mod_s
, mod_f
;
10254 rtx label1
, label2
, x
, cond
;
10256 rval
= operands
[0];
10258 oldval
= operands
[2];
10259 newval
= operands
[3];
10260 is_weak
= (operands
[4] != const0_rtx
);
10261 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10262 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10263 mode
= GET_MODE (mem
);
10265 /* ARC atomic ops work only with 32-bit aligned memories. */
10266 gcc_assert (mode
== SImode
);
10268 arc_pre_atomic_barrier (mod_s
);
10273 label1
= gen_label_rtx ();
10274 emit_label (label1
);
10276 label2
= gen_label_rtx ();
10278 /* Load exclusive. */
10279 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10281 /* Check if it is oldval. */
10282 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10283 cond
= gen_rtx_REG (mode
, CC_REG
);
10284 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10286 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10287 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10288 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10289 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10291 /* Exclusively store new item. Store clobbers CC reg. */
10292 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10296 /* Check the result of the store. */
10297 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10298 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10299 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10300 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10301 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10304 if (mod_f
!= MEMMODEL_RELAXED
)
10305 emit_label (label2
);
10307 arc_post_atomic_barrier (mod_s
);
10309 if (mod_f
== MEMMODEL_RELAXED
)
10310 emit_label (label2
);
10313 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10314 to perform. MEM is the memory on which to operate. VAL is the second
10315 operand of the binary operator. BEFORE and AFTER are optional locations to
10316 return the value of MEM either before of after the operation. MODEL_RTX
10317 is a CONST_INT containing the memory model to use. */
10320 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10321 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10323 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10324 machine_mode mode
= GET_MODE (mem
);
10325 rtx label
, x
, cond
;
10326 rtx before
= orig_before
, after
= orig_after
;
10328 /* ARC atomic ops work only with 32-bit aligned memories. */
10329 gcc_assert (mode
== SImode
);
10331 arc_pre_atomic_barrier (model
);
10333 label
= gen_label_rtx ();
10334 emit_label (label
);
10335 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10337 if (before
== NULL_RTX
)
10338 before
= gen_reg_rtx (mode
);
10340 if (after
== NULL_RTX
)
10341 after
= gen_reg_rtx (mode
);
10343 /* Load exclusive. */
10344 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10349 x
= gen_rtx_AND (mode
, before
, val
);
10350 emit_insn (gen_rtx_SET (after
, x
));
10351 x
= gen_rtx_NOT (mode
, after
);
10352 emit_insn (gen_rtx_SET (after
, x
));
10356 if (CONST_INT_P (val
))
10358 val
= GEN_INT (-INTVAL (val
));
10364 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10365 emit_insn (gen_rtx_SET (after
, x
));
10369 /* Exclusively store new item. Store clobbers CC reg. */
10370 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10372 /* Check the result of the store. */
10373 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10374 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10375 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10377 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10379 arc_post_atomic_barrier (model
);
10382 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10385 arc_no_speculation_in_delay_slots_p ()
10390 /* Return a parallel of registers to represent where to find the
10391 register pieces if required, otherwise NULL_RTX. */
10394 arc_dwarf_register_span (rtx rtl
)
10396 machine_mode mode
= GET_MODE (rtl
);
10400 if (GET_MODE_SIZE (mode
) != 8)
10403 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10404 regno
= REGNO (rtl
);
10405 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10406 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10411 /* Return true if OP is an acceptable memory operand for ARCompact
10412 16-bit load instructions of MODE.
10414 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10415 non scaled instructions.
10417 SCALED: TRUE if address can be scaled. */
10420 compact_memory_operand_p (rtx op
, machine_mode mode
,
10421 bool av2short
, bool scaled
)
10423 rtx addr
, plus0
, plus1
;
10426 /* Eliminate non-memory operations. */
10427 if (GET_CODE (op
) != MEM
)
10430 /* .di instructions have no 16-bit form. */
10431 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10434 if (mode
== VOIDmode
)
10435 mode
= GET_MODE (op
);
10437 size
= GET_MODE_SIZE (mode
);
10439 /* dword operations really put out 2 instructions, so eliminate
10441 if (size
> UNITS_PER_WORD
)
10444 /* Decode the address now. */
10445 addr
= XEXP (op
, 0);
10446 switch (GET_CODE (addr
))
10449 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10450 || COMPACT_GP_REG_P (REGNO (addr
))
10451 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10453 plus0
= XEXP (addr
, 0);
10454 plus1
= XEXP (addr
, 1);
10456 if ((GET_CODE (plus0
) == REG
)
10457 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10458 || COMPACT_GP_REG_P (REGNO (plus0
)))
10459 && ((GET_CODE (plus1
) == REG
)
10460 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10461 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10466 if ((GET_CODE (plus0
) == REG
)
10467 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10468 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10469 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10470 && (GET_CODE (plus1
) == CONST_INT
))
10472 bool valid
= false;
10474 off
= INTVAL (plus1
);
10476 /* Negative offset is not supported in 16-bit load/store insns. */
10480 /* Only u5 immediates allowed in code density instructions. */
10488 /* This is an ldh_s.x instruction, check the u6
10490 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10494 /* Only u5 immediates allowed in 32bit access code
10495 density instructions. */
10496 if (REGNO (plus0
) <= 31)
10497 return ((off
< 32) && (off
% 4 == 0));
10504 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10515 /* The 6-bit constant get shifted to fit the real
10516 5-bits field. Check also for the alignment. */
10517 return ((off
< 64) && (off
% 2 == 0));
10519 return ((off
< 128) && (off
% 4 == 0));
10526 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10527 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10528 || SP_REG_P (REGNO (plus0
)))
10531 off
= INTVAL (plus1
);
10532 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10535 if ((GET_CODE (plus0
) == MULT
)
10536 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10537 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10538 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10539 && (GET_CODE (plus1
) == REG
)
10540 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10541 || COMPACT_GP_REG_P (REGNO (plus1
))))
10545 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10546 for 16-bit load instructions. */
10551 struct gcc_target targetm
= TARGET_INITIALIZER
;
10553 #include "gt-arc.h"