1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2016 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
33 #include "coretypes.h"
41 #include "stringpool.h"
46 #include "diagnostic.h"
47 #include "fold-const.h"
49 #include "stor-layout.h"
52 #include "insn-attr.h"
56 #include "langhooks.h"
57 #include "tm-constrs.h"
58 #include "reload.h" /* For operands_match_p */
60 #include "tree-pass.h"
66 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
67 static const char *arc_cpu_string
= "";
69 /* ??? Loads can handle any constant, stores can only handle small ones. */
70 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
71 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
72 (GET_CODE (X) == CONST_INT \
73 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
74 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
76 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
78 #define LEGITIMATE_OFFSET_ADDRESS_P(MODE, X, INDEX, STRICT) \
79 (GET_CODE (X) == PLUS \
80 && RTX_OK_FOR_BASE_P (XEXP (X, 0), (STRICT)) \
81 && ((INDEX && RTX_OK_FOR_INDEX_P (XEXP (X, 1), (STRICT)) \
82 && GET_MODE_SIZE ((MODE)) <= 4) \
83 || RTX_OK_FOR_OFFSET_P (MODE, XEXP (X, 1))))
85 #define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
86 (GET_CODE (X) == PLUS \
87 && GET_CODE (XEXP (X, 0)) == MULT \
88 && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
89 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
90 && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
91 || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
92 && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
93 || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
95 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
96 (GET_CODE (X) == PLUS \
97 && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
98 && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
99 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
100 || (GET_CODE (XEXP ((X), 1)) == CONST \
101 && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
102 && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
103 && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
104 && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
106 /* Array of valid operand punctuation characters. */
107 char arc_punct_chars
[256];
109 /* State used by arc_ccfsm_advance to implement conditional execution. */
110 struct GTY (()) arc_ccfsm
115 rtx_insn
*target_insn
;
119 #define arc_ccfsm_current cfun->machine->ccfsm_current
121 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
122 ((STATE)->state == 1 || (STATE)->state == 2)
124 /* Indicate we're conditionalizing insns now. */
125 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
126 ((STATE)->state += 2)
128 #define ARC_CCFSM_COND_EXEC_P(STATE) \
129 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
130 || current_insn_predicate)
132 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
133 #define CCFSM_ISCOMPACT(INSN,STATE) \
134 (ARC_CCFSM_COND_EXEC_P (STATE) \
135 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
136 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
137 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
139 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
140 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
141 ((ARC_CCFSM_COND_EXEC_P (STATE) \
143 && INSN_ANNULLED_BRANCH_P (JUMP) \
144 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
145 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
146 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
147 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
149 /* The maximum number of insns skipped which will be conditionalised if
151 /* When optimizing for speed:
152 Let p be the probability that the potentially skipped insns need to
153 be executed, pn the cost of a correctly predicted non-taken branch,
154 mt the cost of a mis/non-predicted taken branch,
155 mn mispredicted non-taken, pt correctly predicted taken ;
156 costs expressed in numbers of instructions like the ones considered
158 Unfortunately we don't have a measure of predictability - this
159 is linked to probability only in that in the no-eviction-scenario
160 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
161 value that can be assumed *if* the distribution is perfectly random.
162 A predictability of 1 is perfectly plausible not matter what p is,
163 because the decision could be dependent on an invocation parameter
165 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
166 For small p, we want MAX_INSNS_SKIPPED == pt
168 When optimizing for size:
169 We want to skip insn unless we could use 16 opcodes for the
170 non-conditionalized insn to balance the branch length or more.
171 Performance can be tie-breaker. */
172 /* If the potentially-skipped insns are likely to be executed, we'll
173 generally save one non-taken branch
175 this to be no less than the 1/p */
176 #define MAX_INSNS_SKIPPED 3
178 /* A nop is needed between a 4 byte insn that sets the condition codes and
179 a branch that uses them (the same isn't true for an 8 byte insn that sets
180 the condition codes). Set by arc_ccfsm_advance. Used by
181 arc_print_operand. */
183 static int get_arc_condition_code (rtx
);
185 static tree
arc_handle_interrupt_attribute (tree
*, tree
, tree
, int, bool *);
187 /* Initialized arc_attribute_table to NULL since arc doesnot have any
188 machine specific supported attributes. */
189 const struct attribute_spec arc_attribute_table
[] =
191 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
192 affects_type_identity } */
193 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute
, true },
194 /* Function calls made to this symbol must be done indirectly, because
195 it may lie outside of the 21/25 bit addressing range of a normal function
197 { "long_call", 0, 0, false, true, true, NULL
, false },
198 /* Whereas these functions are always known to reside within the 25 bit
199 addressing range of unconditionalized bl. */
200 { "medium_call", 0, 0, false, true, true, NULL
, false },
201 /* And these functions are always known to reside within the 21 bit
202 addressing range of blcc. */
203 { "short_call", 0, 0, false, true, true, NULL
, false },
204 { NULL
, 0, 0, false, false, false, NULL
, false }
206 static int arc_comp_type_attributes (const_tree
, const_tree
);
207 static void arc_file_start (void);
208 static void arc_internal_label (FILE *, const char *, unsigned long);
209 static void arc_output_mi_thunk (FILE *, tree
, HOST_WIDE_INT
, HOST_WIDE_INT
,
211 static int arc_address_cost (rtx
, machine_mode
, addr_space_t
, bool);
212 static void arc_encode_section_info (tree decl
, rtx rtl
, int first
);
214 static void arc_init_builtins (void);
215 static rtx
arc_expand_builtin (tree
, rtx
, rtx
, machine_mode
, int);
217 static int branch_dest (rtx
);
219 static void arc_output_pic_addr_const (FILE *, rtx
, int);
220 bool arc_legitimate_pic_operand_p (rtx
);
221 static bool arc_function_ok_for_sibcall (tree
, tree
);
222 static rtx
arc_function_value (const_tree
, const_tree
, bool);
223 const char * output_shift (rtx
*);
224 static void arc_reorg (void);
225 static bool arc_in_small_data_p (const_tree
);
227 static void arc_init_reg_tables (void);
228 static bool arc_return_in_memory (const_tree
, const_tree
);
229 static bool arc_vector_mode_supported_p (machine_mode
);
231 static bool arc_can_use_doloop_p (const widest_int
&, const widest_int
&,
233 static const char *arc_invalid_within_doloop (const rtx_insn
*);
235 static void output_short_suffix (FILE *file
);
237 static bool arc_frame_pointer_required (void);
239 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT
,
241 enum by_pieces_operation op
,
244 /* Implements target hook vector_mode_supported_p. */
247 arc_vector_mode_supported_p (machine_mode mode
)
252 return TARGET_PLUS_DMPY
;
255 return TARGET_PLUS_QMACW
;
258 return TARGET_SIMD_SET
;
265 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
268 arc_preferred_simd_mode (machine_mode mode
)
273 return TARGET_PLUS_QMACW
? V4HImode
: V2HImode
;
282 /* Implements target hook
283 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
286 arc_autovectorize_vector_sizes (void)
288 return TARGET_PLUS_QMACW
? (8 | 4) : 0;
291 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
292 static bool arc_preserve_reload_p (rtx in
) ATTRIBUTE_UNUSED
;
293 static rtx
arc_delegitimize_address (rtx
);
294 static bool arc_can_follow_jump (const rtx_insn
*follower
,
295 const rtx_insn
*followee
);
297 static rtx
frame_insn (rtx
);
298 static void arc_function_arg_advance (cumulative_args_t
, machine_mode
,
300 static rtx
arc_legitimize_address_0 (rtx
, rtx
, machine_mode mode
);
302 static void arc_finalize_pic (void);
304 /* initialize the GCC target structure. */
305 #undef TARGET_COMP_TYPE_ATTRIBUTES
306 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
307 #undef TARGET_ASM_FILE_START
308 #define TARGET_ASM_FILE_START arc_file_start
309 #undef TARGET_ATTRIBUTE_TABLE
310 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
311 #undef TARGET_ASM_INTERNAL_LABEL
312 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
313 #undef TARGET_RTX_COSTS
314 #define TARGET_RTX_COSTS arc_rtx_costs
315 #undef TARGET_ADDRESS_COST
316 #define TARGET_ADDRESS_COST arc_address_cost
318 #undef TARGET_ENCODE_SECTION_INFO
319 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
321 #undef TARGET_CANNOT_FORCE_CONST_MEM
322 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
324 #undef TARGET_INIT_BUILTINS
325 #define TARGET_INIT_BUILTINS arc_init_builtins
327 #undef TARGET_EXPAND_BUILTIN
328 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
330 #undef TARGET_BUILTIN_DECL
331 #define TARGET_BUILTIN_DECL arc_builtin_decl
333 #undef TARGET_ASM_OUTPUT_MI_THUNK
334 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
336 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
337 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
339 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
340 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
342 #undef TARGET_MACHINE_DEPENDENT_REORG
343 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
345 #undef TARGET_IN_SMALL_DATA_P
346 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
348 #undef TARGET_PROMOTE_FUNCTION_MODE
349 #define TARGET_PROMOTE_FUNCTION_MODE \
350 default_promote_function_mode_always_promote
352 #undef TARGET_PROMOTE_PROTOTYPES
353 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
355 #undef TARGET_RETURN_IN_MEMORY
356 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
357 #undef TARGET_PASS_BY_REFERENCE
358 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
360 #undef TARGET_SETUP_INCOMING_VARARGS
361 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
363 #undef TARGET_ARG_PARTIAL_BYTES
364 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
366 #undef TARGET_MUST_PASS_IN_STACK
367 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
369 #undef TARGET_FUNCTION_VALUE
370 #define TARGET_FUNCTION_VALUE arc_function_value
372 #undef TARGET_SCHED_ADJUST_PRIORITY
373 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
375 #undef TARGET_VECTOR_MODE_SUPPORTED_P
376 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
378 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
379 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
381 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
382 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
384 #undef TARGET_CAN_USE_DOLOOP_P
385 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
387 #undef TARGET_INVALID_WITHIN_DOLOOP
388 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
390 #undef TARGET_PRESERVE_RELOAD_P
391 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
393 #undef TARGET_CAN_FOLLOW_JUMP
394 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
396 #undef TARGET_DELEGITIMIZE_ADDRESS
397 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
399 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
400 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
401 arc_use_by_pieces_infrastructure_p
403 /* Usually, we will be able to scale anchor offsets.
404 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
405 #undef TARGET_MIN_ANCHOR_OFFSET
406 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
407 #undef TARGET_MAX_ANCHOR_OFFSET
408 #define TARGET_MAX_ANCHOR_OFFSET (1020)
410 #undef TARGET_SECONDARY_RELOAD
411 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
413 #define TARGET_OPTION_OVERRIDE arc_override_options
415 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
417 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
419 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
421 #define TARGET_CAN_ELIMINATE arc_can_eliminate
423 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
425 #define TARGET_FUNCTION_ARG arc_function_arg
427 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
429 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
431 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
433 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
435 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
437 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
439 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
441 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
442 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
443 arc_no_speculation_in_delay_slots_p
446 #define TARGET_LRA_P arc_lra_p
447 #define TARGET_REGISTER_PRIORITY arc_register_priority
448 /* Stores with scaled offsets have different displacement ranges. */
449 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
450 #define TARGET_SPILL_CLASS arc_spill_class
452 #include "target-def.h"
454 #undef TARGET_ASM_ALIGNED_HI_OP
455 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
456 #undef TARGET_ASM_ALIGNED_SI_OP
457 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
460 #undef TARGET_HAVE_TLS
461 #define TARGET_HAVE_TLS HAVE_AS_TLS
464 #undef TARGET_DWARF_REGISTER_SPAN
465 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
467 /* Try to keep the (mov:DF _, reg) as early as possible so
468 that the d<add/sub/mul>h-lr insns appear together and can
469 use the peephole2 pattern. */
472 arc_sched_adjust_priority (rtx_insn
*insn
, int priority
)
474 rtx set
= single_set (insn
);
476 && GET_MODE (SET_SRC(set
)) == DFmode
477 && GET_CODE (SET_SRC(set
)) == REG
)
479 /* Incrementing priority by 20 (empirically derived). */
480 return priority
+ 20;
486 /* For ARC base register + offset addressing, the validity of the
487 address is mode-dependent for most of the offset range, as the
488 offset can be scaled by the access size.
489 We don't expose these as mode-dependent addresses in the
490 mode_dependent_address_p target hook, because that would disable
491 lots of optimizations, and most uses of these addresses are for 32
492 or 64 bit accesses anyways, which are fine.
493 However, that leaves some addresses for 8 / 16 bit values not
494 properly reloaded by the generic code, which is why we have to
495 schedule secondary reloads for these. */
498 arc_secondary_reload (bool in_p
,
502 secondary_reload_info
*sri
)
504 enum rtx_code code
= GET_CODE (x
);
506 if (cl
== DOUBLE_REGS
)
509 /* The loop counter register can be stored, but not loaded directly. */
510 if ((cl
== LPCOUNT_REG
|| cl
== WRITABLE_CORE_REGS
)
511 && in_p
&& MEM_P (x
))
514 /* If we have a subreg (reg), where reg is a pseudo (that will end in
515 a memory location), then we may need a scratch register to handle
516 the fp/sp+largeoffset address. */
524 int regno
= REGNO (x
);
525 if (regno
>= FIRST_PSEUDO_REGISTER
)
526 regno
= reg_renumber
[regno
];
531 /* It is a pseudo that ends in a stack location. */
532 if (reg_equiv_mem (REGNO (x
)))
534 /* Get the equivalent address and check the range of the
536 rtx mem
= reg_equiv_mem (REGNO (x
));
537 addr
= find_replacement (&XEXP (mem
, 0));
542 gcc_assert (MEM_P (x
));
544 addr
= simplify_rtx (addr
);
546 if (addr
&& GET_CODE (addr
) == PLUS
547 && CONST_INT_P (XEXP (addr
, 1))
548 && (!RTX_OK_FOR_OFFSET_P (mode
, XEXP (addr
, 1))))
554 in_p
? CODE_FOR_reload_qi_load
: CODE_FOR_reload_qi_store
;
558 in_p
? CODE_FOR_reload_hi_load
: CODE_FOR_reload_hi_store
;
568 /* Convert reloads using offsets that are too large to use indirect
572 arc_secondary_reload_conv (rtx reg
, rtx mem
, rtx scratch
, bool store_p
)
576 gcc_assert (GET_CODE (mem
) == MEM
);
577 addr
= XEXP (mem
, 0);
579 /* Large offset: use a move. FIXME: ld ops accepts limms as
580 offsets. Hence, the following move insn is not required. */
581 emit_move_insn (scratch
, addr
);
582 mem
= replace_equiv_address_nv (mem
, scratch
);
584 /* Now create the move. */
586 emit_insn (gen_rtx_SET (mem
, reg
));
588 emit_insn (gen_rtx_SET (reg
, mem
));
593 static unsigned arc_ifcvt (void);
597 const pass_data pass_data_arc_ifcvt
=
600 "arc_ifcvt", /* name */
601 OPTGROUP_NONE
, /* optinfo_flags */
602 TV_IFCVT2
, /* tv_id */
603 0, /* properties_required */
604 0, /* properties_provided */
605 0, /* properties_destroyed */
606 0, /* todo_flags_start */
607 TODO_df_finish
/* todo_flags_finish */
610 class pass_arc_ifcvt
: public rtl_opt_pass
613 pass_arc_ifcvt(gcc::context
*ctxt
)
614 : rtl_opt_pass(pass_data_arc_ifcvt
, ctxt
)
617 /* opt_pass methods: */
618 opt_pass
* clone () { return new pass_arc_ifcvt (m_ctxt
); }
619 virtual unsigned int execute (function
*) { return arc_ifcvt (); }
625 make_pass_arc_ifcvt (gcc::context
*ctxt
)
627 return new pass_arc_ifcvt (ctxt
);
630 static unsigned arc_predicate_delay_insns (void);
634 const pass_data pass_data_arc_predicate_delay_insns
=
637 "arc_predicate_delay_insns", /* name */
638 OPTGROUP_NONE
, /* optinfo_flags */
639 TV_IFCVT2
, /* tv_id */
640 0, /* properties_required */
641 0, /* properties_provided */
642 0, /* properties_destroyed */
643 0, /* todo_flags_start */
644 TODO_df_finish
/* todo_flags_finish */
647 class pass_arc_predicate_delay_insns
: public rtl_opt_pass
650 pass_arc_predicate_delay_insns(gcc::context
*ctxt
)
651 : rtl_opt_pass(pass_data_arc_predicate_delay_insns
, ctxt
)
654 /* opt_pass methods: */
655 virtual unsigned int execute (function
*)
657 return arc_predicate_delay_insns ();
664 make_pass_arc_predicate_delay_insns (gcc::context
*ctxt
)
666 return new pass_arc_predicate_delay_insns (ctxt
);
669 /* Called by OVERRIDE_OPTIONS to initialize various things. */
674 enum attr_tune tune_dflt
= TUNE_NONE
;
678 case PROCESSOR_ARC600
:
679 arc_cpu_string
= "ARC600";
680 tune_dflt
= TUNE_ARC600
;
683 case PROCESSOR_ARC601
:
684 arc_cpu_string
= "ARC601";
685 tune_dflt
= TUNE_ARC600
;
688 case PROCESSOR_ARC700
:
689 arc_cpu_string
= "ARC700";
690 tune_dflt
= TUNE_ARC700_4_2_STD
;
693 case PROCESSOR_NPS400
:
694 arc_cpu_string
= "NPS400";
695 tune_dflt
= TUNE_ARC700_4_2_STD
;
698 case PROCESSOR_ARCEM
:
699 arc_cpu_string
= "EM";
702 case PROCESSOR_ARCHS
:
703 arc_cpu_string
= "HS";
710 if (arc_tune
== TUNE_NONE
)
711 arc_tune
= tune_dflt
;
712 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
713 if (arc_multcost
< 0)
716 case TUNE_ARC700_4_2_STD
:
718 max throughput (1 multiply + 4 other insns) / 5 cycles. */
719 arc_multcost
= COSTS_N_INSNS (4);
720 if (TARGET_NOMPY_SET
)
721 arc_multcost
= COSTS_N_INSNS (30);
723 case TUNE_ARC700_4_2_XMAC
:
725 max throughput (1 multiply + 2 other insns) / 3 cycles. */
726 arc_multcost
= COSTS_N_INSNS (3);
727 if (TARGET_NOMPY_SET
)
728 arc_multcost
= COSTS_N_INSNS (30);
731 if (TARGET_MUL64_SET
)
733 arc_multcost
= COSTS_N_INSNS (4);
738 arc_multcost
= COSTS_N_INSNS (30);
742 /* Support mul64 generation only for ARC600. */
743 if (TARGET_MUL64_SET
&& (!TARGET_ARC600_FAMILY
))
744 error ("-mmul64 not supported for ARC700 or ARCv2");
746 /* MPY instructions valid only for ARC700 or ARCv2. */
747 if (TARGET_NOMPY_SET
&& TARGET_ARC600_FAMILY
)
748 error ("-mno-mpy supported only for ARC700 or ARCv2");
750 /* mul/mac instructions only for ARC600. */
751 if (TARGET_MULMAC_32BY16_SET
&& (!TARGET_ARC600_FAMILY
))
752 error ("-mmul32x16 supported only for ARC600 or ARC601");
754 if (!TARGET_DPFP
&& TARGET_DPFP_DISABLE_LRSR
)
755 error ("-mno-dpfp-lrsr supported only with -mdpfp");
757 /* FPX-1. No fast and compact together. */
758 if ((TARGET_DPFP_FAST_SET
&& TARGET_DPFP_COMPACT_SET
)
759 || (TARGET_SPFP_FAST_SET
&& TARGET_SPFP_COMPACT_SET
))
760 error ("FPX fast and compact options cannot be specified together");
762 /* FPX-2. No fast-spfp for arc600 or arc601. */
763 if (TARGET_SPFP_FAST_SET
&& TARGET_ARC600_FAMILY
)
764 error ("-mspfp_fast not available on ARC600 or ARC601");
766 /* FPX-3. No FPX extensions on pre-ARC600 cores. */
767 if ((TARGET_DPFP
|| TARGET_SPFP
)
768 && (!TARGET_ARCOMPACT_FAMILY
&& !TARGET_EM
))
769 error ("FPX extensions not available on pre-ARC600 cores");
771 /* FPX-4. No FPX extensions mixed with FPU extensions for ARC HS
773 if ((TARGET_DPFP
|| TARGET_SPFP
)
776 error ("No FPX/FPU mixing allowed");
778 /* Only selected multiplier configurations are available for HS. */
779 if (TARGET_HS
&& ((arc_mpy_option
> 2 && arc_mpy_option
< 7)
780 || (arc_mpy_option
== 1)))
781 error ("This multiplier configuration is not available for HS cores");
783 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
784 if (flag_pic
&& TARGET_ARC600_FAMILY
)
787 "PIC is not supported for %s. Generating non-PIC code only..",
792 if (TARGET_ATOMIC
&& !(TARGET_ARC700
|| TARGET_HS
))
793 error ("-matomic is only supported for ARC700 or ARC HS cores");
795 /* ll64 ops only available for HS. */
796 if (TARGET_LL64
&& !TARGET_HS
)
797 error ("-mll64 is only supported for ARC HS cores");
799 /* FPU support only for V2. */
800 if (TARGET_HARD_FLOAT
)
803 && (arc_fpu_build
& ~(FPU_SP
| FPU_SF
| FPU_SC
| FPU_SD
| FPX_DP
)))
804 error ("FPU double precision options are available for ARC HS only");
805 if (TARGET_HS
&& (arc_fpu_build
& FPX_DP
))
806 error ("FPU double precision assist "
807 "options are not available for ARC HS");
808 if (!TARGET_HS
&& !TARGET_EM
)
809 error ("FPU options are available for ARCv2 architecture only");
812 arc_init_reg_tables ();
814 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
815 memset (arc_punct_chars
, 0, sizeof (arc_punct_chars
));
816 arc_punct_chars
['#'] = 1;
817 arc_punct_chars
['*'] = 1;
818 arc_punct_chars
['?'] = 1;
819 arc_punct_chars
['!'] = 1;
820 arc_punct_chars
['^'] = 1;
821 arc_punct_chars
['&'] = 1;
822 arc_punct_chars
['+'] = 1;
823 arc_punct_chars
['_'] = 1;
825 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
827 /* There are two target-independent ifcvt passes, and arc_reorg may do
828 one or more arc_ifcvt calls. */
829 opt_pass
*pass_arc_ifcvt_4
= make_pass_arc_ifcvt (g
);
830 struct register_pass_info arc_ifcvt4_info
831 = { pass_arc_ifcvt_4
, "dbr", 1, PASS_POS_INSERT_AFTER
};
832 struct register_pass_info arc_ifcvt5_info
833 = { pass_arc_ifcvt_4
->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE
};
835 register_pass (&arc_ifcvt4_info
);
836 register_pass (&arc_ifcvt5_info
);
839 if (flag_delayed_branch
)
841 opt_pass
*pass_arc_predicate_delay_insns
842 = make_pass_arc_predicate_delay_insns (g
);
843 struct register_pass_info arc_predicate_delay_info
844 = { pass_arc_predicate_delay_insns
, "dbr", 1, PASS_POS_INSERT_AFTER
};
846 register_pass (&arc_predicate_delay_info
);
850 /* Check ARC options, generate derived target attributes. */
853 arc_override_options (void)
855 if (arc_cpu
== PROCESSOR_NONE
)
856 arc_cpu
= PROCESSOR_ARC700
;
858 if (arc_size_opt_level
== 3)
862 target_flags
|= MASK_NO_SDATA_SET
;
864 if (flag_no_common
== 255)
865 flag_no_common
= !TARGET_NO_SDATA_SET
;
867 /* TARGET_COMPACT_CASESI needs the "q" register class. */
868 if (TARGET_MIXED_CODE
)
871 TARGET_COMPACT_CASESI
= 0;
872 if (TARGET_COMPACT_CASESI
)
873 TARGET_CASE_VECTOR_PC_RELATIVE
= 1;
875 /* These need to be done at start up. It's convenient to do them here. */
879 /* The condition codes of the ARC, and the inverse function. */
880 /* For short branches, the "c" / "nc" names are not defined in the ARC
881 Programmers manual, so we have to use "lo" / "hs"" instead. */
882 static const char *arc_condition_codes
[] =
884 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
885 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
888 enum arc_cc_code_index
890 ARC_CC_AL
, ARC_CC_EQ
= ARC_CC_AL
+2, ARC_CC_NE
, ARC_CC_P
, ARC_CC_N
,
891 ARC_CC_C
, ARC_CC_NC
, ARC_CC_V
, ARC_CC_NV
,
892 ARC_CC_GT
, ARC_CC_LE
, ARC_CC_GE
, ARC_CC_LT
, ARC_CC_HI
, ARC_CC_LS
, ARC_CC_PNZ
,
893 ARC_CC_LO
= ARC_CC_C
, ARC_CC_HS
= ARC_CC_NC
896 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
898 /* Returns the index of the ARC condition code string in
899 `arc_condition_codes'. COMPARISON should be an rtx like
900 `(eq (...) (...))'. */
903 get_arc_condition_code (rtx comparison
)
905 switch (GET_MODE (XEXP (comparison
, 0)))
908 case SImode
: /* For BRcc. */
909 switch (GET_CODE (comparison
))
911 case EQ
: return ARC_CC_EQ
;
912 case NE
: return ARC_CC_NE
;
913 case GT
: return ARC_CC_GT
;
914 case LE
: return ARC_CC_LE
;
915 case GE
: return ARC_CC_GE
;
916 case LT
: return ARC_CC_LT
;
917 case GTU
: return ARC_CC_HI
;
918 case LEU
: return ARC_CC_LS
;
919 case LTU
: return ARC_CC_LO
;
920 case GEU
: return ARC_CC_HS
;
921 default : gcc_unreachable ();
924 switch (GET_CODE (comparison
))
926 case EQ
: return ARC_CC_EQ
;
927 case NE
: return ARC_CC_NE
;
928 case GE
: return ARC_CC_P
;
929 case LT
: return ARC_CC_N
;
930 case GT
: return ARC_CC_PNZ
;
931 default : gcc_unreachable ();
934 switch (GET_CODE (comparison
))
936 case EQ
: return ARC_CC_EQ
;
937 case NE
: return ARC_CC_NE
;
938 default : gcc_unreachable ();
941 switch (GET_CODE (comparison
))
943 case LTU
: return ARC_CC_C
;
944 case GEU
: return ARC_CC_NC
;
945 default : gcc_unreachable ();
948 if (TARGET_ARGONAUT_SET
&& TARGET_SPFP
)
949 switch (GET_CODE (comparison
))
951 case GT
: return ARC_CC_N
;
952 case UNLE
: return ARC_CC_P
;
953 default : gcc_unreachable ();
956 switch (GET_CODE (comparison
))
958 case GT
: return ARC_CC_HI
;
959 case UNLE
: return ARC_CC_LS
;
960 default : gcc_unreachable ();
963 /* Same for FPX and non-FPX. */
964 switch (GET_CODE (comparison
))
966 case GE
: return ARC_CC_HS
;
967 case UNLT
: return ARC_CC_LO
;
968 default : gcc_unreachable ();
971 switch (GET_CODE (comparison
))
973 case UNEQ
: return ARC_CC_EQ
;
974 case LTGT
: return ARC_CC_NE
;
975 default : gcc_unreachable ();
978 switch (GET_CODE (comparison
))
980 case UNORDERED
: return ARC_CC_C
;
981 case ORDERED
: return ARC_CC_NC
;
982 default : gcc_unreachable ();
985 switch (GET_CODE (comparison
))
987 case EQ
: return ARC_CC_EQ
;
988 case NE
: return ARC_CC_NE
;
989 case UNORDERED
: return ARC_CC_C
;
990 case ORDERED
: return ARC_CC_NC
;
991 case LTGT
: return ARC_CC_HI
;
992 case UNEQ
: return ARC_CC_LS
;
993 default : gcc_unreachable ();
996 switch (GET_CODE (comparison
))
998 case EQ
: return ARC_CC_EQ
;
999 case NE
: return ARC_CC_NE
;
1000 case GT
: return ARC_CC_GT
;
1001 case GE
: return ARC_CC_GE
;
1002 case LT
: return ARC_CC_C
;
1003 case LE
: return ARC_CC_LS
;
1004 case UNORDERED
: return ARC_CC_V
;
1005 case ORDERED
: return ARC_CC_NV
;
1006 case UNGT
: return ARC_CC_HI
;
1007 case UNGE
: return ARC_CC_HS
;
1008 case UNLT
: return ARC_CC_LT
;
1009 case UNLE
: return ARC_CC_LE
;
1010 /* UNEQ and LTGT do not have representation. */
1011 case LTGT
: /* Fall through. */
1012 case UNEQ
: /* Fall through. */
1013 default : gcc_unreachable ();
1015 case CC_FPU_UNEQmode
:
1016 switch (GET_CODE (comparison
))
1018 case LTGT
: return ARC_CC_NE
;
1019 case UNEQ
: return ARC_CC_EQ
;
1020 default : gcc_unreachable ();
1022 default : gcc_unreachable ();
1028 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1031 arc_short_comparison_p (rtx comparison
, int offset
)
1033 gcc_assert (ARC_CC_NC
== ARC_CC_HS
);
1034 gcc_assert (ARC_CC_C
== ARC_CC_LO
);
1035 switch (get_arc_condition_code (comparison
))
1037 case ARC_CC_EQ
: case ARC_CC_NE
:
1038 return offset
>= -512 && offset
<= 506;
1039 case ARC_CC_GT
: case ARC_CC_LE
: case ARC_CC_GE
: case ARC_CC_LT
:
1040 case ARC_CC_HI
: case ARC_CC_LS
: case ARC_CC_LO
: case ARC_CC_HS
:
1041 return offset
>= -64 && offset
<= 58;
1047 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1048 return the mode to be used for the comparison. */
1051 arc_select_cc_mode (enum rtx_code op
, rtx x
, rtx y
)
1053 machine_mode mode
= GET_MODE (x
);
1056 /* For an operation that sets the condition codes as a side-effect, the
1057 C and V flags is not set as for cmp, so we can only use comparisons where
1058 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1060 /* ??? We could use "pnz" for greater than zero, however, we could then
1061 get into trouble because the comparison could not be reversed. */
1062 if (GET_MODE_CLASS (mode
) == MODE_INT
1064 && (op
== EQ
|| op
== NE
1065 || ((op
== LT
|| op
== GE
) && GET_MODE_SIZE (GET_MODE (x
)) <= 4)))
1068 /* add.f for if (a+b) */
1070 && GET_CODE (y
) == NEG
1071 && (op
== EQ
|| op
== NE
))
1074 /* Check if this is a test suitable for bxor.f . */
1075 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1076 && ((INTVAL (y
) - 1) & INTVAL (y
)) == 0
1080 /* Check if this is a test suitable for add / bmsk.f . */
1081 if (mode
== SImode
&& (op
== EQ
|| op
== NE
) && CONST_INT_P (y
)
1082 && GET_CODE (x
) == AND
&& CONST_INT_P ((x1
= XEXP (x
, 1)))
1083 && ((INTVAL (x1
) + 1) & INTVAL (x1
)) == 0
1084 && (~INTVAL (x1
) | INTVAL (y
)) < 0
1085 && (~INTVAL (x1
) | INTVAL (y
)) > -0x800)
1088 if (GET_MODE (x
) == SImode
&& (op
== LTU
|| op
== GEU
)
1089 && GET_CODE (x
) == PLUS
1090 && (rtx_equal_p (XEXP (x
, 0), y
) || rtx_equal_p (XEXP (x
, 1), y
)))
1093 if (TARGET_ARGONAUT_SET
1094 && ((mode
== SFmode
&& TARGET_SPFP
) || (mode
== DFmode
&& TARGET_DPFP
)))
1097 case EQ
: case NE
: case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1099 case LT
: case UNGE
: case GT
: case UNLE
:
1100 return CC_FP_GTmode
;
1101 case LE
: case UNGT
: case GE
: case UNLT
:
1102 return CC_FP_GEmode
;
1103 default: gcc_unreachable ();
1105 else if (TARGET_HARD_FLOAT
1106 && ((mode
== SFmode
&& TARGET_FP_SP_BASE
)
1107 || (mode
== DFmode
&& TARGET_FP_DP_BASE
)))
1126 return CC_FPU_UNEQmode
;
1131 else if (GET_MODE_CLASS (mode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1135 case EQ
: case NE
: return CC_Zmode
;
1137 case GT
: case UNLE
: return CC_FP_GTmode
;
1139 case GE
: case UNLT
: return CC_FP_GEmode
;
1140 case UNEQ
: case LTGT
: return CC_FP_UNEQmode
;
1141 case ORDERED
: case UNORDERED
: return CC_FP_ORDmode
;
1142 default: gcc_unreachable ();
1148 /* Vectors to keep interesting information about registers where it can easily
1149 be got. We use to use the actual mode value as the bit number, but there
1150 is (or may be) more than 32 modes now. Instead we use two tables: one
1151 indexed by hard register number, and one indexed by mode. */
1153 /* The purpose of arc_mode_class is to shrink the range of modes so that
1154 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1155 mapped into one arc_mode_class mode. */
1157 enum arc_mode_class
{
1159 S_MODE
, D_MODE
, T_MODE
, O_MODE
,
1160 SF_MODE
, DF_MODE
, TF_MODE
, OF_MODE
,
1164 /* Modes for condition codes. */
1165 #define C_MODES (1 << (int) C_MODE)
1167 /* Modes for single-word and smaller quantities. */
1168 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1170 /* Modes for double-word and smaller quantities. */
1171 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1173 /* Mode for 8-byte DF values only. */
1174 #define DF_MODES (1 << DF_MODE)
1176 /* Modes for quad-word and smaller quantities. */
1177 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1179 /* Modes for 128-bit vectors. */
1180 #define V_MODES (1 << (int) V_MODE)
1182 /* Value is 1 if register/mode pair is acceptable on arc. */
1184 unsigned int arc_hard_regno_mode_ok
[] = {
1185 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1186 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
,
1187 T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, T_MODES
, D_MODES
,
1188 D_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1190 /* ??? Leave these as S_MODES for now. */
1191 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1192 DF_MODES
, 0, DF_MODES
, 0, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1193 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1194 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, C_MODES
, S_MODES
,
1196 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1197 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1198 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1199 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1201 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1202 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1203 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1204 V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
, V_MODES
,
1206 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
,
1207 S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
, S_MODES
1210 unsigned int arc_mode_class
[NUM_MACHINE_MODES
];
1212 enum reg_class arc_regno_reg_class
[FIRST_PSEUDO_REGISTER
];
1215 arc_preferred_reload_class (rtx
, enum reg_class cl
)
1217 if ((cl
) == CHEAP_CORE_REGS
|| (cl
) == WRITABLE_CORE_REGS
)
1218 return GENERAL_REGS
;
1222 /* Initialize the arc_mode_class array. */
1225 arc_init_reg_tables (void)
1229 for (i
= 0; i
< NUM_MACHINE_MODES
; i
++)
1231 machine_mode m
= (machine_mode
) i
;
1233 switch (GET_MODE_CLASS (m
))
1236 case MODE_PARTIAL_INT
:
1237 case MODE_COMPLEX_INT
:
1238 if (GET_MODE_SIZE (m
) <= 4)
1239 arc_mode_class
[i
] = 1 << (int) S_MODE
;
1240 else if (GET_MODE_SIZE (m
) == 8)
1241 arc_mode_class
[i
] = 1 << (int) D_MODE
;
1242 else if (GET_MODE_SIZE (m
) == 16)
1243 arc_mode_class
[i
] = 1 << (int) T_MODE
;
1244 else if (GET_MODE_SIZE (m
) == 32)
1245 arc_mode_class
[i
] = 1 << (int) O_MODE
;
1247 arc_mode_class
[i
] = 0;
1250 case MODE_COMPLEX_FLOAT
:
1251 if (GET_MODE_SIZE (m
) <= 4)
1252 arc_mode_class
[i
] = 1 << (int) SF_MODE
;
1253 else if (GET_MODE_SIZE (m
) == 8)
1254 arc_mode_class
[i
] = 1 << (int) DF_MODE
;
1255 else if (GET_MODE_SIZE (m
) == 16)
1256 arc_mode_class
[i
] = 1 << (int) TF_MODE
;
1257 else if (GET_MODE_SIZE (m
) == 32)
1258 arc_mode_class
[i
] = 1 << (int) OF_MODE
;
1260 arc_mode_class
[i
] = 0;
1262 case MODE_VECTOR_INT
:
1263 if (GET_MODE_SIZE (m
) == 4)
1264 arc_mode_class
[i
] = (1 << (int) S_MODE
);
1265 else if (GET_MODE_SIZE (m
) == 8)
1266 arc_mode_class
[i
] = (1 << (int) D_MODE
);
1268 arc_mode_class
[i
] = (1 << (int) V_MODE
);
1272 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1273 we must explicitly check for them here. */
1274 if (i
== (int) CCmode
|| i
== (int) CC_ZNmode
|| i
== (int) CC_Zmode
1275 || i
== (int) CC_Cmode
1276 || i
== CC_FP_GTmode
|| i
== CC_FP_GEmode
|| i
== CC_FP_ORDmode
1277 || i
== CC_FPUmode
|| i
== CC_FPU_UNEQmode
)
1278 arc_mode_class
[i
] = 1 << (int) C_MODE
;
1280 arc_mode_class
[i
] = 0;
1286 /* Core registers 56..59 are used for multiply extension options.
1287 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1288 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1289 number depends on endianness.
1290 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1291 Because mlo / mhi form a 64 bit value, we use different gcc internal
1292 register numbers to make them form a register pair as the gcc internals
1293 know it. mmid gets number 57, if still available, and mlo / mhi get
1294 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1295 to map this back. */
1296 char rname56
[5] = "r56";
1297 char rname57
[5] = "r57";
1298 char rname58
[5] = "r58";
1299 char rname59
[5] = "r59";
1300 char rname29
[7] = "ilink1";
1301 char rname30
[7] = "ilink2";
1304 arc_conditional_register_usage (void)
1308 int fix_start
= 60, fix_end
= 55;
1312 /* For ARCv2 the core register set is changed. */
1313 strcpy (rname29
, "ilink");
1314 strcpy (rname30
, "r30");
1315 fixed_regs
[30] = call_used_regs
[30] = 1;
1318 if (TARGET_MUL64_SET
)
1323 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1324 you are supposed to refer to it as mlo & mhi, e.g
1325 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1326 In an actual asm instruction, you are of course use mmed.
1327 The point of avoiding having a separate register for mmed is that
1328 this way, we don't have to carry clobbers of that reg around in every
1329 isntruction that modifies mlo and/or mhi. */
1330 strcpy (rname57
, "");
1331 strcpy (rname58
, TARGET_BIG_ENDIAN
? "mhi" : "mlo");
1332 strcpy (rname59
, TARGET_BIG_ENDIAN
? "mlo" : "mhi");
1335 /* The nature of arc_tp_regno is actually something more like a global
1336 register, however globalize_reg requires a declaration.
1337 We use EPILOGUE_USES to compensate so that sets from
1338 __builtin_set_frame_pointer are not deleted. */
1339 if (arc_tp_regno
!= -1)
1340 fixed_regs
[arc_tp_regno
] = call_used_regs
[arc_tp_regno
] = 1;
1342 if (TARGET_MULMAC_32BY16_SET
)
1345 fix_end
= fix_end
> 57 ? fix_end
: 57;
1346 strcpy (rname56
, TARGET_BIG_ENDIAN
? "acc1" : "acc2");
1347 strcpy (rname57
, TARGET_BIG_ENDIAN
? "acc2" : "acc1");
1349 for (regno
= fix_start
; regno
<= fix_end
; regno
++)
1351 if (!fixed_regs
[regno
])
1352 warning (0, "multiply option implies r%d is fixed", regno
);
1353 fixed_regs
[regno
] = call_used_regs
[regno
] = 1;
1357 reg_alloc_order
[2] = 12;
1358 reg_alloc_order
[3] = 13;
1359 reg_alloc_order
[4] = 14;
1360 reg_alloc_order
[5] = 15;
1361 reg_alloc_order
[6] = 1;
1362 reg_alloc_order
[7] = 0;
1363 reg_alloc_order
[8] = 4;
1364 reg_alloc_order
[9] = 5;
1365 reg_alloc_order
[10] = 6;
1366 reg_alloc_order
[11] = 7;
1367 reg_alloc_order
[12] = 8;
1368 reg_alloc_order
[13] = 9;
1369 reg_alloc_order
[14] = 10;
1370 reg_alloc_order
[15] = 11;
1372 if (TARGET_SIMD_SET
)
1375 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1376 reg_alloc_order
[i
] = i
;
1377 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1378 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1379 reg_alloc_order
[i
] = i
;
1381 /* For ARC600, lp_count may not be read in an instruction
1382 following immediately after another one setting it to a new value.
1383 There was some discussion on how to enforce scheduling constraints for
1384 processors with missing interlocks on the gcc mailing list:
1385 http://gcc.gnu.org/ml/gcc/2008-05/msg00021.html .
1386 However, we can't actually use this approach, because for ARC the
1387 delay slot scheduling pass is active, which runs after
1388 machine_dependent_reorg. */
1390 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1391 else if (!TARGET_LP_WR_INTERLOCK
)
1392 fixed_regs
[LP_COUNT
] = 1;
1393 for (regno
= 0; regno
< FIRST_PSEUDO_REGISTER
; regno
++)
1394 if (!call_used_regs
[regno
])
1395 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], regno
);
1396 for (regno
= 32; regno
< 60; regno
++)
1397 if (!fixed_regs
[regno
])
1398 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], regno
);
1399 if (!TARGET_ARC600_FAMILY
)
1401 for (regno
= 32; regno
<= 60; regno
++)
1402 CLEAR_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], regno
);
1404 /* If they have used -ffixed-lp_count, make sure it takes
1406 if (fixed_regs
[LP_COUNT
])
1408 CLEAR_HARD_REG_BIT (reg_class_contents
[LPCOUNT_REG
], LP_COUNT
);
1409 CLEAR_HARD_REG_BIT (reg_class_contents
[SIBCALL_REGS
], LP_COUNT
);
1410 CLEAR_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], LP_COUNT
);
1412 /* Instead of taking out SF_MODE like below, forbid it outright. */
1413 arc_hard_regno_mode_ok
[60] = 0;
1416 arc_hard_regno_mode_ok
[60] = 1 << (int) S_MODE
;
1419 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1423 for (regno
= 1; regno
< 32; regno
+=2)
1425 arc_hard_regno_mode_ok
[regno
] = S_MODES
;
1429 for (i
= 0; i
< FIRST_PSEUDO_REGISTER
; i
++)
1433 if ((TARGET_Q_CLASS
|| TARGET_RRQ_CLASS
)
1434 && ((i
<= 3) || ((i
>= 12) && (i
<= 15))))
1435 arc_regno_reg_class
[i
] = ARCOMPACT16_REGS
;
1437 arc_regno_reg_class
[i
] = GENERAL_REGS
;
1440 arc_regno_reg_class
[i
]
1442 ? (TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
)
1443 ? CHEAP_CORE_REGS
: ALL_CORE_REGS
)
1444 : (((!TARGET_ARC600_FAMILY
)
1445 && TEST_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], i
))
1446 ? CHEAP_CORE_REGS
: WRITABLE_CORE_REGS
));
1448 arc_regno_reg_class
[i
] = NO_REGS
;
1451 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1452 has not been activated. */
1453 if (!TARGET_Q_CLASS
&& !TARGET_RRQ_CLASS
)
1454 CLEAR_HARD_REG_SET(reg_class_contents
[ARCOMPACT16_REGS
]);
1455 if (!TARGET_Q_CLASS
)
1456 CLEAR_HARD_REG_SET(reg_class_contents
[AC16_BASE_REGS
]);
1458 gcc_assert (FIRST_PSEUDO_REGISTER
>= 144);
1460 /* Handle Special Registers. */
1461 arc_regno_reg_class
[29] = LINK_REGS
; /* ilink1 register. */
1463 arc_regno_reg_class
[30] = LINK_REGS
; /* ilink2 register. */
1464 arc_regno_reg_class
[31] = LINK_REGS
; /* blink register. */
1465 arc_regno_reg_class
[60] = LPCOUNT_REG
;
1466 arc_regno_reg_class
[61] = NO_REGS
; /* CC_REG: must be NO_REGS. */
1467 arc_regno_reg_class
[62] = GENERAL_REGS
;
1471 for (i
= 40; i
< 44; ++i
)
1473 arc_regno_reg_class
[i
] = DOUBLE_REGS
;
1475 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1476 no attempt is made to use such a register as a destination
1477 operand in *movdf_insn. */
1478 if (!TARGET_ARGONAUT_SET
)
1480 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1481 interpreted to mean they can use D1 or D2 in their insn. */
1482 CLEAR_HARD_REG_BIT(reg_class_contents
[CHEAP_CORE_REGS
], i
);
1483 CLEAR_HARD_REG_BIT(reg_class_contents
[ALL_CORE_REGS
], i
);
1484 CLEAR_HARD_REG_BIT(reg_class_contents
[WRITABLE_CORE_REGS
], i
);
1485 CLEAR_HARD_REG_BIT(reg_class_contents
[MPY_WRITABLE_CORE_REGS
], i
);
1491 /* Disable all DOUBLE_REGISTER settings,
1492 if not generating DPFP code. */
1493 arc_regno_reg_class
[40] = ALL_REGS
;
1494 arc_regno_reg_class
[41] = ALL_REGS
;
1495 arc_regno_reg_class
[42] = ALL_REGS
;
1496 arc_regno_reg_class
[43] = ALL_REGS
;
1498 arc_hard_regno_mode_ok
[40] = 0;
1499 arc_hard_regno_mode_ok
[42] = 0;
1501 CLEAR_HARD_REG_SET(reg_class_contents
[DOUBLE_REGS
]);
1504 if (TARGET_SIMD_SET
)
1506 gcc_assert (ARC_FIRST_SIMD_VR_REG
== 64);
1507 gcc_assert (ARC_LAST_SIMD_VR_REG
== 127);
1509 for (i
= ARC_FIRST_SIMD_VR_REG
; i
<= ARC_LAST_SIMD_VR_REG
; i
++)
1510 arc_regno_reg_class
[i
] = SIMD_VR_REGS
;
1512 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG
== 128);
1513 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
== 128);
1514 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
== 136);
1515 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG
== 143);
1517 for (i
= ARC_FIRST_SIMD_DMA_CONFIG_REG
;
1518 i
<= ARC_LAST_SIMD_DMA_CONFIG_REG
; i
++)
1519 arc_regno_reg_class
[i
] = SIMD_DMA_CONFIG_REGS
;
1523 arc_regno_reg_class
[PROGRAM_COUNTER_REGNO
] = GENERAL_REGS
;
1525 /*ARCV2 Accumulator. */
1527 && (TARGET_FP_DP_FUSED
|| TARGET_FP_SP_FUSED
))
1529 arc_regno_reg_class
[ACCL_REGNO
] = WRITABLE_CORE_REGS
;
1530 arc_regno_reg_class
[ACCH_REGNO
] = WRITABLE_CORE_REGS
;
1531 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCL_REGNO
);
1532 SET_HARD_REG_BIT (reg_class_contents
[WRITABLE_CORE_REGS
], ACCH_REGNO
);
1533 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCL_REGNO
);
1534 SET_HARD_REG_BIT (reg_class_contents
[CHEAP_CORE_REGS
], ACCH_REGNO
);
1535 arc_hard_regno_mode_ok
[ACC_REG_FIRST
] = D_MODES
;
1539 /* Handle an "interrupt" attribute; arguments as in
1540 struct attribute_spec.handler. */
1543 arc_handle_interrupt_attribute (tree
*, tree name
, tree args
, int,
1548 tree value
= TREE_VALUE (args
);
1550 if (TREE_CODE (value
) != STRING_CST
)
1552 warning (OPT_Wattributes
,
1553 "argument of %qE attribute is not a string constant",
1555 *no_add_attrs
= true;
1557 else if (strcmp (TREE_STRING_POINTER (value
), "ilink1")
1558 && strcmp (TREE_STRING_POINTER (value
), "ilink2")
1561 warning (OPT_Wattributes
,
1562 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1564 *no_add_attrs
= true;
1567 && strcmp (TREE_STRING_POINTER (value
), "ilink"))
1569 warning (OPT_Wattributes
,
1570 "argument of %qE attribute is not \"ilink\"",
1572 *no_add_attrs
= true;
1578 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1579 and two if they are nearly compatible (which causes a warning to be
1583 arc_comp_type_attributes (const_tree type1
,
1586 int l1
, l2
, m1
, m2
, s1
, s2
;
1588 /* Check for mismatch of non-default calling convention. */
1589 if (TREE_CODE (type1
) != FUNCTION_TYPE
)
1592 /* Check for mismatched call attributes. */
1593 l1
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1594 l2
= lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1595 m1
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1596 m2
= lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1597 s1
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1
)) != NULL
;
1598 s2
= lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2
)) != NULL
;
1600 /* Only bother to check if an attribute is defined. */
1601 if (l1
| l2
| m1
| m2
| s1
| s2
)
1603 /* If one type has an attribute, the other must have the same attribute. */
1604 if ((l1
!= l2
) || (m1
!= m2
) || (s1
!= s2
))
1607 /* Disallow mixed attributes. */
1608 if (l1
+ m1
+ s1
> 1)
1616 /* Set the default attributes for TYPE. */
1619 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED
)
1624 /* Misc. utilities. */
1626 /* X and Y are two things to compare using CODE. Emit the compare insn and
1627 return the rtx for the cc reg in the proper mode. */
1630 gen_compare_reg (rtx comparison
, machine_mode omode
)
1632 enum rtx_code code
= GET_CODE (comparison
);
1633 rtx x
= XEXP (comparison
, 0);
1634 rtx y
= XEXP (comparison
, 1);
1636 machine_mode mode
, cmode
;
1639 cmode
= GET_MODE (x
);
1640 if (cmode
== VOIDmode
)
1641 cmode
= GET_MODE (y
);
1642 gcc_assert (cmode
== SImode
|| cmode
== SFmode
|| cmode
== DFmode
);
1643 if (cmode
== SImode
)
1645 if (!register_operand (x
, SImode
))
1647 if (register_operand (y
, SImode
))
1652 code
= swap_condition (code
);
1655 x
= copy_to_mode_reg (SImode
, x
);
1657 if (GET_CODE (y
) == SYMBOL_REF
&& flag_pic
)
1658 y
= copy_to_mode_reg (SImode
, y
);
1662 x
= force_reg (cmode
, x
);
1663 y
= force_reg (cmode
, y
);
1665 mode
= SELECT_CC_MODE (code
, x
, y
);
1667 cc_reg
= gen_rtx_REG (mode
, CC_REG
);
1669 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
1670 cmpdfpx_raw, is not a correct comparison for floats:
1671 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1673 if (TARGET_ARGONAUT_SET
1674 && ((cmode
== SFmode
&& TARGET_SPFP
) || (cmode
== DFmode
&& TARGET_DPFP
)))
1678 case NE
: case EQ
: case LT
: case UNGE
: case LE
: case UNGT
:
1679 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1681 case GT
: case UNLE
: case GE
: case UNLT
:
1682 code
= swap_condition (code
);
1690 if (cmode
== SFmode
)
1692 emit_insn (gen_cmpsfpx_raw (x
, y
));
1696 /* Accepts Dx regs directly by insns. */
1697 emit_insn (gen_cmpdfpx_raw (x
, y
));
1700 if (mode
!= CC_FPXmode
)
1701 emit_insn (gen_rtx_SET (cc_reg
,
1702 gen_rtx_COMPARE (mode
,
1703 gen_rtx_REG (CC_FPXmode
, 61),
1706 else if (TARGET_HARD_FLOAT
1707 && ((cmode
== SFmode
&& TARGET_FP_SP_BASE
)
1708 || (cmode
== DFmode
&& TARGET_FP_DP_BASE
)))
1709 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
1710 else if (GET_MODE_CLASS (cmode
) == MODE_FLOAT
&& TARGET_OPTFPE
)
1712 rtx op0
= gen_rtx_REG (cmode
, 0);
1713 rtx op1
= gen_rtx_REG (cmode
, GET_MODE_SIZE (cmode
) / UNITS_PER_WORD
);
1718 case NE
: case EQ
: case GT
: case UNLE
: case GE
: case UNLT
:
1719 case UNEQ
: case LTGT
: case ORDERED
: case UNORDERED
:
1721 case LT
: case UNGE
: case LE
: case UNGT
:
1722 code
= swap_condition (code
);
1728 if (currently_expanding_to_rtl
)
1736 emit_move_insn (op0
, x
);
1737 emit_move_insn (op1
, y
);
1741 gcc_assert (rtx_equal_p (op0
, x
));
1742 gcc_assert (rtx_equal_p (op1
, y
));
1749 emit_insn (gen_cmp_float (cc_reg
, gen_rtx_COMPARE (mode
, op0
, op1
)));
1752 emit_insn (gen_rtx_SET (cc_reg
, gen_rtx_COMPARE (mode
, x
, y
)));
1753 return gen_rtx_fmt_ee (code
, omode
, cc_reg
, const0_rtx
);
1756 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
1757 We assume the value can be either signed or unsigned. */
1760 arc_double_limm_p (rtx value
)
1762 HOST_WIDE_INT low
, high
;
1764 gcc_assert (GET_CODE (value
) == CONST_DOUBLE
);
1769 low
= CONST_DOUBLE_LOW (value
);
1770 high
= CONST_DOUBLE_HIGH (value
);
1772 if (low
& 0x80000000)
1774 return (((unsigned HOST_WIDE_INT
) low
<= 0xffffffff && high
== 0)
1775 || (((low
& - (unsigned HOST_WIDE_INT
) 0x80000000)
1776 == - (unsigned HOST_WIDE_INT
) 0x80000000)
1781 return (unsigned HOST_WIDE_INT
) low
<= 0x7fffffff && high
== 0;
1785 /* Do any needed setup for a variadic function. For the ARC, we must
1786 create a register parameter block, and then copy any anonymous arguments
1787 in registers to memory.
1789 CUM has not been updated for the last named argument which has type TYPE
1790 and mode MODE, and we rely on this fact. */
1793 arc_setup_incoming_varargs (cumulative_args_t args_so_far
,
1794 machine_mode mode
, tree type
,
1795 int *pretend_size
, int no_rtl
)
1798 CUMULATIVE_ARGS next_cum
;
1800 /* We must treat `__builtin_va_alist' as an anonymous arg. */
1802 next_cum
= *get_cumulative_args (args_so_far
);
1803 arc_function_arg_advance (pack_cumulative_args (&next_cum
),
1805 first_anon_arg
= next_cum
;
1807 if (FUNCTION_ARG_REGNO_P (first_anon_arg
))
1809 /* First anonymous (unnamed) argument is in a reg. */
1811 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
1812 int first_reg_offset
= first_anon_arg
;
1817 = gen_rtx_MEM (BLKmode
, plus_constant (Pmode
, arg_pointer_rtx
,
1818 FIRST_PARM_OFFSET (0)));
1819 move_block_from_reg (first_reg_offset
, regblock
,
1820 MAX_ARC_PARM_REGS
- first_reg_offset
);
1824 = ((MAX_ARC_PARM_REGS
- first_reg_offset
) * UNITS_PER_WORD
);
1828 /* Cost functions. */
1830 /* Provide the costs of an addressing mode that contains ADDR.
1831 If ADDR is not a valid address, its cost is irrelevant. */
1834 arc_address_cost (rtx addr
, machine_mode
, addr_space_t
, bool speed
)
1836 switch (GET_CODE (addr
))
1839 return speed
|| satisfies_constraint_Rcq (addr
) ? 0 : 1;
1840 case PRE_INC
: case PRE_DEC
: case POST_INC
: case POST_DEC
:
1841 case PRE_MODIFY
: case POST_MODIFY
:
1847 if (TARGET_NPS_CMEM
&& cmem_address (addr
, SImode
))
1849 /* Most likely needs a LIMM. */
1850 return COSTS_N_INSNS (1);
1854 register rtx plus0
= XEXP (addr
, 0);
1855 register rtx plus1
= XEXP (addr
, 1);
1857 if (GET_CODE (plus0
) != REG
1858 && (GET_CODE (plus0
) != MULT
1859 || !CONST_INT_P (XEXP (plus0
, 1))
1860 || (INTVAL (XEXP (plus0
, 1)) != 2
1861 && INTVAL (XEXP (plus0
, 1)) != 4)))
1864 switch (GET_CODE (plus1
))
1867 return (!RTX_OK_FOR_OFFSET_P (SImode
, plus1
)
1871 : (satisfies_constraint_Rcq (plus0
)
1872 && satisfies_constraint_O (plus1
))
1876 return (speed
< 1 ? 0
1877 : (satisfies_constraint_Rcq (plus0
)
1878 && satisfies_constraint_Rcq (plus1
))
1883 return COSTS_N_INSNS (1);
1896 /* Emit instruction X with the frame related bit set. */
1902 RTX_FRAME_RELATED_P (x
) = 1;
1906 /* Emit a frame insn to move SRC to DST. */
1909 frame_move (rtx dst
, rtx src
)
1911 rtx tmp
= gen_rtx_SET (dst
, src
);
1912 RTX_FRAME_RELATED_P (tmp
) = 1;
1913 return frame_insn (tmp
);
1916 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
1917 auto increment address, or is zero. */
1920 frame_move_inc (rtx dst
, rtx src
, rtx reg
, rtx addr
)
1922 rtx insn
= frame_move (dst
, src
);
1925 || GET_CODE (addr
) == PRE_DEC
|| GET_CODE (addr
) == POST_INC
1926 || GET_CODE (addr
) == PRE_MODIFY
|| GET_CODE (addr
) == POST_MODIFY
)
1927 add_reg_note (insn
, REG_INC
, reg
);
1931 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
1934 frame_add (rtx reg
, HOST_WIDE_INT offset
)
1936 gcc_assert ((offset
& 0x3) == 0);
1939 return frame_move (reg
, plus_constant (Pmode
, reg
, offset
));
1942 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
1945 frame_stack_add (HOST_WIDE_INT offset
)
1947 return frame_add (stack_pointer_rtx
, offset
);
1950 /* Traditionally, we push saved registers first in the prologue,
1951 then we allocate the rest of the frame - and reverse in the epilogue.
1952 This has still its merits for ease of debugging, or saving code size
1953 or even execution time if the stack frame is so large that some accesses
1954 can't be encoded anymore with offsets in the instruction code when using
1956 Also, it would be a good starting point if we got instructions to help
1957 with register save/restore.
1959 However, often stack frames are small, and the pushing / popping has
1961 - the stack modification prevents a lot of scheduling.
1962 - frame allocation / deallocation needs extra instructions.
1963 - unless we know that we compile ARC700 user code, we need to put
1964 a memory barrier after frame allocation / before deallocation to
1965 prevent interrupts clobbering our data in the frame.
1966 In particular, we don't have any such guarantees for library functions,
1967 which tend to, on the other hand, to have small frames.
1969 Thus, for small frames, we'd like to use a different scheme:
1970 - The frame is allocated in full with the first prologue instruction,
1971 and deallocated in full with the last epilogue instruction.
1972 Thus, the instructions in-betwen can be freely scheduled.
1973 - If the function has no outgoing arguments on the stack, we can allocate
1974 one register save slot at the top of the stack. This register can then
1975 be saved simultanously with frame allocation, and restored with
1977 This register can be picked depending on scheduling considerations,
1978 although same though should go into having some set of registers
1979 to be potentially lingering after a call, and others to be available
1980 immediately - i.e. in the absence of interprocedual optimization, we
1981 can use an ABI-like convention for register allocation to reduce
1982 stalls after function return. */
1983 /* Function prologue/epilogue handlers. */
1985 /* ARCompact stack frames look like:
1987 Before call After call
1988 high +-----------------------+ +-----------------------+
1989 mem | reg parm save area | | reg parm save area |
1990 | only created for | | only created for |
1991 | variable arg fns | | variable arg fns |
1992 AP +-----------------------+ +-----------------------+
1993 | return addr register | | return addr register |
1994 | (if required) | | (if required) |
1995 +-----------------------+ +-----------------------+
1997 | reg save area | | reg save area |
1999 +-----------------------+ +-----------------------+
2000 | frame pointer | | frame pointer |
2001 | (if required) | | (if required) |
2002 FP +-----------------------+ +-----------------------+
2004 | local/temp variables | | local/temp variables |
2006 +-----------------------+ +-----------------------+
2008 | arguments on stack | | arguments on stack |
2010 SP +-----------------------+ +-----------------------+
2011 | reg parm save area |
2012 | only created for |
2013 | variable arg fns |
2014 AP +-----------------------+
2015 | return addr register |
2017 +-----------------------+
2021 +-----------------------+
2024 FP +-----------------------+
2026 | local/temp variables |
2028 +-----------------------+
2030 | arguments on stack |
2032 mem SP +-----------------------+
2035 1) The "reg parm save area" does not exist for non variable argument fns.
2036 The "reg parm save area" can be eliminated completely if we created our
2037 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2039 /* Structure to be filled in by arc_compute_frame_size with register
2040 save masks, and offsets for the current function. */
2041 struct GTY (()) arc_frame_info
2043 unsigned int total_size
; /* # bytes that the entire frame takes up. */
2044 unsigned int extra_size
; /* # bytes of extra stuff. */
2045 unsigned int pretend_size
; /* # bytes we push and pretend caller did. */
2046 unsigned int args_size
; /* # bytes that outgoing arguments take up. */
2047 unsigned int reg_size
; /* # bytes needed to store regs. */
2048 unsigned int var_size
; /* # bytes that variables take up. */
2049 unsigned int reg_offset
; /* Offset from new sp to store regs. */
2050 unsigned int gmask
; /* Mask of saved gp registers. */
2051 int initialized
; /* Nonzero if frame size already calculated. */
2052 short millicode_start_reg
;
2053 short millicode_end_reg
;
2054 bool save_return_addr
;
2057 /* Defining data structures for per-function information. */
2059 typedef struct GTY (()) machine_function
2061 enum arc_function_type fn_type
;
2062 struct arc_frame_info frame_info
;
2063 /* To keep track of unalignment caused by short insns. */
2065 int force_short_suffix
; /* Used when disgorging return delay slot insns. */
2066 const char *size_reason
;
2067 struct arc_ccfsm ccfsm_current
;
2068 /* Map from uid to ccfsm state during branch shortening. */
2069 rtx ccfsm_current_insn
;
2070 char arc_reorg_started
;
2071 char prescan_initialized
;
2074 /* Type of function DECL.
2076 The result is cached. To reset the cache at the end of a function,
2077 call with DECL = NULL_TREE. */
2079 enum arc_function_type
2080 arc_compute_function_type (struct function
*fun
)
2082 tree decl
= fun
->decl
;
2084 enum arc_function_type fn_type
= fun
->machine
->fn_type
;
2086 if (fn_type
!= ARC_FUNCTION_UNKNOWN
)
2089 /* Assume we have a normal function (not an interrupt handler). */
2090 fn_type
= ARC_FUNCTION_NORMAL
;
2092 /* Now see if this is an interrupt handler. */
2093 for (a
= DECL_ATTRIBUTES (decl
);
2097 tree name
= TREE_PURPOSE (a
), args
= TREE_VALUE (a
);
2099 if (name
== get_identifier ("interrupt")
2100 && list_length (args
) == 1
2101 && TREE_CODE (TREE_VALUE (args
)) == STRING_CST
)
2103 tree value
= TREE_VALUE (args
);
2105 if (!strcmp (TREE_STRING_POINTER (value
), "ilink1")
2106 || !strcmp (TREE_STRING_POINTER (value
), "ilink"))
2107 fn_type
= ARC_FUNCTION_ILINK1
;
2108 else if (!strcmp (TREE_STRING_POINTER (value
), "ilink2"))
2109 fn_type
= ARC_FUNCTION_ILINK2
;
2116 return fun
->machine
->fn_type
= fn_type
;
2119 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2120 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2122 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2123 The return address and frame pointer are treated separately.
2124 Don't consider them here.
2125 Addition for pic: The gp register needs to be saved if the current
2126 function changes it to access gotoff variables.
2127 FIXME: This will not be needed if we used some arbitrary register
2130 #define MUST_SAVE_REGISTER(regno, interrupt_p) \
2131 (((regno) != RETURN_ADDR_REGNUM && (regno) != FRAME_POINTER_REGNUM \
2132 && (df_regs_ever_live_p (regno) && (!call_used_regs[regno] || interrupt_p))) \
2133 || (flag_pic && crtl->uses_pic_offset_table \
2134 && regno == PIC_OFFSET_TABLE_REGNUM) )
2136 #define MUST_SAVE_RETURN_ADDR \
2137 (cfun->machine->frame_info.save_return_addr)
2139 /* Return non-zero if there are registers to be saved or loaded using
2140 millicode thunks. We can only use consecutive sequences starting
2141 with r13, and not going beyond r25.
2142 GMASK is a bitmask of registers to save. This function sets
2143 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2144 of registers to be saved / restored with a millicode call. */
2147 arc_compute_millicode_save_restore_regs (unsigned int gmask
,
2148 struct arc_frame_info
*frame
)
2152 int start_reg
= 13, end_reg
= 25;
2154 for (regno
= start_reg
; regno
<= end_reg
&& (gmask
& (1L << regno
));)
2156 end_reg
= regno
- 1;
2157 /* There is no point in using millicode thunks if we don't save/restore
2158 at least three registers. For non-leaf functions we also have the
2160 if (regno
- start_reg
>= 3 - (crtl
->is_leaf
== 0))
2162 frame
->millicode_start_reg
= 13;
2163 frame
->millicode_end_reg
= regno
- 1;
2169 /* Return the bytes needed to compute the frame pointer from the current
2172 SIZE is the size needed for local variables. */
2175 arc_compute_frame_size (int size
) /* size = # of var. bytes allocated. */
2178 unsigned int total_size
, var_size
, args_size
, pretend_size
, extra_size
;
2179 unsigned int reg_size
, reg_offset
;
2181 enum arc_function_type fn_type
;
2183 struct arc_frame_info
*frame_info
= &cfun
->machine
->frame_info
;
2185 size
= ARC_STACK_ALIGN (size
);
2187 /* 1) Size of locals and temporaries */
2190 /* 2) Size of outgoing arguments */
2191 args_size
= crtl
->outgoing_args_size
;
2193 /* 3) Calculate space needed for saved registers.
2194 ??? We ignore the extension registers for now. */
2196 /* See if this is an interrupt handler. Call used registers must be saved
2201 fn_type
= arc_compute_function_type (cfun
);
2202 interrupt_p
= ARC_INTERRUPT_P (fn_type
);
2204 for (regno
= 0; regno
<= 31; regno
++)
2206 if (MUST_SAVE_REGISTER (regno
, interrupt_p
))
2208 reg_size
+= UNITS_PER_WORD
;
2209 gmask
|= 1 << regno
;
2213 /* 4) Space for back trace data structure.
2214 <return addr reg size> (if required) + <fp size> (if required). */
2215 frame_info
->save_return_addr
2216 = (!crtl
->is_leaf
|| df_regs_ever_live_p (RETURN_ADDR_REGNUM
));
2217 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2218 if (optimize_size
&& !TARGET_NO_MILLICODE_THUNK_SET
)
2220 if (arc_compute_millicode_save_restore_regs (gmask
, frame_info
))
2221 frame_info
->save_return_addr
= true;
2225 if (MUST_SAVE_RETURN_ADDR
)
2227 if (frame_pointer_needed
)
2230 /* 5) Space for variable arguments passed in registers */
2231 pretend_size
= crtl
->args
.pretend_args_size
;
2233 /* Ensure everything before the locals is aligned appropriately. */
2235 unsigned int extra_plus_reg_size
;
2236 unsigned int extra_plus_reg_size_aligned
;
2238 extra_plus_reg_size
= extra_size
+ reg_size
;
2239 extra_plus_reg_size_aligned
= ARC_STACK_ALIGN(extra_plus_reg_size
);
2240 reg_size
= extra_plus_reg_size_aligned
- extra_size
;
2243 /* Compute total frame size. */
2244 total_size
= var_size
+ args_size
+ extra_size
+ pretend_size
+ reg_size
;
2246 total_size
= ARC_STACK_ALIGN (total_size
);
2248 /* Compute offset of register save area from stack pointer:
2249 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2251 reg_offset
= (total_size
- (pretend_size
+ reg_size
+ extra_size
)
2252 + (frame_pointer_needed
? 4 : 0));
2254 /* Save computed information. */
2255 frame_info
->total_size
= total_size
;
2256 frame_info
->extra_size
= extra_size
;
2257 frame_info
->pretend_size
= pretend_size
;
2258 frame_info
->var_size
= var_size
;
2259 frame_info
->args_size
= args_size
;
2260 frame_info
->reg_size
= reg_size
;
2261 frame_info
->reg_offset
= reg_offset
;
2262 frame_info
->gmask
= gmask
;
2263 frame_info
->initialized
= reload_completed
;
2265 /* Ok, we're done. */
2269 /* Common code to save/restore registers. */
2270 /* BASE_REG is the base register to use for addressing and to adjust.
2271 GMASK is a bitmask of general purpose registers to save/restore.
2272 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2273 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2274 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2278 arc_save_restore (rtx base_reg
,
2279 unsigned int gmask
, int epilogue_p
, int *first_offset
)
2281 unsigned int offset
= 0;
2283 struct arc_frame_info
*frame
= &cfun
->machine
->frame_info
;
2284 rtx sibthunk_insn
= NULL_RTX
;
2288 /* Millicode thunks implementation:
2289 Generates calls to millicodes for registers starting from r13 to r25
2290 Present Limitations:
2291 - Only one range supported. The remaining regs will have the ordinary
2292 st and ld instructions for store and loads. Hence a gmask asking
2293 to store r13-14, r16-r25 will only generate calls to store and
2294 load r13 to r14 while store and load insns will be generated for
2295 r16 to r25 in the prologue and epilogue respectively.
2297 - Presently library only supports register ranges starting from r13.
2299 if (epilogue_p
== 2 || frame
->millicode_end_reg
> 14)
2301 int start_call
= frame
->millicode_start_reg
;
2302 int end_call
= frame
->millicode_end_reg
;
2303 int n_regs
= end_call
- start_call
+ 1;
2304 int i
= 0, r
, off
= 0;
2306 rtx ret_addr
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2310 /* "reg_size" won't be more than 127 . */
2311 gcc_assert (epilogue_p
|| abs (*first_offset
) <= 127);
2312 frame_add (base_reg
, *first_offset
);
2315 insn
= gen_rtx_PARALLEL
2316 (VOIDmode
, rtvec_alloc ((epilogue_p
== 2) + n_regs
+ 1));
2317 if (epilogue_p
== 2)
2320 XVECEXP (insn
, 0, n_regs
) = gen_rtx_CLOBBER (VOIDmode
, ret_addr
);
2321 for (r
= start_call
; r
<= end_call
; r
++, off
+= UNITS_PER_WORD
, i
++)
2323 rtx reg
= gen_rtx_REG (SImode
, r
);
2325 = gen_frame_mem (SImode
, plus_constant (Pmode
, base_reg
, off
));
2328 XVECEXP (insn
, 0, i
) = gen_rtx_SET (reg
, mem
);
2330 XVECEXP (insn
, 0, i
) = gen_rtx_SET (mem
, reg
);
2331 gmask
= gmask
& ~(1L << r
);
2333 if (epilogue_p
== 2)
2334 sibthunk_insn
= insn
;
2337 insn
= frame_insn (insn
);
2339 for (r
= start_call
; r
<= end_call
; r
++)
2341 rtx reg
= gen_rtx_REG (SImode
, r
);
2342 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2348 for (regno
= 0; regno
<= 31; regno
++)
2350 machine_mode mode
= SImode
;
2355 && ((gmask
& (1L << regno
)) != 0)
2356 && ((gmask
& (1L << (regno
+1))) != 0))
2361 else if ((gmask
& (1L << regno
)) != 0)
2369 rtx reg
= gen_rtx_REG (mode
, regno
);
2371 int cfa_adjust
= *first_offset
;
2375 gcc_assert (!offset
);
2376 addr
= plus_constant (Pmode
, base_reg
, *first_offset
);
2377 addr
= gen_rtx_PRE_MODIFY (Pmode
, base_reg
, addr
);
2382 gcc_assert (SMALL_INT (offset
));
2383 addr
= plus_constant (Pmode
, base_reg
, offset
);
2385 mem
= gen_frame_mem (mode
, addr
);
2389 frame_move_inc (reg
, mem
, base_reg
, addr
);
2390 add_reg_note (insn
, REG_CFA_RESTORE
, reg
);
2393 enum reg_note note
= REG_CFA_ADJUST_CFA
;
2394 add_reg_note (insn
, note
,
2395 gen_rtx_SET (stack_pointer_rtx
,
2396 plus_constant (Pmode
,
2402 frame_move_inc (mem
, reg
, base_reg
, addr
);
2403 offset
+= UNITS_PER_WORD
;
2406 offset
+= UNITS_PER_WORD
;
2414 int start_call
= frame
->millicode_start_reg
;
2415 int end_call
= frame
->millicode_end_reg
;
2418 rtx r12
= gen_rtx_REG (Pmode
, 12);
2420 frame_insn (gen_rtx_SET (r12
, GEN_INT (offset
)));
2421 XVECEXP (sibthunk_insn
, 0, 0) = ret_rtx
;
2422 XVECEXP (sibthunk_insn
, 0, 1)
2423 = gen_rtx_SET (stack_pointer_rtx
,
2424 gen_rtx_PLUS (Pmode
, stack_pointer_rtx
, r12
));
2425 sibthunk_insn
= emit_jump_insn (sibthunk_insn
);
2426 RTX_FRAME_RELATED_P (sibthunk_insn
) = 1;
2428 /* Would be nice if we could do this earlier, when the PARALLEL
2429 is populated, but these need to be attached after the
2431 for (r
= start_call
; r
<= end_call
; r
++)
2433 rtx reg
= gen_rtx_REG (SImode
, r
);
2434 add_reg_note (sibthunk_insn
, REG_CFA_RESTORE
, reg
);
2437 } /* arc_save_restore */
2440 int arc_return_address_regs
[4]
2441 = {0, RETURN_ADDR_REGNUM
, ILINK1_REGNUM
, ILINK2_REGNUM
};
2443 /* Set up the stack and frame pointer (if desired) for the function. */
2446 arc_expand_prologue (void)
2448 int size
= get_frame_size ();
2449 unsigned int gmask
= cfun
->machine
->frame_info
.gmask
;
2450 /* unsigned int frame_pointer_offset;*/
2451 unsigned int frame_size_to_allocate
;
2452 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2453 Change the stack layout so that we rather store a high register with the
2454 PRE_MODIFY, thus enabling more short insn generation.) */
2455 int first_offset
= 0;
2457 size
= ARC_STACK_ALIGN (size
);
2459 /* Compute/get total frame size. */
2460 size
= (!cfun
->machine
->frame_info
.initialized
2461 ? arc_compute_frame_size (size
)
2462 : cfun
->machine
->frame_info
.total_size
);
2464 if (flag_stack_usage_info
)
2465 current_function_static_stack_size
= size
;
2467 /* Keep track of frame size to be allocated. */
2468 frame_size_to_allocate
= size
;
2470 /* These cases shouldn't happen. Catch them now. */
2471 gcc_assert (!(size
== 0 && gmask
));
2473 /* Allocate space for register arguments if this is a variadic function. */
2474 if (cfun
->machine
->frame_info
.pretend_size
!= 0)
2476 /* Ensure pretend_size is maximum of 8 * word_size. */
2477 gcc_assert (cfun
->machine
->frame_info
.pretend_size
<= 32);
2479 frame_stack_add (-(HOST_WIDE_INT
)cfun
->machine
->frame_info
.pretend_size
);
2480 frame_size_to_allocate
-= cfun
->machine
->frame_info
.pretend_size
;
2483 /* The home-grown ABI says link register is saved first. */
2484 if (MUST_SAVE_RETURN_ADDR
)
2486 rtx ra
= gen_rtx_REG (SImode
, RETURN_ADDR_REGNUM
);
2487 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_DEC (Pmode
, stack_pointer_rtx
));
2489 frame_move_inc (mem
, ra
, stack_pointer_rtx
, 0);
2490 frame_size_to_allocate
-= UNITS_PER_WORD
;
2492 } /* MUST_SAVE_RETURN_ADDR */
2494 /* Save any needed call-saved regs (and call-used if this is an
2495 interrupt handler) for ARCompact ISA. */
2496 if (cfun
->machine
->frame_info
.reg_size
)
2498 first_offset
= -cfun
->machine
->frame_info
.reg_size
;
2499 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
2500 arc_save_restore (stack_pointer_rtx
, gmask
, 0, &first_offset
);
2501 frame_size_to_allocate
-= cfun
->machine
->frame_info
.reg_size
;
2505 /* Save frame pointer if needed. */
2506 if (frame_pointer_needed
)
2508 rtx addr
= gen_rtx_PLUS (Pmode
, stack_pointer_rtx
,
2509 GEN_INT (-UNITS_PER_WORD
+ first_offset
));
2510 rtx mem
= gen_frame_mem (Pmode
, gen_rtx_PRE_MODIFY (Pmode
,
2513 frame_move_inc (mem
, frame_pointer_rtx
, stack_pointer_rtx
, 0);
2514 frame_size_to_allocate
-= UNITS_PER_WORD
;
2516 frame_move (frame_pointer_rtx
, stack_pointer_rtx
);
2519 /* ??? We don't handle the case where the saved regs are more than 252
2520 bytes away from sp. This can be handled by decrementing sp once, saving
2521 the regs, and then decrementing it again. The epilogue doesn't have this
2522 problem as the `ld' insn takes reg+limm values (though it would be more
2523 efficient to avoid reg+limm). */
2525 frame_size_to_allocate
-= first_offset
;
2526 /* Allocate the stack frame. */
2527 if (frame_size_to_allocate
> 0)
2528 frame_stack_add ((HOST_WIDE_INT
) 0 - frame_size_to_allocate
);
2530 /* Setup the gp register, if needed. */
2531 if (crtl
->uses_pic_offset_table
)
2532 arc_finalize_pic ();
2535 /* Do any necessary cleanup after a function to restore stack, frame,
2539 arc_expand_epilogue (int sibcall_p
)
2541 int size
= get_frame_size ();
2542 enum arc_function_type fn_type
= arc_compute_function_type (cfun
);
2544 size
= ARC_STACK_ALIGN (size
);
2545 size
= (!cfun
->machine
->frame_info
.initialized
2546 ? arc_compute_frame_size (size
)
2547 : cfun
->machine
->frame_info
.total_size
);
2549 unsigned int pretend_size
= cfun
->machine
->frame_info
.pretend_size
;
2550 unsigned int frame_size
;
2551 unsigned int size_to_deallocate
;
2553 int can_trust_sp_p
= !cfun
->calls_alloca
;
2554 int first_offset
= 0;
2555 int millicode_p
= cfun
->machine
->frame_info
.millicode_end_reg
> 0;
2558 size_to_deallocate
= size
;
2560 frame_size
= size
- (pretend_size
+
2561 cfun
->machine
->frame_info
.reg_size
+
2562 cfun
->machine
->frame_info
.extra_size
);
2564 /* ??? There are lots of optimizations that can be done here.
2565 EG: Use fp to restore regs if it's closer.
2566 Maybe in time we'll do them all. For now, always restore regs from
2567 sp, but don't restore sp if we don't have to. */
2569 if (!can_trust_sp_p
)
2570 gcc_assert (frame_pointer_needed
);
2572 /* Restore stack pointer to the beginning of saved register area for
2576 if (frame_pointer_needed
)
2577 frame_move (stack_pointer_rtx
, frame_pointer_rtx
);
2579 first_offset
= frame_size
;
2580 size_to_deallocate
-= frame_size
;
2582 else if (!can_trust_sp_p
)
2583 frame_stack_add (-frame_size
);
2586 /* Restore any saved registers. */
2587 if (frame_pointer_needed
)
2589 rtx addr
= gen_rtx_POST_INC (Pmode
, stack_pointer_rtx
);
2591 insn
= frame_move_inc (frame_pointer_rtx
, gen_frame_mem (Pmode
, addr
),
2592 stack_pointer_rtx
, 0);
2593 add_reg_note (insn
, REG_CFA_RESTORE
, frame_pointer_rtx
);
2594 add_reg_note (insn
, REG_CFA_DEF_CFA
,
2595 plus_constant (SImode
, stack_pointer_rtx
,
2597 size_to_deallocate
-= UNITS_PER_WORD
;
2600 /* Load blink after the calls to thunk calls in case of optimize size. */
2603 int sibthunk_p
= (!sibcall_p
2604 && fn_type
== ARC_FUNCTION_NORMAL
2605 && !cfun
->machine
->frame_info
.pretend_size
);
2607 gcc_assert (!(cfun
->machine
->frame_info
.gmask
2608 & (FRAME_POINTER_MASK
| RETURN_ADDR_MASK
)));
2609 arc_save_restore (stack_pointer_rtx
,
2610 cfun
->machine
->frame_info
.gmask
,
2611 1 + sibthunk_p
, &first_offset
);
2615 /* If we are to restore registers, and first_offset would require
2616 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
2617 fast add to the stack pointer, do this now. */
2618 if ((!SMALL_INT (first_offset
)
2619 && cfun
->machine
->frame_info
.gmask
2620 && ((TARGET_ARC700
&& !optimize_size
)
2621 ? first_offset
<= 0x800
2622 : satisfies_constraint_C2a (GEN_INT (first_offset
))))
2623 /* Also do this if we have both gprs and return
2624 address to restore, and they both would need a LIMM. */
2625 || (MUST_SAVE_RETURN_ADDR
2626 && !SMALL_INT ((cfun
->machine
->frame_info
.reg_size
+ first_offset
) >> 2)
2627 && cfun
->machine
->frame_info
.gmask
))
2629 frame_stack_add (first_offset
);
2632 if (MUST_SAVE_RETURN_ADDR
)
2634 rtx ra
= gen_rtx_REG (Pmode
, RETURN_ADDR_REGNUM
);
2635 int ra_offs
= cfun
->machine
->frame_info
.reg_size
+ first_offset
;
2636 rtx addr
= plus_constant (Pmode
, stack_pointer_rtx
, ra_offs
);
2637 HOST_WIDE_INT cfa_adjust
= 0;
2639 /* If the load of blink would need a LIMM, but we can add
2640 the offset quickly to sp, do the latter. */
2641 if (!SMALL_INT (ra_offs
>> 2)
2642 && !cfun
->machine
->frame_info
.gmask
2643 && ((TARGET_ARC700
&& !optimize_size
)
2645 : satisfies_constraint_C2a (GEN_INT (ra_offs
))))
2647 size_to_deallocate
-= ra_offs
- first_offset
;
2649 frame_stack_add (ra_offs
);
2651 addr
= stack_pointer_rtx
;
2653 /* See if we can combine the load of the return address with the
2654 final stack adjustment.
2655 We need a separate load if there are still registers to
2656 restore. We also want a separate load if the combined insn
2657 would need a limm, but a separate load doesn't. */
2659 && !cfun
->machine
->frame_info
.gmask
2660 && (SMALL_INT (ra_offs
) || !SMALL_INT (ra_offs
>> 2)))
2662 addr
= gen_rtx_PRE_MODIFY (Pmode
, stack_pointer_rtx
, addr
);
2663 cfa_adjust
= ra_offs
;
2665 size_to_deallocate
-= cfun
->machine
->frame_info
.reg_size
;
2667 else if (!ra_offs
&& size_to_deallocate
== UNITS_PER_WORD
)
2669 addr
= gen_rtx_POST_INC (Pmode
, addr
);
2670 cfa_adjust
= GET_MODE_SIZE (Pmode
);
2671 size_to_deallocate
= 0;
2674 insn
= frame_move_inc (ra
, gen_frame_mem (Pmode
, addr
),
2675 stack_pointer_rtx
, addr
);
2678 enum reg_note note
= REG_CFA_ADJUST_CFA
;
2680 add_reg_note (insn
, note
,
2681 gen_rtx_SET (stack_pointer_rtx
,
2682 plus_constant (SImode
, stack_pointer_rtx
,
2685 add_reg_note (insn
, REG_CFA_RESTORE
, ra
);
2690 if (cfun
->machine
->frame_info
.reg_size
)
2691 arc_save_restore (stack_pointer_rtx
,
2692 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
2693 cfun
->machine
->frame_info
.gmask
2694 & ~(FRAME_POINTER_MASK
| RETURN_ADDR_MASK
), 1, &first_offset
);
2698 /* The rest of this function does the following:
2699 ARCompact : handle epilogue_delay, restore sp (phase-2), return
2702 /* Keep track of how much of the stack pointer we've restored.
2703 It makes the following a lot more readable. */
2704 size_to_deallocate
+= first_offset
;
2705 restored
= size
- size_to_deallocate
;
2707 if (size
> restored
)
2708 frame_stack_add (size
- restored
);
2710 /* Emit the return instruction. */
2711 if (sibcall_p
== FALSE
)
2712 emit_jump_insn (gen_simple_return ());
2715 /* Return the offset relative to the stack pointer where the return address
2716 is stored, or -1 if it is not stored. */
2719 arc_return_slot_offset ()
2721 struct arc_frame_info
*afi
= &cfun
->machine
->frame_info
;
2723 return (afi
->save_return_addr
2724 ? afi
->total_size
- afi
->pretend_size
- afi
->extra_size
: -1);
2729 /* Emit special PIC prologues and epilogues. */
2730 /* If the function has any GOTOFF relocations, then the GOTBASE
2731 register has to be setup in the prologue
2732 The instruction needed at the function start for setting up the
2735 ----------------------------------------------------------
2736 The rtl to be emitted for this should be:
2739 (const (unspec (symref _DYNAMIC) 3)))
2740 ---------------------------------------------------------- */
2743 arc_finalize_pic (void)
2746 rtx baseptr_rtx
= gen_rtx_REG (Pmode
, PIC_OFFSET_TABLE_REGNUM
);
2748 if (crtl
->uses_pic_offset_table
== 0)
2751 gcc_assert (flag_pic
!= 0);
2753 pat
= gen_rtx_SYMBOL_REF (Pmode
, "_DYNAMIC");
2754 pat
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, pat
), ARC_UNSPEC_GOT
);
2755 pat
= gen_rtx_CONST (Pmode
, pat
);
2757 pat
= gen_rtx_SET (baseptr_rtx
, pat
);
2762 /* !TARGET_BARREL_SHIFTER support. */
2763 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
2767 emit_shift (enum rtx_code code
, rtx op0
, rtx op1
, rtx op2
)
2769 rtx shift
= gen_rtx_fmt_ee (code
, SImode
, op1
, op2
);
2771 = ((shift4_operator (shift
, SImode
) ? gen_shift_si3
: gen_shift_si3_loop
)
2772 (op0
, op1
, op2
, shift
));
2776 /* Output the assembler code for doing a shift.
2777 We go to a bit of trouble to generate efficient code as the ARC601 only has
2778 single bit shifts. This is taken from the h8300 port. We only have one
2779 mode of shifting and can't access individual bytes like the h8300 can, so
2780 this is greatly simplified (at the expense of not generating hyper-
2783 This function is not used if the variable shift insns are present. */
2785 /* FIXME: This probably can be done using a define_split in arc.md.
2786 Alternately, generate rtx rather than output instructions. */
2789 output_shift (rtx
*operands
)
2791 /* static int loopend_lab;*/
2792 rtx shift
= operands
[3];
2793 machine_mode mode
= GET_MODE (shift
);
2794 enum rtx_code code
= GET_CODE (shift
);
2795 const char *shift_one
;
2797 gcc_assert (mode
== SImode
);
2801 case ASHIFT
: shift_one
= "add %0,%1,%1"; break;
2802 case ASHIFTRT
: shift_one
= "asr %0,%1"; break;
2803 case LSHIFTRT
: shift_one
= "lsr %0,%1"; break;
2804 default: gcc_unreachable ();
2807 if (GET_CODE (operands
[2]) != CONST_INT
)
2809 output_asm_insn ("and.f lp_count,%2, 0x1f", operands
);
2816 n
= INTVAL (operands
[2]);
2818 /* Only consider the lower 5 bits of the shift count. */
2821 /* First see if we can do them inline. */
2822 /* ??? We could get better scheduling & shorter code (using short insns)
2823 by using splitters. Alas, that'd be even more verbose. */
2824 if (code
== ASHIFT
&& n
<= 9 && n
> 2
2825 && dest_reg_operand (operands
[4], SImode
))
2827 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands
);
2828 for (n
-=3 ; n
>= 3; n
-= 3)
2829 output_asm_insn ("add3 %0,%4,%0", operands
);
2831 output_asm_insn ("add2 %0,%4,%0", operands
);
2833 output_asm_insn ("add %0,%0,%0", operands
);
2839 output_asm_insn (shift_one
, operands
);
2840 operands
[1] = operands
[0];
2843 /* See if we can use a rotate/and. */
2844 else if (n
== BITS_PER_WORD
- 1)
2849 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands
);
2852 /* The ARC doesn't have a rol insn. Use something else. */
2853 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands
);
2856 /* The ARC doesn't have a rol insn. Use something else. */
2857 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands
);
2863 else if (n
== BITS_PER_WORD
- 2 && dest_reg_operand (operands
[4], SImode
))
2868 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands
);
2871 #if 1 /* Need some scheduling comparisons. */
2872 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
2873 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
2875 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
2876 "sbc.f %0,%0,%4\n\trlc %0,%0", operands
);
2881 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
2882 "add.f 0,%4,%4\n\trlc %0,%0", operands
);
2884 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
2885 "and %0,%0,1\n\trlc %0,%0", operands
);
2892 else if (n
== BITS_PER_WORD
- 3 && code
== ASHIFT
)
2893 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
2898 operands
[2] = GEN_INT (n
);
2899 output_asm_insn ("mov.f lp_count, %2", operands
);
2903 output_asm_insn ("lpnz\t2f", operands
);
2904 output_asm_insn (shift_one
, operands
);
2905 output_asm_insn ("nop", operands
);
2906 fprintf (asm_out_file
, "2:\t%s end single insn loop\n",
2915 /* Nested function support. */
2917 /* Directly store VALUE into memory object BLOCK at OFFSET. */
2920 emit_store_direct (rtx block
, int offset
, int value
)
2922 emit_insn (gen_store_direct (adjust_address (block
, SImode
, offset
),
2924 gen_int_mode (value
, SImode
))));
2927 /* Emit RTL insns to initialize the variable parts of a trampoline.
2928 FNADDR is an RTX for the address of the function's pure code.
2929 CXT is an RTX for the static chain value for the function. */
2930 /* With potentially multiple shared objects loaded, and multiple stacks
2931 present for multiple thereds where trampolines might reside, a simple
2932 range check will likely not suffice for the profiler to tell if a callee
2933 is a trampoline. We a speedier check by making the trampoline start at
2934 an address that is not 4-byte aligned.
2935 A trampoline looks like this:
2939 ld_s r12,[pcl,12] 0xd403
2940 ld r11,[pcl,12] 0x170c 700b
2944 The fastest trampoline to execute for trampolines within +-8KB of CTX
2947 j [limm] 0x20200f80 limm
2948 and that would also be faster to write to the stack by computing the offset
2949 from CTX to TRAMP at compile time. However, it would really be better to
2950 get rid of the high cost of cache invalidation when generating trampolines,
2951 which requires that the code part of trampolines stays constant, and
2953 - making sure that no executable code but trampolines is on the stack,
2954 no icache entries linger for the area of the stack from when before the
2955 stack was allocated, and allocating trampolines in trampoline-only
2958 - allocate trampolines fram a special pool of pre-allocated trampolines. */
2961 arc_initialize_trampoline (rtx tramp
, tree fndecl
, rtx cxt
)
2963 rtx fnaddr
= XEXP (DECL_RTL (fndecl
), 0);
2965 emit_store_direct (tramp
, 0, TARGET_BIG_ENDIAN
? 0x78e0d403 : 0xd40378e0);
2966 emit_store_direct (tramp
, 4, TARGET_BIG_ENDIAN
? 0x170c700b : 0x700b170c);
2967 emit_store_direct (tramp
, 8, TARGET_BIG_ENDIAN
? 0x7c0078e0 : 0x78e07c00);
2968 emit_move_insn (adjust_address (tramp
, SImode
, 12), fnaddr
);
2969 emit_move_insn (adjust_address (tramp
, SImode
, 16), cxt
);
2970 emit_insn (gen_flush_icache (adjust_address (tramp
, SImode
, 0)));
2973 /* Allow the profiler to easily distinguish trampolines from normal
2977 arc_trampoline_adjust_address (rtx addr
)
2979 return plus_constant (Pmode
, addr
, 2);
2982 /* This is set briefly to 1 when we output a ".as" address modifer, and then
2983 reset when we output the scaled address. */
2984 static int output_scaled
= 0;
2986 /* Print operand X (an rtx) in assembler syntax to file FILE.
2987 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
2988 For `%' followed by punctuation, CODE is the punctuation and X is null. */
2989 /* In final.c:output_asm_insn:
2992 'c' : constant address if CONSTANT_ADDRESS_P
2998 'p': bit Position of lsb
2999 's': size of bit field
3000 '#': condbranch delay slot suffix
3001 '*': jump delay slot suffix
3002 '?' : nonjump-insn suffix for conditional execution or short instruction
3003 '!' : jump / call suffix for conditional execution or short instruction
3004 '`': fold constant inside unary o-perator, re-recognize, and emit.
3009 'B': Branch comparison operand - suppress sda reference
3010 'H': Most significant word
3011 'L': Least significant word
3012 'A': ASCII decimal representation of floating point value
3013 'U': Load/store update or scaling indicator
3014 'V': cache bypass indicator for volatile
3019 'o': original symbol - no @ prepending. */
3022 arc_print_operand (FILE *file
, rtx x
, int code
)
3027 if (GET_CODE (x
) == CONST_INT
)
3028 fprintf (file
, "%d",exact_log2(INTVAL (x
) + 1) - 1 );
3030 output_operand_lossage ("invalid operand to %%Z code");
3035 if (GET_CODE (x
) == CONST_INT
)
3036 fprintf (file
, "%d",exact_log2(INTVAL (x
)) );
3038 output_operand_lossage ("invalid operand to %%z code");
3043 if (GET_CODE (x
) == CONST_INT
)
3044 fprintf (file
, "%d",exact_log2(~INTVAL (x
)) );
3046 output_operand_lossage ("invalid operand to %%M code");
3051 if (GET_CODE (x
) == CONST_INT
)
3052 fprintf (file
, "%d", exact_log2 (INTVAL (x
) & -INTVAL (x
)));
3054 output_operand_lossage ("invalid operand to %%p code");
3058 if (GET_CODE (x
) == CONST_INT
)
3060 HOST_WIDE_INT i
= INTVAL (x
);
3061 HOST_WIDE_INT s
= exact_log2 (i
& -i
);
3062 fprintf (file
, "%d", exact_log2 (((0xffffffffUL
& i
) >> s
) + 1));
3065 output_operand_lossage ("invalid operand to %%s code");
3069 /* Conditional branches depending on condition codes.
3070 Note that this is only for branches that were known to depend on
3071 condition codes before delay slot scheduling;
3072 out-of-range brcc / bbit expansions should use '*'.
3073 This distinction is important because of the different
3074 allowable delay slot insns and the output of the delay suffix
3075 for TARGET_AT_DBR_COND_EXEC. */
3077 /* Unconditional branches / branches not depending on condition codes.
3078 This could also be a CALL_INSN.
3079 Output the appropriate delay slot suffix. */
3080 if (final_sequence
&& final_sequence
->len () != 1)
3082 rtx_insn
*jump
= final_sequence
->insn (0);
3083 rtx_insn
*delay
= final_sequence
->insn (1);
3085 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3086 if (delay
->deleted ())
3088 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3089 fputs (INSN_FROM_TARGET_P (delay
) ? ".d"
3090 : TARGET_AT_DBR_CONDEXEC
&& code
== '#' ? ".d"
3091 : get_attr_type (jump
) == TYPE_RETURN
&& code
== '#' ? ""
3098 case '?' : /* with leading "." */
3099 case '!' : /* without leading "." */
3100 /* This insn can be conditionally executed. See if the ccfsm machinery
3101 says it should be conditionalized.
3102 If it shouldn't, we'll check the compact attribute if this insn
3103 has a short variant, which may be used depending on code size and
3104 alignment considerations. */
3105 if (current_insn_predicate
)
3106 arc_ccfsm_current
.cc
3107 = get_arc_condition_code (current_insn_predicate
);
3108 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
))
3110 /* Is this insn in a delay slot sequence? */
3111 if (!final_sequence
|| XVECLEN (final_sequence
, 0) < 2
3112 || current_insn_predicate
3113 || CALL_P (final_sequence
->insn (0))
3114 || simplejump_p (final_sequence
->insn (0)))
3116 /* This insn isn't in a delay slot sequence, or conditionalized
3117 independently of its position in a delay slot. */
3118 fprintf (file
, "%s%s",
3119 code
== '?' ? "." : "",
3120 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3121 /* If this is a jump, there are still short variants. However,
3122 only beq_s / bne_s have the same offset range as b_s,
3123 and the only short conditional returns are jeq_s and jne_s. */
3125 && (arc_ccfsm_current
.cc
== ARC_CC_EQ
3126 || arc_ccfsm_current
.cc
== ARC_CC_NE
3127 || 0 /* FIXME: check if branch in 7 bit range. */))
3128 output_short_suffix (file
);
3130 else if (code
== '!') /* Jump with delay slot. */
3131 fputs (arc_condition_codes
[arc_ccfsm_current
.cc
], file
);
3132 else /* An Instruction in a delay slot of a jump or call. */
3134 rtx jump
= XVECEXP (final_sequence
, 0, 0);
3135 rtx insn
= XVECEXP (final_sequence
, 0, 1);
3137 /* If the insn is annulled and is from the target path, we need
3138 to inverse the condition test. */
3139 if (JUMP_P (jump
) && INSN_ANNULLED_BRANCH_P (jump
))
3141 if (INSN_FROM_TARGET_P (insn
))
3142 fprintf (file
, "%s%s",
3143 code
== '?' ? "." : "",
3144 arc_condition_codes
[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current
.cc
)]);
3146 fprintf (file
, "%s%s",
3147 code
== '?' ? "." : "",
3148 arc_condition_codes
[arc_ccfsm_current
.cc
]);
3149 if (arc_ccfsm_current
.state
== 5)
3150 arc_ccfsm_current
.state
= 0;
3153 /* This insn is executed for either path, so don't
3154 conditionalize it at all. */
3155 output_short_suffix (file
);
3160 output_short_suffix (file
);
3163 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3166 fputs (arc_condition_codes
[get_arc_condition_code (x
)], file
);
3169 fputs (arc_condition_codes
[ARC_INVERSE_CONDITION_CODE
3170 (get_arc_condition_code (x
))],
3174 /* Write second word of DImode or DFmode reference,
3175 register or memory. */
3176 if (GET_CODE (x
) == REG
)
3177 fputs (reg_names
[REGNO (x
)+1], file
);
3178 else if (GET_CODE (x
) == MEM
)
3182 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3183 PRE_MODIFY, we will have handled the first word already;
3184 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3185 first word will be done later. In either case, the access
3186 to the first word will do the modify, and we only have
3187 to add an offset of four here. */
3188 if (GET_CODE (XEXP (x
, 0)) == PRE_INC
3189 || GET_CODE (XEXP (x
, 0)) == PRE_DEC
3190 || GET_CODE (XEXP (x
, 0)) == PRE_MODIFY
3191 || GET_CODE (XEXP (x
, 0)) == POST_INC
3192 || GET_CODE (XEXP (x
, 0)) == POST_DEC
3193 || GET_CODE (XEXP (x
, 0)) == POST_MODIFY
)
3194 output_address (VOIDmode
,
3195 plus_constant (Pmode
, XEXP (XEXP (x
, 0), 0), 4));
3196 else if (output_scaled
)
3198 rtx addr
= XEXP (x
, 0);
3199 int size
= GET_MODE_SIZE (GET_MODE (x
));
3201 output_address (VOIDmode
,
3202 plus_constant (Pmode
, XEXP (addr
, 0),
3203 ((INTVAL (XEXP (addr
, 1)) + 4)
3204 >> (size
== 2 ? 1 : 2))));
3208 output_address (VOIDmode
,
3209 plus_constant (Pmode
, XEXP (x
, 0), 4));
3213 output_operand_lossage ("invalid operand to %%R code");
3216 /* FIXME: remove %S option. */
3218 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3221 output_addr_const (file
, x
);
3227 if (GET_CODE (x
) == REG
)
3229 /* L = least significant word, H = most significant word. */
3230 if ((WORDS_BIG_ENDIAN
!= 0) ^ (code
== 'L'))
3231 fputs (reg_names
[REGNO (x
)], file
);
3233 fputs (reg_names
[REGNO (x
)+1], file
);
3235 else if (GET_CODE (x
) == CONST_INT
3236 || GET_CODE (x
) == CONST_DOUBLE
)
3238 rtx first
, second
, word
;
3240 split_double (x
, &first
, &second
);
3242 if((WORDS_BIG_ENDIAN
) == 0)
3243 word
= (code
== 'L' ? first
: second
);
3245 word
= (code
== 'L' ? second
: first
);
3247 fprintf (file
, "0x%08" PRIx32
, ((uint32_t) INTVAL (word
)));
3250 output_operand_lossage ("invalid operand to %%H/%%L code");
3256 gcc_assert (GET_CODE (x
) == CONST_DOUBLE
3257 && GET_MODE_CLASS (GET_MODE (x
)) == MODE_FLOAT
);
3259 real_to_decimal (str
, CONST_DOUBLE_REAL_VALUE (x
), sizeof (str
), 0, 1);
3260 fprintf (file
, "%s", str
);
3264 /* Output a load/store with update indicator if appropriate. */
3265 if (GET_CODE (x
) == MEM
)
3267 rtx addr
= XEXP (x
, 0);
3268 switch (GET_CODE (addr
))
3270 case PRE_INC
: case PRE_DEC
: case PRE_MODIFY
:
3271 fputs (".a", file
); break;
3272 case POST_INC
: case POST_DEC
: case POST_MODIFY
:
3273 fputs (".ab", file
); break;
3275 /* Are we using a scaled index? */
3276 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3277 fputs (".as", file
);
3278 /* Can we use a scaled offset? */
3279 else if (CONST_INT_P (XEXP (addr
, 1))
3280 && GET_MODE_SIZE (GET_MODE (x
)) > 1
3281 && (!(INTVAL (XEXP (addr
, 1))
3282 & (GET_MODE_SIZE (GET_MODE (x
)) - 1) & 3))
3283 /* Does it make a difference? */
3284 && !SMALL_INT_RANGE(INTVAL (XEXP (addr
, 1)),
3285 GET_MODE_SIZE (GET_MODE (x
)) - 2, 0))
3287 fputs (".as", file
);
3294 gcc_assert (CONSTANT_P (addr
)); break;
3298 output_operand_lossage ("invalid operand to %%U code");
3301 /* Output cache bypass indicator for a load/store insn. Volatile memory
3302 refs are defined to use the cache bypass mechanism. */
3303 if (GET_CODE (x
) == MEM
)
3305 if (MEM_VOLATILE_P (x
) && !TARGET_VOLATILE_CACHE_SET
)
3306 fputs (".di", file
);
3309 output_operand_lossage ("invalid operand to %%V code");
3314 /* Do nothing special. */
3317 fputs (reg_names
[REGNO (x
)]+1, file
);
3320 /* This punctuation character is needed because label references are
3321 printed in the output template using %l. This is a front end
3322 character, and when we want to emit a '@' before it, we have to use
3328 /* Output an operator. */
3329 switch (GET_CODE (x
))
3331 case PLUS
: fputs ("add", file
); return;
3332 case SS_PLUS
: fputs ("adds", file
); return;
3333 case AND
: fputs ("and", file
); return;
3334 case IOR
: fputs ("or", file
); return;
3335 case XOR
: fputs ("xor", file
); return;
3336 case MINUS
: fputs ("sub", file
); return;
3337 case SS_MINUS
: fputs ("subs", file
); return;
3338 case ASHIFT
: fputs ("asl", file
); return;
3339 case ASHIFTRT
: fputs ("asr", file
); return;
3340 case LSHIFTRT
: fputs ("lsr", file
); return;
3341 case ROTATERT
: fputs ("ror", file
); return;
3342 case MULT
: fputs ("mpy", file
); return;
3343 case ABS
: fputs ("abs", file
); return; /* Unconditional. */
3344 case NEG
: fputs ("neg", file
); return;
3345 case SS_NEG
: fputs ("negs", file
); return;
3346 case NOT
: fputs ("not", file
); return; /* Unconditional. */
3348 fputs ("ext", file
); /* bmsk allows predication. */
3350 case SIGN_EXTEND
: /* Unconditional. */
3351 fputs ("sex", file
);
3353 switch (GET_MODE (XEXP (x
, 0)))
3355 case QImode
: fputs ("b", file
); return;
3356 case HImode
: fputs ("w", file
); return;
3361 if (GET_MODE (x
) != HImode
)
3363 fputs ("sat16", file
);
3366 output_operand_lossage ("invalid operand to %%O code"); return;
3368 if (GET_CODE (x
) == SYMBOL_REF
)
3370 assemble_name (file
, XSTR (x
, 0));
3375 if (TARGET_ANNOTATE_ALIGN
&& cfun
->machine
->size_reason
)
3376 fprintf (file
, "; unalign: %d", cfun
->machine
->unalign
);
3392 output_operand_lossage ("invalid operand output code");
3395 switch (GET_CODE (x
))
3398 fputs (reg_names
[REGNO (x
)], file
);
3402 rtx addr
= XEXP (x
, 0);
3403 int size
= GET_MODE_SIZE (GET_MODE (x
));
3407 switch (GET_CODE (addr
))
3409 case PRE_INC
: case POST_INC
:
3410 output_address (VOIDmode
,
3411 plus_constant (Pmode
, XEXP (addr
, 0), size
)); break;
3412 case PRE_DEC
: case POST_DEC
:
3413 output_address (VOIDmode
,
3414 plus_constant (Pmode
, XEXP (addr
, 0), -size
));
3416 case PRE_MODIFY
: case POST_MODIFY
:
3417 output_address (VOIDmode
, XEXP (addr
, 1)); break;
3421 output_address (VOIDmode
,
3422 plus_constant (Pmode
, XEXP (addr
, 0),
3423 (INTVAL (XEXP (addr
, 1))
3424 >> (size
== 2 ? 1 : 2))));
3428 output_address (VOIDmode
, addr
);
3431 if (flag_pic
&& CONSTANT_ADDRESS_P (addr
))
3432 arc_output_pic_addr_const (file
, addr
, code
);
3434 output_address (VOIDmode
, addr
);
3441 /* We handle SFmode constants here as output_addr_const doesn't. */
3442 if (GET_MODE (x
) == SFmode
)
3446 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x
), l
);
3447 fprintf (file
, "0x%08lx", l
);
3450 /* Fall through. Let output_addr_const deal with it. */
3453 || (GET_CODE (x
) == CONST
3454 && GET_CODE (XEXP (x
, 0)) == UNSPEC
3455 && (XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_OFF
3456 || XINT (XEXP (x
, 0), 1) == UNSPEC_TLS_GD
))
3457 || (GET_CODE (x
) == CONST
3458 && GET_CODE (XEXP (x
, 0)) == PLUS
3459 && GET_CODE (XEXP (XEXP (x
, 0), 0)) == UNSPEC
3460 && (XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_OFF
3461 || XINT (XEXP (XEXP (x
, 0), 0), 1) == UNSPEC_TLS_GD
)))
3462 arc_output_pic_addr_const (file
, x
, code
);
3465 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3466 with asm_output_symbol_ref */
3467 if (GET_CODE (x
) == CONST
&& GET_CODE (XEXP (x
, 0)) == PLUS
)
3470 output_addr_const (file
, XEXP (x
, 0));
3471 if (GET_CODE (XEXP (x
, 0)) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (XEXP (x
, 0)))
3472 fprintf (file
, "@sda");
3474 if (GET_CODE (XEXP (x
, 1)) != CONST_INT
3475 || INTVAL (XEXP (x
, 1)) >= 0)
3476 fprintf (file
, "+");
3477 output_addr_const (file
, XEXP (x
, 1));
3480 output_addr_const (file
, x
);
3482 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
3483 fprintf (file
, "@sda");
3488 /* Print a memory address as an operand to reference that memory location. */
3491 arc_print_operand_address (FILE *file
, rtx addr
)
3493 register rtx base
, index
= 0;
3495 switch (GET_CODE (addr
))
3498 fputs (reg_names
[REGNO (addr
)], file
);
3501 output_addr_const (file
, addr
);
3502 if (SYMBOL_REF_SMALL_P (addr
))
3503 fprintf (file
, "@sda");
3506 if (GET_CODE (XEXP (addr
, 0)) == MULT
)
3507 index
= XEXP (XEXP (addr
, 0), 0), base
= XEXP (addr
, 1);
3508 else if (CONST_INT_P (XEXP (addr
, 0)))
3509 index
= XEXP (addr
, 0), base
= XEXP (addr
, 1);
3511 base
= XEXP (addr
, 0), index
= XEXP (addr
, 1);
3513 gcc_assert (OBJECT_P (base
));
3514 arc_print_operand_address (file
, base
);
3515 if (CONSTANT_P (base
) && CONST_INT_P (index
))
3519 gcc_assert (OBJECT_P (index
));
3520 arc_print_operand_address (file
, index
);
3524 rtx c
= XEXP (addr
, 0);
3526 if ((GET_CODE (c
) == UNSPEC
3527 && (XINT (c
, 1) == UNSPEC_TLS_OFF
3528 || XINT (c
, 1) == UNSPEC_TLS_IE
))
3529 || (GET_CODE (c
) == PLUS
3530 && GET_CODE (XEXP (c
, 0)) == UNSPEC
3531 && (XINT (XEXP (c
, 0), 1) == UNSPEC_TLS_OFF
)))
3533 arc_output_pic_addr_const (file
, c
, 0);
3536 gcc_assert (GET_CODE (c
) == PLUS
);
3537 gcc_assert (GET_CODE (XEXP (c
, 0)) == SYMBOL_REF
);
3538 gcc_assert (GET_CODE (XEXP (c
, 1)) == CONST_INT
);
3540 output_address (VOIDmode
, XEXP (addr
, 0));
3546 /* We shouldn't get here as we've lost the mode of the memory object
3547 (which says how much to inc/dec by. */
3552 arc_output_pic_addr_const (file
, addr
, 0);
3554 output_addr_const (file
, addr
);
3559 /* Called via walk_stores. DATA points to a hash table we can use to
3560 establish a unique SYMBOL_REF for each counter, which corresponds to
3561 a caller-callee pair.
3562 X is a store which we want to examine for an UNSPEC_PROF, which
3563 would be an address loaded into a register, or directly used in a MEM.
3564 If we found an UNSPEC_PROF, if we encounter a new counter the first time,
3565 write out a description and a data allocation for a 32 bit counter.
3566 Also, fill in the appropriate symbol_ref into each UNSPEC_PROF instance. */
3569 write_profile_sections (rtx dest ATTRIBUTE_UNUSED
, rtx x
, void *data
)
3572 htab_t htab
= (htab_t
) data
;
3575 if (GET_CODE (x
) != SET
)
3577 srcp
= &SET_SRC (x
);
3579 srcp
= &XEXP (*srcp
, 0);
3580 else if (MEM_P (SET_DEST (x
)))
3581 srcp
= &XEXP (SET_DEST (x
), 0);
3583 if (GET_CODE (src
) != CONST
)
3585 src
= XEXP (src
, 0);
3586 if (GET_CODE (src
) != UNSPEC
|| XINT (src
, 1) != UNSPEC_PROF
)
3589 gcc_assert (XVECLEN (src
, 0) == 3);
3590 if (!htab_elements (htab
))
3592 output_asm_insn (".section .__arc_profile_desc, \"a\"\n"
3594 &XVECEXP (src
, 0, 0));
3596 slot
= (rtx
*) htab_find_slot (htab
, src
, INSERT
);
3597 if (*slot
== HTAB_EMPTY_ENTRY
)
3599 static int count_nr
;
3604 sprintf (buf
, "__prof_count%d", count_nr
++);
3605 count
= gen_rtx_SYMBOL_REF (Pmode
, xstrdup (buf
));
3606 XVECEXP (src
, 0, 2) = count
;
3607 output_asm_insn (".section\t.__arc_profile_desc, \"a\"\n"
3609 "\t.section\t.__arc_profile_counters, \"aw\"\n"
3610 "\t.type\t%o2, @object\n"
3613 &XVECEXP (src
, 0, 0));
3617 *srcp
= XVECEXP (*slot
, 0, 2);
3620 /* Hash function for UNSPEC_PROF htab. Use both the caller's name and
3621 the callee's name (if known). */
3624 unspec_prof_hash (const void *x
)
3626 const_rtx u
= (const_rtx
) x
;
3627 const_rtx s1
= XVECEXP (u
, 0, 1);
3629 return (htab_hash_string (XSTR (XVECEXP (u
, 0, 0), 0))
3630 ^ (s1
->code
== SYMBOL_REF
? htab_hash_string (XSTR (s1
, 0)) : 0));
3633 /* Equality function for UNSPEC_PROF htab. Two pieces of UNSPEC_PROF rtl
3634 shall refer to the same counter if both caller name and callee rtl
3638 unspec_prof_htab_eq (const void *x
, const void *y
)
3640 const_rtx u0
= (const_rtx
) x
;
3641 const_rtx u1
= (const_rtx
) y
;
3642 const_rtx s01
= XVECEXP (u0
, 0, 1);
3643 const_rtx s11
= XVECEXP (u1
, 0, 1);
3645 return (!strcmp (XSTR (XVECEXP (u0
, 0, 0), 0),
3646 XSTR (XVECEXP (u1
, 0, 0), 0))
3647 && rtx_equal_p (s01
, s11
));
3650 /* Conditional execution support.
3652 This is based on the ARM port but for now is much simpler.
3654 A finite state machine takes care of noticing whether or not instructions
3655 can be conditionally executed, and thus decrease execution time and code
3656 size by deleting branch instructions. The fsm is controlled by
3657 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
3658 actions of PRINT_OPERAND. The patterns in the .md file for the branch
3659 insns also have a hand in this. */
3660 /* The way we leave dealing with non-anulled or annull-false delay slot
3661 insns to the consumer is awkward. */
3663 /* The state of the fsm controlling condition codes are:
3664 0: normal, do nothing special
3665 1: don't output this insn
3666 2: don't output this insn
3667 3: make insns conditional
3668 4: make insns conditional
3669 5: make insn conditional (only for outputting anulled delay slot insns)
3671 special value for cfun->machine->uid_ccfsm_state:
3672 6: return with but one insn before it since function start / call
3674 State transitions (state->state by whom, under what condition):
3675 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
3677 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
3678 by zero or more non-jump insns and an unconditional branch with
3679 the same target label as the condbranch.
3680 1 -> 3 branch patterns, after having not output the conditional branch
3681 2 -> 4 branch patterns, after having not output the conditional branch
3682 0 -> 5 branch patterns, for anulled delay slot insn.
3683 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
3684 (the target label has CODE_LABEL_NUMBER equal to
3685 arc_ccfsm_target_label).
3686 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
3687 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
3688 5 -> 0 when outputting the delay slot insn
3690 If the jump clobbers the conditions then we use states 2 and 4.
3692 A similar thing can be done with conditional return insns.
3694 We also handle separating branches from sets of the condition code.
3695 This is done here because knowledge of the ccfsm state is required,
3696 we may not be outputting the branch. */
3698 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
3699 before letting final output INSN. */
3702 arc_ccfsm_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
3704 /* BODY will hold the body of INSN. */
3707 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
3708 an if/then/else), and things need to be reversed. */
3711 /* If we start with a return insn, we only succeed if we find another one. */
3712 int seeking_return
= 0;
3714 /* START_INSN will hold the insn from where we start looking. This is the
3715 first insn after the following code_label if REVERSE is true. */
3716 rtx_insn
*start_insn
= insn
;
3718 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
3719 since they don't rely on a cmp preceding the. */
3720 enum attr_type jump_insn_type
;
3722 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
3723 We can't do this in macro FINAL_PRESCAN_INSN because its called from
3724 final_scan_insn which has `optimize' as a local. */
3725 if (optimize
< 2 || TARGET_NO_COND_EXEC
)
3728 /* Ignore notes and labels. */
3731 body
= PATTERN (insn
);
3732 /* If in state 4, check if the target branch is reached, in order to
3733 change back to state 0. */
3734 if (state
->state
== 4)
3736 if (insn
== state
->target_insn
)
3738 state
->target_insn
= NULL
;
3744 /* If in state 3, it is possible to repeat the trick, if this insn is an
3745 unconditional branch to a label, and immediately following this branch
3746 is the previous target label which is only used once, and the label this
3747 branch jumps to is not too far off. Or in other words "we've done the
3748 `then' part, see if we can do the `else' part." */
3749 if (state
->state
== 3)
3751 if (simplejump_p (insn
))
3753 start_insn
= next_nonnote_insn (start_insn
);
3754 if (GET_CODE (start_insn
) == BARRIER
)
3756 /* ??? Isn't this always a barrier? */
3757 start_insn
= next_nonnote_insn (start_insn
);
3759 if (GET_CODE (start_insn
) == CODE_LABEL
3760 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
3761 && LABEL_NUSES (start_insn
) == 1)
3766 else if (GET_CODE (body
) == SIMPLE_RETURN
)
3768 start_insn
= next_nonnote_insn (start_insn
);
3769 if (GET_CODE (start_insn
) == BARRIER
)
3770 start_insn
= next_nonnote_insn (start_insn
);
3771 if (GET_CODE (start_insn
) == CODE_LABEL
3772 && CODE_LABEL_NUMBER (start_insn
) == state
->target_label
3773 && LABEL_NUSES (start_insn
) == 1)
3785 if (GET_CODE (insn
) != JUMP_INSN
3786 || GET_CODE (PATTERN (insn
)) == ADDR_VEC
3787 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
3790 /* We can't predicate BRCC or loop ends.
3791 Also, when generating PIC code, and considering a medium range call,
3792 we can't predicate the call. */
3793 jump_insn_type
= get_attr_type (insn
);
3794 if (jump_insn_type
== TYPE_BRCC
3795 || jump_insn_type
== TYPE_BRCC_NO_DELAY_SLOT
3796 || jump_insn_type
== TYPE_LOOP_END
3797 || (jump_insn_type
== TYPE_CALL
&& !get_attr_predicable (insn
)))
3800 /* This jump might be paralleled with a clobber of the condition codes,
3801 the jump should always come first. */
3802 if (GET_CODE (body
) == PARALLEL
&& XVECLEN (body
, 0) > 0)
3803 body
= XVECEXP (body
, 0, 0);
3806 || (GET_CODE (body
) == SET
&& GET_CODE (SET_DEST (body
)) == PC
3807 && GET_CODE (SET_SRC (body
)) == IF_THEN_ELSE
))
3809 int insns_skipped
= 0, fail
= FALSE
, succeed
= FALSE
;
3810 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
3811 int then_not_else
= TRUE
;
3812 /* Nonzero if next insn must be the target label. */
3813 int next_must_be_target_label_p
;
3814 rtx_insn
*this_insn
= start_insn
;
3817 /* Register the insn jumped to. */
3820 if (!seeking_return
)
3821 label
= XEXP (SET_SRC (body
), 0);
3823 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == LABEL_REF
)
3824 label
= XEXP (XEXP (SET_SRC (body
), 1), 0);
3825 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == LABEL_REF
)
3827 label
= XEXP (XEXP (SET_SRC (body
), 2), 0);
3828 then_not_else
= FALSE
;
3830 else if (GET_CODE (XEXP (SET_SRC (body
), 1)) == SIMPLE_RETURN
)
3832 else if (GET_CODE (XEXP (SET_SRC (body
), 2)) == SIMPLE_RETURN
)
3835 then_not_else
= FALSE
;
3840 /* If this is a non-annulled branch with a delay slot, there is
3841 no need to conditionalize the delay slot. */
3842 if (NEXT_INSN (PREV_INSN (insn
)) != insn
3843 && state
->state
== 0 && !INSN_ANNULLED_BRANCH_P (insn
))
3845 this_insn
= NEXT_INSN (this_insn
);
3846 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn
)))
3847 == NEXT_INSN (this_insn
));
3849 /* See how many insns this branch skips, and what kind of insns. If all
3850 insns are okay, and the label or unconditional branch to the same
3851 label is not too far away, succeed. */
3852 for (insns_skipped
= 0, next_must_be_target_label_p
= FALSE
;
3853 !fail
&& !succeed
&& insns_skipped
< MAX_INSNS_SKIPPED
;
3858 this_insn
= next_nonnote_insn (this_insn
);
3862 if (next_must_be_target_label_p
)
3864 if (GET_CODE (this_insn
) == BARRIER
)
3866 if (GET_CODE (this_insn
) == CODE_LABEL
3867 && this_insn
== label
)
3877 scanbody
= PATTERN (this_insn
);
3879 switch (GET_CODE (this_insn
))
3882 /* Succeed if it is the target label, otherwise fail since
3883 control falls in from somewhere else. */
3884 if (this_insn
== label
)
3894 /* Succeed if the following insn is the target label.
3896 If return insns are used then the last insn in a function
3897 will be a barrier. */
3898 next_must_be_target_label_p
= TRUE
;
3902 /* Can handle a call insn if there are no insns after it.
3903 IE: The next "insn" is the target label. We don't have to
3904 worry about delay slots as such insns are SEQUENCE's inside
3905 INSN's. ??? It is possible to handle such insns though. */
3906 if (get_attr_cond (this_insn
) == COND_CANUSE
)
3907 next_must_be_target_label_p
= TRUE
;
3913 /* If this is an unconditional branch to the same label, succeed.
3914 If it is to another label, do nothing. If it is conditional,
3916 /* ??? Probably, the test for the SET and the PC are
3919 if (GET_CODE (scanbody
) == SET
3920 && GET_CODE (SET_DEST (scanbody
)) == PC
)
3922 if (GET_CODE (SET_SRC (scanbody
)) == LABEL_REF
3923 && XEXP (SET_SRC (scanbody
), 0) == label
&& !reverse
)
3928 else if (GET_CODE (SET_SRC (scanbody
)) == IF_THEN_ELSE
)
3930 else if (get_attr_cond (this_insn
) != COND_CANUSE
)
3933 else if (GET_CODE (scanbody
) == SIMPLE_RETURN
3939 else if (GET_CODE (scanbody
) == PARALLEL
)
3941 if (get_attr_cond (this_insn
) != COND_CANUSE
)
3947 /* We can only do this with insns that can use the condition
3948 codes (and don't set them). */
3949 if (GET_CODE (scanbody
) == SET
3950 || GET_CODE (scanbody
) == PARALLEL
)
3952 if (get_attr_cond (this_insn
) != COND_CANUSE
)
3955 /* We can't handle other insns like sequences. */
3967 if ((!seeking_return
) && (state
->state
== 1 || reverse
))
3968 state
->target_label
= CODE_LABEL_NUMBER (label
);
3969 else if (seeking_return
|| state
->state
== 2)
3971 while (this_insn
&& GET_CODE (PATTERN (this_insn
)) == USE
)
3973 this_insn
= next_nonnote_insn (this_insn
);
3975 gcc_assert (!this_insn
||
3976 (GET_CODE (this_insn
) != BARRIER
3977 && GET_CODE (this_insn
) != CODE_LABEL
));
3981 /* Oh dear! we ran off the end, give up. */
3982 extract_insn_cached (insn
);
3984 state
->target_insn
= NULL
;
3987 state
->target_insn
= this_insn
;
3992 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
3996 state
->cond
= XEXP (SET_SRC (body
), 0);
3997 state
->cc
= get_arc_condition_code (XEXP (SET_SRC (body
), 0));
4000 if (reverse
|| then_not_else
)
4001 state
->cc
= ARC_INVERSE_CONDITION_CODE (state
->cc
);
4004 /* Restore recog_operand. Getting the attributes of other insns can
4005 destroy this array, but final.c assumes that it remains intact
4006 across this call; since the insn has been recognized already we
4007 call insn_extract direct. */
4008 extract_insn_cached (insn
);
4012 /* Record that we are currently outputting label NUM with prefix PREFIX.
4013 It it's the label we're looking for, reset the ccfsm machinery.
4015 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4018 arc_ccfsm_at_label (const char *prefix
, int num
, struct arc_ccfsm
*state
)
4020 if (state
->state
== 3 && state
->target_label
== num
4021 && !strcmp (prefix
, "L"))
4024 state
->target_insn
= NULL
;
4028 /* We are considering a conditional branch with the condition COND.
4029 Check if we want to conditionalize a delay slot insn, and if so modify
4030 the ccfsm state accordingly.
4031 REVERSE says branch will branch when the condition is false. */
4033 arc_ccfsm_record_condition (rtx cond
, bool reverse
, rtx_insn
*jump
,
4034 struct arc_ccfsm
*state
)
4036 rtx_insn
*seq_insn
= NEXT_INSN (PREV_INSN (jump
));
4038 state
= &arc_ccfsm_current
;
4040 gcc_assert (state
->state
== 0);
4041 if (seq_insn
!= jump
)
4043 rtx insn
= XVECEXP (PATTERN (seq_insn
), 0, 1);
4045 if (!as_a
<rtx_insn
*> (insn
)->deleted ()
4046 && INSN_ANNULLED_BRANCH_P (jump
)
4047 && (TARGET_AT_DBR_CONDEXEC
|| INSN_FROM_TARGET_P (insn
)))
4050 state
->cc
= get_arc_condition_code (cond
);
4052 arc_ccfsm_current
.cc
4053 = ARC_INVERSE_CONDITION_CODE (state
->cc
);
4054 rtx pat
= PATTERN (insn
);
4055 if (GET_CODE (pat
) == COND_EXEC
)
4056 gcc_assert ((INSN_FROM_TARGET_P (insn
)
4057 ? ARC_INVERSE_CONDITION_CODE (state
->cc
) : state
->cc
)
4058 == get_arc_condition_code (XEXP (pat
, 0)));
4065 /* Update *STATE as we would when we emit INSN. */
4068 arc_ccfsm_post_advance (rtx_insn
*insn
, struct arc_ccfsm
*state
)
4070 enum attr_type type
;
4073 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn
), state
);
4074 else if (JUMP_P (insn
)
4075 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
4076 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
4077 && ((type
= get_attr_type (insn
)) == TYPE_BRANCH
4078 || (type
== TYPE_UNCOND_BRANCH
4079 /* ??? Maybe should also handle TYPE_RETURN here,
4080 but we don't have a testcase for that. */
4081 && ARC_CCFSM_BRANCH_DELETED_P (state
))))
4083 if (ARC_CCFSM_BRANCH_DELETED_P (state
))
4084 ARC_CCFSM_RECORD_BRANCH_DELETED (state
);
4087 rtx src
= SET_SRC (PATTERN (insn
));
4088 arc_ccfsm_record_condition (XEXP (src
, 0), XEXP (src
, 1) == pc_rtx
,
4092 else if (arc_ccfsm_current
.state
== 5)
4093 arc_ccfsm_current
.state
= 0;
4096 /* Return true if the current insn, which is a conditional branch, is to be
4100 arc_ccfsm_branch_deleted_p (void)
4102 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current
);
4105 /* Record a branch isn't output because subsequent insns can be
4109 arc_ccfsm_record_branch_deleted (void)
4111 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current
);
4114 /* During insn output, indicate if the current insn is predicated. */
4117 arc_ccfsm_cond_exec_p (void)
4119 return (cfun
->machine
->prescan_initialized
4120 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current
));
4123 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4124 and look inside SEQUENCEs. */
4127 arc_next_active_insn (rtx_insn
*insn
, struct arc_ccfsm
*statep
)
4134 arc_ccfsm_post_advance (insn
, statep
);
4135 insn
= NEXT_INSN (insn
);
4136 if (!insn
|| BARRIER_P (insn
))
4139 arc_ccfsm_advance (insn
, statep
);
4141 while (NOTE_P (insn
)
4142 || (cfun
->machine
->arc_reorg_started
4143 && LABEL_P (insn
) && !label_to_alignment (insn
))
4144 || (NONJUMP_INSN_P (insn
)
4145 && (GET_CODE (PATTERN (insn
)) == USE
4146 || GET_CODE (PATTERN (insn
)) == CLOBBER
)));
4147 if (!LABEL_P (insn
))
4149 gcc_assert (INSN_P (insn
));
4150 pat
= PATTERN (insn
);
4151 if (GET_CODE (pat
) == ADDR_VEC
|| GET_CODE (pat
) == ADDR_DIFF_VEC
)
4153 if (GET_CODE (pat
) == SEQUENCE
)
4154 return as_a
<rtx_insn
*> (XVECEXP (pat
, 0, 0));
4159 /* When deciding if an insn should be output short, we want to know something
4160 about the following insns:
4161 - if another insn follows which we know we can output as a short insn
4162 before an alignment-sensitive point, we can output this insn short:
4163 the decision about the eventual alignment can be postponed.
4164 - if a to-be-aligned label comes next, we should output this insn such
4165 as to get / preserve 4-byte alignment.
4166 - if a likely branch without delay slot insn, or a call with an immediately
4167 following short insn comes next, we should out output this insn such as to
4168 get / preserve 2 mod 4 unalignment.
4169 - do the same for a not completely unlikely branch with a short insn
4170 following before any other branch / label.
4171 - in order to decide if we are actually looking at a branch, we need to
4172 call arc_ccfsm_advance.
4173 - in order to decide if we are looking at a short insn, we should know
4174 if it is conditionalized. To a first order of approximation this is
4175 the case if the state from arc_ccfsm_advance from before this insn
4176 indicates the insn is conditionalized. However, a further refinement
4177 could be to not conditionalize an insn if the destination register(s)
4178 is/are dead in the non-executed case. */
4179 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4180 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4181 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4184 arc_verify_short (rtx_insn
*insn
, int, int check_attr
)
4186 enum attr_iscompact iscompact
;
4187 struct machine_function
*machine
;
4191 iscompact
= get_attr_iscompact (insn
);
4192 if (iscompact
== ISCOMPACT_FALSE
)
4195 machine
= cfun
->machine
;
4197 if (machine
->force_short_suffix
>= 0)
4198 return machine
->force_short_suffix
;
4200 return (get_attr_length (insn
) & 2) != 0;
4203 /* When outputting an instruction (alternative) that can potentially be short,
4204 output the short suffix if the insn is in fact short, and update
4205 cfun->machine->unalign accordingly. */
4208 output_short_suffix (FILE *file
)
4210 rtx_insn
*insn
= current_output_insn
;
4212 if (arc_verify_short (insn
, cfun
->machine
->unalign
, 1))
4214 fprintf (file
, "_s");
4215 cfun
->machine
->unalign
^= 2;
4217 /* Restore recog_operand. */
4218 extract_insn_cached (insn
);
4221 /* Implement FINAL_PRESCAN_INSN. */
4224 arc_final_prescan_insn (rtx_insn
*insn
, rtx
*opvec ATTRIBUTE_UNUSED
,
4225 int noperands ATTRIBUTE_UNUSED
)
4227 if (TARGET_DUMPISIZE
)
4228 fprintf (asm_out_file
, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn
)));
4230 /* Output a nop if necessary to prevent a hazard.
4231 Don't do this for delay slots: inserting a nop would
4232 alter semantics, and the only time we would find a hazard is for a
4233 call function result - and in that case, the hazard is spurious to
4235 if (PREV_INSN (insn
)
4236 && PREV_INSN (NEXT_INSN (insn
)) == insn
4237 && arc_hazard (prev_real_insn (insn
), insn
))
4239 current_output_insn
=
4240 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn
)));
4241 final_scan_insn (current_output_insn
, asm_out_file
, optimize
, 1, NULL
);
4242 current_output_insn
= insn
;
4244 /* Restore extraction data which might have been clobbered by arc_hazard. */
4245 extract_constrain_insn_cached (insn
);
4247 if (!cfun
->machine
->prescan_initialized
)
4249 /* Clear lingering state from branch shortening. */
4250 memset (&arc_ccfsm_current
, 0, sizeof arc_ccfsm_current
);
4251 cfun
->machine
->prescan_initialized
= 1;
4253 arc_ccfsm_advance (insn
, &arc_ccfsm_current
);
4255 cfun
->machine
->size_reason
= 0;
4258 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4259 Frame pointer elimination is automatically handled.
4261 All eliminations are permissible. If we need a frame
4262 pointer, we must eliminate ARG_POINTER_REGNUM into
4263 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4266 arc_can_eliminate (const int from ATTRIBUTE_UNUSED
, const int to
)
4268 return to
== FRAME_POINTER_REGNUM
|| !arc_frame_pointer_required ();
4271 /* Define the offset between two registers, one to be eliminated, and
4272 the other its replacement, at the start of a routine. */
4275 arc_initial_elimination_offset (int from
, int to
)
4277 if (! cfun
->machine
->frame_info
.initialized
)
4278 arc_compute_frame_size (get_frame_size ());
4280 if (from
== ARG_POINTER_REGNUM
&& to
== FRAME_POINTER_REGNUM
)
4282 return (cfun
->machine
->frame_info
.extra_size
4283 + cfun
->machine
->frame_info
.reg_size
);
4286 if (from
== ARG_POINTER_REGNUM
&& to
== STACK_POINTER_REGNUM
)
4288 return (cfun
->machine
->frame_info
.total_size
4289 - cfun
->machine
->frame_info
.pretend_size
);
4292 if ((from
== FRAME_POINTER_REGNUM
) && (to
== STACK_POINTER_REGNUM
))
4294 return (cfun
->machine
->frame_info
.total_size
4295 - (cfun
->machine
->frame_info
.pretend_size
4296 + cfun
->machine
->frame_info
.extra_size
4297 + cfun
->machine
->frame_info
.reg_size
));
4304 arc_frame_pointer_required (void)
4306 return cfun
->calls_alloca
;
4310 /* Return the destination address of a branch. */
4313 branch_dest (rtx branch
)
4315 rtx pat
= PATTERN (branch
);
4316 rtx dest
= (GET_CODE (pat
) == PARALLEL
4317 ? SET_SRC (XVECEXP (pat
, 0, 0)) : SET_SRC (pat
));
4320 if (GET_CODE (dest
) == IF_THEN_ELSE
)
4321 dest
= XEXP (dest
, XEXP (dest
, 1) == pc_rtx
? 2 : 1);
4323 dest
= XEXP (dest
, 0);
4324 dest_uid
= INSN_UID (dest
);
4326 return INSN_ADDRESSES (dest_uid
);
4330 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4333 arc_encode_section_info (tree decl
, rtx rtl
, int first
)
4335 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4336 This clears machine specific flags, so has to come first. */
4337 default_encode_section_info (decl
, rtl
, first
);
4339 /* Check if it is a function, and whether it has the
4340 [long/medium/short]_call attribute specified. */
4341 if (TREE_CODE (decl
) == FUNCTION_DECL
)
4343 rtx symbol
= XEXP (rtl
, 0);
4344 int flags
= SYMBOL_REF_FLAGS (symbol
);
4346 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4347 ? TYPE_ATTRIBUTES (TREE_TYPE (decl
)) : NULL_TREE
);
4348 tree long_call_attr
= lookup_attribute ("long_call", attr
);
4349 tree medium_call_attr
= lookup_attribute ("medium_call", attr
);
4350 tree short_call_attr
= lookup_attribute ("short_call", attr
);
4352 if (long_call_attr
!= NULL_TREE
)
4353 flags
|= SYMBOL_FLAG_LONG_CALL
;
4354 else if (medium_call_attr
!= NULL_TREE
)
4355 flags
|= SYMBOL_FLAG_MEDIUM_CALL
;
4356 else if (short_call_attr
!= NULL_TREE
)
4357 flags
|= SYMBOL_FLAG_SHORT_CALL
;
4359 SYMBOL_REF_FLAGS (symbol
) = flags
;
4361 else if (TREE_CODE (decl
) == VAR_DECL
)
4363 rtx symbol
= XEXP (rtl
, 0);
4365 tree attr
= (TREE_TYPE (decl
) != error_mark_node
4366 ? DECL_ATTRIBUTES (decl
) : NULL_TREE
);
4368 tree sec_attr
= lookup_attribute ("section", attr
);
4371 const char *sec_name
4372 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr
)));
4373 if (strcmp (sec_name
, ".cmem") == 0
4374 || strcmp (sec_name
, ".cmem_shared") == 0
4375 || strcmp (sec_name
, ".cmem_private") == 0)
4376 SYMBOL_REF_FLAGS (symbol
) |= SYMBOL_FLAG_CMEM
;
4381 /* This is how to output a definition of an internal numbered label where
4382 PREFIX is the class of label and NUM is the number within the class. */
4384 static void arc_internal_label (FILE *stream
, const char *prefix
, unsigned long labelno
)
4387 arc_ccfsm_at_label (prefix
, labelno
, &arc_ccfsm_current
);
4388 default_internal_label (stream
, prefix
, labelno
);
4391 /* Set the cpu type and print out other fancy things,
4392 at the top of the file. */
4394 static void arc_file_start (void)
4396 default_file_start ();
4397 fprintf (asm_out_file
, "\t.cpu %s\n", arc_cpu_string
);
4400 /* Cost functions. */
4402 /* Compute a (partial) cost for rtx X. Return true if the complete
4403 cost has been computed, and false if subexpressions should be
4404 scanned. In either case, *TOTAL contains the cost result. */
4407 arc_rtx_costs (rtx x
, machine_mode mode
, int outer_code
,
4408 int opno ATTRIBUTE_UNUSED
, int *total
, bool speed
)
4410 int code
= GET_CODE (x
);
4414 /* Small integers are as cheap as registers. */
4417 bool nolimm
= false; /* Can we do without long immediate? */
4418 bool fast
= false; /* Is the result available immediately? */
4419 bool condexec
= false; /* Does this allow conditiobnal execution? */
4420 bool compact
= false; /* Is a 16 bit opcode available? */
4421 /* CONDEXEC also implies that we can have an unconditional
4422 3-address operation. */
4424 nolimm
= compact
= condexec
= false;
4425 if (UNSIGNED_INT6 (INTVAL (x
)))
4426 nolimm
= condexec
= compact
= true;
4429 if (SMALL_INT (INTVAL (x
)))
4430 nolimm
= fast
= true;
4433 case AND
: /* bclr, bmsk, ext[bw] */
4434 if (satisfies_constraint_Ccp (x
) /* bclr */
4435 || satisfies_constraint_C1p (x
) /* bmsk */)
4436 nolimm
= fast
= condexec
= compact
= true;
4438 case IOR
: /* bset */
4439 if (satisfies_constraint_C0p (x
)) /* bset */
4440 nolimm
= fast
= condexec
= compact
= true;
4443 if (satisfies_constraint_C0p (x
)) /* bxor */
4444 nolimm
= fast
= condexec
= true;
4447 if (satisfies_constraint_Crr (x
)) /* ror b,u6 */
4453 /* FIXME: Add target options to attach a small cost if
4454 condexec / compact is not true. */
4463 /* 4 byte values can be fetched as immediate constants -
4464 let's give that the cost of an extra insn. */
4468 *total
= COSTS_N_INSNS (1);
4477 *total
= COSTS_N_INSNS (1);
4480 split_double (x
, &first
, &second
);
4481 *total
= COSTS_N_INSNS (!SMALL_INT (INTVAL (first
))
4482 + !SMALL_INT (INTVAL (second
)));
4486 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4487 If we need more than 12 insns to do a multiply, then go out-of-line,
4488 since the call overhead will be < 10% of the cost of the multiply. */
4492 if (TARGET_BARREL_SHIFTER
)
4494 /* If we want to shift a constant, we need a LIMM. */
4495 /* ??? when the optimizers want to know if a constant should be
4496 hoisted, they ask for the cost of the constant. OUTER_CODE is
4497 insufficient context for shifts since we don't know which operand
4498 we are looking at. */
4499 if (CONSTANT_P (XEXP (x
, 0)))
4501 *total
+= (COSTS_N_INSNS (2)
4502 + rtx_cost (XEXP (x
, 1), mode
, (enum rtx_code
) code
,
4506 *total
= COSTS_N_INSNS (1);
4508 else if (GET_CODE (XEXP (x
, 1)) != CONST_INT
)
4509 *total
= COSTS_N_INSNS (16);
4512 *total
= COSTS_N_INSNS (INTVAL (XEXP ((x
), 1)));
4513 /* ??? want_to_gcse_p can throw negative shift counts at us,
4514 and then panics when it gets a negative cost as result.
4515 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4524 *total
= COSTS_N_INSNS(30);
4526 *total
= COSTS_N_INSNS(1);
4530 if ((TARGET_DPFP
&& GET_MODE (x
) == DFmode
))
4531 *total
= COSTS_N_INSNS (1);
4533 *total
= arc_multcost
;
4534 /* We do not want synth_mult sequences when optimizing
4536 else if (TARGET_MUL64_SET
|| TARGET_ARC700_MPY
)
4537 *total
= COSTS_N_INSNS (1);
4539 *total
= COSTS_N_INSNS (2);
4542 if (GET_CODE (XEXP (x
, 0)) == MULT
4543 && _2_4_8_operand (XEXP (XEXP (x
, 0), 1), VOIDmode
))
4545 *total
+= (rtx_cost (XEXP (x
, 1), mode
, PLUS
, 0, speed
)
4546 + rtx_cost (XEXP (XEXP (x
, 0), 0), mode
, PLUS
, 1, speed
));
4551 if (GET_CODE (XEXP (x
, 1)) == MULT
4552 && _2_4_8_operand (XEXP (XEXP (x
, 1), 1), VOIDmode
))
4554 *total
+= (rtx_cost (XEXP (x
, 0), mode
, PLUS
, 0, speed
)
4555 + rtx_cost (XEXP (XEXP (x
, 1), 0), mode
, PLUS
, 1, speed
));
4561 rtx op0
= XEXP (x
, 0);
4562 rtx op1
= XEXP (x
, 1);
4564 if (GET_CODE (op0
) == ZERO_EXTRACT
&& op1
== const0_rtx
4565 && XEXP (op0
, 1) == const1_rtx
)
4567 /* btst / bbit0 / bbit1:
4568 Small integers and registers are free; everything else can
4569 be put in a register. */
4570 mode
= GET_MODE (XEXP (op0
, 0));
4571 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
4572 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
4575 if (GET_CODE (op0
) == AND
&& op1
== const0_rtx
4576 && satisfies_constraint_C1p (XEXP (op0
, 1)))
4579 *total
= rtx_cost (XEXP (op0
, 0), VOIDmode
, SET
, 1, speed
);
4583 if (GET_CODE (op1
) == NEG
)
4585 /* op0 might be constant, the inside of op1 is rather
4586 unlikely to be so. So swapping the operands might lower
4588 mode
= GET_MODE (op0
);
4589 *total
= (rtx_cost (op0
, mode
, PLUS
, 1, speed
)
4590 + rtx_cost (XEXP (op1
, 0), mode
, PLUS
, 0, speed
));
4595 if (outer_code
== IF_THEN_ELSE
4596 && GET_CODE (XEXP (x
, 0)) == ZERO_EXTRACT
4597 && XEXP (x
, 1) == const0_rtx
4598 && XEXP (XEXP (x
, 0), 1) == const1_rtx
)
4600 /* btst / bbit0 / bbit1:
4601 Small integers and registers are free; everything else can
4602 be put in a register. */
4603 rtx op0
= XEXP (x
, 0);
4605 mode
= GET_MODE (XEXP (op0
, 0));
4606 *total
= (rtx_cost (XEXP (op0
, 0), mode
, SET
, 1, speed
)
4607 + rtx_cost (XEXP (op0
, 2), mode
, SET
, 1, speed
));
4611 /* scc_insn expands into two insns. */
4612 case GTU
: case GEU
: case LEU
:
4614 *total
+= COSTS_N_INSNS (1);
4616 case LTU
: /* might use adc. */
4618 *total
+= COSTS_N_INSNS (1) - 1;
4625 /* Helper used by arc_legitimate_pc_offset_p. */
4628 arc_needs_pcl_p (rtx x
)
4630 register const char *fmt
;
4633 if ((GET_CODE (x
) == UNSPEC
)
4634 && (XVECLEN (x
, 0) == 1)
4635 && (GET_CODE (XVECEXP (x
, 0, 0)) == SYMBOL_REF
))
4636 switch (XINT (x
, 1))
4638 case ARC_UNSPEC_GOT
:
4646 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
4647 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
4651 if (arc_needs_pcl_p (XEXP (x
, i
)))
4654 else if (fmt
[i
] == 'E')
4655 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
4656 if (arc_needs_pcl_p (XVECEXP (x
, i
, j
)))
4663 /* Return true if ADDR is an address that needs to be expressed as an
4664 explicit sum of pcl + offset. */
4667 arc_legitimate_pc_offset_p (rtx addr
)
4669 if (GET_CODE (addr
) != CONST
)
4672 return arc_needs_pcl_p (addr
);
4675 /* Return true if ADDR is a valid pic address.
4676 A valid pic address on arc should look like
4677 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
4680 arc_legitimate_pic_addr_p (rtx addr
)
4682 if (GET_CODE (addr
) == LABEL_REF
)
4684 if (GET_CODE (addr
) != CONST
)
4687 addr
= XEXP (addr
, 0);
4690 if (GET_CODE (addr
) == PLUS
)
4692 if (GET_CODE (XEXP (addr
, 1)) != CONST_INT
)
4694 addr
= XEXP (addr
, 0);
4697 if (GET_CODE (addr
) != UNSPEC
4698 || XVECLEN (addr
, 0) != 1)
4701 /* Must be one of @GOT, @GOTOFF, @tlsgd, tlsie. */
4702 if (XINT (addr
, 1) != ARC_UNSPEC_GOT
4703 && XINT (addr
, 1) != ARC_UNSPEC_GOTOFF
4704 && XINT (addr
, 1) != UNSPEC_TLS_GD
4705 && XINT (addr
, 1) != UNSPEC_TLS_IE
)
4708 if (GET_CODE (XVECEXP (addr
, 0, 0)) != SYMBOL_REF
4709 && GET_CODE (XVECEXP (addr
, 0, 0)) != LABEL_REF
)
4717 /* Return true if OP contains a symbol reference. */
4720 symbolic_reference_mentioned_p (rtx op
)
4722 register const char *fmt
;
4725 if (GET_CODE (op
) == SYMBOL_REF
|| GET_CODE (op
) == LABEL_REF
)
4728 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
4729 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
4735 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
4736 if (symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
)))
4740 else if (fmt
[i
] == 'e' && symbolic_reference_mentioned_p (XEXP (op
, i
)))
4747 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
4748 If SKIP_LOCAL is true, skip symbols that bind locally.
4749 This is used further down in this file, and, without SKIP_LOCAL,
4750 in the addsi3 / subsi3 expanders when generating PIC code. */
4753 arc_raw_symbolic_reference_mentioned_p (rtx op
, bool skip_local
)
4755 register const char *fmt
;
4758 if (GET_CODE(op
) == UNSPEC
)
4761 if (GET_CODE (op
) == SYMBOL_REF
)
4763 if (SYMBOL_REF_TLS_MODEL (op
))
4767 tree decl
= SYMBOL_REF_DECL (op
);
4768 return !skip_local
|| !decl
|| !default_binds_local_p (decl
);
4771 fmt
= GET_RTX_FORMAT (GET_CODE (op
));
4772 for (i
= GET_RTX_LENGTH (GET_CODE (op
)) - 1; i
>= 0; i
--)
4778 for (j
= XVECLEN (op
, i
) - 1; j
>= 0; j
--)
4779 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op
, i
, j
),
4784 else if (fmt
[i
] == 'e'
4785 && arc_raw_symbolic_reference_mentioned_p (XEXP (op
, i
),
4793 /* Get the thread pointer. */
4798 /* If arc_tp_regno has been set, we can use that hard register
4799 directly as a base register. */
4800 if (arc_tp_regno
!= -1)
4801 return gen_rtx_REG (Pmode
, arc_tp_regno
);
4803 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
4804 conflicts with function arguments / results. */
4805 rtx reg
= gen_reg_rtx (Pmode
);
4806 emit_insn (gen_tls_load_tp_soft ());
4807 emit_move_insn (reg
, gen_rtx_REG (Pmode
, R0_REG
));
4811 /* Helper to be used by TLS Global dynamic model. */
4814 arc_emit_call_tls_get_addr (rtx sym
, int reloc
, rtx eqv
)
4816 rtx r0
= gen_rtx_REG (Pmode
, R0_REG
);
4818 rtx call_fusage
= NULL_RTX
;
4822 rtx x
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, sym
), reloc
);
4823 x
= gen_rtx_CONST (Pmode
, x
);
4824 emit_move_insn (r0
, x
);
4825 use_reg (&call_fusage
, r0
);
4827 gcc_assert (reloc
== UNSPEC_TLS_GD
);
4828 rtx call_insn
= emit_call_insn (gen_tls_gd_get_addr (sym
));
4829 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
4830 way that the application should care. */
4831 RTL_PURE_CALL_P (call_insn
) = 1;
4832 add_function_usage_to (call_insn
, call_fusage
);
4834 insns
= get_insns ();
4837 rtx dest
= gen_reg_rtx (Pmode
);
4838 emit_libcall_block (insns
, dest
, r0
, eqv
);
4842 #define DTPOFF_ZERO_SYM ".tdata"
4844 /* Return a legitimized address for ADDR,
4845 which is a SYMBOL_REF with tls_model MODEL. */
4848 arc_legitimize_tls_address (rtx addr
, enum tls_model model
)
4850 if (!flag_pic
&& model
== TLS_MODEL_LOCAL_DYNAMIC
)
4851 model
= TLS_MODEL_LOCAL_EXEC
;
4855 case TLS_MODEL_LOCAL_DYNAMIC
:
4858 const char *base_name
;
4861 decl
= SYMBOL_REF_DECL (addr
);
4862 base_name
= DTPOFF_ZERO_SYM
;
4863 if (decl
&& bss_initializer_p (decl
))
4864 base_name
= ".tbss";
4866 base
= gen_rtx_SYMBOL_REF (Pmode
, base_name
);
4867 if (strcmp (base_name
, DTPOFF_ZERO_SYM
) == 0)
4871 v
= gen_rtvec (1, addr
);
4874 v
= gen_rtvec (2, addr
, base
);
4875 addr
= gen_rtx_UNSPEC (Pmode
, v
, UNSPEC_TLS_OFF
);
4876 addr
= gen_rtx_CONST (Pmode
, addr
);
4877 base
= arc_legitimize_tls_address (base
, TLS_MODEL_GLOBAL_DYNAMIC
);
4878 return gen_rtx_PLUS (Pmode
, force_reg (Pmode
, base
), addr
);
4879 case TLS_MODEL_GLOBAL_DYNAMIC
:
4880 return arc_emit_call_tls_get_addr (addr
, UNSPEC_TLS_GD
, addr
);
4881 case TLS_MODEL_INITIAL_EXEC
:
4882 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLS_IE
);
4883 addr
= gen_rtx_CONST (Pmode
, addr
);
4884 addr
= copy_to_mode_reg (Pmode
, gen_const_mem (Pmode
, addr
));
4885 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
4886 case TLS_MODEL_LOCAL_EXEC
:
4888 addr
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), UNSPEC_TLS_OFF
);
4889 addr
= gen_rtx_CONST (Pmode
, addr
);
4890 return gen_rtx_PLUS (Pmode
, arc_get_tp (), addr
);
4896 /* Legitimize a pic address reference in ORIG.
4897 The return value is the legitimated address.
4898 If OLDX is non-zero, it is the target to assign the address to first. */
4901 arc_legitimize_pic_address (rtx orig
, rtx oldx
)
4910 if (GET_CODE (addr
) == LABEL_REF
)
4912 else if (GET_CODE (addr
) == SYMBOL_REF
)
4914 enum tls_model model
= SYMBOL_REF_TLS_MODEL (addr
);
4916 return arc_legitimize_tls_address (addr
, model
);
4919 else if (CONSTANT_POOL_ADDRESS_P (addr
) || SYMBOL_REF_LOCAL_P (addr
))
4921 /* This symbol may be referenced via a displacement from the
4922 PIC base address (@GOTOFF). */
4924 /* FIXME: if we had a way to emit pc-relative adds that
4925 don't create a GOT entry, we could do without the use of
4927 crtl
->uses_pic_offset_table
= 1;
4928 pat
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), ARC_UNSPEC_GOTOFF
);
4929 pat
= gen_rtx_CONST (Pmode
, pat
);
4930 pat
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, pat
);
4934 /* This symbol must be referenced via a load from the
4935 Global Offset Table (@GOTPC). */
4936 pat
= gen_rtx_UNSPEC (Pmode
, gen_rtvec (1, addr
), ARC_UNSPEC_GOT
);
4937 pat
= gen_rtx_CONST (Pmode
, pat
);
4938 pat
= gen_const_mem (Pmode
, pat
);
4942 oldx
= gen_reg_rtx (Pmode
);
4944 emit_move_insn (oldx
, pat
);
4949 if (GET_CODE (addr
) == CONST
)
4951 addr
= XEXP (addr
, 0);
4952 if (GET_CODE (addr
) == UNSPEC
)
4954 /* Check that the unspec is one of the ones we generate? */
4957 gcc_assert (GET_CODE (addr
) == PLUS
);
4960 if (GET_CODE (addr
) == PLUS
)
4962 rtx op0
= XEXP (addr
, 0), op1
= XEXP (addr
, 1);
4964 base
= arc_legitimize_pic_address (op0
, oldx
);
4965 pat
= arc_legitimize_pic_address (op1
,
4966 base
== oldx
? NULL_RTX
: oldx
);
4968 if (base
== op0
&& pat
== op1
)
4971 if (GET_CODE (pat
) == CONST_INT
)
4972 pat
= plus_constant (Pmode
, base
, INTVAL (pat
));
4975 if (GET_CODE (pat
) == PLUS
&& CONSTANT_P (XEXP (pat
, 1)))
4977 base
= gen_rtx_PLUS (Pmode
, base
, XEXP (pat
, 0));
4978 pat
= XEXP (pat
, 1);
4980 pat
= gen_rtx_PLUS (Pmode
, base
, pat
);
4988 /* Output address constant X to FILE, taking PIC into account. */
4991 arc_output_pic_addr_const (FILE * file
, rtx x
, int code
)
4996 switch (GET_CODE (x
))
5006 output_addr_const (file
, x
);
5008 /* Local functions do not get references through the PLT. */
5009 if (code
== 'P' && ! SYMBOL_REF_LOCAL_P (x
))
5010 fputs ("@plt", file
);
5014 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (XEXP (x
, 0)));
5015 assemble_name (file
, buf
);
5019 ASM_GENERATE_INTERNAL_LABEL (buf
, "L", CODE_LABEL_NUMBER (x
));
5020 assemble_name (file
, buf
);
5024 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, INTVAL (x
));
5028 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5032 if (GET_MODE (x
) == VOIDmode
)
5034 /* We can use %d if the number is one word and positive. */
5035 if (CONST_DOUBLE_HIGH (x
))
5036 fprintf (file
, HOST_WIDE_INT_PRINT_DOUBLE_HEX
,
5037 CONST_DOUBLE_HIGH (x
), CONST_DOUBLE_LOW (x
));
5038 else if (CONST_DOUBLE_LOW (x
) < 0)
5039 fprintf (file
, HOST_WIDE_INT_PRINT_HEX
, CONST_DOUBLE_LOW (x
));
5041 fprintf (file
, HOST_WIDE_INT_PRINT_DEC
, CONST_DOUBLE_LOW (x
));
5044 /* We can't handle floating point constants;
5045 PRINT_OPERAND must handle them. */
5046 output_operand_lossage ("floating constant misused");
5050 /* FIXME: Not needed here. */
5051 /* Some assemblers need integer constants to appear last (eg masm). */
5052 if (GET_CODE (XEXP (x
, 0)) == CONST_INT
)
5054 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5055 fprintf (file
, "+");
5056 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5058 else if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
5060 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5061 if (INTVAL (XEXP (x
, 1)) >= 0)
5062 fprintf (file
, "+");
5063 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5070 /* Avoid outputting things like x-x or x+5-x,
5071 since some assemblers can't handle that. */
5072 x
= simplify_subtraction (x
);
5073 if (GET_CODE (x
) != MINUS
)
5076 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5077 fprintf (file
, "-");
5078 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
5079 && INTVAL (XEXP (x
, 1)) < 0)
5081 fprintf (file
, "(");
5082 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5083 fprintf (file
, ")");
5086 arc_output_pic_addr_const (file
, XEXP (x
, 1), code
);
5091 arc_output_pic_addr_const (file
, XEXP (x
, 0), code
);
5097 bool pcrel
; pcrel
= false;
5098 rtx base
; base
= NULL
;
5099 gcc_assert (XVECLEN (x
, 0) >= 1);
5100 switch (XINT (x
, 1))
5102 case ARC_UNSPEC_GOT
:
5103 suffix
= "@gotpc", pcrel
= true;
5105 case ARC_UNSPEC_GOTOFF
:
5108 case ARC_UNSPEC_PLT
:
5112 suffix
= "@tlsgd", pcrel
= true;
5115 suffix
= "@tlsie", pcrel
= true;
5117 case UNSPEC_TLS_OFF
:
5118 if (XVECLEN (x
, 0) == 2)
5119 base
= XVECEXP (x
, 0, 1);
5120 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x
, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5121 || (!flag_pic
&& !base
))
5127 suffix
= "@invalid";
5128 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x
,1));
5132 fputs ("pcl,", file
);
5133 arc_output_pic_addr_const (file
, XVECEXP (x
, 0, 0), code
);
5134 fputs (suffix
, file
);
5136 arc_output_pic_addr_const (file
, base
, code
);
5140 output_operand_lossage ("invalid expression as operand");
5144 #define SYMBOLIC_CONST(X) \
5145 (GET_CODE (X) == SYMBOL_REF \
5146 || GET_CODE (X) == LABEL_REF \
5147 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5149 /* Emit insns to move operands[1] into operands[0]. */
5152 prepare_pic_move (rtx
*operands
, machine_mode
)
5154 if (GET_CODE (operands
[0]) == MEM
&& SYMBOLIC_CONST (operands
[1])
5156 operands
[1] = force_reg (Pmode
, operands
[1]);
5159 rtx temp
= (reload_in_progress
? operands
[0]
5160 : flag_pic
? gen_reg_rtx (Pmode
) : NULL_RTX
);
5161 operands
[1] = arc_legitimize_pic_address (operands
[1], temp
);
5166 /* The function returning the number of words, at the beginning of an
5167 argument, must be put in registers. The returned value must be
5168 zero for arguments that are passed entirely in registers or that
5169 are entirely pushed on the stack.
5171 On some machines, certain arguments must be passed partially in
5172 registers and partially in memory. On these machines, typically
5173 the first N words of arguments are passed in registers, and the
5174 rest on the stack. If a multi-word argument (a `double' or a
5175 structure) crosses that boundary, its first few words must be
5176 passed in registers and the rest must be pushed. This function
5177 tells the compiler when this occurs, and how many of the words
5178 should go in registers.
5180 `FUNCTION_ARG' for these arguments should return the first register
5181 to be used by the caller for this argument; likewise
5182 `FUNCTION_INCOMING_ARG', for the called function.
5184 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5186 /* If REGNO is the least arg reg available then what is the total number of arg
5188 #define GPR_REST_ARG_REGS(REGNO) \
5189 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5191 /* Since arc parm regs are contiguous. */
5192 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5194 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5197 arc_arg_partial_bytes (cumulative_args_t cum_v
, machine_mode mode
,
5198 tree type
, bool named ATTRIBUTE_UNUSED
)
5200 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5201 int bytes
= (mode
== BLKmode
5202 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5203 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5207 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5208 ret
= GPR_REST_ARG_REGS (arg_num
);
5210 /* ICEd at function.c:2361, and ret is copied to data->partial */
5211 ret
= (ret
>= words
? 0 : ret
* UNITS_PER_WORD
);
5216 /* This function is used to control a function argument is passed in a
5217 register, and which register.
5219 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5220 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5221 all of the previous arguments so far passed in registers; MODE, the
5222 machine mode of the argument; TYPE, the data type of the argument
5223 as a tree node or 0 if that is not known (which happens for C
5224 support library functions); and NAMED, which is 1 for an ordinary
5225 argument and 0 for nameless arguments that correspond to `...' in
5226 the called function's prototype.
5228 The returned value should either be a `reg' RTX for the hard
5229 register in which to pass the argument, or zero to pass the
5230 argument on the stack.
5232 For machines like the Vax and 68000, where normally all arguments
5233 are pushed, zero suffices as a definition.
5235 The usual way to make the ANSI library `stdarg.h' work on a machine
5236 where some arguments are usually passed in registers, is to cause
5237 nameless arguments to be passed on the stack instead. This is done
5238 by making the function return 0 whenever NAMED is 0.
5240 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5241 definition of this function to determine if this argument is of a
5242 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5243 is not defined and the function returns non-zero for such an
5244 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5245 defined, the argument will be computed in the stack and then loaded
5248 The function is used to implement macro FUNCTION_ARG. */
5249 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5250 and the rest are pushed. */
5253 arc_function_arg (cumulative_args_t cum_v
,
5255 const_tree type ATTRIBUTE_UNUSED
,
5256 bool named ATTRIBUTE_UNUSED
)
5258 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5261 const char *debstr ATTRIBUTE_UNUSED
;
5263 arg_num
= ROUND_ADVANCE_CUM (arg_num
, mode
, type
);
5264 /* Return a marker for use in the call instruction. */
5265 if (mode
== VOIDmode
)
5270 else if (GPR_REST_ARG_REGS (arg_num
) > 0)
5272 ret
= gen_rtx_REG (mode
, arg_num
);
5273 debstr
= reg_names
[arg_num
];
5283 /* The function to update the summarizer variable *CUM to advance past
5284 an argument in the argument list. The values MODE, TYPE and NAMED
5285 describe that argument. Once this is done, the variable *CUM is
5286 suitable for analyzing the *following* argument with
5287 `FUNCTION_ARG', etc.
5289 This function need not do anything if the argument in question was
5290 passed on the stack. The compiler knows how to track the amount of
5291 stack space used for arguments without any special help.
5293 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5294 /* For the ARC: the cum set here is passed on to function_arg where we
5295 look at its value and say which reg to use. Strategy: advance the
5296 regnumber here till we run out of arg regs, then set *cum to last
5297 reg. In function_arg, since *cum > last arg reg we would return 0
5298 and thus the arg will end up on the stack. For straddling args of
5299 course function_arg_partial_nregs will come into play. */
5302 arc_function_arg_advance (cumulative_args_t cum_v
,
5305 bool named ATTRIBUTE_UNUSED
)
5307 CUMULATIVE_ARGS
*cum
= get_cumulative_args (cum_v
);
5308 int bytes
= (mode
== BLKmode
5309 ? int_size_in_bytes (type
) : (int) GET_MODE_SIZE (mode
));
5310 int words
= (bytes
+ UNITS_PER_WORD
- 1) / UNITS_PER_WORD
;
5314 *cum
= ROUND_ADVANCE_CUM (*cum
, mode
, type
);
5315 for (i
= 0; i
< words
; i
++)
5316 *cum
= ARC_NEXT_ARG_REG (*cum
);
5320 /* Define how to find the value returned by a function.
5321 VALTYPE is the data type of the value (as a tree).
5322 If the precise function being called is known, FN_DECL_OR_TYPE is its
5323 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5326 arc_function_value (const_tree valtype
,
5327 const_tree fn_decl_or_type ATTRIBUTE_UNUSED
,
5328 bool outgoing ATTRIBUTE_UNUSED
)
5330 machine_mode mode
= TYPE_MODE (valtype
);
5331 int unsignedp ATTRIBUTE_UNUSED
;
5333 unsignedp
= TYPE_UNSIGNED (valtype
);
5334 if (INTEGRAL_TYPE_P (valtype
) || TREE_CODE (valtype
) == OFFSET_TYPE
)
5335 PROMOTE_MODE (mode
, unsignedp
, valtype
);
5336 return gen_rtx_REG (mode
, 0);
5339 /* Returns the return address that is used by builtin_return_address. */
5342 arc_return_addr_rtx (int count
, ATTRIBUTE_UNUSED rtx frame
)
5347 return get_hard_reg_initial_val (Pmode
, RETURN_ADDR_REGNUM
);
5350 /* Nonzero if the constant value X is a legitimate general operand
5351 when generating PIC code. It is given that flag_pic is on and
5352 that X satisfies CONSTANT_P or is a CONST_DOUBLE. */
5355 arc_legitimate_pic_operand_p (rtx x
)
5357 return !arc_raw_symbolic_reference_mentioned_p (x
, true);
5360 /* Determine if a given RTX is a valid constant. We already know this
5361 satisfies CONSTANT_P. */
5364 arc_legitimate_constant_p (machine_mode mode
, rtx x
)
5366 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_TLS_MODEL (x
))
5369 if (!flag_pic
&& mode
!= Pmode
)
5372 switch (GET_CODE (x
))
5377 if (GET_CODE (x
) == PLUS
)
5380 ? GET_CODE (XEXP (x
, 1)) != CONST_INT
5381 : !arc_legitimate_constant_p (mode
, XEXP (x
, 1)))
5386 /* Only some unspecs are valid as "constants". */
5387 if (GET_CODE (x
) == UNSPEC
)
5388 switch (XINT (x
, 1))
5390 case ARC_UNSPEC_PLT
:
5391 case ARC_UNSPEC_GOTOFF
:
5392 case ARC_UNSPEC_GOT
:
5395 case UNSPEC_TLS_OFF
:
5403 /* We must have drilled down to a symbol. */
5404 if (arc_raw_symbolic_reference_mentioned_p (x
, false))
5411 if (SYMBOL_REF_TLS_MODEL (x
))
5423 /* Otherwise we handle everything else in the move patterns. */
5428 arc_legitimate_address_p (machine_mode mode
, rtx x
, bool strict
)
5430 if (RTX_OK_FOR_BASE_P (x
, strict
))
5432 if (LEGITIMATE_OFFSET_ADDRESS_P (mode
, x
, TARGET_INDEXED_LOADS
, strict
))
5434 if (LEGITIMATE_SCALED_ADDRESS_P (mode
, x
, strict
))
5436 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x
))
5438 if (GET_CODE (x
) == CONST_INT
&& LARGE_INT (INTVAL (x
)))
5441 /* When we compile for size avoid const (@sym + offset)
5443 if (!flag_pic
&& optimize_size
&& !reload_completed
5444 && (GET_CODE (x
) == CONST
)
5445 && (GET_CODE (XEXP (x
, 0)) == PLUS
)
5446 && (GET_CODE (XEXP (XEXP (x
, 0), 0)) == SYMBOL_REF
)
5447 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x
, 0), 0)) == 0
5448 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x
, 0), 0)))
5450 rtx addend
= XEXP (XEXP (x
, 0), 1);
5451 gcc_assert (CONST_INT_P (addend
));
5452 HOST_WIDE_INT offset
= INTVAL (addend
);
5454 /* Allow addresses having a large offset to pass. Anyhow they
5455 will end in a limm. */
5456 return !(offset
> -1024 && offset
< 1020);
5459 if ((GET_MODE_SIZE (mode
) != 16) && CONSTANT_P (x
))
5461 if (flag_pic
? arc_legitimate_pic_addr_p (x
)
5462 : arc_legitimate_constant_p (Pmode
, x
))
5465 if ((GET_CODE (x
) == PRE_DEC
|| GET_CODE (x
) == PRE_INC
5466 || GET_CODE (x
) == POST_DEC
|| GET_CODE (x
) == POST_INC
)
5467 && RTX_OK_FOR_BASE_P (XEXP (x
, 0), strict
))
5469 /* We're restricted here by the `st' insn. */
5470 if ((GET_CODE (x
) == PRE_MODIFY
|| GET_CODE (x
) == POST_MODIFY
)
5471 && GET_CODE (XEXP ((x
), 1)) == PLUS
5472 && rtx_equal_p (XEXP ((x
), 0), XEXP (XEXP (x
, 1), 0))
5473 && LEGITIMATE_OFFSET_ADDRESS_P (QImode
, XEXP (x
, 1),
5474 TARGET_AUTO_MODIFY_REG
, strict
))
5479 /* Return true iff ADDR (a legitimate address expression)
5480 has an effect that depends on the machine mode it is used for. */
5483 arc_mode_dependent_address_p (const_rtx addr
, addr_space_t
)
5485 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5486 which is valid for loads and stores, or a limm offset, which is valid for
5488 /* Scaled indices are scaled by the access mode; likewise for scaled
5489 offsets, which are needed for maximum offset stores. */
5490 if (GET_CODE (addr
) == PLUS
5491 && (GET_CODE (XEXP ((addr
), 0)) == MULT
5492 || (CONST_INT_P (XEXP ((addr
), 1))
5493 && !SMALL_INT (INTVAL (XEXP ((addr
), 1))))))
5498 /* Determine if it's legal to put X into the constant pool. */
5501 arc_cannot_force_const_mem (machine_mode mode
, rtx x
)
5503 return !arc_legitimate_constant_p (mode
, x
);
5506 /* IDs for all the ARC builtins. */
5510 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5511 ARC_BUILTIN_ ## NAME,
5512 #include "builtins.def"
5518 struct GTY(()) arc_builtin_description
5520 enum insn_code icode
;
5525 static GTY(()) struct arc_builtin_description
5526 arc_bdesc
[ARC_BUILTIN_COUNT
] =
5528 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5529 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
5530 #include "builtins.def"
5534 /* Transform UP into lowercase and write the result to LO.
5535 You must provide enough space for LO. Return LO. */
5538 arc_tolower (char *lo
, const char *up
)
5542 for (; *up
; up
++, lo
++)
5543 *lo
= TOLOWER (*up
);
5550 /* Implement `TARGET_BUILTIN_DECL'. */
5553 arc_builtin_decl (unsigned id
, bool initialize_p ATTRIBUTE_UNUSED
)
5555 if (id
< ARC_BUILTIN_COUNT
)
5556 return arc_bdesc
[id
].fndecl
;
5558 return error_mark_node
;
5562 arc_init_builtins (void)
5564 tree V4HI_type_node
;
5565 tree V2SI_type_node
;
5566 tree V2HI_type_node
;
5568 /* Vector types based on HS SIMD elements. */
5569 V4HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V4HImode
);
5570 V2SI_type_node
= build_vector_type_for_mode (intSI_type_node
, V2SImode
);
5571 V2HI_type_node
= build_vector_type_for_mode (intHI_type_node
, V2HImode
);
5573 tree pcvoid_type_node
5574 = build_pointer_type (build_qualified_type (void_type_node
,
5576 tree V8HI_type_node
= build_vector_type_for_mode (intHI_type_node
,
5579 tree void_ftype_void
5580 = build_function_type_list (void_type_node
, NULL_TREE
);
5582 = build_function_type_list (integer_type_node
, integer_type_node
,
5584 tree int_ftype_pcvoid_int
5585 = build_function_type_list (integer_type_node
, pcvoid_type_node
,
5586 integer_type_node
, NULL_TREE
);
5587 tree void_ftype_usint_usint
5588 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
5589 long_unsigned_type_node
, NULL_TREE
);
5590 tree int_ftype_int_int
5591 = build_function_type_list (integer_type_node
, integer_type_node
,
5592 integer_type_node
, NULL_TREE
);
5593 tree usint_ftype_usint
5594 = build_function_type_list (long_unsigned_type_node
,
5595 long_unsigned_type_node
, NULL_TREE
);
5596 tree void_ftype_usint
5597 = build_function_type_list (void_type_node
, long_unsigned_type_node
,
5600 = build_function_type_list (integer_type_node
, void_type_node
,
5603 = build_function_type_list (void_type_node
, integer_type_node
,
5605 tree int_ftype_short
5606 = build_function_type_list (integer_type_node
, short_integer_type_node
,
5609 /* Old ARC SIMD types. */
5610 tree v8hi_ftype_v8hi_v8hi
5611 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
5612 V8HI_type_node
, NULL_TREE
);
5613 tree v8hi_ftype_v8hi_int
5614 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
5615 integer_type_node
, NULL_TREE
);
5616 tree v8hi_ftype_v8hi_int_int
5617 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
5618 integer_type_node
, integer_type_node
,
5620 tree void_ftype_v8hi_int_int
5621 = build_function_type_list (void_type_node
, V8HI_type_node
,
5622 integer_type_node
, integer_type_node
,
5624 tree void_ftype_v8hi_int_int_int
5625 = build_function_type_list (void_type_node
, V8HI_type_node
,
5626 integer_type_node
, integer_type_node
,
5627 integer_type_node
, NULL_TREE
);
5628 tree v8hi_ftype_int_int
5629 = build_function_type_list (V8HI_type_node
, integer_type_node
,
5630 integer_type_node
, NULL_TREE
);
5631 tree void_ftype_int_int
5632 = build_function_type_list (void_type_node
, integer_type_node
,
5633 integer_type_node
, NULL_TREE
);
5634 tree v8hi_ftype_v8hi
5635 = build_function_type_list (V8HI_type_node
, V8HI_type_node
,
5637 /* ARCv2 SIMD types. */
5638 tree long_ftype_v4hi_v4hi
5639 = build_function_type_list (long_long_integer_type_node
,
5640 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
5641 tree int_ftype_v2hi_v2hi
5642 = build_function_type_list (integer_type_node
,
5643 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
5644 tree v2si_ftype_v2hi_v2hi
5645 = build_function_type_list (V2SI_type_node
,
5646 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
5647 tree v2hi_ftype_v2hi_v2hi
5648 = build_function_type_list (V2HI_type_node
,
5649 V2HI_type_node
, V2HI_type_node
, NULL_TREE
);
5650 tree v2si_ftype_v2si_v2si
5651 = build_function_type_list (V2SI_type_node
,
5652 V2SI_type_node
, V2SI_type_node
, NULL_TREE
);
5653 tree v4hi_ftype_v4hi_v4hi
5654 = build_function_type_list (V4HI_type_node
,
5655 V4HI_type_node
, V4HI_type_node
, NULL_TREE
);
5656 tree long_ftype_v2si_v2hi
5657 = build_function_type_list (long_long_integer_type_node
,
5658 V2SI_type_node
, V2HI_type_node
, NULL_TREE
);
5660 /* Add the builtins. */
5661 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5663 int id = ARC_BUILTIN_ ## NAME; \
5664 const char *Name = "__builtin_arc_" #NAME; \
5665 char *name = (char*) alloca (1 + strlen (Name)); \
5667 gcc_assert (id < ARC_BUILTIN_COUNT); \
5669 arc_bdesc[id].fndecl \
5670 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
5671 BUILT_IN_MD, NULL, NULL_TREE); \
5673 #include "builtins.def"
5677 /* Helper to expand __builtin_arc_aligned (void* val, int
5681 arc_expand_builtin_aligned (tree exp
)
5683 tree arg0
= CALL_EXPR_ARG (exp
, 0);
5684 tree arg1
= CALL_EXPR_ARG (exp
, 1);
5686 rtx op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
5687 rtx op1
= expand_expr (arg1
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
5689 if (!CONST_INT_P (op1
))
5691 /* If we can't fold the alignment to a constant integer
5692 whilst optimizing, this is probably a user error. */
5694 warning (0, "__builtin_arc_aligned with non-constant alignment");
5698 HOST_WIDE_INT alignTest
= INTVAL (op1
);
5699 /* Check alignTest is positive, and a power of two. */
5700 if (alignTest
<= 0 || alignTest
!= (alignTest
& -alignTest
))
5702 error ("invalid alignment value for __builtin_arc_aligned");
5706 if (CONST_INT_P (op0
))
5708 HOST_WIDE_INT pnt
= INTVAL (op0
);
5710 if ((pnt
& (alignTest
- 1)) == 0)
5715 unsigned align
= get_pointer_alignment (arg0
);
5716 unsigned numBits
= alignTest
* BITS_PER_UNIT
;
5718 if (align
&& align
>= numBits
)
5720 /* Another attempt to ascertain alignment. Check the type
5721 we are pointing to. */
5722 if (POINTER_TYPE_P (TREE_TYPE (arg0
))
5723 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0
))) >= numBits
)
5728 /* Default to false. */
5732 /* Helper arc_expand_builtin, generates a pattern for the given icode
5736 apply_GEN_FCN (enum insn_code icode
, rtx
*arg
)
5738 switch (insn_data
[icode
].n_generator_args
)
5741 return GEN_FCN (icode
) ();
5743 return GEN_FCN (icode
) (arg
[0]);
5745 return GEN_FCN (icode
) (arg
[0], arg
[1]);
5747 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2]);
5749 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3]);
5751 return GEN_FCN (icode
) (arg
[0], arg
[1], arg
[2], arg
[3], arg
[4]);
5757 /* Expand an expression EXP that calls a built-in function,
5758 with result going to TARGET if that's convenient
5759 (and in mode MODE if that's convenient).
5760 SUBTARGET may be used as the target for computing one of EXP's operands.
5761 IGNORE is nonzero if the value is to be ignored. */
5764 arc_expand_builtin (tree exp
,
5766 rtx subtarget ATTRIBUTE_UNUSED
,
5767 machine_mode mode ATTRIBUTE_UNUSED
,
5768 int ignore ATTRIBUTE_UNUSED
)
5770 tree fndecl
= TREE_OPERAND (CALL_EXPR_FN (exp
), 0);
5771 unsigned int id
= DECL_FUNCTION_CODE (fndecl
);
5772 const struct arc_builtin_description
*d
= &arc_bdesc
[id
];
5773 int i
, j
, n_args
= call_expr_nargs (exp
);
5776 enum insn_code icode
= d
->icode
;
5777 machine_mode tmode
= insn_data
[icode
].operand
[0].mode
;
5794 if (id
>= ARC_BUILTIN_COUNT
)
5795 internal_error ("bad builtin fcode");
5797 /* 1st part: Expand special builtins. */
5800 case ARC_BUILTIN_NOP
:
5801 emit_insn (gen_nopv ());
5804 case ARC_BUILTIN_RTIE
:
5805 case ARC_BUILTIN_SYNC
:
5806 case ARC_BUILTIN_BRK
:
5807 case ARC_BUILTIN_SWI
:
5808 case ARC_BUILTIN_UNIMP_S
:
5809 gcc_assert (icode
!= 0);
5810 emit_insn (GEN_FCN (icode
) (const1_rtx
));
5813 case ARC_BUILTIN_ALIGNED
:
5814 return arc_expand_builtin_aligned (exp
);
5816 case ARC_BUILTIN_CLRI
:
5817 target
= gen_reg_rtx (SImode
);
5818 emit_insn (gen_clri (target
, const1_rtx
));
5821 case ARC_BUILTIN_TRAP_S
:
5822 case ARC_BUILTIN_SLEEP
:
5823 arg0
= CALL_EXPR_ARG (exp
, 0);
5825 op0
= expand_expr (arg0
, NULL_RTX
, VOIDmode
, EXPAND_NORMAL
);
5827 if (!CONST_INT_P (op0
) || !satisfies_constraint_L (op0
))
5829 error ("builtin operand should be an unsigned 6-bit value");
5832 gcc_assert (icode
!= 0);
5833 emit_insn (GEN_FCN (icode
) (op0
));
5836 case ARC_BUILTIN_VDORUN
:
5837 case ARC_BUILTIN_VDIRUN
:
5838 arg0
= CALL_EXPR_ARG (exp
, 0);
5839 arg1
= CALL_EXPR_ARG (exp
, 1);
5840 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5841 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5843 target
= gen_rtx_REG (SImode
, (id
== ARC_BUILTIN_VDIRUN
) ? 131 : 139);
5845 mode0
= insn_data
[icode
].operand
[1].mode
;
5846 mode1
= insn_data
[icode
].operand
[2].mode
;
5848 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
5849 op0
= copy_to_mode_reg (mode0
, op0
);
5851 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
5852 op1
= copy_to_mode_reg (mode1
, op1
);
5854 pat
= GEN_FCN (icode
) (target
, op0
, op1
);
5861 case ARC_BUILTIN_VDIWR
:
5862 case ARC_BUILTIN_VDOWR
:
5863 arg0
= CALL_EXPR_ARG (exp
, 0);
5864 arg1
= CALL_EXPR_ARG (exp
, 1);
5865 op0
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5866 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5868 if (!CONST_INT_P (op0
)
5869 || !(UNSIGNED_INT3 (INTVAL (op0
))))
5870 error ("operand 1 should be an unsigned 3-bit immediate");
5872 mode1
= insn_data
[icode
].operand
[1].mode
;
5874 if (icode
== CODE_FOR_vdiwr_insn
)
5875 target
= gen_rtx_REG (SImode
,
5876 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG
+ INTVAL (op0
));
5877 else if (icode
== CODE_FOR_vdowr_insn
)
5878 target
= gen_rtx_REG (SImode
,
5879 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG
+ INTVAL (op0
));
5883 if (!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
5884 op1
= copy_to_mode_reg (mode1
, op1
);
5886 pat
= GEN_FCN (icode
) (target
, op1
);
5893 case ARC_BUILTIN_VASRW
:
5894 case ARC_BUILTIN_VSR8
:
5895 case ARC_BUILTIN_VSR8AW
:
5896 arg0
= CALL_EXPR_ARG (exp
, 0);
5897 arg1
= CALL_EXPR_ARG (exp
, 1);
5898 op0
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
5899 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5900 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
5902 target
= gen_reg_rtx (V8HImode
);
5903 mode0
= insn_data
[icode
].operand
[1].mode
;
5904 mode1
= insn_data
[icode
].operand
[2].mode
;
5906 if (!insn_data
[icode
].operand
[1].predicate (op0
, mode0
))
5907 op0
= copy_to_mode_reg (mode0
, op0
);
5909 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
5910 || !(UNSIGNED_INT3 (INTVAL (op1
))))
5911 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
5913 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
5920 case ARC_BUILTIN_VLD32WH
:
5921 case ARC_BUILTIN_VLD32WL
:
5922 case ARC_BUILTIN_VLD64
:
5923 case ARC_BUILTIN_VLD32
:
5926 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
5927 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
5928 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
5930 src_vreg
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
5931 op0
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5932 op1
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5933 op2
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
5935 /* target <- src vreg. */
5936 emit_insn (gen_move_insn (target
, src_vreg
));
5938 /* target <- vec_concat: target, mem (Ib, u8). */
5939 mode0
= insn_data
[icode
].operand
[3].mode
;
5940 mode1
= insn_data
[icode
].operand
[1].mode
;
5942 if ((!insn_data
[icode
].operand
[3].predicate (op0
, mode0
))
5943 || !(UNSIGNED_INT3 (INTVAL (op0
))))
5944 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
5946 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
5947 || !(UNSIGNED_INT8 (INTVAL (op1
))))
5948 error ("operand 2 should be an unsigned 8-bit value");
5950 pat
= GEN_FCN (icode
) (target
, op1
, op2
, op0
);
5957 case ARC_BUILTIN_VLD64W
:
5958 case ARC_BUILTIN_VLD128
:
5959 arg0
= CALL_EXPR_ARG (exp
, 0); /* dest vreg. */
5960 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
5962 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
5963 op1
= expand_expr (arg0
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5964 op2
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5966 /* target <- src vreg. */
5967 target
= gen_reg_rtx (V8HImode
);
5969 /* target <- vec_concat: target, mem (Ib, u8). */
5970 mode0
= insn_data
[icode
].operand
[1].mode
;
5971 mode1
= insn_data
[icode
].operand
[2].mode
;
5972 mode2
= insn_data
[icode
].operand
[3].mode
;
5974 if ((!insn_data
[icode
].operand
[2].predicate (op1
, mode1
))
5975 || !(UNSIGNED_INT3 (INTVAL (op1
))))
5976 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
5978 if ((!insn_data
[icode
].operand
[3].predicate (op2
, mode2
))
5979 || !(UNSIGNED_INT8 (INTVAL (op2
))))
5980 error ("operand 2 should be an unsigned 8-bit value");
5982 pat
= GEN_FCN (icode
) (target
, op0
, op1
, op2
);
5990 case ARC_BUILTIN_VST128
:
5991 case ARC_BUILTIN_VST64
:
5992 arg0
= CALL_EXPR_ARG (exp
, 0); /* src vreg. */
5993 arg1
= CALL_EXPR_ARG (exp
, 1); /* [I]0-7. */
5994 arg2
= CALL_EXPR_ARG (exp
, 2); /* u8. */
5996 op0
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
5997 op1
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5998 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
5999 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6001 mode0
= insn_data
[icode
].operand
[0].mode
;
6002 mode1
= insn_data
[icode
].operand
[1].mode
;
6003 mode2
= insn_data
[icode
].operand
[2].mode
;
6004 mode3
= insn_data
[icode
].operand
[3].mode
;
6006 if ((!insn_data
[icode
].operand
[1].predicate (op1
, mode1
))
6007 || !(UNSIGNED_INT3 (INTVAL (op1
))))
6008 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6010 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6011 || !(UNSIGNED_INT8 (INTVAL (op2
))))
6012 error ("operand 3 should be an unsigned 8-bit value");
6014 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6015 op3
= copy_to_mode_reg (mode3
, op3
);
6017 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
);
6024 case ARC_BUILTIN_VST16_N
:
6025 case ARC_BUILTIN_VST32_N
:
6026 arg0
= CALL_EXPR_ARG (exp
, 0); /* source vreg. */
6027 arg1
= CALL_EXPR_ARG (exp
, 1); /* u3. */
6028 arg2
= CALL_EXPR_ARG (exp
, 2); /* [I]0-7. */
6029 arg3
= CALL_EXPR_ARG (exp
, 3); /* u8. */
6031 op0
= expand_expr (arg3
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6032 op1
= gen_rtx_REG (V8HImode
, ARC_FIRST_SIMD_VR_REG
);
6033 op2
= expand_expr (arg2
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6034 op3
= expand_expr (arg0
, NULL_RTX
, V8HImode
, EXPAND_NORMAL
);
6035 op4
= expand_expr (arg1
, NULL_RTX
, SImode
, EXPAND_NORMAL
);
6037 mode0
= insn_data
[icode
].operand
[0].mode
;
6038 mode2
= insn_data
[icode
].operand
[2].mode
;
6039 mode3
= insn_data
[icode
].operand
[3].mode
;
6040 mode4
= insn_data
[icode
].operand
[4].mode
;
6042 /* Do some correctness checks for the operands. */
6043 if ((!insn_data
[icode
].operand
[0].predicate (op0
, mode0
))
6044 || !(UNSIGNED_INT8 (INTVAL (op0
))))
6045 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6047 if ((!insn_data
[icode
].operand
[2].predicate (op2
, mode2
))
6048 || !(UNSIGNED_INT3 (INTVAL (op2
))))
6049 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6051 if (!insn_data
[icode
].operand
[3].predicate (op3
, mode3
))
6052 op3
= copy_to_mode_reg (mode3
, op3
);
6054 if ((!insn_data
[icode
].operand
[4].predicate (op4
, mode4
))
6055 || !(UNSIGNED_INT3 (INTVAL (op4
))))
6056 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6057 else if (icode
== CODE_FOR_vst32_n_insn
6058 && ((INTVAL (op4
) % 2) != 0))
6059 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6061 pat
= GEN_FCN (icode
) (op0
, op1
, op2
, op3
, op4
);
6072 /* 2nd part: Expand regular builtins. */
6074 internal_error ("bad builtin fcode");
6076 nonvoid
= TREE_TYPE (TREE_TYPE (fndecl
)) != void_type_node
;
6081 if (target
== NULL_RTX
6082 || GET_MODE (target
) != tmode
6083 || !insn_data
[icode
].operand
[0].predicate (target
, tmode
))
6085 target
= gen_reg_rtx (tmode
);
6090 gcc_assert (n_args
<= 4);
6091 for (i
= 0; i
< n_args
; i
++, j
++)
6093 tree arg
= CALL_EXPR_ARG (exp
, i
);
6094 machine_mode mode
= insn_data
[icode
].operand
[j
].mode
;
6095 rtx op
= expand_expr (arg
, NULL_RTX
, mode
, EXPAND_NORMAL
);
6096 machine_mode opmode
= GET_MODE (op
);
6097 char c
= insn_data
[icode
].operand
[j
].constraint
[0];
6099 /* SIMD extension requires exact immediate operand match. */
6100 if ((id
> ARC_BUILTIN_SIMD_BEGIN
)
6101 && (id
< ARC_BUILTIN_SIMD_END
)
6105 if (!CONST_INT_P (op
))
6106 error ("builtin requires an immediate for operand %d", j
);
6110 if (!satisfies_constraint_L (op
))
6111 error ("operand %d should be a 6 bit unsigned immediate", j
);
6114 if (!satisfies_constraint_P (op
))
6115 error ("operand %d should be a 8 bit unsigned immediate", j
);
6118 if (!satisfies_constraint_K (op
))
6119 error ("operand %d should be a 3 bit unsigned immediate", j
);
6122 error ("unknown builtin immediate operand type for operand %d",
6127 if (CONST_INT_P (op
))
6130 if ((opmode
== SImode
) && (mode
== HImode
))
6133 op
= gen_lowpart (HImode
, op
);
6136 /* In case the insn wants input operands in modes different from
6137 the result, abort. */
6138 gcc_assert (opmode
== mode
|| opmode
== VOIDmode
);
6140 if (!insn_data
[icode
].operand
[i
+ nonvoid
].predicate (op
, mode
))
6141 op
= copy_to_mode_reg (mode
, op
);
6146 pat
= apply_GEN_FCN (icode
, xop
);
6147 if (pat
== NULL_RTX
)
6158 /* Returns true if the operands[opno] is a valid compile-time constant to be
6159 used as register number in the code for builtins. Else it flags an error
6160 and returns false. */
6163 check_if_valid_regno_const (rtx
*operands
, int opno
)
6166 switch (GET_CODE (operands
[opno
]))
6173 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6179 /* Check that after all the constant folding, whether the operand to
6180 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6183 check_if_valid_sleep_operand (rtx
*operands
, int opno
)
6185 switch (GET_CODE (operands
[opno
]))
6189 if( UNSIGNED_INT6 (INTVAL (operands
[opno
])))
6192 fatal_error (input_location
,
6193 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6199 /* Return true if it is ok to make a tail-call to DECL. */
6202 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED
,
6203 tree exp ATTRIBUTE_UNUSED
)
6205 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6206 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun
)))
6209 /* Everything else is ok. */
6213 /* Output code to add DELTA to the first argument, and then jump
6214 to FUNCTION. Used for C++ multiple inheritance. */
6217 arc_output_mi_thunk (FILE *file
, tree thunk ATTRIBUTE_UNUSED
,
6218 HOST_WIDE_INT delta
,
6219 HOST_WIDE_INT vcall_offset
,
6222 int mi_delta
= delta
;
6223 const char *const mi_op
= mi_delta
< 0 ? "sub" : "add";
6226 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function
)), function
) ? 1 : 0;
6230 mi_delta
= - mi_delta
;
6232 /* Add DELTA. When possible use a plain add, otherwise load it into
6233 a register first. */
6235 while (mi_delta
!= 0)
6237 if ((mi_delta
& (3 << shift
)) == 0)
6241 asm_fprintf (file
, "\t%s\t%s, %s, %d\n",
6242 mi_op
, reg_names
[this_regno
], reg_names
[this_regno
],
6243 mi_delta
& (0xff << shift
));
6244 mi_delta
&= ~(0xff << shift
);
6249 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6250 if (vcall_offset
!= 0)
6252 /* ld r12,[this] --> temp = *this
6253 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6255 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6256 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6257 ARC_TEMP_SCRATCH_REG
, reg_names
[this_regno
]);
6258 asm_fprintf (file
, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC
"\n",
6259 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
, vcall_offset
);
6260 asm_fprintf (file
, "\tld\t%s, [%s]\n",
6261 ARC_TEMP_SCRATCH_REG
, ARC_TEMP_SCRATCH_REG
);
6262 asm_fprintf (file
, "\tadd\t%s, %s, %s\n", reg_names
[this_regno
],
6263 reg_names
[this_regno
], ARC_TEMP_SCRATCH_REG
);
6266 fnaddr
= XEXP (DECL_RTL (function
), 0);
6268 if (arc_is_longcall_p (fnaddr
))
6269 fputs ("\tj\t", file
);
6271 fputs ("\tb\t", file
);
6272 assemble_name (file
, XSTR (fnaddr
, 0));
6276 /* Return true if a 32 bit "long_call" should be generated for
6277 this calling SYM_REF. We generate a long_call if the function:
6279 a. has an __attribute__((long call))
6280 or b. the -mlong-calls command line switch has been specified
6282 However we do not generate a long call if the function has an
6283 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6285 This function will be called by C fragments contained in the machine
6286 description file. */
6289 arc_is_longcall_p (rtx sym_ref
)
6291 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6294 return (SYMBOL_REF_LONG_CALL_P (sym_ref
)
6295 || (TARGET_LONG_CALLS_SET
6296 && !SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6297 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6301 /* Likewise for short calls. */
6304 arc_is_shortcall_p (rtx sym_ref
)
6306 if (GET_CODE (sym_ref
) != SYMBOL_REF
)
6309 return (SYMBOL_REF_SHORT_CALL_P (sym_ref
)
6310 || (!TARGET_LONG_CALLS_SET
&& !TARGET_MEDIUM_CALLS
6311 && !SYMBOL_REF_LONG_CALL_P (sym_ref
)
6312 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref
)));
6316 /* Emit profiling code for calling CALLEE. Return true if a special
6317 call pattern needs to be generated. */
6320 arc_profile_call (rtx callee
)
6322 rtx from
= XEXP (DECL_RTL (current_function_decl
), 0);
6324 if (TARGET_UCB_MCOUNT
)
6325 /* Profiling is done by instrumenting the callee. */
6328 if (CONSTANT_P (callee
))
6331 = gen_rtx_CONST (Pmode
,
6332 gen_rtx_UNSPEC (Pmode
,
6333 gen_rtvec (3, from
, callee
,
6334 CONST0_RTX (Pmode
)),
6336 rtx counter
= gen_rtx_MEM (SImode
, count_ptr
);
6337 /* ??? The increment would better be done atomically, but as there is
6338 no proper hardware support, that would be too expensive. */
6339 emit_move_insn (counter
,
6340 force_reg (SImode
, plus_constant (SImode
, counter
, 1)));
6346 = gen_rtx_CONST (Pmode
,
6347 gen_rtx_UNSPEC (Pmode
,
6348 gen_rtvec (3, from
, CONST0_RTX (Pmode
),
6349 CONST0_RTX (Pmode
)),
6351 emit_move_insn (gen_rtx_REG (Pmode
, 8), count_list_ptr
);
6352 emit_move_insn (gen_rtx_REG (Pmode
, 9), callee
);
6357 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6360 arc_return_in_memory (const_tree type
, const_tree fntype ATTRIBUTE_UNUSED
)
6362 if (AGGREGATE_TYPE_P (type
) || TREE_ADDRESSABLE (type
))
6366 HOST_WIDE_INT size
= int_size_in_bytes (type
);
6367 return (size
== -1 || size
> (TARGET_V2
? 16 : 8));
6372 /* This was in rtlanal.c, and can go in there when we decide we want
6373 to submit the change for inclusion in the GCC tree. */
6374 /* Like note_stores, but allow the callback to have side effects on the rtl
6375 (like the note_stores of yore):
6376 Call FUN on each register or MEM that is stored into or clobbered by X.
6377 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6378 ignored by note_stores, but passed to FUN.
6379 FUN may alter parts of the RTL.
6381 FUN receives three arguments:
6382 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6383 2. the SET or CLOBBER rtx that does the store,
6384 3. the pointer DATA provided to note_stores.
6386 If the item being stored in or clobbered is a SUBREG of a hard register,
6387 the SUBREG will be passed. */
6389 /* For now. */ static
6391 walk_stores (rtx x
, void (*fun
) (rtx
, rtx
, void *), void *data
)
6395 if (GET_CODE (x
) == COND_EXEC
)
6396 x
= COND_EXEC_CODE (x
);
6398 if (GET_CODE (x
) == SET
|| GET_CODE (x
) == CLOBBER
)
6400 rtx dest
= SET_DEST (x
);
6402 while ((GET_CODE (dest
) == SUBREG
6403 && (!REG_P (SUBREG_REG (dest
))
6404 || REGNO (SUBREG_REG (dest
)) >= FIRST_PSEUDO_REGISTER
))
6405 || GET_CODE (dest
) == ZERO_EXTRACT
6406 || GET_CODE (dest
) == STRICT_LOW_PART
)
6407 dest
= XEXP (dest
, 0);
6409 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6410 each of whose first operand is a register. */
6411 if (GET_CODE (dest
) == PARALLEL
)
6413 for (i
= XVECLEN (dest
, 0) - 1; i
>= 0; i
--)
6414 if (XEXP (XVECEXP (dest
, 0, i
), 0) != 0)
6415 (*fun
) (XEXP (XVECEXP (dest
, 0, i
), 0), x
, data
);
6418 (*fun
) (dest
, x
, data
);
6421 else if (GET_CODE (x
) == PARALLEL
)
6422 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
6423 walk_stores (XVECEXP (x
, 0, i
), fun
, data
);
6427 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED
,
6428 machine_mode mode ATTRIBUTE_UNUSED
,
6430 bool named ATTRIBUTE_UNUSED
)
6433 && (TREE_CODE (TYPE_SIZE (type
)) != INTEGER_CST
6434 || TREE_ADDRESSABLE (type
)));
6437 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6440 arc_can_use_doloop_p (const widest_int
&iterations
, const widest_int
&,
6441 unsigned int loop_depth
, bool entered_at_top
)
6445 /* Setting up the loop with two sr instructions costs 6 cycles. */
6448 && wi::gtu_p (iterations
, 0)
6449 && wi::leu_p (iterations
, flag_pic
? 6 : 3))
6454 /* NULL if INSN insn is valid within a low-overhead loop.
6455 Otherwise return why doloop cannot be applied. */
6458 arc_invalid_within_doloop (const rtx_insn
*insn
)
6461 return "Function call in the loop.";
6465 /* The same functionality as arc_hazard. It is called in machine
6466 reorg before any other optimization. Hence, the NOP size is taken
6467 into account when doing branch shortening. */
6470 workaround_arc_anomaly (void)
6472 rtx_insn
*insn
, *succ0
;
6474 /* For any architecture: call arc_hazard here. */
6475 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6477 succ0
= next_real_insn (insn
);
6478 if (arc_hazard (insn
, succ0
))
6480 emit_insn_before (gen_nopv (), succ0
);
6485 static int arc_reorg_in_progress
= 0;
6487 /* ARC's machince specific reorg function. */
6498 workaround_arc_anomaly ();
6500 cfun
->machine
->arc_reorg_started
= 1;
6501 arc_reorg_in_progress
= 1;
6503 /* Emit special sections for profiling. */
6506 section
*save_text_section
;
6508 int size
= get_max_uid () >> 4;
6509 htab_t htab
= htab_create (size
, unspec_prof_hash
, unspec_prof_htab_eq
,
6512 save_text_section
= in_section
;
6513 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6514 if (NONJUMP_INSN_P (insn
))
6515 walk_stores (PATTERN (insn
), write_profile_sections
, htab
);
6516 if (htab_elements (htab
))
6518 switch_to_section (save_text_section
);
6522 /* Link up loop ends with their loop start. */
6524 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6525 if (GET_CODE (insn
) == JUMP_INSN
6526 && recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
6529 = as_a
<rtx_insn
*> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 1), 0));
6530 rtx num
= GEN_INT (CODE_LABEL_NUMBER (top_label
));
6531 rtx_insn
*lp
, *prev
= prev_nonnote_insn (top_label
);
6532 rtx_insn
*lp_simple
= NULL
;
6533 rtx_insn
*next
= NULL
;
6534 rtx op0
= XEXP (XVECEXP (PATTERN (insn
), 0, 1), 0);
6535 HOST_WIDE_INT loop_end_id
6536 = -INTVAL (XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0));
6540 (lp
&& NONJUMP_INSN_P (lp
)
6541 && recog_memoized (lp
) != CODE_FOR_doloop_begin_i
);
6542 lp
= prev_nonnote_insn (lp
))
6544 if (!lp
|| !NONJUMP_INSN_P (lp
)
6545 || dead_or_set_regno_p (lp
, LP_COUNT
))
6547 for (prev
= next
= insn
, lp
= NULL
; prev
|| next
;)
6551 if (NONJUMP_INSN_P (prev
)
6552 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
6553 && (INTVAL (XEXP (XVECEXP (PATTERN (prev
), 0, 5), 0))
6559 else if (LABEL_P (prev
))
6561 prev
= prev_nonnote_insn (prev
);
6565 if (NONJUMP_INSN_P (next
)
6566 && recog_memoized (next
) == CODE_FOR_doloop_begin_i
6567 && (INTVAL (XEXP (XVECEXP (PATTERN (next
), 0, 5), 0))
6573 next
= next_nonnote_insn (next
);
6580 if (lp
&& !dead_or_set_regno_p (lp
, LP_COUNT
))
6582 rtx begin_cnt
= XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0);
6583 if (INTVAL (XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0)))
6584 /* The loop end insn has been duplicated. That can happen
6585 when there is a conditional block at the very end of
6588 /* If Register allocation failed to allocate to the right
6589 register, There is no point into teaching reload to
6590 fix this up with reloads, as that would cost more
6591 than using an ordinary core register with the
6592 doloop_fallback pattern. */
6593 if ((true_regnum (op0
) != LP_COUNT
|| !REG_P (begin_cnt
))
6594 /* Likewise, if the loop setup is evidently inside the loop,
6596 || (!lp_simple
&& lp
!= next
&& !seen_label
))
6601 /* It is common that the optimizers copy the loop count from
6602 another register, and doloop_begin_i is stuck with the
6603 source of the move. Making doloop_begin_i only accept "l"
6604 is nonsentical, as this then makes reload evict the pseudo
6605 used for the loop end. The underlying cause is that the
6606 optimizers don't understand that the register allocation for
6607 doloop_begin_i should be treated as part of the loop.
6608 Try to work around this problem by verifying the previous
6610 if (true_regnum (begin_cnt
) != LP_COUNT
)
6615 for (mov
= prev_nonnote_insn (lp
); mov
;
6616 mov
= prev_nonnote_insn (mov
))
6618 if (!NONJUMP_INSN_P (mov
))
6620 else if ((set
= single_set (mov
))
6621 && rtx_equal_p (SET_SRC (set
), begin_cnt
)
6622 && rtx_equal_p (SET_DEST (set
), op0
))
6627 XEXP (XVECEXP (PATTERN (lp
), 0 ,3), 0) = op0
;
6628 note
= find_regno_note (lp
, REG_DEAD
, REGNO (begin_cnt
));
6630 remove_note (lp
, note
);
6638 XEXP (XVECEXP (PATTERN (insn
), 0, 4), 0) = num
;
6639 XEXP (XVECEXP (PATTERN (lp
), 0, 4), 0) = num
;
6641 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const2_rtx
;
6642 else if (!lp_simple
)
6643 XEXP (XVECEXP (PATTERN (lp
), 0, 6), 0) = const1_rtx
;
6644 else if (prev
!= lp
)
6647 add_insn_after (lp
, prev
, NULL
);
6651 XEXP (XVECEXP (PATTERN (lp
), 0, 7), 0)
6652 = gen_rtx_LABEL_REF (Pmode
, top_label
);
6653 add_reg_note (lp
, REG_LABEL_OPERAND
, top_label
);
6654 LABEL_NUSES (top_label
)++;
6656 /* We can avoid tedious loop start / end setting for empty loops
6657 be merely setting the loop count to its final value. */
6658 if (next_active_insn (top_label
) == insn
)
6661 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp
), 0, 3), 0),
6664 rtx_insn
*lc_set_insn
= emit_insn_before (lc_set
, insn
);
6669 /* If the loop is non-empty with zero length, we can't make it
6670 a zero-overhead loop. That can happen for empty asms. */
6675 for (scan
= top_label
;
6676 (scan
&& scan
!= insn
6677 && (!NONJUMP_INSN_P (scan
) || !get_attr_length (scan
)));
6678 scan
= NEXT_INSN (scan
));
6688 /* Sometimes the loop optimizer makes a complete hash of the
6689 loop. If it were only that the loop is not entered at the
6690 top, we could fix this up by setting LP_START with SR .
6691 However, if we can't find the loop begin were it should be,
6692 chances are that it does not even dominate the loop, but is
6693 inside the loop instead. Using SR there would kill
6695 We use the doloop_fallback pattern here, which executes
6696 in two cycles on the ARC700 when predicted correctly. */
6700 rtx op3
= XEXP (XVECEXP (PATTERN (insn
), 0, 5), 0);
6702 emit_insn_before (gen_move_insn (op3
, op0
), insn
);
6704 = gen_doloop_fallback_m (op3
, JUMP_LABEL (insn
), op0
);
6707 XVEC (PATTERN (insn
), 0)
6708 = gen_rtvec (2, XVECEXP (PATTERN (insn
), 0, 0),
6709 XVECEXP (PATTERN (insn
), 0, 1));
6710 INSN_CODE (insn
) = -1;
6715 /* FIXME: should anticipate ccfsm action, generate special patterns for
6716 to-be-deleted branches that have no delay slot and have at least the
6717 length of the size increase forced on other insns that are conditionalized.
6718 This can also have an insn_list inside that enumerates insns which are
6719 not actually conditionalized because the destinations are dead in the
6721 Could also tag branches that we want to be unaligned if they get no delay
6722 slot, or even ones that we don't want to do delay slot sheduling for
6723 because we can unalign them.
6725 However, there are cases when conditional execution is only possible after
6726 delay slot scheduling:
6728 - If a delay slot is filled with a nocond/set insn from above, the previous
6729 basic block can become elegible for conditional execution.
6730 - If a delay slot is filled with a nocond insn from the fall-through path,
6731 the branch with that delay slot can become eligble for conditional
6732 execution (however, with the same sort of data flow analysis that dbr
6733 does, we could have figured out before that we don't need to
6734 conditionalize this insn.)
6735 - If a delay slot insn is filled with an insn from the target, the
6736 target label gets its uses decremented (even deleted if falling to zero),
6737 thus possibly creating more condexec opportunities there.
6738 Therefore, we should still be prepared to apply condexec optimization on
6739 non-prepared branches if the size increase of conditionalized insns is no
6740 more than the size saved from eliminating the branch. An invocation option
6741 could also be used to reserve a bit of extra size for condbranches so that
6742 this'll work more often (could also test in arc_reorg if the block is
6743 'close enough' to be eligible for condexec to make this likely, and
6744 estimate required size increase). */
6745 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
6746 if (TARGET_NO_BRCC_SET
)
6751 init_insn_lengths();
6754 if (optimize
> 1 && !TARGET_NO_COND_EXEC
)
6757 unsigned int flags
= pass_data_arc_ifcvt
.todo_flags_finish
;
6758 df_finish_pass ((flags
& TODO_df_verify
) != 0);
6761 /* Call shorten_branches to calculate the insn lengths. */
6762 shorten_branches (get_insns());
6763 cfun
->machine
->ccfsm_current_insn
= NULL_RTX
;
6765 if (!INSN_ADDRESSES_SET_P())
6766 fatal_error (input_location
, "Insn addresses not set after shorten_branches");
6768 for (insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
6771 enum attr_type insn_type
;
6773 /* If a non-jump insn (or a casesi jump table), continue. */
6774 if (GET_CODE (insn
) != JUMP_INSN
||
6775 GET_CODE (PATTERN (insn
)) == ADDR_VEC
6776 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
6779 /* If we already have a brcc, note if it is suitable for brcc_s.
6780 Be a bit generous with the brcc_s range so that we can take
6781 advantage of any code shortening from delay slot scheduling. */
6782 if (recog_memoized (insn
) == CODE_FOR_cbranchsi4_scratch
)
6784 rtx pat
= PATTERN (insn
);
6785 rtx op
= XEXP (SET_SRC (XVECEXP (pat
, 0, 0)), 0);
6786 rtx
*ccp
= &XEXP (XVECEXP (pat
, 0, 1), 0);
6788 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
6789 if ((offset
>= -140 && offset
< 140)
6790 && rtx_equal_p (XEXP (op
, 1), const0_rtx
)
6791 && compact_register_operand (XEXP (op
, 0), VOIDmode
)
6792 && equality_comparison_operator (op
, VOIDmode
))
6793 PUT_MODE (*ccp
, CC_Zmode
);
6794 else if (GET_MODE (*ccp
) == CC_Zmode
)
6795 PUT_MODE (*ccp
, CC_ZNmode
);
6798 if ((insn_type
= get_attr_type (insn
)) == TYPE_BRCC
6799 || insn_type
== TYPE_BRCC_NO_DELAY_SLOT
)
6802 /* OK. so we have a jump insn. */
6803 /* We need to check that it is a bcc. */
6804 /* Bcc => set (pc) (if_then_else ) */
6805 pattern
= PATTERN (insn
);
6806 if (GET_CODE (pattern
) != SET
6807 || GET_CODE (SET_SRC (pattern
)) != IF_THEN_ELSE
6808 || ANY_RETURN_P (XEXP (SET_SRC (pattern
), 1)))
6811 /* Now check if the jump is beyond the s9 range. */
6812 if (CROSSING_JUMP_P (insn
))
6814 offset
= branch_dest (insn
) - INSN_ADDRESSES (INSN_UID (insn
));
6816 if(offset
> 253 || offset
< -254)
6819 pc_target
= SET_SRC (pattern
);
6821 /* Avoid FPU instructions. */
6822 if ((GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPUmode
)
6823 || (GET_MODE (XEXP (XEXP (pc_target
, 0), 0)) == CC_FPU_UNEQmode
))
6826 /* Now go back and search for the set cc insn. */
6828 label
= XEXP (pc_target
, 1);
6832 rtx_insn
*scan
, *link_insn
= NULL
;
6834 for (scan
= PREV_INSN (insn
);
6835 scan
&& GET_CODE (scan
) != CODE_LABEL
;
6836 scan
= PREV_INSN (scan
))
6838 if (! INSN_P (scan
))
6840 pat
= PATTERN (scan
);
6841 if (GET_CODE (pat
) == SET
6842 && cc_register (SET_DEST (pat
), VOIDmode
))
6851 /* Check if this is a data dependency. */
6853 rtx op
, cc_clob_rtx
, op0
, op1
, brcc_insn
, note
;
6856 /* Ok this is the set cc. copy args here. */
6857 op
= XEXP (pc_target
, 0);
6859 op0
= cmp0
= XEXP (SET_SRC (pat
), 0);
6860 op1
= cmp1
= XEXP (SET_SRC (pat
), 1);
6861 if (GET_CODE (op0
) == ZERO_EXTRACT
6862 && XEXP (op0
, 1) == const1_rtx
6863 && (GET_CODE (op
) == EQ
6864 || GET_CODE (op
) == NE
))
6866 /* btst / b{eq,ne} -> bbit{0,1} */
6867 op0
= XEXP (cmp0
, 0);
6868 op1
= XEXP (cmp0
, 2);
6870 else if (!register_operand (op0
, VOIDmode
)
6871 || !general_operand (op1
, VOIDmode
))
6873 /* Be careful not to break what cmpsfpx_raw is
6874 trying to create for checking equality of
6875 single-precision floats. */
6876 else if (TARGET_SPFP
6877 && GET_MODE (op0
) == SFmode
6878 && GET_MODE (op1
) == SFmode
)
6881 /* None of the two cmp operands should be set between the
6882 cmp and the branch. */
6883 if (reg_set_between_p (op0
, link_insn
, insn
))
6886 if (reg_set_between_p (op1
, link_insn
, insn
))
6889 /* Since the MODE check does not work, check that this is
6890 CC reg's last set location before insn, and also no
6891 instruction between the cmp and branch uses the
6893 if ((reg_set_between_p (SET_DEST (pat
), link_insn
, insn
))
6894 || (reg_used_between_p (SET_DEST (pat
), link_insn
, insn
)))
6897 /* CC reg should be dead after insn. */
6898 if (!find_regno_note (insn
, REG_DEAD
, CC_REG
))
6901 op
= gen_rtx_fmt_ee (GET_CODE (op
),
6902 GET_MODE (op
), cmp0
, cmp1
);
6903 /* If we create a LIMM where there was none before,
6904 we only benefit if we can avoid a scheduling bubble
6905 for the ARC600. Otherwise, we'd only forgo chances
6906 at short insn generation, and risk out-of-range
6908 if (!brcc_nolimm_operator (op
, VOIDmode
)
6909 && !long_immediate_operand (op1
, VOIDmode
)
6911 || next_active_insn (link_insn
) != insn
))
6914 /* Emit bbit / brcc (or brcc_s if possible).
6915 CC_Zmode indicates that brcc_s is possible. */
6918 cc_clob_rtx
= gen_rtx_REG (CC_ZNmode
, CC_REG
);
6919 else if ((offset
>= -140 && offset
< 140)
6920 && rtx_equal_p (op1
, const0_rtx
)
6921 && compact_register_operand (op0
, VOIDmode
)
6922 && (GET_CODE (op
) == EQ
6923 || GET_CODE (op
) == NE
))
6924 cc_clob_rtx
= gen_rtx_REG (CC_Zmode
, CC_REG
);
6926 cc_clob_rtx
= gen_rtx_REG (CCmode
, CC_REG
);
6929 = gen_rtx_IF_THEN_ELSE (VOIDmode
, op
, label
, pc_rtx
);
6930 brcc_insn
= gen_rtx_SET (pc_rtx
, brcc_insn
);
6931 cc_clob_rtx
= gen_rtx_CLOBBER (VOIDmode
, cc_clob_rtx
);
6934 (VOIDmode
, gen_rtvec (2, brcc_insn
, cc_clob_rtx
));
6935 brcc_insn
= emit_jump_insn_before (brcc_insn
, insn
);
6937 JUMP_LABEL (brcc_insn
) = JUMP_LABEL (insn
);
6938 note
= find_reg_note (insn
, REG_BR_PROB
, 0);
6941 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
6942 REG_NOTES (brcc_insn
) = note
;
6944 note
= find_reg_note (link_insn
, REG_DEAD
, op0
);
6947 remove_note (link_insn
, note
);
6948 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
6949 REG_NOTES (brcc_insn
) = note
;
6951 note
= find_reg_note (link_insn
, REG_DEAD
, op1
);
6954 XEXP (note
, 1) = REG_NOTES (brcc_insn
);
6955 REG_NOTES (brcc_insn
) = note
;
6960 /* Delete the bcc insn. */
6961 set_insn_deleted (insn
);
6963 /* Delete the cmp insn. */
6964 set_insn_deleted (link_insn
);
6969 /* Clear out insn_addresses. */
6970 INSN_ADDRESSES_FREE ();
6974 if (INSN_ADDRESSES_SET_P())
6975 fatal_error (input_location
, "insn addresses not freed");
6977 arc_reorg_in_progress
= 0;
6980 /* Check if the operands are valid for BRcc.d generation
6981 Valid Brcc.d patterns are
6985 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
6986 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
6987 does not have a delay slot
6989 Assumed precondition: Second operand is either a register or a u6 value. */
6992 valid_brcc_with_delay_p (rtx
*operands
)
6994 if (optimize_size
&& GET_MODE (operands
[4]) == CC_Zmode
)
6996 return brcc_nolimm_operator (operands
[0], VOIDmode
);
6999 /* ??? Hack. This should no really be here. See PR32143. */
7001 arc_decl_anon_ns_mem_p (const_tree decl
)
7005 if (decl
== NULL_TREE
|| decl
== error_mark_node
)
7007 if (TREE_CODE (decl
) == NAMESPACE_DECL
7008 && DECL_NAME (decl
) == NULL_TREE
)
7010 /* Classes and namespaces inside anonymous namespaces have
7011 TREE_PUBLIC == 0, so we can shortcut the search. */
7012 else if (TYPE_P (decl
))
7013 return (TREE_PUBLIC (TYPE_NAME (decl
)) == 0);
7014 else if (TREE_CODE (decl
) == NAMESPACE_DECL
)
7015 return (TREE_PUBLIC (decl
) == 0);
7017 decl
= DECL_CONTEXT (decl
);
7021 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7022 access DECL using %gp_rel(...)($gp). */
7025 arc_in_small_data_p (const_tree decl
)
7029 if (TREE_CODE (decl
) == STRING_CST
|| TREE_CODE (decl
) == FUNCTION_DECL
)
7033 /* We don't yet generate small-data references for -mabicalls. See related
7034 -G handling in override_options. */
7035 if (TARGET_NO_SDATA_SET
)
7038 if (TREE_CODE (decl
) == VAR_DECL
&& DECL_SECTION_NAME (decl
) != 0)
7042 /* Reject anything that isn't in a known small-data section. */
7043 name
= DECL_SECTION_NAME (decl
);
7044 if (strcmp (name
, ".sdata") != 0 && strcmp (name
, ".sbss") != 0)
7047 /* If a symbol is defined externally, the assembler will use the
7048 usual -G rules when deciding how to implement macros. */
7049 if (!DECL_EXTERNAL (decl
))
7052 /* Only global variables go into sdata section for now. */
7055 /* Don't put constants into the small data section: we want them
7056 to be in ROM rather than RAM. */
7057 if (TREE_CODE (decl
) != VAR_DECL
)
7060 if (TREE_READONLY (decl
)
7061 && !TREE_SIDE_EFFECTS (decl
)
7062 && (!DECL_INITIAL (decl
) || TREE_CONSTANT (DECL_INITIAL (decl
))))
7065 /* TREE_PUBLIC might change after the first call, because of the patch
7067 if (default_binds_local_p_1 (decl
, 1)
7068 || arc_decl_anon_ns_mem_p (decl
))
7071 /* To ensure -mvolatile-cache works
7072 ld.di does not have a gp-relative variant. */
7073 if (TREE_THIS_VOLATILE (decl
))
7077 /* Disable sdata references to weak variables. */
7078 if (DECL_WEAK (decl
))
7081 size
= int_size_in_bytes (TREE_TYPE (decl
));
7083 /* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7086 /* Allow only <=4B long data types into sdata. */
7087 return (size
> 0 && size
<= 4);
7090 /* Return true if X is a small data address that can be rewritten
7094 arc_rewrite_small_data_p (const_rtx x
)
7096 if (GET_CODE (x
) == CONST
)
7099 if (GET_CODE (x
) == PLUS
)
7101 if (GET_CODE (XEXP (x
, 1)) == CONST_INT
)
7105 if (GET_CODE (x
) == SYMBOL_REF
&& SYMBOL_REF_SMALL_P (x
))
7107 gcc_assert (SYMBOL_REF_TLS_MODEL (x
) == 0);
7113 /* If possible, rewrite OP so that it refers to small data using
7114 explicit relocations. */
7117 arc_rewrite_small_data (rtx op
)
7119 op
= copy_insn (op
);
7120 subrtx_ptr_iterator::array_type array
;
7121 FOR_EACH_SUBRTX_PTR (iter
, array
, &op
, ALL
)
7124 if (arc_rewrite_small_data_p (*loc
))
7126 gcc_assert (SDATA_BASE_REGNUM
== PIC_OFFSET_TABLE_REGNUM
);
7127 *loc
= gen_rtx_PLUS (Pmode
, pic_offset_table_rtx
, *loc
);
7130 if (GET_CODE (op
) == MEM
&& &XEXP (op
, 0) == loc
)
7132 else if (GET_CODE (op
) == MEM
7133 && GET_CODE (XEXP (op
, 0)) == PLUS
7134 && GET_CODE (XEXP (XEXP (op
, 0), 0)) == MULT
)
7135 *loc
= force_reg (Pmode
, *loc
);
7139 iter
.skip_subrtxes ();
7141 else if (GET_CODE (*loc
) == PLUS
7142 && rtx_equal_p (XEXP (*loc
, 0), pic_offset_table_rtx
))
7143 iter
.skip_subrtxes ();
7148 /* Return true if OP refers to small data symbols directly, not through
7152 small_data_pattern (rtx op
, machine_mode
)
7154 if (GET_CODE (op
) == SEQUENCE
)
7156 subrtx_iterator::array_type array
;
7157 FOR_EACH_SUBRTX (iter
, array
, op
, ALL
)
7159 const_rtx x
= *iter
;
7160 if (GET_CODE (x
) == PLUS
7161 && rtx_equal_p (XEXP (x
, 0), pic_offset_table_rtx
))
7162 iter
.skip_subrtxes ();
7163 else if (arc_rewrite_small_data_p (x
))
7169 /* Return true if OP is an acceptable memory operand for ARCompact
7170 16-bit gp-relative load instructions.
7171 op shd look like : [r26, symref@sda]
7172 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7174 /* volatile cache option still to be handled. */
7177 compact_sda_memory_operand (rtx op
, machine_mode mode
)
7182 /* Eliminate non-memory operations. */
7183 if (GET_CODE (op
) != MEM
)
7186 if (mode
== VOIDmode
)
7187 mode
= GET_MODE (op
);
7189 size
= GET_MODE_SIZE (mode
);
7191 /* dword operations really put out 2 instructions, so eliminate them. */
7192 if (size
> UNITS_PER_WORD
)
7195 /* Decode the address now. */
7196 addr
= XEXP (op
, 0);
7198 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr
);
7201 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7204 arc_asm_output_aligned_decl_local (FILE * stream
, tree decl
, const char * name
,
7205 unsigned HOST_WIDE_INT size
,
7206 unsigned HOST_WIDE_INT align
,
7207 unsigned HOST_WIDE_INT globalize_p
)
7209 int in_small_data
= arc_in_small_data_p (decl
);
7212 switch_to_section (get_named_section (NULL
, ".sbss", 0));
7213 /* named_section (0,".sbss",0); */
7215 switch_to_section (bss_section
);
7218 (*targetm
.asm_out
.globalize_label
) (stream
, name
);
7220 ASM_OUTPUT_ALIGN (stream
, floor_log2 ((align
) / BITS_PER_UNIT
));
7221 ASM_OUTPUT_TYPE_DIRECTIVE (stream
, name
, "object");
7222 ASM_OUTPUT_SIZE_DIRECTIVE (stream
, name
, size
);
7223 ASM_OUTPUT_LABEL (stream
, name
);
7226 ASM_OUTPUT_SKIP (stream
, size
);
7230 arc_preserve_reload_p (rtx in
)
7232 return (GET_CODE (in
) == PLUS
7233 && RTX_OK_FOR_BASE_P (XEXP (in
, 0), true)
7234 && CONST_INT_P (XEXP (in
, 1))
7235 && !((INTVAL (XEXP (in
, 1)) & 511)));
7239 arc_register_move_cost (machine_mode
,
7240 enum reg_class from_class
, enum reg_class to_class
)
7242 /* The ARC600 has no bypass for extension registers, hence a nop might be
7243 needed to be inserted after a write so that reads are safe. */
7246 if (to_class
== MPY_WRITABLE_CORE_REGS
)
7248 /* Instructions modifying LP_COUNT need 4 additional cycles before
7249 the register will actually contain the value. */
7250 else if (to_class
== LPCOUNT_REG
)
7252 else if (to_class
== WRITABLE_CORE_REGS
)
7256 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7258 && (from_class
== LPCOUNT_REG
|| from_class
== ALL_CORE_REGS
7259 || from_class
== WRITABLE_CORE_REGS
))
7262 /* Force an attempt to 'mov Dy,Dx' to spill. */
7263 if (TARGET_ARC700
&& TARGET_DPFP
7264 && from_class
== DOUBLE_REGS
&& to_class
== DOUBLE_REGS
)
7270 /* Emit code for an addsi3 instruction with OPERANDS.
7271 COND_P indicates if this will use conditional execution.
7272 Return the length of the instruction.
7273 If OUTPUT_P is false, don't actually output the instruction, just return
7276 arc_output_addsi (rtx
*operands
, bool cond_p
, bool output_p
)
7280 int match
= operands_match_p (operands
[0], operands
[1]);
7281 int match2
= operands_match_p (operands
[0], operands
[2]);
7282 int intval
= (REG_P (operands
[2]) ? 1
7283 : CONST_INT_P (operands
[2]) ? INTVAL (operands
[2]) : 0xbadc057);
7284 int neg_intval
= -intval
;
7285 int short_0
= satisfies_constraint_Rcq (operands
[0]);
7286 int short_p
= (!cond_p
&& short_0
&& satisfies_constraint_Rcq (operands
[1]));
7289 #define ADDSI_OUTPUT1(FORMAT) do {\
7291 output_asm_insn (FORMAT, operands);\
7294 #define ADDSI_OUTPUT(LIST) do {\
7297 ADDSI_OUTPUT1 (format);\
7301 /* First try to emit a 16 bit insn. */
7304 /* If we are actually about to output this insn, don't try a 16 bit
7305 variant if we already decided that we don't want that
7306 (I.e. we upsized this insn to align some following insn.)
7307 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7308 but add1 r0,sp,35 doesn't. */
7309 && (!output_p
|| (get_attr_length (current_output_insn
) & 2)))
7312 && (REG_P (operands
[2])
7313 ? (match
|| satisfies_constraint_Rcq (operands
[2]))
7314 : (unsigned) intval
<= (match
? 127 : 7)))
7315 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7316 if (short_0
&& REG_P (operands
[1]) && match2
)
7317 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7318 if ((short_0
|| REGNO (operands
[0]) == STACK_POINTER_REGNUM
)
7319 && REGNO (operands
[1]) == STACK_POINTER_REGNUM
&& !(intval
& ~124))
7320 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7322 if ((short_p
&& (unsigned) neg_intval
<= (match
? 31 : 7))
7323 || (REGNO (operands
[0]) == STACK_POINTER_REGNUM
7324 && match
&& !(neg_intval
& ~124)))
7325 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7328 /* Now try to emit a 32 bit insn without long immediate. */
7330 if (!match
&& match2
&& REG_P (operands
[1]))
7331 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7332 if (match
|| !cond_p
)
7334 int limit
= (match
&& !cond_p
) ? 0x7ff : 0x3f;
7335 int range_factor
= neg_intval
& intval
;
7338 if (intval
== (HOST_WIDE_INT
) (HOST_WIDE_INT_M1U
<< 31))
7339 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7341 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7342 same size, do, so - the insn latency is lower. */
7343 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7345 if ((intval
>= 0 && intval
<= limit
)
7346 || (intval
== -0x800 && limit
== 0x7ff))
7347 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7348 else if ((intval
< 0 && neg_intval
<= limit
)
7349 || (intval
== 0x800 && limit
== 0x7ff))
7350 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7351 shift
= range_factor
>= 8 ? 3 : (range_factor
>> 1);
7352 gcc_assert (shift
== 0 || shift
== 1 || shift
== 2 || shift
== 3);
7353 gcc_assert ((((1 << shift
) - 1) & intval
) == 0);
7354 if (((intval
< 0 && intval
!= -0x4000)
7355 /* sub[123] is slower than add_s / sub, only use it if it
7356 avoids a long immediate. */
7357 && neg_intval
<= limit
<< shift
)
7358 || (intval
== 0x4000 && limit
== 0x7ff))
7359 ADDSI_OUTPUT ((format
, "sub%d%%? %%0,%%1,%d",
7360 shift
, neg_intval
>> shift
));
7361 else if ((intval
>= 0 && intval
<= limit
<< shift
)
7362 || (intval
== -0x4000 && limit
== 0x7ff))
7363 ADDSI_OUTPUT ((format
, "add%d%%? %%0,%%1,%d", shift
, intval
>> shift
));
7365 /* Try to emit a 16 bit opcode with long immediate. */
7367 if (short_p
&& match
)
7368 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7370 /* We have to use a 32 bit opcode, and with a long immediate. */
7372 ADDSI_OUTPUT1 (intval
< 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7375 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
7376 Return the length of the instruction.
7377 If OUTPUT_P is false, don't actually output the instruction, just return
7380 arc_output_commutative_cond_exec (rtx
*operands
, bool output_p
)
7382 enum rtx_code commutative_op
= GET_CODE (operands
[3]);
7383 const char *pat
= NULL
;
7385 /* Canonical rtl should not have a constant in the first operand position. */
7386 gcc_assert (!CONSTANT_P (operands
[1]));
7388 switch (commutative_op
)
7391 if (satisfies_constraint_C1p (operands
[2]))
7392 pat
= "bmsk%? %0,%1,%Z2";
7393 else if (satisfies_constraint_C2p (operands
[2]))
7395 operands
[2] = GEN_INT ((~INTVAL (operands
[2])));
7396 pat
= "bmskn%? %0,%1,%Z2";
7398 else if (satisfies_constraint_Ccp (operands
[2]))
7399 pat
= "bclr%? %0,%1,%M2";
7400 else if (satisfies_constraint_CnL (operands
[2]))
7401 pat
= "bic%? %0,%1,%n2-1";
7404 if (satisfies_constraint_C0p (operands
[2]))
7405 pat
= "bset%? %0,%1,%z2";
7408 if (satisfies_constraint_C0p (operands
[2]))
7409 pat
= "bxor%? %0,%1,%z2";
7412 return arc_output_addsi (operands
, true, output_p
);
7416 output_asm_insn (pat
? pat
: "%O3.%d5 %0,%1,%2", operands
);
7417 if (pat
|| REG_P (operands
[2]) || satisfies_constraint_L (operands
[2]))
7422 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7423 Emit code and return an potentially modified address such that offsets
7424 up to SIZE are can be added to yield a legitimate address.
7425 if REUSE is set, ADDR is a register that may be modified. */
7428 force_offsettable (rtx addr
, HOST_WIDE_INT size
, bool reuse
)
7431 rtx offs
= const0_rtx
;
7433 if (GET_CODE (base
) == PLUS
)
7435 offs
= XEXP (base
, 1);
7436 base
= XEXP (base
, 0);
7439 || (REGNO (base
) != STACK_POINTER_REGNUM
7440 && REGNO_PTR_FRAME_P (REGNO (addr
)))
7441 || !CONST_INT_P (offs
) || !SMALL_INT (INTVAL (offs
))
7442 || !SMALL_INT (INTVAL (offs
) + size
))
7445 emit_insn (gen_add2_insn (addr
, offs
));
7447 addr
= copy_to_mode_reg (Pmode
, addr
);
7452 /* Like move_by_pieces, but take account of load latency, and actual
7453 offset ranges. Return true on success. */
7456 arc_expand_movmem (rtx
*operands
)
7458 rtx dst
= operands
[0];
7459 rtx src
= operands
[1];
7460 rtx dst_addr
, src_addr
;
7462 int align
= INTVAL (operands
[3]);
7469 if (!CONST_INT_P (operands
[2]))
7471 size
= INTVAL (operands
[2]);
7472 /* move_by_pieces_ninsns is static, so we can't use it. */
7476 n_pieces
= (size
+ 4) / 8U + ((size
>> 1) & 1) + (size
& 1);
7478 n_pieces
= (size
+ 2) / 4U + (size
& 1);
7480 else if (align
== 2)
7481 n_pieces
= (size
+ 1) / 2U;
7484 if (n_pieces
>= (unsigned int) (optimize_size
? 3 : 15))
7486 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7488 if (TARGET_LL64
&& (piece
>= 4) && (size
>= 8))
7492 dst_addr
= force_offsettable (XEXP (operands
[0], 0), size
, 0);
7493 src_addr
= force_offsettable (XEXP (operands
[1], 0), size
, 0);
7494 store
[0] = store
[1] = NULL_RTX
;
7495 tmpx
[0] = tmpx
[1] = NULL_RTX
;
7496 for (i
= 0; size
> 0; i
^= 1, size
-= piece
)
7501 while (piece
> size
)
7503 mode
= smallest_mode_for_size (piece
* BITS_PER_UNIT
, MODE_INT
);
7504 /* If we don't re-use temporaries, the scheduler gets carried away,
7505 and the register pressure gets unnecessarily high. */
7506 if (0 && tmpx
[i
] && GET_MODE (tmpx
[i
]) == mode
)
7509 tmpx
[i
] = tmp
= gen_reg_rtx (mode
);
7510 dst_addr
= force_offsettable (dst_addr
, piece
, 1);
7511 src_addr
= force_offsettable (src_addr
, piece
, 1);
7513 emit_insn (store
[i
]);
7514 emit_move_insn (tmp
, change_address (src
, mode
, src_addr
));
7515 store
[i
] = gen_move_insn (change_address (dst
, mode
, dst_addr
), tmp
);
7516 dst_addr
= plus_constant (Pmode
, dst_addr
, piece
);
7517 src_addr
= plus_constant (Pmode
, src_addr
, piece
);
7520 emit_insn (store
[i
]);
7522 emit_insn (store
[i
^1]);
7526 /* Prepare operands for move in MODE. Return true iff the move has
7530 prepare_move_operands (rtx
*operands
, machine_mode mode
)
7532 /* We used to do this only for MODE_INT Modes, but addresses to floating
7533 point variables may well be in the small data section. */
7534 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[0], Pmode
))
7535 operands
[0] = arc_rewrite_small_data (operands
[0]);
7537 if (mode
== SImode
&& SYMBOLIC_CONST (operands
[1]))
7539 prepare_pic_move (operands
, SImode
);
7541 /* Disable any REG_EQUALs associated with the symref
7542 otherwise the optimization pass undoes the work done
7543 here and references the variable directly. */
7546 if (GET_CODE (operands
[0]) != MEM
7547 && !TARGET_NO_SDATA_SET
7548 && small_data_pattern (operands
[1], Pmode
))
7550 /* This is to take care of address calculations involving sdata
7552 operands
[1] = arc_rewrite_small_data (operands
[1]);
7554 emit_insn (gen_rtx_SET (operands
[0],operands
[1]));
7555 /* ??? This note is useless, since it only restates the set itself.
7556 We should rather use the original SYMBOL_REF. However, there is
7557 the problem that we are lying to the compiler about these
7558 SYMBOL_REFs to start with. symbol@sda should be encoded specially
7559 so that we can tell it apart from an actual symbol. */
7560 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
7562 /* Take care of the REG_EQUAL note that will be attached to mark the
7563 output reg equal to the initial symbol_ref after this code is
7565 emit_move_insn (operands
[0], operands
[0]);
7569 if (MEM_P (operands
[0])
7570 && !(reload_in_progress
|| reload_completed
))
7572 operands
[1] = force_reg (mode
, operands
[1]);
7573 if (!move_dest_operand (operands
[0], mode
))
7575 rtx addr
= copy_to_mode_reg (Pmode
, XEXP (operands
[0], 0));
7576 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
7577 except that we can't use that function because it is static. */
7578 rtx pat
= change_address (operands
[0], mode
, addr
);
7579 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
7582 if (!cse_not_expected
)
7584 rtx pat
= XEXP (operands
[0], 0);
7586 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
7589 pat
= change_address (operands
[0], mode
, pat
);
7590 MEM_COPY_ATTRIBUTES (pat
, operands
[0]);
7596 if (MEM_P (operands
[1]) && !cse_not_expected
)
7598 rtx pat
= XEXP (operands
[1], 0);
7600 pat
= arc_legitimize_address_0 (pat
, pat
, mode
);
7603 pat
= change_address (operands
[1], mode
, pat
);
7604 MEM_COPY_ATTRIBUTES (pat
, operands
[1]);
7612 /* Prepare OPERANDS for an extension using CODE to OMODE.
7613 Return true iff the move has been emitted. */
7616 prepare_extend_operands (rtx
*operands
, enum rtx_code code
,
7619 if (!TARGET_NO_SDATA_SET
&& small_data_pattern (operands
[1], Pmode
))
7621 /* This is to take care of address calculations involving sdata
7624 = gen_rtx_fmt_e (code
, omode
, arc_rewrite_small_data (operands
[1]));
7625 emit_insn (gen_rtx_SET (operands
[0], operands
[1]));
7626 set_unique_reg_note (get_last_insn (), REG_EQUAL
, operands
[1]);
7628 /* Take care of the REG_EQUAL note that will be attached to mark the
7629 output reg equal to the initial extension after this code is
7631 emit_move_insn (operands
[0], operands
[0]);
7637 /* Output a library call to a function called FNAME that has been arranged
7638 to be local to any dso. */
7641 arc_output_libcall (const char *fname
)
7643 unsigned len
= strlen (fname
);
7644 static char buf
[64];
7646 gcc_assert (len
< sizeof buf
- 35);
7647 if (TARGET_LONG_CALLS_SET
7648 || (TARGET_MEDIUM_CALLS
&& arc_ccfsm_cond_exec_p ()))
7651 sprintf (buf
, "add r12,pcl,@%s-(.&-4)\n\tjl%%!%%* [r12]", fname
);
7653 sprintf (buf
, "jl%%! @%s", fname
);
7656 sprintf (buf
, "bl%%!%%* @%s", fname
);
7660 /* Return the SImode highpart of the DImode value IN. */
7663 disi_highpart (rtx in
)
7665 return simplify_gen_subreg (SImode
, in
, DImode
, TARGET_BIG_ENDIAN
? 0 : 4);
7668 /* Return length adjustment for INSN.
7670 A write to a core reg greater or equal to 32 must not be immediately
7671 followed by a use. Anticipate the length requirement to insert a nop
7672 between PRED and SUCC to prevent a hazard. */
7675 arc600_corereg_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
7679 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
7680 in front of SUCC anyway, so there will be separation between PRED and
7682 if (recog_memoized (succ
) == CODE_FOR_doloop_end_i
7683 && LABEL_P (prev_nonnote_insn (succ
)))
7685 if (recog_memoized (succ
) == CODE_FOR_doloop_begin_i
)
7687 if (GET_CODE (PATTERN (pred
)) == SEQUENCE
)
7688 pred
= as_a
<rtx_sequence
*> (PATTERN (pred
))->insn (1);
7689 if (GET_CODE (PATTERN (succ
)) == SEQUENCE
)
7690 succ
= as_a
<rtx_sequence
*> (PATTERN (succ
))->insn (0);
7691 if (recog_memoized (pred
) == CODE_FOR_mulsi_600
7692 || recog_memoized (pred
) == CODE_FOR_umul_600
7693 || recog_memoized (pred
) == CODE_FOR_mac_600
7694 || recog_memoized (pred
) == CODE_FOR_mul64_600
7695 || recog_memoized (pred
) == CODE_FOR_mac64_600
7696 || recog_memoized (pred
) == CODE_FOR_umul64_600
7697 || recog_memoized (pred
) == CODE_FOR_umac64_600
)
7699 subrtx_iterator::array_type array
;
7700 FOR_EACH_SUBRTX (iter
, array
, PATTERN (pred
), NONCONST
)
7702 const_rtx x
= *iter
;
7703 switch (GET_CODE (x
))
7705 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
7708 /* This is also fine for PRE/POST_MODIFY, because they
7712 rtx dest
= XEXP (x
, 0);
7713 /* Check if this sets a an extension register. N.B. we use 61 for the
7714 condition codes, which is definitely not an extension register. */
7715 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61
7716 /* Check if the same register is used by the PAT. */
7717 && (refers_to_regno_p
7719 REGNO (dest
) + (GET_MODE_SIZE (GET_MODE (dest
)) + 3) / 4U,
7720 PATTERN (succ
), 0)))
7726 /* Given a rtx, check if it is an assembly instruction or not. */
7729 arc_asm_insn_p (rtx x
)
7736 switch (GET_CODE (x
))
7743 return arc_asm_insn_p (SET_SRC (x
));
7747 for (i
= XVECLEN (x
, 0) - 1; i
>= 0; i
--)
7748 j
+= arc_asm_insn_p (XVECEXP (x
, 0, i
));
7760 /* We might have a CALL to a non-returning function before a loop end.
7761 ??? Although the manual says that's OK (the target is outside the
7762 loop, and the loop counter unused there), the assembler barfs on
7763 this for ARC600, so we must insert a nop before such a call too.
7764 For ARC700, and ARCv2 is not allowed to have the last ZOL
7765 instruction a jump to a location where lp_count is modified. */
7768 arc_loop_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
7770 rtx_insn
*jump
= NULL
;
7771 rtx label_rtx
= NULL_RTX
;
7772 rtx_insn
*label
= NULL
;
7773 basic_block succ_bb
;
7775 if (recog_memoized (succ
) != CODE_FOR_doloop_end_i
)
7778 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
7779 (i.e., jump/call) as the last instruction of a ZOL. */
7780 if (TARGET_ARC600
|| TARGET_HS
)
7781 if (JUMP_P (pred
) || CALL_P (pred
)
7782 || arc_asm_insn_p (PATTERN (pred
))
7783 || GET_CODE (PATTERN (pred
)) == SEQUENCE
)
7786 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
7787 instruction a jump to a location where lp_count is modified. */
7789 /* Phase 2a: Dig for the jump instruction. */
7792 else if (GET_CODE (PATTERN (pred
)) == SEQUENCE
7793 && JUMP_P (XVECEXP (PATTERN (pred
), 0, 0)))
7794 jump
= as_a
<rtx_insn
*> XVECEXP (PATTERN (pred
), 0, 0);
7798 /* Phase 2b: Make sure is not a millicode jump. */
7799 if ((GET_CODE (PATTERN (jump
)) == PARALLEL
)
7800 && (XVECEXP (PATTERN (jump
), 0, 0) == ret_rtx
))
7803 label_rtx
= JUMP_LABEL (jump
);
7807 /* Phase 2c: Make sure is not a return. */
7808 if (ANY_RETURN_P (label_rtx
))
7811 /* Pahse 2d: Go to the target of the jump and check for aliveness of
7812 LP_COUNT register. */
7813 label
= safe_as_a
<rtx_insn
*> (label_rtx
);
7814 succ_bb
= BLOCK_FOR_INSN (label
);
7817 gcc_assert (NEXT_INSN (label
));
7818 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label
)))
7819 succ_bb
= NOTE_BASIC_BLOCK (NEXT_INSN (label
));
7821 succ_bb
= BLOCK_FOR_INSN (NEXT_INSN (label
));
7824 if (succ_bb
&& REGNO_REG_SET_P (df_get_live_out (succ_bb
), LP_COUNT
))
7831 A write to a core reg greater or equal to 32 must not be immediately
7832 followed by a use. Anticipate the length requirement to insert a nop
7833 between PRED and SUCC to prevent a hazard. */
7836 arc_hazard (rtx_insn
*pred
, rtx_insn
*succ
)
7838 if (!pred
|| !INSN_P (pred
) || !succ
|| !INSN_P (succ
))
7841 if (arc_loop_hazard (pred
, succ
))
7845 return arc600_corereg_hazard (pred
, succ
);
7850 /* Return length adjustment for INSN. */
7853 arc_adjust_insn_length (rtx_insn
*insn
, int len
, bool)
7857 /* We already handle sequences by ignoring the delay sequence flag. */
7858 if (GET_CODE (PATTERN (insn
)) == SEQUENCE
)
7861 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
7862 the ZOL mechanism only triggers when advancing to the end address,
7863 so if there's a label at the end of a ZOL, we need to insert a nop.
7864 The ARC600 ZOL also has extra restrictions on jumps at the end of a
7866 if (recog_memoized (insn
) == CODE_FOR_doloop_end_i
)
7868 rtx_insn
*prev
= prev_nonnote_insn (insn
);
7870 return ((LABEL_P (prev
)
7873 || CALL_P (prev
) /* Could be a noreturn call. */
7874 || (NONJUMP_INSN_P (prev
)
7875 && GET_CODE (PATTERN (prev
)) == SEQUENCE
))))
7879 /* Check for return with but one preceding insn since function
7881 if (TARGET_PAD_RETURN
7883 && GET_CODE (PATTERN (insn
)) != ADDR_VEC
7884 && GET_CODE (PATTERN (insn
)) != ADDR_DIFF_VEC
7885 && get_attr_type (insn
) == TYPE_RETURN
)
7887 rtx_insn
*prev
= prev_active_insn (insn
);
7889 if (!prev
|| !(prev
= prev_active_insn (prev
))
7890 || ((NONJUMP_INSN_P (prev
)
7891 && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
7892 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
7894 : CALL_ATTR (prev
, NON_SIBCALL
)))
7899 rtx_insn
*succ
= next_real_insn (insn
);
7901 /* One the ARC600, a write to an extension register must be separated
7903 if (succ
&& INSN_P (succ
))
7904 len
+= arc600_corereg_hazard (insn
, succ
);
7907 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
7909 extract_constrain_insn_cached (insn
);
7914 /* Values for length_sensitive. */
7918 ARC_LS_25
, // 25 bit offset, B
7919 ARC_LS_21
, // 21 bit offset, Bcc
7920 ARC_LS_U13
,// 13 bit unsigned offset, LP
7921 ARC_LS_10
, // 10 bit offset, B_s, Beq_s, Bne_s
7922 ARC_LS_9
, // 9 bit offset, BRcc
7923 ARC_LS_8
, // 8 bit offset, BRcc_s
7924 ARC_LS_U7
, // 7 bit unsigned offset, LPcc
7925 ARC_LS_7
// 7 bit offset, Bcc_s
7928 /* While the infrastructure patch is waiting for review, duplicate the
7929 struct definitions, to allow this file to compile. */
7934 /* Cost as a branch / call target or call return address. */
7936 int fallthrough_cost
;
7939 /* 0 for not length sensitive, 1 for largest offset range,
7940 * 2 for next smaller etc. */
7941 unsigned length_sensitive
: 8;
7943 } insn_length_variant_t
;
7945 typedef struct insn_length_parameters_s
7950 int (*get_variants
) (rtx_insn
*, int, bool, bool, insn_length_variant_t
*);
7951 } insn_length_parameters_t
;
7954 arc_insn_length_parameters (insn_length_parameters_t
*ilp
) ATTRIBUTE_UNUSED
;
7958 arc_get_insn_variants (rtx_insn
*insn
, int len
, bool, bool target_p
,
7959 insn_length_variant_t
*ilv
)
7961 if (!NONDEBUG_INSN_P (insn
))
7963 enum attr_type type
;
7964 /* shorten_branches doesn't take optimize_size into account yet for the
7965 get_variants mechanism, so turn this off for now. */
7968 if (rtx_sequence
*pat
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
7970 /* The interaction of a short delay slot insn with a short branch is
7971 too weird for shorten_branches to piece together, so describe the
7974 if (TARGET_UPSIZE_DBR
7975 && get_attr_length (pat
->insn (1)) <= 2
7976 && (((type
= get_attr_type (inner
= pat
->insn (0)))
7977 == TYPE_UNCOND_BRANCH
)
7978 || type
== TYPE_BRANCH
)
7979 && get_attr_delay_slot_filled (inner
) == DELAY_SLOT_FILLED_YES
)
7982 = arc_get_insn_variants (inner
, get_attr_length (inner
), true,
7984 /* The short variant gets split into a higher-cost aligned
7985 and a lower cost unaligned variant. */
7986 gcc_assert (n_variants
);
7987 gcc_assert (ilv
[1].length_sensitive
== ARC_LS_7
7988 || ilv
[1].length_sensitive
== ARC_LS_10
);
7989 gcc_assert (ilv
[1].align_set
== 3);
7991 ilv
[0].align_set
= 1;
7992 ilv
[0].branch_cost
+= 1;
7993 ilv
[1].align_set
= 2;
7995 for (int i
= 0; i
< n_variants
; i
++)
7997 /* In case an instruction with aligned size is wanted, and
7998 the short variants are unavailable / too expensive, add
7999 versions of long branch + long delay slot. */
8000 for (int i
= 2, end
= n_variants
; i
< end
; i
++, n_variants
++)
8002 ilv
[n_variants
] = ilv
[i
];
8003 ilv
[n_variants
].length
+= 2;
8009 insn_length_variant_t
*first_ilv
= ilv
;
8010 type
= get_attr_type (insn
);
8012 = (get_attr_delay_slot_filled (insn
) == DELAY_SLOT_FILLED_YES
);
8013 int branch_align_cost
= delay_filled
? 0 : 1;
8014 int branch_unalign_cost
= delay_filled
? 0 : TARGET_UNALIGN_BRANCH
? 0 : 1;
8015 /* If the previous instruction is an sfunc call, this insn is always
8016 a target, even though the middle-end is unaware of this. */
8017 bool force_target
= false;
8018 rtx_insn
*prev
= prev_active_insn (insn
);
8019 if (prev
&& arc_next_active_insn (prev
, 0) == insn
8020 && ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8021 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8023 : (CALL_ATTR (prev
, NON_SIBCALL
)
8024 && NEXT_INSN (PREV_INSN (prev
)) == prev
)))
8025 force_target
= true;
8030 /* Short BRCC only comes in no-delay-slot version, and without limm */
8035 ilv
->branch_cost
= 1;
8036 ilv
->enabled
= (len
== 2);
8037 ilv
->length_sensitive
= ARC_LS_8
;
8041 case TYPE_BRCC_NO_DELAY_SLOT
:
8042 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8043 (delay slot) scheduling purposes, but they are longer. */
8044 if (GET_CODE (PATTERN (insn
)) == PARALLEL
8045 && GET_CODE (XVECEXP (PATTERN (insn
), 0, 1)) == SET
)
8047 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8048 ilv
->length
= ((type
== TYPE_BRCC
) ? 4 : 8);
8050 ilv
->branch_cost
= branch_align_cost
;
8051 ilv
->enabled
= (len
<= ilv
->length
);
8052 ilv
->length_sensitive
= ARC_LS_9
;
8053 if ((target_p
|| force_target
)
8054 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8060 ilv
->target_cost
= 1;
8061 ilv
->branch_cost
= branch_unalign_cost
;
8066 op
= XEXP (SET_SRC (XVECEXP (PATTERN (insn
), 0, 0)), 0);
8069 if (GET_CODE (op0
) == ZERO_EXTRACT
8070 && satisfies_constraint_L (XEXP (op0
, 2)))
8071 op0
= XEXP (op0
, 0);
8072 if (satisfies_constraint_Rcq (op0
))
8074 ilv
->length
= ((type
== TYPE_BRCC
) ? 6 : 10);
8076 ilv
->branch_cost
= 1 + branch_align_cost
;
8077 ilv
->fallthrough_cost
= 1;
8078 ilv
->enabled
= true;
8079 ilv
->length_sensitive
= ARC_LS_21
;
8080 if (!delay_filled
&& TARGET_UNALIGN_BRANCH
)
8086 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8090 ilv
->length
= ((type
== TYPE_BRCC
) ? 8 : 12);
8092 ilv
->branch_cost
= 1 + branch_align_cost
;
8093 ilv
->fallthrough_cost
= 1;
8094 ilv
->enabled
= true;
8095 ilv
->length_sensitive
= ARC_LS_21
;
8096 if ((target_p
|| force_target
)
8097 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8103 ilv
->target_cost
= 1;
8104 ilv
->branch_cost
= 1 + branch_unalign_cost
;
8112 case TYPE_CALL_NO_DELAY_SLOT
:
8117 ilv
->length_sensitive
8118 = GET_CODE (PATTERN (insn
)) == COND_EXEC
? ARC_LS_21
: ARC_LS_25
;
8121 ilv
->fallthrough_cost
= branch_align_cost
;
8122 ilv
->enabled
= true;
8123 if ((target_p
|| force_target
)
8124 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8130 ilv
->target_cost
= 1;
8131 ilv
->fallthrough_cost
= branch_unalign_cost
;
8135 case TYPE_UNCOND_BRANCH
:
8136 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8137 but that makes no difference at the moment. */
8138 ilv
->length_sensitive
= ARC_LS_7
;
8139 ilv
[1].length_sensitive
= ARC_LS_25
;
8142 ilv
->length_sensitive
= ARC_LS_10
;
8143 ilv
[1].length_sensitive
= ARC_LS_21
;
8147 ilv
->branch_cost
= branch_align_cost
;
8148 ilv
->enabled
= (len
== ilv
->length
);
8152 ilv
->branch_cost
= branch_align_cost
;
8153 ilv
->enabled
= true;
8154 if ((target_p
|| force_target
)
8155 || (!delay_filled
&& TARGET_UNALIGN_BRANCH
))
8161 ilv
->target_cost
= 1;
8162 ilv
->branch_cost
= branch_unalign_cost
;
8169 /* For every short insn, there is generally also a long insn.
8170 trap_s is an exception. */
8171 if ((len
& 2) == 0 || recog_memoized (insn
) == CODE_FOR_trap_s
)
8178 ilv
->length
= len
+ 2;
8180 if (target_p
|| force_target
)
8186 ilv
->target_cost
= 1;
8190 /* If the previous instruction is an sfunc call, this insn is always
8191 a target, even though the middle-end is unaware of this.
8192 Therefore, if we have a call predecessor, transfer the target cost
8193 to the fallthrough and branch costs. */
8196 for (insn_length_variant_t
*p
= first_ilv
; p
< ilv
; p
++)
8198 p
->fallthrough_cost
+= p
->target_cost
;
8199 p
->branch_cost
+= p
->target_cost
;
8204 return ilv
- first_ilv
;
8208 arc_insn_length_parameters (insn_length_parameters_t
*ilp
)
8210 ilp
->align_unit_log
= 1;
8211 ilp
->align_base_log
= 1;
8212 ilp
->max_variants
= 7;
8213 ilp
->get_variants
= arc_get_insn_variants
;
8216 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8217 CC field of *STATEP. */
8220 arc_get_ccfsm_cond (struct arc_ccfsm
*statep
, bool reverse
)
8222 rtx cond
= statep
->cond
;
8223 int raw_cc
= get_arc_condition_code (cond
);
8225 raw_cc
= ARC_INVERSE_CONDITION_CODE (raw_cc
);
8227 if (statep
->cc
== raw_cc
)
8228 return copy_rtx (cond
);
8230 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc
) == statep
->cc
);
8232 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8233 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8234 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8235 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8237 return gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8238 copy_rtx (XEXP (cond
, 0)), copy_rtx (XEXP (cond
, 1)));
8241 /* Return version of PAT conditionalized with COND, which is part of INSN.
8242 ANNULLED indicates if INSN is an annulled delay-slot insn.
8243 Register further changes if necessary. */
8245 conditionalize_nonjump (rtx pat
, rtx cond
, rtx insn
, bool annulled
)
8247 /* For commutative operators, we generally prefer to have
8248 the first source match the destination. */
8249 if (GET_CODE (pat
) == SET
)
8251 rtx src
= SET_SRC (pat
);
8253 if (COMMUTATIVE_P (src
))
8255 rtx src0
= XEXP (src
, 0);
8256 rtx src1
= XEXP (src
, 1);
8257 rtx dst
= SET_DEST (pat
);
8259 if (rtx_equal_p (src1
, dst
) && !rtx_equal_p (src0
, dst
)
8260 /* Leave add_n alone - the canonical form is to
8261 have the complex summand first. */
8263 pat
= gen_rtx_SET (dst
,
8264 gen_rtx_fmt_ee (GET_CODE (src
), GET_MODE (src
),
8269 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8270 what to do with COND_EXEC. */
8271 if (RTX_FRAME_RELATED_P (insn
))
8273 /* If this is the delay slot insn of an anulled branch,
8274 dwarf2out.c:scan_trace understands the anulling semantics
8275 without the COND_EXEC. */
8276 gcc_assert (annulled
);
8277 rtx note
= alloc_reg_note (REG_FRAME_RELATED_EXPR
, pat
,
8279 validate_change (insn
, ®_NOTES (insn
), note
, 1);
8281 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8285 /* Use the ccfsm machinery to do if conversion. */
8290 struct arc_ccfsm
*statep
= &cfun
->machine
->ccfsm_current
;
8291 basic_block merge_bb
= 0;
8293 memset (statep
, 0, sizeof *statep
);
8294 for (rtx_insn
*insn
= get_insns (); insn
; insn
= next_insn (insn
))
8296 arc_ccfsm_advance (insn
, statep
);
8298 switch (statep
->state
)
8306 /* Deleted branch. */
8307 gcc_assert (!merge_bb
);
8308 merge_bb
= BLOCK_FOR_INSN (insn
);
8310 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn
))));
8311 arc_ccfsm_post_advance (insn
, statep
);
8312 gcc_assert (!IN_RANGE (statep
->state
, 1, 2));
8313 rtx_insn
*seq
= NEXT_INSN (PREV_INSN (insn
));
8316 rtx slot
= XVECEXP (PATTERN (seq
), 0, 1);
8317 rtx pat
= PATTERN (slot
);
8318 if (INSN_ANNULLED_BRANCH_P (insn
))
8321 = arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (slot
));
8322 pat
= gen_rtx_COND_EXEC (VOIDmode
, cond
, pat
);
8324 if (!validate_change (seq
, &PATTERN (seq
), pat
, 0))
8326 PUT_CODE (slot
, NOTE
);
8327 NOTE_KIND (slot
) = NOTE_INSN_DELETED
;
8328 if (merge_bb
&& succ_bb
)
8329 merge_blocks (merge_bb
, succ_bb
);
8331 else if (merge_bb
&& succ_bb
)
8333 set_insn_deleted (insn
);
8334 merge_blocks (merge_bb
, succ_bb
);
8338 PUT_CODE (insn
, NOTE
);
8339 NOTE_KIND (insn
) = NOTE_INSN_DELETED
;
8345 && statep
->target_label
== CODE_LABEL_NUMBER (insn
))
8347 arc_ccfsm_post_advance (insn
, statep
);
8348 basic_block succ_bb
= BLOCK_FOR_INSN (insn
);
8349 if (merge_bb
&& succ_bb
)
8350 merge_blocks (merge_bb
, succ_bb
);
8351 else if (--LABEL_NUSES (insn
) == 0)
8353 const char *name
= LABEL_NAME (insn
);
8354 PUT_CODE (insn
, NOTE
);
8355 NOTE_KIND (insn
) = NOTE_INSN_DELETED_LABEL
;
8356 NOTE_DELETED_LABEL_NAME (insn
) = name
;
8363 if (!NONDEBUG_INSN_P (insn
))
8366 /* Conditionalized insn. */
8368 rtx_insn
*prev
, *pprev
;
8369 rtx
*patp
, pat
, cond
;
8370 bool annulled
; annulled
= false;
8372 /* If this is a delay slot insn in a non-annulled branch,
8373 don't conditionalize it. N.B., this should be fine for
8374 conditional return too. However, don't do this for
8375 unconditional branches, as these would be encountered when
8376 processing an 'else' part. */
8377 prev
= PREV_INSN (insn
);
8378 pprev
= PREV_INSN (prev
);
8379 if (pprev
&& NEXT_INSN (NEXT_INSN (pprev
)) == NEXT_INSN (insn
)
8380 && JUMP_P (prev
) && get_attr_cond (prev
) == COND_USE
)
8382 if (!INSN_ANNULLED_BRANCH_P (prev
))
8387 patp
= &PATTERN (insn
);
8389 cond
= arc_get_ccfsm_cond (statep
, INSN_FROM_TARGET_P (insn
));
8390 if (NONJUMP_INSN_P (insn
) || CALL_P (insn
))
8392 /* ??? don't conditionalize if all side effects are dead
8393 in the not-execute case. */
8395 pat
= conditionalize_nonjump (pat
, cond
, insn
, annulled
);
8397 else if (simplejump_p (insn
))
8399 patp
= &SET_SRC (pat
);
8400 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, *patp
, pc_rtx
);
8402 else if (JUMP_P (insn
) && ANY_RETURN_P (PATTERN (insn
)))
8404 pat
= gen_rtx_IF_THEN_ELSE (VOIDmode
, cond
, pat
, pc_rtx
);
8405 pat
= gen_rtx_SET (pc_rtx
, pat
);
8409 validate_change (insn
, patp
, pat
, 1);
8410 if (!apply_change_group ())
8414 rtx_insn
*next
= next_nonnote_insn (insn
);
8415 if (GET_CODE (next
) == BARRIER
)
8417 if (statep
->state
== 3)
8424 arc_ccfsm_post_advance (insn
, statep
);
8429 /* Find annulled delay insns and convert them to use the appropriate predicate.
8430 This allows branch shortening to size up these insns properly. */
8433 arc_predicate_delay_insns (void)
8435 for (rtx_insn
*insn
= get_insns (); insn
; insn
= NEXT_INSN (insn
))
8437 rtx pat
, jump
, dlay
, src
, cond
, *patp
;
8440 if (!NONJUMP_INSN_P (insn
)
8441 || GET_CODE (pat
= PATTERN (insn
)) != SEQUENCE
)
8443 jump
= XVECEXP (pat
, 0, 0);
8444 dlay
= XVECEXP (pat
, 0, 1);
8445 if (!JUMP_P (jump
) || !INSN_ANNULLED_BRANCH_P (jump
))
8447 /* If the branch insn does the annulling, leave the delay insn alone. */
8448 if (!TARGET_AT_DBR_CONDEXEC
&& !INSN_FROM_TARGET_P (dlay
))
8450 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8451 on the other path. */
8452 gcc_assert (GET_CODE (PATTERN (jump
)) == SET
);
8453 gcc_assert (SET_DEST (PATTERN (jump
)) == pc_rtx
);
8454 src
= SET_SRC (PATTERN (jump
));
8455 gcc_assert (GET_CODE (src
) == IF_THEN_ELSE
);
8456 cond
= XEXP (src
, 0);
8457 if (XEXP (src
, 2) == pc_rtx
)
8459 else if (XEXP (src
, 1) == pc_rtx
)
8463 if (reverse
!= !INSN_FROM_TARGET_P (dlay
))
8465 machine_mode ccm
= GET_MODE (XEXP (cond
, 0));
8466 enum rtx_code code
= reverse_condition (GET_CODE (cond
));
8467 if (code
== UNKNOWN
|| ccm
== CC_FP_GTmode
|| ccm
== CC_FP_GEmode
)
8468 code
= reverse_condition_maybe_unordered (GET_CODE (cond
));
8470 cond
= gen_rtx_fmt_ee (code
, GET_MODE (cond
),
8471 copy_rtx (XEXP (cond
, 0)),
8472 copy_rtx (XEXP (cond
, 1)));
8475 cond
= copy_rtx (cond
);
8476 patp
= &PATTERN (dlay
);
8478 pat
= conditionalize_nonjump (pat
, cond
, dlay
, true);
8479 validate_change (dlay
, patp
, pat
, 1);
8480 if (!apply_change_group ())
8486 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
8487 (other than of a forward brcc), it creates a hazard when there is a read
8488 of the same register at the branch target. We can't know what is at the
8489 branch target of calls, and for branches, we don't really know before the
8490 end of delay slot scheduling, either. Not only can individual instruction
8491 be hoisted out into a delay slot, a basic block can also be emptied this
8492 way, and branch and/or fall through targets be redirected. Hence we don't
8493 want such writes in a delay slot. */
8495 /* Return nonzreo iff INSN writes to an extension core register. */
8498 arc_write_ext_corereg (rtx insn
)
8500 subrtx_iterator::array_type array
;
8501 FOR_EACH_SUBRTX (iter
, array
, PATTERN (insn
), NONCONST
)
8503 const_rtx x
= *iter
;
8504 switch (GET_CODE (x
))
8506 case SET
: case POST_INC
: case POST_DEC
: case PRE_INC
: case PRE_DEC
:
8509 /* This is also fine for PRE/POST_MODIFY, because they
8513 const_rtx dest
= XEXP (x
, 0);
8514 if (REG_P (dest
) && REGNO (dest
) >= 32 && REGNO (dest
) < 61)
8520 /* This is like the hook, but returns NULL when it can't / won't generate
8521 a legitimate address. */
8524 arc_legitimize_address_0 (rtx x
, rtx oldx ATTRIBUTE_UNUSED
,
8529 if (flag_pic
&& SYMBOLIC_CONST (x
))
8530 (x
) = arc_legitimize_pic_address (x
, 0);
8532 if (GET_CODE (addr
) == CONST
)
8533 addr
= XEXP (addr
, 0);
8534 if (GET_CODE (addr
) == PLUS
8535 && CONST_INT_P (XEXP (addr
, 1))
8536 && ((GET_CODE (XEXP (addr
, 0)) == SYMBOL_REF
8537 && !SYMBOL_REF_FUNCTION_P (XEXP (addr
, 0)))
8538 || (REG_P (XEXP (addr
, 0))
8539 && (INTVAL (XEXP (addr
, 1)) & 252))))
8541 HOST_WIDE_INT offs
, upper
;
8542 int size
= GET_MODE_SIZE (mode
);
8544 offs
= INTVAL (XEXP (addr
, 1));
8545 upper
= (offs
+ 256 * size
) & ~511 * size
;
8546 inner
= plus_constant (Pmode
, XEXP (addr
, 0), upper
);
8547 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
8548 if (GET_CODE (x
) == CONST
)
8549 inner
= gen_rtx_CONST (Pmode
, inner
);
8551 addr
= plus_constant (Pmode
, force_reg (Pmode
, inner
), offs
- upper
);
8554 else if (GET_CODE (addr
) == SYMBOL_REF
&& !SYMBOL_REF_FUNCTION_P (addr
))
8555 x
= force_reg (Pmode
, x
);
8556 if (memory_address_p ((machine_mode
) mode
, x
))
8562 arc_legitimize_address (rtx orig_x
, rtx oldx
, machine_mode mode
)
8564 if (GET_CODE (orig_x
) == SYMBOL_REF
)
8566 enum tls_model model
= SYMBOL_REF_TLS_MODEL (orig_x
);
8568 return arc_legitimize_tls_address (orig_x
, model
);
8571 rtx new_x
= arc_legitimize_address_0 (orig_x
, oldx
, mode
);
8579 arc_delegitimize_address_0 (rtx x
)
8583 if (GET_CODE (x
) == CONST
&& GET_CODE (u
= XEXP (x
, 0)) == UNSPEC
)
8585 if (XINT (u
, 1) == ARC_UNSPEC_GOT
)
8586 return XVECEXP (u
, 0, 0);
8588 else if (GET_CODE (x
) == PLUS
8589 && ((REG_P (gp
= XEXP (x
, 0))
8590 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
8591 || (GET_CODE (gp
) == CONST
8592 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
8593 && XINT (u
, 1) == ARC_UNSPEC_GOT
8594 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
8595 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
8596 && GET_CODE (XEXP (x
, 1)) == CONST
8597 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
8598 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
8599 return XVECEXP (u
, 0, 0);
8600 else if (GET_CODE (x
) == PLUS
&& GET_CODE (XEXP (x
, 0)) == PLUS
8601 && ((REG_P (gp
= XEXP (XEXP (x
, 0), 1))
8602 && REGNO (gp
) == PIC_OFFSET_TABLE_REGNUM
)
8603 || (GET_CODE (gp
) == CONST
8604 && GET_CODE (u
= XEXP (gp
, 0)) == UNSPEC
8605 && XINT (u
, 1) == ARC_UNSPEC_GOT
8606 && GET_CODE (XVECEXP (u
, 0, 0)) == SYMBOL_REF
8607 && !strcmp (XSTR (XVECEXP (u
, 0, 0), 0), "_DYNAMIC")))
8608 && GET_CODE (XEXP (x
, 1)) == CONST
8609 && GET_CODE (u
= XEXP (XEXP (x
, 1), 0)) == UNSPEC
8610 && XINT (u
, 1) == ARC_UNSPEC_GOTOFF
)
8611 return gen_rtx_PLUS (GET_MODE (x
), XEXP (XEXP (x
, 0), 0),
8613 else if (GET_CODE (x
) == PLUS
8614 && (u
= arc_delegitimize_address_0 (XEXP (x
, 1))))
8615 return gen_rtx_PLUS (GET_MODE (x
), XEXP (x
, 0), u
);
8620 arc_delegitimize_address (rtx x
)
8622 rtx orig_x
= x
= delegitimize_mem_from_attrs (x
);
8623 if (GET_CODE (x
) == MEM
)
8625 x
= arc_delegitimize_address_0 (x
);
8629 x
= replace_equiv_address_nv (orig_x
, x
);
8635 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
8636 differ from the hardware register number in order to allow the generic
8637 code to correctly split the concatenation of acc1 and acc2. */
8642 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 56: 57);
8645 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
8646 differ from the hardware register number in order to allow the generic
8647 code to correctly split the concatenation of acc1 and acc2. */
8652 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 57: 56);
8655 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
8656 differ from the hardware register number in order to allow the generic
8657 code to correctly split the concatenation of mhi and mlo. */
8662 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 59: 58);
8665 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
8666 differ from the hardware register number in order to allow the generic
8667 code to correctly split the concatenation of mhi and mlo. */
8672 return gen_rtx_REG (SImode
, TARGET_BIG_ENDIAN
? 58: 59);
8675 /* FIXME: a parameter should be added, and code added to final.c,
8676 to reproduce this functionality in shorten_branches. */
8678 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
8679 a previous instruction. */
8681 arc_unalign_branch_p (rtx branch
)
8685 if (!TARGET_UNALIGN_BRANCH
)
8687 /* Do not do this if we have a filled delay slot. */
8688 if (get_attr_delay_slot_filled (branch
) == DELAY_SLOT_FILLED_YES
8689 && !NEXT_INSN (branch
)->deleted ())
8691 note
= find_reg_note (branch
, REG_BR_PROB
, 0);
8693 || (arc_unalign_prob_threshold
&& !br_prob_note_reliable_p (note
))
8694 || INTVAL (XEXP (note
, 0)) < arc_unalign_prob_threshold
);
8698 /* When estimating sizes during arc_reorg, when optimizing for speed, there
8699 are three reasons why we need to consider branches to be length 6:
8700 - annull-false delay slot insns are implemented using conditional execution,
8701 thus preventing short insn formation where used.
8702 - for ARC600: annul-true delay slot insns are implemented where possible
8703 using conditional execution, preventing short insn formation where used.
8704 - for ARC700: likely or somewhat likely taken branches are made long and
8705 unaligned if possible to avoid branch penalty. */
8708 arc_branch_size_unknown_p (void)
8710 return !optimize_size
&& arc_reorg_in_progress
;
8713 /* We are about to output a return insn. Add padding if necessary to avoid
8714 a mispredict. A return could happen immediately after the function
8715 start, but after a call we know that there will be at least a blink
8719 arc_pad_return (void)
8721 rtx_insn
*insn
= current_output_insn
;
8722 rtx_insn
*prev
= prev_active_insn (insn
);
8727 fputs ("\tnop_s\n", asm_out_file
);
8728 cfun
->machine
->unalign
^= 2;
8731 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
8732 because after a call, we'd have to restore blink first. */
8733 else if (GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8737 want_long
= (get_attr_length (prev
) == 2);
8738 prev
= prev_active_insn (prev
);
8741 || ((NONJUMP_INSN_P (prev
) && GET_CODE (PATTERN (prev
)) == SEQUENCE
)
8742 ? CALL_ATTR (as_a
<rtx_sequence
*> (PATTERN (prev
))->insn (0),
8744 : CALL_ATTR (prev
, NON_SIBCALL
)))
8747 cfun
->machine
->size_reason
8748 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
8749 else if (TARGET_UNALIGN_BRANCH
&& cfun
->machine
->unalign
)
8751 cfun
->machine
->size_reason
8752 = "Long unaligned jump avoids non-delay slot penalty";
8755 /* Disgorge delay insn, if there is any, and it may be moved. */
8757 /* ??? Annulled would be OK if we can and do conditionalize
8758 the delay slot insn accordingly. */
8759 && !INSN_ANNULLED_BRANCH_P (insn
)
8760 && (get_attr_cond (insn
) != COND_USE
8761 || !reg_set_p (gen_rtx_REG (CCmode
, CC_REG
),
8762 XVECEXP (final_sequence
, 0, 1))))
8764 prev
= as_a
<rtx_insn
*> (XVECEXP (final_sequence
, 0, 1));
8765 gcc_assert (!prev_real_insn (insn
)
8766 || !arc_hazard (prev_real_insn (insn
), prev
));
8767 cfun
->machine
->force_short_suffix
= !want_long
;
8768 rtx save_pred
= current_insn_predicate
;
8769 final_scan_insn (prev
, asm_out_file
, optimize
, 1, NULL
);
8770 cfun
->machine
->force_short_suffix
= -1;
8771 prev
->set_deleted ();
8772 current_output_insn
= insn
;
8773 current_insn_predicate
= save_pred
;
8776 fputs ("\tnop\n", asm_out_file
);
8779 fputs ("\tnop_s\n", asm_out_file
);
8780 cfun
->machine
->unalign
^= 2;
8786 /* The usual; we set up our machine_function data. */
8788 static struct machine_function
*
8789 arc_init_machine_status (void)
8791 struct machine_function
*machine
;
8792 machine
= ggc_cleared_alloc
<machine_function
> ();
8793 machine
->fn_type
= ARC_FUNCTION_UNKNOWN
;
8794 machine
->force_short_suffix
= -1;
8799 /* Implements INIT_EXPANDERS. We just set up to call the above
8803 arc_init_expanders (void)
8805 init_machine_status
= arc_init_machine_status
;
8808 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
8809 indicates a number of elements to ignore - that allows to have a
8810 sibcall pattern that starts with (return). LOAD_P is zero for store
8811 multiple (for prologues), and one for load multiples (for epilogues),
8812 and two for load multiples where no final clobber of blink is required.
8813 We also skip the first load / store element since this is supposed to
8814 be checked in the instruction pattern. */
8817 arc_check_millicode (rtx op
, int offset
, int load_p
)
8819 int len
= XVECLEN (op
, 0) - offset
;
8824 if (len
< 2 || len
> 13)
8830 rtx elt
= XVECEXP (op
, 0, --len
);
8832 if (GET_CODE (elt
) != CLOBBER
8833 || !REG_P (XEXP (elt
, 0))
8834 || REGNO (XEXP (elt
, 0)) != RETURN_ADDR_REGNUM
8835 || len
< 3 || len
> 13)
8838 for (i
= 1; i
< len
; i
++)
8840 rtx elt
= XVECEXP (op
, 0, i
+ offset
);
8843 if (GET_CODE (elt
) != SET
)
8845 mem
= XEXP (elt
, load_p
);
8846 reg
= XEXP (elt
, 1-load_p
);
8847 if (!REG_P (reg
) || REGNO (reg
) != 13U+i
|| !MEM_P (mem
))
8849 addr
= XEXP (mem
, 0);
8850 if (GET_CODE (addr
) != PLUS
8851 || !rtx_equal_p (stack_pointer_rtx
, XEXP (addr
, 0))
8852 || !CONST_INT_P (XEXP (addr
, 1)) || INTVAL (XEXP (addr
, 1)) != i
*4)
8858 /* Accessor functions for cfun->machine->unalign. */
8861 arc_get_unalign (void)
8863 return cfun
->machine
->unalign
;
8867 arc_clear_unalign (void)
8870 cfun
->machine
->unalign
= 0;
8874 arc_toggle_unalign (void)
8876 cfun
->machine
->unalign
^= 2;
8879 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
8880 constant in operand 2, but which would require a LIMM because of
8882 operands 3 and 4 are new SET_SRCs for operands 0. */
8885 split_addsi (rtx
*operands
)
8887 int val
= INTVAL (operands
[2]);
8889 /* Try for two short insns first. Lengths being equal, we prefer
8890 expansions with shorter register lifetimes. */
8891 if (val
> 127 && val
<= 255
8892 && satisfies_constraint_Rcq (operands
[0]))
8894 operands
[3] = operands
[2];
8895 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
8899 operands
[3] = operands
[1];
8900 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[2]);
8904 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
8905 constant in operand 1, but which would require a LIMM because of
8907 operands 3 and 4 are new SET_SRCs for operands 0. */
8910 split_subsi (rtx
*operands
)
8912 int val
= INTVAL (operands
[1]);
8914 /* Try for two short insns first. Lengths being equal, we prefer
8915 expansions with shorter register lifetimes. */
8916 if (satisfies_constraint_Rcq (operands
[0])
8917 && satisfies_constraint_Rcq (operands
[2]))
8919 if (val
>= -31 && val
<= 127)
8921 operands
[3] = gen_rtx_NEG (SImode
, operands
[2]);
8922 operands
[4] = gen_rtx_PLUS (SImode
, operands
[0], operands
[1]);
8925 else if (val
>= 0 && val
< 255)
8927 operands
[3] = operands
[1];
8928 operands
[4] = gen_rtx_MINUS (SImode
, operands
[0], operands
[2]);
8932 /* If the destination is not an ARCompact16 register, we might
8933 still have a chance to make a short insn if the source is;
8934 we need to start with a reg-reg move for this. */
8935 operands
[3] = operands
[2];
8936 operands
[4] = gen_rtx_MINUS (SImode
, operands
[1], operands
[0]);
8939 /* Handle DOUBLE_REGS uses.
8940 Operand 0: destination register
8941 Operand 1: source register */
8944 arc_process_double_reg_moves (rtx
*operands
)
8946 rtx dest
= operands
[0];
8947 rtx src
= operands
[1];
8949 enum usesDxState
{ none
, srcDx
, destDx
, maxDx
};
8950 enum usesDxState state
= none
;
8952 if (refers_to_regno_p (40, 44, src
, 0))
8954 if (refers_to_regno_p (40, 44, dest
, 0))
8956 /* Via arc_register_move_cost, we should never see D,D moves. */
8957 gcc_assert (state
== none
);
8966 /* Without the LR insn, we need to split this into a
8967 sequence of insns which will use the DEXCLx and DADDHxy
8968 insns to be able to read the Dx register in question. */
8969 if (TARGET_DPFP_DISABLE_LRSR
)
8971 /* gen *movdf_insn_nolrsr */
8972 rtx set
= gen_rtx_SET (dest
, src
);
8973 rtx use1
= gen_rtx_USE (VOIDmode
, const1_rtx
);
8974 emit_insn (gen_rtx_PARALLEL (VOIDmode
, gen_rtvec (2, set
, use1
)));
8978 /* When we have 'mov D, r' or 'mov D, D' then get the target
8979 register pair for use with LR insn. */
8980 rtx destHigh
= simplify_gen_subreg (SImode
, dest
, DFmode
,
8981 TARGET_BIG_ENDIAN
? 0 : 4);
8982 rtx destLow
= simplify_gen_subreg (SImode
, dest
, DFmode
,
8983 TARGET_BIG_ENDIAN
? 4 : 0);
8985 /* Produce the two LR insns to get the high and low parts. */
8986 emit_insn (gen_rtx_SET (destHigh
,
8987 gen_rtx_UNSPEC_VOLATILE (Pmode
,
8989 VUNSPEC_ARC_LR_HIGH
)));
8990 emit_insn (gen_rtx_SET (destLow
,
8991 gen_rtx_UNSPEC_VOLATILE (Pmode
,
8996 else if (state
== destDx
)
8998 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
8999 LR insn get the target register pair. */
9000 rtx srcHigh
= simplify_gen_subreg (SImode
, src
, DFmode
,
9001 TARGET_BIG_ENDIAN
? 0 : 4);
9002 rtx srcLow
= simplify_gen_subreg (SImode
, src
, DFmode
,
9003 TARGET_BIG_ENDIAN
? 4 : 0);
9005 emit_insn (gen_rtx_UNSPEC_VOLATILE (Pmode
,
9006 gen_rtvec (3, dest
, srcHigh
, srcLow
),
9007 VUNSPEC_ARC_DEXCL_NORES
));
9016 /* operands 0..1 are the operands of a 64 bit move instruction.
9017 split it into two moves with operands 2/3 and 4/5. */
9020 arc_split_move (rtx
*operands
)
9022 machine_mode mode
= GET_MODE (operands
[0]);
9029 if (arc_process_double_reg_moves (operands
))
9034 && ((memory_operand (operands
[0], mode
)
9035 && even_register_operand (operands
[1], mode
))
9036 || (memory_operand (operands
[1], mode
)
9037 && even_register_operand (operands
[0], mode
))))
9039 emit_move_insn (operands
[0], operands
[1]);
9043 if (TARGET_PLUS_QMACW
9044 && GET_CODE (operands
[1]) == CONST_VECTOR
)
9046 HOST_WIDE_INT intval0
, intval1
;
9047 if (GET_MODE (operands
[1]) == V2SImode
)
9049 intval0
= INTVAL (XVECEXP (operands
[1], 0, 0));
9050 intval1
= INTVAL (XVECEXP (operands
[1], 0, 1));
9054 intval1
= INTVAL (XVECEXP (operands
[1], 0, 3)) << 16;
9055 intval1
|= INTVAL (XVECEXP (operands
[1], 0, 2)) & 0xFFFF;
9056 intval0
= INTVAL (XVECEXP (operands
[1], 0, 1)) << 16;
9057 intval0
|= INTVAL (XVECEXP (operands
[1], 0, 0)) & 0xFFFF;
9059 xop
[0] = gen_rtx_REG (SImode
, REGNO (operands
[0]));
9060 xop
[3] = gen_rtx_REG (SImode
, REGNO (operands
[0]) + 1);
9061 xop
[2] = GEN_INT (trunc_int_for_mode (intval0
, SImode
));
9062 xop
[1] = GEN_INT (trunc_int_for_mode (intval1
, SImode
));
9063 emit_move_insn (xop
[0], xop
[2]);
9064 emit_move_insn (xop
[3], xop
[1]);
9068 for (i
= 0; i
< 2; i
++)
9070 if (MEM_P (operands
[i
]) && auto_inc_p (XEXP (operands
[i
], 0)))
9072 rtx addr
= XEXP (operands
[i
], 0);
9076 gcc_assert (!reg_overlap_mentioned_p (operands
[0], addr
));
9077 switch (GET_CODE (addr
))
9079 case PRE_DEC
: o
= GEN_INT (-8); goto pre_modify
;
9080 case PRE_INC
: o
= GEN_INT (8); goto pre_modify
;
9081 case PRE_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9085 case POST_DEC
: o
= GEN_INT (-8); goto post_modify
;
9086 case POST_INC
: o
= GEN_INT (8); goto post_modify
;
9087 case POST_MODIFY
: o
= XEXP (XEXP (addr
, 1), 1);
9096 xop
[0+i
] = adjust_automodify_address_nv
9097 (operands
[i
], SImode
,
9098 gen_rtx_fmt_ee (code
, Pmode
, r
,
9099 gen_rtx_PLUS (Pmode
, r
, o
)),
9101 xop
[2+i
] = adjust_automodify_address_nv
9102 (operands
[i
], SImode
, plus_constant (Pmode
, r
, 4), 4);
9106 xop
[0+i
] = operand_subword (operands
[i
], 0, 0, mode
);
9107 xop
[2+i
] = operand_subword (operands
[i
], 1, 0, mode
);
9110 if (reg_overlap_mentioned_p (xop
[0], xop
[3]))
9113 gcc_assert (!reg_overlap_mentioned_p (xop
[2], xop
[1]));
9116 emit_move_insn (xop
[0 + swap
], xop
[1 + swap
]);
9117 emit_move_insn (xop
[2 - swap
], xop
[3 - swap
]);
9121 /* Select between the instruction output templates s_tmpl (for short INSNs)
9122 and l_tmpl (for long INSNs). */
9125 arc_short_long (rtx_insn
*insn
, const char *s_tmpl
, const char *l_tmpl
)
9127 int is_short
= arc_verify_short (insn
, cfun
->machine
->unalign
, -1);
9129 extract_constrain_insn_cached (insn
);
9130 return is_short
? s_tmpl
: l_tmpl
;
9133 /* Searches X for any reference to REGNO, returning the rtx of the
9134 reference found if any. Otherwise, returns NULL_RTX. */
9137 arc_regno_use_in (unsigned int regno
, rtx x
)
9143 if (REG_P (x
) && refers_to_regno_p (regno
, x
))
9146 fmt
= GET_RTX_FORMAT (GET_CODE (x
));
9147 for (i
= GET_RTX_LENGTH (GET_CODE (x
)) - 1; i
>= 0; i
--)
9151 if ((tem
= regno_use_in (regno
, XEXP (x
, i
))))
9154 else if (fmt
[i
] == 'E')
9155 for (j
= XVECLEN (x
, i
) - 1; j
>= 0; j
--)
9156 if ((tem
= regno_use_in (regno
, XVECEXP (x
, i
, j
))))
9163 /* Return the integer value of the "type" attribute for INSN, or -1 if
9164 INSN can't have attributes. */
9167 arc_attr_type (rtx_insn
*insn
)
9169 if (NONJUMP_INSN_P (insn
)
9170 ? (GET_CODE (PATTERN (insn
)) == USE
9171 || GET_CODE (PATTERN (insn
)) == CLOBBER
)
9173 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9174 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9177 return get_attr_type (insn
);
9180 /* Return true if insn sets the condition codes. */
9183 arc_sets_cc_p (rtx_insn
*insn
)
9185 if (NONJUMP_INSN_P (insn
))
9186 if (rtx_sequence
*seq
= dyn_cast
<rtx_sequence
*> (PATTERN (insn
)))
9187 insn
= seq
->insn (seq
->len () - 1);
9188 return arc_attr_type (insn
) == TYPE_COMPARE
;
9191 /* Return true if INSN is an instruction with a delay slot we may want
9195 arc_need_delay (rtx_insn
*insn
)
9199 if (!flag_delayed_branch
)
9201 /* The return at the end of a function needs a delay slot. */
9202 if (NONJUMP_INSN_P (insn
) && GET_CODE (PATTERN (insn
)) == USE
9203 && (!(next
= next_active_insn (insn
))
9204 || ((!NONJUMP_INSN_P (next
) || GET_CODE (PATTERN (next
)) != SEQUENCE
)
9205 && arc_attr_type (next
) == TYPE_RETURN
))
9206 && (!TARGET_PAD_RETURN
9207 || (prev_active_insn (insn
)
9208 && prev_active_insn (prev_active_insn (insn
))
9209 && prev_active_insn (prev_active_insn (prev_active_insn (insn
))))))
9211 if (NONJUMP_INSN_P (insn
)
9212 ? (GET_CODE (PATTERN (insn
)) == USE
9213 || GET_CODE (PATTERN (insn
)) == CLOBBER
9214 || GET_CODE (PATTERN (insn
)) == SEQUENCE
)
9216 ? (GET_CODE (PATTERN (insn
)) == ADDR_VEC
9217 || GET_CODE (PATTERN (insn
)) == ADDR_DIFF_VEC
)
9220 return num_delay_slots (insn
) != 0;
9223 /* Return true if the scheduling pass(es) has/have already run,
9224 i.e. where possible, we should try to mitigate high latencies
9225 by different instruction selection. */
9228 arc_scheduling_not_expected (void)
9230 return cfun
->machine
->arc_reorg_started
;
9233 /* Oddly enough, sometimes we get a zero overhead loop that branch
9234 shortening doesn't think is a loop - observed with compile/pr24883.c
9235 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9236 alignment visible for branch shortening (we actually align the loop
9237 insn before it, but that is equivalent since the loop insn is 4 byte
9241 arc_label_align (rtx label
)
9243 int loop_align
= LOOP_ALIGN (LABEL
);
9245 if (loop_align
> align_labels_log
)
9247 rtx_insn
*prev
= prev_nonnote_insn (label
);
9249 if (prev
&& NONJUMP_INSN_P (prev
)
9250 && GET_CODE (PATTERN (prev
)) == PARALLEL
9251 && recog_memoized (prev
) == CODE_FOR_doloop_begin_i
)
9254 /* Code has a minimum p2 alignment of 1, which we must restore after an
9256 if (align_labels_log
< 1)
9258 rtx_insn
*next
= next_nonnote_nondebug_insn (label
);
9259 if (INSN_P (next
) && recog_memoized (next
) >= 0)
9262 return align_labels_log
;
9265 /* Return true if LABEL is in executable code. */
9268 arc_text_label (rtx_insn
*label
)
9272 /* ??? We use deleted labels like they were still there, see
9273 gcc.c-torture/compile/20000326-2.c . */
9274 gcc_assert (GET_CODE (label
) == CODE_LABEL
9275 || (GET_CODE (label
) == NOTE
9276 && NOTE_KIND (label
) == NOTE_INSN_DELETED_LABEL
));
9277 next
= next_nonnote_insn (label
);
9279 return (!JUMP_TABLE_DATA_P (next
)
9280 || GET_CODE (PATTERN (next
)) != ADDR_VEC
);
9281 else if (!PREV_INSN (label
))
9282 /* ??? sometimes text labels get inserted very late, see
9283 gcc.dg/torture/stackalign/comp-goto-1.c */
9288 /* Return the size of the pretend args for DECL. */
9291 arc_decl_pretend_args (tree decl
)
9293 /* struct function is in DECL_STRUCT_FUNCTION (decl), but no
9294 pretend_args there... See PR38391. */
9295 gcc_assert (decl
== current_function_decl
);
9296 return crtl
->args
.pretend_args_size
;
9299 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9300 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9301 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9302 to redirect two breqs. */
9305 arc_can_follow_jump (const rtx_insn
*follower
, const rtx_insn
*followee
)
9307 /* ??? get_attr_type is declared to take an rtx. */
9308 union { const rtx_insn
*c
; rtx_insn
*r
; } u
;
9311 if (CROSSING_JUMP_P (followee
))
9312 switch (get_attr_type (u
.r
))
9315 case TYPE_BRCC_NO_DELAY_SLOT
:
9323 /* Implement EPILOGUE__USES.
9324 Return true if REGNO should be added to the deemed uses of the epilogue.
9326 We use the return address
9327 arc_return_address_regs[arc_compute_function_type (cfun)] .
9328 But also, we have to make sure all the register restore instructions
9329 are known to be live in interrupt functions. */
9332 arc_epilogue_uses (int regno
)
9334 if (regno
== arc_tp_regno
)
9336 if (reload_completed
)
9338 if (ARC_INTERRUPT_P (cfun
->machine
->fn_type
))
9340 if (!fixed_regs
[regno
])
9342 return regno
== arc_return_address_regs
[cfun
->machine
->fn_type
];
9345 return regno
== RETURN_ADDR_REGNUM
;
9348 return regno
== arc_return_address_regs
[arc_compute_function_type (cfun
)];
9351 /* Helper for EH_USES macro. */
9354 arc_eh_uses (int regno
)
9356 if (regno
== arc_tp_regno
)
9361 #ifndef TARGET_NO_LRA
9362 #define TARGET_NO_LRA !TARGET_LRA
9368 return !TARGET_NO_LRA
;
9371 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9372 Rcq registers, because some insn are shorter with them. OTOH we already
9373 have separate alternatives for this purpose, and other insns don't
9374 mind, so maybe we should rather prefer the other registers?
9375 We need more data, and we can only get that if we allow people to
9378 arc_register_priority (int r
)
9380 switch (arc_lra_priority_tag
)
9382 case ARC_LRA_PRIORITY_NONE
:
9384 case ARC_LRA_PRIORITY_NONCOMPACT
:
9385 return ((((r
& 7) ^ 4) - 4) & 15) != r
;
9386 case ARC_LRA_PRIORITY_COMPACT
:
9387 return ((((r
& 7) ^ 4) - 4) & 15) == r
;
9394 arc_spill_class (reg_class_t
/* orig_class */, machine_mode
)
9396 return GENERAL_REGS
;
9400 arc_legitimize_reload_address (rtx
*p
, machine_mode mode
, int opnum
,
9404 enum reload_type type
= (enum reload_type
) itype
;
9406 if (GET_CODE (x
) == PLUS
9407 && CONST_INT_P (XEXP (x
, 1))
9408 && (RTX_OK_FOR_BASE_P (XEXP (x
, 0), true)
9409 || (REG_P (XEXP (x
, 0))
9410 && reg_equiv_constant (REGNO (XEXP (x
, 0))))))
9412 int scale
= GET_MODE_SIZE (mode
);
9414 rtx index_rtx
= XEXP (x
, 1);
9415 HOST_WIDE_INT offset
= INTVAL (index_rtx
), offset_base
;
9420 if ((scale
-1) & offset
)
9424 = ((offset
+ (256 << shift
))
9425 & ((HOST_WIDE_INT
)((unsigned HOST_WIDE_INT
) -512 << shift
)));
9426 /* Sometimes the normal form does not suit DImode. We
9427 could avoid that by using smaller ranges, but that
9428 would give less optimized code when SImode is
9430 if (GET_MODE_SIZE (mode
) + offset
- offset_base
<= (256 << shift
))
9435 regno
= REGNO (reg
);
9436 sum2
= sum
= plus_constant (Pmode
, reg
, offset_base
);
9438 if (reg_equiv_constant (regno
))
9440 sum2
= plus_constant (Pmode
, reg_equiv_constant (regno
),
9442 if (GET_CODE (sum2
) == PLUS
)
9443 sum2
= gen_rtx_CONST (Pmode
, sum2
);
9445 *p
= gen_rtx_PLUS (Pmode
, sum
, GEN_INT (offset
- offset_base
));
9446 push_reload (sum2
, NULL_RTX
, &XEXP (*p
, 0), NULL
,
9447 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
,
9452 /* We must re-recognize what we created before. */
9453 else if (GET_CODE (x
) == PLUS
9454 && GET_CODE (XEXP (x
, 0)) == PLUS
9455 && CONST_INT_P (XEXP (XEXP (x
, 0), 1))
9456 && REG_P (XEXP (XEXP (x
, 0), 0))
9457 && CONST_INT_P (XEXP (x
, 1)))
9459 /* Because this address is so complex, we know it must have
9460 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9461 it is already unshared, and needs no further unsharing. */
9462 push_reload (XEXP (x
, 0), NULL_RTX
, &XEXP (x
, 0), NULL
,
9463 BASE_REG_CLASS
, Pmode
, VOIDmode
, 0, 0, opnum
, type
);
9469 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9472 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size
,
9474 enum by_pieces_operation op
,
9477 /* Let the movmem expander handle small block moves. */
9478 if (op
== MOVE_BY_PIECES
)
9481 return default_use_by_pieces_infrastructure_p (size
, align
, op
, speed_p
);
9484 /* Emit a (pre) memory barrier around an atomic sequence according to
9488 arc_pre_atomic_barrier (enum memmodel model
)
9490 if (need_atomic_barrier_p (model
, true))
9491 emit_insn (gen_memory_barrier ());
9494 /* Emit a (post) memory barrier around an atomic sequence according to
9498 arc_post_atomic_barrier (enum memmodel model
)
9500 if (need_atomic_barrier_p (model
, false))
9501 emit_insn (gen_memory_barrier ());
9504 /* Expand a compare and swap pattern. */
9507 emit_unlikely_jump (rtx insn
)
9509 int very_unlikely
= REG_BR_PROB_BASE
/ 100 - 1;
9511 insn
= emit_jump_insn (insn
);
9512 add_int_reg_note (insn
, REG_BR_PROB
, very_unlikely
);
9515 /* Expand code to perform a 8 or 16-bit compare and swap by doing
9516 32-bit compare and swap on the word containing the byte or
9517 half-word. The difference between a weak and a strong CAS is that
9518 the weak version may simply fail. The strong version relies on two
9519 loops, one checks if the SCOND op is succsfully or not, the other
9520 checks if the 32 bit accessed location which contains the 8 or 16
9521 bit datum is not changed by other thread. The first loop is
9522 implemented by the atomic_compare_and_swapsi_1 pattern. The second
9523 loops is implemented by this routine. */
9526 arc_expand_compare_and_swap_qh (rtx bool_result
, rtx result
, rtx mem
,
9527 rtx oldval
, rtx newval
, rtx weak
,
9528 rtx mod_s
, rtx mod_f
)
9530 rtx addr1
= force_reg (Pmode
, XEXP (mem
, 0));
9531 rtx addr
= gen_reg_rtx (Pmode
);
9532 rtx off
= gen_reg_rtx (SImode
);
9533 rtx oldv
= gen_reg_rtx (SImode
);
9534 rtx newv
= gen_reg_rtx (SImode
);
9535 rtx oldvalue
= gen_reg_rtx (SImode
);
9536 rtx newvalue
= gen_reg_rtx (SImode
);
9537 rtx res
= gen_reg_rtx (SImode
);
9538 rtx resv
= gen_reg_rtx (SImode
);
9539 rtx memsi
, val
, mask
, end_label
, loop_label
, cc
, x
;
9541 bool is_weak
= (weak
!= const0_rtx
);
9543 /* Truncate the address. */
9544 emit_insn (gen_rtx_SET (addr
,
9545 gen_rtx_AND (Pmode
, addr1
, GEN_INT (-4))));
9547 /* Compute the datum offset. */
9548 emit_insn (gen_rtx_SET (off
,
9549 gen_rtx_AND (SImode
, addr1
, GEN_INT (3))));
9550 if (TARGET_BIG_ENDIAN
)
9551 emit_insn (gen_rtx_SET (off
,
9552 gen_rtx_MINUS (SImode
,
9553 (GET_MODE (mem
) == QImode
) ?
9554 GEN_INT (3) : GEN_INT (2), off
)));
9556 /* Normal read from truncated address. */
9557 memsi
= gen_rtx_MEM (SImode
, addr
);
9558 set_mem_alias_set (memsi
, ALIAS_SET_MEMORY_BARRIER
);
9559 MEM_VOLATILE_P (memsi
) = MEM_VOLATILE_P (mem
);
9561 val
= copy_to_reg (memsi
);
9563 /* Convert the offset in bits. */
9564 emit_insn (gen_rtx_SET (off
,
9565 gen_rtx_ASHIFT (SImode
, off
, GEN_INT (3))));
9567 /* Get the proper mask. */
9568 if (GET_MODE (mem
) == QImode
)
9569 mask
= force_reg (SImode
, GEN_INT (0xff));
9571 mask
= force_reg (SImode
, GEN_INT (0xffff));
9573 emit_insn (gen_rtx_SET (mask
,
9574 gen_rtx_ASHIFT (SImode
, mask
, off
)));
9576 /* Prepare the old and new values. */
9577 emit_insn (gen_rtx_SET (val
,
9578 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
9581 oldval
= gen_lowpart (SImode
, oldval
);
9582 emit_insn (gen_rtx_SET (oldv
,
9583 gen_rtx_ASHIFT (SImode
, oldval
, off
)));
9585 newval
= gen_lowpart_common (SImode
, newval
);
9586 emit_insn (gen_rtx_SET (newv
,
9587 gen_rtx_ASHIFT (SImode
, newval
, off
)));
9589 emit_insn (gen_rtx_SET (oldv
,
9590 gen_rtx_AND (SImode
, oldv
, mask
)));
9592 emit_insn (gen_rtx_SET (newv
,
9593 gen_rtx_AND (SImode
, newv
, mask
)));
9597 end_label
= gen_label_rtx ();
9598 loop_label
= gen_label_rtx ();
9599 emit_label (loop_label
);
9602 /* Make the old and new values. */
9603 emit_insn (gen_rtx_SET (oldvalue
,
9604 gen_rtx_IOR (SImode
, oldv
, val
)));
9606 emit_insn (gen_rtx_SET (newvalue
,
9607 gen_rtx_IOR (SImode
, newv
, val
)));
9609 /* Try an 32bit atomic compare and swap. It clobbers the CC
9611 emit_insn (gen_atomic_compare_and_swapsi_1 (res
, memsi
, oldvalue
, newvalue
,
9612 weak
, mod_s
, mod_f
));
9614 /* Regardless of the weakness of the operation, a proper boolean
9615 result needs to be provided. */
9616 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
9617 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
9618 emit_insn (gen_rtx_SET (bool_result
, x
));
9622 /* Check the results: if the atomic op is successfully the goto
9624 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
9625 x
= gen_rtx_EQ (VOIDmode
, x
, const0_rtx
);
9626 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
9627 gen_rtx_LABEL_REF (Pmode
, end_label
), pc_rtx
);
9628 emit_jump_insn (gen_rtx_SET (pc_rtx
, x
));
9630 /* Wait for the right moment when the accessed 32-bit location
9632 emit_insn (gen_rtx_SET (resv
,
9633 gen_rtx_AND (SImode
, gen_rtx_NOT (SImode
, mask
),
9635 mode
= SELECT_CC_MODE (NE
, resv
, val
);
9636 cc
= gen_rtx_REG (mode
, CC_REG
);
9637 emit_insn (gen_rtx_SET (cc
, gen_rtx_COMPARE (mode
, resv
, val
)));
9639 /* Set the new value of the 32 bit location, proper masked. */
9640 emit_insn (gen_rtx_SET (val
, resv
));
9642 /* Try again if location is unstable. Fall through if only
9644 x
= gen_rtx_NE (VOIDmode
, cc
, const0_rtx
);
9645 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
9646 gen_rtx_LABEL_REF (Pmode
, loop_label
), pc_rtx
);
9647 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
9649 emit_label (end_label
);
9652 /* End: proper return the result for the given mode. */
9653 emit_insn (gen_rtx_SET (res
,
9654 gen_rtx_AND (SImode
, res
, mask
)));
9656 emit_insn (gen_rtx_SET (res
,
9657 gen_rtx_LSHIFTRT (SImode
, res
, off
)));
9659 emit_move_insn (result
, gen_lowpart (GET_MODE (result
), res
));
9662 /* Helper function used by "atomic_compare_and_swap" expand
9666 arc_expand_compare_and_swap (rtx operands
[])
9668 rtx bval
, rval
, mem
, oldval
, newval
, is_weak
, mod_s
, mod_f
, x
;
9674 oldval
= operands
[3];
9675 newval
= operands
[4];
9676 is_weak
= operands
[5];
9677 mod_s
= operands
[6];
9678 mod_f
= operands
[7];
9679 mode
= GET_MODE (mem
);
9681 if (reg_overlap_mentioned_p (rval
, oldval
))
9682 oldval
= copy_to_reg (oldval
);
9686 emit_insn (gen_atomic_compare_and_swapsi_1 (rval
, mem
, oldval
, newval
,
9687 is_weak
, mod_s
, mod_f
));
9688 x
= gen_rtx_REG (CC_Zmode
, CC_REG
);
9689 x
= gen_rtx_EQ (SImode
, x
, const0_rtx
);
9690 emit_insn (gen_rtx_SET (bval
, x
));
9694 arc_expand_compare_and_swap_qh (bval
, rval
, mem
, oldval
, newval
,
9695 is_weak
, mod_s
, mod_f
);
9699 /* Helper function used by the "atomic_compare_and_swapsi_1"
9703 arc_split_compare_and_swap (rtx operands
[])
9705 rtx rval
, mem
, oldval
, newval
;
9707 enum memmodel mod_s
, mod_f
;
9709 rtx label1
, label2
, x
, cond
;
9713 oldval
= operands
[2];
9714 newval
= operands
[3];
9715 is_weak
= (operands
[4] != const0_rtx
);
9716 mod_s
= (enum memmodel
) INTVAL (operands
[5]);
9717 mod_f
= (enum memmodel
) INTVAL (operands
[6]);
9718 mode
= GET_MODE (mem
);
9720 /* ARC atomic ops work only with 32-bit aligned memories. */
9721 gcc_assert (mode
== SImode
);
9723 arc_pre_atomic_barrier (mod_s
);
9728 label1
= gen_label_rtx ();
9729 emit_label (label1
);
9731 label2
= gen_label_rtx ();
9733 /* Load exclusive. */
9734 emit_insn (gen_arc_load_exclusivesi (rval
, mem
));
9736 /* Check if it is oldval. */
9737 mode
= SELECT_CC_MODE (NE
, rval
, oldval
);
9738 cond
= gen_rtx_REG (mode
, CC_REG
);
9739 emit_insn (gen_rtx_SET (cond
, gen_rtx_COMPARE (mode
, rval
, oldval
)));
9741 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
9742 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
9743 gen_rtx_LABEL_REF (Pmode
, label2
), pc_rtx
);
9744 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
9746 /* Exclusively store new item. Store clobbers CC reg. */
9747 emit_insn (gen_arc_store_exclusivesi (mem
, newval
));
9751 /* Check the result of the store. */
9752 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
9753 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
9754 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
9755 gen_rtx_LABEL_REF (Pmode
, label1
), pc_rtx
);
9756 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
9759 if (mod_f
!= MEMMODEL_RELAXED
)
9760 emit_label (label2
);
9762 arc_post_atomic_barrier (mod_s
);
9764 if (mod_f
== MEMMODEL_RELAXED
)
9765 emit_label (label2
);
9768 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
9769 to perform. MEM is the memory on which to operate. VAL is the second
9770 operand of the binary operator. BEFORE and AFTER are optional locations to
9771 return the value of MEM either before of after the operation. MODEL_RTX
9772 is a CONST_INT containing the memory model to use. */
9775 arc_expand_atomic_op (enum rtx_code code
, rtx mem
, rtx val
,
9776 rtx orig_before
, rtx orig_after
, rtx model_rtx
)
9778 enum memmodel model
= (enum memmodel
) INTVAL (model_rtx
);
9779 machine_mode mode
= GET_MODE (mem
);
9781 rtx before
= orig_before
, after
= orig_after
;
9783 /* ARC atomic ops work only with 32-bit aligned memories. */
9784 gcc_assert (mode
== SImode
);
9786 arc_pre_atomic_barrier (model
);
9788 label
= gen_label_rtx ();
9790 label
= gen_rtx_LABEL_REF (VOIDmode
, label
);
9792 if (before
== NULL_RTX
)
9793 before
= gen_reg_rtx (mode
);
9795 if (after
== NULL_RTX
)
9796 after
= gen_reg_rtx (mode
);
9798 /* Load exclusive. */
9799 emit_insn (gen_arc_load_exclusivesi (before
, mem
));
9804 x
= gen_rtx_AND (mode
, before
, val
);
9805 emit_insn (gen_rtx_SET (after
, x
));
9806 x
= gen_rtx_NOT (mode
, after
);
9807 emit_insn (gen_rtx_SET (after
, x
));
9811 if (CONST_INT_P (val
))
9813 val
= GEN_INT (-INTVAL (val
));
9819 x
= gen_rtx_fmt_ee (code
, mode
, before
, val
);
9820 emit_insn (gen_rtx_SET (after
, x
));
9824 /* Exclusively store new item. Store clobbers CC reg. */
9825 emit_insn (gen_arc_store_exclusivesi (mem
, after
));
9827 /* Check the result of the store. */
9828 cond
= gen_rtx_REG (CC_Zmode
, CC_REG
);
9829 x
= gen_rtx_NE (VOIDmode
, cond
, const0_rtx
);
9830 x
= gen_rtx_IF_THEN_ELSE (VOIDmode
, x
,
9832 emit_unlikely_jump (gen_rtx_SET (pc_rtx
, x
));
9834 arc_post_atomic_barrier (model
);
9837 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
9840 arc_no_speculation_in_delay_slots_p ()
9845 /* Return a parallel of registers to represent where to find the
9846 register pieces if required, otherwise NULL_RTX. */
9849 arc_dwarf_register_span (rtx rtl
)
9851 machine_mode mode
= GET_MODE (rtl
);
9855 if (GET_MODE_SIZE (mode
) != 8)
9858 p
= gen_rtx_PARALLEL (VOIDmode
, rtvec_alloc (2));
9859 regno
= REGNO (rtl
);
9860 XVECEXP (p
, 0, 0) = gen_rtx_REG (SImode
, regno
);
9861 XVECEXP (p
, 0, 1) = gen_rtx_REG (SImode
, regno
+ 1);
9866 /* We can't inline this in INSN_REFERENCES_ARE_DELAYED because
9867 resource.h doesn't include the required header files. */
9870 insn_is_tls_gd_dispatch (rtx_insn
*insn
)
9872 return recog_memoized (insn
) == CODE_FOR_tls_gd_dispatch
;
9875 /* Return true if OP is an acceptable memory operand for ARCompact
9876 16-bit load instructions of MODE.
9878 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
9879 non scaled instructions.
9881 SCALED: TRUE if address can be scaled. */
9884 compact_memory_operand_p (rtx op
, machine_mode mode
,
9885 bool av2short
, bool scaled
)
9887 rtx addr
, plus0
, plus1
;
9890 /* Eliminate non-memory operations. */
9891 if (GET_CODE (op
) != MEM
)
9894 /* .di instructions have no 16-bit form. */
9895 if (MEM_VOLATILE_P (op
) && !TARGET_VOLATILE_CACHE_SET
)
9898 if (mode
== VOIDmode
)
9899 mode
= GET_MODE (op
);
9901 size
= GET_MODE_SIZE (mode
);
9903 /* dword operations really put out 2 instructions, so eliminate
9905 if (size
> UNITS_PER_WORD
)
9908 /* Decode the address now. */
9909 addr
= XEXP (op
, 0);
9910 switch (GET_CODE (addr
))
9913 return (REGNO (addr
) >= FIRST_PSEUDO_REGISTER
9914 || COMPACT_GP_REG_P (REGNO (addr
))
9915 || (SP_REG_P (REGNO (addr
)) && (size
!= 2)));
9917 plus0
= XEXP (addr
, 0);
9918 plus1
= XEXP (addr
, 1);
9920 if ((GET_CODE (plus0
) == REG
)
9921 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
9922 || COMPACT_GP_REG_P (REGNO (plus0
)))
9923 && ((GET_CODE (plus1
) == REG
)
9924 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
9925 || COMPACT_GP_REG_P (REGNO (plus1
)))))
9930 if ((GET_CODE (plus0
) == REG
)
9931 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
9932 || (COMPACT_GP_REG_P (REGNO (plus0
)) && !av2short
)
9933 || (IN_RANGE (REGNO (plus0
), 0, 31) && av2short
))
9934 && (GET_CODE (plus1
) == CONST_INT
))
9938 off
= INTVAL (plus1
);
9940 /* Negative offset is not supported in 16-bit load/store insns. */
9944 /* Only u5 immediates allowed in code density instructions. */
9952 /* This is an ldh_s.x instruction, check the u6
9954 if (COMPACT_GP_REG_P (REGNO (plus0
)))
9958 /* Only u5 immediates allowed in 32bit access code
9959 density instructions. */
9960 if (REGNO (plus0
) <= 31)
9961 return ((off
< 32) && (off
% 4 == 0));
9968 if (COMPACT_GP_REG_P (REGNO (plus0
)))
9979 /* The 6-bit constant get shifted to fit the real
9980 5-bits field. Check also for the alignment. */
9981 return ((off
< 64) && (off
% 2 == 0));
9983 return ((off
< 128) && (off
% 4 == 0));
9990 if (REG_P (plus0
) && CONST_INT_P (plus1
)
9991 && ((REGNO (plus0
) >= FIRST_PSEUDO_REGISTER
)
9992 || SP_REG_P (REGNO (plus0
)))
9995 off
= INTVAL (plus1
);
9996 return ((size
!= 2) && (off
>= 0 && off
< 128) && (off
% 4 == 0));
9999 if ((GET_CODE (plus0
) == MULT
)
10000 && (GET_CODE (XEXP (plus0
, 0)) == REG
)
10001 && ((REGNO (XEXP (plus0
, 0)) >= FIRST_PSEUDO_REGISTER
)
10002 || COMPACT_GP_REG_P (REGNO (XEXP (plus0
, 0))))
10003 && (GET_CODE (plus1
) == REG
)
10004 && ((REGNO (plus1
) >= FIRST_PSEUDO_REGISTER
)
10005 || COMPACT_GP_REG_P (REGNO (plus1
))))
10009 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10010 for 16-bit load instructions. */
10015 struct gcc_target targetm
= TARGET_INITIALIZER
;
10017 #include "gt-arc.h"