[2/77] Add an E_ prefix to case statements
[official-gcc.git] / gcc / config / arc / arc.c
blobc072bda257b1069234a5557acc7cd18badfe0630
1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2017 Free Software Foundation, Inc.
4 Sources derived from work done by Sankhya Technologies (www.sankhya.com) on
5 behalf of Synopsys Inc.
7 Position Independent Code support added,Code cleaned up,
8 Comments and Support For ARC700 instructions added by
9 Saurabh Verma (saurabh.verma@codito.com)
10 Ramana Radhakrishnan(ramana.radhakrishnan@codito.com)
12 Fixing ABI inconsistencies, optimizations for ARC600 / ARC700 pipelines,
13 profiling support added by Joern Rennecke <joern.rennecke@embecosm.com>
15 This file is part of GCC.
17 GCC is free software; you can redistribute it and/or modify
18 it under the terms of the GNU General Public License as published by
19 the Free Software Foundation; either version 3, or (at your option)
20 any later version.
22 GCC is distributed in the hope that it will be useful,
23 but WITHOUT ANY WARRANTY; without even the implied warranty of
24 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
25 GNU General Public License for more details.
27 You should have received a copy of the GNU General Public License
28 along with GCC; see the file COPYING3. If not see
29 <http://www.gnu.org/licenses/>. */
31 #include "config.h"
32 #include "system.h"
33 #include "coretypes.h"
34 #include "memmodel.h"
35 #include "backend.h"
36 #include "target.h"
37 #include "rtl.h"
38 #include "tree.h"
39 #include "cfghooks.h"
40 #include "df.h"
41 #include "tm_p.h"
42 #include "stringpool.h"
43 #include "attribs.h"
44 #include "optabs.h"
45 #include "regs.h"
46 #include "emit-rtl.h"
47 #include "recog.h"
48 #include "diagnostic.h"
49 #include "fold-const.h"
50 #include "varasm.h"
51 #include "stor-layout.h"
52 #include "calls.h"
53 #include "output.h"
54 #include "insn-attr.h"
55 #include "flags.h"
56 #include "explow.h"
57 #include "expr.h"
58 #include "langhooks.h"
59 #include "tm-constrs.h"
60 #include "reload.h" /* For operands_match_p */
61 #include "cfgrtl.h"
62 #include "tree-pass.h"
63 #include "context.h"
64 #include "builtins.h"
65 #include "rtl-iter.h"
66 #include "alias.h"
67 #include "opts.h"
69 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
70 static char arc_cpu_name[10] = "";
71 static const char *arc_cpu_string = arc_cpu_name;
73 /* ??? Loads can handle any constant, stores can only handle small ones. */
74 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
75 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
76 (GET_CODE (X) == CONST_INT \
77 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
78 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
79 ? 0 \
80 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
82 #define LEGITIMATE_SCALED_ADDRESS_P(MODE, X, STRICT) \
83 (GET_CODE (X) == PLUS \
84 && GET_CODE (XEXP (X, 0)) == MULT \
85 && RTX_OK_FOR_INDEX_P (XEXP (XEXP (X, 0), 0), (STRICT)) \
86 && GET_CODE (XEXP (XEXP (X, 0), 1)) == CONST_INT \
87 && ((GET_MODE_SIZE (MODE) == 2 && INTVAL (XEXP (XEXP (X, 0), 1)) == 2) \
88 || (GET_MODE_SIZE (MODE) == 4 && INTVAL (XEXP (XEXP (X, 0), 1)) == 4)) \
89 && (RTX_OK_FOR_BASE_P (XEXP (X, 1), (STRICT)) \
90 || (flag_pic ? CONST_INT_P (XEXP (X, 1)) : CONSTANT_P (XEXP (X, 1)))))
92 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
93 (GET_CODE (X) == PLUS \
94 && (REG_P (XEXP ((X), 0)) && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM) \
95 && ((GET_CODE (XEXP((X),1)) == SYMBOL_REF \
96 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
97 || (GET_CODE (XEXP ((X), 1)) == CONST \
98 && GET_CODE (XEXP (XEXP ((X), 1), 0)) == PLUS \
99 && GET_CODE (XEXP (XEXP (XEXP ((X), 1), 0), 0)) == SYMBOL_REF \
100 && SYMBOL_REF_SMALL_P (XEXP (XEXP (XEXP ((X), 1), 0), 0)) \
101 && GET_CODE (XEXP(XEXP (XEXP ((X), 1), 0), 1)) == CONST_INT)))
103 /* Array of valid operand punctuation characters. */
104 char arc_punct_chars[256];
106 /* State used by arc_ccfsm_advance to implement conditional execution. */
107 struct GTY (()) arc_ccfsm
109 int state;
110 int cc;
111 rtx cond;
112 rtx_insn *target_insn;
113 int target_label;
116 /* Status of the IRQ_CTRL_AUX register. */
117 typedef struct irq_ctrl_saved_t
119 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
120 short irq_save_last_reg;
121 /* True if BLINK is automatically saved. */
122 bool irq_save_blink;
123 /* True if LPCOUNT is automatically saved. */
124 bool irq_save_lpcount;
125 } irq_ctrl_saved_t;
126 static irq_ctrl_saved_t irq_ctrl_saved;
128 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
129 ((ARC_INTERRUPT_P (FNTYPE) \
130 && irq_ctrl_saved.irq_save_blink) \
131 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
132 && rgf_banked_register_count > 8))
134 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
135 ((ARC_INTERRUPT_P (FNTYPE) \
136 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
137 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
138 && rgf_banked_register_count > 8))
140 #define ARC_AUTO_IRQ_P(FNTYPE) \
141 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
142 && (irq_ctrl_saved.irq_save_blink \
143 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
145 /* Number of registers in second bank for FIRQ support. */
146 static int rgf_banked_register_count;
148 #define arc_ccfsm_current cfun->machine->ccfsm_current
150 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
151 ((STATE)->state == 1 || (STATE)->state == 2)
153 /* Indicate we're conditionalizing insns now. */
154 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
155 ((STATE)->state += 2)
157 #define ARC_CCFSM_COND_EXEC_P(STATE) \
158 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
159 || current_insn_predicate)
161 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
162 #define CCFSM_ISCOMPACT(INSN,STATE) \
163 (ARC_CCFSM_COND_EXEC_P (STATE) \
164 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
165 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
166 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
168 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
169 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
170 ((ARC_CCFSM_COND_EXEC_P (STATE) \
171 || (JUMP_P (JUMP) \
172 && INSN_ANNULLED_BRANCH_P (JUMP) \
173 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
174 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
175 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
176 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
178 /* The maximum number of insns skipped which will be conditionalised if
179 possible. */
180 /* When optimizing for speed:
181 Let p be the probability that the potentially skipped insns need to
182 be executed, pn the cost of a correctly predicted non-taken branch,
183 mt the cost of a mis/non-predicted taken branch,
184 mn mispredicted non-taken, pt correctly predicted taken ;
185 costs expressed in numbers of instructions like the ones considered
186 skipping.
187 Unfortunately we don't have a measure of predictability - this
188 is linked to probability only in that in the no-eviction-scenario
189 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
190 value that can be assumed *if* the distribution is perfectly random.
191 A predictability of 1 is perfectly plausible not matter what p is,
192 because the decision could be dependent on an invocation parameter
193 of the program.
194 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
195 For small p, we want MAX_INSNS_SKIPPED == pt
197 When optimizing for size:
198 We want to skip insn unless we could use 16 opcodes for the
199 non-conditionalized insn to balance the branch length or more.
200 Performance can be tie-breaker. */
201 /* If the potentially-skipped insns are likely to be executed, we'll
202 generally save one non-taken branch
204 this to be no less than the 1/p */
205 #define MAX_INSNS_SKIPPED 3
207 /* A nop is needed between a 4 byte insn that sets the condition codes and
208 a branch that uses them (the same isn't true for an 8 byte insn that sets
209 the condition codes). Set by arc_ccfsm_advance. Used by
210 arc_print_operand. */
212 static int get_arc_condition_code (rtx);
214 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
215 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
217 /* Initialized arc_attribute_table to NULL since arc doesnot have any
218 machine specific supported attributes. */
219 const struct attribute_spec arc_attribute_table[] =
221 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
222 affects_type_identity } */
223 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute, true },
224 /* Function calls made to this symbol must be done indirectly, because
225 it may lie outside of the 21/25 bit addressing range of a normal function
226 call. */
227 { "long_call", 0, 0, false, true, true, NULL, false },
228 /* Whereas these functions are always known to reside within the 25 bit
229 addressing range of unconditionalized bl. */
230 { "medium_call", 0, 0, false, true, true, NULL, false },
231 /* And these functions are always known to reside within the 21 bit
232 addressing range of blcc. */
233 { "short_call", 0, 0, false, true, true, NULL, false },
234 /* Function which are not having the prologue and epilogue generated
235 by the compiler. */
236 { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute, false },
237 { NULL, 0, 0, false, false, false, NULL, false }
239 static int arc_comp_type_attributes (const_tree, const_tree);
240 static void arc_file_start (void);
241 static void arc_internal_label (FILE *, const char *, unsigned long);
242 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
243 tree);
244 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
245 static void arc_encode_section_info (tree decl, rtx rtl, int first);
247 static void arc_init_builtins (void);
248 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
250 static int branch_dest (rtx);
252 static void arc_output_pic_addr_const (FILE *, rtx, int);
253 static bool arc_function_ok_for_sibcall (tree, tree);
254 static rtx arc_function_value (const_tree, const_tree, bool);
255 const char * output_shift (rtx *);
256 static void arc_reorg (void);
257 static bool arc_in_small_data_p (const_tree);
259 static void arc_init_reg_tables (void);
260 static bool arc_return_in_memory (const_tree, const_tree);
261 static bool arc_vector_mode_supported_p (machine_mode);
263 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
264 unsigned int, bool);
265 static const char *arc_invalid_within_doloop (const rtx_insn *);
267 static void output_short_suffix (FILE *file);
269 static bool arc_frame_pointer_required (void);
271 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
272 unsigned int,
273 enum by_pieces_operation op,
274 bool);
276 /* Globally visible information about currently selected cpu. */
277 const arc_cpu_t *arc_selected_cpu;
279 /* Check for constructions like REG + OFFS, where OFFS can be a
280 register, an immediate or an long immediate. */
282 static bool
283 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
285 if (GET_CODE (x) != PLUS)
286 return false;
288 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
289 return false;
291 /* Check for: [Rx + small offset] or [Rx + Ry]. */
292 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict))
293 && GET_MODE_SIZE ((mode)) <= 4)
294 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1))))
295 return true;
297 /* Check for [Rx + symbol]. */
298 if (!flag_pic
299 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
300 /* Avoid this type of address for double or larger modes. */
301 && (GET_MODE_SIZE (mode) <= 4)
302 /* Avoid small data which ends in something like GP +
303 symb@sda. */
304 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))
305 || TARGET_NO_SDATA_SET))
306 return true;
308 return false;
311 /* Implements target hook vector_mode_supported_p. */
313 static bool
314 arc_vector_mode_supported_p (machine_mode mode)
316 switch (mode)
318 case E_V2HImode:
319 return TARGET_PLUS_DMPY;
320 case E_V4HImode:
321 case E_V2SImode:
322 return TARGET_PLUS_QMACW;
323 case E_V4SImode:
324 case E_V8HImode:
325 return TARGET_SIMD_SET;
327 default:
328 return false;
332 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
334 static machine_mode
335 arc_preferred_simd_mode (machine_mode mode)
337 switch (mode)
339 case E_HImode:
340 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
341 case E_SImode:
342 return V2SImode;
344 default:
345 return word_mode;
349 /* Implements target hook
350 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
352 static unsigned int
353 arc_autovectorize_vector_sizes (void)
355 return TARGET_PLUS_QMACW ? (8 | 4) : 0;
358 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
359 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
360 static rtx arc_delegitimize_address (rtx);
361 static bool arc_can_follow_jump (const rtx_insn *follower,
362 const rtx_insn *followee);
364 static rtx frame_insn (rtx);
365 static void arc_function_arg_advance (cumulative_args_t, machine_mode,
366 const_tree, bool);
367 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
369 static void arc_finalize_pic (void);
371 /* initialize the GCC target structure. */
372 #undef TARGET_COMP_TYPE_ATTRIBUTES
373 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
374 #undef TARGET_ASM_FILE_START
375 #define TARGET_ASM_FILE_START arc_file_start
376 #undef TARGET_ATTRIBUTE_TABLE
377 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
378 #undef TARGET_ASM_INTERNAL_LABEL
379 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
380 #undef TARGET_RTX_COSTS
381 #define TARGET_RTX_COSTS arc_rtx_costs
382 #undef TARGET_ADDRESS_COST
383 #define TARGET_ADDRESS_COST arc_address_cost
385 #undef TARGET_ENCODE_SECTION_INFO
386 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
388 #undef TARGET_CANNOT_FORCE_CONST_MEM
389 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
391 #undef TARGET_INIT_BUILTINS
392 #define TARGET_INIT_BUILTINS arc_init_builtins
394 #undef TARGET_EXPAND_BUILTIN
395 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
397 #undef TARGET_BUILTIN_DECL
398 #define TARGET_BUILTIN_DECL arc_builtin_decl
400 #undef TARGET_ASM_OUTPUT_MI_THUNK
401 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
403 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
404 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
406 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
407 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
409 #undef TARGET_MACHINE_DEPENDENT_REORG
410 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
412 #undef TARGET_IN_SMALL_DATA_P
413 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
415 #undef TARGET_PROMOTE_FUNCTION_MODE
416 #define TARGET_PROMOTE_FUNCTION_MODE \
417 default_promote_function_mode_always_promote
419 #undef TARGET_PROMOTE_PROTOTYPES
420 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
422 #undef TARGET_RETURN_IN_MEMORY
423 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
424 #undef TARGET_PASS_BY_REFERENCE
425 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
427 #undef TARGET_SETUP_INCOMING_VARARGS
428 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
430 #undef TARGET_ARG_PARTIAL_BYTES
431 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
433 #undef TARGET_MUST_PASS_IN_STACK
434 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
436 #undef TARGET_FUNCTION_VALUE
437 #define TARGET_FUNCTION_VALUE arc_function_value
439 #undef TARGET_SCHED_ADJUST_PRIORITY
440 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
442 #undef TARGET_VECTOR_MODE_SUPPORTED_P
443 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
445 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
446 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
448 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
449 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
451 #undef TARGET_CAN_USE_DOLOOP_P
452 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
454 #undef TARGET_INVALID_WITHIN_DOLOOP
455 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
457 #undef TARGET_PRESERVE_RELOAD_P
458 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
460 #undef TARGET_CAN_FOLLOW_JUMP
461 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
463 #undef TARGET_DELEGITIMIZE_ADDRESS
464 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
466 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
467 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
468 arc_use_by_pieces_infrastructure_p
470 /* Usually, we will be able to scale anchor offsets.
471 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
472 #undef TARGET_MIN_ANCHOR_OFFSET
473 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
474 #undef TARGET_MAX_ANCHOR_OFFSET
475 #define TARGET_MAX_ANCHOR_OFFSET (1020)
477 #undef TARGET_SECONDARY_RELOAD
478 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
480 #define TARGET_OPTION_OVERRIDE arc_override_options
482 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
484 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
486 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
488 #define TARGET_CAN_ELIMINATE arc_can_eliminate
490 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
492 #define TARGET_FUNCTION_ARG arc_function_arg
494 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
496 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
498 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
500 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
502 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
504 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
506 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
508 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
509 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
510 arc_no_speculation_in_delay_slots_p
512 #undef TARGET_LRA_P
513 #define TARGET_LRA_P arc_lra_p
514 #define TARGET_REGISTER_PRIORITY arc_register_priority
515 /* Stores with scaled offsets have different displacement ranges. */
516 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
517 #define TARGET_SPILL_CLASS arc_spill_class
519 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
520 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
522 #undef TARGET_WARN_FUNC_RETURN
523 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
525 #include "target-def.h"
527 #undef TARGET_ASM_ALIGNED_HI_OP
528 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
529 #undef TARGET_ASM_ALIGNED_SI_OP
530 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
532 #ifdef HAVE_AS_TLS
533 #undef TARGET_HAVE_TLS
534 #define TARGET_HAVE_TLS HAVE_AS_TLS
535 #endif
537 #undef TARGET_DWARF_REGISTER_SPAN
538 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
540 /* Try to keep the (mov:DF _, reg) as early as possible so
541 that the d<add/sub/mul>h-lr insns appear together and can
542 use the peephole2 pattern. */
544 static int
545 arc_sched_adjust_priority (rtx_insn *insn, int priority)
547 rtx set = single_set (insn);
548 if (set
549 && GET_MODE (SET_SRC(set)) == DFmode
550 && GET_CODE (SET_SRC(set)) == REG)
552 /* Incrementing priority by 20 (empirically derived). */
553 return priority + 20;
556 return priority;
559 /* For ARC base register + offset addressing, the validity of the
560 address is mode-dependent for most of the offset range, as the
561 offset can be scaled by the access size.
562 We don't expose these as mode-dependent addresses in the
563 mode_dependent_address_p target hook, because that would disable
564 lots of optimizations, and most uses of these addresses are for 32
565 or 64 bit accesses anyways, which are fine.
566 However, that leaves some addresses for 8 / 16 bit values not
567 properly reloaded by the generic code, which is why we have to
568 schedule secondary reloads for these. */
570 static reg_class_t
571 arc_secondary_reload (bool in_p,
572 rtx x,
573 reg_class_t cl,
574 machine_mode mode,
575 secondary_reload_info *sri)
577 enum rtx_code code = GET_CODE (x);
579 if (cl == DOUBLE_REGS)
580 return GENERAL_REGS;
582 /* The loop counter register can be stored, but not loaded directly. */
583 if ((cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS)
584 && in_p && MEM_P (x))
585 return GENERAL_REGS;
587 /* If we have a subreg (reg), where reg is a pseudo (that will end in
588 a memory location), then we may need a scratch register to handle
589 the fp/sp+largeoffset address. */
590 if (code == SUBREG)
592 rtx addr = NULL_RTX;
593 x = SUBREG_REG (x);
595 if (REG_P (x))
597 int regno = REGNO (x);
598 if (regno >= FIRST_PSEUDO_REGISTER)
599 regno = reg_renumber[regno];
601 if (regno != -1)
602 return NO_REGS;
604 /* It is a pseudo that ends in a stack location. */
605 if (reg_equiv_mem (REGNO (x)))
607 /* Get the equivalent address and check the range of the
608 offset. */
609 rtx mem = reg_equiv_mem (REGNO (x));
610 addr = find_replacement (&XEXP (mem, 0));
613 else
615 gcc_assert (MEM_P (x));
616 addr = XEXP (x, 0);
617 addr = simplify_rtx (addr);
619 if (addr && GET_CODE (addr) == PLUS
620 && CONST_INT_P (XEXP (addr, 1))
621 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
623 switch (mode)
625 case E_QImode:
626 sri->icode =
627 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store;
628 break;
629 case E_HImode:
630 sri->icode =
631 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store;
632 break;
633 default:
634 break;
638 return NO_REGS;
641 /* Convert reloads using offsets that are too large to use indirect
642 addressing. */
644 void
645 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
647 rtx addr;
649 gcc_assert (GET_CODE (mem) == MEM);
650 addr = XEXP (mem, 0);
652 /* Large offset: use a move. FIXME: ld ops accepts limms as
653 offsets. Hence, the following move insn is not required. */
654 emit_move_insn (scratch, addr);
655 mem = replace_equiv_address_nv (mem, scratch);
657 /* Now create the move. */
658 if (store_p)
659 emit_insn (gen_rtx_SET (mem, reg));
660 else
661 emit_insn (gen_rtx_SET (reg, mem));
663 return;
666 static unsigned arc_ifcvt (void);
668 namespace {
670 const pass_data pass_data_arc_ifcvt =
672 RTL_PASS,
673 "arc_ifcvt", /* name */
674 OPTGROUP_NONE, /* optinfo_flags */
675 TV_IFCVT2, /* tv_id */
676 0, /* properties_required */
677 0, /* properties_provided */
678 0, /* properties_destroyed */
679 0, /* todo_flags_start */
680 TODO_df_finish /* todo_flags_finish */
683 class pass_arc_ifcvt : public rtl_opt_pass
685 public:
686 pass_arc_ifcvt(gcc::context *ctxt)
687 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt)
690 /* opt_pass methods: */
691 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); }
692 virtual unsigned int execute (function *) { return arc_ifcvt (); }
695 } // anon namespace
697 rtl_opt_pass *
698 make_pass_arc_ifcvt (gcc::context *ctxt)
700 return new pass_arc_ifcvt (ctxt);
703 static unsigned arc_predicate_delay_insns (void);
705 namespace {
707 const pass_data pass_data_arc_predicate_delay_insns =
709 RTL_PASS,
710 "arc_predicate_delay_insns", /* name */
711 OPTGROUP_NONE, /* optinfo_flags */
712 TV_IFCVT2, /* tv_id */
713 0, /* properties_required */
714 0, /* properties_provided */
715 0, /* properties_destroyed */
716 0, /* todo_flags_start */
717 TODO_df_finish /* todo_flags_finish */
720 class pass_arc_predicate_delay_insns : public rtl_opt_pass
722 public:
723 pass_arc_predicate_delay_insns(gcc::context *ctxt)
724 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
727 /* opt_pass methods: */
728 virtual unsigned int execute (function *)
730 return arc_predicate_delay_insns ();
734 } // anon namespace
736 rtl_opt_pass *
737 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
739 return new pass_arc_predicate_delay_insns (ctxt);
742 /* Called by OVERRIDE_OPTIONS to initialize various things. */
744 static void
745 arc_init (void)
747 if (TARGET_V2)
749 /* I have the multiplier, then use it*/
750 if (TARGET_MPYW || TARGET_MULTI)
751 arc_multcost = COSTS_N_INSNS (1);
753 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
754 if (arc_multcost < 0)
755 switch (arc_tune)
757 case TUNE_ARC700_4_2_STD:
758 /* latency 7;
759 max throughput (1 multiply + 4 other insns) / 5 cycles. */
760 arc_multcost = COSTS_N_INSNS (4);
761 if (TARGET_NOMPY_SET)
762 arc_multcost = COSTS_N_INSNS (30);
763 break;
764 case TUNE_ARC700_4_2_XMAC:
765 /* latency 5;
766 max throughput (1 multiply + 2 other insns) / 3 cycles. */
767 arc_multcost = COSTS_N_INSNS (3);
768 if (TARGET_NOMPY_SET)
769 arc_multcost = COSTS_N_INSNS (30);
770 break;
771 case TUNE_ARC600:
772 if (TARGET_MUL64_SET)
774 arc_multcost = COSTS_N_INSNS (4);
775 break;
777 /* Fall through. */
778 default:
779 arc_multcost = COSTS_N_INSNS (30);
780 break;
783 /* MPY instructions valid only for ARC700 or ARCv2. */
784 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
785 error ("-mno-mpy supported only for ARC700 or ARCv2");
787 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
788 error ("-mno-dpfp-lrsr supported only with -mdpfp");
790 /* FPX-1. No fast and compact together. */
791 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
792 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
793 error ("FPX fast and compact options cannot be specified together");
795 /* FPX-2. No fast-spfp for arc600 or arc601. */
796 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
797 error ("-mspfp_fast not available on ARC600 or ARC601");
799 /* FPX-4. No FPX extensions mixed with FPU extensions. */
800 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
801 && TARGET_HARD_FLOAT)
802 error ("No FPX/FPU mixing allowed");
804 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
805 if (flag_pic && TARGET_ARC600_FAMILY)
807 warning (DK_WARNING,
808 "PIC is not supported for %s. Generating non-PIC code only..",
809 arc_cpu_string);
810 flag_pic = 0;
813 arc_init_reg_tables ();
815 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
816 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
817 arc_punct_chars['#'] = 1;
818 arc_punct_chars['*'] = 1;
819 arc_punct_chars['?'] = 1;
820 arc_punct_chars['!'] = 1;
821 arc_punct_chars['^'] = 1;
822 arc_punct_chars['&'] = 1;
823 arc_punct_chars['+'] = 1;
824 arc_punct_chars['_'] = 1;
826 if (optimize > 1 && !TARGET_NO_COND_EXEC)
828 /* There are two target-independent ifcvt passes, and arc_reorg may do
829 one or more arc_ifcvt calls. */
830 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g);
831 struct register_pass_info arc_ifcvt4_info
832 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER };
833 struct register_pass_info arc_ifcvt5_info
834 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE };
836 register_pass (&arc_ifcvt4_info);
837 register_pass (&arc_ifcvt5_info);
840 if (flag_delayed_branch)
842 opt_pass *pass_arc_predicate_delay_insns
843 = make_pass_arc_predicate_delay_insns (g);
844 struct register_pass_info arc_predicate_delay_info
845 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER };
847 register_pass (&arc_predicate_delay_info);
851 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
852 register range is specified as two registers separated by a dash.
853 It always starts with r0, and its upper limit is fp register.
854 blink and lp_count registers are optional. */
856 static void
857 irq_range (const char *cstr)
859 int i, first, last, blink, lpcount, xreg;
860 char *str, *dash, *comma;
862 i = strlen (cstr);
863 str = (char *) alloca (i + 1);
864 memcpy (str, cstr, i + 1);
865 blink = -1;
866 lpcount = -1;
868 dash = strchr (str, '-');
869 if (!dash)
871 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
872 return;
874 *dash = '\0';
876 comma = strchr (dash + 1, ',');
877 if (comma)
878 *comma = '\0';
880 first = decode_reg_name (str);
881 if (first != 0)
883 warning (0, "first register must be R0");
884 return;
887 /* At this moment we do not have the register names initialized
888 accordingly. */
889 if (!strcmp (dash + 1, "ilink"))
890 last = 29;
891 else
892 last = decode_reg_name (dash + 1);
894 if (last < 0)
896 warning (0, "unknown register name: %s", dash + 1);
897 return;
900 if (!(last & 0x01))
902 warning (0, "last register name %s must be an odd register", dash + 1);
903 return;
906 *dash = '-';
908 if (first > last)
910 warning (0, "%s-%s is an empty range", str, dash + 1);
911 return;
914 while (comma)
916 *comma = ',';
917 str = comma + 1;
919 comma = strchr (str, ',');
920 if (comma)
921 *comma = '\0';
923 xreg = decode_reg_name (str);
924 switch (xreg)
926 case 31:
927 blink = 31;
928 break;
930 case 60:
931 lpcount = 60;
932 break;
934 default:
935 warning (0, "unknown register name: %s", str);
936 return;
940 irq_ctrl_saved.irq_save_last_reg = last;
941 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31);
942 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60);
945 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
946 8, 16, or 32. */
948 static void
949 parse_mrgf_banked_regs_option (const char *arg)
951 long int val;
952 char *end_ptr;
954 errno = 0;
955 val = strtol (arg, &end_ptr, 10);
956 if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
957 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
959 error ("invalid number in -mrgf-banked-regs=%s "
960 "valid values are 0, 4, 8, 16, or 32", arg);
961 return;
963 rgf_banked_register_count = (int) val;
966 /* Check ARC options, generate derived target attributes. */
968 static void
969 arc_override_options (void)
971 unsigned int i;
972 cl_deferred_option *opt;
973 vec<cl_deferred_option> *vopt
974 = (vec<cl_deferred_option> *) arc_deferred_options;
976 if (arc_cpu == PROCESSOR_NONE)
977 arc_cpu = TARGET_CPU_DEFAULT;
979 /* Set the default cpu options. */
980 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
982 /* Set the architectures. */
983 switch (arc_selected_cpu->arch_info->arch_id)
985 case BASE_ARCH_em:
986 arc_cpu_string = "EM";
987 break;
988 case BASE_ARCH_hs:
989 arc_cpu_string = "HS";
990 break;
991 case BASE_ARCH_700:
992 if (arc_selected_cpu->processor == PROCESSOR_nps400)
993 arc_cpu_string = "NPS400";
994 else
995 arc_cpu_string = "ARC700";
996 break;
997 case BASE_ARCH_6xx:
998 arc_cpu_string = "ARC600";
999 break;
1000 default:
1001 gcc_unreachable ();
1004 irq_ctrl_saved.irq_save_last_reg = -1;
1005 irq_ctrl_saved.irq_save_blink = false;
1006 irq_ctrl_saved.irq_save_lpcount = false;
1008 rgf_banked_register_count = 0;
1010 /* Handle the deferred options. */
1011 if (vopt)
1012 FOR_EACH_VEC_ELT (*vopt, i, opt)
1014 switch (opt->opt_index)
1016 case OPT_mirq_ctrl_saved_:
1017 if (TARGET_V2)
1018 irq_range (opt->arg);
1019 else
1020 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1021 break;
1023 case OPT_mrgf_banked_regs_:
1024 if (TARGET_V2)
1025 parse_mrgf_banked_regs_option (opt->arg);
1026 else
1027 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1028 break;
1030 default:
1031 gcc_unreachable();
1035 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1036 specific flags are set in arc-common.c. The architecture forces
1037 the default hardware configurations in, regardless what command
1038 line options are saying. The CPU optional hw options can be
1039 turned on or off. */
1040 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1041 do { \
1042 if ((arc_selected_cpu->flags & CODE) \
1043 && ((target_flags_explicit & MASK) == 0)) \
1044 target_flags |= MASK; \
1045 if (arc_selected_cpu->arch_info->dflags & CODE) \
1046 target_flags |= MASK; \
1047 } while (0);
1048 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1049 do { \
1050 if ((arc_selected_cpu->flags & CODE) \
1051 && (VAR == DEFAULT_##VAR)) \
1052 VAR = VAL; \
1053 if (arc_selected_cpu->arch_info->dflags & CODE) \
1054 VAR = VAL; \
1055 } while (0);
1057 #include "arc-options.def"
1059 #undef ARC_OPTX
1060 #undef ARC_OPT
1062 /* Check options against architecture options. Throw an error if
1063 option is not allowed. */
1064 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1065 do { \
1066 if ((VAR == VAL) \
1067 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1069 error ("%s is not available for %s architecture", \
1070 DOC, arc_selected_cpu->arch_info->name); \
1072 } while (0);
1073 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1074 do { \
1075 if ((target_flags & MASK) \
1076 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1077 error ("%s is not available for %s architecture", \
1078 DOC, arc_selected_cpu->arch_info->name); \
1079 } while (0);
1081 #include "arc-options.def"
1083 #undef ARC_OPTX
1084 #undef ARC_OPT
1086 /* Set Tune option. */
1087 if (arc_tune == TUNE_NONE)
1088 arc_tune = (enum attr_tune) arc_selected_cpu->tune;
1090 if (arc_size_opt_level == 3)
1091 optimize_size = 1;
1093 /* Compact casesi is not a valid option for ARCv2 family. */
1094 if (TARGET_V2)
1096 if (TARGET_COMPACT_CASESI)
1098 warning (0, "compact-casesi is not applicable to ARCv2");
1099 TARGET_COMPACT_CASESI = 0;
1102 else if (optimize_size == 1
1103 && !global_options_set.x_TARGET_COMPACT_CASESI)
1104 TARGET_COMPACT_CASESI = 1;
1106 if (flag_pic)
1107 target_flags |= MASK_NO_SDATA_SET;
1109 if (flag_no_common == 255)
1110 flag_no_common = !TARGET_NO_SDATA_SET;
1112 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1113 if (TARGET_MIXED_CODE)
1114 TARGET_Q_CLASS = 1;
1115 if (!TARGET_Q_CLASS)
1116 TARGET_COMPACT_CASESI = 0;
1117 if (TARGET_COMPACT_CASESI)
1118 TARGET_CASE_VECTOR_PC_RELATIVE = 1;
1120 /* These need to be done at start up. It's convenient to do them here. */
1121 arc_init ();
1124 /* The condition codes of the ARC, and the inverse function. */
1125 /* For short branches, the "c" / "nc" names are not defined in the ARC
1126 Programmers manual, so we have to use "lo" / "hs"" instead. */
1127 static const char *arc_condition_codes[] =
1129 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1130 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1133 enum arc_cc_code_index
1135 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
1136 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
1137 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
1138 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
1141 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1143 /* Returns the index of the ARC condition code string in
1144 `arc_condition_codes'. COMPARISON should be an rtx like
1145 `(eq (...) (...))'. */
1147 static int
1148 get_arc_condition_code (rtx comparison)
1150 switch (GET_MODE (XEXP (comparison, 0)))
1152 case E_CCmode:
1153 case E_SImode: /* For BRcc. */
1154 switch (GET_CODE (comparison))
1156 case EQ : return ARC_CC_EQ;
1157 case NE : return ARC_CC_NE;
1158 case GT : return ARC_CC_GT;
1159 case LE : return ARC_CC_LE;
1160 case GE : return ARC_CC_GE;
1161 case LT : return ARC_CC_LT;
1162 case GTU : return ARC_CC_HI;
1163 case LEU : return ARC_CC_LS;
1164 case LTU : return ARC_CC_LO;
1165 case GEU : return ARC_CC_HS;
1166 default : gcc_unreachable ();
1168 case E_CC_ZNmode:
1169 switch (GET_CODE (comparison))
1171 case EQ : return ARC_CC_EQ;
1172 case NE : return ARC_CC_NE;
1173 case GE: return ARC_CC_P;
1174 case LT: return ARC_CC_N;
1175 case GT : return ARC_CC_PNZ;
1176 default : gcc_unreachable ();
1178 case E_CC_Zmode:
1179 switch (GET_CODE (comparison))
1181 case EQ : return ARC_CC_EQ;
1182 case NE : return ARC_CC_NE;
1183 default : gcc_unreachable ();
1185 case E_CC_Cmode:
1186 switch (GET_CODE (comparison))
1188 case LTU : return ARC_CC_C;
1189 case GEU : return ARC_CC_NC;
1190 default : gcc_unreachable ();
1192 case E_CC_FP_GTmode:
1193 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1194 switch (GET_CODE (comparison))
1196 case GT : return ARC_CC_N;
1197 case UNLE: return ARC_CC_P;
1198 default : gcc_unreachable ();
1200 else
1201 switch (GET_CODE (comparison))
1203 case GT : return ARC_CC_HI;
1204 case UNLE : return ARC_CC_LS;
1205 default : gcc_unreachable ();
1207 case E_CC_FP_GEmode:
1208 /* Same for FPX and non-FPX. */
1209 switch (GET_CODE (comparison))
1211 case GE : return ARC_CC_HS;
1212 case UNLT : return ARC_CC_LO;
1213 default : gcc_unreachable ();
1215 case E_CC_FP_UNEQmode:
1216 switch (GET_CODE (comparison))
1218 case UNEQ : return ARC_CC_EQ;
1219 case LTGT : return ARC_CC_NE;
1220 default : gcc_unreachable ();
1222 case E_CC_FP_ORDmode:
1223 switch (GET_CODE (comparison))
1225 case UNORDERED : return ARC_CC_C;
1226 case ORDERED : return ARC_CC_NC;
1227 default : gcc_unreachable ();
1229 case E_CC_FPXmode:
1230 switch (GET_CODE (comparison))
1232 case EQ : return ARC_CC_EQ;
1233 case NE : return ARC_CC_NE;
1234 case UNORDERED : return ARC_CC_C;
1235 case ORDERED : return ARC_CC_NC;
1236 case LTGT : return ARC_CC_HI;
1237 case UNEQ : return ARC_CC_LS;
1238 default : gcc_unreachable ();
1240 case E_CC_FPUmode:
1241 switch (GET_CODE (comparison))
1243 case EQ : return ARC_CC_EQ;
1244 case NE : return ARC_CC_NE;
1245 case GT : return ARC_CC_GT;
1246 case GE : return ARC_CC_GE;
1247 case LT : return ARC_CC_C;
1248 case LE : return ARC_CC_LS;
1249 case UNORDERED : return ARC_CC_V;
1250 case ORDERED : return ARC_CC_NV;
1251 case UNGT : return ARC_CC_HI;
1252 case UNGE : return ARC_CC_HS;
1253 case UNLT : return ARC_CC_LT;
1254 case UNLE : return ARC_CC_LE;
1255 /* UNEQ and LTGT do not have representation. */
1256 case LTGT : /* Fall through. */
1257 case UNEQ : /* Fall through. */
1258 default : gcc_unreachable ();
1260 case E_CC_FPU_UNEQmode:
1261 switch (GET_CODE (comparison))
1263 case LTGT : return ARC_CC_NE;
1264 case UNEQ : return ARC_CC_EQ;
1265 default : gcc_unreachable ();
1267 default : gcc_unreachable ();
1269 /*NOTREACHED*/
1270 return (42);
1273 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1275 bool
1276 arc_short_comparison_p (rtx comparison, int offset)
1278 gcc_assert (ARC_CC_NC == ARC_CC_HS);
1279 gcc_assert (ARC_CC_C == ARC_CC_LO);
1280 switch (get_arc_condition_code (comparison))
1282 case ARC_CC_EQ: case ARC_CC_NE:
1283 return offset >= -512 && offset <= 506;
1284 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
1285 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
1286 return offset >= -64 && offset <= 58;
1287 default:
1288 return false;
1292 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1293 return the mode to be used for the comparison. */
1295 machine_mode
1296 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1298 machine_mode mode = GET_MODE (x);
1299 rtx x1;
1301 /* For an operation that sets the condition codes as a side-effect, the
1302 C and V flags is not set as for cmp, so we can only use comparisons where
1303 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1304 instead.) */
1305 /* ??? We could use "pnz" for greater than zero, however, we could then
1306 get into trouble because the comparison could not be reversed. */
1307 if (GET_MODE_CLASS (mode) == MODE_INT
1308 && y == const0_rtx
1309 && (op == EQ || op == NE
1310 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
1311 return CC_ZNmode;
1313 /* add.f for if (a+b) */
1314 if (mode == SImode
1315 && GET_CODE (y) == NEG
1316 && (op == EQ || op == NE))
1317 return CC_ZNmode;
1319 /* Check if this is a test suitable for bxor.f . */
1320 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1321 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1322 && INTVAL (y))
1323 return CC_Zmode;
1325 /* Check if this is a test suitable for add / bmsk.f . */
1326 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1327 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1328 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1329 && (~INTVAL (x1) | INTVAL (y)) < 0
1330 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1331 return CC_Zmode;
1333 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1334 && GET_CODE (x) == PLUS
1335 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1336 return CC_Cmode;
1338 if (TARGET_ARGONAUT_SET
1339 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1340 switch (op)
1342 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1343 return CC_FPXmode;
1344 case LT: case UNGE: case GT: case UNLE:
1345 return CC_FP_GTmode;
1346 case LE: case UNGT: case GE: case UNLT:
1347 return CC_FP_GEmode;
1348 default: gcc_unreachable ();
1350 else if (TARGET_HARD_FLOAT
1351 && ((mode == SFmode && TARGET_FP_SP_BASE)
1352 || (mode == DFmode && TARGET_FP_DP_BASE)))
1353 switch (op)
1355 case EQ:
1356 case NE:
1357 case UNORDERED:
1358 case ORDERED:
1359 case UNLT:
1360 case UNLE:
1361 case UNGT:
1362 case UNGE:
1363 case LT:
1364 case LE:
1365 case GT:
1366 case GE:
1367 return CC_FPUmode;
1369 case LTGT:
1370 case UNEQ:
1371 return CC_FPU_UNEQmode;
1373 default:
1374 gcc_unreachable ();
1376 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1378 switch (op)
1380 case EQ: case NE: return CC_Zmode;
1381 case LT: case UNGE:
1382 case GT: case UNLE: return CC_FP_GTmode;
1383 case LE: case UNGT:
1384 case GE: case UNLT: return CC_FP_GEmode;
1385 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1386 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1387 default: gcc_unreachable ();
1390 return CCmode;
1393 /* Vectors to keep interesting information about registers where it can easily
1394 be got. We use to use the actual mode value as the bit number, but there
1395 is (or may be) more than 32 modes now. Instead we use two tables: one
1396 indexed by hard register number, and one indexed by mode. */
1398 /* The purpose of arc_mode_class is to shrink the range of modes so that
1399 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1400 mapped into one arc_mode_class mode. */
1402 enum arc_mode_class {
1403 C_MODE,
1404 S_MODE, D_MODE, T_MODE, O_MODE,
1405 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1406 V_MODE
1409 /* Modes for condition codes. */
1410 #define C_MODES (1 << (int) C_MODE)
1412 /* Modes for single-word and smaller quantities. */
1413 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1415 /* Modes for double-word and smaller quantities. */
1416 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1418 /* Mode for 8-byte DF values only. */
1419 #define DF_MODES (1 << DF_MODE)
1421 /* Modes for quad-word and smaller quantities. */
1422 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1424 /* Modes for 128-bit vectors. */
1425 #define V_MODES (1 << (int) V_MODE)
1427 /* Value is 1 if register/mode pair is acceptable on arc. */
1429 unsigned int arc_hard_regno_mode_ok[] = {
1430 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1431 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1432 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1433 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1435 /* ??? Leave these as S_MODES for now. */
1436 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1437 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1438 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1439 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1441 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1442 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1443 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1444 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1446 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1447 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1448 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1449 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1451 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1452 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES
1455 unsigned int arc_mode_class [NUM_MACHINE_MODES];
1457 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1459 enum reg_class
1460 arc_preferred_reload_class (rtx, enum reg_class cl)
1462 if ((cl) == CHEAP_CORE_REGS || (cl) == WRITABLE_CORE_REGS)
1463 return GENERAL_REGS;
1464 return cl;
1467 /* Initialize the arc_mode_class array. */
1469 static void
1470 arc_init_reg_tables (void)
1472 int i;
1474 for (i = 0; i < NUM_MACHINE_MODES; i++)
1476 machine_mode m = (machine_mode) i;
1478 switch (GET_MODE_CLASS (m))
1480 case MODE_INT:
1481 case MODE_PARTIAL_INT:
1482 case MODE_COMPLEX_INT:
1483 if (GET_MODE_SIZE (m) <= 4)
1484 arc_mode_class[i] = 1 << (int) S_MODE;
1485 else if (GET_MODE_SIZE (m) == 8)
1486 arc_mode_class[i] = 1 << (int) D_MODE;
1487 else if (GET_MODE_SIZE (m) == 16)
1488 arc_mode_class[i] = 1 << (int) T_MODE;
1489 else if (GET_MODE_SIZE (m) == 32)
1490 arc_mode_class[i] = 1 << (int) O_MODE;
1491 else
1492 arc_mode_class[i] = 0;
1493 break;
1494 case MODE_FLOAT:
1495 case MODE_COMPLEX_FLOAT:
1496 if (GET_MODE_SIZE (m) <= 4)
1497 arc_mode_class[i] = 1 << (int) SF_MODE;
1498 else if (GET_MODE_SIZE (m) == 8)
1499 arc_mode_class[i] = 1 << (int) DF_MODE;
1500 else if (GET_MODE_SIZE (m) == 16)
1501 arc_mode_class[i] = 1 << (int) TF_MODE;
1502 else if (GET_MODE_SIZE (m) == 32)
1503 arc_mode_class[i] = 1 << (int) OF_MODE;
1504 else
1505 arc_mode_class[i] = 0;
1506 break;
1507 case MODE_VECTOR_INT:
1508 if (GET_MODE_SIZE (m) == 4)
1509 arc_mode_class[i] = (1 << (int) S_MODE);
1510 else if (GET_MODE_SIZE (m) == 8)
1511 arc_mode_class[i] = (1 << (int) D_MODE);
1512 else
1513 arc_mode_class[i] = (1 << (int) V_MODE);
1514 break;
1515 case MODE_CC:
1516 default:
1517 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1518 we must explicitly check for them here. */
1519 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1520 || i == (int) CC_Cmode
1521 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
1522 || i == CC_FPUmode || i == CC_FPU_UNEQmode)
1523 arc_mode_class[i] = 1 << (int) C_MODE;
1524 else
1525 arc_mode_class[i] = 0;
1526 break;
1531 /* Core registers 56..59 are used for multiply extension options.
1532 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1533 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1534 number depends on endianness.
1535 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1536 Because mlo / mhi form a 64 bit value, we use different gcc internal
1537 register numbers to make them form a register pair as the gcc internals
1538 know it. mmid gets number 57, if still available, and mlo / mhi get
1539 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1540 to map this back. */
1541 char rname56[5] = "r56";
1542 char rname57[5] = "r57";
1543 char rname58[5] = "r58";
1544 char rname59[5] = "r59";
1545 char rname29[7] = "ilink1";
1546 char rname30[7] = "ilink2";
1548 static void
1549 arc_conditional_register_usage (void)
1551 int regno;
1552 int i;
1553 int fix_start = 60, fix_end = 55;
1555 if (TARGET_V2)
1557 /* For ARCv2 the core register set is changed. */
1558 strcpy (rname29, "ilink");
1559 strcpy (rname30, "r30");
1560 call_used_regs[30] = 1;
1561 fixed_regs[30] = 0;
1563 arc_regno_reg_class[30] = WRITABLE_CORE_REGS;
1564 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], 30);
1565 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], 30);
1566 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 30);
1567 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 30);
1570 if (TARGET_MUL64_SET)
1572 fix_start = 57;
1573 fix_end = 59;
1575 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1576 you are supposed to refer to it as mlo & mhi, e.g
1577 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1578 In an actual asm instruction, you are of course use mmed.
1579 The point of avoiding having a separate register for mmed is that
1580 this way, we don't have to carry clobbers of that reg around in every
1581 isntruction that modifies mlo and/or mhi. */
1582 strcpy (rname57, "");
1583 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo");
1584 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi");
1587 /* The nature of arc_tp_regno is actually something more like a global
1588 register, however globalize_reg requires a declaration.
1589 We use EPILOGUE_USES to compensate so that sets from
1590 __builtin_set_frame_pointer are not deleted. */
1591 if (arc_tp_regno != -1)
1592 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1;
1594 if (TARGET_MULMAC_32BY16_SET)
1596 fix_start = 56;
1597 fix_end = fix_end > 57 ? fix_end : 57;
1598 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1599 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1601 for (regno = fix_start; regno <= fix_end; regno++)
1603 if (!fixed_regs[regno])
1604 warning (0, "multiply option implies r%d is fixed", regno);
1605 fixed_regs [regno] = call_used_regs[regno] = 1;
1607 if (TARGET_Q_CLASS)
1609 if (optimize_size)
1611 reg_alloc_order[0] = 0;
1612 reg_alloc_order[1] = 1;
1613 reg_alloc_order[2] = 2;
1614 reg_alloc_order[3] = 3;
1615 reg_alloc_order[4] = 12;
1616 reg_alloc_order[5] = 13;
1617 reg_alloc_order[6] = 14;
1618 reg_alloc_order[7] = 15;
1619 reg_alloc_order[8] = 4;
1620 reg_alloc_order[9] = 5;
1621 reg_alloc_order[10] = 6;
1622 reg_alloc_order[11] = 7;
1623 reg_alloc_order[12] = 8;
1624 reg_alloc_order[13] = 9;
1625 reg_alloc_order[14] = 10;
1626 reg_alloc_order[15] = 11;
1628 else
1630 reg_alloc_order[2] = 12;
1631 reg_alloc_order[3] = 13;
1632 reg_alloc_order[4] = 14;
1633 reg_alloc_order[5] = 15;
1634 reg_alloc_order[6] = 1;
1635 reg_alloc_order[7] = 0;
1636 reg_alloc_order[8] = 4;
1637 reg_alloc_order[9] = 5;
1638 reg_alloc_order[10] = 6;
1639 reg_alloc_order[11] = 7;
1640 reg_alloc_order[12] = 8;
1641 reg_alloc_order[13] = 9;
1642 reg_alloc_order[14] = 10;
1643 reg_alloc_order[15] = 11;
1646 if (TARGET_SIMD_SET)
1648 int i;
1649 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1650 reg_alloc_order [i] = i;
1651 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1652 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1653 reg_alloc_order [i] = i;
1655 /* For ARC600, lp_count may not be read in an instruction
1656 following immediately after another one setting it to a new value.
1657 There was some discussion on how to enforce scheduling constraints for
1658 processors with missing interlocks on the gcc mailing list:
1659 http://gcc.gnu.org/ml/gcc/2008-05/msg00021.html .
1660 However, we can't actually use this approach, because for ARC the
1661 delay slot scheduling pass is active, which runs after
1662 machine_dependent_reorg. */
1663 if (TARGET_ARC600)
1664 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1665 else if (!TARGET_LP_WR_INTERLOCK)
1666 fixed_regs[LP_COUNT] = 1;
1667 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1668 if (!call_used_regs[regno])
1669 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
1670 for (regno = 32; regno < 60; regno++)
1671 if (!fixed_regs[regno])
1672 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], regno);
1673 if (!TARGET_ARC600_FAMILY)
1675 for (regno = 32; regno <= 60; regno++)
1676 CLEAR_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], regno);
1678 /* If they have used -ffixed-lp_count, make sure it takes
1679 effect. */
1680 if (fixed_regs[LP_COUNT])
1682 CLEAR_HARD_REG_BIT (reg_class_contents[LPCOUNT_REG], LP_COUNT);
1683 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1684 CLEAR_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], LP_COUNT);
1686 /* Instead of taking out SF_MODE like below, forbid it outright. */
1687 arc_hard_regno_mode_ok[60] = 0;
1689 else
1690 arc_hard_regno_mode_ok[60] = 1 << (int) S_MODE;
1693 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1694 registers. */
1695 if (TARGET_HS)
1697 for (regno = 1; regno < 32; regno +=2)
1699 arc_hard_regno_mode_ok[regno] = S_MODES;
1703 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1705 if (i < 29)
1707 if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
1708 && ((i <= 3) || ((i >= 12) && (i <= 15))))
1709 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1710 else
1711 arc_regno_reg_class[i] = GENERAL_REGS;
1713 else if (i < 60)
1714 arc_regno_reg_class[i]
1715 = (fixed_regs[i]
1716 ? (TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i)
1717 ? CHEAP_CORE_REGS : ALL_CORE_REGS)
1718 : (((!TARGET_ARC600_FAMILY)
1719 && TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i))
1720 ? CHEAP_CORE_REGS : WRITABLE_CORE_REGS));
1721 else
1722 arc_regno_reg_class[i] = NO_REGS;
1725 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1726 has not been activated. */
1727 if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
1728 CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
1729 if (!TARGET_Q_CLASS)
1730 CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
1732 gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
1734 /* Handle Special Registers. */
1735 arc_regno_reg_class[29] = LINK_REGS; /* ilink1 register. */
1736 if (!TARGET_V2)
1737 arc_regno_reg_class[30] = LINK_REGS; /* ilink2 register. */
1738 arc_regno_reg_class[31] = LINK_REGS; /* blink register. */
1739 arc_regno_reg_class[60] = LPCOUNT_REG;
1740 arc_regno_reg_class[61] = NO_REGS; /* CC_REG: must be NO_REGS. */
1741 arc_regno_reg_class[62] = GENERAL_REGS;
1743 if (TARGET_DPFP)
1745 for (i = 40; i < 44; ++i)
1747 arc_regno_reg_class[i] = DOUBLE_REGS;
1749 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1750 no attempt is made to use such a register as a destination
1751 operand in *movdf_insn. */
1752 if (!TARGET_ARGONAUT_SET)
1754 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1755 interpreted to mean they can use D1 or D2 in their insn. */
1756 CLEAR_HARD_REG_BIT(reg_class_contents[CHEAP_CORE_REGS ], i);
1757 CLEAR_HARD_REG_BIT(reg_class_contents[ALL_CORE_REGS ], i);
1758 CLEAR_HARD_REG_BIT(reg_class_contents[WRITABLE_CORE_REGS ], i);
1759 CLEAR_HARD_REG_BIT(reg_class_contents[MPY_WRITABLE_CORE_REGS], i);
1763 else
1765 /* Disable all DOUBLE_REGISTER settings,
1766 if not generating DPFP code. */
1767 arc_regno_reg_class[40] = ALL_REGS;
1768 arc_regno_reg_class[41] = ALL_REGS;
1769 arc_regno_reg_class[42] = ALL_REGS;
1770 arc_regno_reg_class[43] = ALL_REGS;
1772 fixed_regs[40] = 1;
1773 fixed_regs[41] = 1;
1774 fixed_regs[42] = 1;
1775 fixed_regs[43] = 1;
1777 arc_hard_regno_mode_ok[40] = 0;
1778 arc_hard_regno_mode_ok[42] = 0;
1780 CLEAR_HARD_REG_SET(reg_class_contents [DOUBLE_REGS]);
1783 if (TARGET_SIMD_SET)
1785 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1786 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
1788 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1789 arc_regno_reg_class [i] = SIMD_VR_REGS;
1791 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
1792 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
1793 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
1794 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
1796 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1797 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1798 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
1801 /* pc : r63 */
1802 arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
1804 /*ARCV2 Accumulator. */
1805 if ((TARGET_V2
1806 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
1807 || TARGET_PLUS_DMPY)
1809 arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
1810 arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
1811 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCL_REGNO);
1812 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO);
1813 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO);
1814 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO);
1815 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO);
1816 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO);
1817 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCL_REGNO);
1818 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCH_REGNO);
1820 /* Allow the compiler to freely use them. */
1821 fixed_regs[ACCL_REGNO] = 0;
1822 fixed_regs[ACCH_REGNO] = 0;
1824 arc_hard_regno_mode_ok[ACC_REG_FIRST] = D_MODES;
1828 /* Handle an "interrupt" attribute; arguments as in
1829 struct attribute_spec.handler. */
1831 static tree
1832 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
1833 bool *no_add_attrs)
1835 gcc_assert (args);
1837 tree value = TREE_VALUE (args);
1839 if (TREE_CODE (value) != STRING_CST)
1841 warning (OPT_Wattributes,
1842 "argument of %qE attribute is not a string constant",
1843 name);
1844 *no_add_attrs = true;
1846 else if (!TARGET_V2
1847 && strcmp (TREE_STRING_POINTER (value), "ilink1")
1848 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
1850 warning (OPT_Wattributes,
1851 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1852 name);
1853 *no_add_attrs = true;
1855 else if (TARGET_V2
1856 && strcmp (TREE_STRING_POINTER (value), "ilink")
1857 && strcmp (TREE_STRING_POINTER (value), "firq"))
1859 warning (OPT_Wattributes,
1860 "argument of %qE attribute is not \"ilink\" or \"firq\"",
1861 name);
1862 *no_add_attrs = true;
1865 return NULL_TREE;
1868 static tree
1869 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
1870 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1872 if (TREE_CODE (*node) != FUNCTION_DECL)
1874 warning (OPT_Wattributes, "%qE attribute only applies to functions",
1875 name);
1876 *no_add_attrs = true;
1879 return NULL_TREE;
1882 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
1884 static bool
1885 arc_allocate_stack_slots_for_args (void)
1887 /* Naked functions should not allocate stack slots for arguments. */
1888 unsigned int fn_type = arc_compute_function_type (cfun);
1890 return !ARC_NAKED_P(fn_type);
1893 /* Implement `TARGET_WARN_FUNC_RETURN'. */
1895 static bool
1896 arc_warn_func_return (tree decl)
1898 struct function *func = DECL_STRUCT_FUNCTION (decl);
1899 unsigned int fn_type = arc_compute_function_type (func);
1901 return !ARC_NAKED_P (fn_type);
1904 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1905 and two if they are nearly compatible (which causes a warning to be
1906 generated). */
1908 static int
1909 arc_comp_type_attributes (const_tree type1,
1910 const_tree type2)
1912 int l1, l2, m1, m2, s1, s2;
1914 /* Check for mismatch of non-default calling convention. */
1915 if (TREE_CODE (type1) != FUNCTION_TYPE)
1916 return 1;
1918 /* Check for mismatched call attributes. */
1919 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
1920 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
1921 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
1922 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
1923 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
1924 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
1926 /* Only bother to check if an attribute is defined. */
1927 if (l1 | l2 | m1 | m2 | s1 | s2)
1929 /* If one type has an attribute, the other must have the same attribute. */
1930 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
1931 return 0;
1933 /* Disallow mixed attributes. */
1934 if (l1 + m1 + s1 > 1)
1935 return 0;
1939 return 1;
1942 /* Set the default attributes for TYPE. */
1944 void
1945 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED)
1947 gcc_unreachable();
1950 /* Misc. utilities. */
1952 /* X and Y are two things to compare using CODE. Emit the compare insn and
1953 return the rtx for the cc reg in the proper mode. */
1956 gen_compare_reg (rtx comparison, machine_mode omode)
1958 enum rtx_code code = GET_CODE (comparison);
1959 rtx x = XEXP (comparison, 0);
1960 rtx y = XEXP (comparison, 1);
1961 rtx tmp, cc_reg;
1962 machine_mode mode, cmode;
1965 cmode = GET_MODE (x);
1966 if (cmode == VOIDmode)
1967 cmode = GET_MODE (y);
1968 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode);
1969 if (cmode == SImode)
1971 if (!register_operand (x, SImode))
1973 if (register_operand (y, SImode))
1975 tmp = x;
1976 x = y;
1977 y = tmp;
1978 code = swap_condition (code);
1980 else
1981 x = copy_to_mode_reg (SImode, x);
1983 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
1984 y = copy_to_mode_reg (SImode, y);
1986 else
1988 x = force_reg (cmode, x);
1989 y = force_reg (cmode, y);
1991 mode = SELECT_CC_MODE (code, x, y);
1993 cc_reg = gen_rtx_REG (mode, CC_REG);
1995 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
1996 cmpdfpx_raw, is not a correct comparison for floats:
1997 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
1999 if (TARGET_ARGONAUT_SET
2000 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2002 switch (code)
2004 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
2005 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2006 break;
2007 case GT: case UNLE: case GE: case UNLT:
2008 code = swap_condition (code);
2009 tmp = x;
2010 x = y;
2011 y = tmp;
2012 break;
2013 default:
2014 gcc_unreachable ();
2016 if (cmode == SFmode)
2018 emit_insn (gen_cmpsfpx_raw (x, y));
2020 else /* DFmode */
2022 /* Accepts Dx regs directly by insns. */
2023 emit_insn (gen_cmpdfpx_raw (x, y));
2026 if (mode != CC_FPXmode)
2027 emit_insn (gen_rtx_SET (cc_reg,
2028 gen_rtx_COMPARE (mode,
2029 gen_rtx_REG (CC_FPXmode, 61),
2030 const0_rtx)));
2032 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2034 switch (code)
2036 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2037 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2038 break;
2039 case LT: case UNGE: case LE: case UNGT:
2040 code = swap_condition (code);
2041 tmp = x;
2042 x = y;
2043 y = tmp;
2044 break;
2045 default:
2046 gcc_unreachable ();
2049 emit_insn (gen_cmp_quark (cc_reg,
2050 gen_rtx_COMPARE (mode, x, y)));
2052 else if (TARGET_HARD_FLOAT
2053 && ((cmode == SFmode && TARGET_FP_SP_BASE)
2054 || (cmode == DFmode && TARGET_FP_DP_BASE)))
2055 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2056 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
2058 rtx op0 = gen_rtx_REG (cmode, 0);
2059 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
2060 bool swap = false;
2062 switch (code)
2064 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2065 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2066 break;
2067 case LT: case UNGE: case LE: case UNGT:
2068 code = swap_condition (code);
2069 swap = true;
2070 break;
2071 default:
2072 gcc_unreachable ();
2074 if (currently_expanding_to_rtl)
2076 if (swap)
2078 tmp = x;
2079 x = y;
2080 y = tmp;
2082 emit_move_insn (op0, x);
2083 emit_move_insn (op1, y);
2085 else
2087 gcc_assert (rtx_equal_p (op0, x));
2088 gcc_assert (rtx_equal_p (op1, y));
2089 if (swap)
2091 op0 = y;
2092 op1 = x;
2095 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2097 else
2098 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2099 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
2102 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2103 We assume the value can be either signed or unsigned. */
2105 bool
2106 arc_double_limm_p (rtx value)
2108 HOST_WIDE_INT low, high;
2110 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2112 if (TARGET_DPFP)
2113 return true;
2115 low = CONST_DOUBLE_LOW (value);
2116 high = CONST_DOUBLE_HIGH (value);
2118 if (low & 0x80000000)
2120 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
2121 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
2122 == - (unsigned HOST_WIDE_INT) 0x80000000)
2123 && high == -1));
2125 else
2127 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2131 /* Do any needed setup for a variadic function. For the ARC, we must
2132 create a register parameter block, and then copy any anonymous arguments
2133 in registers to memory.
2135 CUM has not been updated for the last named argument which has type TYPE
2136 and mode MODE, and we rely on this fact. */
2138 static void
2139 arc_setup_incoming_varargs (cumulative_args_t args_so_far,
2140 machine_mode mode, tree type,
2141 int *pretend_size, int no_rtl)
2143 int first_anon_arg;
2144 CUMULATIVE_ARGS next_cum;
2146 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2148 next_cum = *get_cumulative_args (args_so_far);
2149 arc_function_arg_advance (pack_cumulative_args (&next_cum),
2150 mode, type, true);
2151 first_anon_arg = next_cum;
2153 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2155 /* First anonymous (unnamed) argument is in a reg. */
2157 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2158 int first_reg_offset = first_anon_arg;
2160 if (!no_rtl)
2162 rtx regblock
2163 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2164 FIRST_PARM_OFFSET (0)));
2165 move_block_from_reg (first_reg_offset, regblock,
2166 MAX_ARC_PARM_REGS - first_reg_offset);
2169 *pretend_size
2170 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2174 /* Cost functions. */
2176 /* Provide the costs of an addressing mode that contains ADDR.
2177 If ADDR is not a valid address, its cost is irrelevant. */
2180 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2182 switch (GET_CODE (addr))
2184 case REG :
2185 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1;
2186 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2187 case PRE_MODIFY: case POST_MODIFY:
2188 return !speed;
2190 case LABEL_REF :
2191 case SYMBOL_REF :
2192 case CONST :
2193 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2194 return 0;
2195 /* Most likely needs a LIMM. */
2196 return COSTS_N_INSNS (1);
2198 case PLUS :
2200 register rtx plus0 = XEXP (addr, 0);
2201 register rtx plus1 = XEXP (addr, 1);
2203 if (GET_CODE (plus0) != REG
2204 && (GET_CODE (plus0) != MULT
2205 || !CONST_INT_P (XEXP (plus0, 1))
2206 || (INTVAL (XEXP (plus0, 1)) != 2
2207 && INTVAL (XEXP (plus0, 1)) != 4)))
2208 break;
2210 switch (GET_CODE (plus1))
2212 case CONST_INT :
2213 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2214 ? COSTS_N_INSNS (1)
2215 : speed
2217 : (satisfies_constraint_Rcq (plus0)
2218 && satisfies_constraint_O (plus1))
2220 : 1);
2221 case REG:
2222 return (speed < 1 ? 0
2223 : (satisfies_constraint_Rcq (plus0)
2224 && satisfies_constraint_Rcq (plus1))
2225 ? 0 : 1);
2226 case CONST :
2227 case SYMBOL_REF :
2228 case LABEL_REF :
2229 return COSTS_N_INSNS (1);
2230 default:
2231 break;
2233 break;
2235 default:
2236 break;
2239 return 4;
2242 /* Emit instruction X with the frame related bit set. */
2244 static rtx
2245 frame_insn (rtx x)
2247 x = emit_insn (x);
2248 RTX_FRAME_RELATED_P (x) = 1;
2249 return x;
2252 /* Emit a frame insn to move SRC to DST. */
2254 static rtx
2255 frame_move (rtx dst, rtx src)
2257 rtx tmp = gen_rtx_SET (dst, src);
2258 RTX_FRAME_RELATED_P (tmp) = 1;
2259 return frame_insn (tmp);
2262 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2263 auto increment address, or is zero. */
2265 static rtx
2266 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2268 rtx insn = frame_move (dst, src);
2270 if (!addr
2271 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2272 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2273 add_reg_note (insn, REG_INC, reg);
2274 return insn;
2277 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2279 static rtx
2280 frame_add (rtx reg, HOST_WIDE_INT offset)
2282 gcc_assert ((offset & 0x3) == 0);
2283 if (!offset)
2284 return NULL_RTX;
2285 return frame_move (reg, plus_constant (Pmode, reg, offset));
2288 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2290 static rtx
2291 frame_stack_add (HOST_WIDE_INT offset)
2293 return frame_add (stack_pointer_rtx, offset);
2296 /* Traditionally, we push saved registers first in the prologue,
2297 then we allocate the rest of the frame - and reverse in the epilogue.
2298 This has still its merits for ease of debugging, or saving code size
2299 or even execution time if the stack frame is so large that some accesses
2300 can't be encoded anymore with offsets in the instruction code when using
2301 a different scheme.
2302 Also, it would be a good starting point if we got instructions to help
2303 with register save/restore.
2305 However, often stack frames are small, and the pushing / popping has
2306 some costs:
2307 - the stack modification prevents a lot of scheduling.
2308 - frame allocation / deallocation needs extra instructions.
2309 - unless we know that we compile ARC700 user code, we need to put
2310 a memory barrier after frame allocation / before deallocation to
2311 prevent interrupts clobbering our data in the frame.
2312 In particular, we don't have any such guarantees for library functions,
2313 which tend to, on the other hand, to have small frames.
2315 Thus, for small frames, we'd like to use a different scheme:
2316 - The frame is allocated in full with the first prologue instruction,
2317 and deallocated in full with the last epilogue instruction.
2318 Thus, the instructions in-betwen can be freely scheduled.
2319 - If the function has no outgoing arguments on the stack, we can allocate
2320 one register save slot at the top of the stack. This register can then
2321 be saved simultanously with frame allocation, and restored with
2322 frame deallocation.
2323 This register can be picked depending on scheduling considerations,
2324 although same though should go into having some set of registers
2325 to be potentially lingering after a call, and others to be available
2326 immediately - i.e. in the absence of interprocedual optimization, we
2327 can use an ABI-like convention for register allocation to reduce
2328 stalls after function return. */
2329 /* Function prologue/epilogue handlers. */
2331 /* ARCompact stack frames look like:
2333 Before call After call
2334 high +-----------------------+ +-----------------------+
2335 mem | reg parm save area | | reg parm save area |
2336 | only created for | | only created for |
2337 | variable arg fns | | variable arg fns |
2338 AP +-----------------------+ +-----------------------+
2339 | return addr register | | return addr register |
2340 | (if required) | | (if required) |
2341 +-----------------------+ +-----------------------+
2342 | | | |
2343 | reg save area | | reg save area |
2344 | | | |
2345 +-----------------------+ +-----------------------+
2346 | frame pointer | | frame pointer |
2347 | (if required) | | (if required) |
2348 FP +-----------------------+ +-----------------------+
2349 | | | |
2350 | local/temp variables | | local/temp variables |
2351 | | | |
2352 +-----------------------+ +-----------------------+
2353 | | | |
2354 | arguments on stack | | arguments on stack |
2355 | | | |
2356 SP +-----------------------+ +-----------------------+
2357 | reg parm save area |
2358 | only created for |
2359 | variable arg fns |
2360 AP +-----------------------+
2361 | return addr register |
2362 | (if required) |
2363 +-----------------------+
2365 | reg save area |
2367 +-----------------------+
2368 | frame pointer |
2369 | (if required) |
2370 FP +-----------------------+
2372 | local/temp variables |
2374 +-----------------------+
2376 | arguments on stack |
2377 low | |
2378 mem SP +-----------------------+
2380 Notes:
2381 1) The "reg parm save area" does not exist for non variable argument fns.
2382 The "reg parm save area" can be eliminated completely if we created our
2383 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2385 /* Structure to be filled in by arc_compute_frame_size with register
2386 save masks, and offsets for the current function. */
2387 struct GTY (()) arc_frame_info
2389 unsigned int total_size; /* # bytes that the entire frame takes up. */
2390 unsigned int extra_size; /* # bytes of extra stuff. */
2391 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
2392 unsigned int args_size; /* # bytes that outgoing arguments take up. */
2393 unsigned int reg_size; /* # bytes needed to store regs. */
2394 unsigned int var_size; /* # bytes that variables take up. */
2395 unsigned int reg_offset; /* Offset from new sp to store regs. */
2396 unsigned int gmask; /* Mask of saved gp registers. */
2397 int initialized; /* Nonzero if frame size already calculated. */
2398 short millicode_start_reg;
2399 short millicode_end_reg;
2400 bool save_return_addr;
2403 /* Defining data structures for per-function information. */
2405 typedef struct GTY (()) machine_function
2407 unsigned int fn_type;
2408 struct arc_frame_info frame_info;
2409 /* To keep track of unalignment caused by short insns. */
2410 int unalign;
2411 int force_short_suffix; /* Used when disgorging return delay slot insns. */
2412 const char *size_reason;
2413 struct arc_ccfsm ccfsm_current;
2414 /* Map from uid to ccfsm state during branch shortening. */
2415 rtx ccfsm_current_insn;
2416 char arc_reorg_started;
2417 char prescan_initialized;
2418 } machine_function;
2420 /* Type of function DECL.
2422 The result is cached. To reset the cache at the end of a function,
2423 call with DECL = NULL_TREE. */
2425 unsigned int
2426 arc_compute_function_type (struct function *fun)
2428 tree attr, decl = fun->decl;
2429 unsigned int fn_type = fun->machine->fn_type;
2431 if (fn_type != ARC_FUNCTION_UNKNOWN)
2432 return fn_type;
2434 /* Check if it is a naked function. */
2435 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
2436 fn_type |= ARC_FUNCTION_NAKED;
2437 else
2438 fn_type |= ARC_FUNCTION_NORMAL;
2440 /* Now see if this is an interrupt handler. */
2441 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2442 if (attr != NULL_TREE)
2444 tree value, args = TREE_VALUE (attr);
2446 gcc_assert (list_length (args) == 1);
2447 value = TREE_VALUE (args);
2448 gcc_assert (TREE_CODE (value) == STRING_CST);
2450 if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
2451 || !strcmp (TREE_STRING_POINTER (value), "ilink"))
2452 fn_type |= ARC_FUNCTION_ILINK1;
2453 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
2454 fn_type |= ARC_FUNCTION_ILINK2;
2455 else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
2456 fn_type |= ARC_FUNCTION_FIRQ;
2457 else
2458 gcc_unreachable ();
2461 return fun->machine->fn_type = fn_type;
2464 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2465 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2467 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2468 The return address and frame pointer are treated separately.
2469 Don't consider them here.
2470 Addition for pic: The gp register needs to be saved if the current
2471 function changes it to access gotoff variables.
2472 FIXME: This will not be needed if we used some arbitrary register
2473 instead of r26.
2476 static bool
2477 arc_must_save_register (int regno, struct function *func)
2479 unsigned int fn_type = arc_compute_function_type (func);
2480 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2481 && ARC_AUTO_IRQ_P (fn_type));
2482 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2484 switch (rgf_banked_register_count)
2486 case 4:
2487 firq_auto_save_p &= (regno < 4);
2488 break;
2489 case 8:
2490 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2491 break;
2492 case 16:
2493 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2494 || ((regno > 25) && (regno < 29))
2495 || ((regno > 29) && (regno < 32)));
2496 break;
2497 case 32:
2498 firq_auto_save_p &= (regno != 29) && (regno < 32);
2499 break;
2500 default:
2501 firq_auto_save_p = false;
2502 break;
2505 if ((regno) != RETURN_ADDR_REGNUM
2506 && (regno) != FRAME_POINTER_REGNUM
2507 && df_regs_ever_live_p (regno)
2508 && (!call_used_regs[regno]
2509 || ARC_INTERRUPT_P (fn_type))
2510 /* Do not emit code for auto saved regs. */
2511 && !irq_auto_save_p
2512 && !firq_auto_save_p)
2513 return true;
2515 if (flag_pic && crtl->uses_pic_offset_table
2516 && regno == PIC_OFFSET_TABLE_REGNUM)
2517 return true;
2519 return false;
2522 /* Return true if the return address must be saved in the current function,
2523 otherwise return false. */
2525 static bool
2526 arc_must_save_return_addr (struct function *func)
2528 if (func->machine->frame_info.save_return_addr)
2529 return true;
2531 return false;
2534 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2535 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2536 Register Allocator) pass, while we want to get the frame size
2537 correct earlier than the IRA pass. */
2538 static bool
2539 arc_frame_pointer_needed (void)
2541 return (frame_pointer_needed);
2545 /* Return non-zero if there are registers to be saved or loaded using
2546 millicode thunks. We can only use consecutive sequences starting
2547 with r13, and not going beyond r25.
2548 GMASK is a bitmask of registers to save. This function sets
2549 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2550 of registers to be saved / restored with a millicode call. */
2552 static int
2553 arc_compute_millicode_save_restore_regs (unsigned int gmask,
2554 struct arc_frame_info *frame)
2556 int regno;
2558 int start_reg = 13, end_reg = 25;
2560 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
2561 regno++;
2562 end_reg = regno - 1;
2563 /* There is no point in using millicode thunks if we don't save/restore
2564 at least three registers. For non-leaf functions we also have the
2565 blink restore. */
2566 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2568 frame->millicode_start_reg = 13;
2569 frame->millicode_end_reg = regno - 1;
2570 return 1;
2572 return 0;
2575 /* Return the bytes needed to compute the frame pointer from the current
2576 stack pointer.
2578 SIZE is the size needed for local variables. */
2580 unsigned int
2581 arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */
2583 int regno;
2584 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2585 unsigned int reg_size, reg_offset;
2586 unsigned int gmask;
2587 struct arc_frame_info *frame_info = &cfun->machine->frame_info;
2589 size = ARC_STACK_ALIGN (size);
2591 /* 1) Size of locals and temporaries */
2592 var_size = size;
2594 /* 2) Size of outgoing arguments */
2595 args_size = crtl->outgoing_args_size;
2597 /* 3) Calculate space needed for saved registers.
2598 ??? We ignore the extension registers for now. */
2600 /* See if this is an interrupt handler. Call used registers must be saved
2601 for them too. */
2603 reg_size = 0;
2604 gmask = 0;
2606 for (regno = 0; regno <= 31; regno++)
2608 if (arc_must_save_register (regno, cfun))
2610 reg_size += UNITS_PER_WORD;
2611 gmask |= 1L << regno;
2615 /* 4) Space for back trace data structure.
2616 <return addr reg size> (if required) + <fp size> (if required). */
2617 frame_info->save_return_addr
2618 = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM));
2619 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2620 if (optimize_size && !TARGET_NO_MILLICODE_THUNK_SET)
2622 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2623 frame_info->save_return_addr = true;
2626 extra_size = 0;
2627 if (arc_must_save_return_addr (cfun))
2628 extra_size = 4;
2629 if (arc_frame_pointer_needed ())
2630 extra_size += 4;
2632 /* 5) Space for variable arguments passed in registers */
2633 pretend_size = crtl->args.pretend_args_size;
2635 /* Ensure everything before the locals is aligned appropriately. */
2637 unsigned int extra_plus_reg_size;
2638 unsigned int extra_plus_reg_size_aligned;
2640 extra_plus_reg_size = extra_size + reg_size;
2641 extra_plus_reg_size_aligned = ARC_STACK_ALIGN(extra_plus_reg_size);
2642 reg_size = extra_plus_reg_size_aligned - extra_size;
2645 /* Compute total frame size. */
2646 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2648 total_size = ARC_STACK_ALIGN (total_size);
2650 /* Compute offset of register save area from stack pointer:
2651 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2653 reg_offset = (total_size - (pretend_size + reg_size + extra_size)
2654 + (arc_frame_pointer_needed () ? 4 : 0));
2656 /* Save computed information. */
2657 frame_info->total_size = total_size;
2658 frame_info->extra_size = extra_size;
2659 frame_info->pretend_size = pretend_size;
2660 frame_info->var_size = var_size;
2661 frame_info->args_size = args_size;
2662 frame_info->reg_size = reg_size;
2663 frame_info->reg_offset = reg_offset;
2664 frame_info->gmask = gmask;
2665 frame_info->initialized = reload_completed;
2667 /* Ok, we're done. */
2668 return total_size;
2671 /* Common code to save/restore registers. */
2672 /* BASE_REG is the base register to use for addressing and to adjust.
2673 GMASK is a bitmask of general purpose registers to save/restore.
2674 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2675 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2676 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2677 zeroed. */
2679 static void
2680 arc_save_restore (rtx base_reg,
2681 unsigned int gmask, int epilogue_p, int *first_offset)
2683 unsigned int offset = 0;
2684 int regno;
2685 struct arc_frame_info *frame = &cfun->machine->frame_info;
2686 rtx sibthunk_insn = NULL_RTX;
2688 if (gmask)
2690 /* Millicode thunks implementation:
2691 Generates calls to millicodes for registers starting from r13 to r25
2692 Present Limitations:
2693 - Only one range supported. The remaining regs will have the ordinary
2694 st and ld instructions for store and loads. Hence a gmask asking
2695 to store r13-14, r16-r25 will only generate calls to store and
2696 load r13 to r14 while store and load insns will be generated for
2697 r16 to r25 in the prologue and epilogue respectively.
2699 - Presently library only supports register ranges starting from r13.
2701 if (epilogue_p == 2 || frame->millicode_end_reg > 14)
2703 int start_call = frame->millicode_start_reg;
2704 int end_call = frame->millicode_end_reg;
2705 int n_regs = end_call - start_call + 1;
2706 int i = 0, r, off = 0;
2707 rtx insn;
2708 rtx ret_addr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
2710 if (*first_offset)
2712 /* "reg_size" won't be more than 127 . */
2713 gcc_assert (epilogue_p || abs (*first_offset) <= 127);
2714 frame_add (base_reg, *first_offset);
2715 *first_offset = 0;
2717 insn = gen_rtx_PARALLEL
2718 (VOIDmode, rtvec_alloc ((epilogue_p == 2) + n_regs + 1));
2719 if (epilogue_p == 2)
2720 i += 2;
2721 else
2722 XVECEXP (insn, 0, n_regs) = gen_rtx_CLOBBER (VOIDmode, ret_addr);
2723 for (r = start_call; r <= end_call; r++, off += UNITS_PER_WORD, i++)
2725 rtx reg = gen_rtx_REG (SImode, r);
2726 rtx mem
2727 = gen_frame_mem (SImode, plus_constant (Pmode, base_reg, off));
2729 if (epilogue_p)
2730 XVECEXP (insn, 0, i) = gen_rtx_SET (reg, mem);
2731 else
2732 XVECEXP (insn, 0, i) = gen_rtx_SET (mem, reg);
2733 gmask = gmask & ~(1L << r);
2735 if (epilogue_p == 2)
2736 sibthunk_insn = insn;
2737 else
2739 insn = frame_insn (insn);
2740 if (epilogue_p)
2741 for (r = start_call; r <= end_call; r++)
2743 rtx reg = gen_rtx_REG (SImode, r);
2744 add_reg_note (insn, REG_CFA_RESTORE, reg);
2747 offset += off;
2750 for (regno = 0; regno <= 31; regno++)
2752 machine_mode mode = SImode;
2753 bool found = false;
2755 if (TARGET_LL64
2756 && (regno % 2 == 0)
2757 && ((gmask & (1L << regno)) != 0)
2758 && ((gmask & (1L << (regno+1))) != 0))
2760 found = true;
2761 mode = DImode;
2763 else if ((gmask & (1L << regno)) != 0)
2765 found = true;
2766 mode = SImode;
2769 if (found)
2771 rtx reg = gen_rtx_REG (mode, regno);
2772 rtx addr, mem;
2773 int cfa_adjust = *first_offset;
2775 if (*first_offset)
2777 gcc_assert (!offset);
2778 addr = plus_constant (Pmode, base_reg, *first_offset);
2779 addr = gen_rtx_PRE_MODIFY (Pmode, base_reg, addr);
2780 *first_offset = 0;
2782 else
2784 gcc_assert (SMALL_INT (offset));
2785 addr = plus_constant (Pmode, base_reg, offset);
2787 mem = gen_frame_mem (mode, addr);
2788 if (epilogue_p)
2790 rtx insn =
2791 frame_move_inc (reg, mem, base_reg, addr);
2792 add_reg_note (insn, REG_CFA_RESTORE, reg);
2793 if (cfa_adjust)
2795 enum reg_note note = REG_CFA_ADJUST_CFA;
2796 add_reg_note (insn, note,
2797 gen_rtx_SET (stack_pointer_rtx,
2798 plus_constant (Pmode,
2799 stack_pointer_rtx,
2800 cfa_adjust)));
2803 else
2804 frame_move_inc (mem, reg, base_reg, addr);
2805 offset += UNITS_PER_WORD;
2806 if (mode == DImode)
2808 offset += UNITS_PER_WORD;
2809 ++regno;
2811 } /* if */
2812 } /* for */
2813 }/* if */
2814 if (sibthunk_insn)
2816 int start_call = frame->millicode_start_reg;
2817 int end_call = frame->millicode_end_reg;
2818 int r;
2820 rtx r12 = gen_rtx_REG (Pmode, 12);
2822 frame_insn (gen_rtx_SET (r12, GEN_INT (offset)));
2823 XVECEXP (sibthunk_insn, 0, 0) = ret_rtx;
2824 XVECEXP (sibthunk_insn, 0, 1)
2825 = gen_rtx_SET (stack_pointer_rtx,
2826 gen_rtx_PLUS (Pmode, stack_pointer_rtx, r12));
2827 sibthunk_insn = emit_jump_insn (sibthunk_insn);
2828 RTX_FRAME_RELATED_P (sibthunk_insn) = 1;
2830 /* Would be nice if we could do this earlier, when the PARALLEL
2831 is populated, but these need to be attached after the
2832 emit. */
2833 for (r = start_call; r <= end_call; r++)
2835 rtx reg = gen_rtx_REG (SImode, r);
2836 add_reg_note (sibthunk_insn, REG_CFA_RESTORE, reg);
2839 } /* arc_save_restore */
2841 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2842 mechanism. */
2844 static void
2845 arc_dwarf_emit_irq_save_regs (void)
2847 rtx tmp, par, insn, reg;
2848 int i, offset, j;
2850 par = gen_rtx_SEQUENCE (VOIDmode,
2851 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
2852 + irq_ctrl_saved.irq_save_blink
2853 + irq_ctrl_saved.irq_save_lpcount
2854 + 1));
2856 /* Build the stack adjustment note for unwind info. */
2857 j = 0;
2858 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
2859 + irq_ctrl_saved.irq_save_blink
2860 + irq_ctrl_saved.irq_save_lpcount);
2861 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
2862 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
2863 RTX_FRAME_RELATED_P (tmp) = 1;
2864 XVECEXP (par, 0, j++) = tmp;
2866 offset -= UNITS_PER_WORD;
2868 /* 1st goes LP_COUNT. */
2869 if (irq_ctrl_saved.irq_save_lpcount)
2871 reg = gen_rtx_REG (SImode, 60);
2872 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2873 tmp = gen_frame_mem (SImode, tmp);
2874 tmp = gen_rtx_SET (tmp, reg);
2875 RTX_FRAME_RELATED_P (tmp) = 1;
2876 XVECEXP (par, 0, j++) = tmp;
2877 offset -= UNITS_PER_WORD;
2880 /* 2nd goes BLINK. */
2881 if (irq_ctrl_saved.irq_save_blink)
2883 reg = gen_rtx_REG (SImode, 31);
2884 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2885 tmp = gen_frame_mem (SImode, tmp);
2886 tmp = gen_rtx_SET (tmp, reg);
2887 RTX_FRAME_RELATED_P (tmp) = 1;
2888 XVECEXP (par, 0, j++) = tmp;
2889 offset -= UNITS_PER_WORD;
2892 /* Build the parallel of the remaining registers recorded as saved
2893 for unwind. */
2894 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
2896 reg = gen_rtx_REG (SImode, i);
2897 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2898 tmp = gen_frame_mem (SImode, tmp);
2899 tmp = gen_rtx_SET (tmp, reg);
2900 RTX_FRAME_RELATED_P (tmp) = 1;
2901 XVECEXP (par, 0, j++) = tmp;
2902 offset -= UNITS_PER_WORD;
2905 /* Dummy insn used to anchor the dwarf info. */
2906 insn = emit_insn (gen_stack_irq_dwarf());
2907 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
2908 RTX_FRAME_RELATED_P (insn) = 1;
2911 /* Set up the stack and frame pointer (if desired) for the function. */
2913 void
2914 arc_expand_prologue (void)
2916 int size = get_frame_size ();
2917 unsigned int gmask = cfun->machine->frame_info.gmask;
2918 /* unsigned int frame_pointer_offset;*/
2919 unsigned int frame_size_to_allocate;
2920 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2921 Change the stack layout so that we rather store a high register with the
2922 PRE_MODIFY, thus enabling more short insn generation.) */
2923 int first_offset = 0;
2924 unsigned int fn_type = arc_compute_function_type (cfun);
2926 /* Naked functions don't have prologue. */
2927 if (ARC_NAKED_P (fn_type))
2928 return;
2930 size = ARC_STACK_ALIGN (size);
2932 /* Compute/get total frame size. */
2933 size = (!cfun->machine->frame_info.initialized
2934 ? arc_compute_frame_size (size)
2935 : cfun->machine->frame_info.total_size);
2937 if (flag_stack_usage_info)
2938 current_function_static_stack_size = size;
2940 /* Keep track of frame size to be allocated. */
2941 frame_size_to_allocate = size;
2943 /* These cases shouldn't happen. Catch them now. */
2944 gcc_assert (!(size == 0 && gmask));
2946 /* Allocate space for register arguments if this is a variadic function. */
2947 if (cfun->machine->frame_info.pretend_size != 0)
2949 /* Ensure pretend_size is maximum of 8 * word_size. */
2950 gcc_assert (cfun->machine->frame_info.pretend_size <= 32);
2952 frame_stack_add (-(HOST_WIDE_INT)cfun->machine->frame_info.pretend_size);
2953 frame_size_to_allocate -= cfun->machine->frame_info.pretend_size;
2956 /* IRQ using automatic save mechanism will save the register before
2957 anything we do. */
2958 if (ARC_AUTO_IRQ_P (fn_type)
2959 && !ARC_FAST_INTERRUPT_P (fn_type))
2961 arc_dwarf_emit_irq_save_regs ();
2964 /* The home-grown ABI says link register is saved first. */
2965 if (arc_must_save_return_addr (cfun)
2966 && !ARC_AUTOBLINK_IRQ_P (fn_type))
2968 rtx ra = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
2969 rtx mem = gen_frame_mem (Pmode,
2970 gen_rtx_PRE_DEC (Pmode,
2971 stack_pointer_rtx));
2973 frame_move_inc (mem, ra, stack_pointer_rtx, 0);
2974 frame_size_to_allocate -= UNITS_PER_WORD;
2977 /* Save any needed call-saved regs (and call-used if this is an
2978 interrupt handler) for ARCompact ISA. */
2979 if (cfun->machine->frame_info.reg_size)
2981 first_offset = -cfun->machine->frame_info.reg_size;
2982 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
2983 arc_save_restore (stack_pointer_rtx, gmask, 0, &first_offset);
2984 frame_size_to_allocate -= cfun->machine->frame_info.reg_size;
2987 /* Save frame pointer if needed. First save the FP on stack, if not
2988 autosaved. */
2989 if (arc_frame_pointer_needed ()
2990 && !ARC_AUTOFP_IRQ_P (fn_type))
2992 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
2993 GEN_INT (-UNITS_PER_WORD + first_offset));
2994 rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_MODIFY (Pmode,
2995 stack_pointer_rtx,
2996 addr));
2997 frame_move_inc (mem, frame_pointer_rtx, stack_pointer_rtx, 0);
2998 frame_size_to_allocate -= UNITS_PER_WORD;
2999 first_offset = 0;
3002 /* Emit mov fp,sp. */
3003 if (arc_frame_pointer_needed ())
3005 frame_move (frame_pointer_rtx, stack_pointer_rtx);
3008 /* ??? We don't handle the case where the saved regs are more than 252
3009 bytes away from sp. This can be handled by decrementing sp once, saving
3010 the regs, and then decrementing it again. The epilogue doesn't have this
3011 problem as the `ld' insn takes reg+limm values (though it would be more
3012 efficient to avoid reg+limm). */
3014 frame_size_to_allocate -= first_offset;
3015 /* Allocate the stack frame. */
3016 if (frame_size_to_allocate > 0)
3018 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3019 /* If the frame pointer is needed, emit a special barrier that
3020 will prevent the scheduler from moving stores to the frame
3021 before the stack adjustment. */
3022 if (arc_frame_pointer_needed ())
3023 emit_insn (gen_stack_tie (stack_pointer_rtx,
3024 hard_frame_pointer_rtx));
3027 /* Setup the gp register, if needed. */
3028 if (crtl->uses_pic_offset_table)
3029 arc_finalize_pic ();
3032 /* Do any necessary cleanup after a function to restore stack, frame,
3033 and regs. */
3035 void
3036 arc_expand_epilogue (int sibcall_p)
3038 int size = get_frame_size ();
3039 unsigned int fn_type = arc_compute_function_type (cfun);
3041 size = ARC_STACK_ALIGN (size);
3042 size = (!cfun->machine->frame_info.initialized
3043 ? arc_compute_frame_size (size)
3044 : cfun->machine->frame_info.total_size);
3046 unsigned int pretend_size = cfun->machine->frame_info.pretend_size;
3047 unsigned int frame_size;
3048 unsigned int size_to_deallocate;
3049 int restored;
3050 int can_trust_sp_p = !cfun->calls_alloca;
3051 int first_offset = 0;
3052 int millicode_p = cfun->machine->frame_info.millicode_end_reg > 0;
3053 rtx insn;
3055 /* Naked functions don't have epilogue. */
3056 if (ARC_NAKED_P (fn_type))
3057 return;
3059 size_to_deallocate = size;
3061 frame_size = size - (pretend_size +
3062 cfun->machine->frame_info.reg_size +
3063 cfun->machine->frame_info.extra_size);
3065 /* ??? There are lots of optimizations that can be done here.
3066 EG: Use fp to restore regs if it's closer.
3067 Maybe in time we'll do them all. For now, always restore regs from
3068 sp, but don't restore sp if we don't have to. */
3070 if (!can_trust_sp_p)
3071 gcc_assert (arc_frame_pointer_needed ());
3073 /* Restore stack pointer to the beginning of saved register area for
3074 ARCompact ISA. */
3075 if (frame_size)
3077 if (arc_frame_pointer_needed ())
3078 frame_move (stack_pointer_rtx, frame_pointer_rtx);
3079 else
3080 first_offset = frame_size;
3081 size_to_deallocate -= frame_size;
3083 else if (!can_trust_sp_p)
3084 frame_stack_add (-frame_size);
3087 /* Restore any saved registers. */
3088 if (arc_frame_pointer_needed ()
3089 && !ARC_AUTOFP_IRQ_P (fn_type))
3091 rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
3093 insn = frame_move_inc (frame_pointer_rtx, gen_frame_mem (Pmode, addr),
3094 stack_pointer_rtx, 0);
3095 add_reg_note (insn, REG_CFA_RESTORE, frame_pointer_rtx);
3096 add_reg_note (insn, REG_CFA_DEF_CFA,
3097 plus_constant (SImode, stack_pointer_rtx,
3098 4));
3099 size_to_deallocate -= UNITS_PER_WORD;
3102 /* Load blink after the calls to thunk calls in case of optimize size. */
3103 if (millicode_p)
3105 int sibthunk_p = (!sibcall_p
3106 && fn_type == ARC_FUNCTION_NORMAL
3107 && !cfun->machine->frame_info.pretend_size);
3109 gcc_assert (!(cfun->machine->frame_info.gmask
3110 & (FRAME_POINTER_MASK | RETURN_ADDR_MASK)));
3111 arc_save_restore (stack_pointer_rtx,
3112 cfun->machine->frame_info.gmask,
3113 1 + sibthunk_p, &first_offset);
3114 if (sibthunk_p)
3115 return;
3117 /* If we are to restore registers, and first_offset would require
3118 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3119 fast add to the stack pointer, do this now. */
3120 if ((!SMALL_INT (first_offset)
3121 && cfun->machine->frame_info.gmask
3122 && ((TARGET_ARC700 && !optimize_size)
3123 ? first_offset <= 0x800
3124 : satisfies_constraint_C2a (GEN_INT (first_offset))))
3125 /* Also do this if we have both gprs and return
3126 address to restore, and they both would need a LIMM. */
3127 || (arc_must_save_return_addr (cfun)
3128 && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2)
3129 && cfun->machine->frame_info.gmask))
3131 frame_stack_add (first_offset);
3132 first_offset = 0;
3134 if (arc_must_save_return_addr (cfun)
3135 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3137 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3138 int ra_offs = cfun->machine->frame_info.reg_size + first_offset;
3139 rtx addr = plus_constant (Pmode, stack_pointer_rtx, ra_offs);
3140 HOST_WIDE_INT cfa_adjust = 0;
3142 /* If the load of blink would need a LIMM, but we can add
3143 the offset quickly to sp, do the latter. */
3144 if (!SMALL_INT (ra_offs >> 2)
3145 && !cfun->machine->frame_info.gmask
3146 && ((TARGET_ARC700 && !optimize_size)
3147 ? ra_offs <= 0x800
3148 : satisfies_constraint_C2a (GEN_INT (ra_offs))))
3150 size_to_deallocate -= ra_offs - first_offset;
3151 first_offset = 0;
3152 frame_stack_add (ra_offs);
3153 ra_offs = 0;
3154 addr = stack_pointer_rtx;
3156 /* See if we can combine the load of the return address with the
3157 final stack adjustment.
3158 We need a separate load if there are still registers to
3159 restore. We also want a separate load if the combined insn
3160 would need a limm, but a separate load doesn't. */
3161 if (ra_offs
3162 && !cfun->machine->frame_info.gmask
3163 && (SMALL_INT (ra_offs) || !SMALL_INT (ra_offs >> 2)))
3165 addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, addr);
3166 cfa_adjust = ra_offs;
3167 first_offset = 0;
3168 size_to_deallocate -= cfun->machine->frame_info.reg_size;
3170 else if (!ra_offs && size_to_deallocate == UNITS_PER_WORD)
3172 addr = gen_rtx_POST_INC (Pmode, addr);
3173 cfa_adjust = GET_MODE_SIZE (Pmode);
3174 size_to_deallocate = 0;
3177 insn = frame_move_inc (ra, gen_frame_mem (Pmode, addr),
3178 stack_pointer_rtx, addr);
3179 if (cfa_adjust)
3181 enum reg_note note = REG_CFA_ADJUST_CFA;
3183 add_reg_note (insn, note,
3184 gen_rtx_SET (stack_pointer_rtx,
3185 plus_constant (SImode, stack_pointer_rtx,
3186 cfa_adjust)));
3188 add_reg_note (insn, REG_CFA_RESTORE, ra);
3191 if (!millicode_p)
3193 if (cfun->machine->frame_info.reg_size)
3194 arc_save_restore (stack_pointer_rtx,
3195 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3196 cfun->machine->frame_info.gmask
3197 & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 1, &first_offset);
3200 /* The rest of this function does the following:
3201 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3204 /* Keep track of how much of the stack pointer we've restored.
3205 It makes the following a lot more readable. */
3206 size_to_deallocate += first_offset;
3207 restored = size - size_to_deallocate;
3209 if (size > restored)
3210 frame_stack_add (size - restored);
3212 /* Emit the return instruction. */
3213 if (sibcall_p == FALSE)
3214 emit_jump_insn (gen_simple_return ());
3217 /* Return the offset relative to the stack pointer where the return address
3218 is stored, or -1 if it is not stored. */
3221 arc_return_slot_offset ()
3223 struct arc_frame_info *afi = &cfun->machine->frame_info;
3225 return (afi->save_return_addr
3226 ? afi->total_size - afi->pretend_size - afi->extra_size : -1);
3229 /* PIC */
3231 /* Helper to generate unspec constant. */
3233 static rtx
3234 arc_unspec_offset (rtx loc, int unspec)
3236 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
3237 unspec));
3240 /* Emit special PIC prologues and epilogues. */
3241 /* If the function has any GOTOFF relocations, then the GOTBASE
3242 register has to be setup in the prologue
3243 The instruction needed at the function start for setting up the
3244 GOTBASE register is
3245 add rdest, pc,
3246 ----------------------------------------------------------
3247 The rtl to be emitted for this should be:
3248 set (reg basereg)
3249 (plus (reg pc)
3250 (const (unspec (symref _DYNAMIC) 3)))
3251 ---------------------------------------------------------- */
3253 static void
3254 arc_finalize_pic (void)
3256 rtx pat;
3257 rtx baseptr_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
3259 if (crtl->uses_pic_offset_table == 0)
3260 return;
3262 gcc_assert (flag_pic != 0);
3264 pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC");
3265 pat = arc_unspec_offset (pat, ARC_UNSPEC_GOT);
3266 pat = gen_rtx_SET (baseptr_rtx, pat);
3268 emit_insn (pat);
3271 /* !TARGET_BARREL_SHIFTER support. */
3272 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3273 kind of shift. */
3275 void
3276 emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
3278 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
3279 rtx pat
3280 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop)
3281 (op0, op1, op2, shift));
3282 emit_insn (pat);
3285 /* Output the assembler code for doing a shift.
3286 We go to a bit of trouble to generate efficient code as the ARC601 only has
3287 single bit shifts. This is taken from the h8300 port. We only have one
3288 mode of shifting and can't access individual bytes like the h8300 can, so
3289 this is greatly simplified (at the expense of not generating hyper-
3290 efficient code).
3292 This function is not used if the variable shift insns are present. */
3294 /* FIXME: This probably can be done using a define_split in arc.md.
3295 Alternately, generate rtx rather than output instructions. */
3297 const char *
3298 output_shift (rtx *operands)
3300 /* static int loopend_lab;*/
3301 rtx shift = operands[3];
3302 machine_mode mode = GET_MODE (shift);
3303 enum rtx_code code = GET_CODE (shift);
3304 const char *shift_one;
3306 gcc_assert (mode == SImode);
3308 switch (code)
3310 case ASHIFT: shift_one = "add %0,%1,%1"; break;
3311 case ASHIFTRT: shift_one = "asr %0,%1"; break;
3312 case LSHIFTRT: shift_one = "lsr %0,%1"; break;
3313 default: gcc_unreachable ();
3316 if (GET_CODE (operands[2]) != CONST_INT)
3318 output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
3319 goto shiftloop;
3321 else
3323 int n;
3325 n = INTVAL (operands[2]);
3327 /* Only consider the lower 5 bits of the shift count. */
3328 n = n & 0x1f;
3330 /* First see if we can do them inline. */
3331 /* ??? We could get better scheduling & shorter code (using short insns)
3332 by using splitters. Alas, that'd be even more verbose. */
3333 if (code == ASHIFT && n <= 9 && n > 2
3334 && dest_reg_operand (operands[4], SImode))
3336 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
3337 for (n -=3 ; n >= 3; n -= 3)
3338 output_asm_insn ("add3 %0,%4,%0", operands);
3339 if (n == 2)
3340 output_asm_insn ("add2 %0,%4,%0", operands);
3341 else if (n)
3342 output_asm_insn ("add %0,%0,%0", operands);
3344 else if (n <= 4)
3346 while (--n >= 0)
3348 output_asm_insn (shift_one, operands);
3349 operands[1] = operands[0];
3352 /* See if we can use a rotate/and. */
3353 else if (n == BITS_PER_WORD - 1)
3355 switch (code)
3357 case ASHIFT :
3358 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
3359 break;
3360 case ASHIFTRT :
3361 /* The ARC doesn't have a rol insn. Use something else. */
3362 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
3363 break;
3364 case LSHIFTRT :
3365 /* The ARC doesn't have a rol insn. Use something else. */
3366 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
3367 break;
3368 default:
3369 break;
3372 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
3374 switch (code)
3376 case ASHIFT :
3377 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
3378 break;
3379 case ASHIFTRT :
3380 #if 1 /* Need some scheduling comparisons. */
3381 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3382 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3383 #else
3384 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3385 "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
3386 #endif
3387 break;
3388 case LSHIFTRT :
3389 #if 1
3390 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3391 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3392 #else
3393 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3394 "and %0,%0,1\n\trlc %0,%0", operands);
3395 #endif
3396 break;
3397 default:
3398 break;
3401 else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
3402 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3403 operands);
3404 /* Must loop. */
3405 else
3407 operands[2] = GEN_INT (n);
3408 output_asm_insn ("mov.f lp_count, %2", operands);
3410 shiftloop:
3412 output_asm_insn ("lpnz\t2f", operands);
3413 output_asm_insn (shift_one, operands);
3414 output_asm_insn ("nop", operands);
3415 fprintf (asm_out_file, "2:\t%s end single insn loop\n",
3416 ASM_COMMENT_START);
3421 return "";
3424 /* Nested function support. */
3426 /* Directly store VALUE into memory object BLOCK at OFFSET. */
3428 static void
3429 emit_store_direct (rtx block, int offset, int value)
3431 emit_insn (gen_store_direct (adjust_address (block, SImode, offset),
3432 force_reg (SImode,
3433 gen_int_mode (value, SImode))));
3436 /* Emit RTL insns to initialize the variable parts of a trampoline.
3437 FNADDR is an RTX for the address of the function's pure code.
3438 CXT is an RTX for the static chain value for the function. */
3439 /* With potentially multiple shared objects loaded, and multiple stacks
3440 present for multiple thereds where trampolines might reside, a simple
3441 range check will likely not suffice for the profiler to tell if a callee
3442 is a trampoline. We a speedier check by making the trampoline start at
3443 an address that is not 4-byte aligned.
3444 A trampoline looks like this:
3446 nop_s 0x78e0
3447 entry:
3448 ld_s r12,[pcl,12] 0xd403
3449 ld r11,[pcl,12] 0x170c 700b
3450 j_s [r12] 0x7c00
3451 nop_s 0x78e0
3453 The fastest trampoline to execute for trampolines within +-8KB of CTX
3454 would be:
3455 add2 r11,pcl,s12
3456 j [limm] 0x20200f80 limm
3457 and that would also be faster to write to the stack by computing the offset
3458 from CTX to TRAMP at compile time. However, it would really be better to
3459 get rid of the high cost of cache invalidation when generating trampolines,
3460 which requires that the code part of trampolines stays constant, and
3461 additionally either
3462 - making sure that no executable code but trampolines is on the stack,
3463 no icache entries linger for the area of the stack from when before the
3464 stack was allocated, and allocating trampolines in trampoline-only
3465 cache lines
3467 - allocate trampolines fram a special pool of pre-allocated trampolines. */
3469 static void
3470 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
3472 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3474 emit_store_direct (tramp, 0, TARGET_BIG_ENDIAN ? 0x78e0d403 : 0xd40378e0);
3475 emit_store_direct (tramp, 4, TARGET_BIG_ENDIAN ? 0x170c700b : 0x700b170c);
3476 emit_store_direct (tramp, 8, TARGET_BIG_ENDIAN ? 0x7c0078e0 : 0x78e07c00);
3477 emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
3478 emit_move_insn (adjust_address (tramp, SImode, 16), cxt);
3479 emit_insn (gen_flush_icache (adjust_address (tramp, SImode, 0)));
3482 /* Allow the profiler to easily distinguish trampolines from normal
3483 functions. */
3485 static rtx
3486 arc_trampoline_adjust_address (rtx addr)
3488 return plus_constant (Pmode, addr, 2);
3491 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3492 reset when we output the scaled address. */
3493 static int output_scaled = 0;
3495 /* Print operand X (an rtx) in assembler syntax to file FILE.
3496 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3497 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3498 /* In final.c:output_asm_insn:
3499 'l' : label
3500 'a' : address
3501 'c' : constant address if CONSTANT_ADDRESS_P
3502 'n' : negative
3503 Here:
3504 'Z': log2(x+1)-1
3505 'z': log2
3506 'M': log2(~x)
3507 'p': bit Position of lsb
3508 's': size of bit field
3509 '#': condbranch delay slot suffix
3510 '*': jump delay slot suffix
3511 '?' : nonjump-insn suffix for conditional execution or short instruction
3512 '!' : jump / call suffix for conditional execution or short instruction
3513 '`': fold constant inside unary o-perator, re-recognize, and emit.
3516 'R': Second word
3518 'B': Branch comparison operand - suppress sda reference
3519 'H': Most significant word
3520 'L': Least significant word
3521 'A': ASCII decimal representation of floating point value
3522 'U': Load/store update or scaling indicator
3523 'V': cache bypass indicator for volatile
3527 'O': Operator
3528 'o': original symbol - no @ prepending. */
3530 void
3531 arc_print_operand (FILE *file, rtx x, int code)
3533 switch (code)
3535 case 'Z':
3536 if (GET_CODE (x) == CONST_INT)
3537 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
3538 else
3539 output_operand_lossage ("invalid operand to %%Z code");
3541 return;
3543 case 'z':
3544 if (GET_CODE (x) == CONST_INT)
3545 fprintf (file, "%d",exact_log2(INTVAL (x)) );
3546 else
3547 output_operand_lossage ("invalid operand to %%z code");
3549 return;
3551 case 'c':
3552 if (GET_CODE (x) == CONST_INT)
3553 fprintf (file, "%d", INTVAL (x) );
3554 else
3555 output_operand_lossage ("invalid operands to %%c code");
3557 return;
3559 case 'M':
3560 if (GET_CODE (x) == CONST_INT)
3561 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
3562 else
3563 output_operand_lossage ("invalid operand to %%M code");
3565 return;
3567 case 'p':
3568 if (GET_CODE (x) == CONST_INT)
3569 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
3570 else
3571 output_operand_lossage ("invalid operand to %%p code");
3572 return;
3574 case 's':
3575 if (GET_CODE (x) == CONST_INT)
3577 HOST_WIDE_INT i = INTVAL (x);
3578 HOST_WIDE_INT s = exact_log2 (i & -i);
3579 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
3581 else
3582 output_operand_lossage ("invalid operand to %%s code");
3583 return;
3585 case '#' :
3586 /* Conditional branches depending on condition codes.
3587 Note that this is only for branches that were known to depend on
3588 condition codes before delay slot scheduling;
3589 out-of-range brcc / bbit expansions should use '*'.
3590 This distinction is important because of the different
3591 allowable delay slot insns and the output of the delay suffix
3592 for TARGET_AT_DBR_COND_EXEC. */
3593 case '*' :
3594 /* Unconditional branches / branches not depending on condition codes.
3595 This could also be a CALL_INSN.
3596 Output the appropriate delay slot suffix. */
3597 if (final_sequence && final_sequence->len () != 1)
3599 rtx_insn *jump = final_sequence->insn (0);
3600 rtx_insn *delay = final_sequence->insn (1);
3602 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3603 if (delay->deleted ())
3604 return;
3605 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3606 fputs (INSN_FROM_TARGET_P (delay) ? ".d"
3607 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d"
3608 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? ""
3609 : ".nd",
3610 file);
3611 else
3612 fputs (".d", file);
3614 return;
3615 case '?' : /* with leading "." */
3616 case '!' : /* without leading "." */
3617 /* This insn can be conditionally executed. See if the ccfsm machinery
3618 says it should be conditionalized.
3619 If it shouldn't, we'll check the compact attribute if this insn
3620 has a short variant, which may be used depending on code size and
3621 alignment considerations. */
3622 if (current_insn_predicate)
3623 arc_ccfsm_current.cc
3624 = get_arc_condition_code (current_insn_predicate);
3625 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current))
3627 /* Is this insn in a delay slot sequence? */
3628 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
3629 || current_insn_predicate
3630 || CALL_P (final_sequence->insn (0))
3631 || simplejump_p (final_sequence->insn (0)))
3633 /* This insn isn't in a delay slot sequence, or conditionalized
3634 independently of its position in a delay slot. */
3635 fprintf (file, "%s%s",
3636 code == '?' ? "." : "",
3637 arc_condition_codes[arc_ccfsm_current.cc]);
3638 /* If this is a jump, there are still short variants. However,
3639 only beq_s / bne_s have the same offset range as b_s,
3640 and the only short conditional returns are jeq_s and jne_s. */
3641 if (code == '!'
3642 && (arc_ccfsm_current.cc == ARC_CC_EQ
3643 || arc_ccfsm_current.cc == ARC_CC_NE
3644 || 0 /* FIXME: check if branch in 7 bit range. */))
3645 output_short_suffix (file);
3647 else if (code == '!') /* Jump with delay slot. */
3648 fputs (arc_condition_codes[arc_ccfsm_current.cc], file);
3649 else /* An Instruction in a delay slot of a jump or call. */
3651 rtx jump = XVECEXP (final_sequence, 0, 0);
3652 rtx insn = XVECEXP (final_sequence, 0, 1);
3654 /* If the insn is annulled and is from the target path, we need
3655 to inverse the condition test. */
3656 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3658 if (INSN_FROM_TARGET_P (insn))
3659 fprintf (file, "%s%s",
3660 code == '?' ? "." : "",
3661 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]);
3662 else
3663 fprintf (file, "%s%s",
3664 code == '?' ? "." : "",
3665 arc_condition_codes[arc_ccfsm_current.cc]);
3666 if (arc_ccfsm_current.state == 5)
3667 arc_ccfsm_current.state = 0;
3669 else
3670 /* This insn is executed for either path, so don't
3671 conditionalize it at all. */
3672 output_short_suffix (file);
3676 else
3677 output_short_suffix (file);
3678 return;
3679 case'`':
3680 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3681 gcc_unreachable ();
3682 case 'd' :
3683 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
3684 return;
3685 case 'D' :
3686 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
3687 (get_arc_condition_code (x))],
3688 file);
3689 return;
3690 case 'R' :
3691 /* Write second word of DImode or DFmode reference,
3692 register or memory. */
3693 if (GET_CODE (x) == REG)
3694 fputs (reg_names[REGNO (x)+1], file);
3695 else if (GET_CODE (x) == MEM)
3697 fputc ('[', file);
3699 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3700 PRE_MODIFY, we will have handled the first word already;
3701 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3702 first word will be done later. In either case, the access
3703 to the first word will do the modify, and we only have
3704 to add an offset of four here. */
3705 if (GET_CODE (XEXP (x, 0)) == PRE_INC
3706 || GET_CODE (XEXP (x, 0)) == PRE_DEC
3707 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
3708 || GET_CODE (XEXP (x, 0)) == POST_INC
3709 || GET_CODE (XEXP (x, 0)) == POST_DEC
3710 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
3711 output_address (VOIDmode,
3712 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
3713 else if (output_scaled)
3715 rtx addr = XEXP (x, 0);
3716 int size = GET_MODE_SIZE (GET_MODE (x));
3718 output_address (VOIDmode,
3719 plus_constant (Pmode, XEXP (addr, 0),
3720 ((INTVAL (XEXP (addr, 1)) + 4)
3721 >> (size == 2 ? 1 : 2))));
3722 output_scaled = 0;
3724 else
3725 output_address (VOIDmode,
3726 plus_constant (Pmode, XEXP (x, 0), 4));
3727 fputc (']', file);
3729 else
3730 output_operand_lossage ("invalid operand to %%R code");
3731 return;
3732 case 'S' :
3733 /* FIXME: remove %S option. */
3734 break;
3735 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3736 if (CONSTANT_P (x))
3738 output_addr_const (file, x);
3739 return;
3741 break;
3742 case 'H' :
3743 case 'L' :
3744 if (GET_CODE (x) == REG)
3746 /* L = least significant word, H = most significant word. */
3747 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
3748 fputs (reg_names[REGNO (x)], file);
3749 else
3750 fputs (reg_names[REGNO (x)+1], file);
3752 else if (GET_CODE (x) == CONST_INT
3753 || GET_CODE (x) == CONST_DOUBLE)
3755 rtx first, second, word;
3757 split_double (x, &first, &second);
3759 if((WORDS_BIG_ENDIAN) == 0)
3760 word = (code == 'L' ? first : second);
3761 else
3762 word = (code == 'L' ? second : first);
3764 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
3766 else
3767 output_operand_lossage ("invalid operand to %%H/%%L code");
3768 return;
3769 case 'A' :
3771 char str[30];
3773 gcc_assert (GET_CODE (x) == CONST_DOUBLE
3774 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
3776 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
3777 fprintf (file, "%s", str);
3778 return;
3780 case 'U' :
3781 /* Output a load/store with update indicator if appropriate. */
3782 if (GET_CODE (x) == MEM)
3784 rtx addr = XEXP (x, 0);
3785 switch (GET_CODE (addr))
3787 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
3788 fputs (".a", file); break;
3789 case POST_INC: case POST_DEC: case POST_MODIFY:
3790 fputs (".ab", file); break;
3791 case PLUS:
3792 /* Are we using a scaled index? */
3793 if (GET_CODE (XEXP (addr, 0)) == MULT)
3794 fputs (".as", file);
3795 /* Can we use a scaled offset? */
3796 else if (CONST_INT_P (XEXP (addr, 1))
3797 && GET_MODE_SIZE (GET_MODE (x)) > 1
3798 && (!(INTVAL (XEXP (addr, 1))
3799 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
3800 /* Does it make a difference? */
3801 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
3802 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
3804 fputs (".as", file);
3805 output_scaled = 1;
3807 break;
3808 case REG:
3809 break;
3810 default:
3811 gcc_assert (CONSTANT_P (addr)); break;
3814 else
3815 output_operand_lossage ("invalid operand to %%U code");
3816 return;
3817 case 'V' :
3818 /* Output cache bypass indicator for a load/store insn. Volatile memory
3819 refs are defined to use the cache bypass mechanism. */
3820 if (GET_CODE (x) == MEM)
3822 if (MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET )
3823 fputs (".di", file);
3825 else
3826 output_operand_lossage ("invalid operand to %%V code");
3827 return;
3828 /* plt code. */
3829 case 'P':
3830 case 0 :
3831 /* Do nothing special. */
3832 break;
3833 case 'F':
3834 fputs (reg_names[REGNO (x)]+1, file);
3835 return;
3836 case '^':
3837 /* This punctuation character is needed because label references are
3838 printed in the output template using %l. This is a front end
3839 character, and when we want to emit a '@' before it, we have to use
3840 this '^'. */
3842 fputc('@',file);
3843 return;
3844 case 'O':
3845 /* Output an operator. */
3846 switch (GET_CODE (x))
3848 case PLUS: fputs ("add", file); return;
3849 case SS_PLUS: fputs ("adds", file); return;
3850 case AND: fputs ("and", file); return;
3851 case IOR: fputs ("or", file); return;
3852 case XOR: fputs ("xor", file); return;
3853 case MINUS: fputs ("sub", file); return;
3854 case SS_MINUS: fputs ("subs", file); return;
3855 case ASHIFT: fputs ("asl", file); return;
3856 case ASHIFTRT: fputs ("asr", file); return;
3857 case LSHIFTRT: fputs ("lsr", file); return;
3858 case ROTATERT: fputs ("ror", file); return;
3859 case MULT: fputs ("mpy", file); return;
3860 case ABS: fputs ("abs", file); return; /* Unconditional. */
3861 case NEG: fputs ("neg", file); return;
3862 case SS_NEG: fputs ("negs", file); return;
3863 case NOT: fputs ("not", file); return; /* Unconditional. */
3864 case ZERO_EXTEND:
3865 fputs ("ext", file); /* bmsk allows predication. */
3866 goto size_suffix;
3867 case SIGN_EXTEND: /* Unconditional. */
3868 fputs ("sex", file);
3869 size_suffix:
3870 switch (GET_MODE (XEXP (x, 0)))
3872 case E_QImode: fputs ("b", file); return;
3873 case E_HImode: fputs ("w", file); return;
3874 default: break;
3876 break;
3877 case SS_TRUNCATE:
3878 if (GET_MODE (x) != HImode)
3879 break;
3880 fputs ("sat16", file);
3881 default: break;
3883 output_operand_lossage ("invalid operand to %%O code"); return;
3884 case 'o':
3885 if (GET_CODE (x) == SYMBOL_REF)
3887 assemble_name (file, XSTR (x, 0));
3888 return;
3890 break;
3891 case '&':
3892 if (TARGET_ANNOTATE_ALIGN && cfun->machine->size_reason)
3893 fprintf (file, "; unalign: %d", cfun->machine->unalign);
3894 return;
3895 case '+':
3896 if (TARGET_V2)
3897 fputs ("m", file);
3898 else
3899 fputs ("h", file);
3900 return;
3901 case '_':
3902 if (TARGET_V2)
3903 fputs ("h", file);
3904 else
3905 fputs ("w", file);
3906 return;
3907 default :
3908 /* Unknown flag. */
3909 output_operand_lossage ("invalid operand output code");
3912 switch (GET_CODE (x))
3914 case REG :
3915 fputs (reg_names[REGNO (x)], file);
3916 break;
3917 case MEM :
3919 rtx addr = XEXP (x, 0);
3920 int size = GET_MODE_SIZE (GET_MODE (x));
3922 fputc ('[', file);
3924 switch (GET_CODE (addr))
3926 case PRE_INC: case POST_INC:
3927 output_address (VOIDmode,
3928 plus_constant (Pmode, XEXP (addr, 0), size)); break;
3929 case PRE_DEC: case POST_DEC:
3930 output_address (VOIDmode,
3931 plus_constant (Pmode, XEXP (addr, 0), -size));
3932 break;
3933 case PRE_MODIFY: case POST_MODIFY:
3934 output_address (VOIDmode, XEXP (addr, 1)); break;
3935 case PLUS:
3936 if (output_scaled)
3938 output_address (VOIDmode,
3939 plus_constant (Pmode, XEXP (addr, 0),
3940 (INTVAL (XEXP (addr, 1))
3941 >> (size == 2 ? 1 : 2))));
3942 output_scaled = 0;
3944 else
3945 output_address (VOIDmode, addr);
3946 break;
3947 default:
3948 if (flag_pic && CONSTANT_ADDRESS_P (addr))
3949 arc_output_pic_addr_const (file, addr, code);
3950 else
3951 output_address (VOIDmode, addr);
3952 break;
3954 fputc (']', file);
3955 break;
3957 case CONST_DOUBLE :
3958 /* We handle SFmode constants here as output_addr_const doesn't. */
3959 if (GET_MODE (x) == SFmode)
3961 long l;
3963 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
3964 fprintf (file, "0x%08lx", l);
3965 break;
3967 /* FALLTHRU */
3968 /* Let output_addr_const deal with it. */
3969 default :
3970 if (flag_pic
3971 || (GET_CODE (x) == CONST
3972 && GET_CODE (XEXP (x, 0)) == UNSPEC
3973 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
3974 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
3975 || (GET_CODE (x) == CONST
3976 && GET_CODE (XEXP (x, 0)) == PLUS
3977 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
3978 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
3979 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
3980 arc_output_pic_addr_const (file, x, code);
3981 else
3983 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
3984 with asm_output_symbol_ref */
3985 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
3987 x = XEXP (x, 0);
3988 output_addr_const (file, XEXP (x, 0));
3989 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && SYMBOL_REF_SMALL_P (XEXP (x, 0)))
3990 fprintf (file, "@sda");
3992 if (GET_CODE (XEXP (x, 1)) != CONST_INT
3993 || INTVAL (XEXP (x, 1)) >= 0)
3994 fprintf (file, "+");
3995 output_addr_const (file, XEXP (x, 1));
3997 else
3998 output_addr_const (file, x);
4000 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
4001 fprintf (file, "@sda");
4002 break;
4006 /* Print a memory address as an operand to reference that memory location. */
4008 void
4009 arc_print_operand_address (FILE *file , rtx addr)
4011 register rtx base, index = 0;
4013 switch (GET_CODE (addr))
4015 case REG :
4016 fputs (reg_names[REGNO (addr)], file);
4017 break;
4018 case SYMBOL_REF :
4019 output_addr_const (file, addr);
4020 if (SYMBOL_REF_SMALL_P (addr))
4021 fprintf (file, "@sda");
4022 break;
4023 case PLUS :
4024 if (GET_CODE (XEXP (addr, 0)) == MULT)
4025 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
4026 else if (CONST_INT_P (XEXP (addr, 0)))
4027 index = XEXP (addr, 0), base = XEXP (addr, 1);
4028 else
4029 base = XEXP (addr, 0), index = XEXP (addr, 1);
4031 gcc_assert (OBJECT_P (base));
4032 arc_print_operand_address (file, base);
4033 if (CONSTANT_P (base) && CONST_INT_P (index))
4034 fputc ('+', file);
4035 else
4036 fputc (',', file);
4037 gcc_assert (OBJECT_P (index));
4038 arc_print_operand_address (file, index);
4039 break;
4040 case CONST:
4042 rtx c = XEXP (addr, 0);
4044 if ((GET_CODE (c) == UNSPEC
4045 && (XINT (c, 1) == UNSPEC_TLS_OFF
4046 || XINT (c, 1) == UNSPEC_TLS_IE))
4047 || (GET_CODE (c) == PLUS
4048 && GET_CODE (XEXP (c, 0)) == UNSPEC
4049 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
4050 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
4052 arc_output_pic_addr_const (file, c, 0);
4053 break;
4055 gcc_assert (GET_CODE (c) == PLUS);
4056 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
4057 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
4059 output_address (VOIDmode, XEXP (addr, 0));
4061 break;
4063 case PRE_INC :
4064 case PRE_DEC :
4065 /* We shouldn't get here as we've lost the mode of the memory object
4066 (which says how much to inc/dec by. */
4067 gcc_unreachable ();
4068 break;
4069 default :
4070 if (flag_pic)
4071 arc_output_pic_addr_const (file, addr, 0);
4072 else
4073 output_addr_const (file, addr);
4074 break;
4078 /* Conditional execution support.
4080 This is based on the ARM port but for now is much simpler.
4082 A finite state machine takes care of noticing whether or not instructions
4083 can be conditionally executed, and thus decrease execution time and code
4084 size by deleting branch instructions. The fsm is controlled by
4085 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4086 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4087 insns also have a hand in this. */
4088 /* The way we leave dealing with non-anulled or annull-false delay slot
4089 insns to the consumer is awkward. */
4091 /* The state of the fsm controlling condition codes are:
4092 0: normal, do nothing special
4093 1: don't output this insn
4094 2: don't output this insn
4095 3: make insns conditional
4096 4: make insns conditional
4097 5: make insn conditional (only for outputting anulled delay slot insns)
4099 special value for cfun->machine->uid_ccfsm_state:
4100 6: return with but one insn before it since function start / call
4102 State transitions (state->state by whom, under what condition):
4103 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4104 some instructions.
4105 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4106 by zero or more non-jump insns and an unconditional branch with
4107 the same target label as the condbranch.
4108 1 -> 3 branch patterns, after having not output the conditional branch
4109 2 -> 4 branch patterns, after having not output the conditional branch
4110 0 -> 5 branch patterns, for anulled delay slot insn.
4111 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4112 (the target label has CODE_LABEL_NUMBER equal to
4113 arc_ccfsm_target_label).
4114 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4115 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4116 5 -> 0 when outputting the delay slot insn
4118 If the jump clobbers the conditions then we use states 2 and 4.
4120 A similar thing can be done with conditional return insns.
4122 We also handle separating branches from sets of the condition code.
4123 This is done here because knowledge of the ccfsm state is required,
4124 we may not be outputting the branch. */
4126 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4127 before letting final output INSN. */
4129 static void
4130 arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
4132 /* BODY will hold the body of INSN. */
4133 register rtx body;
4135 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4136 an if/then/else), and things need to be reversed. */
4137 int reverse = 0;
4139 /* If we start with a return insn, we only succeed if we find another one. */
4140 int seeking_return = 0;
4142 /* START_INSN will hold the insn from where we start looking. This is the
4143 first insn after the following code_label if REVERSE is true. */
4144 rtx_insn *start_insn = insn;
4146 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4147 since they don't rely on a cmp preceding the. */
4148 enum attr_type jump_insn_type;
4150 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4151 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4152 final_scan_insn which has `optimize' as a local. */
4153 if (optimize < 2 || TARGET_NO_COND_EXEC)
4154 return;
4156 /* Ignore notes and labels. */
4157 if (!INSN_P (insn))
4158 return;
4159 body = PATTERN (insn);
4160 /* If in state 4, check if the target branch is reached, in order to
4161 change back to state 0. */
4162 if (state->state == 4)
4164 if (insn == state->target_insn)
4166 state->target_insn = NULL;
4167 state->state = 0;
4169 return;
4172 /* If in state 3, it is possible to repeat the trick, if this insn is an
4173 unconditional branch to a label, and immediately following this branch
4174 is the previous target label which is only used once, and the label this
4175 branch jumps to is not too far off. Or in other words "we've done the
4176 `then' part, see if we can do the `else' part." */
4177 if (state->state == 3)
4179 if (simplejump_p (insn))
4181 start_insn = next_nonnote_insn (start_insn);
4182 if (GET_CODE (start_insn) == BARRIER)
4184 /* ??? Isn't this always a barrier? */
4185 start_insn = next_nonnote_insn (start_insn);
4187 if (GET_CODE (start_insn) == CODE_LABEL
4188 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4189 && LABEL_NUSES (start_insn) == 1)
4190 reverse = TRUE;
4191 else
4192 return;
4194 else if (GET_CODE (body) == SIMPLE_RETURN)
4196 start_insn = next_nonnote_insn (start_insn);
4197 if (GET_CODE (start_insn) == BARRIER)
4198 start_insn = next_nonnote_insn (start_insn);
4199 if (GET_CODE (start_insn) == CODE_LABEL
4200 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4201 && LABEL_NUSES (start_insn) == 1)
4203 reverse = TRUE;
4204 seeking_return = 1;
4206 else
4207 return;
4209 else
4210 return;
4213 if (GET_CODE (insn) != JUMP_INSN
4214 || GET_CODE (PATTERN (insn)) == ADDR_VEC
4215 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
4216 return;
4218 /* We can't predicate BRCC or loop ends.
4219 Also, when generating PIC code, and considering a medium range call,
4220 we can't predicate the call. */
4221 jump_insn_type = get_attr_type (insn);
4222 if (jump_insn_type == TYPE_BRCC
4223 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
4224 || jump_insn_type == TYPE_LOOP_END
4225 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
4226 return;
4228 /* This jump might be paralleled with a clobber of the condition codes,
4229 the jump should always come first. */
4230 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
4231 body = XVECEXP (body, 0, 0);
4233 if (reverse
4234 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
4235 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
4237 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
4238 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4239 int then_not_else = TRUE;
4240 /* Nonzero if next insn must be the target label. */
4241 int next_must_be_target_label_p;
4242 rtx_insn *this_insn = start_insn;
4243 rtx label = 0;
4245 /* Register the insn jumped to. */
4246 if (reverse)
4248 if (!seeking_return)
4249 label = XEXP (SET_SRC (body), 0);
4251 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
4252 label = XEXP (XEXP (SET_SRC (body), 1), 0);
4253 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
4255 label = XEXP (XEXP (SET_SRC (body), 2), 0);
4256 then_not_else = FALSE;
4258 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
4259 seeking_return = 1;
4260 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
4262 seeking_return = 1;
4263 then_not_else = FALSE;
4265 else
4266 gcc_unreachable ();
4268 /* If this is a non-annulled branch with a delay slot, there is
4269 no need to conditionalize the delay slot. */
4270 if (NEXT_INSN (PREV_INSN (insn)) != insn
4271 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
4273 this_insn = NEXT_INSN (this_insn);
4274 gcc_assert (NEXT_INSN (NEXT_INSN (PREV_INSN (start_insn)))
4275 == NEXT_INSN (this_insn));
4277 /* See how many insns this branch skips, and what kind of insns. If all
4278 insns are okay, and the label or unconditional branch to the same
4279 label is not too far away, succeed. */
4280 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
4281 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
4282 insns_skipped++)
4284 rtx scanbody;
4286 this_insn = next_nonnote_insn (this_insn);
4287 if (!this_insn)
4288 break;
4290 if (next_must_be_target_label_p)
4292 if (GET_CODE (this_insn) == BARRIER)
4293 continue;
4294 if (GET_CODE (this_insn) == CODE_LABEL
4295 && this_insn == label)
4297 state->state = 1;
4298 succeed = TRUE;
4300 else
4301 fail = TRUE;
4302 break;
4305 switch (GET_CODE (this_insn))
4307 case CODE_LABEL:
4308 /* Succeed if it is the target label, otherwise fail since
4309 control falls in from somewhere else. */
4310 if (this_insn == label)
4312 state->state = 1;
4313 succeed = TRUE;
4315 else
4316 fail = TRUE;
4317 break;
4319 case BARRIER:
4320 /* Succeed if the following insn is the target label.
4321 Otherwise fail.
4322 If return insns are used then the last insn in a function
4323 will be a barrier. */
4324 next_must_be_target_label_p = TRUE;
4325 break;
4327 case CALL_INSN:
4328 /* Can handle a call insn if there are no insns after it.
4329 IE: The next "insn" is the target label. We don't have to
4330 worry about delay slots as such insns are SEQUENCE's inside
4331 INSN's. ??? It is possible to handle such insns though. */
4332 if (get_attr_cond (this_insn) == COND_CANUSE)
4333 next_must_be_target_label_p = TRUE;
4334 else
4335 fail = TRUE;
4336 break;
4338 case JUMP_INSN:
4339 scanbody = PATTERN (this_insn);
4341 /* If this is an unconditional branch to the same label, succeed.
4342 If it is to another label, do nothing. If it is conditional,
4343 fail. */
4344 /* ??? Probably, the test for the SET and the PC are
4345 unnecessary. */
4347 if (GET_CODE (scanbody) == SET
4348 && GET_CODE (SET_DEST (scanbody)) == PC)
4350 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
4351 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
4353 state->state = 2;
4354 succeed = TRUE;
4356 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
4357 fail = TRUE;
4358 else if (get_attr_cond (this_insn) != COND_CANUSE)
4359 fail = TRUE;
4361 else if (GET_CODE (scanbody) == SIMPLE_RETURN
4362 && seeking_return)
4364 state->state = 2;
4365 succeed = TRUE;
4367 else if (GET_CODE (scanbody) == PARALLEL)
4369 if (get_attr_cond (this_insn) != COND_CANUSE)
4370 fail = TRUE;
4372 break;
4374 case INSN:
4375 scanbody = PATTERN (this_insn);
4377 /* We can only do this with insns that can use the condition
4378 codes (and don't set them). */
4379 if (GET_CODE (scanbody) == SET
4380 || GET_CODE (scanbody) == PARALLEL)
4382 if (get_attr_cond (this_insn) != COND_CANUSE)
4383 fail = TRUE;
4385 /* We can't handle other insns like sequences. */
4386 else
4387 fail = TRUE;
4388 break;
4390 default:
4391 break;
4395 if (succeed)
4397 if ((!seeking_return) && (state->state == 1 || reverse))
4398 state->target_label = CODE_LABEL_NUMBER (label);
4399 else if (seeking_return || state->state == 2)
4401 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
4403 this_insn = next_nonnote_insn (this_insn);
4405 gcc_assert (!this_insn ||
4406 (GET_CODE (this_insn) != BARRIER
4407 && GET_CODE (this_insn) != CODE_LABEL));
4409 if (!this_insn)
4411 /* Oh dear! we ran off the end, give up. */
4412 extract_insn_cached (insn);
4413 state->state = 0;
4414 state->target_insn = NULL;
4415 return;
4417 state->target_insn = this_insn;
4419 else
4420 gcc_unreachable ();
4422 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4423 what it was. */
4424 if (!reverse)
4426 state->cond = XEXP (SET_SRC (body), 0);
4427 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
4430 if (reverse || then_not_else)
4431 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
4434 /* Restore recog_operand. Getting the attributes of other insns can
4435 destroy this array, but final.c assumes that it remains intact
4436 across this call; since the insn has been recognized already we
4437 call insn_extract direct. */
4438 extract_insn_cached (insn);
4442 /* Record that we are currently outputting label NUM with prefix PREFIX.
4443 It it's the label we're looking for, reset the ccfsm machinery.
4445 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4447 static void
4448 arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
4450 if (state->state == 3 && state->target_label == num
4451 && !strcmp (prefix, "L"))
4453 state->state = 0;
4454 state->target_insn = NULL;
4458 /* We are considering a conditional branch with the condition COND.
4459 Check if we want to conditionalize a delay slot insn, and if so modify
4460 the ccfsm state accordingly.
4461 REVERSE says branch will branch when the condition is false. */
4462 void
4463 arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
4464 struct arc_ccfsm *state)
4466 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
4467 if (!state)
4468 state = &arc_ccfsm_current;
4470 gcc_assert (state->state == 0);
4471 if (seq_insn != jump)
4473 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
4475 if (!as_a<rtx_insn *> (insn)->deleted ()
4476 && INSN_ANNULLED_BRANCH_P (jump)
4477 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
4479 state->cond = cond;
4480 state->cc = get_arc_condition_code (cond);
4481 if (!reverse)
4482 arc_ccfsm_current.cc
4483 = ARC_INVERSE_CONDITION_CODE (state->cc);
4484 rtx pat = PATTERN (insn);
4485 if (GET_CODE (pat) == COND_EXEC)
4486 gcc_assert ((INSN_FROM_TARGET_P (insn)
4487 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
4488 == get_arc_condition_code (XEXP (pat, 0)));
4489 else
4490 state->state = 5;
4495 /* Update *STATE as we would when we emit INSN. */
4497 static void
4498 arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
4500 enum attr_type type;
4502 if (LABEL_P (insn))
4503 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
4504 else if (JUMP_P (insn)
4505 && GET_CODE (PATTERN (insn)) != ADDR_VEC
4506 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
4507 && ((type = get_attr_type (insn)) == TYPE_BRANCH
4508 || ((type == TYPE_UNCOND_BRANCH
4509 || type == TYPE_RETURN)
4510 && ARC_CCFSM_BRANCH_DELETED_P (state))))
4512 if (ARC_CCFSM_BRANCH_DELETED_P (state))
4513 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
4514 else
4516 rtx src = SET_SRC (PATTERN (insn));
4517 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
4518 insn, state);
4521 else if (arc_ccfsm_current.state == 5)
4522 arc_ccfsm_current.state = 0;
4525 /* Return true if the current insn, which is a conditional branch, is to be
4526 deleted. */
4528 bool
4529 arc_ccfsm_branch_deleted_p (void)
4531 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
4534 /* Record a branch isn't output because subsequent insns can be
4535 conditionalized. */
4537 void
4538 arc_ccfsm_record_branch_deleted (void)
4540 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
4543 /* During insn output, indicate if the current insn is predicated. */
4545 bool
4546 arc_ccfsm_cond_exec_p (void)
4548 return (cfun->machine->prescan_initialized
4549 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
4552 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4553 and look inside SEQUENCEs. */
4555 static rtx_insn *
4556 arc_next_active_insn (rtx_insn *insn, struct arc_ccfsm *statep)
4558 rtx pat;
4562 if (statep)
4563 arc_ccfsm_post_advance (insn, statep);
4564 insn = NEXT_INSN (insn);
4565 if (!insn || BARRIER_P (insn))
4566 return NULL;
4567 if (statep)
4568 arc_ccfsm_advance (insn, statep);
4570 while (NOTE_P (insn)
4571 || (cfun->machine->arc_reorg_started
4572 && LABEL_P (insn) && !label_to_alignment (insn))
4573 || (NONJUMP_INSN_P (insn)
4574 && (GET_CODE (PATTERN (insn)) == USE
4575 || GET_CODE (PATTERN (insn)) == CLOBBER)));
4576 if (!LABEL_P (insn))
4578 gcc_assert (INSN_P (insn));
4579 pat = PATTERN (insn);
4580 if (GET_CODE (pat) == ADDR_VEC || GET_CODE (pat) == ADDR_DIFF_VEC)
4581 return NULL;
4582 if (GET_CODE (pat) == SEQUENCE)
4583 return as_a <rtx_insn *> (XVECEXP (pat, 0, 0));
4585 return insn;
4588 /* When deciding if an insn should be output short, we want to know something
4589 about the following insns:
4590 - if another insn follows which we know we can output as a short insn
4591 before an alignment-sensitive point, we can output this insn short:
4592 the decision about the eventual alignment can be postponed.
4593 - if a to-be-aligned label comes next, we should output this insn such
4594 as to get / preserve 4-byte alignment.
4595 - if a likely branch without delay slot insn, or a call with an immediately
4596 following short insn comes next, we should out output this insn such as to
4597 get / preserve 2 mod 4 unalignment.
4598 - do the same for a not completely unlikely branch with a short insn
4599 following before any other branch / label.
4600 - in order to decide if we are actually looking at a branch, we need to
4601 call arc_ccfsm_advance.
4602 - in order to decide if we are looking at a short insn, we should know
4603 if it is conditionalized. To a first order of approximation this is
4604 the case if the state from arc_ccfsm_advance from before this insn
4605 indicates the insn is conditionalized. However, a further refinement
4606 could be to not conditionalize an insn if the destination register(s)
4607 is/are dead in the non-executed case. */
4608 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4609 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4610 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4613 arc_verify_short (rtx_insn *insn, int, int check_attr)
4615 enum attr_iscompact iscompact;
4616 struct machine_function *machine;
4618 if (check_attr > 0)
4620 iscompact = get_attr_iscompact (insn);
4621 if (iscompact == ISCOMPACT_FALSE)
4622 return 0;
4624 machine = cfun->machine;
4626 if (machine->force_short_suffix >= 0)
4627 return machine->force_short_suffix;
4629 return (get_attr_length (insn) & 2) != 0;
4632 /* When outputting an instruction (alternative) that can potentially be short,
4633 output the short suffix if the insn is in fact short, and update
4634 cfun->machine->unalign accordingly. */
4636 static void
4637 output_short_suffix (FILE *file)
4639 rtx_insn *insn = current_output_insn;
4641 if (arc_verify_short (insn, cfun->machine->unalign, 1))
4643 fprintf (file, "_s");
4644 cfun->machine->unalign ^= 2;
4646 /* Restore recog_operand. */
4647 extract_insn_cached (insn);
4650 /* Implement FINAL_PRESCAN_INSN. */
4652 void
4653 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
4654 int noperands ATTRIBUTE_UNUSED)
4656 if (TARGET_DUMPISIZE)
4657 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
4659 /* Output a nop if necessary to prevent a hazard.
4660 Don't do this for delay slots: inserting a nop would
4661 alter semantics, and the only time we would find a hazard is for a
4662 call function result - and in that case, the hazard is spurious to
4663 start with. */
4664 if (PREV_INSN (insn)
4665 && PREV_INSN (NEXT_INSN (insn)) == insn
4666 && arc_hazard (prev_real_insn (insn), insn))
4668 current_output_insn =
4669 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn)));
4670 final_scan_insn (current_output_insn, asm_out_file, optimize, 1, NULL);
4671 current_output_insn = insn;
4673 /* Restore extraction data which might have been clobbered by arc_hazard. */
4674 extract_constrain_insn_cached (insn);
4676 if (!cfun->machine->prescan_initialized)
4678 /* Clear lingering state from branch shortening. */
4679 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
4680 cfun->machine->prescan_initialized = 1;
4682 arc_ccfsm_advance (insn, &arc_ccfsm_current);
4684 cfun->machine->size_reason = 0;
4687 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4688 Frame pointer elimination is automatically handled.
4690 All eliminations are permissible. If we need a frame
4691 pointer, we must eliminate ARG_POINTER_REGNUM into
4692 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4694 static bool
4695 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
4697 return ((to == FRAME_POINTER_REGNUM) || !arc_frame_pointer_needed ());
4700 /* Define the offset between two registers, one to be eliminated, and
4701 the other its replacement, at the start of a routine. */
4704 arc_initial_elimination_offset (int from, int to)
4706 if (! cfun->machine->frame_info.initialized)
4707 arc_compute_frame_size (get_frame_size ());
4709 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
4711 return (cfun->machine->frame_info.extra_size
4712 + cfun->machine->frame_info.reg_size);
4715 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
4717 return (cfun->machine->frame_info.total_size
4718 - cfun->machine->frame_info.pretend_size);
4721 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
4723 return (cfun->machine->frame_info.total_size
4724 - (cfun->machine->frame_info.pretend_size
4725 + cfun->machine->frame_info.extra_size
4726 + cfun->machine->frame_info.reg_size));
4729 gcc_unreachable ();
4732 static bool
4733 arc_frame_pointer_required (void)
4735 return cfun->calls_alloca;
4739 /* Return the destination address of a branch. */
4742 branch_dest (rtx branch)
4744 rtx pat = PATTERN (branch);
4745 rtx dest = (GET_CODE (pat) == PARALLEL
4746 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
4747 int dest_uid;
4749 if (GET_CODE (dest) == IF_THEN_ELSE)
4750 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
4752 dest = XEXP (dest, 0);
4753 dest_uid = INSN_UID (dest);
4755 return INSN_ADDRESSES (dest_uid);
4759 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4761 static void
4762 arc_encode_section_info (tree decl, rtx rtl, int first)
4764 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4765 This clears machine specific flags, so has to come first. */
4766 default_encode_section_info (decl, rtl, first);
4768 /* Check if it is a function, and whether it has the
4769 [long/medium/short]_call attribute specified. */
4770 if (TREE_CODE (decl) == FUNCTION_DECL)
4772 rtx symbol = XEXP (rtl, 0);
4773 int flags = SYMBOL_REF_FLAGS (symbol);
4775 tree attr = (TREE_TYPE (decl) != error_mark_node
4776 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
4777 tree long_call_attr = lookup_attribute ("long_call", attr);
4778 tree medium_call_attr = lookup_attribute ("medium_call", attr);
4779 tree short_call_attr = lookup_attribute ("short_call", attr);
4781 if (long_call_attr != NULL_TREE)
4782 flags |= SYMBOL_FLAG_LONG_CALL;
4783 else if (medium_call_attr != NULL_TREE)
4784 flags |= SYMBOL_FLAG_MEDIUM_CALL;
4785 else if (short_call_attr != NULL_TREE)
4786 flags |= SYMBOL_FLAG_SHORT_CALL;
4788 SYMBOL_REF_FLAGS (symbol) = flags;
4790 else if (TREE_CODE (decl) == VAR_DECL)
4792 rtx symbol = XEXP (rtl, 0);
4794 tree attr = (TREE_TYPE (decl) != error_mark_node
4795 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
4797 tree sec_attr = lookup_attribute ("section", attr);
4798 if (sec_attr)
4800 const char *sec_name
4801 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
4802 if (strcmp (sec_name, ".cmem") == 0
4803 || strcmp (sec_name, ".cmem_shared") == 0
4804 || strcmp (sec_name, ".cmem_private") == 0)
4805 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
4810 /* This is how to output a definition of an internal numbered label where
4811 PREFIX is the class of label and NUM is the number within the class. */
4813 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
4815 if (cfun)
4816 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
4817 default_internal_label (stream, prefix, labelno);
4820 /* Set the cpu type and print out other fancy things,
4821 at the top of the file. */
4823 static void arc_file_start (void)
4825 default_file_start ();
4826 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
4829 /* Cost functions. */
4831 /* Compute a (partial) cost for rtx X. Return true if the complete
4832 cost has been computed, and false if subexpressions should be
4833 scanned. In either case, *TOTAL contains the cost result. */
4835 static bool
4836 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
4837 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
4839 int code = GET_CODE (x);
4841 switch (code)
4843 /* Small integers are as cheap as registers. */
4844 case CONST_INT:
4846 bool nolimm = false; /* Can we do without long immediate? */
4847 bool fast = false; /* Is the result available immediately? */
4848 bool condexec = false; /* Does this allow conditiobnal execution? */
4849 bool compact = false; /* Is a 16 bit opcode available? */
4850 /* CONDEXEC also implies that we can have an unconditional
4851 3-address operation. */
4853 nolimm = compact = condexec = false;
4854 if (UNSIGNED_INT6 (INTVAL (x)))
4855 nolimm = condexec = compact = true;
4856 else
4858 if (SMALL_INT (INTVAL (x)))
4859 nolimm = fast = true;
4860 switch (outer_code)
4862 case AND: /* bclr, bmsk, ext[bw] */
4863 if (satisfies_constraint_Ccp (x) /* bclr */
4864 || satisfies_constraint_C1p (x) /* bmsk */)
4865 nolimm = fast = condexec = compact = true;
4866 break;
4867 case IOR: /* bset */
4868 if (satisfies_constraint_C0p (x)) /* bset */
4869 nolimm = fast = condexec = compact = true;
4870 break;
4871 case XOR:
4872 if (satisfies_constraint_C0p (x)) /* bxor */
4873 nolimm = fast = condexec = true;
4874 break;
4875 case SET:
4876 if (satisfies_constraint_Crr (x)) /* ror b,u6 */
4877 nolimm = true;
4878 default:
4879 break;
4882 /* FIXME: Add target options to attach a small cost if
4883 condexec / compact is not true. */
4884 if (nolimm)
4886 *total = 0;
4887 return true;
4890 /* FALLTHRU */
4892 /* 4 byte values can be fetched as immediate constants -
4893 let's give that the cost of an extra insn. */
4894 case CONST:
4895 case LABEL_REF:
4896 case SYMBOL_REF:
4897 *total = COSTS_N_INSNS (1);
4898 return true;
4900 case CONST_DOUBLE:
4902 rtx first, second;
4904 if (TARGET_DPFP)
4906 *total = COSTS_N_INSNS (1);
4907 return true;
4909 split_double (x, &first, &second);
4910 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
4911 + !SMALL_INT (INTVAL (second)));
4912 return true;
4915 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4916 If we need more than 12 insns to do a multiply, then go out-of-line,
4917 since the call overhead will be < 10% of the cost of the multiply. */
4918 case ASHIFT:
4919 case ASHIFTRT:
4920 case LSHIFTRT:
4921 if (TARGET_BARREL_SHIFTER)
4923 /* If we want to shift a constant, we need a LIMM. */
4924 /* ??? when the optimizers want to know if a constant should be
4925 hoisted, they ask for the cost of the constant. OUTER_CODE is
4926 insufficient context for shifts since we don't know which operand
4927 we are looking at. */
4928 if (CONSTANT_P (XEXP (x, 0)))
4930 *total += (COSTS_N_INSNS (2)
4931 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
4932 0, speed));
4933 return true;
4935 *total = COSTS_N_INSNS (1);
4937 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
4938 *total = COSTS_N_INSNS (16);
4939 else
4941 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
4942 /* ??? want_to_gcse_p can throw negative shift counts at us,
4943 and then panics when it gets a negative cost as result.
4944 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
4945 if (*total < 0)
4946 *total = 0;
4948 return false;
4950 case DIV:
4951 case UDIV:
4952 if (speed)
4953 *total = COSTS_N_INSNS(30);
4954 else
4955 *total = COSTS_N_INSNS(1);
4956 return false;
4958 case MULT:
4959 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
4960 *total = COSTS_N_INSNS (1);
4961 else if (speed)
4962 *total= arc_multcost;
4963 /* We do not want synth_mult sequences when optimizing
4964 for size. */
4965 else if (TARGET_MUL64_SET || TARGET_ARC700_MPY)
4966 *total = COSTS_N_INSNS (1);
4967 else
4968 *total = COSTS_N_INSNS (2);
4969 return false;
4970 case PLUS:
4971 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
4972 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
4973 || (GET_CODE (XEXP (x, 0)) == MULT
4974 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
4976 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
4977 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
4978 return true;
4980 return false;
4981 case MINUS:
4982 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
4983 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
4984 || (GET_CODE (XEXP (x, 1)) == MULT
4985 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
4987 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
4988 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
4989 return true;
4991 return false;
4992 case COMPARE:
4994 rtx op0 = XEXP (x, 0);
4995 rtx op1 = XEXP (x, 1);
4997 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
4998 && XEXP (op0, 1) == const1_rtx)
5000 /* btst / bbit0 / bbit1:
5001 Small integers and registers are free; everything else can
5002 be put in a register. */
5003 mode = GET_MODE (XEXP (op0, 0));
5004 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5005 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5006 return true;
5008 if (GET_CODE (op0) == AND && op1 == const0_rtx
5009 && satisfies_constraint_C1p (XEXP (op0, 1)))
5011 /* bmsk.f */
5012 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5013 return true;
5015 /* add.f */
5016 if (GET_CODE (op1) == NEG)
5018 /* op0 might be constant, the inside of op1 is rather
5019 unlikely to be so. So swapping the operands might lower
5020 the cost. */
5021 mode = GET_MODE (op0);
5022 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5023 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5025 return false;
5027 case EQ: case NE:
5028 if (outer_code == IF_THEN_ELSE
5029 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5030 && XEXP (x, 1) == const0_rtx
5031 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5033 /* btst / bbit0 / bbit1:
5034 Small integers and registers are free; everything else can
5035 be put in a register. */
5036 rtx op0 = XEXP (x, 0);
5038 mode = GET_MODE (XEXP (op0, 0));
5039 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5040 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5041 return true;
5043 /* Fall through. */
5044 /* scc_insn expands into two insns. */
5045 case GTU: case GEU: case LEU:
5046 if (mode == SImode)
5047 *total += COSTS_N_INSNS (1);
5048 return false;
5049 case LTU: /* might use adc. */
5050 if (mode == SImode)
5051 *total += COSTS_N_INSNS (1) - 1;
5052 return false;
5053 default:
5054 return false;
5058 /* Return true if ADDR is a valid pic address.
5059 A valid pic address on arc should look like
5060 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5062 bool
5063 arc_legitimate_pic_addr_p (rtx addr)
5065 if (GET_CODE (addr) != CONST)
5066 return false;
5068 addr = XEXP (addr, 0);
5071 if (GET_CODE (addr) == PLUS)
5073 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
5074 return false;
5075 addr = XEXP (addr, 0);
5078 if (GET_CODE (addr) != UNSPEC
5079 || XVECLEN (addr, 0) != 1)
5080 return false;
5082 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5083 if (XINT (addr, 1) != ARC_UNSPEC_GOT
5084 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
5085 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
5086 && XINT (addr, 1) != UNSPEC_TLS_GD
5087 && XINT (addr, 1) != UNSPEC_TLS_IE)
5088 return false;
5090 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
5091 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
5092 return false;
5094 return true;
5099 /* Return true if OP contains a symbol reference. */
5101 static bool
5102 symbolic_reference_mentioned_p (rtx op)
5104 register const char *fmt;
5105 register int i;
5107 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5108 return true;
5110 fmt = GET_RTX_FORMAT (GET_CODE (op));
5111 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5113 if (fmt[i] == 'E')
5115 register int j;
5117 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5118 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5119 return true;
5122 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5123 return true;
5126 return false;
5129 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5130 If SKIP_LOCAL is true, skip symbols that bind locally.
5131 This is used further down in this file, and, without SKIP_LOCAL,
5132 in the addsi3 / subsi3 expanders when generating PIC code. */
5134 bool
5135 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
5137 register const char *fmt;
5138 register int i;
5140 if (GET_CODE(op) == UNSPEC)
5141 return false;
5143 if (GET_CODE (op) == SYMBOL_REF)
5145 if (SYMBOL_REF_TLS_MODEL (op))
5146 return true;
5147 if (!flag_pic)
5148 return false;
5149 tree decl = SYMBOL_REF_DECL (op);
5150 return !skip_local || !decl || !default_binds_local_p (decl);
5153 fmt = GET_RTX_FORMAT (GET_CODE (op));
5154 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5156 if (fmt[i] == 'E')
5158 register int j;
5160 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5161 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
5162 skip_local))
5163 return true;
5166 else if (fmt[i] == 'e'
5167 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
5168 skip_local))
5169 return true;
5172 return false;
5175 /* Get the thread pointer. */
5177 static rtx
5178 arc_get_tp (void)
5180 /* If arc_tp_regno has been set, we can use that hard register
5181 directly as a base register. */
5182 if (arc_tp_regno != -1)
5183 return gen_rtx_REG (Pmode, arc_tp_regno);
5185 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5186 conflicts with function arguments / results. */
5187 rtx reg = gen_reg_rtx (Pmode);
5188 emit_insn (gen_tls_load_tp_soft ());
5189 emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG));
5190 return reg;
5193 /* Helper to be used by TLS Global dynamic model. */
5195 static rtx
5196 arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
5198 rtx r0 = gen_rtx_REG (Pmode, R0_REG);
5199 rtx call_fusage = NULL_RTX;
5201 start_sequence ();
5203 rtx x = arc_unspec_offset (sym, reloc);
5204 emit_move_insn (r0, x);
5205 use_reg (&call_fusage, r0);
5207 gcc_assert (reloc == UNSPEC_TLS_GD);
5208 rtx call_insn = emit_call_insn (gen_tls_gd_get_addr (sym));
5209 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5210 way that the application should care. */
5211 RTL_PURE_CALL_P (call_insn) = 1;
5212 add_function_usage_to (call_insn, call_fusage);
5214 rtx_insn *insns = get_insns ();
5215 end_sequence ();
5217 rtx dest = gen_reg_rtx (Pmode);
5218 emit_libcall_block (insns, dest, r0, eqv);
5219 return dest;
5222 #define DTPOFF_ZERO_SYM ".tdata"
5224 /* Return a legitimized address for ADDR,
5225 which is a SYMBOL_REF with tls_model MODEL. */
5227 static rtx
5228 arc_legitimize_tls_address (rtx addr, enum tls_model model)
5230 if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC)
5231 model = TLS_MODEL_LOCAL_EXEC;
5233 switch (model)
5235 case TLS_MODEL_LOCAL_DYNAMIC:
5236 rtx base;
5237 tree decl;
5238 const char *base_name;
5239 rtvec v;
5241 decl = SYMBOL_REF_DECL (addr);
5242 base_name = DTPOFF_ZERO_SYM;
5243 if (decl && bss_initializer_p (decl))
5244 base_name = ".tbss";
5246 base = gen_rtx_SYMBOL_REF (Pmode, base_name);
5247 if (strcmp (base_name, DTPOFF_ZERO_SYM) == 0)
5249 if (!flag_pic)
5250 goto local_exec;
5251 v = gen_rtvec (1, addr);
5253 else
5254 v = gen_rtvec (2, addr, base);
5255 addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_TLS_OFF);
5256 addr = gen_rtx_CONST (Pmode, addr);
5257 base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
5258 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
5260 case TLS_MODEL_GLOBAL_DYNAMIC:
5261 return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
5263 case TLS_MODEL_INITIAL_EXEC:
5264 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
5265 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
5266 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5268 case TLS_MODEL_LOCAL_EXEC:
5269 local_exec:
5270 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
5271 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5272 default:
5273 gcc_unreachable ();
5277 /* Legitimize a pic address reference in ORIG.
5278 The return value is the legitimated address.
5279 If OLDX is non-zero, it is the target to assign the address to first. */
5281 static rtx
5282 arc_legitimize_pic_address (rtx orig, rtx oldx)
5284 rtx addr = orig;
5285 rtx pat = orig;
5286 rtx base;
5288 if (oldx == orig)
5289 oldx = NULL;
5291 if (GET_CODE (addr) == LABEL_REF)
5292 ; /* Do nothing. */
5293 else if (GET_CODE (addr) == SYMBOL_REF)
5295 enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
5296 if (model != 0)
5297 return arc_legitimize_tls_address (addr, model);
5298 else if (!flag_pic)
5299 return orig;
5300 else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
5301 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
5303 /* This symbol must be referenced via a load from the Global
5304 Offset Table (@GOTPC). */
5305 pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
5306 pat = gen_const_mem (Pmode, pat);
5308 if (oldx == NULL)
5309 oldx = gen_reg_rtx (Pmode);
5311 emit_move_insn (oldx, pat);
5312 pat = oldx;
5314 else
5316 if (GET_CODE (addr) == CONST)
5318 addr = XEXP (addr, 0);
5319 if (GET_CODE (addr) == UNSPEC)
5321 /* Check that the unspec is one of the ones we generate? */
5322 return orig;
5324 /* fwprop is placing in the REG_EQUIV notes constant pic
5325 unspecs expressions. Then, loop may use these notes for
5326 optimizations resulting in complex patterns that are not
5327 supported by the current implementation. The following
5328 two if-cases are simplifying the complex patters to
5329 simpler ones. */
5330 else if (GET_CODE (addr) == MINUS)
5332 rtx op0 = XEXP (addr, 0);
5333 rtx op1 = XEXP (addr, 1);
5334 gcc_assert (oldx);
5335 gcc_assert (GET_CODE (op1) == UNSPEC);
5337 emit_move_insn (oldx,
5338 gen_rtx_CONST (SImode,
5339 arc_legitimize_pic_address (op1,
5340 NULL_RTX)));
5341 emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
5342 return oldx;
5345 else if (GET_CODE (addr) != PLUS)
5347 rtx tmp = XEXP (addr, 0);
5348 enum rtx_code code = GET_CODE (addr);
5350 /* It only works for UNARY operations. */
5351 gcc_assert (UNARY_P (addr));
5352 gcc_assert (GET_CODE (tmp) == UNSPEC);
5353 gcc_assert (oldx);
5355 emit_move_insn
5356 (oldx,
5357 gen_rtx_CONST (SImode,
5358 arc_legitimize_pic_address (tmp,
5359 NULL_RTX)));
5361 emit_insn (gen_rtx_SET (oldx,
5362 gen_rtx_fmt_ee (code, SImode,
5363 oldx, const0_rtx)));
5365 return oldx;
5367 else
5369 gcc_assert (GET_CODE (addr) == PLUS);
5370 if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
5371 return orig;
5375 if (GET_CODE (addr) == PLUS)
5377 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
5379 base = arc_legitimize_pic_address (op0, oldx);
5380 pat = arc_legitimize_pic_address (op1,
5381 base == oldx ? NULL_RTX : oldx);
5383 if (base == op0 && pat == op1)
5384 return orig;
5386 if (GET_CODE (pat) == CONST_INT)
5387 pat = plus_constant (Pmode, base, INTVAL (pat));
5388 else
5390 if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1)))
5392 base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0));
5393 pat = XEXP (pat, 1);
5395 pat = gen_rtx_PLUS (Pmode, base, pat);
5400 return pat;
5403 /* Output address constant X to FILE, taking PIC into account. */
5405 void
5406 arc_output_pic_addr_const (FILE * file, rtx x, int code)
5408 char buf[256];
5410 restart:
5411 switch (GET_CODE (x))
5413 case PC:
5414 if (flag_pic)
5415 putc ('.', file);
5416 else
5417 gcc_unreachable ();
5418 break;
5420 case SYMBOL_REF:
5421 output_addr_const (file, x);
5423 /* Local functions do not get references through the PLT. */
5424 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
5425 fputs ("@plt", file);
5426 break;
5428 case LABEL_REF:
5429 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
5430 assemble_name (file, buf);
5431 break;
5433 case CODE_LABEL:
5434 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
5435 assemble_name (file, buf);
5436 break;
5438 case CONST_INT:
5439 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
5440 break;
5442 case CONST:
5443 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5444 break;
5446 case CONST_DOUBLE:
5447 if (GET_MODE (x) == VOIDmode)
5449 /* We can use %d if the number is one word and positive. */
5450 if (CONST_DOUBLE_HIGH (x))
5451 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
5452 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
5453 else if (CONST_DOUBLE_LOW (x) < 0)
5454 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
5455 else
5456 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
5458 else
5459 /* We can't handle floating point constants;
5460 PRINT_OPERAND must handle them. */
5461 output_operand_lossage ("floating constant misused");
5462 break;
5464 case PLUS:
5465 /* FIXME: Not needed here. */
5466 /* Some assemblers need integer constants to appear last (eg masm). */
5467 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
5469 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5470 fprintf (file, "+");
5471 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5473 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5475 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5476 if (INTVAL (XEXP (x, 1)) >= 0)
5477 fprintf (file, "+");
5478 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5480 else
5481 gcc_unreachable();
5482 break;
5484 case MINUS:
5485 /* Avoid outputting things like x-x or x+5-x,
5486 since some assemblers can't handle that. */
5487 x = simplify_subtraction (x);
5488 if (GET_CODE (x) != MINUS)
5489 goto restart;
5491 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5492 fprintf (file, "-");
5493 if (GET_CODE (XEXP (x, 1)) == CONST_INT
5494 && INTVAL (XEXP (x, 1)) < 0)
5496 fprintf (file, "(");
5497 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5498 fprintf (file, ")");
5500 else
5501 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5502 break;
5504 case ZERO_EXTEND:
5505 case SIGN_EXTEND:
5506 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5507 break;
5510 case UNSPEC:
5511 const char *suffix;
5512 bool pcrel; pcrel = false;
5513 rtx base; base = NULL;
5514 gcc_assert (XVECLEN (x, 0) >= 1);
5515 switch (XINT (x, 1))
5517 case ARC_UNSPEC_GOT:
5518 suffix = "@gotpc", pcrel = true;
5519 break;
5520 case ARC_UNSPEC_GOTOFF:
5521 suffix = "@gotoff";
5522 break;
5523 case ARC_UNSPEC_GOTOFFPC:
5524 suffix = "@pcl", pcrel = true;
5525 break;
5526 case ARC_UNSPEC_PLT:
5527 suffix = "@plt";
5528 break;
5529 case UNSPEC_TLS_GD:
5530 suffix = "@tlsgd", pcrel = true;
5531 break;
5532 case UNSPEC_TLS_IE:
5533 suffix = "@tlsie", pcrel = true;
5534 break;
5535 case UNSPEC_TLS_OFF:
5536 if (XVECLEN (x, 0) == 2)
5537 base = XVECEXP (x, 0, 1);
5538 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5539 || (!flag_pic && !base))
5540 suffix = "@tpoff";
5541 else
5542 suffix = "@dtpoff";
5543 break;
5544 default:
5545 suffix = "@invalid";
5546 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
5547 break;
5549 if (pcrel)
5550 fputs ("pcl,", file);
5551 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
5552 fputs (suffix, file);
5553 if (base)
5554 arc_output_pic_addr_const (file, base, code);
5555 break;
5557 default:
5558 output_operand_lossage ("invalid expression as operand");
5562 #define SYMBOLIC_CONST(X) \
5563 (GET_CODE (X) == SYMBOL_REF \
5564 || GET_CODE (X) == LABEL_REF \
5565 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5567 /* Emit insns to move operands[1] into operands[0]. */
5569 static void
5570 prepare_pic_move (rtx *operands, machine_mode)
5572 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])
5573 && flag_pic)
5574 operands[1] = force_reg (Pmode, operands[1]);
5575 else
5577 rtx temp = (reload_in_progress ? operands[0]
5578 : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX);
5579 operands[1] = arc_legitimize_pic_address (operands[1], temp);
5584 /* The function returning the number of words, at the beginning of an
5585 argument, must be put in registers. The returned value must be
5586 zero for arguments that are passed entirely in registers or that
5587 are entirely pushed on the stack.
5589 On some machines, certain arguments must be passed partially in
5590 registers and partially in memory. On these machines, typically
5591 the first N words of arguments are passed in registers, and the
5592 rest on the stack. If a multi-word argument (a `double' or a
5593 structure) crosses that boundary, its first few words must be
5594 passed in registers and the rest must be pushed. This function
5595 tells the compiler when this occurs, and how many of the words
5596 should go in registers.
5598 `FUNCTION_ARG' for these arguments should return the first register
5599 to be used by the caller for this argument; likewise
5600 `FUNCTION_INCOMING_ARG', for the called function.
5602 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5604 /* If REGNO is the least arg reg available then what is the total number of arg
5605 regs available. */
5606 #define GPR_REST_ARG_REGS(REGNO) \
5607 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5609 /* Since arc parm regs are contiguous. */
5610 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5612 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5614 static int
5615 arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
5616 tree type, bool named ATTRIBUTE_UNUSED)
5618 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5619 int bytes = (mode == BLKmode
5620 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5621 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5622 int arg_num = *cum;
5623 int ret;
5625 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5626 ret = GPR_REST_ARG_REGS (arg_num);
5628 /* ICEd at function.c:2361, and ret is copied to data->partial */
5629 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
5631 return ret;
5634 /* This function is used to control a function argument is passed in a
5635 register, and which register.
5637 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5638 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5639 all of the previous arguments so far passed in registers; MODE, the
5640 machine mode of the argument; TYPE, the data type of the argument
5641 as a tree node or 0 if that is not known (which happens for C
5642 support library functions); and NAMED, which is 1 for an ordinary
5643 argument and 0 for nameless arguments that correspond to `...' in
5644 the called function's prototype.
5646 The returned value should either be a `reg' RTX for the hard
5647 register in which to pass the argument, or zero to pass the
5648 argument on the stack.
5650 For machines like the Vax and 68000, where normally all arguments
5651 are pushed, zero suffices as a definition.
5653 The usual way to make the ANSI library `stdarg.h' work on a machine
5654 where some arguments are usually passed in registers, is to cause
5655 nameless arguments to be passed on the stack instead. This is done
5656 by making the function return 0 whenever NAMED is 0.
5658 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5659 definition of this function to determine if this argument is of a
5660 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5661 is not defined and the function returns non-zero for such an
5662 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5663 defined, the argument will be computed in the stack and then loaded
5664 into a register.
5666 The function is used to implement macro FUNCTION_ARG. */
5667 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5668 and the rest are pushed. */
5670 static rtx
5671 arc_function_arg (cumulative_args_t cum_v,
5672 machine_mode mode,
5673 const_tree type ATTRIBUTE_UNUSED,
5674 bool named ATTRIBUTE_UNUSED)
5676 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5677 int arg_num = *cum;
5678 rtx ret;
5679 const char *debstr ATTRIBUTE_UNUSED;
5681 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5682 /* Return a marker for use in the call instruction. */
5683 if (mode == VOIDmode)
5685 ret = const0_rtx;
5686 debstr = "<0>";
5688 else if (GPR_REST_ARG_REGS (arg_num) > 0)
5690 ret = gen_rtx_REG (mode, arg_num);
5691 debstr = reg_names [arg_num];
5693 else
5695 ret = NULL_RTX;
5696 debstr = "memory";
5698 return ret;
5701 /* The function to update the summarizer variable *CUM to advance past
5702 an argument in the argument list. The values MODE, TYPE and NAMED
5703 describe that argument. Once this is done, the variable *CUM is
5704 suitable for analyzing the *following* argument with
5705 `FUNCTION_ARG', etc.
5707 This function need not do anything if the argument in question was
5708 passed on the stack. The compiler knows how to track the amount of
5709 stack space used for arguments without any special help.
5711 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5712 /* For the ARC: the cum set here is passed on to function_arg where we
5713 look at its value and say which reg to use. Strategy: advance the
5714 regnumber here till we run out of arg regs, then set *cum to last
5715 reg. In function_arg, since *cum > last arg reg we would return 0
5716 and thus the arg will end up on the stack. For straddling args of
5717 course function_arg_partial_nregs will come into play. */
5719 static void
5720 arc_function_arg_advance (cumulative_args_t cum_v,
5721 machine_mode mode,
5722 const_tree type,
5723 bool named ATTRIBUTE_UNUSED)
5725 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5726 int bytes = (mode == BLKmode
5727 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5728 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5729 int i;
5731 if (words)
5732 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
5733 for (i = 0; i < words; i++)
5734 *cum = ARC_NEXT_ARG_REG (*cum);
5738 /* Define how to find the value returned by a function.
5739 VALTYPE is the data type of the value (as a tree).
5740 If the precise function being called is known, FN_DECL_OR_TYPE is its
5741 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5743 static rtx
5744 arc_function_value (const_tree valtype,
5745 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
5746 bool outgoing ATTRIBUTE_UNUSED)
5748 machine_mode mode = TYPE_MODE (valtype);
5749 int unsignedp ATTRIBUTE_UNUSED;
5751 unsignedp = TYPE_UNSIGNED (valtype);
5752 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
5753 PROMOTE_MODE (mode, unsignedp, valtype);
5754 return gen_rtx_REG (mode, 0);
5757 /* Returns the return address that is used by builtin_return_address. */
5760 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
5762 if (count != 0)
5763 return const0_rtx;
5765 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
5768 /* Determine if a given RTX is a valid constant. We already know this
5769 satisfies CONSTANT_P. */
5771 bool
5772 arc_legitimate_constant_p (machine_mode mode, rtx x)
5774 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
5775 return false;
5777 if (!flag_pic && mode != Pmode)
5778 return true;
5780 switch (GET_CODE (x))
5782 case CONST:
5783 if (flag_pic)
5785 if (arc_legitimate_pic_addr_p (x))
5786 return true;
5788 return arc_legitimate_constant_p (mode, XEXP (x, 0));
5790 case SYMBOL_REF:
5791 if (SYMBOL_REF_TLS_MODEL (x))
5792 return false;
5793 /* Fall through. */
5794 case LABEL_REF:
5795 if (flag_pic)
5796 return false;
5797 /* Fall through. */
5798 case CONST_INT:
5799 case CONST_DOUBLE:
5800 return true;
5802 case NEG:
5803 return arc_legitimate_constant_p (mode, XEXP (x, 0));
5805 case PLUS:
5806 case MINUS:
5808 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
5809 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
5811 return (t1 && t2);
5814 case CONST_VECTOR:
5815 switch (mode)
5817 case E_V2HImode:
5818 return TARGET_PLUS_DMPY;
5819 case E_V2SImode:
5820 case E_V4HImode:
5821 return TARGET_PLUS_QMACW;
5822 default:
5823 return false;
5826 case UNSPEC:
5827 switch (XINT (x, 1))
5829 case UNSPEC_TLS_GD:
5830 case UNSPEC_TLS_OFF:
5831 case UNSPEC_TLS_IE:
5832 return true;
5833 default:
5834 /* Any other unspec ending here are pic related, hence the above
5835 constant pic address checking returned false. */
5836 return false;
5838 /* Fall through. */
5840 default:
5841 fatal_insn ("unrecognized supposed constant", x);
5844 gcc_unreachable ();
5847 static bool
5848 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
5850 if (RTX_OK_FOR_BASE_P (x, strict))
5851 return true;
5852 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
5853 return true;
5854 if (LEGITIMATE_SCALED_ADDRESS_P (mode, x, strict))
5855 return true;
5856 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
5857 return true;
5858 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
5859 return true;
5861 /* When we compile for size avoid const (@sym + offset)
5862 addresses. */
5863 if (!flag_pic && optimize_size && !reload_completed
5864 && (GET_CODE (x) == CONST)
5865 && (GET_CODE (XEXP (x, 0)) == PLUS)
5866 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
5867 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
5868 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
5870 rtx addend = XEXP (XEXP (x, 0), 1);
5871 gcc_assert (CONST_INT_P (addend));
5872 HOST_WIDE_INT offset = INTVAL (addend);
5874 /* Allow addresses having a large offset to pass. Anyhow they
5875 will end in a limm. */
5876 return !(offset > -1024 && offset < 1020);
5879 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
5881 return arc_legitimate_constant_p (mode, x);
5883 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
5884 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
5885 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
5886 return true;
5887 /* We're restricted here by the `st' insn. */
5888 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
5889 && GET_CODE (XEXP ((x), 1)) == PLUS
5890 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
5891 && legitimate_offset_address_p (QImode, XEXP (x, 1),
5892 TARGET_AUTO_MODIFY_REG, strict))
5893 return true;
5894 return false;
5897 /* Return true iff ADDR (a legitimate address expression)
5898 has an effect that depends on the machine mode it is used for. */
5900 static bool
5901 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
5903 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5904 which is valid for loads and stores, or a limm offset, which is valid for
5905 loads. Scaled indices are scaled by the access mode. */
5906 if (GET_CODE (addr) == PLUS
5907 && GET_CODE (XEXP ((addr), 0)) == MULT)
5908 return true;
5909 return false;
5912 /* Determine if it's legal to put X into the constant pool. */
5914 static bool
5915 arc_cannot_force_const_mem (machine_mode mode, rtx x)
5917 return !arc_legitimate_constant_p (mode, x);
5920 /* IDs for all the ARC builtins. */
5922 enum arc_builtin_id
5924 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5925 ARC_BUILTIN_ ## NAME,
5926 #include "builtins.def"
5927 #undef DEF_BUILTIN
5929 ARC_BUILTIN_COUNT
5932 struct GTY(()) arc_builtin_description
5934 enum insn_code icode;
5935 int n_args;
5936 tree fndecl;
5939 static GTY(()) struct arc_builtin_description
5940 arc_bdesc[ARC_BUILTIN_COUNT] =
5942 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
5943 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
5944 #include "builtins.def"
5945 #undef DEF_BUILTIN
5948 /* Transform UP into lowercase and write the result to LO.
5949 You must provide enough space for LO. Return LO. */
5951 static char*
5952 arc_tolower (char *lo, const char *up)
5954 char *lo0 = lo;
5956 for (; *up; up++, lo++)
5957 *lo = TOLOWER (*up);
5959 *lo = '\0';
5961 return lo0;
5964 /* Implement `TARGET_BUILTIN_DECL'. */
5966 static tree
5967 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
5969 if (id < ARC_BUILTIN_COUNT)
5970 return arc_bdesc[id].fndecl;
5972 return error_mark_node;
5975 static void
5976 arc_init_builtins (void)
5978 tree V4HI_type_node;
5979 tree V2SI_type_node;
5980 tree V2HI_type_node;
5982 /* Vector types based on HS SIMD elements. */
5983 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
5984 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
5985 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
5987 tree pcvoid_type_node
5988 = build_pointer_type (build_qualified_type (void_type_node,
5989 TYPE_QUAL_CONST));
5990 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
5991 V8HImode);
5993 tree void_ftype_void
5994 = build_function_type_list (void_type_node, NULL_TREE);
5995 tree int_ftype_int
5996 = build_function_type_list (integer_type_node, integer_type_node,
5997 NULL_TREE);
5998 tree int_ftype_pcvoid_int
5999 = build_function_type_list (integer_type_node, pcvoid_type_node,
6000 integer_type_node, NULL_TREE);
6001 tree void_ftype_usint_usint
6002 = build_function_type_list (void_type_node, long_unsigned_type_node,
6003 long_unsigned_type_node, NULL_TREE);
6004 tree int_ftype_int_int
6005 = build_function_type_list (integer_type_node, integer_type_node,
6006 integer_type_node, NULL_TREE);
6007 tree usint_ftype_usint
6008 = build_function_type_list (long_unsigned_type_node,
6009 long_unsigned_type_node, NULL_TREE);
6010 tree void_ftype_usint
6011 = build_function_type_list (void_type_node, long_unsigned_type_node,
6012 NULL_TREE);
6013 tree int_ftype_void
6014 = build_function_type_list (integer_type_node, void_type_node,
6015 NULL_TREE);
6016 tree void_ftype_int
6017 = build_function_type_list (void_type_node, integer_type_node,
6018 NULL_TREE);
6019 tree int_ftype_short
6020 = build_function_type_list (integer_type_node, short_integer_type_node,
6021 NULL_TREE);
6023 /* Old ARC SIMD types. */
6024 tree v8hi_ftype_v8hi_v8hi
6025 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6026 V8HI_type_node, NULL_TREE);
6027 tree v8hi_ftype_v8hi_int
6028 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6029 integer_type_node, NULL_TREE);
6030 tree v8hi_ftype_v8hi_int_int
6031 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6032 integer_type_node, integer_type_node,
6033 NULL_TREE);
6034 tree void_ftype_v8hi_int_int
6035 = build_function_type_list (void_type_node, V8HI_type_node,
6036 integer_type_node, integer_type_node,
6037 NULL_TREE);
6038 tree void_ftype_v8hi_int_int_int
6039 = build_function_type_list (void_type_node, V8HI_type_node,
6040 integer_type_node, integer_type_node,
6041 integer_type_node, NULL_TREE);
6042 tree v8hi_ftype_int_int
6043 = build_function_type_list (V8HI_type_node, integer_type_node,
6044 integer_type_node, NULL_TREE);
6045 tree void_ftype_int_int
6046 = build_function_type_list (void_type_node, integer_type_node,
6047 integer_type_node, NULL_TREE);
6048 tree v8hi_ftype_v8hi
6049 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6050 NULL_TREE);
6051 /* ARCv2 SIMD types. */
6052 tree long_ftype_v4hi_v4hi
6053 = build_function_type_list (long_long_integer_type_node,
6054 V4HI_type_node, V4HI_type_node, NULL_TREE);
6055 tree int_ftype_v2hi_v2hi
6056 = build_function_type_list (integer_type_node,
6057 V2HI_type_node, V2HI_type_node, NULL_TREE);
6058 tree v2si_ftype_v2hi_v2hi
6059 = build_function_type_list (V2SI_type_node,
6060 V2HI_type_node, V2HI_type_node, NULL_TREE);
6061 tree v2hi_ftype_v2hi_v2hi
6062 = build_function_type_list (V2HI_type_node,
6063 V2HI_type_node, V2HI_type_node, NULL_TREE);
6064 tree v2si_ftype_v2si_v2si
6065 = build_function_type_list (V2SI_type_node,
6066 V2SI_type_node, V2SI_type_node, NULL_TREE);
6067 tree v4hi_ftype_v4hi_v4hi
6068 = build_function_type_list (V4HI_type_node,
6069 V4HI_type_node, V4HI_type_node, NULL_TREE);
6070 tree long_ftype_v2si_v2hi
6071 = build_function_type_list (long_long_integer_type_node,
6072 V2SI_type_node, V2HI_type_node, NULL_TREE);
6074 /* Add the builtins. */
6075 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6077 int id = ARC_BUILTIN_ ## NAME; \
6078 const char *Name = "__builtin_arc_" #NAME; \
6079 char *name = (char*) alloca (1 + strlen (Name)); \
6081 gcc_assert (id < ARC_BUILTIN_COUNT); \
6082 if (MASK) \
6083 arc_bdesc[id].fndecl \
6084 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6085 BUILT_IN_MD, NULL, NULL_TREE); \
6087 #include "builtins.def"
6088 #undef DEF_BUILTIN
6091 /* Helper to expand __builtin_arc_aligned (void* val, int
6092 alignval). */
6094 static rtx
6095 arc_expand_builtin_aligned (tree exp)
6097 tree arg0 = CALL_EXPR_ARG (exp, 0);
6098 tree arg1 = CALL_EXPR_ARG (exp, 1);
6099 fold (arg1);
6100 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6101 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6103 if (!CONST_INT_P (op1))
6105 /* If we can't fold the alignment to a constant integer
6106 whilst optimizing, this is probably a user error. */
6107 if (optimize)
6108 warning (0, "__builtin_arc_aligned with non-constant alignment");
6110 else
6112 HOST_WIDE_INT alignTest = INTVAL (op1);
6113 /* Check alignTest is positive, and a power of two. */
6114 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6116 error ("invalid alignment value for __builtin_arc_aligned");
6117 return NULL_RTX;
6120 if (CONST_INT_P (op0))
6122 HOST_WIDE_INT pnt = INTVAL (op0);
6124 if ((pnt & (alignTest - 1)) == 0)
6125 return const1_rtx;
6127 else
6129 unsigned align = get_pointer_alignment (arg0);
6130 unsigned numBits = alignTest * BITS_PER_UNIT;
6132 if (align && align >= numBits)
6133 return const1_rtx;
6134 /* Another attempt to ascertain alignment. Check the type
6135 we are pointing to. */
6136 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6137 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6138 return const1_rtx;
6142 /* Default to false. */
6143 return const0_rtx;
6146 /* Helper arc_expand_builtin, generates a pattern for the given icode
6147 and arguments. */
6149 static rtx_insn *
6150 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6152 switch (insn_data[icode].n_generator_args)
6154 case 0:
6155 return GEN_FCN (icode) ();
6156 case 1:
6157 return GEN_FCN (icode) (arg[0]);
6158 case 2:
6159 return GEN_FCN (icode) (arg[0], arg[1]);
6160 case 3:
6161 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6162 case 4:
6163 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6164 case 5:
6165 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6166 default:
6167 gcc_unreachable ();
6171 /* Expand an expression EXP that calls a built-in function,
6172 with result going to TARGET if that's convenient
6173 (and in mode MODE if that's convenient).
6174 SUBTARGET may be used as the target for computing one of EXP's operands.
6175 IGNORE is nonzero if the value is to be ignored. */
6177 static rtx
6178 arc_expand_builtin (tree exp,
6179 rtx target,
6180 rtx subtarget ATTRIBUTE_UNUSED,
6181 machine_mode mode ATTRIBUTE_UNUSED,
6182 int ignore ATTRIBUTE_UNUSED)
6184 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6185 unsigned int id = DECL_FUNCTION_CODE (fndecl);
6186 const struct arc_builtin_description *d = &arc_bdesc[id];
6187 int i, j, n_args = call_expr_nargs (exp);
6188 rtx pat = NULL_RTX;
6189 rtx xop[5];
6190 enum insn_code icode = d->icode;
6191 machine_mode tmode = insn_data[icode].operand[0].mode;
6192 int nonvoid;
6193 tree arg0;
6194 tree arg1;
6195 tree arg2;
6196 tree arg3;
6197 rtx op0;
6198 rtx op1;
6199 rtx op2;
6200 rtx op3;
6201 rtx op4;
6202 machine_mode mode0;
6203 machine_mode mode1;
6204 machine_mode mode2;
6205 machine_mode mode3;
6206 machine_mode mode4;
6208 if (id >= ARC_BUILTIN_COUNT)
6209 internal_error ("bad builtin fcode");
6211 /* 1st part: Expand special builtins. */
6212 switch (id)
6214 case ARC_BUILTIN_NOP:
6215 emit_insn (gen_nopv ());
6216 return NULL_RTX;
6218 case ARC_BUILTIN_RTIE:
6219 case ARC_BUILTIN_SYNC:
6220 case ARC_BUILTIN_BRK:
6221 case ARC_BUILTIN_SWI:
6222 case ARC_BUILTIN_UNIMP_S:
6223 gcc_assert (icode != 0);
6224 emit_insn (GEN_FCN (icode) (const1_rtx));
6225 return NULL_RTX;
6227 case ARC_BUILTIN_ALIGNED:
6228 return arc_expand_builtin_aligned (exp);
6230 case ARC_BUILTIN_CLRI:
6231 target = gen_reg_rtx (SImode);
6232 emit_insn (gen_clri (target, const1_rtx));
6233 return target;
6235 case ARC_BUILTIN_TRAP_S:
6236 case ARC_BUILTIN_SLEEP:
6237 arg0 = CALL_EXPR_ARG (exp, 0);
6238 fold (arg0);
6239 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6241 if (!CONST_INT_P (op0) || !satisfies_constraint_L (op0))
6243 error ("builtin operand should be an unsigned 6-bit value");
6244 return NULL_RTX;
6246 gcc_assert (icode != 0);
6247 emit_insn (GEN_FCN (icode) (op0));
6248 return NULL_RTX;
6250 case ARC_BUILTIN_VDORUN:
6251 case ARC_BUILTIN_VDIRUN:
6252 arg0 = CALL_EXPR_ARG (exp, 0);
6253 arg1 = CALL_EXPR_ARG (exp, 1);
6254 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6255 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6257 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
6259 mode0 = insn_data[icode].operand[1].mode;
6260 mode1 = insn_data[icode].operand[2].mode;
6262 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6263 op0 = copy_to_mode_reg (mode0, op0);
6265 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6266 op1 = copy_to_mode_reg (mode1, op1);
6268 pat = GEN_FCN (icode) (target, op0, op1);
6269 if (!pat)
6270 return NULL_RTX;
6272 emit_insn (pat);
6273 return NULL_RTX;
6275 case ARC_BUILTIN_VDIWR:
6276 case ARC_BUILTIN_VDOWR:
6277 arg0 = CALL_EXPR_ARG (exp, 0);
6278 arg1 = CALL_EXPR_ARG (exp, 1);
6279 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6280 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6282 if (!CONST_INT_P (op0)
6283 || !(UNSIGNED_INT3 (INTVAL (op0))))
6284 error ("operand 1 should be an unsigned 3-bit immediate");
6286 mode1 = insn_data[icode].operand[1].mode;
6288 if (icode == CODE_FOR_vdiwr_insn)
6289 target = gen_rtx_REG (SImode,
6290 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
6291 else if (icode == CODE_FOR_vdowr_insn)
6292 target = gen_rtx_REG (SImode,
6293 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
6294 else
6295 gcc_unreachable ();
6297 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6298 op1 = copy_to_mode_reg (mode1, op1);
6300 pat = GEN_FCN (icode) (target, op1);
6301 if (!pat)
6302 return NULL_RTX;
6304 emit_insn (pat);
6305 return NULL_RTX;
6307 case ARC_BUILTIN_VASRW:
6308 case ARC_BUILTIN_VSR8:
6309 case ARC_BUILTIN_VSR8AW:
6310 arg0 = CALL_EXPR_ARG (exp, 0);
6311 arg1 = CALL_EXPR_ARG (exp, 1);
6312 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6313 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6314 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6316 target = gen_reg_rtx (V8HImode);
6317 mode0 = insn_data[icode].operand[1].mode;
6318 mode1 = insn_data[icode].operand[2].mode;
6320 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6321 op0 = copy_to_mode_reg (mode0, op0);
6323 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6324 || !(UNSIGNED_INT3 (INTVAL (op1))))
6325 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6327 pat = GEN_FCN (icode) (target, op0, op1, op2);
6328 if (!pat)
6329 return NULL_RTX;
6331 emit_insn (pat);
6332 return target;
6334 case ARC_BUILTIN_VLD32WH:
6335 case ARC_BUILTIN_VLD32WL:
6336 case ARC_BUILTIN_VLD64:
6337 case ARC_BUILTIN_VLD32:
6338 rtx src_vreg;
6339 icode = d->icode;
6340 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6341 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6342 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6344 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6345 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6346 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6347 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6349 /* target <- src vreg. */
6350 emit_insn (gen_move_insn (target, src_vreg));
6352 /* target <- vec_concat: target, mem (Ib, u8). */
6353 mode0 = insn_data[icode].operand[3].mode;
6354 mode1 = insn_data[icode].operand[1].mode;
6356 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
6357 || !(UNSIGNED_INT3 (INTVAL (op0))))
6358 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6360 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6361 || !(UNSIGNED_INT8 (INTVAL (op1))))
6362 error ("operand 2 should be an unsigned 8-bit value");
6364 pat = GEN_FCN (icode) (target, op1, op2, op0);
6365 if (!pat)
6366 return NULL_RTX;
6368 emit_insn (pat);
6369 return target;
6371 case ARC_BUILTIN_VLD64W:
6372 case ARC_BUILTIN_VLD128:
6373 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
6374 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6376 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6377 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6378 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6380 /* target <- src vreg. */
6381 target = gen_reg_rtx (V8HImode);
6383 /* target <- vec_concat: target, mem (Ib, u8). */
6384 mode0 = insn_data[icode].operand[1].mode;
6385 mode1 = insn_data[icode].operand[2].mode;
6386 mode2 = insn_data[icode].operand[3].mode;
6388 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6389 || !(UNSIGNED_INT3 (INTVAL (op1))))
6390 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6392 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
6393 || !(UNSIGNED_INT8 (INTVAL (op2))))
6394 error ("operand 2 should be an unsigned 8-bit value");
6396 pat = GEN_FCN (icode) (target, op0, op1, op2);
6398 if (!pat)
6399 return NULL_RTX;
6401 emit_insn (pat);
6402 return target;
6404 case ARC_BUILTIN_VST128:
6405 case ARC_BUILTIN_VST64:
6406 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
6407 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6408 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6410 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6411 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6412 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6413 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6415 mode0 = insn_data[icode].operand[0].mode;
6416 mode1 = insn_data[icode].operand[1].mode;
6417 mode2 = insn_data[icode].operand[2].mode;
6418 mode3 = insn_data[icode].operand[3].mode;
6420 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6421 || !(UNSIGNED_INT3 (INTVAL (op1))))
6422 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6424 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6425 || !(UNSIGNED_INT8 (INTVAL (op2))))
6426 error ("operand 3 should be an unsigned 8-bit value");
6428 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6429 op3 = copy_to_mode_reg (mode3, op3);
6431 pat = GEN_FCN (icode) (op0, op1, op2, op3);
6432 if (!pat)
6433 return NULL_RTX;
6435 emit_insn (pat);
6436 return NULL_RTX;
6438 case ARC_BUILTIN_VST16_N:
6439 case ARC_BUILTIN_VST32_N:
6440 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6441 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
6442 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
6443 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
6445 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
6446 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6447 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6448 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6449 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6451 mode0 = insn_data[icode].operand[0].mode;
6452 mode2 = insn_data[icode].operand[2].mode;
6453 mode3 = insn_data[icode].operand[3].mode;
6454 mode4 = insn_data[icode].operand[4].mode;
6456 /* Do some correctness checks for the operands. */
6457 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
6458 || !(UNSIGNED_INT8 (INTVAL (op0))))
6459 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6461 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6462 || !(UNSIGNED_INT3 (INTVAL (op2))))
6463 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6465 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6466 op3 = copy_to_mode_reg (mode3, op3);
6468 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
6469 || !(UNSIGNED_INT3 (INTVAL (op4))))
6470 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6471 else if (icode == CODE_FOR_vst32_n_insn
6472 && ((INTVAL (op4) % 2) != 0))
6473 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6475 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
6476 if (!pat)
6477 return NULL_RTX;
6479 emit_insn (pat);
6480 return NULL_RTX;
6482 default:
6483 break;
6486 /* 2nd part: Expand regular builtins. */
6487 if (icode == 0)
6488 internal_error ("bad builtin fcode");
6490 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6491 j = 0;
6493 if (nonvoid)
6495 if (target == NULL_RTX
6496 || GET_MODE (target) != tmode
6497 || !insn_data[icode].operand[0].predicate (target, tmode))
6499 target = gen_reg_rtx (tmode);
6501 xop[j++] = target;
6504 gcc_assert (n_args <= 4);
6505 for (i = 0; i < n_args; i++, j++)
6507 tree arg = CALL_EXPR_ARG (exp, i);
6508 machine_mode mode = insn_data[icode].operand[j].mode;
6509 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
6510 machine_mode opmode = GET_MODE (op);
6511 char c = insn_data[icode].operand[j].constraint[0];
6513 /* SIMD extension requires exact immediate operand match. */
6514 if ((id > ARC_BUILTIN_SIMD_BEGIN)
6515 && (id < ARC_BUILTIN_SIMD_END)
6516 && (c != 'v')
6517 && (c != 'r'))
6519 if (!CONST_INT_P (op))
6520 error ("builtin requires an immediate for operand %d", j);
6521 switch (c)
6523 case 'L':
6524 if (!satisfies_constraint_L (op))
6525 error ("operand %d should be a 6 bit unsigned immediate", j);
6526 break;
6527 case 'P':
6528 if (!satisfies_constraint_P (op))
6529 error ("operand %d should be a 8 bit unsigned immediate", j);
6530 break;
6531 case 'K':
6532 if (!satisfies_constraint_K (op))
6533 error ("operand %d should be a 3 bit unsigned immediate", j);
6534 break;
6535 default:
6536 error ("unknown builtin immediate operand type for operand %d",
6541 if (CONST_INT_P (op))
6542 opmode = mode;
6544 if ((opmode == SImode) && (mode == HImode))
6546 opmode = HImode;
6547 op = gen_lowpart (HImode, op);
6550 /* In case the insn wants input operands in modes different from
6551 the result, abort. */
6552 gcc_assert (opmode == mode || opmode == VOIDmode);
6554 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
6555 op = copy_to_mode_reg (mode, op);
6557 xop[j] = op;
6560 pat = apply_GEN_FCN (icode, xop);
6561 if (pat == NULL_RTX)
6562 return NULL_RTX;
6564 emit_insn (pat);
6566 if (nonvoid)
6567 return target;
6568 else
6569 return const0_rtx;
6572 /* Returns true if the operands[opno] is a valid compile-time constant to be
6573 used as register number in the code for builtins. Else it flags an error
6574 and returns false. */
6576 bool
6577 check_if_valid_regno_const (rtx *operands, int opno)
6580 switch (GET_CODE (operands[opno]))
6582 case SYMBOL_REF :
6583 case CONST :
6584 case CONST_INT :
6585 return true;
6586 default:
6587 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6588 break;
6590 return false;
6593 /* Check that after all the constant folding, whether the operand to
6594 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6596 bool
6597 check_if_valid_sleep_operand (rtx *operands, int opno)
6599 switch (GET_CODE (operands[opno]))
6601 case CONST :
6602 case CONST_INT :
6603 if( UNSIGNED_INT6 (INTVAL (operands[opno])))
6604 return true;
6605 /* FALLTHRU */
6606 default:
6607 fatal_error (input_location,
6608 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6609 break;
6611 return false;
6614 /* Return true if it is ok to make a tail-call to DECL. */
6616 static bool
6617 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
6618 tree exp ATTRIBUTE_UNUSED)
6620 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6621 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
6622 return false;
6624 /* Everything else is ok. */
6625 return true;
6628 /* Output code to add DELTA to the first argument, and then jump
6629 to FUNCTION. Used for C++ multiple inheritance. */
6631 static void
6632 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6633 HOST_WIDE_INT delta,
6634 HOST_WIDE_INT vcall_offset,
6635 tree function)
6637 int mi_delta = delta;
6638 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
6639 int shift = 0;
6640 int this_regno
6641 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
6642 rtx fnaddr;
6644 if (mi_delta < 0)
6645 mi_delta = - mi_delta;
6647 /* Add DELTA. When possible use a plain add, otherwise load it into
6648 a register first. */
6650 while (mi_delta != 0)
6652 if ((mi_delta & (3 << shift)) == 0)
6653 shift += 2;
6654 else
6656 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
6657 mi_op, reg_names[this_regno], reg_names[this_regno],
6658 mi_delta & (0xff << shift));
6659 mi_delta &= ~(0xff << shift);
6660 shift += 8;
6664 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6665 if (vcall_offset != 0)
6667 /* ld r12,[this] --> temp = *this
6668 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6669 ld r12,[r12]
6670 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6671 asm_fprintf (file, "\tld\t%s, [%s]\n",
6672 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
6673 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
6674 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
6675 asm_fprintf (file, "\tld\t%s, [%s]\n",
6676 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
6677 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
6678 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
6681 fnaddr = XEXP (DECL_RTL (function), 0);
6683 if (arc_is_longcall_p (fnaddr))
6685 if (flag_pic)
6687 asm_fprintf (file, "\tld\t%s, [pcl, @",
6688 ARC_TEMP_SCRATCH_REG);
6689 assemble_name (file, XSTR (fnaddr, 0));
6690 fputs ("@gotpc]\n", file);
6691 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
6693 else
6695 fputs ("\tj\t@", file);
6696 assemble_name (file, XSTR (fnaddr, 0));
6699 else
6701 fputs ("\tb\t@", file);
6702 assemble_name (file, XSTR (fnaddr, 0));
6703 if (flag_pic)
6704 fputs ("@plt\n", file);
6706 fputc ('\n', file);
6709 /* Return true if a 32 bit "long_call" should be generated for
6710 this calling SYM_REF. We generate a long_call if the function:
6712 a. has an __attribute__((long call))
6713 or b. the -mlong-calls command line switch has been specified
6715 However we do not generate a long call if the function has an
6716 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6718 This function will be called by C fragments contained in the machine
6719 description file. */
6721 bool
6722 arc_is_longcall_p (rtx sym_ref)
6724 if (GET_CODE (sym_ref) != SYMBOL_REF)
6725 return false;
6727 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
6728 || (TARGET_LONG_CALLS_SET
6729 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
6730 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6734 /* Likewise for short calls. */
6736 bool
6737 arc_is_shortcall_p (rtx sym_ref)
6739 if (GET_CODE (sym_ref) != SYMBOL_REF)
6740 return false;
6742 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
6743 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
6744 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
6745 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6749 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6751 static bool
6752 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6754 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
6755 return true;
6756 else
6758 HOST_WIDE_INT size = int_size_in_bytes (type);
6759 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
6764 /* This was in rtlanal.c, and can go in there when we decide we want
6765 to submit the change for inclusion in the GCC tree. */
6766 /* Like note_stores, but allow the callback to have side effects on the rtl
6767 (like the note_stores of yore):
6768 Call FUN on each register or MEM that is stored into or clobbered by X.
6769 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6770 ignored by note_stores, but passed to FUN.
6771 FUN may alter parts of the RTL.
6773 FUN receives three arguments:
6774 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6775 2. the SET or CLOBBER rtx that does the store,
6776 3. the pointer DATA provided to note_stores.
6778 If the item being stored in or clobbered is a SUBREG of a hard register,
6779 the SUBREG will be passed. */
6781 /* For now. */ static
6782 void
6783 walk_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
6785 int i;
6787 if (GET_CODE (x) == COND_EXEC)
6788 x = COND_EXEC_CODE (x);
6790 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
6792 rtx dest = SET_DEST (x);
6794 while ((GET_CODE (dest) == SUBREG
6795 && (!REG_P (SUBREG_REG (dest))
6796 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
6797 || GET_CODE (dest) == ZERO_EXTRACT
6798 || GET_CODE (dest) == STRICT_LOW_PART)
6799 dest = XEXP (dest, 0);
6801 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6802 each of whose first operand is a register. */
6803 if (GET_CODE (dest) == PARALLEL)
6805 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
6806 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
6807 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
6809 else
6810 (*fun) (dest, x, data);
6813 else if (GET_CODE (x) == PARALLEL)
6814 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6815 walk_stores (XVECEXP (x, 0, i), fun, data);
6818 static bool
6819 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
6820 machine_mode mode ATTRIBUTE_UNUSED,
6821 const_tree type,
6822 bool named ATTRIBUTE_UNUSED)
6824 return (type != 0
6825 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
6826 || TREE_ADDRESSABLE (type)));
6829 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6831 static bool
6832 arc_can_use_doloop_p (const widest_int &iterations, const widest_int &,
6833 unsigned int loop_depth, bool entered_at_top)
6835 if (loop_depth > 1)
6836 return false;
6837 /* Setting up the loop with two sr instructions costs 6 cycles. */
6838 if (TARGET_ARC700
6839 && !entered_at_top
6840 && wi::gtu_p (iterations, 0)
6841 && wi::leu_p (iterations, flag_pic ? 6 : 3))
6842 return false;
6843 return true;
6846 /* NULL if INSN insn is valid within a low-overhead loop.
6847 Otherwise return why doloop cannot be applied. */
6849 static const char *
6850 arc_invalid_within_doloop (const rtx_insn *insn)
6852 if (CALL_P (insn))
6853 return "Function call in the loop.";
6854 return NULL;
6857 /* Return true if a load instruction (CONSUMER) uses the same address as a
6858 store instruction (PRODUCER). This function is used to avoid st/ld
6859 address hazard in ARC700 cores. */
6860 bool
6861 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
6863 rtx in_set, out_set;
6864 rtx out_addr, in_addr;
6866 if (!producer)
6867 return false;
6869 if (!consumer)
6870 return false;
6872 /* Peel the producer and the consumer for the address. */
6873 out_set = single_set (producer);
6874 if (out_set)
6876 out_addr = SET_DEST (out_set);
6877 if (!out_addr)
6878 return false;
6879 if (GET_CODE (out_addr) == ZERO_EXTEND
6880 || GET_CODE (out_addr) == SIGN_EXTEND)
6881 out_addr = XEXP (out_addr, 0);
6883 if (!MEM_P (out_addr))
6884 return false;
6886 in_set = single_set (consumer);
6887 if (in_set)
6889 in_addr = SET_SRC (in_set);
6890 if (!in_addr)
6891 return false;
6892 if (GET_CODE (in_addr) == ZERO_EXTEND
6893 || GET_CODE (in_addr) == SIGN_EXTEND)
6894 in_addr = XEXP (in_addr, 0);
6896 if (!MEM_P (in_addr))
6897 return false;
6898 /* Get rid of the MEM and check if the addresses are
6899 equivalent. */
6900 in_addr = XEXP (in_addr, 0);
6901 out_addr = XEXP (out_addr, 0);
6903 return exp_equiv_p (in_addr, out_addr, 0, true);
6906 return false;
6909 /* The same functionality as arc_hazard. It is called in machine
6910 reorg before any other optimization. Hence, the NOP size is taken
6911 into account when doing branch shortening. */
6913 static void
6914 workaround_arc_anomaly (void)
6916 rtx_insn *insn, *succ0;
6918 /* For any architecture: call arc_hazard here. */
6919 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6921 succ0 = next_real_insn (insn);
6922 if (arc_hazard (insn, succ0))
6924 emit_insn_before (gen_nopv (), succ0);
6928 if (TARGET_ARC700)
6930 rtx_insn *succ1;
6932 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6934 succ0 = next_real_insn (insn);
6935 if (arc_store_addr_hazard_p (insn, succ0))
6937 emit_insn_after (gen_nopv (), insn);
6938 emit_insn_after (gen_nopv (), insn);
6939 continue;
6942 /* Avoid adding nops if the instruction between the ST and LD is
6943 a call or jump. */
6944 succ1 = next_real_insn (succ0);
6945 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0)
6946 && arc_store_addr_hazard_p (insn, succ1))
6947 emit_insn_after (gen_nopv (), insn);
6952 static int arc_reorg_in_progress = 0;
6954 /* ARC's machince specific reorg function. */
6956 static void
6957 arc_reorg (void)
6959 rtx_insn *insn;
6960 rtx pattern;
6961 rtx pc_target;
6962 long offset;
6963 int changed;
6965 workaround_arc_anomaly ();
6967 cfun->machine->arc_reorg_started = 1;
6968 arc_reorg_in_progress = 1;
6970 /* Link up loop ends with their loop start. */
6972 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
6973 if (GET_CODE (insn) == JUMP_INSN
6974 && recog_memoized (insn) == CODE_FOR_doloop_end_i)
6976 rtx_insn *top_label
6977 = as_a <rtx_insn *> (XEXP (XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 1), 0));
6978 rtx num = GEN_INT (CODE_LABEL_NUMBER (top_label));
6979 rtx_insn *lp, *prev = prev_nonnote_insn (top_label);
6980 rtx_insn *lp_simple = NULL;
6981 rtx_insn *next = NULL;
6982 rtx op0 = XEXP (XVECEXP (PATTERN (insn), 0, 1), 0);
6983 int seen_label = 0;
6985 for (lp = prev;
6986 (lp && NONJUMP_INSN_P (lp)
6987 && recog_memoized (lp) != CODE_FOR_doloop_begin_i);
6988 lp = prev_nonnote_insn (lp))
6990 if (!lp || !NONJUMP_INSN_P (lp)
6991 || dead_or_set_regno_p (lp, LP_COUNT))
6993 HOST_WIDE_INT loop_end_id
6994 = INTVAL (XEXP (XVECEXP (PATTERN (insn), 0, 4), 0));
6996 for (prev = next = insn, lp = NULL ; prev || next;)
6998 if (prev)
7000 if (NONJUMP_INSN_P (prev)
7001 && recog_memoized (prev) == CODE_FOR_doloop_begin_i
7002 && (INTVAL (XEXP (XVECEXP (PATTERN (prev), 0, 5), 0))
7003 == loop_end_id))
7005 lp = prev;
7006 break;
7008 else if (LABEL_P (prev))
7009 seen_label = 1;
7010 prev = prev_nonnote_insn (prev);
7012 if (next)
7014 if (NONJUMP_INSN_P (next)
7015 && recog_memoized (next) == CODE_FOR_doloop_begin_i
7016 && (INTVAL (XEXP (XVECEXP (PATTERN (next), 0, 5), 0))
7017 == loop_end_id))
7019 lp = next;
7020 break;
7022 next = next_nonnote_insn (next);
7025 prev = NULL;
7027 else
7028 lp_simple = lp;
7029 if (lp && !dead_or_set_regno_p (lp, LP_COUNT))
7031 rtx begin_cnt = XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0);
7032 if (INTVAL (XEXP (XVECEXP (PATTERN (lp), 0, 4), 0)))
7033 /* The loop end insn has been duplicated. That can happen
7034 when there is a conditional block at the very end of
7035 the loop. */
7036 goto failure;
7037 /* If Register allocation failed to allocate to the right
7038 register, There is no point into teaching reload to
7039 fix this up with reloads, as that would cost more
7040 than using an ordinary core register with the
7041 doloop_fallback pattern. */
7042 if ((true_regnum (op0) != LP_COUNT || !REG_P (begin_cnt))
7043 /* Likewise, if the loop setup is evidently inside the loop,
7044 we loose. */
7045 || (!lp_simple && lp != next && !seen_label))
7047 remove_insn (lp);
7048 goto failure;
7050 /* It is common that the optimizers copy the loop count from
7051 another register, and doloop_begin_i is stuck with the
7052 source of the move. Making doloop_begin_i only accept "l"
7053 is nonsentical, as this then makes reload evict the pseudo
7054 used for the loop end. The underlying cause is that the
7055 optimizers don't understand that the register allocation for
7056 doloop_begin_i should be treated as part of the loop.
7057 Try to work around this problem by verifying the previous
7058 move exists. */
7059 if (true_regnum (begin_cnt) != LP_COUNT)
7061 rtx_insn *mov;
7062 rtx set, note;
7064 for (mov = prev_nonnote_insn (lp); mov;
7065 mov = prev_nonnote_insn (mov))
7067 if (!NONJUMP_INSN_P (mov))
7068 mov = 0;
7069 else if ((set = single_set (mov))
7070 && rtx_equal_p (SET_SRC (set), begin_cnt)
7071 && rtx_equal_p (SET_DEST (set), op0))
7072 break;
7074 if (mov)
7076 XEXP (XVECEXP (PATTERN (lp), 0 ,3), 0) = op0;
7077 note = find_regno_note (lp, REG_DEAD, REGNO (begin_cnt));
7078 if (note)
7079 remove_note (lp, note);
7081 else
7083 remove_insn (lp);
7084 goto failure;
7087 XEXP (XVECEXP (PATTERN (insn), 0, 4), 0) = num;
7088 XEXP (XVECEXP (PATTERN (lp), 0, 4), 0) = num;
7089 if (next == lp)
7090 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const2_rtx;
7091 else if (!lp_simple)
7092 XEXP (XVECEXP (PATTERN (lp), 0, 6), 0) = const1_rtx;
7093 else if (prev != lp)
7095 remove_insn (lp);
7096 add_insn_after (lp, prev, NULL);
7098 if (!lp_simple)
7100 XEXP (XVECEXP (PATTERN (lp), 0, 7), 0)
7101 = gen_rtx_LABEL_REF (Pmode, top_label);
7102 add_reg_note (lp, REG_LABEL_OPERAND, top_label);
7103 LABEL_NUSES (top_label)++;
7105 /* We can avoid tedious loop start / end setting for empty loops
7106 be merely setting the loop count to its final value. */
7107 if (next_active_insn (top_label) == insn)
7109 rtx lc_set
7110 = gen_rtx_SET (XEXP (XVECEXP (PATTERN (lp), 0, 3), 0),
7111 const0_rtx);
7113 rtx_insn *lc_set_insn = emit_insn_before (lc_set, insn);
7114 delete_insn (lp);
7115 delete_insn (insn);
7116 insn = lc_set_insn;
7118 /* If the loop is non-empty with zero length, we can't make it
7119 a zero-overhead loop. That can happen for empty asms. */
7120 else
7122 rtx_insn *scan;
7124 for (scan = top_label;
7125 (scan && scan != insn
7126 && (!NONJUMP_INSN_P (scan) || !get_attr_length (scan)));
7127 scan = NEXT_INSN (scan));
7128 if (scan == insn)
7130 remove_insn (lp);
7131 goto failure;
7135 else
7137 /* Sometimes the loop optimizer makes a complete hash of the
7138 loop. If it were only that the loop is not entered at the
7139 top, we could fix this up by setting LP_START with SR .
7140 However, if we can't find the loop begin were it should be,
7141 chances are that it does not even dominate the loop, but is
7142 inside the loop instead. Using SR there would kill
7143 performance.
7144 We use the doloop_fallback pattern here, which executes
7145 in two cycles on the ARC700 when predicted correctly. */
7146 failure:
7147 if (!REG_P (op0))
7149 rtx op3 = XEXP (XVECEXP (PATTERN (insn), 0, 5), 0);
7151 emit_insn_before (gen_move_insn (op3, op0), insn);
7152 PATTERN (insn)
7153 = gen_doloop_fallback_m (op3, JUMP_LABEL (insn), op0);
7155 else
7156 XVEC (PATTERN (insn), 0)
7157 = gen_rtvec (2, XVECEXP (PATTERN (insn), 0, 0),
7158 XVECEXP (PATTERN (insn), 0, 1));
7159 INSN_CODE (insn) = -1;
7164 /* FIXME: should anticipate ccfsm action, generate special patterns for
7165 to-be-deleted branches that have no delay slot and have at least the
7166 length of the size increase forced on other insns that are conditionalized.
7167 This can also have an insn_list inside that enumerates insns which are
7168 not actually conditionalized because the destinations are dead in the
7169 not-execute case.
7170 Could also tag branches that we want to be unaligned if they get no delay
7171 slot, or even ones that we don't want to do delay slot sheduling for
7172 because we can unalign them.
7174 However, there are cases when conditional execution is only possible after
7175 delay slot scheduling:
7177 - If a delay slot is filled with a nocond/set insn from above, the previous
7178 basic block can become elegible for conditional execution.
7179 - If a delay slot is filled with a nocond insn from the fall-through path,
7180 the branch with that delay slot can become eligble for conditional
7181 execution (however, with the same sort of data flow analysis that dbr
7182 does, we could have figured out before that we don't need to
7183 conditionalize this insn.)
7184 - If a delay slot insn is filled with an insn from the target, the
7185 target label gets its uses decremented (even deleted if falling to zero),
7186 thus possibly creating more condexec opportunities there.
7187 Therefore, we should still be prepared to apply condexec optimization on
7188 non-prepared branches if the size increase of conditionalized insns is no
7189 more than the size saved from eliminating the branch. An invocation option
7190 could also be used to reserve a bit of extra size for condbranches so that
7191 this'll work more often (could also test in arc_reorg if the block is
7192 'close enough' to be eligible for condexec to make this likely, and
7193 estimate required size increase). */
7194 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7195 if (TARGET_NO_BRCC_SET)
7196 return;
7200 init_insn_lengths();
7201 changed = 0;
7203 if (optimize > 1 && !TARGET_NO_COND_EXEC)
7205 arc_ifcvt ();
7206 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
7207 df_finish_pass ((flags & TODO_df_verify) != 0);
7210 /* Call shorten_branches to calculate the insn lengths. */
7211 shorten_branches (get_insns());
7212 cfun->machine->ccfsm_current_insn = NULL_RTX;
7214 if (!INSN_ADDRESSES_SET_P())
7215 fatal_error (input_location, "Insn addresses not set after shorten_branches");
7217 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7219 rtx label;
7220 enum attr_type insn_type;
7222 /* If a non-jump insn (or a casesi jump table), continue. */
7223 if (GET_CODE (insn) != JUMP_INSN ||
7224 GET_CODE (PATTERN (insn)) == ADDR_VEC
7225 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
7226 continue;
7228 /* If we already have a brcc, note if it is suitable for brcc_s.
7229 Be a bit generous with the brcc_s range so that we can take
7230 advantage of any code shortening from delay slot scheduling. */
7231 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
7233 rtx pat = PATTERN (insn);
7234 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
7235 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
7237 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7238 if ((offset >= -140 && offset < 140)
7239 && rtx_equal_p (XEXP (op, 1), const0_rtx)
7240 && compact_register_operand (XEXP (op, 0), VOIDmode)
7241 && equality_comparison_operator (op, VOIDmode))
7242 PUT_MODE (*ccp, CC_Zmode);
7243 else if (GET_MODE (*ccp) == CC_Zmode)
7244 PUT_MODE (*ccp, CC_ZNmode);
7245 continue;
7247 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
7248 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
7249 continue;
7251 /* OK. so we have a jump insn. */
7252 /* We need to check that it is a bcc. */
7253 /* Bcc => set (pc) (if_then_else ) */
7254 pattern = PATTERN (insn);
7255 if (GET_CODE (pattern) != SET
7256 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
7257 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
7258 continue;
7260 /* Now check if the jump is beyond the s9 range. */
7261 if (CROSSING_JUMP_P (insn))
7262 continue;
7263 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7265 if(offset > 253 || offset < -254)
7266 continue;
7268 pc_target = SET_SRC (pattern);
7270 /* Avoid FPU instructions. */
7271 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
7272 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
7273 continue;
7275 /* Now go back and search for the set cc insn. */
7277 label = XEXP (pc_target, 1);
7280 rtx pat;
7281 rtx_insn *scan, *link_insn = NULL;
7283 for (scan = PREV_INSN (insn);
7284 scan && GET_CODE (scan) != CODE_LABEL;
7285 scan = PREV_INSN (scan))
7287 if (! INSN_P (scan))
7288 continue;
7289 pat = PATTERN (scan);
7290 if (GET_CODE (pat) == SET
7291 && cc_register (SET_DEST (pat), VOIDmode))
7293 link_insn = scan;
7294 break;
7297 if (!link_insn)
7298 continue;
7299 else
7300 /* Check if this is a data dependency. */
7302 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
7303 rtx cmp0, cmp1;
7305 /* Ok this is the set cc. copy args here. */
7306 op = XEXP (pc_target, 0);
7308 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
7309 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
7310 if (GET_CODE (op0) == ZERO_EXTRACT
7311 && XEXP (op0, 1) == const1_rtx
7312 && (GET_CODE (op) == EQ
7313 || GET_CODE (op) == NE))
7315 /* btst / b{eq,ne} -> bbit{0,1} */
7316 op0 = XEXP (cmp0, 0);
7317 op1 = XEXP (cmp0, 2);
7319 else if (!register_operand (op0, VOIDmode)
7320 || !general_operand (op1, VOIDmode))
7321 continue;
7322 /* Be careful not to break what cmpsfpx_raw is
7323 trying to create for checking equality of
7324 single-precision floats. */
7325 else if (TARGET_SPFP
7326 && GET_MODE (op0) == SFmode
7327 && GET_MODE (op1) == SFmode)
7328 continue;
7330 /* None of the two cmp operands should be set between the
7331 cmp and the branch. */
7332 if (reg_set_between_p (op0, link_insn, insn))
7333 continue;
7335 if (reg_set_between_p (op1, link_insn, insn))
7336 continue;
7338 /* Since the MODE check does not work, check that this is
7339 CC reg's last set location before insn, and also no
7340 instruction between the cmp and branch uses the
7341 condition codes. */
7342 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
7343 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
7344 continue;
7346 /* CC reg should be dead after insn. */
7347 if (!find_regno_note (insn, REG_DEAD, CC_REG))
7348 continue;
7350 op = gen_rtx_fmt_ee (GET_CODE (op),
7351 GET_MODE (op), cmp0, cmp1);
7352 /* If we create a LIMM where there was none before,
7353 we only benefit if we can avoid a scheduling bubble
7354 for the ARC600. Otherwise, we'd only forgo chances
7355 at short insn generation, and risk out-of-range
7356 branches. */
7357 if (!brcc_nolimm_operator (op, VOIDmode)
7358 && !long_immediate_operand (op1, VOIDmode)
7359 && (TARGET_ARC700
7360 || next_active_insn (link_insn) != insn))
7361 continue;
7363 /* Emit bbit / brcc (or brcc_s if possible).
7364 CC_Zmode indicates that brcc_s is possible. */
7366 if (op0 != cmp0)
7367 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
7368 else if ((offset >= -140 && offset < 140)
7369 && rtx_equal_p (op1, const0_rtx)
7370 && compact_register_operand (op0, VOIDmode)
7371 && (GET_CODE (op) == EQ
7372 || GET_CODE (op) == NE))
7373 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
7374 else
7375 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
7377 brcc_insn
7378 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
7379 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
7380 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
7381 brcc_insn
7382 = gen_rtx_PARALLEL
7383 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
7384 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
7386 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
7387 note = find_reg_note (insn, REG_BR_PROB, 0);
7388 if (note)
7390 XEXP (note, 1) = REG_NOTES (brcc_insn);
7391 REG_NOTES (brcc_insn) = note;
7393 note = find_reg_note (link_insn, REG_DEAD, op0);
7394 if (note)
7396 remove_note (link_insn, note);
7397 XEXP (note, 1) = REG_NOTES (brcc_insn);
7398 REG_NOTES (brcc_insn) = note;
7400 note = find_reg_note (link_insn, REG_DEAD, op1);
7401 if (note)
7403 XEXP (note, 1) = REG_NOTES (brcc_insn);
7404 REG_NOTES (brcc_insn) = note;
7407 changed = 1;
7409 /* Delete the bcc insn. */
7410 set_insn_deleted (insn);
7412 /* Delete the cmp insn. */
7413 set_insn_deleted (link_insn);
7418 /* Clear out insn_addresses. */
7419 INSN_ADDRESSES_FREE ();
7421 } while (changed);
7423 if (INSN_ADDRESSES_SET_P())
7424 fatal_error (input_location, "insn addresses not freed");
7426 arc_reorg_in_progress = 0;
7429 /* Check if the operands are valid for BRcc.d generation
7430 Valid Brcc.d patterns are
7431 Brcc.d b, c, s9
7432 Brcc.d b, u6, s9
7434 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7435 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7436 does not have a delay slot
7438 Assumed precondition: Second operand is either a register or a u6 value. */
7440 bool
7441 valid_brcc_with_delay_p (rtx *operands)
7443 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
7444 return false;
7445 return brcc_nolimm_operator (operands[0], VOIDmode);
7448 /* ??? Hack. This should no really be here. See PR32143. */
7449 static bool
7450 arc_decl_anon_ns_mem_p (const_tree decl)
7452 while (1)
7454 if (decl == NULL_TREE || decl == error_mark_node)
7455 return false;
7456 if (TREE_CODE (decl) == NAMESPACE_DECL
7457 && DECL_NAME (decl) == NULL_TREE)
7458 return true;
7459 /* Classes and namespaces inside anonymous namespaces have
7460 TREE_PUBLIC == 0, so we can shortcut the search. */
7461 else if (TYPE_P (decl))
7462 return (TREE_PUBLIC (TYPE_NAME (decl)) == 0);
7463 else if (TREE_CODE (decl) == NAMESPACE_DECL)
7464 return (TREE_PUBLIC (decl) == 0);
7465 else
7466 decl = DECL_CONTEXT (decl);
7470 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7471 access DECL using %gp_rel(...)($gp). */
7473 static bool
7474 arc_in_small_data_p (const_tree decl)
7476 HOST_WIDE_INT size;
7478 if (TREE_CODE (decl) == STRING_CST || TREE_CODE (decl) == FUNCTION_DECL)
7479 return false;
7482 /* We don't yet generate small-data references for -mabicalls. See related
7483 -G handling in override_options. */
7484 if (TARGET_NO_SDATA_SET)
7485 return false;
7487 if (TREE_CODE (decl) == VAR_DECL && DECL_SECTION_NAME (decl) != 0)
7489 const char *name;
7491 /* Reject anything that isn't in a known small-data section. */
7492 name = DECL_SECTION_NAME (decl);
7493 if (strcmp (name, ".sdata") != 0 && strcmp (name, ".sbss") != 0)
7494 return false;
7496 /* If a symbol is defined externally, the assembler will use the
7497 usual -G rules when deciding how to implement macros. */
7498 if (!DECL_EXTERNAL (decl))
7499 return true;
7501 /* Only global variables go into sdata section for now. */
7502 else if (1)
7504 /* Don't put constants into the small data section: we want them
7505 to be in ROM rather than RAM. */
7506 if (TREE_CODE (decl) != VAR_DECL)
7507 return false;
7509 if (TREE_READONLY (decl)
7510 && !TREE_SIDE_EFFECTS (decl)
7511 && (!DECL_INITIAL (decl) || TREE_CONSTANT (DECL_INITIAL (decl))))
7512 return false;
7514 /* TREE_PUBLIC might change after the first call, because of the patch
7515 for PR19238. */
7516 if (default_binds_local_p_1 (decl, 1)
7517 || arc_decl_anon_ns_mem_p (decl))
7518 return false;
7520 /* To ensure -mvolatile-cache works
7521 ld.di does not have a gp-relative variant. */
7522 if (TREE_THIS_VOLATILE (decl))
7523 return false;
7526 /* Disable sdata references to weak variables. */
7527 if (DECL_WEAK (decl))
7528 return false;
7530 size = int_size_in_bytes (TREE_TYPE (decl));
7532 /* if (AGGREGATE_TYPE_P (TREE_TYPE (decl))) */
7533 /* return false; */
7535 /* Allow only <=4B long data types into sdata. */
7536 return (size > 0 && size <= 4);
7539 /* Return true if X is a small data address that can be rewritten
7540 as a gp+symref. */
7542 static bool
7543 arc_rewrite_small_data_p (const_rtx x)
7545 if (GET_CODE (x) == CONST)
7546 x = XEXP (x, 0);
7548 if (GET_CODE (x) == PLUS)
7550 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
7551 x = XEXP (x, 0);
7554 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
7556 gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0);
7557 return true;
7559 return false;
7562 /* If possible, rewrite OP so that it refers to small data using
7563 explicit relocations. */
7566 arc_rewrite_small_data (rtx op)
7568 op = copy_insn (op);
7569 subrtx_ptr_iterator::array_type array;
7570 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
7572 rtx *loc = *iter;
7573 if (arc_rewrite_small_data_p (*loc))
7575 gcc_assert (SDATA_BASE_REGNUM == PIC_OFFSET_TABLE_REGNUM);
7576 *loc = gen_rtx_PLUS (Pmode, pic_offset_table_rtx, *loc);
7577 if (loc != &op)
7579 if (GET_CODE (op) == MEM && &XEXP (op, 0) == loc)
7580 ; /* OK. */
7581 else if (GET_CODE (op) == MEM
7582 && GET_CODE (XEXP (op, 0)) == PLUS
7583 && GET_CODE (XEXP (XEXP (op, 0), 0)) == MULT)
7584 *loc = force_reg (Pmode, *loc);
7585 else
7586 gcc_unreachable ();
7588 iter.skip_subrtxes ();
7590 else if (GET_CODE (*loc) == PLUS
7591 && rtx_equal_p (XEXP (*loc, 0), pic_offset_table_rtx))
7592 iter.skip_subrtxes ();
7594 return op;
7597 /* Return true if OP refers to small data symbols directly, not through
7598 a PLUS. */
7600 bool
7601 small_data_pattern (rtx op, machine_mode)
7603 if (GET_CODE (op) == SEQUENCE)
7604 return false;
7605 subrtx_iterator::array_type array;
7606 FOR_EACH_SUBRTX (iter, array, op, ALL)
7608 const_rtx x = *iter;
7609 if (GET_CODE (x) == PLUS
7610 && rtx_equal_p (XEXP (x, 0), pic_offset_table_rtx))
7611 iter.skip_subrtxes ();
7612 else if (arc_rewrite_small_data_p (x))
7613 return true;
7615 return false;
7618 /* Return true if OP is an acceptable memory operand for ARCompact
7619 16-bit gp-relative load instructions.
7620 op shd look like : [r26, symref@sda]
7621 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7623 /* volatile cache option still to be handled. */
7625 bool
7626 compact_sda_memory_operand (rtx op, machine_mode mode)
7628 rtx addr;
7629 int size;
7631 /* Eliminate non-memory operations. */
7632 if (GET_CODE (op) != MEM)
7633 return false;
7635 if (mode == VOIDmode)
7636 mode = GET_MODE (op);
7638 size = GET_MODE_SIZE (mode);
7640 /* dword operations really put out 2 instructions, so eliminate them. */
7641 if (size > UNITS_PER_WORD)
7642 return false;
7644 /* Decode the address now. */
7645 addr = XEXP (op, 0);
7647 return LEGITIMATE_SMALL_DATA_ADDRESS_P (addr);
7650 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7652 void
7653 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
7654 unsigned HOST_WIDE_INT size,
7655 unsigned HOST_WIDE_INT align,
7656 unsigned HOST_WIDE_INT globalize_p)
7658 int in_small_data = arc_in_small_data_p (decl);
7660 if (in_small_data)
7661 switch_to_section (get_named_section (NULL, ".sbss", 0));
7662 /* named_section (0,".sbss",0); */
7663 else
7664 switch_to_section (bss_section);
7666 if (globalize_p)
7667 (*targetm.asm_out.globalize_label) (stream, name);
7669 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
7670 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
7671 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
7672 ASM_OUTPUT_LABEL (stream, name);
7674 if (size != 0)
7675 ASM_OUTPUT_SKIP (stream, size);
7678 static bool
7679 arc_preserve_reload_p (rtx in)
7681 return (GET_CODE (in) == PLUS
7682 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
7683 && CONST_INT_P (XEXP (in, 1))
7684 && !((INTVAL (XEXP (in, 1)) & 511)));
7688 arc_register_move_cost (machine_mode,
7689 enum reg_class from_class, enum reg_class to_class)
7691 /* The ARC600 has no bypass for extension registers, hence a nop might be
7692 needed to be inserted after a write so that reads are safe. */
7693 if (TARGET_ARC600)
7695 if (to_class == MPY_WRITABLE_CORE_REGS)
7696 return 3;
7697 /* Instructions modifying LP_COUNT need 4 additional cycles before
7698 the register will actually contain the value. */
7699 else if (to_class == LPCOUNT_REG)
7700 return 6;
7701 else if (to_class == WRITABLE_CORE_REGS)
7702 return 6;
7705 /* The ARC700 stalls for 3 cycles when *reading* from lp_count. */
7706 if (TARGET_ARC700
7707 && (from_class == LPCOUNT_REG || from_class == ALL_CORE_REGS
7708 || from_class == WRITABLE_CORE_REGS))
7709 return 8;
7711 /* Force an attempt to 'mov Dy,Dx' to spill. */
7712 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
7713 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
7714 return 100;
7716 return 2;
7719 /* Emit code for an addsi3 instruction with OPERANDS.
7720 COND_P indicates if this will use conditional execution.
7721 Return the length of the instruction.
7722 If OUTPUT_P is false, don't actually output the instruction, just return
7723 its length. */
7725 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
7727 char format[35];
7729 int match = operands_match_p (operands[0], operands[1]);
7730 int match2 = operands_match_p (operands[0], operands[2]);
7731 int intval = (REG_P (operands[2]) ? 1
7732 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
7733 int neg_intval = -intval;
7734 int short_0 = satisfies_constraint_Rcq (operands[0]);
7735 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
7736 int ret = 0;
7738 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
7739 && REGNO (OP) != 30) \
7740 || !TARGET_V2))
7742 #define ADDSI_OUTPUT1(FORMAT) do {\
7743 if (output_p) \
7744 output_asm_insn (FORMAT, operands);\
7745 return ret; \
7746 } while (0)
7747 #define ADDSI_OUTPUT(LIST) do {\
7748 if (output_p) \
7749 sprintf LIST;\
7750 ADDSI_OUTPUT1 (format);\
7751 return ret; \
7752 } while (0)
7754 /* First try to emit a 16 bit insn. */
7755 ret = 2;
7756 if (!cond_p
7757 /* If we are actually about to output this insn, don't try a 16 bit
7758 variant if we already decided that we don't want that
7759 (I.e. we upsized this insn to align some following insn.)
7760 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
7761 but add1 r0,sp,35 doesn't. */
7762 && (!output_p || (get_attr_length (current_output_insn) & 2)))
7764 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
7765 patterns. */
7766 if (short_p
7767 && ((REG_H_P (operands[2])
7768 && (match || satisfies_constraint_Rcq (operands[2])))
7769 || (CONST_INT_P (operands[2])
7770 && ((unsigned) intval <= (match ? 127 : 7)))))
7771 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
7773 /* Generate add_s b,b,h patterns. */
7774 if (short_0 && match2 && REG_H_P (operands[1]))
7775 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
7777 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
7778 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
7779 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
7780 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
7782 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
7783 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
7784 && match && !(neg_intval & ~124)))
7785 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
7787 /* Generate add_s h,h,s3 patterns. */
7788 if (REG_H_P (operands[0]) && match && TARGET_V2
7789 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
7790 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
7792 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
7793 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
7794 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
7795 && satisfies_constraint_Rcq (operands[1])
7796 && satisfies_constraint_L (operands[2]))
7797 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
7800 /* Now try to emit a 32 bit insn without long immediate. */
7801 ret = 4;
7802 if (!match && match2 && REG_P (operands[1]))
7803 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
7804 if (match || !cond_p)
7806 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
7807 int range_factor = neg_intval & intval;
7808 int shift;
7810 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
7811 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
7813 /* If we can use a straight add / sub instead of a {add,sub}[123] of
7814 same size, do, so - the insn latency is lower. */
7815 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
7816 0x800 is not. */
7817 if ((intval >= 0 && intval <= limit)
7818 || (intval == -0x800 && limit == 0x7ff))
7819 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
7820 else if ((intval < 0 && neg_intval <= limit)
7821 || (intval == 0x800 && limit == 0x7ff))
7822 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
7823 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
7824 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
7825 gcc_assert ((((1 << shift) - 1) & intval) == 0);
7826 if (((intval < 0 && intval != -0x4000)
7827 /* sub[123] is slower than add_s / sub, only use it if it
7828 avoids a long immediate. */
7829 && neg_intval <= limit << shift)
7830 || (intval == 0x4000 && limit == 0x7ff))
7831 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
7832 shift, neg_intval >> shift));
7833 else if ((intval >= 0 && intval <= limit << shift)
7834 || (intval == -0x4000 && limit == 0x7ff))
7835 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
7837 /* Try to emit a 16 bit opcode with long immediate. */
7838 ret = 6;
7839 if (short_p && match)
7840 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
7842 /* We have to use a 32 bit opcode, and with a long immediate. */
7843 ret = 8;
7844 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
7847 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
7848 Return the length of the instruction.
7849 If OUTPUT_P is false, don't actually output the instruction, just return
7850 its length. */
7852 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
7854 enum rtx_code commutative_op = GET_CODE (operands[3]);
7855 const char *pat = NULL;
7857 /* Canonical rtl should not have a constant in the first operand position. */
7858 gcc_assert (!CONSTANT_P (operands[1]));
7860 switch (commutative_op)
7862 case AND:
7863 if (satisfies_constraint_C1p (operands[2]))
7864 pat = "bmsk%? %0,%1,%Z2";
7865 else if (satisfies_constraint_C2p (operands[2]))
7867 operands[2] = GEN_INT ((~INTVAL (operands[2])));
7868 pat = "bmskn%? %0,%1,%Z2";
7870 else if (satisfies_constraint_Ccp (operands[2]))
7871 pat = "bclr%? %0,%1,%M2";
7872 else if (satisfies_constraint_CnL (operands[2]))
7873 pat = "bic%? %0,%1,%n2-1";
7874 break;
7875 case IOR:
7876 if (satisfies_constraint_C0p (operands[2]))
7877 pat = "bset%? %0,%1,%z2";
7878 break;
7879 case XOR:
7880 if (satisfies_constraint_C0p (operands[2]))
7881 pat = "bxor%? %0,%1,%z2";
7882 break;
7883 case PLUS:
7884 return arc_output_addsi (operands, true, output_p);
7885 default: break;
7887 if (output_p)
7888 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
7889 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
7890 return 4;
7891 return 8;
7894 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
7895 Emit code and return an potentially modified address such that offsets
7896 up to SIZE are can be added to yield a legitimate address.
7897 if REUSE is set, ADDR is a register that may be modified. */
7899 static rtx
7900 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
7902 rtx base = addr;
7903 rtx offs = const0_rtx;
7905 if (GET_CODE (base) == PLUS)
7907 offs = XEXP (base, 1);
7908 base = XEXP (base, 0);
7910 if (!REG_P (base)
7911 || (REGNO (base) != STACK_POINTER_REGNUM
7912 && REGNO_PTR_FRAME_P (REGNO (base)))
7913 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
7914 || !SMALL_INT (INTVAL (offs) + size))
7916 if (reuse)
7917 emit_insn (gen_add2_insn (addr, offs));
7918 else
7919 addr = copy_to_mode_reg (Pmode, addr);
7921 return addr;
7924 /* Like move_by_pieces, but take account of load latency, and actual
7925 offset ranges. Return true on success. */
7927 bool
7928 arc_expand_movmem (rtx *operands)
7930 rtx dst = operands[0];
7931 rtx src = operands[1];
7932 rtx dst_addr, src_addr;
7933 HOST_WIDE_INT size;
7934 int align = INTVAL (operands[3]);
7935 unsigned n_pieces;
7936 int piece = align;
7937 rtx store[2];
7938 rtx tmpx[2];
7939 int i;
7941 if (!CONST_INT_P (operands[2]))
7942 return false;
7943 size = INTVAL (operands[2]);
7944 /* move_by_pieces_ninsns is static, so we can't use it. */
7945 if (align >= 4)
7947 if (TARGET_LL64)
7948 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
7949 else
7950 n_pieces = (size + 2) / 4U + (size & 1);
7952 else if (align == 2)
7953 n_pieces = (size + 1) / 2U;
7954 else
7955 n_pieces = size;
7956 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
7957 return false;
7958 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
7959 possible. */
7960 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
7961 piece = 8;
7962 else if (piece > 4)
7963 piece = 4;
7964 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
7965 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
7966 store[0] = store[1] = NULL_RTX;
7967 tmpx[0] = tmpx[1] = NULL_RTX;
7968 for (i = 0; size > 0; i ^= 1, size -= piece)
7970 rtx tmp;
7971 machine_mode mode;
7973 while (piece > size)
7974 piece >>= 1;
7975 mode = smallest_mode_for_size (piece * BITS_PER_UNIT, MODE_INT);
7976 /* If we don't re-use temporaries, the scheduler gets carried away,
7977 and the register pressure gets unnecessarily high. */
7978 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
7979 tmp = tmpx[i];
7980 else
7981 tmpx[i] = tmp = gen_reg_rtx (mode);
7982 dst_addr = force_offsettable (dst_addr, piece, 1);
7983 src_addr = force_offsettable (src_addr, piece, 1);
7984 if (store[i])
7985 emit_insn (store[i]);
7986 emit_move_insn (tmp, change_address (src, mode, src_addr));
7987 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
7988 dst_addr = plus_constant (Pmode, dst_addr, piece);
7989 src_addr = plus_constant (Pmode, src_addr, piece);
7991 if (store[i])
7992 emit_insn (store[i]);
7993 if (store[i^1])
7994 emit_insn (store[i^1]);
7995 return true;
7998 /* Prepare operands for move in MODE. Return true iff the move has
7999 been emitted. */
8001 bool
8002 prepare_move_operands (rtx *operands, machine_mode mode)
8004 /* We used to do this only for MODE_INT Modes, but addresses to floating
8005 point variables may well be in the small data section. */
8006 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
8007 operands[0] = arc_rewrite_small_data (operands[0]);
8009 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
8011 prepare_pic_move (operands, SImode);
8013 /* Disable any REG_EQUALs associated with the symref
8014 otherwise the optimization pass undoes the work done
8015 here and references the variable directly. */
8018 if (GET_CODE (operands[0]) != MEM
8019 && !TARGET_NO_SDATA_SET
8020 && small_data_pattern (operands[1], Pmode))
8022 /* This is to take care of address calculations involving sdata
8023 variables. */
8024 operands[1] = arc_rewrite_small_data (operands[1]);
8026 emit_insn (gen_rtx_SET (operands[0],operands[1]));
8027 /* ??? This note is useless, since it only restates the set itself.
8028 We should rather use the original SYMBOL_REF. However, there is
8029 the problem that we are lying to the compiler about these
8030 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8031 so that we can tell it apart from an actual symbol. */
8032 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
8034 /* Take care of the REG_EQUAL note that will be attached to mark the
8035 output reg equal to the initial symbol_ref after this code is
8036 executed. */
8037 emit_move_insn (operands[0], operands[0]);
8038 return true;
8041 if (MEM_P (operands[0])
8042 && !(reload_in_progress || reload_completed))
8044 operands[1] = force_reg (mode, operands[1]);
8045 if (!move_dest_operand (operands[0], mode))
8047 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8048 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8049 except that we can't use that function because it is static. */
8050 rtx pat = change_address (operands[0], mode, addr);
8051 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8052 operands[0] = pat;
8054 if (!cse_not_expected)
8056 rtx pat = XEXP (operands[0], 0);
8058 pat = arc_legitimize_address_0 (pat, pat, mode);
8059 if (pat)
8061 pat = change_address (operands[0], mode, pat);
8062 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8063 operands[0] = pat;
8068 if (MEM_P (operands[1]) && !cse_not_expected)
8070 rtx pat = XEXP (operands[1], 0);
8072 pat = arc_legitimize_address_0 (pat, pat, mode);
8073 if (pat)
8075 pat = change_address (operands[1], mode, pat);
8076 MEM_COPY_ATTRIBUTES (pat, operands[1]);
8077 operands[1] = pat;
8081 return false;
8084 /* Prepare OPERANDS for an extension using CODE to OMODE.
8085 Return true iff the move has been emitted. */
8087 bool
8088 prepare_extend_operands (rtx *operands, enum rtx_code code,
8089 machine_mode omode)
8091 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
8093 /* This is to take care of address calculations involving sdata
8094 variables. */
8095 operands[1]
8096 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
8097 emit_insn (gen_rtx_SET (operands[0], operands[1]));
8098 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
8100 /* Take care of the REG_EQUAL note that will be attached to mark the
8101 output reg equal to the initial extension after this code is
8102 executed. */
8103 emit_move_insn (operands[0], operands[0]);
8104 return true;
8106 return false;
8109 /* Output a library call to a function called FNAME that has been arranged
8110 to be local to any dso. */
8112 const char *
8113 arc_output_libcall (const char *fname)
8115 unsigned len = strlen (fname);
8116 static char buf[64];
8118 gcc_assert (len < sizeof buf - 35);
8119 if (TARGET_LONG_CALLS_SET
8120 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
8122 if (flag_pic)
8123 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
8124 else
8125 sprintf (buf, "jl%%! @%s", fname);
8127 else
8128 sprintf (buf, "bl%%!%%* @%s", fname);
8129 return buf;
8132 /* Return the SImode highpart of the DImode value IN. */
8135 disi_highpart (rtx in)
8137 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
8140 /* Return length adjustment for INSN.
8141 For ARC600:
8142 A write to a core reg greater or equal to 32 must not be immediately
8143 followed by a use. Anticipate the length requirement to insert a nop
8144 between PRED and SUCC to prevent a hazard. */
8146 static int
8147 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
8149 if (!TARGET_ARC600)
8150 return 0;
8151 /* If SUCC is a doloop_end_i with a preceding label, we must output a nop
8152 in front of SUCC anyway, so there will be separation between PRED and
8153 SUCC. */
8154 if (recog_memoized (succ) == CODE_FOR_doloop_end_i
8155 && LABEL_P (prev_nonnote_insn (succ)))
8156 return 0;
8157 if (recog_memoized (succ) == CODE_FOR_doloop_begin_i)
8158 return 0;
8159 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
8160 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
8161 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
8162 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
8163 if (recog_memoized (pred) == CODE_FOR_mulsi_600
8164 || recog_memoized (pred) == CODE_FOR_umul_600
8165 || recog_memoized (pred) == CODE_FOR_mac_600
8166 || recog_memoized (pred) == CODE_FOR_mul64_600
8167 || recog_memoized (pred) == CODE_FOR_mac64_600
8168 || recog_memoized (pred) == CODE_FOR_umul64_600
8169 || recog_memoized (pred) == CODE_FOR_umac64_600)
8170 return 0;
8171 subrtx_iterator::array_type array;
8172 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
8174 const_rtx x = *iter;
8175 switch (GET_CODE (x))
8177 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8178 break;
8179 default:
8180 /* This is also fine for PRE/POST_MODIFY, because they
8181 contain a SET. */
8182 continue;
8184 rtx dest = XEXP (x, 0);
8185 /* Check if this sets a an extension register. N.B. we use 61 for the
8186 condition codes, which is definitely not an extension register. */
8187 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
8188 /* Check if the same register is used by the PAT. */
8189 && (refers_to_regno_p
8190 (REGNO (dest),
8191 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
8192 PATTERN (succ), 0)))
8193 return 4;
8195 return 0;
8198 /* Given a rtx, check if it is an assembly instruction or not. */
8200 static int
8201 arc_asm_insn_p (rtx x)
8203 int i, j;
8205 if (x == 0)
8206 return 0;
8208 switch (GET_CODE (x))
8210 case ASM_OPERANDS:
8211 case ASM_INPUT:
8212 return 1;
8214 case SET:
8215 return arc_asm_insn_p (SET_SRC (x));
8217 case PARALLEL:
8218 j = 0;
8219 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8220 j += arc_asm_insn_p (XVECEXP (x, 0, i));
8221 if ( j > 0)
8222 return 1;
8223 break;
8225 default:
8226 break;
8229 return 0;
8232 /* We might have a CALL to a non-returning function before a loop end.
8233 ??? Although the manual says that's OK (the target is outside the
8234 loop, and the loop counter unused there), the assembler barfs on
8235 this for ARC600, so we must insert a nop before such a call too.
8236 For ARC700, and ARCv2 is not allowed to have the last ZOL
8237 instruction a jump to a location where lp_count is modified. */
8239 static bool
8240 arc_loop_hazard (rtx_insn *pred, rtx_insn *succ)
8242 rtx_insn *jump = NULL;
8243 rtx label_rtx = NULL_RTX;
8244 rtx_insn *label = NULL;
8245 basic_block succ_bb;
8247 if (recog_memoized (succ) != CODE_FOR_doloop_end_i)
8248 return false;
8250 /* Phase 1: ARC600 and ARCv2HS doesn't allow any control instruction
8251 (i.e., jump/call) as the last instruction of a ZOL. */
8252 if (TARGET_ARC600 || TARGET_HS)
8253 if (JUMP_P (pred) || CALL_P (pred)
8254 || arc_asm_insn_p (PATTERN (pred))
8255 || GET_CODE (PATTERN (pred)) == SEQUENCE)
8256 return true;
8258 /* Phase 2: Any architecture, it is not allowed to have the last ZOL
8259 instruction a jump to a location where lp_count is modified. */
8261 /* Phase 2a: Dig for the jump instruction. */
8262 if (JUMP_P (pred))
8263 jump = pred;
8264 else if (GET_CODE (PATTERN (pred)) == SEQUENCE
8265 && JUMP_P (XVECEXP (PATTERN (pred), 0, 0)))
8266 jump = as_a <rtx_insn *> (XVECEXP (PATTERN (pred), 0, 0));
8267 else
8268 return false;
8270 /* Phase 2b: Make sure is not a millicode jump. */
8271 if ((GET_CODE (PATTERN (jump)) == PARALLEL)
8272 && (XVECEXP (PATTERN (jump), 0, 0) == ret_rtx))
8273 return false;
8275 label_rtx = JUMP_LABEL (jump);
8276 if (!label_rtx)
8277 return false;
8279 /* Phase 2c: Make sure is not a return. */
8280 if (ANY_RETURN_P (label_rtx))
8281 return false;
8283 /* Pahse 2d: Go to the target of the jump and check for aliveness of
8284 LP_COUNT register. */
8285 label = safe_as_a <rtx_insn *> (label_rtx);
8286 succ_bb = BLOCK_FOR_INSN (label);
8287 if (!succ_bb)
8289 gcc_assert (NEXT_INSN (label));
8290 if (NOTE_INSN_BASIC_BLOCK_P (NEXT_INSN (label)))
8291 succ_bb = NOTE_BASIC_BLOCK (NEXT_INSN (label));
8292 else
8293 succ_bb = BLOCK_FOR_INSN (NEXT_INSN (label));
8296 if (succ_bb && REGNO_REG_SET_P (df_get_live_out (succ_bb), LP_COUNT))
8297 return true;
8299 return false;
8302 /* For ARC600:
8303 A write to a core reg greater or equal to 32 must not be immediately
8304 followed by a use. Anticipate the length requirement to insert a nop
8305 between PRED and SUCC to prevent a hazard. */
8308 arc_hazard (rtx_insn *pred, rtx_insn *succ)
8310 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
8311 return 0;
8313 if (arc_loop_hazard (pred, succ))
8314 return 4;
8316 if (TARGET_ARC600)
8317 return arc600_corereg_hazard (pred, succ);
8319 return 0;
8322 /* Return length adjustment for INSN. */
8325 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
8327 if (!INSN_P (insn))
8328 return len;
8329 /* We already handle sequences by ignoring the delay sequence flag. */
8330 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
8331 return len;
8333 /* It is impossible to jump to the very end of a Zero-Overhead Loop, as
8334 the ZOL mechanism only triggers when advancing to the end address,
8335 so if there's a label at the end of a ZOL, we need to insert a nop.
8336 The ARC600 ZOL also has extra restrictions on jumps at the end of a
8337 loop. */
8338 if (recog_memoized (insn) == CODE_FOR_doloop_end_i)
8340 rtx_insn *prev = prev_nonnote_insn (insn);
8342 return ((LABEL_P (prev)
8343 || (TARGET_ARC600
8344 && (JUMP_P (prev)
8345 || CALL_P (prev) /* Could be a noreturn call. */
8346 || (NONJUMP_INSN_P (prev)
8347 && GET_CODE (PATTERN (prev)) == SEQUENCE))))
8348 ? len + 4 : len);
8351 /* Check for return with but one preceding insn since function
8352 start / call. */
8353 if (TARGET_PAD_RETURN
8354 && JUMP_P (insn)
8355 && GET_CODE (PATTERN (insn)) != ADDR_VEC
8356 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
8357 && get_attr_type (insn) == TYPE_RETURN)
8359 rtx_insn *prev = prev_active_insn (insn);
8361 if (!prev || !(prev = prev_active_insn (prev))
8362 || ((NONJUMP_INSN_P (prev)
8363 && GET_CODE (PATTERN (prev)) == SEQUENCE)
8364 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8365 NON_SIBCALL)
8366 : CALL_ATTR (prev, NON_SIBCALL)))
8367 return len + 4;
8369 if (TARGET_ARC600)
8371 rtx_insn *succ = next_real_insn (insn);
8373 /* One the ARC600, a write to an extension register must be separated
8374 from a read. */
8375 if (succ && INSN_P (succ))
8376 len += arc600_corereg_hazard (insn, succ);
8379 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8380 can go awry. */
8381 extract_constrain_insn_cached (insn);
8383 return len;
8386 /* Values for length_sensitive. */
8387 enum
8389 ARC_LS_NONE,// Jcc
8390 ARC_LS_25, // 25 bit offset, B
8391 ARC_LS_21, // 21 bit offset, Bcc
8392 ARC_LS_U13,// 13 bit unsigned offset, LP
8393 ARC_LS_10, // 10 bit offset, B_s, Beq_s, Bne_s
8394 ARC_LS_9, // 9 bit offset, BRcc
8395 ARC_LS_8, // 8 bit offset, BRcc_s
8396 ARC_LS_U7, // 7 bit unsigned offset, LPcc
8397 ARC_LS_7 // 7 bit offset, Bcc_s
8400 /* While the infrastructure patch is waiting for review, duplicate the
8401 struct definitions, to allow this file to compile. */
8402 #if 1
8403 typedef struct
8405 unsigned align_set;
8406 /* Cost as a branch / call target or call return address. */
8407 int target_cost;
8408 int fallthrough_cost;
8409 int branch_cost;
8410 int length;
8411 /* 0 for not length sensitive, 1 for largest offset range,
8412 * 2 for next smaller etc. */
8413 unsigned length_sensitive : 8;
8414 bool enabled;
8415 } insn_length_variant_t;
8417 typedef struct insn_length_parameters_s
8419 int align_unit_log;
8420 int align_base_log;
8421 int max_variants;
8422 int (*get_variants) (rtx_insn *, int, bool, bool, insn_length_variant_t *);
8423 } insn_length_parameters_t;
8425 static void
8426 arc_insn_length_parameters (insn_length_parameters_t *ilp) ATTRIBUTE_UNUSED;
8427 #endif
8429 static int
8430 arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
8431 insn_length_variant_t *ilv)
8433 if (!NONDEBUG_INSN_P (insn))
8434 return 0;
8435 enum attr_type type;
8436 /* shorten_branches doesn't take optimize_size into account yet for the
8437 get_variants mechanism, so turn this off for now. */
8438 if (optimize_size)
8439 return 0;
8440 if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
8442 /* The interaction of a short delay slot insn with a short branch is
8443 too weird for shorten_branches to piece together, so describe the
8444 entire SEQUENCE. */
8445 rtx_insn *inner;
8446 if (TARGET_UPSIZE_DBR
8447 && get_attr_length (pat->insn (1)) <= 2
8448 && (((type = get_attr_type (inner = pat->insn (0)))
8449 == TYPE_UNCOND_BRANCH)
8450 || type == TYPE_BRANCH)
8451 && get_attr_delay_slot_filled (inner) == DELAY_SLOT_FILLED_YES)
8453 int n_variants
8454 = arc_get_insn_variants (inner, get_attr_length (inner), true,
8455 target_p, ilv+1);
8456 /* The short variant gets split into a higher-cost aligned
8457 and a lower cost unaligned variant. */
8458 gcc_assert (n_variants);
8459 gcc_assert (ilv[1].length_sensitive == ARC_LS_7
8460 || ilv[1].length_sensitive == ARC_LS_10);
8461 gcc_assert (ilv[1].align_set == 3);
8462 ilv[0] = ilv[1];
8463 ilv[0].align_set = 1;
8464 ilv[0].branch_cost += 1;
8465 ilv[1].align_set = 2;
8466 n_variants++;
8467 for (int i = 0; i < n_variants; i++)
8468 ilv[i].length += 2;
8469 /* In case an instruction with aligned size is wanted, and
8470 the short variants are unavailable / too expensive, add
8471 versions of long branch + long delay slot. */
8472 for (int i = 2, end = n_variants; i < end; i++, n_variants++)
8474 ilv[n_variants] = ilv[i];
8475 ilv[n_variants].length += 2;
8477 return n_variants;
8479 return 0;
8481 insn_length_variant_t *first_ilv = ilv;
8482 type = get_attr_type (insn);
8483 bool delay_filled
8484 = (get_attr_delay_slot_filled (insn) == DELAY_SLOT_FILLED_YES);
8485 int branch_align_cost = delay_filled ? 0 : 1;
8486 int branch_unalign_cost = delay_filled ? 0 : TARGET_UNALIGN_BRANCH ? 0 : 1;
8487 /* If the previous instruction is an sfunc call, this insn is always
8488 a target, even though the middle-end is unaware of this. */
8489 bool force_target = false;
8490 rtx_insn *prev = prev_active_insn (insn);
8491 if (prev && arc_next_active_insn (prev, 0) == insn
8492 && ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
8493 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8494 NON_SIBCALL)
8495 : (CALL_ATTR (prev, NON_SIBCALL)
8496 && NEXT_INSN (PREV_INSN (prev)) == prev)))
8497 force_target = true;
8499 switch (type)
8501 case TYPE_BRCC:
8502 /* Short BRCC only comes in no-delay-slot version, and without limm */
8503 if (!delay_filled)
8505 ilv->align_set = 3;
8506 ilv->length = 2;
8507 ilv->branch_cost = 1;
8508 ilv->enabled = (len == 2);
8509 ilv->length_sensitive = ARC_LS_8;
8510 ilv++;
8512 /* Fall through. */
8513 case TYPE_BRCC_NO_DELAY_SLOT:
8514 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8515 (delay slot) scheduling purposes, but they are longer. */
8516 if (GET_CODE (PATTERN (insn)) == PARALLEL
8517 && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET)
8518 return 0;
8519 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8520 ilv->length = ((type == TYPE_BRCC) ? 4 : 8);
8521 ilv->align_set = 3;
8522 ilv->branch_cost = branch_align_cost;
8523 ilv->enabled = (len <= ilv->length);
8524 ilv->length_sensitive = ARC_LS_9;
8525 if ((target_p || force_target)
8526 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8528 ilv[1] = *ilv;
8529 ilv->align_set = 1;
8530 ilv++;
8531 ilv->align_set = 2;
8532 ilv->target_cost = 1;
8533 ilv->branch_cost = branch_unalign_cost;
8535 ilv++;
8537 rtx op, op0;
8538 op = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
8539 op0 = XEXP (op, 0);
8541 if (GET_CODE (op0) == ZERO_EXTRACT
8542 && satisfies_constraint_L (XEXP (op0, 2)))
8543 op0 = XEXP (op0, 0);
8544 if (satisfies_constraint_Rcq (op0))
8546 ilv->length = ((type == TYPE_BRCC) ? 6 : 10);
8547 ilv->align_set = 3;
8548 ilv->branch_cost = 1 + branch_align_cost;
8549 ilv->fallthrough_cost = 1;
8550 ilv->enabled = true;
8551 ilv->length_sensitive = ARC_LS_21;
8552 if (!delay_filled && TARGET_UNALIGN_BRANCH)
8554 ilv[1] = *ilv;
8555 ilv->align_set = 1;
8556 ilv++;
8557 ilv->align_set = 2;
8558 ilv->branch_cost = 1 + branch_unalign_cost;
8560 ilv++;
8562 ilv->length = ((type == TYPE_BRCC) ? 8 : 12);
8563 ilv->align_set = 3;
8564 ilv->branch_cost = 1 + branch_align_cost;
8565 ilv->fallthrough_cost = 1;
8566 ilv->enabled = true;
8567 ilv->length_sensitive = ARC_LS_21;
8568 if ((target_p || force_target)
8569 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8571 ilv[1] = *ilv;
8572 ilv->align_set = 1;
8573 ilv++;
8574 ilv->align_set = 2;
8575 ilv->target_cost = 1;
8576 ilv->branch_cost = 1 + branch_unalign_cost;
8578 ilv++;
8579 break;
8581 case TYPE_SFUNC:
8582 ilv->length = 12;
8583 goto do_call;
8584 case TYPE_CALL_NO_DELAY_SLOT:
8585 ilv->length = 8;
8586 goto do_call;
8587 case TYPE_CALL:
8588 ilv->length = 4;
8589 ilv->length_sensitive
8590 = GET_CODE (PATTERN (insn)) == COND_EXEC ? ARC_LS_21 : ARC_LS_25;
8591 do_call:
8592 ilv->align_set = 3;
8593 ilv->fallthrough_cost = branch_align_cost;
8594 ilv->enabled = true;
8595 if ((target_p || force_target)
8596 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8598 ilv[1] = *ilv;
8599 ilv->align_set = 1;
8600 ilv++;
8601 ilv->align_set = 2;
8602 ilv->target_cost = 1;
8603 ilv->fallthrough_cost = branch_unalign_cost;
8605 ilv++;
8606 break;
8607 case TYPE_UNCOND_BRANCH:
8608 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8609 but that makes no difference at the moment. */
8610 ilv->length_sensitive = ARC_LS_7;
8611 ilv[1].length_sensitive = ARC_LS_25;
8612 goto do_branch;
8613 case TYPE_BRANCH:
8614 ilv->length_sensitive = ARC_LS_10;
8615 ilv[1].length_sensitive = ARC_LS_21;
8616 do_branch:
8617 ilv->align_set = 3;
8618 ilv->length = 2;
8619 ilv->branch_cost = branch_align_cost;
8620 ilv->enabled = (len == ilv->length);
8621 ilv++;
8622 ilv->length = 4;
8623 ilv->align_set = 3;
8624 ilv->branch_cost = branch_align_cost;
8625 ilv->enabled = true;
8626 if ((target_p || force_target)
8627 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8629 ilv[1] = *ilv;
8630 ilv->align_set = 1;
8631 ilv++;
8632 ilv->align_set = 2;
8633 ilv->target_cost = 1;
8634 ilv->branch_cost = branch_unalign_cost;
8636 ilv++;
8637 break;
8638 case TYPE_JUMP:
8639 return 0;
8640 default:
8641 /* For every short insn, there is generally also a long insn.
8642 trap_s is an exception. */
8643 if ((len & 2) == 0 || recog_memoized (insn) == CODE_FOR_trap_s)
8644 return 0;
8645 ilv->align_set = 3;
8646 ilv->length = len;
8647 ilv->enabled = 1;
8648 ilv++;
8649 ilv->align_set = 3;
8650 ilv->length = len + 2;
8651 ilv->enabled = 1;
8652 if (target_p || force_target)
8654 ilv[1] = *ilv;
8655 ilv->align_set = 1;
8656 ilv++;
8657 ilv->align_set = 2;
8658 ilv->target_cost = 1;
8660 ilv++;
8662 /* If the previous instruction is an sfunc call, this insn is always
8663 a target, even though the middle-end is unaware of this.
8664 Therefore, if we have a call predecessor, transfer the target cost
8665 to the fallthrough and branch costs. */
8666 if (force_target)
8668 for (insn_length_variant_t *p = first_ilv; p < ilv; p++)
8670 p->fallthrough_cost += p->target_cost;
8671 p->branch_cost += p->target_cost;
8672 p->target_cost = 0;
8676 return ilv - first_ilv;
8679 static void
8680 arc_insn_length_parameters (insn_length_parameters_t *ilp)
8682 ilp->align_unit_log = 1;
8683 ilp->align_base_log = 1;
8684 ilp->max_variants = 7;
8685 ilp->get_variants = arc_get_insn_variants;
8688 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8689 CC field of *STATEP. */
8691 static rtx
8692 arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8694 rtx cond = statep->cond;
8695 int raw_cc = get_arc_condition_code (cond);
8696 if (reverse)
8697 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8699 if (statep->cc == raw_cc)
8700 return copy_rtx (cond);
8702 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8704 machine_mode ccm = GET_MODE (XEXP (cond, 0));
8705 enum rtx_code code = reverse_condition (GET_CODE (cond));
8706 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8707 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8709 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8710 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8713 /* Return version of PAT conditionalized with COND, which is part of INSN.
8714 ANNULLED indicates if INSN is an annulled delay-slot insn.
8715 Register further changes if necessary. */
8716 static rtx
8717 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8719 /* For commutative operators, we generally prefer to have
8720 the first source match the destination. */
8721 if (GET_CODE (pat) == SET)
8723 rtx src = SET_SRC (pat);
8725 if (COMMUTATIVE_P (src))
8727 rtx src0 = XEXP (src, 0);
8728 rtx src1 = XEXP (src, 1);
8729 rtx dst = SET_DEST (pat);
8731 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8732 /* Leave add_n alone - the canonical form is to
8733 have the complex summand first. */
8734 && REG_P (src0))
8735 pat = gen_rtx_SET (dst,
8736 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8737 src1, src0));
8741 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8742 what to do with COND_EXEC. */
8743 if (RTX_FRAME_RELATED_P (insn))
8745 /* If this is the delay slot insn of an anulled branch,
8746 dwarf2out.c:scan_trace understands the anulling semantics
8747 without the COND_EXEC. */
8748 gcc_assert (annulled);
8749 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8750 REG_NOTES (insn));
8751 validate_change (insn, &REG_NOTES (insn), note, 1);
8753 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8754 return pat;
8757 /* Use the ccfsm machinery to do if conversion. */
8759 static unsigned
8760 arc_ifcvt (void)
8762 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8763 basic_block merge_bb = 0;
8765 memset (statep, 0, sizeof *statep);
8766 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
8768 arc_ccfsm_advance (insn, statep);
8770 switch (statep->state)
8772 case 0:
8773 if (JUMP_P (insn))
8774 merge_bb = 0;
8775 break;
8776 case 1: case 2:
8778 /* Deleted branch. */
8779 gcc_assert (!merge_bb);
8780 merge_bb = BLOCK_FOR_INSN (insn);
8781 basic_block succ_bb
8782 = BLOCK_FOR_INSN (NEXT_INSN (NEXT_INSN (PREV_INSN (insn))));
8783 arc_ccfsm_post_advance (insn, statep);
8784 gcc_assert (!IN_RANGE (statep->state, 1, 2));
8785 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
8786 if (seq != insn)
8788 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8789 rtx pat = PATTERN (slot);
8790 if (INSN_ANNULLED_BRANCH_P (insn))
8792 rtx cond
8793 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8794 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8796 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8797 gcc_unreachable ();
8798 PUT_CODE (slot, NOTE);
8799 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8800 if (merge_bb && succ_bb)
8801 merge_blocks (merge_bb, succ_bb);
8803 else if (merge_bb && succ_bb)
8805 set_insn_deleted (insn);
8806 merge_blocks (merge_bb, succ_bb);
8808 else
8810 PUT_CODE (insn, NOTE);
8811 NOTE_KIND (insn) = NOTE_INSN_DELETED;
8813 continue;
8815 case 3:
8816 if (LABEL_P (insn)
8817 && statep->target_label == CODE_LABEL_NUMBER (insn))
8819 arc_ccfsm_post_advance (insn, statep);
8820 basic_block succ_bb = BLOCK_FOR_INSN (insn);
8821 if (merge_bb && succ_bb)
8822 merge_blocks (merge_bb, succ_bb);
8823 else if (--LABEL_NUSES (insn) == 0)
8825 const char *name = LABEL_NAME (insn);
8826 PUT_CODE (insn, NOTE);
8827 NOTE_KIND (insn) = NOTE_INSN_DELETED_LABEL;
8828 NOTE_DELETED_LABEL_NAME (insn) = name;
8830 merge_bb = 0;
8831 continue;
8833 /* Fall through. */
8834 case 4: case 5:
8835 if (!NONDEBUG_INSN_P (insn))
8836 break;
8838 /* Conditionalized insn. */
8840 rtx_insn *prev, *pprev;
8841 rtx *patp, pat, cond;
8842 bool annulled; annulled = false;
8844 /* If this is a delay slot insn in a non-annulled branch,
8845 don't conditionalize it. N.B., this should be fine for
8846 conditional return too. However, don't do this for
8847 unconditional branches, as these would be encountered when
8848 processing an 'else' part. */
8849 prev = PREV_INSN (insn);
8850 pprev = PREV_INSN (prev);
8851 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
8852 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8854 if (!INSN_ANNULLED_BRANCH_P (prev))
8855 break;
8856 annulled = true;
8859 patp = &PATTERN (insn);
8860 pat = *patp;
8861 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
8862 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
8864 /* ??? don't conditionalize if all side effects are dead
8865 in the not-execute case. */
8867 pat = conditionalize_nonjump (pat, cond, insn, annulled);
8869 else if (simplejump_p (insn))
8871 patp = &SET_SRC (pat);
8872 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
8874 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
8876 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
8877 pat = gen_rtx_SET (pc_rtx, pat);
8879 else
8880 gcc_unreachable ();
8881 validate_change (insn, patp, pat, 1);
8882 if (!apply_change_group ())
8883 gcc_unreachable ();
8884 if (JUMP_P (insn))
8886 rtx_insn *next = next_nonnote_insn (insn);
8887 if (GET_CODE (next) == BARRIER)
8888 delete_insn (next);
8889 if (statep->state == 3)
8890 continue;
8892 break;
8893 default:
8894 gcc_unreachable ();
8896 arc_ccfsm_post_advance (insn, statep);
8898 return 0;
8901 /* Find annulled delay insns and convert them to use the appropriate predicate.
8902 This allows branch shortening to size up these insns properly. */
8904 static unsigned
8905 arc_predicate_delay_insns (void)
8907 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
8909 rtx pat, jump, dlay, src, cond, *patp;
8910 int reverse;
8912 if (!NONJUMP_INSN_P (insn)
8913 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
8914 continue;
8915 jump = XVECEXP (pat, 0, 0);
8916 dlay = XVECEXP (pat, 0, 1);
8917 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
8918 continue;
8919 /* If the branch insn does the annulling, leave the delay insn alone. */
8920 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
8921 continue;
8922 /* ??? Could also leave DLAY un-conditionalized if its target is dead
8923 on the other path. */
8924 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
8925 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
8926 src = SET_SRC (PATTERN (jump));
8927 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
8928 cond = XEXP (src, 0);
8929 if (XEXP (src, 2) == pc_rtx)
8930 reverse = 0;
8931 else if (XEXP (src, 1) == pc_rtx)
8932 reverse = 1;
8933 else
8934 gcc_unreachable ();
8935 if (reverse != !INSN_FROM_TARGET_P (dlay))
8937 machine_mode ccm = GET_MODE (XEXP (cond, 0));
8938 enum rtx_code code = reverse_condition (GET_CODE (cond));
8939 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8940 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8942 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
8943 copy_rtx (XEXP (cond, 0)),
8944 copy_rtx (XEXP (cond, 1)));
8946 else
8947 cond = copy_rtx (cond);
8948 patp = &PATTERN (dlay);
8949 pat = *patp;
8950 pat = conditionalize_nonjump (pat, cond, dlay, true);
8951 validate_change (dlay, patp, pat, 1);
8952 if (!apply_change_group ())
8953 gcc_unreachable ();
8955 return 0;
8958 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
8959 (other than of a forward brcc), it creates a hazard when there is a read
8960 of the same register at the branch target. We can't know what is at the
8961 branch target of calls, and for branches, we don't really know before the
8962 end of delay slot scheduling, either. Not only can individual instruction
8963 be hoisted out into a delay slot, a basic block can also be emptied this
8964 way, and branch and/or fall through targets be redirected. Hence we don't
8965 want such writes in a delay slot. */
8967 /* Return nonzreo iff INSN writes to an extension core register. */
8970 arc_write_ext_corereg (rtx insn)
8972 subrtx_iterator::array_type array;
8973 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
8975 const_rtx x = *iter;
8976 switch (GET_CODE (x))
8978 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8979 break;
8980 default:
8981 /* This is also fine for PRE/POST_MODIFY, because they
8982 contain a SET. */
8983 continue;
8985 const_rtx dest = XEXP (x, 0);
8986 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
8987 return 1;
8989 return 0;
8992 /* This is like the hook, but returns NULL when it can't / won't generate
8993 a legitimate address. */
8995 static rtx
8996 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
8997 machine_mode mode)
8999 rtx addr, inner;
9001 if (flag_pic && SYMBOLIC_CONST (x))
9002 (x) = arc_legitimize_pic_address (x, 0);
9003 addr = x;
9004 if (GET_CODE (addr) == CONST)
9005 addr = XEXP (addr, 0);
9006 if (GET_CODE (addr) == PLUS
9007 && CONST_INT_P (XEXP (addr, 1))
9008 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9009 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9010 || (REG_P (XEXP (addr, 0))
9011 && (INTVAL (XEXP (addr, 1)) & 252))))
9013 HOST_WIDE_INT offs, upper;
9014 int size = GET_MODE_SIZE (mode);
9016 offs = INTVAL (XEXP (addr, 1));
9017 upper = (offs + 256 * size) & ~511 * size;
9018 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9019 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9020 if (GET_CODE (x) == CONST)
9021 inner = gen_rtx_CONST (Pmode, inner);
9022 #endif
9023 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9024 x = addr;
9026 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9027 x = force_reg (Pmode, x);
9028 if (memory_address_p ((machine_mode) mode, x))
9029 return x;
9030 return NULL_RTX;
9033 static rtx
9034 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9036 if (GET_CODE (orig_x) == SYMBOL_REF)
9038 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
9039 if (model != 0)
9040 return arc_legitimize_tls_address (orig_x, model);
9043 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9045 if (new_x)
9046 return new_x;
9047 return orig_x;
9050 static rtx
9051 arc_delegitimize_address_0 (rtx x)
9053 rtx u, gp, p;
9055 if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
9057 if (XINT (u, 1) == ARC_UNSPEC_GOT
9058 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)
9059 return XVECEXP (u, 0, 0);
9061 else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS
9062 && GET_CODE (u = XEXP (p, 0)) == UNSPEC
9063 && (XINT (u, 1) == ARC_UNSPEC_GOT
9064 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC))
9065 return gen_rtx_CONST
9066 (GET_MODE (x),
9067 gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1)));
9068 else if (GET_CODE (x) == PLUS
9069 && ((REG_P (gp = XEXP (x, 0))
9070 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
9071 || (GET_CODE (gp) == CONST
9072 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
9073 && XINT (u, 1) == ARC_UNSPEC_GOT
9074 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
9075 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
9076 && GET_CODE (XEXP (x, 1)) == CONST
9077 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
9078 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
9079 return XVECEXP (u, 0, 0);
9080 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
9081 && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
9082 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
9083 || (GET_CODE (gp) == CONST
9084 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
9085 && XINT (u, 1) == ARC_UNSPEC_GOT
9086 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
9087 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
9088 && GET_CODE (XEXP (x, 1)) == CONST
9089 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
9090 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
9091 return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
9092 XVECEXP (u, 0, 0));
9093 else if (GET_CODE (x) == PLUS
9094 && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
9095 return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
9096 return NULL_RTX;
9099 static rtx
9100 arc_delegitimize_address (rtx x)
9102 rtx orig_x = x = delegitimize_mem_from_attrs (x);
9103 if (GET_CODE (x) == MEM)
9104 x = XEXP (x, 0);
9105 x = arc_delegitimize_address_0 (x);
9106 if (x)
9108 if (MEM_P (orig_x))
9109 x = replace_equiv_address_nv (orig_x, x);
9110 return x;
9112 return orig_x;
9115 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9116 differ from the hardware register number in order to allow the generic
9117 code to correctly split the concatenation of acc1 and acc2. */
9120 gen_acc1 (void)
9122 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9125 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9126 differ from the hardware register number in order to allow the generic
9127 code to correctly split the concatenation of acc1 and acc2. */
9130 gen_acc2 (void)
9132 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9135 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9136 differ from the hardware register number in order to allow the generic
9137 code to correctly split the concatenation of mhi and mlo. */
9140 gen_mlo (void)
9142 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
9145 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9146 differ from the hardware register number in order to allow the generic
9147 code to correctly split the concatenation of mhi and mlo. */
9150 gen_mhi (void)
9152 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
9155 /* FIXME: a parameter should be added, and code added to final.c,
9156 to reproduce this functionality in shorten_branches. */
9157 #if 0
9158 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9159 a previous instruction. */
9161 arc_unalign_branch_p (rtx branch)
9163 rtx note;
9165 if (!TARGET_UNALIGN_BRANCH)
9166 return 0;
9167 /* Do not do this if we have a filled delay slot. */
9168 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
9169 && !NEXT_INSN (branch)->deleted ())
9170 return 0;
9171 note = find_reg_note (branch, REG_BR_PROB, 0);
9172 return (!note
9173 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
9174 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
9176 #endif
9178 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9179 are three reasons why we need to consider branches to be length 6:
9180 - annull-false delay slot insns are implemented using conditional execution,
9181 thus preventing short insn formation where used.
9182 - for ARC600: annul-true delay slot insns are implemented where possible
9183 using conditional execution, preventing short insn formation where used.
9184 - for ARC700: likely or somewhat likely taken branches are made long and
9185 unaligned if possible to avoid branch penalty. */
9187 bool
9188 arc_branch_size_unknown_p (void)
9190 return !optimize_size && arc_reorg_in_progress;
9193 /* We are about to output a return insn. Add padding if necessary to avoid
9194 a mispredict. A return could happen immediately after the function
9195 start, but after a call we know that there will be at least a blink
9196 restore. */
9198 void
9199 arc_pad_return (void)
9201 rtx_insn *insn = current_output_insn;
9202 rtx_insn *prev = prev_active_insn (insn);
9203 int want_long;
9205 if (!prev)
9207 fputs ("\tnop_s\n", asm_out_file);
9208 cfun->machine->unalign ^= 2;
9209 want_long = 1;
9211 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9212 because after a call, we'd have to restore blink first. */
9213 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
9214 return;
9215 else
9217 want_long = (get_attr_length (prev) == 2);
9218 prev = prev_active_insn (prev);
9220 if (!prev
9221 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
9222 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9223 NON_SIBCALL)
9224 : CALL_ATTR (prev, NON_SIBCALL)))
9226 if (want_long)
9227 cfun->machine->size_reason
9228 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9229 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
9231 cfun->machine->size_reason
9232 = "Long unaligned jump avoids non-delay slot penalty";
9233 want_long = 1;
9235 /* Disgorge delay insn, if there is any, and it may be moved. */
9236 if (final_sequence
9237 /* ??? Annulled would be OK if we can and do conditionalize
9238 the delay slot insn accordingly. */
9239 && !INSN_ANNULLED_BRANCH_P (insn)
9240 && (get_attr_cond (insn) != COND_USE
9241 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
9242 XVECEXP (final_sequence, 0, 1))))
9244 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
9245 gcc_assert (!prev_real_insn (insn)
9246 || !arc_hazard (prev_real_insn (insn), prev));
9247 cfun->machine->force_short_suffix = !want_long;
9248 rtx save_pred = current_insn_predicate;
9249 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
9250 cfun->machine->force_short_suffix = -1;
9251 prev->set_deleted ();
9252 current_output_insn = insn;
9253 current_insn_predicate = save_pred;
9255 else if (want_long)
9256 fputs ("\tnop\n", asm_out_file);
9257 else
9259 fputs ("\tnop_s\n", asm_out_file);
9260 cfun->machine->unalign ^= 2;
9263 return;
9266 /* The usual; we set up our machine_function data. */
9268 static struct machine_function *
9269 arc_init_machine_status (void)
9271 struct machine_function *machine;
9272 machine = ggc_cleared_alloc<machine_function> ();
9273 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9274 machine->force_short_suffix = -1;
9276 return machine;
9279 /* Implements INIT_EXPANDERS. We just set up to call the above
9280 function. */
9282 void
9283 arc_init_expanders (void)
9285 init_machine_status = arc_init_machine_status;
9288 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9289 indicates a number of elements to ignore - that allows to have a
9290 sibcall pattern that starts with (return). LOAD_P is zero for store
9291 multiple (for prologues), and one for load multiples (for epilogues),
9292 and two for load multiples where no final clobber of blink is required.
9293 We also skip the first load / store element since this is supposed to
9294 be checked in the instruction pattern. */
9297 arc_check_millicode (rtx op, int offset, int load_p)
9299 int len = XVECLEN (op, 0) - offset;
9300 int i;
9302 if (load_p == 2)
9304 if (len < 2 || len > 13)
9305 return 0;
9306 load_p = 1;
9308 else
9310 rtx elt = XVECEXP (op, 0, --len);
9312 if (GET_CODE (elt) != CLOBBER
9313 || !REG_P (XEXP (elt, 0))
9314 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9315 || len < 3 || len > 13)
9316 return 0;
9318 for (i = 1; i < len; i++)
9320 rtx elt = XVECEXP (op, 0, i + offset);
9321 rtx reg, mem, addr;
9323 if (GET_CODE (elt) != SET)
9324 return 0;
9325 mem = XEXP (elt, load_p);
9326 reg = XEXP (elt, 1-load_p);
9327 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9328 return 0;
9329 addr = XEXP (mem, 0);
9330 if (GET_CODE (addr) != PLUS
9331 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9332 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9333 return 0;
9335 return 1;
9338 /* Accessor functions for cfun->machine->unalign. */
9341 arc_get_unalign (void)
9343 return cfun->machine->unalign;
9346 void
9347 arc_clear_unalign (void)
9349 if (cfun)
9350 cfun->machine->unalign = 0;
9353 void
9354 arc_toggle_unalign (void)
9356 cfun->machine->unalign ^= 2;
9359 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9360 constant in operand 2, but which would require a LIMM because of
9361 operand mismatch.
9362 operands 3 and 4 are new SET_SRCs for operands 0. */
9364 void
9365 split_addsi (rtx *operands)
9367 int val = INTVAL (operands[2]);
9369 /* Try for two short insns first. Lengths being equal, we prefer
9370 expansions with shorter register lifetimes. */
9371 if (val > 127 && val <= 255
9372 && satisfies_constraint_Rcq (operands[0]))
9374 operands[3] = operands[2];
9375 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9377 else
9379 operands[3] = operands[1];
9380 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
9384 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9385 constant in operand 1, but which would require a LIMM because of
9386 operand mismatch.
9387 operands 3 and 4 are new SET_SRCs for operands 0. */
9389 void
9390 split_subsi (rtx *operands)
9392 int val = INTVAL (operands[1]);
9394 /* Try for two short insns first. Lengths being equal, we prefer
9395 expansions with shorter register lifetimes. */
9396 if (satisfies_constraint_Rcq (operands[0])
9397 && satisfies_constraint_Rcq (operands[2]))
9399 if (val >= -31 && val <= 127)
9401 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9402 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9403 return;
9405 else if (val >= 0 && val < 255)
9407 operands[3] = operands[1];
9408 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9409 return;
9412 /* If the destination is not an ARCompact16 register, we might
9413 still have a chance to make a short insn if the source is;
9414 we need to start with a reg-reg move for this. */
9415 operands[3] = operands[2];
9416 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9419 /* Handle DOUBLE_REGS uses.
9420 Operand 0: destination register
9421 Operand 1: source register */
9423 static bool
9424 arc_process_double_reg_moves (rtx *operands)
9426 rtx dest = operands[0];
9427 rtx src = operands[1];
9429 enum usesDxState { none, srcDx, destDx, maxDx };
9430 enum usesDxState state = none;
9432 if (refers_to_regno_p (40, 44, src, 0))
9433 state = srcDx;
9434 if (refers_to_regno_p (40, 44, dest, 0))
9436 /* Via arc_register_move_cost, we should never see D,D moves. */
9437 gcc_assert (state == none);
9438 state = destDx;
9441 if (state == none)
9442 return false;
9444 if (state == srcDx)
9446 /* Without the LR insn, we need to split this into a
9447 sequence of insns which will use the DEXCLx and DADDHxy
9448 insns to be able to read the Dx register in question. */
9449 if (TARGET_DPFP_DISABLE_LRSR)
9451 /* gen *movdf_insn_nolrsr */
9452 rtx set = gen_rtx_SET (dest, src);
9453 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9454 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9456 else
9458 /* When we have 'mov D, r' or 'mov D, D' then get the target
9459 register pair for use with LR insn. */
9460 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9461 TARGET_BIG_ENDIAN ? 0 : 4);
9462 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9463 TARGET_BIG_ENDIAN ? 4 : 0);
9465 /* Produce the two LR insns to get the high and low parts. */
9466 emit_insn (gen_rtx_SET (destHigh,
9467 gen_rtx_UNSPEC_VOLATILE (Pmode,
9468 gen_rtvec (1, src),
9469 VUNSPEC_ARC_LR_HIGH)));
9470 emit_insn (gen_rtx_SET (destLow,
9471 gen_rtx_UNSPEC_VOLATILE (Pmode,
9472 gen_rtvec (1, src),
9473 VUNSPEC_ARC_LR)));
9476 else if (state == destDx)
9478 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9479 LR insn get the target register pair. */
9480 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9481 TARGET_BIG_ENDIAN ? 0 : 4);
9482 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9483 TARGET_BIG_ENDIAN ? 4 : 0);
9485 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9487 else
9488 gcc_unreachable ();
9490 return true;
9493 /* operands 0..1 are the operands of a 64 bit move instruction.
9494 split it into two moves with operands 2/3 and 4/5. */
9496 void
9497 arc_split_move (rtx *operands)
9499 machine_mode mode = GET_MODE (operands[0]);
9500 int i;
9501 int swap = 0;
9502 rtx xop[4];
9504 if (TARGET_DPFP)
9506 if (arc_process_double_reg_moves (operands))
9507 return;
9510 if (TARGET_LL64
9511 && ((memory_operand (operands[0], mode)
9512 && even_register_operand (operands[1], mode))
9513 || (memory_operand (operands[1], mode)
9514 && even_register_operand (operands[0], mode))))
9516 emit_move_insn (operands[0], operands[1]);
9517 return;
9520 if (TARGET_PLUS_QMACW
9521 && GET_CODE (operands[1]) == CONST_VECTOR)
9523 HOST_WIDE_INT intval0, intval1;
9524 if (GET_MODE (operands[1]) == V2SImode)
9526 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9527 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9529 else
9531 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9532 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9533 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9534 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9536 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9537 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9538 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9539 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9540 emit_move_insn (xop[0], xop[2]);
9541 emit_move_insn (xop[3], xop[1]);
9542 return;
9545 for (i = 0; i < 2; i++)
9547 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9549 rtx addr = XEXP (operands[i], 0);
9550 rtx r, o;
9551 enum rtx_code code;
9553 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9554 switch (GET_CODE (addr))
9556 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9557 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9558 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9559 pre_modify:
9560 code = PRE_MODIFY;
9561 break;
9562 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9563 case POST_INC: o = GEN_INT (8); goto post_modify;
9564 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9565 post_modify:
9566 code = POST_MODIFY;
9567 swap = 2;
9568 break;
9569 default:
9570 gcc_unreachable ();
9572 r = XEXP (addr, 0);
9573 xop[0+i] = adjust_automodify_address_nv
9574 (operands[i], SImode,
9575 gen_rtx_fmt_ee (code, Pmode, r,
9576 gen_rtx_PLUS (Pmode, r, o)),
9578 xop[2+i] = adjust_automodify_address_nv
9579 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9581 else
9583 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9584 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9587 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9589 swap = 2;
9590 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9593 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9594 emit_move_insn (xop[2 - swap], xop[3 - swap]);
9598 /* Select between the instruction output templates s_tmpl (for short INSNs)
9599 and l_tmpl (for long INSNs). */
9601 const char *
9602 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
9604 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9606 extract_constrain_insn_cached (insn);
9607 return is_short ? s_tmpl : l_tmpl;
9610 /* Searches X for any reference to REGNO, returning the rtx of the
9611 reference found if any. Otherwise, returns NULL_RTX. */
9614 arc_regno_use_in (unsigned int regno, rtx x)
9616 const char *fmt;
9617 int i, j;
9618 rtx tem;
9620 if (REG_P (x) && refers_to_regno_p (regno, x))
9621 return x;
9623 fmt = GET_RTX_FORMAT (GET_CODE (x));
9624 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9626 if (fmt[i] == 'e')
9628 if ((tem = regno_use_in (regno, XEXP (x, i))))
9629 return tem;
9631 else if (fmt[i] == 'E')
9632 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9633 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9634 return tem;
9637 return NULL_RTX;
9640 /* Return the integer value of the "type" attribute for INSN, or -1 if
9641 INSN can't have attributes. */
9644 arc_attr_type (rtx_insn *insn)
9646 if (NONJUMP_INSN_P (insn)
9647 ? (GET_CODE (PATTERN (insn)) == USE
9648 || GET_CODE (PATTERN (insn)) == CLOBBER)
9649 : JUMP_P (insn)
9650 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9651 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9652 : !CALL_P (insn))
9653 return -1;
9654 return get_attr_type (insn);
9657 /* Return true if insn sets the condition codes. */
9659 bool
9660 arc_sets_cc_p (rtx_insn *insn)
9662 if (NONJUMP_INSN_P (insn))
9663 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9664 insn = seq->insn (seq->len () - 1);
9665 return arc_attr_type (insn) == TYPE_COMPARE;
9668 /* Return true if INSN is an instruction with a delay slot we may want
9669 to fill. */
9671 bool
9672 arc_need_delay (rtx_insn *insn)
9674 rtx_insn *next;
9676 if (!flag_delayed_branch)
9677 return false;
9678 /* The return at the end of a function needs a delay slot. */
9679 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9680 && (!(next = next_active_insn (insn))
9681 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9682 && arc_attr_type (next) == TYPE_RETURN))
9683 && (!TARGET_PAD_RETURN
9684 || (prev_active_insn (insn)
9685 && prev_active_insn (prev_active_insn (insn))
9686 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9687 return true;
9688 if (NONJUMP_INSN_P (insn)
9689 ? (GET_CODE (PATTERN (insn)) == USE
9690 || GET_CODE (PATTERN (insn)) == CLOBBER
9691 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9692 : JUMP_P (insn)
9693 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9694 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9695 : !CALL_P (insn))
9696 return false;
9697 return num_delay_slots (insn) != 0;
9700 /* Return true if the scheduling pass(es) has/have already run,
9701 i.e. where possible, we should try to mitigate high latencies
9702 by different instruction selection. */
9704 bool
9705 arc_scheduling_not_expected (void)
9707 return cfun->machine->arc_reorg_started;
9710 /* Oddly enough, sometimes we get a zero overhead loop that branch
9711 shortening doesn't think is a loop - observed with compile/pr24883.c
9712 -O3 -fomit-frame-pointer -funroll-loops. Make sure to include the
9713 alignment visible for branch shortening (we actually align the loop
9714 insn before it, but that is equivalent since the loop insn is 4 byte
9715 long.) */
9718 arc_label_align (rtx_insn *label)
9720 int loop_align = LOOP_ALIGN (LABEL);
9722 if (loop_align > align_labels_log)
9724 rtx_insn *prev = prev_nonnote_insn (label);
9726 if (prev && NONJUMP_INSN_P (prev)
9727 && GET_CODE (PATTERN (prev)) == PARALLEL
9728 && recog_memoized (prev) == CODE_FOR_doloop_begin_i)
9729 return loop_align;
9731 /* Code has a minimum p2 alignment of 1, which we must restore after an
9732 ADDR_DIFF_VEC. */
9733 if (align_labels_log < 1)
9735 rtx_insn *next = next_nonnote_nondebug_insn (label);
9736 if (INSN_P (next) && recog_memoized (next) >= 0)
9737 return 1;
9739 return align_labels_log;
9742 /* Return true if LABEL is in executable code. */
9744 bool
9745 arc_text_label (rtx_insn *label)
9747 rtx_insn *next;
9749 /* ??? We use deleted labels like they were still there, see
9750 gcc.c-torture/compile/20000326-2.c . */
9751 gcc_assert (GET_CODE (label) == CODE_LABEL
9752 || (GET_CODE (label) == NOTE
9753 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9754 next = next_nonnote_insn (label);
9755 if (next)
9756 return (!JUMP_TABLE_DATA_P (next)
9757 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9758 else if (!PREV_INSN (label))
9759 /* ??? sometimes text labels get inserted very late, see
9760 gcc.dg/torture/stackalign/comp-goto-1.c */
9761 return true;
9762 return false;
9765 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9766 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9767 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9768 to redirect two breqs. */
9770 static bool
9771 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
9773 /* ??? get_attr_type is declared to take an rtx. */
9774 union { const rtx_insn *c; rtx_insn *r; } u;
9776 u.c = follower;
9777 if (CROSSING_JUMP_P (followee))
9778 switch (get_attr_type (u.r))
9780 case TYPE_BRCC:
9781 case TYPE_BRCC_NO_DELAY_SLOT:
9782 return false;
9783 default:
9784 return true;
9786 return true;
9789 /* Return the register number of the register holding the return address
9790 for a function of type TYPE. */
9793 arc_return_address_register (unsigned int fn_type)
9795 int regno = 0;
9797 if (ARC_INTERRUPT_P (fn_type))
9799 if (((fn_type & ARC_FUNCTION_ILINK1) | ARC_FUNCTION_FIRQ) != 0)
9800 regno = ILINK1_REGNUM;
9801 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
9802 regno = ILINK2_REGNUM;
9803 else
9804 gcc_unreachable ();
9806 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
9807 regno = RETURN_ADDR_REGNUM;
9809 gcc_assert (regno != 0);
9810 return regno;
9813 /* Implement EPILOGUE_USES.
9814 Return true if REGNO should be added to the deemed uses of the epilogue.
9816 We have to make sure all the register restore instructions are
9817 known to be live in interrupt functions, plus the blink register if
9818 it is clobbered by the isr. */
9820 bool
9821 arc_epilogue_uses (int regno)
9823 unsigned int fn_type;
9825 if (regno == arc_tp_regno)
9826 return true;
9828 fn_type = arc_compute_function_type (cfun);
9829 if (reload_completed)
9831 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9833 if (!fixed_regs[regno])
9834 return true;
9835 return ((regno == arc_return_address_register (fn_type))
9836 || (regno == RETURN_ADDR_REGNUM));
9838 else
9839 return regno == RETURN_ADDR_REGNUM;
9841 else
9842 return regno == arc_return_address_register (fn_type);
9845 /* Helper for EH_USES macro. */
9847 bool
9848 arc_eh_uses (int regno)
9850 if (regno == arc_tp_regno)
9851 return true;
9852 return false;
9855 #ifndef TARGET_NO_LRA
9856 #define TARGET_NO_LRA !TARGET_LRA
9857 #endif
9859 static bool
9860 arc_lra_p (void)
9862 return !TARGET_NO_LRA;
9865 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9866 Rcq registers, because some insn are shorter with them. OTOH we already
9867 have separate alternatives for this purpose, and other insns don't
9868 mind, so maybe we should rather prefer the other registers?
9869 We need more data, and we can only get that if we allow people to
9870 try all options. */
9871 static int
9872 arc_register_priority (int r)
9874 switch (arc_lra_priority_tag)
9876 case ARC_LRA_PRIORITY_NONE:
9877 return 0;
9878 case ARC_LRA_PRIORITY_NONCOMPACT:
9879 return ((((r & 7) ^ 4) - 4) & 15) != r;
9880 case ARC_LRA_PRIORITY_COMPACT:
9881 return ((((r & 7) ^ 4) - 4) & 15) == r;
9882 default:
9883 gcc_unreachable ();
9887 static reg_class_t
9888 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
9890 return GENERAL_REGS;
9893 bool
9894 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
9895 int itype)
9897 rtx x = *p;
9898 enum reload_type type = (enum reload_type) itype;
9900 if (GET_CODE (x) == PLUS
9901 && CONST_INT_P (XEXP (x, 1))
9902 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9903 || (REG_P (XEXP (x, 0))
9904 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9906 int scale = GET_MODE_SIZE (mode);
9907 int shift;
9908 rtx index_rtx = XEXP (x, 1);
9909 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9910 rtx reg, sum, sum2;
9912 if (scale > 4)
9913 scale = 4;
9914 if ((scale-1) & offset)
9915 scale = 1;
9916 shift = scale >> 1;
9917 offset_base
9918 = ((offset + (256 << shift))
9919 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
9920 /* Sometimes the normal form does not suit DImode. We
9921 could avoid that by using smaller ranges, but that
9922 would give less optimized code when SImode is
9923 prevalent. */
9924 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9926 int regno;
9928 reg = XEXP (x, 0);
9929 regno = REGNO (reg);
9930 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9932 if (reg_equiv_constant (regno))
9934 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9935 offset_base);
9936 if (GET_CODE (sum2) == PLUS)
9937 sum2 = gen_rtx_CONST (Pmode, sum2);
9939 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9940 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9941 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9942 type);
9943 return true;
9946 /* We must re-recognize what we created before. */
9947 else if (GET_CODE (x) == PLUS
9948 && GET_CODE (XEXP (x, 0)) == PLUS
9949 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9950 && REG_P (XEXP (XEXP (x, 0), 0))
9951 && CONST_INT_P (XEXP (x, 1)))
9953 /* Because this address is so complex, we know it must have
9954 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9955 it is already unshared, and needs no further unsharing. */
9956 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9957 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
9958 return true;
9960 return false;
9963 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
9965 static bool
9966 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
9967 unsigned int align,
9968 enum by_pieces_operation op,
9969 bool speed_p)
9971 /* Let the movmem expander handle small block moves. */
9972 if (op == MOVE_BY_PIECES)
9973 return false;
9975 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
9978 /* Emit a (pre) memory barrier around an atomic sequence according to
9979 MODEL. */
9981 static void
9982 arc_pre_atomic_barrier (enum memmodel model)
9984 if (need_atomic_barrier_p (model, true))
9985 emit_insn (gen_memory_barrier ());
9988 /* Emit a (post) memory barrier around an atomic sequence according to
9989 MODEL. */
9991 static void
9992 arc_post_atomic_barrier (enum memmodel model)
9994 if (need_atomic_barrier_p (model, false))
9995 emit_insn (gen_memory_barrier ());
9998 /* Expand a compare and swap pattern. */
10000 static void
10001 emit_unlikely_jump (rtx insn)
10003 rtx_insn *jump = emit_jump_insn (insn);
10004 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10007 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10008 32-bit compare and swap on the word containing the byte or
10009 half-word. The difference between a weak and a strong CAS is that
10010 the weak version may simply fail. The strong version relies on two
10011 loops, one checks if the SCOND op is succsfully or not, the other
10012 checks if the 32 bit accessed location which contains the 8 or 16
10013 bit datum is not changed by other thread. The first loop is
10014 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10015 loops is implemented by this routine. */
10017 static void
10018 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10019 rtx oldval, rtx newval, rtx weak,
10020 rtx mod_s, rtx mod_f)
10022 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10023 rtx addr = gen_reg_rtx (Pmode);
10024 rtx off = gen_reg_rtx (SImode);
10025 rtx oldv = gen_reg_rtx (SImode);
10026 rtx newv = gen_reg_rtx (SImode);
10027 rtx oldvalue = gen_reg_rtx (SImode);
10028 rtx newvalue = gen_reg_rtx (SImode);
10029 rtx res = gen_reg_rtx (SImode);
10030 rtx resv = gen_reg_rtx (SImode);
10031 rtx memsi, val, mask, end_label, loop_label, cc, x;
10032 machine_mode mode;
10033 bool is_weak = (weak != const0_rtx);
10035 /* Truncate the address. */
10036 emit_insn (gen_rtx_SET (addr,
10037 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10039 /* Compute the datum offset. */
10040 emit_insn (gen_rtx_SET (off,
10041 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10042 if (TARGET_BIG_ENDIAN)
10043 emit_insn (gen_rtx_SET (off,
10044 gen_rtx_MINUS (SImode,
10045 (GET_MODE (mem) == QImode) ?
10046 GEN_INT (3) : GEN_INT (2), off)));
10048 /* Normal read from truncated address. */
10049 memsi = gen_rtx_MEM (SImode, addr);
10050 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10051 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10053 val = copy_to_reg (memsi);
10055 /* Convert the offset in bits. */
10056 emit_insn (gen_rtx_SET (off,
10057 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10059 /* Get the proper mask. */
10060 if (GET_MODE (mem) == QImode)
10061 mask = force_reg (SImode, GEN_INT (0xff));
10062 else
10063 mask = force_reg (SImode, GEN_INT (0xffff));
10065 emit_insn (gen_rtx_SET (mask,
10066 gen_rtx_ASHIFT (SImode, mask, off)));
10068 /* Prepare the old and new values. */
10069 emit_insn (gen_rtx_SET (val,
10070 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10071 val)));
10073 oldval = gen_lowpart (SImode, oldval);
10074 emit_insn (gen_rtx_SET (oldv,
10075 gen_rtx_ASHIFT (SImode, oldval, off)));
10077 newval = gen_lowpart_common (SImode, newval);
10078 emit_insn (gen_rtx_SET (newv,
10079 gen_rtx_ASHIFT (SImode, newval, off)));
10081 emit_insn (gen_rtx_SET (oldv,
10082 gen_rtx_AND (SImode, oldv, mask)));
10084 emit_insn (gen_rtx_SET (newv,
10085 gen_rtx_AND (SImode, newv, mask)));
10087 if (!is_weak)
10089 end_label = gen_label_rtx ();
10090 loop_label = gen_label_rtx ();
10091 emit_label (loop_label);
10094 /* Make the old and new values. */
10095 emit_insn (gen_rtx_SET (oldvalue,
10096 gen_rtx_IOR (SImode, oldv, val)));
10098 emit_insn (gen_rtx_SET (newvalue,
10099 gen_rtx_IOR (SImode, newv, val)));
10101 /* Try an 32bit atomic compare and swap. It clobbers the CC
10102 register. */
10103 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10104 weak, mod_s, mod_f));
10106 /* Regardless of the weakness of the operation, a proper boolean
10107 result needs to be provided. */
10108 x = gen_rtx_REG (CC_Zmode, CC_REG);
10109 x = gen_rtx_EQ (SImode, x, const0_rtx);
10110 emit_insn (gen_rtx_SET (bool_result, x));
10112 if (!is_weak)
10114 /* Check the results: if the atomic op is successfully the goto
10115 to end label. */
10116 x = gen_rtx_REG (CC_Zmode, CC_REG);
10117 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10118 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10119 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10120 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10122 /* Wait for the right moment when the accessed 32-bit location
10123 is stable. */
10124 emit_insn (gen_rtx_SET (resv,
10125 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10126 res)));
10127 mode = SELECT_CC_MODE (NE, resv, val);
10128 cc = gen_rtx_REG (mode, CC_REG);
10129 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10131 /* Set the new value of the 32 bit location, proper masked. */
10132 emit_insn (gen_rtx_SET (val, resv));
10134 /* Try again if location is unstable. Fall through if only
10135 scond op failed. */
10136 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10137 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10138 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10139 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10141 emit_label (end_label);
10144 /* End: proper return the result for the given mode. */
10145 emit_insn (gen_rtx_SET (res,
10146 gen_rtx_AND (SImode, res, mask)));
10148 emit_insn (gen_rtx_SET (res,
10149 gen_rtx_LSHIFTRT (SImode, res, off)));
10151 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10154 /* Helper function used by "atomic_compare_and_swap" expand
10155 pattern. */
10157 void
10158 arc_expand_compare_and_swap (rtx operands[])
10160 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10161 machine_mode mode;
10163 bval = operands[0];
10164 rval = operands[1];
10165 mem = operands[2];
10166 oldval = operands[3];
10167 newval = operands[4];
10168 is_weak = operands[5];
10169 mod_s = operands[6];
10170 mod_f = operands[7];
10171 mode = GET_MODE (mem);
10173 if (reg_overlap_mentioned_p (rval, oldval))
10174 oldval = copy_to_reg (oldval);
10176 if (mode == SImode)
10178 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10179 is_weak, mod_s, mod_f));
10180 x = gen_rtx_REG (CC_Zmode, CC_REG);
10181 x = gen_rtx_EQ (SImode, x, const0_rtx);
10182 emit_insn (gen_rtx_SET (bval, x));
10184 else
10186 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10187 is_weak, mod_s, mod_f);
10191 /* Helper function used by the "atomic_compare_and_swapsi_1"
10192 pattern. */
10194 void
10195 arc_split_compare_and_swap (rtx operands[])
10197 rtx rval, mem, oldval, newval;
10198 machine_mode mode;
10199 enum memmodel mod_s, mod_f;
10200 bool is_weak;
10201 rtx label1, label2, x, cond;
10203 rval = operands[0];
10204 mem = operands[1];
10205 oldval = operands[2];
10206 newval = operands[3];
10207 is_weak = (operands[4] != const0_rtx);
10208 mod_s = (enum memmodel) INTVAL (operands[5]);
10209 mod_f = (enum memmodel) INTVAL (operands[6]);
10210 mode = GET_MODE (mem);
10212 /* ARC atomic ops work only with 32-bit aligned memories. */
10213 gcc_assert (mode == SImode);
10215 arc_pre_atomic_barrier (mod_s);
10217 label1 = NULL_RTX;
10218 if (!is_weak)
10220 label1 = gen_label_rtx ();
10221 emit_label (label1);
10223 label2 = gen_label_rtx ();
10225 /* Load exclusive. */
10226 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10228 /* Check if it is oldval. */
10229 mode = SELECT_CC_MODE (NE, rval, oldval);
10230 cond = gen_rtx_REG (mode, CC_REG);
10231 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10233 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10234 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10235 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10236 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10238 /* Exclusively store new item. Store clobbers CC reg. */
10239 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10241 if (!is_weak)
10243 /* Check the result of the store. */
10244 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10245 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10246 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10247 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10248 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10251 if (mod_f != MEMMODEL_RELAXED)
10252 emit_label (label2);
10254 arc_post_atomic_barrier (mod_s);
10256 if (mod_f == MEMMODEL_RELAXED)
10257 emit_label (label2);
10260 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10261 to perform. MEM is the memory on which to operate. VAL is the second
10262 operand of the binary operator. BEFORE and AFTER are optional locations to
10263 return the value of MEM either before of after the operation. MODEL_RTX
10264 is a CONST_INT containing the memory model to use. */
10266 void
10267 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10268 rtx orig_before, rtx orig_after, rtx model_rtx)
10270 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10271 machine_mode mode = GET_MODE (mem);
10272 rtx label, x, cond;
10273 rtx before = orig_before, after = orig_after;
10275 /* ARC atomic ops work only with 32-bit aligned memories. */
10276 gcc_assert (mode == SImode);
10278 arc_pre_atomic_barrier (model);
10280 label = gen_label_rtx ();
10281 emit_label (label);
10282 label = gen_rtx_LABEL_REF (VOIDmode, label);
10284 if (before == NULL_RTX)
10285 before = gen_reg_rtx (mode);
10287 if (after == NULL_RTX)
10288 after = gen_reg_rtx (mode);
10290 /* Load exclusive. */
10291 emit_insn (gen_arc_load_exclusivesi (before, mem));
10293 switch (code)
10295 case NOT:
10296 x = gen_rtx_AND (mode, before, val);
10297 emit_insn (gen_rtx_SET (after, x));
10298 x = gen_rtx_NOT (mode, after);
10299 emit_insn (gen_rtx_SET (after, x));
10300 break;
10302 case MINUS:
10303 if (CONST_INT_P (val))
10305 val = GEN_INT (-INTVAL (val));
10306 code = PLUS;
10309 /* FALLTHRU. */
10310 default:
10311 x = gen_rtx_fmt_ee (code, mode, before, val);
10312 emit_insn (gen_rtx_SET (after, x));
10313 break;
10316 /* Exclusively store new item. Store clobbers CC reg. */
10317 emit_insn (gen_arc_store_exclusivesi (mem, after));
10319 /* Check the result of the store. */
10320 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10321 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10322 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10323 label, pc_rtx);
10324 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10326 arc_post_atomic_barrier (model);
10329 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10331 static bool
10332 arc_no_speculation_in_delay_slots_p ()
10334 return true;
10337 /* Return a parallel of registers to represent where to find the
10338 register pieces if required, otherwise NULL_RTX. */
10340 static rtx
10341 arc_dwarf_register_span (rtx rtl)
10343 machine_mode mode = GET_MODE (rtl);
10344 unsigned regno;
10345 rtx p;
10347 if (GET_MODE_SIZE (mode) != 8)
10348 return NULL_RTX;
10350 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10351 regno = REGNO (rtl);
10352 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10353 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10355 return p;
10358 /* Return true if OP is an acceptable memory operand for ARCompact
10359 16-bit load instructions of MODE.
10361 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10362 non scaled instructions.
10364 SCALED: TRUE if address can be scaled. */
10366 bool
10367 compact_memory_operand_p (rtx op, machine_mode mode,
10368 bool av2short, bool scaled)
10370 rtx addr, plus0, plus1;
10371 int size, off;
10373 /* Eliminate non-memory operations. */
10374 if (GET_CODE (op) != MEM)
10375 return 0;
10377 /* .di instructions have no 16-bit form. */
10378 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10379 return false;
10381 if (mode == VOIDmode)
10382 mode = GET_MODE (op);
10384 size = GET_MODE_SIZE (mode);
10386 /* dword operations really put out 2 instructions, so eliminate
10387 them. */
10388 if (size > UNITS_PER_WORD)
10389 return false;
10391 /* Decode the address now. */
10392 addr = XEXP (op, 0);
10393 switch (GET_CODE (addr))
10395 case REG:
10396 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10397 || COMPACT_GP_REG_P (REGNO (addr))
10398 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10399 case PLUS:
10400 plus0 = XEXP (addr, 0);
10401 plus1 = XEXP (addr, 1);
10403 if ((GET_CODE (plus0) == REG)
10404 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10405 || COMPACT_GP_REG_P (REGNO (plus0)))
10406 && ((GET_CODE (plus1) == REG)
10407 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10408 || COMPACT_GP_REG_P (REGNO (plus1)))))
10410 return !av2short;
10413 if ((GET_CODE (plus0) == REG)
10414 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10415 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10416 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10417 && (GET_CODE (plus1) == CONST_INT))
10419 bool valid = false;
10421 off = INTVAL (plus1);
10423 /* Negative offset is not supported in 16-bit load/store insns. */
10424 if (off < 0)
10425 return 0;
10427 /* Only u5 immediates allowed in code density instructions. */
10428 if (av2short)
10430 switch (size)
10432 case 1:
10433 return false;
10434 case 2:
10435 /* This is an ldh_s.x instruction, check the u6
10436 immediate. */
10437 if (COMPACT_GP_REG_P (REGNO (plus0)))
10438 valid = true;
10439 break;
10440 case 4:
10441 /* Only u5 immediates allowed in 32bit access code
10442 density instructions. */
10443 if (REGNO (plus0) <= 31)
10444 return ((off < 32) && (off % 4 == 0));
10445 break;
10446 default:
10447 return false;
10450 else
10451 if (COMPACT_GP_REG_P (REGNO (plus0)))
10452 valid = true;
10454 if (valid)
10457 switch (size)
10459 case 1:
10460 return (off < 32);
10461 case 2:
10462 /* The 6-bit constant get shifted to fit the real
10463 5-bits field. Check also for the alignment. */
10464 return ((off < 64) && (off % 2 == 0));
10465 case 4:
10466 return ((off < 128) && (off % 4 == 0));
10467 default:
10468 return false;
10473 if (REG_P (plus0) && CONST_INT_P (plus1)
10474 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10475 || SP_REG_P (REGNO (plus0)))
10476 && !av2short)
10478 off = INTVAL (plus1);
10479 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10482 if ((GET_CODE (plus0) == MULT)
10483 && (GET_CODE (XEXP (plus0, 0)) == REG)
10484 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10485 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10486 && (GET_CODE (plus1) == REG)
10487 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10488 || COMPACT_GP_REG_P (REGNO (plus1))))
10489 return scaled;
10490 default:
10491 break ;
10492 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10493 for 16-bit load instructions. */
10495 return false;
10498 struct gcc_target targetm = TARGET_INITIALIZER;
10500 #include "gt-arc.h"