1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2019 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
31 #define IN_TARGET_CODE 1
35 #include "coretypes.h"
44 #include "stringpool.h"
50 #include "diagnostic.h"
51 #include "fold-const.h"
53 #include "stor-layout.h"
56 #include "insn-attr.h"
60 #include "langhooks.h"
61 #include "tm-constrs.h"
62 #include "reload.h" /* For operands_match_p */
64 #include "tree-pass.h"
70 #include "hw-doloop.h"
72 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
73 static char arc_cpu_name[10] = "";
74 static const char *arc_cpu_string = arc_cpu_name;
76 typedef struct GTY (()) _arc_jli_section
79 struct _arc_jli_section *next;
82 static arc_jli_section *arc_jli_sections = NULL;
84 /* Track which regs are set fixed/call saved/call used from commnad line. */
85 HARD_REG_SET overrideregs;
87 /* Maximum size of a loop. */
88 #define ARC_MAX_LOOP_LENGTH 4095
90 /* Check if an rtx fits in the store instruction format. Loads can
91 handle any constant. */
92 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
93 (GET_CODE (X) == CONST_INT \
94 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & (~0x03), \
95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
97 : -(-GET_MODE_SIZE (MODE) | (~0x03)) >> 1)))
99 /* Array of valid operand punctuation characters. */
100 char arc_punct_chars[256];
102 /* State used by arc_ccfsm_advance to implement conditional execution. */
103 struct GTY (()) arc_ccfsm
108 rtx_insn *target_insn;
112 /* Status of the IRQ_CTRL_AUX register. */
113 typedef struct irq_ctrl_saved_t
115 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
116 short irq_save_last_reg;
117 /* True if BLINK is automatically saved. */
119 /* True if LPCOUNT is automatically saved. */
120 bool irq_save_lpcount;
122 static irq_ctrl_saved_t irq_ctrl_saved;
124 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
125 ((ARC_INTERRUPT_P (FNTYPE) \
126 && irq_ctrl_saved.irq_save_blink) \
127 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
128 && rgf_banked_register_count > 8))
130 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
131 ((ARC_INTERRUPT_P (FNTYPE) \
132 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
133 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
134 && rgf_banked_register_count > 8))
136 #define ARC_AUTO_IRQ_P(FNTYPE) \
137 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
138 && (irq_ctrl_saved.irq_save_blink \
139 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
141 /* Number of registers in second bank for FIRQ support. */
142 static int rgf_banked_register_count;
144 #define arc_ccfsm_current cfun->machine->ccfsm_current
146 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
147 ((STATE)->state == 1 || (STATE)->state == 2)
149 /* Indicate we're conditionalizing insns now. */
150 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
151 ((STATE)->state += 2)
153 #define ARC_CCFSM_COND_EXEC_P(STATE) \
154 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
155 || current_insn_predicate)
157 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
158 #define CCFSM_ISCOMPACT(INSN,STATE) \
159 (ARC_CCFSM_COND_EXEC_P (STATE) \
160 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
161 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
162 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
164 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
165 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
166 ((ARC_CCFSM_COND_EXEC_P (STATE) \
168 && INSN_ANNULLED_BRANCH_P (JUMP) \
169 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
170 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
171 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
172 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
174 /* Start enter/leave register range. */
175 #define ENTER_LEAVE_START_REG 13
177 /* End enter/leave register range. */
178 #define ENTER_LEAVE_END_REG 26
180 /* The maximum number of insns skipped which will be conditionalised if
182 /* When optimizing for speed:
183 Let p be the probability that the potentially skipped insns need to
184 be executed, pn the cost of a correctly predicted non-taken branch,
185 mt the cost of a mis/non-predicted taken branch,
186 mn mispredicted non-taken, pt correctly predicted taken ;
187 costs expressed in numbers of instructions like the ones considered
189 Unfortunately we don't have a measure of predictability - this
190 is linked to probability only in that in the no-eviction-scenario
191 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
192 value that can be assumed *if* the distribution is perfectly random.
193 A predictability of 1 is perfectly plausible not matter what p is,
194 because the decision could be dependent on an invocation parameter
196 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
197 For small p, we want MAX_INSNS_SKIPPED == pt
199 When optimizing for size:
200 We want to skip insn unless we could use 16 opcodes for the
201 non-conditionalized insn to balance the branch length or more.
202 Performance can be tie-breaker. */
203 /* If the potentially-skipped insns are likely to be executed, we'll
204 generally save one non-taken branch
206 this to be no less than the 1/p */
207 #define MAX_INSNS_SKIPPED 3
209 /* 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 /* A nop is needed between a 4 byte insn that sets the condition codes and
217 a branch that uses them (the same isn't true for an 8 byte insn that sets
218 the condition codes). Set by arc_ccfsm_advance. Used by
219 arc_print_operand. */
221 static int get_arc_condition_code (rtx);
223 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
224 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
225 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
226 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
227 static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
228 static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *);
230 /* Initialized arc_attribute_table to NULL since arc doesnot have any
231 machine specific supported attributes. */
232 const struct attribute_spec arc_attribute_table[] =
234 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
235 affects_type_identity, handler, exclude } */
236 { "interrupt", 1, 1, true, false, false, true,
237 arc_handle_interrupt_attribute, NULL },
238 /* Function calls made to this symbol must be done indirectly, because
239 it may lie outside of the 21/25 bit addressing range of a normal function
241 { "long_call", 0, 0, false, true, true, false, NULL, NULL },
242 /* Whereas these functions are always known to reside within the 25 bit
243 addressing range of unconditionalized bl. */
244 { "medium_call", 0, 0, false, true, true, false, NULL, NULL },
245 /* And these functions are always known to reside within the 21 bit
246 addressing range of blcc. */
247 { "short_call", 0, 0, false, true, true, false, NULL, NULL },
248 /* Function which are not having the prologue and epilogue generated
250 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute,
252 /* Functions calls made using jli instruction. The pointer in JLI
253 table is found latter. */
254 { "jli_always", 0, 0, false, true, true, false, NULL, NULL },
255 /* Functions calls made using jli instruction. The pointer in JLI
256 table is given as input parameter. */
257 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute,
259 /* Call a function using secure-mode. */
260 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute,
262 /* Bypass caches using .di flag. */
263 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute,
265 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute, NULL },
266 { NULL, 0, 0, false, false, false, false, NULL, NULL }
268 static int arc_comp_type_attributes (const_tree, const_tree);
269 static void arc_file_start (void);
270 static void arc_internal_label (FILE *, const char *, unsigned long);
271 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
273 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
274 static void arc_encode_section_info (tree decl, rtx rtl, int first);
276 static void arc_init_builtins (void);
277 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
279 static int branch_dest (rtx);
281 static void arc_output_pic_addr_const (FILE *, rtx, int);
282 static bool arc_function_ok_for_sibcall (tree, tree);
283 static rtx arc_function_value (const_tree, const_tree, bool);
284 const char * output_shift (rtx *);
285 static void arc_reorg (void);
286 static bool arc_in_small_data_p (const_tree);
288 static void arc_init_reg_tables (void);
289 static bool arc_return_in_memory (const_tree, const_tree);
290 static bool arc_vector_mode_supported_p (machine_mode);
292 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
294 static const char *arc_invalid_within_doloop (const rtx_insn *);
296 static void output_short_suffix (FILE *file);
298 static bool arc_frame_pointer_required (void);
300 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
302 enum by_pieces_operation op,
305 /* Globally visible information about currently selected cpu. */
306 const arc_cpu_t *arc_selected_cpu;
308 /* Traditionally, we push saved registers first in the prologue,
309 then we allocate the rest of the frame - and reverse in the epilogue.
310 This has still its merits for ease of debugging, or saving code size
311 or even execution time if the stack frame is so large that some accesses
312 can't be encoded anymore with offsets in the instruction code when using
314 Also, it would be a good starting point if we got instructions to help
315 with register save/restore.
317 However, often stack frames are small, and the pushing / popping has
319 - the stack modification prevents a lot of scheduling.
320 - frame allocation / deallocation may need extra instructions.
321 - we need to place a memory barrier after frame allocation to avoid
322 the delay slot scheduler to reschedule a frame related info and
323 messing up with dwarf unwinding. The barrier before deallocation
324 is for flushing all pending sp operations.
326 Thus, for small frames, we'd like to use a different scheme:
327 - The frame is allocated in full with the first prologue instruction,
328 and deallocated in full with the last epilogue instruction.
329 Thus, the instructions in-between can be freely scheduled.
330 - If the function has no outgoing arguments on the stack, we can allocate
331 one register save slot at the top of the stack. This register can then
332 be saved simultaneously with frame allocation, and restored with
334 This register can be picked depending on scheduling considerations,
335 although same though should go into having some set of registers
336 to be potentially lingering after a call, and others to be available
337 immediately - i.e. in the absence of interprocedual optimization, we
338 can use an ABI-like convention for register allocation to reduce
339 stalls after function return. */
341 /* ARCompact stack frames look like:
343 Before call After call
344 high +-----------------------+ +-----------------------+
345 mem | reg parm save area | | reg parm save area |
346 | only created for | | only created for |
347 | variable arg fns | | variable arg fns |
348 AP +-----------------------+ +-----------------------+
349 | return addr register | | return addr register |
350 | (if required) | | (if required) |
351 +-----------------------+ +-----------------------+
353 | reg save area | | reg save area |
355 +-----------------------+ +-----------------------+
356 | frame pointer | | frame pointer |
357 | (if required) | | (if required) |
358 FP +-----------------------+ +-----------------------+
360 | local/temp variables | | local/temp variables |
362 +-----------------------+ +-----------------------+
364 | arguments on stack | | arguments on stack |
366 SP +-----------------------+ +-----------------------+
367 | reg parm save area |
370 AP +-----------------------+
371 | return addr register |
373 +-----------------------+
377 +-----------------------+
380 FP +-----------------------+
382 | local/temp variables |
384 +-----------------------+
386 | arguments on stack |
388 mem SP +-----------------------+
391 1) The "reg parm save area" does not exist for non variable argument fns.
392 The "reg parm save area" can be eliminated completely if we created our
393 own va-arc.h, but that has tradeoffs as well (so it's not done). */
395 /* Structure to be filled in by arc_compute_frame_size with register
396 save masks, and offsets for the current function. */
397 struct GTY (()) arc_frame_info
399 unsigned int total_size; /* # bytes that the entire frame takes up. */
400 unsigned int extra_size; /* # bytes of extra stuff. */
401 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
402 unsigned int args_size; /* # bytes that outgoing arguments take up. */
403 unsigned int reg_size; /* # bytes needed to store regs. */
404 unsigned int var_size; /* # bytes that variables take up. */
405 uint64_t gmask; /* Mask of saved gp registers. */
406 bool initialized; /* FALSE if frame size already calculated. */
407 short millicode_start_reg;
408 short millicode_end_reg;
409 bool save_return_addr;
412 /* GMASK bit length -1. */
415 /* Defining data structures for per-function information. */
417 typedef struct GTY (()) machine_function
419 unsigned int fn_type;
420 struct arc_frame_info frame_info;
421 /* To keep track of unalignment caused by short insns. */
423 struct arc_ccfsm ccfsm_current;
424 /* Map from uid to ccfsm state during branch shortening. */
425 rtx ccfsm_current_insn;
426 char arc_reorg_started;
427 char prescan_initialized;
431 /* Given a symbol RTX (const (symb <+ const_int>), returns its
435 get_symbol_alignment (rtx x)
437 tree decl = NULL_TREE;
440 switch (GET_CODE (x))
443 decl = SYMBOL_REF_DECL (x);
446 return get_symbol_alignment (XEXP (x, 0));
448 gcc_assert (CONST_INT_P (XEXP (x, 1)));
449 return get_symbol_alignment (XEXP (x, 0));
455 align = DECL_ALIGN (decl);
456 align = align / BITS_PER_UNIT;
460 /* Return true if x is ok to be used as a small data address. */
463 legitimate_small_data_address_p (rtx x)
465 switch (GET_CODE (x))
468 return legitimate_small_data_address_p (XEXP (x, 0));
470 return SYMBOL_REF_SMALL_P (x);
473 bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
474 && SYMBOL_REF_SMALL_P (XEXP (x, 0));
475 bool p1 = CONST_INT_P (XEXP (x, 1))
476 && (INTVAL (XEXP (x, 1)) <= g_switch_value);
484 /* TRUE if op is an scaled address. */
486 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
488 if (GET_CODE (op) != PLUS)
491 if (GET_CODE (XEXP (op, 0)) != MULT)
494 /* Check multiplication operands. */
495 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
498 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
501 switch (GET_MODE_SIZE (mode))
504 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
512 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
519 /* Check the base. */
520 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
525 if (CONST_INT_P (XEXP (op, 1)))
530 /* Scalled addresses for sdata is done other places. */
531 if (legitimate_small_data_address_p (op))
534 if (CONSTANT_P (XEXP (op, 1)))
540 /* Check for constructions like REG + OFFS, where OFFS can be a
541 register, an immediate or an long immediate. */
544 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
546 if (GET_CODE (x) != PLUS)
549 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
552 /* Check for: [Rx + small offset] or [Rx + Ry]. */
553 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict))
554 && GET_MODE_SIZE ((mode)) <= 4)
555 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1))))
558 /* Check for [Rx + symbol]. */
560 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
561 /* Avoid this type of address for double or larger modes. */
562 && (GET_MODE_SIZE (mode) <= 4)
563 /* Avoid small data which ends in something like GP +
565 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
571 /* Implements target hook vector_mode_supported_p. */
574 arc_vector_mode_supported_p (machine_mode mode)
579 return TARGET_PLUS_DMPY;
582 return TARGET_PLUS_QMACW;
585 return TARGET_SIMD_SET;
592 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
595 arc_preferred_simd_mode (scalar_mode mode)
600 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
609 /* Implements target hook
610 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
613 arc_autovectorize_vector_sizes (vector_sizes *sizes, bool)
615 if (TARGET_PLUS_QMACW)
617 sizes->quick_push (8);
618 sizes->quick_push (4);
623 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
625 arc_sched_issue_rate (void)
638 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
639 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
640 static rtx arc_delegitimize_address (rtx);
641 static bool arc_can_follow_jump (const rtx_insn *follower,
642 const rtx_insn *followee);
644 static rtx frame_insn (rtx);
645 static void arc_function_arg_advance (cumulative_args_t,
646 const function_arg_info &);
647 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
649 /* initialize the GCC target structure. */
650 #undef TARGET_COMP_TYPE_ATTRIBUTES
651 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
652 #undef TARGET_ASM_FILE_START
653 #define TARGET_ASM_FILE_START arc_file_start
654 #undef TARGET_ATTRIBUTE_TABLE
655 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
656 #undef TARGET_ASM_INTERNAL_LABEL
657 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
658 #undef TARGET_RTX_COSTS
659 #define TARGET_RTX_COSTS arc_rtx_costs
660 #undef TARGET_ADDRESS_COST
661 #define TARGET_ADDRESS_COST arc_address_cost
663 #undef TARGET_ENCODE_SECTION_INFO
664 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
666 #undef TARGET_CANNOT_FORCE_CONST_MEM
667 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
669 #undef TARGET_INIT_BUILTINS
670 #define TARGET_INIT_BUILTINS arc_init_builtins
672 #undef TARGET_EXPAND_BUILTIN
673 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
675 #undef TARGET_BUILTIN_DECL
676 #define TARGET_BUILTIN_DECL arc_builtin_decl
678 #undef TARGET_ASM_OUTPUT_MI_THUNK
679 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
681 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
682 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
684 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
685 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
687 #undef TARGET_MACHINE_DEPENDENT_REORG
688 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
690 #undef TARGET_IN_SMALL_DATA_P
691 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
693 #undef TARGET_PROMOTE_FUNCTION_MODE
694 #define TARGET_PROMOTE_FUNCTION_MODE \
695 default_promote_function_mode_always_promote
697 #undef TARGET_PROMOTE_PROTOTYPES
698 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
700 #undef TARGET_RETURN_IN_MEMORY
701 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
702 #undef TARGET_PASS_BY_REFERENCE
703 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
705 #undef TARGET_SETUP_INCOMING_VARARGS
706 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
708 #undef TARGET_ARG_PARTIAL_BYTES
709 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
711 #undef TARGET_MUST_PASS_IN_STACK
712 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
714 #undef TARGET_FUNCTION_VALUE
715 #define TARGET_FUNCTION_VALUE arc_function_value
717 #undef TARGET_SCHED_ADJUST_PRIORITY
718 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
720 #undef TARGET_SCHED_ISSUE_RATE
721 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
723 #undef TARGET_VECTOR_MODE_SUPPORTED_P
724 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
726 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
727 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
729 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
730 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
732 #undef TARGET_CAN_USE_DOLOOP_P
733 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
735 #undef TARGET_INVALID_WITHIN_DOLOOP
736 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
738 #undef TARGET_PRESERVE_RELOAD_P
739 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
741 #undef TARGET_CAN_FOLLOW_JUMP
742 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
744 #undef TARGET_DELEGITIMIZE_ADDRESS
745 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
747 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
748 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
749 arc_use_by_pieces_infrastructure_p
751 /* Usually, we will be able to scale anchor offsets.
752 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
753 #undef TARGET_MIN_ANCHOR_OFFSET
754 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
755 #undef TARGET_MAX_ANCHOR_OFFSET
756 #define TARGET_MAX_ANCHOR_OFFSET (1020)
758 #undef TARGET_SECONDARY_RELOAD
759 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
761 #define TARGET_OPTION_OVERRIDE arc_override_options
763 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
765 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
767 #define TARGET_CAN_ELIMINATE arc_can_eliminate
769 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
771 #define TARGET_FUNCTION_ARG arc_function_arg
773 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
775 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
777 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
779 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
781 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
783 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
784 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
785 arc_no_speculation_in_delay_slots_p
788 #define TARGET_LRA_P arc_lra_p
789 #define TARGET_REGISTER_PRIORITY arc_register_priority
790 /* Stores with scaled offsets have different displacement ranges. */
791 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
792 #define TARGET_SPILL_CLASS arc_spill_class
794 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
795 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
797 #undef TARGET_WARN_FUNC_RETURN
798 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
800 #include "target-def.h"
802 #undef TARGET_ASM_ALIGNED_HI_OP
803 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
804 #undef TARGET_ASM_ALIGNED_SI_OP
805 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
808 #undef TARGET_HAVE_TLS
809 #define TARGET_HAVE_TLS HAVE_AS_TLS
812 #undef TARGET_DWARF_REGISTER_SPAN
813 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
815 #undef TARGET_HARD_REGNO_NREGS
816 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
817 #undef TARGET_HARD_REGNO_MODE_OK
818 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
820 #undef TARGET_MODES_TIEABLE_P
821 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
823 /* Try to keep the (mov:DF _, reg) as early as possible so
824 that the d<add/sub/mul>h-lr insns appear together and can
825 use the peephole2 pattern. */
828 arc_sched_adjust_priority (rtx_insn *insn, int priority)
830 rtx set = single_set (insn);
832 && GET_MODE (SET_SRC(set)) == DFmode
833 && GET_CODE (SET_SRC(set)) == REG)
835 /* Incrementing priority by 20 (empirically derived). */
836 return priority + 20;
842 /* For ARC base register + offset addressing, the validity of the
843 address is mode-dependent for most of the offset range, as the
844 offset can be scaled by the access size.
845 We don't expose these as mode-dependent addresses in the
846 mode_dependent_address_p target hook, because that would disable
847 lots of optimizations, and most uses of these addresses are for 32
848 or 64 bit accesses anyways, which are fine.
849 However, that leaves some addresses for 8 / 16 bit values not
850 properly reloaded by the generic code, which is why we have to
851 schedule secondary reloads for these. */
854 arc_secondary_reload (bool in_p,
858 secondary_reload_info *sri)
860 enum rtx_code code = GET_CODE (x);
862 if (cl == DOUBLE_REGS)
865 /* If we have a subreg (reg), where reg is a pseudo (that will end in
866 a memory location), then we may need a scratch register to handle
867 the fp/sp+largeoffset address. */
875 int regno = REGNO (x);
876 if (regno >= FIRST_PSEUDO_REGISTER)
877 regno = reg_renumber[regno];
882 /* It is a pseudo that ends in a stack location. This
883 procedure only works with the old reload step. */
884 if (reg_equiv_mem (REGNO (x)) && !lra_in_progress)
886 /* Get the equivalent address and check the range of the
888 rtx mem = reg_equiv_mem (REGNO (x));
889 addr = find_replacement (&XEXP (mem, 0));
894 gcc_assert (MEM_P (x));
896 addr = simplify_rtx (addr);
898 if (addr && GET_CODE (addr) == PLUS
899 && CONST_INT_P (XEXP (addr, 1))
900 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
906 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store;
910 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store;
920 /* Convert reloads using offsets that are too large to use indirect
924 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
928 gcc_assert (GET_CODE (mem) == MEM);
929 addr = XEXP (mem, 0);
931 /* Large offset: use a move. FIXME: ld ops accepts limms as
932 offsets. Hence, the following move insn is not required. */
933 emit_move_insn (scratch, addr);
934 mem = replace_equiv_address_nv (mem, scratch);
936 /* Now create the move. */
938 emit_insn (gen_rtx_SET (mem, reg));
940 emit_insn (gen_rtx_SET (reg, mem));
945 static unsigned arc_ifcvt (void);
949 const pass_data pass_data_arc_ifcvt =
952 "arc_ifcvt", /* name */
953 OPTGROUP_NONE, /* optinfo_flags */
954 TV_IFCVT2, /* tv_id */
955 0, /* properties_required */
956 0, /* properties_provided */
957 0, /* properties_destroyed */
958 0, /* todo_flags_start */
959 TODO_df_finish /* todo_flags_finish */
962 class pass_arc_ifcvt : public rtl_opt_pass
965 pass_arc_ifcvt(gcc::context *ctxt)
966 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt)
969 /* opt_pass methods: */
970 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); }
971 virtual unsigned int execute (function *) { return arc_ifcvt (); }
977 make_pass_arc_ifcvt (gcc::context *ctxt)
979 return new pass_arc_ifcvt (ctxt);
982 static unsigned arc_predicate_delay_insns (void);
986 const pass_data pass_data_arc_predicate_delay_insns =
989 "arc_predicate_delay_insns", /* name */
990 OPTGROUP_NONE, /* optinfo_flags */
991 TV_IFCVT2, /* tv_id */
992 0, /* properties_required */
993 0, /* properties_provided */
994 0, /* properties_destroyed */
995 0, /* todo_flags_start */
996 TODO_df_finish /* todo_flags_finish */
999 class pass_arc_predicate_delay_insns : public rtl_opt_pass
1002 pass_arc_predicate_delay_insns(gcc::context *ctxt)
1003 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
1006 /* opt_pass methods: */
1007 virtual unsigned int execute (function *)
1009 return arc_predicate_delay_insns ();
1016 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
1018 return new pass_arc_predicate_delay_insns (ctxt);
1021 /* Called by OVERRIDE_OPTIONS to initialize various things. */
1028 /* I have the multiplier, then use it*/
1029 if (TARGET_MPYW || TARGET_MULTI)
1030 arc_multcost = COSTS_N_INSNS (1);
1032 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
1033 if (arc_multcost < 0)
1036 case ARC_TUNE_ARC700_4_2_STD:
1038 max throughput (1 multiply + 4 other insns) / 5 cycles. */
1039 arc_multcost = COSTS_N_INSNS (4);
1040 if (TARGET_NOMPY_SET)
1041 arc_multcost = COSTS_N_INSNS (30);
1043 case ARC_TUNE_ARC700_4_2_XMAC:
1045 max throughput (1 multiply + 2 other insns) / 3 cycles. */
1046 arc_multcost = COSTS_N_INSNS (3);
1047 if (TARGET_NOMPY_SET)
1048 arc_multcost = COSTS_N_INSNS (30);
1050 case ARC_TUNE_ARC600:
1051 if (TARGET_MUL64_SET)
1053 arc_multcost = COSTS_N_INSNS (4);
1058 arc_multcost = COSTS_N_INSNS (30);
1062 /* MPY instructions valid only for ARC700 or ARCv2. */
1063 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
1064 error ("%<-mno-mpy%> supported only for ARC700 or ARCv2");
1066 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
1067 error ("%<-mno-dpfp-lrsr%> supported only with %<-mdpfp%>");
1069 /* FPX-1. No fast and compact together. */
1070 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
1071 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
1072 error ("FPX fast and compact options cannot be specified together");
1074 /* FPX-2. No fast-spfp for arc600 or arc601. */
1075 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
1076 error ("%<-mspfp_fast%> not available on ARC600 or ARC601");
1078 /* FPX-4. No FPX extensions mixed with FPU extensions. */
1079 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
1080 && TARGET_HARD_FLOAT)
1081 error ("no FPX/FPU mixing allowed");
1083 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
1084 if (flag_pic && TARGET_ARC600_FAMILY)
1086 warning (0, "PIC is not supported for %qs",
1091 arc_init_reg_tables ();
1093 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
1094 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
1095 arc_punct_chars['#'] = 1;
1096 arc_punct_chars['*'] = 1;
1097 arc_punct_chars['?'] = 1;
1098 arc_punct_chars['!'] = 1;
1099 arc_punct_chars['^'] = 1;
1100 arc_punct_chars['&'] = 1;
1101 arc_punct_chars['+'] = 1;
1102 arc_punct_chars['_'] = 1;
1104 if (optimize > 1 && !TARGET_NO_COND_EXEC)
1106 /* There are two target-independent ifcvt passes, and arc_reorg may do
1107 one or more arc_ifcvt calls. */
1108 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g);
1109 struct register_pass_info arc_ifcvt4_info
1110 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER };
1111 struct register_pass_info arc_ifcvt5_info
1112 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE };
1114 register_pass (&arc_ifcvt4_info);
1115 register_pass (&arc_ifcvt5_info);
1118 if (flag_delayed_branch)
1120 opt_pass *pass_arc_predicate_delay_insns
1121 = make_pass_arc_predicate_delay_insns (g);
1122 struct register_pass_info arc_predicate_delay_info
1123 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER };
1125 register_pass (&arc_predicate_delay_info);
1129 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1130 register range is specified as two registers separated by a dash.
1131 It always starts with r0, and its upper limit is fp register.
1132 blink and lp_count registers are optional. */
1135 irq_range (const char *cstr)
1137 int i, first, last, blink, lpcount, xreg;
1138 char *str, *dash, *comma;
1141 str = (char *) alloca (i + 1);
1142 memcpy (str, cstr, i + 1);
1146 dash = strchr (str, '-');
1149 warning (OPT_mirq_ctrl_saved_, "missing dash");
1154 comma = strchr (dash + 1, ',');
1158 first = decode_reg_name (str);
1161 warning (OPT_mirq_ctrl_saved_, "first register must be R0");
1165 /* At this moment we do not have the register names initialized
1167 if (!strcmp (dash + 1, "ilink"))
1170 last = decode_reg_name (dash + 1);
1174 warning (OPT_mirq_ctrl_saved_, "unknown register name: %s", dash + 1);
1180 warning (OPT_mirq_ctrl_saved_,
1181 "last register name %s must be an odd register", dash + 1);
1189 warning (OPT_mirq_ctrl_saved_,
1190 "%s-%s is an empty range", str, dash + 1);
1199 comma = strchr (str, ',');
1203 xreg = decode_reg_name (str);
1215 warning (OPT_mirq_ctrl_saved_,
1216 "unknown register name: %s", str);
1221 irq_ctrl_saved.irq_save_last_reg = last;
1222 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31);
1223 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60);
1226 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1230 parse_mrgf_banked_regs_option (const char *arg)
1236 val = strtol (arg, &end_ptr, 10);
1237 if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
1238 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
1240 error ("invalid number in %<-mrgf-banked-regs=%s%> "
1241 "valid values are 0, 4, 8, 16, or 32", arg);
1244 rgf_banked_register_count = (int) val;
1247 /* Check ARC options, generate derived target attributes. */
1250 arc_override_options (void)
1253 cl_deferred_option *opt;
1254 vec<cl_deferred_option> *vopt
1255 = (vec<cl_deferred_option> *) arc_deferred_options;
1257 if (arc_cpu == PROCESSOR_NONE)
1258 arc_cpu = TARGET_CPU_DEFAULT;
1260 /* Set the default cpu options. */
1261 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
1263 /* Set the architectures. */
1264 switch (arc_selected_cpu->arch_info->arch_id)
1267 arc_cpu_string = "EM";
1270 arc_cpu_string = "HS";
1273 if (arc_selected_cpu->processor == PROCESSOR_nps400)
1274 arc_cpu_string = "NPS400";
1276 arc_cpu_string = "ARC700";
1279 arc_cpu_string = "ARC600";
1285 irq_ctrl_saved.irq_save_last_reg = -1;
1286 irq_ctrl_saved.irq_save_blink = false;
1287 irq_ctrl_saved.irq_save_lpcount = false;
1289 rgf_banked_register_count = 0;
1291 /* Handle the deferred options. */
1293 FOR_EACH_VEC_ELT (*vopt, i, opt)
1295 switch (opt->opt_index)
1297 case OPT_mirq_ctrl_saved_:
1299 irq_range (opt->arg);
1301 warning (OPT_mirq_ctrl_saved_,
1302 "option %<-mirq-ctrl-saved%> valid only "
1303 "for ARC v2 processors");
1306 case OPT_mrgf_banked_regs_:
1308 parse_mrgf_banked_regs_option (opt->arg);
1310 warning (OPT_mrgf_banked_regs_,
1311 "option %<-mrgf-banked-regs%> valid only for "
1312 "ARC v2 processors");
1320 CLEAR_HARD_REG_SET (overrideregs);
1321 if (common_deferred_options)
1323 vec<cl_deferred_option> v =
1324 *((vec<cl_deferred_option> *) common_deferred_options);
1327 FOR_EACH_VEC_ELT (v, i, opt)
1329 switch (opt->opt_index)
1332 case OPT_fcall_used_:
1333 case OPT_fcall_saved_:
1334 if ((reg = decode_reg_name_and_count (opt->arg, &nregs)) >= 0)
1335 for (j = reg; j < reg + nregs; j++)
1336 SET_HARD_REG_BIT (overrideregs, j);
1344 /* Check options against architecture options. Throw an error if
1345 option is not allowed. Extra, check options against default
1346 architecture/cpu flags and throw an warning if we find a
1348 /* TRANSLATORS: the DOC/DOC0/DOC1 are strings which shouldn't be
1349 translated. They are like keywords which one can relate with the
1350 architectural choices taken for an ARC CPU implementation. */
1351 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1353 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1355 error ("option %<%s=%s%> is not available for %qs CPU", \
1356 DOC0, DOC1, arc_selected_cpu->name); \
1357 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1358 && (VAR != DEFAULT_##VAR) \
1360 warning (0, "option %qs is ignored, the default value %qs" \
1361 " is considered for %qs CPU", DOC0, DOC1, \
1362 arc_selected_cpu->name); \
1364 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1366 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1367 && (target_flags & MASK)) \
1368 error ("option %qs is not available for %qs CPU", \
1369 DOC, arc_selected_cpu->name); \
1370 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1371 && (target_flags_explicit & MASK) \
1372 && (!(target_flags & MASK))) \
1373 warning (0, "unset option %qs is ignored, it is always" \
1374 " enabled for %qs CPU", DOC, \
1375 arc_selected_cpu->name); \
1378 #include "arc-options.def"
1383 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1384 specific flags are set in arc-common.c. The architecture forces
1385 the default hardware configurations in, regardless what command
1386 line options are saying. The CPU optional hw options can be
1387 turned on or off. */
1388 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1390 if ((arc_selected_cpu->flags & CODE) \
1391 && ((target_flags_explicit & MASK) == 0)) \
1392 target_flags |= MASK; \
1393 if (arc_selected_cpu->arch_info->dflags & CODE) \
1394 target_flags |= MASK; \
1396 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1398 if ((arc_selected_cpu->flags & CODE) \
1399 && (VAR == DEFAULT_##VAR)) \
1401 if (arc_selected_cpu->arch_info->dflags & CODE) \
1405 #include "arc-options.def"
1411 switch (arc_selected_cpu->extra)
1413 case HAS_LPCOUNT_16:
1420 /* Set Tune option. */
1421 if (arc_tune == ARC_TUNE_NONE)
1422 arc_tune = (enum arc_tune_attr) arc_selected_cpu->tune;
1424 if (arc_size_opt_level == 3)
1427 if (TARGET_V2 && optimize_size && (ATTRIBUTE_PCS == 2))
1428 TARGET_CODE_DENSITY_FRAME = 1;
1431 target_flags |= MASK_NO_SDATA_SET;
1433 if (flag_no_common == 255)
1434 flag_no_common = !TARGET_NO_SDATA_SET;
1436 if (TARGET_MIXED_CODE)
1439 /* Check for small data option */
1440 if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
1441 g_switch_value = TARGET_LL64 ? 8 : 4;
1443 /* A7 has an issue with delay slots. */
1444 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
1445 flag_delayed_branch = 0;
1447 /* Millicode thunks doesn't work with long calls. */
1448 if (TARGET_LONG_CALLS_SET)
1449 target_flags &= ~MASK_MILLICODE_THUNK_SET;
1451 /* Set unaligned to all HS cpus. */
1452 if (!global_options_set.x_unaligned_access && TARGET_HS)
1453 unaligned_access = 1;
1455 /* These need to be done at start up. It's convenient to do them here. */
1459 /* The condition codes of the ARC, and the inverse function. */
1460 /* For short branches, the "c" / "nc" names are not defined in the ARC
1461 Programmers manual, so we have to use "lo" / "hs"" instead. */
1462 static const char *arc_condition_codes[] =
1464 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1465 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1468 enum arc_cc_code_index
1470 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
1471 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
1472 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
1473 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
1476 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1478 /* Returns the index of the ARC condition code string in
1479 `arc_condition_codes'. COMPARISON should be an rtx like
1480 `(eq (...) (...))'. */
1483 get_arc_condition_code (rtx comparison)
1485 switch (GET_MODE (XEXP (comparison, 0)))
1488 case E_SImode: /* For BRcc. */
1489 switch (GET_CODE (comparison))
1491 case EQ : return ARC_CC_EQ;
1492 case NE : return ARC_CC_NE;
1493 case GT : return ARC_CC_GT;
1494 case LE : return ARC_CC_LE;
1495 case GE : return ARC_CC_GE;
1496 case LT : return ARC_CC_LT;
1497 case GTU : return ARC_CC_HI;
1498 case LEU : return ARC_CC_LS;
1499 case LTU : return ARC_CC_LO;
1500 case GEU : return ARC_CC_HS;
1501 default : gcc_unreachable ();
1504 switch (GET_CODE (comparison))
1506 case EQ : return ARC_CC_EQ;
1507 case NE : return ARC_CC_NE;
1508 case GE: return ARC_CC_P;
1509 case LT: return ARC_CC_N;
1510 case GT : return ARC_CC_PNZ;
1511 default : gcc_unreachable ();
1514 switch (GET_CODE (comparison))
1516 case EQ : return ARC_CC_EQ;
1517 case NE : return ARC_CC_NE;
1518 default : gcc_unreachable ();
1521 switch (GET_CODE (comparison))
1523 case LTU : return ARC_CC_C;
1524 case GEU : return ARC_CC_NC;
1525 default : gcc_unreachable ();
1527 case E_CC_FP_GTmode:
1528 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1529 switch (GET_CODE (comparison))
1531 case GT : return ARC_CC_N;
1532 case UNLE: return ARC_CC_P;
1533 default : gcc_unreachable ();
1536 switch (GET_CODE (comparison))
1538 case GT : return ARC_CC_HI;
1539 case UNLE : return ARC_CC_LS;
1540 default : gcc_unreachable ();
1542 case E_CC_FP_GEmode:
1543 /* Same for FPX and non-FPX. */
1544 switch (GET_CODE (comparison))
1546 case GE : return ARC_CC_HS;
1547 case UNLT : return ARC_CC_LO;
1548 default : gcc_unreachable ();
1550 case E_CC_FP_UNEQmode:
1551 switch (GET_CODE (comparison))
1553 case UNEQ : return ARC_CC_EQ;
1554 case LTGT : return ARC_CC_NE;
1555 default : gcc_unreachable ();
1557 case E_CC_FP_ORDmode:
1558 switch (GET_CODE (comparison))
1560 case UNORDERED : return ARC_CC_C;
1561 case ORDERED : return ARC_CC_NC;
1562 default : gcc_unreachable ();
1565 switch (GET_CODE (comparison))
1567 case EQ : return ARC_CC_EQ;
1568 case NE : return ARC_CC_NE;
1569 case UNORDERED : return ARC_CC_C;
1570 case ORDERED : return ARC_CC_NC;
1571 case LTGT : return ARC_CC_HI;
1572 case UNEQ : return ARC_CC_LS;
1573 default : gcc_unreachable ();
1576 switch (GET_CODE (comparison))
1578 case EQ : return ARC_CC_EQ;
1579 case NE : return ARC_CC_NE;
1580 case GT : return ARC_CC_GT;
1581 case GE : return ARC_CC_GE;
1582 case LT : return ARC_CC_C;
1583 case LE : return ARC_CC_LS;
1584 case UNORDERED : return ARC_CC_V;
1585 case ORDERED : return ARC_CC_NV;
1586 case UNGT : return ARC_CC_HI;
1587 case UNGE : return ARC_CC_HS;
1588 case UNLT : return ARC_CC_LT;
1589 case UNLE : return ARC_CC_LE;
1590 /* UNEQ and LTGT do not have representation. */
1591 case LTGT : /* Fall through. */
1592 case UNEQ : /* Fall through. */
1593 default : gcc_unreachable ();
1595 case E_CC_FPU_UNEQmode:
1596 switch (GET_CODE (comparison))
1598 case LTGT : return ARC_CC_NE;
1599 case UNEQ : return ARC_CC_EQ;
1600 default : gcc_unreachable ();
1602 default : gcc_unreachable ();
1608 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1611 arc_short_comparison_p (rtx comparison, int offset)
1613 gcc_assert (ARC_CC_NC == ARC_CC_HS);
1614 gcc_assert (ARC_CC_C == ARC_CC_LO);
1615 switch (get_arc_condition_code (comparison))
1617 case ARC_CC_EQ: case ARC_CC_NE:
1618 return offset >= -512 && offset <= 506;
1619 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
1620 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
1621 return offset >= -64 && offset <= 58;
1627 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1628 return the mode to be used for the comparison. */
1631 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1633 machine_mode mode = GET_MODE (x);
1636 /* For an operation that sets the condition codes as a side-effect, the
1637 C and V flags is not set as for cmp, so we can only use comparisons where
1638 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1640 /* ??? We could use "pnz" for greater than zero, however, we could then
1641 get into trouble because the comparison could not be reversed. */
1642 if (GET_MODE_CLASS (mode) == MODE_INT
1644 && (op == EQ || op == NE
1645 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
1648 /* add.f for if (a+b) */
1650 && GET_CODE (y) == NEG
1651 && (op == EQ || op == NE))
1654 /* Check if this is a test suitable for bxor.f . */
1655 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1656 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1660 /* Check if this is a test suitable for add / bmsk.f . */
1661 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1662 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1663 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1664 && (~INTVAL (x1) | INTVAL (y)) < 0
1665 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1668 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1669 && GET_CODE (x) == PLUS
1670 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1673 if (TARGET_ARGONAUT_SET
1674 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1677 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1679 case LT: case UNGE: case GT: case UNLE:
1680 return CC_FP_GTmode;
1681 case LE: case UNGT: case GE: case UNLT:
1682 return CC_FP_GEmode;
1683 default: gcc_unreachable ();
1685 else if (TARGET_HARD_FLOAT
1686 && ((mode == SFmode && TARGET_FP_SP_BASE)
1687 || (mode == DFmode && TARGET_FP_DP_BASE)))
1706 return CC_FPU_UNEQmode;
1711 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1715 case EQ: case NE: return CC_Zmode;
1717 case GT: case UNLE: return CC_FP_GTmode;
1719 case GE: case UNLT: return CC_FP_GEmode;
1720 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1721 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1722 default: gcc_unreachable ();
1728 /* Vectors to keep interesting information about registers where it can easily
1729 be got. We use to use the actual mode value as the bit number, but there
1730 is (or may be) more than 32 modes now. Instead we use two tables: one
1731 indexed by hard register number, and one indexed by mode. */
1733 /* The purpose of arc_mode_class is to shrink the range of modes so that
1734 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1735 mapped into one arc_mode_class mode. */
1737 enum arc_mode_class {
1739 S_MODE, D_MODE, T_MODE, O_MODE,
1740 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1744 /* Modes for condition codes. */
1745 #define C_MODES (1 << (int) C_MODE)
1747 /* Modes for single-word and smaller quantities. */
1748 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1750 /* Modes for double-word and smaller quantities. */
1751 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1753 /* Mode for 8-byte DF values only. */
1754 #define DF_MODES (1 << DF_MODE)
1756 /* Modes for quad-word and smaller quantities. */
1757 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1759 /* Modes for 128-bit vectors. */
1760 #define V_MODES (1 << (int) V_MODE)
1762 /* Value is 1 if register/mode pair is acceptable on arc. */
1764 static unsigned int arc_hard_regno_modes[] = {
1765 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1766 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1767 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1768 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1770 /* ??? Leave these as S_MODES for now. */
1771 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1772 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1773 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1774 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1776 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1777 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1778 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1779 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1781 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1782 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1783 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1784 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1786 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1787 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1791 static unsigned int arc_mode_class [NUM_MACHINE_MODES];
1793 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1796 arc_preferred_reload_class (rtx, enum reg_class cl)
1801 /* Initialize the arc_mode_class array. */
1804 arc_init_reg_tables (void)
1808 for (i = 0; i < NUM_MACHINE_MODES; i++)
1810 machine_mode m = (machine_mode) i;
1812 switch (GET_MODE_CLASS (m))
1815 case MODE_PARTIAL_INT:
1816 case MODE_COMPLEX_INT:
1817 if (GET_MODE_SIZE (m) <= 4)
1818 arc_mode_class[i] = 1 << (int) S_MODE;
1819 else if (GET_MODE_SIZE (m) == 8)
1820 arc_mode_class[i] = 1 << (int) D_MODE;
1821 else if (GET_MODE_SIZE (m) == 16)
1822 arc_mode_class[i] = 1 << (int) T_MODE;
1823 else if (GET_MODE_SIZE (m) == 32)
1824 arc_mode_class[i] = 1 << (int) O_MODE;
1826 arc_mode_class[i] = 0;
1829 case MODE_COMPLEX_FLOAT:
1830 if (GET_MODE_SIZE (m) <= 4)
1831 arc_mode_class[i] = 1 << (int) SF_MODE;
1832 else if (GET_MODE_SIZE (m) == 8)
1833 arc_mode_class[i] = 1 << (int) DF_MODE;
1834 else if (GET_MODE_SIZE (m) == 16)
1835 arc_mode_class[i] = 1 << (int) TF_MODE;
1836 else if (GET_MODE_SIZE (m) == 32)
1837 arc_mode_class[i] = 1 << (int) OF_MODE;
1839 arc_mode_class[i] = 0;
1841 case MODE_VECTOR_INT:
1842 if (GET_MODE_SIZE (m) == 4)
1843 arc_mode_class[i] = (1 << (int) S_MODE);
1844 else if (GET_MODE_SIZE (m) == 8)
1845 arc_mode_class[i] = (1 << (int) D_MODE);
1847 arc_mode_class[i] = (1 << (int) V_MODE);
1851 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1852 we must explicitly check for them here. */
1853 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1854 || i == (int) CC_Cmode
1855 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
1856 || i == CC_FPUmode || i == CC_FPU_UNEQmode)
1857 arc_mode_class[i] = 1 << (int) C_MODE;
1859 arc_mode_class[i] = 0;
1865 /* Core registers 56..59 are used for multiply extension options.
1866 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1867 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1868 number depends on endianness.
1869 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1870 Because mlo / mhi form a 64 bit value, we use different gcc internal
1871 register numbers to make them form a register pair as the gcc internals
1872 know it. mmid gets number 57, if still available, and mlo / mhi get
1873 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1874 to map this back. */
1875 char rname56[5] = "r56";
1876 char rname57[5] = "r57";
1877 char rname58[5] = "r58";
1878 char rname59[5] = "r59";
1879 char rname29[7] = "ilink1";
1880 char rname30[7] = "ilink2";
1883 arc_conditional_register_usage (void)
1887 int fix_start = 60, fix_end = 55;
1891 /* For ARCv2 the core register set is changed. */
1892 strcpy (rname29, "ilink");
1893 strcpy (rname30, "r30");
1895 if (!TEST_HARD_REG_BIT (overrideregs, R30_REG))
1897 /* No user interference. Set the r30 to be used by the
1899 call_used_regs[R30_REG] = 1;
1900 fixed_regs[R30_REG] = 0;
1902 arc_regno_reg_class[R30_REG] = GENERAL_REGS;
1906 if (TARGET_MUL64_SET)
1908 fix_start = R57_REG;
1911 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1912 you are supposed to refer to it as mlo & mhi, e.g
1913 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1914 In an actual asm instruction, you are of course use mmed.
1915 The point of avoiding having a separate register for mmed is that
1916 this way, we don't have to carry clobbers of that reg around in every
1917 isntruction that modifies mlo and/or mhi. */
1918 strcpy (rname57, "");
1919 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo");
1920 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi");
1923 /* The nature of arc_tp_regno is actually something more like a global
1924 register, however globalize_reg requires a declaration.
1925 We use EPILOGUE_USES to compensate so that sets from
1926 __builtin_set_frame_pointer are not deleted. */
1927 if (arc_tp_regno != -1)
1928 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1;
1930 if (TARGET_MULMAC_32BY16_SET)
1932 fix_start = MUL32x16_REG;
1933 fix_end = fix_end > R57_REG ? fix_end : R57_REG;
1934 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1935 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1937 for (regno = fix_start; regno <= fix_end; regno++)
1939 if (!fixed_regs[regno])
1940 warning (0, "multiply option implies r%d is fixed", regno);
1941 fixed_regs [regno] = call_used_regs[regno] = 1;
1944 /* Reduced configuration: don't use r4-r9, r16-r25. */
1947 for (i = R4_REG; i <= R9_REG; i++)
1948 fixed_regs[i] = call_used_regs[i] = 1;
1949 for (i = R16_REG; i <= R25_REG; i++)
1950 fixed_regs[i] = call_used_regs[i] = 1;
1953 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1956 for (regno = R1_REG; regno < R32_REG; regno +=2)
1957 arc_hard_regno_modes[regno] = S_MODES;
1959 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1962 if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
1963 && ((i <= R3_REG) || ((i >= R12_REG) && (i <= R15_REG))))
1964 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1966 arc_regno_reg_class[i] = GENERAL_REGS;
1968 else if (i < LP_COUNT)
1969 arc_regno_reg_class[i] = GENERAL_REGS;
1971 arc_regno_reg_class[i] = NO_REGS;
1973 /* Handle Special Registers. */
1974 arc_regno_reg_class[CC_REG] = NO_REGS; /* CC_REG: must be NO_REGS. */
1975 arc_regno_reg_class[FRAME_POINTER_REGNUM] = GENERAL_REGS;
1976 arc_regno_reg_class[ARG_POINTER_REGNUM] = GENERAL_REGS;
1979 for (i = R40_REG; i < R44_REG; ++i)
1981 arc_regno_reg_class[i] = DOUBLE_REGS;
1982 if (!TARGET_ARGONAUT_SET)
1983 CLEAR_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i);
1987 /* Disable all DOUBLE_REGISTER settings, if not generating DPFP
1989 arc_regno_reg_class[R40_REG] = ALL_REGS;
1990 arc_regno_reg_class[R41_REG] = ALL_REGS;
1991 arc_regno_reg_class[R42_REG] = ALL_REGS;
1992 arc_regno_reg_class[R43_REG] = ALL_REGS;
1994 fixed_regs[R40_REG] = 1;
1995 fixed_regs[R41_REG] = 1;
1996 fixed_regs[R42_REG] = 1;
1997 fixed_regs[R43_REG] = 1;
1999 arc_hard_regno_modes[R40_REG] = 0;
2000 arc_hard_regno_modes[R42_REG] = 0;
2003 if (TARGET_SIMD_SET)
2005 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
2006 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
2008 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
2009 arc_regno_reg_class [i] = SIMD_VR_REGS;
2011 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
2012 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
2013 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
2014 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
2016 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
2017 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
2018 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
2022 arc_regno_reg_class[PCL_REG] = NO_REGS;
2024 /*ARCV2 Accumulator. */
2026 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
2027 || TARGET_PLUS_DMPY)
2029 arc_regno_reg_class[ACCL_REGNO] = GENERAL_REGS;
2030 arc_regno_reg_class[ACCH_REGNO] = GENERAL_REGS;
2032 /* Allow the compiler to freely use them. */
2033 if (!TEST_HARD_REG_BIT (overrideregs, ACCL_REGNO))
2034 fixed_regs[ACCL_REGNO] = 0;
2035 if (!TEST_HARD_REG_BIT (overrideregs, ACCH_REGNO))
2036 fixed_regs[ACCH_REGNO] = 0;
2038 if (!fixed_regs[ACCH_REGNO] && !fixed_regs[ACCL_REGNO])
2039 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES;
2043 /* Implement TARGET_HARD_REGNO_NREGS. */
2046 arc_hard_regno_nregs (unsigned int regno, machine_mode mode)
2048 if (GET_MODE_SIZE (mode) == 16
2049 && regno >= ARC_FIRST_SIMD_VR_REG
2050 && regno <= ARC_LAST_SIMD_VR_REG)
2053 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2056 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2059 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2061 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0;
2064 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
2067 arc_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2069 return (GET_MODE_CLASS (mode1) == MODE_INT
2070 && GET_MODE_CLASS (mode2) == MODE_INT
2071 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
2072 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
2075 /* Handle an "interrupt" attribute; arguments as in
2076 struct attribute_spec.handler. */
2079 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
2084 tree value = TREE_VALUE (args);
2086 if (TREE_CODE (value) != STRING_CST)
2088 warning (OPT_Wattributes,
2089 "argument of %qE attribute is not a string constant",
2091 *no_add_attrs = true;
2094 && strcmp (TREE_STRING_POINTER (value), "ilink1")
2095 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
2097 warning (OPT_Wattributes,
2098 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2100 *no_add_attrs = true;
2103 && strcmp (TREE_STRING_POINTER (value), "ilink")
2104 && strcmp (TREE_STRING_POINTER (value), "firq"))
2106 warning (OPT_Wattributes,
2107 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2109 *no_add_attrs = true;
2116 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
2117 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
2119 if (TREE_CODE (*node) != FUNCTION_DECL)
2121 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2123 *no_add_attrs = true;
2129 /* Type of function DECL.
2131 The result is cached. To reset the cache at the end of a function,
2132 call with DECL = NULL_TREE. */
2135 arc_compute_function_type (struct function *fun)
2137 tree attr, decl = fun->decl;
2138 unsigned int fn_type = fun->machine->fn_type;
2140 if (fn_type != ARC_FUNCTION_UNKNOWN)
2143 /* Check if it is a naked function. */
2144 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
2145 fn_type |= ARC_FUNCTION_NAKED;
2147 fn_type |= ARC_FUNCTION_NORMAL;
2149 /* Now see if this is an interrupt handler. */
2150 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2151 if (attr != NULL_TREE)
2153 tree value, args = TREE_VALUE (attr);
2155 gcc_assert (list_length (args) == 1);
2156 value = TREE_VALUE (args);
2157 gcc_assert (TREE_CODE (value) == STRING_CST);
2159 if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
2160 || !strcmp (TREE_STRING_POINTER (value), "ilink"))
2161 fn_type |= ARC_FUNCTION_ILINK1;
2162 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
2163 fn_type |= ARC_FUNCTION_ILINK2;
2164 else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
2165 fn_type |= ARC_FUNCTION_FIRQ;
2170 return fun->machine->fn_type = fn_type;
2173 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2176 arc_allocate_stack_slots_for_args (void)
2178 /* Naked functions should not allocate stack slots for arguments. */
2179 unsigned int fn_type = arc_compute_function_type (cfun);
2181 return !ARC_NAKED_P(fn_type);
2184 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2187 arc_warn_func_return (tree decl)
2189 struct function *func = DECL_STRUCT_FUNCTION (decl);
2190 unsigned int fn_type = arc_compute_function_type (func);
2192 return !ARC_NAKED_P (fn_type);
2195 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2196 and two if they are nearly compatible (which causes a warning to be
2200 arc_comp_type_attributes (const_tree type1,
2203 int l1, l2, m1, m2, s1, s2;
2205 /* Check for mismatch of non-default calling convention. */
2206 if (TREE_CODE (type1) != FUNCTION_TYPE)
2209 /* Check for mismatched call attributes. */
2210 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
2211 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
2212 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
2213 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
2214 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
2215 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
2217 /* Only bother to check if an attribute is defined. */
2218 if (l1 | l2 | m1 | m2 | s1 | s2)
2220 /* If one type has an attribute, the other must have the same attribute. */
2221 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
2224 /* Disallow mixed attributes. */
2225 if (l1 + m1 + s1 > 1)
2233 /* Misc. utilities. */
2235 /* X and Y are two things to compare using CODE. Emit the compare insn and
2236 return the rtx for the cc reg in the proper mode. */
2239 gen_compare_reg (rtx comparison, machine_mode omode)
2241 enum rtx_code code = GET_CODE (comparison);
2242 rtx x = XEXP (comparison, 0);
2243 rtx y = XEXP (comparison, 1);
2245 machine_mode mode, cmode;
2248 cmode = GET_MODE (x);
2249 if (cmode == VOIDmode)
2250 cmode = GET_MODE (y);
2251 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode);
2252 if (cmode == SImode)
2254 if (!register_operand (x, SImode))
2256 if (register_operand (y, SImode))
2261 code = swap_condition (code);
2264 x = copy_to_mode_reg (SImode, x);
2266 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
2267 y = copy_to_mode_reg (SImode, y);
2271 x = force_reg (cmode, x);
2272 y = force_reg (cmode, y);
2274 mode = SELECT_CC_MODE (code, x, y);
2276 cc_reg = gen_rtx_REG (mode, CC_REG);
2278 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2279 cmpdfpx_raw, is not a correct comparison for floats:
2280 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2282 if (TARGET_ARGONAUT_SET
2283 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2287 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
2288 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2290 case GT: case UNLE: case GE: case UNLT:
2291 code = swap_condition (code);
2299 if (cmode == SFmode)
2301 emit_insn (gen_cmpsfpx_raw (x, y));
2305 /* Accepts Dx regs directly by insns. */
2306 emit_insn (gen_cmpdfpx_raw (x, y));
2309 if (mode != CC_FPXmode)
2310 emit_insn (gen_rtx_SET (cc_reg,
2311 gen_rtx_COMPARE (mode,
2312 gen_rtx_REG (CC_FPXmode, 61),
2315 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2319 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2320 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2322 case LT: case UNGE: case LE: case UNGT:
2323 code = swap_condition (code);
2332 emit_insn (gen_cmp_quark (cc_reg,
2333 gen_rtx_COMPARE (mode, x, y)));
2335 else if (TARGET_HARD_FLOAT
2336 && ((cmode == SFmode && TARGET_FP_SP_BASE)
2337 || (cmode == DFmode && TARGET_FP_DP_BASE)))
2338 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2339 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
2341 rtx op0 = gen_rtx_REG (cmode, 0);
2342 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
2347 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2348 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2350 case LT: case UNGE: case LE: case UNGT:
2351 code = swap_condition (code);
2357 if (currently_expanding_to_rtl)
2365 emit_move_insn (op0, x);
2366 emit_move_insn (op1, y);
2370 gcc_assert (rtx_equal_p (op0, x));
2371 gcc_assert (rtx_equal_p (op1, y));
2378 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2381 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2382 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
2385 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2386 We assume the value can be either signed or unsigned. */
2389 arc_double_limm_p (rtx value)
2391 HOST_WIDE_INT low, high;
2393 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2398 low = CONST_DOUBLE_LOW (value);
2399 high = CONST_DOUBLE_HIGH (value);
2401 if (low & 0x80000000)
2403 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
2404 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
2405 == - (unsigned HOST_WIDE_INT) 0x80000000)
2410 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2414 /* Do any needed setup for a variadic function. For the ARC, we must
2415 create a register parameter block, and then copy any anonymous arguments
2416 in registers to memory.
2418 CUM has not been updated for the last named argument (which is given
2419 by ARG), and we rely on this fact. */
2422 arc_setup_incoming_varargs (cumulative_args_t args_so_far,
2423 const function_arg_info &arg,
2424 int *pretend_size, int no_rtl)
2427 CUMULATIVE_ARGS next_cum;
2429 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2431 next_cum = *get_cumulative_args (args_so_far);
2432 arc_function_arg_advance (pack_cumulative_args (&next_cum), arg);
2433 first_anon_arg = next_cum;
2435 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2437 /* First anonymous (unnamed) argument is in a reg. */
2439 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2440 int first_reg_offset = first_anon_arg;
2445 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2446 FIRST_PARM_OFFSET (0)));
2447 move_block_from_reg (first_reg_offset, regblock,
2448 MAX_ARC_PARM_REGS - first_reg_offset);
2452 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2456 /* Cost functions. */
2458 /* Provide the costs of an addressing mode that contains ADDR.
2459 If ADDR is not a valid address, its cost is irrelevant. */
2462 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2464 switch (GET_CODE (addr))
2467 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1;
2468 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2469 case PRE_MODIFY: case POST_MODIFY:
2475 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2477 /* Most likely needs a LIMM. */
2478 return COSTS_N_INSNS (1);
2482 register rtx plus0 = XEXP (addr, 0);
2483 register rtx plus1 = XEXP (addr, 1);
2485 if (GET_CODE (plus0) != REG
2486 && (GET_CODE (plus0) != MULT
2487 || !CONST_INT_P (XEXP (plus0, 1))
2488 || (INTVAL (XEXP (plus0, 1)) != 2
2489 && INTVAL (XEXP (plus0, 1)) != 4)))
2492 switch (GET_CODE (plus1))
2495 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2499 : (satisfies_constraint_Rcq (plus0)
2500 && satisfies_constraint_O (plus1))
2504 return (speed < 1 ? 0
2505 : (satisfies_constraint_Rcq (plus0)
2506 && satisfies_constraint_Rcq (plus1))
2511 return COSTS_N_INSNS (1);
2524 /* Emit instruction X with the frame related bit set. */
2530 RTX_FRAME_RELATED_P (x) = 1;
2534 /* Emit a frame insn to move SRC to DST. */
2537 frame_move (rtx dst, rtx src)
2539 rtx tmp = gen_rtx_SET (dst, src);
2540 RTX_FRAME_RELATED_P (tmp) = 1;
2541 return frame_insn (tmp);
2544 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2545 auto increment address, or is zero. */
2548 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2550 rtx insn = frame_move (dst, src);
2553 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2554 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2555 add_reg_note (insn, REG_INC, reg);
2559 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2562 frame_add (rtx reg, HOST_WIDE_INT offset)
2564 gcc_assert ((offset & 0x3) == 0);
2567 return frame_move (reg, plus_constant (Pmode, reg, offset));
2570 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2573 frame_stack_add (HOST_WIDE_INT offset)
2575 return frame_add (stack_pointer_rtx, offset);
2578 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2579 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2580 Register Allocator) pass, while we want to get the frame size
2581 correct earlier than the IRA pass.
2583 When a function uses eh_return we must ensure that the fp register
2584 is saved and then restored so that the unwinder can restore the
2585 correct value for the frame we are going to jump to.
2587 To do this we force all frames that call eh_return to require a
2588 frame pointer (see arc_frame_pointer_required), this
2589 will ensure that the previous frame pointer is stored on entry to
2590 the function, and will then be reloaded at function exit.
2592 As the frame pointer is handled as a special case in our prologue
2593 and epilogue code it must not be saved and restored using the
2594 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2595 believes that the function is not using a frame pointer and that
2596 the value in the fp register is the frame pointer, while the
2597 prologue and epilogue are busy saving and restoring the fp
2600 During compilation of a function the frame size is evaluated
2601 multiple times, it is not until the reload pass is complete the the
2602 frame size is considered fixed (it is at this point that space for
2603 all spills has been allocated). However the frame_pointer_needed
2604 variable is not set true until the register allocation pass, as a
2605 result in the early stages the frame size does not include space
2606 for the frame pointer to be spilled.
2608 The problem that this causes is that the rtl generated for
2609 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2610 the offset from the frame pointer at which the return address
2611 lives. However, in early passes GCC has not yet realised we need a
2612 frame pointer, and so has not included space for the frame pointer
2613 in the frame size, and so gets the offset of the return address
2614 wrong. This should not be an issue as in later passes GCC has
2615 realised that the frame pointer needs to be spilled, and has
2616 increased the frame size. However, the rtl for the
2617 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2618 offset, and the wrong smaller offset is used. */
2621 arc_frame_pointer_needed (void)
2623 return (frame_pointer_needed || crtl->calls_eh_return);
2626 /* Tell prologue and epilogue if register REGNO should be saved /
2627 restored. The SPECIAL_P is true when the register may need special
2628 ld/st sequence. The return address, and stack pointer are treated
2629 separately. Don't consider them here. */
2632 arc_must_save_register (int regno, struct function *func, bool special_p)
2634 unsigned int fn_type = arc_compute_function_type (func);
2635 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2636 && ARC_AUTO_IRQ_P (fn_type));
2637 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2639 switch (rgf_banked_register_count)
2642 firq_auto_save_p &= (regno < 4);
2645 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2648 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2649 || ((regno > 25) && (regno < 29))
2650 || ((regno > 29) && (regno < 32)));
2653 firq_auto_save_p &= (regno != 29) && (regno < 32);
2656 firq_auto_save_p = false;
2663 case RETURN_ADDR_REGNUM:
2664 case STACK_POINTER_REGNUM:
2665 /* The stack pointer and the return address are handled
2670 /* r30 is either used as ilink2 by ARCv1 or as a free register
2681 /* If those ones are used by the FPX machinery, we handle them
2683 if (TARGET_DPFP && !special_p)
2710 /* The Extension Registers. */
2711 if (ARC_INTERRUPT_P (fn_type)
2712 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2713 || df_regs_ever_live_p (regno))
2714 /* Not all extension registers are available, choose the
2716 && !fixed_regs[regno])
2723 /* Fixed/control register, nothing to do. LP_COUNT is
2727 case HARD_FRAME_POINTER_REGNUM:
2728 /* If we need FP reg as a frame pointer then don't save it as a
2730 if (arc_frame_pointer_needed ())
2738 if (((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
2739 /* In an interrupt save everything. */
2740 || (ARC_INTERRUPT_P (fn_type)
2741 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2742 || df_regs_ever_live_p (regno))))
2743 /* Do not emit code for auto saved regs. */
2745 && !firq_auto_save_p)
2750 /* Return true if the return address must be saved in the current function,
2751 otherwise return false. */
2754 arc_must_save_return_addr (struct function *func)
2756 if (func->machine->frame_info.save_return_addr)
2762 /* Return non-zero if there are registers to be saved or loaded using
2763 millicode thunks. We can only use consecutive sequences starting
2764 with r13, and not going beyond r25.
2765 GMASK is a bitmask of registers to save. This function sets
2766 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2767 of registers to be saved / restored with a millicode call. */
2770 arc_compute_millicode_save_restore_regs (uint64_t gmask,
2771 struct arc_frame_info *frame)
2775 int start_reg = 13, end_reg = 25;
2777 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
2779 end_reg = regno - 1;
2780 /* There is no point in using millicode thunks if we don't save/restore
2781 at least three registers. For non-leaf functions we also have the
2783 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2785 frame->millicode_start_reg = 13;
2786 frame->millicode_end_reg = regno - 1;
2792 /* Return the bytes needed to compute the frame pointer from the
2793 current stack pointer. */
2796 arc_compute_frame_size (void)
2799 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2800 unsigned int reg_size;
2802 struct arc_frame_info *frame_info;
2804 unsigned int extra_plus_reg_size;
2805 unsigned int extra_plus_reg_size_aligned;
2807 /* The answer might already be known. */
2808 if (cfun->machine->frame_info.initialized)
2809 return cfun->machine->frame_info.total_size;
2811 frame_info = &cfun->machine->frame_info;
2812 size = ARC_STACK_ALIGN (get_frame_size ());
2814 /* 1) Size of locals and temporaries. */
2817 /* 2) Size of outgoing arguments. */
2818 args_size = crtl->outgoing_args_size;
2820 /* 3) Calculate space needed for saved registers.
2821 ??? We ignore the extension registers for now. */
2823 /* See if this is an interrupt handler. Call used registers must be saved
2829 /* The last 4 regs are special, avoid them. */
2830 for (regno = 0; regno <= (GMASK_LEN - 4); regno++)
2832 if (arc_must_save_register (regno, cfun, false))
2834 reg_size += UNITS_PER_WORD;
2835 gmask |= 1ULL << regno;
2839 /* In a frame that calls __builtin_eh_return two data registers are
2840 used to pass values back to the exception handler.
2842 Ensure that these registers are spilled to the stack so that the
2843 exception throw code can find them, and update the saved values.
2844 The handling code will then consume these reloaded values to
2845 handle the exception. */
2846 if (crtl->calls_eh_return)
2847 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
2849 reg_size += UNITS_PER_WORD;
2850 gmask |= 1ULL << regno;
2853 /* Check if we need to save the return address. */
2854 frame_info->save_return_addr = (!crtl->is_leaf
2855 || df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2856 || crtl->calls_eh_return);
2858 /* Saving blink reg for millicode thunk calls. */
2859 if (TARGET_MILLICODE_THUNK_SET
2860 && !crtl->calls_eh_return
2861 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
2863 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2864 frame_info->save_return_addr = true;
2867 /* Save lp_count, lp_start and lp_end. */
2868 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
2869 reg_size += UNITS_PER_WORD * 3;
2871 /* Check for the special R40-R44 regs used by FPX extension. */
2872 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
2874 reg_size += UNITS_PER_WORD * 2;
2875 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R43_REG : R42_REG,
2877 reg_size += UNITS_PER_WORD * 2;
2879 /* 4) Calculate extra size made up of the blink + fp size. */
2881 if (arc_must_save_return_addr (cfun))
2883 if (arc_frame_pointer_needed ())
2886 /* 5) Space for variable arguments passed in registers */
2887 pretend_size = crtl->args.pretend_args_size;
2889 /* Ensure everything before the locals is aligned appropriately. */
2890 extra_plus_reg_size = extra_size + reg_size;
2891 extra_plus_reg_size_aligned = ARC_STACK_ALIGN (extra_plus_reg_size);
2892 reg_size = extra_plus_reg_size_aligned - extra_size;
2894 /* Compute total frame size. */
2895 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2897 /* It used to be the case that the alignment was forced at this
2898 point. However, that is dangerous, calculations based on
2899 total_size would be wrong. Given that this has never cropped up
2900 as an issue I've changed this to an assert for now. */
2901 gcc_assert (total_size == ARC_STACK_ALIGN (total_size));
2903 /* Save computed information. */
2904 frame_info->total_size = total_size;
2905 frame_info->extra_size = extra_size;
2906 frame_info->pretend_size = pretend_size;
2907 frame_info->var_size = var_size;
2908 frame_info->args_size = args_size;
2909 frame_info->reg_size = reg_size;
2910 frame_info->gmask = gmask;
2911 frame_info->initialized = reload_completed;
2913 /* Ok, we're done. */
2917 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2921 arc_dwarf_emit_irq_save_regs (void)
2923 rtx tmp, par, insn, reg;
2926 par = gen_rtx_SEQUENCE (VOIDmode,
2927 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
2928 + irq_ctrl_saved.irq_save_blink
2929 + irq_ctrl_saved.irq_save_lpcount
2932 /* Build the stack adjustment note for unwind info. */
2934 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
2935 + irq_ctrl_saved.irq_save_blink
2936 + irq_ctrl_saved.irq_save_lpcount);
2937 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
2938 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
2939 RTX_FRAME_RELATED_P (tmp) = 1;
2940 XVECEXP (par, 0, j++) = tmp;
2942 offset -= UNITS_PER_WORD;
2944 /* 1st goes LP_COUNT. */
2945 if (irq_ctrl_saved.irq_save_lpcount)
2947 reg = gen_rtx_REG (SImode, 60);
2948 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2949 tmp = gen_frame_mem (SImode, tmp);
2950 tmp = gen_rtx_SET (tmp, reg);
2951 RTX_FRAME_RELATED_P (tmp) = 1;
2952 XVECEXP (par, 0, j++) = tmp;
2953 offset -= UNITS_PER_WORD;
2956 /* 2nd goes BLINK. */
2957 if (irq_ctrl_saved.irq_save_blink)
2959 reg = gen_rtx_REG (SImode, 31);
2960 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2961 tmp = gen_frame_mem (SImode, tmp);
2962 tmp = gen_rtx_SET (tmp, reg);
2963 RTX_FRAME_RELATED_P (tmp) = 1;
2964 XVECEXP (par, 0, j++) = tmp;
2965 offset -= UNITS_PER_WORD;
2968 /* Build the parallel of the remaining registers recorded as saved
2970 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
2972 reg = gen_rtx_REG (SImode, i);
2973 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2974 tmp = gen_frame_mem (SImode, tmp);
2975 tmp = gen_rtx_SET (tmp, reg);
2976 RTX_FRAME_RELATED_P (tmp) = 1;
2977 XVECEXP (par, 0, j++) = tmp;
2978 offset -= UNITS_PER_WORD;
2981 /* Dummy insn used to anchor the dwarf info. */
2982 insn = emit_insn (gen_stack_irq_dwarf());
2983 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
2984 RTX_FRAME_RELATED_P (insn) = 1;
2987 /* Helper for prologue: emit frame store with pre_modify or pre_dec to
2988 save register REG on stack. An initial offset OFFSET can be passed
2992 frame_save_reg (rtx reg, HOST_WIDE_INT offset)
2998 rtx tmp = plus_constant (Pmode, stack_pointer_rtx,
2999 offset - GET_MODE_SIZE (GET_MODE (reg)));
3000 addr = gen_frame_mem (GET_MODE (reg),
3001 gen_rtx_PRE_MODIFY (Pmode,
3006 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
3007 stack_pointer_rtx));
3008 frame_move_inc (addr, reg, stack_pointer_rtx, 0);
3010 return GET_MODE_SIZE (GET_MODE (reg)) - offset;
3013 /* Helper used when saving AUX regs during ISR. */
3018 rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
3019 stack_pointer_rtx));
3020 rtx insn = emit_move_insn (stkslot, reg);
3021 RTX_FRAME_RELATED_P (insn) = 1;
3022 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3023 gen_rtx_SET (stack_pointer_rtx,
3024 plus_constant (Pmode, stack_pointer_rtx,
3025 -GET_MODE_SIZE (GET_MODE (reg)))));
3026 return GET_MODE_SIZE (GET_MODE (reg));
3029 /* Helper for epilogue: emit frame load with post_modify or post_inc
3030 to restore register REG from stack. The initial offset is passed
3034 frame_restore_reg (rtx reg, HOST_WIDE_INT offset)
3040 rtx tmp = plus_constant (Pmode, stack_pointer_rtx,
3041 offset + GET_MODE_SIZE (GET_MODE (reg)));
3042 addr = gen_frame_mem (GET_MODE (reg),
3043 gen_rtx_POST_MODIFY (Pmode,
3048 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
3049 stack_pointer_rtx));
3050 insn = frame_move_inc (reg, addr, stack_pointer_rtx, 0);
3051 add_reg_note (insn, REG_CFA_RESTORE, reg);
3053 if (reg == hard_frame_pointer_rtx)
3054 add_reg_note (insn, REG_CFA_DEF_CFA,
3055 plus_constant (Pmode, stack_pointer_rtx,
3056 GET_MODE_SIZE (GET_MODE (reg)) + offset));
3058 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3059 gen_rtx_SET (stack_pointer_rtx,
3060 plus_constant (Pmode, stack_pointer_rtx,
3061 GET_MODE_SIZE (GET_MODE (reg))
3064 return GET_MODE_SIZE (GET_MODE (reg)) + offset;
3067 /* Helper used when restoring AUX regs during ISR. */
3072 rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
3073 stack_pointer_rtx));
3074 rtx insn = emit_move_insn (reg, stkslot);
3075 RTX_FRAME_RELATED_P (insn) = 1;
3076 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3077 gen_rtx_SET (stack_pointer_rtx,
3078 plus_constant (Pmode, stack_pointer_rtx,
3079 GET_MODE_SIZE (GET_MODE (reg)))));
3080 return GET_MODE_SIZE (GET_MODE (reg));
3084 /* Check if we have a continous range to be save/restored with the
3085 help of enter/leave instructions. A vaild register range starts
3086 from $r13 and is up to (including) $r26. */
3089 arc_enter_leave_p (uint64_t gmask)
3092 unsigned int rmask = 0;
3097 for (regno = ENTER_LEAVE_START_REG;
3098 regno <= ENTER_LEAVE_END_REG && (gmask & (1ULL << regno)); regno++)
3099 rmask |= 1ULL << regno;
3107 /* ARC's prologue, save any needed call-saved regs (and call-used if
3108 this is an interrupt handler) for ARCompact ISA, using ST/STD
3112 arc_save_callee_saves (uint64_t gmask,
3115 HOST_WIDE_INT offset)
3118 int frame_allocated = 0;
3121 /* The home-grown ABI says link register is saved first. */
3124 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3125 frame_allocated += frame_save_reg (reg, offset);
3129 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3131 for (i = GMASK_LEN; i >= 0; i--)
3133 machine_mode save_mode = SImode;
3136 && ((i - 1) % 2 == 0)
3137 && ((gmask & (1ULL << i)) != 0)
3138 && ((gmask & (1ULL << (i - 1))) != 0))
3143 else if ((gmask & (1ULL << i)) == 0)
3146 reg = gen_rtx_REG (save_mode, i);
3147 frame_allocated += frame_save_reg (reg, offset);
3151 /* Check if we need to save the ZOL machinery. */
3152 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
3154 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3155 emit_insn (gen_rtx_SET (reg0,
3156 gen_rtx_UNSPEC_VOLATILE
3157 (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_START)),
3159 frame_allocated += push_reg (reg0);
3160 emit_insn (gen_rtx_SET (reg0,
3161 gen_rtx_UNSPEC_VOLATILE
3162 (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_END)),
3164 frame_allocated += push_reg (reg0);
3165 emit_move_insn (reg0, gen_rtx_REG (SImode, LP_COUNT));
3166 frame_allocated += push_reg (reg0);
3169 /* Save AUX regs used by FPX machinery. */
3170 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
3173 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3175 for (i = 0; i < 4; i++)
3177 emit_insn (gen_rtx_SET (reg0,
3178 gen_rtx_UNSPEC_VOLATILE
3179 (Pmode, gen_rtvec (1, GEN_INT (AUX_DPFP_START
3182 frame_allocated += push_reg (reg0);
3186 /* Save frame pointer if needed. First save the FP on stack, if not
3187 autosaved. Unfortunately, I cannot add it to gmask and use the
3188 above loop to save fp because our ABI states fp goes aftert all
3189 registers are saved. */
3192 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3196 /* Emit mov fp,sp. */
3197 if (arc_frame_pointer_needed ())
3198 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3200 return frame_allocated;
3203 /* ARC's epilogue, restore any required call-saved regs (and call-used
3204 if it is for an interrupt handler) using LD/LDD instructions. */
3207 arc_restore_callee_saves (uint64_t gmask,
3210 HOST_WIDE_INT offset,
3211 HOST_WIDE_INT allocated)
3214 int frame_deallocated = 0;
3215 HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
3216 bool early_blink_restore;
3219 /* Emit mov fp,sp. */
3220 if (arc_frame_pointer_needed () && offset)
3222 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3223 frame_deallocated += offset;
3229 /* Any offset is taken care by previous if-statement. */
3230 gcc_assert (offset == 0);
3231 frame_deallocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3234 /* Restore AUX-regs used by FPX machinery. */
3235 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
3238 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3240 gcc_assert (offset == 0);
3241 for (i = 0; i < 4; i++)
3243 frame_deallocated += pop_reg (reg0);
3244 emit_insn (gen_rtx_UNSPEC_VOLATILE
3245 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_DPFP_START
3251 /* Check if we need to restore the ZOL machinery. */
3252 if (arc_lpcwidth !=0 && arc_must_save_register (LP_COUNT, cfun, true))
3254 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3256 gcc_assert (offset == 0);
3257 frame_deallocated += pop_reg (reg0);
3258 emit_move_insn (gen_rtx_REG (SImode, LP_COUNT), reg0);
3260 frame_deallocated += pop_reg (reg0);
3261 emit_insn (gen_rtx_UNSPEC_VOLATILE
3262 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_END)),
3265 frame_deallocated += pop_reg (reg0);
3266 emit_insn (gen_rtx_UNSPEC_VOLATILE
3267 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_START)),
3273 /* No $fp involved, we need to do an add to set the $sp to the
3274 location of the first register. */
3275 frame_stack_add (offset);
3276 frame_deallocated += offset;
3280 /* When we do not optimize for size, restore first blink. */
3281 early_blink_restore = restore_blink && !optimize_size && offs
3282 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun));
3283 if (early_blink_restore)
3285 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
3286 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3287 rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr),
3288 stack_pointer_rtx, NULL_RTX);
3289 add_reg_note (insn, REG_CFA_RESTORE, reg);
3290 restore_blink = false;
3293 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3295 for (i = 0; i <= GMASK_LEN; i++)
3297 machine_mode restore_mode = SImode;
3301 && ((gmask & (1ULL << i)) != 0)
3302 && ((gmask & (1ULL << (i + 1))) != 0))
3303 restore_mode = DImode;
3304 else if ((gmask & (1ULL << i)) == 0)
3307 reg = gen_rtx_REG (restore_mode, i);
3309 switch (restore_mode)
3312 if ((GMASK_LEN - __builtin_clzll (gmask)) == (i + 1)
3313 && early_blink_restore)
3317 if ((GMASK_LEN - __builtin_clzll (gmask)) == i
3318 && early_blink_restore)
3324 frame_deallocated += frame_restore_reg (reg, offs);
3327 if (restore_mode == DImode)
3333 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3334 frame_deallocated += frame_restore_reg (reg, allocated
3336 /* Consider as well the
3342 return frame_deallocated;
3345 /* ARC prologue, save the registers using enter instruction. Leave
3346 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3350 arc_save_callee_enter (uint64_t gmask,
3353 HOST_WIDE_INT offset)
3355 int start_reg = ENTER_LEAVE_START_REG;
3356 int end_reg = ENTER_LEAVE_END_REG;
3357 int regno, indx, off, nregs;
3359 int frame_allocated = 0;
3361 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3364 end_reg = regno - 1;
3365 nregs = end_reg - start_reg + 1;
3366 nregs += save_blink ? 1 : 0;
3367 nregs += save_fp ? 1 : 0;
3370 frame_stack_add (offset);
3372 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + (save_fp ? 1 : 0)
3376 reg = gen_rtx_SET (stack_pointer_rtx,
3377 plus_constant (Pmode,
3379 -nregs * UNITS_PER_WORD));
3380 RTX_FRAME_RELATED_P (reg) = 1;
3381 XVECEXP (insn, 0, indx++) = reg;
3382 off = nregs * UNITS_PER_WORD;
3386 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3387 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3390 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3391 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3392 off -= UNITS_PER_WORD;
3396 for (regno = start_reg;
3398 regno++, indx++, off -= UNITS_PER_WORD)
3400 reg = gen_rtx_REG (SImode, regno);
3401 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3404 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3405 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3406 gmask = gmask & ~(1ULL << regno);
3411 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3414 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, hard_frame_pointer_rtx);
3415 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3416 off -= UNITS_PER_WORD;
3418 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx,
3420 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3424 gcc_assert (off == 0);
3425 insn = frame_insn (insn);
3427 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3429 frame_allocated = nregs * UNITS_PER_WORD;
3431 /* offset is a negative number, make sure we add it. */
3432 return frame_allocated - offset;
3435 /* ARC epilogue, restore the registers using leave instruction. An
3436 initial offset is passed in OFFSET. Besides restoring an register
3437 range, leave can also restore $blink (RESTORE_BLINK), or $fp
3438 (RESTORE_FP), and can automatic return (RETURN_P). */
3441 arc_restore_callee_leave (uint64_t gmask,
3445 HOST_WIDE_INT offset)
3447 int start_reg = ENTER_LEAVE_START_REG;
3448 int end_reg = ENTER_LEAVE_END_REG;
3449 int regno, indx, off, nregs;
3451 int frame_allocated = 0;
3453 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3456 end_reg = regno - 1;
3457 nregs = end_reg - start_reg + 1;
3458 nregs += restore_blink ? 1 : 0;
3459 nregs += restore_fp ? 1 : 0;
3461 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1
3462 + (return_p ? 1 : 0)));
3466 XVECEXP (insn, 0, indx++) = ret_rtx;
3470 /* I cannot emit set (sp, fp) here as cselib expects a single sp
3471 set and not two. Thus, use the offset, and change sp adjust
3473 frame_allocated += offset;
3476 if (offset && !restore_fp)
3478 /* This add is only emmited when we do not restore fp with leave
3480 frame_stack_add (offset);
3481 frame_allocated += offset;
3485 reg = gen_rtx_SET (stack_pointer_rtx,
3486 plus_constant (Pmode,
3488 offset + nregs * UNITS_PER_WORD));
3489 RTX_FRAME_RELATED_P (reg) = 1;
3490 XVECEXP (insn, 0, indx++) = reg;
3491 off = nregs * UNITS_PER_WORD;
3495 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3496 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3499 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3500 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3501 off -= UNITS_PER_WORD;
3504 for (regno = start_reg;
3506 regno++, indx++, off -= UNITS_PER_WORD)
3508 reg = gen_rtx_REG (SImode, regno);
3509 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3512 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3513 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3514 gmask = gmask & ~(1ULL << regno);
3519 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3522 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx, mem);
3523 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3524 off -= UNITS_PER_WORD;
3527 gcc_assert (off == 0);
3530 insn = emit_jump_insn (insn);
3531 RTX_FRAME_RELATED_P (insn) = 1;
3534 insn = frame_insn (insn);
3536 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3538 /* Dwarf related info. */
3541 add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
3542 add_reg_note (insn, REG_CFA_DEF_CFA,
3543 plus_constant (Pmode, stack_pointer_rtx,
3544 offset + nregs * UNITS_PER_WORD));
3548 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3549 gen_rtx_SET (stack_pointer_rtx,
3550 plus_constant (Pmode, stack_pointer_rtx,
3551 nregs * UNITS_PER_WORD)));
3554 add_reg_note (insn, REG_CFA_RESTORE,
3555 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3556 for (regno = start_reg; regno <= end_reg; regno++)
3557 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, regno));
3559 frame_allocated += nregs * UNITS_PER_WORD;
3561 return frame_allocated;
3564 /* Millicode thunks implementation:
3565 Generates calls to millicodes for registers starting from r13 to r25
3566 Present Limitations:
3567 - Only one range supported. The remaining regs will have the ordinary
3568 st and ld instructions for store and loads. Hence a gmask asking
3569 to store r13-14, r16-r25 will only generate calls to store and
3570 load r13 to r14 while store and load insns will be generated for
3571 r16 to r25 in the prologue and epilogue respectively.
3573 - Presently library only supports register ranges starting from r13.
3577 arc_save_callee_milli (uint64_t gmask,
3580 HOST_WIDE_INT offset,
3581 HOST_WIDE_INT reg_size)
3585 int regno, indx, off, nregs;
3587 int frame_allocated = 0;
3589 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3592 end_reg = regno - 1;
3593 nregs = end_reg - start_reg + 1;
3594 gcc_assert (end_reg > 14);
3597 /* Allocate space on stack for the registers, and take into account
3598 also the initial offset. The registers will be saved using
3599 offsets. N.B. OFFSET is a negative number. */
3602 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3603 frame_allocated += frame_save_reg (reg, offset);
3607 if (reg_size || offset)
3609 frame_stack_add (offset - reg_size);
3610 frame_allocated += nregs * UNITS_PER_WORD - offset;
3614 /* Start generate millicode call. */
3615 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
3618 /* This is a call, we clobber blink. */
3619 XVECEXP (insn, 0, nregs) =
3620 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3622 for (regno = start_reg, indx = 0, off = 0;
3624 regno++, indx++, off += UNITS_PER_WORD)
3626 reg = gen_rtx_REG (SImode, regno);
3627 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3630 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3631 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3632 gmask = gmask & ~(1ULL << regno);
3634 insn = frame_insn (insn);
3636 /* Add DWARF info. */
3637 for (regno = start_reg, off = 0;
3639 regno++, off += UNITS_PER_WORD)
3641 reg = gen_rtx_REG (SImode, regno);
3642 mem = gen_rtx_MEM (SImode, plus_constant (Pmode,
3643 stack_pointer_rtx, off));
3644 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
3648 /* In the case of millicode thunk, we need to restore the
3649 clobbered blink register. */
3650 if (arc_must_save_return_addr (cfun))
3652 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
3654 plus_constant (Pmode,
3659 /* Save remaining registers using st instructions. */
3660 for (regno = 0; regno <= GMASK_LEN; regno++)
3662 if ((gmask & (1ULL << regno)) == 0)
3665 reg = gen_rtx_REG (SImode, regno);
3666 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3669 frame_move_inc (mem, reg, stack_pointer_rtx, 0);
3670 frame_allocated += UNITS_PER_WORD;
3671 off += UNITS_PER_WORD;
3674 /* Save frame pointer if needed. First save the FP on stack, if not
3675 autosaved. Unfortunately, I cannot add it to gmask and use the
3676 above loop to save fp because our ABI states fp goes aftert all
3677 registers are saved. */
3679 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3681 /* Emit mov fp,sp. */
3682 if (arc_frame_pointer_needed ())
3683 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3685 return frame_allocated;
3688 /* Like the previous function but restore. */
3691 arc_restore_callee_milli (uint64_t gmask,
3695 HOST_WIDE_INT offset)
3699 int regno, indx, off, nregs;
3701 int frame_allocated = 0;
3703 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3706 end_reg = regno - 1;
3707 nregs = end_reg - start_reg + 1;
3708 gcc_assert (end_reg > 14);
3710 /* Emit mov fp,sp. */
3711 if (arc_frame_pointer_needed () && offset)
3713 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3714 frame_allocated = offset;
3719 frame_allocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3723 /* No fp involved, hence, we need to adjust the sp via an
3725 frame_stack_add (offset);
3726 frame_allocated += offset;
3730 /* Start generate millicode call. */
3731 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc ((return_p ? 1 : 0)
3737 /* sibling call, the blink is restored with the help of the
3738 value held into r12. */
3739 reg = gen_rtx_REG (Pmode, 12);
3740 XVECEXP (insn, 0, indx++) = ret_rtx;
3741 XVECEXP (insn, 0, indx++) =
3742 gen_rtx_SET (stack_pointer_rtx,
3743 gen_rtx_PLUS (Pmode, stack_pointer_rtx, reg));
3744 frame_allocated += UNITS_PER_WORD;
3748 /* This is a call, we clobber blink. */
3749 XVECEXP (insn, 0, nregs) =
3750 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3753 for (regno = start_reg, off = 0;
3755 regno++, indx++, off += UNITS_PER_WORD)
3757 reg = gen_rtx_REG (SImode, regno);
3758 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3761 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3762 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3763 gmask = gmask & ~(1ULL << regno);
3766 /* Restore remaining registers using LD instructions. */
3767 for (regno = 0; regno <= GMASK_LEN; regno++)
3769 if ((gmask & (1ULL << regno)) == 0)
3772 reg = gen_rtx_REG (SImode, regno);
3773 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3776 rtx tmp = frame_move_inc (reg, mem, stack_pointer_rtx, 0);
3777 add_reg_note (tmp, REG_CFA_RESTORE, reg);
3778 off += UNITS_PER_WORD;
3781 /* Emit millicode call. */
3784 reg = gen_rtx_REG (Pmode, 12);
3785 frame_insn (gen_rtx_SET (reg, GEN_INT (off)));
3786 frame_allocated += off;
3787 insn = emit_jump_insn (insn);
3788 RTX_FRAME_RELATED_P (insn) = 1;
3791 insn = frame_insn (insn);
3793 /* Add DWARF info. */
3794 for (regno = start_reg; regno <= end_reg; regno++)
3796 reg = gen_rtx_REG (SImode, regno);
3797 add_reg_note (insn, REG_CFA_RESTORE, reg);
3801 if (restore_blink && !return_p)
3803 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3804 mem = gen_frame_mem (Pmode, plus_constant (Pmode, stack_pointer_rtx,
3806 insn = frame_insn (gen_rtx_SET (reg, mem));
3807 add_reg_note (insn, REG_CFA_RESTORE, reg);
3810 return frame_allocated;
3813 /* Set up the stack and frame pointer (if desired) for the function. */
3816 arc_expand_prologue (void)
3819 uint64_t gmask = cfun->machine->frame_info.gmask;
3820 struct arc_frame_info *frame = &cfun->machine->frame_info;
3821 unsigned int frame_size_to_allocate;
3822 int first_offset = 0;
3823 unsigned int fn_type = arc_compute_function_type (cfun);
3824 bool save_blink = false;
3825 bool save_fp = false;
3827 /* Naked functions don't have prologue. */
3828 if (ARC_NAKED_P (fn_type))
3830 if (flag_stack_usage_info)
3831 current_function_static_stack_size = 0;
3835 /* Compute total frame size. */
3836 size = arc_compute_frame_size ();
3838 if (flag_stack_usage_info)
3839 current_function_static_stack_size = size;
3841 /* Keep track of frame size to be allocated. */
3842 frame_size_to_allocate = size;
3844 /* These cases shouldn't happen. Catch them now. */
3845 gcc_assert (!(size == 0 && gmask));
3847 /* Allocate space for register arguments if this is a variadic function. */
3848 if (frame->pretend_size != 0)
3849 first_offset = -frame->pretend_size;
3851 /* IRQ using automatic save mechanism will save the register before
3853 if (ARC_AUTO_IRQ_P (fn_type)
3854 && !ARC_FAST_INTERRUPT_P (fn_type))
3856 frame_stack_add (first_offset);
3858 arc_dwarf_emit_irq_save_regs ();
3861 save_blink = arc_must_save_return_addr (cfun)
3862 && !ARC_AUTOBLINK_IRQ_P (fn_type);
3863 save_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type);
3865 /* Use enter/leave only for non-interrupt functions. */
3866 if (TARGET_CODE_DENSITY
3867 && TARGET_CODE_DENSITY_FRAME
3868 && !ARC_AUTOFP_IRQ_P (fn_type)
3869 && !ARC_AUTOBLINK_IRQ_P (fn_type)
3870 && !ARC_INTERRUPT_P (fn_type)
3871 && arc_enter_leave_p (gmask))
3872 frame_size_to_allocate -= arc_save_callee_enter (gmask, save_blink,
3875 else if (frame->millicode_end_reg > 14)
3876 frame_size_to_allocate -= arc_save_callee_milli (gmask, save_blink,
3881 frame_size_to_allocate -= arc_save_callee_saves (gmask, save_blink, save_fp,
3884 /* Allocate the stack frame. */
3885 if (frame_size_to_allocate > 0)
3886 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3888 /* Emit a blockage to avoid delay slot scheduling. */
3889 emit_insn (gen_blockage ());
3892 /* Return the register number of the register holding the return address
3893 for a function of type TYPE. */
3896 arc_return_address_register (unsigned int fn_type)
3900 if (ARC_INTERRUPT_P (fn_type))
3902 if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
3904 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
3909 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
3910 regno = RETURN_ADDR_REGNUM;
3912 gcc_assert (regno != 0);
3916 /* Do any necessary cleanup after a function to restore stack, frame,
3920 arc_expand_epilogue (int sibcall_p)
3923 unsigned int fn_type = arc_compute_function_type (cfun);
3924 unsigned int size_to_deallocate;
3926 int can_trust_sp_p = !cfun->calls_alloca;
3928 bool restore_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type);
3929 bool restore_blink = arc_must_save_return_addr (cfun)
3930 && !ARC_AUTOBLINK_IRQ_P (fn_type);
3931 uint64_t gmask = cfun->machine->frame_info.gmask;
3932 bool return_p = !sibcall_p && fn_type == ARC_FUNCTION_NORMAL
3933 && !cfun->machine->frame_info.pretend_size;
3934 struct arc_frame_info *frame = &cfun->machine->frame_info;
3936 /* Naked functions don't have epilogue. */
3937 if (ARC_NAKED_P (fn_type))
3940 size = arc_compute_frame_size ();
3941 size_to_deallocate = size;
3943 first_offset = size - (frame->pretend_size + frame->reg_size
3944 + frame->extra_size);
3946 if (!can_trust_sp_p)
3947 gcc_assert (arc_frame_pointer_needed ());
3949 /* Emit a blockage to avoid/flush all pending sp operations. */
3951 emit_insn (gen_blockage ());
3953 if (TARGET_CODE_DENSITY
3954 && TARGET_CODE_DENSITY_FRAME
3955 && !ARC_AUTOFP_IRQ_P (fn_type)
3956 && !ARC_AUTOBLINK_IRQ_P (fn_type)
3957 && !ARC_INTERRUPT_P (fn_type)
3958 && arc_enter_leave_p (gmask))
3960 /* Using leave instruction. */
3961 size_to_deallocate -= arc_restore_callee_leave (gmask, restore_blink,
3967 gcc_assert (size_to_deallocate == 0);
3971 else if (frame->millicode_end_reg > 14)
3973 /* Using millicode calls. */
3974 size_to_deallocate -= arc_restore_callee_milli (gmask, restore_blink,
3980 gcc_assert (size_to_deallocate == 0);
3985 size_to_deallocate -= arc_restore_callee_saves (gmask, restore_blink,
3988 size_to_deallocate);
3990 /* Keep track of how much of the stack pointer we've restored. It
3991 makes the following a lot more readable. */
3992 restored = size - size_to_deallocate;
3994 if (size > restored)
3995 frame_stack_add (size - restored);
3997 /* For frames that use __builtin_eh_return, the register defined by
3998 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
3999 On eh_return paths however, the register is set to the value that
4000 should be added to the stack pointer in order to restore the
4001 correct stack pointer for the exception handling frame.
4003 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
4004 this onto the stack for eh_return frames. */
4005 if (crtl->calls_eh_return)
4006 emit_insn (gen_add2_insn (stack_pointer_rtx,
4007 EH_RETURN_STACKADJ_RTX));
4009 /* Emit the return instruction. */
4010 if (ARC_INTERRUPT_P (fn_type))
4012 rtx ra = gen_rtx_REG (Pmode, arc_return_address_register (fn_type));
4015 emit_jump_insn (gen_rtie ());
4016 else if (TARGET_ARC700)
4017 emit_jump_insn (gen_rtie ());
4019 emit_jump_insn (gen_arc600_rtie (ra));
4021 else if (sibcall_p == FALSE)
4022 emit_jump_insn (gen_simple_return ());
4025 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable
4026 construct to match either enter or leave instruction. Which one
4027 which is selected by PUSH_P argument. */
4030 arc_check_multi (rtx op, bool push_p)
4032 HOST_WIDE_INT len = XVECLEN (op, 0);
4033 unsigned int regno, i, start;
4034 unsigned int memp = push_p ? 0 : 1;
4041 elt = XVECEXP (op, 0, 0);
4042 if (!push_p && GET_CODE (elt) == RETURN)
4045 for (i = start, regno = ENTER_LEAVE_START_REG; i < len; i++, regno++)
4047 rtx elt = XVECEXP (op, 0, i);
4050 if (GET_CODE (elt) != SET)
4052 mem = XEXP (elt, memp);
4053 reg = XEXP (elt, 1 - memp);
4059 /* Check for blink. */
4060 if (REGNO (reg) == RETURN_ADDR_REGNUM
4063 else if (REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
4065 else if (REGNO (reg) != regno)
4068 addr = XEXP (mem, 0);
4069 if (GET_CODE (addr) == PLUS)
4071 if (!rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
4072 || !CONST_INT_P (XEXP (addr, 1)))
4077 if (!rtx_equal_p (stack_pointer_rtx, addr))
4084 /* Return rtx for the location of the return address on the stack,
4085 suitable for use in __builtin_eh_return. The new return address
4086 will be written to this location in order to redirect the return to
4087 the exception handler. Our ABI says the blink is pushed first on
4088 stack followed by an unknown number of register saves, and finally
4089 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the
4090 stack is not finalized. */
4093 arc_eh_return_address_location (rtx source)
4097 struct arc_frame_info *afi;
4099 arc_compute_frame_size ();
4100 afi = &cfun->machine->frame_info;
4102 gcc_assert (crtl->calls_eh_return);
4103 gcc_assert (afi->save_return_addr);
4104 gcc_assert (afi->extra_size >= 4);
4106 /* The '-4' removes the size of the return address, which is
4107 included in the 'extra_size' field. */
4108 offset = afi->reg_size + afi->extra_size - 4;
4109 mem = gen_frame_mem (Pmode,
4110 plus_constant (Pmode, hard_frame_pointer_rtx, offset));
4112 /* The following should not be needed, and is, really a hack. The
4113 issue being worked around here is that the DSE (Dead Store
4114 Elimination) pass will remove this write to the stack as it sees
4115 a single store and no corresponding read. The read however
4116 occurs in the epilogue code, which is not added into the function
4117 rtl until a later pass. So, at the time of DSE, the decision to
4118 remove this store seems perfectly sensible. Marking the memory
4119 address as volatile obviously has the effect of preventing DSE
4120 from removing the store. */
4121 MEM_VOLATILE_P (mem) = true;
4122 emit_move_insn (mem, source);
4127 /* Helper to generate unspec constant. */
4130 arc_unspec_offset (rtx loc, int unspec)
4132 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
4136 /* !TARGET_BARREL_SHIFTER support. */
4137 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
4141 emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
4143 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
4145 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop)
4146 (op0, op1, op2, shift));
4150 /* Output the assembler code for doing a shift.
4151 We go to a bit of trouble to generate efficient code as the ARC601 only has
4152 single bit shifts. This is taken from the h8300 port. We only have one
4153 mode of shifting and can't access individual bytes like the h8300 can, so
4154 this is greatly simplified (at the expense of not generating hyper-
4157 This function is not used if the variable shift insns are present. */
4159 /* FIXME: This probably can be done using a define_split in arc.md.
4160 Alternately, generate rtx rather than output instructions. */
4163 output_shift (rtx *operands)
4165 /* static int loopend_lab;*/
4166 rtx shift = operands[3];
4167 machine_mode mode = GET_MODE (shift);
4168 enum rtx_code code = GET_CODE (shift);
4169 const char *shift_one;
4171 gcc_assert (mode == SImode);
4175 case ASHIFT: shift_one = "add %0,%1,%1"; break;
4176 case ASHIFTRT: shift_one = "asr %0,%1"; break;
4177 case LSHIFTRT: shift_one = "lsr %0,%1"; break;
4178 default: gcc_unreachable ();
4181 if (GET_CODE (operands[2]) != CONST_INT)
4183 output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
4190 n = INTVAL (operands[2]);
4192 /* Only consider the lower 5 bits of the shift count. */
4195 /* First see if we can do them inline. */
4196 /* ??? We could get better scheduling & shorter code (using short insns)
4197 by using splitters. Alas, that'd be even more verbose. */
4198 if (code == ASHIFT && n <= 9 && n > 2
4199 && dest_reg_operand (operands[4], SImode))
4201 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
4202 for (n -=3 ; n >= 3; n -= 3)
4203 output_asm_insn ("add3 %0,%4,%0", operands);
4205 output_asm_insn ("add2 %0,%4,%0", operands);
4207 output_asm_insn ("add %0,%0,%0", operands);
4213 output_asm_insn (shift_one, operands);
4214 operands[1] = operands[0];
4217 /* See if we can use a rotate/and. */
4218 else if (n == BITS_PER_WORD - 1)
4223 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
4226 /* The ARC doesn't have a rol insn. Use something else. */
4227 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
4230 /* The ARC doesn't have a rol insn. Use something else. */
4231 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
4237 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
4242 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
4245 #if 1 /* Need some scheduling comparisons. */
4246 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
4247 "add.f 0,%4,%4\n\trlc %0,%0", operands);
4249 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
4250 "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
4255 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
4256 "add.f 0,%4,%4\n\trlc %0,%0", operands);
4258 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
4259 "and %0,%0,1\n\trlc %0,%0", operands);
4266 else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
4267 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
4272 operands[2] = GEN_INT (n);
4273 output_asm_insn ("mov.f lp_count, %2", operands);
4277 output_asm_insn ("lpnz\t2f", operands);
4278 output_asm_insn (shift_one, operands);
4279 output_asm_insn ("nop", operands);
4280 fprintf (asm_out_file, "2:\t%s end single insn loop\n",
4289 /* Nested function support. */
4291 /* Output assembler code for a block containing the constant parts of
4292 a trampoline, leaving space for variable parts. A trampoline looks
4298 .word function's address
4299 .word static chain value
4304 arc_asm_trampoline_template (FILE *f)
4306 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG);
4307 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]);
4308 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG);
4309 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4310 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4313 /* Emit RTL insns to initialize the variable parts of a trampoline.
4314 FNADDR is an RTX for the address of the function's pure code. CXT
4315 is an RTX for the static chain value for the function.
4317 The fastest trampoline to execute for trampolines within +-8KB of CTX
4321 j [limm] 0x20200f80 limm
4323 and that would also be faster to write to the stack by computing
4324 the offset from CTX to TRAMP at compile time. However, it would
4325 really be better to get rid of the high cost of cache invalidation
4326 when generating trampolines, which requires that the code part of
4327 trampolines stays constant, and additionally either making sure
4328 that no executable code but trampolines is on the stack, no icache
4329 entries linger for the area of the stack from when before the stack
4330 was allocated, and allocating trampolines in trampoline-only cache
4331 lines or allocate trampolines fram a special pool of pre-allocated
4335 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
4337 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
4339 emit_block_move (tramp, assemble_trampoline_template (),
4340 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4341 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
4342 emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
4343 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
4344 LCT_NORMAL, VOIDmode, XEXP (tramp, 0), Pmode,
4345 plus_constant (Pmode, XEXP (tramp, 0), TRAMPOLINE_SIZE),
4349 /* Add the given function declaration to emit code in JLI section. */
4352 arc_add_jli_section (rtx pat)
4356 arc_jli_section *sec = arc_jli_sections, *new_section;
4357 tree decl = SYMBOL_REF_DECL (pat);
4364 /* For fixed locations do not generate the jli table entry. It
4365 should be provided by the user as an asm file. */
4366 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
4367 if (lookup_attribute ("jli_fixed", attrs))
4371 name = XSTR (pat, 0);
4373 /* Don't insert the same symbol twice. */
4376 if(strcmp (name, sec->name) == 0)
4381 /* New name, insert it. */
4382 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
4383 gcc_assert (new_section != NULL);
4384 new_section->name = name;
4385 new_section->next = arc_jli_sections;
4386 arc_jli_sections = new_section;
4389 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4390 reset when we output the scaled address. */
4391 static int output_scaled = 0;
4393 /* Set when we force sdata output. */
4394 static int output_sdata = 0;
4396 /* Print operand X (an rtx) in assembler syntax to file FILE.
4397 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4398 For `%' followed by punctuation, CODE is the punctuation and X is null. */
4399 /* In final.c:output_asm_insn:
4402 'c' : constant address if CONSTANT_ADDRESS_P
4408 'p': bit Position of lsb
4409 's': size of bit field
4410 '#': condbranch delay slot suffix
4411 '*': jump delay slot suffix
4412 '?' : nonjump-insn suffix for conditional execution or short instruction
4413 '!' : jump / call suffix for conditional execution or short instruction
4414 '`': fold constant inside unary o-perator, re-recognize, and emit.
4418 'S': JLI instruction
4419 'j': used by mov instruction to properly emit jli related labels.
4420 'B': Branch comparison operand - suppress sda reference
4421 'H': Most significant word
4422 'L': Least significant word
4423 'A': ASCII decimal representation of floating point value
4424 'U': Load/store update or scaling indicator
4425 'V': cache bypass indicator for volatile
4430 'o': original symbol - no @ prepending. */
4433 arc_print_operand (FILE *file, rtx x, int code)
4438 if (GET_CODE (x) == CONST_INT)
4439 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
4441 output_operand_lossage ("invalid operand to %%Z code");
4446 if (GET_CODE (x) == CONST_INT)
4447 fprintf (file, "%d",exact_log2 (INTVAL (x) & 0xffffffff));
4449 output_operand_lossage ("invalid operand to %%z code");
4454 if (GET_CODE (x) == CONST_INT)
4455 fprintf (file, "%ld", INTVAL (x) );
4457 output_operand_lossage ("invalid operands to %%c code");
4462 if (GET_CODE (x) == CONST_INT)
4463 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
4465 output_operand_lossage ("invalid operand to %%M code");
4470 if (GET_CODE (x) == CONST_INT)
4471 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
4473 output_operand_lossage ("invalid operand to %%p code");
4477 if (GET_CODE (x) == CONST_INT)
4479 HOST_WIDE_INT i = INTVAL (x);
4480 HOST_WIDE_INT s = exact_log2 (i & -i);
4481 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
4484 output_operand_lossage ("invalid operand to %%s code");
4488 /* Conditional branches depending on condition codes.
4489 Note that this is only for branches that were known to depend on
4490 condition codes before delay slot scheduling;
4491 out-of-range brcc / bbit expansions should use '*'.
4492 This distinction is important because of the different
4493 allowable delay slot insns and the output of the delay suffix
4494 for TARGET_AT_DBR_COND_EXEC. */
4496 /* Unconditional branches / branches not depending on condition codes.
4497 This could also be a CALL_INSN.
4498 Output the appropriate delay slot suffix. */
4499 if (final_sequence && final_sequence->len () != 1)
4501 rtx_insn *jump = final_sequence->insn (0);
4502 rtx_insn *delay = final_sequence->insn (1);
4504 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
4505 if (delay->deleted ())
4507 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
4508 fputs (INSN_FROM_TARGET_P (delay) ? ".d"
4509 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d"
4510 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? ""
4517 case '?' : /* with leading "." */
4518 case '!' : /* without leading "." */
4519 /* This insn can be conditionally executed. See if the ccfsm machinery
4520 says it should be conditionalized.
4521 If it shouldn't, we'll check the compact attribute if this insn
4522 has a short variant, which may be used depending on code size and
4523 alignment considerations. */
4524 if (current_insn_predicate)
4525 arc_ccfsm_current.cc
4526 = get_arc_condition_code (current_insn_predicate);
4527 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current))
4529 /* Is this insn in a delay slot sequence? */
4530 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
4531 || current_insn_predicate
4532 || CALL_P (final_sequence->insn (0))
4533 || simplejump_p (final_sequence->insn (0)))
4535 /* This insn isn't in a delay slot sequence, or conditionalized
4536 independently of its position in a delay slot. */
4537 fprintf (file, "%s%s",
4538 code == '?' ? "." : "",
4539 arc_condition_codes[arc_ccfsm_current.cc]);
4540 /* If this is a jump, there are still short variants. However,
4541 only beq_s / bne_s have the same offset range as b_s,
4542 and the only short conditional returns are jeq_s and jne_s. */
4544 && (arc_ccfsm_current.cc == ARC_CC_EQ
4545 || arc_ccfsm_current.cc == ARC_CC_NE
4546 || 0 /* FIXME: check if branch in 7 bit range. */))
4547 output_short_suffix (file);
4549 else if (code == '!') /* Jump with delay slot. */
4550 fputs (arc_condition_codes[arc_ccfsm_current.cc], file);
4551 else /* An Instruction in a delay slot of a jump or call. */
4553 rtx jump = XVECEXP (final_sequence, 0, 0);
4554 rtx insn = XVECEXP (final_sequence, 0, 1);
4556 /* If the insn is annulled and is from the target path, we need
4557 to inverse the condition test. */
4558 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
4560 if (INSN_FROM_TARGET_P (insn))
4561 fprintf (file, "%s%s",
4562 code == '?' ? "." : "",
4563 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]);
4565 fprintf (file, "%s%s",
4566 code == '?' ? "." : "",
4567 arc_condition_codes[arc_ccfsm_current.cc]);
4568 if (arc_ccfsm_current.state == 5)
4569 arc_ccfsm_current.state = 0;
4572 /* This insn is executed for either path, so don't
4573 conditionalize it at all. */
4574 output_short_suffix (file);
4579 output_short_suffix (file);
4582 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
4585 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
4588 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
4589 (get_arc_condition_code (x))],
4593 /* Write second word of DImode or DFmode reference,
4594 register or memory. */
4595 if (GET_CODE (x) == REG)
4596 fputs (reg_names[REGNO (x)+1], file);
4597 else if (GET_CODE (x) == MEM)
4601 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4602 PRE_MODIFY, we will have handled the first word already;
4603 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4604 first word will be done later. In either case, the access
4605 to the first word will do the modify, and we only have
4606 to add an offset of four here. */
4607 if (GET_CODE (XEXP (x, 0)) == PRE_INC
4608 || GET_CODE (XEXP (x, 0)) == PRE_DEC
4609 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
4610 || GET_CODE (XEXP (x, 0)) == POST_INC
4611 || GET_CODE (XEXP (x, 0)) == POST_DEC
4612 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
4613 output_address (VOIDmode,
4614 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
4615 else if (output_scaled)
4617 rtx addr = XEXP (x, 0);
4618 int size = GET_MODE_SIZE (GET_MODE (x));
4620 output_address (VOIDmode,
4621 plus_constant (Pmode, XEXP (addr, 0),
4622 ((INTVAL (XEXP (addr, 1)) + 4)
4623 >> (size == 2 ? 1 : 2))));
4627 output_address (VOIDmode,
4628 plus_constant (Pmode, XEXP (x, 0), 4));
4632 output_operand_lossage ("invalid operand to %%R code");
4636 if (GET_CODE (x) == SYMBOL_REF
4637 && arc_is_jli_call_p (x))
4639 if (SYMBOL_REF_DECL (x))
4641 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4642 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4644 if (lookup_attribute ("jli_fixed", attrs))
4646 /* No special treatment for jli_fixed functions. */
4649 fprintf (file, "%ld\t; @",
4650 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4651 assemble_name (file, XSTR (x, 0));
4655 fprintf (file, "@__jli.");
4656 assemble_name (file, XSTR (x, 0));
4658 arc_add_jli_section (x);
4661 if (GET_CODE (x) == SYMBOL_REF
4662 && arc_is_secure_call_p (x))
4664 /* No special treatment for secure functions. */
4667 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4668 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4670 fprintf (file, "%ld\t; @",
4671 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4672 assemble_name (file, XSTR (x, 0));
4676 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4679 output_addr_const (file, x);
4685 if (GET_CODE (x) == REG)
4687 /* L = least significant word, H = most significant word. */
4688 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
4689 fputs (reg_names[REGNO (x)], file);
4691 fputs (reg_names[REGNO (x)+1], file);
4693 else if (GET_CODE (x) == CONST_INT
4694 || GET_CODE (x) == CONST_DOUBLE)
4696 rtx first, second, word;
4698 split_double (x, &first, &second);
4700 if((WORDS_BIG_ENDIAN) == 0)
4701 word = (code == 'L' ? first : second);
4703 word = (code == 'L' ? second : first);
4705 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
4708 output_operand_lossage ("invalid operand to %%H/%%L code");
4714 gcc_assert (GET_CODE (x) == CONST_DOUBLE
4715 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
4717 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
4718 fprintf (file, "%s", str);
4722 /* Output a load/store with update indicator if appropriate. */
4723 if (GET_CODE (x) == MEM)
4725 rtx addr = XEXP (x, 0);
4726 switch (GET_CODE (addr))
4728 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
4729 fputs (".a", file); break;
4730 case POST_INC: case POST_DEC: case POST_MODIFY:
4731 fputs (".ab", file); break;
4733 /* Are we using a scaled index? */
4734 if (GET_CODE (XEXP (addr, 0)) == MULT)
4735 fputs (".as", file);
4736 /* Can we use a scaled offset? */
4737 else if (CONST_INT_P (XEXP (addr, 1))
4738 && GET_MODE_SIZE (GET_MODE (x)) > 1
4739 && (!(INTVAL (XEXP (addr, 1))
4740 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
4741 /* Does it make a difference? */
4742 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
4743 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
4745 fputs (".as", file);
4751 if (legitimate_small_data_address_p (addr)
4752 && GET_MODE_SIZE (GET_MODE (x)) > 1)
4754 int align = get_symbol_alignment (addr);
4756 switch (GET_MODE (x))
4765 if (align && ((align & mask) == 0))
4766 fputs (".as", file);
4772 gcc_assert (CONSTANT_P (addr)); break;
4776 output_operand_lossage ("invalid operand to %%U code");
4779 /* Output cache bypass indicator for a load/store insn. Volatile memory
4780 refs are defined to use the cache bypass mechanism. */
4781 if (GET_CODE (x) == MEM)
4783 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
4784 || arc_is_uncached_mem_p (x))
4785 fputs (".di", file);
4788 output_operand_lossage ("invalid operand to %%V code");
4793 /* Do nothing special. */
4796 fputs (reg_names[REGNO (x)]+1, file);
4799 /* This punctuation character is needed because label references are
4800 printed in the output template using %l. This is a front end
4801 character, and when we want to emit a '@' before it, we have to use
4807 /* Output an operator. */
4808 switch (GET_CODE (x))
4810 case PLUS: fputs ("add", file); return;
4811 case SS_PLUS: fputs ("adds", file); return;
4812 case AND: fputs ("and", file); return;
4813 case IOR: fputs ("or", file); return;
4814 case XOR: fputs ("xor", file); return;
4815 case MINUS: fputs ("sub", file); return;
4816 case SS_MINUS: fputs ("subs", file); return;
4817 case ASHIFT: fputs ("asl", file); return;
4818 case ASHIFTRT: fputs ("asr", file); return;
4819 case LSHIFTRT: fputs ("lsr", file); return;
4820 case ROTATERT: fputs ("ror", file); return;
4821 case MULT: fputs ("mpy", file); return;
4822 case ABS: fputs ("abs", file); return; /* Unconditional. */
4823 case NEG: fputs ("neg", file); return;
4824 case SS_NEG: fputs ("negs", file); return;
4825 case NOT: fputs ("not", file); return; /* Unconditional. */
4827 fputs ("ext", file); /* bmsk allows predication. */
4829 case SIGN_EXTEND: /* Unconditional. */
4830 fputs ("sex", file);
4832 switch (GET_MODE (XEXP (x, 0)))
4834 case E_QImode: fputs ("b", file); return;
4835 case E_HImode: fputs ("w", file); return;
4840 if (GET_MODE (x) != HImode)
4842 fputs ("sat16", file);
4845 output_operand_lossage ("invalid operand to %%O code"); return;
4847 if (GET_CODE (x) == SYMBOL_REF)
4849 assemble_name (file, XSTR (x, 0));
4854 if (TARGET_ANNOTATE_ALIGN)
4855 fprintf (file, "; unalign: %d", cfun->machine->unalign);
4871 output_operand_lossage ("invalid operand output code");
4874 switch (GET_CODE (x))
4877 fputs (reg_names[REGNO (x)], file);
4881 rtx addr = XEXP (x, 0);
4882 int size = GET_MODE_SIZE (GET_MODE (x));
4884 if (legitimate_small_data_address_p (addr))
4889 switch (GET_CODE (addr))
4891 case PRE_INC: case POST_INC:
4892 output_address (VOIDmode,
4893 plus_constant (Pmode, XEXP (addr, 0), size)); break;
4894 case PRE_DEC: case POST_DEC:
4895 output_address (VOIDmode,
4896 plus_constant (Pmode, XEXP (addr, 0), -size));
4898 case PRE_MODIFY: case POST_MODIFY:
4899 output_address (VOIDmode, XEXP (addr, 1)); break;
4903 output_address (VOIDmode,
4904 plus_constant (Pmode, XEXP (addr, 0),
4905 (INTVAL (XEXP (addr, 1))
4906 >> (size == 2 ? 1 : 2))));
4910 output_address (VOIDmode, addr);
4913 if (flag_pic && CONSTANT_ADDRESS_P (addr))
4914 arc_output_pic_addr_const (file, addr, code);
4916 output_address (VOIDmode, addr);
4923 /* We handle SFmode constants here as output_addr_const doesn't. */
4924 if (GET_MODE (x) == SFmode)
4928 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
4929 fprintf (file, "0x%08lx", l);
4933 /* Let output_addr_const deal with it. */
4936 || (GET_CODE (x) == CONST
4937 && GET_CODE (XEXP (x, 0)) == UNSPEC
4938 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
4939 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
4940 || (GET_CODE (x) == CONST
4941 && GET_CODE (XEXP (x, 0)) == PLUS
4942 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
4943 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
4944 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
4945 arc_output_pic_addr_const (file, x, code);
4947 output_addr_const (file, x);
4952 /* Print a memory address as an operand to reference that memory location. */
4955 arc_print_operand_address (FILE *file , rtx addr)
4957 register rtx base, index = 0;
4959 switch (GET_CODE (addr))
4962 fputs (reg_names[REGNO (addr)], file);
4966 fputs ("gp,", file);
4967 output_addr_const (file, addr);
4969 fputs ("@sda", file);
4973 if (GET_CODE (XEXP (addr, 0)) == MULT)
4974 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
4975 else if (CONST_INT_P (XEXP (addr, 0)))
4976 index = XEXP (addr, 0), base = XEXP (addr, 1);
4978 base = XEXP (addr, 0), index = XEXP (addr, 1);
4980 gcc_assert (OBJECT_P (base));
4981 arc_print_operand_address (file, base);
4982 if (CONSTANT_P (base) && CONST_INT_P (index))
4986 gcc_assert (OBJECT_P (index));
4987 arc_print_operand_address (file, index);
4991 rtx c = XEXP (addr, 0);
4993 if ((GET_CODE (c) == UNSPEC
4994 && (XINT (c, 1) == UNSPEC_TLS_OFF
4995 || XINT (c, 1) == UNSPEC_TLS_IE))
4996 || (GET_CODE (c) == PLUS
4997 && GET_CODE (XEXP (c, 0)) == UNSPEC
4998 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
4999 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
5001 arc_output_pic_addr_const (file, c, 0);
5004 gcc_assert (GET_CODE (c) == PLUS);
5005 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
5006 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
5008 output_address (VOIDmode, XEXP (addr, 0));
5014 /* We shouldn't get here as we've lost the mode of the memory object
5015 (which says how much to inc/dec by. */
5020 arc_output_pic_addr_const (file, addr, 0);
5022 output_addr_const (file, addr);
5027 /* Conditional execution support.
5029 This is based on the ARM port but for now is much simpler.
5031 A finite state machine takes care of noticing whether or not instructions
5032 can be conditionally executed, and thus decrease execution time and code
5033 size by deleting branch instructions. The fsm is controlled by
5034 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
5035 actions of PRINT_OPERAND. The patterns in the .md file for the branch
5036 insns also have a hand in this. */
5037 /* The way we leave dealing with non-anulled or annull-false delay slot
5038 insns to the consumer is awkward. */
5040 /* The state of the fsm controlling condition codes are:
5041 0: normal, do nothing special
5042 1: don't output this insn
5043 2: don't output this insn
5044 3: make insns conditional
5045 4: make insns conditional
5046 5: make insn conditional (only for outputting anulled delay slot insns)
5048 special value for cfun->machine->uid_ccfsm_state:
5049 6: return with but one insn before it since function start / call
5051 State transitions (state->state by whom, under what condition):
5052 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
5054 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
5055 by zero or more non-jump insns and an unconditional branch with
5056 the same target label as the condbranch.
5057 1 -> 3 branch patterns, after having not output the conditional branch
5058 2 -> 4 branch patterns, after having not output the conditional branch
5059 0 -> 5 branch patterns, for anulled delay slot insn.
5060 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
5061 (the target label has CODE_LABEL_NUMBER equal to
5062 arc_ccfsm_target_label).
5063 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
5064 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
5065 5 -> 0 when outputting the delay slot insn
5067 If the jump clobbers the conditions then we use states 2 and 4.
5069 A similar thing can be done with conditional return insns.
5071 We also handle separating branches from sets of the condition code.
5072 This is done here because knowledge of the ccfsm state is required,
5073 we may not be outputting the branch. */
5075 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
5076 before letting final output INSN. */
5079 arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
5081 /* BODY will hold the body of INSN. */
5084 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
5085 an if/then/else), and things need to be reversed. */
5088 /* If we start with a return insn, we only succeed if we find another one. */
5089 int seeking_return = 0;
5091 /* START_INSN will hold the insn from where we start looking. This is the
5092 first insn after the following code_label if REVERSE is true. */
5093 rtx_insn *start_insn = insn;
5095 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
5096 since they don't rely on a cmp preceding the. */
5097 enum attr_type jump_insn_type;
5099 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
5100 We can't do this in macro FINAL_PRESCAN_INSN because its called from
5101 final_scan_insn which has `optimize' as a local. */
5102 if (optimize < 2 || TARGET_NO_COND_EXEC)
5105 /* Ignore notes and labels. */
5108 body = PATTERN (insn);
5109 /* If in state 4, check if the target branch is reached, in order to
5110 change back to state 0. */
5111 if (state->state == 4)
5113 if (insn == state->target_insn)
5115 state->target_insn = NULL;
5121 /* If in state 3, it is possible to repeat the trick, if this insn is an
5122 unconditional branch to a label, and immediately following this branch
5123 is the previous target label which is only used once, and the label this
5124 branch jumps to is not too far off. Or in other words "we've done the
5125 `then' part, see if we can do the `else' part." */
5126 if (state->state == 3)
5128 if (simplejump_p (insn))
5130 start_insn = next_nonnote_insn (start_insn);
5131 if (GET_CODE (start_insn) == BARRIER)
5133 /* ??? Isn't this always a barrier? */
5134 start_insn = next_nonnote_insn (start_insn);
5136 if (GET_CODE (start_insn) == CODE_LABEL
5137 && CODE_LABEL_NUMBER (start_insn) == state->target_label
5138 && LABEL_NUSES (start_insn) == 1)
5143 else if (GET_CODE (body) == SIMPLE_RETURN)
5145 start_insn = next_nonnote_insn (start_insn);
5146 if (GET_CODE (start_insn) == BARRIER)
5147 start_insn = next_nonnote_insn (start_insn);
5148 if (GET_CODE (start_insn) == CODE_LABEL
5149 && CODE_LABEL_NUMBER (start_insn) == state->target_label
5150 && LABEL_NUSES (start_insn) == 1)
5162 if (GET_CODE (insn) != JUMP_INSN
5163 || GET_CODE (PATTERN (insn)) == ADDR_VEC
5164 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
5167 /* We can't predicate BRCC or loop ends.
5168 Also, when generating PIC code, and considering a medium range call,
5169 we can't predicate the call. */
5170 jump_insn_type = get_attr_type (insn);
5171 if (jump_insn_type == TYPE_BRCC
5172 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
5173 || jump_insn_type == TYPE_LOOP_END
5174 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
5177 /* This jump might be paralleled with a clobber of the condition codes,
5178 the jump should always come first. */
5179 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
5180 body = XVECEXP (body, 0, 0);
5183 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
5184 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
5186 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
5187 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
5188 int then_not_else = TRUE;
5189 /* Nonzero if next insn must be the target label. */
5190 int next_must_be_target_label_p;
5191 rtx_insn *this_insn = start_insn;
5194 /* Register the insn jumped to. */
5197 if (!seeking_return)
5198 label = XEXP (SET_SRC (body), 0);
5200 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
5201 label = XEXP (XEXP (SET_SRC (body), 1), 0);
5202 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
5204 label = XEXP (XEXP (SET_SRC (body), 2), 0);
5205 then_not_else = FALSE;
5207 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
5209 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
5212 then_not_else = FALSE;
5217 /* If this is a non-annulled branch with a delay slot, there is
5218 no need to conditionalize the delay slot. */
5219 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) == SEQUENCE)
5220 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
5222 this_insn = NEXT_INSN (this_insn);
5224 /* See how many insns this branch skips, and what kind of insns. If all
5225 insns are okay, and the label or unconditional branch to the same
5226 label is not too far away, succeed. */
5227 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
5228 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
5233 this_insn = next_nonnote_insn (this_insn);
5237 if (next_must_be_target_label_p)
5239 if (GET_CODE (this_insn) == BARRIER)
5241 if (GET_CODE (this_insn) == CODE_LABEL
5242 && this_insn == label)
5252 switch (GET_CODE (this_insn))
5255 /* Succeed if it is the target label, otherwise fail since
5256 control falls in from somewhere else. */
5257 if (this_insn == label)
5267 /* Succeed if the following insn is the target label.
5269 If return insns are used then the last insn in a function
5270 will be a barrier. */
5271 next_must_be_target_label_p = TRUE;
5275 /* Can handle a call insn if there are no insns after it.
5276 IE: The next "insn" is the target label. We don't have to
5277 worry about delay slots as such insns are SEQUENCE's inside
5278 INSN's. ??? It is possible to handle such insns though. */
5279 if (get_attr_cond (this_insn) == COND_CANUSE)
5280 next_must_be_target_label_p = TRUE;
5286 scanbody = PATTERN (this_insn);
5288 /* If this is an unconditional branch to the same label, succeed.
5289 If it is to another label, do nothing. If it is conditional,
5291 /* ??? Probably, the test for the SET and the PC are
5294 if (GET_CODE (scanbody) == SET
5295 && GET_CODE (SET_DEST (scanbody)) == PC)
5297 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
5298 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
5303 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
5305 else if (get_attr_cond (this_insn) != COND_CANUSE)
5308 else if (GET_CODE (scanbody) == SIMPLE_RETURN
5314 else if (GET_CODE (scanbody) == PARALLEL)
5316 if (get_attr_cond (this_insn) != COND_CANUSE)
5322 scanbody = PATTERN (this_insn);
5324 /* We can only do this with insns that can use the condition
5325 codes (and don't set them). */
5326 if (GET_CODE (scanbody) == SET
5327 || GET_CODE (scanbody) == PARALLEL)
5329 if (get_attr_cond (this_insn) != COND_CANUSE)
5332 /* We can't handle other insns like sequences. */
5344 if ((!seeking_return) && (state->state == 1 || reverse))
5345 state->target_label = CODE_LABEL_NUMBER (label);
5346 else if (seeking_return || state->state == 2)
5348 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
5350 this_insn = next_nonnote_insn (this_insn);
5352 gcc_assert (!this_insn ||
5353 (GET_CODE (this_insn) != BARRIER
5354 && GET_CODE (this_insn) != CODE_LABEL));
5358 /* Oh dear! we ran off the end, give up. */
5359 extract_insn_cached (insn);
5361 state->target_insn = NULL;
5364 state->target_insn = this_insn;
5369 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
5373 state->cond = XEXP (SET_SRC (body), 0);
5374 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
5377 if (reverse || then_not_else)
5378 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
5381 /* Restore recog_operand. Getting the attributes of other insns can
5382 destroy this array, but final.c assumes that it remains intact
5383 across this call; since the insn has been recognized already we
5384 call insn_extract direct. */
5385 extract_insn_cached (insn);
5389 /* Record that we are currently outputting label NUM with prefix PREFIX.
5390 It it's the label we're looking for, reset the ccfsm machinery.
5392 Called from ASM_OUTPUT_INTERNAL_LABEL. */
5395 arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
5397 if (state->state == 3 && state->target_label == num
5398 && !strcmp (prefix, "L"))
5401 state->target_insn = NULL;
5405 /* We are considering a conditional branch with the condition COND.
5406 Check if we want to conditionalize a delay slot insn, and if so modify
5407 the ccfsm state accordingly.
5408 REVERSE says branch will branch when the condition is false. */
5410 arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
5411 struct arc_ccfsm *state)
5413 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
5415 state = &arc_ccfsm_current;
5417 gcc_assert (state->state == 0);
5418 if (seq_insn != jump)
5420 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
5422 if (!as_a<rtx_insn *> (insn)->deleted ()
5423 && INSN_ANNULLED_BRANCH_P (jump)
5424 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
5427 state->cc = get_arc_condition_code (cond);
5429 arc_ccfsm_current.cc
5430 = ARC_INVERSE_CONDITION_CODE (state->cc);
5431 rtx pat = PATTERN (insn);
5432 if (GET_CODE (pat) == COND_EXEC)
5433 gcc_assert ((INSN_FROM_TARGET_P (insn)
5434 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
5435 == get_arc_condition_code (XEXP (pat, 0)));
5442 /* Update *STATE as we would when we emit INSN. */
5445 arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
5447 enum attr_type type;
5450 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
5451 else if (JUMP_P (insn)
5452 && GET_CODE (PATTERN (insn)) != ADDR_VEC
5453 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
5454 && ((type = get_attr_type (insn)) == TYPE_BRANCH
5455 || ((type == TYPE_UNCOND_BRANCH
5456 || type == TYPE_RETURN)
5457 && ARC_CCFSM_BRANCH_DELETED_P (state))))
5459 if (ARC_CCFSM_BRANCH_DELETED_P (state))
5460 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
5463 rtx src = SET_SRC (PATTERN (insn));
5464 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
5468 else if (arc_ccfsm_current.state == 5)
5469 arc_ccfsm_current.state = 0;
5472 /* Return true if the current insn, which is a conditional branch, is to be
5476 arc_ccfsm_branch_deleted_p (void)
5478 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
5481 /* Record a branch isn't output because subsequent insns can be
5485 arc_ccfsm_record_branch_deleted (void)
5487 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
5490 /* During insn output, indicate if the current insn is predicated. */
5493 arc_ccfsm_cond_exec_p (void)
5495 return (cfun->machine->prescan_initialized
5496 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
5499 /* When deciding if an insn should be output short, we want to know something
5500 about the following insns:
5501 - if another insn follows which we know we can output as a short insn
5502 before an alignment-sensitive point, we can output this insn short:
5503 the decision about the eventual alignment can be postponed.
5504 - if a to-be-aligned label comes next, we should output this insn such
5505 as to get / preserve 4-byte alignment.
5506 - if a likely branch without delay slot insn, or a call with an immediately
5507 following short insn comes next, we should out output this insn such as to
5508 get / preserve 2 mod 4 unalignment.
5509 - do the same for a not completely unlikely branch with a short insn
5510 following before any other branch / label.
5511 - in order to decide if we are actually looking at a branch, we need to
5512 call arc_ccfsm_advance.
5513 - in order to decide if we are looking at a short insn, we should know
5514 if it is conditionalized. To a first order of approximation this is
5515 the case if the state from arc_ccfsm_advance from before this insn
5516 indicates the insn is conditionalized. However, a further refinement
5517 could be to not conditionalize an insn if the destination register(s)
5518 is/are dead in the non-executed case. */
5519 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5520 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5521 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5524 arc_verify_short (rtx_insn *insn, int, int check_attr)
5526 enum attr_iscompact iscompact;
5530 iscompact = get_attr_iscompact (insn);
5531 if (iscompact == ISCOMPACT_FALSE)
5535 return (get_attr_length (insn) & 2) != 0;
5538 /* When outputting an instruction (alternative) that can potentially be short,
5539 output the short suffix if the insn is in fact short, and update
5540 cfun->machine->unalign accordingly. */
5543 output_short_suffix (FILE *file)
5545 rtx_insn *insn = current_output_insn;
5547 if (arc_verify_short (insn, cfun->machine->unalign, 1))
5549 fprintf (file, "_s");
5550 cfun->machine->unalign ^= 2;
5552 /* Restore recog_operand. */
5553 extract_insn_cached (insn);
5556 /* Implement FINAL_PRESCAN_INSN. */
5559 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
5560 int noperands ATTRIBUTE_UNUSED)
5562 if (TARGET_DUMPISIZE)
5563 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
5565 if (!cfun->machine->prescan_initialized)
5567 /* Clear lingering state from branch shortening. */
5568 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
5569 cfun->machine->prescan_initialized = 1;
5571 arc_ccfsm_advance (insn, &arc_ccfsm_current);
5574 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5575 Frame pointer elimination is automatically handled.
5577 All eliminations are permissible. If we need a frame
5578 pointer, we must eliminate ARG_POINTER_REGNUM into
5579 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5582 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
5584 return ((to == HARD_FRAME_POINTER_REGNUM) || (to == STACK_POINTER_REGNUM));
5587 /* Define the offset between two registers, one to be eliminated, and
5588 the other its replacement, at the start of a routine. */
5591 arc_initial_elimination_offset (int from, int to)
5593 if (!cfun->machine->frame_info.initialized)
5594 arc_compute_frame_size ();
5596 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
5598 return (cfun->machine->frame_info.extra_size
5599 + cfun->machine->frame_info.reg_size);
5602 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
5604 return (cfun->machine->frame_info.total_size
5605 - cfun->machine->frame_info.pretend_size);
5608 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
5610 return (cfun->machine->frame_info.total_size
5611 - (cfun->machine->frame_info.pretend_size
5612 + cfun->machine->frame_info.extra_size
5613 + cfun->machine->frame_info.reg_size));
5615 if ((from == FRAME_POINTER_REGNUM) && (to == HARD_FRAME_POINTER_REGNUM))
5622 arc_frame_pointer_required (void)
5624 return cfun->calls_alloca || crtl->calls_eh_return;
5628 /* Return the destination address of a branch. */
5631 branch_dest (rtx branch)
5633 rtx pat = PATTERN (branch);
5634 rtx dest = (GET_CODE (pat) == PARALLEL
5635 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
5638 if (GET_CODE (dest) == IF_THEN_ELSE)
5639 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
5641 dest = XEXP (dest, 0);
5642 dest_uid = INSN_UID (dest);
5644 return INSN_ADDRESSES (dest_uid);
5648 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5651 arc_encode_section_info (tree decl, rtx rtl, int first)
5653 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5654 This clears machine specific flags, so has to come first. */
5655 default_encode_section_info (decl, rtl, first);
5657 /* Check if it is a function, and whether it has the
5658 [long/medium/short]_call attribute specified. */
5659 if (TREE_CODE (decl) == FUNCTION_DECL)
5661 rtx symbol = XEXP (rtl, 0);
5662 int flags = SYMBOL_REF_FLAGS (symbol);
5664 tree attr = (TREE_TYPE (decl) != error_mark_node
5665 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
5666 tree long_call_attr = lookup_attribute ("long_call", attr);
5667 tree medium_call_attr = lookup_attribute ("medium_call", attr);
5668 tree short_call_attr = lookup_attribute ("short_call", attr);
5670 if (long_call_attr != NULL_TREE)
5671 flags |= SYMBOL_FLAG_LONG_CALL;
5672 else if (medium_call_attr != NULL_TREE)
5673 flags |= SYMBOL_FLAG_MEDIUM_CALL;
5674 else if (short_call_attr != NULL_TREE)
5675 flags |= SYMBOL_FLAG_SHORT_CALL;
5677 SYMBOL_REF_FLAGS (symbol) = flags;
5679 else if (TREE_CODE (decl) == VAR_DECL)
5681 rtx symbol = XEXP (rtl, 0);
5683 tree attr = (TREE_TYPE (decl) != error_mark_node
5684 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
5686 tree sec_attr = lookup_attribute ("section", attr);
5689 const char *sec_name
5690 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
5691 if (strcmp (sec_name, ".cmem") == 0
5692 || strcmp (sec_name, ".cmem_shared") == 0
5693 || strcmp (sec_name, ".cmem_private") == 0)
5694 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
5699 /* This is how to output a definition of an internal numbered label where
5700 PREFIX is the class of label and NUM is the number within the class. */
5702 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
5705 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
5706 default_internal_label (stream, prefix, labelno);
5709 /* Set the cpu type and print out other fancy things,
5710 at the top of the file. */
5712 static void arc_file_start (void)
5714 default_file_start ();
5715 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
5717 /* Set some want to have build attributes. */
5718 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5720 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5721 TARGET_RF16 ? 1 : 0);
5722 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5724 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5725 (arc_tp_regno != -1) ? 1 : 0);
5726 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5727 TARGET_NO_SDATA_SET ? 0 : 2);
5728 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5729 TARGET_OPTFPE ? 1 : 0);
5731 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5732 (arc_tune < ARC_TUNE_CORE_3) ? 2 :
5733 (arc_tune == ARC_TUNE_CORE_3 ? 3 : 4));
5736 /* Implement `TARGET_ASM_FILE_END'. */
5737 /* Outputs to the stdio stream FILE jli related text. */
5739 void arc_file_end (void)
5741 arc_jli_section *sec = arc_jli_sections;
5745 fprintf (asm_out_file, "\n");
5746 fprintf (asm_out_file, "# JLI entry for function ");
5747 assemble_name (asm_out_file, sec->name);
5748 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
5750 assemble_name (asm_out_file, sec->name);
5751 fprintf (asm_out_file,", comdat\n");
5753 fprintf (asm_out_file, "\t.align\t4\n");
5754 fprintf (asm_out_file, "__jli.");
5755 assemble_name (asm_out_file, sec->name);
5756 fprintf (asm_out_file, ":\n\t.weak __jli.");
5757 assemble_name (asm_out_file, sec->name);
5758 fprintf (asm_out_file, "\n\tb\t@");
5759 assemble_name (asm_out_file, sec->name);
5760 fprintf (asm_out_file, "\n");
5763 file_end_indicate_exec_stack ();
5766 /* Cost functions. */
5768 /* Compute a (partial) cost for rtx X. Return true if the complete
5769 cost has been computed, and false if subexpressions should be
5770 scanned. In either case, *TOTAL contains the cost result. */
5773 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
5774 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5776 int code = GET_CODE (x);
5780 /* Small integers are as cheap as registers. */
5783 bool nolimm = false; /* Can we do without long immediate? */
5786 if (UNSIGNED_INT6 (INTVAL (x)))
5792 case AND: /* bclr, bmsk, ext[bw] */
5793 if (satisfies_constraint_Ccp (x) /* bclr */
5794 || satisfies_constraint_C1p (x) /* bmsk */)
5797 case IOR: /* bset */
5798 if (satisfies_constraint_C0p (x)) /* bset */
5802 if (satisfies_constraint_C0p (x)) /* bxor */
5806 if (UNSIGNED_INT8 (INTVAL (x)))
5808 if (satisfies_constraint_Chi (x))
5810 if (satisfies_constraint_Clo (x))
5824 /* 4 byte values can be fetched as immediate constants -
5825 let's give that the cost of an extra insn. */
5829 *total = speed ? COSTS_N_INSNS (1) : COSTS_N_INSNS (4);
5838 *total = COSTS_N_INSNS (1);
5841 split_double (x, &first, &second);
5842 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
5843 + !SMALL_INT (INTVAL (second)));
5847 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5848 If we need more than 12 insns to do a multiply, then go out-of-line,
5849 since the call overhead will be < 10% of the cost of the multiply. */
5853 if (TARGET_BARREL_SHIFTER)
5855 if (CONSTANT_P (XEXP (x, 0)))
5857 *total += rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
5861 *total = COSTS_N_INSNS (1);
5863 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5864 *total = COSTS_N_INSNS (16);
5867 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
5868 /* ??? want_to_gcse_p can throw negative shift counts at us,
5869 and then panics when it gets a negative cost as result.
5870 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5878 if (GET_MODE_CLASS (mode) == MODE_FLOAT
5879 && (TARGET_FP_SP_SQRT || TARGET_FP_DP_SQRT))
5880 *total = COSTS_N_INSNS(1);
5881 else if (GET_MODE_CLASS (mode) == MODE_INT
5883 *total = COSTS_N_INSNS(1);
5885 *total = COSTS_N_INSNS(30);
5887 *total = COSTS_N_INSNS(1);
5891 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5892 *total = COSTS_N_INSNS (1);
5894 *total= arc_multcost;
5895 /* We do not want synth_mult sequences when optimizing
5897 else if (TARGET_ANY_MPY)
5898 *total = COSTS_N_INSNS (1);
5900 *total = COSTS_N_INSNS (2);
5904 if (outer_code == MEM && CONST_INT_P (XEXP (x, 1))
5905 && RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))
5911 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5912 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5913 || (GET_CODE (XEXP (x, 0)) == MULT
5914 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5916 if (CONSTANT_P (XEXP (x, 1)) && !speed)
5917 *total += COSTS_N_INSNS (4);
5918 *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed);
5923 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5924 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5925 || (GET_CODE (XEXP (x, 1)) == MULT
5926 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5928 if (CONSTANT_P (XEXP (x, 0)) && !speed)
5929 *total += COSTS_N_INSNS (4);
5930 *total += rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed);
5937 rtx op0 = XEXP (x, 0);
5938 rtx op1 = XEXP (x, 1);
5940 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5941 && XEXP (op0, 1) == const1_rtx)
5943 /* btst / bbit0 / bbit1:
5944 Small integers and registers are free; everything else can
5945 be put in a register. */
5946 mode = GET_MODE (XEXP (op0, 0));
5947 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5948 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5951 if (GET_CODE (op0) == AND && op1 == const0_rtx
5952 && satisfies_constraint_C1p (XEXP (op0, 1)))
5955 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5959 if (GET_CODE (op1) == NEG)
5961 /* op0 might be constant, the inside of op1 is rather
5962 unlikely to be so. So swapping the operands might lower
5964 mode = GET_MODE (op0);
5965 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5966 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5971 if (outer_code == IF_THEN_ELSE
5972 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5973 && XEXP (x, 1) == const0_rtx
5974 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5976 /* btst / bbit0 / bbit1:
5977 Small integers and registers are free; everything else can
5978 be put in a register. */
5979 rtx op0 = XEXP (x, 0);
5981 mode = GET_MODE (XEXP (op0, 0));
5982 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5983 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5987 /* scc_insn expands into two insns. */
5988 case GTU: case GEU: case LEU:
5990 *total += COSTS_N_INSNS (1);
5992 case LTU: /* might use adc. */
5994 *total += COSTS_N_INSNS (1) - 1;
6001 /* Return true if ADDR is a valid pic address.
6002 A valid pic address on arc should look like
6003 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
6006 arc_legitimate_pic_addr_p (rtx addr)
6008 if (GET_CODE (addr) != CONST)
6011 addr = XEXP (addr, 0);
6014 if (GET_CODE (addr) == PLUS)
6016 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
6018 addr = XEXP (addr, 0);
6021 if (GET_CODE (addr) != UNSPEC
6022 || XVECLEN (addr, 0) != 1)
6025 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
6026 if (XINT (addr, 1) != ARC_UNSPEC_GOT
6027 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
6028 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
6029 && XINT (addr, 1) != UNSPEC_TLS_GD
6030 && XINT (addr, 1) != UNSPEC_TLS_IE)
6033 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
6034 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
6042 /* Return true if OP contains a symbol reference. */
6045 symbolic_reference_mentioned_p (rtx op)
6047 register const char *fmt;
6050 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
6053 fmt = GET_RTX_FORMAT (GET_CODE (op));
6054 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
6060 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
6061 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
6065 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
6072 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
6073 If SKIP_LOCAL is true, skip symbols that bind locally.
6074 This is used further down in this file, and, without SKIP_LOCAL,
6075 in the addsi3 / subsi3 expanders when generating PIC code. */
6078 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
6080 register const char *fmt;
6083 if (GET_CODE(op) == UNSPEC)
6086 if (GET_CODE (op) == SYMBOL_REF)
6088 if (SYMBOL_REF_TLS_MODEL (op))
6092 tree decl = SYMBOL_REF_DECL (op);
6093 return !skip_local || !decl || !default_binds_local_p (decl);
6096 fmt = GET_RTX_FORMAT (GET_CODE (op));
6097 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
6103 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
6104 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
6109 else if (fmt[i] == 'e'
6110 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
6118 /* The __tls_get_attr symbol. */
6119 static GTY(()) rtx arc_tls_symbol;
6121 /* Emit a call to __tls_get_addr. TI is the argument to this function.
6122 RET is an RTX for the return value location. The entire insn sequence
6126 arc_call_tls_get_addr (rtx ti)
6128 rtx arg = gen_rtx_REG (Pmode, R0_REG);
6129 rtx ret = gen_rtx_REG (Pmode, R0_REG);
6133 if (!arc_tls_symbol)
6134 arc_tls_symbol = init_one_libfunc ("__tls_get_addr");
6136 emit_move_insn (arg, ti);
6137 fn = gen_rtx_MEM (SImode, arc_tls_symbol);
6138 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
6139 RTL_CONST_CALL_P (insn) = 1;
6140 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
6141 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
6146 #define DTPOFF_ZERO_SYM ".tdata"
6148 /* Return a legitimized address for ADDR,
6149 which is a SYMBOL_REF with tls_model MODEL. */
6152 arc_legitimize_tls_address (rtx addr, enum tls_model model)
6156 if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC)
6157 model = TLS_MODEL_LOCAL_EXEC;
6160 /* The TP pointer needs to be set. */
6161 gcc_assert (arc_tp_regno != -1);
6165 case TLS_MODEL_GLOBAL_DYNAMIC:
6166 tmp = gen_reg_rtx (Pmode);
6167 emit_move_insn (tmp, arc_unspec_offset (addr, UNSPEC_TLS_GD));
6168 return arc_call_tls_get_addr (tmp);
6170 case TLS_MODEL_LOCAL_DYNAMIC:
6173 const char *base_name;
6175 decl = SYMBOL_REF_DECL (addr);
6176 base_name = DTPOFF_ZERO_SYM;
6177 if (decl && bss_initializer_p (decl))
6178 base_name = ".tbss";
6180 base = gen_rtx_SYMBOL_REF (Pmode, base_name);
6181 tmp = gen_reg_rtx (Pmode);
6182 emit_move_insn (tmp, arc_unspec_offset (base, UNSPEC_TLS_GD));
6183 base = arc_call_tls_get_addr (tmp);
6184 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base),
6185 arc_unspec_offset (addr, UNSPEC_TLS_OFF));
6187 case TLS_MODEL_INITIAL_EXEC:
6188 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
6189 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
6190 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
6192 case TLS_MODEL_LOCAL_EXEC:
6193 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
6194 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
6201 /* Return true if SYMBOL_REF X binds locally. */
6204 arc_symbol_binds_local_p (const_rtx x)
6206 return (SYMBOL_REF_DECL (x)
6207 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
6208 : SYMBOL_REF_LOCAL_P (x));
6211 /* Legitimize a pic address reference in ADDR. The return value is
6212 the legitimated address. */
6215 arc_legitimize_pic_address (rtx addr)
6220 switch (GET_CODE (addr))
6223 /* TLS symbols are handled in different place. */
6224 if (SYMBOL_REF_TLS_MODEL (addr))
6227 /* This symbol must be referenced via a load from the Global
6228 Offset Table (@GOTPC). */
6229 if (!arc_symbol_binds_local_p (addr))
6230 return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT));
6232 /* Local symb: use @pcl to access it. */
6235 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
6244 /* Output address constant X to FILE, taking PIC into account. */
6247 arc_output_pic_addr_const (FILE * file, rtx x, int code)
6252 switch (GET_CODE (x))
6262 output_addr_const (file, x);
6264 /* Local functions do not get references through the PLT. */
6265 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
6266 fputs ("@plt", file);
6270 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
6271 assemble_name (file, buf);
6275 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
6276 assemble_name (file, buf);
6280 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
6284 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6288 if (GET_MODE (x) == VOIDmode)
6290 /* We can use %d if the number is one word and positive. */
6291 if (CONST_DOUBLE_HIGH (x))
6292 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
6293 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
6294 else if (CONST_DOUBLE_LOW (x) < 0)
6295 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
6297 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
6300 /* We can't handle floating point constants;
6301 PRINT_OPERAND must handle them. */
6302 output_operand_lossage ("floating constant misused");
6306 /* FIXME: Not needed here. */
6307 /* Some assemblers need integer constants to appear last (eg masm). */
6308 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
6310 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6311 fprintf (file, "+");
6312 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6314 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
6316 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6317 if (INTVAL (XEXP (x, 1)) >= 0)
6318 fprintf (file, "+");
6319 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6326 /* Avoid outputting things like x-x or x+5-x,
6327 since some assemblers can't handle that. */
6328 x = simplify_subtraction (x);
6329 if (GET_CODE (x) != MINUS)
6332 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6333 fprintf (file, "-");
6334 if (GET_CODE (XEXP (x, 1)) == CONST_INT
6335 && INTVAL (XEXP (x, 1)) < 0)
6337 fprintf (file, "(");
6338 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6339 fprintf (file, ")");
6342 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6347 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6353 bool pcrel; pcrel = false;
6354 rtx base; base = NULL;
6355 gcc_assert (XVECLEN (x, 0) >= 1);
6356 switch (XINT (x, 1))
6358 case ARC_UNSPEC_GOT:
6359 suffix = "@gotpc", pcrel = true;
6361 case ARC_UNSPEC_GOTOFF:
6364 case ARC_UNSPEC_GOTOFFPC:
6365 suffix = "@pcl", pcrel = true;
6367 case ARC_UNSPEC_PLT:
6371 suffix = "@tlsgd", pcrel = true;
6374 suffix = "@tlsie", pcrel = true;
6376 case UNSPEC_TLS_OFF:
6377 if (XVECLEN (x, 0) == 2)
6378 base = XVECEXP (x, 0, 1);
6379 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6380 || (!flag_pic && !base))
6386 suffix = "@invalid";
6387 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
6391 fputs ("pcl,", file);
6392 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
6393 fputs (suffix, file);
6395 arc_output_pic_addr_const (file, base, code);
6399 output_operand_lossage ("invalid expression as operand");
6403 /* The function returning the number of words, at the beginning of an
6404 argument, must be put in registers. The returned value must be
6405 zero for arguments that are passed entirely in registers or that
6406 are entirely pushed on the stack.
6408 On some machines, certain arguments must be passed partially in
6409 registers and partially in memory. On these machines, typically
6410 the first N words of arguments are passed in registers, and the
6411 rest on the stack. If a multi-word argument (a `double' or a
6412 structure) crosses that boundary, its first few words must be
6413 passed in registers and the rest must be pushed. This function
6414 tells the compiler when this occurs, and how many of the words
6415 should go in registers.
6417 `FUNCTION_ARG' for these arguments should return the first register
6418 to be used by the caller for this argument; likewise
6419 `FUNCTION_INCOMING_ARG', for the called function.
6421 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6423 /* If REGNO is the least arg reg available then what is the total number of arg
6425 #define GPR_REST_ARG_REGS(REGNO) \
6426 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6428 /* Since arc parm regs are contiguous. */
6429 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6431 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6434 arc_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
6436 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6437 int bytes = arg.promoted_size_in_bytes ();
6438 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6442 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6443 ret = GPR_REST_ARG_REGS (arg_num);
6445 /* ICEd at function.c:2361, and ret is copied to data->partial */
6446 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
6451 /* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
6452 args are normally in registers and the rest are pushed. */
6455 arc_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
6457 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6460 const char *debstr ATTRIBUTE_UNUSED;
6462 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6463 /* Return a marker for use in the call instruction. */
6464 if (arg.end_marker_p ())
6469 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6471 ret = gen_rtx_REG (arg.mode, arg_num);
6472 debstr = reg_names [arg_num];
6482 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6483 /* For the ARC: the cum set here is passed on to function_arg where we
6484 look at its value and say which reg to use. Strategy: advance the
6485 regnumber here till we run out of arg regs, then set *cum to last
6486 reg. In function_arg, since *cum > last arg reg we would return 0
6487 and thus the arg will end up on the stack. For straddling args of
6488 course function_arg_partial_nregs will come into play. */
6491 arc_function_arg_advance (cumulative_args_t cum_v,
6492 const function_arg_info &arg)
6494 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6495 int bytes = arg.promoted_size_in_bytes ();
6496 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6500 *cum = ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type);
6501 for (i = 0; i < words; i++)
6502 *cum = ARC_NEXT_ARG_REG (*cum);
6506 /* Define how to find the value returned by a function.
6507 VALTYPE is the data type of the value (as a tree).
6508 If the precise function being called is known, FN_DECL_OR_TYPE is its
6509 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6512 arc_function_value (const_tree valtype,
6513 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6514 bool outgoing ATTRIBUTE_UNUSED)
6516 machine_mode mode = TYPE_MODE (valtype);
6517 int unsignedp ATTRIBUTE_UNUSED;
6519 unsignedp = TYPE_UNSIGNED (valtype);
6520 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6521 PROMOTE_MODE (mode, unsignedp, valtype);
6522 return gen_rtx_REG (mode, 0);
6525 /* Returns the return address that is used by builtin_return_address. */
6528 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6533 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6536 /* Determine if a given RTX is a valid constant. We already know this
6537 satisfies CONSTANT_P. */
6540 arc_legitimate_constant_p (machine_mode mode, rtx x)
6542 switch (GET_CODE (x))
6547 if (arc_legitimate_pic_addr_p (x))
6550 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6553 if (SYMBOL_REF_TLS_MODEL (x))
6565 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6570 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6571 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6580 return TARGET_PLUS_DMPY;
6583 return TARGET_PLUS_QMACW;
6589 switch (XINT (x, 1))
6592 case UNSPEC_TLS_OFF:
6596 /* Any other unspec ending here are pic related, hence the above
6597 constant pic address checking returned false. */
6603 fatal_insn ("unrecognized supposed constant", x);
6610 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
6612 if (RTX_OK_FOR_BASE_P (x, strict))
6614 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
6616 if (legitimate_scaled_address_p (mode, x, strict))
6618 if (legitimate_small_data_address_p (x))
6620 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6623 /* When we compile for size avoid const (@sym + offset)
6625 if (!flag_pic && optimize_size && !reload_completed
6626 && (GET_CODE (x) == CONST)
6627 && (GET_CODE (XEXP (x, 0)) == PLUS)
6628 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6629 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6630 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
6632 rtx addend = XEXP (XEXP (x, 0), 1);
6633 gcc_assert (CONST_INT_P (addend));
6634 HOST_WIDE_INT offset = INTVAL (addend);
6636 /* Allow addresses having a large offset to pass. Anyhow they
6637 will end in a limm. */
6638 return !(offset > -1024 && offset < 1020);
6641 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6643 return arc_legitimate_constant_p (mode, x);
6645 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6646 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6647 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6649 /* We're restricted here by the `st' insn. */
6650 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6651 && GET_CODE (XEXP ((x), 1)) == PLUS
6652 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
6653 && legitimate_offset_address_p (QImode, XEXP (x, 1),
6654 TARGET_AUTO_MODIFY_REG, strict))
6659 /* Return true iff ADDR (a legitimate address expression)
6660 has an effect that depends on the machine mode it is used for. */
6663 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6665 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6666 which is valid for loads and stores, or a limm offset, which is valid for
6667 loads. Scaled indices are scaled by the access mode. */
6668 if (GET_CODE (addr) == PLUS
6669 && GET_CODE (XEXP ((addr), 0)) == MULT)
6674 /* Determine if it's legal to put X into the constant pool. */
6677 arc_cannot_force_const_mem (machine_mode mode, rtx x)
6679 return !arc_legitimate_constant_p (mode, x);
6682 /* IDs for all the ARC builtins. */
6686 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6687 ARC_BUILTIN_ ## NAME,
6688 #include "builtins.def"
6694 struct GTY(()) arc_builtin_description
6696 enum insn_code icode;
6701 static GTY(()) struct arc_builtin_description
6702 arc_bdesc[ARC_BUILTIN_COUNT] =
6704 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6705 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6706 #include "builtins.def"
6710 /* Transform UP into lowercase and write the result to LO.
6711 You must provide enough space for LO. Return LO. */
6714 arc_tolower (char *lo, const char *up)
6718 for (; *up; up++, lo++)
6719 *lo = TOLOWER (*up);
6726 /* Implement `TARGET_BUILTIN_DECL'. */
6729 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6731 if (id < ARC_BUILTIN_COUNT)
6732 return arc_bdesc[id].fndecl;
6734 return error_mark_node;
6738 arc_init_builtins (void)
6740 tree V4HI_type_node;
6741 tree V2SI_type_node;
6742 tree V2HI_type_node;
6744 /* Vector types based on HS SIMD elements. */
6745 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6746 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6747 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6749 tree pcvoid_type_node
6750 = build_pointer_type (build_qualified_type (void_type_node,
6752 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6755 tree void_ftype_void
6756 = build_function_type_list (void_type_node, NULL_TREE);
6758 = build_function_type_list (integer_type_node, integer_type_node,
6760 tree int_ftype_pcvoid_int
6761 = build_function_type_list (integer_type_node, pcvoid_type_node,
6762 integer_type_node, NULL_TREE);
6763 tree void_ftype_usint_usint
6764 = build_function_type_list (void_type_node, long_unsigned_type_node,
6765 long_unsigned_type_node, NULL_TREE);
6766 tree int_ftype_int_int
6767 = build_function_type_list (integer_type_node, integer_type_node,
6768 integer_type_node, NULL_TREE);
6769 tree usint_ftype_usint
6770 = build_function_type_list (long_unsigned_type_node,
6771 long_unsigned_type_node, NULL_TREE);
6772 tree void_ftype_usint
6773 = build_function_type_list (void_type_node, long_unsigned_type_node,
6776 = build_function_type_list (integer_type_node, void_type_node,
6779 = build_function_type_list (void_type_node, integer_type_node,
6781 tree int_ftype_short
6782 = build_function_type_list (integer_type_node, short_integer_type_node,
6785 /* Old ARC SIMD types. */
6786 tree v8hi_ftype_v8hi_v8hi
6787 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6788 V8HI_type_node, NULL_TREE);
6789 tree v8hi_ftype_v8hi_int
6790 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6791 integer_type_node, NULL_TREE);
6792 tree v8hi_ftype_v8hi_int_int
6793 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6794 integer_type_node, integer_type_node,
6796 tree void_ftype_v8hi_int_int
6797 = build_function_type_list (void_type_node, V8HI_type_node,
6798 integer_type_node, integer_type_node,
6800 tree void_ftype_v8hi_int_int_int
6801 = build_function_type_list (void_type_node, V8HI_type_node,
6802 integer_type_node, integer_type_node,
6803 integer_type_node, NULL_TREE);
6804 tree v8hi_ftype_int_int
6805 = build_function_type_list (V8HI_type_node, integer_type_node,
6806 integer_type_node, NULL_TREE);
6807 tree void_ftype_int_int
6808 = build_function_type_list (void_type_node, integer_type_node,
6809 integer_type_node, NULL_TREE);
6810 tree v8hi_ftype_v8hi
6811 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6813 /* ARCv2 SIMD types. */
6814 tree long_ftype_v4hi_v4hi
6815 = build_function_type_list (long_long_integer_type_node,
6816 V4HI_type_node, V4HI_type_node, NULL_TREE);
6817 tree int_ftype_v2hi_v2hi
6818 = build_function_type_list (integer_type_node,
6819 V2HI_type_node, V2HI_type_node, NULL_TREE);
6820 tree v2si_ftype_v2hi_v2hi
6821 = build_function_type_list (V2SI_type_node,
6822 V2HI_type_node, V2HI_type_node, NULL_TREE);
6823 tree v2hi_ftype_v2hi_v2hi
6824 = build_function_type_list (V2HI_type_node,
6825 V2HI_type_node, V2HI_type_node, NULL_TREE);
6826 tree v2si_ftype_v2si_v2si
6827 = build_function_type_list (V2SI_type_node,
6828 V2SI_type_node, V2SI_type_node, NULL_TREE);
6829 tree v4hi_ftype_v4hi_v4hi
6830 = build_function_type_list (V4HI_type_node,
6831 V4HI_type_node, V4HI_type_node, NULL_TREE);
6832 tree long_ftype_v2si_v2hi
6833 = build_function_type_list (long_long_integer_type_node,
6834 V2SI_type_node, V2HI_type_node, NULL_TREE);
6836 /* Add the builtins. */
6837 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6839 int id = ARC_BUILTIN_ ## NAME; \
6840 const char *Name = "__builtin_arc_" #NAME; \
6841 char *name = (char*) alloca (1 + strlen (Name)); \
6843 gcc_assert (id < ARC_BUILTIN_COUNT); \
6845 arc_bdesc[id].fndecl \
6846 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6847 BUILT_IN_MD, NULL, NULL_TREE); \
6849 #include "builtins.def"
6853 /* Helper to expand __builtin_arc_aligned (void* val, int
6857 arc_expand_builtin_aligned (tree exp)
6859 tree arg0 = CALL_EXPR_ARG (exp, 0);
6860 tree arg1 = CALL_EXPR_ARG (exp, 1);
6862 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6863 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6865 if (!CONST_INT_P (op1))
6867 /* If we can't fold the alignment to a constant integer
6868 whilst optimizing, this is probably a user error. */
6870 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
6874 HOST_WIDE_INT alignTest = INTVAL (op1);
6875 /* Check alignTest is positive, and a power of two. */
6876 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6878 error ("invalid alignment value for %<__builtin_arc_aligned%>");
6882 if (CONST_INT_P (op0))
6884 HOST_WIDE_INT pnt = INTVAL (op0);
6886 if ((pnt & (alignTest - 1)) == 0)
6891 unsigned align = get_pointer_alignment (arg0);
6892 unsigned numBits = alignTest * BITS_PER_UNIT;
6894 if (align && align >= numBits)
6896 /* Another attempt to ascertain alignment. Check the type
6897 we are pointing to. */
6898 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6899 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6904 /* Default to false. */
6908 /* Helper arc_expand_builtin, generates a pattern for the given icode
6912 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6914 switch (insn_data[icode].n_generator_args)
6917 return GEN_FCN (icode) ();
6919 return GEN_FCN (icode) (arg[0]);
6921 return GEN_FCN (icode) (arg[0], arg[1]);
6923 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6925 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6927 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6933 /* Expand an expression EXP that calls a built-in function,
6934 with result going to TARGET if that's convenient
6935 (and in mode MODE if that's convenient).
6936 SUBTARGET may be used as the target for computing one of EXP's operands.
6937 IGNORE is nonzero if the value is to be ignored. */
6940 arc_expand_builtin (tree exp,
6942 rtx subtarget ATTRIBUTE_UNUSED,
6943 machine_mode mode ATTRIBUTE_UNUSED,
6944 int ignore ATTRIBUTE_UNUSED)
6946 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6947 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
6948 const struct arc_builtin_description *d = &arc_bdesc[id];
6949 int i, j, n_args = call_expr_nargs (exp);
6952 enum insn_code icode = d->icode;
6953 machine_mode tmode = insn_data[icode].operand[0].mode;
6970 if (id >= ARC_BUILTIN_COUNT)
6971 internal_error ("bad builtin fcode");
6973 /* 1st part: Expand special builtins. */
6976 case ARC_BUILTIN_NOP:
6977 emit_insn (gen_nopv ());
6980 case ARC_BUILTIN_RTIE:
6981 case ARC_BUILTIN_SYNC:
6982 case ARC_BUILTIN_BRK:
6983 case ARC_BUILTIN_SWI:
6984 case ARC_BUILTIN_UNIMP_S:
6985 gcc_assert (icode != 0);
6986 emit_insn (GEN_FCN (icode) (const1_rtx));
6989 case ARC_BUILTIN_ALIGNED:
6990 return arc_expand_builtin_aligned (exp);
6992 case ARC_BUILTIN_CLRI:
6993 target = gen_reg_rtx (SImode);
6994 emit_insn (gen_clri (target, const1_rtx));
6997 case ARC_BUILTIN_TRAP_S:
6998 case ARC_BUILTIN_SLEEP:
6999 arg0 = CALL_EXPR_ARG (exp, 0);
7001 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7003 gcc_assert (icode != 0);
7004 emit_insn (GEN_FCN (icode) (op0));
7007 case ARC_BUILTIN_VDORUN:
7008 case ARC_BUILTIN_VDIRUN:
7009 arg0 = CALL_EXPR_ARG (exp, 0);
7010 arg1 = CALL_EXPR_ARG (exp, 1);
7011 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7012 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7014 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
7016 mode0 = insn_data[icode].operand[1].mode;
7017 mode1 = insn_data[icode].operand[2].mode;
7019 if (!insn_data[icode].operand[1].predicate (op0, mode0))
7020 op0 = copy_to_mode_reg (mode0, op0);
7022 if (!insn_data[icode].operand[2].predicate (op1, mode1))
7023 op1 = copy_to_mode_reg (mode1, op1);
7025 pat = GEN_FCN (icode) (target, op0, op1);
7032 case ARC_BUILTIN_VDIWR:
7033 case ARC_BUILTIN_VDOWR:
7034 arg0 = CALL_EXPR_ARG (exp, 0);
7035 arg1 = CALL_EXPR_ARG (exp, 1);
7036 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7037 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7039 if (!CONST_INT_P (op0)
7040 || !(UNSIGNED_INT3 (INTVAL (op0))))
7041 error ("operand 1 should be an unsigned 3-bit immediate");
7043 mode1 = insn_data[icode].operand[1].mode;
7045 if (icode == CODE_FOR_vdiwr_insn)
7046 target = gen_rtx_REG (SImode,
7047 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
7048 else if (icode == CODE_FOR_vdowr_insn)
7049 target = gen_rtx_REG (SImode,
7050 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
7054 if (!insn_data[icode].operand[2].predicate (op1, mode1))
7055 op1 = copy_to_mode_reg (mode1, op1);
7057 pat = GEN_FCN (icode) (target, op1);
7064 case ARC_BUILTIN_VASRW:
7065 case ARC_BUILTIN_VSR8:
7066 case ARC_BUILTIN_VSR8AW:
7067 arg0 = CALL_EXPR_ARG (exp, 0);
7068 arg1 = CALL_EXPR_ARG (exp, 1);
7069 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7070 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7071 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7073 target = gen_reg_rtx (V8HImode);
7074 mode0 = insn_data[icode].operand[1].mode;
7075 mode1 = insn_data[icode].operand[2].mode;
7077 if (!insn_data[icode].operand[1].predicate (op0, mode0))
7078 op0 = copy_to_mode_reg (mode0, op0);
7080 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7081 || !(UNSIGNED_INT3 (INTVAL (op1))))
7082 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7084 pat = GEN_FCN (icode) (target, op0, op1, op2);
7091 case ARC_BUILTIN_VLD32WH:
7092 case ARC_BUILTIN_VLD32WL:
7093 case ARC_BUILTIN_VLD64:
7094 case ARC_BUILTIN_VLD32:
7097 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7098 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7099 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
7101 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7102 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7103 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7104 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7106 /* target <- src vreg. */
7107 emit_insn (gen_move_insn (target, src_vreg));
7109 /* target <- vec_concat: target, mem (Ib, u8). */
7110 mode0 = insn_data[icode].operand[3].mode;
7111 mode1 = insn_data[icode].operand[1].mode;
7113 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
7114 || !(UNSIGNED_INT3 (INTVAL (op0))))
7115 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7117 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7118 || !(UNSIGNED_INT8 (INTVAL (op1))))
7119 error ("operand 2 should be an unsigned 8-bit value");
7121 pat = GEN_FCN (icode) (target, op1, op2, op0);
7128 case ARC_BUILTIN_VLD64W:
7129 case ARC_BUILTIN_VLD128:
7130 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
7131 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7133 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7134 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7135 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7137 /* target <- src vreg. */
7138 target = gen_reg_rtx (V8HImode);
7140 /* target <- vec_concat: target, mem (Ib, u8). */
7141 mode0 = insn_data[icode].operand[1].mode;
7142 mode1 = insn_data[icode].operand[2].mode;
7143 mode2 = insn_data[icode].operand[3].mode;
7145 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7146 || !(UNSIGNED_INT3 (INTVAL (op1))))
7147 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7149 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
7150 || !(UNSIGNED_INT8 (INTVAL (op2))))
7151 error ("operand 2 should be an unsigned 8-bit value");
7153 pat = GEN_FCN (icode) (target, op0, op1, op2);
7161 case ARC_BUILTIN_VST128:
7162 case ARC_BUILTIN_VST64:
7163 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
7164 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7165 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
7167 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7168 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7169 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7170 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7172 mode0 = insn_data[icode].operand[0].mode;
7173 mode1 = insn_data[icode].operand[1].mode;
7174 mode2 = insn_data[icode].operand[2].mode;
7175 mode3 = insn_data[icode].operand[3].mode;
7177 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7178 || !(UNSIGNED_INT3 (INTVAL (op1))))
7179 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7181 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7182 || !(UNSIGNED_INT8 (INTVAL (op2))))
7183 error ("operand 3 should be an unsigned 8-bit value");
7185 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7186 op3 = copy_to_mode_reg (mode3, op3);
7188 pat = GEN_FCN (icode) (op0, op1, op2, op3);
7195 case ARC_BUILTIN_VST16_N:
7196 case ARC_BUILTIN_VST32_N:
7197 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7198 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
7199 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
7200 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
7202 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
7203 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7204 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7205 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7206 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7208 mode0 = insn_data[icode].operand[0].mode;
7209 mode2 = insn_data[icode].operand[2].mode;
7210 mode3 = insn_data[icode].operand[3].mode;
7211 mode4 = insn_data[icode].operand[4].mode;
7213 /* Do some correctness checks for the operands. */
7214 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
7215 || !(UNSIGNED_INT8 (INTVAL (op0))))
7216 error ("operand 4 should be an unsigned 8-bit value (0-255)");
7218 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7219 || !(UNSIGNED_INT3 (INTVAL (op2))))
7220 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
7222 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7223 op3 = copy_to_mode_reg (mode3, op3);
7225 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
7226 || !(UNSIGNED_INT3 (INTVAL (op4))))
7227 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
7228 else if (icode == CODE_FOR_vst32_n_insn
7229 && ((INTVAL (op4) % 2) != 0))
7230 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
7232 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
7243 /* 2nd part: Expand regular builtins. */
7245 internal_error ("bad builtin fcode");
7247 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7252 if (target == NULL_RTX
7253 || GET_MODE (target) != tmode
7254 || !insn_data[icode].operand[0].predicate (target, tmode))
7256 target = gen_reg_rtx (tmode);
7261 gcc_assert (n_args <= 4);
7262 for (i = 0; i < n_args; i++, j++)
7264 tree arg = CALL_EXPR_ARG (exp, i);
7265 machine_mode mode = insn_data[icode].operand[j].mode;
7266 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
7267 machine_mode opmode = GET_MODE (op);
7268 char c = insn_data[icode].operand[j].constraint[0];
7270 /* SIMD extension requires exact immediate operand match. */
7271 if ((id > ARC_BUILTIN_SIMD_BEGIN)
7272 && (id < ARC_BUILTIN_SIMD_END)
7276 if (!CONST_INT_P (op))
7277 error ("builtin requires an immediate for operand %d", j);
7281 if (!satisfies_constraint_L (op))
7282 error ("operand %d should be a 6 bit unsigned immediate", j);
7285 if (!satisfies_constraint_P (op))
7286 error ("operand %d should be a 8 bit unsigned immediate", j);
7289 if (!satisfies_constraint_K (op))
7290 error ("operand %d should be a 3 bit unsigned immediate", j);
7293 error ("unknown builtin immediate operand type for operand %d",
7298 if (CONST_INT_P (op))
7301 if ((opmode == SImode) && (mode == HImode))
7304 op = gen_lowpart (HImode, op);
7307 /* In case the insn wants input operands in modes different from
7308 the result, abort. */
7309 gcc_assert (opmode == mode || opmode == VOIDmode);
7311 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
7312 op = copy_to_mode_reg (mode, op);
7317 pat = apply_GEN_FCN (icode, xop);
7318 if (pat == NULL_RTX)
7329 /* Returns true if the operands[opno] is a valid compile-time constant to be
7330 used as register number in the code for builtins. Else it flags an error
7331 and returns false. */
7334 check_if_valid_regno_const (rtx *operands, int opno)
7337 switch (GET_CODE (operands[opno]))
7344 error ("register number must be a compile-time constant. "
7345 "Try giving higher optimization levels");
7351 /* Return true if it is ok to make a tail-call to DECL. */
7354 arc_function_ok_for_sibcall (tree decl,
7355 tree exp ATTRIBUTE_UNUSED)
7357 tree attrs = NULL_TREE;
7359 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7360 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
7365 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
7367 if (lookup_attribute ("jli_always", attrs))
7369 if (lookup_attribute ("jli_fixed", attrs))
7371 if (lookup_attribute ("secure_call", attrs))
7375 /* Everything else is ok. */
7379 /* Output code to add DELTA to the first argument, and then jump
7380 to FUNCTION. Used for C++ multiple inheritance. */
7383 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7384 HOST_WIDE_INT delta,
7385 HOST_WIDE_INT vcall_offset,
7388 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
7389 int mi_delta = delta;
7390 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
7393 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
7396 assemble_start_function (thunk, fnname);
7399 mi_delta = - mi_delta;
7401 /* Add DELTA. When possible use a plain add, otherwise load it into
7402 a register first. */
7404 while (mi_delta != 0)
7406 if ((mi_delta & (3 << shift)) == 0)
7410 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
7411 mi_op, reg_names[this_regno], reg_names[this_regno],
7412 mi_delta & (0xff << shift));
7413 mi_delta &= ~(0xff << shift);
7418 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7419 if (vcall_offset != 0)
7421 /* ld r12,[this] --> temp = *this
7422 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7424 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7425 asm_fprintf (file, "\tld\t%s, [%s]\n",
7426 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
7427 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
7428 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7429 asm_fprintf (file, "\tld\t%s, [%s]\n",
7430 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7431 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7432 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7435 fnaddr = XEXP (DECL_RTL (function), 0);
7437 if (arc_is_longcall_p (fnaddr))
7441 asm_fprintf (file, "\tld\t%s, [pcl, @",
7442 ARC_TEMP_SCRATCH_REG);
7443 assemble_name (file, XSTR (fnaddr, 0));
7444 fputs ("@gotpc]\n", file);
7445 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7449 fputs ("\tj\t@", file);
7450 assemble_name (file, XSTR (fnaddr, 0));
7455 fputs ("\tb\t@", file);
7456 assemble_name (file, XSTR (fnaddr, 0));
7458 fputs ("@plt\n", file);
7461 assemble_end_function (thunk, fnname);
7464 /* Return true if a 32 bit "long_call" should be generated for
7465 this calling SYM_REF. We generate a long_call if the function:
7467 a. has an __attribute__((long call))
7468 or b. the -mlong-calls command line switch has been specified
7470 However we do not generate a long call if the function has an
7471 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7473 This function will be called by C fragments contained in the machine
7474 description file. */
7477 arc_is_longcall_p (rtx sym_ref)
7479 if (GET_CODE (sym_ref) != SYMBOL_REF)
7482 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7483 || (TARGET_LONG_CALLS_SET
7484 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7485 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7489 /* Likewise for short calls. */
7492 arc_is_shortcall_p (rtx sym_ref)
7494 if (GET_CODE (sym_ref) != SYMBOL_REF)
7497 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7498 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7499 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7500 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7504 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7507 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7509 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7513 HOST_WIDE_INT size = int_size_in_bytes (type);
7514 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
7519 arc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
7521 return (arg.type != 0
7522 && (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST
7523 || TREE_ADDRESSABLE (arg.type)));
7526 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7529 arc_can_use_doloop_p (const widest_int &,
7530 const widest_int &iterations_max,
7531 unsigned int loop_depth, bool entered_at_top)
7533 /* Considering limitations in the hardware, only use doloop
7534 for innermost loops which must be entered from the top. */
7535 if (loop_depth > 1 || !entered_at_top)
7538 /* Check for lp_count width boundary. */
7539 if (arc_lpcwidth != 32
7540 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7541 || wi::eq_p (iterations_max, 0)))
7546 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7547 return why doloop cannot be applied. */
7550 arc_invalid_within_doloop (const rtx_insn *insn)
7553 return "Function call in the loop.";
7555 /* FIXME! add here all the ZOL exceptions. */
7559 /* Return the next active insn, skiping the inline assembly code. */
7562 arc_active_insn (rtx_insn *insn)
7564 rtx_insn *nxt = next_active_insn (insn);
7566 if (nxt && GET_CODE (PATTERN (nxt)) == ASM_INPUT)
7567 nxt = next_active_insn (nxt);
7571 /* Search for a sequence made out of two stores and a given number of
7572 loads, insert a nop if required. */
7575 check_store_cacheline_hazard (void)
7577 rtx_insn *insn, *succ0, *insn1;
7580 for (insn = get_insns (); insn; insn = arc_active_insn (insn))
7582 succ0 = arc_active_insn (insn);
7587 if (!single_set (insn) || !single_set (succ0))
7590 if ((get_attr_type (insn) != TYPE_STORE)
7591 || (get_attr_type (succ0) != TYPE_STORE))
7594 /* Found at least two consecutive stores. Goto the end of the
7596 for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1))
7597 if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE)
7600 /* Now, check the next two instructions for the following cases:
7601 1. next instruction is a LD => insert 2 nops between store
7603 2. next-next instruction is a LD => inset 1 nop after the store
7605 if (insn1 && single_set (insn1)
7606 && (get_attr_type (insn1) == TYPE_LOAD))
7609 emit_insn_before (gen_nopv (), insn1);
7610 emit_insn_before (gen_nopv (), insn1);
7614 if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE))
7616 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7617 reorg, so it is safe to reuse it for avoiding the
7618 current compare insn to be part of a BRcc
7620 add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3));
7622 insn1 = arc_active_insn (insn1);
7623 if (insn1 && single_set (insn1)
7624 && (get_attr_type (insn1) == TYPE_LOAD))
7627 emit_insn_before (gen_nopv (), insn1);
7637 /* Return true if a load instruction (CONSUMER) uses the same address as a
7638 store instruction (PRODUCER). This function is used to avoid st/ld
7639 address hazard in ARC700 cores. */
7642 arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer)
7644 rtx in_set, out_set;
7645 rtx out_addr, in_addr;
7653 /* Peel the producer and the consumer for the address. */
7654 out_set = single_set (producer);
7657 out_addr = SET_DEST (out_set);
7660 if (GET_CODE (out_addr) == ZERO_EXTEND
7661 || GET_CODE (out_addr) == SIGN_EXTEND)
7662 out_addr = XEXP (out_addr, 0);
7664 if (!MEM_P (out_addr))
7667 in_set = single_set (consumer);
7670 in_addr = SET_SRC (in_set);
7673 if (GET_CODE (in_addr) == ZERO_EXTEND
7674 || GET_CODE (in_addr) == SIGN_EXTEND)
7675 in_addr = XEXP (in_addr, 0);
7677 if (!MEM_P (in_addr))
7679 /* Get rid of the MEM and check if the addresses are
7681 in_addr = XEXP (in_addr, 0);
7682 out_addr = XEXP (out_addr, 0);
7684 return exp_equiv_p (in_addr, out_addr, 0, true);
7690 /* Return TRUE is we have an store address hazard. */
7693 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7695 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
7697 return arc_store_addr_hazard_internal_p (producer, consumer);
7700 /* The same functionality as arc_hazard. It is called in machine
7701 reorg before any other optimization. Hence, the NOP size is taken
7702 into account when doing branch shortening. */
7705 workaround_arc_anomaly (void)
7707 rtx_insn *insn, *succ0;
7710 /* For any architecture: call arc_hazard here. */
7711 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7713 succ0 = next_real_insn (insn);
7714 if (arc_hazard (insn, succ0))
7716 emit_insn_before (gen_nopv (), succ0);
7723 /* Old A7 are suffering of a cache hazard, and we need to insert two
7724 nops between any sequence of stores and a load. */
7725 if (arc_tune != ARC_TUNE_ARC7XX)
7726 check_store_cacheline_hazard ();
7728 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7730 succ0 = next_real_insn (insn);
7731 if (arc_store_addr_hazard_internal_p (insn, succ0))
7733 emit_insn_after (gen_nopv (), insn);
7734 emit_insn_after (gen_nopv (), insn);
7738 /* Avoid adding nops if the instruction between the ST and LD is
7740 succ1 = next_real_insn (succ0);
7741 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0)
7742 && arc_store_addr_hazard_internal_p (insn, succ1))
7743 emit_insn_after (gen_nopv (), insn);
7747 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7748 turns out not to be optimizable; we have to split the loop_end pattern into
7749 a subtract and a test. */
7752 hwloop_fail (hwloop_info loop)
7755 rtx insn = loop->loop_end;
7758 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7759 && REG_P (loop->iter_reg))
7761 /* TARGET_V2 core3 has dbnz instructions. */
7762 test = gen_dbnz (loop->iter_reg, loop->start_label);
7763 insn = emit_jump_insn_before (test, loop->loop_end);
7765 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7767 /* We have the lp_count as loop iterator, try to use it. */
7768 emit_insn_before (gen_loop_fail (), loop->loop_end);
7769 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7771 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7772 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7774 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7779 emit_insn_before (gen_addsi3 (loop->iter_reg,
7783 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7784 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7790 JUMP_LABEL (insn) = loop->start_label;
7791 LABEL_NUSES (loop->start_label)++;
7792 delete_insn (loop->loop_end);
7795 /* Return the next insn after INSN that is not a NOTE, but stop the
7796 search before we enter another basic block. This routine does not
7797 look inside SEQUENCEs. */
7800 next_nonnote_insn_bb (rtx_insn *insn)
7804 insn = NEXT_INSN (insn);
7805 if (insn == 0 || !NOTE_P (insn))
7807 if (NOTE_INSN_BASIC_BLOCK_P (insn))
7814 /* Optimize LOOP. */
7817 hwloop_optimize (hwloop_info loop)
7821 basic_block entry_bb, bb;
7823 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label;
7824 unsigned int length;
7825 bool need_fix = false;
7826 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7828 if (loop->depth > 1)
7831 fprintf (dump_file, ";; loop %d is not innermost\n",
7836 if (!loop->incoming_dest)
7839 fprintf (dump_file, ";; loop %d has more than one entry\n",
7844 if (loop->incoming_dest != loop->head)
7847 fprintf (dump_file, ";; loop %d is not entered from head\n",
7852 if (loop->has_call || loop->has_asm)
7855 fprintf (dump_file, ";; loop %d has invalid insn\n",
7860 /* Scan all the blocks to make sure they don't use iter_reg. */
7861 if (loop->iter_reg_used || loop->iter_reg_used_outside)
7864 fprintf (dump_file, ";; loop %d uses iterator\n",
7869 /* Check if start_label appears before doloop_end. */
7871 for (insn = loop->start_label;
7872 insn && insn != loop->loop_end;
7873 insn = NEXT_INSN (insn))
7875 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
7876 if (JUMP_TABLES_IN_TEXT_SECTION
7877 && JUMP_TABLE_DATA_P (insn))
7880 fprintf (dump_file, ";; loop %d has a jump table\n",
7889 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
7894 loop->length = length;
7895 if (loop->length > ARC_MAX_LOOP_LENGTH)
7898 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7901 else if (!loop->length)
7904 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
7908 /* Check if we use a register or not. */
7909 if (!REG_P (loop->iter_reg))
7912 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7917 /* Check if we use a register or not. */
7918 if (!REG_P (loop->iter_reg))
7921 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7926 /* Check if loop register is lpcount. */
7927 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
7930 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
7933 /* This loop doesn't use the lp_count, check though if we can
7935 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
7936 /* In very unique cases we may have LP_COUNT alive. */
7937 || (loop->incoming_src
7938 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
7942 fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no);
7949 /* Check for control like instruction as the last instruction of a
7952 last_insn = PREV_INSN (loop->loop_end);
7956 for (; last_insn != BB_HEAD (bb);
7957 last_insn = PREV_INSN (last_insn))
7958 if (NONDEBUG_INSN_P (last_insn))
7961 if (last_insn != BB_HEAD (bb))
7964 if (single_pred_p (bb)
7965 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
7966 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
7968 bb = single_pred (bb);
7969 last_insn = BB_END (bb);
7982 fprintf (dump_file, ";; loop %d has no last instruction\n",
7987 if ((TARGET_ARC600_FAMILY || TARGET_HS)
7988 && INSN_P (last_insn)
7989 && (JUMP_P (last_insn) || CALL_P (last_insn)
7990 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
7991 /* At this stage we can have (insn (clobber (mem:BLK
7992 (reg)))) instructions, ignore them. */
7993 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
7994 && (get_attr_type (last_insn) == TYPE_BRCC
7995 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
7997 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
8000 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
8004 fprintf (dump_file, ";; loop %d has a control like last insn;"
8008 last_insn = emit_insn_after (gen_nopv (), last_insn);
8011 if (LABEL_P (last_insn))
8014 fprintf (dump_file, ";; loop %d has a label as last insn;"
8017 last_insn = emit_insn_after (gen_nopv (), last_insn);
8020 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
8021 and we can use it to indicate the last ZOL instruction cannot be
8022 part of a delay slot. */
8023 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
8025 loop->last_insn = last_insn;
8027 /* Get the loop iteration register. */
8028 iter_reg = loop->iter_reg;
8030 gcc_assert (REG_P (iter_reg));
8034 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
8035 if (entry_edge->flags & EDGE_FALLTHRU)
8038 if (entry_edge == NULL)
8041 fprintf (dump_file, ";; loop %d has no fallthru edge jumping"
8046 /* The loop is good. */
8047 end_label = gen_label_rtx ();
8048 loop->end_label = end_label;
8050 /* Place the zero_cost_loop_start instruction before the loop. */
8051 entry_bb = entry_edge->src;
8057 /* The loop uses a R-register, but the lp_count is free, thus
8059 emit_insn (gen_rtx_SET (lp_reg, iter_reg));
8060 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
8064 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
8069 insn = emit_insn (gen_arc_lp (loop->start_label,
8075 entry_after = BB_END (entry_bb);
8076 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
8083 emit_insn_before (seq, BB_HEAD (loop->head));
8084 seq = emit_label_before (gen_label_rtx (), seq);
8085 new_bb = create_basic_block (seq, insn, entry_bb);
8086 FOR_EACH_EDGE (e, ei, loop->incoming)
8088 if (!(e->flags & EDGE_FALLTHRU))
8089 redirect_edge_and_branch_force (e, new_bb);
8091 redirect_edge_succ (e, new_bb);
8094 make_edge (new_bb, loop->head, 0);
8099 while (DEBUG_INSN_P (entry_after)
8100 || (NOTE_P (entry_after)
8101 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
8102 /* Make sure we don't split a call and its corresponding
8103 CALL_ARG_LOCATION note. */
8104 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
8105 entry_after = NEXT_INSN (entry_after);
8107 entry_after = next_nonnote_insn_bb (entry_after);
8109 gcc_assert (entry_after);
8110 emit_insn_before (seq, entry_after);
8113 /* Insert the loop end label before the last instruction of the
8115 emit_label_after (end_label, loop->last_insn);
8116 /* Make sure we mark the begining and end label as used. */
8117 LABEL_NUSES (loop->end_label)++;
8118 LABEL_NUSES (loop->start_label)++;
8123 /* A callback for the hw-doloop pass. This function examines INSN; if
8124 it is a loop_end pattern we recognize, return the reg rtx for the
8125 loop counter. Otherwise, return NULL_RTX. */
8128 hwloop_pattern_reg (rtx_insn *insn)
8132 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
8135 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
8141 static struct hw_doloop_hooks arc_doloop_hooks =
8148 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8149 and tries to rewrite the RTL of these loops so that proper Blackfin
8150 hardware loops are generated. */
8153 arc_reorg_loops (void)
8155 reorg_loops (true, &arc_doloop_hooks);
8158 /* Scan all calls and add symbols to be emitted in the jli section if
8162 jli_call_scan (void)
8166 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8171 rtx pat = PATTERN (insn);
8172 if (GET_CODE (pat) == COND_EXEC)
8173 pat = COND_EXEC_CODE (pat);
8174 pat = XVECEXP (pat, 0, 0);
8175 if (GET_CODE (pat) == SET)
8176 pat = SET_SRC (pat);
8178 pat = XEXP (XEXP (pat, 0), 0);
8179 if (GET_CODE (pat) == SYMBOL_REF
8180 && arc_is_jli_call_p (pat))
8181 arc_add_jli_section (pat);
8185 /* Add padding if necessary to avoid a mispredict. A return could
8186 happen immediately after the function start. A call/return and
8187 return/return must be 6 bytes apart to avoid mispredict. */
8195 if (!TARGET_PAD_RETURN)
8198 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8200 rtx_insn *prev0 = prev_active_insn (insn);
8201 bool wantlong = false;
8203 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN)
8208 prev0 = emit_insn_before (gen_nopv (), insn);
8209 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8210 so it is safe to reuse it for forcing a particular length
8211 for an instruction. */
8212 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8213 emit_insn_before (gen_nopv (), insn);
8216 offset = get_attr_length (prev0);
8218 if (get_attr_length (prev0) == 2
8219 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE)
8221 /* Force long version of the insn. */
8226 rtx_insn *prev = prev_active_insn (prev0);
8228 offset += get_attr_length (prev);
8230 prev = prev_active_insn (prev);
8232 offset += get_attr_length (prev);
8237 prev = emit_insn_before (gen_nopv (), insn);
8238 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1));
8241 emit_insn_before (gen_nopv (), insn);
8248 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8250 /* Emit a blockage to avoid delay slot scheduling. */
8251 emit_insn_before (gen_blockage (), insn);
8255 static int arc_reorg_in_progress = 0;
8257 /* ARC's machince specific reorg function. */
8268 cfun->machine->arc_reorg_started = 1;
8269 arc_reorg_in_progress = 1;
8271 compute_bb_for_insn ();
8275 /* Doloop optimization. */
8278 workaround_arc_anomaly ();
8282 /* FIXME: should anticipate ccfsm action, generate special patterns for
8283 to-be-deleted branches that have no delay slot and have at least the
8284 length of the size increase forced on other insns that are conditionalized.
8285 This can also have an insn_list inside that enumerates insns which are
8286 not actually conditionalized because the destinations are dead in the
8288 Could also tag branches that we want to be unaligned if they get no delay
8289 slot, or even ones that we don't want to do delay slot sheduling for
8290 because we can unalign them.
8292 However, there are cases when conditional execution is only possible after
8293 delay slot scheduling:
8295 - If a delay slot is filled with a nocond/set insn from above, the previous
8296 basic block can become elegible for conditional execution.
8297 - If a delay slot is filled with a nocond insn from the fall-through path,
8298 the branch with that delay slot can become eligble for conditional
8299 execution (however, with the same sort of data flow analysis that dbr
8300 does, we could have figured out before that we don't need to
8301 conditionalize this insn.)
8302 - If a delay slot insn is filled with an insn from the target, the
8303 target label gets its uses decremented (even deleted if falling to zero),
8304 thus possibly creating more condexec opportunities there.
8305 Therefore, we should still be prepared to apply condexec optimization on
8306 non-prepared branches if the size increase of conditionalized insns is no
8307 more than the size saved from eliminating the branch. An invocation option
8308 could also be used to reserve a bit of extra size for condbranches so that
8309 this'll work more often (could also test in arc_reorg if the block is
8310 'close enough' to be eligible for condexec to make this likely, and
8311 estimate required size increase). */
8312 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8313 if (TARGET_NO_BRCC_SET)
8318 init_insn_lengths();
8321 if (optimize > 1 && !TARGET_NO_COND_EXEC)
8324 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
8325 df_finish_pass ((flags & TODO_df_verify) != 0);
8329 fprintf (dump_file, ";; After if conversion:\n\n");
8330 print_rtl (dump_file, get_insns ());
8334 /* Call shorten_branches to calculate the insn lengths. */
8335 shorten_branches (get_insns());
8336 cfun->machine->ccfsm_current_insn = NULL_RTX;
8338 if (!INSN_ADDRESSES_SET_P())
8339 fatal_error (input_location,
8340 "insn addresses not set after shorten_branches");
8342 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8345 enum attr_type insn_type;
8347 /* If a non-jump insn (or a casesi jump table), continue. */
8348 if (GET_CODE (insn) != JUMP_INSN ||
8349 GET_CODE (PATTERN (insn)) == ADDR_VEC
8350 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
8353 /* If we already have a brcc, note if it is suitable for brcc_s.
8354 Be a bit generous with the brcc_s range so that we can take
8355 advantage of any code shortening from delay slot scheduling. */
8356 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
8358 rtx pat = PATTERN (insn);
8359 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
8360 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
8362 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8363 if ((offset >= -140 && offset < 140)
8364 && rtx_equal_p (XEXP (op, 1), const0_rtx)
8365 && compact_register_operand (XEXP (op, 0), VOIDmode)
8366 && equality_comparison_operator (op, VOIDmode))
8367 PUT_MODE (*ccp, CC_Zmode);
8368 else if (GET_MODE (*ccp) == CC_Zmode)
8369 PUT_MODE (*ccp, CC_ZNmode);
8372 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
8373 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
8376 /* OK. so we have a jump insn. */
8377 /* We need to check that it is a bcc. */
8378 /* Bcc => set (pc) (if_then_else ) */
8379 pattern = PATTERN (insn);
8380 if (GET_CODE (pattern) != SET
8381 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
8382 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
8385 /* Now check if the jump is beyond the s9 range. */
8386 if (CROSSING_JUMP_P (insn))
8388 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8390 if(offset > 253 || offset < -254)
8393 pc_target = SET_SRC (pattern);
8395 /* Avoid FPU instructions. */
8396 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
8397 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
8400 /* Now go back and search for the set cc insn. */
8402 label = XEXP (pc_target, 1);
8406 rtx_insn *scan, *link_insn = NULL;
8408 for (scan = PREV_INSN (insn);
8409 scan && GET_CODE (scan) != CODE_LABEL;
8410 scan = PREV_INSN (scan))
8412 if (! INSN_P (scan))
8414 pat = PATTERN (scan);
8415 if (GET_CODE (pat) == SET
8416 && cc_register (SET_DEST (pat), VOIDmode))
8426 /* Check if this is a data dependency. */
8427 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
8430 /* Make sure we can use it for brcc insns. */
8431 if (find_reg_note (link_insn, REG_SAVE_NOTE, GEN_INT (3)))
8434 /* Ok this is the set cc. copy args here. */
8435 op = XEXP (pc_target, 0);
8437 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
8438 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
8439 if (GET_CODE (op0) == ZERO_EXTRACT
8440 && XEXP (op0, 1) == const1_rtx
8441 && (GET_CODE (op) == EQ
8442 || GET_CODE (op) == NE))
8444 /* btst / b{eq,ne} -> bbit{0,1} */
8445 op0 = XEXP (cmp0, 0);
8446 op1 = XEXP (cmp0, 2);
8448 else if (!register_operand (op0, VOIDmode)
8449 || !general_operand (op1, VOIDmode))
8451 /* Be careful not to break what cmpsfpx_raw is
8452 trying to create for checking equality of
8453 single-precision floats. */
8454 else if (TARGET_SPFP
8455 && GET_MODE (op0) == SFmode
8456 && GET_MODE (op1) == SFmode)
8459 /* None of the two cmp operands should be set between the
8460 cmp and the branch. */
8461 if (reg_set_between_p (op0, link_insn, insn))
8464 if (reg_set_between_p (op1, link_insn, insn))
8467 /* Since the MODE check does not work, check that this is
8468 CC reg's last set location before insn, and also no
8469 instruction between the cmp and branch uses the
8471 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
8472 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
8475 /* CC reg should be dead after insn. */
8476 if (!find_regno_note (insn, REG_DEAD, CC_REG))
8479 op = gen_rtx_fmt_ee (GET_CODE (op),
8480 GET_MODE (op), cmp0, cmp1);
8481 /* If we create a LIMM where there was none before,
8482 we only benefit if we can avoid a scheduling bubble
8483 for the ARC600. Otherwise, we'd only forgo chances
8484 at short insn generation, and risk out-of-range
8486 if (!brcc_nolimm_operator (op, VOIDmode)
8487 && !long_immediate_operand (op1, VOIDmode)
8489 || next_active_insn (link_insn) != insn))
8492 /* Emit bbit / brcc (or brcc_s if possible).
8493 CC_Zmode indicates that brcc_s is possible. */
8496 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
8497 else if ((offset >= -140 && offset < 140)
8498 && rtx_equal_p (op1, const0_rtx)
8499 && compact_register_operand (op0, VOIDmode)
8500 && (GET_CODE (op) == EQ
8501 || GET_CODE (op) == NE))
8502 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
8504 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
8507 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
8508 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
8509 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
8512 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
8513 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
8515 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
8516 note = find_reg_note (insn, REG_BR_PROB, 0);
8519 XEXP (note, 1) = REG_NOTES (brcc_insn);
8520 REG_NOTES (brcc_insn) = note;
8522 note = find_reg_note (link_insn, REG_DEAD, op0);
8525 remove_note (link_insn, note);
8526 XEXP (note, 1) = REG_NOTES (brcc_insn);
8527 REG_NOTES (brcc_insn) = note;
8529 note = find_reg_note (link_insn, REG_DEAD, op1);
8532 XEXP (note, 1) = REG_NOTES (brcc_insn);
8533 REG_NOTES (brcc_insn) = note;
8538 /* Delete the bcc insn. */
8539 set_insn_deleted (insn);
8541 /* Delete the cmp insn. */
8542 set_insn_deleted (link_insn);
8547 /* Clear out insn_addresses. */
8548 INSN_ADDRESSES_FREE ();
8552 if (INSN_ADDRESSES_SET_P())
8553 fatal_error (input_location, "insn addresses not freed");
8555 arc_reorg_in_progress = 0;
8558 /* Check if the operands are valid for BRcc.d generation
8559 Valid Brcc.d patterns are
8563 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
8564 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8565 does not have a delay slot
8567 Assumed precondition: Second operand is either a register or a u6 value. */
8570 valid_brcc_with_delay_p (rtx *operands)
8572 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
8574 return brcc_nolimm_operator (operands[0], VOIDmode);
8577 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8578 access DECL using %gp_rel(...)($gp). */
8581 arc_in_small_data_p (const_tree decl)
8586 /* Only variables are going into small data area. */
8587 if (TREE_CODE (decl) != VAR_DECL)
8590 if (TARGET_NO_SDATA_SET)
8593 /* Disable sdata references to weak variables. */
8594 if (DECL_WEAK (decl))
8597 /* Don't put constants into the small data section: we want them to
8598 be in ROM rather than RAM. */
8599 if (TREE_READONLY (decl))
8602 /* To ensure -mvolatile-cache works ld.di does not have a
8603 gp-relative variant. */
8604 if (!TARGET_VOLATILE_CACHE_SET
8605 && TREE_THIS_VOLATILE (decl))
8608 /* Likewise for uncached data. */
8609 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
8610 if (lookup_attribute ("uncached", attr))
8613 /* and for aux regs. */
8614 attr = DECL_ATTRIBUTES (decl);
8615 if (lookup_attribute ("aux", attr))
8618 if (DECL_SECTION_NAME (decl) != 0)
8620 const char *name = DECL_SECTION_NAME (decl);
8621 if (strcmp (name, ".sdata") == 0
8622 || strcmp (name, ".sbss") == 0)
8625 /* If it's not public, there's no need to put it in the small data
8627 else if (TREE_PUBLIC (decl))
8629 size = int_size_in_bytes (TREE_TYPE (decl));
8630 return (size > 0 && size <= g_switch_value);
8635 /* Return true if OP is an acceptable memory operand for ARCompact
8636 16-bit gp-relative load instructions.
8638 /* volatile cache option still to be handled. */
8641 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
8648 /* Eliminate non-memory operations. */
8649 if (GET_CODE (op) != MEM)
8652 if (mode == VOIDmode)
8653 mode = GET_MODE (op);
8655 size = GET_MODE_SIZE (mode);
8657 /* dword operations really put out 2 instructions, so eliminate them. */
8658 if (size > UNITS_PER_WORD)
8661 /* Decode the address now. */
8662 addr = XEXP (op, 0);
8664 if (!legitimate_small_data_address_p (addr))
8667 if (!short_p || size == 1)
8670 /* Now check for the alignment, the short loads using gp require the
8671 addresses to be aligned. */
8672 align = get_symbol_alignment (addr);
8683 if (align && ((align & mask) == 0))
8688 /* Return TRUE if PAT is accessing an aux-reg. */
8691 arc_is_aux_reg_p (rtx pat)
8693 tree attrs = NULL_TREE;
8699 /* Get the memory attributes. */
8700 addr = MEM_EXPR (pat);
8704 /* Get the attributes. */
8705 if (TREE_CODE (addr) == VAR_DECL)
8706 attrs = DECL_ATTRIBUTES (addr);
8707 else if (TREE_CODE (addr) == MEM_REF)
8708 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8712 if (lookup_attribute ("aux", attrs))
8717 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8720 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8721 unsigned HOST_WIDE_INT size,
8722 unsigned HOST_WIDE_INT align,
8723 unsigned HOST_WIDE_INT globalize_p)
8725 int in_small_data = arc_in_small_data_p (decl);
8726 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8728 /* Don't output aux-reg symbols. */
8729 if (mem != NULL_RTX && MEM_P (mem)
8730 && SYMBOL_REF_P (XEXP (mem, 0))
8731 && arc_is_aux_reg_p (mem))
8735 switch_to_section (get_named_section (NULL, ".sbss", 0));
8736 /* named_section (0,".sbss",0); */
8738 switch_to_section (bss_section);
8741 (*targetm.asm_out.globalize_label) (stream, name);
8743 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8744 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8745 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8746 ASM_OUTPUT_LABEL (stream, name);
8749 ASM_OUTPUT_SKIP (stream, size);
8753 arc_preserve_reload_p (rtx in)
8755 return (GET_CODE (in) == PLUS
8756 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8757 && CONST_INT_P (XEXP (in, 1))
8758 && !((INTVAL (XEXP (in, 1)) & 511)));
8761 /* Implement TARGET_REGISTER_MOVE_COST. */
8764 arc_register_move_cost (machine_mode,
8765 reg_class_t from_class, reg_class_t to_class)
8767 /* Force an attempt to 'mov Dy,Dx' to spill. */
8768 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
8769 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8775 /* Emit code for an addsi3 instruction with OPERANDS.
8776 COND_P indicates if this will use conditional execution.
8777 Return the length of the instruction.
8778 If OUTPUT_P is false, don't actually output the instruction, just return
8781 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8785 int match = operands_match_p (operands[0], operands[1]);
8786 int match2 = operands_match_p (operands[0], operands[2]);
8787 int intval = (REG_P (operands[2]) ? 1
8788 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8789 int neg_intval = -intval;
8790 int short_0 = satisfies_constraint_Rcq (operands[0]);
8791 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
8794 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8795 && REGNO (OP) != 30) \
8798 #define ADDSI_OUTPUT1(FORMAT) do {\
8800 output_asm_insn (FORMAT, operands);\
8803 #define ADDSI_OUTPUT(LIST) do {\
8806 ADDSI_OUTPUT1 (format);\
8810 /* First try to emit a 16 bit insn. */
8813 /* If we are actually about to output this insn, don't try a 16 bit
8814 variant if we already decided that we don't want that
8815 (I.e. we upsized this insn to align some following insn.)
8816 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8817 but add1 r0,sp,35 doesn't. */
8818 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8820 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8823 && ((REG_H_P (operands[2])
8824 && (match || satisfies_constraint_Rcq (operands[2])))
8825 || (CONST_INT_P (operands[2])
8826 && ((unsigned) intval <= (match ? 127 : 7)))))
8827 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8829 /* Generate add_s b,b,h patterns. */
8830 if (short_0 && match2 && REG_H_P (operands[1]))
8831 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8833 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8834 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8835 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8836 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8838 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8839 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8840 && match && !(neg_intval & ~124)))
8841 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8843 /* Generate add_s h,h,s3 patterns. */
8844 if (REG_H_P (operands[0]) && match && TARGET_V2
8845 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8846 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8848 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8849 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8850 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8851 && satisfies_constraint_Rcq (operands[1])
8852 && satisfies_constraint_L (operands[2]))
8853 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8856 /* Now try to emit a 32 bit insn without long immediate. */
8858 if (!match && match2 && REG_P (operands[1]))
8859 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8860 if (match || !cond_p)
8862 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8863 int range_factor = neg_intval & intval;
8866 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8867 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8869 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8870 same size, do, so - the insn latency is lower. */
8871 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8873 if ((intval >= 0 && intval <= limit)
8874 || (intval == -0x800 && limit == 0x7ff))
8875 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8876 else if ((intval < 0 && neg_intval <= limit)
8877 || (intval == 0x800 && limit == 0x7ff))
8878 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8879 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
8880 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
8881 gcc_assert ((((1 << shift) - 1) & intval) == 0);
8882 if (((intval < 0 && intval != -0x4000)
8883 /* sub[123] is slower than add_s / sub, only use it if it
8884 avoids a long immediate. */
8885 && neg_intval <= limit << shift)
8886 || (intval == 0x4000 && limit == 0x7ff))
8887 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
8888 shift, neg_intval >> shift));
8889 else if ((intval >= 0 && intval <= limit << shift)
8890 || (intval == -0x4000 && limit == 0x7ff))
8891 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
8893 /* Try to emit a 16 bit opcode with long immediate. */
8895 if (short_p && match)
8896 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8898 /* We have to use a 32 bit opcode, and with a long immediate. */
8900 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8903 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8904 Return the length of the instruction.
8905 If OUTPUT_P is false, don't actually output the instruction, just return
8908 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
8910 enum rtx_code commutative_op = GET_CODE (operands[3]);
8911 const char *pat = NULL;
8913 /* Canonical rtl should not have a constant in the first operand position. */
8914 gcc_assert (!CONSTANT_P (operands[1]));
8916 switch (commutative_op)
8919 if (satisfies_constraint_C1p (operands[2]))
8920 pat = "bmsk%? %0,%1,%Z2";
8921 else if (satisfies_constraint_C2p (operands[2]))
8923 operands[2] = GEN_INT ((~INTVAL (operands[2])));
8924 pat = "bmskn%? %0,%1,%Z2";
8926 else if (satisfies_constraint_Ccp (operands[2]))
8927 pat = "bclr%? %0,%1,%M2";
8928 else if (satisfies_constraint_CnL (operands[2]))
8929 pat = "bic%? %0,%1,%n2-1";
8932 if (satisfies_constraint_C0p (operands[2]))
8933 pat = "bset%? %0,%1,%z2";
8936 if (satisfies_constraint_C0p (operands[2]))
8937 pat = "bxor%? %0,%1,%z2";
8940 return arc_output_addsi (operands, true, output_p);
8944 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
8945 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
8950 /* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
8951 Emit code and return an potentially modified address such that offsets
8952 up to SIZE are can be added to yield a legitimate address.
8953 if REUSE is set, ADDR is a register that may be modified. */
8956 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
8959 rtx offs = const0_rtx;
8961 if (GET_CODE (base) == PLUS)
8963 offs = XEXP (base, 1);
8964 base = XEXP (base, 0);
8967 || (REGNO (base) != STACK_POINTER_REGNUM
8968 && REGNO_PTR_FRAME_P (REGNO (base)))
8969 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
8970 || !SMALL_INT (INTVAL (offs) + size))
8973 emit_insn (gen_add2_insn (addr, offs));
8975 addr = copy_to_mode_reg (Pmode, addr);
8980 /* Like move_by_pieces, but take account of load latency, and actual
8981 offset ranges. Return true on success. */
8984 arc_expand_cpymem (rtx *operands)
8986 rtx dst = operands[0];
8987 rtx src = operands[1];
8988 rtx dst_addr, src_addr;
8990 int align = INTVAL (operands[3]);
8997 if (!CONST_INT_P (operands[2]))
8999 size = INTVAL (operands[2]);
9000 /* move_by_pieces_ninsns is static, so we can't use it. */
9004 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
9006 n_pieces = (size + 2) / 4U + (size & 1);
9008 else if (align == 2)
9009 n_pieces = (size + 1) / 2U;
9012 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
9014 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
9016 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
9020 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
9021 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
9022 store[0] = store[1] = NULL_RTX;
9023 tmpx[0] = tmpx[1] = NULL_RTX;
9024 for (i = 0; size > 0; i ^= 1, size -= piece)
9029 while (piece > size)
9031 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
9032 /* If we don't re-use temporaries, the scheduler gets carried away,
9033 and the register pressure gets unnecessarily high. */
9034 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
9037 tmpx[i] = tmp = gen_reg_rtx (mode);
9038 dst_addr = force_offsettable (dst_addr, piece, 1);
9039 src_addr = force_offsettable (src_addr, piece, 1);
9041 emit_insn (store[i]);
9042 emit_move_insn (tmp, change_address (src, mode, src_addr));
9043 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
9044 dst_addr = plus_constant (Pmode, dst_addr, piece);
9045 src_addr = plus_constant (Pmode, src_addr, piece);
9048 emit_insn (store[i]);
9050 emit_insn (store[i^1]);
9055 arc_get_aux_arg (rtx pat, int *auxr)
9057 tree attr, addr = MEM_EXPR (pat);
9058 if (TREE_CODE (addr) != VAR_DECL)
9061 attr = DECL_ATTRIBUTES (addr);
9062 if (lookup_attribute ("aux", attr))
9064 tree arg = TREE_VALUE (attr);
9067 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
9075 /* Prepare operands for move in MODE. Return true iff the move has
9079 prepare_move_operands (rtx *operands, machine_mode mode)
9081 /* First handle aux attribute. */
9083 && (MEM_P (operands[0]) || MEM_P (operands[1])))
9087 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
9089 /* Save operation. */
9090 if (arc_get_aux_arg (operands[0], &auxr))
9092 tmp = gen_reg_rtx (SImode);
9093 emit_move_insn (tmp, GEN_INT (auxr));
9097 tmp = XEXP (operands[0], 0);
9100 operands[1] = force_reg (SImode, operands[1]);
9101 emit_insn (gen_rtx_UNSPEC_VOLATILE
9102 (VOIDmode, gen_rtvec (2, operands[1], tmp),
9106 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
9108 if (arc_get_aux_arg (operands[1], &auxr))
9110 tmp = gen_reg_rtx (SImode);
9111 emit_move_insn (tmp, GEN_INT (auxr));
9115 tmp = XEXP (operands[1], 0);
9116 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
9118 /* Load operation. */
9119 gcc_assert (REG_P (operands[0]));
9120 emit_insn (gen_rtx_SET (operands[0],
9121 gen_rtx_UNSPEC_VOLATILE
9122 (SImode, gen_rtvec (1, tmp),
9128 if (GET_CODE (operands[1]) == SYMBOL_REF)
9130 enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
9131 if (MEM_P (operands[0]))
9132 operands[1] = force_reg (mode, operands[1]);
9134 operands[1] = arc_legitimize_tls_address (operands[1], model);
9137 operands[1] = arc_legitimize_pic_address (operands[1]);
9139 /* Store instructions are limited, they only accept as address an
9140 immediate, a register or a register plus a small immediate. */
9141 if (MEM_P (operands[0])
9142 && !move_dest_operand (operands[0], mode))
9144 rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9145 rtx tmp1 = change_address (operands[0], mode, tmp0);
9146 MEM_COPY_ATTRIBUTES (tmp1, operands[0]);
9150 /* Check if it is constant but it is not legitimized. */
9151 if (CONSTANT_P (operands[1])
9152 && !arc_legitimate_constant_p (mode, operands[1]))
9153 operands[1] = force_reg (mode, XEXP (operands[1], 0));
9154 else if (MEM_P (operands[0])
9155 && ((CONSTANT_P (operands[1])
9156 && !satisfies_constraint_Cm3 (operands[1]))
9157 || MEM_P (operands[1])))
9158 operands[1] = force_reg (mode, operands[1]);
9163 /* Output a library call to a function called FNAME that has been arranged
9164 to be local to any dso. */
9167 arc_output_libcall (const char *fname)
9169 unsigned len = strlen (fname);
9170 static char buf[64];
9172 gcc_assert (len < sizeof buf - 35);
9173 if (TARGET_LONG_CALLS_SET
9174 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
9177 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
9179 sprintf (buf, "jl%%! @%s", fname);
9182 sprintf (buf, "bl%%!%%* @%s", fname);
9186 /* Return the SImode highpart of the DImode value IN. */
9189 disi_highpart (rtx in)
9191 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
9194 /* Return length adjustment for INSN.
9196 A write to a core reg greater or equal to 32 must not be immediately
9197 followed by a use. Anticipate the length requirement to insert a nop
9198 between PRED and SUCC to prevent a hazard. */
9201 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
9205 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
9206 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
9207 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
9208 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
9209 if (recog_memoized (pred) == CODE_FOR_mulsi_600
9210 || recog_memoized (pred) == CODE_FOR_umul_600
9211 || recog_memoized (pred) == CODE_FOR_mac_600
9212 || recog_memoized (pred) == CODE_FOR_mul64_600
9213 || recog_memoized (pred) == CODE_FOR_mac64_600
9214 || recog_memoized (pred) == CODE_FOR_umul64_600
9215 || recog_memoized (pred) == CODE_FOR_umac64_600)
9217 subrtx_iterator::array_type array;
9218 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
9220 const_rtx x = *iter;
9221 switch (GET_CODE (x))
9223 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9226 /* This is also fine for PRE/POST_MODIFY, because they
9230 rtx dest = XEXP (x, 0);
9231 /* Check if this sets a an extension register. N.B. we use 61 for the
9232 condition codes, which is definitely not an extension register. */
9233 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
9234 /* Check if the same register is used by the PAT. */
9235 && (refers_to_regno_p
9237 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
9238 PATTERN (succ), 0)))
9244 /* Given a rtx, check if it is an assembly instruction or not. */
9247 arc_asm_insn_p (rtx x)
9254 switch (GET_CODE (x))
9261 return arc_asm_insn_p (SET_SRC (x));
9265 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
9266 j += arc_asm_insn_p (XVECEXP (x, 0, i));
9279 A write to a core reg greater or equal to 32 must not be immediately
9280 followed by a use. Anticipate the length requirement to insert a nop
9281 between PRED and SUCC to prevent a hazard. */
9284 arc_hazard (rtx_insn *pred, rtx_insn *succ)
9286 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
9290 return arc600_corereg_hazard (pred, succ);
9295 /* Return length adjustment for INSN. */
9298 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
9302 /* We already handle sequences by ignoring the delay sequence flag. */
9303 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
9306 /* Check for return with but one preceding insn since function
9308 if (TARGET_PAD_RETURN
9310 && GET_CODE (PATTERN (insn)) != ADDR_VEC
9311 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
9312 && get_attr_type (insn) == TYPE_RETURN)
9314 rtx_insn *prev = prev_active_insn (insn);
9316 if (!prev || !(prev = prev_active_insn (prev))
9317 || ((NONJUMP_INSN_P (prev)
9318 && GET_CODE (PATTERN (prev)) == SEQUENCE)
9319 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9321 : CALL_ATTR (prev, NON_SIBCALL)))
9326 rtx_insn *succ = next_real_insn (insn);
9328 /* One the ARC600, a write to an extension register must be separated
9330 if (succ && INSN_P (succ))
9331 len += arc600_corereg_hazard (insn, succ);
9334 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9336 extract_constrain_insn_cached (insn);
9341 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
9342 CC field of *STATEP. */
9345 arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
9347 rtx cond = statep->cond;
9348 int raw_cc = get_arc_condition_code (cond);
9350 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
9352 if (statep->cc == raw_cc)
9353 return copy_rtx (cond);
9355 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
9357 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9358 enum rtx_code code = reverse_condition (GET_CODE (cond));
9359 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9360 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9362 return gen_rtx_fmt_ee (code, GET_MODE (cond),
9363 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
9366 /* Return version of PAT conditionalized with COND, which is part of INSN.
9367 ANNULLED indicates if INSN is an annulled delay-slot insn.
9368 Register further changes if necessary. */
9370 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
9372 /* For commutative operators, we generally prefer to have
9373 the first source match the destination. */
9374 if (GET_CODE (pat) == SET)
9376 rtx src = SET_SRC (pat);
9378 if (COMMUTATIVE_P (src))
9380 rtx src0 = XEXP (src, 0);
9381 rtx src1 = XEXP (src, 1);
9382 rtx dst = SET_DEST (pat);
9384 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
9385 /* Leave add_n alone - the canonical form is to
9386 have the complex summand first. */
9388 pat = gen_rtx_SET (dst,
9389 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
9394 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
9395 what to do with COND_EXEC. */
9396 if (RTX_FRAME_RELATED_P (insn))
9398 /* If this is the delay slot insn of an anulled branch,
9399 dwarf2out.c:scan_trace understands the anulling semantics
9400 without the COND_EXEC. */
9401 gcc_assert (annulled);
9402 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
9404 validate_change (insn, ®_NOTES (insn), note, 1);
9406 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9410 /* Use the ccfsm machinery to do if conversion. */
9415 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
9417 memset (statep, 0, sizeof *statep);
9418 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
9420 arc_ccfsm_advance (insn, statep);
9422 switch (statep->state)
9428 /* Deleted branch. */
9429 arc_ccfsm_post_advance (insn, statep);
9430 gcc_assert (!IN_RANGE (statep->state, 1, 2));
9431 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
9432 if (GET_CODE (PATTERN (seq)) == SEQUENCE)
9434 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
9435 rtx pat = PATTERN (slot);
9436 if (INSN_ANNULLED_BRANCH_P (insn))
9439 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
9440 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9442 if (!validate_change (seq, &PATTERN (seq), pat, 0))
9444 PUT_CODE (slot, NOTE);
9445 NOTE_KIND (slot) = NOTE_INSN_DELETED;
9449 set_insn_deleted (insn);
9455 && statep->target_label == CODE_LABEL_NUMBER (insn))
9457 arc_ccfsm_post_advance (insn, statep);
9458 if (--LABEL_NUSES (insn) == 0)
9464 if (!NONDEBUG_INSN_P (insn))
9467 /* Conditionalized insn. */
9469 rtx_insn *prev, *pprev;
9470 rtx *patp, pat, cond;
9471 bool annulled; annulled = false;
9473 /* If this is a delay slot insn in a non-annulled branch,
9474 don't conditionalize it. N.B., this should be fine for
9475 conditional return too. However, don't do this for
9476 unconditional branches, as these would be encountered when
9477 processing an 'else' part. */
9478 prev = PREV_INSN (insn);
9479 pprev = PREV_INSN (prev);
9480 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
9481 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
9483 if (!INSN_ANNULLED_BRANCH_P (prev))
9488 patp = &PATTERN (insn);
9490 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
9491 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
9493 /* ??? don't conditionalize if all side effects are dead
9494 in the not-execute case. */
9496 pat = conditionalize_nonjump (pat, cond, insn, annulled);
9498 else if (simplejump_p (insn))
9500 patp = &SET_SRC (pat);
9501 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
9503 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
9505 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
9506 pat = gen_rtx_SET (pc_rtx, pat);
9510 validate_change (insn, patp, pat, 1);
9511 if (!apply_change_group ())
9515 rtx_insn *next = next_nonnote_insn (insn);
9516 if (GET_CODE (next) == BARRIER)
9518 if (statep->state == 3)
9525 arc_ccfsm_post_advance (insn, statep);
9530 /* Find annulled delay insns and convert them to use the appropriate predicate.
9531 This allows branch shortening to size up these insns properly. */
9534 arc_predicate_delay_insns (void)
9536 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9538 rtx pat, jump, dlay, src, cond, *patp;
9541 if (!NONJUMP_INSN_P (insn)
9542 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9544 jump = XVECEXP (pat, 0, 0);
9545 dlay = XVECEXP (pat, 0, 1);
9546 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9548 /* If the branch insn does the annulling, leave the delay insn alone. */
9549 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9551 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9552 on the other path. */
9553 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9554 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9555 src = SET_SRC (PATTERN (jump));
9556 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9557 cond = XEXP (src, 0);
9558 if (XEXP (src, 2) == pc_rtx)
9560 else if (XEXP (src, 1) == pc_rtx)
9564 if (reverse != !INSN_FROM_TARGET_P (dlay))
9566 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9567 enum rtx_code code = reverse_condition (GET_CODE (cond));
9568 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9569 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9571 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9572 copy_rtx (XEXP (cond, 0)),
9573 copy_rtx (XEXP (cond, 1)));
9576 cond = copy_rtx (cond);
9577 patp = &PATTERN (dlay);
9579 pat = conditionalize_nonjump (pat, cond, dlay, true);
9580 validate_change (dlay, patp, pat, 1);
9581 if (!apply_change_group ())
9587 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9588 (other than of a forward brcc), it creates a hazard when there is a read
9589 of the same register at the branch target. We can't know what is at the
9590 branch target of calls, and for branches, we don't really know before the
9591 end of delay slot scheduling, either. Not only can individual instruction
9592 be hoisted out into a delay slot, a basic block can also be emptied this
9593 way, and branch and/or fall through targets be redirected. Hence we don't
9594 want such writes in a delay slot. */
9596 /* Return nonzreo iff INSN writes to an extension core register. */
9599 arc_write_ext_corereg (rtx insn)
9601 subrtx_iterator::array_type array;
9602 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9604 const_rtx x = *iter;
9605 switch (GET_CODE (x))
9607 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9610 /* This is also fine for PRE/POST_MODIFY, because they
9614 const_rtx dest = XEXP (x, 0);
9615 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9621 /* This is like the hook, but returns NULL when it can't / won't generate
9622 a legitimate address. */
9625 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9631 if (GET_CODE (addr) == CONST)
9632 addr = XEXP (addr, 0);
9634 if (GET_CODE (addr) == PLUS
9635 && CONST_INT_P (XEXP (addr, 1))
9636 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9637 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9638 || (REG_P (XEXP (addr, 0))
9639 && (INTVAL (XEXP (addr, 1)) & 252))))
9641 HOST_WIDE_INT offs, upper;
9642 int size = GET_MODE_SIZE (mode);
9644 offs = INTVAL (XEXP (addr, 1));
9645 upper = (offs + 256 * size) & ~511 * size;
9646 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9647 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9648 if (GET_CODE (x) == CONST)
9649 inner = gen_rtx_CONST (Pmode, inner);
9651 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9654 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9655 x = force_reg (Pmode, x);
9656 if (memory_address_p ((machine_mode) mode, x))
9662 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9664 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9672 arc_delegitimize_address_0 (rtx op)
9674 switch (GET_CODE (op))
9677 return arc_delegitimize_address_0 (XEXP (op, 0));
9680 switch (XINT (op, 1))
9682 case ARC_UNSPEC_GOT:
9683 case ARC_UNSPEC_GOTOFFPC:
9684 return XVECEXP (op, 0, 0);
9692 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9693 rtx t2 = XEXP (op, 1);
9696 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9707 arc_delegitimize_address (rtx orig_x)
9714 x = arc_delegitimize_address_0 (x);
9719 x = replace_equiv_address_nv (orig_x, x);
9723 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9724 differ from the hardware register number in order to allow the generic
9725 code to correctly split the concatenation of acc1 and acc2. */
9730 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9733 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9734 differ from the hardware register number in order to allow the generic
9735 code to correctly split the concatenation of acc1 and acc2. */
9740 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9743 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9744 differ from the hardware register number in order to allow the generic
9745 code to correctly split the concatenation of mhi and mlo. */
9750 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
9753 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9754 differ from the hardware register number in order to allow the generic
9755 code to correctly split the concatenation of mhi and mlo. */
9760 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
9763 /* FIXME: a parameter should be added, and code added to final.c,
9764 to reproduce this functionality in shorten_branches. */
9766 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9767 a previous instruction. */
9769 arc_unalign_branch_p (rtx branch)
9773 if (!TARGET_UNALIGN_BRANCH)
9775 /* Do not do this if we have a filled delay slot. */
9776 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
9777 && !NEXT_INSN (branch)->deleted ())
9779 note = find_reg_note (branch, REG_BR_PROB, 0);
9781 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
9782 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
9786 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9787 are three reasons why we need to consider branches to be length 6:
9788 - annull-false delay slot insns are implemented using conditional execution,
9789 thus preventing short insn formation where used.
9790 - for ARC600: annul-true delay slot insns are implemented where possible
9791 using conditional execution, preventing short insn formation where used.
9792 - for ARC700: likely or somewhat likely taken branches are made long and
9793 unaligned if possible to avoid branch penalty. */
9796 arc_branch_size_unknown_p (void)
9798 return !optimize_size && arc_reorg_in_progress;
9801 /* The usual; we set up our machine_function data. */
9803 static struct machine_function *
9804 arc_init_machine_status (void)
9806 struct machine_function *machine;
9807 machine = ggc_cleared_alloc<machine_function> ();
9808 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9813 /* Implements INIT_EXPANDERS. We just set up to call the above
9817 arc_init_expanders (void)
9819 init_machine_status = arc_init_machine_status;
9822 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9823 indicates a number of elements to ignore - that allows to have a
9824 sibcall pattern that starts with (return). LOAD_P is zero for store
9825 multiple (for prologues), and one for load multiples (for epilogues),
9826 and two for load multiples where no final clobber of blink is required.
9827 We also skip the first load / store element since this is supposed to
9828 be checked in the instruction pattern. */
9831 arc_check_millicode (rtx op, int offset, int load_p)
9833 int len = XVECLEN (op, 0) - offset;
9838 if (len < 2 || len > 13)
9844 rtx elt = XVECEXP (op, 0, --len);
9846 if (GET_CODE (elt) != CLOBBER
9847 || !REG_P (XEXP (elt, 0))
9848 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9849 || len < 3 || len > 13)
9852 for (i = 1; i < len; i++)
9854 rtx elt = XVECEXP (op, 0, i + offset);
9857 if (GET_CODE (elt) != SET)
9859 mem = XEXP (elt, load_p);
9860 reg = XEXP (elt, 1-load_p);
9861 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9863 addr = XEXP (mem, 0);
9864 if (GET_CODE (addr) != PLUS
9865 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9866 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9872 /* Accessor functions for cfun->machine->unalign. */
9875 arc_clear_unalign (void)
9878 cfun->machine->unalign = 0;
9882 arc_toggle_unalign (void)
9884 cfun->machine->unalign ^= 2;
9887 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9888 constant in operand 2, but which would require a LIMM because of
9890 operands 3 and 4 are new SET_SRCs for operands 0. */
9893 split_addsi (rtx *operands)
9895 int val = INTVAL (operands[2]);
9897 /* Try for two short insns first. Lengths being equal, we prefer
9898 expansions with shorter register lifetimes. */
9899 if (val > 127 && val <= 255
9900 && satisfies_constraint_Rcq (operands[0]))
9902 operands[3] = operands[2];
9903 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9907 operands[3] = operands[1];
9908 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
9912 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9913 constant in operand 1, but which would require a LIMM because of
9915 operands 3 and 4 are new SET_SRCs for operands 0. */
9918 split_subsi (rtx *operands)
9920 int val = INTVAL (operands[1]);
9922 /* Try for two short insns first. Lengths being equal, we prefer
9923 expansions with shorter register lifetimes. */
9924 if (satisfies_constraint_Rcq (operands[0])
9925 && satisfies_constraint_Rcq (operands[2]))
9927 if (val >= -31 && val <= 127)
9929 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9930 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9933 else if (val >= 0 && val < 255)
9935 operands[3] = operands[1];
9936 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9940 /* If the destination is not an ARCompact16 register, we might
9941 still have a chance to make a short insn if the source is;
9942 we need to start with a reg-reg move for this. */
9943 operands[3] = operands[2];
9944 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9947 /* Handle DOUBLE_REGS uses.
9948 Operand 0: destination register
9949 Operand 1: source register */
9952 arc_process_double_reg_moves (rtx *operands)
9954 enum usesDxState { none, srcDx, destDx, maxDx };
9955 enum usesDxState state = none;
9956 rtx dest = operands[0];
9957 rtx src = operands[1];
9959 if (refers_to_regno_p (40, 44, src, 0))
9962 gcc_assert (REG_P (dest));
9964 if (refers_to_regno_p (40, 44, dest, 0))
9966 /* Via arc_register_move_cost, we should never see D,D moves. */
9967 gcc_assert (REG_P (src));
9968 gcc_assert (state == none);
9977 /* Without the LR insn, we need to split this into a
9978 sequence of insns which will use the DEXCLx and DADDHxy
9979 insns to be able to read the Dx register in question. */
9980 if (TARGET_DPFP_DISABLE_LRSR)
9982 /* gen *movdf_insn_nolrsr */
9983 rtx set = gen_rtx_SET (dest, src);
9984 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9985 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9989 /* When we have 'mov D, r' or 'mov D, D' then get the target
9990 register pair for use with LR insn. */
9991 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9992 TARGET_BIG_ENDIAN ? 0 : 4);
9993 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9994 TARGET_BIG_ENDIAN ? 4 : 0);
9996 /* Produce the two LR insns to get the high and low parts. */
9997 emit_insn (gen_rtx_SET (destHigh,
9998 gen_rtx_UNSPEC_VOLATILE (Pmode,
10000 VUNSPEC_ARC_LR_HIGH)));
10001 emit_insn (gen_rtx_SET (destLow,
10002 gen_rtx_UNSPEC_VOLATILE (Pmode,
10003 gen_rtvec (1, src),
10007 else if (state == destDx)
10009 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
10010 LR insn get the target register pair. */
10011 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
10012 TARGET_BIG_ENDIAN ? 0 : 4);
10013 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
10014 TARGET_BIG_ENDIAN ? 4 : 0);
10016 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
10019 gcc_unreachable ();
10024 /* operands 0..1 are the operands of a 64 bit move instruction.
10025 split it into two moves with operands 2/3 and 4/5. */
10028 arc_split_move (rtx *operands)
10030 machine_mode mode = GET_MODE (operands[0]);
10037 if (arc_process_double_reg_moves (operands))
10042 && ((memory_operand (operands[0], mode)
10043 && (even_register_operand (operands[1], mode)
10044 || satisfies_constraint_Cm3 (operands[1])))
10045 || (memory_operand (operands[1], mode)
10046 && even_register_operand (operands[0], mode))))
10048 emit_move_insn (operands[0], operands[1]);
10052 if (TARGET_PLUS_QMACW
10053 && GET_CODE (operands[1]) == CONST_VECTOR)
10055 HOST_WIDE_INT intval0, intval1;
10056 if (GET_MODE (operands[1]) == V2SImode)
10058 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
10059 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
10063 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
10064 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
10065 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
10066 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
10068 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
10069 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
10070 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
10071 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
10072 emit_move_insn (xop[0], xop[2]);
10073 emit_move_insn (xop[3], xop[1]);
10077 for (i = 0; i < 2; i++)
10079 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
10081 rtx addr = XEXP (operands[i], 0);
10083 enum rtx_code code;
10085 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
10086 switch (GET_CODE (addr))
10088 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
10089 case PRE_INC: o = GEN_INT (8); goto pre_modify;
10090 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
10094 case POST_DEC: o = GEN_INT (-8); goto post_modify;
10095 case POST_INC: o = GEN_INT (8); goto post_modify;
10096 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
10098 code = POST_MODIFY;
10102 gcc_unreachable ();
10104 r = XEXP (addr, 0);
10105 xop[0+i] = adjust_automodify_address_nv
10106 (operands[i], SImode,
10107 gen_rtx_fmt_ee (code, Pmode, r,
10108 gen_rtx_PLUS (Pmode, r, o)),
10110 xop[2+i] = adjust_automodify_address_nv
10111 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
10115 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
10116 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
10119 if (reg_overlap_mentioned_p (xop[0], xop[3]))
10122 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
10125 emit_move_insn (xop[0 + swap], xop[1 + swap]);
10126 emit_move_insn (xop[2 - swap], xop[3 - swap]);
10130 /* Select between the instruction output templates s_tmpl (for short INSNs)
10131 and l_tmpl (for long INSNs). */
10134 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
10136 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
10138 extract_constrain_insn_cached (insn);
10139 return is_short ? s_tmpl : l_tmpl;
10142 /* Searches X for any reference to REGNO, returning the rtx of the
10143 reference found if any. Otherwise, returns NULL_RTX. */
10146 arc_regno_use_in (unsigned int regno, rtx x)
10152 if (REG_P (x) && refers_to_regno_p (regno, x))
10155 fmt = GET_RTX_FORMAT (GET_CODE (x));
10156 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
10160 if ((tem = regno_use_in (regno, XEXP (x, i))))
10163 else if (fmt[i] == 'E')
10164 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
10165 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
10172 /* Return the integer value of the "type" attribute for INSN, or -1 if
10173 INSN can't have attributes. */
10176 arc_attr_type (rtx_insn *insn)
10178 if (NONJUMP_INSN_P (insn)
10179 ? (GET_CODE (PATTERN (insn)) == USE
10180 || GET_CODE (PATTERN (insn)) == CLOBBER)
10182 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
10183 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
10186 return get_attr_type (insn);
10189 /* Return true if insn sets the condition codes. */
10192 arc_sets_cc_p (rtx_insn *insn)
10194 if (NONJUMP_INSN_P (insn))
10195 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
10196 insn = seq->insn (seq->len () - 1);
10197 return arc_attr_type (insn) == TYPE_COMPARE;
10200 /* Return true if INSN is an instruction with a delay slot we may want
10204 arc_need_delay (rtx_insn *insn)
10208 if (!flag_delayed_branch)
10210 /* The return at the end of a function needs a delay slot. */
10211 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
10212 && (!(next = next_active_insn (insn))
10213 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
10214 && arc_attr_type (next) == TYPE_RETURN))
10215 && (!TARGET_PAD_RETURN
10216 || (prev_active_insn (insn)
10217 && prev_active_insn (prev_active_insn (insn))
10218 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
10220 if (NONJUMP_INSN_P (insn)
10221 ? (GET_CODE (PATTERN (insn)) == USE
10222 || GET_CODE (PATTERN (insn)) == CLOBBER
10223 || GET_CODE (PATTERN (insn)) == SEQUENCE)
10225 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
10226 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
10229 return num_delay_slots (insn) != 0;
10232 /* Return true if the scheduling pass(es) has/have already run,
10233 i.e. where possible, we should try to mitigate high latencies
10234 by different instruction selection. */
10237 arc_scheduling_not_expected (void)
10239 return cfun->machine->arc_reorg_started;
10242 /* Code has a minimum p2 alignment of 1, which we must restore after
10243 an ADDR_DIFF_VEC. */
10246 arc_label_align (rtx_insn *label)
10248 if (align_labels.levels[0].log < 1)
10250 rtx_insn *next = next_nonnote_nondebug_insn (label);
10251 if (INSN_P (next) && recog_memoized (next) >= 0)
10254 return align_labels.levels[0].log;
10257 /* Return true if LABEL is in executable code. */
10260 arc_text_label (rtx_insn *label)
10264 /* ??? We use deleted labels like they were still there, see
10265 gcc.c-torture/compile/20000326-2.c . */
10266 gcc_assert (GET_CODE (label) == CODE_LABEL
10267 || (GET_CODE (label) == NOTE
10268 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
10269 next = next_nonnote_insn (label);
10271 return (!JUMP_TABLE_DATA_P (next)
10272 || GET_CODE (PATTERN (next)) != ADDR_VEC);
10273 else if (!PREV_INSN (label))
10274 /* ??? sometimes text labels get inserted very late, see
10275 gcc.dg/torture/stackalign/comp-goto-1.c */
10280 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
10281 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
10282 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
10283 to redirect two breqs. */
10286 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
10288 /* ??? get_attr_type is declared to take an rtx. */
10289 union { const rtx_insn *c; rtx_insn *r; } u;
10292 if (CROSSING_JUMP_P (followee))
10293 switch (get_attr_type (u.r))
10296 if (get_attr_length (u.r) != 2)
10298 /* Fall through. */
10300 case TYPE_BRCC_NO_DELAY_SLOT:
10309 /* Implement EPILOGUE_USES.
10310 Return true if REGNO should be added to the deemed uses of the epilogue.
10312 We have to make sure all the register restore instructions are
10313 known to be live in interrupt functions, plus the blink register if
10314 it is clobbered by the isr. */
10317 arc_epilogue_uses (int regno)
10319 unsigned int fn_type;
10320 fn_type = arc_compute_function_type (cfun);
10322 if (regno == arc_tp_regno)
10325 if (regno == RETURN_ADDR_REGNUM)
10328 if (regno == arc_return_address_register (fn_type))
10331 if (epilogue_completed && ARC_INTERRUPT_P (fn_type))
10333 /* An interrupt function restores more registers. */
10334 if (df_regs_ever_live_p (regno) || call_used_or_fixed_reg_p (regno))
10341 /* Helper for EH_USES macro. */
10344 arc_eh_uses (int regno)
10346 if (regno == arc_tp_regno)
10351 /* Return true if we use LRA instead of reload pass. */
10356 return arc_lra_flag;
10359 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10360 Rcq registers, because some insn are shorter with them. OTOH we already
10361 have separate alternatives for this purpose, and other insns don't
10362 mind, so maybe we should rather prefer the other registers?
10363 We need more data, and we can only get that if we allow people to
10364 try all options. */
10366 arc_register_priority (int r)
10368 switch (arc_lra_priority_tag)
10370 case ARC_LRA_PRIORITY_NONE:
10372 case ARC_LRA_PRIORITY_NONCOMPACT:
10373 return ((((r & 7) ^ 4) - 4) & 15) != r;
10374 case ARC_LRA_PRIORITY_COMPACT:
10375 return ((((r & 7) ^ 4) - 4) & 15) == r;
10377 gcc_unreachable ();
10382 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
10384 return GENERAL_REGS;
10388 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
10392 enum reload_type type = (enum reload_type) itype;
10394 if (GET_CODE (x) == PLUS
10395 && CONST_INT_P (XEXP (x, 1))
10396 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
10397 || (REG_P (XEXP (x, 0))
10398 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
10400 int scale = GET_MODE_SIZE (mode);
10402 rtx index_rtx = XEXP (x, 1);
10403 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
10404 rtx reg, sum, sum2;
10408 if ((scale-1) & offset)
10410 shift = scale >> 1;
10412 = ((offset + (256 << shift))
10413 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
10414 /* Sometimes the normal form does not suit DImode. We
10415 could avoid that by using smaller ranges, but that
10416 would give less optimized code when SImode is
10418 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
10423 regno = REGNO (reg);
10424 sum2 = sum = plus_constant (Pmode, reg, offset_base);
10426 if (reg_equiv_constant (regno))
10428 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
10430 if (GET_CODE (sum2) == PLUS)
10431 sum2 = gen_rtx_CONST (Pmode, sum2);
10433 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
10434 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
10435 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
10440 /* We must re-recognize what we created before. */
10441 else if (GET_CODE (x) == PLUS
10442 && GET_CODE (XEXP (x, 0)) == PLUS
10443 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
10444 && REG_P (XEXP (XEXP (x, 0), 0))
10445 && CONST_INT_P (XEXP (x, 1)))
10447 /* Because this address is so complex, we know it must have
10448 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10449 it is already unshared, and needs no further unsharing. */
10450 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
10451 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10457 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10460 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
10461 unsigned int align,
10462 enum by_pieces_operation op,
10465 /* Let the cpymem expander handle small block moves. */
10466 if (op == MOVE_BY_PIECES)
10469 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10472 /* Emit a (pre) memory barrier around an atomic sequence according to
10476 arc_pre_atomic_barrier (enum memmodel model)
10478 if (need_atomic_barrier_p (model, true))
10479 emit_insn (gen_memory_barrier ());
10482 /* Emit a (post) memory barrier around an atomic sequence according to
10486 arc_post_atomic_barrier (enum memmodel model)
10488 if (need_atomic_barrier_p (model, false))
10489 emit_insn (gen_memory_barrier ());
10492 /* Expand a compare and swap pattern. */
10495 emit_unlikely_jump (rtx insn)
10497 rtx_insn *jump = emit_jump_insn (insn);
10498 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10501 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10502 32-bit compare and swap on the word containing the byte or
10503 half-word. The difference between a weak and a strong CAS is that
10504 the weak version may simply fail. The strong version relies on two
10505 loops, one checks if the SCOND op is succsfully or not, the other
10506 checks if the 32 bit accessed location which contains the 8 or 16
10507 bit datum is not changed by other thread. The first loop is
10508 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10509 loops is implemented by this routine. */
10512 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10513 rtx oldval, rtx newval, rtx weak,
10514 rtx mod_s, rtx mod_f)
10516 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10517 rtx addr = gen_reg_rtx (Pmode);
10518 rtx off = gen_reg_rtx (SImode);
10519 rtx oldv = gen_reg_rtx (SImode);
10520 rtx newv = gen_reg_rtx (SImode);
10521 rtx oldvalue = gen_reg_rtx (SImode);
10522 rtx newvalue = gen_reg_rtx (SImode);
10523 rtx res = gen_reg_rtx (SImode);
10524 rtx resv = gen_reg_rtx (SImode);
10525 rtx memsi, val, mask, end_label, loop_label, cc, x;
10527 bool is_weak = (weak != const0_rtx);
10529 /* Truncate the address. */
10530 emit_insn (gen_rtx_SET (addr,
10531 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10533 /* Compute the datum offset. */
10534 emit_insn (gen_rtx_SET (off,
10535 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10536 if (TARGET_BIG_ENDIAN)
10537 emit_insn (gen_rtx_SET (off,
10538 gen_rtx_MINUS (SImode,
10539 (GET_MODE (mem) == QImode) ?
10540 GEN_INT (3) : GEN_INT (2), off)));
10542 /* Normal read from truncated address. */
10543 memsi = gen_rtx_MEM (SImode, addr);
10544 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10545 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10547 val = copy_to_reg (memsi);
10549 /* Convert the offset in bits. */
10550 emit_insn (gen_rtx_SET (off,
10551 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10553 /* Get the proper mask. */
10554 if (GET_MODE (mem) == QImode)
10555 mask = force_reg (SImode, GEN_INT (0xff));
10557 mask = force_reg (SImode, GEN_INT (0xffff));
10559 emit_insn (gen_rtx_SET (mask,
10560 gen_rtx_ASHIFT (SImode, mask, off)));
10562 /* Prepare the old and new values. */
10563 emit_insn (gen_rtx_SET (val,
10564 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10567 oldval = gen_lowpart (SImode, oldval);
10568 emit_insn (gen_rtx_SET (oldv,
10569 gen_rtx_ASHIFT (SImode, oldval, off)));
10571 newval = gen_lowpart_common (SImode, newval);
10572 emit_insn (gen_rtx_SET (newv,
10573 gen_rtx_ASHIFT (SImode, newval, off)));
10575 emit_insn (gen_rtx_SET (oldv,
10576 gen_rtx_AND (SImode, oldv, mask)));
10578 emit_insn (gen_rtx_SET (newv,
10579 gen_rtx_AND (SImode, newv, mask)));
10583 end_label = gen_label_rtx ();
10584 loop_label = gen_label_rtx ();
10585 emit_label (loop_label);
10588 /* Make the old and new values. */
10589 emit_insn (gen_rtx_SET (oldvalue,
10590 gen_rtx_IOR (SImode, oldv, val)));
10592 emit_insn (gen_rtx_SET (newvalue,
10593 gen_rtx_IOR (SImode, newv, val)));
10595 /* Try an 32bit atomic compare and swap. It clobbers the CC
10597 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10598 weak, mod_s, mod_f));
10600 /* Regardless of the weakness of the operation, a proper boolean
10601 result needs to be provided. */
10602 x = gen_rtx_REG (CC_Zmode, CC_REG);
10603 x = gen_rtx_EQ (SImode, x, const0_rtx);
10604 emit_insn (gen_rtx_SET (bool_result, x));
10608 /* Check the results: if the atomic op is successfully the goto
10610 x = gen_rtx_REG (CC_Zmode, CC_REG);
10611 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10612 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10613 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10614 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10616 /* Wait for the right moment when the accessed 32-bit location
10618 emit_insn (gen_rtx_SET (resv,
10619 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10621 mode = SELECT_CC_MODE (NE, resv, val);
10622 cc = gen_rtx_REG (mode, CC_REG);
10623 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10625 /* Set the new value of the 32 bit location, proper masked. */
10626 emit_insn (gen_rtx_SET (val, resv));
10628 /* Try again if location is unstable. Fall through if only
10629 scond op failed. */
10630 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10631 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10632 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10633 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10635 emit_label (end_label);
10638 /* End: proper return the result for the given mode. */
10639 emit_insn (gen_rtx_SET (res,
10640 gen_rtx_AND (SImode, res, mask)));
10642 emit_insn (gen_rtx_SET (res,
10643 gen_rtx_LSHIFTRT (SImode, res, off)));
10645 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10648 /* Helper function used by "atomic_compare_and_swap" expand
10652 arc_expand_compare_and_swap (rtx operands[])
10654 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10657 bval = operands[0];
10658 rval = operands[1];
10660 oldval = operands[3];
10661 newval = operands[4];
10662 is_weak = operands[5];
10663 mod_s = operands[6];
10664 mod_f = operands[7];
10665 mode = GET_MODE (mem);
10667 if (reg_overlap_mentioned_p (rval, oldval))
10668 oldval = copy_to_reg (oldval);
10670 if (mode == SImode)
10672 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10673 is_weak, mod_s, mod_f));
10674 x = gen_rtx_REG (CC_Zmode, CC_REG);
10675 x = gen_rtx_EQ (SImode, x, const0_rtx);
10676 emit_insn (gen_rtx_SET (bval, x));
10680 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10681 is_weak, mod_s, mod_f);
10685 /* Helper function used by the "atomic_compare_and_swapsi_1"
10689 arc_split_compare_and_swap (rtx operands[])
10691 rtx rval, mem, oldval, newval;
10693 enum memmodel mod_s, mod_f;
10695 rtx label1, label2, x, cond;
10697 rval = operands[0];
10699 oldval = operands[2];
10700 newval = operands[3];
10701 is_weak = (operands[4] != const0_rtx);
10702 mod_s = (enum memmodel) INTVAL (operands[5]);
10703 mod_f = (enum memmodel) INTVAL (operands[6]);
10704 mode = GET_MODE (mem);
10706 /* ARC atomic ops work only with 32-bit aligned memories. */
10707 gcc_assert (mode == SImode);
10709 arc_pre_atomic_barrier (mod_s);
10714 label1 = gen_label_rtx ();
10715 emit_label (label1);
10717 label2 = gen_label_rtx ();
10719 /* Load exclusive. */
10720 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10722 /* Check if it is oldval. */
10723 mode = SELECT_CC_MODE (NE, rval, oldval);
10724 cond = gen_rtx_REG (mode, CC_REG);
10725 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10727 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10728 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10729 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10730 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10732 /* Exclusively store new item. Store clobbers CC reg. */
10733 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10737 /* Check the result of the store. */
10738 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10739 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10740 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10741 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10742 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10745 if (mod_f != MEMMODEL_RELAXED)
10746 emit_label (label2);
10748 arc_post_atomic_barrier (mod_s);
10750 if (mod_f == MEMMODEL_RELAXED)
10751 emit_label (label2);
10754 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10755 to perform. MEM is the memory on which to operate. VAL is the second
10756 operand of the binary operator. BEFORE and AFTER are optional locations to
10757 return the value of MEM either before of after the operation. MODEL_RTX
10758 is a CONST_INT containing the memory model to use. */
10761 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10762 rtx orig_before, rtx orig_after, rtx model_rtx)
10764 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10765 machine_mode mode = GET_MODE (mem);
10766 rtx label, x, cond;
10767 rtx before = orig_before, after = orig_after;
10769 /* ARC atomic ops work only with 32-bit aligned memories. */
10770 gcc_assert (mode == SImode);
10772 arc_pre_atomic_barrier (model);
10774 label = gen_label_rtx ();
10775 emit_label (label);
10776 label = gen_rtx_LABEL_REF (VOIDmode, label);
10778 if (before == NULL_RTX)
10779 before = gen_reg_rtx (mode);
10781 if (after == NULL_RTX)
10782 after = gen_reg_rtx (mode);
10784 /* Load exclusive. */
10785 emit_insn (gen_arc_load_exclusivesi (before, mem));
10790 x = gen_rtx_AND (mode, before, val);
10791 emit_insn (gen_rtx_SET (after, x));
10792 x = gen_rtx_NOT (mode, after);
10793 emit_insn (gen_rtx_SET (after, x));
10797 if (CONST_INT_P (val))
10799 val = GEN_INT (-INTVAL (val));
10805 x = gen_rtx_fmt_ee (code, mode, before, val);
10806 emit_insn (gen_rtx_SET (after, x));
10810 /* Exclusively store new item. Store clobbers CC reg. */
10811 emit_insn (gen_arc_store_exclusivesi (mem, after));
10813 /* Check the result of the store. */
10814 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10815 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10816 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10818 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10820 arc_post_atomic_barrier (model);
10823 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10826 arc_no_speculation_in_delay_slots_p ()
10831 /* Return a parallel of registers to represent where to find the
10832 register pieces if required, otherwise NULL_RTX. */
10835 arc_dwarf_register_span (rtx rtl)
10837 machine_mode mode = GET_MODE (rtl);
10841 if (GET_MODE_SIZE (mode) != 8)
10844 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10845 regno = REGNO (rtl);
10846 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10847 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10852 /* Return true if OP is an acceptable memory operand for ARCompact
10853 16-bit load instructions of MODE.
10855 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10856 non scaled instructions.
10858 SCALED: TRUE if address can be scaled. */
10861 compact_memory_operand_p (rtx op, machine_mode mode,
10862 bool av2short, bool scaled)
10864 rtx addr, plus0, plus1;
10867 /* Eliminate non-memory operations. */
10868 if (GET_CODE (op) != MEM)
10871 /* .di instructions have no 16-bit form. */
10872 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10875 /* likewise for uncached types. */
10876 if (arc_is_uncached_mem_p (op))
10879 if (mode == VOIDmode)
10880 mode = GET_MODE (op);
10882 size = GET_MODE_SIZE (mode);
10884 /* dword operations really put out 2 instructions, so eliminate
10886 if (size > UNITS_PER_WORD)
10889 /* Decode the address now. */
10890 addr = XEXP (op, 0);
10891 switch (GET_CODE (addr))
10894 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10895 || COMPACT_GP_REG_P (REGNO (addr))
10896 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10898 plus0 = XEXP (addr, 0);
10899 plus1 = XEXP (addr, 1);
10901 if ((GET_CODE (plus0) == REG)
10902 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10903 || COMPACT_GP_REG_P (REGNO (plus0)))
10904 && ((GET_CODE (plus1) == REG)
10905 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10906 || COMPACT_GP_REG_P (REGNO (plus1)))))
10911 if ((GET_CODE (plus0) == REG)
10912 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10913 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10914 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10915 && (GET_CODE (plus1) == CONST_INT))
10917 bool valid = false;
10919 off = INTVAL (plus1);
10921 /* Negative offset is not supported in 16-bit load/store insns. */
10925 /* Only u5 immediates allowed in code density instructions. */
10933 /* This is an ldh_s.x instruction, check the u6
10935 if (COMPACT_GP_REG_P (REGNO (plus0)))
10939 /* Only u5 immediates allowed in 32bit access code
10940 density instructions. */
10941 if (REGNO (plus0) <= 31)
10942 return ((off < 32) && (off % 4 == 0));
10949 if (COMPACT_GP_REG_P (REGNO (plus0)))
10960 /* The 6-bit constant get shifted to fit the real
10961 5-bits field. Check also for the alignment. */
10962 return ((off < 64) && (off % 2 == 0));
10964 return ((off < 128) && (off % 4 == 0));
10971 if (REG_P (plus0) && CONST_INT_P (plus1)
10972 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10973 || SP_REG_P (REGNO (plus0)))
10976 off = INTVAL (plus1);
10977 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10980 if ((GET_CODE (plus0) == MULT)
10981 && (GET_CODE (XEXP (plus0, 0)) == REG)
10982 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10983 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10984 && (GET_CODE (plus1) == REG)
10985 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10986 || COMPACT_GP_REG_P (REGNO (plus1))))
10990 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10991 for 16-bit load instructions. */
10996 /* Return nonzero if a jli call should be generated for a call from
10997 the current function to DECL. */
11000 arc_is_jli_call_p (rtx pat)
11003 tree decl = SYMBOL_REF_DECL (pat);
11005 /* If it is not a well defined public function then return false. */
11006 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
11009 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
11010 if (lookup_attribute ("jli_always", attrs))
11013 if (lookup_attribute ("jli_fixed", attrs))
11016 return TARGET_JLI_ALWAYS;
11019 /* Handle and "jli" attribute; arguments as in struct
11020 attribute_spec.handler. */
11023 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
11024 tree name, tree args, int,
11025 bool *no_add_attrs)
11029 warning (OPT_Wattributes,
11030 "%qE attribute only valid for ARCv2 architecture",
11032 *no_add_attrs = true;
11035 if (args == NULL_TREE)
11037 warning (OPT_Wattributes,
11038 "argument of %qE attribute is missing",
11040 *no_add_attrs = true;
11044 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11045 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11046 tree arg = TREE_VALUE (args);
11047 if (TREE_CODE (arg) != INTEGER_CST)
11049 warning (0, "%qE attribute allows only an integer constant argument",
11051 *no_add_attrs = true;
11053 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11058 /* Handle and "scure" attribute; arguments as in struct
11059 attribute_spec.handler. */
11062 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
11063 tree name, tree args, int,
11064 bool *no_add_attrs)
11068 warning (OPT_Wattributes,
11069 "%qE attribute only valid for ARC EM architecture",
11071 *no_add_attrs = true;
11074 if (args == NULL_TREE)
11076 warning (OPT_Wattributes,
11077 "argument of %qE attribute is missing",
11079 *no_add_attrs = true;
11083 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11084 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11085 tree arg = TREE_VALUE (args);
11086 if (TREE_CODE (arg) != INTEGER_CST)
11088 warning (0, "%qE attribute allows only an integer constant argument",
11090 *no_add_attrs = true;
11096 /* Return nonzero if the symbol is a secure function. */
11099 arc_is_secure_call_p (rtx pat)
11102 tree decl = SYMBOL_REF_DECL (pat);
11107 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
11108 if (lookup_attribute ("secure_call", attrs))
11114 /* Handle "uncached" qualifier. */
11117 arc_handle_uncached_attribute (tree *node,
11118 tree name, tree args,
11119 int flags ATTRIBUTE_UNUSED,
11120 bool *no_add_attrs)
11122 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
11124 error ("%qE attribute only applies to types",
11126 *no_add_attrs = true;
11130 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
11135 /* Return TRUE if PAT is a memory addressing an uncached data. */
11138 arc_is_uncached_mem_p (rtx pat)
11140 tree attrs = NULL_TREE;
11146 /* Get the memory attributes. */
11147 addr = MEM_EXPR (pat);
11151 /* Get the attributes. */
11152 if (TREE_CODE (addr) == MEM_REF)
11154 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
11155 if (lookup_attribute ("uncached", attrs))
11158 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
11159 if (lookup_attribute ("uncached", attrs))
11163 /* For COMPONENT_REF, use the FIELD_DECL from tree operand 1. */
11164 if (TREE_CODE (addr) == COMPONENT_REF)
11166 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
11167 if (lookup_attribute ("uncached", attrs))
11173 /* Handle aux attribute. The auxiliary registers are addressed using
11174 special instructions lr and sr. The attribute 'aux' indicates if a
11175 variable refers to the aux-regs and what is the register number
11179 arc_handle_aux_attribute (tree *node,
11180 tree name, tree args, int,
11181 bool *no_add_attrs)
11183 /* Isn't it better to use address spaces for the aux-regs? */
11184 if (DECL_P (*node))
11186 if (TREE_CODE (*node) != VAR_DECL)
11188 error ("%qE attribute only applies to variables", name);
11189 *no_add_attrs = true;
11193 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11194 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11195 tree arg = TREE_VALUE (args);
11196 if (TREE_CODE (arg) != INTEGER_CST)
11198 warning (OPT_Wattributes, "%qE attribute allows only an integer "
11199 "constant argument", name);
11200 *no_add_attrs = true;
11202 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11205 if (TREE_CODE (*node) == VAR_DECL)
11207 tree fntype = TREE_TYPE (*node);
11208 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
11210 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
11211 TYPE_ATTRIBUTES (fntype));
11212 TYPE_ATTRIBUTES (fntype) = attrs;
11219 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
11220 anchors for small data: the GP register acts as an anchor in that
11221 case. We also don't want to use them for PC-relative accesses,
11222 where the PC acts as an anchor. Prohibit also TLS symbols to use
11226 arc_use_anchors_for_symbol_p (const_rtx symbol)
11228 if (SYMBOL_REF_TLS_MODEL (symbol))
11234 if (SYMBOL_REF_SMALL_P (symbol))
11237 return default_use_anchors_for_symbol_p (symbol);
11240 /* Return true if SUBST can't safely replace its equivalent during RA. */
11242 arc_cannot_substitute_mem_equiv_p (rtx)
11244 /* If SUBST is mem[base+index], the address may not fit ISA,
11245 thus return true. */
11249 /* Checks whether the operands are valid for use in an LDD/STD
11250 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
11251 by the patterns. Assumes that the address in the base register RN
11252 is word aligned. Pattern guarantees that both memory accesses use
11253 the same base register, the offsets are constants within the range,
11254 and the gap between the offsets is 4. If reload complete then
11255 check that registers are legal. */
11258 operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT offset)
11260 unsigned int t, t2;
11262 if (!reload_completed)
11265 if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & (~0x03),
11266 (offset & (GET_MODE_SIZE (DImode) - 1) & 3
11267 ? 0 : -(-GET_MODE_SIZE (DImode) | (~0x03)) >> 1))))
11273 if ((t2 == PCL_REG)
11274 || (t % 2 != 0) /* First destination register is not even. */
11281 /* Helper for gen_operands_ldd_std. Returns true iff the memory
11282 operand MEM's address contains an immediate offset from the base
11283 register and has no side effects, in which case it sets BASE and
11284 OFFSET accordingly. */
11287 mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset)
11291 gcc_assert (base != NULL && offset != NULL);
11293 /* TODO: Handle more general memory operand patterns, such as
11294 PRE_DEC and PRE_INC. */
11296 if (side_effects_p (mem))
11299 /* Can't deal with subregs. */
11300 if (GET_CODE (mem) == SUBREG)
11303 gcc_assert (MEM_P (mem));
11305 *offset = const0_rtx;
11307 addr = XEXP (mem, 0);
11309 /* If addr isn't valid for DImode, then we can't handle it. */
11310 if (!arc_legitimate_address_p (DImode, addr,
11311 reload_in_progress || reload_completed))
11319 else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
11321 *base = XEXP (addr, 0);
11322 *offset = XEXP (addr, 1);
11323 return (REG_P (*base) && CONST_INT_P (*offset));
11329 /* Called from peephole2 to replace two word-size accesses with a
11330 single LDD/STD instruction. Returns true iff we can generate a new
11331 instruction sequence. That is, both accesses use the same base
11332 register and the gap between constant offsets is 4. OPERANDS are
11333 the operands found by the peephole matcher; OPERANDS[0,1] are
11334 register operands, and OPERANDS[2,3] are the corresponding memory
11335 operands. LOAD indicates whether the access is load or store. */
11338 gen_operands_ldd_std (rtx *operands, bool load, bool commute)
11341 HOST_WIDE_INT offsets[2], offset;
11343 rtx cur_base, cur_offset, tmp;
11344 rtx base = NULL_RTX;
11346 /* Check that the memory references are immediate offsets from the
11347 same base register. Extract the base register, the destination
11348 registers, and the corresponding memory offsets. */
11349 for (i = 0; i < nops; i++)
11351 if (!mem_ok_for_ldd_std (operands[nops+i], &cur_base, &cur_offset))
11356 else if (REGNO (base) != REGNO (cur_base))
11359 offsets[i] = INTVAL (cur_offset);
11360 if (GET_CODE (operands[i]) == SUBREG)
11362 tmp = SUBREG_REG (operands[i]);
11363 gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp));
11368 /* Make sure there is no dependency between the individual loads. */
11369 if (load && REGNO (operands[0]) == REGNO (base))
11370 return false; /* RAW. */
11372 if (load && REGNO (operands[0]) == REGNO (operands[1]))
11373 return false; /* WAW. */
11375 /* Make sure the instructions are ordered with lower memory access first. */
11376 if (offsets[0] > offsets[1])
11378 gap = offsets[0] - offsets[1];
11379 offset = offsets[1];
11381 /* Swap the instructions such that lower memory is accessed first. */
11382 std::swap (operands[0], operands[1]);
11383 std::swap (operands[2], operands[3]);
11387 gap = offsets[1] - offsets[0];
11388 offset = offsets[0];
11391 /* Make sure accesses are to consecutive memory locations. */
11395 /* Make sure we generate legal instructions. */
11396 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11399 if (load && commute)
11401 /* Try reordering registers. */
11402 std::swap (operands[0], operands[1]);
11403 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11410 /* This order of allocation is used when we compile for size. It
11411 allocates first the registers which are most probably to end up in
11412 a short instruction. */
11413 static const int size_alloc_order[] =
11415 0, 1, 2, 3, 12, 13, 14, 15,
11416 4, 5, 6, 7, 8, 9, 10, 11
11419 /* Adjust register allocation order when compiling for size. */
11421 arc_adjust_reg_alloc_order (void)
11423 const int arc_default_alloc_order[] = REG_ALLOC_ORDER;
11424 memcpy (reg_alloc_order, arc_default_alloc_order, sizeof (reg_alloc_order));
11426 memcpy (reg_alloc_order, size_alloc_order, sizeof (size_alloc_order));
11429 /* Implement TARGET_MEMORY_MOVE_COST. */
11432 arc_memory_move_cost (machine_mode mode,
11433 reg_class_t rclass ATTRIBUTE_UNUSED,
11434 bool in ATTRIBUTE_UNUSED)
11436 if ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
11437 || ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD * 2) && TARGET_LL64))
11440 return (2 * GET_MODE_SIZE (mode));
11443 /* Split an OR instruction into multiple BSET/OR instructions in a
11444 attempt to avoid long immediate constants. The next strategies are
11445 employed when destination is 'q' reg.
11447 1. if there are up to three bits set in the mask, a succession of
11448 three bset instruction will be emitted:
11450 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
11452 2. if the lower 6 bits of the mask is set and there is only one
11453 bit set in the upper remaining bits then we will emit one bset and
11454 one OR instruction:
11455 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
11457 3. otherwise an OR with limm will be emmitted. */
11460 arc_split_ior (rtx *operands)
11462 unsigned HOST_WIDE_INT mask, maskx;
11463 rtx op1 = operands[1];
11465 gcc_assert (CONST_INT_P (operands[2]));
11466 mask = INTVAL (operands[2]) & 0xffffffff;
11468 if (__builtin_popcount (mask) > 3 || (mask & 0x3f))
11470 maskx = mask & 0x3f;
11471 emit_insn (gen_rtx_SET (operands[0],
11472 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11477 switch (__builtin_popcount (mask))
11480 maskx = 1 << (__builtin_ffs (mask) - 1);
11481 emit_insn (gen_rtx_SET (operands[0],
11482 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11487 maskx = 1 << (__builtin_ffs (mask) - 1);
11488 emit_insn (gen_rtx_SET (operands[0],
11489 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11494 maskx = 1 << (__builtin_ffs (mask) - 1);
11495 emit_insn (gen_rtx_SET (operands[0],
11496 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11503 /* Helper to check C0x constraint. */
11506 arc_check_ior_const (HOST_WIDE_INT ival)
11508 unsigned int mask = (unsigned int) (ival & 0xffffffff);
11509 if (__builtin_popcount (mask) <= 3)
11511 if (__builtin_popcount (mask & ~0x3f) <= 1)
11516 /* Split a mov with long immediate instruction into smaller, size
11517 friendly instructions. */
11520 arc_split_mov_const (rtx *operands)
11522 unsigned HOST_WIDE_INT ival;
11523 HOST_WIDE_INT shimm;
11524 machine_mode mode = GET_MODE (operands[0]);
11526 /* Manage a constant. */
11527 gcc_assert (CONST_INT_P (operands[1]));
11528 ival = INTVAL (operands[1]) & 0xffffffff;
11530 if (SIGNED_INT12 (ival))
11533 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11534 if (TARGET_BARREL_SHIFTER && TARGET_V2
11535 && ((ival & ~0x3f000000) == 0))
11537 shimm = (ival >> 24) & 0x3f;
11538 emit_insn (gen_rtx_SET (operands[0],
11539 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11543 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11544 if (TARGET_BARREL_SHIFTER && TARGET_V2
11545 && ((ival & ~0x3f00) == 0))
11547 shimm = (ival >> 8) & 0x3f;
11548 emit_insn (gen_rtx_SET (operands[0],
11549 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11554 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11555 if (TARGET_BARREL_SHIFTER && TARGET_V2
11556 && ((ival & ~0x3f0000) == 0))
11558 shimm = (ival >> 16) & 0x3f;
11559 emit_insn (gen_rtx_SET (operands[0],
11560 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11565 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11566 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0
11567 && TARGET_BARREL_SHIFTER)
11569 HOST_WIDE_INT shift = __builtin_ffs (ival);
11570 shimm = (ival >> (shift - 1)) & 0xff;
11571 emit_insn (gen_rtx_SET (operands[0], GEN_INT (shimm)));
11572 emit_insn (gen_rtx_SET (operands[0],
11573 gen_rtx_ASHIFT (mode, operands[0],
11574 GEN_INT (shift - 1))));
11578 /* 5. Check if we can just rotate the limm, useful when no barrel
11579 shifter is present. */
11580 if ((ival & ~0x8000001f) == 0)
11582 shimm = (ival * 2 + 1) & 0x3f;
11583 emit_insn (gen_rtx_SET (operands[0],
11584 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11589 /* 6. Check if we can do something with bmask. */
11590 if (IS_POWEROF2_P (ival + 1))
11592 emit_insn (gen_rtx_SET (operands[0], constm1_rtx));
11593 emit_insn (gen_rtx_SET (operands[0],
11594 gen_rtx_AND (mode, operands[0],
11602 /* Helper to check Cax constraint. */
11605 arc_check_mov_const (HOST_WIDE_INT ival)
11607 ival = ival & 0xffffffff;
11609 if ((ival & ~0x8000001f) == 0)
11612 if (IS_POWEROF2_P (ival + 1))
11615 /* The next rules requires a barrel shifter. */
11616 if (!TARGET_BARREL_SHIFTER)
11619 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0)
11622 if ((ival & ~0x3f00) == 0)
11625 if ((ival & ~0x3f0000) == 0)
11628 if ((ival & ~0x3f000000) == 0)
11634 /* Return nonzero if this function is known to have a null epilogue.
11635 This allows the optimizer to omit jumps to jumps if no stack
11639 arc_can_use_return_insn (void)
11641 return (reload_completed && cfun->machine->frame_info.total_size == 0
11642 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
11645 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11646 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11648 #undef TARGET_CONSTANT_ALIGNMENT
11649 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11651 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11652 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11654 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11655 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11657 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11658 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11660 #undef TARGET_REGISTER_MOVE_COST
11661 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11663 #undef TARGET_MEMORY_MOVE_COST
11664 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11666 struct gcc_target targetm = TARGET_INITIALIZER;
11668 #include "gt-arc.h"