1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2021 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
31 #define IN_TARGET_CODE 1
35 #include "coretypes.h"
44 #include "stringpool.h"
50 #include "diagnostic.h"
51 #include "fold-const.h"
53 #include "stor-layout.h"
56 #include "insn-attr.h"
60 #include "langhooks.h"
61 #include "tm-constrs.h"
62 #include "reload.h" /* For operands_match_p */
64 #include "tree-pass.h"
70 #include "hw-doloop.h"
72 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
73 static char arc_cpu_name
[10] = "";
74 static const char *arc_cpu_string
= arc_cpu_name
;
76 typedef struct GTY (()) _arc_jli_section
79 struct _arc_jli_section
*next
;
82 static arc_jli_section
*arc_jli_sections
= NULL
;
84 /* Track which regs are set fixed/call saved/call used from commnad line. */
85 HARD_REG_SET overrideregs
;
87 /* Maximum size of a loop. */
88 #define ARC_MAX_LOOP_LENGTH 4095
90 /* Check if an rtx fits in the store instruction format. Loads can
91 handle any constant. */
92 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
93 (GET_CODE (X) == CONST_INT \
94 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & (~0x03), \
95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
97 : -(-GET_MODE_SIZE (MODE) | (~0x03)) >> 1)))
99 /* Array of valid operand punctuation characters. */
100 char arc_punct_chars
[256];
102 /* State used by arc_ccfsm_advance to implement conditional execution. */
103 struct GTY (()) arc_ccfsm
108 rtx_insn
*target_insn
;
112 /* Status of the IRQ_CTRL_AUX register. */
113 typedef struct irq_ctrl_saved_t
115 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
116 short irq_save_last_reg
;
117 /* True if BLINK is automatically saved. */
119 /* True if LPCOUNT is automatically saved. */
120 bool irq_save_lpcount
;
122 static irq_ctrl_saved_t irq_ctrl_saved
;
124 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
125 ((ARC_INTERRUPT_P (FNTYPE) \
126 && irq_ctrl_saved.irq_save_blink) \
127 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
128 && rgf_banked_register_count > 8))
130 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
131 ((ARC_INTERRUPT_P (FNTYPE) \
132 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
133 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
134 && rgf_banked_register_count > 8))
136 #define ARC_AUTO_IRQ_P(FNTYPE) \
137 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
138 && (irq_ctrl_saved.irq_save_blink \
139 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
141 /* Number of registers in second bank for FIRQ support. */
142 static int rgf_banked_register_count
;
144 #define arc_ccfsm_current cfun->machine->ccfsm_current
146 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
147 ((STATE)->state == 1 || (STATE)->state == 2)
149 /* Indicate we're conditionalizing insns now. */
150 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
151 ((STATE)->state += 2)
153 #define ARC_CCFSM_COND_EXEC_P(STATE) \
154 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
155 || current_insn_predicate)
157 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
158 #define CCFSM_ISCOMPACT(INSN,STATE) \
159 (ARC_CCFSM_COND_EXEC_P (STATE) \
160 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
161 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
162 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
164 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
165 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
166 ((ARC_CCFSM_COND_EXEC_P (STATE) \
168 && INSN_ANNULLED_BRANCH_P (JUMP) \
169 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
170 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
171 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
172 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
174 /* Start enter/leave register range. */
175 #define ENTER_LEAVE_START_REG 13
177 /* End enter/leave register range. */
178 #define ENTER_LEAVE_END_REG 26
180 /* The maximum number of insns skipped which will be conditionalised if
182 /* When optimizing for speed:
183 Let p be the probability that the potentially skipped insns need to
184 be executed, pn the cost of a correctly predicted non-taken branch,
185 mt the cost of a mis/non-predicted taken branch,
186 mn mispredicted non-taken, pt correctly predicted taken ;
187 costs expressed in numbers of instructions like the ones considered
189 Unfortunately we don't have a measure of predictability - this
190 is linked to probability only in that in the no-eviction-scenario
191 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
192 value that can be assumed *if* the distribution is perfectly random.
193 A predictability of 1 is perfectly plausible not matter what p is,
194 because the decision could be dependent on an invocation parameter
196 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
197 For small p, we want MAX_INSNS_SKIPPED == pt
199 When optimizing for size:
200 We want to skip insn unless we could use 16 opcodes for the
201 non-conditionalized insn to balance the branch length or more.
202 Performance can be tie-breaker. */
203 /* If the potentially-skipped insns are likely to be executed, we'll
204 generally save one non-taken branch
206 this to be no less than the 1/p */
207 #define MAX_INSNS_SKIPPED 3
209 /* ZOL control registers. */
210 #define AUX_LP_START 0x02
211 #define AUX_LP_END 0x03
213 /* FPX AUX registers. */
214 #define AUX_DPFP_START 0x301
216 /* ARC600 MULHI register. */
217 #define AUX_MULHI 0x12
219 /* A nop is needed between a 4 byte insn that sets the condition codes and
220 a branch that uses them (the same isn't true for an 8 byte insn that sets
221 the condition codes). Set by arc_ccfsm_advance. Used by
222 arc_print_operand. */
224 static int get_arc_condition_code (rtx
);
226 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
227 static tree
arc_handle_fndecl_attribute (tree
*, tree
, tree
, int, bool *);
228 static tree
arc_handle_jli_attribute (tree
*, tree
, tree
, int, bool *);
229 static tree
arc_handle_secure_attribute (tree
*, tree
, tree
, int, bool *);
230 static tree
arc_handle_uncached_attribute (tree
*, tree
, tree
, int, bool *);
231 static tree
arc_handle_aux_attribute (tree
*, tree
, tree
, int, bool *);
233 /* Initialized arc_attribute_table to NULL since arc doesnot have any
234 machine specific supported attributes. */
235 const struct attribute_spec arc_attribute_table
[] =
237 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
238 affects_type_identity, handler, exclude } */
239 { "interrupt", 1, 1, true, false, false, true,
240 arc_handle_interrupt_attribute
, NULL
},
241 /* Function calls made to this symbol must be done indirectly, because
242 it may lie outside of the 21/25 bit addressing range of a normal function
244 { "long_call", 0, 0, false, true, true, false, NULL
, NULL
},
245 /* Whereas these functions are always known to reside within the 25 bit
246 addressing range of unconditionalized bl. */
247 { "medium_call", 0, 0, false, true, true, false, NULL
, NULL
},
248 /* And these functions are always known to reside within the 21 bit
249 addressing range of blcc. */
250 { "short_call", 0, 0, false, true, true, false, NULL
, NULL
},
251 /* Function which are not having the prologue and epilogue generated
253 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute
,
255 /* Functions calls made using jli instruction. The pointer in JLI
256 table is found latter. */
257 { "jli_always", 0, 0, false, true, true, false, NULL
, NULL
},
258 /* Functions calls made using jli instruction. The pointer in JLI
259 table is given as input parameter. */
260 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute
,
262 /* Call a function using secure-mode. */
263 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute
,
265 /* Bypass caches using .di flag. */
266 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute
,
268 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute
, NULL
},
269 { NULL
, 0, 0, false, false, false, false, NULL
, NULL
}
271 static int arc_comp_type_attributes (const_tree
, const_tree
);
272 static void arc_file_start (void);
273 static void arc_internal_label (FILE *, const char *, unsigned long);
274 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
276 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
277 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
279 static void arc_init_builtins (void);
280 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
282 static int branch_dest (rtx
);
284 static void arc_output_pic_addr_const (FILE *, rtx
, int);
285 static bool arc_function_ok_for_sibcall (tree
, tree
);
286 static rtx
arc_function_value (const_tree
, const_tree
, bool);
287 const char * output_shift (rtx
*);
288 static void arc_reorg (void);
289 static bool arc_in_small_data_p (const_tree
);
291 static void arc_init_reg_tables (void);
292 static bool arc_return_in_memory (const_tree
, const_tree
);
293 static bool arc_vector_mode_supported_p (machine_mode
);
295 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
297 static const char *arc_invalid_within_doloop (const rtx_insn
*);
299 static void output_short_suffix (FILE *file
);
301 static bool arc_frame_pointer_required (void);
303 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
305 enum by_pieces_operation op
,
308 /* Globally visible information about currently selected cpu. */
309 const arc_cpu_t
*arc_selected_cpu
;
311 /* Traditionally, we push saved registers first in the prologue,
312 then we allocate the rest of the frame - and reverse in the epilogue.
313 This has still its merits for ease of debugging, or saving code size
314 or even execution time if the stack frame is so large that some accesses
315 can't be encoded anymore with offsets in the instruction code when using
317 Also, it would be a good starting point if we got instructions to help
318 with register save/restore.
320 However, often stack frames are small, and the pushing / popping has
322 - the stack modification prevents a lot of scheduling.
323 - frame allocation / deallocation may need extra instructions.
324 - we need to place a memory barrier after frame allocation to avoid
325 the delay slot scheduler to reschedule a frame related info and
326 messing up with dwarf unwinding. The barrier before deallocation
327 is for flushing all pending sp operations.
329 Thus, for small frames, we'd like to use a different scheme:
330 - The frame is allocated in full with the first prologue instruction,
331 and deallocated in full with the last epilogue instruction.
332 Thus, the instructions in-between can be freely scheduled.
333 - If the function has no outgoing arguments on the stack, we can allocate
334 one register save slot at the top of the stack. This register can then
335 be saved simultaneously with frame allocation, and restored with
337 This register can be picked depending on scheduling considerations,
338 although same though should go into having some set of registers
339 to be potentially lingering after a call, and others to be available
340 immediately - i.e. in the absence of interprocedual optimization, we
341 can use an ABI-like convention for register allocation to reduce
342 stalls after function return. */
344 /* ARCompact stack frames look like:
346 Before call After call
347 high +-----------------------+ +-----------------------+
348 mem | reg parm save area | | reg parm save area |
349 | only created for | | only created for |
350 | variable arg fns | | variable arg fns |
351 AP +-----------------------+ +-----------------------+
352 | return addr register | | return addr register |
353 | (if required) | | (if required) |
354 +-----------------------+ +-----------------------+
356 | reg save area | | reg save area |
358 +-----------------------+ +-----------------------+
359 | frame pointer | | frame pointer |
360 | (if required) | | (if required) |
361 FP +-----------------------+ +-----------------------+
363 | local/temp variables | | local/temp variables |
365 +-----------------------+ +-----------------------+
367 | arguments on stack | | arguments on stack |
369 SP +-----------------------+ +-----------------------+
370 | reg parm save area |
373 AP +-----------------------+
374 | return addr register |
376 +-----------------------+
380 +-----------------------+
383 FP +-----------------------+
385 | local/temp variables |
387 +-----------------------+
389 | arguments on stack |
391 mem SP +-----------------------+
394 1) The "reg parm save area" does not exist for non variable argument fns.
395 The "reg parm save area" can be eliminated completely if we created our
396 own va-arc.h, but that has tradeoffs as well (so it's not done). */
398 /* Structure to be filled in by arc_compute_frame_size with register
399 save masks, and offsets for the current function. */
400 struct GTY (()) arc_frame_info
402 unsigned int total_size
; /* # bytes that the entire frame takes up. */
403 unsigned int extra_size
; /* # bytes of extra stuff. */
404 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
405 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
406 unsigned int reg_size
; /* # bytes needed to store regs. */
407 unsigned int var_size
; /* # bytes that variables take up. */
408 uint64_t gmask
; /* Mask of saved gp registers. */
409 bool initialized
; /* FALSE if frame size already calculated. */
410 short millicode_start_reg
;
411 short millicode_end_reg
;
412 bool save_return_addr
;
415 /* GMASK bit length -1. */
418 /* Defining data structures for per-function information. */
420 typedef struct GTY (()) machine_function
422 unsigned int fn_type
;
423 struct arc_frame_info frame_info
;
424 /* To keep track of unalignment caused by short insns. */
426 struct arc_ccfsm ccfsm_current
;
427 /* Map from uid to ccfsm state during branch shortening. */
428 rtx ccfsm_current_insn
;
429 char arc_reorg_started
;
430 char prescan_initialized
;
434 /* Given a symbol RTX (const (symb <+ const_int>), returns its
438 get_symbol_alignment (rtx x
)
440 tree decl
= NULL_TREE
;
443 switch (GET_CODE (x
))
446 decl
= SYMBOL_REF_DECL (x
);
449 return get_symbol_alignment (XEXP (x
, 0));
451 gcc_assert (CONST_INT_P (XEXP (x
, 1)));
452 return get_symbol_alignment (XEXP (x
, 0));
458 align
= DECL_ALIGN (decl
);
459 align
= align
/ BITS_PER_UNIT
;
463 /* Return true if x is ok to be used as a small data address. */
466 legitimate_small_data_address_p (rtx x
, machine_mode mode
)
468 switch (GET_CODE (x
))
471 return legitimate_small_data_address_p (XEXP (x
, 0), mode
);
473 return SYMBOL_REF_SMALL_P (x
);
476 bool p0
= (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
)
477 && SYMBOL_REF_SMALL_P (XEXP (x
, 0));
479 /* If no constant then we cannot do small data. */
480 if (!CONST_INT_P (XEXP (x
, 1)))
483 /* Small data relocs works with scalled addresses, check if
484 the immediate fits the requirements. */
485 switch (GET_MODE_SIZE (mode
))
490 return p0
&& ((INTVAL (XEXP (x
, 1)) & 0x1) == 0);
493 return p0
&& ((INTVAL (XEXP (x
, 1)) & 0x3) == 0);
503 /* TRUE if op is an scaled address. */
505 legitimate_scaled_address_p (machine_mode mode
, rtx op
, bool strict
)
507 if (GET_CODE (op
) != PLUS
)
510 if (GET_CODE (XEXP (op
, 0)) != MULT
)
513 /* Check multiplication operands. */
514 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op
, 0), 0), strict
))
517 if (!CONST_INT_P (XEXP (XEXP (op
, 0), 1)))
520 switch (GET_MODE_SIZE (mode
))
523 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 2)
531 if (INTVAL (XEXP (XEXP (op
, 0), 1)) != 4)
538 /* Check the base. */
539 if (RTX_OK_FOR_BASE_P (XEXP (op
, 1), (strict
)))
544 if (CONST_INT_P (XEXP (op
, 1)))
549 /* Scalled addresses for sdata is done other places. */
550 if (legitimate_small_data_address_p (op
, mode
))
553 if (CONSTANT_P (XEXP (op
, 1)))
559 /* Check for constructions like REG + OFFS, where OFFS can be a
560 register, an immediate or an long immediate. */
563 legitimate_offset_address_p (machine_mode mode
, rtx x
, bool index
, bool strict
)
565 if (GET_CODE (x
) != PLUS
)
568 if (!RTX_OK_FOR_BASE_P (XEXP (x
, 0), (strict
)))
571 /* Check for: [Rx + small offset] or [Rx + Ry]. */
572 if (((index
&& RTX_OK_FOR_INDEX_P (XEXP (x
, 1), (strict
))
573 && GET_MODE_SIZE ((mode
)) <= 4)
574 || RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1))))
577 /* Check for [Rx + symbol]. */
579 && (GET_CODE (XEXP (x
, 1)) == SYMBOL_REF
)
580 /* Avoid this type of address for double or larger modes. */
581 && (GET_MODE_SIZE (mode
) <= 4)
582 /* Avoid small data which ends in something like GP +
584 && (!SYMBOL_REF_SMALL_P (XEXP (x
, 1))))
590 /* Implements target hook vector_mode_supported_p. */
593 arc_vector_mode_supported_p (machine_mode mode
)
598 return TARGET_PLUS_DMPY
;
601 return TARGET_PLUS_QMACW
;
604 return TARGET_SIMD_SET
;
611 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
614 arc_preferred_simd_mode (scalar_mode mode
)
619 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
628 /* Implements target hook
629 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
632 arc_autovectorize_vector_modes (vector_modes
*modes
, bool)
634 if (TARGET_PLUS_QMACW
)
636 modes
->quick_push (V4HImode
);
637 modes
->quick_push (V2HImode
);
643 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
645 arc_sched_issue_rate (void)
658 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
659 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
660 static rtx
arc_delegitimize_address (rtx
);
661 static bool arc_can_follow_jump (const rtx_insn
*follower
,
662 const rtx_insn
*followee
);
664 static rtx
frame_insn (rtx
);
665 static void arc_function_arg_advance (cumulative_args_t
,
666 const function_arg_info
&);
667 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
669 /* initialize the GCC target structure. */
670 #undef TARGET_COMP_TYPE_ATTRIBUTES
671 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
672 #undef TARGET_ASM_FILE_START
673 #define TARGET_ASM_FILE_START arc_file_start
674 #undef TARGET_ATTRIBUTE_TABLE
675 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
676 #undef TARGET_ASM_INTERNAL_LABEL
677 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
678 #undef TARGET_RTX_COSTS
679 #define TARGET_RTX_COSTS arc_rtx_costs
680 #undef TARGET_ADDRESS_COST
681 #define TARGET_ADDRESS_COST arc_address_cost
683 #undef TARGET_ENCODE_SECTION_INFO
684 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
686 #undef TARGET_CANNOT_FORCE_CONST_MEM
687 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
689 #undef TARGET_INIT_BUILTINS
690 #define TARGET_INIT_BUILTINS arc_init_builtins
692 #undef TARGET_EXPAND_BUILTIN
693 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
695 #undef TARGET_BUILTIN_DECL
696 #define TARGET_BUILTIN_DECL arc_builtin_decl
698 #undef TARGET_ASM_OUTPUT_MI_THUNK
699 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
701 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
702 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
704 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
705 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
707 #undef TARGET_MACHINE_DEPENDENT_REORG
708 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
710 #undef TARGET_IN_SMALL_DATA_P
711 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
713 #undef TARGET_PROMOTE_FUNCTION_MODE
714 #define TARGET_PROMOTE_FUNCTION_MODE \
715 default_promote_function_mode_always_promote
717 #undef TARGET_PROMOTE_PROTOTYPES
718 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
720 #undef TARGET_RETURN_IN_MEMORY
721 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
722 #undef TARGET_PASS_BY_REFERENCE
723 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
725 #undef TARGET_SETUP_INCOMING_VARARGS
726 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
728 #undef TARGET_ARG_PARTIAL_BYTES
729 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
731 #undef TARGET_MUST_PASS_IN_STACK
732 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
734 #undef TARGET_FUNCTION_VALUE
735 #define TARGET_FUNCTION_VALUE arc_function_value
737 #undef TARGET_SCHED_ADJUST_PRIORITY
738 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
740 #undef TARGET_SCHED_ISSUE_RATE
741 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
743 #undef TARGET_VECTOR_MODE_SUPPORTED_P
744 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
746 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
747 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
749 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
750 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES arc_autovectorize_vector_modes
752 #undef TARGET_CAN_USE_DOLOOP_P
753 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
755 #undef TARGET_INVALID_WITHIN_DOLOOP
756 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
758 #undef TARGET_PRESERVE_RELOAD_P
759 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
761 #undef TARGET_CAN_FOLLOW_JUMP
762 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
764 #undef TARGET_DELEGITIMIZE_ADDRESS
765 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
767 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
768 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
769 arc_use_by_pieces_infrastructure_p
771 /* Usually, we will be able to scale anchor offsets.
772 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
773 #undef TARGET_MIN_ANCHOR_OFFSET
774 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
775 #undef TARGET_MAX_ANCHOR_OFFSET
776 #define TARGET_MAX_ANCHOR_OFFSET (1020)
778 #undef TARGET_SECONDARY_RELOAD
779 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
781 #define TARGET_OPTION_OVERRIDE arc_override_options
783 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
785 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
787 #define TARGET_CAN_ELIMINATE arc_can_eliminate
789 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
791 #define TARGET_FUNCTION_ARG arc_function_arg
793 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
795 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
797 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
799 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
801 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
803 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
804 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
805 arc_no_speculation_in_delay_slots_p
808 #define TARGET_LRA_P arc_lra_p
809 #define TARGET_REGISTER_PRIORITY arc_register_priority
810 /* Stores with scaled offsets have different displacement ranges. */
811 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
812 #define TARGET_SPILL_CLASS arc_spill_class
814 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
815 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
817 #undef TARGET_WARN_FUNC_RETURN
818 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
820 #include "target-def.h"
822 #undef TARGET_ASM_ALIGNED_HI_OP
823 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
824 #undef TARGET_ASM_ALIGNED_SI_OP
825 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
828 #undef TARGET_HAVE_TLS
829 #define TARGET_HAVE_TLS HAVE_AS_TLS
832 #undef TARGET_DWARF_REGISTER_SPAN
833 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
835 #undef TARGET_HARD_REGNO_NREGS
836 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
837 #undef TARGET_HARD_REGNO_MODE_OK
838 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
840 #undef TARGET_MODES_TIEABLE_P
841 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
843 /* Try to keep the (mov:DF _, reg) as early as possible so
844 that the d<add/sub/mul>h-lr insns appear together and can
845 use the peephole2 pattern. */
848 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
850 rtx set
= single_set (insn
);
852 && GET_MODE (SET_SRC(set
)) == DFmode
853 && GET_CODE (SET_SRC(set
)) == REG
)
855 /* Incrementing priority by 20 (empirically derived). */
856 return priority
+ 20;
862 /* For ARC base register + offset addressing, the validity of the
863 address is mode-dependent for most of the offset range, as the
864 offset can be scaled by the access size.
865 We don't expose these as mode-dependent addresses in the
866 mode_dependent_address_p target hook, because that would disable
867 lots of optimizations, and most uses of these addresses are for 32
868 or 64 bit accesses anyways, which are fine.
869 However, that leaves some addresses for 8 / 16 bit values not
870 properly reloaded by the generic code, which is why we have to
871 schedule secondary reloads for these. */
874 arc_secondary_reload (bool in_p
,
878 secondary_reload_info
*sri
)
880 enum rtx_code code
= GET_CODE (x
);
882 if (cl
== DOUBLE_REGS
)
885 /* If we have a subreg (reg), where reg is a pseudo (that will end in
886 a memory location), then we may need a scratch register to handle
887 the fp/sp+largeoffset address. */
895 int regno
= REGNO (x
);
896 if (regno
>= FIRST_PSEUDO_REGISTER
)
897 regno
= reg_renumber
[regno
];
902 /* It is a pseudo that ends in a stack location. This
903 procedure only works with the old reload step. */
904 if (!lra_in_progress
&& reg_equiv_mem (REGNO (x
)))
906 /* Get the equivalent address and check the range of the
908 rtx mem
= reg_equiv_mem (REGNO (x
));
909 addr
= find_replacement (&XEXP (mem
, 0));
914 gcc_assert (MEM_P (x
));
916 addr
= simplify_rtx (addr
);
918 if (addr
&& GET_CODE (addr
) == PLUS
919 && CONST_INT_P (XEXP (addr
, 1))
920 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
926 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
930 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
940 /* Convert reloads using offsets that are too large to use indirect
944 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
948 gcc_assert (GET_CODE (mem
) == MEM
);
949 addr
= XEXP (mem
, 0);
951 /* Large offset: use a move. FIXME: ld ops accepts limms as
952 offsets. Hence, the following move insn is not required. */
953 emit_move_insn (scratch
, addr
);
954 mem
= replace_equiv_address_nv (mem
, scratch
);
956 /* Now create the move. */
958 emit_insn (gen_rtx_SET (mem
, reg
));
960 emit_insn (gen_rtx_SET (reg
, mem
));
965 static unsigned arc_ifcvt (void);
969 const pass_data pass_data_arc_ifcvt
=
972 "arc_ifcvt", /* name */
973 OPTGROUP_NONE
, /* optinfo_flags */
974 TV_IFCVT2
, /* tv_id */
975 0, /* properties_required */
976 0, /* properties_provided */
977 0, /* properties_destroyed */
978 0, /* todo_flags_start */
979 TODO_df_finish
/* todo_flags_finish */
982 class pass_arc_ifcvt
: public rtl_opt_pass
985 pass_arc_ifcvt (gcc::context
*ctxt
)
986 : rtl_opt_pass (pass_data_arc_ifcvt
, ctxt
)
989 /* opt_pass methods: */
992 return new pass_arc_ifcvt (m_ctxt
);
994 virtual unsigned int execute (function
*)
998 virtual bool gate (function
*)
1000 return (optimize
> 1 && !TARGET_NO_COND_EXEC
);
1007 make_pass_arc_ifcvt (gcc::context
*ctxt
)
1009 return new pass_arc_ifcvt (ctxt
);
1012 static unsigned arc_predicate_delay_insns (void);
1016 const pass_data pass_data_arc_predicate_delay_insns
=
1019 "arc_predicate_delay_insns", /* name */
1020 OPTGROUP_NONE
, /* optinfo_flags */
1021 TV_IFCVT2
, /* tv_id */
1022 0, /* properties_required */
1023 0, /* properties_provided */
1024 0, /* properties_destroyed */
1025 0, /* todo_flags_start */
1026 TODO_df_finish
/* todo_flags_finish */
1029 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
1032 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
1033 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
1036 /* opt_pass methods: */
1037 virtual unsigned int execute (function
*)
1039 return arc_predicate_delay_insns ();
1041 virtual bool gate (function
*)
1043 return flag_delayed_branch
;
1050 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
1052 return new pass_arc_predicate_delay_insns (ctxt
);
1055 /* Called by OVERRIDE_OPTIONS to initialize various things. */
1062 /* I have the multiplier, then use it*/
1063 if (TARGET_MPYW
|| TARGET_MULTI
)
1064 arc_multcost
= COSTS_N_INSNS (1);
1066 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
1067 if (arc_multcost
< 0)
1070 case ARC_TUNE_ARC700_4_2_STD
:
1072 max throughput (1 multiply + 4 other insns) / 5 cycles. */
1073 arc_multcost
= COSTS_N_INSNS (4);
1074 if (TARGET_NOMPY_SET
)
1075 arc_multcost
= COSTS_N_INSNS (30);
1077 case ARC_TUNE_ARC700_4_2_XMAC
:
1079 max throughput (1 multiply + 2 other insns) / 3 cycles. */
1080 arc_multcost
= COSTS_N_INSNS (3);
1081 if (TARGET_NOMPY_SET
)
1082 arc_multcost
= COSTS_N_INSNS (30);
1084 case ARC_TUNE_ARC600
:
1085 if (TARGET_MUL64_SET
)
1087 arc_multcost
= COSTS_N_INSNS (4);
1092 arc_multcost
= COSTS_N_INSNS (30);
1096 /* MPY instructions valid only for ARC700 or ARCv2. */
1097 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
1098 error ("%<-mno-mpy%> supported only for ARC700 or ARCv2");
1100 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
1101 error ("%<-mno-dpfp-lrsr%> supported only with %<-mdpfp%>");
1103 /* FPX-1. No fast and compact together. */
1104 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
1105 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
1106 error ("FPX fast and compact options cannot be specified together");
1108 /* FPX-2. No fast-spfp for arc600 or arc601. */
1109 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
1110 error ("%<-mspfp_fast%> not available on ARC600 or ARC601");
1112 /* FPX-4. No FPX extensions mixed with FPU extensions. */
1113 if ((TARGET_DPFP_FAST_SET
|| TARGET_DPFP_COMPACT_SET
|| TARGET_SPFP
)
1114 && TARGET_HARD_FLOAT
)
1115 error ("no FPX/FPU mixing allowed");
1117 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
1118 if (flag_pic
&& TARGET_ARC600_FAMILY
)
1120 warning (0, "PIC is not supported for %qs",
1125 arc_init_reg_tables ();
1127 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
1128 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
1129 arc_punct_chars
['#'] = 1;
1130 arc_punct_chars
['*'] = 1;
1131 arc_punct_chars
['?'] = 1;
1132 arc_punct_chars
['!'] = 1;
1133 arc_punct_chars
['^'] = 1;
1134 arc_punct_chars
['&'] = 1;
1135 arc_punct_chars
['+'] = 1;
1136 arc_punct_chars
['_'] = 1;
1139 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1140 register range is specified as two registers separated by a dash.
1141 It always starts with r0, and its upper limit is fp register.
1142 blink and lp_count registers are optional. */
1145 irq_range (const char *cstr
)
1147 int i
, first
, last
, blink
, lpcount
, xreg
;
1148 char *str
, *dash
, *comma
;
1151 str
= (char *) alloca (i
+ 1);
1152 memcpy (str
, cstr
, i
+ 1);
1156 dash
= strchr (str
, '-');
1159 warning (OPT_mirq_ctrl_saved_
, "missing dash");
1164 comma
= strchr (dash
+ 1, ',');
1168 first
= decode_reg_name (str
);
1171 warning (OPT_mirq_ctrl_saved_
, "first register must be R0");
1175 /* At this moment we do not have the register names initialized
1177 if (!strcmp (dash
+ 1, "ilink"))
1180 last
= decode_reg_name (dash
+ 1);
1184 warning (OPT_mirq_ctrl_saved_
, "unknown register name: %s", dash
+ 1);
1190 warning (OPT_mirq_ctrl_saved_
,
1191 "last register name %s must be an odd register", dash
+ 1);
1199 warning (OPT_mirq_ctrl_saved_
,
1200 "%s-%s is an empty range", str
, dash
+ 1);
1209 comma
= strchr (str
, ',');
1213 xreg
= decode_reg_name (str
);
1225 warning (OPT_mirq_ctrl_saved_
,
1226 "unknown register name: %s", str
);
1231 irq_ctrl_saved
.irq_save_last_reg
= last
;
1232 irq_ctrl_saved
.irq_save_blink
= (blink
== 31) || (last
== 31);
1233 irq_ctrl_saved
.irq_save_lpcount
= (lpcount
== 60);
1236 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1240 parse_mrgf_banked_regs_option (const char *arg
)
1246 val
= strtol (arg
, &end_ptr
, 10);
1247 if (errno
!= 0 || *arg
== '\0' || *end_ptr
!= '\0'
1248 || (val
!= 0 && val
!= 4 && val
!= 8 && val
!= 16 && val
!= 32))
1250 error ("invalid number in %<-mrgf-banked-regs=%s%> "
1251 "valid values are 0, 4, 8, 16, or 32", arg
);
1254 rgf_banked_register_count
= (int) val
;
1257 /* Check ARC options, generate derived target attributes. */
1260 arc_override_options (void)
1263 cl_deferred_option
*opt
;
1264 vec
<cl_deferred_option
> *vopt
1265 = (vec
<cl_deferred_option
> *) arc_deferred_options
;
1267 if (arc_cpu
== PROCESSOR_NONE
)
1268 arc_cpu
= TARGET_CPU_DEFAULT
;
1270 /* Set the default cpu options. */
1271 arc_selected_cpu
= &arc_cpu_types
[(int) arc_cpu
];
1273 /* Set the architectures. */
1274 switch (arc_selected_cpu
->arch_info
->arch_id
)
1277 arc_cpu_string
= "EM";
1280 arc_cpu_string
= "HS";
1283 if (arc_selected_cpu
->processor
== PROCESSOR_nps400
)
1284 arc_cpu_string
= "NPS400";
1286 arc_cpu_string
= "ARC700";
1289 arc_cpu_string
= "ARC600";
1295 irq_ctrl_saved
.irq_save_last_reg
= -1;
1296 irq_ctrl_saved
.irq_save_blink
= false;
1297 irq_ctrl_saved
.irq_save_lpcount
= false;
1299 rgf_banked_register_count
= 0;
1301 /* Handle the deferred options. */
1303 FOR_EACH_VEC_ELT (*vopt
, i
, opt
)
1305 switch (opt
->opt_index
)
1307 case OPT_mirq_ctrl_saved_
:
1309 irq_range (opt
->arg
);
1311 warning (OPT_mirq_ctrl_saved_
,
1312 "option %<-mirq-ctrl-saved%> valid only "
1313 "for ARC v2 processors");
1316 case OPT_mrgf_banked_regs_
:
1318 parse_mrgf_banked_regs_option (opt
->arg
);
1320 warning (OPT_mrgf_banked_regs_
,
1321 "option %<-mrgf-banked-regs%> valid only for "
1322 "ARC v2 processors");
1330 CLEAR_HARD_REG_SET (overrideregs
);
1331 if (common_deferred_options
)
1333 vec
<cl_deferred_option
> v
=
1334 *((vec
<cl_deferred_option
> *) common_deferred_options
);
1337 FOR_EACH_VEC_ELT (v
, i
, opt
)
1339 switch (opt
->opt_index
)
1342 case OPT_fcall_used_
:
1343 case OPT_fcall_saved_
:
1344 if ((reg
= decode_reg_name_and_count (opt
->arg
, &nregs
)) >= 0)
1345 for (j
= reg
; j
< reg
+ nregs
; j
++)
1346 SET_HARD_REG_BIT (overrideregs
, j
);
1354 /* Check options against architecture options. Throw an error if
1355 option is not allowed. Extra, check options against default
1356 architecture/cpu flags and throw an warning if we find a
1358 /* TRANSLATORS: the DOC/DOC0/DOC1 are strings which shouldn't be
1359 translated. They are like keywords which one can relate with the
1360 architectural choices taken for an ARC CPU implementation. */
1361 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1363 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1365 error ("option %<%s=%s%> is not available for %qs CPU", \
1366 DOC0, DOC1, arc_selected_cpu->name); \
1367 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1368 && (VAR != DEFAULT_##VAR) \
1370 warning (0, "option %qs is ignored, the default value %qs" \
1371 " is considered for %qs CPU", DOC0, DOC1, \
1372 arc_selected_cpu->name); \
1374 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1376 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1377 && (target_flags & MASK)) \
1378 error ("option %qs is not available for %qs CPU", \
1379 DOC, arc_selected_cpu->name); \
1380 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1381 && (target_flags_explicit & MASK) \
1382 && (!(target_flags & MASK))) \
1383 warning (0, "unset option %qs is ignored, it is always" \
1384 " enabled for %qs CPU", DOC, \
1385 arc_selected_cpu->name); \
1388 #include "arc-options.def"
1393 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1394 specific flags are set in arc-common.c. The architecture forces
1395 the default hardware configurations in, regardless what command
1396 line options are saying. The CPU optional hw options can be
1397 turned on or off. */
1398 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1400 if ((arc_selected_cpu->flags & CODE) \
1401 && ((target_flags_explicit & MASK) == 0)) \
1402 target_flags |= MASK; \
1403 if (arc_selected_cpu->arch_info->dflags & CODE) \
1404 target_flags |= MASK; \
1406 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1408 if ((arc_selected_cpu->flags & CODE) \
1409 && (VAR == DEFAULT_##VAR)) \
1411 if (arc_selected_cpu->arch_info->dflags & CODE) \
1415 #include "arc-options.def"
1421 switch (arc_selected_cpu
->extra
)
1423 case HAS_LPCOUNT_16
:
1430 /* Set Tune option. */
1431 if (arc_tune
== ARC_TUNE_NONE
)
1432 arc_tune
= (enum arc_tune_attr
) arc_selected_cpu
->tune
;
1434 if (arc_size_opt_level
== 3)
1437 if (TARGET_V2
&& optimize_size
&& (ATTRIBUTE_PCS
== 2))
1438 TARGET_CODE_DENSITY_FRAME
= 1;
1441 target_flags
|= MASK_NO_SDATA_SET
;
1443 if (flag_no_common
== 255)
1444 flag_no_common
= !TARGET_NO_SDATA_SET
;
1446 /* Check for small data option */
1447 if (!global_options_set
.x_g_switch_value
&& !TARGET_NO_SDATA_SET
)
1448 g_switch_value
= TARGET_LL64
? 8 : 4;
1450 /* A7 has an issue with delay slots. */
1451 if (TARGET_ARC700
&& (arc_tune
!= ARC_TUNE_ARC7XX
))
1452 flag_delayed_branch
= 0;
1454 /* Millicode thunks doesn't work with long calls. */
1455 if (TARGET_LONG_CALLS_SET
)
1456 target_flags
&= ~MASK_MILLICODE_THUNK_SET
;
1458 /* Set unaligned to all HS cpus. */
1459 if (!global_options_set
.x_unaligned_access
&& TARGET_HS
)
1460 unaligned_access
= 1;
1462 /* These need to be done at start up. It's convenient to do them here. */
1466 /* The condition codes of the ARC, and the inverse function. */
1467 /* For short branches, the "c" / "nc" names are not defined in the ARC
1468 Programmers manual, so we have to use "lo" / "hs"" instead. */
1469 static const char *arc_condition_codes
[] =
1471 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1472 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1475 enum arc_cc_code_index
1477 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
1478 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
1479 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
1480 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
1483 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1485 /* Returns the index of the ARC condition code string in
1486 `arc_condition_codes'. COMPARISON should be an rtx like
1487 `(eq (...) (...))'. */
1490 get_arc_condition_code (rtx comparison
)
1492 switch (GET_MODE (XEXP (comparison
, 0)))
1495 case E_SImode
: /* For BRcc. */
1496 switch (GET_CODE (comparison
))
1498 case EQ
: return ARC_CC_EQ
;
1499 case NE
: return ARC_CC_NE
;
1500 case GT
: return ARC_CC_GT
;
1501 case LE
: return ARC_CC_LE
;
1502 case GE
: return ARC_CC_GE
;
1503 case LT
: return ARC_CC_LT
;
1504 case GTU
: return ARC_CC_HI
;
1505 case LEU
: return ARC_CC_LS
;
1506 case LTU
: return ARC_CC_LO
;
1507 case GEU
: return ARC_CC_HS
;
1508 default : gcc_unreachable ();
1511 switch (GET_CODE (comparison
))
1513 case EQ
: return ARC_CC_EQ
;
1514 case NE
: return ARC_CC_NE
;
1515 case GE
: return ARC_CC_P
;
1516 case LT
: return ARC_CC_N
;
1517 case GT
: return ARC_CC_PNZ
;
1518 default : gcc_unreachable ();
1521 switch (GET_CODE (comparison
))
1523 case EQ
: return ARC_CC_EQ
;
1524 case NE
: return ARC_CC_NE
;
1525 default : gcc_unreachable ();
1528 switch (GET_CODE (comparison
))
1530 case LTU
: return ARC_CC_C
;
1531 case GEU
: return ARC_CC_NC
;
1532 default : gcc_unreachable ();
1534 case E_CC_FP_GTmode
:
1535 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
1536 switch (GET_CODE (comparison
))
1538 case GT
: return ARC_CC_N
;
1539 case UNLE
: return ARC_CC_P
;
1540 default : gcc_unreachable ();
1543 switch (GET_CODE (comparison
))
1545 case GT
: return ARC_CC_HI
;
1546 case UNLE
: return ARC_CC_LS
;
1547 default : gcc_unreachable ();
1549 case E_CC_FP_GEmode
:
1550 /* Same for FPX and non-FPX. */
1551 switch (GET_CODE (comparison
))
1553 case GE
: return ARC_CC_HS
;
1554 case UNLT
: return ARC_CC_LO
;
1555 default : gcc_unreachable ();
1557 case E_CC_FP_UNEQmode
:
1558 switch (GET_CODE (comparison
))
1560 case UNEQ
: return ARC_CC_EQ
;
1561 case LTGT
: return ARC_CC_NE
;
1562 default : gcc_unreachable ();
1564 case E_CC_FP_ORDmode
:
1565 switch (GET_CODE (comparison
))
1567 case UNORDERED
: return ARC_CC_C
;
1568 case ORDERED
: return ARC_CC_NC
;
1569 default : gcc_unreachable ();
1572 switch (GET_CODE (comparison
))
1574 case EQ
: return ARC_CC_EQ
;
1575 case NE
: return ARC_CC_NE
;
1576 case UNORDERED
: return ARC_CC_C
;
1577 case ORDERED
: return ARC_CC_NC
;
1578 case LTGT
: return ARC_CC_HI
;
1579 case UNEQ
: return ARC_CC_LS
;
1580 default : gcc_unreachable ();
1584 switch (GET_CODE (comparison
))
1586 case EQ
: return ARC_CC_EQ
;
1587 case NE
: return ARC_CC_NE
;
1588 case GT
: return ARC_CC_GT
;
1589 case GE
: return ARC_CC_GE
;
1590 case LT
: return ARC_CC_C
;
1591 case LE
: return ARC_CC_LS
;
1592 case UNORDERED
: return ARC_CC_V
;
1593 case ORDERED
: return ARC_CC_NV
;
1594 case UNGT
: return ARC_CC_HI
;
1595 case UNGE
: return ARC_CC_HS
;
1596 case UNLT
: return ARC_CC_LT
;
1597 case UNLE
: return ARC_CC_LE
;
1598 /* UNEQ and LTGT do not have representation. */
1599 case LTGT
: /* Fall through. */
1600 case UNEQ
: /* Fall through. */
1601 default : gcc_unreachable ();
1603 case E_CC_FPU_UNEQmode
:
1604 switch (GET_CODE (comparison
))
1606 case LTGT
: return ARC_CC_NE
;
1607 case UNEQ
: return ARC_CC_EQ
;
1608 default : gcc_unreachable ();
1610 default : gcc_unreachable ();
1616 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1619 arc_short_comparison_p (rtx comparison
, int offset
)
1621 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1622 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1623 switch (get_arc_condition_code (comparison
))
1625 case ARC_CC_EQ
: case ARC_CC_NE
:
1626 return offset
>= -512 && offset
<= 506;
1627 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1628 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1629 return offset
>= -64 && offset
<= 58;
1635 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1636 return the mode to be used for the comparison. */
1639 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1641 machine_mode mode
= GET_MODE (x
);
1644 /* For an operation that sets the condition codes as a side-effect, the
1645 C and V flags is not set as for cmp, so we can only use comparisons where
1646 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1648 /* ??? We could use "pnz" for greater than zero, however, we could then
1649 get into trouble because the comparison could not be reversed. */
1650 if (GET_MODE_CLASS (mode
) == MODE_INT
1652 && (op
== EQ
|| op
== NE
1653 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1656 /* add.f for if (a+b) */
1658 && GET_CODE (y
) == NEG
1659 && (op
== EQ
|| op
== NE
))
1662 /* Check if this is a test suitable for bxor.f . */
1663 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1664 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1668 /* Check if this is a test suitable for add / bmsk.f . */
1669 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1670 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1671 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1672 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1673 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1676 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1677 && GET_CODE (x
) == PLUS
1678 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1681 if (TARGET_ARGONAUT_SET
1682 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1685 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1687 case LT
: case UNGE
: case GT
: case UNLE
:
1688 return CC_FP_GTmode
;
1689 case LE
: case UNGT
: case GE
: case UNLT
:
1690 return CC_FP_GEmode
;
1691 default: gcc_unreachable ();
1693 else if (TARGET_HARD_FLOAT
1694 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1695 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1716 return CC_FPU_UNEQmode
;
1721 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1725 case EQ
: case NE
: return CC_Zmode
;
1727 case GT
: case UNLE
: return CC_FP_GTmode
;
1729 case GE
: case UNLT
: return CC_FP_GEmode
;
1730 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1731 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1732 default: gcc_unreachable ();
1738 /* Vectors to keep interesting information about registers where it can easily
1739 be got. We use to use the actual mode value as the bit number, but there
1740 is (or may be) more than 32 modes now. Instead we use two tables: one
1741 indexed by hard register number, and one indexed by mode. */
1743 /* The purpose of arc_mode_class is to shrink the range of modes so that
1744 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1745 mapped into one arc_mode_class mode. */
1747 enum arc_mode_class
{
1749 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1750 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1754 /* Modes for condition codes. */
1755 #define C_MODES (1 << (int) C_MODE)
1757 /* Modes for single-word and smaller quantities. */
1758 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1760 /* Modes for double-word and smaller quantities. */
1761 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1763 /* Mode for 8-byte DF values only. */
1764 #define DF_MODES (1 << DF_MODE)
1766 /* Modes for quad-word and smaller quantities. */
1767 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1769 /* Modes for 128-bit vectors. */
1770 #define V_MODES (1 << (int) V_MODE)
1772 /* Value is 1 if register/mode pair is acceptable on arc. */
1774 static unsigned int arc_hard_regno_modes
[] = {
1775 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1776 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1777 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1778 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1780 /* ??? Leave these as S_MODES for now. */
1781 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1782 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1783 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1784 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1786 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1787 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1788 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1789 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1791 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1792 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1793 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1794 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1796 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1797 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1801 static unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1803 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1806 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1811 /* Initialize the arc_mode_class array. */
1814 arc_init_reg_tables (void)
1818 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1820 machine_mode m
= (machine_mode
) i
;
1822 switch (GET_MODE_CLASS (m
))
1825 case MODE_PARTIAL_INT
:
1826 case MODE_COMPLEX_INT
:
1827 if (GET_MODE_SIZE (m
) <= 4)
1828 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1829 else if (GET_MODE_SIZE (m
) == 8)
1830 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1831 else if (GET_MODE_SIZE (m
) == 16)
1832 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1833 else if (GET_MODE_SIZE (m
) == 32)
1834 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1836 arc_mode_class
[i
] = 0;
1839 case MODE_COMPLEX_FLOAT
:
1840 if (GET_MODE_SIZE (m
) <= 4)
1841 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1842 else if (GET_MODE_SIZE (m
) == 8)
1843 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1844 else if (GET_MODE_SIZE (m
) == 16)
1845 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1846 else if (GET_MODE_SIZE (m
) == 32)
1847 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1849 arc_mode_class
[i
] = 0;
1851 case MODE_VECTOR_INT
:
1852 if (GET_MODE_SIZE (m
) == 4)
1853 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1854 else if (GET_MODE_SIZE (m
) == 8)
1855 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1857 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1861 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1862 we must explicitly check for them here. */
1863 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1864 || i
== (int) CC_Cmode
1865 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1866 || i
== CC_FPUmode
|| i
== CC_FPUEmode
|| i
== CC_FPU_UNEQmode
)
1867 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1869 arc_mode_class
[i
] = 0;
1875 /* Core registers 56..59 are used for multiply extension options.
1876 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1877 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1878 number depends on endianness.
1879 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1880 Because mlo / mhi form a 64 bit value, we use different gcc internal
1881 register numbers to make them form a register pair as the gcc internals
1882 know it. mmid gets number 57, if still available, and mlo / mhi get
1883 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1884 to map this back. */
1885 char rname56
[5] = "r56";
1886 char rname57
[5] = "r57";
1887 char rname58
[5] = "r58";
1888 char rname59
[5] = "r59";
1889 char rname29
[7] = "ilink1";
1890 char rname30
[7] = "ilink2";
1893 arc_conditional_register_usage (void)
1897 int fix_start
= 60, fix_end
= 55;
1901 /* For ARCv2 the core register set is changed. */
1902 strcpy (rname29
, "ilink");
1903 strcpy (rname30
, "r30");
1905 if (!TEST_HARD_REG_BIT (overrideregs
, R30_REG
))
1907 /* No user interference. Set the r30 to be used by the
1909 call_used_regs
[R30_REG
] = 1;
1910 fixed_regs
[R30_REG
] = 0;
1912 arc_regno_reg_class
[R30_REG
] = GENERAL_REGS
;
1916 if (TARGET_MUL64_SET
)
1918 fix_start
= R57_REG
;
1921 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1922 you are supposed to refer to it as mlo & mhi, e.g
1923 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1924 In an actual asm instruction, you are of course use mmed.
1925 The point of avoiding having a separate register for mmed is that
1926 this way, we don't have to carry clobbers of that reg around in every
1927 isntruction that modifies mlo and/or mhi. */
1928 strcpy (rname57
, "");
1929 strcpy (rname58
, "mlo");
1930 strcpy (rname59
, "mhi");
1933 /* The nature of arc_tp_regno is actually something more like a global
1934 register, however globalize_reg requires a declaration.
1935 We use EPILOGUE_USES to compensate so that sets from
1936 __builtin_set_frame_pointer are not deleted. */
1937 if (arc_tp_regno
!= -1)
1938 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1940 if (TARGET_MULMAC_32BY16_SET
)
1942 fix_start
= MUL32x16_REG
;
1943 fix_end
= fix_end
> R57_REG
? fix_end
: R57_REG
;
1944 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1945 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1947 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1949 if (!fixed_regs
[regno
])
1950 warning (0, "multiply option implies r%d is fixed", regno
);
1951 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1954 /* Reduced configuration: don't use r4-r9, r16-r25. */
1957 for (i
= R4_REG
; i
<= R9_REG
; i
++)
1958 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1959 for (i
= R16_REG
; i
<= R25_REG
; i
++)
1960 fixed_regs
[i
] = call_used_regs
[i
] = 1;
1963 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1966 for (regno
= R1_REG
; regno
< R32_REG
; regno
+=2)
1967 arc_hard_regno_modes
[regno
] = S_MODES
;
1969 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1972 if ((i
<= R3_REG
) || ((i
>= R12_REG
) && (i
<= R15_REG
)))
1973 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1975 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1977 else if (i
< LP_COUNT
)
1978 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1980 arc_regno_reg_class
[i
] = NO_REGS
;
1982 /* Handle Special Registers. */
1983 arc_regno_reg_class
[CC_REG
] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1984 arc_regno_reg_class
[FRAME_POINTER_REGNUM
] = GENERAL_REGS
;
1985 arc_regno_reg_class
[ARG_POINTER_REGNUM
] = GENERAL_REGS
;
1988 for (i
= R40_REG
; i
< R44_REG
; ++i
)
1990 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1991 if (!TARGET_ARGONAUT_SET
)
1992 CLEAR_HARD_REG_BIT (reg_class_contents
[GENERAL_REGS
], i
);
1996 /* Disable all DOUBLE_REGISTER settings, if not generating DPFP
1998 arc_regno_reg_class
[R40_REG
] = ALL_REGS
;
1999 arc_regno_reg_class
[R41_REG
] = ALL_REGS
;
2000 arc_regno_reg_class
[R42_REG
] = ALL_REGS
;
2001 arc_regno_reg_class
[R43_REG
] = ALL_REGS
;
2003 fixed_regs
[R40_REG
] = 1;
2004 fixed_regs
[R41_REG
] = 1;
2005 fixed_regs
[R42_REG
] = 1;
2006 fixed_regs
[R43_REG
] = 1;
2008 arc_hard_regno_modes
[R40_REG
] = 0;
2009 arc_hard_regno_modes
[R42_REG
] = 0;
2012 if (TARGET_SIMD_SET
)
2014 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
2015 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
2017 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
2018 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
2020 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
2021 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
2022 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
2023 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
2025 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
2026 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
2027 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
2031 arc_regno_reg_class
[PCL_REG
] = NO_REGS
;
2033 /*ARCV2 Accumulator. */
2035 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
2036 || TARGET_PLUS_DMPY
)
2038 arc_regno_reg_class
[ACCL_REGNO
] = GENERAL_REGS
;
2039 arc_regno_reg_class
[ACCH_REGNO
] = GENERAL_REGS
;
2041 /* Allow the compiler to freely use them. */
2042 if (!TEST_HARD_REG_BIT (overrideregs
, ACCL_REGNO
))
2043 fixed_regs
[ACCL_REGNO
] = 0;
2044 if (!TEST_HARD_REG_BIT (overrideregs
, ACCH_REGNO
))
2045 fixed_regs
[ACCH_REGNO
] = 0;
2047 if (!fixed_regs
[ACCH_REGNO
] && !fixed_regs
[ACCL_REGNO
])
2048 arc_hard_regno_modes
[ACC_REG_FIRST
] = D_MODES
;
2052 /* Implement TARGET_HARD_REGNO_NREGS. */
2055 arc_hard_regno_nregs (unsigned int regno
, machine_mode mode
)
2057 if (GET_MODE_SIZE (mode
) == 16
2058 && regno
>= ARC_FIRST_SIMD_VR_REG
2059 && regno
<= ARC_LAST_SIMD_VR_REG
)
2062 return CEIL (GET_MODE_SIZE (mode
), UNITS_PER_WORD
);
2065 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2068 arc_hard_regno_mode_ok (unsigned int regno
, machine_mode mode
)
2070 return (arc_hard_regno_modes
[regno
] & arc_mode_class
[mode
]) != 0;
2073 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
2076 arc_modes_tieable_p (machine_mode mode1
, machine_mode mode2
)
2078 return (GET_MODE_CLASS (mode1
) == MODE_INT
2079 && GET_MODE_CLASS (mode2
) == MODE_INT
2080 && GET_MODE_SIZE (mode1
) <= UNITS_PER_WORD
2081 && GET_MODE_SIZE (mode2
) <= UNITS_PER_WORD
);
2084 /* Handle an "interrupt" attribute; arguments as in
2085 struct attribute_spec.handler. */
2088 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
2093 tree value
= TREE_VALUE (args
);
2095 if (TREE_CODE (value
) != STRING_CST
)
2097 warning (OPT_Wattributes
,
2098 "argument of %qE attribute is not a string constant",
2100 *no_add_attrs
= true;
2103 && strcmp (TREE_STRING_POINTER (value
), "ilink1")
2104 && strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2106 warning (OPT_Wattributes
,
2107 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2109 *no_add_attrs
= true;
2112 && strcmp (TREE_STRING_POINTER (value
), "ilink")
2113 && strcmp (TREE_STRING_POINTER (value
), "firq"))
2115 warning (OPT_Wattributes
,
2116 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2118 *no_add_attrs
= true;
2125 arc_handle_fndecl_attribute (tree
*node
, tree name
, tree args ATTRIBUTE_UNUSED
,
2126 int flags ATTRIBUTE_UNUSED
, bool *no_add_attrs
)
2128 if (TREE_CODE (*node
) != FUNCTION_DECL
)
2130 warning (OPT_Wattributes
, "%qE attribute only applies to functions",
2132 *no_add_attrs
= true;
2138 /* Type of function DECL.
2140 The result is cached. To reset the cache at the end of a function,
2141 call with DECL = NULL_TREE. */
2144 arc_compute_function_type (struct function
*fun
)
2146 tree attr
, decl
= fun
->decl
;
2147 unsigned int fn_type
= fun
->machine
->fn_type
;
2149 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2152 /* Check if it is a naked function. */
2153 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl
)) != NULL_TREE
)
2154 fn_type
|= ARC_FUNCTION_NAKED
;
2156 fn_type
|= ARC_FUNCTION_NORMAL
;
2158 /* Now see if this is an interrupt handler. */
2159 attr
= lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl
));
2160 if (attr
!= NULL_TREE
)
2162 tree value
, args
= TREE_VALUE (attr
);
2164 gcc_assert (list_length (args
) == 1);
2165 value
= TREE_VALUE (args
);
2166 gcc_assert (TREE_CODE (value
) == STRING_CST
);
2168 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2169 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2170 fn_type
|= ARC_FUNCTION_ILINK1
;
2171 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2172 fn_type
|= ARC_FUNCTION_ILINK2
;
2173 else if (!strcmp (TREE_STRING_POINTER (value
), "firq"))
2174 fn_type
|= ARC_FUNCTION_FIRQ
;
2179 return fun
->machine
->fn_type
= fn_type
;
2182 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2185 arc_allocate_stack_slots_for_args (void)
2187 /* Naked functions should not allocate stack slots for arguments. */
2188 unsigned int fn_type
= arc_compute_function_type (cfun
);
2190 return !ARC_NAKED_P(fn_type
);
2193 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2196 arc_warn_func_return (tree decl
)
2198 struct function
*func
= DECL_STRUCT_FUNCTION (decl
);
2199 unsigned int fn_type
= arc_compute_function_type (func
);
2201 return !ARC_NAKED_P (fn_type
);
2204 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2205 and two if they are nearly compatible (which causes a warning to be
2209 arc_comp_type_attributes (const_tree type1
,
2212 int l1
, l2
, m1
, m2
, s1
, s2
;
2214 /* Check for mismatch of non-default calling convention. */
2215 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
2218 /* Check for mismatched call attributes. */
2219 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2220 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2221 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2222 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2223 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
2224 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
2226 /* Only bother to check if an attribute is defined. */
2227 if (l1
| l2
| m1
| m2
| s1
| s2
)
2229 /* If one type has an attribute, the other must have the same attribute. */
2230 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
2233 /* Disallow mixed attributes. */
2234 if (l1
+ m1
+ s1
> 1)
2242 /* Misc. utilities. */
2244 /* X and Y are two things to compare using CODE. Emit the compare insn and
2245 return the rtx for the cc reg in the proper mode. */
2248 gen_compare_reg (rtx comparison
, machine_mode omode
)
2250 enum rtx_code code
= GET_CODE (comparison
);
2251 rtx x
= XEXP (comparison
, 0);
2252 rtx y
= XEXP (comparison
, 1);
2254 machine_mode mode
, cmode
;
2257 cmode
= GET_MODE (x
);
2258 if (cmode
== VOIDmode
)
2259 cmode
= GET_MODE (y
);
2260 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
2261 if (cmode
== SImode
)
2263 if (!register_operand (x
, SImode
))
2265 if (register_operand (y
, SImode
))
2270 code
= swap_condition (code
);
2273 x
= copy_to_mode_reg (SImode
, x
);
2275 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
2276 y
= copy_to_mode_reg (SImode
, y
);
2280 x
= force_reg (cmode
, x
);
2281 y
= force_reg (cmode
, y
);
2283 mode
= SELECT_CC_MODE (code
, x
, y
);
2285 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
2287 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2288 cmpdfpx_raw, is not a correct comparison for floats:
2289 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2291 if (TARGET_ARGONAUT_SET
2292 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
2296 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
2297 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2299 case GT
: case UNLE
: case GE
: case UNLT
:
2300 code
= swap_condition (code
);
2308 if (cmode
== SFmode
)
2310 emit_insn (gen_cmpsfpx_raw (x
, y
));
2314 /* Accepts Dx regs directly by insns. */
2315 emit_insn (gen_cmpdfpx_raw (x
, y
));
2318 if (mode
!= CC_FPXmode
)
2319 emit_insn (gen_rtx_SET (cc_reg
,
2320 gen_rtx_COMPARE (mode
,
2321 gen_rtx_REG (CC_FPXmode
, 61),
2324 else if (TARGET_FPX_QUARK
&& (cmode
== SFmode
))
2328 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2329 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2331 case LT
: case UNGE
: case LE
: case UNGT
:
2332 code
= swap_condition (code
);
2341 emit_insn (gen_cmp_quark (cc_reg
,
2342 gen_rtx_COMPARE (mode
, x
, y
)));
2344 else if (TARGET_HARD_FLOAT
2345 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
2346 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
2347 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2348 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
2350 rtx op0
= gen_rtx_REG (cmode
, 0);
2351 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
2356 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
2357 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
2359 case LT
: case UNGE
: case LE
: case UNGT
:
2360 code
= swap_condition (code
);
2366 if (currently_expanding_to_rtl
)
2374 emit_move_insn (op0
, x
);
2375 emit_move_insn (op1
, y
);
2379 gcc_assert (rtx_equal_p (op0
, x
));
2380 gcc_assert (rtx_equal_p (op1
, y
));
2387 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
2390 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
2391 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
2394 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2395 We assume the value can be either signed or unsigned. */
2398 arc_double_limm_p (rtx value
)
2400 HOST_WIDE_INT low
, high
;
2402 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
2407 low
= CONST_DOUBLE_LOW (value
);
2408 high
= CONST_DOUBLE_HIGH (value
);
2410 if (low
& 0x80000000)
2412 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
2413 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
2414 == - (unsigned HOST_WIDE_INT
) 0x80000000)
2419 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
2423 /* Do any needed setup for a variadic function. For the ARC, we must
2424 create a register parameter block, and then copy any anonymous arguments
2425 in registers to memory.
2427 CUM has not been updated for the last named argument (which is given
2428 by ARG), and we rely on this fact. */
2431 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
2432 const function_arg_info
&arg
,
2433 int *pretend_size
, int no_rtl
)
2436 CUMULATIVE_ARGS next_cum
;
2438 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2440 next_cum
= *get_cumulative_args (args_so_far
);
2441 arc_function_arg_advance (pack_cumulative_args (&next_cum
), arg
);
2442 first_anon_arg
= next_cum
;
2444 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
2446 /* First anonymous (unnamed) argument is in a reg. */
2448 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2449 int first_reg_offset
= first_anon_arg
;
2454 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
2455 FIRST_PARM_OFFSET (0)));
2456 move_block_from_reg (first_reg_offset
, regblock
,
2457 MAX_ARC_PARM_REGS
- first_reg_offset
);
2461 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
2465 /* Cost functions. */
2467 /* Provide the costs of an addressing mode that contains ADDR.
2468 If ADDR is not a valid address, its cost is irrelevant. */
2471 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
2473 switch (GET_CODE (addr
))
2476 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
2477 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
2478 case PRE_MODIFY
: case POST_MODIFY
:
2484 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
2486 /* Most likely needs a LIMM. */
2487 return COSTS_N_INSNS (1);
2491 register rtx plus0
= XEXP (addr
, 0);
2492 register rtx plus1
= XEXP (addr
, 1);
2494 if (GET_CODE (plus0
) != REG
2495 && (GET_CODE (plus0
) != MULT
2496 || !CONST_INT_P (XEXP (plus0
, 1))
2497 || (INTVAL (XEXP (plus0
, 1)) != 2
2498 && INTVAL (XEXP (plus0
, 1)) != 4)))
2501 switch (GET_CODE (plus1
))
2504 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
2508 : (satisfies_constraint_Rcq (plus0
)
2509 && satisfies_constraint_O (plus1
))
2513 return (speed
< 1 ? 0
2514 : (satisfies_constraint_Rcq (plus0
)
2515 && satisfies_constraint_Rcq (plus1
))
2520 return COSTS_N_INSNS (1);
2533 /* Emit instruction X with the frame related bit set. */
2539 RTX_FRAME_RELATED_P (x
) = 1;
2543 /* Emit a frame insn to move SRC to DST. */
2546 frame_move (rtx dst
, rtx src
)
2548 rtx tmp
= gen_rtx_SET (dst
, src
);
2549 RTX_FRAME_RELATED_P (tmp
) = 1;
2550 return frame_insn (tmp
);
2553 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2554 auto increment address, or is zero. */
2557 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
2559 rtx insn
= frame_move (dst
, src
);
2562 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
2563 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
2564 add_reg_note (insn
, REG_INC
, reg
);
2568 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2571 frame_add (rtx reg
, HOST_WIDE_INT offset
)
2573 gcc_assert ((offset
& 0x3) == 0);
2576 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
2579 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2582 frame_stack_add (HOST_WIDE_INT offset
)
2584 return frame_add (stack_pointer_rtx
, offset
);
2587 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2588 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2589 Register Allocator) pass, while we want to get the frame size
2590 correct earlier than the IRA pass.
2592 When a function uses eh_return we must ensure that the fp register
2593 is saved and then restored so that the unwinder can restore the
2594 correct value for the frame we are going to jump to.
2596 To do this we force all frames that call eh_return to require a
2597 frame pointer (see arc_frame_pointer_required), this
2598 will ensure that the previous frame pointer is stored on entry to
2599 the function, and will then be reloaded at function exit.
2601 As the frame pointer is handled as a special case in our prologue
2602 and epilogue code it must not be saved and restored using the
2603 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2604 believes that the function is not using a frame pointer and that
2605 the value in the fp register is the frame pointer, while the
2606 prologue and epilogue are busy saving and restoring the fp
2609 During compilation of a function the frame size is evaluated
2610 multiple times, it is not until the reload pass is complete the
2611 frame size is considered fixed (it is at this point that space for
2612 all spills has been allocated). However the frame_pointer_needed
2613 variable is not set true until the register allocation pass, as a
2614 result in the early stages the frame size does not include space
2615 for the frame pointer to be spilled.
2617 The problem that this causes is that the rtl generated for
2618 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2619 the offset from the frame pointer at which the return address
2620 lives. However, in early passes GCC has not yet realised we need a
2621 frame pointer, and so has not included space for the frame pointer
2622 in the frame size, and so gets the offset of the return address
2623 wrong. This should not be an issue as in later passes GCC has
2624 realised that the frame pointer needs to be spilled, and has
2625 increased the frame size. However, the rtl for the
2626 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2627 offset, and the wrong smaller offset is used. */
2630 arc_frame_pointer_needed (void)
2632 return (frame_pointer_needed
|| crtl
->calls_eh_return
);
2635 /* Tell prologue and epilogue if register REGNO should be saved /
2636 restored. The SPECIAL_P is true when the register may need special
2637 ld/st sequence. The return address, and stack pointer are treated
2638 separately. Don't consider them here. */
2641 arc_must_save_register (int regno
, struct function
*func
, bool special_p
)
2643 unsigned int fn_type
= arc_compute_function_type (func
);
2644 bool irq_auto_save_p
= ((irq_ctrl_saved
.irq_save_last_reg
>= regno
)
2645 && ARC_AUTO_IRQ_P (fn_type
));
2646 bool firq_auto_save_p
= ARC_FAST_INTERRUPT_P (fn_type
);
2648 switch (rgf_banked_register_count
)
2651 firq_auto_save_p
&= (regno
< 4);
2654 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 11) && (regno
< 16)));
2657 firq_auto_save_p
&= ((regno
< 4) || ((regno
> 9) && (regno
< 16))
2658 || ((regno
> 25) && (regno
< 29))
2659 || ((regno
> 29) && (regno
< 32)));
2662 firq_auto_save_p
&= (regno
!= 29) && (regno
< 32);
2665 firq_auto_save_p
= false;
2672 case RETURN_ADDR_REGNUM
:
2673 case STACK_POINTER_REGNUM
:
2674 /* The stack pointer and the return address are handled
2679 /* r30 is either used as ilink2 by ARCv1 or as a free register
2690 /* If those ones are used by the FPX machinery, we handle them
2692 if (TARGET_DPFP
&& !special_p
)
2717 /* The Extension Registers. */
2718 if (ARC_INTERRUPT_P (fn_type
)
2719 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2720 || df_regs_ever_live_p (regno
))
2721 /* Not all extension registers are available, choose the
2723 && !fixed_regs
[regno
])
2729 /* ARC600 specifies those ones as mlo/mhi registers, otherwise
2730 just handle them like any other extension register. */
2731 if (ARC_INTERRUPT_P (fn_type
)
2732 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2733 || df_regs_ever_live_p (regno
))
2734 /* Not all extension registers are available, choose the
2736 && ((!fixed_regs
[regno
] && !special_p
)
2737 || (TARGET_MUL64_SET
&& special_p
)))
2744 /* Fixed/control register, nothing to do. LP_COUNT is
2748 case HARD_FRAME_POINTER_REGNUM
:
2749 /* If we need FP reg as a frame pointer then don't save it as a
2751 if (arc_frame_pointer_needed ())
2759 if (((df_regs_ever_live_p (regno
) && !call_used_or_fixed_reg_p (regno
))
2760 /* In an interrupt save everything. */
2761 || (ARC_INTERRUPT_P (fn_type
)
2762 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2763 || df_regs_ever_live_p (regno
))))
2764 /* Do not emit code for auto saved regs. */
2766 && !firq_auto_save_p
)
2771 /* Return true if the return address must be saved in the current function,
2772 otherwise return false. */
2775 arc_must_save_return_addr (struct function
*func
)
2777 if (func
->machine
->frame_info
.save_return_addr
)
2783 /* Return non-zero if there are registers to be saved or loaded using
2784 millicode thunks. We can only use consecutive sequences starting
2785 with r13, and not going beyond r25.
2786 GMASK is a bitmask of registers to save. This function sets
2787 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2788 of registers to be saved / restored with a millicode call. */
2791 arc_compute_millicode_save_restore_regs (uint64_t gmask
,
2792 struct arc_frame_info
*frame
)
2796 int start_reg
= 13, end_reg
= 25;
2798 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
2800 end_reg
= regno
- 1;
2801 /* There is no point in using millicode thunks if we don't save/restore
2802 at least three registers. For non-leaf functions we also have the
2804 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2806 frame
->millicode_start_reg
= 13;
2807 frame
->millicode_end_reg
= regno
- 1;
2813 /* Return the bytes needed to compute the frame pointer from the
2814 current stack pointer. */
2817 arc_compute_frame_size (void)
2820 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2821 unsigned int reg_size
;
2823 struct arc_frame_info
*frame_info
;
2825 unsigned int extra_plus_reg_size
;
2826 unsigned int extra_plus_reg_size_aligned
;
2827 unsigned int fn_type
= arc_compute_function_type (cfun
);
2829 /* The answer might already be known. */
2830 if (cfun
->machine
->frame_info
.initialized
)
2831 return cfun
->machine
->frame_info
.total_size
;
2833 frame_info
= &cfun
->machine
->frame_info
;
2834 size
= ARC_STACK_ALIGN (get_frame_size ());
2836 /* 1) Size of locals and temporaries. */
2839 /* 2) Size of outgoing arguments. */
2840 args_size
= crtl
->outgoing_args_size
;
2842 /* 3) Calculate space needed for saved registers.
2843 ??? We ignore the extension registers for now. */
2845 /* See if this is an interrupt handler. Call used registers must be saved
2851 /* The last 4 regs are special, avoid them. */
2852 for (regno
= 0; regno
<= (GMASK_LEN
- 4); regno
++)
2854 if (arc_must_save_register (regno
, cfun
, false))
2856 reg_size
+= UNITS_PER_WORD
;
2857 gmask
|= 1ULL << regno
;
2861 /* In a frame that calls __builtin_eh_return two data registers are
2862 used to pass values back to the exception handler.
2864 Ensure that these registers are spilled to the stack so that the
2865 exception throw code can find them, and update the saved values.
2866 The handling code will then consume these reloaded values to
2867 handle the exception. */
2868 if (crtl
->calls_eh_return
)
2869 for (regno
= 0; EH_RETURN_DATA_REGNO (regno
) != INVALID_REGNUM
; regno
++)
2871 reg_size
+= UNITS_PER_WORD
;
2872 gmask
|= 1ULL << regno
;
2875 /* Check if we need to save the return address. */
2876 frame_info
->save_return_addr
= (!crtl
->is_leaf
2877 || df_regs_ever_live_p (RETURN_ADDR_REGNUM
)
2878 || crtl
->calls_eh_return
);
2880 /* Saving blink reg for millicode thunk calls. */
2881 if (TARGET_MILLICODE_THUNK_SET
2882 && !ARC_INTERRUPT_P (fn_type
)
2883 && !crtl
->calls_eh_return
)
2885 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2886 frame_info
->save_return_addr
= true;
2889 /* Save lp_count, lp_start and lp_end. */
2890 if (arc_lpcwidth
!= 0 && arc_must_save_register (LP_COUNT
, cfun
, true))
2891 reg_size
+= UNITS_PER_WORD
* 3;
2893 /* Check for the special R40-R44 regs used by FPX extension. */
2894 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R41_REG
: R40_REG
,
2896 reg_size
+= UNITS_PER_WORD
* 2;
2897 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R43_REG
: R42_REG
,
2899 reg_size
+= UNITS_PER_WORD
* 2;
2901 /* Check for special MLO/MHI case used by ARC600' MUL64
2903 if (arc_must_save_register (R58_REG
, cfun
, TARGET_MUL64_SET
))
2904 reg_size
+= UNITS_PER_WORD
* 2;
2906 /* 4) Calculate extra size made up of the blink + fp size. */
2908 if (arc_must_save_return_addr (cfun
))
2910 /* Add FP size only when it is not autosaved. */
2911 if (arc_frame_pointer_needed ()
2912 && !ARC_AUTOFP_IRQ_P (fn_type
))
2915 /* 5) Space for variable arguments passed in registers */
2916 pretend_size
= crtl
->args
.pretend_args_size
;
2918 /* Ensure everything before the locals is aligned appropriately. */
2919 extra_plus_reg_size
= extra_size
+ reg_size
;
2920 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN (extra_plus_reg_size
);
2921 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2923 /* Compute total frame size. */
2924 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2926 /* It used to be the case that the alignment was forced at this
2927 point. However, that is dangerous, calculations based on
2928 total_size would be wrong. Given that this has never cropped up
2929 as an issue I've changed this to an assert for now. */
2930 gcc_assert (total_size
== ARC_STACK_ALIGN (total_size
));
2932 /* Save computed information. */
2933 frame_info
->total_size
= total_size
;
2934 frame_info
->extra_size
= extra_size
;
2935 frame_info
->pretend_size
= pretend_size
;
2936 frame_info
->var_size
= var_size
;
2937 frame_info
->args_size
= args_size
;
2938 frame_info
->reg_size
= reg_size
;
2939 frame_info
->gmask
= gmask
;
2940 frame_info
->initialized
= reload_completed
;
2942 /* Ok, we're done. */
2946 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2950 arc_dwarf_emit_irq_save_regs (void)
2952 rtx tmp
, par
, insn
, reg
;
2955 par
= gen_rtx_SEQUENCE (VOIDmode
,
2956 rtvec_alloc (irq_ctrl_saved
.irq_save_last_reg
+ 1
2957 + irq_ctrl_saved
.irq_save_blink
2958 + irq_ctrl_saved
.irq_save_lpcount
2961 /* Build the stack adjustment note for unwind info. */
2963 offset
= UNITS_PER_WORD
* (irq_ctrl_saved
.irq_save_last_reg
+ 1
2964 + irq_ctrl_saved
.irq_save_blink
2965 + irq_ctrl_saved
.irq_save_lpcount
);
2966 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, -1 * offset
);
2967 tmp
= gen_rtx_SET (stack_pointer_rtx
, tmp
);
2968 RTX_FRAME_RELATED_P (tmp
) = 1;
2969 XVECEXP (par
, 0, j
++) = tmp
;
2971 offset
-= UNITS_PER_WORD
;
2973 /* 1st goes LP_COUNT. */
2974 if (irq_ctrl_saved
.irq_save_lpcount
)
2976 reg
= gen_rtx_REG (SImode
, 60);
2977 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2978 tmp
= gen_frame_mem (SImode
, tmp
);
2979 tmp
= gen_rtx_SET (tmp
, reg
);
2980 RTX_FRAME_RELATED_P (tmp
) = 1;
2981 XVECEXP (par
, 0, j
++) = tmp
;
2982 offset
-= UNITS_PER_WORD
;
2985 /* 2nd goes BLINK. */
2986 if (irq_ctrl_saved
.irq_save_blink
)
2988 reg
= gen_rtx_REG (SImode
, 31);
2989 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
2990 tmp
= gen_frame_mem (SImode
, tmp
);
2991 tmp
= gen_rtx_SET (tmp
, reg
);
2992 RTX_FRAME_RELATED_P (tmp
) = 1;
2993 XVECEXP (par
, 0, j
++) = tmp
;
2994 offset
-= UNITS_PER_WORD
;
2997 /* Build the parallel of the remaining registers recorded as saved
2999 for (i
= irq_ctrl_saved
.irq_save_last_reg
; i
>= 0; i
--)
3001 reg
= gen_rtx_REG (SImode
, i
);
3002 tmp
= plus_constant (Pmode
, stack_pointer_rtx
, offset
);
3003 tmp
= gen_frame_mem (SImode
, tmp
);
3004 tmp
= gen_rtx_SET (tmp
, reg
);
3005 RTX_FRAME_RELATED_P (tmp
) = 1;
3006 XVECEXP (par
, 0, j
++) = tmp
;
3007 offset
-= UNITS_PER_WORD
;
3010 /* Dummy insn used to anchor the dwarf info. */
3011 insn
= emit_insn (gen_stack_irq_dwarf());
3012 add_reg_note (insn
, REG_FRAME_RELATED_EXPR
, par
);
3013 RTX_FRAME_RELATED_P (insn
) = 1;
3016 /* Helper for prologue: emit frame store with pre_modify or pre_dec to
3017 save register REG on stack. An initial offset OFFSET can be passed
3021 frame_save_reg (rtx reg
, HOST_WIDE_INT offset
)
3027 rtx tmp
= plus_constant (Pmode
, stack_pointer_rtx
,
3028 offset
- GET_MODE_SIZE (GET_MODE (reg
)));
3029 addr
= gen_frame_mem (GET_MODE (reg
),
3030 gen_rtx_PRE_MODIFY (Pmode
,
3035 addr
= gen_frame_mem (GET_MODE (reg
), gen_rtx_PRE_DEC (Pmode
,
3036 stack_pointer_rtx
));
3037 frame_move_inc (addr
, reg
, stack_pointer_rtx
, 0);
3039 return GET_MODE_SIZE (GET_MODE (reg
)) - offset
;
3042 /* Helper used when saving AUX regs during ISR. */
3047 rtx stkslot
= gen_rtx_MEM (GET_MODE (reg
), gen_rtx_PRE_DEC (Pmode
,
3048 stack_pointer_rtx
));
3049 rtx insn
= emit_move_insn (stkslot
, reg
);
3050 RTX_FRAME_RELATED_P (insn
) = 1;
3051 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3052 gen_rtx_SET (stack_pointer_rtx
,
3053 plus_constant (Pmode
, stack_pointer_rtx
,
3054 -GET_MODE_SIZE (GET_MODE (reg
)))));
3055 return GET_MODE_SIZE (GET_MODE (reg
));
3058 /* Helper for epilogue: emit frame load with post_modify or post_inc
3059 to restore register REG from stack. The initial offset is passed
3063 frame_restore_reg (rtx reg
, HOST_WIDE_INT offset
)
3069 rtx tmp
= plus_constant (Pmode
, stack_pointer_rtx
,
3070 offset
+ GET_MODE_SIZE (GET_MODE (reg
)));
3071 addr
= gen_frame_mem (GET_MODE (reg
),
3072 gen_rtx_POST_MODIFY (Pmode
,
3077 addr
= gen_frame_mem (GET_MODE (reg
), gen_rtx_POST_INC (Pmode
,
3078 stack_pointer_rtx
));
3079 insn
= frame_move_inc (reg
, addr
, stack_pointer_rtx
, 0);
3080 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3082 if (reg
== hard_frame_pointer_rtx
)
3083 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3084 plus_constant (Pmode
, stack_pointer_rtx
,
3085 GET_MODE_SIZE (GET_MODE (reg
)) + offset
));
3087 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3088 gen_rtx_SET (stack_pointer_rtx
,
3089 plus_constant (Pmode
, stack_pointer_rtx
,
3090 GET_MODE_SIZE (GET_MODE (reg
))
3093 return GET_MODE_SIZE (GET_MODE (reg
)) + offset
;
3096 /* Helper used when restoring AUX regs during ISR. */
3101 rtx stkslot
= gen_rtx_MEM (GET_MODE (reg
), gen_rtx_POST_INC (Pmode
,
3102 stack_pointer_rtx
));
3103 rtx insn
= emit_move_insn (reg
, stkslot
);
3104 RTX_FRAME_RELATED_P (insn
) = 1;
3105 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3106 gen_rtx_SET (stack_pointer_rtx
,
3107 plus_constant (Pmode
, stack_pointer_rtx
,
3108 GET_MODE_SIZE (GET_MODE (reg
)))));
3109 return GET_MODE_SIZE (GET_MODE (reg
));
3112 /* Check if we have a continous range to be save/restored with the
3113 help of enter/leave instructions. A vaild register range starts
3114 from $r13 and is up to (including) $r26. */
3117 arc_enter_leave_p (uint64_t gmask
)
3120 unsigned int rmask
= 0;
3125 for (regno
= ENTER_LEAVE_START_REG
;
3126 regno
<= ENTER_LEAVE_END_REG
&& (gmask
& (1ULL << regno
)); regno
++)
3127 rmask
|= 1ULL << regno
;
3135 /* ARC's prologue, save any needed call-saved regs (and call-used if
3136 this is an interrupt handler) for ARCompact ISA, using ST/STD
3140 arc_save_callee_saves (uint64_t gmask
,
3143 HOST_WIDE_INT offset
,
3147 int frame_allocated
= 0;
3150 /* The home-grown ABI says link register is saved first. */
3153 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3154 frame_allocated
+= frame_save_reg (reg
, offset
);
3158 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3160 for (i
= GMASK_LEN
; i
>= 0; i
--)
3162 machine_mode save_mode
= SImode
;
3165 && ((i
- 1) % 2 == 0)
3166 && ((gmask
& (1ULL << i
)) != 0)
3167 && ((gmask
& (1ULL << (i
- 1))) != 0))
3172 else if ((gmask
& (1ULL << i
)) == 0)
3175 reg
= gen_rtx_REG (save_mode
, i
);
3176 frame_allocated
+= frame_save_reg (reg
, offset
);
3180 /* Save frame pointer if needed. First save the FP on stack, if not
3181 autosaved. Unfortunately, I cannot add it to gmask and use the
3182 above loop to save fp because our ABI states fp goes aftert all
3183 registers are saved. */
3186 frame_allocated
+= frame_save_reg (hard_frame_pointer_rtx
, offset
);
3190 /* Emit mov fp,sp. */
3192 frame_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
3194 return frame_allocated
;
3197 /* ARC's epilogue, restore any required call-saved regs (and call-used
3198 if it is for an interrupt handler) using LD/LDD instructions. */
3201 arc_restore_callee_saves (uint64_t gmask
,
3204 HOST_WIDE_INT offset
,
3205 HOST_WIDE_INT allocated
)
3208 int frame_deallocated
= 0;
3209 HOST_WIDE_INT offs
= cfun
->machine
->frame_info
.reg_size
;
3210 unsigned int fn_type
= arc_compute_function_type (cfun
);
3211 bool early_blink_restore
;
3214 /* Emit mov fp,sp. */
3215 if (arc_frame_pointer_needed () && offset
)
3217 frame_move (stack_pointer_rtx
, hard_frame_pointer_rtx
);
3218 frame_deallocated
+= offset
;
3224 /* Any offset is taken care by previous if-statement. */
3225 gcc_assert (offset
== 0);
3226 frame_deallocated
+= frame_restore_reg (hard_frame_pointer_rtx
, 0);
3231 /* No $fp involved, we need to do an add to set the $sp to the
3232 location of the first register. */
3233 frame_stack_add (offset
);
3234 frame_deallocated
+= offset
;
3238 /* When we do not optimize for size or we aren't in an interrupt,
3239 restore first blink. */
3240 early_blink_restore
= restore_blink
&& !optimize_size
&& offs
3241 && !ARC_INTERRUPT_P (fn_type
);
3242 if (early_blink_restore
)
3244 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, offs
);
3245 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3246 rtx insn
= frame_move_inc (reg
, gen_frame_mem (Pmode
, addr
),
3247 stack_pointer_rtx
, NULL_RTX
);
3248 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3249 restore_blink
= false;
3252 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3254 for (i
= 0; i
<= GMASK_LEN
; i
++)
3256 machine_mode restore_mode
= SImode
;
3260 && ((gmask
& (1ULL << i
)) != 0)
3261 && ((gmask
& (1ULL << (i
+ 1))) != 0))
3262 restore_mode
= DImode
;
3263 else if ((gmask
& (1ULL << i
)) == 0)
3266 reg
= gen_rtx_REG (restore_mode
, i
);
3268 switch (restore_mode
)
3271 if ((GMASK_LEN
- __builtin_clzll (gmask
)) == (i
+ 1)
3272 && early_blink_restore
)
3276 if ((GMASK_LEN
- __builtin_clzll (gmask
)) == i
3277 && early_blink_restore
)
3283 frame_deallocated
+= frame_restore_reg (reg
, offs
);
3286 if (restore_mode
== DImode
)
3292 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3293 frame_deallocated
+= frame_restore_reg (reg
, allocated
3295 /* Consider as well the
3301 return frame_deallocated
;
3304 /* ARC prologue, save the registers using enter instruction. Leave
3305 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3309 arc_save_callee_enter (uint64_t gmask
,
3312 HOST_WIDE_INT offset
)
3314 int start_reg
= ENTER_LEAVE_START_REG
;
3315 int end_reg
= ENTER_LEAVE_END_REG
;
3316 int regno
, indx
, off
, nregs
;
3318 int frame_allocated
= 0;
3320 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3323 end_reg
= regno
- 1;
3324 nregs
= end_reg
- start_reg
+ 1;
3325 nregs
+= save_blink
? 1 : 0;
3326 nregs
+= save_fp
? 1 : 0;
3329 frame_stack_add (offset
);
3331 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ (save_fp
? 1 : 0)
3335 reg
= gen_rtx_SET (stack_pointer_rtx
,
3336 plus_constant (Pmode
,
3338 -nregs
* UNITS_PER_WORD
));
3339 RTX_FRAME_RELATED_P (reg
) = 1;
3340 XVECEXP (insn
, 0, indx
++) = reg
;
3341 off
= nregs
* UNITS_PER_WORD
;
3345 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3346 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3349 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3350 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3351 off
-= UNITS_PER_WORD
;
3355 for (regno
= start_reg
;
3357 regno
++, indx
++, off
-= UNITS_PER_WORD
)
3359 reg
= gen_rtx_REG (SImode
, regno
);
3360 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3363 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3364 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3365 gmask
= gmask
& ~(1ULL << regno
);
3370 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3373 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, hard_frame_pointer_rtx
);
3374 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3375 off
-= UNITS_PER_WORD
;
3377 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (hard_frame_pointer_rtx
,
3379 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3383 gcc_assert (off
== 0);
3384 insn
= frame_insn (insn
);
3386 add_reg_note (insn
, REG_INC
, stack_pointer_rtx
);
3388 frame_allocated
= nregs
* UNITS_PER_WORD
;
3390 /* offset is a negative number, make sure we add it. */
3391 return frame_allocated
- offset
;
3394 /* ARC epilogue, restore the registers using leave instruction. An
3395 initial offset is passed in OFFSET. Besides restoring an register
3396 range, leave can also restore $blink (RESTORE_BLINK), or $fp
3397 (RESTORE_FP), and can automatic return (RETURN_P). */
3400 arc_restore_callee_leave (uint64_t gmask
,
3404 HOST_WIDE_INT offset
)
3406 int start_reg
= ENTER_LEAVE_START_REG
;
3407 int end_reg
= ENTER_LEAVE_END_REG
;
3408 int regno
, indx
, off
, nregs
;
3410 int frame_allocated
= 0;
3412 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3415 end_reg
= regno
- 1;
3416 nregs
= end_reg
- start_reg
+ 1;
3417 nregs
+= restore_blink
? 1 : 0;
3418 nregs
+= restore_fp
? 1 : 0;
3420 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ 1
3421 + (return_p
? 1 : 0)));
3425 XVECEXP (insn
, 0, indx
++) = ret_rtx
;
3429 /* I cannot emit set (sp, fp) here as cselib expects a single sp
3430 set and not two. Thus, use the offset, and change sp adjust
3432 frame_allocated
+= offset
;
3435 if (offset
&& !restore_fp
)
3437 /* This add is only emmited when we do not restore fp with leave
3439 frame_stack_add (offset
);
3440 frame_allocated
+= offset
;
3444 reg
= gen_rtx_SET (stack_pointer_rtx
,
3445 plus_constant (Pmode
,
3447 offset
+ nregs
* UNITS_PER_WORD
));
3448 RTX_FRAME_RELATED_P (reg
) = 1;
3449 XVECEXP (insn
, 0, indx
++) = reg
;
3450 off
= nregs
* UNITS_PER_WORD
;
3454 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3455 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3458 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3459 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3460 off
-= UNITS_PER_WORD
;
3463 for (regno
= start_reg
;
3465 regno
++, indx
++, off
-= UNITS_PER_WORD
)
3467 reg
= gen_rtx_REG (SImode
, regno
);
3468 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3471 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3472 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3473 gmask
= gmask
& ~(1ULL << regno
);
3478 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
,
3481 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (hard_frame_pointer_rtx
, mem
);
3482 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
++)) = 1;
3483 off
-= UNITS_PER_WORD
;
3486 gcc_assert (off
== 0);
3489 insn
= emit_jump_insn (insn
);
3490 RTX_FRAME_RELATED_P (insn
) = 1;
3493 insn
= frame_insn (insn
);
3495 add_reg_note (insn
, REG_INC
, stack_pointer_rtx
);
3497 /* Dwarf related info. */
3500 add_reg_note (insn
, REG_CFA_RESTORE
, hard_frame_pointer_rtx
);
3501 add_reg_note (insn
, REG_CFA_DEF_CFA
,
3502 plus_constant (Pmode
, stack_pointer_rtx
,
3503 offset
+ nregs
* UNITS_PER_WORD
));
3507 add_reg_note (insn
, REG_CFA_ADJUST_CFA
,
3508 gen_rtx_SET (stack_pointer_rtx
,
3509 plus_constant (Pmode
, stack_pointer_rtx
,
3510 nregs
* UNITS_PER_WORD
)));
3513 add_reg_note (insn
, REG_CFA_RESTORE
,
3514 gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3515 for (regno
= start_reg
; regno
<= end_reg
; regno
++)
3516 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, regno
));
3518 frame_allocated
+= nregs
* UNITS_PER_WORD
;
3520 return frame_allocated
;
3523 /* Millicode thunks implementation:
3524 Generates calls to millicodes for registers starting from r13 to r25
3525 Present Limitations:
3526 - Only one range supported. The remaining regs will have the ordinary
3527 st and ld instructions for store and loads. Hence a gmask asking
3528 to store r13-14, r16-r25 will only generate calls to store and
3529 load r13 to r14 while store and load insns will be generated for
3530 r16 to r25 in the prologue and epilogue respectively.
3532 - Presently library only supports register ranges starting from r13.
3536 arc_save_callee_milli (uint64_t gmask
,
3539 HOST_WIDE_INT offset
,
3540 HOST_WIDE_INT reg_size
)
3544 int regno
, indx
, off
, nregs
;
3546 int frame_allocated
= 0;
3548 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3551 end_reg
= regno
- 1;
3552 nregs
= end_reg
- start_reg
+ 1;
3553 gcc_assert (end_reg
> 14);
3556 /* Allocate space on stack for the registers, and take into account
3557 also the initial offset. The registers will be saved using
3558 offsets. N.B. OFFSET is a negative number. */
3561 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3562 frame_allocated
+= frame_save_reg (reg
, offset
);
3566 if (reg_size
|| offset
)
3568 frame_stack_add (offset
- reg_size
);
3569 frame_allocated
+= nregs
* UNITS_PER_WORD
- offset
;
3573 /* Start generate millicode call. */
3574 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (nregs
+ 1));
3577 /* This is a call, we clobber blink. */
3578 XVECEXP (insn
, 0, nregs
) =
3579 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3581 for (regno
= start_reg
, indx
= 0, off
= 0;
3583 regno
++, indx
++, off
+= UNITS_PER_WORD
)
3585 reg
= gen_rtx_REG (SImode
, regno
);
3586 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3589 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (mem
, reg
);
3590 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3591 gmask
= gmask
& ~(1ULL << regno
);
3593 insn
= frame_insn (insn
);
3595 /* Add DWARF info. */
3596 for (regno
= start_reg
, off
= 0;
3598 regno
++, off
+= UNITS_PER_WORD
)
3600 reg
= gen_rtx_REG (SImode
, regno
);
3601 mem
= gen_rtx_MEM (SImode
, plus_constant (Pmode
,
3602 stack_pointer_rtx
, off
));
3603 add_reg_note (insn
, REG_CFA_OFFSET
, gen_rtx_SET (mem
, reg
));
3607 /* In the case of millicode thunk, we need to restore the
3608 clobbered blink register. */
3609 if (arc_must_save_return_addr (cfun
))
3611 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
),
3613 plus_constant (Pmode
,
3618 /* Save remaining registers using st instructions. */
3619 for (regno
= 0; regno
<= GMASK_LEN
; regno
++)
3621 if ((gmask
& (1ULL << regno
)) == 0)
3624 reg
= gen_rtx_REG (SImode
, regno
);
3625 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3628 frame_move_inc (mem
, reg
, stack_pointer_rtx
, 0);
3629 frame_allocated
+= UNITS_PER_WORD
;
3630 off
+= UNITS_PER_WORD
;
3633 /* Save frame pointer if needed. First save the FP on stack, if not
3634 autosaved. Unfortunately, I cannot add it to gmask and use the
3635 above loop to save fp because our ABI states fp goes aftert all
3636 registers are saved. */
3638 frame_allocated
+= frame_save_reg (hard_frame_pointer_rtx
, offset
);
3640 /* Emit mov fp,sp. */
3641 if (arc_frame_pointer_needed ())
3642 frame_move (hard_frame_pointer_rtx
, stack_pointer_rtx
);
3644 return frame_allocated
;
3647 /* Like the previous function but restore. */
3650 arc_restore_callee_milli (uint64_t gmask
,
3654 HOST_WIDE_INT offset
)
3658 int regno
, indx
, off
, nregs
;
3660 int frame_allocated
= 0;
3662 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1ULL << regno
));)
3665 end_reg
= regno
- 1;
3666 nregs
= end_reg
- start_reg
+ 1;
3667 gcc_assert (end_reg
> 14);
3669 /* Emit mov fp,sp. */
3670 if (arc_frame_pointer_needed () && offset
)
3672 frame_move (stack_pointer_rtx
, hard_frame_pointer_rtx
);
3673 frame_allocated
= offset
;
3678 frame_allocated
+= frame_restore_reg (hard_frame_pointer_rtx
, 0);
3682 /* No fp involved, hence, we need to adjust the sp via an
3684 frame_stack_add (offset
);
3685 frame_allocated
+= offset
;
3689 /* Start generate millicode call. */
3690 insn
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc ((return_p
? 1 : 0)
3696 /* sibling call, the blink is restored with the help of the
3697 value held into r12. */
3698 reg
= gen_rtx_REG (Pmode
, 12);
3699 XVECEXP (insn
, 0, indx
++) = ret_rtx
;
3700 XVECEXP (insn
, 0, indx
++) =
3701 gen_rtx_SET (stack_pointer_rtx
,
3702 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, reg
));
3703 frame_allocated
+= UNITS_PER_WORD
;
3707 /* This is a call, we clobber blink. */
3708 XVECEXP (insn
, 0, nregs
) =
3709 gen_rtx_CLOBBER (VOIDmode
, gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
));
3712 for (regno
= start_reg
, off
= 0;
3714 regno
++, indx
++, off
+= UNITS_PER_WORD
)
3716 reg
= gen_rtx_REG (SImode
, regno
);
3717 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3720 XVECEXP (insn
, 0, indx
) = gen_rtx_SET (reg
, mem
);
3721 RTX_FRAME_RELATED_P (XVECEXP (insn
, 0, indx
)) = 1;
3722 gmask
= gmask
& ~(1ULL << regno
);
3725 /* Restore remaining registers using LD instructions. */
3726 for (regno
= 0; regno
<= GMASK_LEN
; regno
++)
3728 if ((gmask
& (1ULL << regno
)) == 0)
3731 reg
= gen_rtx_REG (SImode
, regno
);
3732 mem
= gen_frame_mem (SImode
, plus_constant (Pmode
,
3735 rtx tmp
= frame_move_inc (reg
, mem
, stack_pointer_rtx
, 0);
3736 add_reg_note (tmp
, REG_CFA_RESTORE
, reg
);
3737 off
+= UNITS_PER_WORD
;
3740 /* Emit millicode call. */
3743 reg
= gen_rtx_REG (Pmode
, 12);
3744 frame_insn (gen_rtx_SET (reg
, GEN_INT (off
)));
3745 frame_allocated
+= off
;
3746 insn
= emit_jump_insn (insn
);
3747 RTX_FRAME_RELATED_P (insn
) = 1;
3750 insn
= frame_insn (insn
);
3752 /* Add DWARF info. */
3753 for (regno
= start_reg
; regno
<= end_reg
; regno
++)
3755 reg
= gen_rtx_REG (SImode
, regno
);
3756 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3760 if (restore_blink
&& !return_p
)
3762 reg
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
3763 mem
= gen_frame_mem (Pmode
, plus_constant (Pmode
, stack_pointer_rtx
,
3765 insn
= frame_insn (gen_rtx_SET (reg
, mem
));
3766 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
3769 return frame_allocated
;
3772 /* Set up the stack and frame pointer (if desired) for the function. */
3775 arc_expand_prologue (void)
3778 uint64_t gmask
= cfun
->machine
->frame_info
.gmask
;
3779 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
3780 unsigned int frame_size_to_allocate
;
3781 int first_offset
= 0;
3782 unsigned int fn_type
= arc_compute_function_type (cfun
);
3783 bool save_blink
= false;
3784 bool save_fp
= false;
3785 bool emit_move
= false;
3787 /* Naked functions don't have prologue. */
3788 if (ARC_NAKED_P (fn_type
))
3790 if (flag_stack_usage_info
)
3791 current_function_static_stack_size
= 0;
3795 /* Compute total frame size. */
3796 size
= arc_compute_frame_size ();
3798 if (flag_stack_usage_info
)
3799 current_function_static_stack_size
= size
;
3801 /* Keep track of frame size to be allocated. */
3802 frame_size_to_allocate
= size
;
3804 /* These cases shouldn't happen. Catch them now. */
3805 gcc_assert (!(size
== 0 && gmask
));
3807 /* Allocate space for register arguments if this is a variadic function. */
3808 if (frame
->pretend_size
!= 0)
3809 first_offset
= -frame
->pretend_size
;
3811 /* IRQ using automatic save mechanism will save the register before
3813 if (ARC_AUTO_IRQ_P (fn_type
)
3814 && !ARC_FAST_INTERRUPT_P (fn_type
))
3816 frame_stack_add (first_offset
);
3818 arc_dwarf_emit_irq_save_regs ();
3821 save_blink
= arc_must_save_return_addr (cfun
)
3822 && !ARC_AUTOBLINK_IRQ_P (fn_type
);
3823 save_fp
= arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type
)
3824 && !ARC_INTERRUPT_P (fn_type
);
3825 emit_move
= arc_frame_pointer_needed () && !ARC_INTERRUPT_P (fn_type
);
3827 /* Use enter/leave only for non-interrupt functions. */
3828 if (TARGET_CODE_DENSITY
3829 && TARGET_CODE_DENSITY_FRAME
3830 && !ARC_AUTOFP_IRQ_P (fn_type
)
3831 && !ARC_AUTOBLINK_IRQ_P (fn_type
)
3832 && !ARC_INTERRUPT_P (fn_type
)
3833 && arc_enter_leave_p (gmask
))
3834 frame_size_to_allocate
-= arc_save_callee_enter (gmask
, save_blink
,
3837 else if (frame
->millicode_end_reg
> 14)
3838 frame_size_to_allocate
-= arc_save_callee_milli (gmask
, save_blink
,
3843 frame_size_to_allocate
-= arc_save_callee_saves (gmask
, save_blink
, save_fp
,
3844 first_offset
, emit_move
);
3846 /* Check if we need to save the ZOL machinery. */
3847 if (arc_lpcwidth
!= 0 && arc_must_save_register (LP_COUNT
, cfun
, true))
3849 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3850 emit_insn (gen_rtx_SET (reg0
,
3851 gen_rtx_UNSPEC_VOLATILE
3852 (Pmode
, gen_rtvec (1, GEN_INT (AUX_LP_START
)),
3854 frame_size_to_allocate
-= push_reg (reg0
);
3855 emit_insn (gen_rtx_SET (reg0
,
3856 gen_rtx_UNSPEC_VOLATILE
3857 (Pmode
, gen_rtvec (1, GEN_INT (AUX_LP_END
)),
3859 frame_size_to_allocate
-= push_reg (reg0
);
3860 emit_move_insn (reg0
, gen_rtx_REG (SImode
, LP_COUNT
));
3861 frame_size_to_allocate
-= push_reg (reg0
);
3864 /* Save AUX regs used by FPX machinery. */
3865 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R41_REG
: R40_REG
,
3868 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3871 for (i
= 0; i
< 4; i
++)
3873 emit_insn (gen_rtx_SET (reg0
,
3874 gen_rtx_UNSPEC_VOLATILE
3875 (Pmode
, gen_rtvec (1, GEN_INT (AUX_DPFP_START
3878 frame_size_to_allocate
-= push_reg (reg0
);
3882 /* Save ARC600' MUL64 registers. */
3883 if (arc_must_save_register (R58_REG
, cfun
, true))
3884 frame_size_to_allocate
-= arc_save_callee_saves (3ULL << 58,
3885 false, false, 0, false);
3887 if (arc_frame_pointer_needed () && ARC_INTERRUPT_P (fn_type
))
3889 /* Just save fp at the end of the saving context. */
3890 frame_size_to_allocate
-=
3891 arc_save_callee_saves (0, false, !ARC_AUTOFP_IRQ_P (fn_type
), 0, true);
3894 /* Allocate the stack frame. */
3895 if (frame_size_to_allocate
> 0)
3896 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
3898 /* Emit a blockage to avoid delay slot scheduling. */
3899 emit_insn (gen_blockage ());
3902 /* Return the register number of the register holding the return address
3903 for a function of type TYPE. */
3906 arc_return_address_register (unsigned int fn_type
)
3910 if (ARC_INTERRUPT_P (fn_type
))
3912 if ((fn_type
& (ARC_FUNCTION_ILINK1
| ARC_FUNCTION_FIRQ
)) != 0)
3914 else if ((fn_type
& ARC_FUNCTION_ILINK2
) != 0)
3919 else if (ARC_NORMAL_P (fn_type
) || ARC_NAKED_P (fn_type
))
3920 regno
= RETURN_ADDR_REGNUM
;
3922 gcc_assert (regno
!= 0);
3926 /* Do any necessary cleanup after a function to restore stack, frame,
3930 arc_expand_epilogue (int sibcall_p
)
3933 unsigned int fn_type
= arc_compute_function_type (cfun
);
3934 unsigned int size_to_deallocate
;
3936 int can_trust_sp_p
= !cfun
->calls_alloca
;
3938 bool restore_fp
= arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type
);
3939 bool restore_blink
= arc_must_save_return_addr (cfun
)
3940 && !ARC_AUTOBLINK_IRQ_P (fn_type
);
3941 uint64_t gmask
= cfun
->machine
->frame_info
.gmask
;
3942 bool return_p
= !sibcall_p
&& fn_type
== ARC_FUNCTION_NORMAL
3943 && !cfun
->machine
->frame_info
.pretend_size
;
3944 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
3946 /* Naked functions don't have epilogue. */
3947 if (ARC_NAKED_P (fn_type
))
3950 size
= arc_compute_frame_size ();
3951 size_to_deallocate
= size
;
3953 first_offset
= size
- (frame
->pretend_size
+ frame
->reg_size
3954 + frame
->extra_size
);
3956 if (!can_trust_sp_p
)
3957 gcc_assert (arc_frame_pointer_needed ());
3959 /* Emit a blockage to avoid/flush all pending sp operations. */
3961 emit_insn (gen_blockage ());
3963 if (ARC_INTERRUPT_P (fn_type
) && restore_fp
)
3965 /* We need to restore FP before any SP operation in an
3967 size_to_deallocate
-= arc_restore_callee_saves (0, false,
3970 size_to_deallocate
);
3975 /* Restore ARC600' MUL64 registers. */
3976 if (arc_must_save_register (R58_REG
, cfun
, true))
3979 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
3980 rtx reg1
= gen_rtx_REG (SImode
, R1_REG
);
3981 size_to_deallocate
-= pop_reg (reg0
);
3982 size_to_deallocate
-= pop_reg (reg1
);
3984 insn
= emit_insn (gen_mulu64 (reg0
, const1_rtx
));
3985 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, R58_REG
));
3986 RTX_FRAME_RELATED_P (insn
) = 1;
3987 emit_insn (gen_arc600_stall ());
3988 insn
= emit_insn (gen_rtx_UNSPEC_VOLATILE
3989 (VOIDmode
, gen_rtvec (2, reg1
, GEN_INT (AUX_MULHI
)),
3991 add_reg_note (insn
, REG_CFA_RESTORE
, gen_rtx_REG (SImode
, R59_REG
));
3992 RTX_FRAME_RELATED_P (insn
) = 1;
3995 /* Restore AUX-regs used by FPX machinery. */
3996 if (arc_must_save_register (TARGET_BIG_ENDIAN
? R41_REG
: R40_REG
,
3999 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
4002 for (i
= 0; i
< 4; i
++)
4004 size_to_deallocate
-= pop_reg (reg0
);
4005 emit_insn (gen_rtx_UNSPEC_VOLATILE
4006 (VOIDmode
, gen_rtvec (2, reg0
, GEN_INT (AUX_DPFP_START
4012 /* Check if we need to restore the ZOL machinery. */
4013 if (arc_lpcwidth
!=0 && arc_must_save_register (LP_COUNT
, cfun
, true))
4015 rtx reg0
= gen_rtx_REG (SImode
, R0_REG
);
4017 size_to_deallocate
-= pop_reg (reg0
);
4018 emit_move_insn (gen_rtx_REG (SImode
, LP_COUNT
), reg0
);
4020 size_to_deallocate
-= pop_reg (reg0
);
4021 emit_insn (gen_rtx_UNSPEC_VOLATILE
4022 (VOIDmode
, gen_rtvec (2, reg0
, GEN_INT (AUX_LP_END
)),
4025 size_to_deallocate
-= pop_reg (reg0
);
4026 emit_insn (gen_rtx_UNSPEC_VOLATILE
4027 (VOIDmode
, gen_rtvec (2, reg0
, GEN_INT (AUX_LP_START
)),
4031 if (TARGET_CODE_DENSITY
4032 && TARGET_CODE_DENSITY_FRAME
4033 && !ARC_AUTOFP_IRQ_P (fn_type
)
4034 && !ARC_AUTOBLINK_IRQ_P (fn_type
)
4035 && !ARC_INTERRUPT_P (fn_type
)
4036 && arc_enter_leave_p (gmask
))
4038 /* Using leave instruction. */
4039 size_to_deallocate
-= arc_restore_callee_leave (gmask
, restore_blink
,
4045 gcc_assert (size_to_deallocate
== 0);
4049 else if (frame
->millicode_end_reg
> 14)
4051 /* Using millicode calls. */
4052 size_to_deallocate
-= arc_restore_callee_milli (gmask
, restore_blink
,
4058 gcc_assert (size_to_deallocate
== 0);
4063 size_to_deallocate
-= arc_restore_callee_saves (gmask
, restore_blink
,
4066 size_to_deallocate
);
4068 /* Keep track of how much of the stack pointer we've restored. It
4069 makes the following a lot more readable. */
4070 restored
= size
- size_to_deallocate
;
4072 if (size
> restored
)
4073 frame_stack_add (size
- restored
);
4075 /* For frames that use __builtin_eh_return, the register defined by
4076 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
4077 On eh_return paths however, the register is set to the value that
4078 should be added to the stack pointer in order to restore the
4079 correct stack pointer for the exception handling frame.
4081 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
4082 this onto the stack for eh_return frames. */
4083 if (crtl
->calls_eh_return
)
4084 emit_insn (gen_add2_insn (stack_pointer_rtx
,
4085 EH_RETURN_STACKADJ_RTX
));
4087 /* Emit the return instruction. */
4088 if (ARC_INTERRUPT_P (fn_type
))
4090 rtx ra
= gen_rtx_REG (Pmode
, arc_return_address_register (fn_type
));
4093 emit_jump_insn (gen_rtie ());
4094 else if (TARGET_ARC700
)
4095 emit_jump_insn (gen_rtie ());
4097 emit_jump_insn (gen_arc600_rtie (ra
));
4099 else if (sibcall_p
== FALSE
)
4100 emit_jump_insn (gen_simple_return ());
4103 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable
4104 construct to match either enter or leave instruction. Which one
4105 which is selected by PUSH_P argument. */
4108 arc_check_multi (rtx op
, bool push_p
)
4110 HOST_WIDE_INT len
= XVECLEN (op
, 0);
4111 unsigned int regno
, i
, start
;
4112 unsigned int memp
= push_p
? 0 : 1;
4119 elt
= XVECEXP (op
, 0, 0);
4120 if (!push_p
&& GET_CODE (elt
) == RETURN
)
4123 for (i
= start
, regno
= ENTER_LEAVE_START_REG
; i
< len
; i
++, regno
++)
4125 rtx elt
= XVECEXP (op
, 0, i
);
4128 if (GET_CODE (elt
) != SET
)
4130 mem
= XEXP (elt
, memp
);
4131 reg
= XEXP (elt
, 1 - memp
);
4137 /* Check for blink. */
4138 if (REGNO (reg
) == RETURN_ADDR_REGNUM
4141 else if (REGNO (reg
) == HARD_FRAME_POINTER_REGNUM
)
4143 else if (REGNO (reg
) != regno
)
4146 addr
= XEXP (mem
, 0);
4147 if (GET_CODE (addr
) == PLUS
)
4149 if (!rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
4150 || !CONST_INT_P (XEXP (addr
, 1)))
4155 if (!rtx_equal_p (stack_pointer_rtx
, addr
))
4162 /* Return rtx for the location of the return address on the stack,
4163 suitable for use in __builtin_eh_return. The new return address
4164 will be written to this location in order to redirect the return to
4165 the exception handler. Our ABI says the blink is pushed first on
4166 stack followed by an unknown number of register saves, and finally
4167 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the
4168 stack is not finalized. */
4171 arc_eh_return_address_location (rtx source
)
4175 struct arc_frame_info
*afi
;
4177 arc_compute_frame_size ();
4178 afi
= &cfun
->machine
->frame_info
;
4180 gcc_assert (crtl
->calls_eh_return
);
4181 gcc_assert (afi
->save_return_addr
);
4182 gcc_assert (afi
->extra_size
>= 4);
4184 /* The '-4' removes the size of the return address, which is
4185 included in the 'extra_size' field. */
4186 offset
= afi
->reg_size
+ afi
->extra_size
- 4;
4187 mem
= gen_frame_mem (Pmode
,
4188 plus_constant (Pmode
, hard_frame_pointer_rtx
, offset
));
4190 /* The following should not be needed, and is, really a hack. The
4191 issue being worked around here is that the DSE (Dead Store
4192 Elimination) pass will remove this write to the stack as it sees
4193 a single store and no corresponding read. The read however
4194 occurs in the epilogue code, which is not added into the function
4195 rtl until a later pass. So, at the time of DSE, the decision to
4196 remove this store seems perfectly sensible. Marking the memory
4197 address as volatile obviously has the effect of preventing DSE
4198 from removing the store. */
4199 MEM_VOLATILE_P (mem
) = true;
4200 emit_move_insn (mem
, source
);
4205 /* Helper to generate unspec constant. */
4208 arc_unspec_offset (rtx loc
, int unspec
)
4210 return gen_rtx_CONST (Pmode
, gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, loc
),
4214 /* !TARGET_BARREL_SHIFTER support. */
4215 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
4219 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
4221 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
4223 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
4224 (op0
, op1
, op2
, shift
));
4228 /* Output the assembler code for doing a shift.
4229 We go to a bit of trouble to generate efficient code as the ARC601 only has
4230 single bit shifts. This is taken from the h8300 port. We only have one
4231 mode of shifting and can't access individual bytes like the h8300 can, so
4232 this is greatly simplified (at the expense of not generating hyper-
4235 This function is not used if the variable shift insns are present. */
4237 /* FIXME: This probably can be done using a define_split in arc.md.
4238 Alternately, generate rtx rather than output instructions. */
4241 output_shift (rtx
*operands
)
4243 /* static int loopend_lab;*/
4244 rtx shift
= operands
[3];
4245 machine_mode mode
= GET_MODE (shift
);
4246 enum rtx_code code
= GET_CODE (shift
);
4247 const char *shift_one
;
4249 gcc_assert (mode
== SImode
);
4253 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
4254 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
4255 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
4256 default: gcc_unreachable ();
4259 if (GET_CODE (operands
[2]) != CONST_INT
)
4261 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
4268 n
= INTVAL (operands
[2]);
4270 /* Only consider the lower 5 bits of the shift count. */
4273 /* First see if we can do them inline. */
4274 /* ??? We could get better scheduling & shorter code (using short insns)
4275 by using splitters. Alas, that'd be even more verbose. */
4276 if (code
== ASHIFT
&& n
<= 9 && n
> 2
4277 && dest_reg_operand (operands
[4], SImode
))
4279 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
4280 for (n
-=3 ; n
>= 3; n
-= 3)
4281 output_asm_insn ("add3 %0,%4,%0", operands
);
4283 output_asm_insn ("add2 %0,%4,%0", operands
);
4285 output_asm_insn ("add %0,%0,%0", operands
);
4291 output_asm_insn (shift_one
, operands
);
4292 operands
[1] = operands
[0];
4295 /* See if we can use a rotate/and. */
4296 else if (n
== BITS_PER_WORD
- 1)
4301 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
4304 /* The ARC doesn't have a rol insn. Use something else. */
4305 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
4308 /* The ARC doesn't have a rol insn. Use something else. */
4309 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
4315 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
4320 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
4323 #if 1 /* Need some scheduling comparisons. */
4324 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
4325 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
4327 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
4328 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
4333 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
4334 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
4336 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
4337 "and %0,%0,1\n\trlc %0,%0", operands
);
4344 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
4345 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
4350 operands
[2] = GEN_INT (n
);
4351 output_asm_insn ("mov.f lp_count, %2", operands
);
4355 output_asm_insn ("lpnz\t2f", operands
);
4356 output_asm_insn (shift_one
, operands
);
4357 output_asm_insn ("nop", operands
);
4358 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
4367 /* Nested function support. */
4369 /* Output assembler code for a block containing the constant parts of
4370 a trampoline, leaving space for variable parts. A trampoline looks
4376 .word function's address
4377 .word static chain value
4382 arc_asm_trampoline_template (FILE *f
)
4384 asm_fprintf (f
, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG
);
4385 asm_fprintf (f
, "\tld\t%s,[pcl,12]\n", reg_names
[STATIC_CHAIN_REGNUM
]);
4386 asm_fprintf (f
, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG
);
4387 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
4388 assemble_aligned_integer (UNITS_PER_WORD
, const0_rtx
);
4391 /* Emit RTL insns to initialize the variable parts of a trampoline.
4392 FNADDR is an RTX for the address of the function's pure code. CXT
4393 is an RTX for the static chain value for the function.
4395 The fastest trampoline to execute for trampolines within +-8KB of CTX
4399 j [limm] 0x20200f80 limm
4401 and that would also be faster to write to the stack by computing
4402 the offset from CTX to TRAMP at compile time. However, it would
4403 really be better to get rid of the high cost of cache invalidation
4404 when generating trampolines, which requires that the code part of
4405 trampolines stays constant, and additionally either making sure
4406 that no executable code but trampolines is on the stack, no icache
4407 entries linger for the area of the stack from when before the stack
4408 was allocated, and allocating trampolines in trampoline-only cache
4409 lines or allocate trampolines fram a special pool of pre-allocated
4413 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
4415 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
4417 emit_block_move (tramp
, assemble_trampoline_template (),
4418 GEN_INT (TRAMPOLINE_SIZE
), BLOCK_OP_NORMAL
);
4419 emit_move_insn (adjust_address (tramp
, SImode
, 8), fnaddr
);
4420 emit_move_insn (adjust_address (tramp
, SImode
, 12), cxt
);
4421 maybe_emit_call_builtin___clear_cache (XEXP (tramp
, 0),
4422 plus_constant (Pmode
,
4427 /* Add the given function declaration to emit code in JLI section. */
4430 arc_add_jli_section (rtx pat
)
4434 arc_jli_section
*sec
= arc_jli_sections
, *new_section
;
4435 tree decl
= SYMBOL_REF_DECL (pat
);
4442 /* For fixed locations do not generate the jli table entry. It
4443 should be provided by the user as an asm file. */
4444 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
4445 if (lookup_attribute ("jli_fixed", attrs
))
4449 name
= XSTR (pat
, 0);
4451 /* Don't insert the same symbol twice. */
4454 if(strcmp (name
, sec
->name
) == 0)
4459 /* New name, insert it. */
4460 new_section
= (arc_jli_section
*) xmalloc (sizeof (arc_jli_section
));
4461 gcc_assert (new_section
!= NULL
);
4462 new_section
->name
= name
;
4463 new_section
->next
= arc_jli_sections
;
4464 arc_jli_sections
= new_section
;
4467 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4468 reset when we output the scaled address. */
4469 static int output_scaled
= 0;
4471 /* Set when we force sdata output. */
4472 static int output_sdata
= 0;
4474 /* Print operand X (an rtx) in assembler syntax to file FILE.
4475 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4476 For `%' followed by punctuation, CODE is the punctuation and X is null. */
4477 /* In final.c:output_asm_insn:
4480 'c' : constant address if CONSTANT_ADDRESS_P
4486 'p': bit Position of lsb
4487 's': size of bit field
4488 '#': condbranch delay slot suffix
4489 '*': jump delay slot suffix
4490 '?' : nonjump-insn suffix for conditional execution or short instruction
4491 '!' : jump / call suffix for conditional execution or short instruction
4492 '`': fold constant inside unary o-perator, re-recognize, and emit.
4496 'S': JLI instruction
4497 'j': used by mov instruction to properly emit jli related labels.
4498 'B': Branch comparison operand - suppress sda reference
4499 'H': Most significant word
4500 'L': Least significant word
4501 'A': ASCII decimal representation of floating point value
4502 'U': Load/store update or scaling indicator
4503 'V': cache bypass indicator for volatile
4508 'o': original symbol - no @ prepending. */
4511 arc_print_operand (FILE *file
, rtx x
, int code
)
4516 if (GET_CODE (x
) == CONST_INT
)
4517 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
4519 output_operand_lossage ("invalid operand to %%Z code");
4524 if (GET_CODE (x
) == CONST_INT
)
4525 fprintf (file
, "%d",exact_log2 (INTVAL (x
) & 0xffffffff));
4527 output_operand_lossage ("invalid operand to %%z code");
4532 if (GET_CODE (x
) == CONST_INT
)
4533 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
) );
4535 output_operand_lossage ("invalid operands to %%c code");
4540 if (GET_CODE (x
) == CONST_INT
)
4541 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
4543 output_operand_lossage ("invalid operand to %%M code");
4548 if (GET_CODE (x
) == CONST_INT
)
4549 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
4551 output_operand_lossage ("invalid operand to %%p code");
4555 if (GET_CODE (x
) == CONST_INT
)
4557 HOST_WIDE_INT i
= INTVAL (x
);
4558 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
4559 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
4562 output_operand_lossage ("invalid operand to %%s code");
4566 /* Conditional branches depending on condition codes.
4567 Note that this is only for branches that were known to depend on
4568 condition codes before delay slot scheduling;
4569 out-of-range brcc / bbit expansions should use '*'.
4570 This distinction is important because of the different
4571 allowable delay slot insns and the output of the delay suffix
4572 for TARGET_AT_DBR_COND_EXEC. */
4574 /* Unconditional branches / branches not depending on condition codes.
4575 This could also be a CALL_INSN.
4576 Output the appropriate delay slot suffix. */
4577 if (final_sequence
&& final_sequence
->len () != 1)
4579 rtx_insn
*jump
= final_sequence
->insn (0);
4580 rtx_insn
*delay
= final_sequence
->insn (1);
4582 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
4583 if (delay
->deleted ())
4585 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
4586 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
4587 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
4588 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
4595 case '?' : /* with leading "." */
4596 case '!' : /* without leading "." */
4597 /* This insn can be conditionally executed. See if the ccfsm machinery
4598 says it should be conditionalized.
4599 If it shouldn't, we'll check the compact attribute if this insn
4600 has a short variant, which may be used depending on code size and
4601 alignment considerations. */
4602 if (current_insn_predicate
)
4603 arc_ccfsm_current
.cc
4604 = get_arc_condition_code (current_insn_predicate
);
4605 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
4607 /* Is this insn in a delay slot sequence? */
4608 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
4609 || current_insn_predicate
4610 || CALL_P (final_sequence
->insn (0))
4611 || simplejump_p (final_sequence
->insn (0)))
4613 /* This insn isn't in a delay slot sequence, or conditionalized
4614 independently of its position in a delay slot. */
4615 fprintf (file
, "%s%s",
4616 code
== '?' ? "." : "",
4617 arc_condition_codes
[arc_ccfsm_current
.cc
]);
4618 /* If this is a jump, there are still short variants. However,
4619 only beq_s / bne_s have the same offset range as b_s,
4620 and the only short conditional returns are jeq_s and jne_s. */
4622 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
4623 || arc_ccfsm_current
.cc
== ARC_CC_NE
4624 || 0 /* FIXME: check if branch in 7 bit range. */))
4625 output_short_suffix (file
);
4627 else if (code
== '!') /* Jump with delay slot. */
4628 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
4629 else /* An Instruction in a delay slot of a jump or call. */
4631 rtx jump
= XVECEXP (final_sequence
, 0, 0);
4632 rtx insn
= XVECEXP (final_sequence
, 0, 1);
4634 /* If the insn is annulled and is from the target path, we need
4635 to inverse the condition test. */
4636 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
4638 if (INSN_FROM_TARGET_P (insn
))
4639 fprintf (file
, "%s%s",
4640 code
== '?' ? "." : "",
4641 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
4643 fprintf (file
, "%s%s",
4644 code
== '?' ? "." : "",
4645 arc_condition_codes
[arc_ccfsm_current
.cc
]);
4646 if (arc_ccfsm_current
.state
== 5)
4647 arc_ccfsm_current
.state
= 0;
4650 /* This insn is executed for either path, so don't
4651 conditionalize it at all. */
4652 output_short_suffix (file
);
4657 output_short_suffix (file
);
4660 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
4663 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
4666 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
4667 (get_arc_condition_code (x
))],
4671 /* Write second word of DImode or DFmode reference,
4672 register or memory. */
4673 if (GET_CODE (x
) == REG
)
4674 fputs (reg_names
[REGNO (x
)+1], file
);
4675 else if (GET_CODE (x
) == MEM
)
4679 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4680 PRE_MODIFY, we will have handled the first word already;
4681 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4682 first word will be done later. In either case, the access
4683 to the first word will do the modify, and we only have
4684 to add an offset of four here. */
4685 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
4686 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
4687 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
4688 || GET_CODE (XEXP (x
, 0)) == POST_INC
4689 || GET_CODE (XEXP (x
, 0)) == POST_DEC
4690 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
4691 output_address (VOIDmode
,
4692 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
4693 else if (output_scaled
)
4695 rtx addr
= XEXP (x
, 0);
4696 int size
= GET_MODE_SIZE (GET_MODE (x
));
4698 output_address (VOIDmode
,
4699 plus_constant (Pmode
, XEXP (addr
, 0),
4700 ((INTVAL (XEXP (addr
, 1)) + 4)
4701 >> (size
== 2 ? 1 : 2))));
4705 output_address (VOIDmode
,
4706 plus_constant (Pmode
, XEXP (x
, 0), 4));
4710 output_operand_lossage ("invalid operand to %%R code");
4714 if (GET_CODE (x
) == SYMBOL_REF
4715 && arc_is_jli_call_p (x
))
4717 if (SYMBOL_REF_DECL (x
))
4719 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4720 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4722 if (lookup_attribute ("jli_fixed", attrs
))
4724 /* No special treatment for jli_fixed functions. */
4727 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"\t; @",
4728 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4729 assemble_name (file
, XSTR (x
, 0));
4733 fprintf (file
, "@__jli.");
4734 assemble_name (file
, XSTR (x
, 0));
4736 arc_add_jli_section (x
);
4739 if (GET_CODE (x
) == SYMBOL_REF
4740 && arc_is_secure_call_p (x
))
4742 /* No special treatment for secure functions. */
4745 tree attrs
= (TREE_TYPE (SYMBOL_REF_DECL (x
)) != error_mark_node
4746 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x
)))
4748 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
"\t; @",
4749 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs
))));
4750 assemble_name (file
, XSTR (x
, 0));
4754 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4757 output_addr_const (file
, x
);
4763 if (GET_CODE (x
) == REG
)
4765 /* L = least significant word, H = most significant word. */
4766 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
4767 fputs (reg_names
[REGNO (x
)], file
);
4769 fputs (reg_names
[REGNO (x
)+1], file
);
4771 else if (GET_CODE (x
) == CONST_INT
4772 || GET_CODE (x
) == CONST_DOUBLE
)
4774 rtx first
, second
, word
;
4776 split_double (x
, &first
, &second
);
4778 if((WORDS_BIG_ENDIAN
) == 0)
4779 word
= (code
== 'L' ? first
: second
);
4781 word
= (code
== 'L' ? second
: first
);
4783 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
4786 output_operand_lossage ("invalid operand to %%H/%%L code");
4792 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
4793 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
4795 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
4796 fprintf (file
, "%s", str
);
4800 /* Output a load/store with update indicator if appropriate. */
4801 if (GET_CODE (x
) == MEM
)
4803 rtx addr
= XEXP (x
, 0);
4804 switch (GET_CODE (addr
))
4806 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
4807 fputs (".a", file
); break;
4808 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
4809 fputs (".ab", file
); break;
4811 /* Are we using a scaled index? */
4812 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
4813 fputs (".as", file
);
4814 /* Can we use a scaled offset? */
4815 else if (CONST_INT_P (XEXP (addr
, 1))
4816 && GET_MODE_SIZE (GET_MODE (x
)) > 1
4817 && (!(INTVAL (XEXP (addr
, 1))
4818 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
4819 /* Does it make a difference? */
4820 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
4821 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
4823 fputs (".as", file
);
4829 if (legitimate_small_data_address_p (addr
, GET_MODE (x
))
4830 && GET_MODE_SIZE (GET_MODE (x
)) > 1)
4832 int align
= get_symbol_alignment (addr
);
4834 switch (GET_MODE (x
))
4843 if (align
&& ((align
& mask
) == 0))
4844 fputs (".as", file
);
4850 gcc_assert (CONSTANT_P (addr
)); break;
4854 output_operand_lossage ("invalid operand to %%U code");
4857 /* Output cache bypass indicator for a load/store insn. Volatile memory
4858 refs are defined to use the cache bypass mechanism. */
4859 if (GET_CODE (x
) == MEM
)
4861 if ((MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
4862 || arc_is_uncached_mem_p (x
))
4863 fputs (".di", file
);
4866 output_operand_lossage ("invalid operand to %%V code");
4871 /* Do nothing special. */
4874 fputs (reg_names
[REGNO (x
)]+1, file
);
4877 /* This punctuation character is needed because label references are
4878 printed in the output template using %l. This is a front end
4879 character, and when we want to emit a '@' before it, we have to use
4885 /* Output an operator. */
4886 switch (GET_CODE (x
))
4888 case PLUS
: fputs ("add", file
); return;
4889 case SS_PLUS
: fputs ("adds", file
); return;
4890 case AND
: fputs ("and", file
); return;
4891 case IOR
: fputs ("or", file
); return;
4892 case XOR
: fputs ("xor", file
); return;
4893 case MINUS
: fputs ("sub", file
); return;
4894 case SS_MINUS
: fputs ("subs", file
); return;
4895 case ASHIFT
: fputs ("asl", file
); return;
4896 case ASHIFTRT
: fputs ("asr", file
); return;
4897 case LSHIFTRT
: fputs ("lsr", file
); return;
4898 case ROTATERT
: fputs ("ror", file
); return;
4899 case MULT
: fputs ("mpy", file
); return;
4900 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
4901 case NEG
: fputs ("neg", file
); return;
4902 case SS_NEG
: fputs ("negs", file
); return;
4903 case NOT
: fputs ("not", file
); return; /* Unconditional. */
4905 fputs ("ext", file
); /* bmsk allows predication. */
4907 case SIGN_EXTEND
: /* Unconditional. */
4908 fputs ("sex", file
);
4910 switch (GET_MODE (XEXP (x
, 0)))
4912 case E_QImode
: fputs ("b", file
); return;
4913 case E_HImode
: fputs ("w", file
); return;
4918 if (GET_MODE (x
) != HImode
)
4920 fputs ("sat16", file
);
4923 output_operand_lossage ("invalid operand to %%O code"); return;
4925 if (GET_CODE (x
) == SYMBOL_REF
)
4927 assemble_name (file
, XSTR (x
, 0));
4932 if (TARGET_ANNOTATE_ALIGN
)
4933 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
4949 output_operand_lossage ("invalid operand output code");
4952 switch (GET_CODE (x
))
4955 fputs (reg_names
[REGNO (x
)], file
);
4959 rtx addr
= XEXP (x
, 0);
4960 int size
= GET_MODE_SIZE (GET_MODE (x
));
4962 if (legitimate_small_data_address_p (addr
, GET_MODE (x
)))
4967 switch (GET_CODE (addr
))
4969 case PRE_INC
: case POST_INC
:
4970 output_address (VOIDmode
,
4971 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
4972 case PRE_DEC
: case POST_DEC
:
4973 output_address (VOIDmode
,
4974 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
4976 case PRE_MODIFY
: case POST_MODIFY
:
4977 output_address (VOIDmode
, XEXP (addr
, 1)); break;
4981 output_address (VOIDmode
,
4982 plus_constant (Pmode
, XEXP (addr
, 0),
4983 (INTVAL (XEXP (addr
, 1))
4984 >> (size
== 2 ? 1 : 2))));
4988 output_address (VOIDmode
, addr
);
4991 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
4992 arc_output_pic_addr_const (file
, addr
, code
);
4994 output_address (VOIDmode
, addr
);
5001 /* We handle SFmode constants here as output_addr_const doesn't. */
5002 if (GET_MODE (x
) == SFmode
)
5006 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
5007 fprintf (file
, "0x%08lx", l
);
5011 /* Let output_addr_const deal with it. */
5014 || (GET_CODE (x
) == CONST
5015 && GET_CODE (XEXP (x
, 0)) == UNSPEC
5016 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
5017 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
5018 || (GET_CODE (x
) == CONST
5019 && GET_CODE (XEXP (x
, 0)) == PLUS
5020 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
5021 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
5022 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
5023 arc_output_pic_addr_const (file
, x
, code
);
5025 output_addr_const (file
, x
);
5030 /* Print a memory address as an operand to reference that memory location. */
5033 arc_print_operand_address (FILE *file
, rtx addr
)
5035 register rtx base
, index
= 0;
5037 switch (GET_CODE (addr
))
5040 fputs (reg_names
[REGNO (addr
)], file
);
5044 fputs ("gp,", file
);
5045 output_addr_const (file
, addr
);
5047 fputs ("@sda", file
);
5051 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
5052 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
5053 else if (CONST_INT_P (XEXP (addr
, 0)))
5054 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
5056 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
5058 gcc_assert (OBJECT_P (base
));
5059 arc_print_operand_address (file
, base
);
5060 if (CONSTANT_P (base
) && CONST_INT_P (index
))
5064 gcc_assert (OBJECT_P (index
));
5065 arc_print_operand_address (file
, index
);
5069 rtx c
= XEXP (addr
, 0);
5071 if ((GET_CODE (c
) == UNSPEC
5072 && (XINT (c
, 1) == UNSPEC_TLS_OFF
5073 || XINT (c
, 1) == UNSPEC_TLS_IE
))
5074 || (GET_CODE (c
) == PLUS
5075 && GET_CODE (XEXP (c
, 0)) == UNSPEC
5076 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
5077 || XINT (XEXP (c
, 0), 1) == ARC_UNSPEC_GOTOFFPC
)))
5079 arc_output_pic_addr_const (file
, c
, 0);
5082 gcc_assert (GET_CODE (c
) == PLUS
);
5083 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
5084 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
5086 output_address (VOIDmode
, XEXP (addr
, 0));
5092 /* We shouldn't get here as we've lost the mode of the memory object
5093 (which says how much to inc/dec by. */
5098 arc_output_pic_addr_const (file
, addr
, 0);
5100 output_addr_const (file
, addr
);
5105 /* Conditional execution support.
5107 This is based on the ARM port but for now is much simpler.
5109 A finite state machine takes care of noticing whether or not instructions
5110 can be conditionally executed, and thus decrease execution time and code
5111 size by deleting branch instructions. The fsm is controlled by
5112 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
5113 actions of PRINT_OPERAND. The patterns in the .md file for the branch
5114 insns also have a hand in this. */
5115 /* The way we leave dealing with non-anulled or annull-false delay slot
5116 insns to the consumer is awkward. */
5118 /* The state of the fsm controlling condition codes are:
5119 0: normal, do nothing special
5120 1: don't output this insn
5121 2: don't output this insn
5122 3: make insns conditional
5123 4: make insns conditional
5124 5: make insn conditional (only for outputting anulled delay slot insns)
5126 special value for cfun->machine->uid_ccfsm_state:
5127 6: return with but one insn before it since function start / call
5129 State transitions (state->state by whom, under what condition):
5130 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
5132 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
5133 by zero or more non-jump insns and an unconditional branch with
5134 the same target label as the condbranch.
5135 1 -> 3 branch patterns, after having not output the conditional branch
5136 2 -> 4 branch patterns, after having not output the conditional branch
5137 0 -> 5 branch patterns, for anulled delay slot insn.
5138 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
5139 (the target label has CODE_LABEL_NUMBER equal to
5140 arc_ccfsm_target_label).
5141 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
5142 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
5143 5 -> 0 when outputting the delay slot insn
5145 If the jump clobbers the conditions then we use states 2 and 4.
5147 A similar thing can be done with conditional return insns.
5149 We also handle separating branches from sets of the condition code.
5150 This is done here because knowledge of the ccfsm state is required,
5151 we may not be outputting the branch. */
5153 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
5154 before letting final output INSN. */
5157 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
5159 /* BODY will hold the body of INSN. */
5162 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
5163 an if/then/else), and things need to be reversed. */
5166 /* If we start with a return insn, we only succeed if we find another one. */
5167 int seeking_return
= 0;
5169 /* START_INSN will hold the insn from where we start looking. This is the
5170 first insn after the following code_label if REVERSE is true. */
5171 rtx_insn
*start_insn
= insn
;
5173 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
5174 since they don't rely on a cmp preceding the. */
5175 enum attr_type jump_insn_type
;
5177 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
5178 We can't do this in macro FINAL_PRESCAN_INSN because its called from
5179 final_scan_insn which has `optimize' as a local. */
5180 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
5183 /* Ignore notes and labels. */
5186 body
= PATTERN (insn
);
5187 /* If in state 4, check if the target branch is reached, in order to
5188 change back to state 0. */
5189 if (state
->state
== 4)
5191 if (insn
== state
->target_insn
)
5193 state
->target_insn
= NULL
;
5199 /* If in state 3, it is possible to repeat the trick, if this insn is an
5200 unconditional branch to a label, and immediately following this branch
5201 is the previous target label which is only used once, and the label this
5202 branch jumps to is not too far off. Or in other words "we've done the
5203 `then' part, see if we can do the `else' part." */
5204 if (state
->state
== 3)
5206 if (simplejump_p (insn
))
5208 start_insn
= next_nonnote_insn (start_insn
);
5209 if (GET_CODE (start_insn
) == BARRIER
)
5211 /* ??? Isn't this always a barrier? */
5212 start_insn
= next_nonnote_insn (start_insn
);
5214 if (GET_CODE (start_insn
) == CODE_LABEL
5215 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
5216 && LABEL_NUSES (start_insn
) == 1)
5221 else if (GET_CODE (body
) == SIMPLE_RETURN
)
5223 start_insn
= next_nonnote_insn (start_insn
);
5224 if (GET_CODE (start_insn
) == BARRIER
)
5225 start_insn
= next_nonnote_insn (start_insn
);
5226 if (GET_CODE (start_insn
) == CODE_LABEL
5227 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
5228 && LABEL_NUSES (start_insn
) == 1)
5240 if (GET_CODE (insn
) != JUMP_INSN
5241 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
5242 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
5245 /* We can't predicate BRCC or loop ends.
5246 Also, when generating PIC code, and considering a medium range call,
5247 we can't predicate the call. */
5248 jump_insn_type
= get_attr_type (insn
);
5249 if (jump_insn_type
== TYPE_BRCC
5250 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
5251 || jump_insn_type
== TYPE_LOOP_END
5252 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
5255 /* This jump might be paralleled with a clobber of the condition codes,
5256 the jump should always come first. */
5257 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
5258 body
= XVECEXP (body
, 0, 0);
5261 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
5262 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
5264 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
5265 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
5266 int then_not_else
= TRUE
;
5267 /* Nonzero if next insn must be the target label. */
5268 int next_must_be_target_label_p
;
5269 rtx_insn
*this_insn
= start_insn
;
5272 /* Register the insn jumped to. */
5275 if (!seeking_return
)
5276 label
= XEXP (SET_SRC (body
), 0);
5278 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
5279 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
5280 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
5282 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
5283 then_not_else
= FALSE
;
5285 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
5287 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
5290 then_not_else
= FALSE
;
5295 /* If this is a non-annulled branch with a delay slot, there is
5296 no need to conditionalize the delay slot. */
5297 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn
)))) == SEQUENCE
)
5298 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
5300 this_insn
= NEXT_INSN (this_insn
);
5302 /* See how many insns this branch skips, and what kind of insns. If all
5303 insns are okay, and the label or unconditional branch to the same
5304 label is not too far away, succeed. */
5305 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
5306 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
5311 this_insn
= next_nonnote_insn (this_insn
);
5315 if (next_must_be_target_label_p
)
5317 if (GET_CODE (this_insn
) == BARRIER
)
5319 if (GET_CODE (this_insn
) == CODE_LABEL
5320 && this_insn
== label
)
5330 switch (GET_CODE (this_insn
))
5333 /* Succeed if it is the target label, otherwise fail since
5334 control falls in from somewhere else. */
5335 if (this_insn
== label
)
5345 /* Succeed if the following insn is the target label.
5347 If return insns are used then the last insn in a function
5348 will be a barrier. */
5349 next_must_be_target_label_p
= TRUE
;
5353 /* Can handle a call insn if there are no insns after it.
5354 IE: The next "insn" is the target label. We don't have to
5355 worry about delay slots as such insns are SEQUENCE's inside
5356 INSN's. ??? It is possible to handle such insns though. */
5357 if (get_attr_cond (this_insn
) == COND_CANUSE
)
5358 next_must_be_target_label_p
= TRUE
;
5364 scanbody
= PATTERN (this_insn
);
5366 /* If this is an unconditional branch to the same label, succeed.
5367 If it is to another label, do nothing. If it is conditional,
5369 /* ??? Probably, the test for the SET and the PC are
5372 if (GET_CODE (scanbody
) == SET
5373 && GET_CODE (SET_DEST (scanbody
)) == PC
)
5375 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
5376 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
5381 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
5383 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
5386 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
5392 else if (GET_CODE (scanbody
) == PARALLEL
)
5394 if (get_attr_cond (this_insn
) != COND_CANUSE
)
5400 scanbody
= PATTERN (this_insn
);
5402 /* We can only do this with insns that can use the condition
5403 codes (and don't set them). */
5404 if (GET_CODE (scanbody
) == SET
5405 || GET_CODE (scanbody
) == PARALLEL
)
5407 if (get_attr_cond (this_insn
) != COND_CANUSE
)
5410 /* We can't handle other insns like sequences. */
5422 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
5423 state
->target_label
= CODE_LABEL_NUMBER (label
);
5424 else if (seeking_return
|| state
->state
== 2)
5426 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
5428 this_insn
= next_nonnote_insn (this_insn
);
5430 gcc_assert (!this_insn
||
5431 (GET_CODE (this_insn
) != BARRIER
5432 && GET_CODE (this_insn
) != CODE_LABEL
));
5436 /* Oh dear! we ran off the end, give up. */
5437 extract_insn_cached (insn
);
5439 state
->target_insn
= NULL
;
5442 state
->target_insn
= this_insn
;
5447 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
5451 state
->cond
= XEXP (SET_SRC (body
), 0);
5452 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
5455 if (reverse
|| then_not_else
)
5456 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
5459 /* Restore recog_operand. Getting the attributes of other insns can
5460 destroy this array, but final.c assumes that it remains intact
5461 across this call; since the insn has been recognized already we
5462 call insn_extract direct. */
5463 extract_insn_cached (insn
);
5467 /* Record that we are currently outputting label NUM with prefix PREFIX.
5468 It it's the label we're looking for, reset the ccfsm machinery.
5470 Called from ASM_OUTPUT_INTERNAL_LABEL. */
5473 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
5475 if (state
->state
== 3 && state
->target_label
== num
5476 && !strcmp (prefix
, "L"))
5479 state
->target_insn
= NULL
;
5483 /* We are considering a conditional branch with the condition COND.
5484 Check if we want to conditionalize a delay slot insn, and if so modify
5485 the ccfsm state accordingly.
5486 REVERSE says branch will branch when the condition is false. */
5488 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
5489 struct arc_ccfsm
*state
)
5491 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
5493 state
= &arc_ccfsm_current
;
5495 gcc_assert (state
->state
== 0);
5496 if (seq_insn
!= jump
)
5498 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
5500 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
5501 && INSN_ANNULLED_BRANCH_P (jump
)
5502 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
5505 state
->cc
= get_arc_condition_code (cond
);
5507 arc_ccfsm_current
.cc
5508 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
5509 rtx pat
= PATTERN (insn
);
5510 if (GET_CODE (pat
) == COND_EXEC
)
5511 gcc_assert ((INSN_FROM_TARGET_P (insn
)
5512 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
5513 == get_arc_condition_code (XEXP (pat
, 0)));
5520 /* Update *STATE as we would when we emit INSN. */
5523 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
5525 enum attr_type type
;
5528 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
5529 else if (JUMP_P (insn
)
5530 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
5531 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
5532 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
5533 || ((type
== TYPE_UNCOND_BRANCH
5534 || type
== TYPE_RETURN
)
5535 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
5537 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
5538 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
5541 rtx src
= SET_SRC (PATTERN (insn
));
5542 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
5546 else if (arc_ccfsm_current
.state
== 5)
5547 arc_ccfsm_current
.state
= 0;
5550 /* Return true if the current insn, which is a conditional branch, is to be
5554 arc_ccfsm_branch_deleted_p (void)
5556 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
5559 /* Record a branch isn't output because subsequent insns can be
5563 arc_ccfsm_record_branch_deleted (void)
5565 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
5568 /* During insn output, indicate if the current insn is predicated. */
5571 arc_ccfsm_cond_exec_p (void)
5573 return (cfun
->machine
->prescan_initialized
5574 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
5577 /* When deciding if an insn should be output short, we want to know something
5578 about the following insns:
5579 - if another insn follows which we know we can output as a short insn
5580 before an alignment-sensitive point, we can output this insn short:
5581 the decision about the eventual alignment can be postponed.
5582 - if a to-be-aligned label comes next, we should output this insn such
5583 as to get / preserve 4-byte alignment.
5584 - if a likely branch without delay slot insn, or a call with an immediately
5585 following short insn comes next, we should out output this insn such as to
5586 get / preserve 2 mod 4 unalignment.
5587 - do the same for a not completely unlikely branch with a short insn
5588 following before any other branch / label.
5589 - in order to decide if we are actually looking at a branch, we need to
5590 call arc_ccfsm_advance.
5591 - in order to decide if we are looking at a short insn, we should know
5592 if it is conditionalized. To a first order of approximation this is
5593 the case if the state from arc_ccfsm_advance from before this insn
5594 indicates the insn is conditionalized. However, a further refinement
5595 could be to not conditionalize an insn if the destination register(s)
5596 is/are dead in the non-executed case. */
5597 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5598 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5599 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5602 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
5604 enum attr_iscompact iscompact
;
5608 iscompact
= get_attr_iscompact (insn
);
5609 if (iscompact
== ISCOMPACT_FALSE
)
5613 return (get_attr_length (insn
) & 2) != 0;
5616 /* When outputting an instruction (alternative) that can potentially be short,
5617 output the short suffix if the insn is in fact short, and update
5618 cfun->machine->unalign accordingly. */
5621 output_short_suffix (FILE *file
)
5623 rtx_insn
*insn
= current_output_insn
;
5627 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
5629 fprintf (file
, "_s");
5630 cfun
->machine
->unalign
^= 2;
5632 /* Restore recog_operand. */
5633 extract_insn_cached (insn
);
5636 /* Implement FINAL_PRESCAN_INSN. */
5639 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
5640 int noperands ATTRIBUTE_UNUSED
)
5642 if (TARGET_DUMPISIZE
)
5643 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
5645 if (!cfun
->machine
->prescan_initialized
)
5647 /* Clear lingering state from branch shortening. */
5648 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
5649 cfun
->machine
->prescan_initialized
= 1;
5651 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
5654 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5655 Frame pointer elimination is automatically handled.
5657 All eliminations are permissible. If we need a frame
5658 pointer, we must eliminate ARG_POINTER_REGNUM into
5659 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5662 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
5664 return ((to
== HARD_FRAME_POINTER_REGNUM
) || (to
== STACK_POINTER_REGNUM
));
5667 /* Define the offset between two registers, one to be eliminated, and
5668 the other its replacement, at the start of a routine. */
5671 arc_initial_elimination_offset (int from
, int to
)
5673 if (!cfun
->machine
->frame_info
.initialized
)
5674 arc_compute_frame_size ();
5676 if (from
== ARG_POINTER_REGNUM
&& to
== HARD_FRAME_POINTER_REGNUM
)
5678 return (cfun
->machine
->frame_info
.extra_size
5679 + cfun
->machine
->frame_info
.reg_size
);
5682 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
5684 return (cfun
->machine
->frame_info
.total_size
5685 - cfun
->machine
->frame_info
.pretend_size
);
5688 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
5690 return (cfun
->machine
->frame_info
.total_size
5691 - (cfun
->machine
->frame_info
.pretend_size
5692 + cfun
->machine
->frame_info
.extra_size
5693 + cfun
->machine
->frame_info
.reg_size
));
5695 if ((from
== FRAME_POINTER_REGNUM
) && (to
== HARD_FRAME_POINTER_REGNUM
))
5702 arc_frame_pointer_required (void)
5704 return cfun
->calls_alloca
|| crtl
->calls_eh_return
;
5708 /* Return the destination address of a branch. */
5711 branch_dest (rtx branch
)
5713 rtx pat
= PATTERN (branch
);
5714 rtx dest
= (GET_CODE (pat
) == PARALLEL
5715 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
5718 if (GET_CODE (dest
) == IF_THEN_ELSE
)
5719 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
5721 dest
= XEXP (dest
, 0);
5722 dest_uid
= INSN_UID (dest
);
5724 return INSN_ADDRESSES (dest_uid
);
5728 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5731 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
5733 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5734 This clears machine specific flags, so has to come first. */
5735 default_encode_section_info (decl
, rtl
, first
);
5737 /* Check if it is a function, and whether it has the
5738 [long/medium/short]_call attribute specified. */
5739 if (TREE_CODE (decl
) == FUNCTION_DECL
)
5741 rtx symbol
= XEXP (rtl
, 0);
5742 int flags
= SYMBOL_REF_FLAGS (symbol
);
5744 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5745 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
5746 tree long_call_attr
= lookup_attribute ("long_call", attr
);
5747 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
5748 tree short_call_attr
= lookup_attribute ("short_call", attr
);
5750 if (long_call_attr
!= NULL_TREE
)
5751 flags
|= SYMBOL_FLAG_LONG_CALL
;
5752 else if (medium_call_attr
!= NULL_TREE
)
5753 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
5754 else if (short_call_attr
!= NULL_TREE
)
5755 flags
|= SYMBOL_FLAG_SHORT_CALL
;
5757 SYMBOL_REF_FLAGS (symbol
) = flags
;
5759 else if (TREE_CODE (decl
) == VAR_DECL
)
5761 rtx symbol
= XEXP (rtl
, 0);
5763 tree attr
= (TREE_TYPE (decl
) != error_mark_node
5764 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
5766 tree sec_attr
= lookup_attribute ("section", attr
);
5769 const char *sec_name
5770 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
5771 if (strcmp (sec_name
, ".cmem") == 0
5772 || strcmp (sec_name
, ".cmem_shared") == 0
5773 || strcmp (sec_name
, ".cmem_private") == 0)
5774 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
5779 /* This is how to output a definition of an internal numbered label where
5780 PREFIX is the class of label and NUM is the number within the class. */
5782 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
5785 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
5786 default_internal_label (stream
, prefix
, labelno
);
5789 /* Set the cpu type and print out other fancy things,
5790 at the top of the file. */
5792 static void arc_file_start (void)
5794 default_file_start ();
5795 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
5797 /* Set some want to have build attributes. */
5798 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5800 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5801 TARGET_RF16
? 1 : 0);
5802 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5804 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5805 (arc_tp_regno
!= -1) ? 1 : 0);
5806 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5807 TARGET_NO_SDATA_SET
? 0 : 2);
5808 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5809 TARGET_OPTFPE
? 1 : 0);
5811 asm_fprintf (asm_out_file
, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5812 (arc_tune
< ARC_TUNE_CORE_3
) ? 2 :
5813 (arc_tune
== ARC_TUNE_CORE_3
? 3 : 4));
5816 /* Implement `TARGET_ASM_FILE_END'. */
5817 /* Outputs to the stdio stream FILE jli related text. */
5819 void arc_file_end (void)
5821 arc_jli_section
*sec
= arc_jli_sections
;
5825 fprintf (asm_out_file
, "\n");
5826 fprintf (asm_out_file
, "# JLI entry for function ");
5827 assemble_name (asm_out_file
, sec
->name
);
5828 fprintf (asm_out_file
, "\n\t.section .jlitab, \"axG\", @progbits, "
5830 assemble_name (asm_out_file
, sec
->name
);
5831 fprintf (asm_out_file
,", comdat\n");
5833 fprintf (asm_out_file
, "\t.align\t4\n");
5834 fprintf (asm_out_file
, "__jli.");
5835 assemble_name (asm_out_file
, sec
->name
);
5836 fprintf (asm_out_file
, ":\n\t.weak __jli.");
5837 assemble_name (asm_out_file
, sec
->name
);
5838 fprintf (asm_out_file
, "\n\tb\t@");
5839 assemble_name (asm_out_file
, sec
->name
);
5840 fprintf (asm_out_file
, "\n");
5843 file_end_indicate_exec_stack ();
5846 /* Cost functions. */
5848 /* Compute a (partial) cost for rtx X. Return true if the complete
5849 cost has been computed, and false if subexpressions should be
5850 scanned. In either case, *TOTAL contains the cost result. */
5853 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
5854 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
5856 int code
= GET_CODE (x
);
5860 /* Small integers are as cheap as registers. */
5863 bool nolimm
= false; /* Can we do without long immediate? */
5866 if (UNSIGNED_INT6 (INTVAL (x
)))
5872 case AND
: /* bclr, bmsk, ext[bw] */
5873 if (satisfies_constraint_Ccp (x
) /* bclr */
5874 || satisfies_constraint_C1p (x
) /* bmsk */)
5877 case IOR
: /* bset */
5878 if (satisfies_constraint_C0p (x
)) /* bset */
5882 if (satisfies_constraint_C0p (x
)) /* bxor */
5886 if (UNSIGNED_INT8 (INTVAL (x
)))
5888 if (satisfies_constraint_Chi (x
))
5890 if (satisfies_constraint_Clo (x
))
5894 if (TARGET_MUL64_SET
)
5895 if (SIGNED_INT12 (INTVAL (x
)))
5910 /* 4 byte values can be fetched as immediate constants -
5911 let's give that the cost of an extra insn. */
5915 *total
= speed
? COSTS_N_INSNS (1) : COSTS_N_INSNS (4);
5924 *total
= COSTS_N_INSNS (1);
5927 split_double (x
, &first
, &second
);
5928 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
5929 + !SMALL_INT (INTVAL (second
)));
5933 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5934 If we need more than 12 insns to do a multiply, then go out-of-line,
5935 since the call overhead will be < 10% of the cost of the multiply. */
5939 if (TARGET_BARREL_SHIFTER
)
5941 if (CONSTANT_P (XEXP (x
, 0)))
5943 *total
+= rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
5947 *total
= COSTS_N_INSNS (1);
5949 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
5950 *total
= COSTS_N_INSNS (16);
5953 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
5954 /* ??? want_to_gcse_p can throw negative shift counts at us,
5955 and then panics when it gets a negative cost as result.
5956 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5964 if (GET_MODE_CLASS (mode
) == MODE_FLOAT
5965 && (TARGET_FP_SP_SQRT
|| TARGET_FP_DP_SQRT
))
5966 *total
= COSTS_N_INSNS(1);
5967 else if (GET_MODE_CLASS (mode
) == MODE_INT
5969 *total
= COSTS_N_INSNS(1);
5971 *total
= COSTS_N_INSNS(30);
5973 *total
= COSTS_N_INSNS(1);
5977 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
5978 *total
= COSTS_N_INSNS (1);
5980 *total
= arc_multcost
;
5981 /* We do not want synth_mult sequences when optimizing
5983 else if (TARGET_ANY_MPY
)
5984 *total
= COSTS_N_INSNS (1);
5986 *total
= COSTS_N_INSNS (2);
5990 if (outer_code
== MEM
&& CONST_INT_P (XEXP (x
, 1))
5991 && RTX_OK_FOR_OFFSET_P (mode
, XEXP (x
, 1)))
5997 if ((GET_CODE (XEXP (x
, 0)) == ASHIFT
5998 && _1_2_3_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
5999 || (GET_CODE (XEXP (x
, 0)) == MULT
6000 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
)))
6002 if (CONSTANT_P (XEXP (x
, 1)) && !speed
)
6003 *total
+= COSTS_N_INSNS (4);
6004 *total
+= rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
);
6009 if ((GET_CODE (XEXP (x
, 1)) == ASHIFT
6010 && _1_2_3_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
6011 || (GET_CODE (XEXP (x
, 1)) == MULT
6012 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
)))
6014 if (CONSTANT_P (XEXP (x
, 0)) && !speed
)
6015 *total
+= COSTS_N_INSNS (4);
6016 *total
+= rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
);
6023 rtx op0
= XEXP (x
, 0);
6024 rtx op1
= XEXP (x
, 1);
6026 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
6027 && XEXP (op0
, 1) == const1_rtx
)
6029 /* btst / bbit0 / bbit1:
6030 Small integers and registers are free; everything else can
6031 be put in a register. */
6032 mode
= GET_MODE (XEXP (op0
, 0));
6033 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
6034 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
6037 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
6038 && satisfies_constraint_C1p (XEXP (op0
, 1)))
6041 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
6045 if (GET_CODE (op1
) == NEG
)
6047 /* op0 might be constant, the inside of op1 is rather
6048 unlikely to be so. So swapping the operands might lower
6050 mode
= GET_MODE (op0
);
6051 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
6052 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
6057 if (outer_code
== IF_THEN_ELSE
6058 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
6059 && XEXP (x
, 1) == const0_rtx
6060 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
6062 /* btst / bbit0 / bbit1:
6063 Small integers and registers are free; everything else can
6064 be put in a register. */
6065 rtx op0
= XEXP (x
, 0);
6067 mode
= GET_MODE (XEXP (op0
, 0));
6068 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
6069 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
6073 /* scc_insn expands into two insns. */
6074 case GTU
: case GEU
: case LEU
:
6076 *total
+= COSTS_N_INSNS (1);
6078 case LTU
: /* might use adc. */
6080 *total
+= COSTS_N_INSNS (1) - 1;
6087 /* Return true if ADDR is a valid pic address.
6088 A valid pic address on arc should look like
6089 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
6092 arc_legitimate_pic_addr_p (rtx addr
)
6094 if (GET_CODE (addr
) != CONST
)
6097 addr
= XEXP (addr
, 0);
6100 if (GET_CODE (addr
) == PLUS
)
6102 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
6104 addr
= XEXP (addr
, 0);
6107 if (GET_CODE (addr
) != UNSPEC
6108 || XVECLEN (addr
, 0) != 1)
6111 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
6112 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
6113 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
6114 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFFPC
6115 && XINT (addr
, 1) != UNSPEC_TLS_GD
6116 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
6119 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
6120 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
6128 /* Return true if OP contains a symbol reference. */
6131 symbolic_reference_mentioned_p (rtx op
)
6133 register const char *fmt
;
6136 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
6139 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
6140 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
6146 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
6147 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
6151 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
6158 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
6159 If SKIP_LOCAL is true, skip symbols that bind locally.
6160 This is used further down in this file, and, without SKIP_LOCAL,
6161 in the addsi3 / subsi3 expanders when generating PIC code. */
6164 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
6166 register const char *fmt
;
6169 if (GET_CODE(op
) == UNSPEC
)
6172 if (GET_CODE (op
) == SYMBOL_REF
)
6174 if (SYMBOL_REF_TLS_MODEL (op
))
6178 tree decl
= SYMBOL_REF_DECL (op
);
6179 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
6182 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
6183 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
6189 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
6190 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
6195 else if (fmt
[i
] == 'e'
6196 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
6204 /* The __tls_get_attr symbol. */
6205 static GTY(()) rtx arc_tls_symbol
;
6207 /* Emit a call to __tls_get_addr. TI is the argument to this function.
6208 RET is an RTX for the return value location. The entire insn sequence
6212 arc_call_tls_get_addr (rtx ti
)
6214 rtx arg
= gen_rtx_REG (Pmode
, R0_REG
);
6215 rtx ret
= gen_rtx_REG (Pmode
, R0_REG
);
6219 if (!arc_tls_symbol
)
6220 arc_tls_symbol
= init_one_libfunc ("__tls_get_addr");
6222 emit_move_insn (arg
, ti
);
6223 fn
= gen_rtx_MEM (SImode
, arc_tls_symbol
);
6224 insn
= emit_call_insn (gen_call_value (ret
, fn
, const0_rtx
));
6225 RTL_CONST_CALL_P (insn
) = 1;
6226 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), ret
);
6227 use_reg (&CALL_INSN_FUNCTION_USAGE (insn
), arg
);
6232 #define DTPOFF_ZERO_SYM ".tdata"
6234 /* Return a legitimized address for ADDR,
6235 which is a SYMBOL_REF with tls_model MODEL. */
6238 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
6242 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
6243 model
= TLS_MODEL_LOCAL_EXEC
;
6246 /* The TP pointer needs to be set. */
6247 gcc_assert (arc_tp_regno
!= -1);
6251 case TLS_MODEL_GLOBAL_DYNAMIC
:
6252 tmp
= gen_reg_rtx (Pmode
);
6253 emit_move_insn (tmp
, arc_unspec_offset (addr
, UNSPEC_TLS_GD
));
6254 return arc_call_tls_get_addr (tmp
);
6256 case TLS_MODEL_LOCAL_DYNAMIC
:
6259 const char *base_name
;
6261 decl
= SYMBOL_REF_DECL (addr
);
6262 base_name
= DTPOFF_ZERO_SYM
;
6263 if (decl
&& bss_initializer_p (decl
))
6264 base_name
= ".tbss";
6266 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
6267 tmp
= gen_reg_rtx (Pmode
);
6268 emit_move_insn (tmp
, arc_unspec_offset (base
, UNSPEC_TLS_GD
));
6269 base
= arc_call_tls_get_addr (tmp
);
6270 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
),
6271 arc_unspec_offset (addr
, UNSPEC_TLS_OFF
));
6273 case TLS_MODEL_INITIAL_EXEC
:
6274 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_IE
);
6275 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
6276 return gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
, arc_tp_regno
), addr
);
6278 case TLS_MODEL_LOCAL_EXEC
:
6279 addr
= arc_unspec_offset (addr
, UNSPEC_TLS_OFF
);
6280 return gen_rtx_PLUS (Pmode
, gen_rtx_REG (Pmode
, arc_tp_regno
), addr
);
6287 /* Return true if SYMBOL_REF X binds locally. */
6290 arc_symbol_binds_local_p (const_rtx x
)
6292 return (SYMBOL_REF_DECL (x
)
6293 ? targetm
.binds_local_p (SYMBOL_REF_DECL (x
))
6294 : SYMBOL_REF_LOCAL_P (x
));
6297 /* Legitimize a pic address reference in ADDR. The return value is
6298 the legitimated address. */
6301 arc_legitimize_pic_address (rtx addr
)
6306 switch (GET_CODE (addr
))
6309 /* Can be one or our GOT or GOTOFFPC unspecs. This situation
6310 happens when an address is not a legitimate constant and we
6311 need the resolve it via force_reg in
6312 prepare_move_operands. */
6313 switch (XINT (addr
, 1))
6315 case ARC_UNSPEC_GOT
:
6316 case ARC_UNSPEC_GOTOFFPC
:
6317 /* Recover the symbol ref. */
6318 addr
= XVECEXP (addr
, 0, 0);
6325 /* TLS symbols are handled in different place. */
6326 if (SYMBOL_REF_TLS_MODEL (addr
))
6329 /* This symbol must be referenced via a load from the Global
6330 Offset Table (@GOTPC). */
6331 if (!arc_symbol_binds_local_p (addr
))
6332 return gen_const_mem (Pmode
, arc_unspec_offset (addr
, ARC_UNSPEC_GOT
));
6334 /* Local symb: use @pcl to access it. */
6337 return arc_unspec_offset (addr
, ARC_UNSPEC_GOTOFFPC
);
6346 /* Output address constant X to FILE, taking PIC into account. */
6349 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
6354 switch (GET_CODE (x
))
6364 output_addr_const (file
, x
);
6366 /* Local functions do not get references through the PLT. */
6367 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
6368 fputs ("@plt", file
);
6372 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
6373 assemble_name (file
, buf
);
6377 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
6378 assemble_name (file
, buf
);
6382 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
6386 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6390 if (GET_MODE (x
) == VOIDmode
)
6392 /* We can use %d if the number is one word and positive. */
6393 if (CONST_DOUBLE_HIGH (x
))
6394 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
6395 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
6396 else if (CONST_DOUBLE_LOW (x
) < 0)
6397 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
6399 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
6402 /* We can't handle floating point constants;
6403 PRINT_OPERAND must handle them. */
6404 output_operand_lossage ("floating constant misused");
6408 /* FIXME: Not needed here. */
6409 /* Some assemblers need integer constants to appear last (eg masm). */
6410 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
6412 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6413 fprintf (file
, "+");
6414 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6416 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
6418 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6419 if (INTVAL (XEXP (x
, 1)) >= 0)
6420 fprintf (file
, "+");
6421 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6428 /* Avoid outputting things like x-x or x+5-x,
6429 since some assemblers can't handle that. */
6430 x
= simplify_subtraction (x
);
6431 if (GET_CODE (x
) != MINUS
)
6434 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6435 fprintf (file
, "-");
6436 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
6437 && INTVAL (XEXP (x
, 1)) < 0)
6439 fprintf (file
, "(");
6440 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6441 fprintf (file
, ")");
6444 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
6449 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
6455 bool pcrel
; pcrel
= false;
6456 rtx base
; base
= NULL
;
6457 gcc_assert (XVECLEN (x
, 0) >= 1);
6458 switch (XINT (x
, 1))
6460 case ARC_UNSPEC_GOT
:
6461 suffix
= "@gotpc", pcrel
= true;
6463 case ARC_UNSPEC_GOTOFF
:
6466 case ARC_UNSPEC_GOTOFFPC
:
6467 suffix
= "@pcl", pcrel
= true;
6469 case ARC_UNSPEC_PLT
:
6473 suffix
= "@tlsgd", pcrel
= true;
6476 suffix
= "@tlsie", pcrel
= true;
6478 case UNSPEC_TLS_OFF
:
6479 if (XVECLEN (x
, 0) == 2)
6480 base
= XVECEXP (x
, 0, 1);
6481 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6482 || (!flag_pic
&& !base
))
6488 suffix
= "@invalid";
6489 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
6493 fputs ("pcl,", file
);
6494 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
6495 fputs (suffix
, file
);
6497 arc_output_pic_addr_const (file
, base
, code
);
6501 output_operand_lossage ("invalid expression as operand");
6505 /* The function returning the number of words, at the beginning of an
6506 argument, must be put in registers. The returned value must be
6507 zero for arguments that are passed entirely in registers or that
6508 are entirely pushed on the stack.
6510 On some machines, certain arguments must be passed partially in
6511 registers and partially in memory. On these machines, typically
6512 the first N words of arguments are passed in registers, and the
6513 rest on the stack. If a multi-word argument (a `double' or a
6514 structure) crosses that boundary, its first few words must be
6515 passed in registers and the rest must be pushed. This function
6516 tells the compiler when this occurs, and how many of the words
6517 should go in registers.
6519 `FUNCTION_ARG' for these arguments should return the first register
6520 to be used by the caller for this argument; likewise
6521 `FUNCTION_INCOMING_ARG', for the called function.
6523 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6525 /* If REGNO is the least arg reg available then what is the total number of arg
6527 #define GPR_REST_ARG_REGS(REGNO) \
6528 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6530 /* Since arc parm regs are contiguous. */
6531 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6533 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6536 arc_arg_partial_bytes (cumulative_args_t cum_v
, const function_arg_info
&arg
)
6538 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6539 int bytes
= arg
.promoted_size_in_bytes ();
6540 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6544 arg_num
= ROUND_ADVANCE_CUM (arg_num
, arg
.mode
, arg
.type
);
6545 ret
= GPR_REST_ARG_REGS (arg_num
);
6547 /* ICEd at function.c:2361, and ret is copied to data->partial */
6548 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
6553 /* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
6554 args are normally in registers and the rest are pushed. */
6557 arc_function_arg (cumulative_args_t cum_v
, const function_arg_info
&arg
)
6559 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6562 const char *debstr ATTRIBUTE_UNUSED
;
6564 arg_num
= ROUND_ADVANCE_CUM (arg_num
, arg
.mode
, arg
.type
);
6565 /* Return a marker for use in the call instruction. */
6566 if (arg
.end_marker_p ())
6571 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
6573 ret
= gen_rtx_REG (arg
.mode
, arg_num
);
6574 debstr
= reg_names
[arg_num
];
6584 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6585 /* For the ARC: the cum set here is passed on to function_arg where we
6586 look at its value and say which reg to use. Strategy: advance the
6587 regnumber here till we run out of arg regs, then set *cum to last
6588 reg. In function_arg, since *cum > last arg reg we would return 0
6589 and thus the arg will end up on the stack. For straddling args of
6590 course function_arg_partial_nregs will come into play. */
6593 arc_function_arg_advance (cumulative_args_t cum_v
,
6594 const function_arg_info
&arg
)
6596 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
6597 int bytes
= arg
.promoted_size_in_bytes ();
6598 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
6602 *cum
= ROUND_ADVANCE_CUM (*cum
, arg
.mode
, arg
.type
);
6603 for (i
= 0; i
< words
; i
++)
6604 *cum
= ARC_NEXT_ARG_REG (*cum
);
6608 /* Define how to find the value returned by a function.
6609 VALTYPE is the data type of the value (as a tree).
6610 If the precise function being called is known, FN_DECL_OR_TYPE is its
6611 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6614 arc_function_value (const_tree valtype
,
6615 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
6616 bool outgoing ATTRIBUTE_UNUSED
)
6618 machine_mode mode
= TYPE_MODE (valtype
);
6619 int unsignedp ATTRIBUTE_UNUSED
;
6621 unsignedp
= TYPE_UNSIGNED (valtype
);
6622 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
6623 PROMOTE_MODE (mode
, unsignedp
, valtype
);
6624 return gen_rtx_REG (mode
, 0);
6627 /* Returns the return address that is used by builtin_return_address. */
6630 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
6635 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
6638 /* Determine if a given RTX is a valid constant. We already know this
6639 satisfies CONSTANT_P. */
6642 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
6644 switch (GET_CODE (x
))
6649 if (arc_legitimate_pic_addr_p (x
))
6652 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6655 if (SYMBOL_REF_TLS_MODEL (x
))
6667 return arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6672 bool t1
= arc_legitimate_constant_p (mode
, XEXP (x
, 0));
6673 bool t2
= arc_legitimate_constant_p (mode
, XEXP (x
, 1));
6682 return TARGET_PLUS_DMPY
;
6685 return TARGET_PLUS_QMACW
;
6691 switch (XINT (x
, 1))
6694 case UNSPEC_TLS_OFF
:
6698 /* Any other unspec ending here are pic related, hence the above
6699 constant pic address checking returned false. */
6705 fatal_insn ("unrecognized supposed constant", x
);
6712 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
6714 if (RTX_OK_FOR_BASE_P (x
, strict
))
6716 if (legitimate_offset_address_p (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
6718 if (legitimate_scaled_address_p (mode
, x
, strict
))
6720 if (legitimate_small_data_address_p (x
, mode
))
6722 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
6725 /* When we compile for size avoid const (@sym + offset)
6727 if (!flag_pic
&& optimize_size
&& !reload_completed
6728 && (GET_CODE (x
) == CONST
)
6729 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
6730 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
6731 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
6732 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
6734 rtx addend
= XEXP (XEXP (x
, 0), 1);
6735 gcc_assert (CONST_INT_P (addend
));
6736 HOST_WIDE_INT offset
= INTVAL (addend
);
6738 /* Allow addresses having a large offset to pass. Anyhow they
6739 will end in a limm. */
6740 return !(offset
> -1024 && offset
< 1020);
6743 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
6745 return arc_legitimate_constant_p (mode
, x
);
6747 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
6748 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
6749 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
6751 /* We're restricted here by the `st' insn. */
6752 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
6753 && GET_CODE (XEXP ((x
), 1)) == PLUS
6754 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
6755 && legitimate_offset_address_p (QImode
, XEXP (x
, 1),
6756 TARGET_AUTO_MODIFY_REG
, strict
))
6761 /* Return true iff ADDR (a legitimate address expression)
6762 has an effect that depends on the machine mode it is used for. */
6765 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
6767 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6768 which is valid for loads and stores, or a limm offset, which is valid for
6769 loads. Scaled indices are scaled by the access mode. */
6770 if (GET_CODE (addr
) == PLUS
6771 && GET_CODE (XEXP ((addr
), 0)) == MULT
)
6776 /* Determine if it's legal to put X into the constant pool. */
6779 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
6781 return !arc_legitimate_constant_p (mode
, x
);
6784 /* IDs for all the ARC builtins. */
6788 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6789 ARC_BUILTIN_ ## NAME,
6790 #include "builtins.def"
6796 struct GTY(()) arc_builtin_description
6798 enum insn_code icode
;
6803 static GTY(()) struct arc_builtin_description
6804 arc_bdesc
[ARC_BUILTIN_COUNT
] =
6806 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6807 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6808 #include "builtins.def"
6812 /* Transform UP into lowercase and write the result to LO.
6813 You must provide enough space for LO. Return LO. */
6816 arc_tolower (char *lo
, const char *up
)
6820 for (; *up
; up
++, lo
++)
6821 *lo
= TOLOWER (*up
);
6828 /* Implement `TARGET_BUILTIN_DECL'. */
6831 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
6833 if (id
< ARC_BUILTIN_COUNT
)
6834 return arc_bdesc
[id
].fndecl
;
6836 return error_mark_node
;
6840 arc_init_builtins (void)
6842 tree V4HI_type_node
;
6843 tree V2SI_type_node
;
6844 tree V2HI_type_node
;
6846 /* Vector types based on HS SIMD elements. */
6847 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
6848 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
6849 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
6851 tree pcvoid_type_node
6852 = build_pointer_type (build_qualified_type (void_type_node
,
6854 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
6857 tree void_ftype_void
6858 = build_function_type_list (void_type_node
, NULL_TREE
);
6860 = build_function_type_list (integer_type_node
, integer_type_node
,
6862 tree int_ftype_pcvoid_int
6863 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
6864 integer_type_node
, NULL_TREE
);
6865 tree void_ftype_usint_usint
6866 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6867 long_unsigned_type_node
, NULL_TREE
);
6868 tree int_ftype_int_int
6869 = build_function_type_list (integer_type_node
, integer_type_node
,
6870 integer_type_node
, NULL_TREE
);
6871 tree usint_ftype_usint
6872 = build_function_type_list (long_unsigned_type_node
,
6873 long_unsigned_type_node
, NULL_TREE
);
6874 tree void_ftype_usint
6875 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
6878 = build_function_type_list (integer_type_node
, void_type_node
,
6881 = build_function_type_list (void_type_node
, integer_type_node
,
6883 tree int_ftype_short
6884 = build_function_type_list (integer_type_node
, short_integer_type_node
,
6887 /* Old ARC SIMD types. */
6888 tree v8hi_ftype_v8hi_v8hi
6889 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6890 V8HI_type_node
, NULL_TREE
);
6891 tree v8hi_ftype_v8hi_int
6892 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6893 integer_type_node
, NULL_TREE
);
6894 tree v8hi_ftype_v8hi_int_int
6895 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6896 integer_type_node
, integer_type_node
,
6898 tree void_ftype_v8hi_int_int
6899 = build_function_type_list (void_type_node
, V8HI_type_node
,
6900 integer_type_node
, integer_type_node
,
6902 tree void_ftype_v8hi_int_int_int
6903 = build_function_type_list (void_type_node
, V8HI_type_node
,
6904 integer_type_node
, integer_type_node
,
6905 integer_type_node
, NULL_TREE
);
6906 tree v8hi_ftype_int_int
6907 = build_function_type_list (V8HI_type_node
, integer_type_node
,
6908 integer_type_node
, NULL_TREE
);
6909 tree void_ftype_int_int
6910 = build_function_type_list (void_type_node
, integer_type_node
,
6911 integer_type_node
, NULL_TREE
);
6912 tree v8hi_ftype_v8hi
6913 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
6915 /* ARCv2 SIMD types. */
6916 tree long_ftype_v4hi_v4hi
6917 = build_function_type_list (long_long_integer_type_node
,
6918 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6919 tree int_ftype_v2hi_v2hi
6920 = build_function_type_list (integer_type_node
,
6921 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6922 tree v2si_ftype_v2hi_v2hi
6923 = build_function_type_list (V2SI_type_node
,
6924 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6925 tree v2hi_ftype_v2hi_v2hi
6926 = build_function_type_list (V2HI_type_node
,
6927 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
6928 tree v2si_ftype_v2si_v2si
6929 = build_function_type_list (V2SI_type_node
,
6930 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
6931 tree v4hi_ftype_v4hi_v4hi
6932 = build_function_type_list (V4HI_type_node
,
6933 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
6934 tree long_ftype_v2si_v2hi
6935 = build_function_type_list (long_long_integer_type_node
,
6936 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
6938 /* Add the builtins. */
6939 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6941 int id = ARC_BUILTIN_ ## NAME; \
6942 const char *Name = "__builtin_arc_" #NAME; \
6943 char *name = (char*) alloca (1 + strlen (Name)); \
6945 gcc_assert (id < ARC_BUILTIN_COUNT); \
6947 arc_bdesc[id].fndecl \
6948 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6949 BUILT_IN_MD, NULL, NULL_TREE); \
6951 #include "builtins.def"
6955 /* Helper to expand __builtin_arc_aligned (void* val, int
6959 arc_expand_builtin_aligned (tree exp
)
6961 tree arg0
= CALL_EXPR_ARG (exp
, 0);
6962 tree arg1
= CALL_EXPR_ARG (exp
, 1);
6964 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6965 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
6967 if (!CONST_INT_P (op1
))
6969 /* If we can't fold the alignment to a constant integer
6970 whilst optimizing, this is probably a user error. */
6972 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
6976 HOST_WIDE_INT alignTest
= INTVAL (op1
);
6977 /* Check alignTest is positive, and a power of two. */
6978 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
6980 error ("invalid alignment value for %<__builtin_arc_aligned%>");
6984 if (CONST_INT_P (op0
))
6986 HOST_WIDE_INT pnt
= INTVAL (op0
);
6988 if ((pnt
& (alignTest
- 1)) == 0)
6993 unsigned align
= get_pointer_alignment (arg0
);
6994 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
6996 if (align
&& align
>= numBits
)
6998 /* Another attempt to ascertain alignment. Check the type
6999 we are pointing to. */
7000 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
7001 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
7006 /* Default to false. */
7010 /* Helper arc_expand_builtin, generates a pattern for the given icode
7014 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
7016 switch (insn_data
[icode
].n_generator_args
)
7019 return GEN_FCN (icode
) ();
7021 return GEN_FCN (icode
) (arg
[0]);
7023 return GEN_FCN (icode
) (arg
[0], arg
[1]);
7025 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
7027 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
7029 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
7035 /* Expand an expression EXP that calls a built-in function,
7036 with result going to TARGET if that's convenient
7037 (and in mode MODE if that's convenient).
7038 SUBTARGET may be used as the target for computing one of EXP's operands.
7039 IGNORE is nonzero if the value is to be ignored. */
7042 arc_expand_builtin (tree exp
,
7044 rtx subtarget ATTRIBUTE_UNUSED
,
7045 machine_mode mode ATTRIBUTE_UNUSED
,
7046 int ignore ATTRIBUTE_UNUSED
)
7048 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
7049 unsigned int id
= DECL_MD_FUNCTION_CODE (fndecl
);
7050 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
7051 int i
, j
, n_args
= call_expr_nargs (exp
);
7054 enum insn_code icode
= d
->icode
;
7055 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
7072 if (id
>= ARC_BUILTIN_COUNT
)
7073 internal_error ("bad builtin fcode");
7075 /* 1st part: Expand special builtins. */
7078 case ARC_BUILTIN_NOP
:
7079 emit_insn (gen_nopv ());
7082 case ARC_BUILTIN_RTIE
:
7083 case ARC_BUILTIN_SYNC
:
7084 case ARC_BUILTIN_BRK
:
7085 case ARC_BUILTIN_SWI
:
7086 case ARC_BUILTIN_UNIMP_S
:
7087 gcc_assert (icode
!= 0);
7088 emit_insn (GEN_FCN (icode
) (const1_rtx
));
7091 case ARC_BUILTIN_ALIGNED
:
7092 return arc_expand_builtin_aligned (exp
);
7094 case ARC_BUILTIN_CLRI
:
7095 target
= gen_reg_rtx (SImode
);
7096 emit_insn (gen_clri (target
, const1_rtx
));
7099 case ARC_BUILTIN_TRAP_S
:
7100 case ARC_BUILTIN_SLEEP
:
7101 arg0
= CALL_EXPR_ARG (exp
, 0);
7103 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
7105 gcc_assert (icode
!= 0);
7106 emit_insn (GEN_FCN (icode
) (op0
));
7109 case ARC_BUILTIN_VDORUN
:
7110 case ARC_BUILTIN_VDIRUN
:
7111 arg0
= CALL_EXPR_ARG (exp
, 0);
7112 arg1
= CALL_EXPR_ARG (exp
, 1);
7113 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7114 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7116 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
7118 mode0
= insn_data
[icode
].operand
[1].mode
;
7119 mode1
= insn_data
[icode
].operand
[2].mode
;
7121 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
7122 op0
= copy_to_mode_reg (mode0
, op0
);
7124 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
7125 op1
= copy_to_mode_reg (mode1
, op1
);
7127 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
7134 case ARC_BUILTIN_VDIWR
:
7135 case ARC_BUILTIN_VDOWR
:
7136 arg0
= CALL_EXPR_ARG (exp
, 0);
7137 arg1
= CALL_EXPR_ARG (exp
, 1);
7138 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7139 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7141 if (!CONST_INT_P (op0
)
7142 || !(UNSIGNED_INT3 (INTVAL (op0
))))
7143 error ("operand 1 should be an unsigned 3-bit immediate");
7145 mode1
= insn_data
[icode
].operand
[1].mode
;
7147 if (icode
== CODE_FOR_vdiwr_insn
)
7148 target
= gen_rtx_REG (SImode
,
7149 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
7150 else if (icode
== CODE_FOR_vdowr_insn
)
7151 target
= gen_rtx_REG (SImode
,
7152 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
7156 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
7157 op1
= copy_to_mode_reg (mode1
, op1
);
7159 pat
= GEN_FCN (icode
) (target
, op1
);
7166 case ARC_BUILTIN_VASRW
:
7167 case ARC_BUILTIN_VSR8
:
7168 case ARC_BUILTIN_VSR8AW
:
7169 arg0
= CALL_EXPR_ARG (exp
, 0);
7170 arg1
= CALL_EXPR_ARG (exp
, 1);
7171 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7172 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7173 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7175 target
= gen_reg_rtx (V8HImode
);
7176 mode0
= insn_data
[icode
].operand
[1].mode
;
7177 mode1
= insn_data
[icode
].operand
[2].mode
;
7179 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
7180 op0
= copy_to_mode_reg (mode0
, op0
);
7182 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
7183 || !(UNSIGNED_INT3 (INTVAL (op1
))))
7184 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7186 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
7193 case ARC_BUILTIN_VLD32WH
:
7194 case ARC_BUILTIN_VLD32WL
:
7195 case ARC_BUILTIN_VLD64
:
7196 case ARC_BUILTIN_VLD32
:
7199 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
7200 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
7201 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
7203 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7204 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7205 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7206 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7208 /* target <- src vreg. */
7209 emit_insn (gen_move_insn (target
, src_vreg
));
7211 /* target <- vec_concat: target, mem (Ib, u8). */
7212 mode0
= insn_data
[icode
].operand
[3].mode
;
7213 mode1
= insn_data
[icode
].operand
[1].mode
;
7215 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
7216 || !(UNSIGNED_INT3 (INTVAL (op0
))))
7217 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7219 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
7220 || !(UNSIGNED_INT8 (INTVAL (op1
))))
7221 error ("operand 2 should be an unsigned 8-bit value");
7223 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
7230 case ARC_BUILTIN_VLD64W
:
7231 case ARC_BUILTIN_VLD128
:
7232 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
7233 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
7235 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7236 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7237 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7239 /* target <- src vreg. */
7240 target
= gen_reg_rtx (V8HImode
);
7242 /* target <- vec_concat: target, mem (Ib, u8). */
7243 mode0
= insn_data
[icode
].operand
[1].mode
;
7244 mode1
= insn_data
[icode
].operand
[2].mode
;
7245 mode2
= insn_data
[icode
].operand
[3].mode
;
7247 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
7248 || !(UNSIGNED_INT3 (INTVAL (op1
))))
7249 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7251 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
7252 || !(UNSIGNED_INT8 (INTVAL (op2
))))
7253 error ("operand 2 should be an unsigned 8-bit value");
7255 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
7263 case ARC_BUILTIN_VST128
:
7264 case ARC_BUILTIN_VST64
:
7265 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
7266 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
7267 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
7269 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7270 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7271 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7272 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7274 mode0
= insn_data
[icode
].operand
[0].mode
;
7275 mode1
= insn_data
[icode
].operand
[1].mode
;
7276 mode2
= insn_data
[icode
].operand
[2].mode
;
7277 mode3
= insn_data
[icode
].operand
[3].mode
;
7279 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
7280 || !(UNSIGNED_INT3 (INTVAL (op1
))))
7281 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7283 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
7284 || !(UNSIGNED_INT8 (INTVAL (op2
))))
7285 error ("operand 3 should be an unsigned 8-bit value");
7287 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
7288 op3
= copy_to_mode_reg (mode3
, op3
);
7290 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
7297 case ARC_BUILTIN_VST16_N
:
7298 case ARC_BUILTIN_VST32_N
:
7299 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
7300 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
7301 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
7302 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
7304 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7305 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
7306 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7307 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
7308 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
7310 mode0
= insn_data
[icode
].operand
[0].mode
;
7311 mode2
= insn_data
[icode
].operand
[2].mode
;
7312 mode3
= insn_data
[icode
].operand
[3].mode
;
7313 mode4
= insn_data
[icode
].operand
[4].mode
;
7315 /* Do some correctness checks for the operands. */
7316 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
7317 || !(UNSIGNED_INT8 (INTVAL (op0
))))
7318 error ("operand 4 should be an unsigned 8-bit value (0-255)");
7320 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
7321 || !(UNSIGNED_INT3 (INTVAL (op2
))))
7322 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
7324 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
7325 op3
= copy_to_mode_reg (mode3
, op3
);
7327 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
7328 || !(UNSIGNED_INT3 (INTVAL (op4
))))
7329 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
7330 else if (icode
== CODE_FOR_vst32_n_insn
7331 && ((INTVAL (op4
) % 2) != 0))
7332 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
7334 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
7345 /* 2nd part: Expand regular builtins. */
7347 internal_error ("bad builtin fcode");
7349 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
7354 if (target
== NULL_RTX
7355 || GET_MODE (target
) != tmode
7356 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
7358 target
= gen_reg_rtx (tmode
);
7363 gcc_assert (n_args
<= 4);
7364 for (i
= 0; i
< n_args
; i
++, j
++)
7366 tree arg
= CALL_EXPR_ARG (exp
, i
);
7367 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
7368 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
7369 machine_mode opmode
= GET_MODE (op
);
7370 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
7372 /* SIMD extension requires exact immediate operand match. */
7373 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
7374 && (id
< ARC_BUILTIN_SIMD_END
)
7378 if (!CONST_INT_P (op
))
7379 error ("builtin requires an immediate for operand %d", j
);
7383 if (!satisfies_constraint_L (op
))
7384 error ("operand %d should be a 6 bit unsigned immediate", j
);
7387 if (!satisfies_constraint_P (op
))
7388 error ("operand %d should be a 8 bit unsigned immediate", j
);
7391 if (!satisfies_constraint_K (op
))
7392 error ("operand %d should be a 3 bit unsigned immediate", j
);
7395 error ("unknown builtin immediate operand type for operand %d",
7400 if (CONST_INT_P (op
))
7403 if ((opmode
== SImode
) && (mode
== HImode
))
7406 op
= gen_lowpart (HImode
, op
);
7409 /* In case the insn wants input operands in modes different from
7410 the result, abort. */
7411 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
7413 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
7414 op
= copy_to_mode_reg (mode
, op
);
7419 pat
= apply_GEN_FCN (icode
, xop
);
7420 if (pat
== NULL_RTX
)
7431 /* Returns true if the operands[opno] is a valid compile-time constant to be
7432 used as register number in the code for builtins. Else it flags an error
7433 and returns false. */
7436 check_if_valid_regno_const (rtx
*operands
, int opno
)
7439 switch (GET_CODE (operands
[opno
]))
7446 error ("register number must be a compile-time constant. "
7447 "Try giving higher optimization levels");
7453 /* Return true if it is ok to make a tail-call to DECL. */
7456 arc_function_ok_for_sibcall (tree decl
,
7457 tree exp ATTRIBUTE_UNUSED
)
7459 tree attrs
= NULL_TREE
;
7461 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7462 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
7467 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
7469 if (lookup_attribute ("jli_always", attrs
))
7471 if (lookup_attribute ("jli_fixed", attrs
))
7473 if (lookup_attribute ("secure_call", attrs
))
7477 /* Everything else is ok. */
7481 /* Output code to add DELTA to the first argument, and then jump
7482 to FUNCTION. Used for C++ multiple inheritance. */
7485 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
7486 HOST_WIDE_INT delta
,
7487 HOST_WIDE_INT vcall_offset
,
7490 const char *fnname
= IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk
));
7491 int mi_delta
= delta
;
7492 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
7495 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
7498 assemble_start_function (thunk
, fnname
);
7501 mi_delta
= - mi_delta
;
7503 /* Add DELTA. When possible use a plain add, otherwise load it into
7504 a register first. */
7506 while (mi_delta
!= 0)
7508 if ((mi_delta
& (3 << shift
)) == 0)
7512 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
7513 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
7514 mi_delta
& (0xff << shift
));
7515 mi_delta
&= ~(0xff << shift
);
7520 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7521 if (vcall_offset
!= 0)
7523 /* ld r12,[this] --> temp = *this
7524 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7526 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7527 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7528 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
7529 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
7530 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
7531 asm_fprintf (file
, "\tld\t%s, [%s]\n",
7532 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
7533 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
7534 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
7537 fnaddr
= XEXP (DECL_RTL (function
), 0);
7539 if (arc_is_longcall_p (fnaddr
))
7543 asm_fprintf (file
, "\tld\t%s, [pcl, @",
7544 ARC_TEMP_SCRATCH_REG
);
7545 assemble_name (file
, XSTR (fnaddr
, 0));
7546 fputs ("@gotpc]\n", file
);
7547 asm_fprintf (file
, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG
);
7551 fputs ("\tj\t@", file
);
7552 assemble_name (file
, XSTR (fnaddr
, 0));
7557 fputs ("\tb\t@", file
);
7558 assemble_name (file
, XSTR (fnaddr
, 0));
7560 fputs ("@plt\n", file
);
7563 assemble_end_function (thunk
, fnname
);
7566 /* Return true if a 32 bit "long_call" should be generated for
7567 this calling SYM_REF. We generate a long_call if the function:
7569 a. has an __attribute__((long call))
7570 or b. the -mlong-calls command line switch has been specified
7572 However we do not generate a long call if the function has an
7573 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7575 This function will be called by C fragments contained in the machine
7576 description file. */
7579 arc_is_longcall_p (rtx sym_ref
)
7581 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7584 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
7585 || (TARGET_LONG_CALLS_SET
7586 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7587 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7591 /* Likewise for short calls. */
7594 arc_is_shortcall_p (rtx sym_ref
)
7596 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
7599 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
7600 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
7601 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
7602 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
7606 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7609 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
7611 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
7615 HOST_WIDE_INT size
= int_size_in_bytes (type
);
7616 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
7621 arc_pass_by_reference (cumulative_args_t
, const function_arg_info
&arg
)
7623 return (arg
.type
!= 0
7624 && (TREE_CODE (TYPE_SIZE (arg
.type
)) != INTEGER_CST
7625 || TREE_ADDRESSABLE (arg
.type
)));
7628 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7631 arc_can_use_doloop_p (const widest_int
&,
7632 const widest_int
&iterations_max
,
7633 unsigned int loop_depth
, bool entered_at_top
)
7635 /* Considering limitations in the hardware, only use doloop
7636 for innermost loops which must be entered from the top. */
7637 if (loop_depth
> 1 || !entered_at_top
)
7640 /* Check for lp_count width boundary. */
7641 if (arc_lpcwidth
!= 32
7642 && (wi::gtu_p (iterations_max
, ((1 << arc_lpcwidth
) - 1))
7643 || wi::eq_p (iterations_max
, 0)))
7648 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7649 return why doloop cannot be applied. */
7652 arc_invalid_within_doloop (const rtx_insn
*insn
)
7655 return "Function call in the loop.";
7657 /* FIXME! add here all the ZOL exceptions. */
7661 /* Return the next active insn, skiping the inline assembly code. */
7664 arc_active_insn (rtx_insn
*insn
)
7668 insn
= NEXT_INSN (insn
);
7670 || (active_insn_p (insn
)
7671 && NONDEBUG_INSN_P (insn
)
7673 && GET_CODE (PATTERN (insn
)) != UNSPEC_VOLATILE
7674 && GET_CODE (PATTERN (insn
)) != PARALLEL
))
7680 /* Search for a sequence made out of two stores and a given number of
7681 loads, insert a nop if required. */
7684 check_store_cacheline_hazard (void)
7686 rtx_insn
*insn
, *succ0
, *insn1
;
7689 for (insn
= get_insns (); insn
; insn
= arc_active_insn (insn
))
7691 succ0
= arc_active_insn (insn
);
7696 if (!single_set (insn
))
7699 if ((get_attr_type (insn
) != TYPE_STORE
))
7702 /* Found at least two consecutive stores. Goto the end of the
7704 for (insn1
= succ0
; insn1
; insn1
= arc_active_insn (insn1
))
7705 if (!single_set (insn1
) || get_attr_type (insn1
) != TYPE_STORE
)
7708 /* Save were we are. */
7711 /* Now, check the next two instructions for the following cases:
7712 1. next instruction is a LD => insert 2 nops between store
7714 2. next-next instruction is a LD => inset 1 nop after the store
7716 if (insn1
&& single_set (insn1
)
7717 && (get_attr_type (insn1
) == TYPE_LOAD
))
7720 emit_insn_before (gen_nopv (), insn1
);
7721 emit_insn_before (gen_nopv (), insn1
);
7725 if (insn1
&& (get_attr_type (insn1
) == TYPE_COMPARE
))
7727 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7728 reorg, so it is safe to reuse it for avoiding the
7729 current compare insn to be part of a BRcc
7731 add_reg_note (insn1
, REG_SAVE_NOTE
, GEN_INT (3));
7733 insn1
= arc_active_insn (insn1
);
7734 if (insn1
&& single_set (insn1
)
7735 && (get_attr_type (insn1
) == TYPE_LOAD
))
7738 emit_insn_before (gen_nopv (), insn1
);
7752 /* Return true if a load instruction (CONSUMER) uses the same address as a
7753 store instruction (PRODUCER). This function is used to avoid st/ld
7754 address hazard in ARC700 cores. */
7757 arc_store_addr_hazard_internal_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7759 rtx in_set
, out_set
;
7760 rtx out_addr
, in_addr
;
7768 /* Peel the producer and the consumer for the address. */
7769 out_set
= single_set (producer
);
7772 out_addr
= SET_DEST (out_set
);
7775 if (GET_CODE (out_addr
) == ZERO_EXTEND
7776 || GET_CODE (out_addr
) == SIGN_EXTEND
)
7777 out_addr
= XEXP (out_addr
, 0);
7779 if (!MEM_P (out_addr
))
7782 in_set
= single_set (consumer
);
7785 in_addr
= SET_SRC (in_set
);
7788 if (GET_CODE (in_addr
) == ZERO_EXTEND
7789 || GET_CODE (in_addr
) == SIGN_EXTEND
)
7790 in_addr
= XEXP (in_addr
, 0);
7792 if (!MEM_P (in_addr
))
7794 /* Get rid of the MEM and check if the addresses are
7796 in_addr
= XEXP (in_addr
, 0);
7797 out_addr
= XEXP (out_addr
, 0);
7799 return exp_equiv_p (in_addr
, out_addr
, 0, true);
7805 /* Return TRUE is we have an store address hazard. */
7808 arc_store_addr_hazard_p (rtx_insn
* producer
, rtx_insn
* consumer
)
7810 if (TARGET_ARC700
&& (arc_tune
!= ARC_TUNE_ARC7XX
))
7812 return arc_store_addr_hazard_internal_p (producer
, consumer
);
7815 /* The same functionality as arc_hazard. It is called in machine
7816 reorg before any other optimization. Hence, the NOP size is taken
7817 into account when doing branch shortening. */
7820 workaround_arc_anomaly (void)
7822 rtx_insn
*insn
, *succ0
;
7824 /* For any architecture: call arc_hazard here. */
7825 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
7827 succ0
= next_real_insn (insn
);
7828 if (arc_hazard (insn
, succ0
))
7830 emit_insn_before (gen_nopv (), succ0
);
7837 /* Old A7 are suffering of a cache hazard, and we need to insert two
7838 nops between any sequence of stores and a load. */
7839 if (arc_tune
!= ARC_TUNE_ARC7XX
)
7840 check_store_cacheline_hazard ();
7843 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7844 turns out not to be optimizable; we have to split the loop_end pattern into
7845 a subtract and a test. */
7848 hwloop_fail (hwloop_info loop
)
7851 rtx insn
= loop
->loop_end
;
7854 && (loop
->length
&& (loop
->length
<= ARC_MAX_LOOP_LENGTH
))
7855 && REG_P (loop
->iter_reg
))
7857 /* TARGET_V2 core3 has dbnz instructions. */
7858 test
= gen_dbnz (loop
->iter_reg
, loop
->start_label
);
7859 insn
= emit_jump_insn_before (test
, loop
->loop_end
);
7861 else if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
) == LP_COUNT
))
7863 /* We have the lp_count as loop iterator, try to use it. */
7864 emit_insn_before (gen_loop_fail (), loop
->loop_end
);
7865 test
= gen_rtx_NE (VOIDmode
, gen_rtx_REG (CC_ZNmode
, CC_REG
),
7867 test
= gen_rtx_IF_THEN_ELSE (VOIDmode
, test
,
7868 gen_rtx_LABEL_REF (Pmode
, loop
->start_label
),
7870 insn
= emit_jump_insn_before (gen_rtx_SET (pc_rtx
, test
),
7875 emit_insn_before (gen_addsi3 (loop
->iter_reg
,
7879 test
= gen_rtx_NE (VOIDmode
, loop
->iter_reg
, const0_rtx
);
7880 insn
= emit_jump_insn_before (gen_cbranchsi4 (test
,
7886 JUMP_LABEL (insn
) = loop
->start_label
;
7887 LABEL_NUSES (loop
->start_label
)++;
7888 delete_insn (loop
->loop_end
);
7891 /* Return the next insn after INSN that is not a NOTE, but stop the
7892 search before we enter another basic block. This routine does not
7893 look inside SEQUENCEs. */
7896 next_nonnote_insn_bb (rtx_insn
*insn
)
7900 insn
= NEXT_INSN (insn
);
7901 if (insn
== 0 || !NOTE_P (insn
))
7903 if (NOTE_INSN_BASIC_BLOCK_P (insn
))
7910 /* Optimize LOOP. */
7913 hwloop_optimize (hwloop_info loop
)
7917 basic_block entry_bb
, bb
;
7919 rtx_insn
*insn
, *seq
, *entry_after
, *last_insn
, *end_label
;
7920 unsigned int length
;
7921 bool need_fix
= false;
7922 rtx lp_reg
= gen_rtx_REG (SImode
, LP_COUNT
);
7924 if (loop
->depth
> 1)
7927 fprintf (dump_file
, ";; loop %d is not innermost\n",
7932 if (!loop
->incoming_dest
)
7935 fprintf (dump_file
, ";; loop %d has more than one entry\n",
7940 if (loop
->incoming_dest
!= loop
->head
)
7943 fprintf (dump_file
, ";; loop %d is not entered from head\n",
7948 if (loop
->has_call
|| loop
->has_asm
)
7951 fprintf (dump_file
, ";; loop %d has invalid insn\n",
7956 /* Scan all the blocks to make sure they don't use iter_reg. */
7957 if (loop
->iter_reg_used
|| loop
->iter_reg_used_outside
)
7960 fprintf (dump_file
, ";; loop %d uses iterator\n",
7965 /* Check if start_label appears before doloop_end. */
7967 for (insn
= loop
->start_label
;
7968 insn
&& insn
!= loop
->loop_end
;
7969 insn
= NEXT_INSN (insn
))
7971 length
+= NONDEBUG_INSN_P (insn
) ? get_attr_length (insn
) : 0;
7972 if (JUMP_TABLES_IN_TEXT_SECTION
7973 && JUMP_TABLE_DATA_P (insn
))
7976 fprintf (dump_file
, ";; loop %d has a jump table\n",
7985 fprintf (dump_file
, ";; loop %d start_label not before loop_end\n",
7990 loop
->length
= length
;
7991 if (loop
->length
> ARC_MAX_LOOP_LENGTH
)
7994 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
7997 else if (!loop
->length
)
8000 fprintf (dump_file
, ";; loop %d is empty\n", loop
->loop_no
);
8004 /* Check if we use a register or not. */
8005 if (!REG_P (loop
->iter_reg
))
8008 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
8013 /* Check if we use a register or not. */
8014 if (!REG_P (loop
->iter_reg
))
8017 fprintf (dump_file
, ";; loop %d iterator is MEM\n",
8022 /* Check if loop register is lpcount. */
8023 if (REG_P (loop
->iter_reg
) && (REGNO (loop
->iter_reg
)) != LP_COUNT
)
8026 fprintf (dump_file
, ";; loop %d doesn't use lp_count as loop"
8029 /* This loop doesn't use the lp_count, check though if we can
8031 if (TEST_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
)
8032 /* In very unique cases we may have LP_COUNT alive. */
8033 || (loop
->incoming_src
8034 && REGNO_REG_SET_P (df_get_live_out (loop
->incoming_src
),
8038 fprintf (dump_file
, ";; loop %d, lp_count is alive", loop
->loop_no
);
8045 /* Check for control like instruction as the last instruction of a
8048 last_insn
= PREV_INSN (loop
->loop_end
);
8052 for (; last_insn
!= BB_HEAD (bb
);
8053 last_insn
= PREV_INSN (last_insn
))
8054 if (NONDEBUG_INSN_P (last_insn
))
8057 if (last_insn
!= BB_HEAD (bb
))
8060 if (single_pred_p (bb
)
8061 && single_pred_edge (bb
)->flags
& EDGE_FALLTHRU
8062 && single_pred (bb
) != ENTRY_BLOCK_PTR_FOR_FN (cfun
))
8064 bb
= single_pred (bb
);
8065 last_insn
= BB_END (bb
);
8078 fprintf (dump_file
, ";; loop %d has no last instruction\n",
8083 if ((TARGET_ARC600_FAMILY
|| TARGET_HS
)
8084 && INSN_P (last_insn
)
8085 && (JUMP_P (last_insn
) || CALL_P (last_insn
)
8086 || GET_CODE (PATTERN (last_insn
)) == SEQUENCE
8087 /* At this stage we can have (insn (clobber (mem:BLK
8088 (reg)))) instructions, ignore them. */
8089 || (GET_CODE (PATTERN (last_insn
)) != CLOBBER
8090 && (get_attr_type (last_insn
) == TYPE_BRCC
8091 || get_attr_type (last_insn
) == TYPE_BRCC_NO_DELAY_SLOT
))))
8093 if (loop
->length
+ 2 > ARC_MAX_LOOP_LENGTH
)
8096 fprintf (dump_file
, ";; loop %d too long\n", loop
->loop_no
);
8100 fprintf (dump_file
, ";; loop %d has a control like last insn; "
8104 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
8107 if (LABEL_P (last_insn
))
8110 fprintf (dump_file
, ";; loop %d has a label as last insn; "
8113 last_insn
= emit_insn_after (gen_nopv (), last_insn
);
8116 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
8117 and we can use it to indicate the last ZOL instruction cannot be
8118 part of a delay slot. */
8119 add_reg_note (last_insn
, REG_SAVE_NOTE
, GEN_INT (2));
8121 loop
->last_insn
= last_insn
;
8123 /* Get the loop iteration register. */
8124 iter_reg
= loop
->iter_reg
;
8126 gcc_assert (REG_P (iter_reg
));
8130 FOR_EACH_VEC_SAFE_ELT (loop
->incoming
, i
, entry_edge
)
8131 if (entry_edge
->flags
& EDGE_FALLTHRU
)
8134 if (entry_edge
== NULL
)
8137 fprintf (dump_file
, ";; loop %d has no fallthru edge jumping "
8142 /* The loop is good. */
8143 end_label
= gen_label_rtx ();
8144 loop
->end_label
= end_label
;
8146 /* Place the zero_cost_loop_start instruction before the loop. */
8147 entry_bb
= entry_edge
->src
;
8153 /* The loop uses a R-register, but the lp_count is free, thus
8155 emit_insn (gen_rtx_SET (lp_reg
, iter_reg
));
8156 SET_HARD_REG_BIT (loop
->regs_set_in_loop
, LP_COUNT
);
8160 fprintf (dump_file
, ";; fix loop %d to use lp_count\n",
8165 insn
= emit_insn (gen_arc_lp (loop
->start_label
,
8171 entry_after
= BB_END (entry_bb
);
8172 if (!single_succ_p (entry_bb
) || vec_safe_length (loop
->incoming
) > 1
8179 emit_insn_before (seq
, BB_HEAD (loop
->head
));
8180 seq
= emit_label_before (gen_label_rtx (), seq
);
8181 new_bb
= create_basic_block (seq
, insn
, entry_bb
);
8182 FOR_EACH_EDGE (e
, ei
, loop
->incoming
)
8184 if (!(e
->flags
& EDGE_FALLTHRU
))
8185 redirect_edge_and_branch_force (e
, new_bb
);
8187 redirect_edge_succ (e
, new_bb
);
8190 make_edge (new_bb
, loop
->head
, 0);
8195 while (DEBUG_INSN_P (entry_after
)
8196 || (NOTE_P (entry_after
)
8197 && NOTE_KIND (entry_after
) != NOTE_INSN_BASIC_BLOCK
8198 /* Make sure we don't split a call and its corresponding
8199 CALL_ARG_LOCATION note. */
8200 && NOTE_KIND (entry_after
) != NOTE_INSN_CALL_ARG_LOCATION
))
8201 entry_after
= NEXT_INSN (entry_after
);
8203 entry_after
= next_nonnote_insn_bb (entry_after
);
8205 gcc_assert (entry_after
);
8206 emit_insn_before (seq
, entry_after
);
8209 /* Insert the loop end label before the last instruction of the
8211 emit_label_after (end_label
, loop
->last_insn
);
8212 /* Make sure we mark the begining and end label as used. */
8213 LABEL_NUSES (loop
->end_label
)++;
8214 LABEL_NUSES (loop
->start_label
)++;
8219 /* A callback for the hw-doloop pass. This function examines INSN; if
8220 it is a loop_end pattern we recognize, return the reg rtx for the
8221 loop counter. Otherwise, return NULL_RTX. */
8224 hwloop_pattern_reg (rtx_insn
*insn
)
8228 if (!JUMP_P (insn
) || recog_memoized (insn
) != CODE_FOR_loop_end
)
8231 reg
= SET_DEST (XVECEXP (PATTERN (insn
), 0, 1));
8237 static struct hw_doloop_hooks arc_doloop_hooks
=
8244 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8245 and tries to rewrite the RTL of these loops so that proper Blackfin
8246 hardware loops are generated. */
8249 arc_reorg_loops (void)
8251 reorg_loops (true, &arc_doloop_hooks
);
8254 /* Scan all calls and add symbols to be emitted in the jli section if
8258 jli_call_scan (void)
8262 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8267 rtx pat
= PATTERN (insn
);
8268 if (GET_CODE (pat
) == COND_EXEC
)
8269 pat
= COND_EXEC_CODE (pat
);
8270 pat
= XVECEXP (pat
, 0, 0);
8271 if (GET_CODE (pat
) == SET
)
8272 pat
= SET_SRC (pat
);
8274 pat
= XEXP (XEXP (pat
, 0), 0);
8275 if (GET_CODE (pat
) == SYMBOL_REF
8276 && arc_is_jli_call_p (pat
))
8277 arc_add_jli_section (pat
);
8281 /* Add padding if necessary to avoid a mispredict. A return could
8282 happen immediately after the function start. A call/return and
8283 return/return must be 6 bytes apart to avoid mispredict. */
8291 if (!TARGET_PAD_RETURN
)
8294 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8296 rtx_insn
*prev0
= prev_active_insn (insn
);
8297 bool wantlong
= false;
8299 if (!INSN_P (insn
) || GET_CODE (PATTERN (insn
)) != SIMPLE_RETURN
)
8304 prev0
= emit_insn_before (gen_nopv (), insn
);
8305 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8306 so it is safe to reuse it for forcing a particular length
8307 for an instruction. */
8308 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
8309 emit_insn_before (gen_nopv (), insn
);
8312 offset
= get_attr_length (prev0
);
8314 if (get_attr_length (prev0
) == 2
8315 && get_attr_iscompact (prev0
) != ISCOMPACT_TRUE
)
8317 /* Force long version of the insn. */
8322 rtx_insn
*prev
= prev_active_insn (prev0
);
8324 offset
+= get_attr_length (prev
);
8326 prev
= prev_active_insn (prev
);
8328 offset
+= get_attr_length (prev
);
8333 prev
= emit_insn_before (gen_nopv (), insn
);
8334 add_reg_note (prev
, REG_SAVE_NOTE
, GEN_INT (1));
8337 emit_insn_before (gen_nopv (), insn
);
8344 add_reg_note (prev0
, REG_SAVE_NOTE
, GEN_INT (1));
8346 /* Emit a blockage to avoid delay slot scheduling. */
8347 emit_insn_before (gen_blockage (), insn
);
8351 static int arc_reorg_in_progress
= 0;
8353 /* ARC's machince specific reorg function. */
8364 cfun
->machine
->arc_reorg_started
= 1;
8365 arc_reorg_in_progress
= 1;
8367 compute_bb_for_insn ();
8371 /* Doloop optimization. */
8374 workaround_arc_anomaly ();
8378 /* FIXME: should anticipate ccfsm action, generate special patterns for
8379 to-be-deleted branches that have no delay slot and have at least the
8380 length of the size increase forced on other insns that are conditionalized.
8381 This can also have an insn_list inside that enumerates insns which are
8382 not actually conditionalized because the destinations are dead in the
8384 Could also tag branches that we want to be unaligned if they get no delay
8385 slot, or even ones that we don't want to do delay slot sheduling for
8386 because we can unalign them.
8388 However, there are cases when conditional execution is only possible after
8389 delay slot scheduling:
8391 - If a delay slot is filled with a nocond/set insn from above, the previous
8392 basic block can become elegible for conditional execution.
8393 - If a delay slot is filled with a nocond insn from the fall-through path,
8394 the branch with that delay slot can become eligble for conditional
8395 execution (however, with the same sort of data flow analysis that dbr
8396 does, we could have figured out before that we don't need to
8397 conditionalize this insn.)
8398 - If a delay slot insn is filled with an insn from the target, the
8399 target label gets its uses decremented (even deleted if falling to zero),
8400 thus possibly creating more condexec opportunities there.
8401 Therefore, we should still be prepared to apply condexec optimization on
8402 non-prepared branches if the size increase of conditionalized insns is no
8403 more than the size saved from eliminating the branch. An invocation option
8404 could also be used to reserve a bit of extra size for condbranches so that
8405 this'll work more often (could also test in arc_reorg if the block is
8406 'close enough' to be eligible for condexec to make this likely, and
8407 estimate required size increase). */
8408 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8409 if (TARGET_NO_BRCC_SET
)
8414 init_insn_lengths();
8417 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
8420 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
8421 df_finish_pass ((flags
& TODO_df_verify
) != 0);
8425 fprintf (dump_file
, ";; After if conversion:\n\n");
8426 print_rtl (dump_file
, get_insns ());
8430 /* Call shorten_branches to calculate the insn lengths. */
8431 shorten_branches (get_insns());
8432 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
8434 if (!INSN_ADDRESSES_SET_P())
8435 fatal_error (input_location
,
8436 "insn addresses not set after shorten_branches");
8438 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8441 enum attr_type insn_type
;
8443 /* If a non-jump insn (or a casesi jump table), continue. */
8444 if (GET_CODE (insn
) != JUMP_INSN
||
8445 GET_CODE (PATTERN (insn
)) == ADDR_VEC
8446 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
8449 /* If we already have a brcc, note if it is suitable for brcc_s.
8450 Be a bit generous with the brcc_s range so that we can take
8451 advantage of any code shortening from delay slot scheduling. */
8452 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
8454 rtx pat
= PATTERN (insn
);
8455 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
8456 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
8458 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
8459 if ((offset
>= -140 && offset
< 140)
8460 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
8461 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
8462 && equality_comparison_operator (op
, VOIDmode
))
8463 PUT_MODE (*ccp
, CC_Zmode
);
8464 else if (GET_MODE (*ccp
) == CC_Zmode
)
8465 PUT_MODE (*ccp
, CC_ZNmode
);
8468 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
8469 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
8472 /* OK. so we have a jump insn. */
8473 /* We need to check that it is a bcc. */
8474 /* Bcc => set (pc) (if_then_else ) */
8475 pattern
= PATTERN (insn
);
8476 if (GET_CODE (pattern
) != SET
8477 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
8478 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
8481 /* Now check if the jump is beyond the s9 range. */
8482 if (CROSSING_JUMP_P (insn
))
8484 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
8486 if(offset
> 253 || offset
< -254)
8489 pc_target
= SET_SRC (pattern
);
8491 /* Avoid FPU instructions. */
8492 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
8493 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUEmode
)
8494 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
8497 /* Now go back and search for the set cc insn. */
8499 label
= XEXP (pc_target
, 1);
8503 rtx_insn
*scan
, *link_insn
= NULL
;
8505 for (scan
= PREV_INSN (insn
);
8506 scan
&& GET_CODE (scan
) != CODE_LABEL
;
8507 scan
= PREV_INSN (scan
))
8509 if (! INSN_P (scan
))
8511 pat
= PATTERN (scan
);
8512 if (GET_CODE (pat
) == SET
8513 && cc_register (SET_DEST (pat
), VOIDmode
))
8523 /* Check if this is a data dependency. */
8524 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
8527 /* Make sure we can use it for brcc insns. */
8528 if (find_reg_note (link_insn
, REG_SAVE_NOTE
, GEN_INT (3)))
8531 /* Ok this is the set cc. copy args here. */
8532 op
= XEXP (pc_target
, 0);
8534 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
8535 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
8536 if (GET_CODE (op0
) == ZERO_EXTRACT
8537 && XEXP (op0
, 1) == const1_rtx
8538 && (GET_CODE (op
) == EQ
8539 || GET_CODE (op
) == NE
))
8541 /* btst / b{eq,ne} -> bbit{0,1} */
8542 op0
= XEXP (cmp0
, 0);
8543 op1
= XEXP (cmp0
, 2);
8545 else if (!register_operand (op0
, VOIDmode
)
8546 || !general_operand (op1
, VOIDmode
))
8548 /* Be careful not to break what cmpsfpx_raw is
8549 trying to create for checking equality of
8550 single-precision floats. */
8551 else if (TARGET_SPFP
8552 && GET_MODE (op0
) == SFmode
8553 && GET_MODE (op1
) == SFmode
)
8556 /* None of the two cmp operands should be set between the
8557 cmp and the branch. */
8558 if (reg_set_between_p (op0
, link_insn
, insn
))
8561 if (reg_set_between_p (op1
, link_insn
, insn
))
8564 /* Since the MODE check does not work, check that this is
8565 CC reg's last set location before insn, and also no
8566 instruction between the cmp and branch uses the
8568 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
8569 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
8572 /* CC reg should be dead after insn. */
8573 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
8576 op
= gen_rtx_fmt_ee (GET_CODE (op
),
8577 GET_MODE (op
), cmp0
, cmp1
);
8578 /* If we create a LIMM where there was none before,
8579 we only benefit if we can avoid a scheduling bubble
8580 for the ARC600. Otherwise, we'd only forgo chances
8581 at short insn generation, and risk out-of-range
8583 if (!brcc_nolimm_operator (op
, VOIDmode
)
8584 && !long_immediate_operand (op1
, VOIDmode
)
8586 || (TARGET_V2
&& optimize_size
)
8587 || next_active_insn (link_insn
) != insn
))
8590 /* Emit bbit / brcc (or brcc_s if possible).
8591 CC_Zmode indicates that brcc_s is possible. */
8594 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
8595 else if ((offset
>= -140 && offset
< 140)
8596 && rtx_equal_p (op1
, const0_rtx
)
8597 && compact_register_operand (op0
, VOIDmode
)
8598 && (GET_CODE (op
) == EQ
8599 || GET_CODE (op
) == NE
))
8600 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
8602 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
8605 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
8606 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
8607 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
8610 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
8611 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
8613 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
8614 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
8617 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8618 REG_NOTES (brcc_insn
) = note
;
8620 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
8623 remove_note (link_insn
, note
);
8624 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8625 REG_NOTES (brcc_insn
) = note
;
8627 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
8630 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
8631 REG_NOTES (brcc_insn
) = note
;
8636 /* Delete the bcc insn. */
8637 set_insn_deleted (insn
);
8639 /* Delete the cmp insn. */
8640 set_insn_deleted (link_insn
);
8645 /* Clear out insn_addresses. */
8646 INSN_ADDRESSES_FREE ();
8650 if (INSN_ADDRESSES_SET_P())
8651 fatal_error (input_location
, "insn addresses not freed");
8653 arc_reorg_in_progress
= 0;
8656 /* Check if the operands are valid for BRcc.d generation
8657 Valid Brcc.d patterns are
8661 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
8662 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8663 does not have a delay slot
8665 Assumed precondition: Second operand is either a register or a u6 value. */
8668 valid_brcc_with_delay_p (rtx
*operands
)
8670 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
8672 return brcc_nolimm_operator (operands
[0], VOIDmode
);
8675 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8676 access DECL using %gp_rel(...)($gp). */
8679 arc_in_small_data_p (const_tree decl
)
8684 /* Only variables are going into small data area. */
8685 if (TREE_CODE (decl
) != VAR_DECL
)
8688 if (TARGET_NO_SDATA_SET
)
8691 /* Disable sdata references to weak variables. */
8692 if (DECL_WEAK (decl
))
8695 /* Don't put constants into the small data section: we want them to
8696 be in ROM rather than RAM. */
8697 if (TREE_READONLY (decl
))
8700 /* To ensure -mvolatile-cache works ld.di does not have a
8701 gp-relative variant. */
8702 if (!TARGET_VOLATILE_CACHE_SET
8703 && TREE_THIS_VOLATILE (decl
))
8706 /* Likewise for uncached data. */
8707 attr
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
8708 if (lookup_attribute ("uncached", attr
))
8711 /* and for aux regs. */
8712 attr
= DECL_ATTRIBUTES (decl
);
8713 if (lookup_attribute ("aux", attr
))
8716 if (DECL_SECTION_NAME (decl
) != 0)
8718 const char *name
= DECL_SECTION_NAME (decl
);
8719 if (strcmp (name
, ".sdata") == 0
8720 || strcmp (name
, ".sbss") == 0)
8723 /* If it's not public, there's no need to put it in the small data
8725 else if (TREE_PUBLIC (decl
))
8727 size
= int_size_in_bytes (TREE_TYPE (decl
));
8728 return (size
> 0 && size
<= g_switch_value
);
8733 /* Return true if OP is an acceptable memory operand for ARCompact
8734 16-bit gp-relative load instructions.
8736 /* volatile cache option still to be handled. */
8739 compact_sda_memory_operand (rtx op
, machine_mode mode
, bool short_p
)
8746 /* Eliminate non-memory operations. */
8747 if (GET_CODE (op
) != MEM
)
8750 if (mode
== VOIDmode
)
8751 mode
= GET_MODE (op
);
8753 size
= GET_MODE_SIZE (mode
);
8755 /* dword operations really put out 2 instructions, so eliminate them. */
8756 if (size
> UNITS_PER_WORD
)
8759 /* Decode the address now. */
8760 addr
= XEXP (op
, 0);
8762 if (!legitimate_small_data_address_p (addr
, mode
))
8765 if (!short_p
|| size
== 1)
8768 /* Now check for the alignment, the short loads using gp require the
8769 addresses to be aligned. */
8770 align
= get_symbol_alignment (addr
);
8781 if (align
&& ((align
& mask
) == 0))
8786 /* Return TRUE if PAT is accessing an aux-reg. */
8789 arc_is_aux_reg_p (rtx pat
)
8791 tree attrs
= NULL_TREE
;
8797 /* Get the memory attributes. */
8798 addr
= MEM_EXPR (pat
);
8802 /* Get the attributes. */
8803 if (TREE_CODE (addr
) == VAR_DECL
)
8804 attrs
= DECL_ATTRIBUTES (addr
);
8805 else if (TREE_CODE (addr
) == MEM_REF
)
8806 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
8810 if (lookup_attribute ("aux", attrs
))
8815 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8818 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
8819 unsigned HOST_WIDE_INT size
,
8820 unsigned HOST_WIDE_INT align
,
8821 unsigned HOST_WIDE_INT globalize_p
)
8823 int in_small_data
= arc_in_small_data_p (decl
);
8824 rtx mem
= decl
== NULL_TREE
? NULL_RTX
: DECL_RTL (decl
);
8826 /* Don't output aux-reg symbols. */
8827 if (mem
!= NULL_RTX
&& MEM_P (mem
)
8828 && SYMBOL_REF_P (XEXP (mem
, 0))
8829 && arc_is_aux_reg_p (mem
))
8833 switch_to_section (get_named_section (NULL
, ".sbss", 0));
8834 /* named_section (0,".sbss",0); */
8836 switch_to_section (bss_section
);
8839 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
8841 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
8842 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
8843 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
8844 ASM_OUTPUT_LABEL (stream
, name
);
8847 ASM_OUTPUT_SKIP (stream
, size
);
8851 arc_preserve_reload_p (rtx in
)
8853 return (GET_CODE (in
) == PLUS
8854 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
8855 && CONST_INT_P (XEXP (in
, 1))
8856 && !((INTVAL (XEXP (in
, 1)) & 511)));
8859 /* Implement TARGET_REGISTER_MOVE_COST. */
8862 arc_register_move_cost (machine_mode
,
8863 reg_class_t from_class
, reg_class_t to_class
)
8865 /* Force an attempt to 'mov Dy,Dx' to spill. */
8866 if ((TARGET_ARC700
|| TARGET_EM
) && TARGET_DPFP
8867 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
8873 /* Emit code for an addsi3 instruction with OPERANDS.
8874 COND_P indicates if this will use conditional execution.
8875 Return the length of the instruction.
8876 If OUTPUT_P is false, don't actually output the instruction, just return
8879 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
8883 int match
= operands_match_p (operands
[0], operands
[1]);
8884 int match2
= operands_match_p (operands
[0], operands
[2]);
8885 int intval
= (REG_P (operands
[2]) ? 1
8886 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
8887 int neg_intval
= -intval
;
8888 int short_0
= satisfies_constraint_Rcq (operands
[0]);
8889 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
8892 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8893 && REGNO (OP) != 30) \
8896 #define ADDSI_OUTPUT1(FORMAT) do {\
8898 output_asm_insn (FORMAT, operands);\
8901 #define ADDSI_OUTPUT(LIST) do {\
8904 ADDSI_OUTPUT1 (format);\
8908 /* First try to emit a 16 bit insn. */
8911 /* If we are actually about to output this insn, don't try a 16 bit
8912 variant if we already decided that we don't want that
8913 (I.e. we upsized this insn to align some following insn.)
8914 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8915 but add1 r0,sp,35 doesn't. */
8916 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
8918 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8921 && ((REG_H_P (operands
[2])
8922 && (match
|| satisfies_constraint_Rcq (operands
[2])))
8923 || (CONST_INT_P (operands
[2])
8924 && ((unsigned) intval
<= (match
? 127 : 7)))))
8925 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8927 /* Generate add_s b,b,h patterns. */
8928 if (short_0
&& match2
&& REG_H_P (operands
[1]))
8929 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8931 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8932 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
8933 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
8934 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8936 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
8937 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
8938 && match
&& !(neg_intval
& ~124)))
8939 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8941 /* Generate add_s h,h,s3 patterns. */
8942 if (REG_H_P (operands
[0]) && match
&& TARGET_V2
8943 && CONST_INT_P (operands
[2]) && ((intval
>= -1) && (intval
<= 6)))
8944 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8946 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8947 if (TARGET_CODE_DENSITY
&& REG_P (operands
[0]) && REG_P (operands
[1])
8948 && ((REGNO (operands
[0]) == 0) || (REGNO (operands
[0]) == 1))
8949 && satisfies_constraint_Rcq (operands
[1])
8950 && satisfies_constraint_L (operands
[2]))
8951 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8954 /* Now try to emit a 32 bit insn without long immediate. */
8956 if (!match
&& match2
&& REG_P (operands
[1]))
8957 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8958 if (match
|| !cond_p
)
8960 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
8961 int range_factor
= neg_intval
& intval
;
8964 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
8965 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8967 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8968 same size, do, so - the insn latency is lower. */
8969 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8971 if ((intval
>= 0 && intval
<= limit
)
8972 || (intval
== -0x800 && limit
== 0x7ff))
8973 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8974 else if ((intval
< 0 && neg_intval
<= limit
)
8975 || (intval
== 0x800 && limit
== 0x7ff))
8976 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8977 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
8978 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
8979 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
8980 if (((intval
< 0 && intval
!= -0x4000)
8981 /* sub[123] is slower than add_s / sub, only use it if it
8982 avoids a long immediate. */
8983 && neg_intval
<= limit
<< shift
)
8984 || (intval
== 0x4000 && limit
== 0x7ff))
8985 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
8986 shift
, neg_intval
>> shift
));
8987 else if ((intval
>= 0 && intval
<= limit
<< shift
)
8988 || (intval
== -0x4000 && limit
== 0x7ff))
8989 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
8991 /* Try to emit a 16 bit opcode with long immediate. */
8993 if (short_p
&& match
)
8994 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8996 /* We have to use a 32 bit opcode, and with a long immediate. */
8998 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
9001 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
9002 Return the length of the instruction.
9003 If OUTPUT_P is false, don't actually output the instruction, just return
9006 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
9008 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
9009 const char *pat
= NULL
;
9011 /* Canonical rtl should not have a constant in the first operand position. */
9012 gcc_assert (!CONSTANT_P (operands
[1]));
9014 switch (commutative_op
)
9017 if (satisfies_constraint_C1p (operands
[2]))
9018 pat
= "bmsk%? %0,%1,%Z2";
9019 else if (satisfies_constraint_C2p (operands
[2]))
9021 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
9022 pat
= "bmskn%? %0,%1,%Z2";
9024 else if (satisfies_constraint_Ccp (operands
[2]))
9025 pat
= "bclr%? %0,%1,%M2";
9026 else if (satisfies_constraint_CnL (operands
[2]))
9027 pat
= "bic%? %0,%1,%n2-1";
9030 if (satisfies_constraint_C0p (operands
[2]))
9031 pat
= "bset%? %0,%1,%z2";
9034 if (satisfies_constraint_C0p (operands
[2]))
9035 pat
= "bxor%? %0,%1,%z2";
9038 return arc_output_addsi (operands
, true, output_p
);
9042 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
9043 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
9048 /* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
9049 Emit code and return an potentially modified address such that offsets
9050 up to SIZE are can be added to yield a legitimate address.
9051 if REUSE is set, ADDR is a register that may be modified. */
9054 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
9057 rtx offs
= const0_rtx
;
9059 if (GET_CODE (base
) == PLUS
)
9061 offs
= XEXP (base
, 1);
9062 base
= XEXP (base
, 0);
9065 || (REGNO (base
) != STACK_POINTER_REGNUM
9066 && REGNO_PTR_FRAME_P (REGNO (base
)))
9067 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
9068 || !SMALL_INT (INTVAL (offs
) + size
))
9071 emit_insn (gen_add2_insn (addr
, offs
));
9073 addr
= copy_to_mode_reg (Pmode
, addr
);
9078 /* Like move_by_pieces, but take account of load latency, and actual
9079 offset ranges. Return true on success. */
9082 arc_expand_cpymem (rtx
*operands
)
9084 rtx dst
= operands
[0];
9085 rtx src
= operands
[1];
9086 rtx dst_addr
, src_addr
;
9088 int align
= INTVAL (operands
[3]);
9095 if (!CONST_INT_P (operands
[2]))
9097 size
= INTVAL (operands
[2]);
9098 /* move_by_pieces_ninsns is static, so we can't use it. */
9102 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
9104 n_pieces
= (size
+ 2) / 4U + (size
& 1);
9106 else if (align
== 2)
9107 n_pieces
= (size
+ 1) / 2U;
9110 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
9112 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
9114 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
9118 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
9119 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
9120 store
[0] = store
[1] = NULL_RTX
;
9121 tmpx
[0] = tmpx
[1] = NULL_RTX
;
9122 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
9127 while (piece
> size
)
9129 mode
= smallest_int_mode_for_size (piece
* BITS_PER_UNIT
);
9130 /* If we don't re-use temporaries, the scheduler gets carried away,
9131 and the register pressure gets unnecessarily high. */
9132 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
9135 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
9136 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
9137 src_addr
= force_offsettable (src_addr
, piece
, 1);
9139 emit_insn (store
[i
]);
9140 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
9141 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
9142 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
9143 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
9146 emit_insn (store
[i
]);
9148 emit_insn (store
[i
^1]);
9153 arc_get_aux_arg (rtx pat
, int *auxr
)
9155 tree attr
, addr
= MEM_EXPR (pat
);
9156 if (TREE_CODE (addr
) != VAR_DECL
)
9159 attr
= DECL_ATTRIBUTES (addr
);
9160 if (lookup_attribute ("aux", attr
))
9162 tree arg
= TREE_VALUE (attr
);
9165 *auxr
= TREE_INT_CST_LOW (TREE_VALUE (arg
));
9173 /* Prepare operands for move in MODE. Return true iff the move has
9177 prepare_move_operands (rtx
*operands
, machine_mode mode
)
9179 if ((MEM_P (operands
[0]) || MEM_P (operands
[1]))
9180 && SCALAR_INT_MODE_P (mode
))
9182 /* First handle aux attribute. */
9187 if (MEM_P (operands
[0]) && arc_is_aux_reg_p (operands
[0]))
9189 /* Save operation. */
9190 if (arc_get_aux_arg (operands
[0], &auxr
))
9192 tmp
= gen_reg_rtx (SImode
);
9193 emit_move_insn (tmp
, GEN_INT (auxr
));
9196 tmp
= XEXP (operands
[0], 0);
9198 operands
[1] = force_reg (SImode
, operands
[1]);
9199 emit_insn (gen_rtx_UNSPEC_VOLATILE
9200 (VOIDmode
, gen_rtvec (2, operands
[1], tmp
),
9204 if (MEM_P (operands
[1]) && arc_is_aux_reg_p (operands
[1]))
9206 if (arc_get_aux_arg (operands
[1], &auxr
))
9208 tmp
= gen_reg_rtx (SImode
);
9209 emit_move_insn (tmp
, GEN_INT (auxr
));
9213 tmp
= XEXP (operands
[1], 0);
9214 gcc_assert (GET_CODE (tmp
) == SYMBOL_REF
);
9216 /* Load operation. */
9217 gcc_assert (REG_P (operands
[0]));
9218 emit_insn (gen_rtx_SET (operands
[0],
9219 gen_rtx_UNSPEC_VOLATILE
9220 (SImode
, gen_rtvec (1, tmp
),
9225 /* Second, we check for the uncached. */
9226 if (arc_is_uncached_mem_p (operands
[0]))
9228 if (!REG_P (operands
[1]))
9229 operands
[1] = force_reg (mode
, operands
[1]);
9230 emit_insn (gen_rtx_UNSPEC_VOLATILE
9231 (VOIDmode
, gen_rtvec (2, operands
[0], operands
[1]),
9235 if (arc_is_uncached_mem_p (operands
[1]))
9237 rtx tmp
= operands
[0];
9239 if (MEM_P (operands
[0]))
9240 tmp
= gen_reg_rtx (mode
);
9242 emit_insn (gen_rtx_SET
9244 gen_rtx_UNSPEC_VOLATILE
9245 (mode
, gen_rtvec (1, operands
[1]),
9246 VUNSPEC_ARC_LDDI
)));
9247 if (MEM_P (operands
[0]))
9256 if (GET_CODE (operands
[1]) == SYMBOL_REF
)
9258 enum tls_model model
= SYMBOL_REF_TLS_MODEL (operands
[1]);
9259 if (MEM_P (operands
[0]))
9260 operands
[1] = force_reg (mode
, operands
[1]);
9262 operands
[1] = arc_legitimize_tls_address (operands
[1], model
);
9265 operands
[1] = arc_legitimize_pic_address (operands
[1]);
9267 /* Store instructions are limited, they only accept as address an
9268 immediate, a register or a register plus a small immediate. */
9269 if (MEM_P (operands
[0])
9270 && !move_dest_operand (operands
[0], mode
))
9272 rtx tmp0
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
9273 rtx tmp1
= change_address (operands
[0], mode
, tmp0
);
9274 MEM_COPY_ATTRIBUTES (tmp1
, operands
[0]);
9278 /* Check if it is constant but it is not legitimized. */
9279 if (CONSTANT_P (operands
[1])
9280 && !arc_legitimate_constant_p (mode
, operands
[1]))
9281 operands
[1] = force_reg (mode
, XEXP (operands
[1], 0));
9282 else if (MEM_P (operands
[0])
9283 && ((CONSTANT_P (operands
[1])
9284 && !satisfies_constraint_Cm3 (operands
[1]))
9285 || MEM_P (operands
[1])))
9286 operands
[1] = force_reg (mode
, operands
[1]);
9291 /* Output a library call to a function called FNAME that has been arranged
9292 to be local to any dso. */
9295 arc_output_libcall (const char *fname
)
9297 unsigned len
= strlen (fname
);
9298 static char buf
[64];
9300 gcc_assert (len
< sizeof buf
- 35);
9301 if (TARGET_LONG_CALLS_SET
9302 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
9305 sprintf (buf
, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname
);
9307 sprintf (buf
, "jl%%! @%s", fname
);
9310 sprintf (buf
, "bl%%!%%* @%s", fname
);
9314 /* Return the SImode highpart of the DImode value IN. */
9317 disi_highpart (rtx in
)
9319 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
9322 /* Return length adjustment for INSN.
9324 A write to a core reg greater or equal to 32 must not be immediately
9325 followed by a use. Anticipate the length requirement to insert a nop
9326 between PRED and SUCC to prevent a hazard. */
9329 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
9333 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
9334 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
9335 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
9336 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
9337 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
9338 || recog_memoized (pred
) == CODE_FOR_umul_600
9339 || recog_memoized (pred
) == CODE_FOR_mac_600
9340 || recog_memoized (pred
) == CODE_FOR_mul64_600
9341 || recog_memoized (pred
) == CODE_FOR_mac64_600
9342 || recog_memoized (pred
) == CODE_FOR_umul64_600
9343 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
9345 subrtx_iterator::array_type array
;
9346 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
9348 const_rtx x
= *iter
;
9349 switch (GET_CODE (x
))
9351 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9354 /* This is also fine for PRE/POST_MODIFY, because they
9358 rtx dest
= XEXP (x
, 0);
9359 /* Check if this sets an extension register. N.B. we use 61 for the
9360 condition codes, which is definitely not an extension register. */
9361 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
9362 /* Check if the same register is used by the PAT. */
9363 && (refers_to_regno_p
9365 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
9366 PATTERN (succ
), 0)))
9372 /* Given a rtx, check if it is an assembly instruction or not. */
9375 arc_asm_insn_p (rtx x
)
9382 switch (GET_CODE (x
))
9389 return arc_asm_insn_p (SET_SRC (x
));
9393 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
9394 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
9407 A write to a core reg greater or equal to 32 must not be immediately
9408 followed by a use. Anticipate the length requirement to insert a nop
9409 between PRED and SUCC to prevent a hazard. */
9412 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
9414 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
9418 return arc600_corereg_hazard (pred
, succ
);
9423 /* Return length adjustment for INSN. */
9426 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
9430 /* We already handle sequences by ignoring the delay sequence flag. */
9431 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9434 /* Check for return with but one preceding insn since function
9436 if (TARGET_PAD_RETURN
9438 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
9439 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
9440 && get_attr_type (insn
) == TYPE_RETURN
)
9442 rtx_insn
*prev
= prev_active_insn (insn
);
9444 if (!prev
|| !(prev
= prev_active_insn (prev
))
9445 || ((NONJUMP_INSN_P (prev
)
9446 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
9447 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
9449 : CALL_ATTR (prev
, NON_SIBCALL
)))
9454 rtx_insn
*succ
= next_real_insn (insn
);
9456 /* One the ARC600, a write to an extension register must be separated
9458 if (succ
&& INSN_P (succ
))
9459 len
+= arc600_corereg_hazard (insn
, succ
);
9462 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9464 extract_constrain_insn_cached (insn
);
9469 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
9470 CC field of *STATEP. */
9473 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
9475 rtx cond
= statep
->cond
;
9476 int raw_cc
= get_arc_condition_code (cond
);
9478 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
9480 if (statep
->cc
== raw_cc
)
9481 return copy_rtx (cond
);
9483 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
9485 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9486 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9487 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9488 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9490 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9491 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
9494 /* Return version of PAT conditionalized with COND, which is part of INSN.
9495 ANNULLED indicates if INSN is an annulled delay-slot insn.
9496 Register further changes if necessary. */
9498 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
9500 /* For commutative operators, we generally prefer to have
9501 the first source match the destination. */
9502 if (GET_CODE (pat
) == SET
)
9504 rtx src
= SET_SRC (pat
);
9506 if (COMMUTATIVE_P (src
))
9508 rtx src0
= XEXP (src
, 0);
9509 rtx src1
= XEXP (src
, 1);
9510 rtx dst
= SET_DEST (pat
);
9512 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
9513 /* Leave add_n alone - the canonical form is to
9514 have the complex summand first. */
9516 pat
= gen_rtx_SET (dst
,
9517 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
9522 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
9523 what to do with COND_EXEC. */
9524 if (RTX_FRAME_RELATED_P (insn
))
9526 /* If this is the delay slot insn of an anulled branch,
9527 dwarf2out.c:scan_trace understands the anulling semantics
9528 without the COND_EXEC. */
9529 gcc_assert (annulled
);
9530 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
9532 validate_change (insn
, ®_NOTES (insn
), note
, 1);
9534 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
9538 /* Use the ccfsm machinery to do if conversion. */
9543 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
9545 memset (statep
, 0, sizeof *statep
);
9546 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
9548 arc_ccfsm_advance (insn
, statep
);
9550 switch (statep
->state
)
9556 /* Deleted branch. */
9557 arc_ccfsm_post_advance (insn
, statep
);
9558 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
9559 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
9560 if (GET_CODE (PATTERN (seq
)) == SEQUENCE
)
9562 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
9563 rtx pat
= PATTERN (slot
);
9564 if (INSN_ANNULLED_BRANCH_P (insn
))
9567 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
9568 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
9570 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
9572 PUT_CODE (slot
, NOTE
);
9573 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
9577 set_insn_deleted (insn
);
9583 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
9585 arc_ccfsm_post_advance (insn
, statep
);
9586 if (--LABEL_NUSES (insn
) == 0)
9592 if (!NONDEBUG_INSN_P (insn
))
9595 /* Conditionalized insn. */
9597 rtx_insn
*prev
, *pprev
;
9598 rtx
*patp
, pat
, cond
;
9599 bool annulled
; annulled
= false;
9601 /* If this is a delay slot insn in a non-annulled branch,
9602 don't conditionalize it. N.B., this should be fine for
9603 conditional return too. However, don't do this for
9604 unconditional branches, as these would be encountered when
9605 processing an 'else' part. */
9606 prev
= PREV_INSN (insn
);
9607 pprev
= PREV_INSN (prev
);
9608 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
9609 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
9611 if (!INSN_ANNULLED_BRANCH_P (prev
))
9616 patp
= &PATTERN (insn
);
9618 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
9619 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
9621 /* ??? don't conditionalize if all side effects are dead
9622 in the not-execute case. */
9624 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
9626 else if (simplejump_p (insn
))
9628 patp
= &SET_SRC (pat
);
9629 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
9631 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
9633 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
9634 pat
= gen_rtx_SET (pc_rtx
, pat
);
9638 validate_change (insn
, patp
, pat
, 1);
9639 if (!apply_change_group ())
9643 rtx_insn
*next
= next_nonnote_insn (insn
);
9644 if (GET_CODE (next
) == BARRIER
)
9646 if (statep
->state
== 3)
9653 arc_ccfsm_post_advance (insn
, statep
);
9658 /* Find annulled delay insns and convert them to use the appropriate predicate.
9659 This allows branch shortening to size up these insns properly. */
9662 arc_predicate_delay_insns (void)
9664 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
9666 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
9669 if (!NONJUMP_INSN_P (insn
)
9670 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
9672 jump
= XVECEXP (pat
, 0, 0);
9673 dlay
= XVECEXP (pat
, 0, 1);
9674 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
9676 /* If the branch insn does the annulling, leave the delay insn alone. */
9677 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
9679 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9680 on the other path. */
9681 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
9682 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
9683 src
= SET_SRC (PATTERN (jump
));
9684 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
9685 cond
= XEXP (src
, 0);
9686 if (XEXP (src
, 2) == pc_rtx
)
9688 else if (XEXP (src
, 1) == pc_rtx
)
9692 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
9694 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
9695 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
9696 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
9697 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
9699 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
9700 copy_rtx (XEXP (cond
, 0)),
9701 copy_rtx (XEXP (cond
, 1)));
9704 cond
= copy_rtx (cond
);
9705 patp
= &PATTERN (dlay
);
9707 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
9708 validate_change (dlay
, patp
, pat
, 1);
9709 if (!apply_change_group ())
9715 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9716 (other than of a forward brcc), it creates a hazard when there is a read
9717 of the same register at the branch target. We can't know what is at the
9718 branch target of calls, and for branches, we don't really know before the
9719 end of delay slot scheduling, either. Not only can individual instruction
9720 be hoisted out into a delay slot, a basic block can also be emptied this
9721 way, and branch and/or fall through targets be redirected. Hence we don't
9722 want such writes in a delay slot. */
9724 /* Return nonzreo iff INSN writes to an extension core register. */
9727 arc_write_ext_corereg (rtx insn
)
9729 subrtx_iterator::array_type array
;
9730 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
9732 const_rtx x
= *iter
;
9733 switch (GET_CODE (x
))
9735 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
9738 /* This is also fine for PRE/POST_MODIFY, because they
9742 const_rtx dest
= XEXP (x
, 0);
9743 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
9749 /* This is like the hook, but returns NULL when it can't / won't generate
9750 a legitimate address. */
9753 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
9759 if (GET_CODE (addr
) == CONST
)
9760 addr
= XEXP (addr
, 0);
9762 if (GET_CODE (addr
) == PLUS
9763 && CONST_INT_P (XEXP (addr
, 1))
9764 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
9765 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
9766 || (REG_P (XEXP (addr
, 0))
9767 && (INTVAL (XEXP (addr
, 1)) & 252))))
9769 HOST_WIDE_INT offs
, upper
;
9770 int size
= GET_MODE_SIZE (mode
);
9772 offs
= INTVAL (XEXP (addr
, 1));
9773 upper
= (offs
+ 256 * size
) & ~511 * size
;
9774 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
9775 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9776 if (GET_CODE (x
) == CONST
)
9777 inner
= gen_rtx_CONST (Pmode
, inner
);
9779 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
9782 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
9783 x
= force_reg (Pmode
, x
);
9784 if (memory_address_p ((machine_mode
) mode
, x
))
9790 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
9792 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
9800 arc_delegitimize_address_0 (rtx op
)
9802 switch (GET_CODE (op
))
9805 return arc_delegitimize_address_0 (XEXP (op
, 0));
9808 switch (XINT (op
, 1))
9810 case ARC_UNSPEC_GOT
:
9811 case ARC_UNSPEC_GOTOFFPC
:
9812 return XVECEXP (op
, 0, 0);
9820 rtx t1
= arc_delegitimize_address_0 (XEXP (op
, 0));
9821 rtx t2
= XEXP (op
, 1);
9824 return gen_rtx_PLUS (GET_MODE (op
), t1
, t2
);
9835 arc_delegitimize_address (rtx orig_x
)
9842 x
= arc_delegitimize_address_0 (x
);
9847 x
= replace_equiv_address_nv (orig_x
, x
);
9851 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9852 differ from the hardware register number in order to allow the generic
9853 code to correctly split the concatenation of acc1 and acc2. */
9858 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
9861 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9862 differ from the hardware register number in order to allow the generic
9863 code to correctly split the concatenation of acc1 and acc2. */
9868 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
9871 /* FIXME: a parameter should be added, and code added to final.c,
9872 to reproduce this functionality in shorten_branches. */
9874 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9875 a previous instruction. */
9877 arc_unalign_branch_p (rtx branch
)
9881 if (!TARGET_UNALIGN_BRANCH
)
9883 /* Do not do this if we have a filled delay slot. */
9884 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
9885 && !NEXT_INSN (branch
)->deleted ())
9887 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
9889 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
9890 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
9894 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9895 are three reasons why we need to consider branches to be length 6:
9896 - annull-false delay slot insns are implemented using conditional execution,
9897 thus preventing short insn formation where used.
9898 - for ARC600: annul-true delay slot insns are implemented where possible
9899 using conditional execution, preventing short insn formation where used.
9900 - for ARC700: likely or somewhat likely taken branches are made long and
9901 unaligned if possible to avoid branch penalty. */
9904 arc_branch_size_unknown_p (void)
9906 return !optimize_size
&& arc_reorg_in_progress
;
9909 /* The usual; we set up our machine_function data. */
9911 static struct machine_function
*
9912 arc_init_machine_status (void)
9914 struct machine_function
*machine
;
9915 machine
= ggc_cleared_alloc
<machine_function
> ();
9916 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
9921 /* Implements INIT_EXPANDERS. We just set up to call the above
9925 arc_init_expanders (void)
9927 init_machine_status
= arc_init_machine_status
;
9930 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9931 indicates a number of elements to ignore - that allows to have a
9932 sibcall pattern that starts with (return). LOAD_P is zero for store
9933 multiple (for prologues), and one for load multiples (for epilogues),
9934 and two for load multiples where no final clobber of blink is required.
9935 We also skip the first load / store element since this is supposed to
9936 be checked in the instruction pattern. */
9939 arc_check_millicode (rtx op
, int offset
, int load_p
)
9941 int len
= XVECLEN (op
, 0) - offset
;
9946 if (len
< 2 || len
> 13)
9952 rtx elt
= XVECEXP (op
, 0, --len
);
9954 if (GET_CODE (elt
) != CLOBBER
9955 || !REG_P (XEXP (elt
, 0))
9956 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
9957 || len
< 3 || len
> 13)
9960 for (i
= 1; i
< len
; i
++)
9962 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
9965 if (GET_CODE (elt
) != SET
)
9967 mem
= XEXP (elt
, load_p
);
9968 reg
= XEXP (elt
, 1-load_p
);
9969 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
9971 addr
= XEXP (mem
, 0);
9972 if (GET_CODE (addr
) != PLUS
9973 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
9974 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
9980 /* Accessor functions for cfun->machine->unalign. */
9983 arc_clear_unalign (void)
9986 cfun
->machine
->unalign
= 0;
9990 arc_toggle_unalign (void)
9992 cfun
->machine
->unalign
^= 2;
9995 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9996 constant in operand 2, but which would require a LIMM because of
9998 operands 3 and 4 are new SET_SRCs for operands 0. */
10001 split_addsi (rtx
*operands
)
10003 int val
= INTVAL (operands
[2]);
10005 /* Try for two short insns first. Lengths being equal, we prefer
10006 expansions with shorter register lifetimes. */
10007 if (val
> 127 && val
<= 255
10008 && satisfies_constraint_Rcq (operands
[0]))
10010 operands
[3] = operands
[2];
10011 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
10015 operands
[3] = operands
[1];
10016 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
10020 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
10021 constant in operand 1, but which would require a LIMM because of
10023 operands 3 and 4 are new SET_SRCs for operands 0. */
10026 split_subsi (rtx
*operands
)
10028 int val
= INTVAL (operands
[1]);
10030 /* Try for two short insns first. Lengths being equal, we prefer
10031 expansions with shorter register lifetimes. */
10032 if (satisfies_constraint_Rcq (operands
[0])
10033 && satisfies_constraint_Rcq (operands
[2]))
10035 if (val
>= -31 && val
<= 127)
10037 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
10038 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
10041 else if (val
>= 0 && val
< 255)
10043 operands
[3] = operands
[1];
10044 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
10048 /* If the destination is not an ARCompact16 register, we might
10049 still have a chance to make a short insn if the source is;
10050 we need to start with a reg-reg move for this. */
10051 operands
[3] = operands
[2];
10052 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
10055 /* Handle DOUBLE_REGS uses.
10056 Operand 0: destination register
10057 Operand 1: source register */
10060 arc_process_double_reg_moves (rtx
*operands
)
10062 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
10063 enum usesDxState state
= none
;
10064 rtx dest
= operands
[0];
10065 rtx src
= operands
[1];
10067 if (refers_to_regno_p (40, 44, src
, 0))
10070 gcc_assert (REG_P (dest
));
10072 if (refers_to_regno_p (40, 44, dest
, 0))
10074 /* Via arc_register_move_cost, we should never see D,D moves. */
10075 gcc_assert (REG_P (src
));
10076 gcc_assert (state
== none
);
10083 if (state
== srcDx
)
10085 /* Without the LR insn, we need to split this into a
10086 sequence of insns which will use the DEXCLx and DADDHxy
10087 insns to be able to read the Dx register in question. */
10088 if (TARGET_DPFP_DISABLE_LRSR
)
10090 /* gen *movdf_insn_nolrsr */
10091 rtx set
= gen_rtx_SET (dest
, src
);
10092 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
10093 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
10097 /* When we have 'mov D, r' or 'mov D, D' then get the target
10098 register pair for use with LR insn. */
10099 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
10100 TARGET_BIG_ENDIAN
? 0 : 4);
10101 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
10102 TARGET_BIG_ENDIAN
? 4 : 0);
10104 /* Produce the two LR insns to get the high and low parts. */
10105 emit_insn (gen_rtx_SET (destHigh
,
10106 gen_rtx_UNSPEC_VOLATILE (Pmode
,
10107 gen_rtvec (1, src
),
10108 VUNSPEC_ARC_LR_HIGH
)));
10109 emit_insn (gen_rtx_SET (destLow
,
10110 gen_rtx_UNSPEC_VOLATILE (Pmode
,
10111 gen_rtvec (1, src
),
10115 else if (state
== destDx
)
10117 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
10118 LR insn get the target register pair. */
10119 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
10120 TARGET_BIG_ENDIAN
? 0 : 4);
10121 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
10122 TARGET_BIG_ENDIAN
? 4 : 0);
10124 emit_insn (gen_dexcl_2op (dest
, srcHigh
, srcLow
));
10127 gcc_unreachable ();
10132 /* operands 0..1 are the operands of a 64 bit move instruction.
10133 split it into two moves with operands 2/3 and 4/5. */
10136 arc_split_move (rtx
*operands
)
10138 machine_mode mode
= GET_MODE (operands
[0]);
10145 if (arc_process_double_reg_moves (operands
))
10150 && ((memory_operand (operands
[0], mode
)
10151 && (even_register_operand (operands
[1], mode
)
10152 || satisfies_constraint_Cm3 (operands
[1])))
10153 || (memory_operand (operands
[1], mode
)
10154 && even_register_operand (operands
[0], mode
))))
10156 emit_move_insn (operands
[0], operands
[1]);
10160 if (TARGET_PLUS_QMACW
10161 && even_register_operand (operands
[0], mode
)
10162 && even_register_operand (operands
[1], mode
))
10164 emit_move_insn (operands
[0], operands
[1]);
10168 if (TARGET_PLUS_QMACW
10169 && GET_CODE (operands
[1]) == CONST_VECTOR
)
10171 HOST_WIDE_INT intval0
, intval1
;
10172 if (GET_MODE (operands
[1]) == V2SImode
)
10174 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
10175 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
10179 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
10180 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
10181 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
10182 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
10184 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
10185 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
10186 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
10187 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
10188 emit_move_insn (xop
[0], xop
[2]);
10189 emit_move_insn (xop
[3], xop
[1]);
10193 for (i
= 0; i
< 2; i
++)
10195 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
10197 rtx addr
= XEXP (operands
[i
], 0);
10199 enum rtx_code code
;
10201 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
10202 switch (GET_CODE (addr
))
10204 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
10205 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
10206 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
10210 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
10211 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
10212 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
10214 code
= POST_MODIFY
;
10218 gcc_unreachable ();
10220 r
= XEXP (addr
, 0);
10221 xop
[0+i
] = adjust_automodify_address_nv
10222 (operands
[i
], SImode
,
10223 gen_rtx_fmt_ee (code
, Pmode
, r
,
10224 gen_rtx_PLUS (Pmode
, r
, o
)),
10226 xop
[2+i
] = adjust_automodify_address_nv
10227 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
10231 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
10232 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
10235 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
10238 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
10241 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
10242 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
10246 /* Select between the instruction output templates s_tmpl (for short INSNs)
10247 and l_tmpl (for long INSNs). */
10250 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
10252 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
10254 extract_constrain_insn_cached (insn
);
10255 return is_short
? s_tmpl
: l_tmpl
;
10258 /* Searches X for any reference to REGNO, returning the rtx of the
10259 reference found if any. Otherwise, returns NULL_RTX. */
10262 arc_regno_use_in (unsigned int regno
, rtx x
)
10268 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
10271 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
10272 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
10276 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
10279 else if (fmt
[i
] == 'E')
10280 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
10281 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
10288 /* Return the integer value of the "type" attribute for INSN, or -1 if
10289 INSN can't have attributes. */
10292 arc_attr_type (rtx_insn
*insn
)
10294 if (NONJUMP_INSN_P (insn
)
10295 ? (GET_CODE (PATTERN (insn
)) == USE
10296 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
10298 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
10299 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
10302 return get_attr_type (insn
);
10305 /* Code has a minimum p2 alignment of 1, which we must restore after
10306 an ADDR_DIFF_VEC. */
10309 arc_label_align (rtx_insn
*label
)
10311 if (align_labels
.levels
[0].log
< 1)
10313 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
10314 if (INSN_P (next
) && recog_memoized (next
) >= 0)
10317 return align_labels
.levels
[0].log
;
10320 /* Return true if LABEL is in executable code. */
10323 arc_text_label (rtx_insn
*label
)
10327 /* ??? We use deleted labels like they were still there, see
10328 gcc.c-torture/compile/20000326-2.c . */
10329 gcc_assert (GET_CODE (label
) == CODE_LABEL
10330 || (GET_CODE (label
) == NOTE
10331 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
10332 next
= next_nonnote_insn (label
);
10334 return (!JUMP_TABLE_DATA_P (next
)
10335 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
10336 else if (!PREV_INSN (label
))
10337 /* ??? sometimes text labels get inserted very late, see
10338 gcc.dg/torture/stackalign/comp-goto-1.c */
10343 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
10344 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
10345 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
10346 to redirect two breqs. */
10349 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
10351 /* ??? get_attr_type is declared to take an rtx. */
10352 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
10355 if (CROSSING_JUMP_P (followee
))
10356 switch (get_attr_type (u
.r
))
10359 if (get_attr_length (u
.r
) != 2)
10361 /* Fall through. */
10363 case TYPE_BRCC_NO_DELAY_SLOT
:
10372 /* Implement EPILOGUE_USES.
10373 Return true if REGNO should be added to the deemed uses of the epilogue.
10375 We have to make sure all the register restore instructions are
10376 known to be live in interrupt functions, plus the blink register if
10377 it is clobbered by the isr. */
10380 arc_epilogue_uses (int regno
)
10382 unsigned int fn_type
;
10383 fn_type
= arc_compute_function_type (cfun
);
10385 if (regno
== arc_tp_regno
)
10388 if (regno
== RETURN_ADDR_REGNUM
)
10391 if (regno
== arc_return_address_register (fn_type
))
10394 if (epilogue_completed
&& ARC_INTERRUPT_P (fn_type
))
10396 /* An interrupt function restores more registers. */
10397 if (df_regs_ever_live_p (regno
) || call_used_or_fixed_reg_p (regno
))
10404 /* Helper for EH_USES macro. */
10407 arc_eh_uses (int regno
)
10409 if (regno
== arc_tp_regno
)
10414 /* Return true if we use LRA instead of reload pass. */
10419 return arc_lra_flag
;
10422 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10423 Rcq registers, because some insn are shorter with them. OTOH we already
10424 have separate alternatives for this purpose, and other insns don't
10425 mind, so maybe we should rather prefer the other registers?
10426 We need more data, and we can only get that if we allow people to
10427 try all options. */
10429 arc_register_priority (int r
)
10431 switch (arc_lra_priority_tag
)
10433 case ARC_LRA_PRIORITY_NONE
:
10435 case ARC_LRA_PRIORITY_NONCOMPACT
:
10436 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
10437 case ARC_LRA_PRIORITY_COMPACT
:
10438 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
10440 gcc_unreachable ();
10445 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
10447 return GENERAL_REGS
;
10451 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
10455 enum reload_type type
= (enum reload_type
) itype
;
10457 if (GET_CODE (x
) == PLUS
10458 && CONST_INT_P (XEXP (x
, 1))
10459 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
10460 || (REG_P (XEXP (x
, 0))
10461 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
10463 int scale
= GET_MODE_SIZE (mode
);
10465 rtx index_rtx
= XEXP (x
, 1);
10466 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
10467 rtx reg
, sum
, sum2
;
10471 if ((scale
-1) & offset
)
10473 shift
= scale
>> 1;
10475 = ((offset
+ (256 << shift
))
10476 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
10477 /* Sometimes the normal form does not suit DImode. We
10478 could avoid that by using smaller ranges, but that
10479 would give less optimized code when SImode is
10481 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
10486 regno
= REGNO (reg
);
10487 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
10489 if (reg_equiv_constant (regno
))
10491 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
10493 if (GET_CODE (sum2
) == PLUS
)
10494 sum2
= gen_rtx_CONST (Pmode
, sum2
);
10496 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
10497 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
10498 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
10503 /* We must re-recognize what we created before. */
10504 else if (GET_CODE (x
) == PLUS
10505 && GET_CODE (XEXP (x
, 0)) == PLUS
10506 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
10507 && REG_P (XEXP (XEXP (x
, 0), 0))
10508 && CONST_INT_P (XEXP (x
, 1)))
10510 /* Because this address is so complex, we know it must have
10511 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10512 it is already unshared, and needs no further unsharing. */
10513 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
10514 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
10520 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10523 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
10524 unsigned int align
,
10525 enum by_pieces_operation op
,
10528 /* Let the cpymem expander handle small block moves. */
10529 if (op
== MOVE_BY_PIECES
)
10532 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
10535 /* Emit a (pre) memory barrier around an atomic sequence according to
10539 arc_pre_atomic_barrier (enum memmodel model
)
10541 if (need_atomic_barrier_p (model
, true))
10542 emit_insn (gen_memory_barrier ());
10545 /* Emit a (post) memory barrier around an atomic sequence according to
10549 arc_post_atomic_barrier (enum memmodel model
)
10551 if (need_atomic_barrier_p (model
, false))
10552 emit_insn (gen_memory_barrier ());
10555 /* Expand a compare and swap pattern. */
10558 emit_unlikely_jump (rtx insn
)
10560 rtx_insn
*jump
= emit_jump_insn (insn
);
10561 add_reg_br_prob_note (jump
, profile_probability::very_unlikely ());
10564 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10565 32-bit compare and swap on the word containing the byte or
10566 half-word. The difference between a weak and a strong CAS is that
10567 the weak version may simply fail. The strong version relies on two
10568 loops, one checks if the SCOND op is succsfully or not, the other
10569 checks if the 32 bit accessed location which contains the 8 or 16
10570 bit datum is not changed by other thread. The first loop is
10571 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10572 loops is implemented by this routine. */
10575 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
10576 rtx oldval
, rtx newval
, rtx weak
,
10577 rtx mod_s
, rtx mod_f
)
10579 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
10580 rtx addr
= gen_reg_rtx (Pmode
);
10581 rtx off
= gen_reg_rtx (SImode
);
10582 rtx oldv
= gen_reg_rtx (SImode
);
10583 rtx newv
= gen_reg_rtx (SImode
);
10584 rtx oldvalue
= gen_reg_rtx (SImode
);
10585 rtx newvalue
= gen_reg_rtx (SImode
);
10586 rtx res
= gen_reg_rtx (SImode
);
10587 rtx resv
= gen_reg_rtx (SImode
);
10588 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
10590 bool is_weak
= (weak
!= const0_rtx
);
10592 /* Truncate the address. */
10593 emit_insn (gen_rtx_SET (addr
,
10594 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
10596 /* Compute the datum offset. */
10597 emit_insn (gen_rtx_SET (off
,
10598 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
10599 if (TARGET_BIG_ENDIAN
)
10600 emit_insn (gen_rtx_SET (off
,
10601 gen_rtx_MINUS (SImode
,
10602 (GET_MODE (mem
) == QImode
) ?
10603 GEN_INT (3) : GEN_INT (2), off
)));
10605 /* Normal read from truncated address. */
10606 memsi
= gen_rtx_MEM (SImode
, addr
);
10607 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
10608 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
10610 val
= copy_to_reg (memsi
);
10612 /* Convert the offset in bits. */
10613 emit_insn (gen_rtx_SET (off
,
10614 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
10616 /* Get the proper mask. */
10617 if (GET_MODE (mem
) == QImode
)
10618 mask
= force_reg (SImode
, GEN_INT (0xff));
10620 mask
= force_reg (SImode
, GEN_INT (0xffff));
10622 emit_insn (gen_rtx_SET (mask
,
10623 gen_rtx_ASHIFT (SImode
, mask
, off
)));
10625 /* Prepare the old and new values. */
10626 emit_insn (gen_rtx_SET (val
,
10627 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10630 oldval
= gen_lowpart (SImode
, oldval
);
10631 emit_insn (gen_rtx_SET (oldv
,
10632 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
10634 newval
= gen_lowpart_common (SImode
, newval
);
10635 emit_insn (gen_rtx_SET (newv
,
10636 gen_rtx_ASHIFT (SImode
, newval
, off
)));
10638 emit_insn (gen_rtx_SET (oldv
,
10639 gen_rtx_AND (SImode
, oldv
, mask
)));
10641 emit_insn (gen_rtx_SET (newv
,
10642 gen_rtx_AND (SImode
, newv
, mask
)));
10646 end_label
= gen_label_rtx ();
10647 loop_label
= gen_label_rtx ();
10648 emit_label (loop_label
);
10651 /* Make the old and new values. */
10652 emit_insn (gen_rtx_SET (oldvalue
,
10653 gen_rtx_IOR (SImode
, oldv
, val
)));
10655 emit_insn (gen_rtx_SET (newvalue
,
10656 gen_rtx_IOR (SImode
, newv
, val
)));
10658 /* Try an 32bit atomic compare and swap. It clobbers the CC
10660 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
10661 weak
, mod_s
, mod_f
));
10663 /* Regardless of the weakness of the operation, a proper boolean
10664 result needs to be provided. */
10665 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10666 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10667 emit_insn (gen_rtx_SET (bool_result
, x
));
10671 /* Check the results: if the atomic op is successfully the goto
10673 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10674 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
10675 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10676 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
10677 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
10679 /* Wait for the right moment when the accessed 32-bit location
10681 emit_insn (gen_rtx_SET (resv
,
10682 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
10684 mode
= SELECT_CC_MODE (NE
, resv
, val
);
10685 cc
= gen_rtx_REG (mode
, CC_REG
);
10686 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
10688 /* Set the new value of the 32 bit location, proper masked. */
10689 emit_insn (gen_rtx_SET (val
, resv
));
10691 /* Try again if location is unstable. Fall through if only
10692 scond op failed. */
10693 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
10694 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10695 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
10696 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10698 emit_label (end_label
);
10701 /* End: proper return the result for the given mode. */
10702 emit_insn (gen_rtx_SET (res
,
10703 gen_rtx_AND (SImode
, res
, mask
)));
10705 emit_insn (gen_rtx_SET (res
,
10706 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
10708 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
10711 /* Helper function used by "atomic_compare_and_swap" expand
10715 arc_expand_compare_and_swap (rtx operands
[])
10717 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
10720 bval
= operands
[0];
10721 rval
= operands
[1];
10723 oldval
= operands
[3];
10724 newval
= operands
[4];
10725 is_weak
= operands
[5];
10726 mod_s
= operands
[6];
10727 mod_f
= operands
[7];
10728 mode
= GET_MODE (mem
);
10730 if (reg_overlap_mentioned_p (rval
, oldval
))
10731 oldval
= copy_to_reg (oldval
);
10733 if (mode
== SImode
)
10735 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
10736 is_weak
, mod_s
, mod_f
));
10737 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10738 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
10739 emit_insn (gen_rtx_SET (bval
, x
));
10743 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
10744 is_weak
, mod_s
, mod_f
);
10748 /* Helper function used by the "atomic_compare_and_swapsi_1"
10752 arc_split_compare_and_swap (rtx operands
[])
10754 rtx rval
, mem
, oldval
, newval
;
10756 enum memmodel mod_s
, mod_f
;
10758 rtx label1
, label2
, x
, cond
;
10760 rval
= operands
[0];
10762 oldval
= operands
[2];
10763 newval
= operands
[3];
10764 is_weak
= (operands
[4] != const0_rtx
);
10765 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
10766 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
10767 mode
= GET_MODE (mem
);
10769 /* ARC atomic ops work only with 32-bit aligned memories. */
10770 gcc_assert (mode
== SImode
);
10772 arc_pre_atomic_barrier (mod_s
);
10777 label1
= gen_label_rtx ();
10778 emit_label (label1
);
10780 label2
= gen_label_rtx ();
10782 /* Load exclusive. */
10783 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
10785 /* Check if it is oldval. */
10786 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
10787 cond
= gen_rtx_REG (mode
, CC_REG
);
10788 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
10790 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10791 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10792 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
10793 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10795 /* Exclusively store new item. Store clobbers CC reg. */
10796 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
10800 /* Check the result of the store. */
10801 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10802 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10803 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10804 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
10805 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10808 if (mod_f
!= MEMMODEL_RELAXED
)
10809 emit_label (label2
);
10811 arc_post_atomic_barrier (mod_s
);
10813 if (mod_f
== MEMMODEL_RELAXED
)
10814 emit_label (label2
);
10817 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10818 to perform. MEM is the memory on which to operate. VAL is the second
10819 operand of the binary operator. BEFORE and AFTER are optional locations to
10820 return the value of MEM either before of after the operation. MODEL_RTX
10821 is a CONST_INT containing the memory model to use. */
10824 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
10825 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
10827 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
10828 machine_mode mode
= GET_MODE (mem
);
10829 rtx label
, x
, cond
;
10830 rtx before
= orig_before
, after
= orig_after
;
10832 /* ARC atomic ops work only with 32-bit aligned memories. */
10833 gcc_assert (mode
== SImode
);
10835 arc_pre_atomic_barrier (model
);
10837 label
= gen_label_rtx ();
10838 emit_label (label
);
10839 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
10841 if (before
== NULL_RTX
)
10842 before
= gen_reg_rtx (mode
);
10844 if (after
== NULL_RTX
)
10845 after
= gen_reg_rtx (mode
);
10847 /* Load exclusive. */
10848 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
10853 x
= gen_rtx_AND (mode
, before
, val
);
10854 emit_insn (gen_rtx_SET (after
, x
));
10855 x
= gen_rtx_NOT (mode
, after
);
10856 emit_insn (gen_rtx_SET (after
, x
));
10860 if (CONST_INT_P (val
))
10862 val
= GEN_INT (-INTVAL (val
));
10868 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
10869 emit_insn (gen_rtx_SET (after
, x
));
10873 /* Exclusively store new item. Store clobbers CC reg. */
10874 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
10876 /* Check the result of the store. */
10877 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
10878 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
10879 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
10881 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
10883 arc_post_atomic_barrier (model
);
10886 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10889 arc_no_speculation_in_delay_slots_p ()
10894 /* Return a parallel of registers to represent where to find the
10895 register pieces if required, otherwise NULL_RTX. */
10898 arc_dwarf_register_span (rtx rtl
)
10900 machine_mode mode
= GET_MODE (rtl
);
10904 if (GET_MODE_SIZE (mode
) != 8)
10907 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
10908 regno
= REGNO (rtl
);
10909 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
10910 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
10915 /* Return true if OP is an acceptable memory operand for ARCompact
10916 16-bit load instructions of MODE.
10918 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10919 non scaled instructions.
10921 SCALED: TRUE if address can be scaled. */
10924 compact_memory_operand_p (rtx op
, machine_mode mode
,
10925 bool av2short
, bool scaled
)
10927 rtx addr
, plus0
, plus1
;
10930 /* Eliminate non-memory operations. */
10931 if (GET_CODE (op
) != MEM
)
10934 /* .di instructions have no 16-bit form. */
10935 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
10938 /* likewise for uncached types. */
10939 if (arc_is_uncached_mem_p (op
))
10942 if (mode
== VOIDmode
)
10943 mode
= GET_MODE (op
);
10945 size
= GET_MODE_SIZE (mode
);
10947 /* dword operations really put out 2 instructions, so eliminate
10949 if (size
> UNITS_PER_WORD
)
10952 /* Decode the address now. */
10953 addr
= XEXP (op
, 0);
10954 switch (GET_CODE (addr
))
10957 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
10958 || COMPACT_GP_REG_P (REGNO (addr
))
10959 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
10961 plus0
= XEXP (addr
, 0);
10962 plus1
= XEXP (addr
, 1);
10964 if ((GET_CODE (plus0
) == REG
)
10965 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10966 || COMPACT_GP_REG_P (REGNO (plus0
)))
10967 && ((GET_CODE (plus1
) == REG
)
10968 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10969 || COMPACT_GP_REG_P (REGNO (plus1
)))))
10974 if ((GET_CODE (plus0
) == REG
)
10975 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
10976 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
10977 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
10978 && (GET_CODE (plus1
) == CONST_INT
))
10980 bool valid
= false;
10982 off
= INTVAL (plus1
);
10984 /* Negative offset is not supported in 16-bit load/store insns. */
10988 /* Only u5 immediates allowed in code density instructions. */
10996 /* This is an ldh_s.x instruction, check the u6
10998 if (COMPACT_GP_REG_P (REGNO (plus0
)))
11002 /* Only u5 immediates allowed in 32bit access code
11003 density instructions. */
11004 if (REGNO (plus0
) <= 31)
11005 return ((off
< 32) && (off
% 4 == 0));
11012 if (COMPACT_GP_REG_P (REGNO (plus0
)))
11023 /* The 6-bit constant get shifted to fit the real
11024 5-bits field. Check also for the alignment. */
11025 return ((off
< 64) && (off
% 2 == 0));
11027 return ((off
< 128) && (off
% 4 == 0));
11034 if (REG_P (plus0
) && CONST_INT_P (plus1
)
11035 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
11036 || SP_REG_P (REGNO (plus0
)))
11039 off
= INTVAL (plus1
);
11040 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
11043 if ((GET_CODE (plus0
) == MULT
)
11044 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
11045 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
11046 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
11047 && (GET_CODE (plus1
) == REG
)
11048 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
11049 || COMPACT_GP_REG_P (REGNO (plus1
))))
11053 /* TODO: 'gp' and 'pcl' are to supported as base address operand
11054 for 16-bit load instructions. */
11059 /* Return nonzero if a jli call should be generated for a call from
11060 the current function to DECL. */
11063 arc_is_jli_call_p (rtx pat
)
11066 tree decl
= SYMBOL_REF_DECL (pat
);
11068 /* If it is not a well defined public function then return false. */
11069 if (!decl
|| !SYMBOL_REF_FUNCTION_P (pat
) || !TREE_PUBLIC (decl
))
11072 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
11073 if (lookup_attribute ("jli_always", attrs
))
11076 if (lookup_attribute ("jli_fixed", attrs
))
11079 return TARGET_JLI_ALWAYS
;
11082 /* Handle and "jli" attribute; arguments as in struct
11083 attribute_spec.handler. */
11086 arc_handle_jli_attribute (tree
*node ATTRIBUTE_UNUSED
,
11087 tree name
, tree args
, int,
11088 bool *no_add_attrs
)
11092 warning (OPT_Wattributes
,
11093 "%qE attribute only valid for ARCv2 architecture",
11095 *no_add_attrs
= true;
11098 if (args
== NULL_TREE
)
11100 warning (OPT_Wattributes
,
11101 "argument of %qE attribute is missing",
11103 *no_add_attrs
= true;
11107 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
11108 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
11109 tree arg
= TREE_VALUE (args
);
11110 if (TREE_CODE (arg
) != INTEGER_CST
)
11112 warning (0, "%qE attribute allows only an integer constant argument",
11114 *no_add_attrs
= true;
11116 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11121 /* Handle and "scure" attribute; arguments as in struct
11122 attribute_spec.handler. */
11125 arc_handle_secure_attribute (tree
*node ATTRIBUTE_UNUSED
,
11126 tree name
, tree args
, int,
11127 bool *no_add_attrs
)
11131 warning (OPT_Wattributes
,
11132 "%qE attribute only valid for ARC EM architecture",
11134 *no_add_attrs
= true;
11137 if (args
== NULL_TREE
)
11139 warning (OPT_Wattributes
,
11140 "argument of %qE attribute is missing",
11142 *no_add_attrs
= true;
11146 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
11147 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
11148 tree arg
= TREE_VALUE (args
);
11149 if (TREE_CODE (arg
) != INTEGER_CST
)
11151 warning (0, "%qE attribute allows only an integer constant argument",
11153 *no_add_attrs
= true;
11159 /* Return nonzero if the symbol is a secure function. */
11162 arc_is_secure_call_p (rtx pat
)
11165 tree decl
= SYMBOL_REF_DECL (pat
);
11170 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (decl
));
11171 if (lookup_attribute ("secure_call", attrs
))
11177 /* Handle "uncached" qualifier. */
11180 arc_handle_uncached_attribute (tree
*node
,
11181 tree name
, tree args
,
11182 int flags ATTRIBUTE_UNUSED
,
11183 bool *no_add_attrs
)
11185 if (DECL_P (*node
) && TREE_CODE (*node
) != TYPE_DECL
)
11187 error ("%qE attribute only applies to types",
11189 *no_add_attrs
= true;
11193 warning (OPT_Wattributes
, "argument of %qE attribute ignored", name
);
11198 /* Return TRUE if PAT is a memory addressing an uncached data. */
11201 arc_is_uncached_mem_p (rtx pat
)
11203 tree attrs
= NULL_TREE
;
11209 /* Get the memory attributes. */
11210 addr
= MEM_EXPR (pat
);
11214 /* Get the attributes. */
11215 if (TREE_CODE (addr
) == MEM_REF
11216 || TREE_CODE (addr
) == VAR_DECL
)
11218 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (addr
));
11219 if (lookup_attribute ("uncached", attrs
))
11222 if (TREE_CODE (addr
) == MEM_REF
)
11224 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
11225 if (lookup_attribute ("uncached", attrs
))
11227 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 1)));
11228 if (lookup_attribute ("uncached", attrs
))
11232 /* Check the definitions of the structs. */
11233 while (handled_component_p (addr
))
11235 if (TREE_CODE (addr
) == COMPONENT_REF
)
11237 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (addr
));
11238 if (lookup_attribute ("uncached", attrs
))
11240 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 0)));
11241 if (lookup_attribute ("uncached", attrs
))
11243 attrs
= TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr
, 1)));
11244 if (lookup_attribute ("uncached", attrs
))
11247 addr
= TREE_OPERAND (addr
, 0);
11252 /* Handle aux attribute. The auxiliary registers are addressed using
11253 special instructions lr and sr. The attribute 'aux' indicates if a
11254 variable refers to the aux-regs and what is the register number
11258 arc_handle_aux_attribute (tree
*node
,
11259 tree name
, tree args
, int,
11260 bool *no_add_attrs
)
11262 /* Isn't it better to use address spaces for the aux-regs? */
11263 if (DECL_P (*node
))
11265 if (TREE_CODE (*node
) != VAR_DECL
)
11267 error ("%qE attribute only applies to variables", name
);
11268 *no_add_attrs
= true;
11272 if (TREE_CODE (TREE_VALUE (args
)) == NON_LVALUE_EXPR
)
11273 TREE_VALUE (args
) = TREE_OPERAND (TREE_VALUE (args
), 0);
11274 tree arg
= TREE_VALUE (args
);
11275 if (TREE_CODE (arg
) != INTEGER_CST
)
11277 warning (OPT_Wattributes
, "%qE attribute allows only an integer "
11278 "constant argument", name
);
11279 *no_add_attrs
= true;
11281 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11284 if (TREE_CODE (*node
) == VAR_DECL
)
11286 tree fntype
= TREE_TYPE (*node
);
11287 if (fntype
&& TREE_CODE (fntype
) == POINTER_TYPE
)
11289 tree attrs
= tree_cons (get_identifier ("aux"), NULL_TREE
,
11290 TYPE_ATTRIBUTES (fntype
));
11291 TYPE_ATTRIBUTES (fntype
) = attrs
;
11298 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
11299 anchors for small data: the GP register acts as an anchor in that
11300 case. We also don't want to use them for PC-relative accesses,
11301 where the PC acts as an anchor. Prohibit also TLS symbols to use
11305 arc_use_anchors_for_symbol_p (const_rtx symbol
)
11307 if (SYMBOL_REF_TLS_MODEL (symbol
))
11313 if (SYMBOL_REF_SMALL_P (symbol
))
11316 return default_use_anchors_for_symbol_p (symbol
);
11319 /* Return true if SUBST can't safely replace its equivalent during RA. */
11321 arc_cannot_substitute_mem_equiv_p (rtx
)
11323 /* If SUBST is mem[base+index], the address may not fit ISA,
11324 thus return true. */
11328 /* Checks whether the operands are valid for use in an LDD/STD
11329 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
11330 by the patterns. Assumes that the address in the base register RN
11331 is word aligned. Pattern guarantees that both memory accesses use
11332 the same base register, the offsets are constants within the range,
11333 and the gap between the offsets is 4. If reload complete then
11334 check that registers are legal. */
11337 operands_ok_ldd_std (rtx rt
, rtx rt2
, HOST_WIDE_INT offset
)
11339 unsigned int t
, t2
;
11341 if (!reload_completed
)
11344 if (!(SMALL_INT_RANGE (offset
, (GET_MODE_SIZE (DImode
) - 1) & (~0x03),
11345 (offset
& (GET_MODE_SIZE (DImode
) - 1) & 3
11346 ? 0 : -(-GET_MODE_SIZE (DImode
) | (~0x03)) >> 1))))
11352 if ((t2
== PCL_REG
)
11353 || (t
% 2 != 0) /* First destination register is not even. */
11360 /* Helper for gen_operands_ldd_std. Returns true iff the memory
11361 operand MEM's address contains an immediate offset from the base
11362 register and has no side effects, in which case it sets BASE and
11363 OFFSET accordingly. */
11366 mem_ok_for_ldd_std (rtx mem
, rtx
*base
, rtx
*offset
)
11370 gcc_assert (base
!= NULL
&& offset
!= NULL
);
11372 /* TODO: Handle more general memory operand patterns, such as
11373 PRE_DEC and PRE_INC. */
11375 if (side_effects_p (mem
))
11378 /* Can't deal with subregs. */
11379 if (GET_CODE (mem
) == SUBREG
)
11382 gcc_assert (MEM_P (mem
));
11384 *offset
= const0_rtx
;
11386 addr
= XEXP (mem
, 0);
11388 /* If addr isn't valid for DImode, then we can't handle it. */
11389 if (!arc_legitimate_address_p (DImode
, addr
,
11390 reload_in_progress
|| reload_completed
))
11398 else if (GET_CODE (addr
) == PLUS
|| GET_CODE (addr
) == MINUS
)
11400 *base
= XEXP (addr
, 0);
11401 *offset
= XEXP (addr
, 1);
11402 return (REG_P (*base
) && CONST_INT_P (*offset
));
11408 /* Called from peephole2 to replace two word-size accesses with a
11409 single LDD/STD instruction. Returns true iff we can generate a new
11410 instruction sequence. That is, both accesses use the same base
11411 register and the gap between constant offsets is 4. OPERANDS are
11412 the operands found by the peephole matcher; OPERANDS[0,1] are
11413 register operands, and OPERANDS[2,3] are the corresponding memory
11414 operands. LOAD indicates whether the access is load or store. */
11417 gen_operands_ldd_std (rtx
*operands
, bool load
, bool commute
)
11420 HOST_WIDE_INT offsets
[2], offset
;
11422 rtx cur_base
, cur_offset
, tmp
;
11423 rtx base
= NULL_RTX
;
11425 /* Check that the memory references are immediate offsets from the
11426 same base register. Extract the base register, the destination
11427 registers, and the corresponding memory offsets. */
11428 for (i
= 0; i
< nops
; i
++)
11430 if (!mem_ok_for_ldd_std (operands
[nops
+i
], &cur_base
, &cur_offset
))
11435 else if (REGNO (base
) != REGNO (cur_base
))
11438 offsets
[i
] = INTVAL (cur_offset
);
11439 if (GET_CODE (operands
[i
]) == SUBREG
)
11441 tmp
= SUBREG_REG (operands
[i
]);
11442 gcc_assert (GET_MODE (operands
[i
]) == GET_MODE (tmp
));
11447 /* Make sure there is no dependency between the individual loads. */
11448 if (load
&& REGNO (operands
[0]) == REGNO (base
))
11449 return false; /* RAW. */
11451 if (load
&& REGNO (operands
[0]) == REGNO (operands
[1]))
11452 return false; /* WAW. */
11454 /* Make sure the instructions are ordered with lower memory access first. */
11455 if (offsets
[0] > offsets
[1])
11457 gap
= offsets
[0] - offsets
[1];
11458 offset
= offsets
[1];
11460 /* Swap the instructions such that lower memory is accessed first. */
11461 std::swap (operands
[0], operands
[1]);
11462 std::swap (operands
[2], operands
[3]);
11466 gap
= offsets
[1] - offsets
[0];
11467 offset
= offsets
[0];
11470 /* Make sure accesses are to consecutive memory locations. */
11474 /* Make sure we generate legal instructions. */
11475 if (operands_ok_ldd_std (operands
[0], operands
[1], offset
))
11478 if (load
&& commute
)
11480 /* Try reordering registers. */
11481 std::swap (operands
[0], operands
[1]);
11482 if (operands_ok_ldd_std (operands
[0], operands
[1], offset
))
11489 /* This order of allocation is used when we compile for size. It
11490 allocates first the registers which are most probably to end up in
11491 a short instruction. */
11492 static const int size_alloc_order
[] =
11494 0, 1, 2, 3, 12, 13, 14, 15,
11495 4, 5, 6, 7, 8, 9, 10, 11
11498 /* Adjust register allocation order when compiling for size. */
11500 arc_adjust_reg_alloc_order (void)
11502 const int arc_default_alloc_order
[] = REG_ALLOC_ORDER
;
11503 memcpy (reg_alloc_order
, arc_default_alloc_order
, sizeof (reg_alloc_order
));
11505 memcpy (reg_alloc_order
, size_alloc_order
, sizeof (size_alloc_order
));
11508 /* Implement TARGET_MEMORY_MOVE_COST. */
11511 arc_memory_move_cost (machine_mode mode
,
11512 reg_class_t rclass ATTRIBUTE_UNUSED
,
11513 bool in ATTRIBUTE_UNUSED
)
11515 if ((GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
)
11516 || ((GET_MODE_SIZE (mode
) <= UNITS_PER_WORD
* 2) && TARGET_LL64
))
11519 return (2 * GET_MODE_SIZE (mode
));
11522 /* Split an OR instruction into multiple BSET/OR instructions in a
11523 attempt to avoid long immediate constants. The next strategies are
11524 employed when destination is 'q' reg.
11526 1. if there are up to three bits set in the mask, a succession of
11527 three bset instruction will be emitted:
11529 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
11531 2. if the lower 6 bits of the mask is set and there is only one
11532 bit set in the upper remaining bits then we will emit one bset and
11533 one OR instruction:
11534 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
11536 3. otherwise an OR with limm will be emmitted. */
11539 arc_split_ior (rtx
*operands
)
11541 unsigned HOST_WIDE_INT mask
, maskx
;
11542 rtx op1
= operands
[1];
11544 gcc_assert (CONST_INT_P (operands
[2]));
11545 mask
= INTVAL (operands
[2]) & 0xffffffff;
11547 if (__builtin_popcount (mask
) > 3 || (mask
& 0x3f))
11549 maskx
= mask
& 0x3f;
11550 emit_insn (gen_rtx_SET (operands
[0],
11551 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11556 switch (__builtin_popcount (mask
))
11559 maskx
= 1 << (__builtin_ffs (mask
) - 1);
11560 emit_insn (gen_rtx_SET (operands
[0],
11561 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11566 maskx
= 1 << (__builtin_ffs (mask
) - 1);
11567 emit_insn (gen_rtx_SET (operands
[0],
11568 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11573 maskx
= 1 << (__builtin_ffs (mask
) - 1);
11574 emit_insn (gen_rtx_SET (operands
[0],
11575 gen_rtx_IOR (SImode
, op1
, GEN_INT (maskx
))));
11580 gcc_unreachable ();
11584 /* Helper to check C0x constraint. */
11587 arc_check_ior_const (HOST_WIDE_INT ival
)
11589 unsigned int mask
= (unsigned int) (ival
& 0xffffffff);
11591 if (UNSIGNED_INT6 (ival
)
11592 || IS_POWEROF2_P (mask
))
11594 if (__builtin_popcount (mask
) <= 3)
11596 if (__builtin_popcount (mask
& ~0x3f) <= 1)
11601 /* Split a mov with long immediate instruction into smaller, size
11602 friendly instructions. */
11605 arc_split_mov_const (rtx
*operands
)
11607 unsigned HOST_WIDE_INT ival
;
11608 HOST_WIDE_INT shimm
;
11609 machine_mode mode
= GET_MODE (operands
[0]);
11611 /* Manage a constant. */
11612 gcc_assert (CONST_INT_P (operands
[1]));
11613 ival
= INTVAL (operands
[1]) & 0xffffffff;
11615 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11616 if (TARGET_BARREL_SHIFTER
&& TARGET_V2
11617 && ((ival
& ~0x3f000000) == 0))
11619 shimm
= (ival
>> 24) & 0x3f;
11620 emit_insn (gen_rtx_SET (operands
[0],
11621 gen_rtx_ROTATERT (mode
, GEN_INT (shimm
),
11625 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11626 if (TARGET_BARREL_SHIFTER
&& TARGET_V2
11627 && ((ival
& ~0x3f00) == 0))
11629 shimm
= (ival
>> 8) & 0x3f;
11630 emit_insn (gen_rtx_SET (operands
[0],
11631 gen_rtx_ASHIFT (mode
, GEN_INT (shimm
),
11636 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11637 if (TARGET_BARREL_SHIFTER
&& TARGET_V2
11638 && ((ival
& ~0x3f0000) == 0))
11640 shimm
= (ival
>> 16) & 0x3f;
11641 emit_insn (gen_rtx_SET (operands
[0],
11642 gen_rtx_ASHIFT (mode
, GEN_INT (shimm
),
11647 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11648 if (((ival
>> (__builtin_ffs (ival
) - 1)) & 0xffffff00) == 0
11649 && TARGET_BARREL_SHIFTER
)
11651 HOST_WIDE_INT shift
= __builtin_ffs (ival
);
11652 shimm
= (ival
>> (shift
- 1)) & 0xff;
11653 emit_insn (gen_rtx_SET (operands
[0], GEN_INT (shimm
)));
11654 emit_insn (gen_rtx_SET (operands
[0],
11655 gen_rtx_ASHIFT (mode
, operands
[0],
11656 GEN_INT (shift
- 1))));
11660 /* 5. Check if we can just rotate the limm, useful when no barrel
11661 shifter is present. */
11662 if ((ival
& ~0x8000001f) == 0)
11664 shimm
= (ival
* 2 + 1) & 0x3f;
11665 emit_insn (gen_rtx_SET (operands
[0],
11666 gen_rtx_ROTATERT (mode
, GEN_INT (shimm
),
11671 /* 6. Check if we can do something with bmask. */
11672 if (IS_POWEROF2_P (ival
+ 1))
11674 emit_insn (gen_rtx_SET (operands
[0], constm1_rtx
));
11675 emit_insn (gen_rtx_SET (operands
[0],
11676 gen_rtx_AND (mode
, operands
[0],
11681 gcc_unreachable ();
11684 /* Helper to check Cax constraint. */
11687 arc_check_mov_const (HOST_WIDE_INT ival
)
11689 ival
= ival
& 0xffffffff;
11691 if (SIGNED_INT12 (ival
))
11694 if ((ival
& ~0x8000001f) == 0)
11697 if (IS_POWEROF2_P (ival
+ 1))
11700 /* The next rules requires a barrel shifter. */
11701 if (!TARGET_BARREL_SHIFTER
)
11704 if (((ival
>> (__builtin_ffs (ival
) - 1)) & 0xffffff00) == 0)
11707 if ((ival
& ~0x3f00) == 0)
11710 if ((ival
& ~0x3f0000) == 0)
11713 if ((ival
& ~0x3f000000) == 0)
11719 /* Return nonzero if this function is known to have a null epilogue.
11720 This allows the optimizer to omit jumps to jumps if no stack
11724 arc_can_use_return_insn (void)
11726 return (reload_completed
&& cfun
->machine
->frame_info
.total_size
== 0
11727 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun
)));
11730 /* Helper for INSN_COST.
11732 Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
11733 insn, a set, a set source, any random piece of one). set_src_cost,
11734 set_rtx_cost, etc. are helper functions that use that.
11736 Those functions do not work for parallels. Also, costs are not
11737 additive like this simplified model assumes. Also, more complex
11738 backends tend to miss many cases in their rtx_costs function.
11740 Many passes that want costs want to know the cost of a full insn. Like
11741 combine. That's why I created insn_cost: it solves all of the above
11745 arc_insn_cost (rtx_insn
*insn
, bool speed
)
11748 if (recog_memoized (insn
) < 0)
11751 /* If optimizing for size, we want the insn size. */
11753 return get_attr_length (insn
);
11755 /* Use cost if provided. */
11756 cost
= get_attr_cost (insn
);
11760 /* For speed make a simple cost model: memory access is more
11761 expensive than any other instruction. */
11762 enum attr_type type
= get_attr_type (insn
);
11768 cost
= COSTS_N_INSNS (2);
11772 cost
= COSTS_N_INSNS (1);
11779 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11780 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11782 #undef TARGET_CONSTANT_ALIGNMENT
11783 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11785 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11786 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11788 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11789 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11791 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11792 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11794 #undef TARGET_REGISTER_MOVE_COST
11795 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11797 #undef TARGET_MEMORY_MOVE_COST
11798 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11800 #undef TARGET_INSN_COST
11801 #define TARGET_INSN_COST arc_insn_cost
11803 struct gcc_target targetm
= TARGET_INITIALIZER
;
11805 #include "gt-arc.h"