go: update builtin function attributes
[official-gcc.git] / gcc / config / arc / arc.cc
blobbe4bd612a09218d736118d0732b1b2995c91e2b2
1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2025 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"
71 #include "targhooks.h"
72 #include "case-cfn-macros.h"
74 /* Which cpu we're compiling for (ARC600, ARC601, ARC700). */
75 static char arc_cpu_name[10] = "";
76 static const char *arc_cpu_string = arc_cpu_name;
78 typedef struct GTY (()) _arc_jli_section
80 const char *name;
81 struct _arc_jli_section *next;
82 } arc_jli_section;
84 static arc_jli_section *arc_jli_sections = NULL;
86 /* Track which regs are set fixed/call saved/call used from commnad line. */
87 HARD_REG_SET overrideregs;
89 /* Maximum size of a loop. */
90 #define ARC_MAX_LOOP_LENGTH 4095
92 /* Check if an rtx fits in the store instruction format. Loads can
93 handle any constant. */
94 #define RTX_OK_FOR_OFFSET_P(MODE, X) \
95 (GET_CODE (X) == CONST_INT \
96 && SMALL_INT_RANGE (INTVAL (X), (GET_MODE_SIZE (MODE) - 1) & (~0x03), \
97 (INTVAL (X) & (GET_MODE_SIZE (MODE) - 1) & 3 \
98 ? 0 \
99 : -(-GET_MODE_SIZE (MODE) | (~0x03)) >> 1)))
101 /* Array of valid operand punctuation characters. */
102 char arc_punct_chars[256];
104 /* Status of the IRQ_CTRL_AUX register. */
105 typedef struct irq_ctrl_saved_t
107 /* Last register number used by IRQ_CTRL_SAVED aux_reg. */
108 short irq_save_last_reg;
109 /* True if BLINK is automatically saved. */
110 bool irq_save_blink;
111 /* True if LPCOUNT is automatically saved. */
112 bool irq_save_lpcount;
113 } irq_ctrl_saved_t;
114 static irq_ctrl_saved_t irq_ctrl_saved;
116 #define ARC_AUTOBLINK_IRQ_P(FNTYPE) \
117 ((ARC_INTERRUPT_P (FNTYPE) \
118 && irq_ctrl_saved.irq_save_blink) \
119 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
120 && rgf_banked_register_count > 8))
122 #define ARC_AUTOFP_IRQ_P(FNTYPE) \
123 ((ARC_INTERRUPT_P (FNTYPE) \
124 && (irq_ctrl_saved.irq_save_last_reg > 26)) \
125 || (ARC_FAST_INTERRUPT_P (FNTYPE) \
126 && rgf_banked_register_count > 8))
128 #define ARC_AUTO_IRQ_P(FNTYPE) \
129 (ARC_INTERRUPT_P (FNTYPE) && !ARC_FAST_INTERRUPT_P (FNTYPE) \
130 && (irq_ctrl_saved.irq_save_blink \
131 || (irq_ctrl_saved.irq_save_last_reg >= 0)))
133 /* Number of registers in second bank for FIRQ support. */
134 static int rgf_banked_register_count;
136 /* Start enter/leave register range. */
137 #define ENTER_LEAVE_START_REG 13
139 /* End enter/leave register range. */
140 #define ENTER_LEAVE_END_REG 26
142 /* The maximum number of insns skipped which will be conditionalised if
143 possible. */
144 /* When optimizing for speed:
145 Let p be the probability that the potentially skipped insns need to
146 be executed, pn the cost of a correctly predicted non-taken branch,
147 mt the cost of a mis/non-predicted taken branch,
148 mn mispredicted non-taken, pt correctly predicted taken ;
149 costs expressed in numbers of instructions like the ones considered
150 skipping.
151 Unfortunately we don't have a measure of predictability - this
152 is linked to probability only in that in the no-eviction-scenario
153 there is a lower bound 1 - 2 * min (p, 1-p), and a somewhat larger
154 value that can be assumed *if* the distribution is perfectly random.
155 A predictability of 1 is perfectly plausible not matter what p is,
156 because the decision could be dependent on an invocation parameter
157 of the program.
158 For large p, we want MAX_INSNS_SKIPPED == pn/(1-p) + mt - pn
159 For small p, we want MAX_INSNS_SKIPPED == pt
161 When optimizing for size:
162 We want to skip insn unless we could use 16 opcodes for the
163 non-conditionalized insn to balance the branch length or more.
164 Performance can be tie-breaker. */
165 /* If the potentially-skipped insns are likely to be executed, we'll
166 generally save one non-taken branch
168 this to be no less than the 1/p */
169 #define MAX_INSNS_SKIPPED 3
171 /* ZOL control registers. */
172 #define AUX_LP_START 0x02
173 #define AUX_LP_END 0x03
175 /* FPX AUX registers. */
176 #define AUX_DPFP_START 0x301
178 /* ARC600 MULHI register. */
179 #define AUX_MULHI 0x12
181 static int get_arc_condition_code (rtx);
183 static tree arc_handle_interrupt_attribute (tree *, tree, tree, int, bool *);
184 static tree arc_handle_fndecl_attribute (tree *, tree, tree, int, bool *);
185 static tree arc_handle_jli_attribute (tree *, tree, tree, int, bool *);
186 static tree arc_handle_secure_attribute (tree *, tree, tree, int, bool *);
187 static tree arc_handle_uncached_attribute (tree *, tree, tree, int, bool *);
188 static tree arc_handle_aux_attribute (tree *, tree, tree, int, bool *);
190 static int arc_comp_type_attributes (const_tree, const_tree);
191 static void arc_file_start (void);
192 static void arc_internal_label (FILE *, const char *, unsigned long);
193 static void arc_output_mi_thunk (FILE *, tree, HOST_WIDE_INT, HOST_WIDE_INT,
194 tree);
195 static int arc_address_cost (rtx, machine_mode, addr_space_t, bool);
196 static void arc_encode_section_info (tree decl, rtx rtl, int first);
198 static void arc_init_builtins (void);
199 static rtx arc_expand_builtin (tree, rtx, rtx, machine_mode, int);
201 static int branch_dest (rtx);
203 static void arc_output_pic_addr_const (FILE *, rtx, int);
204 static bool arc_function_ok_for_sibcall (tree, tree);
205 static rtx arc_function_value (const_tree, const_tree, bool);
206 static void arc_reorg (void);
207 static bool arc_in_small_data_p (const_tree);
209 static void arc_init_reg_tables (void);
210 static bool arc_return_in_memory (const_tree, const_tree);
211 static bool arc_vector_mode_supported_p (machine_mode);
213 static bool arc_can_use_doloop_p (const widest_int &, const widest_int &,
214 unsigned int, bool);
215 static const char *arc_invalid_within_doloop (const rtx_insn *);
217 static void output_short_suffix (FILE *file);
219 static bool arc_frame_pointer_required (void);
221 static bool arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT,
222 unsigned int,
223 enum by_pieces_operation op,
224 bool);
226 /* Globally visible information about currently selected cpu. */
227 const arc_cpu_t *arc_selected_cpu;
229 /* Traditionally, we push saved registers first in the prologue,
230 then we allocate the rest of the frame - and reverse in the epilogue.
231 This has still its merits for ease of debugging, or saving code size
232 or even execution time if the stack frame is so large that some accesses
233 can't be encoded anymore with offsets in the instruction code when using
234 a different scheme.
235 Also, it would be a good starting point if we got instructions to help
236 with register save/restore.
238 However, often stack frames are small, and the pushing / popping has
239 some costs:
240 - the stack modification prevents a lot of scheduling.
241 - frame allocation / deallocation may need extra instructions.
242 - we need to place a memory barrier after frame allocation to avoid
243 the delay slot scheduler to reschedule a frame related info and
244 messing up with dwarf unwinding. The barrier before deallocation
245 is for flushing all pending sp operations.
247 Thus, for small frames, we'd like to use a different scheme:
248 - The frame is allocated in full with the first prologue instruction,
249 and deallocated in full with the last epilogue instruction.
250 Thus, the instructions in-between can be freely scheduled.
251 - If the function has no outgoing arguments on the stack, we can allocate
252 one register save slot at the top of the stack. This register can then
253 be saved simultaneously with frame allocation, and restored with
254 frame deallocation.
255 This register can be picked depending on scheduling considerations,
256 although same though should go into having some set of registers
257 to be potentially lingering after a call, and others to be available
258 immediately - i.e. in the absence of interprocedual optimization, we
259 can use an ABI-like convention for register allocation to reduce
260 stalls after function return. */
262 /* ARCompact stack frames look like:
264 Before call After call
265 high +-----------------------+ +-----------------------+
266 mem | reg parm save area | | reg parm save area |
267 | only created for | | only created for |
268 | variable arg fns | | variable arg fns |
269 AP +-----------------------+ +-----------------------+
270 | return addr register | | return addr register |
271 | (if required) | | (if required) |
272 +-----------------------+ +-----------------------+
273 | | | |
274 | reg save area | | reg save area |
275 | | | |
276 +-----------------------+ +-----------------------+
277 | frame pointer | | frame pointer |
278 | (if required) | | (if required) |
279 FP +-----------------------+ +-----------------------+
280 | | | |
281 | local/temp variables | | local/temp variables |
282 | | | |
283 +-----------------------+ +-----------------------+
284 | | | |
285 | arguments on stack | | arguments on stack |
286 | | | |
287 SP +-----------------------+ +-----------------------+
288 | reg parm save area |
289 | only created for |
290 | variable arg fns |
291 AP +-----------------------+
292 | return addr register |
293 | (if required) |
294 +-----------------------+
296 | reg save area |
298 +-----------------------+
299 | frame pointer |
300 | (if required) |
301 FP +-----------------------+
303 | local/temp variables |
305 +-----------------------+
307 | arguments on stack |
308 low | |
309 mem SP +-----------------------+
311 Notes:
312 1) The "reg parm save area" does not exist for non variable argument fns.
313 The "reg parm save area" can be eliminated completely if we created our
314 own va-arc.h, but that has tradeoffs as well (so it's not done). */
316 /* Structure to be filled in by arc_compute_frame_size with register
317 save masks, and offsets for the current function. */
318 struct GTY (()) arc_frame_info
320 unsigned int total_size; /* # bytes that the entire frame takes up. */
321 unsigned int extra_size; /* # bytes of extra stuff. */
322 unsigned int pretend_size; /* # bytes we push and pretend caller did. */
323 unsigned int args_size; /* # bytes that outgoing arguments take up. */
324 unsigned int reg_size; /* # bytes needed to store regs. */
325 unsigned int var_size; /* # bytes that variables take up. */
326 uint64_t gmask; /* Mask of saved gp registers. */
327 bool initialized; /* FALSE if frame size already calculated. */
328 short millicode_start_reg;
329 short millicode_end_reg;
330 bool save_return_addr;
333 /* GMASK bit length -1. */
334 #define GMASK_LEN 63
336 /* Defining data structures for per-function information. */
338 typedef struct GTY (()) machine_function
340 unsigned int fn_type;
341 struct arc_frame_info frame_info;
342 char arc_reorg_started;
343 char prescan_initialized;
344 } machine_function;
347 /* Given a symbol RTX (const (symb <+ const_int>), returns its
348 alignment. */
350 static int
351 get_symbol_alignment (rtx x)
353 tree decl = NULL_TREE;
354 int align = 0;
356 switch (GET_CODE (x))
358 case SYMBOL_REF:
359 decl = SYMBOL_REF_DECL (x);
360 break;
361 case CONST:
362 return get_symbol_alignment (XEXP (x, 0));
363 case PLUS:
364 gcc_assert (CONST_INT_P (XEXP (x, 1)));
365 return get_symbol_alignment (XEXP (x, 0));
366 default:
367 return 0;
370 if (decl)
371 align = DECL_ALIGN (decl);
372 align = align / BITS_PER_UNIT;
373 return align;
376 /* Return true if x is ok to be used as a small data address. */
378 static bool
379 legitimate_small_data_address_p (rtx x, machine_mode mode)
381 switch (GET_CODE (x))
383 case CONST:
384 return legitimate_small_data_address_p (XEXP (x, 0), mode);
385 case SYMBOL_REF:
386 return SYMBOL_REF_SMALL_P (x);
387 case PLUS:
389 bool p0 = (GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
390 && SYMBOL_REF_SMALL_P (XEXP (x, 0));
392 /* If no constant then we cannot do small data. */
393 if (!CONST_INT_P (XEXP (x, 1)))
394 return false;
396 /* Small data relocs works with scalled addresses, check if
397 the immediate fits the requirements. */
398 switch (GET_MODE_SIZE (mode))
400 case 1:
401 return p0;
402 case 2:
403 return p0 && ((INTVAL (XEXP (x, 1)) & 0x1) == 0);
404 case 4:
405 case 8:
406 return p0 && ((INTVAL (XEXP (x, 1)) & 0x3) == 0);
407 default:
408 return false;
411 default:
412 return false;
416 /* TRUE if op is an scaled address. */
417 static bool
418 legitimate_scaled_address_p (machine_mode mode, rtx op, bool strict)
420 if (GET_CODE (op) != PLUS)
421 return false;
423 if (GET_CODE (XEXP (op, 0)) != MULT)
424 return false;
426 /* Check multiplication operands. */
427 if (!RTX_OK_FOR_INDEX_P (XEXP (XEXP (op, 0), 0), strict))
428 return false;
430 if (!CONST_INT_P (XEXP (XEXP (op, 0), 1)))
431 return false;
433 switch (GET_MODE_SIZE (mode))
435 case 2:
436 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 2)
437 return false;
438 break;
439 case 8:
440 if (!TARGET_LL64)
441 return false;
442 /* Fall through. */
443 case 4:
444 if (INTVAL (XEXP (XEXP (op, 0), 1)) != 4)
445 return false;
446 /* Fall through. */
447 default:
448 return false;
451 /* Check the base. */
452 if (RTX_OK_FOR_BASE_P (XEXP (op, 1), (strict)))
453 return true;
455 if (flag_pic)
457 if (CONST_INT_P (XEXP (op, 1)))
458 return true;
459 return false;
462 /* Scalled addresses for sdata is done other places. */
463 if (legitimate_small_data_address_p (op, mode))
464 return false;
466 if (CONSTANT_P (XEXP (op, 1)))
467 return true;
469 return false;
472 /* Check for constructions like REG + OFFS, where OFFS can be a
473 register, an immediate or an long immediate. */
475 static bool
476 legitimate_offset_address_p (machine_mode mode, rtx x, bool index, bool strict)
478 if (GET_CODE (x) != PLUS)
479 return false;
481 if (!RTX_OK_FOR_BASE_P (XEXP (x, 0), (strict)))
482 return false;
484 /* Check for: [Rx + small offset] or [Rx + Ry]. */
485 if (((index && RTX_OK_FOR_INDEX_P (XEXP (x, 1), (strict))
486 && GET_MODE_SIZE ((mode)) <= 4)
487 || RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1))))
488 return true;
490 /* Check for [Rx + symbol]. */
491 if (!flag_pic
492 && (GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
493 /* Avoid this type of address for double or larger modes. */
494 && (GET_MODE_SIZE (mode) <= 4)
495 /* Avoid small data which ends in something like GP +
496 symb@sda. */
497 && (!SYMBOL_REF_SMALL_P (XEXP (x, 1))))
498 return true;
500 return false;
503 /* Implements target hook vector_mode_supported_p. */
505 static bool
506 arc_vector_mode_supported_p (machine_mode mode)
508 switch (mode)
510 case E_V2HImode:
511 return TARGET_PLUS_DMPY;
512 case E_V4HImode:
513 case E_V2SImode:
514 return TARGET_PLUS_QMACW;
515 case E_V4SImode:
516 case E_V8HImode:
517 return TARGET_SIMD_SET;
519 default:
520 return false;
524 /* Implements target hook TARGET_VECTORIZE_PREFERRED_SIMD_MODE. */
526 static machine_mode
527 arc_preferred_simd_mode (scalar_mode mode)
529 switch (mode)
531 case E_HImode:
532 return TARGET_PLUS_QMACW ? V4HImode : V2HImode;
533 case E_SImode:
534 return V2SImode;
536 default:
537 return word_mode;
541 /* Implements target hook
542 TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES. */
544 static unsigned int
545 arc_autovectorize_vector_modes (vector_modes *modes, bool)
547 if (TARGET_PLUS_QMACW)
549 modes->quick_push (V4HImode);
550 modes->quick_push (V2HImode);
552 return 0;
556 /* Implements target hook TARGET_SCHED_ISSUE_RATE. */
557 static int
558 arc_sched_issue_rate (void)
560 switch (arc_tune)
562 case ARC_TUNE_ARCHS4X:
563 case ARC_TUNE_ARCHS4XD:
564 return 3;
565 default:
566 break;
568 return 1;
571 /* TARGET_PRESERVE_RELOAD_P is still awaiting patch re-evaluation / review. */
572 static bool arc_preserve_reload_p (rtx in) ATTRIBUTE_UNUSED;
573 static rtx arc_delegitimize_address (rtx);
574 static bool arc_can_follow_jump (const rtx_insn *follower,
575 const rtx_insn *followee);
577 static rtx frame_insn (rtx);
578 static void arc_function_arg_advance (cumulative_args_t,
579 const function_arg_info &);
580 static rtx arc_legitimize_address_0 (rtx, rtx, machine_mode mode);
582 /* initialize the GCC target structure. */
583 #undef TARGET_COMP_TYPE_ATTRIBUTES
584 #define TARGET_COMP_TYPE_ATTRIBUTES arc_comp_type_attributes
585 #undef TARGET_ASM_FILE_START
586 #define TARGET_ASM_FILE_START arc_file_start
587 #undef TARGET_ATTRIBUTE_TABLE
588 #define TARGET_ATTRIBUTE_TABLE arc_attribute_table
589 #undef TARGET_ASM_INTERNAL_LABEL
590 #define TARGET_ASM_INTERNAL_LABEL arc_internal_label
591 #undef TARGET_RTX_COSTS
592 #define TARGET_RTX_COSTS arc_rtx_costs
593 #undef TARGET_ADDRESS_COST
594 #define TARGET_ADDRESS_COST arc_address_cost
596 #undef TARGET_ENCODE_SECTION_INFO
597 #define TARGET_ENCODE_SECTION_INFO arc_encode_section_info
599 #undef TARGET_CANNOT_FORCE_CONST_MEM
600 #define TARGET_CANNOT_FORCE_CONST_MEM arc_cannot_force_const_mem
602 #undef TARGET_INIT_BUILTINS
603 #define TARGET_INIT_BUILTINS arc_init_builtins
605 #undef TARGET_EXPAND_BUILTIN
606 #define TARGET_EXPAND_BUILTIN arc_expand_builtin
608 #undef TARGET_FOLD_BUILTIN
609 #define TARGET_FOLD_BUILTIN arc_fold_builtin
611 #undef TARGET_BUILTIN_DECL
612 #define TARGET_BUILTIN_DECL arc_builtin_decl
614 #undef TARGET_ASM_OUTPUT_MI_THUNK
615 #define TARGET_ASM_OUTPUT_MI_THUNK arc_output_mi_thunk
617 #undef TARGET_ASM_CAN_OUTPUT_MI_THUNK
618 #define TARGET_ASM_CAN_OUTPUT_MI_THUNK hook_bool_const_tree_hwi_hwi_const_tree_true
620 #undef TARGET_FUNCTION_OK_FOR_SIBCALL
621 #define TARGET_FUNCTION_OK_FOR_SIBCALL arc_function_ok_for_sibcall
623 #undef TARGET_MACHINE_DEPENDENT_REORG
624 #define TARGET_MACHINE_DEPENDENT_REORG arc_reorg
626 #undef TARGET_IN_SMALL_DATA_P
627 #define TARGET_IN_SMALL_DATA_P arc_in_small_data_p
629 #undef TARGET_PROMOTE_FUNCTION_MODE
630 #define TARGET_PROMOTE_FUNCTION_MODE \
631 default_promote_function_mode_always_promote
633 #undef TARGET_PROMOTE_PROTOTYPES
634 #define TARGET_PROMOTE_PROTOTYPES hook_bool_const_tree_true
636 #undef TARGET_RETURN_IN_MEMORY
637 #define TARGET_RETURN_IN_MEMORY arc_return_in_memory
638 #undef TARGET_PASS_BY_REFERENCE
639 #define TARGET_PASS_BY_REFERENCE arc_pass_by_reference
641 #undef TARGET_SETUP_INCOMING_VARARGS
642 #define TARGET_SETUP_INCOMING_VARARGS arc_setup_incoming_varargs
644 #undef TARGET_ARG_PARTIAL_BYTES
645 #define TARGET_ARG_PARTIAL_BYTES arc_arg_partial_bytes
647 #undef TARGET_MUST_PASS_IN_STACK
648 #define TARGET_MUST_PASS_IN_STACK must_pass_in_stack_var_size
650 #undef TARGET_FUNCTION_VALUE
651 #define TARGET_FUNCTION_VALUE arc_function_value
653 #undef TARGET_SCHED_ADJUST_PRIORITY
654 #define TARGET_SCHED_ADJUST_PRIORITY arc_sched_adjust_priority
656 #undef TARGET_SCHED_ISSUE_RATE
657 #define TARGET_SCHED_ISSUE_RATE arc_sched_issue_rate
659 #undef TARGET_VECTOR_MODE_SUPPORTED_P
660 #define TARGET_VECTOR_MODE_SUPPORTED_P arc_vector_mode_supported_p
662 #undef TARGET_VECTORIZE_PREFERRED_SIMD_MODE
663 #define TARGET_VECTORIZE_PREFERRED_SIMD_MODE arc_preferred_simd_mode
665 #undef TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES
666 #define TARGET_VECTORIZE_AUTOVECTORIZE_VECTOR_MODES arc_autovectorize_vector_modes
668 #undef TARGET_CAN_USE_DOLOOP_P
669 #define TARGET_CAN_USE_DOLOOP_P arc_can_use_doloop_p
671 #undef TARGET_INVALID_WITHIN_DOLOOP
672 #define TARGET_INVALID_WITHIN_DOLOOP arc_invalid_within_doloop
674 #undef TARGET_PRESERVE_RELOAD_P
675 #define TARGET_PRESERVE_RELOAD_P arc_preserve_reload_p
677 #undef TARGET_CAN_FOLLOW_JUMP
678 #define TARGET_CAN_FOLLOW_JUMP arc_can_follow_jump
680 #undef TARGET_DELEGITIMIZE_ADDRESS
681 #define TARGET_DELEGITIMIZE_ADDRESS arc_delegitimize_address
683 #undef TARGET_USE_BY_PIECES_INFRASTRUCTURE_P
684 #define TARGET_USE_BY_PIECES_INFRASTRUCTURE_P \
685 arc_use_by_pieces_infrastructure_p
687 /* Usually, we will be able to scale anchor offsets.
688 When this fails, we want LEGITIMIZE_ADDRESS to kick in. */
689 #undef TARGET_MIN_ANCHOR_OFFSET
690 #define TARGET_MIN_ANCHOR_OFFSET (-1024)
691 #undef TARGET_MAX_ANCHOR_OFFSET
692 #define TARGET_MAX_ANCHOR_OFFSET (1020)
694 #undef TARGET_SECONDARY_RELOAD
695 #define TARGET_SECONDARY_RELOAD arc_secondary_reload
697 #define TARGET_OPTION_OVERRIDE arc_override_options
699 #define TARGET_CONDITIONAL_REGISTER_USAGE arc_conditional_register_usage
701 #define TARGET_TRAMPOLINE_INIT arc_initialize_trampoline
703 #define TARGET_CAN_ELIMINATE arc_can_eliminate
705 #define TARGET_FRAME_POINTER_REQUIRED arc_frame_pointer_required
707 #define TARGET_FUNCTION_ARG arc_function_arg
709 #define TARGET_FUNCTION_ARG_ADVANCE arc_function_arg_advance
711 #define TARGET_LEGITIMATE_CONSTANT_P arc_legitimate_constant_p
713 #define TARGET_LEGITIMATE_ADDRESS_P arc_legitimate_address_p
715 #define TARGET_MODE_DEPENDENT_ADDRESS_P arc_mode_dependent_address_p
717 #define TARGET_LEGITIMIZE_ADDRESS arc_legitimize_address
719 #undef TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P
720 #define TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P \
721 arc_no_speculation_in_delay_slots_p
723 #undef TARGET_LRA_P
724 #define TARGET_LRA_P hook_bool_void_true
725 #define TARGET_REGISTER_PRIORITY arc_register_priority
726 /* Stores with scaled offsets have different displacement ranges. */
727 #define TARGET_DIFFERENT_ADDR_DISPLACEMENT_P hook_bool_void_true
728 #define TARGET_SPILL_CLASS arc_spill_class
730 #undef TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS
731 #define TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS arc_allocate_stack_slots_for_args
733 #undef TARGET_WARN_FUNC_RETURN
734 #define TARGET_WARN_FUNC_RETURN arc_warn_func_return
736 #include "target-def.h"
738 TARGET_GNU_ATTRIBUTES (arc_attribute_table,
740 /* { name, min_len, max_len, decl_req, type_req, fn_type_req,
741 affects_type_identity, handler, exclude } */
742 { "interrupt", 1, 1, true, false, false, true,
743 arc_handle_interrupt_attribute, NULL },
744 /* Function calls made to this symbol must be done indirectly, because
745 it may lie outside of the 21/25 bit addressing range of a normal function
746 call. */
747 { "long_call", 0, 0, false, true, true, false, NULL, NULL },
748 /* Whereas these functions are always known to reside within the 25 bit
749 addressing range of unconditionalized bl. */
750 { "medium_call", 0, 0, false, true, true, false, NULL, NULL },
751 /* And these functions are always known to reside within the 21 bit
752 addressing range of blcc. */
753 { "short_call", 0, 0, false, true, true, false, NULL, NULL },
754 /* Function which are not having the prologue and epilogue generated
755 by the compiler. */
756 { "naked", 0, 0, true, false, false, false, arc_handle_fndecl_attribute,
757 NULL },
758 /* Functions calls made using jli instruction. The pointer in JLI
759 table is found latter. */
760 { "jli_always", 0, 0, false, true, true, false, NULL, NULL },
761 /* Functions calls made using jli instruction. The pointer in JLI
762 table is given as input parameter. */
763 { "jli_fixed", 1, 1, false, true, true, false, arc_handle_jli_attribute,
764 NULL },
765 /* Call a function using secure-mode. */
766 { "secure_call", 1, 1, false, true, true, false, arc_handle_secure_attribute,
767 NULL },
768 /* Bypass caches using .di flag. */
769 { "uncached", 0, 0, false, true, false, false, arc_handle_uncached_attribute,
770 NULL },
771 { "aux", 0, 1, true, false, false, false, arc_handle_aux_attribute, NULL }
774 #undef TARGET_ASM_ALIGNED_HI_OP
775 #define TARGET_ASM_ALIGNED_HI_OP "\t.hword\t"
776 #undef TARGET_ASM_ALIGNED_SI_OP
777 #define TARGET_ASM_ALIGNED_SI_OP "\t.word\t"
779 #ifdef HAVE_AS_TLS
780 #undef TARGET_HAVE_TLS
781 #define TARGET_HAVE_TLS HAVE_AS_TLS
782 #endif
784 #undef TARGET_DWARF_REGISTER_SPAN
785 #define TARGET_DWARF_REGISTER_SPAN arc_dwarf_register_span
787 #undef TARGET_HARD_REGNO_NREGS
788 #define TARGET_HARD_REGNO_NREGS arc_hard_regno_nregs
789 #undef TARGET_HARD_REGNO_MODE_OK
790 #define TARGET_HARD_REGNO_MODE_OK arc_hard_regno_mode_ok
792 #undef TARGET_MODES_TIEABLE_P
793 #define TARGET_MODES_TIEABLE_P arc_modes_tieable_p
795 /* Try to keep the (mov:DF _, reg) as early as possible so
796 that the d<add/sub/mul>h-lr insns appear together and can
797 use the peephole2 pattern. */
799 static int
800 arc_sched_adjust_priority (rtx_insn *insn, int priority)
802 rtx set = single_set (insn);
803 if (set
804 && GET_MODE (SET_SRC(set)) == DFmode
805 && GET_CODE (SET_SRC(set)) == REG)
807 /* Incrementing priority by 20 (empirically derived). */
808 return priority + 20;
811 return priority;
814 /* For ARC base register + offset addressing, the validity of the
815 address is mode-dependent for most of the offset range, as the
816 offset can be scaled by the access size.
817 We don't expose these as mode-dependent addresses in the
818 mode_dependent_address_p target hook, because that would disable
819 lots of optimizations, and most uses of these addresses are for 32
820 or 64 bit accesses anyways, which are fine.
821 However, that leaves some addresses for 8 / 16 bit values not
822 properly reloaded by the generic code, which is why we have to
823 schedule secondary reloads for these. */
825 static reg_class_t
826 arc_secondary_reload (bool in_p,
827 rtx x,
828 reg_class_t cl,
829 machine_mode mode,
830 secondary_reload_info *sri)
832 enum rtx_code code = GET_CODE (x);
834 if (cl == DOUBLE_REGS)
835 return GENERAL_REGS;
837 /* If we have a subreg (reg), where reg is a pseudo (that will end in
838 a memory location), then we may need a scratch register to handle
839 the fp/sp+largeoffset address. */
840 if (code == SUBREG)
842 rtx addr = NULL_RTX;
843 x = SUBREG_REG (x);
845 if (REG_P (x))
847 int regno = REGNO (x);
848 if (regno >= FIRST_PSEUDO_REGISTER)
849 regno = reg_renumber[regno];
851 if (regno != -1)
852 return NO_REGS;
854 /* It is a pseudo that ends in a stack location. This
855 procedure only works with the old reload step. */
856 if (!lra_in_progress && reg_equiv_mem (REGNO (x)))
858 /* Get the equivalent address and check the range of the
859 offset. */
860 rtx mem = reg_equiv_mem (REGNO (x));
861 addr = find_replacement (&XEXP (mem, 0));
864 else
866 gcc_assert (MEM_P (x));
867 addr = XEXP (x, 0);
868 addr = simplify_rtx (addr);
870 if (addr && GET_CODE (addr) == PLUS
871 && CONST_INT_P (XEXP (addr, 1))
872 && (!RTX_OK_FOR_OFFSET_P (mode, XEXP (addr, 1))))
874 switch (mode)
876 case E_QImode:
877 sri->icode =
878 in_p ? CODE_FOR_reload_qi_load : CODE_FOR_reload_qi_store;
879 break;
880 case E_HImode:
881 sri->icode =
882 in_p ? CODE_FOR_reload_hi_load : CODE_FOR_reload_hi_store;
883 break;
884 default:
885 break;
889 return NO_REGS;
892 /* Convert reloads using offsets that are too large to use indirect
893 addressing. */
895 void
896 arc_secondary_reload_conv (rtx reg, rtx mem, rtx scratch, bool store_p)
898 rtx addr;
900 gcc_assert (GET_CODE (mem) == MEM);
901 addr = XEXP (mem, 0);
903 /* Large offset: use a move. FIXME: ld ops accepts limms as
904 offsets. Hence, the following move insn is not required. */
905 emit_move_insn (scratch, addr);
906 mem = replace_equiv_address_nv (mem, scratch);
908 /* Now create the move. */
909 if (store_p)
910 emit_insn (gen_rtx_SET (mem, reg));
911 else
912 emit_insn (gen_rtx_SET (reg, mem));
914 return;
917 static unsigned arc_predicate_delay_insns (void);
919 namespace {
921 const pass_data pass_data_arc_predicate_delay_insns =
923 RTL_PASS,
924 "arc_predicate_delay_insns", /* name */
925 OPTGROUP_NONE, /* optinfo_flags */
926 TV_IFCVT2, /* tv_id */
927 0, /* properties_required */
928 0, /* properties_provided */
929 0, /* properties_destroyed */
930 0, /* todo_flags_start */
931 TODO_df_finish /* todo_flags_finish */
934 class pass_arc_predicate_delay_insns : public rtl_opt_pass
936 public:
937 pass_arc_predicate_delay_insns(gcc::context *ctxt)
938 : rtl_opt_pass(pass_data_arc_predicate_delay_insns, ctxt)
941 /* opt_pass methods: */
942 virtual unsigned int execute (function *)
944 return arc_predicate_delay_insns ();
946 virtual bool gate (function *)
948 return flag_delayed_branch;
952 } // anon namespace
954 rtl_opt_pass *
955 make_pass_arc_predicate_delay_insns (gcc::context *ctxt)
957 return new pass_arc_predicate_delay_insns (ctxt);
960 /* Called by OVERRIDE_OPTIONS to initialize various things. */
962 static void
963 arc_init (void)
965 if (TARGET_V2)
967 /* I have the multiplier, then use it*/
968 if (TARGET_MPYW || TARGET_MULTI)
969 arc_multcost = COSTS_N_INSNS (1);
971 /* Note: arc_multcost is only used in rtx_cost if speed is true. */
972 if (arc_multcost < 0)
973 switch (arc_tune)
975 case ARC_TUNE_ARC700_4_2_STD:
976 /* latency 7;
977 max throughput (1 multiply + 4 other insns) / 5 cycles. */
978 arc_multcost = COSTS_N_INSNS (4);
979 if (TARGET_NOMPY_SET)
980 arc_multcost = COSTS_N_INSNS (30);
981 break;
982 case ARC_TUNE_ARC700_4_2_XMAC:
983 /* latency 5;
984 max throughput (1 multiply + 2 other insns) / 3 cycles. */
985 arc_multcost = COSTS_N_INSNS (3);
986 if (TARGET_NOMPY_SET)
987 arc_multcost = COSTS_N_INSNS (30);
988 break;
989 case ARC_TUNE_ARC600:
990 if (TARGET_MUL64_SET)
992 arc_multcost = COSTS_N_INSNS (4);
993 break;
995 /* Fall through. */
996 default:
997 arc_multcost = COSTS_N_INSNS (30);
998 break;
1001 /* MPY instructions valid only for ARC700 or ARCv2. */
1002 if (TARGET_NOMPY_SET && TARGET_ARC600_FAMILY)
1003 error ("%<-mno-mpy%> supported only for ARC700 or ARCv2");
1005 if (!TARGET_DPFP && TARGET_DPFP_DISABLE_LRSR)
1006 error ("%<-mno-dpfp-lrsr%> supported only with %<-mdpfp%>");
1008 /* FPX-1. No fast and compact together. */
1009 if ((TARGET_DPFP_FAST_SET && TARGET_DPFP_COMPACT_SET)
1010 || (TARGET_SPFP_FAST_SET && TARGET_SPFP_COMPACT_SET))
1011 error ("FPX fast and compact options cannot be specified together");
1013 /* FPX-2. No fast-spfp for arc600 or arc601. */
1014 if (TARGET_SPFP_FAST_SET && TARGET_ARC600_FAMILY)
1015 error ("%<-mspfp_fast%> not available on ARC600 or ARC601");
1017 /* FPX-4. No FPX extensions mixed with FPU extensions. */
1018 if ((TARGET_DPFP_FAST_SET || TARGET_DPFP_COMPACT_SET || TARGET_SPFP)
1019 && TARGET_HARD_FLOAT)
1020 error ("no FPX/FPU mixing allowed");
1022 /* Warn for unimplemented PIC in pre-ARC700 cores, and disable flag_pic. */
1023 if (flag_pic && TARGET_ARC600_FAMILY)
1025 warning (0, "PIC is not supported for %qs",
1026 arc_cpu_string);
1027 flag_pic = 0;
1030 arc_init_reg_tables ();
1032 /* Initialize array for PRINT_OPERAND_PUNCT_VALID_P. */
1033 memset (arc_punct_chars, 0, sizeof (arc_punct_chars));
1034 arc_punct_chars['*'] = 1;
1035 arc_punct_chars['?'] = 1;
1036 arc_punct_chars['!'] = 1;
1037 arc_punct_chars['+'] = 1;
1038 arc_punct_chars['_'] = 1;
1041 /* Parse -mirq-ctrl-saved=RegisterRange, blink, lp_copunt. The
1042 register range is specified as two registers separated by a dash.
1043 It always starts with r0, and its upper limit is fp register.
1044 blink and lp_count registers are optional. */
1046 static void
1047 irq_range (const char *cstr)
1049 int i, first, last, blink, lpcount, xreg;
1050 char *str, *dash, *comma;
1052 i = strlen (cstr);
1053 str = (char *) alloca (i + 1);
1054 memcpy (str, cstr, i + 1);
1055 blink = -1;
1056 lpcount = -1;
1058 dash = strchr (str, '-');
1059 if (!dash)
1061 warning (OPT_mirq_ctrl_saved_, "missing dash");
1062 return;
1064 *dash = '\0';
1066 comma = strchr (dash + 1, ',');
1067 if (comma)
1068 *comma = '\0';
1070 first = decode_reg_name (str);
1071 if (first != 0)
1073 warning (OPT_mirq_ctrl_saved_, "first register must be R0");
1074 return;
1077 /* At this moment we do not have the register names initialized
1078 accordingly. */
1079 if (!strcmp (dash + 1, "ilink"))
1080 last = 29;
1081 else
1082 last = decode_reg_name (dash + 1);
1084 if (last < 0)
1086 warning (OPT_mirq_ctrl_saved_, "unknown register name: %s", dash + 1);
1087 return;
1090 if (!(last & 0x01))
1092 warning (OPT_mirq_ctrl_saved_,
1093 "last register name %s must be an odd register", dash + 1);
1094 return;
1097 *dash = '-';
1099 if (first > last)
1101 warning (OPT_mirq_ctrl_saved_,
1102 "%s-%s is an empty range", str, dash + 1);
1103 return;
1106 while (comma)
1108 *comma = ',';
1109 str = comma + 1;
1111 comma = strchr (str, ',');
1112 if (comma)
1113 *comma = '\0';
1115 xreg = decode_reg_name (str);
1116 switch (xreg)
1118 case 31:
1119 blink = 31;
1120 break;
1122 case 60:
1123 lpcount = 60;
1124 break;
1126 default:
1127 warning (OPT_mirq_ctrl_saved_,
1128 "unknown register name: %s", str);
1129 return;
1133 irq_ctrl_saved.irq_save_last_reg = last;
1134 irq_ctrl_saved.irq_save_blink = (blink == 31) || (last == 31);
1135 irq_ctrl_saved.irq_save_lpcount = (lpcount == 60);
1138 /* Parse -mrgf-banked-regs=NUM option string. Valid values for NUM are 4,
1139 8, 16, or 32. */
1141 static void
1142 parse_mrgf_banked_regs_option (const char *arg)
1144 long int val;
1145 char *end_ptr;
1147 errno = 0;
1148 val = strtol (arg, &end_ptr, 10);
1149 if (errno != 0 || *arg == '\0' || *end_ptr != '\0'
1150 || (val != 0 && val != 4 && val != 8 && val != 16 && val != 32))
1152 error ("invalid number in %<-mrgf-banked-regs=%s%> "
1153 "valid values are 0, 4, 8, 16, or 32", arg);
1154 return;
1156 rgf_banked_register_count = (int) val;
1159 /* Check ARC options, generate derived target attributes. */
1161 static void
1162 arc_override_options (void)
1164 unsigned int i;
1165 cl_deferred_option *opt;
1166 vec<cl_deferred_option> *vopt
1167 = (vec<cl_deferred_option> *) arc_deferred_options;
1169 if (arc_cpu == PROCESSOR_NONE)
1170 arc_cpu = TARGET_CPU_DEFAULT;
1172 /* Set the default cpu options. */
1173 arc_selected_cpu = &arc_cpu_types[(int) arc_cpu];
1175 /* Set the architectures. */
1176 switch (arc_selected_cpu->arch_info->arch_id)
1178 case BASE_ARCH_em:
1179 arc_cpu_string = "EM";
1180 break;
1181 case BASE_ARCH_hs:
1182 arc_cpu_string = "HS";
1183 break;
1184 case BASE_ARCH_700:
1185 if (arc_selected_cpu->processor == PROCESSOR_nps400)
1186 arc_cpu_string = "NPS400";
1187 else
1188 arc_cpu_string = "ARC700";
1189 break;
1190 case BASE_ARCH_6xx:
1191 arc_cpu_string = "ARC600";
1192 break;
1193 default:
1194 gcc_unreachable ();
1197 irq_ctrl_saved.irq_save_last_reg = -1;
1198 irq_ctrl_saved.irq_save_blink = false;
1199 irq_ctrl_saved.irq_save_lpcount = false;
1201 rgf_banked_register_count = 0;
1203 /* Handle the deferred options. */
1204 if (vopt)
1205 FOR_EACH_VEC_ELT (*vopt, i, opt)
1207 switch (opt->opt_index)
1209 case OPT_mirq_ctrl_saved_:
1210 if (TARGET_V2)
1211 irq_range (opt->arg);
1212 else
1213 warning (OPT_mirq_ctrl_saved_,
1214 "option %<-mirq-ctrl-saved%> valid only "
1215 "for ARC v2 processors");
1216 break;
1218 case OPT_mrgf_banked_regs_:
1219 if (TARGET_V2)
1220 parse_mrgf_banked_regs_option (opt->arg);
1221 else
1222 warning (OPT_mrgf_banked_regs_,
1223 "option %<-mrgf-banked-regs%> valid only for "
1224 "ARC v2 processors");
1225 break;
1227 default:
1228 gcc_unreachable();
1232 CLEAR_HARD_REG_SET (overrideregs);
1233 if (common_deferred_options)
1235 vec<cl_deferred_option> v =
1236 *((vec<cl_deferred_option> *) common_deferred_options);
1237 int reg, nregs, j;
1239 FOR_EACH_VEC_ELT (v, i, opt)
1241 switch (opt->opt_index)
1243 case OPT_ffixed_:
1244 case OPT_fcall_used_:
1245 case OPT_fcall_saved_:
1246 if ((reg = decode_reg_name_and_count (opt->arg, &nregs)) >= 0)
1247 for (j = reg; j < reg + nregs; j++)
1248 SET_HARD_REG_BIT (overrideregs, j);
1249 break;
1250 default:
1251 break;
1256 /* Check options against architecture options. Throw an error if
1257 option is not allowed. Extra, check options against default
1258 architecture/cpu flags and throw an warning if we find a
1259 mismatch. */
1260 /* TRANSLATORS: the DOC/DOC0/DOC1 are strings which shouldn't be
1261 translated. They are like keywords which one can relate with the
1262 architectural choices taken for an ARC CPU implementation. */
1263 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1264 do { \
1265 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1266 && (VAR == VAL)) \
1267 error ("option %<%s=%s%> is not available for %qs CPU", \
1268 DOC0, DOC1, arc_selected_cpu->name); \
1269 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1270 && (VAR != DEFAULT_##VAR) \
1271 && (VAR != VAL)) \
1272 warning (0, "option %qs is ignored, the default value %qs" \
1273 " is considered for %qs CPU", DOC0, DOC1, \
1274 arc_selected_cpu->name); \
1275 } while (0);
1276 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1277 do { \
1278 if ((!(arc_selected_cpu->arch_info->flags & CODE)) \
1279 && (target_flags & MASK)) \
1280 error ("option %qs is not available for %qs CPU", \
1281 DOC, arc_selected_cpu->name); \
1282 if ((arc_selected_cpu->arch_info->dflags & CODE) \
1283 && (target_flags_explicit & MASK) \
1284 && (!(target_flags & MASK))) \
1285 warning (0, "unset option %qs is ignored, it is always" \
1286 " enabled for %qs CPU", DOC, \
1287 arc_selected_cpu->name); \
1288 } while (0);
1290 #include "arc-options.def"
1292 #undef ARC_OPTX
1293 #undef ARC_OPT
1295 /* Set cpu flags accordingly to architecture/selected cpu. The cpu
1296 specific flags are set in arc-common.cc. The architecture forces
1297 the default hardware configurations in, regardless what command
1298 line options are saying. The CPU optional hw options can be
1299 turned on or off. */
1300 #define ARC_OPT(NAME, CODE, MASK, DOC) \
1301 do { \
1302 if ((arc_selected_cpu->flags & CODE) \
1303 && ((target_flags_explicit & MASK) == 0)) \
1304 target_flags |= MASK; \
1305 if (arc_selected_cpu->arch_info->dflags & CODE) \
1306 target_flags |= MASK; \
1307 } while (0);
1308 #define ARC_OPTX(NAME, CODE, VAR, VAL, DOC0, DOC1) \
1309 do { \
1310 if ((arc_selected_cpu->flags & CODE) \
1311 && (VAR == DEFAULT_##VAR)) \
1312 VAR = VAL; \
1313 if (arc_selected_cpu->arch_info->dflags & CODE) \
1314 VAR = VAL; \
1315 } while (0);
1317 #include "arc-options.def"
1319 #undef ARC_OPTX
1320 #undef ARC_OPT
1322 /* Set extras. */
1323 switch (arc_selected_cpu->extra)
1325 case HAS_LPCOUNT_16:
1326 arc_lpcwidth = 16;
1327 break;
1328 default:
1329 break;
1332 /* Set Tune option. */
1333 if (arc_tune == ARC_TUNE_NONE)
1334 arc_tune = (enum arc_tune_attr) arc_selected_cpu->tune;
1336 if (arc_size_opt_level == 3)
1337 optimize_size = 1;
1339 if (TARGET_V2 && optimize_size && (ATTRIBUTE_PCS == 2))
1340 TARGET_CODE_DENSITY_FRAME = 1;
1342 if (flag_pic)
1343 target_flags |= MASK_NO_SDATA_SET;
1345 /* Check for small data option */
1346 if (!OPTION_SET_P (g_switch_value) && !TARGET_NO_SDATA_SET)
1347 g_switch_value = TARGET_LL64 ? 8 : 4;
1349 /* A7 has an issue with delay slots. */
1350 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
1351 flag_delayed_branch = 0;
1353 /* Millicode thunks doesn't work for long calls. */
1354 if (TARGET_LONG_CALLS_SET
1355 /* neither for RF16. */
1356 || TARGET_RF16)
1357 target_flags &= ~MASK_MILLICODE_THUNK_SET;
1359 /* Set unaligned to all HS cpus. */
1360 if (!OPTION_SET_P (unaligned_access) && TARGET_HS)
1361 unaligned_access = 1;
1363 if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
1365 TARGET_CODE_DENSITY_FRAME = 0;
1366 flag_delayed_branch = 0;
1369 /* These need to be done at start up. It's convenient to do them here. */
1370 arc_init ();
1373 /* The condition codes of the ARC, and the inverse function. */
1374 /* For short branches, the "c" / "nc" names are not defined in the ARC
1375 Programmers manual, so we have to use "lo" / "hs"" instead. */
1376 static const char *arc_condition_codes[] =
1378 "al", 0, "eq", "ne", "p", "n", "lo", "hs", "v", "nv",
1379 "gt", "le", "ge", "lt", "hi", "ls", "pnz", 0
1382 enum arc_cc_code_index
1384 ARC_CC_AL, ARC_CC_EQ = ARC_CC_AL+2, ARC_CC_NE, ARC_CC_P, ARC_CC_N,
1385 ARC_CC_C, ARC_CC_NC, ARC_CC_V, ARC_CC_NV,
1386 ARC_CC_GT, ARC_CC_LE, ARC_CC_GE, ARC_CC_LT, ARC_CC_HI, ARC_CC_LS, ARC_CC_PNZ,
1387 ARC_CC_LO = ARC_CC_C, ARC_CC_HS = ARC_CC_NC
1390 #define ARC_INVERSE_CONDITION_CODE(X) ((X) ^ 1)
1392 /* Returns the index of the ARC condition code string in
1393 `arc_condition_codes'. COMPARISON should be an rtx like
1394 `(eq (...) (...))'. */
1396 static int
1397 get_arc_condition_code (rtx comparison)
1399 switch (GET_MODE (XEXP (comparison, 0)))
1401 case E_CCmode:
1402 case E_SImode: /* For BRcc. */
1403 switch (GET_CODE (comparison))
1405 case EQ : return ARC_CC_EQ;
1406 case NE : return ARC_CC_NE;
1407 case GT : return ARC_CC_GT;
1408 case LE : return ARC_CC_LE;
1409 case GE : return ARC_CC_GE;
1410 case LT : return ARC_CC_LT;
1411 case GTU : return ARC_CC_HI;
1412 case LEU : return ARC_CC_LS;
1413 case LTU : return ARC_CC_LO;
1414 case GEU : return ARC_CC_HS;
1415 default : gcc_unreachable ();
1417 case E_CC_ZNmode:
1418 switch (GET_CODE (comparison))
1420 case EQ : return ARC_CC_EQ;
1421 case NE : return ARC_CC_NE;
1422 case GE: return ARC_CC_P;
1423 case LT: return ARC_CC_N;
1424 case GT : return ARC_CC_PNZ;
1425 default : gcc_unreachable ();
1427 case E_CC_Zmode:
1428 switch (GET_CODE (comparison))
1430 case EQ : return ARC_CC_EQ;
1431 case NE : return ARC_CC_NE;
1432 default : gcc_unreachable ();
1434 case E_CC_Cmode:
1435 switch (GET_CODE (comparison))
1437 case LTU : return ARC_CC_C;
1438 case GEU : return ARC_CC_NC;
1439 default : gcc_unreachable ();
1441 case E_CC_FP_GTmode:
1442 if (TARGET_ARGONAUT_SET && TARGET_SPFP)
1443 switch (GET_CODE (comparison))
1445 case GT : return ARC_CC_N;
1446 case UNLE: return ARC_CC_P;
1447 default : gcc_unreachable ();
1449 else
1450 switch (GET_CODE (comparison))
1452 case GT : return ARC_CC_HI;
1453 case UNLE : return ARC_CC_LS;
1454 default : gcc_unreachable ();
1456 case E_CC_FP_GEmode:
1457 /* Same for FPX and non-FPX. */
1458 switch (GET_CODE (comparison))
1460 case GE : return ARC_CC_HS;
1461 case UNLT : return ARC_CC_LO;
1462 default : gcc_unreachable ();
1464 case E_CC_FP_UNEQmode:
1465 switch (GET_CODE (comparison))
1467 case UNEQ : return ARC_CC_EQ;
1468 case LTGT : return ARC_CC_NE;
1469 default : gcc_unreachable ();
1471 case E_CC_FP_ORDmode:
1472 switch (GET_CODE (comparison))
1474 case UNORDERED : return ARC_CC_C;
1475 case ORDERED : return ARC_CC_NC;
1476 default : gcc_unreachable ();
1478 case E_CC_FPXmode:
1479 switch (GET_CODE (comparison))
1481 case EQ : return ARC_CC_EQ;
1482 case NE : return ARC_CC_NE;
1483 case UNORDERED : return ARC_CC_C;
1484 case ORDERED : return ARC_CC_NC;
1485 case LTGT : return ARC_CC_HI;
1486 case UNEQ : return ARC_CC_LS;
1487 default : gcc_unreachable ();
1489 case E_CC_FPUmode:
1490 case E_CC_FPUEmode:
1491 switch (GET_CODE (comparison))
1493 case EQ : return ARC_CC_EQ;
1494 case NE : return ARC_CC_NE;
1495 case GT : return ARC_CC_GT;
1496 case GE : return ARC_CC_GE;
1497 case LT : return ARC_CC_C;
1498 case LE : return ARC_CC_LS;
1499 case UNORDERED : return ARC_CC_V;
1500 case ORDERED : return ARC_CC_NV;
1501 case UNGT : return ARC_CC_HI;
1502 case UNGE : return ARC_CC_HS;
1503 case UNLT : return ARC_CC_LT;
1504 case UNLE : return ARC_CC_LE;
1505 /* UNEQ and LTGT do not have representation. */
1506 case LTGT : /* Fall through. */
1507 case UNEQ : /* Fall through. */
1508 default : gcc_unreachable ();
1510 case E_CC_FPU_UNEQmode:
1511 switch (GET_CODE (comparison))
1513 case LTGT : return ARC_CC_NE;
1514 case UNEQ : return ARC_CC_EQ;
1515 default : gcc_unreachable ();
1517 default : gcc_unreachable ();
1519 /*NOTREACHED*/
1520 return (42);
1523 /* Return true if COMPARISON has a short form that can accomodate OFFSET. */
1525 bool
1526 arc_short_comparison_p (rtx comparison, int offset)
1528 gcc_assert (ARC_CC_NC == ARC_CC_HS);
1529 gcc_assert (ARC_CC_C == ARC_CC_LO);
1530 switch (get_arc_condition_code (comparison))
1532 case ARC_CC_EQ: case ARC_CC_NE:
1533 return offset >= -512 && offset <= 506;
1534 case ARC_CC_GT: case ARC_CC_LE: case ARC_CC_GE: case ARC_CC_LT:
1535 case ARC_CC_HI: case ARC_CC_LS: case ARC_CC_LO: case ARC_CC_HS:
1536 return offset >= -64 && offset <= 58;
1537 default:
1538 return false;
1542 /* Given a comparison code (EQ, NE, etc.) and the first operand of a COMPARE,
1543 return the mode to be used for the comparison. */
1545 machine_mode
1546 arc_select_cc_mode (enum rtx_code op, rtx x, rtx y)
1548 machine_mode mode = GET_MODE (x);
1549 rtx x1;
1551 /* For an operation that sets the condition codes as a side-effect, the
1552 C and V flags is not set as for cmp, so we can only use comparisons where
1553 this doesn't matter. (For LT and GE we can use "mi" and "pl"
1554 instead.) */
1555 /* ??? We could use "pnz" for greater than zero, however, we could then
1556 get into trouble because the comparison could not be reversed. */
1557 if (GET_MODE_CLASS (mode) == MODE_INT
1558 && y == const0_rtx
1559 && (op == EQ || op == NE
1560 || ((op == LT || op == GE) && GET_MODE_SIZE (GET_MODE (x)) <= 4)))
1561 return CC_ZNmode;
1563 /* add.f for if (a+b) */
1564 if (mode == SImode
1565 && GET_CODE (x) == NEG
1566 && (op == EQ || op == NE))
1567 return CC_ZNmode;
1569 /* Check if this is a test suitable for bxor.f . */
1570 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1571 && ((INTVAL (y) - 1) & INTVAL (y)) == 0
1572 && INTVAL (y))
1573 return CC_Zmode;
1575 /* Check if this is a test suitable for add / bmsk.f . */
1576 if (mode == SImode && (op == EQ || op == NE) && CONST_INT_P (y)
1577 && GET_CODE (x) == AND && CONST_INT_P ((x1 = XEXP (x, 1)))
1578 && ((INTVAL (x1) + 1) & INTVAL (x1)) == 0
1579 && (~INTVAL (x1) | INTVAL (y)) < 0
1580 && (~INTVAL (x1) | INTVAL (y)) > -0x800)
1581 return CC_Zmode;
1583 if (GET_MODE (x) == SImode && (op == LTU || op == GEU)
1584 && GET_CODE (x) == PLUS
1585 && (rtx_equal_p (XEXP (x, 0), y) || rtx_equal_p (XEXP (x, 1), y)))
1586 return CC_Cmode;
1588 if (TARGET_ARGONAUT_SET
1589 && ((mode == SFmode && TARGET_SPFP) || (mode == DFmode && TARGET_DPFP)))
1590 switch (op)
1592 case EQ: case NE: case UNEQ: case LTGT: case ORDERED: case UNORDERED:
1593 return CC_FPXmode;
1594 case LT: case UNGE: case GT: case UNLE:
1595 return CC_FP_GTmode;
1596 case LE: case UNGT: case GE: case UNLT:
1597 return CC_FP_GEmode;
1598 default: gcc_unreachable ();
1600 else if (TARGET_HARD_FLOAT
1601 && ((mode == SFmode && TARGET_FP_SP_BASE)
1602 || (mode == DFmode && TARGET_FP_DP_BASE)))
1603 switch (op)
1605 case EQ:
1606 case NE:
1607 case UNORDERED:
1608 case ORDERED:
1609 case UNLT:
1610 case UNLE:
1611 case UNGT:
1612 case UNGE:
1613 return CC_FPUmode;
1615 case LT:
1616 case LE:
1617 case GT:
1618 case GE:
1619 return CC_FPUEmode;
1621 case LTGT:
1622 case UNEQ:
1623 return CC_FPU_UNEQmode;
1625 default:
1626 gcc_unreachable ();
1628 else if (GET_MODE_CLASS (mode) == MODE_FLOAT && TARGET_OPTFPE)
1630 switch (op)
1632 case EQ: case NE: return CC_Zmode;
1633 case LT: case UNGE:
1634 case GT: case UNLE: return CC_FP_GTmode;
1635 case LE: case UNGT:
1636 case GE: case UNLT: return CC_FP_GEmode;
1637 case UNEQ: case LTGT: return CC_FP_UNEQmode;
1638 case ORDERED: case UNORDERED: return CC_FP_ORDmode;
1639 default: gcc_unreachable ();
1642 return CCmode;
1645 /* Vectors to keep interesting information about registers where it can easily
1646 be got. We use to use the actual mode value as the bit number, but there
1647 is (or may be) more than 32 modes now. Instead we use two tables: one
1648 indexed by hard register number, and one indexed by mode. */
1650 /* The purpose of arc_mode_class is to shrink the range of modes so that
1651 they all fit (as bit numbers) in a 32-bit word (again). Each real mode is
1652 mapped into one arc_mode_class mode. */
1654 enum arc_mode_class {
1655 C_MODE,
1656 S_MODE, D_MODE, T_MODE, O_MODE,
1657 SF_MODE, DF_MODE, TF_MODE, OF_MODE,
1658 V_MODE
1661 /* Modes for condition codes. */
1662 #define C_MODES (1 << (int) C_MODE)
1664 /* Modes for single-word and smaller quantities. */
1665 #define S_MODES ((1 << (int) S_MODE) | (1 << (int) SF_MODE))
1667 /* Modes for double-word and smaller quantities. */
1668 #define D_MODES (S_MODES | (1 << (int) D_MODE) | (1 << DF_MODE))
1670 /* Mode for 8-byte DF values only. */
1671 #define DF_MODES (1 << DF_MODE)
1673 /* Modes for quad-word and smaller quantities. */
1674 #define T_MODES (D_MODES | (1 << (int) T_MODE) | (1 << (int) TF_MODE))
1676 /* Modes for 128-bit vectors. */
1677 #define V_MODES (1 << (int) V_MODE)
1679 /* Value is 1 if register/mode pair is acceptable on arc. */
1681 static unsigned int arc_hard_regno_modes[] = {
1682 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1683 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES,
1684 T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, T_MODES, D_MODES,
1685 D_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1687 /* ??? Leave these as S_MODES for now. */
1688 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1689 DF_MODES, 0, DF_MODES, 0, S_MODES, S_MODES, S_MODES, S_MODES,
1690 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1691 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, C_MODES, S_MODES,
1693 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1694 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1695 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1696 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1698 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1699 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1700 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1701 V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES, V_MODES,
1703 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1704 S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES, S_MODES,
1705 S_MODES, S_MODES
1708 static unsigned int arc_mode_class [NUM_MACHINE_MODES];
1710 enum reg_class arc_regno_reg_class[FIRST_PSEUDO_REGISTER];
1712 enum reg_class
1713 arc_preferred_reload_class (rtx, enum reg_class cl)
1715 return cl;
1718 /* Initialize the arc_mode_class array. */
1720 static void
1721 arc_init_reg_tables (void)
1723 int i;
1725 for (i = 0; i < NUM_MACHINE_MODES; i++)
1727 machine_mode m = (machine_mode) i;
1729 switch (GET_MODE_CLASS (m))
1731 case MODE_INT:
1732 case MODE_PARTIAL_INT:
1733 case MODE_COMPLEX_INT:
1734 if (GET_MODE_SIZE (m) <= 4)
1735 arc_mode_class[i] = 1 << (int) S_MODE;
1736 else if (GET_MODE_SIZE (m) == 8)
1737 arc_mode_class[i] = 1 << (int) D_MODE;
1738 else if (GET_MODE_SIZE (m) == 16)
1739 arc_mode_class[i] = 1 << (int) T_MODE;
1740 else if (GET_MODE_SIZE (m) == 32)
1741 arc_mode_class[i] = 1 << (int) O_MODE;
1742 else
1743 arc_mode_class[i] = 0;
1744 break;
1745 case MODE_FLOAT:
1746 case MODE_COMPLEX_FLOAT:
1747 if (GET_MODE_SIZE (m) <= 4)
1748 arc_mode_class[i] = 1 << (int) SF_MODE;
1749 else if (GET_MODE_SIZE (m) == 8)
1750 arc_mode_class[i] = 1 << (int) DF_MODE;
1751 else if (GET_MODE_SIZE (m) == 16)
1752 arc_mode_class[i] = 1 << (int) TF_MODE;
1753 else if (GET_MODE_SIZE (m) == 32)
1754 arc_mode_class[i] = 1 << (int) OF_MODE;
1755 else
1756 arc_mode_class[i] = 0;
1757 break;
1758 case MODE_VECTOR_INT:
1759 if (GET_MODE_SIZE (m) == 4)
1760 arc_mode_class[i] = (1 << (int) S_MODE);
1761 else if (GET_MODE_SIZE (m) == 8)
1762 arc_mode_class[i] = (1 << (int) D_MODE);
1763 else
1764 arc_mode_class[i] = (1 << (int) V_MODE);
1765 break;
1766 case MODE_CC:
1767 default:
1768 /* mode_class hasn't been initialized yet for EXTRA_CC_MODES, so
1769 we must explicitly check for them here. */
1770 if (i == (int) CCmode || i == (int) CC_ZNmode || i == (int) CC_Zmode
1771 || i == (int) CC_Cmode
1772 || i == CC_FP_GTmode || i == CC_FP_GEmode || i == CC_FP_ORDmode
1773 || i == CC_FPUmode || i == CC_FPUEmode || i == CC_FPU_UNEQmode)
1774 arc_mode_class[i] = 1 << (int) C_MODE;
1775 else
1776 arc_mode_class[i] = 0;
1777 break;
1782 /* Core registers 56..59 are used for multiply extension options.
1783 The dsp option uses r56 and r57, these are then named acc1 and acc2.
1784 acc1 is the highpart, and acc2 the lowpart, so which register gets which
1785 number depends on endianness.
1786 The mul64 multiplier options use r57 for mlo, r58 for mmid and r59 for mhi.
1787 Because mlo / mhi form a 64 bit value, we use different gcc internal
1788 register numbers to make them form a register pair as the gcc internals
1789 know it. mmid gets number 57, if still available, and mlo / mhi get
1790 number 58 and 59, depending on endianness. We use DEBUGGER_REGNO
1791 to map this back. */
1792 char rname56[5] = "r56";
1793 char rname57[5] = "r57";
1794 char rname58[5] = "r58";
1795 char rname59[5] = "r59";
1796 char rname29[7] = "ilink1";
1797 char rname30[7] = "ilink2";
1799 static void
1800 arc_conditional_register_usage (void)
1802 int regno;
1803 int i;
1804 int fix_start = 60, fix_end = 55;
1806 if (TARGET_V2)
1808 /* For ARCv2 the core register set is changed. */
1809 strcpy (rname29, "ilink");
1810 strcpy (rname30, "r30");
1812 if (!TEST_HARD_REG_BIT (overrideregs, R30_REG))
1814 /* No user interference. Set the r30 to be used by the
1815 compiler. */
1816 call_used_regs[R30_REG] = 1;
1817 fixed_regs[R30_REG] = 0;
1819 arc_regno_reg_class[R30_REG] = GENERAL_REGS;
1823 if (TARGET_MUL64_SET)
1825 fix_start = R57_REG;
1826 fix_end = R59_REG;
1828 /* We don't provide a name for mmed. In rtl / assembly resource lists,
1829 you are supposed to refer to it as mlo & mhi, e.g
1830 (zero_extract:SI (reg:DI 58) (const_int 32) (16)) .
1831 In an actual asm instruction, you are of course use mmed.
1832 The point of avoiding having a separate register for mmed is that
1833 this way, we don't have to carry clobbers of that reg around in every
1834 isntruction that modifies mlo and/or mhi. */
1835 strcpy (rname57, "");
1836 strcpy (rname58, "mlo");
1837 strcpy (rname59, "mhi");
1840 /* The nature of arc_tp_regno is actually something more like a global
1841 register, however globalize_reg requires a declaration.
1842 We use EPILOGUE_USES to compensate so that sets from
1843 __builtin_set_frame_pointer are not deleted. */
1844 if (arc_tp_regno != -1)
1845 fixed_regs[arc_tp_regno] = call_used_regs[arc_tp_regno] = 1;
1847 if (TARGET_MULMAC_32BY16_SET)
1849 fix_start = MUL32x16_REG;
1850 fix_end = fix_end > R57_REG ? fix_end : R57_REG;
1851 strcpy (rname56, TARGET_BIG_ENDIAN ? "acc1" : "acc2");
1852 strcpy (rname57, TARGET_BIG_ENDIAN ? "acc2" : "acc1");
1854 for (regno = fix_start; regno <= fix_end; regno++)
1856 if (!fixed_regs[regno])
1857 warning (0, "multiply option implies r%d is fixed", regno);
1858 fixed_regs [regno] = call_used_regs[regno] = 1;
1861 /* Reduced configuration: don't use r4-r9, r16-r25. */
1862 if (TARGET_RF16)
1864 for (i = R4_REG; i <= R9_REG; i++)
1865 fixed_regs[i] = call_used_regs[i] = 1;
1866 for (i = R16_REG; i <= R25_REG; i++)
1867 fixed_regs[i] = call_used_regs[i] = 1;
1870 /* ARCHS has 64-bit data-path which makes use of the even-odd paired
1871 registers. */
1872 if (TARGET_HS)
1873 for (regno = R1_REG; regno < R32_REG; regno +=2)
1874 arc_hard_regno_modes[regno] = S_MODES;
1876 for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
1877 if (i < ILINK1_REG)
1879 if ((i <= R3_REG) || ((i >= R12_REG) && (i <= R15_REG)))
1880 arc_regno_reg_class[i] = ARCOMPACT16_REGS;
1881 else
1882 arc_regno_reg_class[i] = GENERAL_REGS;
1884 else if (i < LP_COUNT)
1885 arc_regno_reg_class[i] = GENERAL_REGS;
1886 else
1887 arc_regno_reg_class[i] = NO_REGS;
1889 /* Handle Special Registers. */
1890 arc_regno_reg_class[CC_REG] = NO_REGS; /* CC_REG: must be NO_REGS. */
1891 arc_regno_reg_class[FRAME_POINTER_REGNUM] = GENERAL_REGS;
1892 arc_regno_reg_class[ARG_POINTER_REGNUM] = GENERAL_REGS;
1894 if (TARGET_DPFP)
1895 for (i = R40_REG; i < R44_REG; ++i)
1897 arc_regno_reg_class[i] = DOUBLE_REGS;
1898 if (!TARGET_ARGONAUT_SET)
1899 CLEAR_HARD_REG_BIT (reg_class_contents[GENERAL_REGS], i);
1901 else
1903 /* Disable all DOUBLE_REGISTER settings, if not generating DPFP
1904 code. */
1905 arc_regno_reg_class[R40_REG] = ALL_REGS;
1906 arc_regno_reg_class[R41_REG] = ALL_REGS;
1907 arc_regno_reg_class[R42_REG] = ALL_REGS;
1908 arc_regno_reg_class[R43_REG] = ALL_REGS;
1910 fixed_regs[R40_REG] = 1;
1911 fixed_regs[R41_REG] = 1;
1912 fixed_regs[R42_REG] = 1;
1913 fixed_regs[R43_REG] = 1;
1915 arc_hard_regno_modes[R40_REG] = 0;
1916 arc_hard_regno_modes[R42_REG] = 0;
1919 if (TARGET_SIMD_SET)
1921 gcc_assert (ARC_FIRST_SIMD_VR_REG == 64);
1922 gcc_assert (ARC_LAST_SIMD_VR_REG == 127);
1924 for (i = ARC_FIRST_SIMD_VR_REG; i <= ARC_LAST_SIMD_VR_REG; i++)
1925 arc_regno_reg_class [i] = SIMD_VR_REGS;
1927 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_REG == 128);
1928 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_IN_REG == 128);
1929 gcc_assert (ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG == 136);
1930 gcc_assert (ARC_LAST_SIMD_DMA_CONFIG_REG == 143);
1932 for (i = ARC_FIRST_SIMD_DMA_CONFIG_REG;
1933 i <= ARC_LAST_SIMD_DMA_CONFIG_REG; i++)
1934 arc_regno_reg_class [i] = SIMD_DMA_CONFIG_REGS;
1937 /* pc : r63 */
1938 arc_regno_reg_class[PCL_REG] = NO_REGS;
1940 /*ARCV2 Accumulator. */
1941 if ((TARGET_V2
1942 && (TARGET_FP_DP_FUSED || TARGET_FP_SP_FUSED))
1943 || TARGET_PLUS_DMPY)
1945 arc_regno_reg_class[ACCL_REGNO] = GENERAL_REGS;
1946 arc_regno_reg_class[ACCH_REGNO] = GENERAL_REGS;
1948 /* Allow the compiler to freely use them. */
1949 if (!TEST_HARD_REG_BIT (overrideregs, ACCL_REGNO))
1950 fixed_regs[ACCL_REGNO] = 0;
1951 if (!TEST_HARD_REG_BIT (overrideregs, ACCH_REGNO))
1952 fixed_regs[ACCH_REGNO] = 0;
1954 if (!fixed_regs[ACCH_REGNO] && !fixed_regs[ACCL_REGNO])
1955 arc_hard_regno_modes[ACC_REG_FIRST] = D_MODES;
1959 /* Implement TARGET_HARD_REGNO_NREGS. */
1961 static unsigned int
1962 arc_hard_regno_nregs (unsigned int regno, machine_mode mode)
1964 if (GET_MODE_SIZE (mode) == 16
1965 && regno >= ARC_FIRST_SIMD_VR_REG
1966 && regno <= ARC_LAST_SIMD_VR_REG)
1967 return 1;
1969 return CEIL (GET_MODE_SIZE (mode), UNITS_PER_WORD);
1972 /* Implement TARGET_HARD_REGNO_MODE_OK. */
1974 static bool
1975 arc_hard_regno_mode_ok (unsigned int regno, machine_mode mode)
1977 return (arc_hard_regno_modes[regno] & arc_mode_class[mode]) != 0;
1980 /* Implement TARGET_MODES_TIEABLE_P. Tie QI/HI/SI modes together. */
1982 static bool
1983 arc_modes_tieable_p (machine_mode mode1, machine_mode mode2)
1985 return (GET_MODE_CLASS (mode1) == MODE_INT
1986 && GET_MODE_CLASS (mode2) == MODE_INT
1987 && GET_MODE_SIZE (mode1) <= UNITS_PER_WORD
1988 && GET_MODE_SIZE (mode2) <= UNITS_PER_WORD);
1991 /* Handle an "interrupt" attribute; arguments as in
1992 struct attribute_spec.handler. */
1994 static tree
1995 arc_handle_interrupt_attribute (tree *, tree name, tree args, int,
1996 bool *no_add_attrs)
1998 gcc_assert (args);
2000 tree value = TREE_VALUE (args);
2002 if (TREE_CODE (value) != STRING_CST)
2004 warning (OPT_Wattributes,
2005 "argument of %qE attribute is not a string constant",
2006 name);
2007 *no_add_attrs = true;
2009 else if (!TARGET_V2
2010 && strcmp (TREE_STRING_POINTER (value), "ilink1")
2011 && strcmp (TREE_STRING_POINTER (value), "ilink2"))
2013 warning (OPT_Wattributes,
2014 "argument of %qE attribute is not \"ilink1\" or \"ilink2\"",
2015 name);
2016 *no_add_attrs = true;
2018 else if (TARGET_V2
2019 && strcmp (TREE_STRING_POINTER (value), "ilink")
2020 && strcmp (TREE_STRING_POINTER (value), "firq"))
2022 warning (OPT_Wattributes,
2023 "argument of %qE attribute is not \"ilink\" or \"firq\"",
2024 name);
2025 *no_add_attrs = true;
2028 return NULL_TREE;
2031 static tree
2032 arc_handle_fndecl_attribute (tree *node, tree name, tree args ATTRIBUTE_UNUSED,
2033 int flags ATTRIBUTE_UNUSED, bool *no_add_attrs)
2035 if (TREE_CODE (*node) != FUNCTION_DECL)
2037 warning (OPT_Wattributes, "%qE attribute only applies to functions",
2038 name);
2039 *no_add_attrs = true;
2042 return NULL_TREE;
2045 /* Type of function DECL.
2047 The result is cached. To reset the cache at the end of a function,
2048 call with DECL = NULL_TREE. */
2050 static unsigned int
2051 arc_compute_function_type (struct function *fun)
2053 tree attr, decl = fun->decl;
2054 unsigned int fn_type = fun->machine->fn_type;
2056 if (fn_type != ARC_FUNCTION_UNKNOWN)
2057 return fn_type;
2059 /* Check if it is a naked function. */
2060 if (lookup_attribute ("naked", DECL_ATTRIBUTES (decl)) != NULL_TREE)
2061 fn_type |= ARC_FUNCTION_NAKED;
2062 else
2063 fn_type |= ARC_FUNCTION_NORMAL;
2065 /* Now see if this is an interrupt handler. */
2066 attr = lookup_attribute ("interrupt", DECL_ATTRIBUTES (decl));
2067 if (attr != NULL_TREE)
2069 tree value, args = TREE_VALUE (attr);
2071 gcc_assert (list_length (args) == 1);
2072 value = TREE_VALUE (args);
2073 gcc_assert (TREE_CODE (value) == STRING_CST);
2075 if (!strcmp (TREE_STRING_POINTER (value), "ilink1")
2076 || !strcmp (TREE_STRING_POINTER (value), "ilink"))
2077 fn_type |= ARC_FUNCTION_ILINK1;
2078 else if (!strcmp (TREE_STRING_POINTER (value), "ilink2"))
2079 fn_type |= ARC_FUNCTION_ILINK2;
2080 else if (!strcmp (TREE_STRING_POINTER (value), "firq"))
2081 fn_type |= ARC_FUNCTION_FIRQ;
2082 else
2083 gcc_unreachable ();
2086 return fun->machine->fn_type = fn_type;
2089 /* Implement `TARGET_ALLOCATE_STACK_SLOTS_FOR_ARGS' */
2091 static bool
2092 arc_allocate_stack_slots_for_args (void)
2094 /* Naked functions should not allocate stack slots for arguments. */
2095 unsigned int fn_type = arc_compute_function_type (cfun);
2097 return !ARC_NAKED_P(fn_type);
2100 /* Implement `TARGET_WARN_FUNC_RETURN'. */
2102 static bool
2103 arc_warn_func_return (tree decl)
2105 struct function *func = DECL_STRUCT_FUNCTION (decl);
2106 unsigned int fn_type = arc_compute_function_type (func);
2108 return !ARC_NAKED_P (fn_type);
2111 /* Return zero if TYPE1 and TYPE are incompatible, one if they are compatible,
2112 and two if they are nearly compatible (which causes a warning to be
2113 generated). */
2115 static int
2116 arc_comp_type_attributes (const_tree type1,
2117 const_tree type2)
2119 int l1, l2, m1, m2, s1, s2;
2121 /* Check for mismatch of non-default calling convention. */
2122 if (TREE_CODE (type1) != FUNCTION_TYPE)
2123 return 1;
2125 /* Check for mismatched call attributes. */
2126 l1 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type1)) != NULL;
2127 l2 = lookup_attribute ("long_call", TYPE_ATTRIBUTES (type2)) != NULL;
2128 m1 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type1)) != NULL;
2129 m2 = lookup_attribute ("medium_call", TYPE_ATTRIBUTES (type2)) != NULL;
2130 s1 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type1)) != NULL;
2131 s2 = lookup_attribute ("short_call", TYPE_ATTRIBUTES (type2)) != NULL;
2133 /* Only bother to check if an attribute is defined. */
2134 if (l1 | l2 | m1 | m2 | s1 | s2)
2136 /* If one type has an attribute, the other must have the same attribute. */
2137 if ((l1 != l2) || (m1 != m2) || (s1 != s2))
2138 return 0;
2140 /* Disallow mixed attributes. */
2141 if (l1 + m1 + s1 > 1)
2142 return 0;
2146 return 1;
2149 /* Misc. utilities. */
2151 /* X and Y are two things to compare using CODE. Emit the compare insn and
2152 return the rtx for the cc reg in the proper mode. */
2155 gen_compare_reg (rtx comparison, machine_mode omode)
2157 enum rtx_code code = GET_CODE (comparison);
2158 rtx x = XEXP (comparison, 0);
2159 rtx y = XEXP (comparison, 1);
2160 rtx tmp, cc_reg;
2161 machine_mode mode, cmode;
2164 cmode = GET_MODE (x);
2165 if (cmode == VOIDmode)
2166 cmode = GET_MODE (y);
2168 /* If ifcvt passed us a MODE_CC comparison we can
2169 just return it. It should be in the proper form already. */
2170 if (GET_MODE_CLASS (cmode) == MODE_CC)
2171 return comparison;
2173 if (cmode != SImode && cmode != SFmode && cmode != DFmode)
2174 return NULL_RTX;
2175 if (cmode == SImode)
2177 if (!register_operand (x, SImode))
2179 if (register_operand (y, SImode))
2181 tmp = x;
2182 x = y;
2183 y = tmp;
2184 code = swap_condition (code);
2186 else
2187 x = copy_to_mode_reg (SImode, x);
2189 if (GET_CODE (y) == SYMBOL_REF && flag_pic)
2190 y = copy_to_mode_reg (SImode, y);
2192 else
2194 x = force_reg (cmode, x);
2195 y = force_reg (cmode, y);
2197 mode = SELECT_CC_MODE (code, x, y);
2199 cc_reg = gen_rtx_REG (mode, CC_REG);
2201 /* ??? FIXME (x-y)==0, as done by both cmpsfpx_raw and
2202 cmpdfpx_raw, is not a correct comparison for floats:
2203 http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
2205 if (TARGET_ARGONAUT_SET
2206 && ((cmode == SFmode && TARGET_SPFP) || (cmode == DFmode && TARGET_DPFP)))
2208 switch (code)
2210 case NE: case EQ: case LT: case UNGE: case LE: case UNGT:
2211 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2212 break;
2213 case GT: case UNLE: case GE: case UNLT:
2214 code = swap_condition (code);
2215 tmp = x;
2216 x = y;
2217 y = tmp;
2218 break;
2219 default:
2220 gcc_unreachable ();
2222 if (cmode == SFmode)
2224 emit_insn (gen_cmpsfpx_raw (x, y));
2226 else /* DFmode */
2228 /* Accepts Dx regs directly by insns. */
2229 emit_insn (gen_cmpdfpx_raw (x, y));
2232 if (mode != CC_FPXmode)
2233 emit_insn (gen_rtx_SET (cc_reg,
2234 gen_rtx_COMPARE (mode,
2235 gen_rtx_REG (CC_FPXmode, 61),
2236 const0_rtx)));
2238 else if (TARGET_FPX_QUARK && (cmode == SFmode))
2240 switch (code)
2242 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2243 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2244 break;
2245 case LT: case UNGE: case LE: case UNGT:
2246 code = swap_condition (code);
2247 tmp = x;
2248 x = y;
2249 y = tmp;
2250 break;
2251 default:
2252 gcc_unreachable ();
2255 emit_insn (gen_cmp_quark (cc_reg,
2256 gen_rtx_COMPARE (mode, x, y)));
2258 else if (TARGET_HARD_FLOAT
2259 && ((cmode == SFmode && TARGET_FP_SP_BASE)
2260 || (cmode == DFmode && TARGET_FP_DP_BASE)))
2261 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2262 else if (GET_MODE_CLASS (cmode) == MODE_FLOAT && TARGET_OPTFPE)
2264 rtx op0 = gen_rtx_REG (cmode, 0);
2265 rtx op1 = gen_rtx_REG (cmode, GET_MODE_SIZE (cmode) / UNITS_PER_WORD);
2266 bool swap = false;
2268 switch (code)
2270 case NE: case EQ: case GT: case UNLE: case GE: case UNLT:
2271 case UNEQ: case LTGT: case ORDERED: case UNORDERED:
2272 break;
2273 case LT: case UNGE: case LE: case UNGT:
2274 code = swap_condition (code);
2275 swap = true;
2276 break;
2277 default:
2278 gcc_unreachable ();
2280 if (currently_expanding_to_rtl)
2282 if (swap)
2284 tmp = x;
2285 x = y;
2286 y = tmp;
2288 emit_move_insn (op0, x);
2289 emit_move_insn (op1, y);
2291 else
2293 gcc_assert (rtx_equal_p (op0, x));
2294 gcc_assert (rtx_equal_p (op1, y));
2295 if (swap)
2297 op0 = y;
2298 op1 = x;
2301 emit_insn (gen_cmp_float (cc_reg, gen_rtx_COMPARE (mode, op0, op1)));
2303 else
2304 emit_insn (gen_rtx_SET (cc_reg, gen_rtx_COMPARE (mode, x, y)));
2305 return gen_rtx_fmt_ee (code, omode, cc_reg, const0_rtx);
2308 /* Return true if VALUE, a const_double, will fit in a limm (4 byte number).
2309 We assume the value can be either signed or unsigned. */
2311 bool
2312 arc_double_limm_p (rtx value)
2314 HOST_WIDE_INT low, high;
2316 gcc_assert (GET_CODE (value) == CONST_DOUBLE);
2318 if (TARGET_DPFP)
2319 return true;
2321 low = CONST_DOUBLE_LOW (value);
2322 high = CONST_DOUBLE_HIGH (value);
2324 if (low & 0x80000000)
2326 return (((unsigned HOST_WIDE_INT) low <= 0xffffffff && high == 0)
2327 || (((low & - (unsigned HOST_WIDE_INT) 0x80000000)
2328 == - (unsigned HOST_WIDE_INT) 0x80000000)
2329 && high == -1));
2331 else
2333 return (unsigned HOST_WIDE_INT) low <= 0x7fffffff && high == 0;
2337 /* Do any needed setup for a variadic function. For the ARC, we must
2338 create a register parameter block, and then copy any anonymous arguments
2339 in registers to memory.
2341 CUM has not been updated for the last named argument (which is given
2342 by ARG), and we rely on this fact. */
2344 static void
2345 arc_setup_incoming_varargs (cumulative_args_t args_so_far,
2346 const function_arg_info &arg,
2347 int *pretend_size, int no_rtl)
2349 int first_anon_arg;
2350 CUMULATIVE_ARGS next_cum;
2352 /* We must treat `__builtin_va_alist' as an anonymous arg. */
2354 next_cum = *get_cumulative_args (args_so_far);
2355 if (!TYPE_NO_NAMED_ARGS_STDARG_P (TREE_TYPE (current_function_decl))
2356 || arg.type != NULL_TREE)
2357 arc_function_arg_advance (pack_cumulative_args (&next_cum), arg);
2358 first_anon_arg = next_cum;
2360 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2362 /* First anonymous (unnamed) argument is in a reg. */
2364 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2365 int first_reg_offset = first_anon_arg;
2367 if (!no_rtl)
2369 rtx regblock
2370 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2371 FIRST_PARM_OFFSET (0)));
2372 move_block_from_reg (first_reg_offset, regblock,
2373 MAX_ARC_PARM_REGS - first_reg_offset);
2376 *pretend_size
2377 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2381 /* Return TRUE if reg is ok for short instrcutions. */
2383 static bool
2384 arc_check_short_reg_p (rtx op)
2386 if (!REG_P (op))
2387 return false;
2389 if (IN_RANGE (REGNO (op) ^ 4, 4, 11))
2390 return true;
2392 return false;
2395 /* Cost functions. */
2397 /* Provide the costs of an addressing mode that contains ADDR.
2398 If ADDR is not a valid address, its cost is irrelevant. */
2400 static int
2401 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2403 switch (GET_CODE (addr))
2405 case REG :
2406 return speed || arc_check_short_reg_p (addr) ? 0 : 1;
2407 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2408 case PRE_MODIFY: case POST_MODIFY:
2409 return !speed;
2411 case LABEL_REF :
2412 case SYMBOL_REF :
2413 case CONST :
2414 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2415 return 0;
2416 /* Most likely needs a LIMM. */
2417 return COSTS_N_INSNS (1);
2419 case PLUS :
2421 rtx plus0 = XEXP (addr, 0);
2422 rtx plus1 = XEXP (addr, 1);
2424 if (GET_CODE (plus0) != REG
2425 && (GET_CODE (plus0) != MULT
2426 || !CONST_INT_P (XEXP (plus0, 1))
2427 || (INTVAL (XEXP (plus0, 1)) != 2
2428 && INTVAL (XEXP (plus0, 1)) != 4)))
2429 break;
2431 switch (GET_CODE (plus1))
2433 case CONST_INT :
2434 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2435 ? COSTS_N_INSNS (1)
2436 : speed
2438 : (arc_check_short_reg_p (plus0)
2439 && satisfies_constraint_O (plus1))
2441 : 1);
2442 case REG:
2443 return (speed < 1 ? 0
2444 : (arc_check_short_reg_p (plus0)
2445 && arc_check_short_reg_p (plus1))
2446 ? 0 : 1);
2447 case CONST :
2448 case SYMBOL_REF :
2449 case LABEL_REF :
2450 return COSTS_N_INSNS (1);
2451 default:
2452 break;
2454 break;
2456 default:
2457 break;
2460 return 4;
2463 /* Emit instruction X with the frame related bit set. */
2465 static rtx
2466 frame_insn (rtx x)
2468 x = emit_insn (x);
2469 RTX_FRAME_RELATED_P (x) = 1;
2470 return x;
2473 /* Emit a frame insn to move SRC to DST. */
2475 static rtx
2476 frame_move (rtx dst, rtx src)
2478 rtx tmp = gen_rtx_SET (dst, src);
2479 RTX_FRAME_RELATED_P (tmp) = 1;
2480 return frame_insn (tmp);
2483 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2484 auto increment address, or is zero. */
2486 static rtx
2487 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2489 rtx insn = frame_move (dst, src);
2491 if (!addr
2492 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2493 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2494 add_reg_note (insn, REG_INC, reg);
2495 return insn;
2498 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2500 static rtx
2501 frame_add (rtx reg, HOST_WIDE_INT offset)
2503 gcc_assert ((offset & 0x3) == 0);
2504 if (!offset)
2505 return NULL_RTX;
2506 return frame_move (reg, plus_constant (Pmode, reg, offset));
2509 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2511 static rtx
2512 frame_stack_add (HOST_WIDE_INT offset)
2514 return frame_add (stack_pointer_rtx, offset);
2517 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2518 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2519 Register Allocator) pass, while we want to get the frame size
2520 correct earlier than the IRA pass.
2522 When a function uses eh_return we must ensure that the fp register
2523 is saved and then restored so that the unwinder can restore the
2524 correct value for the frame we are going to jump to.
2526 To do this we force all frames that call eh_return to require a
2527 frame pointer (see arc_frame_pointer_required), this
2528 will ensure that the previous frame pointer is stored on entry to
2529 the function, and will then be reloaded at function exit.
2531 As the frame pointer is handled as a special case in our prologue
2532 and epilogue code it must not be saved and restored using the
2533 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2534 believes that the function is not using a frame pointer and that
2535 the value in the fp register is the frame pointer, while the
2536 prologue and epilogue are busy saving and restoring the fp
2537 register.
2539 During compilation of a function the frame size is evaluated
2540 multiple times, it is not until the reload pass is complete the
2541 frame size is considered fixed (it is at this point that space for
2542 all spills has been allocated). However the frame_pointer_needed
2543 variable is not set true until the register allocation pass, as a
2544 result in the early stages the frame size does not include space
2545 for the frame pointer to be spilled.
2547 The problem that this causes is that the rtl generated for
2548 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2549 the offset from the frame pointer at which the return address
2550 lives. However, in early passes GCC has not yet realised we need a
2551 frame pointer, and so has not included space for the frame pointer
2552 in the frame size, and so gets the offset of the return address
2553 wrong. This should not be an issue as in later passes GCC has
2554 realised that the frame pointer needs to be spilled, and has
2555 increased the frame size. However, the rtl for the
2556 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2557 offset, and the wrong smaller offset is used. */
2559 static bool
2560 arc_frame_pointer_needed (void)
2562 return (frame_pointer_needed || crtl->calls_eh_return);
2565 /* Tell prologue and epilogue if register REGNO should be saved /
2566 restored. The SPECIAL_P is true when the register may need special
2567 ld/st sequence. The return address, and stack pointer are treated
2568 separately. Don't consider them here. */
2570 static bool
2571 arc_must_save_register (int regno, struct function *func, bool special_p)
2573 unsigned int fn_type = arc_compute_function_type (func);
2574 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2575 && ARC_AUTO_IRQ_P (fn_type));
2576 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2578 switch (rgf_banked_register_count)
2580 case 4:
2581 firq_auto_save_p &= (regno < 4);
2582 break;
2583 case 8:
2584 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2585 break;
2586 case 16:
2587 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2588 || ((regno > 25) && (regno < 29))
2589 || ((regno > 29) && (regno < 32)));
2590 break;
2591 case 32:
2592 firq_auto_save_p &= (regno != 29) && (regno < 32);
2593 break;
2594 default:
2595 firq_auto_save_p = false;
2596 break;
2599 switch (regno)
2601 case ILINK1_REG:
2602 case RETURN_ADDR_REGNUM:
2603 case STACK_POINTER_REGNUM:
2604 /* The stack pointer and the return address are handled
2605 separately. */
2606 return false;
2608 case R30_REG:
2609 /* r30 is either used as ilink2 by ARCv1 or as a free register
2610 by ARCv2. */
2611 if (!TARGET_V2)
2612 return false;
2613 break;
2615 case R40_REG:
2616 case R41_REG:
2617 case R42_REG:
2618 case R43_REG:
2619 case R44_REG:
2620 /* If those ones are used by the FPX machinery, we handle them
2621 separately. */
2622 if (TARGET_DPFP && !special_p)
2623 return false;
2624 /* FALLTHRU. */
2626 case R32_REG:
2627 case R33_REG:
2628 case R34_REG:
2629 case R35_REG:
2630 case R36_REG:
2631 case R37_REG:
2632 case R38_REG:
2633 case R39_REG:
2634 case R45_REG:
2635 case R46_REG:
2636 case R47_REG:
2637 case R48_REG:
2638 case R49_REG:
2639 case R50_REG:
2640 case R51_REG:
2641 case R52_REG:
2642 case R53_REG:
2643 case R54_REG:
2644 case R55_REG:
2645 case R56_REG:
2646 case R57_REG:
2647 /* The Extension Registers. */
2648 if (ARC_INTERRUPT_P (fn_type)
2649 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2650 || df_regs_ever_live_p (regno))
2651 /* Not all extension registers are available, choose the
2652 real ones. */
2653 && !fixed_regs[regno])
2654 return true;
2655 return false;
2657 case R58_REG:
2658 case R59_REG:
2659 /* ARC600 specifies those ones as mlo/mhi registers, otherwise
2660 just handle them like any other extension register. */
2661 if (ARC_INTERRUPT_P (fn_type)
2662 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2663 || df_regs_ever_live_p (regno))
2664 /* Not all extension registers are available, choose the
2665 real ones. */
2666 && ((!fixed_regs[regno] && !special_p)
2667 || (TARGET_MUL64_SET && special_p)))
2668 return true;
2669 return false;
2671 case 61:
2672 case 62:
2673 case 63:
2674 /* Fixed/control register, nothing to do. LP_COUNT is
2675 different. */
2676 return false;
2678 case HARD_FRAME_POINTER_REGNUM:
2679 /* If we need FP reg as a frame pointer then don't save it as a
2680 regular reg. */
2681 if (arc_frame_pointer_needed ())
2682 return false;
2683 break;
2685 default:
2686 break;
2689 if (((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
2690 /* In an interrupt save everything. */
2691 || (ARC_INTERRUPT_P (fn_type)
2692 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2693 || df_regs_ever_live_p (regno))))
2694 /* Do not emit code for auto saved regs. */
2695 && !irq_auto_save_p
2696 && !firq_auto_save_p)
2697 return true;
2698 return false;
2701 /* Return true if the return address must be saved in the current function,
2702 otherwise return false. */
2704 static bool
2705 arc_must_save_return_addr (struct function *func)
2707 if (func->machine->frame_info.save_return_addr)
2708 return true;
2710 return false;
2713 /* Return non-zero if there are registers to be saved or loaded using
2714 millicode thunks. We can only use consecutive sequences starting
2715 with r13, and not going beyond r25.
2716 GMASK is a bitmask of registers to save. This function sets
2717 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2718 of registers to be saved / restored with a millicode call. */
2720 static int
2721 arc_compute_millicode_save_restore_regs (uint64_t gmask,
2722 struct arc_frame_info *frame)
2724 int regno;
2726 int start_reg = 13, end_reg = 25;
2728 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
2729 regno++;
2730 end_reg = regno - 1;
2731 /* There is no point in using millicode thunks if we don't save/restore
2732 at least three registers. For non-leaf functions we also have the
2733 blink restore. */
2734 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2736 frame->millicode_start_reg = 13;
2737 frame->millicode_end_reg = regno - 1;
2738 return 1;
2740 return 0;
2743 /* Return the bytes needed to compute the frame pointer from the
2744 current stack pointer. */
2746 static unsigned int
2747 arc_compute_frame_size (void)
2749 int regno;
2750 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2751 unsigned int reg_size;
2752 uint64_t gmask;
2753 struct arc_frame_info *frame_info;
2754 int size;
2755 unsigned int extra_plus_reg_size;
2756 unsigned int extra_plus_reg_size_aligned;
2757 unsigned int fn_type = arc_compute_function_type (cfun);
2759 /* The answer might already be known. */
2760 if (cfun->machine->frame_info.initialized)
2761 return cfun->machine->frame_info.total_size;
2763 frame_info = &cfun->machine->frame_info;
2764 size = ARC_STACK_ALIGN (get_frame_size ());
2766 /* 1) Size of locals and temporaries. */
2767 var_size = size;
2769 /* 2) Size of outgoing arguments. */
2770 args_size = crtl->outgoing_args_size;
2772 /* 3) Calculate space needed for saved registers.
2773 ??? We ignore the extension registers for now. */
2775 /* See if this is an interrupt handler. Call used registers must be saved
2776 for them too. */
2778 reg_size = 0;
2779 gmask = 0;
2781 /* The last 4 regs are special, avoid them. */
2782 for (regno = 0; regno <= (GMASK_LEN - 4); regno++)
2784 if (arc_must_save_register (regno, cfun, false))
2786 reg_size += UNITS_PER_WORD;
2787 gmask |= 1ULL << regno;
2791 /* In a frame that calls __builtin_eh_return two data registers are
2792 used to pass values back to the exception handler.
2794 Ensure that these registers are spilled to the stack so that the
2795 exception throw code can find them, and update the saved values.
2796 The handling code will then consume these reloaded values to
2797 handle the exception. */
2798 if (crtl->calls_eh_return)
2799 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
2801 reg_size += UNITS_PER_WORD;
2802 gmask |= 1ULL << regno;
2805 /* Check if we need to save the return address. */
2806 frame_info->save_return_addr = (!crtl->is_leaf
2807 || df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2808 || crtl->calls_eh_return);
2810 /* Saving blink reg for millicode thunk calls. */
2811 if (TARGET_MILLICODE_THUNK_SET
2812 && !ARC_INTERRUPT_P (fn_type)
2813 && !crtl->calls_eh_return)
2815 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2816 frame_info->save_return_addr = true;
2819 /* Save lp_count, lp_start and lp_end. */
2820 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
2821 reg_size += UNITS_PER_WORD * 3;
2823 /* Check for the special R40-R44 regs used by FPX extension. */
2824 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
2825 cfun, TARGET_DPFP))
2826 reg_size += UNITS_PER_WORD * 2;
2827 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R43_REG : R42_REG,
2828 cfun, TARGET_DPFP))
2829 reg_size += UNITS_PER_WORD * 2;
2831 /* Check if R58 is used. */
2832 if (arc_must_save_register (R58_REG, cfun, true))
2833 reg_size += UNITS_PER_WORD * 2;
2835 /* 4) Calculate extra size made up of the blink + fp size. */
2836 extra_size = 0;
2837 if (arc_must_save_return_addr (cfun))
2838 extra_size = 4;
2839 /* Add FP size only when it is not autosaved. */
2840 if (arc_frame_pointer_needed ()
2841 && !ARC_AUTOFP_IRQ_P (fn_type))
2842 extra_size += 4;
2844 /* 5) Space for variable arguments passed in registers */
2845 pretend_size = crtl->args.pretend_args_size;
2847 /* Ensure everything before the locals is aligned appropriately. */
2848 extra_plus_reg_size = extra_size + reg_size;
2849 extra_plus_reg_size_aligned = ARC_STACK_ALIGN (extra_plus_reg_size);
2850 reg_size = extra_plus_reg_size_aligned - extra_size;
2852 /* Compute total frame size. */
2853 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2855 /* It used to be the case that the alignment was forced at this
2856 point. However, that is dangerous, calculations based on
2857 total_size would be wrong. Given that this has never cropped up
2858 as an issue I've changed this to an assert for now. */
2859 gcc_assert (total_size == ARC_STACK_ALIGN (total_size));
2861 /* Save computed information. */
2862 frame_info->total_size = total_size;
2863 frame_info->extra_size = extra_size;
2864 frame_info->pretend_size = pretend_size;
2865 frame_info->var_size = var_size;
2866 frame_info->args_size = args_size;
2867 frame_info->reg_size = reg_size;
2868 frame_info->gmask = gmask;
2869 frame_info->initialized = reload_completed;
2871 /* Ok, we're done. */
2872 return total_size;
2875 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2876 mechanism. */
2878 static void
2879 arc_dwarf_emit_irq_save_regs (void)
2881 rtx tmp, par, insn, reg;
2882 int i, offset, j;
2884 par = gen_rtx_SEQUENCE (VOIDmode,
2885 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
2886 + irq_ctrl_saved.irq_save_blink
2887 + irq_ctrl_saved.irq_save_lpcount
2888 + 1));
2890 /* Build the stack adjustment note for unwind info. */
2891 j = 0;
2892 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
2893 + irq_ctrl_saved.irq_save_blink
2894 + irq_ctrl_saved.irq_save_lpcount);
2895 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
2896 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
2897 RTX_FRAME_RELATED_P (tmp) = 1;
2898 XVECEXP (par, 0, j++) = tmp;
2900 offset -= UNITS_PER_WORD;
2902 /* 1st goes LP_COUNT. */
2903 if (irq_ctrl_saved.irq_save_lpcount)
2905 reg = gen_rtx_REG (SImode, 60);
2906 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2907 tmp = gen_frame_mem (SImode, tmp);
2908 tmp = gen_rtx_SET (tmp, reg);
2909 RTX_FRAME_RELATED_P (tmp) = 1;
2910 XVECEXP (par, 0, j++) = tmp;
2911 offset -= UNITS_PER_WORD;
2914 /* 2nd goes BLINK. */
2915 if (irq_ctrl_saved.irq_save_blink)
2917 reg = gen_rtx_REG (SImode, 31);
2918 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2919 tmp = gen_frame_mem (SImode, tmp);
2920 tmp = gen_rtx_SET (tmp, reg);
2921 RTX_FRAME_RELATED_P (tmp) = 1;
2922 XVECEXP (par, 0, j++) = tmp;
2923 offset -= UNITS_PER_WORD;
2926 /* Build the parallel of the remaining registers recorded as saved
2927 for unwind. */
2928 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
2930 reg = gen_rtx_REG (SImode, i);
2931 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2932 tmp = gen_frame_mem (SImode, tmp);
2933 tmp = gen_rtx_SET (tmp, reg);
2934 RTX_FRAME_RELATED_P (tmp) = 1;
2935 XVECEXP (par, 0, j++) = tmp;
2936 offset -= UNITS_PER_WORD;
2939 /* Dummy insn used to anchor the dwarf info. */
2940 insn = emit_insn (gen_stack_irq_dwarf());
2941 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
2942 RTX_FRAME_RELATED_P (insn) = 1;
2945 /* Helper for prologue: emit frame store with pre_modify or pre_dec to
2946 save register REG on stack. An initial offset OFFSET can be passed
2947 to the function. */
2949 static int
2950 frame_save_reg (rtx reg, HOST_WIDE_INT offset)
2952 rtx addr;
2954 if (offset)
2956 rtx tmp = plus_constant (Pmode, stack_pointer_rtx,
2957 offset - GET_MODE_SIZE (GET_MODE (reg)));
2958 addr = gen_frame_mem (GET_MODE (reg),
2959 gen_rtx_PRE_MODIFY (Pmode,
2960 stack_pointer_rtx,
2961 tmp));
2963 else
2964 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
2965 stack_pointer_rtx));
2966 frame_move_inc (addr, reg, stack_pointer_rtx, 0);
2968 return GET_MODE_SIZE (GET_MODE (reg)) - offset;
2971 /* Helper used when saving AUX regs during ISR. */
2973 static int
2974 push_reg (rtx reg)
2976 rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
2977 stack_pointer_rtx));
2978 rtx insn = emit_move_insn (stkslot, reg);
2979 RTX_FRAME_RELATED_P (insn) = 1;
2980 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2981 gen_rtx_SET (stack_pointer_rtx,
2982 plus_constant (Pmode, stack_pointer_rtx,
2983 -GET_MODE_SIZE (GET_MODE (reg)))));
2984 return GET_MODE_SIZE (GET_MODE (reg));
2987 /* Helper for epilogue: emit frame load with post_modify or post_inc
2988 to restore register REG from stack. The initial offset is passed
2989 via OFFSET. */
2991 static int
2992 frame_restore_reg (rtx reg, HOST_WIDE_INT offset)
2994 rtx addr, insn;
2996 if (offset)
2998 rtx tmp = plus_constant (Pmode, stack_pointer_rtx,
2999 offset + GET_MODE_SIZE (GET_MODE (reg)));
3000 addr = gen_frame_mem (GET_MODE (reg),
3001 gen_rtx_POST_MODIFY (Pmode,
3002 stack_pointer_rtx,
3003 tmp));
3005 else
3006 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
3007 stack_pointer_rtx));
3008 insn = frame_move_inc (reg, addr, stack_pointer_rtx, 0);
3009 add_reg_note (insn, REG_CFA_RESTORE, reg);
3011 if (reg == hard_frame_pointer_rtx)
3012 add_reg_note (insn, REG_CFA_DEF_CFA,
3013 plus_constant (Pmode, stack_pointer_rtx,
3014 GET_MODE_SIZE (GET_MODE (reg)) + offset));
3015 else
3016 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3017 gen_rtx_SET (stack_pointer_rtx,
3018 plus_constant (Pmode, stack_pointer_rtx,
3019 GET_MODE_SIZE (GET_MODE (reg))
3020 + offset)));
3022 return GET_MODE_SIZE (GET_MODE (reg)) + offset;
3025 /* Helper used when restoring AUX regs during ISR. */
3027 static int
3028 pop_reg (rtx reg)
3030 rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
3031 stack_pointer_rtx));
3032 rtx insn = emit_move_insn (reg, stkslot);
3033 RTX_FRAME_RELATED_P (insn) = 1;
3034 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3035 gen_rtx_SET (stack_pointer_rtx,
3036 plus_constant (Pmode, stack_pointer_rtx,
3037 GET_MODE_SIZE (GET_MODE (reg)))));
3038 return GET_MODE_SIZE (GET_MODE (reg));
3041 /* Check if we have a continous range to be save/restored with the
3042 help of enter/leave instructions. A vaild register range starts
3043 from $r13 and is up to (including) $r26. */
3045 static bool
3046 arc_enter_leave_p (uint64_t gmask)
3048 int regno;
3049 unsigned int rmask = 0;
3051 if (!gmask)
3052 return false;
3054 for (regno = ENTER_LEAVE_START_REG;
3055 regno <= ENTER_LEAVE_END_REG && (gmask & (1ULL << regno)); regno++)
3056 rmask |= 1ULL << regno;
3058 if (rmask ^ gmask)
3059 return false;
3061 return true;
3064 /* ARC's prologue, save any needed call-saved regs (and call-used if
3065 this is an interrupt handler) for ARCompact ISA, using ST/STD
3066 instructions. */
3068 static int
3069 arc_save_callee_saves (uint64_t gmask,
3070 bool save_blink,
3071 bool save_fp,
3072 HOST_WIDE_INT offset,
3073 bool emit_move)
3075 rtx reg;
3076 int frame_allocated = 0;
3077 int i;
3079 /* The home-grown ABI says link register is saved first. */
3080 if (save_blink)
3082 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3083 frame_allocated += frame_save_reg (reg, offset);
3084 offset = 0;
3087 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3088 if (gmask)
3089 for (i = GMASK_LEN; i >= 0; i--)
3091 machine_mode save_mode = SImode;
3093 if (TARGET_LL64
3094 && ((i - 1) % 2 == 0)
3095 && ((gmask & (1ULL << i)) != 0)
3096 && ((gmask & (1ULL << (i - 1))) != 0))
3098 save_mode = DImode;
3099 --i;
3101 else if ((gmask & (1ULL << i)) == 0)
3102 continue;
3104 reg = gen_rtx_REG (save_mode, i);
3105 frame_allocated += frame_save_reg (reg, offset);
3106 offset = 0;
3109 /* Save frame pointer if needed. First save the FP on stack, if not
3110 autosaved. Unfortunately, I cannot add it to gmask and use the
3111 above loop to save fp because our ABI states fp goes aftert all
3112 registers are saved. */
3113 if (save_fp)
3115 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3116 offset = 0;
3119 /* Emit mov fp,sp. */
3120 if (emit_move)
3121 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3123 return frame_allocated;
3126 /* ARC's epilogue, restore any required call-saved regs (and call-used
3127 if it is for an interrupt handler) using LD/LDD instructions. */
3129 static int
3130 arc_restore_callee_saves (uint64_t gmask,
3131 bool restore_blink,
3132 bool restore_fp,
3133 HOST_WIDE_INT offset,
3134 HOST_WIDE_INT allocated)
3136 rtx reg;
3137 int frame_deallocated = 0;
3138 HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
3139 unsigned int fn_type = arc_compute_function_type (cfun);
3140 bool early_blink_restore;
3141 int i;
3143 /* Emit mov fp,sp. */
3144 if (arc_frame_pointer_needed () && offset)
3146 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3147 frame_deallocated += offset;
3148 offset = 0;
3151 if (restore_fp)
3153 /* Any offset is taken care by previous if-statement. */
3154 gcc_assert (offset == 0);
3155 frame_deallocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3158 if (offset)
3160 /* No $fp involved, we need to do an add to set the $sp to the
3161 location of the first register. */
3162 frame_stack_add (offset);
3163 frame_deallocated += offset;
3164 offset = 0;
3167 /* When we do not optimize for size or we aren't in an interrupt,
3168 restore first blink. */
3169 early_blink_restore = restore_blink && !optimize_size && offs
3170 && !ARC_INTERRUPT_P (fn_type);
3171 if (early_blink_restore)
3173 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
3174 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3175 rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr),
3176 stack_pointer_rtx, NULL_RTX);
3177 add_reg_note (insn, REG_CFA_RESTORE, reg);
3178 restore_blink = false;
3181 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3182 if (gmask)
3183 for (i = 0; i <= GMASK_LEN; i++)
3185 machine_mode restore_mode = SImode;
3187 if (TARGET_LL64
3188 && ((i % 2) == 0)
3189 && ((gmask & (1ULL << i)) != 0)
3190 && ((gmask & (1ULL << (i + 1))) != 0))
3191 restore_mode = DImode;
3192 else if ((gmask & (1ULL << i)) == 0)
3193 continue;
3195 reg = gen_rtx_REG (restore_mode, i);
3196 offs = 0;
3197 switch (restore_mode)
3199 case E_DImode:
3200 if ((GMASK_LEN - __builtin_clzll (gmask)) == (i + 1)
3201 && early_blink_restore)
3202 offs = 4;
3203 break;
3204 case E_SImode:
3205 if ((GMASK_LEN - __builtin_clzll (gmask)) == i
3206 && early_blink_restore)
3207 offs = 4;
3208 break;
3209 default:
3210 offs = 0;
3212 frame_deallocated += frame_restore_reg (reg, offs);
3213 offset = 0;
3215 if (restore_mode == DImode)
3216 i++;
3219 if (restore_blink)
3221 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3222 frame_deallocated += frame_restore_reg (reg, allocated
3223 - frame_deallocated
3224 /* Consider as well the
3225 current restored
3226 register size. */
3227 - UNITS_PER_WORD);
3230 return frame_deallocated;
3233 /* ARC prologue, save the registers using enter instruction. Leave
3234 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3235 register. */
3237 static int
3238 arc_save_callee_enter (uint64_t gmask,
3239 bool save_blink,
3240 bool save_fp,
3241 HOST_WIDE_INT offset)
3243 int start_reg = ENTER_LEAVE_START_REG;
3244 int end_reg = ENTER_LEAVE_END_REG;
3245 int regno, indx, off, nregs;
3246 rtx insn, reg, mem;
3247 int frame_allocated = 0;
3249 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3250 regno++;
3252 end_reg = regno - 1;
3253 nregs = end_reg - start_reg + 1;
3254 nregs += save_blink ? 1 : 0;
3255 nregs += save_fp ? 1 : 0;
3257 if (offset)
3258 frame_stack_add (offset);
3260 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + (save_fp ? 1 : 0)
3261 + 1));
3262 indx = 0;
3264 reg = gen_rtx_SET (stack_pointer_rtx,
3265 plus_constant (Pmode,
3266 stack_pointer_rtx,
3267 -nregs * UNITS_PER_WORD));
3268 RTX_FRAME_RELATED_P (reg) = 1;
3269 XVECEXP (insn, 0, indx++) = reg;
3270 off = nregs * UNITS_PER_WORD;
3272 if (save_blink)
3274 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3275 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3276 stack_pointer_rtx,
3277 -off));
3278 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3279 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3280 off -= UNITS_PER_WORD;
3281 save_blink = false;
3284 for (regno = start_reg;
3285 regno <= end_reg;
3286 regno++, indx++, off -= UNITS_PER_WORD)
3288 reg = gen_rtx_REG (SImode, regno);
3289 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3290 stack_pointer_rtx,
3291 -off));
3292 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3293 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3294 gmask = gmask & ~(1ULL << regno);
3297 if (save_fp)
3299 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3300 stack_pointer_rtx,
3301 -off));
3302 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, hard_frame_pointer_rtx);
3303 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3304 off -= UNITS_PER_WORD;
3306 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx,
3307 stack_pointer_rtx);
3308 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3309 save_fp = false;
3312 gcc_assert (off == 0);
3313 insn = frame_insn (insn);
3315 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3317 frame_allocated = nregs * UNITS_PER_WORD;
3319 /* offset is a negative number, make sure we add it. */
3320 return frame_allocated - offset;
3323 /* ARC epilogue, restore the registers using leave instruction. An
3324 initial offset is passed in OFFSET. Besides restoring an register
3325 range, leave can also restore $blink (RESTORE_BLINK), or $fp
3326 (RESTORE_FP), and can automatic return (RETURN_P). */
3328 static int
3329 arc_restore_callee_leave (uint64_t gmask,
3330 bool restore_blink,
3331 bool restore_fp,
3332 bool return_p,
3333 HOST_WIDE_INT offset)
3335 int start_reg = ENTER_LEAVE_START_REG;
3336 int end_reg = ENTER_LEAVE_END_REG;
3337 int regno, indx, off, nregs;
3338 rtx insn, reg, mem;
3339 int frame_allocated = 0;
3341 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3342 regno++;
3344 end_reg = regno - 1;
3345 nregs = end_reg - start_reg + 1;
3346 nregs += restore_blink ? 1 : 0;
3347 nregs += restore_fp ? 1 : 0;
3349 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1
3350 + (return_p ? 1 : 0)));
3351 indx = 0;
3353 if (return_p)
3354 XVECEXP (insn, 0, indx++) = ret_rtx;
3356 if (restore_fp)
3358 /* I cannot emit set (sp, fp) here as cselib expects a single sp
3359 set and not two. Thus, use the offset, and change sp adjust
3360 value. */
3361 frame_allocated += offset;
3364 if (offset && !restore_fp)
3366 /* This add is only emmited when we do not restore fp with leave
3367 instruction. */
3368 frame_stack_add (offset);
3369 frame_allocated += offset;
3370 offset = 0;
3373 reg = gen_rtx_SET (stack_pointer_rtx,
3374 plus_constant (Pmode,
3375 stack_pointer_rtx,
3376 offset + nregs * UNITS_PER_WORD));
3377 RTX_FRAME_RELATED_P (reg) = 1;
3378 XVECEXP (insn, 0, indx++) = reg;
3379 off = nregs * UNITS_PER_WORD;
3381 if (restore_blink)
3383 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3384 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3385 stack_pointer_rtx,
3386 off));
3387 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3388 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3389 off -= UNITS_PER_WORD;
3392 for (regno = start_reg;
3393 regno <= end_reg;
3394 regno++, indx++, off -= UNITS_PER_WORD)
3396 reg = gen_rtx_REG (SImode, regno);
3397 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3398 stack_pointer_rtx,
3399 off));
3400 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3401 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3402 gmask = gmask & ~(1ULL << regno);
3405 if (restore_fp)
3407 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3408 stack_pointer_rtx,
3409 off));
3410 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx, mem);
3411 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3412 off -= UNITS_PER_WORD;
3415 gcc_assert (off == 0);
3416 if (return_p)
3418 insn = emit_jump_insn (insn);
3419 RTX_FRAME_RELATED_P (insn) = 1;
3421 else
3422 insn = frame_insn (insn);
3424 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3426 /* Dwarf related info. */
3427 if (restore_fp)
3429 add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
3430 add_reg_note (insn, REG_CFA_DEF_CFA,
3431 plus_constant (Pmode, stack_pointer_rtx,
3432 offset + nregs * UNITS_PER_WORD));
3434 else
3436 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3437 gen_rtx_SET (stack_pointer_rtx,
3438 plus_constant (Pmode, stack_pointer_rtx,
3439 nregs * UNITS_PER_WORD)));
3441 if (restore_blink)
3442 add_reg_note (insn, REG_CFA_RESTORE,
3443 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3444 for (regno = start_reg; regno <= end_reg; regno++)
3445 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, regno));
3447 frame_allocated += nregs * UNITS_PER_WORD;
3449 return frame_allocated;
3452 /* Millicode thunks implementation:
3453 Generates calls to millicodes for registers starting from r13 to r25
3454 Present Limitations:
3455 - Only one range supported. The remaining regs will have the ordinary
3456 st and ld instructions for store and loads. Hence a gmask asking
3457 to store r13-14, r16-r25 will only generate calls to store and
3458 load r13 to r14 while store and load insns will be generated for
3459 r16 to r25 in the prologue and epilogue respectively.
3461 - Presently library only supports register ranges starting from r13.
3464 static int
3465 arc_save_callee_milli (uint64_t gmask,
3466 bool save_blink,
3467 bool save_fp,
3468 HOST_WIDE_INT offset,
3469 HOST_WIDE_INT reg_size)
3471 int start_reg = 13;
3472 int end_reg = 25;
3473 int regno, indx, off, nregs;
3474 rtx insn, reg, mem;
3475 int frame_allocated = 0;
3477 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3478 regno++;
3480 end_reg = regno - 1;
3481 nregs = end_reg - start_reg + 1;
3482 gcc_assert (end_reg > 14);
3485 /* Allocate space on stack for the registers, and take into account
3486 also the initial offset. The registers will be saved using
3487 offsets. N.B. OFFSET is a negative number. */
3488 if (save_blink)
3490 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3491 frame_allocated += frame_save_reg (reg, offset);
3492 offset = 0;
3495 if (reg_size || offset)
3497 frame_stack_add (offset - reg_size);
3498 frame_allocated += nregs * UNITS_PER_WORD - offset;
3499 offset = 0;
3502 /* Start generate millicode call. */
3503 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
3504 indx = 0;
3506 /* This is a call, we clobber blink. */
3507 XVECEXP (insn, 0, nregs) =
3508 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3510 for (regno = start_reg, indx = 0, off = 0;
3511 regno <= end_reg;
3512 regno++, indx++, off += UNITS_PER_WORD)
3514 reg = gen_rtx_REG (SImode, regno);
3515 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3516 stack_pointer_rtx,
3517 off));
3518 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3519 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3520 gmask = gmask & ~(1ULL << regno);
3522 insn = frame_insn (insn);
3524 /* Add DWARF info. */
3525 for (regno = start_reg, off = 0;
3526 regno <= end_reg;
3527 regno++, off += UNITS_PER_WORD)
3529 reg = gen_rtx_REG (SImode, regno);
3530 mem = gen_rtx_MEM (SImode, plus_constant (Pmode,
3531 stack_pointer_rtx, off));
3532 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
3536 /* In the case of millicode thunk, we need to restore the
3537 clobbered blink register. */
3538 if (arc_must_save_return_addr (cfun))
3540 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
3541 gen_rtx_MEM (Pmode,
3542 plus_constant (Pmode,
3543 stack_pointer_rtx,
3544 reg_size))));
3547 /* Save remaining registers using st instructions. */
3548 for (regno = 0; regno <= GMASK_LEN; regno++)
3550 if ((gmask & (1ULL << regno)) == 0)
3551 continue;
3553 reg = gen_rtx_REG (SImode, regno);
3554 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3555 stack_pointer_rtx,
3556 off));
3557 frame_move_inc (mem, reg, stack_pointer_rtx, 0);
3558 frame_allocated += UNITS_PER_WORD;
3559 off += UNITS_PER_WORD;
3562 /* Save frame pointer if needed. First save the FP on stack, if not
3563 autosaved. Unfortunately, I cannot add it to gmask and use the
3564 above loop to save fp because our ABI states fp goes aftert all
3565 registers are saved. */
3566 if (save_fp)
3567 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3569 /* Emit mov fp,sp. */
3570 if (arc_frame_pointer_needed ())
3571 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3573 return frame_allocated;
3576 /* Like the previous function but restore. */
3578 static int
3579 arc_restore_callee_milli (uint64_t gmask,
3580 bool restore_blink,
3581 bool restore_fp,
3582 bool return_p,
3583 HOST_WIDE_INT offset)
3585 int start_reg = 13;
3586 int end_reg = 25;
3587 int regno, indx, off, nregs;
3588 rtx insn, reg, mem;
3589 int frame_allocated = 0;
3591 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3592 regno++;
3594 end_reg = regno - 1;
3595 nregs = end_reg - start_reg + 1;
3596 gcc_assert (end_reg > 14);
3598 /* Emit mov fp,sp. */
3599 if (arc_frame_pointer_needed () && offset)
3601 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3602 frame_allocated = offset;
3603 offset = 0;
3606 if (restore_fp)
3607 frame_allocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3609 if (offset)
3611 /* No fp involved, hence, we need to adjust the sp via an
3612 add. */
3613 frame_stack_add (offset);
3614 frame_allocated += offset;
3615 offset = 0;
3618 /* Start generate millicode call. */
3619 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc ((return_p ? 1 : 0)
3620 + nregs + 1));
3621 indx = 0;
3623 if (return_p)
3625 /* sibling call, the blink is restored with the help of the
3626 value held into r12. */
3627 reg = gen_rtx_REG (Pmode, 12);
3628 XVECEXP (insn, 0, indx++) = ret_rtx;
3629 XVECEXP (insn, 0, indx++) =
3630 gen_rtx_SET (stack_pointer_rtx,
3631 gen_rtx_PLUS (Pmode, stack_pointer_rtx, reg));
3632 frame_allocated += UNITS_PER_WORD;
3634 else
3636 /* This is a call, we clobber blink. */
3637 XVECEXP (insn, 0, nregs) =
3638 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3641 for (regno = start_reg, off = 0;
3642 regno <= end_reg;
3643 regno++, indx++, off += UNITS_PER_WORD)
3645 reg = gen_rtx_REG (SImode, regno);
3646 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3647 stack_pointer_rtx,
3648 off));
3649 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3650 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3651 gmask = gmask & ~(1ULL << regno);
3654 /* Restore remaining registers using LD instructions. */
3655 for (regno = 0; regno <= GMASK_LEN; regno++)
3657 if ((gmask & (1ULL << regno)) == 0)
3658 continue;
3660 reg = gen_rtx_REG (SImode, regno);
3661 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3662 stack_pointer_rtx,
3663 off));
3664 rtx tmp = frame_move_inc (reg, mem, stack_pointer_rtx, 0);
3665 add_reg_note (tmp, REG_CFA_RESTORE, reg);
3666 off += UNITS_PER_WORD;
3669 /* Emit millicode call. */
3670 if (return_p)
3672 reg = gen_rtx_REG (Pmode, 12);
3673 frame_insn (gen_rtx_SET (reg, GEN_INT (off)));
3674 frame_allocated += off;
3675 insn = emit_jump_insn (insn);
3676 RTX_FRAME_RELATED_P (insn) = 1;
3678 else
3679 insn = frame_insn (insn);
3681 /* Add DWARF info. */
3682 for (regno = start_reg; regno <= end_reg; regno++)
3684 reg = gen_rtx_REG (SImode, regno);
3685 add_reg_note (insn, REG_CFA_RESTORE, reg);
3689 if (restore_blink && !return_p)
3691 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3692 mem = gen_frame_mem (Pmode, plus_constant (Pmode, stack_pointer_rtx,
3693 off));
3694 insn = frame_insn (gen_rtx_SET (reg, mem));
3695 add_reg_note (insn, REG_CFA_RESTORE, reg);
3698 return frame_allocated;
3701 /* Set up the stack and frame pointer (if desired) for the function. */
3703 void
3704 arc_expand_prologue (void)
3706 int size;
3707 uint64_t gmask = cfun->machine->frame_info.gmask;
3708 struct arc_frame_info *frame = &cfun->machine->frame_info;
3709 unsigned int frame_size_to_allocate;
3710 int first_offset = 0;
3711 unsigned int fn_type = arc_compute_function_type (cfun);
3712 bool save_blink = false;
3713 bool save_fp = false;
3714 bool emit_move = false;
3716 /* Naked functions don't have prologue. */
3717 if (ARC_NAKED_P (fn_type))
3719 if (flag_stack_usage_info)
3720 current_function_static_stack_size = 0;
3721 return;
3724 /* Compute total frame size. */
3725 size = arc_compute_frame_size ();
3727 if (flag_stack_usage_info)
3728 current_function_static_stack_size = size;
3730 /* Keep track of frame size to be allocated. */
3731 frame_size_to_allocate = size;
3733 /* These cases shouldn't happen. Catch them now. */
3734 gcc_assert (!(size == 0 && gmask));
3736 /* Allocate space for register arguments if this is a variadic function. */
3737 if (frame->pretend_size != 0)
3738 first_offset = -frame->pretend_size;
3740 /* IRQ using automatic save mechanism will save the register before
3741 anything we do. */
3742 if (ARC_AUTO_IRQ_P (fn_type)
3743 && !ARC_FAST_INTERRUPT_P (fn_type))
3745 frame_stack_add (first_offset);
3746 first_offset = 0;
3747 arc_dwarf_emit_irq_save_regs ();
3750 save_blink = arc_must_save_return_addr (cfun)
3751 && !ARC_AUTOBLINK_IRQ_P (fn_type);
3752 save_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type)
3753 && !ARC_INTERRUPT_P (fn_type);
3754 emit_move = arc_frame_pointer_needed () && !ARC_INTERRUPT_P (fn_type);
3756 /* Use enter/leave only for non-interrupt functions. */
3757 if (TARGET_CODE_DENSITY
3758 && TARGET_CODE_DENSITY_FRAME
3759 && !ARC_AUTOFP_IRQ_P (fn_type)
3760 && !ARC_AUTOBLINK_IRQ_P (fn_type)
3761 && !ARC_INTERRUPT_P (fn_type)
3762 && arc_enter_leave_p (gmask))
3763 frame_size_to_allocate -= arc_save_callee_enter (gmask, save_blink,
3764 save_fp,
3765 first_offset);
3766 else if (frame->millicode_end_reg > 14)
3767 frame_size_to_allocate -= arc_save_callee_milli (gmask, save_blink,
3768 save_fp,
3769 first_offset,
3770 frame->reg_size);
3771 else
3772 frame_size_to_allocate -= arc_save_callee_saves (gmask, save_blink, save_fp,
3773 first_offset, emit_move);
3775 /* Check if we need to save the ZOL machinery. */
3776 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
3778 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3779 emit_insn (gen_rtx_SET (reg0,
3780 gen_rtx_UNSPEC_VOLATILE
3781 (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_START)),
3782 VUNSPEC_ARC_LR)));
3783 frame_size_to_allocate -= push_reg (reg0);
3784 emit_insn (gen_rtx_SET (reg0,
3785 gen_rtx_UNSPEC_VOLATILE
3786 (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_END)),
3787 VUNSPEC_ARC_LR)));
3788 frame_size_to_allocate -= push_reg (reg0);
3789 emit_move_insn (reg0, gen_rtx_REG (SImode, LP_COUNT));
3790 frame_size_to_allocate -= push_reg (reg0);
3793 /* Save AUX regs used by FPX machinery. */
3794 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
3795 cfun, TARGET_DPFP))
3797 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3798 int i;
3800 for (i = 0; i < 4; i++)
3802 emit_insn (gen_rtx_SET (reg0,
3803 gen_rtx_UNSPEC_VOLATILE
3804 (Pmode, gen_rtvec (1, GEN_INT (AUX_DPFP_START
3805 + i)),
3806 VUNSPEC_ARC_LR)));
3807 frame_size_to_allocate -= push_reg (reg0);
3811 /* Save accumulator registers. */
3812 if (arc_must_save_register (R58_REG, cfun, true))
3813 frame_size_to_allocate -= arc_save_callee_saves (3ULL << 58,
3814 false, false, 0, false);
3816 if (arc_frame_pointer_needed () && ARC_INTERRUPT_P (fn_type))
3818 /* Just save fp at the end of the saving context. */
3819 frame_size_to_allocate -=
3820 arc_save_callee_saves (0, false, !ARC_AUTOFP_IRQ_P (fn_type), 0, true);
3823 /* Allocate the stack frame. */
3824 if (frame_size_to_allocate > 0)
3825 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3827 /* Emit a blockage to avoid delay slot scheduling. */
3828 emit_insn (gen_blockage ());
3831 /* Return the register number of the register holding the return address
3832 for a function of type TYPE. */
3834 static int
3835 arc_return_address_register (unsigned int fn_type)
3837 int regno = 0;
3839 if (ARC_INTERRUPT_P (fn_type))
3841 if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
3842 regno = ILINK1_REG;
3843 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
3844 regno = ILINK2_REG;
3845 else
3846 gcc_unreachable ();
3848 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
3849 regno = RETURN_ADDR_REGNUM;
3851 gcc_assert (regno != 0);
3852 return regno;
3855 /* Do any necessary cleanup after a function to restore stack, frame,
3856 and regs. */
3858 void
3859 arc_expand_epilogue (int sibcall_p)
3861 int size;
3862 unsigned int fn_type = arc_compute_function_type (cfun);
3863 unsigned int size_to_deallocate;
3864 int restored;
3865 int can_trust_sp_p = !cfun->calls_alloca;
3866 int first_offset;
3867 bool restore_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type);
3868 bool restore_blink = arc_must_save_return_addr (cfun)
3869 && !ARC_AUTOBLINK_IRQ_P (fn_type);
3870 uint64_t gmask = cfun->machine->frame_info.gmask;
3871 bool return_p = !sibcall_p && fn_type == ARC_FUNCTION_NORMAL
3872 && !cfun->machine->frame_info.pretend_size;
3873 struct arc_frame_info *frame = &cfun->machine->frame_info;
3875 /* Naked functions don't have epilogue. */
3876 if (ARC_NAKED_P (fn_type))
3877 return;
3879 size = arc_compute_frame_size ();
3880 size_to_deallocate = size;
3882 first_offset = size - (frame->pretend_size + frame->reg_size
3883 + frame->extra_size);
3885 if (!can_trust_sp_p)
3886 gcc_assert (arc_frame_pointer_needed ());
3888 /* Emit a blockage to avoid/flush all pending sp operations. */
3889 if (size)
3890 emit_insn (gen_blockage ());
3892 if (ARC_INTERRUPT_P (fn_type))
3894 /* We need to restore FP before any SP operation in an
3895 interrupt. */
3896 size_to_deallocate -= arc_restore_callee_saves (0, false,
3897 restore_fp,
3898 first_offset,
3899 size_to_deallocate);
3900 restore_fp = false;
3901 first_offset = 0;
3904 /* Restore accumulator registers. */
3905 if (arc_must_save_register (R58_REG, cfun, true))
3907 rtx insn;
3908 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3909 rtx reg1 = gen_rtx_REG (SImode, R1_REG);
3910 size_to_deallocate -= pop_reg (reg0);
3911 size_to_deallocate -= pop_reg (reg1);
3913 insn = emit_insn (gen_mulu64 (reg0, const1_rtx));
3914 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, R58_REG));
3915 RTX_FRAME_RELATED_P (insn) = 1;
3916 emit_insn (gen_arc600_stall ());
3917 insn = emit_insn (gen_rtx_UNSPEC_VOLATILE
3918 (VOIDmode, gen_rtvec (2, reg1, GEN_INT (AUX_MULHI)),
3919 VUNSPEC_ARC_SR));
3920 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, R59_REG));
3921 RTX_FRAME_RELATED_P (insn) = 1;
3924 /* Restore AUX-regs used by FPX machinery. */
3925 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
3926 cfun, TARGET_DPFP))
3928 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3929 int i;
3931 for (i = 0; i < 4; i++)
3933 size_to_deallocate -= pop_reg (reg0);
3934 emit_insn (gen_rtx_UNSPEC_VOLATILE
3935 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_DPFP_START
3936 + i)),
3937 VUNSPEC_ARC_SR));
3941 /* Check if we need to restore the ZOL machinery. */
3942 if (arc_lpcwidth !=0 && arc_must_save_register (LP_COUNT, cfun, true))
3944 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3946 size_to_deallocate -= pop_reg (reg0);
3947 emit_move_insn (gen_rtx_REG (SImode, LP_COUNT), reg0);
3949 size_to_deallocate -= pop_reg (reg0);
3950 emit_insn (gen_rtx_UNSPEC_VOLATILE
3951 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_END)),
3952 VUNSPEC_ARC_SR));
3954 size_to_deallocate -= pop_reg (reg0);
3955 emit_insn (gen_rtx_UNSPEC_VOLATILE
3956 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_START)),
3957 VUNSPEC_ARC_SR));
3960 if (TARGET_CODE_DENSITY
3961 && TARGET_CODE_DENSITY_FRAME
3962 && !ARC_AUTOFP_IRQ_P (fn_type)
3963 && !ARC_AUTOBLINK_IRQ_P (fn_type)
3964 && !ARC_INTERRUPT_P (fn_type)
3965 && arc_enter_leave_p (gmask))
3967 /* Using leave instruction. */
3968 size_to_deallocate -= arc_restore_callee_leave (gmask, restore_blink,
3969 restore_fp,
3970 return_p,
3971 first_offset);
3972 if (return_p)
3974 gcc_assert (size_to_deallocate == 0);
3975 return;
3978 else if (frame->millicode_end_reg > 14)
3980 /* Using millicode calls. */
3981 size_to_deallocate -= arc_restore_callee_milli (gmask, restore_blink,
3982 restore_fp,
3983 return_p,
3984 first_offset);
3985 if (return_p)
3987 gcc_assert (size_to_deallocate == 0);
3988 return;
3991 else
3992 size_to_deallocate -= arc_restore_callee_saves (gmask, restore_blink,
3993 restore_fp,
3994 first_offset,
3995 size_to_deallocate);
3997 /* Keep track of how much of the stack pointer we've restored. It
3998 makes the following a lot more readable. */
3999 restored = size - size_to_deallocate;
4001 if (size > restored)
4002 frame_stack_add (size - restored);
4004 /* For frames that use __builtin_eh_return, the register defined by
4005 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
4006 On eh_return paths however, the register is set to the value that
4007 should be added to the stack pointer in order to restore the
4008 correct stack pointer for the exception handling frame.
4010 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
4011 this onto the stack for eh_return frames. */
4012 if (crtl->calls_eh_return)
4013 emit_insn (gen_add2_insn (stack_pointer_rtx,
4014 EH_RETURN_STACKADJ_RTX));
4016 /* Emit the return instruction. */
4017 if (ARC_INTERRUPT_P (fn_type))
4019 rtx ra = gen_rtx_REG (Pmode, arc_return_address_register (fn_type));
4021 if (TARGET_V2)
4022 emit_jump_insn (gen_rtie ());
4023 else if (TARGET_ARC700)
4024 emit_jump_insn (gen_rtie ());
4025 else
4026 emit_jump_insn (gen_arc600_rtie (ra));
4028 else if (sibcall_p == FALSE)
4029 emit_jump_insn (gen_simple_return ());
4032 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable
4033 construct to match either enter or leave instruction. Which one
4034 which is selected by PUSH_P argument. */
4036 bool
4037 arc_check_multi (rtx op, bool push_p)
4039 HOST_WIDE_INT len = XVECLEN (op, 0);
4040 unsigned int regno, i, start;
4041 unsigned int memp = push_p ? 0 : 1;
4042 rtx elt;
4044 if (len <= 1)
4045 return false;
4047 start = 1;
4048 elt = XVECEXP (op, 0, 0);
4049 if (!push_p && GET_CODE (elt) == RETURN)
4050 start = 2;
4052 for (i = start, regno = ENTER_LEAVE_START_REG; i < len; i++, regno++)
4054 rtx elt = XVECEXP (op, 0, i);
4055 rtx reg, mem, addr;
4057 if (GET_CODE (elt) != SET)
4058 return false;
4059 mem = XEXP (elt, memp);
4060 reg = XEXP (elt, 1 - memp);
4062 if (!REG_P (reg)
4063 || !MEM_P (mem))
4064 return false;
4066 /* Check for blink. */
4067 if (REGNO (reg) == RETURN_ADDR_REGNUM
4068 && i == start)
4069 regno = 12;
4070 else if (REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
4071 ++i;
4072 else if (REGNO (reg) != regno)
4073 return false;
4075 addr = XEXP (mem, 0);
4076 if (GET_CODE (addr) == PLUS)
4078 if (!rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
4079 || !CONST_INT_P (XEXP (addr, 1)))
4080 return false;
4082 else
4084 if (!rtx_equal_p (stack_pointer_rtx, addr))
4085 return false;
4088 return true;
4091 /* Return rtx for the location of the return address on the stack,
4092 suitable for use in __builtin_eh_return. The new return address
4093 will be written to this location in order to redirect the return to
4094 the exception handler. Our ABI says the blink is pushed first on
4095 stack followed by an unknown number of register saves, and finally
4096 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the
4097 stack is not finalized. */
4099 void
4100 arc_eh_return_address_location (rtx source)
4102 rtx mem;
4103 int offset;
4104 struct arc_frame_info *afi;
4106 arc_compute_frame_size ();
4107 afi = &cfun->machine->frame_info;
4109 gcc_assert (crtl->calls_eh_return);
4110 gcc_assert (afi->save_return_addr);
4111 gcc_assert (afi->extra_size >= 4);
4113 /* The '-4' removes the size of the return address, which is
4114 included in the 'extra_size' field. */
4115 offset = afi->reg_size + afi->extra_size - 4;
4116 mem = gen_frame_mem (Pmode,
4117 plus_constant (Pmode, hard_frame_pointer_rtx, offset));
4119 /* The following should not be needed, and is, really a hack. The
4120 issue being worked around here is that the DSE (Dead Store
4121 Elimination) pass will remove this write to the stack as it sees
4122 a single store and no corresponding read. The read however
4123 occurs in the epilogue code, which is not added into the function
4124 rtl until a later pass. So, at the time of DSE, the decision to
4125 remove this store seems perfectly sensible. Marking the memory
4126 address as volatile obviously has the effect of preventing DSE
4127 from removing the store. */
4128 MEM_VOLATILE_P (mem) = true;
4129 emit_move_insn (mem, source);
4132 /* PIC */
4134 /* Helper to generate unspec constant. */
4136 static rtx
4137 arc_unspec_offset (rtx loc, int unspec)
4139 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
4140 unspec));
4143 /* Predicate for pre-reload splitters with associated instructions,
4144 which can match any time before the split1 pass (usually combine),
4145 then are unconditionally split in that pass and should not be
4146 matched again afterwards. */
4148 bool
4149 arc_pre_reload_split (void)
4151 return (can_create_pseudo_p ()
4152 && !(cfun->curr_properties & PROP_rtl_split_insns));
4155 /* Output the assembler code for a zero-overhead loop doing a shift
4156 or rotate. We know OPERANDS[0] == OPERANDS[1], and the bit count
4157 is OPERANDS[2]. */
4159 const char *
4160 output_shift_loop (enum rtx_code code, rtx *operands)
4162 bool twice_p = false;
4163 gcc_assert (GET_MODE (operands[0]) == SImode);
4165 if (GET_CODE (operands[2]) != CONST_INT)
4167 output_asm_insn ("and.f\tlp_count,%2,0x1f", operands);
4168 output_asm_insn ("lpnz\t2f", operands);
4170 else
4172 int n = INTVAL (operands[2]) & 31;
4173 if (!n)
4175 output_asm_insn ("mov\t%0,%1",operands);
4176 return "";
4179 if ((n & 1) == 0 && code != ROTATE)
4181 twice_p = true;
4182 n >>= 1;
4184 operands[2] = GEN_INT (n);
4185 output_asm_insn ("mov\tlp_count,%2", operands);
4186 output_asm_insn ("lp\t2f", operands);
4189 switch (code)
4191 case ASHIFT:
4192 output_asm_insn ("add\t%0,%1,%1", operands);
4193 if (twice_p)
4194 output_asm_insn ("add\t%0,%1,%1", operands);
4195 break;
4196 case ASHIFTRT:
4197 output_asm_insn ("asr\t%0,%1", operands);
4198 if (twice_p)
4199 output_asm_insn ("asr\t%0,%1", operands);
4200 break;
4201 case LSHIFTRT:
4202 output_asm_insn ("lsr\t%0,%1", operands);
4203 if (twice_p)
4204 output_asm_insn ("lsr\t%0,%1", operands);
4205 break;
4206 case ROTATERT:
4207 output_asm_insn ("ror\t%0,%1", operands);
4208 if (twice_p)
4209 output_asm_insn ("ror\t%0,%1", operands);
4210 break;
4211 case ROTATE:
4212 output_asm_insn ("add.f\t%0,%1,%1", operands);
4213 output_asm_insn ("adc\t%0,%0,0", operands);
4214 twice_p = true;
4215 break;
4216 default:
4217 gcc_unreachable ();
4220 if (!twice_p)
4221 output_asm_insn ("nop", operands);
4222 fprintf (asm_out_file, "2:\t%s end single insn loop\n", ASM_COMMENT_START);
4223 return "";
4226 /* See below where shifts are handled for explanation of this enum. */
4227 enum arc_shift_alg
4229 SHIFT_MOVE, /* Register-to-register move. */
4230 SHIFT_LOOP, /* Zero-overhead loop implementation. */
4231 SHIFT_INLINE, /* Mmultiple LSHIFTs and LSHIFT-PLUSs. */
4232 SHIFT_AND_ROT, /* Bitwise AND, then ROTATERTs. */
4233 SHIFT_SWAP, /* SWAP then multiple LSHIFTs/LSHIFT-PLUSs. */
4234 SHIFT_AND_SWAP_ROT /* Bitwise AND, then SWAP, then ROTATERTs. */
4237 struct arc_shift_info {
4238 enum arc_shift_alg alg;
4239 unsigned int cost;
4242 /* Return shift algorithm context, an index into the following tables.
4243 * 0 for -Os (optimize for size) 3 for -O2 (optimized for speed)
4244 * 1 for -Os -mswap TARGET_V2 4 for -O2 -mswap TARGET_V2
4245 * 2 for -Os -mswap !TARGET_V2 5 for -O2 -mswap !TARGET_V2 */
4246 static unsigned int
4247 arc_shift_context_idx ()
4249 if (optimize_function_for_size_p (cfun))
4251 if (!TARGET_SWAP)
4252 return 0;
4253 if (TARGET_V2)
4254 return 1;
4255 return 2;
4257 else
4259 if (!TARGET_SWAP)
4260 return 3;
4261 if (TARGET_V2)
4262 return 4;
4263 return 5;
4267 static const arc_shift_info arc_ashl_alg[6][32] = {
4268 { /* 0: -Os. */
4269 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4270 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4271 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4272 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4273 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4274 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4275 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4276 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4277 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4278 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4279 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 10 */
4280 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 11 */
4281 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 12 */
4282 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 13 */
4283 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 14 */
4284 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 15 */
4285 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 16 */
4286 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 17 */
4287 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 18 */
4288 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 19 */
4289 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 20 */
4290 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 21 */
4291 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 22 */
4292 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 23 */
4293 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 24 */
4294 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 25 */
4295 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 26 */
4296 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 27 */
4297 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 28 */
4298 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4299 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4300 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4302 { /* 1: -Os -mswap TARGET_V2. */
4303 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4304 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4305 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4306 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4307 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4308 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4309 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4310 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4311 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4312 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4313 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 10 */
4314 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 11 */
4315 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 12 */
4316 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 13 */
4317 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4318 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4319 { SHIFT_SWAP, COSTS_N_INSNS (1) }, /* 16 */
4320 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 17 */
4321 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 18 */
4322 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 19 */
4323 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 20 */
4324 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 21 */
4325 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 22 */
4326 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 23 */
4327 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 24 */
4328 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 25 */
4329 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 26 */
4330 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 27 */
4331 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 28 */
4332 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4333 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4334 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4336 { /* 2: -Os -mswap !TARGET_V2. */
4337 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4338 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4339 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4340 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4341 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4342 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4343 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4344 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4345 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4346 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4347 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 10 */
4348 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 11 */
4349 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 12 */
4350 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 13 */
4351 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4352 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4353 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 16 */
4354 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 17 */
4355 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 18 */
4356 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 19 */
4357 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 20 */
4358 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 21 */
4359 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 22 */
4360 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 23 */
4361 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 24 */
4362 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 25 */
4363 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 26 */
4364 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 27 */
4365 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 28 */
4366 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4367 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4368 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4370 { /* 3: -O2. */
4371 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4372 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4373 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4374 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4375 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4376 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4377 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4378 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4379 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4380 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4381 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 10 */
4382 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 11 */
4383 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 12 */
4384 { SHIFT_INLINE, COSTS_N_INSNS (6) }, /* 13 */
4385 { SHIFT_INLINE, COSTS_N_INSNS (6) }, /* 14 */
4386 { SHIFT_INLINE, COSTS_N_INSNS (6) }, /* 15 */
4387 { SHIFT_INLINE, COSTS_N_INSNS (7) }, /* 16 */
4388 { SHIFT_INLINE, COSTS_N_INSNS (7) }, /* 17 */
4389 { SHIFT_INLINE, COSTS_N_INSNS (7) }, /* 18 */
4390 { SHIFT_INLINE, COSTS_N_INSNS (8) }, /* 19 */
4391 { SHIFT_INLINE, COSTS_N_INSNS (8) }, /* 20 */
4392 { SHIFT_INLINE, COSTS_N_INSNS (8) }, /* 21 */
4393 { SHIFT_INLINE, COSTS_N_INSNS (9) }, /* 22 */
4394 { SHIFT_INLINE, COSTS_N_INSNS (9) }, /* 23 */
4395 { SHIFT_AND_ROT, COSTS_N_INSNS (9) }, /* 24 */
4396 { SHIFT_AND_ROT, COSTS_N_INSNS (8) }, /* 25 */
4397 { SHIFT_AND_ROT, COSTS_N_INSNS (7) }, /* 26 */
4398 { SHIFT_AND_ROT, COSTS_N_INSNS (6) }, /* 27 */
4399 { SHIFT_AND_ROT, COSTS_N_INSNS (5) }, /* 28 */
4400 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4401 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4402 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4404 { /* 4: -O2 -mswap TARGET_V2. */
4405 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4406 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4407 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4408 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4409 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4410 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4411 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4412 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4413 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4414 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4415 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 10 */
4416 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 11 */
4417 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 12 */
4418 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (5) }, /* 13 */
4419 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4420 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4421 { SHIFT_SWAP, COSTS_N_INSNS (1) }, /* 16 */
4422 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 17 */
4423 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 18 */
4424 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 19 */
4425 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 20 */
4426 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 21 */
4427 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 22 */
4428 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 23 */
4429 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 24 */
4430 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 25 */
4431 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 26 */
4432 { SHIFT_AND_ROT, COSTS_N_INSNS (6) }, /* 27 */
4433 { SHIFT_AND_ROT, COSTS_N_INSNS (5) }, /* 28 */
4434 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4435 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4436 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4438 { /* 5: -O2 -mswap !TARGET_V2. */
4439 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4440 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4441 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4442 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4443 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4444 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4445 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4446 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4447 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4448 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4449 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 10 */
4450 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 11 */
4451 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 12 */
4452 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (5) }, /* 13 */
4453 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4454 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4455 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 16 */
4456 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 17 */
4457 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 18 */
4458 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 19 */
4459 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 20 */
4460 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 21 */
4461 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 22 */
4462 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 23 */
4463 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 24 */
4464 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 25 */
4465 { SHIFT_AND_ROT, COSTS_N_INSNS (7) }, /* 26 */
4466 { SHIFT_AND_ROT, COSTS_N_INSNS (6) }, /* 27 */
4467 { SHIFT_AND_ROT, COSTS_N_INSNS (5) }, /* 28 */
4468 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4469 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4470 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4474 /* Split SImode left shift instruction. */
4475 void
4476 arc_split_ashl (rtx *operands)
4478 if (CONST_INT_P (operands[2]))
4480 int n = INTVAL (operands[2]) & 0x1f;
4481 switch (arc_ashl_alg [arc_shift_context_idx ()][n].alg)
4483 case SHIFT_MOVE:
4484 emit_move_insn (operands[0], operands[1]);
4485 return;
4487 case SHIFT_SWAP:
4488 if (!TARGET_V2)
4490 emit_insn (gen_andsi3_i (operands[0], operands[1],
4491 GEN_INT (0xffff)));
4492 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[0]));
4494 else
4495 emit_insn (gen_ashlsi2_cnt16 (operands[0], operands[1]));
4496 n -= 16;
4497 if (n == 0)
4498 return;
4499 operands[1] = operands[0];
4500 /* FALL THRU */
4502 case SHIFT_INLINE:
4503 if (n <= 2)
4505 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
4506 if (n == 2)
4507 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
4509 else
4511 rtx zero = gen_reg_rtx (SImode);
4512 emit_move_insn (zero, const0_rtx);
4513 emit_insn (gen_add_shift (operands[0], operands[1],
4514 GEN_INT (3), zero));
4515 for (n -= 3; n >= 3; n -= 3)
4516 emit_insn (gen_add_shift (operands[0], operands[0],
4517 GEN_INT (3), zero));
4518 if (n == 2)
4519 emit_insn (gen_add_shift (operands[0], operands[0],
4520 const2_rtx, zero));
4521 else if (n)
4522 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
4524 return;
4526 case SHIFT_AND_ROT:
4527 emit_insn (gen_andsi3_i (operands[0], operands[1],
4528 GEN_INT ((1 << (32 - n)) - 1)));
4529 for (; n < 32; n++)
4530 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4531 return;
4533 case SHIFT_AND_SWAP_ROT:
4534 emit_insn (gen_andsi3_i (operands[0], operands[1],
4535 GEN_INT ((1 << (32 - n)) - 1)));
4536 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[0]));
4537 for (; n < 16; n++)
4538 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4539 return;
4541 case SHIFT_LOOP:
4542 break;
4544 default:
4545 gcc_unreachable ();
4549 emit_insn (gen_ashlsi3_loop (operands[0], operands[1], operands[2]));
4552 /* Split SImode arithmetic right shift instruction. */
4553 void
4554 arc_split_ashr (rtx *operands)
4556 if (CONST_INT_P (operands[2]))
4558 int n = INTVAL (operands[2]) & 0x1f;
4559 if (n <= 4)
4561 if (n != 0)
4563 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
4564 while (--n > 0)
4565 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
4567 else
4568 emit_move_insn (operands[0], operands[1]);
4569 return;
4571 else if (n >= 16 && n <= 18 && TARGET_SWAP)
4573 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4574 emit_insn (gen_extendhisi2 (operands[0],
4575 gen_lowpart (HImode, operands[0])));
4576 while (--n >= 16)
4577 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
4578 return;
4580 else if (n == 30)
4582 rtx tmp = gen_reg_rtx (SImode);
4583 emit_insn (gen_add_f (tmp, operands[1], operands[1]));
4584 emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
4585 emit_insn (gen_addsi_compare_2 (tmp, tmp));
4586 emit_insn (gen_adc (operands[0], operands[0], operands[0]));
4587 return;
4589 else if (n == 31)
4591 emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
4592 emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
4593 return;
4597 emit_insn (gen_ashrsi3_loop (operands[0], operands[1], operands[2]));
4600 /* Split SImode logical right shift instruction. */
4601 void
4602 arc_split_lshr (rtx *operands)
4604 if (CONST_INT_P (operands[2]))
4606 int n = INTVAL (operands[2]) & 0x1f;
4607 if (n <= 4)
4609 if (n != 0)
4611 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
4612 while (--n > 0)
4613 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
4615 else
4616 emit_move_insn (operands[0], operands[1]);
4617 return;
4619 else if (n >= 16 && n <= 19 && TARGET_SWAP && TARGET_V2)
4621 emit_insn (gen_lshrsi2_cnt16 (operands[0], operands[1]));
4622 while (--n >= 16)
4623 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
4624 return;
4626 else if (n == 30)
4628 rtx tmp = gen_reg_rtx (SImode);
4629 emit_insn (gen_add_f (tmp, operands[1], operands[1]));
4630 emit_insn (gen_scc_ltu_cc_c (operands[0]));
4631 emit_insn (gen_addsi_compare_2 (tmp, tmp));
4632 emit_insn (gen_adc (operands[0], operands[0], operands[0]));
4633 return;
4635 else if (n == 31)
4637 emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
4638 emit_insn (gen_scc_ltu_cc_c (operands[0]));
4639 return;
4643 emit_insn (gen_lshrsi3_loop (operands[0], operands[1], operands[2]));
4646 /* Split SImode rotate left instruction. */
4647 void
4648 arc_split_rotl (rtx *operands)
4650 if (CONST_INT_P (operands[2]))
4652 int n = INTVAL (operands[2]) & 0x1f;
4653 if (n <= 2)
4655 if (n != 0)
4657 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
4658 if (n == 2)
4659 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4661 else
4662 emit_move_insn (operands[0], operands[1]);
4663 return;
4665 else if (n >= 28)
4667 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
4668 while (++n < 32)
4669 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4670 return;
4672 else if (n >= 13 && n <= 16 && TARGET_SWAP)
4674 emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
4675 while (++n <= 16)
4676 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4677 return;
4679 else if (n == 17 && TARGET_SWAP)
4681 emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
4682 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4683 return;
4685 else if (n >= 16 || n == 12 || n == 14)
4687 emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
4688 GEN_INT (32 - n)));
4689 return;
4693 emit_insn (gen_rotlsi3_loop (operands[0], operands[1], operands[2]));
4696 /* Split SImode rotate right instruction. */
4697 void
4698 arc_split_rotr (rtx *operands)
4700 if (CONST_INT_P (operands[2]))
4702 int n = INTVAL (operands[2]) & 0x1f;
4703 if (n <= 4)
4705 if (n != 0)
4707 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
4708 while (--n > 0)
4709 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4711 else
4712 emit_move_insn (operands[0], operands[1]);
4713 return;
4715 else if (n == 15 && TARGET_SWAP)
4717 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4718 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4719 return;
4721 else if (n >= 16 && n <= 19 && TARGET_SWAP)
4723 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4724 while (--n >= 16)
4725 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4726 return;
4728 else if (n >= 30)
4730 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
4731 if (n == 31)
4732 emit_insn (gen_rotlsi3_cnt1 (operands[1], operands[1]));
4733 return;
4735 else if (n >= 21 || n == 17 || n == 19)
4737 emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
4738 GEN_INT (32 - n)));
4739 return;
4743 emit_insn (gen_rotrsi3_loop (operands[0], operands[1], operands[2]));
4746 /* Nested function support. */
4748 /* Output assembler code for a block containing the constant parts of
4749 a trampoline, leaving space for variable parts. A trampoline looks
4750 like this:
4752 ld_s r12,[pcl,8]
4753 ld r11,[pcl,12]
4754 j_s [r12]
4755 .word function's address
4756 .word static chain value
4760 static void
4761 arc_asm_trampoline_template (FILE *f)
4763 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG);
4764 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]);
4765 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG);
4766 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4767 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4770 /* Emit RTL insns to initialize the variable parts of a trampoline.
4771 FNADDR is an RTX for the address of the function's pure code. CXT
4772 is an RTX for the static chain value for the function.
4774 The fastest trampoline to execute for trampolines within +-8KB of CTX
4775 would be:
4777 add2 r11,pcl,s12
4778 j [limm] 0x20200f80 limm
4780 and that would also be faster to write to the stack by computing
4781 the offset from CTX to TRAMP at compile time. However, it would
4782 really be better to get rid of the high cost of cache invalidation
4783 when generating trampolines, which requires that the code part of
4784 trampolines stays constant, and additionally either making sure
4785 that no executable code but trampolines is on the stack, no icache
4786 entries linger for the area of the stack from when before the stack
4787 was allocated, and allocating trampolines in trampoline-only cache
4788 lines or allocate trampolines fram a special pool of pre-allocated
4789 trampolines. */
4791 static void
4792 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
4794 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
4796 emit_block_move (tramp, assemble_trampoline_template (),
4797 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4798 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
4799 emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
4800 maybe_emit_call_builtin___clear_cache (XEXP (tramp, 0),
4801 plus_constant (Pmode,
4802 XEXP (tramp, 0),
4803 TRAMPOLINE_SIZE));
4806 /* Add the given function declaration to emit code in JLI section. */
4808 static void
4809 arc_add_jli_section (rtx pat)
4811 const char *name;
4812 tree attrs;
4813 arc_jli_section *sec = arc_jli_sections, *new_section;
4814 tree decl = SYMBOL_REF_DECL (pat);
4816 if (!pat)
4817 return;
4819 if (decl)
4821 /* For fixed locations do not generate the jli table entry. It
4822 should be provided by the user as an asm file. */
4823 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
4824 if (lookup_attribute ("jli_fixed", attrs))
4825 return;
4828 name = XSTR (pat, 0);
4830 /* Don't insert the same symbol twice. */
4831 while (sec != NULL)
4833 if(strcmp (name, sec->name) == 0)
4834 return;
4835 sec = sec->next;
4838 /* New name, insert it. */
4839 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
4840 gcc_assert (new_section != NULL);
4841 new_section->name = name;
4842 new_section->next = arc_jli_sections;
4843 arc_jli_sections = new_section;
4846 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4847 reset when we output the scaled address. */
4848 static int output_scaled = 0;
4850 /* Set when we force sdata output. */
4851 static int output_sdata = 0;
4853 /* Print operand X (an rtx) in assembler syntax to file FILE.
4854 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4855 For `%' followed by punctuation, CODE is the punctuation and X is null.
4856 In final.cc:output_asm_insn:
4857 'l' : label
4858 'a' : address
4859 'c' : constant address if CONSTANT_ADDRESS_P
4860 'n' : negative
4861 Here:
4862 'Z': log2(x+1)-1
4863 'z': log2
4864 'M': log2(~x)
4865 'p': bit Position of lsb
4866 's': scalled immediate
4867 'S': Scalled immediate, to be used in pair with 's'.
4868 'N': Negative immediate, to be used in pair with 's'.
4869 'x': size of bit field
4870 '*': jump delay slot suffix
4871 '?' : nonjump-insn suffix for conditional execution or short instruction
4874 'R': Second word
4875 'J': JLI instruction
4876 'j': used by mov instruction to properly emit jli related labels.
4877 'B': Branch comparison operand - suppress sda reference
4878 'H': Most significant word
4879 'L': Least significant word
4880 'A': ASCII decimal representation of floating point value
4881 'U': Load/store update or scaling indicator
4882 'V': cache bypass indicator for volatile
4885 'O': Operator
4886 'o': original symbol - no @ prepending. */
4888 void
4889 arc_print_operand (FILE *file, rtx x, int code)
4891 HOST_WIDE_INT ival;
4892 unsigned scalled = 0;
4893 int sign = 1;
4895 switch (code)
4897 case 'Z':
4898 if (GET_CODE (x) == CONST_INT)
4899 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
4900 else
4901 output_operand_lossage ("invalid operand to %%Z code");
4903 return;
4905 case 'z':
4906 if (GET_CODE (x) == CONST_INT)
4907 fprintf (file, "%d",exact_log2 (INTVAL (x) & 0xffffffff));
4908 else
4909 output_operand_lossage ("invalid operand to %%z code");
4911 return;
4913 case 'c':
4914 if (GET_CODE (x) == CONST_INT)
4915 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) );
4916 else
4917 output_operand_lossage ("invalid operands to %%c code");
4919 return;
4921 case 'M':
4922 if (GET_CODE (x) == CONST_INT)
4923 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
4924 else
4925 output_operand_lossage ("invalid operand to %%M code");
4927 return;
4929 case 'p':
4930 if (GET_CODE (x) == CONST_INT)
4931 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
4932 else
4933 output_operand_lossage ("invalid operand to %%p code");
4934 return;
4936 case 's':
4937 if (REG_P (x))
4938 return;
4939 if (!CONST_INT_P (x))
4941 output_operand_lossage ("invalid operand for %%s code");
4942 return;
4944 ival = INTVAL (x);
4945 if ((ival & 0x07) == 0)
4946 scalled = 3;
4947 else if ((ival & 0x03) == 0)
4948 scalled = 2;
4949 else if ((ival & 0x01) == 0)
4950 scalled = 1;
4952 if (scalled)
4953 asm_fprintf (file, "%d", scalled);
4954 return;
4956 case 'N':
4957 if (REG_P (x))
4959 output_operand_lossage ("invalid operand for %%N code");
4960 return;
4962 sign = -1;
4963 /* fall through */
4964 case 'S':
4965 if (REG_P (x))
4967 asm_fprintf (file, "%s", reg_names [REGNO (x)]);
4968 return;
4970 if (!CONST_INT_P (x))
4972 output_operand_lossage ("invalid operand for %%N or %%S code");
4973 return;
4975 ival = sign * INTVAL (x);
4976 if ((ival & 0x07) == 0)
4977 scalled = 3;
4978 else if ((ival & 0x03) == 0)
4979 scalled = 2;
4980 else if ((ival & 0x01) == 0)
4981 scalled = 1;
4983 asm_fprintf (file, "%wd", (ival >> scalled));
4984 return;
4986 case 'x':
4987 if (GET_CODE (x) == CONST_INT)
4989 HOST_WIDE_INT i = INTVAL (x);
4990 HOST_WIDE_INT s = exact_log2 (i & -i);
4991 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
4993 else
4994 output_operand_lossage ("invalid operand to %%s code");
4995 return;
4997 case '*' :
4998 /* Unconditional branches / branches not depending on condition codes.
4999 This could also be a CALL_INSN.
5000 Output the appropriate delay slot suffix. */
5001 if (final_sequence && final_sequence->len () != 1)
5003 rtx_insn *delay = final_sequence->insn (1);
5005 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
5006 if (delay->deleted ())
5007 return;
5008 fputs (".d", file);
5010 return;
5012 case '?' : /* with leading "." */
5013 case '!' : /* without leading "." */
5014 if (current_insn_predicate)
5016 int cc = get_arc_condition_code (current_insn_predicate);
5017 /* Is this insn in a delay slot sequence? */
5018 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
5019 || current_insn_predicate
5020 || CALL_P (final_sequence->insn (0))
5021 || simplejump_p (final_sequence->insn (0)))
5023 /* This insn isn't in a delay slot sequence, or conditionalized
5024 independently of its position in a delay slot. */
5025 fprintf (file, "%s%s",
5026 code == '?' ? "." : "", arc_condition_codes[cc]);
5027 /* If this is a jump, there are still short variants. However,
5028 only beq_s / bne_s have the same offset range as b_s,
5029 and the only short conditional returns are jeq_s and jne_s. */
5030 if (code == '!'
5031 && (cc == ARC_CC_EQ || cc == ARC_CC_NE))
5032 output_short_suffix (file);
5034 else if (code == '!') /* Jump with delay slot. */
5035 fputs (arc_condition_codes[cc], file);
5036 else /* An Instruction in a delay slot of a jump or call. */
5038 rtx jump = XVECEXP (final_sequence, 0, 0);
5039 rtx insn = XVECEXP (final_sequence, 0, 1);
5041 /* If the insn is annulled and is from the target path, we need
5042 to inverse the condition test. */
5043 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
5045 if (INSN_FROM_TARGET_P (insn))
5046 fprintf (file, "%s%s",
5047 code == '?' ? "." : "",
5048 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (cc)]);
5049 else
5050 fprintf (file, "%s%s",
5051 code == '?' ? "." : "",
5052 arc_condition_codes[cc]);
5054 else
5056 /* This insn is executed for either path, so don't
5057 conditionalize it at all. */
5058 output_short_suffix (file);
5062 else
5063 output_short_suffix (file);
5064 return;
5066 case 'd' :
5067 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
5068 return;
5069 case 'D' :
5070 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
5071 (get_arc_condition_code (x))],
5072 file);
5073 return;
5074 case 'R' :
5075 /* Write second word of DImode or DFmode reference,
5076 register or memory. */
5077 if (GET_CODE (x) == REG)
5078 fputs (reg_names[REGNO (x)+1], file);
5079 else if (GET_CODE (x) == MEM)
5081 fputc ('[', file);
5083 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
5084 PRE_MODIFY, we will have handled the first word already;
5085 For POST_INC / POST_DEC / POST_MODIFY, the access to the
5086 first word will be done later. In either case, the access
5087 to the first word will do the modify, and we only have
5088 to add an offset of four here. */
5089 if (GET_CODE (XEXP (x, 0)) == PRE_INC
5090 || GET_CODE (XEXP (x, 0)) == PRE_DEC
5091 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
5092 || GET_CODE (XEXP (x, 0)) == POST_INC
5093 || GET_CODE (XEXP (x, 0)) == POST_DEC
5094 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
5095 output_address (VOIDmode,
5096 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
5097 else if (output_scaled)
5099 rtx addr = XEXP (x, 0);
5100 int size = GET_MODE_SIZE (GET_MODE (x));
5102 output_address (VOIDmode,
5103 plus_constant (Pmode, XEXP (addr, 0),
5104 ((INTVAL (XEXP (addr, 1)) + 4)
5105 >> (size == 2 ? 1 : 2))));
5106 output_scaled = 0;
5108 else
5109 output_address (VOIDmode,
5110 plus_constant (Pmode, XEXP (x, 0), 4));
5111 fputc (']', file);
5113 else
5114 output_operand_lossage ("invalid operand to %%R code");
5115 return;
5116 case 'j':
5117 case 'J' :
5118 if (GET_CODE (x) == SYMBOL_REF
5119 && arc_is_jli_call_p (x))
5121 if (SYMBOL_REF_DECL (x))
5123 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
5124 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
5125 : NULL_TREE);
5126 if (lookup_attribute ("jli_fixed", attrs))
5128 /* No special treatment for jli_fixed functions. */
5129 if (code == 'j')
5130 break;
5131 fprintf (file, HOST_WIDE_INT_PRINT_DEC "\t; @",
5132 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
5133 assemble_name (file, XSTR (x, 0));
5134 return;
5137 fprintf (file, "@__jli.");
5138 assemble_name (file, XSTR (x, 0));
5139 if (code == 'j')
5140 arc_add_jli_section (x);
5141 return;
5143 if (GET_CODE (x) == SYMBOL_REF
5144 && arc_is_secure_call_p (x))
5146 /* No special treatment for secure functions. */
5147 if (code == 'j' )
5148 break;
5149 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
5150 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
5151 : NULL_TREE);
5152 fprintf (file, HOST_WIDE_INT_PRINT_DEC "\t; @",
5153 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
5154 assemble_name (file, XSTR (x, 0));
5155 return;
5157 break;
5158 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
5159 if (CONSTANT_P (x))
5161 output_addr_const (file, x);
5162 return;
5164 break;
5165 case 'H' :
5166 case 'L' :
5167 if (GET_CODE (x) == REG)
5169 /* L = least significant word, H = most significant word. */
5170 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
5171 fputs (reg_names[REGNO (x)], file);
5172 else
5173 fputs (reg_names[REGNO (x)+1], file);
5175 else if (GET_CODE (x) == CONST_INT
5176 || GET_CODE (x) == CONST_DOUBLE)
5178 rtx first, second, word;
5180 split_double (x, &first, &second);
5182 if((WORDS_BIG_ENDIAN) == 0)
5183 word = (code == 'L' ? first : second);
5184 else
5185 word = (code == 'L' ? second : first);
5187 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
5189 else
5190 output_operand_lossage ("invalid operand to %%H/%%L code");
5191 return;
5192 case 'A' :
5194 char str[30];
5196 gcc_assert (GET_CODE (x) == CONST_DOUBLE
5197 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
5199 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
5200 fprintf (file, "%s", str);
5201 return;
5203 case 'U' :
5204 /* Output a load/store with update indicator if appropriate. */
5205 if (GET_CODE (x) == MEM)
5207 rtx addr = XEXP (x, 0);
5208 switch (GET_CODE (addr))
5210 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
5211 fputs (".a", file); break;
5212 case POST_INC: case POST_DEC: case POST_MODIFY:
5213 fputs (".ab", file); break;
5214 case PLUS:
5215 /* Are we using a scaled index? */
5216 if (GET_CODE (XEXP (addr, 0)) == MULT)
5217 fputs (".as", file);
5218 /* Can we use a scaled offset? */
5219 else if (CONST_INT_P (XEXP (addr, 1))
5220 && GET_MODE_SIZE (GET_MODE (x)) > 1
5221 && (!(INTVAL (XEXP (addr, 1))
5222 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
5223 /* Does it make a difference? */
5224 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
5225 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
5227 fputs (".as", file);
5228 output_scaled = 1;
5230 break;
5231 case SYMBOL_REF:
5232 case CONST:
5233 if (legitimate_small_data_address_p (addr, GET_MODE (x))
5234 && GET_MODE_SIZE (GET_MODE (x)) > 1)
5236 int align = get_symbol_alignment (addr);
5237 int mask = 0;
5238 switch (GET_MODE (x))
5240 case E_HImode:
5241 mask = 1;
5242 break;
5243 default:
5244 mask = 3;
5245 break;
5247 if (align && ((align & mask) == 0))
5248 fputs (".as", file);
5250 break;
5251 case REG:
5252 break;
5253 default:
5254 gcc_assert (CONSTANT_P (addr)); break;
5257 else
5258 output_operand_lossage ("invalid operand to %%U code");
5259 return;
5260 case 'V' :
5261 /* Output cache bypass indicator for a load/store insn. Volatile memory
5262 refs are defined to use the cache bypass mechanism. */
5263 if (GET_CODE (x) == MEM)
5265 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
5266 || arc_is_uncached_mem_p (x))
5267 fputs (".di", file);
5269 else
5270 output_operand_lossage ("invalid operand to %%V code");
5271 return;
5272 /* plt code. */
5273 case 'P':
5274 case 0 :
5275 /* Do nothing special. */
5276 break;
5277 case 'F':
5278 fputs (reg_names[REGNO (x)]+1, file);
5279 return;
5281 case 'O':
5282 /* Output an operator. */
5283 switch (GET_CODE (x))
5285 case PLUS: fputs ("add", file); return;
5286 case SS_PLUS: fputs ("adds", file); return;
5287 case AND: fputs ("and", file); return;
5288 case IOR: fputs ("or", file); return;
5289 case XOR: fputs ("xor", file); return;
5290 case MINUS: fputs ("sub", file); return;
5291 case SS_MINUS: fputs ("subs", file); return;
5292 case ASHIFT: fputs ("asl", file); return;
5293 case ASHIFTRT: fputs ("asr", file); return;
5294 case LSHIFTRT: fputs ("lsr", file); return;
5295 case ROTATERT: fputs ("ror", file); return;
5296 case MULT: fputs ("mpy", file); return;
5297 case ABS: fputs ("abs", file); return; /* Unconditional. */
5298 case NEG: fputs ("neg", file); return;
5299 case SS_NEG: fputs ("negs", file); return;
5300 case NOT: fputs ("not", file); return; /* Unconditional. */
5301 case ZERO_EXTEND:
5302 fputs ("ext", file); /* bmsk allows predication. */
5303 goto size_suffix;
5304 case SIGN_EXTEND: /* Unconditional. */
5305 fputs ("sex", file);
5306 size_suffix:
5307 switch (GET_MODE (XEXP (x, 0)))
5309 case E_QImode: fputs ("b", file); return;
5310 case E_HImode: fputs ("w", file); return;
5311 default: break;
5313 break;
5314 case SS_TRUNCATE:
5315 if (GET_MODE (x) != HImode)
5316 break;
5317 fputs ("sat16", file);
5318 default: break;
5320 output_operand_lossage ("invalid operand to %%O code"); return;
5321 case 'o':
5322 if (GET_CODE (x) == SYMBOL_REF)
5324 assemble_name (file, XSTR (x, 0));
5325 return;
5327 break;
5329 case '+':
5330 if (TARGET_V2)
5331 fputs ("m", file);
5332 else
5333 fputs ("h", file);
5334 return;
5335 case '_':
5336 if (TARGET_V2)
5337 fputs ("h", file);
5338 else
5339 fputs ("w", file);
5340 return;
5341 default :
5342 /* Unknown flag. */
5343 output_operand_lossage ("invalid operand output code");
5346 switch (GET_CODE (x))
5348 case REG :
5349 fputs (reg_names[REGNO (x)], file);
5350 break;
5351 case MEM :
5353 rtx addr = XEXP (x, 0);
5354 int size = GET_MODE_SIZE (GET_MODE (x));
5356 if (legitimate_small_data_address_p (addr, GET_MODE (x)))
5357 output_sdata = 1;
5359 fputc ('[', file);
5361 switch (GET_CODE (addr))
5363 case PRE_INC: case POST_INC:
5364 output_address (VOIDmode,
5365 plus_constant (Pmode, XEXP (addr, 0), size)); break;
5366 case PRE_DEC: case POST_DEC:
5367 output_address (VOIDmode,
5368 plus_constant (Pmode, XEXP (addr, 0), -size));
5369 break;
5370 case PRE_MODIFY: case POST_MODIFY:
5371 output_address (VOIDmode, XEXP (addr, 1)); break;
5372 case PLUS:
5373 if (output_scaled)
5375 output_address (VOIDmode,
5376 plus_constant (Pmode, XEXP (addr, 0),
5377 (INTVAL (XEXP (addr, 1))
5378 >> (size == 2 ? 1 : 2))));
5379 output_scaled = 0;
5381 else
5382 output_address (VOIDmode, addr);
5383 break;
5384 default:
5385 if (flag_pic && CONSTANT_ADDRESS_P (addr))
5386 arc_output_pic_addr_const (file, addr, code);
5387 else
5388 output_address (VOIDmode, addr);
5389 break;
5391 fputc (']', file);
5392 break;
5394 case CONST_DOUBLE :
5395 /* We handle SFmode constants here as output_addr_const doesn't. */
5396 if (GET_MODE (x) == SFmode)
5398 long l;
5400 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
5401 fprintf (file, "0x%08lx", l);
5402 break;
5404 /* FALLTHRU */
5405 /* Let output_addr_const deal with it. */
5406 default :
5407 if (flag_pic
5408 || (GET_CODE (x) == CONST
5409 && GET_CODE (XEXP (x, 0)) == UNSPEC
5410 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
5411 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
5412 || (GET_CODE (x) == CONST
5413 && GET_CODE (XEXP (x, 0)) == PLUS
5414 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
5415 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
5416 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
5417 arc_output_pic_addr_const (file, x, code);
5418 else
5419 output_addr_const (file, x);
5420 break;
5424 /* Print a memory address as an operand to reference that memory location. */
5426 void
5427 arc_print_operand_address (FILE *file , rtx addr)
5429 rtx base, index = 0;
5431 switch (GET_CODE (addr))
5433 case REG :
5434 fputs (reg_names[REGNO (addr)], file);
5435 break;
5436 case SYMBOL_REF:
5437 if (output_sdata)
5438 fputs ("gp,", file);
5439 output_addr_const (file, addr);
5440 if (output_sdata)
5441 fputs ("@sda", file);
5442 output_sdata = 0;
5443 break;
5444 case PLUS :
5445 if (GET_CODE (XEXP (addr, 0)) == MULT)
5446 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
5447 else if (CONST_INT_P (XEXP (addr, 0)))
5448 index = XEXP (addr, 0), base = XEXP (addr, 1);
5449 else
5450 base = XEXP (addr, 0), index = XEXP (addr, 1);
5452 gcc_assert (OBJECT_P (base));
5453 arc_print_operand_address (file, base);
5454 if (CONSTANT_P (base) && CONST_INT_P (index))
5455 fputc ('+', file);
5456 else
5457 fputc (',', file);
5458 gcc_assert (OBJECT_P (index));
5459 arc_print_operand_address (file, index);
5460 break;
5461 case CONST:
5463 rtx c = XEXP (addr, 0);
5465 if ((GET_CODE (c) == UNSPEC
5466 && (XINT (c, 1) == UNSPEC_TLS_OFF
5467 || XINT (c, 1) == UNSPEC_TLS_IE))
5468 || (GET_CODE (c) == PLUS
5469 && GET_CODE (XEXP (c, 0)) == UNSPEC
5470 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
5471 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
5473 arc_output_pic_addr_const (file, c, 0);
5474 break;
5476 gcc_assert (GET_CODE (c) == PLUS);
5477 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
5478 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
5480 output_address (VOIDmode, XEXP (addr, 0));
5482 break;
5484 case PRE_INC :
5485 case PRE_DEC :
5486 /* We shouldn't get here as we've lost the mode of the memory object
5487 (which says how much to inc/dec by. */
5488 gcc_unreachable ();
5489 break;
5490 default :
5491 if (flag_pic)
5492 arc_output_pic_addr_const (file, addr, 0);
5493 else
5494 output_addr_const (file, addr);
5495 break;
5499 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5500 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5501 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5503 static int
5504 arc_verify_short (rtx_insn *insn, int check_attr)
5506 enum attr_iscompact iscompact;
5508 if (check_attr > 0)
5510 iscompact = get_attr_iscompact (insn);
5511 if (iscompact == ISCOMPACT_FALSE)
5512 return 0;
5515 return (get_attr_length (insn) & 2) != 0;
5518 /* When outputting an instruction (alternative) that can potentially be short,
5519 output the short suffix if the insn is in fact short. */
5521 static void
5522 output_short_suffix (FILE *file)
5524 rtx_insn *insn = current_output_insn;
5525 if (!insn)
5526 return;
5528 if (arc_verify_short (insn, 1))
5530 fprintf (file, "_s");
5532 /* Restore recog_operand. */
5533 extract_insn_cached (insn);
5536 /* Implement FINAL_PRESCAN_INSN. */
5538 void
5539 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
5540 int noperands ATTRIBUTE_UNUSED)
5542 if (TARGET_DUMPISIZE)
5543 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
5546 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5547 Frame pointer elimination is automatically handled.
5549 All eliminations are permissible. If we need a frame
5550 pointer, we must eliminate ARG_POINTER_REGNUM into
5551 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5553 static bool
5554 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
5556 return ((to == HARD_FRAME_POINTER_REGNUM) || (to == STACK_POINTER_REGNUM));
5559 /* Define the offset between two registers, one to be eliminated, and
5560 the other its replacement, at the start of a routine. */
5563 arc_initial_elimination_offset (int from, int to)
5565 if (!cfun->machine->frame_info.initialized)
5566 arc_compute_frame_size ();
5568 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
5570 return (cfun->machine->frame_info.extra_size
5571 + cfun->machine->frame_info.reg_size);
5574 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
5576 return (cfun->machine->frame_info.total_size
5577 - cfun->machine->frame_info.pretend_size);
5580 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
5582 return (cfun->machine->frame_info.total_size
5583 - (cfun->machine->frame_info.pretend_size
5584 + cfun->machine->frame_info.extra_size
5585 + cfun->machine->frame_info.reg_size));
5587 if ((from == FRAME_POINTER_REGNUM) && (to == HARD_FRAME_POINTER_REGNUM))
5588 return 0;
5590 gcc_unreachable ();
5593 static bool
5594 arc_frame_pointer_required (void)
5596 return cfun->calls_alloca || crtl->calls_eh_return;
5600 /* Return the destination address of a branch. */
5602 static int
5603 branch_dest (rtx branch)
5605 rtx pat = PATTERN (branch);
5606 rtx dest = (GET_CODE (pat) == PARALLEL
5607 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
5608 int dest_uid;
5610 if (GET_CODE (dest) == IF_THEN_ELSE)
5611 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
5613 dest = XEXP (dest, 0);
5614 dest_uid = INSN_UID (dest);
5616 return INSN_ADDRESSES (dest_uid);
5620 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5622 static void
5623 arc_encode_section_info (tree decl, rtx rtl, int first)
5625 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5626 This clears machine specific flags, so has to come first. */
5627 default_encode_section_info (decl, rtl, first);
5629 /* Check if it is a function, and whether it has the
5630 [long/medium/short]_call attribute specified. */
5631 if (TREE_CODE (decl) == FUNCTION_DECL)
5633 rtx symbol = XEXP (rtl, 0);
5634 int flags = SYMBOL_REF_FLAGS (symbol);
5636 tree attr = (TREE_TYPE (decl) != error_mark_node
5637 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
5638 tree long_call_attr = lookup_attribute ("long_call", attr);
5639 tree medium_call_attr = lookup_attribute ("medium_call", attr);
5640 tree short_call_attr = lookup_attribute ("short_call", attr);
5642 if (long_call_attr != NULL_TREE)
5643 flags |= SYMBOL_FLAG_LONG_CALL;
5644 else if (medium_call_attr != NULL_TREE)
5645 flags |= SYMBOL_FLAG_MEDIUM_CALL;
5646 else if (short_call_attr != NULL_TREE)
5647 flags |= SYMBOL_FLAG_SHORT_CALL;
5649 SYMBOL_REF_FLAGS (symbol) = flags;
5651 else if (VAR_P (decl))
5653 rtx symbol = XEXP (rtl, 0);
5655 tree attr = (TREE_TYPE (decl) != error_mark_node
5656 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
5658 tree sec_attr = lookup_attribute ("section", attr);
5659 if (sec_attr)
5661 const char *sec_name
5662 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
5663 if (strcmp (sec_name, ".cmem") == 0
5664 || strcmp (sec_name, ".cmem_shared") == 0
5665 || strcmp (sec_name, ".cmem_private") == 0)
5666 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
5671 /* This is how to output a definition of an internal numbered label where
5672 PREFIX is the class of label and NUM is the number within the class. */
5674 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
5676 default_internal_label (stream, prefix, labelno);
5679 /* Set the cpu type and print out other fancy things,
5680 at the top of the file. */
5682 static void arc_file_start (void)
5684 default_file_start ();
5685 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
5687 /* Set some want to have build attributes. */
5688 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5689 ATTRIBUTE_PCS);
5690 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5691 TARGET_RF16 ? 1 : 0);
5692 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5693 flag_pic ? 2 : 0);
5694 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5695 (arc_tp_regno != -1) ? 1 : 0);
5696 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5697 TARGET_NO_SDATA_SET ? 0 : 2);
5698 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5699 TARGET_OPTFPE ? 1 : 0);
5700 if (TARGET_V2)
5701 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5702 (arc_tune < ARC_TUNE_CORE_3) ? 2 :
5703 (arc_tune == ARC_TUNE_CORE_3 ? 3 : 4));
5706 /* Implement `TARGET_ASM_FILE_END'. */
5707 /* Outputs to the stdio stream FILE jli related text. */
5709 void arc_file_end (void)
5711 arc_jli_section *sec = arc_jli_sections;
5713 while (sec != NULL)
5715 fprintf (asm_out_file, "\n");
5716 fprintf (asm_out_file, "# JLI entry for function ");
5717 assemble_name (asm_out_file, sec->name);
5718 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
5719 ".jlitab.");
5720 assemble_name (asm_out_file, sec->name);
5721 fprintf (asm_out_file,", comdat\n");
5723 fprintf (asm_out_file, "\t.align\t4\n");
5724 fprintf (asm_out_file, "__jli.");
5725 assemble_name (asm_out_file, sec->name);
5726 fprintf (asm_out_file, ":\n\t.weak __jli.");
5727 assemble_name (asm_out_file, sec->name);
5728 fprintf (asm_out_file, "\n\tb\t@");
5729 assemble_name (asm_out_file, sec->name);
5730 fprintf (asm_out_file, "\n");
5731 sec = sec->next;
5733 file_end_indicate_exec_stack ();
5736 /* Cost functions. */
5738 /* Compute a (partial) cost for rtx X. Return true if the complete
5739 cost has been computed, and false if subexpressions should be
5740 scanned. In either case, *TOTAL contains the cost result. */
5742 static bool
5743 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
5744 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5746 int code = GET_CODE (x);
5748 switch (code)
5750 /* Small integers are as cheap as registers. */
5751 case CONST_INT:
5753 bool nolimm = false; /* Can we do without long immediate? */
5755 nolimm = false;
5756 if (UNSIGNED_INT6 (INTVAL (x)))
5757 nolimm = true;
5758 else
5760 switch (outer_code)
5762 case AND: /* bclr, bmsk, ext[bw] */
5763 if (satisfies_constraint_Ccp (x) /* bclr */
5764 || satisfies_constraint_C1p (x) /* bmsk */)
5765 nolimm = true;
5766 break;
5767 case IOR: /* bset */
5768 if (satisfies_constraint_C0p (x)) /* bset */
5769 nolimm = true;
5770 break;
5771 case XOR:
5772 if (satisfies_constraint_C0p (x)) /* bxor */
5773 nolimm = true;
5774 break;
5775 case SET:
5776 if (UNSIGNED_INT8 (INTVAL (x)))
5777 nolimm = true;
5778 if (satisfies_constraint_Chi (x))
5779 nolimm = true;
5780 if (satisfies_constraint_Clo (x))
5781 nolimm = true;
5782 break;
5783 case MULT:
5784 if (TARGET_MUL64_SET)
5785 if (SIGNED_INT12 (INTVAL (x)))
5786 nolimm = true;
5787 break;
5788 default:
5789 break;
5792 if (nolimm)
5794 *total = 0;
5795 return true;
5798 /* FALLTHRU */
5800 /* 4 byte values can be fetched as immediate constants -
5801 let's give that the cost of an extra insn. */
5802 case CONST:
5803 case LABEL_REF:
5804 case SYMBOL_REF:
5805 *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
5806 return true;
5808 case CONST_DOUBLE:
5810 rtx first, second;
5812 if (TARGET_DPFP)
5814 *total = COSTS_N_INSNS (1);
5815 return true;
5817 split_double (x, &first, &second);
5818 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
5819 + !SMALL_INT (INTVAL (second)));
5820 return true;
5823 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5824 If we need more than 12 insns to do a multiply, then go out-of-line,
5825 since the call overhead will be < 10% of the cost of the multiply. */
5826 case ASHIFT:
5827 if (mode == DImode)
5829 if (XEXP (x, 1) == const1_rtx)
5831 *total += rtx_cost (XEXP (x, 0), mode, ASHIFT, 0, speed)
5832 + COSTS_N_INSNS (2);
5833 return true;
5835 return false;
5837 if (TARGET_BARREL_SHIFTER)
5839 *total = COSTS_N_INSNS (1);
5840 if (CONST_INT_P (XEXP (x, 1)))
5842 *total += rtx_cost (XEXP (x, 0), mode, ASHIFT, 0, speed);
5843 return true;
5846 else if (CONST_INT_P (XEXP (x, 1)))
5848 unsigned int n = INTVAL (XEXP (x, 1)) & 0x1f;
5849 *total = arc_ashl_alg[arc_shift_context_idx ()][n].cost
5850 + rtx_cost (XEXP (x, 0), mode, ASHIFT, 0, speed);
5851 return true;
5853 else
5854 /* Variable shift loop takes 2 * n + 2 cycles. */
5855 *total = speed ? COSTS_N_INSNS (64) : COSTS_N_INSNS (4);
5856 return false;
5858 case ASHIFTRT:
5859 case LSHIFTRT:
5860 case ROTATE:
5861 case ROTATERT:
5862 if (mode == DImode)
5863 return false;
5864 if (TARGET_BARREL_SHIFTER)
5866 *total = COSTS_N_INSNS (1);
5867 if (CONSTANT_P (XEXP (x, 1)))
5869 *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
5870 0, speed);
5871 return true;
5874 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5875 *total = speed ? COSTS_N_INSNS (16) : COSTS_N_INSNS (4);
5876 else
5878 int n = INTVAL (XEXP (x, 1)) & 31;
5879 if (n < 4)
5880 *total = COSTS_N_INSNS (n);
5881 else
5882 *total = speed ? COSTS_N_INSNS (n + 2) : COSTS_N_INSNS (4);
5883 *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
5884 0, speed);
5885 return true;
5887 return false;
5889 case DIV:
5890 case UDIV:
5891 if (GET_MODE_CLASS (mode) == MODE_FLOAT
5892 && (TARGET_FP_SP_SQRT || TARGET_FP_DP_SQRT))
5893 *total = COSTS_N_INSNS(1);
5894 else if (GET_MODE_CLASS (mode) == MODE_INT
5895 && TARGET_DIVREM)
5896 *total = COSTS_N_INSNS(1);
5897 else if (speed)
5898 *total = COSTS_N_INSNS(30);
5899 else
5900 *total = COSTS_N_INSNS(1);
5901 return false;
5903 case MULT:
5904 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5905 *total = COSTS_N_INSNS (1);
5906 else if (speed)
5907 *total= arc_multcost;
5908 /* We do not want synth_mult sequences when optimizing
5909 for size. */
5910 else if (TARGET_ANY_MPY)
5911 *total = COSTS_N_INSNS (1);
5912 else
5913 *total = COSTS_N_INSNS (2);
5914 return false;
5916 case PLUS:
5917 if (mode == DImode)
5918 return false;
5919 if (outer_code == MEM && CONST_INT_P (XEXP (x, 1))
5920 && RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))
5922 *total = 0;
5923 return true;
5926 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5927 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5928 || (GET_CODE (XEXP (x, 0)) == MULT
5929 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5931 if (CONSTANT_P (XEXP (x, 1)) && !speed)
5932 *total += COSTS_N_INSNS (4);
5933 *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed);
5934 return true;
5936 return false;
5937 case MINUS:
5938 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5939 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5940 || (GET_CODE (XEXP (x, 1)) == MULT
5941 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5943 if (CONSTANT_P (XEXP (x, 0)) && !speed)
5944 *total += COSTS_N_INSNS (4);
5945 *total += rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed);
5946 return true;
5948 return false;
5950 case COMPARE:
5952 rtx op0 = XEXP (x, 0);
5953 rtx op1 = XEXP (x, 1);
5955 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5956 && XEXP (op0, 1) == const1_rtx)
5958 /* btst / bbit0 / bbit1:
5959 Small integers and registers are free; everything else can
5960 be put in a register. */
5961 mode = GET_MODE (XEXP (op0, 0));
5962 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5963 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5964 return true;
5966 if (GET_CODE (op0) == AND && op1 == const0_rtx
5967 && satisfies_constraint_C1p (XEXP (op0, 1)))
5969 /* bmsk.f */
5970 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5971 return true;
5973 /* add.f */
5974 if (GET_CODE (op1) == NEG)
5976 /* op0 might be constant, the inside of op1 is rather
5977 unlikely to be so. So swapping the operands might lower
5978 the cost. */
5979 mode = GET_MODE (op0);
5980 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5981 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5983 return false;
5985 case EQ: case NE:
5986 if (outer_code == IF_THEN_ELSE
5987 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5988 && XEXP (x, 1) == const0_rtx
5989 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5991 /* btst / bbit0 / bbit1:
5992 Small integers and registers are free; everything else can
5993 be put in a register. */
5994 rtx op0 = XEXP (x, 0);
5996 mode = GET_MODE (XEXP (op0, 0));
5997 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5998 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5999 return true;
6001 /* Fall through. */
6002 /* scc_insn expands into two insns. */
6003 case GTU: case GEU: case LEU:
6004 if (mode == SImode)
6005 *total += COSTS_N_INSNS (1);
6006 return false;
6007 case LTU: /* might use adc. */
6008 if (mode == SImode)
6009 *total += COSTS_N_INSNS (1) - 1;
6010 return false;
6011 default:
6012 return false;
6016 /* Return true if ADDR is a valid pic address.
6017 A valid pic address on arc should look like
6018 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
6020 bool
6021 arc_legitimate_pic_addr_p (rtx addr)
6023 if (GET_CODE (addr) != CONST)
6024 return false;
6026 addr = XEXP (addr, 0);
6029 if (GET_CODE (addr) == PLUS)
6031 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
6032 return false;
6033 addr = XEXP (addr, 0);
6036 if (GET_CODE (addr) != UNSPEC
6037 || XVECLEN (addr, 0) != 1)
6038 return false;
6040 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
6041 if (XINT (addr, 1) != ARC_UNSPEC_GOT
6042 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
6043 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
6044 && XINT (addr, 1) != UNSPEC_TLS_GD
6045 && XINT (addr, 1) != UNSPEC_TLS_IE)
6046 return false;
6048 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
6049 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
6050 return false;
6052 return true;
6057 /* Return true if OP contains a symbol reference. */
6059 static bool
6060 symbolic_reference_mentioned_p (rtx op)
6062 const char *fmt;
6063 int i;
6065 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
6066 return true;
6068 fmt = GET_RTX_FORMAT (GET_CODE (op));
6069 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
6071 if (fmt[i] == 'E')
6073 int j;
6075 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
6076 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
6077 return true;
6080 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
6081 return true;
6084 return false;
6087 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
6088 If SKIP_LOCAL is true, skip symbols that bind locally.
6089 This is used further down in this file, and, without SKIP_LOCAL,
6090 in the addsi3 / subsi3 expanders when generating PIC code. */
6092 bool
6093 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
6095 const char *fmt;
6096 int i;
6098 if (GET_CODE(op) == UNSPEC)
6099 return false;
6101 if (GET_CODE (op) == SYMBOL_REF)
6103 if (SYMBOL_REF_TLS_MODEL (op))
6104 return true;
6105 if (!flag_pic)
6106 return false;
6107 tree decl = SYMBOL_REF_DECL (op);
6108 return !skip_local || !decl || !default_binds_local_p (decl);
6111 fmt = GET_RTX_FORMAT (GET_CODE (op));
6112 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
6114 if (fmt[i] == 'E')
6116 int j;
6118 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
6119 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
6120 skip_local))
6121 return true;
6124 else if (fmt[i] == 'e'
6125 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
6126 skip_local))
6127 return true;
6130 return false;
6133 /* The __tls_get_attr symbol. */
6134 static GTY(()) rtx arc_tls_symbol;
6136 /* Emit a call to __tls_get_addr. TI is the argument to this function.
6137 RET is an RTX for the return value location. The entire insn sequence
6138 is returned. */
6140 static rtx
6141 arc_call_tls_get_addr (rtx ti)
6143 rtx arg = gen_rtx_REG (Pmode, R0_REG);
6144 rtx ret = gen_rtx_REG (Pmode, R0_REG);
6145 rtx fn;
6146 rtx_insn *insn;
6148 if (!arc_tls_symbol)
6149 arc_tls_symbol = init_one_libfunc ("__tls_get_addr");
6151 emit_move_insn (arg, ti);
6152 fn = gen_rtx_MEM (SImode, arc_tls_symbol);
6153 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
6154 RTL_CONST_CALL_P (insn) = 1;
6155 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
6156 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
6158 return ret;
6161 /* Return a legitimized address for ADDR,
6162 which is a SYMBOL_REF with tls_model MODEL. */
6164 static rtx
6165 arc_legitimize_tls_address (rtx addr, enum tls_model model)
6167 rtx tmp;
6169 /* The TP pointer needs to be set. */
6170 gcc_assert (arc_tp_regno != -1);
6172 switch (model)
6174 case TLS_MODEL_GLOBAL_DYNAMIC:
6175 case TLS_MODEL_LOCAL_DYNAMIC:
6176 tmp = gen_reg_rtx (Pmode);
6177 emit_move_insn (tmp, arc_unspec_offset (addr, UNSPEC_TLS_GD));
6178 return arc_call_tls_get_addr (tmp);
6180 case TLS_MODEL_INITIAL_EXEC:
6181 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
6182 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
6183 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
6185 case TLS_MODEL_LOCAL_EXEC:
6186 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
6187 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
6189 default:
6190 gcc_unreachable ();
6194 /* Return true if SYMBOL_REF X binds locally. */
6196 static bool
6197 arc_symbol_binds_local_p (const_rtx x)
6199 return (SYMBOL_REF_DECL (x)
6200 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
6201 : SYMBOL_REF_LOCAL_P (x));
6204 /* Legitimize a pic address reference in ADDR. The return value is
6205 the legitimated address. */
6207 static rtx
6208 arc_legitimize_pic_address (rtx addr)
6210 if (!flag_pic)
6211 return addr;
6213 switch (GET_CODE (addr))
6215 case UNSPEC:
6216 /* Can be one or our GOT or GOTOFFPC unspecs. This situation
6217 happens when an address is not a legitimate constant and we
6218 need the resolve it via force_reg in
6219 prepare_move_operands. */
6220 switch (XINT (addr, 1))
6222 case ARC_UNSPEC_GOT:
6223 case ARC_UNSPEC_GOTOFFPC:
6224 /* Recover the symbol ref. */
6225 addr = XVECEXP (addr, 0, 0);
6226 break;
6227 default:
6228 return addr;
6230 /* Fall through. */
6231 case SYMBOL_REF:
6232 /* TLS symbols are handled in different place. */
6233 if (SYMBOL_REF_TLS_MODEL (addr))
6234 return addr;
6236 /* This symbol must be referenced via a load from the Global
6237 Offset Table (@GOTPC). */
6238 if (!arc_symbol_binds_local_p (addr))
6239 return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT));
6241 /* Local symb: use @pcl to access it. */
6242 /* Fall through. */
6243 case LABEL_REF:
6244 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
6246 default:
6247 break;
6250 return addr;
6253 /* Output address constant X to FILE, taking PIC into account. */
6255 static void
6256 arc_output_pic_addr_const (FILE * file, rtx x, int code)
6258 char buf[256];
6260 restart:
6261 switch (GET_CODE (x))
6263 case PC:
6264 if (flag_pic)
6265 putc ('.', file);
6266 else
6267 gcc_unreachable ();
6268 break;
6270 case SYMBOL_REF:
6271 output_addr_const (file, x);
6273 /* Local functions do not get references through the PLT. */
6274 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
6275 fputs ("@plt", file);
6276 break;
6278 case LABEL_REF:
6279 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
6280 assemble_name (file, buf);
6281 break;
6283 case CODE_LABEL:
6284 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
6285 assemble_name (file, buf);
6286 break;
6288 case CONST_INT:
6289 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
6290 break;
6292 case CONST:
6293 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6294 break;
6296 case CONST_DOUBLE:
6297 if (GET_MODE (x) == VOIDmode)
6299 /* We can use %d if the number is one word and positive. */
6300 if (CONST_DOUBLE_HIGH (x))
6301 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
6302 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
6303 else if (CONST_DOUBLE_LOW (x) < 0)
6304 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
6305 else
6306 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
6308 else
6309 /* We can't handle floating point constants;
6310 PRINT_OPERAND must handle them. */
6311 output_operand_lossage ("floating constant misused");
6312 break;
6314 case PLUS:
6315 /* FIXME: Not needed here. */
6316 /* Some assemblers need integer constants to appear last (eg masm). */
6317 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
6319 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6320 fprintf (file, "+");
6321 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6323 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
6325 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6326 if (INTVAL (XEXP (x, 1)) >= 0)
6327 fprintf (file, "+");
6328 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6330 else
6331 gcc_unreachable();
6332 break;
6334 case MINUS:
6335 /* Avoid outputting things like x-x or x+5-x,
6336 since some assemblers can't handle that. */
6337 x = simplify_subtraction (x);
6338 if (GET_CODE (x) != MINUS)
6339 goto restart;
6341 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6342 fprintf (file, "-");
6343 if (GET_CODE (XEXP (x, 1)) == CONST_INT
6344 && INTVAL (XEXP (x, 1)) < 0)
6346 fprintf (file, "(");
6347 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6348 fprintf (file, ")");
6350 else
6351 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6352 break;
6354 case ZERO_EXTEND:
6355 case SIGN_EXTEND:
6356 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6357 break;
6360 case UNSPEC:
6361 const char *suffix;
6362 bool pcrel; pcrel = false;
6363 rtx base; base = NULL;
6364 gcc_assert (XVECLEN (x, 0) >= 1);
6365 switch (XINT (x, 1))
6367 case ARC_UNSPEC_GOT:
6368 suffix = "@gotpc", pcrel = true;
6369 break;
6370 case ARC_UNSPEC_GOTOFF:
6371 suffix = "@gotoff";
6372 break;
6373 case ARC_UNSPEC_GOTOFFPC:
6374 suffix = "@pcl", pcrel = true;
6375 break;
6376 case ARC_UNSPEC_PLT:
6377 suffix = "@plt";
6378 break;
6379 case UNSPEC_TLS_GD:
6380 suffix = "@tlsgd", pcrel = true;
6381 break;
6382 case UNSPEC_TLS_IE:
6383 suffix = "@tlsie", pcrel = true;
6384 break;
6385 case UNSPEC_TLS_OFF:
6386 if (XVECLEN (x, 0) == 2)
6387 base = XVECEXP (x, 0, 1);
6388 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6389 || (!flag_pic && !base))
6390 suffix = "@tpoff";
6391 else
6392 suffix = "@dtpoff";
6393 break;
6394 default:
6395 suffix = "@invalid";
6396 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
6397 break;
6399 if (pcrel)
6400 fputs ("pcl,", file);
6401 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
6402 fputs (suffix, file);
6403 if (base)
6404 arc_output_pic_addr_const (file, base, code);
6405 break;
6407 default:
6408 output_operand_lossage ("invalid expression as operand");
6412 /* The function returning the number of words, at the beginning of an
6413 argument, must be put in registers. The returned value must be
6414 zero for arguments that are passed entirely in registers or that
6415 are entirely pushed on the stack.
6417 On some machines, certain arguments must be passed partially in
6418 registers and partially in memory. On these machines, typically
6419 the first N words of arguments are passed in registers, and the
6420 rest on the stack. If a multi-word argument (a `double' or a
6421 structure) crosses that boundary, its first few words must be
6422 passed in registers and the rest must be pushed. This function
6423 tells the compiler when this occurs, and how many of the words
6424 should go in registers.
6426 `FUNCTION_ARG' for these arguments should return the first register
6427 to be used by the caller for this argument; likewise
6428 `FUNCTION_INCOMING_ARG', for the called function.
6430 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6432 /* If REGNO is the least arg reg available then what is the total number of arg
6433 regs available. */
6434 #define GPR_REST_ARG_REGS(REGNO) \
6435 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6437 /* Since arc parm regs are contiguous. */
6438 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6440 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6442 static int
6443 arc_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
6445 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6446 int bytes = arg.promoted_size_in_bytes ();
6447 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6448 int arg_num = *cum;
6449 int ret;
6451 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6452 ret = GPR_REST_ARG_REGS (arg_num);
6454 /* ICEd at function.cc:2361, and ret is copied to data->partial */
6455 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
6457 return ret;
6460 /* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
6461 args are normally in registers and the rest are pushed. */
6463 static rtx
6464 arc_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
6466 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6467 int arg_num = *cum;
6468 rtx ret;
6469 const char *debstr ATTRIBUTE_UNUSED;
6471 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6472 /* Return a marker for use in the call instruction. */
6473 if (arg.end_marker_p ())
6475 ret = const0_rtx;
6476 debstr = "<0>";
6478 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6480 ret = gen_rtx_REG (arg.mode, arg_num);
6481 debstr = reg_names [arg_num];
6483 else
6485 ret = NULL_RTX;
6486 debstr = "memory";
6488 return ret;
6491 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6492 /* For the ARC: the cum set here is passed on to function_arg where we
6493 look at its value and say which reg to use. Strategy: advance the
6494 regnumber here till we run out of arg regs, then set *cum to last
6495 reg. In function_arg, since *cum > last arg reg we would return 0
6496 and thus the arg will end up on the stack. For straddling args of
6497 course function_arg_partial_nregs will come into play. */
6499 static void
6500 arc_function_arg_advance (cumulative_args_t cum_v,
6501 const function_arg_info &arg)
6503 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6504 int bytes = arg.promoted_size_in_bytes ();
6505 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6506 int i;
6508 if (words)
6509 *cum = ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type);
6510 for (i = 0; i < words; i++)
6511 *cum = ARC_NEXT_ARG_REG (*cum);
6515 /* Define how to find the value returned by a function.
6516 VALTYPE is the data type of the value (as a tree).
6517 If the precise function being called is known, FN_DECL_OR_TYPE is its
6518 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6520 static rtx
6521 arc_function_value (const_tree valtype,
6522 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6523 bool outgoing ATTRIBUTE_UNUSED)
6525 machine_mode mode = TYPE_MODE (valtype);
6526 int unsignedp ATTRIBUTE_UNUSED;
6528 unsignedp = TYPE_UNSIGNED (valtype);
6529 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6530 PROMOTE_MODE (mode, unsignedp, valtype);
6531 return gen_rtx_REG (mode, 0);
6534 /* Returns the return address that is used by builtin_return_address. */
6537 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6539 if (count != 0)
6540 return const0_rtx;
6542 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6545 /* Determine if a given RTX is a valid constant. We already know this
6546 satisfies CONSTANT_P. */
6548 bool
6549 arc_legitimate_constant_p (machine_mode mode, rtx x)
6551 switch (GET_CODE (x))
6553 case CONST:
6554 if (flag_pic)
6556 if (arc_legitimate_pic_addr_p (x))
6557 return true;
6559 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6561 case SYMBOL_REF:
6562 if (SYMBOL_REF_TLS_MODEL (x))
6563 return false;
6564 /* Fall through. */
6565 case LABEL_REF:
6566 if (flag_pic)
6567 return false;
6568 /* Fall through. */
6569 case CONST_INT:
6570 case CONST_DOUBLE:
6571 return true;
6573 case NEG:
6574 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6576 case PLUS:
6577 case MINUS:
6579 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6580 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6582 return (t1 && t2);
6585 case CONST_VECTOR:
6586 switch (mode)
6588 case E_V2HImode:
6589 return TARGET_PLUS_DMPY;
6590 case E_V2SImode:
6591 case E_V4HImode:
6592 return TARGET_PLUS_QMACW;
6593 default:
6594 return false;
6597 case UNSPEC:
6598 switch (XINT (x, 1))
6600 case UNSPEC_TLS_GD:
6601 case UNSPEC_TLS_OFF:
6602 case UNSPEC_TLS_IE:
6603 return true;
6604 default:
6605 /* Any other unspec ending here are pic related, hence the above
6606 constant pic address checking returned false. */
6607 return false;
6609 /* Fall through. */
6611 default:
6612 fatal_insn ("unrecognized supposed constant", x);
6615 gcc_unreachable ();
6618 static bool
6619 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict,
6620 code_helper = ERROR_MARK)
6622 if (RTX_OK_FOR_BASE_P (x, strict))
6623 return true;
6624 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
6625 return true;
6626 if (legitimate_scaled_address_p (mode, x, strict))
6627 return true;
6628 if (legitimate_small_data_address_p (x, mode))
6629 return true;
6630 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6631 return true;
6633 /* When we compile for size avoid const (@sym + offset)
6634 addresses. */
6635 if (!flag_pic && optimize_size && !reload_completed
6636 && (GET_CODE (x) == CONST)
6637 && (GET_CODE (XEXP (x, 0)) == PLUS)
6638 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6639 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6640 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
6642 rtx addend = XEXP (XEXP (x, 0), 1);
6643 gcc_assert (CONST_INT_P (addend));
6644 HOST_WIDE_INT offset = INTVAL (addend);
6646 /* Allow addresses having a large offset to pass. Anyhow they
6647 will end in a limm. */
6648 return !(offset > -1024 && offset < 1020);
6651 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6653 return arc_legitimate_constant_p (mode, x);
6655 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6656 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6657 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6658 return true;
6659 /* We're restricted here by the `st' insn. */
6660 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6661 && GET_CODE (XEXP ((x), 1)) == PLUS
6662 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
6663 && legitimate_offset_address_p (QImode, XEXP (x, 1),
6664 TARGET_AUTO_MODIFY_REG, strict))
6665 return true;
6666 return false;
6669 /* Return true iff ADDR (a legitimate address expression)
6670 has an effect that depends on the machine mode it is used for. */
6672 static bool
6673 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6675 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6676 which is valid for loads and stores, or a limm offset, which is valid for
6677 loads. Scaled indices are scaled by the access mode. */
6678 if (GET_CODE (addr) == PLUS
6679 && GET_CODE (XEXP ((addr), 0)) == MULT)
6680 return true;
6681 return false;
6684 /* Determine if it's legal to put X into the constant pool. */
6686 static bool
6687 arc_cannot_force_const_mem (machine_mode mode, rtx x)
6689 return !arc_legitimate_constant_p (mode, x);
6692 /* IDs for all the ARC builtins. */
6694 enum arc_builtin_id
6696 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6697 ARC_BUILTIN_ ## NAME,
6698 #include "builtins.def"
6699 #undef DEF_BUILTIN
6701 ARC_BUILTIN_COUNT
6704 struct GTY(()) arc_builtin_description
6706 enum insn_code icode;
6707 int n_args;
6708 tree fndecl;
6711 static GTY(()) struct arc_builtin_description
6712 arc_bdesc[ARC_BUILTIN_COUNT] =
6714 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6715 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6716 #include "builtins.def"
6717 #undef DEF_BUILTIN
6720 /* Transform UP into lowercase and write the result to LO.
6721 You must provide enough space for LO. Return LO. */
6723 static char*
6724 arc_tolower (char *lo, const char *up)
6726 char *lo0 = lo;
6728 for (; *up; up++, lo++)
6729 *lo = TOLOWER (*up);
6731 *lo = '\0';
6733 return lo0;
6736 /* Implement `TARGET_BUILTIN_DECL'. */
6738 static tree
6739 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6741 if (id < ARC_BUILTIN_COUNT)
6742 return arc_bdesc[id].fndecl;
6744 return error_mark_node;
6747 static void
6748 arc_init_builtins (void)
6750 tree V4HI_type_node;
6751 tree V2SI_type_node;
6752 tree V2HI_type_node;
6754 /* Vector types based on HS SIMD elements. */
6755 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6756 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6757 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6759 tree pcvoid_type_node
6760 = build_pointer_type (build_qualified_type (void_type_node,
6761 TYPE_QUAL_CONST));
6762 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6763 V8HImode);
6765 tree void_ftype_void
6766 = build_function_type_list (void_type_node, NULL_TREE);
6767 tree int_ftype_int
6768 = build_function_type_list (integer_type_node, integer_type_node,
6769 NULL_TREE);
6770 tree int_ftype_pcvoid_int
6771 = build_function_type_list (integer_type_node, pcvoid_type_node,
6772 integer_type_node, NULL_TREE);
6773 tree void_ftype_usint_usint
6774 = build_function_type_list (void_type_node, long_unsigned_type_node,
6775 long_unsigned_type_node, NULL_TREE);
6776 tree int_ftype_int_int
6777 = build_function_type_list (integer_type_node, integer_type_node,
6778 integer_type_node, NULL_TREE);
6779 tree usint_ftype_usint
6780 = build_function_type_list (long_unsigned_type_node,
6781 long_unsigned_type_node, NULL_TREE);
6782 tree void_ftype_usint
6783 = build_function_type_list (void_type_node, long_unsigned_type_node,
6784 NULL_TREE);
6785 tree int_ftype_void
6786 = build_function_type_list (integer_type_node, void_type_node,
6787 NULL_TREE);
6788 tree void_ftype_int
6789 = build_function_type_list (void_type_node, integer_type_node,
6790 NULL_TREE);
6791 tree int_ftype_short
6792 = build_function_type_list (integer_type_node, short_integer_type_node,
6793 NULL_TREE);
6795 /* Old ARC SIMD types. */
6796 tree v8hi_ftype_v8hi_v8hi
6797 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6798 V8HI_type_node, NULL_TREE);
6799 tree v8hi_ftype_v8hi_int
6800 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6801 integer_type_node, NULL_TREE);
6802 tree v8hi_ftype_v8hi_int_int
6803 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6804 integer_type_node, integer_type_node,
6805 NULL_TREE);
6806 tree void_ftype_v8hi_int_int
6807 = build_function_type_list (void_type_node, V8HI_type_node,
6808 integer_type_node, integer_type_node,
6809 NULL_TREE);
6810 tree void_ftype_v8hi_int_int_int
6811 = build_function_type_list (void_type_node, V8HI_type_node,
6812 integer_type_node, integer_type_node,
6813 integer_type_node, NULL_TREE);
6814 tree v8hi_ftype_int_int
6815 = build_function_type_list (V8HI_type_node, integer_type_node,
6816 integer_type_node, NULL_TREE);
6817 tree void_ftype_int_int
6818 = build_function_type_list (void_type_node, integer_type_node,
6819 integer_type_node, NULL_TREE);
6820 tree v8hi_ftype_v8hi
6821 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6822 NULL_TREE);
6823 /* ARCv2 SIMD types. */
6824 tree long_ftype_v4hi_v4hi
6825 = build_function_type_list (long_long_integer_type_node,
6826 V4HI_type_node, V4HI_type_node, NULL_TREE);
6827 tree int_ftype_v2hi_v2hi
6828 = build_function_type_list (integer_type_node,
6829 V2HI_type_node, V2HI_type_node, NULL_TREE);
6830 tree v2si_ftype_v2hi_v2hi
6831 = build_function_type_list (V2SI_type_node,
6832 V2HI_type_node, V2HI_type_node, NULL_TREE);
6833 tree v2hi_ftype_v2hi_v2hi
6834 = build_function_type_list (V2HI_type_node,
6835 V2HI_type_node, V2HI_type_node, NULL_TREE);
6836 tree v2si_ftype_v2si_v2si
6837 = build_function_type_list (V2SI_type_node,
6838 V2SI_type_node, V2SI_type_node, NULL_TREE);
6839 tree v4hi_ftype_v4hi_v4hi
6840 = build_function_type_list (V4HI_type_node,
6841 V4HI_type_node, V4HI_type_node, NULL_TREE);
6842 tree long_ftype_v2si_v2hi
6843 = build_function_type_list (long_long_integer_type_node,
6844 V2SI_type_node, V2HI_type_node, NULL_TREE);
6846 /* Add the builtins. */
6847 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6849 int id = ARC_BUILTIN_ ## NAME; \
6850 const char *Name = "__builtin_arc_" #NAME; \
6851 char *name = (char*) alloca (1 + strlen (Name)); \
6853 gcc_assert (id < ARC_BUILTIN_COUNT); \
6854 if (MASK) \
6855 arc_bdesc[id].fndecl \
6856 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6857 BUILT_IN_MD, NULL, NULL_TREE); \
6859 #include "builtins.def"
6860 #undef DEF_BUILTIN
6863 /* Helper to expand __builtin_arc_aligned (void* val, int
6864 alignval). */
6866 static rtx
6867 arc_expand_builtin_aligned (tree exp)
6869 tree arg0 = CALL_EXPR_ARG (exp, 0);
6870 tree arg1 = CALL_EXPR_ARG (exp, 1);
6871 fold (arg1);
6872 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6873 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6875 if (!CONST_INT_P (op1))
6877 /* If we can't fold the alignment to a constant integer
6878 whilst optimizing, this is probably a user error. */
6879 if (optimize)
6880 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
6882 else
6884 HOST_WIDE_INT alignTest = INTVAL (op1);
6885 /* Check alignTest is positive, and a power of two. */
6886 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6888 error ("invalid alignment value for %<__builtin_arc_aligned%>");
6889 return NULL_RTX;
6892 if (CONST_INT_P (op0))
6894 HOST_WIDE_INT pnt = INTVAL (op0);
6896 if ((pnt & (alignTest - 1)) == 0)
6897 return const1_rtx;
6899 else
6901 unsigned align = get_pointer_alignment (arg0);
6902 unsigned numBits = alignTest * BITS_PER_UNIT;
6904 if (align && align >= numBits)
6905 return const1_rtx;
6906 /* Another attempt to ascertain alignment. Check the type
6907 we are pointing to. */
6908 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6909 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6910 return const1_rtx;
6914 /* Default to false. */
6915 return const0_rtx;
6918 /* Helper arc_expand_builtin, generates a pattern for the given icode
6919 and arguments. */
6921 static rtx_insn *
6922 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6924 switch (insn_data[icode].n_generator_args)
6926 case 0:
6927 return GEN_FCN (icode) ();
6928 case 1:
6929 return GEN_FCN (icode) (arg[0]);
6930 case 2:
6931 return GEN_FCN (icode) (arg[0], arg[1]);
6932 case 3:
6933 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6934 case 4:
6935 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6936 case 5:
6937 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6938 default:
6939 gcc_unreachable ();
6943 /* Expand an expression EXP that calls a built-in function,
6944 with result going to TARGET if that's convenient
6945 (and in mode MODE if that's convenient).
6946 SUBTARGET may be used as the target for computing one of EXP's operands.
6947 IGNORE is nonzero if the value is to be ignored. */
6949 static rtx
6950 arc_expand_builtin (tree exp,
6951 rtx target,
6952 rtx subtarget ATTRIBUTE_UNUSED,
6953 machine_mode mode ATTRIBUTE_UNUSED,
6954 int ignore ATTRIBUTE_UNUSED)
6956 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6957 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
6958 const struct arc_builtin_description *d = &arc_bdesc[id];
6959 int i, j, n_args = call_expr_nargs (exp);
6960 rtx pat = NULL_RTX;
6961 rtx xop[5];
6962 enum insn_code icode = d->icode;
6963 machine_mode tmode = insn_data[icode].operand[0].mode;
6964 int nonvoid;
6965 tree arg0;
6966 tree arg1;
6967 tree arg2;
6968 tree arg3;
6969 rtx op0;
6970 rtx op1;
6971 rtx op2;
6972 rtx op3;
6973 rtx op4;
6974 machine_mode mode0;
6975 machine_mode mode1;
6976 machine_mode mode2;
6977 machine_mode mode3;
6978 machine_mode mode4;
6980 if (id >= ARC_BUILTIN_COUNT)
6981 internal_error ("bad builtin fcode");
6983 /* 1st part: Expand special builtins. */
6984 switch (id)
6986 case ARC_BUILTIN_NOP:
6987 emit_insn (gen_nopv ());
6988 return NULL_RTX;
6990 case ARC_BUILTIN_RTIE:
6991 case ARC_BUILTIN_SYNC:
6992 case ARC_BUILTIN_BRK:
6993 case ARC_BUILTIN_SWI:
6994 case ARC_BUILTIN_UNIMP_S:
6995 gcc_assert (icode != 0);
6996 emit_insn (GEN_FCN (icode) (const1_rtx));
6997 return NULL_RTX;
6999 case ARC_BUILTIN_ALIGNED:
7000 return arc_expand_builtin_aligned (exp);
7002 case ARC_BUILTIN_CLRI:
7003 target = gen_reg_rtx (SImode);
7004 emit_insn (gen_clri (target, const1_rtx));
7005 return target;
7007 case ARC_BUILTIN_TRAP_S:
7008 case ARC_BUILTIN_SLEEP:
7009 arg0 = CALL_EXPR_ARG (exp, 0);
7010 fold (arg0);
7011 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7013 gcc_assert (icode != 0);
7014 emit_insn (GEN_FCN (icode) (op0));
7015 return NULL_RTX;
7017 case ARC_BUILTIN_VDORUN:
7018 case ARC_BUILTIN_VDIRUN:
7019 arg0 = CALL_EXPR_ARG (exp, 0);
7020 arg1 = CALL_EXPR_ARG (exp, 1);
7021 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7022 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7024 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
7026 mode0 = insn_data[icode].operand[1].mode;
7027 mode1 = insn_data[icode].operand[2].mode;
7029 if (!insn_data[icode].operand[1].predicate (op0, mode0))
7030 op0 = copy_to_mode_reg (mode0, op0);
7032 if (!insn_data[icode].operand[2].predicate (op1, mode1))
7033 op1 = copy_to_mode_reg (mode1, op1);
7035 pat = GEN_FCN (icode) (target, op0, op1);
7036 if (!pat)
7037 return NULL_RTX;
7039 emit_insn (pat);
7040 return NULL_RTX;
7042 case ARC_BUILTIN_VDIWR:
7043 case ARC_BUILTIN_VDOWR:
7044 arg0 = CALL_EXPR_ARG (exp, 0);
7045 arg1 = CALL_EXPR_ARG (exp, 1);
7046 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7047 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7049 if (!CONST_INT_P (op0)
7050 || !(UNSIGNED_INT3 (INTVAL (op0))))
7051 error ("operand 1 should be an unsigned 3-bit immediate");
7053 mode1 = insn_data[icode].operand[1].mode;
7055 if (icode == CODE_FOR_vdiwr_insn)
7056 target = gen_rtx_REG (SImode,
7057 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
7058 else if (icode == CODE_FOR_vdowr_insn)
7059 target = gen_rtx_REG (SImode,
7060 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
7061 else
7062 gcc_unreachable ();
7064 if (!insn_data[icode].operand[2].predicate (op1, mode1))
7065 op1 = copy_to_mode_reg (mode1, op1);
7067 pat = GEN_FCN (icode) (target, op1);
7068 if (!pat)
7069 return NULL_RTX;
7071 emit_insn (pat);
7072 return NULL_RTX;
7074 case ARC_BUILTIN_VASRW:
7075 case ARC_BUILTIN_VSR8:
7076 case ARC_BUILTIN_VSR8AW:
7077 arg0 = CALL_EXPR_ARG (exp, 0);
7078 arg1 = CALL_EXPR_ARG (exp, 1);
7079 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7080 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7081 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7083 target = gen_reg_rtx (V8HImode);
7084 mode0 = insn_data[icode].operand[1].mode;
7085 mode1 = insn_data[icode].operand[2].mode;
7087 if (!insn_data[icode].operand[1].predicate (op0, mode0))
7088 op0 = copy_to_mode_reg (mode0, op0);
7090 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7091 || !(UNSIGNED_INT3 (INTVAL (op1))))
7092 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7094 pat = GEN_FCN (icode) (target, op0, op1, op2);
7095 if (!pat)
7096 return NULL_RTX;
7098 emit_insn (pat);
7099 return target;
7101 case ARC_BUILTIN_VLD32WH:
7102 case ARC_BUILTIN_VLD32WL:
7103 case ARC_BUILTIN_VLD64:
7104 case ARC_BUILTIN_VLD32:
7105 rtx src_vreg;
7106 icode = d->icode;
7107 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7108 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7109 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
7111 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7112 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7113 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7114 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7116 /* target <- src vreg. */
7117 emit_insn (gen_move_insn (target, src_vreg));
7119 /* target <- vec_concat: target, mem (Ib, u8). */
7120 mode0 = insn_data[icode].operand[3].mode;
7121 mode1 = insn_data[icode].operand[1].mode;
7123 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
7124 || !(UNSIGNED_INT3 (INTVAL (op0))))
7125 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7127 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7128 || !(UNSIGNED_INT8 (INTVAL (op1))))
7129 error ("operand 2 should be an unsigned 8-bit value");
7131 pat = GEN_FCN (icode) (target, op1, op2, op0);
7132 if (!pat)
7133 return NULL_RTX;
7135 emit_insn (pat);
7136 return target;
7138 case ARC_BUILTIN_VLD64W:
7139 case ARC_BUILTIN_VLD128:
7140 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
7141 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7143 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7144 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7145 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7147 /* target <- src vreg. */
7148 target = gen_reg_rtx (V8HImode);
7150 /* target <- vec_concat: target, mem (Ib, u8). */
7151 mode0 = insn_data[icode].operand[1].mode;
7152 mode1 = insn_data[icode].operand[2].mode;
7153 mode2 = insn_data[icode].operand[3].mode;
7155 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7156 || !(UNSIGNED_INT3 (INTVAL (op1))))
7157 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7159 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
7160 || !(UNSIGNED_INT8 (INTVAL (op2))))
7161 error ("operand 2 should be an unsigned 8-bit value");
7163 pat = GEN_FCN (icode) (target, op0, op1, op2);
7165 if (!pat)
7166 return NULL_RTX;
7168 emit_insn (pat);
7169 return target;
7171 case ARC_BUILTIN_VST128:
7172 case ARC_BUILTIN_VST64:
7173 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
7174 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7175 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
7177 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7178 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7179 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7180 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7182 mode0 = insn_data[icode].operand[0].mode;
7183 mode1 = insn_data[icode].operand[1].mode;
7184 mode2 = insn_data[icode].operand[2].mode;
7185 mode3 = insn_data[icode].operand[3].mode;
7187 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7188 || !(UNSIGNED_INT3 (INTVAL (op1))))
7189 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7191 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7192 || !(UNSIGNED_INT8 (INTVAL (op2))))
7193 error ("operand 3 should be an unsigned 8-bit value");
7195 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7196 op3 = copy_to_mode_reg (mode3, op3);
7198 pat = GEN_FCN (icode) (op0, op1, op2, op3);
7199 if (!pat)
7200 return NULL_RTX;
7202 emit_insn (pat);
7203 return NULL_RTX;
7205 case ARC_BUILTIN_VST16_N:
7206 case ARC_BUILTIN_VST32_N:
7207 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7208 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
7209 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
7210 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
7212 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
7213 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7214 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7215 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7216 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7218 mode0 = insn_data[icode].operand[0].mode;
7219 mode2 = insn_data[icode].operand[2].mode;
7220 mode3 = insn_data[icode].operand[3].mode;
7221 mode4 = insn_data[icode].operand[4].mode;
7223 /* Do some correctness checks for the operands. */
7224 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
7225 || !(UNSIGNED_INT8 (INTVAL (op0))))
7226 error ("operand 4 should be an unsigned 8-bit value (0-255)");
7228 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7229 || !(UNSIGNED_INT3 (INTVAL (op2))))
7230 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
7232 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7233 op3 = copy_to_mode_reg (mode3, op3);
7235 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
7236 || !(UNSIGNED_INT3 (INTVAL (op4))))
7237 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
7238 else if (icode == CODE_FOR_vst32_n_insn
7239 && ((INTVAL (op4) % 2) != 0))
7240 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
7242 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
7243 if (!pat)
7244 return NULL_RTX;
7246 emit_insn (pat);
7247 return NULL_RTX;
7249 default:
7250 break;
7253 /* 2nd part: Expand regular builtins. */
7254 if (icode == 0)
7255 internal_error ("bad builtin fcode");
7257 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7258 j = 0;
7260 if (nonvoid)
7262 if (target == NULL_RTX
7263 || GET_MODE (target) != tmode
7264 || !insn_data[icode].operand[0].predicate (target, tmode))
7266 target = gen_reg_rtx (tmode);
7268 xop[j++] = target;
7271 gcc_assert (n_args <= 4);
7272 for (i = 0; i < n_args; i++, j++)
7274 tree arg = CALL_EXPR_ARG (exp, i);
7275 machine_mode mode = insn_data[icode].operand[j].mode;
7276 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
7277 machine_mode opmode = GET_MODE (op);
7278 char c = insn_data[icode].operand[j].constraint[0];
7280 /* SIMD extension requires exact immediate operand match. */
7281 if ((id > ARC_BUILTIN_SIMD_BEGIN)
7282 && (id < ARC_BUILTIN_SIMD_END)
7283 && (c != 'v')
7284 && (c != 'r'))
7286 if (!CONST_INT_P (op))
7287 error ("builtin requires an immediate for operand %d", j);
7288 switch (c)
7290 case 'L':
7291 if (!satisfies_constraint_L (op))
7292 error ("operand %d should be a 6 bit unsigned immediate", j);
7293 break;
7294 case 'P':
7295 if (!satisfies_constraint_P (op))
7296 error ("operand %d should be a 8 bit unsigned immediate", j);
7297 break;
7298 case 'K':
7299 if (!satisfies_constraint_K (op))
7300 error ("operand %d should be a 3 bit unsigned immediate", j);
7301 break;
7302 default:
7303 error ("unknown builtin immediate operand type for operand %d",
7308 if (CONST_INT_P (op))
7309 opmode = mode;
7311 if ((opmode == SImode) && (mode == HImode))
7313 opmode = HImode;
7314 op = gen_lowpart (HImode, op);
7317 /* In case the insn wants input operands in modes different from
7318 the result, abort. */
7319 gcc_assert (opmode == mode || opmode == VOIDmode);
7321 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
7322 op = copy_to_mode_reg (mode, op);
7324 xop[j] = op;
7327 pat = apply_GEN_FCN (icode, xop);
7328 if (pat == NULL_RTX)
7329 return NULL_RTX;
7331 emit_insn (pat);
7333 if (nonvoid)
7334 return target;
7335 else
7336 return const0_rtx;
7339 /* Implement TARGET_FOLD_BUILTIN. */
7341 static tree
7342 arc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
7343 bool ignore ATTRIBUTE_UNUSED)
7345 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
7347 switch (fcode)
7349 default:
7350 break;
7352 case ARC_BUILTIN_SWAP:
7353 return fold_build2 (LROTATE_EXPR, integer_type_node, arg[0],
7354 build_int_cst (integer_type_node, 16));
7356 case ARC_BUILTIN_NORM:
7357 if (TREE_CODE (arg[0]) == INTEGER_CST
7358 && !TREE_OVERFLOW (arg[0]))
7360 wide_int arg0 = wi::to_wide (arg[0], 32);
7361 wide_int result = wi::shwi (wi::clrsb (arg0), 32);
7362 return wide_int_to_tree (integer_type_node, result);
7364 break;
7366 case ARC_BUILTIN_NORMW:
7367 if (TREE_CODE (arg[0]) == INTEGER_CST
7368 && !TREE_OVERFLOW (arg[0]))
7370 wide_int arg0 = wi::to_wide (arg[0], 16);
7371 wide_int result = wi::shwi (wi::clrsb (arg0), 32);
7372 return wide_int_to_tree (integer_type_node, result);
7374 break;
7376 return NULL_TREE;
7379 /* Returns true if the operands[opno] is a valid compile-time constant to be
7380 used as register number in the code for builtins. Else it flags an error
7381 and returns false. */
7383 bool
7384 check_if_valid_regno_const (rtx *operands, int opno)
7387 switch (GET_CODE (operands[opno]))
7389 case SYMBOL_REF :
7390 case CONST :
7391 case CONST_INT :
7392 return true;
7393 default:
7394 error ("register number must be a compile-time constant. "
7395 "Try giving higher optimization levels");
7396 break;
7398 return false;
7401 /* Return true if it is ok to make a tail-call to DECL. */
7403 static bool
7404 arc_function_ok_for_sibcall (tree decl,
7405 tree exp ATTRIBUTE_UNUSED)
7407 tree attrs = NULL_TREE;
7409 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7410 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
7411 return false;
7413 if (decl)
7415 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
7417 if (lookup_attribute ("jli_always", attrs))
7418 return false;
7419 if (lookup_attribute ("jli_fixed", attrs))
7420 return false;
7421 if (lookup_attribute ("secure_call", attrs))
7422 return false;
7425 /* Everything else is ok. */
7426 return true;
7429 /* Output code to add DELTA to the first argument, and then jump
7430 to FUNCTION. Used for C++ multiple inheritance. */
7432 static void
7433 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7434 HOST_WIDE_INT delta,
7435 HOST_WIDE_INT vcall_offset,
7436 tree function)
7438 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
7439 int mi_delta = delta;
7440 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
7441 int shift = 0;
7442 int this_regno
7443 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
7444 rtx fnaddr;
7446 assemble_start_function (thunk, fnname);
7448 if (mi_delta < 0)
7449 mi_delta = - mi_delta;
7451 /* Add DELTA. When possible use a plain add, otherwise load it into
7452 a register first. */
7454 while (mi_delta != 0)
7456 if ((mi_delta & (3 << shift)) == 0)
7457 shift += 2;
7458 else
7460 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
7461 mi_op, reg_names[this_regno], reg_names[this_regno],
7462 mi_delta & (0xff << shift));
7463 mi_delta &= ~(0xff << shift);
7464 shift += 8;
7468 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7469 if (vcall_offset != 0)
7471 /* ld r12,[this] --> temp = *this
7472 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7473 ld r12,[r12]
7474 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7475 asm_fprintf (file, "\tld\t%s, [%s]\n",
7476 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
7477 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
7478 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7479 asm_fprintf (file, "\tld\t%s, [%s]\n",
7480 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7481 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7482 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7485 fnaddr = XEXP (DECL_RTL (function), 0);
7487 if (arc_is_longcall_p (fnaddr))
7489 if (flag_pic)
7491 asm_fprintf (file, "\tld\t%s, [pcl, @",
7492 ARC_TEMP_SCRATCH_REG);
7493 assemble_name (file, XSTR (fnaddr, 0));
7494 fputs ("@gotpc]\n", file);
7495 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7497 else
7499 fputs ("\tj\t@", file);
7500 assemble_name (file, XSTR (fnaddr, 0));
7503 else
7505 fputs ("\tb\t@", file);
7506 assemble_name (file, XSTR (fnaddr, 0));
7507 if (flag_pic)
7508 fputs ("@plt\n", file);
7510 fputc ('\n', file);
7511 assemble_end_function (thunk, fnname);
7514 /* Return true if a 32 bit "long_call" should be generated for
7515 this calling SYM_REF. We generate a long_call if the function:
7517 a. has an __attribute__((long call))
7518 or b. the -mlong-calls command line switch has been specified
7520 However we do not generate a long call if the function has an
7521 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7523 This function will be called by C fragments contained in the machine
7524 description file. */
7526 bool
7527 arc_is_longcall_p (rtx sym_ref)
7529 if (GET_CODE (sym_ref) != SYMBOL_REF)
7530 return false;
7532 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7533 || (TARGET_LONG_CALLS_SET
7534 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7535 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7539 /* Likewise for short calls. */
7541 bool
7542 arc_is_shortcall_p (rtx sym_ref)
7544 if (GET_CODE (sym_ref) != SYMBOL_REF)
7545 return false;
7547 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7548 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7549 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7550 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7554 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7556 static bool
7557 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7559 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7560 return true;
7561 else
7563 HOST_WIDE_INT size = int_size_in_bytes (type);
7564 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
7568 static bool
7569 arc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
7571 return (arg.type != 0
7572 && (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST
7573 || TREE_ADDRESSABLE (arg.type)));
7576 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7578 static bool
7579 arc_can_use_doloop_p (const widest_int &,
7580 const widest_int &iterations_max,
7581 unsigned int loop_depth, bool entered_at_top)
7583 /* Considering limitations in the hardware, only use doloop
7584 for innermost loops which must be entered from the top. */
7585 if (loop_depth > 1 || !entered_at_top)
7586 return false;
7588 /* Check for lp_count width boundary. */
7589 if (arc_lpcwidth != 32
7590 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7591 || wi::eq_p (iterations_max, 0)))
7592 return false;
7593 return true;
7596 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7597 return why doloop cannot be applied. */
7599 static const char *
7600 arc_invalid_within_doloop (const rtx_insn *insn)
7602 if (CALL_P (insn))
7603 return "Function call in the loop.";
7605 /* FIXME! add here all the ZOL exceptions. */
7606 return NULL;
7609 /* Return the next active insn, skiping the inline assembly code. */
7611 static rtx_insn *
7612 arc_active_insn (rtx_insn *insn)
7614 while (insn)
7616 insn = NEXT_INSN (insn);
7617 if (insn == 0
7618 || (active_insn_p (insn)
7619 && NONDEBUG_INSN_P (insn)
7620 && !NOTE_P (insn)
7621 && GET_CODE (PATTERN (insn)) != UNSPEC_VOLATILE
7622 && GET_CODE (PATTERN (insn)) != PARALLEL))
7623 break;
7625 return insn;
7628 /* Search for a sequence made out of two stores and a given number of
7629 loads, insert a nop if required. */
7631 static void
7632 check_store_cacheline_hazard (void)
7634 rtx_insn *insn, *succ0, *insn1;
7635 bool found = false;
7637 for (insn = get_insns (); insn; insn = arc_active_insn (insn))
7639 succ0 = arc_active_insn (insn);
7641 if (!succ0)
7642 return;
7644 if (!single_set (insn))
7645 continue;
7647 if ((get_attr_type (insn) != TYPE_STORE))
7648 continue;
7650 /* Found at least two consecutive stores. Goto the end of the
7651 store sequence. */
7652 for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1))
7653 if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE)
7654 break;
7656 /* Save were we are. */
7657 succ0 = insn1;
7659 /* Now, check the next two instructions for the following cases:
7660 1. next instruction is a LD => insert 2 nops between store
7661 sequence and load.
7662 2. next-next instruction is a LD => inset 1 nop after the store
7663 sequence. */
7664 if (insn1 && single_set (insn1)
7665 && (get_attr_type (insn1) == TYPE_LOAD))
7667 found = true;
7668 emit_insn_before (gen_nopv (), insn1);
7669 emit_insn_before (gen_nopv (), insn1);
7671 else
7673 if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE))
7675 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7676 reorg, so it is safe to reuse it for avoiding the
7677 current compare insn to be part of a BRcc
7678 optimization. */
7679 add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3));
7681 insn1 = arc_active_insn (insn1);
7682 if (insn1 && single_set (insn1)
7683 && (get_attr_type (insn1) == TYPE_LOAD))
7685 found = true;
7686 emit_insn_before (gen_nopv (), insn1);
7690 if (found)
7692 insn = insn1;
7693 found = false;
7695 else
7696 insn = succ0;
7700 /* Return true if a load instruction (CONSUMER) uses the same address as a
7701 store instruction (PRODUCER). This function is used to avoid st/ld
7702 address hazard in ARC700 cores. */
7704 static bool
7705 arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer)
7707 rtx in_set, out_set;
7708 rtx out_addr, in_addr;
7710 if (!producer)
7711 return false;
7713 if (!consumer)
7714 return false;
7716 /* Peel the producer and the consumer for the address. */
7717 out_set = single_set (producer);
7718 if (out_set)
7720 out_addr = SET_DEST (out_set);
7721 if (!out_addr)
7722 return false;
7723 if (GET_CODE (out_addr) == ZERO_EXTEND
7724 || GET_CODE (out_addr) == SIGN_EXTEND)
7725 out_addr = XEXP (out_addr, 0);
7727 if (!MEM_P (out_addr))
7728 return false;
7730 in_set = single_set (consumer);
7731 if (in_set)
7733 in_addr = SET_SRC (in_set);
7734 if (!in_addr)
7735 return false;
7736 if (GET_CODE (in_addr) == ZERO_EXTEND
7737 || GET_CODE (in_addr) == SIGN_EXTEND)
7738 in_addr = XEXP (in_addr, 0);
7740 if (!MEM_P (in_addr))
7741 return false;
7742 /* Get rid of the MEM and check if the addresses are
7743 equivalent. */
7744 in_addr = XEXP (in_addr, 0);
7745 out_addr = XEXP (out_addr, 0);
7747 return exp_equiv_p (in_addr, out_addr, 0, true);
7750 return false;
7753 /* Return TRUE is we have an store address hazard. */
7755 bool
7756 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7758 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
7759 return true;
7760 return arc_store_addr_hazard_internal_p (producer, consumer);
7763 /* Return length adjustment for INSN.
7764 For ARC600:
7765 A write to a core reg greater or equal to 32 must not be immediately
7766 followed by a use. Anticipate the length requirement to insert a nop
7767 between PRED and SUCC to prevent a hazard. */
7769 static int
7770 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
7772 if (!TARGET_ARC600)
7773 return 0;
7774 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
7775 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
7776 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
7777 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
7778 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7779 || recog_memoized (pred) == CODE_FOR_umul_600
7780 || recog_memoized (pred) == CODE_FOR_mac_600
7781 || recog_memoized (pred) == CODE_FOR_mul64_600
7782 || recog_memoized (pred) == CODE_FOR_mac64_600
7783 || recog_memoized (pred) == CODE_FOR_umul64_600
7784 || recog_memoized (pred) == CODE_FOR_umac64_600)
7785 return 0;
7786 subrtx_iterator::array_type array;
7787 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7789 const_rtx x = *iter;
7790 switch (GET_CODE (x))
7792 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7793 break;
7794 default:
7795 /* This is also fine for PRE/POST_MODIFY, because they
7796 contain a SET. */
7797 continue;
7799 rtx dest = XEXP (x, 0);
7800 /* Check if this sets a an extension register. N.B. we use 61 for the
7801 condition codes, which is definitely not an extension register. */
7802 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7803 /* Check if the same register is used by the PAT. */
7804 && (refers_to_regno_p
7805 (REGNO (dest),
7806 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7807 PATTERN (succ), 0)))
7808 return 4;
7810 return 0;
7813 /* For ARC600:
7814 A write to a core reg greater or equal to 32 must not be immediately
7815 followed by a use. Anticipate the length requirement to insert a nop
7816 between PRED and SUCC to prevent a hazard. */
7819 arc_hazard (rtx_insn *pred, rtx_insn *succ)
7821 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7822 return 0;
7824 if (TARGET_ARC600)
7825 return arc600_corereg_hazard (pred, succ);
7827 return 0;
7830 /* When compiling for release 310a, insert a nop before any
7831 conditional jump. */
7833 static int
7834 arc_check_release31a (rtx_insn *pred, rtx_insn *succ)
7836 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7837 return 0;
7839 if (!JUMP_P (pred) && !single_set (pred))
7840 return 0;
7842 if (!JUMP_P (succ) && !single_set (succ))
7843 return 0;
7845 if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
7846 switch (get_attr_type (pred))
7848 case TYPE_STORE:
7849 switch (get_attr_type (succ))
7851 case TYPE_BRCC:
7852 case TYPE_BRCC_NO_DELAY_SLOT:
7853 case TYPE_LOOP_END:
7854 return 1;
7855 default:
7856 break;
7858 break;
7859 case TYPE_BRCC:
7860 case TYPE_BRCC_NO_DELAY_SLOT:
7861 case TYPE_LOOP_END:
7862 if (get_attr_type (succ) == TYPE_STORE)
7863 return 1;
7864 break;
7865 default:
7866 break;
7869 return 0;
7872 /* The same functionality as arc_hazard. It is called in machine
7873 reorg before any other optimization. Hence, the NOP size is taken
7874 into account when doing branch shortening. */
7876 static void
7877 workaround_arc_anomaly (void)
7879 rtx_insn *insn, *succ0;
7881 /* For any architecture: call arc_hazard here. */
7882 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7884 succ0 = next_real_insn (insn);
7885 if (arc_hazard (insn, succ0) || arc_check_release31a (insn, succ0))
7886 emit_insn_before (gen_nopv (), succ0);
7889 if (!TARGET_ARC700)
7890 return;
7892 /* Old A7 are suffering of a cache hazard, and we need to insert two
7893 nops between any sequence of stores and a load. */
7894 if (arc_tune != ARC_TUNE_ARC7XX)
7895 check_store_cacheline_hazard ();
7898 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7899 turns out not to be optimizable; we have to split the loop_end pattern into
7900 a subtract and a test. */
7902 static void
7903 hwloop_fail (hwloop_info loop)
7905 rtx test;
7906 rtx insn = loop->loop_end;
7908 if (TARGET_DBNZ
7909 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7910 && REG_P (loop->iter_reg))
7912 /* TARGET_V2 core3 has dbnz instructions. */
7913 test = gen_dbnz (loop->iter_reg, loop->start_label);
7914 insn = emit_jump_insn_before (test, loop->loop_end);
7916 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7918 /* We have the lp_count as loop iterator, try to use it. */
7919 emit_insn_before (gen_loop_fail (), loop->loop_end);
7920 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7921 const0_rtx);
7922 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7923 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7924 pc_rtx);
7925 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7926 loop->loop_end);
7928 else
7930 emit_insn_before (gen_addsi3 (loop->iter_reg,
7931 loop->iter_reg,
7932 constm1_rtx),
7933 loop->loop_end);
7934 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7935 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7936 loop->iter_reg,
7937 const0_rtx,
7938 loop->start_label),
7939 loop->loop_end);
7941 JUMP_LABEL (insn) = loop->start_label;
7942 LABEL_NUSES (loop->start_label)++;
7943 delete_insn (loop->loop_end);
7946 /* Return the next insn after INSN that is not a NOTE, but stop the
7947 search before we enter another basic block. This routine does not
7948 look inside SEQUENCEs. */
7950 static rtx_insn *
7951 next_nonnote_insn_bb (rtx_insn *insn)
7953 while (insn)
7955 insn = NEXT_INSN (insn);
7956 if (insn == 0 || !NOTE_P (insn))
7957 break;
7958 if (NOTE_INSN_BASIC_BLOCK_P (insn))
7959 return NULL;
7962 return insn;
7965 /* Optimize LOOP. */
7967 static bool
7968 hwloop_optimize (hwloop_info loop)
7970 int i;
7971 edge entry_edge;
7972 basic_block entry_bb, bb;
7973 rtx iter_reg;
7974 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label;
7975 unsigned int length;
7976 bool need_fix = false;
7977 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7979 if (loop->depth > 1)
7981 if (dump_file)
7982 fprintf (dump_file, ";; loop %d is not innermost\n",
7983 loop->loop_no);
7984 return false;
7987 if (!loop->incoming_dest)
7989 if (dump_file)
7990 fprintf (dump_file, ";; loop %d has more than one entry\n",
7991 loop->loop_no);
7992 return false;
7995 if (loop->incoming_dest != loop->head)
7997 if (dump_file)
7998 fprintf (dump_file, ";; loop %d is not entered from head\n",
7999 loop->loop_no);
8000 return false;
8003 if (loop->has_call || loop->has_asm)
8005 if (dump_file)
8006 fprintf (dump_file, ";; loop %d has invalid insn\n",
8007 loop->loop_no);
8008 return false;
8011 /* Scan all the blocks to make sure they don't use iter_reg. */
8012 if (loop->iter_reg_used || loop->iter_reg_used_outside)
8014 if (dump_file)
8015 fprintf (dump_file, ";; loop %d uses iterator\n",
8016 loop->loop_no);
8017 return false;
8020 /* Check if start_label appears before doloop_end. */
8021 length = 0;
8022 for (insn = loop->start_label;
8023 insn && insn != loop->loop_end;
8024 insn = NEXT_INSN (insn))
8026 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
8027 if (JUMP_TABLES_IN_TEXT_SECTION
8028 && JUMP_TABLE_DATA_P (insn))
8030 if (dump_file)
8031 fprintf (dump_file, ";; loop %d has a jump table\n",
8032 loop->loop_no);
8033 return false;
8037 if (!insn)
8039 if (dump_file)
8040 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
8041 loop->loop_no);
8042 return false;
8045 loop->length = length;
8046 if (loop->length > ARC_MAX_LOOP_LENGTH)
8048 if (dump_file)
8049 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
8050 return false;
8052 else if (!loop->length)
8054 if (dump_file)
8055 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
8056 return false;
8059 /* Check if we use a register or not. */
8060 if (!REG_P (loop->iter_reg))
8062 if (dump_file)
8063 fprintf (dump_file, ";; loop %d iterator is MEM\n",
8064 loop->loop_no);
8065 return false;
8068 /* Check if we use a register or not. */
8069 if (!REG_P (loop->iter_reg))
8071 if (dump_file)
8072 fprintf (dump_file, ";; loop %d iterator is MEM\n",
8073 loop->loop_no);
8074 return false;
8077 /* Check if loop register is lpcount. */
8078 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
8080 if (dump_file)
8081 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
8082 " iterator\n",
8083 loop->loop_no);
8084 /* This loop doesn't use the lp_count, check though if we can
8085 fix it. */
8086 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
8087 /* In very unique cases we may have LP_COUNT alive. */
8088 || (loop->incoming_src
8089 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
8090 LP_COUNT)))
8092 if (dump_file)
8093 fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no);
8094 return false;
8096 else
8097 need_fix = true;
8100 /* Check for control like instruction as the last instruction of a
8101 ZOL. */
8102 bb = loop->tail;
8103 last_insn = PREV_INSN (loop->loop_end);
8105 while (1)
8107 for (; last_insn != BB_HEAD (bb);
8108 last_insn = PREV_INSN (last_insn))
8109 if (NONDEBUG_INSN_P (last_insn))
8110 break;
8112 if (last_insn != BB_HEAD (bb))
8113 break;
8115 if (single_pred_p (bb)
8116 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
8117 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
8119 bb = single_pred (bb);
8120 last_insn = BB_END (bb);
8121 continue;
8123 else
8125 last_insn = NULL;
8126 break;
8130 if (!last_insn)
8132 if (dump_file)
8133 fprintf (dump_file, ";; loop %d has no last instruction\n",
8134 loop->loop_no);
8135 return false;
8138 if ((TARGET_ARC600_FAMILY || TARGET_HS)
8139 && INSN_P (last_insn)
8140 && (JUMP_P (last_insn) || CALL_P (last_insn)
8141 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
8142 /* At this stage we can have (insn (clobber (mem:BLK
8143 (reg)))) instructions, ignore them. */
8144 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
8145 && (get_attr_type (last_insn) == TYPE_BRCC
8146 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
8148 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
8150 if (dump_file)
8151 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
8152 return false;
8154 if (dump_file)
8155 fprintf (dump_file, ";; loop %d has a control like last insn; "
8156 "add a nop\n",
8157 loop->loop_no);
8159 last_insn = emit_insn_after (gen_nopv (), last_insn);
8162 if (LABEL_P (last_insn))
8164 if (dump_file)
8165 fprintf (dump_file, ";; loop %d has a label as last insn; "
8166 "add a nop\n",
8167 loop->loop_no);
8168 last_insn = emit_insn_after (gen_nopv (), last_insn);
8171 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
8172 and we can use it to indicate the last ZOL instruction cannot be
8173 part of a delay slot. */
8174 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
8176 loop->last_insn = last_insn;
8178 /* Get the loop iteration register. */
8179 iter_reg = loop->iter_reg;
8181 gcc_assert (REG_P (iter_reg));
8183 entry_edge = NULL;
8185 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
8186 if (entry_edge->flags & EDGE_FALLTHRU)
8187 break;
8189 if (entry_edge == NULL)
8191 if (dump_file)
8192 fprintf (dump_file, ";; loop %d has no fallthru edge jumping "
8193 "into the loop\n",
8194 loop->loop_no);
8195 return false;
8197 /* The loop is good. */
8198 end_label = gen_label_rtx ();
8199 loop->end_label = end_label;
8201 /* Place the zero_cost_loop_start instruction before the loop. */
8202 entry_bb = entry_edge->src;
8204 start_sequence ();
8206 if (need_fix)
8208 /* The loop uses a R-register, but the lp_count is free, thus
8209 use lp_count. */
8210 emit_insn (gen_rtx_SET (lp_reg, iter_reg));
8211 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
8212 iter_reg = lp_reg;
8213 if (dump_file)
8215 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
8216 loop->loop_no);
8220 insn = emit_insn (gen_arc_lp (loop->start_label,
8221 loop->end_label));
8223 seq = get_insns ();
8224 end_sequence ();
8226 entry_after = BB_END (entry_bb);
8227 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
8228 || !entry_after)
8230 basic_block new_bb;
8231 edge e;
8232 edge_iterator ei;
8234 emit_insn_before (seq, BB_HEAD (loop->head));
8235 seq = emit_label_before (gen_label_rtx (), seq);
8236 new_bb = create_basic_block (seq, insn, entry_bb);
8237 FOR_EACH_EDGE (e, ei, loop->incoming)
8239 if (!(e->flags & EDGE_FALLTHRU))
8240 redirect_edge_and_branch_force (e, new_bb);
8241 else
8242 redirect_edge_succ (e, new_bb);
8245 make_edge (new_bb, loop->head, 0);
8247 else
8249 #if 0
8250 while (DEBUG_INSN_P (entry_after)
8251 || (NOTE_P (entry_after)
8252 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
8253 /* Make sure we don't split a call and its corresponding
8254 CALL_ARG_LOCATION note. */
8255 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
8256 entry_after = NEXT_INSN (entry_after);
8257 #endif
8258 entry_after = next_nonnote_insn_bb (entry_after);
8260 gcc_assert (entry_after);
8261 emit_insn_before (seq, entry_after);
8264 /* Insert the loop end label before the last instruction of the
8265 loop. */
8266 emit_label_after (end_label, loop->last_insn);
8267 /* Make sure we mark the begining and end label as used. */
8268 LABEL_NUSES (loop->end_label)++;
8269 LABEL_NUSES (loop->start_label)++;
8271 return true;
8274 /* A callback for the hw-doloop pass. This function examines INSN; if
8275 it is a loop_end pattern we recognize, return the reg rtx for the
8276 loop counter. Otherwise, return NULL_RTX. */
8278 static rtx
8279 hwloop_pattern_reg (rtx_insn *insn)
8281 rtx reg;
8283 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
8284 return NULL_RTX;
8286 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
8287 if (!REG_P (reg))
8288 return NULL_RTX;
8289 return reg;
8292 static struct hw_doloop_hooks arc_doloop_hooks =
8294 hwloop_pattern_reg,
8295 hwloop_optimize,
8296 hwloop_fail
8299 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8300 and tries to rewrite the RTL of these loops so that proper Blackfin
8301 hardware loops are generated. */
8303 static void
8304 arc_reorg_loops (void)
8306 reorg_loops (true, &arc_doloop_hooks);
8309 /* Scan all calls and add symbols to be emitted in the jli section if
8310 needed. */
8312 static void
8313 jli_call_scan (void)
8315 rtx_insn *insn;
8317 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8319 if (!CALL_P (insn))
8320 continue;
8322 rtx pat = PATTERN (insn);
8323 if (GET_CODE (pat) == COND_EXEC)
8324 pat = COND_EXEC_CODE (pat);
8325 pat = XVECEXP (pat, 0, 0);
8326 if (GET_CODE (pat) == SET)
8327 pat = SET_SRC (pat);
8329 pat = XEXP (XEXP (pat, 0), 0);
8330 if (GET_CODE (pat) == SYMBOL_REF
8331 && arc_is_jli_call_p (pat))
8332 arc_add_jli_section (pat);
8336 /* Add padding if necessary to avoid a mispredict. A return could
8337 happen immediately after the function start. A call/return and
8338 return/return must be 6 bytes apart to avoid mispredict. */
8340 static void
8341 pad_return (void)
8343 rtx_insn *insn;
8344 long offset;
8346 if (!TARGET_PAD_RETURN)
8347 return;
8349 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8351 rtx_insn *prev0 = prev_active_insn (insn);
8352 bool wantlong = false;
8354 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN)
8355 continue;
8357 if (!prev0)
8359 prev0 = emit_insn_before (gen_nopv (), insn);
8360 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8361 so it is safe to reuse it for forcing a particular length
8362 for an instruction. */
8363 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8364 emit_insn_before (gen_nopv (), insn);
8365 continue;
8367 offset = get_attr_length (prev0);
8369 if (get_attr_length (prev0) == 2
8370 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE)
8372 /* Force long version of the insn. */
8373 wantlong = true;
8374 offset += 2;
8377 rtx_insn *prev = prev_active_insn (prev0);
8378 if (prev)
8379 offset += get_attr_length (prev);
8381 prev = prev_active_insn (prev);
8382 if (prev)
8383 offset += get_attr_length (prev);
8385 switch (offset)
8387 case 2:
8388 prev = emit_insn_before (gen_nopv (), insn);
8389 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1));
8390 break;
8391 case 4:
8392 emit_insn_before (gen_nopv (), insn);
8393 break;
8394 default:
8395 continue;
8398 if (wantlong)
8399 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8401 /* Emit a blockage to avoid delay slot scheduling. */
8402 emit_insn_before (gen_blockage (), insn);
8406 static int arc_reorg_in_progress = 0;
8408 /* ARC's machince specific reorg function. */
8410 static void
8411 arc_reorg (void)
8413 rtx_insn *insn;
8414 rtx pattern;
8415 rtx pc_target;
8416 long offset;
8417 int changed;
8419 cfun->machine->arc_reorg_started = 1;
8420 arc_reorg_in_progress = 1;
8422 compute_bb_for_insn ();
8424 df_analyze ();
8426 /* Doloop optimization. */
8427 arc_reorg_loops ();
8429 workaround_arc_anomaly ();
8430 jli_call_scan ();
8431 pad_return ();
8433 /* There are cases when conditional execution is only possible after
8434 delay slot scheduling:
8436 - If a delay slot is filled with a nocond/set insn from above, the previous
8437 basic block can become elegible for conditional execution.
8438 - If a delay slot is filled with a nocond insn from the fall-through path,
8439 the branch with that delay slot can become eligble for conditional
8440 execution (however, with the same sort of data flow analysis that dbr
8441 does, we could have figured out before that we don't need to
8442 conditionalize this insn.)
8443 - If a delay slot insn is filled with an insn from the target, the
8444 target label gets its uses decremented (even deleted if falling to zero),
8445 thus possibly creating more condexec opportunities there.
8446 Therefore, we should still be prepared to apply condexec optimization on
8447 non-prepared branches if the size increase of conditionalized insns is no
8448 more than the size saved from eliminating the branch. An invocation option
8449 could also be used to reserve a bit of extra size for condbranches so that
8450 this'll work more often (could also test in arc_reorg if the block is
8451 'close enough' to be eligible for condexec to make this likely, and
8452 estimate required size increase). */
8453 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8454 if (TARGET_NO_BRCC_SET)
8455 return;
8459 init_insn_lengths();
8460 changed = 0;
8462 /* Call shorten_branches to calculate the insn lengths. */
8463 shorten_branches (get_insns());
8465 if (!INSN_ADDRESSES_SET_P())
8466 fatal_error (input_location,
8467 "insn addresses not set after shorten branches");
8469 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8471 rtx label;
8472 enum attr_type insn_type;
8474 /* If a non-jump insn (or a casesi jump table), continue. */
8475 if (GET_CODE (insn) != JUMP_INSN ||
8476 GET_CODE (PATTERN (insn)) == ADDR_VEC
8477 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
8478 continue;
8480 /* If we already have a brcc, note if it is suitable for brcc_s.
8481 Be a bit generous with the brcc_s range so that we can take
8482 advantage of any code shortening from delay slot scheduling. */
8483 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
8485 rtx pat = PATTERN (insn);
8486 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
8487 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
8489 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8490 if ((offset >= -140 && offset < 140)
8491 && rtx_equal_p (XEXP (op, 1), const0_rtx)
8492 && compact_register_operand (XEXP (op, 0), VOIDmode)
8493 && equality_comparison_operator (op, VOIDmode))
8494 PUT_MODE (*ccp, CC_Zmode);
8495 else if (GET_MODE (*ccp) == CC_Zmode)
8496 PUT_MODE (*ccp, CC_ZNmode);
8497 continue;
8499 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
8500 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
8501 continue;
8503 /* OK. so we have a jump insn. */
8504 /* We need to check that it is a bcc. */
8505 /* Bcc => set (pc) (if_then_else ) */
8506 pattern = PATTERN (insn);
8507 if (GET_CODE (pattern) != SET
8508 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
8509 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
8510 continue;
8512 /* Now check if the jump is beyond the s9 range. */
8513 if (CROSSING_JUMP_P (insn))
8514 continue;
8515 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8517 if(offset > 253 || offset < -254)
8518 continue;
8520 pc_target = SET_SRC (pattern);
8522 /* Avoid FPU instructions. */
8523 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
8524 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUEmode)
8525 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
8526 continue;
8528 /* Now go back and search for the set cc insn. */
8530 label = XEXP (pc_target, 1);
8533 rtx pat;
8534 rtx_insn *scan, *link_insn = NULL;
8536 for (scan = PREV_INSN (insn);
8537 scan && GET_CODE (scan) != CODE_LABEL;
8538 scan = PREV_INSN (scan))
8540 if (! INSN_P (scan))
8541 continue;
8542 pat = PATTERN (scan);
8543 if (GET_CODE (pat) == SET
8544 && cc_register (SET_DEST (pat), VOIDmode))
8546 link_insn = scan;
8547 break;
8550 if (!link_insn)
8551 continue;
8552 else
8554 /* Check if this is a data dependency. */
8555 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
8556 rtx cmp0, cmp1;
8558 /* Make sure we can use it for brcc insns. */
8559 if (find_reg_note (link_insn, REG_SAVE_NOTE, GEN_INT (3)))
8560 continue;
8562 /* Ok this is the set cc. copy args here. */
8563 op = XEXP (pc_target, 0);
8565 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
8566 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
8567 if (GET_CODE (op0) == ZERO_EXTRACT
8568 && XEXP (op0, 1) == const1_rtx
8569 && (GET_CODE (op) == EQ
8570 || GET_CODE (op) == NE))
8572 /* btst / b{eq,ne} -> bbit{0,1} */
8573 op0 = XEXP (cmp0, 0);
8574 op1 = XEXP (cmp0, 2);
8576 else if (!register_operand (op0, VOIDmode)
8577 || !general_operand (op1, VOIDmode))
8578 continue;
8579 /* Be careful not to break what cmpsfpx_raw is
8580 trying to create for checking equality of
8581 single-precision floats. */
8582 else if (TARGET_SPFP
8583 && GET_MODE (op0) == SFmode
8584 && GET_MODE (op1) == SFmode)
8585 continue;
8587 /* None of the two cmp operands should be set between the
8588 cmp and the branch. */
8589 if (reg_set_between_p (op0, link_insn, insn))
8590 continue;
8592 if (reg_set_between_p (op1, link_insn, insn))
8593 continue;
8595 /* Since the MODE check does not work, check that this is
8596 CC reg's last set location before insn, and also no
8597 instruction between the cmp and branch uses the
8598 condition codes. */
8599 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
8600 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
8601 continue;
8603 /* CC reg should be dead after insn. */
8604 if (!find_regno_note (insn, REG_DEAD, CC_REG))
8605 continue;
8607 op = gen_rtx_fmt_ee (GET_CODE (op),
8608 GET_MODE (op), cmp0, cmp1);
8609 /* If we create a LIMM where there was none before,
8610 we only benefit if we can avoid a scheduling bubble
8611 for the ARC600. Otherwise, we'd only forgo chances
8612 at short insn generation, and risk out-of-range
8613 branches. */
8614 if (!brcc_nolimm_operator (op, VOIDmode)
8615 && !long_immediate_operand (op1, VOIDmode)
8616 && (TARGET_ARC700
8617 || (TARGET_V2 && optimize_size)
8618 || next_active_insn (link_insn) != insn))
8619 continue;
8621 /* Emit bbit / brcc (or brcc_s if possible).
8622 CC_Zmode indicates that brcc_s is possible. */
8624 if (op0 != cmp0)
8625 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
8626 else if ((offset >= -140 && offset < 140)
8627 && rtx_equal_p (op1, const0_rtx)
8628 && compact_register_operand (op0, VOIDmode)
8629 && (GET_CODE (op) == EQ
8630 || GET_CODE (op) == NE))
8631 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
8632 else
8633 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
8635 brcc_insn
8636 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
8637 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
8638 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
8639 brcc_insn
8640 = gen_rtx_PARALLEL
8641 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
8642 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
8644 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
8645 note = find_reg_note (insn, REG_BR_PROB, 0);
8646 if (note)
8648 XEXP (note, 1) = REG_NOTES (brcc_insn);
8649 REG_NOTES (brcc_insn) = note;
8651 note = find_reg_note (link_insn, REG_DEAD, op0);
8652 if (note)
8654 remove_note (link_insn, note);
8655 XEXP (note, 1) = REG_NOTES (brcc_insn);
8656 REG_NOTES (brcc_insn) = note;
8658 note = find_reg_note (link_insn, REG_DEAD, op1);
8659 if (note)
8661 XEXP (note, 1) = REG_NOTES (brcc_insn);
8662 REG_NOTES (brcc_insn) = note;
8665 changed = 1;
8667 /* Delete the bcc insn. */
8668 set_insn_deleted (insn);
8670 /* Delete the cmp insn. */
8671 set_insn_deleted (link_insn);
8676 /* Clear out insn_addresses. */
8677 INSN_ADDRESSES_FREE ();
8679 } while (changed);
8681 if (INSN_ADDRESSES_SET_P())
8682 fatal_error (input_location, "insn addresses not freed");
8684 arc_reorg_in_progress = 0;
8687 /* Check if the operands are valid for BRcc.d generation
8688 Valid Brcc.d patterns are
8689 Brcc.d b, c, s9
8690 Brcc.d b, u6, s9
8692 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
8693 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8694 does not have a delay slot
8696 Assumed precondition: Second operand is either a register or a u6 value. */
8698 bool
8699 valid_brcc_with_delay_p (rtx *operands)
8701 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
8702 return false;
8703 return brcc_nolimm_operator (operands[0], VOIDmode);
8706 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8707 access DECL using %gp_rel(...)($gp). */
8709 static bool
8710 arc_in_small_data_p (const_tree decl)
8712 HOST_WIDE_INT size;
8713 tree attr;
8715 /* Only variables are going into small data area. */
8716 if (TREE_CODE (decl) != VAR_DECL)
8717 return false;
8719 if (TARGET_NO_SDATA_SET)
8720 return false;
8722 /* Disable sdata references to weak variables. */
8723 if (DECL_WEAK (decl))
8724 return false;
8726 /* Don't put constants into the small data section: we want them to
8727 be in ROM rather than RAM. */
8728 if (TREE_READONLY (decl))
8729 return false;
8731 /* To ensure -mvolatile-cache works ld.di does not have a
8732 gp-relative variant. */
8733 if (!TARGET_VOLATILE_CACHE_SET
8734 && TREE_THIS_VOLATILE (decl))
8735 return false;
8737 /* Likewise for uncached data. */
8738 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
8739 if (lookup_attribute ("uncached", attr))
8740 return false;
8742 /* and for aux regs. */
8743 attr = DECL_ATTRIBUTES (decl);
8744 if (lookup_attribute ("aux", attr))
8745 return false;
8747 if (DECL_SECTION_NAME (decl) != 0)
8749 const char *name = DECL_SECTION_NAME (decl);
8750 if (strcmp (name, ".sdata") == 0
8751 || strcmp (name, ".sbss") == 0)
8752 return true;
8754 /* If it's not public, there's no need to put it in the small data
8755 section. */
8756 else if (TREE_PUBLIC (decl))
8758 size = int_size_in_bytes (TREE_TYPE (decl));
8759 return (size > 0 && size <= g_switch_value);
8761 return false;
8764 /* Return true if OP is an acceptable memory operand for ARCompact
8765 16-bit gp-relative load instructions.
8767 /* volatile cache option still to be handled. */
8769 bool
8770 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
8772 rtx addr;
8773 int size;
8774 int align = 0;
8775 int mask = 0;
8777 /* Eliminate non-memory operations. */
8778 if (GET_CODE (op) != MEM)
8779 return false;
8781 if (mode == VOIDmode)
8782 mode = GET_MODE (op);
8784 size = GET_MODE_SIZE (mode);
8786 /* dword operations really put out 2 instructions, so eliminate them. */
8787 if (size > UNITS_PER_WORD)
8788 return false;
8790 /* Decode the address now. */
8791 addr = XEXP (op, 0);
8793 if (!legitimate_small_data_address_p (addr, mode))
8794 return false;
8796 if (!short_p || size == 1)
8797 return true;
8799 /* Now check for the alignment, the short loads using gp require the
8800 addresses to be aligned. */
8801 align = get_symbol_alignment (addr);
8802 switch (mode)
8804 case E_HImode:
8805 mask = 1;
8806 break;
8807 default:
8808 mask = 3;
8809 break;
8812 if (align && ((align & mask) == 0))
8813 return true;
8814 return false;
8817 /* Return TRUE if PAT is accessing an aux-reg. */
8819 static bool
8820 arc_is_aux_reg_p (rtx pat)
8822 tree attrs = NULL_TREE;
8823 tree addr;
8825 if (!MEM_P (pat))
8826 return false;
8828 /* Get the memory attributes. */
8829 addr = MEM_EXPR (pat);
8830 if (!addr)
8831 return false;
8833 /* Get the attributes. */
8834 if (VAR_P (addr))
8835 attrs = DECL_ATTRIBUTES (addr);
8836 else if (TREE_CODE (addr) == MEM_REF)
8837 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8838 else
8839 return false;
8841 if (lookup_attribute ("aux", attrs))
8842 return true;
8843 return false;
8846 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8848 void
8849 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8850 unsigned HOST_WIDE_INT size,
8851 unsigned HOST_WIDE_INT align,
8852 unsigned HOST_WIDE_INT globalize_p)
8854 int in_small_data = arc_in_small_data_p (decl);
8855 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8857 /* Don't output aux-reg symbols. */
8858 if (mem != NULL_RTX && MEM_P (mem)
8859 && SYMBOL_REF_P (XEXP (mem, 0))
8860 && arc_is_aux_reg_p (mem))
8861 return;
8863 if (in_small_data)
8864 switch_to_section (get_named_section (NULL, ".sbss", 0));
8865 /* named_section (0,".sbss",0); */
8866 else
8867 switch_to_section (bss_section);
8869 if (globalize_p)
8870 (*targetm.asm_out.globalize_label) (stream, name);
8872 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8873 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8874 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8875 ASM_OUTPUT_LABEL (stream, name);
8877 if (size != 0)
8878 ASM_OUTPUT_SKIP (stream, size);
8881 static bool
8882 arc_preserve_reload_p (rtx in)
8884 return (GET_CODE (in) == PLUS
8885 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8886 && CONST_INT_P (XEXP (in, 1))
8887 && !((INTVAL (XEXP (in, 1)) & 511)));
8890 /* Implement TARGET_REGISTER_MOVE_COST. */
8892 static int
8893 arc_register_move_cost (machine_mode,
8894 reg_class_t from_class, reg_class_t to_class)
8896 /* Force an attempt to 'mov Dy,Dx' to spill. */
8897 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
8898 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8899 return 100;
8901 return 2;
8904 /* Emit code for an addsi3 instruction with OPERANDS.
8905 COND_P indicates if this will use conditional execution.
8906 Return the length of the instruction.
8907 If OUTPUT_P is false, don't actually output the instruction, just return
8908 its length. */
8909 static int
8910 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8912 char format[35];
8914 int match = operands_match_p (operands[0], operands[1]);
8915 int match2 = operands_match_p (operands[0], operands[2]);
8916 int intval = (REG_P (operands[2]) ? 1
8917 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8918 int neg_intval = -intval;
8919 int short_0 = arc_check_short_reg_p (operands[0]);
8920 int short_p = (!cond_p && short_0 && arc_check_short_reg_p (operands[1]));
8921 int ret = 0;
8923 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8924 && REGNO (OP) != 30) \
8925 || !TARGET_V2))
8927 #define ADDSI_OUTPUT1(FORMAT) do {\
8928 if (output_p) \
8929 output_asm_insn (FORMAT, operands);\
8930 return ret; \
8931 } while (0)
8932 #define ADDSI_OUTPUT(LIST) do {\
8933 if (output_p) \
8934 sprintf LIST;\
8935 ADDSI_OUTPUT1 (format);\
8936 return ret; \
8937 } while (0)
8939 /* First try to emit a 16 bit insn. */
8940 ret = 2;
8941 if (!cond_p
8942 /* If we are actually about to output this insn, don't try a 16 bit
8943 variant if we already decided that we don't want that
8944 (I.e. we upsized this insn to align some following insn.)
8945 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8946 but add1 r0,sp,35 doesn't. */
8947 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8949 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8950 patterns. */
8951 if (short_p
8952 && ((REG_H_P (operands[2])
8953 && (match || arc_check_short_reg_p (operands[2])))
8954 || (CONST_INT_P (operands[2])
8955 && ((unsigned) intval <= (match ? 127 : 7)))))
8956 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8958 /* Generate add_s b,b,h patterns. */
8959 if (short_0 && match2 && REG_H_P (operands[1]))
8960 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8962 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8963 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8964 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8965 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8967 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8968 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8969 && match && !(neg_intval & ~124)))
8970 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8972 /* Generate add_s h,h,s3 patterns. */
8973 if (REG_H_P (operands[0]) && match && TARGET_V2
8974 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8975 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8977 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8978 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8979 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8980 && arc_check_short_reg_p (operands[1])
8981 && satisfies_constraint_L (operands[2]))
8982 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8985 /* Now try to emit a 32 bit insn without long immediate. */
8986 ret = 4;
8987 if (!match && match2 && REG_P (operands[1]))
8988 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8989 if (match || !cond_p)
8991 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8992 int range_factor = neg_intval & intval;
8993 int shift;
8995 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8996 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8998 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8999 same size, do, so - the insn latency is lower. */
9000 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
9001 0x800 is not. */
9002 if ((intval >= 0 && intval <= limit)
9003 || (intval == -0x800 && limit == 0x7ff))
9004 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
9005 else if ((intval < 0 && neg_intval <= limit)
9006 || (intval == 0x800 && limit == 0x7ff))
9007 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
9008 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
9009 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
9010 gcc_assert ((((1 << shift) - 1) & intval) == 0);
9011 if (((intval < 0 && intval != -0x4000)
9012 /* sub[123] is slower than add_s / sub, only use it if it
9013 avoids a long immediate. */
9014 && neg_intval <= limit << shift)
9015 || (intval == 0x4000 && limit == 0x7ff))
9016 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
9017 shift, neg_intval >> shift));
9018 else if ((intval >= 0 && intval <= limit << shift)
9019 || (intval == -0x4000 && limit == 0x7ff))
9020 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
9022 /* Try to emit a 16 bit opcode with long immediate. */
9023 ret = 6;
9024 if (short_p && match)
9025 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
9027 /* We have to use a 32 bit opcode, and with a long immediate. */
9028 ret = 8;
9029 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
9032 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
9033 Return the length of the instruction.
9034 If OUTPUT_P is false, don't actually output the instruction, just return
9035 its length. */
9037 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
9039 enum rtx_code commutative_op = GET_CODE (operands[3]);
9040 const char *pat = NULL;
9042 /* Canonical rtl should not have a constant in the first operand position. */
9043 gcc_assert (!CONSTANT_P (operands[1]));
9045 switch (commutative_op)
9047 case AND:
9048 if (satisfies_constraint_C1p (operands[2]))
9049 pat = "bmsk%? %0,%1,%Z2";
9050 else if (satisfies_constraint_C2p (operands[2]))
9052 operands[2] = GEN_INT ((~INTVAL (operands[2])));
9053 pat = "bmskn%? %0,%1,%Z2";
9055 else if (satisfies_constraint_Ccp (operands[2]))
9056 pat = "bclr%? %0,%1,%M2";
9057 else if (satisfies_constraint_CnL (operands[2]))
9058 pat = "bic%? %0,%1,%n2-1";
9059 break;
9060 case IOR:
9061 if (satisfies_constraint_C0p (operands[2]))
9062 pat = "bset%? %0,%1,%z2";
9063 break;
9064 case XOR:
9065 if (satisfies_constraint_C0p (operands[2]))
9066 pat = "bxor%? %0,%1,%z2";
9067 break;
9068 case PLUS:
9069 return arc_output_addsi (operands, true, output_p);
9070 default: break;
9072 if (output_p)
9073 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
9074 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
9075 return 4;
9076 return 8;
9079 /* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
9080 Emit code and return an potentially modified address such that offsets
9081 up to SIZE are can be added to yield a legitimate address.
9082 if REUSE is set, ADDR is a register that may be modified. */
9084 static rtx
9085 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
9087 rtx base = addr;
9088 rtx offs = const0_rtx;
9090 if (GET_CODE (base) == PLUS)
9092 offs = XEXP (base, 1);
9093 base = XEXP (base, 0);
9095 if (!REG_P (base)
9096 || (REGNO (base) != STACK_POINTER_REGNUM
9097 && REGNO_PTR_FRAME_P (REGNO (base)))
9098 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
9099 || !SMALL_INT (INTVAL (offs) + size))
9101 if (reuse)
9102 emit_insn (gen_add2_insn (addr, offs));
9103 else
9104 addr = copy_to_mode_reg (Pmode, addr);
9106 return addr;
9109 /* Like move_by_pieces, but take account of load latency, and actual
9110 offset ranges. Return true on success. */
9112 bool
9113 arc_expand_cpymem (rtx *operands)
9115 rtx dst = operands[0];
9116 rtx src = operands[1];
9117 rtx dst_addr, src_addr;
9118 HOST_WIDE_INT size;
9119 int align = INTVAL (operands[3]);
9120 unsigned n_pieces;
9121 int piece = align;
9122 rtx store[2];
9123 rtx tmpx[2];
9124 int i;
9126 if (!CONST_INT_P (operands[2]))
9127 return false;
9128 size = INTVAL (operands[2]);
9129 /* move_by_pieces_ninsns is static, so we can't use it. */
9130 if (align >= 4)
9132 if (TARGET_LL64)
9133 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
9134 else
9135 n_pieces = (size + 2) / 4U + (size & 1);
9137 else if (align == 2)
9138 n_pieces = (size + 1) / 2U;
9139 else
9140 n_pieces = size;
9141 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
9142 return false;
9143 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
9144 possible. */
9145 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
9146 piece = 8;
9147 else if (piece > 4)
9148 piece = 4;
9149 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
9150 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
9151 store[0] = store[1] = NULL_RTX;
9152 tmpx[0] = tmpx[1] = NULL_RTX;
9153 for (i = 0; size > 0; i ^= 1, size -= piece)
9155 rtx tmp;
9156 machine_mode mode;
9158 while (piece > size)
9159 piece >>= 1;
9160 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT).require ();
9161 /* If we don't re-use temporaries, the scheduler gets carried away,
9162 and the register pressure gets unnecessarily high. */
9163 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
9164 tmp = tmpx[i];
9165 else
9166 tmpx[i] = tmp = gen_reg_rtx (mode);
9167 dst_addr = force_offsettable (dst_addr, piece, 1);
9168 src_addr = force_offsettable (src_addr, piece, 1);
9169 if (store[i])
9170 emit_insn (store[i]);
9171 emit_move_insn (tmp, change_address (src, mode, src_addr));
9172 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
9173 dst_addr = plus_constant (Pmode, dst_addr, piece);
9174 src_addr = plus_constant (Pmode, src_addr, piece);
9176 if (store[i])
9177 emit_insn (store[i]);
9178 if (store[i^1])
9179 emit_insn (store[i^1]);
9180 return true;
9183 static bool
9184 arc_get_aux_arg (rtx pat, int *auxr)
9186 tree attr, addr = MEM_EXPR (pat);
9187 if (TREE_CODE (addr) != VAR_DECL)
9188 return false;
9190 attr = DECL_ATTRIBUTES (addr);
9191 if (lookup_attribute ("aux", attr))
9193 tree arg = TREE_VALUE (attr);
9194 if (arg)
9196 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
9197 return true;
9201 return false;
9204 /* Prepare operands for move in MODE. Return true iff the move has
9205 been emitted. */
9207 bool
9208 prepare_move_operands (rtx *operands, machine_mode mode)
9210 if ((MEM_P (operands[0]) || MEM_P (operands[1]))
9211 && SCALAR_INT_MODE_P (mode))
9213 /* First handle aux attribute. */
9214 if (mode == SImode)
9216 rtx tmp;
9217 int auxr = 0;
9218 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
9220 /* Save operation. */
9221 if (arc_get_aux_arg (operands[0], &auxr))
9223 tmp = gen_reg_rtx (SImode);
9224 emit_move_insn (tmp, GEN_INT (auxr));
9226 else
9227 tmp = XEXP (operands[0], 0);
9229 operands[1] = force_reg (SImode, operands[1]);
9230 emit_insn (gen_rtx_UNSPEC_VOLATILE
9231 (VOIDmode, gen_rtvec (2, operands[1], tmp),
9232 VUNSPEC_ARC_SR));
9233 return true;
9235 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
9237 if (arc_get_aux_arg (operands[1], &auxr))
9239 tmp = gen_reg_rtx (SImode);
9240 emit_move_insn (tmp, GEN_INT (auxr));
9242 else
9244 tmp = XEXP (operands[1], 0);
9245 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
9247 /* Load operation. */
9248 gcc_assert (REG_P (operands[0]));
9249 emit_insn (gen_rtx_SET (operands[0],
9250 gen_rtx_UNSPEC_VOLATILE
9251 (SImode, gen_rtvec (1, tmp),
9252 VUNSPEC_ARC_LR)));
9253 return true;
9256 /* Second, we check for the uncached. */
9257 if (arc_is_uncached_mem_p (operands[0]))
9259 if (!REG_P (operands[1]))
9260 operands[1] = force_reg (mode, operands[1]);
9261 emit_insn (gen_rtx_UNSPEC_VOLATILE
9262 (VOIDmode, gen_rtvec (2, operands[0], operands[1]),
9263 VUNSPEC_ARC_STDI));
9264 return true;
9266 if (arc_is_uncached_mem_p (operands[1]))
9268 rtx tmp = operands[0];
9270 if (MEM_P (operands[0]))
9271 tmp = gen_reg_rtx (mode);
9273 emit_insn (gen_rtx_SET
9274 (tmp,
9275 gen_rtx_UNSPEC_VOLATILE
9276 (mode, gen_rtvec (1, operands[1]),
9277 VUNSPEC_ARC_LDDI)));
9278 if (MEM_P (operands[0]))
9280 operands[1] = tmp;
9281 return false;
9283 return true;
9287 if (GET_CODE (operands[1]) == SYMBOL_REF)
9289 enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
9290 if (MEM_P (operands[0]))
9291 operands[1] = force_reg (mode, operands[1]);
9292 else if (model)
9293 operands[1] = arc_legitimize_tls_address (operands[1], model);
9296 operands[1] = arc_legitimize_pic_address (operands[1]);
9298 /* Store instructions are limited, they only accept as address an
9299 immediate, a register or a register plus a small immediate. */
9300 if (MEM_P (operands[0])
9301 && !move_dest_operand (operands[0], mode))
9303 rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9304 rtx tmp1 = change_address (operands[0], mode, tmp0);
9305 MEM_COPY_ATTRIBUTES (tmp1, operands[0]);
9306 operands[0] = tmp1;
9309 /* Check if it is constant but it is not legitimized. */
9310 if (CONSTANT_P (operands[1])
9311 && !arc_legitimate_constant_p (mode, operands[1]))
9312 operands[1] = force_reg (mode, XEXP (operands[1], 0));
9313 else if (MEM_P (operands[0])
9314 && ((CONSTANT_P (operands[1])
9315 && !satisfies_constraint_Cm3 (operands[1]))
9316 || MEM_P (operands[1])))
9317 operands[1] = force_reg (mode, operands[1]);
9319 return false;
9322 /* Output a library call to a function called FNAME that has been arranged
9323 to be local to any dso. */
9325 const char *
9326 arc_output_libcall (const char *fname)
9328 unsigned len = strlen (fname);
9329 static char buf[64];
9331 gcc_assert (len < sizeof buf - 35);
9332 if (TARGET_LONG_CALLS_SET)
9334 if (flag_pic)
9335 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
9336 else
9337 sprintf (buf, "jl%%! @%s", fname);
9339 else
9340 sprintf (buf, "bl%%!%%* @%s", fname);
9341 return buf;
9344 /* Return the SImode highpart of the DImode value IN. */
9347 disi_highpart (rtx in)
9349 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
9352 /* Given a rtx, check if it is an assembly instruction or not. */
9354 static int
9355 arc_asm_insn_p (rtx x)
9357 int i, j;
9359 if (x == 0)
9360 return 0;
9362 switch (GET_CODE (x))
9364 case ASM_OPERANDS:
9365 case ASM_INPUT:
9366 return 1;
9368 case SET:
9369 return arc_asm_insn_p (SET_SRC (x));
9371 case PARALLEL:
9372 j = 0;
9373 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
9374 j += arc_asm_insn_p (XVECEXP (x, 0, i));
9375 if ( j > 0)
9376 return 1;
9377 break;
9379 default:
9380 break;
9383 return 0;
9386 /* Return length adjustment for INSN. */
9389 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
9391 if (!INSN_P (insn))
9392 return len;
9393 /* We already handle sequences by ignoring the delay sequence flag. */
9394 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
9395 return len;
9397 /* Check for return with but one preceding insn since function
9398 start / call. */
9399 if (TARGET_PAD_RETURN
9400 && JUMP_P (insn)
9401 && GET_CODE (PATTERN (insn)) != ADDR_VEC
9402 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
9403 && get_attr_type (insn) == TYPE_RETURN)
9405 rtx_insn *prev = prev_active_insn (insn);
9407 if (!prev || !(prev = prev_active_insn (prev))
9408 || ((NONJUMP_INSN_P (prev)
9409 && GET_CODE (PATTERN (prev)) == SEQUENCE)
9410 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9411 NON_SIBCALL)
9412 : CALL_ATTR (prev, NON_SIBCALL)))
9413 return len + 4;
9415 if (TARGET_ARC600)
9417 rtx_insn *succ = next_real_insn (insn);
9419 /* One the ARC600, a write to an extension register must be separated
9420 from a read. */
9421 if (succ && INSN_P (succ))
9422 len += arc600_corereg_hazard (insn, succ);
9425 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9426 can go awry. */
9427 extract_constrain_insn_cached (insn);
9429 return len;
9432 /* Return version of PAT conditionalized with COND, which is part of INSN.
9433 ANNULLED indicates if INSN is an annulled delay-slot insn.
9434 Register further changes if necessary. */
9435 static rtx
9436 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
9438 /* For commutative operators, we generally prefer to have
9439 the first source match the destination. */
9440 if (GET_CODE (pat) == SET)
9442 rtx src = SET_SRC (pat);
9444 if (COMMUTATIVE_P (src))
9446 rtx src0 = XEXP (src, 0);
9447 rtx src1 = XEXP (src, 1);
9448 rtx dst = SET_DEST (pat);
9450 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
9451 /* Leave add_n alone - the canonical form is to
9452 have the complex summand first. */
9453 && REG_P (src0))
9454 pat = gen_rtx_SET (dst,
9455 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
9456 src1, src0));
9460 /* dwarf2out.cc:dwarf2out_frame_debug_expr doesn't know
9461 what to do with COND_EXEC. */
9462 if (RTX_FRAME_RELATED_P (insn))
9464 /* If this is the delay slot insn of an anulled branch,
9465 dwarf2out.cc:scan_trace understands the anulling semantics
9466 without the COND_EXEC. */
9467 gcc_assert (annulled);
9468 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
9469 REG_NOTES (insn));
9470 validate_change (insn, &REG_NOTES (insn), note, 1);
9472 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9473 return pat;
9477 /* Find annulled delay insns and convert them to use the appropriate predicate.
9478 This allows branch shortening to size up these insns properly. */
9480 static unsigned
9481 arc_predicate_delay_insns (void)
9483 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9485 rtx pat, jump, dlay, src, cond, *patp;
9486 int reverse;
9488 if (!NONJUMP_INSN_P (insn)
9489 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9490 continue;
9491 jump = XVECEXP (pat, 0, 0);
9492 dlay = XVECEXP (pat, 0, 1);
9493 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9494 continue;
9495 /* If the branch insn does the annulling, leave the delay insn alone. */
9496 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9497 continue;
9498 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9499 on the other path. */
9500 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9501 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9502 src = SET_SRC (PATTERN (jump));
9503 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9504 cond = XEXP (src, 0);
9505 if (XEXP (src, 2) == pc_rtx)
9506 reverse = 0;
9507 else if (XEXP (src, 1) == pc_rtx)
9508 reverse = 1;
9509 else
9510 gcc_unreachable ();
9511 if (reverse != !INSN_FROM_TARGET_P (dlay))
9513 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9514 enum rtx_code code = reverse_condition (GET_CODE (cond));
9515 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9516 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9518 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9519 copy_rtx (XEXP (cond, 0)),
9520 copy_rtx (XEXP (cond, 1)));
9522 else
9523 cond = copy_rtx (cond);
9524 patp = &PATTERN (dlay);
9525 pat = *patp;
9526 pat = conditionalize_nonjump (pat, cond, dlay, true);
9527 validate_change (dlay, patp, pat, 1);
9528 if (!apply_change_group ())
9529 gcc_unreachable ();
9531 return 0;
9534 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9535 (other than of a forward brcc), it creates a hazard when there is a read
9536 of the same register at the branch target. We can't know what is at the
9537 branch target of calls, and for branches, we don't really know before the
9538 end of delay slot scheduling, either. Not only can individual instruction
9539 be hoisted out into a delay slot, a basic block can also be emptied this
9540 way, and branch and/or fall through targets be redirected. Hence we don't
9541 want such writes in a delay slot. */
9543 /* Return nonzreo iff INSN writes to an extension core register. */
9546 arc_write_ext_corereg (rtx insn)
9548 subrtx_iterator::array_type array;
9549 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9551 const_rtx x = *iter;
9552 switch (GET_CODE (x))
9554 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9555 break;
9556 default:
9557 /* This is also fine for PRE/POST_MODIFY, because they
9558 contain a SET. */
9559 continue;
9561 const_rtx dest = XEXP (x, 0);
9562 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9563 return 1;
9565 return 0;
9568 /* This is like the hook, but returns NULL when it can't / won't generate
9569 a legitimate address. */
9571 static rtx
9572 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9573 machine_mode mode)
9575 rtx addr, inner;
9577 addr = x;
9578 if (GET_CODE (addr) == CONST)
9579 addr = XEXP (addr, 0);
9581 if (GET_CODE (addr) == PLUS
9582 && CONST_INT_P (XEXP (addr, 1))
9583 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9584 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9585 || (REG_P (XEXP (addr, 0))
9586 && (INTVAL (XEXP (addr, 1)) & 252))))
9588 HOST_WIDE_INT offs, upper;
9589 int size = GET_MODE_SIZE (mode);
9591 offs = INTVAL (XEXP (addr, 1));
9592 upper = (offs + 256 * size) & ~511 * size;
9593 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9594 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9595 if (GET_CODE (x) == CONST)
9596 inner = gen_rtx_CONST (Pmode, inner);
9597 #endif
9598 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9599 x = addr;
9601 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9602 x = force_reg (Pmode, x);
9603 if (memory_address_p ((machine_mode) mode, x))
9604 return x;
9605 return NULL_RTX;
9608 static rtx
9609 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9611 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9613 if (new_x)
9614 return new_x;
9615 return orig_x;
9618 static rtx
9619 arc_delegitimize_address_0 (rtx op)
9621 switch (GET_CODE (op))
9623 case CONST:
9624 return arc_delegitimize_address_0 (XEXP (op, 0));
9626 case UNSPEC:
9627 switch (XINT (op, 1))
9629 case ARC_UNSPEC_GOT:
9630 case ARC_UNSPEC_GOTOFFPC:
9631 return XVECEXP (op, 0, 0);
9632 default:
9633 break;
9635 break;
9637 case PLUS:
9639 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9640 rtx t2 = XEXP (op, 1);
9642 if (t1 && t2)
9643 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9644 break;
9647 default:
9648 break;
9650 return NULL_RTX;
9653 static rtx
9654 arc_delegitimize_address (rtx orig_x)
9656 rtx x = orig_x;
9658 if (MEM_P (x))
9659 x = XEXP (x, 0);
9661 x = arc_delegitimize_address_0 (x);
9662 if (!x)
9663 return orig_x;
9665 if (MEM_P (orig_x))
9666 x = replace_equiv_address_nv (orig_x, x);
9667 return x;
9670 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9671 differ from the hardware register number in order to allow the generic
9672 code to correctly split the concatenation of acc1 and acc2. */
9675 gen_acc1 (void)
9677 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56 : 57);
9680 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9681 differ from the hardware register number in order to allow the generic
9682 code to correctly split the concatenation of acc1 and acc2. */
9685 gen_acc2 (void)
9687 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57 : 56);
9690 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9691 are three reasons why we need to consider branches to be length 6:
9692 - annull-false delay slot insns are implemented using conditional execution,
9693 thus preventing short insn formation where used.
9694 - for ARC600: annul-true delay slot insns are implemented where possible
9695 using conditional execution, preventing short insn formation where used.
9696 - for ARC700: likely or somewhat likely taken branches are made long and
9697 unaligned if possible to avoid branch penalty. */
9699 bool
9700 arc_branch_size_unknown_p (void)
9702 return !optimize_size && arc_reorg_in_progress;
9705 /* The usual; we set up our machine_function data. */
9707 static struct machine_function *
9708 arc_init_machine_status (void)
9710 struct machine_function *machine;
9711 machine = ggc_cleared_alloc<machine_function> ();
9712 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9714 return machine;
9717 /* Implements INIT_EXPANDERS. We just set up to call the above
9718 function. */
9720 void
9721 arc_init_expanders (void)
9723 init_machine_status = arc_init_machine_status;
9726 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9727 indicates a number of elements to ignore - that allows to have a
9728 sibcall pattern that starts with (return). LOAD_P is zero for store
9729 multiple (for prologues), and one for load multiples (for epilogues),
9730 and two for load multiples where no final clobber of blink is required.
9731 We also skip the first load / store element since this is supposed to
9732 be checked in the instruction pattern. */
9735 arc_check_millicode (rtx op, int offset, int load_p)
9737 int len = XVECLEN (op, 0) - offset;
9738 int i;
9740 if (load_p == 2)
9742 if (len < 2 || len > 13)
9743 return 0;
9744 load_p = 1;
9746 else
9748 rtx elt = XVECEXP (op, 0, --len);
9750 if (GET_CODE (elt) != CLOBBER
9751 || !REG_P (XEXP (elt, 0))
9752 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9753 || len < 3 || len > 13)
9754 return 0;
9756 for (i = 1; i < len; i++)
9758 rtx elt = XVECEXP (op, 0, i + offset);
9759 rtx reg, mem, addr;
9761 if (GET_CODE (elt) != SET)
9762 return 0;
9763 mem = XEXP (elt, load_p);
9764 reg = XEXP (elt, 1-load_p);
9765 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9766 return 0;
9767 addr = XEXP (mem, 0);
9768 if (GET_CODE (addr) != PLUS
9769 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9770 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9771 return 0;
9773 return 1;
9776 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9777 constant in operand 1, but which would require a LIMM because of
9778 operand mismatch.
9779 operands 3 and 4 are new SET_SRCs for operands 0. */
9781 void
9782 split_subsi (rtx *operands)
9784 int val = INTVAL (operands[1]);
9786 /* Try for two short insns first. Lengths being equal, we prefer
9787 expansions with shorter register lifetimes. */
9788 if (arc_check_short_reg_p (operands[0])
9789 && arc_check_short_reg_p (operands[2]))
9791 if (val >= -31 && val <= 127)
9793 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9794 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9795 return;
9797 else if (val >= 0 && val < 255)
9799 operands[3] = operands[1];
9800 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9801 return;
9804 /* If the destination is not an ARCompact16 register, we might
9805 still have a chance to make a short insn if the source is;
9806 we need to start with a reg-reg move for this. */
9807 operands[3] = operands[2];
9808 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9811 /* Handle DOUBLE_REGS uses.
9812 Operand 0: destination register
9813 Operand 1: source register */
9815 static bool
9816 arc_process_double_reg_moves (rtx *operands)
9818 enum usesDxState { none, srcDx, destDx, maxDx };
9819 enum usesDxState state = none;
9820 rtx dest = operands[0];
9821 rtx src = operands[1];
9823 if (refers_to_regno_p (40, 44, src, 0))
9825 state = srcDx;
9826 gcc_assert (REG_P (dest));
9828 if (refers_to_regno_p (40, 44, dest, 0))
9830 /* Via arc_register_move_cost, we should never see D,D moves. */
9831 gcc_assert (REG_P (src));
9832 gcc_assert (state == none);
9833 state = destDx;
9836 if (state == none)
9837 return false;
9839 if (state == srcDx)
9841 /* Without the LR insn, we need to split this into a
9842 sequence of insns which will use the DEXCLx and DADDHxy
9843 insns to be able to read the Dx register in question. */
9844 if (TARGET_DPFP_DISABLE_LRSR)
9846 /* gen *movdf_insn_nolrsr */
9847 rtx set = gen_rtx_SET (dest, src);
9848 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9849 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9851 else
9853 /* When we have 'mov D, r' or 'mov D, D' then get the target
9854 register pair for use with LR insn. */
9855 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9856 TARGET_BIG_ENDIAN ? 0 : 4);
9857 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9858 TARGET_BIG_ENDIAN ? 4 : 0);
9860 /* Produce the two LR insns to get the high and low parts. */
9861 emit_insn (gen_rtx_SET (destHigh,
9862 gen_rtx_UNSPEC_VOLATILE (Pmode,
9863 gen_rtvec (1, src),
9864 VUNSPEC_ARC_LR_HIGH)));
9865 emit_insn (gen_rtx_SET (destLow,
9866 gen_rtx_UNSPEC_VOLATILE (Pmode,
9867 gen_rtvec (1, src),
9868 VUNSPEC_ARC_LR)));
9871 else if (state == destDx)
9873 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9874 LR insn get the target register pair. */
9875 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9876 TARGET_BIG_ENDIAN ? 0 : 4);
9877 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9878 TARGET_BIG_ENDIAN ? 4 : 0);
9880 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9882 else
9883 gcc_unreachable ();
9885 return true;
9889 /* Check if we need to split a 64bit move. We do not need to split it if we can
9890 use vadd2 or ldd/std instructions. */
9892 bool
9893 arc_split_move_p (rtx *operands)
9895 machine_mode mode = GET_MODE (operands[0]);
9897 if (TARGET_LL64
9898 && ((memory_operand (operands[0], mode)
9899 && (even_register_operand (operands[1], mode)
9900 || satisfies_constraint_Cm3 (operands[1])))
9901 || (memory_operand (operands[1], mode)
9902 && even_register_operand (operands[0], mode))))
9903 return false;
9905 if (TARGET_PLUS_QMACW
9906 && even_register_operand (operands[0], mode)
9907 && even_register_operand (operands[1], mode))
9908 return false;
9910 return true;
9913 /* operands 0..1 are the operands of a 64 bit move instruction.
9914 split it into two moves with operands 2/3 and 4/5. */
9916 void
9917 arc_split_move (rtx *operands)
9919 machine_mode mode = GET_MODE (operands[0]);
9920 int i;
9921 int swap = 0;
9922 rtx xop[4];
9924 if (TARGET_DPFP)
9926 if (arc_process_double_reg_moves (operands))
9927 return;
9930 if (TARGET_PLUS_QMACW
9931 && GET_CODE (operands[1]) == CONST_VECTOR)
9933 HOST_WIDE_INT intval0, intval1;
9934 if (GET_MODE (operands[1]) == V2SImode)
9936 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9937 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9939 else
9941 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9942 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9943 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9944 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9946 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9947 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9948 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9949 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9950 emit_move_insn (xop[0], xop[2]);
9951 emit_move_insn (xop[3], xop[1]);
9952 return;
9955 for (i = 0; i < 2; i++)
9957 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9959 rtx addr = XEXP (operands[i], 0);
9960 rtx r, o;
9961 enum rtx_code code;
9963 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9964 switch (GET_CODE (addr))
9966 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9967 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9968 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9969 pre_modify:
9970 code = PRE_MODIFY;
9971 break;
9972 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9973 case POST_INC: o = GEN_INT (8); goto post_modify;
9974 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9975 post_modify:
9976 code = POST_MODIFY;
9977 swap = 2;
9978 break;
9979 default:
9980 gcc_unreachable ();
9982 r = XEXP (addr, 0);
9983 xop[0+i] = adjust_automodify_address_nv
9984 (operands[i], SImode,
9985 gen_rtx_fmt_ee (code, Pmode, r,
9986 gen_rtx_PLUS (Pmode, r, o)),
9988 xop[2+i] = adjust_automodify_address_nv
9989 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9991 else
9993 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9994 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9997 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9999 swap = 2;
10000 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
10003 emit_move_insn (xop[0 + swap], xop[1 + swap]);
10004 emit_move_insn (xop[2 - swap], xop[3 - swap]);
10008 /* Select between the instruction output templates s_tmpl (for short INSNs)
10009 and l_tmpl (for long INSNs). */
10011 const char *
10012 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
10014 int is_short = arc_verify_short (insn, -1);
10016 extract_constrain_insn_cached (insn);
10017 return is_short ? s_tmpl : l_tmpl;
10020 /* Searches X for any reference to REGNO, returning the rtx of the
10021 reference found if any. Otherwise, returns NULL_RTX. */
10024 arc_regno_use_in (unsigned int regno, rtx x)
10026 const char *fmt;
10027 int i, j;
10028 rtx tem;
10030 if (REG_P (x) && refers_to_regno_p (regno, x))
10031 return x;
10033 fmt = GET_RTX_FORMAT (GET_CODE (x));
10034 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
10036 if (fmt[i] == 'e')
10038 if ((tem = regno_use_in (regno, XEXP (x, i))))
10039 return tem;
10041 else if (fmt[i] == 'E')
10042 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
10043 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
10044 return tem;
10047 return NULL_RTX;
10050 /* Code has a minimum p2 alignment of 1, which we must restore after
10051 an ADDR_DIFF_VEC. */
10054 arc_label_align (rtx_insn *label)
10056 if (align_labels.levels[0].log < 1)
10058 rtx_insn *next = next_nonnote_nondebug_insn (label);
10059 if (INSN_P (next) && recog_memoized (next) >= 0)
10060 return 1;
10062 return align_labels.levels[0].log;
10065 /* Return true if LABEL is in executable code. */
10067 bool
10068 arc_text_label (rtx_insn *label)
10070 rtx_insn *next;
10072 /* ??? We use deleted labels like they were still there, see
10073 gcc.c-torture/compile/20000326-2.c . */
10074 gcc_assert (GET_CODE (label) == CODE_LABEL
10075 || (GET_CODE (label) == NOTE
10076 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
10077 next = next_nonnote_insn (label);
10078 if (next)
10079 return (!JUMP_TABLE_DATA_P (next)
10080 || GET_CODE (PATTERN (next)) != ADDR_VEC);
10081 else if (!PREV_INSN (label))
10082 /* ??? sometimes text labels get inserted very late, see
10083 gcc.dg/torture/stackalign/comp-goto-1.c */
10084 return true;
10085 return false;
10088 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
10089 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
10090 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
10091 to redirect two breqs. */
10093 static bool
10094 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
10096 /* ??? get_attr_type is declared to take an rtx. */
10097 union { const rtx_insn *c; rtx_insn *r; } u;
10099 u.c = follower;
10100 if (CROSSING_JUMP_P (followee))
10101 switch (get_attr_type (u.r))
10103 case TYPE_BRANCH:
10104 if (get_attr_length (u.r) != 2)
10105 break;
10106 /* Fall through. */
10107 case TYPE_BRCC:
10108 case TYPE_BRCC_NO_DELAY_SLOT:
10109 return false;
10110 default:
10111 return true;
10113 return true;
10117 /* Implement EPILOGUE_USES.
10118 Return true if REGNO should be added to the deemed uses of the epilogue.
10120 We have to make sure all the register restore instructions are
10121 known to be live in interrupt functions, plus the blink register if
10122 it is clobbered by the isr. */
10124 bool
10125 arc_epilogue_uses (int regno)
10127 unsigned int fn_type;
10128 fn_type = arc_compute_function_type (cfun);
10130 if (regno == arc_tp_regno)
10131 return true;
10133 if (regno == RETURN_ADDR_REGNUM)
10134 return true;
10136 if (regno == arc_return_address_register (fn_type))
10137 return true;
10139 if (epilogue_completed && ARC_INTERRUPT_P (fn_type))
10141 /* An interrupt function restores more registers. */
10142 if (df_regs_ever_live_p (regno) || call_used_or_fixed_reg_p (regno))
10143 return true;
10146 return false;
10149 /* Helper for EH_USES macro. */
10151 bool
10152 arc_eh_uses (int regno)
10154 if (regno == arc_tp_regno)
10155 return true;
10156 return false;
10159 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to
10160 use q registers, because some insn are shorter with them. OTOH we
10161 already have separate alternatives for this purpose, and other
10162 insns don't mind, so maybe we should rather prefer the other
10163 registers? We need more data, and we can only get that if we allow
10164 people to try all options. */
10165 static int
10166 arc_register_priority (int r)
10168 switch (arc_lra_priority_tag)
10170 case ARC_LRA_PRIORITY_NONE:
10171 return 0;
10172 case ARC_LRA_PRIORITY_NONCOMPACT:
10173 return ((((r & 7) ^ 4) - 4) & 15) != r;
10174 case ARC_LRA_PRIORITY_COMPACT:
10175 return ((((r & 7) ^ 4) - 4) & 15) == r;
10176 default:
10177 gcc_unreachable ();
10181 static reg_class_t
10182 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
10184 return GENERAL_REGS;
10187 bool
10188 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
10189 int itype)
10191 rtx x = *p;
10192 enum reload_type type = (enum reload_type) itype;
10194 if (GET_CODE (x) == PLUS
10195 && CONST_INT_P (XEXP (x, 1))
10196 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
10197 || (REG_P (XEXP (x, 0))
10198 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
10200 int scale = GET_MODE_SIZE (mode);
10201 int shift;
10202 rtx index_rtx = XEXP (x, 1);
10203 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
10204 rtx reg, sum, sum2;
10206 if (scale > 4)
10207 scale = 4;
10208 if ((scale-1) & offset)
10209 scale = 1;
10210 shift = scale >> 1;
10211 offset_base
10212 = ((offset + (256 << shift))
10213 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
10214 /* Sometimes the normal form does not suit DImode. We
10215 could avoid that by using smaller ranges, but that
10216 would give less optimized code when SImode is
10217 prevalent. */
10218 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
10220 int regno;
10222 reg = XEXP (x, 0);
10223 regno = REGNO (reg);
10224 sum2 = sum = plus_constant (Pmode, reg, offset_base);
10226 if (reg_equiv_constant (regno))
10228 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
10229 offset_base);
10230 if (GET_CODE (sum2) == PLUS)
10231 sum2 = gen_rtx_CONST (Pmode, sum2);
10233 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
10234 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
10235 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
10236 type);
10237 return true;
10240 /* We must re-recognize what we created before. */
10241 else if (GET_CODE (x) == PLUS
10242 && GET_CODE (XEXP (x, 0)) == PLUS
10243 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
10244 && REG_P (XEXP (XEXP (x, 0), 0))
10245 && CONST_INT_P (XEXP (x, 1)))
10247 /* Because this address is so complex, we know it must have
10248 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10249 it is already unshared, and needs no further unsharing. */
10250 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
10251 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10252 return true;
10254 return false;
10257 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10259 static bool
10260 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
10261 unsigned int align,
10262 enum by_pieces_operation op,
10263 bool speed_p)
10265 /* Let the cpymem expander handle small block moves. */
10266 if (op == MOVE_BY_PIECES)
10267 return false;
10269 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10272 /* Emit a (pre) memory barrier around an atomic sequence according to
10273 MODEL. */
10275 static void
10276 arc_pre_atomic_barrier (enum memmodel model)
10278 if (need_atomic_barrier_p (model, true))
10279 emit_insn (gen_memory_barrier ());
10282 /* Emit a (post) memory barrier around an atomic sequence according to
10283 MODEL. */
10285 static void
10286 arc_post_atomic_barrier (enum memmodel model)
10288 if (need_atomic_barrier_p (model, false))
10289 emit_insn (gen_memory_barrier ());
10292 /* Expand a compare and swap pattern. */
10294 static void
10295 emit_unlikely_jump (rtx insn)
10297 rtx_insn *jump = emit_jump_insn (insn);
10298 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10301 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10302 32-bit compare and swap on the word containing the byte or
10303 half-word. The difference between a weak and a strong CAS is that
10304 the weak version may simply fail. The strong version relies on two
10305 loops, one checks if the SCOND op is succsfully or not, the other
10306 checks if the 32 bit accessed location which contains the 8 or 16
10307 bit datum is not changed by other thread. The first loop is
10308 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10309 loops is implemented by this routine. */
10311 static void
10312 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10313 rtx oldval, rtx newval, rtx weak,
10314 rtx mod_s, rtx mod_f)
10316 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10317 rtx addr = gen_reg_rtx (Pmode);
10318 rtx off = gen_reg_rtx (SImode);
10319 rtx oldv = gen_reg_rtx (SImode);
10320 rtx newv = gen_reg_rtx (SImode);
10321 rtx oldvalue = gen_reg_rtx (SImode);
10322 rtx newvalue = gen_reg_rtx (SImode);
10323 rtx res = gen_reg_rtx (SImode);
10324 rtx resv = gen_reg_rtx (SImode);
10325 rtx memsi, val, mask, end_label, loop_label, cc, x;
10326 machine_mode mode;
10327 bool is_weak = (weak != const0_rtx);
10329 /* Truncate the address. */
10330 emit_insn (gen_rtx_SET (addr,
10331 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10333 /* Compute the datum offset. */
10334 emit_insn (gen_rtx_SET (off,
10335 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10336 if (TARGET_BIG_ENDIAN)
10337 emit_insn (gen_rtx_SET (off,
10338 gen_rtx_MINUS (SImode,
10339 (GET_MODE (mem) == QImode) ?
10340 GEN_INT (3) : GEN_INT (2), off)));
10342 /* Normal read from truncated address. */
10343 memsi = gen_rtx_MEM (SImode, addr);
10344 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10345 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10347 val = copy_to_reg (memsi);
10349 /* Convert the offset in bits. */
10350 emit_insn (gen_rtx_SET (off,
10351 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10353 /* Get the proper mask. */
10354 if (GET_MODE (mem) == QImode)
10355 mask = force_reg (SImode, GEN_INT (0xff));
10356 else
10357 mask = force_reg (SImode, GEN_INT (0xffff));
10359 emit_insn (gen_rtx_SET (mask,
10360 gen_rtx_ASHIFT (SImode, mask, off)));
10362 /* Prepare the old and new values. */
10363 emit_insn (gen_rtx_SET (val,
10364 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10365 val)));
10367 oldval = gen_lowpart (SImode, oldval);
10368 emit_insn (gen_rtx_SET (oldv,
10369 gen_rtx_ASHIFT (SImode, oldval, off)));
10371 newval = gen_lowpart_common (SImode, newval);
10372 emit_insn (gen_rtx_SET (newv,
10373 gen_rtx_ASHIFT (SImode, newval, off)));
10375 emit_insn (gen_rtx_SET (oldv,
10376 gen_rtx_AND (SImode, oldv, mask)));
10378 emit_insn (gen_rtx_SET (newv,
10379 gen_rtx_AND (SImode, newv, mask)));
10381 if (!is_weak)
10383 end_label = gen_label_rtx ();
10384 loop_label = gen_label_rtx ();
10385 emit_label (loop_label);
10388 /* Make the old and new values. */
10389 emit_insn (gen_rtx_SET (oldvalue,
10390 gen_rtx_IOR (SImode, oldv, val)));
10392 emit_insn (gen_rtx_SET (newvalue,
10393 gen_rtx_IOR (SImode, newv, val)));
10395 /* Try an 32bit atomic compare and swap. It clobbers the CC
10396 register. */
10397 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10398 weak, mod_s, mod_f));
10400 /* Regardless of the weakness of the operation, a proper boolean
10401 result needs to be provided. */
10402 x = gen_rtx_REG (CC_Zmode, CC_REG);
10403 x = gen_rtx_EQ (SImode, x, const0_rtx);
10404 emit_insn (gen_rtx_SET (bool_result, x));
10406 if (!is_weak)
10408 /* Check the results: if the atomic op is successfully the goto
10409 to end label. */
10410 x = gen_rtx_REG (CC_Zmode, CC_REG);
10411 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10412 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10413 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10414 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10416 /* Wait for the right moment when the accessed 32-bit location
10417 is stable. */
10418 emit_insn (gen_rtx_SET (resv,
10419 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10420 res)));
10421 mode = SELECT_CC_MODE (NE, resv, val);
10422 cc = gen_rtx_REG (mode, CC_REG);
10423 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10425 /* Set the new value of the 32 bit location, proper masked. */
10426 emit_insn (gen_rtx_SET (val, resv));
10428 /* Try again if location is unstable. Fall through if only
10429 scond op failed. */
10430 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10431 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10432 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10433 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10435 emit_label (end_label);
10438 /* End: proper return the result for the given mode. */
10439 emit_insn (gen_rtx_SET (res,
10440 gen_rtx_AND (SImode, res, mask)));
10442 emit_insn (gen_rtx_SET (res,
10443 gen_rtx_LSHIFTRT (SImode, res, off)));
10445 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10448 /* Helper function used by "atomic_compare_and_swap" expand
10449 pattern. */
10451 void
10452 arc_expand_compare_and_swap (rtx operands[])
10454 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10455 machine_mode mode;
10457 bval = operands[0];
10458 rval = operands[1];
10459 mem = operands[2];
10460 oldval = operands[3];
10461 newval = operands[4];
10462 is_weak = operands[5];
10463 mod_s = operands[6];
10464 mod_f = operands[7];
10465 mode = GET_MODE (mem);
10467 if (reg_overlap_mentioned_p (rval, oldval))
10468 oldval = copy_to_reg (oldval);
10470 if (mode == SImode)
10472 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10473 is_weak, mod_s, mod_f));
10474 x = gen_rtx_REG (CC_Zmode, CC_REG);
10475 x = gen_rtx_EQ (SImode, x, const0_rtx);
10476 emit_insn (gen_rtx_SET (bval, x));
10478 else
10480 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10481 is_weak, mod_s, mod_f);
10485 /* Helper function used by the "atomic_compare_and_swapsi_1"
10486 pattern. */
10488 void
10489 arc_split_compare_and_swap (rtx operands[])
10491 rtx rval, mem, oldval, newval;
10492 machine_mode mode;
10493 enum memmodel mod_s, mod_f;
10494 bool is_weak;
10495 rtx label1, label2, x, cond;
10497 rval = operands[0];
10498 mem = operands[1];
10499 oldval = operands[2];
10500 newval = operands[3];
10501 is_weak = (operands[4] != const0_rtx);
10502 mod_s = (enum memmodel) INTVAL (operands[5]);
10503 mod_f = (enum memmodel) INTVAL (operands[6]);
10504 mode = GET_MODE (mem);
10506 /* ARC atomic ops work only with 32-bit aligned memories. */
10507 gcc_assert (mode == SImode);
10509 arc_pre_atomic_barrier (mod_s);
10511 label1 = NULL_RTX;
10512 if (!is_weak)
10514 label1 = gen_label_rtx ();
10515 emit_label (label1);
10517 label2 = gen_label_rtx ();
10519 /* Load exclusive. */
10520 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10522 /* Check if it is oldval. */
10523 mode = SELECT_CC_MODE (NE, rval, oldval);
10524 cond = gen_rtx_REG (mode, CC_REG);
10525 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10527 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10528 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10529 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10530 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10532 /* Exclusively store new item. Store clobbers CC reg. */
10533 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10535 if (!is_weak)
10537 /* Check the result of the store. */
10538 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10539 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10540 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10541 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10542 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10545 if (mod_f != MEMMODEL_RELAXED)
10546 emit_label (label2);
10548 arc_post_atomic_barrier (mod_s);
10550 if (mod_f == MEMMODEL_RELAXED)
10551 emit_label (label2);
10554 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10555 to perform. MEM is the memory on which to operate. VAL is the second
10556 operand of the binary operator. BEFORE and AFTER are optional locations to
10557 return the value of MEM either before of after the operation. MODEL_RTX
10558 is a CONST_INT containing the memory model to use. */
10560 void
10561 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10562 rtx orig_before, rtx orig_after, rtx model_rtx)
10564 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10565 machine_mode mode = GET_MODE (mem);
10566 rtx label, x, cond;
10567 rtx before = orig_before, after = orig_after;
10569 /* ARC atomic ops work only with 32-bit aligned memories. */
10570 gcc_assert (mode == SImode);
10572 arc_pre_atomic_barrier (model);
10574 label = gen_label_rtx ();
10575 emit_label (label);
10576 label = gen_rtx_LABEL_REF (VOIDmode, label);
10578 if (before == NULL_RTX)
10579 before = gen_reg_rtx (mode);
10581 if (after == NULL_RTX)
10582 after = gen_reg_rtx (mode);
10584 /* Load exclusive. */
10585 emit_insn (gen_arc_load_exclusivesi (before, mem));
10587 switch (code)
10589 case NOT:
10590 x = gen_rtx_AND (mode, before, val);
10591 emit_insn (gen_rtx_SET (after, x));
10592 x = gen_rtx_NOT (mode, after);
10593 emit_insn (gen_rtx_SET (after, x));
10594 break;
10596 case MINUS:
10597 if (CONST_INT_P (val))
10599 val = GEN_INT (-INTVAL (val));
10600 code = PLUS;
10603 /* FALLTHRU. */
10604 default:
10605 x = gen_rtx_fmt_ee (code, mode, before, val);
10606 emit_insn (gen_rtx_SET (after, x));
10607 break;
10610 /* Exclusively store new item. Store clobbers CC reg. */
10611 emit_insn (gen_arc_store_exclusivesi (mem, after));
10613 /* Check the result of the store. */
10614 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10615 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10616 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10617 label, pc_rtx);
10618 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10620 arc_post_atomic_barrier (model);
10623 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10625 static bool
10626 arc_no_speculation_in_delay_slots_p ()
10628 return true;
10631 /* Return a parallel of registers to represent where to find the
10632 register pieces if required, otherwise NULL_RTX. */
10634 static rtx
10635 arc_dwarf_register_span (rtx rtl)
10637 machine_mode mode = GET_MODE (rtl);
10638 unsigned regno;
10639 rtx p;
10641 if (GET_MODE_SIZE (mode) != 8)
10642 return NULL_RTX;
10644 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10645 regno = REGNO (rtl);
10646 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10647 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10649 return p;
10652 /* Return true if OP is an acceptable memory operand for ARCompact
10653 16-bit load instructions of MODE.
10655 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10656 non scaled instructions.
10658 SCALED: TRUE if address can be scaled. */
10660 bool
10661 compact_memory_operand_p (rtx op, machine_mode mode,
10662 bool av2short, bool scaled)
10664 rtx addr, plus0, plus1;
10665 int size, off;
10667 /* Eliminate non-memory operations. */
10668 if (GET_CODE (op) != MEM)
10669 return 0;
10671 /* .di instructions have no 16-bit form. */
10672 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10673 return false;
10675 /* likewise for uncached types. */
10676 if (arc_is_uncached_mem_p (op))
10677 return false;
10679 if (mode == VOIDmode)
10680 mode = GET_MODE (op);
10682 size = GET_MODE_SIZE (mode);
10684 /* dword operations really put out 2 instructions, so eliminate
10685 them. */
10686 if (size > UNITS_PER_WORD)
10687 return false;
10689 /* Decode the address now. */
10690 addr = XEXP (op, 0);
10691 switch (GET_CODE (addr))
10693 case REG:
10694 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10695 || COMPACT_GP_REG_P (REGNO (addr))
10696 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10697 case PLUS:
10698 plus0 = XEXP (addr, 0);
10699 plus1 = XEXP (addr, 1);
10701 if ((GET_CODE (plus0) == REG)
10702 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10703 || COMPACT_GP_REG_P (REGNO (plus0)))
10704 && ((GET_CODE (plus1) == REG)
10705 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10706 || COMPACT_GP_REG_P (REGNO (plus1)))))
10708 return !av2short;
10711 if ((GET_CODE (plus0) == REG)
10712 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10713 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10714 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10715 && (GET_CODE (plus1) == CONST_INT))
10717 bool valid = false;
10719 off = INTVAL (plus1);
10721 /* Negative offset is not supported in 16-bit load/store insns. */
10722 if (off < 0)
10723 return 0;
10725 /* Only u5 immediates allowed in code density instructions. */
10726 if (av2short)
10728 switch (size)
10730 case 1:
10731 return false;
10732 case 2:
10733 /* This is an ldh_s.x instruction, check the u6
10734 immediate. */
10735 if (COMPACT_GP_REG_P (REGNO (plus0)))
10736 valid = true;
10737 break;
10738 case 4:
10739 /* Only u5 immediates allowed in 32bit access code
10740 density instructions. */
10741 if (REGNO (plus0) <= 31)
10742 return ((off < 32) && (off % 4 == 0));
10743 break;
10744 default:
10745 return false;
10748 else
10749 if (COMPACT_GP_REG_P (REGNO (plus0)))
10750 valid = true;
10752 if (valid)
10755 switch (size)
10757 case 1:
10758 return (off < 32);
10759 case 2:
10760 /* The 6-bit constant get shifted to fit the real
10761 5-bits field. Check also for the alignment. */
10762 return ((off < 64) && (off % 2 == 0));
10763 case 4:
10764 return ((off < 128) && (off % 4 == 0));
10765 default:
10766 return false;
10771 if (REG_P (plus0) && CONST_INT_P (plus1)
10772 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10773 || SP_REG_P (REGNO (plus0)))
10774 && !av2short)
10776 off = INTVAL (plus1);
10777 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10780 if ((GET_CODE (plus0) == MULT)
10781 && (GET_CODE (XEXP (plus0, 0)) == REG)
10782 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10783 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10784 && (GET_CODE (plus1) == REG)
10785 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10786 || COMPACT_GP_REG_P (REGNO (plus1))))
10787 return scaled;
10788 default:
10789 break ;
10790 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10791 for 16-bit load instructions. */
10793 return false;
10796 /* Return nonzero if a jli call should be generated for a call from
10797 the current function to DECL. */
10799 bool
10800 arc_is_jli_call_p (rtx pat)
10802 tree attrs;
10803 tree decl = SYMBOL_REF_DECL (pat);
10805 /* If it is not a well defined public function then return false. */
10806 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
10807 return false;
10809 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10810 if (lookup_attribute ("jli_always", attrs))
10811 return true;
10813 if (lookup_attribute ("jli_fixed", attrs))
10814 return true;
10816 return TARGET_JLI_ALWAYS;
10819 /* Handle and "jli" attribute; arguments as in struct
10820 attribute_spec.handler. */
10822 static tree
10823 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
10824 tree name, tree args, int,
10825 bool *no_add_attrs)
10827 if (!TARGET_V2)
10829 warning (OPT_Wattributes,
10830 "%qE attribute only valid for ARCv2 architecture",
10831 name);
10832 *no_add_attrs = true;
10835 if (args == NULL_TREE)
10837 warning (OPT_Wattributes,
10838 "argument of %qE attribute is missing",
10839 name);
10840 *no_add_attrs = true;
10842 else
10844 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10845 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10846 tree arg = TREE_VALUE (args);
10847 if (TREE_CODE (arg) != INTEGER_CST)
10849 warning (0, "%qE attribute allows only an integer constant argument",
10850 name);
10851 *no_add_attrs = true;
10853 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10855 return NULL_TREE;
10858 /* Handle and "scure" attribute; arguments as in struct
10859 attribute_spec.handler. */
10861 static tree
10862 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
10863 tree name, tree args, int,
10864 bool *no_add_attrs)
10866 if (!TARGET_EM)
10868 warning (OPT_Wattributes,
10869 "%qE attribute only valid for ARC EM architecture",
10870 name);
10871 *no_add_attrs = true;
10874 if (args == NULL_TREE)
10876 warning (OPT_Wattributes,
10877 "argument of %qE attribute is missing",
10878 name);
10879 *no_add_attrs = true;
10881 else
10883 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10884 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10885 tree arg = TREE_VALUE (args);
10886 if (TREE_CODE (arg) != INTEGER_CST)
10888 warning (0, "%qE attribute allows only an integer constant argument",
10889 name);
10890 *no_add_attrs = true;
10893 return NULL_TREE;
10896 /* Return nonzero if the symbol is a secure function. */
10898 bool
10899 arc_is_secure_call_p (rtx pat)
10901 tree attrs;
10902 tree decl = SYMBOL_REF_DECL (pat);
10904 if (!decl)
10905 return false;
10907 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10908 if (lookup_attribute ("secure_call", attrs))
10909 return true;
10911 return false;
10914 /* Handle "uncached" qualifier. */
10916 static tree
10917 arc_handle_uncached_attribute (tree *node,
10918 tree name, tree args,
10919 int flags ATTRIBUTE_UNUSED,
10920 bool *no_add_attrs)
10922 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
10924 error ("%qE attribute only applies to types",
10925 name);
10926 *no_add_attrs = true;
10928 else if (args)
10930 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
10932 return NULL_TREE;
10935 /* Return TRUE if PAT is a memory addressing an uncached data. */
10937 bool
10938 arc_is_uncached_mem_p (rtx pat)
10940 tree attrs = NULL_TREE;
10941 tree addr;
10943 if (!MEM_P (pat))
10944 return false;
10946 /* Get the memory attributes. */
10947 addr = MEM_EXPR (pat);
10948 if (!addr)
10949 return false;
10951 /* Get the attributes. */
10952 if (TREE_CODE (addr) == MEM_REF
10953 || VAR_P (addr))
10955 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10956 if (lookup_attribute ("uncached", attrs))
10957 return true;
10959 if (TREE_CODE (addr) == MEM_REF)
10961 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10962 if (lookup_attribute ("uncached", attrs))
10963 return true;
10964 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10965 if (lookup_attribute ("uncached", attrs))
10966 return true;
10969 /* Check the definitions of the structs. */
10970 while (handled_component_p (addr))
10972 if (TREE_CODE (addr) == COMPONENT_REF)
10974 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10975 if (lookup_attribute ("uncached", attrs))
10976 return true;
10977 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10978 if (lookup_attribute ("uncached", attrs))
10979 return true;
10980 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10981 if (lookup_attribute ("uncached", attrs))
10982 return true;
10984 addr = TREE_OPERAND (addr, 0);
10986 return false;
10989 /* Handle aux attribute. The auxiliary registers are addressed using
10990 special instructions lr and sr. The attribute 'aux' indicates if a
10991 variable refers to the aux-regs and what is the register number
10992 desired. */
10994 static tree
10995 arc_handle_aux_attribute (tree *node,
10996 tree name, tree args, int,
10997 bool *no_add_attrs)
10999 /* Isn't it better to use address spaces for the aux-regs? */
11000 if (DECL_P (*node))
11002 if (TREE_CODE (*node) != VAR_DECL)
11004 error ("%qE attribute only applies to variables", name);
11005 *no_add_attrs = true;
11007 else if (args)
11009 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11010 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11011 tree arg = TREE_VALUE (args);
11012 if (TREE_CODE (arg) != INTEGER_CST)
11014 warning (OPT_Wattributes, "%qE attribute allows only an integer "
11015 "constant argument", name);
11016 *no_add_attrs = true;
11018 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11021 if (VAR_P (*node))
11023 tree fntype = TREE_TYPE (*node);
11024 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
11026 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
11027 TYPE_ATTRIBUTES (fntype));
11028 TYPE_ATTRIBUTES (fntype) = attrs;
11032 return NULL_TREE;
11035 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
11036 anchors for small data: the GP register acts as an anchor in that
11037 case. We also don't want to use them for PC-relative accesses,
11038 where the PC acts as an anchor. Prohibit also TLS symbols to use
11039 anchors. */
11041 static bool
11042 arc_use_anchors_for_symbol_p (const_rtx symbol)
11044 if (SYMBOL_REF_TLS_MODEL (symbol))
11045 return false;
11047 if (flag_pic)
11048 return false;
11050 if (SYMBOL_REF_SMALL_P (symbol))
11051 return false;
11053 return default_use_anchors_for_symbol_p (symbol);
11056 /* Return true if SUBST can't safely replace its equivalent during RA. */
11057 static bool
11058 arc_cannot_substitute_mem_equiv_p (rtx)
11060 /* If SUBST is mem[base+index], the address may not fit ISA,
11061 thus return true. */
11062 return true;
11065 /* Checks whether the operands are valid for use in an LDD/STD
11066 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
11067 by the patterns. Assumes that the address in the base register RN
11068 is word aligned. Pattern guarantees that both memory accesses use
11069 the same base register, the offsets are constants within the range,
11070 and the gap between the offsets is 4. If reload complete then
11071 check that registers are legal. */
11073 static bool
11074 operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT offset)
11076 unsigned int t, t2;
11078 if (!reload_completed)
11079 return true;
11081 if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & (~0x03),
11082 (offset & (GET_MODE_SIZE (DImode) - 1) & 3
11083 ? 0 : -(-GET_MODE_SIZE (DImode) | (~0x03)) >> 1))))
11084 return false;
11086 t = REGNO (rt);
11087 t2 = REGNO (rt2);
11089 if ((t2 == PCL_REG)
11090 || (t % 2 != 0) /* First destination register is not even. */
11091 || (t2 != t + 1))
11092 return false;
11094 return true;
11097 /* Helper for gen_operands_ldd_std. Returns true iff the memory
11098 operand MEM's address contains an immediate offset from the base
11099 register and has no side effects, in which case it sets BASE and
11100 OFFSET accordingly. */
11102 static bool
11103 mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset)
11105 rtx addr;
11107 gcc_assert (base != NULL && offset != NULL);
11109 /* TODO: Handle more general memory operand patterns, such as
11110 PRE_DEC and PRE_INC. */
11112 if (side_effects_p (mem))
11113 return false;
11115 /* Can't deal with subregs. */
11116 if (GET_CODE (mem) == SUBREG)
11117 return false;
11119 gcc_assert (MEM_P (mem));
11121 *offset = const0_rtx;
11123 addr = XEXP (mem, 0);
11125 /* If addr isn't valid for DImode, then we can't handle it. */
11126 if (!arc_legitimate_address_p (DImode, addr,
11127 reload_in_progress || reload_completed))
11128 return false;
11130 if (REG_P (addr))
11132 *base = addr;
11133 return true;
11135 else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
11137 *base = XEXP (addr, 0);
11138 *offset = XEXP (addr, 1);
11139 return (REG_P (*base) && CONST_INT_P (*offset));
11142 return false;
11145 /* Called from peephole2 to replace two word-size accesses with a
11146 single LDD/STD instruction. Returns true iff we can generate a new
11147 instruction sequence. That is, both accesses use the same base
11148 register and the gap between constant offsets is 4. OPERANDS are
11149 the operands found by the peephole matcher; OPERANDS[0,1] are
11150 register operands, and OPERANDS[2,3] are the corresponding memory
11151 operands. LOAD indicates whether the access is load or store. */
11153 bool
11154 gen_operands_ldd_std (rtx *operands, bool load, bool commute)
11156 int i, gap;
11157 HOST_WIDE_INT offsets[2], offset;
11158 int nops = 2;
11159 rtx cur_base, cur_offset, tmp;
11160 rtx base = NULL_RTX;
11162 /* Check that the memory references are immediate offsets from the
11163 same base register. Extract the base register, the destination
11164 registers, and the corresponding memory offsets. */
11165 for (i = 0; i < nops; i++)
11167 if (!mem_ok_for_ldd_std (operands[nops+i], &cur_base, &cur_offset))
11168 return false;
11170 if (i == 0)
11171 base = cur_base;
11172 else if (REGNO (base) != REGNO (cur_base))
11173 return false;
11175 offsets[i] = INTVAL (cur_offset);
11176 if (GET_CODE (operands[i]) == SUBREG)
11178 tmp = SUBREG_REG (operands[i]);
11179 gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp));
11180 operands[i] = tmp;
11184 /* Make sure there is no dependency between the individual loads. */
11185 if (load && REGNO (operands[0]) == REGNO (base))
11186 return false; /* RAW. */
11188 if (load && REGNO (operands[0]) == REGNO (operands[1]))
11189 return false; /* WAW. */
11191 /* Make sure the instructions are ordered with lower memory access first. */
11192 if (offsets[0] > offsets[1])
11194 gap = offsets[0] - offsets[1];
11195 offset = offsets[1];
11197 /* Swap the instructions such that lower memory is accessed first. */
11198 std::swap (operands[0], operands[1]);
11199 std::swap (operands[2], operands[3]);
11201 else
11203 gap = offsets[1] - offsets[0];
11204 offset = offsets[0];
11207 /* Make sure accesses are to consecutive memory locations. */
11208 if (gap != 4)
11209 return false;
11211 /* Make sure we generate legal instructions. */
11212 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11213 return true;
11215 if (load && commute)
11217 /* Try reordering registers. */
11218 std::swap (operands[0], operands[1]);
11219 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11220 return true;
11223 return false;
11226 /* This order of allocation is used when we compile for size. It
11227 allocates first the registers which are most probably to end up in
11228 a short instruction. */
11229 static const int size_alloc_order[] =
11231 0, 1, 2, 3, 12, 13, 14, 15,
11232 4, 5, 6, 7, 8, 9, 10, 11
11235 /* Adjust register allocation order when compiling for size. */
11236 void
11237 arc_adjust_reg_alloc_order (void)
11239 const int arc_default_alloc_order[] = REG_ALLOC_ORDER;
11240 memcpy (reg_alloc_order, arc_default_alloc_order, sizeof (reg_alloc_order));
11241 if (optimize_size)
11242 memcpy (reg_alloc_order, size_alloc_order, sizeof (size_alloc_order));
11245 /* Implement TARGET_MEMORY_MOVE_COST. */
11247 static int
11248 arc_memory_move_cost (machine_mode mode,
11249 reg_class_t rclass ATTRIBUTE_UNUSED,
11250 bool in ATTRIBUTE_UNUSED)
11252 if ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
11253 || ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD * 2) && TARGET_LL64))
11254 return 6;
11256 return (2 * GET_MODE_SIZE (mode));
11259 /* Split an OR instruction into multiple BSET/OR instructions in a
11260 attempt to avoid long immediate constants. The next strategies are
11261 employed when destination is 'q' reg.
11263 1. if there are up to three bits set in the mask, a succession of
11264 three bset instruction will be emitted:
11265 OR rA, rB, mask ->
11266 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
11268 2. if the lower 6 bits of the mask is set and there is only one
11269 bit set in the upper remaining bits then we will emit one bset and
11270 one OR instruction:
11271 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
11273 3. otherwise an OR with limm will be emmitted. */
11275 void
11276 arc_split_ior (rtx *operands)
11278 unsigned HOST_WIDE_INT mask, maskx;
11279 rtx op1 = operands[1];
11281 gcc_assert (CONST_INT_P (operands[2]));
11282 mask = INTVAL (operands[2]) & 0xffffffff;
11284 if (__builtin_popcount (mask) > 3 || (mask & 0x3f))
11286 maskx = mask & 0x3f;
11287 emit_insn (gen_rtx_SET (operands[0],
11288 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11289 op1 = operands[0];
11290 mask &= ~maskx;
11293 switch (__builtin_popcount (mask))
11295 case 3:
11296 maskx = 1 << (__builtin_ffs (mask) - 1);
11297 emit_insn (gen_rtx_SET (operands[0],
11298 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11299 mask &= ~maskx;
11300 op1 = operands[0];
11301 /* FALLTHRU */
11302 case 2:
11303 maskx = 1 << (__builtin_ffs (mask) - 1);
11304 emit_insn (gen_rtx_SET (operands[0],
11305 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11306 mask &= ~maskx;
11307 op1 = operands[0];
11308 /* FALLTHRU */
11309 case 1:
11310 maskx = 1 << (__builtin_ffs (mask) - 1);
11311 emit_insn (gen_rtx_SET (operands[0],
11312 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11313 break;
11314 case 0:
11315 break;
11316 default:
11317 gcc_unreachable ();
11321 /* Helper to check C0x constraint. */
11323 bool
11324 arc_check_ior_const (HOST_WIDE_INT ival)
11326 unsigned int mask = (unsigned int) (ival & 0xffffffff);
11328 if (UNSIGNED_INT6 (ival)
11329 || IS_POWEROF2_P (mask))
11330 return false;
11331 if (__builtin_popcount (mask) <= 3)
11332 return true;
11333 if (__builtin_popcount (mask & ~0x3f) <= 1)
11334 return true;
11335 return false;
11338 /* Split a mov with long immediate instruction into smaller, size
11339 friendly instructions. */
11341 bool
11342 arc_split_mov_const (rtx *operands)
11344 unsigned HOST_WIDE_INT ival;
11345 HOST_WIDE_INT shimm;
11346 machine_mode mode = GET_MODE (operands[0]);
11348 /* Manage a constant. */
11349 gcc_assert (CONST_INT_P (operands[1]));
11350 ival = INTVAL (operands[1]) & 0xffffffff;
11352 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11353 if (TARGET_BARREL_SHIFTER && TARGET_V2
11354 && ((ival & ~0x3f000000) == 0))
11356 shimm = (ival >> 24) & 0x3f;
11357 emit_insn (gen_rtx_SET (operands[0],
11358 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11359 GEN_INT (8))));
11360 return true;
11362 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11363 if (TARGET_BARREL_SHIFTER && TARGET_V2
11364 && ((ival & ~0x3f00) == 0))
11366 shimm = (ival >> 8) & 0x3f;
11367 emit_insn (gen_rtx_SET (operands[0],
11368 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11369 GEN_INT (8))));
11370 return true;
11373 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11374 if (TARGET_SWAP && TARGET_V2
11375 && ((ival & ~0x3f0000) == 0))
11377 shimm = (ival >> 16) & 0x3f;
11378 emit_insn (gen_rtx_SET (operands[0],
11379 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11380 GEN_INT (16))));
11381 return true;
11384 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11385 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0
11386 && TARGET_BARREL_SHIFTER)
11388 HOST_WIDE_INT shift = __builtin_ffs (ival);
11389 shimm = (ival >> (shift - 1)) & 0xff;
11390 emit_insn (gen_rtx_SET (operands[0], GEN_INT (shimm)));
11391 emit_insn (gen_rtx_SET (operands[0],
11392 gen_rtx_ASHIFT (mode, operands[0],
11393 GEN_INT (shift - 1))));
11394 return true;
11397 /* 5. Check if we can just rotate the limm, useful when no barrel
11398 shifter is present. */
11399 if ((ival & ~0x8000001f) == 0)
11401 shimm = (ival * 2 + 1) & 0x3f;
11402 emit_insn (gen_rtx_SET (operands[0],
11403 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11404 const1_rtx)));
11405 return true;
11408 /* 6. Check if we can do something with bmask. */
11409 if (IS_POWEROF2_P (ival + 1))
11411 emit_insn (gen_rtx_SET (operands[0], constm1_rtx));
11412 emit_insn (gen_rtx_SET (operands[0],
11413 gen_rtx_AND (mode, operands[0],
11414 GEN_INT (ival))));
11415 return true;
11418 gcc_unreachable ();
11421 /* Helper to check Cax constraint. */
11423 bool
11424 arc_check_mov_const (HOST_WIDE_INT ival)
11426 ival = ival & 0xffffffff;
11428 if (SIGNED_INT12 (ival))
11429 return false;
11431 if ((ival & ~0x8000001f) == 0)
11432 return true;
11434 if (IS_POWEROF2_P (ival + 1))
11435 return true;
11437 /* The next rules requires a barrel shifter. */
11438 if (!TARGET_BARREL_SHIFTER)
11439 return false;
11441 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0)
11442 return true;
11444 if ((ival & ~0x3f00) == 0)
11445 return true;
11447 if ((ival & ~0x3f0000) == 0)
11448 return true;
11450 if ((ival & ~0x3f000000) == 0)
11451 return true;
11453 return false;
11456 /* Return nonzero if this function is known to have a null epilogue.
11457 This allows the optimizer to omit jumps to jumps if no stack
11458 was created. */
11460 bool
11461 arc_can_use_return_insn (void)
11463 return (reload_completed && cfun->machine->frame_info.total_size == 0
11464 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
11467 /* Helper for INSN_COST.
11469 Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
11470 insn, a set, a set source, any random piece of one). set_src_cost,
11471 set_rtx_cost, etc. are helper functions that use that.
11473 Those functions do not work for parallels. Also, costs are not
11474 additive like this simplified model assumes. Also, more complex
11475 backends tend to miss many cases in their rtx_costs function.
11477 Many passes that want costs want to know the cost of a full insn. Like
11478 combine. That's why I created insn_cost: it solves all of the above
11479 problems. */
11481 static int
11482 arc_insn_cost (rtx_insn *insn, bool speed)
11484 int cost;
11485 enum attr_type type;
11486 if (recog_memoized (insn) >= 0)
11488 if (speed)
11490 /* Use cost if provided. */
11491 cost = get_attr_cost (insn);
11492 if (cost > 0)
11493 return cost;
11494 /* For speed make a simple cost model: memory access is more
11495 expensive than any other instruction. */
11496 type = get_attr_type (insn);
11497 if (type == TYPE_LOAD || type == TYPE_STORE)
11498 return COSTS_N_INSNS (2);
11500 else
11502 /* If optimizing for size, we want the insn size. */
11503 type = get_attr_type (insn);
11504 if (type != TYPE_MULTI)
11505 return get_attr_length (insn);
11509 if (rtx set = single_set (insn))
11510 cost = set_rtx_cost (set, speed);
11511 else
11512 cost = pattern_cost (PATTERN (insn), speed);
11513 /* If the cost is zero, then it's likely a complex insn. We don't
11514 want the cost of these to be less than something we know about. */
11515 return cost ? cost : COSTS_N_INSNS (2);
11518 static unsigned
11519 arc_libm_function_max_error (unsigned cfn, machine_mode mode,
11520 bool boundary_p)
11522 #ifdef OPTION_GLIBC
11523 bool glibc_p = OPTION_GLIBC;
11524 #else
11525 bool glibc_p = false;
11526 #endif
11527 if (glibc_p)
11529 int rnd = flag_rounding_math ? 4 : 0;
11530 switch (cfn)
11532 CASE_CFN_SIN:
11533 CASE_CFN_SIN_FN:
11534 if (!boundary_p && mode == DFmode)
11535 return 7 + rnd;
11536 break;
11537 CASE_CFN_COS:
11538 CASE_CFN_COS_FN:
11539 if (!boundary_p && mode == DFmode)
11540 return 4 + rnd;
11541 default:
11542 break;
11544 return glibc_linux_libm_function_max_error (cfn, mode, boundary_p);
11546 return default_libm_function_max_error (cfn, mode, boundary_p);
11549 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11550 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11552 #undef TARGET_CONSTANT_ALIGNMENT
11553 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11555 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11556 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11558 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11559 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11561 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11562 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11564 #undef TARGET_REGISTER_MOVE_COST
11565 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11567 #undef TARGET_MEMORY_MOVE_COST
11568 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11570 #undef TARGET_INSN_COST
11571 #define TARGET_INSN_COST arc_insn_cost
11573 #undef TARGET_LIBM_FUNCTION_MAX_ERROR
11574 #define TARGET_LIBM_FUNCTION_MAX_ERROR arc_libm_function_max_error
11576 #undef TARGET_DOCUMENTATION_NAME
11577 #define TARGET_DOCUMENTATION_NAME "ARC"
11579 struct gcc_target targetm = TARGET_INITIALIZER;
11581 #include "gt-arc.h"