1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2024 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
31 #define IN_TARGET_CODE 1
35 #include "coretypes.h"
44 #include "stringpool.h"
50 #include "diagnostic.h"
51 #include "fold-const.h"
53 #include "stor-layout.h"
56 #include "insn-attr.h"
60 #include "langhooks.h"
61 #include "tm-constrs.h"
62 #include "reload.h" /* For operands_match_p */
64 #include "tree-pass.h"
70 #include "hw-doloop.h"
71 #include "targhooks.h"
72 #include "case-cfn-macros.h"
74 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
75 static char arc_cpu_name
[10] = "";
76 static const char *arc_cpu_string
= arc_cpu_name
;
78 typedef struct GTY (()) _arc_jli_section
81 struct _arc_jli_section
*next
;
84 static arc_jli_section
*arc_jli_sections
= NULL
;
86 /* Track which regs are set fixed/call saved/call used from commnad line. */
87 HARD_REG_SET overrideregs
;
89 /* Maximum size of a loop. */
90 #define ARC_MAX_LOOP_LENGTH 4095
92 /* Check if an rtx fits in the store instruction format. Loads can
93 handle any constant. */
94 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
95 (GET_CODE (X) == CONST_INT \
96 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & (~0x03), \
97 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
99 : -(-GET_MODE_SIZE (MODE) | (~0x03)) >> 1)))
101 /* Array of valid operand punctuation characters. */
102 char arc_punct_chars
[256];
104 /* Status of the IRQ_CTRL_AUX register. */
105 typedef struct irq_ctrl_saved_t
107 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
108 short irq_save_last_reg
;
109 /* True if BLINK is automatically saved. */
111 /* True if LPCOUNT is automatically saved. */
112 bool irq_save_lpcount
;
114 static irq_ctrl_saved_t irq_ctrl_saved
;
116 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
117 ((ARC_INTERRUPT_P (FNTYPE) \
118 && irq_ctrl_saved.irq_save_blink) \
119 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
120 && rgf_banked_register_count > 8))
122 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
123 ((ARC_INTERRUPT_P (FNTYPE) \
124 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
125 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
126 && rgf_banked_register_count > 8))
128 #define ARC_AUTO_IRQ_P(FNTYPE) \
129 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
130 && (irq_ctrl_saved.irq_save_blink \
131 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
133 /* Number of registers in second bank for FIRQ support. */
134 static int rgf_banked_register_count
;
136 /* Start enter/leave register range. */
137 #define ENTER_LEAVE_START_REG 13
139 /* End enter/leave register range. */
140 #define ENTER_LEAVE_END_REG 26
142 /* The maximum number of insns skipped which will be conditionalised if
144 /* When optimizing for speed:
145 Let p be the probability that the potentially skipped insns need to
146 be executed, pn the cost of a correctly predicted non-taken branch,
147 mt the cost of a mis/non-predicted taken branch,
148 mn mispredicted non-taken, pt correctly predicted taken ;
149 costs expressed in numbers of instructions like the ones considered
151 Unfortunately we don't have a measure of predictability - this
152 is linked to probability only in that in the no-eviction-scenario
153 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
154 value that can be assumed *if* the distribution is perfectly random.
155 A predictability of 1 is perfectly plausible not matter what p is,
156 because the decision could be dependent on an invocation parameter
158 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
159 For small p, we want MAX_INSNS_SKIPPED == pt
161 When optimizing for size:
162 We want to skip insn unless we could use 16 opcodes for the
163 non-conditionalized insn to balance the branch length or more.
164 Performance can be tie-breaker. */
165 /* If the potentially-skipped insns are likely to be executed, we'll
166 generally save one non-taken branch
168 this to be no less than the 1/p */
169 #define MAX_INSNS_SKIPPED 3
171 /* ZOL control registers. */
172 #define AUX_LP_START 0x02
173 #define AUX_LP_END 0x03
175 /* FPX AUX registers. */
176 #define AUX_DPFP_START 0x301
178 /* ARC600 MULHI register. */
179 #define AUX_MULHI 0x12
181 static int get_arc_condition_code (rtx
);
183 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
184 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
185 static tree
arc_handle_jli_attribute (tree
*, tree
, tree
, int, bool *);
186 static tree
arc_handle_secure_attribute (tree
*, tree
, tree
, int, bool *);
187 static tree
arc_handle_uncached_attribute (tree
*, tree
, tree
, int, bool *);
188 static tree
arc_handle_aux_attribute (tree
*, tree
, tree
, int, bool *);
190 static int arc_comp_type_attributes (const_tree
, const_tree
);
191 static void arc_file_start (void);
192 static void arc_internal_label (FILE *, const char *, unsigned long);
193 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
195 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
196 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
198 static void arc_init_builtins (void);
199 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
201 static int branch_dest (rtx
);
203 static void arc_output_pic_addr_const (FILE *, rtx
, int);
204 static bool arc_function_ok_for_sibcall (tree
, tree
);
205 static rtx
arc_function_value (const_tree
, const_tree
, bool);
206 static void arc_reorg (void);
207 static bool arc_in_small_data_p (const_tree
);
209 static void arc_init_reg_tables (void);
210 static bool arc_return_in_memory (const_tree
, const_tree
);
211 static bool arc_vector_mode_supported_p (machine_mode
);
213 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
215 static const char *arc_invalid_within_doloop (const rtx_insn
*);
217 static void output_short_suffix (FILE *file
);
219 static bool arc_frame_pointer_required (void);
221 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
223 enum by_pieces_operation op
,
226 /* Globally visible information about currently selected cpu. */
227 const arc_cpu_t
*arc_selected_cpu
;
229 /* Traditionally, we push saved registers first in the prologue,
230 then we allocate the rest of the frame - and reverse in the epilogue.
231 This has still its merits for ease of debugging, or saving code size
232 or even execution time if the stack frame is so large that some accesses
233 can't be encoded anymore with offsets in the instruction code when using
235 Also, it would be a good starting point if we got instructions to help
236 with register save/restore.
238 However, often stack frames are small, and the pushing / popping has
240 - the stack modification prevents a lot of scheduling.
241 - frame allocation / deallocation may need extra instructions.
242 - we need to place a memory barrier after frame allocation to avoid
243 the delay slot scheduler to reschedule a frame related info and
244 messing up with dwarf unwinding. The barrier before deallocation
245 is for flushing all pending sp operations.
247 Thus, for small frames, we'd like to use a different scheme:
248 - The frame is allocated in full with the first prologue instruction,
249 and deallocated in full with the last epilogue instruction.
250 Thus, the instructions in-between can be freely scheduled.
251 - If the function has no outgoing arguments on the stack, we can allocate
252 one register save slot at the top of the stack. This register can then
253 be saved simultaneously with frame allocation, and restored with
255 This register can be picked depending on scheduling considerations,
256 although same though should go into having some set of registers
257 to be potentially lingering after a call, and others to be available
258 immediately - i.e. in the absence of interprocedual optimization, we
259 can use an ABI-like convention for register allocation to reduce
260 stalls after function return. */
262 /* ARCompact stack frames look like:
264 Before call After call
265 high +-----------------------+ +-----------------------+
266 mem | reg parm save area | | reg parm save area |
267 | only created for | | only created for |
268 | variable arg fns | | variable arg fns |
269 AP +-----------------------+ +-----------------------+
270 | return addr register | | return addr register |
271 | (if required) | | (if required) |
272 +-----------------------+ +-----------------------+
274 | reg save area | | reg save area |
276 +-----------------------+ +-----------------------+
277 | frame pointer | | frame pointer |
278 | (if required) | | (if required) |
279 FP +-----------------------+ +-----------------------+
281 | local/temp variables | | local/temp variables |
283 +-----------------------+ +-----------------------+
285 | arguments on stack | | arguments on stack |
287 SP +-----------------------+ +-----------------------+
288 | reg parm save area |
291 AP +-----------------------+
292 | return addr register |
294 +-----------------------+
298 +-----------------------+
301 FP +-----------------------+
303 | local/temp variables |
305 +-----------------------+
307 | arguments on stack |
309 mem SP +-----------------------+
312 1) The "reg parm save area" does not exist for non variable argument fns.
313 The "reg parm save area" can be eliminated completely if we created our
314 own va-arc.h, but that has tradeoffs as well (so it's not done). */
316 /* Structure to be filled in by arc_compute_frame_size with register
317 save masks, and offsets for the current function. */
318 struct GTY (()) arc_frame_info
320 unsigned int total_size
; /* # bytes that the entire frame takes up. */
321 unsigned int extra_size
; /* # bytes of extra stuff. */
322 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
323 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
324 unsigned int reg_size
; /* # bytes needed to store regs. */
325 unsigned int var_size
; /* # bytes that variables take up. */
326 uint64_t gmask
; /* Mask of saved gp registers. */
327 bool initialized
; /* FALSE if frame size already calculated. */
328 short millicode_start_reg
;
329 short millicode_end_reg
;
330 bool save_return_addr
;
333 /* GMASK bit length -1. */
336 /* Defining data structures for per-function information. */
338 typedef struct GTY (()) machine_function
340 unsigned int fn_type
;
341 struct arc_frame_info frame_info
;
342 char arc_reorg_started
;
343 char prescan_initialized
;
347 /* Given a symbol RTX (const (symb <+ const_int>), returns its
351 get_symbol_alignment (rtx x
)
353 tree decl
= NULL_TREE
;
356 switch (GET_CODE (x
))
359 decl
= SYMBOL_REF_DECL (x
);
362 return get_symbol_alignment (XEXP (x
, 0));
364 gcc_assert (CONST_INT_P (XEXP (x
, 1)));
365 return get_symbol_alignment (XEXP (x
, 0));
371 align
= DECL_ALIGN (decl
);
372 align
= align
/ BITS_PER_UNIT
;
376 /* Return true if x is ok to be used as a small data address. */
379 legitimate_small_data_address_p (rtx x
, machine_mode mode
)
381 switch (GET_CODE (x
))
384 return legitimate_small_data_address_p (XEXP (x
, 0), mode
);
386 return SYMBOL_REF_SMALL_P (x
);
389 bool p0
= (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
)
390 && SYMBOL_REF_SMALL_P (XEXP (x
, 0));
392 /* If no constant then we cannot do small data. */
393 if (!CONST_INT_P (XEXP (x
, 1)))
396 /* Small data relocs works with scalled addresses, check if
397 the immediate fits the requirements. */
398 switch (GET_MODE_SIZE (mode
))
403 return p0
&& ((INTVAL (XEXP (x
, 1)) & 0x1) == 0);
406 return p0
&& ((INTVAL (XEXP (x
, 1)) & 0x3) == 0);
416 /* TRUE if op is an scaled address. */
418 legitimate_scaled_address_p (machine_mode mode
, rtx op
, bool strict
)
420 if (GET_CODE (op
) != PLUS
)
423 if (GET_CODE (XEXP (op
, 0)) != MULT
)
426 /* Check multiplication operands. */
427 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op
, 0), 0), strict
))
430 if (!CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
433 switch (GET_MODE_SIZE (mode
))
436 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 2)
444 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 4)
451 /* Check the base. */
452 if (RTX_OK_FOR_BASE_P (XEXP (op
, 1), (strict
)))
457 if (CONST_INT_P (XEXP (op
, 1)))
462 /* Scalled addresses for sdata is done other places. */
463 if (legitimate_small_data_address_p (op
, mode
))
466 if (CONSTANT_P (XEXP (op
, 1)))
472 /* Check for constructions like REG + OFFS, where OFFS can be a
473 register, an immediate or an long immediate. */
476 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
478 if (GET_CODE (x
) != PLUS
)
481 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
484 /* Check for: [Rx + small offset] or [Rx + Ry]. */
485 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
486 && GET_MODE_SIZE ((mode
)) <= 4)
487 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
490 /* Check for [Rx + symbol]. */
492 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
493 /* Avoid this type of address for double or larger modes. */
494 && (GET_MODE_SIZE (mode
) <= 4)
495 /* Avoid small data which ends in something like GP +
497 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))))
503 /* Implements target hook vector_mode_supported_p. */
506 arc_vector_mode_supported_p (machine_mode mode
)
511 return TARGET_PLUS_DMPY
;
514 return TARGET_PLUS_QMACW
;
517 return TARGET_SIMD_SET
;
524 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
527 arc_preferred_simd_mode (scalar_mode mode
)
532 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
541 /* Implements target hook
542 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
545 arc_autovectorize_vector_modes (vector_modes
*modes
, bool)
547 if (TARGET_PLUS_QMACW
)
549 modes
->quick_push (V4HImode
);
550 modes
->quick_push (V2HImode
);
556 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
558 arc_sched_issue_rate (void)
562 case ARC_TUNE_ARCHS4X
:
563 case ARC_TUNE_ARCHS4XD
:
571 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
572 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
573 static rtx
arc_delegitimize_address (rtx
);
574 static bool arc_can_follow_jump (const rtx_insn
*follower
,
575 const rtx_insn
*followee
);
577 static rtx
frame_insn (rtx
);
578 static void arc_function_arg_advance (cumulative_args_t
,
579 const function_arg_info
&);
580 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
582 /* initialize the GCC target structure. */
583 #undef TARGET_COMP_TYPE_ATTRIBUTES
584 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
585 #undef TARGET_ASM_FILE_START
586 #define TARGET_ASM_FILE_START arc_file_start
587 #undef TARGET_ATTRIBUTE_TABLE
588 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
589 #undef TARGET_ASM_INTERNAL_LABEL
590 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
591 #undef TARGET_RTX_COSTS
592 #define TARGET_RTX_COSTS arc_rtx_costs
593 #undef TARGET_ADDRESS_COST
594 #define TARGET_ADDRESS_COST arc_address_cost
596 #undef TARGET_ENCODE_SECTION_INFO
597 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
599 #undef TARGET_CANNOT_FORCE_CONST_MEM
600 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
602 #undef TARGET_INIT_BUILTINS
603 #define TARGET_INIT_BUILTINS arc_init_builtins
605 #undef TARGET_EXPAND_BUILTIN
606 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
608 #undef TARGET_FOLD_BUILTIN
609 #define TARGET_FOLD_BUILTIN arc_fold_builtin
611 #undef TARGET_BUILTIN_DECL
612 #define TARGET_BUILTIN_DECL arc_builtin_decl
614 #undef TARGET_ASM_OUTPUT_MI_THUNK
615 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
617 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
618 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
620 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
621 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
623 #undef TARGET_MACHINE_DEPENDENT_REORG
624 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
626 #undef TARGET_IN_SMALL_DATA_P
627 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
629 #undef TARGET_PROMOTE_FUNCTION_MODE
630 #define TARGET_PROMOTE_FUNCTION_MODE \
631 default_promote_function_mode_always_promote
633 #undef TARGET_PROMOTE_PROTOTYPES
634 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
636 #undef TARGET_RETURN_IN_MEMORY
637 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
638 #undef TARGET_PASS_BY_REFERENCE
639 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
641 #undef TARGET_SETUP_INCOMING_VARARGS
642 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
644 #undef TARGET_ARG_PARTIAL_BYTES
645 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
647 #undef TARGET_MUST_PASS_IN_STACK
648 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
650 #undef TARGET_FUNCTION_VALUE
651 #define TARGET_FUNCTION_VALUE arc_function_value
653 #undef TARGET_SCHED_ADJUST_PRIORITY
654 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
656 #undef TARGET_SCHED_ISSUE_RATE
657 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
659 #undef TARGET_VECTOR_MODE_SUPPORTED_P
660 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
662 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
663 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
665 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
666 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES arc_autovectorize_vector_modes
668 #undef TARGET_CAN_USE_DOLOOP_P
669 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
671 #undef TARGET_INVALID_WITHIN_DOLOOP
672 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
674 #undef TARGET_PRESERVE_RELOAD_P
675 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
677 #undef TARGET_CAN_FOLLOW_JUMP
678 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
680 #undef TARGET_DELEGITIMIZE_ADDRESS
681 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
683 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
684 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
685 arc_use_by_pieces_infrastructure_p
687 /* Usually, we will be able to scale anchor offsets.
688 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
689 #undef TARGET_MIN_ANCHOR_OFFSET
690 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
691 #undef TARGET_MAX_ANCHOR_OFFSET
692 #define TARGET_MAX_ANCHOR_OFFSET (1020)
694 #undef TARGET_SECONDARY_RELOAD
695 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
697 #define TARGET_OPTION_OVERRIDE arc_override_options
699 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
701 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
703 #define TARGET_CAN_ELIMINATE arc_can_eliminate
705 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
707 #define TARGET_FUNCTION_ARG arc_function_arg
709 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
711 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
713 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
715 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
717 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
719 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
720 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
721 arc_no_speculation_in_delay_slots_p
724 #define TARGET_LRA_P arc_lra_p
725 #define TARGET_REGISTER_PRIORITY arc_register_priority
726 /* Stores with scaled offsets have different displacement ranges. */
727 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
728 #define TARGET_SPILL_CLASS arc_spill_class
730 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
731 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
733 #undef TARGET_WARN_FUNC_RETURN
734 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
736 #include "target-def.h"
738 TARGET_GNU_ATTRIBUTES (arc_attribute_table
,
740 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
741 affects_type_identity, handler, exclude } */
742 { "interrupt", 1, 1, true, false, false, true,
743 arc_handle_interrupt_attribute
, NULL
},
744 /* Function calls made to this symbol must be done indirectly, because
745 it may lie outside of the 21/25 bit addressing range of a normal function
747 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
748 /* Whereas these functions are always known to reside within the 25 bit
749 addressing range of unconditionalized bl. */
750 { "medium_call", 0, 0, false, true, true, false, NULL
, NULL
},
751 /* And these functions are always known to reside within the 21 bit
752 addressing range of blcc. */
753 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
754 /* Function which are not having the prologue and epilogue generated
756 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute
,
758 /* Functions calls made using jli instruction. The pointer in JLI
759 table is found latter. */
760 { "jli_always", 0, 0, false, true, true, false, NULL
, NULL
},
761 /* Functions calls made using jli instruction. The pointer in JLI
762 table is given as input parameter. */
763 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute
,
765 /* Call a function using secure-mode. */
766 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute
,
768 /* Bypass caches using .di flag. */
769 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute
,
771 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute
, NULL
}
774 #undef TARGET_ASM_ALIGNED_HI_OP
775 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
776 #undef TARGET_ASM_ALIGNED_SI_OP
777 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
780 #undef TARGET_HAVE_TLS
781 #define TARGET_HAVE_TLS HAVE_AS_TLS
784 #undef TARGET_DWARF_REGISTER_SPAN
785 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
787 #undef TARGET_HARD_REGNO_NREGS
788 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
789 #undef TARGET_HARD_REGNO_MODE_OK
790 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
792 #undef TARGET_MODES_TIEABLE_P
793 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
795 /* Try to keep the (mov:DF _, reg) as early as possible so
796 that the d<add/sub/mul>h-lr insns appear together and can
797 use the peephole2 pattern. */
800 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
802 rtx set
= single_set (insn
);
804 && GET_MODE (SET_SRC(set
)) == DFmode
805 && GET_CODE (SET_SRC(set
)) == REG
)
807 /* Incrementing priority by 20 (empirically derived). */
808 return priority
+ 20;
814 /* For ARC base register + offset addressing, the validity of the
815 address is mode-dependent for most of the offset range, as the
816 offset can be scaled by the access size.
817 We don't expose these as mode-dependent addresses in the
818 mode_dependent_address_p target hook, because that would disable
819 lots of optimizations, and most uses of these addresses are for 32
820 or 64 bit accesses anyways, which are fine.
821 However, that leaves some addresses for 8 / 16 bit values not
822 properly reloaded by the generic code, which is why we have to
823 schedule secondary reloads for these. */
826 arc_secondary_reload (bool in_p
,
830 secondary_reload_info
*sri
)
832 enum rtx_code code
= GET_CODE (x
);
834 if (cl
== DOUBLE_REGS
)
837 /* If we have a subreg (reg), where reg is a pseudo (that will end in
838 a memory location), then we may need a scratch register to handle
839 the fp/sp+largeoffset address. */
847 int regno
= REGNO (x
);
848 if (regno
>= FIRST_PSEUDO_REGISTER
)
849 regno
= reg_renumber
[regno
];
854 /* It is a pseudo that ends in a stack location. This
855 procedure only works with the old reload step. */
856 if (!lra_in_progress
&& reg_equiv_mem (REGNO (x
)))
858 /* Get the equivalent address and check the range of the
860 rtx mem
= reg_equiv_mem (REGNO (x
));
861 addr
= find_replacement (&XEXP (mem
, 0));
866 gcc_assert (MEM_P (x
));
868 addr
= simplify_rtx (addr
);
870 if (addr
&& GET_CODE (addr
) == PLUS
871 && CONST_INT_P (XEXP (addr
, 1))
872 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
878 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
882 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
892 /* Convert reloads using offsets that are too large to use indirect
896 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
900 gcc_assert (GET_CODE (mem
) == MEM
);
901 addr
= XEXP (mem
, 0);
903 /* Large offset: use a move. FIXME: ld ops accepts limms as
904 offsets. Hence, the following move insn is not required. */
905 emit_move_insn (scratch
, addr
);
906 mem
= replace_equiv_address_nv (mem
, scratch
);
908 /* Now create the move. */
910 emit_insn (gen_rtx_SET (mem
, reg
));
912 emit_insn (gen_rtx_SET (reg
, mem
));
917 static unsigned arc_predicate_delay_insns (void);
921 const pass_data pass_data_arc_predicate_delay_insns
=
924 "arc_predicate_delay_insns", /* name */
925 OPTGROUP_NONE
, /* optinfo_flags */
926 TV_IFCVT2
, /* tv_id */
927 0, /* properties_required */
928 0, /* properties_provided */
929 0, /* properties_destroyed */
930 0, /* todo_flags_start */
931 TODO_df_finish
/* todo_flags_finish */
934 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
937 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
938 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
941 /* opt_pass methods: */
942 virtual unsigned int execute (function
*)
944 return arc_predicate_delay_insns ();
946 virtual bool gate (function
*)
948 return flag_delayed_branch
;
955 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
957 return new pass_arc_predicate_delay_insns (ctxt
);
960 /* Called by OVERRIDE_OPTIONS to initialize various things. */
967 /* I have the multiplier, then use it*/
968 if (TARGET_MPYW
|| TARGET_MULTI
)
969 arc_multcost
= COSTS_N_INSNS (1);
971 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
972 if (arc_multcost
< 0)
975 case ARC_TUNE_ARC700_4_2_STD
:
977 max throughput (1 multiply + 4 other insns) / 5 cycles. */
978 arc_multcost
= COSTS_N_INSNS (4);
979 if (TARGET_NOMPY_SET
)
980 arc_multcost
= COSTS_N_INSNS (30);
982 case ARC_TUNE_ARC700_4_2_XMAC
:
984 max throughput (1 multiply + 2 other insns) / 3 cycles. */
985 arc_multcost
= COSTS_N_INSNS (3);
986 if (TARGET_NOMPY_SET
)
987 arc_multcost
= COSTS_N_INSNS (30);
989 case ARC_TUNE_ARC600
:
990 if (TARGET_MUL64_SET
)
992 arc_multcost
= COSTS_N_INSNS (4);
997 arc_multcost
= COSTS_N_INSNS (30);
1001 /* MPY instructions valid only for ARC700 or ARCv2. */
1002 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
1003 error ("%<-mno-mpy%> supported only for ARC700 or ARCv2");
1005 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
1006 error ("%<-mno-dpfp-lrsr%> supported only with %<-mdpfp%>");
1008 /* FPX-1. No fast and compact together. */
1009 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
1010 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
1011 error ("FPX fast and compact options cannot be specified together");
1013 /* FPX-2. No fast-spfp for arc600 or arc601. */
1014 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
1015 error ("%<-mspfp_fast%> not available on ARC600 or ARC601");
1017 /* FPX-4. No FPX extensions mixed with FPU extensions. */
1018 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
1019 && TARGET_HARD_FLOAT
)
1020 error ("no FPX/FPU mixing allowed");
1022 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
1023 if (flag_pic
&& TARGET_ARC600_FAMILY
)
1025 warning (0, "PIC is not supported for %qs",
1030 arc_init_reg_tables ();
1032 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
1033 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
1034 arc_punct_chars
['*'] = 1;
1035 arc_punct_chars
['?'] = 1;
1036 arc_punct_chars
['!'] = 1;
1037 arc_punct_chars
['+'] = 1;
1038 arc_punct_chars
['_'] = 1;
1041 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1042 register range is specified as two registers separated by a dash.
1043 It always starts with r0, and its upper limit is fp register.
1044 blink and lp_count registers are optional. */
1047 irq_range (const char *cstr
)
1049 int i
, first
, last
, blink
, lpcount
, xreg
;
1050 char *str
, *dash
, *comma
;
1053 str
= (char *) alloca (i
+ 1);
1054 memcpy (str
, cstr
, i
+ 1);
1058 dash
= strchr (str
, '-');
1061 warning (OPT_mirq_ctrl_saved_
, "missing dash");
1066 comma
= strchr (dash
+ 1, ',');
1070 first
= decode_reg_name (str
);
1073 warning (OPT_mirq_ctrl_saved_
, "first register must be R0");
1077 /* At this moment we do not have the register names initialized
1079 if (!strcmp (dash
+ 1, "ilink"))
1082 last
= decode_reg_name (dash
+ 1);
1086 warning (OPT_mirq_ctrl_saved_
, "unknown register name: %s", dash
+ 1);
1092 warning (OPT_mirq_ctrl_saved_
,
1093 "last register name %s must be an odd register", dash
+ 1);
1101 warning (OPT_mirq_ctrl_saved_
,
1102 "%s-%s is an empty range", str
, dash
+ 1);
1111 comma
= strchr (str
, ',');
1115 xreg
= decode_reg_name (str
);
1127 warning (OPT_mirq_ctrl_saved_
,
1128 "unknown register name: %s", str
);
1133 irq_ctrl_saved
.irq_save_last_reg
= last
;
1134 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
1135 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
1138 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1142 parse_mrgf_banked_regs_option (const char *arg
)
1148 val
= strtol (arg
, &end_ptr
, 10);
1149 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
1150 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
1152 error ("invalid number in %<-mrgf-banked-regs=%s%> "
1153 "valid values are 0, 4, 8, 16, or 32", arg
);
1156 rgf_banked_register_count
= (int) val
;
1159 /* Check ARC options, generate derived target attributes. */
1162 arc_override_options (void)
1165 cl_deferred_option
*opt
;
1166 vec
<cl_deferred_option
> *vopt
1167 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
1169 if (arc_cpu
== PROCESSOR_NONE
)
1170 arc_cpu
= TARGET_CPU_DEFAULT
;
1172 /* Set the default cpu options. */
1173 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
1175 /* Set the architectures. */
1176 switch (arc_selected_cpu
->arch_info
->arch_id
)
1179 arc_cpu_string
= "EM";
1182 arc_cpu_string
= "HS";
1185 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
1186 arc_cpu_string
= "NPS400";
1188 arc_cpu_string
= "ARC700";
1191 arc_cpu_string
= "ARC600";
1197 irq_ctrl_saved
.irq_save_last_reg
= -1;
1198 irq_ctrl_saved
.irq_save_blink
= false;
1199 irq_ctrl_saved
.irq_save_lpcount
= false;
1201 rgf_banked_register_count
= 0;
1203 /* Handle the deferred options. */
1205 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1207 switch (opt
->opt_index
)
1209 case OPT_mirq_ctrl_saved_
:
1211 irq_range (opt
->arg
);
1213 warning (OPT_mirq_ctrl_saved_
,
1214 "option %<-mirq-ctrl-saved%> valid only "
1215 "for ARC v2 processors");
1218 case OPT_mrgf_banked_regs_
:
1220 parse_mrgf_banked_regs_option (opt
->arg
);
1222 warning (OPT_mrgf_banked_regs_
,
1223 "option %<-mrgf-banked-regs%> valid only for "
1224 "ARC v2 processors");
1232 CLEAR_HARD_REG_SET (overrideregs
);
1233 if (common_deferred_options
)
1235 vec
<cl_deferred_option
> v
=
1236 *((vec
<cl_deferred_option
> *) common_deferred_options
);
1239 FOR_EACH_VEC_ELT (v
, i
, opt
)
1241 switch (opt
->opt_index
)
1244 case OPT_fcall_used_
:
1245 case OPT_fcall_saved_
:
1246 if ((reg
= decode_reg_name_and_count (opt
->arg
, &nregs
)) >= 0)
1247 for (j
= reg
; j
< reg
+ nregs
; j
++)
1248 SET_HARD_REG_BIT (overrideregs
, j
);
1256 /* Check options against architecture options. Throw an error if
1257 option is not allowed. Extra, check options against default
1258 architecture/cpu flags and throw an warning if we find a
1260 /* TRANSLATORS: the DOC/DOC0/DOC1 are strings which shouldn't be
1261 translated. They are like keywords which one can relate with the
1262 architectural choices taken for an ARC CPU implementation. */
1263 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1265 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1267 error ("option %<%s=%s%> is not available for %qs CPU", \
1268 DOC0, DOC1, arc_selected_cpu->name); \
1269 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1270 && (VAR != DEFAULT_##VAR) \
1272 warning (0, "option %qs is ignored, the default value %qs" \
1273 " is considered for %qs CPU", DOC0, DOC1, \
1274 arc_selected_cpu->name); \
1276 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1278 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1279 && (target_flags & MASK)) \
1280 error ("option %qs is not available for %qs CPU", \
1281 DOC, arc_selected_cpu->name); \
1282 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1283 && (target_flags_explicit & MASK) \
1284 && (!(target_flags & MASK))) \
1285 warning (0, "unset option %qs is ignored, it is always" \
1286 " enabled for %qs CPU", DOC, \
1287 arc_selected_cpu->name); \
1290 #include "arc-options.def"
1295 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1296 specific flags are set in arc-common.cc. The architecture forces
1297 the default hardware configurations in, regardless what command
1298 line options are saying. The CPU optional hw options can be
1299 turned on or off. */
1300 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1302 if ((arc_selected_cpu->flags & CODE) \
1303 && ((target_flags_explicit & MASK) == 0)) \
1304 target_flags |= MASK; \
1305 if (arc_selected_cpu->arch_info->dflags & CODE) \
1306 target_flags |= MASK; \
1308 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1310 if ((arc_selected_cpu->flags & CODE) \
1311 && (VAR == DEFAULT_##VAR)) \
1313 if (arc_selected_cpu->arch_info->dflags & CODE) \
1317 #include "arc-options.def"
1323 switch (arc_selected_cpu
->extra
)
1325 case HAS_LPCOUNT_16
:
1332 /* Set Tune option. */
1333 if (arc_tune
== ARC_TUNE_NONE
)
1334 arc_tune
= (enum arc_tune_attr
) arc_selected_cpu
->tune
;
1336 if (arc_size_opt_level
== 3)
1339 if (TARGET_V2
&& optimize_size
&& (ATTRIBUTE_PCS
== 2))
1340 TARGET_CODE_DENSITY_FRAME
= 1;
1343 target_flags
|= MASK_NO_SDATA_SET
;
1345 /* Check for small data option */
1346 if (!OPTION_SET_P (g_switch_value
) && !TARGET_NO_SDATA_SET
)
1347 g_switch_value
= TARGET_LL64
? 8 : 4;
1349 /* A7 has an issue with delay slots. */
1350 if (TARGET_ARC700
&& (arc_tune
!= ARC_TUNE_ARC7XX
))
1351 flag_delayed_branch
= 0;
1353 /* Millicode thunks doesn't work for long calls. */
1354 if (TARGET_LONG_CALLS_SET
1355 /* neither for RF16. */
1357 target_flags
&= ~MASK_MILLICODE_THUNK_SET
;
1359 /* Set unaligned to all HS cpus. */
1360 if (!OPTION_SET_P (unaligned_access
) && TARGET_HS
)
1361 unaligned_access
= 1;
1363 if (TARGET_HS
&& (arc_tune
== ARC_TUNE_ARCHS4X_REL31A
))
1365 TARGET_CODE_DENSITY_FRAME
= 0;
1366 flag_delayed_branch
= 0;
1369 /* These need to be done at start up. It's convenient to do them here. */
1373 /* The condition codes of the ARC, and the inverse function. */
1374 /* For short branches, the "c" / "nc" names are not defined in the ARC
1375 Programmers manual, so we have to use "lo" / "hs"" instead. */
1376 static const char *arc_condition_codes
[] =
1378 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1379 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1382 enum arc_cc_code_index
1384 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1385 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1386 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1387 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1390 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1392 /* Returns the index of the ARC condition code string in
1393 `arc_condition_codes'. COMPARISON should be an rtx like
1394 `(eq (...) (...))'. */
1397 get_arc_condition_code (rtx comparison
)
1399 switch (GET_MODE (XEXP (comparison
, 0)))
1402 case E_SImode
: /* For BRcc. */
1403 switch (GET_CODE (comparison
))
1405 case EQ
: return ARC_CC_EQ
;
1406 case NE
: return ARC_CC_NE
;
1407 case GT
: return ARC_CC_GT
;
1408 case LE
: return ARC_CC_LE
;
1409 case GE
: return ARC_CC_GE
;
1410 case LT
: return ARC_CC_LT
;
1411 case GTU
: return ARC_CC_HI
;
1412 case LEU
: return ARC_CC_LS
;
1413 case LTU
: return ARC_CC_LO
;
1414 case GEU
: return ARC_CC_HS
;
1415 default : gcc_unreachable ();
1418 switch (GET_CODE (comparison
))
1420 case EQ
: return ARC_CC_EQ
;
1421 case NE
: return ARC_CC_NE
;
1422 case GE
: return ARC_CC_P
;
1423 case LT
: return ARC_CC_N
;
1424 case GT
: return ARC_CC_PNZ
;
1425 default : gcc_unreachable ();
1428 switch (GET_CODE (comparison
))
1430 case EQ
: return ARC_CC_EQ
;
1431 case NE
: return ARC_CC_NE
;
1432 default : gcc_unreachable ();
1435 switch (GET_CODE (comparison
))
1437 case LTU
: return ARC_CC_C
;
1438 case GEU
: return ARC_CC_NC
;
1439 default : gcc_unreachable ();
1441 case E_CC_FP_GTmode
:
1442 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1443 switch (GET_CODE (comparison
))
1445 case GT
: return ARC_CC_N
;
1446 case UNLE
: return ARC_CC_P
;
1447 default : gcc_unreachable ();
1450 switch (GET_CODE (comparison
))
1452 case GT
: return ARC_CC_HI
;
1453 case UNLE
: return ARC_CC_LS
;
1454 default : gcc_unreachable ();
1456 case E_CC_FP_GEmode
:
1457 /* Same for FPX and non-FPX. */
1458 switch (GET_CODE (comparison
))
1460 case GE
: return ARC_CC_HS
;
1461 case UNLT
: return ARC_CC_LO
;
1462 default : gcc_unreachable ();
1464 case E_CC_FP_UNEQmode
:
1465 switch (GET_CODE (comparison
))
1467 case UNEQ
: return ARC_CC_EQ
;
1468 case LTGT
: return ARC_CC_NE
;
1469 default : gcc_unreachable ();
1471 case E_CC_FP_ORDmode
:
1472 switch (GET_CODE (comparison
))
1474 case UNORDERED
: return ARC_CC_C
;
1475 case ORDERED
: return ARC_CC_NC
;
1476 default : gcc_unreachable ();
1479 switch (GET_CODE (comparison
))
1481 case EQ
: return ARC_CC_EQ
;
1482 case NE
: return ARC_CC_NE
;
1483 case UNORDERED
: return ARC_CC_C
;
1484 case ORDERED
: return ARC_CC_NC
;
1485 case LTGT
: return ARC_CC_HI
;
1486 case UNEQ
: return ARC_CC_LS
;
1487 default : gcc_unreachable ();
1491 switch (GET_CODE (comparison
))
1493 case EQ
: return ARC_CC_EQ
;
1494 case NE
: return ARC_CC_NE
;
1495 case GT
: return ARC_CC_GT
;
1496 case GE
: return ARC_CC_GE
;
1497 case LT
: return ARC_CC_C
;
1498 case LE
: return ARC_CC_LS
;
1499 case UNORDERED
: return ARC_CC_V
;
1500 case ORDERED
: return ARC_CC_NV
;
1501 case UNGT
: return ARC_CC_HI
;
1502 case UNGE
: return ARC_CC_HS
;
1503 case UNLT
: return ARC_CC_LT
;
1504 case UNLE
: return ARC_CC_LE
;
1505 /* UNEQ and LTGT do not have representation. */
1506 case LTGT
: /* Fall through. */
1507 case UNEQ
: /* Fall through. */
1508 default : gcc_unreachable ();
1510 case E_CC_FPU_UNEQmode
:
1511 switch (GET_CODE (comparison
))
1513 case LTGT
: return ARC_CC_NE
;
1514 case UNEQ
: return ARC_CC_EQ
;
1515 default : gcc_unreachable ();
1517 default : gcc_unreachable ();
1523 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1526 arc_short_comparison_p (rtx comparison
, int offset
)
1528 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1529 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1530 switch (get_arc_condition_code (comparison
))
1532 case ARC_CC_EQ
: case ARC_CC_NE
:
1533 return offset
>= -512 && offset
<= 506;
1534 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1535 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1536 return offset
>= -64 && offset
<= 58;
1542 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1543 return the mode to be used for the comparison. */
1546 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1548 machine_mode mode
= GET_MODE (x
);
1551 /* For an operation that sets the condition codes as a side-effect, the
1552 C and V flags is not set as for cmp, so we can only use comparisons where
1553 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1555 /* ??? We could use "pnz" for greater than zero, however, we could then
1556 get into trouble because the comparison could not be reversed. */
1557 if (GET_MODE_CLASS (mode
) == MODE_INT
1559 && (op
== EQ
|| op
== NE
1560 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1563 /* add.f for if (a+b) */
1565 && GET_CODE (x
) == NEG
1566 && (op
== EQ
|| op
== NE
))
1569 /* Check if this is a test suitable for bxor.f . */
1570 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1571 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1575 /* Check if this is a test suitable for add / bmsk.f . */
1576 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1577 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1578 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1579 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1580 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1583 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1584 && GET_CODE (x
) == PLUS
1585 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1588 if (TARGET_ARGONAUT_SET
1589 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1592 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1594 case LT
: case UNGE
: case GT
: case UNLE
:
1595 return CC_FP_GTmode
;
1596 case LE
: case UNGT
: case GE
: case UNLT
:
1597 return CC_FP_GEmode
;
1598 default: gcc_unreachable ();
1600 else if (TARGET_HARD_FLOAT
1601 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1602 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1623 return CC_FPU_UNEQmode
;
1628 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1632 case EQ
: case NE
: return CC_Zmode
;
1634 case GT
: case UNLE
: return CC_FP_GTmode
;
1636 case GE
: case UNLT
: return CC_FP_GEmode
;
1637 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1638 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1639 default: gcc_unreachable ();
1645 /* Vectors to keep interesting information about registers where it can easily
1646 be got. We use to use the actual mode value as the bit number, but there
1647 is (or may be) more than 32 modes now. Instead we use two tables: one
1648 indexed by hard register number, and one indexed by mode. */
1650 /* The purpose of arc_mode_class is to shrink the range of modes so that
1651 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1652 mapped into one arc_mode_class mode. */
1654 enum arc_mode_class
{
1656 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1657 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1661 /* Modes for condition codes. */
1662 #define C_MODES (1 << (int) C_MODE)
1664 /* Modes for single-word and smaller quantities. */
1665 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1667 /* Modes for double-word and smaller quantities. */
1668 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1670 /* Mode for 8-byte DF values only. */
1671 #define DF_MODES (1 << DF_MODE)
1673 /* Modes for quad-word and smaller quantities. */
1674 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1676 /* Modes for 128-bit vectors. */
1677 #define V_MODES (1 << (int) V_MODE)
1679 /* Value is 1 if register/mode pair is acceptable on arc. */
1681 static unsigned int arc_hard_regno_modes
[] = {
1682 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1683 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1684 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1685 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1687 /* ??? Leave these as S_MODES for now. */
1688 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1689 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1690 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1691 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1693 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1694 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1695 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1696 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1698 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1699 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1700 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1701 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1703 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1704 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1708 static unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1710 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1713 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1718 /* Initialize the arc_mode_class array. */
1721 arc_init_reg_tables (void)
1725 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1727 machine_mode m
= (machine_mode
) i
;
1729 switch (GET_MODE_CLASS (m
))
1732 case MODE_PARTIAL_INT
:
1733 case MODE_COMPLEX_INT
:
1734 if (GET_MODE_SIZE (m
) <= 4)
1735 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1736 else if (GET_MODE_SIZE (m
) == 8)
1737 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1738 else if (GET_MODE_SIZE (m
) == 16)
1739 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1740 else if (GET_MODE_SIZE (m
) == 32)
1741 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1743 arc_mode_class
[i
] = 0;
1746 case MODE_COMPLEX_FLOAT
:
1747 if (GET_MODE_SIZE (m
) <= 4)
1748 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1749 else if (GET_MODE_SIZE (m
) == 8)
1750 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1751 else if (GET_MODE_SIZE (m
) == 16)
1752 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1753 else if (GET_MODE_SIZE (m
) == 32)
1754 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1756 arc_mode_class
[i
] = 0;
1758 case MODE_VECTOR_INT
:
1759 if (GET_MODE_SIZE (m
) == 4)
1760 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1761 else if (GET_MODE_SIZE (m
) == 8)
1762 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1764 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1768 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1769 we must explicitly check for them here. */
1770 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1771 || i
== (int) CC_Cmode
1772 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1773 || i
== CC_FPUmode
|| i
== CC_FPUEmode
|| i
== CC_FPU_UNEQmode
)
1774 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1776 arc_mode_class
[i
] = 0;
1782 /* Core registers 56..59 are used for multiply extension options.
1783 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1784 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1785 number depends on endianness.
1786 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1787 Because mlo / mhi form a 64 bit value, we use different gcc internal
1788 register numbers to make them form a register pair as the gcc internals
1789 know it. mmid gets number 57, if still available, and mlo / mhi get
1790 number 58 and 59, depending on endianness. We use DEBUGGER_REGNO
1791 to map this back. */
1792 char rname56
[5] = "r56";
1793 char rname57
[5] = "r57";
1794 char rname58
[5] = "r58";
1795 char rname59
[5] = "r59";
1796 char rname29
[7] = "ilink1";
1797 char rname30
[7] = "ilink2";
1800 arc_conditional_register_usage (void)
1804 int fix_start
= 60, fix_end
= 55;
1808 /* For ARCv2 the core register set is changed. */
1809 strcpy (rname29
, "ilink");
1810 strcpy (rname30
, "r30");
1812 if (!TEST_HARD_REG_BIT (overrideregs
, R30_REG
))
1814 /* No user interference. Set the r30 to be used by the
1816 call_used_regs
[R30_REG
] = 1;
1817 fixed_regs
[R30_REG
] = 0;
1819 arc_regno_reg_class
[R30_REG
] = GENERAL_REGS
;
1823 if (TARGET_MUL64_SET
)
1825 fix_start
= R57_REG
;
1828 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1829 you are supposed to refer to it as mlo & mhi, e.g
1830 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1831 In an actual asm instruction, you are of course use mmed.
1832 The point of avoiding having a separate register for mmed is that
1833 this way, we don't have to carry clobbers of that reg around in every
1834 isntruction that modifies mlo and/or mhi. */
1835 strcpy (rname57
, "");
1836 strcpy (rname58
, "mlo");
1837 strcpy (rname59
, "mhi");
1840 /* The nature of arc_tp_regno is actually something more like a global
1841 register, however globalize_reg requires a declaration.
1842 We use EPILOGUE_USES to compensate so that sets from
1843 __builtin_set_frame_pointer are not deleted. */
1844 if (arc_tp_regno
!= -1)
1845 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1847 if (TARGET_MULMAC_32BY16_SET
)
1849 fix_start
= MUL32x16_REG
;
1850 fix_end
= fix_end
> R57_REG
? fix_end
: R57_REG
;
1851 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1852 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1854 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1856 if (!fixed_regs
[regno
])
1857 warning (0, "multiply option implies r%d is fixed", regno
);
1858 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1861 /* Reduced configuration: don't use r4-r9, r16-r25. */
1864 for (i
= R4_REG
; i
<= R9_REG
; i
++)
1865 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1866 for (i
= R16_REG
; i
<= R25_REG
; i
++)
1867 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1870 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1873 for (regno
= R1_REG
; regno
< R32_REG
; regno
+=2)
1874 arc_hard_regno_modes
[regno
] = S_MODES
;
1876 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1879 if ((i
<= R3_REG
) || ((i
>= R12_REG
) && (i
<= R15_REG
)))
1880 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1882 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1884 else if (i
< LP_COUNT
)
1885 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1887 arc_regno_reg_class
[i
] = NO_REGS
;
1889 /* Handle Special Registers. */
1890 arc_regno_reg_class
[CC_REG
] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1891 arc_regno_reg_class
[FRAME_POINTER_REGNUM
] = GENERAL_REGS
;
1892 arc_regno_reg_class
[ARG_POINTER_REGNUM
] = GENERAL_REGS
;
1895 for (i
= R40_REG
; i
< R44_REG
; ++i
)
1897 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1898 if (!TARGET_ARGONAUT_SET
)
1899 CLEAR_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], i
);
1903 /* Disable all DOUBLE_REGISTER settings, if not generating DPFP
1905 arc_regno_reg_class
[R40_REG
] = ALL_REGS
;
1906 arc_regno_reg_class
[R41_REG
] = ALL_REGS
;
1907 arc_regno_reg_class
[R42_REG
] = ALL_REGS
;
1908 arc_regno_reg_class
[R43_REG
] = ALL_REGS
;
1910 fixed_regs
[R40_REG
] = 1;
1911 fixed_regs
[R41_REG
] = 1;
1912 fixed_regs
[R42_REG
] = 1;
1913 fixed_regs
[R43_REG
] = 1;
1915 arc_hard_regno_modes
[R40_REG
] = 0;
1916 arc_hard_regno_modes
[R42_REG
] = 0;
1919 if (TARGET_SIMD_SET
)
1921 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1922 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1924 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1925 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1927 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1928 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1929 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1930 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1932 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1933 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1934 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1938 arc_regno_reg_class
[PCL_REG
] = NO_REGS
;
1940 /*ARCV2 Accumulator. */
1942 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1943 || TARGET_PLUS_DMPY
)
1945 arc_regno_reg_class
[ACCL_REGNO
] = GENERAL_REGS
;
1946 arc_regno_reg_class
[ACCH_REGNO
] = GENERAL_REGS
;
1948 /* Allow the compiler to freely use them. */
1949 if (!TEST_HARD_REG_BIT (overrideregs
, ACCL_REGNO
))
1950 fixed_regs
[ACCL_REGNO
] = 0;
1951 if (!TEST_HARD_REG_BIT (overrideregs
, ACCH_REGNO
))
1952 fixed_regs
[ACCH_REGNO
] = 0;
1954 if (!fixed_regs
[ACCH_REGNO
] && !fixed_regs
[ACCL_REGNO
])
1955 arc_hard_regno_modes
[ACC_REG_FIRST
] = D_MODES
;
1959 /* Implement TARGET_HARD_REGNO_NREGS. */
1962 arc_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
1964 if (GET_MODE_SIZE (mode
) == 16
1965 && regno
>= ARC_FIRST_SIMD_VR_REG
1966 && regno
<= ARC_LAST_SIMD_VR_REG
)
1969 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
1972 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1975 arc_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
1977 return (arc_hard_regno_modes
[regno
] & arc_mode_class
[mode
]) != 0;
1980 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1983 arc_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
1985 return (GET_MODE_CLASS (mode1
) == MODE_INT
1986 && GET_MODE_CLASS (mode2
) == MODE_INT
1987 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
1988 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
);
1991 /* Handle an "interrupt" attribute; arguments as in
1992 struct attribute_spec.handler. */
1995 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
2000 tree value
= TREE_VALUE (args
);
2002 if (TREE_CODE (value
) != STRING_CST
)
2004 warning (OPT_Wattributes
,
2005 "argument of %qE attribute is not a string constant",
2007 *no_add_attrs
= true;
2010 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
2011 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2013 warning (OPT_Wattributes
,
2014 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2016 *no_add_attrs
= true;
2019 && strcmp (TREE_STRING_POINTER (value
), "ilink")
2020 && strcmp (TREE_STRING_POINTER (value
), "firq"))
2022 warning (OPT_Wattributes
,
2023 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2025 *no_add_attrs
= true;
2032 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
2033 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
2035 if (TREE_CODE (*node
) != FUNCTION_DECL
)
2037 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2039 *no_add_attrs
= true;
2045 /* Type of function DECL.
2047 The result is cached. To reset the cache at the end of a function,
2048 call with DECL = NULL_TREE. */
2051 arc_compute_function_type (struct function
*fun
)
2053 tree attr
, decl
= fun
->decl
;
2054 unsigned int fn_type
= fun
->machine
->fn_type
;
2056 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2059 /* Check if it is a naked function. */
2060 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2061 fn_type
|= ARC_FUNCTION_NAKED
;
2063 fn_type
|= ARC_FUNCTION_NORMAL
;
2065 /* Now see if this is an interrupt handler. */
2066 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2067 if (attr
!= NULL_TREE
)
2069 tree value
, args
= TREE_VALUE (attr
);
2071 gcc_assert (list_length (args
) == 1);
2072 value
= TREE_VALUE (args
);
2073 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2075 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2076 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2077 fn_type
|= ARC_FUNCTION_ILINK1
;
2078 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2079 fn_type
|= ARC_FUNCTION_ILINK2
;
2080 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2081 fn_type
|= ARC_FUNCTION_FIRQ
;
2086 return fun
->machine
->fn_type
= fn_type
;
2089 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2092 arc_allocate_stack_slots_for_args (void)
2094 /* Naked functions should not allocate stack slots for arguments. */
2095 unsigned int fn_type
= arc_compute_function_type (cfun
);
2097 return !ARC_NAKED_P(fn_type
);
2100 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2103 arc_warn_func_return (tree decl
)
2105 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
2106 unsigned int fn_type
= arc_compute_function_type (func
);
2108 return !ARC_NAKED_P (fn_type
);
2111 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2112 and two if they are nearly compatible (which causes a warning to be
2116 arc_comp_type_attributes (const_tree type1
,
2119 int l1
, l2
, m1
, m2
, s1
, s2
;
2121 /* Check for mismatch of non-default calling convention. */
2122 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
2125 /* Check for mismatched call attributes. */
2126 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2127 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2128 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2129 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2130 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2131 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2133 /* Only bother to check if an attribute is defined. */
2134 if (l1
| l2
| m1
| m2
| s1
| s2
)
2136 /* If one type has an attribute, the other must have the same attribute. */
2137 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
2140 /* Disallow mixed attributes. */
2141 if (l1
+ m1
+ s1
> 1)
2149 /* Misc. utilities. */
2151 /* X and Y are two things to compare using CODE. Emit the compare insn and
2152 return the rtx for the cc reg in the proper mode. */
2155 gen_compare_reg (rtx comparison
, machine_mode omode
)
2157 enum rtx_code code
= GET_CODE (comparison
);
2158 rtx x
= XEXP (comparison
, 0);
2159 rtx y
= XEXP (comparison
, 1);
2161 machine_mode mode
, cmode
;
2164 cmode
= GET_MODE (x
);
2165 if (cmode
== VOIDmode
)
2166 cmode
= GET_MODE (y
);
2168 /* If ifcvt passed us a MODE_CC comparison we can
2169 just return it. It should be in the proper form already. */
2170 if (GET_MODE_CLASS (cmode
) == MODE_CC
)
2173 if (cmode
!= SImode
&& cmode
!= SFmode
&& cmode
!= DFmode
)
2175 if (cmode
== SImode
)
2177 if (!register_operand (x
, SImode
))
2179 if (register_operand (y
, SImode
))
2184 code
= swap_condition (code
);
2187 x
= copy_to_mode_reg (SImode
, x
);
2189 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
2190 y
= copy_to_mode_reg (SImode
, y
);
2194 x
= force_reg (cmode
, x
);
2195 y
= force_reg (cmode
, y
);
2197 mode
= SELECT_CC_MODE (code
, x
, y
);
2199 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
2201 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2202 cmpdfpx_raw, is not a correct comparison for floats:
2203 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2205 if (TARGET_ARGONAUT_SET
2206 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2210 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2211 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2213 case GT
: case UNLE
: case GE
: case UNLT
:
2214 code
= swap_condition (code
);
2222 if (cmode
== SFmode
)
2224 emit_insn (gen_cmpsfpx_raw (x
, y
));
2228 /* Accepts Dx regs directly by insns. */
2229 emit_insn (gen_cmpdfpx_raw (x
, y
));
2232 if (mode
!= CC_FPXmode
)
2233 emit_insn (gen_rtx_SET (cc_reg
,
2234 gen_rtx_COMPARE (mode
,
2235 gen_rtx_REG (CC_FPXmode
, 61),
2238 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2242 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2243 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2245 case LT
: case UNGE
: case LE
: case UNGT
:
2246 code
= swap_condition (code
);
2255 emit_insn (gen_cmp_quark (cc_reg
,
2256 gen_rtx_COMPARE (mode
, x
, y
)));
2258 else if (TARGET_HARD_FLOAT
2259 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2260 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2261 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2262 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2264 rtx op0
= gen_rtx_REG (cmode
, 0);
2265 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2270 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2271 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2273 case LT
: case UNGE
: case LE
: case UNGT
:
2274 code
= swap_condition (code
);
2280 if (currently_expanding_to_rtl
)
2288 emit_move_insn (op0
, x
);
2289 emit_move_insn (op1
, y
);
2293 gcc_assert (rtx_equal_p (op0
, x
));
2294 gcc_assert (rtx_equal_p (op1
, y
));
2301 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2304 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2305 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2308 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2309 We assume the value can be either signed or unsigned. */
2312 arc_double_limm_p (rtx value
)
2314 HOST_WIDE_INT low
, high
;
2316 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2321 low
= CONST_DOUBLE_LOW (value
);
2322 high
= CONST_DOUBLE_HIGH (value
);
2324 if (low
& 0x80000000)
2326 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2327 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2328 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2333 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2337 /* Do any needed setup for a variadic function. For the ARC, we must
2338 create a register parameter block, and then copy any anonymous arguments
2339 in registers to memory.
2341 CUM has not been updated for the last named argument (which is given
2342 by ARG), and we rely on this fact. */
2345 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2346 const function_arg_info
&arg
,
2347 int *pretend_size
, int no_rtl
)
2350 CUMULATIVE_ARGS next_cum
;
2352 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2354 next_cum
= *get_cumulative_args (args_so_far
);
2355 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl
)))
2356 arc_function_arg_advance (pack_cumulative_args (&next_cum
), arg
);
2357 first_anon_arg
= next_cum
;
2359 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2361 /* First anonymous (unnamed) argument is in a reg. */
2363 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2364 int first_reg_offset
= first_anon_arg
;
2369 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2370 FIRST_PARM_OFFSET (0)));
2371 move_block_from_reg (first_reg_offset
, regblock
,
2372 MAX_ARC_PARM_REGS
- first_reg_offset
);
2376 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2380 /* Return TRUE if reg is ok for short instrcutions. */
2383 arc_check_short_reg_p (rtx op
)
2388 if (IN_RANGE (REGNO (op
) ^ 4, 4, 11))
2394 /* Cost functions. */
2396 /* Provide the costs of an addressing mode that contains ADDR.
2397 If ADDR is not a valid address, its cost is irrelevant. */
2400 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2402 switch (GET_CODE (addr
))
2405 return speed
|| arc_check_short_reg_p (addr
) ? 0 : 1;
2406 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2407 case PRE_MODIFY
: case POST_MODIFY
:
2413 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2415 /* Most likely needs a LIMM. */
2416 return COSTS_N_INSNS (1);
2420 rtx plus0
= XEXP (addr
, 0);
2421 rtx plus1
= XEXP (addr
, 1);
2423 if (GET_CODE (plus0
) != REG
2424 && (GET_CODE (plus0
) != MULT
2425 || !CONST_INT_P (XEXP (plus0
, 1))
2426 || (INTVAL (XEXP (plus0
, 1)) != 2
2427 && INTVAL (XEXP (plus0
, 1)) != 4)))
2430 switch (GET_CODE (plus1
))
2433 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2437 : (arc_check_short_reg_p (plus0
)
2438 && satisfies_constraint_O (plus1
))
2442 return (speed
< 1 ? 0
2443 : (arc_check_short_reg_p (plus0
)
2444 && arc_check_short_reg_p (plus1
))
2449 return COSTS_N_INSNS (1);
2462 /* Emit instruction X with the frame related bit set. */
2468 RTX_FRAME_RELATED_P (x
) = 1;
2472 /* Emit a frame insn to move SRC to DST. */
2475 frame_move (rtx dst
, rtx src
)
2477 rtx tmp
= gen_rtx_SET (dst
, src
);
2478 RTX_FRAME_RELATED_P (tmp
) = 1;
2479 return frame_insn (tmp
);
2482 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2483 auto increment address, or is zero. */
2486 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2488 rtx insn
= frame_move (dst
, src
);
2491 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2492 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2493 add_reg_note (insn
, REG_INC
, reg
);
2497 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2500 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2502 gcc_assert ((offset
& 0x3) == 0);
2505 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2508 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2511 frame_stack_add (HOST_WIDE_INT offset
)
2513 return frame_add (stack_pointer_rtx
, offset
);
2516 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2517 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2518 Register Allocator) pass, while we want to get the frame size
2519 correct earlier than the IRA pass.
2521 When a function uses eh_return we must ensure that the fp register
2522 is saved and then restored so that the unwinder can restore the
2523 correct value for the frame we are going to jump to.
2525 To do this we force all frames that call eh_return to require a
2526 frame pointer (see arc_frame_pointer_required), this
2527 will ensure that the previous frame pointer is stored on entry to
2528 the function, and will then be reloaded at function exit.
2530 As the frame pointer is handled as a special case in our prologue
2531 and epilogue code it must not be saved and restored using the
2532 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2533 believes that the function is not using a frame pointer and that
2534 the value in the fp register is the frame pointer, while the
2535 prologue and epilogue are busy saving and restoring the fp
2538 During compilation of a function the frame size is evaluated
2539 multiple times, it is not until the reload pass is complete the
2540 frame size is considered fixed (it is at this point that space for
2541 all spills has been allocated). However the frame_pointer_needed
2542 variable is not set true until the register allocation pass, as a
2543 result in the early stages the frame size does not include space
2544 for the frame pointer to be spilled.
2546 The problem that this causes is that the rtl generated for
2547 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2548 the offset from the frame pointer at which the return address
2549 lives. However, in early passes GCC has not yet realised we need a
2550 frame pointer, and so has not included space for the frame pointer
2551 in the frame size, and so gets the offset of the return address
2552 wrong. This should not be an issue as in later passes GCC has
2553 realised that the frame pointer needs to be spilled, and has
2554 increased the frame size. However, the rtl for the
2555 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2556 offset, and the wrong smaller offset is used. */
2559 arc_frame_pointer_needed (void)
2561 return (frame_pointer_needed
|| crtl
->calls_eh_return
);
2564 /* Tell prologue and epilogue if register REGNO should be saved /
2565 restored. The SPECIAL_P is true when the register may need special
2566 ld/st sequence. The return address, and stack pointer are treated
2567 separately. Don't consider them here. */
2570 arc_must_save_register (int regno
, struct function
*func
, bool special_p
)
2572 unsigned int fn_type
= arc_compute_function_type (func
);
2573 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2574 && ARC_AUTO_IRQ_P (fn_type
));
2575 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2577 switch (rgf_banked_register_count
)
2580 firq_auto_save_p
&= (regno
< 4);
2583 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2586 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2587 || ((regno
> 25) && (regno
< 29))
2588 || ((regno
> 29) && (regno
< 32)));
2591 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2594 firq_auto_save_p
= false;
2601 case RETURN_ADDR_REGNUM
:
2602 case STACK_POINTER_REGNUM
:
2603 /* The stack pointer and the return address are handled
2608 /* r30 is either used as ilink2 by ARCv1 or as a free register
2619 /* If those ones are used by the FPX machinery, we handle them
2621 if (TARGET_DPFP
&& !special_p
)
2646 /* The Extension Registers. */
2647 if (ARC_INTERRUPT_P (fn_type
)
2648 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2649 || df_regs_ever_live_p (regno
))
2650 /* Not all extension registers are available, choose the
2652 && !fixed_regs
[regno
])
2658 /* ARC600 specifies those ones as mlo/mhi registers, otherwise
2659 just handle them like any other extension register. */
2660 if (ARC_INTERRUPT_P (fn_type
)
2661 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2662 || df_regs_ever_live_p (regno
))
2663 /* Not all extension registers are available, choose the
2665 && ((!fixed_regs
[regno
] && !special_p
)
2666 || (TARGET_MUL64_SET
&& special_p
)))
2673 /* Fixed/control register, nothing to do. LP_COUNT is
2677 case HARD_FRAME_POINTER_REGNUM
:
2678 /* If we need FP reg as a frame pointer then don't save it as a
2680 if (arc_frame_pointer_needed ())
2688 if (((df_regs_ever_live_p (regno
) && !call_used_or_fixed_reg_p (regno
))
2689 /* In an interrupt save everything. */
2690 || (ARC_INTERRUPT_P (fn_type
)
2691 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2692 || df_regs_ever_live_p (regno
))))
2693 /* Do not emit code for auto saved regs. */
2695 && !firq_auto_save_p
)
2700 /* Return true if the return address must be saved in the current function,
2701 otherwise return false. */
2704 arc_must_save_return_addr (struct function
*func
)
2706 if (func
->machine
->frame_info
.save_return_addr
)
2712 /* Return non-zero if there are registers to be saved or loaded using
2713 millicode thunks. We can only use consecutive sequences starting
2714 with r13, and not going beyond r25.
2715 GMASK is a bitmask of registers to save. This function sets
2716 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2717 of registers to be saved / restored with a millicode call. */
2720 arc_compute_millicode_save_restore_regs (uint64_t gmask
,
2721 struct arc_frame_info
*frame
)
2725 int start_reg
= 13, end_reg
= 25;
2727 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
2729 end_reg
= regno
- 1;
2730 /* There is no point in using millicode thunks if we don't save/restore
2731 at least three registers. For non-leaf functions we also have the
2733 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2735 frame
->millicode_start_reg
= 13;
2736 frame
->millicode_end_reg
= regno
- 1;
2742 /* Return the bytes needed to compute the frame pointer from the
2743 current stack pointer. */
2746 arc_compute_frame_size (void)
2749 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2750 unsigned int reg_size
;
2752 struct arc_frame_info
*frame_info
;
2754 unsigned int extra_plus_reg_size
;
2755 unsigned int extra_plus_reg_size_aligned
;
2756 unsigned int fn_type
= arc_compute_function_type (cfun
);
2758 /* The answer might already be known. */
2759 if (cfun
->machine
->frame_info
.initialized
)
2760 return cfun
->machine
->frame_info
.total_size
;
2762 frame_info
= &cfun
->machine
->frame_info
;
2763 size
= ARC_STACK_ALIGN (get_frame_size ());
2765 /* 1) Size of locals and temporaries. */
2768 /* 2) Size of outgoing arguments. */
2769 args_size
= crtl
->outgoing_args_size
;
2771 /* 3) Calculate space needed for saved registers.
2772 ??? We ignore the extension registers for now. */
2774 /* See if this is an interrupt handler. Call used registers must be saved
2780 /* The last 4 regs are special, avoid them. */
2781 for (regno
= 0; regno
<= (GMASK_LEN
- 4); regno
++)
2783 if (arc_must_save_register (regno
, cfun
, false))
2785 reg_size
+= UNITS_PER_WORD
;
2786 gmask
|= 1ULL << regno
;
2790 /* In a frame that calls __builtin_eh_return two data registers are
2791 used to pass values back to the exception handler.
2793 Ensure that these registers are spilled to the stack so that the
2794 exception throw code can find them, and update the saved values.
2795 The handling code will then consume these reloaded values to
2796 handle the exception. */
2797 if (crtl
->calls_eh_return
)
2798 for (regno
= 0; EH_RETURN_DATA_REGNO (regno
) != INVALID_REGNUM
; regno
++)
2800 reg_size
+= UNITS_PER_WORD
;
2801 gmask
|= 1ULL << regno
;
2804 /* Check if we need to save the return address. */
2805 frame_info
->save_return_addr
= (!crtl
->is_leaf
2806 || df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2807 || crtl
->calls_eh_return
);
2809 /* Saving blink reg for millicode thunk calls. */
2810 if (TARGET_MILLICODE_THUNK_SET
2811 && !ARC_INTERRUPT_P (fn_type
)
2812 && !crtl
->calls_eh_return
)
2814 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2815 frame_info
->save_return_addr
= true;
2818 /* Save lp_count, lp_start and lp_end. */
2819 if (arc_lpcwidth
!= 0 && arc_must_save_register (LP_COUNT
, cfun
, true))
2820 reg_size
+= UNITS_PER_WORD
* 3;
2822 /* Check for the special R40-R44 regs used by FPX extension. */
2823 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R41_REG
: R40_REG
,
2825 reg_size
+= UNITS_PER_WORD
* 2;
2826 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R43_REG
: R42_REG
,
2828 reg_size
+= UNITS_PER_WORD
* 2;
2830 /* Check if R58 is used. */
2831 if (arc_must_save_register (R58_REG
, cfun
, true))
2832 reg_size
+= UNITS_PER_WORD
* 2;
2834 /* 4) Calculate extra size made up of the blink + fp size. */
2836 if (arc_must_save_return_addr (cfun
))
2838 /* Add FP size only when it is not autosaved. */
2839 if (arc_frame_pointer_needed ()
2840 && !ARC_AUTOFP_IRQ_P (fn_type
))
2843 /* 5) Space for variable arguments passed in registers */
2844 pretend_size
= crtl
->args
.pretend_args_size
;
2846 /* Ensure everything before the locals is aligned appropriately. */
2847 extra_plus_reg_size
= extra_size
+ reg_size
;
2848 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN (extra_plus_reg_size
);
2849 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2851 /* Compute total frame size. */
2852 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2854 /* It used to be the case that the alignment was forced at this
2855 point. However, that is dangerous, calculations based on
2856 total_size would be wrong. Given that this has never cropped up
2857 as an issue I've changed this to an assert for now. */
2858 gcc_assert (total_size
== ARC_STACK_ALIGN (total_size
));
2860 /* Save computed information. */
2861 frame_info
->total_size
= total_size
;
2862 frame_info
->extra_size
= extra_size
;
2863 frame_info
->pretend_size
= pretend_size
;
2864 frame_info
->var_size
= var_size
;
2865 frame_info
->args_size
= args_size
;
2866 frame_info
->reg_size
= reg_size
;
2867 frame_info
->gmask
= gmask
;
2868 frame_info
->initialized
= reload_completed
;
2870 /* Ok, we're done. */
2874 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2878 arc_dwarf_emit_irq_save_regs (void)
2880 rtx tmp
, par
, insn
, reg
;
2883 par
= gen_rtx_SEQUENCE (VOIDmode
,
2884 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2885 + irq_ctrl_saved
.irq_save_blink
2886 + irq_ctrl_saved
.irq_save_lpcount
2889 /* Build the stack adjustment note for unwind info. */
2891 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2892 + irq_ctrl_saved
.irq_save_blink
2893 + irq_ctrl_saved
.irq_save_lpcount
);
2894 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2895 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2896 RTX_FRAME_RELATED_P (tmp
) = 1;
2897 XVECEXP (par
, 0, j
++) = tmp
;
2899 offset
-= UNITS_PER_WORD
;
2901 /* 1st goes LP_COUNT. */
2902 if (irq_ctrl_saved
.irq_save_lpcount
)
2904 reg
= gen_rtx_REG (SImode
, 60);
2905 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2906 tmp
= gen_frame_mem (SImode
, tmp
);
2907 tmp
= gen_rtx_SET (tmp
, reg
);
2908 RTX_FRAME_RELATED_P (tmp
) = 1;
2909 XVECEXP (par
, 0, j
++) = tmp
;
2910 offset
-= UNITS_PER_WORD
;
2913 /* 2nd goes BLINK. */
2914 if (irq_ctrl_saved
.irq_save_blink
)
2916 reg
= gen_rtx_REG (SImode
, 31);
2917 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2918 tmp
= gen_frame_mem (SImode
, tmp
);
2919 tmp
= gen_rtx_SET (tmp
, reg
);
2920 RTX_FRAME_RELATED_P (tmp
) = 1;
2921 XVECEXP (par
, 0, j
++) = tmp
;
2922 offset
-= UNITS_PER_WORD
;
2925 /* Build the parallel of the remaining registers recorded as saved
2927 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
2929 reg
= gen_rtx_REG (SImode
, i
);
2930 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2931 tmp
= gen_frame_mem (SImode
, tmp
);
2932 tmp
= gen_rtx_SET (tmp
, reg
);
2933 RTX_FRAME_RELATED_P (tmp
) = 1;
2934 XVECEXP (par
, 0, j
++) = tmp
;
2935 offset
-= UNITS_PER_WORD
;
2938 /* Dummy insn used to anchor the dwarf info. */
2939 insn
= emit_insn (gen_stack_irq_dwarf());
2940 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
2941 RTX_FRAME_RELATED_P (insn
) = 1;
2944 /* Helper for prologue: emit frame store with pre_modify or pre_dec to
2945 save register REG on stack. An initial offset OFFSET can be passed
2949 frame_save_reg (rtx reg
, HOST_WIDE_INT offset
)
2955 rtx tmp
= plus_constant (Pmode
, stack_pointer_rtx
,
2956 offset
- GET_MODE_SIZE (GET_MODE (reg
)));
2957 addr
= gen_frame_mem (GET_MODE (reg
),
2958 gen_rtx_PRE_MODIFY (Pmode
,
2963 addr
= gen_frame_mem (GET_MODE (reg
), gen_rtx_PRE_DEC (Pmode
,
2964 stack_pointer_rtx
));
2965 frame_move_inc (addr
, reg
, stack_pointer_rtx
, 0);
2967 return GET_MODE_SIZE (GET_MODE (reg
)) - offset
;
2970 /* Helper used when saving AUX regs during ISR. */
2975 rtx stkslot
= gen_rtx_MEM (GET_MODE (reg
), gen_rtx_PRE_DEC (Pmode
,
2976 stack_pointer_rtx
));
2977 rtx insn
= emit_move_insn (stkslot
, reg
);
2978 RTX_FRAME_RELATED_P (insn
) = 1;
2979 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
2980 gen_rtx_SET (stack_pointer_rtx
,
2981 plus_constant (Pmode
, stack_pointer_rtx
,
2982 -GET_MODE_SIZE (GET_MODE (reg
)))));
2983 return GET_MODE_SIZE (GET_MODE (reg
));
2986 /* Helper for epilogue: emit frame load with post_modify or post_inc
2987 to restore register REG from stack. The initial offset is passed
2991 frame_restore_reg (rtx reg
, HOST_WIDE_INT offset
)
2997 rtx tmp
= plus_constant (Pmode
, stack_pointer_rtx
,
2998 offset
+ GET_MODE_SIZE (GET_MODE (reg
)));
2999 addr
= gen_frame_mem (GET_MODE (reg
),
3000 gen_rtx_POST_MODIFY (Pmode
,
3005 addr
= gen_frame_mem (GET_MODE (reg
), gen_rtx_POST_INC (Pmode
,
3006 stack_pointer_rtx
));
3007 insn
= frame_move_inc (reg
, addr
, stack_pointer_rtx
, 0);
3008 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3010 if (reg
== hard_frame_pointer_rtx
)
3011 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3012 plus_constant (Pmode
, stack_pointer_rtx
,
3013 GET_MODE_SIZE (GET_MODE (reg
)) + offset
));
3015 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3016 gen_rtx_SET (stack_pointer_rtx
,
3017 plus_constant (Pmode
, stack_pointer_rtx
,
3018 GET_MODE_SIZE (GET_MODE (reg
))
3021 return GET_MODE_SIZE (GET_MODE (reg
)) + offset
;
3024 /* Helper used when restoring AUX regs during ISR. */
3029 rtx stkslot
= gen_rtx_MEM (GET_MODE (reg
), gen_rtx_POST_INC (Pmode
,
3030 stack_pointer_rtx
));
3031 rtx insn
= emit_move_insn (reg
, stkslot
);
3032 RTX_FRAME_RELATED_P (insn
) = 1;
3033 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3034 gen_rtx_SET (stack_pointer_rtx
,
3035 plus_constant (Pmode
, stack_pointer_rtx
,
3036 GET_MODE_SIZE (GET_MODE (reg
)))));
3037 return GET_MODE_SIZE (GET_MODE (reg
));
3040 /* Check if we have a continous range to be save/restored with the
3041 help of enter/leave instructions. A vaild register range starts
3042 from $r13 and is up to (including) $r26. */
3045 arc_enter_leave_p (uint64_t gmask
)
3048 unsigned int rmask
= 0;
3053 for (regno
= ENTER_LEAVE_START_REG
;
3054 regno
<= ENTER_LEAVE_END_REG
&& (gmask
& (1ULL << regno
)); regno
++)
3055 rmask
|= 1ULL << regno
;
3063 /* ARC's prologue, save any needed call-saved regs (and call-used if
3064 this is an interrupt handler) for ARCompact ISA, using ST/STD
3068 arc_save_callee_saves (uint64_t gmask
,
3071 HOST_WIDE_INT offset
,
3075 int frame_allocated
= 0;
3078 /* The home-grown ABI says link register is saved first. */
3081 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3082 frame_allocated
+= frame_save_reg (reg
, offset
);
3086 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3088 for (i
= GMASK_LEN
; i
>= 0; i
--)
3090 machine_mode save_mode
= SImode
;
3093 && ((i
- 1) % 2 == 0)
3094 && ((gmask
& (1ULL << i
)) != 0)
3095 && ((gmask
& (1ULL << (i
- 1))) != 0))
3100 else if ((gmask
& (1ULL << i
)) == 0)
3103 reg
= gen_rtx_REG (save_mode
, i
);
3104 frame_allocated
+= frame_save_reg (reg
, offset
);
3108 /* Save frame pointer if needed. First save the FP on stack, if not
3109 autosaved. Unfortunately, I cannot add it to gmask and use the
3110 above loop to save fp because our ABI states fp goes aftert all
3111 registers are saved. */
3114 frame_allocated
+= frame_save_reg (hard_frame_pointer_rtx
, offset
);
3118 /* Emit mov fp,sp. */
3120 frame_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
3122 return frame_allocated
;
3125 /* ARC's epilogue, restore any required call-saved regs (and call-used
3126 if it is for an interrupt handler) using LD/LDD instructions. */
3129 arc_restore_callee_saves (uint64_t gmask
,
3132 HOST_WIDE_INT offset
,
3133 HOST_WIDE_INT allocated
)
3136 int frame_deallocated
= 0;
3137 HOST_WIDE_INT offs
= cfun
->machine
->frame_info
.reg_size
;
3138 unsigned int fn_type
= arc_compute_function_type (cfun
);
3139 bool early_blink_restore
;
3142 /* Emit mov fp,sp. */
3143 if (arc_frame_pointer_needed () && offset
)
3145 frame_move (stack_pointer_rtx
, hard_frame_pointer_rtx
);
3146 frame_deallocated
+= offset
;
3152 /* Any offset is taken care by previous if-statement. */
3153 gcc_assert (offset
== 0);
3154 frame_deallocated
+= frame_restore_reg (hard_frame_pointer_rtx
, 0);
3159 /* No $fp involved, we need to do an add to set the $sp to the
3160 location of the first register. */
3161 frame_stack_add (offset
);
3162 frame_deallocated
+= offset
;
3166 /* When we do not optimize for size or we aren't in an interrupt,
3167 restore first blink. */
3168 early_blink_restore
= restore_blink
&& !optimize_size
&& offs
3169 && !ARC_INTERRUPT_P (fn_type
);
3170 if (early_blink_restore
)
3172 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, offs
);
3173 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3174 rtx insn
= frame_move_inc (reg
, gen_frame_mem (Pmode
, addr
),
3175 stack_pointer_rtx
, NULL_RTX
);
3176 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3177 restore_blink
= false;
3180 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3182 for (i
= 0; i
<= GMASK_LEN
; i
++)
3184 machine_mode restore_mode
= SImode
;
3188 && ((gmask
& (1ULL << i
)) != 0)
3189 && ((gmask
& (1ULL << (i
+ 1))) != 0))
3190 restore_mode
= DImode
;
3191 else if ((gmask
& (1ULL << i
)) == 0)
3194 reg
= gen_rtx_REG (restore_mode
, i
);
3196 switch (restore_mode
)
3199 if ((GMASK_LEN
- __builtin_clzll (gmask
)) == (i
+ 1)
3200 && early_blink_restore
)
3204 if ((GMASK_LEN
- __builtin_clzll (gmask
)) == i
3205 && early_blink_restore
)
3211 frame_deallocated
+= frame_restore_reg (reg
, offs
);
3214 if (restore_mode
== DImode
)
3220 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3221 frame_deallocated
+= frame_restore_reg (reg
, allocated
3223 /* Consider as well the
3229 return frame_deallocated
;
3232 /* ARC prologue, save the registers using enter instruction. Leave
3233 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3237 arc_save_callee_enter (uint64_t gmask
,
3240 HOST_WIDE_INT offset
)
3242 int start_reg
= ENTER_LEAVE_START_REG
;
3243 int end_reg
= ENTER_LEAVE_END_REG
;
3244 int regno
, indx
, off
, nregs
;
3246 int frame_allocated
= 0;
3248 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3251 end_reg
= regno
- 1;
3252 nregs
= end_reg
- start_reg
+ 1;
3253 nregs
+= save_blink
? 1 : 0;
3254 nregs
+= save_fp
? 1 : 0;
3257 frame_stack_add (offset
);
3259 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ (save_fp
? 1 : 0)
3263 reg
= gen_rtx_SET (stack_pointer_rtx
,
3264 plus_constant (Pmode
,
3266 -nregs
* UNITS_PER_WORD
));
3267 RTX_FRAME_RELATED_P (reg
) = 1;
3268 XVECEXP (insn
, 0, indx
++) = reg
;
3269 off
= nregs
* UNITS_PER_WORD
;
3273 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3274 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3277 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3278 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3279 off
-= UNITS_PER_WORD
;
3283 for (regno
= start_reg
;
3285 regno
++, indx
++, off
-= UNITS_PER_WORD
)
3287 reg
= gen_rtx_REG (SImode
, regno
);
3288 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3291 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3292 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3293 gmask
= gmask
& ~(1ULL << regno
);
3298 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3301 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, hard_frame_pointer_rtx
);
3302 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3303 off
-= UNITS_PER_WORD
;
3305 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (hard_frame_pointer_rtx
,
3307 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3311 gcc_assert (off
== 0);
3312 insn
= frame_insn (insn
);
3314 add_reg_note (insn
, REG_INC
, stack_pointer_rtx
);
3316 frame_allocated
= nregs
* UNITS_PER_WORD
;
3318 /* offset is a negative number, make sure we add it. */
3319 return frame_allocated
- offset
;
3322 /* ARC epilogue, restore the registers using leave instruction. An
3323 initial offset is passed in OFFSET. Besides restoring an register
3324 range, leave can also restore $blink (RESTORE_BLINK), or $fp
3325 (RESTORE_FP), and can automatic return (RETURN_P). */
3328 arc_restore_callee_leave (uint64_t gmask
,
3332 HOST_WIDE_INT offset
)
3334 int start_reg
= ENTER_LEAVE_START_REG
;
3335 int end_reg
= ENTER_LEAVE_END_REG
;
3336 int regno
, indx
, off
, nregs
;
3338 int frame_allocated
= 0;
3340 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3343 end_reg
= regno
- 1;
3344 nregs
= end_reg
- start_reg
+ 1;
3345 nregs
+= restore_blink
? 1 : 0;
3346 nregs
+= restore_fp
? 1 : 0;
3348 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ 1
3349 + (return_p
? 1 : 0)));
3353 XVECEXP (insn
, 0, indx
++) = ret_rtx
;
3357 /* I cannot emit set (sp, fp) here as cselib expects a single sp
3358 set and not two. Thus, use the offset, and change sp adjust
3360 frame_allocated
+= offset
;
3363 if (offset
&& !restore_fp
)
3365 /* This add is only emmited when we do not restore fp with leave
3367 frame_stack_add (offset
);
3368 frame_allocated
+= offset
;
3372 reg
= gen_rtx_SET (stack_pointer_rtx
,
3373 plus_constant (Pmode
,
3375 offset
+ nregs
* UNITS_PER_WORD
));
3376 RTX_FRAME_RELATED_P (reg
) = 1;
3377 XVECEXP (insn
, 0, indx
++) = reg
;
3378 off
= nregs
* UNITS_PER_WORD
;
3382 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3383 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3386 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3387 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3388 off
-= UNITS_PER_WORD
;
3391 for (regno
= start_reg
;
3393 regno
++, indx
++, off
-= UNITS_PER_WORD
)
3395 reg
= gen_rtx_REG (SImode
, regno
);
3396 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3399 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3400 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3401 gmask
= gmask
& ~(1ULL << regno
);
3406 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3409 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (hard_frame_pointer_rtx
, mem
);
3410 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3411 off
-= UNITS_PER_WORD
;
3414 gcc_assert (off
== 0);
3417 insn
= emit_jump_insn (insn
);
3418 RTX_FRAME_RELATED_P (insn
) = 1;
3421 insn
= frame_insn (insn
);
3423 add_reg_note (insn
, REG_INC
, stack_pointer_rtx
);
3425 /* Dwarf related info. */
3428 add_reg_note (insn
, REG_CFA_RESTORE
, hard_frame_pointer_rtx
);
3429 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3430 plus_constant (Pmode
, stack_pointer_rtx
,
3431 offset
+ nregs
* UNITS_PER_WORD
));
3435 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3436 gen_rtx_SET (stack_pointer_rtx
,
3437 plus_constant (Pmode
, stack_pointer_rtx
,
3438 nregs
* UNITS_PER_WORD
)));
3441 add_reg_note (insn
, REG_CFA_RESTORE
,
3442 gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3443 for (regno
= start_reg
; regno
<= end_reg
; regno
++)
3444 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, regno
));
3446 frame_allocated
+= nregs
* UNITS_PER_WORD
;
3448 return frame_allocated
;
3451 /* Millicode thunks implementation:
3452 Generates calls to millicodes for registers starting from r13 to r25
3453 Present Limitations:
3454 - Only one range supported. The remaining regs will have the ordinary
3455 st and ld instructions for store and loads. Hence a gmask asking
3456 to store r13-14, r16-r25 will only generate calls to store and
3457 load r13 to r14 while store and load insns will be generated for
3458 r16 to r25 in the prologue and epilogue respectively.
3460 - Presently library only supports register ranges starting from r13.
3464 arc_save_callee_milli (uint64_t gmask
,
3467 HOST_WIDE_INT offset
,
3468 HOST_WIDE_INT reg_size
)
3472 int regno
, indx
, off
, nregs
;
3474 int frame_allocated
= 0;
3476 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3479 end_reg
= regno
- 1;
3480 nregs
= end_reg
- start_reg
+ 1;
3481 gcc_assert (end_reg
> 14);
3484 /* Allocate space on stack for the registers, and take into account
3485 also the initial offset. The registers will be saved using
3486 offsets. N.B. OFFSET is a negative number. */
3489 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3490 frame_allocated
+= frame_save_reg (reg
, offset
);
3494 if (reg_size
|| offset
)
3496 frame_stack_add (offset
- reg_size
);
3497 frame_allocated
+= nregs
* UNITS_PER_WORD
- offset
;
3501 /* Start generate millicode call. */
3502 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ 1));
3505 /* This is a call, we clobber blink. */
3506 XVECEXP (insn
, 0, nregs
) =
3507 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3509 for (regno
= start_reg
, indx
= 0, off
= 0;
3511 regno
++, indx
++, off
+= UNITS_PER_WORD
)
3513 reg
= gen_rtx_REG (SImode
, regno
);
3514 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3517 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3518 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3519 gmask
= gmask
& ~(1ULL << regno
);
3521 insn
= frame_insn (insn
);
3523 /* Add DWARF info. */
3524 for (regno
= start_reg
, off
= 0;
3526 regno
++, off
+= UNITS_PER_WORD
)
3528 reg
= gen_rtx_REG (SImode
, regno
);
3529 mem
= gen_rtx_MEM (SImode
, plus_constant (Pmode
,
3530 stack_pointer_rtx
, off
));
3531 add_reg_note (insn
, REG_CFA_OFFSET
, gen_rtx_SET (mem
, reg
));
3535 /* In the case of millicode thunk, we need to restore the
3536 clobbered blink register. */
3537 if (arc_must_save_return_addr (cfun
))
3539 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
),
3541 plus_constant (Pmode
,
3546 /* Save remaining registers using st instructions. */
3547 for (regno
= 0; regno
<= GMASK_LEN
; regno
++)
3549 if ((gmask
& (1ULL << regno
)) == 0)
3552 reg
= gen_rtx_REG (SImode
, regno
);
3553 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3556 frame_move_inc (mem
, reg
, stack_pointer_rtx
, 0);
3557 frame_allocated
+= UNITS_PER_WORD
;
3558 off
+= UNITS_PER_WORD
;
3561 /* Save frame pointer if needed. First save the FP on stack, if not
3562 autosaved. Unfortunately, I cannot add it to gmask and use the
3563 above loop to save fp because our ABI states fp goes aftert all
3564 registers are saved. */
3566 frame_allocated
+= frame_save_reg (hard_frame_pointer_rtx
, offset
);
3568 /* Emit mov fp,sp. */
3569 if (arc_frame_pointer_needed ())
3570 frame_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
3572 return frame_allocated
;
3575 /* Like the previous function but restore. */
3578 arc_restore_callee_milli (uint64_t gmask
,
3582 HOST_WIDE_INT offset
)
3586 int regno
, indx
, off
, nregs
;
3588 int frame_allocated
= 0;
3590 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3593 end_reg
= regno
- 1;
3594 nregs
= end_reg
- start_reg
+ 1;
3595 gcc_assert (end_reg
> 14);
3597 /* Emit mov fp,sp. */
3598 if (arc_frame_pointer_needed () && offset
)
3600 frame_move (stack_pointer_rtx
, hard_frame_pointer_rtx
);
3601 frame_allocated
= offset
;
3606 frame_allocated
+= frame_restore_reg (hard_frame_pointer_rtx
, 0);
3610 /* No fp involved, hence, we need to adjust the sp via an
3612 frame_stack_add (offset
);
3613 frame_allocated
+= offset
;
3617 /* Start generate millicode call. */
3618 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc ((return_p
? 1 : 0)
3624 /* sibling call, the blink is restored with the help of the
3625 value held into r12. */
3626 reg
= gen_rtx_REG (Pmode
, 12);
3627 XVECEXP (insn
, 0, indx
++) = ret_rtx
;
3628 XVECEXP (insn
, 0, indx
++) =
3629 gen_rtx_SET (stack_pointer_rtx
,
3630 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, reg
));
3631 frame_allocated
+= UNITS_PER_WORD
;
3635 /* This is a call, we clobber blink. */
3636 XVECEXP (insn
, 0, nregs
) =
3637 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3640 for (regno
= start_reg
, off
= 0;
3642 regno
++, indx
++, off
+= UNITS_PER_WORD
)
3644 reg
= gen_rtx_REG (SImode
, regno
);
3645 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3648 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3649 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3650 gmask
= gmask
& ~(1ULL << regno
);
3653 /* Restore remaining registers using LD instructions. */
3654 for (regno
= 0; regno
<= GMASK_LEN
; regno
++)
3656 if ((gmask
& (1ULL << regno
)) == 0)
3659 reg
= gen_rtx_REG (SImode
, regno
);
3660 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3663 rtx tmp
= frame_move_inc (reg
, mem
, stack_pointer_rtx
, 0);
3664 add_reg_note (tmp
, REG_CFA_RESTORE
, reg
);
3665 off
+= UNITS_PER_WORD
;
3668 /* Emit millicode call. */
3671 reg
= gen_rtx_REG (Pmode
, 12);
3672 frame_insn (gen_rtx_SET (reg
, GEN_INT (off
)));
3673 frame_allocated
+= off
;
3674 insn
= emit_jump_insn (insn
);
3675 RTX_FRAME_RELATED_P (insn
) = 1;
3678 insn
= frame_insn (insn
);
3680 /* Add DWARF info. */
3681 for (regno
= start_reg
; regno
<= end_reg
; regno
++)
3683 reg
= gen_rtx_REG (SImode
, regno
);
3684 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3688 if (restore_blink
&& !return_p
)
3690 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3691 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, stack_pointer_rtx
,
3693 insn
= frame_insn (gen_rtx_SET (reg
, mem
));
3694 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3697 return frame_allocated
;
3700 /* Set up the stack and frame pointer (if desired) for the function. */
3703 arc_expand_prologue (void)
3706 uint64_t gmask
= cfun
->machine
->frame_info
.gmask
;
3707 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
3708 unsigned int frame_size_to_allocate
;
3709 int first_offset
= 0;
3710 unsigned int fn_type
= arc_compute_function_type (cfun
);
3711 bool save_blink
= false;
3712 bool save_fp
= false;
3713 bool emit_move
= false;
3715 /* Naked functions don't have prologue. */
3716 if (ARC_NAKED_P (fn_type
))
3718 if (flag_stack_usage_info
)
3719 current_function_static_stack_size
= 0;
3723 /* Compute total frame size. */
3724 size
= arc_compute_frame_size ();
3726 if (flag_stack_usage_info
)
3727 current_function_static_stack_size
= size
;
3729 /* Keep track of frame size to be allocated. */
3730 frame_size_to_allocate
= size
;
3732 /* These cases shouldn't happen. Catch them now. */
3733 gcc_assert (!(size
== 0 && gmask
));
3735 /* Allocate space for register arguments if this is a variadic function. */
3736 if (frame
->pretend_size
!= 0)
3737 first_offset
= -frame
->pretend_size
;
3739 /* IRQ using automatic save mechanism will save the register before
3741 if (ARC_AUTO_IRQ_P (fn_type
)
3742 && !ARC_FAST_INTERRUPT_P (fn_type
))
3744 frame_stack_add (first_offset
);
3746 arc_dwarf_emit_irq_save_regs ();
3749 save_blink
= arc_must_save_return_addr (cfun
)
3750 && !ARC_AUTOBLINK_IRQ_P (fn_type
);
3751 save_fp
= arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type
)
3752 && !ARC_INTERRUPT_P (fn_type
);
3753 emit_move
= arc_frame_pointer_needed () && !ARC_INTERRUPT_P (fn_type
);
3755 /* Use enter/leave only for non-interrupt functions. */
3756 if (TARGET_CODE_DENSITY
3757 && TARGET_CODE_DENSITY_FRAME
3758 && !ARC_AUTOFP_IRQ_P (fn_type
)
3759 && !ARC_AUTOBLINK_IRQ_P (fn_type
)
3760 && !ARC_INTERRUPT_P (fn_type
)
3761 && arc_enter_leave_p (gmask
))
3762 frame_size_to_allocate
-= arc_save_callee_enter (gmask
, save_blink
,
3765 else if (frame
->millicode_end_reg
> 14)
3766 frame_size_to_allocate
-= arc_save_callee_milli (gmask
, save_blink
,
3771 frame_size_to_allocate
-= arc_save_callee_saves (gmask
, save_blink
, save_fp
,
3772 first_offset
, emit_move
);
3774 /* Check if we need to save the ZOL machinery. */
3775 if (arc_lpcwidth
!= 0 && arc_must_save_register (LP_COUNT
, cfun
, true))
3777 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3778 emit_insn (gen_rtx_SET (reg0
,
3779 gen_rtx_UNSPEC_VOLATILE
3780 (Pmode
, gen_rtvec (1, GEN_INT (AUX_LP_START
)),
3782 frame_size_to_allocate
-= push_reg (reg0
);
3783 emit_insn (gen_rtx_SET (reg0
,
3784 gen_rtx_UNSPEC_VOLATILE
3785 (Pmode
, gen_rtvec (1, GEN_INT (AUX_LP_END
)),
3787 frame_size_to_allocate
-= push_reg (reg0
);
3788 emit_move_insn (reg0
, gen_rtx_REG (SImode
, LP_COUNT
));
3789 frame_size_to_allocate
-= push_reg (reg0
);
3792 /* Save AUX regs used by FPX machinery. */
3793 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R41_REG
: R40_REG
,
3796 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3799 for (i
= 0; i
< 4; i
++)
3801 emit_insn (gen_rtx_SET (reg0
,
3802 gen_rtx_UNSPEC_VOLATILE
3803 (Pmode
, gen_rtvec (1, GEN_INT (AUX_DPFP_START
3806 frame_size_to_allocate
-= push_reg (reg0
);
3810 /* Save accumulator registers. */
3811 if (arc_must_save_register (R58_REG
, cfun
, true))
3812 frame_size_to_allocate
-= arc_save_callee_saves (3ULL << 58,
3813 false, false, 0, false);
3815 if (arc_frame_pointer_needed () && ARC_INTERRUPT_P (fn_type
))
3817 /* Just save fp at the end of the saving context. */
3818 frame_size_to_allocate
-=
3819 arc_save_callee_saves (0, false, !ARC_AUTOFP_IRQ_P (fn_type
), 0, true);
3822 /* Allocate the stack frame. */
3823 if (frame_size_to_allocate
> 0)
3824 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3826 /* Emit a blockage to avoid delay slot scheduling. */
3827 emit_insn (gen_blockage ());
3830 /* Return the register number of the register holding the return address
3831 for a function of type TYPE. */
3834 arc_return_address_register (unsigned int fn_type
)
3838 if (ARC_INTERRUPT_P (fn_type
))
3840 if ((fn_type
& (ARC_FUNCTION_ILINK1
| ARC_FUNCTION_FIRQ
)) != 0)
3842 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
3847 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
3848 regno
= RETURN_ADDR_REGNUM
;
3850 gcc_assert (regno
!= 0);
3854 /* Do any necessary cleanup after a function to restore stack, frame,
3858 arc_expand_epilogue (int sibcall_p
)
3861 unsigned int fn_type
= arc_compute_function_type (cfun
);
3862 unsigned int size_to_deallocate
;
3864 int can_trust_sp_p
= !cfun
->calls_alloca
;
3866 bool restore_fp
= arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type
);
3867 bool restore_blink
= arc_must_save_return_addr (cfun
)
3868 && !ARC_AUTOBLINK_IRQ_P (fn_type
);
3869 uint64_t gmask
= cfun
->machine
->frame_info
.gmask
;
3870 bool return_p
= !sibcall_p
&& fn_type
== ARC_FUNCTION_NORMAL
3871 && !cfun
->machine
->frame_info
.pretend_size
;
3872 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
3874 /* Naked functions don't have epilogue. */
3875 if (ARC_NAKED_P (fn_type
))
3878 size
= arc_compute_frame_size ();
3879 size_to_deallocate
= size
;
3881 first_offset
= size
- (frame
->pretend_size
+ frame
->reg_size
3882 + frame
->extra_size
);
3884 if (!can_trust_sp_p
)
3885 gcc_assert (arc_frame_pointer_needed ());
3887 /* Emit a blockage to avoid/flush all pending sp operations. */
3889 emit_insn (gen_blockage ());
3891 if (ARC_INTERRUPT_P (fn_type
))
3893 /* We need to restore FP before any SP operation in an
3895 size_to_deallocate
-= arc_restore_callee_saves (0, false,
3898 size_to_deallocate
);
3903 /* Restore accumulator registers. */
3904 if (arc_must_save_register (R58_REG
, cfun
, true))
3907 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3908 rtx reg1
= gen_rtx_REG (SImode
, R1_REG
);
3909 size_to_deallocate
-= pop_reg (reg0
);
3910 size_to_deallocate
-= pop_reg (reg1
);
3912 insn
= emit_insn (gen_mulu64 (reg0
, const1_rtx
));
3913 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, R58_REG
));
3914 RTX_FRAME_RELATED_P (insn
) = 1;
3915 emit_insn (gen_arc600_stall ());
3916 insn
= emit_insn (gen_rtx_UNSPEC_VOLATILE
3917 (VOIDmode
, gen_rtvec (2, reg1
, GEN_INT (AUX_MULHI
)),
3919 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, R59_REG
));
3920 RTX_FRAME_RELATED_P (insn
) = 1;
3923 /* Restore AUX-regs used by FPX machinery. */
3924 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R41_REG
: R40_REG
,
3927 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3930 for (i
= 0; i
< 4; i
++)
3932 size_to_deallocate
-= pop_reg (reg0
);
3933 emit_insn (gen_rtx_UNSPEC_VOLATILE
3934 (VOIDmode
, gen_rtvec (2, reg0
, GEN_INT (AUX_DPFP_START
3940 /* Check if we need to restore the ZOL machinery. */
3941 if (arc_lpcwidth
!=0 && arc_must_save_register (LP_COUNT
, cfun
, true))
3943 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3945 size_to_deallocate
-= pop_reg (reg0
);
3946 emit_move_insn (gen_rtx_REG (SImode
, LP_COUNT
), reg0
);
3948 size_to_deallocate
-= pop_reg (reg0
);
3949 emit_insn (gen_rtx_UNSPEC_VOLATILE
3950 (VOIDmode
, gen_rtvec (2, reg0
, GEN_INT (AUX_LP_END
)),
3953 size_to_deallocate
-= pop_reg (reg0
);
3954 emit_insn (gen_rtx_UNSPEC_VOLATILE
3955 (VOIDmode
, gen_rtvec (2, reg0
, GEN_INT (AUX_LP_START
)),
3959 if (TARGET_CODE_DENSITY
3960 && TARGET_CODE_DENSITY_FRAME
3961 && !ARC_AUTOFP_IRQ_P (fn_type
)
3962 && !ARC_AUTOBLINK_IRQ_P (fn_type
)
3963 && !ARC_INTERRUPT_P (fn_type
)
3964 && arc_enter_leave_p (gmask
))
3966 /* Using leave instruction. */
3967 size_to_deallocate
-= arc_restore_callee_leave (gmask
, restore_blink
,
3973 gcc_assert (size_to_deallocate
== 0);
3977 else if (frame
->millicode_end_reg
> 14)
3979 /* Using millicode calls. */
3980 size_to_deallocate
-= arc_restore_callee_milli (gmask
, restore_blink
,
3986 gcc_assert (size_to_deallocate
== 0);
3991 size_to_deallocate
-= arc_restore_callee_saves (gmask
, restore_blink
,
3994 size_to_deallocate
);
3996 /* Keep track of how much of the stack pointer we've restored. It
3997 makes the following a lot more readable. */
3998 restored
= size
- size_to_deallocate
;
4000 if (size
> restored
)
4001 frame_stack_add (size
- restored
);
4003 /* For frames that use __builtin_eh_return, the register defined by
4004 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
4005 On eh_return paths however, the register is set to the value that
4006 should be added to the stack pointer in order to restore the
4007 correct stack pointer for the exception handling frame.
4009 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
4010 this onto the stack for eh_return frames. */
4011 if (crtl
->calls_eh_return
)
4012 emit_insn (gen_add2_insn (stack_pointer_rtx
,
4013 EH_RETURN_STACKADJ_RTX
));
4015 /* Emit the return instruction. */
4016 if (ARC_INTERRUPT_P (fn_type
))
4018 rtx ra
= gen_rtx_REG (Pmode
, arc_return_address_register (fn_type
));
4021 emit_jump_insn (gen_rtie ());
4022 else if (TARGET_ARC700
)
4023 emit_jump_insn (gen_rtie ());
4025 emit_jump_insn (gen_arc600_rtie (ra
));
4027 else if (sibcall_p
== FALSE
)
4028 emit_jump_insn (gen_simple_return ());
4031 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable
4032 construct to match either enter or leave instruction. Which one
4033 which is selected by PUSH_P argument. */
4036 arc_check_multi (rtx op
, bool push_p
)
4038 HOST_WIDE_INT len
= XVECLEN (op
, 0);
4039 unsigned int regno
, i
, start
;
4040 unsigned int memp
= push_p
? 0 : 1;
4047 elt
= XVECEXP (op
, 0, 0);
4048 if (!push_p
&& GET_CODE (elt
) == RETURN
)
4051 for (i
= start
, regno
= ENTER_LEAVE_START_REG
; i
< len
; i
++, regno
++)
4053 rtx elt
= XVECEXP (op
, 0, i
);
4056 if (GET_CODE (elt
) != SET
)
4058 mem
= XEXP (elt
, memp
);
4059 reg
= XEXP (elt
, 1 - memp
);
4065 /* Check for blink. */
4066 if (REGNO (reg
) == RETURN_ADDR_REGNUM
4069 else if (REGNO (reg
) == HARD_FRAME_POINTER_REGNUM
)
4071 else if (REGNO (reg
) != regno
)
4074 addr
= XEXP (mem
, 0);
4075 if (GET_CODE (addr
) == PLUS
)
4077 if (!rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
4078 || !CONST_INT_P (XEXP (addr
, 1)))
4083 if (!rtx_equal_p (stack_pointer_rtx
, addr
))
4090 /* Return rtx for the location of the return address on the stack,
4091 suitable for use in __builtin_eh_return. The new return address
4092 will be written to this location in order to redirect the return to
4093 the exception handler. Our ABI says the blink is pushed first on
4094 stack followed by an unknown number of register saves, and finally
4095 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the
4096 stack is not finalized. */
4099 arc_eh_return_address_location (rtx source
)
4103 struct arc_frame_info
*afi
;
4105 arc_compute_frame_size ();
4106 afi
= &cfun
->machine
->frame_info
;
4108 gcc_assert (crtl
->calls_eh_return
);
4109 gcc_assert (afi
->save_return_addr
);
4110 gcc_assert (afi
->extra_size
>= 4);
4112 /* The '-4' removes the size of the return address, which is
4113 included in the 'extra_size' field. */
4114 offset
= afi
->reg_size
+ afi
->extra_size
- 4;
4115 mem
= gen_frame_mem (Pmode
,
4116 plus_constant (Pmode
, hard_frame_pointer_rtx
, offset
));
4118 /* The following should not be needed, and is, really a hack. The
4119 issue being worked around here is that the DSE (Dead Store
4120 Elimination) pass will remove this write to the stack as it sees
4121 a single store and no corresponding read. The read however
4122 occurs in the epilogue code, which is not added into the function
4123 rtl until a later pass. So, at the time of DSE, the decision to
4124 remove this store seems perfectly sensible. Marking the memory
4125 address as volatile obviously has the effect of preventing DSE
4126 from removing the store. */
4127 MEM_VOLATILE_P (mem
) = true;
4128 emit_move_insn (mem
, source
);
4133 /* Helper to generate unspec constant. */
4136 arc_unspec_offset (rtx loc
, int unspec
)
4138 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
4142 /* Predicate for pre-reload splitters with associated instructions,
4143 which can match any time before the split1 pass (usually combine),
4144 then are unconditionally split in that pass and should not be
4145 matched again afterwards. */
4148 arc_pre_reload_split (void)
4150 return (can_create_pseudo_p ()
4151 && !(cfun
->curr_properties
& PROP_rtl_split_insns
));
4154 /* Output the assembler code for a zero-overhead loop doing a shift
4155 or rotate. We know OPERANDS[0] == OPERANDS[1], and the bit count
4159 output_shift_loop (enum rtx_code code
, rtx
*operands
)
4161 bool twice_p
= false;
4162 gcc_assert (GET_MODE (operands
[0]) == SImode
);
4164 if (GET_CODE (operands
[2]) != CONST_INT
)
4166 output_asm_insn ("and.f\tlp_count,%2,0x1f", operands
);
4167 output_asm_insn ("lpnz\t2f", operands
);
4171 int n
= INTVAL (operands
[2]) & 31;
4174 output_asm_insn ("mov\t%0,%1",operands
);
4178 if ((n
& 1) == 0 && code
!= ROTATE
)
4183 operands
[2] = GEN_INT (n
);
4184 output_asm_insn ("mov\tlp_count,%2", operands
);
4185 output_asm_insn ("lp\t2f", operands
);
4191 output_asm_insn ("add\t%0,%1,%1", operands
);
4193 output_asm_insn ("add\t%0,%1,%1", operands
);
4196 output_asm_insn ("asr\t%0,%1", operands
);
4198 output_asm_insn ("asr\t%0,%1", operands
);
4201 output_asm_insn ("lsr\t%0,%1", operands
);
4203 output_asm_insn ("lsr\t%0,%1", operands
);
4206 output_asm_insn ("ror\t%0,%1", operands
);
4208 output_asm_insn ("ror\t%0,%1", operands
);
4211 output_asm_insn ("add.f\t%0,%1,%1", operands
);
4212 output_asm_insn ("adc\t%0,%0,0", operands
);
4220 output_asm_insn ("nop", operands
);
4221 fprintf (asm_out_file
, "2:\t%s end single insn loop\n", ASM_COMMENT_START
);
4226 /* Split SImode left shift instruction. */
4228 arc_split_ashl (rtx
*operands
)
4230 if (CONST_INT_P (operands
[2]))
4232 int n
= INTVAL (operands
[2]) & 0x1f;
4236 emit_move_insn (operands
[0], operands
[1]);
4239 emit_insn (gen_ashlsi3_cnt1 (operands
[0], operands
[1]));
4241 emit_insn (gen_ashlsi3_cnt1 (operands
[0], operands
[0]));
4245 rtx zero
= gen_reg_rtx (SImode
);
4246 emit_move_insn (zero
, const0_rtx
);
4247 emit_insn (gen_add_shift (operands
[0], operands
[1],
4248 GEN_INT (3), zero
));
4249 for (n
-= 3; n
>= 3; n
-= 3)
4250 emit_insn (gen_add_shift (operands
[0], operands
[0],
4251 GEN_INT (3), zero
));
4253 emit_insn (gen_add_shift (operands
[0], operands
[0],
4256 emit_insn (gen_ashlsi3_cnt1 (operands
[0], operands
[0]));
4260 else if (n
>= 16 && n
<= 22 && TARGET_SWAP
&& TARGET_V2
)
4262 emit_insn (gen_ashlsi2_cnt16 (operands
[0], operands
[1]));
4265 operands
[1] = operands
[0];
4266 operands
[2] = GEN_INT (n
- 16);
4267 arc_split_ashl (operands
);
4277 emit_insn (gen_andsi3_i (operands
[0], operands
[1],
4279 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4282 emit_insn (gen_andsi3_i (operands
[0], operands
[1],
4284 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4287 emit_insn (gen_andsi3_i (operands
[0], operands
[1], const1_rtx
));
4288 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4293 emit_insn (gen_ashlsi3_loop (operands
[0], operands
[1], operands
[2]));
4296 /* Split SImode arithmetic right shift instruction. */
4298 arc_split_ashr (rtx
*operands
)
4300 if (CONST_INT_P (operands
[2]))
4302 int n
= INTVAL (operands
[2]) & 0x1f;
4307 emit_insn (gen_ashrsi3_cnt1 (operands
[0], operands
[1]));
4309 emit_insn (gen_ashrsi3_cnt1 (operands
[0], operands
[0]));
4312 emit_move_insn (operands
[0], operands
[1]);
4315 else if (n
>= 16 && n
<= 18 && TARGET_SWAP
)
4317 emit_insn (gen_rotrsi2_cnt16 (operands
[0], operands
[1]));
4318 emit_insn (gen_extendhisi2 (operands
[0],
4319 gen_lowpart (HImode
, operands
[0])));
4321 emit_insn (gen_ashrsi3_cnt1 (operands
[0], operands
[0]));
4326 rtx tmp
= gen_reg_rtx (SImode
);
4327 emit_insn (gen_add_f (tmp
, operands
[1], operands
[1]));
4328 emit_insn (gen_sbc (operands
[0], operands
[0], operands
[0]));
4329 emit_insn (gen_addsi_compare_2 (tmp
, tmp
));
4330 emit_insn (gen_adc (operands
[0], operands
[0], operands
[0]));
4335 emit_insn (gen_addsi_compare_2 (operands
[1], operands
[1]));
4336 emit_insn (gen_sbc (operands
[0], operands
[0], operands
[0]));
4341 emit_insn (gen_ashrsi3_loop (operands
[0], operands
[1], operands
[2]));
4344 /* Split SImode logical right shift instruction. */
4346 arc_split_lshr (rtx
*operands
)
4348 if (CONST_INT_P (operands
[2]))
4350 int n
= INTVAL (operands
[2]) & 0x1f;
4355 emit_insn (gen_lshrsi3_cnt1 (operands
[0], operands
[1]));
4357 emit_insn (gen_lshrsi3_cnt1 (operands
[0], operands
[0]));
4360 emit_move_insn (operands
[0], operands
[1]);
4363 else if (n
>= 16 && n
<= 19 && TARGET_SWAP
&& TARGET_V2
)
4365 emit_insn (gen_lshrsi2_cnt16 (operands
[0], operands
[1]));
4367 emit_insn (gen_lshrsi3_cnt1 (operands
[0], operands
[0]));
4372 rtx tmp
= gen_reg_rtx (SImode
);
4373 emit_insn (gen_add_f (tmp
, operands
[1], operands
[1]));
4374 emit_insn (gen_scc_ltu_cc_c (operands
[0]));
4375 emit_insn (gen_addsi_compare_2 (tmp
, tmp
));
4376 emit_insn (gen_adc (operands
[0], operands
[0], operands
[0]));
4381 emit_insn (gen_addsi_compare_2 (operands
[1], operands
[1]));
4382 emit_insn (gen_scc_ltu_cc_c (operands
[0]));
4387 emit_insn (gen_lshrsi3_loop (operands
[0], operands
[1], operands
[2]));
4390 /* Split SImode rotate left instruction. */
4392 arc_split_rotl (rtx
*operands
)
4394 if (CONST_INT_P (operands
[2]))
4396 int n
= INTVAL (operands
[2]) & 0x1f;
4401 emit_insn (gen_rotlsi3_cnt1 (operands
[0], operands
[1]));
4403 emit_insn (gen_rotlsi3_cnt1 (operands
[0], operands
[0]));
4406 emit_move_insn (operands
[0], operands
[1]);
4411 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[1]));
4413 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4416 else if (n
>= 13 && n
<= 16 && TARGET_SWAP
)
4418 emit_insn (gen_rotlsi2_cnt16 (operands
[0], operands
[1]));
4420 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4423 else if (n
== 17 && TARGET_SWAP
)
4425 emit_insn (gen_rotlsi2_cnt16 (operands
[0], operands
[1]));
4426 emit_insn (gen_rotlsi3_cnt1 (operands
[0], operands
[0]));
4429 else if (n
>= 16 || n
== 12 || n
== 14)
4431 emit_insn (gen_rotrsi3_loop (operands
[0], operands
[1],
4437 emit_insn (gen_rotlsi3_loop (operands
[0], operands
[1], operands
[2]));
4440 /* Split SImode rotate right instruction. */
4442 arc_split_rotr (rtx
*operands
)
4444 if (CONST_INT_P (operands
[2]))
4446 int n
= INTVAL (operands
[2]) & 0x1f;
4451 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[1]));
4453 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4456 emit_move_insn (operands
[0], operands
[1]);
4459 else if (n
== 15 && TARGET_SWAP
)
4461 emit_insn (gen_rotrsi2_cnt16 (operands
[0], operands
[1]));
4462 emit_insn (gen_rotlsi3_cnt1 (operands
[0], operands
[0]));
4465 else if (n
>= 16 && n
<= 19 && TARGET_SWAP
)
4467 emit_insn (gen_rotrsi2_cnt16 (operands
[0], operands
[1]));
4469 emit_insn (gen_rotrsi3_cnt1 (operands
[0], operands
[0]));
4474 emit_insn (gen_rotlsi3_cnt1 (operands
[0], operands
[1]));
4476 emit_insn (gen_rotlsi3_cnt1 (operands
[1], operands
[1]));
4479 else if (n
>= 21 || n
== 17 || n
== 19)
4481 emit_insn (gen_rotrsi3_loop (operands
[0], operands
[1],
4487 emit_insn (gen_rotrsi3_loop (operands
[0], operands
[1], operands
[2]));
4490 /* Nested function support. */
4492 /* Output assembler code for a block containing the constant parts of
4493 a trampoline, leaving space for variable parts. A trampoline looks
4499 .word function's address
4500 .word static chain value
4505 arc_asm_trampoline_template (FILE *f
)
4507 asm_fprintf (f
, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG
);
4508 asm_fprintf (f
, "\tld\t%s,[pcl,12]\n", reg_names
[STATIC_CHAIN_REGNUM
]);
4509 asm_fprintf (f
, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG
);
4510 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
4511 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
4514 /* Emit RTL insns to initialize the variable parts of a trampoline.
4515 FNADDR is an RTX for the address of the function's pure code. CXT
4516 is an RTX for the static chain value for the function.
4518 The fastest trampoline to execute for trampolines within +-8KB of CTX
4522 j [limm] 0x20200f80 limm
4524 and that would also be faster to write to the stack by computing
4525 the offset from CTX to TRAMP at compile time. However, it would
4526 really be better to get rid of the high cost of cache invalidation
4527 when generating trampolines, which requires that the code part of
4528 trampolines stays constant, and additionally either making sure
4529 that no executable code but trampolines is on the stack, no icache
4530 entries linger for the area of the stack from when before the stack
4531 was allocated, and allocating trampolines in trampoline-only cache
4532 lines or allocate trampolines fram a special pool of pre-allocated
4536 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
4538 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
4540 emit_block_move (tramp
, assemble_trampoline_template (),
4541 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
4542 emit_move_insn (adjust_address (tramp
, SImode
, 8), fnaddr
);
4543 emit_move_insn (adjust_address (tramp
, SImode
, 12), cxt
);
4544 maybe_emit_call_builtin___clear_cache (XEXP (tramp
, 0),
4545 plus_constant (Pmode
,
4550 /* Add the given function declaration to emit code in JLI section. */
4553 arc_add_jli_section (rtx pat
)
4557 arc_jli_section
*sec
= arc_jli_sections
, *new_section
;
4558 tree decl
= SYMBOL_REF_DECL (pat
);
4565 /* For fixed locations do not generate the jli table entry. It
4566 should be provided by the user as an asm file. */
4567 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
4568 if (lookup_attribute ("jli_fixed", attrs
))
4572 name
= XSTR (pat
, 0);
4574 /* Don't insert the same symbol twice. */
4577 if(strcmp (name
, sec
->name
) == 0)
4582 /* New name, insert it. */
4583 new_section
= (arc_jli_section
*) xmalloc (sizeof (arc_jli_section
));
4584 gcc_assert (new_section
!= NULL
);
4585 new_section
->name
= name
;
4586 new_section
->next
= arc_jli_sections
;
4587 arc_jli_sections
= new_section
;
4590 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4591 reset when we output the scaled address. */
4592 static int output_scaled
= 0;
4594 /* Set when we force sdata output. */
4595 static int output_sdata
= 0;
4597 /* Print operand X (an rtx) in assembler syntax to file FILE.
4598 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4599 For `%' followed by punctuation, CODE is the punctuation and X is null.
4600 In final.cc:output_asm_insn:
4603 'c' : constant address if CONSTANT_ADDRESS_P
4609 'p': bit Position of lsb
4610 's': scalled immediate
4611 'S': Scalled immediate, to be used in pair with 's'.
4612 'N': Negative immediate, to be used in pair with 's'.
4613 'x': size of bit field
4614 '*': jump delay slot suffix
4615 '?' : nonjump-insn suffix for conditional execution or short instruction
4619 'J': JLI instruction
4620 'j': used by mov instruction to properly emit jli related labels.
4621 'B': Branch comparison operand - suppress sda reference
4622 'H': Most significant word
4623 'L': Least significant word
4624 'A': ASCII decimal representation of floating point value
4625 'U': Load/store update or scaling indicator
4626 'V': cache bypass indicator for volatile
4630 'o': original symbol - no @ prepending. */
4633 arc_print_operand (FILE *file
, rtx x
, int code
)
4636 unsigned scalled
= 0;
4642 if (GET_CODE (x
) == CONST_INT
)
4643 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
4645 output_operand_lossage ("invalid operand to %%Z code");
4650 if (GET_CODE (x
) == CONST_INT
)
4651 fprintf (file
, "%d",exact_log2 (INTVAL (x
) & 0xffffffff));
4653 output_operand_lossage ("invalid operand to %%z code");
4658 if (GET_CODE (x
) == CONST_INT
)
4659 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) );
4661 output_operand_lossage ("invalid operands to %%c code");
4666 if (GET_CODE (x
) == CONST_INT
)
4667 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
4669 output_operand_lossage ("invalid operand to %%M code");
4674 if (GET_CODE (x
) == CONST_INT
)
4675 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
4677 output_operand_lossage ("invalid operand to %%p code");
4683 if (!CONST_INT_P (x
))
4685 output_operand_lossage ("invalid operand for %%s code");
4689 if ((ival
& 0x07) == 0)
4691 else if ((ival
& 0x03) == 0)
4693 else if ((ival
& 0x01) == 0)
4697 asm_fprintf (file
, "%d", scalled
);
4703 output_operand_lossage ("invalid operand for %%N code");
4711 asm_fprintf (file
, "%s", reg_names
[REGNO (x
)]);
4714 if (!CONST_INT_P (x
))
4716 output_operand_lossage ("invalid operand for %%N or %%S code");
4719 ival
= sign
* INTVAL (x
);
4720 if ((ival
& 0x07) == 0)
4722 else if ((ival
& 0x03) == 0)
4724 else if ((ival
& 0x01) == 0)
4727 asm_fprintf (file
, "%wd", (ival
>> scalled
));
4731 if (GET_CODE (x
) == CONST_INT
)
4733 HOST_WIDE_INT i
= INTVAL (x
);
4734 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
4735 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
4738 output_operand_lossage ("invalid operand to %%s code");
4742 /* Unconditional branches / branches not depending on condition codes.
4743 This could also be a CALL_INSN.
4744 Output the appropriate delay slot suffix. */
4745 if (final_sequence
&& final_sequence
->len () != 1)
4747 rtx_insn
*delay
= final_sequence
->insn (1);
4749 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
4750 if (delay
->deleted ())
4756 case '?' : /* with leading "." */
4757 case '!' : /* without leading "." */
4758 if (current_insn_predicate
)
4760 int cc
= get_arc_condition_code (current_insn_predicate
);
4761 /* Is this insn in a delay slot sequence? */
4762 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
4763 || current_insn_predicate
4764 || CALL_P (final_sequence
->insn (0))
4765 || simplejump_p (final_sequence
->insn (0)))
4767 /* This insn isn't in a delay slot sequence, or conditionalized
4768 independently of its position in a delay slot. */
4769 fprintf (file
, "%s%s",
4770 code
== '?' ? "." : "", arc_condition_codes
[cc
]);
4771 /* If this is a jump, there are still short variants. However,
4772 only beq_s / bne_s have the same offset range as b_s,
4773 and the only short conditional returns are jeq_s and jne_s. */
4775 && (cc
== ARC_CC_EQ
|| cc
== ARC_CC_NE
))
4776 output_short_suffix (file
);
4778 else if (code
== '!') /* Jump with delay slot. */
4779 fputs (arc_condition_codes
[cc
], file
);
4780 else /* An Instruction in a delay slot of a jump or call. */
4782 rtx jump
= XVECEXP (final_sequence
, 0, 0);
4783 rtx insn
= XVECEXP (final_sequence
, 0, 1);
4785 /* If the insn is annulled and is from the target path, we need
4786 to inverse the condition test. */
4787 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
4789 if (INSN_FROM_TARGET_P (insn
))
4790 fprintf (file
, "%s%s",
4791 code
== '?' ? "." : "",
4792 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (cc
)]);
4794 fprintf (file
, "%s%s",
4795 code
== '?' ? "." : "",
4796 arc_condition_codes
[cc
]);
4800 /* This insn is executed for either path, so don't
4801 conditionalize it at all. */
4802 output_short_suffix (file
);
4807 output_short_suffix (file
);
4811 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
4814 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
4815 (get_arc_condition_code (x
))],
4819 /* Write second word of DImode or DFmode reference,
4820 register or memory. */
4821 if (GET_CODE (x
) == REG
)
4822 fputs (reg_names
[REGNO (x
)+1], file
);
4823 else if (GET_CODE (x
) == MEM
)
4827 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4828 PRE_MODIFY, we will have handled the first word already;
4829 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4830 first word will be done later. In either case, the access
4831 to the first word will do the modify, and we only have
4832 to add an offset of four here. */
4833 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
4834 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
4835 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
4836 || GET_CODE (XEXP (x
, 0)) == POST_INC
4837 || GET_CODE (XEXP (x
, 0)) == POST_DEC
4838 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
4839 output_address (VOIDmode
,
4840 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
4841 else if (output_scaled
)
4843 rtx addr
= XEXP (x
, 0);
4844 int size
= GET_MODE_SIZE (GET_MODE (x
));
4846 output_address (VOIDmode
,
4847 plus_constant (Pmode
, XEXP (addr
, 0),
4848 ((INTVAL (XEXP (addr
, 1)) + 4)
4849 >> (size
== 2 ? 1 : 2))));
4853 output_address (VOIDmode
,
4854 plus_constant (Pmode
, XEXP (x
, 0), 4));
4858 output_operand_lossage ("invalid operand to %%R code");
4862 if (GET_CODE (x
) == SYMBOL_REF
4863 && arc_is_jli_call_p (x
))
4865 if (SYMBOL_REF_DECL (x
))
4867 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4868 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4870 if (lookup_attribute ("jli_fixed", attrs
))
4872 /* No special treatment for jli_fixed functions. */
4875 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"\t; @",
4876 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4877 assemble_name (file
, XSTR (x
, 0));
4881 fprintf (file
, "@__jli.");
4882 assemble_name (file
, XSTR (x
, 0));
4884 arc_add_jli_section (x
);
4887 if (GET_CODE (x
) == SYMBOL_REF
4888 && arc_is_secure_call_p (x
))
4890 /* No special treatment for secure functions. */
4893 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4894 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4896 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"\t; @",
4897 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4898 assemble_name (file
, XSTR (x
, 0));
4902 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4905 output_addr_const (file
, x
);
4911 if (GET_CODE (x
) == REG
)
4913 /* L = least significant word, H = most significant word. */
4914 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
4915 fputs (reg_names
[REGNO (x
)], file
);
4917 fputs (reg_names
[REGNO (x
)+1], file
);
4919 else if (GET_CODE (x
) == CONST_INT
4920 || GET_CODE (x
) == CONST_DOUBLE
)
4922 rtx first
, second
, word
;
4924 split_double (x
, &first
, &second
);
4926 if((WORDS_BIG_ENDIAN
) == 0)
4927 word
= (code
== 'L' ? first
: second
);
4929 word
= (code
== 'L' ? second
: first
);
4931 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
4934 output_operand_lossage ("invalid operand to %%H/%%L code");
4940 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
4941 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
4943 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
4944 fprintf (file
, "%s", str
);
4948 /* Output a load/store with update indicator if appropriate. */
4949 if (GET_CODE (x
) == MEM
)
4951 rtx addr
= XEXP (x
, 0);
4952 switch (GET_CODE (addr
))
4954 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
4955 fputs (".a", file
); break;
4956 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
4957 fputs (".ab", file
); break;
4959 /* Are we using a scaled index? */
4960 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4961 fputs (".as", file
);
4962 /* Can we use a scaled offset? */
4963 else if (CONST_INT_P (XEXP (addr
, 1))
4964 && GET_MODE_SIZE (GET_MODE (x
)) > 1
4965 && (!(INTVAL (XEXP (addr
, 1))
4966 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
4967 /* Does it make a difference? */
4968 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
4969 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
4971 fputs (".as", file
);
4977 if (legitimate_small_data_address_p (addr
, GET_MODE (x
))
4978 && GET_MODE_SIZE (GET_MODE (x
)) > 1)
4980 int align
= get_symbol_alignment (addr
);
4982 switch (GET_MODE (x
))
4991 if (align
&& ((align
& mask
) == 0))
4992 fputs (".as", file
);
4998 gcc_assert (CONSTANT_P (addr
)); break;
5002 output_operand_lossage ("invalid operand to %%U code");
5005 /* Output cache bypass indicator for a load/store insn. Volatile memory
5006 refs are defined to use the cache bypass mechanism. */
5007 if (GET_CODE (x
) == MEM
)
5009 if ((MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
5010 || arc_is_uncached_mem_p (x
))
5011 fputs (".di", file
);
5014 output_operand_lossage ("invalid operand to %%V code");
5019 /* Do nothing special. */
5022 fputs (reg_names
[REGNO (x
)]+1, file
);
5026 /* Output an operator. */
5027 switch (GET_CODE (x
))
5029 case PLUS
: fputs ("add", file
); return;
5030 case SS_PLUS
: fputs ("adds", file
); return;
5031 case AND
: fputs ("and", file
); return;
5032 case IOR
: fputs ("or", file
); return;
5033 case XOR
: fputs ("xor", file
); return;
5034 case MINUS
: fputs ("sub", file
); return;
5035 case SS_MINUS
: fputs ("subs", file
); return;
5036 case ASHIFT
: fputs ("asl", file
); return;
5037 case ASHIFTRT
: fputs ("asr", file
); return;
5038 case LSHIFTRT
: fputs ("lsr", file
); return;
5039 case ROTATERT
: fputs ("ror", file
); return;
5040 case MULT
: fputs ("mpy", file
); return;
5041 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
5042 case NEG
: fputs ("neg", file
); return;
5043 case SS_NEG
: fputs ("negs", file
); return;
5044 case NOT
: fputs ("not", file
); return; /* Unconditional. */
5046 fputs ("ext", file
); /* bmsk allows predication. */
5048 case SIGN_EXTEND
: /* Unconditional. */
5049 fputs ("sex", file
);
5051 switch (GET_MODE (XEXP (x
, 0)))
5053 case E_QImode
: fputs ("b", file
); return;
5054 case E_HImode
: fputs ("w", file
); return;
5059 if (GET_MODE (x
) != HImode
)
5061 fputs ("sat16", file
);
5064 output_operand_lossage ("invalid operand to %%O code"); return;
5066 if (GET_CODE (x
) == SYMBOL_REF
)
5068 assemble_name (file
, XSTR (x
, 0));
5087 output_operand_lossage ("invalid operand output code");
5090 switch (GET_CODE (x
))
5093 fputs (reg_names
[REGNO (x
)], file
);
5097 rtx addr
= XEXP (x
, 0);
5098 int size
= GET_MODE_SIZE (GET_MODE (x
));
5100 if (legitimate_small_data_address_p (addr
, GET_MODE (x
)))
5105 switch (GET_CODE (addr
))
5107 case PRE_INC
: case POST_INC
:
5108 output_address (VOIDmode
,
5109 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
5110 case PRE_DEC
: case POST_DEC
:
5111 output_address (VOIDmode
,
5112 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
5114 case PRE_MODIFY
: case POST_MODIFY
:
5115 output_address (VOIDmode
, XEXP (addr
, 1)); break;
5119 output_address (VOIDmode
,
5120 plus_constant (Pmode
, XEXP (addr
, 0),
5121 (INTVAL (XEXP (addr
, 1))
5122 >> (size
== 2 ? 1 : 2))));
5126 output_address (VOIDmode
, addr
);
5129 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
5130 arc_output_pic_addr_const (file
, addr
, code
);
5132 output_address (VOIDmode
, addr
);
5139 /* We handle SFmode constants here as output_addr_const doesn't. */
5140 if (GET_MODE (x
) == SFmode
)
5144 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
5145 fprintf (file
, "0x%08lx", l
);
5149 /* Let output_addr_const deal with it. */
5152 || (GET_CODE (x
) == CONST
5153 && GET_CODE (XEXP (x
, 0)) == UNSPEC
5154 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
5155 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
5156 || (GET_CODE (x
) == CONST
5157 && GET_CODE (XEXP (x
, 0)) == PLUS
5158 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
5159 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
5160 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
5161 arc_output_pic_addr_const (file
, x
, code
);
5163 output_addr_const (file
, x
);
5168 /* Print a memory address as an operand to reference that memory location. */
5171 arc_print_operand_address (FILE *file
, rtx addr
)
5173 rtx base
, index
= 0;
5175 switch (GET_CODE (addr
))
5178 fputs (reg_names
[REGNO (addr
)], file
);
5182 fputs ("gp,", file
);
5183 output_addr_const (file
, addr
);
5185 fputs ("@sda", file
);
5189 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
5190 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
5191 else if (CONST_INT_P (XEXP (addr
, 0)))
5192 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
5194 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
5196 gcc_assert (OBJECT_P (base
));
5197 arc_print_operand_address (file
, base
);
5198 if (CONSTANT_P (base
) && CONST_INT_P (index
))
5202 gcc_assert (OBJECT_P (index
));
5203 arc_print_operand_address (file
, index
);
5207 rtx c
= XEXP (addr
, 0);
5209 if ((GET_CODE (c
) == UNSPEC
5210 && (XINT (c
, 1) == UNSPEC_TLS_OFF
5211 || XINT (c
, 1) == UNSPEC_TLS_IE
))
5212 || (GET_CODE (c
) == PLUS
5213 && GET_CODE (XEXP (c
, 0)) == UNSPEC
5214 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
5215 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
5217 arc_output_pic_addr_const (file
, c
, 0);
5220 gcc_assert (GET_CODE (c
) == PLUS
);
5221 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
5222 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
5224 output_address (VOIDmode
, XEXP (addr
, 0));
5230 /* We shouldn't get here as we've lost the mode of the memory object
5231 (which says how much to inc/dec by. */
5236 arc_output_pic_addr_const (file
, addr
, 0);
5238 output_addr_const (file
, addr
);
5243 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5244 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5245 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5248 arc_verify_short (rtx_insn
*insn
, int check_attr
)
5250 enum attr_iscompact iscompact
;
5254 iscompact
= get_attr_iscompact (insn
);
5255 if (iscompact
== ISCOMPACT_FALSE
)
5259 return (get_attr_length (insn
) & 2) != 0;
5262 /* When outputting an instruction (alternative) that can potentially be short,
5263 output the short suffix if the insn is in fact short. */
5266 output_short_suffix (FILE *file
)
5268 rtx_insn
*insn
= current_output_insn
;
5272 if (arc_verify_short (insn
, 1))
5274 fprintf (file
, "_s");
5276 /* Restore recog_operand. */
5277 extract_insn_cached (insn
);
5280 /* Implement FINAL_PRESCAN_INSN. */
5283 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
5284 int noperands ATTRIBUTE_UNUSED
)
5286 if (TARGET_DUMPISIZE
)
5287 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
5290 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5291 Frame pointer elimination is automatically handled.
5293 All eliminations are permissible. If we need a frame
5294 pointer, we must eliminate ARG_POINTER_REGNUM into
5295 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5298 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
5300 return ((to
== HARD_FRAME_POINTER_REGNUM
) || (to
== STACK_POINTER_REGNUM
));
5303 /* Define the offset between two registers, one to be eliminated, and
5304 the other its replacement, at the start of a routine. */
5307 arc_initial_elimination_offset (int from
, int to
)
5309 if (!cfun
->machine
->frame_info
.initialized
)
5310 arc_compute_frame_size ();
5312 if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
5314 return (cfun
->machine
->frame_info
.extra_size
5315 + cfun
->machine
->frame_info
.reg_size
);
5318 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
5320 return (cfun
->machine
->frame_info
.total_size
5321 - cfun
->machine
->frame_info
.pretend_size
);
5324 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
5326 return (cfun
->machine
->frame_info
.total_size
5327 - (cfun
->machine
->frame_info
.pretend_size
5328 + cfun
->machine
->frame_info
.extra_size
5329 + cfun
->machine
->frame_info
.reg_size
));
5331 if ((from
== FRAME_POINTER_REGNUM
) && (to
== HARD_FRAME_POINTER_REGNUM
))
5338 arc_frame_pointer_required (void)
5340 return cfun
->calls_alloca
|| crtl
->calls_eh_return
;
5344 /* Return the destination address of a branch. */
5347 branch_dest (rtx branch
)
5349 rtx pat
= PATTERN (branch
);
5350 rtx dest
= (GET_CODE (pat
) == PARALLEL
5351 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
5354 if (GET_CODE (dest
) == IF_THEN_ELSE
)
5355 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
5357 dest
= XEXP (dest
, 0);
5358 dest_uid
= INSN_UID (dest
);
5360 return INSN_ADDRESSES (dest_uid
);
5364 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5367 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
5369 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5370 This clears machine specific flags, so has to come first. */
5371 default_encode_section_info (decl
, rtl
, first
);
5373 /* Check if it is a function, and whether it has the
5374 [long/medium/short]_call attribute specified. */
5375 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5377 rtx symbol
= XEXP (rtl
, 0);
5378 int flags
= SYMBOL_REF_FLAGS (symbol
);
5380 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5381 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
5382 tree long_call_attr
= lookup_attribute ("long_call", attr
);
5383 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
5384 tree short_call_attr
= lookup_attribute ("short_call", attr
);
5386 if (long_call_attr
!= NULL_TREE
)
5387 flags
|= SYMBOL_FLAG_LONG_CALL
;
5388 else if (medium_call_attr
!= NULL_TREE
)
5389 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
5390 else if (short_call_attr
!= NULL_TREE
)
5391 flags
|= SYMBOL_FLAG_SHORT_CALL
;
5393 SYMBOL_REF_FLAGS (symbol
) = flags
;
5395 else if (VAR_P (decl
))
5397 rtx symbol
= XEXP (rtl
, 0);
5399 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5400 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
5402 tree sec_attr
= lookup_attribute ("section", attr
);
5405 const char *sec_name
5406 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
5407 if (strcmp (sec_name
, ".cmem") == 0
5408 || strcmp (sec_name
, ".cmem_shared") == 0
5409 || strcmp (sec_name
, ".cmem_private") == 0)
5410 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
5415 /* This is how to output a definition of an internal numbered label where
5416 PREFIX is the class of label and NUM is the number within the class. */
5418 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
5420 default_internal_label (stream
, prefix
, labelno
);
5423 /* Set the cpu type and print out other fancy things,
5424 at the top of the file. */
5426 static void arc_file_start (void)
5428 default_file_start ();
5429 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
5431 /* Set some want to have build attributes. */
5432 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5434 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5435 TARGET_RF16
? 1 : 0);
5436 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5438 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5439 (arc_tp_regno
!= -1) ? 1 : 0);
5440 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5441 TARGET_NO_SDATA_SET
? 0 : 2);
5442 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5443 TARGET_OPTFPE
? 1 : 0);
5445 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5446 (arc_tune
< ARC_TUNE_CORE_3
) ? 2 :
5447 (arc_tune
== ARC_TUNE_CORE_3
? 3 : 4));
5450 /* Implement `TARGET_ASM_FILE_END'. */
5451 /* Outputs to the stdio stream FILE jli related text. */
5453 void arc_file_end (void)
5455 arc_jli_section
*sec
= arc_jli_sections
;
5459 fprintf (asm_out_file
, "\n");
5460 fprintf (asm_out_file
, "# JLI entry for function ");
5461 assemble_name (asm_out_file
, sec
->name
);
5462 fprintf (asm_out_file
, "\n\t.section .jlitab, \"axG\", @progbits, "
5464 assemble_name (asm_out_file
, sec
->name
);
5465 fprintf (asm_out_file
,", comdat\n");
5467 fprintf (asm_out_file
, "\t.align\t4\n");
5468 fprintf (asm_out_file
, "__jli.");
5469 assemble_name (asm_out_file
, sec
->name
);
5470 fprintf (asm_out_file
, ":\n\t.weak __jli.");
5471 assemble_name (asm_out_file
, sec
->name
);
5472 fprintf (asm_out_file
, "\n\tb\t@");
5473 assemble_name (asm_out_file
, sec
->name
);
5474 fprintf (asm_out_file
, "\n");
5477 file_end_indicate_exec_stack ();
5480 /* Cost functions. */
5482 /* Compute a (partial) cost for rtx X. Return true if the complete
5483 cost has been computed, and false if subexpressions should be
5484 scanned. In either case, *TOTAL contains the cost result. */
5487 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
5488 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
5490 int code
= GET_CODE (x
);
5494 /* Small integers are as cheap as registers. */
5497 bool nolimm
= false; /* Can we do without long immediate? */
5500 if (UNSIGNED_INT6 (INTVAL (x
)))
5506 case AND
: /* bclr, bmsk, ext[bw] */
5507 if (satisfies_constraint_Ccp (x
) /* bclr */
5508 || satisfies_constraint_C1p (x
) /* bmsk */)
5511 case IOR
: /* bset */
5512 if (satisfies_constraint_C0p (x
)) /* bset */
5516 if (satisfies_constraint_C0p (x
)) /* bxor */
5520 if (UNSIGNED_INT8 (INTVAL (x
)))
5522 if (satisfies_constraint_Chi (x
))
5524 if (satisfies_constraint_Clo (x
))
5528 if (TARGET_MUL64_SET
)
5529 if (SIGNED_INT12 (INTVAL (x
)))
5544 /* 4 byte values can be fetched as immediate constants -
5545 let's give that the cost of an extra insn. */
5549 *total
= speed
? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
5558 *total
= COSTS_N_INSNS (1);
5561 split_double (x
, &first
, &second
);
5562 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
5563 + !SMALL_INT (INTVAL (second
)));
5567 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5568 If we need more than 12 insns to do a multiply, then go out-of-line,
5569 since the call overhead will be < 10% of the cost of the multiply. */
5577 if (TARGET_BARREL_SHIFTER
)
5579 *total
= COSTS_N_INSNS (1);
5580 if (CONSTANT_P (XEXP (x
, 1)))
5582 *total
+= rtx_cost (XEXP (x
, 0), mode
, (enum rtx_code
) code
,
5587 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5588 *total
= speed
? COSTS_N_INSNS (16) : COSTS_N_INSNS (4);
5591 int n
= INTVAL (XEXP (x
, 1)) & 31;
5593 *total
= COSTS_N_INSNS (n
);
5595 *total
= speed
? COSTS_N_INSNS (n
+ 2) : COSTS_N_INSNS (4);
5596 *total
+= rtx_cost (XEXP (x
, 0), mode
, (enum rtx_code
) code
,
5604 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
5605 && (TARGET_FP_SP_SQRT
|| TARGET_FP_DP_SQRT
))
5606 *total
= COSTS_N_INSNS(1);
5607 else if (GET_MODE_CLASS (mode
) == MODE_INT
5609 *total
= COSTS_N_INSNS(1);
5611 *total
= COSTS_N_INSNS(30);
5613 *total
= COSTS_N_INSNS(1);
5617 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
5618 *total
= COSTS_N_INSNS (1);
5620 *total
= arc_multcost
;
5621 /* We do not want synth_mult sequences when optimizing
5623 else if (TARGET_ANY_MPY
)
5624 *total
= COSTS_N_INSNS (1);
5626 *total
= COSTS_N_INSNS (2);
5632 if (outer_code
== MEM
&& CONST_INT_P (XEXP (x
, 1))
5633 && RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1)))
5639 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
5640 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
5641 || (GET_CODE (XEXP (x
, 0)) == MULT
5642 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
5644 if (CONSTANT_P (XEXP (x
, 1)) && !speed
)
5645 *total
+= COSTS_N_INSNS (4);
5646 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
);
5651 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
5652 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
5653 || (GET_CODE (XEXP (x
, 1)) == MULT
5654 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
5656 if (CONSTANT_P (XEXP (x
, 0)) && !speed
)
5657 *total
+= COSTS_N_INSNS (4);
5658 *total
+= rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
);
5665 rtx op0
= XEXP (x
, 0);
5666 rtx op1
= XEXP (x
, 1);
5668 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
5669 && XEXP (op0
, 1) == const1_rtx
)
5671 /* btst / bbit0 / bbit1:
5672 Small integers and registers are free; everything else can
5673 be put in a register. */
5674 mode
= GET_MODE (XEXP (op0
, 0));
5675 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5676 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5679 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
5680 && satisfies_constraint_C1p (XEXP (op0
, 1)))
5683 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
5687 if (GET_CODE (op1
) == NEG
)
5689 /* op0 might be constant, the inside of op1 is rather
5690 unlikely to be so. So swapping the operands might lower
5692 mode
= GET_MODE (op0
);
5693 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
5694 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
5699 if (outer_code
== IF_THEN_ELSE
5700 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
5701 && XEXP (x
, 1) == const0_rtx
5702 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
5704 /* btst / bbit0 / bbit1:
5705 Small integers and registers are free; everything else can
5706 be put in a register. */
5707 rtx op0
= XEXP (x
, 0);
5709 mode
= GET_MODE (XEXP (op0
, 0));
5710 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
5711 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
5715 /* scc_insn expands into two insns. */
5716 case GTU
: case GEU
: case LEU
:
5718 *total
+= COSTS_N_INSNS (1);
5720 case LTU
: /* might use adc. */
5722 *total
+= COSTS_N_INSNS (1) - 1;
5729 /* Return true if ADDR is a valid pic address.
5730 A valid pic address on arc should look like
5731 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5734 arc_legitimate_pic_addr_p (rtx addr
)
5736 if (GET_CODE (addr
) != CONST
)
5739 addr
= XEXP (addr
, 0);
5742 if (GET_CODE (addr
) == PLUS
)
5744 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
5746 addr
= XEXP (addr
, 0);
5749 if (GET_CODE (addr
) != UNSPEC
5750 || XVECLEN (addr
, 0) != 1)
5753 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5754 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
5755 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
5756 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
5757 && XINT (addr
, 1) != UNSPEC_TLS_GD
5758 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
5761 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
5762 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
5770 /* Return true if OP contains a symbol reference. */
5773 symbolic_reference_mentioned_p (rtx op
)
5778 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
5781 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5782 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5788 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5789 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
5793 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
5800 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5801 If SKIP_LOCAL is true, skip symbols that bind locally.
5802 This is used further down in this file, and, without SKIP_LOCAL,
5803 in the addsi3 / subsi3 expanders when generating PIC code. */
5806 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
5811 if (GET_CODE(op
) == UNSPEC
)
5814 if (GET_CODE (op
) == SYMBOL_REF
)
5816 if (SYMBOL_REF_TLS_MODEL (op
))
5820 tree decl
= SYMBOL_REF_DECL (op
);
5821 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
5824 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
5825 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
5831 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
5832 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
5837 else if (fmt
[i
] == 'e'
5838 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
5846 /* The __tls_get_attr symbol. */
5847 static GTY(()) rtx arc_tls_symbol
;
5849 /* Emit a call to __tls_get_addr. TI is the argument to this function.
5850 RET is an RTX for the return value location. The entire insn sequence
5854 arc_call_tls_get_addr (rtx ti
)
5856 rtx arg
= gen_rtx_REG (Pmode
, R0_REG
);
5857 rtx ret
= gen_rtx_REG (Pmode
, R0_REG
);
5861 if (!arc_tls_symbol
)
5862 arc_tls_symbol
= init_one_libfunc ("__tls_get_addr");
5864 emit_move_insn (arg
, ti
);
5865 fn
= gen_rtx_MEM (SImode
, arc_tls_symbol
);
5866 insn
= emit_call_insn (gen_call_value (ret
, fn
, const0_rtx
));
5867 RTL_CONST_CALL_P (insn
) = 1;
5868 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), ret
);
5869 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), arg
);
5874 /* Return a legitimized address for ADDR,
5875 which is a SYMBOL_REF with tls_model MODEL. */
5878 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
5882 /* The TP pointer needs to be set. */
5883 gcc_assert (arc_tp_regno
!= -1);
5887 case TLS_MODEL_GLOBAL_DYNAMIC
:
5888 case TLS_MODEL_LOCAL_DYNAMIC
:
5889 tmp
= gen_reg_rtx (Pmode
);
5890 emit_move_insn (tmp
, arc_unspec_offset (addr
, UNSPEC_TLS_GD
));
5891 return arc_call_tls_get_addr (tmp
);
5893 case TLS_MODEL_INITIAL_EXEC
:
5894 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
5895 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
5896 return gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
, arc_tp_regno
), addr
);
5898 case TLS_MODEL_LOCAL_EXEC
:
5899 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
5900 return gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
, arc_tp_regno
), addr
);
5907 /* Return true if SYMBOL_REF X binds locally. */
5910 arc_symbol_binds_local_p (const_rtx x
)
5912 return (SYMBOL_REF_DECL (x
)
5913 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
5914 : SYMBOL_REF_LOCAL_P (x
));
5917 /* Legitimize a pic address reference in ADDR. The return value is
5918 the legitimated address. */
5921 arc_legitimize_pic_address (rtx addr
)
5926 switch (GET_CODE (addr
))
5929 /* Can be one or our GOT or GOTOFFPC unspecs. This situation
5930 happens when an address is not a legitimate constant and we
5931 need the resolve it via force_reg in
5932 prepare_move_operands. */
5933 switch (XINT (addr
, 1))
5935 case ARC_UNSPEC_GOT
:
5936 case ARC_UNSPEC_GOTOFFPC
:
5937 /* Recover the symbol ref. */
5938 addr
= XVECEXP (addr
, 0, 0);
5945 /* TLS symbols are handled in different place. */
5946 if (SYMBOL_REF_TLS_MODEL (addr
))
5949 /* This symbol must be referenced via a load from the Global
5950 Offset Table (@GOTPC). */
5951 if (!arc_symbol_binds_local_p (addr
))
5952 return gen_const_mem (Pmode
, arc_unspec_offset (addr
, ARC_UNSPEC_GOT
));
5954 /* Local symb: use @pcl to access it. */
5957 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
5966 /* Output address constant X to FILE, taking PIC into account. */
5969 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
5974 switch (GET_CODE (x
))
5984 output_addr_const (file
, x
);
5986 /* Local functions do not get references through the PLT. */
5987 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5988 fputs ("@plt", file
);
5992 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5993 assemble_name (file
, buf
);
5997 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5998 assemble_name (file
, buf
);
6002 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
6006 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6010 if (GET_MODE (x
) == VOIDmode
)
6012 /* We can use %d if the number is one word and positive. */
6013 if (CONST_DOUBLE_HIGH (x
))
6014 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
6015 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
6016 else if (CONST_DOUBLE_LOW (x
) < 0)
6017 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
6019 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
6022 /* We can't handle floating point constants;
6023 PRINT_OPERAND must handle them. */
6024 output_operand_lossage ("floating constant misused");
6028 /* FIXME: Not needed here. */
6029 /* Some assemblers need integer constants to appear last (eg masm). */
6030 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
6032 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6033 fprintf (file
, "+");
6034 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6036 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6038 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6039 if (INTVAL (XEXP (x
, 1)) >= 0)
6040 fprintf (file
, "+");
6041 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6048 /* Avoid outputting things like x-x or x+5-x,
6049 since some assemblers can't handle that. */
6050 x
= simplify_subtraction (x
);
6051 if (GET_CODE (x
) != MINUS
)
6054 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6055 fprintf (file
, "-");
6056 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
6057 && INTVAL (XEXP (x
, 1)) < 0)
6059 fprintf (file
, "(");
6060 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6061 fprintf (file
, ")");
6064 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6069 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6075 bool pcrel
; pcrel
= false;
6076 rtx base
; base
= NULL
;
6077 gcc_assert (XVECLEN (x
, 0) >= 1);
6078 switch (XINT (x
, 1))
6080 case ARC_UNSPEC_GOT
:
6081 suffix
= "@gotpc", pcrel
= true;
6083 case ARC_UNSPEC_GOTOFF
:
6086 case ARC_UNSPEC_GOTOFFPC
:
6087 suffix
= "@pcl", pcrel
= true;
6089 case ARC_UNSPEC_PLT
:
6093 suffix
= "@tlsgd", pcrel
= true;
6096 suffix
= "@tlsie", pcrel
= true;
6098 case UNSPEC_TLS_OFF
:
6099 if (XVECLEN (x
, 0) == 2)
6100 base
= XVECEXP (x
, 0, 1);
6101 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6102 || (!flag_pic
&& !base
))
6108 suffix
= "@invalid";
6109 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
6113 fputs ("pcl,", file
);
6114 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
6115 fputs (suffix
, file
);
6117 arc_output_pic_addr_const (file
, base
, code
);
6121 output_operand_lossage ("invalid expression as operand");
6125 /* The function returning the number of words, at the beginning of an
6126 argument, must be put in registers. The returned value must be
6127 zero for arguments that are passed entirely in registers or that
6128 are entirely pushed on the stack.
6130 On some machines, certain arguments must be passed partially in
6131 registers and partially in memory. On these machines, typically
6132 the first N words of arguments are passed in registers, and the
6133 rest on the stack. If a multi-word argument (a `double' or a
6134 structure) crosses that boundary, its first few words must be
6135 passed in registers and the rest must be pushed. This function
6136 tells the compiler when this occurs, and how many of the words
6137 should go in registers.
6139 `FUNCTION_ARG' for these arguments should return the first register
6140 to be used by the caller for this argument; likewise
6141 `FUNCTION_INCOMING_ARG', for the called function.
6143 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6145 /* If REGNO is the least arg reg available then what is the total number of arg
6147 #define GPR_REST_ARG_REGS(REGNO) \
6148 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6150 /* Since arc parm regs are contiguous. */
6151 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6153 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6156 arc_arg_partial_bytes (cumulative_args_t cum_v
, const function_arg_info
&arg
)
6158 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6159 int bytes
= arg
.promoted_size_in_bytes ();
6160 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6164 arg_num
= ROUND_ADVANCE_CUM (arg_num
, arg
.mode
, arg
.type
);
6165 ret
= GPR_REST_ARG_REGS (arg_num
);
6167 /* ICEd at function.cc:2361, and ret is copied to data->partial */
6168 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
6173 /* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
6174 args are normally in registers and the rest are pushed. */
6177 arc_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
6179 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6182 const char *debstr ATTRIBUTE_UNUSED
;
6184 arg_num
= ROUND_ADVANCE_CUM (arg_num
, arg
.mode
, arg
.type
);
6185 /* Return a marker for use in the call instruction. */
6186 if (arg
.end_marker_p ())
6191 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
6193 ret
= gen_rtx_REG (arg
.mode
, arg_num
);
6194 debstr
= reg_names
[arg_num
];
6204 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6205 /* For the ARC: the cum set here is passed on to function_arg where we
6206 look at its value and say which reg to use. Strategy: advance the
6207 regnumber here till we run out of arg regs, then set *cum to last
6208 reg. In function_arg, since *cum > last arg reg we would return 0
6209 and thus the arg will end up on the stack. For straddling args of
6210 course function_arg_partial_nregs will come into play. */
6213 arc_function_arg_advance (cumulative_args_t cum_v
,
6214 const function_arg_info
&arg
)
6216 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6217 int bytes
= arg
.promoted_size_in_bytes ();
6218 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6222 *cum
= ROUND_ADVANCE_CUM (*cum
, arg
.mode
, arg
.type
);
6223 for (i
= 0; i
< words
; i
++)
6224 *cum
= ARC_NEXT_ARG_REG (*cum
);
6228 /* Define how to find the value returned by a function.
6229 VALTYPE is the data type of the value (as a tree).
6230 If the precise function being called is known, FN_DECL_OR_TYPE is its
6231 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6234 arc_function_value (const_tree valtype
,
6235 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
6236 bool outgoing ATTRIBUTE_UNUSED
)
6238 machine_mode mode
= TYPE_MODE (valtype
);
6239 int unsignedp ATTRIBUTE_UNUSED
;
6241 unsignedp
= TYPE_UNSIGNED (valtype
);
6242 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
6243 PROMOTE_MODE (mode
, unsignedp
, valtype
);
6244 return gen_rtx_REG (mode
, 0);
6247 /* Returns the return address that is used by builtin_return_address. */
6250 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
6255 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6258 /* Determine if a given RTX is a valid constant. We already know this
6259 satisfies CONSTANT_P. */
6262 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
6264 switch (GET_CODE (x
))
6269 if (arc_legitimate_pic_addr_p (x
))
6272 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6275 if (SYMBOL_REF_TLS_MODEL (x
))
6287 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6292 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6293 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
6302 return TARGET_PLUS_DMPY
;
6305 return TARGET_PLUS_QMACW
;
6311 switch (XINT (x
, 1))
6314 case UNSPEC_TLS_OFF
:
6318 /* Any other unspec ending here are pic related, hence the above
6319 constant pic address checking returned false. */
6325 fatal_insn ("unrecognized supposed constant", x
);
6332 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
,
6333 code_helper
= ERROR_MARK
)
6335 if (RTX_OK_FOR_BASE_P (x
, strict
))
6337 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
6339 if (legitimate_scaled_address_p (mode
, x
, strict
))
6341 if (legitimate_small_data_address_p (x
, mode
))
6343 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
6346 /* When we compile for size avoid const (@sym + offset)
6348 if (!flag_pic
&& optimize_size
&& !reload_completed
6349 && (GET_CODE (x
) == CONST
)
6350 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
6351 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
6352 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
6353 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
6355 rtx addend
= XEXP (XEXP (x
, 0), 1);
6356 gcc_assert (CONST_INT_P (addend
));
6357 HOST_WIDE_INT offset
= INTVAL (addend
);
6359 /* Allow addresses having a large offset to pass. Anyhow they
6360 will end in a limm. */
6361 return !(offset
> -1024 && offset
< 1020);
6364 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
6366 return arc_legitimate_constant_p (mode
, x
);
6368 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
6369 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
6370 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
6372 /* We're restricted here by the `st' insn. */
6373 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
6374 && GET_CODE (XEXP ((x
), 1)) == PLUS
6375 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
6376 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
6377 TARGET_AUTO_MODIFY_REG
, strict
))
6382 /* Return true iff ADDR (a legitimate address expression)
6383 has an effect that depends on the machine mode it is used for. */
6386 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
6388 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6389 which is valid for loads and stores, or a limm offset, which is valid for
6390 loads. Scaled indices are scaled by the access mode. */
6391 if (GET_CODE (addr
) == PLUS
6392 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
6397 /* Determine if it's legal to put X into the constant pool. */
6400 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
6402 return !arc_legitimate_constant_p (mode
, x
);
6405 /* IDs for all the ARC builtins. */
6409 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6410 ARC_BUILTIN_ ## NAME,
6411 #include "builtins.def"
6417 struct GTY(()) arc_builtin_description
6419 enum insn_code icode
;
6424 static GTY(()) struct arc_builtin_description
6425 arc_bdesc
[ARC_BUILTIN_COUNT
] =
6427 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6428 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6429 #include "builtins.def"
6433 /* Transform UP into lowercase and write the result to LO.
6434 You must provide enough space for LO. Return LO. */
6437 arc_tolower (char *lo
, const char *up
)
6441 for (; *up
; up
++, lo
++)
6442 *lo
= TOLOWER (*up
);
6449 /* Implement `TARGET_BUILTIN_DECL'. */
6452 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6454 if (id
< ARC_BUILTIN_COUNT
)
6455 return arc_bdesc
[id
].fndecl
;
6457 return error_mark_node
;
6461 arc_init_builtins (void)
6463 tree V4HI_type_node
;
6464 tree V2SI_type_node
;
6465 tree V2HI_type_node
;
6467 /* Vector types based on HS SIMD elements. */
6468 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6469 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6470 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6472 tree pcvoid_type_node
6473 = build_pointer_type (build_qualified_type (void_type_node
,
6475 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6478 tree void_ftype_void
6479 = build_function_type_list (void_type_node
, NULL_TREE
);
6481 = build_function_type_list (integer_type_node
, integer_type_node
,
6483 tree int_ftype_pcvoid_int
6484 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6485 integer_type_node
, NULL_TREE
);
6486 tree void_ftype_usint_usint
6487 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6488 long_unsigned_type_node
, NULL_TREE
);
6489 tree int_ftype_int_int
6490 = build_function_type_list (integer_type_node
, integer_type_node
,
6491 integer_type_node
, NULL_TREE
);
6492 tree usint_ftype_usint
6493 = build_function_type_list (long_unsigned_type_node
,
6494 long_unsigned_type_node
, NULL_TREE
);
6495 tree void_ftype_usint
6496 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6499 = build_function_type_list (integer_type_node
, void_type_node
,
6502 = build_function_type_list (void_type_node
, integer_type_node
,
6504 tree int_ftype_short
6505 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6508 /* Old ARC SIMD types. */
6509 tree v8hi_ftype_v8hi_v8hi
6510 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6511 V8HI_type_node
, NULL_TREE
);
6512 tree v8hi_ftype_v8hi_int
6513 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6514 integer_type_node
, NULL_TREE
);
6515 tree v8hi_ftype_v8hi_int_int
6516 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6517 integer_type_node
, integer_type_node
,
6519 tree void_ftype_v8hi_int_int
6520 = build_function_type_list (void_type_node
, V8HI_type_node
,
6521 integer_type_node
, integer_type_node
,
6523 tree void_ftype_v8hi_int_int_int
6524 = build_function_type_list (void_type_node
, V8HI_type_node
,
6525 integer_type_node
, integer_type_node
,
6526 integer_type_node
, NULL_TREE
);
6527 tree v8hi_ftype_int_int
6528 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6529 integer_type_node
, NULL_TREE
);
6530 tree void_ftype_int_int
6531 = build_function_type_list (void_type_node
, integer_type_node
,
6532 integer_type_node
, NULL_TREE
);
6533 tree v8hi_ftype_v8hi
6534 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6536 /* ARCv2 SIMD types. */
6537 tree long_ftype_v4hi_v4hi
6538 = build_function_type_list (long_long_integer_type_node
,
6539 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6540 tree int_ftype_v2hi_v2hi
6541 = build_function_type_list (integer_type_node
,
6542 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6543 tree v2si_ftype_v2hi_v2hi
6544 = build_function_type_list (V2SI_type_node
,
6545 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6546 tree v2hi_ftype_v2hi_v2hi
6547 = build_function_type_list (V2HI_type_node
,
6548 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6549 tree v2si_ftype_v2si_v2si
6550 = build_function_type_list (V2SI_type_node
,
6551 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6552 tree v4hi_ftype_v4hi_v4hi
6553 = build_function_type_list (V4HI_type_node
,
6554 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6555 tree long_ftype_v2si_v2hi
6556 = build_function_type_list (long_long_integer_type_node
,
6557 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6559 /* Add the builtins. */
6560 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6562 int id = ARC_BUILTIN_ ## NAME; \
6563 const char *Name = "__builtin_arc_" #NAME; \
6564 char *name = (char*) alloca (1 + strlen (Name)); \
6566 gcc_assert (id < ARC_BUILTIN_COUNT); \
6568 arc_bdesc[id].fndecl \
6569 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6570 BUILT_IN_MD, NULL, NULL_TREE); \
6572 #include "builtins.def"
6576 /* Helper to expand __builtin_arc_aligned (void* val, int
6580 arc_expand_builtin_aligned (tree exp
)
6582 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6583 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6585 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6586 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6588 if (!CONST_INT_P (op1
))
6590 /* If we can't fold the alignment to a constant integer
6591 whilst optimizing, this is probably a user error. */
6593 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
6597 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6598 /* Check alignTest is positive, and a power of two. */
6599 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6601 error ("invalid alignment value for %<__builtin_arc_aligned%>");
6605 if (CONST_INT_P (op0
))
6607 HOST_WIDE_INT pnt
= INTVAL (op0
);
6609 if ((pnt
& (alignTest
- 1)) == 0)
6614 unsigned align
= get_pointer_alignment (arg0
);
6615 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6617 if (align
&& align
>= numBits
)
6619 /* Another attempt to ascertain alignment. Check the type
6620 we are pointing to. */
6621 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
6622 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
6627 /* Default to false. */
6631 /* Helper arc_expand_builtin, generates a pattern for the given icode
6635 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
6637 switch (insn_data
[icode
].n_generator_args
)
6640 return GEN_FCN (icode
) ();
6642 return GEN_FCN (icode
) (arg
[0]);
6644 return GEN_FCN (icode
) (arg
[0], arg
[1]);
6646 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
6648 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
6650 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
6656 /* Expand an expression EXP that calls a built-in function,
6657 with result going to TARGET if that's convenient
6658 (and in mode MODE if that's convenient).
6659 SUBTARGET may be used as the target for computing one of EXP's operands.
6660 IGNORE is nonzero if the value is to be ignored. */
6663 arc_expand_builtin (tree exp
,
6665 rtx subtarget ATTRIBUTE_UNUSED
,
6666 machine_mode mode ATTRIBUTE_UNUSED
,
6667 int ignore ATTRIBUTE_UNUSED
)
6669 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
6670 unsigned int id
= DECL_MD_FUNCTION_CODE (fndecl
);
6671 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
6672 int i
, j
, n_args
= call_expr_nargs (exp
);
6675 enum insn_code icode
= d
->icode
;
6676 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
6693 if (id
>= ARC_BUILTIN_COUNT
)
6694 internal_error ("bad builtin fcode");
6696 /* 1st part: Expand special builtins. */
6699 case ARC_BUILTIN_NOP
:
6700 emit_insn (gen_nopv ());
6703 case ARC_BUILTIN_RTIE
:
6704 case ARC_BUILTIN_SYNC
:
6705 case ARC_BUILTIN_BRK
:
6706 case ARC_BUILTIN_SWI
:
6707 case ARC_BUILTIN_UNIMP_S
:
6708 gcc_assert (icode
!= 0);
6709 emit_insn (GEN_FCN (icode
) (const1_rtx
));
6712 case ARC_BUILTIN_ALIGNED
:
6713 return arc_expand_builtin_aligned (exp
);
6715 case ARC_BUILTIN_CLRI
:
6716 target
= gen_reg_rtx (SImode
);
6717 emit_insn (gen_clri (target
, const1_rtx
));
6720 case ARC_BUILTIN_TRAP_S
:
6721 case ARC_BUILTIN_SLEEP
:
6722 arg0
= CALL_EXPR_ARG (exp
, 0);
6724 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6726 gcc_assert (icode
!= 0);
6727 emit_insn (GEN_FCN (icode
) (op0
));
6730 case ARC_BUILTIN_VDORUN
:
6731 case ARC_BUILTIN_VDIRUN
:
6732 arg0
= CALL_EXPR_ARG (exp
, 0);
6733 arg1
= CALL_EXPR_ARG (exp
, 1);
6734 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6735 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6737 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
6739 mode0
= insn_data
[icode
].operand
[1].mode
;
6740 mode1
= insn_data
[icode
].operand
[2].mode
;
6742 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6743 op0
= copy_to_mode_reg (mode0
, op0
);
6745 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6746 op1
= copy_to_mode_reg (mode1
, op1
);
6748 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
6755 case ARC_BUILTIN_VDIWR
:
6756 case ARC_BUILTIN_VDOWR
:
6757 arg0
= CALL_EXPR_ARG (exp
, 0);
6758 arg1
= CALL_EXPR_ARG (exp
, 1);
6759 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6760 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6762 if (!CONST_INT_P (op0
)
6763 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6764 error ("operand 1 should be an unsigned 3-bit immediate");
6766 mode1
= insn_data
[icode
].operand
[1].mode
;
6768 if (icode
== CODE_FOR_vdiwr_insn
)
6769 target
= gen_rtx_REG (SImode
,
6770 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
6771 else if (icode
== CODE_FOR_vdowr_insn
)
6772 target
= gen_rtx_REG (SImode
,
6773 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
6777 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6778 op1
= copy_to_mode_reg (mode1
, op1
);
6780 pat
= GEN_FCN (icode
) (target
, op1
);
6787 case ARC_BUILTIN_VASRW
:
6788 case ARC_BUILTIN_VSR8
:
6789 case ARC_BUILTIN_VSR8AW
:
6790 arg0
= CALL_EXPR_ARG (exp
, 0);
6791 arg1
= CALL_EXPR_ARG (exp
, 1);
6792 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6793 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6794 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6796 target
= gen_reg_rtx (V8HImode
);
6797 mode0
= insn_data
[icode
].operand
[1].mode
;
6798 mode1
= insn_data
[icode
].operand
[2].mode
;
6800 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
6801 op0
= copy_to_mode_reg (mode0
, op0
);
6803 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6804 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6805 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6807 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6814 case ARC_BUILTIN_VLD32WH
:
6815 case ARC_BUILTIN_VLD32WL
:
6816 case ARC_BUILTIN_VLD64
:
6817 case ARC_BUILTIN_VLD32
:
6820 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6821 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6822 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6824 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6825 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6826 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6827 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6829 /* target <- src vreg. */
6830 emit_insn (gen_move_insn (target
, src_vreg
));
6832 /* target <- vec_concat: target, mem (Ib, u8). */
6833 mode0
= insn_data
[icode
].operand
[3].mode
;
6834 mode1
= insn_data
[icode
].operand
[1].mode
;
6836 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
6837 || !(UNSIGNED_INT3 (INTVAL (op0
))))
6838 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6840 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6841 || !(UNSIGNED_INT8 (INTVAL (op1
))))
6842 error ("operand 2 should be an unsigned 8-bit value");
6844 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
6851 case ARC_BUILTIN_VLD64W
:
6852 case ARC_BUILTIN_VLD128
:
6853 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
6854 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6856 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6857 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6858 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6860 /* target <- src vreg. */
6861 target
= gen_reg_rtx (V8HImode
);
6863 /* target <- vec_concat: target, mem (Ib, u8). */
6864 mode0
= insn_data
[icode
].operand
[1].mode
;
6865 mode1
= insn_data
[icode
].operand
[2].mode
;
6866 mode2
= insn_data
[icode
].operand
[3].mode
;
6868 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
6869 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6870 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6872 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
6873 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6874 error ("operand 2 should be an unsigned 8-bit value");
6876 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
6884 case ARC_BUILTIN_VST128
:
6885 case ARC_BUILTIN_VST64
:
6886 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
6887 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
6888 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
6890 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6891 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6892 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6893 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6895 mode0
= insn_data
[icode
].operand
[0].mode
;
6896 mode1
= insn_data
[icode
].operand
[1].mode
;
6897 mode2
= insn_data
[icode
].operand
[2].mode
;
6898 mode3
= insn_data
[icode
].operand
[3].mode
;
6900 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6901 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6902 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6904 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6905 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6906 error ("operand 3 should be an unsigned 8-bit value");
6908 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6909 op3
= copy_to_mode_reg (mode3
, op3
);
6911 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6918 case ARC_BUILTIN_VST16_N
:
6919 case ARC_BUILTIN_VST32_N
:
6920 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6921 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6922 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6923 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6925 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6926 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6927 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6928 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6929 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6931 mode0
= insn_data
[icode
].operand
[0].mode
;
6932 mode2
= insn_data
[icode
].operand
[2].mode
;
6933 mode3
= insn_data
[icode
].operand
[3].mode
;
6934 mode4
= insn_data
[icode
].operand
[4].mode
;
6936 /* Do some correctness checks for the operands. */
6937 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6938 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6939 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6941 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6942 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6943 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6945 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6946 op3
= copy_to_mode_reg (mode3
, op3
);
6948 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6949 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6950 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6951 else if (icode
== CODE_FOR_vst32_n_insn
6952 && ((INTVAL (op4
) % 2) != 0))
6953 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6955 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6966 /* 2nd part: Expand regular builtins. */
6968 internal_error ("bad builtin fcode");
6970 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6975 if (target
== NULL_RTX
6976 || GET_MODE (target
) != tmode
6977 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6979 target
= gen_reg_rtx (tmode
);
6984 gcc_assert (n_args
<= 4);
6985 for (i
= 0; i
< n_args
; i
++, j
++)
6987 tree arg
= CALL_EXPR_ARG (exp
, i
);
6988 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6989 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6990 machine_mode opmode
= GET_MODE (op
);
6991 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6993 /* SIMD extension requires exact immediate operand match. */
6994 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6995 && (id
< ARC_BUILTIN_SIMD_END
)
6999 if (!CONST_INT_P (op
))
7000 error ("builtin requires an immediate for operand %d", j
);
7004 if (!satisfies_constraint_L (op
))
7005 error ("operand %d should be a 6 bit unsigned immediate", j
);
7008 if (!satisfies_constraint_P (op
))
7009 error ("operand %d should be a 8 bit unsigned immediate", j
);
7012 if (!satisfies_constraint_K (op
))
7013 error ("operand %d should be a 3 bit unsigned immediate", j
);
7016 error ("unknown builtin immediate operand type for operand %d",
7021 if (CONST_INT_P (op
))
7024 if ((opmode
== SImode
) && (mode
== HImode
))
7027 op
= gen_lowpart (HImode
, op
);
7030 /* In case the insn wants input operands in modes different from
7031 the result, abort. */
7032 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
7034 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
7035 op
= copy_to_mode_reg (mode
, op
);
7040 pat
= apply_GEN_FCN (icode
, xop
);
7041 if (pat
== NULL_RTX
)
7052 /* Implement TARGET_FOLD_BUILTIN. */
7055 arc_fold_builtin (tree fndecl
, int n_args ATTRIBUTE_UNUSED
, tree
*arg
,
7056 bool ignore ATTRIBUTE_UNUSED
)
7058 unsigned int fcode
= DECL_MD_FUNCTION_CODE (fndecl
);
7065 case ARC_BUILTIN_SWAP
:
7066 return fold_build2 (LROTATE_EXPR
, integer_type_node
, arg
[0],
7067 build_int_cst (integer_type_node
, 16));
7069 case ARC_BUILTIN_NORM
:
7070 if (TREE_CODE (arg
[0]) == INTEGER_CST
7071 && !TREE_OVERFLOW (arg
[0]))
7073 wide_int arg0
= wi::to_wide (arg
[0], 32);
7074 wide_int result
= wi::shwi (wi::clrsb (arg0
), 32);
7075 return wide_int_to_tree (integer_type_node
, result
);
7079 case ARC_BUILTIN_NORMW
:
7080 if (TREE_CODE (arg
[0]) == INTEGER_CST
7081 && !TREE_OVERFLOW (arg
[0]))
7083 wide_int arg0
= wi::to_wide (arg
[0], 16);
7084 wide_int result
= wi::shwi (wi::clrsb (arg0
), 32);
7085 return wide_int_to_tree (integer_type_node
, result
);
7092 /* Returns true if the operands[opno] is a valid compile-time constant to be
7093 used as register number in the code for builtins. Else it flags an error
7094 and returns false. */
7097 check_if_valid_regno_const (rtx
*operands
, int opno
)
7100 switch (GET_CODE (operands
[opno
]))
7107 error ("register number must be a compile-time constant. "
7108 "Try giving higher optimization levels");
7114 /* Return true if it is ok to make a tail-call to DECL. */
7117 arc_function_ok_for_sibcall (tree decl
,
7118 tree exp ATTRIBUTE_UNUSED
)
7120 tree attrs
= NULL_TREE
;
7122 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7123 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
7128 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
7130 if (lookup_attribute ("jli_always", attrs
))
7132 if (lookup_attribute ("jli_fixed", attrs
))
7134 if (lookup_attribute ("secure_call", attrs
))
7138 /* Everything else is ok. */
7142 /* Output code to add DELTA to the first argument, and then jump
7143 to FUNCTION. Used for C++ multiple inheritance. */
7146 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7147 HOST_WIDE_INT delta
,
7148 HOST_WIDE_INT vcall_offset
,
7151 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk
));
7152 int mi_delta
= delta
;
7153 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
7156 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
7159 assemble_start_function (thunk
, fnname
);
7162 mi_delta
= - mi_delta
;
7164 /* Add DELTA. When possible use a plain add, otherwise load it into
7165 a register first. */
7167 while (mi_delta
!= 0)
7169 if ((mi_delta
& (3 << shift
)) == 0)
7173 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
7174 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
7175 mi_delta
& (0xff << shift
));
7176 mi_delta
&= ~(0xff << shift
);
7181 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7182 if (vcall_offset
!= 0)
7184 /* ld r12,[this] --> temp = *this
7185 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7187 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7188 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7189 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
7190 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
7191 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
7192 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7193 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
7194 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
7195 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
7198 fnaddr
= XEXP (DECL_RTL (function
), 0);
7200 if (arc_is_longcall_p (fnaddr
))
7204 asm_fprintf (file
, "\tld\t%s, [pcl, @",
7205 ARC_TEMP_SCRATCH_REG
);
7206 assemble_name (file
, XSTR (fnaddr
, 0));
7207 fputs ("@gotpc]\n", file
);
7208 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
7212 fputs ("\tj\t@", file
);
7213 assemble_name (file
, XSTR (fnaddr
, 0));
7218 fputs ("\tb\t@", file
);
7219 assemble_name (file
, XSTR (fnaddr
, 0));
7221 fputs ("@plt\n", file
);
7224 assemble_end_function (thunk
, fnname
);
7227 /* Return true if a 32 bit "long_call" should be generated for
7228 this calling SYM_REF. We generate a long_call if the function:
7230 a. has an __attribute__((long call))
7231 or b. the -mlong-calls command line switch has been specified
7233 However we do not generate a long call if the function has an
7234 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7236 This function will be called by C fragments contained in the machine
7237 description file. */
7240 arc_is_longcall_p (rtx sym_ref
)
7242 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7245 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
7246 || (TARGET_LONG_CALLS_SET
7247 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7248 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7252 /* Likewise for short calls. */
7255 arc_is_shortcall_p (rtx sym_ref
)
7257 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7260 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7261 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
7262 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
7263 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7267 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7270 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7272 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
7276 HOST_WIDE_INT size
= int_size_in_bytes (type
);
7277 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
7282 arc_pass_by_reference (cumulative_args_t
, const function_arg_info
&arg
)
7284 return (arg
.type
!= 0
7285 && (TREE_CODE (TYPE_SIZE (arg
.type
)) != INTEGER_CST
7286 || TREE_ADDRESSABLE (arg
.type
)));
7289 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7292 arc_can_use_doloop_p (const widest_int
&,
7293 const widest_int
&iterations_max
,
7294 unsigned int loop_depth
, bool entered_at_top
)
7296 /* Considering limitations in the hardware, only use doloop
7297 for innermost loops which must be entered from the top. */
7298 if (loop_depth
> 1 || !entered_at_top
)
7301 /* Check for lp_count width boundary. */
7302 if (arc_lpcwidth
!= 32
7303 && (wi::gtu_p (iterations_max
, ((1 << arc_lpcwidth
) - 1))
7304 || wi::eq_p (iterations_max
, 0)))
7309 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7310 return why doloop cannot be applied. */
7313 arc_invalid_within_doloop (const rtx_insn
*insn
)
7316 return "Function call in the loop.";
7318 /* FIXME! add here all the ZOL exceptions. */
7322 /* Return the next active insn, skiping the inline assembly code. */
7325 arc_active_insn (rtx_insn
*insn
)
7329 insn
= NEXT_INSN (insn
);
7331 || (active_insn_p (insn
)
7332 && NONDEBUG_INSN_P (insn
)
7334 && GET_CODE (PATTERN (insn
)) != UNSPEC_VOLATILE
7335 && GET_CODE (PATTERN (insn
)) != PARALLEL
))
7341 /* Search for a sequence made out of two stores and a given number of
7342 loads, insert a nop if required. */
7345 check_store_cacheline_hazard (void)
7347 rtx_insn
*insn
, *succ0
, *insn1
;
7350 for (insn
= get_insns (); insn
; insn
= arc_active_insn (insn
))
7352 succ0
= arc_active_insn (insn
);
7357 if (!single_set (insn
))
7360 if ((get_attr_type (insn
) != TYPE_STORE
))
7363 /* Found at least two consecutive stores. Goto the end of the
7365 for (insn1
= succ0
; insn1
; insn1
= arc_active_insn (insn1
))
7366 if (!single_set (insn1
) || get_attr_type (insn1
) != TYPE_STORE
)
7369 /* Save were we are. */
7372 /* Now, check the next two instructions for the following cases:
7373 1. next instruction is a LD => insert 2 nops between store
7375 2. next-next instruction is a LD => inset 1 nop after the store
7377 if (insn1
&& single_set (insn1
)
7378 && (get_attr_type (insn1
) == TYPE_LOAD
))
7381 emit_insn_before (gen_nopv (), insn1
);
7382 emit_insn_before (gen_nopv (), insn1
);
7386 if (insn1
&& (get_attr_type (insn1
) == TYPE_COMPARE
))
7388 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7389 reorg, so it is safe to reuse it for avoiding the
7390 current compare insn to be part of a BRcc
7392 add_reg_note (insn1
, REG_SAVE_NOTE
, GEN_INT (3));
7394 insn1
= arc_active_insn (insn1
);
7395 if (insn1
&& single_set (insn1
)
7396 && (get_attr_type (insn1
) == TYPE_LOAD
))
7399 emit_insn_before (gen_nopv (), insn1
);
7413 /* Return true if a load instruction (CONSUMER) uses the same address as a
7414 store instruction (PRODUCER). This function is used to avoid st/ld
7415 address hazard in ARC700 cores. */
7418 arc_store_addr_hazard_internal_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7420 rtx in_set
, out_set
;
7421 rtx out_addr
, in_addr
;
7429 /* Peel the producer and the consumer for the address. */
7430 out_set
= single_set (producer
);
7433 out_addr
= SET_DEST (out_set
);
7436 if (GET_CODE (out_addr
) == ZERO_EXTEND
7437 || GET_CODE (out_addr
) == SIGN_EXTEND
)
7438 out_addr
= XEXP (out_addr
, 0);
7440 if (!MEM_P (out_addr
))
7443 in_set
= single_set (consumer
);
7446 in_addr
= SET_SRC (in_set
);
7449 if (GET_CODE (in_addr
) == ZERO_EXTEND
7450 || GET_CODE (in_addr
) == SIGN_EXTEND
)
7451 in_addr
= XEXP (in_addr
, 0);
7453 if (!MEM_P (in_addr
))
7455 /* Get rid of the MEM and check if the addresses are
7457 in_addr
= XEXP (in_addr
, 0);
7458 out_addr
= XEXP (out_addr
, 0);
7460 return exp_equiv_p (in_addr
, out_addr
, 0, true);
7466 /* Return TRUE is we have an store address hazard. */
7469 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7471 if (TARGET_ARC700
&& (arc_tune
!= ARC_TUNE_ARC7XX
))
7473 return arc_store_addr_hazard_internal_p (producer
, consumer
);
7476 /* Return length adjustment for INSN.
7478 A write to a core reg greater or equal to 32 must not be immediately
7479 followed by a use. Anticipate the length requirement to insert a nop
7480 between PRED and SUCC to prevent a hazard. */
7483 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
7487 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
7488 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
7489 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
7490 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
7491 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
7492 || recog_memoized (pred
) == CODE_FOR_umul_600
7493 || recog_memoized (pred
) == CODE_FOR_mac_600
7494 || recog_memoized (pred
) == CODE_FOR_mul64_600
7495 || recog_memoized (pred
) == CODE_FOR_mac64_600
7496 || recog_memoized (pred
) == CODE_FOR_umul64_600
7497 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
7499 subrtx_iterator::array_type array
;
7500 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
7502 const_rtx x
= *iter
;
7503 switch (GET_CODE (x
))
7505 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
7508 /* This is also fine for PRE/POST_MODIFY, because they
7512 rtx dest
= XEXP (x
, 0);
7513 /* Check if this sets a an extension register. N.B. we use 61 for the
7514 condition codes, which is definitely not an extension register. */
7515 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
7516 /* Check if the same register is used by the PAT. */
7517 && (refers_to_regno_p
7519 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
7520 PATTERN (succ
), 0)))
7527 A write to a core reg greater or equal to 32 must not be immediately
7528 followed by a use. Anticipate the length requirement to insert a nop
7529 between PRED and SUCC to prevent a hazard. */
7532 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
7534 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
7538 return arc600_corereg_hazard (pred
, succ
);
7543 /* When compiling for release 310a, insert a nop before any
7544 conditional jump. */
7547 arc_check_release31a (rtx_insn
*pred
, rtx_insn
*succ
)
7549 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
7552 if (!JUMP_P (pred
) && !single_set (pred
))
7555 if (!JUMP_P (succ
) && !single_set (succ
))
7558 if (TARGET_HS
&& (arc_tune
== ARC_TUNE_ARCHS4X_REL31A
))
7559 switch (get_attr_type (pred
))
7562 switch (get_attr_type (succ
))
7565 case TYPE_BRCC_NO_DELAY_SLOT
:
7573 case TYPE_BRCC_NO_DELAY_SLOT
:
7575 if (get_attr_type (succ
) == TYPE_STORE
)
7585 /* The same functionality as arc_hazard. It is called in machine
7586 reorg before any other optimization. Hence, the NOP size is taken
7587 into account when doing branch shortening. */
7590 workaround_arc_anomaly (void)
7592 rtx_insn
*insn
, *succ0
;
7594 /* For any architecture: call arc_hazard here. */
7595 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7597 succ0
= next_real_insn (insn
);
7598 if (arc_hazard (insn
, succ0
) || arc_check_release31a (insn
, succ0
))
7599 emit_insn_before (gen_nopv (), succ0
);
7605 /* Old A7 are suffering of a cache hazard, and we need to insert two
7606 nops between any sequence of stores and a load. */
7607 if (arc_tune
!= ARC_TUNE_ARC7XX
)
7608 check_store_cacheline_hazard ();
7611 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7612 turns out not to be optimizable; we have to split the loop_end pattern into
7613 a subtract and a test. */
7616 hwloop_fail (hwloop_info loop
)
7619 rtx insn
= loop
->loop_end
;
7622 && (loop
->length
&& (loop
->length
<= ARC_MAX_LOOP_LENGTH
))
7623 && REG_P (loop
->iter_reg
))
7625 /* TARGET_V2 core3 has dbnz instructions. */
7626 test
= gen_dbnz (loop
->iter_reg
, loop
->start_label
);
7627 insn
= emit_jump_insn_before (test
, loop
->loop_end
);
7629 else if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
) == LP_COUNT
))
7631 /* We have the lp_count as loop iterator, try to use it. */
7632 emit_insn_before (gen_loop_fail (), loop
->loop_end
);
7633 test
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CC_ZNmode
, CC_REG
),
7635 test
= gen_rtx_IF_THEN_ELSE (VOIDmode
, test
,
7636 gen_rtx_LABEL_REF (Pmode
, loop
->start_label
),
7638 insn
= emit_jump_insn_before (gen_rtx_SET (pc_rtx
, test
),
7643 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
7647 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
7648 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
7654 JUMP_LABEL (insn
) = loop
->start_label
;
7655 LABEL_NUSES (loop
->start_label
)++;
7656 delete_insn (loop
->loop_end
);
7659 /* Return the next insn after INSN that is not a NOTE, but stop the
7660 search before we enter another basic block. This routine does not
7661 look inside SEQUENCEs. */
7664 next_nonnote_insn_bb (rtx_insn
*insn
)
7668 insn
= NEXT_INSN (insn
);
7669 if (insn
== 0 || !NOTE_P (insn
))
7671 if (NOTE_INSN_BASIC_BLOCK_P (insn
))
7678 /* Optimize LOOP. */
7681 hwloop_optimize (hwloop_info loop
)
7685 basic_block entry_bb
, bb
;
7687 rtx_insn
*insn
, *seq
, *entry_after
, *last_insn
, *end_label
;
7688 unsigned int length
;
7689 bool need_fix
= false;
7690 rtx lp_reg
= gen_rtx_REG (SImode
, LP_COUNT
);
7692 if (loop
->depth
> 1)
7695 fprintf (dump_file
, ";; loop %d is not innermost\n",
7700 if (!loop
->incoming_dest
)
7703 fprintf (dump_file
, ";; loop %d has more than one entry\n",
7708 if (loop
->incoming_dest
!= loop
->head
)
7711 fprintf (dump_file
, ";; loop %d is not entered from head\n",
7716 if (loop
->has_call
|| loop
->has_asm
)
7719 fprintf (dump_file
, ";; loop %d has invalid insn\n",
7724 /* Scan all the blocks to make sure they don't use iter_reg. */
7725 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
7728 fprintf (dump_file
, ";; loop %d uses iterator\n",
7733 /* Check if start_label appears before doloop_end. */
7735 for (insn
= loop
->start_label
;
7736 insn
&& insn
!= loop
->loop_end
;
7737 insn
= NEXT_INSN (insn
))
7739 length
+= NONDEBUG_INSN_P (insn
) ? get_attr_length (insn
) : 0;
7740 if (JUMP_TABLES_IN_TEXT_SECTION
7741 && JUMP_TABLE_DATA_P (insn
))
7744 fprintf (dump_file
, ";; loop %d has a jump table\n",
7753 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
7758 loop
->length
= length
;
7759 if (loop
->length
> ARC_MAX_LOOP_LENGTH
)
7762 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7765 else if (!loop
->length
)
7768 fprintf (dump_file
, ";; loop %d is empty\n", loop
->loop_no
);
7772 /* Check if we use a register or not. */
7773 if (!REG_P (loop
->iter_reg
))
7776 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7781 /* Check if we use a register or not. */
7782 if (!REG_P (loop
->iter_reg
))
7785 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
7790 /* Check if loop register is lpcount. */
7791 if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
)) != LP_COUNT
)
7794 fprintf (dump_file
, ";; loop %d doesn't use lp_count as loop"
7797 /* This loop doesn't use the lp_count, check though if we can
7799 if (TEST_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
)
7800 /* In very unique cases we may have LP_COUNT alive. */
7801 || (loop
->incoming_src
7802 && REGNO_REG_SET_P (df_get_live_out (loop
->incoming_src
),
7806 fprintf (dump_file
, ";; loop %d, lp_count is alive", loop
->loop_no
);
7813 /* Check for control like instruction as the last instruction of a
7816 last_insn
= PREV_INSN (loop
->loop_end
);
7820 for (; last_insn
!= BB_HEAD (bb
);
7821 last_insn
= PREV_INSN (last_insn
))
7822 if (NONDEBUG_INSN_P (last_insn
))
7825 if (last_insn
!= BB_HEAD (bb
))
7828 if (single_pred_p (bb
)
7829 && single_pred_edge (bb
)->flags
& EDGE_FALLTHRU
7830 && single_pred (bb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
))
7832 bb
= single_pred (bb
);
7833 last_insn
= BB_END (bb
);
7846 fprintf (dump_file
, ";; loop %d has no last instruction\n",
7851 if ((TARGET_ARC600_FAMILY
|| TARGET_HS
)
7852 && INSN_P (last_insn
)
7853 && (JUMP_P (last_insn
) || CALL_P (last_insn
)
7854 || GET_CODE (PATTERN (last_insn
)) == SEQUENCE
7855 /* At this stage we can have (insn (clobber (mem:BLK
7856 (reg)))) instructions, ignore them. */
7857 || (GET_CODE (PATTERN (last_insn
)) != CLOBBER
7858 && (get_attr_type (last_insn
) == TYPE_BRCC
7859 || get_attr_type (last_insn
) == TYPE_BRCC_NO_DELAY_SLOT
))))
7861 if (loop
->length
+ 2 > ARC_MAX_LOOP_LENGTH
)
7864 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7868 fprintf (dump_file
, ";; loop %d has a control like last insn; "
7872 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7875 if (LABEL_P (last_insn
))
7878 fprintf (dump_file
, ";; loop %d has a label as last insn; "
7881 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
7884 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7885 and we can use it to indicate the last ZOL instruction cannot be
7886 part of a delay slot. */
7887 add_reg_note (last_insn
, REG_SAVE_NOTE
, GEN_INT (2));
7889 loop
->last_insn
= last_insn
;
7891 /* Get the loop iteration register. */
7892 iter_reg
= loop
->iter_reg
;
7894 gcc_assert (REG_P (iter_reg
));
7898 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
7899 if (entry_edge
->flags
& EDGE_FALLTHRU
)
7902 if (entry_edge
== NULL
)
7905 fprintf (dump_file
, ";; loop %d has no fallthru edge jumping "
7910 /* The loop is good. */
7911 end_label
= gen_label_rtx ();
7912 loop
->end_label
= end_label
;
7914 /* Place the zero_cost_loop_start instruction before the loop. */
7915 entry_bb
= entry_edge
->src
;
7921 /* The loop uses a R-register, but the lp_count is free, thus
7923 emit_insn (gen_rtx_SET (lp_reg
, iter_reg
));
7924 SET_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
);
7928 fprintf (dump_file
, ";; fix loop %d to use lp_count\n",
7933 insn
= emit_insn (gen_arc_lp (loop
->start_label
,
7939 entry_after
= BB_END (entry_bb
);
7940 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
7947 emit_insn_before (seq
, BB_HEAD (loop
->head
));
7948 seq
= emit_label_before (gen_label_rtx (), seq
);
7949 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
7950 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
7952 if (!(e
->flags
& EDGE_FALLTHRU
))
7953 redirect_edge_and_branch_force (e
, new_bb
);
7955 redirect_edge_succ (e
, new_bb
);
7958 make_edge (new_bb
, loop
->head
, 0);
7963 while (DEBUG_INSN_P (entry_after
)
7964 || (NOTE_P (entry_after
)
7965 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
7966 /* Make sure we don't split a call and its corresponding
7967 CALL_ARG_LOCATION note. */
7968 && NOTE_KIND (entry_after
) != NOTE_INSN_CALL_ARG_LOCATION
))
7969 entry_after
= NEXT_INSN (entry_after
);
7971 entry_after
= next_nonnote_insn_bb (entry_after
);
7973 gcc_assert (entry_after
);
7974 emit_insn_before (seq
, entry_after
);
7977 /* Insert the loop end label before the last instruction of the
7979 emit_label_after (end_label
, loop
->last_insn
);
7980 /* Make sure we mark the begining and end label as used. */
7981 LABEL_NUSES (loop
->end_label
)++;
7982 LABEL_NUSES (loop
->start_label
)++;
7987 /* A callback for the hw-doloop pass. This function examines INSN; if
7988 it is a loop_end pattern we recognize, return the reg rtx for the
7989 loop counter. Otherwise, return NULL_RTX. */
7992 hwloop_pattern_reg (rtx_insn
*insn
)
7996 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
7999 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
8005 static struct hw_doloop_hooks arc_doloop_hooks
=
8012 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8013 and tries to rewrite the RTL of these loops so that proper Blackfin
8014 hardware loops are generated. */
8017 arc_reorg_loops (void)
8019 reorg_loops (true, &arc_doloop_hooks
);
8022 /* Scan all calls and add symbols to be emitted in the jli section if
8026 jli_call_scan (void)
8030 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8035 rtx pat
= PATTERN (insn
);
8036 if (GET_CODE (pat
) == COND_EXEC
)
8037 pat
= COND_EXEC_CODE (pat
);
8038 pat
= XVECEXP (pat
, 0, 0);
8039 if (GET_CODE (pat
) == SET
)
8040 pat
= SET_SRC (pat
);
8042 pat
= XEXP (XEXP (pat
, 0), 0);
8043 if (GET_CODE (pat
) == SYMBOL_REF
8044 && arc_is_jli_call_p (pat
))
8045 arc_add_jli_section (pat
);
8049 /* Add padding if necessary to avoid a mispredict. A return could
8050 happen immediately after the function start. A call/return and
8051 return/return must be 6 bytes apart to avoid mispredict. */
8059 if (!TARGET_PAD_RETURN
)
8062 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8064 rtx_insn
*prev0
= prev_active_insn (insn
);
8065 bool wantlong
= false;
8067 if (!INSN_P (insn
) || GET_CODE (PATTERN (insn
)) != SIMPLE_RETURN
)
8072 prev0
= emit_insn_before (gen_nopv (), insn
);
8073 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8074 so it is safe to reuse it for forcing a particular length
8075 for an instruction. */
8076 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
8077 emit_insn_before (gen_nopv (), insn
);
8080 offset
= get_attr_length (prev0
);
8082 if (get_attr_length (prev0
) == 2
8083 && get_attr_iscompact (prev0
) != ISCOMPACT_TRUE
)
8085 /* Force long version of the insn. */
8090 rtx_insn
*prev
= prev_active_insn (prev0
);
8092 offset
+= get_attr_length (prev
);
8094 prev
= prev_active_insn (prev
);
8096 offset
+= get_attr_length (prev
);
8101 prev
= emit_insn_before (gen_nopv (), insn
);
8102 add_reg_note (prev
, REG_SAVE_NOTE
, GEN_INT (1));
8105 emit_insn_before (gen_nopv (), insn
);
8112 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
8114 /* Emit a blockage to avoid delay slot scheduling. */
8115 emit_insn_before (gen_blockage (), insn
);
8119 static int arc_reorg_in_progress
= 0;
8121 /* ARC's machince specific reorg function. */
8132 cfun
->machine
->arc_reorg_started
= 1;
8133 arc_reorg_in_progress
= 1;
8135 compute_bb_for_insn ();
8139 /* Doloop optimization. */
8142 workaround_arc_anomaly ();
8146 /* There are cases when conditional execution is only possible after
8147 delay slot scheduling:
8149 - If a delay slot is filled with a nocond/set insn from above, the previous
8150 basic block can become elegible for conditional execution.
8151 - If a delay slot is filled with a nocond insn from the fall-through path,
8152 the branch with that delay slot can become eligble for conditional
8153 execution (however, with the same sort of data flow analysis that dbr
8154 does, we could have figured out before that we don't need to
8155 conditionalize this insn.)
8156 - If a delay slot insn is filled with an insn from the target, the
8157 target label gets its uses decremented (even deleted if falling to zero),
8158 thus possibly creating more condexec opportunities there.
8159 Therefore, we should still be prepared to apply condexec optimization on
8160 non-prepared branches if the size increase of conditionalized insns is no
8161 more than the size saved from eliminating the branch. An invocation option
8162 could also be used to reserve a bit of extra size for condbranches so that
8163 this'll work more often (could also test in arc_reorg if the block is
8164 'close enough' to be eligible for condexec to make this likely, and
8165 estimate required size increase). */
8166 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8167 if (TARGET_NO_BRCC_SET
)
8172 init_insn_lengths();
8175 /* Call shorten_branches to calculate the insn lengths. */
8176 shorten_branches (get_insns());
8178 if (!INSN_ADDRESSES_SET_P())
8179 fatal_error (input_location
,
8180 "insn addresses not set after shorten branches");
8182 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8185 enum attr_type insn_type
;
8187 /* If a non-jump insn (or a casesi jump table), continue. */
8188 if (GET_CODE (insn
) != JUMP_INSN
||
8189 GET_CODE (PATTERN (insn
)) == ADDR_VEC
8190 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
8193 /* If we already have a brcc, note if it is suitable for brcc_s.
8194 Be a bit generous with the brcc_s range so that we can take
8195 advantage of any code shortening from delay slot scheduling. */
8196 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
8198 rtx pat
= PATTERN (insn
);
8199 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
8200 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
8202 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
8203 if ((offset
>= -140 && offset
< 140)
8204 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
8205 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
8206 && equality_comparison_operator (op
, VOIDmode
))
8207 PUT_MODE (*ccp
, CC_Zmode
);
8208 else if (GET_MODE (*ccp
) == CC_Zmode
)
8209 PUT_MODE (*ccp
, CC_ZNmode
);
8212 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
8213 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
8216 /* OK. so we have a jump insn. */
8217 /* We need to check that it is a bcc. */
8218 /* Bcc => set (pc) (if_then_else ) */
8219 pattern
= PATTERN (insn
);
8220 if (GET_CODE (pattern
) != SET
8221 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
8222 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
8225 /* Now check if the jump is beyond the s9 range. */
8226 if (CROSSING_JUMP_P (insn
))
8228 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
8230 if(offset
> 253 || offset
< -254)
8233 pc_target
= SET_SRC (pattern
);
8235 /* Avoid FPU instructions. */
8236 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
8237 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUEmode
)
8238 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
8241 /* Now go back and search for the set cc insn. */
8243 label
= XEXP (pc_target
, 1);
8247 rtx_insn
*scan
, *link_insn
= NULL
;
8249 for (scan
= PREV_INSN (insn
);
8250 scan
&& GET_CODE (scan
) != CODE_LABEL
;
8251 scan
= PREV_INSN (scan
))
8253 if (! INSN_P (scan
))
8255 pat
= PATTERN (scan
);
8256 if (GET_CODE (pat
) == SET
8257 && cc_register (SET_DEST (pat
), VOIDmode
))
8267 /* Check if this is a data dependency. */
8268 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
8271 /* Make sure we can use it for brcc insns. */
8272 if (find_reg_note (link_insn
, REG_SAVE_NOTE
, GEN_INT (3)))
8275 /* Ok this is the set cc. copy args here. */
8276 op
= XEXP (pc_target
, 0);
8278 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
8279 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
8280 if (GET_CODE (op0
) == ZERO_EXTRACT
8281 && XEXP (op0
, 1) == const1_rtx
8282 && (GET_CODE (op
) == EQ
8283 || GET_CODE (op
) == NE
))
8285 /* btst / b{eq,ne} -> bbit{0,1} */
8286 op0
= XEXP (cmp0
, 0);
8287 op1
= XEXP (cmp0
, 2);
8289 else if (!register_operand (op0
, VOIDmode
)
8290 || !general_operand (op1
, VOIDmode
))
8292 /* Be careful not to break what cmpsfpx_raw is
8293 trying to create for checking equality of
8294 single-precision floats. */
8295 else if (TARGET_SPFP
8296 && GET_MODE (op0
) == SFmode
8297 && GET_MODE (op1
) == SFmode
)
8300 /* None of the two cmp operands should be set between the
8301 cmp and the branch. */
8302 if (reg_set_between_p (op0
, link_insn
, insn
))
8305 if (reg_set_between_p (op1
, link_insn
, insn
))
8308 /* Since the MODE check does not work, check that this is
8309 CC reg's last set location before insn, and also no
8310 instruction between the cmp and branch uses the
8312 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
8313 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
8316 /* CC reg should be dead after insn. */
8317 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
8320 op
= gen_rtx_fmt_ee (GET_CODE (op
),
8321 GET_MODE (op
), cmp0
, cmp1
);
8322 /* If we create a LIMM where there was none before,
8323 we only benefit if we can avoid a scheduling bubble
8324 for the ARC600. Otherwise, we'd only forgo chances
8325 at short insn generation, and risk out-of-range
8327 if (!brcc_nolimm_operator (op
, VOIDmode
)
8328 && !long_immediate_operand (op1
, VOIDmode
)
8330 || (TARGET_V2
&& optimize_size
)
8331 || next_active_insn (link_insn
) != insn
))
8334 /* Emit bbit / brcc (or brcc_s if possible).
8335 CC_Zmode indicates that brcc_s is possible. */
8338 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
8339 else if ((offset
>= -140 && offset
< 140)
8340 && rtx_equal_p (op1
, const0_rtx
)
8341 && compact_register_operand (op0
, VOIDmode
)
8342 && (GET_CODE (op
) == EQ
8343 || GET_CODE (op
) == NE
))
8344 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
8346 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
8349 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
8350 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
8351 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
8354 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
8355 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
8357 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
8358 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
8361 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8362 REG_NOTES (brcc_insn
) = note
;
8364 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
8367 remove_note (link_insn
, note
);
8368 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8369 REG_NOTES (brcc_insn
) = note
;
8371 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
8374 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8375 REG_NOTES (brcc_insn
) = note
;
8380 /* Delete the bcc insn. */
8381 set_insn_deleted (insn
);
8383 /* Delete the cmp insn. */
8384 set_insn_deleted (link_insn
);
8389 /* Clear out insn_addresses. */
8390 INSN_ADDRESSES_FREE ();
8394 if (INSN_ADDRESSES_SET_P())
8395 fatal_error (input_location
, "insn addresses not freed");
8397 arc_reorg_in_progress
= 0;
8400 /* Check if the operands are valid for BRcc.d generation
8401 Valid Brcc.d patterns are
8405 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
8406 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8407 does not have a delay slot
8409 Assumed precondition: Second operand is either a register or a u6 value. */
8412 valid_brcc_with_delay_p (rtx
*operands
)
8414 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
8416 return brcc_nolimm_operator (operands
[0], VOIDmode
);
8419 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8420 access DECL using %gp_rel(...)($gp). */
8423 arc_in_small_data_p (const_tree decl
)
8428 /* Only variables are going into small data area. */
8429 if (TREE_CODE (decl
) != VAR_DECL
)
8432 if (TARGET_NO_SDATA_SET
)
8435 /* Disable sdata references to weak variables. */
8436 if (DECL_WEAK (decl
))
8439 /* Don't put constants into the small data section: we want them to
8440 be in ROM rather than RAM. */
8441 if (TREE_READONLY (decl
))
8444 /* To ensure -mvolatile-cache works ld.di does not have a
8445 gp-relative variant. */
8446 if (!TARGET_VOLATILE_CACHE_SET
8447 && TREE_THIS_VOLATILE (decl
))
8450 /* Likewise for uncached data. */
8451 attr
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
8452 if (lookup_attribute ("uncached", attr
))
8455 /* and for aux regs. */
8456 attr
= DECL_ATTRIBUTES (decl
);
8457 if (lookup_attribute ("aux", attr
))
8460 if (DECL_SECTION_NAME (decl
) != 0)
8462 const char *name
= DECL_SECTION_NAME (decl
);
8463 if (strcmp (name
, ".sdata") == 0
8464 || strcmp (name
, ".sbss") == 0)
8467 /* If it's not public, there's no need to put it in the small data
8469 else if (TREE_PUBLIC (decl
))
8471 size
= int_size_in_bytes (TREE_TYPE (decl
));
8472 return (size
> 0 && size
<= g_switch_value
);
8477 /* Return true if OP is an acceptable memory operand for ARCompact
8478 16-bit gp-relative load instructions.
8480 /* volatile cache option still to be handled. */
8483 compact_sda_memory_operand (rtx op
, machine_mode mode
, bool short_p
)
8490 /* Eliminate non-memory operations. */
8491 if (GET_CODE (op
) != MEM
)
8494 if (mode
== VOIDmode
)
8495 mode
= GET_MODE (op
);
8497 size
= GET_MODE_SIZE (mode
);
8499 /* dword operations really put out 2 instructions, so eliminate them. */
8500 if (size
> UNITS_PER_WORD
)
8503 /* Decode the address now. */
8504 addr
= XEXP (op
, 0);
8506 if (!legitimate_small_data_address_p (addr
, mode
))
8509 if (!short_p
|| size
== 1)
8512 /* Now check for the alignment, the short loads using gp require the
8513 addresses to be aligned. */
8514 align
= get_symbol_alignment (addr
);
8525 if (align
&& ((align
& mask
) == 0))
8530 /* Return TRUE if PAT is accessing an aux-reg. */
8533 arc_is_aux_reg_p (rtx pat
)
8535 tree attrs
= NULL_TREE
;
8541 /* Get the memory attributes. */
8542 addr
= MEM_EXPR (pat
);
8546 /* Get the attributes. */
8548 attrs
= DECL_ATTRIBUTES (addr
);
8549 else if (TREE_CODE (addr
) == MEM_REF
)
8550 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
8554 if (lookup_attribute ("aux", attrs
))
8559 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8562 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
8563 unsigned HOST_WIDE_INT size
,
8564 unsigned HOST_WIDE_INT align
,
8565 unsigned HOST_WIDE_INT globalize_p
)
8567 int in_small_data
= arc_in_small_data_p (decl
);
8568 rtx mem
= decl
== NULL_TREE
? NULL_RTX
: DECL_RTL (decl
);
8570 /* Don't output aux-reg symbols. */
8571 if (mem
!= NULL_RTX
&& MEM_P (mem
)
8572 && SYMBOL_REF_P (XEXP (mem
, 0))
8573 && arc_is_aux_reg_p (mem
))
8577 switch_to_section (get_named_section (NULL
, ".sbss", 0));
8578 /* named_section (0,".sbss",0); */
8580 switch_to_section (bss_section
);
8583 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
8585 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
8586 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
8587 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
8588 ASM_OUTPUT_LABEL (stream
, name
);
8591 ASM_OUTPUT_SKIP (stream
, size
);
8595 arc_preserve_reload_p (rtx in
)
8597 return (GET_CODE (in
) == PLUS
8598 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
8599 && CONST_INT_P (XEXP (in
, 1))
8600 && !((INTVAL (XEXP (in
, 1)) & 511)));
8603 /* Implement TARGET_REGISTER_MOVE_COST. */
8606 arc_register_move_cost (machine_mode
,
8607 reg_class_t from_class
, reg_class_t to_class
)
8609 /* Force an attempt to 'mov Dy,Dx' to spill. */
8610 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
8611 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
8617 /* Emit code for an addsi3 instruction with OPERANDS.
8618 COND_P indicates if this will use conditional execution.
8619 Return the length of the instruction.
8620 If OUTPUT_P is false, don't actually output the instruction, just return
8623 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
8627 int match
= operands_match_p (operands
[0], operands
[1]);
8628 int match2
= operands_match_p (operands
[0], operands
[2]);
8629 int intval
= (REG_P (operands
[2]) ? 1
8630 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
8631 int neg_intval
= -intval
;
8632 int short_0
= arc_check_short_reg_p (operands
[0]);
8633 int short_p
= (!cond_p
&& short_0
&& arc_check_short_reg_p (operands
[1]));
8636 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8637 && REGNO (OP) != 30) \
8640 #define ADDSI_OUTPUT1(FORMAT) do {\
8642 output_asm_insn (FORMAT, operands);\
8645 #define ADDSI_OUTPUT(LIST) do {\
8648 ADDSI_OUTPUT1 (format);\
8652 /* First try to emit a 16 bit insn. */
8655 /* If we are actually about to output this insn, don't try a 16 bit
8656 variant if we already decided that we don't want that
8657 (I.e. we upsized this insn to align some following insn.)
8658 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8659 but add1 r0,sp,35 doesn't. */
8660 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
8662 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8665 && ((REG_H_P (operands
[2])
8666 && (match
|| arc_check_short_reg_p (operands
[2])))
8667 || (CONST_INT_P (operands
[2])
8668 && ((unsigned) intval
<= (match
? 127 : 7)))))
8669 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8671 /* Generate add_s b,b,h patterns. */
8672 if (short_0
&& match2
&& REG_H_P (operands
[1]))
8673 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8675 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8676 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
8677 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
8678 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8680 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
8681 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
8682 && match
&& !(neg_intval
& ~124)))
8683 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8685 /* Generate add_s h,h,s3 patterns. */
8686 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
8687 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
8688 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8690 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8691 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
8692 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
8693 && arc_check_short_reg_p (operands
[1])
8694 && satisfies_constraint_L (operands
[2]))
8695 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8698 /* Now try to emit a 32 bit insn without long immediate. */
8700 if (!match
&& match2
&& REG_P (operands
[1]))
8701 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8702 if (match
|| !cond_p
)
8704 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
8705 int range_factor
= neg_intval
& intval
;
8708 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
8709 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8711 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8712 same size, do, so - the insn latency is lower. */
8713 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8715 if ((intval
>= 0 && intval
<= limit
)
8716 || (intval
== -0x800 && limit
== 0x7ff))
8717 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8718 else if ((intval
< 0 && neg_intval
<= limit
)
8719 || (intval
== 0x800 && limit
== 0x7ff))
8720 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8721 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
8722 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
8723 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
8724 if (((intval
< 0 && intval
!= -0x4000)
8725 /* sub[123] is slower than add_s / sub, only use it if it
8726 avoids a long immediate. */
8727 && neg_intval
<= limit
<< shift
)
8728 || (intval
== 0x4000 && limit
== 0x7ff))
8729 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
8730 shift
, neg_intval
>> shift
));
8731 else if ((intval
>= 0 && intval
<= limit
<< shift
)
8732 || (intval
== -0x4000 && limit
== 0x7ff))
8733 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
8735 /* Try to emit a 16 bit opcode with long immediate. */
8737 if (short_p
&& match
)
8738 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8740 /* We have to use a 32 bit opcode, and with a long immediate. */
8742 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8745 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8746 Return the length of the instruction.
8747 If OUTPUT_P is false, don't actually output the instruction, just return
8750 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
8752 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
8753 const char *pat
= NULL
;
8755 /* Canonical rtl should not have a constant in the first operand position. */
8756 gcc_assert (!CONSTANT_P (operands
[1]));
8758 switch (commutative_op
)
8761 if (satisfies_constraint_C1p (operands
[2]))
8762 pat
= "bmsk%? %0,%1,%Z2";
8763 else if (satisfies_constraint_C2p (operands
[2]))
8765 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
8766 pat
= "bmskn%? %0,%1,%Z2";
8768 else if (satisfies_constraint_Ccp (operands
[2]))
8769 pat
= "bclr%? %0,%1,%M2";
8770 else if (satisfies_constraint_CnL (operands
[2]))
8771 pat
= "bic%? %0,%1,%n2-1";
8774 if (satisfies_constraint_C0p (operands
[2]))
8775 pat
= "bset%? %0,%1,%z2";
8778 if (satisfies_constraint_C0p (operands
[2]))
8779 pat
= "bxor%? %0,%1,%z2";
8782 return arc_output_addsi (operands
, true, output_p
);
8786 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
8787 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
8792 /* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
8793 Emit code and return an potentially modified address such that offsets
8794 up to SIZE are can be added to yield a legitimate address.
8795 if REUSE is set, ADDR is a register that may be modified. */
8798 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
8801 rtx offs
= const0_rtx
;
8803 if (GET_CODE (base
) == PLUS
)
8805 offs
= XEXP (base
, 1);
8806 base
= XEXP (base
, 0);
8809 || (REGNO (base
) != STACK_POINTER_REGNUM
8810 && REGNO_PTR_FRAME_P (REGNO (base
)))
8811 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
8812 || !SMALL_INT (INTVAL (offs
) + size
))
8815 emit_insn (gen_add2_insn (addr
, offs
));
8817 addr
= copy_to_mode_reg (Pmode
, addr
);
8822 /* Like move_by_pieces, but take account of load latency, and actual
8823 offset ranges. Return true on success. */
8826 arc_expand_cpymem (rtx
*operands
)
8828 rtx dst
= operands
[0];
8829 rtx src
= operands
[1];
8830 rtx dst_addr
, src_addr
;
8832 int align
= INTVAL (operands
[3]);
8839 if (!CONST_INT_P (operands
[2]))
8841 size
= INTVAL (operands
[2]);
8842 /* move_by_pieces_ninsns is static, so we can't use it. */
8846 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
8848 n_pieces
= (size
+ 2) / 4U + (size
& 1);
8850 else if (align
== 2)
8851 n_pieces
= (size
+ 1) / 2U;
8854 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
8856 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8858 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
8862 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
8863 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
8864 store
[0] = store
[1] = NULL_RTX
;
8865 tmpx
[0] = tmpx
[1] = NULL_RTX
;
8866 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
8871 while (piece
> size
)
8873 mode
= smallest_int_mode_for_size (piece
* BITS_PER_UNIT
);
8874 /* If we don't re-use temporaries, the scheduler gets carried away,
8875 and the register pressure gets unnecessarily high. */
8876 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
8879 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
8880 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
8881 src_addr
= force_offsettable (src_addr
, piece
, 1);
8883 emit_insn (store
[i
]);
8884 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
8885 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
8886 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
8887 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
8890 emit_insn (store
[i
]);
8892 emit_insn (store
[i
^1]);
8897 arc_get_aux_arg (rtx pat
, int *auxr
)
8899 tree attr
, addr
= MEM_EXPR (pat
);
8900 if (TREE_CODE (addr
) != VAR_DECL
)
8903 attr
= DECL_ATTRIBUTES (addr
);
8904 if (lookup_attribute ("aux", attr
))
8906 tree arg
= TREE_VALUE (attr
);
8909 *auxr
= TREE_INT_CST_LOW (TREE_VALUE (arg
));
8917 /* Prepare operands for move in MODE. Return true iff the move has
8921 prepare_move_operands (rtx
*operands
, machine_mode mode
)
8923 if ((MEM_P (operands
[0]) || MEM_P (operands
[1]))
8924 && SCALAR_INT_MODE_P (mode
))
8926 /* First handle aux attribute. */
8931 if (MEM_P (operands
[0]) && arc_is_aux_reg_p (operands
[0]))
8933 /* Save operation. */
8934 if (arc_get_aux_arg (operands
[0], &auxr
))
8936 tmp
= gen_reg_rtx (SImode
);
8937 emit_move_insn (tmp
, GEN_INT (auxr
));
8940 tmp
= XEXP (operands
[0], 0);
8942 operands
[1] = force_reg (SImode
, operands
[1]);
8943 emit_insn (gen_rtx_UNSPEC_VOLATILE
8944 (VOIDmode
, gen_rtvec (2, operands
[1], tmp
),
8948 if (MEM_P (operands
[1]) && arc_is_aux_reg_p (operands
[1]))
8950 if (arc_get_aux_arg (operands
[1], &auxr
))
8952 tmp
= gen_reg_rtx (SImode
);
8953 emit_move_insn (tmp
, GEN_INT (auxr
));
8957 tmp
= XEXP (operands
[1], 0);
8958 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
8960 /* Load operation. */
8961 gcc_assert (REG_P (operands
[0]));
8962 emit_insn (gen_rtx_SET (operands
[0],
8963 gen_rtx_UNSPEC_VOLATILE
8964 (SImode
, gen_rtvec (1, tmp
),
8969 /* Second, we check for the uncached. */
8970 if (arc_is_uncached_mem_p (operands
[0]))
8972 if (!REG_P (operands
[1]))
8973 operands
[1] = force_reg (mode
, operands
[1]);
8974 emit_insn (gen_rtx_UNSPEC_VOLATILE
8975 (VOIDmode
, gen_rtvec (2, operands
[0], operands
[1]),
8979 if (arc_is_uncached_mem_p (operands
[1]))
8981 rtx tmp
= operands
[0];
8983 if (MEM_P (operands
[0]))
8984 tmp
= gen_reg_rtx (mode
);
8986 emit_insn (gen_rtx_SET
8988 gen_rtx_UNSPEC_VOLATILE
8989 (mode
, gen_rtvec (1, operands
[1]),
8990 VUNSPEC_ARC_LDDI
)));
8991 if (MEM_P (operands
[0]))
9000 if (GET_CODE (operands
[1]) == SYMBOL_REF
)
9002 enum tls_model model
= SYMBOL_REF_TLS_MODEL (operands
[1]);
9003 if (MEM_P (operands
[0]))
9004 operands
[1] = force_reg (mode
, operands
[1]);
9006 operands
[1] = arc_legitimize_tls_address (operands
[1], model
);
9009 operands
[1] = arc_legitimize_pic_address (operands
[1]);
9011 /* Store instructions are limited, they only accept as address an
9012 immediate, a register or a register plus a small immediate. */
9013 if (MEM_P (operands
[0])
9014 && !move_dest_operand (operands
[0], mode
))
9016 rtx tmp0
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
9017 rtx tmp1
= change_address (operands
[0], mode
, tmp0
);
9018 MEM_COPY_ATTRIBUTES (tmp1
, operands
[0]);
9022 /* Check if it is constant but it is not legitimized. */
9023 if (CONSTANT_P (operands
[1])
9024 && !arc_legitimate_constant_p (mode
, operands
[1]))
9025 operands
[1] = force_reg (mode
, XEXP (operands
[1], 0));
9026 else if (MEM_P (operands
[0])
9027 && ((CONSTANT_P (operands
[1])
9028 && !satisfies_constraint_Cm3 (operands
[1]))
9029 || MEM_P (operands
[1])))
9030 operands
[1] = force_reg (mode
, operands
[1]);
9035 /* Output a library call to a function called FNAME that has been arranged
9036 to be local to any dso. */
9039 arc_output_libcall (const char *fname
)
9041 unsigned len
= strlen (fname
);
9042 static char buf
[64];
9044 gcc_assert (len
< sizeof buf
- 35);
9045 if (TARGET_LONG_CALLS_SET
)
9048 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
9050 sprintf (buf
, "jl%%! @%s", fname
);
9053 sprintf (buf
, "bl%%!%%* @%s", fname
);
9057 /* Return the SImode highpart of the DImode value IN. */
9060 disi_highpart (rtx in
)
9062 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
9065 /* Given a rtx, check if it is an assembly instruction or not. */
9068 arc_asm_insn_p (rtx x
)
9075 switch (GET_CODE (x
))
9082 return arc_asm_insn_p (SET_SRC (x
));
9086 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
9087 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
9099 /* Return length adjustment for INSN. */
9102 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
9106 /* We already handle sequences by ignoring the delay sequence flag. */
9107 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9110 /* Check for return with but one preceding insn since function
9112 if (TARGET_PAD_RETURN
9114 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
9115 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
9116 && get_attr_type (insn
) == TYPE_RETURN
)
9118 rtx_insn
*prev
= prev_active_insn (insn
);
9120 if (!prev
|| !(prev
= prev_active_insn (prev
))
9121 || ((NONJUMP_INSN_P (prev
)
9122 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9123 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9125 : CALL_ATTR (prev
, NON_SIBCALL
)))
9130 rtx_insn
*succ
= next_real_insn (insn
);
9132 /* One the ARC600, a write to an extension register must be separated
9134 if (succ
&& INSN_P (succ
))
9135 len
+= arc600_corereg_hazard (insn
, succ
);
9138 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9140 extract_constrain_insn_cached (insn
);
9145 /* Return version of PAT conditionalized with COND, which is part of INSN.
9146 ANNULLED indicates if INSN is an annulled delay-slot insn.
9147 Register further changes if necessary. */
9149 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
9151 /* For commutative operators, we generally prefer to have
9152 the first source match the destination. */
9153 if (GET_CODE (pat
) == SET
)
9155 rtx src
= SET_SRC (pat
);
9157 if (COMMUTATIVE_P (src
))
9159 rtx src0
= XEXP (src
, 0);
9160 rtx src1
= XEXP (src
, 1);
9161 rtx dst
= SET_DEST (pat
);
9163 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
9164 /* Leave add_n alone - the canonical form is to
9165 have the complex summand first. */
9167 pat
= gen_rtx_SET (dst
,
9168 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
9173 /* dwarf2out.cc:dwarf2out_frame_debug_expr doesn't know
9174 what to do with COND_EXEC. */
9175 if (RTX_FRAME_RELATED_P (insn
))
9177 /* If this is the delay slot insn of an anulled branch,
9178 dwarf2out.cc:scan_trace understands the anulling semantics
9179 without the COND_EXEC. */
9180 gcc_assert (annulled
);
9181 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
9183 validate_change (insn
, ®_NOTES (insn
), note
, 1);
9185 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
9190 /* Find annulled delay insns and convert them to use the appropriate predicate.
9191 This allows branch shortening to size up these insns properly. */
9194 arc_predicate_delay_insns (void)
9196 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9198 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
9201 if (!NONJUMP_INSN_P (insn
)
9202 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
9204 jump
= XVECEXP (pat
, 0, 0);
9205 dlay
= XVECEXP (pat
, 0, 1);
9206 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
9208 /* If the branch insn does the annulling, leave the delay insn alone. */
9209 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
9211 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9212 on the other path. */
9213 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
9214 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
9215 src
= SET_SRC (PATTERN (jump
));
9216 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
9217 cond
= XEXP (src
, 0);
9218 if (XEXP (src
, 2) == pc_rtx
)
9220 else if (XEXP (src
, 1) == pc_rtx
)
9224 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
9226 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9227 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9228 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9229 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9231 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9232 copy_rtx (XEXP (cond
, 0)),
9233 copy_rtx (XEXP (cond
, 1)));
9236 cond
= copy_rtx (cond
);
9237 patp
= &PATTERN (dlay
);
9239 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9240 validate_change (dlay
, patp
, pat
, 1);
9241 if (!apply_change_group ())
9247 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9248 (other than of a forward brcc), it creates a hazard when there is a read
9249 of the same register at the branch target. We can't know what is at the
9250 branch target of calls, and for branches, we don't really know before the
9251 end of delay slot scheduling, either. Not only can individual instruction
9252 be hoisted out into a delay slot, a basic block can also be emptied this
9253 way, and branch and/or fall through targets be redirected. Hence we don't
9254 want such writes in a delay slot. */
9256 /* Return nonzreo iff INSN writes to an extension core register. */
9259 arc_write_ext_corereg (rtx insn
)
9261 subrtx_iterator::array_type array
;
9262 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9264 const_rtx x
= *iter
;
9265 switch (GET_CODE (x
))
9267 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9270 /* This is also fine for PRE/POST_MODIFY, because they
9274 const_rtx dest
= XEXP (x
, 0);
9275 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9281 /* This is like the hook, but returns NULL when it can't / won't generate
9282 a legitimate address. */
9285 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9291 if (GET_CODE (addr
) == CONST
)
9292 addr
= XEXP (addr
, 0);
9294 if (GET_CODE (addr
) == PLUS
9295 && CONST_INT_P (XEXP (addr
, 1))
9296 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9297 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9298 || (REG_P (XEXP (addr
, 0))
9299 && (INTVAL (XEXP (addr
, 1)) & 252))))
9301 HOST_WIDE_INT offs
, upper
;
9302 int size
= GET_MODE_SIZE (mode
);
9304 offs
= INTVAL (XEXP (addr
, 1));
9305 upper
= (offs
+ 256 * size
) & ~511 * size
;
9306 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9307 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9308 if (GET_CODE (x
) == CONST
)
9309 inner
= gen_rtx_CONST (Pmode
, inner
);
9311 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9314 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9315 x
= force_reg (Pmode
, x
);
9316 if (memory_address_p ((machine_mode
) mode
, x
))
9322 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9324 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9332 arc_delegitimize_address_0 (rtx op
)
9334 switch (GET_CODE (op
))
9337 return arc_delegitimize_address_0 (XEXP (op
, 0));
9340 switch (XINT (op
, 1))
9342 case ARC_UNSPEC_GOT
:
9343 case ARC_UNSPEC_GOTOFFPC
:
9344 return XVECEXP (op
, 0, 0);
9352 rtx t1
= arc_delegitimize_address_0 (XEXP (op
, 0));
9353 rtx t2
= XEXP (op
, 1);
9356 return gen_rtx_PLUS (GET_MODE (op
), t1
, t2
);
9367 arc_delegitimize_address (rtx orig_x
)
9374 x
= arc_delegitimize_address_0 (x
);
9379 x
= replace_equiv_address_nv (orig_x
, x
);
9383 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9384 differ from the hardware register number in order to allow the generic
9385 code to correctly split the concatenation of acc1 and acc2. */
9390 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9393 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9394 differ from the hardware register number in order to allow the generic
9395 code to correctly split the concatenation of acc1 and acc2. */
9400 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9403 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9404 are three reasons why we need to consider branches to be length 6:
9405 - annull-false delay slot insns are implemented using conditional execution,
9406 thus preventing short insn formation where used.
9407 - for ARC600: annul-true delay slot insns are implemented where possible
9408 using conditional execution, preventing short insn formation where used.
9409 - for ARC700: likely or somewhat likely taken branches are made long and
9410 unaligned if possible to avoid branch penalty. */
9413 arc_branch_size_unknown_p (void)
9415 return !optimize_size
&& arc_reorg_in_progress
;
9418 /* The usual; we set up our machine_function data. */
9420 static struct machine_function
*
9421 arc_init_machine_status (void)
9423 struct machine_function
*machine
;
9424 machine
= ggc_cleared_alloc
<machine_function
> ();
9425 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9430 /* Implements INIT_EXPANDERS. We just set up to call the above
9434 arc_init_expanders (void)
9436 init_machine_status
= arc_init_machine_status
;
9439 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9440 indicates a number of elements to ignore - that allows to have a
9441 sibcall pattern that starts with (return). LOAD_P is zero for store
9442 multiple (for prologues), and one for load multiples (for epilogues),
9443 and two for load multiples where no final clobber of blink is required.
9444 We also skip the first load / store element since this is supposed to
9445 be checked in the instruction pattern. */
9448 arc_check_millicode (rtx op
, int offset
, int load_p
)
9450 int len
= XVECLEN (op
, 0) - offset
;
9455 if (len
< 2 || len
> 13)
9461 rtx elt
= XVECEXP (op
, 0, --len
);
9463 if (GET_CODE (elt
) != CLOBBER
9464 || !REG_P (XEXP (elt
, 0))
9465 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9466 || len
< 3 || len
> 13)
9469 for (i
= 1; i
< len
; i
++)
9471 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9474 if (GET_CODE (elt
) != SET
)
9476 mem
= XEXP (elt
, load_p
);
9477 reg
= XEXP (elt
, 1-load_p
);
9478 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9480 addr
= XEXP (mem
, 0);
9481 if (GET_CODE (addr
) != PLUS
9482 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9483 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9489 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9490 constant in operand 1, but which would require a LIMM because of
9492 operands 3 and 4 are new SET_SRCs for operands 0. */
9495 split_subsi (rtx
*operands
)
9497 int val
= INTVAL (operands
[1]);
9499 /* Try for two short insns first. Lengths being equal, we prefer
9500 expansions with shorter register lifetimes. */
9501 if (arc_check_short_reg_p (operands
[0])
9502 && arc_check_short_reg_p (operands
[2]))
9504 if (val
>= -31 && val
<= 127)
9506 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
9507 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
9510 else if (val
>= 0 && val
< 255)
9512 operands
[3] = operands
[1];
9513 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
9517 /* If the destination is not an ARCompact16 register, we might
9518 still have a chance to make a short insn if the source is;
9519 we need to start with a reg-reg move for this. */
9520 operands
[3] = operands
[2];
9521 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
9524 /* Handle DOUBLE_REGS uses.
9525 Operand 0: destination register
9526 Operand 1: source register */
9529 arc_process_double_reg_moves (rtx
*operands
)
9531 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
9532 enum usesDxState state
= none
;
9533 rtx dest
= operands
[0];
9534 rtx src
= operands
[1];
9536 if (refers_to_regno_p (40, 44, src
, 0))
9539 gcc_assert (REG_P (dest
));
9541 if (refers_to_regno_p (40, 44, dest
, 0))
9543 /* Via arc_register_move_cost, we should never see D,D moves. */
9544 gcc_assert (REG_P (src
));
9545 gcc_assert (state
== none
);
9554 /* Without the LR insn, we need to split this into a
9555 sequence of insns which will use the DEXCLx and DADDHxy
9556 insns to be able to read the Dx register in question. */
9557 if (TARGET_DPFP_DISABLE_LRSR
)
9559 /* gen *movdf_insn_nolrsr */
9560 rtx set
= gen_rtx_SET (dest
, src
);
9561 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
9562 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
9566 /* When we have 'mov D, r' or 'mov D, D' then get the target
9567 register pair for use with LR insn. */
9568 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9569 TARGET_BIG_ENDIAN
? 0 : 4);
9570 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
9571 TARGET_BIG_ENDIAN
? 4 : 0);
9573 /* Produce the two LR insns to get the high and low parts. */
9574 emit_insn (gen_rtx_SET (destHigh
,
9575 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9577 VUNSPEC_ARC_LR_HIGH
)));
9578 emit_insn (gen_rtx_SET (destLow
,
9579 gen_rtx_UNSPEC_VOLATILE (Pmode
,
9584 else if (state
== destDx
)
9586 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9587 LR insn get the target register pair. */
9588 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9589 TARGET_BIG_ENDIAN
? 0 : 4);
9590 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9591 TARGET_BIG_ENDIAN
? 4 : 0);
9593 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
9602 /* Check if we need to split a 64bit move. We do not need to split it if we can
9603 use vadd2 or ldd/std instructions. */
9606 arc_split_move_p (rtx
*operands
)
9608 machine_mode mode
= GET_MODE (operands
[0]);
9611 && ((memory_operand (operands
[0], mode
)
9612 && (even_register_operand (operands
[1], mode
)
9613 || satisfies_constraint_Cm3 (operands
[1])))
9614 || (memory_operand (operands
[1], mode
)
9615 && even_register_operand (operands
[0], mode
))))
9618 if (TARGET_PLUS_QMACW
9619 && even_register_operand (operands
[0], mode
)
9620 && even_register_operand (operands
[1], mode
))
9626 /* operands 0..1 are the operands of a 64 bit move instruction.
9627 split it into two moves with operands 2/3 and 4/5. */
9630 arc_split_move (rtx
*operands
)
9632 machine_mode mode
= GET_MODE (operands
[0]);
9639 if (arc_process_double_reg_moves (operands
))
9643 if (TARGET_PLUS_QMACW
9644 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9646 HOST_WIDE_INT intval0
, intval1
;
9647 if (GET_MODE (operands
[1]) == V2SImode
)
9649 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9650 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9654 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9655 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9656 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9657 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9659 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9660 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9661 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9662 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9663 emit_move_insn (xop
[0], xop
[2]);
9664 emit_move_insn (xop
[3], xop
[1]);
9668 for (i
= 0; i
< 2; i
++)
9670 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9672 rtx addr
= XEXP (operands
[i
], 0);
9676 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9677 switch (GET_CODE (addr
))
9679 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9680 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9681 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9685 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9686 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9687 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9696 xop
[0+i
] = adjust_automodify_address_nv
9697 (operands
[i
], SImode
,
9698 gen_rtx_fmt_ee (code
, Pmode
, r
,
9699 gen_rtx_PLUS (Pmode
, r
, o
)),
9701 xop
[2+i
] = adjust_automodify_address_nv
9702 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9706 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9707 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9710 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9713 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9716 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9717 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9721 /* Select between the instruction output templates s_tmpl (for short INSNs)
9722 and l_tmpl (for long INSNs). */
9725 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9727 int is_short
= arc_verify_short (insn
, -1);
9729 extract_constrain_insn_cached (insn
);
9730 return is_short
? s_tmpl
: l_tmpl
;
9733 /* Searches X for any reference to REGNO, returning the rtx of the
9734 reference found if any. Otherwise, returns NULL_RTX. */
9737 arc_regno_use_in (unsigned int regno
, rtx x
)
9743 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9746 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9747 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9751 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9754 else if (fmt
[i
] == 'E')
9755 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9756 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9763 /* Code has a minimum p2 alignment of 1, which we must restore after
9764 an ADDR_DIFF_VEC. */
9767 arc_label_align (rtx_insn
*label
)
9769 if (align_labels
.levels
[0].log
< 1)
9771 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9772 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9775 return align_labels
.levels
[0].log
;
9778 /* Return true if LABEL is in executable code. */
9781 arc_text_label (rtx_insn
*label
)
9785 /* ??? We use deleted labels like they were still there, see
9786 gcc.c-torture/compile/20000326-2.c . */
9787 gcc_assert (GET_CODE (label
) == CODE_LABEL
9788 || (GET_CODE (label
) == NOTE
9789 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9790 next
= next_nonnote_insn (label
);
9792 return (!JUMP_TABLE_DATA_P (next
)
9793 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9794 else if (!PREV_INSN (label
))
9795 /* ??? sometimes text labels get inserted very late, see
9796 gcc.dg/torture/stackalign/comp-goto-1.c */
9801 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9802 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9803 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9804 to redirect two breqs. */
9807 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9809 /* ??? get_attr_type is declared to take an rtx. */
9810 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9813 if (CROSSING_JUMP_P (followee
))
9814 switch (get_attr_type (u
.r
))
9817 if (get_attr_length (u
.r
) != 2)
9821 case TYPE_BRCC_NO_DELAY_SLOT
:
9830 /* Implement EPILOGUE_USES.
9831 Return true if REGNO should be added to the deemed uses of the epilogue.
9833 We have to make sure all the register restore instructions are
9834 known to be live in interrupt functions, plus the blink register if
9835 it is clobbered by the isr. */
9838 arc_epilogue_uses (int regno
)
9840 unsigned int fn_type
;
9841 fn_type
= arc_compute_function_type (cfun
);
9843 if (regno
== arc_tp_regno
)
9846 if (regno
== RETURN_ADDR_REGNUM
)
9849 if (regno
== arc_return_address_register (fn_type
))
9852 if (epilogue_completed
&& ARC_INTERRUPT_P (fn_type
))
9854 /* An interrupt function restores more registers. */
9855 if (df_regs_ever_live_p (regno
) || call_used_or_fixed_reg_p (regno
))
9862 /* Helper for EH_USES macro. */
9865 arc_eh_uses (int regno
)
9867 if (regno
== arc_tp_regno
)
9872 /* Return true if we use LRA instead of reload pass. */
9877 return arc_lra_flag
;
9880 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to
9881 use q registers, because some insn are shorter with them. OTOH we
9882 already have separate alternatives for this purpose, and other
9883 insns don't mind, so maybe we should rather prefer the other
9884 registers? We need more data, and we can only get that if we allow
9885 people to try all options. */
9887 arc_register_priority (int r
)
9889 switch (arc_lra_priority_tag
)
9891 case ARC_LRA_PRIORITY_NONE
:
9893 case ARC_LRA_PRIORITY_NONCOMPACT
:
9894 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
9895 case ARC_LRA_PRIORITY_COMPACT
:
9896 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
9903 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
9905 return GENERAL_REGS
;
9909 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
9913 enum reload_type type
= (enum reload_type
) itype
;
9915 if (GET_CODE (x
) == PLUS
9916 && CONST_INT_P (XEXP (x
, 1))
9917 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
9918 || (REG_P (XEXP (x
, 0))
9919 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
9921 int scale
= GET_MODE_SIZE (mode
);
9923 rtx index_rtx
= XEXP (x
, 1);
9924 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
9929 if ((scale
-1) & offset
)
9933 = ((offset
+ (256 << shift
))
9934 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
9935 /* Sometimes the normal form does not suit DImode. We
9936 could avoid that by using smaller ranges, but that
9937 would give less optimized code when SImode is
9939 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
9944 regno
= REGNO (reg
);
9945 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
9947 if (reg_equiv_constant (regno
))
9949 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
9951 if (GET_CODE (sum2
) == PLUS
)
9952 sum2
= gen_rtx_CONST (Pmode
, sum2
);
9954 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
9955 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
9956 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
9961 /* We must re-recognize what we created before. */
9962 else if (GET_CODE (x
) == PLUS
9963 && GET_CODE (XEXP (x
, 0)) == PLUS
9964 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
9965 && REG_P (XEXP (XEXP (x
, 0), 0))
9966 && CONST_INT_P (XEXP (x
, 1)))
9968 /* Because this address is so complex, we know it must have
9969 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9970 it is already unshared, and needs no further unsharing. */
9971 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
9972 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
9978 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9981 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
9983 enum by_pieces_operation op
,
9986 /* Let the cpymem expander handle small block moves. */
9987 if (op
== MOVE_BY_PIECES
)
9990 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
9993 /* Emit a (pre) memory barrier around an atomic sequence according to
9997 arc_pre_atomic_barrier (enum memmodel model
)
9999 if (need_atomic_barrier_p (model
, true))
10000 emit_insn (gen_memory_barrier ());
10003 /* Emit a (post) memory barrier around an atomic sequence according to
10007 arc_post_atomic_barrier (enum memmodel model
)
10009 if (need_atomic_barrier_p (model
, false))
10010 emit_insn (gen_memory_barrier ());
10013 /* Expand a compare and swap pattern. */
10016 emit_unlikely_jump (rtx insn
)
10018 rtx_insn
*jump
= emit_jump_insn (insn
);
10019 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10022 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10023 32-bit compare and swap on the word containing the byte or
10024 half-word. The difference between a weak and a strong CAS is that
10025 the weak version may simply fail. The strong version relies on two
10026 loops, one checks if the SCOND op is succsfully or not, the other
10027 checks if the 32 bit accessed location which contains the 8 or 16
10028 bit datum is not changed by other thread. The first loop is
10029 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10030 loops is implemented by this routine. */
10033 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10034 rtx oldval
, rtx newval
, rtx weak
,
10035 rtx mod_s
, rtx mod_f
)
10037 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10038 rtx addr
= gen_reg_rtx (Pmode
);
10039 rtx off
= gen_reg_rtx (SImode
);
10040 rtx oldv
= gen_reg_rtx (SImode
);
10041 rtx newv
= gen_reg_rtx (SImode
);
10042 rtx oldvalue
= gen_reg_rtx (SImode
);
10043 rtx newvalue
= gen_reg_rtx (SImode
);
10044 rtx res
= gen_reg_rtx (SImode
);
10045 rtx resv
= gen_reg_rtx (SImode
);
10046 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10048 bool is_weak
= (weak
!= const0_rtx
);
10050 /* Truncate the address. */
10051 emit_insn (gen_rtx_SET (addr
,
10052 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10054 /* Compute the datum offset. */
10055 emit_insn (gen_rtx_SET (off
,
10056 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10057 if (TARGET_BIG_ENDIAN
)
10058 emit_insn (gen_rtx_SET (off
,
10059 gen_rtx_MINUS (SImode
,
10060 (GET_MODE (mem
) == QImode
) ?
10061 GEN_INT (3) : GEN_INT (2), off
)));
10063 /* Normal read from truncated address. */
10064 memsi
= gen_rtx_MEM (SImode
, addr
);
10065 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10066 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10068 val
= copy_to_reg (memsi
);
10070 /* Convert the offset in bits. */
10071 emit_insn (gen_rtx_SET (off
,
10072 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10074 /* Get the proper mask. */
10075 if (GET_MODE (mem
) == QImode
)
10076 mask
= force_reg (SImode
, GEN_INT (0xff));
10078 mask
= force_reg (SImode
, GEN_INT (0xffff));
10080 emit_insn (gen_rtx_SET (mask
,
10081 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10083 /* Prepare the old and new values. */
10084 emit_insn (gen_rtx_SET (val
,
10085 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10088 oldval
= gen_lowpart (SImode
, oldval
);
10089 emit_insn (gen_rtx_SET (oldv
,
10090 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10092 newval
= gen_lowpart_common (SImode
, newval
);
10093 emit_insn (gen_rtx_SET (newv
,
10094 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10096 emit_insn (gen_rtx_SET (oldv
,
10097 gen_rtx_AND (SImode
, oldv
, mask
)));
10099 emit_insn (gen_rtx_SET (newv
,
10100 gen_rtx_AND (SImode
, newv
, mask
)));
10104 end_label
= gen_label_rtx ();
10105 loop_label
= gen_label_rtx ();
10106 emit_label (loop_label
);
10109 /* Make the old and new values. */
10110 emit_insn (gen_rtx_SET (oldvalue
,
10111 gen_rtx_IOR (SImode
, oldv
, val
)));
10113 emit_insn (gen_rtx_SET (newvalue
,
10114 gen_rtx_IOR (SImode
, newv
, val
)));
10116 /* Try an 32bit atomic compare and swap. It clobbers the CC
10118 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10119 weak
, mod_s
, mod_f
));
10121 /* Regardless of the weakness of the operation, a proper boolean
10122 result needs to be provided. */
10123 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10124 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10125 emit_insn (gen_rtx_SET (bool_result
, x
));
10129 /* Check the results: if the atomic op is successfully the goto
10131 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10132 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10133 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10134 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10135 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10137 /* Wait for the right moment when the accessed 32-bit location
10139 emit_insn (gen_rtx_SET (resv
,
10140 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10142 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10143 cc
= gen_rtx_REG (mode
, CC_REG
);
10144 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10146 /* Set the new value of the 32 bit location, proper masked. */
10147 emit_insn (gen_rtx_SET (val
, resv
));
10149 /* Try again if location is unstable. Fall through if only
10150 scond op failed. */
10151 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10152 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10153 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10154 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10156 emit_label (end_label
);
10159 /* End: proper return the result for the given mode. */
10160 emit_insn (gen_rtx_SET (res
,
10161 gen_rtx_AND (SImode
, res
, mask
)));
10163 emit_insn (gen_rtx_SET (res
,
10164 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10166 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10169 /* Helper function used by "atomic_compare_and_swap" expand
10173 arc_expand_compare_and_swap (rtx operands
[])
10175 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10178 bval
= operands
[0];
10179 rval
= operands
[1];
10181 oldval
= operands
[3];
10182 newval
= operands
[4];
10183 is_weak
= operands
[5];
10184 mod_s
= operands
[6];
10185 mod_f
= operands
[7];
10186 mode
= GET_MODE (mem
);
10188 if (reg_overlap_mentioned_p (rval
, oldval
))
10189 oldval
= copy_to_reg (oldval
);
10191 if (mode
== SImode
)
10193 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10194 is_weak
, mod_s
, mod_f
));
10195 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10196 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10197 emit_insn (gen_rtx_SET (bval
, x
));
10201 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10202 is_weak
, mod_s
, mod_f
);
10206 /* Helper function used by the "atomic_compare_and_swapsi_1"
10210 arc_split_compare_and_swap (rtx operands
[])
10212 rtx rval
, mem
, oldval
, newval
;
10214 enum memmodel mod_s
, mod_f
;
10216 rtx label1
, label2
, x
, cond
;
10218 rval
= operands
[0];
10220 oldval
= operands
[2];
10221 newval
= operands
[3];
10222 is_weak
= (operands
[4] != const0_rtx
);
10223 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10224 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10225 mode
= GET_MODE (mem
);
10227 /* ARC atomic ops work only with 32-bit aligned memories. */
10228 gcc_assert (mode
== SImode
);
10230 arc_pre_atomic_barrier (mod_s
);
10235 label1
= gen_label_rtx ();
10236 emit_label (label1
);
10238 label2
= gen_label_rtx ();
10240 /* Load exclusive. */
10241 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10243 /* Check if it is oldval. */
10244 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10245 cond
= gen_rtx_REG (mode
, CC_REG
);
10246 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10248 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10249 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10250 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10251 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10253 /* Exclusively store new item. Store clobbers CC reg. */
10254 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10258 /* Check the result of the store. */
10259 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10260 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10261 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10262 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10263 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10266 if (mod_f
!= MEMMODEL_RELAXED
)
10267 emit_label (label2
);
10269 arc_post_atomic_barrier (mod_s
);
10271 if (mod_f
== MEMMODEL_RELAXED
)
10272 emit_label (label2
);
10275 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10276 to perform. MEM is the memory on which to operate. VAL is the second
10277 operand of the binary operator. BEFORE and AFTER are optional locations to
10278 return the value of MEM either before of after the operation. MODEL_RTX
10279 is a CONST_INT containing the memory model to use. */
10282 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10283 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10285 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10286 machine_mode mode
= GET_MODE (mem
);
10287 rtx label
, x
, cond
;
10288 rtx before
= orig_before
, after
= orig_after
;
10290 /* ARC atomic ops work only with 32-bit aligned memories. */
10291 gcc_assert (mode
== SImode
);
10293 arc_pre_atomic_barrier (model
);
10295 label
= gen_label_rtx ();
10296 emit_label (label
);
10297 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10299 if (before
== NULL_RTX
)
10300 before
= gen_reg_rtx (mode
);
10302 if (after
== NULL_RTX
)
10303 after
= gen_reg_rtx (mode
);
10305 /* Load exclusive. */
10306 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10311 x
= gen_rtx_AND (mode
, before
, val
);
10312 emit_insn (gen_rtx_SET (after
, x
));
10313 x
= gen_rtx_NOT (mode
, after
);
10314 emit_insn (gen_rtx_SET (after
, x
));
10318 if (CONST_INT_P (val
))
10320 val
= GEN_INT (-INTVAL (val
));
10326 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10327 emit_insn (gen_rtx_SET (after
, x
));
10331 /* Exclusively store new item. Store clobbers CC reg. */
10332 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10334 /* Check the result of the store. */
10335 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10336 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10337 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10339 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10341 arc_post_atomic_barrier (model
);
10344 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10347 arc_no_speculation_in_delay_slots_p ()
10352 /* Return a parallel of registers to represent where to find the
10353 register pieces if required, otherwise NULL_RTX. */
10356 arc_dwarf_register_span (rtx rtl
)
10358 machine_mode mode
= GET_MODE (rtl
);
10362 if (GET_MODE_SIZE (mode
) != 8)
10365 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10366 regno
= REGNO (rtl
);
10367 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10368 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10373 /* Return true if OP is an acceptable memory operand for ARCompact
10374 16-bit load instructions of MODE.
10376 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10377 non scaled instructions.
10379 SCALED: TRUE if address can be scaled. */
10382 compact_memory_operand_p (rtx op
, machine_mode mode
,
10383 bool av2short
, bool scaled
)
10385 rtx addr
, plus0
, plus1
;
10388 /* Eliminate non-memory operations. */
10389 if (GET_CODE (op
) != MEM
)
10392 /* .di instructions have no 16-bit form. */
10393 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10396 /* likewise for uncached types. */
10397 if (arc_is_uncached_mem_p (op
))
10400 if (mode
== VOIDmode
)
10401 mode
= GET_MODE (op
);
10403 size
= GET_MODE_SIZE (mode
);
10405 /* dword operations really put out 2 instructions, so eliminate
10407 if (size
> UNITS_PER_WORD
)
10410 /* Decode the address now. */
10411 addr
= XEXP (op
, 0);
10412 switch (GET_CODE (addr
))
10415 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10416 || COMPACT_GP_REG_P (REGNO (addr
))
10417 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10419 plus0
= XEXP (addr
, 0);
10420 plus1
= XEXP (addr
, 1);
10422 if ((GET_CODE (plus0
) == REG
)
10423 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10424 || COMPACT_GP_REG_P (REGNO (plus0
)))
10425 && ((GET_CODE (plus1
) == REG
)
10426 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10427 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10432 if ((GET_CODE (plus0
) == REG
)
10433 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10434 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10435 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10436 && (GET_CODE (plus1
) == CONST_INT
))
10438 bool valid
= false;
10440 off
= INTVAL (plus1
);
10442 /* Negative offset is not supported in 16-bit load/store insns. */
10446 /* Only u5 immediates allowed in code density instructions. */
10454 /* This is an ldh_s.x instruction, check the u6
10456 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10460 /* Only u5 immediates allowed in 32bit access code
10461 density instructions. */
10462 if (REGNO (plus0
) <= 31)
10463 return ((off
< 32) && (off
% 4 == 0));
10470 if (COMPACT_GP_REG_P (REGNO (plus0
)))
10481 /* The 6-bit constant get shifted to fit the real
10482 5-bits field. Check also for the alignment. */
10483 return ((off
< 64) && (off
% 2 == 0));
10485 return ((off
< 128) && (off
% 4 == 0));
10492 if (REG_P (plus0
) && CONST_INT_P (plus1
)
10493 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10494 || SP_REG_P (REGNO (plus0
)))
10497 off
= INTVAL (plus1
);
10498 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
10501 if ((GET_CODE (plus0
) == MULT
)
10502 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10503 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10504 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10505 && (GET_CODE (plus1
) == REG
)
10506 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10507 || COMPACT_GP_REG_P (REGNO (plus1
))))
10511 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10512 for 16-bit load instructions. */
10517 /* Return nonzero if a jli call should be generated for a call from
10518 the current function to DECL. */
10521 arc_is_jli_call_p (rtx pat
)
10524 tree decl
= SYMBOL_REF_DECL (pat
);
10526 /* If it is not a well defined public function then return false. */
10527 if (!decl
|| !SYMBOL_REF_FUNCTION_P (pat
) || !TREE_PUBLIC (decl
))
10530 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
10531 if (lookup_attribute ("jli_always", attrs
))
10534 if (lookup_attribute ("jli_fixed", attrs
))
10537 return TARGET_JLI_ALWAYS
;
10540 /* Handle and "jli" attribute; arguments as in struct
10541 attribute_spec.handler. */
10544 arc_handle_jli_attribute (tree
*node ATTRIBUTE_UNUSED
,
10545 tree name
, tree args
, int,
10546 bool *no_add_attrs
)
10550 warning (OPT_Wattributes
,
10551 "%qE attribute only valid for ARCv2 architecture",
10553 *no_add_attrs
= true;
10556 if (args
== NULL_TREE
)
10558 warning (OPT_Wattributes
,
10559 "argument of %qE attribute is missing",
10561 *no_add_attrs
= true;
10565 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10566 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10567 tree arg
= TREE_VALUE (args
);
10568 if (TREE_CODE (arg
) != INTEGER_CST
)
10570 warning (0, "%qE attribute allows only an integer constant argument",
10572 *no_add_attrs
= true;
10574 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10579 /* Handle and "scure" attribute; arguments as in struct
10580 attribute_spec.handler. */
10583 arc_handle_secure_attribute (tree
*node ATTRIBUTE_UNUSED
,
10584 tree name
, tree args
, int,
10585 bool *no_add_attrs
)
10589 warning (OPT_Wattributes
,
10590 "%qE attribute only valid for ARC EM architecture",
10592 *no_add_attrs
= true;
10595 if (args
== NULL_TREE
)
10597 warning (OPT_Wattributes
,
10598 "argument of %qE attribute is missing",
10600 *no_add_attrs
= true;
10604 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10605 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10606 tree arg
= TREE_VALUE (args
);
10607 if (TREE_CODE (arg
) != INTEGER_CST
)
10609 warning (0, "%qE attribute allows only an integer constant argument",
10611 *no_add_attrs
= true;
10617 /* Return nonzero if the symbol is a secure function. */
10620 arc_is_secure_call_p (rtx pat
)
10623 tree decl
= SYMBOL_REF_DECL (pat
);
10628 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
10629 if (lookup_attribute ("secure_call", attrs
))
10635 /* Handle "uncached" qualifier. */
10638 arc_handle_uncached_attribute (tree
*node
,
10639 tree name
, tree args
,
10640 int flags ATTRIBUTE_UNUSED
,
10641 bool *no_add_attrs
)
10643 if (DECL_P (*node
) && TREE_CODE (*node
) != TYPE_DECL
)
10645 error ("%qE attribute only applies to types",
10647 *no_add_attrs
= true;
10651 warning (OPT_Wattributes
, "argument of %qE attribute ignored", name
);
10656 /* Return TRUE if PAT is a memory addressing an uncached data. */
10659 arc_is_uncached_mem_p (rtx pat
)
10661 tree attrs
= NULL_TREE
;
10667 /* Get the memory attributes. */
10668 addr
= MEM_EXPR (pat
);
10672 /* Get the attributes. */
10673 if (TREE_CODE (addr
) == MEM_REF
10676 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (addr
));
10677 if (lookup_attribute ("uncached", attrs
))
10680 if (TREE_CODE (addr
) == MEM_REF
)
10682 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
10683 if (lookup_attribute ("uncached", attrs
))
10685 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 1)));
10686 if (lookup_attribute ("uncached", attrs
))
10690 /* Check the definitions of the structs. */
10691 while (handled_component_p (addr
))
10693 if (TREE_CODE (addr
) == COMPONENT_REF
)
10695 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (addr
));
10696 if (lookup_attribute ("uncached", attrs
))
10698 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
10699 if (lookup_attribute ("uncached", attrs
))
10701 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 1)));
10702 if (lookup_attribute ("uncached", attrs
))
10705 addr
= TREE_OPERAND (addr
, 0);
10710 /* Handle aux attribute. The auxiliary registers are addressed using
10711 special instructions lr and sr. The attribute 'aux' indicates if a
10712 variable refers to the aux-regs and what is the register number
10716 arc_handle_aux_attribute (tree
*node
,
10717 tree name
, tree args
, int,
10718 bool *no_add_attrs
)
10720 /* Isn't it better to use address spaces for the aux-regs? */
10721 if (DECL_P (*node
))
10723 if (TREE_CODE (*node
) != VAR_DECL
)
10725 error ("%qE attribute only applies to variables", name
);
10726 *no_add_attrs
= true;
10730 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
10731 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
10732 tree arg
= TREE_VALUE (args
);
10733 if (TREE_CODE (arg
) != INTEGER_CST
)
10735 warning (OPT_Wattributes
, "%qE attribute allows only an integer "
10736 "constant argument", name
);
10737 *no_add_attrs
= true;
10739 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10744 tree fntype
= TREE_TYPE (*node
);
10745 if (fntype
&& TREE_CODE (fntype
) == POINTER_TYPE
)
10747 tree attrs
= tree_cons (get_identifier ("aux"), NULL_TREE
,
10748 TYPE_ATTRIBUTES (fntype
));
10749 TYPE_ATTRIBUTES (fntype
) = attrs
;
10756 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10757 anchors for small data: the GP register acts as an anchor in that
10758 case. We also don't want to use them for PC-relative accesses,
10759 where the PC acts as an anchor. Prohibit also TLS symbols to use
10763 arc_use_anchors_for_symbol_p (const_rtx symbol
)
10765 if (SYMBOL_REF_TLS_MODEL (symbol
))
10771 if (SYMBOL_REF_SMALL_P (symbol
))
10774 return default_use_anchors_for_symbol_p (symbol
);
10777 /* Return true if SUBST can't safely replace its equivalent during RA. */
10779 arc_cannot_substitute_mem_equiv_p (rtx
)
10781 /* If SUBST is mem[base+index], the address may not fit ISA,
10782 thus return true. */
10786 /* Checks whether the operands are valid for use in an LDD/STD
10787 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
10788 by the patterns. Assumes that the address in the base register RN
10789 is word aligned. Pattern guarantees that both memory accesses use
10790 the same base register, the offsets are constants within the range,
10791 and the gap between the offsets is 4. If reload complete then
10792 check that registers are legal. */
10795 operands_ok_ldd_std (rtx rt
, rtx rt2
, HOST_WIDE_INT offset
)
10797 unsigned int t
, t2
;
10799 if (!reload_completed
)
10802 if (!(SMALL_INT_RANGE (offset
, (GET_MODE_SIZE (DImode
) - 1) & (~0x03),
10803 (offset
& (GET_MODE_SIZE (DImode
) - 1) & 3
10804 ? 0 : -(-GET_MODE_SIZE (DImode
) | (~0x03)) >> 1))))
10810 if ((t2
== PCL_REG
)
10811 || (t
% 2 != 0) /* First destination register is not even. */
10818 /* Helper for gen_operands_ldd_std. Returns true iff the memory
10819 operand MEM's address contains an immediate offset from the base
10820 register and has no side effects, in which case it sets BASE and
10821 OFFSET accordingly. */
10824 mem_ok_for_ldd_std (rtx mem
, rtx
*base
, rtx
*offset
)
10828 gcc_assert (base
!= NULL
&& offset
!= NULL
);
10830 /* TODO: Handle more general memory operand patterns, such as
10831 PRE_DEC and PRE_INC. */
10833 if (side_effects_p (mem
))
10836 /* Can't deal with subregs. */
10837 if (GET_CODE (mem
) == SUBREG
)
10840 gcc_assert (MEM_P (mem
));
10842 *offset
= const0_rtx
;
10844 addr
= XEXP (mem
, 0);
10846 /* If addr isn't valid for DImode, then we can't handle it. */
10847 if (!arc_legitimate_address_p (DImode
, addr
,
10848 reload_in_progress
|| reload_completed
))
10856 else if (GET_CODE (addr
) == PLUS
|| GET_CODE (addr
) == MINUS
)
10858 *base
= XEXP (addr
, 0);
10859 *offset
= XEXP (addr
, 1);
10860 return (REG_P (*base
) && CONST_INT_P (*offset
));
10866 /* Called from peephole2 to replace two word-size accesses with a
10867 single LDD/STD instruction. Returns true iff we can generate a new
10868 instruction sequence. That is, both accesses use the same base
10869 register and the gap between constant offsets is 4. OPERANDS are
10870 the operands found by the peephole matcher; OPERANDS[0,1] are
10871 register operands, and OPERANDS[2,3] are the corresponding memory
10872 operands. LOAD indicates whether the access is load or store. */
10875 gen_operands_ldd_std (rtx
*operands
, bool load
, bool commute
)
10878 HOST_WIDE_INT offsets
[2], offset
;
10880 rtx cur_base
, cur_offset
, tmp
;
10881 rtx base
= NULL_RTX
;
10883 /* Check that the memory references are immediate offsets from the
10884 same base register. Extract the base register, the destination
10885 registers, and the corresponding memory offsets. */
10886 for (i
= 0; i
< nops
; i
++)
10888 if (!mem_ok_for_ldd_std (operands
[nops
+i
], &cur_base
, &cur_offset
))
10893 else if (REGNO (base
) != REGNO (cur_base
))
10896 offsets
[i
] = INTVAL (cur_offset
);
10897 if (GET_CODE (operands
[i
]) == SUBREG
)
10899 tmp
= SUBREG_REG (operands
[i
]);
10900 gcc_assert (GET_MODE (operands
[i
]) == GET_MODE (tmp
));
10905 /* Make sure there is no dependency between the individual loads. */
10906 if (load
&& REGNO (operands
[0]) == REGNO (base
))
10907 return false; /* RAW. */
10909 if (load
&& REGNO (operands
[0]) == REGNO (operands
[1]))
10910 return false; /* WAW. */
10912 /* Make sure the instructions are ordered with lower memory access first. */
10913 if (offsets
[0] > offsets
[1])
10915 gap
= offsets
[0] - offsets
[1];
10916 offset
= offsets
[1];
10918 /* Swap the instructions such that lower memory is accessed first. */
10919 std::swap (operands
[0], operands
[1]);
10920 std::swap (operands
[2], operands
[3]);
10924 gap
= offsets
[1] - offsets
[0];
10925 offset
= offsets
[0];
10928 /* Make sure accesses are to consecutive memory locations. */
10932 /* Make sure we generate legal instructions. */
10933 if (operands_ok_ldd_std (operands
[0], operands
[1], offset
))
10936 if (load
&& commute
)
10938 /* Try reordering registers. */
10939 std::swap (operands
[0], operands
[1]);
10940 if (operands_ok_ldd_std (operands
[0], operands
[1], offset
))
10947 /* This order of allocation is used when we compile for size. It
10948 allocates first the registers which are most probably to end up in
10949 a short instruction. */
10950 static const int size_alloc_order
[] =
10952 0, 1, 2, 3, 12, 13, 14, 15,
10953 4, 5, 6, 7, 8, 9, 10, 11
10956 /* Adjust register allocation order when compiling for size. */
10958 arc_adjust_reg_alloc_order (void)
10960 const int arc_default_alloc_order
[] = REG_ALLOC_ORDER
;
10961 memcpy (reg_alloc_order
, arc_default_alloc_order
, sizeof (reg_alloc_order
));
10963 memcpy (reg_alloc_order
, size_alloc_order
, sizeof (size_alloc_order
));
10966 /* Implement TARGET_MEMORY_MOVE_COST. */
10969 arc_memory_move_cost (machine_mode mode
,
10970 reg_class_t rclass ATTRIBUTE_UNUSED
,
10971 bool in ATTRIBUTE_UNUSED
)
10973 if ((GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
10974 || ((GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
* 2) && TARGET_LL64
))
10977 return (2 * GET_MODE_SIZE (mode
));
10980 /* Split an OR instruction into multiple BSET/OR instructions in a
10981 attempt to avoid long immediate constants. The next strategies are
10982 employed when destination is 'q' reg.
10984 1. if there are up to three bits set in the mask, a succession of
10985 three bset instruction will be emitted:
10987 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
10989 2. if the lower 6 bits of the mask is set and there is only one
10990 bit set in the upper remaining bits then we will emit one bset and
10991 one OR instruction:
10992 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
10994 3. otherwise an OR with limm will be emmitted. */
10997 arc_split_ior (rtx
*operands
)
10999 unsigned HOST_WIDE_INT mask
, maskx
;
11000 rtx op1
= operands
[1];
11002 gcc_assert (CONST_INT_P (operands
[2]));
11003 mask
= INTVAL (operands
[2]) & 0xffffffff;
11005 if (__builtin_popcount (mask
) > 3 || (mask
& 0x3f))
11007 maskx
= mask
& 0x3f;
11008 emit_insn (gen_rtx_SET (operands
[0],
11009 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11014 switch (__builtin_popcount (mask
))
11017 maskx
= 1 << (__builtin_ffs (mask
) - 1);
11018 emit_insn (gen_rtx_SET (operands
[0],
11019 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11024 maskx
= 1 << (__builtin_ffs (mask
) - 1);
11025 emit_insn (gen_rtx_SET (operands
[0],
11026 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11031 maskx
= 1 << (__builtin_ffs (mask
) - 1);
11032 emit_insn (gen_rtx_SET (operands
[0],
11033 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11038 gcc_unreachable ();
11042 /* Helper to check C0x constraint. */
11045 arc_check_ior_const (HOST_WIDE_INT ival
)
11047 unsigned int mask
= (unsigned int) (ival
& 0xffffffff);
11049 if (UNSIGNED_INT6 (ival
)
11050 || IS_POWEROF2_P (mask
))
11052 if (__builtin_popcount (mask
) <= 3)
11054 if (__builtin_popcount (mask
& ~0x3f) <= 1)
11059 /* Split a mov with long immediate instruction into smaller, size
11060 friendly instructions. */
11063 arc_split_mov_const (rtx
*operands
)
11065 unsigned HOST_WIDE_INT ival
;
11066 HOST_WIDE_INT shimm
;
11067 machine_mode mode
= GET_MODE (operands
[0]);
11069 /* Manage a constant. */
11070 gcc_assert (CONST_INT_P (operands
[1]));
11071 ival
= INTVAL (operands
[1]) & 0xffffffff;
11073 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11074 if (TARGET_BARREL_SHIFTER
&& TARGET_V2
11075 && ((ival
& ~0x3f000000) == 0))
11077 shimm
= (ival
>> 24) & 0x3f;
11078 emit_insn (gen_rtx_SET (operands
[0],
11079 gen_rtx_ROTATERT (mode
, GEN_INT (shimm
),
11083 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11084 if (TARGET_BARREL_SHIFTER
&& TARGET_V2
11085 && ((ival
& ~0x3f00) == 0))
11087 shimm
= (ival
>> 8) & 0x3f;
11088 emit_insn (gen_rtx_SET (operands
[0],
11089 gen_rtx_ASHIFT (mode
, GEN_INT (shimm
),
11094 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11095 if (TARGET_SWAP
&& TARGET_V2
11096 && ((ival
& ~0x3f0000) == 0))
11098 shimm
= (ival
>> 16) & 0x3f;
11099 emit_insn (gen_rtx_SET (operands
[0],
11100 gen_rtx_ASHIFT (mode
, GEN_INT (shimm
),
11105 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11106 if (((ival
>> (__builtin_ffs (ival
) - 1)) & 0xffffff00) == 0
11107 && TARGET_BARREL_SHIFTER
)
11109 HOST_WIDE_INT shift
= __builtin_ffs (ival
);
11110 shimm
= (ival
>> (shift
- 1)) & 0xff;
11111 emit_insn (gen_rtx_SET (operands
[0], GEN_INT (shimm
)));
11112 emit_insn (gen_rtx_SET (operands
[0],
11113 gen_rtx_ASHIFT (mode
, operands
[0],
11114 GEN_INT (shift
- 1))));
11118 /* 5. Check if we can just rotate the limm, useful when no barrel
11119 shifter is present. */
11120 if ((ival
& ~0x8000001f) == 0)
11122 shimm
= (ival
* 2 + 1) & 0x3f;
11123 emit_insn (gen_rtx_SET (operands
[0],
11124 gen_rtx_ROTATERT (mode
, GEN_INT (shimm
),
11129 /* 6. Check if we can do something with bmask. */
11130 if (IS_POWEROF2_P (ival
+ 1))
11132 emit_insn (gen_rtx_SET (operands
[0], constm1_rtx
));
11133 emit_insn (gen_rtx_SET (operands
[0],
11134 gen_rtx_AND (mode
, operands
[0],
11139 gcc_unreachable ();
11142 /* Helper to check Cax constraint. */
11145 arc_check_mov_const (HOST_WIDE_INT ival
)
11147 ival
= ival
& 0xffffffff;
11149 if (SIGNED_INT12 (ival
))
11152 if ((ival
& ~0x8000001f) == 0)
11155 if (IS_POWEROF2_P (ival
+ 1))
11158 /* The next rules requires a barrel shifter. */
11159 if (!TARGET_BARREL_SHIFTER
)
11162 if (((ival
>> (__builtin_ffs (ival
) - 1)) & 0xffffff00) == 0)
11165 if ((ival
& ~0x3f00) == 0)
11168 if ((ival
& ~0x3f0000) == 0)
11171 if ((ival
& ~0x3f000000) == 0)
11177 /* Return nonzero if this function is known to have a null epilogue.
11178 This allows the optimizer to omit jumps to jumps if no stack
11182 arc_can_use_return_insn (void)
11184 return (reload_completed
&& cfun
->machine
->frame_info
.total_size
== 0
11185 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun
)));
11188 /* Helper for INSN_COST.
11190 Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
11191 insn, a set, a set source, any random piece of one). set_src_cost,
11192 set_rtx_cost, etc. are helper functions that use that.
11194 Those functions do not work for parallels. Also, costs are not
11195 additive like this simplified model assumes. Also, more complex
11196 backends tend to miss many cases in their rtx_costs function.
11198 Many passes that want costs want to know the cost of a full insn. Like
11199 combine. That's why I created insn_cost: it solves all of the above
11203 arc_insn_cost (rtx_insn
*insn
, bool speed
)
11206 enum attr_type type
;
11207 if (recog_memoized (insn
) >= 0)
11211 /* Use cost if provided. */
11212 cost
= get_attr_cost (insn
);
11215 /* For speed make a simple cost model: memory access is more
11216 expensive than any other instruction. */
11217 type
= get_attr_type (insn
);
11218 if (type
== TYPE_LOAD
|| type
== TYPE_STORE
)
11219 return COSTS_N_INSNS (2);
11223 /* If optimizing for size, we want the insn size. */
11224 type
= get_attr_type (insn
);
11225 if (type
!= TYPE_MULTI
)
11226 return get_attr_length (insn
);
11230 if (rtx set
= single_set (insn
))
11231 cost
= set_rtx_cost (set
, speed
);
11233 cost
= pattern_cost (PATTERN (insn
), speed
);
11234 /* If the cost is zero, then it's likely a complex insn. We don't
11235 want the cost of these to be less than something we know about. */
11236 return cost
? cost
: COSTS_N_INSNS (2);
11240 arc_libm_function_max_error (unsigned cfn
, machine_mode mode
,
11243 #ifdef OPTION_GLIBC
11244 bool glibc_p
= OPTION_GLIBC
;
11246 bool glibc_p
= false;
11250 int rnd
= flag_rounding_math
? 4 : 0;
11255 if (!boundary_p
&& mode
== DFmode
)
11260 if (!boundary_p
&& mode
== DFmode
)
11265 return glibc_linux_libm_function_max_error (cfn
, mode
, boundary_p
);
11267 return default_libm_function_max_error (cfn
, mode
, boundary_p
);
11270 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11271 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11273 #undef TARGET_CONSTANT_ALIGNMENT
11274 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11276 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11277 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11279 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11280 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11282 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11283 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11285 #undef TARGET_REGISTER_MOVE_COST
11286 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11288 #undef TARGET_MEMORY_MOVE_COST
11289 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11291 #undef TARGET_INSN_COST
11292 #define TARGET_INSN_COST arc_insn_cost
11294 #undef TARGET_LIBM_FUNCTION_MAX_ERROR
11295 #define TARGET_LIBM_FUNCTION_MAX_ERROR arc_libm_function_max_error
11297 struct gcc_target targetm
= TARGET_INITIALIZER
;
11299 #include "gt-arc.h"