Fix version check for ATTRIBUTE_GCC_DUMP_PRINTF
[official-gcc.git] / gcc / config / arc / arc.c
blobc186e02e0f183e8c1d8a6a4939ee5ce148702604
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 /* Array of valid operand punctuation characters. */
100 char arc_punct_chars[256];
102 /* State used by arc_ccfsm_advance to implement conditional execution. */
103 struct GTY (()) arc_ccfsm
105 int state;
106 int cc;
107 rtx cond;
108 rtx_insn *target_insn;
109 int target_label;
112 /* Status of the IRQ_CTRL_AUX register. */
113 typedef struct irq_ctrl_saved_t
115 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
116 short irq_save_last_reg;
117 /* True if BLINK is automatically saved. */
118 bool irq_save_blink;
119 /* True if LPCOUNT is automatically saved. */
120 bool irq_save_lpcount;
121 } irq_ctrl_saved_t;
122 static irq_ctrl_saved_t irq_ctrl_saved;
124 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
125 ((ARC_INTERRUPT_P (FNTYPE) \
126 && irq_ctrl_saved.irq_save_blink) \
127 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
128 && rgf_banked_register_count > 8))
130 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
131 ((ARC_INTERRUPT_P (FNTYPE) \
132 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
133 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
134 && rgf_banked_register_count > 8))
136 #define ARC_AUTO_IRQ_P(FNTYPE) \
137 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
138 && (irq_ctrl_saved.irq_save_blink \
139 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
141 /* Number of registers in second bank for FIRQ support. */
142 static int rgf_banked_register_count;
144 #define arc_ccfsm_current cfun->machine->ccfsm_current
146 #define ARC_CCFSM_BRANCH_DELETED_P(STATE) \
147 ((STATE)->state == 1 || (STATE)->state == 2)
149 /* Indicate we're conditionalizing insns now. */
150 #define ARC_CCFSM_RECORD_BRANCH_DELETED(STATE) \
151 ((STATE)->state += 2)
153 #define ARC_CCFSM_COND_EXEC_P(STATE) \
154 ((STATE)->state == 3 || (STATE)->state == 4 || (STATE)->state == 5 \
155 || current_insn_predicate)
157 /* Check if INSN has a 16 bit opcode considering struct arc_ccfsm *STATE. */
158 #define CCFSM_ISCOMPACT(INSN,STATE) \
159 (ARC_CCFSM_COND_EXEC_P (STATE) \
160 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
161 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
162 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
164 /* Likewise, but also consider that INSN might be in a delay slot of JUMP. */
165 #define CCFSM_DBR_ISCOMPACT(INSN,JUMP,STATE) \
166 ((ARC_CCFSM_COND_EXEC_P (STATE) \
167 || (JUMP_P (JUMP) \
168 && INSN_ANNULLED_BRANCH_P (JUMP) \
169 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (INSN)))) \
170 ? (get_attr_iscompact (INSN) == ISCOMPACT_TRUE \
171 || get_attr_iscompact (INSN) == ISCOMPACT_TRUE_LIMM) \
172 : get_attr_iscompact (INSN) != ISCOMPACT_FALSE)
174 /* The maximum number of insns skipped which will be conditionalised if
175 possible. */
176 /* When optimizing for speed:
177 Let p be the probability that the potentially skipped insns need to
178 be executed, pn the cost of a correctly predicted non-taken branch,
179 mt the cost of a mis/non-predicted taken branch,
180 mn mispredicted non-taken, pt correctly predicted taken ;
181 costs expressed in numbers of instructions like the ones considered
182 skipping.
183 Unfortunately we don't have a measure of predictability - this
184 is linked to probability only in that in the no-eviction-scenario
185 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
186 value that can be assumed *if* the distribution is perfectly random.
187 A predictability of 1 is perfectly plausible not matter what p is,
188 because the decision could be dependent on an invocation parameter
189 of the program.
190 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
191 For small p, we want MAX_INSNS_SKIPPED == pt
193 When optimizing for size:
194 We want to skip insn unless we could use 16 opcodes for the
195 non-conditionalized insn to balance the branch length or more.
196 Performance can be tie-breaker. */
197 /* If the potentially-skipped insns are likely to be executed, we'll
198 generally save one non-taken branch
200 this to be no less than the 1/p */
201 #define MAX_INSNS_SKIPPED 3
203 /* A nop is needed between a 4 byte insn that sets the condition codes and
204 a branch that uses them (the same isn't true for an 8 byte insn that sets
205 the condition codes). Set by arc_ccfsm_advance. Used by
206 arc_print_operand. */
208 static int get_arc_condition_code (rtx);
210 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
211 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
212 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
213 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
214 static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
215 static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *);
217 /* Initialized arc_attribute_table to NULL since arc doesnot have any
218 machine specific supported attributes. */
219 const struct attribute_spec arc_attribute_table[] =
221 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
222 affects_type_identity, handler, exclude } */
223 { "interrupt", 1, 1, true, false, false, true,
224 arc_handle_interrupt_attribute, NULL },
225 /* Function calls made to this symbol must be done indirectly, because
226 it may lie outside of the 21/25 bit addressing range of a normal function
227 call. */
228 { "long_call", 0, 0, false, true, true, false, NULL, NULL },
229 /* Whereas these functions are always known to reside within the 25 bit
230 addressing range of unconditionalized bl. */
231 { "medium_call", 0, 0, false, true, true, false, NULL, NULL },
232 /* And these functions are always known to reside within the 21 bit
233 addressing range of blcc. */
234 { "short_call", 0, 0, false, true, true, false, NULL, NULL },
235 /* Function which are not having the prologue and epilogue generated
236 by the compiler. */
237 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute,
238 NULL },
239 /* Functions calls made using jli instruction. The pointer in JLI
240 table is found latter. */
241 { "jli_always", 0, 0, false, true, true, false, NULL, NULL },
242 /* Functions calls made using jli instruction. The pointer in JLI
243 table is given as input parameter. */
244 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute,
245 NULL },
246 /* Call a function using secure-mode. */
247 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute,
248 NULL },
249 /* Bypass caches using .di flag. */
250 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute,
251 NULL },
252 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute, NULL },
253 { NULL, 0, 0, false, false, false, false, NULL, NULL }
255 static int arc_comp_type_attributes (const_tree, const_tree);
256 static void arc_file_start (void);
257 static void arc_internal_label (FILE *, const char *, unsigned long);
258 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
259 tree);
260 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
261 static void arc_encode_section_info (tree decl, rtx rtl, int first);
263 static void arc_init_builtins (void);
264 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
266 static int branch_dest (rtx);
268 static void arc_output_pic_addr_const (FILE *, rtx, int);
269 static bool arc_function_ok_for_sibcall (tree, tree);
270 static rtx arc_function_value (const_tree, const_tree, bool);
271 const char * output_shift (rtx *);
272 static void arc_reorg (void);
273 static bool arc_in_small_data_p (const_tree);
275 static void arc_init_reg_tables (void);
276 static bool arc_return_in_memory (const_tree, const_tree);
277 static bool arc_vector_mode_supported_p (machine_mode);
279 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
280 unsigned int, bool);
281 static const char *arc_invalid_within_doloop (const rtx_insn *);
283 static void output_short_suffix (FILE *file);
285 static bool arc_frame_pointer_required (void);
287 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
288 unsigned int,
289 enum by_pieces_operation op,
290 bool);
292 /* Globally visible information about currently selected cpu. */
293 const arc_cpu_t *arc_selected_cpu;
295 /* Given a symbol RTX (const (symb <+ const_int>), returns its
296 alignment. */
298 static int
299 get_symbol_alignment (rtx x)
301 tree decl = NULL_TREE;
302 int align = 0;
304 switch (GET_CODE (x))
306 case SYMBOL_REF:
307 decl = SYMBOL_REF_DECL (x);
308 break;
309 case CONST:
310 return get_symbol_alignment (XEXP (x, 0));
311 case PLUS:
312 gcc_assert (CONST_INT_P (XEXP (x, 1)));
313 return get_symbol_alignment (XEXP (x, 0));
314 default:
315 return 0;
318 if (decl)
319 align = DECL_ALIGN (decl);
320 align = align / BITS_PER_UNIT;
321 return align;
324 /* Return true if x is ok to be used as a small data address. */
326 static bool
327 legitimate_small_data_address_p (rtx x)
329 switch (GET_CODE (x))
331 case CONST:
332 return legitimate_small_data_address_p (XEXP (x, 0));
333 case SYMBOL_REF:
334 return SYMBOL_REF_SMALL_P (x);
335 case PLUS:
337 bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
338 && SYMBOL_REF_SMALL_P (XEXP (x, 0));
339 bool p1 = CONST_INT_P (XEXP (x, 1))
340 && (INTVAL (XEXP (x, 1)) <= g_switch_value);
341 return p0 && p1;
343 default:
344 return false;
348 /* TRUE if op is an scaled address. */
349 static bool
350 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
352 if (GET_CODE (op) != PLUS)
353 return false;
355 if (GET_CODE (XEXP (op, 0)) != MULT)
356 return false;
358 /* Check multiplication operands. */
359 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
360 return false;
362 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
363 return false;
365 switch (GET_MODE_SIZE (mode))
367 case 2:
368 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
369 return false;
370 break;
371 case 8:
372 if (!TARGET_LL64)
373 return false;
374 /* Fall through. */
375 case 4:
376 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
377 return false;
378 /* Fall through. */
379 default:
380 return false;
383 /* Check the base. */
384 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
385 return true;
387 if (flag_pic)
389 if (CONST_INT_P (XEXP (op, 1)))
390 return true;
391 return false;
394 /* Scalled addresses for sdata is done other places. */
395 if (legitimate_small_data_address_p (op))
396 return false;
398 if (CONSTANT_P (XEXP (op, 1)))
399 return true;
401 return false;
404 /* Check for constructions like REG + OFFS, where OFFS can be a
405 register, an immediate or an long immediate. */
407 static bool
408 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
410 if (GET_CODE (x) != PLUS)
411 return false;
413 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
414 return false;
416 /* Check for: [Rx + small offset] or [Rx + Ry]. */
417 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict))
418 && GET_MODE_SIZE ((mode)) <= 4)
419 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1))))
420 return true;
422 /* Check for [Rx + symbol]. */
423 if (!flag_pic
424 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
425 /* Avoid this type of address for double or larger modes. */
426 && (GET_MODE_SIZE (mode) <= 4)
427 /* Avoid small data which ends in something like GP +
428 symb@sda. */
429 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
430 return true;
432 return false;
435 /* Implements target hook vector_mode_supported_p. */
437 static bool
438 arc_vector_mode_supported_p (machine_mode mode)
440 switch (mode)
442 case E_V2HImode:
443 return TARGET_PLUS_DMPY;
444 case E_V4HImode:
445 case E_V2SImode:
446 return TARGET_PLUS_QMACW;
447 case E_V4SImode:
448 case E_V8HImode:
449 return TARGET_SIMD_SET;
451 default:
452 return false;
456 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
458 static machine_mode
459 arc_preferred_simd_mode (scalar_mode mode)
461 switch (mode)
463 case E_HImode:
464 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
465 case E_SImode:
466 return V2SImode;
468 default:
469 return word_mode;
473 /* Implements target hook
474 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES. */
476 static void
477 arc_autovectorize_vector_sizes (vector_sizes *sizes)
479 if (TARGET_PLUS_QMACW)
481 sizes->quick_push (8);
482 sizes->quick_push (4);
487 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
488 static int
489 arc_sched_issue_rate (void)
491 switch (arc_tune)
493 case TUNE_ARCHS4X:
494 case TUNE_ARCHS4XD:
495 return 3;
496 default:
497 break;
499 return 1;
502 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
503 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
504 static rtx arc_delegitimize_address (rtx);
505 static bool arc_can_follow_jump (const rtx_insn *follower,
506 const rtx_insn *followee);
508 static rtx frame_insn (rtx);
509 static void arc_function_arg_advance (cumulative_args_t, machine_mode,
510 const_tree, bool);
511 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
513 /* initialize the GCC target structure. */
514 #undef TARGET_COMP_TYPE_ATTRIBUTES
515 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
516 #undef TARGET_ASM_FILE_START
517 #define TARGET_ASM_FILE_START arc_file_start
518 #undef TARGET_ATTRIBUTE_TABLE
519 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
520 #undef TARGET_ASM_INTERNAL_LABEL
521 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
522 #undef TARGET_RTX_COSTS
523 #define TARGET_RTX_COSTS arc_rtx_costs
524 #undef TARGET_ADDRESS_COST
525 #define TARGET_ADDRESS_COST arc_address_cost
527 #undef TARGET_ENCODE_SECTION_INFO
528 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
530 #undef TARGET_CANNOT_FORCE_CONST_MEM
531 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
533 #undef TARGET_INIT_BUILTINS
534 #define TARGET_INIT_BUILTINS arc_init_builtins
536 #undef TARGET_EXPAND_BUILTIN
537 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
539 #undef TARGET_BUILTIN_DECL
540 #define TARGET_BUILTIN_DECL arc_builtin_decl
542 #undef TARGET_ASM_OUTPUT_MI_THUNK
543 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
545 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
546 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
548 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
549 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
551 #undef TARGET_MACHINE_DEPENDENT_REORG
552 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
554 #undef TARGET_IN_SMALL_DATA_P
555 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
557 #undef TARGET_PROMOTE_FUNCTION_MODE
558 #define TARGET_PROMOTE_FUNCTION_MODE \
559 default_promote_function_mode_always_promote
561 #undef TARGET_PROMOTE_PROTOTYPES
562 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
564 #undef TARGET_RETURN_IN_MEMORY
565 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
566 #undef TARGET_PASS_BY_REFERENCE
567 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
569 #undef TARGET_SETUP_INCOMING_VARARGS
570 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
572 #undef TARGET_ARG_PARTIAL_BYTES
573 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
575 #undef TARGET_MUST_PASS_IN_STACK
576 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
578 #undef TARGET_FUNCTION_VALUE
579 #define TARGET_FUNCTION_VALUE arc_function_value
581 #undef TARGET_SCHED_ADJUST_PRIORITY
582 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
584 #undef TARGET_SCHED_ISSUE_RATE
585 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
587 #undef TARGET_VECTOR_MODE_SUPPORTED_P
588 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
590 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
591 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
593 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES
594 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_SIZES arc_autovectorize_vector_sizes
596 #undef TARGET_CAN_USE_DOLOOP_P
597 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
599 #undef TARGET_INVALID_WITHIN_DOLOOP
600 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
602 #undef TARGET_PRESERVE_RELOAD_P
603 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
605 #undef TARGET_CAN_FOLLOW_JUMP
606 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
608 #undef TARGET_DELEGITIMIZE_ADDRESS
609 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
611 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
612 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
613 arc_use_by_pieces_infrastructure_p
615 /* Usually, we will be able to scale anchor offsets.
616 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
617 #undef TARGET_MIN_ANCHOR_OFFSET
618 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
619 #undef TARGET_MAX_ANCHOR_OFFSET
620 #define TARGET_MAX_ANCHOR_OFFSET (1020)
622 #undef TARGET_SECONDARY_RELOAD
623 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
625 #define TARGET_OPTION_OVERRIDE arc_override_options
627 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
629 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
631 #define TARGET_CAN_ELIMINATE arc_can_eliminate
633 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
635 #define TARGET_FUNCTION_ARG arc_function_arg
637 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
639 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
641 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
643 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
645 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
647 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
648 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
649 arc_no_speculation_in_delay_slots_p
651 #undef TARGET_LRA_P
652 #define TARGET_LRA_P arc_lra_p
653 #define TARGET_REGISTER_PRIORITY arc_register_priority
654 /* Stores with scaled offsets have different displacement ranges. */
655 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
656 #define TARGET_SPILL_CLASS arc_spill_class
658 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
659 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
661 #undef TARGET_WARN_FUNC_RETURN
662 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
664 #include "target-def.h"
666 #undef TARGET_ASM_ALIGNED_HI_OP
667 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
668 #undef TARGET_ASM_ALIGNED_SI_OP
669 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
671 #ifdef HAVE_AS_TLS
672 #undef TARGET_HAVE_TLS
673 #define TARGET_HAVE_TLS HAVE_AS_TLS
674 #endif
676 #undef TARGET_DWARF_REGISTER_SPAN
677 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
679 #undef TARGET_HARD_REGNO_NREGS
680 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
681 #undef TARGET_HARD_REGNO_MODE_OK
682 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
684 #undef TARGET_MODES_TIEABLE_P
685 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
686 #undef TARGET_BUILTIN_SETJMP_FRAME_VALUE
687 #define TARGET_BUILTIN_SETJMP_FRAME_VALUE arc_builtin_setjmp_frame_value
689 /* Try to keep the (mov:DF _, reg) as early as possible so
690 that the d<add/sub/mul>h-lr insns appear together and can
691 use the peephole2 pattern. */
693 static int
694 arc_sched_adjust_priority (rtx_insn *insn, int priority)
696 rtx set = single_set (insn);
697 if (set
698 && GET_MODE (SET_SRC(set)) == DFmode
699 && GET_CODE (SET_SRC(set)) == REG)
701 /* Incrementing priority by 20 (empirically derived). */
702 return priority + 20;
705 return priority;
708 /* For ARC base register + offset addressing, the validity of the
709 address is mode-dependent for most of the offset range, as the
710 offset can be scaled by the access size.
711 We don't expose these as mode-dependent addresses in the
712 mode_dependent_address_p target hook, because that would disable
713 lots of optimizations, and most uses of these addresses are for 32
714 or 64 bit accesses anyways, which are fine.
715 However, that leaves some addresses for 8 / 16 bit values not
716 properly reloaded by the generic code, which is why we have to
717 schedule secondary reloads for these. */
719 static reg_class_t
720 arc_secondary_reload (bool in_p,
721 rtx x,
722 reg_class_t cl,
723 machine_mode mode,
724 secondary_reload_info *sri)
726 enum rtx_code code = GET_CODE (x);
728 if (cl == DOUBLE_REGS)
729 return GENERAL_REGS;
731 /* The loop counter register can be stored, but not loaded directly. */
732 if ((cl == LPCOUNT_REG || cl == WRITABLE_CORE_REGS)
733 && in_p && MEM_P (x))
734 return GENERAL_REGS;
736 /* If we have a subreg (reg), where reg is a pseudo (that will end in
737 a memory location), then we may need a scratch register to handle
738 the fp/sp+largeoffset address. */
739 if (code == SUBREG)
741 rtx addr = NULL_RTX;
742 x = SUBREG_REG (x);
744 if (REG_P (x))
746 int regno = REGNO (x);
747 if (regno >= FIRST_PSEUDO_REGISTER)
748 regno = reg_renumber[regno];
750 if (regno != -1)
751 return NO_REGS;
753 /* It is a pseudo that ends in a stack location. */
754 if (reg_equiv_mem (REGNO (x)))
756 /* Get the equivalent address and check the range of the
757 offset. */
758 rtx mem = reg_equiv_mem (REGNO (x));
759 addr = find_replacement (&XEXP (mem, 0));
762 else
764 gcc_assert (MEM_P (x));
765 addr = XEXP (x, 0);
766 addr = simplify_rtx (addr);
768 if (addr && GET_CODE (addr) == PLUS
769 && CONST_INT_P (XEXP (addr, 1))
770 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
772 switch (mode)
774 case E_QImode:
775 sri->icode =
776 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store;
777 break;
778 case E_HImode:
779 sri->icode =
780 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store;
781 break;
782 default:
783 break;
787 return NO_REGS;
790 /* Convert reloads using offsets that are too large to use indirect
791 addressing. */
793 void
794 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
796 rtx addr;
798 gcc_assert (GET_CODE (mem) == MEM);
799 addr = XEXP (mem, 0);
801 /* Large offset: use a move. FIXME: ld ops accepts limms as
802 offsets. Hence, the following move insn is not required. */
803 emit_move_insn (scratch, addr);
804 mem = replace_equiv_address_nv (mem, scratch);
806 /* Now create the move. */
807 if (store_p)
808 emit_insn (gen_rtx_SET (mem, reg));
809 else
810 emit_insn (gen_rtx_SET (reg, mem));
812 return;
815 static unsigned arc_ifcvt (void);
817 namespace {
819 const pass_data pass_data_arc_ifcvt =
821 RTL_PASS,
822 "arc_ifcvt", /* name */
823 OPTGROUP_NONE, /* optinfo_flags */
824 TV_IFCVT2, /* tv_id */
825 0, /* properties_required */
826 0, /* properties_provided */
827 0, /* properties_destroyed */
828 0, /* todo_flags_start */
829 TODO_df_finish /* todo_flags_finish */
832 class pass_arc_ifcvt : public rtl_opt_pass
834 public:
835 pass_arc_ifcvt(gcc::context *ctxt)
836 : rtl_opt_pass(pass_data_arc_ifcvt, ctxt)
839 /* opt_pass methods: */
840 opt_pass * clone () { return new pass_arc_ifcvt (m_ctxt); }
841 virtual unsigned int execute (function *) { return arc_ifcvt (); }
844 } // anon namespace
846 rtl_opt_pass *
847 make_pass_arc_ifcvt (gcc::context *ctxt)
849 return new pass_arc_ifcvt (ctxt);
852 static unsigned arc_predicate_delay_insns (void);
854 namespace {
856 const pass_data pass_data_arc_predicate_delay_insns =
858 RTL_PASS,
859 "arc_predicate_delay_insns", /* name */
860 OPTGROUP_NONE, /* optinfo_flags */
861 TV_IFCVT2, /* tv_id */
862 0, /* properties_required */
863 0, /* properties_provided */
864 0, /* properties_destroyed */
865 0, /* todo_flags_start */
866 TODO_df_finish /* todo_flags_finish */
869 class pass_arc_predicate_delay_insns : public rtl_opt_pass
871 public:
872 pass_arc_predicate_delay_insns(gcc::context *ctxt)
873 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
876 /* opt_pass methods: */
877 virtual unsigned int execute (function *)
879 return arc_predicate_delay_insns ();
883 } // anon namespace
885 rtl_opt_pass *
886 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
888 return new pass_arc_predicate_delay_insns (ctxt);
891 /* Called by OVERRIDE_OPTIONS to initialize various things. */
893 static void
894 arc_init (void)
896 if (TARGET_V2)
898 /* I have the multiplier, then use it*/
899 if (TARGET_MPYW || TARGET_MULTI)
900 arc_multcost = COSTS_N_INSNS (1);
902 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
903 if (arc_multcost < 0)
904 switch (arc_tune)
906 case ARC_TUNE_ARC700_4_2_STD:
907 /* latency 7;
908 max throughput (1 multiply + 4 other insns) / 5 cycles. */
909 arc_multcost = COSTS_N_INSNS (4);
910 if (TARGET_NOMPY_SET)
911 arc_multcost = COSTS_N_INSNS (30);
912 break;
913 case ARC_TUNE_ARC700_4_2_XMAC:
914 /* latency 5;
915 max throughput (1 multiply + 2 other insns) / 3 cycles. */
916 arc_multcost = COSTS_N_INSNS (3);
917 if (TARGET_NOMPY_SET)
918 arc_multcost = COSTS_N_INSNS (30);
919 break;
920 case ARC_TUNE_ARC600:
921 if (TARGET_MUL64_SET)
923 arc_multcost = COSTS_N_INSNS (4);
924 break;
926 /* Fall through. */
927 default:
928 arc_multcost = COSTS_N_INSNS (30);
929 break;
932 /* MPY instructions valid only for ARC700 or ARCv2. */
933 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
934 error ("-mno-mpy supported only for ARC700 or ARCv2");
936 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
937 error ("-mno-dpfp-lrsr supported only with -mdpfp");
939 /* FPX-1. No fast and compact together. */
940 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
941 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
942 error ("FPX fast and compact options cannot be specified together");
944 /* FPX-2. No fast-spfp for arc600 or arc601. */
945 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
946 error ("-mspfp_fast not available on ARC600 or ARC601");
948 /* FPX-4. No FPX extensions mixed with FPU extensions. */
949 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
950 && TARGET_HARD_FLOAT)
951 error ("No FPX/FPU mixing allowed");
953 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
954 if (flag_pic && TARGET_ARC600_FAMILY)
956 warning (0,
957 "PIC is not supported for %s. Generating non-PIC code only..",
958 arc_cpu_string);
959 flag_pic = 0;
962 arc_init_reg_tables ();
964 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
965 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
966 arc_punct_chars['#'] = 1;
967 arc_punct_chars['*'] = 1;
968 arc_punct_chars['?'] = 1;
969 arc_punct_chars['!'] = 1;
970 arc_punct_chars['^'] = 1;
971 arc_punct_chars['&'] = 1;
972 arc_punct_chars['+'] = 1;
973 arc_punct_chars['_'] = 1;
975 if (optimize > 1 && !TARGET_NO_COND_EXEC)
977 /* There are two target-independent ifcvt passes, and arc_reorg may do
978 one or more arc_ifcvt calls. */
979 opt_pass *pass_arc_ifcvt_4 = make_pass_arc_ifcvt (g);
980 struct register_pass_info arc_ifcvt4_info
981 = { pass_arc_ifcvt_4, "dbr", 1, PASS_POS_INSERT_AFTER };
982 struct register_pass_info arc_ifcvt5_info
983 = { pass_arc_ifcvt_4->clone (), "shorten", 1, PASS_POS_INSERT_BEFORE };
985 register_pass (&arc_ifcvt4_info);
986 register_pass (&arc_ifcvt5_info);
989 if (flag_delayed_branch)
991 opt_pass *pass_arc_predicate_delay_insns
992 = make_pass_arc_predicate_delay_insns (g);
993 struct register_pass_info arc_predicate_delay_info
994 = { pass_arc_predicate_delay_insns, "dbr", 1, PASS_POS_INSERT_AFTER };
996 register_pass (&arc_predicate_delay_info);
1000 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1001 register range is specified as two registers separated by a dash.
1002 It always starts with r0, and its upper limit is fp register.
1003 blink and lp_count registers are optional. */
1005 static void
1006 irq_range (const char *cstr)
1008 int i, first, last, blink, lpcount, xreg;
1009 char *str, *dash, *comma;
1011 i = strlen (cstr);
1012 str = (char *) alloca (i + 1);
1013 memcpy (str, cstr, i + 1);
1014 blink = -1;
1015 lpcount = -1;
1017 dash = strchr (str, '-');
1018 if (!dash)
1020 warning (OPT_mirq_ctrl_saved_, "missing dash");
1021 return;
1023 *dash = '\0';
1025 comma = strchr (dash + 1, ',');
1026 if (comma)
1027 *comma = '\0';
1029 first = decode_reg_name (str);
1030 if (first != 0)
1032 warning (OPT_mirq_ctrl_saved_, "first register must be R0");
1033 return;
1036 /* At this moment we do not have the register names initialized
1037 accordingly. */
1038 if (!strcmp (dash + 1, "ilink"))
1039 last = 29;
1040 else
1041 last = decode_reg_name (dash + 1);
1043 if (last < 0)
1045 warning (OPT_mirq_ctrl_saved_, "unknown register name: %s", dash + 1);
1046 return;
1049 if (!(last & 0x01))
1051 warning (OPT_mirq_ctrl_saved_,
1052 "last register name %s must be an odd register", dash + 1);
1053 return;
1056 *dash = '-';
1058 if (first > last)
1060 warning (OPT_mirq_ctrl_saved_,
1061 "%s-%s is an empty range", str, dash + 1);
1062 return;
1065 while (comma)
1067 *comma = ',';
1068 str = comma + 1;
1070 comma = strchr (str, ',');
1071 if (comma)
1072 *comma = '\0';
1074 xreg = decode_reg_name (str);
1075 switch (xreg)
1077 case 31:
1078 blink = 31;
1079 break;
1081 case 60:
1082 lpcount = 60;
1083 break;
1085 default:
1086 warning (OPT_mirq_ctrl_saved_,
1087 "unknown register name: %s", str);
1088 return;
1092 irq_ctrl_saved.irq_save_last_reg = last;
1093 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31);
1094 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60);
1097 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1098 8, 16, or 32. */
1100 static void
1101 parse_mrgf_banked_regs_option (const char *arg)
1103 long int val;
1104 char *end_ptr;
1106 errno = 0;
1107 val = strtol (arg, &end_ptr, 10);
1108 if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
1109 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
1111 error ("invalid number in -mrgf-banked-regs=%s "
1112 "valid values are 0, 4, 8, 16, or 32", arg);
1113 return;
1115 rgf_banked_register_count = (int) val;
1118 /* Check ARC options, generate derived target attributes. */
1120 static void
1121 arc_override_options (void)
1123 unsigned int i;
1124 cl_deferred_option *opt;
1125 vec<cl_deferred_option> *vopt
1126 = (vec<cl_deferred_option> *) arc_deferred_options;
1128 if (arc_cpu == PROCESSOR_NONE)
1129 arc_cpu = TARGET_CPU_DEFAULT;
1131 /* Set the default cpu options. */
1132 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
1134 /* Set the architectures. */
1135 switch (arc_selected_cpu->arch_info->arch_id)
1137 case BASE_ARCH_em:
1138 arc_cpu_string = "EM";
1139 break;
1140 case BASE_ARCH_hs:
1141 arc_cpu_string = "HS";
1142 break;
1143 case BASE_ARCH_700:
1144 if (arc_selected_cpu->processor == PROCESSOR_nps400)
1145 arc_cpu_string = "NPS400";
1146 else
1147 arc_cpu_string = "ARC700";
1148 break;
1149 case BASE_ARCH_6xx:
1150 arc_cpu_string = "ARC600";
1151 break;
1152 default:
1153 gcc_unreachable ();
1156 irq_ctrl_saved.irq_save_last_reg = -1;
1157 irq_ctrl_saved.irq_save_blink = false;
1158 irq_ctrl_saved.irq_save_lpcount = false;
1160 rgf_banked_register_count = 0;
1162 /* Handle the deferred options. */
1163 if (vopt)
1164 FOR_EACH_VEC_ELT (*vopt, i, opt)
1166 switch (opt->opt_index)
1168 case OPT_mirq_ctrl_saved_:
1169 if (TARGET_V2)
1170 irq_range (opt->arg);
1171 else
1172 warning (OPT_mirq_ctrl_saved_,
1173 "option -mirq-ctrl-saved valid only for ARC v2 processors");
1174 break;
1176 case OPT_mrgf_banked_regs_:
1177 if (TARGET_V2)
1178 parse_mrgf_banked_regs_option (opt->arg);
1179 else
1180 warning (OPT_mrgf_banked_regs_,
1181 "option -mrgf-banked-regs valid only for ARC v2 processors");
1182 break;
1184 default:
1185 gcc_unreachable();
1189 CLEAR_HARD_REG_SET (overrideregs);
1190 if (common_deferred_options)
1192 vec<cl_deferred_option> v =
1193 *((vec<cl_deferred_option> *) common_deferred_options);
1194 int reg, nregs, j;
1196 FOR_EACH_VEC_ELT (v, i, opt)
1198 switch (opt->opt_index)
1200 case OPT_ffixed_:
1201 case OPT_fcall_used_:
1202 case OPT_fcall_saved_:
1203 if ((reg = decode_reg_name_and_count (opt->arg, &nregs)) >= 0)
1204 for (j = reg; j < reg + nregs; j++)
1205 SET_HARD_REG_BIT (overrideregs, j);
1206 break;
1207 default:
1208 break;
1213 /* Check options against architecture options. Throw an error if
1214 option is not allowed. Extra, check options against default
1215 architecture/cpu flags and throw an warning if we find a
1216 mismatch. */
1217 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1218 do { \
1219 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1220 && (VAR == VAL)) \
1221 error ("Option %s=%s is not available for %s CPU.", \
1222 DOC0, DOC1, arc_selected_cpu->name); \
1223 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1224 && (VAR != DEFAULT_##VAR) \
1225 && (VAR != VAL)) \
1226 warning (0, "Option %s is ignored, the default value %s" \
1227 " is considered for %s CPU.", DOC0, DOC1, \
1228 arc_selected_cpu->name); \
1229 } while (0);
1230 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1231 do { \
1232 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1233 && (target_flags & MASK)) \
1234 error ("Option %s is not available for %s CPU", \
1235 DOC, arc_selected_cpu->name); \
1236 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1237 && (target_flags_explicit & MASK) \
1238 && (!(target_flags & MASK))) \
1239 warning (0, "Unset option %s is ignored, it is always" \
1240 " enabled for %s CPU.", DOC, \
1241 arc_selected_cpu->name); \
1242 } while (0);
1244 #include "arc-options.def"
1246 #undef ARC_OPTX
1247 #undef ARC_OPT
1249 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1250 specific flags are set in arc-common.c. The architecture forces
1251 the default hardware configurations in, regardless what command
1252 line options are saying. The CPU optional hw options can be
1253 turned on or off. */
1254 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1255 do { \
1256 if ((arc_selected_cpu->flags & CODE) \
1257 && ((target_flags_explicit & MASK) == 0)) \
1258 target_flags |= MASK; \
1259 if (arc_selected_cpu->arch_info->dflags & CODE) \
1260 target_flags |= MASK; \
1261 } while (0);
1262 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1263 do { \
1264 if ((arc_selected_cpu->flags & CODE) \
1265 && (VAR == DEFAULT_##VAR)) \
1266 VAR = VAL; \
1267 if (arc_selected_cpu->arch_info->dflags & CODE) \
1268 VAR = VAL; \
1269 } while (0);
1271 #include "arc-options.def"
1273 #undef ARC_OPTX
1274 #undef ARC_OPT
1276 /* Set extras. */
1277 switch (arc_selected_cpu->extra)
1279 case HAS_LPCOUNT_16:
1280 arc_lpcwidth = 16;
1281 break;
1282 default:
1283 break;
1286 /* Set Tune option. */
1287 if (arc_tune == ARC_TUNE_NONE)
1288 arc_tune = (enum arc_tune_attr) arc_selected_cpu->tune;
1290 if (arc_size_opt_level == 3)
1291 optimize_size = 1;
1293 /* Compact casesi is not a valid option for ARCv2 family. */
1294 if (TARGET_V2)
1296 if (TARGET_COMPACT_CASESI)
1298 warning (OPT_mcompact_casesi,
1299 "compact-casesi is not applicable to ARCv2");
1300 TARGET_COMPACT_CASESI = 0;
1303 else if (optimize_size == 1
1304 && !global_options_set.x_TARGET_COMPACT_CASESI)
1305 TARGET_COMPACT_CASESI = 1;
1307 if (flag_pic)
1308 target_flags |= MASK_NO_SDATA_SET;
1310 if (flag_no_common == 255)
1311 flag_no_common = !TARGET_NO_SDATA_SET;
1313 /* TARGET_COMPACT_CASESI needs the "q" register class. */
1314 if (TARGET_MIXED_CODE)
1315 TARGET_Q_CLASS = 1;
1316 if (!TARGET_Q_CLASS)
1317 TARGET_COMPACT_CASESI = 0;
1318 if (TARGET_COMPACT_CASESI)
1319 TARGET_CASE_VECTOR_PC_RELATIVE = 1;
1321 /* Check for small data option */
1322 if (!global_options_set.x_g_switch_value && !TARGET_NO_SDATA_SET)
1323 g_switch_value = TARGET_LL64 ? 8 : 4;
1325 /* These need to be done at start up. It's convenient to do them here. */
1326 arc_init ();
1329 /* The condition codes of the ARC, and the inverse function. */
1330 /* For short branches, the "c" / "nc" names are not defined in the ARC
1331 Programmers manual, so we have to use "lo" / "hs"" instead. */
1332 static const char *arc_condition_codes[] =
1334 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1335 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1338 enum arc_cc_code_index
1340 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
1341 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
1342 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
1343 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
1346 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1348 /* Returns the index of the ARC condition code string in
1349 `arc_condition_codes'. COMPARISON should be an rtx like
1350 `(eq (...) (...))'. */
1352 static int
1353 get_arc_condition_code (rtx comparison)
1355 switch (GET_MODE (XEXP (comparison, 0)))
1357 case E_CCmode:
1358 case E_SImode: /* For BRcc. */
1359 switch (GET_CODE (comparison))
1361 case EQ : return ARC_CC_EQ;
1362 case NE : return ARC_CC_NE;
1363 case GT : return ARC_CC_GT;
1364 case LE : return ARC_CC_LE;
1365 case GE : return ARC_CC_GE;
1366 case LT : return ARC_CC_LT;
1367 case GTU : return ARC_CC_HI;
1368 case LEU : return ARC_CC_LS;
1369 case LTU : return ARC_CC_LO;
1370 case GEU : return ARC_CC_HS;
1371 default : gcc_unreachable ();
1373 case E_CC_ZNmode:
1374 switch (GET_CODE (comparison))
1376 case EQ : return ARC_CC_EQ;
1377 case NE : return ARC_CC_NE;
1378 case GE: return ARC_CC_P;
1379 case LT: return ARC_CC_N;
1380 case GT : return ARC_CC_PNZ;
1381 default : gcc_unreachable ();
1383 case E_CC_Zmode:
1384 switch (GET_CODE (comparison))
1386 case EQ : return ARC_CC_EQ;
1387 case NE : return ARC_CC_NE;
1388 default : gcc_unreachable ();
1390 case E_CC_Cmode:
1391 switch (GET_CODE (comparison))
1393 case LTU : return ARC_CC_C;
1394 case GEU : return ARC_CC_NC;
1395 default : gcc_unreachable ();
1397 case E_CC_FP_GTmode:
1398 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1399 switch (GET_CODE (comparison))
1401 case GT : return ARC_CC_N;
1402 case UNLE: return ARC_CC_P;
1403 default : gcc_unreachable ();
1405 else
1406 switch (GET_CODE (comparison))
1408 case GT : return ARC_CC_HI;
1409 case UNLE : return ARC_CC_LS;
1410 default : gcc_unreachable ();
1412 case E_CC_FP_GEmode:
1413 /* Same for FPX and non-FPX. */
1414 switch (GET_CODE (comparison))
1416 case GE : return ARC_CC_HS;
1417 case UNLT : return ARC_CC_LO;
1418 default : gcc_unreachable ();
1420 case E_CC_FP_UNEQmode:
1421 switch (GET_CODE (comparison))
1423 case UNEQ : return ARC_CC_EQ;
1424 case LTGT : return ARC_CC_NE;
1425 default : gcc_unreachable ();
1427 case E_CC_FP_ORDmode:
1428 switch (GET_CODE (comparison))
1430 case UNORDERED : return ARC_CC_C;
1431 case ORDERED : return ARC_CC_NC;
1432 default : gcc_unreachable ();
1434 case E_CC_FPXmode:
1435 switch (GET_CODE (comparison))
1437 case EQ : return ARC_CC_EQ;
1438 case NE : return ARC_CC_NE;
1439 case UNORDERED : return ARC_CC_C;
1440 case ORDERED : return ARC_CC_NC;
1441 case LTGT : return ARC_CC_HI;
1442 case UNEQ : return ARC_CC_LS;
1443 default : gcc_unreachable ();
1445 case E_CC_FPUmode:
1446 switch (GET_CODE (comparison))
1448 case EQ : return ARC_CC_EQ;
1449 case NE : return ARC_CC_NE;
1450 case GT : return ARC_CC_GT;
1451 case GE : return ARC_CC_GE;
1452 case LT : return ARC_CC_C;
1453 case LE : return ARC_CC_LS;
1454 case UNORDERED : return ARC_CC_V;
1455 case ORDERED : return ARC_CC_NV;
1456 case UNGT : return ARC_CC_HI;
1457 case UNGE : return ARC_CC_HS;
1458 case UNLT : return ARC_CC_LT;
1459 case UNLE : return ARC_CC_LE;
1460 /* UNEQ and LTGT do not have representation. */
1461 case LTGT : /* Fall through. */
1462 case UNEQ : /* Fall through. */
1463 default : gcc_unreachable ();
1465 case E_CC_FPU_UNEQmode:
1466 switch (GET_CODE (comparison))
1468 case LTGT : return ARC_CC_NE;
1469 case UNEQ : return ARC_CC_EQ;
1470 default : gcc_unreachable ();
1472 default : gcc_unreachable ();
1474 /*NOTREACHED*/
1475 return (42);
1478 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1480 bool
1481 arc_short_comparison_p (rtx comparison, int offset)
1483 gcc_assert (ARC_CC_NC == ARC_CC_HS);
1484 gcc_assert (ARC_CC_C == ARC_CC_LO);
1485 switch (get_arc_condition_code (comparison))
1487 case ARC_CC_EQ: case ARC_CC_NE:
1488 return offset >= -512 && offset <= 506;
1489 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
1490 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
1491 return offset >= -64 && offset <= 58;
1492 default:
1493 return false;
1497 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1498 return the mode to be used for the comparison. */
1500 machine_mode
1501 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1503 machine_mode mode = GET_MODE (x);
1504 rtx x1;
1506 /* For an operation that sets the condition codes as a side-effect, the
1507 C and V flags is not set as for cmp, so we can only use comparisons where
1508 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1509 instead.) */
1510 /* ??? We could use "pnz" for greater than zero, however, we could then
1511 get into trouble because the comparison could not be reversed. */
1512 if (GET_MODE_CLASS (mode) == MODE_INT
1513 && y == const0_rtx
1514 && (op == EQ || op == NE
1515 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
1516 return CC_ZNmode;
1518 /* add.f for if (a+b) */
1519 if (mode == SImode
1520 && GET_CODE (y) == NEG
1521 && (op == EQ || op == NE))
1522 return CC_ZNmode;
1524 /* Check if this is a test suitable for bxor.f . */
1525 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1526 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1527 && INTVAL (y))
1528 return CC_Zmode;
1530 /* Check if this is a test suitable for add / bmsk.f . */
1531 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1532 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1533 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1534 && (~INTVAL (x1) | INTVAL (y)) < 0
1535 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1536 return CC_Zmode;
1538 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1539 && GET_CODE (x) == PLUS
1540 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1541 return CC_Cmode;
1543 if (TARGET_ARGONAUT_SET
1544 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1545 switch (op)
1547 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1548 return CC_FPXmode;
1549 case LT: case UNGE: case GT: case UNLE:
1550 return CC_FP_GTmode;
1551 case LE: case UNGT: case GE: case UNLT:
1552 return CC_FP_GEmode;
1553 default: gcc_unreachable ();
1555 else if (TARGET_HARD_FLOAT
1556 && ((mode == SFmode && TARGET_FP_SP_BASE)
1557 || (mode == DFmode && TARGET_FP_DP_BASE)))
1558 switch (op)
1560 case EQ:
1561 case NE:
1562 case UNORDERED:
1563 case ORDERED:
1564 case UNLT:
1565 case UNLE:
1566 case UNGT:
1567 case UNGE:
1568 case LT:
1569 case LE:
1570 case GT:
1571 case GE:
1572 return CC_FPUmode;
1574 case LTGT:
1575 case UNEQ:
1576 return CC_FPU_UNEQmode;
1578 default:
1579 gcc_unreachable ();
1581 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1583 switch (op)
1585 case EQ: case NE: return CC_Zmode;
1586 case LT: case UNGE:
1587 case GT: case UNLE: return CC_FP_GTmode;
1588 case LE: case UNGT:
1589 case GE: case UNLT: return CC_FP_GEmode;
1590 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1591 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1592 default: gcc_unreachable ();
1595 return CCmode;
1598 /* Vectors to keep interesting information about registers where it can easily
1599 be got. We use to use the actual mode value as the bit number, but there
1600 is (or may be) more than 32 modes now. Instead we use two tables: one
1601 indexed by hard register number, and one indexed by mode. */
1603 /* The purpose of arc_mode_class is to shrink the range of modes so that
1604 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1605 mapped into one arc_mode_class mode. */
1607 enum arc_mode_class {
1608 C_MODE,
1609 S_MODE, D_MODE, T_MODE, O_MODE,
1610 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1611 V_MODE
1614 /* Modes for condition codes. */
1615 #define C_MODES (1 << (int) C_MODE)
1617 /* Modes for single-word and smaller quantities. */
1618 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1620 /* Modes for double-word and smaller quantities. */
1621 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1623 /* Mode for 8-byte DF values only. */
1624 #define DF_MODES (1 << DF_MODE)
1626 /* Modes for quad-word and smaller quantities. */
1627 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1629 /* Modes for 128-bit vectors. */
1630 #define V_MODES (1 << (int) V_MODE)
1632 /* Value is 1 if register/mode pair is acceptable on arc. */
1634 static unsigned int arc_hard_regno_modes[] = {
1635 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1636 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1637 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1638 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1640 /* ??? Leave these as S_MODES for now. */
1641 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1642 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1643 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1644 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1646 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1647 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1648 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1649 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1651 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1652 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1653 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1654 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1656 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1657 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES
1660 static unsigned int arc_mode_class [NUM_MACHINE_MODES];
1662 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1664 enum reg_class
1665 arc_preferred_reload_class (rtx, enum reg_class cl)
1667 if ((cl) == CHEAP_CORE_REGS || (cl) == WRITABLE_CORE_REGS)
1668 return GENERAL_REGS;
1669 return cl;
1672 /* Initialize the arc_mode_class array. */
1674 static void
1675 arc_init_reg_tables (void)
1677 int i;
1679 for (i = 0; i < NUM_MACHINE_MODES; i++)
1681 machine_mode m = (machine_mode) i;
1683 switch (GET_MODE_CLASS (m))
1685 case MODE_INT:
1686 case MODE_PARTIAL_INT:
1687 case MODE_COMPLEX_INT:
1688 if (GET_MODE_SIZE (m) <= 4)
1689 arc_mode_class[i] = 1 << (int) S_MODE;
1690 else if (GET_MODE_SIZE (m) == 8)
1691 arc_mode_class[i] = 1 << (int) D_MODE;
1692 else if (GET_MODE_SIZE (m) == 16)
1693 arc_mode_class[i] = 1 << (int) T_MODE;
1694 else if (GET_MODE_SIZE (m) == 32)
1695 arc_mode_class[i] = 1 << (int) O_MODE;
1696 else
1697 arc_mode_class[i] = 0;
1698 break;
1699 case MODE_FLOAT:
1700 case MODE_COMPLEX_FLOAT:
1701 if (GET_MODE_SIZE (m) <= 4)
1702 arc_mode_class[i] = 1 << (int) SF_MODE;
1703 else if (GET_MODE_SIZE (m) == 8)
1704 arc_mode_class[i] = 1 << (int) DF_MODE;
1705 else if (GET_MODE_SIZE (m) == 16)
1706 arc_mode_class[i] = 1 << (int) TF_MODE;
1707 else if (GET_MODE_SIZE (m) == 32)
1708 arc_mode_class[i] = 1 << (int) OF_MODE;
1709 else
1710 arc_mode_class[i] = 0;
1711 break;
1712 case MODE_VECTOR_INT:
1713 if (GET_MODE_SIZE (m) == 4)
1714 arc_mode_class[i] = (1 << (int) S_MODE);
1715 else if (GET_MODE_SIZE (m) == 8)
1716 arc_mode_class[i] = (1 << (int) D_MODE);
1717 else
1718 arc_mode_class[i] = (1 << (int) V_MODE);
1719 break;
1720 case MODE_CC:
1721 default:
1722 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1723 we must explicitly check for them here. */
1724 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1725 || i == (int) CC_Cmode
1726 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
1727 || i == CC_FPUmode || i == CC_FPU_UNEQmode)
1728 arc_mode_class[i] = 1 << (int) C_MODE;
1729 else
1730 arc_mode_class[i] = 0;
1731 break;
1736 /* Core registers 56..59 are used for multiply extension options.
1737 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1738 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1739 number depends on endianness.
1740 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1741 Because mlo / mhi form a 64 bit value, we use different gcc internal
1742 register numbers to make them form a register pair as the gcc internals
1743 know it. mmid gets number 57, if still available, and mlo / mhi get
1744 number 58 and 59, depending on endianness. We use DBX_REGISTER_NUMBER
1745 to map this back. */
1746 char rname56[5] = "r56";
1747 char rname57[5] = "r57";
1748 char rname58[5] = "r58";
1749 char rname59[5] = "r59";
1750 char rname29[7] = "ilink1";
1751 char rname30[7] = "ilink2";
1753 static void
1754 arc_conditional_register_usage (void)
1756 int regno;
1757 int i;
1758 int fix_start = 60, fix_end = 55;
1760 if (TARGET_V2)
1762 /* For ARCv2 the core register set is changed. */
1763 strcpy (rname29, "ilink");
1764 strcpy (rname30, "r30");
1766 if (!TEST_HARD_REG_BIT (overrideregs, 30))
1768 /* No user interference. Set the r30 to be used by the
1769 compiler. */
1770 call_used_regs[30] = 1;
1771 fixed_regs[30] = 0;
1773 arc_regno_reg_class[30] = WRITABLE_CORE_REGS;
1774 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], 30);
1775 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], 30);
1776 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], 30);
1777 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], 30);
1781 if (TARGET_MUL64_SET)
1783 fix_start = 57;
1784 fix_end = 59;
1786 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1787 you are supposed to refer to it as mlo & mhi, e.g
1788 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1789 In an actual asm instruction, you are of course use mmed.
1790 The point of avoiding having a separate register for mmed is that
1791 this way, we don't have to carry clobbers of that reg around in every
1792 isntruction that modifies mlo and/or mhi. */
1793 strcpy (rname57, "");
1794 strcpy (rname58, TARGET_BIG_ENDIAN ? "mhi" : "mlo");
1795 strcpy (rname59, TARGET_BIG_ENDIAN ? "mlo" : "mhi");
1798 /* The nature of arc_tp_regno is actually something more like a global
1799 register, however globalize_reg requires a declaration.
1800 We use EPILOGUE_USES to compensate so that sets from
1801 __builtin_set_frame_pointer are not deleted. */
1802 if (arc_tp_regno != -1)
1803 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1;
1805 if (TARGET_MULMAC_32BY16_SET)
1807 fix_start = 56;
1808 fix_end = fix_end > 57 ? fix_end : 57;
1809 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1810 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1812 for (regno = fix_start; regno <= fix_end; regno++)
1814 if (!fixed_regs[regno])
1815 warning (0, "multiply option implies r%d is fixed", regno);
1816 fixed_regs [regno] = call_used_regs[regno] = 1;
1818 if (TARGET_Q_CLASS)
1820 if (optimize_size)
1822 reg_alloc_order[0] = 0;
1823 reg_alloc_order[1] = 1;
1824 reg_alloc_order[2] = 2;
1825 reg_alloc_order[3] = 3;
1826 reg_alloc_order[4] = 12;
1827 reg_alloc_order[5] = 13;
1828 reg_alloc_order[6] = 14;
1829 reg_alloc_order[7] = 15;
1830 reg_alloc_order[8] = 4;
1831 reg_alloc_order[9] = 5;
1832 reg_alloc_order[10] = 6;
1833 reg_alloc_order[11] = 7;
1834 reg_alloc_order[12] = 8;
1835 reg_alloc_order[13] = 9;
1836 reg_alloc_order[14] = 10;
1837 reg_alloc_order[15] = 11;
1839 else
1841 reg_alloc_order[2] = 12;
1842 reg_alloc_order[3] = 13;
1843 reg_alloc_order[4] = 14;
1844 reg_alloc_order[5] = 15;
1845 reg_alloc_order[6] = 1;
1846 reg_alloc_order[7] = 0;
1847 reg_alloc_order[8] = 4;
1848 reg_alloc_order[9] = 5;
1849 reg_alloc_order[10] = 6;
1850 reg_alloc_order[11] = 7;
1851 reg_alloc_order[12] = 8;
1852 reg_alloc_order[13] = 9;
1853 reg_alloc_order[14] = 10;
1854 reg_alloc_order[15] = 11;
1857 if (TARGET_SIMD_SET)
1859 int i;
1860 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1861 reg_alloc_order [i] = i;
1862 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1863 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1864 reg_alloc_order [i] = i;
1867 /* Reduced configuration: don't use r4-r9, r16-r25. */
1868 if (TARGET_RF16)
1870 for (i = 4; i <= 9; i++)
1872 fixed_regs[i] = call_used_regs[i] = 1;
1874 for (i = 16; i <= 25; i++)
1876 fixed_regs[i] = call_used_regs[i] = 1;
1880 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; regno++)
1881 if (!call_used_regs[regno])
1882 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], regno);
1883 for (regno = 32; regno < 60; regno++)
1884 if (!fixed_regs[regno])
1885 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], regno);
1886 if (!TARGET_ARC600_FAMILY)
1888 for (regno = 32; regno <= 60; regno++)
1889 CLEAR_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], regno);
1891 /* If they have used -ffixed-lp_count, make sure it takes
1892 effect. */
1893 if (fixed_regs[LP_COUNT])
1895 CLEAR_HARD_REG_BIT (reg_class_contents[LPCOUNT_REG], LP_COUNT);
1896 CLEAR_HARD_REG_BIT (reg_class_contents[SIBCALL_REGS], LP_COUNT);
1897 CLEAR_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], LP_COUNT);
1899 /* Instead of taking out SF_MODE like below, forbid it outright. */
1900 arc_hard_regno_modes[60] = 0;
1902 else
1903 arc_hard_regno_modes[60] = 1 << (int) S_MODE;
1906 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1907 registers. */
1908 if (TARGET_HS)
1910 for (regno = 1; regno < 32; regno +=2)
1912 arc_hard_regno_modes[regno] = S_MODES;
1916 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1918 if (i < 29)
1920 if ((TARGET_Q_CLASS || TARGET_RRQ_CLASS)
1921 && ((i <= 3) || ((i >= 12) && (i <= 15))))
1922 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1923 else
1924 arc_regno_reg_class[i] = GENERAL_REGS;
1926 else if (i < 60)
1927 arc_regno_reg_class[i]
1928 = (fixed_regs[i]
1929 ? (TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i)
1930 ? CHEAP_CORE_REGS : ALL_CORE_REGS)
1931 : (((!TARGET_ARC600_FAMILY)
1932 && TEST_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], i))
1933 ? CHEAP_CORE_REGS : WRITABLE_CORE_REGS));
1934 else
1935 arc_regno_reg_class[i] = NO_REGS;
1938 /* ARCOMPACT16_REGS is empty, if TARGET_Q_CLASS / TARGET_RRQ_CLASS
1939 has not been activated. */
1940 if (!TARGET_Q_CLASS && !TARGET_RRQ_CLASS)
1941 CLEAR_HARD_REG_SET(reg_class_contents [ARCOMPACT16_REGS]);
1942 if (!TARGET_Q_CLASS)
1943 CLEAR_HARD_REG_SET(reg_class_contents [AC16_BASE_REGS]);
1945 gcc_assert (FIRST_PSEUDO_REGISTER >= 144);
1947 /* Handle Special Registers. */
1948 arc_regno_reg_class[29] = LINK_REGS; /* ilink1 register. */
1949 if (!TARGET_V2)
1950 arc_regno_reg_class[30] = LINK_REGS; /* ilink2 register. */
1951 arc_regno_reg_class[31] = LINK_REGS; /* blink register. */
1952 arc_regno_reg_class[60] = LPCOUNT_REG;
1953 arc_regno_reg_class[61] = NO_REGS; /* CC_REG: must be NO_REGS. */
1954 arc_regno_reg_class[62] = GENERAL_REGS;
1956 if (TARGET_DPFP)
1958 for (i = 40; i < 44; ++i)
1960 arc_regno_reg_class[i] = DOUBLE_REGS;
1962 /* Unless they want us to do 'mov d1, 0x00000000' make sure
1963 no attempt is made to use such a register as a destination
1964 operand in *movdf_insn. */
1965 if (!TARGET_ARGONAUT_SET)
1967 /* Make sure no 'c', 'w', 'W', or 'Rac' constraint is
1968 interpreted to mean they can use D1 or D2 in their insn. */
1969 CLEAR_HARD_REG_BIT(reg_class_contents[CHEAP_CORE_REGS ], i);
1970 CLEAR_HARD_REG_BIT(reg_class_contents[ALL_CORE_REGS ], i);
1971 CLEAR_HARD_REG_BIT(reg_class_contents[WRITABLE_CORE_REGS ], i);
1972 CLEAR_HARD_REG_BIT(reg_class_contents[MPY_WRITABLE_CORE_REGS], i);
1976 else
1978 /* Disable all DOUBLE_REGISTER settings,
1979 if not generating DPFP code. */
1980 arc_regno_reg_class[40] = ALL_REGS;
1981 arc_regno_reg_class[41] = ALL_REGS;
1982 arc_regno_reg_class[42] = ALL_REGS;
1983 arc_regno_reg_class[43] = ALL_REGS;
1985 fixed_regs[40] = 1;
1986 fixed_regs[41] = 1;
1987 fixed_regs[42] = 1;
1988 fixed_regs[43] = 1;
1990 arc_hard_regno_modes[40] = 0;
1991 arc_hard_regno_modes[42] = 0;
1993 CLEAR_HARD_REG_SET(reg_class_contents [DOUBLE_REGS]);
1996 if (TARGET_SIMD_SET)
1998 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1999 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
2001 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
2002 arc_regno_reg_class [i] = SIMD_VR_REGS;
2004 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
2005 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
2006 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
2007 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
2009 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
2010 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
2011 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
2014 /* pc : r63 */
2015 arc_regno_reg_class[PROGRAM_COUNTER_REGNO] = GENERAL_REGS;
2017 /*ARCV2 Accumulator. */
2018 if ((TARGET_V2
2019 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
2020 || TARGET_PLUS_DMPY)
2022 arc_regno_reg_class[ACCL_REGNO] = WRITABLE_CORE_REGS;
2023 arc_regno_reg_class[ACCH_REGNO] = WRITABLE_CORE_REGS;
2024 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCL_REGNO);
2025 SET_HARD_REG_BIT (reg_class_contents[WRITABLE_CORE_REGS], ACCH_REGNO);
2026 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCL_REGNO);
2027 SET_HARD_REG_BIT (reg_class_contents[CHEAP_CORE_REGS], ACCH_REGNO);
2028 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCL_REGNO);
2029 SET_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], ACCH_REGNO);
2030 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCL_REGNO);
2031 SET_HARD_REG_BIT (reg_class_contents[MPY_WRITABLE_CORE_REGS], ACCH_REGNO);
2033 /* Allow the compiler to freely use them. */
2034 if (!TEST_HARD_REG_BIT (overrideregs, ACCL_REGNO))
2035 fixed_regs[ACCL_REGNO] = 0;
2036 if (!TEST_HARD_REG_BIT (overrideregs, ACCH_REGNO))
2037 fixed_regs[ACCH_REGNO] = 0;
2039 if (!fixed_regs[ACCH_REGNO] && !fixed_regs[ACCL_REGNO])
2040 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES;
2044 /* Implement TARGET_HARD_REGNO_NREGS. */
2046 static unsigned int
2047 arc_hard_regno_nregs (unsigned int regno, machine_mode mode)
2049 if (GET_MODE_SIZE (mode) == 16
2050 && regno >= ARC_FIRST_SIMD_VR_REG
2051 && regno <= ARC_LAST_SIMD_VR_REG)
2052 return 1;
2054 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
2057 /* Implement TARGET_HARD_REGNO_MODE_OK. */
2059 static bool
2060 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
2062 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0;
2065 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
2067 static bool
2068 arc_modes_tieable_p (machine_mode mode1, machine_mode mode2)
2070 return (GET_MODE_CLASS (mode1) == MODE_INT
2071 && GET_MODE_CLASS (mode2) == MODE_INT
2072 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
2073 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
2076 /* Handle an "interrupt" attribute; arguments as in
2077 struct attribute_spec.handler. */
2079 static tree
2080 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
2081 bool *no_add_attrs)
2083 gcc_assert (args);
2085 tree value = TREE_VALUE (args);
2087 if (TREE_CODE (value) != STRING_CST)
2089 warning (OPT_Wattributes,
2090 "argument of %qE attribute is not a string constant",
2091 name);
2092 *no_add_attrs = true;
2094 else if (!TARGET_V2
2095 && strcmp (TREE_STRING_POINTER (value), "ilink1")
2096 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
2098 warning (OPT_Wattributes,
2099 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2100 name);
2101 *no_add_attrs = true;
2103 else if (TARGET_V2
2104 && strcmp (TREE_STRING_POINTER (value), "ilink")
2105 && strcmp (TREE_STRING_POINTER (value), "firq"))
2107 warning (OPT_Wattributes,
2108 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2109 name);
2110 *no_add_attrs = true;
2113 return NULL_TREE;
2116 static tree
2117 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
2118 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
2120 if (TREE_CODE (*node) != FUNCTION_DECL)
2122 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2123 name);
2124 *no_add_attrs = true;
2127 return NULL_TREE;
2130 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2132 static bool
2133 arc_allocate_stack_slots_for_args (void)
2135 /* Naked functions should not allocate stack slots for arguments. */
2136 unsigned int fn_type = arc_compute_function_type (cfun);
2138 return !ARC_NAKED_P(fn_type);
2141 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2143 static bool
2144 arc_warn_func_return (tree decl)
2146 struct function *func = DECL_STRUCT_FUNCTION (decl);
2147 unsigned int fn_type = arc_compute_function_type (func);
2149 return !ARC_NAKED_P (fn_type);
2152 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2153 and two if they are nearly compatible (which causes a warning to be
2154 generated). */
2156 static int
2157 arc_comp_type_attributes (const_tree type1,
2158 const_tree type2)
2160 int l1, l2, m1, m2, s1, s2;
2162 /* Check for mismatch of non-default calling convention. */
2163 if (TREE_CODE (type1) != FUNCTION_TYPE)
2164 return 1;
2166 /* Check for mismatched call attributes. */
2167 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
2168 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
2169 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
2170 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
2171 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
2172 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
2174 /* Only bother to check if an attribute is defined. */
2175 if (l1 | l2 | m1 | m2 | s1 | s2)
2177 /* If one type has an attribute, the other must have the same attribute. */
2178 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
2179 return 0;
2181 /* Disallow mixed attributes. */
2182 if (l1 + m1 + s1 > 1)
2183 return 0;
2187 return 1;
2190 /* Misc. utilities. */
2192 /* X and Y are two things to compare using CODE. Emit the compare insn and
2193 return the rtx for the cc reg in the proper mode. */
2196 gen_compare_reg (rtx comparison, machine_mode omode)
2198 enum rtx_code code = GET_CODE (comparison);
2199 rtx x = XEXP (comparison, 0);
2200 rtx y = XEXP (comparison, 1);
2201 rtx tmp, cc_reg;
2202 machine_mode mode, cmode;
2205 cmode = GET_MODE (x);
2206 if (cmode == VOIDmode)
2207 cmode = GET_MODE (y);
2208 gcc_assert (cmode == SImode || cmode == SFmode || cmode == DFmode);
2209 if (cmode == SImode)
2211 if (!register_operand (x, SImode))
2213 if (register_operand (y, SImode))
2215 tmp = x;
2216 x = y;
2217 y = tmp;
2218 code = swap_condition (code);
2220 else
2221 x = copy_to_mode_reg (SImode, x);
2223 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
2224 y = copy_to_mode_reg (SImode, y);
2226 else
2228 x = force_reg (cmode, x);
2229 y = force_reg (cmode, y);
2231 mode = SELECT_CC_MODE (code, x, y);
2233 cc_reg = gen_rtx_REG (mode, CC_REG);
2235 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2236 cmpdfpx_raw, is not a correct comparison for floats:
2237 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2239 if (TARGET_ARGONAUT_SET
2240 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2242 switch (code)
2244 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
2245 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2246 break;
2247 case GT: case UNLE: case GE: case UNLT:
2248 code = swap_condition (code);
2249 tmp = x;
2250 x = y;
2251 y = tmp;
2252 break;
2253 default:
2254 gcc_unreachable ();
2256 if (cmode == SFmode)
2258 emit_insn (gen_cmpsfpx_raw (x, y));
2260 else /* DFmode */
2262 /* Accepts Dx regs directly by insns. */
2263 emit_insn (gen_cmpdfpx_raw (x, y));
2266 if (mode != CC_FPXmode)
2267 emit_insn (gen_rtx_SET (cc_reg,
2268 gen_rtx_COMPARE (mode,
2269 gen_rtx_REG (CC_FPXmode, 61),
2270 const0_rtx)));
2272 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2274 switch (code)
2276 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2277 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2278 break;
2279 case LT: case UNGE: case LE: case UNGT:
2280 code = swap_condition (code);
2281 tmp = x;
2282 x = y;
2283 y = tmp;
2284 break;
2285 default:
2286 gcc_unreachable ();
2289 emit_insn (gen_cmp_quark (cc_reg,
2290 gen_rtx_COMPARE (mode, x, y)));
2292 else if (TARGET_HARD_FLOAT
2293 && ((cmode == SFmode && TARGET_FP_SP_BASE)
2294 || (cmode == DFmode && TARGET_FP_DP_BASE)))
2295 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2296 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
2298 rtx op0 = gen_rtx_REG (cmode, 0);
2299 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
2300 bool swap = false;
2302 switch (code)
2304 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2305 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2306 break;
2307 case LT: case UNGE: case LE: case UNGT:
2308 code = swap_condition (code);
2309 swap = true;
2310 break;
2311 default:
2312 gcc_unreachable ();
2314 if (currently_expanding_to_rtl)
2316 if (swap)
2318 tmp = x;
2319 x = y;
2320 y = tmp;
2322 emit_move_insn (op0, x);
2323 emit_move_insn (op1, y);
2325 else
2327 gcc_assert (rtx_equal_p (op0, x));
2328 gcc_assert (rtx_equal_p (op1, y));
2329 if (swap)
2331 op0 = y;
2332 op1 = x;
2335 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2337 else
2338 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2339 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
2342 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2343 We assume the value can be either signed or unsigned. */
2345 bool
2346 arc_double_limm_p (rtx value)
2348 HOST_WIDE_INT low, high;
2350 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2352 if (TARGET_DPFP)
2353 return true;
2355 low = CONST_DOUBLE_LOW (value);
2356 high = CONST_DOUBLE_HIGH (value);
2358 if (low & 0x80000000)
2360 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
2361 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
2362 == - (unsigned HOST_WIDE_INT) 0x80000000)
2363 && high == -1));
2365 else
2367 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2371 /* Do any needed setup for a variadic function. For the ARC, we must
2372 create a register parameter block, and then copy any anonymous arguments
2373 in registers to memory.
2375 CUM has not been updated for the last named argument which has type TYPE
2376 and mode MODE, and we rely on this fact. */
2378 static void
2379 arc_setup_incoming_varargs (cumulative_args_t args_so_far,
2380 machine_mode mode, tree type,
2381 int *pretend_size, int no_rtl)
2383 int first_anon_arg;
2384 CUMULATIVE_ARGS next_cum;
2386 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2388 next_cum = *get_cumulative_args (args_so_far);
2389 arc_function_arg_advance (pack_cumulative_args (&next_cum),
2390 mode, type, true);
2391 first_anon_arg = next_cum;
2393 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2395 /* First anonymous (unnamed) argument is in a reg. */
2397 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2398 int first_reg_offset = first_anon_arg;
2400 if (!no_rtl)
2402 rtx regblock
2403 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2404 FIRST_PARM_OFFSET (0)));
2405 move_block_from_reg (first_reg_offset, regblock,
2406 MAX_ARC_PARM_REGS - first_reg_offset);
2409 *pretend_size
2410 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2414 /* Cost functions. */
2416 /* Provide the costs of an addressing mode that contains ADDR.
2417 If ADDR is not a valid address, its cost is irrelevant. */
2419 static int
2420 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2422 switch (GET_CODE (addr))
2424 case REG :
2425 return speed || satisfies_constraint_Rcq (addr) ? 0 : 1;
2426 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2427 case PRE_MODIFY: case POST_MODIFY:
2428 return !speed;
2430 case LABEL_REF :
2431 case SYMBOL_REF :
2432 case CONST :
2433 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2434 return 0;
2435 /* Most likely needs a LIMM. */
2436 return COSTS_N_INSNS (1);
2438 case PLUS :
2440 register rtx plus0 = XEXP (addr, 0);
2441 register rtx plus1 = XEXP (addr, 1);
2443 if (GET_CODE (plus0) != REG
2444 && (GET_CODE (plus0) != MULT
2445 || !CONST_INT_P (XEXP (plus0, 1))
2446 || (INTVAL (XEXP (plus0, 1)) != 2
2447 && INTVAL (XEXP (plus0, 1)) != 4)))
2448 break;
2450 switch (GET_CODE (plus1))
2452 case CONST_INT :
2453 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2454 ? COSTS_N_INSNS (1)
2455 : speed
2457 : (satisfies_constraint_Rcq (plus0)
2458 && satisfies_constraint_O (plus1))
2460 : 1);
2461 case REG:
2462 return (speed < 1 ? 0
2463 : (satisfies_constraint_Rcq (plus0)
2464 && satisfies_constraint_Rcq (plus1))
2465 ? 0 : 1);
2466 case CONST :
2467 case SYMBOL_REF :
2468 case LABEL_REF :
2469 return COSTS_N_INSNS (1);
2470 default:
2471 break;
2473 break;
2475 default:
2476 break;
2479 return 4;
2482 /* Emit instruction X with the frame related bit set. */
2484 static rtx
2485 frame_insn (rtx x)
2487 x = emit_insn (x);
2488 RTX_FRAME_RELATED_P (x) = 1;
2489 return x;
2492 /* Emit a frame insn to move SRC to DST. */
2494 static rtx
2495 frame_move (rtx dst, rtx src)
2497 rtx tmp = gen_rtx_SET (dst, src);
2498 RTX_FRAME_RELATED_P (tmp) = 1;
2499 return frame_insn (tmp);
2502 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2503 auto increment address, or is zero. */
2505 static rtx
2506 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2508 rtx insn = frame_move (dst, src);
2510 if (!addr
2511 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2512 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2513 add_reg_note (insn, REG_INC, reg);
2514 return insn;
2517 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2519 static rtx
2520 frame_add (rtx reg, HOST_WIDE_INT offset)
2522 gcc_assert ((offset & 0x3) == 0);
2523 if (!offset)
2524 return NULL_RTX;
2525 return frame_move (reg, plus_constant (Pmode, reg, offset));
2528 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2530 static rtx
2531 frame_stack_add (HOST_WIDE_INT offset)
2533 return frame_add (stack_pointer_rtx, offset);
2536 /* Traditionally, we push saved registers first in the prologue,
2537 then we allocate the rest of the frame - and reverse in the epilogue.
2538 This has still its merits for ease of debugging, or saving code size
2539 or even execution time if the stack frame is so large that some accesses
2540 can't be encoded anymore with offsets in the instruction code when using
2541 a different scheme.
2542 Also, it would be a good starting point if we got instructions to help
2543 with register save/restore.
2545 However, often stack frames are small, and the pushing / popping has
2546 some costs:
2547 - the stack modification prevents a lot of scheduling.
2548 - frame allocation / deallocation needs extra instructions.
2549 - unless we know that we compile ARC700 user code, we need to put
2550 a memory barrier after frame allocation / before deallocation to
2551 prevent interrupts clobbering our data in the frame.
2552 In particular, we don't have any such guarantees for library functions,
2553 which tend to, on the other hand, to have small frames.
2555 Thus, for small frames, we'd like to use a different scheme:
2556 - The frame is allocated in full with the first prologue instruction,
2557 and deallocated in full with the last epilogue instruction.
2558 Thus, the instructions in-betwen can be freely scheduled.
2559 - If the function has no outgoing arguments on the stack, we can allocate
2560 one register save slot at the top of the stack. This register can then
2561 be saved simultanously with frame allocation, and restored with
2562 frame deallocation.
2563 This register can be picked depending on scheduling considerations,
2564 although same though should go into having some set of registers
2565 to be potentially lingering after a call, and others to be available
2566 immediately - i.e. in the absence of interprocedual optimization, we
2567 can use an ABI-like convention for register allocation to reduce
2568 stalls after function return. */
2569 /* Function prologue/epilogue handlers. */
2571 /* ARCompact stack frames look like:
2573 Before call After call
2574 high +-----------------------+ +-----------------------+
2575 mem | reg parm save area | | reg parm save area |
2576 | only created for | | only created for |
2577 | variable arg fns | | variable arg fns |
2578 AP +-----------------------+ +-----------------------+
2579 | return addr register | | return addr register |
2580 | (if required) | | (if required) |
2581 +-----------------------+ +-----------------------+
2582 | | | |
2583 | reg save area | | reg save area |
2584 | | | |
2585 +-----------------------+ +-----------------------+
2586 | frame pointer | | frame pointer |
2587 | (if required) | | (if required) |
2588 FP +-----------------------+ +-----------------------+
2589 | | | |
2590 | local/temp variables | | local/temp variables |
2591 | | | |
2592 +-----------------------+ +-----------------------+
2593 | | | |
2594 | arguments on stack | | arguments on stack |
2595 | | | |
2596 SP +-----------------------+ +-----------------------+
2597 | reg parm save area |
2598 | only created for |
2599 | variable arg fns |
2600 AP +-----------------------+
2601 | return addr register |
2602 | (if required) |
2603 +-----------------------+
2605 | reg save area |
2607 +-----------------------+
2608 | frame pointer |
2609 | (if required) |
2610 FP +-----------------------+
2612 | local/temp variables |
2614 +-----------------------+
2616 | arguments on stack |
2617 low | |
2618 mem SP +-----------------------+
2620 Notes:
2621 1) The "reg parm save area" does not exist for non variable argument fns.
2622 The "reg parm save area" can be eliminated completely if we created our
2623 own va-arc.h, but that has tradeoffs as well (so it's not done). */
2625 /* Structure to be filled in by arc_compute_frame_size with register
2626 save masks, and offsets for the current function. */
2627 struct GTY (()) arc_frame_info
2629 unsigned int total_size; /* # bytes that the entire frame takes up. */
2630 unsigned int extra_size; /* # bytes of extra stuff. */
2631 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
2632 unsigned int args_size; /* # bytes that outgoing arguments take up. */
2633 unsigned int reg_size; /* # bytes needed to store regs. */
2634 unsigned int var_size; /* # bytes that variables take up. */
2635 unsigned int reg_offset; /* Offset from new sp to store regs. */
2636 unsigned int gmask; /* Mask of saved gp registers. */
2637 int initialized; /* Nonzero if frame size already calculated. */
2638 short millicode_start_reg;
2639 short millicode_end_reg;
2640 bool save_return_addr;
2643 /* Defining data structures for per-function information. */
2645 typedef struct GTY (()) machine_function
2647 unsigned int fn_type;
2648 struct arc_frame_info frame_info;
2649 /* To keep track of unalignment caused by short insns. */
2650 int unalign;
2651 struct arc_ccfsm ccfsm_current;
2652 /* Map from uid to ccfsm state during branch shortening. */
2653 rtx ccfsm_current_insn;
2654 char arc_reorg_started;
2655 char prescan_initialized;
2656 } machine_function;
2658 /* Type of function DECL.
2660 The result is cached. To reset the cache at the end of a function,
2661 call with DECL = NULL_TREE. */
2663 unsigned int
2664 arc_compute_function_type (struct function *fun)
2666 tree attr, decl = fun->decl;
2667 unsigned int fn_type = fun->machine->fn_type;
2669 if (fn_type != ARC_FUNCTION_UNKNOWN)
2670 return fn_type;
2672 /* Check if it is a naked function. */
2673 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
2674 fn_type |= ARC_FUNCTION_NAKED;
2675 else
2676 fn_type |= ARC_FUNCTION_NORMAL;
2678 /* Now see if this is an interrupt handler. */
2679 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2680 if (attr != NULL_TREE)
2682 tree value, args = TREE_VALUE (attr);
2684 gcc_assert (list_length (args) == 1);
2685 value = TREE_VALUE (args);
2686 gcc_assert (TREE_CODE (value) == STRING_CST);
2688 if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
2689 || !strcmp (TREE_STRING_POINTER (value), "ilink"))
2690 fn_type |= ARC_FUNCTION_ILINK1;
2691 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
2692 fn_type |= ARC_FUNCTION_ILINK2;
2693 else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
2694 fn_type |= ARC_FUNCTION_FIRQ;
2695 else
2696 gcc_unreachable ();
2699 return fun->machine->fn_type = fn_type;
2702 #define FRAME_POINTER_MASK (1 << (FRAME_POINTER_REGNUM))
2703 #define RETURN_ADDR_MASK (1 << (RETURN_ADDR_REGNUM))
2705 /* Tell prologue and epilogue if register REGNO should be saved / restored.
2706 The return address and frame pointer are treated separately.
2707 Don't consider them here.
2708 Addition for pic: The gp register needs to be saved if the current
2709 function changes it to access gotoff variables.
2710 FIXME: This will not be needed if we used some arbitrary register
2711 instead of r26. */
2713 static bool
2714 arc_must_save_register (int regno, struct function *func)
2716 unsigned int fn_type = arc_compute_function_type (func);
2717 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2718 && ARC_AUTO_IRQ_P (fn_type));
2719 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2721 switch (rgf_banked_register_count)
2723 case 4:
2724 firq_auto_save_p &= (regno < 4);
2725 break;
2726 case 8:
2727 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2728 break;
2729 case 16:
2730 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2731 || ((regno > 25) && (regno < 29))
2732 || ((regno > 29) && (regno < 32)));
2733 break;
2734 case 32:
2735 firq_auto_save_p &= (regno != 29) && (regno < 32);
2736 break;
2737 default:
2738 firq_auto_save_p = false;
2739 break;
2742 if ((regno) != RETURN_ADDR_REGNUM
2743 && (regno) != FRAME_POINTER_REGNUM
2744 && df_regs_ever_live_p (regno)
2745 && (!call_used_regs[regno]
2746 || ARC_INTERRUPT_P (fn_type))
2747 /* Do not emit code for auto saved regs. */
2748 && !irq_auto_save_p
2749 && !firq_auto_save_p)
2750 return true;
2752 return false;
2755 /* Return true if the return address must be saved in the current function,
2756 otherwise return false. */
2758 static bool
2759 arc_must_save_return_addr (struct function *func)
2761 if (func->machine->frame_info.save_return_addr)
2762 return true;
2764 return false;
2767 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2768 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2769 Register Allocator) pass, while we want to get the frame size
2770 correct earlier than the IRA pass.
2772 When a function uses eh_return we must ensure that the fp register
2773 is saved and then restored so that the unwinder can restore the
2774 correct value for the frame we are going to jump to.
2776 To do this we force all frames that call eh_return to require a
2777 frame pointer (see arc_frame_pointer_required), this
2778 will ensure that the previous frame pointer is stored on entry to
2779 the function, and will then be reloaded at function exit.
2781 As the frame pointer is handled as a special case in our prologue
2782 and epilogue code it must not be saved and restored using the
2783 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2784 believes that the function is not using a frame pointer and that
2785 the value in the fp register is the frame pointer, while the
2786 prologue and epilogue are busy saving and restoring the fp
2787 register.
2789 During compilation of a function the frame size is evaluated
2790 multiple times, it is not until the reload pass is complete the the
2791 frame size is considered fixed (it is at this point that space for
2792 all spills has been allocated). However the frame_pointer_needed
2793 variable is not set true until the register allocation pass, as a
2794 result in the early stages the frame size does not include space
2795 for the frame pointer to be spilled.
2797 The problem that this causes is that the rtl generated for
2798 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2799 the offset from the frame pointer at which the return address
2800 lives. However, in early passes GCC has not yet realised we need a
2801 frame pointer, and so has not included space for the frame pointer
2802 in the frame size, and so gets the offset of the return address
2803 wrong. This should not be an issue as in later passes GCC has
2804 realised that the frame pointer needs to be spilled, and has
2805 increased the frame size. However, the rtl for the
2806 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2807 offset, and the wrong smaller offset is used. */
2809 static bool
2810 arc_frame_pointer_needed (void)
2812 return (frame_pointer_needed || crtl->calls_eh_return);
2815 /* Return non-zero if there are registers to be saved or loaded using
2816 millicode thunks. We can only use consecutive sequences starting
2817 with r13, and not going beyond r25.
2818 GMASK is a bitmask of registers to save. This function sets
2819 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2820 of registers to be saved / restored with a millicode call. */
2822 static int
2823 arc_compute_millicode_save_restore_regs (unsigned int gmask,
2824 struct arc_frame_info *frame)
2826 int regno;
2828 int start_reg = 13, end_reg = 25;
2830 for (regno = start_reg; regno <= end_reg && (gmask & (1L << regno));)
2831 regno++;
2832 end_reg = regno - 1;
2833 /* There is no point in using millicode thunks if we don't save/restore
2834 at least three registers. For non-leaf functions we also have the
2835 blink restore. */
2836 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2838 frame->millicode_start_reg = 13;
2839 frame->millicode_end_reg = regno - 1;
2840 return 1;
2842 return 0;
2845 /* Return the bytes needed to compute the frame pointer from the
2846 current stack pointer. */
2848 static unsigned int
2849 arc_compute_frame_size (void)
2851 int regno;
2852 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2853 unsigned int reg_size, reg_offset;
2854 unsigned int gmask;
2855 struct arc_frame_info *frame_info;
2856 int size;
2858 /* The answer might already be known. */
2859 if (cfun->machine->frame_info.initialized)
2860 return cfun->machine->frame_info.total_size;
2862 frame_info = &cfun->machine->frame_info;
2863 size = ARC_STACK_ALIGN (get_frame_size ());
2865 /* 1) Size of locals and temporaries. */
2866 var_size = size;
2868 /* 2) Size of outgoing arguments. */
2869 args_size = crtl->outgoing_args_size;
2871 /* 3) Calculate space needed for saved registers.
2872 ??? We ignore the extension registers for now. */
2874 /* See if this is an interrupt handler. Call used registers must be saved
2875 for them too. */
2877 reg_size = 0;
2878 gmask = 0;
2880 for (regno = 0; regno <= 31; regno++)
2882 if (arc_must_save_register (regno, cfun))
2884 reg_size += UNITS_PER_WORD;
2885 gmask |= 1L << regno;
2889 /* In a frame that calls __builtin_eh_return two data registers are
2890 used to pass values back to the exception handler.
2892 Ensure that these registers are spilled to the stack so that the
2893 exception throw code can find them, and update the saved values.
2894 The handling code will then consume these reloaded values to
2895 handle the exception. */
2896 if (crtl->calls_eh_return)
2897 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
2899 reg_size += UNITS_PER_WORD;
2900 gmask |= 1 << regno;
2903 /* 4) Space for back trace data structure.
2904 <return addr reg size> (if required) + <fp size> (if required). */
2905 frame_info->save_return_addr
2906 = (!crtl->is_leaf || df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2907 || crtl->calls_eh_return);
2908 /* Saving blink reg in case of leaf function for millicode thunk calls. */
2909 if (optimize_size
2910 && !TARGET_NO_MILLICODE_THUNK_SET
2911 && !crtl->calls_eh_return)
2913 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2914 frame_info->save_return_addr = true;
2917 extra_size = 0;
2918 if (arc_must_save_return_addr (cfun))
2919 extra_size = 4;
2920 if (arc_frame_pointer_needed ())
2921 extra_size += 4;
2923 /* 5) Space for variable arguments passed in registers */
2924 pretend_size = crtl->args.pretend_args_size;
2926 /* Ensure everything before the locals is aligned appropriately. */
2928 unsigned int extra_plus_reg_size;
2929 unsigned int extra_plus_reg_size_aligned;
2931 extra_plus_reg_size = extra_size + reg_size;
2932 extra_plus_reg_size_aligned = ARC_STACK_ALIGN(extra_plus_reg_size);
2933 reg_size = extra_plus_reg_size_aligned - extra_size;
2936 /* Compute total frame size. */
2937 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2939 /* It used to be the case that the alignment was forced at this
2940 point. However, that is dangerous, calculations based on
2941 total_size would be wrong. Given that this has never cropped up
2942 as an issue I've changed this to an assert for now. */
2943 gcc_assert (total_size == ARC_STACK_ALIGN (total_size));
2945 /* Compute offset of register save area from stack pointer:
2946 Frame: pretend_size <blink> reg_size <fp> var_size args_size <--sp
2948 reg_offset = (total_size - (pretend_size + reg_size + extra_size)
2949 + (arc_frame_pointer_needed () ? 4 : 0));
2951 /* Save computed information. */
2952 frame_info->total_size = total_size;
2953 frame_info->extra_size = extra_size;
2954 frame_info->pretend_size = pretend_size;
2955 frame_info->var_size = var_size;
2956 frame_info->args_size = args_size;
2957 frame_info->reg_size = reg_size;
2958 frame_info->reg_offset = reg_offset;
2959 frame_info->gmask = gmask;
2960 frame_info->initialized = reload_completed;
2962 /* Ok, we're done. */
2963 return total_size;
2966 /* Common code to save/restore registers. */
2967 /* BASE_REG is the base register to use for addressing and to adjust.
2968 GMASK is a bitmask of general purpose registers to save/restore.
2969 epilogue_p 0: prologue 1:epilogue 2:epilogue, sibling thunk
2970 If *FIRST_OFFSET is non-zero, add it first to BASE_REG - preferably
2971 using a pre-modify for the first memory access. *FIRST_OFFSET is then
2972 zeroed. */
2974 static void
2975 arc_save_restore (rtx base_reg,
2976 unsigned int gmask, int epilogue_p, int *first_offset)
2978 unsigned int offset = 0;
2979 int regno;
2980 struct arc_frame_info *frame = &cfun->machine->frame_info;
2981 rtx sibthunk_insn = NULL_RTX;
2983 if (gmask)
2985 /* Millicode thunks implementation:
2986 Generates calls to millicodes for registers starting from r13 to r25
2987 Present Limitations:
2988 - Only one range supported. The remaining regs will have the ordinary
2989 st and ld instructions for store and loads. Hence a gmask asking
2990 to store r13-14, r16-r25 will only generate calls to store and
2991 load r13 to r14 while store and load insns will be generated for
2992 r16 to r25 in the prologue and epilogue respectively.
2994 - Presently library only supports register ranges starting from r13.
2996 if (epilogue_p == 2 || frame->millicode_end_reg > 14)
2998 int start_call = frame->millicode_start_reg;
2999 int end_call = frame->millicode_end_reg;
3000 int n_regs = end_call - start_call + 1;
3001 int i = 0, r, off = 0;
3002 rtx insn;
3003 rtx ret_addr = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3005 if (*first_offset)
3007 /* "reg_size" won't be more than 127 . */
3008 gcc_assert (epilogue_p || abs (*first_offset) <= 127);
3009 frame_add (base_reg, *first_offset);
3010 *first_offset = 0;
3012 insn = gen_rtx_PARALLEL
3013 (VOIDmode, rtvec_alloc ((epilogue_p == 2) + n_regs + 1));
3014 if (epilogue_p == 2)
3015 i += 2;
3016 else
3017 XVECEXP (insn, 0, n_regs) = gen_rtx_CLOBBER (VOIDmode, ret_addr);
3018 for (r = start_call; r <= end_call; r++, off += UNITS_PER_WORD, i++)
3020 rtx reg = gen_rtx_REG (SImode, r);
3021 rtx mem
3022 = gen_frame_mem (SImode, plus_constant (Pmode, base_reg, off));
3024 if (epilogue_p)
3025 XVECEXP (insn, 0, i) = gen_rtx_SET (reg, mem);
3026 else
3027 XVECEXP (insn, 0, i) = gen_rtx_SET (mem, reg);
3028 gmask = gmask & ~(1L << r);
3030 if (epilogue_p == 2)
3031 sibthunk_insn = insn;
3032 else
3034 insn = frame_insn (insn);
3035 for (r = start_call, off = 0;
3036 r <= end_call;
3037 r++, off += UNITS_PER_WORD)
3039 rtx reg = gen_rtx_REG (SImode, r);
3040 if (epilogue_p)
3041 add_reg_note (insn, REG_CFA_RESTORE, reg);
3042 else
3044 rtx mem = gen_rtx_MEM (SImode, plus_constant (Pmode,
3045 base_reg,
3046 off));
3048 add_reg_note (insn, REG_CFA_OFFSET,
3049 gen_rtx_SET (mem, reg));
3053 offset += off;
3056 for (regno = 0; regno <= 31; regno++)
3058 machine_mode mode = SImode;
3059 bool found = false;
3061 if (TARGET_LL64
3062 && (regno % 2 == 0)
3063 && ((gmask & (1L << regno)) != 0)
3064 && ((gmask & (1L << (regno+1))) != 0))
3066 found = true;
3067 mode = DImode;
3069 else if ((gmask & (1L << regno)) != 0)
3071 found = true;
3072 mode = SImode;
3075 if (found)
3077 rtx reg = gen_rtx_REG (mode, regno);
3078 rtx addr, mem;
3079 int cfa_adjust = *first_offset;
3081 if (*first_offset)
3083 gcc_assert (!offset);
3084 addr = plus_constant (Pmode, base_reg, *first_offset);
3085 addr = gen_rtx_PRE_MODIFY (Pmode, base_reg, addr);
3086 *first_offset = 0;
3088 else
3090 gcc_assert (SMALL_INT (offset));
3091 addr = plus_constant (Pmode, base_reg, offset);
3093 mem = gen_frame_mem (mode, addr);
3094 if (epilogue_p)
3096 rtx insn =
3097 frame_move_inc (reg, mem, base_reg, addr);
3098 add_reg_note (insn, REG_CFA_RESTORE, reg);
3099 if (cfa_adjust)
3101 enum reg_note note = REG_CFA_ADJUST_CFA;
3102 add_reg_note (insn, note,
3103 gen_rtx_SET (stack_pointer_rtx,
3104 plus_constant (Pmode,
3105 stack_pointer_rtx,
3106 cfa_adjust)));
3109 else
3110 frame_move_inc (mem, reg, base_reg, addr);
3111 offset += UNITS_PER_WORD;
3112 if (mode == DImode)
3114 offset += UNITS_PER_WORD;
3115 ++regno;
3117 } /* if */
3118 } /* for */
3119 }/* if */
3120 if (sibthunk_insn)
3122 int start_call = frame->millicode_start_reg;
3123 int end_call = frame->millicode_end_reg;
3124 int r;
3126 rtx r12 = gen_rtx_REG (Pmode, 12);
3128 frame_insn (gen_rtx_SET (r12, GEN_INT (offset)));
3129 XVECEXP (sibthunk_insn, 0, 0) = ret_rtx;
3130 XVECEXP (sibthunk_insn, 0, 1)
3131 = gen_rtx_SET (stack_pointer_rtx,
3132 gen_rtx_PLUS (Pmode, stack_pointer_rtx, r12));
3133 sibthunk_insn = emit_jump_insn (sibthunk_insn);
3134 RTX_FRAME_RELATED_P (sibthunk_insn) = 1;
3136 /* Would be nice if we could do this earlier, when the PARALLEL
3137 is populated, but these need to be attached after the
3138 emit. */
3139 for (r = start_call; r <= end_call; r++)
3141 rtx reg = gen_rtx_REG (SImode, r);
3142 add_reg_note (sibthunk_insn, REG_CFA_RESTORE, reg);
3145 } /* arc_save_restore */
3147 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
3148 mechanism. */
3150 static void
3151 arc_dwarf_emit_irq_save_regs (void)
3153 rtx tmp, par, insn, reg;
3154 int i, offset, j;
3156 par = gen_rtx_SEQUENCE (VOIDmode,
3157 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
3158 + irq_ctrl_saved.irq_save_blink
3159 + irq_ctrl_saved.irq_save_lpcount
3160 + 1));
3162 /* Build the stack adjustment note for unwind info. */
3163 j = 0;
3164 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
3165 + irq_ctrl_saved.irq_save_blink
3166 + irq_ctrl_saved.irq_save_lpcount);
3167 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
3168 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
3169 RTX_FRAME_RELATED_P (tmp) = 1;
3170 XVECEXP (par, 0, j++) = tmp;
3172 offset -= UNITS_PER_WORD;
3174 /* 1st goes LP_COUNT. */
3175 if (irq_ctrl_saved.irq_save_lpcount)
3177 reg = gen_rtx_REG (SImode, 60);
3178 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
3179 tmp = gen_frame_mem (SImode, tmp);
3180 tmp = gen_rtx_SET (tmp, reg);
3181 RTX_FRAME_RELATED_P (tmp) = 1;
3182 XVECEXP (par, 0, j++) = tmp;
3183 offset -= UNITS_PER_WORD;
3186 /* 2nd goes BLINK. */
3187 if (irq_ctrl_saved.irq_save_blink)
3189 reg = gen_rtx_REG (SImode, 31);
3190 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
3191 tmp = gen_frame_mem (SImode, tmp);
3192 tmp = gen_rtx_SET (tmp, reg);
3193 RTX_FRAME_RELATED_P (tmp) = 1;
3194 XVECEXP (par, 0, j++) = tmp;
3195 offset -= UNITS_PER_WORD;
3198 /* Build the parallel of the remaining registers recorded as saved
3199 for unwind. */
3200 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
3202 reg = gen_rtx_REG (SImode, i);
3203 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
3204 tmp = gen_frame_mem (SImode, tmp);
3205 tmp = gen_rtx_SET (tmp, reg);
3206 RTX_FRAME_RELATED_P (tmp) = 1;
3207 XVECEXP (par, 0, j++) = tmp;
3208 offset -= UNITS_PER_WORD;
3211 /* Dummy insn used to anchor the dwarf info. */
3212 insn = emit_insn (gen_stack_irq_dwarf());
3213 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
3214 RTX_FRAME_RELATED_P (insn) = 1;
3217 /* Set up the stack and frame pointer (if desired) for the function. */
3219 void
3220 arc_expand_prologue (void)
3222 int size;
3223 unsigned int gmask = cfun->machine->frame_info.gmask;
3224 /* unsigned int frame_pointer_offset;*/
3225 unsigned int frame_size_to_allocate;
3226 /* (FIXME: The first store will use a PRE_MODIFY; this will usually be r13.
3227 Change the stack layout so that we rather store a high register with the
3228 PRE_MODIFY, thus enabling more short insn generation.) */
3229 int first_offset = 0;
3230 unsigned int fn_type = arc_compute_function_type (cfun);
3232 /* Naked functions don't have prologue. */
3233 if (ARC_NAKED_P (fn_type))
3235 if (flag_stack_usage_info)
3236 current_function_static_stack_size = 0;
3237 return;
3240 /* Compute total frame size. */
3241 size = arc_compute_frame_size ();
3243 if (flag_stack_usage_info)
3244 current_function_static_stack_size = size;
3246 /* Keep track of frame size to be allocated. */
3247 frame_size_to_allocate = size;
3249 /* These cases shouldn't happen. Catch them now. */
3250 gcc_assert (!(size == 0 && gmask));
3252 /* Allocate space for register arguments if this is a variadic function. */
3253 if (cfun->machine->frame_info.pretend_size != 0)
3255 /* Ensure pretend_size is maximum of 8 * word_size. */
3256 gcc_assert (cfun->machine->frame_info.pretend_size <= 32);
3258 frame_stack_add (-(HOST_WIDE_INT)cfun->machine->frame_info.pretend_size);
3259 frame_size_to_allocate -= cfun->machine->frame_info.pretend_size;
3262 /* IRQ using automatic save mechanism will save the register before
3263 anything we do. */
3264 if (ARC_AUTO_IRQ_P (fn_type)
3265 && !ARC_FAST_INTERRUPT_P (fn_type))
3267 arc_dwarf_emit_irq_save_regs ();
3270 /* The home-grown ABI says link register is saved first. */
3271 if (arc_must_save_return_addr (cfun)
3272 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3274 rtx ra = gen_rtx_REG (SImode, RETURN_ADDR_REGNUM);
3275 rtx mem = gen_frame_mem (Pmode,
3276 gen_rtx_PRE_DEC (Pmode,
3277 stack_pointer_rtx));
3279 frame_move_inc (mem, ra, stack_pointer_rtx, 0);
3280 frame_size_to_allocate -= UNITS_PER_WORD;
3283 /* Save any needed call-saved regs (and call-used if this is an
3284 interrupt handler) for ARCompact ISA. */
3285 if (cfun->machine->frame_info.reg_size)
3287 first_offset = -cfun->machine->frame_info.reg_size;
3288 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3289 arc_save_restore (stack_pointer_rtx, gmask, 0, &first_offset);
3290 frame_size_to_allocate -= cfun->machine->frame_info.reg_size;
3293 /* In the case of millicode thunk, we need to restore the clobbered
3294 blink register. */
3295 if (cfun->machine->frame_info.millicode_end_reg > 0
3296 && arc_must_save_return_addr (cfun))
3298 HOST_WIDE_INT tmp = cfun->machine->frame_info.reg_size;
3299 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
3300 gen_rtx_MEM (Pmode,
3301 plus_constant (Pmode,
3302 stack_pointer_rtx,
3303 tmp))));
3306 /* Save frame pointer if needed. First save the FP on stack, if not
3307 autosaved. */
3308 if (arc_frame_pointer_needed ()
3309 && !ARC_AUTOFP_IRQ_P (fn_type))
3311 rtx addr = gen_rtx_PLUS (Pmode, stack_pointer_rtx,
3312 GEN_INT (-UNITS_PER_WORD + first_offset));
3313 rtx mem = gen_frame_mem (Pmode, gen_rtx_PRE_MODIFY (Pmode,
3314 stack_pointer_rtx,
3315 addr));
3316 frame_move_inc (mem, frame_pointer_rtx, stack_pointer_rtx, 0);
3317 frame_size_to_allocate -= UNITS_PER_WORD;
3318 first_offset = 0;
3321 /* Emit mov fp,sp. */
3322 if (arc_frame_pointer_needed ())
3324 frame_move (frame_pointer_rtx, stack_pointer_rtx);
3327 /* ??? We don't handle the case where the saved regs are more than 252
3328 bytes away from sp. This can be handled by decrementing sp once, saving
3329 the regs, and then decrementing it again. The epilogue doesn't have this
3330 problem as the `ld' insn takes reg+limm values (though it would be more
3331 efficient to avoid reg+limm). */
3333 frame_size_to_allocate -= first_offset;
3334 /* Allocate the stack frame. */
3335 if (frame_size_to_allocate > 0)
3337 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3338 /* If the frame pointer is needed, emit a special barrier that
3339 will prevent the scheduler from moving stores to the frame
3340 before the stack adjustment. */
3341 if (arc_frame_pointer_needed ())
3342 emit_insn (gen_stack_tie (stack_pointer_rtx,
3343 hard_frame_pointer_rtx));
3347 /* Do any necessary cleanup after a function to restore stack, frame,
3348 and regs. */
3350 void
3351 arc_expand_epilogue (int sibcall_p)
3353 int size;
3354 unsigned int fn_type = arc_compute_function_type (cfun);
3356 size = arc_compute_frame_size ();
3358 unsigned int pretend_size = cfun->machine->frame_info.pretend_size;
3359 unsigned int frame_size;
3360 unsigned int size_to_deallocate;
3361 int restored;
3362 int can_trust_sp_p = !cfun->calls_alloca;
3363 int first_offset = 0;
3364 int millicode_p = cfun->machine->frame_info.millicode_end_reg > 0;
3365 rtx insn;
3367 /* Naked functions don't have epilogue. */
3368 if (ARC_NAKED_P (fn_type))
3369 return;
3371 size_to_deallocate = size;
3373 frame_size = size - (pretend_size +
3374 cfun->machine->frame_info.reg_size +
3375 cfun->machine->frame_info.extra_size);
3377 /* ??? There are lots of optimizations that can be done here.
3378 EG: Use fp to restore regs if it's closer.
3379 Maybe in time we'll do them all. For now, always restore regs from
3380 sp, but don't restore sp if we don't have to. */
3382 if (!can_trust_sp_p)
3383 gcc_assert (arc_frame_pointer_needed ());
3385 /* Restore stack pointer to the beginning of saved register area for
3386 ARCompact ISA. */
3387 if (frame_size)
3389 if (arc_frame_pointer_needed ())
3390 frame_move (stack_pointer_rtx, frame_pointer_rtx);
3391 else
3392 first_offset = frame_size;
3393 size_to_deallocate -= frame_size;
3395 else if (!can_trust_sp_p)
3396 frame_stack_add (-frame_size);
3399 /* Restore any saved registers. */
3400 if (arc_frame_pointer_needed ()
3401 && !ARC_AUTOFP_IRQ_P (fn_type))
3403 rtx addr = gen_rtx_POST_INC (Pmode, stack_pointer_rtx);
3405 insn = frame_move_inc (frame_pointer_rtx, gen_frame_mem (Pmode, addr),
3406 stack_pointer_rtx, 0);
3407 add_reg_note (insn, REG_CFA_RESTORE, frame_pointer_rtx);
3408 add_reg_note (insn, REG_CFA_DEF_CFA,
3409 plus_constant (SImode, stack_pointer_rtx,
3410 4));
3411 size_to_deallocate -= UNITS_PER_WORD;
3414 /* Load blink after the calls to thunk calls in case of optimize size. */
3415 if (millicode_p)
3417 int sibthunk_p = (!sibcall_p
3418 && fn_type == ARC_FUNCTION_NORMAL
3419 && !cfun->machine->frame_info.pretend_size);
3421 gcc_assert (!(cfun->machine->frame_info.gmask
3422 & (FRAME_POINTER_MASK | RETURN_ADDR_MASK)));
3423 arc_save_restore (stack_pointer_rtx,
3424 cfun->machine->frame_info.gmask,
3425 1 + sibthunk_p, &first_offset);
3426 if (sibthunk_p)
3427 return;
3429 /* If we are to restore registers, and first_offset would require
3430 a limm to be encoded in a PRE_MODIFY, yet we can add it with a
3431 fast add to the stack pointer, do this now. */
3432 if ((!SMALL_INT (first_offset)
3433 && cfun->machine->frame_info.gmask
3434 && ((TARGET_ARC700 && !optimize_size)
3435 ? first_offset <= 0x800
3436 : satisfies_constraint_C2a (GEN_INT (first_offset))))
3437 /* Also do this if we have both gprs and return
3438 address to restore, and they both would need a LIMM. */
3439 || (arc_must_save_return_addr (cfun)
3440 && !SMALL_INT ((cfun->machine->frame_info.reg_size + first_offset) >> 2)
3441 && cfun->machine->frame_info.gmask))
3443 frame_stack_add (first_offset);
3444 first_offset = 0;
3446 if (arc_must_save_return_addr (cfun)
3447 && !ARC_AUTOBLINK_IRQ_P (fn_type))
3449 rtx ra = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3450 int ra_offs = cfun->machine->frame_info.reg_size + first_offset;
3451 rtx addr = plus_constant (Pmode, stack_pointer_rtx, ra_offs);
3452 HOST_WIDE_INT cfa_adjust = 0;
3454 /* If the load of blink would need a LIMM, but we can add
3455 the offset quickly to sp, do the latter. */
3456 if (!SMALL_INT (ra_offs >> 2)
3457 && !cfun->machine->frame_info.gmask
3458 && ((TARGET_ARC700 && !optimize_size)
3459 ? ra_offs <= 0x800
3460 : satisfies_constraint_C2a (GEN_INT (ra_offs))))
3462 size_to_deallocate -= ra_offs - first_offset;
3463 first_offset = 0;
3464 frame_stack_add (ra_offs);
3465 ra_offs = 0;
3466 addr = stack_pointer_rtx;
3468 /* See if we can combine the load of the return address with the
3469 final stack adjustment.
3470 We need a separate load if there are still registers to
3471 restore. We also want a separate load if the combined insn
3472 would need a limm, but a separate load doesn't. */
3473 if (ra_offs
3474 && !cfun->machine->frame_info.gmask
3475 && (SMALL_INT (ra_offs) || !SMALL_INT (ra_offs >> 2)))
3477 addr = gen_rtx_PRE_MODIFY (Pmode, stack_pointer_rtx, addr);
3478 cfa_adjust = ra_offs;
3479 first_offset = 0;
3480 size_to_deallocate -= cfun->machine->frame_info.reg_size;
3482 else if (!ra_offs && size_to_deallocate == UNITS_PER_WORD)
3484 addr = gen_rtx_POST_INC (Pmode, addr);
3485 cfa_adjust = GET_MODE_SIZE (Pmode);
3486 size_to_deallocate = 0;
3489 insn = frame_move_inc (ra, gen_frame_mem (Pmode, addr),
3490 stack_pointer_rtx, addr);
3491 if (cfa_adjust)
3493 enum reg_note note = REG_CFA_ADJUST_CFA;
3495 add_reg_note (insn, note,
3496 gen_rtx_SET (stack_pointer_rtx,
3497 plus_constant (SImode, stack_pointer_rtx,
3498 cfa_adjust)));
3500 add_reg_note (insn, REG_CFA_RESTORE, ra);
3503 if (!millicode_p)
3505 if (cfun->machine->frame_info.reg_size)
3506 arc_save_restore (stack_pointer_rtx,
3507 /* The zeroing of these two bits is unnecessary, but leave this in for clarity. */
3508 cfun->machine->frame_info.gmask
3509 & ~(FRAME_POINTER_MASK | RETURN_ADDR_MASK), 1, &first_offset);
3512 /* The rest of this function does the following:
3513 ARCompact : handle epilogue_delay, restore sp (phase-2), return
3516 /* Keep track of how much of the stack pointer we've restored.
3517 It makes the following a lot more readable. */
3518 size_to_deallocate += first_offset;
3519 restored = size - size_to_deallocate;
3521 if (size > restored)
3522 frame_stack_add (size - restored);
3524 /* For frames that use __builtin_eh_return, the register defined by
3525 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
3526 On eh_return paths however, the register is set to the value that
3527 should be added to the stack pointer in order to restore the
3528 correct stack pointer for the exception handling frame.
3530 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
3531 this onto the stack for eh_return frames. */
3532 if (crtl->calls_eh_return)
3533 emit_insn (gen_add2_insn (stack_pointer_rtx,
3534 EH_RETURN_STACKADJ_RTX));
3536 /* Emit the return instruction. */
3537 if (sibcall_p == FALSE)
3538 emit_jump_insn (gen_simple_return ());
3541 /* Return rtx for the location of the return address on the stack,
3542 suitable for use in __builtin_eh_return. The new return address
3543 will be written to this location in order to redirect the return to
3544 the exception handler. */
3547 arc_eh_return_address_location (void)
3549 rtx mem;
3550 int offset;
3551 struct arc_frame_info *afi;
3553 arc_compute_frame_size ();
3554 afi = &cfun->machine->frame_info;
3556 gcc_assert (crtl->calls_eh_return);
3557 gcc_assert (afi->save_return_addr);
3558 gcc_assert (afi->extra_size >= 4);
3560 /* The '-4' removes the size of the return address, which is
3561 included in the 'extra_size' field. */
3562 offset = afi->reg_size + afi->extra_size - 4;
3563 mem = gen_frame_mem (Pmode,
3564 plus_constant (Pmode, frame_pointer_rtx, offset));
3566 /* The following should not be needed, and is, really a hack. The
3567 issue being worked around here is that the DSE (Dead Store
3568 Elimination) pass will remove this write to the stack as it sees
3569 a single store and no corresponding read. The read however
3570 occurs in the epilogue code, which is not added into the function
3571 rtl until a later pass. So, at the time of DSE, the decision to
3572 remove this store seems perfectly sensible. Marking the memory
3573 address as volatile obviously has the effect of preventing DSE
3574 from removing the store. */
3575 MEM_VOLATILE_P (mem) = 1;
3576 return mem;
3579 /* PIC */
3581 /* Helper to generate unspec constant. */
3583 static rtx
3584 arc_unspec_offset (rtx loc, int unspec)
3586 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
3587 unspec));
3590 /* !TARGET_BARREL_SHIFTER support. */
3591 /* Emit a shift insn to set OP0 to OP1 shifted by OP2; CODE specifies what
3592 kind of shift. */
3594 void
3595 emit_shift (enum rtx_code code, rtx op0, rtx op1, rtx op2)
3597 rtx shift = gen_rtx_fmt_ee (code, SImode, op1, op2);
3598 rtx pat
3599 = ((shift4_operator (shift, SImode) ? gen_shift_si3 : gen_shift_si3_loop)
3600 (op0, op1, op2, shift));
3601 emit_insn (pat);
3604 /* Output the assembler code for doing a shift.
3605 We go to a bit of trouble to generate efficient code as the ARC601 only has
3606 single bit shifts. This is taken from the h8300 port. We only have one
3607 mode of shifting and can't access individual bytes like the h8300 can, so
3608 this is greatly simplified (at the expense of not generating hyper-
3609 efficient code).
3611 This function is not used if the variable shift insns are present. */
3613 /* FIXME: This probably can be done using a define_split in arc.md.
3614 Alternately, generate rtx rather than output instructions. */
3616 const char *
3617 output_shift (rtx *operands)
3619 /* static int loopend_lab;*/
3620 rtx shift = operands[3];
3621 machine_mode mode = GET_MODE (shift);
3622 enum rtx_code code = GET_CODE (shift);
3623 const char *shift_one;
3625 gcc_assert (mode == SImode);
3627 switch (code)
3629 case ASHIFT: shift_one = "add %0,%1,%1"; break;
3630 case ASHIFTRT: shift_one = "asr %0,%1"; break;
3631 case LSHIFTRT: shift_one = "lsr %0,%1"; break;
3632 default: gcc_unreachable ();
3635 if (GET_CODE (operands[2]) != CONST_INT)
3637 output_asm_insn ("and.f lp_count,%2, 0x1f", operands);
3638 goto shiftloop;
3640 else
3642 int n;
3644 n = INTVAL (operands[2]);
3646 /* Only consider the lower 5 bits of the shift count. */
3647 n = n & 0x1f;
3649 /* First see if we can do them inline. */
3650 /* ??? We could get better scheduling & shorter code (using short insns)
3651 by using splitters. Alas, that'd be even more verbose. */
3652 if (code == ASHIFT && n <= 9 && n > 2
3653 && dest_reg_operand (operands[4], SImode))
3655 output_asm_insn ("mov %4,0\n\tadd3 %0,%4,%1", operands);
3656 for (n -=3 ; n >= 3; n -= 3)
3657 output_asm_insn ("add3 %0,%4,%0", operands);
3658 if (n == 2)
3659 output_asm_insn ("add2 %0,%4,%0", operands);
3660 else if (n)
3661 output_asm_insn ("add %0,%0,%0", operands);
3663 else if (n <= 4)
3665 while (--n >= 0)
3667 output_asm_insn (shift_one, operands);
3668 operands[1] = operands[0];
3671 /* See if we can use a rotate/and. */
3672 else if (n == BITS_PER_WORD - 1)
3674 switch (code)
3676 case ASHIFT :
3677 output_asm_insn ("and %0,%1,1\n\tror %0,%0", operands);
3678 break;
3679 case ASHIFTRT :
3680 /* The ARC doesn't have a rol insn. Use something else. */
3681 output_asm_insn ("add.f 0,%1,%1\n\tsbc %0,%0,%0", operands);
3682 break;
3683 case LSHIFTRT :
3684 /* The ARC doesn't have a rol insn. Use something else. */
3685 output_asm_insn ("add.f 0,%1,%1\n\trlc %0,0", operands);
3686 break;
3687 default:
3688 break;
3691 else if (n == BITS_PER_WORD - 2 && dest_reg_operand (operands[4], SImode))
3693 switch (code)
3695 case ASHIFT :
3696 output_asm_insn ("and %0,%1,3\n\tror %0,%0\n\tror %0,%0", operands);
3697 break;
3698 case ASHIFTRT :
3699 #if 1 /* Need some scheduling comparisons. */
3700 output_asm_insn ("add.f %4,%1,%1\n\tsbc %0,%0,%0\n\t"
3701 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3702 #else
3703 output_asm_insn ("add.f %4,%1,%1\n\tbxor %0,%4,31\n\t"
3704 "sbc.f %0,%0,%4\n\trlc %0,%0", operands);
3705 #endif
3706 break;
3707 case LSHIFTRT :
3708 #if 1
3709 output_asm_insn ("add.f %4,%1,%1\n\trlc %0,0\n\t"
3710 "add.f 0,%4,%4\n\trlc %0,%0", operands);
3711 #else
3712 output_asm_insn ("add.f %0,%1,%1\n\trlc.f %0,0\n\t"
3713 "and %0,%0,1\n\trlc %0,%0", operands);
3714 #endif
3715 break;
3716 default:
3717 break;
3720 else if (n == BITS_PER_WORD - 3 && code == ASHIFT)
3721 output_asm_insn ("and %0,%1,7\n\tror %0,%0\n\tror %0,%0\n\tror %0,%0",
3722 operands);
3723 /* Must loop. */
3724 else
3726 operands[2] = GEN_INT (n);
3727 output_asm_insn ("mov.f lp_count, %2", operands);
3729 shiftloop:
3731 output_asm_insn ("lpnz\t2f", operands);
3732 output_asm_insn (shift_one, operands);
3733 output_asm_insn ("nop", operands);
3734 fprintf (asm_out_file, "2:\t%s end single insn loop\n",
3735 ASM_COMMENT_START);
3740 return "";
3743 /* Nested function support. */
3745 /* Output assembler code for a block containing the constant parts of
3746 a trampoline, leaving space for variable parts. A trampoline looks
3747 like this:
3749 ld_s r12,[pcl,8]
3750 ld r11,[pcl,12]
3751 j_s [r12]
3752 .word function's address
3753 .word static chain value
3757 static void
3758 arc_asm_trampoline_template (FILE *f)
3760 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG);
3761 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]);
3762 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG);
3763 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3764 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
3767 /* Emit RTL insns to initialize the variable parts of a trampoline.
3768 FNADDR is an RTX for the address of the function's pure code. CXT
3769 is an RTX for the static chain value for the function.
3771 The fastest trampoline to execute for trampolines within +-8KB of CTX
3772 would be:
3774 add2 r11,pcl,s12
3775 j [limm] 0x20200f80 limm
3777 and that would also be faster to write to the stack by computing
3778 the offset from CTX to TRAMP at compile time. However, it would
3779 really be better to get rid of the high cost of cache invalidation
3780 when generating trampolines, which requires that the code part of
3781 trampolines stays constant, and additionally either making sure
3782 that no executable code but trampolines is on the stack, no icache
3783 entries linger for the area of the stack from when before the stack
3784 was allocated, and allocating trampolines in trampoline-only cache
3785 lines or allocate trampolines fram a special pool of pre-allocated
3786 trampolines. */
3788 static void
3789 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
3791 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
3793 emit_block_move (tramp, assemble_trampoline_template (),
3794 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
3795 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
3796 emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
3797 emit_library_call (gen_rtx_SYMBOL_REF (Pmode, "__clear_cache"),
3798 LCT_NORMAL, VOIDmode, XEXP (tramp, 0), Pmode,
3799 plus_constant (Pmode, XEXP (tramp, 0), TRAMPOLINE_SIZE),
3800 Pmode);
3803 /* Add the given function declaration to emit code in JLI section. */
3805 static void
3806 arc_add_jli_section (rtx pat)
3808 const char *name;
3809 tree attrs;
3810 arc_jli_section *sec = arc_jli_sections, *new_section;
3811 tree decl = SYMBOL_REF_DECL (pat);
3813 if (!pat)
3814 return;
3816 if (decl)
3818 /* For fixed locations do not generate the jli table entry. It
3819 should be provided by the user as an asm file. */
3820 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
3821 if (lookup_attribute ("jli_fixed", attrs))
3822 return;
3825 name = XSTR (pat, 0);
3827 /* Don't insert the same symbol twice. */
3828 while (sec != NULL)
3830 if(strcmp (name, sec->name) == 0)
3831 return;
3832 sec = sec->next;
3835 /* New name, insert it. */
3836 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
3837 gcc_assert (new_section != NULL);
3838 new_section->name = name;
3839 new_section->next = arc_jli_sections;
3840 arc_jli_sections = new_section;
3843 /* This is set briefly to 1 when we output a ".as" address modifer, and then
3844 reset when we output the scaled address. */
3845 static int output_scaled = 0;
3847 /* Set when we force sdata output. */
3848 static int output_sdata = 0;
3850 /* Print operand X (an rtx) in assembler syntax to file FILE.
3851 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
3852 For `%' followed by punctuation, CODE is the punctuation and X is null. */
3853 /* In final.c:output_asm_insn:
3854 'l' : label
3855 'a' : address
3856 'c' : constant address if CONSTANT_ADDRESS_P
3857 'n' : negative
3858 Here:
3859 'Z': log2(x+1)-1
3860 'z': log2
3861 'M': log2(~x)
3862 'p': bit Position of lsb
3863 's': size of bit field
3864 '#': condbranch delay slot suffix
3865 '*': jump delay slot suffix
3866 '?' : nonjump-insn suffix for conditional execution or short instruction
3867 '!' : jump / call suffix for conditional execution or short instruction
3868 '`': fold constant inside unary o-perator, re-recognize, and emit.
3871 'R': Second word
3872 'S': JLI instruction
3873 'j': used by mov instruction to properly emit jli related labels.
3874 'B': Branch comparison operand - suppress sda reference
3875 'H': Most significant word
3876 'L': Least significant word
3877 'A': ASCII decimal representation of floating point value
3878 'U': Load/store update or scaling indicator
3879 'V': cache bypass indicator for volatile
3883 'O': Operator
3884 'o': original symbol - no @ prepending. */
3886 void
3887 arc_print_operand (FILE *file, rtx x, int code)
3889 switch (code)
3891 case 'Z':
3892 if (GET_CODE (x) == CONST_INT)
3893 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
3894 else
3895 output_operand_lossage ("invalid operand to %%Z code");
3897 return;
3899 case 'z':
3900 if (GET_CODE (x) == CONST_INT)
3901 fprintf (file, "%d",exact_log2(INTVAL (x)) );
3902 else
3903 output_operand_lossage ("invalid operand to %%z code");
3905 return;
3907 case 'c':
3908 if (GET_CODE (x) == CONST_INT)
3909 fprintf (file, "%ld", INTVAL (x) );
3910 else
3911 output_operand_lossage ("invalid operands to %%c code");
3913 return;
3915 case 'M':
3916 if (GET_CODE (x) == CONST_INT)
3917 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
3918 else
3919 output_operand_lossage ("invalid operand to %%M code");
3921 return;
3923 case 'p':
3924 if (GET_CODE (x) == CONST_INT)
3925 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
3926 else
3927 output_operand_lossage ("invalid operand to %%p code");
3928 return;
3930 case 's':
3931 if (GET_CODE (x) == CONST_INT)
3933 HOST_WIDE_INT i = INTVAL (x);
3934 HOST_WIDE_INT s = exact_log2 (i & -i);
3935 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
3937 else
3938 output_operand_lossage ("invalid operand to %%s code");
3939 return;
3941 case '#' :
3942 /* Conditional branches depending on condition codes.
3943 Note that this is only for branches that were known to depend on
3944 condition codes before delay slot scheduling;
3945 out-of-range brcc / bbit expansions should use '*'.
3946 This distinction is important because of the different
3947 allowable delay slot insns and the output of the delay suffix
3948 for TARGET_AT_DBR_COND_EXEC. */
3949 case '*' :
3950 /* Unconditional branches / branches not depending on condition codes.
3951 This could also be a CALL_INSN.
3952 Output the appropriate delay slot suffix. */
3953 if (final_sequence && final_sequence->len () != 1)
3955 rtx_insn *jump = final_sequence->insn (0);
3956 rtx_insn *delay = final_sequence->insn (1);
3958 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
3959 if (delay->deleted ())
3960 return;
3961 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
3962 fputs (INSN_FROM_TARGET_P (delay) ? ".d"
3963 : TARGET_AT_DBR_CONDEXEC && code == '#' ? ".d"
3964 : get_attr_type (jump) == TYPE_RETURN && code == '#' ? ""
3965 : ".nd",
3966 file);
3967 else
3968 fputs (".d", file);
3970 return;
3971 case '?' : /* with leading "." */
3972 case '!' : /* without leading "." */
3973 /* This insn can be conditionally executed. See if the ccfsm machinery
3974 says it should be conditionalized.
3975 If it shouldn't, we'll check the compact attribute if this insn
3976 has a short variant, which may be used depending on code size and
3977 alignment considerations. */
3978 if (current_insn_predicate)
3979 arc_ccfsm_current.cc
3980 = get_arc_condition_code (current_insn_predicate);
3981 if (ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current))
3983 /* Is this insn in a delay slot sequence? */
3984 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
3985 || current_insn_predicate
3986 || CALL_P (final_sequence->insn (0))
3987 || simplejump_p (final_sequence->insn (0)))
3989 /* This insn isn't in a delay slot sequence, or conditionalized
3990 independently of its position in a delay slot. */
3991 fprintf (file, "%s%s",
3992 code == '?' ? "." : "",
3993 arc_condition_codes[arc_ccfsm_current.cc]);
3994 /* If this is a jump, there are still short variants. However,
3995 only beq_s / bne_s have the same offset range as b_s,
3996 and the only short conditional returns are jeq_s and jne_s. */
3997 if (code == '!'
3998 && (arc_ccfsm_current.cc == ARC_CC_EQ
3999 || arc_ccfsm_current.cc == ARC_CC_NE
4000 || 0 /* FIXME: check if branch in 7 bit range. */))
4001 output_short_suffix (file);
4003 else if (code == '!') /* Jump with delay slot. */
4004 fputs (arc_condition_codes[arc_ccfsm_current.cc], file);
4005 else /* An Instruction in a delay slot of a jump or call. */
4007 rtx jump = XVECEXP (final_sequence, 0, 0);
4008 rtx insn = XVECEXP (final_sequence, 0, 1);
4010 /* If the insn is annulled and is from the target path, we need
4011 to inverse the condition test. */
4012 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
4014 if (INSN_FROM_TARGET_P (insn))
4015 fprintf (file, "%s%s",
4016 code == '?' ? "." : "",
4017 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (arc_ccfsm_current.cc)]);
4018 else
4019 fprintf (file, "%s%s",
4020 code == '?' ? "." : "",
4021 arc_condition_codes[arc_ccfsm_current.cc]);
4022 if (arc_ccfsm_current.state == 5)
4023 arc_ccfsm_current.state = 0;
4025 else
4026 /* This insn is executed for either path, so don't
4027 conditionalize it at all. */
4028 output_short_suffix (file);
4032 else
4033 output_short_suffix (file);
4034 return;
4035 case'`':
4036 /* FIXME: fold constant inside unary operator, re-recognize, and emit. */
4037 gcc_unreachable ();
4038 case 'd' :
4039 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
4040 return;
4041 case 'D' :
4042 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
4043 (get_arc_condition_code (x))],
4044 file);
4045 return;
4046 case 'R' :
4047 /* Write second word of DImode or DFmode reference,
4048 register or memory. */
4049 if (GET_CODE (x) == REG)
4050 fputs (reg_names[REGNO (x)+1], file);
4051 else if (GET_CODE (x) == MEM)
4053 fputc ('[', file);
4055 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
4056 PRE_MODIFY, we will have handled the first word already;
4057 For POST_INC / POST_DEC / POST_MODIFY, the access to the
4058 first word will be done later. In either case, the access
4059 to the first word will do the modify, and we only have
4060 to add an offset of four here. */
4061 if (GET_CODE (XEXP (x, 0)) == PRE_INC
4062 || GET_CODE (XEXP (x, 0)) == PRE_DEC
4063 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
4064 || GET_CODE (XEXP (x, 0)) == POST_INC
4065 || GET_CODE (XEXP (x, 0)) == POST_DEC
4066 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
4067 output_address (VOIDmode,
4068 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
4069 else if (output_scaled)
4071 rtx addr = XEXP (x, 0);
4072 int size = GET_MODE_SIZE (GET_MODE (x));
4074 output_address (VOIDmode,
4075 plus_constant (Pmode, XEXP (addr, 0),
4076 ((INTVAL (XEXP (addr, 1)) + 4)
4077 >> (size == 2 ? 1 : 2))));
4078 output_scaled = 0;
4080 else
4081 output_address (VOIDmode,
4082 plus_constant (Pmode, XEXP (x, 0), 4));
4083 fputc (']', file);
4085 else
4086 output_operand_lossage ("invalid operand to %%R code");
4087 return;
4088 case 'j':
4089 case 'S' :
4090 if (GET_CODE (x) == SYMBOL_REF
4091 && arc_is_jli_call_p (x))
4093 if (SYMBOL_REF_DECL (x))
4095 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4096 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4097 : NULL_TREE);
4098 if (lookup_attribute ("jli_fixed", attrs))
4100 /* No special treatment for jli_fixed functions. */
4101 if (code == 'j')
4102 break;
4103 fprintf (file, "%ld\t; @",
4104 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4105 assemble_name (file, XSTR (x, 0));
4106 return;
4109 fprintf (file, "@__jli.");
4110 assemble_name (file, XSTR (x, 0));
4111 if (code == 'j')
4112 arc_add_jli_section (x);
4113 return;
4115 if (GET_CODE (x) == SYMBOL_REF
4116 && arc_is_secure_call_p (x))
4118 /* No special treatment for secure functions. */
4119 if (code == 'j' )
4120 break;
4121 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
4122 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
4123 : NULL_TREE);
4124 fprintf (file, "%ld\t; @",
4125 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
4126 assemble_name (file, XSTR (x, 0));
4127 return;
4129 break;
4130 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
4131 if (CONSTANT_P (x))
4133 output_addr_const (file, x);
4134 return;
4136 break;
4137 case 'H' :
4138 case 'L' :
4139 if (GET_CODE (x) == REG)
4141 /* L = least significant word, H = most significant word. */
4142 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
4143 fputs (reg_names[REGNO (x)], file);
4144 else
4145 fputs (reg_names[REGNO (x)+1], file);
4147 else if (GET_CODE (x) == CONST_INT
4148 || GET_CODE (x) == CONST_DOUBLE)
4150 rtx first, second, word;
4152 split_double (x, &first, &second);
4154 if((WORDS_BIG_ENDIAN) == 0)
4155 word = (code == 'L' ? first : second);
4156 else
4157 word = (code == 'L' ? second : first);
4159 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
4161 else
4162 output_operand_lossage ("invalid operand to %%H/%%L code");
4163 return;
4164 case 'A' :
4166 char str[30];
4168 gcc_assert (GET_CODE (x) == CONST_DOUBLE
4169 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
4171 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
4172 fprintf (file, "%s", str);
4173 return;
4175 case 'U' :
4176 /* Output a load/store with update indicator if appropriate. */
4177 if (GET_CODE (x) == MEM)
4179 rtx addr = XEXP (x, 0);
4180 switch (GET_CODE (addr))
4182 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
4183 fputs (".a", file); break;
4184 case POST_INC: case POST_DEC: case POST_MODIFY:
4185 fputs (".ab", file); break;
4186 case PLUS:
4187 /* Are we using a scaled index? */
4188 if (GET_CODE (XEXP (addr, 0)) == MULT)
4189 fputs (".as", file);
4190 /* Can we use a scaled offset? */
4191 else if (CONST_INT_P (XEXP (addr, 1))
4192 && GET_MODE_SIZE (GET_MODE (x)) > 1
4193 && (!(INTVAL (XEXP (addr, 1))
4194 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
4195 /* Does it make a difference? */
4196 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
4197 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
4199 fputs (".as", file);
4200 output_scaled = 1;
4202 break;
4203 case SYMBOL_REF:
4204 case CONST:
4205 if (legitimate_small_data_address_p (addr)
4206 && GET_MODE_SIZE (GET_MODE (x)) > 1)
4208 int align = get_symbol_alignment (addr);
4209 int mask = 0;
4210 switch (GET_MODE (x))
4212 case E_HImode:
4213 mask = 1;
4214 break;
4215 default:
4216 mask = 3;
4217 break;
4219 if (align && ((align & mask) == 0))
4220 fputs (".as", file);
4222 break;
4223 case REG:
4224 break;
4225 default:
4226 gcc_assert (CONSTANT_P (addr)); break;
4229 else
4230 output_operand_lossage ("invalid operand to %%U code");
4231 return;
4232 case 'V' :
4233 /* Output cache bypass indicator for a load/store insn. Volatile memory
4234 refs are defined to use the cache bypass mechanism. */
4235 if (GET_CODE (x) == MEM)
4237 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
4238 || arc_is_uncached_mem_p (x))
4239 fputs (".di", file);
4241 else
4242 output_operand_lossage ("invalid operand to %%V code");
4243 return;
4244 /* plt code. */
4245 case 'P':
4246 case 0 :
4247 /* Do nothing special. */
4248 break;
4249 case 'F':
4250 fputs (reg_names[REGNO (x)]+1, file);
4251 return;
4252 case '^':
4253 /* This punctuation character is needed because label references are
4254 printed in the output template using %l. This is a front end
4255 character, and when we want to emit a '@' before it, we have to use
4256 this '^'. */
4258 fputc('@',file);
4259 return;
4260 case 'O':
4261 /* Output an operator. */
4262 switch (GET_CODE (x))
4264 case PLUS: fputs ("add", file); return;
4265 case SS_PLUS: fputs ("adds", file); return;
4266 case AND: fputs ("and", file); return;
4267 case IOR: fputs ("or", file); return;
4268 case XOR: fputs ("xor", file); return;
4269 case MINUS: fputs ("sub", file); return;
4270 case SS_MINUS: fputs ("subs", file); return;
4271 case ASHIFT: fputs ("asl", file); return;
4272 case ASHIFTRT: fputs ("asr", file); return;
4273 case LSHIFTRT: fputs ("lsr", file); return;
4274 case ROTATERT: fputs ("ror", file); return;
4275 case MULT: fputs ("mpy", file); return;
4276 case ABS: fputs ("abs", file); return; /* Unconditional. */
4277 case NEG: fputs ("neg", file); return;
4278 case SS_NEG: fputs ("negs", file); return;
4279 case NOT: fputs ("not", file); return; /* Unconditional. */
4280 case ZERO_EXTEND:
4281 fputs ("ext", file); /* bmsk allows predication. */
4282 goto size_suffix;
4283 case SIGN_EXTEND: /* Unconditional. */
4284 fputs ("sex", file);
4285 size_suffix:
4286 switch (GET_MODE (XEXP (x, 0)))
4288 case E_QImode: fputs ("b", file); return;
4289 case E_HImode: fputs ("w", file); return;
4290 default: break;
4292 break;
4293 case SS_TRUNCATE:
4294 if (GET_MODE (x) != HImode)
4295 break;
4296 fputs ("sat16", file);
4297 default: break;
4299 output_operand_lossage ("invalid operand to %%O code"); return;
4300 case 'o':
4301 if (GET_CODE (x) == SYMBOL_REF)
4303 assemble_name (file, XSTR (x, 0));
4304 return;
4306 break;
4307 case '&':
4308 if (TARGET_ANNOTATE_ALIGN)
4309 fprintf (file, "; unalign: %d", cfun->machine->unalign);
4310 return;
4311 case '+':
4312 if (TARGET_V2)
4313 fputs ("m", file);
4314 else
4315 fputs ("h", file);
4316 return;
4317 case '_':
4318 if (TARGET_V2)
4319 fputs ("h", file);
4320 else
4321 fputs ("w", file);
4322 return;
4323 default :
4324 /* Unknown flag. */
4325 output_operand_lossage ("invalid operand output code");
4328 switch (GET_CODE (x))
4330 case REG :
4331 fputs (reg_names[REGNO (x)], file);
4332 break;
4333 case MEM :
4335 rtx addr = XEXP (x, 0);
4336 int size = GET_MODE_SIZE (GET_MODE (x));
4338 if (legitimate_small_data_address_p (addr))
4339 output_sdata = 1;
4341 fputc ('[', file);
4343 switch (GET_CODE (addr))
4345 case PRE_INC: case POST_INC:
4346 output_address (VOIDmode,
4347 plus_constant (Pmode, XEXP (addr, 0), size)); break;
4348 case PRE_DEC: case POST_DEC:
4349 output_address (VOIDmode,
4350 plus_constant (Pmode, XEXP (addr, 0), -size));
4351 break;
4352 case PRE_MODIFY: case POST_MODIFY:
4353 output_address (VOIDmode, XEXP (addr, 1)); break;
4354 case PLUS:
4355 if (output_scaled)
4357 output_address (VOIDmode,
4358 plus_constant (Pmode, XEXP (addr, 0),
4359 (INTVAL (XEXP (addr, 1))
4360 >> (size == 2 ? 1 : 2))));
4361 output_scaled = 0;
4363 else
4364 output_address (VOIDmode, addr);
4365 break;
4366 default:
4367 if (flag_pic && CONSTANT_ADDRESS_P (addr))
4368 arc_output_pic_addr_const (file, addr, code);
4369 else
4370 output_address (VOIDmode, addr);
4371 break;
4373 fputc (']', file);
4374 break;
4376 case CONST_DOUBLE :
4377 /* We handle SFmode constants here as output_addr_const doesn't. */
4378 if (GET_MODE (x) == SFmode)
4380 long l;
4382 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
4383 fprintf (file, "0x%08lx", l);
4384 break;
4386 /* FALLTHRU */
4387 /* Let output_addr_const deal with it. */
4388 default :
4389 if (flag_pic
4390 || (GET_CODE (x) == CONST
4391 && GET_CODE (XEXP (x, 0)) == UNSPEC
4392 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
4393 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
4394 || (GET_CODE (x) == CONST
4395 && GET_CODE (XEXP (x, 0)) == PLUS
4396 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
4397 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
4398 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
4399 arc_output_pic_addr_const (file, x, code);
4400 else
4401 output_addr_const (file, x);
4402 break;
4406 /* Print a memory address as an operand to reference that memory location. */
4408 void
4409 arc_print_operand_address (FILE *file , rtx addr)
4411 register rtx base, index = 0;
4413 switch (GET_CODE (addr))
4415 case REG :
4416 fputs (reg_names[REGNO (addr)], file);
4417 break;
4418 case SYMBOL_REF:
4419 if (output_sdata)
4420 fputs ("gp,", file);
4421 output_addr_const (file, addr);
4422 if (output_sdata)
4423 fputs ("@sda", file);
4424 output_sdata = 0;
4425 break;
4426 case PLUS :
4427 if (GET_CODE (XEXP (addr, 0)) == MULT)
4428 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
4429 else if (CONST_INT_P (XEXP (addr, 0)))
4430 index = XEXP (addr, 0), base = XEXP (addr, 1);
4431 else
4432 base = XEXP (addr, 0), index = XEXP (addr, 1);
4434 gcc_assert (OBJECT_P (base));
4435 arc_print_operand_address (file, base);
4436 if (CONSTANT_P (base) && CONST_INT_P (index))
4437 fputc ('+', file);
4438 else
4439 fputc (',', file);
4440 gcc_assert (OBJECT_P (index));
4441 arc_print_operand_address (file, index);
4442 break;
4443 case CONST:
4445 rtx c = XEXP (addr, 0);
4447 if ((GET_CODE (c) == UNSPEC
4448 && (XINT (c, 1) == UNSPEC_TLS_OFF
4449 || XINT (c, 1) == UNSPEC_TLS_IE))
4450 || (GET_CODE (c) == PLUS
4451 && GET_CODE (XEXP (c, 0)) == UNSPEC
4452 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
4453 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
4455 arc_output_pic_addr_const (file, c, 0);
4456 break;
4458 gcc_assert (GET_CODE (c) == PLUS);
4459 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
4460 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
4462 output_address (VOIDmode, XEXP (addr, 0));
4464 break;
4466 case PRE_INC :
4467 case PRE_DEC :
4468 /* We shouldn't get here as we've lost the mode of the memory object
4469 (which says how much to inc/dec by. */
4470 gcc_unreachable ();
4471 break;
4472 default :
4473 if (flag_pic)
4474 arc_output_pic_addr_const (file, addr, 0);
4475 else
4476 output_addr_const (file, addr);
4477 break;
4481 /* Conditional execution support.
4483 This is based on the ARM port but for now is much simpler.
4485 A finite state machine takes care of noticing whether or not instructions
4486 can be conditionally executed, and thus decrease execution time and code
4487 size by deleting branch instructions. The fsm is controlled by
4488 arc_ccfsm_advance (called by arc_final_prescan_insn), and controls the
4489 actions of PRINT_OPERAND. The patterns in the .md file for the branch
4490 insns also have a hand in this. */
4491 /* The way we leave dealing with non-anulled or annull-false delay slot
4492 insns to the consumer is awkward. */
4494 /* The state of the fsm controlling condition codes are:
4495 0: normal, do nothing special
4496 1: don't output this insn
4497 2: don't output this insn
4498 3: make insns conditional
4499 4: make insns conditional
4500 5: make insn conditional (only for outputting anulled delay slot insns)
4502 special value for cfun->machine->uid_ccfsm_state:
4503 6: return with but one insn before it since function start / call
4505 State transitions (state->state by whom, under what condition):
4506 0 -> 1 arc_ccfsm_advance, if insn is a conditional branch skipping over
4507 some instructions.
4508 0 -> 2 arc_ccfsm_advance, if insn is a conditional branch followed
4509 by zero or more non-jump insns and an unconditional branch with
4510 the same target label as the condbranch.
4511 1 -> 3 branch patterns, after having not output the conditional branch
4512 2 -> 4 branch patterns, after having not output the conditional branch
4513 0 -> 5 branch patterns, for anulled delay slot insn.
4514 3 -> 0 ASM_OUTPUT_INTERNAL_LABEL, if the `target' label is reached
4515 (the target label has CODE_LABEL_NUMBER equal to
4516 arc_ccfsm_target_label).
4517 4 -> 0 arc_ccfsm_advance, if `target' unconditional branch is reached
4518 3 -> 1 arc_ccfsm_advance, finding an 'else' jump skipping over some insns.
4519 5 -> 0 when outputting the delay slot insn
4521 If the jump clobbers the conditions then we use states 2 and 4.
4523 A similar thing can be done with conditional return insns.
4525 We also handle separating branches from sets of the condition code.
4526 This is done here because knowledge of the ccfsm state is required,
4527 we may not be outputting the branch. */
4529 /* arc_final_prescan_insn calls arc_ccfsm_advance to adjust arc_ccfsm_current,
4530 before letting final output INSN. */
4532 static void
4533 arc_ccfsm_advance (rtx_insn *insn, struct arc_ccfsm *state)
4535 /* BODY will hold the body of INSN. */
4536 register rtx body;
4538 /* This will be 1 if trying to repeat the trick (ie: do the `else' part of
4539 an if/then/else), and things need to be reversed. */
4540 int reverse = 0;
4542 /* If we start with a return insn, we only succeed if we find another one. */
4543 int seeking_return = 0;
4545 /* START_INSN will hold the insn from where we start looking. This is the
4546 first insn after the following code_label if REVERSE is true. */
4547 rtx_insn *start_insn = insn;
4549 /* Type of the jump_insn. Brcc insns don't affect ccfsm changes,
4550 since they don't rely on a cmp preceding the. */
4551 enum attr_type jump_insn_type;
4553 /* Allow -mdebug-ccfsm to turn this off so we can see how well it does.
4554 We can't do this in macro FINAL_PRESCAN_INSN because its called from
4555 final_scan_insn which has `optimize' as a local. */
4556 if (optimize < 2 || TARGET_NO_COND_EXEC)
4557 return;
4559 /* Ignore notes and labels. */
4560 if (!INSN_P (insn))
4561 return;
4562 body = PATTERN (insn);
4563 /* If in state 4, check if the target branch is reached, in order to
4564 change back to state 0. */
4565 if (state->state == 4)
4567 if (insn == state->target_insn)
4569 state->target_insn = NULL;
4570 state->state = 0;
4572 return;
4575 /* If in state 3, it is possible to repeat the trick, if this insn is an
4576 unconditional branch to a label, and immediately following this branch
4577 is the previous target label which is only used once, and the label this
4578 branch jumps to is not too far off. Or in other words "we've done the
4579 `then' part, see if we can do the `else' part." */
4580 if (state->state == 3)
4582 if (simplejump_p (insn))
4584 start_insn = next_nonnote_insn (start_insn);
4585 if (GET_CODE (start_insn) == BARRIER)
4587 /* ??? Isn't this always a barrier? */
4588 start_insn = next_nonnote_insn (start_insn);
4590 if (GET_CODE (start_insn) == CODE_LABEL
4591 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4592 && LABEL_NUSES (start_insn) == 1)
4593 reverse = TRUE;
4594 else
4595 return;
4597 else if (GET_CODE (body) == SIMPLE_RETURN)
4599 start_insn = next_nonnote_insn (start_insn);
4600 if (GET_CODE (start_insn) == BARRIER)
4601 start_insn = next_nonnote_insn (start_insn);
4602 if (GET_CODE (start_insn) == CODE_LABEL
4603 && CODE_LABEL_NUMBER (start_insn) == state->target_label
4604 && LABEL_NUSES (start_insn) == 1)
4606 reverse = TRUE;
4607 seeking_return = 1;
4609 else
4610 return;
4612 else
4613 return;
4616 if (GET_CODE (insn) != JUMP_INSN
4617 || GET_CODE (PATTERN (insn)) == ADDR_VEC
4618 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
4619 return;
4621 /* We can't predicate BRCC or loop ends.
4622 Also, when generating PIC code, and considering a medium range call,
4623 we can't predicate the call. */
4624 jump_insn_type = get_attr_type (insn);
4625 if (jump_insn_type == TYPE_BRCC
4626 || jump_insn_type == TYPE_BRCC_NO_DELAY_SLOT
4627 || jump_insn_type == TYPE_LOOP_END
4628 || (jump_insn_type == TYPE_CALL && !get_attr_predicable (insn)))
4629 return;
4631 /* This jump might be paralleled with a clobber of the condition codes,
4632 the jump should always come first. */
4633 if (GET_CODE (body) == PARALLEL && XVECLEN (body, 0) > 0)
4634 body = XVECEXP (body, 0, 0);
4636 if (reverse
4637 || (GET_CODE (body) == SET && GET_CODE (SET_DEST (body)) == PC
4638 && GET_CODE (SET_SRC (body)) == IF_THEN_ELSE))
4640 int insns_skipped = 0, fail = FALSE, succeed = FALSE;
4641 /* Flag which part of the IF_THEN_ELSE is the LABEL_REF. */
4642 int then_not_else = TRUE;
4643 /* Nonzero if next insn must be the target label. */
4644 int next_must_be_target_label_p;
4645 rtx_insn *this_insn = start_insn;
4646 rtx label = 0;
4648 /* Register the insn jumped to. */
4649 if (reverse)
4651 if (!seeking_return)
4652 label = XEXP (SET_SRC (body), 0);
4654 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == LABEL_REF)
4655 label = XEXP (XEXP (SET_SRC (body), 1), 0);
4656 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == LABEL_REF)
4658 label = XEXP (XEXP (SET_SRC (body), 2), 0);
4659 then_not_else = FALSE;
4661 else if (GET_CODE (XEXP (SET_SRC (body), 1)) == SIMPLE_RETURN)
4662 seeking_return = 1;
4663 else if (GET_CODE (XEXP (SET_SRC (body), 2)) == SIMPLE_RETURN)
4665 seeking_return = 1;
4666 then_not_else = FALSE;
4668 else
4669 gcc_unreachable ();
4671 /* If this is a non-annulled branch with a delay slot, there is
4672 no need to conditionalize the delay slot. */
4673 if ((GET_CODE (PATTERN (NEXT_INSN (PREV_INSN (insn)))) == SEQUENCE)
4674 && state->state == 0 && !INSN_ANNULLED_BRANCH_P (insn))
4676 this_insn = NEXT_INSN (this_insn);
4678 /* See how many insns this branch skips, and what kind of insns. If all
4679 insns are okay, and the label or unconditional branch to the same
4680 label is not too far away, succeed. */
4681 for (insns_skipped = 0, next_must_be_target_label_p = FALSE;
4682 !fail && !succeed && insns_skipped < MAX_INSNS_SKIPPED;
4683 insns_skipped++)
4685 rtx scanbody;
4687 this_insn = next_nonnote_insn (this_insn);
4688 if (!this_insn)
4689 break;
4691 if (next_must_be_target_label_p)
4693 if (GET_CODE (this_insn) == BARRIER)
4694 continue;
4695 if (GET_CODE (this_insn) == CODE_LABEL
4696 && this_insn == label)
4698 state->state = 1;
4699 succeed = TRUE;
4701 else
4702 fail = TRUE;
4703 break;
4706 switch (GET_CODE (this_insn))
4708 case CODE_LABEL:
4709 /* Succeed if it is the target label, otherwise fail since
4710 control falls in from somewhere else. */
4711 if (this_insn == label)
4713 state->state = 1;
4714 succeed = TRUE;
4716 else
4717 fail = TRUE;
4718 break;
4720 case BARRIER:
4721 /* Succeed if the following insn is the target label.
4722 Otherwise fail.
4723 If return insns are used then the last insn in a function
4724 will be a barrier. */
4725 next_must_be_target_label_p = TRUE;
4726 break;
4728 case CALL_INSN:
4729 /* Can handle a call insn if there are no insns after it.
4730 IE: The next "insn" is the target label. We don't have to
4731 worry about delay slots as such insns are SEQUENCE's inside
4732 INSN's. ??? It is possible to handle such insns though. */
4733 if (get_attr_cond (this_insn) == COND_CANUSE)
4734 next_must_be_target_label_p = TRUE;
4735 else
4736 fail = TRUE;
4737 break;
4739 case JUMP_INSN:
4740 scanbody = PATTERN (this_insn);
4742 /* If this is an unconditional branch to the same label, succeed.
4743 If it is to another label, do nothing. If it is conditional,
4744 fail. */
4745 /* ??? Probably, the test for the SET and the PC are
4746 unnecessary. */
4748 if (GET_CODE (scanbody) == SET
4749 && GET_CODE (SET_DEST (scanbody)) == PC)
4751 if (GET_CODE (SET_SRC (scanbody)) == LABEL_REF
4752 && XEXP (SET_SRC (scanbody), 0) == label && !reverse)
4754 state->state = 2;
4755 succeed = TRUE;
4757 else if (GET_CODE (SET_SRC (scanbody)) == IF_THEN_ELSE)
4758 fail = TRUE;
4759 else if (get_attr_cond (this_insn) != COND_CANUSE)
4760 fail = TRUE;
4762 else if (GET_CODE (scanbody) == SIMPLE_RETURN
4763 && seeking_return)
4765 state->state = 2;
4766 succeed = TRUE;
4768 else if (GET_CODE (scanbody) == PARALLEL)
4770 if (get_attr_cond (this_insn) != COND_CANUSE)
4771 fail = TRUE;
4773 break;
4775 case INSN:
4776 scanbody = PATTERN (this_insn);
4778 /* We can only do this with insns that can use the condition
4779 codes (and don't set them). */
4780 if (GET_CODE (scanbody) == SET
4781 || GET_CODE (scanbody) == PARALLEL)
4783 if (get_attr_cond (this_insn) != COND_CANUSE)
4784 fail = TRUE;
4786 /* We can't handle other insns like sequences. */
4787 else
4788 fail = TRUE;
4789 break;
4791 default:
4792 break;
4796 if (succeed)
4798 if ((!seeking_return) && (state->state == 1 || reverse))
4799 state->target_label = CODE_LABEL_NUMBER (label);
4800 else if (seeking_return || state->state == 2)
4802 while (this_insn && GET_CODE (PATTERN (this_insn)) == USE)
4804 this_insn = next_nonnote_insn (this_insn);
4806 gcc_assert (!this_insn ||
4807 (GET_CODE (this_insn) != BARRIER
4808 && GET_CODE (this_insn) != CODE_LABEL));
4810 if (!this_insn)
4812 /* Oh dear! we ran off the end, give up. */
4813 extract_insn_cached (insn);
4814 state->state = 0;
4815 state->target_insn = NULL;
4816 return;
4818 state->target_insn = this_insn;
4820 else
4821 gcc_unreachable ();
4823 /* If REVERSE is true, ARM_CURRENT_CC needs to be inverted from
4824 what it was. */
4825 if (!reverse)
4827 state->cond = XEXP (SET_SRC (body), 0);
4828 state->cc = get_arc_condition_code (XEXP (SET_SRC (body), 0));
4831 if (reverse || then_not_else)
4832 state->cc = ARC_INVERSE_CONDITION_CODE (state->cc);
4835 /* Restore recog_operand. Getting the attributes of other insns can
4836 destroy this array, but final.c assumes that it remains intact
4837 across this call; since the insn has been recognized already we
4838 call insn_extract direct. */
4839 extract_insn_cached (insn);
4843 /* Record that we are currently outputting label NUM with prefix PREFIX.
4844 It it's the label we're looking for, reset the ccfsm machinery.
4846 Called from ASM_OUTPUT_INTERNAL_LABEL. */
4848 static void
4849 arc_ccfsm_at_label (const char *prefix, int num, struct arc_ccfsm *state)
4851 if (state->state == 3 && state->target_label == num
4852 && !strcmp (prefix, "L"))
4854 state->state = 0;
4855 state->target_insn = NULL;
4859 /* We are considering a conditional branch with the condition COND.
4860 Check if we want to conditionalize a delay slot insn, and if so modify
4861 the ccfsm state accordingly.
4862 REVERSE says branch will branch when the condition is false. */
4863 void
4864 arc_ccfsm_record_condition (rtx cond, bool reverse, rtx_insn *jump,
4865 struct arc_ccfsm *state)
4867 rtx_insn *seq_insn = NEXT_INSN (PREV_INSN (jump));
4868 if (!state)
4869 state = &arc_ccfsm_current;
4871 gcc_assert (state->state == 0);
4872 if (seq_insn != jump)
4874 rtx insn = XVECEXP (PATTERN (seq_insn), 0, 1);
4876 if (!as_a<rtx_insn *> (insn)->deleted ()
4877 && INSN_ANNULLED_BRANCH_P (jump)
4878 && (TARGET_AT_DBR_CONDEXEC || INSN_FROM_TARGET_P (insn)))
4880 state->cond = cond;
4881 state->cc = get_arc_condition_code (cond);
4882 if (!reverse)
4883 arc_ccfsm_current.cc
4884 = ARC_INVERSE_CONDITION_CODE (state->cc);
4885 rtx pat = PATTERN (insn);
4886 if (GET_CODE (pat) == COND_EXEC)
4887 gcc_assert ((INSN_FROM_TARGET_P (insn)
4888 ? ARC_INVERSE_CONDITION_CODE (state->cc) : state->cc)
4889 == get_arc_condition_code (XEXP (pat, 0)));
4890 else
4891 state->state = 5;
4896 /* Update *STATE as we would when we emit INSN. */
4898 static void
4899 arc_ccfsm_post_advance (rtx_insn *insn, struct arc_ccfsm *state)
4901 enum attr_type type;
4903 if (LABEL_P (insn))
4904 arc_ccfsm_at_label ("L", CODE_LABEL_NUMBER (insn), state);
4905 else if (JUMP_P (insn)
4906 && GET_CODE (PATTERN (insn)) != ADDR_VEC
4907 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
4908 && ((type = get_attr_type (insn)) == TYPE_BRANCH
4909 || ((type == TYPE_UNCOND_BRANCH
4910 || type == TYPE_RETURN)
4911 && ARC_CCFSM_BRANCH_DELETED_P (state))))
4913 if (ARC_CCFSM_BRANCH_DELETED_P (state))
4914 ARC_CCFSM_RECORD_BRANCH_DELETED (state);
4915 else
4917 rtx src = SET_SRC (PATTERN (insn));
4918 arc_ccfsm_record_condition (XEXP (src, 0), XEXP (src, 1) == pc_rtx,
4919 insn, state);
4922 else if (arc_ccfsm_current.state == 5)
4923 arc_ccfsm_current.state = 0;
4926 /* Return true if the current insn, which is a conditional branch, is to be
4927 deleted. */
4929 bool
4930 arc_ccfsm_branch_deleted_p (void)
4932 return ARC_CCFSM_BRANCH_DELETED_P (&arc_ccfsm_current);
4935 /* Record a branch isn't output because subsequent insns can be
4936 conditionalized. */
4938 void
4939 arc_ccfsm_record_branch_deleted (void)
4941 ARC_CCFSM_RECORD_BRANCH_DELETED (&arc_ccfsm_current);
4944 /* During insn output, indicate if the current insn is predicated. */
4946 bool
4947 arc_ccfsm_cond_exec_p (void)
4949 return (cfun->machine->prescan_initialized
4950 && ARC_CCFSM_COND_EXEC_P (&arc_ccfsm_current));
4953 /* When deciding if an insn should be output short, we want to know something
4954 about the following insns:
4955 - if another insn follows which we know we can output as a short insn
4956 before an alignment-sensitive point, we can output this insn short:
4957 the decision about the eventual alignment can be postponed.
4958 - if a to-be-aligned label comes next, we should output this insn such
4959 as to get / preserve 4-byte alignment.
4960 - if a likely branch without delay slot insn, or a call with an immediately
4961 following short insn comes next, we should out output this insn such as to
4962 get / preserve 2 mod 4 unalignment.
4963 - do the same for a not completely unlikely branch with a short insn
4964 following before any other branch / label.
4965 - in order to decide if we are actually looking at a branch, we need to
4966 call arc_ccfsm_advance.
4967 - in order to decide if we are looking at a short insn, we should know
4968 if it is conditionalized. To a first order of approximation this is
4969 the case if the state from arc_ccfsm_advance from before this insn
4970 indicates the insn is conditionalized. However, a further refinement
4971 could be to not conditionalize an insn if the destination register(s)
4972 is/are dead in the non-executed case. */
4973 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
4974 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
4975 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
4977 static int
4978 arc_verify_short (rtx_insn *insn, int, int check_attr)
4980 enum attr_iscompact iscompact;
4982 if (check_attr > 0)
4984 iscompact = get_attr_iscompact (insn);
4985 if (iscompact == ISCOMPACT_FALSE)
4986 return 0;
4989 return (get_attr_length (insn) & 2) != 0;
4992 /* When outputting an instruction (alternative) that can potentially be short,
4993 output the short suffix if the insn is in fact short, and update
4994 cfun->machine->unalign accordingly. */
4996 static void
4997 output_short_suffix (FILE *file)
4999 rtx_insn *insn = current_output_insn;
5001 if (arc_verify_short (insn, cfun->machine->unalign, 1))
5003 fprintf (file, "_s");
5004 cfun->machine->unalign ^= 2;
5006 /* Restore recog_operand. */
5007 extract_insn_cached (insn);
5010 /* Implement FINAL_PRESCAN_INSN. */
5012 void
5013 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
5014 int noperands ATTRIBUTE_UNUSED)
5016 if (TARGET_DUMPISIZE)
5017 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
5019 if (!cfun->machine->prescan_initialized)
5021 /* Clear lingering state from branch shortening. */
5022 memset (&arc_ccfsm_current, 0, sizeof arc_ccfsm_current);
5023 cfun->machine->prescan_initialized = 1;
5025 arc_ccfsm_advance (insn, &arc_ccfsm_current);
5028 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5029 Frame pointer elimination is automatically handled.
5031 All eliminations are permissible. If we need a frame
5032 pointer, we must eliminate ARG_POINTER_REGNUM into
5033 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5035 static bool
5036 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
5038 return ((to == FRAME_POINTER_REGNUM) || !arc_frame_pointer_needed ());
5041 /* Define the offset between two registers, one to be eliminated, and
5042 the other its replacement, at the start of a routine. */
5045 arc_initial_elimination_offset (int from, int to)
5047 if (!cfun->machine->frame_info.initialized)
5048 arc_compute_frame_size ();
5050 if (from == ARG_POINTER_REGNUM && to == FRAME_POINTER_REGNUM)
5052 return (cfun->machine->frame_info.extra_size
5053 + cfun->machine->frame_info.reg_size);
5056 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
5058 return (cfun->machine->frame_info.total_size
5059 - cfun->machine->frame_info.pretend_size);
5062 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
5064 return (cfun->machine->frame_info.total_size
5065 - (cfun->machine->frame_info.pretend_size
5066 + cfun->machine->frame_info.extra_size
5067 + cfun->machine->frame_info.reg_size));
5070 gcc_unreachable ();
5073 static bool
5074 arc_frame_pointer_required (void)
5076 return cfun->calls_alloca || crtl->calls_eh_return;
5080 /* Return the destination address of a branch. */
5082 static int
5083 branch_dest (rtx branch)
5085 rtx pat = PATTERN (branch);
5086 rtx dest = (GET_CODE (pat) == PARALLEL
5087 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
5088 int dest_uid;
5090 if (GET_CODE (dest) == IF_THEN_ELSE)
5091 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
5093 dest = XEXP (dest, 0);
5094 dest_uid = INSN_UID (dest);
5096 return INSN_ADDRESSES (dest_uid);
5100 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5102 static void
5103 arc_encode_section_info (tree decl, rtx rtl, int first)
5105 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5106 This clears machine specific flags, so has to come first. */
5107 default_encode_section_info (decl, rtl, first);
5109 /* Check if it is a function, and whether it has the
5110 [long/medium/short]_call attribute specified. */
5111 if (TREE_CODE (decl) == FUNCTION_DECL)
5113 rtx symbol = XEXP (rtl, 0);
5114 int flags = SYMBOL_REF_FLAGS (symbol);
5116 tree attr = (TREE_TYPE (decl) != error_mark_node
5117 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
5118 tree long_call_attr = lookup_attribute ("long_call", attr);
5119 tree medium_call_attr = lookup_attribute ("medium_call", attr);
5120 tree short_call_attr = lookup_attribute ("short_call", attr);
5122 if (long_call_attr != NULL_TREE)
5123 flags |= SYMBOL_FLAG_LONG_CALL;
5124 else if (medium_call_attr != NULL_TREE)
5125 flags |= SYMBOL_FLAG_MEDIUM_CALL;
5126 else if (short_call_attr != NULL_TREE)
5127 flags |= SYMBOL_FLAG_SHORT_CALL;
5129 SYMBOL_REF_FLAGS (symbol) = flags;
5131 else if (TREE_CODE (decl) == VAR_DECL)
5133 rtx symbol = XEXP (rtl, 0);
5135 tree attr = (TREE_TYPE (decl) != error_mark_node
5136 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
5138 tree sec_attr = lookup_attribute ("section", attr);
5139 if (sec_attr)
5141 const char *sec_name
5142 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
5143 if (strcmp (sec_name, ".cmem") == 0
5144 || strcmp (sec_name, ".cmem_shared") == 0
5145 || strcmp (sec_name, ".cmem_private") == 0)
5146 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
5151 /* This is how to output a definition of an internal numbered label where
5152 PREFIX is the class of label and NUM is the number within the class. */
5154 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
5156 if (cfun)
5157 arc_ccfsm_at_label (prefix, labelno, &arc_ccfsm_current);
5158 default_internal_label (stream, prefix, labelno);
5161 /* Set the cpu type and print out other fancy things,
5162 at the top of the file. */
5164 static void arc_file_start (void)
5166 default_file_start ();
5167 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
5169 /* Set some want to have build attributes. */
5170 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5171 ATTRIBUTE_PCS);
5172 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5173 TARGET_RF16 ? 1 : 0);
5174 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5175 flag_pic ? 2 : 0);
5176 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5177 (arc_tp_regno != -1) ? 1 : 0);
5178 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5179 TARGET_NO_SDATA_SET ? 0 : 2);
5180 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5181 TARGET_OPTFPE ? 1 : 0);
5182 if (TARGET_V2)
5183 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5184 arc_tune == ARC_TUNE_CORE_3 ? 3 : 2);
5187 /* Implement `TARGET_ASM_FILE_END'. */
5188 /* Outputs to the stdio stream FILE jli related text. */
5190 void arc_file_end (void)
5192 arc_jli_section *sec = arc_jli_sections;
5194 while (sec != NULL)
5196 fprintf (asm_out_file, "\n");
5197 fprintf (asm_out_file, "# JLI entry for function ");
5198 assemble_name (asm_out_file, sec->name);
5199 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
5200 ".jlitab.");
5201 assemble_name (asm_out_file, sec->name);
5202 fprintf (asm_out_file,", comdat\n");
5204 fprintf (asm_out_file, "\t.align\t4\n");
5205 fprintf (asm_out_file, "__jli.");
5206 assemble_name (asm_out_file, sec->name);
5207 fprintf (asm_out_file, ":\n\t.weak __jli.");
5208 assemble_name (asm_out_file, sec->name);
5209 fprintf (asm_out_file, "\n\tb\t@");
5210 assemble_name (asm_out_file, sec->name);
5211 fprintf (asm_out_file, "\n");
5212 sec = sec->next;
5214 file_end_indicate_exec_stack ();
5217 /* Cost functions. */
5219 /* Compute a (partial) cost for rtx X. Return true if the complete
5220 cost has been computed, and false if subexpressions should be
5221 scanned. In either case, *TOTAL contains the cost result. */
5223 static bool
5224 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
5225 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5227 int code = GET_CODE (x);
5229 switch (code)
5231 /* Small integers are as cheap as registers. */
5232 case CONST_INT:
5234 bool nolimm = false; /* Can we do without long immediate? */
5235 bool fast = false; /* Is the result available immediately? */
5236 bool condexec = false; /* Does this allow conditiobnal execution? */
5237 bool compact = false; /* Is a 16 bit opcode available? */
5238 /* CONDEXEC also implies that we can have an unconditional
5239 3-address operation. */
5241 nolimm = compact = condexec = false;
5242 if (UNSIGNED_INT6 (INTVAL (x)))
5243 nolimm = condexec = compact = true;
5244 else
5246 if (SMALL_INT (INTVAL (x)))
5247 nolimm = fast = true;
5248 switch (outer_code)
5250 case AND: /* bclr, bmsk, ext[bw] */
5251 if (satisfies_constraint_Ccp (x) /* bclr */
5252 || satisfies_constraint_C1p (x) /* bmsk */)
5253 nolimm = fast = condexec = compact = true;
5254 break;
5255 case IOR: /* bset */
5256 if (satisfies_constraint_C0p (x)) /* bset */
5257 nolimm = fast = condexec = compact = true;
5258 break;
5259 case XOR:
5260 if (satisfies_constraint_C0p (x)) /* bxor */
5261 nolimm = fast = condexec = true;
5262 break;
5263 case SET:
5264 if (satisfies_constraint_Crr (x)) /* ror b,u6 */
5265 nolimm = true;
5266 default:
5267 break;
5270 /* FIXME: Add target options to attach a small cost if
5271 condexec / compact is not true. */
5272 if (nolimm)
5274 *total = 0;
5275 return true;
5278 /* FALLTHRU */
5280 /* 4 byte values can be fetched as immediate constants -
5281 let's give that the cost of an extra insn. */
5282 case CONST:
5283 case LABEL_REF:
5284 case SYMBOL_REF:
5285 *total = COSTS_N_INSNS (1);
5286 return true;
5288 case CONST_DOUBLE:
5290 rtx first, second;
5292 if (TARGET_DPFP)
5294 *total = COSTS_N_INSNS (1);
5295 return true;
5297 split_double (x, &first, &second);
5298 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
5299 + !SMALL_INT (INTVAL (second)));
5300 return true;
5303 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5304 If we need more than 12 insns to do a multiply, then go out-of-line,
5305 since the call overhead will be < 10% of the cost of the multiply. */
5306 case ASHIFT:
5307 case ASHIFTRT:
5308 case LSHIFTRT:
5309 if (TARGET_BARREL_SHIFTER)
5311 /* If we want to shift a constant, we need a LIMM. */
5312 /* ??? when the optimizers want to know if a constant should be
5313 hoisted, they ask for the cost of the constant. OUTER_CODE is
5314 insufficient context for shifts since we don't know which operand
5315 we are looking at. */
5316 if (CONSTANT_P (XEXP (x, 0)))
5318 *total += (COSTS_N_INSNS (2)
5319 + rtx_cost (XEXP (x, 1), mode, (enum rtx_code) code,
5320 0, speed));
5321 return true;
5323 *total = COSTS_N_INSNS (1);
5325 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5326 *total = COSTS_N_INSNS (16);
5327 else
5329 *total = COSTS_N_INSNS (INTVAL (XEXP ((x), 1)));
5330 /* ??? want_to_gcse_p can throw negative shift counts at us,
5331 and then panics when it gets a negative cost as result.
5332 Seen for gcc.c-torture/compile/20020710-1.c -Os . */
5333 if (*total < 0)
5334 *total = 0;
5336 return false;
5338 case DIV:
5339 case UDIV:
5340 if (speed)
5341 *total = COSTS_N_INSNS(30);
5342 else
5343 *total = COSTS_N_INSNS(1);
5344 return false;
5346 case MULT:
5347 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5348 *total = COSTS_N_INSNS (1);
5349 else if (speed)
5350 *total= arc_multcost;
5351 /* We do not want synth_mult sequences when optimizing
5352 for size. */
5353 else if (TARGET_MUL64_SET || TARGET_ARC700_MPY)
5354 *total = COSTS_N_INSNS (1);
5355 else
5356 *total = COSTS_N_INSNS (2);
5357 return false;
5358 case PLUS:
5359 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5360 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5361 || (GET_CODE (XEXP (x, 0)) == MULT
5362 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5364 *total += (rtx_cost (XEXP (x, 1), mode, PLUS, 0, speed)
5365 + rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed));
5366 return true;
5368 return false;
5369 case MINUS:
5370 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5371 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5372 || (GET_CODE (XEXP (x, 1)) == MULT
5373 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5375 *total += (rtx_cost (XEXP (x, 0), mode, PLUS, 0, speed)
5376 + rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed));
5377 return true;
5379 return false;
5380 case COMPARE:
5382 rtx op0 = XEXP (x, 0);
5383 rtx op1 = XEXP (x, 1);
5385 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5386 && XEXP (op0, 1) == const1_rtx)
5388 /* btst / bbit0 / bbit1:
5389 Small integers and registers are free; everything else can
5390 be put in a register. */
5391 mode = GET_MODE (XEXP (op0, 0));
5392 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5393 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5394 return true;
5396 if (GET_CODE (op0) == AND && op1 == const0_rtx
5397 && satisfies_constraint_C1p (XEXP (op0, 1)))
5399 /* bmsk.f */
5400 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5401 return true;
5403 /* add.f */
5404 if (GET_CODE (op1) == NEG)
5406 /* op0 might be constant, the inside of op1 is rather
5407 unlikely to be so. So swapping the operands might lower
5408 the cost. */
5409 mode = GET_MODE (op0);
5410 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5411 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5413 return false;
5415 case EQ: case NE:
5416 if (outer_code == IF_THEN_ELSE
5417 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5418 && XEXP (x, 1) == const0_rtx
5419 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5421 /* btst / bbit0 / bbit1:
5422 Small integers and registers are free; everything else can
5423 be put in a register. */
5424 rtx op0 = XEXP (x, 0);
5426 mode = GET_MODE (XEXP (op0, 0));
5427 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5428 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5429 return true;
5431 /* Fall through. */
5432 /* scc_insn expands into two insns. */
5433 case GTU: case GEU: case LEU:
5434 if (mode == SImode)
5435 *total += COSTS_N_INSNS (1);
5436 return false;
5437 case LTU: /* might use adc. */
5438 if (mode == SImode)
5439 *total += COSTS_N_INSNS (1) - 1;
5440 return false;
5441 default:
5442 return false;
5446 /* Return true if ADDR is a valid pic address.
5447 A valid pic address on arc should look like
5448 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
5450 bool
5451 arc_legitimate_pic_addr_p (rtx addr)
5453 if (GET_CODE (addr) != CONST)
5454 return false;
5456 addr = XEXP (addr, 0);
5459 if (GET_CODE (addr) == PLUS)
5461 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
5462 return false;
5463 addr = XEXP (addr, 0);
5466 if (GET_CODE (addr) != UNSPEC
5467 || XVECLEN (addr, 0) != 1)
5468 return false;
5470 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
5471 if (XINT (addr, 1) != ARC_UNSPEC_GOT
5472 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
5473 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
5474 && XINT (addr, 1) != UNSPEC_TLS_GD
5475 && XINT (addr, 1) != UNSPEC_TLS_IE)
5476 return false;
5478 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
5479 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
5480 return false;
5482 return true;
5487 /* Return true if OP contains a symbol reference. */
5489 static bool
5490 symbolic_reference_mentioned_p (rtx op)
5492 register const char *fmt;
5493 register int i;
5495 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
5496 return true;
5498 fmt = GET_RTX_FORMAT (GET_CODE (op));
5499 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5501 if (fmt[i] == 'E')
5503 register int j;
5505 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5506 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
5507 return true;
5510 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
5511 return true;
5514 return false;
5517 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
5518 If SKIP_LOCAL is true, skip symbols that bind locally.
5519 This is used further down in this file, and, without SKIP_LOCAL,
5520 in the addsi3 / subsi3 expanders when generating PIC code. */
5522 bool
5523 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
5525 register const char *fmt;
5526 register int i;
5528 if (GET_CODE(op) == UNSPEC)
5529 return false;
5531 if (GET_CODE (op) == SYMBOL_REF)
5533 if (SYMBOL_REF_TLS_MODEL (op))
5534 return true;
5535 if (!flag_pic)
5536 return false;
5537 tree decl = SYMBOL_REF_DECL (op);
5538 return !skip_local || !decl || !default_binds_local_p (decl);
5541 fmt = GET_RTX_FORMAT (GET_CODE (op));
5542 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
5544 if (fmt[i] == 'E')
5546 register int j;
5548 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
5549 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
5550 skip_local))
5551 return true;
5554 else if (fmt[i] == 'e'
5555 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
5556 skip_local))
5557 return true;
5560 return false;
5563 /* Get the thread pointer. */
5565 static rtx
5566 arc_get_tp (void)
5568 /* If arc_tp_regno has been set, we can use that hard register
5569 directly as a base register. */
5570 if (arc_tp_regno != -1)
5571 return gen_rtx_REG (Pmode, arc_tp_regno);
5573 /* Otherwise, call __read_tp. Copy the result to a pseudo to avoid
5574 conflicts with function arguments / results. */
5575 rtx reg = gen_reg_rtx (Pmode);
5576 emit_insn (gen_tls_load_tp_soft ());
5577 emit_move_insn (reg, gen_rtx_REG (Pmode, R0_REG));
5578 return reg;
5581 /* Helper to be used by TLS Global dynamic model. */
5583 static rtx
5584 arc_emit_call_tls_get_addr (rtx sym, int reloc, rtx eqv)
5586 rtx r0 = gen_rtx_REG (Pmode, R0_REG);
5587 rtx call_fusage = NULL_RTX;
5589 start_sequence ();
5591 rtx x = arc_unspec_offset (sym, reloc);
5592 emit_move_insn (r0, x);
5593 use_reg (&call_fusage, r0);
5595 gcc_assert (reloc == UNSPEC_TLS_GD);
5596 rtx call_insn = emit_call_insn (gen_tls_gd_get_addr (sym));
5597 /* Should we set RTL_CONST_CALL_P? We read memory, but not in a
5598 way that the application should care. */
5599 RTL_PURE_CALL_P (call_insn) = 1;
5600 add_function_usage_to (call_insn, call_fusage);
5602 rtx_insn *insns = get_insns ();
5603 end_sequence ();
5605 rtx dest = gen_reg_rtx (Pmode);
5606 emit_libcall_block (insns, dest, r0, eqv);
5607 return dest;
5610 #define DTPOFF_ZERO_SYM ".tdata"
5612 /* Return a legitimized address for ADDR,
5613 which is a SYMBOL_REF with tls_model MODEL. */
5615 static rtx
5616 arc_legitimize_tls_address (rtx addr, enum tls_model model)
5618 if (!flag_pic && model == TLS_MODEL_LOCAL_DYNAMIC)
5619 model = TLS_MODEL_LOCAL_EXEC;
5621 switch (model)
5623 case TLS_MODEL_LOCAL_DYNAMIC:
5624 rtx base;
5625 tree decl;
5626 const char *base_name;
5627 rtvec v;
5629 decl = SYMBOL_REF_DECL (addr);
5630 base_name = DTPOFF_ZERO_SYM;
5631 if (decl && bss_initializer_p (decl))
5632 base_name = ".tbss";
5634 base = gen_rtx_SYMBOL_REF (Pmode, base_name);
5635 if (strcmp (base_name, DTPOFF_ZERO_SYM) == 0)
5637 if (!flag_pic)
5638 goto local_exec;
5639 v = gen_rtvec (1, addr);
5641 else
5642 v = gen_rtvec (2, addr, base);
5643 addr = gen_rtx_UNSPEC (Pmode, v, UNSPEC_TLS_OFF);
5644 addr = gen_rtx_CONST (Pmode, addr);
5645 base = arc_legitimize_tls_address (base, TLS_MODEL_GLOBAL_DYNAMIC);
5646 return gen_rtx_PLUS (Pmode, force_reg (Pmode, base), addr);
5648 case TLS_MODEL_GLOBAL_DYNAMIC:
5649 return arc_emit_call_tls_get_addr (addr, UNSPEC_TLS_GD, addr);
5651 case TLS_MODEL_INITIAL_EXEC:
5652 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
5653 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
5654 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5656 case TLS_MODEL_LOCAL_EXEC:
5657 local_exec:
5658 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
5659 return gen_rtx_PLUS (Pmode, arc_get_tp (), addr);
5660 default:
5661 gcc_unreachable ();
5665 /* Legitimize a pic address reference in ORIG.
5666 The return value is the legitimated address.
5667 If OLDX is non-zero, it is the target to assign the address to first. */
5669 static rtx
5670 arc_legitimize_pic_address (rtx orig, rtx oldx)
5672 rtx addr = orig;
5673 rtx pat = orig;
5674 rtx base;
5676 if (oldx == orig)
5677 oldx = NULL;
5679 if (GET_CODE (addr) == LABEL_REF)
5680 ; /* Do nothing. */
5681 else if (GET_CODE (addr) == SYMBOL_REF)
5683 enum tls_model model = SYMBOL_REF_TLS_MODEL (addr);
5684 if (model != 0)
5685 return arc_legitimize_tls_address (addr, model);
5686 else if (!flag_pic)
5687 return orig;
5688 else if (CONSTANT_POOL_ADDRESS_P (addr) || SYMBOL_REF_LOCAL_P (addr))
5689 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
5691 /* This symbol must be referenced via a load from the Global
5692 Offset Table (@GOTPC). */
5693 pat = arc_unspec_offset (addr, ARC_UNSPEC_GOT);
5694 pat = gen_const_mem (Pmode, pat);
5696 if (oldx == NULL)
5697 oldx = gen_reg_rtx (Pmode);
5699 emit_move_insn (oldx, pat);
5700 pat = oldx;
5702 else
5704 if (GET_CODE (addr) == CONST)
5706 addr = XEXP (addr, 0);
5707 if (GET_CODE (addr) == UNSPEC)
5709 /* Check that the unspec is one of the ones we generate? */
5710 return orig;
5712 /* fwprop is placing in the REG_EQUIV notes constant pic
5713 unspecs expressions. Then, loop may use these notes for
5714 optimizations resulting in complex patterns that are not
5715 supported by the current implementation. The following
5716 two if-cases are simplifying the complex patters to
5717 simpler ones. */
5718 else if (GET_CODE (addr) == MINUS)
5720 rtx op0 = XEXP (addr, 0);
5721 rtx op1 = XEXP (addr, 1);
5722 gcc_assert (oldx);
5723 gcc_assert (GET_CODE (op1) == UNSPEC);
5725 emit_move_insn (oldx,
5726 gen_rtx_CONST (SImode,
5727 arc_legitimize_pic_address (op1,
5728 NULL_RTX)));
5729 emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
5730 return oldx;
5733 else if (GET_CODE (addr) != PLUS)
5735 rtx tmp = XEXP (addr, 0);
5736 enum rtx_code code = GET_CODE (addr);
5738 /* It only works for UNARY operations. */
5739 gcc_assert (UNARY_P (addr));
5740 gcc_assert (GET_CODE (tmp) == UNSPEC);
5741 gcc_assert (oldx);
5743 emit_move_insn
5744 (oldx,
5745 gen_rtx_CONST (SImode,
5746 arc_legitimize_pic_address (tmp,
5747 NULL_RTX)));
5749 emit_insn (gen_rtx_SET (oldx,
5750 gen_rtx_fmt_ee (code, SImode,
5751 oldx, const0_rtx)));
5753 return oldx;
5755 else
5757 gcc_assert (GET_CODE (addr) == PLUS);
5758 if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
5759 return orig;
5763 if (GET_CODE (addr) == PLUS)
5765 rtx op0 = XEXP (addr, 0), op1 = XEXP (addr, 1);
5767 base = arc_legitimize_pic_address (op0, oldx);
5768 pat = arc_legitimize_pic_address (op1,
5769 base == oldx ? NULL_RTX : oldx);
5771 if (base == op0 && pat == op1)
5772 return orig;
5774 if (GET_CODE (pat) == CONST_INT)
5775 pat = plus_constant (Pmode, base, INTVAL (pat));
5776 else
5778 if (GET_CODE (pat) == PLUS && CONSTANT_P (XEXP (pat, 1)))
5780 base = gen_rtx_PLUS (Pmode, base, XEXP (pat, 0));
5781 pat = XEXP (pat, 1);
5783 pat = gen_rtx_PLUS (Pmode, base, pat);
5788 return pat;
5791 /* Output address constant X to FILE, taking PIC into account. */
5793 static void
5794 arc_output_pic_addr_const (FILE * file, rtx x, int code)
5796 char buf[256];
5798 restart:
5799 switch (GET_CODE (x))
5801 case PC:
5802 if (flag_pic)
5803 putc ('.', file);
5804 else
5805 gcc_unreachable ();
5806 break;
5808 case SYMBOL_REF:
5809 output_addr_const (file, x);
5811 /* Local functions do not get references through the PLT. */
5812 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
5813 fputs ("@plt", file);
5814 break;
5816 case LABEL_REF:
5817 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
5818 assemble_name (file, buf);
5819 break;
5821 case CODE_LABEL:
5822 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
5823 assemble_name (file, buf);
5824 break;
5826 case CONST_INT:
5827 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
5828 break;
5830 case CONST:
5831 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5832 break;
5834 case CONST_DOUBLE:
5835 if (GET_MODE (x) == VOIDmode)
5837 /* We can use %d if the number is one word and positive. */
5838 if (CONST_DOUBLE_HIGH (x))
5839 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
5840 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
5841 else if (CONST_DOUBLE_LOW (x) < 0)
5842 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
5843 else
5844 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
5846 else
5847 /* We can't handle floating point constants;
5848 PRINT_OPERAND must handle them. */
5849 output_operand_lossage ("floating constant misused");
5850 break;
5852 case PLUS:
5853 /* FIXME: Not needed here. */
5854 /* Some assemblers need integer constants to appear last (eg masm). */
5855 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
5857 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5858 fprintf (file, "+");
5859 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5861 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
5863 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5864 if (INTVAL (XEXP (x, 1)) >= 0)
5865 fprintf (file, "+");
5866 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5868 else
5869 gcc_unreachable();
5870 break;
5872 case MINUS:
5873 /* Avoid outputting things like x-x or x+5-x,
5874 since some assemblers can't handle that. */
5875 x = simplify_subtraction (x);
5876 if (GET_CODE (x) != MINUS)
5877 goto restart;
5879 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5880 fprintf (file, "-");
5881 if (GET_CODE (XEXP (x, 1)) == CONST_INT
5882 && INTVAL (XEXP (x, 1)) < 0)
5884 fprintf (file, "(");
5885 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5886 fprintf (file, ")");
5888 else
5889 arc_output_pic_addr_const (file, XEXP (x, 1), code);
5890 break;
5892 case ZERO_EXTEND:
5893 case SIGN_EXTEND:
5894 arc_output_pic_addr_const (file, XEXP (x, 0), code);
5895 break;
5898 case UNSPEC:
5899 const char *suffix;
5900 bool pcrel; pcrel = false;
5901 rtx base; base = NULL;
5902 gcc_assert (XVECLEN (x, 0) >= 1);
5903 switch (XINT (x, 1))
5905 case ARC_UNSPEC_GOT:
5906 suffix = "@gotpc", pcrel = true;
5907 break;
5908 case ARC_UNSPEC_GOTOFF:
5909 suffix = "@gotoff";
5910 break;
5911 case ARC_UNSPEC_GOTOFFPC:
5912 suffix = "@pcl", pcrel = true;
5913 break;
5914 case ARC_UNSPEC_PLT:
5915 suffix = "@plt";
5916 break;
5917 case UNSPEC_TLS_GD:
5918 suffix = "@tlsgd", pcrel = true;
5919 break;
5920 case UNSPEC_TLS_IE:
5921 suffix = "@tlsie", pcrel = true;
5922 break;
5923 case UNSPEC_TLS_OFF:
5924 if (XVECLEN (x, 0) == 2)
5925 base = XVECEXP (x, 0, 1);
5926 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
5927 || (!flag_pic && !base))
5928 suffix = "@tpoff";
5929 else
5930 suffix = "@dtpoff";
5931 break;
5932 default:
5933 suffix = "@invalid";
5934 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
5935 break;
5937 if (pcrel)
5938 fputs ("pcl,", file);
5939 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
5940 fputs (suffix, file);
5941 if (base)
5942 arc_output_pic_addr_const (file, base, code);
5943 break;
5945 default:
5946 output_operand_lossage ("invalid expression as operand");
5950 #define SYMBOLIC_CONST(X) \
5951 (GET_CODE (X) == SYMBOL_REF \
5952 || GET_CODE (X) == LABEL_REF \
5953 || (GET_CODE (X) == CONST && symbolic_reference_mentioned_p (X)))
5955 /* Emit insns to move operands[1] into operands[0]. */
5957 static void
5958 prepare_pic_move (rtx *operands, machine_mode)
5960 if (GET_CODE (operands[0]) == MEM && SYMBOLIC_CONST (operands[1])
5961 && flag_pic)
5962 operands[1] = force_reg (Pmode, operands[1]);
5963 else
5965 rtx temp = (reload_in_progress ? operands[0]
5966 : flag_pic? gen_reg_rtx (Pmode) : NULL_RTX);
5967 operands[1] = arc_legitimize_pic_address (operands[1], temp);
5972 /* The function returning the number of words, at the beginning of an
5973 argument, must be put in registers. The returned value must be
5974 zero for arguments that are passed entirely in registers or that
5975 are entirely pushed on the stack.
5977 On some machines, certain arguments must be passed partially in
5978 registers and partially in memory. On these machines, typically
5979 the first N words of arguments are passed in registers, and the
5980 rest on the stack. If a multi-word argument (a `double' or a
5981 structure) crosses that boundary, its first few words must be
5982 passed in registers and the rest must be pushed. This function
5983 tells the compiler when this occurs, and how many of the words
5984 should go in registers.
5986 `FUNCTION_ARG' for these arguments should return the first register
5987 to be used by the caller for this argument; likewise
5988 `FUNCTION_INCOMING_ARG', for the called function.
5990 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
5992 /* If REGNO is the least arg reg available then what is the total number of arg
5993 regs available. */
5994 #define GPR_REST_ARG_REGS(REGNO) \
5995 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
5997 /* Since arc parm regs are contiguous. */
5998 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6000 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6002 static int
6003 arc_arg_partial_bytes (cumulative_args_t cum_v, machine_mode mode,
6004 tree type, bool named ATTRIBUTE_UNUSED)
6006 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6007 int bytes = (mode == BLKmode
6008 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
6009 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6010 int arg_num = *cum;
6011 int ret;
6013 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
6014 ret = GPR_REST_ARG_REGS (arg_num);
6016 /* ICEd at function.c:2361, and ret is copied to data->partial */
6017 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
6019 return ret;
6022 /* This function is used to control a function argument is passed in a
6023 register, and which register.
6025 The arguments are CUM, of type CUMULATIVE_ARGS, which summarizes
6026 (in a way defined by INIT_CUMULATIVE_ARGS and FUNCTION_ARG_ADVANCE)
6027 all of the previous arguments so far passed in registers; MODE, the
6028 machine mode of the argument; TYPE, the data type of the argument
6029 as a tree node or 0 if that is not known (which happens for C
6030 support library functions); and NAMED, which is 1 for an ordinary
6031 argument and 0 for nameless arguments that correspond to `...' in
6032 the called function's prototype.
6034 The returned value should either be a `reg' RTX for the hard
6035 register in which to pass the argument, or zero to pass the
6036 argument on the stack.
6038 For machines like the Vax and 68000, where normally all arguments
6039 are pushed, zero suffices as a definition.
6041 The usual way to make the ANSI library `stdarg.h' work on a machine
6042 where some arguments are usually passed in registers, is to cause
6043 nameless arguments to be passed on the stack instead. This is done
6044 by making the function return 0 whenever NAMED is 0.
6046 You may use the macro `MUST_PASS_IN_STACK (MODE, TYPE)' in the
6047 definition of this function to determine if this argument is of a
6048 type that must be passed in the stack. If `REG_PARM_STACK_SPACE'
6049 is not defined and the function returns non-zero for such an
6050 argument, the compiler will abort. If `REG_PARM_STACK_SPACE' is
6051 defined, the argument will be computed in the stack and then loaded
6052 into a register.
6054 The function is used to implement macro FUNCTION_ARG. */
6055 /* On the ARC the first MAX_ARC_PARM_REGS args are normally in registers
6056 and the rest are pushed. */
6058 static rtx
6059 arc_function_arg (cumulative_args_t cum_v,
6060 machine_mode mode,
6061 const_tree type ATTRIBUTE_UNUSED,
6062 bool named ATTRIBUTE_UNUSED)
6064 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6065 int arg_num = *cum;
6066 rtx ret;
6067 const char *debstr ATTRIBUTE_UNUSED;
6069 arg_num = ROUND_ADVANCE_CUM (arg_num, mode, type);
6070 /* Return a marker for use in the call instruction. */
6071 if (mode == VOIDmode)
6073 ret = const0_rtx;
6074 debstr = "<0>";
6076 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6078 ret = gen_rtx_REG (mode, arg_num);
6079 debstr = reg_names [arg_num];
6081 else
6083 ret = NULL_RTX;
6084 debstr = "memory";
6086 return ret;
6089 /* The function to update the summarizer variable *CUM to advance past
6090 an argument in the argument list. The values MODE, TYPE and NAMED
6091 describe that argument. Once this is done, the variable *CUM is
6092 suitable for analyzing the *following* argument with
6093 `FUNCTION_ARG', etc.
6095 This function need not do anything if the argument in question was
6096 passed on the stack. The compiler knows how to track the amount of
6097 stack space used for arguments without any special help.
6099 The function is used to implement macro FUNCTION_ARG_ADVANCE. */
6100 /* For the ARC: the cum set here is passed on to function_arg where we
6101 look at its value and say which reg to use. Strategy: advance the
6102 regnumber here till we run out of arg regs, then set *cum to last
6103 reg. In function_arg, since *cum > last arg reg we would return 0
6104 and thus the arg will end up on the stack. For straddling args of
6105 course function_arg_partial_nregs will come into play. */
6107 static void
6108 arc_function_arg_advance (cumulative_args_t cum_v,
6109 machine_mode mode,
6110 const_tree type,
6111 bool named ATTRIBUTE_UNUSED)
6113 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6114 int bytes = (mode == BLKmode
6115 ? int_size_in_bytes (type) : (int) GET_MODE_SIZE (mode));
6116 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6117 int i;
6119 if (words)
6120 *cum = ROUND_ADVANCE_CUM (*cum, mode, type);
6121 for (i = 0; i < words; i++)
6122 *cum = ARC_NEXT_ARG_REG (*cum);
6126 /* Define how to find the value returned by a function.
6127 VALTYPE is the data type of the value (as a tree).
6128 If the precise function being called is known, FN_DECL_OR_TYPE is its
6129 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6131 static rtx
6132 arc_function_value (const_tree valtype,
6133 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6134 bool outgoing ATTRIBUTE_UNUSED)
6136 machine_mode mode = TYPE_MODE (valtype);
6137 int unsignedp ATTRIBUTE_UNUSED;
6139 unsignedp = TYPE_UNSIGNED (valtype);
6140 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6141 PROMOTE_MODE (mode, unsignedp, valtype);
6142 return gen_rtx_REG (mode, 0);
6145 /* Returns the return address that is used by builtin_return_address. */
6148 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6150 if (count != 0)
6151 return const0_rtx;
6153 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6156 /* Determine if a given RTX is a valid constant. We already know this
6157 satisfies CONSTANT_P. */
6159 bool
6160 arc_legitimate_constant_p (machine_mode mode, rtx x)
6162 switch (GET_CODE (x))
6164 case CONST:
6165 if (flag_pic)
6167 if (arc_legitimate_pic_addr_p (x))
6168 return true;
6170 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6172 case SYMBOL_REF:
6173 if (SYMBOL_REF_TLS_MODEL (x))
6174 return false;
6175 /* Fall through. */
6176 case LABEL_REF:
6177 if (flag_pic)
6178 return false;
6179 /* Fall through. */
6180 case CONST_INT:
6181 case CONST_DOUBLE:
6182 return true;
6184 case NEG:
6185 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6187 case PLUS:
6188 case MINUS:
6190 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6191 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6193 return (t1 && t2);
6196 case CONST_VECTOR:
6197 switch (mode)
6199 case E_V2HImode:
6200 return TARGET_PLUS_DMPY;
6201 case E_V2SImode:
6202 case E_V4HImode:
6203 return TARGET_PLUS_QMACW;
6204 default:
6205 return false;
6208 case UNSPEC:
6209 switch (XINT (x, 1))
6211 case UNSPEC_TLS_GD:
6212 case UNSPEC_TLS_OFF:
6213 case UNSPEC_TLS_IE:
6214 return true;
6215 default:
6216 /* Any other unspec ending here are pic related, hence the above
6217 constant pic address checking returned false. */
6218 return false;
6220 /* Fall through. */
6222 default:
6223 fatal_insn ("unrecognized supposed constant", x);
6226 gcc_unreachable ();
6229 static bool
6230 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict)
6232 if (RTX_OK_FOR_BASE_P (x, strict))
6233 return true;
6234 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
6235 return true;
6236 if (legitimate_scaled_address_p (mode, x, strict))
6237 return true;
6238 if (legitimate_small_data_address_p (x))
6239 return true;
6240 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6241 return true;
6243 /* When we compile for size avoid const (@sym + offset)
6244 addresses. */
6245 if (!flag_pic && optimize_size && !reload_completed
6246 && (GET_CODE (x) == CONST)
6247 && (GET_CODE (XEXP (x, 0)) == PLUS)
6248 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6249 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6250 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
6252 rtx addend = XEXP (XEXP (x, 0), 1);
6253 gcc_assert (CONST_INT_P (addend));
6254 HOST_WIDE_INT offset = INTVAL (addend);
6256 /* Allow addresses having a large offset to pass. Anyhow they
6257 will end in a limm. */
6258 return !(offset > -1024 && offset < 1020);
6261 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6263 return arc_legitimate_constant_p (mode, x);
6265 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6266 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6267 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6268 return true;
6269 /* We're restricted here by the `st' insn. */
6270 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6271 && GET_CODE (XEXP ((x), 1)) == PLUS
6272 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
6273 && legitimate_offset_address_p (QImode, XEXP (x, 1),
6274 TARGET_AUTO_MODIFY_REG, strict))
6275 return true;
6276 return false;
6279 /* Return true iff ADDR (a legitimate address expression)
6280 has an effect that depends on the machine mode it is used for. */
6282 static bool
6283 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6285 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6286 which is valid for loads and stores, or a limm offset, which is valid for
6287 loads. Scaled indices are scaled by the access mode. */
6288 if (GET_CODE (addr) == PLUS
6289 && GET_CODE (XEXP ((addr), 0)) == MULT)
6290 return true;
6291 return false;
6294 /* Determine if it's legal to put X into the constant pool. */
6296 static bool
6297 arc_cannot_force_const_mem (machine_mode mode, rtx x)
6299 return !arc_legitimate_constant_p (mode, x);
6302 /* IDs for all the ARC builtins. */
6304 enum arc_builtin_id
6306 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6307 ARC_BUILTIN_ ## NAME,
6308 #include "builtins.def"
6309 #undef DEF_BUILTIN
6311 ARC_BUILTIN_COUNT
6314 struct GTY(()) arc_builtin_description
6316 enum insn_code icode;
6317 int n_args;
6318 tree fndecl;
6321 static GTY(()) struct arc_builtin_description
6322 arc_bdesc[ARC_BUILTIN_COUNT] =
6324 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6325 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6326 #include "builtins.def"
6327 #undef DEF_BUILTIN
6330 /* Transform UP into lowercase and write the result to LO.
6331 You must provide enough space for LO. Return LO. */
6333 static char*
6334 arc_tolower (char *lo, const char *up)
6336 char *lo0 = lo;
6338 for (; *up; up++, lo++)
6339 *lo = TOLOWER (*up);
6341 *lo = '\0';
6343 return lo0;
6346 /* Implement `TARGET_BUILTIN_DECL'. */
6348 static tree
6349 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6351 if (id < ARC_BUILTIN_COUNT)
6352 return arc_bdesc[id].fndecl;
6354 return error_mark_node;
6357 static void
6358 arc_init_builtins (void)
6360 tree V4HI_type_node;
6361 tree V2SI_type_node;
6362 tree V2HI_type_node;
6364 /* Vector types based on HS SIMD elements. */
6365 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6366 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6367 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6369 tree pcvoid_type_node
6370 = build_pointer_type (build_qualified_type (void_type_node,
6371 TYPE_QUAL_CONST));
6372 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6373 V8HImode);
6375 tree void_ftype_void
6376 = build_function_type_list (void_type_node, NULL_TREE);
6377 tree int_ftype_int
6378 = build_function_type_list (integer_type_node, integer_type_node,
6379 NULL_TREE);
6380 tree int_ftype_pcvoid_int
6381 = build_function_type_list (integer_type_node, pcvoid_type_node,
6382 integer_type_node, NULL_TREE);
6383 tree void_ftype_usint_usint
6384 = build_function_type_list (void_type_node, long_unsigned_type_node,
6385 long_unsigned_type_node, NULL_TREE);
6386 tree int_ftype_int_int
6387 = build_function_type_list (integer_type_node, integer_type_node,
6388 integer_type_node, NULL_TREE);
6389 tree usint_ftype_usint
6390 = build_function_type_list (long_unsigned_type_node,
6391 long_unsigned_type_node, NULL_TREE);
6392 tree void_ftype_usint
6393 = build_function_type_list (void_type_node, long_unsigned_type_node,
6394 NULL_TREE);
6395 tree int_ftype_void
6396 = build_function_type_list (integer_type_node, void_type_node,
6397 NULL_TREE);
6398 tree void_ftype_int
6399 = build_function_type_list (void_type_node, integer_type_node,
6400 NULL_TREE);
6401 tree int_ftype_short
6402 = build_function_type_list (integer_type_node, short_integer_type_node,
6403 NULL_TREE);
6405 /* Old ARC SIMD types. */
6406 tree v8hi_ftype_v8hi_v8hi
6407 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6408 V8HI_type_node, NULL_TREE);
6409 tree v8hi_ftype_v8hi_int
6410 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6411 integer_type_node, NULL_TREE);
6412 tree v8hi_ftype_v8hi_int_int
6413 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6414 integer_type_node, integer_type_node,
6415 NULL_TREE);
6416 tree void_ftype_v8hi_int_int
6417 = build_function_type_list (void_type_node, V8HI_type_node,
6418 integer_type_node, integer_type_node,
6419 NULL_TREE);
6420 tree void_ftype_v8hi_int_int_int
6421 = build_function_type_list (void_type_node, V8HI_type_node,
6422 integer_type_node, integer_type_node,
6423 integer_type_node, NULL_TREE);
6424 tree v8hi_ftype_int_int
6425 = build_function_type_list (V8HI_type_node, integer_type_node,
6426 integer_type_node, NULL_TREE);
6427 tree void_ftype_int_int
6428 = build_function_type_list (void_type_node, integer_type_node,
6429 integer_type_node, NULL_TREE);
6430 tree v8hi_ftype_v8hi
6431 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6432 NULL_TREE);
6433 /* ARCv2 SIMD types. */
6434 tree long_ftype_v4hi_v4hi
6435 = build_function_type_list (long_long_integer_type_node,
6436 V4HI_type_node, V4HI_type_node, NULL_TREE);
6437 tree int_ftype_v2hi_v2hi
6438 = build_function_type_list (integer_type_node,
6439 V2HI_type_node, V2HI_type_node, NULL_TREE);
6440 tree v2si_ftype_v2hi_v2hi
6441 = build_function_type_list (V2SI_type_node,
6442 V2HI_type_node, V2HI_type_node, NULL_TREE);
6443 tree v2hi_ftype_v2hi_v2hi
6444 = build_function_type_list (V2HI_type_node,
6445 V2HI_type_node, V2HI_type_node, NULL_TREE);
6446 tree v2si_ftype_v2si_v2si
6447 = build_function_type_list (V2SI_type_node,
6448 V2SI_type_node, V2SI_type_node, NULL_TREE);
6449 tree v4hi_ftype_v4hi_v4hi
6450 = build_function_type_list (V4HI_type_node,
6451 V4HI_type_node, V4HI_type_node, NULL_TREE);
6452 tree long_ftype_v2si_v2hi
6453 = build_function_type_list (long_long_integer_type_node,
6454 V2SI_type_node, V2HI_type_node, NULL_TREE);
6456 /* Add the builtins. */
6457 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6459 int id = ARC_BUILTIN_ ## NAME; \
6460 const char *Name = "__builtin_arc_" #NAME; \
6461 char *name = (char*) alloca (1 + strlen (Name)); \
6463 gcc_assert (id < ARC_BUILTIN_COUNT); \
6464 if (MASK) \
6465 arc_bdesc[id].fndecl \
6466 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6467 BUILT_IN_MD, NULL, NULL_TREE); \
6469 #include "builtins.def"
6470 #undef DEF_BUILTIN
6473 /* Helper to expand __builtin_arc_aligned (void* val, int
6474 alignval). */
6476 static rtx
6477 arc_expand_builtin_aligned (tree exp)
6479 tree arg0 = CALL_EXPR_ARG (exp, 0);
6480 tree arg1 = CALL_EXPR_ARG (exp, 1);
6481 fold (arg1);
6482 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6483 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6485 if (!CONST_INT_P (op1))
6487 /* If we can't fold the alignment to a constant integer
6488 whilst optimizing, this is probably a user error. */
6489 if (optimize)
6490 warning (0, "__builtin_arc_aligned with non-constant alignment");
6492 else
6494 HOST_WIDE_INT alignTest = INTVAL (op1);
6495 /* Check alignTest is positive, and a power of two. */
6496 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6498 error ("invalid alignment value for __builtin_arc_aligned");
6499 return NULL_RTX;
6502 if (CONST_INT_P (op0))
6504 HOST_WIDE_INT pnt = INTVAL (op0);
6506 if ((pnt & (alignTest - 1)) == 0)
6507 return const1_rtx;
6509 else
6511 unsigned align = get_pointer_alignment (arg0);
6512 unsigned numBits = alignTest * BITS_PER_UNIT;
6514 if (align && align >= numBits)
6515 return const1_rtx;
6516 /* Another attempt to ascertain alignment. Check the type
6517 we are pointing to. */
6518 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6519 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6520 return const1_rtx;
6524 /* Default to false. */
6525 return const0_rtx;
6528 /* Helper arc_expand_builtin, generates a pattern for the given icode
6529 and arguments. */
6531 static rtx_insn *
6532 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6534 switch (insn_data[icode].n_generator_args)
6536 case 0:
6537 return GEN_FCN (icode) ();
6538 case 1:
6539 return GEN_FCN (icode) (arg[0]);
6540 case 2:
6541 return GEN_FCN (icode) (arg[0], arg[1]);
6542 case 3:
6543 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6544 case 4:
6545 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6546 case 5:
6547 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6548 default:
6549 gcc_unreachable ();
6553 /* Expand an expression EXP that calls a built-in function,
6554 with result going to TARGET if that's convenient
6555 (and in mode MODE if that's convenient).
6556 SUBTARGET may be used as the target for computing one of EXP's operands.
6557 IGNORE is nonzero if the value is to be ignored. */
6559 static rtx
6560 arc_expand_builtin (tree exp,
6561 rtx target,
6562 rtx subtarget ATTRIBUTE_UNUSED,
6563 machine_mode mode ATTRIBUTE_UNUSED,
6564 int ignore ATTRIBUTE_UNUSED)
6566 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6567 unsigned int id = DECL_FUNCTION_CODE (fndecl);
6568 const struct arc_builtin_description *d = &arc_bdesc[id];
6569 int i, j, n_args = call_expr_nargs (exp);
6570 rtx pat = NULL_RTX;
6571 rtx xop[5];
6572 enum insn_code icode = d->icode;
6573 machine_mode tmode = insn_data[icode].operand[0].mode;
6574 int nonvoid;
6575 tree arg0;
6576 tree arg1;
6577 tree arg2;
6578 tree arg3;
6579 rtx op0;
6580 rtx op1;
6581 rtx op2;
6582 rtx op3;
6583 rtx op4;
6584 machine_mode mode0;
6585 machine_mode mode1;
6586 machine_mode mode2;
6587 machine_mode mode3;
6588 machine_mode mode4;
6590 if (id >= ARC_BUILTIN_COUNT)
6591 internal_error ("bad builtin fcode");
6593 /* 1st part: Expand special builtins. */
6594 switch (id)
6596 case ARC_BUILTIN_NOP:
6597 emit_insn (gen_nopv ());
6598 return NULL_RTX;
6600 case ARC_BUILTIN_RTIE:
6601 case ARC_BUILTIN_SYNC:
6602 case ARC_BUILTIN_BRK:
6603 case ARC_BUILTIN_SWI:
6604 case ARC_BUILTIN_UNIMP_S:
6605 gcc_assert (icode != 0);
6606 emit_insn (GEN_FCN (icode) (const1_rtx));
6607 return NULL_RTX;
6609 case ARC_BUILTIN_ALIGNED:
6610 return arc_expand_builtin_aligned (exp);
6612 case ARC_BUILTIN_CLRI:
6613 target = gen_reg_rtx (SImode);
6614 emit_insn (gen_clri (target, const1_rtx));
6615 return target;
6617 case ARC_BUILTIN_TRAP_S:
6618 case ARC_BUILTIN_SLEEP:
6619 arg0 = CALL_EXPR_ARG (exp, 0);
6620 fold (arg0);
6621 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6623 gcc_assert (icode != 0);
6624 emit_insn (GEN_FCN (icode) (op0));
6625 return NULL_RTX;
6627 case ARC_BUILTIN_VDORUN:
6628 case ARC_BUILTIN_VDIRUN:
6629 arg0 = CALL_EXPR_ARG (exp, 0);
6630 arg1 = CALL_EXPR_ARG (exp, 1);
6631 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6632 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6634 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
6636 mode0 = insn_data[icode].operand[1].mode;
6637 mode1 = insn_data[icode].operand[2].mode;
6639 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6640 op0 = copy_to_mode_reg (mode0, op0);
6642 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6643 op1 = copy_to_mode_reg (mode1, op1);
6645 pat = GEN_FCN (icode) (target, op0, op1);
6646 if (!pat)
6647 return NULL_RTX;
6649 emit_insn (pat);
6650 return NULL_RTX;
6652 case ARC_BUILTIN_VDIWR:
6653 case ARC_BUILTIN_VDOWR:
6654 arg0 = CALL_EXPR_ARG (exp, 0);
6655 arg1 = CALL_EXPR_ARG (exp, 1);
6656 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6657 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6659 if (!CONST_INT_P (op0)
6660 || !(UNSIGNED_INT3 (INTVAL (op0))))
6661 error ("operand 1 should be an unsigned 3-bit immediate");
6663 mode1 = insn_data[icode].operand[1].mode;
6665 if (icode == CODE_FOR_vdiwr_insn)
6666 target = gen_rtx_REG (SImode,
6667 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
6668 else if (icode == CODE_FOR_vdowr_insn)
6669 target = gen_rtx_REG (SImode,
6670 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
6671 else
6672 gcc_unreachable ();
6674 if (!insn_data[icode].operand[2].predicate (op1, mode1))
6675 op1 = copy_to_mode_reg (mode1, op1);
6677 pat = GEN_FCN (icode) (target, op1);
6678 if (!pat)
6679 return NULL_RTX;
6681 emit_insn (pat);
6682 return NULL_RTX;
6684 case ARC_BUILTIN_VASRW:
6685 case ARC_BUILTIN_VSR8:
6686 case ARC_BUILTIN_VSR8AW:
6687 arg0 = CALL_EXPR_ARG (exp, 0);
6688 arg1 = CALL_EXPR_ARG (exp, 1);
6689 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6690 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6691 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6693 target = gen_reg_rtx (V8HImode);
6694 mode0 = insn_data[icode].operand[1].mode;
6695 mode1 = insn_data[icode].operand[2].mode;
6697 if (!insn_data[icode].operand[1].predicate (op0, mode0))
6698 op0 = copy_to_mode_reg (mode0, op0);
6700 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6701 || !(UNSIGNED_INT3 (INTVAL (op1))))
6702 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6704 pat = GEN_FCN (icode) (target, op0, op1, op2);
6705 if (!pat)
6706 return NULL_RTX;
6708 emit_insn (pat);
6709 return target;
6711 case ARC_BUILTIN_VLD32WH:
6712 case ARC_BUILTIN_VLD32WL:
6713 case ARC_BUILTIN_VLD64:
6714 case ARC_BUILTIN_VLD32:
6715 rtx src_vreg;
6716 icode = d->icode;
6717 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6718 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6719 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6721 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6722 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6723 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6724 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6726 /* target <- src vreg. */
6727 emit_insn (gen_move_insn (target, src_vreg));
6729 /* target <- vec_concat: target, mem (Ib, u8). */
6730 mode0 = insn_data[icode].operand[3].mode;
6731 mode1 = insn_data[icode].operand[1].mode;
6733 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
6734 || !(UNSIGNED_INT3 (INTVAL (op0))))
6735 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6737 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6738 || !(UNSIGNED_INT8 (INTVAL (op1))))
6739 error ("operand 2 should be an unsigned 8-bit value");
6741 pat = GEN_FCN (icode) (target, op1, op2, op0);
6742 if (!pat)
6743 return NULL_RTX;
6745 emit_insn (pat);
6746 return target;
6748 case ARC_BUILTIN_VLD64W:
6749 case ARC_BUILTIN_VLD128:
6750 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
6751 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6753 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6754 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
6755 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6757 /* target <- src vreg. */
6758 target = gen_reg_rtx (V8HImode);
6760 /* target <- vec_concat: target, mem (Ib, u8). */
6761 mode0 = insn_data[icode].operand[1].mode;
6762 mode1 = insn_data[icode].operand[2].mode;
6763 mode2 = insn_data[icode].operand[3].mode;
6765 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
6766 || !(UNSIGNED_INT3 (INTVAL (op1))))
6767 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
6769 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
6770 || !(UNSIGNED_INT8 (INTVAL (op2))))
6771 error ("operand 2 should be an unsigned 8-bit value");
6773 pat = GEN_FCN (icode) (target, op0, op1, op2);
6775 if (!pat)
6776 return NULL_RTX;
6778 emit_insn (pat);
6779 return target;
6781 case ARC_BUILTIN_VST128:
6782 case ARC_BUILTIN_VST64:
6783 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
6784 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
6785 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
6787 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6788 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6789 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6790 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6792 mode0 = insn_data[icode].operand[0].mode;
6793 mode1 = insn_data[icode].operand[1].mode;
6794 mode2 = insn_data[icode].operand[2].mode;
6795 mode3 = insn_data[icode].operand[3].mode;
6797 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
6798 || !(UNSIGNED_INT3 (INTVAL (op1))))
6799 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
6801 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6802 || !(UNSIGNED_INT8 (INTVAL (op2))))
6803 error ("operand 3 should be an unsigned 8-bit value");
6805 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6806 op3 = copy_to_mode_reg (mode3, op3);
6808 pat = GEN_FCN (icode) (op0, op1, op2, op3);
6809 if (!pat)
6810 return NULL_RTX;
6812 emit_insn (pat);
6813 return NULL_RTX;
6815 case ARC_BUILTIN_VST16_N:
6816 case ARC_BUILTIN_VST32_N:
6817 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
6818 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
6819 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
6820 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
6822 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
6823 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
6824 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
6825 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
6826 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
6828 mode0 = insn_data[icode].operand[0].mode;
6829 mode2 = insn_data[icode].operand[2].mode;
6830 mode3 = insn_data[icode].operand[3].mode;
6831 mode4 = insn_data[icode].operand[4].mode;
6833 /* Do some correctness checks for the operands. */
6834 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
6835 || !(UNSIGNED_INT8 (INTVAL (op0))))
6836 error ("operand 4 should be an unsigned 8-bit value (0-255)");
6838 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
6839 || !(UNSIGNED_INT3 (INTVAL (op2))))
6840 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
6842 if (!insn_data[icode].operand[3].predicate (op3, mode3))
6843 op3 = copy_to_mode_reg (mode3, op3);
6845 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
6846 || !(UNSIGNED_INT3 (INTVAL (op4))))
6847 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
6848 else if (icode == CODE_FOR_vst32_n_insn
6849 && ((INTVAL (op4) % 2) != 0))
6850 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
6852 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
6853 if (!pat)
6854 return NULL_RTX;
6856 emit_insn (pat);
6857 return NULL_RTX;
6859 default:
6860 break;
6863 /* 2nd part: Expand regular builtins. */
6864 if (icode == 0)
6865 internal_error ("bad builtin fcode");
6867 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
6868 j = 0;
6870 if (nonvoid)
6872 if (target == NULL_RTX
6873 || GET_MODE (target) != tmode
6874 || !insn_data[icode].operand[0].predicate (target, tmode))
6876 target = gen_reg_rtx (tmode);
6878 xop[j++] = target;
6881 gcc_assert (n_args <= 4);
6882 for (i = 0; i < n_args; i++, j++)
6884 tree arg = CALL_EXPR_ARG (exp, i);
6885 machine_mode mode = insn_data[icode].operand[j].mode;
6886 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
6887 machine_mode opmode = GET_MODE (op);
6888 char c = insn_data[icode].operand[j].constraint[0];
6890 /* SIMD extension requires exact immediate operand match. */
6891 if ((id > ARC_BUILTIN_SIMD_BEGIN)
6892 && (id < ARC_BUILTIN_SIMD_END)
6893 && (c != 'v')
6894 && (c != 'r'))
6896 if (!CONST_INT_P (op))
6897 error ("builtin requires an immediate for operand %d", j);
6898 switch (c)
6900 case 'L':
6901 if (!satisfies_constraint_L (op))
6902 error ("operand %d should be a 6 bit unsigned immediate", j);
6903 break;
6904 case 'P':
6905 if (!satisfies_constraint_P (op))
6906 error ("operand %d should be a 8 bit unsigned immediate", j);
6907 break;
6908 case 'K':
6909 if (!satisfies_constraint_K (op))
6910 error ("operand %d should be a 3 bit unsigned immediate", j);
6911 break;
6912 default:
6913 error ("unknown builtin immediate operand type for operand %d",
6918 if (CONST_INT_P (op))
6919 opmode = mode;
6921 if ((opmode == SImode) && (mode == HImode))
6923 opmode = HImode;
6924 op = gen_lowpart (HImode, op);
6927 /* In case the insn wants input operands in modes different from
6928 the result, abort. */
6929 gcc_assert (opmode == mode || opmode == VOIDmode);
6931 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
6932 op = copy_to_mode_reg (mode, op);
6934 xop[j] = op;
6937 pat = apply_GEN_FCN (icode, xop);
6938 if (pat == NULL_RTX)
6939 return NULL_RTX;
6941 emit_insn (pat);
6943 if (nonvoid)
6944 return target;
6945 else
6946 return const0_rtx;
6949 /* Returns true if the operands[opno] is a valid compile-time constant to be
6950 used as register number in the code for builtins. Else it flags an error
6951 and returns false. */
6953 bool
6954 check_if_valid_regno_const (rtx *operands, int opno)
6957 switch (GET_CODE (operands[opno]))
6959 case SYMBOL_REF :
6960 case CONST :
6961 case CONST_INT :
6962 return true;
6963 default:
6964 error ("register number must be a compile-time constant. Try giving higher optimization levels");
6965 break;
6967 return false;
6970 /* Return true if it is ok to make a tail-call to DECL. */
6972 static bool
6973 arc_function_ok_for_sibcall (tree decl,
6974 tree exp ATTRIBUTE_UNUSED)
6976 tree attrs = NULL_TREE;
6978 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
6979 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
6980 return false;
6982 if (decl)
6984 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
6986 if (lookup_attribute ("jli_always", attrs))
6987 return false;
6988 if (lookup_attribute ("jli_fixed", attrs))
6989 return false;
6990 if (lookup_attribute ("secure_call", attrs))
6991 return false;
6994 /* Everything else is ok. */
6995 return true;
6998 /* Output code to add DELTA to the first argument, and then jump
6999 to FUNCTION. Used for C++ multiple inheritance. */
7001 static void
7002 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7003 HOST_WIDE_INT delta,
7004 HOST_WIDE_INT vcall_offset,
7005 tree function)
7007 int mi_delta = delta;
7008 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
7009 int shift = 0;
7010 int this_regno
7011 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
7012 rtx fnaddr;
7014 if (mi_delta < 0)
7015 mi_delta = - mi_delta;
7017 /* Add DELTA. When possible use a plain add, otherwise load it into
7018 a register first. */
7020 while (mi_delta != 0)
7022 if ((mi_delta & (3 << shift)) == 0)
7023 shift += 2;
7024 else
7026 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
7027 mi_op, reg_names[this_regno], reg_names[this_regno],
7028 mi_delta & (0xff << shift));
7029 mi_delta &= ~(0xff << shift);
7030 shift += 8;
7034 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7035 if (vcall_offset != 0)
7037 /* ld r12,[this] --> temp = *this
7038 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7039 ld r12,[r12]
7040 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7041 asm_fprintf (file, "\tld\t%s, [%s]\n",
7042 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
7043 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
7044 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7045 asm_fprintf (file, "\tld\t%s, [%s]\n",
7046 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7047 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7048 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7051 fnaddr = XEXP (DECL_RTL (function), 0);
7053 if (arc_is_longcall_p (fnaddr))
7055 if (flag_pic)
7057 asm_fprintf (file, "\tld\t%s, [pcl, @",
7058 ARC_TEMP_SCRATCH_REG);
7059 assemble_name (file, XSTR (fnaddr, 0));
7060 fputs ("@gotpc]\n", file);
7061 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7063 else
7065 fputs ("\tj\t@", file);
7066 assemble_name (file, XSTR (fnaddr, 0));
7069 else
7071 fputs ("\tb\t@", file);
7072 assemble_name (file, XSTR (fnaddr, 0));
7073 if (flag_pic)
7074 fputs ("@plt\n", file);
7076 fputc ('\n', file);
7079 /* Return true if a 32 bit "long_call" should be generated for
7080 this calling SYM_REF. We generate a long_call if the function:
7082 a. has an __attribute__((long call))
7083 or b. the -mlong-calls command line switch has been specified
7085 However we do not generate a long call if the function has an
7086 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7088 This function will be called by C fragments contained in the machine
7089 description file. */
7091 bool
7092 arc_is_longcall_p (rtx sym_ref)
7094 if (GET_CODE (sym_ref) != SYMBOL_REF)
7095 return false;
7097 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7098 || (TARGET_LONG_CALLS_SET
7099 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7100 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7104 /* Likewise for short calls. */
7106 bool
7107 arc_is_shortcall_p (rtx sym_ref)
7109 if (GET_CODE (sym_ref) != SYMBOL_REF)
7110 return false;
7112 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7113 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7114 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7115 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7119 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7121 static bool
7122 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7124 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7125 return true;
7126 else
7128 HOST_WIDE_INT size = int_size_in_bytes (type);
7129 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
7133 static bool
7134 arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED,
7135 machine_mode mode ATTRIBUTE_UNUSED,
7136 const_tree type,
7137 bool named ATTRIBUTE_UNUSED)
7139 return (type != 0
7140 && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST
7141 || TREE_ADDRESSABLE (type)));
7144 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7146 static bool
7147 arc_can_use_doloop_p (const widest_int &,
7148 const widest_int &iterations_max,
7149 unsigned int loop_depth, bool entered_at_top)
7151 /* Considering limitations in the hardware, only use doloop
7152 for innermost loops which must be entered from the top. */
7153 if (loop_depth > 1 || !entered_at_top)
7154 return false;
7156 /* Check for lp_count width boundary. */
7157 if (arc_lpcwidth != 32
7158 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7159 || wi::eq_p (iterations_max, 0)))
7160 return false;
7161 return true;
7164 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7165 return why doloop cannot be applied. */
7167 static const char *
7168 arc_invalid_within_doloop (const rtx_insn *insn)
7170 if (CALL_P (insn))
7171 return "Function call in the loop.";
7173 /* FIXME! add here all the ZOL exceptions. */
7174 return NULL;
7177 /* Return true if a load instruction (CONSUMER) uses the same address as a
7178 store instruction (PRODUCER). This function is used to avoid st/ld
7179 address hazard in ARC700 cores. */
7180 bool
7181 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7183 rtx in_set, out_set;
7184 rtx out_addr, in_addr;
7186 if (!producer)
7187 return false;
7189 if (!consumer)
7190 return false;
7192 /* Peel the producer and the consumer for the address. */
7193 out_set = single_set (producer);
7194 if (out_set)
7196 out_addr = SET_DEST (out_set);
7197 if (!out_addr)
7198 return false;
7199 if (GET_CODE (out_addr) == ZERO_EXTEND
7200 || GET_CODE (out_addr) == SIGN_EXTEND)
7201 out_addr = XEXP (out_addr, 0);
7203 if (!MEM_P (out_addr))
7204 return false;
7206 in_set = single_set (consumer);
7207 if (in_set)
7209 in_addr = SET_SRC (in_set);
7210 if (!in_addr)
7211 return false;
7212 if (GET_CODE (in_addr) == ZERO_EXTEND
7213 || GET_CODE (in_addr) == SIGN_EXTEND)
7214 in_addr = XEXP (in_addr, 0);
7216 if (!MEM_P (in_addr))
7217 return false;
7218 /* Get rid of the MEM and check if the addresses are
7219 equivalent. */
7220 in_addr = XEXP (in_addr, 0);
7221 out_addr = XEXP (out_addr, 0);
7223 return exp_equiv_p (in_addr, out_addr, 0, true);
7226 return false;
7229 /* The same functionality as arc_hazard. It is called in machine
7230 reorg before any other optimization. Hence, the NOP size is taken
7231 into account when doing branch shortening. */
7233 static void
7234 workaround_arc_anomaly (void)
7236 rtx_insn *insn, *succ0;
7238 /* For any architecture: call arc_hazard here. */
7239 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7241 succ0 = next_real_insn (insn);
7242 if (arc_hazard (insn, succ0))
7244 emit_insn_before (gen_nopv (), succ0);
7248 if (TARGET_ARC700)
7250 rtx_insn *succ1;
7252 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7254 succ0 = next_real_insn (insn);
7255 if (arc_store_addr_hazard_p (insn, succ0))
7257 emit_insn_after (gen_nopv (), insn);
7258 emit_insn_after (gen_nopv (), insn);
7259 continue;
7262 /* Avoid adding nops if the instruction between the ST and LD is
7263 a call or jump. */
7264 succ1 = next_real_insn (succ0);
7265 if (succ0 && !JUMP_P (succ0) && !CALL_P (succ0)
7266 && arc_store_addr_hazard_p (insn, succ1))
7267 emit_insn_after (gen_nopv (), insn);
7272 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7273 turns out not to be optimizable; we have to split the loop_end pattern into
7274 a subtract and a test. */
7276 static void
7277 hwloop_fail (hwloop_info loop)
7279 rtx test;
7280 rtx insn = loop->loop_end;
7282 if (TARGET_DBNZ
7283 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7284 && REG_P (loop->iter_reg))
7286 /* TARGET_V2 core3 has dbnz instructions. */
7287 test = gen_dbnz (loop->iter_reg, loop->start_label);
7288 insn = emit_jump_insn_before (test, loop->loop_end);
7290 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7292 /* We have the lp_count as loop iterator, try to use it. */
7293 emit_insn_before (gen_loop_fail (), loop->loop_end);
7294 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7295 const0_rtx);
7296 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7297 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7298 pc_rtx);
7299 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7300 loop->loop_end);
7302 else
7304 emit_insn_before (gen_addsi3 (loop->iter_reg,
7305 loop->iter_reg,
7306 constm1_rtx),
7307 loop->loop_end);
7308 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7309 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7310 loop->iter_reg,
7311 const0_rtx,
7312 loop->start_label),
7313 loop->loop_end);
7315 JUMP_LABEL (insn) = loop->start_label;
7316 LABEL_NUSES (loop->start_label)++;
7317 delete_insn (loop->loop_end);
7320 /* Optimize LOOP. */
7322 static bool
7323 hwloop_optimize (hwloop_info loop)
7325 int i;
7326 edge entry_edge;
7327 basic_block entry_bb, bb;
7328 rtx iter_reg;
7329 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label;
7330 unsigned int length;
7331 bool need_fix = false;
7332 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7334 if (loop->depth > 1)
7336 if (dump_file)
7337 fprintf (dump_file, ";; loop %d is not innermost\n",
7338 loop->loop_no);
7339 return false;
7342 if (!loop->incoming_dest)
7344 if (dump_file)
7345 fprintf (dump_file, ";; loop %d has more than one entry\n",
7346 loop->loop_no);
7347 return false;
7350 if (loop->incoming_dest != loop->head)
7352 if (dump_file)
7353 fprintf (dump_file, ";; loop %d is not entered from head\n",
7354 loop->loop_no);
7355 return false;
7358 if (loop->has_call || loop->has_asm)
7360 if (dump_file)
7361 fprintf (dump_file, ";; loop %d has invalid insn\n",
7362 loop->loop_no);
7363 return false;
7366 /* Scan all the blocks to make sure they don't use iter_reg. */
7367 if (loop->iter_reg_used || loop->iter_reg_used_outside)
7369 if (dump_file)
7370 fprintf (dump_file, ";; loop %d uses iterator\n",
7371 loop->loop_no);
7372 return false;
7375 /* Check if start_label appears before doloop_end. */
7376 length = 0;
7377 for (insn = loop->start_label;
7378 insn && insn != loop->loop_end;
7379 insn = NEXT_INSN (insn))
7380 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
7382 if (!insn)
7384 if (dump_file)
7385 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
7386 loop->loop_no);
7387 return false;
7390 loop->length = length;
7391 if (loop->length > ARC_MAX_LOOP_LENGTH)
7393 if (dump_file)
7394 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7395 return false;
7397 else if (!loop->length)
7399 if (dump_file)
7400 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
7401 return false;
7404 /* Check if we use a register or not. */
7405 if (!REG_P (loop->iter_reg))
7407 if (dump_file)
7408 fprintf (dump_file, ";; loop %d iterator is MEM\n",
7409 loop->loop_no);
7410 return false;
7413 /* Check if loop register is lpcount. */
7414 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
7416 if (dump_file)
7417 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
7418 " iterator\n",
7419 loop->loop_no);
7420 /* This loop doesn't use the lp_count, check though if we can
7421 fix it. */
7422 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
7423 /* In very unique cases we may have LP_COUNT alive. */
7424 || (loop->incoming_src
7425 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
7426 LP_COUNT)))
7427 return false;
7428 else
7429 need_fix = true;
7432 /* Check for control like instruction as the last instruction of a
7433 ZOL. */
7434 bb = loop->tail;
7435 last_insn = PREV_INSN (loop->loop_end);
7437 while (1)
7439 for (; last_insn != BB_HEAD (bb);
7440 last_insn = PREV_INSN (last_insn))
7441 if (NONDEBUG_INSN_P (last_insn))
7442 break;
7444 if (last_insn != BB_HEAD (bb))
7445 break;
7447 if (single_pred_p (bb)
7448 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
7449 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
7451 bb = single_pred (bb);
7452 last_insn = BB_END (bb);
7453 continue;
7455 else
7457 last_insn = NULL;
7458 break;
7462 if (!last_insn)
7464 if (dump_file)
7465 fprintf (dump_file, ";; loop %d has no last instruction\n",
7466 loop->loop_no);
7467 return false;
7470 if ((TARGET_ARC600_FAMILY || TARGET_HS)
7471 && INSN_P (last_insn)
7472 && (JUMP_P (last_insn) || CALL_P (last_insn)
7473 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
7474 /* At this stage we can have (insn (clobber (mem:BLK
7475 (reg)))) instructions, ignore them. */
7476 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
7477 && (get_attr_type (last_insn) == TYPE_BRCC
7478 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
7480 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
7482 if (dump_file)
7483 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
7484 return false;
7486 if (dump_file)
7487 fprintf (dump_file, ";; loop %d has a control like last insn;"
7488 "add a nop\n",
7489 loop->loop_no);
7491 last_insn = emit_insn_after (gen_nopv (), last_insn);
7494 if (LABEL_P (last_insn))
7496 if (dump_file)
7497 fprintf (dump_file, ";; loop %d has a label as last insn;"
7498 "add a nop\n",
7499 loop->loop_no);
7500 last_insn = emit_insn_after (gen_nopv (), last_insn);
7503 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
7504 and we can use it to indicate the last ZOL instruction cannot be
7505 part of a delay slot. */
7506 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
7508 loop->last_insn = last_insn;
7510 /* Get the loop iteration register. */
7511 iter_reg = loop->iter_reg;
7513 gcc_assert (REG_P (iter_reg));
7515 entry_edge = NULL;
7517 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
7518 if (entry_edge->flags & EDGE_FALLTHRU)
7519 break;
7521 if (entry_edge == NULL)
7523 if (dump_file)
7524 fprintf (dump_file, ";; loop %d has no fallthru edge jumping"
7525 "into the loop\n",
7526 loop->loop_no);
7527 return false;
7529 /* The loop is good. */
7530 end_label = gen_label_rtx ();
7531 loop->end_label = end_label;
7533 /* Place the zero_cost_loop_start instruction before the loop. */
7534 entry_bb = entry_edge->src;
7536 start_sequence ();
7538 if (need_fix)
7540 /* The loop uses a R-register, but the lp_count is free, thus
7541 use lp_count. */
7542 emit_insn (gen_movsi (lp_reg, iter_reg));
7543 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
7544 iter_reg = lp_reg;
7545 if (dump_file)
7547 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
7548 loop->loop_no);
7552 insn = emit_insn (gen_arc_lp (iter_reg,
7553 loop->start_label,
7554 loop->end_label));
7556 seq = get_insns ();
7557 end_sequence ();
7559 entry_after = BB_END (entry_bb);
7560 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
7561 || !entry_after)
7563 basic_block new_bb;
7564 edge e;
7565 edge_iterator ei;
7567 emit_insn_before (seq, BB_HEAD (loop->head));
7568 seq = emit_label_before (gen_label_rtx (), seq);
7569 new_bb = create_basic_block (seq, insn, entry_bb);
7570 FOR_EACH_EDGE (e, ei, loop->incoming)
7572 if (!(e->flags & EDGE_FALLTHRU))
7573 redirect_edge_and_branch_force (e, new_bb);
7574 else
7575 redirect_edge_succ (e, new_bb);
7578 make_edge (new_bb, loop->head, 0);
7580 else
7582 #if 0
7583 while (DEBUG_INSN_P (entry_after)
7584 || (NOTE_P (entry_after)
7585 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK))
7586 entry_after = NEXT_INSN (entry_after);
7587 #endif
7588 entry_after = next_nonnote_nondebug_insn_bb (entry_after);
7590 gcc_assert (entry_after);
7591 emit_insn_before (seq, entry_after);
7594 delete_insn (loop->loop_end);
7595 /* Insert the loop end label before the last instruction of the
7596 loop. */
7597 emit_label_after (end_label, loop->last_insn);
7598 /* Make sure we mark the begining and end label as used. */
7599 LABEL_NUSES (loop->end_label)++;
7600 LABEL_NUSES (loop->start_label)++;
7602 return true;
7605 /* A callback for the hw-doloop pass. This function examines INSN; if
7606 it is a loop_end pattern we recognize, return the reg rtx for the
7607 loop counter. Otherwise, return NULL_RTX. */
7609 static rtx
7610 hwloop_pattern_reg (rtx_insn *insn)
7612 rtx reg;
7614 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
7615 return NULL_RTX;
7617 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
7618 if (!REG_P (reg))
7619 return NULL_RTX;
7620 return reg;
7623 static struct hw_doloop_hooks arc_doloop_hooks =
7625 hwloop_pattern_reg,
7626 hwloop_optimize,
7627 hwloop_fail
7630 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
7631 and tries to rewrite the RTL of these loops so that proper Blackfin
7632 hardware loops are generated. */
7634 static void
7635 arc_reorg_loops (void)
7637 reorg_loops (true, &arc_doloop_hooks);
7640 /* Scan all calls and add symbols to be emitted in the jli section if
7641 needed. */
7643 static void
7644 jli_call_scan (void)
7646 rtx_insn *insn;
7648 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7650 if (!CALL_P (insn))
7651 continue;
7653 rtx pat = PATTERN (insn);
7654 if (GET_CODE (pat) == COND_EXEC)
7655 pat = COND_EXEC_CODE (pat);
7656 pat = XVECEXP (pat, 0, 0);
7657 if (GET_CODE (pat) == SET)
7658 pat = SET_SRC (pat);
7660 pat = XEXP (XEXP (pat, 0), 0);
7661 if (GET_CODE (pat) == SYMBOL_REF
7662 && arc_is_jli_call_p (pat))
7663 arc_add_jli_section (pat);
7667 /* Add padding if necessary to avoid a mispredict. A return could
7668 happen immediately after the function start. A call/return and
7669 return/return must be 6 bytes apart to avoid mispredict. */
7671 static void
7672 pad_return (void)
7674 rtx_insn *insn;
7675 long offset;
7677 if (!TARGET_PAD_RETURN)
7678 return;
7680 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7682 rtx_insn *prev0 = prev_active_insn (insn);
7683 bool wantlong = false;
7685 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN)
7686 continue;
7688 if (!prev0)
7690 prev0 = emit_insn_before (gen_nopv (), insn);
7691 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
7692 so it is safe to reuse it for forcing a particular length
7693 for an instruction. */
7694 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
7695 emit_insn_before (gen_nopv (), insn);
7696 continue;
7698 offset = get_attr_length (prev0);
7700 if (get_attr_length (prev0) == 2
7701 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE)
7703 /* Force long version of the insn. */
7704 wantlong = true;
7705 offset += 2;
7708 rtx_insn *prev = prev_active_insn (prev0);
7709 if (prev)
7710 offset += get_attr_length (prev);
7712 prev = prev_active_insn (prev);
7713 if (prev)
7714 offset += get_attr_length (prev);
7716 switch (offset)
7718 case 2:
7719 prev = emit_insn_before (gen_nopv (), insn);
7720 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1));
7721 break;
7722 case 4:
7723 emit_insn_before (gen_nopv (), insn);
7724 break;
7725 default:
7726 continue;
7729 if (wantlong)
7730 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
7732 /* Emit a blockage to avoid delay slot scheduling. */
7733 emit_insn_before (gen_blockage (), insn);
7737 static int arc_reorg_in_progress = 0;
7739 /* ARC's machince specific reorg function. */
7741 static void
7742 arc_reorg (void)
7744 rtx_insn *insn;
7745 rtx pattern;
7746 rtx pc_target;
7747 long offset;
7748 int changed;
7750 cfun->machine->arc_reorg_started = 1;
7751 arc_reorg_in_progress = 1;
7753 compute_bb_for_insn ();
7755 df_analyze ();
7757 /* Doloop optimization. */
7758 arc_reorg_loops ();
7760 workaround_arc_anomaly ();
7761 jli_call_scan ();
7762 pad_return ();
7764 /* FIXME: should anticipate ccfsm action, generate special patterns for
7765 to-be-deleted branches that have no delay slot and have at least the
7766 length of the size increase forced on other insns that are conditionalized.
7767 This can also have an insn_list inside that enumerates insns which are
7768 not actually conditionalized because the destinations are dead in the
7769 not-execute case.
7770 Could also tag branches that we want to be unaligned if they get no delay
7771 slot, or even ones that we don't want to do delay slot sheduling for
7772 because we can unalign them.
7774 However, there are cases when conditional execution is only possible after
7775 delay slot scheduling:
7777 - If a delay slot is filled with a nocond/set insn from above, the previous
7778 basic block can become elegible for conditional execution.
7779 - If a delay slot is filled with a nocond insn from the fall-through path,
7780 the branch with that delay slot can become eligble for conditional
7781 execution (however, with the same sort of data flow analysis that dbr
7782 does, we could have figured out before that we don't need to
7783 conditionalize this insn.)
7784 - If a delay slot insn is filled with an insn from the target, the
7785 target label gets its uses decremented (even deleted if falling to zero),
7786 thus possibly creating more condexec opportunities there.
7787 Therefore, we should still be prepared to apply condexec optimization on
7788 non-prepared branches if the size increase of conditionalized insns is no
7789 more than the size saved from eliminating the branch. An invocation option
7790 could also be used to reserve a bit of extra size for condbranches so that
7791 this'll work more often (could also test in arc_reorg if the block is
7792 'close enough' to be eligible for condexec to make this likely, and
7793 estimate required size increase). */
7794 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
7795 if (TARGET_NO_BRCC_SET)
7796 return;
7800 init_insn_lengths();
7801 changed = 0;
7803 if (optimize > 1 && !TARGET_NO_COND_EXEC)
7805 arc_ifcvt ();
7806 unsigned int flags = pass_data_arc_ifcvt.todo_flags_finish;
7807 df_finish_pass ((flags & TODO_df_verify) != 0);
7809 if (dump_file)
7811 fprintf (dump_file, ";; After if conversion:\n\n");
7812 print_rtl (dump_file, get_insns ());
7816 /* Call shorten_branches to calculate the insn lengths. */
7817 shorten_branches (get_insns());
7818 cfun->machine->ccfsm_current_insn = NULL_RTX;
7820 if (!INSN_ADDRESSES_SET_P())
7821 fatal_error (input_location, "Insn addresses not set after shorten_branches");
7823 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7825 rtx label;
7826 enum attr_type insn_type;
7828 /* If a non-jump insn (or a casesi jump table), continue. */
7829 if (GET_CODE (insn) != JUMP_INSN ||
7830 GET_CODE (PATTERN (insn)) == ADDR_VEC
7831 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
7832 continue;
7834 /* If we already have a brcc, note if it is suitable for brcc_s.
7835 Be a bit generous with the brcc_s range so that we can take
7836 advantage of any code shortening from delay slot scheduling. */
7837 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
7839 rtx pat = PATTERN (insn);
7840 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
7841 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
7843 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7844 if ((offset >= -140 && offset < 140)
7845 && rtx_equal_p (XEXP (op, 1), const0_rtx)
7846 && compact_register_operand (XEXP (op, 0), VOIDmode)
7847 && equality_comparison_operator (op, VOIDmode))
7848 PUT_MODE (*ccp, CC_Zmode);
7849 else if (GET_MODE (*ccp) == CC_Zmode)
7850 PUT_MODE (*ccp, CC_ZNmode);
7851 continue;
7853 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
7854 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
7855 continue;
7857 /* OK. so we have a jump insn. */
7858 /* We need to check that it is a bcc. */
7859 /* Bcc => set (pc) (if_then_else ) */
7860 pattern = PATTERN (insn);
7861 if (GET_CODE (pattern) != SET
7862 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
7863 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
7864 continue;
7866 /* Now check if the jump is beyond the s9 range. */
7867 if (CROSSING_JUMP_P (insn))
7868 continue;
7869 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
7871 if(offset > 253 || offset < -254)
7872 continue;
7874 pc_target = SET_SRC (pattern);
7876 /* Avoid FPU instructions. */
7877 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
7878 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
7879 continue;
7881 /* Now go back and search for the set cc insn. */
7883 label = XEXP (pc_target, 1);
7886 rtx pat;
7887 rtx_insn *scan, *link_insn = NULL;
7889 for (scan = PREV_INSN (insn);
7890 scan && GET_CODE (scan) != CODE_LABEL;
7891 scan = PREV_INSN (scan))
7893 if (! INSN_P (scan))
7894 continue;
7895 pat = PATTERN (scan);
7896 if (GET_CODE (pat) == SET
7897 && cc_register (SET_DEST (pat), VOIDmode))
7899 link_insn = scan;
7900 break;
7903 if (!link_insn)
7904 continue;
7905 else
7906 /* Check if this is a data dependency. */
7908 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
7909 rtx cmp0, cmp1;
7911 /* Ok this is the set cc. copy args here. */
7912 op = XEXP (pc_target, 0);
7914 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
7915 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
7916 if (GET_CODE (op0) == ZERO_EXTRACT
7917 && XEXP (op0, 1) == const1_rtx
7918 && (GET_CODE (op) == EQ
7919 || GET_CODE (op) == NE))
7921 /* btst / b{eq,ne} -> bbit{0,1} */
7922 op0 = XEXP (cmp0, 0);
7923 op1 = XEXP (cmp0, 2);
7925 else if (!register_operand (op0, VOIDmode)
7926 || !general_operand (op1, VOIDmode))
7927 continue;
7928 /* Be careful not to break what cmpsfpx_raw is
7929 trying to create for checking equality of
7930 single-precision floats. */
7931 else if (TARGET_SPFP
7932 && GET_MODE (op0) == SFmode
7933 && GET_MODE (op1) == SFmode)
7934 continue;
7936 /* None of the two cmp operands should be set between the
7937 cmp and the branch. */
7938 if (reg_set_between_p (op0, link_insn, insn))
7939 continue;
7941 if (reg_set_between_p (op1, link_insn, insn))
7942 continue;
7944 /* Since the MODE check does not work, check that this is
7945 CC reg's last set location before insn, and also no
7946 instruction between the cmp and branch uses the
7947 condition codes. */
7948 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
7949 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
7950 continue;
7952 /* CC reg should be dead after insn. */
7953 if (!find_regno_note (insn, REG_DEAD, CC_REG))
7954 continue;
7956 op = gen_rtx_fmt_ee (GET_CODE (op),
7957 GET_MODE (op), cmp0, cmp1);
7958 /* If we create a LIMM where there was none before,
7959 we only benefit if we can avoid a scheduling bubble
7960 for the ARC600. Otherwise, we'd only forgo chances
7961 at short insn generation, and risk out-of-range
7962 branches. */
7963 if (!brcc_nolimm_operator (op, VOIDmode)
7964 && !long_immediate_operand (op1, VOIDmode)
7965 && (TARGET_ARC700
7966 || next_active_insn (link_insn) != insn))
7967 continue;
7969 /* Emit bbit / brcc (or brcc_s if possible).
7970 CC_Zmode indicates that brcc_s is possible. */
7972 if (op0 != cmp0)
7973 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
7974 else if ((offset >= -140 && offset < 140)
7975 && rtx_equal_p (op1, const0_rtx)
7976 && compact_register_operand (op0, VOIDmode)
7977 && (GET_CODE (op) == EQ
7978 || GET_CODE (op) == NE))
7979 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
7980 else
7981 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
7983 brcc_insn
7984 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
7985 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
7986 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
7987 brcc_insn
7988 = gen_rtx_PARALLEL
7989 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
7990 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
7992 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
7993 note = find_reg_note (insn, REG_BR_PROB, 0);
7994 if (note)
7996 XEXP (note, 1) = REG_NOTES (brcc_insn);
7997 REG_NOTES (brcc_insn) = note;
7999 note = find_reg_note (link_insn, REG_DEAD, op0);
8000 if (note)
8002 remove_note (link_insn, note);
8003 XEXP (note, 1) = REG_NOTES (brcc_insn);
8004 REG_NOTES (brcc_insn) = note;
8006 note = find_reg_note (link_insn, REG_DEAD, op1);
8007 if (note)
8009 XEXP (note, 1) = REG_NOTES (brcc_insn);
8010 REG_NOTES (brcc_insn) = note;
8013 changed = 1;
8015 /* Delete the bcc insn. */
8016 set_insn_deleted (insn);
8018 /* Delete the cmp insn. */
8019 set_insn_deleted (link_insn);
8024 /* Clear out insn_addresses. */
8025 INSN_ADDRESSES_FREE ();
8027 } while (changed);
8029 if (INSN_ADDRESSES_SET_P())
8030 fatal_error (input_location, "insn addresses not freed");
8032 arc_reorg_in_progress = 0;
8035 /* Check if the operands are valid for BRcc.d generation
8036 Valid Brcc.d patterns are
8037 Brcc.d b, c, s9
8038 Brcc.d b, u6, s9
8040 For cc={GT, LE, GTU, LEU}, u6=63 can not be allowed,
8041 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8042 does not have a delay slot
8044 Assumed precondition: Second operand is either a register or a u6 value. */
8046 bool
8047 valid_brcc_with_delay_p (rtx *operands)
8049 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
8050 return false;
8051 return brcc_nolimm_operator (operands[0], VOIDmode);
8054 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8055 access DECL using %gp_rel(...)($gp). */
8057 static bool
8058 arc_in_small_data_p (const_tree decl)
8060 HOST_WIDE_INT size;
8061 tree attr;
8063 /* Only variables are going into small data area. */
8064 if (TREE_CODE (decl) != VAR_DECL)
8065 return false;
8067 if (TARGET_NO_SDATA_SET)
8068 return false;
8070 /* Disable sdata references to weak variables. */
8071 if (DECL_WEAK (decl))
8072 return false;
8074 /* Don't put constants into the small data section: we want them to
8075 be in ROM rather than RAM. */
8076 if (TREE_READONLY (decl))
8077 return false;
8079 /* To ensure -mvolatile-cache works ld.di does not have a
8080 gp-relative variant. */
8081 if (!TARGET_VOLATILE_CACHE_SET
8082 && TREE_THIS_VOLATILE (decl))
8083 return false;
8085 /* Likewise for uncached data. */
8086 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
8087 if (lookup_attribute ("uncached", attr))
8088 return false;
8090 /* and for aux regs. */
8091 attr = DECL_ATTRIBUTES (decl);
8092 if (lookup_attribute ("aux", attr))
8093 return false;
8095 if (DECL_SECTION_NAME (decl) != 0)
8097 const char *name = DECL_SECTION_NAME (decl);
8098 if (strcmp (name, ".sdata") == 0
8099 || strcmp (name, ".sbss") == 0)
8100 return true;
8102 /* If it's not public, there's no need to put it in the small data
8103 section. */
8104 else if (TREE_PUBLIC (decl))
8106 size = int_size_in_bytes (TREE_TYPE (decl));
8107 return (size > 0 && size <= g_switch_value);
8109 return false;
8112 /* Return true if OP is an acceptable memory operand for ARCompact
8113 16-bit gp-relative load instructions.
8115 /* volatile cache option still to be handled. */
8117 bool
8118 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
8120 rtx addr;
8121 int size;
8122 int align = 0;
8123 int mask = 0;
8125 /* Eliminate non-memory operations. */
8126 if (GET_CODE (op) != MEM)
8127 return false;
8129 if (mode == VOIDmode)
8130 mode = GET_MODE (op);
8132 size = GET_MODE_SIZE (mode);
8134 /* dword operations really put out 2 instructions, so eliminate them. */
8135 if (size > UNITS_PER_WORD)
8136 return false;
8138 /* Decode the address now. */
8139 addr = XEXP (op, 0);
8141 if (!legitimate_small_data_address_p (addr))
8142 return false;
8144 if (!short_p || size == 1)
8145 return true;
8147 /* Now check for the alignment, the short loads using gp require the
8148 addresses to be aligned. */
8149 align = get_symbol_alignment (addr);
8150 switch (mode)
8152 case E_HImode:
8153 mask = 1;
8154 break;
8155 default:
8156 mask = 3;
8157 break;
8160 if (align && ((align & mask) == 0))
8161 return true;
8162 return false;
8165 /* Return TRUE if PAT is accessing an aux-reg. */
8167 static bool
8168 arc_is_aux_reg_p (rtx pat)
8170 tree attrs = NULL_TREE;
8171 tree addr;
8173 if (!MEM_P (pat))
8174 return false;
8176 /* Get the memory attributes. */
8177 addr = MEM_EXPR (pat);
8178 if (!addr)
8179 return false;
8181 /* Get the attributes. */
8182 if (TREE_CODE (addr) == VAR_DECL)
8183 attrs = DECL_ATTRIBUTES (addr);
8184 else if (TREE_CODE (addr) == MEM_REF)
8185 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8186 else
8187 return false;
8189 if (lookup_attribute ("aux", attrs))
8190 return true;
8191 return false;
8194 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8196 void
8197 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8198 unsigned HOST_WIDE_INT size,
8199 unsigned HOST_WIDE_INT align,
8200 unsigned HOST_WIDE_INT globalize_p)
8202 int in_small_data = arc_in_small_data_p (decl);
8203 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8205 /* Don't output aux-reg symbols. */
8206 if (mem != NULL_RTX && MEM_P (mem)
8207 && SYMBOL_REF_P (XEXP (mem, 0))
8208 && arc_is_aux_reg_p (mem))
8209 return;
8211 if (in_small_data)
8212 switch_to_section (get_named_section (NULL, ".sbss", 0));
8213 /* named_section (0,".sbss",0); */
8214 else
8215 switch_to_section (bss_section);
8217 if (globalize_p)
8218 (*targetm.asm_out.globalize_label) (stream, name);
8220 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8221 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8222 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8223 ASM_OUTPUT_LABEL (stream, name);
8225 if (size != 0)
8226 ASM_OUTPUT_SKIP (stream, size);
8229 static bool
8230 arc_preserve_reload_p (rtx in)
8232 return (GET_CODE (in) == PLUS
8233 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8234 && CONST_INT_P (XEXP (in, 1))
8235 && !((INTVAL (XEXP (in, 1)) & 511)));
8239 arc_register_move_cost (machine_mode,
8240 enum reg_class from_class, enum reg_class to_class)
8242 /* The ARC600 has no bypass for extension registers, hence a nop might be
8243 needed to be inserted after a write so that reads are safe. */
8244 if (TARGET_ARC600)
8246 if (to_class == MPY_WRITABLE_CORE_REGS)
8247 return 3;
8248 /* Instructions modifying LP_COUNT need 4 additional cycles before
8249 the register will actually contain the value. */
8250 else if (to_class == LPCOUNT_REG)
8251 return 6;
8252 else if (to_class == WRITABLE_CORE_REGS)
8253 return 6;
8256 /* Using lp_count as scratch reg is a VERY bad idea. */
8257 if (from_class == LPCOUNT_REG)
8258 return 1000;
8259 if (to_class == LPCOUNT_REG)
8260 return 6;
8262 /* Force an attempt to 'mov Dy,Dx' to spill. */
8263 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
8264 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8265 return 100;
8267 return 2;
8270 /* Emit code for an addsi3 instruction with OPERANDS.
8271 COND_P indicates if this will use conditional execution.
8272 Return the length of the instruction.
8273 If OUTPUT_P is false, don't actually output the instruction, just return
8274 its length. */
8276 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8278 char format[35];
8280 int match = operands_match_p (operands[0], operands[1]);
8281 int match2 = operands_match_p (operands[0], operands[2]);
8282 int intval = (REG_P (operands[2]) ? 1
8283 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8284 int neg_intval = -intval;
8285 int short_0 = satisfies_constraint_Rcq (operands[0]);
8286 int short_p = (!cond_p && short_0 && satisfies_constraint_Rcq (operands[1]));
8287 int ret = 0;
8289 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8290 && REGNO (OP) != 30) \
8291 || !TARGET_V2))
8293 #define ADDSI_OUTPUT1(FORMAT) do {\
8294 if (output_p) \
8295 output_asm_insn (FORMAT, operands);\
8296 return ret; \
8297 } while (0)
8298 #define ADDSI_OUTPUT(LIST) do {\
8299 if (output_p) \
8300 sprintf LIST;\
8301 ADDSI_OUTPUT1 (format);\
8302 return ret; \
8303 } while (0)
8305 /* First try to emit a 16 bit insn. */
8306 ret = 2;
8307 if (!cond_p
8308 /* If we are actually about to output this insn, don't try a 16 bit
8309 variant if we already decided that we don't want that
8310 (I.e. we upsized this insn to align some following insn.)
8311 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8312 but add1 r0,sp,35 doesn't. */
8313 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8315 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8316 patterns. */
8317 if (short_p
8318 && ((REG_H_P (operands[2])
8319 && (match || satisfies_constraint_Rcq (operands[2])))
8320 || (CONST_INT_P (operands[2])
8321 && ((unsigned) intval <= (match ? 127 : 7)))))
8322 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8324 /* Generate add_s b,b,h patterns. */
8325 if (short_0 && match2 && REG_H_P (operands[1]))
8326 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8328 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8329 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8330 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8331 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8333 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8334 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8335 && match && !(neg_intval & ~124)))
8336 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8338 /* Generate add_s h,h,s3 patterns. */
8339 if (REG_H_P (operands[0]) && match && TARGET_V2
8340 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8341 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8343 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8344 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8345 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8346 && satisfies_constraint_Rcq (operands[1])
8347 && satisfies_constraint_L (operands[2]))
8348 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8351 /* Now try to emit a 32 bit insn without long immediate. */
8352 ret = 4;
8353 if (!match && match2 && REG_P (operands[1]))
8354 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8355 if (match || !cond_p)
8357 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8358 int range_factor = neg_intval & intval;
8359 int shift;
8361 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8362 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8364 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8365 same size, do, so - the insn latency is lower. */
8366 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
8367 0x800 is not. */
8368 if ((intval >= 0 && intval <= limit)
8369 || (intval == -0x800 && limit == 0x7ff))
8370 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8371 else if ((intval < 0 && neg_intval <= limit)
8372 || (intval == 0x800 && limit == 0x7ff))
8373 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
8374 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
8375 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
8376 gcc_assert ((((1 << shift) - 1) & intval) == 0);
8377 if (((intval < 0 && intval != -0x4000)
8378 /* sub[123] is slower than add_s / sub, only use it if it
8379 avoids a long immediate. */
8380 && neg_intval <= limit << shift)
8381 || (intval == 0x4000 && limit == 0x7ff))
8382 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
8383 shift, neg_intval >> shift));
8384 else if ((intval >= 0 && intval <= limit << shift)
8385 || (intval == -0x4000 && limit == 0x7ff))
8386 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
8388 /* Try to emit a 16 bit opcode with long immediate. */
8389 ret = 6;
8390 if (short_p && match)
8391 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
8393 /* We have to use a 32 bit opcode, and with a long immediate. */
8394 ret = 8;
8395 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
8398 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
8399 Return the length of the instruction.
8400 If OUTPUT_P is false, don't actually output the instruction, just return
8401 its length. */
8403 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
8405 enum rtx_code commutative_op = GET_CODE (operands[3]);
8406 const char *pat = NULL;
8408 /* Canonical rtl should not have a constant in the first operand position. */
8409 gcc_assert (!CONSTANT_P (operands[1]));
8411 switch (commutative_op)
8413 case AND:
8414 if (satisfies_constraint_C1p (operands[2]))
8415 pat = "bmsk%? %0,%1,%Z2";
8416 else if (satisfies_constraint_C2p (operands[2]))
8418 operands[2] = GEN_INT ((~INTVAL (operands[2])));
8419 pat = "bmskn%? %0,%1,%Z2";
8421 else if (satisfies_constraint_Ccp (operands[2]))
8422 pat = "bclr%? %0,%1,%M2";
8423 else if (satisfies_constraint_CnL (operands[2]))
8424 pat = "bic%? %0,%1,%n2-1";
8425 break;
8426 case IOR:
8427 if (satisfies_constraint_C0p (operands[2]))
8428 pat = "bset%? %0,%1,%z2";
8429 break;
8430 case XOR:
8431 if (satisfies_constraint_C0p (operands[2]))
8432 pat = "bxor%? %0,%1,%z2";
8433 break;
8434 case PLUS:
8435 return arc_output_addsi (operands, true, output_p);
8436 default: break;
8438 if (output_p)
8439 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
8440 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
8441 return 4;
8442 return 8;
8445 /* Helper function of arc_expand_movmem. ADDR points to a chunk of memory.
8446 Emit code and return an potentially modified address such that offsets
8447 up to SIZE are can be added to yield a legitimate address.
8448 if REUSE is set, ADDR is a register that may be modified. */
8450 static rtx
8451 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
8453 rtx base = addr;
8454 rtx offs = const0_rtx;
8456 if (GET_CODE (base) == PLUS)
8458 offs = XEXP (base, 1);
8459 base = XEXP (base, 0);
8461 if (!REG_P (base)
8462 || (REGNO (base) != STACK_POINTER_REGNUM
8463 && REGNO_PTR_FRAME_P (REGNO (base)))
8464 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
8465 || !SMALL_INT (INTVAL (offs) + size))
8467 if (reuse)
8468 emit_insn (gen_add2_insn (addr, offs));
8469 else
8470 addr = copy_to_mode_reg (Pmode, addr);
8472 return addr;
8475 /* Like move_by_pieces, but take account of load latency, and actual
8476 offset ranges. Return true on success. */
8478 bool
8479 arc_expand_movmem (rtx *operands)
8481 rtx dst = operands[0];
8482 rtx src = operands[1];
8483 rtx dst_addr, src_addr;
8484 HOST_WIDE_INT size;
8485 int align = INTVAL (operands[3]);
8486 unsigned n_pieces;
8487 int piece = align;
8488 rtx store[2];
8489 rtx tmpx[2];
8490 int i;
8492 if (!CONST_INT_P (operands[2]))
8493 return false;
8494 size = INTVAL (operands[2]);
8495 /* move_by_pieces_ninsns is static, so we can't use it. */
8496 if (align >= 4)
8498 if (TARGET_LL64)
8499 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
8500 else
8501 n_pieces = (size + 2) / 4U + (size & 1);
8503 else if (align == 2)
8504 n_pieces = (size + 1) / 2U;
8505 else
8506 n_pieces = size;
8507 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
8508 return false;
8509 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
8510 possible. */
8511 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
8512 piece = 8;
8513 else if (piece > 4)
8514 piece = 4;
8515 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
8516 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
8517 store[0] = store[1] = NULL_RTX;
8518 tmpx[0] = tmpx[1] = NULL_RTX;
8519 for (i = 0; size > 0; i ^= 1, size -= piece)
8521 rtx tmp;
8522 machine_mode mode;
8524 while (piece > size)
8525 piece >>= 1;
8526 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
8527 /* If we don't re-use temporaries, the scheduler gets carried away,
8528 and the register pressure gets unnecessarily high. */
8529 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
8530 tmp = tmpx[i];
8531 else
8532 tmpx[i] = tmp = gen_reg_rtx (mode);
8533 dst_addr = force_offsettable (dst_addr, piece, 1);
8534 src_addr = force_offsettable (src_addr, piece, 1);
8535 if (store[i])
8536 emit_insn (store[i]);
8537 emit_move_insn (tmp, change_address (src, mode, src_addr));
8538 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
8539 dst_addr = plus_constant (Pmode, dst_addr, piece);
8540 src_addr = plus_constant (Pmode, src_addr, piece);
8542 if (store[i])
8543 emit_insn (store[i]);
8544 if (store[i^1])
8545 emit_insn (store[i^1]);
8546 return true;
8549 static bool
8550 arc_get_aux_arg (rtx pat, int *auxr)
8552 tree attr, addr = MEM_EXPR (pat);
8553 if (TREE_CODE (addr) != VAR_DECL)
8554 return false;
8556 attr = DECL_ATTRIBUTES (addr);
8557 if (lookup_attribute ("aux", attr))
8559 tree arg = TREE_VALUE (attr);
8560 if (arg)
8562 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
8563 return true;
8567 return false;
8570 /* Prepare operands for move in MODE. Return true iff the move has
8571 been emitted. */
8573 bool
8574 prepare_move_operands (rtx *operands, machine_mode mode)
8576 /* First handle aux attribute. */
8577 if (mode == SImode
8578 && (MEM_P (operands[0]) || MEM_P (operands[1])))
8580 rtx tmp;
8581 int auxr = 0;
8582 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
8584 /* Save operation. */
8585 if (arc_get_aux_arg (operands[0], &auxr))
8587 tmp = gen_reg_rtx (SImode);
8588 emit_move_insn (tmp, GEN_INT (auxr));
8590 else
8592 tmp = XEXP (operands[0], 0);
8595 operands[1] = force_reg (SImode, operands[1]);
8596 emit_insn (gen_rtx_UNSPEC_VOLATILE
8597 (VOIDmode, gen_rtvec (2, operands[1], tmp),
8598 VUNSPEC_ARC_SR));
8599 return true;
8601 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
8603 if (arc_get_aux_arg (operands[1], &auxr))
8605 tmp = gen_reg_rtx (SImode);
8606 emit_move_insn (tmp, GEN_INT (auxr));
8608 else
8610 tmp = XEXP (operands[1], 0);
8611 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
8613 /* Load operation. */
8614 gcc_assert (REG_P (operands[0]));
8615 emit_insn (gen_rtx_SET (operands[0],
8616 gen_rtx_UNSPEC_VOLATILE
8617 (SImode, gen_rtvec (1, tmp),
8618 VUNSPEC_ARC_LR)));
8619 return true;
8623 if (mode == SImode && SYMBOLIC_CONST (operands[1]))
8625 prepare_pic_move (operands, SImode);
8627 /* Disable any REG_EQUALs associated with the symref
8628 otherwise the optimization pass undoes the work done
8629 here and references the variable directly. */
8632 if (MEM_P (operands[0])
8633 && !(reload_in_progress || reload_completed))
8635 operands[1] = force_reg (mode, operands[1]);
8636 if (!move_dest_operand (operands[0], mode))
8638 rtx addr = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
8639 /* This is like change_address_1 (operands[0], mode, 0, 1) ,
8640 except that we can't use that function because it is static. */
8641 rtx pat = change_address (operands[0], mode, addr);
8642 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8643 operands[0] = pat;
8645 if (!cse_not_expected)
8647 rtx pat = XEXP (operands[0], 0);
8649 pat = arc_legitimize_address_0 (pat, pat, mode);
8650 if (pat)
8652 pat = change_address (operands[0], mode, pat);
8653 MEM_COPY_ATTRIBUTES (pat, operands[0]);
8654 operands[0] = pat;
8659 if (MEM_P (operands[1]) && !cse_not_expected)
8661 rtx pat = XEXP (operands[1], 0);
8663 pat = arc_legitimize_address_0 (pat, pat, mode);
8664 if (pat)
8666 pat = change_address (operands[1], mode, pat);
8667 MEM_COPY_ATTRIBUTES (pat, operands[1]);
8668 operands[1] = pat;
8672 return false;
8675 /* Output a library call to a function called FNAME that has been arranged
8676 to be local to any dso. */
8678 const char *
8679 arc_output_libcall (const char *fname)
8681 unsigned len = strlen (fname);
8682 static char buf[64];
8684 gcc_assert (len < sizeof buf - 35);
8685 if (TARGET_LONG_CALLS_SET
8686 || (TARGET_MEDIUM_CALLS && arc_ccfsm_cond_exec_p ()))
8688 if (flag_pic)
8689 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
8690 else
8691 sprintf (buf, "jl%%! @%s", fname);
8693 else
8694 sprintf (buf, "bl%%!%%* @%s", fname);
8695 return buf;
8698 /* Return the SImode highpart of the DImode value IN. */
8701 disi_highpart (rtx in)
8703 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
8706 /* Return length adjustment for INSN.
8707 For ARC600:
8708 A write to a core reg greater or equal to 32 must not be immediately
8709 followed by a use. Anticipate the length requirement to insert a nop
8710 between PRED and SUCC to prevent a hazard. */
8712 static int
8713 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
8715 if (!TARGET_ARC600)
8716 return 0;
8717 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
8718 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
8719 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
8720 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
8721 if (recog_memoized (pred) == CODE_FOR_mulsi_600
8722 || recog_memoized (pred) == CODE_FOR_umul_600
8723 || recog_memoized (pred) == CODE_FOR_mac_600
8724 || recog_memoized (pred) == CODE_FOR_mul64_600
8725 || recog_memoized (pred) == CODE_FOR_mac64_600
8726 || recog_memoized (pred) == CODE_FOR_umul64_600
8727 || recog_memoized (pred) == CODE_FOR_umac64_600)
8728 return 0;
8729 subrtx_iterator::array_type array;
8730 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
8732 const_rtx x = *iter;
8733 switch (GET_CODE (x))
8735 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
8736 break;
8737 default:
8738 /* This is also fine for PRE/POST_MODIFY, because they
8739 contain a SET. */
8740 continue;
8742 rtx dest = XEXP (x, 0);
8743 /* Check if this sets a an extension register. N.B. we use 61 for the
8744 condition codes, which is definitely not an extension register. */
8745 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
8746 /* Check if the same register is used by the PAT. */
8747 && (refers_to_regno_p
8748 (REGNO (dest),
8749 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
8750 PATTERN (succ), 0)))
8751 return 4;
8753 return 0;
8756 /* Given a rtx, check if it is an assembly instruction or not. */
8758 static int
8759 arc_asm_insn_p (rtx x)
8761 int i, j;
8763 if (x == 0)
8764 return 0;
8766 switch (GET_CODE (x))
8768 case ASM_OPERANDS:
8769 case ASM_INPUT:
8770 return 1;
8772 case SET:
8773 return arc_asm_insn_p (SET_SRC (x));
8775 case PARALLEL:
8776 j = 0;
8777 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
8778 j += arc_asm_insn_p (XVECEXP (x, 0, i));
8779 if ( j > 0)
8780 return 1;
8781 break;
8783 default:
8784 break;
8787 return 0;
8790 /* For ARC600:
8791 A write to a core reg greater or equal to 32 must not be immediately
8792 followed by a use. Anticipate the length requirement to insert a nop
8793 between PRED and SUCC to prevent a hazard. */
8796 arc_hazard (rtx_insn *pred, rtx_insn *succ)
8798 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
8799 return 0;
8801 if (TARGET_ARC600)
8802 return arc600_corereg_hazard (pred, succ);
8804 return 0;
8807 /* Return length adjustment for INSN. */
8810 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
8812 if (!INSN_P (insn))
8813 return len;
8814 /* We already handle sequences by ignoring the delay sequence flag. */
8815 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
8816 return len;
8818 /* Check for return with but one preceding insn since function
8819 start / call. */
8820 if (TARGET_PAD_RETURN
8821 && JUMP_P (insn)
8822 && GET_CODE (PATTERN (insn)) != ADDR_VEC
8823 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
8824 && get_attr_type (insn) == TYPE_RETURN)
8826 rtx_insn *prev = prev_active_insn (insn);
8828 if (!prev || !(prev = prev_active_insn (prev))
8829 || ((NONJUMP_INSN_P (prev)
8830 && GET_CODE (PATTERN (prev)) == SEQUENCE)
8831 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
8832 NON_SIBCALL)
8833 : CALL_ATTR (prev, NON_SIBCALL)))
8834 return len + 4;
8836 if (TARGET_ARC600)
8838 rtx_insn *succ = next_real_insn (insn);
8840 /* One the ARC600, a write to an extension register must be separated
8841 from a read. */
8842 if (succ && INSN_P (succ))
8843 len += arc600_corereg_hazard (insn, succ);
8846 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
8847 can go awry. */
8848 extract_constrain_insn_cached (insn);
8850 return len;
8853 /* Return a copy of COND from *STATEP, inverted if that is indicated by the
8854 CC field of *STATEP. */
8856 static rtx
8857 arc_get_ccfsm_cond (struct arc_ccfsm *statep, bool reverse)
8859 rtx cond = statep->cond;
8860 int raw_cc = get_arc_condition_code (cond);
8861 if (reverse)
8862 raw_cc = ARC_INVERSE_CONDITION_CODE (raw_cc);
8864 if (statep->cc == raw_cc)
8865 return copy_rtx (cond);
8867 gcc_assert (ARC_INVERSE_CONDITION_CODE (raw_cc) == statep->cc);
8869 machine_mode ccm = GET_MODE (XEXP (cond, 0));
8870 enum rtx_code code = reverse_condition (GET_CODE (cond));
8871 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
8872 code = reverse_condition_maybe_unordered (GET_CODE (cond));
8874 return gen_rtx_fmt_ee (code, GET_MODE (cond),
8875 copy_rtx (XEXP (cond, 0)), copy_rtx (XEXP (cond, 1)));
8878 /* Return version of PAT conditionalized with COND, which is part of INSN.
8879 ANNULLED indicates if INSN is an annulled delay-slot insn.
8880 Register further changes if necessary. */
8881 static rtx
8882 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
8884 /* For commutative operators, we generally prefer to have
8885 the first source match the destination. */
8886 if (GET_CODE (pat) == SET)
8888 rtx src = SET_SRC (pat);
8890 if (COMMUTATIVE_P (src))
8892 rtx src0 = XEXP (src, 0);
8893 rtx src1 = XEXP (src, 1);
8894 rtx dst = SET_DEST (pat);
8896 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
8897 /* Leave add_n alone - the canonical form is to
8898 have the complex summand first. */
8899 && REG_P (src0))
8900 pat = gen_rtx_SET (dst,
8901 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
8902 src1, src0));
8906 /* dwarf2out.c:dwarf2out_frame_debug_expr doesn't know
8907 what to do with COND_EXEC. */
8908 if (RTX_FRAME_RELATED_P (insn))
8910 /* If this is the delay slot insn of an anulled branch,
8911 dwarf2out.c:scan_trace understands the anulling semantics
8912 without the COND_EXEC. */
8913 gcc_assert (annulled);
8914 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
8915 REG_NOTES (insn));
8916 validate_change (insn, &REG_NOTES (insn), note, 1);
8918 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8919 return pat;
8922 /* Use the ccfsm machinery to do if conversion. */
8924 static unsigned
8925 arc_ifcvt (void)
8927 struct arc_ccfsm *statep = &cfun->machine->ccfsm_current;
8929 memset (statep, 0, sizeof *statep);
8930 for (rtx_insn *insn = get_insns (); insn; insn = next_insn (insn))
8932 arc_ccfsm_advance (insn, statep);
8934 switch (statep->state)
8936 case 0:
8937 break;
8938 case 1: case 2:
8940 /* Deleted branch. */
8941 arc_ccfsm_post_advance (insn, statep);
8942 gcc_assert (!IN_RANGE (statep->state, 1, 2));
8943 rtx_insn *seq = NEXT_INSN (PREV_INSN (insn));
8944 if (GET_CODE (PATTERN (seq)) == SEQUENCE)
8946 rtx slot = XVECEXP (PATTERN (seq), 0, 1);
8947 rtx pat = PATTERN (slot);
8948 if (INSN_ANNULLED_BRANCH_P (insn))
8950 rtx cond
8951 = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (slot));
8952 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
8954 if (!validate_change (seq, &PATTERN (seq), pat, 0))
8955 gcc_unreachable ();
8956 PUT_CODE (slot, NOTE);
8957 NOTE_KIND (slot) = NOTE_INSN_DELETED;
8959 else
8961 set_insn_deleted (insn);
8963 continue;
8965 case 3:
8966 if (LABEL_P (insn)
8967 && statep->target_label == CODE_LABEL_NUMBER (insn))
8969 arc_ccfsm_post_advance (insn, statep);
8970 if (--LABEL_NUSES (insn) == 0)
8971 delete_insn (insn);
8972 continue;
8974 /* Fall through. */
8975 case 4: case 5:
8976 if (!NONDEBUG_INSN_P (insn))
8977 break;
8979 /* Conditionalized insn. */
8981 rtx_insn *prev, *pprev;
8982 rtx *patp, pat, cond;
8983 bool annulled; annulled = false;
8985 /* If this is a delay slot insn in a non-annulled branch,
8986 don't conditionalize it. N.B., this should be fine for
8987 conditional return too. However, don't do this for
8988 unconditional branches, as these would be encountered when
8989 processing an 'else' part. */
8990 prev = PREV_INSN (insn);
8991 pprev = PREV_INSN (prev);
8992 if (pprev && NEXT_INSN (NEXT_INSN (pprev)) == NEXT_INSN (insn)
8993 && JUMP_P (prev) && get_attr_cond (prev) == COND_USE)
8995 if (!INSN_ANNULLED_BRANCH_P (prev))
8996 break;
8997 annulled = true;
9000 patp = &PATTERN (insn);
9001 pat = *patp;
9002 cond = arc_get_ccfsm_cond (statep, INSN_FROM_TARGET_P (insn));
9003 if (NONJUMP_INSN_P (insn) || CALL_P (insn))
9005 /* ??? don't conditionalize if all side effects are dead
9006 in the not-execute case. */
9008 pat = conditionalize_nonjump (pat, cond, insn, annulled);
9010 else if (simplejump_p (insn))
9012 patp = &SET_SRC (pat);
9013 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, *patp, pc_rtx);
9015 else if (JUMP_P (insn) && ANY_RETURN_P (PATTERN (insn)))
9017 pat = gen_rtx_IF_THEN_ELSE (VOIDmode, cond, pat, pc_rtx);
9018 pat = gen_rtx_SET (pc_rtx, pat);
9020 else
9021 gcc_unreachable ();
9022 validate_change (insn, patp, pat, 1);
9023 if (!apply_change_group ())
9024 gcc_unreachable ();
9025 if (JUMP_P (insn))
9027 rtx_insn *next = next_nonnote_insn (insn);
9028 if (GET_CODE (next) == BARRIER)
9029 delete_insn (next);
9030 if (statep->state == 3)
9031 continue;
9033 break;
9034 default:
9035 gcc_unreachable ();
9037 arc_ccfsm_post_advance (insn, statep);
9039 return 0;
9042 /* Find annulled delay insns and convert them to use the appropriate predicate.
9043 This allows branch shortening to size up these insns properly. */
9045 static unsigned
9046 arc_predicate_delay_insns (void)
9048 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9050 rtx pat, jump, dlay, src, cond, *patp;
9051 int reverse;
9053 if (!NONJUMP_INSN_P (insn)
9054 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9055 continue;
9056 jump = XVECEXP (pat, 0, 0);
9057 dlay = XVECEXP (pat, 0, 1);
9058 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9059 continue;
9060 /* If the branch insn does the annulling, leave the delay insn alone. */
9061 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9062 continue;
9063 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9064 on the other path. */
9065 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9066 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9067 src = SET_SRC (PATTERN (jump));
9068 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9069 cond = XEXP (src, 0);
9070 if (XEXP (src, 2) == pc_rtx)
9071 reverse = 0;
9072 else if (XEXP (src, 1) == pc_rtx)
9073 reverse = 1;
9074 else
9075 gcc_unreachable ();
9076 if (reverse != !INSN_FROM_TARGET_P (dlay))
9078 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9079 enum rtx_code code = reverse_condition (GET_CODE (cond));
9080 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9081 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9083 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9084 copy_rtx (XEXP (cond, 0)),
9085 copy_rtx (XEXP (cond, 1)));
9087 else
9088 cond = copy_rtx (cond);
9089 patp = &PATTERN (dlay);
9090 pat = *patp;
9091 pat = conditionalize_nonjump (pat, cond, dlay, true);
9092 validate_change (dlay, patp, pat, 1);
9093 if (!apply_change_group ())
9094 gcc_unreachable ();
9096 return 0;
9099 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9100 (other than of a forward brcc), it creates a hazard when there is a read
9101 of the same register at the branch target. We can't know what is at the
9102 branch target of calls, and for branches, we don't really know before the
9103 end of delay slot scheduling, either. Not only can individual instruction
9104 be hoisted out into a delay slot, a basic block can also be emptied this
9105 way, and branch and/or fall through targets be redirected. Hence we don't
9106 want such writes in a delay slot. */
9108 /* Return nonzreo iff INSN writes to an extension core register. */
9111 arc_write_ext_corereg (rtx insn)
9113 subrtx_iterator::array_type array;
9114 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9116 const_rtx x = *iter;
9117 switch (GET_CODE (x))
9119 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9120 break;
9121 default:
9122 /* This is also fine for PRE/POST_MODIFY, because they
9123 contain a SET. */
9124 continue;
9126 const_rtx dest = XEXP (x, 0);
9127 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9128 return 1;
9130 return 0;
9133 /* This is like the hook, but returns NULL when it can't / won't generate
9134 a legitimate address. */
9136 static rtx
9137 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9138 machine_mode mode)
9140 rtx addr, inner;
9142 if (flag_pic && SYMBOLIC_CONST (x))
9143 (x) = arc_legitimize_pic_address (x, 0);
9144 addr = x;
9145 if (GET_CODE (addr) == CONST)
9146 addr = XEXP (addr, 0);
9147 if (GET_CODE (addr) == PLUS
9148 && CONST_INT_P (XEXP (addr, 1))
9149 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9150 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9151 || (REG_P (XEXP (addr, 0))
9152 && (INTVAL (XEXP (addr, 1)) & 252))))
9154 HOST_WIDE_INT offs, upper;
9155 int size = GET_MODE_SIZE (mode);
9157 offs = INTVAL (XEXP (addr, 1));
9158 upper = (offs + 256 * size) & ~511 * size;
9159 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9160 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9161 if (GET_CODE (x) == CONST)
9162 inner = gen_rtx_CONST (Pmode, inner);
9163 #endif
9164 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9165 x = addr;
9167 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9168 x = force_reg (Pmode, x);
9169 if (memory_address_p ((machine_mode) mode, x))
9170 return x;
9171 return NULL_RTX;
9174 static rtx
9175 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9177 if (GET_CODE (orig_x) == SYMBOL_REF)
9179 enum tls_model model = SYMBOL_REF_TLS_MODEL (orig_x);
9180 if (model != 0)
9181 return arc_legitimize_tls_address (orig_x, model);
9184 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9186 if (new_x)
9187 return new_x;
9188 return orig_x;
9191 static rtx
9192 arc_delegitimize_address_0 (rtx op)
9194 switch (GET_CODE (op))
9196 case CONST:
9197 return arc_delegitimize_address_0 (XEXP (op, 0));
9199 case UNSPEC:
9200 switch (XINT (op, 1))
9202 case ARC_UNSPEC_GOT:
9203 case ARC_UNSPEC_GOTOFFPC:
9204 return XVECEXP (op, 0, 0);
9205 default:
9206 break;
9208 break;
9210 case PLUS:
9212 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9213 rtx t2 = XEXP (op, 1);
9215 if (t1 && t2)
9216 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9217 break;
9220 default:
9221 break;
9223 return NULL_RTX;
9226 static rtx
9227 arc_delegitimize_address (rtx orig_x)
9229 rtx x = orig_x;
9231 if (MEM_P (x))
9232 x = XEXP (x, 0);
9234 x = arc_delegitimize_address_0 (x);
9235 if (!x)
9236 return orig_x;
9238 if (MEM_P (orig_x))
9239 x = replace_equiv_address_nv (orig_x, x);
9240 return x;
9243 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9244 differ from the hardware register number in order to allow the generic
9245 code to correctly split the concatenation of acc1 and acc2. */
9248 gen_acc1 (void)
9250 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9253 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9254 differ from the hardware register number in order to allow the generic
9255 code to correctly split the concatenation of acc1 and acc2. */
9258 gen_acc2 (void)
9260 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9263 /* Return a REG rtx for mlo. N.B. the gcc-internal representation may
9264 differ from the hardware register number in order to allow the generic
9265 code to correctly split the concatenation of mhi and mlo. */
9268 gen_mlo (void)
9270 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 59: 58);
9273 /* Return a REG rtx for mhi. N.B. the gcc-internal representation may
9274 differ from the hardware register number in order to allow the generic
9275 code to correctly split the concatenation of mhi and mlo. */
9278 gen_mhi (void)
9280 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 58: 59);
9283 /* FIXME: a parameter should be added, and code added to final.c,
9284 to reproduce this functionality in shorten_branches. */
9285 #if 0
9286 /* Return nonzero iff BRANCH should be unaligned if possible by upsizing
9287 a previous instruction. */
9289 arc_unalign_branch_p (rtx branch)
9291 rtx note;
9293 if (!TARGET_UNALIGN_BRANCH)
9294 return 0;
9295 /* Do not do this if we have a filled delay slot. */
9296 if (get_attr_delay_slot_filled (branch) == DELAY_SLOT_FILLED_YES
9297 && !NEXT_INSN (branch)->deleted ())
9298 return 0;
9299 note = find_reg_note (branch, REG_BR_PROB, 0);
9300 return (!note
9301 || (arc_unalign_prob_threshold && !br_prob_note_reliable_p (note))
9302 || INTVAL (XEXP (note, 0)) < arc_unalign_prob_threshold);
9304 #endif
9306 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9307 are three reasons why we need to consider branches to be length 6:
9308 - annull-false delay slot insns are implemented using conditional execution,
9309 thus preventing short insn formation where used.
9310 - for ARC600: annul-true delay slot insns are implemented where possible
9311 using conditional execution, preventing short insn formation where used.
9312 - for ARC700: likely or somewhat likely taken branches are made long and
9313 unaligned if possible to avoid branch penalty. */
9315 bool
9316 arc_branch_size_unknown_p (void)
9318 return !optimize_size && arc_reorg_in_progress;
9321 /* The usual; we set up our machine_function data. */
9323 static struct machine_function *
9324 arc_init_machine_status (void)
9326 struct machine_function *machine;
9327 machine = ggc_cleared_alloc<machine_function> ();
9328 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9330 return machine;
9333 /* Implements INIT_EXPANDERS. We just set up to call the above
9334 function. */
9336 void
9337 arc_init_expanders (void)
9339 init_machine_status = arc_init_machine_status;
9342 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9343 indicates a number of elements to ignore - that allows to have a
9344 sibcall pattern that starts with (return). LOAD_P is zero for store
9345 multiple (for prologues), and one for load multiples (for epilogues),
9346 and two for load multiples where no final clobber of blink is required.
9347 We also skip the first load / store element since this is supposed to
9348 be checked in the instruction pattern. */
9351 arc_check_millicode (rtx op, int offset, int load_p)
9353 int len = XVECLEN (op, 0) - offset;
9354 int i;
9356 if (load_p == 2)
9358 if (len < 2 || len > 13)
9359 return 0;
9360 load_p = 1;
9362 else
9364 rtx elt = XVECEXP (op, 0, --len);
9366 if (GET_CODE (elt) != CLOBBER
9367 || !REG_P (XEXP (elt, 0))
9368 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9369 || len < 3 || len > 13)
9370 return 0;
9372 for (i = 1; i < len; i++)
9374 rtx elt = XVECEXP (op, 0, i + offset);
9375 rtx reg, mem, addr;
9377 if (GET_CODE (elt) != SET)
9378 return 0;
9379 mem = XEXP (elt, load_p);
9380 reg = XEXP (elt, 1-load_p);
9381 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9382 return 0;
9383 addr = XEXP (mem, 0);
9384 if (GET_CODE (addr) != PLUS
9385 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9386 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9387 return 0;
9389 return 1;
9392 /* Accessor functions for cfun->machine->unalign. */
9395 arc_get_unalign (void)
9397 return cfun->machine->unalign;
9400 void
9401 arc_clear_unalign (void)
9403 if (cfun)
9404 cfun->machine->unalign = 0;
9407 void
9408 arc_toggle_unalign (void)
9410 cfun->machine->unalign ^= 2;
9413 /* Operands 0..2 are the operands of a addsi which uses a 12 bit
9414 constant in operand 2, but which would require a LIMM because of
9415 operand mismatch.
9416 operands 3 and 4 are new SET_SRCs for operands 0. */
9418 void
9419 split_addsi (rtx *operands)
9421 int val = INTVAL (operands[2]);
9423 /* Try for two short insns first. Lengths being equal, we prefer
9424 expansions with shorter register lifetimes. */
9425 if (val > 127 && val <= 255
9426 && satisfies_constraint_Rcq (operands[0]))
9428 operands[3] = operands[2];
9429 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9431 else
9433 operands[3] = operands[1];
9434 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[2]);
9438 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9439 constant in operand 1, but which would require a LIMM because of
9440 operand mismatch.
9441 operands 3 and 4 are new SET_SRCs for operands 0. */
9443 void
9444 split_subsi (rtx *operands)
9446 int val = INTVAL (operands[1]);
9448 /* Try for two short insns first. Lengths being equal, we prefer
9449 expansions with shorter register lifetimes. */
9450 if (satisfies_constraint_Rcq (operands[0])
9451 && satisfies_constraint_Rcq (operands[2]))
9453 if (val >= -31 && val <= 127)
9455 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9456 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9457 return;
9459 else if (val >= 0 && val < 255)
9461 operands[3] = operands[1];
9462 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9463 return;
9466 /* If the destination is not an ARCompact16 register, we might
9467 still have a chance to make a short insn if the source is;
9468 we need to start with a reg-reg move for this. */
9469 operands[3] = operands[2];
9470 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9473 /* Handle DOUBLE_REGS uses.
9474 Operand 0: destination register
9475 Operand 1: source register */
9477 static bool
9478 arc_process_double_reg_moves (rtx *operands)
9480 rtx dest = operands[0];
9481 rtx src = operands[1];
9483 enum usesDxState { none, srcDx, destDx, maxDx };
9484 enum usesDxState state = none;
9486 if (refers_to_regno_p (40, 44, src, 0))
9487 state = srcDx;
9488 if (refers_to_regno_p (40, 44, dest, 0))
9490 /* Via arc_register_move_cost, we should never see D,D moves. */
9491 gcc_assert (state == none);
9492 state = destDx;
9495 if (state == none)
9496 return false;
9498 if (state == srcDx)
9500 /* Without the LR insn, we need to split this into a
9501 sequence of insns which will use the DEXCLx and DADDHxy
9502 insns to be able to read the Dx register in question. */
9503 if (TARGET_DPFP_DISABLE_LRSR)
9505 /* gen *movdf_insn_nolrsr */
9506 rtx set = gen_rtx_SET (dest, src);
9507 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9508 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9510 else
9512 /* When we have 'mov D, r' or 'mov D, D' then get the target
9513 register pair for use with LR insn. */
9514 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9515 TARGET_BIG_ENDIAN ? 0 : 4);
9516 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9517 TARGET_BIG_ENDIAN ? 4 : 0);
9519 /* Produce the two LR insns to get the high and low parts. */
9520 emit_insn (gen_rtx_SET (destHigh,
9521 gen_rtx_UNSPEC_VOLATILE (Pmode,
9522 gen_rtvec (1, src),
9523 VUNSPEC_ARC_LR_HIGH)));
9524 emit_insn (gen_rtx_SET (destLow,
9525 gen_rtx_UNSPEC_VOLATILE (Pmode,
9526 gen_rtvec (1, src),
9527 VUNSPEC_ARC_LR)));
9530 else if (state == destDx)
9532 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9533 LR insn get the target register pair. */
9534 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9535 TARGET_BIG_ENDIAN ? 0 : 4);
9536 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9537 TARGET_BIG_ENDIAN ? 4 : 0);
9539 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9541 else
9542 gcc_unreachable ();
9544 return true;
9547 /* operands 0..1 are the operands of a 64 bit move instruction.
9548 split it into two moves with operands 2/3 and 4/5. */
9550 void
9551 arc_split_move (rtx *operands)
9553 machine_mode mode = GET_MODE (operands[0]);
9554 int i;
9555 int swap = 0;
9556 rtx xop[4];
9558 if (TARGET_DPFP)
9560 if (arc_process_double_reg_moves (operands))
9561 return;
9564 if (TARGET_LL64
9565 && ((memory_operand (operands[0], mode)
9566 && (even_register_operand (operands[1], mode)
9567 || satisfies_constraint_Cm3 (operands[1])))
9568 || (memory_operand (operands[1], mode)
9569 && even_register_operand (operands[0], mode))))
9571 emit_move_insn (operands[0], operands[1]);
9572 return;
9575 if (TARGET_PLUS_QMACW
9576 && GET_CODE (operands[1]) == CONST_VECTOR)
9578 HOST_WIDE_INT intval0, intval1;
9579 if (GET_MODE (operands[1]) == V2SImode)
9581 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9582 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9584 else
9586 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9587 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9588 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9589 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9591 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9592 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9593 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9594 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9595 emit_move_insn (xop[0], xop[2]);
9596 emit_move_insn (xop[3], xop[1]);
9597 return;
9600 for (i = 0; i < 2; i++)
9602 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9604 rtx addr = XEXP (operands[i], 0);
9605 rtx r, o;
9606 enum rtx_code code;
9608 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9609 switch (GET_CODE (addr))
9611 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9612 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9613 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9614 pre_modify:
9615 code = PRE_MODIFY;
9616 break;
9617 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9618 case POST_INC: o = GEN_INT (8); goto post_modify;
9619 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9620 post_modify:
9621 code = POST_MODIFY;
9622 swap = 2;
9623 break;
9624 default:
9625 gcc_unreachable ();
9627 r = XEXP (addr, 0);
9628 xop[0+i] = adjust_automodify_address_nv
9629 (operands[i], SImode,
9630 gen_rtx_fmt_ee (code, Pmode, r,
9631 gen_rtx_PLUS (Pmode, r, o)),
9633 xop[2+i] = adjust_automodify_address_nv
9634 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9636 else
9638 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9639 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9642 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9644 swap = 2;
9645 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
9648 emit_move_insn (xop[0 + swap], xop[1 + swap]);
9649 emit_move_insn (xop[2 - swap], xop[3 - swap]);
9653 /* Select between the instruction output templates s_tmpl (for short INSNs)
9654 and l_tmpl (for long INSNs). */
9656 const char *
9657 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
9659 int is_short = arc_verify_short (insn, cfun->machine->unalign, -1);
9661 extract_constrain_insn_cached (insn);
9662 return is_short ? s_tmpl : l_tmpl;
9665 /* Searches X for any reference to REGNO, returning the rtx of the
9666 reference found if any. Otherwise, returns NULL_RTX. */
9669 arc_regno_use_in (unsigned int regno, rtx x)
9671 const char *fmt;
9672 int i, j;
9673 rtx tem;
9675 if (REG_P (x) && refers_to_regno_p (regno, x))
9676 return x;
9678 fmt = GET_RTX_FORMAT (GET_CODE (x));
9679 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
9681 if (fmt[i] == 'e')
9683 if ((tem = regno_use_in (regno, XEXP (x, i))))
9684 return tem;
9686 else if (fmt[i] == 'E')
9687 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
9688 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
9689 return tem;
9692 return NULL_RTX;
9695 /* Return the integer value of the "type" attribute for INSN, or -1 if
9696 INSN can't have attributes. */
9698 static int
9699 arc_attr_type (rtx_insn *insn)
9701 if (NONJUMP_INSN_P (insn)
9702 ? (GET_CODE (PATTERN (insn)) == USE
9703 || GET_CODE (PATTERN (insn)) == CLOBBER)
9704 : JUMP_P (insn)
9705 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9706 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9707 : !CALL_P (insn))
9708 return -1;
9709 return get_attr_type (insn);
9712 /* Return true if insn sets the condition codes. */
9714 bool
9715 arc_sets_cc_p (rtx_insn *insn)
9717 if (NONJUMP_INSN_P (insn))
9718 if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
9719 insn = seq->insn (seq->len () - 1);
9720 return arc_attr_type (insn) == TYPE_COMPARE;
9723 /* Return true if INSN is an instruction with a delay slot we may want
9724 to fill. */
9726 bool
9727 arc_need_delay (rtx_insn *insn)
9729 rtx_insn *next;
9731 if (!flag_delayed_branch)
9732 return false;
9733 /* The return at the end of a function needs a delay slot. */
9734 if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE
9735 && (!(next = next_active_insn (insn))
9736 || ((!NONJUMP_INSN_P (next) || GET_CODE (PATTERN (next)) != SEQUENCE)
9737 && arc_attr_type (next) == TYPE_RETURN))
9738 && (!TARGET_PAD_RETURN
9739 || (prev_active_insn (insn)
9740 && prev_active_insn (prev_active_insn (insn))
9741 && prev_active_insn (prev_active_insn (prev_active_insn (insn))))))
9742 return true;
9743 if (NONJUMP_INSN_P (insn)
9744 ? (GET_CODE (PATTERN (insn)) == USE
9745 || GET_CODE (PATTERN (insn)) == CLOBBER
9746 || GET_CODE (PATTERN (insn)) == SEQUENCE)
9747 : JUMP_P (insn)
9748 ? (GET_CODE (PATTERN (insn)) == ADDR_VEC
9749 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
9750 : !CALL_P (insn))
9751 return false;
9752 return num_delay_slots (insn) != 0;
9755 /* Return true if the scheduling pass(es) has/have already run,
9756 i.e. where possible, we should try to mitigate high latencies
9757 by different instruction selection. */
9759 bool
9760 arc_scheduling_not_expected (void)
9762 return cfun->machine->arc_reorg_started;
9765 /* Code has a minimum p2 alignment of 1, which we must restore after
9766 an ADDR_DIFF_VEC. */
9769 arc_label_align (rtx_insn *label)
9771 if (align_labels.levels[0].log < 1)
9773 rtx_insn *next = next_nonnote_nondebug_insn (label);
9774 if (INSN_P (next) && recog_memoized (next) >= 0)
9775 return 1;
9777 return align_labels.levels[0].log;
9780 /* Return true if LABEL is in executable code. */
9782 bool
9783 arc_text_label (rtx_insn *label)
9785 rtx_insn *next;
9787 /* ??? We use deleted labels like they were still there, see
9788 gcc.c-torture/compile/20000326-2.c . */
9789 gcc_assert (GET_CODE (label) == CODE_LABEL
9790 || (GET_CODE (label) == NOTE
9791 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
9792 next = next_nonnote_insn (label);
9793 if (next)
9794 return (!JUMP_TABLE_DATA_P (next)
9795 || GET_CODE (PATTERN (next)) != ADDR_VEC);
9796 else if (!PREV_INSN (label))
9797 /* ??? sometimes text labels get inserted very late, see
9798 gcc.dg/torture/stackalign/comp-goto-1.c */
9799 return true;
9800 return false;
9803 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
9804 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
9805 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
9806 to redirect two breqs. */
9808 static bool
9809 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
9811 /* ??? get_attr_type is declared to take an rtx. */
9812 union { const rtx_insn *c; rtx_insn *r; } u;
9814 u.c = follower;
9815 if (CROSSING_JUMP_P (followee))
9816 switch (get_attr_type (u.r))
9818 case TYPE_BRANCH:
9819 if (get_attr_length (u.r) != 2)
9820 break;
9821 /* Fall through. */
9822 case TYPE_BRCC:
9823 case TYPE_BRCC_NO_DELAY_SLOT:
9824 return false;
9825 default:
9826 return true;
9828 return true;
9831 /* Return the register number of the register holding the return address
9832 for a function of type TYPE. */
9835 arc_return_address_register (unsigned int fn_type)
9837 int regno = 0;
9839 if (ARC_INTERRUPT_P (fn_type))
9841 if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
9842 regno = ILINK1_REGNUM;
9843 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
9844 regno = ILINK2_REGNUM;
9845 else
9846 gcc_unreachable ();
9848 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
9849 regno = RETURN_ADDR_REGNUM;
9851 gcc_assert (regno != 0);
9852 return regno;
9855 /* Implement EPILOGUE_USES.
9856 Return true if REGNO should be added to the deemed uses of the epilogue.
9858 We have to make sure all the register restore instructions are
9859 known to be live in interrupt functions, plus the blink register if
9860 it is clobbered by the isr. */
9862 bool
9863 arc_epilogue_uses (int regno)
9865 unsigned int fn_type;
9867 if (regno == arc_tp_regno)
9868 return true;
9870 fn_type = arc_compute_function_type (cfun);
9871 if (reload_completed)
9873 if (ARC_INTERRUPT_P (cfun->machine->fn_type))
9875 if (!fixed_regs[regno])
9876 return true;
9877 return ((regno == arc_return_address_register (fn_type))
9878 || (regno == RETURN_ADDR_REGNUM));
9880 else
9881 return regno == RETURN_ADDR_REGNUM;
9883 else
9884 return regno == arc_return_address_register (fn_type);
9887 /* Helper for EH_USES macro. */
9889 bool
9890 arc_eh_uses (int regno)
9892 if (regno == arc_tp_regno)
9893 return true;
9894 return false;
9897 #ifndef TARGET_NO_LRA
9898 #define TARGET_NO_LRA !TARGET_LRA
9899 #endif
9901 static bool
9902 arc_lra_p (void)
9904 return !TARGET_NO_LRA;
9907 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to use
9908 Rcq registers, because some insn are shorter with them. OTOH we already
9909 have separate alternatives for this purpose, and other insns don't
9910 mind, so maybe we should rather prefer the other registers?
9911 We need more data, and we can only get that if we allow people to
9912 try all options. */
9913 static int
9914 arc_register_priority (int r)
9916 switch (arc_lra_priority_tag)
9918 case ARC_LRA_PRIORITY_NONE:
9919 return 0;
9920 case ARC_LRA_PRIORITY_NONCOMPACT:
9921 return ((((r & 7) ^ 4) - 4) & 15) != r;
9922 case ARC_LRA_PRIORITY_COMPACT:
9923 return ((((r & 7) ^ 4) - 4) & 15) == r;
9924 default:
9925 gcc_unreachable ();
9929 static reg_class_t
9930 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
9932 return GENERAL_REGS;
9935 bool
9936 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
9937 int itype)
9939 rtx x = *p;
9940 enum reload_type type = (enum reload_type) itype;
9942 if (GET_CODE (x) == PLUS
9943 && CONST_INT_P (XEXP (x, 1))
9944 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
9945 || (REG_P (XEXP (x, 0))
9946 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
9948 int scale = GET_MODE_SIZE (mode);
9949 int shift;
9950 rtx index_rtx = XEXP (x, 1);
9951 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
9952 rtx reg, sum, sum2;
9954 if (scale > 4)
9955 scale = 4;
9956 if ((scale-1) & offset)
9957 scale = 1;
9958 shift = scale >> 1;
9959 offset_base
9960 = ((offset + (256 << shift))
9961 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
9962 /* Sometimes the normal form does not suit DImode. We
9963 could avoid that by using smaller ranges, but that
9964 would give less optimized code when SImode is
9965 prevalent. */
9966 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
9968 int regno;
9970 reg = XEXP (x, 0);
9971 regno = REGNO (reg);
9972 sum2 = sum = plus_constant (Pmode, reg, offset_base);
9974 if (reg_equiv_constant (regno))
9976 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
9977 offset_base);
9978 if (GET_CODE (sum2) == PLUS)
9979 sum2 = gen_rtx_CONST (Pmode, sum2);
9981 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
9982 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
9983 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
9984 type);
9985 return true;
9988 /* We must re-recognize what we created before. */
9989 else if (GET_CODE (x) == PLUS
9990 && GET_CODE (XEXP (x, 0)) == PLUS
9991 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
9992 && REG_P (XEXP (XEXP (x, 0), 0))
9993 && CONST_INT_P (XEXP (x, 1)))
9995 /* Because this address is so complex, we know it must have
9996 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
9997 it is already unshared, and needs no further unsharing. */
9998 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
9999 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10000 return true;
10002 return false;
10005 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10007 static bool
10008 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
10009 unsigned int align,
10010 enum by_pieces_operation op,
10011 bool speed_p)
10013 /* Let the movmem expander handle small block moves. */
10014 if (op == MOVE_BY_PIECES)
10015 return false;
10017 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10020 /* Emit a (pre) memory barrier around an atomic sequence according to
10021 MODEL. */
10023 static void
10024 arc_pre_atomic_barrier (enum memmodel model)
10026 if (need_atomic_barrier_p (model, true))
10027 emit_insn (gen_memory_barrier ());
10030 /* Emit a (post) memory barrier around an atomic sequence according to
10031 MODEL. */
10033 static void
10034 arc_post_atomic_barrier (enum memmodel model)
10036 if (need_atomic_barrier_p (model, false))
10037 emit_insn (gen_memory_barrier ());
10040 /* Expand a compare and swap pattern. */
10042 static void
10043 emit_unlikely_jump (rtx insn)
10045 rtx_insn *jump = emit_jump_insn (insn);
10046 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10049 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10050 32-bit compare and swap on the word containing the byte or
10051 half-word. The difference between a weak and a strong CAS is that
10052 the weak version may simply fail. The strong version relies on two
10053 loops, one checks if the SCOND op is succsfully or not, the other
10054 checks if the 32 bit accessed location which contains the 8 or 16
10055 bit datum is not changed by other thread. The first loop is
10056 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10057 loops is implemented by this routine. */
10059 static void
10060 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10061 rtx oldval, rtx newval, rtx weak,
10062 rtx mod_s, rtx mod_f)
10064 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10065 rtx addr = gen_reg_rtx (Pmode);
10066 rtx off = gen_reg_rtx (SImode);
10067 rtx oldv = gen_reg_rtx (SImode);
10068 rtx newv = gen_reg_rtx (SImode);
10069 rtx oldvalue = gen_reg_rtx (SImode);
10070 rtx newvalue = gen_reg_rtx (SImode);
10071 rtx res = gen_reg_rtx (SImode);
10072 rtx resv = gen_reg_rtx (SImode);
10073 rtx memsi, val, mask, end_label, loop_label, cc, x;
10074 machine_mode mode;
10075 bool is_weak = (weak != const0_rtx);
10077 /* Truncate the address. */
10078 emit_insn (gen_rtx_SET (addr,
10079 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10081 /* Compute the datum offset. */
10082 emit_insn (gen_rtx_SET (off,
10083 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10084 if (TARGET_BIG_ENDIAN)
10085 emit_insn (gen_rtx_SET (off,
10086 gen_rtx_MINUS (SImode,
10087 (GET_MODE (mem) == QImode) ?
10088 GEN_INT (3) : GEN_INT (2), off)));
10090 /* Normal read from truncated address. */
10091 memsi = gen_rtx_MEM (SImode, addr);
10092 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10093 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10095 val = copy_to_reg (memsi);
10097 /* Convert the offset in bits. */
10098 emit_insn (gen_rtx_SET (off,
10099 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10101 /* Get the proper mask. */
10102 if (GET_MODE (mem) == QImode)
10103 mask = force_reg (SImode, GEN_INT (0xff));
10104 else
10105 mask = force_reg (SImode, GEN_INT (0xffff));
10107 emit_insn (gen_rtx_SET (mask,
10108 gen_rtx_ASHIFT (SImode, mask, off)));
10110 /* Prepare the old and new values. */
10111 emit_insn (gen_rtx_SET (val,
10112 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10113 val)));
10115 oldval = gen_lowpart (SImode, oldval);
10116 emit_insn (gen_rtx_SET (oldv,
10117 gen_rtx_ASHIFT (SImode, oldval, off)));
10119 newval = gen_lowpart_common (SImode, newval);
10120 emit_insn (gen_rtx_SET (newv,
10121 gen_rtx_ASHIFT (SImode, newval, off)));
10123 emit_insn (gen_rtx_SET (oldv,
10124 gen_rtx_AND (SImode, oldv, mask)));
10126 emit_insn (gen_rtx_SET (newv,
10127 gen_rtx_AND (SImode, newv, mask)));
10129 if (!is_weak)
10131 end_label = gen_label_rtx ();
10132 loop_label = gen_label_rtx ();
10133 emit_label (loop_label);
10136 /* Make the old and new values. */
10137 emit_insn (gen_rtx_SET (oldvalue,
10138 gen_rtx_IOR (SImode, oldv, val)));
10140 emit_insn (gen_rtx_SET (newvalue,
10141 gen_rtx_IOR (SImode, newv, val)));
10143 /* Try an 32bit atomic compare and swap. It clobbers the CC
10144 register. */
10145 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10146 weak, mod_s, mod_f));
10148 /* Regardless of the weakness of the operation, a proper boolean
10149 result needs to be provided. */
10150 x = gen_rtx_REG (CC_Zmode, CC_REG);
10151 x = gen_rtx_EQ (SImode, x, const0_rtx);
10152 emit_insn (gen_rtx_SET (bool_result, x));
10154 if (!is_weak)
10156 /* Check the results: if the atomic op is successfully the goto
10157 to end label. */
10158 x = gen_rtx_REG (CC_Zmode, CC_REG);
10159 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10160 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10161 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10162 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10164 /* Wait for the right moment when the accessed 32-bit location
10165 is stable. */
10166 emit_insn (gen_rtx_SET (resv,
10167 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10168 res)));
10169 mode = SELECT_CC_MODE (NE, resv, val);
10170 cc = gen_rtx_REG (mode, CC_REG);
10171 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10173 /* Set the new value of the 32 bit location, proper masked. */
10174 emit_insn (gen_rtx_SET (val, resv));
10176 /* Try again if location is unstable. Fall through if only
10177 scond op failed. */
10178 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10179 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10180 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10181 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10183 emit_label (end_label);
10186 /* End: proper return the result for the given mode. */
10187 emit_insn (gen_rtx_SET (res,
10188 gen_rtx_AND (SImode, res, mask)));
10190 emit_insn (gen_rtx_SET (res,
10191 gen_rtx_LSHIFTRT (SImode, res, off)));
10193 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10196 /* Helper function used by "atomic_compare_and_swap" expand
10197 pattern. */
10199 void
10200 arc_expand_compare_and_swap (rtx operands[])
10202 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10203 machine_mode mode;
10205 bval = operands[0];
10206 rval = operands[1];
10207 mem = operands[2];
10208 oldval = operands[3];
10209 newval = operands[4];
10210 is_weak = operands[5];
10211 mod_s = operands[6];
10212 mod_f = operands[7];
10213 mode = GET_MODE (mem);
10215 if (reg_overlap_mentioned_p (rval, oldval))
10216 oldval = copy_to_reg (oldval);
10218 if (mode == SImode)
10220 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10221 is_weak, mod_s, mod_f));
10222 x = gen_rtx_REG (CC_Zmode, CC_REG);
10223 x = gen_rtx_EQ (SImode, x, const0_rtx);
10224 emit_insn (gen_rtx_SET (bval, x));
10226 else
10228 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10229 is_weak, mod_s, mod_f);
10233 /* Helper function used by the "atomic_compare_and_swapsi_1"
10234 pattern. */
10236 void
10237 arc_split_compare_and_swap (rtx operands[])
10239 rtx rval, mem, oldval, newval;
10240 machine_mode mode;
10241 enum memmodel mod_s, mod_f;
10242 bool is_weak;
10243 rtx label1, label2, x, cond;
10245 rval = operands[0];
10246 mem = operands[1];
10247 oldval = operands[2];
10248 newval = operands[3];
10249 is_weak = (operands[4] != const0_rtx);
10250 mod_s = (enum memmodel) INTVAL (operands[5]);
10251 mod_f = (enum memmodel) INTVAL (operands[6]);
10252 mode = GET_MODE (mem);
10254 /* ARC atomic ops work only with 32-bit aligned memories. */
10255 gcc_assert (mode == SImode);
10257 arc_pre_atomic_barrier (mod_s);
10259 label1 = NULL_RTX;
10260 if (!is_weak)
10262 label1 = gen_label_rtx ();
10263 emit_label (label1);
10265 label2 = gen_label_rtx ();
10267 /* Load exclusive. */
10268 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10270 /* Check if it is oldval. */
10271 mode = SELECT_CC_MODE (NE, rval, oldval);
10272 cond = gen_rtx_REG (mode, CC_REG);
10273 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10275 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10276 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10277 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10278 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10280 /* Exclusively store new item. Store clobbers CC reg. */
10281 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10283 if (!is_weak)
10285 /* Check the result of the store. */
10286 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10287 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10288 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10289 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10290 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10293 if (mod_f != MEMMODEL_RELAXED)
10294 emit_label (label2);
10296 arc_post_atomic_barrier (mod_s);
10298 if (mod_f == MEMMODEL_RELAXED)
10299 emit_label (label2);
10302 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10303 to perform. MEM is the memory on which to operate. VAL is the second
10304 operand of the binary operator. BEFORE and AFTER are optional locations to
10305 return the value of MEM either before of after the operation. MODEL_RTX
10306 is a CONST_INT containing the memory model to use. */
10308 void
10309 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10310 rtx orig_before, rtx orig_after, rtx model_rtx)
10312 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10313 machine_mode mode = GET_MODE (mem);
10314 rtx label, x, cond;
10315 rtx before = orig_before, after = orig_after;
10317 /* ARC atomic ops work only with 32-bit aligned memories. */
10318 gcc_assert (mode == SImode);
10320 arc_pre_atomic_barrier (model);
10322 label = gen_label_rtx ();
10323 emit_label (label);
10324 label = gen_rtx_LABEL_REF (VOIDmode, label);
10326 if (before == NULL_RTX)
10327 before = gen_reg_rtx (mode);
10329 if (after == NULL_RTX)
10330 after = gen_reg_rtx (mode);
10332 /* Load exclusive. */
10333 emit_insn (gen_arc_load_exclusivesi (before, mem));
10335 switch (code)
10337 case NOT:
10338 x = gen_rtx_AND (mode, before, val);
10339 emit_insn (gen_rtx_SET (after, x));
10340 x = gen_rtx_NOT (mode, after);
10341 emit_insn (gen_rtx_SET (after, x));
10342 break;
10344 case MINUS:
10345 if (CONST_INT_P (val))
10347 val = GEN_INT (-INTVAL (val));
10348 code = PLUS;
10351 /* FALLTHRU. */
10352 default:
10353 x = gen_rtx_fmt_ee (code, mode, before, val);
10354 emit_insn (gen_rtx_SET (after, x));
10355 break;
10358 /* Exclusively store new item. Store clobbers CC reg. */
10359 emit_insn (gen_arc_store_exclusivesi (mem, after));
10361 /* Check the result of the store. */
10362 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10363 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10364 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10365 label, pc_rtx);
10366 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10368 arc_post_atomic_barrier (model);
10371 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10373 static bool
10374 arc_no_speculation_in_delay_slots_p ()
10376 return true;
10379 /* Return a parallel of registers to represent where to find the
10380 register pieces if required, otherwise NULL_RTX. */
10382 static rtx
10383 arc_dwarf_register_span (rtx rtl)
10385 machine_mode mode = GET_MODE (rtl);
10386 unsigned regno;
10387 rtx p;
10389 if (GET_MODE_SIZE (mode) != 8)
10390 return NULL_RTX;
10392 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10393 regno = REGNO (rtl);
10394 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10395 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10397 return p;
10400 /* Return true if OP is an acceptable memory operand for ARCompact
10401 16-bit load instructions of MODE.
10403 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10404 non scaled instructions.
10406 SCALED: TRUE if address can be scaled. */
10408 bool
10409 compact_memory_operand_p (rtx op, machine_mode mode,
10410 bool av2short, bool scaled)
10412 rtx addr, plus0, plus1;
10413 int size, off;
10415 /* Eliminate non-memory operations. */
10416 if (GET_CODE (op) != MEM)
10417 return 0;
10419 /* .di instructions have no 16-bit form. */
10420 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10421 return false;
10423 /* likewise for uncached types. */
10424 if (arc_is_uncached_mem_p (op))
10425 return false;
10427 if (mode == VOIDmode)
10428 mode = GET_MODE (op);
10430 size = GET_MODE_SIZE (mode);
10432 /* dword operations really put out 2 instructions, so eliminate
10433 them. */
10434 if (size > UNITS_PER_WORD)
10435 return false;
10437 /* Decode the address now. */
10438 addr = XEXP (op, 0);
10439 switch (GET_CODE (addr))
10441 case REG:
10442 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10443 || COMPACT_GP_REG_P (REGNO (addr))
10444 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10445 case PLUS:
10446 plus0 = XEXP (addr, 0);
10447 plus1 = XEXP (addr, 1);
10449 if ((GET_CODE (plus0) == REG)
10450 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10451 || COMPACT_GP_REG_P (REGNO (plus0)))
10452 && ((GET_CODE (plus1) == REG)
10453 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10454 || COMPACT_GP_REG_P (REGNO (plus1)))))
10456 return !av2short;
10459 if ((GET_CODE (plus0) == REG)
10460 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10461 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10462 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10463 && (GET_CODE (plus1) == CONST_INT))
10465 bool valid = false;
10467 off = INTVAL (plus1);
10469 /* Negative offset is not supported in 16-bit load/store insns. */
10470 if (off < 0)
10471 return 0;
10473 /* Only u5 immediates allowed in code density instructions. */
10474 if (av2short)
10476 switch (size)
10478 case 1:
10479 return false;
10480 case 2:
10481 /* This is an ldh_s.x instruction, check the u6
10482 immediate. */
10483 if (COMPACT_GP_REG_P (REGNO (plus0)))
10484 valid = true;
10485 break;
10486 case 4:
10487 /* Only u5 immediates allowed in 32bit access code
10488 density instructions. */
10489 if (REGNO (plus0) <= 31)
10490 return ((off < 32) && (off % 4 == 0));
10491 break;
10492 default:
10493 return false;
10496 else
10497 if (COMPACT_GP_REG_P (REGNO (plus0)))
10498 valid = true;
10500 if (valid)
10503 switch (size)
10505 case 1:
10506 return (off < 32);
10507 case 2:
10508 /* The 6-bit constant get shifted to fit the real
10509 5-bits field. Check also for the alignment. */
10510 return ((off < 64) && (off % 2 == 0));
10511 case 4:
10512 return ((off < 128) && (off % 4 == 0));
10513 default:
10514 return false;
10519 if (REG_P (plus0) && CONST_INT_P (plus1)
10520 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10521 || SP_REG_P (REGNO (plus0)))
10522 && !av2short)
10524 off = INTVAL (plus1);
10525 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10528 if ((GET_CODE (plus0) == MULT)
10529 && (GET_CODE (XEXP (plus0, 0)) == REG)
10530 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10531 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10532 && (GET_CODE (plus1) == REG)
10533 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10534 || COMPACT_GP_REG_P (REGNO (plus1))))
10535 return scaled;
10536 default:
10537 break ;
10538 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10539 for 16-bit load instructions. */
10541 return false;
10544 /* Return the frame pointer value to be backed up in the setjmp buffer. */
10546 static rtx
10547 arc_builtin_setjmp_frame_value (void)
10549 /* We always want to preserve whatever value is currently in the frame
10550 pointer register. For frames that are using the frame pointer the new
10551 value of the frame pointer register will have already been computed
10552 (as part of the prologue). For frames that are not using the frame
10553 pointer it is important that we backup whatever value is in the frame
10554 pointer register, as earlier (more outer) frames may have placed a
10555 value into the frame pointer register. It might be tempting to try
10556 and use `frame_pointer_rtx` here, however, this is not what we want.
10557 For frames that are using the frame pointer this will give the
10558 correct value. However, for frames that are not using the frame
10559 pointer this will still give the value that _would_ have been the
10560 frame pointer value for this frame (if the use of the frame pointer
10561 had not been removed). We really do want the raw frame pointer
10562 register value. */
10563 return gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
10566 /* Return nonzero if a jli call should be generated for a call from
10567 the current function to DECL. */
10569 bool
10570 arc_is_jli_call_p (rtx pat)
10572 tree attrs;
10573 tree decl = SYMBOL_REF_DECL (pat);
10575 /* If it is not a well defined public function then return false. */
10576 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
10577 return false;
10579 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10580 if (lookup_attribute ("jli_always", attrs))
10581 return true;
10583 if (lookup_attribute ("jli_fixed", attrs))
10584 return true;
10586 return TARGET_JLI_ALWAYS;
10589 /* Handle and "jli" attribute; arguments as in struct
10590 attribute_spec.handler. */
10592 static tree
10593 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
10594 tree name, tree args, int,
10595 bool *no_add_attrs)
10597 if (!TARGET_V2)
10599 warning (OPT_Wattributes,
10600 "%qE attribute only valid for ARCv2 architecture",
10601 name);
10602 *no_add_attrs = true;
10605 if (args == NULL_TREE)
10607 warning (OPT_Wattributes,
10608 "argument of %qE attribute is missing",
10609 name);
10610 *no_add_attrs = true;
10612 else
10614 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10615 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10616 tree arg = TREE_VALUE (args);
10617 if (TREE_CODE (arg) != INTEGER_CST)
10619 warning (0, "%qE attribute allows only an integer constant argument",
10620 name);
10621 *no_add_attrs = true;
10623 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10625 return NULL_TREE;
10628 /* Handle and "scure" attribute; arguments as in struct
10629 attribute_spec.handler. */
10631 static tree
10632 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
10633 tree name, tree args, int,
10634 bool *no_add_attrs)
10636 if (!TARGET_EM)
10638 warning (OPT_Wattributes,
10639 "%qE attribute only valid for ARC EM architecture",
10640 name);
10641 *no_add_attrs = true;
10644 if (args == NULL_TREE)
10646 warning (OPT_Wattributes,
10647 "argument of %qE attribute is missing",
10648 name);
10649 *no_add_attrs = true;
10651 else
10653 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10654 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10655 tree arg = TREE_VALUE (args);
10656 if (TREE_CODE (arg) != INTEGER_CST)
10658 warning (0, "%qE attribute allows only an integer constant argument",
10659 name);
10660 *no_add_attrs = true;
10663 return NULL_TREE;
10666 /* Return nonzero if the symbol is a secure function. */
10668 bool
10669 arc_is_secure_call_p (rtx pat)
10671 tree attrs;
10672 tree decl = SYMBOL_REF_DECL (pat);
10674 if (!decl)
10675 return false;
10677 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10678 if (lookup_attribute ("secure_call", attrs))
10679 return true;
10681 return false;
10684 /* Handle "uncached" qualifier. */
10686 static tree
10687 arc_handle_uncached_attribute (tree *node,
10688 tree name, tree args,
10689 int flags ATTRIBUTE_UNUSED,
10690 bool *no_add_attrs)
10692 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
10694 error ("%qE attribute only applies to types",
10695 name);
10696 *no_add_attrs = true;
10698 else if (args)
10700 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
10702 return NULL_TREE;
10705 /* Return TRUE if PAT is a memory addressing an uncached data. */
10707 bool
10708 arc_is_uncached_mem_p (rtx pat)
10710 tree attrs = NULL_TREE;
10711 tree addr;
10713 if (!MEM_P (pat))
10714 return false;
10716 /* Get the memory attributes. */
10717 addr = MEM_EXPR (pat);
10718 if (!addr)
10719 return false;
10721 /* Get the attributes. */
10722 if (TREE_CODE (addr) == MEM_REF)
10724 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10725 if (lookup_attribute ("uncached", attrs))
10726 return true;
10728 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10729 if (lookup_attribute ("uncached", attrs))
10730 return true;
10733 /* For COMPONENT_REF, use the FIELD_DECL from tree operand 1. */
10734 if (TREE_CODE (addr) == COMPONENT_REF)
10736 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10737 if (lookup_attribute ("uncached", attrs))
10738 return true;
10740 return false;
10743 /* Handle aux attribute. The auxiliary registers are addressed using
10744 special instructions lr and sr. The attribute 'aux' indicates if a
10745 variable refers to the aux-regs and what is the register number
10746 desired. */
10748 static tree
10749 arc_handle_aux_attribute (tree *node,
10750 tree name, tree args, int,
10751 bool *no_add_attrs)
10753 /* Isn't it better to use address spaces for the aux-regs? */
10754 if (DECL_P (*node))
10756 if (TREE_CODE (*node) != VAR_DECL)
10758 error ("%qE attribute only applies to variables", name);
10759 *no_add_attrs = true;
10761 else if (args)
10763 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10764 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10765 tree arg = TREE_VALUE (args);
10766 if (TREE_CODE (arg) != INTEGER_CST)
10768 warning (OPT_Wattributes, "%qE attribute allows only an integer "
10769 "constant argument", name);
10770 *no_add_attrs = true;
10772 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10775 if (TREE_CODE (*node) == VAR_DECL)
10777 tree fntype = TREE_TYPE (*node);
10778 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
10780 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
10781 TYPE_ATTRIBUTES (fntype));
10782 TYPE_ATTRIBUTES (fntype) = attrs;
10786 return NULL_TREE;
10789 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
10790 anchors for small data: the GP register acts as an anchor in that
10791 case. We also don't want to use them for PC-relative accesses,
10792 where the PC acts as an anchor. Prohibit also TLS symbols to use
10793 anchors. */
10795 static bool
10796 arc_use_anchors_for_symbol_p (const_rtx symbol)
10798 if (SYMBOL_REF_TLS_MODEL (symbol))
10799 return false;
10801 if (flag_pic)
10802 return false;
10804 if (SYMBOL_REF_SMALL_P (symbol))
10805 return false;
10807 return default_use_anchors_for_symbol_p (symbol);
10810 /* Return true if SUBST can't safely replace its equivalent during RA. */
10811 static bool
10812 arc_cannot_substitute_mem_equiv_p (rtx)
10814 /* If SUBST is mem[base+index], the address may not fit ISA,
10815 thus return true. */
10816 return true;
10819 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
10820 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
10822 #undef TARGET_CONSTANT_ALIGNMENT
10823 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
10825 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
10826 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
10828 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
10829 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
10831 struct gcc_target targetm = TARGET_INITIALIZER;
10833 #include "gt-arc.h"