Add hppa*-*-hpux* to targets which do not support split DWARF
[official-gcc.git] / gcc / config / arc / arc.cc
blob179f11f707780a3d525b5630d2220d28aa040101
1 /* Subroutines used for code generation on the Synopsys DesignWare ARC cpu.
2 Copyright (C) 1994-2024 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 arc_lra_p
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 arc_function_arg_advance (pack_cumulative_args (&next_cum), arg);
2357 first_anon_arg = next_cum;
2359 if (FUNCTION_ARG_REGNO_P (first_anon_arg))
2361 /* First anonymous (unnamed) argument is in a reg. */
2363 /* Note that first_reg_offset < MAX_ARC_PARM_REGS. */
2364 int first_reg_offset = first_anon_arg;
2366 if (!no_rtl)
2368 rtx regblock
2369 = gen_rtx_MEM (BLKmode, plus_constant (Pmode, arg_pointer_rtx,
2370 FIRST_PARM_OFFSET (0)));
2371 move_block_from_reg (first_reg_offset, regblock,
2372 MAX_ARC_PARM_REGS - first_reg_offset);
2375 *pretend_size
2376 = ((MAX_ARC_PARM_REGS - first_reg_offset ) * UNITS_PER_WORD);
2380 /* Return TRUE if reg is ok for short instrcutions. */
2382 static bool
2383 arc_check_short_reg_p (rtx op)
2385 if (!REG_P (op))
2386 return false;
2388 if (IN_RANGE (REGNO (op) ^ 4, 4, 11))
2389 return true;
2391 return false;
2394 /* Cost functions. */
2396 /* Provide the costs of an addressing mode that contains ADDR.
2397 If ADDR is not a valid address, its cost is irrelevant. */
2399 static int
2400 arc_address_cost (rtx addr, machine_mode, addr_space_t, bool speed)
2402 switch (GET_CODE (addr))
2404 case REG :
2405 return speed || arc_check_short_reg_p (addr) ? 0 : 1;
2406 case PRE_INC: case PRE_DEC: case POST_INC: case POST_DEC:
2407 case PRE_MODIFY: case POST_MODIFY:
2408 return !speed;
2410 case LABEL_REF :
2411 case SYMBOL_REF :
2412 case CONST :
2413 if (TARGET_NPS_CMEM && cmem_address (addr, SImode))
2414 return 0;
2415 /* Most likely needs a LIMM. */
2416 return COSTS_N_INSNS (1);
2418 case PLUS :
2420 rtx plus0 = XEXP (addr, 0);
2421 rtx plus1 = XEXP (addr, 1);
2423 if (GET_CODE (plus0) != REG
2424 && (GET_CODE (plus0) != MULT
2425 || !CONST_INT_P (XEXP (plus0, 1))
2426 || (INTVAL (XEXP (plus0, 1)) != 2
2427 && INTVAL (XEXP (plus0, 1)) != 4)))
2428 break;
2430 switch (GET_CODE (plus1))
2432 case CONST_INT :
2433 return (!RTX_OK_FOR_OFFSET_P (SImode, plus1)
2434 ? COSTS_N_INSNS (1)
2435 : speed
2437 : (arc_check_short_reg_p (plus0)
2438 && satisfies_constraint_O (plus1))
2440 : 1);
2441 case REG:
2442 return (speed < 1 ? 0
2443 : (arc_check_short_reg_p (plus0)
2444 && arc_check_short_reg_p (plus1))
2445 ? 0 : 1);
2446 case CONST :
2447 case SYMBOL_REF :
2448 case LABEL_REF :
2449 return COSTS_N_INSNS (1);
2450 default:
2451 break;
2453 break;
2455 default:
2456 break;
2459 return 4;
2462 /* Emit instruction X with the frame related bit set. */
2464 static rtx
2465 frame_insn (rtx x)
2467 x = emit_insn (x);
2468 RTX_FRAME_RELATED_P (x) = 1;
2469 return x;
2472 /* Emit a frame insn to move SRC to DST. */
2474 static rtx
2475 frame_move (rtx dst, rtx src)
2477 rtx tmp = gen_rtx_SET (dst, src);
2478 RTX_FRAME_RELATED_P (tmp) = 1;
2479 return frame_insn (tmp);
2482 /* Like frame_move, but add a REG_INC note for REG if ADDR contains an
2483 auto increment address, or is zero. */
2485 static rtx
2486 frame_move_inc (rtx dst, rtx src, rtx reg, rtx addr)
2488 rtx insn = frame_move (dst, src);
2490 if (!addr
2491 || GET_CODE (addr) == PRE_DEC || GET_CODE (addr) == POST_INC
2492 || GET_CODE (addr) == PRE_MODIFY || GET_CODE (addr) == POST_MODIFY)
2493 add_reg_note (insn, REG_INC, reg);
2494 return insn;
2497 /* Emit a frame insn which adjusts a frame address register REG by OFFSET. */
2499 static rtx
2500 frame_add (rtx reg, HOST_WIDE_INT offset)
2502 gcc_assert ((offset & 0x3) == 0);
2503 if (!offset)
2504 return NULL_RTX;
2505 return frame_move (reg, plus_constant (Pmode, reg, offset));
2508 /* Emit a frame insn which adjusts stack pointer by OFFSET. */
2510 static rtx
2511 frame_stack_add (HOST_WIDE_INT offset)
2513 return frame_add (stack_pointer_rtx, offset);
2516 /* Helper function to wrap FRAME_POINTER_NEEDED. We do this as
2517 FRAME_POINTER_NEEDED will not be true until the IRA (Integrated
2518 Register Allocator) pass, while we want to get the frame size
2519 correct earlier than the IRA pass.
2521 When a function uses eh_return we must ensure that the fp register
2522 is saved and then restored so that the unwinder can restore the
2523 correct value for the frame we are going to jump to.
2525 To do this we force all frames that call eh_return to require a
2526 frame pointer (see arc_frame_pointer_required), this
2527 will ensure that the previous frame pointer is stored on entry to
2528 the function, and will then be reloaded at function exit.
2530 As the frame pointer is handled as a special case in our prologue
2531 and epilogue code it must not be saved and restored using the
2532 MUST_SAVE_REGISTER mechanism otherwise we run into issues where GCC
2533 believes that the function is not using a frame pointer and that
2534 the value in the fp register is the frame pointer, while the
2535 prologue and epilogue are busy saving and restoring the fp
2536 register.
2538 During compilation of a function the frame size is evaluated
2539 multiple times, it is not until the reload pass is complete the
2540 frame size is considered fixed (it is at this point that space for
2541 all spills has been allocated). However the frame_pointer_needed
2542 variable is not set true until the register allocation pass, as a
2543 result in the early stages the frame size does not include space
2544 for the frame pointer to be spilled.
2546 The problem that this causes is that the rtl generated for
2547 EH_RETURN_HANDLER_RTX uses the details of the frame size to compute
2548 the offset from the frame pointer at which the return address
2549 lives. However, in early passes GCC has not yet realised we need a
2550 frame pointer, and so has not included space for the frame pointer
2551 in the frame size, and so gets the offset of the return address
2552 wrong. This should not be an issue as in later passes GCC has
2553 realised that the frame pointer needs to be spilled, and has
2554 increased the frame size. However, the rtl for the
2555 EH_RETURN_HANDLER_RTX is not regenerated to use the newer, larger
2556 offset, and the wrong smaller offset is used. */
2558 static bool
2559 arc_frame_pointer_needed (void)
2561 return (frame_pointer_needed || crtl->calls_eh_return);
2564 /* Tell prologue and epilogue if register REGNO should be saved /
2565 restored. The SPECIAL_P is true when the register may need special
2566 ld/st sequence. The return address, and stack pointer are treated
2567 separately. Don't consider them here. */
2569 static bool
2570 arc_must_save_register (int regno, struct function *func, bool special_p)
2572 unsigned int fn_type = arc_compute_function_type (func);
2573 bool irq_auto_save_p = ((irq_ctrl_saved.irq_save_last_reg >= regno)
2574 && ARC_AUTO_IRQ_P (fn_type));
2575 bool firq_auto_save_p = ARC_FAST_INTERRUPT_P (fn_type);
2577 switch (rgf_banked_register_count)
2579 case 4:
2580 firq_auto_save_p &= (regno < 4);
2581 break;
2582 case 8:
2583 firq_auto_save_p &= ((regno < 4) || ((regno > 11) && (regno < 16)));
2584 break;
2585 case 16:
2586 firq_auto_save_p &= ((regno < 4) || ((regno > 9) && (regno < 16))
2587 || ((regno > 25) && (regno < 29))
2588 || ((regno > 29) && (regno < 32)));
2589 break;
2590 case 32:
2591 firq_auto_save_p &= (regno != 29) && (regno < 32);
2592 break;
2593 default:
2594 firq_auto_save_p = false;
2595 break;
2598 switch (regno)
2600 case ILINK1_REG:
2601 case RETURN_ADDR_REGNUM:
2602 case STACK_POINTER_REGNUM:
2603 /* The stack pointer and the return address are handled
2604 separately. */
2605 return false;
2607 case R30_REG:
2608 /* r30 is either used as ilink2 by ARCv1 or as a free register
2609 by ARCv2. */
2610 if (!TARGET_V2)
2611 return false;
2612 break;
2614 case R40_REG:
2615 case R41_REG:
2616 case R42_REG:
2617 case R43_REG:
2618 case R44_REG:
2619 /* If those ones are used by the FPX machinery, we handle them
2620 separately. */
2621 if (TARGET_DPFP && !special_p)
2622 return false;
2623 /* FALLTHRU. */
2625 case R32_REG:
2626 case R33_REG:
2627 case R34_REG:
2628 case R35_REG:
2629 case R36_REG:
2630 case R37_REG:
2631 case R38_REG:
2632 case R39_REG:
2633 case R45_REG:
2634 case R46_REG:
2635 case R47_REG:
2636 case R48_REG:
2637 case R49_REG:
2638 case R50_REG:
2639 case R51_REG:
2640 case R52_REG:
2641 case R53_REG:
2642 case R54_REG:
2643 case R55_REG:
2644 case R56_REG:
2645 case R57_REG:
2646 /* The Extension Registers. */
2647 if (ARC_INTERRUPT_P (fn_type)
2648 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2649 || df_regs_ever_live_p (regno))
2650 /* Not all extension registers are available, choose the
2651 real ones. */
2652 && !fixed_regs[regno])
2653 return true;
2654 return false;
2656 case R58_REG:
2657 case R59_REG:
2658 /* ARC600 specifies those ones as mlo/mhi registers, otherwise
2659 just handle them like any other extension register. */
2660 if (ARC_INTERRUPT_P (fn_type)
2661 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2662 || df_regs_ever_live_p (regno))
2663 /* Not all extension registers are available, choose the
2664 real ones. */
2665 && ((!fixed_regs[regno] && !special_p)
2666 || (TARGET_MUL64_SET && special_p)))
2667 return true;
2668 return false;
2670 case 61:
2671 case 62:
2672 case 63:
2673 /* Fixed/control register, nothing to do. LP_COUNT is
2674 different. */
2675 return false;
2677 case HARD_FRAME_POINTER_REGNUM:
2678 /* If we need FP reg as a frame pointer then don't save it as a
2679 regular reg. */
2680 if (arc_frame_pointer_needed ())
2681 return false;
2682 break;
2684 default:
2685 break;
2688 if (((df_regs_ever_live_p (regno) && !call_used_or_fixed_reg_p (regno))
2689 /* In an interrupt save everything. */
2690 || (ARC_INTERRUPT_P (fn_type)
2691 && (df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2692 || df_regs_ever_live_p (regno))))
2693 /* Do not emit code for auto saved regs. */
2694 && !irq_auto_save_p
2695 && !firq_auto_save_p)
2696 return true;
2697 return false;
2700 /* Return true if the return address must be saved in the current function,
2701 otherwise return false. */
2703 static bool
2704 arc_must_save_return_addr (struct function *func)
2706 if (func->machine->frame_info.save_return_addr)
2707 return true;
2709 return false;
2712 /* Return non-zero if there are registers to be saved or loaded using
2713 millicode thunks. We can only use consecutive sequences starting
2714 with r13, and not going beyond r25.
2715 GMASK is a bitmask of registers to save. This function sets
2716 FRAME->millicod_start_reg .. FRAME->millicode_end_reg to the range
2717 of registers to be saved / restored with a millicode call. */
2719 static int
2720 arc_compute_millicode_save_restore_regs (uint64_t gmask,
2721 struct arc_frame_info *frame)
2723 int regno;
2725 int start_reg = 13, end_reg = 25;
2727 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
2728 regno++;
2729 end_reg = regno - 1;
2730 /* There is no point in using millicode thunks if we don't save/restore
2731 at least three registers. For non-leaf functions we also have the
2732 blink restore. */
2733 if (regno - start_reg >= 3 - (crtl->is_leaf == 0))
2735 frame->millicode_start_reg = 13;
2736 frame->millicode_end_reg = regno - 1;
2737 return 1;
2739 return 0;
2742 /* Return the bytes needed to compute the frame pointer from the
2743 current stack pointer. */
2745 static unsigned int
2746 arc_compute_frame_size (void)
2748 int regno;
2749 unsigned int total_size, var_size, args_size, pretend_size, extra_size;
2750 unsigned int reg_size;
2751 uint64_t gmask;
2752 struct arc_frame_info *frame_info;
2753 int size;
2754 unsigned int extra_plus_reg_size;
2755 unsigned int extra_plus_reg_size_aligned;
2756 unsigned int fn_type = arc_compute_function_type (cfun);
2758 /* The answer might already be known. */
2759 if (cfun->machine->frame_info.initialized)
2760 return cfun->machine->frame_info.total_size;
2762 frame_info = &cfun->machine->frame_info;
2763 size = ARC_STACK_ALIGN (get_frame_size ());
2765 /* 1) Size of locals and temporaries. */
2766 var_size = size;
2768 /* 2) Size of outgoing arguments. */
2769 args_size = crtl->outgoing_args_size;
2771 /* 3) Calculate space needed for saved registers.
2772 ??? We ignore the extension registers for now. */
2774 /* See if this is an interrupt handler. Call used registers must be saved
2775 for them too. */
2777 reg_size = 0;
2778 gmask = 0;
2780 /* The last 4 regs are special, avoid them. */
2781 for (regno = 0; regno <= (GMASK_LEN - 4); regno++)
2783 if (arc_must_save_register (regno, cfun, false))
2785 reg_size += UNITS_PER_WORD;
2786 gmask |= 1ULL << regno;
2790 /* In a frame that calls __builtin_eh_return two data registers are
2791 used to pass values back to the exception handler.
2793 Ensure that these registers are spilled to the stack so that the
2794 exception throw code can find them, and update the saved values.
2795 The handling code will then consume these reloaded values to
2796 handle the exception. */
2797 if (crtl->calls_eh_return)
2798 for (regno = 0; EH_RETURN_DATA_REGNO (regno) != INVALID_REGNUM; regno++)
2800 reg_size += UNITS_PER_WORD;
2801 gmask |= 1ULL << regno;
2804 /* Check if we need to save the return address. */
2805 frame_info->save_return_addr = (!crtl->is_leaf
2806 || df_regs_ever_live_p (RETURN_ADDR_REGNUM)
2807 || crtl->calls_eh_return);
2809 /* Saving blink reg for millicode thunk calls. */
2810 if (TARGET_MILLICODE_THUNK_SET
2811 && !ARC_INTERRUPT_P (fn_type)
2812 && !crtl->calls_eh_return)
2814 if (arc_compute_millicode_save_restore_regs (gmask, frame_info))
2815 frame_info->save_return_addr = true;
2818 /* Save lp_count, lp_start and lp_end. */
2819 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
2820 reg_size += UNITS_PER_WORD * 3;
2822 /* Check for the special R40-R44 regs used by FPX extension. */
2823 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
2824 cfun, TARGET_DPFP))
2825 reg_size += UNITS_PER_WORD * 2;
2826 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R43_REG : R42_REG,
2827 cfun, TARGET_DPFP))
2828 reg_size += UNITS_PER_WORD * 2;
2830 /* Check if R58 is used. */
2831 if (arc_must_save_register (R58_REG, cfun, true))
2832 reg_size += UNITS_PER_WORD * 2;
2834 /* 4) Calculate extra size made up of the blink + fp size. */
2835 extra_size = 0;
2836 if (arc_must_save_return_addr (cfun))
2837 extra_size = 4;
2838 /* Add FP size only when it is not autosaved. */
2839 if (arc_frame_pointer_needed ()
2840 && !ARC_AUTOFP_IRQ_P (fn_type))
2841 extra_size += 4;
2843 /* 5) Space for variable arguments passed in registers */
2844 pretend_size = crtl->args.pretend_args_size;
2846 /* Ensure everything before the locals is aligned appropriately. */
2847 extra_plus_reg_size = extra_size + reg_size;
2848 extra_plus_reg_size_aligned = ARC_STACK_ALIGN (extra_plus_reg_size);
2849 reg_size = extra_plus_reg_size_aligned - extra_size;
2851 /* Compute total frame size. */
2852 total_size = var_size + args_size + extra_size + pretend_size + reg_size;
2854 /* It used to be the case that the alignment was forced at this
2855 point. However, that is dangerous, calculations based on
2856 total_size would be wrong. Given that this has never cropped up
2857 as an issue I've changed this to an assert for now. */
2858 gcc_assert (total_size == ARC_STACK_ALIGN (total_size));
2860 /* Save computed information. */
2861 frame_info->total_size = total_size;
2862 frame_info->extra_size = extra_size;
2863 frame_info->pretend_size = pretend_size;
2864 frame_info->var_size = var_size;
2865 frame_info->args_size = args_size;
2866 frame_info->reg_size = reg_size;
2867 frame_info->gmask = gmask;
2868 frame_info->initialized = reload_completed;
2870 /* Ok, we're done. */
2871 return total_size;
2874 /* Build dwarf information when the context is saved via AUX_IRQ_CTRL
2875 mechanism. */
2877 static void
2878 arc_dwarf_emit_irq_save_regs (void)
2880 rtx tmp, par, insn, reg;
2881 int i, offset, j;
2883 par = gen_rtx_SEQUENCE (VOIDmode,
2884 rtvec_alloc (irq_ctrl_saved.irq_save_last_reg + 1
2885 + irq_ctrl_saved.irq_save_blink
2886 + irq_ctrl_saved.irq_save_lpcount
2887 + 1));
2889 /* Build the stack adjustment note for unwind info. */
2890 j = 0;
2891 offset = UNITS_PER_WORD * (irq_ctrl_saved.irq_save_last_reg + 1
2892 + irq_ctrl_saved.irq_save_blink
2893 + irq_ctrl_saved.irq_save_lpcount);
2894 tmp = plus_constant (Pmode, stack_pointer_rtx, -1 * offset);
2895 tmp = gen_rtx_SET (stack_pointer_rtx, tmp);
2896 RTX_FRAME_RELATED_P (tmp) = 1;
2897 XVECEXP (par, 0, j++) = tmp;
2899 offset -= UNITS_PER_WORD;
2901 /* 1st goes LP_COUNT. */
2902 if (irq_ctrl_saved.irq_save_lpcount)
2904 reg = gen_rtx_REG (SImode, 60);
2905 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2906 tmp = gen_frame_mem (SImode, tmp);
2907 tmp = gen_rtx_SET (tmp, reg);
2908 RTX_FRAME_RELATED_P (tmp) = 1;
2909 XVECEXP (par, 0, j++) = tmp;
2910 offset -= UNITS_PER_WORD;
2913 /* 2nd goes BLINK. */
2914 if (irq_ctrl_saved.irq_save_blink)
2916 reg = gen_rtx_REG (SImode, 31);
2917 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2918 tmp = gen_frame_mem (SImode, tmp);
2919 tmp = gen_rtx_SET (tmp, reg);
2920 RTX_FRAME_RELATED_P (tmp) = 1;
2921 XVECEXP (par, 0, j++) = tmp;
2922 offset -= UNITS_PER_WORD;
2925 /* Build the parallel of the remaining registers recorded as saved
2926 for unwind. */
2927 for (i = irq_ctrl_saved.irq_save_last_reg; i >= 0; i--)
2929 reg = gen_rtx_REG (SImode, i);
2930 tmp = plus_constant (Pmode, stack_pointer_rtx, offset);
2931 tmp = gen_frame_mem (SImode, tmp);
2932 tmp = gen_rtx_SET (tmp, reg);
2933 RTX_FRAME_RELATED_P (tmp) = 1;
2934 XVECEXP (par, 0, j++) = tmp;
2935 offset -= UNITS_PER_WORD;
2938 /* Dummy insn used to anchor the dwarf info. */
2939 insn = emit_insn (gen_stack_irq_dwarf());
2940 add_reg_note (insn, REG_FRAME_RELATED_EXPR, par);
2941 RTX_FRAME_RELATED_P (insn) = 1;
2944 /* Helper for prologue: emit frame store with pre_modify or pre_dec to
2945 save register REG on stack. An initial offset OFFSET can be passed
2946 to the function. */
2948 static int
2949 frame_save_reg (rtx reg, HOST_WIDE_INT offset)
2951 rtx addr;
2953 if (offset)
2955 rtx tmp = plus_constant (Pmode, stack_pointer_rtx,
2956 offset - GET_MODE_SIZE (GET_MODE (reg)));
2957 addr = gen_frame_mem (GET_MODE (reg),
2958 gen_rtx_PRE_MODIFY (Pmode,
2959 stack_pointer_rtx,
2960 tmp));
2962 else
2963 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
2964 stack_pointer_rtx));
2965 frame_move_inc (addr, reg, stack_pointer_rtx, 0);
2967 return GET_MODE_SIZE (GET_MODE (reg)) - offset;
2970 /* Helper used when saving AUX regs during ISR. */
2972 static int
2973 push_reg (rtx reg)
2975 rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_PRE_DEC (Pmode,
2976 stack_pointer_rtx));
2977 rtx insn = emit_move_insn (stkslot, reg);
2978 RTX_FRAME_RELATED_P (insn) = 1;
2979 add_reg_note (insn, REG_CFA_ADJUST_CFA,
2980 gen_rtx_SET (stack_pointer_rtx,
2981 plus_constant (Pmode, stack_pointer_rtx,
2982 -GET_MODE_SIZE (GET_MODE (reg)))));
2983 return GET_MODE_SIZE (GET_MODE (reg));
2986 /* Helper for epilogue: emit frame load with post_modify or post_inc
2987 to restore register REG from stack. The initial offset is passed
2988 via OFFSET. */
2990 static int
2991 frame_restore_reg (rtx reg, HOST_WIDE_INT offset)
2993 rtx addr, insn;
2995 if (offset)
2997 rtx tmp = plus_constant (Pmode, stack_pointer_rtx,
2998 offset + GET_MODE_SIZE (GET_MODE (reg)));
2999 addr = gen_frame_mem (GET_MODE (reg),
3000 gen_rtx_POST_MODIFY (Pmode,
3001 stack_pointer_rtx,
3002 tmp));
3004 else
3005 addr = gen_frame_mem (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
3006 stack_pointer_rtx));
3007 insn = frame_move_inc (reg, addr, stack_pointer_rtx, 0);
3008 add_reg_note (insn, REG_CFA_RESTORE, reg);
3010 if (reg == hard_frame_pointer_rtx)
3011 add_reg_note (insn, REG_CFA_DEF_CFA,
3012 plus_constant (Pmode, stack_pointer_rtx,
3013 GET_MODE_SIZE (GET_MODE (reg)) + offset));
3014 else
3015 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3016 gen_rtx_SET (stack_pointer_rtx,
3017 plus_constant (Pmode, stack_pointer_rtx,
3018 GET_MODE_SIZE (GET_MODE (reg))
3019 + offset)));
3021 return GET_MODE_SIZE (GET_MODE (reg)) + offset;
3024 /* Helper used when restoring AUX regs during ISR. */
3026 static int
3027 pop_reg (rtx reg)
3029 rtx stkslot = gen_rtx_MEM (GET_MODE (reg), gen_rtx_POST_INC (Pmode,
3030 stack_pointer_rtx));
3031 rtx insn = emit_move_insn (reg, stkslot);
3032 RTX_FRAME_RELATED_P (insn) = 1;
3033 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3034 gen_rtx_SET (stack_pointer_rtx,
3035 plus_constant (Pmode, stack_pointer_rtx,
3036 GET_MODE_SIZE (GET_MODE (reg)))));
3037 return GET_MODE_SIZE (GET_MODE (reg));
3040 /* Check if we have a continous range to be save/restored with the
3041 help of enter/leave instructions. A vaild register range starts
3042 from $r13 and is up to (including) $r26. */
3044 static bool
3045 arc_enter_leave_p (uint64_t gmask)
3047 int regno;
3048 unsigned int rmask = 0;
3050 if (!gmask)
3051 return false;
3053 for (regno = ENTER_LEAVE_START_REG;
3054 regno <= ENTER_LEAVE_END_REG && (gmask & (1ULL << regno)); regno++)
3055 rmask |= 1ULL << regno;
3057 if (rmask ^ gmask)
3058 return false;
3060 return true;
3063 /* ARC's prologue, save any needed call-saved regs (and call-used if
3064 this is an interrupt handler) for ARCompact ISA, using ST/STD
3065 instructions. */
3067 static int
3068 arc_save_callee_saves (uint64_t gmask,
3069 bool save_blink,
3070 bool save_fp,
3071 HOST_WIDE_INT offset,
3072 bool emit_move)
3074 rtx reg;
3075 int frame_allocated = 0;
3076 int i;
3078 /* The home-grown ABI says link register is saved first. */
3079 if (save_blink)
3081 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3082 frame_allocated += frame_save_reg (reg, offset);
3083 offset = 0;
3086 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3087 if (gmask)
3088 for (i = GMASK_LEN; i >= 0; i--)
3090 machine_mode save_mode = SImode;
3092 if (TARGET_LL64
3093 && ((i - 1) % 2 == 0)
3094 && ((gmask & (1ULL << i)) != 0)
3095 && ((gmask & (1ULL << (i - 1))) != 0))
3097 save_mode = DImode;
3098 --i;
3100 else if ((gmask & (1ULL << i)) == 0)
3101 continue;
3103 reg = gen_rtx_REG (save_mode, i);
3104 frame_allocated += frame_save_reg (reg, offset);
3105 offset = 0;
3108 /* Save frame pointer if needed. First save the FP on stack, if not
3109 autosaved. Unfortunately, I cannot add it to gmask and use the
3110 above loop to save fp because our ABI states fp goes aftert all
3111 registers are saved. */
3112 if (save_fp)
3114 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3115 offset = 0;
3118 /* Emit mov fp,sp. */
3119 if (emit_move)
3120 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3122 return frame_allocated;
3125 /* ARC's epilogue, restore any required call-saved regs (and call-used
3126 if it is for an interrupt handler) using LD/LDD instructions. */
3128 static int
3129 arc_restore_callee_saves (uint64_t gmask,
3130 bool restore_blink,
3131 bool restore_fp,
3132 HOST_WIDE_INT offset,
3133 HOST_WIDE_INT allocated)
3135 rtx reg;
3136 int frame_deallocated = 0;
3137 HOST_WIDE_INT offs = cfun->machine->frame_info.reg_size;
3138 unsigned int fn_type = arc_compute_function_type (cfun);
3139 bool early_blink_restore;
3140 int i;
3142 /* Emit mov fp,sp. */
3143 if (arc_frame_pointer_needed () && offset)
3145 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3146 frame_deallocated += offset;
3147 offset = 0;
3150 if (restore_fp)
3152 /* Any offset is taken care by previous if-statement. */
3153 gcc_assert (offset == 0);
3154 frame_deallocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3157 if (offset)
3159 /* No $fp involved, we need to do an add to set the $sp to the
3160 location of the first register. */
3161 frame_stack_add (offset);
3162 frame_deallocated += offset;
3163 offset = 0;
3166 /* When we do not optimize for size or we aren't in an interrupt,
3167 restore first blink. */
3168 early_blink_restore = restore_blink && !optimize_size && offs
3169 && !ARC_INTERRUPT_P (fn_type);
3170 if (early_blink_restore)
3172 rtx addr = plus_constant (Pmode, stack_pointer_rtx, offs);
3173 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3174 rtx insn = frame_move_inc (reg, gen_frame_mem (Pmode, addr),
3175 stack_pointer_rtx, NULL_RTX);
3176 add_reg_note (insn, REG_CFA_RESTORE, reg);
3177 restore_blink = false;
3180 /* N.B. FRAME_POINTER_MASK and RETURN_ADDR_MASK are cleared in gmask. */
3181 if (gmask)
3182 for (i = 0; i <= GMASK_LEN; i++)
3184 machine_mode restore_mode = SImode;
3186 if (TARGET_LL64
3187 && ((i % 2) == 0)
3188 && ((gmask & (1ULL << i)) != 0)
3189 && ((gmask & (1ULL << (i + 1))) != 0))
3190 restore_mode = DImode;
3191 else if ((gmask & (1ULL << i)) == 0)
3192 continue;
3194 reg = gen_rtx_REG (restore_mode, i);
3195 offs = 0;
3196 switch (restore_mode)
3198 case E_DImode:
3199 if ((GMASK_LEN - __builtin_clzll (gmask)) == (i + 1)
3200 && early_blink_restore)
3201 offs = 4;
3202 break;
3203 case E_SImode:
3204 if ((GMASK_LEN - __builtin_clzll (gmask)) == i
3205 && early_blink_restore)
3206 offs = 4;
3207 break;
3208 default:
3209 offs = 0;
3211 frame_deallocated += frame_restore_reg (reg, offs);
3212 offset = 0;
3214 if (restore_mode == DImode)
3215 i++;
3218 if (restore_blink)
3220 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3221 frame_deallocated += frame_restore_reg (reg, allocated
3222 - frame_deallocated
3223 /* Consider as well the
3224 current restored
3225 register size. */
3226 - UNITS_PER_WORD);
3229 return frame_deallocated;
3232 /* ARC prologue, save the registers using enter instruction. Leave
3233 instruction can also save $blink (SAVE_BLINK) and $fp (SAVE_FP)
3234 register. */
3236 static int
3237 arc_save_callee_enter (uint64_t gmask,
3238 bool save_blink,
3239 bool save_fp,
3240 HOST_WIDE_INT offset)
3242 int start_reg = ENTER_LEAVE_START_REG;
3243 int end_reg = ENTER_LEAVE_END_REG;
3244 int regno, indx, off, nregs;
3245 rtx insn, reg, mem;
3246 int frame_allocated = 0;
3248 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3249 regno++;
3251 end_reg = regno - 1;
3252 nregs = end_reg - start_reg + 1;
3253 nregs += save_blink ? 1 : 0;
3254 nregs += save_fp ? 1 : 0;
3256 if (offset)
3257 frame_stack_add (offset);
3259 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + (save_fp ? 1 : 0)
3260 + 1));
3261 indx = 0;
3263 reg = gen_rtx_SET (stack_pointer_rtx,
3264 plus_constant (Pmode,
3265 stack_pointer_rtx,
3266 -nregs * UNITS_PER_WORD));
3267 RTX_FRAME_RELATED_P (reg) = 1;
3268 XVECEXP (insn, 0, indx++) = reg;
3269 off = nregs * UNITS_PER_WORD;
3271 if (save_blink)
3273 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3274 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3275 stack_pointer_rtx,
3276 -off));
3277 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3278 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3279 off -= UNITS_PER_WORD;
3280 save_blink = false;
3283 for (regno = start_reg;
3284 regno <= end_reg;
3285 regno++, indx++, off -= UNITS_PER_WORD)
3287 reg = gen_rtx_REG (SImode, regno);
3288 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3289 stack_pointer_rtx,
3290 -off));
3291 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3292 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3293 gmask = gmask & ~(1ULL << regno);
3296 if (save_fp)
3298 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3299 stack_pointer_rtx,
3300 -off));
3301 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, hard_frame_pointer_rtx);
3302 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3303 off -= UNITS_PER_WORD;
3305 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx,
3306 stack_pointer_rtx);
3307 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3308 save_fp = false;
3311 gcc_assert (off == 0);
3312 insn = frame_insn (insn);
3314 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3316 frame_allocated = nregs * UNITS_PER_WORD;
3318 /* offset is a negative number, make sure we add it. */
3319 return frame_allocated - offset;
3322 /* ARC epilogue, restore the registers using leave instruction. An
3323 initial offset is passed in OFFSET. Besides restoring an register
3324 range, leave can also restore $blink (RESTORE_BLINK), or $fp
3325 (RESTORE_FP), and can automatic return (RETURN_P). */
3327 static int
3328 arc_restore_callee_leave (uint64_t gmask,
3329 bool restore_blink,
3330 bool restore_fp,
3331 bool return_p,
3332 HOST_WIDE_INT offset)
3334 int start_reg = ENTER_LEAVE_START_REG;
3335 int end_reg = ENTER_LEAVE_END_REG;
3336 int regno, indx, off, nregs;
3337 rtx insn, reg, mem;
3338 int frame_allocated = 0;
3340 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3341 regno++;
3343 end_reg = regno - 1;
3344 nregs = end_reg - start_reg + 1;
3345 nregs += restore_blink ? 1 : 0;
3346 nregs += restore_fp ? 1 : 0;
3348 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1
3349 + (return_p ? 1 : 0)));
3350 indx = 0;
3352 if (return_p)
3353 XVECEXP (insn, 0, indx++) = ret_rtx;
3355 if (restore_fp)
3357 /* I cannot emit set (sp, fp) here as cselib expects a single sp
3358 set and not two. Thus, use the offset, and change sp adjust
3359 value. */
3360 frame_allocated += offset;
3363 if (offset && !restore_fp)
3365 /* This add is only emmited when we do not restore fp with leave
3366 instruction. */
3367 frame_stack_add (offset);
3368 frame_allocated += offset;
3369 offset = 0;
3372 reg = gen_rtx_SET (stack_pointer_rtx,
3373 plus_constant (Pmode,
3374 stack_pointer_rtx,
3375 offset + nregs * UNITS_PER_WORD));
3376 RTX_FRAME_RELATED_P (reg) = 1;
3377 XVECEXP (insn, 0, indx++) = reg;
3378 off = nregs * UNITS_PER_WORD;
3380 if (restore_blink)
3382 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3383 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3384 stack_pointer_rtx,
3385 off));
3386 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3387 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3388 off -= UNITS_PER_WORD;
3391 for (regno = start_reg;
3392 regno <= end_reg;
3393 regno++, indx++, off -= UNITS_PER_WORD)
3395 reg = gen_rtx_REG (SImode, regno);
3396 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3397 stack_pointer_rtx,
3398 off));
3399 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3400 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3401 gmask = gmask & ~(1ULL << regno);
3404 if (restore_fp)
3406 mem = gen_frame_mem (Pmode, plus_constant (Pmode,
3407 stack_pointer_rtx,
3408 off));
3409 XVECEXP (insn, 0, indx) = gen_rtx_SET (hard_frame_pointer_rtx, mem);
3410 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx++)) = 1;
3411 off -= UNITS_PER_WORD;
3414 gcc_assert (off == 0);
3415 if (return_p)
3417 insn = emit_jump_insn (insn);
3418 RTX_FRAME_RELATED_P (insn) = 1;
3420 else
3421 insn = frame_insn (insn);
3423 add_reg_note (insn, REG_INC, stack_pointer_rtx);
3425 /* Dwarf related info. */
3426 if (restore_fp)
3428 add_reg_note (insn, REG_CFA_RESTORE, hard_frame_pointer_rtx);
3429 add_reg_note (insn, REG_CFA_DEF_CFA,
3430 plus_constant (Pmode, stack_pointer_rtx,
3431 offset + nregs * UNITS_PER_WORD));
3433 else
3435 add_reg_note (insn, REG_CFA_ADJUST_CFA,
3436 gen_rtx_SET (stack_pointer_rtx,
3437 plus_constant (Pmode, stack_pointer_rtx,
3438 nregs * UNITS_PER_WORD)));
3440 if (restore_blink)
3441 add_reg_note (insn, REG_CFA_RESTORE,
3442 gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3443 for (regno = start_reg; regno <= end_reg; regno++)
3444 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, regno));
3446 frame_allocated += nregs * UNITS_PER_WORD;
3448 return frame_allocated;
3451 /* Millicode thunks implementation:
3452 Generates calls to millicodes for registers starting from r13 to r25
3453 Present Limitations:
3454 - Only one range supported. The remaining regs will have the ordinary
3455 st and ld instructions for store and loads. Hence a gmask asking
3456 to store r13-14, r16-r25 will only generate calls to store and
3457 load r13 to r14 while store and load insns will be generated for
3458 r16 to r25 in the prologue and epilogue respectively.
3460 - Presently library only supports register ranges starting from r13.
3463 static int
3464 arc_save_callee_milli (uint64_t gmask,
3465 bool save_blink,
3466 bool save_fp,
3467 HOST_WIDE_INT offset,
3468 HOST_WIDE_INT reg_size)
3470 int start_reg = 13;
3471 int end_reg = 25;
3472 int regno, indx, off, nregs;
3473 rtx insn, reg, mem;
3474 int frame_allocated = 0;
3476 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3477 regno++;
3479 end_reg = regno - 1;
3480 nregs = end_reg - start_reg + 1;
3481 gcc_assert (end_reg > 14);
3484 /* Allocate space on stack for the registers, and take into account
3485 also the initial offset. The registers will be saved using
3486 offsets. N.B. OFFSET is a negative number. */
3487 if (save_blink)
3489 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3490 frame_allocated += frame_save_reg (reg, offset);
3491 offset = 0;
3494 if (reg_size || offset)
3496 frame_stack_add (offset - reg_size);
3497 frame_allocated += nregs * UNITS_PER_WORD - offset;
3498 offset = 0;
3501 /* Start generate millicode call. */
3502 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (nregs + 1));
3503 indx = 0;
3505 /* This is a call, we clobber blink. */
3506 XVECEXP (insn, 0, nregs) =
3507 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3509 for (regno = start_reg, indx = 0, off = 0;
3510 regno <= end_reg;
3511 regno++, indx++, off += UNITS_PER_WORD)
3513 reg = gen_rtx_REG (SImode, regno);
3514 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3515 stack_pointer_rtx,
3516 off));
3517 XVECEXP (insn, 0, indx) = gen_rtx_SET (mem, reg);
3518 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3519 gmask = gmask & ~(1ULL << regno);
3521 insn = frame_insn (insn);
3523 /* Add DWARF info. */
3524 for (regno = start_reg, off = 0;
3525 regno <= end_reg;
3526 regno++, off += UNITS_PER_WORD)
3528 reg = gen_rtx_REG (SImode, regno);
3529 mem = gen_rtx_MEM (SImode, plus_constant (Pmode,
3530 stack_pointer_rtx, off));
3531 add_reg_note (insn, REG_CFA_OFFSET, gen_rtx_SET (mem, reg));
3535 /* In the case of millicode thunk, we need to restore the
3536 clobbered blink register. */
3537 if (arc_must_save_return_addr (cfun))
3539 emit_insn (gen_rtx_SET (gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM),
3540 gen_rtx_MEM (Pmode,
3541 plus_constant (Pmode,
3542 stack_pointer_rtx,
3543 reg_size))));
3546 /* Save remaining registers using st instructions. */
3547 for (regno = 0; regno <= GMASK_LEN; regno++)
3549 if ((gmask & (1ULL << regno)) == 0)
3550 continue;
3552 reg = gen_rtx_REG (SImode, regno);
3553 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3554 stack_pointer_rtx,
3555 off));
3556 frame_move_inc (mem, reg, stack_pointer_rtx, 0);
3557 frame_allocated += UNITS_PER_WORD;
3558 off += UNITS_PER_WORD;
3561 /* Save frame pointer if needed. First save the FP on stack, if not
3562 autosaved. Unfortunately, I cannot add it to gmask and use the
3563 above loop to save fp because our ABI states fp goes aftert all
3564 registers are saved. */
3565 if (save_fp)
3566 frame_allocated += frame_save_reg (hard_frame_pointer_rtx, offset);
3568 /* Emit mov fp,sp. */
3569 if (arc_frame_pointer_needed ())
3570 frame_move (hard_frame_pointer_rtx, stack_pointer_rtx);
3572 return frame_allocated;
3575 /* Like the previous function but restore. */
3577 static int
3578 arc_restore_callee_milli (uint64_t gmask,
3579 bool restore_blink,
3580 bool restore_fp,
3581 bool return_p,
3582 HOST_WIDE_INT offset)
3584 int start_reg = 13;
3585 int end_reg = 25;
3586 int regno, indx, off, nregs;
3587 rtx insn, reg, mem;
3588 int frame_allocated = 0;
3590 for (regno = start_reg; regno <= end_reg && (gmask & (1ULL << regno));)
3591 regno++;
3593 end_reg = regno - 1;
3594 nregs = end_reg - start_reg + 1;
3595 gcc_assert (end_reg > 14);
3597 /* Emit mov fp,sp. */
3598 if (arc_frame_pointer_needed () && offset)
3600 frame_move (stack_pointer_rtx, hard_frame_pointer_rtx);
3601 frame_allocated = offset;
3602 offset = 0;
3605 if (restore_fp)
3606 frame_allocated += frame_restore_reg (hard_frame_pointer_rtx, 0);
3608 if (offset)
3610 /* No fp involved, hence, we need to adjust the sp via an
3611 add. */
3612 frame_stack_add (offset);
3613 frame_allocated += offset;
3614 offset = 0;
3617 /* Start generate millicode call. */
3618 insn = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc ((return_p ? 1 : 0)
3619 + nregs + 1));
3620 indx = 0;
3622 if (return_p)
3624 /* sibling call, the blink is restored with the help of the
3625 value held into r12. */
3626 reg = gen_rtx_REG (Pmode, 12);
3627 XVECEXP (insn, 0, indx++) = ret_rtx;
3628 XVECEXP (insn, 0, indx++) =
3629 gen_rtx_SET (stack_pointer_rtx,
3630 gen_rtx_PLUS (Pmode, stack_pointer_rtx, reg));
3631 frame_allocated += UNITS_PER_WORD;
3633 else
3635 /* This is a call, we clobber blink. */
3636 XVECEXP (insn, 0, nregs) =
3637 gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM));
3640 for (regno = start_reg, off = 0;
3641 regno <= end_reg;
3642 regno++, indx++, off += UNITS_PER_WORD)
3644 reg = gen_rtx_REG (SImode, regno);
3645 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3646 stack_pointer_rtx,
3647 off));
3648 XVECEXP (insn, 0, indx) = gen_rtx_SET (reg, mem);
3649 RTX_FRAME_RELATED_P (XVECEXP (insn, 0, indx)) = 1;
3650 gmask = gmask & ~(1ULL << regno);
3653 /* Restore remaining registers using LD instructions. */
3654 for (regno = 0; regno <= GMASK_LEN; regno++)
3656 if ((gmask & (1ULL << regno)) == 0)
3657 continue;
3659 reg = gen_rtx_REG (SImode, regno);
3660 mem = gen_frame_mem (SImode, plus_constant (Pmode,
3661 stack_pointer_rtx,
3662 off));
3663 rtx tmp = frame_move_inc (reg, mem, stack_pointer_rtx, 0);
3664 add_reg_note (tmp, REG_CFA_RESTORE, reg);
3665 off += UNITS_PER_WORD;
3668 /* Emit millicode call. */
3669 if (return_p)
3671 reg = gen_rtx_REG (Pmode, 12);
3672 frame_insn (gen_rtx_SET (reg, GEN_INT (off)));
3673 frame_allocated += off;
3674 insn = emit_jump_insn (insn);
3675 RTX_FRAME_RELATED_P (insn) = 1;
3677 else
3678 insn = frame_insn (insn);
3680 /* Add DWARF info. */
3681 for (regno = start_reg; regno <= end_reg; regno++)
3683 reg = gen_rtx_REG (SImode, regno);
3684 add_reg_note (insn, REG_CFA_RESTORE, reg);
3688 if (restore_blink && !return_p)
3690 reg = gen_rtx_REG (Pmode, RETURN_ADDR_REGNUM);
3691 mem = gen_frame_mem (Pmode, plus_constant (Pmode, stack_pointer_rtx,
3692 off));
3693 insn = frame_insn (gen_rtx_SET (reg, mem));
3694 add_reg_note (insn, REG_CFA_RESTORE, reg);
3697 return frame_allocated;
3700 /* Set up the stack and frame pointer (if desired) for the function. */
3702 void
3703 arc_expand_prologue (void)
3705 int size;
3706 uint64_t gmask = cfun->machine->frame_info.gmask;
3707 struct arc_frame_info *frame = &cfun->machine->frame_info;
3708 unsigned int frame_size_to_allocate;
3709 int first_offset = 0;
3710 unsigned int fn_type = arc_compute_function_type (cfun);
3711 bool save_blink = false;
3712 bool save_fp = false;
3713 bool emit_move = false;
3715 /* Naked functions don't have prologue. */
3716 if (ARC_NAKED_P (fn_type))
3718 if (flag_stack_usage_info)
3719 current_function_static_stack_size = 0;
3720 return;
3723 /* Compute total frame size. */
3724 size = arc_compute_frame_size ();
3726 if (flag_stack_usage_info)
3727 current_function_static_stack_size = size;
3729 /* Keep track of frame size to be allocated. */
3730 frame_size_to_allocate = size;
3732 /* These cases shouldn't happen. Catch them now. */
3733 gcc_assert (!(size == 0 && gmask));
3735 /* Allocate space for register arguments if this is a variadic function. */
3736 if (frame->pretend_size != 0)
3737 first_offset = -frame->pretend_size;
3739 /* IRQ using automatic save mechanism will save the register before
3740 anything we do. */
3741 if (ARC_AUTO_IRQ_P (fn_type)
3742 && !ARC_FAST_INTERRUPT_P (fn_type))
3744 frame_stack_add (first_offset);
3745 first_offset = 0;
3746 arc_dwarf_emit_irq_save_regs ();
3749 save_blink = arc_must_save_return_addr (cfun)
3750 && !ARC_AUTOBLINK_IRQ_P (fn_type);
3751 save_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type)
3752 && !ARC_INTERRUPT_P (fn_type);
3753 emit_move = arc_frame_pointer_needed () && !ARC_INTERRUPT_P (fn_type);
3755 /* Use enter/leave only for non-interrupt functions. */
3756 if (TARGET_CODE_DENSITY
3757 && TARGET_CODE_DENSITY_FRAME
3758 && !ARC_AUTOFP_IRQ_P (fn_type)
3759 && !ARC_AUTOBLINK_IRQ_P (fn_type)
3760 && !ARC_INTERRUPT_P (fn_type)
3761 && arc_enter_leave_p (gmask))
3762 frame_size_to_allocate -= arc_save_callee_enter (gmask, save_blink,
3763 save_fp,
3764 first_offset);
3765 else if (frame->millicode_end_reg > 14)
3766 frame_size_to_allocate -= arc_save_callee_milli (gmask, save_blink,
3767 save_fp,
3768 first_offset,
3769 frame->reg_size);
3770 else
3771 frame_size_to_allocate -= arc_save_callee_saves (gmask, save_blink, save_fp,
3772 first_offset, emit_move);
3774 /* Check if we need to save the ZOL machinery. */
3775 if (arc_lpcwidth != 0 && arc_must_save_register (LP_COUNT, cfun, true))
3777 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3778 emit_insn (gen_rtx_SET (reg0,
3779 gen_rtx_UNSPEC_VOLATILE
3780 (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_START)),
3781 VUNSPEC_ARC_LR)));
3782 frame_size_to_allocate -= push_reg (reg0);
3783 emit_insn (gen_rtx_SET (reg0,
3784 gen_rtx_UNSPEC_VOLATILE
3785 (Pmode, gen_rtvec (1, GEN_INT (AUX_LP_END)),
3786 VUNSPEC_ARC_LR)));
3787 frame_size_to_allocate -= push_reg (reg0);
3788 emit_move_insn (reg0, gen_rtx_REG (SImode, LP_COUNT));
3789 frame_size_to_allocate -= push_reg (reg0);
3792 /* Save AUX regs used by FPX machinery. */
3793 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
3794 cfun, TARGET_DPFP))
3796 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3797 int i;
3799 for (i = 0; i < 4; i++)
3801 emit_insn (gen_rtx_SET (reg0,
3802 gen_rtx_UNSPEC_VOLATILE
3803 (Pmode, gen_rtvec (1, GEN_INT (AUX_DPFP_START
3804 + i)),
3805 VUNSPEC_ARC_LR)));
3806 frame_size_to_allocate -= push_reg (reg0);
3810 /* Save accumulator registers. */
3811 if (arc_must_save_register (R58_REG, cfun, true))
3812 frame_size_to_allocate -= arc_save_callee_saves (3ULL << 58,
3813 false, false, 0, false);
3815 if (arc_frame_pointer_needed () && ARC_INTERRUPT_P (fn_type))
3817 /* Just save fp at the end of the saving context. */
3818 frame_size_to_allocate -=
3819 arc_save_callee_saves (0, false, !ARC_AUTOFP_IRQ_P (fn_type), 0, true);
3822 /* Allocate the stack frame. */
3823 if (frame_size_to_allocate > 0)
3824 frame_stack_add ((HOST_WIDE_INT) 0 - frame_size_to_allocate);
3826 /* Emit a blockage to avoid delay slot scheduling. */
3827 emit_insn (gen_blockage ());
3830 /* Return the register number of the register holding the return address
3831 for a function of type TYPE. */
3833 static int
3834 arc_return_address_register (unsigned int fn_type)
3836 int regno = 0;
3838 if (ARC_INTERRUPT_P (fn_type))
3840 if ((fn_type & (ARC_FUNCTION_ILINK1 | ARC_FUNCTION_FIRQ)) != 0)
3841 regno = ILINK1_REG;
3842 else if ((fn_type & ARC_FUNCTION_ILINK2) != 0)
3843 regno = ILINK2_REG;
3844 else
3845 gcc_unreachable ();
3847 else if (ARC_NORMAL_P (fn_type) || ARC_NAKED_P (fn_type))
3848 regno = RETURN_ADDR_REGNUM;
3850 gcc_assert (regno != 0);
3851 return regno;
3854 /* Do any necessary cleanup after a function to restore stack, frame,
3855 and regs. */
3857 void
3858 arc_expand_epilogue (int sibcall_p)
3860 int size;
3861 unsigned int fn_type = arc_compute_function_type (cfun);
3862 unsigned int size_to_deallocate;
3863 int restored;
3864 int can_trust_sp_p = !cfun->calls_alloca;
3865 int first_offset;
3866 bool restore_fp = arc_frame_pointer_needed () && !ARC_AUTOFP_IRQ_P (fn_type);
3867 bool restore_blink = arc_must_save_return_addr (cfun)
3868 && !ARC_AUTOBLINK_IRQ_P (fn_type);
3869 uint64_t gmask = cfun->machine->frame_info.gmask;
3870 bool return_p = !sibcall_p && fn_type == ARC_FUNCTION_NORMAL
3871 && !cfun->machine->frame_info.pretend_size;
3872 struct arc_frame_info *frame = &cfun->machine->frame_info;
3874 /* Naked functions don't have epilogue. */
3875 if (ARC_NAKED_P (fn_type))
3876 return;
3878 size = arc_compute_frame_size ();
3879 size_to_deallocate = size;
3881 first_offset = size - (frame->pretend_size + frame->reg_size
3882 + frame->extra_size);
3884 if (!can_trust_sp_p)
3885 gcc_assert (arc_frame_pointer_needed ());
3887 /* Emit a blockage to avoid/flush all pending sp operations. */
3888 if (size)
3889 emit_insn (gen_blockage ());
3891 if (ARC_INTERRUPT_P (fn_type))
3893 /* We need to restore FP before any SP operation in an
3894 interrupt. */
3895 size_to_deallocate -= arc_restore_callee_saves (0, false,
3896 restore_fp,
3897 first_offset,
3898 size_to_deallocate);
3899 restore_fp = false;
3900 first_offset = 0;
3903 /* Restore accumulator registers. */
3904 if (arc_must_save_register (R58_REG, cfun, true))
3906 rtx insn;
3907 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3908 rtx reg1 = gen_rtx_REG (SImode, R1_REG);
3909 size_to_deallocate -= pop_reg (reg0);
3910 size_to_deallocate -= pop_reg (reg1);
3912 insn = emit_insn (gen_mulu64 (reg0, const1_rtx));
3913 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, R58_REG));
3914 RTX_FRAME_RELATED_P (insn) = 1;
3915 emit_insn (gen_arc600_stall ());
3916 insn = emit_insn (gen_rtx_UNSPEC_VOLATILE
3917 (VOIDmode, gen_rtvec (2, reg1, GEN_INT (AUX_MULHI)),
3918 VUNSPEC_ARC_SR));
3919 add_reg_note (insn, REG_CFA_RESTORE, gen_rtx_REG (SImode, R59_REG));
3920 RTX_FRAME_RELATED_P (insn) = 1;
3923 /* Restore AUX-regs used by FPX machinery. */
3924 if (arc_must_save_register (TARGET_BIG_ENDIAN ? R41_REG : R40_REG,
3925 cfun, TARGET_DPFP))
3927 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3928 int i;
3930 for (i = 0; i < 4; i++)
3932 size_to_deallocate -= pop_reg (reg0);
3933 emit_insn (gen_rtx_UNSPEC_VOLATILE
3934 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_DPFP_START
3935 + i)),
3936 VUNSPEC_ARC_SR));
3940 /* Check if we need to restore the ZOL machinery. */
3941 if (arc_lpcwidth !=0 && arc_must_save_register (LP_COUNT, cfun, true))
3943 rtx reg0 = gen_rtx_REG (SImode, R0_REG);
3945 size_to_deallocate -= pop_reg (reg0);
3946 emit_move_insn (gen_rtx_REG (SImode, LP_COUNT), reg0);
3948 size_to_deallocate -= pop_reg (reg0);
3949 emit_insn (gen_rtx_UNSPEC_VOLATILE
3950 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_END)),
3951 VUNSPEC_ARC_SR));
3953 size_to_deallocate -= pop_reg (reg0);
3954 emit_insn (gen_rtx_UNSPEC_VOLATILE
3955 (VOIDmode, gen_rtvec (2, reg0, GEN_INT (AUX_LP_START)),
3956 VUNSPEC_ARC_SR));
3959 if (TARGET_CODE_DENSITY
3960 && TARGET_CODE_DENSITY_FRAME
3961 && !ARC_AUTOFP_IRQ_P (fn_type)
3962 && !ARC_AUTOBLINK_IRQ_P (fn_type)
3963 && !ARC_INTERRUPT_P (fn_type)
3964 && arc_enter_leave_p (gmask))
3966 /* Using leave instruction. */
3967 size_to_deallocate -= arc_restore_callee_leave (gmask, restore_blink,
3968 restore_fp,
3969 return_p,
3970 first_offset);
3971 if (return_p)
3973 gcc_assert (size_to_deallocate == 0);
3974 return;
3977 else if (frame->millicode_end_reg > 14)
3979 /* Using millicode calls. */
3980 size_to_deallocate -= arc_restore_callee_milli (gmask, restore_blink,
3981 restore_fp,
3982 return_p,
3983 first_offset);
3984 if (return_p)
3986 gcc_assert (size_to_deallocate == 0);
3987 return;
3990 else
3991 size_to_deallocate -= arc_restore_callee_saves (gmask, restore_blink,
3992 restore_fp,
3993 first_offset,
3994 size_to_deallocate);
3996 /* Keep track of how much of the stack pointer we've restored. It
3997 makes the following a lot more readable. */
3998 restored = size - size_to_deallocate;
4000 if (size > restored)
4001 frame_stack_add (size - restored);
4003 /* For frames that use __builtin_eh_return, the register defined by
4004 EH_RETURN_STACKADJ_RTX is set to 0 for all standard return paths.
4005 On eh_return paths however, the register is set to the value that
4006 should be added to the stack pointer in order to restore the
4007 correct stack pointer for the exception handling frame.
4009 For ARC we are going to use r2 for EH_RETURN_STACKADJ_RTX, add
4010 this onto the stack for eh_return frames. */
4011 if (crtl->calls_eh_return)
4012 emit_insn (gen_add2_insn (stack_pointer_rtx,
4013 EH_RETURN_STACKADJ_RTX));
4015 /* Emit the return instruction. */
4016 if (ARC_INTERRUPT_P (fn_type))
4018 rtx ra = gen_rtx_REG (Pmode, arc_return_address_register (fn_type));
4020 if (TARGET_V2)
4021 emit_jump_insn (gen_rtie ());
4022 else if (TARGET_ARC700)
4023 emit_jump_insn (gen_rtie ());
4024 else
4025 emit_jump_insn (gen_arc600_rtie (ra));
4027 else if (sibcall_p == FALSE)
4028 emit_jump_insn (gen_simple_return ());
4031 /* Helper for {push/pop}_multi_operand: check if rtx OP is a suitable
4032 construct to match either enter or leave instruction. Which one
4033 which is selected by PUSH_P argument. */
4035 bool
4036 arc_check_multi (rtx op, bool push_p)
4038 HOST_WIDE_INT len = XVECLEN (op, 0);
4039 unsigned int regno, i, start;
4040 unsigned int memp = push_p ? 0 : 1;
4041 rtx elt;
4043 if (len <= 1)
4044 return false;
4046 start = 1;
4047 elt = XVECEXP (op, 0, 0);
4048 if (!push_p && GET_CODE (elt) == RETURN)
4049 start = 2;
4051 for (i = start, regno = ENTER_LEAVE_START_REG; i < len; i++, regno++)
4053 rtx elt = XVECEXP (op, 0, i);
4054 rtx reg, mem, addr;
4056 if (GET_CODE (elt) != SET)
4057 return false;
4058 mem = XEXP (elt, memp);
4059 reg = XEXP (elt, 1 - memp);
4061 if (!REG_P (reg)
4062 || !MEM_P (mem))
4063 return false;
4065 /* Check for blink. */
4066 if (REGNO (reg) == RETURN_ADDR_REGNUM
4067 && i == start)
4068 regno = 12;
4069 else if (REGNO (reg) == HARD_FRAME_POINTER_REGNUM)
4070 ++i;
4071 else if (REGNO (reg) != regno)
4072 return false;
4074 addr = XEXP (mem, 0);
4075 if (GET_CODE (addr) == PLUS)
4077 if (!rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
4078 || !CONST_INT_P (XEXP (addr, 1)))
4079 return false;
4081 else
4083 if (!rtx_equal_p (stack_pointer_rtx, addr))
4084 return false;
4087 return true;
4090 /* Return rtx for the location of the return address on the stack,
4091 suitable for use in __builtin_eh_return. The new return address
4092 will be written to this location in order to redirect the return to
4093 the exception handler. Our ABI says the blink is pushed first on
4094 stack followed by an unknown number of register saves, and finally
4095 by fp. Hence we cannot use the EH_RETURN_ADDRESS macro as the
4096 stack is not finalized. */
4098 void
4099 arc_eh_return_address_location (rtx source)
4101 rtx mem;
4102 int offset;
4103 struct arc_frame_info *afi;
4105 arc_compute_frame_size ();
4106 afi = &cfun->machine->frame_info;
4108 gcc_assert (crtl->calls_eh_return);
4109 gcc_assert (afi->save_return_addr);
4110 gcc_assert (afi->extra_size >= 4);
4112 /* The '-4' removes the size of the return address, which is
4113 included in the 'extra_size' field. */
4114 offset = afi->reg_size + afi->extra_size - 4;
4115 mem = gen_frame_mem (Pmode,
4116 plus_constant (Pmode, hard_frame_pointer_rtx, offset));
4118 /* The following should not be needed, and is, really a hack. The
4119 issue being worked around here is that the DSE (Dead Store
4120 Elimination) pass will remove this write to the stack as it sees
4121 a single store and no corresponding read. The read however
4122 occurs in the epilogue code, which is not added into the function
4123 rtl until a later pass. So, at the time of DSE, the decision to
4124 remove this store seems perfectly sensible. Marking the memory
4125 address as volatile obviously has the effect of preventing DSE
4126 from removing the store. */
4127 MEM_VOLATILE_P (mem) = true;
4128 emit_move_insn (mem, source);
4131 /* PIC */
4133 /* Helper to generate unspec constant. */
4135 static rtx
4136 arc_unspec_offset (rtx loc, int unspec)
4138 return gen_rtx_CONST (Pmode, gen_rtx_UNSPEC (Pmode, gen_rtvec (1, loc),
4139 unspec));
4142 /* Predicate for pre-reload splitters with associated instructions,
4143 which can match any time before the split1 pass (usually combine),
4144 then are unconditionally split in that pass and should not be
4145 matched again afterwards. */
4147 bool
4148 arc_pre_reload_split (void)
4150 return (can_create_pseudo_p ()
4151 && !(cfun->curr_properties & PROP_rtl_split_insns));
4154 /* Output the assembler code for a zero-overhead loop doing a shift
4155 or rotate. We know OPERANDS[0] == OPERANDS[1], and the bit count
4156 is OPERANDS[2]. */
4158 const char *
4159 output_shift_loop (enum rtx_code code, rtx *operands)
4161 bool twice_p = false;
4162 gcc_assert (GET_MODE (operands[0]) == SImode);
4164 if (GET_CODE (operands[2]) != CONST_INT)
4166 output_asm_insn ("and.f\tlp_count,%2,0x1f", operands);
4167 output_asm_insn ("lpnz\t2f", operands);
4169 else
4171 int n = INTVAL (operands[2]) & 31;
4172 if (!n)
4174 output_asm_insn ("mov\t%0,%1",operands);
4175 return "";
4178 if ((n & 1) == 0 && code != ROTATE)
4180 twice_p = true;
4181 n >>= 1;
4183 operands[2] = GEN_INT (n);
4184 output_asm_insn ("mov\tlp_count,%2", operands);
4185 output_asm_insn ("lp\t2f", operands);
4188 switch (code)
4190 case ASHIFT:
4191 output_asm_insn ("add\t%0,%1,%1", operands);
4192 if (twice_p)
4193 output_asm_insn ("add\t%0,%1,%1", operands);
4194 break;
4195 case ASHIFTRT:
4196 output_asm_insn ("asr\t%0,%1", operands);
4197 if (twice_p)
4198 output_asm_insn ("asr\t%0,%1", operands);
4199 break;
4200 case LSHIFTRT:
4201 output_asm_insn ("lsr\t%0,%1", operands);
4202 if (twice_p)
4203 output_asm_insn ("lsr\t%0,%1", operands);
4204 break;
4205 case ROTATERT:
4206 output_asm_insn ("ror\t%0,%1", operands);
4207 if (twice_p)
4208 output_asm_insn ("ror\t%0,%1", operands);
4209 break;
4210 case ROTATE:
4211 output_asm_insn ("add.f\t%0,%1,%1", operands);
4212 output_asm_insn ("adc\t%0,%0,0", operands);
4213 twice_p = true;
4214 break;
4215 default:
4216 gcc_unreachable ();
4219 if (!twice_p)
4220 output_asm_insn ("nop", operands);
4221 fprintf (asm_out_file, "2:\t%s end single insn loop\n", ASM_COMMENT_START);
4222 return "";
4225 /* See below where shifts are handled for explanation of this enum. */
4226 enum arc_shift_alg
4228 SHIFT_MOVE, /* Register-to-register move. */
4229 SHIFT_LOOP, /* Zero-overhead loop implementation. */
4230 SHIFT_INLINE, /* Mmultiple LSHIFTs and LSHIFT-PLUSs. */
4231 SHIFT_AND_ROT, /* Bitwise AND, then ROTATERTs. */
4232 SHIFT_SWAP, /* SWAP then multiple LSHIFTs/LSHIFT-PLUSs. */
4233 SHIFT_AND_SWAP_ROT /* Bitwise AND, then SWAP, then ROTATERTs. */
4236 struct arc_shift_info {
4237 enum arc_shift_alg alg;
4238 unsigned int cost;
4241 /* Return shift algorithm context, an index into the following tables.
4242 * 0 for -Os (optimize for size) 3 for -O2 (optimized for speed)
4243 * 1 for -Os -mswap TARGET_V2 4 for -O2 -mswap TARGET_V2
4244 * 2 for -Os -mswap !TARGET_V2 5 for -O2 -mswap !TARGET_V2 */
4245 static unsigned int
4246 arc_shift_context_idx ()
4248 if (optimize_function_for_size_p (cfun))
4250 if (!TARGET_SWAP)
4251 return 0;
4252 if (TARGET_V2)
4253 return 1;
4254 return 2;
4256 else
4258 if (!TARGET_SWAP)
4259 return 3;
4260 if (TARGET_V2)
4261 return 4;
4262 return 5;
4266 static const arc_shift_info arc_ashl_alg[6][32] = {
4267 { /* 0: -Os. */
4268 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4269 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4270 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4271 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4272 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4273 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4274 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4275 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4276 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4277 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4278 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 10 */
4279 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 11 */
4280 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 12 */
4281 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 13 */
4282 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 14 */
4283 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 15 */
4284 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 16 */
4285 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 17 */
4286 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 18 */
4287 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 19 */
4288 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 20 */
4289 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 21 */
4290 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 22 */
4291 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 23 */
4292 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 24 */
4293 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 25 */
4294 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 26 */
4295 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 27 */
4296 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 28 */
4297 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4298 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4299 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4301 { /* 1: -Os -mswap TARGET_V2. */
4302 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4303 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4304 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4305 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4306 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4307 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4308 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4309 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4310 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4311 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4312 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 10 */
4313 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 11 */
4314 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 12 */
4315 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 13 */
4316 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4317 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4318 { SHIFT_SWAP, COSTS_N_INSNS (1) }, /* 16 */
4319 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 17 */
4320 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 18 */
4321 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 19 */
4322 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 20 */
4323 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 21 */
4324 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 22 */
4325 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 23 */
4326 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 24 */
4327 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 25 */
4328 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 26 */
4329 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 27 */
4330 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 28 */
4331 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4332 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4333 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4335 { /* 2: -Os -mswap !TARGET_V2. */
4336 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4337 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4338 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4339 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4340 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4341 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4342 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4343 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4344 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4345 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4346 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 10 */
4347 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 11 */
4348 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 12 */
4349 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 13 */
4350 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4351 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4352 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 16 */
4353 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 17 */
4354 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 18 */
4355 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 19 */
4356 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 20 */
4357 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 21 */
4358 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 22 */
4359 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 23 */
4360 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 24 */
4361 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 25 */
4362 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 26 */
4363 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 27 */
4364 { SHIFT_LOOP, COSTS_N_INSNS (4) }, /* 28 */
4365 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4366 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4367 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4369 { /* 3: -O2. */
4370 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4371 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4372 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4373 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4374 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4375 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4376 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4377 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4378 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4379 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4380 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 10 */
4381 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 11 */
4382 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 12 */
4383 { SHIFT_INLINE, COSTS_N_INSNS (6) }, /* 13 */
4384 { SHIFT_INLINE, COSTS_N_INSNS (6) }, /* 14 */
4385 { SHIFT_INLINE, COSTS_N_INSNS (6) }, /* 15 */
4386 { SHIFT_INLINE, COSTS_N_INSNS (7) }, /* 16 */
4387 { SHIFT_INLINE, COSTS_N_INSNS (7) }, /* 17 */
4388 { SHIFT_INLINE, COSTS_N_INSNS (7) }, /* 18 */
4389 { SHIFT_INLINE, COSTS_N_INSNS (8) }, /* 19 */
4390 { SHIFT_INLINE, COSTS_N_INSNS (8) }, /* 20 */
4391 { SHIFT_INLINE, COSTS_N_INSNS (8) }, /* 21 */
4392 { SHIFT_INLINE, COSTS_N_INSNS (9) }, /* 22 */
4393 { SHIFT_INLINE, COSTS_N_INSNS (9) }, /* 23 */
4394 { SHIFT_AND_ROT, COSTS_N_INSNS (9) }, /* 24 */
4395 { SHIFT_AND_ROT, COSTS_N_INSNS (8) }, /* 25 */
4396 { SHIFT_AND_ROT, COSTS_N_INSNS (7) }, /* 26 */
4397 { SHIFT_AND_ROT, COSTS_N_INSNS (6) }, /* 27 */
4398 { SHIFT_AND_ROT, COSTS_N_INSNS (5) }, /* 28 */
4399 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4400 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4401 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4403 { /* 4: -O2 -mswap TARGET_V2. */
4404 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4405 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4406 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4407 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4408 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4409 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4410 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4411 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4412 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4413 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4414 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 10 */
4415 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 11 */
4416 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 12 */
4417 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (5) }, /* 13 */
4418 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4419 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4420 { SHIFT_SWAP, COSTS_N_INSNS (1) }, /* 16 */
4421 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 17 */
4422 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 18 */
4423 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 19 */
4424 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 20 */
4425 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 21 */
4426 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 22 */
4427 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 23 */
4428 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 24 */
4429 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 25 */
4430 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 26 */
4431 { SHIFT_AND_ROT, COSTS_N_INSNS (6) }, /* 27 */
4432 { SHIFT_AND_ROT, COSTS_N_INSNS (5) }, /* 28 */
4433 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4434 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4435 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4437 { /* 5: -O2 -mswap !TARGET_V2. */
4438 { SHIFT_MOVE, COSTS_N_INSNS (1) }, /* 0 */
4439 { SHIFT_INLINE, COSTS_N_INSNS (1) }, /* 1 */
4440 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 2 */
4441 { SHIFT_INLINE, COSTS_N_INSNS (2) }, /* 3 */
4442 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 4 */
4443 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 5 */
4444 { SHIFT_INLINE, COSTS_N_INSNS (3) }, /* 6 */
4445 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 7 */
4446 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 8 */
4447 { SHIFT_INLINE, COSTS_N_INSNS (4) }, /* 9 */
4448 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 10 */
4449 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 11 */
4450 { SHIFT_INLINE, COSTS_N_INSNS (5) }, /* 12 */
4451 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (5) }, /* 13 */
4452 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (4) }, /* 14 */
4453 { SHIFT_AND_SWAP_ROT, COSTS_N_INSNS (3) }, /* 15 */
4454 { SHIFT_SWAP, COSTS_N_INSNS (2) }, /* 16 */
4455 { SHIFT_SWAP, COSTS_N_INSNS (3) }, /* 17 */
4456 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 18 */
4457 { SHIFT_SWAP, COSTS_N_INSNS (4) }, /* 19 */
4458 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 20 */
4459 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 21 */
4460 { SHIFT_SWAP, COSTS_N_INSNS (5) }, /* 22 */
4461 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 23 */
4462 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 24 */
4463 { SHIFT_SWAP, COSTS_N_INSNS (6) }, /* 25 */
4464 { SHIFT_AND_ROT, COSTS_N_INSNS (7) }, /* 26 */
4465 { SHIFT_AND_ROT, COSTS_N_INSNS (6) }, /* 27 */
4466 { SHIFT_AND_ROT, COSTS_N_INSNS (5) }, /* 28 */
4467 { SHIFT_AND_ROT, COSTS_N_INSNS (4) }, /* 29 */
4468 { SHIFT_AND_ROT, COSTS_N_INSNS (3) }, /* 30 */
4469 { SHIFT_AND_ROT, COSTS_N_INSNS (2) } /* 31 */
4473 /* Split SImode left shift instruction. */
4474 void
4475 arc_split_ashl (rtx *operands)
4477 if (CONST_INT_P (operands[2]))
4479 int n = INTVAL (operands[2]) & 0x1f;
4480 switch (arc_ashl_alg [arc_shift_context_idx ()][n].alg)
4482 case SHIFT_MOVE:
4483 emit_move_insn (operands[0], operands[1]);
4484 return;
4486 case SHIFT_SWAP:
4487 if (!TARGET_V2)
4489 emit_insn (gen_andsi3_i (operands[0], operands[1],
4490 GEN_INT (0xffff)));
4491 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[0]));
4493 else
4494 emit_insn (gen_ashlsi2_cnt16 (operands[0], operands[1]));
4495 n -= 16;
4496 if (n == 0)
4497 return;
4498 operands[1] = operands[0];
4499 /* FALL THRU */
4501 case SHIFT_INLINE:
4502 if (n <= 2)
4504 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[1]));
4505 if (n == 2)
4506 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
4508 else
4510 rtx zero = gen_reg_rtx (SImode);
4511 emit_move_insn (zero, const0_rtx);
4512 emit_insn (gen_add_shift (operands[0], operands[1],
4513 GEN_INT (3), zero));
4514 for (n -= 3; n >= 3; n -= 3)
4515 emit_insn (gen_add_shift (operands[0], operands[0],
4516 GEN_INT (3), zero));
4517 if (n == 2)
4518 emit_insn (gen_add_shift (operands[0], operands[0],
4519 const2_rtx, zero));
4520 else if (n)
4521 emit_insn (gen_ashlsi3_cnt1 (operands[0], operands[0]));
4523 return;
4525 case SHIFT_AND_ROT:
4526 emit_insn (gen_andsi3_i (operands[0], operands[1],
4527 GEN_INT ((1 << (32 - n)) - 1)));
4528 for (; n < 32; n++)
4529 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4530 return;
4532 case SHIFT_AND_SWAP_ROT:
4533 emit_insn (gen_andsi3_i (operands[0], operands[1],
4534 GEN_INT ((1 << (32 - n)) - 1)));
4535 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[0]));
4536 for (; n < 16; n++)
4537 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4538 return;
4540 case SHIFT_LOOP:
4541 break;
4543 default:
4544 gcc_unreachable ();
4548 emit_insn (gen_ashlsi3_loop (operands[0], operands[1], operands[2]));
4551 /* Split SImode arithmetic right shift instruction. */
4552 void
4553 arc_split_ashr (rtx *operands)
4555 if (CONST_INT_P (operands[2]))
4557 int n = INTVAL (operands[2]) & 0x1f;
4558 if (n <= 4)
4560 if (n != 0)
4562 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[1]));
4563 while (--n > 0)
4564 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
4566 else
4567 emit_move_insn (operands[0], operands[1]);
4568 return;
4570 else if (n >= 16 && n <= 18 && TARGET_SWAP)
4572 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4573 emit_insn (gen_extendhisi2 (operands[0],
4574 gen_lowpart (HImode, operands[0])));
4575 while (--n >= 16)
4576 emit_insn (gen_ashrsi3_cnt1 (operands[0], operands[0]));
4577 return;
4579 else if (n == 30)
4581 rtx tmp = gen_reg_rtx (SImode);
4582 emit_insn (gen_add_f (tmp, operands[1], operands[1]));
4583 emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
4584 emit_insn (gen_addsi_compare_2 (tmp, tmp));
4585 emit_insn (gen_adc (operands[0], operands[0], operands[0]));
4586 return;
4588 else if (n == 31)
4590 emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
4591 emit_insn (gen_sbc (operands[0], operands[0], operands[0]));
4592 return;
4596 emit_insn (gen_ashrsi3_loop (operands[0], operands[1], operands[2]));
4599 /* Split SImode logical right shift instruction. */
4600 void
4601 arc_split_lshr (rtx *operands)
4603 if (CONST_INT_P (operands[2]))
4605 int n = INTVAL (operands[2]) & 0x1f;
4606 if (n <= 4)
4608 if (n != 0)
4610 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[1]));
4611 while (--n > 0)
4612 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
4614 else
4615 emit_move_insn (operands[0], operands[1]);
4616 return;
4618 else if (n >= 16 && n <= 19 && TARGET_SWAP && TARGET_V2)
4620 emit_insn (gen_lshrsi2_cnt16 (operands[0], operands[1]));
4621 while (--n >= 16)
4622 emit_insn (gen_lshrsi3_cnt1 (operands[0], operands[0]));
4623 return;
4625 else if (n == 30)
4627 rtx tmp = gen_reg_rtx (SImode);
4628 emit_insn (gen_add_f (tmp, operands[1], operands[1]));
4629 emit_insn (gen_scc_ltu_cc_c (operands[0]));
4630 emit_insn (gen_addsi_compare_2 (tmp, tmp));
4631 emit_insn (gen_adc (operands[0], operands[0], operands[0]));
4632 return;
4634 else if (n == 31)
4636 emit_insn (gen_addsi_compare_2 (operands[1], operands[1]));
4637 emit_insn (gen_scc_ltu_cc_c (operands[0]));
4638 return;
4642 emit_insn (gen_lshrsi3_loop (operands[0], operands[1], operands[2]));
4645 /* Split SImode rotate left instruction. */
4646 void
4647 arc_split_rotl (rtx *operands)
4649 if (CONST_INT_P (operands[2]))
4651 int n = INTVAL (operands[2]) & 0x1f;
4652 if (n <= 2)
4654 if (n != 0)
4656 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
4657 if (n == 2)
4658 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4660 else
4661 emit_move_insn (operands[0], operands[1]);
4662 return;
4664 else if (n >= 28)
4666 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
4667 while (++n < 32)
4668 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4669 return;
4671 else if (n >= 13 && n <= 16 && TARGET_SWAP)
4673 emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
4674 while (++n <= 16)
4675 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4676 return;
4678 else if (n == 17 && TARGET_SWAP)
4680 emit_insn (gen_rotlsi2_cnt16 (operands[0], operands[1]));
4681 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4682 return;
4684 else if (n >= 16 || n == 12 || n == 14)
4686 emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
4687 GEN_INT (32 - n)));
4688 return;
4692 emit_insn (gen_rotlsi3_loop (operands[0], operands[1], operands[2]));
4695 /* Split SImode rotate right instruction. */
4696 void
4697 arc_split_rotr (rtx *operands)
4699 if (CONST_INT_P (operands[2]))
4701 int n = INTVAL (operands[2]) & 0x1f;
4702 if (n <= 4)
4704 if (n != 0)
4706 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[1]));
4707 while (--n > 0)
4708 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4710 else
4711 emit_move_insn (operands[0], operands[1]);
4712 return;
4714 else if (n == 15 && TARGET_SWAP)
4716 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4717 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[0]));
4718 return;
4720 else if (n >= 16 && n <= 19 && TARGET_SWAP)
4722 emit_insn (gen_rotrsi2_cnt16 (operands[0], operands[1]));
4723 while (--n >= 16)
4724 emit_insn (gen_rotrsi3_cnt1 (operands[0], operands[0]));
4725 return;
4727 else if (n >= 30)
4729 emit_insn (gen_rotlsi3_cnt1 (operands[0], operands[1]));
4730 if (n == 31)
4731 emit_insn (gen_rotlsi3_cnt1 (operands[1], operands[1]));
4732 return;
4734 else if (n >= 21 || n == 17 || n == 19)
4736 emit_insn (gen_rotrsi3_loop (operands[0], operands[1],
4737 GEN_INT (32 - n)));
4738 return;
4742 emit_insn (gen_rotrsi3_loop (operands[0], operands[1], operands[2]));
4745 /* Nested function support. */
4747 /* Output assembler code for a block containing the constant parts of
4748 a trampoline, leaving space for variable parts. A trampoline looks
4749 like this:
4751 ld_s r12,[pcl,8]
4752 ld r11,[pcl,12]
4753 j_s [r12]
4754 .word function's address
4755 .word static chain value
4759 static void
4760 arc_asm_trampoline_template (FILE *f)
4762 asm_fprintf (f, "\tld_s\t%s,[pcl,8]\n", ARC_TEMP_SCRATCH_REG);
4763 asm_fprintf (f, "\tld\t%s,[pcl,12]\n", reg_names[STATIC_CHAIN_REGNUM]);
4764 asm_fprintf (f, "\tj_s\t[%s]\n", ARC_TEMP_SCRATCH_REG);
4765 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4766 assemble_aligned_integer (UNITS_PER_WORD, const0_rtx);
4769 /* Emit RTL insns to initialize the variable parts of a trampoline.
4770 FNADDR is an RTX for the address of the function's pure code. CXT
4771 is an RTX for the static chain value for the function.
4773 The fastest trampoline to execute for trampolines within +-8KB of CTX
4774 would be:
4776 add2 r11,pcl,s12
4777 j [limm] 0x20200f80 limm
4779 and that would also be faster to write to the stack by computing
4780 the offset from CTX to TRAMP at compile time. However, it would
4781 really be better to get rid of the high cost of cache invalidation
4782 when generating trampolines, which requires that the code part of
4783 trampolines stays constant, and additionally either making sure
4784 that no executable code but trampolines is on the stack, no icache
4785 entries linger for the area of the stack from when before the stack
4786 was allocated, and allocating trampolines in trampoline-only cache
4787 lines or allocate trampolines fram a special pool of pre-allocated
4788 trampolines. */
4790 static void
4791 arc_initialize_trampoline (rtx tramp, tree fndecl, rtx cxt)
4793 rtx fnaddr = XEXP (DECL_RTL (fndecl), 0);
4795 emit_block_move (tramp, assemble_trampoline_template (),
4796 GEN_INT (TRAMPOLINE_SIZE), BLOCK_OP_NORMAL);
4797 emit_move_insn (adjust_address (tramp, SImode, 8), fnaddr);
4798 emit_move_insn (adjust_address (tramp, SImode, 12), cxt);
4799 maybe_emit_call_builtin___clear_cache (XEXP (tramp, 0),
4800 plus_constant (Pmode,
4801 XEXP (tramp, 0),
4802 TRAMPOLINE_SIZE));
4805 /* Add the given function declaration to emit code in JLI section. */
4807 static void
4808 arc_add_jli_section (rtx pat)
4810 const char *name;
4811 tree attrs;
4812 arc_jli_section *sec = arc_jli_sections, *new_section;
4813 tree decl = SYMBOL_REF_DECL (pat);
4815 if (!pat)
4816 return;
4818 if (decl)
4820 /* For fixed locations do not generate the jli table entry. It
4821 should be provided by the user as an asm file. */
4822 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
4823 if (lookup_attribute ("jli_fixed", attrs))
4824 return;
4827 name = XSTR (pat, 0);
4829 /* Don't insert the same symbol twice. */
4830 while (sec != NULL)
4832 if(strcmp (name, sec->name) == 0)
4833 return;
4834 sec = sec->next;
4837 /* New name, insert it. */
4838 new_section = (arc_jli_section *) xmalloc (sizeof (arc_jli_section));
4839 gcc_assert (new_section != NULL);
4840 new_section->name = name;
4841 new_section->next = arc_jli_sections;
4842 arc_jli_sections = new_section;
4845 /* This is set briefly to 1 when we output a ".as" address modifer, and then
4846 reset when we output the scaled address. */
4847 static int output_scaled = 0;
4849 /* Set when we force sdata output. */
4850 static int output_sdata = 0;
4852 /* Print operand X (an rtx) in assembler syntax to file FILE.
4853 CODE is a letter or dot (`z' in `%z0') or 0 if no letter was specified.
4854 For `%' followed by punctuation, CODE is the punctuation and X is null.
4855 In final.cc:output_asm_insn:
4856 'l' : label
4857 'a' : address
4858 'c' : constant address if CONSTANT_ADDRESS_P
4859 'n' : negative
4860 Here:
4861 'Z': log2(x+1)-1
4862 'z': log2
4863 'M': log2(~x)
4864 'p': bit Position of lsb
4865 's': scalled immediate
4866 'S': Scalled immediate, to be used in pair with 's'.
4867 'N': Negative immediate, to be used in pair with 's'.
4868 'x': size of bit field
4869 '*': jump delay slot suffix
4870 '?' : nonjump-insn suffix for conditional execution or short instruction
4873 'R': Second word
4874 'J': JLI instruction
4875 'j': used by mov instruction to properly emit jli related labels.
4876 'B': Branch comparison operand - suppress sda reference
4877 'H': Most significant word
4878 'L': Least significant word
4879 'A': ASCII decimal representation of floating point value
4880 'U': Load/store update or scaling indicator
4881 'V': cache bypass indicator for volatile
4884 'O': Operator
4885 'o': original symbol - no @ prepending. */
4887 void
4888 arc_print_operand (FILE *file, rtx x, int code)
4890 HOST_WIDE_INT ival;
4891 unsigned scalled = 0;
4892 int sign = 1;
4894 switch (code)
4896 case 'Z':
4897 if (GET_CODE (x) == CONST_INT)
4898 fprintf (file, "%d",exact_log2(INTVAL (x) + 1) - 1 );
4899 else
4900 output_operand_lossage ("invalid operand to %%Z code");
4902 return;
4904 case 'z':
4905 if (GET_CODE (x) == CONST_INT)
4906 fprintf (file, "%d",exact_log2 (INTVAL (x) & 0xffffffff));
4907 else
4908 output_operand_lossage ("invalid operand to %%z code");
4910 return;
4912 case 'c':
4913 if (GET_CODE (x) == CONST_INT)
4914 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x) );
4915 else
4916 output_operand_lossage ("invalid operands to %%c code");
4918 return;
4920 case 'M':
4921 if (GET_CODE (x) == CONST_INT)
4922 fprintf (file, "%d",exact_log2(~INTVAL (x)) );
4923 else
4924 output_operand_lossage ("invalid operand to %%M code");
4926 return;
4928 case 'p':
4929 if (GET_CODE (x) == CONST_INT)
4930 fprintf (file, "%d", exact_log2 (INTVAL (x) & -INTVAL (x)));
4931 else
4932 output_operand_lossage ("invalid operand to %%p code");
4933 return;
4935 case 's':
4936 if (REG_P (x))
4937 return;
4938 if (!CONST_INT_P (x))
4940 output_operand_lossage ("invalid operand for %%s code");
4941 return;
4943 ival = INTVAL (x);
4944 if ((ival & 0x07) == 0)
4945 scalled = 3;
4946 else if ((ival & 0x03) == 0)
4947 scalled = 2;
4948 else if ((ival & 0x01) == 0)
4949 scalled = 1;
4951 if (scalled)
4952 asm_fprintf (file, "%d", scalled);
4953 return;
4955 case 'N':
4956 if (REG_P (x))
4958 output_operand_lossage ("invalid operand for %%N code");
4959 return;
4961 sign = -1;
4962 /* fall through */
4963 case 'S':
4964 if (REG_P (x))
4966 asm_fprintf (file, "%s", reg_names [REGNO (x)]);
4967 return;
4969 if (!CONST_INT_P (x))
4971 output_operand_lossage ("invalid operand for %%N or %%S code");
4972 return;
4974 ival = sign * INTVAL (x);
4975 if ((ival & 0x07) == 0)
4976 scalled = 3;
4977 else if ((ival & 0x03) == 0)
4978 scalled = 2;
4979 else if ((ival & 0x01) == 0)
4980 scalled = 1;
4982 asm_fprintf (file, "%wd", (ival >> scalled));
4983 return;
4985 case 'x':
4986 if (GET_CODE (x) == CONST_INT)
4988 HOST_WIDE_INT i = INTVAL (x);
4989 HOST_WIDE_INT s = exact_log2 (i & -i);
4990 fprintf (file, "%d", exact_log2 (((0xffffffffUL & i) >> s) + 1));
4992 else
4993 output_operand_lossage ("invalid operand to %%s code");
4994 return;
4996 case '*' :
4997 /* Unconditional branches / branches not depending on condition codes.
4998 This could also be a CALL_INSN.
4999 Output the appropriate delay slot suffix. */
5000 if (final_sequence && final_sequence->len () != 1)
5002 rtx_insn *delay = final_sequence->insn (1);
5004 /* For TARGET_PAD_RETURN we might have grabbed the delay insn. */
5005 if (delay->deleted ())
5006 return;
5007 fputs (".d", file);
5009 return;
5011 case '?' : /* with leading "." */
5012 case '!' : /* without leading "." */
5013 if (current_insn_predicate)
5015 int cc = get_arc_condition_code (current_insn_predicate);
5016 /* Is this insn in a delay slot sequence? */
5017 if (!final_sequence || XVECLEN (final_sequence, 0) < 2
5018 || current_insn_predicate
5019 || CALL_P (final_sequence->insn (0))
5020 || simplejump_p (final_sequence->insn (0)))
5022 /* This insn isn't in a delay slot sequence, or conditionalized
5023 independently of its position in a delay slot. */
5024 fprintf (file, "%s%s",
5025 code == '?' ? "." : "", arc_condition_codes[cc]);
5026 /* If this is a jump, there are still short variants. However,
5027 only beq_s / bne_s have the same offset range as b_s,
5028 and the only short conditional returns are jeq_s and jne_s. */
5029 if (code == '!'
5030 && (cc == ARC_CC_EQ || cc == ARC_CC_NE))
5031 output_short_suffix (file);
5033 else if (code == '!') /* Jump with delay slot. */
5034 fputs (arc_condition_codes[cc], file);
5035 else /* An Instruction in a delay slot of a jump or call. */
5037 rtx jump = XVECEXP (final_sequence, 0, 0);
5038 rtx insn = XVECEXP (final_sequence, 0, 1);
5040 /* If the insn is annulled and is from the target path, we need
5041 to inverse the condition test. */
5042 if (JUMP_P (jump) && INSN_ANNULLED_BRANCH_P (jump))
5044 if (INSN_FROM_TARGET_P (insn))
5045 fprintf (file, "%s%s",
5046 code == '?' ? "." : "",
5047 arc_condition_codes[ARC_INVERSE_CONDITION_CODE (cc)]);
5048 else
5049 fprintf (file, "%s%s",
5050 code == '?' ? "." : "",
5051 arc_condition_codes[cc]);
5053 else
5055 /* This insn is executed for either path, so don't
5056 conditionalize it at all. */
5057 output_short_suffix (file);
5061 else
5062 output_short_suffix (file);
5063 return;
5065 case 'd' :
5066 fputs (arc_condition_codes[get_arc_condition_code (x)], file);
5067 return;
5068 case 'D' :
5069 fputs (arc_condition_codes[ARC_INVERSE_CONDITION_CODE
5070 (get_arc_condition_code (x))],
5071 file);
5072 return;
5073 case 'R' :
5074 /* Write second word of DImode or DFmode reference,
5075 register or memory. */
5076 if (GET_CODE (x) == REG)
5077 fputs (reg_names[REGNO (x)+1], file);
5078 else if (GET_CODE (x) == MEM)
5080 fputc ('[', file);
5082 /* Handle possible auto-increment. For PRE_INC / PRE_DEC /
5083 PRE_MODIFY, we will have handled the first word already;
5084 For POST_INC / POST_DEC / POST_MODIFY, the access to the
5085 first word will be done later. In either case, the access
5086 to the first word will do the modify, and we only have
5087 to add an offset of four here. */
5088 if (GET_CODE (XEXP (x, 0)) == PRE_INC
5089 || GET_CODE (XEXP (x, 0)) == PRE_DEC
5090 || GET_CODE (XEXP (x, 0)) == PRE_MODIFY
5091 || GET_CODE (XEXP (x, 0)) == POST_INC
5092 || GET_CODE (XEXP (x, 0)) == POST_DEC
5093 || GET_CODE (XEXP (x, 0)) == POST_MODIFY)
5094 output_address (VOIDmode,
5095 plus_constant (Pmode, XEXP (XEXP (x, 0), 0), 4));
5096 else if (output_scaled)
5098 rtx addr = XEXP (x, 0);
5099 int size = GET_MODE_SIZE (GET_MODE (x));
5101 output_address (VOIDmode,
5102 plus_constant (Pmode, XEXP (addr, 0),
5103 ((INTVAL (XEXP (addr, 1)) + 4)
5104 >> (size == 2 ? 1 : 2))));
5105 output_scaled = 0;
5107 else
5108 output_address (VOIDmode,
5109 plus_constant (Pmode, XEXP (x, 0), 4));
5110 fputc (']', file);
5112 else
5113 output_operand_lossage ("invalid operand to %%R code");
5114 return;
5115 case 'j':
5116 case 'J' :
5117 if (GET_CODE (x) == SYMBOL_REF
5118 && arc_is_jli_call_p (x))
5120 if (SYMBOL_REF_DECL (x))
5122 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
5123 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
5124 : NULL_TREE);
5125 if (lookup_attribute ("jli_fixed", attrs))
5127 /* No special treatment for jli_fixed functions. */
5128 if (code == 'j')
5129 break;
5130 fprintf (file, HOST_WIDE_INT_PRINT_DEC "\t; @",
5131 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
5132 assemble_name (file, XSTR (x, 0));
5133 return;
5136 fprintf (file, "@__jli.");
5137 assemble_name (file, XSTR (x, 0));
5138 if (code == 'j')
5139 arc_add_jli_section (x);
5140 return;
5142 if (GET_CODE (x) == SYMBOL_REF
5143 && arc_is_secure_call_p (x))
5145 /* No special treatment for secure functions. */
5146 if (code == 'j' )
5147 break;
5148 tree attrs = (TREE_TYPE (SYMBOL_REF_DECL (x)) != error_mark_node
5149 ? TYPE_ATTRIBUTES (TREE_TYPE (SYMBOL_REF_DECL (x)))
5150 : NULL_TREE);
5151 fprintf (file, HOST_WIDE_INT_PRINT_DEC "\t; @",
5152 TREE_INT_CST_LOW (TREE_VALUE (TREE_VALUE (attrs))));
5153 assemble_name (file, XSTR (x, 0));
5154 return;
5156 break;
5157 case 'B' /* Branch or other LIMM ref - must not use sda references. */ :
5158 if (CONSTANT_P (x))
5160 output_addr_const (file, x);
5161 return;
5163 break;
5164 case 'H' :
5165 case 'L' :
5166 if (GET_CODE (x) == REG)
5168 /* L = least significant word, H = most significant word. */
5169 if ((WORDS_BIG_ENDIAN != 0) ^ (code == 'L'))
5170 fputs (reg_names[REGNO (x)], file);
5171 else
5172 fputs (reg_names[REGNO (x)+1], file);
5174 else if (GET_CODE (x) == CONST_INT
5175 || GET_CODE (x) == CONST_DOUBLE)
5177 rtx first, second, word;
5179 split_double (x, &first, &second);
5181 if((WORDS_BIG_ENDIAN) == 0)
5182 word = (code == 'L' ? first : second);
5183 else
5184 word = (code == 'L' ? second : first);
5186 fprintf (file, "0x%08" PRIx32, ((uint32_t) INTVAL (word)));
5188 else
5189 output_operand_lossage ("invalid operand to %%H/%%L code");
5190 return;
5191 case 'A' :
5193 char str[30];
5195 gcc_assert (GET_CODE (x) == CONST_DOUBLE
5196 && GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT);
5198 real_to_decimal (str, CONST_DOUBLE_REAL_VALUE (x), sizeof (str), 0, 1);
5199 fprintf (file, "%s", str);
5200 return;
5202 case 'U' :
5203 /* Output a load/store with update indicator if appropriate. */
5204 if (GET_CODE (x) == MEM)
5206 rtx addr = XEXP (x, 0);
5207 switch (GET_CODE (addr))
5209 case PRE_INC: case PRE_DEC: case PRE_MODIFY:
5210 fputs (".a", file); break;
5211 case POST_INC: case POST_DEC: case POST_MODIFY:
5212 fputs (".ab", file); break;
5213 case PLUS:
5214 /* Are we using a scaled index? */
5215 if (GET_CODE (XEXP (addr, 0)) == MULT)
5216 fputs (".as", file);
5217 /* Can we use a scaled offset? */
5218 else if (CONST_INT_P (XEXP (addr, 1))
5219 && GET_MODE_SIZE (GET_MODE (x)) > 1
5220 && (!(INTVAL (XEXP (addr, 1))
5221 & (GET_MODE_SIZE (GET_MODE (x)) - 1) & 3))
5222 /* Does it make a difference? */
5223 && !SMALL_INT_RANGE(INTVAL (XEXP (addr, 1)),
5224 GET_MODE_SIZE (GET_MODE (x)) - 2, 0))
5226 fputs (".as", file);
5227 output_scaled = 1;
5229 break;
5230 case SYMBOL_REF:
5231 case CONST:
5232 if (legitimate_small_data_address_p (addr, GET_MODE (x))
5233 && GET_MODE_SIZE (GET_MODE (x)) > 1)
5235 int align = get_symbol_alignment (addr);
5236 int mask = 0;
5237 switch (GET_MODE (x))
5239 case E_HImode:
5240 mask = 1;
5241 break;
5242 default:
5243 mask = 3;
5244 break;
5246 if (align && ((align & mask) == 0))
5247 fputs (".as", file);
5249 break;
5250 case REG:
5251 break;
5252 default:
5253 gcc_assert (CONSTANT_P (addr)); break;
5256 else
5257 output_operand_lossage ("invalid operand to %%U code");
5258 return;
5259 case 'V' :
5260 /* Output cache bypass indicator for a load/store insn. Volatile memory
5261 refs are defined to use the cache bypass mechanism. */
5262 if (GET_CODE (x) == MEM)
5264 if ((MEM_VOLATILE_P (x) && !TARGET_VOLATILE_CACHE_SET)
5265 || arc_is_uncached_mem_p (x))
5266 fputs (".di", file);
5268 else
5269 output_operand_lossage ("invalid operand to %%V code");
5270 return;
5271 /* plt code. */
5272 case 'P':
5273 case 0 :
5274 /* Do nothing special. */
5275 break;
5276 case 'F':
5277 fputs (reg_names[REGNO (x)]+1, file);
5278 return;
5280 case 'O':
5281 /* Output an operator. */
5282 switch (GET_CODE (x))
5284 case PLUS: fputs ("add", file); return;
5285 case SS_PLUS: fputs ("adds", file); return;
5286 case AND: fputs ("and", file); return;
5287 case IOR: fputs ("or", file); return;
5288 case XOR: fputs ("xor", file); return;
5289 case MINUS: fputs ("sub", file); return;
5290 case SS_MINUS: fputs ("subs", file); return;
5291 case ASHIFT: fputs ("asl", file); return;
5292 case ASHIFTRT: fputs ("asr", file); return;
5293 case LSHIFTRT: fputs ("lsr", file); return;
5294 case ROTATERT: fputs ("ror", file); return;
5295 case MULT: fputs ("mpy", file); return;
5296 case ABS: fputs ("abs", file); return; /* Unconditional. */
5297 case NEG: fputs ("neg", file); return;
5298 case SS_NEG: fputs ("negs", file); return;
5299 case NOT: fputs ("not", file); return; /* Unconditional. */
5300 case ZERO_EXTEND:
5301 fputs ("ext", file); /* bmsk allows predication. */
5302 goto size_suffix;
5303 case SIGN_EXTEND: /* Unconditional. */
5304 fputs ("sex", file);
5305 size_suffix:
5306 switch (GET_MODE (XEXP (x, 0)))
5308 case E_QImode: fputs ("b", file); return;
5309 case E_HImode: fputs ("w", file); return;
5310 default: break;
5312 break;
5313 case SS_TRUNCATE:
5314 if (GET_MODE (x) != HImode)
5315 break;
5316 fputs ("sat16", file);
5317 default: break;
5319 output_operand_lossage ("invalid operand to %%O code"); return;
5320 case 'o':
5321 if (GET_CODE (x) == SYMBOL_REF)
5323 assemble_name (file, XSTR (x, 0));
5324 return;
5326 break;
5328 case '+':
5329 if (TARGET_V2)
5330 fputs ("m", file);
5331 else
5332 fputs ("h", file);
5333 return;
5334 case '_':
5335 if (TARGET_V2)
5336 fputs ("h", file);
5337 else
5338 fputs ("w", file);
5339 return;
5340 default :
5341 /* Unknown flag. */
5342 output_operand_lossage ("invalid operand output code");
5345 switch (GET_CODE (x))
5347 case REG :
5348 fputs (reg_names[REGNO (x)], file);
5349 break;
5350 case MEM :
5352 rtx addr = XEXP (x, 0);
5353 int size = GET_MODE_SIZE (GET_MODE (x));
5355 if (legitimate_small_data_address_p (addr, GET_MODE (x)))
5356 output_sdata = 1;
5358 fputc ('[', file);
5360 switch (GET_CODE (addr))
5362 case PRE_INC: case POST_INC:
5363 output_address (VOIDmode,
5364 plus_constant (Pmode, XEXP (addr, 0), size)); break;
5365 case PRE_DEC: case POST_DEC:
5366 output_address (VOIDmode,
5367 plus_constant (Pmode, XEXP (addr, 0), -size));
5368 break;
5369 case PRE_MODIFY: case POST_MODIFY:
5370 output_address (VOIDmode, XEXP (addr, 1)); break;
5371 case PLUS:
5372 if (output_scaled)
5374 output_address (VOIDmode,
5375 plus_constant (Pmode, XEXP (addr, 0),
5376 (INTVAL (XEXP (addr, 1))
5377 >> (size == 2 ? 1 : 2))));
5378 output_scaled = 0;
5380 else
5381 output_address (VOIDmode, addr);
5382 break;
5383 default:
5384 if (flag_pic && CONSTANT_ADDRESS_P (addr))
5385 arc_output_pic_addr_const (file, addr, code);
5386 else
5387 output_address (VOIDmode, addr);
5388 break;
5390 fputc (']', file);
5391 break;
5393 case CONST_DOUBLE :
5394 /* We handle SFmode constants here as output_addr_const doesn't. */
5395 if (GET_MODE (x) == SFmode)
5397 long l;
5399 REAL_VALUE_TO_TARGET_SINGLE (*CONST_DOUBLE_REAL_VALUE (x), l);
5400 fprintf (file, "0x%08lx", l);
5401 break;
5403 /* FALLTHRU */
5404 /* Let output_addr_const deal with it. */
5405 default :
5406 if (flag_pic
5407 || (GET_CODE (x) == CONST
5408 && GET_CODE (XEXP (x, 0)) == UNSPEC
5409 && (XINT (XEXP (x, 0), 1) == UNSPEC_TLS_OFF
5410 || XINT (XEXP (x, 0), 1) == UNSPEC_TLS_GD))
5411 || (GET_CODE (x) == CONST
5412 && GET_CODE (XEXP (x, 0)) == PLUS
5413 && GET_CODE (XEXP (XEXP (x, 0), 0)) == UNSPEC
5414 && (XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_OFF
5415 || XINT (XEXP (XEXP (x, 0), 0), 1) == UNSPEC_TLS_GD)))
5416 arc_output_pic_addr_const (file, x, code);
5417 else
5418 output_addr_const (file, x);
5419 break;
5423 /* Print a memory address as an operand to reference that memory location. */
5425 void
5426 arc_print_operand_address (FILE *file , rtx addr)
5428 rtx base, index = 0;
5430 switch (GET_CODE (addr))
5432 case REG :
5433 fputs (reg_names[REGNO (addr)], file);
5434 break;
5435 case SYMBOL_REF:
5436 if (output_sdata)
5437 fputs ("gp,", file);
5438 output_addr_const (file, addr);
5439 if (output_sdata)
5440 fputs ("@sda", file);
5441 output_sdata = 0;
5442 break;
5443 case PLUS :
5444 if (GET_CODE (XEXP (addr, 0)) == MULT)
5445 index = XEXP (XEXP (addr, 0), 0), base = XEXP (addr, 1);
5446 else if (CONST_INT_P (XEXP (addr, 0)))
5447 index = XEXP (addr, 0), base = XEXP (addr, 1);
5448 else
5449 base = XEXP (addr, 0), index = XEXP (addr, 1);
5451 gcc_assert (OBJECT_P (base));
5452 arc_print_operand_address (file, base);
5453 if (CONSTANT_P (base) && CONST_INT_P (index))
5454 fputc ('+', file);
5455 else
5456 fputc (',', file);
5457 gcc_assert (OBJECT_P (index));
5458 arc_print_operand_address (file, index);
5459 break;
5460 case CONST:
5462 rtx c = XEXP (addr, 0);
5464 if ((GET_CODE (c) == UNSPEC
5465 && (XINT (c, 1) == UNSPEC_TLS_OFF
5466 || XINT (c, 1) == UNSPEC_TLS_IE))
5467 || (GET_CODE (c) == PLUS
5468 && GET_CODE (XEXP (c, 0)) == UNSPEC
5469 && (XINT (XEXP (c, 0), 1) == UNSPEC_TLS_OFF
5470 || XINT (XEXP (c, 0), 1) == ARC_UNSPEC_GOTOFFPC)))
5472 arc_output_pic_addr_const (file, c, 0);
5473 break;
5475 gcc_assert (GET_CODE (c) == PLUS);
5476 gcc_assert (GET_CODE (XEXP (c, 0)) == SYMBOL_REF);
5477 gcc_assert (GET_CODE (XEXP (c, 1)) == CONST_INT);
5479 output_address (VOIDmode, XEXP (addr, 0));
5481 break;
5483 case PRE_INC :
5484 case PRE_DEC :
5485 /* We shouldn't get here as we've lost the mode of the memory object
5486 (which says how much to inc/dec by. */
5487 gcc_unreachable ();
5488 break;
5489 default :
5490 if (flag_pic)
5491 arc_output_pic_addr_const (file, addr, 0);
5492 else
5493 output_addr_const (file, addr);
5494 break;
5498 /* Return non-zero if INSN should be output as a short insn. UNALIGN is
5499 zero if the current insn is aligned to a 4-byte-boundary, two otherwise.
5500 If CHECK_ATTR is greater than 0, check the iscompact attribute first. */
5502 static int
5503 arc_verify_short (rtx_insn *insn, int check_attr)
5505 enum attr_iscompact iscompact;
5507 if (check_attr > 0)
5509 iscompact = get_attr_iscompact (insn);
5510 if (iscompact == ISCOMPACT_FALSE)
5511 return 0;
5514 return (get_attr_length (insn) & 2) != 0;
5517 /* When outputting an instruction (alternative) that can potentially be short,
5518 output the short suffix if the insn is in fact short. */
5520 static void
5521 output_short_suffix (FILE *file)
5523 rtx_insn *insn = current_output_insn;
5524 if (!insn)
5525 return;
5527 if (arc_verify_short (insn, 1))
5529 fprintf (file, "_s");
5531 /* Restore recog_operand. */
5532 extract_insn_cached (insn);
5535 /* Implement FINAL_PRESCAN_INSN. */
5537 void
5538 arc_final_prescan_insn (rtx_insn *insn, rtx *opvec ATTRIBUTE_UNUSED,
5539 int noperands ATTRIBUTE_UNUSED)
5541 if (TARGET_DUMPISIZE)
5542 fprintf (asm_out_file, "\n; at %04x\n", INSN_ADDRESSES (INSN_UID (insn)));
5545 /* Given FROM and TO register numbers, say whether this elimination is allowed.
5546 Frame pointer elimination is automatically handled.
5548 All eliminations are permissible. If we need a frame
5549 pointer, we must eliminate ARG_POINTER_REGNUM into
5550 FRAME_POINTER_REGNUM and not into STACK_POINTER_REGNUM. */
5552 static bool
5553 arc_can_eliminate (const int from ATTRIBUTE_UNUSED, const int to)
5555 return ((to == HARD_FRAME_POINTER_REGNUM) || (to == STACK_POINTER_REGNUM));
5558 /* Define the offset between two registers, one to be eliminated, and
5559 the other its replacement, at the start of a routine. */
5562 arc_initial_elimination_offset (int from, int to)
5564 if (!cfun->machine->frame_info.initialized)
5565 arc_compute_frame_size ();
5567 if (from == ARG_POINTER_REGNUM && to == HARD_FRAME_POINTER_REGNUM)
5569 return (cfun->machine->frame_info.extra_size
5570 + cfun->machine->frame_info.reg_size);
5573 if (from == ARG_POINTER_REGNUM && to == STACK_POINTER_REGNUM)
5575 return (cfun->machine->frame_info.total_size
5576 - cfun->machine->frame_info.pretend_size);
5579 if ((from == FRAME_POINTER_REGNUM) && (to == STACK_POINTER_REGNUM))
5581 return (cfun->machine->frame_info.total_size
5582 - (cfun->machine->frame_info.pretend_size
5583 + cfun->machine->frame_info.extra_size
5584 + cfun->machine->frame_info.reg_size));
5586 if ((from == FRAME_POINTER_REGNUM) && (to == HARD_FRAME_POINTER_REGNUM))
5587 return 0;
5589 gcc_unreachable ();
5592 static bool
5593 arc_frame_pointer_required (void)
5595 return cfun->calls_alloca || crtl->calls_eh_return;
5599 /* Return the destination address of a branch. */
5601 static int
5602 branch_dest (rtx branch)
5604 rtx pat = PATTERN (branch);
5605 rtx dest = (GET_CODE (pat) == PARALLEL
5606 ? SET_SRC (XVECEXP (pat, 0, 0)) : SET_SRC (pat));
5607 int dest_uid;
5609 if (GET_CODE (dest) == IF_THEN_ELSE)
5610 dest = XEXP (dest, XEXP (dest, 1) == pc_rtx ? 2 : 1);
5612 dest = XEXP (dest, 0);
5613 dest_uid = INSN_UID (dest);
5615 return INSN_ADDRESSES (dest_uid);
5619 /* Implement TARGET_ENCODE_SECTION_INFO hook. */
5621 static void
5622 arc_encode_section_info (tree decl, rtx rtl, int first)
5624 /* For sdata, SYMBOL_FLAG_LOCAL and SYMBOL_FLAG_FUNCTION.
5625 This clears machine specific flags, so has to come first. */
5626 default_encode_section_info (decl, rtl, first);
5628 /* Check if it is a function, and whether it has the
5629 [long/medium/short]_call attribute specified. */
5630 if (TREE_CODE (decl) == FUNCTION_DECL)
5632 rtx symbol = XEXP (rtl, 0);
5633 int flags = SYMBOL_REF_FLAGS (symbol);
5635 tree attr = (TREE_TYPE (decl) != error_mark_node
5636 ? TYPE_ATTRIBUTES (TREE_TYPE (decl)) : NULL_TREE);
5637 tree long_call_attr = lookup_attribute ("long_call", attr);
5638 tree medium_call_attr = lookup_attribute ("medium_call", attr);
5639 tree short_call_attr = lookup_attribute ("short_call", attr);
5641 if (long_call_attr != NULL_TREE)
5642 flags |= SYMBOL_FLAG_LONG_CALL;
5643 else if (medium_call_attr != NULL_TREE)
5644 flags |= SYMBOL_FLAG_MEDIUM_CALL;
5645 else if (short_call_attr != NULL_TREE)
5646 flags |= SYMBOL_FLAG_SHORT_CALL;
5648 SYMBOL_REF_FLAGS (symbol) = flags;
5650 else if (VAR_P (decl))
5652 rtx symbol = XEXP (rtl, 0);
5654 tree attr = (TREE_TYPE (decl) != error_mark_node
5655 ? DECL_ATTRIBUTES (decl) : NULL_TREE);
5657 tree sec_attr = lookup_attribute ("section", attr);
5658 if (sec_attr)
5660 const char *sec_name
5661 = TREE_STRING_POINTER (TREE_VALUE (TREE_VALUE (sec_attr)));
5662 if (strcmp (sec_name, ".cmem") == 0
5663 || strcmp (sec_name, ".cmem_shared") == 0
5664 || strcmp (sec_name, ".cmem_private") == 0)
5665 SYMBOL_REF_FLAGS (symbol) |= SYMBOL_FLAG_CMEM;
5670 /* This is how to output a definition of an internal numbered label where
5671 PREFIX is the class of label and NUM is the number within the class. */
5673 static void arc_internal_label (FILE *stream, const char *prefix, unsigned long labelno)
5675 default_internal_label (stream, prefix, labelno);
5678 /* Set the cpu type and print out other fancy things,
5679 at the top of the file. */
5681 static void arc_file_start (void)
5683 default_file_start ();
5684 fprintf (asm_out_file, "\t.cpu %s\n", arc_cpu_string);
5686 /* Set some want to have build attributes. */
5687 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_PCS_config, %d\n",
5688 ATTRIBUTE_PCS);
5689 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_rf16, %d\n",
5690 TARGET_RF16 ? 1 : 0);
5691 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_pic, %d\n",
5692 flag_pic ? 2 : 0);
5693 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_tls, %d\n",
5694 (arc_tp_regno != -1) ? 1 : 0);
5695 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_sda, %d\n",
5696 TARGET_NO_SDATA_SET ? 0 : 2);
5697 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_ABI_exceptions, %d\n",
5698 TARGET_OPTFPE ? 1 : 0);
5699 if (TARGET_V2)
5700 asm_fprintf (asm_out_file, "\t.arc_attribute Tag_ARC_CPU_variation, %d\n",
5701 (arc_tune < ARC_TUNE_CORE_3) ? 2 :
5702 (arc_tune == ARC_TUNE_CORE_3 ? 3 : 4));
5705 /* Implement `TARGET_ASM_FILE_END'. */
5706 /* Outputs to the stdio stream FILE jli related text. */
5708 void arc_file_end (void)
5710 arc_jli_section *sec = arc_jli_sections;
5712 while (sec != NULL)
5714 fprintf (asm_out_file, "\n");
5715 fprintf (asm_out_file, "# JLI entry for function ");
5716 assemble_name (asm_out_file, sec->name);
5717 fprintf (asm_out_file, "\n\t.section .jlitab, \"axG\", @progbits, "
5718 ".jlitab.");
5719 assemble_name (asm_out_file, sec->name);
5720 fprintf (asm_out_file,", comdat\n");
5722 fprintf (asm_out_file, "\t.align\t4\n");
5723 fprintf (asm_out_file, "__jli.");
5724 assemble_name (asm_out_file, sec->name);
5725 fprintf (asm_out_file, ":\n\t.weak __jli.");
5726 assemble_name (asm_out_file, sec->name);
5727 fprintf (asm_out_file, "\n\tb\t@");
5728 assemble_name (asm_out_file, sec->name);
5729 fprintf (asm_out_file, "\n");
5730 sec = sec->next;
5732 file_end_indicate_exec_stack ();
5735 /* Cost functions. */
5737 /* Compute a (partial) cost for rtx X. Return true if the complete
5738 cost has been computed, and false if subexpressions should be
5739 scanned. In either case, *TOTAL contains the cost result. */
5741 static bool
5742 arc_rtx_costs (rtx x, machine_mode mode, int outer_code,
5743 int opno ATTRIBUTE_UNUSED, int *total, bool speed)
5745 int code = GET_CODE (x);
5747 switch (code)
5749 /* Small integers are as cheap as registers. */
5750 case CONST_INT:
5752 bool nolimm = false; /* Can we do without long immediate? */
5754 nolimm = false;
5755 if (UNSIGNED_INT6 (INTVAL (x)))
5756 nolimm = true;
5757 else
5759 switch (outer_code)
5761 case AND: /* bclr, bmsk, ext[bw] */
5762 if (satisfies_constraint_Ccp (x) /* bclr */
5763 || satisfies_constraint_C1p (x) /* bmsk */)
5764 nolimm = true;
5765 break;
5766 case IOR: /* bset */
5767 if (satisfies_constraint_C0p (x)) /* bset */
5768 nolimm = true;
5769 break;
5770 case XOR:
5771 if (satisfies_constraint_C0p (x)) /* bxor */
5772 nolimm = true;
5773 break;
5774 case SET:
5775 if (UNSIGNED_INT8 (INTVAL (x)))
5776 nolimm = true;
5777 if (satisfies_constraint_Chi (x))
5778 nolimm = true;
5779 if (satisfies_constraint_Clo (x))
5780 nolimm = true;
5781 break;
5782 case MULT:
5783 if (TARGET_MUL64_SET)
5784 if (SIGNED_INT12 (INTVAL (x)))
5785 nolimm = true;
5786 break;
5787 default:
5788 break;
5791 if (nolimm)
5793 *total = 0;
5794 return true;
5797 /* FALLTHRU */
5799 /* 4 byte values can be fetched as immediate constants -
5800 let's give that the cost of an extra insn. */
5801 case CONST:
5802 case LABEL_REF:
5803 case SYMBOL_REF:
5804 *total = speed ? COSTS_N_INSNS (1) : COSTS_N_BYTES (4);
5805 return true;
5807 case CONST_DOUBLE:
5809 rtx first, second;
5811 if (TARGET_DPFP)
5813 *total = COSTS_N_INSNS (1);
5814 return true;
5816 split_double (x, &first, &second);
5817 *total = COSTS_N_INSNS (!SMALL_INT (INTVAL (first))
5818 + !SMALL_INT (INTVAL (second)));
5819 return true;
5822 /* Encourage synth_mult to find a synthetic multiply when reasonable.
5823 If we need more than 12 insns to do a multiply, then go out-of-line,
5824 since the call overhead will be < 10% of the cost of the multiply. */
5825 case ASHIFT:
5826 if (mode == DImode)
5828 if (XEXP (x, 1) == const1_rtx)
5830 *total += rtx_cost (XEXP (x, 0), mode, ASHIFT, 0, speed)
5831 + COSTS_N_INSNS (2);
5832 return true;
5834 return false;
5836 if (TARGET_BARREL_SHIFTER)
5838 *total = COSTS_N_INSNS (1);
5839 if (CONST_INT_P (XEXP (x, 1)))
5841 *total += rtx_cost (XEXP (x, 0), mode, ASHIFT, 0, speed);
5842 return true;
5845 else if (CONST_INT_P (XEXP (x, 1)))
5847 unsigned int n = INTVAL (XEXP (x, 1)) & 0x1f;
5848 *total = arc_ashl_alg[arc_shift_context_idx ()][n].cost
5849 + rtx_cost (XEXP (x, 0), mode, ASHIFT, 0, speed);
5850 return true;
5852 else
5853 /* Variable shift loop takes 2 * n + 2 cycles. */
5854 *total = speed ? COSTS_N_INSNS (64) : COSTS_N_INSNS (4);
5855 return false;
5857 case ASHIFTRT:
5858 case LSHIFTRT:
5859 case ROTATE:
5860 case ROTATERT:
5861 if (mode == DImode)
5862 return false;
5863 if (TARGET_BARREL_SHIFTER)
5865 *total = COSTS_N_INSNS (1);
5866 if (CONSTANT_P (XEXP (x, 1)))
5868 *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
5869 0, speed);
5870 return true;
5873 else if (GET_CODE (XEXP (x, 1)) != CONST_INT)
5874 *total = speed ? COSTS_N_INSNS (16) : COSTS_N_INSNS (4);
5875 else
5877 int n = INTVAL (XEXP (x, 1)) & 31;
5878 if (n < 4)
5879 *total = COSTS_N_INSNS (n);
5880 else
5881 *total = speed ? COSTS_N_INSNS (n + 2) : COSTS_N_INSNS (4);
5882 *total += rtx_cost (XEXP (x, 0), mode, (enum rtx_code) code,
5883 0, speed);
5884 return true;
5886 return false;
5888 case DIV:
5889 case UDIV:
5890 if (GET_MODE_CLASS (mode) == MODE_FLOAT
5891 && (TARGET_FP_SP_SQRT || TARGET_FP_DP_SQRT))
5892 *total = COSTS_N_INSNS(1);
5893 else if (GET_MODE_CLASS (mode) == MODE_INT
5894 && TARGET_DIVREM)
5895 *total = COSTS_N_INSNS(1);
5896 else if (speed)
5897 *total = COSTS_N_INSNS(30);
5898 else
5899 *total = COSTS_N_INSNS(1);
5900 return false;
5902 case MULT:
5903 if ((TARGET_DPFP && GET_MODE (x) == DFmode))
5904 *total = COSTS_N_INSNS (1);
5905 else if (speed)
5906 *total= arc_multcost;
5907 /* We do not want synth_mult sequences when optimizing
5908 for size. */
5909 else if (TARGET_ANY_MPY)
5910 *total = COSTS_N_INSNS (1);
5911 else
5912 *total = COSTS_N_INSNS (2);
5913 return false;
5915 case PLUS:
5916 if (mode == DImode)
5917 return false;
5918 if (outer_code == MEM && CONST_INT_P (XEXP (x, 1))
5919 && RTX_OK_FOR_OFFSET_P (mode, XEXP (x, 1)))
5921 *total = 0;
5922 return true;
5925 if ((GET_CODE (XEXP (x, 0)) == ASHIFT
5926 && _1_2_3_operand (XEXP (XEXP (x, 0), 1), VOIDmode))
5927 || (GET_CODE (XEXP (x, 0)) == MULT
5928 && _2_4_8_operand (XEXP (XEXP (x, 0), 1), VOIDmode)))
5930 if (CONSTANT_P (XEXP (x, 1)) && !speed)
5931 *total += COSTS_N_INSNS (4);
5932 *total += rtx_cost (XEXP (XEXP (x, 0), 0), mode, PLUS, 1, speed);
5933 return true;
5935 return false;
5936 case MINUS:
5937 if ((GET_CODE (XEXP (x, 1)) == ASHIFT
5938 && _1_2_3_operand (XEXP (XEXP (x, 1), 1), VOIDmode))
5939 || (GET_CODE (XEXP (x, 1)) == MULT
5940 && _2_4_8_operand (XEXP (XEXP (x, 1), 1), VOIDmode)))
5942 if (CONSTANT_P (XEXP (x, 0)) && !speed)
5943 *total += COSTS_N_INSNS (4);
5944 *total += rtx_cost (XEXP (XEXP (x, 1), 0), mode, PLUS, 1, speed);
5945 return true;
5947 return false;
5949 case COMPARE:
5951 rtx op0 = XEXP (x, 0);
5952 rtx op1 = XEXP (x, 1);
5954 if (GET_CODE (op0) == ZERO_EXTRACT && op1 == const0_rtx
5955 && XEXP (op0, 1) == const1_rtx)
5957 /* btst / bbit0 / bbit1:
5958 Small integers and registers are free; everything else can
5959 be put in a register. */
5960 mode = GET_MODE (XEXP (op0, 0));
5961 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5962 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5963 return true;
5965 if (GET_CODE (op0) == AND && op1 == const0_rtx
5966 && satisfies_constraint_C1p (XEXP (op0, 1)))
5968 /* bmsk.f */
5969 *total = rtx_cost (XEXP (op0, 0), VOIDmode, SET, 1, speed);
5970 return true;
5972 /* add.f */
5973 if (GET_CODE (op1) == NEG)
5975 /* op0 might be constant, the inside of op1 is rather
5976 unlikely to be so. So swapping the operands might lower
5977 the cost. */
5978 mode = GET_MODE (op0);
5979 *total = (rtx_cost (op0, mode, PLUS, 1, speed)
5980 + rtx_cost (XEXP (op1, 0), mode, PLUS, 0, speed));
5982 return false;
5984 case EQ: case NE:
5985 if (outer_code == IF_THEN_ELSE
5986 && GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
5987 && XEXP (x, 1) == const0_rtx
5988 && XEXP (XEXP (x, 0), 1) == const1_rtx)
5990 /* btst / bbit0 / bbit1:
5991 Small integers and registers are free; everything else can
5992 be put in a register. */
5993 rtx op0 = XEXP (x, 0);
5995 mode = GET_MODE (XEXP (op0, 0));
5996 *total = (rtx_cost (XEXP (op0, 0), mode, SET, 1, speed)
5997 + rtx_cost (XEXP (op0, 2), mode, SET, 1, speed));
5998 return true;
6000 /* Fall through. */
6001 /* scc_insn expands into two insns. */
6002 case GTU: case GEU: case LEU:
6003 if (mode == SImode)
6004 *total += COSTS_N_INSNS (1);
6005 return false;
6006 case LTU: /* might use adc. */
6007 if (mode == SImode)
6008 *total += COSTS_N_INSNS (1) - 1;
6009 return false;
6010 default:
6011 return false;
6015 /* Return true if ADDR is a valid pic address.
6016 A valid pic address on arc should look like
6017 const (unspec (SYMBOL_REF/LABEL) (ARC_UNSPEC_GOTOFF/ARC_UNSPEC_GOT)) */
6019 bool
6020 arc_legitimate_pic_addr_p (rtx addr)
6022 if (GET_CODE (addr) != CONST)
6023 return false;
6025 addr = XEXP (addr, 0);
6028 if (GET_CODE (addr) == PLUS)
6030 if (GET_CODE (XEXP (addr, 1)) != CONST_INT)
6031 return false;
6032 addr = XEXP (addr, 0);
6035 if (GET_CODE (addr) != UNSPEC
6036 || XVECLEN (addr, 0) != 1)
6037 return false;
6039 /* Must be one of @GOT, @GOTOFF, @GOTOFFPC, @tlsgd, tlsie. */
6040 if (XINT (addr, 1) != ARC_UNSPEC_GOT
6041 && XINT (addr, 1) != ARC_UNSPEC_GOTOFF
6042 && XINT (addr, 1) != ARC_UNSPEC_GOTOFFPC
6043 && XINT (addr, 1) != UNSPEC_TLS_GD
6044 && XINT (addr, 1) != UNSPEC_TLS_IE)
6045 return false;
6047 if (GET_CODE (XVECEXP (addr, 0, 0)) != SYMBOL_REF
6048 && GET_CODE (XVECEXP (addr, 0, 0)) != LABEL_REF)
6049 return false;
6051 return true;
6056 /* Return true if OP contains a symbol reference. */
6058 static bool
6059 symbolic_reference_mentioned_p (rtx op)
6061 const char *fmt;
6062 int i;
6064 if (GET_CODE (op) == SYMBOL_REF || GET_CODE (op) == LABEL_REF)
6065 return true;
6067 fmt = GET_RTX_FORMAT (GET_CODE (op));
6068 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
6070 if (fmt[i] == 'E')
6072 int j;
6074 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
6075 if (symbolic_reference_mentioned_p (XVECEXP (op, i, j)))
6076 return true;
6079 else if (fmt[i] == 'e' && symbolic_reference_mentioned_p (XEXP (op, i)))
6080 return true;
6083 return false;
6086 /* Return true if OP contains a SYMBOL_REF that is not wrapped in an unspec.
6087 If SKIP_LOCAL is true, skip symbols that bind locally.
6088 This is used further down in this file, and, without SKIP_LOCAL,
6089 in the addsi3 / subsi3 expanders when generating PIC code. */
6091 bool
6092 arc_raw_symbolic_reference_mentioned_p (rtx op, bool skip_local)
6094 const char *fmt;
6095 int i;
6097 if (GET_CODE(op) == UNSPEC)
6098 return false;
6100 if (GET_CODE (op) == SYMBOL_REF)
6102 if (SYMBOL_REF_TLS_MODEL (op))
6103 return true;
6104 if (!flag_pic)
6105 return false;
6106 tree decl = SYMBOL_REF_DECL (op);
6107 return !skip_local || !decl || !default_binds_local_p (decl);
6110 fmt = GET_RTX_FORMAT (GET_CODE (op));
6111 for (i = GET_RTX_LENGTH (GET_CODE (op)) - 1; i >= 0; i--)
6113 if (fmt[i] == 'E')
6115 int j;
6117 for (j = XVECLEN (op, i) - 1; j >= 0; j--)
6118 if (arc_raw_symbolic_reference_mentioned_p (XVECEXP (op, i, j),
6119 skip_local))
6120 return true;
6123 else if (fmt[i] == 'e'
6124 && arc_raw_symbolic_reference_mentioned_p (XEXP (op, i),
6125 skip_local))
6126 return true;
6129 return false;
6132 /* The __tls_get_attr symbol. */
6133 static GTY(()) rtx arc_tls_symbol;
6135 /* Emit a call to __tls_get_addr. TI is the argument to this function.
6136 RET is an RTX for the return value location. The entire insn sequence
6137 is returned. */
6139 static rtx
6140 arc_call_tls_get_addr (rtx ti)
6142 rtx arg = gen_rtx_REG (Pmode, R0_REG);
6143 rtx ret = gen_rtx_REG (Pmode, R0_REG);
6144 rtx fn;
6145 rtx_insn *insn;
6147 if (!arc_tls_symbol)
6148 arc_tls_symbol = init_one_libfunc ("__tls_get_addr");
6150 emit_move_insn (arg, ti);
6151 fn = gen_rtx_MEM (SImode, arc_tls_symbol);
6152 insn = emit_call_insn (gen_call_value (ret, fn, const0_rtx));
6153 RTL_CONST_CALL_P (insn) = 1;
6154 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), ret);
6155 use_reg (&CALL_INSN_FUNCTION_USAGE (insn), arg);
6157 return ret;
6160 /* Return a legitimized address for ADDR,
6161 which is a SYMBOL_REF with tls_model MODEL. */
6163 static rtx
6164 arc_legitimize_tls_address (rtx addr, enum tls_model model)
6166 rtx tmp;
6168 /* The TP pointer needs to be set. */
6169 gcc_assert (arc_tp_regno != -1);
6171 switch (model)
6173 case TLS_MODEL_GLOBAL_DYNAMIC:
6174 case TLS_MODEL_LOCAL_DYNAMIC:
6175 tmp = gen_reg_rtx (Pmode);
6176 emit_move_insn (tmp, arc_unspec_offset (addr, UNSPEC_TLS_GD));
6177 return arc_call_tls_get_addr (tmp);
6179 case TLS_MODEL_INITIAL_EXEC:
6180 addr = arc_unspec_offset (addr, UNSPEC_TLS_IE);
6181 addr = copy_to_mode_reg (Pmode, gen_const_mem (Pmode, addr));
6182 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
6184 case TLS_MODEL_LOCAL_EXEC:
6185 addr = arc_unspec_offset (addr, UNSPEC_TLS_OFF);
6186 return gen_rtx_PLUS (Pmode, gen_rtx_REG (Pmode, arc_tp_regno), addr);
6188 default:
6189 gcc_unreachable ();
6193 /* Return true if SYMBOL_REF X binds locally. */
6195 static bool
6196 arc_symbol_binds_local_p (const_rtx x)
6198 return (SYMBOL_REF_DECL (x)
6199 ? targetm.binds_local_p (SYMBOL_REF_DECL (x))
6200 : SYMBOL_REF_LOCAL_P (x));
6203 /* Legitimize a pic address reference in ADDR. The return value is
6204 the legitimated address. */
6206 static rtx
6207 arc_legitimize_pic_address (rtx addr)
6209 if (!flag_pic)
6210 return addr;
6212 switch (GET_CODE (addr))
6214 case UNSPEC:
6215 /* Can be one or our GOT or GOTOFFPC unspecs. This situation
6216 happens when an address is not a legitimate constant and we
6217 need the resolve it via force_reg in
6218 prepare_move_operands. */
6219 switch (XINT (addr, 1))
6221 case ARC_UNSPEC_GOT:
6222 case ARC_UNSPEC_GOTOFFPC:
6223 /* Recover the symbol ref. */
6224 addr = XVECEXP (addr, 0, 0);
6225 break;
6226 default:
6227 return addr;
6229 /* Fall through. */
6230 case SYMBOL_REF:
6231 /* TLS symbols are handled in different place. */
6232 if (SYMBOL_REF_TLS_MODEL (addr))
6233 return addr;
6235 /* This symbol must be referenced via a load from the Global
6236 Offset Table (@GOTPC). */
6237 if (!arc_symbol_binds_local_p (addr))
6238 return gen_const_mem (Pmode, arc_unspec_offset (addr, ARC_UNSPEC_GOT));
6240 /* Local symb: use @pcl to access it. */
6241 /* Fall through. */
6242 case LABEL_REF:
6243 return arc_unspec_offset (addr, ARC_UNSPEC_GOTOFFPC);
6245 default:
6246 break;
6249 return addr;
6252 /* Output address constant X to FILE, taking PIC into account. */
6254 static void
6255 arc_output_pic_addr_const (FILE * file, rtx x, int code)
6257 char buf[256];
6259 restart:
6260 switch (GET_CODE (x))
6262 case PC:
6263 if (flag_pic)
6264 putc ('.', file);
6265 else
6266 gcc_unreachable ();
6267 break;
6269 case SYMBOL_REF:
6270 output_addr_const (file, x);
6272 /* Local functions do not get references through the PLT. */
6273 if (code == 'P' && ! SYMBOL_REF_LOCAL_P (x))
6274 fputs ("@plt", file);
6275 break;
6277 case LABEL_REF:
6278 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (XEXP (x, 0)));
6279 assemble_name (file, buf);
6280 break;
6282 case CODE_LABEL:
6283 ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
6284 assemble_name (file, buf);
6285 break;
6287 case CONST_INT:
6288 fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
6289 break;
6291 case CONST:
6292 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6293 break;
6295 case CONST_DOUBLE:
6296 if (GET_MODE (x) == VOIDmode)
6298 /* We can use %d if the number is one word and positive. */
6299 if (CONST_DOUBLE_HIGH (x))
6300 fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
6301 CONST_DOUBLE_HIGH (x), CONST_DOUBLE_LOW (x));
6302 else if (CONST_DOUBLE_LOW (x) < 0)
6303 fprintf (file, HOST_WIDE_INT_PRINT_HEX, CONST_DOUBLE_LOW (x));
6304 else
6305 fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
6307 else
6308 /* We can't handle floating point constants;
6309 PRINT_OPERAND must handle them. */
6310 output_operand_lossage ("floating constant misused");
6311 break;
6313 case PLUS:
6314 /* FIXME: Not needed here. */
6315 /* Some assemblers need integer constants to appear last (eg masm). */
6316 if (GET_CODE (XEXP (x, 0)) == CONST_INT)
6318 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6319 fprintf (file, "+");
6320 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6322 else if (GET_CODE (XEXP (x, 1)) == CONST_INT)
6324 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6325 if (INTVAL (XEXP (x, 1)) >= 0)
6326 fprintf (file, "+");
6327 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6329 else
6330 gcc_unreachable();
6331 break;
6333 case MINUS:
6334 /* Avoid outputting things like x-x or x+5-x,
6335 since some assemblers can't handle that. */
6336 x = simplify_subtraction (x);
6337 if (GET_CODE (x) != MINUS)
6338 goto restart;
6340 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6341 fprintf (file, "-");
6342 if (GET_CODE (XEXP (x, 1)) == CONST_INT
6343 && INTVAL (XEXP (x, 1)) < 0)
6345 fprintf (file, "(");
6346 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6347 fprintf (file, ")");
6349 else
6350 arc_output_pic_addr_const (file, XEXP (x, 1), code);
6351 break;
6353 case ZERO_EXTEND:
6354 case SIGN_EXTEND:
6355 arc_output_pic_addr_const (file, XEXP (x, 0), code);
6356 break;
6359 case UNSPEC:
6360 const char *suffix;
6361 bool pcrel; pcrel = false;
6362 rtx base; base = NULL;
6363 gcc_assert (XVECLEN (x, 0) >= 1);
6364 switch (XINT (x, 1))
6366 case ARC_UNSPEC_GOT:
6367 suffix = "@gotpc", pcrel = true;
6368 break;
6369 case ARC_UNSPEC_GOTOFF:
6370 suffix = "@gotoff";
6371 break;
6372 case ARC_UNSPEC_GOTOFFPC:
6373 suffix = "@pcl", pcrel = true;
6374 break;
6375 case ARC_UNSPEC_PLT:
6376 suffix = "@plt";
6377 break;
6378 case UNSPEC_TLS_GD:
6379 suffix = "@tlsgd", pcrel = true;
6380 break;
6381 case UNSPEC_TLS_IE:
6382 suffix = "@tlsie", pcrel = true;
6383 break;
6384 case UNSPEC_TLS_OFF:
6385 if (XVECLEN (x, 0) == 2)
6386 base = XVECEXP (x, 0, 1);
6387 if (SYMBOL_REF_TLS_MODEL (XVECEXP (x, 0, 0)) == TLS_MODEL_LOCAL_EXEC
6388 || (!flag_pic && !base))
6389 suffix = "@tpoff";
6390 else
6391 suffix = "@dtpoff";
6392 break;
6393 default:
6394 suffix = "@invalid";
6395 output_operand_lossage ("invalid UNSPEC as operand: %d", XINT (x,1));
6396 break;
6398 if (pcrel)
6399 fputs ("pcl,", file);
6400 arc_output_pic_addr_const (file, XVECEXP (x, 0, 0), code);
6401 fputs (suffix, file);
6402 if (base)
6403 arc_output_pic_addr_const (file, base, code);
6404 break;
6406 default:
6407 output_operand_lossage ("invalid expression as operand");
6411 /* The function returning the number of words, at the beginning of an
6412 argument, must be put in registers. The returned value must be
6413 zero for arguments that are passed entirely in registers or that
6414 are entirely pushed on the stack.
6416 On some machines, certain arguments must be passed partially in
6417 registers and partially in memory. On these machines, typically
6418 the first N words of arguments are passed in registers, and the
6419 rest on the stack. If a multi-word argument (a `double' or a
6420 structure) crosses that boundary, its first few words must be
6421 passed in registers and the rest must be pushed. This function
6422 tells the compiler when this occurs, and how many of the words
6423 should go in registers.
6425 `FUNCTION_ARG' for these arguments should return the first register
6426 to be used by the caller for this argument; likewise
6427 `FUNCTION_INCOMING_ARG', for the called function.
6429 The function is used to implement macro FUNCTION_ARG_PARTIAL_NREGS. */
6431 /* If REGNO is the least arg reg available then what is the total number of arg
6432 regs available. */
6433 #define GPR_REST_ARG_REGS(REGNO) \
6434 ((REGNO) <= MAX_ARC_PARM_REGS ? MAX_ARC_PARM_REGS - (REGNO) : 0 )
6436 /* Since arc parm regs are contiguous. */
6437 #define ARC_NEXT_ARG_REG(REGNO) ( (REGNO) + 1 )
6439 /* Implement TARGET_ARG_PARTIAL_BYTES. */
6441 static int
6442 arc_arg_partial_bytes (cumulative_args_t cum_v, const function_arg_info &arg)
6444 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6445 int bytes = arg.promoted_size_in_bytes ();
6446 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6447 int arg_num = *cum;
6448 int ret;
6450 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6451 ret = GPR_REST_ARG_REGS (arg_num);
6453 /* ICEd at function.cc:2361, and ret is copied to data->partial */
6454 ret = (ret >= words ? 0 : ret * UNITS_PER_WORD);
6456 return ret;
6459 /* Implement TARGET_FUNCTION_ARG. On the ARC the first MAX_ARC_PARM_REGS
6460 args are normally in registers and the rest are pushed. */
6462 static rtx
6463 arc_function_arg (cumulative_args_t cum_v, const function_arg_info &arg)
6465 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6466 int arg_num = *cum;
6467 rtx ret;
6468 const char *debstr ATTRIBUTE_UNUSED;
6470 arg_num = ROUND_ADVANCE_CUM (arg_num, arg.mode, arg.type);
6471 /* Return a marker for use in the call instruction. */
6472 if (arg.end_marker_p ())
6474 ret = const0_rtx;
6475 debstr = "<0>";
6477 else if (GPR_REST_ARG_REGS (arg_num) > 0)
6479 ret = gen_rtx_REG (arg.mode, arg_num);
6480 debstr = reg_names [arg_num];
6482 else
6484 ret = NULL_RTX;
6485 debstr = "memory";
6487 return ret;
6490 /* Implement TARGET_FUNCTION_ARG_ADVANCE. */
6491 /* For the ARC: the cum set here is passed on to function_arg where we
6492 look at its value and say which reg to use. Strategy: advance the
6493 regnumber here till we run out of arg regs, then set *cum to last
6494 reg. In function_arg, since *cum > last arg reg we would return 0
6495 and thus the arg will end up on the stack. For straddling args of
6496 course function_arg_partial_nregs will come into play. */
6498 static void
6499 arc_function_arg_advance (cumulative_args_t cum_v,
6500 const function_arg_info &arg)
6502 CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v);
6503 int bytes = arg.promoted_size_in_bytes ();
6504 int words = (bytes + UNITS_PER_WORD - 1) / UNITS_PER_WORD;
6505 int i;
6507 if (words)
6508 *cum = ROUND_ADVANCE_CUM (*cum, arg.mode, arg.type);
6509 for (i = 0; i < words; i++)
6510 *cum = ARC_NEXT_ARG_REG (*cum);
6514 /* Define how to find the value returned by a function.
6515 VALTYPE is the data type of the value (as a tree).
6516 If the precise function being called is known, FN_DECL_OR_TYPE is its
6517 FUNCTION_DECL; otherwise, FN_DECL_OR_TYPE is its type. */
6519 static rtx
6520 arc_function_value (const_tree valtype,
6521 const_tree fn_decl_or_type ATTRIBUTE_UNUSED,
6522 bool outgoing ATTRIBUTE_UNUSED)
6524 machine_mode mode = TYPE_MODE (valtype);
6525 int unsignedp ATTRIBUTE_UNUSED;
6527 unsignedp = TYPE_UNSIGNED (valtype);
6528 if (INTEGRAL_TYPE_P (valtype) || TREE_CODE (valtype) == OFFSET_TYPE)
6529 PROMOTE_MODE (mode, unsignedp, valtype);
6530 return gen_rtx_REG (mode, 0);
6533 /* Returns the return address that is used by builtin_return_address. */
6536 arc_return_addr_rtx (int count, ATTRIBUTE_UNUSED rtx frame)
6538 if (count != 0)
6539 return const0_rtx;
6541 return get_hard_reg_initial_val (Pmode , RETURN_ADDR_REGNUM);
6544 /* Determine if a given RTX is a valid constant. We already know this
6545 satisfies CONSTANT_P. */
6547 bool
6548 arc_legitimate_constant_p (machine_mode mode, rtx x)
6550 switch (GET_CODE (x))
6552 case CONST:
6553 if (flag_pic)
6555 if (arc_legitimate_pic_addr_p (x))
6556 return true;
6558 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6560 case SYMBOL_REF:
6561 if (SYMBOL_REF_TLS_MODEL (x))
6562 return false;
6563 /* Fall through. */
6564 case LABEL_REF:
6565 if (flag_pic)
6566 return false;
6567 /* Fall through. */
6568 case CONST_INT:
6569 case CONST_DOUBLE:
6570 return true;
6572 case NEG:
6573 return arc_legitimate_constant_p (mode, XEXP (x, 0));
6575 case PLUS:
6576 case MINUS:
6578 bool t1 = arc_legitimate_constant_p (mode, XEXP (x, 0));
6579 bool t2 = arc_legitimate_constant_p (mode, XEXP (x, 1));
6581 return (t1 && t2);
6584 case CONST_VECTOR:
6585 switch (mode)
6587 case E_V2HImode:
6588 return TARGET_PLUS_DMPY;
6589 case E_V2SImode:
6590 case E_V4HImode:
6591 return TARGET_PLUS_QMACW;
6592 default:
6593 return false;
6596 case UNSPEC:
6597 switch (XINT (x, 1))
6599 case UNSPEC_TLS_GD:
6600 case UNSPEC_TLS_OFF:
6601 case UNSPEC_TLS_IE:
6602 return true;
6603 default:
6604 /* Any other unspec ending here are pic related, hence the above
6605 constant pic address checking returned false. */
6606 return false;
6608 /* Fall through. */
6610 default:
6611 fatal_insn ("unrecognized supposed constant", x);
6614 gcc_unreachable ();
6617 static bool
6618 arc_legitimate_address_p (machine_mode mode, rtx x, bool strict,
6619 code_helper = ERROR_MARK)
6621 if (RTX_OK_FOR_BASE_P (x, strict))
6622 return true;
6623 if (legitimate_offset_address_p (mode, x, TARGET_INDEXED_LOADS, strict))
6624 return true;
6625 if (legitimate_scaled_address_p (mode, x, strict))
6626 return true;
6627 if (legitimate_small_data_address_p (x, mode))
6628 return true;
6629 if (GET_CODE (x) == CONST_INT && LARGE_INT (INTVAL (x)))
6630 return true;
6632 /* When we compile for size avoid const (@sym + offset)
6633 addresses. */
6634 if (!flag_pic && optimize_size && !reload_completed
6635 && (GET_CODE (x) == CONST)
6636 && (GET_CODE (XEXP (x, 0)) == PLUS)
6637 && (GET_CODE (XEXP (XEXP (x, 0), 0)) == SYMBOL_REF)
6638 && SYMBOL_REF_TLS_MODEL (XEXP (XEXP (x, 0), 0)) == 0
6639 && !SYMBOL_REF_FUNCTION_P (XEXP (XEXP (x, 0), 0)))
6641 rtx addend = XEXP (XEXP (x, 0), 1);
6642 gcc_assert (CONST_INT_P (addend));
6643 HOST_WIDE_INT offset = INTVAL (addend);
6645 /* Allow addresses having a large offset to pass. Anyhow they
6646 will end in a limm. */
6647 return !(offset > -1024 && offset < 1020);
6650 if ((GET_MODE_SIZE (mode) != 16) && CONSTANT_P (x))
6652 return arc_legitimate_constant_p (mode, x);
6654 if ((GET_CODE (x) == PRE_DEC || GET_CODE (x) == PRE_INC
6655 || GET_CODE (x) == POST_DEC || GET_CODE (x) == POST_INC)
6656 && RTX_OK_FOR_BASE_P (XEXP (x, 0), strict))
6657 return true;
6658 /* We're restricted here by the `st' insn. */
6659 if ((GET_CODE (x) == PRE_MODIFY || GET_CODE (x) == POST_MODIFY)
6660 && GET_CODE (XEXP ((x), 1)) == PLUS
6661 && rtx_equal_p (XEXP ((x), 0), XEXP (XEXP (x, 1), 0))
6662 && legitimate_offset_address_p (QImode, XEXP (x, 1),
6663 TARGET_AUTO_MODIFY_REG, strict))
6664 return true;
6665 return false;
6668 /* Return true iff ADDR (a legitimate address expression)
6669 has an effect that depends on the machine mode it is used for. */
6671 static bool
6672 arc_mode_dependent_address_p (const_rtx addr, addr_space_t)
6674 /* SYMBOL_REF is not mode dependent: it is either a small data reference,
6675 which is valid for loads and stores, or a limm offset, which is valid for
6676 loads. Scaled indices are scaled by the access mode. */
6677 if (GET_CODE (addr) == PLUS
6678 && GET_CODE (XEXP ((addr), 0)) == MULT)
6679 return true;
6680 return false;
6683 /* Determine if it's legal to put X into the constant pool. */
6685 static bool
6686 arc_cannot_force_const_mem (machine_mode mode, rtx x)
6688 return !arc_legitimate_constant_p (mode, x);
6691 /* IDs for all the ARC builtins. */
6693 enum arc_builtin_id
6695 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6696 ARC_BUILTIN_ ## NAME,
6697 #include "builtins.def"
6698 #undef DEF_BUILTIN
6700 ARC_BUILTIN_COUNT
6703 struct GTY(()) arc_builtin_description
6705 enum insn_code icode;
6706 int n_args;
6707 tree fndecl;
6710 static GTY(()) struct arc_builtin_description
6711 arc_bdesc[ARC_BUILTIN_COUNT] =
6713 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6714 { (enum insn_code) CODE_FOR_ ## ICODE, N_ARGS, NULL_TREE },
6715 #include "builtins.def"
6716 #undef DEF_BUILTIN
6719 /* Transform UP into lowercase and write the result to LO.
6720 You must provide enough space for LO. Return LO. */
6722 static char*
6723 arc_tolower (char *lo, const char *up)
6725 char *lo0 = lo;
6727 for (; *up; up++, lo++)
6728 *lo = TOLOWER (*up);
6730 *lo = '\0';
6732 return lo0;
6735 /* Implement `TARGET_BUILTIN_DECL'. */
6737 static tree
6738 arc_builtin_decl (unsigned id, bool initialize_p ATTRIBUTE_UNUSED)
6740 if (id < ARC_BUILTIN_COUNT)
6741 return arc_bdesc[id].fndecl;
6743 return error_mark_node;
6746 static void
6747 arc_init_builtins (void)
6749 tree V4HI_type_node;
6750 tree V2SI_type_node;
6751 tree V2HI_type_node;
6753 /* Vector types based on HS SIMD elements. */
6754 V4HI_type_node = build_vector_type_for_mode (intHI_type_node, V4HImode);
6755 V2SI_type_node = build_vector_type_for_mode (intSI_type_node, V2SImode);
6756 V2HI_type_node = build_vector_type_for_mode (intHI_type_node, V2HImode);
6758 tree pcvoid_type_node
6759 = build_pointer_type (build_qualified_type (void_type_node,
6760 TYPE_QUAL_CONST));
6761 tree V8HI_type_node = build_vector_type_for_mode (intHI_type_node,
6762 V8HImode);
6764 tree void_ftype_void
6765 = build_function_type_list (void_type_node, NULL_TREE);
6766 tree int_ftype_int
6767 = build_function_type_list (integer_type_node, integer_type_node,
6768 NULL_TREE);
6769 tree int_ftype_pcvoid_int
6770 = build_function_type_list (integer_type_node, pcvoid_type_node,
6771 integer_type_node, NULL_TREE);
6772 tree void_ftype_usint_usint
6773 = build_function_type_list (void_type_node, long_unsigned_type_node,
6774 long_unsigned_type_node, NULL_TREE);
6775 tree int_ftype_int_int
6776 = build_function_type_list (integer_type_node, integer_type_node,
6777 integer_type_node, NULL_TREE);
6778 tree usint_ftype_usint
6779 = build_function_type_list (long_unsigned_type_node,
6780 long_unsigned_type_node, NULL_TREE);
6781 tree void_ftype_usint
6782 = build_function_type_list (void_type_node, long_unsigned_type_node,
6783 NULL_TREE);
6784 tree int_ftype_void
6785 = build_function_type_list (integer_type_node, void_type_node,
6786 NULL_TREE);
6787 tree void_ftype_int
6788 = build_function_type_list (void_type_node, integer_type_node,
6789 NULL_TREE);
6790 tree int_ftype_short
6791 = build_function_type_list (integer_type_node, short_integer_type_node,
6792 NULL_TREE);
6794 /* Old ARC SIMD types. */
6795 tree v8hi_ftype_v8hi_v8hi
6796 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6797 V8HI_type_node, NULL_TREE);
6798 tree v8hi_ftype_v8hi_int
6799 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6800 integer_type_node, NULL_TREE);
6801 tree v8hi_ftype_v8hi_int_int
6802 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6803 integer_type_node, integer_type_node,
6804 NULL_TREE);
6805 tree void_ftype_v8hi_int_int
6806 = build_function_type_list (void_type_node, V8HI_type_node,
6807 integer_type_node, integer_type_node,
6808 NULL_TREE);
6809 tree void_ftype_v8hi_int_int_int
6810 = build_function_type_list (void_type_node, V8HI_type_node,
6811 integer_type_node, integer_type_node,
6812 integer_type_node, NULL_TREE);
6813 tree v8hi_ftype_int_int
6814 = build_function_type_list (V8HI_type_node, integer_type_node,
6815 integer_type_node, NULL_TREE);
6816 tree void_ftype_int_int
6817 = build_function_type_list (void_type_node, integer_type_node,
6818 integer_type_node, NULL_TREE);
6819 tree v8hi_ftype_v8hi
6820 = build_function_type_list (V8HI_type_node, V8HI_type_node,
6821 NULL_TREE);
6822 /* ARCv2 SIMD types. */
6823 tree long_ftype_v4hi_v4hi
6824 = build_function_type_list (long_long_integer_type_node,
6825 V4HI_type_node, V4HI_type_node, NULL_TREE);
6826 tree int_ftype_v2hi_v2hi
6827 = build_function_type_list (integer_type_node,
6828 V2HI_type_node, V2HI_type_node, NULL_TREE);
6829 tree v2si_ftype_v2hi_v2hi
6830 = build_function_type_list (V2SI_type_node,
6831 V2HI_type_node, V2HI_type_node, NULL_TREE);
6832 tree v2hi_ftype_v2hi_v2hi
6833 = build_function_type_list (V2HI_type_node,
6834 V2HI_type_node, V2HI_type_node, NULL_TREE);
6835 tree v2si_ftype_v2si_v2si
6836 = build_function_type_list (V2SI_type_node,
6837 V2SI_type_node, V2SI_type_node, NULL_TREE);
6838 tree v4hi_ftype_v4hi_v4hi
6839 = build_function_type_list (V4HI_type_node,
6840 V4HI_type_node, V4HI_type_node, NULL_TREE);
6841 tree long_ftype_v2si_v2hi
6842 = build_function_type_list (long_long_integer_type_node,
6843 V2SI_type_node, V2HI_type_node, NULL_TREE);
6845 /* Add the builtins. */
6846 #define DEF_BUILTIN(NAME, N_ARGS, TYPE, ICODE, MASK) \
6848 int id = ARC_BUILTIN_ ## NAME; \
6849 const char *Name = "__builtin_arc_" #NAME; \
6850 char *name = (char*) alloca (1 + strlen (Name)); \
6852 gcc_assert (id < ARC_BUILTIN_COUNT); \
6853 if (MASK) \
6854 arc_bdesc[id].fndecl \
6855 = add_builtin_function (arc_tolower(name, Name), TYPE, id, \
6856 BUILT_IN_MD, NULL, NULL_TREE); \
6858 #include "builtins.def"
6859 #undef DEF_BUILTIN
6862 /* Helper to expand __builtin_arc_aligned (void* val, int
6863 alignval). */
6865 static rtx
6866 arc_expand_builtin_aligned (tree exp)
6868 tree arg0 = CALL_EXPR_ARG (exp, 0);
6869 tree arg1 = CALL_EXPR_ARG (exp, 1);
6870 fold (arg1);
6871 rtx op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6872 rtx op1 = expand_expr (arg1, NULL_RTX, VOIDmode, EXPAND_NORMAL);
6874 if (!CONST_INT_P (op1))
6876 /* If we can't fold the alignment to a constant integer
6877 whilst optimizing, this is probably a user error. */
6878 if (optimize)
6879 warning (0, "%<__builtin_arc_aligned%> with non-constant alignment");
6881 else
6883 HOST_WIDE_INT alignTest = INTVAL (op1);
6884 /* Check alignTest is positive, and a power of two. */
6885 if (alignTest <= 0 || alignTest != (alignTest & -alignTest))
6887 error ("invalid alignment value for %<__builtin_arc_aligned%>");
6888 return NULL_RTX;
6891 if (CONST_INT_P (op0))
6893 HOST_WIDE_INT pnt = INTVAL (op0);
6895 if ((pnt & (alignTest - 1)) == 0)
6896 return const1_rtx;
6898 else
6900 unsigned align = get_pointer_alignment (arg0);
6901 unsigned numBits = alignTest * BITS_PER_UNIT;
6903 if (align && align >= numBits)
6904 return const1_rtx;
6905 /* Another attempt to ascertain alignment. Check the type
6906 we are pointing to. */
6907 if (POINTER_TYPE_P (TREE_TYPE (arg0))
6908 && TYPE_ALIGN (TREE_TYPE (TREE_TYPE (arg0))) >= numBits)
6909 return const1_rtx;
6913 /* Default to false. */
6914 return const0_rtx;
6917 /* Helper arc_expand_builtin, generates a pattern for the given icode
6918 and arguments. */
6920 static rtx_insn *
6921 apply_GEN_FCN (enum insn_code icode, rtx *arg)
6923 switch (insn_data[icode].n_generator_args)
6925 case 0:
6926 return GEN_FCN (icode) ();
6927 case 1:
6928 return GEN_FCN (icode) (arg[0]);
6929 case 2:
6930 return GEN_FCN (icode) (arg[0], arg[1]);
6931 case 3:
6932 return GEN_FCN (icode) (arg[0], arg[1], arg[2]);
6933 case 4:
6934 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3]);
6935 case 5:
6936 return GEN_FCN (icode) (arg[0], arg[1], arg[2], arg[3], arg[4]);
6937 default:
6938 gcc_unreachable ();
6942 /* Expand an expression EXP that calls a built-in function,
6943 with result going to TARGET if that's convenient
6944 (and in mode MODE if that's convenient).
6945 SUBTARGET may be used as the target for computing one of EXP's operands.
6946 IGNORE is nonzero if the value is to be ignored. */
6948 static rtx
6949 arc_expand_builtin (tree exp,
6950 rtx target,
6951 rtx subtarget ATTRIBUTE_UNUSED,
6952 machine_mode mode ATTRIBUTE_UNUSED,
6953 int ignore ATTRIBUTE_UNUSED)
6955 tree fndecl = TREE_OPERAND (CALL_EXPR_FN (exp), 0);
6956 unsigned int id = DECL_MD_FUNCTION_CODE (fndecl);
6957 const struct arc_builtin_description *d = &arc_bdesc[id];
6958 int i, j, n_args = call_expr_nargs (exp);
6959 rtx pat = NULL_RTX;
6960 rtx xop[5];
6961 enum insn_code icode = d->icode;
6962 machine_mode tmode = insn_data[icode].operand[0].mode;
6963 int nonvoid;
6964 tree arg0;
6965 tree arg1;
6966 tree arg2;
6967 tree arg3;
6968 rtx op0;
6969 rtx op1;
6970 rtx op2;
6971 rtx op3;
6972 rtx op4;
6973 machine_mode mode0;
6974 machine_mode mode1;
6975 machine_mode mode2;
6976 machine_mode mode3;
6977 machine_mode mode4;
6979 if (id >= ARC_BUILTIN_COUNT)
6980 internal_error ("bad builtin fcode");
6982 /* 1st part: Expand special builtins. */
6983 switch (id)
6985 case ARC_BUILTIN_NOP:
6986 emit_insn (gen_nopv ());
6987 return NULL_RTX;
6989 case ARC_BUILTIN_RTIE:
6990 case ARC_BUILTIN_SYNC:
6991 case ARC_BUILTIN_BRK:
6992 case ARC_BUILTIN_SWI:
6993 case ARC_BUILTIN_UNIMP_S:
6994 gcc_assert (icode != 0);
6995 emit_insn (GEN_FCN (icode) (const1_rtx));
6996 return NULL_RTX;
6998 case ARC_BUILTIN_ALIGNED:
6999 return arc_expand_builtin_aligned (exp);
7001 case ARC_BUILTIN_CLRI:
7002 target = gen_reg_rtx (SImode);
7003 emit_insn (gen_clri (target, const1_rtx));
7004 return target;
7006 case ARC_BUILTIN_TRAP_S:
7007 case ARC_BUILTIN_SLEEP:
7008 arg0 = CALL_EXPR_ARG (exp, 0);
7009 fold (arg0);
7010 op0 = expand_expr (arg0, NULL_RTX, VOIDmode, EXPAND_NORMAL);
7012 gcc_assert (icode != 0);
7013 emit_insn (GEN_FCN (icode) (op0));
7014 return NULL_RTX;
7016 case ARC_BUILTIN_VDORUN:
7017 case ARC_BUILTIN_VDIRUN:
7018 arg0 = CALL_EXPR_ARG (exp, 0);
7019 arg1 = CALL_EXPR_ARG (exp, 1);
7020 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7021 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7023 target = gen_rtx_REG (SImode, (id == ARC_BUILTIN_VDIRUN) ? 131 : 139);
7025 mode0 = insn_data[icode].operand[1].mode;
7026 mode1 = insn_data[icode].operand[2].mode;
7028 if (!insn_data[icode].operand[1].predicate (op0, mode0))
7029 op0 = copy_to_mode_reg (mode0, op0);
7031 if (!insn_data[icode].operand[2].predicate (op1, mode1))
7032 op1 = copy_to_mode_reg (mode1, op1);
7034 pat = GEN_FCN (icode) (target, op0, op1);
7035 if (!pat)
7036 return NULL_RTX;
7038 emit_insn (pat);
7039 return NULL_RTX;
7041 case ARC_BUILTIN_VDIWR:
7042 case ARC_BUILTIN_VDOWR:
7043 arg0 = CALL_EXPR_ARG (exp, 0);
7044 arg1 = CALL_EXPR_ARG (exp, 1);
7045 op0 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7046 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7048 if (!CONST_INT_P (op0)
7049 || !(UNSIGNED_INT3 (INTVAL (op0))))
7050 error ("operand 1 should be an unsigned 3-bit immediate");
7052 mode1 = insn_data[icode].operand[1].mode;
7054 if (icode == CODE_FOR_vdiwr_insn)
7055 target = gen_rtx_REG (SImode,
7056 ARC_FIRST_SIMD_DMA_CONFIG_IN_REG + INTVAL (op0));
7057 else if (icode == CODE_FOR_vdowr_insn)
7058 target = gen_rtx_REG (SImode,
7059 ARC_FIRST_SIMD_DMA_CONFIG_OUT_REG + INTVAL (op0));
7060 else
7061 gcc_unreachable ();
7063 if (!insn_data[icode].operand[2].predicate (op1, mode1))
7064 op1 = copy_to_mode_reg (mode1, op1);
7066 pat = GEN_FCN (icode) (target, op1);
7067 if (!pat)
7068 return NULL_RTX;
7070 emit_insn (pat);
7071 return NULL_RTX;
7073 case ARC_BUILTIN_VASRW:
7074 case ARC_BUILTIN_VSR8:
7075 case ARC_BUILTIN_VSR8AW:
7076 arg0 = CALL_EXPR_ARG (exp, 0);
7077 arg1 = CALL_EXPR_ARG (exp, 1);
7078 op0 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7079 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7080 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7082 target = gen_reg_rtx (V8HImode);
7083 mode0 = insn_data[icode].operand[1].mode;
7084 mode1 = insn_data[icode].operand[2].mode;
7086 if (!insn_data[icode].operand[1].predicate (op0, mode0))
7087 op0 = copy_to_mode_reg (mode0, op0);
7089 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7090 || !(UNSIGNED_INT3 (INTVAL (op1))))
7091 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7093 pat = GEN_FCN (icode) (target, op0, op1, op2);
7094 if (!pat)
7095 return NULL_RTX;
7097 emit_insn (pat);
7098 return target;
7100 case ARC_BUILTIN_VLD32WH:
7101 case ARC_BUILTIN_VLD32WL:
7102 case ARC_BUILTIN_VLD64:
7103 case ARC_BUILTIN_VLD32:
7104 rtx src_vreg;
7105 icode = d->icode;
7106 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7107 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7108 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
7110 src_vreg = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7111 op0 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7112 op1 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7113 op2 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7115 /* target <- src vreg. */
7116 emit_insn (gen_move_insn (target, src_vreg));
7118 /* target <- vec_concat: target, mem (Ib, u8). */
7119 mode0 = insn_data[icode].operand[3].mode;
7120 mode1 = insn_data[icode].operand[1].mode;
7122 if ((!insn_data[icode].operand[3].predicate (op0, mode0))
7123 || !(UNSIGNED_INT3 (INTVAL (op0))))
7124 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7126 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7127 || !(UNSIGNED_INT8 (INTVAL (op1))))
7128 error ("operand 2 should be an unsigned 8-bit value");
7130 pat = GEN_FCN (icode) (target, op1, op2, op0);
7131 if (!pat)
7132 return NULL_RTX;
7134 emit_insn (pat);
7135 return target;
7137 case ARC_BUILTIN_VLD64W:
7138 case ARC_BUILTIN_VLD128:
7139 arg0 = CALL_EXPR_ARG (exp, 0); /* dest vreg. */
7140 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7142 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7143 op1 = expand_expr (arg0, NULL_RTX, SImode, EXPAND_NORMAL);
7144 op2 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7146 /* target <- src vreg. */
7147 target = gen_reg_rtx (V8HImode);
7149 /* target <- vec_concat: target, mem (Ib, u8). */
7150 mode0 = insn_data[icode].operand[1].mode;
7151 mode1 = insn_data[icode].operand[2].mode;
7152 mode2 = insn_data[icode].operand[3].mode;
7154 if ((!insn_data[icode].operand[2].predicate (op1, mode1))
7155 || !(UNSIGNED_INT3 (INTVAL (op1))))
7156 error ("operand 1 should be an unsigned 3-bit value (I0-I7)");
7158 if ((!insn_data[icode].operand[3].predicate (op2, mode2))
7159 || !(UNSIGNED_INT8 (INTVAL (op2))))
7160 error ("operand 2 should be an unsigned 8-bit value");
7162 pat = GEN_FCN (icode) (target, op0, op1, op2);
7164 if (!pat)
7165 return NULL_RTX;
7167 emit_insn (pat);
7168 return target;
7170 case ARC_BUILTIN_VST128:
7171 case ARC_BUILTIN_VST64:
7172 arg0 = CALL_EXPR_ARG (exp, 0); /* src vreg. */
7173 arg1 = CALL_EXPR_ARG (exp, 1); /* [I]0-7. */
7174 arg2 = CALL_EXPR_ARG (exp, 2); /* u8. */
7176 op0 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7177 op1 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7178 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7179 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7181 mode0 = insn_data[icode].operand[0].mode;
7182 mode1 = insn_data[icode].operand[1].mode;
7183 mode2 = insn_data[icode].operand[2].mode;
7184 mode3 = insn_data[icode].operand[3].mode;
7186 if ((!insn_data[icode].operand[1].predicate (op1, mode1))
7187 || !(UNSIGNED_INT3 (INTVAL (op1))))
7188 error ("operand 2 should be an unsigned 3-bit value (I0-I7)");
7190 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7191 || !(UNSIGNED_INT8 (INTVAL (op2))))
7192 error ("operand 3 should be an unsigned 8-bit value");
7194 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7195 op3 = copy_to_mode_reg (mode3, op3);
7197 pat = GEN_FCN (icode) (op0, op1, op2, op3);
7198 if (!pat)
7199 return NULL_RTX;
7201 emit_insn (pat);
7202 return NULL_RTX;
7204 case ARC_BUILTIN_VST16_N:
7205 case ARC_BUILTIN_VST32_N:
7206 arg0 = CALL_EXPR_ARG (exp, 0); /* source vreg. */
7207 arg1 = CALL_EXPR_ARG (exp, 1); /* u3. */
7208 arg2 = CALL_EXPR_ARG (exp, 2); /* [I]0-7. */
7209 arg3 = CALL_EXPR_ARG (exp, 3); /* u8. */
7211 op0 = expand_expr (arg3, NULL_RTX, SImode, EXPAND_NORMAL);
7212 op1 = gen_rtx_REG (V8HImode, ARC_FIRST_SIMD_VR_REG);
7213 op2 = expand_expr (arg2, NULL_RTX, SImode, EXPAND_NORMAL);
7214 op3 = expand_expr (arg0, NULL_RTX, V8HImode, EXPAND_NORMAL);
7215 op4 = expand_expr (arg1, NULL_RTX, SImode, EXPAND_NORMAL);
7217 mode0 = insn_data[icode].operand[0].mode;
7218 mode2 = insn_data[icode].operand[2].mode;
7219 mode3 = insn_data[icode].operand[3].mode;
7220 mode4 = insn_data[icode].operand[4].mode;
7222 /* Do some correctness checks for the operands. */
7223 if ((!insn_data[icode].operand[0].predicate (op0, mode0))
7224 || !(UNSIGNED_INT8 (INTVAL (op0))))
7225 error ("operand 4 should be an unsigned 8-bit value (0-255)");
7227 if ((!insn_data[icode].operand[2].predicate (op2, mode2))
7228 || !(UNSIGNED_INT3 (INTVAL (op2))))
7229 error ("operand 3 should be an unsigned 3-bit value (I0-I7)");
7231 if (!insn_data[icode].operand[3].predicate (op3, mode3))
7232 op3 = copy_to_mode_reg (mode3, op3);
7234 if ((!insn_data[icode].operand[4].predicate (op4, mode4))
7235 || !(UNSIGNED_INT3 (INTVAL (op4))))
7236 error ("operand 2 should be an unsigned 3-bit value (subreg 0-7)");
7237 else if (icode == CODE_FOR_vst32_n_insn
7238 && ((INTVAL (op4) % 2) != 0))
7239 error ("operand 2 should be an even 3-bit value (subreg 0,2,4,6)");
7241 pat = GEN_FCN (icode) (op0, op1, op2, op3, op4);
7242 if (!pat)
7243 return NULL_RTX;
7245 emit_insn (pat);
7246 return NULL_RTX;
7248 default:
7249 break;
7252 /* 2nd part: Expand regular builtins. */
7253 if (icode == 0)
7254 internal_error ("bad builtin fcode");
7256 nonvoid = TREE_TYPE (TREE_TYPE (fndecl)) != void_type_node;
7257 j = 0;
7259 if (nonvoid)
7261 if (target == NULL_RTX
7262 || GET_MODE (target) != tmode
7263 || !insn_data[icode].operand[0].predicate (target, tmode))
7265 target = gen_reg_rtx (tmode);
7267 xop[j++] = target;
7270 gcc_assert (n_args <= 4);
7271 for (i = 0; i < n_args; i++, j++)
7273 tree arg = CALL_EXPR_ARG (exp, i);
7274 machine_mode mode = insn_data[icode].operand[j].mode;
7275 rtx op = expand_expr (arg, NULL_RTX, mode, EXPAND_NORMAL);
7276 machine_mode opmode = GET_MODE (op);
7277 char c = insn_data[icode].operand[j].constraint[0];
7279 /* SIMD extension requires exact immediate operand match. */
7280 if ((id > ARC_BUILTIN_SIMD_BEGIN)
7281 && (id < ARC_BUILTIN_SIMD_END)
7282 && (c != 'v')
7283 && (c != 'r'))
7285 if (!CONST_INT_P (op))
7286 error ("builtin requires an immediate for operand %d", j);
7287 switch (c)
7289 case 'L':
7290 if (!satisfies_constraint_L (op))
7291 error ("operand %d should be a 6 bit unsigned immediate", j);
7292 break;
7293 case 'P':
7294 if (!satisfies_constraint_P (op))
7295 error ("operand %d should be a 8 bit unsigned immediate", j);
7296 break;
7297 case 'K':
7298 if (!satisfies_constraint_K (op))
7299 error ("operand %d should be a 3 bit unsigned immediate", j);
7300 break;
7301 default:
7302 error ("unknown builtin immediate operand type for operand %d",
7307 if (CONST_INT_P (op))
7308 opmode = mode;
7310 if ((opmode == SImode) && (mode == HImode))
7312 opmode = HImode;
7313 op = gen_lowpart (HImode, op);
7316 /* In case the insn wants input operands in modes different from
7317 the result, abort. */
7318 gcc_assert (opmode == mode || opmode == VOIDmode);
7320 if (!insn_data[icode].operand[i + nonvoid].predicate (op, mode))
7321 op = copy_to_mode_reg (mode, op);
7323 xop[j] = op;
7326 pat = apply_GEN_FCN (icode, xop);
7327 if (pat == NULL_RTX)
7328 return NULL_RTX;
7330 emit_insn (pat);
7332 if (nonvoid)
7333 return target;
7334 else
7335 return const0_rtx;
7338 /* Implement TARGET_FOLD_BUILTIN. */
7340 static tree
7341 arc_fold_builtin (tree fndecl, int n_args ATTRIBUTE_UNUSED, tree *arg,
7342 bool ignore ATTRIBUTE_UNUSED)
7344 unsigned int fcode = DECL_MD_FUNCTION_CODE (fndecl);
7346 switch (fcode)
7348 default:
7349 break;
7351 case ARC_BUILTIN_SWAP:
7352 return fold_build2 (LROTATE_EXPR, integer_type_node, arg[0],
7353 build_int_cst (integer_type_node, 16));
7355 case ARC_BUILTIN_NORM:
7356 if (TREE_CODE (arg[0]) == INTEGER_CST
7357 && !TREE_OVERFLOW (arg[0]))
7359 wide_int arg0 = wi::to_wide (arg[0], 32);
7360 wide_int result = wi::shwi (wi::clrsb (arg0), 32);
7361 return wide_int_to_tree (integer_type_node, result);
7363 break;
7365 case ARC_BUILTIN_NORMW:
7366 if (TREE_CODE (arg[0]) == INTEGER_CST
7367 && !TREE_OVERFLOW (arg[0]))
7369 wide_int arg0 = wi::to_wide (arg[0], 16);
7370 wide_int result = wi::shwi (wi::clrsb (arg0), 32);
7371 return wide_int_to_tree (integer_type_node, result);
7373 break;
7375 return NULL_TREE;
7378 /* Returns true if the operands[opno] is a valid compile-time constant to be
7379 used as register number in the code for builtins. Else it flags an error
7380 and returns false. */
7382 bool
7383 check_if_valid_regno_const (rtx *operands, int opno)
7386 switch (GET_CODE (operands[opno]))
7388 case SYMBOL_REF :
7389 case CONST :
7390 case CONST_INT :
7391 return true;
7392 default:
7393 error ("register number must be a compile-time constant. "
7394 "Try giving higher optimization levels");
7395 break;
7397 return false;
7400 /* Return true if it is ok to make a tail-call to DECL. */
7402 static bool
7403 arc_function_ok_for_sibcall (tree decl,
7404 tree exp ATTRIBUTE_UNUSED)
7406 tree attrs = NULL_TREE;
7408 /* Never tailcall from an ISR routine - it needs a special exit sequence. */
7409 if (ARC_INTERRUPT_P (arc_compute_function_type (cfun)))
7410 return false;
7412 if (decl)
7414 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
7416 if (lookup_attribute ("jli_always", attrs))
7417 return false;
7418 if (lookup_attribute ("jli_fixed", attrs))
7419 return false;
7420 if (lookup_attribute ("secure_call", attrs))
7421 return false;
7424 /* Everything else is ok. */
7425 return true;
7428 /* Output code to add DELTA to the first argument, and then jump
7429 to FUNCTION. Used for C++ multiple inheritance. */
7431 static void
7432 arc_output_mi_thunk (FILE *file, tree thunk ATTRIBUTE_UNUSED,
7433 HOST_WIDE_INT delta,
7434 HOST_WIDE_INT vcall_offset,
7435 tree function)
7437 const char *fnname = IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (thunk));
7438 int mi_delta = delta;
7439 const char *const mi_op = mi_delta < 0 ? "sub" : "add";
7440 int shift = 0;
7441 int this_regno
7442 = aggregate_value_p (TREE_TYPE (TREE_TYPE (function)), function) ? 1 : 0;
7443 rtx fnaddr;
7445 assemble_start_function (thunk, fnname);
7447 if (mi_delta < 0)
7448 mi_delta = - mi_delta;
7450 /* Add DELTA. When possible use a plain add, otherwise load it into
7451 a register first. */
7453 while (mi_delta != 0)
7455 if ((mi_delta & (3 << shift)) == 0)
7456 shift += 2;
7457 else
7459 asm_fprintf (file, "\t%s\t%s, %s, %d\n",
7460 mi_op, reg_names[this_regno], reg_names[this_regno],
7461 mi_delta & (0xff << shift));
7462 mi_delta &= ~(0xff << shift);
7463 shift += 8;
7467 /* If needed, add *(*THIS + VCALL_OFFSET) to THIS. */
7468 if (vcall_offset != 0)
7470 /* ld r12,[this] --> temp = *this
7471 add r12,r12,vcall_offset --> temp = *(*this + vcall_offset)
7472 ld r12,[r12]
7473 add this,this,r12 --> this+ = *(*this + vcall_offset) */
7474 asm_fprintf (file, "\tld\t%s, [%s]\n",
7475 ARC_TEMP_SCRATCH_REG, reg_names[this_regno]);
7476 asm_fprintf (file, "\tadd\t%s, %s, " HOST_WIDE_INT_PRINT_DEC "\n",
7477 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG, vcall_offset);
7478 asm_fprintf (file, "\tld\t%s, [%s]\n",
7479 ARC_TEMP_SCRATCH_REG, ARC_TEMP_SCRATCH_REG);
7480 asm_fprintf (file, "\tadd\t%s, %s, %s\n", reg_names[this_regno],
7481 reg_names[this_regno], ARC_TEMP_SCRATCH_REG);
7484 fnaddr = XEXP (DECL_RTL (function), 0);
7486 if (arc_is_longcall_p (fnaddr))
7488 if (flag_pic)
7490 asm_fprintf (file, "\tld\t%s, [pcl, @",
7491 ARC_TEMP_SCRATCH_REG);
7492 assemble_name (file, XSTR (fnaddr, 0));
7493 fputs ("@gotpc]\n", file);
7494 asm_fprintf (file, "\tj\t[%s]", ARC_TEMP_SCRATCH_REG);
7496 else
7498 fputs ("\tj\t@", file);
7499 assemble_name (file, XSTR (fnaddr, 0));
7502 else
7504 fputs ("\tb\t@", file);
7505 assemble_name (file, XSTR (fnaddr, 0));
7506 if (flag_pic)
7507 fputs ("@plt\n", file);
7509 fputc ('\n', file);
7510 assemble_end_function (thunk, fnname);
7513 /* Return true if a 32 bit "long_call" should be generated for
7514 this calling SYM_REF. We generate a long_call if the function:
7516 a. has an __attribute__((long call))
7517 or b. the -mlong-calls command line switch has been specified
7519 However we do not generate a long call if the function has an
7520 __attribute__ ((short_call)) or __attribute__ ((medium_call))
7522 This function will be called by C fragments contained in the machine
7523 description file. */
7525 bool
7526 arc_is_longcall_p (rtx sym_ref)
7528 if (GET_CODE (sym_ref) != SYMBOL_REF)
7529 return false;
7531 return (SYMBOL_REF_LONG_CALL_P (sym_ref)
7532 || (TARGET_LONG_CALLS_SET
7533 && !SYMBOL_REF_SHORT_CALL_P (sym_ref)
7534 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7538 /* Likewise for short calls. */
7540 bool
7541 arc_is_shortcall_p (rtx sym_ref)
7543 if (GET_CODE (sym_ref) != SYMBOL_REF)
7544 return false;
7546 return (SYMBOL_REF_SHORT_CALL_P (sym_ref)
7547 || (!TARGET_LONG_CALLS_SET && !TARGET_MEDIUM_CALLS
7548 && !SYMBOL_REF_LONG_CALL_P (sym_ref)
7549 && !SYMBOL_REF_MEDIUM_CALL_P (sym_ref)));
7553 /* Worker function for TARGET_RETURN_IN_MEMORY. */
7555 static bool
7556 arc_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED)
7558 if (AGGREGATE_TYPE_P (type) || TREE_ADDRESSABLE (type))
7559 return true;
7560 else
7562 HOST_WIDE_INT size = int_size_in_bytes (type);
7563 return (size == -1 || size > (TARGET_V2 ? 16 : 8));
7567 static bool
7568 arc_pass_by_reference (cumulative_args_t, const function_arg_info &arg)
7570 return (arg.type != 0
7571 && (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST
7572 || TREE_ADDRESSABLE (arg.type)));
7575 /* Implement TARGET_CAN_USE_DOLOOP_P. */
7577 static bool
7578 arc_can_use_doloop_p (const widest_int &,
7579 const widest_int &iterations_max,
7580 unsigned int loop_depth, bool entered_at_top)
7582 /* Considering limitations in the hardware, only use doloop
7583 for innermost loops which must be entered from the top. */
7584 if (loop_depth > 1 || !entered_at_top)
7585 return false;
7587 /* Check for lp_count width boundary. */
7588 if (arc_lpcwidth != 32
7589 && (wi::gtu_p (iterations_max, ((1 << arc_lpcwidth) - 1))
7590 || wi::eq_p (iterations_max, 0)))
7591 return false;
7592 return true;
7595 /* NULL if INSN insn is valid within a low-overhead loop. Otherwise
7596 return why doloop cannot be applied. */
7598 static const char *
7599 arc_invalid_within_doloop (const rtx_insn *insn)
7601 if (CALL_P (insn))
7602 return "Function call in the loop.";
7604 /* FIXME! add here all the ZOL exceptions. */
7605 return NULL;
7608 /* Return the next active insn, skiping the inline assembly code. */
7610 static rtx_insn *
7611 arc_active_insn (rtx_insn *insn)
7613 while (insn)
7615 insn = NEXT_INSN (insn);
7616 if (insn == 0
7617 || (active_insn_p (insn)
7618 && NONDEBUG_INSN_P (insn)
7619 && !NOTE_P (insn)
7620 && GET_CODE (PATTERN (insn)) != UNSPEC_VOLATILE
7621 && GET_CODE (PATTERN (insn)) != PARALLEL))
7622 break;
7624 return insn;
7627 /* Search for a sequence made out of two stores and a given number of
7628 loads, insert a nop if required. */
7630 static void
7631 check_store_cacheline_hazard (void)
7633 rtx_insn *insn, *succ0, *insn1;
7634 bool found = false;
7636 for (insn = get_insns (); insn; insn = arc_active_insn (insn))
7638 succ0 = arc_active_insn (insn);
7640 if (!succ0)
7641 return;
7643 if (!single_set (insn))
7644 continue;
7646 if ((get_attr_type (insn) != TYPE_STORE))
7647 continue;
7649 /* Found at least two consecutive stores. Goto the end of the
7650 store sequence. */
7651 for (insn1 = succ0; insn1; insn1 = arc_active_insn (insn1))
7652 if (!single_set (insn1) || get_attr_type (insn1) != TYPE_STORE)
7653 break;
7655 /* Save were we are. */
7656 succ0 = insn1;
7658 /* Now, check the next two instructions for the following cases:
7659 1. next instruction is a LD => insert 2 nops between store
7660 sequence and load.
7661 2. next-next instruction is a LD => inset 1 nop after the store
7662 sequence. */
7663 if (insn1 && single_set (insn1)
7664 && (get_attr_type (insn1) == TYPE_LOAD))
7666 found = true;
7667 emit_insn_before (gen_nopv (), insn1);
7668 emit_insn_before (gen_nopv (), insn1);
7670 else
7672 if (insn1 && (get_attr_type (insn1) == TYPE_COMPARE))
7674 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in
7675 reorg, so it is safe to reuse it for avoiding the
7676 current compare insn to be part of a BRcc
7677 optimization. */
7678 add_reg_note (insn1, REG_SAVE_NOTE, GEN_INT (3));
7680 insn1 = arc_active_insn (insn1);
7681 if (insn1 && single_set (insn1)
7682 && (get_attr_type (insn1) == TYPE_LOAD))
7684 found = true;
7685 emit_insn_before (gen_nopv (), insn1);
7689 if (found)
7691 insn = insn1;
7692 found = false;
7694 else
7695 insn = succ0;
7699 /* Return true if a load instruction (CONSUMER) uses the same address as a
7700 store instruction (PRODUCER). This function is used to avoid st/ld
7701 address hazard in ARC700 cores. */
7703 static bool
7704 arc_store_addr_hazard_internal_p (rtx_insn* producer, rtx_insn* consumer)
7706 rtx in_set, out_set;
7707 rtx out_addr, in_addr;
7709 if (!producer)
7710 return false;
7712 if (!consumer)
7713 return false;
7715 /* Peel the producer and the consumer for the address. */
7716 out_set = single_set (producer);
7717 if (out_set)
7719 out_addr = SET_DEST (out_set);
7720 if (!out_addr)
7721 return false;
7722 if (GET_CODE (out_addr) == ZERO_EXTEND
7723 || GET_CODE (out_addr) == SIGN_EXTEND)
7724 out_addr = XEXP (out_addr, 0);
7726 if (!MEM_P (out_addr))
7727 return false;
7729 in_set = single_set (consumer);
7730 if (in_set)
7732 in_addr = SET_SRC (in_set);
7733 if (!in_addr)
7734 return false;
7735 if (GET_CODE (in_addr) == ZERO_EXTEND
7736 || GET_CODE (in_addr) == SIGN_EXTEND)
7737 in_addr = XEXP (in_addr, 0);
7739 if (!MEM_P (in_addr))
7740 return false;
7741 /* Get rid of the MEM and check if the addresses are
7742 equivalent. */
7743 in_addr = XEXP (in_addr, 0);
7744 out_addr = XEXP (out_addr, 0);
7746 return exp_equiv_p (in_addr, out_addr, 0, true);
7749 return false;
7752 /* Return TRUE is we have an store address hazard. */
7754 bool
7755 arc_store_addr_hazard_p (rtx_insn* producer, rtx_insn* consumer)
7757 if (TARGET_ARC700 && (arc_tune != ARC_TUNE_ARC7XX))
7758 return true;
7759 return arc_store_addr_hazard_internal_p (producer, consumer);
7762 /* Return length adjustment for INSN.
7763 For ARC600:
7764 A write to a core reg greater or equal to 32 must not be immediately
7765 followed by a use. Anticipate the length requirement to insert a nop
7766 between PRED and SUCC to prevent a hazard. */
7768 static int
7769 arc600_corereg_hazard (rtx_insn *pred, rtx_insn *succ)
7771 if (!TARGET_ARC600)
7772 return 0;
7773 if (GET_CODE (PATTERN (pred)) == SEQUENCE)
7774 pred = as_a <rtx_sequence *> (PATTERN (pred))->insn (1);
7775 if (GET_CODE (PATTERN (succ)) == SEQUENCE)
7776 succ = as_a <rtx_sequence *> (PATTERN (succ))->insn (0);
7777 if (recog_memoized (pred) == CODE_FOR_mulsi_600
7778 || recog_memoized (pred) == CODE_FOR_umul_600
7779 || recog_memoized (pred) == CODE_FOR_mac_600
7780 || recog_memoized (pred) == CODE_FOR_mul64_600
7781 || recog_memoized (pred) == CODE_FOR_mac64_600
7782 || recog_memoized (pred) == CODE_FOR_umul64_600
7783 || recog_memoized (pred) == CODE_FOR_umac64_600)
7784 return 0;
7785 subrtx_iterator::array_type array;
7786 FOR_EACH_SUBRTX (iter, array, PATTERN (pred), NONCONST)
7788 const_rtx x = *iter;
7789 switch (GET_CODE (x))
7791 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
7792 break;
7793 default:
7794 /* This is also fine for PRE/POST_MODIFY, because they
7795 contain a SET. */
7796 continue;
7798 rtx dest = XEXP (x, 0);
7799 /* Check if this sets a an extension register. N.B. we use 61 for the
7800 condition codes, which is definitely not an extension register. */
7801 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61
7802 /* Check if the same register is used by the PAT. */
7803 && (refers_to_regno_p
7804 (REGNO (dest),
7805 REGNO (dest) + (GET_MODE_SIZE (GET_MODE (dest)) + 3) / 4U,
7806 PATTERN (succ), 0)))
7807 return 4;
7809 return 0;
7812 /* For ARC600:
7813 A write to a core reg greater or equal to 32 must not be immediately
7814 followed by a use. Anticipate the length requirement to insert a nop
7815 between PRED and SUCC to prevent a hazard. */
7818 arc_hazard (rtx_insn *pred, rtx_insn *succ)
7820 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7821 return 0;
7823 if (TARGET_ARC600)
7824 return arc600_corereg_hazard (pred, succ);
7826 return 0;
7829 /* When compiling for release 310a, insert a nop before any
7830 conditional jump. */
7832 static int
7833 arc_check_release31a (rtx_insn *pred, rtx_insn *succ)
7835 if (!pred || !INSN_P (pred) || !succ || !INSN_P (succ))
7836 return 0;
7838 if (!JUMP_P (pred) && !single_set (pred))
7839 return 0;
7841 if (!JUMP_P (succ) && !single_set (succ))
7842 return 0;
7844 if (TARGET_HS && (arc_tune == ARC_TUNE_ARCHS4X_REL31A))
7845 switch (get_attr_type (pred))
7847 case TYPE_STORE:
7848 switch (get_attr_type (succ))
7850 case TYPE_BRCC:
7851 case TYPE_BRCC_NO_DELAY_SLOT:
7852 case TYPE_LOOP_END:
7853 return 1;
7854 default:
7855 break;
7857 break;
7858 case TYPE_BRCC:
7859 case TYPE_BRCC_NO_DELAY_SLOT:
7860 case TYPE_LOOP_END:
7861 if (get_attr_type (succ) == TYPE_STORE)
7862 return 1;
7863 break;
7864 default:
7865 break;
7868 return 0;
7871 /* The same functionality as arc_hazard. It is called in machine
7872 reorg before any other optimization. Hence, the NOP size is taken
7873 into account when doing branch shortening. */
7875 static void
7876 workaround_arc_anomaly (void)
7878 rtx_insn *insn, *succ0;
7880 /* For any architecture: call arc_hazard here. */
7881 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
7883 succ0 = next_real_insn (insn);
7884 if (arc_hazard (insn, succ0) || arc_check_release31a (insn, succ0))
7885 emit_insn_before (gen_nopv (), succ0);
7888 if (!TARGET_ARC700)
7889 return;
7891 /* Old A7 are suffering of a cache hazard, and we need to insert two
7892 nops between any sequence of stores and a load. */
7893 if (arc_tune != ARC_TUNE_ARC7XX)
7894 check_store_cacheline_hazard ();
7897 /* A callback for the hw-doloop pass. Called when a loop we have discovered
7898 turns out not to be optimizable; we have to split the loop_end pattern into
7899 a subtract and a test. */
7901 static void
7902 hwloop_fail (hwloop_info loop)
7904 rtx test;
7905 rtx insn = loop->loop_end;
7907 if (TARGET_DBNZ
7908 && (loop->length && (loop->length <= ARC_MAX_LOOP_LENGTH))
7909 && REG_P (loop->iter_reg))
7911 /* TARGET_V2 core3 has dbnz instructions. */
7912 test = gen_dbnz (loop->iter_reg, loop->start_label);
7913 insn = emit_jump_insn_before (test, loop->loop_end);
7915 else if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg) == LP_COUNT))
7917 /* We have the lp_count as loop iterator, try to use it. */
7918 emit_insn_before (gen_loop_fail (), loop->loop_end);
7919 test = gen_rtx_NE (VOIDmode, gen_rtx_REG (CC_ZNmode, CC_REG),
7920 const0_rtx);
7921 test = gen_rtx_IF_THEN_ELSE (VOIDmode, test,
7922 gen_rtx_LABEL_REF (Pmode, loop->start_label),
7923 pc_rtx);
7924 insn = emit_jump_insn_before (gen_rtx_SET (pc_rtx, test),
7925 loop->loop_end);
7927 else
7929 emit_insn_before (gen_addsi3 (loop->iter_reg,
7930 loop->iter_reg,
7931 constm1_rtx),
7932 loop->loop_end);
7933 test = gen_rtx_NE (VOIDmode, loop->iter_reg, const0_rtx);
7934 insn = emit_jump_insn_before (gen_cbranchsi4 (test,
7935 loop->iter_reg,
7936 const0_rtx,
7937 loop->start_label),
7938 loop->loop_end);
7940 JUMP_LABEL (insn) = loop->start_label;
7941 LABEL_NUSES (loop->start_label)++;
7942 delete_insn (loop->loop_end);
7945 /* Return the next insn after INSN that is not a NOTE, but stop the
7946 search before we enter another basic block. This routine does not
7947 look inside SEQUENCEs. */
7949 static rtx_insn *
7950 next_nonnote_insn_bb (rtx_insn *insn)
7952 while (insn)
7954 insn = NEXT_INSN (insn);
7955 if (insn == 0 || !NOTE_P (insn))
7956 break;
7957 if (NOTE_INSN_BASIC_BLOCK_P (insn))
7958 return NULL;
7961 return insn;
7964 /* Optimize LOOP. */
7966 static bool
7967 hwloop_optimize (hwloop_info loop)
7969 int i;
7970 edge entry_edge;
7971 basic_block entry_bb, bb;
7972 rtx iter_reg;
7973 rtx_insn *insn, *seq, *entry_after, *last_insn, *end_label;
7974 unsigned int length;
7975 bool need_fix = false;
7976 rtx lp_reg = gen_rtx_REG (SImode, LP_COUNT);
7978 if (loop->depth > 1)
7980 if (dump_file)
7981 fprintf (dump_file, ";; loop %d is not innermost\n",
7982 loop->loop_no);
7983 return false;
7986 if (!loop->incoming_dest)
7988 if (dump_file)
7989 fprintf (dump_file, ";; loop %d has more than one entry\n",
7990 loop->loop_no);
7991 return false;
7994 if (loop->incoming_dest != loop->head)
7996 if (dump_file)
7997 fprintf (dump_file, ";; loop %d is not entered from head\n",
7998 loop->loop_no);
7999 return false;
8002 if (loop->has_call || loop->has_asm)
8004 if (dump_file)
8005 fprintf (dump_file, ";; loop %d has invalid insn\n",
8006 loop->loop_no);
8007 return false;
8010 /* Scan all the blocks to make sure they don't use iter_reg. */
8011 if (loop->iter_reg_used || loop->iter_reg_used_outside)
8013 if (dump_file)
8014 fprintf (dump_file, ";; loop %d uses iterator\n",
8015 loop->loop_no);
8016 return false;
8019 /* Check if start_label appears before doloop_end. */
8020 length = 0;
8021 for (insn = loop->start_label;
8022 insn && insn != loop->loop_end;
8023 insn = NEXT_INSN (insn))
8025 length += NONDEBUG_INSN_P (insn) ? get_attr_length (insn) : 0;
8026 if (JUMP_TABLES_IN_TEXT_SECTION
8027 && JUMP_TABLE_DATA_P (insn))
8029 if (dump_file)
8030 fprintf (dump_file, ";; loop %d has a jump table\n",
8031 loop->loop_no);
8032 return false;
8036 if (!insn)
8038 if (dump_file)
8039 fprintf (dump_file, ";; loop %d start_label not before loop_end\n",
8040 loop->loop_no);
8041 return false;
8044 loop->length = length;
8045 if (loop->length > ARC_MAX_LOOP_LENGTH)
8047 if (dump_file)
8048 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
8049 return false;
8051 else if (!loop->length)
8053 if (dump_file)
8054 fprintf (dump_file, ";; loop %d is empty\n", loop->loop_no);
8055 return false;
8058 /* Check if we use a register or not. */
8059 if (!REG_P (loop->iter_reg))
8061 if (dump_file)
8062 fprintf (dump_file, ";; loop %d iterator is MEM\n",
8063 loop->loop_no);
8064 return false;
8067 /* Check if we use a register or not. */
8068 if (!REG_P (loop->iter_reg))
8070 if (dump_file)
8071 fprintf (dump_file, ";; loop %d iterator is MEM\n",
8072 loop->loop_no);
8073 return false;
8076 /* Check if loop register is lpcount. */
8077 if (REG_P (loop->iter_reg) && (REGNO (loop->iter_reg)) != LP_COUNT)
8079 if (dump_file)
8080 fprintf (dump_file, ";; loop %d doesn't use lp_count as loop"
8081 " iterator\n",
8082 loop->loop_no);
8083 /* This loop doesn't use the lp_count, check though if we can
8084 fix it. */
8085 if (TEST_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT)
8086 /* In very unique cases we may have LP_COUNT alive. */
8087 || (loop->incoming_src
8088 && REGNO_REG_SET_P (df_get_live_out (loop->incoming_src),
8089 LP_COUNT)))
8091 if (dump_file)
8092 fprintf (dump_file, ";; loop %d, lp_count is alive", loop->loop_no);
8093 return false;
8095 else
8096 need_fix = true;
8099 /* Check for control like instruction as the last instruction of a
8100 ZOL. */
8101 bb = loop->tail;
8102 last_insn = PREV_INSN (loop->loop_end);
8104 while (1)
8106 for (; last_insn != BB_HEAD (bb);
8107 last_insn = PREV_INSN (last_insn))
8108 if (NONDEBUG_INSN_P (last_insn))
8109 break;
8111 if (last_insn != BB_HEAD (bb))
8112 break;
8114 if (single_pred_p (bb)
8115 && single_pred_edge (bb)->flags & EDGE_FALLTHRU
8116 && single_pred (bb) != ENTRY_BLOCK_PTR_FOR_FN (cfun))
8118 bb = single_pred (bb);
8119 last_insn = BB_END (bb);
8120 continue;
8122 else
8124 last_insn = NULL;
8125 break;
8129 if (!last_insn)
8131 if (dump_file)
8132 fprintf (dump_file, ";; loop %d has no last instruction\n",
8133 loop->loop_no);
8134 return false;
8137 if ((TARGET_ARC600_FAMILY || TARGET_HS)
8138 && INSN_P (last_insn)
8139 && (JUMP_P (last_insn) || CALL_P (last_insn)
8140 || GET_CODE (PATTERN (last_insn)) == SEQUENCE
8141 /* At this stage we can have (insn (clobber (mem:BLK
8142 (reg)))) instructions, ignore them. */
8143 || (GET_CODE (PATTERN (last_insn)) != CLOBBER
8144 && (get_attr_type (last_insn) == TYPE_BRCC
8145 || get_attr_type (last_insn) == TYPE_BRCC_NO_DELAY_SLOT))))
8147 if (loop->length + 2 > ARC_MAX_LOOP_LENGTH)
8149 if (dump_file)
8150 fprintf (dump_file, ";; loop %d too long\n", loop->loop_no);
8151 return false;
8153 if (dump_file)
8154 fprintf (dump_file, ";; loop %d has a control like last insn; "
8155 "add a nop\n",
8156 loop->loop_no);
8158 last_insn = emit_insn_after (gen_nopv (), last_insn);
8161 if (LABEL_P (last_insn))
8163 if (dump_file)
8164 fprintf (dump_file, ";; loop %d has a label as last insn; "
8165 "add a nop\n",
8166 loop->loop_no);
8167 last_insn = emit_insn_after (gen_nopv (), last_insn);
8170 /* SAVE_NOTE is used by haifa scheduler. However, we are after it
8171 and we can use it to indicate the last ZOL instruction cannot be
8172 part of a delay slot. */
8173 add_reg_note (last_insn, REG_SAVE_NOTE, GEN_INT (2));
8175 loop->last_insn = last_insn;
8177 /* Get the loop iteration register. */
8178 iter_reg = loop->iter_reg;
8180 gcc_assert (REG_P (iter_reg));
8182 entry_edge = NULL;
8184 FOR_EACH_VEC_SAFE_ELT (loop->incoming, i, entry_edge)
8185 if (entry_edge->flags & EDGE_FALLTHRU)
8186 break;
8188 if (entry_edge == NULL)
8190 if (dump_file)
8191 fprintf (dump_file, ";; loop %d has no fallthru edge jumping "
8192 "into the loop\n",
8193 loop->loop_no);
8194 return false;
8196 /* The loop is good. */
8197 end_label = gen_label_rtx ();
8198 loop->end_label = end_label;
8200 /* Place the zero_cost_loop_start instruction before the loop. */
8201 entry_bb = entry_edge->src;
8203 start_sequence ();
8205 if (need_fix)
8207 /* The loop uses a R-register, but the lp_count is free, thus
8208 use lp_count. */
8209 emit_insn (gen_rtx_SET (lp_reg, iter_reg));
8210 SET_HARD_REG_BIT (loop->regs_set_in_loop, LP_COUNT);
8211 iter_reg = lp_reg;
8212 if (dump_file)
8214 fprintf (dump_file, ";; fix loop %d to use lp_count\n",
8215 loop->loop_no);
8219 insn = emit_insn (gen_arc_lp (loop->start_label,
8220 loop->end_label));
8222 seq = get_insns ();
8223 end_sequence ();
8225 entry_after = BB_END (entry_bb);
8226 if (!single_succ_p (entry_bb) || vec_safe_length (loop->incoming) > 1
8227 || !entry_after)
8229 basic_block new_bb;
8230 edge e;
8231 edge_iterator ei;
8233 emit_insn_before (seq, BB_HEAD (loop->head));
8234 seq = emit_label_before (gen_label_rtx (), seq);
8235 new_bb = create_basic_block (seq, insn, entry_bb);
8236 FOR_EACH_EDGE (e, ei, loop->incoming)
8238 if (!(e->flags & EDGE_FALLTHRU))
8239 redirect_edge_and_branch_force (e, new_bb);
8240 else
8241 redirect_edge_succ (e, new_bb);
8244 make_edge (new_bb, loop->head, 0);
8246 else
8248 #if 0
8249 while (DEBUG_INSN_P (entry_after)
8250 || (NOTE_P (entry_after)
8251 && NOTE_KIND (entry_after) != NOTE_INSN_BASIC_BLOCK
8252 /* Make sure we don't split a call and its corresponding
8253 CALL_ARG_LOCATION note. */
8254 && NOTE_KIND (entry_after) != NOTE_INSN_CALL_ARG_LOCATION))
8255 entry_after = NEXT_INSN (entry_after);
8256 #endif
8257 entry_after = next_nonnote_insn_bb (entry_after);
8259 gcc_assert (entry_after);
8260 emit_insn_before (seq, entry_after);
8263 /* Insert the loop end label before the last instruction of the
8264 loop. */
8265 emit_label_after (end_label, loop->last_insn);
8266 /* Make sure we mark the begining and end label as used. */
8267 LABEL_NUSES (loop->end_label)++;
8268 LABEL_NUSES (loop->start_label)++;
8270 return true;
8273 /* A callback for the hw-doloop pass. This function examines INSN; if
8274 it is a loop_end pattern we recognize, return the reg rtx for the
8275 loop counter. Otherwise, return NULL_RTX. */
8277 static rtx
8278 hwloop_pattern_reg (rtx_insn *insn)
8280 rtx reg;
8282 if (!JUMP_P (insn) || recog_memoized (insn) != CODE_FOR_loop_end)
8283 return NULL_RTX;
8285 reg = SET_DEST (XVECEXP (PATTERN (insn), 0, 1));
8286 if (!REG_P (reg))
8287 return NULL_RTX;
8288 return reg;
8291 static struct hw_doloop_hooks arc_doloop_hooks =
8293 hwloop_pattern_reg,
8294 hwloop_optimize,
8295 hwloop_fail
8298 /* Run from machine_dependent_reorg, this pass looks for doloop_end insns
8299 and tries to rewrite the RTL of these loops so that proper Blackfin
8300 hardware loops are generated. */
8302 static void
8303 arc_reorg_loops (void)
8305 reorg_loops (true, &arc_doloop_hooks);
8308 /* Scan all calls and add symbols to be emitted in the jli section if
8309 needed. */
8311 static void
8312 jli_call_scan (void)
8314 rtx_insn *insn;
8316 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8318 if (!CALL_P (insn))
8319 continue;
8321 rtx pat = PATTERN (insn);
8322 if (GET_CODE (pat) == COND_EXEC)
8323 pat = COND_EXEC_CODE (pat);
8324 pat = XVECEXP (pat, 0, 0);
8325 if (GET_CODE (pat) == SET)
8326 pat = SET_SRC (pat);
8328 pat = XEXP (XEXP (pat, 0), 0);
8329 if (GET_CODE (pat) == SYMBOL_REF
8330 && arc_is_jli_call_p (pat))
8331 arc_add_jli_section (pat);
8335 /* Add padding if necessary to avoid a mispredict. A return could
8336 happen immediately after the function start. A call/return and
8337 return/return must be 6 bytes apart to avoid mispredict. */
8339 static void
8340 pad_return (void)
8342 rtx_insn *insn;
8343 long offset;
8345 if (!TARGET_PAD_RETURN)
8346 return;
8348 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8350 rtx_insn *prev0 = prev_active_insn (insn);
8351 bool wantlong = false;
8353 if (!INSN_P (insn) || GET_CODE (PATTERN (insn)) != SIMPLE_RETURN)
8354 continue;
8356 if (!prev0)
8358 prev0 = emit_insn_before (gen_nopv (), insn);
8359 /* REG_SAVE_NOTE is used by Haifa scheduler, we are in reorg
8360 so it is safe to reuse it for forcing a particular length
8361 for an instruction. */
8362 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8363 emit_insn_before (gen_nopv (), insn);
8364 continue;
8366 offset = get_attr_length (prev0);
8368 if (get_attr_length (prev0) == 2
8369 && get_attr_iscompact (prev0) != ISCOMPACT_TRUE)
8371 /* Force long version of the insn. */
8372 wantlong = true;
8373 offset += 2;
8376 rtx_insn *prev = prev_active_insn (prev0);
8377 if (prev)
8378 offset += get_attr_length (prev);
8380 prev = prev_active_insn (prev);
8381 if (prev)
8382 offset += get_attr_length (prev);
8384 switch (offset)
8386 case 2:
8387 prev = emit_insn_before (gen_nopv (), insn);
8388 add_reg_note (prev, REG_SAVE_NOTE, GEN_INT (1));
8389 break;
8390 case 4:
8391 emit_insn_before (gen_nopv (), insn);
8392 break;
8393 default:
8394 continue;
8397 if (wantlong)
8398 add_reg_note (prev0, REG_SAVE_NOTE, GEN_INT (1));
8400 /* Emit a blockage to avoid delay slot scheduling. */
8401 emit_insn_before (gen_blockage (), insn);
8405 static int arc_reorg_in_progress = 0;
8407 /* ARC's machince specific reorg function. */
8409 static void
8410 arc_reorg (void)
8412 rtx_insn *insn;
8413 rtx pattern;
8414 rtx pc_target;
8415 long offset;
8416 int changed;
8418 cfun->machine->arc_reorg_started = 1;
8419 arc_reorg_in_progress = 1;
8421 compute_bb_for_insn ();
8423 df_analyze ();
8425 /* Doloop optimization. */
8426 arc_reorg_loops ();
8428 workaround_arc_anomaly ();
8429 jli_call_scan ();
8430 pad_return ();
8432 /* There are cases when conditional execution is only possible after
8433 delay slot scheduling:
8435 - If a delay slot is filled with a nocond/set insn from above, the previous
8436 basic block can become elegible for conditional execution.
8437 - If a delay slot is filled with a nocond insn from the fall-through path,
8438 the branch with that delay slot can become eligble for conditional
8439 execution (however, with the same sort of data flow analysis that dbr
8440 does, we could have figured out before that we don't need to
8441 conditionalize this insn.)
8442 - If a delay slot insn is filled with an insn from the target, the
8443 target label gets its uses decremented (even deleted if falling to zero),
8444 thus possibly creating more condexec opportunities there.
8445 Therefore, we should still be prepared to apply condexec optimization on
8446 non-prepared branches if the size increase of conditionalized insns is no
8447 more than the size saved from eliminating the branch. An invocation option
8448 could also be used to reserve a bit of extra size for condbranches so that
8449 this'll work more often (could also test in arc_reorg if the block is
8450 'close enough' to be eligible for condexec to make this likely, and
8451 estimate required size increase). */
8452 /* Generate BRcc insns, by combining cmp and Bcc insns wherever possible. */
8453 if (TARGET_NO_BRCC_SET)
8454 return;
8458 init_insn_lengths();
8459 changed = 0;
8461 /* Call shorten_branches to calculate the insn lengths. */
8462 shorten_branches (get_insns());
8464 if (!INSN_ADDRESSES_SET_P())
8465 fatal_error (input_location,
8466 "insn addresses not set after shorten branches");
8468 for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
8470 rtx label;
8471 enum attr_type insn_type;
8473 /* If a non-jump insn (or a casesi jump table), continue. */
8474 if (GET_CODE (insn) != JUMP_INSN ||
8475 GET_CODE (PATTERN (insn)) == ADDR_VEC
8476 || GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
8477 continue;
8479 /* If we already have a brcc, note if it is suitable for brcc_s.
8480 Be a bit generous with the brcc_s range so that we can take
8481 advantage of any code shortening from delay slot scheduling. */
8482 if (recog_memoized (insn) == CODE_FOR_cbranchsi4_scratch)
8484 rtx pat = PATTERN (insn);
8485 rtx op = XEXP (SET_SRC (XVECEXP (pat, 0, 0)), 0);
8486 rtx *ccp = &XEXP (XVECEXP (pat, 0, 1), 0);
8488 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8489 if ((offset >= -140 && offset < 140)
8490 && rtx_equal_p (XEXP (op, 1), const0_rtx)
8491 && compact_register_operand (XEXP (op, 0), VOIDmode)
8492 && equality_comparison_operator (op, VOIDmode))
8493 PUT_MODE (*ccp, CC_Zmode);
8494 else if (GET_MODE (*ccp) == CC_Zmode)
8495 PUT_MODE (*ccp, CC_ZNmode);
8496 continue;
8498 if ((insn_type = get_attr_type (insn)) == TYPE_BRCC
8499 || insn_type == TYPE_BRCC_NO_DELAY_SLOT)
8500 continue;
8502 /* OK. so we have a jump insn. */
8503 /* We need to check that it is a bcc. */
8504 /* Bcc => set (pc) (if_then_else ) */
8505 pattern = PATTERN (insn);
8506 if (GET_CODE (pattern) != SET
8507 || GET_CODE (SET_SRC (pattern)) != IF_THEN_ELSE
8508 || ANY_RETURN_P (XEXP (SET_SRC (pattern), 1)))
8509 continue;
8511 /* Now check if the jump is beyond the s9 range. */
8512 if (CROSSING_JUMP_P (insn))
8513 continue;
8514 offset = branch_dest (insn) - INSN_ADDRESSES (INSN_UID (insn));
8516 if(offset > 253 || offset < -254)
8517 continue;
8519 pc_target = SET_SRC (pattern);
8521 /* Avoid FPU instructions. */
8522 if ((GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUmode)
8523 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPUEmode)
8524 || (GET_MODE (XEXP (XEXP (pc_target, 0), 0)) == CC_FPU_UNEQmode))
8525 continue;
8527 /* Now go back and search for the set cc insn. */
8529 label = XEXP (pc_target, 1);
8532 rtx pat;
8533 rtx_insn *scan, *link_insn = NULL;
8535 for (scan = PREV_INSN (insn);
8536 scan && GET_CODE (scan) != CODE_LABEL;
8537 scan = PREV_INSN (scan))
8539 if (! INSN_P (scan))
8540 continue;
8541 pat = PATTERN (scan);
8542 if (GET_CODE (pat) == SET
8543 && cc_register (SET_DEST (pat), VOIDmode))
8545 link_insn = scan;
8546 break;
8549 if (!link_insn)
8550 continue;
8551 else
8553 /* Check if this is a data dependency. */
8554 rtx op, cc_clob_rtx, op0, op1, brcc_insn, note;
8555 rtx cmp0, cmp1;
8557 /* Make sure we can use it for brcc insns. */
8558 if (find_reg_note (link_insn, REG_SAVE_NOTE, GEN_INT (3)))
8559 continue;
8561 /* Ok this is the set cc. copy args here. */
8562 op = XEXP (pc_target, 0);
8564 op0 = cmp0 = XEXP (SET_SRC (pat), 0);
8565 op1 = cmp1 = XEXP (SET_SRC (pat), 1);
8566 if (GET_CODE (op0) == ZERO_EXTRACT
8567 && XEXP (op0, 1) == const1_rtx
8568 && (GET_CODE (op) == EQ
8569 || GET_CODE (op) == NE))
8571 /* btst / b{eq,ne} -> bbit{0,1} */
8572 op0 = XEXP (cmp0, 0);
8573 op1 = XEXP (cmp0, 2);
8575 else if (!register_operand (op0, VOIDmode)
8576 || !general_operand (op1, VOIDmode))
8577 continue;
8578 /* Be careful not to break what cmpsfpx_raw is
8579 trying to create for checking equality of
8580 single-precision floats. */
8581 else if (TARGET_SPFP
8582 && GET_MODE (op0) == SFmode
8583 && GET_MODE (op1) == SFmode)
8584 continue;
8586 /* None of the two cmp operands should be set between the
8587 cmp and the branch. */
8588 if (reg_set_between_p (op0, link_insn, insn))
8589 continue;
8591 if (reg_set_between_p (op1, link_insn, insn))
8592 continue;
8594 /* Since the MODE check does not work, check that this is
8595 CC reg's last set location before insn, and also no
8596 instruction between the cmp and branch uses the
8597 condition codes. */
8598 if ((reg_set_between_p (SET_DEST (pat), link_insn, insn))
8599 || (reg_used_between_p (SET_DEST (pat), link_insn, insn)))
8600 continue;
8602 /* CC reg should be dead after insn. */
8603 if (!find_regno_note (insn, REG_DEAD, CC_REG))
8604 continue;
8606 op = gen_rtx_fmt_ee (GET_CODE (op),
8607 GET_MODE (op), cmp0, cmp1);
8608 /* If we create a LIMM where there was none before,
8609 we only benefit if we can avoid a scheduling bubble
8610 for the ARC600. Otherwise, we'd only forgo chances
8611 at short insn generation, and risk out-of-range
8612 branches. */
8613 if (!brcc_nolimm_operator (op, VOIDmode)
8614 && !long_immediate_operand (op1, VOIDmode)
8615 && (TARGET_ARC700
8616 || (TARGET_V2 && optimize_size)
8617 || next_active_insn (link_insn) != insn))
8618 continue;
8620 /* Emit bbit / brcc (or brcc_s if possible).
8621 CC_Zmode indicates that brcc_s is possible. */
8623 if (op0 != cmp0)
8624 cc_clob_rtx = gen_rtx_REG (CC_ZNmode, CC_REG);
8625 else if ((offset >= -140 && offset < 140)
8626 && rtx_equal_p (op1, const0_rtx)
8627 && compact_register_operand (op0, VOIDmode)
8628 && (GET_CODE (op) == EQ
8629 || GET_CODE (op) == NE))
8630 cc_clob_rtx = gen_rtx_REG (CC_Zmode, CC_REG);
8631 else
8632 cc_clob_rtx = gen_rtx_REG (CCmode, CC_REG);
8634 brcc_insn
8635 = gen_rtx_IF_THEN_ELSE (VOIDmode, op, label, pc_rtx);
8636 brcc_insn = gen_rtx_SET (pc_rtx, brcc_insn);
8637 cc_clob_rtx = gen_rtx_CLOBBER (VOIDmode, cc_clob_rtx);
8638 brcc_insn
8639 = gen_rtx_PARALLEL
8640 (VOIDmode, gen_rtvec (2, brcc_insn, cc_clob_rtx));
8641 brcc_insn = emit_jump_insn_before (brcc_insn, insn);
8643 JUMP_LABEL (brcc_insn) = JUMP_LABEL (insn);
8644 note = find_reg_note (insn, REG_BR_PROB, 0);
8645 if (note)
8647 XEXP (note, 1) = REG_NOTES (brcc_insn);
8648 REG_NOTES (brcc_insn) = note;
8650 note = find_reg_note (link_insn, REG_DEAD, op0);
8651 if (note)
8653 remove_note (link_insn, note);
8654 XEXP (note, 1) = REG_NOTES (brcc_insn);
8655 REG_NOTES (brcc_insn) = note;
8657 note = find_reg_note (link_insn, REG_DEAD, op1);
8658 if (note)
8660 XEXP (note, 1) = REG_NOTES (brcc_insn);
8661 REG_NOTES (brcc_insn) = note;
8664 changed = 1;
8666 /* Delete the bcc insn. */
8667 set_insn_deleted (insn);
8669 /* Delete the cmp insn. */
8670 set_insn_deleted (link_insn);
8675 /* Clear out insn_addresses. */
8676 INSN_ADDRESSES_FREE ();
8678 } while (changed);
8680 if (INSN_ADDRESSES_SET_P())
8681 fatal_error (input_location, "insn addresses not freed");
8683 arc_reorg_in_progress = 0;
8686 /* Check if the operands are valid for BRcc.d generation
8687 Valid Brcc.d patterns are
8688 Brcc.d b, c, s9
8689 Brcc.d b, u6, s9
8691 For cc={GT, LE, GTU, LEU}, u6=63 cannot be allowed,
8692 since they are encoded by the assembler as {GE, LT, HS, LS} 64, which
8693 does not have a delay slot
8695 Assumed precondition: Second operand is either a register or a u6 value. */
8697 bool
8698 valid_brcc_with_delay_p (rtx *operands)
8700 if (optimize_size && GET_MODE (operands[4]) == CC_Zmode)
8701 return false;
8702 return brcc_nolimm_operator (operands[0], VOIDmode);
8705 /* Implement TARGET_IN_SMALL_DATA_P. Return true if it would be safe to
8706 access DECL using %gp_rel(...)($gp). */
8708 static bool
8709 arc_in_small_data_p (const_tree decl)
8711 HOST_WIDE_INT size;
8712 tree attr;
8714 /* Only variables are going into small data area. */
8715 if (TREE_CODE (decl) != VAR_DECL)
8716 return false;
8718 if (TARGET_NO_SDATA_SET)
8719 return false;
8721 /* Disable sdata references to weak variables. */
8722 if (DECL_WEAK (decl))
8723 return false;
8725 /* Don't put constants into the small data section: we want them to
8726 be in ROM rather than RAM. */
8727 if (TREE_READONLY (decl))
8728 return false;
8730 /* To ensure -mvolatile-cache works ld.di does not have a
8731 gp-relative variant. */
8732 if (!TARGET_VOLATILE_CACHE_SET
8733 && TREE_THIS_VOLATILE (decl))
8734 return false;
8736 /* Likewise for uncached data. */
8737 attr = TYPE_ATTRIBUTES (TREE_TYPE (decl));
8738 if (lookup_attribute ("uncached", attr))
8739 return false;
8741 /* and for aux regs. */
8742 attr = DECL_ATTRIBUTES (decl);
8743 if (lookup_attribute ("aux", attr))
8744 return false;
8746 if (DECL_SECTION_NAME (decl) != 0)
8748 const char *name = DECL_SECTION_NAME (decl);
8749 if (strcmp (name, ".sdata") == 0
8750 || strcmp (name, ".sbss") == 0)
8751 return true;
8753 /* If it's not public, there's no need to put it in the small data
8754 section. */
8755 else if (TREE_PUBLIC (decl))
8757 size = int_size_in_bytes (TREE_TYPE (decl));
8758 return (size > 0 && size <= g_switch_value);
8760 return false;
8763 /* Return true if OP is an acceptable memory operand for ARCompact
8764 16-bit gp-relative load instructions.
8766 /* volatile cache option still to be handled. */
8768 bool
8769 compact_sda_memory_operand (rtx op, machine_mode mode, bool short_p)
8771 rtx addr;
8772 int size;
8773 int align = 0;
8774 int mask = 0;
8776 /* Eliminate non-memory operations. */
8777 if (GET_CODE (op) != MEM)
8778 return false;
8780 if (mode == VOIDmode)
8781 mode = GET_MODE (op);
8783 size = GET_MODE_SIZE (mode);
8785 /* dword operations really put out 2 instructions, so eliminate them. */
8786 if (size > UNITS_PER_WORD)
8787 return false;
8789 /* Decode the address now. */
8790 addr = XEXP (op, 0);
8792 if (!legitimate_small_data_address_p (addr, mode))
8793 return false;
8795 if (!short_p || size == 1)
8796 return true;
8798 /* Now check for the alignment, the short loads using gp require the
8799 addresses to be aligned. */
8800 align = get_symbol_alignment (addr);
8801 switch (mode)
8803 case E_HImode:
8804 mask = 1;
8805 break;
8806 default:
8807 mask = 3;
8808 break;
8811 if (align && ((align & mask) == 0))
8812 return true;
8813 return false;
8816 /* Return TRUE if PAT is accessing an aux-reg. */
8818 static bool
8819 arc_is_aux_reg_p (rtx pat)
8821 tree attrs = NULL_TREE;
8822 tree addr;
8824 if (!MEM_P (pat))
8825 return false;
8827 /* Get the memory attributes. */
8828 addr = MEM_EXPR (pat);
8829 if (!addr)
8830 return false;
8832 /* Get the attributes. */
8833 if (VAR_P (addr))
8834 attrs = DECL_ATTRIBUTES (addr);
8835 else if (TREE_CODE (addr) == MEM_REF)
8836 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
8837 else
8838 return false;
8840 if (lookup_attribute ("aux", attrs))
8841 return true;
8842 return false;
8845 /* Implement ASM_OUTPUT_ALIGNED_DECL_LOCAL. */
8847 void
8848 arc_asm_output_aligned_decl_local (FILE * stream, tree decl, const char * name,
8849 unsigned HOST_WIDE_INT size,
8850 unsigned HOST_WIDE_INT align,
8851 unsigned HOST_WIDE_INT globalize_p)
8853 int in_small_data = arc_in_small_data_p (decl);
8854 rtx mem = decl == NULL_TREE ? NULL_RTX : DECL_RTL (decl);
8856 /* Don't output aux-reg symbols. */
8857 if (mem != NULL_RTX && MEM_P (mem)
8858 && SYMBOL_REF_P (XEXP (mem, 0))
8859 && arc_is_aux_reg_p (mem))
8860 return;
8862 if (in_small_data)
8863 switch_to_section (get_named_section (NULL, ".sbss", 0));
8864 /* named_section (0,".sbss",0); */
8865 else
8866 switch_to_section (bss_section);
8868 if (globalize_p)
8869 (*targetm.asm_out.globalize_label) (stream, name);
8871 ASM_OUTPUT_ALIGN (stream, floor_log2 ((align) / BITS_PER_UNIT));
8872 ASM_OUTPUT_TYPE_DIRECTIVE (stream, name, "object");
8873 ASM_OUTPUT_SIZE_DIRECTIVE (stream, name, size);
8874 ASM_OUTPUT_LABEL (stream, name);
8876 if (size != 0)
8877 ASM_OUTPUT_SKIP (stream, size);
8880 static bool
8881 arc_preserve_reload_p (rtx in)
8883 return (GET_CODE (in) == PLUS
8884 && RTX_OK_FOR_BASE_P (XEXP (in, 0), true)
8885 && CONST_INT_P (XEXP (in, 1))
8886 && !((INTVAL (XEXP (in, 1)) & 511)));
8889 /* Implement TARGET_REGISTER_MOVE_COST. */
8891 static int
8892 arc_register_move_cost (machine_mode,
8893 reg_class_t from_class, reg_class_t to_class)
8895 /* Force an attempt to 'mov Dy,Dx' to spill. */
8896 if ((TARGET_ARC700 || TARGET_EM) && TARGET_DPFP
8897 && from_class == DOUBLE_REGS && to_class == DOUBLE_REGS)
8898 return 100;
8900 return 2;
8903 /* Emit code for an addsi3 instruction with OPERANDS.
8904 COND_P indicates if this will use conditional execution.
8905 Return the length of the instruction.
8906 If OUTPUT_P is false, don't actually output the instruction, just return
8907 its length. */
8908 static int
8909 arc_output_addsi (rtx *operands, bool cond_p, bool output_p)
8911 char format[35];
8913 int match = operands_match_p (operands[0], operands[1]);
8914 int match2 = operands_match_p (operands[0], operands[2]);
8915 int intval = (REG_P (operands[2]) ? 1
8916 : CONST_INT_P (operands[2]) ? INTVAL (operands[2]) : 0xbadc057);
8917 int neg_intval = -intval;
8918 int short_0 = arc_check_short_reg_p (operands[0]);
8919 int short_p = (!cond_p && short_0 && arc_check_short_reg_p (operands[1]));
8920 int ret = 0;
8922 #define REG_H_P(OP) (REG_P (OP) && ((TARGET_V2 && REGNO (OP) <= 31 \
8923 && REGNO (OP) != 30) \
8924 || !TARGET_V2))
8926 #define ADDSI_OUTPUT1(FORMAT) do {\
8927 if (output_p) \
8928 output_asm_insn (FORMAT, operands);\
8929 return ret; \
8930 } while (0)
8931 #define ADDSI_OUTPUT(LIST) do {\
8932 if (output_p) \
8933 sprintf LIST;\
8934 ADDSI_OUTPUT1 (format);\
8935 return ret; \
8936 } while (0)
8938 /* First try to emit a 16 bit insn. */
8939 ret = 2;
8940 if (!cond_p
8941 /* If we are actually about to output this insn, don't try a 16 bit
8942 variant if we already decided that we don't want that
8943 (I.e. we upsized this insn to align some following insn.)
8944 E.g. add_s r0,sp,70 is 16 bit, but add r0,sp,70 requires a LIMM -
8945 but add1 r0,sp,35 doesn't. */
8946 && (!output_p || (get_attr_length (current_output_insn) & 2)))
8948 /* Generate add_s a,b,c; add_s b,b,u7; add_s c,b,u3; add_s b,b,h
8949 patterns. */
8950 if (short_p
8951 && ((REG_H_P (operands[2])
8952 && (match || arc_check_short_reg_p (operands[2])))
8953 || (CONST_INT_P (operands[2])
8954 && ((unsigned) intval <= (match ? 127 : 7)))))
8955 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;1");
8957 /* Generate add_s b,b,h patterns. */
8958 if (short_0 && match2 && REG_H_P (operands[1]))
8959 ADDSI_OUTPUT1 ("add%? %0,%2,%1 ;2");
8961 /* Generate add_s b,sp,u7; add_s sp,sp,u7 patterns. */
8962 if ((short_0 || REGNO (operands[0]) == STACK_POINTER_REGNUM)
8963 && REGNO (operands[1]) == STACK_POINTER_REGNUM && !(intval & ~124))
8964 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;3");
8966 if ((short_p && (unsigned) neg_intval <= (match ? 31 : 7))
8967 || (REGNO (operands[0]) == STACK_POINTER_REGNUM
8968 && match && !(neg_intval & ~124)))
8969 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2 ;4");
8971 /* Generate add_s h,h,s3 patterns. */
8972 if (REG_H_P (operands[0]) && match && TARGET_V2
8973 && CONST_INT_P (operands[2]) && ((intval>= -1) && (intval <= 6)))
8974 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;5");
8976 /* Generate add_s r0,b,u6; add_s r1,b,u6 patterns. */
8977 if (TARGET_CODE_DENSITY && REG_P (operands[0]) && REG_P (operands[1])
8978 && ((REGNO (operands[0]) == 0) || (REGNO (operands[0]) == 1))
8979 && arc_check_short_reg_p (operands[1])
8980 && satisfies_constraint_L (operands[2]))
8981 ADDSI_OUTPUT1 ("add%? %0,%1,%2 ;6");
8984 /* Now try to emit a 32 bit insn without long immediate. */
8985 ret = 4;
8986 if (!match && match2 && REG_P (operands[1]))
8987 ADDSI_OUTPUT1 ("add%? %0,%2,%1");
8988 if (match || !cond_p)
8990 int limit = (match && !cond_p) ? 0x7ff : 0x3f;
8991 int range_factor = neg_intval & intval;
8992 int shift;
8994 if (intval == (HOST_WIDE_INT) (HOST_WIDE_INT_M1U << 31))
8995 ADDSI_OUTPUT1 ("bxor%? %0,%1,31");
8997 /* If we can use a straight add / sub instead of a {add,sub}[123] of
8998 same size, do, so - the insn latency is lower. */
8999 /* -0x800 is a 12-bit constant for add /add3 / sub / sub3, but
9000 0x800 is not. */
9001 if ((intval >= 0 && intval <= limit)
9002 || (intval == -0x800 && limit == 0x7ff))
9003 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
9004 else if ((intval < 0 && neg_intval <= limit)
9005 || (intval == 0x800 && limit == 0x7ff))
9006 ADDSI_OUTPUT1 ("sub%? %0,%1,%n2");
9007 shift = range_factor >= 8 ? 3 : (range_factor >> 1);
9008 gcc_assert (shift == 0 || shift == 1 || shift == 2 || shift == 3);
9009 gcc_assert ((((1 << shift) - 1) & intval) == 0);
9010 if (((intval < 0 && intval != -0x4000)
9011 /* sub[123] is slower than add_s / sub, only use it if it
9012 avoids a long immediate. */
9013 && neg_intval <= limit << shift)
9014 || (intval == 0x4000 && limit == 0x7ff))
9015 ADDSI_OUTPUT ((format, "sub%d%%? %%0,%%1,%d",
9016 shift, neg_intval >> shift));
9017 else if ((intval >= 0 && intval <= limit << shift)
9018 || (intval == -0x4000 && limit == 0x7ff))
9019 ADDSI_OUTPUT ((format, "add%d%%? %%0,%%1,%d", shift, intval >> shift));
9021 /* Try to emit a 16 bit opcode with long immediate. */
9022 ret = 6;
9023 if (short_p && match)
9024 ADDSI_OUTPUT1 ("add%? %0,%1,%2");
9026 /* We have to use a 32 bit opcode, and with a long immediate. */
9027 ret = 8;
9028 ADDSI_OUTPUT1 (intval < 0 ? "sub%? %0,%1,%n2" : "add%? %0,%1,%2");
9031 /* Emit code for an commutative_cond_exec instruction with OPERANDS.
9032 Return the length of the instruction.
9033 If OUTPUT_P is false, don't actually output the instruction, just return
9034 its length. */
9036 arc_output_commutative_cond_exec (rtx *operands, bool output_p)
9038 enum rtx_code commutative_op = GET_CODE (operands[3]);
9039 const char *pat = NULL;
9041 /* Canonical rtl should not have a constant in the first operand position. */
9042 gcc_assert (!CONSTANT_P (operands[1]));
9044 switch (commutative_op)
9046 case AND:
9047 if (satisfies_constraint_C1p (operands[2]))
9048 pat = "bmsk%? %0,%1,%Z2";
9049 else if (satisfies_constraint_C2p (operands[2]))
9051 operands[2] = GEN_INT ((~INTVAL (operands[2])));
9052 pat = "bmskn%? %0,%1,%Z2";
9054 else if (satisfies_constraint_Ccp (operands[2]))
9055 pat = "bclr%? %0,%1,%M2";
9056 else if (satisfies_constraint_CnL (operands[2]))
9057 pat = "bic%? %0,%1,%n2-1";
9058 break;
9059 case IOR:
9060 if (satisfies_constraint_C0p (operands[2]))
9061 pat = "bset%? %0,%1,%z2";
9062 break;
9063 case XOR:
9064 if (satisfies_constraint_C0p (operands[2]))
9065 pat = "bxor%? %0,%1,%z2";
9066 break;
9067 case PLUS:
9068 return arc_output_addsi (operands, true, output_p);
9069 default: break;
9071 if (output_p)
9072 output_asm_insn (pat ? pat : "%O3.%d5 %0,%1,%2", operands);
9073 if (pat || REG_P (operands[2]) || satisfies_constraint_L (operands[2]))
9074 return 4;
9075 return 8;
9078 /* Helper function of arc_expand_cpymem. ADDR points to a chunk of memory.
9079 Emit code and return an potentially modified address such that offsets
9080 up to SIZE are can be added to yield a legitimate address.
9081 if REUSE is set, ADDR is a register that may be modified. */
9083 static rtx
9084 force_offsettable (rtx addr, HOST_WIDE_INT size, bool reuse)
9086 rtx base = addr;
9087 rtx offs = const0_rtx;
9089 if (GET_CODE (base) == PLUS)
9091 offs = XEXP (base, 1);
9092 base = XEXP (base, 0);
9094 if (!REG_P (base)
9095 || (REGNO (base) != STACK_POINTER_REGNUM
9096 && REGNO_PTR_FRAME_P (REGNO (base)))
9097 || !CONST_INT_P (offs) || !SMALL_INT (INTVAL (offs))
9098 || !SMALL_INT (INTVAL (offs) + size))
9100 if (reuse)
9101 emit_insn (gen_add2_insn (addr, offs));
9102 else
9103 addr = copy_to_mode_reg (Pmode, addr);
9105 return addr;
9108 /* Like move_by_pieces, but take account of load latency, and actual
9109 offset ranges. Return true on success. */
9111 bool
9112 arc_expand_cpymem (rtx *operands)
9114 rtx dst = operands[0];
9115 rtx src = operands[1];
9116 rtx dst_addr, src_addr;
9117 HOST_WIDE_INT size;
9118 int align = INTVAL (operands[3]);
9119 unsigned n_pieces;
9120 int piece = align;
9121 rtx store[2];
9122 rtx tmpx[2];
9123 int i;
9125 if (!CONST_INT_P (operands[2]))
9126 return false;
9127 size = INTVAL (operands[2]);
9128 /* move_by_pieces_ninsns is static, so we can't use it. */
9129 if (align >= 4)
9131 if (TARGET_LL64)
9132 n_pieces = (size + 4) / 8U + ((size >> 1) & 1) + (size & 1);
9133 else
9134 n_pieces = (size + 2) / 4U + (size & 1);
9136 else if (align == 2)
9137 n_pieces = (size + 1) / 2U;
9138 else
9139 n_pieces = size;
9140 if (n_pieces >= (unsigned int) (optimize_size ? 3 : 15))
9141 return false;
9142 /* Force 32 bit aligned and larger datum to use 64 bit transfers, if
9143 possible. */
9144 if (TARGET_LL64 && (piece >= 4) && (size >= 8))
9145 piece = 8;
9146 else if (piece > 4)
9147 piece = 4;
9148 dst_addr = force_offsettable (XEXP (operands[0], 0), size, 0);
9149 src_addr = force_offsettable (XEXP (operands[1], 0), size, 0);
9150 store[0] = store[1] = NULL_RTX;
9151 tmpx[0] = tmpx[1] = NULL_RTX;
9152 for (i = 0; size > 0; i ^= 1, size -= piece)
9154 rtx tmp;
9155 machine_mode mode;
9157 while (piece > size)
9158 piece >>= 1;
9159 mode = smallest_int_mode_for_size (piece * BITS_PER_UNIT);
9160 /* If we don't re-use temporaries, the scheduler gets carried away,
9161 and the register pressure gets unnecessarily high. */
9162 if (0 && tmpx[i] && GET_MODE (tmpx[i]) == mode)
9163 tmp = tmpx[i];
9164 else
9165 tmpx[i] = tmp = gen_reg_rtx (mode);
9166 dst_addr = force_offsettable (dst_addr, piece, 1);
9167 src_addr = force_offsettable (src_addr, piece, 1);
9168 if (store[i])
9169 emit_insn (store[i]);
9170 emit_move_insn (tmp, change_address (src, mode, src_addr));
9171 store[i] = gen_move_insn (change_address (dst, mode, dst_addr), tmp);
9172 dst_addr = plus_constant (Pmode, dst_addr, piece);
9173 src_addr = plus_constant (Pmode, src_addr, piece);
9175 if (store[i])
9176 emit_insn (store[i]);
9177 if (store[i^1])
9178 emit_insn (store[i^1]);
9179 return true;
9182 static bool
9183 arc_get_aux_arg (rtx pat, int *auxr)
9185 tree attr, addr = MEM_EXPR (pat);
9186 if (TREE_CODE (addr) != VAR_DECL)
9187 return false;
9189 attr = DECL_ATTRIBUTES (addr);
9190 if (lookup_attribute ("aux", attr))
9192 tree arg = TREE_VALUE (attr);
9193 if (arg)
9195 *auxr = TREE_INT_CST_LOW (TREE_VALUE (arg));
9196 return true;
9200 return false;
9203 /* Prepare operands for move in MODE. Return true iff the move has
9204 been emitted. */
9206 bool
9207 prepare_move_operands (rtx *operands, machine_mode mode)
9209 if ((MEM_P (operands[0]) || MEM_P (operands[1]))
9210 && SCALAR_INT_MODE_P (mode))
9212 /* First handle aux attribute. */
9213 if (mode == SImode)
9215 rtx tmp;
9216 int auxr = 0;
9217 if (MEM_P (operands[0]) && arc_is_aux_reg_p (operands[0]))
9219 /* Save operation. */
9220 if (arc_get_aux_arg (operands[0], &auxr))
9222 tmp = gen_reg_rtx (SImode);
9223 emit_move_insn (tmp, GEN_INT (auxr));
9225 else
9226 tmp = XEXP (operands[0], 0);
9228 operands[1] = force_reg (SImode, operands[1]);
9229 emit_insn (gen_rtx_UNSPEC_VOLATILE
9230 (VOIDmode, gen_rtvec (2, operands[1], tmp),
9231 VUNSPEC_ARC_SR));
9232 return true;
9234 if (MEM_P (operands[1]) && arc_is_aux_reg_p (operands[1]))
9236 if (arc_get_aux_arg (operands[1], &auxr))
9238 tmp = gen_reg_rtx (SImode);
9239 emit_move_insn (tmp, GEN_INT (auxr));
9241 else
9243 tmp = XEXP (operands[1], 0);
9244 gcc_assert (GET_CODE (tmp) == SYMBOL_REF);
9246 /* Load operation. */
9247 gcc_assert (REG_P (operands[0]));
9248 emit_insn (gen_rtx_SET (operands[0],
9249 gen_rtx_UNSPEC_VOLATILE
9250 (SImode, gen_rtvec (1, tmp),
9251 VUNSPEC_ARC_LR)));
9252 return true;
9255 /* Second, we check for the uncached. */
9256 if (arc_is_uncached_mem_p (operands[0]))
9258 if (!REG_P (operands[1]))
9259 operands[1] = force_reg (mode, operands[1]);
9260 emit_insn (gen_rtx_UNSPEC_VOLATILE
9261 (VOIDmode, gen_rtvec (2, operands[0], operands[1]),
9262 VUNSPEC_ARC_STDI));
9263 return true;
9265 if (arc_is_uncached_mem_p (operands[1]))
9267 rtx tmp = operands[0];
9269 if (MEM_P (operands[0]))
9270 tmp = gen_reg_rtx (mode);
9272 emit_insn (gen_rtx_SET
9273 (tmp,
9274 gen_rtx_UNSPEC_VOLATILE
9275 (mode, gen_rtvec (1, operands[1]),
9276 VUNSPEC_ARC_LDDI)));
9277 if (MEM_P (operands[0]))
9279 operands[1] = tmp;
9280 return false;
9282 return true;
9286 if (GET_CODE (operands[1]) == SYMBOL_REF)
9288 enum tls_model model = SYMBOL_REF_TLS_MODEL (operands[1]);
9289 if (MEM_P (operands[0]))
9290 operands[1] = force_reg (mode, operands[1]);
9291 else if (model)
9292 operands[1] = arc_legitimize_tls_address (operands[1], model);
9295 operands[1] = arc_legitimize_pic_address (operands[1]);
9297 /* Store instructions are limited, they only accept as address an
9298 immediate, a register or a register plus a small immediate. */
9299 if (MEM_P (operands[0])
9300 && !move_dest_operand (operands[0], mode))
9302 rtx tmp0 = copy_to_mode_reg (Pmode, XEXP (operands[0], 0));
9303 rtx tmp1 = change_address (operands[0], mode, tmp0);
9304 MEM_COPY_ATTRIBUTES (tmp1, operands[0]);
9305 operands[0] = tmp1;
9308 /* Check if it is constant but it is not legitimized. */
9309 if (CONSTANT_P (operands[1])
9310 && !arc_legitimate_constant_p (mode, operands[1]))
9311 operands[1] = force_reg (mode, XEXP (operands[1], 0));
9312 else if (MEM_P (operands[0])
9313 && ((CONSTANT_P (operands[1])
9314 && !satisfies_constraint_Cm3 (operands[1]))
9315 || MEM_P (operands[1])))
9316 operands[1] = force_reg (mode, operands[1]);
9318 return false;
9321 /* Output a library call to a function called FNAME that has been arranged
9322 to be local to any dso. */
9324 const char *
9325 arc_output_libcall (const char *fname)
9327 unsigned len = strlen (fname);
9328 static char buf[64];
9330 gcc_assert (len < sizeof buf - 35);
9331 if (TARGET_LONG_CALLS_SET)
9333 if (flag_pic)
9334 sprintf (buf, "add r12,pcl,@%s@pcl\n\tjl%%!%%* [r12]", fname);
9335 else
9336 sprintf (buf, "jl%%! @%s", fname);
9338 else
9339 sprintf (buf, "bl%%!%%* @%s", fname);
9340 return buf;
9343 /* Return the SImode highpart of the DImode value IN. */
9346 disi_highpart (rtx in)
9348 return simplify_gen_subreg (SImode, in, DImode, TARGET_BIG_ENDIAN ? 0 : 4);
9351 /* Given a rtx, check if it is an assembly instruction or not. */
9353 static int
9354 arc_asm_insn_p (rtx x)
9356 int i, j;
9358 if (x == 0)
9359 return 0;
9361 switch (GET_CODE (x))
9363 case ASM_OPERANDS:
9364 case ASM_INPUT:
9365 return 1;
9367 case SET:
9368 return arc_asm_insn_p (SET_SRC (x));
9370 case PARALLEL:
9371 j = 0;
9372 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
9373 j += arc_asm_insn_p (XVECEXP (x, 0, i));
9374 if ( j > 0)
9375 return 1;
9376 break;
9378 default:
9379 break;
9382 return 0;
9385 /* Return length adjustment for INSN. */
9388 arc_adjust_insn_length (rtx_insn *insn, int len, bool)
9390 if (!INSN_P (insn))
9391 return len;
9392 /* We already handle sequences by ignoring the delay sequence flag. */
9393 if (GET_CODE (PATTERN (insn)) == SEQUENCE)
9394 return len;
9396 /* Check for return with but one preceding insn since function
9397 start / call. */
9398 if (TARGET_PAD_RETURN
9399 && JUMP_P (insn)
9400 && GET_CODE (PATTERN (insn)) != ADDR_VEC
9401 && GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC
9402 && get_attr_type (insn) == TYPE_RETURN)
9404 rtx_insn *prev = prev_active_insn (insn);
9406 if (!prev || !(prev = prev_active_insn (prev))
9407 || ((NONJUMP_INSN_P (prev)
9408 && GET_CODE (PATTERN (prev)) == SEQUENCE)
9409 ? CALL_ATTR (as_a <rtx_sequence *> (PATTERN (prev))->insn (0),
9410 NON_SIBCALL)
9411 : CALL_ATTR (prev, NON_SIBCALL)))
9412 return len + 4;
9414 if (TARGET_ARC600)
9416 rtx_insn *succ = next_real_insn (insn);
9418 /* One the ARC600, a write to an extension register must be separated
9419 from a read. */
9420 if (succ && INSN_P (succ))
9421 len += arc600_corereg_hazard (insn, succ);
9424 /* Restore extracted operands - otherwise splitters like the addsi3_mixed one
9425 can go awry. */
9426 extract_constrain_insn_cached (insn);
9428 return len;
9431 /* Return version of PAT conditionalized with COND, which is part of INSN.
9432 ANNULLED indicates if INSN is an annulled delay-slot insn.
9433 Register further changes if necessary. */
9434 static rtx
9435 conditionalize_nonjump (rtx pat, rtx cond, rtx insn, bool annulled)
9437 /* For commutative operators, we generally prefer to have
9438 the first source match the destination. */
9439 if (GET_CODE (pat) == SET)
9441 rtx src = SET_SRC (pat);
9443 if (COMMUTATIVE_P (src))
9445 rtx src0 = XEXP (src, 0);
9446 rtx src1 = XEXP (src, 1);
9447 rtx dst = SET_DEST (pat);
9449 if (rtx_equal_p (src1, dst) && !rtx_equal_p (src0, dst)
9450 /* Leave add_n alone - the canonical form is to
9451 have the complex summand first. */
9452 && REG_P (src0))
9453 pat = gen_rtx_SET (dst,
9454 gen_rtx_fmt_ee (GET_CODE (src), GET_MODE (src),
9455 src1, src0));
9459 /* dwarf2out.cc:dwarf2out_frame_debug_expr doesn't know
9460 what to do with COND_EXEC. */
9461 if (RTX_FRAME_RELATED_P (insn))
9463 /* If this is the delay slot insn of an anulled branch,
9464 dwarf2out.cc:scan_trace understands the anulling semantics
9465 without the COND_EXEC. */
9466 gcc_assert (annulled);
9467 rtx note = alloc_reg_note (REG_FRAME_RELATED_EXPR, pat,
9468 REG_NOTES (insn));
9469 validate_change (insn, &REG_NOTES (insn), note, 1);
9471 pat = gen_rtx_COND_EXEC (VOIDmode, cond, pat);
9472 return pat;
9476 /* Find annulled delay insns and convert them to use the appropriate predicate.
9477 This allows branch shortening to size up these insns properly. */
9479 static unsigned
9480 arc_predicate_delay_insns (void)
9482 for (rtx_insn *insn = get_insns (); insn; insn = NEXT_INSN (insn))
9484 rtx pat, jump, dlay, src, cond, *patp;
9485 int reverse;
9487 if (!NONJUMP_INSN_P (insn)
9488 || GET_CODE (pat = PATTERN (insn)) != SEQUENCE)
9489 continue;
9490 jump = XVECEXP (pat, 0, 0);
9491 dlay = XVECEXP (pat, 0, 1);
9492 if (!JUMP_P (jump) || !INSN_ANNULLED_BRANCH_P (jump))
9493 continue;
9494 /* If the branch insn does the annulling, leave the delay insn alone. */
9495 if (!TARGET_AT_DBR_CONDEXEC && !INSN_FROM_TARGET_P (dlay))
9496 continue;
9497 /* ??? Could also leave DLAY un-conditionalized if its target is dead
9498 on the other path. */
9499 gcc_assert (GET_CODE (PATTERN (jump)) == SET);
9500 gcc_assert (SET_DEST (PATTERN (jump)) == pc_rtx);
9501 src = SET_SRC (PATTERN (jump));
9502 gcc_assert (GET_CODE (src) == IF_THEN_ELSE);
9503 cond = XEXP (src, 0);
9504 if (XEXP (src, 2) == pc_rtx)
9505 reverse = 0;
9506 else if (XEXP (src, 1) == pc_rtx)
9507 reverse = 1;
9508 else
9509 gcc_unreachable ();
9510 if (reverse != !INSN_FROM_TARGET_P (dlay))
9512 machine_mode ccm = GET_MODE (XEXP (cond, 0));
9513 enum rtx_code code = reverse_condition (GET_CODE (cond));
9514 if (code == UNKNOWN || ccm == CC_FP_GTmode || ccm == CC_FP_GEmode)
9515 code = reverse_condition_maybe_unordered (GET_CODE (cond));
9517 cond = gen_rtx_fmt_ee (code, GET_MODE (cond),
9518 copy_rtx (XEXP (cond, 0)),
9519 copy_rtx (XEXP (cond, 1)));
9521 else
9522 cond = copy_rtx (cond);
9523 patp = &PATTERN (dlay);
9524 pat = *patp;
9525 pat = conditionalize_nonjump (pat, cond, dlay, true);
9526 validate_change (dlay, patp, pat, 1);
9527 if (!apply_change_group ())
9528 gcc_unreachable ();
9530 return 0;
9533 /* For ARC600: If a write to a core reg >=32 appears in a delay slot
9534 (other than of a forward brcc), it creates a hazard when there is a read
9535 of the same register at the branch target. We can't know what is at the
9536 branch target of calls, and for branches, we don't really know before the
9537 end of delay slot scheduling, either. Not only can individual instruction
9538 be hoisted out into a delay slot, a basic block can also be emptied this
9539 way, and branch and/or fall through targets be redirected. Hence we don't
9540 want such writes in a delay slot. */
9542 /* Return nonzreo iff INSN writes to an extension core register. */
9545 arc_write_ext_corereg (rtx insn)
9547 subrtx_iterator::array_type array;
9548 FOR_EACH_SUBRTX (iter, array, PATTERN (insn), NONCONST)
9550 const_rtx x = *iter;
9551 switch (GET_CODE (x))
9553 case SET: case POST_INC: case POST_DEC: case PRE_INC: case PRE_DEC:
9554 break;
9555 default:
9556 /* This is also fine for PRE/POST_MODIFY, because they
9557 contain a SET. */
9558 continue;
9560 const_rtx dest = XEXP (x, 0);
9561 if (REG_P (dest) && REGNO (dest) >= 32 && REGNO (dest) < 61)
9562 return 1;
9564 return 0;
9567 /* This is like the hook, but returns NULL when it can't / won't generate
9568 a legitimate address. */
9570 static rtx
9571 arc_legitimize_address_0 (rtx x, rtx oldx ATTRIBUTE_UNUSED,
9572 machine_mode mode)
9574 rtx addr, inner;
9576 addr = x;
9577 if (GET_CODE (addr) == CONST)
9578 addr = XEXP (addr, 0);
9580 if (GET_CODE (addr) == PLUS
9581 && CONST_INT_P (XEXP (addr, 1))
9582 && ((GET_CODE (XEXP (addr, 0)) == SYMBOL_REF
9583 && !SYMBOL_REF_FUNCTION_P (XEXP (addr, 0)))
9584 || (REG_P (XEXP (addr, 0))
9585 && (INTVAL (XEXP (addr, 1)) & 252))))
9587 HOST_WIDE_INT offs, upper;
9588 int size = GET_MODE_SIZE (mode);
9590 offs = INTVAL (XEXP (addr, 1));
9591 upper = (offs + 256 * size) & ~511 * size;
9592 inner = plus_constant (Pmode, XEXP (addr, 0), upper);
9593 #if 0 /* ??? this produces worse code for EEMBC idctrn01 */
9594 if (GET_CODE (x) == CONST)
9595 inner = gen_rtx_CONST (Pmode, inner);
9596 #endif
9597 addr = plus_constant (Pmode, force_reg (Pmode, inner), offs - upper);
9598 x = addr;
9600 else if (GET_CODE (addr) == SYMBOL_REF && !SYMBOL_REF_FUNCTION_P (addr))
9601 x = force_reg (Pmode, x);
9602 if (memory_address_p ((machine_mode) mode, x))
9603 return x;
9604 return NULL_RTX;
9607 static rtx
9608 arc_legitimize_address (rtx orig_x, rtx oldx, machine_mode mode)
9610 rtx new_x = arc_legitimize_address_0 (orig_x, oldx, mode);
9612 if (new_x)
9613 return new_x;
9614 return orig_x;
9617 static rtx
9618 arc_delegitimize_address_0 (rtx op)
9620 switch (GET_CODE (op))
9622 case CONST:
9623 return arc_delegitimize_address_0 (XEXP (op, 0));
9625 case UNSPEC:
9626 switch (XINT (op, 1))
9628 case ARC_UNSPEC_GOT:
9629 case ARC_UNSPEC_GOTOFFPC:
9630 return XVECEXP (op, 0, 0);
9631 default:
9632 break;
9634 break;
9636 case PLUS:
9638 rtx t1 = arc_delegitimize_address_0 (XEXP (op, 0));
9639 rtx t2 = XEXP (op, 1);
9641 if (t1 && t2)
9642 return gen_rtx_PLUS (GET_MODE (op), t1, t2);
9643 break;
9646 default:
9647 break;
9649 return NULL_RTX;
9652 static rtx
9653 arc_delegitimize_address (rtx orig_x)
9655 rtx x = orig_x;
9657 if (MEM_P (x))
9658 x = XEXP (x, 0);
9660 x = arc_delegitimize_address_0 (x);
9661 if (!x)
9662 return orig_x;
9664 if (MEM_P (orig_x))
9665 x = replace_equiv_address_nv (orig_x, x);
9666 return x;
9669 /* Return a REG rtx for acc1. N.B. the gcc-internal representation may
9670 differ from the hardware register number in order to allow the generic
9671 code to correctly split the concatenation of acc1 and acc2. */
9674 gen_acc1 (void)
9676 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 56: 57);
9679 /* Return a REG rtx for acc2. N.B. the gcc-internal representation may
9680 differ from the hardware register number in order to allow the generic
9681 code to correctly split the concatenation of acc1 and acc2. */
9684 gen_acc2 (void)
9686 return gen_rtx_REG (SImode, TARGET_BIG_ENDIAN ? 57: 56);
9689 /* When estimating sizes during arc_reorg, when optimizing for speed, there
9690 are three reasons why we need to consider branches to be length 6:
9691 - annull-false delay slot insns are implemented using conditional execution,
9692 thus preventing short insn formation where used.
9693 - for ARC600: annul-true delay slot insns are implemented where possible
9694 using conditional execution, preventing short insn formation where used.
9695 - for ARC700: likely or somewhat likely taken branches are made long and
9696 unaligned if possible to avoid branch penalty. */
9698 bool
9699 arc_branch_size_unknown_p (void)
9701 return !optimize_size && arc_reorg_in_progress;
9704 /* The usual; we set up our machine_function data. */
9706 static struct machine_function *
9707 arc_init_machine_status (void)
9709 struct machine_function *machine;
9710 machine = ggc_cleared_alloc<machine_function> ();
9711 machine->fn_type = ARC_FUNCTION_UNKNOWN;
9713 return machine;
9716 /* Implements INIT_EXPANDERS. We just set up to call the above
9717 function. */
9719 void
9720 arc_init_expanders (void)
9722 init_machine_status = arc_init_machine_status;
9725 /* Check if OP is a proper parallel of a millicode call pattern. OFFSET
9726 indicates a number of elements to ignore - that allows to have a
9727 sibcall pattern that starts with (return). LOAD_P is zero for store
9728 multiple (for prologues), and one for load multiples (for epilogues),
9729 and two for load multiples where no final clobber of blink is required.
9730 We also skip the first load / store element since this is supposed to
9731 be checked in the instruction pattern. */
9734 arc_check_millicode (rtx op, int offset, int load_p)
9736 int len = XVECLEN (op, 0) - offset;
9737 int i;
9739 if (load_p == 2)
9741 if (len < 2 || len > 13)
9742 return 0;
9743 load_p = 1;
9745 else
9747 rtx elt = XVECEXP (op, 0, --len);
9749 if (GET_CODE (elt) != CLOBBER
9750 || !REG_P (XEXP (elt, 0))
9751 || REGNO (XEXP (elt, 0)) != RETURN_ADDR_REGNUM
9752 || len < 3 || len > 13)
9753 return 0;
9755 for (i = 1; i < len; i++)
9757 rtx elt = XVECEXP (op, 0, i + offset);
9758 rtx reg, mem, addr;
9760 if (GET_CODE (elt) != SET)
9761 return 0;
9762 mem = XEXP (elt, load_p);
9763 reg = XEXP (elt, 1-load_p);
9764 if (!REG_P (reg) || REGNO (reg) != 13U+i || !MEM_P (mem))
9765 return 0;
9766 addr = XEXP (mem, 0);
9767 if (GET_CODE (addr) != PLUS
9768 || !rtx_equal_p (stack_pointer_rtx, XEXP (addr, 0))
9769 || !CONST_INT_P (XEXP (addr, 1)) || INTVAL (XEXP (addr, 1)) != i*4)
9770 return 0;
9772 return 1;
9775 /* Operands 0..2 are the operands of a subsi which uses a 12 bit
9776 constant in operand 1, but which would require a LIMM because of
9777 operand mismatch.
9778 operands 3 and 4 are new SET_SRCs for operands 0. */
9780 void
9781 split_subsi (rtx *operands)
9783 int val = INTVAL (operands[1]);
9785 /* Try for two short insns first. Lengths being equal, we prefer
9786 expansions with shorter register lifetimes. */
9787 if (arc_check_short_reg_p (operands[0])
9788 && arc_check_short_reg_p (operands[2]))
9790 if (val >= -31 && val <= 127)
9792 operands[3] = gen_rtx_NEG (SImode, operands[2]);
9793 operands[4] = gen_rtx_PLUS (SImode, operands[0], operands[1]);
9794 return;
9796 else if (val >= 0 && val < 255)
9798 operands[3] = operands[1];
9799 operands[4] = gen_rtx_MINUS (SImode, operands[0], operands[2]);
9800 return;
9803 /* If the destination is not an ARCompact16 register, we might
9804 still have a chance to make a short insn if the source is;
9805 we need to start with a reg-reg move for this. */
9806 operands[3] = operands[2];
9807 operands[4] = gen_rtx_MINUS (SImode, operands[1], operands[0]);
9810 /* Handle DOUBLE_REGS uses.
9811 Operand 0: destination register
9812 Operand 1: source register */
9814 static bool
9815 arc_process_double_reg_moves (rtx *operands)
9817 enum usesDxState { none, srcDx, destDx, maxDx };
9818 enum usesDxState state = none;
9819 rtx dest = operands[0];
9820 rtx src = operands[1];
9822 if (refers_to_regno_p (40, 44, src, 0))
9824 state = srcDx;
9825 gcc_assert (REG_P (dest));
9827 if (refers_to_regno_p (40, 44, dest, 0))
9829 /* Via arc_register_move_cost, we should never see D,D moves. */
9830 gcc_assert (REG_P (src));
9831 gcc_assert (state == none);
9832 state = destDx;
9835 if (state == none)
9836 return false;
9838 if (state == srcDx)
9840 /* Without the LR insn, we need to split this into a
9841 sequence of insns which will use the DEXCLx and DADDHxy
9842 insns to be able to read the Dx register in question. */
9843 if (TARGET_DPFP_DISABLE_LRSR)
9845 /* gen *movdf_insn_nolrsr */
9846 rtx set = gen_rtx_SET (dest, src);
9847 rtx use1 = gen_rtx_USE (VOIDmode, const1_rtx);
9848 emit_insn (gen_rtx_PARALLEL (VOIDmode, gen_rtvec (2, set, use1)));
9850 else
9852 /* When we have 'mov D, r' or 'mov D, D' then get the target
9853 register pair for use with LR insn. */
9854 rtx destHigh = simplify_gen_subreg (SImode, dest, DFmode,
9855 TARGET_BIG_ENDIAN ? 0 : 4);
9856 rtx destLow = simplify_gen_subreg (SImode, dest, DFmode,
9857 TARGET_BIG_ENDIAN ? 4 : 0);
9859 /* Produce the two LR insns to get the high and low parts. */
9860 emit_insn (gen_rtx_SET (destHigh,
9861 gen_rtx_UNSPEC_VOLATILE (Pmode,
9862 gen_rtvec (1, src),
9863 VUNSPEC_ARC_LR_HIGH)));
9864 emit_insn (gen_rtx_SET (destLow,
9865 gen_rtx_UNSPEC_VOLATILE (Pmode,
9866 gen_rtvec (1, src),
9867 VUNSPEC_ARC_LR)));
9870 else if (state == destDx)
9872 /* When we have 'mov r, D' or 'mov D, D' and we have access to the
9873 LR insn get the target register pair. */
9874 rtx srcHigh = simplify_gen_subreg (SImode, src, DFmode,
9875 TARGET_BIG_ENDIAN ? 0 : 4);
9876 rtx srcLow = simplify_gen_subreg (SImode, src, DFmode,
9877 TARGET_BIG_ENDIAN ? 4 : 0);
9879 emit_insn (gen_dexcl_2op (dest, srcHigh, srcLow));
9881 else
9882 gcc_unreachable ();
9884 return true;
9888 /* Check if we need to split a 64bit move. We do not need to split it if we can
9889 use vadd2 or ldd/std instructions. */
9891 bool
9892 arc_split_move_p (rtx *operands)
9894 machine_mode mode = GET_MODE (operands[0]);
9896 if (TARGET_LL64
9897 && ((memory_operand (operands[0], mode)
9898 && (even_register_operand (operands[1], mode)
9899 || satisfies_constraint_Cm3 (operands[1])))
9900 || (memory_operand (operands[1], mode)
9901 && even_register_operand (operands[0], mode))))
9902 return false;
9904 if (TARGET_PLUS_QMACW
9905 && even_register_operand (operands[0], mode)
9906 && even_register_operand (operands[1], mode))
9907 return false;
9909 return true;
9912 /* operands 0..1 are the operands of a 64 bit move instruction.
9913 split it into two moves with operands 2/3 and 4/5. */
9915 void
9916 arc_split_move (rtx *operands)
9918 machine_mode mode = GET_MODE (operands[0]);
9919 int i;
9920 int swap = 0;
9921 rtx xop[4];
9923 if (TARGET_DPFP)
9925 if (arc_process_double_reg_moves (operands))
9926 return;
9929 if (TARGET_PLUS_QMACW
9930 && GET_CODE (operands[1]) == CONST_VECTOR)
9932 HOST_WIDE_INT intval0, intval1;
9933 if (GET_MODE (operands[1]) == V2SImode)
9935 intval0 = INTVAL (XVECEXP (operands[1], 0, 0));
9936 intval1 = INTVAL (XVECEXP (operands[1], 0, 1));
9938 else
9940 intval1 = INTVAL (XVECEXP (operands[1], 0, 3)) << 16;
9941 intval1 |= INTVAL (XVECEXP (operands[1], 0, 2)) & 0xFFFF;
9942 intval0 = INTVAL (XVECEXP (operands[1], 0, 1)) << 16;
9943 intval0 |= INTVAL (XVECEXP (operands[1], 0, 0)) & 0xFFFF;
9945 xop[0] = gen_rtx_REG (SImode, REGNO (operands[0]));
9946 xop[3] = gen_rtx_REG (SImode, REGNO (operands[0]) + 1);
9947 xop[2] = GEN_INT (trunc_int_for_mode (intval0, SImode));
9948 xop[1] = GEN_INT (trunc_int_for_mode (intval1, SImode));
9949 emit_move_insn (xop[0], xop[2]);
9950 emit_move_insn (xop[3], xop[1]);
9951 return;
9954 for (i = 0; i < 2; i++)
9956 if (MEM_P (operands[i]) && auto_inc_p (XEXP (operands[i], 0)))
9958 rtx addr = XEXP (operands[i], 0);
9959 rtx r, o;
9960 enum rtx_code code;
9962 gcc_assert (!reg_overlap_mentioned_p (operands[0], addr));
9963 switch (GET_CODE (addr))
9965 case PRE_DEC: o = GEN_INT (-8); goto pre_modify;
9966 case PRE_INC: o = GEN_INT (8); goto pre_modify;
9967 case PRE_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9968 pre_modify:
9969 code = PRE_MODIFY;
9970 break;
9971 case POST_DEC: o = GEN_INT (-8); goto post_modify;
9972 case POST_INC: o = GEN_INT (8); goto post_modify;
9973 case POST_MODIFY: o = XEXP (XEXP (addr, 1), 1);
9974 post_modify:
9975 code = POST_MODIFY;
9976 swap = 2;
9977 break;
9978 default:
9979 gcc_unreachable ();
9981 r = XEXP (addr, 0);
9982 xop[0+i] = adjust_automodify_address_nv
9983 (operands[i], SImode,
9984 gen_rtx_fmt_ee (code, Pmode, r,
9985 gen_rtx_PLUS (Pmode, r, o)),
9987 xop[2+i] = adjust_automodify_address_nv
9988 (operands[i], SImode, plus_constant (Pmode, r, 4), 4);
9990 else
9992 xop[0+i] = operand_subword (operands[i], 0, 0, mode);
9993 xop[2+i] = operand_subword (operands[i], 1, 0, mode);
9996 if (reg_overlap_mentioned_p (xop[0], xop[3]))
9998 swap = 2;
9999 gcc_assert (!reg_overlap_mentioned_p (xop[2], xop[1]));
10002 emit_move_insn (xop[0 + swap], xop[1 + swap]);
10003 emit_move_insn (xop[2 - swap], xop[3 - swap]);
10007 /* Select between the instruction output templates s_tmpl (for short INSNs)
10008 and l_tmpl (for long INSNs). */
10010 const char *
10011 arc_short_long (rtx_insn *insn, const char *s_tmpl, const char *l_tmpl)
10013 int is_short = arc_verify_short (insn, -1);
10015 extract_constrain_insn_cached (insn);
10016 return is_short ? s_tmpl : l_tmpl;
10019 /* Searches X for any reference to REGNO, returning the rtx of the
10020 reference found if any. Otherwise, returns NULL_RTX. */
10023 arc_regno_use_in (unsigned int regno, rtx x)
10025 const char *fmt;
10026 int i, j;
10027 rtx tem;
10029 if (REG_P (x) && refers_to_regno_p (regno, x))
10030 return x;
10032 fmt = GET_RTX_FORMAT (GET_CODE (x));
10033 for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
10035 if (fmt[i] == 'e')
10037 if ((tem = regno_use_in (regno, XEXP (x, i))))
10038 return tem;
10040 else if (fmt[i] == 'E')
10041 for (j = XVECLEN (x, i) - 1; j >= 0; j--)
10042 if ((tem = regno_use_in (regno , XVECEXP (x, i, j))))
10043 return tem;
10046 return NULL_RTX;
10049 /* Code has a minimum p2 alignment of 1, which we must restore after
10050 an ADDR_DIFF_VEC. */
10053 arc_label_align (rtx_insn *label)
10055 if (align_labels.levels[0].log < 1)
10057 rtx_insn *next = next_nonnote_nondebug_insn (label);
10058 if (INSN_P (next) && recog_memoized (next) >= 0)
10059 return 1;
10061 return align_labels.levels[0].log;
10064 /* Return true if LABEL is in executable code. */
10066 bool
10067 arc_text_label (rtx_insn *label)
10069 rtx_insn *next;
10071 /* ??? We use deleted labels like they were still there, see
10072 gcc.c-torture/compile/20000326-2.c . */
10073 gcc_assert (GET_CODE (label) == CODE_LABEL
10074 || (GET_CODE (label) == NOTE
10075 && NOTE_KIND (label) == NOTE_INSN_DELETED_LABEL));
10076 next = next_nonnote_insn (label);
10077 if (next)
10078 return (!JUMP_TABLE_DATA_P (next)
10079 || GET_CODE (PATTERN (next)) != ADDR_VEC);
10080 else if (!PREV_INSN (label))
10081 /* ??? sometimes text labels get inserted very late, see
10082 gcc.dg/torture/stackalign/comp-goto-1.c */
10083 return true;
10084 return false;
10087 /* Without this, gcc.dg/tree-prof/bb-reorg.c fails to assemble
10088 when compiling with -O2 -freorder-blocks-and-partition -fprofile-use
10089 -D_PROFILE_USE; delay branch scheduling then follows a crossing jump
10090 to redirect two breqs. */
10092 static bool
10093 arc_can_follow_jump (const rtx_insn *follower, const rtx_insn *followee)
10095 /* ??? get_attr_type is declared to take an rtx. */
10096 union { const rtx_insn *c; rtx_insn *r; } u;
10098 u.c = follower;
10099 if (CROSSING_JUMP_P (followee))
10100 switch (get_attr_type (u.r))
10102 case TYPE_BRANCH:
10103 if (get_attr_length (u.r) != 2)
10104 break;
10105 /* Fall through. */
10106 case TYPE_BRCC:
10107 case TYPE_BRCC_NO_DELAY_SLOT:
10108 return false;
10109 default:
10110 return true;
10112 return true;
10116 /* Implement EPILOGUE_USES.
10117 Return true if REGNO should be added to the deemed uses of the epilogue.
10119 We have to make sure all the register restore instructions are
10120 known to be live in interrupt functions, plus the blink register if
10121 it is clobbered by the isr. */
10123 bool
10124 arc_epilogue_uses (int regno)
10126 unsigned int fn_type;
10127 fn_type = arc_compute_function_type (cfun);
10129 if (regno == arc_tp_regno)
10130 return true;
10132 if (regno == RETURN_ADDR_REGNUM)
10133 return true;
10135 if (regno == arc_return_address_register (fn_type))
10136 return true;
10138 if (epilogue_completed && ARC_INTERRUPT_P (fn_type))
10140 /* An interrupt function restores more registers. */
10141 if (df_regs_ever_live_p (regno) || call_used_or_fixed_reg_p (regno))
10142 return true;
10145 return false;
10148 /* Helper for EH_USES macro. */
10150 bool
10151 arc_eh_uses (int regno)
10153 if (regno == arc_tp_regno)
10154 return true;
10155 return false;
10158 /* Return true if we use LRA instead of reload pass. */
10160 bool
10161 arc_lra_p (void)
10163 return arc_lra_flag;
10166 /* ??? Should we define TARGET_REGISTER_PRIORITY? We might perfer to
10167 use q registers, because some insn are shorter with them. OTOH we
10168 already have separate alternatives for this purpose, and other
10169 insns don't mind, so maybe we should rather prefer the other
10170 registers? We need more data, and we can only get that if we allow
10171 people to try all options. */
10172 static int
10173 arc_register_priority (int r)
10175 switch (arc_lra_priority_tag)
10177 case ARC_LRA_PRIORITY_NONE:
10178 return 0;
10179 case ARC_LRA_PRIORITY_NONCOMPACT:
10180 return ((((r & 7) ^ 4) - 4) & 15) != r;
10181 case ARC_LRA_PRIORITY_COMPACT:
10182 return ((((r & 7) ^ 4) - 4) & 15) == r;
10183 default:
10184 gcc_unreachable ();
10188 static reg_class_t
10189 arc_spill_class (reg_class_t /* orig_class */, machine_mode)
10191 return GENERAL_REGS;
10194 bool
10195 arc_legitimize_reload_address (rtx *p, machine_mode mode, int opnum,
10196 int itype)
10198 rtx x = *p;
10199 enum reload_type type = (enum reload_type) itype;
10201 if (GET_CODE (x) == PLUS
10202 && CONST_INT_P (XEXP (x, 1))
10203 && (RTX_OK_FOR_BASE_P (XEXP (x, 0), true)
10204 || (REG_P (XEXP (x, 0))
10205 && reg_equiv_constant (REGNO (XEXP (x, 0))))))
10207 int scale = GET_MODE_SIZE (mode);
10208 int shift;
10209 rtx index_rtx = XEXP (x, 1);
10210 HOST_WIDE_INT offset = INTVAL (index_rtx), offset_base;
10211 rtx reg, sum, sum2;
10213 if (scale > 4)
10214 scale = 4;
10215 if ((scale-1) & offset)
10216 scale = 1;
10217 shift = scale >> 1;
10218 offset_base
10219 = ((offset + (256 << shift))
10220 & ((HOST_WIDE_INT)((unsigned HOST_WIDE_INT) -512 << shift)));
10221 /* Sometimes the normal form does not suit DImode. We
10222 could avoid that by using smaller ranges, but that
10223 would give less optimized code when SImode is
10224 prevalent. */
10225 if (GET_MODE_SIZE (mode) + offset - offset_base <= (256 << shift))
10227 int regno;
10229 reg = XEXP (x, 0);
10230 regno = REGNO (reg);
10231 sum2 = sum = plus_constant (Pmode, reg, offset_base);
10233 if (reg_equiv_constant (regno))
10235 sum2 = plus_constant (Pmode, reg_equiv_constant (regno),
10236 offset_base);
10237 if (GET_CODE (sum2) == PLUS)
10238 sum2 = gen_rtx_CONST (Pmode, sum2);
10240 *p = gen_rtx_PLUS (Pmode, sum, GEN_INT (offset - offset_base));
10241 push_reload (sum2, NULL_RTX, &XEXP (*p, 0), NULL,
10242 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum,
10243 type);
10244 return true;
10247 /* We must re-recognize what we created before. */
10248 else if (GET_CODE (x) == PLUS
10249 && GET_CODE (XEXP (x, 0)) == PLUS
10250 && CONST_INT_P (XEXP (XEXP (x, 0), 1))
10251 && REG_P (XEXP (XEXP (x, 0), 0))
10252 && CONST_INT_P (XEXP (x, 1)))
10254 /* Because this address is so complex, we know it must have
10255 been created by LEGITIMIZE_RELOAD_ADDRESS before; thus,
10256 it is already unshared, and needs no further unsharing. */
10257 push_reload (XEXP (x, 0), NULL_RTX, &XEXP (x, 0), NULL,
10258 BASE_REG_CLASS, Pmode, VOIDmode, 0, 0, opnum, type);
10259 return true;
10261 return false;
10264 /* Implement TARGET_USE_BY_PIECES_INFRASTRUCTURE_P. */
10266 static bool
10267 arc_use_by_pieces_infrastructure_p (unsigned HOST_WIDE_INT size,
10268 unsigned int align,
10269 enum by_pieces_operation op,
10270 bool speed_p)
10272 /* Let the cpymem expander handle small block moves. */
10273 if (op == MOVE_BY_PIECES)
10274 return false;
10276 return default_use_by_pieces_infrastructure_p (size, align, op, speed_p);
10279 /* Emit a (pre) memory barrier around an atomic sequence according to
10280 MODEL. */
10282 static void
10283 arc_pre_atomic_barrier (enum memmodel model)
10285 if (need_atomic_barrier_p (model, true))
10286 emit_insn (gen_memory_barrier ());
10289 /* Emit a (post) memory barrier around an atomic sequence according to
10290 MODEL. */
10292 static void
10293 arc_post_atomic_barrier (enum memmodel model)
10295 if (need_atomic_barrier_p (model, false))
10296 emit_insn (gen_memory_barrier ());
10299 /* Expand a compare and swap pattern. */
10301 static void
10302 emit_unlikely_jump (rtx insn)
10304 rtx_insn *jump = emit_jump_insn (insn);
10305 add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
10308 /* Expand code to perform a 8 or 16-bit compare and swap by doing
10309 32-bit compare and swap on the word containing the byte or
10310 half-word. The difference between a weak and a strong CAS is that
10311 the weak version may simply fail. The strong version relies on two
10312 loops, one checks if the SCOND op is succsfully or not, the other
10313 checks if the 32 bit accessed location which contains the 8 or 16
10314 bit datum is not changed by other thread. The first loop is
10315 implemented by the atomic_compare_and_swapsi_1 pattern. The second
10316 loops is implemented by this routine. */
10318 static void
10319 arc_expand_compare_and_swap_qh (rtx bool_result, rtx result, rtx mem,
10320 rtx oldval, rtx newval, rtx weak,
10321 rtx mod_s, rtx mod_f)
10323 rtx addr1 = force_reg (Pmode, XEXP (mem, 0));
10324 rtx addr = gen_reg_rtx (Pmode);
10325 rtx off = gen_reg_rtx (SImode);
10326 rtx oldv = gen_reg_rtx (SImode);
10327 rtx newv = gen_reg_rtx (SImode);
10328 rtx oldvalue = gen_reg_rtx (SImode);
10329 rtx newvalue = gen_reg_rtx (SImode);
10330 rtx res = gen_reg_rtx (SImode);
10331 rtx resv = gen_reg_rtx (SImode);
10332 rtx memsi, val, mask, end_label, loop_label, cc, x;
10333 machine_mode mode;
10334 bool is_weak = (weak != const0_rtx);
10336 /* Truncate the address. */
10337 emit_insn (gen_rtx_SET (addr,
10338 gen_rtx_AND (Pmode, addr1, GEN_INT (-4))));
10340 /* Compute the datum offset. */
10341 emit_insn (gen_rtx_SET (off,
10342 gen_rtx_AND (SImode, addr1, GEN_INT (3))));
10343 if (TARGET_BIG_ENDIAN)
10344 emit_insn (gen_rtx_SET (off,
10345 gen_rtx_MINUS (SImode,
10346 (GET_MODE (mem) == QImode) ?
10347 GEN_INT (3) : GEN_INT (2), off)));
10349 /* Normal read from truncated address. */
10350 memsi = gen_rtx_MEM (SImode, addr);
10351 set_mem_alias_set (memsi, ALIAS_SET_MEMORY_BARRIER);
10352 MEM_VOLATILE_P (memsi) = MEM_VOLATILE_P (mem);
10354 val = copy_to_reg (memsi);
10356 /* Convert the offset in bits. */
10357 emit_insn (gen_rtx_SET (off,
10358 gen_rtx_ASHIFT (SImode, off, GEN_INT (3))));
10360 /* Get the proper mask. */
10361 if (GET_MODE (mem) == QImode)
10362 mask = force_reg (SImode, GEN_INT (0xff));
10363 else
10364 mask = force_reg (SImode, GEN_INT (0xffff));
10366 emit_insn (gen_rtx_SET (mask,
10367 gen_rtx_ASHIFT (SImode, mask, off)));
10369 /* Prepare the old and new values. */
10370 emit_insn (gen_rtx_SET (val,
10371 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10372 val)));
10374 oldval = gen_lowpart (SImode, oldval);
10375 emit_insn (gen_rtx_SET (oldv,
10376 gen_rtx_ASHIFT (SImode, oldval, off)));
10378 newval = gen_lowpart_common (SImode, newval);
10379 emit_insn (gen_rtx_SET (newv,
10380 gen_rtx_ASHIFT (SImode, newval, off)));
10382 emit_insn (gen_rtx_SET (oldv,
10383 gen_rtx_AND (SImode, oldv, mask)));
10385 emit_insn (gen_rtx_SET (newv,
10386 gen_rtx_AND (SImode, newv, mask)));
10388 if (!is_weak)
10390 end_label = gen_label_rtx ();
10391 loop_label = gen_label_rtx ();
10392 emit_label (loop_label);
10395 /* Make the old and new values. */
10396 emit_insn (gen_rtx_SET (oldvalue,
10397 gen_rtx_IOR (SImode, oldv, val)));
10399 emit_insn (gen_rtx_SET (newvalue,
10400 gen_rtx_IOR (SImode, newv, val)));
10402 /* Try an 32bit atomic compare and swap. It clobbers the CC
10403 register. */
10404 emit_insn (gen_atomic_compare_and_swapsi_1 (res, memsi, oldvalue, newvalue,
10405 weak, mod_s, mod_f));
10407 /* Regardless of the weakness of the operation, a proper boolean
10408 result needs to be provided. */
10409 x = gen_rtx_REG (CC_Zmode, CC_REG);
10410 x = gen_rtx_EQ (SImode, x, const0_rtx);
10411 emit_insn (gen_rtx_SET (bool_result, x));
10413 if (!is_weak)
10415 /* Check the results: if the atomic op is successfully the goto
10416 to end label. */
10417 x = gen_rtx_REG (CC_Zmode, CC_REG);
10418 x = gen_rtx_EQ (VOIDmode, x, const0_rtx);
10419 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10420 gen_rtx_LABEL_REF (Pmode, end_label), pc_rtx);
10421 emit_jump_insn (gen_rtx_SET (pc_rtx, x));
10423 /* Wait for the right moment when the accessed 32-bit location
10424 is stable. */
10425 emit_insn (gen_rtx_SET (resv,
10426 gen_rtx_AND (SImode, gen_rtx_NOT (SImode, mask),
10427 res)));
10428 mode = SELECT_CC_MODE (NE, resv, val);
10429 cc = gen_rtx_REG (mode, CC_REG);
10430 emit_insn (gen_rtx_SET (cc, gen_rtx_COMPARE (mode, resv, val)));
10432 /* Set the new value of the 32 bit location, proper masked. */
10433 emit_insn (gen_rtx_SET (val, resv));
10435 /* Try again if location is unstable. Fall through if only
10436 scond op failed. */
10437 x = gen_rtx_NE (VOIDmode, cc, const0_rtx);
10438 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10439 gen_rtx_LABEL_REF (Pmode, loop_label), pc_rtx);
10440 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10442 emit_label (end_label);
10445 /* End: proper return the result for the given mode. */
10446 emit_insn (gen_rtx_SET (res,
10447 gen_rtx_AND (SImode, res, mask)));
10449 emit_insn (gen_rtx_SET (res,
10450 gen_rtx_LSHIFTRT (SImode, res, off)));
10452 emit_move_insn (result, gen_lowpart (GET_MODE (result), res));
10455 /* Helper function used by "atomic_compare_and_swap" expand
10456 pattern. */
10458 void
10459 arc_expand_compare_and_swap (rtx operands[])
10461 rtx bval, rval, mem, oldval, newval, is_weak, mod_s, mod_f, x;
10462 machine_mode mode;
10464 bval = operands[0];
10465 rval = operands[1];
10466 mem = operands[2];
10467 oldval = operands[3];
10468 newval = operands[4];
10469 is_weak = operands[5];
10470 mod_s = operands[6];
10471 mod_f = operands[7];
10472 mode = GET_MODE (mem);
10474 if (reg_overlap_mentioned_p (rval, oldval))
10475 oldval = copy_to_reg (oldval);
10477 if (mode == SImode)
10479 emit_insn (gen_atomic_compare_and_swapsi_1 (rval, mem, oldval, newval,
10480 is_weak, mod_s, mod_f));
10481 x = gen_rtx_REG (CC_Zmode, CC_REG);
10482 x = gen_rtx_EQ (SImode, x, const0_rtx);
10483 emit_insn (gen_rtx_SET (bval, x));
10485 else
10487 arc_expand_compare_and_swap_qh (bval, rval, mem, oldval, newval,
10488 is_weak, mod_s, mod_f);
10492 /* Helper function used by the "atomic_compare_and_swapsi_1"
10493 pattern. */
10495 void
10496 arc_split_compare_and_swap (rtx operands[])
10498 rtx rval, mem, oldval, newval;
10499 machine_mode mode;
10500 enum memmodel mod_s, mod_f;
10501 bool is_weak;
10502 rtx label1, label2, x, cond;
10504 rval = operands[0];
10505 mem = operands[1];
10506 oldval = operands[2];
10507 newval = operands[3];
10508 is_weak = (operands[4] != const0_rtx);
10509 mod_s = (enum memmodel) INTVAL (operands[5]);
10510 mod_f = (enum memmodel) INTVAL (operands[6]);
10511 mode = GET_MODE (mem);
10513 /* ARC atomic ops work only with 32-bit aligned memories. */
10514 gcc_assert (mode == SImode);
10516 arc_pre_atomic_barrier (mod_s);
10518 label1 = NULL_RTX;
10519 if (!is_weak)
10521 label1 = gen_label_rtx ();
10522 emit_label (label1);
10524 label2 = gen_label_rtx ();
10526 /* Load exclusive. */
10527 emit_insn (gen_arc_load_exclusivesi (rval, mem));
10529 /* Check if it is oldval. */
10530 mode = SELECT_CC_MODE (NE, rval, oldval);
10531 cond = gen_rtx_REG (mode, CC_REG);
10532 emit_insn (gen_rtx_SET (cond, gen_rtx_COMPARE (mode, rval, oldval)));
10534 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10535 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10536 gen_rtx_LABEL_REF (Pmode, label2), pc_rtx);
10537 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10539 /* Exclusively store new item. Store clobbers CC reg. */
10540 emit_insn (gen_arc_store_exclusivesi (mem, newval));
10542 if (!is_weak)
10544 /* Check the result of the store. */
10545 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10546 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10547 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10548 gen_rtx_LABEL_REF (Pmode, label1), pc_rtx);
10549 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10552 if (mod_f != MEMMODEL_RELAXED)
10553 emit_label (label2);
10555 arc_post_atomic_barrier (mod_s);
10557 if (mod_f == MEMMODEL_RELAXED)
10558 emit_label (label2);
10561 /* Expand an atomic fetch-and-operate pattern. CODE is the binary operation
10562 to perform. MEM is the memory on which to operate. VAL is the second
10563 operand of the binary operator. BEFORE and AFTER are optional locations to
10564 return the value of MEM either before of after the operation. MODEL_RTX
10565 is a CONST_INT containing the memory model to use. */
10567 void
10568 arc_expand_atomic_op (enum rtx_code code, rtx mem, rtx val,
10569 rtx orig_before, rtx orig_after, rtx model_rtx)
10571 enum memmodel model = (enum memmodel) INTVAL (model_rtx);
10572 machine_mode mode = GET_MODE (mem);
10573 rtx label, x, cond;
10574 rtx before = orig_before, after = orig_after;
10576 /* ARC atomic ops work only with 32-bit aligned memories. */
10577 gcc_assert (mode == SImode);
10579 arc_pre_atomic_barrier (model);
10581 label = gen_label_rtx ();
10582 emit_label (label);
10583 label = gen_rtx_LABEL_REF (VOIDmode, label);
10585 if (before == NULL_RTX)
10586 before = gen_reg_rtx (mode);
10588 if (after == NULL_RTX)
10589 after = gen_reg_rtx (mode);
10591 /* Load exclusive. */
10592 emit_insn (gen_arc_load_exclusivesi (before, mem));
10594 switch (code)
10596 case NOT:
10597 x = gen_rtx_AND (mode, before, val);
10598 emit_insn (gen_rtx_SET (after, x));
10599 x = gen_rtx_NOT (mode, after);
10600 emit_insn (gen_rtx_SET (after, x));
10601 break;
10603 case MINUS:
10604 if (CONST_INT_P (val))
10606 val = GEN_INT (-INTVAL (val));
10607 code = PLUS;
10610 /* FALLTHRU. */
10611 default:
10612 x = gen_rtx_fmt_ee (code, mode, before, val);
10613 emit_insn (gen_rtx_SET (after, x));
10614 break;
10617 /* Exclusively store new item. Store clobbers CC reg. */
10618 emit_insn (gen_arc_store_exclusivesi (mem, after));
10620 /* Check the result of the store. */
10621 cond = gen_rtx_REG (CC_Zmode, CC_REG);
10622 x = gen_rtx_NE (VOIDmode, cond, const0_rtx);
10623 x = gen_rtx_IF_THEN_ELSE (VOIDmode, x,
10624 label, pc_rtx);
10625 emit_unlikely_jump (gen_rtx_SET (pc_rtx, x));
10627 arc_post_atomic_barrier (model);
10630 /* Implement TARGET_NO_SPECULATION_IN_DELAY_SLOTS_P. */
10632 static bool
10633 arc_no_speculation_in_delay_slots_p ()
10635 return true;
10638 /* Return a parallel of registers to represent where to find the
10639 register pieces if required, otherwise NULL_RTX. */
10641 static rtx
10642 arc_dwarf_register_span (rtx rtl)
10644 machine_mode mode = GET_MODE (rtl);
10645 unsigned regno;
10646 rtx p;
10648 if (GET_MODE_SIZE (mode) != 8)
10649 return NULL_RTX;
10651 p = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (2));
10652 regno = REGNO (rtl);
10653 XVECEXP (p, 0, 0) = gen_rtx_REG (SImode, regno);
10654 XVECEXP (p, 0, 1) = gen_rtx_REG (SImode, regno + 1);
10656 return p;
10659 /* Return true if OP is an acceptable memory operand for ARCompact
10660 16-bit load instructions of MODE.
10662 AV2SHORT: TRUE if address needs to fit into the new ARCv2 short
10663 non scaled instructions.
10665 SCALED: TRUE if address can be scaled. */
10667 bool
10668 compact_memory_operand_p (rtx op, machine_mode mode,
10669 bool av2short, bool scaled)
10671 rtx addr, plus0, plus1;
10672 int size, off;
10674 /* Eliminate non-memory operations. */
10675 if (GET_CODE (op) != MEM)
10676 return 0;
10678 /* .di instructions have no 16-bit form. */
10679 if (MEM_VOLATILE_P (op) && !TARGET_VOLATILE_CACHE_SET)
10680 return false;
10682 /* likewise for uncached types. */
10683 if (arc_is_uncached_mem_p (op))
10684 return false;
10686 if (mode == VOIDmode)
10687 mode = GET_MODE (op);
10689 size = GET_MODE_SIZE (mode);
10691 /* dword operations really put out 2 instructions, so eliminate
10692 them. */
10693 if (size > UNITS_PER_WORD)
10694 return false;
10696 /* Decode the address now. */
10697 addr = XEXP (op, 0);
10698 switch (GET_CODE (addr))
10700 case REG:
10701 return (REGNO (addr) >= FIRST_PSEUDO_REGISTER
10702 || COMPACT_GP_REG_P (REGNO (addr))
10703 || (SP_REG_P (REGNO (addr)) && (size != 2)));
10704 case PLUS:
10705 plus0 = XEXP (addr, 0);
10706 plus1 = XEXP (addr, 1);
10708 if ((GET_CODE (plus0) == REG)
10709 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10710 || COMPACT_GP_REG_P (REGNO (plus0)))
10711 && ((GET_CODE (plus1) == REG)
10712 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10713 || COMPACT_GP_REG_P (REGNO (plus1)))))
10715 return !av2short;
10718 if ((GET_CODE (plus0) == REG)
10719 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10720 || (COMPACT_GP_REG_P (REGNO (plus0)) && !av2short)
10721 || (IN_RANGE (REGNO (plus0), 0, 31) && av2short))
10722 && (GET_CODE (plus1) == CONST_INT))
10724 bool valid = false;
10726 off = INTVAL (plus1);
10728 /* Negative offset is not supported in 16-bit load/store insns. */
10729 if (off < 0)
10730 return 0;
10732 /* Only u5 immediates allowed in code density instructions. */
10733 if (av2short)
10735 switch (size)
10737 case 1:
10738 return false;
10739 case 2:
10740 /* This is an ldh_s.x instruction, check the u6
10741 immediate. */
10742 if (COMPACT_GP_REG_P (REGNO (plus0)))
10743 valid = true;
10744 break;
10745 case 4:
10746 /* Only u5 immediates allowed in 32bit access code
10747 density instructions. */
10748 if (REGNO (plus0) <= 31)
10749 return ((off < 32) && (off % 4 == 0));
10750 break;
10751 default:
10752 return false;
10755 else
10756 if (COMPACT_GP_REG_P (REGNO (plus0)))
10757 valid = true;
10759 if (valid)
10762 switch (size)
10764 case 1:
10765 return (off < 32);
10766 case 2:
10767 /* The 6-bit constant get shifted to fit the real
10768 5-bits field. Check also for the alignment. */
10769 return ((off < 64) && (off % 2 == 0));
10770 case 4:
10771 return ((off < 128) && (off % 4 == 0));
10772 default:
10773 return false;
10778 if (REG_P (plus0) && CONST_INT_P (plus1)
10779 && ((REGNO (plus0) >= FIRST_PSEUDO_REGISTER)
10780 || SP_REG_P (REGNO (plus0)))
10781 && !av2short)
10783 off = INTVAL (plus1);
10784 return ((size != 2) && (off >= 0 && off < 128) && (off % 4 == 0));
10787 if ((GET_CODE (plus0) == MULT)
10788 && (GET_CODE (XEXP (plus0, 0)) == REG)
10789 && ((REGNO (XEXP (plus0, 0)) >= FIRST_PSEUDO_REGISTER)
10790 || COMPACT_GP_REG_P (REGNO (XEXP (plus0, 0))))
10791 && (GET_CODE (plus1) == REG)
10792 && ((REGNO (plus1) >= FIRST_PSEUDO_REGISTER)
10793 || COMPACT_GP_REG_P (REGNO (plus1))))
10794 return scaled;
10795 default:
10796 break ;
10797 /* TODO: 'gp' and 'pcl' are to supported as base address operand
10798 for 16-bit load instructions. */
10800 return false;
10803 /* Return nonzero if a jli call should be generated for a call from
10804 the current function to DECL. */
10806 bool
10807 arc_is_jli_call_p (rtx pat)
10809 tree attrs;
10810 tree decl = SYMBOL_REF_DECL (pat);
10812 /* If it is not a well defined public function then return false. */
10813 if (!decl || !SYMBOL_REF_FUNCTION_P (pat) || !TREE_PUBLIC (decl))
10814 return false;
10816 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10817 if (lookup_attribute ("jli_always", attrs))
10818 return true;
10820 if (lookup_attribute ("jli_fixed", attrs))
10821 return true;
10823 return TARGET_JLI_ALWAYS;
10826 /* Handle and "jli" attribute; arguments as in struct
10827 attribute_spec.handler. */
10829 static tree
10830 arc_handle_jli_attribute (tree *node ATTRIBUTE_UNUSED,
10831 tree name, tree args, int,
10832 bool *no_add_attrs)
10834 if (!TARGET_V2)
10836 warning (OPT_Wattributes,
10837 "%qE attribute only valid for ARCv2 architecture",
10838 name);
10839 *no_add_attrs = true;
10842 if (args == NULL_TREE)
10844 warning (OPT_Wattributes,
10845 "argument of %qE attribute is missing",
10846 name);
10847 *no_add_attrs = true;
10849 else
10851 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10852 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10853 tree arg = TREE_VALUE (args);
10854 if (TREE_CODE (arg) != INTEGER_CST)
10856 warning (0, "%qE attribute allows only an integer constant argument",
10857 name);
10858 *no_add_attrs = true;
10860 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
10862 return NULL_TREE;
10865 /* Handle and "scure" attribute; arguments as in struct
10866 attribute_spec.handler. */
10868 static tree
10869 arc_handle_secure_attribute (tree *node ATTRIBUTE_UNUSED,
10870 tree name, tree args, int,
10871 bool *no_add_attrs)
10873 if (!TARGET_EM)
10875 warning (OPT_Wattributes,
10876 "%qE attribute only valid for ARC EM architecture",
10877 name);
10878 *no_add_attrs = true;
10881 if (args == NULL_TREE)
10883 warning (OPT_Wattributes,
10884 "argument of %qE attribute is missing",
10885 name);
10886 *no_add_attrs = true;
10888 else
10890 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
10891 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
10892 tree arg = TREE_VALUE (args);
10893 if (TREE_CODE (arg) != INTEGER_CST)
10895 warning (0, "%qE attribute allows only an integer constant argument",
10896 name);
10897 *no_add_attrs = true;
10900 return NULL_TREE;
10903 /* Return nonzero if the symbol is a secure function. */
10905 bool
10906 arc_is_secure_call_p (rtx pat)
10908 tree attrs;
10909 tree decl = SYMBOL_REF_DECL (pat);
10911 if (!decl)
10912 return false;
10914 attrs = TYPE_ATTRIBUTES (TREE_TYPE (decl));
10915 if (lookup_attribute ("secure_call", attrs))
10916 return true;
10918 return false;
10921 /* Handle "uncached" qualifier. */
10923 static tree
10924 arc_handle_uncached_attribute (tree *node,
10925 tree name, tree args,
10926 int flags ATTRIBUTE_UNUSED,
10927 bool *no_add_attrs)
10929 if (DECL_P (*node) && TREE_CODE (*node) != TYPE_DECL)
10931 error ("%qE attribute only applies to types",
10932 name);
10933 *no_add_attrs = true;
10935 else if (args)
10937 warning (OPT_Wattributes, "argument of %qE attribute ignored", name);
10939 return NULL_TREE;
10942 /* Return TRUE if PAT is a memory addressing an uncached data. */
10944 bool
10945 arc_is_uncached_mem_p (rtx pat)
10947 tree attrs = NULL_TREE;
10948 tree addr;
10950 if (!MEM_P (pat))
10951 return false;
10953 /* Get the memory attributes. */
10954 addr = MEM_EXPR (pat);
10955 if (!addr)
10956 return false;
10958 /* Get the attributes. */
10959 if (TREE_CODE (addr) == MEM_REF
10960 || VAR_P (addr))
10962 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10963 if (lookup_attribute ("uncached", attrs))
10964 return true;
10966 if (TREE_CODE (addr) == MEM_REF)
10968 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10969 if (lookup_attribute ("uncached", attrs))
10970 return true;
10971 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10972 if (lookup_attribute ("uncached", attrs))
10973 return true;
10976 /* Check the definitions of the structs. */
10977 while (handled_component_p (addr))
10979 if (TREE_CODE (addr) == COMPONENT_REF)
10981 attrs = TYPE_ATTRIBUTES (TREE_TYPE (addr));
10982 if (lookup_attribute ("uncached", attrs))
10983 return true;
10984 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 0)));
10985 if (lookup_attribute ("uncached", attrs))
10986 return true;
10987 attrs = TYPE_ATTRIBUTES (TREE_TYPE (TREE_OPERAND (addr, 1)));
10988 if (lookup_attribute ("uncached", attrs))
10989 return true;
10991 addr = TREE_OPERAND (addr, 0);
10993 return false;
10996 /* Handle aux attribute. The auxiliary registers are addressed using
10997 special instructions lr and sr. The attribute 'aux' indicates if a
10998 variable refers to the aux-regs and what is the register number
10999 desired. */
11001 static tree
11002 arc_handle_aux_attribute (tree *node,
11003 tree name, tree args, int,
11004 bool *no_add_attrs)
11006 /* Isn't it better to use address spaces for the aux-regs? */
11007 if (DECL_P (*node))
11009 if (TREE_CODE (*node) != VAR_DECL)
11011 error ("%qE attribute only applies to variables", name);
11012 *no_add_attrs = true;
11014 else if (args)
11016 if (TREE_CODE (TREE_VALUE (args)) == NON_LVALUE_EXPR)
11017 TREE_VALUE (args) = TREE_OPERAND (TREE_VALUE (args), 0);
11018 tree arg = TREE_VALUE (args);
11019 if (TREE_CODE (arg) != INTEGER_CST)
11021 warning (OPT_Wattributes, "%qE attribute allows only an integer "
11022 "constant argument", name);
11023 *no_add_attrs = true;
11025 /* FIXME! add range check. TREE_INT_CST_LOW (arg) */
11028 if (VAR_P (*node))
11030 tree fntype = TREE_TYPE (*node);
11031 if (fntype && TREE_CODE (fntype) == POINTER_TYPE)
11033 tree attrs = tree_cons (get_identifier ("aux"), NULL_TREE,
11034 TYPE_ATTRIBUTES (fntype));
11035 TYPE_ATTRIBUTES (fntype) = attrs;
11039 return NULL_TREE;
11042 /* Implement TARGET_USE_ANCHORS_FOR_SYMBOL_P. We don't want to use
11043 anchors for small data: the GP register acts as an anchor in that
11044 case. We also don't want to use them for PC-relative accesses,
11045 where the PC acts as an anchor. Prohibit also TLS symbols to use
11046 anchors. */
11048 static bool
11049 arc_use_anchors_for_symbol_p (const_rtx symbol)
11051 if (SYMBOL_REF_TLS_MODEL (symbol))
11052 return false;
11054 if (flag_pic)
11055 return false;
11057 if (SYMBOL_REF_SMALL_P (symbol))
11058 return false;
11060 return default_use_anchors_for_symbol_p (symbol);
11063 /* Return true if SUBST can't safely replace its equivalent during RA. */
11064 static bool
11065 arc_cannot_substitute_mem_equiv_p (rtx)
11067 /* If SUBST is mem[base+index], the address may not fit ISA,
11068 thus return true. */
11069 return true;
11072 /* Checks whether the operands are valid for use in an LDD/STD
11073 instruction. Assumes that RT, and RT2 are REG. This is guaranteed
11074 by the patterns. Assumes that the address in the base register RN
11075 is word aligned. Pattern guarantees that both memory accesses use
11076 the same base register, the offsets are constants within the range,
11077 and the gap between the offsets is 4. If reload complete then
11078 check that registers are legal. */
11080 static bool
11081 operands_ok_ldd_std (rtx rt, rtx rt2, HOST_WIDE_INT offset)
11083 unsigned int t, t2;
11085 if (!reload_completed)
11086 return true;
11088 if (!(SMALL_INT_RANGE (offset, (GET_MODE_SIZE (DImode) - 1) & (~0x03),
11089 (offset & (GET_MODE_SIZE (DImode) - 1) & 3
11090 ? 0 : -(-GET_MODE_SIZE (DImode) | (~0x03)) >> 1))))
11091 return false;
11093 t = REGNO (rt);
11094 t2 = REGNO (rt2);
11096 if ((t2 == PCL_REG)
11097 || (t % 2 != 0) /* First destination register is not even. */
11098 || (t2 != t + 1))
11099 return false;
11101 return true;
11104 /* Helper for gen_operands_ldd_std. Returns true iff the memory
11105 operand MEM's address contains an immediate offset from the base
11106 register and has no side effects, in which case it sets BASE and
11107 OFFSET accordingly. */
11109 static bool
11110 mem_ok_for_ldd_std (rtx mem, rtx *base, rtx *offset)
11112 rtx addr;
11114 gcc_assert (base != NULL && offset != NULL);
11116 /* TODO: Handle more general memory operand patterns, such as
11117 PRE_DEC and PRE_INC. */
11119 if (side_effects_p (mem))
11120 return false;
11122 /* Can't deal with subregs. */
11123 if (GET_CODE (mem) == SUBREG)
11124 return false;
11126 gcc_assert (MEM_P (mem));
11128 *offset = const0_rtx;
11130 addr = XEXP (mem, 0);
11132 /* If addr isn't valid for DImode, then we can't handle it. */
11133 if (!arc_legitimate_address_p (DImode, addr,
11134 reload_in_progress || reload_completed))
11135 return false;
11137 if (REG_P (addr))
11139 *base = addr;
11140 return true;
11142 else if (GET_CODE (addr) == PLUS || GET_CODE (addr) == MINUS)
11144 *base = XEXP (addr, 0);
11145 *offset = XEXP (addr, 1);
11146 return (REG_P (*base) && CONST_INT_P (*offset));
11149 return false;
11152 /* Called from peephole2 to replace two word-size accesses with a
11153 single LDD/STD instruction. Returns true iff we can generate a new
11154 instruction sequence. That is, both accesses use the same base
11155 register and the gap between constant offsets is 4. OPERANDS are
11156 the operands found by the peephole matcher; OPERANDS[0,1] are
11157 register operands, and OPERANDS[2,3] are the corresponding memory
11158 operands. LOAD indicates whether the access is load or store. */
11160 bool
11161 gen_operands_ldd_std (rtx *operands, bool load, bool commute)
11163 int i, gap;
11164 HOST_WIDE_INT offsets[2], offset;
11165 int nops = 2;
11166 rtx cur_base, cur_offset, tmp;
11167 rtx base = NULL_RTX;
11169 /* Check that the memory references are immediate offsets from the
11170 same base register. Extract the base register, the destination
11171 registers, and the corresponding memory offsets. */
11172 for (i = 0; i < nops; i++)
11174 if (!mem_ok_for_ldd_std (operands[nops+i], &cur_base, &cur_offset))
11175 return false;
11177 if (i == 0)
11178 base = cur_base;
11179 else if (REGNO (base) != REGNO (cur_base))
11180 return false;
11182 offsets[i] = INTVAL (cur_offset);
11183 if (GET_CODE (operands[i]) == SUBREG)
11185 tmp = SUBREG_REG (operands[i]);
11186 gcc_assert (GET_MODE (operands[i]) == GET_MODE (tmp));
11187 operands[i] = tmp;
11191 /* Make sure there is no dependency between the individual loads. */
11192 if (load && REGNO (operands[0]) == REGNO (base))
11193 return false; /* RAW. */
11195 if (load && REGNO (operands[0]) == REGNO (operands[1]))
11196 return false; /* WAW. */
11198 /* Make sure the instructions are ordered with lower memory access first. */
11199 if (offsets[0] > offsets[1])
11201 gap = offsets[0] - offsets[1];
11202 offset = offsets[1];
11204 /* Swap the instructions such that lower memory is accessed first. */
11205 std::swap (operands[0], operands[1]);
11206 std::swap (operands[2], operands[3]);
11208 else
11210 gap = offsets[1] - offsets[0];
11211 offset = offsets[0];
11214 /* Make sure accesses are to consecutive memory locations. */
11215 if (gap != 4)
11216 return false;
11218 /* Make sure we generate legal instructions. */
11219 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11220 return true;
11222 if (load && commute)
11224 /* Try reordering registers. */
11225 std::swap (operands[0], operands[1]);
11226 if (operands_ok_ldd_std (operands[0], operands[1], offset))
11227 return true;
11230 return false;
11233 /* This order of allocation is used when we compile for size. It
11234 allocates first the registers which are most probably to end up in
11235 a short instruction. */
11236 static const int size_alloc_order[] =
11238 0, 1, 2, 3, 12, 13, 14, 15,
11239 4, 5, 6, 7, 8, 9, 10, 11
11242 /* Adjust register allocation order when compiling for size. */
11243 void
11244 arc_adjust_reg_alloc_order (void)
11246 const int arc_default_alloc_order[] = REG_ALLOC_ORDER;
11247 memcpy (reg_alloc_order, arc_default_alloc_order, sizeof (reg_alloc_order));
11248 if (optimize_size)
11249 memcpy (reg_alloc_order, size_alloc_order, sizeof (size_alloc_order));
11252 /* Implement TARGET_MEMORY_MOVE_COST. */
11254 static int
11255 arc_memory_move_cost (machine_mode mode,
11256 reg_class_t rclass ATTRIBUTE_UNUSED,
11257 bool in ATTRIBUTE_UNUSED)
11259 if ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD)
11260 || ((GET_MODE_SIZE (mode) <= UNITS_PER_WORD * 2) && TARGET_LL64))
11261 return 6;
11263 return (2 * GET_MODE_SIZE (mode));
11266 /* Split an OR instruction into multiple BSET/OR instructions in a
11267 attempt to avoid long immediate constants. The next strategies are
11268 employed when destination is 'q' reg.
11270 1. if there are up to three bits set in the mask, a succession of
11271 three bset instruction will be emitted:
11272 OR rA, rB, mask ->
11273 BSET(_S) rA,rB,mask1/BSET_S rA,rA,mask2/BSET_S rA,rA,mask3
11275 2. if the lower 6 bits of the mask is set and there is only one
11276 bit set in the upper remaining bits then we will emit one bset and
11277 one OR instruction:
11278 OR rA, rB, mask -> OR rA,rB,mask1/BSET_S rA,mask2
11280 3. otherwise an OR with limm will be emmitted. */
11282 void
11283 arc_split_ior (rtx *operands)
11285 unsigned HOST_WIDE_INT mask, maskx;
11286 rtx op1 = operands[1];
11288 gcc_assert (CONST_INT_P (operands[2]));
11289 mask = INTVAL (operands[2]) & 0xffffffff;
11291 if (__builtin_popcount (mask) > 3 || (mask & 0x3f))
11293 maskx = mask & 0x3f;
11294 emit_insn (gen_rtx_SET (operands[0],
11295 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11296 op1 = operands[0];
11297 mask &= ~maskx;
11300 switch (__builtin_popcount (mask))
11302 case 3:
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 2:
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 mask &= ~maskx;
11314 op1 = operands[0];
11315 /* FALLTHRU */
11316 case 1:
11317 maskx = 1 << (__builtin_ffs (mask) - 1);
11318 emit_insn (gen_rtx_SET (operands[0],
11319 gen_rtx_IOR (SImode, op1, GEN_INT (maskx))));
11320 break;
11321 case 0:
11322 break;
11323 default:
11324 gcc_unreachable ();
11328 /* Helper to check C0x constraint. */
11330 bool
11331 arc_check_ior_const (HOST_WIDE_INT ival)
11333 unsigned int mask = (unsigned int) (ival & 0xffffffff);
11335 if (UNSIGNED_INT6 (ival)
11336 || IS_POWEROF2_P (mask))
11337 return false;
11338 if (__builtin_popcount (mask) <= 3)
11339 return true;
11340 if (__builtin_popcount (mask & ~0x3f) <= 1)
11341 return true;
11342 return false;
11345 /* Split a mov with long immediate instruction into smaller, size
11346 friendly instructions. */
11348 bool
11349 arc_split_mov_const (rtx *operands)
11351 unsigned HOST_WIDE_INT ival;
11352 HOST_WIDE_INT shimm;
11353 machine_mode mode = GET_MODE (operands[0]);
11355 /* Manage a constant. */
11356 gcc_assert (CONST_INT_P (operands[1]));
11357 ival = INTVAL (operands[1]) & 0xffffffff;
11359 /* 1. Check if we can just rotate limm by 8 but using ROR8. */
11360 if (TARGET_BARREL_SHIFTER && TARGET_V2
11361 && ((ival & ~0x3f000000) == 0))
11363 shimm = (ival >> 24) & 0x3f;
11364 emit_insn (gen_rtx_SET (operands[0],
11365 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11366 GEN_INT (8))));
11367 return true;
11369 /* 2. Check if we can just shift by 8 to fit into the u6 of LSL8. */
11370 if (TARGET_BARREL_SHIFTER && TARGET_V2
11371 && ((ival & ~0x3f00) == 0))
11373 shimm = (ival >> 8) & 0x3f;
11374 emit_insn (gen_rtx_SET (operands[0],
11375 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11376 GEN_INT (8))));
11377 return true;
11380 /* 3. Check if we can just shift by 16 to fit into the u6 of LSL16. */
11381 if (TARGET_SWAP && TARGET_V2
11382 && ((ival & ~0x3f0000) == 0))
11384 shimm = (ival >> 16) & 0x3f;
11385 emit_insn (gen_rtx_SET (operands[0],
11386 gen_rtx_ASHIFT (mode, GEN_INT (shimm),
11387 GEN_INT (16))));
11388 return true;
11391 /* 4. Check if we can do something like mov_s h,u8 / asl_s ra,h,#nb. */
11392 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0
11393 && TARGET_BARREL_SHIFTER)
11395 HOST_WIDE_INT shift = __builtin_ffs (ival);
11396 shimm = (ival >> (shift - 1)) & 0xff;
11397 emit_insn (gen_rtx_SET (operands[0], GEN_INT (shimm)));
11398 emit_insn (gen_rtx_SET (operands[0],
11399 gen_rtx_ASHIFT (mode, operands[0],
11400 GEN_INT (shift - 1))));
11401 return true;
11404 /* 5. Check if we can just rotate the limm, useful when no barrel
11405 shifter is present. */
11406 if ((ival & ~0x8000001f) == 0)
11408 shimm = (ival * 2 + 1) & 0x3f;
11409 emit_insn (gen_rtx_SET (operands[0],
11410 gen_rtx_ROTATERT (mode, GEN_INT (shimm),
11411 const1_rtx)));
11412 return true;
11415 /* 6. Check if we can do something with bmask. */
11416 if (IS_POWEROF2_P (ival + 1))
11418 emit_insn (gen_rtx_SET (operands[0], constm1_rtx));
11419 emit_insn (gen_rtx_SET (operands[0],
11420 gen_rtx_AND (mode, operands[0],
11421 GEN_INT (ival))));
11422 return true;
11425 gcc_unreachable ();
11428 /* Helper to check Cax constraint. */
11430 bool
11431 arc_check_mov_const (HOST_WIDE_INT ival)
11433 ival = ival & 0xffffffff;
11435 if (SIGNED_INT12 (ival))
11436 return false;
11438 if ((ival & ~0x8000001f) == 0)
11439 return true;
11441 if (IS_POWEROF2_P (ival + 1))
11442 return true;
11444 /* The next rules requires a barrel shifter. */
11445 if (!TARGET_BARREL_SHIFTER)
11446 return false;
11448 if (((ival >> (__builtin_ffs (ival) - 1)) & 0xffffff00) == 0)
11449 return true;
11451 if ((ival & ~0x3f00) == 0)
11452 return true;
11454 if ((ival & ~0x3f0000) == 0)
11455 return true;
11457 if ((ival & ~0x3f000000) == 0)
11458 return true;
11460 return false;
11463 /* Return nonzero if this function is known to have a null epilogue.
11464 This allows the optimizer to omit jumps to jumps if no stack
11465 was created. */
11467 bool
11468 arc_can_use_return_insn (void)
11470 return (reload_completed && cfun->machine->frame_info.total_size == 0
11471 && !ARC_INTERRUPT_P (arc_compute_function_type (cfun)));
11474 /* Helper for INSN_COST.
11476 Per Segher Boessenkool: rtx_costs computes the cost for any rtx (an
11477 insn, a set, a set source, any random piece of one). set_src_cost,
11478 set_rtx_cost, etc. are helper functions that use that.
11480 Those functions do not work for parallels. Also, costs are not
11481 additive like this simplified model assumes. Also, more complex
11482 backends tend to miss many cases in their rtx_costs function.
11484 Many passes that want costs want to know the cost of a full insn. Like
11485 combine. That's why I created insn_cost: it solves all of the above
11486 problems. */
11488 static int
11489 arc_insn_cost (rtx_insn *insn, bool speed)
11491 int cost;
11492 enum attr_type type;
11493 if (recog_memoized (insn) >= 0)
11495 if (speed)
11497 /* Use cost if provided. */
11498 cost = get_attr_cost (insn);
11499 if (cost > 0)
11500 return cost;
11501 /* For speed make a simple cost model: memory access is more
11502 expensive than any other instruction. */
11503 type = get_attr_type (insn);
11504 if (type == TYPE_LOAD || type == TYPE_STORE)
11505 return COSTS_N_INSNS (2);
11507 else
11509 /* If optimizing for size, we want the insn size. */
11510 type = get_attr_type (insn);
11511 if (type != TYPE_MULTI)
11512 return get_attr_length (insn);
11516 if (rtx set = single_set (insn))
11517 cost = set_rtx_cost (set, speed);
11518 else
11519 cost = pattern_cost (PATTERN (insn), speed);
11520 /* If the cost is zero, then it's likely a complex insn. We don't
11521 want the cost of these to be less than something we know about. */
11522 return cost ? cost : COSTS_N_INSNS (2);
11525 static unsigned
11526 arc_libm_function_max_error (unsigned cfn, machine_mode mode,
11527 bool boundary_p)
11529 #ifdef OPTION_GLIBC
11530 bool glibc_p = OPTION_GLIBC;
11531 #else
11532 bool glibc_p = false;
11533 #endif
11534 if (glibc_p)
11536 int rnd = flag_rounding_math ? 4 : 0;
11537 switch (cfn)
11539 CASE_CFN_SIN:
11540 CASE_CFN_SIN_FN:
11541 if (!boundary_p && mode == DFmode)
11542 return 7 + rnd;
11543 break;
11544 CASE_CFN_COS:
11545 CASE_CFN_COS_FN:
11546 if (!boundary_p && mode == DFmode)
11547 return 4 + rnd;
11548 default:
11549 break;
11551 return glibc_linux_libm_function_max_error (cfn, mode, boundary_p);
11553 return default_libm_function_max_error (cfn, mode, boundary_p);
11556 #undef TARGET_USE_ANCHORS_FOR_SYMBOL_P
11557 #define TARGET_USE_ANCHORS_FOR_SYMBOL_P arc_use_anchors_for_symbol_p
11559 #undef TARGET_CONSTANT_ALIGNMENT
11560 #define TARGET_CONSTANT_ALIGNMENT constant_alignment_word_strings
11562 #undef TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P
11563 #define TARGET_CANNOT_SUBSTITUTE_MEM_EQUIV_P arc_cannot_substitute_mem_equiv_p
11565 #undef TARGET_ASM_TRAMPOLINE_TEMPLATE
11566 #define TARGET_ASM_TRAMPOLINE_TEMPLATE arc_asm_trampoline_template
11568 #undef TARGET_HAVE_SPECULATION_SAFE_VALUE
11569 #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed
11571 #undef TARGET_REGISTER_MOVE_COST
11572 #define TARGET_REGISTER_MOVE_COST arc_register_move_cost
11574 #undef TARGET_MEMORY_MOVE_COST
11575 #define TARGET_MEMORY_MOVE_COST arc_memory_move_cost
11577 #undef TARGET_INSN_COST
11578 #define TARGET_INSN_COST arc_insn_cost
11580 #undef TARGET_LIBM_FUNCTION_MAX_ERROR
11581 #define TARGET_LIBM_FUNCTION_MAX_ERROR arc_libm_function_max_error
11583 struct gcc_target targetm = TARGET_INITIALIZER;
11585 #include "gt-arc.h"