Turn HARD_REGNO_MODE_OK into a target hook
[official-gcc.git] / gcc / config / arc / arc.c
blob3438980d1c3758fe56ca728ed58cf192015b459a
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"
68 #include "hw-doloop.h"
70 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
71 static char arc_cpu_name[10] = "";
72 static const char *arc_cpu_string = arc_cpu_name;
74 /* Maximum size of a loop. */
75 #define ARC_MAX_LOOP_LENGTH 4095
77 /* ??? Loads can handle any constant, stores can only handle small ones. */
78 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
79 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
80 (GET_CODE (X) == CONST_INT \
81 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
82 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
83 ? 0 \
84 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
86 #define LEGITIMATE_SMALL_DATA_OFFSET_P(X) \
87 (GET_CODE (X) == CONST \
88 && GET_CODE (XEXP ((X), 0)) == PLUS \
89 && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \
90 && SYMBOL_REF_SMALL_P (XEXP (XEXP ((X), 0), 0)) \
91 && GET_CODE (XEXP(XEXP ((X), 0), 1)) == CONST_INT \
92 && INTVAL (XEXP (XEXP ((X), 0), 1)) <= g_switch_value)
94 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
95 (GET_CODE (X) == PLUS \
96 && REG_P (XEXP ((X), 0)) \
97 && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM \
98 && ((GET_CODE (XEXP ((X), 1)) == SYMBOL_REF \
99 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
100 || LEGITIMATE_SMALL_DATA_OFFSET_P (XEXP ((X), 1))))
102 /* Array of valid operand punctuation characters. */
103 char arc_punct_chars[256];
105 /* State used by arc_ccfsm_advance to implement conditional execution. */
106 struct GTY (()) arc_ccfsm
108 int state;
109 int cc;
110 rtx cond;
111 rtx_insn *target_insn;
112 int target_label;
115 /* Status of the IRQ_CTRL_AUX register. */
116 typedef struct irq_ctrl_saved_t
118 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
119 short irq_save_last_reg;
120 /* True if BLINK is automatically saved. */
121 bool irq_save_blink;
122 /* True if LPCOUNT is automatically saved. */
123 bool irq_save_lpcount;
124 } irq_ctrl_saved_t;
125 static irq_ctrl_saved_t irq_ctrl_saved;
127 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
128 ((ARC_INTERRUPT_P (FNTYPE) \
129 && irq_ctrl_saved.irq_save_blink) \
130 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
131 && rgf_banked_register_count > 8))
133 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
134 ((ARC_INTERRUPT_P (FNTYPE) \
135 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
136 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
137 && rgf_banked_register_count > 8))
139 #define ARC_AUTO_IRQ_P(FNTYPE) \
140 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
141 && (irq_ctrl_saved.irq_save_blink \
142 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
144 /* Number of registers in second bank for FIRQ support. */
145 static int rgf_banked_register_count;
147 #define arc_ccfsm_current cfun->machine->ccfsm_current
149 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
150 ((STATE)->state == 1 || (STATE)->state == 2)
152 /* Indicate we're conditionalizing insns now. */
153 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
154 ((STATE)->state += 2)
156 #define ARC_CCFSM_COND_EXEC_P(STATE) \
157 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
158 || current_insn_predicate)
160 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
161 #define CCFSM_ISCOMPACT(INSN,STATE) \
162 (ARC_CCFSM_COND_EXEC_P (STATE) \
163 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
164 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
165 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
167 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
168 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
169 ((ARC_CCFSM_COND_EXEC_P (STATE) \
170 || (JUMP_P (JUMP) \
171 && INSN_ANNULLED_BRANCH_P (JUMP) \
172 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
173 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
174 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
175 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
177 /* The maximum number of insns skipped which will be conditionalised if
178 possible. */
179 /* When optimizing for speed:
180 Let p be the probability that the potentially skipped insns need to
181 be executed, pn the cost of a correctly predicted non-taken branch,
182 mt the cost of a mis/non-predicted taken branch,
183 mn mispredicted non-taken, pt correctly predicted taken ;
184 costs expressed in numbers of instructions like the ones considered
185 skipping.
186 Unfortunately we don't have a measure of predictability - this
187 is linked to probability only in that in the no-eviction-scenario
188 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
189 value that can be assumed *if* the distribution is perfectly random.
190 A predictability of 1 is perfectly plausible not matter what p is,
191 because the decision could be dependent on an invocation parameter
192 of the program.
193 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
194 For small p, we want MAX_INSNS_SKIPPED == pt
196 When optimizing for size:
197 We want to skip insn unless we could use 16 opcodes for the
198 non-conditionalized insn to balance the branch length or more.
199 Performance can be tie-breaker. */
200 /* If the potentially-skipped insns are likely to be executed, we'll
201 generally save one non-taken branch
203 this to be no less than the 1/p */
204 #define MAX_INSNS_SKIPPED 3
206 /* A nop is needed between a 4 byte insn that sets the condition codes and
207 a branch that uses them (the same isn't true for an 8 byte insn that sets
208 the condition codes). Set by arc_ccfsm_advance. Used by
209 arc_print_operand. */
211 static int get_arc_condition_code (rtx);
213 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
214 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
216 /* Initialized arc_attribute_table to NULL since arc doesnot have any
217 machine specific supported attributes. */
218 const struct attribute_spec arc_attribute_table[] =
220 /* { name, min_len, max_len, decl_req, type_req, fn_type_req, handler,
221 affects_type_identity } */
222 { "interrupt", 1, 1, true, false, false, arc_handle_interrupt_attribute, true },
223 /* Function calls made to this symbol must be done indirectly, because
224 it may lie outside of the 21/25 bit addressing range of a normal function
225 call. */
226 { "long_call", 0, 0, false, true, true, NULL, false },
227 /* Whereas these functions are always known to reside within the 25 bit
228 addressing range of unconditionalized bl. */
229 { "medium_call", 0, 0, false, true, true, NULL, false },
230 /* And these functions are always known to reside within the 21 bit
231 addressing range of blcc. */
232 { "short_call", 0, 0, false, true, true, NULL, false },
233 /* Function which are not having the prologue and epilogue generated
234 by the compiler. */
235 { "naked", 0, 0, true, false, false, arc_handle_fndecl_attribute, false },
236 { NULL, 0, 0, false, false, false, NULL, false }
238 static int arc_comp_type_attributes (const_tree, const_tree);
239 static void arc_file_start (void);
240 static void arc_internal_label (FILE *, const char *, unsigned long);
241 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
242 tree);
243 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
244 static void arc_encode_section_info (tree decl, rtx rtl, int first);
246 static void arc_init_builtins (void);
247 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
249 static int branch_dest (rtx);
251 static void arc_output_pic_addr_const (FILE *, rtx, int);
252 static bool arc_function_ok_for_sibcall (tree, tree);
253 static rtx arc_function_value (const_tree, const_tree, bool);
254 const char * output_shift (rtx *);
255 static void arc_reorg (void);
256 static bool arc_in_small_data_p (const_tree);
258 static void arc_init_reg_tables (void);
259 static bool arc_return_in_memory (const_tree, const_tree);
260 static bool arc_vector_mode_supported_p (machine_mode);
262 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
263 unsigned int, bool);
264 static const char *arc_invalid_within_doloop (const rtx_insn *);
266 static void output_short_suffix (FILE *file);
268 static bool arc_frame_pointer_required (void);
270 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
271 unsigned int,
272 enum by_pieces_operation op,
273 bool);
275 /* Globally visible information about currently selected cpu. */
276 const arc_cpu_t *arc_selected_cpu;
278 static bool
279 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
281 if (GET_CODE (op) != PLUS)
282 return false;
284 if (GET_CODE (XEXP (op, 0)) != MULT)
285 return false;
287 /* Check multiplication operands. */
288 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
289 return false;
291 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
292 return false;
294 switch (GET_MODE_SIZE (mode))
296 case 2:
297 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
298 return false;
299 break;
300 case 8:
301 if (!TARGET_LL64)
302 return false;
303 /* Fall through. */
304 case 4:
305 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
306 return false;
307 default:
308 return false;
311 /* Check the base. */
312 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
313 return true;
315 if (flag_pic)
317 if (CONST_INT_P (XEXP (op, 1)))
318 return true;
319 return false;
321 if (CONSTANT_P (XEXP (op, 1)))
323 /* Scalled addresses for sdata is done other places. */
324 if (GET_CODE (XEXP (op, 1)) == SYMBOL_REF
325 && SYMBOL_REF_SMALL_P (XEXP (op, 1)))
326 return false;
327 return true;
330 return false;
333 /* Check for constructions like REG + OFFS, where OFFS can be a
334 register, an immediate or an long immediate. */
336 static bool
337 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
339 if (GET_CODE (x) != PLUS)
340 return false;
342 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
343 return false;
345 /* Check for: [Rx + small offset] or [Rx + Ry]. */
346 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict))
347 && GET_MODE_SIZE ((mode)) <= 4)
348 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1))))
349 return true;
351 /* Check for [Rx + symbol]. */
352 if (!flag_pic
353 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
354 /* Avoid this type of address for double or larger modes. */
355 && (GET_MODE_SIZE (mode) <= 4)
356 /* Avoid small data which ends in something like GP +
357 symb@sda. */
358 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
359 return true;
361 return false;
364 /* Implements target hook vector_mode_supported_p. */
366 static bool
367 arc_vector_mode_supported_p (machine_mode mode)
369 switch (mode)
371 case E_V2HImode:
372 return TARGET_PLUS_DMPY;
373 case E_V4HImode:
374 case E_V2SImode:
375 return TARGET_PLUS_QMACW;
376 case E_V4SImode:
377 case E_V8HImode:
378 return TARGET_SIMD_SET;
380 default:
381 return false;
385 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
387 static machine_mode
388 arc_preferred_simd_mode (scalar_mode mode)
390 switch (mode)
392 case E_HImode:
393 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
394 case E_SImode:
395 return V2SImode;
397 default:
398 return word_mode;
402 /* Implements target hook
403 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
405 static unsigned int
406 arc_autovectorize_vector_sizes (void)
408 return TARGET_PLUS_QMACW ? (8 | 4) : 0;
411 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
412 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
413 static rtx arc_delegitimize_address (rtx);
414 static bool arc_can_follow_jump (const rtx_insn *follower,
415 const rtx_insn *followee);
417 static rtx frame_insn (rtx);
418 static void arc_function_arg_advance (cumulative_args_t, machine_mode,
419 const_tree, bool);
420 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
422 static void arc_finalize_pic (void);
424 /* initialize the GCC target structure. */
425 #undef TARGET_COMP_TYPE_ATTRIBUTES
426 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
427 #undef TARGET_ASM_FILE_START
428 #define TARGET_ASM_FILE_START arc_file_start
429 #undef TARGET_ATTRIBUTE_TABLE
430 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
431 #undef TARGET_ASM_INTERNAL_LABEL
432 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
433 #undef TARGET_RTX_COSTS
434 #define TARGET_RTX_COSTS arc_rtx_costs
435 #undef TARGET_ADDRESS_COST
436 #define TARGET_ADDRESS_COST arc_address_cost
438 #undef TARGET_ENCODE_SECTION_INFO
439 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
441 #undef TARGET_CANNOT_FORCE_CONST_MEM
442 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
444 #undef TARGET_INIT_BUILTINS
445 #define TARGET_INIT_BUILTINS arc_init_builtins
447 #undef TARGET_EXPAND_BUILTIN
448 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
450 #undef TARGET_BUILTIN_DECL
451 #define TARGET_BUILTIN_DECL arc_builtin_decl
453 #undef TARGET_ASM_OUTPUT_MI_THUNK
454 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
456 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
457 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
459 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
460 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
462 #undef TARGET_MACHINE_DEPENDENT_REORG
463 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
465 #undef TARGET_IN_SMALL_DATA_P
466 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
468 #undef TARGET_PROMOTE_FUNCTION_MODE
469 #define TARGET_PROMOTE_FUNCTION_MODE \
470 default_promote_function_mode_always_promote
472 #undef TARGET_PROMOTE_PROTOTYPES
473 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
475 #undef TARGET_RETURN_IN_MEMORY
476 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
477 #undef TARGET_PASS_BY_REFERENCE
478 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
480 #undef TARGET_SETUP_INCOMING_VARARGS
481 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
483 #undef TARGET_ARG_PARTIAL_BYTES
484 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
486 #undef TARGET_MUST_PASS_IN_STACK
487 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
489 #undef TARGET_FUNCTION_VALUE
490 #define TARGET_FUNCTION_VALUE arc_function_value
492 #undef TARGET_SCHED_ADJUST_PRIORITY
493 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
495 #undef TARGET_VECTOR_MODE_SUPPORTED_P
496 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
498 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
499 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
501 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
502 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
504 #undef TARGET_CAN_USE_DOLOOP_P
505 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
507 #undef TARGET_INVALID_WITHIN_DOLOOP
508 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
510 #undef TARGET_PRESERVE_RELOAD_P
511 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
513 #undef TARGET_CAN_FOLLOW_JUMP
514 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
516 #undef TARGET_DELEGITIMIZE_ADDRESS
517 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
519 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
520 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
521 arc_use_by_pieces_infrastructure_p
523 /* Usually, we will be able to scale anchor offsets.
524 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
525 #undef TARGET_MIN_ANCHOR_OFFSET
526 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
527 #undef TARGET_MAX_ANCHOR_OFFSET
528 #define TARGET_MAX_ANCHOR_OFFSET (1020)
530 #undef TARGET_SECONDARY_RELOAD
531 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
533 #define TARGET_OPTION_OVERRIDE arc_override_options
535 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
537 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
539 #define TARGET_TRAMPOLINE_ADJUST_ADDRESS arc_trampoline_adjust_address
541 #define TARGET_CAN_ELIMINATE arc_can_eliminate
543 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
545 #define TARGET_FUNCTION_ARG arc_function_arg
547 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
549 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
551 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
553 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
555 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
557 #define TARGET_ADJUST_INSN_LENGTH arc_adjust_insn_length
559 #define TARGET_INSN_LENGTH_PARAMETERS arc_insn_length_parameters
561 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
562 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
563 arc_no_speculation_in_delay_slots_p
565 #undef TARGET_LRA_P
566 #define TARGET_LRA_P arc_lra_p
567 #define TARGET_REGISTER_PRIORITY arc_register_priority
568 /* Stores with scaled offsets have different displacement ranges. */
569 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
570 #define TARGET_SPILL_CLASS arc_spill_class
572 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
573 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
575 #undef TARGET_WARN_FUNC_RETURN
576 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
578 #include "target-def.h"
580 #undef TARGET_ASM_ALIGNED_HI_OP
581 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
582 #undef TARGET_ASM_ALIGNED_SI_OP
583 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
585 #ifdef HAVE_AS_TLS
586 #undef TARGET_HAVE_TLS
587 #define TARGET_HAVE_TLS HAVE_AS_TLS
588 #endif
590 #undef TARGET_DWARF_REGISTER_SPAN
591 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
593 #undef TARGET_HARD_REGNO_MODE_OK
594 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
596 /* Try to keep the (mov:DF _, reg) as early as possible so
597 that the d<add/sub/mul>h-lr insns appear together and can
598 use the peephole2 pattern. */
600 static int
601 arc_sched_adjust_priority (rtx_insn *insn, int priority)
603 rtx set = single_set (insn);
604 if (set
605 && GET_MODE (SET_SRC(set)) == DFmode
606 && GET_CODE (SET_SRC(set)) == REG)
608 /* Incrementing priority by 20 (empirically derived). */
609 return priority + 20;
612 return priority;
615 /* For ARC base register + offset addressing, the validity of the
616 address is mode-dependent for most of the offset range, as the
617 offset can be scaled by the access size.
618 We don't expose these as mode-dependent addresses in the
619 mode_dependent_address_p target hook, because that would disable
620 lots of optimizations, and most uses of these addresses are for 32
621 or 64 bit accesses anyways, which are fine.
622 However, that leaves some addresses for 8 / 16 bit values not
623 properly reloaded by the generic code, which is why we have to
624 schedule secondary reloads for these. */
626 static reg_class_t
627 arc_secondary_reload (bool in_p,
628 rtx x,
629 reg_class_t cl,
630 machine_mode mode,
631 secondary_reload_info *sri)
633 enum rtx_code code = GET_CODE (x);
635 if (cl == DOUBLE_REGS)
636 return GENERAL_REGS;
638 /* The loop counter register can be stored, but not loaded directly. */
639 if ((cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS)
640 && in_p && MEM_P (x))
641 return GENERAL_REGS;
643 /* If we have a subreg (reg), where reg is a pseudo (that will end in
644 a memory location), then we may need a scratch register to handle
645 the fp/sp+largeoffset address. */
646 if (code == SUBREG)
648 rtx addr = NULL_RTX;
649 x = SUBREG_REG (x);
651 if (REG_P (x))
653 int regno = REGNO (x);
654 if (regno >= FIRST_PSEUDO_REGISTER)
655 regno = reg_renumber[regno];
657 if (regno != -1)
658 return NO_REGS;
660 /* It is a pseudo that ends in a stack location. */
661 if (reg_equiv_mem (REGNO (x)))
663 /* Get the equivalent address and check the range of the
664 offset. */
665 rtx mem = reg_equiv_mem (REGNO (x));
666 addr = find_replacement (&XEXP (mem, 0));
669 else
671 gcc_assert (MEM_P (x));
672 addr = XEXP (x, 0);
673 addr = simplify_rtx (addr);
675 if (addr && GET_CODE (addr) == PLUS
676 && CONST_INT_P (XEXP (addr, 1))
677 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
679 switch (mode)
681 case E_QImode:
682 sri->icode =
683 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store;
684 break;
685 case E_HImode:
686 sri->icode =
687 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store;
688 break;
689 default:
690 break;
694 return NO_REGS;
697 /* Convert reloads using offsets that are too large to use indirect
698 addressing. */
700 void
701 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
703 rtx addr;
705 gcc_assert (GET_CODE (mem) == MEM);
706 addr = XEXP (mem, 0);
708 /* Large offset: use a move. FIXME: ld ops accepts limms as
709 offsets. Hence, the following move insn is not required. */
710 emit_move_insn (scratch, addr);
711 mem = replace_equiv_address_nv (mem, scratch);
713 /* Now create the move. */
714 if (store_p)
715 emit_insn (gen_rtx_SET (mem, reg));
716 else
717 emit_insn (gen_rtx_SET (reg, mem));
719 return;
722 static unsigned arc_ifcvt (void);
724 namespace {
726 const pass_data pass_data_arc_ifcvt =
728 RTL_PASS,
729 "arc_ifcvt", /* name */
730 OPTGROUP_NONE, /* optinfo_flags */
731 TV_IFCVT2, /* tv_id */
732 0, /* properties_required */
733 0, /* properties_provided */
734 0, /* properties_destroyed */
735 0, /* todo_flags_start */
736 TODO_df_finish /* todo_flags_finish */
739 class pass_arc_ifcvt : public rtl_opt_pass
741 public:
742 pass_arc_ifcvt(gcc::context *ctxt)
743 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt)
746 /* opt_pass methods: */
747 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); }
748 virtual unsigned int execute (function *) { return arc_ifcvt (); }
751 } // anon namespace
753 rtl_opt_pass *
754 make_pass_arc_ifcvt (gcc::context *ctxt)
756 return new pass_arc_ifcvt (ctxt);
759 static unsigned arc_predicate_delay_insns (void);
761 namespace {
763 const pass_data pass_data_arc_predicate_delay_insns =
765 RTL_PASS,
766 "arc_predicate_delay_insns", /* name */
767 OPTGROUP_NONE, /* optinfo_flags */
768 TV_IFCVT2, /* tv_id */
769 0, /* properties_required */
770 0, /* properties_provided */
771 0, /* properties_destroyed */
772 0, /* todo_flags_start */
773 TODO_df_finish /* todo_flags_finish */
776 class pass_arc_predicate_delay_insns : public rtl_opt_pass
778 public:
779 pass_arc_predicate_delay_insns(gcc::context *ctxt)
780 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
783 /* opt_pass methods: */
784 virtual unsigned int execute (function *)
786 return arc_predicate_delay_insns ();
790 } // anon namespace
792 rtl_opt_pass *
793 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
795 return new pass_arc_predicate_delay_insns (ctxt);
798 /* Called by OVERRIDE_OPTIONS to initialize various things. */
800 static void
801 arc_init (void)
803 if (TARGET_V2)
805 /* I have the multiplier, then use it*/
806 if (TARGET_MPYW || TARGET_MULTI)
807 arc_multcost = COSTS_N_INSNS (1);
809 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
810 if (arc_multcost < 0)
811 switch (arc_tune)
813 case TUNE_ARC700_4_2_STD:
814 /* latency 7;
815 max throughput (1 multiply + 4 other insns) / 5 cycles. */
816 arc_multcost = COSTS_N_INSNS (4);
817 if (TARGET_NOMPY_SET)
818 arc_multcost = COSTS_N_INSNS (30);
819 break;
820 case TUNE_ARC700_4_2_XMAC:
821 /* latency 5;
822 max throughput (1 multiply + 2 other insns) / 3 cycles. */
823 arc_multcost = COSTS_N_INSNS (3);
824 if (TARGET_NOMPY_SET)
825 arc_multcost = COSTS_N_INSNS (30);
826 break;
827 case TUNE_ARC600:
828 if (TARGET_MUL64_SET)
830 arc_multcost = COSTS_N_INSNS (4);
831 break;
833 /* Fall through. */
834 default:
835 arc_multcost = COSTS_N_INSNS (30);
836 break;
839 /* MPY instructions valid only for ARC700 or ARCv2. */
840 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
841 error ("-mno-mpy supported only for ARC700 or ARCv2");
843 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
844 error ("-mno-dpfp-lrsr supported only with -mdpfp");
846 /* FPX-1. No fast and compact together. */
847 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
848 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
849 error ("FPX fast and compact options cannot be specified together");
851 /* FPX-2. No fast-spfp for arc600 or arc601. */
852 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
853 error ("-mspfp_fast not available on ARC600 or ARC601");
855 /* FPX-4. No FPX extensions mixed with FPU extensions. */
856 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
857 && TARGET_HARD_FLOAT)
858 error ("No FPX/FPU mixing allowed");
860 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
861 if (flag_pic && TARGET_ARC600_FAMILY)
863 warning (DK_WARNING,
864 "PIC is not supported for %s. Generating non-PIC code only..",
865 arc_cpu_string);
866 flag_pic = 0;
869 arc_init_reg_tables ();
871 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
872 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
873 arc_punct_chars['#'] = 1;
874 arc_punct_chars['*'] = 1;
875 arc_punct_chars['?'] = 1;
876 arc_punct_chars['!'] = 1;
877 arc_punct_chars['^'] = 1;
878 arc_punct_chars['&'] = 1;
879 arc_punct_chars['+'] = 1;
880 arc_punct_chars['_'] = 1;
882 if (optimize > 1 && !TARGET_NO_COND_EXEC)
884 /* There are two target-independent ifcvt passes, and arc_reorg may do
885 one or more arc_ifcvt calls. */
886 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g);
887 struct register_pass_info arc_ifcvt4_info
888 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER };
889 struct register_pass_info arc_ifcvt5_info
890 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE };
892 register_pass (&arc_ifcvt4_info);
893 register_pass (&arc_ifcvt5_info);
896 if (flag_delayed_branch)
898 opt_pass *pass_arc_predicate_delay_insns
899 = make_pass_arc_predicate_delay_insns (g);
900 struct register_pass_info arc_predicate_delay_info
901 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER };
903 register_pass (&arc_predicate_delay_info);
907 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
908 register range is specified as two registers separated by a dash.
909 It always starts with r0, and its upper limit is fp register.
910 blink and lp_count registers are optional. */
912 static void
913 irq_range (const char *cstr)
915 int i, first, last, blink, lpcount, xreg;
916 char *str, *dash, *comma;
918 i = strlen (cstr);
919 str = (char *) alloca (i + 1);
920 memcpy (str, cstr, i + 1);
921 blink = -1;
922 lpcount = -1;
924 dash = strchr (str, '-');
925 if (!dash)
927 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
928 return;
930 *dash = '\0';
932 comma = strchr (dash + 1, ',');
933 if (comma)
934 *comma = '\0';
936 first = decode_reg_name (str);
937 if (first != 0)
939 warning (0, "first register must be R0");
940 return;
943 /* At this moment we do not have the register names initialized
944 accordingly. */
945 if (!strcmp (dash + 1, "ilink"))
946 last = 29;
947 else
948 last = decode_reg_name (dash + 1);
950 if (last < 0)
952 warning (0, "unknown register name: %s", dash + 1);
953 return;
956 if (!(last & 0x01))
958 warning (0, "last register name %s must be an odd register", dash + 1);
959 return;
962 *dash = '-';
964 if (first > last)
966 warning (0, "%s-%s is an empty range", str, dash + 1);
967 return;
970 while (comma)
972 *comma = ',';
973 str = comma + 1;
975 comma = strchr (str, ',');
976 if (comma)
977 *comma = '\0';
979 xreg = decode_reg_name (str);
980 switch (xreg)
982 case 31:
983 blink = 31;
984 break;
986 case 60:
987 lpcount = 60;
988 break;
990 default:
991 warning (0, "unknown register name: %s", str);
992 return;
996 irq_ctrl_saved.irq_save_last_reg = last;
997 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31);
998 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60);
1001 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1002 8, 16, or 32. */
1004 static void
1005 parse_mrgf_banked_regs_option (const char *arg)
1007 long int val;
1008 char *end_ptr;
1010 errno = 0;
1011 val = strtol (arg, &end_ptr, 10);
1012 if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
1013 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
1015 error ("invalid number in -mrgf-banked-regs=%s "
1016 "valid values are 0, 4, 8, 16, or 32", arg);
1017 return;
1019 rgf_banked_register_count = (int) val;
1022 /* Check ARC options, generate derived target attributes. */
1024 static void
1025 arc_override_options (void)
1027 unsigned int i;
1028 cl_deferred_option *opt;
1029 vec<cl_deferred_option> *vopt
1030 = (vec<cl_deferred_option> *) arc_deferred_options;
1032 if (arc_cpu == PROCESSOR_NONE)
1033 arc_cpu = TARGET_CPU_DEFAULT;
1035 /* Set the default cpu options. */
1036 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
1038 /* Set the architectures. */
1039 switch (arc_selected_cpu->arch_info->arch_id)
1041 case BASE_ARCH_em:
1042 arc_cpu_string = "EM";
1043 break;
1044 case BASE_ARCH_hs:
1045 arc_cpu_string = "HS";
1046 break;
1047 case BASE_ARCH_700:
1048 if (arc_selected_cpu->processor == PROCESSOR_nps400)
1049 arc_cpu_string = "NPS400";
1050 else
1051 arc_cpu_string = "ARC700";
1052 break;
1053 case BASE_ARCH_6xx:
1054 arc_cpu_string = "ARC600";
1055 break;
1056 default:
1057 gcc_unreachable ();
1060 irq_ctrl_saved.irq_save_last_reg = -1;
1061 irq_ctrl_saved.irq_save_blink = false;
1062 irq_ctrl_saved.irq_save_lpcount = false;
1064 rgf_banked_register_count = 0;
1066 /* Handle the deferred options. */
1067 if (vopt)
1068 FOR_EACH_VEC_ELT (*vopt, i, opt)
1070 switch (opt->opt_index)
1072 case OPT_mirq_ctrl_saved_:
1073 if (TARGET_V2)
1074 irq_range (opt->arg);
1075 else
1076 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1077 break;
1079 case OPT_mrgf_banked_regs_:
1080 if (TARGET_V2)
1081 parse_mrgf_banked_regs_option (opt->arg);
1082 else
1083 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1084 break;
1086 default:
1087 gcc_unreachable();
1091 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1092 specific flags are set in arc-common.c. The architecture forces
1093 the default hardware configurations in, regardless what command
1094 line options are saying. The CPU optional hw options can be
1095 turned on or off. */
1096 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1097 do { \
1098 if ((arc_selected_cpu->flags & CODE) \
1099 && ((target_flags_explicit & MASK) == 0)) \
1100 target_flags |= MASK; \
1101 if (arc_selected_cpu->arch_info->dflags & CODE) \
1102 target_flags |= MASK; \
1103 } while (0);
1104 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1105 do { \
1106 if ((arc_selected_cpu->flags & CODE) \
1107 && (VAR == DEFAULT_##VAR)) \
1108 VAR = VAL; \
1109 if (arc_selected_cpu->arch_info->dflags & CODE) \
1110 VAR = VAL; \
1111 } while (0);
1113 #include "arc-options.def"
1115 #undef ARC_OPTX
1116 #undef ARC_OPT
1118 /* Check options against architecture options. Throw an error if
1119 option is not allowed. */
1120 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1121 do { \
1122 if ((VAR == VAL) \
1123 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1125 error ("%s is not available for %s architecture", \
1126 DOC, arc_selected_cpu->arch_info->name); \
1128 } while (0);
1129 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1130 do { \
1131 if ((target_flags & MASK) \
1132 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1133 error ("%s is not available for %s architecture", \
1134 DOC, arc_selected_cpu->arch_info->name); \
1135 } while (0);
1137 #include "arc-options.def"
1139 #undef ARC_OPTX
1140 #undef ARC_OPT
1142 /* Set Tune option. */
1143 if (arc_tune == TUNE_NONE)
1144 arc_tune = (enum attr_tune) arc_selected_cpu->tune;
1146 if (arc_size_opt_level == 3)
1147 optimize_size = 1;
1149 /* Compact casesi is not a valid option for ARCv2 family. */
1150 if (TARGET_V2)
1152 if (TARGET_COMPACT_CASESI)
1154 warning (0, "compact-casesi is not applicable to ARCv2");
1155 TARGET_COMPACT_CASESI = 0;
1158 else if (optimize_size == 1
1159 && !global_options_set.x_TARGET_COMPACT_CASESI)
1160 TARGET_COMPACT_CASESI = 1;
1162 if (flag_pic)
1163 target_flags |= MASK_NO_SDATA_SET;
1165 if (flag_no_common == 255)
1166 flag_no_common = !TARGET_NO_SDATA_SET;
1168 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1169 if (TARGET_MIXED_CODE)
1170 TARGET_Q_CLASS = 1;
1171 if (!TARGET_Q_CLASS)
1172 TARGET_COMPACT_CASESI = 0;
1173 if (TARGET_COMPACT_CASESI)
1174 TARGET_CASE_VECTOR_PC_RELATIVE = 1;
1176 /* Check for small data option */
1177 if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
1178 g_switch_value = TARGET_LL64 ? 8 : 4;
1180 /* These need to be done at start up. It's convenient to do them here. */
1181 arc_init ();
1184 /* The condition codes of the ARC, and the inverse function. */
1185 /* For short branches, the "c" / "nc" names are not defined in the ARC
1186 Programmers manual, so we have to use "lo" / "hs"" instead. */
1187 static const char *arc_condition_codes[] =
1189 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1190 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1193 enum arc_cc_code_index
1195 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
1196 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
1197 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
1198 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
1201 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1203 /* Returns the index of the ARC condition code string in
1204 `arc_condition_codes'. COMPARISON should be an rtx like
1205 `(eq (...) (...))'. */
1207 static int
1208 get_arc_condition_code (rtx comparison)
1210 switch (GET_MODE (XEXP (comparison, 0)))
1212 case E_CCmode:
1213 case E_SImode: /* For BRcc. */
1214 switch (GET_CODE (comparison))
1216 case EQ : return ARC_CC_EQ;
1217 case NE : return ARC_CC_NE;
1218 case GT : return ARC_CC_GT;
1219 case LE : return ARC_CC_LE;
1220 case GE : return ARC_CC_GE;
1221 case LT : return ARC_CC_LT;
1222 case GTU : return ARC_CC_HI;
1223 case LEU : return ARC_CC_LS;
1224 case LTU : return ARC_CC_LO;
1225 case GEU : return ARC_CC_HS;
1226 default : gcc_unreachable ();
1228 case E_CC_ZNmode:
1229 switch (GET_CODE (comparison))
1231 case EQ : return ARC_CC_EQ;
1232 case NE : return ARC_CC_NE;
1233 case GE: return ARC_CC_P;
1234 case LT: return ARC_CC_N;
1235 case GT : return ARC_CC_PNZ;
1236 default : gcc_unreachable ();
1238 case E_CC_Zmode:
1239 switch (GET_CODE (comparison))
1241 case EQ : return ARC_CC_EQ;
1242 case NE : return ARC_CC_NE;
1243 default : gcc_unreachable ();
1245 case E_CC_Cmode:
1246 switch (GET_CODE (comparison))
1248 case LTU : return ARC_CC_C;
1249 case GEU : return ARC_CC_NC;
1250 default : gcc_unreachable ();
1252 case E_CC_FP_GTmode:
1253 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1254 switch (GET_CODE (comparison))
1256 case GT : return ARC_CC_N;
1257 case UNLE: return ARC_CC_P;
1258 default : gcc_unreachable ();
1260 else
1261 switch (GET_CODE (comparison))
1263 case GT : return ARC_CC_HI;
1264 case UNLE : return ARC_CC_LS;
1265 default : gcc_unreachable ();
1267 case E_CC_FP_GEmode:
1268 /* Same for FPX and non-FPX. */
1269 switch (GET_CODE (comparison))
1271 case GE : return ARC_CC_HS;
1272 case UNLT : return ARC_CC_LO;
1273 default : gcc_unreachable ();
1275 case E_CC_FP_UNEQmode:
1276 switch (GET_CODE (comparison))
1278 case UNEQ : return ARC_CC_EQ;
1279 case LTGT : return ARC_CC_NE;
1280 default : gcc_unreachable ();
1282 case E_CC_FP_ORDmode:
1283 switch (GET_CODE (comparison))
1285 case UNORDERED : return ARC_CC_C;
1286 case ORDERED : return ARC_CC_NC;
1287 default : gcc_unreachable ();
1289 case E_CC_FPXmode:
1290 switch (GET_CODE (comparison))
1292 case EQ : return ARC_CC_EQ;
1293 case NE : return ARC_CC_NE;
1294 case UNORDERED : return ARC_CC_C;
1295 case ORDERED : return ARC_CC_NC;
1296 case LTGT : return ARC_CC_HI;
1297 case UNEQ : return ARC_CC_LS;
1298 default : gcc_unreachable ();
1300 case E_CC_FPUmode:
1301 switch (GET_CODE (comparison))
1303 case EQ : return ARC_CC_EQ;
1304 case NE : return ARC_CC_NE;
1305 case GT : return ARC_CC_GT;
1306 case GE : return ARC_CC_GE;
1307 case LT : return ARC_CC_C;
1308 case LE : return ARC_CC_LS;
1309 case UNORDERED : return ARC_CC_V;
1310 case ORDERED : return ARC_CC_NV;
1311 case UNGT : return ARC_CC_HI;
1312 case UNGE : return ARC_CC_HS;
1313 case UNLT : return ARC_CC_LT;
1314 case UNLE : return ARC_CC_LE;
1315 /* UNEQ and LTGT do not have representation. */
1316 case LTGT : /* Fall through. */
1317 case UNEQ : /* Fall through. */
1318 default : gcc_unreachable ();
1320 case E_CC_FPU_UNEQmode:
1321 switch (GET_CODE (comparison))
1323 case LTGT : return ARC_CC_NE;
1324 case UNEQ : return ARC_CC_EQ;
1325 default : gcc_unreachable ();
1327 default : gcc_unreachable ();
1329 /*NOTREACHED*/
1330 return (42);
1333 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1335 bool
1336 arc_short_comparison_p (rtx comparison, int offset)
1338 gcc_assert (ARC_CC_NC == ARC_CC_HS);
1339 gcc_assert (ARC_CC_C == ARC_CC_LO);
1340 switch (get_arc_condition_code (comparison))
1342 case ARC_CC_EQ: case ARC_CC_NE:
1343 return offset >= -512 && offset <= 506;
1344 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
1345 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
1346 return offset >= -64 && offset <= 58;
1347 default:
1348 return false;
1352 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1353 return the mode to be used for the comparison. */
1355 machine_mode
1356 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1358 machine_mode mode = GET_MODE (x);
1359 rtx x1;
1361 /* For an operation that sets the condition codes as a side-effect, the
1362 C and V flags is not set as for cmp, so we can only use comparisons where
1363 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1364 instead.) */
1365 /* ??? We could use "pnz" for greater than zero, however, we could then
1366 get into trouble because the comparison could not be reversed. */
1367 if (GET_MODE_CLASS (mode) == MODE_INT
1368 && y == const0_rtx
1369 && (op == EQ || op == NE
1370 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
1371 return CC_ZNmode;
1373 /* add.f for if (a+b) */
1374 if (mode == SImode
1375 && GET_CODE (y) == NEG
1376 && (op == EQ || op == NE))
1377 return CC_ZNmode;
1379 /* Check if this is a test suitable for bxor.f . */
1380 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1381 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1382 && INTVAL (y))
1383 return CC_Zmode;
1385 /* Check if this is a test suitable for add / bmsk.f . */
1386 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1387 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1388 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1389 && (~INTVAL (x1) | INTVAL (y)) < 0
1390 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1391 return CC_Zmode;
1393 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1394 && GET_CODE (x) == PLUS
1395 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1396 return CC_Cmode;
1398 if (TARGET_ARGONAUT_SET
1399 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1400 switch (op)
1402 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1403 return CC_FPXmode;
1404 case LT: case UNGE: case GT: case UNLE:
1405 return CC_FP_GTmode;
1406 case LE: case UNGT: case GE: case UNLT:
1407 return CC_FP_GEmode;
1408 default: gcc_unreachable ();
1410 else if (TARGET_HARD_FLOAT
1411 && ((mode == SFmode && TARGET_FP_SP_BASE)
1412 || (mode == DFmode && TARGET_FP_DP_BASE)))
1413 switch (op)
1415 case EQ:
1416 case NE:
1417 case UNORDERED:
1418 case ORDERED:
1419 case UNLT:
1420 case UNLE:
1421 case UNGT:
1422 case UNGE:
1423 case LT:
1424 case LE:
1425 case GT:
1426 case GE:
1427 return CC_FPUmode;
1429 case LTGT:
1430 case UNEQ:
1431 return CC_FPU_UNEQmode;
1433 default:
1434 gcc_unreachable ();
1436 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1438 switch (op)
1440 case EQ: case NE: return CC_Zmode;
1441 case LT: case UNGE:
1442 case GT: case UNLE: return CC_FP_GTmode;
1443 case LE: case UNGT:
1444 case GE: case UNLT: return CC_FP_GEmode;
1445 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1446 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1447 default: gcc_unreachable ();
1450 return CCmode;
1453 /* Vectors to keep interesting information about registers where it can easily
1454 be got. We use to use the actual mode value as the bit number, but there
1455 is (or may be) more than 32 modes now. Instead we use two tables: one
1456 indexed by hard register number, and one indexed by mode. */
1458 /* The purpose of arc_mode_class is to shrink the range of modes so that
1459 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1460 mapped into one arc_mode_class mode. */
1462 enum arc_mode_class {
1463 C_MODE,
1464 S_MODE, D_MODE, T_MODE, O_MODE,
1465 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1466 V_MODE
1469 /* Modes for condition codes. */
1470 #define C_MODES (1 << (int) C_MODE)
1472 /* Modes for single-word and smaller quantities. */
1473 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1475 /* Modes for double-word and smaller quantities. */
1476 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1478 /* Mode for 8-byte DF values only. */
1479 #define DF_MODES (1 << DF_MODE)
1481 /* Modes for quad-word and smaller quantities. */
1482 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1484 /* Modes for 128-bit vectors. */
1485 #define V_MODES (1 << (int) V_MODE)
1487 /* Value is 1 if register/mode pair is acceptable on arc. */
1489 static unsigned int arc_hard_regno_modes[] = {
1490 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1491 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1492 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1493 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1495 /* ??? Leave these as S_MODES for now. */
1496 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1497 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1498 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1499 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1501 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1502 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1503 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1504 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1506 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1507 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1508 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1509 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1511 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1512 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES
1515 static unsigned int arc_mode_class [NUM_MACHINE_MODES];
1517 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1519 enum reg_class
1520 arc_preferred_reload_class (rtx, enum reg_class cl)
1522 if ((cl) == CHEAP_CORE_REGS || (cl) == WRITABLE_CORE_REGS)
1523 return GENERAL_REGS;
1524 return cl;
1527 /* Initialize the arc_mode_class array. */
1529 static void
1530 arc_init_reg_tables (void)
1532 int i;
1534 for (i = 0; i < NUM_MACHINE_MODES; i++)
1536 machine_mode m = (machine_mode) i;
1538 switch (GET_MODE_CLASS (m))
1540 case MODE_INT:
1541 case MODE_PARTIAL_INT:
1542 case MODE_COMPLEX_INT:
1543 if (GET_MODE_SIZE (m) <= 4)
1544 arc_mode_class[i] = 1 << (int) S_MODE;
1545 else if (GET_MODE_SIZE (m) == 8)
1546 arc_mode_class[i] = 1 << (int) D_MODE;
1547 else if (GET_MODE_SIZE (m) == 16)
1548 arc_mode_class[i] = 1 << (int) T_MODE;
1549 else if (GET_MODE_SIZE (m) == 32)
1550 arc_mode_class[i] = 1 << (int) O_MODE;
1551 else
1552 arc_mode_class[i] = 0;
1553 break;
1554 case MODE_FLOAT:
1555 case MODE_COMPLEX_FLOAT:
1556 if (GET_MODE_SIZE (m) <= 4)
1557 arc_mode_class[i] = 1 << (int) SF_MODE;
1558 else if (GET_MODE_SIZE (m) == 8)
1559 arc_mode_class[i] = 1 << (int) DF_MODE;
1560 else if (GET_MODE_SIZE (m) == 16)
1561 arc_mode_class[i] = 1 << (int) TF_MODE;
1562 else if (GET_MODE_SIZE (m) == 32)
1563 arc_mode_class[i] = 1 << (int) OF_MODE;
1564 else
1565 arc_mode_class[i] = 0;
1566 break;
1567 case MODE_VECTOR_INT:
1568 if (GET_MODE_SIZE (m) == 4)
1569 arc_mode_class[i] = (1 << (int) S_MODE);
1570 else if (GET_MODE_SIZE (m) == 8)
1571 arc_mode_class[i] = (1 << (int) D_MODE);
1572 else
1573 arc_mode_class[i] = (1 << (int) V_MODE);
1574 break;
1575 case MODE_CC:
1576 default:
1577 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1578 we must explicitly check for them here. */
1579 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1580 || i == (int) CC_Cmode
1581 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
1582 || i == CC_FPUmode || i == CC_FPU_UNEQmode)
1583 arc_mode_class[i] = 1 << (int) C_MODE;
1584 else
1585 arc_mode_class[i] = 0;
1586 break;
1591 /* Core registers 56..59 are used for multiply extension options.
1592 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1593 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1594 number depends on endianness.
1595 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1596 Because mlo / mhi form a 64 bit value, we use different gcc internal
1597 register numbers to make them form a register pair as the gcc internals
1598 know it. mmid gets number 57, if still available, and mlo / mhi get
1599 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1600 to map this back. */
1601 char rname56[5] = "r56";
1602 char rname57[5] = "r57";
1603 char rname58[5] = "r58";
1604 char rname59[5] = "r59";
1605 char rname29[7] = "ilink1";
1606 char rname30[7] = "ilink2";
1608 static void
1609 arc_conditional_register_usage (void)
1611 int regno;
1612 int i;
1613 int fix_start = 60, fix_end = 55;
1615 if (TARGET_V2)
1617 /* For ARCv2 the core register set is changed. */
1618 strcpy (rname29, "ilink");
1619 strcpy (rname30, "r30");
1620 call_used_regs[30] = 1;
1621 fixed_regs[30] = 0;
1623 arc_regno_reg_class[30] = WRITABLE_CORE_REGS;
1624 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], 30);
1625 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], 30);
1626 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 30);
1627 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 30);
1630 if (TARGET_MUL64_SET)
1632 fix_start = 57;
1633 fix_end = 59;
1635 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1636 you are supposed to refer to it as mlo & mhi, e.g
1637 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1638 In an actual asm instruction, you are of course use mmed.
1639 The point of avoiding having a separate register for mmed is that
1640 this way, we don't have to carry clobbers of that reg around in every
1641 isntruction that modifies mlo and/or mhi. */
1642 strcpy (rname57, "");
1643 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo");
1644 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi");
1647 /* The nature of arc_tp_regno is actually something more like a global
1648 register, however globalize_reg requires a declaration.
1649 We use EPILOGUE_USES to compensate so that sets from
1650 __builtin_set_frame_pointer are not deleted. */
1651 if (arc_tp_regno != -1)
1652 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1;
1654 if (TARGET_MULMAC_32BY16_SET)
1656 fix_start = 56;
1657 fix_end = fix_end > 57 ? fix_end : 57;
1658 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1659 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1661 for (regno = fix_start; regno <= fix_end; regno++)
1663 if (!fixed_regs[regno])
1664 warning (0, "multiply option implies r%d is fixed", regno);
1665 fixed_regs [regno] = call_used_regs[regno] = 1;
1667 if (TARGET_Q_CLASS)
1669 if (optimize_size)
1671 reg_alloc_order[0] = 0;
1672 reg_alloc_order[1] = 1;
1673 reg_alloc_order[2] = 2;
1674 reg_alloc_order[3] = 3;
1675 reg_alloc_order[4] = 12;
1676 reg_alloc_order[5] = 13;
1677 reg_alloc_order[6] = 14;
1678 reg_alloc_order[7] = 15;
1679 reg_alloc_order[8] = 4;
1680 reg_alloc_order[9] = 5;
1681 reg_alloc_order[10] = 6;
1682 reg_alloc_order[11] = 7;
1683 reg_alloc_order[12] = 8;
1684 reg_alloc_order[13] = 9;
1685 reg_alloc_order[14] = 10;
1686 reg_alloc_order[15] = 11;
1688 else
1690 reg_alloc_order[2] = 12;
1691 reg_alloc_order[3] = 13;
1692 reg_alloc_order[4] = 14;
1693 reg_alloc_order[5] = 15;
1694 reg_alloc_order[6] = 1;
1695 reg_alloc_order[7] = 0;
1696 reg_alloc_order[8] = 4;
1697 reg_alloc_order[9] = 5;
1698 reg_alloc_order[10] = 6;
1699 reg_alloc_order[11] = 7;
1700 reg_alloc_order[12] = 8;
1701 reg_alloc_order[13] = 9;
1702 reg_alloc_order[14] = 10;
1703 reg_alloc_order[15] = 11;
1706 if (TARGET_SIMD_SET)
1708 int i;
1709 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1710 reg_alloc_order [i] = i;
1711 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1712 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1713 reg_alloc_order [i] = i;
1716 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1717 if (!call_used_regs[regno])
1718 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
1719 for (regno = 32; regno < 60; regno++)
1720 if (!fixed_regs[regno])
1721 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], regno);
1722 if (!TARGET_ARC600_FAMILY)
1724 for (regno = 32; regno <= 60; regno++)
1725 CLEAR_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], regno);
1727 /* If they have used -ffixed-lp_count, make sure it takes
1728 effect. */
1729 if (fixed_regs[LP_COUNT])
1731 CLEAR_HARD_REG_BIT (reg_class_contents[LPCOUNT_REG], LP_COUNT);
1732 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1733 CLEAR_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], LP_COUNT);
1735 /* Instead of taking out SF_MODE like below, forbid it outright. */
1736 arc_hard_regno_modes[60] = 0;
1738 else
1739 arc_hard_regno_modes[60] = 1 << (int) S_MODE;
1742 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1743 registers. */
1744 if (TARGET_HS)
1746 for (regno = 1; regno < 32; regno +=2)
1748 arc_hard_regno_modes[regno] = S_MODES;
1752 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1754 if (i < 29)
1756 if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
1757 && ((i <= 3) || ((i >= 12) && (i <= 15))))
1758 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1759 else
1760 arc_regno_reg_class[i] = GENERAL_REGS;
1762 else if (i < 60)
1763 arc_regno_reg_class[i]
1764 = (fixed_regs[i]
1765 ? (TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i)
1766 ? CHEAP_CORE_REGS : ALL_CORE_REGS)
1767 : (((!TARGET_ARC600_FAMILY)
1768 && TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i))
1769 ? CHEAP_CORE_REGS : WRITABLE_CORE_REGS));
1770 else
1771 arc_regno_reg_class[i] = NO_REGS;
1774 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1775 has not been activated. */
1776 if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
1777 CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
1778 if (!TARGET_Q_CLASS)
1779 CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
1781 gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
1783 /* Handle Special Registers. */
1784 arc_regno_reg_class[29] = LINK_REGS; /* ilink1 register. */
1785 if (!TARGET_V2)
1786 arc_regno_reg_class[30] = LINK_REGS; /* ilink2 register. */
1787 arc_regno_reg_class[31] = LINK_REGS; /* blink register. */
1788 arc_regno_reg_class[60] = LPCOUNT_REG;
1789 arc_regno_reg_class[61] = NO_REGS; /* CC_REG: must be NO_REGS. */
1790 arc_regno_reg_class[62] = GENERAL_REGS;
1792 if (TARGET_DPFP)
1794 for (i = 40; i < 44; ++i)
1796 arc_regno_reg_class[i] = DOUBLE_REGS;
1798 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1799 no attempt is made to use such a register as a destination
1800 operand in *movdf_insn. */
1801 if (!TARGET_ARGONAUT_SET)
1803 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1804 interpreted to mean they can use D1 or D2 in their insn. */
1805 CLEAR_HARD_REG_BIT(reg_class_contents[CHEAP_CORE_REGS ], i);
1806 CLEAR_HARD_REG_BIT(reg_class_contents[ALL_CORE_REGS ], i);
1807 CLEAR_HARD_REG_BIT(reg_class_contents[WRITABLE_CORE_REGS ], i);
1808 CLEAR_HARD_REG_BIT(reg_class_contents[MPY_WRITABLE_CORE_REGS], i);
1812 else
1814 /* Disable all DOUBLE_REGISTER settings,
1815 if not generating DPFP code. */
1816 arc_regno_reg_class[40] = ALL_REGS;
1817 arc_regno_reg_class[41] = ALL_REGS;
1818 arc_regno_reg_class[42] = ALL_REGS;
1819 arc_regno_reg_class[43] = ALL_REGS;
1821 fixed_regs[40] = 1;
1822 fixed_regs[41] = 1;
1823 fixed_regs[42] = 1;
1824 fixed_regs[43] = 1;
1826 arc_hard_regno_modes[40] = 0;
1827 arc_hard_regno_modes[42] = 0;
1829 CLEAR_HARD_REG_SET(reg_class_contents [DOUBLE_REGS]);
1832 if (TARGET_SIMD_SET)
1834 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1835 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
1837 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1838 arc_regno_reg_class [i] = SIMD_VR_REGS;
1840 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
1841 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
1842 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
1843 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
1845 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1846 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1847 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
1850 /* pc : r63 */
1851 arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
1853 /*ARCV2 Accumulator. */
1854 if ((TARGET_V2
1855 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
1856 || TARGET_PLUS_DMPY)
1858 arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
1859 arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
1860 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCL_REGNO);
1861 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO);
1862 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO);
1863 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO);
1864 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO);
1865 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO);
1866 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCL_REGNO);
1867 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCH_REGNO);
1869 /* Allow the compiler to freely use them. */
1870 fixed_regs[ACCL_REGNO] = 0;
1871 fixed_regs[ACCH_REGNO] = 0;
1873 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES;
1877 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1879 static bool
1880 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
1882 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0;
1885 /* Handle an "interrupt" attribute; arguments as in
1886 struct attribute_spec.handler. */
1888 static tree
1889 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
1890 bool *no_add_attrs)
1892 gcc_assert (args);
1894 tree value = TREE_VALUE (args);
1896 if (TREE_CODE (value) != STRING_CST)
1898 warning (OPT_Wattributes,
1899 "argument of %qE attribute is not a string constant",
1900 name);
1901 *no_add_attrs = true;
1903 else if (!TARGET_V2
1904 && strcmp (TREE_STRING_POINTER (value), "ilink1")
1905 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
1907 warning (OPT_Wattributes,
1908 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
1909 name);
1910 *no_add_attrs = true;
1912 else if (TARGET_V2
1913 && strcmp (TREE_STRING_POINTER (value), "ilink")
1914 && strcmp (TREE_STRING_POINTER (value), "firq"))
1916 warning (OPT_Wattributes,
1917 "argument of %qE attribute is not \"ilink\" or \"firq\"",
1918 name);
1919 *no_add_attrs = true;
1922 return NULL_TREE;
1925 static tree
1926 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
1927 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
1929 if (TREE_CODE (*node) != FUNCTION_DECL)
1931 warning (OPT_Wattributes, "%qE attribute only applies to functions",
1932 name);
1933 *no_add_attrs = true;
1936 return NULL_TREE;
1939 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
1941 static bool
1942 arc_allocate_stack_slots_for_args (void)
1944 /* Naked functions should not allocate stack slots for arguments. */
1945 unsigned int fn_type = arc_compute_function_type (cfun);
1947 return !ARC_NAKED_P(fn_type);
1950 /* Implement `TARGET_WARN_FUNC_RETURN'. */
1952 static bool
1953 arc_warn_func_return (tree decl)
1955 struct function *func = DECL_STRUCT_FUNCTION (decl);
1956 unsigned int fn_type = arc_compute_function_type (func);
1958 return !ARC_NAKED_P (fn_type);
1961 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
1962 and two if they are nearly compatible (which causes a warning to be
1963 generated). */
1965 static int
1966 arc_comp_type_attributes (const_tree type1,
1967 const_tree type2)
1969 int l1, l2, m1, m2, s1, s2;
1971 /* Check for mismatch of non-default calling convention. */
1972 if (TREE_CODE (type1) != FUNCTION_TYPE)
1973 return 1;
1975 /* Check for mismatched call attributes. */
1976 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
1977 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
1978 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
1979 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
1980 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
1981 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
1983 /* Only bother to check if an attribute is defined. */
1984 if (l1 | l2 | m1 | m2 | s1 | s2)
1986 /* If one type has an attribute, the other must have the same attribute. */
1987 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
1988 return 0;
1990 /* Disallow mixed attributes. */
1991 if (l1 + m1 + s1 > 1)
1992 return 0;
1996 return 1;
1999 /* Set the default attributes for TYPE. */
2001 void
2002 arc_set_default_type_attributes (tree type ATTRIBUTE_UNUSED)
2004 gcc_unreachable();
2007 /* Misc. utilities. */
2009 /* X and Y are two things to compare using CODE. Emit the compare insn and
2010 return the rtx for the cc reg in the proper mode. */
2013 gen_compare_reg (rtx comparison, machine_mode omode)
2015 enum rtx_code code = GET_CODE (comparison);
2016 rtx x = XEXP (comparison, 0);
2017 rtx y = XEXP (comparison, 1);
2018 rtx tmp, cc_reg;
2019 machine_mode mode, cmode;
2022 cmode = GET_MODE (x);
2023 if (cmode == VOIDmode)
2024 cmode = GET_MODE (y);
2025 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode);
2026 if (cmode == SImode)
2028 if (!register_operand (x, SImode))
2030 if (register_operand (y, SImode))
2032 tmp = x;
2033 x = y;
2034 y = tmp;
2035 code = swap_condition (code);
2037 else
2038 x = copy_to_mode_reg (SImode, x);
2040 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
2041 y = copy_to_mode_reg (SImode, y);
2043 else
2045 x = force_reg (cmode, x);
2046 y = force_reg (cmode, y);
2048 mode = SELECT_CC_MODE (code, x, y);
2050 cc_reg = gen_rtx_REG (mode, CC_REG);
2052 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2053 cmpdfpx_raw, is not a correct comparison for floats:
2054 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2056 if (TARGET_ARGONAUT_SET
2057 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2059 switch (code)
2061 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
2062 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2063 break;
2064 case GT: case UNLE: case GE: case UNLT:
2065 code = swap_condition (code);
2066 tmp = x;
2067 x = y;
2068 y = tmp;
2069 break;
2070 default:
2071 gcc_unreachable ();
2073 if (cmode == SFmode)
2075 emit_insn (gen_cmpsfpx_raw (x, y));
2077 else /* DFmode */
2079 /* Accepts Dx regs directly by insns. */
2080 emit_insn (gen_cmpdfpx_raw (x, y));
2083 if (mode != CC_FPXmode)
2084 emit_insn (gen_rtx_SET (cc_reg,
2085 gen_rtx_COMPARE (mode,
2086 gen_rtx_REG (CC_FPXmode, 61),
2087 const0_rtx)));
2089 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2091 switch (code)
2093 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2094 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2095 break;
2096 case LT: case UNGE: case LE: case UNGT:
2097 code = swap_condition (code);
2098 tmp = x;
2099 x = y;
2100 y = tmp;
2101 break;
2102 default:
2103 gcc_unreachable ();
2106 emit_insn (gen_cmp_quark (cc_reg,
2107 gen_rtx_COMPARE (mode, x, y)));
2109 else if (TARGET_HARD_FLOAT
2110 && ((cmode == SFmode && TARGET_FP_SP_BASE)
2111 || (cmode == DFmode && TARGET_FP_DP_BASE)))
2112 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2113 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
2115 rtx op0 = gen_rtx_REG (cmode, 0);
2116 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
2117 bool swap = false;
2119 switch (code)
2121 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2122 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2123 break;
2124 case LT: case UNGE: case LE: case UNGT:
2125 code = swap_condition (code);
2126 swap = true;
2127 break;
2128 default:
2129 gcc_unreachable ();
2131 if (currently_expanding_to_rtl)
2133 if (swap)
2135 tmp = x;
2136 x = y;
2137 y = tmp;
2139 emit_move_insn (op0, x);
2140 emit_move_insn (op1, y);
2142 else
2144 gcc_assert (rtx_equal_p (op0, x));
2145 gcc_assert (rtx_equal_p (op1, y));
2146 if (swap)
2148 op0 = y;
2149 op1 = x;
2152 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2154 else
2155 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2156 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
2159 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2160 We assume the value can be either signed or unsigned. */
2162 bool
2163 arc_double_limm_p (rtx value)
2165 HOST_WIDE_INT low, high;
2167 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2169 if (TARGET_DPFP)
2170 return true;
2172 low = CONST_DOUBLE_LOW (value);
2173 high = CONST_DOUBLE_HIGH (value);
2175 if (low & 0x80000000)
2177 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
2178 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
2179 == - (unsigned HOST_WIDE_INT) 0x80000000)
2180 && high == -1));
2182 else
2184 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2188 /* Do any needed setup for a variadic function. For the ARC, we must
2189 create a register parameter block, and then copy any anonymous arguments
2190 in registers to memory.
2192 CUM has not been updated for the last named argument which has type TYPE
2193 and mode MODE, and we rely on this fact. */
2195 static void
2196 arc_setup_incoming_varargs (cumulative_args_t args_so_far,
2197 machine_mode mode, tree type,
2198 int *pretend_size, int no_rtl)
2200 int first_anon_arg;
2201 CUMULATIVE_ARGS next_cum;
2203 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2205 next_cum = *get_cumulative_args (args_so_far);
2206 arc_function_arg_advance (pack_cumulative_args (&next_cum),
2207 mode, type, true);
2208 first_anon_arg = next_cum;
2210 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2212 /* First anonymous (unnamed) argument is in a reg. */
2214 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2215 int first_reg_offset = first_anon_arg;
2217 if (!no_rtl)
2219 rtx regblock
2220 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2221 FIRST_PARM_OFFSET (0)));
2222 move_block_from_reg (first_reg_offset, regblock,
2223 MAX_ARC_PARM_REGS - first_reg_offset);
2226 *pretend_size
2227 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2231 /* Cost functions. */
2233 /* Provide the costs of an addressing mode that contains ADDR.
2234 If ADDR is not a valid address, its cost is irrelevant. */
2237 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2239 switch (GET_CODE (addr))
2241 case REG :
2242 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1;
2243 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2244 case PRE_MODIFY: case POST_MODIFY:
2245 return !speed;
2247 case LABEL_REF :
2248 case SYMBOL_REF :
2249 case CONST :
2250 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2251 return 0;
2252 /* Most likely needs a LIMM. */
2253 return COSTS_N_INSNS (1);
2255 case PLUS :
2257 register rtx plus0 = XEXP (addr, 0);
2258 register rtx plus1 = XEXP (addr, 1);
2260 if (GET_CODE (plus0) != REG
2261 && (GET_CODE (plus0) != MULT
2262 || !CONST_INT_P (XEXP (plus0, 1))
2263 || (INTVAL (XEXP (plus0, 1)) != 2
2264 && INTVAL (XEXP (plus0, 1)) != 4)))
2265 break;
2267 switch (GET_CODE (plus1))
2269 case CONST_INT :
2270 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2271 ? COSTS_N_INSNS (1)
2272 : speed
2274 : (satisfies_constraint_Rcq (plus0)
2275 && satisfies_constraint_O (plus1))
2277 : 1);
2278 case REG:
2279 return (speed < 1 ? 0
2280 : (satisfies_constraint_Rcq (plus0)
2281 && satisfies_constraint_Rcq (plus1))
2282 ? 0 : 1);
2283 case CONST :
2284 case SYMBOL_REF :
2285 case LABEL_REF :
2286 return COSTS_N_INSNS (1);
2287 default:
2288 break;
2290 break;
2292 default:
2293 break;
2296 return 4;
2299 /* Emit instruction X with the frame related bit set. */
2301 static rtx
2302 frame_insn (rtx x)
2304 x = emit_insn (x);
2305 RTX_FRAME_RELATED_P (x) = 1;
2306 return x;
2309 /* Emit a frame insn to move SRC to DST. */
2311 static rtx
2312 frame_move (rtx dst, rtx src)
2314 rtx tmp = gen_rtx_SET (dst, src);
2315 RTX_FRAME_RELATED_P (tmp) = 1;
2316 return frame_insn (tmp);
2319 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2320 auto increment address, or is zero. */
2322 static rtx
2323 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2325 rtx insn = frame_move (dst, src);
2327 if (!addr
2328 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2329 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2330 add_reg_note (insn, REG_INC, reg);
2331 return insn;
2334 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2336 static rtx
2337 frame_add (rtx reg, HOST_WIDE_INT offset)
2339 gcc_assert ((offset & 0x3) == 0);
2340 if (!offset)
2341 return NULL_RTX;
2342 return frame_move (reg, plus_constant (Pmode, reg, offset));
2345 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2347 static rtx
2348 frame_stack_add (HOST_WIDE_INT offset)
2350 return frame_add (stack_pointer_rtx, offset);
2353 /* Traditionally, we push saved registers first in the prologue,
2354 then we allocate the rest of the frame - and reverse in the epilogue.
2355 This has still its merits for ease of debugging, or saving code size
2356 or even execution time if the stack frame is so large that some accesses
2357 can't be encoded anymore with offsets in the instruction code when using
2358 a different scheme.
2359 Also, it would be a good starting point if we got instructions to help
2360 with register save/restore.
2362 However, often stack frames are small, and the pushing / popping has
2363 some costs:
2364 - the stack modification prevents a lot of scheduling.
2365 - frame allocation / deallocation needs extra instructions.
2366 - unless we know that we compile ARC700 user code, we need to put
2367 a memory barrier after frame allocation / before deallocation to
2368 prevent interrupts clobbering our data in the frame.
2369 In particular, we don't have any such guarantees for library functions,
2370 which tend to, on the other hand, to have small frames.
2372 Thus, for small frames, we'd like to use a different scheme:
2373 - The frame is allocated in full with the first prologue instruction,
2374 and deallocated in full with the last epilogue instruction.
2375 Thus, the instructions in-betwen can be freely scheduled.
2376 - If the function has no outgoing arguments on the stack, we can allocate
2377 one register save slot at the top of the stack. This register can then
2378 be saved simultanously with frame allocation, and restored with
2379 frame deallocation.
2380 This register can be picked depending on scheduling considerations,
2381 although same though should go into having some set of registers
2382 to be potentially lingering after a call, and others to be available
2383 immediately - i.e. in the absence of interprocedual optimization, we
2384 can use an ABI-like convention for register allocation to reduce
2385 stalls after function return. */
2386 /* Function prologue/epilogue handlers. */
2388 /* ARCompact stack frames look like:
2390 Before call After call
2391 high +-----------------------+ +-----------------------+
2392 mem | reg parm save area | | reg parm save area |
2393 | only created for | | only created for |
2394 | variable arg fns | | variable arg fns |
2395 AP +-----------------------+ +-----------------------+
2396 | return addr register | | return addr register |
2397 | (if required) | | (if required) |
2398 +-----------------------+ +-----------------------+
2399 | | | |
2400 | reg save area | | reg save area |
2401 | | | |
2402 +-----------------------+ +-----------------------+
2403 | frame pointer | | frame pointer |
2404 | (if required) | | (if required) |
2405 FP +-----------------------+ +-----------------------+
2406 | | | |
2407 | local/temp variables | | local/temp variables |
2408 | | | |
2409 +-----------------------+ +-----------------------+
2410 | | | |
2411 | arguments on stack | | arguments on stack |
2412 | | | |
2413 SP +-----------------------+ +-----------------------+
2414 | reg parm save area |
2415 | only created for |
2416 | variable arg fns |
2417 AP +-----------------------+
2418 | return addr register |
2419 | (if required) |
2420 +-----------------------+
2422 | reg save area |
2424 +-----------------------+
2425 | frame pointer |
2426 | (if required) |
2427 FP +-----------------------+
2429 | local/temp variables |
2431 +-----------------------+
2433 | arguments on stack |
2434 low | |
2435 mem SP +-----------------------+
2437 Notes:
2438 1) The "reg parm save area" does not exist for non variable argument fns.
2439 The "reg parm save area" can be eliminated completely if we created our
2440 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2442 /* Structure to be filled in by arc_compute_frame_size with register
2443 save masks, and offsets for the current function. */
2444 struct GTY (()) arc_frame_info
2446 unsigned int total_size; /* # bytes that the entire frame takes up. */
2447 unsigned int extra_size; /* # bytes of extra stuff. */
2448 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
2449 unsigned int args_size; /* # bytes that outgoing arguments take up. */
2450 unsigned int reg_size; /* # bytes needed to store regs. */
2451 unsigned int var_size; /* # bytes that variables take up. */
2452 unsigned int reg_offset; /* Offset from new sp to store regs. */
2453 unsigned int gmask; /* Mask of saved gp registers. */
2454 int initialized; /* Nonzero if frame size already calculated. */
2455 short millicode_start_reg;
2456 short millicode_end_reg;
2457 bool save_return_addr;
2460 /* Defining data structures for per-function information. */
2462 typedef struct GTY (()) machine_function
2464 unsigned int fn_type;
2465 struct arc_frame_info frame_info;
2466 /* To keep track of unalignment caused by short insns. */
2467 int unalign;
2468 int force_short_suffix; /* Used when disgorging return delay slot insns. */
2469 const char *size_reason;
2470 struct arc_ccfsm ccfsm_current;
2471 /* Map from uid to ccfsm state during branch shortening. */
2472 rtx ccfsm_current_insn;
2473 char arc_reorg_started;
2474 char prescan_initialized;
2475 } machine_function;
2477 /* Type of function DECL.
2479 The result is cached. To reset the cache at the end of a function,
2480 call with DECL = NULL_TREE. */
2482 unsigned int
2483 arc_compute_function_type (struct function *fun)
2485 tree attr, decl = fun->decl;
2486 unsigned int fn_type = fun->machine->fn_type;
2488 if (fn_type != ARC_FUNCTION_UNKNOWN)
2489 return fn_type;
2491 /* Check if it is a naked function. */
2492 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
2493 fn_type |= ARC_FUNCTION_NAKED;
2494 else
2495 fn_type |= ARC_FUNCTION_NORMAL;
2497 /* Now see if this is an interrupt handler. */
2498 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2499 if (attr != NULL_TREE)
2501 tree value, args = TREE_VALUE (attr);
2503 gcc_assert (list_length (args) == 1);
2504 value = TREE_VALUE (args);
2505 gcc_assert (TREE_CODE (value) == STRING_CST);
2507 if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
2508 || !strcmp (TREE_STRING_POINTER (value), "ilink"))
2509 fn_type |= ARC_FUNCTION_ILINK1;
2510 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
2511 fn_type |= ARC_FUNCTION_ILINK2;
2512 else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
2513 fn_type |= ARC_FUNCTION_FIRQ;
2514 else
2515 gcc_unreachable ();
2518 return fun->machine->fn_type = fn_type;
2521 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2522 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2524 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2525 The return address and frame pointer are treated separately.
2526 Don't consider them here.
2527 Addition for pic: The gp register needs to be saved if the current
2528 function changes it to access gotoff variables.
2529 FIXME: This will not be needed if we used some arbitrary register
2530 instead of r26.
2533 static bool
2534 arc_must_save_register (int regno, struct function *func)
2536 unsigned int fn_type = arc_compute_function_type (func);
2537 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2538 && ARC_AUTO_IRQ_P (fn_type));
2539 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2541 switch (rgf_banked_register_count)
2543 case 4:
2544 firq_auto_save_p &= (regno < 4);
2545 break;
2546 case 8:
2547 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2548 break;
2549 case 16:
2550 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2551 || ((regno > 25) && (regno < 29))
2552 || ((regno > 29) && (regno < 32)));
2553 break;
2554 case 32:
2555 firq_auto_save_p &= (regno != 29) && (regno < 32);
2556 break;
2557 default:
2558 firq_auto_save_p = false;
2559 break;
2562 if ((regno) != RETURN_ADDR_REGNUM
2563 && (regno) != FRAME_POINTER_REGNUM
2564 && df_regs_ever_live_p (regno)
2565 && (!call_used_regs[regno]
2566 || ARC_INTERRUPT_P (fn_type))
2567 /* Do not emit code for auto saved regs. */
2568 && !irq_auto_save_p
2569 && !firq_auto_save_p)
2570 return true;
2572 if (flag_pic && crtl->uses_pic_offset_table
2573 && regno == PIC_OFFSET_TABLE_REGNUM)
2574 return true;
2576 return false;
2579 /* Return true if the return address must be saved in the current function,
2580 otherwise return false. */
2582 static bool
2583 arc_must_save_return_addr (struct function *func)
2585 if (func->machine->frame_info.save_return_addr)
2586 return true;
2588 return false;
2591 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2592 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2593 Register Allocator) pass, while we want to get the frame size
2594 correct earlier than the IRA pass. */
2595 static bool
2596 arc_frame_pointer_needed (void)
2598 return (frame_pointer_needed);
2602 /* Return non-zero if there are registers to be saved or loaded using
2603 millicode thunks. We can only use consecutive sequences starting
2604 with r13, and not going beyond r25.
2605 GMASK is a bitmask of registers to save. This function sets
2606 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2607 of registers to be saved / restored with a millicode call. */
2609 static int
2610 arc_compute_millicode_save_restore_regs (unsigned int gmask,
2611 struct arc_frame_info *frame)
2613 int regno;
2615 int start_reg = 13, end_reg = 25;
2617 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
2618 regno++;
2619 end_reg = regno - 1;
2620 /* There is no point in using millicode thunks if we don't save/restore
2621 at least three registers. For non-leaf functions we also have the
2622 blink restore. */
2623 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2625 frame->millicode_start_reg = 13;
2626 frame->millicode_end_reg = regno - 1;
2627 return 1;
2629 return 0;
2632 /* Return the bytes needed to compute the frame pointer from the current
2633 stack pointer.
2635 SIZE is the size needed for local variables. */
2637 unsigned int
2638 arc_compute_frame_size (int size) /* size = # of var. bytes allocated. */
2640 int regno;
2641 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2642 unsigned int reg_size, reg_offset;
2643 unsigned int gmask;
2644 struct arc_frame_info *frame_info = &cfun->machine->frame_info;
2646 size = ARC_STACK_ALIGN (size);
2648 /* 1) Size of locals and temporaries */
2649 var_size = size;
2651 /* 2) Size of outgoing arguments */
2652 args_size = crtl->outgoing_args_size;
2654 /* 3) Calculate space needed for saved registers.
2655 ??? We ignore the extension registers for now. */
2657 /* See if this is an interrupt handler. Call used registers must be saved
2658 for them too. */
2660 reg_size = 0;
2661 gmask = 0;
2663 for (regno = 0; regno <= 31; regno++)
2665 if (arc_must_save_register (regno, cfun))
2667 reg_size += UNITS_PER_WORD;
2668 gmask |= 1L << regno;
2672 /* 4) Space for back trace data structure.
2673 <return addr reg size> (if required) + <fp size> (if required). */
2674 frame_info->save_return_addr
2675 = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM));
2676 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2677 if (optimize_size && !TARGET_NO_MILLICODE_THUNK_SET)
2679 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2680 frame_info->save_return_addr = true;
2683 extra_size = 0;
2684 if (arc_must_save_return_addr (cfun))
2685 extra_size = 4;
2686 if (arc_frame_pointer_needed ())
2687 extra_size += 4;
2689 /* 5) Space for variable arguments passed in registers */
2690 pretend_size = crtl->args.pretend_args_size;
2692 /* Ensure everything before the locals is aligned appropriately. */
2694 unsigned int extra_plus_reg_size;
2695 unsigned int extra_plus_reg_size_aligned;
2697 extra_plus_reg_size = extra_size + reg_size;
2698 extra_plus_reg_size_aligned = ARC_STACK_ALIGN(extra_plus_reg_size);
2699 reg_size = extra_plus_reg_size_aligned - extra_size;
2702 /* Compute total frame size. */
2703 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2705 total_size = ARC_STACK_ALIGN (total_size);
2707 /* Compute offset of register save area from stack pointer:
2708 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2710 reg_offset = (total_size - (pretend_size + reg_size + extra_size)
2711 + (arc_frame_pointer_needed () ? 4 : 0));
2713 /* Save computed information. */
2714 frame_info->total_size = total_size;
2715 frame_info->extra_size = extra_size;
2716 frame_info->pretend_size = pretend_size;
2717 frame_info->var_size = var_size;
2718 frame_info->args_size = args_size;
2719 frame_info->reg_size = reg_size;
2720 frame_info->reg_offset = reg_offset;
2721 frame_info->gmask = gmask;
2722 frame_info->initialized = reload_completed;
2724 /* Ok, we're done. */
2725 return total_size;
2728 /* Common code to save/restore registers. */
2729 /* BASE_REG is the base register to use for addressing and to adjust.
2730 GMASK is a bitmask of general purpose registers to save/restore.
2731 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2732 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2733 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2734 zeroed. */
2736 static void
2737 arc_save_restore (rtx base_reg,
2738 unsigned int gmask, int epilogue_p, int *first_offset)
2740 unsigned int offset = 0;
2741 int regno;
2742 struct arc_frame_info *frame = &cfun->machine->frame_info;
2743 rtx sibthunk_insn = NULL_RTX;
2745 if (gmask)
2747 /* Millicode thunks implementation:
2748 Generates calls to millicodes for registers starting from r13 to r25
2749 Present Limitations:
2750 - Only one range supported. The remaining regs will have the ordinary
2751 st and ld instructions for store and loads. Hence a gmask asking
2752 to store r13-14, r16-r25 will only generate calls to store and
2753 load r13 to r14 while store and load insns will be generated for
2754 r16 to r25 in the prologue and epilogue respectively.
2756 - Presently library only supports register ranges starting from r13.
2758 if (epilogue_p == 2 || frame->millicode_end_reg > 14)
2760 int start_call = frame->millicode_start_reg;
2761 int end_call = frame->millicode_end_reg;
2762 int n_regs = end_call - start_call + 1;
2763 int i = 0, r, off = 0;
2764 rtx insn;
2765 rtx ret_addr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
2767 if (*first_offset)
2769 /* "reg_size" won't be more than 127 . */
2770 gcc_assert (epilogue_p || abs (*first_offset) <= 127);
2771 frame_add (base_reg, *first_offset);
2772 *first_offset = 0;
2774 insn = gen_rtx_PARALLEL
2775 (VOIDmode, rtvec_alloc ((epilogue_p == 2) + n_regs + 1));
2776 if (epilogue_p == 2)
2777 i += 2;
2778 else
2779 XVECEXP (insn, 0, n_regs) = gen_rtx_CLOBBER (VOIDmode, ret_addr);
2780 for (r = start_call; r <= end_call; r++, off += UNITS_PER_WORD, i++)
2782 rtx reg = gen_rtx_REG (SImode, r);
2783 rtx mem
2784 = gen_frame_mem (SImode, plus_constant (Pmode, base_reg, off));
2786 if (epilogue_p)
2787 XVECEXP (insn, 0, i) = gen_rtx_SET (reg, mem);
2788 else
2789 XVECEXP (insn, 0, i) = gen_rtx_SET (mem, reg);
2790 gmask = gmask & ~(1L << r);
2792 if (epilogue_p == 2)
2793 sibthunk_insn = insn;
2794 else
2796 insn = frame_insn (insn);
2797 if (epilogue_p)
2798 for (r = start_call; r <= end_call; r++)
2800 rtx reg = gen_rtx_REG (SImode, r);
2801 add_reg_note (insn, REG_CFA_RESTORE, reg);
2804 offset += off;
2807 for (regno = 0; regno <= 31; regno++)
2809 machine_mode mode = SImode;
2810 bool found = false;
2812 if (TARGET_LL64
2813 && (regno % 2 == 0)
2814 && ((gmask & (1L << regno)) != 0)
2815 && ((gmask & (1L << (regno+1))) != 0))
2817 found = true;
2818 mode = DImode;
2820 else if ((gmask & (1L << regno)) != 0)
2822 found = true;
2823 mode = SImode;
2826 if (found)
2828 rtx reg = gen_rtx_REG (mode, regno);
2829 rtx addr, mem;
2830 int cfa_adjust = *first_offset;
2832 if (*first_offset)
2834 gcc_assert (!offset);
2835 addr = plus_constant (Pmode, base_reg, *first_offset);
2836 addr = gen_rtx_PRE_MODIFY (Pmode, base_reg, addr);
2837 *first_offset = 0;
2839 else
2841 gcc_assert (SMALL_INT (offset));
2842 addr = plus_constant (Pmode, base_reg, offset);
2844 mem = gen_frame_mem (mode, addr);
2845 if (epilogue_p)
2847 rtx insn =
2848 frame_move_inc (reg, mem, base_reg, addr);
2849 add_reg_note (insn, REG_CFA_RESTORE, reg);
2850 if (cfa_adjust)
2852 enum reg_note note = REG_CFA_ADJUST_CFA;
2853 add_reg_note (insn, note,
2854 gen_rtx_SET (stack_pointer_rtx,
2855 plus_constant (Pmode,
2856 stack_pointer_rtx,
2857 cfa_adjust)));
2860 else
2861 frame_move_inc (mem, reg, base_reg, addr);
2862 offset += UNITS_PER_WORD;
2863 if (mode == DImode)
2865 offset += UNITS_PER_WORD;
2866 ++regno;
2868 } /* if */
2869 } /* for */
2870 }/* if */
2871 if (sibthunk_insn)
2873 int start_call = frame->millicode_start_reg;
2874 int end_call = frame->millicode_end_reg;
2875 int r;
2877 rtx r12 = gen_rtx_REG (Pmode, 12);
2879 frame_insn (gen_rtx_SET (r12, GEN_INT (offset)));
2880 XVECEXP (sibthunk_insn, 0, 0) = ret_rtx;
2881 XVECEXP (sibthunk_insn, 0, 1)
2882 = gen_rtx_SET (stack_pointer_rtx,
2883 gen_rtx_PLUS (Pmode, stack_pointer_rtx, r12));
2884 sibthunk_insn = emit_jump_insn (sibthunk_insn);
2885 RTX_FRAME_RELATED_P (sibthunk_insn) = 1;
2887 /* Would be nice if we could do this earlier, when the PARALLEL
2888 is populated, but these need to be attached after the
2889 emit. */
2890 for (r = start_call; r <= end_call; r++)
2892 rtx reg = gen_rtx_REG (SImode, r);
2893 add_reg_note (sibthunk_insn, REG_CFA_RESTORE, reg);
2896 } /* arc_save_restore */
2898 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2899 mechanism. */
2901 static void
2902 arc_dwarf_emit_irq_save_regs (void)
2904 rtx tmp, par, insn, reg;
2905 int i, offset, j;
2907 par = gen_rtx_SEQUENCE (VOIDmode,
2908 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
2909 + irq_ctrl_saved.irq_save_blink
2910 + irq_ctrl_saved.irq_save_lpcount
2911 + 1));
2913 /* Build the stack adjustment note for unwind info. */
2914 j = 0;
2915 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
2916 + irq_ctrl_saved.irq_save_blink
2917 + irq_ctrl_saved.irq_save_lpcount);
2918 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
2919 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
2920 RTX_FRAME_RELATED_P (tmp) = 1;
2921 XVECEXP (par, 0, j++) = tmp;
2923 offset -= UNITS_PER_WORD;
2925 /* 1st goes LP_COUNT. */
2926 if (irq_ctrl_saved.irq_save_lpcount)
2928 reg = gen_rtx_REG (SImode, 60);
2929 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2930 tmp = gen_frame_mem (SImode, tmp);
2931 tmp = gen_rtx_SET (tmp, reg);
2932 RTX_FRAME_RELATED_P (tmp) = 1;
2933 XVECEXP (par, 0, j++) = tmp;
2934 offset -= UNITS_PER_WORD;
2937 /* 2nd goes BLINK. */
2938 if (irq_ctrl_saved.irq_save_blink)
2940 reg = gen_rtx_REG (SImode, 31);
2941 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2942 tmp = gen_frame_mem (SImode, tmp);
2943 tmp = gen_rtx_SET (tmp, reg);
2944 RTX_FRAME_RELATED_P (tmp) = 1;
2945 XVECEXP (par, 0, j++) = tmp;
2946 offset -= UNITS_PER_WORD;
2949 /* Build the parallel of the remaining registers recorded as saved
2950 for unwind. */
2951 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
2953 reg = gen_rtx_REG (SImode, i);
2954 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2955 tmp = gen_frame_mem (SImode, tmp);
2956 tmp = gen_rtx_SET (tmp, reg);
2957 RTX_FRAME_RELATED_P (tmp) = 1;
2958 XVECEXP (par, 0, j++) = tmp;
2959 offset -= UNITS_PER_WORD;
2962 /* Dummy insn used to anchor the dwarf info. */
2963 insn = emit_insn (gen_stack_irq_dwarf());
2964 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
2965 RTX_FRAME_RELATED_P (insn) = 1;
2968 /* Set up the stack and frame pointer (if desired) for the function. */
2970 void
2971 arc_expand_prologue (void)
2973 int size = get_frame_size ();
2974 unsigned int gmask = cfun->machine->frame_info.gmask;
2975 /* unsigned int frame_pointer_offset;*/
2976 unsigned int frame_size_to_allocate;
2977 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
2978 Change the stack layout so that we rather store a high register with the
2979 PRE_MODIFY, thus enabling more short insn generation.) */
2980 int first_offset = 0;
2981 unsigned int fn_type = arc_compute_function_type (cfun);
2983 /* Naked functions don't have prologue. */
2984 if (ARC_NAKED_P (fn_type))
2985 return;
2987 size = ARC_STACK_ALIGN (size);
2989 /* Compute/get total frame size. */
2990 size = (!cfun->machine->frame_info.initialized
2991 ? arc_compute_frame_size (size)
2992 : cfun->machine->frame_info.total_size);
2994 if (flag_stack_usage_info)
2995 current_function_static_stack_size = size;
2997 /* Keep track of frame size to be allocated. */
2998 frame_size_to_allocate = size;
3000 /* These cases shouldn't happen. Catch them now. */
3001 gcc_assert (!(size == 0 && gmask));
3003 /* Allocate space for register arguments if this is a variadic function. */
3004 if (cfun->machine->frame_info.pretend_size != 0)
3006 /* Ensure pretend_size is maximum of 8 * word_size. */
3007 gcc_assert (cfun->machine->frame_info.pretend_size <= 32);
3009 frame_stack_add (-(HOST_WIDE_INT)cfun->machine->frame_info.pretend_size);
3010 frame_size_to_allocate -= cfun->machine->frame_info.pretend_size;
3013 /* IRQ using automatic save mechanism will save the register before
3014 anything we do. */
3015 if (ARC_AUTO_IRQ_P (fn_type)
3016 && !ARC_FAST_INTERRUPT_P (fn_type))
3018 arc_dwarf_emit_irq_save_regs ();
3021 /* The home-grown ABI says link register is saved first. */
3022 if (arc_must_save_return_addr (cfun)
3023 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3025 rtx ra = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
3026 rtx mem = gen_frame_mem (Pmode,
3027 gen_rtx_PRE_DEC (Pmode,
3028 stack_pointer_rtx));
3030 frame_move_inc (mem, ra, stack_pointer_rtx, 0);
3031 frame_size_to_allocate -= UNITS_PER_WORD;
3034 /* Save any needed call-saved regs (and call-used if this is an
3035 interrupt handler) for ARCompact ISA. */
3036 if (cfun->machine->frame_info.reg_size)
3038 first_offset = -cfun->machine->frame_info.reg_size;
3039 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3040 arc_save_restore (stack_pointer_rtx, gmask, 0, &first_offset);
3041 frame_size_to_allocate -= cfun->machine->frame_info.reg_size;
3044 /* Save frame pointer if needed. First save the FP on stack, if not
3045 autosaved. */
3046 if (arc_frame_pointer_needed ()
3047 && !ARC_AUTOFP_IRQ_P (fn_type))
3049 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3050 GEN_INT (-UNITS_PER_WORD + first_offset));
3051 rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_MODIFY (Pmode,
3052 stack_pointer_rtx,
3053 addr));
3054 frame_move_inc (mem, frame_pointer_rtx, stack_pointer_rtx, 0);
3055 frame_size_to_allocate -= UNITS_PER_WORD;
3056 first_offset = 0;
3059 /* Emit mov fp,sp. */
3060 if (arc_frame_pointer_needed ())
3062 frame_move (frame_pointer_rtx, stack_pointer_rtx);
3065 /* ??? We don't handle the case where the saved regs are more than 252
3066 bytes away from sp. This can be handled by decrementing sp once, saving
3067 the regs, and then decrementing it again. The epilogue doesn't have this
3068 problem as the `ld' insn takes reg+limm values (though it would be more
3069 efficient to avoid reg+limm). */
3071 frame_size_to_allocate -= first_offset;
3072 /* Allocate the stack frame. */
3073 if (frame_size_to_allocate > 0)
3075 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3076 /* If the frame pointer is needed, emit a special barrier that
3077 will prevent the scheduler from moving stores to the frame
3078 before the stack adjustment. */
3079 if (arc_frame_pointer_needed ())
3080 emit_insn (gen_stack_tie (stack_pointer_rtx,
3081 hard_frame_pointer_rtx));
3084 /* Setup the gp register, if needed. */
3085 if (crtl->uses_pic_offset_table)
3086 arc_finalize_pic ();
3089 /* Do any necessary cleanup after a function to restore stack, frame,
3090 and regs. */
3092 void
3093 arc_expand_epilogue (int sibcall_p)
3095 int size = get_frame_size ();
3096 unsigned int fn_type = arc_compute_function_type (cfun);
3098 size = ARC_STACK_ALIGN (size);
3099 size = (!cfun->machine->frame_info.initialized
3100 ? arc_compute_frame_size (size)
3101 : cfun->machine->frame_info.total_size);
3103 unsigned int pretend_size = cfun->machine->frame_info.pretend_size;
3104 unsigned int frame_size;
3105 unsigned int size_to_deallocate;
3106 int restored;
3107 int can_trust_sp_p = !cfun->calls_alloca;
3108 int first_offset = 0;
3109 int millicode_p = cfun->machine->frame_info.millicode_end_reg > 0;
3110 rtx insn;
3112 /* Naked functions don't have epilogue. */
3113 if (ARC_NAKED_P (fn_type))
3114 return;
3116 size_to_deallocate = size;
3118 frame_size = size - (pretend_size +
3119 cfun->machine->frame_info.reg_size +
3120 cfun->machine->frame_info.extra_size);
3122 /* ??? There are lots of optimizations that can be done here.
3123 EG: Use fp to restore regs if it's closer.
3124 Maybe in time we'll do them all. For now, always restore regs from
3125 sp, but don't restore sp if we don't have to. */
3127 if (!can_trust_sp_p)
3128 gcc_assert (arc_frame_pointer_needed ());
3130 /* Restore stack pointer to the beginning of saved register area for
3131 ARCompact ISA. */
3132 if (frame_size)
3134 if (arc_frame_pointer_needed ())
3135 frame_move (stack_pointer_rtx, frame_pointer_rtx);
3136 else
3137 first_offset = frame_size;
3138 size_to_deallocate -= frame_size;
3140 else if (!can_trust_sp_p)
3141 frame_stack_add (-frame_size);
3144 /* Restore any saved registers. */
3145 if (arc_frame_pointer_needed ()
3146 && !ARC_AUTOFP_IRQ_P (fn_type))
3148 rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
3150 insn = frame_move_inc (frame_pointer_rtx, gen_frame_mem (Pmode, addr),
3151 stack_pointer_rtx, 0);
3152 add_reg_note (insn, REG_CFA_RESTORE, frame_pointer_rtx);
3153 add_reg_note (insn, REG_CFA_DEF_CFA,
3154 plus_constant (SImode, stack_pointer_rtx,
3155 4));
3156 size_to_deallocate -= UNITS_PER_WORD;
3159 /* Load blink after the calls to thunk calls in case of optimize size. */
3160 if (millicode_p)
3162 int sibthunk_p = (!sibcall_p
3163 && fn_type == ARC_FUNCTION_NORMAL
3164 && !cfun->machine->frame_info.pretend_size);
3166 gcc_assert (!(cfun->machine->frame_info.gmask
3167 & (FRAME_POINTER_MASK | RETURN_ADDR_MASK)));
3168 arc_save_restore (stack_pointer_rtx,
3169 cfun->machine->frame_info.gmask,
3170 1 + sibthunk_p, &first_offset);
3171 if (sibthunk_p)
3172 return;
3174 /* If we are to restore registers, and first_offset would require
3175 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3176 fast add to the stack pointer, do this now. */
3177 if ((!SMALL_INT (first_offset)
3178 && cfun->machine->frame_info.gmask
3179 && ((TARGET_ARC700 && !optimize_size)
3180 ? first_offset <= 0x800
3181 : satisfies_constraint_C2a (GEN_INT (first_offset))))
3182 /* Also do this if we have both gprs and return
3183 address to restore, and they both would need a LIMM. */
3184 || (arc_must_save_return_addr (cfun)
3185 && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2)
3186 && cfun->machine->frame_info.gmask))
3188 frame_stack_add (first_offset);
3189 first_offset = 0;
3191 if (arc_must_save_return_addr (cfun)
3192 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3194 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3195 int ra_offs = cfun->machine->frame_info.reg_size + first_offset;
3196 rtx addr = plus_constant (Pmode, stack_pointer_rtx, ra_offs);
3197 HOST_WIDE_INT cfa_adjust = 0;
3199 /* If the load of blink would need a LIMM, but we can add
3200 the offset quickly to sp, do the latter. */
3201 if (!SMALL_INT (ra_offs >> 2)
3202 && !cfun->machine->frame_info.gmask
3203 && ((TARGET_ARC700 && !optimize_size)
3204 ? ra_offs <= 0x800
3205 : satisfies_constraint_C2a (GEN_INT (ra_offs))))
3207 size_to_deallocate -= ra_offs - first_offset;
3208 first_offset = 0;
3209 frame_stack_add (ra_offs);
3210 ra_offs = 0;
3211 addr = stack_pointer_rtx;
3213 /* See if we can combine the load of the return address with the
3214 final stack adjustment.
3215 We need a separate load if there are still registers to
3216 restore. We also want a separate load if the combined insn
3217 would need a limm, but a separate load doesn't. */
3218 if (ra_offs
3219 && !cfun->machine->frame_info.gmask
3220 && (SMALL_INT (ra_offs) || !SMALL_INT (ra_offs >> 2)))
3222 addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, addr);
3223 cfa_adjust = ra_offs;
3224 first_offset = 0;
3225 size_to_deallocate -= cfun->machine->frame_info.reg_size;
3227 else if (!ra_offs && size_to_deallocate == UNITS_PER_WORD)
3229 addr = gen_rtx_POST_INC (Pmode, addr);
3230 cfa_adjust = GET_MODE_SIZE (Pmode);
3231 size_to_deallocate = 0;
3234 insn = frame_move_inc (ra, gen_frame_mem (Pmode, addr),
3235 stack_pointer_rtx, addr);
3236 if (cfa_adjust)
3238 enum reg_note note = REG_CFA_ADJUST_CFA;
3240 add_reg_note (insn, note,
3241 gen_rtx_SET (stack_pointer_rtx,
3242 plus_constant (SImode, stack_pointer_rtx,
3243 cfa_adjust)));
3245 add_reg_note (insn, REG_CFA_RESTORE, ra);
3248 if (!millicode_p)
3250 if (cfun->machine->frame_info.reg_size)
3251 arc_save_restore (stack_pointer_rtx,
3252 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3253 cfun->machine->frame_info.gmask
3254 & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 1, &first_offset);
3257 /* The rest of this function does the following:
3258 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3261 /* Keep track of how much of the stack pointer we've restored.
3262 It makes the following a lot more readable. */
3263 size_to_deallocate += first_offset;
3264 restored = size - size_to_deallocate;
3266 if (size > restored)
3267 frame_stack_add (size - restored);
3269 /* Emit the return instruction. */
3270 if (sibcall_p == FALSE)
3271 emit_jump_insn (gen_simple_return ());
3274 /* Return the offset relative to the stack pointer where the return address
3275 is stored, or -1 if it is not stored. */
3278 arc_return_slot_offset ()
3280 struct arc_frame_info *afi = &cfun->machine->frame_info;
3282 return (afi->save_return_addr
3283 ? afi->total_size - afi->pretend_size - afi->extra_size : -1);
3286 /* PIC */
3288 /* Helper to generate unspec constant. */
3290 static rtx
3291 arc_unspec_offset (rtx loc, int unspec)
3293 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
3294 unspec));
3297 /* Emit special PIC prologues and epilogues. */
3298 /* If the function has any GOTOFF relocations, then the GOTBASE
3299 register has to be setup in the prologue
3300 The instruction needed at the function start for setting up the
3301 GOTBASE register is
3302 add rdest, pc,
3303 ----------------------------------------------------------
3304 The rtl to be emitted for this should be:
3305 set (reg basereg)
3306 (plus (reg pc)
3307 (const (unspec (symref _DYNAMIC) 3)))
3308 ---------------------------------------------------------- */
3310 static void
3311 arc_finalize_pic (void)
3313 rtx pat;
3314 rtx baseptr_rtx = gen_rtx_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);
3316 if (crtl->uses_pic_offset_table == 0)
3317 return;
3319 gcc_assert (flag_pic != 0);
3321 pat = gen_rtx_SYMBOL_REF (Pmode, "_DYNAMIC");
3322 pat = arc_unspec_offset (pat, ARC_UNSPEC_GOT);
3323 pat = gen_rtx_SET (baseptr_rtx, pat);
3325 emit_insn (pat);
3328 /* !TARGET_BARREL_SHIFTER support. */
3329 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3330 kind of shift. */
3332 void
3333 emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
3335 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
3336 rtx pat
3337 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop)
3338 (op0, op1, op2, shift));
3339 emit_insn (pat);
3342 /* Output the assembler code for doing a shift.
3343 We go to a bit of trouble to generate efficient code as the ARC601 only has
3344 single bit shifts. This is taken from the h8300 port. We only have one
3345 mode of shifting and can't access individual bytes like the h8300 can, so
3346 this is greatly simplified (at the expense of not generating hyper-
3347 efficient code).
3349 This function is not used if the variable shift insns are present. */
3351 /* FIXME: This probably can be done using a define_split in arc.md.
3352 Alternately, generate rtx rather than output instructions. */
3354 const char *
3355 output_shift (rtx *operands)
3357 /* static int loopend_lab;*/
3358 rtx shift = operands[3];
3359 machine_mode mode = GET_MODE (shift);
3360 enum rtx_code code = GET_CODE (shift);
3361 const char *shift_one;
3363 gcc_assert (mode == SImode);
3365 switch (code)
3367 case ASHIFT: shift_one = "add %0,%1,%1"; break;
3368 case ASHIFTRT: shift_one = "asr %0,%1"; break;
3369 case LSHIFTRT: shift_one = "lsr %0,%1"; break;
3370 default: gcc_unreachable ();
3373 if (GET_CODE (operands[2]) != CONST_INT)
3375 output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
3376 goto shiftloop;
3378 else
3380 int n;
3382 n = INTVAL (operands[2]);
3384 /* Only consider the lower 5 bits of the shift count. */
3385 n = n & 0x1f;
3387 /* First see if we can do them inline. */
3388 /* ??? We could get better scheduling & shorter code (using short insns)
3389 by using splitters. Alas, that'd be even more verbose. */
3390 if (code == ASHIFT && n <= 9 && n > 2
3391 && dest_reg_operand (operands[4], SImode))
3393 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
3394 for (n -=3 ; n >= 3; n -= 3)
3395 output_asm_insn ("add3 %0,%4,%0", operands);
3396 if (n == 2)
3397 output_asm_insn ("add2 %0,%4,%0", operands);
3398 else if (n)
3399 output_asm_insn ("add %0,%0,%0", operands);
3401 else if (n <= 4)
3403 while (--n >= 0)
3405 output_asm_insn (shift_one, operands);
3406 operands[1] = operands[0];
3409 /* See if we can use a rotate/and. */
3410 else if (n == BITS_PER_WORD - 1)
3412 switch (code)
3414 case ASHIFT :
3415 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
3416 break;
3417 case ASHIFTRT :
3418 /* The ARC doesn't have a rol insn. Use something else. */
3419 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
3420 break;
3421 case LSHIFTRT :
3422 /* The ARC doesn't have a rol insn. Use something else. */
3423 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
3424 break;
3425 default:
3426 break;
3429 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
3431 switch (code)
3433 case ASHIFT :
3434 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
3435 break;
3436 case ASHIFTRT :
3437 #if 1 /* Need some scheduling comparisons. */
3438 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3439 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3440 #else
3441 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3442 "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
3443 #endif
3444 break;
3445 case LSHIFTRT :
3446 #if 1
3447 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3448 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3449 #else
3450 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3451 "and %0,%0,1\n\trlc %0,%0", operands);
3452 #endif
3453 break;
3454 default:
3455 break;
3458 else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
3459 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3460 operands);
3461 /* Must loop. */
3462 else
3464 operands[2] = GEN_INT (n);
3465 output_asm_insn ("mov.f lp_count, %2", operands);
3467 shiftloop:
3469 output_asm_insn ("lpnz\t2f", operands);
3470 output_asm_insn (shift_one, operands);
3471 output_asm_insn ("nop", operands);
3472 fprintf (asm_out_file, "2:\t%s end single insn loop\n",
3473 ASM_COMMENT_START);
3478 return "";
3481 /* Nested function support. */
3483 /* Directly store VALUE into memory object BLOCK at OFFSET. */
3485 static void
3486 emit_store_direct (rtx block, int offset, int value)
3488 emit_insn (gen_store_direct (adjust_address (block, SImode, offset),
3489 force_reg (SImode,
3490 gen_int_mode (value, SImode))));
3493 /* Emit RTL insns to initialize the variable parts of a trampoline.
3494 FNADDR is an RTX for the address of the function's pure code.
3495 CXT is an RTX for the static chain value for the function. */
3496 /* With potentially multiple shared objects loaded, and multiple stacks
3497 present for multiple thereds where trampolines might reside, a simple
3498 range check will likely not suffice for the profiler to tell if a callee
3499 is a trampoline. We a speedier check by making the trampoline start at
3500 an address that is not 4-byte aligned.
3501 A trampoline looks like this:
3503 nop_s 0x78e0
3504 entry:
3505 ld_s r12,[pcl,12] 0xd403
3506 ld r11,[pcl,12] 0x170c 700b
3507 j_s [r12] 0x7c00
3508 nop_s 0x78e0
3510 The fastest trampoline to execute for trampolines within +-8KB of CTX
3511 would be:
3512 add2 r11,pcl,s12
3513 j [limm] 0x20200f80 limm
3514 and that would also be faster to write to the stack by computing the offset
3515 from CTX to TRAMP at compile time. However, it would really be better to
3516 get rid of the high cost of cache invalidation when generating trampolines,
3517 which requires that the code part of trampolines stays constant, and
3518 additionally either
3519 - making sure that no executable code but trampolines is on the stack,
3520 no icache entries linger for the area of the stack from when before the
3521 stack was allocated, and allocating trampolines in trampoline-only
3522 cache lines
3524 - allocate trampolines fram a special pool of pre-allocated trampolines. */
3526 static void
3527 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
3529 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3531 emit_store_direct (tramp, 0, TARGET_BIG_ENDIAN ? 0x78e0d403 : 0xd40378e0);
3532 emit_store_direct (tramp, 4, TARGET_BIG_ENDIAN ? 0x170c700b : 0x700b170c);
3533 emit_store_direct (tramp, 8, TARGET_BIG_ENDIAN ? 0x7c0078e0 : 0x78e07c00);
3534 emit_move_insn (adjust_address (tramp, SImode, 12), fnaddr);
3535 emit_move_insn (adjust_address (tramp, SImode, 16), cxt);
3536 emit_insn (gen_flush_icache (adjust_address (tramp, SImode, 0)));
3539 /* Allow the profiler to easily distinguish trampolines from normal
3540 functions. */
3542 static rtx
3543 arc_trampoline_adjust_address (rtx addr)
3545 return plus_constant (Pmode, addr, 2);
3548 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3549 reset when we output the scaled address. */
3550 static int output_scaled = 0;
3552 /* Print operand X (an rtx) in assembler syntax to file FILE.
3553 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3554 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3555 /* In final.c:output_asm_insn:
3556 'l' : label
3557 'a' : address
3558 'c' : constant address if CONSTANT_ADDRESS_P
3559 'n' : negative
3560 Here:
3561 'Z': log2(x+1)-1
3562 'z': log2
3563 'M': log2(~x)
3564 'p': bit Position of lsb
3565 's': size of bit field
3566 '#': condbranch delay slot suffix
3567 '*': jump delay slot suffix
3568 '?' : nonjump-insn suffix for conditional execution or short instruction
3569 '!' : jump / call suffix for conditional execution or short instruction
3570 '`': fold constant inside unary o-perator, re-recognize, and emit.
3573 'R': Second word
3575 'B': Branch comparison operand - suppress sda reference
3576 'H': Most significant word
3577 'L': Least significant word
3578 'A': ASCII decimal representation of floating point value
3579 'U': Load/store update or scaling indicator
3580 'V': cache bypass indicator for volatile
3584 'O': Operator
3585 'o': original symbol - no @ prepending. */
3587 void
3588 arc_print_operand (FILE *file, rtx x, int code)
3590 switch (code)
3592 case 'Z':
3593 if (GET_CODE (x) == CONST_INT)
3594 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
3595 else
3596 output_operand_lossage ("invalid operand to %%Z code");
3598 return;
3600 case 'z':
3601 if (GET_CODE (x) == CONST_INT)
3602 fprintf (file, "%d",exact_log2(INTVAL (x)) );
3603 else
3604 output_operand_lossage ("invalid operand to %%z code");
3606 return;
3608 case 'c':
3609 if (GET_CODE (x) == CONST_INT)
3610 fprintf (file, "%d", INTVAL (x) );
3611 else
3612 output_operand_lossage ("invalid operands to %%c code");
3614 return;
3616 case 'M':
3617 if (GET_CODE (x) == CONST_INT)
3618 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
3619 else
3620 output_operand_lossage ("invalid operand to %%M code");
3622 return;
3624 case 'p':
3625 if (GET_CODE (x) == CONST_INT)
3626 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
3627 else
3628 output_operand_lossage ("invalid operand to %%p code");
3629 return;
3631 case 's':
3632 if (GET_CODE (x) == CONST_INT)
3634 HOST_WIDE_INT i = INTVAL (x);
3635 HOST_WIDE_INT s = exact_log2 (i & -i);
3636 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
3638 else
3639 output_operand_lossage ("invalid operand to %%s code");
3640 return;
3642 case '#' :
3643 /* Conditional branches depending on condition codes.
3644 Note that this is only for branches that were known to depend on
3645 condition codes before delay slot scheduling;
3646 out-of-range brcc / bbit expansions should use '*'.
3647 This distinction is important because of the different
3648 allowable delay slot insns and the output of the delay suffix
3649 for TARGET_AT_DBR_COND_EXEC. */
3650 case '*' :
3651 /* Unconditional branches / branches not depending on condition codes.
3652 This could also be a CALL_INSN.
3653 Output the appropriate delay slot suffix. */
3654 if (final_sequence && final_sequence->len () != 1)
3656 rtx_insn *jump = final_sequence->insn (0);
3657 rtx_insn *delay = final_sequence->insn (1);
3659 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3660 if (delay->deleted ())
3661 return;
3662 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3663 fputs (INSN_FROM_TARGET_P (delay) ? ".d"
3664 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d"
3665 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? ""
3666 : ".nd",
3667 file);
3668 else
3669 fputs (".d", file);
3671 return;
3672 case '?' : /* with leading "." */
3673 case '!' : /* without leading "." */
3674 /* This insn can be conditionally executed. See if the ccfsm machinery
3675 says it should be conditionalized.
3676 If it shouldn't, we'll check the compact attribute if this insn
3677 has a short variant, which may be used depending on code size and
3678 alignment considerations. */
3679 if (current_insn_predicate)
3680 arc_ccfsm_current.cc
3681 = get_arc_condition_code (current_insn_predicate);
3682 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current))
3684 /* Is this insn in a delay slot sequence? */
3685 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
3686 || current_insn_predicate
3687 || CALL_P (final_sequence->insn (0))
3688 || simplejump_p (final_sequence->insn (0)))
3690 /* This insn isn't in a delay slot sequence, or conditionalized
3691 independently of its position in a delay slot. */
3692 fprintf (file, "%s%s",
3693 code == '?' ? "." : "",
3694 arc_condition_codes[arc_ccfsm_current.cc]);
3695 /* If this is a jump, there are still short variants. However,
3696 only beq_s / bne_s have the same offset range as b_s,
3697 and the only short conditional returns are jeq_s and jne_s. */
3698 if (code == '!'
3699 && (arc_ccfsm_current.cc == ARC_CC_EQ
3700 || arc_ccfsm_current.cc == ARC_CC_NE
3701 || 0 /* FIXME: check if branch in 7 bit range. */))
3702 output_short_suffix (file);
3704 else if (code == '!') /* Jump with delay slot. */
3705 fputs (arc_condition_codes[arc_ccfsm_current.cc], file);
3706 else /* An Instruction in a delay slot of a jump or call. */
3708 rtx jump = XVECEXP (final_sequence, 0, 0);
3709 rtx insn = XVECEXP (final_sequence, 0, 1);
3711 /* If the insn is annulled and is from the target path, we need
3712 to inverse the condition test. */
3713 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3715 if (INSN_FROM_TARGET_P (insn))
3716 fprintf (file, "%s%s",
3717 code == '?' ? "." : "",
3718 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]);
3719 else
3720 fprintf (file, "%s%s",
3721 code == '?' ? "." : "",
3722 arc_condition_codes[arc_ccfsm_current.cc]);
3723 if (arc_ccfsm_current.state == 5)
3724 arc_ccfsm_current.state = 0;
3726 else
3727 /* This insn is executed for either path, so don't
3728 conditionalize it at all. */
3729 output_short_suffix (file);
3733 else
3734 output_short_suffix (file);
3735 return;
3736 case'`':
3737 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3738 gcc_unreachable ();
3739 case 'd' :
3740 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
3741 return;
3742 case 'D' :
3743 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
3744 (get_arc_condition_code (x))],
3745 file);
3746 return;
3747 case 'R' :
3748 /* Write second word of DImode or DFmode reference,
3749 register or memory. */
3750 if (GET_CODE (x) == REG)
3751 fputs (reg_names[REGNO (x)+1], file);
3752 else if (GET_CODE (x) == MEM)
3754 fputc ('[', file);
3756 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3757 PRE_MODIFY, we will have handled the first word already;
3758 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3759 first word will be done later. In either case, the access
3760 to the first word will do the modify, and we only have
3761 to add an offset of four here. */
3762 if (GET_CODE (XEXP (x, 0)) == PRE_INC
3763 || GET_CODE (XEXP (x, 0)) == PRE_DEC
3764 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
3765 || GET_CODE (XEXP (x, 0)) == POST_INC
3766 || GET_CODE (XEXP (x, 0)) == POST_DEC
3767 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
3768 output_address (VOIDmode,
3769 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
3770 else if (output_scaled)
3772 rtx addr = XEXP (x, 0);
3773 int size = GET_MODE_SIZE (GET_MODE (x));
3775 output_address (VOIDmode,
3776 plus_constant (Pmode, XEXP (addr, 0),
3777 ((INTVAL (XEXP (addr, 1)) + 4)
3778 >> (size == 2 ? 1 : 2))));
3779 output_scaled = 0;
3781 else
3782 output_address (VOIDmode,
3783 plus_constant (Pmode, XEXP (x, 0), 4));
3784 fputc (']', file);
3786 else
3787 output_operand_lossage ("invalid operand to %%R code");
3788 return;
3789 case 'S' :
3790 /* FIXME: remove %S option. */
3791 break;
3792 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
3793 if (CONSTANT_P (x))
3795 output_addr_const (file, x);
3796 return;
3798 break;
3799 case 'H' :
3800 case 'L' :
3801 if (GET_CODE (x) == REG)
3803 /* L = least significant word, H = most significant word. */
3804 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
3805 fputs (reg_names[REGNO (x)], file);
3806 else
3807 fputs (reg_names[REGNO (x)+1], file);
3809 else if (GET_CODE (x) == CONST_INT
3810 || GET_CODE (x) == CONST_DOUBLE)
3812 rtx first, second, word;
3814 split_double (x, &first, &second);
3816 if((WORDS_BIG_ENDIAN) == 0)
3817 word = (code == 'L' ? first : second);
3818 else
3819 word = (code == 'L' ? second : first);
3821 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
3823 else
3824 output_operand_lossage ("invalid operand to %%H/%%L code");
3825 return;
3826 case 'A' :
3828 char str[30];
3830 gcc_assert (GET_CODE (x) == CONST_DOUBLE
3831 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
3833 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
3834 fprintf (file, "%s", str);
3835 return;
3837 case 'U' :
3838 /* Output a load/store with update indicator if appropriate. */
3839 if (GET_CODE (x) == MEM)
3841 rtx addr = XEXP (x, 0);
3842 switch (GET_CODE (addr))
3844 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
3845 fputs (".a", file); break;
3846 case POST_INC: case POST_DEC: case POST_MODIFY:
3847 fputs (".ab", file); break;
3848 case PLUS:
3849 /* Are we using a scaled index? */
3850 if (GET_CODE (XEXP (addr, 0)) == MULT)
3851 fputs (".as", file);
3852 /* Can we use a scaled offset? */
3853 else if (CONST_INT_P (XEXP (addr, 1))
3854 && GET_MODE_SIZE (GET_MODE (x)) > 1
3855 && (!(INTVAL (XEXP (addr, 1))
3856 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
3857 /* Does it make a difference? */
3858 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
3859 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
3861 fputs (".as", file);
3862 output_scaled = 1;
3864 else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr)
3865 && GET_MODE_SIZE (GET_MODE (x)) > 1)
3867 tree decl = NULL_TREE;
3868 int align = 0;
3869 if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
3870 decl = SYMBOL_REF_DECL (XEXP (addr, 1));
3871 else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0))
3872 == SYMBOL_REF)
3873 decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
3874 if (decl)
3875 align = DECL_ALIGN (decl);
3876 align = align / BITS_PER_UNIT;
3877 if ((GET_MODE_SIZE (GET_MODE (x)) == 2)
3878 && align && ((align & 1) == 0))
3879 fputs (".as", file);
3880 if ((GET_MODE_SIZE (GET_MODE (x)) >= 4)
3881 && align && ((align & 3) == 0))
3882 fputs (".as", file);
3884 break;
3885 case REG:
3886 break;
3887 default:
3888 gcc_assert (CONSTANT_P (addr)); break;
3891 else
3892 output_operand_lossage ("invalid operand to %%U code");
3893 return;
3894 case 'V' :
3895 /* Output cache bypass indicator for a load/store insn. Volatile memory
3896 refs are defined to use the cache bypass mechanism. */
3897 if (GET_CODE (x) == MEM)
3899 if (MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET )
3900 fputs (".di", file);
3902 else
3903 output_operand_lossage ("invalid operand to %%V code");
3904 return;
3905 /* plt code. */
3906 case 'P':
3907 case 0 :
3908 /* Do nothing special. */
3909 break;
3910 case 'F':
3911 fputs (reg_names[REGNO (x)]+1, file);
3912 return;
3913 case '^':
3914 /* This punctuation character is needed because label references are
3915 printed in the output template using %l. This is a front end
3916 character, and when we want to emit a '@' before it, we have to use
3917 this '^'. */
3919 fputc('@',file);
3920 return;
3921 case 'O':
3922 /* Output an operator. */
3923 switch (GET_CODE (x))
3925 case PLUS: fputs ("add", file); return;
3926 case SS_PLUS: fputs ("adds", file); return;
3927 case AND: fputs ("and", file); return;
3928 case IOR: fputs ("or", file); return;
3929 case XOR: fputs ("xor", file); return;
3930 case MINUS: fputs ("sub", file); return;
3931 case SS_MINUS: fputs ("subs", file); return;
3932 case ASHIFT: fputs ("asl", file); return;
3933 case ASHIFTRT: fputs ("asr", file); return;
3934 case LSHIFTRT: fputs ("lsr", file); return;
3935 case ROTATERT: fputs ("ror", file); return;
3936 case MULT: fputs ("mpy", file); return;
3937 case ABS: fputs ("abs", file); return; /* Unconditional. */
3938 case NEG: fputs ("neg", file); return;
3939 case SS_NEG: fputs ("negs", file); return;
3940 case NOT: fputs ("not", file); return; /* Unconditional. */
3941 case ZERO_EXTEND:
3942 fputs ("ext", file); /* bmsk allows predication. */
3943 goto size_suffix;
3944 case SIGN_EXTEND: /* Unconditional. */
3945 fputs ("sex", file);
3946 size_suffix:
3947 switch (GET_MODE (XEXP (x, 0)))
3949 case E_QImode: fputs ("b", file); return;
3950 case E_HImode: fputs ("w", file); return;
3951 default: break;
3953 break;
3954 case SS_TRUNCATE:
3955 if (GET_MODE (x) != HImode)
3956 break;
3957 fputs ("sat16", file);
3958 default: break;
3960 output_operand_lossage ("invalid operand to %%O code"); return;
3961 case 'o':
3962 if (GET_CODE (x) == SYMBOL_REF)
3964 assemble_name (file, XSTR (x, 0));
3965 return;
3967 break;
3968 case '&':
3969 if (TARGET_ANNOTATE_ALIGN && cfun->machine->size_reason)
3970 fprintf (file, "; unalign: %d", cfun->machine->unalign);
3971 return;
3972 case '+':
3973 if (TARGET_V2)
3974 fputs ("m", file);
3975 else
3976 fputs ("h", file);
3977 return;
3978 case '_':
3979 if (TARGET_V2)
3980 fputs ("h", file);
3981 else
3982 fputs ("w", file);
3983 return;
3984 default :
3985 /* Unknown flag. */
3986 output_operand_lossage ("invalid operand output code");
3989 switch (GET_CODE (x))
3991 case REG :
3992 fputs (reg_names[REGNO (x)], file);
3993 break;
3994 case MEM :
3996 rtx addr = XEXP (x, 0);
3997 int size = GET_MODE_SIZE (GET_MODE (x));
3999 fputc ('[', file);
4001 switch (GET_CODE (addr))
4003 case PRE_INC: case POST_INC:
4004 output_address (VOIDmode,
4005 plus_constant (Pmode, XEXP (addr, 0), size)); break;
4006 case PRE_DEC: case POST_DEC:
4007 output_address (VOIDmode,
4008 plus_constant (Pmode, XEXP (addr, 0), -size));
4009 break;
4010 case PRE_MODIFY: case POST_MODIFY:
4011 output_address (VOIDmode, XEXP (addr, 1)); break;
4012 case PLUS:
4013 if (output_scaled)
4015 output_address (VOIDmode,
4016 plus_constant (Pmode, XEXP (addr, 0),
4017 (INTVAL (XEXP (addr, 1))
4018 >> (size == 2 ? 1 : 2))));
4019 output_scaled = 0;
4021 else
4022 output_address (VOIDmode, addr);
4023 break;
4024 default:
4025 if (flag_pic && CONSTANT_ADDRESS_P (addr))
4026 arc_output_pic_addr_const (file, addr, code);
4027 else
4028 output_address (VOIDmode, addr);
4029 break;
4031 fputc (']', file);
4032 break;
4034 case CONST_DOUBLE :
4035 /* We handle SFmode constants here as output_addr_const doesn't. */
4036 if (GET_MODE (x) == SFmode)
4038 long l;
4040 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
4041 fprintf (file, "0x%08lx", l);
4042 break;
4044 /* FALLTHRU */
4045 /* Let output_addr_const deal with it. */
4046 default :
4047 if (flag_pic
4048 || (GET_CODE (x) == CONST
4049 && GET_CODE (XEXP (x, 0)) == UNSPEC
4050 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
4051 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
4052 || (GET_CODE (x) == CONST
4053 && GET_CODE (XEXP (x, 0)) == PLUS
4054 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
4055 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
4056 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
4057 arc_output_pic_addr_const (file, x, code);
4058 else
4060 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
4061 with asm_output_symbol_ref */
4062 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
4064 x = XEXP (x, 0);
4065 output_addr_const (file, XEXP (x, 0));
4066 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && SYMBOL_REF_SMALL_P (XEXP (x, 0)))
4067 fprintf (file, "@sda");
4069 if (GET_CODE (XEXP (x, 1)) != CONST_INT
4070 || INTVAL (XEXP (x, 1)) >= 0)
4071 fprintf (file, "+");
4072 output_addr_const (file, XEXP (x, 1));
4074 else
4075 output_addr_const (file, x);
4077 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
4078 fprintf (file, "@sda");
4079 break;
4083 /* Print a memory address as an operand to reference that memory location. */
4085 void
4086 arc_print_operand_address (FILE *file , rtx addr)
4088 register rtx base, index = 0;
4090 switch (GET_CODE (addr))
4092 case REG :
4093 fputs (reg_names[REGNO (addr)], file);
4094 break;
4095 case SYMBOL_REF :
4096 output_addr_const (file, addr);
4097 if (SYMBOL_REF_SMALL_P (addr))
4098 fprintf (file, "@sda");
4099 break;
4100 case PLUS :
4101 if (GET_CODE (XEXP (addr, 0)) == MULT)
4102 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
4103 else if (CONST_INT_P (XEXP (addr, 0)))
4104 index = XEXP (addr, 0), base = XEXP (addr, 1);
4105 else
4106 base = XEXP (addr, 0), index = XEXP (addr, 1);
4108 gcc_assert (OBJECT_P (base));
4109 arc_print_operand_address (file, base);
4110 if (CONSTANT_P (base) && CONST_INT_P (index))
4111 fputc ('+', file);
4112 else
4113 fputc (',', file);
4114 gcc_assert (OBJECT_P (index));
4115 arc_print_operand_address (file, index);
4116 break;
4117 case CONST:
4119 rtx c = XEXP (addr, 0);
4121 if ((GET_CODE (c) == UNSPEC
4122 && (XINT (c, 1) == UNSPEC_TLS_OFF
4123 || XINT (c, 1) == UNSPEC_TLS_IE))
4124 || (GET_CODE (c) == PLUS
4125 && GET_CODE (XEXP (c, 0)) == UNSPEC
4126 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
4127 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
4129 arc_output_pic_addr_const (file, c, 0);
4130 break;
4132 gcc_assert (GET_CODE (c) == PLUS);
4133 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
4134 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
4136 output_address (VOIDmode, XEXP (addr, 0));
4138 break;
4140 case PRE_INC :
4141 case PRE_DEC :
4142 /* We shouldn't get here as we've lost the mode of the memory object
4143 (which says how much to inc/dec by. */
4144 gcc_unreachable ();
4145 break;
4146 default :
4147 if (flag_pic)
4148 arc_output_pic_addr_const (file, addr, 0);
4149 else
4150 output_addr_const (file, addr);
4151 break;
4155 /* Conditional execution support.
4157 This is based on the ARM port but for now is much simpler.
4159 A finite state machine takes care of noticing whether or not instructions
4160 can be conditionally executed, and thus decrease execution time and code
4161 size by deleting branch instructions. The fsm is controlled by
4162 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4163 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4164 insns also have a hand in this. */
4165 /* The way we leave dealing with non-anulled or annull-false delay slot
4166 insns to the consumer is awkward. */
4168 /* The state of the fsm controlling condition codes are:
4169 0: normal, do nothing special
4170 1: don't output this insn
4171 2: don't output this insn
4172 3: make insns conditional
4173 4: make insns conditional
4174 5: make insn conditional (only for outputting anulled delay slot insns)
4176 special value for cfun->machine->uid_ccfsm_state:
4177 6: return with but one insn before it since function start / call
4179 State transitions (state->state by whom, under what condition):
4180 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4181 some instructions.
4182 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4183 by zero or more non-jump insns and an unconditional branch with
4184 the same target label as the condbranch.
4185 1 -> 3 branch patterns, after having not output the conditional branch
4186 2 -> 4 branch patterns, after having not output the conditional branch
4187 0 -> 5 branch patterns, for anulled delay slot insn.
4188 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4189 (the target label has CODE_LABEL_NUMBER equal to
4190 arc_ccfsm_target_label).
4191 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4192 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4193 5 -> 0 when outputting the delay slot insn
4195 If the jump clobbers the conditions then we use states 2 and 4.
4197 A similar thing can be done with conditional return insns.
4199 We also handle separating branches from sets of the condition code.
4200 This is done here because knowledge of the ccfsm state is required,
4201 we may not be outputting the branch. */
4203 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4204 before letting final output INSN. */
4206 static void
4207 arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
4209 /* BODY will hold the body of INSN. */
4210 register rtx body;
4212 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4213 an if/then/else), and things need to be reversed. */
4214 int reverse = 0;
4216 /* If we start with a return insn, we only succeed if we find another one. */
4217 int seeking_return = 0;
4219 /* START_INSN will hold the insn from where we start looking. This is the
4220 first insn after the following code_label if REVERSE is true. */
4221 rtx_insn *start_insn = insn;
4223 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4224 since they don't rely on a cmp preceding the. */
4225 enum attr_type jump_insn_type;
4227 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4228 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4229 final_scan_insn which has `optimize' as a local. */
4230 if (optimize < 2 || TARGET_NO_COND_EXEC)
4231 return;
4233 /* Ignore notes and labels. */
4234 if (!INSN_P (insn))
4235 return;
4236 body = PATTERN (insn);
4237 /* If in state 4, check if the target branch is reached, in order to
4238 change back to state 0. */
4239 if (state->state == 4)
4241 if (insn == state->target_insn)
4243 state->target_insn = NULL;
4244 state->state = 0;
4246 return;
4249 /* If in state 3, it is possible to repeat the trick, if this insn is an
4250 unconditional branch to a label, and immediately following this branch
4251 is the previous target label which is only used once, and the label this
4252 branch jumps to is not too far off. Or in other words "we've done the
4253 `then' part, see if we can do the `else' part." */
4254 if (state->state == 3)
4256 if (simplejump_p (insn))
4258 start_insn = next_nonnote_insn (start_insn);
4259 if (GET_CODE (start_insn) == BARRIER)
4261 /* ??? Isn't this always a barrier? */
4262 start_insn = next_nonnote_insn (start_insn);
4264 if (GET_CODE (start_insn) == CODE_LABEL
4265 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4266 && LABEL_NUSES (start_insn) == 1)
4267 reverse = TRUE;
4268 else
4269 return;
4271 else if (GET_CODE (body) == SIMPLE_RETURN)
4273 start_insn = next_nonnote_insn (start_insn);
4274 if (GET_CODE (start_insn) == BARRIER)
4275 start_insn = next_nonnote_insn (start_insn);
4276 if (GET_CODE (start_insn) == CODE_LABEL
4277 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4278 && LABEL_NUSES (start_insn) == 1)
4280 reverse = TRUE;
4281 seeking_return = 1;
4283 else
4284 return;
4286 else
4287 return;
4290 if (GET_CODE (insn) != JUMP_INSN
4291 || GET_CODE (PATTERN (insn)) == ADDR_VEC
4292 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
4293 return;
4295 /* We can't predicate BRCC or loop ends.
4296 Also, when generating PIC code, and considering a medium range call,
4297 we can't predicate the call. */
4298 jump_insn_type = get_attr_type (insn);
4299 if (jump_insn_type == TYPE_BRCC
4300 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
4301 || jump_insn_type == TYPE_LOOP_END
4302 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
4303 return;
4305 /* This jump might be paralleled with a clobber of the condition codes,
4306 the jump should always come first. */
4307 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
4308 body = XVECEXP (body, 0, 0);
4310 if (reverse
4311 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
4312 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
4314 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
4315 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4316 int then_not_else = TRUE;
4317 /* Nonzero if next insn must be the target label. */
4318 int next_must_be_target_label_p;
4319 rtx_insn *this_insn = start_insn;
4320 rtx label = 0;
4322 /* Register the insn jumped to. */
4323 if (reverse)
4325 if (!seeking_return)
4326 label = XEXP (SET_SRC (body), 0);
4328 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
4329 label = XEXP (XEXP (SET_SRC (body), 1), 0);
4330 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
4332 label = XEXP (XEXP (SET_SRC (body), 2), 0);
4333 then_not_else = FALSE;
4335 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
4336 seeking_return = 1;
4337 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
4339 seeking_return = 1;
4340 then_not_else = FALSE;
4342 else
4343 gcc_unreachable ();
4345 /* If this is a non-annulled branch with a delay slot, there is
4346 no need to conditionalize the delay slot. */
4347 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) == SEQUENCE)
4348 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
4350 this_insn = NEXT_INSN (this_insn);
4352 /* See how many insns this branch skips, and what kind of insns. If all
4353 insns are okay, and the label or unconditional branch to the same
4354 label is not too far away, succeed. */
4355 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
4356 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
4357 insns_skipped++)
4359 rtx scanbody;
4361 this_insn = next_nonnote_insn (this_insn);
4362 if (!this_insn)
4363 break;
4365 if (next_must_be_target_label_p)
4367 if (GET_CODE (this_insn) == BARRIER)
4368 continue;
4369 if (GET_CODE (this_insn) == CODE_LABEL
4370 && this_insn == label)
4372 state->state = 1;
4373 succeed = TRUE;
4375 else
4376 fail = TRUE;
4377 break;
4380 switch (GET_CODE (this_insn))
4382 case CODE_LABEL:
4383 /* Succeed if it is the target label, otherwise fail since
4384 control falls in from somewhere else. */
4385 if (this_insn == label)
4387 state->state = 1;
4388 succeed = TRUE;
4390 else
4391 fail = TRUE;
4392 break;
4394 case BARRIER:
4395 /* Succeed if the following insn is the target label.
4396 Otherwise fail.
4397 If return insns are used then the last insn in a function
4398 will be a barrier. */
4399 next_must_be_target_label_p = TRUE;
4400 break;
4402 case CALL_INSN:
4403 /* Can handle a call insn if there are no insns after it.
4404 IE: The next "insn" is the target label. We don't have to
4405 worry about delay slots as such insns are SEQUENCE's inside
4406 INSN's. ??? It is possible to handle such insns though. */
4407 if (get_attr_cond (this_insn) == COND_CANUSE)
4408 next_must_be_target_label_p = TRUE;
4409 else
4410 fail = TRUE;
4411 break;
4413 case JUMP_INSN:
4414 scanbody = PATTERN (this_insn);
4416 /* If this is an unconditional branch to the same label, succeed.
4417 If it is to another label, do nothing. If it is conditional,
4418 fail. */
4419 /* ??? Probably, the test for the SET and the PC are
4420 unnecessary. */
4422 if (GET_CODE (scanbody) == SET
4423 && GET_CODE (SET_DEST (scanbody)) == PC)
4425 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
4426 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
4428 state->state = 2;
4429 succeed = TRUE;
4431 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
4432 fail = TRUE;
4433 else if (get_attr_cond (this_insn) != COND_CANUSE)
4434 fail = TRUE;
4436 else if (GET_CODE (scanbody) == SIMPLE_RETURN
4437 && seeking_return)
4439 state->state = 2;
4440 succeed = TRUE;
4442 else if (GET_CODE (scanbody) == PARALLEL)
4444 if (get_attr_cond (this_insn) != COND_CANUSE)
4445 fail = TRUE;
4447 break;
4449 case INSN:
4450 scanbody = PATTERN (this_insn);
4452 /* We can only do this with insns that can use the condition
4453 codes (and don't set them). */
4454 if (GET_CODE (scanbody) == SET
4455 || GET_CODE (scanbody) == PARALLEL)
4457 if (get_attr_cond (this_insn) != COND_CANUSE)
4458 fail = TRUE;
4460 /* We can't handle other insns like sequences. */
4461 else
4462 fail = TRUE;
4463 break;
4465 default:
4466 break;
4470 if (succeed)
4472 if ((!seeking_return) && (state->state == 1 || reverse))
4473 state->target_label = CODE_LABEL_NUMBER (label);
4474 else if (seeking_return || state->state == 2)
4476 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
4478 this_insn = next_nonnote_insn (this_insn);
4480 gcc_assert (!this_insn ||
4481 (GET_CODE (this_insn) != BARRIER
4482 && GET_CODE (this_insn) != CODE_LABEL));
4484 if (!this_insn)
4486 /* Oh dear! we ran off the end, give up. */
4487 extract_insn_cached (insn);
4488 state->state = 0;
4489 state->target_insn = NULL;
4490 return;
4492 state->target_insn = this_insn;
4494 else
4495 gcc_unreachable ();
4497 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4498 what it was. */
4499 if (!reverse)
4501 state->cond = XEXP (SET_SRC (body), 0);
4502 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
4505 if (reverse || then_not_else)
4506 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
4509 /* Restore recog_operand. Getting the attributes of other insns can
4510 destroy this array, but final.c assumes that it remains intact
4511 across this call; since the insn has been recognized already we
4512 call insn_extract direct. */
4513 extract_insn_cached (insn);
4517 /* Record that we are currently outputting label NUM with prefix PREFIX.
4518 It it's the label we're looking for, reset the ccfsm machinery.
4520 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4522 static void
4523 arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
4525 if (state->state == 3 && state->target_label == num
4526 && !strcmp (prefix, "L"))
4528 state->state = 0;
4529 state->target_insn = NULL;
4533 /* We are considering a conditional branch with the condition COND.
4534 Check if we want to conditionalize a delay slot insn, and if so modify
4535 the ccfsm state accordingly.
4536 REVERSE says branch will branch when the condition is false. */
4537 void
4538 arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
4539 struct arc_ccfsm *state)
4541 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
4542 if (!state)
4543 state = &arc_ccfsm_current;
4545 gcc_assert (state->state == 0);
4546 if (seq_insn != jump)
4548 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
4550 if (!as_a<rtx_insn *> (insn)->deleted ()
4551 && INSN_ANNULLED_BRANCH_P (jump)
4552 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
4554 state->cond = cond;
4555 state->cc = get_arc_condition_code (cond);
4556 if (!reverse)
4557 arc_ccfsm_current.cc
4558 = ARC_INVERSE_CONDITION_CODE (state->cc);
4559 rtx pat = PATTERN (insn);
4560 if (GET_CODE (pat) == COND_EXEC)
4561 gcc_assert ((INSN_FROM_TARGET_P (insn)
4562 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
4563 == get_arc_condition_code (XEXP (pat, 0)));
4564 else
4565 state->state = 5;
4570 /* Update *STATE as we would when we emit INSN. */
4572 static void
4573 arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
4575 enum attr_type type;
4577 if (LABEL_P (insn))
4578 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
4579 else if (JUMP_P (insn)
4580 && GET_CODE (PATTERN (insn)) != ADDR_VEC
4581 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
4582 && ((type = get_attr_type (insn)) == TYPE_BRANCH
4583 || ((type == TYPE_UNCOND_BRANCH
4584 || type == TYPE_RETURN)
4585 && ARC_CCFSM_BRANCH_DELETED_P (state))))
4587 if (ARC_CCFSM_BRANCH_DELETED_P (state))
4588 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
4589 else
4591 rtx src = SET_SRC (PATTERN (insn));
4592 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
4593 insn, state);
4596 else if (arc_ccfsm_current.state == 5)
4597 arc_ccfsm_current.state = 0;
4600 /* Return true if the current insn, which is a conditional branch, is to be
4601 deleted. */
4603 bool
4604 arc_ccfsm_branch_deleted_p (void)
4606 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
4609 /* Record a branch isn't output because subsequent insns can be
4610 conditionalized. */
4612 void
4613 arc_ccfsm_record_branch_deleted (void)
4615 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
4618 /* During insn output, indicate if the current insn is predicated. */
4620 bool
4621 arc_ccfsm_cond_exec_p (void)
4623 return (cfun->machine->prescan_initialized
4624 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
4627 /* Like next_active_insn, but return NULL if we find an ADDR_(DIFF_)VEC,
4628 and look inside SEQUENCEs. */
4630 static rtx_insn *
4631 arc_next_active_insn (rtx_insn *insn, struct arc_ccfsm *statep)
4633 rtx pat;
4637 if (statep)
4638 arc_ccfsm_post_advance (insn, statep);
4639 insn = NEXT_INSN (insn);
4640 if (!insn || BARRIER_P (insn))
4641 return NULL;
4642 if (statep)
4643 arc_ccfsm_advance (insn, statep);
4645 while (NOTE_P (insn)
4646 || (cfun->machine->arc_reorg_started
4647 && LABEL_P (insn) && !label_to_alignment (insn))
4648 || (NONJUMP_INSN_P (insn)
4649 && (GET_CODE (PATTERN (insn)) == USE
4650 || GET_CODE (PATTERN (insn)) == CLOBBER)));
4651 if (!LABEL_P (insn))
4653 gcc_assert (INSN_P (insn));
4654 pat = PATTERN (insn);
4655 if (GET_CODE (pat) == ADDR_VEC || GET_CODE (pat) == ADDR_DIFF_VEC)
4656 return NULL;
4657 if (GET_CODE (pat) == SEQUENCE)
4658 return as_a <rtx_insn *> (XVECEXP (pat, 0, 0));
4660 return insn;
4663 /* When deciding if an insn should be output short, we want to know something
4664 about the following insns:
4665 - if another insn follows which we know we can output as a short insn
4666 before an alignment-sensitive point, we can output this insn short:
4667 the decision about the eventual alignment can be postponed.
4668 - if a to-be-aligned label comes next, we should output this insn such
4669 as to get / preserve 4-byte alignment.
4670 - if a likely branch without delay slot insn, or a call with an immediately
4671 following short insn comes next, we should out output this insn such as to
4672 get / preserve 2 mod 4 unalignment.
4673 - do the same for a not completely unlikely branch with a short insn
4674 following before any other branch / label.
4675 - in order to decide if we are actually looking at a branch, we need to
4676 call arc_ccfsm_advance.
4677 - in order to decide if we are looking at a short insn, we should know
4678 if it is conditionalized. To a first order of approximation this is
4679 the case if the state from arc_ccfsm_advance from before this insn
4680 indicates the insn is conditionalized. However, a further refinement
4681 could be to not conditionalize an insn if the destination register(s)
4682 is/are dead in the non-executed case. */
4683 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4684 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4685 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4688 arc_verify_short (rtx_insn *insn, int, int check_attr)
4690 enum attr_iscompact iscompact;
4691 struct machine_function *machine;
4693 if (check_attr > 0)
4695 iscompact = get_attr_iscompact (insn);
4696 if (iscompact == ISCOMPACT_FALSE)
4697 return 0;
4699 machine = cfun->machine;
4701 if (machine->force_short_suffix >= 0)
4702 return machine->force_short_suffix;
4704 return (get_attr_length (insn) & 2) != 0;
4707 /* When outputting an instruction (alternative) that can potentially be short,
4708 output the short suffix if the insn is in fact short, and update
4709 cfun->machine->unalign accordingly. */
4711 static void
4712 output_short_suffix (FILE *file)
4714 rtx_insn *insn = current_output_insn;
4716 if (arc_verify_short (insn, cfun->machine->unalign, 1))
4718 fprintf (file, "_s");
4719 cfun->machine->unalign ^= 2;
4721 /* Restore recog_operand. */
4722 extract_insn_cached (insn);
4725 /* Implement FINAL_PRESCAN_INSN. */
4727 void
4728 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
4729 int noperands ATTRIBUTE_UNUSED)
4731 if (TARGET_DUMPISIZE)
4732 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
4734 /* Output a nop if necessary to prevent a hazard.
4735 Don't do this for delay slots: inserting a nop would
4736 alter semantics, and the only time we would find a hazard is for a
4737 call function result - and in that case, the hazard is spurious to
4738 start with. */
4739 if (PREV_INSN (insn)
4740 && PREV_INSN (NEXT_INSN (insn)) == insn
4741 && arc_hazard (prev_real_insn (insn), insn))
4743 current_output_insn =
4744 emit_insn_before (gen_nop (), NEXT_INSN (PREV_INSN (insn)));
4745 final_scan_insn (current_output_insn, asm_out_file, optimize, 1, NULL);
4746 current_output_insn = insn;
4748 /* Restore extraction data which might have been clobbered by arc_hazard. */
4749 extract_constrain_insn_cached (insn);
4751 if (!cfun->machine->prescan_initialized)
4753 /* Clear lingering state from branch shortening. */
4754 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
4755 cfun->machine->prescan_initialized = 1;
4757 arc_ccfsm_advance (insn, &arc_ccfsm_current);
4759 cfun->machine->size_reason = 0;
4762 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4763 Frame pointer elimination is automatically handled.
4765 All eliminations are permissible. If we need a frame
4766 pointer, we must eliminate ARG_POINTER_REGNUM into
4767 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4769 static bool
4770 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
4772 return ((to == FRAME_POINTER_REGNUM) || !arc_frame_pointer_needed ());
4775 /* Define the offset between two registers, one to be eliminated, and
4776 the other its replacement, at the start of a routine. */
4779 arc_initial_elimination_offset (int from, int to)
4781 if (! cfun->machine->frame_info.initialized)
4782 arc_compute_frame_size (get_frame_size ());
4784 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
4786 return (cfun->machine->frame_info.extra_size
4787 + cfun->machine->frame_info.reg_size);
4790 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
4792 return (cfun->machine->frame_info.total_size
4793 - cfun->machine->frame_info.pretend_size);
4796 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
4798 return (cfun->machine->frame_info.total_size
4799 - (cfun->machine->frame_info.pretend_size
4800 + cfun->machine->frame_info.extra_size
4801 + cfun->machine->frame_info.reg_size));
4804 gcc_unreachable ();
4807 static bool
4808 arc_frame_pointer_required (void)
4810 return cfun->calls_alloca;
4814 /* Return the destination address of a branch. */
4817 branch_dest (rtx branch)
4819 rtx pat = PATTERN (branch);
4820 rtx dest = (GET_CODE (pat) == PARALLEL
4821 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
4822 int dest_uid;
4824 if (GET_CODE (dest) == IF_THEN_ELSE)
4825 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
4827 dest = XEXP (dest, 0);
4828 dest_uid = INSN_UID (dest);
4830 return INSN_ADDRESSES (dest_uid);
4834 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
4836 static void
4837 arc_encode_section_info (tree decl, rtx rtl, int first)
4839 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
4840 This clears machine specific flags, so has to come first. */
4841 default_encode_section_info (decl, rtl, first);
4843 /* Check if it is a function, and whether it has the
4844 [long/medium/short]_call attribute specified. */
4845 if (TREE_CODE (decl) == FUNCTION_DECL)
4847 rtx symbol = XEXP (rtl, 0);
4848 int flags = SYMBOL_REF_FLAGS (symbol);
4850 tree attr = (TREE_TYPE (decl) != error_mark_node
4851 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
4852 tree long_call_attr = lookup_attribute ("long_call", attr);
4853 tree medium_call_attr = lookup_attribute ("medium_call", attr);
4854 tree short_call_attr = lookup_attribute ("short_call", attr);
4856 if (long_call_attr != NULL_TREE)
4857 flags |= SYMBOL_FLAG_LONG_CALL;
4858 else if (medium_call_attr != NULL_TREE)
4859 flags |= SYMBOL_FLAG_MEDIUM_CALL;
4860 else if (short_call_attr != NULL_TREE)
4861 flags |= SYMBOL_FLAG_SHORT_CALL;
4863 SYMBOL_REF_FLAGS (symbol) = flags;
4865 else if (TREE_CODE (decl) == VAR_DECL)
4867 rtx symbol = XEXP (rtl, 0);
4869 tree attr = (TREE_TYPE (decl) != error_mark_node
4870 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
4872 tree sec_attr = lookup_attribute ("section", attr);
4873 if (sec_attr)
4875 const char *sec_name
4876 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
4877 if (strcmp (sec_name, ".cmem") == 0
4878 || strcmp (sec_name, ".cmem_shared") == 0
4879 || strcmp (sec_name, ".cmem_private") == 0)
4880 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
4885 /* This is how to output a definition of an internal numbered label where
4886 PREFIX is the class of label and NUM is the number within the class. */
4888 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
4890 if (cfun)
4891 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
4892 default_internal_label (stream, prefix, labelno);
4895 /* Set the cpu type and print out other fancy things,
4896 at the top of the file. */
4898 static void arc_file_start (void)
4900 default_file_start ();
4901 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
4904 /* Cost functions. */
4906 /* Compute a (partial) cost for rtx X. Return true if the complete
4907 cost has been computed, and false if subexpressions should be
4908 scanned. In either case, *TOTAL contains the cost result. */
4910 static bool
4911 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
4912 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
4914 int code = GET_CODE (x);
4916 switch (code)
4918 /* Small integers are as cheap as registers. */
4919 case CONST_INT:
4921 bool nolimm = false; /* Can we do without long immediate? */
4922 bool fast = false; /* Is the result available immediately? */
4923 bool condexec = false; /* Does this allow conditiobnal execution? */
4924 bool compact = false; /* Is a 16 bit opcode available? */
4925 /* CONDEXEC also implies that we can have an unconditional
4926 3-address operation. */
4928 nolimm = compact = condexec = false;
4929 if (UNSIGNED_INT6 (INTVAL (x)))
4930 nolimm = condexec = compact = true;
4931 else
4933 if (SMALL_INT (INTVAL (x)))
4934 nolimm = fast = true;
4935 switch (outer_code)
4937 case AND: /* bclr, bmsk, ext[bw] */
4938 if (satisfies_constraint_Ccp (x) /* bclr */
4939 || satisfies_constraint_C1p (x) /* bmsk */)
4940 nolimm = fast = condexec = compact = true;
4941 break;
4942 case IOR: /* bset */
4943 if (satisfies_constraint_C0p (x)) /* bset */
4944 nolimm = fast = condexec = compact = true;
4945 break;
4946 case XOR:
4947 if (satisfies_constraint_C0p (x)) /* bxor */
4948 nolimm = fast = condexec = true;
4949 break;
4950 case SET:
4951 if (satisfies_constraint_Crr (x)) /* ror b,u6 */
4952 nolimm = true;
4953 default:
4954 break;
4957 /* FIXME: Add target options to attach a small cost if
4958 condexec / compact is not true. */
4959 if (nolimm)
4961 *total = 0;
4962 return true;
4965 /* FALLTHRU */
4967 /* 4 byte values can be fetched as immediate constants -
4968 let's give that the cost of an extra insn. */
4969 case CONST:
4970 case LABEL_REF:
4971 case SYMBOL_REF:
4972 *total = COSTS_N_INSNS (1);
4973 return true;
4975 case CONST_DOUBLE:
4977 rtx first, second;
4979 if (TARGET_DPFP)
4981 *total = COSTS_N_INSNS (1);
4982 return true;
4984 split_double (x, &first, &second);
4985 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
4986 + !SMALL_INT (INTVAL (second)));
4987 return true;
4990 /* Encourage synth_mult to find a synthetic multiply when reasonable.
4991 If we need more than 12 insns to do a multiply, then go out-of-line,
4992 since the call overhead will be < 10% of the cost of the multiply. */
4993 case ASHIFT:
4994 case ASHIFTRT:
4995 case LSHIFTRT:
4996 if (TARGET_BARREL_SHIFTER)
4998 /* If we want to shift a constant, we need a LIMM. */
4999 /* ??? when the optimizers want to know if a constant should be
5000 hoisted, they ask for the cost of the constant. OUTER_CODE is
5001 insufficient context for shifts since we don't know which operand
5002 we are looking at. */
5003 if (CONSTANT_P (XEXP (x, 0)))
5005 *total += (COSTS_N_INSNS (2)
5006 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
5007 0, speed));
5008 return true;
5010 *total = COSTS_N_INSNS (1);
5012 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5013 *total = COSTS_N_INSNS (16);
5014 else
5016 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
5017 /* ??? want_to_gcse_p can throw negative shift counts at us,
5018 and then panics when it gets a negative cost as result.
5019 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5020 if (*total < 0)
5021 *total = 0;
5023 return false;
5025 case DIV:
5026 case UDIV:
5027 if (speed)
5028 *total = COSTS_N_INSNS(30);
5029 else
5030 *total = COSTS_N_INSNS(1);
5031 return false;
5033 case MULT:
5034 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5035 *total = COSTS_N_INSNS (1);
5036 else if (speed)
5037 *total= arc_multcost;
5038 /* We do not want synth_mult sequences when optimizing
5039 for size. */
5040 else if (TARGET_MUL64_SET || TARGET_ARC700_MPY)
5041 *total = COSTS_N_INSNS (1);
5042 else
5043 *total = COSTS_N_INSNS (2);
5044 return false;
5045 case PLUS:
5046 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5047 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5048 || (GET_CODE (XEXP (x, 0)) == MULT
5049 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5051 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
5052 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
5053 return true;
5055 return false;
5056 case MINUS:
5057 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5058 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5059 || (GET_CODE (XEXP (x, 1)) == MULT
5060 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5062 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
5063 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
5064 return true;
5066 return false;
5067 case COMPARE:
5069 rtx op0 = XEXP (x, 0);
5070 rtx op1 = XEXP (x, 1);
5072 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5073 && XEXP (op0, 1) == const1_rtx)
5075 /* btst / bbit0 / bbit1:
5076 Small integers and registers are free; everything else can
5077 be put in a register. */
5078 mode = GET_MODE (XEXP (op0, 0));
5079 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5080 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5081 return true;
5083 if (GET_CODE (op0) == AND && op1 == const0_rtx
5084 && satisfies_constraint_C1p (XEXP (op0, 1)))
5086 /* bmsk.f */
5087 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5088 return true;
5090 /* add.f */
5091 if (GET_CODE (op1) == NEG)
5093 /* op0 might be constant, the inside of op1 is rather
5094 unlikely to be so. So swapping the operands might lower
5095 the cost. */
5096 mode = GET_MODE (op0);
5097 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5098 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5100 return false;
5102 case EQ: case NE:
5103 if (outer_code == IF_THEN_ELSE
5104 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5105 && XEXP (x, 1) == const0_rtx
5106 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5108 /* btst / bbit0 / bbit1:
5109 Small integers and registers are free; everything else can
5110 be put in a register. */
5111 rtx op0 = XEXP (x, 0);
5113 mode = GET_MODE (XEXP (op0, 0));
5114 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5115 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5116 return true;
5118 /* Fall through. */
5119 /* scc_insn expands into two insns. */
5120 case GTU: case GEU: case LEU:
5121 if (mode == SImode)
5122 *total += COSTS_N_INSNS (1);
5123 return false;
5124 case LTU: /* might use adc. */
5125 if (mode == SImode)
5126 *total += COSTS_N_INSNS (1) - 1;
5127 return false;
5128 default:
5129 return false;
5133 /* Return true if ADDR is a valid pic address.
5134 A valid pic address on arc should look like
5135 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5137 bool
5138 arc_legitimate_pic_addr_p (rtx addr)
5140 if (GET_CODE (addr) != CONST)
5141 return false;
5143 addr = XEXP (addr, 0);
5146 if (GET_CODE (addr) == PLUS)
5148 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
5149 return false;
5150 addr = XEXP (addr, 0);
5153 if (GET_CODE (addr) != UNSPEC
5154 || XVECLEN (addr, 0) != 1)
5155 return false;
5157 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5158 if (XINT (addr, 1) != ARC_UNSPEC_GOT
5159 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
5160 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
5161 && XINT (addr, 1) != UNSPEC_TLS_GD
5162 && XINT (addr, 1) != UNSPEC_TLS_IE)
5163 return false;
5165 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
5166 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
5167 return false;
5169 return true;
5174 /* Return true if OP contains a symbol reference. */
5176 static bool
5177 symbolic_reference_mentioned_p (rtx op)
5179 register const char *fmt;
5180 register int i;
5182 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5183 return true;
5185 fmt = GET_RTX_FORMAT (GET_CODE (op));
5186 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5188 if (fmt[i] == 'E')
5190 register int j;
5192 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5193 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5194 return true;
5197 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5198 return true;
5201 return false;
5204 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5205 If SKIP_LOCAL is true, skip symbols that bind locally.
5206 This is used further down in this file, and, without SKIP_LOCAL,
5207 in the addsi3 / subsi3 expanders when generating PIC code. */
5209 bool
5210 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
5212 register const char *fmt;
5213 register int i;
5215 if (GET_CODE(op) == UNSPEC)
5216 return false;
5218 if (GET_CODE (op) == SYMBOL_REF)
5220 if (SYMBOL_REF_TLS_MODEL (op))
5221 return true;
5222 if (!flag_pic)
5223 return false;
5224 tree decl = SYMBOL_REF_DECL (op);
5225 return !skip_local || !decl || !default_binds_local_p (decl);
5228 fmt = GET_RTX_FORMAT (GET_CODE (op));
5229 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5231 if (fmt[i] == 'E')
5233 register int j;
5235 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5236 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
5237 skip_local))
5238 return true;
5241 else if (fmt[i] == 'e'
5242 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
5243 skip_local))
5244 return true;
5247 return false;
5250 /* Get the thread pointer. */
5252 static rtx
5253 arc_get_tp (void)
5255 /* If arc_tp_regno has been set, we can use that hard register
5256 directly as a base register. */
5257 if (arc_tp_regno != -1)
5258 return gen_rtx_REG (Pmode, arc_tp_regno);
5260 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5261 conflicts with function arguments / results. */
5262 rtx reg = gen_reg_rtx (Pmode);
5263 emit_insn (gen_tls_load_tp_soft ());
5264 emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG));
5265 return reg;
5268 /* Helper to be used by TLS Global dynamic model. */
5270 static rtx
5271 arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
5273 rtx r0 = gen_rtx_REG (Pmode, R0_REG);
5274 rtx call_fusage = NULL_RTX;
5276 start_sequence ();
5278 rtx x = arc_unspec_offset (sym, reloc);
5279 emit_move_insn (r0, x);
5280 use_reg (&call_fusage, r0);
5282 gcc_assert (reloc == UNSPEC_TLS_GD);
5283 rtx call_insn = emit_call_insn (gen_tls_gd_get_addr (sym));
5284 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5285 way that the application should care. */
5286 RTL_PURE_CALL_P (call_insn) = 1;
5287 add_function_usage_to (call_insn, call_fusage);
5289 rtx_insn *insns = get_insns ();
5290 end_sequence ();
5292 rtx dest = gen_reg_rtx (Pmode);
5293 emit_libcall_block (insns, dest, r0, eqv);
5294 return dest;
5297 #define DTPOFF_ZERO_SYM ".tdata"
5299 /* Return a legitimized address for ADDR,
5300 which is a SYMBOL_REF with tls_model MODEL. */
5302 static rtx
5303 arc_legitimize_tls_address (rtx addr, enum tls_model model)
5305 if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC)
5306 model = TLS_MODEL_LOCAL_EXEC;
5308 switch (model)
5310 case TLS_MODEL_LOCAL_DYNAMIC:
5311 rtx base;
5312 tree decl;
5313 const char *base_name;
5314 rtvec v;
5316 decl = SYMBOL_REF_DECL (addr);
5317 base_name = DTPOFF_ZERO_SYM;
5318 if (decl && bss_initializer_p (decl))
5319 base_name = ".tbss";
5321 base = gen_rtx_SYMBOL_REF (Pmode, base_name);
5322 if (strcmp (base_name, DTPOFF_ZERO_SYM) == 0)
5324 if (!flag_pic)
5325 goto local_exec;
5326 v = gen_rtvec (1, addr);
5328 else
5329 v = gen_rtvec (2, addr, base);
5330 addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_TLS_OFF);
5331 addr = gen_rtx_CONST (Pmode, addr);
5332 base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
5333 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
5335 case TLS_MODEL_GLOBAL_DYNAMIC:
5336 return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
5338 case TLS_MODEL_INITIAL_EXEC:
5339 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
5340 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
5341 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5343 case TLS_MODEL_LOCAL_EXEC:
5344 local_exec:
5345 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
5346 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5347 default:
5348 gcc_unreachable ();
5352 /* Legitimize a pic address reference in ORIG.
5353 The return value is the legitimated address.
5354 If OLDX is non-zero, it is the target to assign the address to first. */
5356 static rtx
5357 arc_legitimize_pic_address (rtx orig, rtx oldx)
5359 rtx addr = orig;
5360 rtx pat = orig;
5361 rtx base;
5363 if (oldx == orig)
5364 oldx = NULL;
5366 if (GET_CODE (addr) == LABEL_REF)
5367 ; /* Do nothing. */
5368 else if (GET_CODE (addr) == SYMBOL_REF)
5370 enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
5371 if (model != 0)
5372 return arc_legitimize_tls_address (addr, model);
5373 else if (!flag_pic)
5374 return orig;
5375 else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
5376 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
5378 /* This symbol must be referenced via a load from the Global
5379 Offset Table (@GOTPC). */
5380 pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
5381 pat = gen_const_mem (Pmode, pat);
5383 if (oldx == NULL)
5384 oldx = gen_reg_rtx (Pmode);
5386 emit_move_insn (oldx, pat);
5387 pat = oldx;
5389 else
5391 if (GET_CODE (addr) == CONST)
5393 addr = XEXP (addr, 0);
5394 if (GET_CODE (addr) == UNSPEC)
5396 /* Check that the unspec is one of the ones we generate? */
5397 return orig;
5399 /* fwprop is placing in the REG_EQUIV notes constant pic
5400 unspecs expressions. Then, loop may use these notes for
5401 optimizations resulting in complex patterns that are not
5402 supported by the current implementation. The following
5403 two if-cases are simplifying the complex patters to
5404 simpler ones. */
5405 else if (GET_CODE (addr) == MINUS)
5407 rtx op0 = XEXP (addr, 0);
5408 rtx op1 = XEXP (addr, 1);
5409 gcc_assert (oldx);
5410 gcc_assert (GET_CODE (op1) == UNSPEC);
5412 emit_move_insn (oldx,
5413 gen_rtx_CONST (SImode,
5414 arc_legitimize_pic_address (op1,
5415 NULL_RTX)));
5416 emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
5417 return oldx;
5420 else if (GET_CODE (addr) != PLUS)
5422 rtx tmp = XEXP (addr, 0);
5423 enum rtx_code code = GET_CODE (addr);
5425 /* It only works for UNARY operations. */
5426 gcc_assert (UNARY_P (addr));
5427 gcc_assert (GET_CODE (tmp) == UNSPEC);
5428 gcc_assert (oldx);
5430 emit_move_insn
5431 (oldx,
5432 gen_rtx_CONST (SImode,
5433 arc_legitimize_pic_address (tmp,
5434 NULL_RTX)));
5436 emit_insn (gen_rtx_SET (oldx,
5437 gen_rtx_fmt_ee (code, SImode,
5438 oldx, const0_rtx)));
5440 return oldx;
5442 else
5444 gcc_assert (GET_CODE (addr) == PLUS);
5445 if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
5446 return orig;
5450 if (GET_CODE (addr) == PLUS)
5452 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
5454 base = arc_legitimize_pic_address (op0, oldx);
5455 pat = arc_legitimize_pic_address (op1,
5456 base == oldx ? NULL_RTX : oldx);
5458 if (base == op0 && pat == op1)
5459 return orig;
5461 if (GET_CODE (pat) == CONST_INT)
5462 pat = plus_constant (Pmode, base, INTVAL (pat));
5463 else
5465 if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1)))
5467 base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0));
5468 pat = XEXP (pat, 1);
5470 pat = gen_rtx_PLUS (Pmode, base, pat);
5475 return pat;
5478 /* Output address constant X to FILE, taking PIC into account. */
5480 static void
5481 arc_output_pic_addr_const (FILE * file, rtx x, int code)
5483 char buf[256];
5485 restart:
5486 switch (GET_CODE (x))
5488 case PC:
5489 if (flag_pic)
5490 putc ('.', file);
5491 else
5492 gcc_unreachable ();
5493 break;
5495 case SYMBOL_REF:
5496 output_addr_const (file, x);
5498 /* Local functions do not get references through the PLT. */
5499 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
5500 fputs ("@plt", file);
5501 break;
5503 case LABEL_REF:
5504 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
5505 assemble_name (file, buf);
5506 break;
5508 case CODE_LABEL:
5509 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
5510 assemble_name (file, buf);
5511 break;
5513 case CONST_INT:
5514 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
5515 break;
5517 case CONST:
5518 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5519 break;
5521 case CONST_DOUBLE:
5522 if (GET_MODE (x) == VOIDmode)
5524 /* We can use %d if the number is one word and positive. */
5525 if (CONST_DOUBLE_HIGH (x))
5526 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
5527 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
5528 else if (CONST_DOUBLE_LOW (x) < 0)
5529 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
5530 else
5531 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
5533 else
5534 /* We can't handle floating point constants;
5535 PRINT_OPERAND must handle them. */
5536 output_operand_lossage ("floating constant misused");
5537 break;
5539 case PLUS:
5540 /* FIXME: Not needed here. */
5541 /* Some assemblers need integer constants to appear last (eg masm). */
5542 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
5544 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5545 fprintf (file, "+");
5546 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5548 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5550 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5551 if (INTVAL (XEXP (x, 1)) >= 0)
5552 fprintf (file, "+");
5553 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5555 else
5556 gcc_unreachable();
5557 break;
5559 case MINUS:
5560 /* Avoid outputting things like x-x or x+5-x,
5561 since some assemblers can't handle that. */
5562 x = simplify_subtraction (x);
5563 if (GET_CODE (x) != MINUS)
5564 goto restart;
5566 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5567 fprintf (file, "-");
5568 if (GET_CODE (XEXP (x, 1)) == CONST_INT
5569 && INTVAL (XEXP (x, 1)) < 0)
5571 fprintf (file, "(");
5572 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5573 fprintf (file, ")");
5575 else
5576 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5577 break;
5579 case ZERO_EXTEND:
5580 case SIGN_EXTEND:
5581 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5582 break;
5585 case UNSPEC:
5586 const char *suffix;
5587 bool pcrel; pcrel = false;
5588 rtx base; base = NULL;
5589 gcc_assert (XVECLEN (x, 0) >= 1);
5590 switch (XINT (x, 1))
5592 case ARC_UNSPEC_GOT:
5593 suffix = "@gotpc", pcrel = true;
5594 break;
5595 case ARC_UNSPEC_GOTOFF:
5596 suffix = "@gotoff";
5597 break;
5598 case ARC_UNSPEC_GOTOFFPC:
5599 suffix = "@pcl", pcrel = true;
5600 break;
5601 case ARC_UNSPEC_PLT:
5602 suffix = "@plt";
5603 break;
5604 case UNSPEC_TLS_GD:
5605 suffix = "@tlsgd", pcrel = true;
5606 break;
5607 case UNSPEC_TLS_IE:
5608 suffix = "@tlsie", pcrel = true;
5609 break;
5610 case UNSPEC_TLS_OFF:
5611 if (XVECLEN (x, 0) == 2)
5612 base = XVECEXP (x, 0, 1);
5613 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5614 || (!flag_pic && !base))
5615 suffix = "@tpoff";
5616 else
5617 suffix = "@dtpoff";
5618 break;
5619 default:
5620 suffix = "@invalid";
5621 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
5622 break;
5624 if (pcrel)
5625 fputs ("pcl,", file);
5626 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
5627 fputs (suffix, file);
5628 if (base)
5629 arc_output_pic_addr_const (file, base, code);
5630 break;
5632 default:
5633 output_operand_lossage ("invalid expression as operand");
5637 #define SYMBOLIC_CONST(X) \
5638 (GET_CODE (X) == SYMBOL_REF \
5639 || GET_CODE (X) == LABEL_REF \
5640 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5642 /* Emit insns to move operands[1] into operands[0]. */
5644 static void
5645 prepare_pic_move (rtx *operands, machine_mode)
5647 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])
5648 && flag_pic)
5649 operands[1] = force_reg (Pmode, operands[1]);
5650 else
5652 rtx temp = (reload_in_progress ? operands[0]
5653 : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX);
5654 operands[1] = arc_legitimize_pic_address (operands[1], temp);
5659 /* The function returning the number of words, at the beginning of an
5660 argument, must be put in registers. The returned value must be
5661 zero for arguments that are passed entirely in registers or that
5662 are entirely pushed on the stack.
5664 On some machines, certain arguments must be passed partially in
5665 registers and partially in memory. On these machines, typically
5666 the first N words of arguments are passed in registers, and the
5667 rest on the stack. If a multi-word argument (a `double' or a
5668 structure) crosses that boundary, its first few words must be
5669 passed in registers and the rest must be pushed. This function
5670 tells the compiler when this occurs, and how many of the words
5671 should go in registers.
5673 `FUNCTION_ARG' for these arguments should return the first register
5674 to be used by the caller for this argument; likewise
5675 `FUNCTION_INCOMING_ARG', for the called function.
5677 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5679 /* If REGNO is the least arg reg available then what is the total number of arg
5680 regs available. */
5681 #define GPR_REST_ARG_REGS(REGNO) \
5682 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5684 /* Since arc parm regs are contiguous. */
5685 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5687 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5689 static int
5690 arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
5691 tree type, bool named ATTRIBUTE_UNUSED)
5693 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5694 int bytes = (mode == BLKmode
5695 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5696 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5697 int arg_num = *cum;
5698 int ret;
5700 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5701 ret = GPR_REST_ARG_REGS (arg_num);
5703 /* ICEd at function.c:2361, and ret is copied to data->partial */
5704 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
5706 return ret;
5709 /* This function is used to control a function argument is passed in a
5710 register, and which register.
5712 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5713 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5714 all of the previous arguments so far passed in registers; MODE, the
5715 machine mode of the argument; TYPE, the data type of the argument
5716 as a tree node or 0 if that is not known (which happens for C
5717 support library functions); and NAMED, which is 1 for an ordinary
5718 argument and 0 for nameless arguments that correspond to `...' in
5719 the called function's prototype.
5721 The returned value should either be a `reg' RTX for the hard
5722 register in which to pass the argument, or zero to pass the
5723 argument on the stack.
5725 For machines like the Vax and 68000, where normally all arguments
5726 are pushed, zero suffices as a definition.
5728 The usual way to make the ANSI library `stdarg.h' work on a machine
5729 where some arguments are usually passed in registers, is to cause
5730 nameless arguments to be passed on the stack instead. This is done
5731 by making the function return 0 whenever NAMED is 0.
5733 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5734 definition of this function to determine if this argument is of a
5735 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5736 is not defined and the function returns non-zero for such an
5737 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5738 defined, the argument will be computed in the stack and then loaded
5739 into a register.
5741 The function is used to implement macro FUNCTION_ARG. */
5742 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5743 and the rest are pushed. */
5745 static rtx
5746 arc_function_arg (cumulative_args_t cum_v,
5747 machine_mode mode,
5748 const_tree type ATTRIBUTE_UNUSED,
5749 bool named ATTRIBUTE_UNUSED)
5751 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5752 int arg_num = *cum;
5753 rtx ret;
5754 const char *debstr ATTRIBUTE_UNUSED;
5756 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5757 /* Return a marker for use in the call instruction. */
5758 if (mode == VOIDmode)
5760 ret = const0_rtx;
5761 debstr = "<0>";
5763 else if (GPR_REST_ARG_REGS (arg_num) > 0)
5765 ret = gen_rtx_REG (mode, arg_num);
5766 debstr = reg_names [arg_num];
5768 else
5770 ret = NULL_RTX;
5771 debstr = "memory";
5773 return ret;
5776 /* The function to update the summarizer variable *CUM to advance past
5777 an argument in the argument list. The values MODE, TYPE and NAMED
5778 describe that argument. Once this is done, the variable *CUM is
5779 suitable for analyzing the *following* argument with
5780 `FUNCTION_ARG', etc.
5782 This function need not do anything if the argument in question was
5783 passed on the stack. The compiler knows how to track the amount of
5784 stack space used for arguments without any special help.
5786 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
5787 /* For the ARC: the cum set here is passed on to function_arg where we
5788 look at its value and say which reg to use. Strategy: advance the
5789 regnumber here till we run out of arg regs, then set *cum to last
5790 reg. In function_arg, since *cum > last arg reg we would return 0
5791 and thus the arg will end up on the stack. For straddling args of
5792 course function_arg_partial_nregs will come into play. */
5794 static void
5795 arc_function_arg_advance (cumulative_args_t cum_v,
5796 machine_mode mode,
5797 const_tree type,
5798 bool named ATTRIBUTE_UNUSED)
5800 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5801 int bytes = (mode == BLKmode
5802 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5803 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5804 int i;
5806 if (words)
5807 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
5808 for (i = 0; i < words; i++)
5809 *cum = ARC_NEXT_ARG_REG (*cum);
5813 /* Define how to find the value returned by a function.
5814 VALTYPE is the data type of the value (as a tree).
5815 If the precise function being called is known, FN_DECL_OR_TYPE is its
5816 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
5818 static rtx
5819 arc_function_value (const_tree valtype,
5820 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
5821 bool outgoing ATTRIBUTE_UNUSED)
5823 machine_mode mode = TYPE_MODE (valtype);
5824 int unsignedp ATTRIBUTE_UNUSED;
5826 unsignedp = TYPE_UNSIGNED (valtype);
5827 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
5828 PROMOTE_MODE (mode, unsignedp, valtype);
5829 return gen_rtx_REG (mode, 0);
5832 /* Returns the return address that is used by builtin_return_address. */
5835 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
5837 if (count != 0)
5838 return const0_rtx;
5840 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
5843 /* Determine if a given RTX is a valid constant. We already know this
5844 satisfies CONSTANT_P. */
5846 bool
5847 arc_legitimate_constant_p (machine_mode mode, rtx x)
5849 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_TLS_MODEL (x))
5850 return false;
5852 if (!flag_pic && mode != Pmode)
5853 return true;
5855 switch (GET_CODE (x))
5857 case CONST:
5858 if (flag_pic)
5860 if (arc_legitimate_pic_addr_p (x))
5861 return true;
5863 return arc_legitimate_constant_p (mode, XEXP (x, 0));
5865 case SYMBOL_REF:
5866 if (SYMBOL_REF_TLS_MODEL (x))
5867 return false;
5868 /* Fall through. */
5869 case LABEL_REF:
5870 if (flag_pic)
5871 return false;
5872 /* Fall through. */
5873 case CONST_INT:
5874 case CONST_DOUBLE:
5875 return true;
5877 case NEG:
5878 return arc_legitimate_constant_p (mode, XEXP (x, 0));
5880 case PLUS:
5881 case MINUS:
5883 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
5884 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
5886 return (t1 && t2);
5889 case CONST_VECTOR:
5890 switch (mode)
5892 case E_V2HImode:
5893 return TARGET_PLUS_DMPY;
5894 case E_V2SImode:
5895 case E_V4HImode:
5896 return TARGET_PLUS_QMACW;
5897 default:
5898 return false;
5901 case UNSPEC:
5902 switch (XINT (x, 1))
5904 case UNSPEC_TLS_GD:
5905 case UNSPEC_TLS_OFF:
5906 case UNSPEC_TLS_IE:
5907 return true;
5908 default:
5909 /* Any other unspec ending here are pic related, hence the above
5910 constant pic address checking returned false. */
5911 return false;
5913 /* Fall through. */
5915 default:
5916 fatal_insn ("unrecognized supposed constant", x);
5919 gcc_unreachable ();
5922 static bool
5923 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
5925 if (RTX_OK_FOR_BASE_P (x, strict))
5926 return true;
5927 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
5928 return true;
5929 if (legitimate_scaled_address_p (mode, x, strict))
5930 return true;
5931 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
5932 return true;
5933 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
5934 return true;
5936 /* When we compile for size avoid const (@sym + offset)
5937 addresses. */
5938 if (!flag_pic && optimize_size && !reload_completed
5939 && (GET_CODE (x) == CONST)
5940 && (GET_CODE (XEXP (x, 0)) == PLUS)
5941 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
5942 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
5943 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
5945 rtx addend = XEXP (XEXP (x, 0), 1);
5946 gcc_assert (CONST_INT_P (addend));
5947 HOST_WIDE_INT offset = INTVAL (addend);
5949 /* Allow addresses having a large offset to pass. Anyhow they
5950 will end in a limm. */
5951 return !(offset > -1024 && offset < 1020);
5954 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
5956 return arc_legitimate_constant_p (mode, x);
5958 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
5959 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
5960 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
5961 return true;
5962 /* We're restricted here by the `st' insn. */
5963 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
5964 && GET_CODE (XEXP ((x), 1)) == PLUS
5965 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
5966 && legitimate_offset_address_p (QImode, XEXP (x, 1),
5967 TARGET_AUTO_MODIFY_REG, strict))
5968 return true;
5969 return false;
5972 /* Return true iff ADDR (a legitimate address expression)
5973 has an effect that depends on the machine mode it is used for. */
5975 static bool
5976 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
5978 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
5979 which is valid for loads and stores, or a limm offset, which is valid for
5980 loads. Scaled indices are scaled by the access mode. */
5981 if (GET_CODE (addr) == PLUS
5982 && GET_CODE (XEXP ((addr), 0)) == MULT)
5983 return true;
5984 return false;
5987 /* Determine if it's legal to put X into the constant pool. */
5989 static bool
5990 arc_cannot_force_const_mem (machine_mode mode, rtx x)
5992 return !arc_legitimate_constant_p (mode, x);
5995 /* IDs for all the ARC builtins. */
5997 enum arc_builtin_id
5999 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6000 ARC_BUILTIN_ ## NAME,
6001 #include "builtins.def"
6002 #undef DEF_BUILTIN
6004 ARC_BUILTIN_COUNT
6007 struct GTY(()) arc_builtin_description
6009 enum insn_code icode;
6010 int n_args;
6011 tree fndecl;
6014 static GTY(()) struct arc_builtin_description
6015 arc_bdesc[ARC_BUILTIN_COUNT] =
6017 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6018 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6019 #include "builtins.def"
6020 #undef DEF_BUILTIN
6023 /* Transform UP into lowercase and write the result to LO.
6024 You must provide enough space for LO. Return LO. */
6026 static char*
6027 arc_tolower (char *lo, const char *up)
6029 char *lo0 = lo;
6031 for (; *up; up++, lo++)
6032 *lo = TOLOWER (*up);
6034 *lo = '\0';
6036 return lo0;
6039 /* Implement `TARGET_BUILTIN_DECL'. */
6041 static tree
6042 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6044 if (id < ARC_BUILTIN_COUNT)
6045 return arc_bdesc[id].fndecl;
6047 return error_mark_node;
6050 static void
6051 arc_init_builtins (void)
6053 tree V4HI_type_node;
6054 tree V2SI_type_node;
6055 tree V2HI_type_node;
6057 /* Vector types based on HS SIMD elements. */
6058 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6059 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6060 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6062 tree pcvoid_type_node
6063 = build_pointer_type (build_qualified_type (void_type_node,
6064 TYPE_QUAL_CONST));
6065 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6066 V8HImode);
6068 tree void_ftype_void
6069 = build_function_type_list (void_type_node, NULL_TREE);
6070 tree int_ftype_int
6071 = build_function_type_list (integer_type_node, integer_type_node,
6072 NULL_TREE);
6073 tree int_ftype_pcvoid_int
6074 = build_function_type_list (integer_type_node, pcvoid_type_node,
6075 integer_type_node, NULL_TREE);
6076 tree void_ftype_usint_usint
6077 = build_function_type_list (void_type_node, long_unsigned_type_node,
6078 long_unsigned_type_node, NULL_TREE);
6079 tree int_ftype_int_int
6080 = build_function_type_list (integer_type_node, integer_type_node,
6081 integer_type_node, NULL_TREE);
6082 tree usint_ftype_usint
6083 = build_function_type_list (long_unsigned_type_node,
6084 long_unsigned_type_node, NULL_TREE);
6085 tree void_ftype_usint
6086 = build_function_type_list (void_type_node, long_unsigned_type_node,
6087 NULL_TREE);
6088 tree int_ftype_void
6089 = build_function_type_list (integer_type_node, void_type_node,
6090 NULL_TREE);
6091 tree void_ftype_int
6092 = build_function_type_list (void_type_node, integer_type_node,
6093 NULL_TREE);
6094 tree int_ftype_short
6095 = build_function_type_list (integer_type_node, short_integer_type_node,
6096 NULL_TREE);
6098 /* Old ARC SIMD types. */
6099 tree v8hi_ftype_v8hi_v8hi
6100 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6101 V8HI_type_node, NULL_TREE);
6102 tree v8hi_ftype_v8hi_int
6103 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6104 integer_type_node, NULL_TREE);
6105 tree v8hi_ftype_v8hi_int_int
6106 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6107 integer_type_node, integer_type_node,
6108 NULL_TREE);
6109 tree void_ftype_v8hi_int_int
6110 = build_function_type_list (void_type_node, V8HI_type_node,
6111 integer_type_node, integer_type_node,
6112 NULL_TREE);
6113 tree void_ftype_v8hi_int_int_int
6114 = build_function_type_list (void_type_node, V8HI_type_node,
6115 integer_type_node, integer_type_node,
6116 integer_type_node, NULL_TREE);
6117 tree v8hi_ftype_int_int
6118 = build_function_type_list (V8HI_type_node, integer_type_node,
6119 integer_type_node, NULL_TREE);
6120 tree void_ftype_int_int
6121 = build_function_type_list (void_type_node, integer_type_node,
6122 integer_type_node, NULL_TREE);
6123 tree v8hi_ftype_v8hi
6124 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6125 NULL_TREE);
6126 /* ARCv2 SIMD types. */
6127 tree long_ftype_v4hi_v4hi
6128 = build_function_type_list (long_long_integer_type_node,
6129 V4HI_type_node, V4HI_type_node, NULL_TREE);
6130 tree int_ftype_v2hi_v2hi
6131 = build_function_type_list (integer_type_node,
6132 V2HI_type_node, V2HI_type_node, NULL_TREE);
6133 tree v2si_ftype_v2hi_v2hi
6134 = build_function_type_list (V2SI_type_node,
6135 V2HI_type_node, V2HI_type_node, NULL_TREE);
6136 tree v2hi_ftype_v2hi_v2hi
6137 = build_function_type_list (V2HI_type_node,
6138 V2HI_type_node, V2HI_type_node, NULL_TREE);
6139 tree v2si_ftype_v2si_v2si
6140 = build_function_type_list (V2SI_type_node,
6141 V2SI_type_node, V2SI_type_node, NULL_TREE);
6142 tree v4hi_ftype_v4hi_v4hi
6143 = build_function_type_list (V4HI_type_node,
6144 V4HI_type_node, V4HI_type_node, NULL_TREE);
6145 tree long_ftype_v2si_v2hi
6146 = build_function_type_list (long_long_integer_type_node,
6147 V2SI_type_node, V2HI_type_node, NULL_TREE);
6149 /* Add the builtins. */
6150 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6152 int id = ARC_BUILTIN_ ## NAME; \
6153 const char *Name = "__builtin_arc_" #NAME; \
6154 char *name = (char*) alloca (1 + strlen (Name)); \
6156 gcc_assert (id < ARC_BUILTIN_COUNT); \
6157 if (MASK) \
6158 arc_bdesc[id].fndecl \
6159 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6160 BUILT_IN_MD, NULL, NULL_TREE); \
6162 #include "builtins.def"
6163 #undef DEF_BUILTIN
6166 /* Helper to expand __builtin_arc_aligned (void* val, int
6167 alignval). */
6169 static rtx
6170 arc_expand_builtin_aligned (tree exp)
6172 tree arg0 = CALL_EXPR_ARG (exp, 0);
6173 tree arg1 = CALL_EXPR_ARG (exp, 1);
6174 fold (arg1);
6175 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6176 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6178 if (!CONST_INT_P (op1))
6180 /* If we can't fold the alignment to a constant integer
6181 whilst optimizing, this is probably a user error. */
6182 if (optimize)
6183 warning (0, "__builtin_arc_aligned with non-constant alignment");
6185 else
6187 HOST_WIDE_INT alignTest = INTVAL (op1);
6188 /* Check alignTest is positive, and a power of two. */
6189 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6191 error ("invalid alignment value for __builtin_arc_aligned");
6192 return NULL_RTX;
6195 if (CONST_INT_P (op0))
6197 HOST_WIDE_INT pnt = INTVAL (op0);
6199 if ((pnt & (alignTest - 1)) == 0)
6200 return const1_rtx;
6202 else
6204 unsigned align = get_pointer_alignment (arg0);
6205 unsigned numBits = alignTest * BITS_PER_UNIT;
6207 if (align && align >= numBits)
6208 return const1_rtx;
6209 /* Another attempt to ascertain alignment. Check the type
6210 we are pointing to. */
6211 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6212 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6213 return const1_rtx;
6217 /* Default to false. */
6218 return const0_rtx;
6221 /* Helper arc_expand_builtin, generates a pattern for the given icode
6222 and arguments. */
6224 static rtx_insn *
6225 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6227 switch (insn_data[icode].n_generator_args)
6229 case 0:
6230 return GEN_FCN (icode) ();
6231 case 1:
6232 return GEN_FCN (icode) (arg[0]);
6233 case 2:
6234 return GEN_FCN (icode) (arg[0], arg[1]);
6235 case 3:
6236 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6237 case 4:
6238 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6239 case 5:
6240 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6241 default:
6242 gcc_unreachable ();
6246 /* Expand an expression EXP that calls a built-in function,
6247 with result going to TARGET if that's convenient
6248 (and in mode MODE if that's convenient).
6249 SUBTARGET may be used as the target for computing one of EXP's operands.
6250 IGNORE is nonzero if the value is to be ignored. */
6252 static rtx
6253 arc_expand_builtin (tree exp,
6254 rtx target,
6255 rtx subtarget ATTRIBUTE_UNUSED,
6256 machine_mode mode ATTRIBUTE_UNUSED,
6257 int ignore ATTRIBUTE_UNUSED)
6259 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6260 unsigned int id = DECL_FUNCTION_CODE (fndecl);
6261 const struct arc_builtin_description *d = &arc_bdesc[id];
6262 int i, j, n_args = call_expr_nargs (exp);
6263 rtx pat = NULL_RTX;
6264 rtx xop[5];
6265 enum insn_code icode = d->icode;
6266 machine_mode tmode = insn_data[icode].operand[0].mode;
6267 int nonvoid;
6268 tree arg0;
6269 tree arg1;
6270 tree arg2;
6271 tree arg3;
6272 rtx op0;
6273 rtx op1;
6274 rtx op2;
6275 rtx op3;
6276 rtx op4;
6277 machine_mode mode0;
6278 machine_mode mode1;
6279 machine_mode mode2;
6280 machine_mode mode3;
6281 machine_mode mode4;
6283 if (id >= ARC_BUILTIN_COUNT)
6284 internal_error ("bad builtin fcode");
6286 /* 1st part: Expand special builtins. */
6287 switch (id)
6289 case ARC_BUILTIN_NOP:
6290 emit_insn (gen_nopv ());
6291 return NULL_RTX;
6293 case ARC_BUILTIN_RTIE:
6294 case ARC_BUILTIN_SYNC:
6295 case ARC_BUILTIN_BRK:
6296 case ARC_BUILTIN_SWI:
6297 case ARC_BUILTIN_UNIMP_S:
6298 gcc_assert (icode != 0);
6299 emit_insn (GEN_FCN (icode) (const1_rtx));
6300 return NULL_RTX;
6302 case ARC_BUILTIN_ALIGNED:
6303 return arc_expand_builtin_aligned (exp);
6305 case ARC_BUILTIN_CLRI:
6306 target = gen_reg_rtx (SImode);
6307 emit_insn (gen_clri (target, const1_rtx));
6308 return target;
6310 case ARC_BUILTIN_TRAP_S:
6311 case ARC_BUILTIN_SLEEP:
6312 arg0 = CALL_EXPR_ARG (exp, 0);
6313 fold (arg0);
6314 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6316 if (!CONST_INT_P (op0) || !satisfies_constraint_L (op0))
6318 error ("builtin operand should be an unsigned 6-bit value");
6319 return NULL_RTX;
6321 gcc_assert (icode != 0);
6322 emit_insn (GEN_FCN (icode) (op0));
6323 return NULL_RTX;
6325 case ARC_BUILTIN_VDORUN:
6326 case ARC_BUILTIN_VDIRUN:
6327 arg0 = CALL_EXPR_ARG (exp, 0);
6328 arg1 = CALL_EXPR_ARG (exp, 1);
6329 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6330 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6332 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
6334 mode0 = insn_data[icode].operand[1].mode;
6335 mode1 = insn_data[icode].operand[2].mode;
6337 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6338 op0 = copy_to_mode_reg (mode0, op0);
6340 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6341 op1 = copy_to_mode_reg (mode1, op1);
6343 pat = GEN_FCN (icode) (target, op0, op1);
6344 if (!pat)
6345 return NULL_RTX;
6347 emit_insn (pat);
6348 return NULL_RTX;
6350 case ARC_BUILTIN_VDIWR:
6351 case ARC_BUILTIN_VDOWR:
6352 arg0 = CALL_EXPR_ARG (exp, 0);
6353 arg1 = CALL_EXPR_ARG (exp, 1);
6354 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6355 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6357 if (!CONST_INT_P (op0)
6358 || !(UNSIGNED_INT3 (INTVAL (op0))))
6359 error ("operand 1 should be an unsigned 3-bit immediate");
6361 mode1 = insn_data[icode].operand[1].mode;
6363 if (icode == CODE_FOR_vdiwr_insn)
6364 target = gen_rtx_REG (SImode,
6365 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
6366 else if (icode == CODE_FOR_vdowr_insn)
6367 target = gen_rtx_REG (SImode,
6368 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
6369 else
6370 gcc_unreachable ();
6372 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6373 op1 = copy_to_mode_reg (mode1, op1);
6375 pat = GEN_FCN (icode) (target, op1);
6376 if (!pat)
6377 return NULL_RTX;
6379 emit_insn (pat);
6380 return NULL_RTX;
6382 case ARC_BUILTIN_VASRW:
6383 case ARC_BUILTIN_VSR8:
6384 case ARC_BUILTIN_VSR8AW:
6385 arg0 = CALL_EXPR_ARG (exp, 0);
6386 arg1 = CALL_EXPR_ARG (exp, 1);
6387 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6388 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6389 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6391 target = gen_reg_rtx (V8HImode);
6392 mode0 = insn_data[icode].operand[1].mode;
6393 mode1 = insn_data[icode].operand[2].mode;
6395 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6396 op0 = copy_to_mode_reg (mode0, op0);
6398 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6399 || !(UNSIGNED_INT3 (INTVAL (op1))))
6400 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6402 pat = GEN_FCN (icode) (target, op0, op1, op2);
6403 if (!pat)
6404 return NULL_RTX;
6406 emit_insn (pat);
6407 return target;
6409 case ARC_BUILTIN_VLD32WH:
6410 case ARC_BUILTIN_VLD32WL:
6411 case ARC_BUILTIN_VLD64:
6412 case ARC_BUILTIN_VLD32:
6413 rtx src_vreg;
6414 icode = d->icode;
6415 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6416 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6417 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6419 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6420 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6421 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6422 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6424 /* target <- src vreg. */
6425 emit_insn (gen_move_insn (target, src_vreg));
6427 /* target <- vec_concat: target, mem (Ib, u8). */
6428 mode0 = insn_data[icode].operand[3].mode;
6429 mode1 = insn_data[icode].operand[1].mode;
6431 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
6432 || !(UNSIGNED_INT3 (INTVAL (op0))))
6433 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6435 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6436 || !(UNSIGNED_INT8 (INTVAL (op1))))
6437 error ("operand 2 should be an unsigned 8-bit value");
6439 pat = GEN_FCN (icode) (target, op1, op2, op0);
6440 if (!pat)
6441 return NULL_RTX;
6443 emit_insn (pat);
6444 return target;
6446 case ARC_BUILTIN_VLD64W:
6447 case ARC_BUILTIN_VLD128:
6448 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
6449 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6451 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6452 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6453 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6455 /* target <- src vreg. */
6456 target = gen_reg_rtx (V8HImode);
6458 /* target <- vec_concat: target, mem (Ib, u8). */
6459 mode0 = insn_data[icode].operand[1].mode;
6460 mode1 = insn_data[icode].operand[2].mode;
6461 mode2 = insn_data[icode].operand[3].mode;
6463 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6464 || !(UNSIGNED_INT3 (INTVAL (op1))))
6465 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6467 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
6468 || !(UNSIGNED_INT8 (INTVAL (op2))))
6469 error ("operand 2 should be an unsigned 8-bit value");
6471 pat = GEN_FCN (icode) (target, op0, op1, op2);
6473 if (!pat)
6474 return NULL_RTX;
6476 emit_insn (pat);
6477 return target;
6479 case ARC_BUILTIN_VST128:
6480 case ARC_BUILTIN_VST64:
6481 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
6482 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6483 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6485 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6486 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6487 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6488 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6490 mode0 = insn_data[icode].operand[0].mode;
6491 mode1 = insn_data[icode].operand[1].mode;
6492 mode2 = insn_data[icode].operand[2].mode;
6493 mode3 = insn_data[icode].operand[3].mode;
6495 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6496 || !(UNSIGNED_INT3 (INTVAL (op1))))
6497 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6499 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6500 || !(UNSIGNED_INT8 (INTVAL (op2))))
6501 error ("operand 3 should be an unsigned 8-bit value");
6503 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6504 op3 = copy_to_mode_reg (mode3, op3);
6506 pat = GEN_FCN (icode) (op0, op1, op2, op3);
6507 if (!pat)
6508 return NULL_RTX;
6510 emit_insn (pat);
6511 return NULL_RTX;
6513 case ARC_BUILTIN_VST16_N:
6514 case ARC_BUILTIN_VST32_N:
6515 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6516 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
6517 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
6518 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
6520 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
6521 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6522 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6523 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6524 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6526 mode0 = insn_data[icode].operand[0].mode;
6527 mode2 = insn_data[icode].operand[2].mode;
6528 mode3 = insn_data[icode].operand[3].mode;
6529 mode4 = insn_data[icode].operand[4].mode;
6531 /* Do some correctness checks for the operands. */
6532 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
6533 || !(UNSIGNED_INT8 (INTVAL (op0))))
6534 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6536 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6537 || !(UNSIGNED_INT3 (INTVAL (op2))))
6538 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6540 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6541 op3 = copy_to_mode_reg (mode3, op3);
6543 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
6544 || !(UNSIGNED_INT3 (INTVAL (op4))))
6545 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6546 else if (icode == CODE_FOR_vst32_n_insn
6547 && ((INTVAL (op4) % 2) != 0))
6548 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6550 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
6551 if (!pat)
6552 return NULL_RTX;
6554 emit_insn (pat);
6555 return NULL_RTX;
6557 default:
6558 break;
6561 /* 2nd part: Expand regular builtins. */
6562 if (icode == 0)
6563 internal_error ("bad builtin fcode");
6565 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6566 j = 0;
6568 if (nonvoid)
6570 if (target == NULL_RTX
6571 || GET_MODE (target) != tmode
6572 || !insn_data[icode].operand[0].predicate (target, tmode))
6574 target = gen_reg_rtx (tmode);
6576 xop[j++] = target;
6579 gcc_assert (n_args <= 4);
6580 for (i = 0; i < n_args; i++, j++)
6582 tree arg = CALL_EXPR_ARG (exp, i);
6583 machine_mode mode = insn_data[icode].operand[j].mode;
6584 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
6585 machine_mode opmode = GET_MODE (op);
6586 char c = insn_data[icode].operand[j].constraint[0];
6588 /* SIMD extension requires exact immediate operand match. */
6589 if ((id > ARC_BUILTIN_SIMD_BEGIN)
6590 && (id < ARC_BUILTIN_SIMD_END)
6591 && (c != 'v')
6592 && (c != 'r'))
6594 if (!CONST_INT_P (op))
6595 error ("builtin requires an immediate for operand %d", j);
6596 switch (c)
6598 case 'L':
6599 if (!satisfies_constraint_L (op))
6600 error ("operand %d should be a 6 bit unsigned immediate", j);
6601 break;
6602 case 'P':
6603 if (!satisfies_constraint_P (op))
6604 error ("operand %d should be a 8 bit unsigned immediate", j);
6605 break;
6606 case 'K':
6607 if (!satisfies_constraint_K (op))
6608 error ("operand %d should be a 3 bit unsigned immediate", j);
6609 break;
6610 default:
6611 error ("unknown builtin immediate operand type for operand %d",
6616 if (CONST_INT_P (op))
6617 opmode = mode;
6619 if ((opmode == SImode) && (mode == HImode))
6621 opmode = HImode;
6622 op = gen_lowpart (HImode, op);
6625 /* In case the insn wants input operands in modes different from
6626 the result, abort. */
6627 gcc_assert (opmode == mode || opmode == VOIDmode);
6629 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
6630 op = copy_to_mode_reg (mode, op);
6632 xop[j] = op;
6635 pat = apply_GEN_FCN (icode, xop);
6636 if (pat == NULL_RTX)
6637 return NULL_RTX;
6639 emit_insn (pat);
6641 if (nonvoid)
6642 return target;
6643 else
6644 return const0_rtx;
6647 /* Returns true if the operands[opno] is a valid compile-time constant to be
6648 used as register number in the code for builtins. Else it flags an error
6649 and returns false. */
6651 bool
6652 check_if_valid_regno_const (rtx *operands, int opno)
6655 switch (GET_CODE (operands[opno]))
6657 case SYMBOL_REF :
6658 case CONST :
6659 case CONST_INT :
6660 return true;
6661 default:
6662 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6663 break;
6665 return false;
6668 /* Check that after all the constant folding, whether the operand to
6669 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6671 bool
6672 check_if_valid_sleep_operand (rtx *operands, int opno)
6674 switch (GET_CODE (operands[opno]))
6676 case CONST :
6677 case CONST_INT :
6678 if( UNSIGNED_INT6 (INTVAL (operands[opno])))
6679 return true;
6680 /* FALLTHRU */
6681 default:
6682 fatal_error (input_location,
6683 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6684 break;
6686 return false;
6689 /* Return true if it is ok to make a tail-call to DECL. */
6691 static bool
6692 arc_function_ok_for_sibcall (tree decl ATTRIBUTE_UNUSED,
6693 tree exp ATTRIBUTE_UNUSED)
6695 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6696 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
6697 return false;
6699 /* Everything else is ok. */
6700 return true;
6703 /* Output code to add DELTA to the first argument, and then jump
6704 to FUNCTION. Used for C++ multiple inheritance. */
6706 static void
6707 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6708 HOST_WIDE_INT delta,
6709 HOST_WIDE_INT vcall_offset,
6710 tree function)
6712 int mi_delta = delta;
6713 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
6714 int shift = 0;
6715 int this_regno
6716 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
6717 rtx fnaddr;
6719 if (mi_delta < 0)
6720 mi_delta = - mi_delta;
6722 /* Add DELTA. When possible use a plain add, otherwise load it into
6723 a register first. */
6725 while (mi_delta != 0)
6727 if ((mi_delta & (3 << shift)) == 0)
6728 shift += 2;
6729 else
6731 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
6732 mi_op, reg_names[this_regno], reg_names[this_regno],
6733 mi_delta & (0xff << shift));
6734 mi_delta &= ~(0xff << shift);
6735 shift += 8;
6739 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6740 if (vcall_offset != 0)
6742 /* ld r12,[this] --> temp = *this
6743 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
6744 ld r12,[r12]
6745 add this,this,r12 --> this+ = *(*this + vcall_offset) */
6746 asm_fprintf (file, "\tld\t%s, [%s]\n",
6747 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
6748 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
6749 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
6750 asm_fprintf (file, "\tld\t%s, [%s]\n",
6751 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
6752 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
6753 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
6756 fnaddr = XEXP (DECL_RTL (function), 0);
6758 if (arc_is_longcall_p (fnaddr))
6760 if (flag_pic)
6762 asm_fprintf (file, "\tld\t%s, [pcl, @",
6763 ARC_TEMP_SCRATCH_REG);
6764 assemble_name (file, XSTR (fnaddr, 0));
6765 fputs ("@gotpc]\n", file);
6766 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
6768 else
6770 fputs ("\tj\t@", file);
6771 assemble_name (file, XSTR (fnaddr, 0));
6774 else
6776 fputs ("\tb\t@", file);
6777 assemble_name (file, XSTR (fnaddr, 0));
6778 if (flag_pic)
6779 fputs ("@plt\n", file);
6781 fputc ('\n', file);
6784 /* Return true if a 32 bit "long_call" should be generated for
6785 this calling SYM_REF. We generate a long_call if the function:
6787 a. has an __attribute__((long call))
6788 or b. the -mlong-calls command line switch has been specified
6790 However we do not generate a long call if the function has an
6791 __attribute__ ((short_call)) or __attribute__ ((medium_call))
6793 This function will be called by C fragments contained in the machine
6794 description file. */
6796 bool
6797 arc_is_longcall_p (rtx sym_ref)
6799 if (GET_CODE (sym_ref) != SYMBOL_REF)
6800 return false;
6802 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
6803 || (TARGET_LONG_CALLS_SET
6804 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
6805 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6809 /* Likewise for short calls. */
6811 bool
6812 arc_is_shortcall_p (rtx sym_ref)
6814 if (GET_CODE (sym_ref) != SYMBOL_REF)
6815 return false;
6817 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
6818 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
6819 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
6820 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
6824 /* Worker function for TARGET_RETURN_IN_MEMORY. */
6826 static bool
6827 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
6829 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
6830 return true;
6831 else
6833 HOST_WIDE_INT size = int_size_in_bytes (type);
6834 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
6839 /* This was in rtlanal.c, and can go in there when we decide we want
6840 to submit the change for inclusion in the GCC tree. */
6841 /* Like note_stores, but allow the callback to have side effects on the rtl
6842 (like the note_stores of yore):
6843 Call FUN on each register or MEM that is stored into or clobbered by X.
6844 (X would be the pattern of an insn). DATA is an arbitrary pointer,
6845 ignored by note_stores, but passed to FUN.
6846 FUN may alter parts of the RTL.
6848 FUN receives three arguments:
6849 1. the REG, MEM, CC0 or PC being stored in or clobbered,
6850 2. the SET or CLOBBER rtx that does the store,
6851 3. the pointer DATA provided to note_stores.
6853 If the item being stored in or clobbered is a SUBREG of a hard register,
6854 the SUBREG will be passed. */
6856 /* For now. */ static
6857 void
6858 walk_stores (rtx x, void (*fun) (rtx, rtx, void *), void *data)
6860 int i;
6862 if (GET_CODE (x) == COND_EXEC)
6863 x = COND_EXEC_CODE (x);
6865 if (GET_CODE (x) == SET || GET_CODE (x) == CLOBBER)
6867 rtx dest = SET_DEST (x);
6869 while ((GET_CODE (dest) == SUBREG
6870 && (!REG_P (SUBREG_REG (dest))
6871 || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
6872 || GET_CODE (dest) == ZERO_EXTRACT
6873 || GET_CODE (dest) == STRICT_LOW_PART)
6874 dest = XEXP (dest, 0);
6876 /* If we have a PARALLEL, SET_DEST is a list of EXPR_LIST expressions,
6877 each of whose first operand is a register. */
6878 if (GET_CODE (dest) == PARALLEL)
6880 for (i = XVECLEN (dest, 0) - 1; i >= 0; i--)
6881 if (XEXP (XVECEXP (dest, 0, i), 0) != 0)
6882 (*fun) (XEXP (XVECEXP (dest, 0, i), 0), x, data);
6884 else
6885 (*fun) (dest, x, data);
6888 else if (GET_CODE (x) == PARALLEL)
6889 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
6890 walk_stores (XVECEXP (x, 0, i), fun, data);
6893 static bool
6894 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
6895 machine_mode mode ATTRIBUTE_UNUSED,
6896 const_tree type,
6897 bool named ATTRIBUTE_UNUSED)
6899 return (type != 0
6900 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
6901 || TREE_ADDRESSABLE (type)));
6904 /* Implement TARGET_CAN_USE_DOLOOP_P. */
6906 static bool
6907 arc_can_use_doloop_p (const widest_int &,
6908 const widest_int &iterations_max,
6909 unsigned int loop_depth, bool entered_at_top)
6911 /* Considering limitations in the hardware, only use doloop
6912 for innermost loops which must be entered from the top. */
6913 if (loop_depth > 1 || !entered_at_top)
6914 return false;
6916 /* Check for lp_count width boundary. */
6917 if (arc_lpcwidth != 32
6918 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
6919 || wi::eq_p (iterations_max, 0)))
6920 return false;
6921 return true;
6924 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
6925 return why doloop cannot be applied. */
6927 static const char *
6928 arc_invalid_within_doloop (const rtx_insn *insn)
6930 if (CALL_P (insn))
6931 return "Function call in the loop.";
6933 /* FIXME! add here all the ZOL exceptions. */
6934 return NULL;
6937 /* Return true if a load instruction (CONSUMER) uses the same address as a
6938 store instruction (PRODUCER). This function is used to avoid st/ld
6939 address hazard in ARC700 cores. */
6940 bool
6941 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
6943 rtx in_set, out_set;
6944 rtx out_addr, in_addr;
6946 if (!producer)
6947 return false;
6949 if (!consumer)
6950 return false;
6952 /* Peel the producer and the consumer for the address. */
6953 out_set = single_set (producer);
6954 if (out_set)
6956 out_addr = SET_DEST (out_set);
6957 if (!out_addr)
6958 return false;
6959 if (GET_CODE (out_addr) == ZERO_EXTEND
6960 || GET_CODE (out_addr) == SIGN_EXTEND)
6961 out_addr = XEXP (out_addr, 0);
6963 if (!MEM_P (out_addr))
6964 return false;
6966 in_set = single_set (consumer);
6967 if (in_set)
6969 in_addr = SET_SRC (in_set);
6970 if (!in_addr)
6971 return false;
6972 if (GET_CODE (in_addr) == ZERO_EXTEND
6973 || GET_CODE (in_addr) == SIGN_EXTEND)
6974 in_addr = XEXP (in_addr, 0);
6976 if (!MEM_P (in_addr))
6977 return false;
6978 /* Get rid of the MEM and check if the addresses are
6979 equivalent. */
6980 in_addr = XEXP (in_addr, 0);
6981 out_addr = XEXP (out_addr, 0);
6983 return exp_equiv_p (in_addr, out_addr, 0, true);
6986 return false;
6989 /* The same functionality as arc_hazard. It is called in machine
6990 reorg before any other optimization. Hence, the NOP size is taken
6991 into account when doing branch shortening. */
6993 static void
6994 workaround_arc_anomaly (void)
6996 rtx_insn *insn, *succ0;
6998 /* For any architecture: call arc_hazard here. */
6999 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7001 succ0 = next_real_insn (insn);
7002 if (arc_hazard (insn, succ0))
7004 emit_insn_before (gen_nopv (), succ0);
7008 if (TARGET_ARC700)
7010 rtx_insn *succ1;
7012 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7014 succ0 = next_real_insn (insn);
7015 if (arc_store_addr_hazard_p (insn, succ0))
7017 emit_insn_after (gen_nopv (), insn);
7018 emit_insn_after (gen_nopv (), insn);
7019 continue;
7022 /* Avoid adding nops if the instruction between the ST and LD is
7023 a call or jump. */
7024 succ1 = next_real_insn (succ0);
7025 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0)
7026 && arc_store_addr_hazard_p (insn, succ1))
7027 emit_insn_after (gen_nopv (), insn);
7032 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7033 turns out not to be optimizable; we have to split the loop_end pattern into
7034 a subtract and a test. */
7036 static void
7037 hwloop_fail (hwloop_info loop)
7039 rtx test;
7040 rtx insn = loop->loop_end;
7042 if (TARGET_V2
7043 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7044 && REG_P (loop->iter_reg))
7046 /* TARGET_V2 has dbnz instructions. */
7047 test = gen_dbnz (loop->iter_reg, loop->start_label);
7048 insn = emit_jump_insn_before (test, loop->loop_end);
7050 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7052 /* We have the lp_count as loop iterator, try to use it. */
7053 emit_insn_before (gen_loop_fail (), loop->loop_end);
7054 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7055 const0_rtx);
7056 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7057 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7058 pc_rtx);
7059 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7060 loop->loop_end);
7062 else
7064 emit_insn_before (gen_addsi3 (loop->iter_reg,
7065 loop->iter_reg,
7066 constm1_rtx),
7067 loop->loop_end);
7068 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7069 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7070 loop->iter_reg,
7071 const0_rtx,
7072 loop->start_label),
7073 loop->loop_end);
7075 JUMP_LABEL (insn) = loop->start_label;
7076 LABEL_NUSES (loop->start_label)++;
7077 delete_insn (loop->loop_end);
7080 /* Optimize LOOP. */
7082 static bool
7083 hwloop_optimize (hwloop_info loop)
7085 int i;
7086 edge entry_edge;
7087 basic_block entry_bb, bb;
7088 rtx iter_reg, end_label;
7089 rtx_insn *insn, *seq, *entry_after, *last_insn;
7090 unsigned int length;
7091 bool need_fix = false;
7092 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7094 if (loop->depth > 1)
7096 if (dump_file)
7097 fprintf (dump_file, ";; loop %d is not innermost\n",
7098 loop->loop_no);
7099 return false;
7102 if (!loop->incoming_dest)
7104 if (dump_file)
7105 fprintf (dump_file, ";; loop %d has more than one entry\n",
7106 loop->loop_no);
7107 return false;
7110 if (loop->incoming_dest != loop->head)
7112 if (dump_file)
7113 fprintf (dump_file, ";; loop %d is not entered from head\n",
7114 loop->loop_no);
7115 return false;
7118 if (loop->has_call || loop->has_asm)
7120 if (dump_file)
7121 fprintf (dump_file, ";; loop %d has invalid insn\n",
7122 loop->loop_no);
7123 return false;
7126 /* Scan all the blocks to make sure they don't use iter_reg. */
7127 if (loop->iter_reg_used || loop->iter_reg_used_outside)
7129 if (dump_file)
7130 fprintf (dump_file, ";; loop %d uses iterator\n",
7131 loop->loop_no);
7132 return false;
7135 /* Check if start_label appears before doloop_end. */
7136 length = 0;
7137 for (insn = loop->start_label;
7138 insn && insn != loop->loop_end;
7139 insn = NEXT_INSN (insn))
7140 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
7142 if (!insn)
7144 if (dump_file)
7145 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
7146 loop->loop_no);
7147 return false;
7150 loop->length = length;
7151 if (loop->length > ARC_MAX_LOOP_LENGTH)
7153 if (dump_file)
7154 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7155 return false;
7158 /* Check if we use a register or not. */
7159 if (!REG_P (loop->iter_reg))
7161 if (dump_file)
7162 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7163 loop->loop_no);
7164 return false;
7167 /* Check if loop register is lpcount. */
7168 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
7170 if (dump_file)
7171 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
7172 " iterator\n",
7173 loop->loop_no);
7174 /* This loop doesn't use the lp_count, check though if we can
7175 fix it. */
7176 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
7177 /* In very unique cases we may have LP_COUNT alive. */
7178 || (loop->incoming_src
7179 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
7180 LP_COUNT)))
7181 return false;
7182 else
7183 need_fix = true;
7186 /* Check for control like instruction as the last instruction of a
7187 ZOL. */
7188 bb = loop->tail;
7189 last_insn = PREV_INSN (loop->loop_end);
7191 while (1)
7193 for (; last_insn != BB_HEAD (bb);
7194 last_insn = PREV_INSN (last_insn))
7195 if (NONDEBUG_INSN_P (last_insn))
7196 break;
7198 if (last_insn != BB_HEAD (bb))
7199 break;
7201 if (single_pred_p (bb)
7202 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
7203 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
7205 bb = single_pred (bb);
7206 last_insn = BB_END (bb);
7207 continue;
7209 else
7211 last_insn = NULL;
7212 break;
7216 if (!last_insn)
7218 if (dump_file)
7219 fprintf (dump_file, ";; loop %d has no last instruction\n",
7220 loop->loop_no);
7221 return false;
7224 if ((TARGET_ARC600_FAMILY || TARGET_HS)
7225 && INSN_P (last_insn)
7226 && (JUMP_P (last_insn) || CALL_P (last_insn)
7227 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
7228 || get_attr_type (last_insn) == TYPE_BRCC
7229 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))
7231 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
7233 if (dump_file)
7234 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7235 return false;
7237 if (dump_file)
7238 fprintf (dump_file, ";; loop %d has a control like last insn;"
7239 "add a nop\n",
7240 loop->loop_no);
7242 last_insn = emit_insn_after (gen_nopv (), last_insn);
7245 if (LABEL_P (last_insn))
7247 if (dump_file)
7248 fprintf (dump_file, ";; loop %d has a label as last insn;"
7249 "add a nop\n",
7250 loop->loop_no);
7251 last_insn = emit_insn_after (gen_nopv (), last_insn);
7253 loop->last_insn = last_insn;
7255 /* Get the loop iteration register. */
7256 iter_reg = loop->iter_reg;
7258 gcc_assert (REG_P (iter_reg));
7260 entry_edge = NULL;
7262 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
7263 if (entry_edge->flags & EDGE_FALLTHRU)
7264 break;
7266 if (entry_edge == NULL)
7268 if (dump_file)
7269 fprintf (dump_file, ";; loop %d has no fallthru edge jumping"
7270 "into the loop\n",
7271 loop->loop_no);
7272 return false;
7274 /* The loop is good. */
7275 end_label = gen_label_rtx ();
7276 loop->end_label = end_label;
7278 /* Place the zero_cost_loop_start instruction before the loop. */
7279 entry_bb = entry_edge->src;
7281 start_sequence ();
7283 if (need_fix)
7285 /* The loop uses a R-register, but the lp_count is free, thus
7286 use lp_count. */
7287 emit_insn (gen_movsi (lp_reg, iter_reg));
7288 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
7289 iter_reg = lp_reg;
7290 if (dump_file)
7292 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
7293 loop->loop_no);
7297 insn = emit_insn (gen_arc_lp (iter_reg,
7298 loop->start_label,
7299 loop->end_label));
7301 seq = get_insns ();
7302 end_sequence ();
7304 entry_after = BB_END (entry_bb);
7305 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
7306 || !entry_after)
7308 basic_block new_bb;
7309 edge e;
7310 edge_iterator ei;
7312 emit_insn_before (seq, BB_HEAD (loop->head));
7313 seq = emit_label_before (gen_label_rtx (), seq);
7314 new_bb = create_basic_block (seq, insn, entry_bb);
7315 FOR_EACH_EDGE (e, ei, loop->incoming)
7317 if (!(e->flags & EDGE_FALLTHRU))
7318 redirect_edge_and_branch_force (e, new_bb);
7319 else
7320 redirect_edge_succ (e, new_bb);
7323 make_edge (new_bb, loop->head, 0);
7325 else
7327 #if 0
7328 while (DEBUG_INSN_P (entry_after)
7329 || (NOTE_P (entry_after)
7330 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
7331 /* Make sure we don't split a call and its corresponding
7332 CALL_ARG_LOCATION note. */
7333 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
7334 entry_after = NEXT_INSN (entry_after);
7335 #endif
7336 entry_after = next_nonnote_insn_bb (entry_after);
7338 gcc_assert (entry_after);
7339 emit_insn_before (seq, entry_after);
7342 delete_insn (loop->loop_end);
7343 /* Insert the loop end label before the last instruction of the
7344 loop. */
7345 emit_label_after (end_label, loop->last_insn);
7347 return true;
7350 /* A callback for the hw-doloop pass. This function examines INSN; if
7351 it is a loop_end pattern we recognize, return the reg rtx for the
7352 loop counter. Otherwise, return NULL_RTX. */
7354 static rtx
7355 hwloop_pattern_reg (rtx_insn *insn)
7357 rtx reg;
7359 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
7360 return NULL_RTX;
7362 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
7363 if (!REG_P (reg))
7364 return NULL_RTX;
7365 return reg;
7368 static struct hw_doloop_hooks arc_doloop_hooks =
7370 hwloop_pattern_reg,
7371 hwloop_optimize,
7372 hwloop_fail
7375 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
7376 and tries to rewrite the RTL of these loops so that proper Blackfin
7377 hardware loops are generated. */
7379 static void
7380 arc_reorg_loops (void)
7382 reorg_loops (true, &arc_doloop_hooks);
7385 static int arc_reorg_in_progress = 0;
7387 /* ARC's machince specific reorg function. */
7389 static void
7390 arc_reorg (void)
7392 rtx_insn *insn;
7393 rtx pattern;
7394 rtx pc_target;
7395 long offset;
7396 int changed;
7398 cfun->machine->arc_reorg_started = 1;
7399 arc_reorg_in_progress = 1;
7401 compute_bb_for_insn ();
7403 df_analyze ();
7405 /* Doloop optimization. */
7406 arc_reorg_loops ();
7408 workaround_arc_anomaly ();
7410 /* FIXME: should anticipate ccfsm action, generate special patterns for
7411 to-be-deleted branches that have no delay slot and have at least the
7412 length of the size increase forced on other insns that are conditionalized.
7413 This can also have an insn_list inside that enumerates insns which are
7414 not actually conditionalized because the destinations are dead in the
7415 not-execute case.
7416 Could also tag branches that we want to be unaligned if they get no delay
7417 slot, or even ones that we don't want to do delay slot sheduling for
7418 because we can unalign them.
7420 However, there are cases when conditional execution is only possible after
7421 delay slot scheduling:
7423 - If a delay slot is filled with a nocond/set insn from above, the previous
7424 basic block can become elegible for conditional execution.
7425 - If a delay slot is filled with a nocond insn from the fall-through path,
7426 the branch with that delay slot can become eligble for conditional
7427 execution (however, with the same sort of data flow analysis that dbr
7428 does, we could have figured out before that we don't need to
7429 conditionalize this insn.)
7430 - If a delay slot insn is filled with an insn from the target, the
7431 target label gets its uses decremented (even deleted if falling to zero),
7432 thus possibly creating more condexec opportunities there.
7433 Therefore, we should still be prepared to apply condexec optimization on
7434 non-prepared branches if the size increase of conditionalized insns is no
7435 more than the size saved from eliminating the branch. An invocation option
7436 could also be used to reserve a bit of extra size for condbranches so that
7437 this'll work more often (could also test in arc_reorg if the block is
7438 'close enough' to be eligible for condexec to make this likely, and
7439 estimate required size increase). */
7440 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7441 if (TARGET_NO_BRCC_SET)
7442 return;
7446 init_insn_lengths();
7447 changed = 0;
7449 if (optimize > 1 && !TARGET_NO_COND_EXEC)
7451 arc_ifcvt ();
7452 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
7453 df_finish_pass ((flags & TODO_df_verify) != 0);
7455 if (dump_file)
7457 fprintf (dump_file, ";; After if conversion:\n\n");
7458 print_rtl (dump_file, get_insns ());
7462 /* Call shorten_branches to calculate the insn lengths. */
7463 shorten_branches (get_insns());
7464 cfun->machine->ccfsm_current_insn = NULL_RTX;
7466 if (!INSN_ADDRESSES_SET_P())
7467 fatal_error (input_location, "Insn addresses not set after shorten_branches");
7469 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7471 rtx label;
7472 enum attr_type insn_type;
7474 /* If a non-jump insn (or a casesi jump table), continue. */
7475 if (GET_CODE (insn) != JUMP_INSN ||
7476 GET_CODE (PATTERN (insn)) == ADDR_VEC
7477 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
7478 continue;
7480 /* If we already have a brcc, note if it is suitable for brcc_s.
7481 Be a bit generous with the brcc_s range so that we can take
7482 advantage of any code shortening from delay slot scheduling. */
7483 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
7485 rtx pat = PATTERN (insn);
7486 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
7487 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
7489 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7490 if ((offset >= -140 && offset < 140)
7491 && rtx_equal_p (XEXP (op, 1), const0_rtx)
7492 && compact_register_operand (XEXP (op, 0), VOIDmode)
7493 && equality_comparison_operator (op, VOIDmode))
7494 PUT_MODE (*ccp, CC_Zmode);
7495 else if (GET_MODE (*ccp) == CC_Zmode)
7496 PUT_MODE (*ccp, CC_ZNmode);
7497 continue;
7499 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
7500 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
7501 continue;
7503 /* OK. so we have a jump insn. */
7504 /* We need to check that it is a bcc. */
7505 /* Bcc => set (pc) (if_then_else ) */
7506 pattern = PATTERN (insn);
7507 if (GET_CODE (pattern) != SET
7508 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
7509 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
7510 continue;
7512 /* Now check if the jump is beyond the s9 range. */
7513 if (CROSSING_JUMP_P (insn))
7514 continue;
7515 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7517 if(offset > 253 || offset < -254)
7518 continue;
7520 pc_target = SET_SRC (pattern);
7522 /* Avoid FPU instructions. */
7523 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
7524 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
7525 continue;
7527 /* Now go back and search for the set cc insn. */
7529 label = XEXP (pc_target, 1);
7532 rtx pat;
7533 rtx_insn *scan, *link_insn = NULL;
7535 for (scan = PREV_INSN (insn);
7536 scan && GET_CODE (scan) != CODE_LABEL;
7537 scan = PREV_INSN (scan))
7539 if (! INSN_P (scan))
7540 continue;
7541 pat = PATTERN (scan);
7542 if (GET_CODE (pat) == SET
7543 && cc_register (SET_DEST (pat), VOIDmode))
7545 link_insn = scan;
7546 break;
7549 if (!link_insn)
7550 continue;
7551 else
7552 /* Check if this is a data dependency. */
7554 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
7555 rtx cmp0, cmp1;
7557 /* Ok this is the set cc. copy args here. */
7558 op = XEXP (pc_target, 0);
7560 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
7561 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
7562 if (GET_CODE (op0) == ZERO_EXTRACT
7563 && XEXP (op0, 1) == const1_rtx
7564 && (GET_CODE (op) == EQ
7565 || GET_CODE (op) == NE))
7567 /* btst / b{eq,ne} -> bbit{0,1} */
7568 op0 = XEXP (cmp0, 0);
7569 op1 = XEXP (cmp0, 2);
7571 else if (!register_operand (op0, VOIDmode)
7572 || !general_operand (op1, VOIDmode))
7573 continue;
7574 /* Be careful not to break what cmpsfpx_raw is
7575 trying to create for checking equality of
7576 single-precision floats. */
7577 else if (TARGET_SPFP
7578 && GET_MODE (op0) == SFmode
7579 && GET_MODE (op1) == SFmode)
7580 continue;
7582 /* None of the two cmp operands should be set between the
7583 cmp and the branch. */
7584 if (reg_set_between_p (op0, link_insn, insn))
7585 continue;
7587 if (reg_set_between_p (op1, link_insn, insn))
7588 continue;
7590 /* Since the MODE check does not work, check that this is
7591 CC reg's last set location before insn, and also no
7592 instruction between the cmp and branch uses the
7593 condition codes. */
7594 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
7595 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
7596 continue;
7598 /* CC reg should be dead after insn. */
7599 if (!find_regno_note (insn, REG_DEAD, CC_REG))
7600 continue;
7602 op = gen_rtx_fmt_ee (GET_CODE (op),
7603 GET_MODE (op), cmp0, cmp1);
7604 /* If we create a LIMM where there was none before,
7605 we only benefit if we can avoid a scheduling bubble
7606 for the ARC600. Otherwise, we'd only forgo chances
7607 at short insn generation, and risk out-of-range
7608 branches. */
7609 if (!brcc_nolimm_operator (op, VOIDmode)
7610 && !long_immediate_operand (op1, VOIDmode)
7611 && (TARGET_ARC700
7612 || next_active_insn (link_insn) != insn))
7613 continue;
7615 /* Emit bbit / brcc (or brcc_s if possible).
7616 CC_Zmode indicates that brcc_s is possible. */
7618 if (op0 != cmp0)
7619 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
7620 else if ((offset >= -140 && offset < 140)
7621 && rtx_equal_p (op1, const0_rtx)
7622 && compact_register_operand (op0, VOIDmode)
7623 && (GET_CODE (op) == EQ
7624 || GET_CODE (op) == NE))
7625 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
7626 else
7627 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
7629 brcc_insn
7630 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
7631 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
7632 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
7633 brcc_insn
7634 = gen_rtx_PARALLEL
7635 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
7636 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
7638 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
7639 note = find_reg_note (insn, REG_BR_PROB, 0);
7640 if (note)
7642 XEXP (note, 1) = REG_NOTES (brcc_insn);
7643 REG_NOTES (brcc_insn) = note;
7645 note = find_reg_note (link_insn, REG_DEAD, op0);
7646 if (note)
7648 remove_note (link_insn, note);
7649 XEXP (note, 1) = REG_NOTES (brcc_insn);
7650 REG_NOTES (brcc_insn) = note;
7652 note = find_reg_note (link_insn, REG_DEAD, op1);
7653 if (note)
7655 XEXP (note, 1) = REG_NOTES (brcc_insn);
7656 REG_NOTES (brcc_insn) = note;
7659 changed = 1;
7661 /* Delete the bcc insn. */
7662 set_insn_deleted (insn);
7664 /* Delete the cmp insn. */
7665 set_insn_deleted (link_insn);
7670 /* Clear out insn_addresses. */
7671 INSN_ADDRESSES_FREE ();
7673 } while (changed);
7675 if (INSN_ADDRESSES_SET_P())
7676 fatal_error (input_location, "insn addresses not freed");
7678 arc_reorg_in_progress = 0;
7681 /* Check if the operands are valid for BRcc.d generation
7682 Valid Brcc.d patterns are
7683 Brcc.d b, c, s9
7684 Brcc.d b, u6, s9
7686 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7687 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7688 does not have a delay slot
7690 Assumed precondition: Second operand is either a register or a u6 value. */
7692 bool
7693 valid_brcc_with_delay_p (rtx *operands)
7695 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
7696 return false;
7697 return brcc_nolimm_operator (operands[0], VOIDmode);
7700 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7701 access DECL using %gp_rel(...)($gp). */
7703 static bool
7704 arc_in_small_data_p (const_tree decl)
7706 HOST_WIDE_INT size;
7708 /* Only variables are going into small data area. */
7709 if (TREE_CODE (decl) != VAR_DECL)
7710 return false;
7712 if (TARGET_NO_SDATA_SET)
7713 return false;
7715 /* Disable sdata references to weak variables. */
7716 if (DECL_WEAK (decl))
7717 return false;
7719 /* Don't put constants into the small data section: we want them to
7720 be in ROM rather than RAM. */
7721 if (TREE_READONLY (decl))
7722 return false;
7724 /* To ensure -mvolatile-cache works ld.di does not have a
7725 gp-relative variant. */
7726 if (!TARGET_VOLATILE_CACHE_SET
7727 && TREE_THIS_VOLATILE (decl))
7728 return false;
7730 if (DECL_SECTION_NAME (decl) != 0)
7732 const char *name = DECL_SECTION_NAME (decl);
7733 if (strcmp (name, ".sdata") == 0
7734 || strcmp (name, ".sbss") == 0)
7735 return true;
7737 /* If it's not public, there's no need to put it in the small data
7738 section. */
7739 else if (TREE_PUBLIC (decl))
7741 size = int_size_in_bytes (TREE_TYPE (decl));
7742 return (size > 0 && size <= g_switch_value);
7744 return false;
7747 /* Return true if X is a small data address that can be rewritten
7748 as a gp+symref. */
7750 static bool
7751 arc_rewrite_small_data_p (const_rtx x)
7753 if (GET_CODE (x) == CONST)
7754 x = XEXP (x, 0);
7756 if (GET_CODE (x) == PLUS)
7758 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
7759 x = XEXP (x, 0);
7762 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
7764 gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0);
7765 return true;
7767 return false;
7770 /* If possible, rewrite OP so that it refers to small data using
7771 explicit relocations. */
7773 static rtx
7774 arc_rewrite_small_data_1 (rtx op)
7776 rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
7777 op = copy_insn (op);
7778 subrtx_ptr_iterator::array_type array;
7779 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
7781 rtx *loc = *iter;
7782 if (arc_rewrite_small_data_p (*loc))
7784 *loc = gen_rtx_PLUS (Pmode, rgp, *loc);
7785 iter.skip_subrtxes ();
7787 else if (GET_CODE (*loc) == PLUS
7788 && rtx_equal_p (XEXP (*loc, 0), rgp))
7789 iter.skip_subrtxes ();
7791 return op;
7795 arc_rewrite_small_data (rtx op)
7797 op = arc_rewrite_small_data_1 (op);
7799 /* Check if we fit small data constraints. */
7800 if (MEM_P (op)
7801 && !LEGITIMATE_SMALL_DATA_ADDRESS_P (XEXP (op, 0)))
7803 rtx addr = XEXP (op, 0);
7804 rtx tmp = gen_reg_rtx (Pmode);
7805 emit_move_insn (tmp, addr);
7806 op = replace_equiv_address_nv (op, tmp);
7808 return op;
7811 /* Return true if OP refers to small data symbols directly, not through
7812 a PLUS. */
7814 bool
7815 small_data_pattern (rtx op, machine_mode)
7817 if (GET_CODE (op) == SEQUENCE)
7818 return false;
7820 rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
7821 subrtx_iterator::array_type array;
7822 FOR_EACH_SUBRTX (iter, array, op, ALL)
7824 const_rtx x = *iter;
7825 if (GET_CODE (x) == PLUS
7826 && rtx_equal_p (XEXP (x, 0), rgp))
7827 iter.skip_subrtxes ();
7828 else if (arc_rewrite_small_data_p (x))
7829 return true;
7831 return false;
7834 /* Return true if OP is an acceptable memory operand for ARCompact
7835 16-bit gp-relative load instructions.
7836 op shd look like : [r26, symref@sda]
7837 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
7839 /* volatile cache option still to be handled. */
7841 bool
7842 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
7844 rtx addr;
7845 int size;
7846 tree decl = NULL_TREE;
7847 int align = 0;
7848 int mask = 0;
7850 /* Eliminate non-memory operations. */
7851 if (GET_CODE (op) != MEM)
7852 return false;
7854 if (mode == VOIDmode)
7855 mode = GET_MODE (op);
7857 size = GET_MODE_SIZE (mode);
7859 /* dword operations really put out 2 instructions, so eliminate them. */
7860 if (size > UNITS_PER_WORD)
7861 return false;
7863 /* Decode the address now. */
7864 addr = XEXP (op, 0);
7866 if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr))
7867 return false;
7869 if (!short_p || size == 1)
7870 return true;
7872 /* Now check for the alignment, the short loads using gp require the
7873 addresses to be aligned. */
7874 if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
7875 decl = SYMBOL_REF_DECL (XEXP (addr, 1));
7876 else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0)) == SYMBOL_REF)
7877 decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
7878 if (decl)
7879 align = DECL_ALIGN (decl);
7880 align = align / BITS_PER_UNIT;
7882 switch (mode)
7884 case E_HImode:
7885 mask = 1;
7886 break;
7887 default:
7888 mask = 3;
7889 break;
7892 if (align && ((align & mask) == 0))
7893 return true;
7894 return false;
7897 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
7899 void
7900 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
7901 unsigned HOST_WIDE_INT size,
7902 unsigned HOST_WIDE_INT align,
7903 unsigned HOST_WIDE_INT globalize_p)
7905 int in_small_data = arc_in_small_data_p (decl);
7907 if (in_small_data)
7908 switch_to_section (get_named_section (NULL, ".sbss", 0));
7909 /* named_section (0,".sbss",0); */
7910 else
7911 switch_to_section (bss_section);
7913 if (globalize_p)
7914 (*targetm.asm_out.globalize_label) (stream, name);
7916 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
7917 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
7918 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
7919 ASM_OUTPUT_LABEL (stream, name);
7921 if (size != 0)
7922 ASM_OUTPUT_SKIP (stream, size);
7925 static bool
7926 arc_preserve_reload_p (rtx in)
7928 return (GET_CODE (in) == PLUS
7929 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
7930 && CONST_INT_P (XEXP (in, 1))
7931 && !((INTVAL (XEXP (in, 1)) & 511)));
7935 arc_register_move_cost (machine_mode,
7936 enum reg_class from_class, enum reg_class to_class)
7938 /* The ARC600 has no bypass for extension registers, hence a nop might be
7939 needed to be inserted after a write so that reads are safe. */
7940 if (TARGET_ARC600)
7942 if (to_class == MPY_WRITABLE_CORE_REGS)
7943 return 3;
7944 /* Instructions modifying LP_COUNT need 4 additional cycles before
7945 the register will actually contain the value. */
7946 else if (to_class == LPCOUNT_REG)
7947 return 6;
7948 else if (to_class == WRITABLE_CORE_REGS)
7949 return 6;
7952 /* Using lp_count as scratch reg is a VERY bad idea. */
7953 if (from_class == LPCOUNT_REG)
7954 return 1000;
7955 if (to_class == LPCOUNT_REG)
7956 return 6;
7958 /* Force an attempt to 'mov Dy,Dx' to spill. */
7959 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
7960 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
7961 return 100;
7963 return 2;
7966 /* Emit code for an addsi3 instruction with OPERANDS.
7967 COND_P indicates if this will use conditional execution.
7968 Return the length of the instruction.
7969 If OUTPUT_P is false, don't actually output the instruction, just return
7970 its length. */
7972 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
7974 char format[35];
7976 int match = operands_match_p (operands[0], operands[1]);
7977 int match2 = operands_match_p (operands[0], operands[2]);
7978 int intval = (REG_P (operands[2]) ? 1
7979 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
7980 int neg_intval = -intval;
7981 int short_0 = satisfies_constraint_Rcq (operands[0]);
7982 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
7983 int ret = 0;
7985 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
7986 && REGNO (OP) != 30) \
7987 || !TARGET_V2))
7989 #define ADDSI_OUTPUT1(FORMAT) do {\
7990 if (output_p) \
7991 output_asm_insn (FORMAT, operands);\
7992 return ret; \
7993 } while (0)
7994 #define ADDSI_OUTPUT(LIST) do {\
7995 if (output_p) \
7996 sprintf LIST;\
7997 ADDSI_OUTPUT1 (format);\
7998 return ret; \
7999 } while (0)
8001 /* First try to emit a 16 bit insn. */
8002 ret = 2;
8003 if (!cond_p
8004 /* If we are actually about to output this insn, don't try a 16 bit
8005 variant if we already decided that we don't want that
8006 (I.e. we upsized this insn to align some following insn.)
8007 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8008 but add1 r0,sp,35 doesn't. */
8009 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8011 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8012 patterns. */
8013 if (short_p
8014 && ((REG_H_P (operands[2])
8015 && (match || satisfies_constraint_Rcq (operands[2])))
8016 || (CONST_INT_P (operands[2])
8017 && ((unsigned) intval <= (match ? 127 : 7)))))
8018 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8020 /* Generate add_s b,b,h patterns. */
8021 if (short_0 && match2 && REG_H_P (operands[1]))
8022 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8024 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8025 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8026 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8027 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8029 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8030 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8031 && match && !(neg_intval & ~124)))
8032 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8034 /* Generate add_s h,h,s3 patterns. */
8035 if (REG_H_P (operands[0]) && match && TARGET_V2
8036 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8037 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8039 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8040 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8041 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8042 && satisfies_constraint_Rcq (operands[1])
8043 && satisfies_constraint_L (operands[2]))
8044 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8047 /* Now try to emit a 32 bit insn without long immediate. */
8048 ret = 4;
8049 if (!match && match2 && REG_P (operands[1]))
8050 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8051 if (match || !cond_p)
8053 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8054 int range_factor = neg_intval & intval;
8055 int shift;
8057 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8058 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8060 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8061 same size, do, so - the insn latency is lower. */
8062 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8063 0x800 is not. */
8064 if ((intval >= 0 && intval <= limit)
8065 || (intval == -0x800 && limit == 0x7ff))
8066 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8067 else if ((intval < 0 && neg_intval <= limit)
8068 || (intval == 0x800 && limit == 0x7ff))
8069 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8070 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
8071 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
8072 gcc_assert ((((1 << shift) - 1) & intval) == 0);
8073 if (((intval < 0 && intval != -0x4000)
8074 /* sub[123] is slower than add_s / sub, only use it if it
8075 avoids a long immediate. */
8076 && neg_intval <= limit << shift)
8077 || (intval == 0x4000 && limit == 0x7ff))
8078 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
8079 shift, neg_intval >> shift));
8080 else if ((intval >= 0 && intval <= limit << shift)
8081 || (intval == -0x4000 && limit == 0x7ff))
8082 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
8084 /* Try to emit a 16 bit opcode with long immediate. */
8085 ret = 6;
8086 if (short_p && match)
8087 ADDSI_OUTPUT1 ("add%? %0,%1,%S2");
8089 /* We have to use a 32 bit opcode, and with a long immediate. */
8090 ret = 8;
8091 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%S2");
8094 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8095 Return the length of the instruction.
8096 If OUTPUT_P is false, don't actually output the instruction, just return
8097 its length. */
8099 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
8101 enum rtx_code commutative_op = GET_CODE (operands[3]);
8102 const char *pat = NULL;
8104 /* Canonical rtl should not have a constant in the first operand position. */
8105 gcc_assert (!CONSTANT_P (operands[1]));
8107 switch (commutative_op)
8109 case AND:
8110 if (satisfies_constraint_C1p (operands[2]))
8111 pat = "bmsk%? %0,%1,%Z2";
8112 else if (satisfies_constraint_C2p (operands[2]))
8114 operands[2] = GEN_INT ((~INTVAL (operands[2])));
8115 pat = "bmskn%? %0,%1,%Z2";
8117 else if (satisfies_constraint_Ccp (operands[2]))
8118 pat = "bclr%? %0,%1,%M2";
8119 else if (satisfies_constraint_CnL (operands[2]))
8120 pat = "bic%? %0,%1,%n2-1";
8121 break;
8122 case IOR:
8123 if (satisfies_constraint_C0p (operands[2]))
8124 pat = "bset%? %0,%1,%z2";
8125 break;
8126 case XOR:
8127 if (satisfies_constraint_C0p (operands[2]))
8128 pat = "bxor%? %0,%1,%z2";
8129 break;
8130 case PLUS:
8131 return arc_output_addsi (operands, true, output_p);
8132 default: break;
8134 if (output_p)
8135 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
8136 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
8137 return 4;
8138 return 8;
8141 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8142 Emit code and return an potentially modified address such that offsets
8143 up to SIZE are can be added to yield a legitimate address.
8144 if REUSE is set, ADDR is a register that may be modified. */
8146 static rtx
8147 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
8149 rtx base = addr;
8150 rtx offs = const0_rtx;
8152 if (GET_CODE (base) == PLUS)
8154 offs = XEXP (base, 1);
8155 base = XEXP (base, 0);
8157 if (!REG_P (base)
8158 || (REGNO (base) != STACK_POINTER_REGNUM
8159 && REGNO_PTR_FRAME_P (REGNO (base)))
8160 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
8161 || !SMALL_INT (INTVAL (offs) + size))
8163 if (reuse)
8164 emit_insn (gen_add2_insn (addr, offs));
8165 else
8166 addr = copy_to_mode_reg (Pmode, addr);
8168 return addr;
8171 /* Like move_by_pieces, but take account of load latency, and actual
8172 offset ranges. Return true on success. */
8174 bool
8175 arc_expand_movmem (rtx *operands)
8177 rtx dst = operands[0];
8178 rtx src = operands[1];
8179 rtx dst_addr, src_addr;
8180 HOST_WIDE_INT size;
8181 int align = INTVAL (operands[3]);
8182 unsigned n_pieces;
8183 int piece = align;
8184 rtx store[2];
8185 rtx tmpx[2];
8186 int i;
8188 if (!CONST_INT_P (operands[2]))
8189 return false;
8190 size = INTVAL (operands[2]);
8191 /* move_by_pieces_ninsns is static, so we can't use it. */
8192 if (align >= 4)
8194 if (TARGET_LL64)
8195 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
8196 else
8197 n_pieces = (size + 2) / 4U + (size & 1);
8199 else if (align == 2)
8200 n_pieces = (size + 1) / 2U;
8201 else
8202 n_pieces = size;
8203 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
8204 return false;
8205 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8206 possible. */
8207 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
8208 piece = 8;
8209 else if (piece > 4)
8210 piece = 4;
8211 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
8212 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
8213 store[0] = store[1] = NULL_RTX;
8214 tmpx[0] = tmpx[1] = NULL_RTX;
8215 for (i = 0; size > 0; i ^= 1, size -= piece)
8217 rtx tmp;
8218 machine_mode mode;
8220 while (piece > size)
8221 piece >>= 1;
8222 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
8223 /* If we don't re-use temporaries, the scheduler gets carried away,
8224 and the register pressure gets unnecessarily high. */
8225 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
8226 tmp = tmpx[i];
8227 else
8228 tmpx[i] = tmp = gen_reg_rtx (mode);
8229 dst_addr = force_offsettable (dst_addr, piece, 1);
8230 src_addr = force_offsettable (src_addr, piece, 1);
8231 if (store[i])
8232 emit_insn (store[i]);
8233 emit_move_insn (tmp, change_address (src, mode, src_addr));
8234 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
8235 dst_addr = plus_constant (Pmode, dst_addr, piece);
8236 src_addr = plus_constant (Pmode, src_addr, piece);
8238 if (store[i])
8239 emit_insn (store[i]);
8240 if (store[i^1])
8241 emit_insn (store[i^1]);
8242 return true;
8245 /* Prepare operands for move in MODE. Return true iff the move has
8246 been emitted. */
8248 bool
8249 prepare_move_operands (rtx *operands, machine_mode mode)
8251 /* We used to do this only for MODE_INT Modes, but addresses to floating
8252 point variables may well be in the small data section. */
8253 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
8254 operands[0] = arc_rewrite_small_data (operands[0]);
8256 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
8258 prepare_pic_move (operands, SImode);
8260 /* Disable any REG_EQUALs associated with the symref
8261 otherwise the optimization pass undoes the work done
8262 here and references the variable directly. */
8265 if (GET_CODE (operands[0]) != MEM
8266 && !TARGET_NO_SDATA_SET
8267 && small_data_pattern (operands[1], Pmode))
8269 /* This is to take care of address calculations involving sdata
8270 variables. */
8271 operands[1] = arc_rewrite_small_data (operands[1]);
8273 emit_insn (gen_rtx_SET (operands[0],operands[1]));
8274 /* ??? This note is useless, since it only restates the set itself.
8275 We should rather use the original SYMBOL_REF. However, there is
8276 the problem that we are lying to the compiler about these
8277 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8278 so that we can tell it apart from an actual symbol. */
8279 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
8281 /* Take care of the REG_EQUAL note that will be attached to mark the
8282 output reg equal to the initial symbol_ref after this code is
8283 executed. */
8284 emit_move_insn (operands[0], operands[0]);
8285 return true;
8288 if (MEM_P (operands[0])
8289 && !(reload_in_progress || reload_completed))
8291 operands[1] = force_reg (mode, operands[1]);
8292 if (!move_dest_operand (operands[0], mode))
8294 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8295 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8296 except that we can't use that function because it is static. */
8297 rtx pat = change_address (operands[0], mode, addr);
8298 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8299 operands[0] = pat;
8301 if (!cse_not_expected)
8303 rtx pat = XEXP (operands[0], 0);
8305 pat = arc_legitimize_address_0 (pat, pat, mode);
8306 if (pat)
8308 pat = change_address (operands[0], mode, pat);
8309 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8310 operands[0] = pat;
8315 if (MEM_P (operands[1]) && !cse_not_expected)
8317 rtx pat = XEXP (operands[1], 0);
8319 pat = arc_legitimize_address_0 (pat, pat, mode);
8320 if (pat)
8322 pat = change_address (operands[1], mode, pat);
8323 MEM_COPY_ATTRIBUTES (pat, operands[1]);
8324 operands[1] = pat;
8328 return false;
8331 /* Prepare OPERANDS for an extension using CODE to OMODE.
8332 Return true iff the move has been emitted. */
8334 bool
8335 prepare_extend_operands (rtx *operands, enum rtx_code code,
8336 machine_mode omode)
8338 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
8340 /* This is to take care of address calculations involving sdata
8341 variables. */
8342 operands[1]
8343 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
8344 emit_insn (gen_rtx_SET (operands[0], operands[1]));
8345 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
8347 /* Take care of the REG_EQUAL note that will be attached to mark the
8348 output reg equal to the initial extension after this code is
8349 executed. */
8350 emit_move_insn (operands[0], operands[0]);
8351 return true;
8353 return false;
8356 /* Output a library call to a function called FNAME that has been arranged
8357 to be local to any dso. */
8359 const char *
8360 arc_output_libcall (const char *fname)
8362 unsigned len = strlen (fname);
8363 static char buf[64];
8365 gcc_assert (len < sizeof buf - 35);
8366 if (TARGET_LONG_CALLS_SET
8367 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
8369 if (flag_pic)
8370 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
8371 else
8372 sprintf (buf, "jl%%! @%s", fname);
8374 else
8375 sprintf (buf, "bl%%!%%* @%s", fname);
8376 return buf;
8379 /* Return the SImode highpart of the DImode value IN. */
8382 disi_highpart (rtx in)
8384 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
8387 /* Return length adjustment for INSN.
8388 For ARC600:
8389 A write to a core reg greater or equal to 32 must not be immediately
8390 followed by a use. Anticipate the length requirement to insert a nop
8391 between PRED and SUCC to prevent a hazard. */
8393 static int
8394 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
8396 if (!TARGET_ARC600)
8397 return 0;
8398 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
8399 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
8400 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
8401 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
8402 if (recog_memoized (pred) == CODE_FOR_mulsi_600
8403 || recog_memoized (pred) == CODE_FOR_umul_600
8404 || recog_memoized (pred) == CODE_FOR_mac_600
8405 || recog_memoized (pred) == CODE_FOR_mul64_600
8406 || recog_memoized (pred) == CODE_FOR_mac64_600
8407 || recog_memoized (pred) == CODE_FOR_umul64_600
8408 || recog_memoized (pred) == CODE_FOR_umac64_600)
8409 return 0;
8410 subrtx_iterator::array_type array;
8411 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
8413 const_rtx x = *iter;
8414 switch (GET_CODE (x))
8416 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8417 break;
8418 default:
8419 /* This is also fine for PRE/POST_MODIFY, because they
8420 contain a SET. */
8421 continue;
8423 rtx dest = XEXP (x, 0);
8424 /* Check if this sets a an extension register. N.B. we use 61 for the
8425 condition codes, which is definitely not an extension register. */
8426 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
8427 /* Check if the same register is used by the PAT. */
8428 && (refers_to_regno_p
8429 (REGNO (dest),
8430 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
8431 PATTERN (succ), 0)))
8432 return 4;
8434 return 0;
8437 /* Given a rtx, check if it is an assembly instruction or not. */
8439 static int
8440 arc_asm_insn_p (rtx x)
8442 int i, j;
8444 if (x == 0)
8445 return 0;
8447 switch (GET_CODE (x))
8449 case ASM_OPERANDS:
8450 case ASM_INPUT:
8451 return 1;
8453 case SET:
8454 return arc_asm_insn_p (SET_SRC (x));
8456 case PARALLEL:
8457 j = 0;
8458 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8459 j += arc_asm_insn_p (XVECEXP (x, 0, i));
8460 if ( j > 0)
8461 return 1;
8462 break;
8464 default:
8465 break;
8468 return 0;
8471 /* For ARC600:
8472 A write to a core reg greater or equal to 32 must not be immediately
8473 followed by a use. Anticipate the length requirement to insert a nop
8474 between PRED and SUCC to prevent a hazard. */
8477 arc_hazard (rtx_insn *pred, rtx_insn *succ)
8479 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
8480 return 0;
8482 if (TARGET_ARC600)
8483 return arc600_corereg_hazard (pred, succ);
8485 return 0;
8488 /* Return length adjustment for INSN. */
8491 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
8493 if (!INSN_P (insn))
8494 return len;
8495 /* We already handle sequences by ignoring the delay sequence flag. */
8496 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
8497 return len;
8499 /* Check for return with but one preceding insn since function
8500 start / call. */
8501 if (TARGET_PAD_RETURN
8502 && JUMP_P (insn)
8503 && GET_CODE (PATTERN (insn)) != ADDR_VEC
8504 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
8505 && get_attr_type (insn) == TYPE_RETURN)
8507 rtx_insn *prev = prev_active_insn (insn);
8509 if (!prev || !(prev = prev_active_insn (prev))
8510 || ((NONJUMP_INSN_P (prev)
8511 && GET_CODE (PATTERN (prev)) == SEQUENCE)
8512 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8513 NON_SIBCALL)
8514 : CALL_ATTR (prev, NON_SIBCALL)))
8515 return len + 4;
8517 if (TARGET_ARC600)
8519 rtx_insn *succ = next_real_insn (insn);
8521 /* One the ARC600, a write to an extension register must be separated
8522 from a read. */
8523 if (succ && INSN_P (succ))
8524 len += arc600_corereg_hazard (insn, succ);
8527 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8528 can go awry. */
8529 extract_constrain_insn_cached (insn);
8531 return len;
8534 /* Values for length_sensitive. */
8535 enum
8537 ARC_LS_NONE,// Jcc
8538 ARC_LS_25, // 25 bit offset, B
8539 ARC_LS_21, // 21 bit offset, Bcc
8540 ARC_LS_U13,// 13 bit unsigned offset, LP
8541 ARC_LS_10, // 10 bit offset, B_s, Beq_s, Bne_s
8542 ARC_LS_9, // 9 bit offset, BRcc
8543 ARC_LS_8, // 8 bit offset, BRcc_s
8544 ARC_LS_U7, // 7 bit unsigned offset, LPcc
8545 ARC_LS_7 // 7 bit offset, Bcc_s
8548 /* While the infrastructure patch is waiting for review, duplicate the
8549 struct definitions, to allow this file to compile. */
8550 #if 1
8551 typedef struct
8553 unsigned align_set;
8554 /* Cost as a branch / call target or call return address. */
8555 int target_cost;
8556 int fallthrough_cost;
8557 int branch_cost;
8558 int length;
8559 /* 0 for not length sensitive, 1 for largest offset range,
8560 * 2 for next smaller etc. */
8561 unsigned length_sensitive : 8;
8562 bool enabled;
8563 } insn_length_variant_t;
8565 typedef struct insn_length_parameters_s
8567 int align_unit_log;
8568 int align_base_log;
8569 int max_variants;
8570 int (*get_variants) (rtx_insn *, int, bool, bool, insn_length_variant_t *);
8571 } insn_length_parameters_t;
8573 static void
8574 arc_insn_length_parameters (insn_length_parameters_t *ilp) ATTRIBUTE_UNUSED;
8575 #endif
8577 static int
8578 arc_get_insn_variants (rtx_insn *insn, int len, bool, bool target_p,
8579 insn_length_variant_t *ilv)
8581 if (!NONDEBUG_INSN_P (insn))
8582 return 0;
8583 enum attr_type type;
8584 /* shorten_branches doesn't take optimize_size into account yet for the
8585 get_variants mechanism, so turn this off for now. */
8586 if (optimize_size)
8587 return 0;
8588 if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
8590 /* The interaction of a short delay slot insn with a short branch is
8591 too weird for shorten_branches to piece together, so describe the
8592 entire SEQUENCE. */
8593 rtx_insn *inner;
8594 if (TARGET_UPSIZE_DBR
8595 && get_attr_length (pat->insn (1)) <= 2
8596 && (((type = get_attr_type (inner = pat->insn (0)))
8597 == TYPE_UNCOND_BRANCH)
8598 || type == TYPE_BRANCH)
8599 && get_attr_delay_slot_filled (inner) == DELAY_SLOT_FILLED_YES)
8601 int n_variants
8602 = arc_get_insn_variants (inner, get_attr_length (inner), true,
8603 target_p, ilv+1);
8604 /* The short variant gets split into a higher-cost aligned
8605 and a lower cost unaligned variant. */
8606 gcc_assert (n_variants);
8607 gcc_assert (ilv[1].length_sensitive == ARC_LS_7
8608 || ilv[1].length_sensitive == ARC_LS_10);
8609 gcc_assert (ilv[1].align_set == 3);
8610 ilv[0] = ilv[1];
8611 ilv[0].align_set = 1;
8612 ilv[0].branch_cost += 1;
8613 ilv[1].align_set = 2;
8614 n_variants++;
8615 for (int i = 0; i < n_variants; i++)
8616 ilv[i].length += 2;
8617 /* In case an instruction with aligned size is wanted, and
8618 the short variants are unavailable / too expensive, add
8619 versions of long branch + long delay slot. */
8620 for (int i = 2, end = n_variants; i < end; i++, n_variants++)
8622 ilv[n_variants] = ilv[i];
8623 ilv[n_variants].length += 2;
8625 return n_variants;
8627 return 0;
8629 insn_length_variant_t *first_ilv = ilv;
8630 type = get_attr_type (insn);
8631 bool delay_filled
8632 = (get_attr_delay_slot_filled (insn) == DELAY_SLOT_FILLED_YES);
8633 int branch_align_cost = delay_filled ? 0 : 1;
8634 int branch_unalign_cost = delay_filled ? 0 : TARGET_UNALIGN_BRANCH ? 0 : 1;
8635 /* If the previous instruction is an sfunc call, this insn is always
8636 a target, even though the middle-end is unaware of this. */
8637 bool force_target = false;
8638 rtx_insn *prev = prev_active_insn (insn);
8639 if (prev && arc_next_active_insn (prev, 0) == insn
8640 && ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
8641 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8642 NON_SIBCALL)
8643 : (CALL_ATTR (prev, NON_SIBCALL)
8644 && NEXT_INSN (PREV_INSN (prev)) == prev)))
8645 force_target = true;
8647 switch (type)
8649 case TYPE_BRCC:
8650 /* Short BRCC only comes in no-delay-slot version, and without limm */
8651 if (!delay_filled)
8653 ilv->align_set = 3;
8654 ilv->length = 2;
8655 ilv->branch_cost = 1;
8656 ilv->enabled = (len == 2);
8657 ilv->length_sensitive = ARC_LS_8;
8658 ilv++;
8660 /* Fall through. */
8661 case TYPE_BRCC_NO_DELAY_SLOT:
8662 /* doloop_fallback* patterns are TYPE_BRCC_NO_DELAY_SLOT for
8663 (delay slot) scheduling purposes, but they are longer. */
8664 if (GET_CODE (PATTERN (insn)) == PARALLEL
8665 && GET_CODE (XVECEXP (PATTERN (insn), 0, 1)) == SET)
8666 return 0;
8667 /* Standard BRCC: 4 bytes, or 8 bytes with limm. */
8668 ilv->length = ((type == TYPE_BRCC) ? 4 : 8);
8669 ilv->align_set = 3;
8670 ilv->branch_cost = branch_align_cost;
8671 ilv->enabled = (len <= ilv->length);
8672 ilv->length_sensitive = ARC_LS_9;
8673 if ((target_p || force_target)
8674 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8676 ilv[1] = *ilv;
8677 ilv->align_set = 1;
8678 ilv++;
8679 ilv->align_set = 2;
8680 ilv->target_cost = 1;
8681 ilv->branch_cost = branch_unalign_cost;
8683 ilv++;
8685 rtx op, op0;
8686 op = XEXP (SET_SRC (XVECEXP (PATTERN (insn), 0, 0)), 0);
8687 op0 = XEXP (op, 0);
8689 if (GET_CODE (op0) == ZERO_EXTRACT
8690 && satisfies_constraint_L (XEXP (op0, 2)))
8691 op0 = XEXP (op0, 0);
8692 if (satisfies_constraint_Rcq (op0))
8694 ilv->length = ((type == TYPE_BRCC) ? 6 : 10);
8695 ilv->align_set = 3;
8696 ilv->branch_cost = 1 + branch_align_cost;
8697 ilv->fallthrough_cost = 1;
8698 ilv->enabled = true;
8699 ilv->length_sensitive = ARC_LS_21;
8700 if (!delay_filled && TARGET_UNALIGN_BRANCH)
8702 ilv[1] = *ilv;
8703 ilv->align_set = 1;
8704 ilv++;
8705 ilv->align_set = 2;
8706 ilv->branch_cost = 1 + branch_unalign_cost;
8708 ilv++;
8710 ilv->length = ((type == TYPE_BRCC) ? 8 : 12);
8711 ilv->align_set = 3;
8712 ilv->branch_cost = 1 + branch_align_cost;
8713 ilv->fallthrough_cost = 1;
8714 ilv->enabled = true;
8715 ilv->length_sensitive = ARC_LS_21;
8716 if ((target_p || force_target)
8717 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8719 ilv[1] = *ilv;
8720 ilv->align_set = 1;
8721 ilv++;
8722 ilv->align_set = 2;
8723 ilv->target_cost = 1;
8724 ilv->branch_cost = 1 + branch_unalign_cost;
8726 ilv++;
8727 break;
8729 case TYPE_SFUNC:
8730 ilv->length = 12;
8731 goto do_call;
8732 case TYPE_CALL_NO_DELAY_SLOT:
8733 ilv->length = 8;
8734 goto do_call;
8735 case TYPE_CALL:
8736 ilv->length = 4;
8737 ilv->length_sensitive
8738 = GET_CODE (PATTERN (insn)) == COND_EXEC ? ARC_LS_21 : ARC_LS_25;
8739 do_call:
8740 ilv->align_set = 3;
8741 ilv->fallthrough_cost = branch_align_cost;
8742 ilv->enabled = true;
8743 if ((target_p || force_target)
8744 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8746 ilv[1] = *ilv;
8747 ilv->align_set = 1;
8748 ilv++;
8749 ilv->align_set = 2;
8750 ilv->target_cost = 1;
8751 ilv->fallthrough_cost = branch_unalign_cost;
8753 ilv++;
8754 break;
8755 case TYPE_UNCOND_BRANCH:
8756 /* Strictly speaking, this should be ARC_LS_10 for equality comparisons,
8757 but that makes no difference at the moment. */
8758 ilv->length_sensitive = ARC_LS_7;
8759 ilv[1].length_sensitive = ARC_LS_25;
8760 goto do_branch;
8761 case TYPE_BRANCH:
8762 ilv->length_sensitive = ARC_LS_10;
8763 ilv[1].length_sensitive = ARC_LS_21;
8764 do_branch:
8765 ilv->align_set = 3;
8766 ilv->length = 2;
8767 ilv->branch_cost = branch_align_cost;
8768 ilv->enabled = (len == ilv->length);
8769 ilv++;
8770 ilv->length = 4;
8771 ilv->align_set = 3;
8772 ilv->branch_cost = branch_align_cost;
8773 ilv->enabled = true;
8774 if ((target_p || force_target)
8775 || (!delay_filled && TARGET_UNALIGN_BRANCH))
8777 ilv[1] = *ilv;
8778 ilv->align_set = 1;
8779 ilv++;
8780 ilv->align_set = 2;
8781 ilv->target_cost = 1;
8782 ilv->branch_cost = branch_unalign_cost;
8784 ilv++;
8785 break;
8786 case TYPE_JUMP:
8787 return 0;
8788 default:
8789 /* For every short insn, there is generally also a long insn.
8790 trap_s is an exception. */
8791 if ((len & 2) == 0 || recog_memoized (insn) == CODE_FOR_trap_s)
8792 return 0;
8793 ilv->align_set = 3;
8794 ilv->length = len;
8795 ilv->enabled = 1;
8796 ilv++;
8797 ilv->align_set = 3;
8798 ilv->length = len + 2;
8799 ilv->enabled = 1;
8800 if (target_p || force_target)
8802 ilv[1] = *ilv;
8803 ilv->align_set = 1;
8804 ilv++;
8805 ilv->align_set = 2;
8806 ilv->target_cost = 1;
8808 ilv++;
8810 /* If the previous instruction is an sfunc call, this insn is always
8811 a target, even though the middle-end is unaware of this.
8812 Therefore, if we have a call predecessor, transfer the target cost
8813 to the fallthrough and branch costs. */
8814 if (force_target)
8816 for (insn_length_variant_t *p = first_ilv; p < ilv; p++)
8818 p->fallthrough_cost += p->target_cost;
8819 p->branch_cost += p->target_cost;
8820 p->target_cost = 0;
8824 return ilv - first_ilv;
8827 static void
8828 arc_insn_length_parameters (insn_length_parameters_t *ilp)
8830 ilp->align_unit_log = 1;
8831 ilp->align_base_log = 1;
8832 ilp->max_variants = 7;
8833 ilp->get_variants = arc_get_insn_variants;
8836 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8837 CC field of *STATEP. */
8839 static rtx
8840 arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8842 rtx cond = statep->cond;
8843 int raw_cc = get_arc_condition_code (cond);
8844 if (reverse)
8845 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8847 if (statep->cc == raw_cc)
8848 return copy_rtx (cond);
8850 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8852 machine_mode ccm = GET_MODE (XEXP (cond, 0));
8853 enum rtx_code code = reverse_condition (GET_CODE (cond));
8854 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8855 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8857 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8858 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8861 /* Return version of PAT conditionalized with COND, which is part of INSN.
8862 ANNULLED indicates if INSN is an annulled delay-slot insn.
8863 Register further changes if necessary. */
8864 static rtx
8865 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8867 /* For commutative operators, we generally prefer to have
8868 the first source match the destination. */
8869 if (GET_CODE (pat) == SET)
8871 rtx src = SET_SRC (pat);
8873 if (COMMUTATIVE_P (src))
8875 rtx src0 = XEXP (src, 0);
8876 rtx src1 = XEXP (src, 1);
8877 rtx dst = SET_DEST (pat);
8879 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8880 /* Leave add_n alone - the canonical form is to
8881 have the complex summand first. */
8882 && REG_P (src0))
8883 pat = gen_rtx_SET (dst,
8884 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8885 src1, src0));
8889 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8890 what to do with COND_EXEC. */
8891 if (RTX_FRAME_RELATED_P (insn))
8893 /* If this is the delay slot insn of an anulled branch,
8894 dwarf2out.c:scan_trace understands the anulling semantics
8895 without the COND_EXEC. */
8896 gcc_assert (annulled);
8897 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8898 REG_NOTES (insn));
8899 validate_change (insn, &REG_NOTES (insn), note, 1);
8901 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8902 return pat;
8905 /* Use the ccfsm machinery to do if conversion. */
8907 static unsigned
8908 arc_ifcvt (void)
8910 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8912 memset (statep, 0, sizeof *statep);
8913 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
8915 arc_ccfsm_advance (insn, statep);
8917 switch (statep->state)
8919 case 0:
8920 break;
8921 case 1: case 2:
8923 /* Deleted branch. */
8924 arc_ccfsm_post_advance (insn, statep);
8925 gcc_assert (!IN_RANGE (statep->state, 1, 2));
8926 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
8927 if (GET_CODE (PATTERN (seq)) == SEQUENCE)
8929 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8930 rtx pat = PATTERN (slot);
8931 if (INSN_ANNULLED_BRANCH_P (insn))
8933 rtx cond
8934 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8935 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8937 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8938 gcc_unreachable ();
8939 PUT_CODE (slot, NOTE);
8940 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8942 else
8944 set_insn_deleted (insn);
8946 continue;
8948 case 3:
8949 if (LABEL_P (insn)
8950 && statep->target_label == CODE_LABEL_NUMBER (insn))
8952 arc_ccfsm_post_advance (insn, statep);
8953 if (--LABEL_NUSES (insn) == 0)
8954 delete_insn (insn);
8955 continue;
8957 /* Fall through. */
8958 case 4: case 5:
8959 if (!NONDEBUG_INSN_P (insn))
8960 break;
8962 /* Conditionalized insn. */
8964 rtx_insn *prev, *pprev;
8965 rtx *patp, pat, cond;
8966 bool annulled; annulled = false;
8968 /* If this is a delay slot insn in a non-annulled branch,
8969 don't conditionalize it. N.B., this should be fine for
8970 conditional return too. However, don't do this for
8971 unconditional branches, as these would be encountered when
8972 processing an 'else' part. */
8973 prev = PREV_INSN (insn);
8974 pprev = PREV_INSN (prev);
8975 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
8976 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8978 if (!INSN_ANNULLED_BRANCH_P (prev))
8979 break;
8980 annulled = true;
8983 patp = &PATTERN (insn);
8984 pat = *patp;
8985 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
8986 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
8988 /* ??? don't conditionalize if all side effects are dead
8989 in the not-execute case. */
8991 pat = conditionalize_nonjump (pat, cond, insn, annulled);
8993 else if (simplejump_p (insn))
8995 patp = &SET_SRC (pat);
8996 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
8998 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
9000 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
9001 pat = gen_rtx_SET (pc_rtx, pat);
9003 else
9004 gcc_unreachable ();
9005 validate_change (insn, patp, pat, 1);
9006 if (!apply_change_group ())
9007 gcc_unreachable ();
9008 if (JUMP_P (insn))
9010 rtx_insn *next = next_nonnote_insn (insn);
9011 if (GET_CODE (next) == BARRIER)
9012 delete_insn (next);
9013 if (statep->state == 3)
9014 continue;
9016 break;
9017 default:
9018 gcc_unreachable ();
9020 arc_ccfsm_post_advance (insn, statep);
9022 return 0;
9025 /* Find annulled delay insns and convert them to use the appropriate predicate.
9026 This allows branch shortening to size up these insns properly. */
9028 static unsigned
9029 arc_predicate_delay_insns (void)
9031 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9033 rtx pat, jump, dlay, src, cond, *patp;
9034 int reverse;
9036 if (!NONJUMP_INSN_P (insn)
9037 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9038 continue;
9039 jump = XVECEXP (pat, 0, 0);
9040 dlay = XVECEXP (pat, 0, 1);
9041 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9042 continue;
9043 /* If the branch insn does the annulling, leave the delay insn alone. */
9044 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9045 continue;
9046 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9047 on the other path. */
9048 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9049 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9050 src = SET_SRC (PATTERN (jump));
9051 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9052 cond = XEXP (src, 0);
9053 if (XEXP (src, 2) == pc_rtx)
9054 reverse = 0;
9055 else if (XEXP (src, 1) == pc_rtx)
9056 reverse = 1;
9057 else
9058 gcc_unreachable ();
9059 if (reverse != !INSN_FROM_TARGET_P (dlay))
9061 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9062 enum rtx_code code = reverse_condition (GET_CODE (cond));
9063 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9064 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9066 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9067 copy_rtx (XEXP (cond, 0)),
9068 copy_rtx (XEXP (cond, 1)));
9070 else
9071 cond = copy_rtx (cond);
9072 patp = &PATTERN (dlay);
9073 pat = *patp;
9074 pat = conditionalize_nonjump (pat, cond, dlay, true);
9075 validate_change (dlay, patp, pat, 1);
9076 if (!apply_change_group ())
9077 gcc_unreachable ();
9079 return 0;
9082 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9083 (other than of a forward brcc), it creates a hazard when there is a read
9084 of the same register at the branch target. We can't know what is at the
9085 branch target of calls, and for branches, we don't really know before the
9086 end of delay slot scheduling, either. Not only can individual instruction
9087 be hoisted out into a delay slot, a basic block can also be emptied this
9088 way, and branch and/or fall through targets be redirected. Hence we don't
9089 want such writes in a delay slot. */
9091 /* Return nonzreo iff INSN writes to an extension core register. */
9094 arc_write_ext_corereg (rtx insn)
9096 subrtx_iterator::array_type array;
9097 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9099 const_rtx x = *iter;
9100 switch (GET_CODE (x))
9102 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9103 break;
9104 default:
9105 /* This is also fine for PRE/POST_MODIFY, because they
9106 contain a SET. */
9107 continue;
9109 const_rtx dest = XEXP (x, 0);
9110 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9111 return 1;
9113 return 0;
9116 /* This is like the hook, but returns NULL when it can't / won't generate
9117 a legitimate address. */
9119 static rtx
9120 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9121 machine_mode mode)
9123 rtx addr, inner;
9125 if (flag_pic && SYMBOLIC_CONST (x))
9126 (x) = arc_legitimize_pic_address (x, 0);
9127 addr = x;
9128 if (GET_CODE (addr) == CONST)
9129 addr = XEXP (addr, 0);
9130 if (GET_CODE (addr) == PLUS
9131 && CONST_INT_P (XEXP (addr, 1))
9132 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9133 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9134 || (REG_P (XEXP (addr, 0))
9135 && (INTVAL (XEXP (addr, 1)) & 252))))
9137 HOST_WIDE_INT offs, upper;
9138 int size = GET_MODE_SIZE (mode);
9140 offs = INTVAL (XEXP (addr, 1));
9141 upper = (offs + 256 * size) & ~511 * size;
9142 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9143 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9144 if (GET_CODE (x) == CONST)
9145 inner = gen_rtx_CONST (Pmode, inner);
9146 #endif
9147 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9148 x = addr;
9150 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9151 x = force_reg (Pmode, x);
9152 if (memory_address_p ((machine_mode) mode, x))
9153 return x;
9154 return NULL_RTX;
9157 static rtx
9158 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9160 if (GET_CODE (orig_x) == SYMBOL_REF)
9162 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
9163 if (model != 0)
9164 return arc_legitimize_tls_address (orig_x, model);
9167 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9169 if (new_x)
9170 return new_x;
9171 return orig_x;
9174 static rtx
9175 arc_delegitimize_address_0 (rtx x)
9177 rtx u, gp, p;
9179 if (GET_CODE (x) == CONST && GET_CODE (u = XEXP (x, 0)) == UNSPEC)
9181 if (XINT (u, 1) == ARC_UNSPEC_GOT
9182 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC)
9183 return XVECEXP (u, 0, 0);
9185 else if (GET_CODE (x) == CONST && GET_CODE (p = XEXP (x, 0)) == PLUS
9186 && GET_CODE (u = XEXP (p, 0)) == UNSPEC
9187 && (XINT (u, 1) == ARC_UNSPEC_GOT
9188 || XINT (u, 1) == ARC_UNSPEC_GOTOFFPC))
9189 return gen_rtx_CONST
9190 (GET_MODE (x),
9191 gen_rtx_PLUS (GET_MODE (p), XVECEXP (u, 0, 0), XEXP (p, 1)));
9192 else if (GET_CODE (x) == PLUS
9193 && ((REG_P (gp = XEXP (x, 0))
9194 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
9195 || (GET_CODE (gp) == CONST
9196 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
9197 && XINT (u, 1) == ARC_UNSPEC_GOT
9198 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
9199 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
9200 && GET_CODE (XEXP (x, 1)) == CONST
9201 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
9202 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
9203 return XVECEXP (u, 0, 0);
9204 else if (GET_CODE (x) == PLUS && GET_CODE (XEXP (x, 0)) == PLUS
9205 && ((REG_P (gp = XEXP (XEXP (x, 0), 1))
9206 && REGNO (gp) == PIC_OFFSET_TABLE_REGNUM)
9207 || (GET_CODE (gp) == CONST
9208 && GET_CODE (u = XEXP (gp, 0)) == UNSPEC
9209 && XINT (u, 1) == ARC_UNSPEC_GOT
9210 && GET_CODE (XVECEXP (u, 0, 0)) == SYMBOL_REF
9211 && !strcmp (XSTR (XVECEXP (u, 0, 0), 0), "_DYNAMIC")))
9212 && GET_CODE (XEXP (x, 1)) == CONST
9213 && GET_CODE (u = XEXP (XEXP (x, 1), 0)) == UNSPEC
9214 && XINT (u, 1) == ARC_UNSPEC_GOTOFF)
9215 return gen_rtx_PLUS (GET_MODE (x), XEXP (XEXP (x, 0), 0),
9216 XVECEXP (u, 0, 0));
9217 else if (GET_CODE (x) == PLUS
9218 && (u = arc_delegitimize_address_0 (XEXP (x, 1))))
9219 return gen_rtx_PLUS (GET_MODE (x), XEXP (x, 0), u);
9220 return NULL_RTX;
9223 static rtx
9224 arc_delegitimize_address (rtx x)
9226 rtx orig_x = x = delegitimize_mem_from_attrs (x);
9227 if (GET_CODE (x) == MEM)
9228 x = XEXP (x, 0);
9229 x = arc_delegitimize_address_0 (x);
9230 if (x)
9232 if (MEM_P (orig_x))
9233 x = replace_equiv_address_nv (orig_x, x);
9234 return x;
9236 return orig_x;
9239 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9240 differ from the hardware register number in order to allow the generic
9241 code to correctly split the concatenation of acc1 and acc2. */
9244 gen_acc1 (void)
9246 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9249 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9250 differ from the hardware register number in order to allow the generic
9251 code to correctly split the concatenation of acc1 and acc2. */
9254 gen_acc2 (void)
9256 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9259 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9260 differ from the hardware register number in order to allow the generic
9261 code to correctly split the concatenation of mhi and mlo. */
9264 gen_mlo (void)
9266 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
9269 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9270 differ from the hardware register number in order to allow the generic
9271 code to correctly split the concatenation of mhi and mlo. */
9274 gen_mhi (void)
9276 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
9279 /* FIXME: a parameter should be added, and code added to final.c,
9280 to reproduce this functionality in shorten_branches. */
9281 #if 0
9282 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9283 a previous instruction. */
9285 arc_unalign_branch_p (rtx branch)
9287 rtx note;
9289 if (!TARGET_UNALIGN_BRANCH)
9290 return 0;
9291 /* Do not do this if we have a filled delay slot. */
9292 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
9293 && !NEXT_INSN (branch)->deleted ())
9294 return 0;
9295 note = find_reg_note (branch, REG_BR_PROB, 0);
9296 return (!note
9297 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
9298 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
9300 #endif
9302 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9303 are three reasons why we need to consider branches to be length 6:
9304 - annull-false delay slot insns are implemented using conditional execution,
9305 thus preventing short insn formation where used.
9306 - for ARC600: annul-true delay slot insns are implemented where possible
9307 using conditional execution, preventing short insn formation where used.
9308 - for ARC700: likely or somewhat likely taken branches are made long and
9309 unaligned if possible to avoid branch penalty. */
9311 bool
9312 arc_branch_size_unknown_p (void)
9314 return !optimize_size && arc_reorg_in_progress;
9317 /* We are about to output a return insn. Add padding if necessary to avoid
9318 a mispredict. A return could happen immediately after the function
9319 start, but after a call we know that there will be at least a blink
9320 restore. */
9322 void
9323 arc_pad_return (void)
9325 rtx_insn *insn = current_output_insn;
9326 rtx_insn *prev = prev_active_insn (insn);
9327 int want_long;
9329 if (!prev)
9331 fputs ("\tnop_s\n", asm_out_file);
9332 cfun->machine->unalign ^= 2;
9333 want_long = 1;
9335 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9336 because after a call, we'd have to restore blink first. */
9337 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
9338 return;
9339 else
9341 want_long = (get_attr_length (prev) == 2);
9342 prev = prev_active_insn (prev);
9344 if (!prev
9345 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
9346 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9347 NON_SIBCALL)
9348 : CALL_ATTR (prev, NON_SIBCALL)))
9350 if (want_long)
9351 cfun->machine->size_reason
9352 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9353 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
9355 cfun->machine->size_reason
9356 = "Long unaligned jump avoids non-delay slot penalty";
9357 want_long = 1;
9359 /* Disgorge delay insn, if there is any, and it may be moved. */
9360 if (final_sequence
9361 /* ??? Annulled would be OK if we can and do conditionalize
9362 the delay slot insn accordingly. */
9363 && !INSN_ANNULLED_BRANCH_P (insn)
9364 && (get_attr_cond (insn) != COND_USE
9365 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
9366 XVECEXP (final_sequence, 0, 1))))
9368 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
9369 gcc_assert (!prev_real_insn (insn)
9370 || !arc_hazard (prev_real_insn (insn), prev));
9371 cfun->machine->force_short_suffix = !want_long;
9372 rtx save_pred = current_insn_predicate;
9373 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
9374 cfun->machine->force_short_suffix = -1;
9375 prev->set_deleted ();
9376 current_output_insn = insn;
9377 current_insn_predicate = save_pred;
9379 else if (want_long)
9380 fputs ("\tnop\n", asm_out_file);
9381 else
9383 fputs ("\tnop_s\n", asm_out_file);
9384 cfun->machine->unalign ^= 2;
9387 return;
9390 /* The usual; we set up our machine_function data. */
9392 static struct machine_function *
9393 arc_init_machine_status (void)
9395 struct machine_function *machine;
9396 machine = ggc_cleared_alloc<machine_function> ();
9397 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9398 machine->force_short_suffix = -1;
9400 return machine;
9403 /* Implements INIT_EXPANDERS. We just set up to call the above
9404 function. */
9406 void
9407 arc_init_expanders (void)
9409 init_machine_status = arc_init_machine_status;
9412 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9413 indicates a number of elements to ignore - that allows to have a
9414 sibcall pattern that starts with (return). LOAD_P is zero for store
9415 multiple (for prologues), and one for load multiples (for epilogues),
9416 and two for load multiples where no final clobber of blink is required.
9417 We also skip the first load / store element since this is supposed to
9418 be checked in the instruction pattern. */
9421 arc_check_millicode (rtx op, int offset, int load_p)
9423 int len = XVECLEN (op, 0) - offset;
9424 int i;
9426 if (load_p == 2)
9428 if (len < 2 || len > 13)
9429 return 0;
9430 load_p = 1;
9432 else
9434 rtx elt = XVECEXP (op, 0, --len);
9436 if (GET_CODE (elt) != CLOBBER
9437 || !REG_P (XEXP (elt, 0))
9438 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9439 || len < 3 || len > 13)
9440 return 0;
9442 for (i = 1; i < len; i++)
9444 rtx elt = XVECEXP (op, 0, i + offset);
9445 rtx reg, mem, addr;
9447 if (GET_CODE (elt) != SET)
9448 return 0;
9449 mem = XEXP (elt, load_p);
9450 reg = XEXP (elt, 1-load_p);
9451 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9452 return 0;
9453 addr = XEXP (mem, 0);
9454 if (GET_CODE (addr) != PLUS
9455 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9456 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9457 return 0;
9459 return 1;
9462 /* Accessor functions for cfun->machine->unalign. */
9465 arc_get_unalign (void)
9467 return cfun->machine->unalign;
9470 void
9471 arc_clear_unalign (void)
9473 if (cfun)
9474 cfun->machine->unalign = 0;
9477 void
9478 arc_toggle_unalign (void)
9480 cfun->machine->unalign ^= 2;
9483 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9484 constant in operand 2, but which would require a LIMM because of
9485 operand mismatch.
9486 operands 3 and 4 are new SET_SRCs for operands 0. */
9488 void
9489 split_addsi (rtx *operands)
9491 int val = INTVAL (operands[2]);
9493 /* Try for two short insns first. Lengths being equal, we prefer
9494 expansions with shorter register lifetimes. */
9495 if (val > 127 && val <= 255
9496 && satisfies_constraint_Rcq (operands[0]))
9498 operands[3] = operands[2];
9499 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9501 else
9503 operands[3] = operands[1];
9504 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
9508 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9509 constant in operand 1, but which would require a LIMM because of
9510 operand mismatch.
9511 operands 3 and 4 are new SET_SRCs for operands 0. */
9513 void
9514 split_subsi (rtx *operands)
9516 int val = INTVAL (operands[1]);
9518 /* Try for two short insns first. Lengths being equal, we prefer
9519 expansions with shorter register lifetimes. */
9520 if (satisfies_constraint_Rcq (operands[0])
9521 && satisfies_constraint_Rcq (operands[2]))
9523 if (val >= -31 && val <= 127)
9525 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9526 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9527 return;
9529 else if (val >= 0 && val < 255)
9531 operands[3] = operands[1];
9532 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9533 return;
9536 /* If the destination is not an ARCompact16 register, we might
9537 still have a chance to make a short insn if the source is;
9538 we need to start with a reg-reg move for this. */
9539 operands[3] = operands[2];
9540 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9543 /* Handle DOUBLE_REGS uses.
9544 Operand 0: destination register
9545 Operand 1: source register */
9547 static bool
9548 arc_process_double_reg_moves (rtx *operands)
9550 rtx dest = operands[0];
9551 rtx src = operands[1];
9553 enum usesDxState { none, srcDx, destDx, maxDx };
9554 enum usesDxState state = none;
9556 if (refers_to_regno_p (40, 44, src, 0))
9557 state = srcDx;
9558 if (refers_to_regno_p (40, 44, dest, 0))
9560 /* Via arc_register_move_cost, we should never see D,D moves. */
9561 gcc_assert (state == none);
9562 state = destDx;
9565 if (state == none)
9566 return false;
9568 if (state == srcDx)
9570 /* Without the LR insn, we need to split this into a
9571 sequence of insns which will use the DEXCLx and DADDHxy
9572 insns to be able to read the Dx register in question. */
9573 if (TARGET_DPFP_DISABLE_LRSR)
9575 /* gen *movdf_insn_nolrsr */
9576 rtx set = gen_rtx_SET (dest, src);
9577 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9578 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9580 else
9582 /* When we have 'mov D, r' or 'mov D, D' then get the target
9583 register pair for use with LR insn. */
9584 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9585 TARGET_BIG_ENDIAN ? 0 : 4);
9586 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9587 TARGET_BIG_ENDIAN ? 4 : 0);
9589 /* Produce the two LR insns to get the high and low parts. */
9590 emit_insn (gen_rtx_SET (destHigh,
9591 gen_rtx_UNSPEC_VOLATILE (Pmode,
9592 gen_rtvec (1, src),
9593 VUNSPEC_ARC_LR_HIGH)));
9594 emit_insn (gen_rtx_SET (destLow,
9595 gen_rtx_UNSPEC_VOLATILE (Pmode,
9596 gen_rtvec (1, src),
9597 VUNSPEC_ARC_LR)));
9600 else if (state == destDx)
9602 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9603 LR insn get the target register pair. */
9604 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9605 TARGET_BIG_ENDIAN ? 0 : 4);
9606 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9607 TARGET_BIG_ENDIAN ? 4 : 0);
9609 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9611 else
9612 gcc_unreachable ();
9614 return true;
9617 /* operands 0..1 are the operands of a 64 bit move instruction.
9618 split it into two moves with operands 2/3 and 4/5. */
9620 void
9621 arc_split_move (rtx *operands)
9623 machine_mode mode = GET_MODE (operands[0]);
9624 int i;
9625 int swap = 0;
9626 rtx xop[4];
9628 if (TARGET_DPFP)
9630 if (arc_process_double_reg_moves (operands))
9631 return;
9634 if (TARGET_LL64
9635 && ((memory_operand (operands[0], mode)
9636 && even_register_operand (operands[1], mode))
9637 || (memory_operand (operands[1], mode)
9638 && even_register_operand (operands[0], mode))))
9640 emit_move_insn (operands[0], operands[1]);
9641 return;
9644 if (TARGET_PLUS_QMACW
9645 && GET_CODE (operands[1]) == CONST_VECTOR)
9647 HOST_WIDE_INT intval0, intval1;
9648 if (GET_MODE (operands[1]) == V2SImode)
9650 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9651 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9653 else
9655 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9656 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9657 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9658 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9660 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9661 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9662 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9663 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9664 emit_move_insn (xop[0], xop[2]);
9665 emit_move_insn (xop[3], xop[1]);
9666 return;
9669 for (i = 0; i < 2; i++)
9671 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9673 rtx addr = XEXP (operands[i], 0);
9674 rtx r, o;
9675 enum rtx_code code;
9677 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9678 switch (GET_CODE (addr))
9680 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9681 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9682 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9683 pre_modify:
9684 code = PRE_MODIFY;
9685 break;
9686 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9687 case POST_INC: o = GEN_INT (8); goto post_modify;
9688 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9689 post_modify:
9690 code = POST_MODIFY;
9691 swap = 2;
9692 break;
9693 default:
9694 gcc_unreachable ();
9696 r = XEXP (addr, 0);
9697 xop[0+i] = adjust_automodify_address_nv
9698 (operands[i], SImode,
9699 gen_rtx_fmt_ee (code, Pmode, r,
9700 gen_rtx_PLUS (Pmode, r, o)),
9702 xop[2+i] = adjust_automodify_address_nv
9703 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9705 else
9707 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9708 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9711 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9713 swap = 2;
9714 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9717 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9718 emit_move_insn (xop[2 - swap], xop[3 - swap]);
9722 /* Select between the instruction output templates s_tmpl (for short INSNs)
9723 and l_tmpl (for long INSNs). */
9725 const char *
9726 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
9728 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9730 extract_constrain_insn_cached (insn);
9731 return is_short ? s_tmpl : l_tmpl;
9734 /* Searches X for any reference to REGNO, returning the rtx of the
9735 reference found if any. Otherwise, returns NULL_RTX. */
9738 arc_regno_use_in (unsigned int regno, rtx x)
9740 const char *fmt;
9741 int i, j;
9742 rtx tem;
9744 if (REG_P (x) && refers_to_regno_p (regno, x))
9745 return x;
9747 fmt = GET_RTX_FORMAT (GET_CODE (x));
9748 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9750 if (fmt[i] == 'e')
9752 if ((tem = regno_use_in (regno, XEXP (x, i))))
9753 return tem;
9755 else if (fmt[i] == 'E')
9756 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9757 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9758 return tem;
9761 return NULL_RTX;
9764 /* Return the integer value of the "type" attribute for INSN, or -1 if
9765 INSN can't have attributes. */
9768 arc_attr_type (rtx_insn *insn)
9770 if (NONJUMP_INSN_P (insn)
9771 ? (GET_CODE (PATTERN (insn)) == USE
9772 || GET_CODE (PATTERN (insn)) == CLOBBER)
9773 : JUMP_P (insn)
9774 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9775 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9776 : !CALL_P (insn))
9777 return -1;
9778 return get_attr_type (insn);
9781 /* Return true if insn sets the condition codes. */
9783 bool
9784 arc_sets_cc_p (rtx_insn *insn)
9786 if (NONJUMP_INSN_P (insn))
9787 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9788 insn = seq->insn (seq->len () - 1);
9789 return arc_attr_type (insn) == TYPE_COMPARE;
9792 /* Return true if INSN is an instruction with a delay slot we may want
9793 to fill. */
9795 bool
9796 arc_need_delay (rtx_insn *insn)
9798 rtx_insn *next;
9800 if (!flag_delayed_branch)
9801 return false;
9802 /* The return at the end of a function needs a delay slot. */
9803 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9804 && (!(next = next_active_insn (insn))
9805 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9806 && arc_attr_type (next) == TYPE_RETURN))
9807 && (!TARGET_PAD_RETURN
9808 || (prev_active_insn (insn)
9809 && prev_active_insn (prev_active_insn (insn))
9810 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9811 return true;
9812 if (NONJUMP_INSN_P (insn)
9813 ? (GET_CODE (PATTERN (insn)) == USE
9814 || GET_CODE (PATTERN (insn)) == CLOBBER
9815 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9816 : JUMP_P (insn)
9817 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9818 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9819 : !CALL_P (insn))
9820 return false;
9821 return num_delay_slots (insn) != 0;
9824 /* Return true if the scheduling pass(es) has/have already run,
9825 i.e. where possible, we should try to mitigate high latencies
9826 by different instruction selection. */
9828 bool
9829 arc_scheduling_not_expected (void)
9831 return cfun->machine->arc_reorg_started;
9835 arc_label_align (rtx_insn *label)
9837 /* Code has a minimum p2 alignment of 1, which we must restore after an
9838 ADDR_DIFF_VEC. */
9839 if (align_labels_log < 1)
9841 rtx_insn *next = next_nonnote_nondebug_insn (label);
9842 if (INSN_P (next) && recog_memoized (next) >= 0)
9843 return 1;
9845 return align_labels_log;
9848 /* Return true if LABEL is in executable code. */
9850 bool
9851 arc_text_label (rtx_insn *label)
9853 rtx_insn *next;
9855 /* ??? We use deleted labels like they were still there, see
9856 gcc.c-torture/compile/20000326-2.c . */
9857 gcc_assert (GET_CODE (label) == CODE_LABEL
9858 || (GET_CODE (label) == NOTE
9859 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9860 next = next_nonnote_insn (label);
9861 if (next)
9862 return (!JUMP_TABLE_DATA_P (next)
9863 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9864 else if (!PREV_INSN (label))
9865 /* ??? sometimes text labels get inserted very late, see
9866 gcc.dg/torture/stackalign/comp-goto-1.c */
9867 return true;
9868 return false;
9871 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9872 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9873 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9874 to redirect two breqs. */
9876 static bool
9877 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
9879 /* ??? get_attr_type is declared to take an rtx. */
9880 union { const rtx_insn *c; rtx_insn *r; } u;
9882 u.c = follower;
9883 if (CROSSING_JUMP_P (followee))
9884 switch (get_attr_type (u.r))
9886 case TYPE_BRANCH:
9887 if (get_attr_length (u.r) != 2)
9888 break;
9889 case TYPE_BRCC:
9890 case TYPE_BRCC_NO_DELAY_SLOT:
9891 return false;
9892 default:
9893 return true;
9895 return true;
9898 /* Return the register number of the register holding the return address
9899 for a function of type TYPE. */
9902 arc_return_address_register (unsigned int fn_type)
9904 int regno = 0;
9906 if (ARC_INTERRUPT_P (fn_type))
9908 if (((fn_type & ARC_FUNCTION_ILINK1) | ARC_FUNCTION_FIRQ) != 0)
9909 regno = ILINK1_REGNUM;
9910 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
9911 regno = ILINK2_REGNUM;
9912 else
9913 gcc_unreachable ();
9915 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
9916 regno = RETURN_ADDR_REGNUM;
9918 gcc_assert (regno != 0);
9919 return regno;
9922 /* Implement EPILOGUE_USES.
9923 Return true if REGNO should be added to the deemed uses of the epilogue.
9925 We have to make sure all the register restore instructions are
9926 known to be live in interrupt functions, plus the blink register if
9927 it is clobbered by the isr. */
9929 bool
9930 arc_epilogue_uses (int regno)
9932 unsigned int fn_type;
9934 if (regno == arc_tp_regno)
9935 return true;
9937 fn_type = arc_compute_function_type (cfun);
9938 if (reload_completed)
9940 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9942 if (!fixed_regs[regno])
9943 return true;
9944 return ((regno == arc_return_address_register (fn_type))
9945 || (regno == RETURN_ADDR_REGNUM));
9947 else
9948 return regno == RETURN_ADDR_REGNUM;
9950 else
9951 return regno == arc_return_address_register (fn_type);
9954 /* Helper for EH_USES macro. */
9956 bool
9957 arc_eh_uses (int regno)
9959 if (regno == arc_tp_regno)
9960 return true;
9961 return false;
9964 #ifndef TARGET_NO_LRA
9965 #define TARGET_NO_LRA !TARGET_LRA
9966 #endif
9968 static bool
9969 arc_lra_p (void)
9971 return !TARGET_NO_LRA;
9974 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9975 Rcq registers, because some insn are shorter with them. OTOH we already
9976 have separate alternatives for this purpose, and other insns don't
9977 mind, so maybe we should rather prefer the other registers?
9978 We need more data, and we can only get that if we allow people to
9979 try all options. */
9980 static int
9981 arc_register_priority (int r)
9983 switch (arc_lra_priority_tag)
9985 case ARC_LRA_PRIORITY_NONE:
9986 return 0;
9987 case ARC_LRA_PRIORITY_NONCOMPACT:
9988 return ((((r & 7) ^ 4) - 4) & 15) != r;
9989 case ARC_LRA_PRIORITY_COMPACT:
9990 return ((((r & 7) ^ 4) - 4) & 15) == r;
9991 default:
9992 gcc_unreachable ();
9996 static reg_class_t
9997 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
9999 return GENERAL_REGS;
10002 bool
10003 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
10004 int itype)
10006 rtx x = *p;
10007 enum reload_type type = (enum reload_type) itype;
10009 if (GET_CODE (x) == PLUS
10010 && CONST_INT_P (XEXP (x, 1))
10011 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
10012 || (REG_P (XEXP (x, 0))
10013 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
10015 int scale = GET_MODE_SIZE (mode);
10016 int shift;
10017 rtx index_rtx = XEXP (x, 1);
10018 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
10019 rtx reg, sum, sum2;
10021 if (scale > 4)
10022 scale = 4;
10023 if ((scale-1) & offset)
10024 scale = 1;
10025 shift = scale >> 1;
10026 offset_base
10027 = ((offset + (256 << shift))
10028 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
10029 /* Sometimes the normal form does not suit DImode. We
10030 could avoid that by using smaller ranges, but that
10031 would give less optimized code when SImode is
10032 prevalent. */
10033 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
10035 int regno;
10037 reg = XEXP (x, 0);
10038 regno = REGNO (reg);
10039 sum2 = sum = plus_constant (Pmode, reg, offset_base);
10041 if (reg_equiv_constant (regno))
10043 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
10044 offset_base);
10045 if (GET_CODE (sum2) == PLUS)
10046 sum2 = gen_rtx_CONST (Pmode, sum2);
10048 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
10049 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
10050 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
10051 type);
10052 return true;
10055 /* We must re-recognize what we created before. */
10056 else if (GET_CODE (x) == PLUS
10057 && GET_CODE (XEXP (x, 0)) == PLUS
10058 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
10059 && REG_P (XEXP (XEXP (x, 0), 0))
10060 && CONST_INT_P (XEXP (x, 1)))
10062 /* Because this address is so complex, we know it must have
10063 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10064 it is already unshared, and needs no further unsharing. */
10065 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
10066 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10067 return true;
10069 return false;
10072 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10074 static bool
10075 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
10076 unsigned int align,
10077 enum by_pieces_operation op,
10078 bool speed_p)
10080 /* Let the movmem expander handle small block moves. */
10081 if (op == MOVE_BY_PIECES)
10082 return false;
10084 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10087 /* Emit a (pre) memory barrier around an atomic sequence according to
10088 MODEL. */
10090 static void
10091 arc_pre_atomic_barrier (enum memmodel model)
10093 if (need_atomic_barrier_p (model, true))
10094 emit_insn (gen_memory_barrier ());
10097 /* Emit a (post) memory barrier around an atomic sequence according to
10098 MODEL. */
10100 static void
10101 arc_post_atomic_barrier (enum memmodel model)
10103 if (need_atomic_barrier_p (model, false))
10104 emit_insn (gen_memory_barrier ());
10107 /* Expand a compare and swap pattern. */
10109 static void
10110 emit_unlikely_jump (rtx insn)
10112 rtx_insn *jump = emit_jump_insn (insn);
10113 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10116 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10117 32-bit compare and swap on the word containing the byte or
10118 half-word. The difference between a weak and a strong CAS is that
10119 the weak version may simply fail. The strong version relies on two
10120 loops, one checks if the SCOND op is succsfully or not, the other
10121 checks if the 32 bit accessed location which contains the 8 or 16
10122 bit datum is not changed by other thread. The first loop is
10123 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10124 loops is implemented by this routine. */
10126 static void
10127 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10128 rtx oldval, rtx newval, rtx weak,
10129 rtx mod_s, rtx mod_f)
10131 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10132 rtx addr = gen_reg_rtx (Pmode);
10133 rtx off = gen_reg_rtx (SImode);
10134 rtx oldv = gen_reg_rtx (SImode);
10135 rtx newv = gen_reg_rtx (SImode);
10136 rtx oldvalue = gen_reg_rtx (SImode);
10137 rtx newvalue = gen_reg_rtx (SImode);
10138 rtx res = gen_reg_rtx (SImode);
10139 rtx resv = gen_reg_rtx (SImode);
10140 rtx memsi, val, mask, end_label, loop_label, cc, x;
10141 machine_mode mode;
10142 bool is_weak = (weak != const0_rtx);
10144 /* Truncate the address. */
10145 emit_insn (gen_rtx_SET (addr,
10146 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10148 /* Compute the datum offset. */
10149 emit_insn (gen_rtx_SET (off,
10150 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10151 if (TARGET_BIG_ENDIAN)
10152 emit_insn (gen_rtx_SET (off,
10153 gen_rtx_MINUS (SImode,
10154 (GET_MODE (mem) == QImode) ?
10155 GEN_INT (3) : GEN_INT (2), off)));
10157 /* Normal read from truncated address. */
10158 memsi = gen_rtx_MEM (SImode, addr);
10159 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10160 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10162 val = copy_to_reg (memsi);
10164 /* Convert the offset in bits. */
10165 emit_insn (gen_rtx_SET (off,
10166 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10168 /* Get the proper mask. */
10169 if (GET_MODE (mem) == QImode)
10170 mask = force_reg (SImode, GEN_INT (0xff));
10171 else
10172 mask = force_reg (SImode, GEN_INT (0xffff));
10174 emit_insn (gen_rtx_SET (mask,
10175 gen_rtx_ASHIFT (SImode, mask, off)));
10177 /* Prepare the old and new values. */
10178 emit_insn (gen_rtx_SET (val,
10179 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10180 val)));
10182 oldval = gen_lowpart (SImode, oldval);
10183 emit_insn (gen_rtx_SET (oldv,
10184 gen_rtx_ASHIFT (SImode, oldval, off)));
10186 newval = gen_lowpart_common (SImode, newval);
10187 emit_insn (gen_rtx_SET (newv,
10188 gen_rtx_ASHIFT (SImode, newval, off)));
10190 emit_insn (gen_rtx_SET (oldv,
10191 gen_rtx_AND (SImode, oldv, mask)));
10193 emit_insn (gen_rtx_SET (newv,
10194 gen_rtx_AND (SImode, newv, mask)));
10196 if (!is_weak)
10198 end_label = gen_label_rtx ();
10199 loop_label = gen_label_rtx ();
10200 emit_label (loop_label);
10203 /* Make the old and new values. */
10204 emit_insn (gen_rtx_SET (oldvalue,
10205 gen_rtx_IOR (SImode, oldv, val)));
10207 emit_insn (gen_rtx_SET (newvalue,
10208 gen_rtx_IOR (SImode, newv, val)));
10210 /* Try an 32bit atomic compare and swap. It clobbers the CC
10211 register. */
10212 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10213 weak, mod_s, mod_f));
10215 /* Regardless of the weakness of the operation, a proper boolean
10216 result needs to be provided. */
10217 x = gen_rtx_REG (CC_Zmode, CC_REG);
10218 x = gen_rtx_EQ (SImode, x, const0_rtx);
10219 emit_insn (gen_rtx_SET (bool_result, x));
10221 if (!is_weak)
10223 /* Check the results: if the atomic op is successfully the goto
10224 to end label. */
10225 x = gen_rtx_REG (CC_Zmode, CC_REG);
10226 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10227 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10228 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10229 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10231 /* Wait for the right moment when the accessed 32-bit location
10232 is stable. */
10233 emit_insn (gen_rtx_SET (resv,
10234 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10235 res)));
10236 mode = SELECT_CC_MODE (NE, resv, val);
10237 cc = gen_rtx_REG (mode, CC_REG);
10238 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10240 /* Set the new value of the 32 bit location, proper masked. */
10241 emit_insn (gen_rtx_SET (val, resv));
10243 /* Try again if location is unstable. Fall through if only
10244 scond op failed. */
10245 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10246 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10247 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10248 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10250 emit_label (end_label);
10253 /* End: proper return the result for the given mode. */
10254 emit_insn (gen_rtx_SET (res,
10255 gen_rtx_AND (SImode, res, mask)));
10257 emit_insn (gen_rtx_SET (res,
10258 gen_rtx_LSHIFTRT (SImode, res, off)));
10260 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10263 /* Helper function used by "atomic_compare_and_swap" expand
10264 pattern. */
10266 void
10267 arc_expand_compare_and_swap (rtx operands[])
10269 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10270 machine_mode mode;
10272 bval = operands[0];
10273 rval = operands[1];
10274 mem = operands[2];
10275 oldval = operands[3];
10276 newval = operands[4];
10277 is_weak = operands[5];
10278 mod_s = operands[6];
10279 mod_f = operands[7];
10280 mode = GET_MODE (mem);
10282 if (reg_overlap_mentioned_p (rval, oldval))
10283 oldval = copy_to_reg (oldval);
10285 if (mode == SImode)
10287 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10288 is_weak, mod_s, mod_f));
10289 x = gen_rtx_REG (CC_Zmode, CC_REG);
10290 x = gen_rtx_EQ (SImode, x, const0_rtx);
10291 emit_insn (gen_rtx_SET (bval, x));
10293 else
10295 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10296 is_weak, mod_s, mod_f);
10300 /* Helper function used by the "atomic_compare_and_swapsi_1"
10301 pattern. */
10303 void
10304 arc_split_compare_and_swap (rtx operands[])
10306 rtx rval, mem, oldval, newval;
10307 machine_mode mode;
10308 enum memmodel mod_s, mod_f;
10309 bool is_weak;
10310 rtx label1, label2, x, cond;
10312 rval = operands[0];
10313 mem = operands[1];
10314 oldval = operands[2];
10315 newval = operands[3];
10316 is_weak = (operands[4] != const0_rtx);
10317 mod_s = (enum memmodel) INTVAL (operands[5]);
10318 mod_f = (enum memmodel) INTVAL (operands[6]);
10319 mode = GET_MODE (mem);
10321 /* ARC atomic ops work only with 32-bit aligned memories. */
10322 gcc_assert (mode == SImode);
10324 arc_pre_atomic_barrier (mod_s);
10326 label1 = NULL_RTX;
10327 if (!is_weak)
10329 label1 = gen_label_rtx ();
10330 emit_label (label1);
10332 label2 = gen_label_rtx ();
10334 /* Load exclusive. */
10335 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10337 /* Check if it is oldval. */
10338 mode = SELECT_CC_MODE (NE, rval, oldval);
10339 cond = gen_rtx_REG (mode, CC_REG);
10340 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10342 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10343 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10344 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10345 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10347 /* Exclusively store new item. Store clobbers CC reg. */
10348 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10350 if (!is_weak)
10352 /* Check the result of the store. */
10353 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10354 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10355 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10356 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10357 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10360 if (mod_f != MEMMODEL_RELAXED)
10361 emit_label (label2);
10363 arc_post_atomic_barrier (mod_s);
10365 if (mod_f == MEMMODEL_RELAXED)
10366 emit_label (label2);
10369 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10370 to perform. MEM is the memory on which to operate. VAL is the second
10371 operand of the binary operator. BEFORE and AFTER are optional locations to
10372 return the value of MEM either before of after the operation. MODEL_RTX
10373 is a CONST_INT containing the memory model to use. */
10375 void
10376 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10377 rtx orig_before, rtx orig_after, rtx model_rtx)
10379 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10380 machine_mode mode = GET_MODE (mem);
10381 rtx label, x, cond;
10382 rtx before = orig_before, after = orig_after;
10384 /* ARC atomic ops work only with 32-bit aligned memories. */
10385 gcc_assert (mode == SImode);
10387 arc_pre_atomic_barrier (model);
10389 label = gen_label_rtx ();
10390 emit_label (label);
10391 label = gen_rtx_LABEL_REF (VOIDmode, label);
10393 if (before == NULL_RTX)
10394 before = gen_reg_rtx (mode);
10396 if (after == NULL_RTX)
10397 after = gen_reg_rtx (mode);
10399 /* Load exclusive. */
10400 emit_insn (gen_arc_load_exclusivesi (before, mem));
10402 switch (code)
10404 case NOT:
10405 x = gen_rtx_AND (mode, before, val);
10406 emit_insn (gen_rtx_SET (after, x));
10407 x = gen_rtx_NOT (mode, after);
10408 emit_insn (gen_rtx_SET (after, x));
10409 break;
10411 case MINUS:
10412 if (CONST_INT_P (val))
10414 val = GEN_INT (-INTVAL (val));
10415 code = PLUS;
10418 /* FALLTHRU. */
10419 default:
10420 x = gen_rtx_fmt_ee (code, mode, before, val);
10421 emit_insn (gen_rtx_SET (after, x));
10422 break;
10425 /* Exclusively store new item. Store clobbers CC reg. */
10426 emit_insn (gen_arc_store_exclusivesi (mem, after));
10428 /* Check the result of the store. */
10429 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10430 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10431 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10432 label, pc_rtx);
10433 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10435 arc_post_atomic_barrier (model);
10438 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10440 static bool
10441 arc_no_speculation_in_delay_slots_p ()
10443 return true;
10446 /* Return a parallel of registers to represent where to find the
10447 register pieces if required, otherwise NULL_RTX. */
10449 static rtx
10450 arc_dwarf_register_span (rtx rtl)
10452 machine_mode mode = GET_MODE (rtl);
10453 unsigned regno;
10454 rtx p;
10456 if (GET_MODE_SIZE (mode) != 8)
10457 return NULL_RTX;
10459 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10460 regno = REGNO (rtl);
10461 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10462 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10464 return p;
10467 /* Return true if OP is an acceptable memory operand for ARCompact
10468 16-bit load instructions of MODE.
10470 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10471 non scaled instructions.
10473 SCALED: TRUE if address can be scaled. */
10475 bool
10476 compact_memory_operand_p (rtx op, machine_mode mode,
10477 bool av2short, bool scaled)
10479 rtx addr, plus0, plus1;
10480 int size, off;
10482 /* Eliminate non-memory operations. */
10483 if (GET_CODE (op) != MEM)
10484 return 0;
10486 /* .di instructions have no 16-bit form. */
10487 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10488 return false;
10490 if (mode == VOIDmode)
10491 mode = GET_MODE (op);
10493 size = GET_MODE_SIZE (mode);
10495 /* dword operations really put out 2 instructions, so eliminate
10496 them. */
10497 if (size > UNITS_PER_WORD)
10498 return false;
10500 /* Decode the address now. */
10501 addr = XEXP (op, 0);
10502 switch (GET_CODE (addr))
10504 case REG:
10505 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10506 || COMPACT_GP_REG_P (REGNO (addr))
10507 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10508 case PLUS:
10509 plus0 = XEXP (addr, 0);
10510 plus1 = XEXP (addr, 1);
10512 if ((GET_CODE (plus0) == REG)
10513 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10514 || COMPACT_GP_REG_P (REGNO (plus0)))
10515 && ((GET_CODE (plus1) == REG)
10516 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10517 || COMPACT_GP_REG_P (REGNO (plus1)))))
10519 return !av2short;
10522 if ((GET_CODE (plus0) == REG)
10523 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10524 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10525 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10526 && (GET_CODE (plus1) == CONST_INT))
10528 bool valid = false;
10530 off = INTVAL (plus1);
10532 /* Negative offset is not supported in 16-bit load/store insns. */
10533 if (off < 0)
10534 return 0;
10536 /* Only u5 immediates allowed in code density instructions. */
10537 if (av2short)
10539 switch (size)
10541 case 1:
10542 return false;
10543 case 2:
10544 /* This is an ldh_s.x instruction, check the u6
10545 immediate. */
10546 if (COMPACT_GP_REG_P (REGNO (plus0)))
10547 valid = true;
10548 break;
10549 case 4:
10550 /* Only u5 immediates allowed in 32bit access code
10551 density instructions. */
10552 if (REGNO (plus0) <= 31)
10553 return ((off < 32) && (off % 4 == 0));
10554 break;
10555 default:
10556 return false;
10559 else
10560 if (COMPACT_GP_REG_P (REGNO (plus0)))
10561 valid = true;
10563 if (valid)
10566 switch (size)
10568 case 1:
10569 return (off < 32);
10570 case 2:
10571 /* The 6-bit constant get shifted to fit the real
10572 5-bits field. Check also for the alignment. */
10573 return ((off < 64) && (off % 2 == 0));
10574 case 4:
10575 return ((off < 128) && (off % 4 == 0));
10576 default:
10577 return false;
10582 if (REG_P (plus0) && CONST_INT_P (plus1)
10583 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10584 || SP_REG_P (REGNO (plus0)))
10585 && !av2short)
10587 off = INTVAL (plus1);
10588 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10591 if ((GET_CODE (plus0) == MULT)
10592 && (GET_CODE (XEXP (plus0, 0)) == REG)
10593 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10594 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10595 && (GET_CODE (plus1) == REG)
10596 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10597 || COMPACT_GP_REG_P (REGNO (plus1))))
10598 return scaled;
10599 default:
10600 break ;
10601 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10602 for 16-bit load instructions. */
10604 return false;
10607 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10608 anchors for small data: the GP register acts as an anchor in that
10609 case. We also don't want to use them for PC-relative accesses,
10610 where the PC acts as an anchor. Prohibit also TLS symbols to use
10611 anchors. */
10613 static bool
10614 arc_use_anchors_for_symbol_p (const_rtx symbol)
10616 if (SYMBOL_REF_TLS_MODEL (symbol))
10617 return false;
10619 if (flag_pic)
10620 return false;
10622 if (SYMBOL_REF_SMALL_P (symbol))
10623 return false;
10625 return default_use_anchors_for_symbol_p (symbol);
10628 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
10629 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
10631 struct gcc_target targetm = TARGET_INITIALIZER;
10633 #include "gt-arc.h"