Daily bump.
[official-gcc.git] / gcc / config / arc / arc.c
blob3cb4ba5b4dd7f81e93c54b230cb6425966829ad2
1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2018 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 #define IN_TARGET_CODE 1
33 #include "config.h"
34 #include "system.h"
35 #include "coretypes.h"
36 #include "memmodel.h"
37 #include "backend.h"
38 #include "target.h"
39 #include "rtl.h"
40 #include "tree.h"
41 #include "cfghooks.h"
42 #include "df.h"
43 #include "tm_p.h"
44 #include "stringpool.h"
45 #include "attribs.h"
46 #include "optabs.h"
47 #include "regs.h"
48 #include "emit-rtl.h"
49 #include "recog.h"
50 #include "diagnostic.h"
51 #include "fold-const.h"
52 #include "varasm.h"
53 #include "stor-layout.h"
54 #include "calls.h"
55 #include "output.h"
56 #include "insn-attr.h"
57 #include "flags.h"
58 #include "explow.h"
59 #include "expr.h"
60 #include "langhooks.h"
61 #include "tm-constrs.h"
62 #include "reload.h" /* For operands_match_p */
63 #include "cfgrtl.h"
64 #include "tree-pass.h"
65 #include "context.h"
66 #include "builtins.h"
67 #include "rtl-iter.h"
68 #include "alias.h"
69 #include "opts.h"
70 #include "hw-doloop.h"
72 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
73 static char arc_cpu_name[10] = "";
74 static const char *arc_cpu_string = arc_cpu_name;
76 typedef struct GTY (()) _arc_jli_section
78 const char *name;
79 struct _arc_jli_section *next;
80 } arc_jli_section;
82 static arc_jli_section *arc_jli_sections = NULL;
84 /* Track which regs are set fixed/call saved/call used from commnad line. */
85 HARD_REG_SET overrideregs;
87 /* Maximum size of a loop. */
88 #define ARC_MAX_LOOP_LENGTH 4095
90 /* ??? Loads can handle any constant, stores can only handle small ones. */
91 /* OTOH, LIMMs cost extra, so their usefulness is limited. */
92 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
93 (GET_CODE (X) == CONST_INT \
94 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & -4, \
95 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
96 ? 0 \
97 : -(-GET_MODE_SIZE (MODE) | -4) >> 1)))
99 #define LEGITIMATE_SMALL_DATA_OFFSET_P(X) \
100 (GET_CODE (X) == CONST \
101 && GET_CODE (XEXP ((X), 0)) == PLUS \
102 && GET_CODE (XEXP (XEXP ((X), 0), 0)) == SYMBOL_REF \
103 && SYMBOL_REF_SMALL_P (XEXP (XEXP ((X), 0), 0)) \
104 && GET_CODE (XEXP(XEXP ((X), 0), 1)) == CONST_INT \
105 && INTVAL (XEXP (XEXP ((X), 0), 1)) <= g_switch_value)
107 #define LEGITIMATE_SMALL_DATA_ADDRESS_P(X) \
108 (GET_CODE (X) == PLUS \
109 && REG_P (XEXP ((X), 0)) \
110 && REGNO (XEXP ((X), 0)) == SDATA_BASE_REGNUM \
111 && ((GET_CODE (XEXP ((X), 1)) == SYMBOL_REF \
112 && SYMBOL_REF_SMALL_P (XEXP ((X), 1))) \
113 || LEGITIMATE_SMALL_DATA_OFFSET_P (XEXP ((X), 1))))
115 /* Array of valid operand punctuation characters. */
116 char arc_punct_chars[256];
118 /* State used by arc_ccfsm_advance to implement conditional execution. */
119 struct GTY (()) arc_ccfsm
121 int state;
122 int cc;
123 rtx cond;
124 rtx_insn *target_insn;
125 int target_label;
128 /* Status of the IRQ_CTRL_AUX register. */
129 typedef struct irq_ctrl_saved_t
131 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
132 short irq_save_last_reg;
133 /* True if BLINK is automatically saved. */
134 bool irq_save_blink;
135 /* True if LPCOUNT is automatically saved. */
136 bool irq_save_lpcount;
137 } irq_ctrl_saved_t;
138 static irq_ctrl_saved_t irq_ctrl_saved;
140 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
141 ((ARC_INTERRUPT_P (FNTYPE) \
142 && irq_ctrl_saved.irq_save_blink) \
143 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
144 && rgf_banked_register_count > 8))
146 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
147 ((ARC_INTERRUPT_P (FNTYPE) \
148 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
149 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
150 && rgf_banked_register_count > 8))
152 #define ARC_AUTO_IRQ_P(FNTYPE) \
153 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
154 && (irq_ctrl_saved.irq_save_blink \
155 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
157 /* Number of registers in second bank for FIRQ support. */
158 static int rgf_banked_register_count;
160 #define arc_ccfsm_current cfun->machine->ccfsm_current
162 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
163 ((STATE)->state == 1 || (STATE)->state == 2)
165 /* Indicate we're conditionalizing insns now. */
166 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
167 ((STATE)->state += 2)
169 #define ARC_CCFSM_COND_EXEC_P(STATE) \
170 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
171 || current_insn_predicate)
173 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
174 #define CCFSM_ISCOMPACT(INSN,STATE) \
175 (ARC_CCFSM_COND_EXEC_P (STATE) \
176 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
177 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
178 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
180 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
181 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
182 ((ARC_CCFSM_COND_EXEC_P (STATE) \
183 || (JUMP_P (JUMP) \
184 && INSN_ANNULLED_BRANCH_P (JUMP) \
185 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
186 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
187 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
188 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
190 /* The maximum number of insns skipped which will be conditionalised if
191 possible. */
192 /* When optimizing for speed:
193 Let p be the probability that the potentially skipped insns need to
194 be executed, pn the cost of a correctly predicted non-taken branch,
195 mt the cost of a mis/non-predicted taken branch,
196 mn mispredicted non-taken, pt correctly predicted taken ;
197 costs expressed in numbers of instructions like the ones considered
198 skipping.
199 Unfortunately we don't have a measure of predictability - this
200 is linked to probability only in that in the no-eviction-scenario
201 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
202 value that can be assumed *if* the distribution is perfectly random.
203 A predictability of 1 is perfectly plausible not matter what p is,
204 because the decision could be dependent on an invocation parameter
205 of the program.
206 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
207 For small p, we want MAX_INSNS_SKIPPED == pt
209 When optimizing for size:
210 We want to skip insn unless we could use 16 opcodes for the
211 non-conditionalized insn to balance the branch length or more.
212 Performance can be tie-breaker. */
213 /* If the potentially-skipped insns are likely to be executed, we'll
214 generally save one non-taken branch
216 this to be no less than the 1/p */
217 #define MAX_INSNS_SKIPPED 3
219 /* A nop is needed between a 4 byte insn that sets the condition codes and
220 a branch that uses them (the same isn't true for an 8 byte insn that sets
221 the condition codes). Set by arc_ccfsm_advance. Used by
222 arc_print_operand. */
224 static int get_arc_condition_code (rtx);
226 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
227 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
228 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
229 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
230 static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
231 static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *);
233 /* Initialized arc_attribute_table to NULL since arc doesnot have any
234 machine specific supported attributes. */
235 const struct attribute_spec arc_attribute_table[] =
237 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
238 affects_type_identity, handler, exclude } */
239 { "interrupt", 1, 1, true, false, false, true,
240 arc_handle_interrupt_attribute, NULL },
241 /* Function calls made to this symbol must be done indirectly, because
242 it may lie outside of the 21/25 bit addressing range of a normal function
243 call. */
244 { "long_call", 0, 0, false, true, true, false, NULL, NULL },
245 /* Whereas these functions are always known to reside within the 25 bit
246 addressing range of unconditionalized bl. */
247 { "medium_call", 0, 0, false, true, true, false, NULL, NULL },
248 /* And these functions are always known to reside within the 21 bit
249 addressing range of blcc. */
250 { "short_call", 0, 0, false, true, true, false, NULL, NULL },
251 /* Function which are not having the prologue and epilogue generated
252 by the compiler. */
253 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute,
254 NULL },
255 /* Functions calls made using jli instruction. The pointer in JLI
256 table is found latter. */
257 { "jli_always", 0, 0, false, true, true, false, NULL, NULL },
258 /* Functions calls made using jli instruction. The pointer in JLI
259 table is given as input parameter. */
260 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute,
261 NULL },
262 /* Call a function using secure-mode. */
263 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute,
264 NULL },
265 /* Bypass caches using .di flag. */
266 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute,
267 NULL },
268 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute, NULL },
269 { NULL, 0, 0, false, false, false, false, NULL, NULL }
271 static int arc_comp_type_attributes (const_tree, const_tree);
272 static void arc_file_start (void);
273 static void arc_internal_label (FILE *, const char *, unsigned long);
274 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
275 tree);
276 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
277 static void arc_encode_section_info (tree decl, rtx rtl, int first);
279 static void arc_init_builtins (void);
280 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
282 static int branch_dest (rtx);
284 static void arc_output_pic_addr_const (FILE *, rtx, int);
285 static bool arc_function_ok_for_sibcall (tree, tree);
286 static rtx arc_function_value (const_tree, const_tree, bool);
287 const char * output_shift (rtx *);
288 static void arc_reorg (void);
289 static bool arc_in_small_data_p (const_tree);
291 static void arc_init_reg_tables (void);
292 static bool arc_return_in_memory (const_tree, const_tree);
293 static bool arc_vector_mode_supported_p (machine_mode);
295 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
296 unsigned int, bool);
297 static const char *arc_invalid_within_doloop (const rtx_insn *);
299 static void output_short_suffix (FILE *file);
301 static bool arc_frame_pointer_required (void);
303 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
304 unsigned int,
305 enum by_pieces_operation op,
306 bool);
308 /* Globally visible information about currently selected cpu. */
309 const arc_cpu_t *arc_selected_cpu;
311 static bool
312 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
314 if (GET_CODE (op) != PLUS)
315 return false;
317 if (GET_CODE (XEXP (op, 0)) != MULT)
318 return false;
320 /* Check multiplication operands. */
321 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
322 return false;
324 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
325 return false;
327 switch (GET_MODE_SIZE (mode))
329 case 2:
330 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
331 return false;
332 break;
333 case 8:
334 if (!TARGET_LL64)
335 return false;
336 /* Fall through. */
337 case 4:
338 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
339 return false;
340 /* Fall through. */
341 default:
342 return false;
345 /* Check the base. */
346 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
347 return true;
349 if (flag_pic)
351 if (CONST_INT_P (XEXP (op, 1)))
352 return true;
353 return false;
355 if (CONSTANT_P (XEXP (op, 1)))
357 /* Scalled addresses for sdata is done other places. */
358 if (GET_CODE (XEXP (op, 1)) == SYMBOL_REF
359 && SYMBOL_REF_SMALL_P (XEXP (op, 1)))
360 return false;
361 return true;
364 return false;
367 /* Check for constructions like REG + OFFS, where OFFS can be a
368 register, an immediate or an long immediate. */
370 static bool
371 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
373 if (GET_CODE (x) != PLUS)
374 return false;
376 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
377 return false;
379 /* Check for: [Rx + small offset] or [Rx + Ry]. */
380 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict))
381 && GET_MODE_SIZE ((mode)) <= 4)
382 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1))))
383 return true;
385 /* Check for [Rx + symbol]. */
386 if (!flag_pic
387 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
388 /* Avoid this type of address for double or larger modes. */
389 && (GET_MODE_SIZE (mode) <= 4)
390 /* Avoid small data which ends in something like GP +
391 symb@sda. */
392 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
393 return true;
395 return false;
398 /* Implements target hook vector_mode_supported_p. */
400 static bool
401 arc_vector_mode_supported_p (machine_mode mode)
403 switch (mode)
405 case E_V2HImode:
406 return TARGET_PLUS_DMPY;
407 case E_V4HImode:
408 case E_V2SImode:
409 return TARGET_PLUS_QMACW;
410 case E_V4SImode:
411 case E_V8HImode:
412 return TARGET_SIMD_SET;
414 default:
415 return false;
419 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
421 static machine_mode
422 arc_preferred_simd_mode (scalar_mode mode)
424 switch (mode)
426 case E_HImode:
427 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
428 case E_SImode:
429 return V2SImode;
431 default:
432 return word_mode;
436 /* Implements target hook
437 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
439 static void
440 arc_autovectorize_vector_sizes (vector_sizes *sizes)
442 if (TARGET_PLUS_QMACW)
444 sizes->quick_push (8);
445 sizes->quick_push (4);
449 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
450 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
451 static rtx arc_delegitimize_address (rtx);
452 static bool arc_can_follow_jump (const rtx_insn *follower,
453 const rtx_insn *followee);
455 static rtx frame_insn (rtx);
456 static void arc_function_arg_advance (cumulative_args_t, machine_mode,
457 const_tree, bool);
458 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
460 /* initialize the GCC target structure. */
461 #undef TARGET_COMP_TYPE_ATTRIBUTES
462 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
463 #undef TARGET_ASM_FILE_START
464 #define TARGET_ASM_FILE_START arc_file_start
465 #undef TARGET_ATTRIBUTE_TABLE
466 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
467 #undef TARGET_ASM_INTERNAL_LABEL
468 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
469 #undef TARGET_RTX_COSTS
470 #define TARGET_RTX_COSTS arc_rtx_costs
471 #undef TARGET_ADDRESS_COST
472 #define TARGET_ADDRESS_COST arc_address_cost
474 #undef TARGET_ENCODE_SECTION_INFO
475 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
477 #undef TARGET_CANNOT_FORCE_CONST_MEM
478 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
480 #undef TARGET_INIT_BUILTINS
481 #define TARGET_INIT_BUILTINS arc_init_builtins
483 #undef TARGET_EXPAND_BUILTIN
484 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
486 #undef TARGET_BUILTIN_DECL
487 #define TARGET_BUILTIN_DECL arc_builtin_decl
489 #undef TARGET_ASM_OUTPUT_MI_THUNK
490 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
492 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
493 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
495 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
496 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
498 #undef TARGET_MACHINE_DEPENDENT_REORG
499 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
501 #undef TARGET_IN_SMALL_DATA_P
502 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
504 #undef TARGET_PROMOTE_FUNCTION_MODE
505 #define TARGET_PROMOTE_FUNCTION_MODE \
506 default_promote_function_mode_always_promote
508 #undef TARGET_PROMOTE_PROTOTYPES
509 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
511 #undef TARGET_RETURN_IN_MEMORY
512 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
513 #undef TARGET_PASS_BY_REFERENCE
514 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
516 #undef TARGET_SETUP_INCOMING_VARARGS
517 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
519 #undef TARGET_ARG_PARTIAL_BYTES
520 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
522 #undef TARGET_MUST_PASS_IN_STACK
523 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
525 #undef TARGET_FUNCTION_VALUE
526 #define TARGET_FUNCTION_VALUE arc_function_value
528 #undef TARGET_SCHED_ADJUST_PRIORITY
529 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
531 #undef TARGET_VECTOR_MODE_SUPPORTED_P
532 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
534 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
535 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
537 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
538 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
540 #undef TARGET_CAN_USE_DOLOOP_P
541 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
543 #undef TARGET_INVALID_WITHIN_DOLOOP
544 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
546 #undef TARGET_PRESERVE_RELOAD_P
547 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
549 #undef TARGET_CAN_FOLLOW_JUMP
550 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
552 #undef TARGET_DELEGITIMIZE_ADDRESS
553 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
555 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
556 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
557 arc_use_by_pieces_infrastructure_p
559 /* Usually, we will be able to scale anchor offsets.
560 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
561 #undef TARGET_MIN_ANCHOR_OFFSET
562 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
563 #undef TARGET_MAX_ANCHOR_OFFSET
564 #define TARGET_MAX_ANCHOR_OFFSET (1020)
566 #undef TARGET_SECONDARY_RELOAD
567 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
569 #define TARGET_OPTION_OVERRIDE arc_override_options
571 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
573 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
575 #define TARGET_CAN_ELIMINATE arc_can_eliminate
577 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
579 #define TARGET_FUNCTION_ARG arc_function_arg
581 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
583 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
585 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
587 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
589 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
591 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
592 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
593 arc_no_speculation_in_delay_slots_p
595 #undef TARGET_LRA_P
596 #define TARGET_LRA_P arc_lra_p
597 #define TARGET_REGISTER_PRIORITY arc_register_priority
598 /* Stores with scaled offsets have different displacement ranges. */
599 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
600 #define TARGET_SPILL_CLASS arc_spill_class
602 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
603 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
605 #undef TARGET_WARN_FUNC_RETURN
606 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
608 #include "target-def.h"
610 #undef TARGET_ASM_ALIGNED_HI_OP
611 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
612 #undef TARGET_ASM_ALIGNED_SI_OP
613 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
615 #ifdef HAVE_AS_TLS
616 #undef TARGET_HAVE_TLS
617 #define TARGET_HAVE_TLS HAVE_AS_TLS
618 #endif
620 #undef TARGET_DWARF_REGISTER_SPAN
621 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
623 #undef TARGET_HARD_REGNO_NREGS
624 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
625 #undef TARGET_HARD_REGNO_MODE_OK
626 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
628 #undef TARGET_MODES_TIEABLE_P
629 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
630 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
631 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value
633 /* Try to keep the (mov:DF _, reg) as early as possible so
634 that the d<add/sub/mul>h-lr insns appear together and can
635 use the peephole2 pattern. */
637 static int
638 arc_sched_adjust_priority (rtx_insn *insn, int priority)
640 rtx set = single_set (insn);
641 if (set
642 && GET_MODE (SET_SRC(set)) == DFmode
643 && GET_CODE (SET_SRC(set)) == REG)
645 /* Incrementing priority by 20 (empirically derived). */
646 return priority + 20;
649 return priority;
652 /* For ARC base register + offset addressing, the validity of the
653 address is mode-dependent for most of the offset range, as the
654 offset can be scaled by the access size.
655 We don't expose these as mode-dependent addresses in the
656 mode_dependent_address_p target hook, because that would disable
657 lots of optimizations, and most uses of these addresses are for 32
658 or 64 bit accesses anyways, which are fine.
659 However, that leaves some addresses for 8 / 16 bit values not
660 properly reloaded by the generic code, which is why we have to
661 schedule secondary reloads for these. */
663 static reg_class_t
664 arc_secondary_reload (bool in_p,
665 rtx x,
666 reg_class_t cl,
667 machine_mode mode,
668 secondary_reload_info *sri)
670 enum rtx_code code = GET_CODE (x);
672 if (cl == DOUBLE_REGS)
673 return GENERAL_REGS;
675 /* The loop counter register can be stored, but not loaded directly. */
676 if ((cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS)
677 && in_p && MEM_P (x))
678 return GENERAL_REGS;
680 /* If we have a subreg (reg), where reg is a pseudo (that will end in
681 a memory location), then we may need a scratch register to handle
682 the fp/sp+largeoffset address. */
683 if (code == SUBREG)
685 rtx addr = NULL_RTX;
686 x = SUBREG_REG (x);
688 if (REG_P (x))
690 int regno = REGNO (x);
691 if (regno >= FIRST_PSEUDO_REGISTER)
692 regno = reg_renumber[regno];
694 if (regno != -1)
695 return NO_REGS;
697 /* It is a pseudo that ends in a stack location. */
698 if (reg_equiv_mem (REGNO (x)))
700 /* Get the equivalent address and check the range of the
701 offset. */
702 rtx mem = reg_equiv_mem (REGNO (x));
703 addr = find_replacement (&XEXP (mem, 0));
706 else
708 gcc_assert (MEM_P (x));
709 addr = XEXP (x, 0);
710 addr = simplify_rtx (addr);
712 if (addr && GET_CODE (addr) == PLUS
713 && CONST_INT_P (XEXP (addr, 1))
714 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
716 switch (mode)
718 case E_QImode:
719 sri->icode =
720 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store;
721 break;
722 case E_HImode:
723 sri->icode =
724 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store;
725 break;
726 default:
727 break;
731 return NO_REGS;
734 /* Convert reloads using offsets that are too large to use indirect
735 addressing. */
737 void
738 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
740 rtx addr;
742 gcc_assert (GET_CODE (mem) == MEM);
743 addr = XEXP (mem, 0);
745 /* Large offset: use a move. FIXME: ld ops accepts limms as
746 offsets. Hence, the following move insn is not required. */
747 emit_move_insn (scratch, addr);
748 mem = replace_equiv_address_nv (mem, scratch);
750 /* Now create the move. */
751 if (store_p)
752 emit_insn (gen_rtx_SET (mem, reg));
753 else
754 emit_insn (gen_rtx_SET (reg, mem));
756 return;
759 static unsigned arc_ifcvt (void);
761 namespace {
763 const pass_data pass_data_arc_ifcvt =
765 RTL_PASS,
766 "arc_ifcvt", /* 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_ifcvt : public rtl_opt_pass
778 public:
779 pass_arc_ifcvt(gcc::context *ctxt)
780 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt)
783 /* opt_pass methods: */
784 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); }
785 virtual unsigned int execute (function *) { return arc_ifcvt (); }
788 } // anon namespace
790 rtl_opt_pass *
791 make_pass_arc_ifcvt (gcc::context *ctxt)
793 return new pass_arc_ifcvt (ctxt);
796 static unsigned arc_predicate_delay_insns (void);
798 namespace {
800 const pass_data pass_data_arc_predicate_delay_insns =
802 RTL_PASS,
803 "arc_predicate_delay_insns", /* name */
804 OPTGROUP_NONE, /* optinfo_flags */
805 TV_IFCVT2, /* tv_id */
806 0, /* properties_required */
807 0, /* properties_provided */
808 0, /* properties_destroyed */
809 0, /* todo_flags_start */
810 TODO_df_finish /* todo_flags_finish */
813 class pass_arc_predicate_delay_insns : public rtl_opt_pass
815 public:
816 pass_arc_predicate_delay_insns(gcc::context *ctxt)
817 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
820 /* opt_pass methods: */
821 virtual unsigned int execute (function *)
823 return arc_predicate_delay_insns ();
827 } // anon namespace
829 rtl_opt_pass *
830 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
832 return new pass_arc_predicate_delay_insns (ctxt);
835 /* Called by OVERRIDE_OPTIONS to initialize various things. */
837 static void
838 arc_init (void)
840 if (TARGET_V2)
842 /* I have the multiplier, then use it*/
843 if (TARGET_MPYW || TARGET_MULTI)
844 arc_multcost = COSTS_N_INSNS (1);
846 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
847 if (arc_multcost < 0)
848 switch (arc_tune)
850 case ARC_TUNE_ARC700_4_2_STD:
851 /* latency 7;
852 max throughput (1 multiply + 4 other insns) / 5 cycles. */
853 arc_multcost = COSTS_N_INSNS (4);
854 if (TARGET_NOMPY_SET)
855 arc_multcost = COSTS_N_INSNS (30);
856 break;
857 case ARC_TUNE_ARC700_4_2_XMAC:
858 /* latency 5;
859 max throughput (1 multiply + 2 other insns) / 3 cycles. */
860 arc_multcost = COSTS_N_INSNS (3);
861 if (TARGET_NOMPY_SET)
862 arc_multcost = COSTS_N_INSNS (30);
863 break;
864 case ARC_TUNE_ARC600:
865 if (TARGET_MUL64_SET)
867 arc_multcost = COSTS_N_INSNS (4);
868 break;
870 /* Fall through. */
871 default:
872 arc_multcost = COSTS_N_INSNS (30);
873 break;
876 /* MPY instructions valid only for ARC700 or ARCv2. */
877 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
878 error ("-mno-mpy supported only for ARC700 or ARCv2");
880 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
881 error ("-mno-dpfp-lrsr supported only with -mdpfp");
883 /* FPX-1. No fast and compact together. */
884 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
885 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
886 error ("FPX fast and compact options cannot be specified together");
888 /* FPX-2. No fast-spfp for arc600 or arc601. */
889 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
890 error ("-mspfp_fast not available on ARC600 or ARC601");
892 /* FPX-4. No FPX extensions mixed with FPU extensions. */
893 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
894 && TARGET_HARD_FLOAT)
895 error ("No FPX/FPU mixing allowed");
897 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
898 if (flag_pic && TARGET_ARC600_FAMILY)
900 warning (DK_WARNING,
901 "PIC is not supported for %s. Generating non-PIC code only..",
902 arc_cpu_string);
903 flag_pic = 0;
906 arc_init_reg_tables ();
908 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
909 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
910 arc_punct_chars['#'] = 1;
911 arc_punct_chars['*'] = 1;
912 arc_punct_chars['?'] = 1;
913 arc_punct_chars['!'] = 1;
914 arc_punct_chars['^'] = 1;
915 arc_punct_chars['&'] = 1;
916 arc_punct_chars['+'] = 1;
917 arc_punct_chars['_'] = 1;
919 if (optimize > 1 && !TARGET_NO_COND_EXEC)
921 /* There are two target-independent ifcvt passes, and arc_reorg may do
922 one or more arc_ifcvt calls. */
923 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g);
924 struct register_pass_info arc_ifcvt4_info
925 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER };
926 struct register_pass_info arc_ifcvt5_info
927 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE };
929 register_pass (&arc_ifcvt4_info);
930 register_pass (&arc_ifcvt5_info);
933 if (flag_delayed_branch)
935 opt_pass *pass_arc_predicate_delay_insns
936 = make_pass_arc_predicate_delay_insns (g);
937 struct register_pass_info arc_predicate_delay_info
938 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER };
940 register_pass (&arc_predicate_delay_info);
944 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
945 register range is specified as two registers separated by a dash.
946 It always starts with r0, and its upper limit is fp register.
947 blink and lp_count registers are optional. */
949 static void
950 irq_range (const char *cstr)
952 int i, first, last, blink, lpcount, xreg;
953 char *str, *dash, *comma;
955 i = strlen (cstr);
956 str = (char *) alloca (i + 1);
957 memcpy (str, cstr, i + 1);
958 blink = -1;
959 lpcount = -1;
961 dash = strchr (str, '-');
962 if (!dash)
964 warning (0, "value of -mirq-ctrl-saved must have form R0-REGx");
965 return;
967 *dash = '\0';
969 comma = strchr (dash + 1, ',');
970 if (comma)
971 *comma = '\0';
973 first = decode_reg_name (str);
974 if (first != 0)
976 warning (0, "first register must be R0");
977 return;
980 /* At this moment we do not have the register names initialized
981 accordingly. */
982 if (!strcmp (dash + 1, "ilink"))
983 last = 29;
984 else
985 last = decode_reg_name (dash + 1);
987 if (last < 0)
989 warning (0, "unknown register name: %s", dash + 1);
990 return;
993 if (!(last & 0x01))
995 warning (0, "last register name %s must be an odd register", dash + 1);
996 return;
999 *dash = '-';
1001 if (first > last)
1003 warning (0, "%s-%s is an empty range", str, dash + 1);
1004 return;
1007 while (comma)
1009 *comma = ',';
1010 str = comma + 1;
1012 comma = strchr (str, ',');
1013 if (comma)
1014 *comma = '\0';
1016 xreg = decode_reg_name (str);
1017 switch (xreg)
1019 case 31:
1020 blink = 31;
1021 break;
1023 case 60:
1024 lpcount = 60;
1025 break;
1027 default:
1028 warning (0, "unknown register name: %s", str);
1029 return;
1033 irq_ctrl_saved.irq_save_last_reg = last;
1034 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31);
1035 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60);
1038 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1039 8, 16, or 32. */
1041 static void
1042 parse_mrgf_banked_regs_option (const char *arg)
1044 long int val;
1045 char *end_ptr;
1047 errno = 0;
1048 val = strtol (arg, &end_ptr, 10);
1049 if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
1050 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
1052 error ("invalid number in -mrgf-banked-regs=%s "
1053 "valid values are 0, 4, 8, 16, or 32", arg);
1054 return;
1056 rgf_banked_register_count = (int) val;
1059 /* Check ARC options, generate derived target attributes. */
1061 static void
1062 arc_override_options (void)
1064 unsigned int i;
1065 cl_deferred_option *opt;
1066 vec<cl_deferred_option> *vopt
1067 = (vec<cl_deferred_option> *) arc_deferred_options;
1069 if (arc_cpu == PROCESSOR_NONE)
1070 arc_cpu = TARGET_CPU_DEFAULT;
1072 /* Set the default cpu options. */
1073 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
1075 /* Set the architectures. */
1076 switch (arc_selected_cpu->arch_info->arch_id)
1078 case BASE_ARCH_em:
1079 arc_cpu_string = "EM";
1080 break;
1081 case BASE_ARCH_hs:
1082 arc_cpu_string = "HS";
1083 break;
1084 case BASE_ARCH_700:
1085 if (arc_selected_cpu->processor == PROCESSOR_nps400)
1086 arc_cpu_string = "NPS400";
1087 else
1088 arc_cpu_string = "ARC700";
1089 break;
1090 case BASE_ARCH_6xx:
1091 arc_cpu_string = "ARC600";
1092 break;
1093 default:
1094 gcc_unreachable ();
1097 irq_ctrl_saved.irq_save_last_reg = -1;
1098 irq_ctrl_saved.irq_save_blink = false;
1099 irq_ctrl_saved.irq_save_lpcount = false;
1101 rgf_banked_register_count = 0;
1103 /* Handle the deferred options. */
1104 if (vopt)
1105 FOR_EACH_VEC_ELT (*vopt, i, opt)
1107 switch (opt->opt_index)
1109 case OPT_mirq_ctrl_saved_:
1110 if (TARGET_V2)
1111 irq_range (opt->arg);
1112 else
1113 warning (0, "option -mirq-ctrl-saved valid only for ARC v2 processors");
1114 break;
1116 case OPT_mrgf_banked_regs_:
1117 if (TARGET_V2)
1118 parse_mrgf_banked_regs_option (opt->arg);
1119 else
1120 warning (0, "option -mrgf-banked-regs valid only for ARC v2 processors");
1121 break;
1123 default:
1124 gcc_unreachable();
1128 CLEAR_HARD_REG_SET (overrideregs);
1129 if (common_deferred_options)
1131 vec<cl_deferred_option> v =
1132 *((vec<cl_deferred_option> *) common_deferred_options);
1133 int reg, nregs, j;
1135 FOR_EACH_VEC_ELT (v, i, opt)
1137 switch (opt->opt_index)
1139 case OPT_ffixed_:
1140 case OPT_fcall_used_:
1141 case OPT_fcall_saved_:
1142 if ((reg = decode_reg_name_and_count (opt->arg, &nregs)) >= 0)
1143 for (j = reg; j < reg + nregs; j++)
1144 SET_HARD_REG_BIT (overrideregs, j);
1145 break;
1146 default:
1147 break;
1152 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1153 specific flags are set in arc-common.c. The architecture forces
1154 the default hardware configurations in, regardless what command
1155 line options are saying. The CPU optional hw options can be
1156 turned on or off. */
1157 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1158 do { \
1159 if ((arc_selected_cpu->flags & CODE) \
1160 && ((target_flags_explicit & MASK) == 0)) \
1161 target_flags |= MASK; \
1162 if (arc_selected_cpu->arch_info->dflags & CODE) \
1163 target_flags |= MASK; \
1164 } while (0);
1165 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1166 do { \
1167 if ((arc_selected_cpu->flags & CODE) \
1168 && (VAR == DEFAULT_##VAR)) \
1169 VAR = VAL; \
1170 if (arc_selected_cpu->arch_info->dflags & CODE) \
1171 VAR = VAL; \
1172 } while (0);
1174 #include "arc-options.def"
1176 #undef ARC_OPTX
1177 #undef ARC_OPT
1179 /* Check options against architecture options. Throw an error if
1180 option is not allowed. */
1181 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC) \
1182 do { \
1183 if ((VAR == VAL) \
1184 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1186 error ("%s is not available for %s architecture", \
1187 DOC, arc_selected_cpu->arch_info->name); \
1189 } while (0);
1190 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1191 do { \
1192 if ((target_flags & MASK) \
1193 && (!(arc_selected_cpu->arch_info->flags & CODE))) \
1194 error ("%s is not available for %s architecture", \
1195 DOC, arc_selected_cpu->arch_info->name); \
1196 } while (0);
1198 #include "arc-options.def"
1200 #undef ARC_OPTX
1201 #undef ARC_OPT
1203 /* Set Tune option. */
1204 if (arc_tune == ARC_TUNE_NONE)
1205 arc_tune = (enum arc_tune_attr) arc_selected_cpu->tune;
1207 if (arc_size_opt_level == 3)
1208 optimize_size = 1;
1210 /* Compact casesi is not a valid option for ARCv2 family. */
1211 if (TARGET_V2)
1213 if (TARGET_COMPACT_CASESI)
1215 warning (0, "compact-casesi is not applicable to ARCv2");
1216 TARGET_COMPACT_CASESI = 0;
1219 else if (optimize_size == 1
1220 && !global_options_set.x_TARGET_COMPACT_CASESI)
1221 TARGET_COMPACT_CASESI = 1;
1223 if (flag_pic)
1224 target_flags |= MASK_NO_SDATA_SET;
1226 if (flag_no_common == 255)
1227 flag_no_common = !TARGET_NO_SDATA_SET;
1229 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1230 if (TARGET_MIXED_CODE)
1231 TARGET_Q_CLASS = 1;
1232 if (!TARGET_Q_CLASS)
1233 TARGET_COMPACT_CASESI = 0;
1234 if (TARGET_COMPACT_CASESI)
1235 TARGET_CASE_VECTOR_PC_RELATIVE = 1;
1237 /* Check for small data option */
1238 if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
1239 g_switch_value = TARGET_LL64 ? 8 : 4;
1241 /* These need to be done at start up. It's convenient to do them here. */
1242 arc_init ();
1245 /* The condition codes of the ARC, and the inverse function. */
1246 /* For short branches, the "c" / "nc" names are not defined in the ARC
1247 Programmers manual, so we have to use "lo" / "hs"" instead. */
1248 static const char *arc_condition_codes[] =
1250 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1251 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1254 enum arc_cc_code_index
1256 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
1257 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
1258 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
1259 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
1262 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1264 /* Returns the index of the ARC condition code string in
1265 `arc_condition_codes'. COMPARISON should be an rtx like
1266 `(eq (...) (...))'. */
1268 static int
1269 get_arc_condition_code (rtx comparison)
1271 switch (GET_MODE (XEXP (comparison, 0)))
1273 case E_CCmode:
1274 case E_SImode: /* For BRcc. */
1275 switch (GET_CODE (comparison))
1277 case EQ : return ARC_CC_EQ;
1278 case NE : return ARC_CC_NE;
1279 case GT : return ARC_CC_GT;
1280 case LE : return ARC_CC_LE;
1281 case GE : return ARC_CC_GE;
1282 case LT : return ARC_CC_LT;
1283 case GTU : return ARC_CC_HI;
1284 case LEU : return ARC_CC_LS;
1285 case LTU : return ARC_CC_LO;
1286 case GEU : return ARC_CC_HS;
1287 default : gcc_unreachable ();
1289 case E_CC_ZNmode:
1290 switch (GET_CODE (comparison))
1292 case EQ : return ARC_CC_EQ;
1293 case NE : return ARC_CC_NE;
1294 case GE: return ARC_CC_P;
1295 case LT: return ARC_CC_N;
1296 case GT : return ARC_CC_PNZ;
1297 default : gcc_unreachable ();
1299 case E_CC_Zmode:
1300 switch (GET_CODE (comparison))
1302 case EQ : return ARC_CC_EQ;
1303 case NE : return ARC_CC_NE;
1304 default : gcc_unreachable ();
1306 case E_CC_Cmode:
1307 switch (GET_CODE (comparison))
1309 case LTU : return ARC_CC_C;
1310 case GEU : return ARC_CC_NC;
1311 default : gcc_unreachable ();
1313 case E_CC_FP_GTmode:
1314 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1315 switch (GET_CODE (comparison))
1317 case GT : return ARC_CC_N;
1318 case UNLE: return ARC_CC_P;
1319 default : gcc_unreachable ();
1321 else
1322 switch (GET_CODE (comparison))
1324 case GT : return ARC_CC_HI;
1325 case UNLE : return ARC_CC_LS;
1326 default : gcc_unreachable ();
1328 case E_CC_FP_GEmode:
1329 /* Same for FPX and non-FPX. */
1330 switch (GET_CODE (comparison))
1332 case GE : return ARC_CC_HS;
1333 case UNLT : return ARC_CC_LO;
1334 default : gcc_unreachable ();
1336 case E_CC_FP_UNEQmode:
1337 switch (GET_CODE (comparison))
1339 case UNEQ : return ARC_CC_EQ;
1340 case LTGT : return ARC_CC_NE;
1341 default : gcc_unreachable ();
1343 case E_CC_FP_ORDmode:
1344 switch (GET_CODE (comparison))
1346 case UNORDERED : return ARC_CC_C;
1347 case ORDERED : return ARC_CC_NC;
1348 default : gcc_unreachable ();
1350 case E_CC_FPXmode:
1351 switch (GET_CODE (comparison))
1353 case EQ : return ARC_CC_EQ;
1354 case NE : return ARC_CC_NE;
1355 case UNORDERED : return ARC_CC_C;
1356 case ORDERED : return ARC_CC_NC;
1357 case LTGT : return ARC_CC_HI;
1358 case UNEQ : return ARC_CC_LS;
1359 default : gcc_unreachable ();
1361 case E_CC_FPUmode:
1362 switch (GET_CODE (comparison))
1364 case EQ : return ARC_CC_EQ;
1365 case NE : return ARC_CC_NE;
1366 case GT : return ARC_CC_GT;
1367 case GE : return ARC_CC_GE;
1368 case LT : return ARC_CC_C;
1369 case LE : return ARC_CC_LS;
1370 case UNORDERED : return ARC_CC_V;
1371 case ORDERED : return ARC_CC_NV;
1372 case UNGT : return ARC_CC_HI;
1373 case UNGE : return ARC_CC_HS;
1374 case UNLT : return ARC_CC_LT;
1375 case UNLE : return ARC_CC_LE;
1376 /* UNEQ and LTGT do not have representation. */
1377 case LTGT : /* Fall through. */
1378 case UNEQ : /* Fall through. */
1379 default : gcc_unreachable ();
1381 case E_CC_FPU_UNEQmode:
1382 switch (GET_CODE (comparison))
1384 case LTGT : return ARC_CC_NE;
1385 case UNEQ : return ARC_CC_EQ;
1386 default : gcc_unreachable ();
1388 default : gcc_unreachable ();
1390 /*NOTREACHED*/
1391 return (42);
1394 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1396 bool
1397 arc_short_comparison_p (rtx comparison, int offset)
1399 gcc_assert (ARC_CC_NC == ARC_CC_HS);
1400 gcc_assert (ARC_CC_C == ARC_CC_LO);
1401 switch (get_arc_condition_code (comparison))
1403 case ARC_CC_EQ: case ARC_CC_NE:
1404 return offset >= -512 && offset <= 506;
1405 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
1406 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
1407 return offset >= -64 && offset <= 58;
1408 default:
1409 return false;
1413 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1414 return the mode to be used for the comparison. */
1416 machine_mode
1417 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1419 machine_mode mode = GET_MODE (x);
1420 rtx x1;
1422 /* For an operation that sets the condition codes as a side-effect, the
1423 C and V flags is not set as for cmp, so we can only use comparisons where
1424 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1425 instead.) */
1426 /* ??? We could use "pnz" for greater than zero, however, we could then
1427 get into trouble because the comparison could not be reversed. */
1428 if (GET_MODE_CLASS (mode) == MODE_INT
1429 && y == const0_rtx
1430 && (op == EQ || op == NE
1431 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
1432 return CC_ZNmode;
1434 /* add.f for if (a+b) */
1435 if (mode == SImode
1436 && GET_CODE (y) == NEG
1437 && (op == EQ || op == NE))
1438 return CC_ZNmode;
1440 /* Check if this is a test suitable for bxor.f . */
1441 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1442 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1443 && INTVAL (y))
1444 return CC_Zmode;
1446 /* Check if this is a test suitable for add / bmsk.f . */
1447 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1448 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1449 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1450 && (~INTVAL (x1) | INTVAL (y)) < 0
1451 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1452 return CC_Zmode;
1454 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1455 && GET_CODE (x) == PLUS
1456 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1457 return CC_Cmode;
1459 if (TARGET_ARGONAUT_SET
1460 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1461 switch (op)
1463 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1464 return CC_FPXmode;
1465 case LT: case UNGE: case GT: case UNLE:
1466 return CC_FP_GTmode;
1467 case LE: case UNGT: case GE: case UNLT:
1468 return CC_FP_GEmode;
1469 default: gcc_unreachable ();
1471 else if (TARGET_HARD_FLOAT
1472 && ((mode == SFmode && TARGET_FP_SP_BASE)
1473 || (mode == DFmode && TARGET_FP_DP_BASE)))
1474 switch (op)
1476 case EQ:
1477 case NE:
1478 case UNORDERED:
1479 case ORDERED:
1480 case UNLT:
1481 case UNLE:
1482 case UNGT:
1483 case UNGE:
1484 case LT:
1485 case LE:
1486 case GT:
1487 case GE:
1488 return CC_FPUmode;
1490 case LTGT:
1491 case UNEQ:
1492 return CC_FPU_UNEQmode;
1494 default:
1495 gcc_unreachable ();
1497 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1499 switch (op)
1501 case EQ: case NE: return CC_Zmode;
1502 case LT: case UNGE:
1503 case GT: case UNLE: return CC_FP_GTmode;
1504 case LE: case UNGT:
1505 case GE: case UNLT: return CC_FP_GEmode;
1506 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1507 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1508 default: gcc_unreachable ();
1511 return CCmode;
1514 /* Vectors to keep interesting information about registers where it can easily
1515 be got. We use to use the actual mode value as the bit number, but there
1516 is (or may be) more than 32 modes now. Instead we use two tables: one
1517 indexed by hard register number, and one indexed by mode. */
1519 /* The purpose of arc_mode_class is to shrink the range of modes so that
1520 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1521 mapped into one arc_mode_class mode. */
1523 enum arc_mode_class {
1524 C_MODE,
1525 S_MODE, D_MODE, T_MODE, O_MODE,
1526 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1527 V_MODE
1530 /* Modes for condition codes. */
1531 #define C_MODES (1 << (int) C_MODE)
1533 /* Modes for single-word and smaller quantities. */
1534 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1536 /* Modes for double-word and smaller quantities. */
1537 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1539 /* Mode for 8-byte DF values only. */
1540 #define DF_MODES (1 << DF_MODE)
1542 /* Modes for quad-word and smaller quantities. */
1543 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1545 /* Modes for 128-bit vectors. */
1546 #define V_MODES (1 << (int) V_MODE)
1548 /* Value is 1 if register/mode pair is acceptable on arc. */
1550 static unsigned int arc_hard_regno_modes[] = {
1551 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1552 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1553 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1554 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1556 /* ??? Leave these as S_MODES for now. */
1557 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1558 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1559 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1560 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1562 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1563 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1564 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1565 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1567 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1568 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1569 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1570 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1572 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1573 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES
1576 static unsigned int arc_mode_class [NUM_MACHINE_MODES];
1578 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1580 enum reg_class
1581 arc_preferred_reload_class (rtx, enum reg_class cl)
1583 if ((cl) == CHEAP_CORE_REGS || (cl) == WRITABLE_CORE_REGS)
1584 return GENERAL_REGS;
1585 return cl;
1588 /* Initialize the arc_mode_class array. */
1590 static void
1591 arc_init_reg_tables (void)
1593 int i;
1595 for (i = 0; i < NUM_MACHINE_MODES; i++)
1597 machine_mode m = (machine_mode) i;
1599 switch (GET_MODE_CLASS (m))
1601 case MODE_INT:
1602 case MODE_PARTIAL_INT:
1603 case MODE_COMPLEX_INT:
1604 if (GET_MODE_SIZE (m) <= 4)
1605 arc_mode_class[i] = 1 << (int) S_MODE;
1606 else if (GET_MODE_SIZE (m) == 8)
1607 arc_mode_class[i] = 1 << (int) D_MODE;
1608 else if (GET_MODE_SIZE (m) == 16)
1609 arc_mode_class[i] = 1 << (int) T_MODE;
1610 else if (GET_MODE_SIZE (m) == 32)
1611 arc_mode_class[i] = 1 << (int) O_MODE;
1612 else
1613 arc_mode_class[i] = 0;
1614 break;
1615 case MODE_FLOAT:
1616 case MODE_COMPLEX_FLOAT:
1617 if (GET_MODE_SIZE (m) <= 4)
1618 arc_mode_class[i] = 1 << (int) SF_MODE;
1619 else if (GET_MODE_SIZE (m) == 8)
1620 arc_mode_class[i] = 1 << (int) DF_MODE;
1621 else if (GET_MODE_SIZE (m) == 16)
1622 arc_mode_class[i] = 1 << (int) TF_MODE;
1623 else if (GET_MODE_SIZE (m) == 32)
1624 arc_mode_class[i] = 1 << (int) OF_MODE;
1625 else
1626 arc_mode_class[i] = 0;
1627 break;
1628 case MODE_VECTOR_INT:
1629 if (GET_MODE_SIZE (m) == 4)
1630 arc_mode_class[i] = (1 << (int) S_MODE);
1631 else if (GET_MODE_SIZE (m) == 8)
1632 arc_mode_class[i] = (1 << (int) D_MODE);
1633 else
1634 arc_mode_class[i] = (1 << (int) V_MODE);
1635 break;
1636 case MODE_CC:
1637 default:
1638 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1639 we must explicitly check for them here. */
1640 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1641 || i == (int) CC_Cmode
1642 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
1643 || i == CC_FPUmode || i == CC_FPU_UNEQmode)
1644 arc_mode_class[i] = 1 << (int) C_MODE;
1645 else
1646 arc_mode_class[i] = 0;
1647 break;
1652 /* Core registers 56..59 are used for multiply extension options.
1653 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1654 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1655 number depends on endianness.
1656 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1657 Because mlo / mhi form a 64 bit value, we use different gcc internal
1658 register numbers to make them form a register pair as the gcc internals
1659 know it. mmid gets number 57, if still available, and mlo / mhi get
1660 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1661 to map this back. */
1662 char rname56[5] = "r56";
1663 char rname57[5] = "r57";
1664 char rname58[5] = "r58";
1665 char rname59[5] = "r59";
1666 char rname29[7] = "ilink1";
1667 char rname30[7] = "ilink2";
1669 static void
1670 arc_conditional_register_usage (void)
1672 int regno;
1673 int i;
1674 int fix_start = 60, fix_end = 55;
1676 if (TARGET_V2)
1678 /* For ARCv2 the core register set is changed. */
1679 strcpy (rname29, "ilink");
1680 strcpy (rname30, "r30");
1682 if (!TEST_HARD_REG_BIT (overrideregs, 30))
1684 /* No user interference. Set the r30 to be used by the
1685 compiler. */
1686 call_used_regs[30] = 1;
1687 fixed_regs[30] = 0;
1689 arc_regno_reg_class[30] = WRITABLE_CORE_REGS;
1690 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], 30);
1691 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], 30);
1692 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 30);
1693 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 30);
1697 if (TARGET_MUL64_SET)
1699 fix_start = 57;
1700 fix_end = 59;
1702 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1703 you are supposed to refer to it as mlo & mhi, e.g
1704 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1705 In an actual asm instruction, you are of course use mmed.
1706 The point of avoiding having a separate register for mmed is that
1707 this way, we don't have to carry clobbers of that reg around in every
1708 isntruction that modifies mlo and/or mhi. */
1709 strcpy (rname57, "");
1710 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo");
1711 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi");
1714 /* The nature of arc_tp_regno is actually something more like a global
1715 register, however globalize_reg requires a declaration.
1716 We use EPILOGUE_USES to compensate so that sets from
1717 __builtin_set_frame_pointer are not deleted. */
1718 if (arc_tp_regno != -1)
1719 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1;
1721 if (TARGET_MULMAC_32BY16_SET)
1723 fix_start = 56;
1724 fix_end = fix_end > 57 ? fix_end : 57;
1725 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1726 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1728 for (regno = fix_start; regno <= fix_end; regno++)
1730 if (!fixed_regs[regno])
1731 warning (0, "multiply option implies r%d is fixed", regno);
1732 fixed_regs [regno] = call_used_regs[regno] = 1;
1734 if (TARGET_Q_CLASS)
1736 if (optimize_size)
1738 reg_alloc_order[0] = 0;
1739 reg_alloc_order[1] = 1;
1740 reg_alloc_order[2] = 2;
1741 reg_alloc_order[3] = 3;
1742 reg_alloc_order[4] = 12;
1743 reg_alloc_order[5] = 13;
1744 reg_alloc_order[6] = 14;
1745 reg_alloc_order[7] = 15;
1746 reg_alloc_order[8] = 4;
1747 reg_alloc_order[9] = 5;
1748 reg_alloc_order[10] = 6;
1749 reg_alloc_order[11] = 7;
1750 reg_alloc_order[12] = 8;
1751 reg_alloc_order[13] = 9;
1752 reg_alloc_order[14] = 10;
1753 reg_alloc_order[15] = 11;
1755 else
1757 reg_alloc_order[2] = 12;
1758 reg_alloc_order[3] = 13;
1759 reg_alloc_order[4] = 14;
1760 reg_alloc_order[5] = 15;
1761 reg_alloc_order[6] = 1;
1762 reg_alloc_order[7] = 0;
1763 reg_alloc_order[8] = 4;
1764 reg_alloc_order[9] = 5;
1765 reg_alloc_order[10] = 6;
1766 reg_alloc_order[11] = 7;
1767 reg_alloc_order[12] = 8;
1768 reg_alloc_order[13] = 9;
1769 reg_alloc_order[14] = 10;
1770 reg_alloc_order[15] = 11;
1773 if (TARGET_SIMD_SET)
1775 int i;
1776 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1777 reg_alloc_order [i] = i;
1778 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1779 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1780 reg_alloc_order [i] = i;
1783 /* Reduced configuration: don't use r4-r9, r16-r25. */
1784 if (TARGET_RF16)
1786 for (i = 4; i <= 9; i++)
1788 fixed_regs[i] = call_used_regs[i] = 1;
1790 for (i = 16; i <= 25; i++)
1792 fixed_regs[i] = call_used_regs[i] = 1;
1796 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1797 if (!call_used_regs[regno])
1798 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
1799 for (regno = 32; regno < 60; regno++)
1800 if (!fixed_regs[regno])
1801 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], regno);
1802 if (!TARGET_ARC600_FAMILY)
1804 for (regno = 32; regno <= 60; regno++)
1805 CLEAR_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], regno);
1807 /* If they have used -ffixed-lp_count, make sure it takes
1808 effect. */
1809 if (fixed_regs[LP_COUNT])
1811 CLEAR_HARD_REG_BIT (reg_class_contents[LPCOUNT_REG], LP_COUNT);
1812 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1813 CLEAR_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], LP_COUNT);
1815 /* Instead of taking out SF_MODE like below, forbid it outright. */
1816 arc_hard_regno_modes[60] = 0;
1818 else
1819 arc_hard_regno_modes[60] = 1 << (int) S_MODE;
1822 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1823 registers. */
1824 if (TARGET_HS)
1826 for (regno = 1; regno < 32; regno +=2)
1828 arc_hard_regno_modes[regno] = S_MODES;
1832 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1834 if (i < 29)
1836 if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
1837 && ((i <= 3) || ((i >= 12) && (i <= 15))))
1838 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1839 else
1840 arc_regno_reg_class[i] = GENERAL_REGS;
1842 else if (i < 60)
1843 arc_regno_reg_class[i]
1844 = (fixed_regs[i]
1845 ? (TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i)
1846 ? CHEAP_CORE_REGS : ALL_CORE_REGS)
1847 : (((!TARGET_ARC600_FAMILY)
1848 && TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i))
1849 ? CHEAP_CORE_REGS : WRITABLE_CORE_REGS));
1850 else
1851 arc_regno_reg_class[i] = NO_REGS;
1854 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1855 has not been activated. */
1856 if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
1857 CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
1858 if (!TARGET_Q_CLASS)
1859 CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
1861 gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
1863 /* Handle Special Registers. */
1864 arc_regno_reg_class[29] = LINK_REGS; /* ilink1 register. */
1865 if (!TARGET_V2)
1866 arc_regno_reg_class[30] = LINK_REGS; /* ilink2 register. */
1867 arc_regno_reg_class[31] = LINK_REGS; /* blink register. */
1868 arc_regno_reg_class[60] = LPCOUNT_REG;
1869 arc_regno_reg_class[61] = NO_REGS; /* CC_REG: must be NO_REGS. */
1870 arc_regno_reg_class[62] = GENERAL_REGS;
1872 if (TARGET_DPFP)
1874 for (i = 40; i < 44; ++i)
1876 arc_regno_reg_class[i] = DOUBLE_REGS;
1878 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1879 no attempt is made to use such a register as a destination
1880 operand in *movdf_insn. */
1881 if (!TARGET_ARGONAUT_SET)
1883 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1884 interpreted to mean they can use D1 or D2 in their insn. */
1885 CLEAR_HARD_REG_BIT(reg_class_contents[CHEAP_CORE_REGS ], i);
1886 CLEAR_HARD_REG_BIT(reg_class_contents[ALL_CORE_REGS ], i);
1887 CLEAR_HARD_REG_BIT(reg_class_contents[WRITABLE_CORE_REGS ], i);
1888 CLEAR_HARD_REG_BIT(reg_class_contents[MPY_WRITABLE_CORE_REGS], i);
1892 else
1894 /* Disable all DOUBLE_REGISTER settings,
1895 if not generating DPFP code. */
1896 arc_regno_reg_class[40] = ALL_REGS;
1897 arc_regno_reg_class[41] = ALL_REGS;
1898 arc_regno_reg_class[42] = ALL_REGS;
1899 arc_regno_reg_class[43] = ALL_REGS;
1901 fixed_regs[40] = 1;
1902 fixed_regs[41] = 1;
1903 fixed_regs[42] = 1;
1904 fixed_regs[43] = 1;
1906 arc_hard_regno_modes[40] = 0;
1907 arc_hard_regno_modes[42] = 0;
1909 CLEAR_HARD_REG_SET(reg_class_contents [DOUBLE_REGS]);
1912 if (TARGET_SIMD_SET)
1914 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1915 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
1917 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1918 arc_regno_reg_class [i] = SIMD_VR_REGS;
1920 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
1921 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
1922 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
1923 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
1925 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1926 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1927 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
1930 /* pc : r63 */
1931 arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
1933 /*ARCV2 Accumulator. */
1934 if ((TARGET_V2
1935 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
1936 || TARGET_PLUS_DMPY)
1938 arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
1939 arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
1940 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCL_REGNO);
1941 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO);
1942 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO);
1943 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO);
1944 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO);
1945 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO);
1946 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCL_REGNO);
1947 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCH_REGNO);
1949 /* Allow the compiler to freely use them. */
1950 if (!TEST_HARD_REG_BIT (overrideregs, ACCL_REGNO))
1951 fixed_regs[ACCL_REGNO] = 0;
1952 if (!TEST_HARD_REG_BIT (overrideregs, ACCH_REGNO))
1953 fixed_regs[ACCH_REGNO] = 0;
1955 if (!fixed_regs[ACCH_REGNO] && !fixed_regs[ACCL_REGNO])
1956 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES;
1960 /* Implement TARGET_HARD_REGNO_NREGS. */
1962 static unsigned int
1963 arc_hard_regno_nregs (unsigned int regno, machine_mode mode)
1965 if (GET_MODE_SIZE (mode) == 16
1966 && regno >= ARC_FIRST_SIMD_VR_REG
1967 && regno <= ARC_LAST_SIMD_VR_REG)
1968 return 1;
1970 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
1973 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1975 static bool
1976 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
1978 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0;
1981 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1983 static bool
1984 arc_modes_tieable_p (machine_mode mode1, machine_mode mode2)
1986 return (GET_MODE_CLASS (mode1) == MODE_INT
1987 && GET_MODE_CLASS (mode2) == MODE_INT
1988 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
1989 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
1992 /* Handle an "interrupt" attribute; arguments as in
1993 struct attribute_spec.handler. */
1995 static tree
1996 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
1997 bool *no_add_attrs)
1999 gcc_assert (args);
2001 tree value = TREE_VALUE (args);
2003 if (TREE_CODE (value) != STRING_CST)
2005 warning (OPT_Wattributes,
2006 "argument of %qE attribute is not a string constant",
2007 name);
2008 *no_add_attrs = true;
2010 else if (!TARGET_V2
2011 && strcmp (TREE_STRING_POINTER (value), "ilink1")
2012 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
2014 warning (OPT_Wattributes,
2015 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2016 name);
2017 *no_add_attrs = true;
2019 else if (TARGET_V2
2020 && strcmp (TREE_STRING_POINTER (value), "ilink")
2021 && strcmp (TREE_STRING_POINTER (value), "firq"))
2023 warning (OPT_Wattributes,
2024 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2025 name);
2026 *no_add_attrs = true;
2029 return NULL_TREE;
2032 static tree
2033 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
2034 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
2036 if (TREE_CODE (*node) != FUNCTION_DECL)
2038 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2039 name);
2040 *no_add_attrs = true;
2043 return NULL_TREE;
2046 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2048 static bool
2049 arc_allocate_stack_slots_for_args (void)
2051 /* Naked functions should not allocate stack slots for arguments. */
2052 unsigned int fn_type = arc_compute_function_type (cfun);
2054 return !ARC_NAKED_P(fn_type);
2057 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2059 static bool
2060 arc_warn_func_return (tree decl)
2062 struct function *func = DECL_STRUCT_FUNCTION (decl);
2063 unsigned int fn_type = arc_compute_function_type (func);
2065 return !ARC_NAKED_P (fn_type);
2068 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2069 and two if they are nearly compatible (which causes a warning to be
2070 generated). */
2072 static int
2073 arc_comp_type_attributes (const_tree type1,
2074 const_tree type2)
2076 int l1, l2, m1, m2, s1, s2;
2078 /* Check for mismatch of non-default calling convention. */
2079 if (TREE_CODE (type1) != FUNCTION_TYPE)
2080 return 1;
2082 /* Check for mismatched call attributes. */
2083 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
2084 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
2085 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
2086 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
2087 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
2088 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
2090 /* Only bother to check if an attribute is defined. */
2091 if (l1 | l2 | m1 | m2 | s1 | s2)
2093 /* If one type has an attribute, the other must have the same attribute. */
2094 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
2095 return 0;
2097 /* Disallow mixed attributes. */
2098 if (l1 + m1 + s1 > 1)
2099 return 0;
2103 return 1;
2106 /* Misc. utilities. */
2108 /* X and Y are two things to compare using CODE. Emit the compare insn and
2109 return the rtx for the cc reg in the proper mode. */
2112 gen_compare_reg (rtx comparison, machine_mode omode)
2114 enum rtx_code code = GET_CODE (comparison);
2115 rtx x = XEXP (comparison, 0);
2116 rtx y = XEXP (comparison, 1);
2117 rtx tmp, cc_reg;
2118 machine_mode mode, cmode;
2121 cmode = GET_MODE (x);
2122 if (cmode == VOIDmode)
2123 cmode = GET_MODE (y);
2124 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode);
2125 if (cmode == SImode)
2127 if (!register_operand (x, SImode))
2129 if (register_operand (y, SImode))
2131 tmp = x;
2132 x = y;
2133 y = tmp;
2134 code = swap_condition (code);
2136 else
2137 x = copy_to_mode_reg (SImode, x);
2139 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
2140 y = copy_to_mode_reg (SImode, y);
2142 else
2144 x = force_reg (cmode, x);
2145 y = force_reg (cmode, y);
2147 mode = SELECT_CC_MODE (code, x, y);
2149 cc_reg = gen_rtx_REG (mode, CC_REG);
2151 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2152 cmpdfpx_raw, is not a correct comparison for floats:
2153 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2155 if (TARGET_ARGONAUT_SET
2156 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2158 switch (code)
2160 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
2161 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2162 break;
2163 case GT: case UNLE: case GE: case UNLT:
2164 code = swap_condition (code);
2165 tmp = x;
2166 x = y;
2167 y = tmp;
2168 break;
2169 default:
2170 gcc_unreachable ();
2172 if (cmode == SFmode)
2174 emit_insn (gen_cmpsfpx_raw (x, y));
2176 else /* DFmode */
2178 /* Accepts Dx regs directly by insns. */
2179 emit_insn (gen_cmpdfpx_raw (x, y));
2182 if (mode != CC_FPXmode)
2183 emit_insn (gen_rtx_SET (cc_reg,
2184 gen_rtx_COMPARE (mode,
2185 gen_rtx_REG (CC_FPXmode, 61),
2186 const0_rtx)));
2188 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2190 switch (code)
2192 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2193 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2194 break;
2195 case LT: case UNGE: case LE: case UNGT:
2196 code = swap_condition (code);
2197 tmp = x;
2198 x = y;
2199 y = tmp;
2200 break;
2201 default:
2202 gcc_unreachable ();
2205 emit_insn (gen_cmp_quark (cc_reg,
2206 gen_rtx_COMPARE (mode, x, y)));
2208 else if (TARGET_HARD_FLOAT
2209 && ((cmode == SFmode && TARGET_FP_SP_BASE)
2210 || (cmode == DFmode && TARGET_FP_DP_BASE)))
2211 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2212 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
2214 rtx op0 = gen_rtx_REG (cmode, 0);
2215 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
2216 bool swap = false;
2218 switch (code)
2220 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2221 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2222 break;
2223 case LT: case UNGE: case LE: case UNGT:
2224 code = swap_condition (code);
2225 swap = true;
2226 break;
2227 default:
2228 gcc_unreachable ();
2230 if (currently_expanding_to_rtl)
2232 if (swap)
2234 tmp = x;
2235 x = y;
2236 y = tmp;
2238 emit_move_insn (op0, x);
2239 emit_move_insn (op1, y);
2241 else
2243 gcc_assert (rtx_equal_p (op0, x));
2244 gcc_assert (rtx_equal_p (op1, y));
2245 if (swap)
2247 op0 = y;
2248 op1 = x;
2251 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2253 else
2254 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2255 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
2258 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2259 We assume the value can be either signed or unsigned. */
2261 bool
2262 arc_double_limm_p (rtx value)
2264 HOST_WIDE_INT low, high;
2266 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2268 if (TARGET_DPFP)
2269 return true;
2271 low = CONST_DOUBLE_LOW (value);
2272 high = CONST_DOUBLE_HIGH (value);
2274 if (low & 0x80000000)
2276 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
2277 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
2278 == - (unsigned HOST_WIDE_INT) 0x80000000)
2279 && high == -1));
2281 else
2283 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2287 /* Do any needed setup for a variadic function. For the ARC, we must
2288 create a register parameter block, and then copy any anonymous arguments
2289 in registers to memory.
2291 CUM has not been updated for the last named argument which has type TYPE
2292 and mode MODE, and we rely on this fact. */
2294 static void
2295 arc_setup_incoming_varargs (cumulative_args_t args_so_far,
2296 machine_mode mode, tree type,
2297 int *pretend_size, int no_rtl)
2299 int first_anon_arg;
2300 CUMULATIVE_ARGS next_cum;
2302 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2304 next_cum = *get_cumulative_args (args_so_far);
2305 arc_function_arg_advance (pack_cumulative_args (&next_cum),
2306 mode, type, true);
2307 first_anon_arg = next_cum;
2309 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2311 /* First anonymous (unnamed) argument is in a reg. */
2313 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2314 int first_reg_offset = first_anon_arg;
2316 if (!no_rtl)
2318 rtx regblock
2319 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2320 FIRST_PARM_OFFSET (0)));
2321 move_block_from_reg (first_reg_offset, regblock,
2322 MAX_ARC_PARM_REGS - first_reg_offset);
2325 *pretend_size
2326 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2330 /* Cost functions. */
2332 /* Provide the costs of an addressing mode that contains ADDR.
2333 If ADDR is not a valid address, its cost is irrelevant. */
2335 static int
2336 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2338 switch (GET_CODE (addr))
2340 case REG :
2341 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1;
2342 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2343 case PRE_MODIFY: case POST_MODIFY:
2344 return !speed;
2346 case LABEL_REF :
2347 case SYMBOL_REF :
2348 case CONST :
2349 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2350 return 0;
2351 /* Most likely needs a LIMM. */
2352 return COSTS_N_INSNS (1);
2354 case PLUS :
2356 register rtx plus0 = XEXP (addr, 0);
2357 register rtx plus1 = XEXP (addr, 1);
2359 if (GET_CODE (plus0) != REG
2360 && (GET_CODE (plus0) != MULT
2361 || !CONST_INT_P (XEXP (plus0, 1))
2362 || (INTVAL (XEXP (plus0, 1)) != 2
2363 && INTVAL (XEXP (plus0, 1)) != 4)))
2364 break;
2366 switch (GET_CODE (plus1))
2368 case CONST_INT :
2369 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2370 ? COSTS_N_INSNS (1)
2371 : speed
2373 : (satisfies_constraint_Rcq (plus0)
2374 && satisfies_constraint_O (plus1))
2376 : 1);
2377 case REG:
2378 return (speed < 1 ? 0
2379 : (satisfies_constraint_Rcq (plus0)
2380 && satisfies_constraint_Rcq (plus1))
2381 ? 0 : 1);
2382 case CONST :
2383 case SYMBOL_REF :
2384 case LABEL_REF :
2385 return COSTS_N_INSNS (1);
2386 default:
2387 break;
2389 break;
2391 default:
2392 break;
2395 return 4;
2398 /* Emit instruction X with the frame related bit set. */
2400 static rtx
2401 frame_insn (rtx x)
2403 x = emit_insn (x);
2404 RTX_FRAME_RELATED_P (x) = 1;
2405 return x;
2408 /* Emit a frame insn to move SRC to DST. */
2410 static rtx
2411 frame_move (rtx dst, rtx src)
2413 rtx tmp = gen_rtx_SET (dst, src);
2414 RTX_FRAME_RELATED_P (tmp) = 1;
2415 return frame_insn (tmp);
2418 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2419 auto increment address, or is zero. */
2421 static rtx
2422 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2424 rtx insn = frame_move (dst, src);
2426 if (!addr
2427 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2428 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2429 add_reg_note (insn, REG_INC, reg);
2430 return insn;
2433 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2435 static rtx
2436 frame_add (rtx reg, HOST_WIDE_INT offset)
2438 gcc_assert ((offset & 0x3) == 0);
2439 if (!offset)
2440 return NULL_RTX;
2441 return frame_move (reg, plus_constant (Pmode, reg, offset));
2444 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2446 static rtx
2447 frame_stack_add (HOST_WIDE_INT offset)
2449 return frame_add (stack_pointer_rtx, offset);
2452 /* Traditionally, we push saved registers first in the prologue,
2453 then we allocate the rest of the frame - and reverse in the epilogue.
2454 This has still its merits for ease of debugging, or saving code size
2455 or even execution time if the stack frame is so large that some accesses
2456 can't be encoded anymore with offsets in the instruction code when using
2457 a different scheme.
2458 Also, it would be a good starting point if we got instructions to help
2459 with register save/restore.
2461 However, often stack frames are small, and the pushing / popping has
2462 some costs:
2463 - the stack modification prevents a lot of scheduling.
2464 - frame allocation / deallocation needs extra instructions.
2465 - unless we know that we compile ARC700 user code, we need to put
2466 a memory barrier after frame allocation / before deallocation to
2467 prevent interrupts clobbering our data in the frame.
2468 In particular, we don't have any such guarantees for library functions,
2469 which tend to, on the other hand, to have small frames.
2471 Thus, for small frames, we'd like to use a different scheme:
2472 - The frame is allocated in full with the first prologue instruction,
2473 and deallocated in full with the last epilogue instruction.
2474 Thus, the instructions in-betwen can be freely scheduled.
2475 - If the function has no outgoing arguments on the stack, we can allocate
2476 one register save slot at the top of the stack. This register can then
2477 be saved simultanously with frame allocation, and restored with
2478 frame deallocation.
2479 This register can be picked depending on scheduling considerations,
2480 although same though should go into having some set of registers
2481 to be potentially lingering after a call, and others to be available
2482 immediately - i.e. in the absence of interprocedual optimization, we
2483 can use an ABI-like convention for register allocation to reduce
2484 stalls after function return. */
2485 /* Function prologue/epilogue handlers. */
2487 /* ARCompact stack frames look like:
2489 Before call After call
2490 high +-----------------------+ +-----------------------+
2491 mem | reg parm save area | | reg parm save area |
2492 | only created for | | only created for |
2493 | variable arg fns | | variable arg fns |
2494 AP +-----------------------+ +-----------------------+
2495 | return addr register | | return addr register |
2496 | (if required) | | (if required) |
2497 +-----------------------+ +-----------------------+
2498 | | | |
2499 | reg save area | | reg save area |
2500 | | | |
2501 +-----------------------+ +-----------------------+
2502 | frame pointer | | frame pointer |
2503 | (if required) | | (if required) |
2504 FP +-----------------------+ +-----------------------+
2505 | | | |
2506 | local/temp variables | | local/temp variables |
2507 | | | |
2508 +-----------------------+ +-----------------------+
2509 | | | |
2510 | arguments on stack | | arguments on stack |
2511 | | | |
2512 SP +-----------------------+ +-----------------------+
2513 | reg parm save area |
2514 | only created for |
2515 | variable arg fns |
2516 AP +-----------------------+
2517 | return addr register |
2518 | (if required) |
2519 +-----------------------+
2521 | reg save area |
2523 +-----------------------+
2524 | frame pointer |
2525 | (if required) |
2526 FP +-----------------------+
2528 | local/temp variables |
2530 +-----------------------+
2532 | arguments on stack |
2533 low | |
2534 mem SP +-----------------------+
2536 Notes:
2537 1) The "reg parm save area" does not exist for non variable argument fns.
2538 The "reg parm save area" can be eliminated completely if we created our
2539 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2541 /* Structure to be filled in by arc_compute_frame_size with register
2542 save masks, and offsets for the current function. */
2543 struct GTY (()) arc_frame_info
2545 unsigned int total_size; /* # bytes that the entire frame takes up. */
2546 unsigned int extra_size; /* # bytes of extra stuff. */
2547 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
2548 unsigned int args_size; /* # bytes that outgoing arguments take up. */
2549 unsigned int reg_size; /* # bytes needed to store regs. */
2550 unsigned int var_size; /* # bytes that variables take up. */
2551 unsigned int reg_offset; /* Offset from new sp to store regs. */
2552 unsigned int gmask; /* Mask of saved gp registers. */
2553 int initialized; /* Nonzero if frame size already calculated. */
2554 short millicode_start_reg;
2555 short millicode_end_reg;
2556 bool save_return_addr;
2559 /* Defining data structures for per-function information. */
2561 typedef struct GTY (()) machine_function
2563 unsigned int fn_type;
2564 struct arc_frame_info frame_info;
2565 /* To keep track of unalignment caused by short insns. */
2566 int unalign;
2567 int force_short_suffix; /* Used when disgorging return delay slot insns. */
2568 const char *size_reason;
2569 struct arc_ccfsm ccfsm_current;
2570 /* Map from uid to ccfsm state during branch shortening. */
2571 rtx ccfsm_current_insn;
2572 char arc_reorg_started;
2573 char prescan_initialized;
2574 } machine_function;
2576 /* Type of function DECL.
2578 The result is cached. To reset the cache at the end of a function,
2579 call with DECL = NULL_TREE. */
2581 unsigned int
2582 arc_compute_function_type (struct function *fun)
2584 tree attr, decl = fun->decl;
2585 unsigned int fn_type = fun->machine->fn_type;
2587 if (fn_type != ARC_FUNCTION_UNKNOWN)
2588 return fn_type;
2590 /* Check if it is a naked function. */
2591 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
2592 fn_type |= ARC_FUNCTION_NAKED;
2593 else
2594 fn_type |= ARC_FUNCTION_NORMAL;
2596 /* Now see if this is an interrupt handler. */
2597 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2598 if (attr != NULL_TREE)
2600 tree value, args = TREE_VALUE (attr);
2602 gcc_assert (list_length (args) == 1);
2603 value = TREE_VALUE (args);
2604 gcc_assert (TREE_CODE (value) == STRING_CST);
2606 if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
2607 || !strcmp (TREE_STRING_POINTER (value), "ilink"))
2608 fn_type |= ARC_FUNCTION_ILINK1;
2609 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
2610 fn_type |= ARC_FUNCTION_ILINK2;
2611 else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
2612 fn_type |= ARC_FUNCTION_FIRQ;
2613 else
2614 gcc_unreachable ();
2617 return fun->machine->fn_type = fn_type;
2620 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2621 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2623 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2624 The return address and frame pointer are treated separately.
2625 Don't consider them here.
2626 Addition for pic: The gp register needs to be saved if the current
2627 function changes it to access gotoff variables.
2628 FIXME: This will not be needed if we used some arbitrary register
2629 instead of r26. */
2631 static bool
2632 arc_must_save_register (int regno, struct function *func)
2634 unsigned int fn_type = arc_compute_function_type (func);
2635 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2636 && ARC_AUTO_IRQ_P (fn_type));
2637 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2639 switch (rgf_banked_register_count)
2641 case 4:
2642 firq_auto_save_p &= (regno < 4);
2643 break;
2644 case 8:
2645 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2646 break;
2647 case 16:
2648 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2649 || ((regno > 25) && (regno < 29))
2650 || ((regno > 29) && (regno < 32)));
2651 break;
2652 case 32:
2653 firq_auto_save_p &= (regno != 29) && (regno < 32);
2654 break;
2655 default:
2656 firq_auto_save_p = false;
2657 break;
2660 if ((regno) != RETURN_ADDR_REGNUM
2661 && (regno) != FRAME_POINTER_REGNUM
2662 && df_regs_ever_live_p (regno)
2663 && (!call_used_regs[regno]
2664 || ARC_INTERRUPT_P (fn_type))
2665 /* Do not emit code for auto saved regs. */
2666 && !irq_auto_save_p
2667 && !firq_auto_save_p)
2668 return true;
2670 return false;
2673 /* Return true if the return address must be saved in the current function,
2674 otherwise return false. */
2676 static bool
2677 arc_must_save_return_addr (struct function *func)
2679 if (func->machine->frame_info.save_return_addr)
2680 return true;
2682 return false;
2685 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2686 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2687 Register Allocator) pass, while we want to get the frame size
2688 correct earlier than the IRA pass.
2690 When a function uses eh_return we must ensure that the fp register
2691 is saved and then restored so that the unwinder can restore the
2692 correct value for the frame we are going to jump to.
2694 To do this we force all frames that call eh_return to require a
2695 frame pointer (see arc_frame_pointer_required), this
2696 will ensure that the previous frame pointer is stored on entry to
2697 the function, and will then be reloaded at function exit.
2699 As the frame pointer is handled as a special case in our prologue
2700 and epilogue code it must not be saved and restored using the
2701 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2702 believes that the function is not using a frame pointer and that
2703 the value in the fp register is the frame pointer, while the
2704 prologue and epilogue are busy saving and restoring the fp
2705 register.
2707 During compilation of a function the frame size is evaluated
2708 multiple times, it is not until the reload pass is complete the the
2709 frame size is considered fixed (it is at this point that space for
2710 all spills has been allocated). However the frame_pointer_needed
2711 variable is not set true until the register allocation pass, as a
2712 result in the early stages the frame size does not include space
2713 for the frame pointer to be spilled.
2715 The problem that this causes is that the rtl generated for
2716 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2717 the offset from the frame pointer at which the return address
2718 lives. However, in early passes GCC has not yet realised we need a
2719 frame pointer, and so has not included space for the frame pointer
2720 in the frame size, and so gets the offset of the return address
2721 wrong. This should not be an issue as in later passes GCC has
2722 realised that the frame pointer needs to be spilled, and has
2723 increased the frame size. However, the rtl for the
2724 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2725 offset, and the wrong smaller offset is used. */
2727 static bool
2728 arc_frame_pointer_needed (void)
2730 return (frame_pointer_needed || crtl->calls_eh_return);
2733 /* Return non-zero if there are registers to be saved or loaded using
2734 millicode thunks. We can only use consecutive sequences starting
2735 with r13, and not going beyond r25.
2736 GMASK is a bitmask of registers to save. This function sets
2737 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2738 of registers to be saved / restored with a millicode call. */
2740 static int
2741 arc_compute_millicode_save_restore_regs (unsigned int gmask,
2742 struct arc_frame_info *frame)
2744 int regno;
2746 int start_reg = 13, end_reg = 25;
2748 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
2749 regno++;
2750 end_reg = regno - 1;
2751 /* There is no point in using millicode thunks if we don't save/restore
2752 at least three registers. For non-leaf functions we also have the
2753 blink restore. */
2754 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2756 frame->millicode_start_reg = 13;
2757 frame->millicode_end_reg = regno - 1;
2758 return 1;
2760 return 0;
2763 /* Return the bytes needed to compute the frame pointer from the
2764 current stack pointer. */
2766 static unsigned int
2767 arc_compute_frame_size (void)
2769 int regno;
2770 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2771 unsigned int reg_size, reg_offset;
2772 unsigned int gmask;
2773 struct arc_frame_info *frame_info;
2774 int size;
2776 /* The answer might already be known. */
2777 if (cfun->machine->frame_info.initialized)
2778 return cfun->machine->frame_info.total_size;
2780 frame_info = &cfun->machine->frame_info;
2781 size = ARC_STACK_ALIGN (get_frame_size ());
2783 /* 1) Size of locals and temporaries. */
2784 var_size = size;
2786 /* 2) Size of outgoing arguments. */
2787 args_size = crtl->outgoing_args_size;
2789 /* 3) Calculate space needed for saved registers.
2790 ??? We ignore the extension registers for now. */
2792 /* See if this is an interrupt handler. Call used registers must be saved
2793 for them too. */
2795 reg_size = 0;
2796 gmask = 0;
2798 for (regno = 0; regno <= 31; regno++)
2800 if (arc_must_save_register (regno, cfun))
2802 reg_size += UNITS_PER_WORD;
2803 gmask |= 1L << regno;
2807 /* In a frame that calls __builtin_eh_return two data registers are
2808 used to pass values back to the exception handler.
2810 Ensure that these registers are spilled to the stack so that the
2811 exception throw code can find them, and update the saved values.
2812 The handling code will then consume these reloaded values to
2813 handle the exception. */
2814 if (crtl->calls_eh_return)
2815 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
2817 reg_size += UNITS_PER_WORD;
2818 gmask |= 1 << regno;
2821 /* 4) Space for back trace data structure.
2822 <return addr reg size> (if required) + <fp size> (if required). */
2823 frame_info->save_return_addr
2824 = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2825 || crtl->calls_eh_return);
2826 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2827 if (optimize_size
2828 && !TARGET_NO_MILLICODE_THUNK_SET
2829 && !crtl->calls_eh_return)
2831 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2832 frame_info->save_return_addr = true;
2835 extra_size = 0;
2836 if (arc_must_save_return_addr (cfun))
2837 extra_size = 4;
2838 if (arc_frame_pointer_needed ())
2839 extra_size += 4;
2841 /* 5) Space for variable arguments passed in registers */
2842 pretend_size = crtl->args.pretend_args_size;
2844 /* Ensure everything before the locals is aligned appropriately. */
2846 unsigned int extra_plus_reg_size;
2847 unsigned int extra_plus_reg_size_aligned;
2849 extra_plus_reg_size = extra_size + reg_size;
2850 extra_plus_reg_size_aligned = ARC_STACK_ALIGN(extra_plus_reg_size);
2851 reg_size = extra_plus_reg_size_aligned - extra_size;
2854 /* Compute total frame size. */
2855 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2857 /* It used to be the case that the alignment was forced at this
2858 point. However, that is dangerous, calculations based on
2859 total_size would be wrong. Given that this has never cropped up
2860 as an issue I've changed this to an assert for now. */
2861 gcc_assert (total_size == ARC_STACK_ALIGN (total_size));
2863 /* Compute offset of register save area from stack pointer:
2864 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2866 reg_offset = (total_size - (pretend_size + reg_size + extra_size)
2867 + (arc_frame_pointer_needed () ? 4 : 0));
2869 /* Save computed information. */
2870 frame_info->total_size = total_size;
2871 frame_info->extra_size = extra_size;
2872 frame_info->pretend_size = pretend_size;
2873 frame_info->var_size = var_size;
2874 frame_info->args_size = args_size;
2875 frame_info->reg_size = reg_size;
2876 frame_info->reg_offset = reg_offset;
2877 frame_info->gmask = gmask;
2878 frame_info->initialized = reload_completed;
2880 /* Ok, we're done. */
2881 return total_size;
2884 /* Common code to save/restore registers. */
2885 /* BASE_REG is the base register to use for addressing and to adjust.
2886 GMASK is a bitmask of general purpose registers to save/restore.
2887 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2888 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2889 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2890 zeroed. */
2892 static void
2893 arc_save_restore (rtx base_reg,
2894 unsigned int gmask, int epilogue_p, int *first_offset)
2896 unsigned int offset = 0;
2897 int regno;
2898 struct arc_frame_info *frame = &cfun->machine->frame_info;
2899 rtx sibthunk_insn = NULL_RTX;
2901 if (gmask)
2903 /* Millicode thunks implementation:
2904 Generates calls to millicodes for registers starting from r13 to r25
2905 Present Limitations:
2906 - Only one range supported. The remaining regs will have the ordinary
2907 st and ld instructions for store and loads. Hence a gmask asking
2908 to store r13-14, r16-r25 will only generate calls to store and
2909 load r13 to r14 while store and load insns will be generated for
2910 r16 to r25 in the prologue and epilogue respectively.
2912 - Presently library only supports register ranges starting from r13.
2914 if (epilogue_p == 2 || frame->millicode_end_reg > 14)
2916 int start_call = frame->millicode_start_reg;
2917 int end_call = frame->millicode_end_reg;
2918 int n_regs = end_call - start_call + 1;
2919 int i = 0, r, off = 0;
2920 rtx insn;
2921 rtx ret_addr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
2923 if (*first_offset)
2925 /* "reg_size" won't be more than 127 . */
2926 gcc_assert (epilogue_p || abs (*first_offset) <= 127);
2927 frame_add (base_reg, *first_offset);
2928 *first_offset = 0;
2930 insn = gen_rtx_PARALLEL
2931 (VOIDmode, rtvec_alloc ((epilogue_p == 2) + n_regs + 1));
2932 if (epilogue_p == 2)
2933 i += 2;
2934 else
2935 XVECEXP (insn, 0, n_regs) = gen_rtx_CLOBBER (VOIDmode, ret_addr);
2936 for (r = start_call; r <= end_call; r++, off += UNITS_PER_WORD, i++)
2938 rtx reg = gen_rtx_REG (SImode, r);
2939 rtx mem
2940 = gen_frame_mem (SImode, plus_constant (Pmode, base_reg, off));
2942 if (epilogue_p)
2943 XVECEXP (insn, 0, i) = gen_rtx_SET (reg, mem);
2944 else
2945 XVECEXP (insn, 0, i) = gen_rtx_SET (mem, reg);
2946 gmask = gmask & ~(1L << r);
2948 if (epilogue_p == 2)
2949 sibthunk_insn = insn;
2950 else
2952 insn = frame_insn (insn);
2953 for (r = start_call, off = 0;
2954 r <= end_call;
2955 r++, off += UNITS_PER_WORD)
2957 rtx reg = gen_rtx_REG (SImode, r);
2958 if (epilogue_p)
2959 add_reg_note (insn, REG_CFA_RESTORE, reg);
2960 else
2962 rtx mem = gen_rtx_MEM (SImode, plus_constant (Pmode,
2963 base_reg,
2964 off));
2966 add_reg_note (insn, REG_CFA_OFFSET,
2967 gen_rtx_SET (mem, reg));
2971 offset += off;
2974 for (regno = 0; regno <= 31; regno++)
2976 machine_mode mode = SImode;
2977 bool found = false;
2979 if (TARGET_LL64
2980 && (regno % 2 == 0)
2981 && ((gmask & (1L << regno)) != 0)
2982 && ((gmask & (1L << (regno+1))) != 0))
2984 found = true;
2985 mode = DImode;
2987 else if ((gmask & (1L << regno)) != 0)
2989 found = true;
2990 mode = SImode;
2993 if (found)
2995 rtx reg = gen_rtx_REG (mode, regno);
2996 rtx addr, mem;
2997 int cfa_adjust = *first_offset;
2999 if (*first_offset)
3001 gcc_assert (!offset);
3002 addr = plus_constant (Pmode, base_reg, *first_offset);
3003 addr = gen_rtx_PRE_MODIFY (Pmode, base_reg, addr);
3004 *first_offset = 0;
3006 else
3008 gcc_assert (SMALL_INT (offset));
3009 addr = plus_constant (Pmode, base_reg, offset);
3011 mem = gen_frame_mem (mode, addr);
3012 if (epilogue_p)
3014 rtx insn =
3015 frame_move_inc (reg, mem, base_reg, addr);
3016 add_reg_note (insn, REG_CFA_RESTORE, reg);
3017 if (cfa_adjust)
3019 enum reg_note note = REG_CFA_ADJUST_CFA;
3020 add_reg_note (insn, note,
3021 gen_rtx_SET (stack_pointer_rtx,
3022 plus_constant (Pmode,
3023 stack_pointer_rtx,
3024 cfa_adjust)));
3027 else
3028 frame_move_inc (mem, reg, base_reg, addr);
3029 offset += UNITS_PER_WORD;
3030 if (mode == DImode)
3032 offset += UNITS_PER_WORD;
3033 ++regno;
3035 } /* if */
3036 } /* for */
3037 }/* if */
3038 if (sibthunk_insn)
3040 int start_call = frame->millicode_start_reg;
3041 int end_call = frame->millicode_end_reg;
3042 int r;
3044 rtx r12 = gen_rtx_REG (Pmode, 12);
3046 frame_insn (gen_rtx_SET (r12, GEN_INT (offset)));
3047 XVECEXP (sibthunk_insn, 0, 0) = ret_rtx;
3048 XVECEXP (sibthunk_insn, 0, 1)
3049 = gen_rtx_SET (stack_pointer_rtx,
3050 gen_rtx_PLUS (Pmode, stack_pointer_rtx, r12));
3051 sibthunk_insn = emit_jump_insn (sibthunk_insn);
3052 RTX_FRAME_RELATED_P (sibthunk_insn) = 1;
3054 /* Would be nice if we could do this earlier, when the PARALLEL
3055 is populated, but these need to be attached after the
3056 emit. */
3057 for (r = start_call; r <= end_call; r++)
3059 rtx reg = gen_rtx_REG (SImode, r);
3060 add_reg_note (sibthunk_insn, REG_CFA_RESTORE, reg);
3063 } /* arc_save_restore */
3065 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
3066 mechanism. */
3068 static void
3069 arc_dwarf_emit_irq_save_regs (void)
3071 rtx tmp, par, insn, reg;
3072 int i, offset, j;
3074 par = gen_rtx_SEQUENCE (VOIDmode,
3075 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
3076 + irq_ctrl_saved.irq_save_blink
3077 + irq_ctrl_saved.irq_save_lpcount
3078 + 1));
3080 /* Build the stack adjustment note for unwind info. */
3081 j = 0;
3082 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
3083 + irq_ctrl_saved.irq_save_blink
3084 + irq_ctrl_saved.irq_save_lpcount);
3085 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
3086 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
3087 RTX_FRAME_RELATED_P (tmp) = 1;
3088 XVECEXP (par, 0, j++) = tmp;
3090 offset -= UNITS_PER_WORD;
3092 /* 1st goes LP_COUNT. */
3093 if (irq_ctrl_saved.irq_save_lpcount)
3095 reg = gen_rtx_REG (SImode, 60);
3096 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
3097 tmp = gen_frame_mem (SImode, tmp);
3098 tmp = gen_rtx_SET (tmp, reg);
3099 RTX_FRAME_RELATED_P (tmp) = 1;
3100 XVECEXP (par, 0, j++) = tmp;
3101 offset -= UNITS_PER_WORD;
3104 /* 2nd goes BLINK. */
3105 if (irq_ctrl_saved.irq_save_blink)
3107 reg = gen_rtx_REG (SImode, 31);
3108 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
3109 tmp = gen_frame_mem (SImode, tmp);
3110 tmp = gen_rtx_SET (tmp, reg);
3111 RTX_FRAME_RELATED_P (tmp) = 1;
3112 XVECEXP (par, 0, j++) = tmp;
3113 offset -= UNITS_PER_WORD;
3116 /* Build the parallel of the remaining registers recorded as saved
3117 for unwind. */
3118 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
3120 reg = gen_rtx_REG (SImode, i);
3121 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
3122 tmp = gen_frame_mem (SImode, tmp);
3123 tmp = gen_rtx_SET (tmp, reg);
3124 RTX_FRAME_RELATED_P (tmp) = 1;
3125 XVECEXP (par, 0, j++) = tmp;
3126 offset -= UNITS_PER_WORD;
3129 /* Dummy insn used to anchor the dwarf info. */
3130 insn = emit_insn (gen_stack_irq_dwarf());
3131 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
3132 RTX_FRAME_RELATED_P (insn) = 1;
3135 /* Set up the stack and frame pointer (if desired) for the function. */
3137 void
3138 arc_expand_prologue (void)
3140 int size;
3141 unsigned int gmask = cfun->machine->frame_info.gmask;
3142 /* unsigned int frame_pointer_offset;*/
3143 unsigned int frame_size_to_allocate;
3144 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
3145 Change the stack layout so that we rather store a high register with the
3146 PRE_MODIFY, thus enabling more short insn generation.) */
3147 int first_offset = 0;
3148 unsigned int fn_type = arc_compute_function_type (cfun);
3150 /* Naked functions don't have prologue. */
3151 if (ARC_NAKED_P (fn_type))
3153 if (flag_stack_usage_info)
3154 current_function_static_stack_size = 0;
3155 return;
3158 /* Compute total frame size. */
3159 size = arc_compute_frame_size ();
3161 if (flag_stack_usage_info)
3162 current_function_static_stack_size = size;
3164 /* Keep track of frame size to be allocated. */
3165 frame_size_to_allocate = size;
3167 /* These cases shouldn't happen. Catch them now. */
3168 gcc_assert (!(size == 0 && gmask));
3170 /* Allocate space for register arguments if this is a variadic function. */
3171 if (cfun->machine->frame_info.pretend_size != 0)
3173 /* Ensure pretend_size is maximum of 8 * word_size. */
3174 gcc_assert (cfun->machine->frame_info.pretend_size <= 32);
3176 frame_stack_add (-(HOST_WIDE_INT)cfun->machine->frame_info.pretend_size);
3177 frame_size_to_allocate -= cfun->machine->frame_info.pretend_size;
3180 /* IRQ using automatic save mechanism will save the register before
3181 anything we do. */
3182 if (ARC_AUTO_IRQ_P (fn_type)
3183 && !ARC_FAST_INTERRUPT_P (fn_type))
3185 arc_dwarf_emit_irq_save_regs ();
3188 /* The home-grown ABI says link register is saved first. */
3189 if (arc_must_save_return_addr (cfun)
3190 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3192 rtx ra = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
3193 rtx mem = gen_frame_mem (Pmode,
3194 gen_rtx_PRE_DEC (Pmode,
3195 stack_pointer_rtx));
3197 frame_move_inc (mem, ra, stack_pointer_rtx, 0);
3198 frame_size_to_allocate -= UNITS_PER_WORD;
3201 /* Save any needed call-saved regs (and call-used if this is an
3202 interrupt handler) for ARCompact ISA. */
3203 if (cfun->machine->frame_info.reg_size)
3205 first_offset = -cfun->machine->frame_info.reg_size;
3206 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3207 arc_save_restore (stack_pointer_rtx, gmask, 0, &first_offset);
3208 frame_size_to_allocate -= cfun->machine->frame_info.reg_size;
3211 /* In the case of millicode thunk, we need to restore the clobbered
3212 blink register. */
3213 if (cfun->machine->frame_info.millicode_end_reg > 0
3214 && arc_must_save_return_addr (cfun))
3216 HOST_WIDE_INT tmp = cfun->machine->frame_info.reg_size;
3217 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
3218 gen_rtx_MEM (Pmode,
3219 plus_constant (Pmode,
3220 stack_pointer_rtx,
3221 tmp))));
3224 /* Save frame pointer if needed. First save the FP on stack, if not
3225 autosaved. */
3226 if (arc_frame_pointer_needed ()
3227 && !ARC_AUTOFP_IRQ_P (fn_type))
3229 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3230 GEN_INT (-UNITS_PER_WORD + first_offset));
3231 rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_MODIFY (Pmode,
3232 stack_pointer_rtx,
3233 addr));
3234 frame_move_inc (mem, frame_pointer_rtx, stack_pointer_rtx, 0);
3235 frame_size_to_allocate -= UNITS_PER_WORD;
3236 first_offset = 0;
3239 /* Emit mov fp,sp. */
3240 if (arc_frame_pointer_needed ())
3242 frame_move (frame_pointer_rtx, stack_pointer_rtx);
3245 /* ??? We don't handle the case where the saved regs are more than 252
3246 bytes away from sp. This can be handled by decrementing sp once, saving
3247 the regs, and then decrementing it again. The epilogue doesn't have this
3248 problem as the `ld' insn takes reg+limm values (though it would be more
3249 efficient to avoid reg+limm). */
3251 frame_size_to_allocate -= first_offset;
3252 /* Allocate the stack frame. */
3253 if (frame_size_to_allocate > 0)
3255 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3256 /* If the frame pointer is needed, emit a special barrier that
3257 will prevent the scheduler from moving stores to the frame
3258 before the stack adjustment. */
3259 if (arc_frame_pointer_needed ())
3260 emit_insn (gen_stack_tie (stack_pointer_rtx,
3261 hard_frame_pointer_rtx));
3265 /* Do any necessary cleanup after a function to restore stack, frame,
3266 and regs. */
3268 void
3269 arc_expand_epilogue (int sibcall_p)
3271 int size;
3272 unsigned int fn_type = arc_compute_function_type (cfun);
3274 size = arc_compute_frame_size ();
3276 unsigned int pretend_size = cfun->machine->frame_info.pretend_size;
3277 unsigned int frame_size;
3278 unsigned int size_to_deallocate;
3279 int restored;
3280 int can_trust_sp_p = !cfun->calls_alloca;
3281 int first_offset = 0;
3282 int millicode_p = cfun->machine->frame_info.millicode_end_reg > 0;
3283 rtx insn;
3285 /* Naked functions don't have epilogue. */
3286 if (ARC_NAKED_P (fn_type))
3287 return;
3289 size_to_deallocate = size;
3291 frame_size = size - (pretend_size +
3292 cfun->machine->frame_info.reg_size +
3293 cfun->machine->frame_info.extra_size);
3295 /* ??? There are lots of optimizations that can be done here.
3296 EG: Use fp to restore regs if it's closer.
3297 Maybe in time we'll do them all. For now, always restore regs from
3298 sp, but don't restore sp if we don't have to. */
3300 if (!can_trust_sp_p)
3301 gcc_assert (arc_frame_pointer_needed ());
3303 /* Restore stack pointer to the beginning of saved register area for
3304 ARCompact ISA. */
3305 if (frame_size)
3307 if (arc_frame_pointer_needed ())
3308 frame_move (stack_pointer_rtx, frame_pointer_rtx);
3309 else
3310 first_offset = frame_size;
3311 size_to_deallocate -= frame_size;
3313 else if (!can_trust_sp_p)
3314 frame_stack_add (-frame_size);
3317 /* Restore any saved registers. */
3318 if (arc_frame_pointer_needed ()
3319 && !ARC_AUTOFP_IRQ_P (fn_type))
3321 rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
3323 insn = frame_move_inc (frame_pointer_rtx, gen_frame_mem (Pmode, addr),
3324 stack_pointer_rtx, 0);
3325 add_reg_note (insn, REG_CFA_RESTORE, frame_pointer_rtx);
3326 add_reg_note (insn, REG_CFA_DEF_CFA,
3327 plus_constant (SImode, stack_pointer_rtx,
3328 4));
3329 size_to_deallocate -= UNITS_PER_WORD;
3332 /* Load blink after the calls to thunk calls in case of optimize size. */
3333 if (millicode_p)
3335 int sibthunk_p = (!sibcall_p
3336 && fn_type == ARC_FUNCTION_NORMAL
3337 && !cfun->machine->frame_info.pretend_size);
3339 gcc_assert (!(cfun->machine->frame_info.gmask
3340 & (FRAME_POINTER_MASK | RETURN_ADDR_MASK)));
3341 arc_save_restore (stack_pointer_rtx,
3342 cfun->machine->frame_info.gmask,
3343 1 + sibthunk_p, &first_offset);
3344 if (sibthunk_p)
3345 return;
3347 /* If we are to restore registers, and first_offset would require
3348 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3349 fast add to the stack pointer, do this now. */
3350 if ((!SMALL_INT (first_offset)
3351 && cfun->machine->frame_info.gmask
3352 && ((TARGET_ARC700 && !optimize_size)
3353 ? first_offset <= 0x800
3354 : satisfies_constraint_C2a (GEN_INT (first_offset))))
3355 /* Also do this if we have both gprs and return
3356 address to restore, and they both would need a LIMM. */
3357 || (arc_must_save_return_addr (cfun)
3358 && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2)
3359 && cfun->machine->frame_info.gmask))
3361 frame_stack_add (first_offset);
3362 first_offset = 0;
3364 if (arc_must_save_return_addr (cfun)
3365 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3367 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3368 int ra_offs = cfun->machine->frame_info.reg_size + first_offset;
3369 rtx addr = plus_constant (Pmode, stack_pointer_rtx, ra_offs);
3370 HOST_WIDE_INT cfa_adjust = 0;
3372 /* If the load of blink would need a LIMM, but we can add
3373 the offset quickly to sp, do the latter. */
3374 if (!SMALL_INT (ra_offs >> 2)
3375 && !cfun->machine->frame_info.gmask
3376 && ((TARGET_ARC700 && !optimize_size)
3377 ? ra_offs <= 0x800
3378 : satisfies_constraint_C2a (GEN_INT (ra_offs))))
3380 size_to_deallocate -= ra_offs - first_offset;
3381 first_offset = 0;
3382 frame_stack_add (ra_offs);
3383 ra_offs = 0;
3384 addr = stack_pointer_rtx;
3386 /* See if we can combine the load of the return address with the
3387 final stack adjustment.
3388 We need a separate load if there are still registers to
3389 restore. We also want a separate load if the combined insn
3390 would need a limm, but a separate load doesn't. */
3391 if (ra_offs
3392 && !cfun->machine->frame_info.gmask
3393 && (SMALL_INT (ra_offs) || !SMALL_INT (ra_offs >> 2)))
3395 addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, addr);
3396 cfa_adjust = ra_offs;
3397 first_offset = 0;
3398 size_to_deallocate -= cfun->machine->frame_info.reg_size;
3400 else if (!ra_offs && size_to_deallocate == UNITS_PER_WORD)
3402 addr = gen_rtx_POST_INC (Pmode, addr);
3403 cfa_adjust = GET_MODE_SIZE (Pmode);
3404 size_to_deallocate = 0;
3407 insn = frame_move_inc (ra, gen_frame_mem (Pmode, addr),
3408 stack_pointer_rtx, addr);
3409 if (cfa_adjust)
3411 enum reg_note note = REG_CFA_ADJUST_CFA;
3413 add_reg_note (insn, note,
3414 gen_rtx_SET (stack_pointer_rtx,
3415 plus_constant (SImode, stack_pointer_rtx,
3416 cfa_adjust)));
3418 add_reg_note (insn, REG_CFA_RESTORE, ra);
3421 if (!millicode_p)
3423 if (cfun->machine->frame_info.reg_size)
3424 arc_save_restore (stack_pointer_rtx,
3425 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3426 cfun->machine->frame_info.gmask
3427 & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 1, &first_offset);
3430 /* The rest of this function does the following:
3431 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3434 /* Keep track of how much of the stack pointer we've restored.
3435 It makes the following a lot more readable. */
3436 size_to_deallocate += first_offset;
3437 restored = size - size_to_deallocate;
3439 if (size > restored)
3440 frame_stack_add (size - restored);
3442 /* For frames that use __builtin_eh_return, the register defined by
3443 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
3444 On eh_return paths however, the register is set to the value that
3445 should be added to the stack pointer in order to restore the
3446 correct stack pointer for the exception handling frame.
3448 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
3449 this onto the stack for eh_return frames. */
3450 if (crtl->calls_eh_return)
3451 emit_insn (gen_add2_insn (stack_pointer_rtx,
3452 EH_RETURN_STACKADJ_RTX));
3454 /* Emit the return instruction. */
3455 if (sibcall_p == FALSE)
3456 emit_jump_insn (gen_simple_return ());
3459 /* Return rtx for the location of the return address on the stack,
3460 suitable for use in __builtin_eh_return. The new return address
3461 will be written to this location in order to redirect the return to
3462 the exception handler. */
3465 arc_eh_return_address_location (void)
3467 rtx mem;
3468 int offset;
3469 struct arc_frame_info *afi;
3471 arc_compute_frame_size ();
3472 afi = &cfun->machine->frame_info;
3474 gcc_assert (crtl->calls_eh_return);
3475 gcc_assert (afi->save_return_addr);
3476 gcc_assert (afi->extra_size >= 4);
3478 /* The '-4' removes the size of the return address, which is
3479 included in the 'extra_size' field. */
3480 offset = afi->reg_size + afi->extra_size - 4;
3481 mem = gen_frame_mem (Pmode,
3482 plus_constant (Pmode, frame_pointer_rtx, offset));
3484 /* The following should not be needed, and is, really a hack. The
3485 issue being worked around here is that the DSE (Dead Store
3486 Elimination) pass will remove this write to the stack as it sees
3487 a single store and no corresponding read. The read however
3488 occurs in the epilogue code, which is not added into the function
3489 rtl until a later pass. So, at the time of DSE, the decision to
3490 remove this store seems perfectly sensible. Marking the memory
3491 address as volatile obviously has the effect of preventing DSE
3492 from removing the store. */
3493 MEM_VOLATILE_P (mem) = 1;
3494 return mem;
3497 /* PIC */
3499 /* Helper to generate unspec constant. */
3501 static rtx
3502 arc_unspec_offset (rtx loc, int unspec)
3504 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
3505 unspec));
3508 /* !TARGET_BARREL_SHIFTER support. */
3509 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3510 kind of shift. */
3512 void
3513 emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
3515 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
3516 rtx pat
3517 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop)
3518 (op0, op1, op2, shift));
3519 emit_insn (pat);
3522 /* Output the assembler code for doing a shift.
3523 We go to a bit of trouble to generate efficient code as the ARC601 only has
3524 single bit shifts. This is taken from the h8300 port. We only have one
3525 mode of shifting and can't access individual bytes like the h8300 can, so
3526 this is greatly simplified (at the expense of not generating hyper-
3527 efficient code).
3529 This function is not used if the variable shift insns are present. */
3531 /* FIXME: This probably can be done using a define_split in arc.md.
3532 Alternately, generate rtx rather than output instructions. */
3534 const char *
3535 output_shift (rtx *operands)
3537 /* static int loopend_lab;*/
3538 rtx shift = operands[3];
3539 machine_mode mode = GET_MODE (shift);
3540 enum rtx_code code = GET_CODE (shift);
3541 const char *shift_one;
3543 gcc_assert (mode == SImode);
3545 switch (code)
3547 case ASHIFT: shift_one = "add %0,%1,%1"; break;
3548 case ASHIFTRT: shift_one = "asr %0,%1"; break;
3549 case LSHIFTRT: shift_one = "lsr %0,%1"; break;
3550 default: gcc_unreachable ();
3553 if (GET_CODE (operands[2]) != CONST_INT)
3555 output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
3556 goto shiftloop;
3558 else
3560 int n;
3562 n = INTVAL (operands[2]);
3564 /* Only consider the lower 5 bits of the shift count. */
3565 n = n & 0x1f;
3567 /* First see if we can do them inline. */
3568 /* ??? We could get better scheduling & shorter code (using short insns)
3569 by using splitters. Alas, that'd be even more verbose. */
3570 if (code == ASHIFT && n <= 9 && n > 2
3571 && dest_reg_operand (operands[4], SImode))
3573 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
3574 for (n -=3 ; n >= 3; n -= 3)
3575 output_asm_insn ("add3 %0,%4,%0", operands);
3576 if (n == 2)
3577 output_asm_insn ("add2 %0,%4,%0", operands);
3578 else if (n)
3579 output_asm_insn ("add %0,%0,%0", operands);
3581 else if (n <= 4)
3583 while (--n >= 0)
3585 output_asm_insn (shift_one, operands);
3586 operands[1] = operands[0];
3589 /* See if we can use a rotate/and. */
3590 else if (n == BITS_PER_WORD - 1)
3592 switch (code)
3594 case ASHIFT :
3595 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
3596 break;
3597 case ASHIFTRT :
3598 /* The ARC doesn't have a rol insn. Use something else. */
3599 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
3600 break;
3601 case LSHIFTRT :
3602 /* The ARC doesn't have a rol insn. Use something else. */
3603 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
3604 break;
3605 default:
3606 break;
3609 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
3611 switch (code)
3613 case ASHIFT :
3614 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
3615 break;
3616 case ASHIFTRT :
3617 #if 1 /* Need some scheduling comparisons. */
3618 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3619 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3620 #else
3621 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3622 "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
3623 #endif
3624 break;
3625 case LSHIFTRT :
3626 #if 1
3627 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3628 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3629 #else
3630 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3631 "and %0,%0,1\n\trlc %0,%0", operands);
3632 #endif
3633 break;
3634 default:
3635 break;
3638 else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
3639 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3640 operands);
3641 /* Must loop. */
3642 else
3644 operands[2] = GEN_INT (n);
3645 output_asm_insn ("mov.f lp_count, %2", operands);
3647 shiftloop:
3649 output_asm_insn ("lpnz\t2f", operands);
3650 output_asm_insn (shift_one, operands);
3651 output_asm_insn ("nop", operands);
3652 fprintf (asm_out_file, "2:\t%s end single insn loop\n",
3653 ASM_COMMENT_START);
3658 return "";
3661 /* Nested function support. */
3663 /* Output assembler code for a block containing the constant parts of
3664 a trampoline, leaving space for variable parts. A trampoline looks
3665 like this:
3667 ld_s r12,[pcl,8]
3668 ld r11,[pcl,12]
3669 j_s [r12]
3670 .word function's address
3671 .word static chain value
3675 static void
3676 arc_asm_trampoline_template (FILE *f)
3678 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG);
3679 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]);
3680 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG);
3681 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3682 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3685 /* Emit RTL insns to initialize the variable parts of a trampoline.
3686 FNADDR is an RTX for the address of the function's pure code. CXT
3687 is an RTX for the static chain value for the function.
3689 The fastest trampoline to execute for trampolines within +-8KB of CTX
3690 would be:
3692 add2 r11,pcl,s12
3693 j [limm] 0x20200f80 limm
3695 and that would also be faster to write to the stack by computing
3696 the offset from CTX to TRAMP at compile time. However, it would
3697 really be better to get rid of the high cost of cache invalidation
3698 when generating trampolines, which requires that the code part of
3699 trampolines stays constant, and additionally either making sure
3700 that no executable code but trampolines is on the stack, no icache
3701 entries linger for the area of the stack from when before the stack
3702 was allocated, and allocating trampolines in trampoline-only cache
3703 lines or allocate trampolines fram a special pool of pre-allocated
3704 trampolines. */
3706 static void
3707 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
3709 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3711 emit_block_move (tramp, assemble_trampoline_template (),
3712 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3713 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
3714 emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
3715 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
3716 LCT_NORMAL, VOIDmode, XEXP (tramp, 0), Pmode,
3717 plus_constant (Pmode, XEXP (tramp, 0), TRAMPOLINE_SIZE),
3718 Pmode);
3721 /* Add the given function declaration to emit code in JLI section. */
3723 static void
3724 arc_add_jli_section (rtx pat)
3726 const char *name;
3727 tree attrs;
3728 arc_jli_section *sec = arc_jli_sections, *new_section;
3729 tree decl = SYMBOL_REF_DECL (pat);
3731 if (!pat)
3732 return;
3734 if (decl)
3736 /* For fixed locations do not generate the jli table entry. It
3737 should be provided by the user as an asm file. */
3738 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
3739 if (lookup_attribute ("jli_fixed", attrs))
3740 return;
3743 name = XSTR (pat, 0);
3745 /* Don't insert the same symbol twice. */
3746 while (sec != NULL)
3748 if(strcmp (name, sec->name) == 0)
3749 return;
3750 sec = sec->next;
3753 /* New name, insert it. */
3754 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
3755 gcc_assert (new_section != NULL);
3756 new_section->name = name;
3757 new_section->next = arc_jli_sections;
3758 arc_jli_sections = new_section;
3761 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3762 reset when we output the scaled address. */
3763 static int output_scaled = 0;
3765 /* Print operand X (an rtx) in assembler syntax to file FILE.
3766 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3767 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3768 /* In final.c:output_asm_insn:
3769 'l' : label
3770 'a' : address
3771 'c' : constant address if CONSTANT_ADDRESS_P
3772 'n' : negative
3773 Here:
3774 'Z': log2(x+1)-1
3775 'z': log2
3776 'M': log2(~x)
3777 'p': bit Position of lsb
3778 's': size of bit field
3779 '#': condbranch delay slot suffix
3780 '*': jump delay slot suffix
3781 '?' : nonjump-insn suffix for conditional execution or short instruction
3782 '!' : jump / call suffix for conditional execution or short instruction
3783 '`': fold constant inside unary o-perator, re-recognize, and emit.
3786 'R': Second word
3787 'S': JLI instruction
3788 'j': used by mov instruction to properly emit jli related labels.
3789 'B': Branch comparison operand - suppress sda reference
3790 'H': Most significant word
3791 'L': Least significant word
3792 'A': ASCII decimal representation of floating point value
3793 'U': Load/store update or scaling indicator
3794 'V': cache bypass indicator for volatile
3798 'O': Operator
3799 'o': original symbol - no @ prepending. */
3801 void
3802 arc_print_operand (FILE *file, rtx x, int code)
3804 switch (code)
3806 case 'Z':
3807 if (GET_CODE (x) == CONST_INT)
3808 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
3809 else
3810 output_operand_lossage ("invalid operand to %%Z code");
3812 return;
3814 case 'z':
3815 if (GET_CODE (x) == CONST_INT)
3816 fprintf (file, "%d",exact_log2(INTVAL (x)) );
3817 else
3818 output_operand_lossage ("invalid operand to %%z code");
3820 return;
3822 case 'c':
3823 if (GET_CODE (x) == CONST_INT)
3824 fprintf (file, "%ld", INTVAL (x) );
3825 else
3826 output_operand_lossage ("invalid operands to %%c code");
3828 return;
3830 case 'M':
3831 if (GET_CODE (x) == CONST_INT)
3832 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
3833 else
3834 output_operand_lossage ("invalid operand to %%M code");
3836 return;
3838 case 'p':
3839 if (GET_CODE (x) == CONST_INT)
3840 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
3841 else
3842 output_operand_lossage ("invalid operand to %%p code");
3843 return;
3845 case 's':
3846 if (GET_CODE (x) == CONST_INT)
3848 HOST_WIDE_INT i = INTVAL (x);
3849 HOST_WIDE_INT s = exact_log2 (i & -i);
3850 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
3852 else
3853 output_operand_lossage ("invalid operand to %%s code");
3854 return;
3856 case '#' :
3857 /* Conditional branches depending on condition codes.
3858 Note that this is only for branches that were known to depend on
3859 condition codes before delay slot scheduling;
3860 out-of-range brcc / bbit expansions should use '*'.
3861 This distinction is important because of the different
3862 allowable delay slot insns and the output of the delay suffix
3863 for TARGET_AT_DBR_COND_EXEC. */
3864 case '*' :
3865 /* Unconditional branches / branches not depending on condition codes.
3866 This could also be a CALL_INSN.
3867 Output the appropriate delay slot suffix. */
3868 if (final_sequence && final_sequence->len () != 1)
3870 rtx_insn *jump = final_sequence->insn (0);
3871 rtx_insn *delay = final_sequence->insn (1);
3873 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3874 if (delay->deleted ())
3875 return;
3876 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3877 fputs (INSN_FROM_TARGET_P (delay) ? ".d"
3878 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d"
3879 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? ""
3880 : ".nd",
3881 file);
3882 else
3883 fputs (".d", file);
3885 return;
3886 case '?' : /* with leading "." */
3887 case '!' : /* without leading "." */
3888 /* This insn can be conditionally executed. See if the ccfsm machinery
3889 says it should be conditionalized.
3890 If it shouldn't, we'll check the compact attribute if this insn
3891 has a short variant, which may be used depending on code size and
3892 alignment considerations. */
3893 if (current_insn_predicate)
3894 arc_ccfsm_current.cc
3895 = get_arc_condition_code (current_insn_predicate);
3896 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current))
3898 /* Is this insn in a delay slot sequence? */
3899 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
3900 || current_insn_predicate
3901 || CALL_P (final_sequence->insn (0))
3902 || simplejump_p (final_sequence->insn (0)))
3904 /* This insn isn't in a delay slot sequence, or conditionalized
3905 independently of its position in a delay slot. */
3906 fprintf (file, "%s%s",
3907 code == '?' ? "." : "",
3908 arc_condition_codes[arc_ccfsm_current.cc]);
3909 /* If this is a jump, there are still short variants. However,
3910 only beq_s / bne_s have the same offset range as b_s,
3911 and the only short conditional returns are jeq_s and jne_s. */
3912 if (code == '!'
3913 && (arc_ccfsm_current.cc == ARC_CC_EQ
3914 || arc_ccfsm_current.cc == ARC_CC_NE
3915 || 0 /* FIXME: check if branch in 7 bit range. */))
3916 output_short_suffix (file);
3918 else if (code == '!') /* Jump with delay slot. */
3919 fputs (arc_condition_codes[arc_ccfsm_current.cc], file);
3920 else /* An Instruction in a delay slot of a jump or call. */
3922 rtx jump = XVECEXP (final_sequence, 0, 0);
3923 rtx insn = XVECEXP (final_sequence, 0, 1);
3925 /* If the insn is annulled and is from the target path, we need
3926 to inverse the condition test. */
3927 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3929 if (INSN_FROM_TARGET_P (insn))
3930 fprintf (file, "%s%s",
3931 code == '?' ? "." : "",
3932 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]);
3933 else
3934 fprintf (file, "%s%s",
3935 code == '?' ? "." : "",
3936 arc_condition_codes[arc_ccfsm_current.cc]);
3937 if (arc_ccfsm_current.state == 5)
3938 arc_ccfsm_current.state = 0;
3940 else
3941 /* This insn is executed for either path, so don't
3942 conditionalize it at all. */
3943 output_short_suffix (file);
3947 else
3948 output_short_suffix (file);
3949 return;
3950 case'`':
3951 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
3952 gcc_unreachable ();
3953 case 'd' :
3954 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
3955 return;
3956 case 'D' :
3957 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
3958 (get_arc_condition_code (x))],
3959 file);
3960 return;
3961 case 'R' :
3962 /* Write second word of DImode or DFmode reference,
3963 register or memory. */
3964 if (GET_CODE (x) == REG)
3965 fputs (reg_names[REGNO (x)+1], file);
3966 else if (GET_CODE (x) == MEM)
3968 fputc ('[', file);
3970 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
3971 PRE_MODIFY, we will have handled the first word already;
3972 For POST_INC / POST_DEC / POST_MODIFY, the access to the
3973 first word will be done later. In either case, the access
3974 to the first word will do the modify, and we only have
3975 to add an offset of four here. */
3976 if (GET_CODE (XEXP (x, 0)) == PRE_INC
3977 || GET_CODE (XEXP (x, 0)) == PRE_DEC
3978 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
3979 || GET_CODE (XEXP (x, 0)) == POST_INC
3980 || GET_CODE (XEXP (x, 0)) == POST_DEC
3981 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
3982 output_address (VOIDmode,
3983 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
3984 else if (output_scaled)
3986 rtx addr = XEXP (x, 0);
3987 int size = GET_MODE_SIZE (GET_MODE (x));
3989 output_address (VOIDmode,
3990 plus_constant (Pmode, XEXP (addr, 0),
3991 ((INTVAL (XEXP (addr, 1)) + 4)
3992 >> (size == 2 ? 1 : 2))));
3993 output_scaled = 0;
3995 else
3996 output_address (VOIDmode,
3997 plus_constant (Pmode, XEXP (x, 0), 4));
3998 fputc (']', file);
4000 else
4001 output_operand_lossage ("invalid operand to %%R code");
4002 return;
4003 case 'j':
4004 case 'S' :
4005 if (GET_CODE (x) == SYMBOL_REF
4006 && arc_is_jli_call_p (x))
4008 if (SYMBOL_REF_DECL (x))
4010 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4011 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4012 : NULL_TREE);
4013 if (lookup_attribute ("jli_fixed", attrs))
4015 /* No special treatment for jli_fixed functions. */
4016 if (code == 'j')
4017 break;
4018 fprintf (file, "%ld\t; @",
4019 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4020 assemble_name (file, XSTR (x, 0));
4021 return;
4024 fprintf (file, "@__jli.");
4025 assemble_name (file, XSTR (x, 0));
4026 if (code == 'j')
4027 arc_add_jli_section (x);
4028 return;
4030 if (GET_CODE (x) == SYMBOL_REF
4031 && arc_is_secure_call_p (x))
4033 /* No special treatment for secure functions. */
4034 if (code == 'j' )
4035 break;
4036 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4037 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4038 : NULL_TREE);
4039 fprintf (file, "%ld\t; @",
4040 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4041 assemble_name (file, XSTR (x, 0));
4042 return;
4044 break;
4045 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4046 if (CONSTANT_P (x))
4048 output_addr_const (file, x);
4049 return;
4051 break;
4052 case 'H' :
4053 case 'L' :
4054 if (GET_CODE (x) == REG)
4056 /* L = least significant word, H = most significant word. */
4057 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
4058 fputs (reg_names[REGNO (x)], file);
4059 else
4060 fputs (reg_names[REGNO (x)+1], file);
4062 else if (GET_CODE (x) == CONST_INT
4063 || GET_CODE (x) == CONST_DOUBLE)
4065 rtx first, second, word;
4067 split_double (x, &first, &second);
4069 if((WORDS_BIG_ENDIAN) == 0)
4070 word = (code == 'L' ? first : second);
4071 else
4072 word = (code == 'L' ? second : first);
4074 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
4076 else
4077 output_operand_lossage ("invalid operand to %%H/%%L code");
4078 return;
4079 case 'A' :
4081 char str[30];
4083 gcc_assert (GET_CODE (x) == CONST_DOUBLE
4084 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
4086 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
4087 fprintf (file, "%s", str);
4088 return;
4090 case 'U' :
4091 /* Output a load/store with update indicator if appropriate. */
4092 if (GET_CODE (x) == MEM)
4094 rtx addr = XEXP (x, 0);
4095 switch (GET_CODE (addr))
4097 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
4098 fputs (".a", file); break;
4099 case POST_INC: case POST_DEC: case POST_MODIFY:
4100 fputs (".ab", file); break;
4101 case PLUS:
4102 /* Are we using a scaled index? */
4103 if (GET_CODE (XEXP (addr, 0)) == MULT)
4104 fputs (".as", file);
4105 /* Can we use a scaled offset? */
4106 else if (CONST_INT_P (XEXP (addr, 1))
4107 && GET_MODE_SIZE (GET_MODE (x)) > 1
4108 && (!(INTVAL (XEXP (addr, 1))
4109 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
4110 /* Does it make a difference? */
4111 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
4112 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
4114 fputs (".as", file);
4115 output_scaled = 1;
4117 else if (LEGITIMATE_SMALL_DATA_ADDRESS_P (addr)
4118 && GET_MODE_SIZE (GET_MODE (x)) > 1)
4120 tree decl = NULL_TREE;
4121 int align = 0;
4122 if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
4123 decl = SYMBOL_REF_DECL (XEXP (addr, 1));
4124 else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0))
4125 == SYMBOL_REF)
4126 decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
4127 if (decl)
4128 align = DECL_ALIGN (decl);
4129 align = align / BITS_PER_UNIT;
4130 if ((GET_MODE_SIZE (GET_MODE (x)) == 2)
4131 && align && ((align & 1) == 0))
4132 fputs (".as", file);
4133 if ((GET_MODE_SIZE (GET_MODE (x)) >= 4)
4134 && align && ((align & 3) == 0))
4135 fputs (".as", file);
4137 break;
4138 case REG:
4139 break;
4140 default:
4141 gcc_assert (CONSTANT_P (addr)); break;
4144 else
4145 output_operand_lossage ("invalid operand to %%U code");
4146 return;
4147 case 'V' :
4148 /* Output cache bypass indicator for a load/store insn. Volatile memory
4149 refs are defined to use the cache bypass mechanism. */
4150 if (GET_CODE (x) == MEM)
4152 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
4153 || arc_is_uncached_mem_p (x))
4154 fputs (".di", file);
4156 else
4157 output_operand_lossage ("invalid operand to %%V code");
4158 return;
4159 /* plt code. */
4160 case 'P':
4161 case 0 :
4162 /* Do nothing special. */
4163 break;
4164 case 'F':
4165 fputs (reg_names[REGNO (x)]+1, file);
4166 return;
4167 case '^':
4168 /* This punctuation character is needed because label references are
4169 printed in the output template using %l. This is a front end
4170 character, and when we want to emit a '@' before it, we have to use
4171 this '^'. */
4173 fputc('@',file);
4174 return;
4175 case 'O':
4176 /* Output an operator. */
4177 switch (GET_CODE (x))
4179 case PLUS: fputs ("add", file); return;
4180 case SS_PLUS: fputs ("adds", file); return;
4181 case AND: fputs ("and", file); return;
4182 case IOR: fputs ("or", file); return;
4183 case XOR: fputs ("xor", file); return;
4184 case MINUS: fputs ("sub", file); return;
4185 case SS_MINUS: fputs ("subs", file); return;
4186 case ASHIFT: fputs ("asl", file); return;
4187 case ASHIFTRT: fputs ("asr", file); return;
4188 case LSHIFTRT: fputs ("lsr", file); return;
4189 case ROTATERT: fputs ("ror", file); return;
4190 case MULT: fputs ("mpy", file); return;
4191 case ABS: fputs ("abs", file); return; /* Unconditional. */
4192 case NEG: fputs ("neg", file); return;
4193 case SS_NEG: fputs ("negs", file); return;
4194 case NOT: fputs ("not", file); return; /* Unconditional. */
4195 case ZERO_EXTEND:
4196 fputs ("ext", file); /* bmsk allows predication. */
4197 goto size_suffix;
4198 case SIGN_EXTEND: /* Unconditional. */
4199 fputs ("sex", file);
4200 size_suffix:
4201 switch (GET_MODE (XEXP (x, 0)))
4203 case E_QImode: fputs ("b", file); return;
4204 case E_HImode: fputs ("w", file); return;
4205 default: break;
4207 break;
4208 case SS_TRUNCATE:
4209 if (GET_MODE (x) != HImode)
4210 break;
4211 fputs ("sat16", file);
4212 default: break;
4214 output_operand_lossage ("invalid operand to %%O code"); return;
4215 case 'o':
4216 if (GET_CODE (x) == SYMBOL_REF)
4218 assemble_name (file, XSTR (x, 0));
4219 return;
4221 break;
4222 case '&':
4223 if (TARGET_ANNOTATE_ALIGN && cfun->machine->size_reason)
4224 fprintf (file, "; unalign: %d", cfun->machine->unalign);
4225 return;
4226 case '+':
4227 if (TARGET_V2)
4228 fputs ("m", file);
4229 else
4230 fputs ("h", file);
4231 return;
4232 case '_':
4233 if (TARGET_V2)
4234 fputs ("h", file);
4235 else
4236 fputs ("w", file);
4237 return;
4238 default :
4239 /* Unknown flag. */
4240 output_operand_lossage ("invalid operand output code");
4243 switch (GET_CODE (x))
4245 case REG :
4246 fputs (reg_names[REGNO (x)], file);
4247 break;
4248 case MEM :
4250 rtx addr = XEXP (x, 0);
4251 int size = GET_MODE_SIZE (GET_MODE (x));
4253 fputc ('[', file);
4255 switch (GET_CODE (addr))
4257 case PRE_INC: case POST_INC:
4258 output_address (VOIDmode,
4259 plus_constant (Pmode, XEXP (addr, 0), size)); break;
4260 case PRE_DEC: case POST_DEC:
4261 output_address (VOIDmode,
4262 plus_constant (Pmode, XEXP (addr, 0), -size));
4263 break;
4264 case PRE_MODIFY: case POST_MODIFY:
4265 output_address (VOIDmode, XEXP (addr, 1)); break;
4266 case PLUS:
4267 if (output_scaled)
4269 output_address (VOIDmode,
4270 plus_constant (Pmode, XEXP (addr, 0),
4271 (INTVAL (XEXP (addr, 1))
4272 >> (size == 2 ? 1 : 2))));
4273 output_scaled = 0;
4275 else
4276 output_address (VOIDmode, addr);
4277 break;
4278 default:
4279 if (flag_pic && CONSTANT_ADDRESS_P (addr))
4280 arc_output_pic_addr_const (file, addr, code);
4281 else
4282 output_address (VOIDmode, addr);
4283 break;
4285 fputc (']', file);
4286 break;
4288 case CONST_DOUBLE :
4289 /* We handle SFmode constants here as output_addr_const doesn't. */
4290 if (GET_MODE (x) == SFmode)
4292 long l;
4294 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
4295 fprintf (file, "0x%08lx", l);
4296 break;
4298 /* FALLTHRU */
4299 /* Let output_addr_const deal with it. */
4300 default :
4301 if (flag_pic
4302 || (GET_CODE (x) == CONST
4303 && GET_CODE (XEXP (x, 0)) == UNSPEC
4304 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
4305 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
4306 || (GET_CODE (x) == CONST
4307 && GET_CODE (XEXP (x, 0)) == PLUS
4308 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
4309 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
4310 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
4311 arc_output_pic_addr_const (file, x, code);
4312 else
4314 /* FIXME: Dirty way to handle @var@sda+const. Shd be handled
4315 with asm_output_symbol_ref */
4316 if (GET_CODE (x) == CONST && GET_CODE (XEXP (x, 0)) == PLUS)
4318 x = XEXP (x, 0);
4319 output_addr_const (file, XEXP (x, 0));
4320 if (GET_CODE (XEXP (x, 0)) == SYMBOL_REF && SYMBOL_REF_SMALL_P (XEXP (x, 0)))
4321 fprintf (file, "@sda");
4323 if (GET_CODE (XEXP (x, 1)) != CONST_INT
4324 || INTVAL (XEXP (x, 1)) >= 0)
4325 fprintf (file, "+");
4326 output_addr_const (file, XEXP (x, 1));
4328 else
4329 output_addr_const (file, x);
4331 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
4332 fprintf (file, "@sda");
4333 break;
4337 /* Print a memory address as an operand to reference that memory location. */
4339 void
4340 arc_print_operand_address (FILE *file , rtx addr)
4342 register rtx base, index = 0;
4344 switch (GET_CODE (addr))
4346 case REG :
4347 fputs (reg_names[REGNO (addr)], file);
4348 break;
4349 case SYMBOL_REF :
4350 output_addr_const (file, addr);
4351 if (SYMBOL_REF_SMALL_P (addr))
4352 fprintf (file, "@sda");
4353 break;
4354 case PLUS :
4355 if (GET_CODE (XEXP (addr, 0)) == MULT)
4356 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
4357 else if (CONST_INT_P (XEXP (addr, 0)))
4358 index = XEXP (addr, 0), base = XEXP (addr, 1);
4359 else
4360 base = XEXP (addr, 0), index = XEXP (addr, 1);
4362 gcc_assert (OBJECT_P (base));
4363 arc_print_operand_address (file, base);
4364 if (CONSTANT_P (base) && CONST_INT_P (index))
4365 fputc ('+', file);
4366 else
4367 fputc (',', file);
4368 gcc_assert (OBJECT_P (index));
4369 arc_print_operand_address (file, index);
4370 break;
4371 case CONST:
4373 rtx c = XEXP (addr, 0);
4375 if ((GET_CODE (c) == UNSPEC
4376 && (XINT (c, 1) == UNSPEC_TLS_OFF
4377 || XINT (c, 1) == UNSPEC_TLS_IE))
4378 || (GET_CODE (c) == PLUS
4379 && GET_CODE (XEXP (c, 0)) == UNSPEC
4380 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
4381 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
4383 arc_output_pic_addr_const (file, c, 0);
4384 break;
4386 gcc_assert (GET_CODE (c) == PLUS);
4387 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
4388 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
4390 output_address (VOIDmode, XEXP (addr, 0));
4392 break;
4394 case PRE_INC :
4395 case PRE_DEC :
4396 /* We shouldn't get here as we've lost the mode of the memory object
4397 (which says how much to inc/dec by. */
4398 gcc_unreachable ();
4399 break;
4400 default :
4401 if (flag_pic)
4402 arc_output_pic_addr_const (file, addr, 0);
4403 else
4404 output_addr_const (file, addr);
4405 break;
4409 /* Conditional execution support.
4411 This is based on the ARM port but for now is much simpler.
4413 A finite state machine takes care of noticing whether or not instructions
4414 can be conditionally executed, and thus decrease execution time and code
4415 size by deleting branch instructions. The fsm is controlled by
4416 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4417 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4418 insns also have a hand in this. */
4419 /* The way we leave dealing with non-anulled or annull-false delay slot
4420 insns to the consumer is awkward. */
4422 /* The state of the fsm controlling condition codes are:
4423 0: normal, do nothing special
4424 1: don't output this insn
4425 2: don't output this insn
4426 3: make insns conditional
4427 4: make insns conditional
4428 5: make insn conditional (only for outputting anulled delay slot insns)
4430 special value for cfun->machine->uid_ccfsm_state:
4431 6: return with but one insn before it since function start / call
4433 State transitions (state->state by whom, under what condition):
4434 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4435 some instructions.
4436 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4437 by zero or more non-jump insns and an unconditional branch with
4438 the same target label as the condbranch.
4439 1 -> 3 branch patterns, after having not output the conditional branch
4440 2 -> 4 branch patterns, after having not output the conditional branch
4441 0 -> 5 branch patterns, for anulled delay slot insn.
4442 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4443 (the target label has CODE_LABEL_NUMBER equal to
4444 arc_ccfsm_target_label).
4445 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4446 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4447 5 -> 0 when outputting the delay slot insn
4449 If the jump clobbers the conditions then we use states 2 and 4.
4451 A similar thing can be done with conditional return insns.
4453 We also handle separating branches from sets of the condition code.
4454 This is done here because knowledge of the ccfsm state is required,
4455 we may not be outputting the branch. */
4457 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4458 before letting final output INSN. */
4460 static void
4461 arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
4463 /* BODY will hold the body of INSN. */
4464 register rtx body;
4466 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4467 an if/then/else), and things need to be reversed. */
4468 int reverse = 0;
4470 /* If we start with a return insn, we only succeed if we find another one. */
4471 int seeking_return = 0;
4473 /* START_INSN will hold the insn from where we start looking. This is the
4474 first insn after the following code_label if REVERSE is true. */
4475 rtx_insn *start_insn = insn;
4477 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4478 since they don't rely on a cmp preceding the. */
4479 enum attr_type jump_insn_type;
4481 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4482 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4483 final_scan_insn which has `optimize' as a local. */
4484 if (optimize < 2 || TARGET_NO_COND_EXEC)
4485 return;
4487 /* Ignore notes and labels. */
4488 if (!INSN_P (insn))
4489 return;
4490 body = PATTERN (insn);
4491 /* If in state 4, check if the target branch is reached, in order to
4492 change back to state 0. */
4493 if (state->state == 4)
4495 if (insn == state->target_insn)
4497 state->target_insn = NULL;
4498 state->state = 0;
4500 return;
4503 /* If in state 3, it is possible to repeat the trick, if this insn is an
4504 unconditional branch to a label, and immediately following this branch
4505 is the previous target label which is only used once, and the label this
4506 branch jumps to is not too far off. Or in other words "we've done the
4507 `then' part, see if we can do the `else' part." */
4508 if (state->state == 3)
4510 if (simplejump_p (insn))
4512 start_insn = next_nonnote_insn (start_insn);
4513 if (GET_CODE (start_insn) == BARRIER)
4515 /* ??? Isn't this always a barrier? */
4516 start_insn = next_nonnote_insn (start_insn);
4518 if (GET_CODE (start_insn) == CODE_LABEL
4519 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4520 && LABEL_NUSES (start_insn) == 1)
4521 reverse = TRUE;
4522 else
4523 return;
4525 else if (GET_CODE (body) == SIMPLE_RETURN)
4527 start_insn = next_nonnote_insn (start_insn);
4528 if (GET_CODE (start_insn) == BARRIER)
4529 start_insn = next_nonnote_insn (start_insn);
4530 if (GET_CODE (start_insn) == CODE_LABEL
4531 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4532 && LABEL_NUSES (start_insn) == 1)
4534 reverse = TRUE;
4535 seeking_return = 1;
4537 else
4538 return;
4540 else
4541 return;
4544 if (GET_CODE (insn) != JUMP_INSN
4545 || GET_CODE (PATTERN (insn)) == ADDR_VEC
4546 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
4547 return;
4549 /* We can't predicate BRCC or loop ends.
4550 Also, when generating PIC code, and considering a medium range call,
4551 we can't predicate the call. */
4552 jump_insn_type = get_attr_type (insn);
4553 if (jump_insn_type == TYPE_BRCC
4554 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
4555 || jump_insn_type == TYPE_LOOP_END
4556 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
4557 return;
4559 /* This jump might be paralleled with a clobber of the condition codes,
4560 the jump should always come first. */
4561 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
4562 body = XVECEXP (body, 0, 0);
4564 if (reverse
4565 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
4566 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
4568 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
4569 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4570 int then_not_else = TRUE;
4571 /* Nonzero if next insn must be the target label. */
4572 int next_must_be_target_label_p;
4573 rtx_insn *this_insn = start_insn;
4574 rtx label = 0;
4576 /* Register the insn jumped to. */
4577 if (reverse)
4579 if (!seeking_return)
4580 label = XEXP (SET_SRC (body), 0);
4582 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
4583 label = XEXP (XEXP (SET_SRC (body), 1), 0);
4584 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
4586 label = XEXP (XEXP (SET_SRC (body), 2), 0);
4587 then_not_else = FALSE;
4589 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
4590 seeking_return = 1;
4591 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
4593 seeking_return = 1;
4594 then_not_else = FALSE;
4596 else
4597 gcc_unreachable ();
4599 /* If this is a non-annulled branch with a delay slot, there is
4600 no need to conditionalize the delay slot. */
4601 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) == SEQUENCE)
4602 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
4604 this_insn = NEXT_INSN (this_insn);
4606 /* See how many insns this branch skips, and what kind of insns. If all
4607 insns are okay, and the label or unconditional branch to the same
4608 label is not too far away, succeed. */
4609 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
4610 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
4611 insns_skipped++)
4613 rtx scanbody;
4615 this_insn = next_nonnote_insn (this_insn);
4616 if (!this_insn)
4617 break;
4619 if (next_must_be_target_label_p)
4621 if (GET_CODE (this_insn) == BARRIER)
4622 continue;
4623 if (GET_CODE (this_insn) == CODE_LABEL
4624 && this_insn == label)
4626 state->state = 1;
4627 succeed = TRUE;
4629 else
4630 fail = TRUE;
4631 break;
4634 switch (GET_CODE (this_insn))
4636 case CODE_LABEL:
4637 /* Succeed if it is the target label, otherwise fail since
4638 control falls in from somewhere else. */
4639 if (this_insn == label)
4641 state->state = 1;
4642 succeed = TRUE;
4644 else
4645 fail = TRUE;
4646 break;
4648 case BARRIER:
4649 /* Succeed if the following insn is the target label.
4650 Otherwise fail.
4651 If return insns are used then the last insn in a function
4652 will be a barrier. */
4653 next_must_be_target_label_p = TRUE;
4654 break;
4656 case CALL_INSN:
4657 /* Can handle a call insn if there are no insns after it.
4658 IE: The next "insn" is the target label. We don't have to
4659 worry about delay slots as such insns are SEQUENCE's inside
4660 INSN's. ??? It is possible to handle such insns though. */
4661 if (get_attr_cond (this_insn) == COND_CANUSE)
4662 next_must_be_target_label_p = TRUE;
4663 else
4664 fail = TRUE;
4665 break;
4667 case JUMP_INSN:
4668 scanbody = PATTERN (this_insn);
4670 /* If this is an unconditional branch to the same label, succeed.
4671 If it is to another label, do nothing. If it is conditional,
4672 fail. */
4673 /* ??? Probably, the test for the SET and the PC are
4674 unnecessary. */
4676 if (GET_CODE (scanbody) == SET
4677 && GET_CODE (SET_DEST (scanbody)) == PC)
4679 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
4680 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
4682 state->state = 2;
4683 succeed = TRUE;
4685 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
4686 fail = TRUE;
4687 else if (get_attr_cond (this_insn) != COND_CANUSE)
4688 fail = TRUE;
4690 else if (GET_CODE (scanbody) == SIMPLE_RETURN
4691 && seeking_return)
4693 state->state = 2;
4694 succeed = TRUE;
4696 else if (GET_CODE (scanbody) == PARALLEL)
4698 if (get_attr_cond (this_insn) != COND_CANUSE)
4699 fail = TRUE;
4701 break;
4703 case INSN:
4704 scanbody = PATTERN (this_insn);
4706 /* We can only do this with insns that can use the condition
4707 codes (and don't set them). */
4708 if (GET_CODE (scanbody) == SET
4709 || GET_CODE (scanbody) == PARALLEL)
4711 if (get_attr_cond (this_insn) != COND_CANUSE)
4712 fail = TRUE;
4714 /* We can't handle other insns like sequences. */
4715 else
4716 fail = TRUE;
4717 break;
4719 default:
4720 break;
4724 if (succeed)
4726 if ((!seeking_return) && (state->state == 1 || reverse))
4727 state->target_label = CODE_LABEL_NUMBER (label);
4728 else if (seeking_return || state->state == 2)
4730 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
4732 this_insn = next_nonnote_insn (this_insn);
4734 gcc_assert (!this_insn ||
4735 (GET_CODE (this_insn) != BARRIER
4736 && GET_CODE (this_insn) != CODE_LABEL));
4738 if (!this_insn)
4740 /* Oh dear! we ran off the end, give up. */
4741 extract_insn_cached (insn);
4742 state->state = 0;
4743 state->target_insn = NULL;
4744 return;
4746 state->target_insn = this_insn;
4748 else
4749 gcc_unreachable ();
4751 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4752 what it was. */
4753 if (!reverse)
4755 state->cond = XEXP (SET_SRC (body), 0);
4756 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
4759 if (reverse || then_not_else)
4760 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
4763 /* Restore recog_operand. Getting the attributes of other insns can
4764 destroy this array, but final.c assumes that it remains intact
4765 across this call; since the insn has been recognized already we
4766 call insn_extract direct. */
4767 extract_insn_cached (insn);
4771 /* Record that we are currently outputting label NUM with prefix PREFIX.
4772 It it's the label we're looking for, reset the ccfsm machinery.
4774 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4776 static void
4777 arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
4779 if (state->state == 3 && state->target_label == num
4780 && !strcmp (prefix, "L"))
4782 state->state = 0;
4783 state->target_insn = NULL;
4787 /* We are considering a conditional branch with the condition COND.
4788 Check if we want to conditionalize a delay slot insn, and if so modify
4789 the ccfsm state accordingly.
4790 REVERSE says branch will branch when the condition is false. */
4791 void
4792 arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
4793 struct arc_ccfsm *state)
4795 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
4796 if (!state)
4797 state = &arc_ccfsm_current;
4799 gcc_assert (state->state == 0);
4800 if (seq_insn != jump)
4802 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
4804 if (!as_a<rtx_insn *> (insn)->deleted ()
4805 && INSN_ANNULLED_BRANCH_P (jump)
4806 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
4808 state->cond = cond;
4809 state->cc = get_arc_condition_code (cond);
4810 if (!reverse)
4811 arc_ccfsm_current.cc
4812 = ARC_INVERSE_CONDITION_CODE (state->cc);
4813 rtx pat = PATTERN (insn);
4814 if (GET_CODE (pat) == COND_EXEC)
4815 gcc_assert ((INSN_FROM_TARGET_P (insn)
4816 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
4817 == get_arc_condition_code (XEXP (pat, 0)));
4818 else
4819 state->state = 5;
4824 /* Update *STATE as we would when we emit INSN. */
4826 static void
4827 arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
4829 enum attr_type type;
4831 if (LABEL_P (insn))
4832 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
4833 else if (JUMP_P (insn)
4834 && GET_CODE (PATTERN (insn)) != ADDR_VEC
4835 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
4836 && ((type = get_attr_type (insn)) == TYPE_BRANCH
4837 || ((type == TYPE_UNCOND_BRANCH
4838 || type == TYPE_RETURN)
4839 && ARC_CCFSM_BRANCH_DELETED_P (state))))
4841 if (ARC_CCFSM_BRANCH_DELETED_P (state))
4842 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
4843 else
4845 rtx src = SET_SRC (PATTERN (insn));
4846 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
4847 insn, state);
4850 else if (arc_ccfsm_current.state == 5)
4851 arc_ccfsm_current.state = 0;
4854 /* Return true if the current insn, which is a conditional branch, is to be
4855 deleted. */
4857 bool
4858 arc_ccfsm_branch_deleted_p (void)
4860 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
4863 /* Record a branch isn't output because subsequent insns can be
4864 conditionalized. */
4866 void
4867 arc_ccfsm_record_branch_deleted (void)
4869 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
4872 /* During insn output, indicate if the current insn is predicated. */
4874 bool
4875 arc_ccfsm_cond_exec_p (void)
4877 return (cfun->machine->prescan_initialized
4878 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
4881 /* When deciding if an insn should be output short, we want to know something
4882 about the following insns:
4883 - if another insn follows which we know we can output as a short insn
4884 before an alignment-sensitive point, we can output this insn short:
4885 the decision about the eventual alignment can be postponed.
4886 - if a to-be-aligned label comes next, we should output this insn such
4887 as to get / preserve 4-byte alignment.
4888 - if a likely branch without delay slot insn, or a call with an immediately
4889 following short insn comes next, we should out output this insn such as to
4890 get / preserve 2 mod 4 unalignment.
4891 - do the same for a not completely unlikely branch with a short insn
4892 following before any other branch / label.
4893 - in order to decide if we are actually looking at a branch, we need to
4894 call arc_ccfsm_advance.
4895 - in order to decide if we are looking at a short insn, we should know
4896 if it is conditionalized. To a first order of approximation this is
4897 the case if the state from arc_ccfsm_advance from before this insn
4898 indicates the insn is conditionalized. However, a further refinement
4899 could be to not conditionalize an insn if the destination register(s)
4900 is/are dead in the non-executed case. */
4901 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4902 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4903 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4905 static int
4906 arc_verify_short (rtx_insn *insn, int, int check_attr)
4908 enum attr_iscompact iscompact;
4909 struct machine_function *machine;
4911 if (check_attr > 0)
4913 iscompact = get_attr_iscompact (insn);
4914 if (iscompact == ISCOMPACT_FALSE)
4915 return 0;
4917 machine = cfun->machine;
4919 if (machine->force_short_suffix >= 0)
4920 return machine->force_short_suffix;
4922 return (get_attr_length (insn) & 2) != 0;
4925 /* When outputting an instruction (alternative) that can potentially be short,
4926 output the short suffix if the insn is in fact short, and update
4927 cfun->machine->unalign accordingly. */
4929 static void
4930 output_short_suffix (FILE *file)
4932 rtx_insn *insn = current_output_insn;
4934 if (arc_verify_short (insn, cfun->machine->unalign, 1))
4936 fprintf (file, "_s");
4937 cfun->machine->unalign ^= 2;
4939 /* Restore recog_operand. */
4940 extract_insn_cached (insn);
4943 /* Implement FINAL_PRESCAN_INSN. */
4945 void
4946 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
4947 int noperands ATTRIBUTE_UNUSED)
4949 if (TARGET_DUMPISIZE)
4950 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
4952 if (!cfun->machine->prescan_initialized)
4954 /* Clear lingering state from branch shortening. */
4955 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
4956 cfun->machine->prescan_initialized = 1;
4958 arc_ccfsm_advance (insn, &arc_ccfsm_current);
4960 cfun->machine->size_reason = 0;
4963 /* Given FROM and TO register numbers, say whether this elimination is allowed.
4964 Frame pointer elimination is automatically handled.
4966 All eliminations are permissible. If we need a frame
4967 pointer, we must eliminate ARG_POINTER_REGNUM into
4968 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
4970 static bool
4971 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
4973 return ((to == FRAME_POINTER_REGNUM) || !arc_frame_pointer_needed ());
4976 /* Define the offset between two registers, one to be eliminated, and
4977 the other its replacement, at the start of a routine. */
4980 arc_initial_elimination_offset (int from, int to)
4982 if (!cfun->machine->frame_info.initialized)
4983 arc_compute_frame_size ();
4985 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
4987 return (cfun->machine->frame_info.extra_size
4988 + cfun->machine->frame_info.reg_size);
4991 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
4993 return (cfun->machine->frame_info.total_size
4994 - cfun->machine->frame_info.pretend_size);
4997 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
4999 return (cfun->machine->frame_info.total_size
5000 - (cfun->machine->frame_info.pretend_size
5001 + cfun->machine->frame_info.extra_size
5002 + cfun->machine->frame_info.reg_size));
5005 gcc_unreachable ();
5008 static bool
5009 arc_frame_pointer_required (void)
5011 return cfun->calls_alloca || crtl->calls_eh_return;
5015 /* Return the destination address of a branch. */
5017 static int
5018 branch_dest (rtx branch)
5020 rtx pat = PATTERN (branch);
5021 rtx dest = (GET_CODE (pat) == PARALLEL
5022 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
5023 int dest_uid;
5025 if (GET_CODE (dest) == IF_THEN_ELSE)
5026 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
5028 dest = XEXP (dest, 0);
5029 dest_uid = INSN_UID (dest);
5031 return INSN_ADDRESSES (dest_uid);
5035 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5037 static void
5038 arc_encode_section_info (tree decl, rtx rtl, int first)
5040 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5041 This clears machine specific flags, so has to come first. */
5042 default_encode_section_info (decl, rtl, first);
5044 /* Check if it is a function, and whether it has the
5045 [long/medium/short]_call attribute specified. */
5046 if (TREE_CODE (decl) == FUNCTION_DECL)
5048 rtx symbol = XEXP (rtl, 0);
5049 int flags = SYMBOL_REF_FLAGS (symbol);
5051 tree attr = (TREE_TYPE (decl) != error_mark_node
5052 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
5053 tree long_call_attr = lookup_attribute ("long_call", attr);
5054 tree medium_call_attr = lookup_attribute ("medium_call", attr);
5055 tree short_call_attr = lookup_attribute ("short_call", attr);
5057 if (long_call_attr != NULL_TREE)
5058 flags |= SYMBOL_FLAG_LONG_CALL;
5059 else if (medium_call_attr != NULL_TREE)
5060 flags |= SYMBOL_FLAG_MEDIUM_CALL;
5061 else if (short_call_attr != NULL_TREE)
5062 flags |= SYMBOL_FLAG_SHORT_CALL;
5064 SYMBOL_REF_FLAGS (symbol) = flags;
5066 else if (TREE_CODE (decl) == VAR_DECL)
5068 rtx symbol = XEXP (rtl, 0);
5070 tree attr = (TREE_TYPE (decl) != error_mark_node
5071 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
5073 tree sec_attr = lookup_attribute ("section", attr);
5074 if (sec_attr)
5076 const char *sec_name
5077 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
5078 if (strcmp (sec_name, ".cmem") == 0
5079 || strcmp (sec_name, ".cmem_shared") == 0
5080 || strcmp (sec_name, ".cmem_private") == 0)
5081 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
5086 /* This is how to output a definition of an internal numbered label where
5087 PREFIX is the class of label and NUM is the number within the class. */
5089 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
5091 if (cfun)
5092 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
5093 default_internal_label (stream, prefix, labelno);
5096 /* Set the cpu type and print out other fancy things,
5097 at the top of the file. */
5099 static void arc_file_start (void)
5101 default_file_start ();
5102 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
5104 /* Set some want to have build attributes. */
5105 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5106 ATTRIBUTE_PCS);
5107 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5108 TARGET_RF16 ? 1 : 0);
5109 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5110 flag_pic ? 2 : 0);
5111 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5112 (arc_tp_regno != -1) ? 1 : 0);
5113 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5114 TARGET_NO_SDATA_SET ? 0 : 2);
5115 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5116 TARGET_OPTFPE ? 1 : 0);
5117 if (TARGET_V2)
5118 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5119 arc_tune == ARC_TUNE_CORE_3 ? 3 : 2);
5122 /* Implement `TARGET_ASM_FILE_END'. */
5123 /* Outputs to the stdio stream FILE jli related text. */
5125 void arc_file_end (void)
5127 arc_jli_section *sec = arc_jli_sections;
5129 while (sec != NULL)
5131 fprintf (asm_out_file, "\n");
5132 fprintf (asm_out_file, "# JLI entry for function ");
5133 assemble_name (asm_out_file, sec->name);
5134 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
5135 ".jlitab.");
5136 assemble_name (asm_out_file, sec->name);
5137 fprintf (asm_out_file,", comdat\n");
5139 fprintf (asm_out_file, "\t.align\t4\n");
5140 fprintf (asm_out_file, "__jli.");
5141 assemble_name (asm_out_file, sec->name);
5142 fprintf (asm_out_file, ":\n\t.weak __jli.");
5143 assemble_name (asm_out_file, sec->name);
5144 fprintf (asm_out_file, "\n\tb\t@");
5145 assemble_name (asm_out_file, sec->name);
5146 fprintf (asm_out_file, "\n");
5147 sec = sec->next;
5149 file_end_indicate_exec_stack ();
5152 /* Cost functions. */
5154 /* Compute a (partial) cost for rtx X. Return true if the complete
5155 cost has been computed, and false if subexpressions should be
5156 scanned. In either case, *TOTAL contains the cost result. */
5158 static bool
5159 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
5160 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5162 int code = GET_CODE (x);
5164 switch (code)
5166 /* Small integers are as cheap as registers. */
5167 case CONST_INT:
5169 bool nolimm = false; /* Can we do without long immediate? */
5170 bool fast = false; /* Is the result available immediately? */
5171 bool condexec = false; /* Does this allow conditiobnal execution? */
5172 bool compact = false; /* Is a 16 bit opcode available? */
5173 /* CONDEXEC also implies that we can have an unconditional
5174 3-address operation. */
5176 nolimm = compact = condexec = false;
5177 if (UNSIGNED_INT6 (INTVAL (x)))
5178 nolimm = condexec = compact = true;
5179 else
5181 if (SMALL_INT (INTVAL (x)))
5182 nolimm = fast = true;
5183 switch (outer_code)
5185 case AND: /* bclr, bmsk, ext[bw] */
5186 if (satisfies_constraint_Ccp (x) /* bclr */
5187 || satisfies_constraint_C1p (x) /* bmsk */)
5188 nolimm = fast = condexec = compact = true;
5189 break;
5190 case IOR: /* bset */
5191 if (satisfies_constraint_C0p (x)) /* bset */
5192 nolimm = fast = condexec = compact = true;
5193 break;
5194 case XOR:
5195 if (satisfies_constraint_C0p (x)) /* bxor */
5196 nolimm = fast = condexec = true;
5197 break;
5198 case SET:
5199 if (satisfies_constraint_Crr (x)) /* ror b,u6 */
5200 nolimm = true;
5201 default:
5202 break;
5205 /* FIXME: Add target options to attach a small cost if
5206 condexec / compact is not true. */
5207 if (nolimm)
5209 *total = 0;
5210 return true;
5213 /* FALLTHRU */
5215 /* 4 byte values can be fetched as immediate constants -
5216 let's give that the cost of an extra insn. */
5217 case CONST:
5218 case LABEL_REF:
5219 case SYMBOL_REF:
5220 *total = COSTS_N_INSNS (1);
5221 return true;
5223 case CONST_DOUBLE:
5225 rtx first, second;
5227 if (TARGET_DPFP)
5229 *total = COSTS_N_INSNS (1);
5230 return true;
5232 split_double (x, &first, &second);
5233 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
5234 + !SMALL_INT (INTVAL (second)));
5235 return true;
5238 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5239 If we need more than 12 insns to do a multiply, then go out-of-line,
5240 since the call overhead will be < 10% of the cost of the multiply. */
5241 case ASHIFT:
5242 case ASHIFTRT:
5243 case LSHIFTRT:
5244 if (TARGET_BARREL_SHIFTER)
5246 /* If we want to shift a constant, we need a LIMM. */
5247 /* ??? when the optimizers want to know if a constant should be
5248 hoisted, they ask for the cost of the constant. OUTER_CODE is
5249 insufficient context for shifts since we don't know which operand
5250 we are looking at. */
5251 if (CONSTANT_P (XEXP (x, 0)))
5253 *total += (COSTS_N_INSNS (2)
5254 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
5255 0, speed));
5256 return true;
5258 *total = COSTS_N_INSNS (1);
5260 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5261 *total = COSTS_N_INSNS (16);
5262 else
5264 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
5265 /* ??? want_to_gcse_p can throw negative shift counts at us,
5266 and then panics when it gets a negative cost as result.
5267 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5268 if (*total < 0)
5269 *total = 0;
5271 return false;
5273 case DIV:
5274 case UDIV:
5275 if (speed)
5276 *total = COSTS_N_INSNS(30);
5277 else
5278 *total = COSTS_N_INSNS(1);
5279 return false;
5281 case MULT:
5282 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5283 *total = COSTS_N_INSNS (1);
5284 else if (speed)
5285 *total= arc_multcost;
5286 /* We do not want synth_mult sequences when optimizing
5287 for size. */
5288 else if (TARGET_MUL64_SET || TARGET_ARC700_MPY)
5289 *total = COSTS_N_INSNS (1);
5290 else
5291 *total = COSTS_N_INSNS (2);
5292 return false;
5293 case PLUS:
5294 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5295 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5296 || (GET_CODE (XEXP (x, 0)) == MULT
5297 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5299 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
5300 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
5301 return true;
5303 return false;
5304 case MINUS:
5305 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5306 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5307 || (GET_CODE (XEXP (x, 1)) == MULT
5308 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5310 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
5311 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
5312 return true;
5314 return false;
5315 case COMPARE:
5317 rtx op0 = XEXP (x, 0);
5318 rtx op1 = XEXP (x, 1);
5320 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5321 && XEXP (op0, 1) == const1_rtx)
5323 /* btst / bbit0 / bbit1:
5324 Small integers and registers are free; everything else can
5325 be put in a register. */
5326 mode = GET_MODE (XEXP (op0, 0));
5327 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5328 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5329 return true;
5331 if (GET_CODE (op0) == AND && op1 == const0_rtx
5332 && satisfies_constraint_C1p (XEXP (op0, 1)))
5334 /* bmsk.f */
5335 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5336 return true;
5338 /* add.f */
5339 if (GET_CODE (op1) == NEG)
5341 /* op0 might be constant, the inside of op1 is rather
5342 unlikely to be so. So swapping the operands might lower
5343 the cost. */
5344 mode = GET_MODE (op0);
5345 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5346 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5348 return false;
5350 case EQ: case NE:
5351 if (outer_code == IF_THEN_ELSE
5352 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5353 && XEXP (x, 1) == const0_rtx
5354 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5356 /* btst / bbit0 / bbit1:
5357 Small integers and registers are free; everything else can
5358 be put in a register. */
5359 rtx op0 = XEXP (x, 0);
5361 mode = GET_MODE (XEXP (op0, 0));
5362 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5363 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5364 return true;
5366 /* Fall through. */
5367 /* scc_insn expands into two insns. */
5368 case GTU: case GEU: case LEU:
5369 if (mode == SImode)
5370 *total += COSTS_N_INSNS (1);
5371 return false;
5372 case LTU: /* might use adc. */
5373 if (mode == SImode)
5374 *total += COSTS_N_INSNS (1) - 1;
5375 return false;
5376 default:
5377 return false;
5381 /* Return true if ADDR is a valid pic address.
5382 A valid pic address on arc should look like
5383 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5385 bool
5386 arc_legitimate_pic_addr_p (rtx addr)
5388 if (GET_CODE (addr) != CONST)
5389 return false;
5391 addr = XEXP (addr, 0);
5394 if (GET_CODE (addr) == PLUS)
5396 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
5397 return false;
5398 addr = XEXP (addr, 0);
5401 if (GET_CODE (addr) != UNSPEC
5402 || XVECLEN (addr, 0) != 1)
5403 return false;
5405 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5406 if (XINT (addr, 1) != ARC_UNSPEC_GOT
5407 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
5408 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
5409 && XINT (addr, 1) != UNSPEC_TLS_GD
5410 && XINT (addr, 1) != UNSPEC_TLS_IE)
5411 return false;
5413 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
5414 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
5415 return false;
5417 return true;
5422 /* Return true if OP contains a symbol reference. */
5424 static bool
5425 symbolic_reference_mentioned_p (rtx op)
5427 register const char *fmt;
5428 register int i;
5430 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5431 return true;
5433 fmt = GET_RTX_FORMAT (GET_CODE (op));
5434 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5436 if (fmt[i] == 'E')
5438 register int j;
5440 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5441 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5442 return true;
5445 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5446 return true;
5449 return false;
5452 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5453 If SKIP_LOCAL is true, skip symbols that bind locally.
5454 This is used further down in this file, and, without SKIP_LOCAL,
5455 in the addsi3 / subsi3 expanders when generating PIC code. */
5457 bool
5458 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
5460 register const char *fmt;
5461 register int i;
5463 if (GET_CODE(op) == UNSPEC)
5464 return false;
5466 if (GET_CODE (op) == SYMBOL_REF)
5468 if (SYMBOL_REF_TLS_MODEL (op))
5469 return true;
5470 if (!flag_pic)
5471 return false;
5472 tree decl = SYMBOL_REF_DECL (op);
5473 return !skip_local || !decl || !default_binds_local_p (decl);
5476 fmt = GET_RTX_FORMAT (GET_CODE (op));
5477 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5479 if (fmt[i] == 'E')
5481 register int j;
5483 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5484 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
5485 skip_local))
5486 return true;
5489 else if (fmt[i] == 'e'
5490 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
5491 skip_local))
5492 return true;
5495 return false;
5498 /* Get the thread pointer. */
5500 static rtx
5501 arc_get_tp (void)
5503 /* If arc_tp_regno has been set, we can use that hard register
5504 directly as a base register. */
5505 if (arc_tp_regno != -1)
5506 return gen_rtx_REG (Pmode, arc_tp_regno);
5508 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5509 conflicts with function arguments / results. */
5510 rtx reg = gen_reg_rtx (Pmode);
5511 emit_insn (gen_tls_load_tp_soft ());
5512 emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG));
5513 return reg;
5516 /* Helper to be used by TLS Global dynamic model. */
5518 static rtx
5519 arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
5521 rtx r0 = gen_rtx_REG (Pmode, R0_REG);
5522 rtx call_fusage = NULL_RTX;
5524 start_sequence ();
5526 rtx x = arc_unspec_offset (sym, reloc);
5527 emit_move_insn (r0, x);
5528 use_reg (&call_fusage, r0);
5530 gcc_assert (reloc == UNSPEC_TLS_GD);
5531 rtx call_insn = emit_call_insn (gen_tls_gd_get_addr (sym));
5532 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5533 way that the application should care. */
5534 RTL_PURE_CALL_P (call_insn) = 1;
5535 add_function_usage_to (call_insn, call_fusage);
5537 rtx_insn *insns = get_insns ();
5538 end_sequence ();
5540 rtx dest = gen_reg_rtx (Pmode);
5541 emit_libcall_block (insns, dest, r0, eqv);
5542 return dest;
5545 #define DTPOFF_ZERO_SYM ".tdata"
5547 /* Return a legitimized address for ADDR,
5548 which is a SYMBOL_REF with tls_model MODEL. */
5550 static rtx
5551 arc_legitimize_tls_address (rtx addr, enum tls_model model)
5553 if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC)
5554 model = TLS_MODEL_LOCAL_EXEC;
5556 switch (model)
5558 case TLS_MODEL_LOCAL_DYNAMIC:
5559 rtx base;
5560 tree decl;
5561 const char *base_name;
5562 rtvec v;
5564 decl = SYMBOL_REF_DECL (addr);
5565 base_name = DTPOFF_ZERO_SYM;
5566 if (decl && bss_initializer_p (decl))
5567 base_name = ".tbss";
5569 base = gen_rtx_SYMBOL_REF (Pmode, base_name);
5570 if (strcmp (base_name, DTPOFF_ZERO_SYM) == 0)
5572 if (!flag_pic)
5573 goto local_exec;
5574 v = gen_rtvec (1, addr);
5576 else
5577 v = gen_rtvec (2, addr, base);
5578 addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_TLS_OFF);
5579 addr = gen_rtx_CONST (Pmode, addr);
5580 base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
5581 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
5583 case TLS_MODEL_GLOBAL_DYNAMIC:
5584 return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
5586 case TLS_MODEL_INITIAL_EXEC:
5587 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
5588 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
5589 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5591 case TLS_MODEL_LOCAL_EXEC:
5592 local_exec:
5593 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
5594 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5595 default:
5596 gcc_unreachable ();
5600 /* Legitimize a pic address reference in ORIG.
5601 The return value is the legitimated address.
5602 If OLDX is non-zero, it is the target to assign the address to first. */
5604 static rtx
5605 arc_legitimize_pic_address (rtx orig, rtx oldx)
5607 rtx addr = orig;
5608 rtx pat = orig;
5609 rtx base;
5611 if (oldx == orig)
5612 oldx = NULL;
5614 if (GET_CODE (addr) == LABEL_REF)
5615 ; /* Do nothing. */
5616 else if (GET_CODE (addr) == SYMBOL_REF)
5618 enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
5619 if (model != 0)
5620 return arc_legitimize_tls_address (addr, model);
5621 else if (!flag_pic)
5622 return orig;
5623 else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
5624 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
5626 /* This symbol must be referenced via a load from the Global
5627 Offset Table (@GOTPC). */
5628 pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
5629 pat = gen_const_mem (Pmode, pat);
5631 if (oldx == NULL)
5632 oldx = gen_reg_rtx (Pmode);
5634 emit_move_insn (oldx, pat);
5635 pat = oldx;
5637 else
5639 if (GET_CODE (addr) == CONST)
5641 addr = XEXP (addr, 0);
5642 if (GET_CODE (addr) == UNSPEC)
5644 /* Check that the unspec is one of the ones we generate? */
5645 return orig;
5647 /* fwprop is placing in the REG_EQUIV notes constant pic
5648 unspecs expressions. Then, loop may use these notes for
5649 optimizations resulting in complex patterns that are not
5650 supported by the current implementation. The following
5651 two if-cases are simplifying the complex patters to
5652 simpler ones. */
5653 else if (GET_CODE (addr) == MINUS)
5655 rtx op0 = XEXP (addr, 0);
5656 rtx op1 = XEXP (addr, 1);
5657 gcc_assert (oldx);
5658 gcc_assert (GET_CODE (op1) == UNSPEC);
5660 emit_move_insn (oldx,
5661 gen_rtx_CONST (SImode,
5662 arc_legitimize_pic_address (op1,
5663 NULL_RTX)));
5664 emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
5665 return oldx;
5668 else if (GET_CODE (addr) != PLUS)
5670 rtx tmp = XEXP (addr, 0);
5671 enum rtx_code code = GET_CODE (addr);
5673 /* It only works for UNARY operations. */
5674 gcc_assert (UNARY_P (addr));
5675 gcc_assert (GET_CODE (tmp) == UNSPEC);
5676 gcc_assert (oldx);
5678 emit_move_insn
5679 (oldx,
5680 gen_rtx_CONST (SImode,
5681 arc_legitimize_pic_address (tmp,
5682 NULL_RTX)));
5684 emit_insn (gen_rtx_SET (oldx,
5685 gen_rtx_fmt_ee (code, SImode,
5686 oldx, const0_rtx)));
5688 return oldx;
5690 else
5692 gcc_assert (GET_CODE (addr) == PLUS);
5693 if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
5694 return orig;
5698 if (GET_CODE (addr) == PLUS)
5700 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
5702 base = arc_legitimize_pic_address (op0, oldx);
5703 pat = arc_legitimize_pic_address (op1,
5704 base == oldx ? NULL_RTX : oldx);
5706 if (base == op0 && pat == op1)
5707 return orig;
5709 if (GET_CODE (pat) == CONST_INT)
5710 pat = plus_constant (Pmode, base, INTVAL (pat));
5711 else
5713 if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1)))
5715 base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0));
5716 pat = XEXP (pat, 1);
5718 pat = gen_rtx_PLUS (Pmode, base, pat);
5723 return pat;
5726 /* Output address constant X to FILE, taking PIC into account. */
5728 static void
5729 arc_output_pic_addr_const (FILE * file, rtx x, int code)
5731 char buf[256];
5733 restart:
5734 switch (GET_CODE (x))
5736 case PC:
5737 if (flag_pic)
5738 putc ('.', file);
5739 else
5740 gcc_unreachable ();
5741 break;
5743 case SYMBOL_REF:
5744 output_addr_const (file, x);
5746 /* Local functions do not get references through the PLT. */
5747 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
5748 fputs ("@plt", file);
5749 break;
5751 case LABEL_REF:
5752 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
5753 assemble_name (file, buf);
5754 break;
5756 case CODE_LABEL:
5757 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
5758 assemble_name (file, buf);
5759 break;
5761 case CONST_INT:
5762 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
5763 break;
5765 case CONST:
5766 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5767 break;
5769 case CONST_DOUBLE:
5770 if (GET_MODE (x) == VOIDmode)
5772 /* We can use %d if the number is one word and positive. */
5773 if (CONST_DOUBLE_HIGH (x))
5774 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
5775 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
5776 else if (CONST_DOUBLE_LOW (x) < 0)
5777 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
5778 else
5779 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
5781 else
5782 /* We can't handle floating point constants;
5783 PRINT_OPERAND must handle them. */
5784 output_operand_lossage ("floating constant misused");
5785 break;
5787 case PLUS:
5788 /* FIXME: Not needed here. */
5789 /* Some assemblers need integer constants to appear last (eg masm). */
5790 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
5792 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5793 fprintf (file, "+");
5794 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5796 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5798 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5799 if (INTVAL (XEXP (x, 1)) >= 0)
5800 fprintf (file, "+");
5801 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5803 else
5804 gcc_unreachable();
5805 break;
5807 case MINUS:
5808 /* Avoid outputting things like x-x or x+5-x,
5809 since some assemblers can't handle that. */
5810 x = simplify_subtraction (x);
5811 if (GET_CODE (x) != MINUS)
5812 goto restart;
5814 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5815 fprintf (file, "-");
5816 if (GET_CODE (XEXP (x, 1)) == CONST_INT
5817 && INTVAL (XEXP (x, 1)) < 0)
5819 fprintf (file, "(");
5820 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5821 fprintf (file, ")");
5823 else
5824 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5825 break;
5827 case ZERO_EXTEND:
5828 case SIGN_EXTEND:
5829 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5830 break;
5833 case UNSPEC:
5834 const char *suffix;
5835 bool pcrel; pcrel = false;
5836 rtx base; base = NULL;
5837 gcc_assert (XVECLEN (x, 0) >= 1);
5838 switch (XINT (x, 1))
5840 case ARC_UNSPEC_GOT:
5841 suffix = "@gotpc", pcrel = true;
5842 break;
5843 case ARC_UNSPEC_GOTOFF:
5844 suffix = "@gotoff";
5845 break;
5846 case ARC_UNSPEC_GOTOFFPC:
5847 suffix = "@pcl", pcrel = true;
5848 break;
5849 case ARC_UNSPEC_PLT:
5850 suffix = "@plt";
5851 break;
5852 case UNSPEC_TLS_GD:
5853 suffix = "@tlsgd", pcrel = true;
5854 break;
5855 case UNSPEC_TLS_IE:
5856 suffix = "@tlsie", pcrel = true;
5857 break;
5858 case UNSPEC_TLS_OFF:
5859 if (XVECLEN (x, 0) == 2)
5860 base = XVECEXP (x, 0, 1);
5861 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5862 || (!flag_pic && !base))
5863 suffix = "@tpoff";
5864 else
5865 suffix = "@dtpoff";
5866 break;
5867 default:
5868 suffix = "@invalid";
5869 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
5870 break;
5872 if (pcrel)
5873 fputs ("pcl,", file);
5874 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
5875 fputs (suffix, file);
5876 if (base)
5877 arc_output_pic_addr_const (file, base, code);
5878 break;
5880 default:
5881 output_operand_lossage ("invalid expression as operand");
5885 #define SYMBOLIC_CONST(X) \
5886 (GET_CODE (X) == SYMBOL_REF \
5887 || GET_CODE (X) == LABEL_REF \
5888 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5890 /* Emit insns to move operands[1] into operands[0]. */
5892 static void
5893 prepare_pic_move (rtx *operands, machine_mode)
5895 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])
5896 && flag_pic)
5897 operands[1] = force_reg (Pmode, operands[1]);
5898 else
5900 rtx temp = (reload_in_progress ? operands[0]
5901 : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX);
5902 operands[1] = arc_legitimize_pic_address (operands[1], temp);
5907 /* The function returning the number of words, at the beginning of an
5908 argument, must be put in registers. The returned value must be
5909 zero for arguments that are passed entirely in registers or that
5910 are entirely pushed on the stack.
5912 On some machines, certain arguments must be passed partially in
5913 registers and partially in memory. On these machines, typically
5914 the first N words of arguments are passed in registers, and the
5915 rest on the stack. If a multi-word argument (a `double' or a
5916 structure) crosses that boundary, its first few words must be
5917 passed in registers and the rest must be pushed. This function
5918 tells the compiler when this occurs, and how many of the words
5919 should go in registers.
5921 `FUNCTION_ARG' for these arguments should return the first register
5922 to be used by the caller for this argument; likewise
5923 `FUNCTION_INCOMING_ARG', for the called function.
5925 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5927 /* If REGNO is the least arg reg available then what is the total number of arg
5928 regs available. */
5929 #define GPR_REST_ARG_REGS(REGNO) \
5930 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5932 /* Since arc parm regs are contiguous. */
5933 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
5935 /* Implement TARGET_ARG_PARTIAL_BYTES. */
5937 static int
5938 arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
5939 tree type, bool named ATTRIBUTE_UNUSED)
5941 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
5942 int bytes = (mode == BLKmode
5943 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
5944 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
5945 int arg_num = *cum;
5946 int ret;
5948 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
5949 ret = GPR_REST_ARG_REGS (arg_num);
5951 /* ICEd at function.c:2361, and ret is copied to data->partial */
5952 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
5954 return ret;
5957 /* This function is used to control a function argument is passed in a
5958 register, and which register.
5960 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
5961 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
5962 all of the previous arguments so far passed in registers; MODE, the
5963 machine mode of the argument; TYPE, the data type of the argument
5964 as a tree node or 0 if that is not known (which happens for C
5965 support library functions); and NAMED, which is 1 for an ordinary
5966 argument and 0 for nameless arguments that correspond to `...' in
5967 the called function's prototype.
5969 The returned value should either be a `reg' RTX for the hard
5970 register in which to pass the argument, or zero to pass the
5971 argument on the stack.
5973 For machines like the Vax and 68000, where normally all arguments
5974 are pushed, zero suffices as a definition.
5976 The usual way to make the ANSI library `stdarg.h' work on a machine
5977 where some arguments are usually passed in registers, is to cause
5978 nameless arguments to be passed on the stack instead. This is done
5979 by making the function return 0 whenever NAMED is 0.
5981 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
5982 definition of this function to determine if this argument is of a
5983 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
5984 is not defined and the function returns non-zero for such an
5985 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
5986 defined, the argument will be computed in the stack and then loaded
5987 into a register.
5989 The function is used to implement macro FUNCTION_ARG. */
5990 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
5991 and the rest are pushed. */
5993 static rtx
5994 arc_function_arg (cumulative_args_t cum_v,
5995 machine_mode mode,
5996 const_tree type ATTRIBUTE_UNUSED,
5997 bool named ATTRIBUTE_UNUSED)
5999 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6000 int arg_num = *cum;
6001 rtx ret;
6002 const char *debstr ATTRIBUTE_UNUSED;
6004 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
6005 /* Return a marker for use in the call instruction. */
6006 if (mode == VOIDmode)
6008 ret = const0_rtx;
6009 debstr = "<0>";
6011 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6013 ret = gen_rtx_REG (mode, arg_num);
6014 debstr = reg_names [arg_num];
6016 else
6018 ret = NULL_RTX;
6019 debstr = "memory";
6021 return ret;
6024 /* The function to update the summarizer variable *CUM to advance past
6025 an argument in the argument list. The values MODE, TYPE and NAMED
6026 describe that argument. Once this is done, the variable *CUM is
6027 suitable for analyzing the *following* argument with
6028 `FUNCTION_ARG', etc.
6030 This function need not do anything if the argument in question was
6031 passed on the stack. The compiler knows how to track the amount of
6032 stack space used for arguments without any special help.
6034 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
6035 /* For the ARC: the cum set here is passed on to function_arg where we
6036 look at its value and say which reg to use. Strategy: advance the
6037 regnumber here till we run out of arg regs, then set *cum to last
6038 reg. In function_arg, since *cum > last arg reg we would return 0
6039 and thus the arg will end up on the stack. For straddling args of
6040 course function_arg_partial_nregs will come into play. */
6042 static void
6043 arc_function_arg_advance (cumulative_args_t cum_v,
6044 machine_mode mode,
6045 const_tree type,
6046 bool named ATTRIBUTE_UNUSED)
6048 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6049 int bytes = (mode == BLKmode
6050 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
6051 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6052 int i;
6054 if (words)
6055 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
6056 for (i = 0; i < words; i++)
6057 *cum = ARC_NEXT_ARG_REG (*cum);
6061 /* Define how to find the value returned by a function.
6062 VALTYPE is the data type of the value (as a tree).
6063 If the precise function being called is known, FN_DECL_OR_TYPE is its
6064 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6066 static rtx
6067 arc_function_value (const_tree valtype,
6068 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6069 bool outgoing ATTRIBUTE_UNUSED)
6071 machine_mode mode = TYPE_MODE (valtype);
6072 int unsignedp ATTRIBUTE_UNUSED;
6074 unsignedp = TYPE_UNSIGNED (valtype);
6075 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6076 PROMOTE_MODE (mode, unsignedp, valtype);
6077 return gen_rtx_REG (mode, 0);
6080 /* Returns the return address that is used by builtin_return_address. */
6083 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6085 if (count != 0)
6086 return const0_rtx;
6088 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6091 /* Determine if a given RTX is a valid constant. We already know this
6092 satisfies CONSTANT_P. */
6094 bool
6095 arc_legitimate_constant_p (machine_mode mode, rtx x)
6097 switch (GET_CODE (x))
6099 case CONST:
6100 if (flag_pic)
6102 if (arc_legitimate_pic_addr_p (x))
6103 return true;
6105 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6107 case SYMBOL_REF:
6108 if (SYMBOL_REF_TLS_MODEL (x))
6109 return false;
6110 /* Fall through. */
6111 case LABEL_REF:
6112 if (flag_pic)
6113 return false;
6114 /* Fall through. */
6115 case CONST_INT:
6116 case CONST_DOUBLE:
6117 return true;
6119 case NEG:
6120 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6122 case PLUS:
6123 case MINUS:
6125 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6126 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6128 return (t1 && t2);
6131 case CONST_VECTOR:
6132 switch (mode)
6134 case E_V2HImode:
6135 return TARGET_PLUS_DMPY;
6136 case E_V2SImode:
6137 case E_V4HImode:
6138 return TARGET_PLUS_QMACW;
6139 default:
6140 return false;
6143 case UNSPEC:
6144 switch (XINT (x, 1))
6146 case UNSPEC_TLS_GD:
6147 case UNSPEC_TLS_OFF:
6148 case UNSPEC_TLS_IE:
6149 return true;
6150 default:
6151 /* Any other unspec ending here are pic related, hence the above
6152 constant pic address checking returned false. */
6153 return false;
6155 /* Fall through. */
6157 default:
6158 fatal_insn ("unrecognized supposed constant", x);
6161 gcc_unreachable ();
6164 static bool
6165 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
6167 if (RTX_OK_FOR_BASE_P (x, strict))
6168 return true;
6169 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
6170 return true;
6171 if (legitimate_scaled_address_p (mode, x, strict))
6172 return true;
6173 if (LEGITIMATE_SMALL_DATA_ADDRESS_P (x))
6174 return true;
6175 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6176 return true;
6178 /* When we compile for size avoid const (@sym + offset)
6179 addresses. */
6180 if (!flag_pic && optimize_size && !reload_completed
6181 && (GET_CODE (x) == CONST)
6182 && (GET_CODE (XEXP (x, 0)) == PLUS)
6183 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6184 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6185 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
6187 rtx addend = XEXP (XEXP (x, 0), 1);
6188 gcc_assert (CONST_INT_P (addend));
6189 HOST_WIDE_INT offset = INTVAL (addend);
6191 /* Allow addresses having a large offset to pass. Anyhow they
6192 will end in a limm. */
6193 return !(offset > -1024 && offset < 1020);
6196 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6198 return arc_legitimate_constant_p (mode, x);
6200 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6201 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6202 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6203 return true;
6204 /* We're restricted here by the `st' insn. */
6205 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6206 && GET_CODE (XEXP ((x), 1)) == PLUS
6207 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
6208 && legitimate_offset_address_p (QImode, XEXP (x, 1),
6209 TARGET_AUTO_MODIFY_REG, strict))
6210 return true;
6211 return false;
6214 /* Return true iff ADDR (a legitimate address expression)
6215 has an effect that depends on the machine mode it is used for. */
6217 static bool
6218 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6220 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6221 which is valid for loads and stores, or a limm offset, which is valid for
6222 loads. Scaled indices are scaled by the access mode. */
6223 if (GET_CODE (addr) == PLUS
6224 && GET_CODE (XEXP ((addr), 0)) == MULT)
6225 return true;
6226 return false;
6229 /* Determine if it's legal to put X into the constant pool. */
6231 static bool
6232 arc_cannot_force_const_mem (machine_mode mode, rtx x)
6234 return !arc_legitimate_constant_p (mode, x);
6237 /* IDs for all the ARC builtins. */
6239 enum arc_builtin_id
6241 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6242 ARC_BUILTIN_ ## NAME,
6243 #include "builtins.def"
6244 #undef DEF_BUILTIN
6246 ARC_BUILTIN_COUNT
6249 struct GTY(()) arc_builtin_description
6251 enum insn_code icode;
6252 int n_args;
6253 tree fndecl;
6256 static GTY(()) struct arc_builtin_description
6257 arc_bdesc[ARC_BUILTIN_COUNT] =
6259 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6260 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6261 #include "builtins.def"
6262 #undef DEF_BUILTIN
6265 /* Transform UP into lowercase and write the result to LO.
6266 You must provide enough space for LO. Return LO. */
6268 static char*
6269 arc_tolower (char *lo, const char *up)
6271 char *lo0 = lo;
6273 for (; *up; up++, lo++)
6274 *lo = TOLOWER (*up);
6276 *lo = '\0';
6278 return lo0;
6281 /* Implement `TARGET_BUILTIN_DECL'. */
6283 static tree
6284 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6286 if (id < ARC_BUILTIN_COUNT)
6287 return arc_bdesc[id].fndecl;
6289 return error_mark_node;
6292 static void
6293 arc_init_builtins (void)
6295 tree V4HI_type_node;
6296 tree V2SI_type_node;
6297 tree V2HI_type_node;
6299 /* Vector types based on HS SIMD elements. */
6300 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6301 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6302 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6304 tree pcvoid_type_node
6305 = build_pointer_type (build_qualified_type (void_type_node,
6306 TYPE_QUAL_CONST));
6307 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6308 V8HImode);
6310 tree void_ftype_void
6311 = build_function_type_list (void_type_node, NULL_TREE);
6312 tree int_ftype_int
6313 = build_function_type_list (integer_type_node, integer_type_node,
6314 NULL_TREE);
6315 tree int_ftype_pcvoid_int
6316 = build_function_type_list (integer_type_node, pcvoid_type_node,
6317 integer_type_node, NULL_TREE);
6318 tree void_ftype_usint_usint
6319 = build_function_type_list (void_type_node, long_unsigned_type_node,
6320 long_unsigned_type_node, NULL_TREE);
6321 tree int_ftype_int_int
6322 = build_function_type_list (integer_type_node, integer_type_node,
6323 integer_type_node, NULL_TREE);
6324 tree usint_ftype_usint
6325 = build_function_type_list (long_unsigned_type_node,
6326 long_unsigned_type_node, NULL_TREE);
6327 tree void_ftype_usint
6328 = build_function_type_list (void_type_node, long_unsigned_type_node,
6329 NULL_TREE);
6330 tree int_ftype_void
6331 = build_function_type_list (integer_type_node, void_type_node,
6332 NULL_TREE);
6333 tree void_ftype_int
6334 = build_function_type_list (void_type_node, integer_type_node,
6335 NULL_TREE);
6336 tree int_ftype_short
6337 = build_function_type_list (integer_type_node, short_integer_type_node,
6338 NULL_TREE);
6340 /* Old ARC SIMD types. */
6341 tree v8hi_ftype_v8hi_v8hi
6342 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6343 V8HI_type_node, NULL_TREE);
6344 tree v8hi_ftype_v8hi_int
6345 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6346 integer_type_node, NULL_TREE);
6347 tree v8hi_ftype_v8hi_int_int
6348 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6349 integer_type_node, integer_type_node,
6350 NULL_TREE);
6351 tree void_ftype_v8hi_int_int
6352 = build_function_type_list (void_type_node, V8HI_type_node,
6353 integer_type_node, integer_type_node,
6354 NULL_TREE);
6355 tree void_ftype_v8hi_int_int_int
6356 = build_function_type_list (void_type_node, V8HI_type_node,
6357 integer_type_node, integer_type_node,
6358 integer_type_node, NULL_TREE);
6359 tree v8hi_ftype_int_int
6360 = build_function_type_list (V8HI_type_node, integer_type_node,
6361 integer_type_node, NULL_TREE);
6362 tree void_ftype_int_int
6363 = build_function_type_list (void_type_node, integer_type_node,
6364 integer_type_node, NULL_TREE);
6365 tree v8hi_ftype_v8hi
6366 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6367 NULL_TREE);
6368 /* ARCv2 SIMD types. */
6369 tree long_ftype_v4hi_v4hi
6370 = build_function_type_list (long_long_integer_type_node,
6371 V4HI_type_node, V4HI_type_node, NULL_TREE);
6372 tree int_ftype_v2hi_v2hi
6373 = build_function_type_list (integer_type_node,
6374 V2HI_type_node, V2HI_type_node, NULL_TREE);
6375 tree v2si_ftype_v2hi_v2hi
6376 = build_function_type_list (V2SI_type_node,
6377 V2HI_type_node, V2HI_type_node, NULL_TREE);
6378 tree v2hi_ftype_v2hi_v2hi
6379 = build_function_type_list (V2HI_type_node,
6380 V2HI_type_node, V2HI_type_node, NULL_TREE);
6381 tree v2si_ftype_v2si_v2si
6382 = build_function_type_list (V2SI_type_node,
6383 V2SI_type_node, V2SI_type_node, NULL_TREE);
6384 tree v4hi_ftype_v4hi_v4hi
6385 = build_function_type_list (V4HI_type_node,
6386 V4HI_type_node, V4HI_type_node, NULL_TREE);
6387 tree long_ftype_v2si_v2hi
6388 = build_function_type_list (long_long_integer_type_node,
6389 V2SI_type_node, V2HI_type_node, NULL_TREE);
6391 /* Add the builtins. */
6392 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6394 int id = ARC_BUILTIN_ ## NAME; \
6395 const char *Name = "__builtin_arc_" #NAME; \
6396 char *name = (char*) alloca (1 + strlen (Name)); \
6398 gcc_assert (id < ARC_BUILTIN_COUNT); \
6399 if (MASK) \
6400 arc_bdesc[id].fndecl \
6401 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6402 BUILT_IN_MD, NULL, NULL_TREE); \
6404 #include "builtins.def"
6405 #undef DEF_BUILTIN
6408 /* Helper to expand __builtin_arc_aligned (void* val, int
6409 alignval). */
6411 static rtx
6412 arc_expand_builtin_aligned (tree exp)
6414 tree arg0 = CALL_EXPR_ARG (exp, 0);
6415 tree arg1 = CALL_EXPR_ARG (exp, 1);
6416 fold (arg1);
6417 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6418 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6420 if (!CONST_INT_P (op1))
6422 /* If we can't fold the alignment to a constant integer
6423 whilst optimizing, this is probably a user error. */
6424 if (optimize)
6425 warning (0, "__builtin_arc_aligned with non-constant alignment");
6427 else
6429 HOST_WIDE_INT alignTest = INTVAL (op1);
6430 /* Check alignTest is positive, and a power of two. */
6431 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6433 error ("invalid alignment value for __builtin_arc_aligned");
6434 return NULL_RTX;
6437 if (CONST_INT_P (op0))
6439 HOST_WIDE_INT pnt = INTVAL (op0);
6441 if ((pnt & (alignTest - 1)) == 0)
6442 return const1_rtx;
6444 else
6446 unsigned align = get_pointer_alignment (arg0);
6447 unsigned numBits = alignTest * BITS_PER_UNIT;
6449 if (align && align >= numBits)
6450 return const1_rtx;
6451 /* Another attempt to ascertain alignment. Check the type
6452 we are pointing to. */
6453 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6454 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6455 return const1_rtx;
6459 /* Default to false. */
6460 return const0_rtx;
6463 /* Helper arc_expand_builtin, generates a pattern for the given icode
6464 and arguments. */
6466 static rtx_insn *
6467 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6469 switch (insn_data[icode].n_generator_args)
6471 case 0:
6472 return GEN_FCN (icode) ();
6473 case 1:
6474 return GEN_FCN (icode) (arg[0]);
6475 case 2:
6476 return GEN_FCN (icode) (arg[0], arg[1]);
6477 case 3:
6478 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6479 case 4:
6480 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6481 case 5:
6482 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6483 default:
6484 gcc_unreachable ();
6488 /* Expand an expression EXP that calls a built-in function,
6489 with result going to TARGET if that's convenient
6490 (and in mode MODE if that's convenient).
6491 SUBTARGET may be used as the target for computing one of EXP's operands.
6492 IGNORE is nonzero if the value is to be ignored. */
6494 static rtx
6495 arc_expand_builtin (tree exp,
6496 rtx target,
6497 rtx subtarget ATTRIBUTE_UNUSED,
6498 machine_mode mode ATTRIBUTE_UNUSED,
6499 int ignore ATTRIBUTE_UNUSED)
6501 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6502 unsigned int id = DECL_FUNCTION_CODE (fndecl);
6503 const struct arc_builtin_description *d = &arc_bdesc[id];
6504 int i, j, n_args = call_expr_nargs (exp);
6505 rtx pat = NULL_RTX;
6506 rtx xop[5];
6507 enum insn_code icode = d->icode;
6508 machine_mode tmode = insn_data[icode].operand[0].mode;
6509 int nonvoid;
6510 tree arg0;
6511 tree arg1;
6512 tree arg2;
6513 tree arg3;
6514 rtx op0;
6515 rtx op1;
6516 rtx op2;
6517 rtx op3;
6518 rtx op4;
6519 machine_mode mode0;
6520 machine_mode mode1;
6521 machine_mode mode2;
6522 machine_mode mode3;
6523 machine_mode mode4;
6525 if (id >= ARC_BUILTIN_COUNT)
6526 internal_error ("bad builtin fcode");
6528 /* 1st part: Expand special builtins. */
6529 switch (id)
6531 case ARC_BUILTIN_NOP:
6532 emit_insn (gen_nopv ());
6533 return NULL_RTX;
6535 case ARC_BUILTIN_RTIE:
6536 case ARC_BUILTIN_SYNC:
6537 case ARC_BUILTIN_BRK:
6538 case ARC_BUILTIN_SWI:
6539 case ARC_BUILTIN_UNIMP_S:
6540 gcc_assert (icode != 0);
6541 emit_insn (GEN_FCN (icode) (const1_rtx));
6542 return NULL_RTX;
6544 case ARC_BUILTIN_ALIGNED:
6545 return arc_expand_builtin_aligned (exp);
6547 case ARC_BUILTIN_CLRI:
6548 target = gen_reg_rtx (SImode);
6549 emit_insn (gen_clri (target, const1_rtx));
6550 return target;
6552 case ARC_BUILTIN_TRAP_S:
6553 case ARC_BUILTIN_SLEEP:
6554 arg0 = CALL_EXPR_ARG (exp, 0);
6555 fold (arg0);
6556 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6558 if (!CONST_INT_P (op0) || !satisfies_constraint_L (op0))
6560 error ("builtin operand should be an unsigned 6-bit value");
6561 return NULL_RTX;
6563 gcc_assert (icode != 0);
6564 emit_insn (GEN_FCN (icode) (op0));
6565 return NULL_RTX;
6567 case ARC_BUILTIN_VDORUN:
6568 case ARC_BUILTIN_VDIRUN:
6569 arg0 = CALL_EXPR_ARG (exp, 0);
6570 arg1 = CALL_EXPR_ARG (exp, 1);
6571 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6572 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6574 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
6576 mode0 = insn_data[icode].operand[1].mode;
6577 mode1 = insn_data[icode].operand[2].mode;
6579 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6580 op0 = copy_to_mode_reg (mode0, op0);
6582 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6583 op1 = copy_to_mode_reg (mode1, op1);
6585 pat = GEN_FCN (icode) (target, op0, op1);
6586 if (!pat)
6587 return NULL_RTX;
6589 emit_insn (pat);
6590 return NULL_RTX;
6592 case ARC_BUILTIN_VDIWR:
6593 case ARC_BUILTIN_VDOWR:
6594 arg0 = CALL_EXPR_ARG (exp, 0);
6595 arg1 = CALL_EXPR_ARG (exp, 1);
6596 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6597 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6599 if (!CONST_INT_P (op0)
6600 || !(UNSIGNED_INT3 (INTVAL (op0))))
6601 error ("operand 1 should be an unsigned 3-bit immediate");
6603 mode1 = insn_data[icode].operand[1].mode;
6605 if (icode == CODE_FOR_vdiwr_insn)
6606 target = gen_rtx_REG (SImode,
6607 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
6608 else if (icode == CODE_FOR_vdowr_insn)
6609 target = gen_rtx_REG (SImode,
6610 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
6611 else
6612 gcc_unreachable ();
6614 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6615 op1 = copy_to_mode_reg (mode1, op1);
6617 pat = GEN_FCN (icode) (target, op1);
6618 if (!pat)
6619 return NULL_RTX;
6621 emit_insn (pat);
6622 return NULL_RTX;
6624 case ARC_BUILTIN_VASRW:
6625 case ARC_BUILTIN_VSR8:
6626 case ARC_BUILTIN_VSR8AW:
6627 arg0 = CALL_EXPR_ARG (exp, 0);
6628 arg1 = CALL_EXPR_ARG (exp, 1);
6629 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6630 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6631 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6633 target = gen_reg_rtx (V8HImode);
6634 mode0 = insn_data[icode].operand[1].mode;
6635 mode1 = insn_data[icode].operand[2].mode;
6637 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6638 op0 = copy_to_mode_reg (mode0, op0);
6640 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6641 || !(UNSIGNED_INT3 (INTVAL (op1))))
6642 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6644 pat = GEN_FCN (icode) (target, op0, op1, op2);
6645 if (!pat)
6646 return NULL_RTX;
6648 emit_insn (pat);
6649 return target;
6651 case ARC_BUILTIN_VLD32WH:
6652 case ARC_BUILTIN_VLD32WL:
6653 case ARC_BUILTIN_VLD64:
6654 case ARC_BUILTIN_VLD32:
6655 rtx src_vreg;
6656 icode = d->icode;
6657 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6658 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6659 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6661 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6662 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6663 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6664 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6666 /* target <- src vreg. */
6667 emit_insn (gen_move_insn (target, src_vreg));
6669 /* target <- vec_concat: target, mem (Ib, u8). */
6670 mode0 = insn_data[icode].operand[3].mode;
6671 mode1 = insn_data[icode].operand[1].mode;
6673 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
6674 || !(UNSIGNED_INT3 (INTVAL (op0))))
6675 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6677 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6678 || !(UNSIGNED_INT8 (INTVAL (op1))))
6679 error ("operand 2 should be an unsigned 8-bit value");
6681 pat = GEN_FCN (icode) (target, op1, op2, op0);
6682 if (!pat)
6683 return NULL_RTX;
6685 emit_insn (pat);
6686 return target;
6688 case ARC_BUILTIN_VLD64W:
6689 case ARC_BUILTIN_VLD128:
6690 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
6691 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6693 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6694 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6695 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6697 /* target <- src vreg. */
6698 target = gen_reg_rtx (V8HImode);
6700 /* target <- vec_concat: target, mem (Ib, u8). */
6701 mode0 = insn_data[icode].operand[1].mode;
6702 mode1 = insn_data[icode].operand[2].mode;
6703 mode2 = insn_data[icode].operand[3].mode;
6705 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6706 || !(UNSIGNED_INT3 (INTVAL (op1))))
6707 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6709 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
6710 || !(UNSIGNED_INT8 (INTVAL (op2))))
6711 error ("operand 2 should be an unsigned 8-bit value");
6713 pat = GEN_FCN (icode) (target, op0, op1, op2);
6715 if (!pat)
6716 return NULL_RTX;
6718 emit_insn (pat);
6719 return target;
6721 case ARC_BUILTIN_VST128:
6722 case ARC_BUILTIN_VST64:
6723 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
6724 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6725 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6727 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6728 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6729 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6730 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6732 mode0 = insn_data[icode].operand[0].mode;
6733 mode1 = insn_data[icode].operand[1].mode;
6734 mode2 = insn_data[icode].operand[2].mode;
6735 mode3 = insn_data[icode].operand[3].mode;
6737 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6738 || !(UNSIGNED_INT3 (INTVAL (op1))))
6739 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6741 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6742 || !(UNSIGNED_INT8 (INTVAL (op2))))
6743 error ("operand 3 should be an unsigned 8-bit value");
6745 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6746 op3 = copy_to_mode_reg (mode3, op3);
6748 pat = GEN_FCN (icode) (op0, op1, op2, op3);
6749 if (!pat)
6750 return NULL_RTX;
6752 emit_insn (pat);
6753 return NULL_RTX;
6755 case ARC_BUILTIN_VST16_N:
6756 case ARC_BUILTIN_VST32_N:
6757 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6758 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
6759 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
6760 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
6762 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
6763 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6764 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6765 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6766 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6768 mode0 = insn_data[icode].operand[0].mode;
6769 mode2 = insn_data[icode].operand[2].mode;
6770 mode3 = insn_data[icode].operand[3].mode;
6771 mode4 = insn_data[icode].operand[4].mode;
6773 /* Do some correctness checks for the operands. */
6774 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
6775 || !(UNSIGNED_INT8 (INTVAL (op0))))
6776 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6778 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6779 || !(UNSIGNED_INT3 (INTVAL (op2))))
6780 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6782 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6783 op3 = copy_to_mode_reg (mode3, op3);
6785 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
6786 || !(UNSIGNED_INT3 (INTVAL (op4))))
6787 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6788 else if (icode == CODE_FOR_vst32_n_insn
6789 && ((INTVAL (op4) % 2) != 0))
6790 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6792 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
6793 if (!pat)
6794 return NULL_RTX;
6796 emit_insn (pat);
6797 return NULL_RTX;
6799 default:
6800 break;
6803 /* 2nd part: Expand regular builtins. */
6804 if (icode == 0)
6805 internal_error ("bad builtin fcode");
6807 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6808 j = 0;
6810 if (nonvoid)
6812 if (target == NULL_RTX
6813 || GET_MODE (target) != tmode
6814 || !insn_data[icode].operand[0].predicate (target, tmode))
6816 target = gen_reg_rtx (tmode);
6818 xop[j++] = target;
6821 gcc_assert (n_args <= 4);
6822 for (i = 0; i < n_args; i++, j++)
6824 tree arg = CALL_EXPR_ARG (exp, i);
6825 machine_mode mode = insn_data[icode].operand[j].mode;
6826 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
6827 machine_mode opmode = GET_MODE (op);
6828 char c = insn_data[icode].operand[j].constraint[0];
6830 /* SIMD extension requires exact immediate operand match. */
6831 if ((id > ARC_BUILTIN_SIMD_BEGIN)
6832 && (id < ARC_BUILTIN_SIMD_END)
6833 && (c != 'v')
6834 && (c != 'r'))
6836 if (!CONST_INT_P (op))
6837 error ("builtin requires an immediate for operand %d", j);
6838 switch (c)
6840 case 'L':
6841 if (!satisfies_constraint_L (op))
6842 error ("operand %d should be a 6 bit unsigned immediate", j);
6843 break;
6844 case 'P':
6845 if (!satisfies_constraint_P (op))
6846 error ("operand %d should be a 8 bit unsigned immediate", j);
6847 break;
6848 case 'K':
6849 if (!satisfies_constraint_K (op))
6850 error ("operand %d should be a 3 bit unsigned immediate", j);
6851 break;
6852 default:
6853 error ("unknown builtin immediate operand type for operand %d",
6858 if (CONST_INT_P (op))
6859 opmode = mode;
6861 if ((opmode == SImode) && (mode == HImode))
6863 opmode = HImode;
6864 op = gen_lowpart (HImode, op);
6867 /* In case the insn wants input operands in modes different from
6868 the result, abort. */
6869 gcc_assert (opmode == mode || opmode == VOIDmode);
6871 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
6872 op = copy_to_mode_reg (mode, op);
6874 xop[j] = op;
6877 pat = apply_GEN_FCN (icode, xop);
6878 if (pat == NULL_RTX)
6879 return NULL_RTX;
6881 emit_insn (pat);
6883 if (nonvoid)
6884 return target;
6885 else
6886 return const0_rtx;
6889 /* Returns true if the operands[opno] is a valid compile-time constant to be
6890 used as register number in the code for builtins. Else it flags an error
6891 and returns false. */
6893 bool
6894 check_if_valid_regno_const (rtx *operands, int opno)
6897 switch (GET_CODE (operands[opno]))
6899 case SYMBOL_REF :
6900 case CONST :
6901 case CONST_INT :
6902 return true;
6903 default:
6904 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6905 break;
6907 return false;
6910 /* Check that after all the constant folding, whether the operand to
6911 __builtin_arc_sleep is an unsigned int of 6 bits. If not, flag an error. */
6913 bool
6914 check_if_valid_sleep_operand (rtx *operands, int opno)
6916 switch (GET_CODE (operands[opno]))
6918 case CONST :
6919 case CONST_INT :
6920 if( UNSIGNED_INT6 (INTVAL (operands[opno])))
6921 return true;
6922 /* FALLTHRU */
6923 default:
6924 fatal_error (input_location,
6925 "operand for sleep instruction must be an unsigned 6 bit compile-time constant");
6926 break;
6928 return false;
6931 /* Return true if it is ok to make a tail-call to DECL. */
6933 static bool
6934 arc_function_ok_for_sibcall (tree decl,
6935 tree exp ATTRIBUTE_UNUSED)
6937 tree attrs = NULL_TREE;
6939 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6940 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
6941 return false;
6943 if (decl)
6945 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
6947 if (lookup_attribute ("jli_always", attrs))
6948 return false;
6949 if (lookup_attribute ("jli_fixed", attrs))
6950 return false;
6951 if (lookup_attribute ("secure_call", attrs))
6952 return false;
6955 /* Everything else is ok. */
6956 return true;
6959 /* Output code to add DELTA to the first argument, and then jump
6960 to FUNCTION. Used for C++ multiple inheritance. */
6962 static void
6963 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
6964 HOST_WIDE_INT delta,
6965 HOST_WIDE_INT vcall_offset,
6966 tree function)
6968 int mi_delta = delta;
6969 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
6970 int shift = 0;
6971 int this_regno
6972 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
6973 rtx fnaddr;
6975 if (mi_delta < 0)
6976 mi_delta = - mi_delta;
6978 /* Add DELTA. When possible use a plain add, otherwise load it into
6979 a register first. */
6981 while (mi_delta != 0)
6983 if ((mi_delta & (3 << shift)) == 0)
6984 shift += 2;
6985 else
6987 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
6988 mi_op, reg_names[this_regno], reg_names[this_regno],
6989 mi_delta & (0xff << shift));
6990 mi_delta &= ~(0xff << shift);
6991 shift += 8;
6995 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
6996 if (vcall_offset != 0)
6998 /* ld r12,[this] --> temp = *this
6999 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7000 ld r12,[r12]
7001 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7002 asm_fprintf (file, "\tld\t%s, [%s]\n",
7003 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
7004 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
7005 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7006 asm_fprintf (file, "\tld\t%s, [%s]\n",
7007 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7008 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7009 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7012 fnaddr = XEXP (DECL_RTL (function), 0);
7014 if (arc_is_longcall_p (fnaddr))
7016 if (flag_pic)
7018 asm_fprintf (file, "\tld\t%s, [pcl, @",
7019 ARC_TEMP_SCRATCH_REG);
7020 assemble_name (file, XSTR (fnaddr, 0));
7021 fputs ("@gotpc]\n", file);
7022 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7024 else
7026 fputs ("\tj\t@", file);
7027 assemble_name (file, XSTR (fnaddr, 0));
7030 else
7032 fputs ("\tb\t@", file);
7033 assemble_name (file, XSTR (fnaddr, 0));
7034 if (flag_pic)
7035 fputs ("@plt\n", file);
7037 fputc ('\n', file);
7040 /* Return true if a 32 bit "long_call" should be generated for
7041 this calling SYM_REF. We generate a long_call if the function:
7043 a. has an __attribute__((long call))
7044 or b. the -mlong-calls command line switch has been specified
7046 However we do not generate a long call if the function has an
7047 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7049 This function will be called by C fragments contained in the machine
7050 description file. */
7052 bool
7053 arc_is_longcall_p (rtx sym_ref)
7055 if (GET_CODE (sym_ref) != SYMBOL_REF)
7056 return false;
7058 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7059 || (TARGET_LONG_CALLS_SET
7060 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7061 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7065 /* Likewise for short calls. */
7067 bool
7068 arc_is_shortcall_p (rtx sym_ref)
7070 if (GET_CODE (sym_ref) != SYMBOL_REF)
7071 return false;
7073 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7074 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7075 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7076 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7080 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7082 static bool
7083 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7085 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7086 return true;
7087 else
7089 HOST_WIDE_INT size = int_size_in_bytes (type);
7090 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
7094 static bool
7095 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
7096 machine_mode mode ATTRIBUTE_UNUSED,
7097 const_tree type,
7098 bool named ATTRIBUTE_UNUSED)
7100 return (type != 0
7101 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
7102 || TREE_ADDRESSABLE (type)));
7105 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7107 static bool
7108 arc_can_use_doloop_p (const widest_int &,
7109 const widest_int &iterations_max,
7110 unsigned int loop_depth, bool entered_at_top)
7112 /* Considering limitations in the hardware, only use doloop
7113 for innermost loops which must be entered from the top. */
7114 if (loop_depth > 1 || !entered_at_top)
7115 return false;
7117 /* Check for lp_count width boundary. */
7118 if (arc_lpcwidth != 32
7119 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7120 || wi::eq_p (iterations_max, 0)))
7121 return false;
7122 return true;
7125 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7126 return why doloop cannot be applied. */
7128 static const char *
7129 arc_invalid_within_doloop (const rtx_insn *insn)
7131 if (CALL_P (insn))
7132 return "Function call in the loop.";
7134 /* FIXME! add here all the ZOL exceptions. */
7135 return NULL;
7138 /* Return true if a load instruction (CONSUMER) uses the same address as a
7139 store instruction (PRODUCER). This function is used to avoid st/ld
7140 address hazard in ARC700 cores. */
7141 bool
7142 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7144 rtx in_set, out_set;
7145 rtx out_addr, in_addr;
7147 if (!producer)
7148 return false;
7150 if (!consumer)
7151 return false;
7153 /* Peel the producer and the consumer for the address. */
7154 out_set = single_set (producer);
7155 if (out_set)
7157 out_addr = SET_DEST (out_set);
7158 if (!out_addr)
7159 return false;
7160 if (GET_CODE (out_addr) == ZERO_EXTEND
7161 || GET_CODE (out_addr) == SIGN_EXTEND)
7162 out_addr = XEXP (out_addr, 0);
7164 if (!MEM_P (out_addr))
7165 return false;
7167 in_set = single_set (consumer);
7168 if (in_set)
7170 in_addr = SET_SRC (in_set);
7171 if (!in_addr)
7172 return false;
7173 if (GET_CODE (in_addr) == ZERO_EXTEND
7174 || GET_CODE (in_addr) == SIGN_EXTEND)
7175 in_addr = XEXP (in_addr, 0);
7177 if (!MEM_P (in_addr))
7178 return false;
7179 /* Get rid of the MEM and check if the addresses are
7180 equivalent. */
7181 in_addr = XEXP (in_addr, 0);
7182 out_addr = XEXP (out_addr, 0);
7184 return exp_equiv_p (in_addr, out_addr, 0, true);
7187 return false;
7190 /* The same functionality as arc_hazard. It is called in machine
7191 reorg before any other optimization. Hence, the NOP size is taken
7192 into account when doing branch shortening. */
7194 static void
7195 workaround_arc_anomaly (void)
7197 rtx_insn *insn, *succ0;
7199 /* For any architecture: call arc_hazard here. */
7200 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7202 succ0 = next_real_insn (insn);
7203 if (arc_hazard (insn, succ0))
7205 emit_insn_before (gen_nopv (), succ0);
7209 if (TARGET_ARC700)
7211 rtx_insn *succ1;
7213 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7215 succ0 = next_real_insn (insn);
7216 if (arc_store_addr_hazard_p (insn, succ0))
7218 emit_insn_after (gen_nopv (), insn);
7219 emit_insn_after (gen_nopv (), insn);
7220 continue;
7223 /* Avoid adding nops if the instruction between the ST and LD is
7224 a call or jump. */
7225 succ1 = next_real_insn (succ0);
7226 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0)
7227 && arc_store_addr_hazard_p (insn, succ1))
7228 emit_insn_after (gen_nopv (), insn);
7233 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7234 turns out not to be optimizable; we have to split the loop_end pattern into
7235 a subtract and a test. */
7237 static void
7238 hwloop_fail (hwloop_info loop)
7240 rtx test;
7241 rtx insn = loop->loop_end;
7243 if (TARGET_DBNZ
7244 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7245 && REG_P (loop->iter_reg))
7247 /* TARGET_V2 core3 has dbnz instructions. */
7248 test = gen_dbnz (loop->iter_reg, loop->start_label);
7249 insn = emit_jump_insn_before (test, loop->loop_end);
7251 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7253 /* We have the lp_count as loop iterator, try to use it. */
7254 emit_insn_before (gen_loop_fail (), loop->loop_end);
7255 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7256 const0_rtx);
7257 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7258 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7259 pc_rtx);
7260 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7261 loop->loop_end);
7263 else
7265 emit_insn_before (gen_addsi3 (loop->iter_reg,
7266 loop->iter_reg,
7267 constm1_rtx),
7268 loop->loop_end);
7269 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7270 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7271 loop->iter_reg,
7272 const0_rtx,
7273 loop->start_label),
7274 loop->loop_end);
7276 JUMP_LABEL (insn) = loop->start_label;
7277 LABEL_NUSES (loop->start_label)++;
7278 delete_insn (loop->loop_end);
7281 /* Optimize LOOP. */
7283 static bool
7284 hwloop_optimize (hwloop_info loop)
7286 int i;
7287 edge entry_edge;
7288 basic_block entry_bb, bb;
7289 rtx iter_reg, end_label;
7290 rtx_insn *insn, *seq, *entry_after, *last_insn;
7291 unsigned int length;
7292 bool need_fix = false;
7293 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7295 if (loop->depth > 1)
7297 if (dump_file)
7298 fprintf (dump_file, ";; loop %d is not innermost\n",
7299 loop->loop_no);
7300 return false;
7303 if (!loop->incoming_dest)
7305 if (dump_file)
7306 fprintf (dump_file, ";; loop %d has more than one entry\n",
7307 loop->loop_no);
7308 return false;
7311 if (loop->incoming_dest != loop->head)
7313 if (dump_file)
7314 fprintf (dump_file, ";; loop %d is not entered from head\n",
7315 loop->loop_no);
7316 return false;
7319 if (loop->has_call || loop->has_asm)
7321 if (dump_file)
7322 fprintf (dump_file, ";; loop %d has invalid insn\n",
7323 loop->loop_no);
7324 return false;
7327 /* Scan all the blocks to make sure they don't use iter_reg. */
7328 if (loop->iter_reg_used || loop->iter_reg_used_outside)
7330 if (dump_file)
7331 fprintf (dump_file, ";; loop %d uses iterator\n",
7332 loop->loop_no);
7333 return false;
7336 /* Check if start_label appears before doloop_end. */
7337 length = 0;
7338 for (insn = loop->start_label;
7339 insn && insn != loop->loop_end;
7340 insn = NEXT_INSN (insn))
7341 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
7343 if (!insn)
7345 if (dump_file)
7346 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
7347 loop->loop_no);
7348 return false;
7351 loop->length = length;
7352 if (loop->length > ARC_MAX_LOOP_LENGTH)
7354 if (dump_file)
7355 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7356 return false;
7358 else if (!loop->length)
7360 if (dump_file)
7361 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
7362 return false;
7365 /* Check if we use a register or not. */
7366 if (!REG_P (loop->iter_reg))
7368 if (dump_file)
7369 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7370 loop->loop_no);
7371 return false;
7374 /* Check if loop register is lpcount. */
7375 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
7377 if (dump_file)
7378 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
7379 " iterator\n",
7380 loop->loop_no);
7381 /* This loop doesn't use the lp_count, check though if we can
7382 fix it. */
7383 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
7384 /* In very unique cases we may have LP_COUNT alive. */
7385 || (loop->incoming_src
7386 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
7387 LP_COUNT)))
7388 return false;
7389 else
7390 need_fix = true;
7393 /* Check for control like instruction as the last instruction of a
7394 ZOL. */
7395 bb = loop->tail;
7396 last_insn = PREV_INSN (loop->loop_end);
7398 while (1)
7400 for (; last_insn != BB_HEAD (bb);
7401 last_insn = PREV_INSN (last_insn))
7402 if (NONDEBUG_INSN_P (last_insn))
7403 break;
7405 if (last_insn != BB_HEAD (bb))
7406 break;
7408 if (single_pred_p (bb)
7409 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
7410 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
7412 bb = single_pred (bb);
7413 last_insn = BB_END (bb);
7414 continue;
7416 else
7418 last_insn = NULL;
7419 break;
7423 if (!last_insn)
7425 if (dump_file)
7426 fprintf (dump_file, ";; loop %d has no last instruction\n",
7427 loop->loop_no);
7428 return false;
7431 if ((TARGET_ARC600_FAMILY || TARGET_HS)
7432 && INSN_P (last_insn)
7433 && (JUMP_P (last_insn) || CALL_P (last_insn)
7434 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
7435 /* At this stage we can have (insn (clobber (mem:BLK
7436 (reg)))) instructions, ignore them. */
7437 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
7438 && (get_attr_type (last_insn) == TYPE_BRCC
7439 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
7441 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
7443 if (dump_file)
7444 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7445 return false;
7447 if (dump_file)
7448 fprintf (dump_file, ";; loop %d has a control like last insn;"
7449 "add a nop\n",
7450 loop->loop_no);
7452 last_insn = emit_insn_after (gen_nopv (), last_insn);
7455 if (LABEL_P (last_insn))
7457 if (dump_file)
7458 fprintf (dump_file, ";; loop %d has a label as last insn;"
7459 "add a nop\n",
7460 loop->loop_no);
7461 last_insn = emit_insn_after (gen_nopv (), last_insn);
7464 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7465 and we can use it to indicate the last ZOL instruction cannot be
7466 part of a delay slot. */
7467 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
7469 loop->last_insn = last_insn;
7471 /* Get the loop iteration register. */
7472 iter_reg = loop->iter_reg;
7474 gcc_assert (REG_P (iter_reg));
7476 entry_edge = NULL;
7478 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
7479 if (entry_edge->flags & EDGE_FALLTHRU)
7480 break;
7482 if (entry_edge == NULL)
7484 if (dump_file)
7485 fprintf (dump_file, ";; loop %d has no fallthru edge jumping"
7486 "into the loop\n",
7487 loop->loop_no);
7488 return false;
7490 /* The loop is good. */
7491 end_label = gen_label_rtx ();
7492 loop->end_label = end_label;
7494 /* Place the zero_cost_loop_start instruction before the loop. */
7495 entry_bb = entry_edge->src;
7497 start_sequence ();
7499 if (need_fix)
7501 /* The loop uses a R-register, but the lp_count is free, thus
7502 use lp_count. */
7503 emit_insn (gen_movsi (lp_reg, iter_reg));
7504 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
7505 iter_reg = lp_reg;
7506 if (dump_file)
7508 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
7509 loop->loop_no);
7513 insn = emit_insn (gen_arc_lp (iter_reg,
7514 loop->start_label,
7515 loop->end_label));
7517 seq = get_insns ();
7518 end_sequence ();
7520 entry_after = BB_END (entry_bb);
7521 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
7522 || !entry_after)
7524 basic_block new_bb;
7525 edge e;
7526 edge_iterator ei;
7528 emit_insn_before (seq, BB_HEAD (loop->head));
7529 seq = emit_label_before (gen_label_rtx (), seq);
7530 new_bb = create_basic_block (seq, insn, entry_bb);
7531 FOR_EACH_EDGE (e, ei, loop->incoming)
7533 if (!(e->flags & EDGE_FALLTHRU))
7534 redirect_edge_and_branch_force (e, new_bb);
7535 else
7536 redirect_edge_succ (e, new_bb);
7539 make_edge (new_bb, loop->head, 0);
7541 else
7543 #if 0
7544 while (DEBUG_INSN_P (entry_after)
7545 || (NOTE_P (entry_after)
7546 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
7547 entry_after = NEXT_INSN (entry_after);
7548 #endif
7549 entry_after = next_nonnote_nondebug_insn_bb (entry_after);
7551 gcc_assert (entry_after);
7552 emit_insn_before (seq, entry_after);
7555 delete_insn (loop->loop_end);
7556 /* Insert the loop end label before the last instruction of the
7557 loop. */
7558 emit_label_after (end_label, loop->last_insn);
7559 /* Make sure we mark the begining and end label as used. */
7560 LABEL_NUSES (loop->end_label)++;
7561 LABEL_NUSES (loop->start_label)++;
7563 return true;
7566 /* A callback for the hw-doloop pass. This function examines INSN; if
7567 it is a loop_end pattern we recognize, return the reg rtx for the
7568 loop counter. Otherwise, return NULL_RTX. */
7570 static rtx
7571 hwloop_pattern_reg (rtx_insn *insn)
7573 rtx reg;
7575 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
7576 return NULL_RTX;
7578 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
7579 if (!REG_P (reg))
7580 return NULL_RTX;
7581 return reg;
7584 static struct hw_doloop_hooks arc_doloop_hooks =
7586 hwloop_pattern_reg,
7587 hwloop_optimize,
7588 hwloop_fail
7591 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
7592 and tries to rewrite the RTL of these loops so that proper Blackfin
7593 hardware loops are generated. */
7595 static void
7596 arc_reorg_loops (void)
7598 reorg_loops (true, &arc_doloop_hooks);
7601 /* Scan all calls and add symbols to be emitted in the jli section if
7602 needed. */
7604 static void
7605 jli_call_scan (void)
7607 rtx_insn *insn;
7609 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7611 if (!CALL_P (insn))
7612 continue;
7614 rtx pat = PATTERN (insn);
7615 if (GET_CODE (pat) == COND_EXEC)
7616 pat = COND_EXEC_CODE (pat);
7617 pat = XVECEXP (pat, 0, 0);
7618 if (GET_CODE (pat) == SET)
7619 pat = SET_SRC (pat);
7621 pat = XEXP (XEXP (pat, 0), 0);
7622 if (GET_CODE (pat) == SYMBOL_REF
7623 && arc_is_jli_call_p (pat))
7624 arc_add_jli_section (pat);
7628 static int arc_reorg_in_progress = 0;
7630 /* ARC's machince specific reorg function. */
7632 static void
7633 arc_reorg (void)
7635 rtx_insn *insn;
7636 rtx pattern;
7637 rtx pc_target;
7638 long offset;
7639 int changed;
7641 cfun->machine->arc_reorg_started = 1;
7642 arc_reorg_in_progress = 1;
7644 compute_bb_for_insn ();
7646 df_analyze ();
7648 /* Doloop optimization. */
7649 arc_reorg_loops ();
7651 workaround_arc_anomaly ();
7652 jli_call_scan ();
7654 /* FIXME: should anticipate ccfsm action, generate special patterns for
7655 to-be-deleted branches that have no delay slot and have at least the
7656 length of the size increase forced on other insns that are conditionalized.
7657 This can also have an insn_list inside that enumerates insns which are
7658 not actually conditionalized because the destinations are dead in the
7659 not-execute case.
7660 Could also tag branches that we want to be unaligned if they get no delay
7661 slot, or even ones that we don't want to do delay slot sheduling for
7662 because we can unalign them.
7664 However, there are cases when conditional execution is only possible after
7665 delay slot scheduling:
7667 - If a delay slot is filled with a nocond/set insn from above, the previous
7668 basic block can become elegible for conditional execution.
7669 - If a delay slot is filled with a nocond insn from the fall-through path,
7670 the branch with that delay slot can become eligble for conditional
7671 execution (however, with the same sort of data flow analysis that dbr
7672 does, we could have figured out before that we don't need to
7673 conditionalize this insn.)
7674 - If a delay slot insn is filled with an insn from the target, the
7675 target label gets its uses decremented (even deleted if falling to zero),
7676 thus possibly creating more condexec opportunities there.
7677 Therefore, we should still be prepared to apply condexec optimization on
7678 non-prepared branches if the size increase of conditionalized insns is no
7679 more than the size saved from eliminating the branch. An invocation option
7680 could also be used to reserve a bit of extra size for condbranches so that
7681 this'll work more often (could also test in arc_reorg if the block is
7682 'close enough' to be eligible for condexec to make this likely, and
7683 estimate required size increase). */
7684 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7685 if (TARGET_NO_BRCC_SET)
7686 return;
7690 init_insn_lengths();
7691 changed = 0;
7693 if (optimize > 1 && !TARGET_NO_COND_EXEC)
7695 arc_ifcvt ();
7696 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
7697 df_finish_pass ((flags & TODO_df_verify) != 0);
7699 if (dump_file)
7701 fprintf (dump_file, ";; After if conversion:\n\n");
7702 print_rtl (dump_file, get_insns ());
7706 /* Call shorten_branches to calculate the insn lengths. */
7707 shorten_branches (get_insns());
7708 cfun->machine->ccfsm_current_insn = NULL_RTX;
7710 if (!INSN_ADDRESSES_SET_P())
7711 fatal_error (input_location, "Insn addresses not set after shorten_branches");
7713 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7715 rtx label;
7716 enum attr_type insn_type;
7718 /* If a non-jump insn (or a casesi jump table), continue. */
7719 if (GET_CODE (insn) != JUMP_INSN ||
7720 GET_CODE (PATTERN (insn)) == ADDR_VEC
7721 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
7722 continue;
7724 /* If we already have a brcc, note if it is suitable for brcc_s.
7725 Be a bit generous with the brcc_s range so that we can take
7726 advantage of any code shortening from delay slot scheduling. */
7727 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
7729 rtx pat = PATTERN (insn);
7730 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
7731 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
7733 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7734 if ((offset >= -140 && offset < 140)
7735 && rtx_equal_p (XEXP (op, 1), const0_rtx)
7736 && compact_register_operand (XEXP (op, 0), VOIDmode)
7737 && equality_comparison_operator (op, VOIDmode))
7738 PUT_MODE (*ccp, CC_Zmode);
7739 else if (GET_MODE (*ccp) == CC_Zmode)
7740 PUT_MODE (*ccp, CC_ZNmode);
7741 continue;
7743 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
7744 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
7745 continue;
7747 /* OK. so we have a jump insn. */
7748 /* We need to check that it is a bcc. */
7749 /* Bcc => set (pc) (if_then_else ) */
7750 pattern = PATTERN (insn);
7751 if (GET_CODE (pattern) != SET
7752 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
7753 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
7754 continue;
7756 /* Now check if the jump is beyond the s9 range. */
7757 if (CROSSING_JUMP_P (insn))
7758 continue;
7759 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7761 if(offset > 253 || offset < -254)
7762 continue;
7764 pc_target = SET_SRC (pattern);
7766 /* Avoid FPU instructions. */
7767 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
7768 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
7769 continue;
7771 /* Now go back and search for the set cc insn. */
7773 label = XEXP (pc_target, 1);
7776 rtx pat;
7777 rtx_insn *scan, *link_insn = NULL;
7779 for (scan = PREV_INSN (insn);
7780 scan && GET_CODE (scan) != CODE_LABEL;
7781 scan = PREV_INSN (scan))
7783 if (! INSN_P (scan))
7784 continue;
7785 pat = PATTERN (scan);
7786 if (GET_CODE (pat) == SET
7787 && cc_register (SET_DEST (pat), VOIDmode))
7789 link_insn = scan;
7790 break;
7793 if (!link_insn)
7794 continue;
7795 else
7796 /* Check if this is a data dependency. */
7798 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
7799 rtx cmp0, cmp1;
7801 /* Ok this is the set cc. copy args here. */
7802 op = XEXP (pc_target, 0);
7804 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
7805 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
7806 if (GET_CODE (op0) == ZERO_EXTRACT
7807 && XEXP (op0, 1) == const1_rtx
7808 && (GET_CODE (op) == EQ
7809 || GET_CODE (op) == NE))
7811 /* btst / b{eq,ne} -> bbit{0,1} */
7812 op0 = XEXP (cmp0, 0);
7813 op1 = XEXP (cmp0, 2);
7815 else if (!register_operand (op0, VOIDmode)
7816 || !general_operand (op1, VOIDmode))
7817 continue;
7818 /* Be careful not to break what cmpsfpx_raw is
7819 trying to create for checking equality of
7820 single-precision floats. */
7821 else if (TARGET_SPFP
7822 && GET_MODE (op0) == SFmode
7823 && GET_MODE (op1) == SFmode)
7824 continue;
7826 /* None of the two cmp operands should be set between the
7827 cmp and the branch. */
7828 if (reg_set_between_p (op0, link_insn, insn))
7829 continue;
7831 if (reg_set_between_p (op1, link_insn, insn))
7832 continue;
7834 /* Since the MODE check does not work, check that this is
7835 CC reg's last set location before insn, and also no
7836 instruction between the cmp and branch uses the
7837 condition codes. */
7838 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
7839 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
7840 continue;
7842 /* CC reg should be dead after insn. */
7843 if (!find_regno_note (insn, REG_DEAD, CC_REG))
7844 continue;
7846 op = gen_rtx_fmt_ee (GET_CODE (op),
7847 GET_MODE (op), cmp0, cmp1);
7848 /* If we create a LIMM where there was none before,
7849 we only benefit if we can avoid a scheduling bubble
7850 for the ARC600. Otherwise, we'd only forgo chances
7851 at short insn generation, and risk out-of-range
7852 branches. */
7853 if (!brcc_nolimm_operator (op, VOIDmode)
7854 && !long_immediate_operand (op1, VOIDmode)
7855 && (TARGET_ARC700
7856 || next_active_insn (link_insn) != insn))
7857 continue;
7859 /* Emit bbit / brcc (or brcc_s if possible).
7860 CC_Zmode indicates that brcc_s is possible. */
7862 if (op0 != cmp0)
7863 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
7864 else if ((offset >= -140 && offset < 140)
7865 && rtx_equal_p (op1, const0_rtx)
7866 && compact_register_operand (op0, VOIDmode)
7867 && (GET_CODE (op) == EQ
7868 || GET_CODE (op) == NE))
7869 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
7870 else
7871 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
7873 brcc_insn
7874 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
7875 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
7876 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
7877 brcc_insn
7878 = gen_rtx_PARALLEL
7879 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
7880 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
7882 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
7883 note = find_reg_note (insn, REG_BR_PROB, 0);
7884 if (note)
7886 XEXP (note, 1) = REG_NOTES (brcc_insn);
7887 REG_NOTES (brcc_insn) = note;
7889 note = find_reg_note (link_insn, REG_DEAD, op0);
7890 if (note)
7892 remove_note (link_insn, note);
7893 XEXP (note, 1) = REG_NOTES (brcc_insn);
7894 REG_NOTES (brcc_insn) = note;
7896 note = find_reg_note (link_insn, REG_DEAD, op1);
7897 if (note)
7899 XEXP (note, 1) = REG_NOTES (brcc_insn);
7900 REG_NOTES (brcc_insn) = note;
7903 changed = 1;
7905 /* Delete the bcc insn. */
7906 set_insn_deleted (insn);
7908 /* Delete the cmp insn. */
7909 set_insn_deleted (link_insn);
7914 /* Clear out insn_addresses. */
7915 INSN_ADDRESSES_FREE ();
7917 } while (changed);
7919 if (INSN_ADDRESSES_SET_P())
7920 fatal_error (input_location, "insn addresses not freed");
7922 arc_reorg_in_progress = 0;
7925 /* Check if the operands are valid for BRcc.d generation
7926 Valid Brcc.d patterns are
7927 Brcc.d b, c, s9
7928 Brcc.d b, u6, s9
7930 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
7931 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
7932 does not have a delay slot
7934 Assumed precondition: Second operand is either a register or a u6 value. */
7936 bool
7937 valid_brcc_with_delay_p (rtx *operands)
7939 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
7940 return false;
7941 return brcc_nolimm_operator (operands[0], VOIDmode);
7944 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
7945 access DECL using %gp_rel(...)($gp). */
7947 static bool
7948 arc_in_small_data_p (const_tree decl)
7950 HOST_WIDE_INT size;
7951 tree attr;
7953 /* Only variables are going into small data area. */
7954 if (TREE_CODE (decl) != VAR_DECL)
7955 return false;
7957 if (TARGET_NO_SDATA_SET)
7958 return false;
7960 /* Disable sdata references to weak variables. */
7961 if (DECL_WEAK (decl))
7962 return false;
7964 /* Don't put constants into the small data section: we want them to
7965 be in ROM rather than RAM. */
7966 if (TREE_READONLY (decl))
7967 return false;
7969 /* To ensure -mvolatile-cache works ld.di does not have a
7970 gp-relative variant. */
7971 if (!TARGET_VOLATILE_CACHE_SET
7972 && TREE_THIS_VOLATILE (decl))
7973 return false;
7975 /* Likewise for uncached data. */
7976 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
7977 if (lookup_attribute ("uncached", attr))
7978 return false;
7980 /* and for aux regs. */
7981 attr = DECL_ATTRIBUTES (decl);
7982 if (lookup_attribute ("aux", attr))
7983 return false;
7985 if (DECL_SECTION_NAME (decl) != 0)
7987 const char *name = DECL_SECTION_NAME (decl);
7988 if (strcmp (name, ".sdata") == 0
7989 || strcmp (name, ".sbss") == 0)
7990 return true;
7992 /* If it's not public, there's no need to put it in the small data
7993 section. */
7994 else if (TREE_PUBLIC (decl))
7996 size = int_size_in_bytes (TREE_TYPE (decl));
7997 return (size > 0 && size <= g_switch_value);
7999 return false;
8002 /* Return true if X is a small data address that can be rewritten
8003 as a gp+symref. */
8005 static bool
8006 arc_rewrite_small_data_p (const_rtx x)
8008 if (GET_CODE (x) == CONST)
8009 x = XEXP (x, 0);
8011 if (GET_CODE (x) == PLUS)
8013 if (GET_CODE (XEXP (x, 1)) == CONST_INT)
8014 x = XEXP (x, 0);
8017 if (GET_CODE (x) == SYMBOL_REF && SYMBOL_REF_SMALL_P (x))
8019 gcc_assert (SYMBOL_REF_TLS_MODEL (x) == 0);
8020 return true;
8022 return false;
8025 /* If possible, rewrite OP so that it refers to small data using
8026 explicit relocations. */
8028 static rtx
8029 arc_rewrite_small_data_1 (rtx op)
8031 rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
8032 op = copy_insn (op);
8033 subrtx_ptr_iterator::array_type array;
8034 FOR_EACH_SUBRTX_PTR (iter, array, &op, ALL)
8036 rtx *loc = *iter;
8037 if (arc_rewrite_small_data_p (*loc))
8039 *loc = gen_rtx_PLUS (Pmode, rgp, *loc);
8040 iter.skip_subrtxes ();
8042 else if (GET_CODE (*loc) == PLUS
8043 && rtx_equal_p (XEXP (*loc, 0), rgp))
8044 iter.skip_subrtxes ();
8046 return op;
8050 arc_rewrite_small_data (rtx op)
8052 op = arc_rewrite_small_data_1 (op);
8054 /* Check if we fit small data constraints. */
8055 if (MEM_P (op)
8056 && !LEGITIMATE_SMALL_DATA_ADDRESS_P (XEXP (op, 0)))
8058 rtx addr = XEXP (op, 0);
8059 rtx tmp = gen_reg_rtx (Pmode);
8060 emit_move_insn (tmp, addr);
8061 op = replace_equiv_address_nv (op, tmp);
8063 return op;
8066 /* Return true if OP refers to small data symbols directly, not through
8067 a PLUS. */
8069 bool
8070 small_data_pattern (rtx op, machine_mode)
8072 if (GET_CODE (op) == SEQUENCE)
8073 return false;
8075 rtx rgp = gen_rtx_REG (Pmode, SDATA_BASE_REGNUM);
8076 subrtx_iterator::array_type array;
8077 FOR_EACH_SUBRTX (iter, array, op, ALL)
8079 const_rtx x = *iter;
8080 if (GET_CODE (x) == PLUS
8081 && rtx_equal_p (XEXP (x, 0), rgp))
8082 iter.skip_subrtxes ();
8083 else if (arc_rewrite_small_data_p (x))
8084 return true;
8086 return false;
8089 /* Return true if OP is an acceptable memory operand for ARCompact
8090 16-bit gp-relative load instructions.
8091 op shd look like : [r26, symref@sda]
8092 i.e. (mem (plus (reg 26) (symref with smalldata flag set))
8094 /* volatile cache option still to be handled. */
8096 bool
8097 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
8099 rtx addr;
8100 int size;
8101 tree decl = NULL_TREE;
8102 int align = 0;
8103 int mask = 0;
8105 /* Eliminate non-memory operations. */
8106 if (GET_CODE (op) != MEM)
8107 return false;
8109 if (mode == VOIDmode)
8110 mode = GET_MODE (op);
8112 size = GET_MODE_SIZE (mode);
8114 /* dword operations really put out 2 instructions, so eliminate them. */
8115 if (size > UNITS_PER_WORD)
8116 return false;
8118 /* Decode the address now. */
8119 addr = XEXP (op, 0);
8121 if (!LEGITIMATE_SMALL_DATA_ADDRESS_P (addr))
8122 return false;
8124 if (!short_p || size == 1)
8125 return true;
8127 /* Now check for the alignment, the short loads using gp require the
8128 addresses to be aligned. */
8129 if (GET_CODE (XEXP (addr, 1)) == SYMBOL_REF)
8130 decl = SYMBOL_REF_DECL (XEXP (addr, 1));
8131 else if (GET_CODE (XEXP (XEXP (XEXP (addr, 1), 0), 0)) == SYMBOL_REF)
8132 decl = SYMBOL_REF_DECL (XEXP (XEXP (XEXP (addr, 1), 0), 0));
8133 if (decl)
8134 align = DECL_ALIGN (decl);
8135 align = align / BITS_PER_UNIT;
8137 switch (mode)
8139 case E_HImode:
8140 mask = 1;
8141 break;
8142 default:
8143 mask = 3;
8144 break;
8147 if (align && ((align & mask) == 0))
8148 return true;
8149 return false;
8152 /* Return TRUE if PAT is accessing an aux-reg. */
8154 static bool
8155 arc_is_aux_reg_p (rtx pat)
8157 tree attrs = NULL_TREE;
8158 tree addr;
8160 if (!MEM_P (pat))
8161 return false;
8163 /* Get the memory attributes. */
8164 addr = MEM_EXPR (pat);
8165 if (!addr)
8166 return false;
8168 /* Get the attributes. */
8169 if (TREE_CODE (addr) == VAR_DECL)
8170 attrs = DECL_ATTRIBUTES (addr);
8171 else if (TREE_CODE (addr) == MEM_REF)
8172 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8173 else
8174 return false;
8176 if (lookup_attribute ("aux", attrs))
8177 return true;
8178 return false;
8181 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8183 void
8184 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8185 unsigned HOST_WIDE_INT size,
8186 unsigned HOST_WIDE_INT align,
8187 unsigned HOST_WIDE_INT globalize_p)
8189 int in_small_data = arc_in_small_data_p (decl);
8190 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8192 /* Don't output aux-reg symbols. */
8193 if (mem != NULL_RTX && MEM_P (mem)
8194 && SYMBOL_REF_P (XEXP (mem, 0))
8195 && arc_is_aux_reg_p (mem))
8196 return;
8198 if (in_small_data)
8199 switch_to_section (get_named_section (NULL, ".sbss", 0));
8200 /* named_section (0,".sbss",0); */
8201 else
8202 switch_to_section (bss_section);
8204 if (globalize_p)
8205 (*targetm.asm_out.globalize_label) (stream, name);
8207 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8208 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8209 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8210 ASM_OUTPUT_LABEL (stream, name);
8212 if (size != 0)
8213 ASM_OUTPUT_SKIP (stream, size);
8216 static bool
8217 arc_preserve_reload_p (rtx in)
8219 return (GET_CODE (in) == PLUS
8220 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8221 && CONST_INT_P (XEXP (in, 1))
8222 && !((INTVAL (XEXP (in, 1)) & 511)));
8226 arc_register_move_cost (machine_mode,
8227 enum reg_class from_class, enum reg_class to_class)
8229 /* The ARC600 has no bypass for extension registers, hence a nop might be
8230 needed to be inserted after a write so that reads are safe. */
8231 if (TARGET_ARC600)
8233 if (to_class == MPY_WRITABLE_CORE_REGS)
8234 return 3;
8235 /* Instructions modifying LP_COUNT need 4 additional cycles before
8236 the register will actually contain the value. */
8237 else if (to_class == LPCOUNT_REG)
8238 return 6;
8239 else if (to_class == WRITABLE_CORE_REGS)
8240 return 6;
8243 /* Using lp_count as scratch reg is a VERY bad idea. */
8244 if (from_class == LPCOUNT_REG)
8245 return 1000;
8246 if (to_class == LPCOUNT_REG)
8247 return 6;
8249 /* Force an attempt to 'mov Dy,Dx' to spill. */
8250 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
8251 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8252 return 100;
8254 return 2;
8257 /* Emit code for an addsi3 instruction with OPERANDS.
8258 COND_P indicates if this will use conditional execution.
8259 Return the length of the instruction.
8260 If OUTPUT_P is false, don't actually output the instruction, just return
8261 its length. */
8263 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8265 char format[35];
8267 int match = operands_match_p (operands[0], operands[1]);
8268 int match2 = operands_match_p (operands[0], operands[2]);
8269 int intval = (REG_P (operands[2]) ? 1
8270 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8271 int neg_intval = -intval;
8272 int short_0 = satisfies_constraint_Rcq (operands[0]);
8273 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
8274 int ret = 0;
8276 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8277 && REGNO (OP) != 30) \
8278 || !TARGET_V2))
8280 #define ADDSI_OUTPUT1(FORMAT) do {\
8281 if (output_p) \
8282 output_asm_insn (FORMAT, operands);\
8283 return ret; \
8284 } while (0)
8285 #define ADDSI_OUTPUT(LIST) do {\
8286 if (output_p) \
8287 sprintf LIST;\
8288 ADDSI_OUTPUT1 (format);\
8289 return ret; \
8290 } while (0)
8292 /* First try to emit a 16 bit insn. */
8293 ret = 2;
8294 if (!cond_p
8295 /* If we are actually about to output this insn, don't try a 16 bit
8296 variant if we already decided that we don't want that
8297 (I.e. we upsized this insn to align some following insn.)
8298 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8299 but add1 r0,sp,35 doesn't. */
8300 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8302 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8303 patterns. */
8304 if (short_p
8305 && ((REG_H_P (operands[2])
8306 && (match || satisfies_constraint_Rcq (operands[2])))
8307 || (CONST_INT_P (operands[2])
8308 && ((unsigned) intval <= (match ? 127 : 7)))))
8309 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8311 /* Generate add_s b,b,h patterns. */
8312 if (short_0 && match2 && REG_H_P (operands[1]))
8313 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8315 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8316 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8317 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8318 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8320 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8321 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8322 && match && !(neg_intval & ~124)))
8323 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8325 /* Generate add_s h,h,s3 patterns. */
8326 if (REG_H_P (operands[0]) && match && TARGET_V2
8327 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8328 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8330 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8331 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8332 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8333 && satisfies_constraint_Rcq (operands[1])
8334 && satisfies_constraint_L (operands[2]))
8335 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8338 /* Now try to emit a 32 bit insn without long immediate. */
8339 ret = 4;
8340 if (!match && match2 && REG_P (operands[1]))
8341 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8342 if (match || !cond_p)
8344 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8345 int range_factor = neg_intval & intval;
8346 int shift;
8348 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8349 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8351 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8352 same size, do, so - the insn latency is lower. */
8353 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8354 0x800 is not. */
8355 if ((intval >= 0 && intval <= limit)
8356 || (intval == -0x800 && limit == 0x7ff))
8357 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8358 else if ((intval < 0 && neg_intval <= limit)
8359 || (intval == 0x800 && limit == 0x7ff))
8360 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8361 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
8362 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
8363 gcc_assert ((((1 << shift) - 1) & intval) == 0);
8364 if (((intval < 0 && intval != -0x4000)
8365 /* sub[123] is slower than add_s / sub, only use it if it
8366 avoids a long immediate. */
8367 && neg_intval <= limit << shift)
8368 || (intval == 0x4000 && limit == 0x7ff))
8369 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
8370 shift, neg_intval >> shift));
8371 else if ((intval >= 0 && intval <= limit << shift)
8372 || (intval == -0x4000 && limit == 0x7ff))
8373 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
8375 /* Try to emit a 16 bit opcode with long immediate. */
8376 ret = 6;
8377 if (short_p && match)
8378 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8380 /* We have to use a 32 bit opcode, and with a long immediate. */
8381 ret = 8;
8382 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8385 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8386 Return the length of the instruction.
8387 If OUTPUT_P is false, don't actually output the instruction, just return
8388 its length. */
8390 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
8392 enum rtx_code commutative_op = GET_CODE (operands[3]);
8393 const char *pat = NULL;
8395 /* Canonical rtl should not have a constant in the first operand position. */
8396 gcc_assert (!CONSTANT_P (operands[1]));
8398 switch (commutative_op)
8400 case AND:
8401 if (satisfies_constraint_C1p (operands[2]))
8402 pat = "bmsk%? %0,%1,%Z2";
8403 else if (satisfies_constraint_C2p (operands[2]))
8405 operands[2] = GEN_INT ((~INTVAL (operands[2])));
8406 pat = "bmskn%? %0,%1,%Z2";
8408 else if (satisfies_constraint_Ccp (operands[2]))
8409 pat = "bclr%? %0,%1,%M2";
8410 else if (satisfies_constraint_CnL (operands[2]))
8411 pat = "bic%? %0,%1,%n2-1";
8412 break;
8413 case IOR:
8414 if (satisfies_constraint_C0p (operands[2]))
8415 pat = "bset%? %0,%1,%z2";
8416 break;
8417 case XOR:
8418 if (satisfies_constraint_C0p (operands[2]))
8419 pat = "bxor%? %0,%1,%z2";
8420 break;
8421 case PLUS:
8422 return arc_output_addsi (operands, true, output_p);
8423 default: break;
8425 if (output_p)
8426 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
8427 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
8428 return 4;
8429 return 8;
8432 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8433 Emit code and return an potentially modified address such that offsets
8434 up to SIZE are can be added to yield a legitimate address.
8435 if REUSE is set, ADDR is a register that may be modified. */
8437 static rtx
8438 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
8440 rtx base = addr;
8441 rtx offs = const0_rtx;
8443 if (GET_CODE (base) == PLUS)
8445 offs = XEXP (base, 1);
8446 base = XEXP (base, 0);
8448 if (!REG_P (base)
8449 || (REGNO (base) != STACK_POINTER_REGNUM
8450 && REGNO_PTR_FRAME_P (REGNO (base)))
8451 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
8452 || !SMALL_INT (INTVAL (offs) + size))
8454 if (reuse)
8455 emit_insn (gen_add2_insn (addr, offs));
8456 else
8457 addr = copy_to_mode_reg (Pmode, addr);
8459 return addr;
8462 /* Like move_by_pieces, but take account of load latency, and actual
8463 offset ranges. Return true on success. */
8465 bool
8466 arc_expand_movmem (rtx *operands)
8468 rtx dst = operands[0];
8469 rtx src = operands[1];
8470 rtx dst_addr, src_addr;
8471 HOST_WIDE_INT size;
8472 int align = INTVAL (operands[3]);
8473 unsigned n_pieces;
8474 int piece = align;
8475 rtx store[2];
8476 rtx tmpx[2];
8477 int i;
8479 if (!CONST_INT_P (operands[2]))
8480 return false;
8481 size = INTVAL (operands[2]);
8482 /* move_by_pieces_ninsns is static, so we can't use it. */
8483 if (align >= 4)
8485 if (TARGET_LL64)
8486 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
8487 else
8488 n_pieces = (size + 2) / 4U + (size & 1);
8490 else if (align == 2)
8491 n_pieces = (size + 1) / 2U;
8492 else
8493 n_pieces = size;
8494 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
8495 return false;
8496 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8497 possible. */
8498 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
8499 piece = 8;
8500 else if (piece > 4)
8501 piece = 4;
8502 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
8503 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
8504 store[0] = store[1] = NULL_RTX;
8505 tmpx[0] = tmpx[1] = NULL_RTX;
8506 for (i = 0; size > 0; i ^= 1, size -= piece)
8508 rtx tmp;
8509 machine_mode mode;
8511 while (piece > size)
8512 piece >>= 1;
8513 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
8514 /* If we don't re-use temporaries, the scheduler gets carried away,
8515 and the register pressure gets unnecessarily high. */
8516 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
8517 tmp = tmpx[i];
8518 else
8519 tmpx[i] = tmp = gen_reg_rtx (mode);
8520 dst_addr = force_offsettable (dst_addr, piece, 1);
8521 src_addr = force_offsettable (src_addr, piece, 1);
8522 if (store[i])
8523 emit_insn (store[i]);
8524 emit_move_insn (tmp, change_address (src, mode, src_addr));
8525 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
8526 dst_addr = plus_constant (Pmode, dst_addr, piece);
8527 src_addr = plus_constant (Pmode, src_addr, piece);
8529 if (store[i])
8530 emit_insn (store[i]);
8531 if (store[i^1])
8532 emit_insn (store[i^1]);
8533 return true;
8536 static bool
8537 arc_get_aux_arg (rtx pat, int *auxr)
8539 tree attr, addr = MEM_EXPR (pat);
8540 if (TREE_CODE (addr) != VAR_DECL)
8541 return false;
8543 attr = DECL_ATTRIBUTES (addr);
8544 if (lookup_attribute ("aux", attr))
8546 tree arg = TREE_VALUE (attr);
8547 if (arg)
8549 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
8550 return true;
8554 return false;
8557 /* Prepare operands for move in MODE. Return true iff the move has
8558 been emitted. */
8560 bool
8561 prepare_move_operands (rtx *operands, machine_mode mode)
8563 /* First handle aux attribute. */
8564 if (mode == SImode
8565 && (MEM_P (operands[0]) || MEM_P (operands[1])))
8567 rtx tmp;
8568 int auxr = 0;
8569 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
8571 /* Save operation. */
8572 if (arc_get_aux_arg (operands[0], &auxr))
8574 tmp = gen_reg_rtx (SImode);
8575 emit_move_insn (tmp, GEN_INT (auxr));
8577 else
8579 tmp = XEXP (operands[0], 0);
8582 operands[1] = force_reg (SImode, operands[1]);
8583 emit_insn (gen_rtx_UNSPEC_VOLATILE
8584 (VOIDmode, gen_rtvec (2, operands[1], tmp),
8585 VUNSPEC_ARC_SR));
8586 return true;
8588 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
8590 if (arc_get_aux_arg (operands[1], &auxr))
8592 tmp = gen_reg_rtx (SImode);
8593 emit_move_insn (tmp, GEN_INT (auxr));
8595 else
8597 tmp = XEXP (operands[1], 0);
8598 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
8600 /* Load operation. */
8601 gcc_assert (REG_P (operands[0]));
8602 emit_insn (gen_rtx_SET (operands[0],
8603 gen_rtx_UNSPEC_VOLATILE
8604 (SImode, gen_rtvec (1, tmp),
8605 VUNSPEC_ARC_LR)));
8606 return true;
8610 /* We used to do this only for MODE_INT Modes, but addresses to floating
8611 point variables may well be in the small data section. */
8612 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[0], Pmode))
8613 operands[0] = arc_rewrite_small_data (operands[0]);
8615 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
8617 prepare_pic_move (operands, SImode);
8619 /* Disable any REG_EQUALs associated with the symref
8620 otherwise the optimization pass undoes the work done
8621 here and references the variable directly. */
8624 if (GET_CODE (operands[0]) != MEM
8625 && !TARGET_NO_SDATA_SET
8626 && small_data_pattern (operands[1], Pmode))
8628 /* This is to take care of address calculations involving sdata
8629 variables. */
8630 operands[1] = arc_rewrite_small_data (operands[1]);
8632 emit_insn (gen_rtx_SET (operands[0],operands[1]));
8633 /* ??? This note is useless, since it only restates the set itself.
8634 We should rather use the original SYMBOL_REF. However, there is
8635 the problem that we are lying to the compiler about these
8636 SYMBOL_REFs to start with. symbol@sda should be encoded specially
8637 so that we can tell it apart from an actual symbol. */
8638 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
8640 /* Take care of the REG_EQUAL note that will be attached to mark the
8641 output reg equal to the initial symbol_ref after this code is
8642 executed. */
8643 emit_move_insn (operands[0], operands[0]);
8644 return true;
8647 if (MEM_P (operands[0])
8648 && !(reload_in_progress || reload_completed))
8650 operands[1] = force_reg (mode, operands[1]);
8651 if (!move_dest_operand (operands[0], mode))
8653 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8654 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8655 except that we can't use that function because it is static. */
8656 rtx pat = change_address (operands[0], mode, addr);
8657 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8658 operands[0] = pat;
8660 if (!cse_not_expected)
8662 rtx pat = XEXP (operands[0], 0);
8664 pat = arc_legitimize_address_0 (pat, pat, mode);
8665 if (pat)
8667 pat = change_address (operands[0], mode, pat);
8668 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8669 operands[0] = pat;
8674 if (MEM_P (operands[1]) && !cse_not_expected)
8676 rtx pat = XEXP (operands[1], 0);
8678 pat = arc_legitimize_address_0 (pat, pat, mode);
8679 if (pat)
8681 pat = change_address (operands[1], mode, pat);
8682 MEM_COPY_ATTRIBUTES (pat, operands[1]);
8683 operands[1] = pat;
8687 return false;
8690 /* Prepare OPERANDS for an extension using CODE to OMODE.
8691 Return true iff the move has been emitted. */
8693 bool
8694 prepare_extend_operands (rtx *operands, enum rtx_code code,
8695 machine_mode omode)
8697 if (!TARGET_NO_SDATA_SET && small_data_pattern (operands[1], Pmode))
8699 /* This is to take care of address calculations involving sdata
8700 variables. */
8701 operands[1]
8702 = gen_rtx_fmt_e (code, omode, arc_rewrite_small_data (operands[1]));
8703 emit_insn (gen_rtx_SET (operands[0], operands[1]));
8704 set_unique_reg_note (get_last_insn (), REG_EQUAL, operands[1]);
8706 /* Take care of the REG_EQUAL note that will be attached to mark the
8707 output reg equal to the initial extension after this code is
8708 executed. */
8709 emit_move_insn (operands[0], operands[0]);
8710 return true;
8712 return false;
8715 /* Output a library call to a function called FNAME that has been arranged
8716 to be local to any dso. */
8718 const char *
8719 arc_output_libcall (const char *fname)
8721 unsigned len = strlen (fname);
8722 static char buf[64];
8724 gcc_assert (len < sizeof buf - 35);
8725 if (TARGET_LONG_CALLS_SET
8726 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
8728 if (flag_pic)
8729 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
8730 else
8731 sprintf (buf, "jl%%! @%s", fname);
8733 else
8734 sprintf (buf, "bl%%!%%* @%s", fname);
8735 return buf;
8738 /* Return the SImode highpart of the DImode value IN. */
8741 disi_highpart (rtx in)
8743 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
8746 /* Return length adjustment for INSN.
8747 For ARC600:
8748 A write to a core reg greater or equal to 32 must not be immediately
8749 followed by a use. Anticipate the length requirement to insert a nop
8750 between PRED and SUCC to prevent a hazard. */
8752 static int
8753 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
8755 if (!TARGET_ARC600)
8756 return 0;
8757 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
8758 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
8759 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
8760 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
8761 if (recog_memoized (pred) == CODE_FOR_mulsi_600
8762 || recog_memoized (pred) == CODE_FOR_umul_600
8763 || recog_memoized (pred) == CODE_FOR_mac_600
8764 || recog_memoized (pred) == CODE_FOR_mul64_600
8765 || recog_memoized (pred) == CODE_FOR_mac64_600
8766 || recog_memoized (pred) == CODE_FOR_umul64_600
8767 || recog_memoized (pred) == CODE_FOR_umac64_600)
8768 return 0;
8769 subrtx_iterator::array_type array;
8770 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
8772 const_rtx x = *iter;
8773 switch (GET_CODE (x))
8775 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8776 break;
8777 default:
8778 /* This is also fine for PRE/POST_MODIFY, because they
8779 contain a SET. */
8780 continue;
8782 rtx dest = XEXP (x, 0);
8783 /* Check if this sets a an extension register. N.B. we use 61 for the
8784 condition codes, which is definitely not an extension register. */
8785 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
8786 /* Check if the same register is used by the PAT. */
8787 && (refers_to_regno_p
8788 (REGNO (dest),
8789 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
8790 PATTERN (succ), 0)))
8791 return 4;
8793 return 0;
8796 /* Given a rtx, check if it is an assembly instruction or not. */
8798 static int
8799 arc_asm_insn_p (rtx x)
8801 int i, j;
8803 if (x == 0)
8804 return 0;
8806 switch (GET_CODE (x))
8808 case ASM_OPERANDS:
8809 case ASM_INPUT:
8810 return 1;
8812 case SET:
8813 return arc_asm_insn_p (SET_SRC (x));
8815 case PARALLEL:
8816 j = 0;
8817 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8818 j += arc_asm_insn_p (XVECEXP (x, 0, i));
8819 if ( j > 0)
8820 return 1;
8821 break;
8823 default:
8824 break;
8827 return 0;
8830 /* For ARC600:
8831 A write to a core reg greater or equal to 32 must not be immediately
8832 followed by a use. Anticipate the length requirement to insert a nop
8833 between PRED and SUCC to prevent a hazard. */
8836 arc_hazard (rtx_insn *pred, rtx_insn *succ)
8838 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
8839 return 0;
8841 if (TARGET_ARC600)
8842 return arc600_corereg_hazard (pred, succ);
8844 return 0;
8847 /* Return length adjustment for INSN. */
8850 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
8852 if (!INSN_P (insn))
8853 return len;
8854 /* We already handle sequences by ignoring the delay sequence flag. */
8855 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
8856 return len;
8858 /* Check for return with but one preceding insn since function
8859 start / call. */
8860 if (TARGET_PAD_RETURN
8861 && JUMP_P (insn)
8862 && GET_CODE (PATTERN (insn)) != ADDR_VEC
8863 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
8864 && get_attr_type (insn) == TYPE_RETURN)
8866 rtx_insn *prev = prev_active_insn (insn);
8868 if (!prev || !(prev = prev_active_insn (prev))
8869 || ((NONJUMP_INSN_P (prev)
8870 && GET_CODE (PATTERN (prev)) == SEQUENCE)
8871 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8872 NON_SIBCALL)
8873 : CALL_ATTR (prev, NON_SIBCALL)))
8874 return len + 4;
8876 if (TARGET_ARC600)
8878 rtx_insn *succ = next_real_insn (insn);
8880 /* One the ARC600, a write to an extension register must be separated
8881 from a read. */
8882 if (succ && INSN_P (succ))
8883 len += arc600_corereg_hazard (insn, succ);
8886 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8887 can go awry. */
8888 extract_constrain_insn_cached (insn);
8890 return len;
8893 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8894 CC field of *STATEP. */
8896 static rtx
8897 arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8899 rtx cond = statep->cond;
8900 int raw_cc = get_arc_condition_code (cond);
8901 if (reverse)
8902 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8904 if (statep->cc == raw_cc)
8905 return copy_rtx (cond);
8907 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8909 machine_mode ccm = GET_MODE (XEXP (cond, 0));
8910 enum rtx_code code = reverse_condition (GET_CODE (cond));
8911 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8912 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8914 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8915 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8918 /* Return version of PAT conditionalized with COND, which is part of INSN.
8919 ANNULLED indicates if INSN is an annulled delay-slot insn.
8920 Register further changes if necessary. */
8921 static rtx
8922 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8924 /* For commutative operators, we generally prefer to have
8925 the first source match the destination. */
8926 if (GET_CODE (pat) == SET)
8928 rtx src = SET_SRC (pat);
8930 if (COMMUTATIVE_P (src))
8932 rtx src0 = XEXP (src, 0);
8933 rtx src1 = XEXP (src, 1);
8934 rtx dst = SET_DEST (pat);
8936 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8937 /* Leave add_n alone - the canonical form is to
8938 have the complex summand first. */
8939 && REG_P (src0))
8940 pat = gen_rtx_SET (dst,
8941 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8942 src1, src0));
8946 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8947 what to do with COND_EXEC. */
8948 if (RTX_FRAME_RELATED_P (insn))
8950 /* If this is the delay slot insn of an anulled branch,
8951 dwarf2out.c:scan_trace understands the anulling semantics
8952 without the COND_EXEC. */
8953 gcc_assert (annulled);
8954 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8955 REG_NOTES (insn));
8956 validate_change (insn, &REG_NOTES (insn), note, 1);
8958 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8959 return pat;
8962 /* Use the ccfsm machinery to do if conversion. */
8964 static unsigned
8965 arc_ifcvt (void)
8967 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8969 memset (statep, 0, sizeof *statep);
8970 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
8972 arc_ccfsm_advance (insn, statep);
8974 switch (statep->state)
8976 case 0:
8977 break;
8978 case 1: case 2:
8980 /* Deleted branch. */
8981 arc_ccfsm_post_advance (insn, statep);
8982 gcc_assert (!IN_RANGE (statep->state, 1, 2));
8983 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
8984 if (GET_CODE (PATTERN (seq)) == SEQUENCE)
8986 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8987 rtx pat = PATTERN (slot);
8988 if (INSN_ANNULLED_BRANCH_P (insn))
8990 rtx cond
8991 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8992 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8994 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8995 gcc_unreachable ();
8996 PUT_CODE (slot, NOTE);
8997 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8999 else
9001 set_insn_deleted (insn);
9003 continue;
9005 case 3:
9006 if (LABEL_P (insn)
9007 && statep->target_label == CODE_LABEL_NUMBER (insn))
9009 arc_ccfsm_post_advance (insn, statep);
9010 if (--LABEL_NUSES (insn) == 0)
9011 delete_insn (insn);
9012 continue;
9014 /* Fall through. */
9015 case 4: case 5:
9016 if (!NONDEBUG_INSN_P (insn))
9017 break;
9019 /* Conditionalized insn. */
9021 rtx_insn *prev, *pprev;
9022 rtx *patp, pat, cond;
9023 bool annulled; annulled = false;
9025 /* If this is a delay slot insn in a non-annulled branch,
9026 don't conditionalize it. N.B., this should be fine for
9027 conditional return too. However, don't do this for
9028 unconditional branches, as these would be encountered when
9029 processing an 'else' part. */
9030 prev = PREV_INSN (insn);
9031 pprev = PREV_INSN (prev);
9032 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
9033 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
9035 if (!INSN_ANNULLED_BRANCH_P (prev))
9036 break;
9037 annulled = true;
9040 patp = &PATTERN (insn);
9041 pat = *patp;
9042 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
9043 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
9045 /* ??? don't conditionalize if all side effects are dead
9046 in the not-execute case. */
9048 pat = conditionalize_nonjump (pat, cond, insn, annulled);
9050 else if (simplejump_p (insn))
9052 patp = &SET_SRC (pat);
9053 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
9055 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
9057 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
9058 pat = gen_rtx_SET (pc_rtx, pat);
9060 else
9061 gcc_unreachable ();
9062 validate_change (insn, patp, pat, 1);
9063 if (!apply_change_group ())
9064 gcc_unreachable ();
9065 if (JUMP_P (insn))
9067 rtx_insn *next = next_nonnote_insn (insn);
9068 if (GET_CODE (next) == BARRIER)
9069 delete_insn (next);
9070 if (statep->state == 3)
9071 continue;
9073 break;
9074 default:
9075 gcc_unreachable ();
9077 arc_ccfsm_post_advance (insn, statep);
9079 return 0;
9082 /* Find annulled delay insns and convert them to use the appropriate predicate.
9083 This allows branch shortening to size up these insns properly. */
9085 static unsigned
9086 arc_predicate_delay_insns (void)
9088 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9090 rtx pat, jump, dlay, src, cond, *patp;
9091 int reverse;
9093 if (!NONJUMP_INSN_P (insn)
9094 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9095 continue;
9096 jump = XVECEXP (pat, 0, 0);
9097 dlay = XVECEXP (pat, 0, 1);
9098 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9099 continue;
9100 /* If the branch insn does the annulling, leave the delay insn alone. */
9101 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9102 continue;
9103 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9104 on the other path. */
9105 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9106 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9107 src = SET_SRC (PATTERN (jump));
9108 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9109 cond = XEXP (src, 0);
9110 if (XEXP (src, 2) == pc_rtx)
9111 reverse = 0;
9112 else if (XEXP (src, 1) == pc_rtx)
9113 reverse = 1;
9114 else
9115 gcc_unreachable ();
9116 if (reverse != !INSN_FROM_TARGET_P (dlay))
9118 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9119 enum rtx_code code = reverse_condition (GET_CODE (cond));
9120 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9121 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9123 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9124 copy_rtx (XEXP (cond, 0)),
9125 copy_rtx (XEXP (cond, 1)));
9127 else
9128 cond = copy_rtx (cond);
9129 patp = &PATTERN (dlay);
9130 pat = *patp;
9131 pat = conditionalize_nonjump (pat, cond, dlay, true);
9132 validate_change (dlay, patp, pat, 1);
9133 if (!apply_change_group ())
9134 gcc_unreachable ();
9136 return 0;
9139 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9140 (other than of a forward brcc), it creates a hazard when there is a read
9141 of the same register at the branch target. We can't know what is at the
9142 branch target of calls, and for branches, we don't really know before the
9143 end of delay slot scheduling, either. Not only can individual instruction
9144 be hoisted out into a delay slot, a basic block can also be emptied this
9145 way, and branch and/or fall through targets be redirected. Hence we don't
9146 want such writes in a delay slot. */
9148 /* Return nonzreo iff INSN writes to an extension core register. */
9151 arc_write_ext_corereg (rtx insn)
9153 subrtx_iterator::array_type array;
9154 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9156 const_rtx x = *iter;
9157 switch (GET_CODE (x))
9159 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9160 break;
9161 default:
9162 /* This is also fine for PRE/POST_MODIFY, because they
9163 contain a SET. */
9164 continue;
9166 const_rtx dest = XEXP (x, 0);
9167 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9168 return 1;
9170 return 0;
9173 /* This is like the hook, but returns NULL when it can't / won't generate
9174 a legitimate address. */
9176 static rtx
9177 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9178 machine_mode mode)
9180 rtx addr, inner;
9182 if (flag_pic && SYMBOLIC_CONST (x))
9183 (x) = arc_legitimize_pic_address (x, 0);
9184 addr = x;
9185 if (GET_CODE (addr) == CONST)
9186 addr = XEXP (addr, 0);
9187 if (GET_CODE (addr) == PLUS
9188 && CONST_INT_P (XEXP (addr, 1))
9189 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9190 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9191 || (REG_P (XEXP (addr, 0))
9192 && (INTVAL (XEXP (addr, 1)) & 252))))
9194 HOST_WIDE_INT offs, upper;
9195 int size = GET_MODE_SIZE (mode);
9197 offs = INTVAL (XEXP (addr, 1));
9198 upper = (offs + 256 * size) & ~511 * size;
9199 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9200 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9201 if (GET_CODE (x) == CONST)
9202 inner = gen_rtx_CONST (Pmode, inner);
9203 #endif
9204 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9205 x = addr;
9207 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9208 x = force_reg (Pmode, x);
9209 if (memory_address_p ((machine_mode) mode, x))
9210 return x;
9211 return NULL_RTX;
9214 static rtx
9215 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9217 if (GET_CODE (orig_x) == SYMBOL_REF)
9219 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
9220 if (model != 0)
9221 return arc_legitimize_tls_address (orig_x, model);
9224 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9226 if (new_x)
9227 return new_x;
9228 return orig_x;
9231 static rtx
9232 arc_delegitimize_address_0 (rtx op)
9234 switch (GET_CODE (op))
9236 case CONST:
9237 return arc_delegitimize_address_0 (XEXP (op, 0));
9239 case UNSPEC:
9240 switch (XINT (op, 1))
9242 case ARC_UNSPEC_GOT:
9243 case ARC_UNSPEC_GOTOFFPC:
9244 return XVECEXP (op, 0, 0);
9245 default:
9246 break;
9248 break;
9250 case PLUS:
9252 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9253 rtx t2 = XEXP (op, 1);
9255 if (t1 && t2)
9256 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9257 break;
9260 default:
9261 break;
9263 return NULL_RTX;
9266 static rtx
9267 arc_delegitimize_address (rtx orig_x)
9269 rtx x = orig_x;
9271 if (MEM_P (x))
9272 x = XEXP (x, 0);
9274 x = arc_delegitimize_address_0 (x);
9275 if (!x)
9276 return orig_x;
9278 if (MEM_P (orig_x))
9279 x = replace_equiv_address_nv (orig_x, x);
9280 return x;
9283 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9284 differ from the hardware register number in order to allow the generic
9285 code to correctly split the concatenation of acc1 and acc2. */
9288 gen_acc1 (void)
9290 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9293 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9294 differ from the hardware register number in order to allow the generic
9295 code to correctly split the concatenation of acc1 and acc2. */
9298 gen_acc2 (void)
9300 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9303 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9304 differ from the hardware register number in order to allow the generic
9305 code to correctly split the concatenation of mhi and mlo. */
9308 gen_mlo (void)
9310 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
9313 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9314 differ from the hardware register number in order to allow the generic
9315 code to correctly split the concatenation of mhi and mlo. */
9318 gen_mhi (void)
9320 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
9323 /* FIXME: a parameter should be added, and code added to final.c,
9324 to reproduce this functionality in shorten_branches. */
9325 #if 0
9326 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9327 a previous instruction. */
9329 arc_unalign_branch_p (rtx branch)
9331 rtx note;
9333 if (!TARGET_UNALIGN_BRANCH)
9334 return 0;
9335 /* Do not do this if we have a filled delay slot. */
9336 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
9337 && !NEXT_INSN (branch)->deleted ())
9338 return 0;
9339 note = find_reg_note (branch, REG_BR_PROB, 0);
9340 return (!note
9341 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
9342 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
9344 #endif
9346 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9347 are three reasons why we need to consider branches to be length 6:
9348 - annull-false delay slot insns are implemented using conditional execution,
9349 thus preventing short insn formation where used.
9350 - for ARC600: annul-true delay slot insns are implemented where possible
9351 using conditional execution, preventing short insn formation where used.
9352 - for ARC700: likely or somewhat likely taken branches are made long and
9353 unaligned if possible to avoid branch penalty. */
9355 bool
9356 arc_branch_size_unknown_p (void)
9358 return !optimize_size && arc_reorg_in_progress;
9361 /* We are about to output a return insn. Add padding if necessary to avoid
9362 a mispredict. A return could happen immediately after the function
9363 start, but after a call we know that there will be at least a blink
9364 restore. */
9366 void
9367 arc_pad_return (void)
9369 rtx_insn *insn = current_output_insn;
9370 rtx_insn *prev = prev_active_insn (insn);
9371 int want_long;
9373 if (!prev)
9375 fputs ("\tnop_s\n", asm_out_file);
9376 cfun->machine->unalign ^= 2;
9377 want_long = 1;
9379 /* If PREV is a sequence, we know it must be a branch / jump or a tailcall,
9380 because after a call, we'd have to restore blink first. */
9381 else if (GET_CODE (PATTERN (prev)) == SEQUENCE)
9382 return;
9383 else
9385 want_long = (get_attr_length (prev) == 2);
9386 prev = prev_active_insn (prev);
9388 if (!prev
9389 || ((NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
9390 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9391 NON_SIBCALL)
9392 : CALL_ATTR (prev, NON_SIBCALL)))
9394 if (want_long)
9395 cfun->machine->size_reason
9396 = "call/return and return/return must be 6 bytes apart to avoid mispredict";
9397 else if (TARGET_UNALIGN_BRANCH && cfun->machine->unalign)
9399 cfun->machine->size_reason
9400 = "Long unaligned jump avoids non-delay slot penalty";
9401 want_long = 1;
9403 /* Disgorge delay insn, if there is any, and it may be moved. */
9404 if (final_sequence
9405 /* ??? Annulled would be OK if we can and do conditionalize
9406 the delay slot insn accordingly. */
9407 && !INSN_ANNULLED_BRANCH_P (insn)
9408 && (get_attr_cond (insn) != COND_USE
9409 || !reg_set_p (gen_rtx_REG (CCmode, CC_REG),
9410 XVECEXP (final_sequence, 0, 1))))
9412 prev = as_a <rtx_insn *> (XVECEXP (final_sequence, 0, 1));
9413 gcc_assert (!prev_real_insn (insn)
9414 || !arc_hazard (prev_real_insn (insn), prev));
9415 cfun->machine->force_short_suffix = !want_long;
9416 rtx save_pred = current_insn_predicate;
9417 final_scan_insn (prev, asm_out_file, optimize, 1, NULL);
9418 cfun->machine->force_short_suffix = -1;
9419 prev->set_deleted ();
9420 current_output_insn = insn;
9421 current_insn_predicate = save_pred;
9423 else if (want_long)
9424 fputs ("\tnop\n", asm_out_file);
9425 else
9427 fputs ("\tnop_s\n", asm_out_file);
9428 cfun->machine->unalign ^= 2;
9431 return;
9434 /* The usual; we set up our machine_function data. */
9436 static struct machine_function *
9437 arc_init_machine_status (void)
9439 struct machine_function *machine;
9440 machine = ggc_cleared_alloc<machine_function> ();
9441 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9442 machine->force_short_suffix = -1;
9444 return machine;
9447 /* Implements INIT_EXPANDERS. We just set up to call the above
9448 function. */
9450 void
9451 arc_init_expanders (void)
9453 init_machine_status = arc_init_machine_status;
9456 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9457 indicates a number of elements to ignore - that allows to have a
9458 sibcall pattern that starts with (return). LOAD_P is zero for store
9459 multiple (for prologues), and one for load multiples (for epilogues),
9460 and two for load multiples where no final clobber of blink is required.
9461 We also skip the first load / store element since this is supposed to
9462 be checked in the instruction pattern. */
9465 arc_check_millicode (rtx op, int offset, int load_p)
9467 int len = XVECLEN (op, 0) - offset;
9468 int i;
9470 if (load_p == 2)
9472 if (len < 2 || len > 13)
9473 return 0;
9474 load_p = 1;
9476 else
9478 rtx elt = XVECEXP (op, 0, --len);
9480 if (GET_CODE (elt) != CLOBBER
9481 || !REG_P (XEXP (elt, 0))
9482 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9483 || len < 3 || len > 13)
9484 return 0;
9486 for (i = 1; i < len; i++)
9488 rtx elt = XVECEXP (op, 0, i + offset);
9489 rtx reg, mem, addr;
9491 if (GET_CODE (elt) != SET)
9492 return 0;
9493 mem = XEXP (elt, load_p);
9494 reg = XEXP (elt, 1-load_p);
9495 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9496 return 0;
9497 addr = XEXP (mem, 0);
9498 if (GET_CODE (addr) != PLUS
9499 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9500 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9501 return 0;
9503 return 1;
9506 /* Accessor functions for cfun->machine->unalign. */
9509 arc_get_unalign (void)
9511 return cfun->machine->unalign;
9514 void
9515 arc_clear_unalign (void)
9517 if (cfun)
9518 cfun->machine->unalign = 0;
9521 void
9522 arc_toggle_unalign (void)
9524 cfun->machine->unalign ^= 2;
9527 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9528 constant in operand 2, but which would require a LIMM because of
9529 operand mismatch.
9530 operands 3 and 4 are new SET_SRCs for operands 0. */
9532 void
9533 split_addsi (rtx *operands)
9535 int val = INTVAL (operands[2]);
9537 /* Try for two short insns first. Lengths being equal, we prefer
9538 expansions with shorter register lifetimes. */
9539 if (val > 127 && val <= 255
9540 && satisfies_constraint_Rcq (operands[0]))
9542 operands[3] = operands[2];
9543 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9545 else
9547 operands[3] = operands[1];
9548 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
9552 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9553 constant in operand 1, but which would require a LIMM because of
9554 operand mismatch.
9555 operands 3 and 4 are new SET_SRCs for operands 0. */
9557 void
9558 split_subsi (rtx *operands)
9560 int val = INTVAL (operands[1]);
9562 /* Try for two short insns first. Lengths being equal, we prefer
9563 expansions with shorter register lifetimes. */
9564 if (satisfies_constraint_Rcq (operands[0])
9565 && satisfies_constraint_Rcq (operands[2]))
9567 if (val >= -31 && val <= 127)
9569 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9570 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9571 return;
9573 else if (val >= 0 && val < 255)
9575 operands[3] = operands[1];
9576 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9577 return;
9580 /* If the destination is not an ARCompact16 register, we might
9581 still have a chance to make a short insn if the source is;
9582 we need to start with a reg-reg move for this. */
9583 operands[3] = operands[2];
9584 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9587 /* Handle DOUBLE_REGS uses.
9588 Operand 0: destination register
9589 Operand 1: source register */
9591 static bool
9592 arc_process_double_reg_moves (rtx *operands)
9594 rtx dest = operands[0];
9595 rtx src = operands[1];
9597 enum usesDxState { none, srcDx, destDx, maxDx };
9598 enum usesDxState state = none;
9600 if (refers_to_regno_p (40, 44, src, 0))
9601 state = srcDx;
9602 if (refers_to_regno_p (40, 44, dest, 0))
9604 /* Via arc_register_move_cost, we should never see D,D moves. */
9605 gcc_assert (state == none);
9606 state = destDx;
9609 if (state == none)
9610 return false;
9612 if (state == srcDx)
9614 /* Without the LR insn, we need to split this into a
9615 sequence of insns which will use the DEXCLx and DADDHxy
9616 insns to be able to read the Dx register in question. */
9617 if (TARGET_DPFP_DISABLE_LRSR)
9619 /* gen *movdf_insn_nolrsr */
9620 rtx set = gen_rtx_SET (dest, src);
9621 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9622 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9624 else
9626 /* When we have 'mov D, r' or 'mov D, D' then get the target
9627 register pair for use with LR insn. */
9628 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9629 TARGET_BIG_ENDIAN ? 0 : 4);
9630 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9631 TARGET_BIG_ENDIAN ? 4 : 0);
9633 /* Produce the two LR insns to get the high and low parts. */
9634 emit_insn (gen_rtx_SET (destHigh,
9635 gen_rtx_UNSPEC_VOLATILE (Pmode,
9636 gen_rtvec (1, src),
9637 VUNSPEC_ARC_LR_HIGH)));
9638 emit_insn (gen_rtx_SET (destLow,
9639 gen_rtx_UNSPEC_VOLATILE (Pmode,
9640 gen_rtvec (1, src),
9641 VUNSPEC_ARC_LR)));
9644 else if (state == destDx)
9646 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9647 LR insn get the target register pair. */
9648 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9649 TARGET_BIG_ENDIAN ? 0 : 4);
9650 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9651 TARGET_BIG_ENDIAN ? 4 : 0);
9653 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9655 else
9656 gcc_unreachable ();
9658 return true;
9661 /* operands 0..1 are the operands of a 64 bit move instruction.
9662 split it into two moves with operands 2/3 and 4/5. */
9664 void
9665 arc_split_move (rtx *operands)
9667 machine_mode mode = GET_MODE (operands[0]);
9668 int i;
9669 int swap = 0;
9670 rtx xop[4];
9672 if (TARGET_DPFP)
9674 if (arc_process_double_reg_moves (operands))
9675 return;
9678 if (TARGET_LL64
9679 && ((memory_operand (operands[0], mode)
9680 && even_register_operand (operands[1], mode))
9681 || (memory_operand (operands[1], mode)
9682 && even_register_operand (operands[0], mode))))
9684 emit_move_insn (operands[0], operands[1]);
9685 return;
9688 if (TARGET_PLUS_QMACW
9689 && GET_CODE (operands[1]) == CONST_VECTOR)
9691 HOST_WIDE_INT intval0, intval1;
9692 if (GET_MODE (operands[1]) == V2SImode)
9694 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9695 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9697 else
9699 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9700 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9701 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9702 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9704 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9705 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9706 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9707 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9708 emit_move_insn (xop[0], xop[2]);
9709 emit_move_insn (xop[3], xop[1]);
9710 return;
9713 for (i = 0; i < 2; i++)
9715 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9717 rtx addr = XEXP (operands[i], 0);
9718 rtx r, o;
9719 enum rtx_code code;
9721 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9722 switch (GET_CODE (addr))
9724 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9725 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9726 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9727 pre_modify:
9728 code = PRE_MODIFY;
9729 break;
9730 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9731 case POST_INC: o = GEN_INT (8); goto post_modify;
9732 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9733 post_modify:
9734 code = POST_MODIFY;
9735 swap = 2;
9736 break;
9737 default:
9738 gcc_unreachable ();
9740 r = XEXP (addr, 0);
9741 xop[0+i] = adjust_automodify_address_nv
9742 (operands[i], SImode,
9743 gen_rtx_fmt_ee (code, Pmode, r,
9744 gen_rtx_PLUS (Pmode, r, o)),
9746 xop[2+i] = adjust_automodify_address_nv
9747 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9749 else
9751 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9752 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9755 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9757 swap = 2;
9758 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9761 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9762 emit_move_insn (xop[2 - swap], xop[3 - swap]);
9766 /* Select between the instruction output templates s_tmpl (for short INSNs)
9767 and l_tmpl (for long INSNs). */
9769 const char *
9770 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
9772 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9774 extract_constrain_insn_cached (insn);
9775 return is_short ? s_tmpl : l_tmpl;
9778 /* Searches X for any reference to REGNO, returning the rtx of the
9779 reference found if any. Otherwise, returns NULL_RTX. */
9782 arc_regno_use_in (unsigned int regno, rtx x)
9784 const char *fmt;
9785 int i, j;
9786 rtx tem;
9788 if (REG_P (x) && refers_to_regno_p (regno, x))
9789 return x;
9791 fmt = GET_RTX_FORMAT (GET_CODE (x));
9792 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9794 if (fmt[i] == 'e')
9796 if ((tem = regno_use_in (regno, XEXP (x, i))))
9797 return tem;
9799 else if (fmt[i] == 'E')
9800 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9801 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9802 return tem;
9805 return NULL_RTX;
9808 /* Return the integer value of the "type" attribute for INSN, or -1 if
9809 INSN can't have attributes. */
9811 static int
9812 arc_attr_type (rtx_insn *insn)
9814 if (NONJUMP_INSN_P (insn)
9815 ? (GET_CODE (PATTERN (insn)) == USE
9816 || GET_CODE (PATTERN (insn)) == CLOBBER)
9817 : JUMP_P (insn)
9818 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9819 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9820 : !CALL_P (insn))
9821 return -1;
9822 return get_attr_type (insn);
9825 /* Return true if insn sets the condition codes. */
9827 bool
9828 arc_sets_cc_p (rtx_insn *insn)
9830 if (NONJUMP_INSN_P (insn))
9831 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9832 insn = seq->insn (seq->len () - 1);
9833 return arc_attr_type (insn) == TYPE_COMPARE;
9836 /* Return true if INSN is an instruction with a delay slot we may want
9837 to fill. */
9839 bool
9840 arc_need_delay (rtx_insn *insn)
9842 rtx_insn *next;
9844 if (!flag_delayed_branch)
9845 return false;
9846 /* The return at the end of a function needs a delay slot. */
9847 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9848 && (!(next = next_active_insn (insn))
9849 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9850 && arc_attr_type (next) == TYPE_RETURN))
9851 && (!TARGET_PAD_RETURN
9852 || (prev_active_insn (insn)
9853 && prev_active_insn (prev_active_insn (insn))
9854 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9855 return true;
9856 if (NONJUMP_INSN_P (insn)
9857 ? (GET_CODE (PATTERN (insn)) == USE
9858 || GET_CODE (PATTERN (insn)) == CLOBBER
9859 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9860 : JUMP_P (insn)
9861 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9862 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9863 : !CALL_P (insn))
9864 return false;
9865 return num_delay_slots (insn) != 0;
9868 /* Return true if the scheduling pass(es) has/have already run,
9869 i.e. where possible, we should try to mitigate high latencies
9870 by different instruction selection. */
9872 bool
9873 arc_scheduling_not_expected (void)
9875 return cfun->machine->arc_reorg_started;
9879 arc_label_align (rtx_insn *label)
9881 /* Code has a minimum p2 alignment of 1, which we must restore after an
9882 ADDR_DIFF_VEC. */
9883 if (align_labels_log < 1)
9885 rtx_insn *next = next_nonnote_nondebug_insn (label);
9886 if (INSN_P (next) && recog_memoized (next) >= 0)
9887 return 1;
9889 return align_labels_log;
9892 /* Return true if LABEL is in executable code. */
9894 bool
9895 arc_text_label (rtx_insn *label)
9897 rtx_insn *next;
9899 /* ??? We use deleted labels like they were still there, see
9900 gcc.c-torture/compile/20000326-2.c . */
9901 gcc_assert (GET_CODE (label) == CODE_LABEL
9902 || (GET_CODE (label) == NOTE
9903 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9904 next = next_nonnote_insn (label);
9905 if (next)
9906 return (!JUMP_TABLE_DATA_P (next)
9907 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9908 else if (!PREV_INSN (label))
9909 /* ??? sometimes text labels get inserted very late, see
9910 gcc.dg/torture/stackalign/comp-goto-1.c */
9911 return true;
9912 return false;
9915 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9916 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9917 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9918 to redirect two breqs. */
9920 static bool
9921 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
9923 /* ??? get_attr_type is declared to take an rtx. */
9924 union { const rtx_insn *c; rtx_insn *r; } u;
9926 u.c = follower;
9927 if (CROSSING_JUMP_P (followee))
9928 switch (get_attr_type (u.r))
9930 case TYPE_BRANCH:
9931 if (get_attr_length (u.r) != 2)
9932 break;
9933 /* Fall through. */
9934 case TYPE_BRCC:
9935 case TYPE_BRCC_NO_DELAY_SLOT:
9936 return false;
9937 default:
9938 return true;
9940 return true;
9943 /* Return the register number of the register holding the return address
9944 for a function of type TYPE. */
9947 arc_return_address_register (unsigned int fn_type)
9949 int regno = 0;
9951 if (ARC_INTERRUPT_P (fn_type))
9953 if (((fn_type & ARC_FUNCTION_ILINK1) | ARC_FUNCTION_FIRQ) != 0)
9954 regno = ILINK1_REGNUM;
9955 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
9956 regno = ILINK2_REGNUM;
9957 else
9958 gcc_unreachable ();
9960 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
9961 regno = RETURN_ADDR_REGNUM;
9963 gcc_assert (regno != 0);
9964 return regno;
9967 /* Implement EPILOGUE_USES.
9968 Return true if REGNO should be added to the deemed uses of the epilogue.
9970 We have to make sure all the register restore instructions are
9971 known to be live in interrupt functions, plus the blink register if
9972 it is clobbered by the isr. */
9974 bool
9975 arc_epilogue_uses (int regno)
9977 unsigned int fn_type;
9979 if (regno == arc_tp_regno)
9980 return true;
9982 fn_type = arc_compute_function_type (cfun);
9983 if (reload_completed)
9985 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9987 if (!fixed_regs[regno])
9988 return true;
9989 return ((regno == arc_return_address_register (fn_type))
9990 || (regno == RETURN_ADDR_REGNUM));
9992 else
9993 return regno == RETURN_ADDR_REGNUM;
9995 else
9996 return regno == arc_return_address_register (fn_type);
9999 /* Helper for EH_USES macro. */
10001 bool
10002 arc_eh_uses (int regno)
10004 if (regno == arc_tp_regno)
10005 return true;
10006 return false;
10009 #ifndef TARGET_NO_LRA
10010 #define TARGET_NO_LRA !TARGET_LRA
10011 #endif
10013 static bool
10014 arc_lra_p (void)
10016 return !TARGET_NO_LRA;
10019 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
10020 Rcq registers, because some insn are shorter with them. OTOH we already
10021 have separate alternatives for this purpose, and other insns don't
10022 mind, so maybe we should rather prefer the other registers?
10023 We need more data, and we can only get that if we allow people to
10024 try all options. */
10025 static int
10026 arc_register_priority (int r)
10028 switch (arc_lra_priority_tag)
10030 case ARC_LRA_PRIORITY_NONE:
10031 return 0;
10032 case ARC_LRA_PRIORITY_NONCOMPACT:
10033 return ((((r & 7) ^ 4) - 4) & 15) != r;
10034 case ARC_LRA_PRIORITY_COMPACT:
10035 return ((((r & 7) ^ 4) - 4) & 15) == r;
10036 default:
10037 gcc_unreachable ();
10041 static reg_class_t
10042 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
10044 return GENERAL_REGS;
10047 bool
10048 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
10049 int itype)
10051 rtx x = *p;
10052 enum reload_type type = (enum reload_type) itype;
10054 if (GET_CODE (x) == PLUS
10055 && CONST_INT_P (XEXP (x, 1))
10056 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
10057 || (REG_P (XEXP (x, 0))
10058 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
10060 int scale = GET_MODE_SIZE (mode);
10061 int shift;
10062 rtx index_rtx = XEXP (x, 1);
10063 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
10064 rtx reg, sum, sum2;
10066 if (scale > 4)
10067 scale = 4;
10068 if ((scale-1) & offset)
10069 scale = 1;
10070 shift = scale >> 1;
10071 offset_base
10072 = ((offset + (256 << shift))
10073 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
10074 /* Sometimes the normal form does not suit DImode. We
10075 could avoid that by using smaller ranges, but that
10076 would give less optimized code when SImode is
10077 prevalent. */
10078 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
10080 int regno;
10082 reg = XEXP (x, 0);
10083 regno = REGNO (reg);
10084 sum2 = sum = plus_constant (Pmode, reg, offset_base);
10086 if (reg_equiv_constant (regno))
10088 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
10089 offset_base);
10090 if (GET_CODE (sum2) == PLUS)
10091 sum2 = gen_rtx_CONST (Pmode, sum2);
10093 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
10094 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
10095 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
10096 type);
10097 return true;
10100 /* We must re-recognize what we created before. */
10101 else if (GET_CODE (x) == PLUS
10102 && GET_CODE (XEXP (x, 0)) == PLUS
10103 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
10104 && REG_P (XEXP (XEXP (x, 0), 0))
10105 && CONST_INT_P (XEXP (x, 1)))
10107 /* Because this address is so complex, we know it must have
10108 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10109 it is already unshared, and needs no further unsharing. */
10110 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
10111 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10112 return true;
10114 return false;
10117 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10119 static bool
10120 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
10121 unsigned int align,
10122 enum by_pieces_operation op,
10123 bool speed_p)
10125 /* Let the movmem expander handle small block moves. */
10126 if (op == MOVE_BY_PIECES)
10127 return false;
10129 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10132 /* Emit a (pre) memory barrier around an atomic sequence according to
10133 MODEL. */
10135 static void
10136 arc_pre_atomic_barrier (enum memmodel model)
10138 if (need_atomic_barrier_p (model, true))
10139 emit_insn (gen_memory_barrier ());
10142 /* Emit a (post) memory barrier around an atomic sequence according to
10143 MODEL. */
10145 static void
10146 arc_post_atomic_barrier (enum memmodel model)
10148 if (need_atomic_barrier_p (model, false))
10149 emit_insn (gen_memory_barrier ());
10152 /* Expand a compare and swap pattern. */
10154 static void
10155 emit_unlikely_jump (rtx insn)
10157 rtx_insn *jump = emit_jump_insn (insn);
10158 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10161 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10162 32-bit compare and swap on the word containing the byte or
10163 half-word. The difference between a weak and a strong CAS is that
10164 the weak version may simply fail. The strong version relies on two
10165 loops, one checks if the SCOND op is succsfully or not, the other
10166 checks if the 32 bit accessed location which contains the 8 or 16
10167 bit datum is not changed by other thread. The first loop is
10168 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10169 loops is implemented by this routine. */
10171 static void
10172 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10173 rtx oldval, rtx newval, rtx weak,
10174 rtx mod_s, rtx mod_f)
10176 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10177 rtx addr = gen_reg_rtx (Pmode);
10178 rtx off = gen_reg_rtx (SImode);
10179 rtx oldv = gen_reg_rtx (SImode);
10180 rtx newv = gen_reg_rtx (SImode);
10181 rtx oldvalue = gen_reg_rtx (SImode);
10182 rtx newvalue = gen_reg_rtx (SImode);
10183 rtx res = gen_reg_rtx (SImode);
10184 rtx resv = gen_reg_rtx (SImode);
10185 rtx memsi, val, mask, end_label, loop_label, cc, x;
10186 machine_mode mode;
10187 bool is_weak = (weak != const0_rtx);
10189 /* Truncate the address. */
10190 emit_insn (gen_rtx_SET (addr,
10191 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10193 /* Compute the datum offset. */
10194 emit_insn (gen_rtx_SET (off,
10195 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10196 if (TARGET_BIG_ENDIAN)
10197 emit_insn (gen_rtx_SET (off,
10198 gen_rtx_MINUS (SImode,
10199 (GET_MODE (mem) == QImode) ?
10200 GEN_INT (3) : GEN_INT (2), off)));
10202 /* Normal read from truncated address. */
10203 memsi = gen_rtx_MEM (SImode, addr);
10204 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10205 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10207 val = copy_to_reg (memsi);
10209 /* Convert the offset in bits. */
10210 emit_insn (gen_rtx_SET (off,
10211 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10213 /* Get the proper mask. */
10214 if (GET_MODE (mem) == QImode)
10215 mask = force_reg (SImode, GEN_INT (0xff));
10216 else
10217 mask = force_reg (SImode, GEN_INT (0xffff));
10219 emit_insn (gen_rtx_SET (mask,
10220 gen_rtx_ASHIFT (SImode, mask, off)));
10222 /* Prepare the old and new values. */
10223 emit_insn (gen_rtx_SET (val,
10224 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10225 val)));
10227 oldval = gen_lowpart (SImode, oldval);
10228 emit_insn (gen_rtx_SET (oldv,
10229 gen_rtx_ASHIFT (SImode, oldval, off)));
10231 newval = gen_lowpart_common (SImode, newval);
10232 emit_insn (gen_rtx_SET (newv,
10233 gen_rtx_ASHIFT (SImode, newval, off)));
10235 emit_insn (gen_rtx_SET (oldv,
10236 gen_rtx_AND (SImode, oldv, mask)));
10238 emit_insn (gen_rtx_SET (newv,
10239 gen_rtx_AND (SImode, newv, mask)));
10241 if (!is_weak)
10243 end_label = gen_label_rtx ();
10244 loop_label = gen_label_rtx ();
10245 emit_label (loop_label);
10248 /* Make the old and new values. */
10249 emit_insn (gen_rtx_SET (oldvalue,
10250 gen_rtx_IOR (SImode, oldv, val)));
10252 emit_insn (gen_rtx_SET (newvalue,
10253 gen_rtx_IOR (SImode, newv, val)));
10255 /* Try an 32bit atomic compare and swap. It clobbers the CC
10256 register. */
10257 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10258 weak, mod_s, mod_f));
10260 /* Regardless of the weakness of the operation, a proper boolean
10261 result needs to be provided. */
10262 x = gen_rtx_REG (CC_Zmode, CC_REG);
10263 x = gen_rtx_EQ (SImode, x, const0_rtx);
10264 emit_insn (gen_rtx_SET (bool_result, x));
10266 if (!is_weak)
10268 /* Check the results: if the atomic op is successfully the goto
10269 to end label. */
10270 x = gen_rtx_REG (CC_Zmode, CC_REG);
10271 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10272 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10273 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10274 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10276 /* Wait for the right moment when the accessed 32-bit location
10277 is stable. */
10278 emit_insn (gen_rtx_SET (resv,
10279 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10280 res)));
10281 mode = SELECT_CC_MODE (NE, resv, val);
10282 cc = gen_rtx_REG (mode, CC_REG);
10283 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10285 /* Set the new value of the 32 bit location, proper masked. */
10286 emit_insn (gen_rtx_SET (val, resv));
10288 /* Try again if location is unstable. Fall through if only
10289 scond op failed. */
10290 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10291 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10292 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10293 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10295 emit_label (end_label);
10298 /* End: proper return the result for the given mode. */
10299 emit_insn (gen_rtx_SET (res,
10300 gen_rtx_AND (SImode, res, mask)));
10302 emit_insn (gen_rtx_SET (res,
10303 gen_rtx_LSHIFTRT (SImode, res, off)));
10305 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10308 /* Helper function used by "atomic_compare_and_swap" expand
10309 pattern. */
10311 void
10312 arc_expand_compare_and_swap (rtx operands[])
10314 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10315 machine_mode mode;
10317 bval = operands[0];
10318 rval = operands[1];
10319 mem = operands[2];
10320 oldval = operands[3];
10321 newval = operands[4];
10322 is_weak = operands[5];
10323 mod_s = operands[6];
10324 mod_f = operands[7];
10325 mode = GET_MODE (mem);
10327 if (reg_overlap_mentioned_p (rval, oldval))
10328 oldval = copy_to_reg (oldval);
10330 if (mode == SImode)
10332 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10333 is_weak, mod_s, mod_f));
10334 x = gen_rtx_REG (CC_Zmode, CC_REG);
10335 x = gen_rtx_EQ (SImode, x, const0_rtx);
10336 emit_insn (gen_rtx_SET (bval, x));
10338 else
10340 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10341 is_weak, mod_s, mod_f);
10345 /* Helper function used by the "atomic_compare_and_swapsi_1"
10346 pattern. */
10348 void
10349 arc_split_compare_and_swap (rtx operands[])
10351 rtx rval, mem, oldval, newval;
10352 machine_mode mode;
10353 enum memmodel mod_s, mod_f;
10354 bool is_weak;
10355 rtx label1, label2, x, cond;
10357 rval = operands[0];
10358 mem = operands[1];
10359 oldval = operands[2];
10360 newval = operands[3];
10361 is_weak = (operands[4] != const0_rtx);
10362 mod_s = (enum memmodel) INTVAL (operands[5]);
10363 mod_f = (enum memmodel) INTVAL (operands[6]);
10364 mode = GET_MODE (mem);
10366 /* ARC atomic ops work only with 32-bit aligned memories. */
10367 gcc_assert (mode == SImode);
10369 arc_pre_atomic_barrier (mod_s);
10371 label1 = NULL_RTX;
10372 if (!is_weak)
10374 label1 = gen_label_rtx ();
10375 emit_label (label1);
10377 label2 = gen_label_rtx ();
10379 /* Load exclusive. */
10380 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10382 /* Check if it is oldval. */
10383 mode = SELECT_CC_MODE (NE, rval, oldval);
10384 cond = gen_rtx_REG (mode, CC_REG);
10385 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10387 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10388 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10389 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10390 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10392 /* Exclusively store new item. Store clobbers CC reg. */
10393 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10395 if (!is_weak)
10397 /* Check the result of the store. */
10398 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10399 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10400 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10401 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10402 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10405 if (mod_f != MEMMODEL_RELAXED)
10406 emit_label (label2);
10408 arc_post_atomic_barrier (mod_s);
10410 if (mod_f == MEMMODEL_RELAXED)
10411 emit_label (label2);
10414 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10415 to perform. MEM is the memory on which to operate. VAL is the second
10416 operand of the binary operator. BEFORE and AFTER are optional locations to
10417 return the value of MEM either before of after the operation. MODEL_RTX
10418 is a CONST_INT containing the memory model to use. */
10420 void
10421 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10422 rtx orig_before, rtx orig_after, rtx model_rtx)
10424 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10425 machine_mode mode = GET_MODE (mem);
10426 rtx label, x, cond;
10427 rtx before = orig_before, after = orig_after;
10429 /* ARC atomic ops work only with 32-bit aligned memories. */
10430 gcc_assert (mode == SImode);
10432 arc_pre_atomic_barrier (model);
10434 label = gen_label_rtx ();
10435 emit_label (label);
10436 label = gen_rtx_LABEL_REF (VOIDmode, label);
10438 if (before == NULL_RTX)
10439 before = gen_reg_rtx (mode);
10441 if (after == NULL_RTX)
10442 after = gen_reg_rtx (mode);
10444 /* Load exclusive. */
10445 emit_insn (gen_arc_load_exclusivesi (before, mem));
10447 switch (code)
10449 case NOT:
10450 x = gen_rtx_AND (mode, before, val);
10451 emit_insn (gen_rtx_SET (after, x));
10452 x = gen_rtx_NOT (mode, after);
10453 emit_insn (gen_rtx_SET (after, x));
10454 break;
10456 case MINUS:
10457 if (CONST_INT_P (val))
10459 val = GEN_INT (-INTVAL (val));
10460 code = PLUS;
10463 /* FALLTHRU. */
10464 default:
10465 x = gen_rtx_fmt_ee (code, mode, before, val);
10466 emit_insn (gen_rtx_SET (after, x));
10467 break;
10470 /* Exclusively store new item. Store clobbers CC reg. */
10471 emit_insn (gen_arc_store_exclusivesi (mem, after));
10473 /* Check the result of the store. */
10474 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10475 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10476 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10477 label, pc_rtx);
10478 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10480 arc_post_atomic_barrier (model);
10483 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10485 static bool
10486 arc_no_speculation_in_delay_slots_p ()
10488 return true;
10491 /* Return a parallel of registers to represent where to find the
10492 register pieces if required, otherwise NULL_RTX. */
10494 static rtx
10495 arc_dwarf_register_span (rtx rtl)
10497 machine_mode mode = GET_MODE (rtl);
10498 unsigned regno;
10499 rtx p;
10501 if (GET_MODE_SIZE (mode) != 8)
10502 return NULL_RTX;
10504 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10505 regno = REGNO (rtl);
10506 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10507 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10509 return p;
10512 /* Return true if OP is an acceptable memory operand for ARCompact
10513 16-bit load instructions of MODE.
10515 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10516 non scaled instructions.
10518 SCALED: TRUE if address can be scaled. */
10520 bool
10521 compact_memory_operand_p (rtx op, machine_mode mode,
10522 bool av2short, bool scaled)
10524 rtx addr, plus0, plus1;
10525 int size, off;
10527 /* Eliminate non-memory operations. */
10528 if (GET_CODE (op) != MEM)
10529 return 0;
10531 /* .di instructions have no 16-bit form. */
10532 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10533 return false;
10535 if (mode == VOIDmode)
10536 mode = GET_MODE (op);
10538 size = GET_MODE_SIZE (mode);
10540 /* dword operations really put out 2 instructions, so eliminate
10541 them. */
10542 if (size > UNITS_PER_WORD)
10543 return false;
10545 /* Decode the address now. */
10546 addr = XEXP (op, 0);
10547 switch (GET_CODE (addr))
10549 case REG:
10550 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10551 || COMPACT_GP_REG_P (REGNO (addr))
10552 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10553 case PLUS:
10554 plus0 = XEXP (addr, 0);
10555 plus1 = XEXP (addr, 1);
10557 if ((GET_CODE (plus0) == REG)
10558 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10559 || COMPACT_GP_REG_P (REGNO (plus0)))
10560 && ((GET_CODE (plus1) == REG)
10561 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10562 || COMPACT_GP_REG_P (REGNO (plus1)))))
10564 return !av2short;
10567 if ((GET_CODE (plus0) == REG)
10568 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10569 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10570 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10571 && (GET_CODE (plus1) == CONST_INT))
10573 bool valid = false;
10575 off = INTVAL (plus1);
10577 /* Negative offset is not supported in 16-bit load/store insns. */
10578 if (off < 0)
10579 return 0;
10581 /* Only u5 immediates allowed in code density instructions. */
10582 if (av2short)
10584 switch (size)
10586 case 1:
10587 return false;
10588 case 2:
10589 /* This is an ldh_s.x instruction, check the u6
10590 immediate. */
10591 if (COMPACT_GP_REG_P (REGNO (plus0)))
10592 valid = true;
10593 break;
10594 case 4:
10595 /* Only u5 immediates allowed in 32bit access code
10596 density instructions. */
10597 if (REGNO (plus0) <= 31)
10598 return ((off < 32) && (off % 4 == 0));
10599 break;
10600 default:
10601 return false;
10604 else
10605 if (COMPACT_GP_REG_P (REGNO (plus0)))
10606 valid = true;
10608 if (valid)
10611 switch (size)
10613 case 1:
10614 return (off < 32);
10615 case 2:
10616 /* The 6-bit constant get shifted to fit the real
10617 5-bits field. Check also for the alignment. */
10618 return ((off < 64) && (off % 2 == 0));
10619 case 4:
10620 return ((off < 128) && (off % 4 == 0));
10621 default:
10622 return false;
10627 if (REG_P (plus0) && CONST_INT_P (plus1)
10628 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10629 || SP_REG_P (REGNO (plus0)))
10630 && !av2short)
10632 off = INTVAL (plus1);
10633 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10636 if ((GET_CODE (plus0) == MULT)
10637 && (GET_CODE (XEXP (plus0, 0)) == REG)
10638 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10639 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10640 && (GET_CODE (plus1) == REG)
10641 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10642 || COMPACT_GP_REG_P (REGNO (plus1))))
10643 return scaled;
10644 default:
10645 break ;
10646 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10647 for 16-bit load instructions. */
10649 return false;
10652 /* Return the frame pointer value to be backed up in the setjmp buffer. */
10654 static rtx
10655 arc_builtin_setjmp_frame_value (void)
10657 /* We always want to preserve whatever value is currently in the frame
10658 pointer register. For frames that are using the frame pointer the new
10659 value of the frame pointer register will have already been computed
10660 (as part of the prologue). For frames that are not using the frame
10661 pointer it is important that we backup whatever value is in the frame
10662 pointer register, as earlier (more outer) frames may have placed a
10663 value into the frame pointer register. It might be tempting to try
10664 and use `frame_pointer_rtx` here, however, this is not what we want.
10665 For frames that are using the frame pointer this will give the
10666 correct value. However, for frames that are not using the frame
10667 pointer this will still give the value that _would_ have been the
10668 frame pointer value for this frame (if the use of the frame pointer
10669 had not been removed). We really do want the raw frame pointer
10670 register value. */
10671 return gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
10674 /* Return nonzero if a jli call should be generated for a call from
10675 the current function to DECL. */
10677 bool
10678 arc_is_jli_call_p (rtx pat)
10680 tree attrs;
10681 tree decl = SYMBOL_REF_DECL (pat);
10683 /* If it is not a well defined public function then return false. */
10684 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
10685 return false;
10687 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10688 if (lookup_attribute ("jli_always", attrs))
10689 return true;
10691 if (lookup_attribute ("jli_fixed", attrs))
10692 return true;
10694 return TARGET_JLI_ALWAYS;
10697 /* Handle and "jli" attribute; arguments as in struct
10698 attribute_spec.handler. */
10700 static tree
10701 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
10702 tree name, tree args, int,
10703 bool *no_add_attrs)
10705 if (!TARGET_V2)
10707 warning (OPT_Wattributes,
10708 "%qE attribute only valid for ARCv2 architecture",
10709 name);
10710 *no_add_attrs = true;
10713 if (args == NULL_TREE)
10715 warning (OPT_Wattributes,
10716 "argument of %qE attribute is missing",
10717 name);
10718 *no_add_attrs = true;
10720 else
10722 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10723 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10724 tree arg = TREE_VALUE (args);
10725 if (TREE_CODE (arg) != INTEGER_CST)
10727 warning (0, "%qE attribute allows only an integer constant argument",
10728 name);
10729 *no_add_attrs = true;
10731 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10733 return NULL_TREE;
10736 /* Handle and "scure" attribute; arguments as in struct
10737 attribute_spec.handler. */
10739 static tree
10740 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
10741 tree name, tree args, int,
10742 bool *no_add_attrs)
10744 if (!TARGET_EM)
10746 warning (OPT_Wattributes,
10747 "%qE attribute only valid for ARC EM architecture",
10748 name);
10749 *no_add_attrs = true;
10752 if (args == NULL_TREE)
10754 warning (OPT_Wattributes,
10755 "argument of %qE attribute is missing",
10756 name);
10757 *no_add_attrs = true;
10759 else
10761 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10762 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10763 tree arg = TREE_VALUE (args);
10764 if (TREE_CODE (arg) != INTEGER_CST)
10766 warning (0, "%qE attribute allows only an integer constant argument",
10767 name);
10768 *no_add_attrs = true;
10771 return NULL_TREE;
10774 /* Return nonzero if the symbol is a secure function. */
10776 bool
10777 arc_is_secure_call_p (rtx pat)
10779 tree attrs;
10780 tree decl = SYMBOL_REF_DECL (pat);
10782 if (!decl)
10783 return false;
10785 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10786 if (lookup_attribute ("secure_call", attrs))
10787 return true;
10789 return false;
10792 /* Handle "uncached" qualifier. */
10794 static tree
10795 arc_handle_uncached_attribute (tree *node,
10796 tree name, tree args,
10797 int flags ATTRIBUTE_UNUSED,
10798 bool *no_add_attrs)
10800 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
10802 error ("%qE attribute only applies to types",
10803 name);
10804 *no_add_attrs = true;
10806 else if (args)
10808 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
10810 return NULL_TREE;
10813 /* Return TRUE if PAT is a memory addressing an uncached data. */
10815 bool
10816 arc_is_uncached_mem_p (rtx pat)
10818 tree attrs;
10819 tree ttype;
10820 struct mem_attrs *refattrs;
10822 if (!MEM_P (pat))
10823 return false;
10825 /* Get the memory attributes. */
10826 refattrs = MEM_ATTRS (pat);
10827 if (!refattrs
10828 || !refattrs->expr)
10829 return false;
10831 /* Get the type declaration. */
10832 ttype = TREE_TYPE (refattrs->expr);
10833 if (!ttype)
10834 return false;
10836 /* Get the type attributes. */
10837 attrs = TYPE_ATTRIBUTES (ttype);
10838 if (lookup_attribute ("uncached", attrs))
10839 return true;
10840 return false;
10843 /* Handle aux attribute. The auxiliary registers are addressed using
10844 special instructions lr and sr. The attribute 'aux' indicates if a
10845 variable refers to the aux-regs and what is the register number
10846 desired. */
10848 static tree
10849 arc_handle_aux_attribute (tree *node,
10850 tree name, tree args, int,
10851 bool *no_add_attrs)
10853 /* Isn't it better to use address spaces for the aux-regs? */
10854 if (DECL_P (*node))
10856 if (TREE_CODE (*node) != VAR_DECL)
10858 error ("%qE attribute only applies to variables", name);
10859 *no_add_attrs = true;
10861 else if (args)
10863 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10864 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10865 tree arg = TREE_VALUE (args);
10866 if (TREE_CODE (arg) != INTEGER_CST)
10868 warning (0, "%qE attribute allows only an integer "
10869 "constant argument", name);
10870 *no_add_attrs = true;
10872 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10875 if (TREE_CODE (*node) == VAR_DECL)
10877 tree fntype = TREE_TYPE (*node);
10878 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
10880 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
10881 TYPE_ATTRIBUTES (fntype));
10882 TYPE_ATTRIBUTES (fntype) = attrs;
10886 return NULL_TREE;
10889 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10890 anchors for small data: the GP register acts as an anchor in that
10891 case. We also don't want to use them for PC-relative accesses,
10892 where the PC acts as an anchor. Prohibit also TLS symbols to use
10893 anchors. */
10895 static bool
10896 arc_use_anchors_for_symbol_p (const_rtx symbol)
10898 if (SYMBOL_REF_TLS_MODEL (symbol))
10899 return false;
10901 if (flag_pic)
10902 return false;
10904 if (SYMBOL_REF_SMALL_P (symbol))
10905 return false;
10907 return default_use_anchors_for_symbol_p (symbol);
10910 /* Return true if SUBST can't safely replace its equivalent during RA. */
10911 static bool
10912 arc_cannot_substitute_mem_equiv_p (rtx)
10914 /* If SUBST is mem[base+index], the address may not fit ISA,
10915 thus return true. */
10916 return true;
10919 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
10920 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
10922 #undef TARGET_CONSTANT_ALIGNMENT
10923 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
10925 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
10926 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
10928 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10929 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
10931 struct gcc_target targetm = TARGET_INITIALIZER;
10933 #include "gt-arc.h"